diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 70205b0..e529a83 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -3,7 +3,7 @@ name: Node.js Package on: push: pull_request: - types: [opened] + types: [opened, synchronize, reopened] # release: # types: [created] @@ -18,6 +18,7 @@ env: permissions: contents: read packages: read + pull-requests: write jobs: build: @@ -34,6 +35,11 @@ jobs: - run: pnpm install - run: pnpm run test + - name: 'Report Coverage' + # Set if: always() to also generate the report if tests are failing + # Only works if you set `reportOnFailure: true` in your vite config as specified above + if: always() + uses: davelosert/vitest-coverage-report-action@v2 - run: pnpm run build - uses: actions/upload-artifact@v3 with: diff --git a/.gitignore b/.gitignore index a20be92..305deb2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ /node_modules/ .turbo/ /.pnpm-store/ -/out/ \ No newline at end of file +/out/ +/coverage/ +/e2e-tmp/ \ No newline at end of file diff --git a/package.json b/package.json index c986ff2..f0384f9 100644 --- a/package.json +++ b/package.json @@ -8,21 +8,25 @@ "build": "turbo build", "build:dev": "tsc --build --watch", "test:lint": "eslint ./packages/*/src", - "test": "pnpm run test:lint" + "test:code": "vitest --coverage", + "test": "pnpm run test:lint && pnpm run test:code" }, "keywords": [], "author": "", "devDependencies": { "@react-native-community/eslint-config": "^3.2.0", + "@vitest/coverage-v8": "^1.2.0", "eslint": "^8.53.0", "prettier": "^2.8.8", "turbo": "^1.10.16", - "typescript": "^5.3.3" + "typescript": "^5.3.3", + "vite": "^5.0.11" }, "dependencies": { "@pnpm/find-workspace-packages": "^6.0.9", "@types/node": "^20.10.8", - "ts-node": "^10.9.2" + "ts-node": "^10.9.2", + "vitest": "^1.2.0" }, "homepage": "https://github.com/morten-olsen/mini-loader", "repository": { diff --git a/packages/cli/bin/index.mjs b/packages/cli/bin/index.mjs index efb0ee3..a13dc09 100755 --- a/packages/cli/bin/index.mjs +++ b/packages/cli/bin/index.mjs @@ -1,4 +1,4 @@ #!/usr/bin/env node import 'source-map-support/register.js'; -import '../dist/esm/index.js'; +import '../dist/esm/bin.js'; diff --git a/packages/cli/package.json b/packages/cli/package.json index cda0c1e..fbb40aa 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -40,7 +40,8 @@ "rollup": "^4.9.4", "rollup-plugin-node-polyfills": "^0.2.1", "source-map-support": "^0.5.21", - "superjson": "^2.2.1" + "superjson": "^2.2.1", + "typedi": "^0.10.0" }, "devDependencies": { "@morten-olsen/mini-loader-configs": "workspace:^", diff --git a/packages/cli/src/api/api.ts b/packages/cli/src/api/api.ts new file mode 100644 index 0000000..d9678db --- /dev/null +++ b/packages/cli/src/api/api.ts @@ -0,0 +1,46 @@ +import { ContainerInstance, Service } from 'typedi'; +import { Context } from '../context/context.js'; +import { Config } from '../config/config.js'; +import { Client, createClient } from '../client/client.js'; +import type { Runtime } from '@morten-olsen/mini-loader-server'; +import { Terminal } from './output.js'; + +@Service() +class CliApi { + #container: ContainerInstance; + #client?: Client; + + constructor(container: ContainerInstance) { + this.#container = container; + } + + public get log() { + return this.#container.get(Terminal).log; + } + + public get step() { + return this.#container.get(Terminal).step; + } + + public get output() { + return this.#container.get(Terminal).output; + } + + public get config() { + return this.#container.get(Config); + } + + public get client() { + if (!this.#client) { + this.#client = createClient(this.context); + } + return this.#client; + } + + public get context() { + return new Context(this.config); + } +} + +export type { Runtime }; +export { CliApi }; diff --git a/packages/cli/src/api/output.ts b/packages/cli/src/api/output.ts new file mode 100644 index 0000000..60b41f2 --- /dev/null +++ b/packages/cli/src/api/output.ts @@ -0,0 +1,27 @@ +import ora from 'ora'; +import { Service } from 'typedi'; + +@Service() +class Terminal { + public log = (message: string) => { + console.log(message); + }; + + public output = (data: unknown) => { + console.table(data); + }; + + public step = async (message: string, action: () => Promise) => { + const spinner = ora(message).start(); + try { + const result = await action(); + await spinner.succeed(); + return result; + } catch (err) { + await spinner.fail(); + throw err; + } + }; +} + +export { Terminal }; diff --git a/packages/cli/src/bin.ts b/packages/cli/src/bin.ts new file mode 100644 index 0000000..963af04 --- /dev/null +++ b/packages/cli/src/bin.ts @@ -0,0 +1,7 @@ +import { ContainerInstance } from 'typedi'; +import { createClientCli } from './index.js'; + +const container = new ContainerInstance('client'); +const program = createClientCli(container); + +await program.parseAsync(); diff --git a/packages/cli/src/client/client.ts b/packages/cli/src/client/client.ts index 91a3af1..09f7aea 100644 --- a/packages/cli/src/client/client.ts +++ b/packages/cli/src/client/client.ts @@ -1,14 +1,9 @@ import { createTRPCProxyClient, httpBatchLink } from '@trpc/client'; import superjson from 'superjson'; -import { createRequire } from 'module'; import type { Runtime } from '@morten-olsen/mini-loader-server'; import type { RootRouter } from '@morten-olsen/mini-loader-server'; import { Context } from '../context/context.js'; -import { readFile } from 'fs/promises'; -const require = createRequire(import.meta.url); - -const pkg = JSON.parse(await readFile(require.resolve('#pkg'), 'utf-8')); const createClient = (context: Context) => { if (!context.host || !context.token) { throw new Error('Not signed in'); @@ -19,7 +14,6 @@ const createClient = (context: Context) => { httpBatchLink({ url: `${context.host}/trpc`, headers: { - 'x-version': pkg.version, authorization: `Bearer ${context.token}`, }, }), diff --git a/packages/cli/src/commands/artifacts/artifacts.list.ts b/packages/cli/src/commands/artifacts/artifacts.list.ts index 3d92276..8147e84 100644 --- a/packages/cli/src/commands/artifacts/artifacts.list.ts +++ b/packages/cli/src/commands/artifacts/artifacts.list.ts @@ -1,8 +1,5 @@ import { Command } from 'commander'; -import { createClient } from '../../client/client.js'; -import { step } from '../../utils/step.js'; -import { Context } from '../../context/context.js'; -import { Config } from '../../config/config.js'; +import { getApi } from '../../utils/command.js'; const list = new Command('list'); @@ -22,11 +19,7 @@ list .option('-a, --limit ', 'Limit', '1000') .action(async () => { const { runId, loadId, offset, limit } = list.opts(); - const config = new Config(); - const context = new Context(config.context); - const client = await step('Connecting to server', async () => { - return createClient(context); - }); + const { step, client } = getApi(list); const artifacts = await step('Getting artifacts', async () => { return await client.artifacts.find.query({ runId, diff --git a/packages/cli/src/commands/artifacts/artifacts.pull.ts b/packages/cli/src/commands/artifacts/artifacts.pull.ts index df24f02..09940f3 100644 --- a/packages/cli/src/commands/artifacts/artifacts.pull.ts +++ b/packages/cli/src/commands/artifacts/artifacts.pull.ts @@ -1,10 +1,7 @@ import { Command } from 'commander'; -import { createClient } from '../../client/client.js'; -import { step } from '../../utils/step.js'; -import { Context } from '../../context/context.js'; import { dirname, resolve } from 'path'; import { mkdir, writeFile } from 'fs/promises'; -import { Config } from '../../config/config.js'; +import { getApi } from '../../utils/command.js'; const pull = new Command('pull'); @@ -13,12 +10,8 @@ pull .argument('', 'Artifact ID') .argument('', 'File to save') .action(async (id, file) => { - const config = new Config(); - const context = new Context(config.context); + const { step, client } = getApi(pull); const target = resolve(file); - const client = await step('Connecting to server', async () => { - return createClient(context); - }); const artifact = await step('Getting artifact', async () => { const result = await client.artifacts.get.query(id); if (!result) { diff --git a/packages/cli/src/commands/artifacts/artifacts.remove.ts b/packages/cli/src/commands/artifacts/artifacts.remove.ts index ce0cae4..5b7a991 100644 --- a/packages/cli/src/commands/artifacts/artifacts.remove.ts +++ b/packages/cli/src/commands/artifacts/artifacts.remove.ts @@ -1,9 +1,6 @@ import { Command } from 'commander'; -import { createClient } from '../../client/client.js'; -import { step } from '../../utils/step.js'; -import { Context } from '../../context/context.js'; import inquirer from 'inquirer'; -import { Config } from '../../config/config.js'; +import { getApi } from '../../utils/command.js'; const remove = new Command('remove'); @@ -22,12 +19,8 @@ remove .option('-o, --offset ', 'Offset') .option('-a, --limit ', 'Limit', '1000') .action(async () => { + const { step, client } = getApi(remove); const { runId, loadId, offset, limit } = remove.opts(); - const config = new Config(); - const context = new Context(config.context); - const client = await step('Connecting to server', async () => { - return createClient(context); - }); const response = await step('Preparing to delete', async () => { return await client.artifacts.prepareRemove.query({ runId, diff --git a/packages/cli/src/commands/auth/auth.login.ts b/packages/cli/src/commands/auth/auth.login.ts index dd29429..d4ddf29 100644 --- a/packages/cli/src/commands/auth/auth.login.ts +++ b/packages/cli/src/commands/auth/auth.login.ts @@ -1,28 +1,37 @@ import { Command } from 'commander'; import inquerer from 'inquirer'; -import { Context } from '../../context/context.js'; -import { step } from '../../utils/step.js'; -import { Config } from '../../config/config.js'; +import { getApi } from '../../utils/command.js'; const login = new Command('login'); login.description('Login to your account'); +login.option('--host ', 'The host of your server'); +login.option('--token ', 'The token of your account'); login.action(async () => { - const config = new Config(); - const context = new Context(config.context); - const { host, token } = await inquerer.prompt([ - { - type: 'input', - name: 'host', - message: 'Enter the host of your server', - default: context.host ?? 'http://localhost:4500', - }, - { - type: 'password', - name: 'token', - message: 'Enter your token', - }, - ]); + let { host, token } = login.opts(); + const { step, context } = getApi(login); + if (!host) { + const answers = await inquerer.prompt([ + { + type: 'input', + name: 'host', + message: 'Enter the host of your server', + default: context.host || 'http://localhost:4500', + }, + ]); + host = answers.host; + } + + if (!token) { + const answers = await inquerer.prompt([ + { + type: 'password', + name: 'token', + message: 'Enter your token', + }, + ]); + token = answers.token; + } const healthResponse = await step('Getting auth status', async () => { return await fetch(`${host}/health`, { diff --git a/packages/cli/src/commands/contexts/contexts.current.ts b/packages/cli/src/commands/contexts/contexts.current.ts index 8fbd140..1fe84a5 100644 --- a/packages/cli/src/commands/contexts/contexts.current.ts +++ b/packages/cli/src/commands/contexts/contexts.current.ts @@ -1,9 +1,9 @@ import { Command } from 'commander'; -import { Config } from '../../config/config.js'; +import { getApi } from '../../utils/command.js'; const current = new Command('current'); current.action(async () => { - const config = new Config(); + const { config } = getApi(current); console.log(config.context); }); diff --git a/packages/cli/src/commands/contexts/contexts.use.ts b/packages/cli/src/commands/contexts/contexts.use.ts index 56c1e22..672e080 100644 --- a/packages/cli/src/commands/contexts/contexts.use.ts +++ b/packages/cli/src/commands/contexts/contexts.use.ts @@ -1,10 +1,10 @@ import { Command } from 'commander'; -import { Config } from '../../config/config.js'; +import { getApi } from '../../utils/command.js'; const use = new Command('use'); use.argument('').action(async (name) => { - const config = new Config(); + const { config } = getApi(use); await config.setContext(name); }); diff --git a/packages/cli/src/commands/loads/loads.list.ts b/packages/cli/src/commands/loads/loads.list.ts index 0a7b4db..a6c2b1d 100644 --- a/packages/cli/src/commands/loads/loads.list.ts +++ b/packages/cli/src/commands/loads/loads.list.ts @@ -1,8 +1,5 @@ import { Command } from 'commander'; -import { createClient } from '../../client/client.js'; -import { step } from '../../utils/step.js'; -import { Context } from '../../context/context.js'; -import { Config } from '../../config/config.js'; +import { getApi } from '../../utils/command.js'; const list = new Command('list'); @@ -10,15 +7,11 @@ list .alias('ls') .description('List loads') .action(async () => { - const config = new Config(); - const context = new Context(config.context); - const client = await step('Connecting to server', async () => { - return createClient(context); - }); + const { output, step, client } = getApi(list); const loads = await step('Getting data', async () => { return await client.loads.find.query({}); }); - console.table(loads); + await output(loads); }); export { list }; diff --git a/packages/cli/src/commands/loads/loads.push.ts b/packages/cli/src/commands/loads/loads.push.ts index 9a4dd9a..5a2d0a5 100644 --- a/packages/cli/src/commands/loads/loads.push.ts +++ b/packages/cli/src/commands/loads/loads.push.ts @@ -1,10 +1,7 @@ import { Command } from 'commander'; import { resolve } from 'path'; -import { createClient } from '../../client/client.js'; import { bundle } from '../../bundler/bundler.js'; -import { step } from '../../utils/step.js'; -import { Context } from '../../context/context.js'; -import { Config } from '../../config/config.js'; +import { getApi } from '../../utils/command.js'; const push = new Command('push'); @@ -16,12 +13,8 @@ push .option('-ai, --auto-install', 'Auto install dependencies', false) .action(async (script) => { const opts = push.opts(); - const config = new Config(); - const context = new Context(config.context); + const { step, log, client } = getApi(push); const location = resolve(script); - const client = await step('Connecting to server', async () => { - return createClient(context); - }); const code = await step('Bundling', async () => { return await bundle({ entry: location, autoInstall: opts.autoInstall }); }); @@ -32,12 +25,12 @@ push script: code, }); }); - console.log('created load with id', id); + await log(`created load with id ${id}`); if (opts.run) { const runId = await step('Creating run', async () => { return await client.runs.create.mutate({ loadId: id }); }); - console.log('created run with id', runId); + await log(`created run with id ${runId}`); } }); diff --git a/packages/cli/src/commands/local/local.run.ts b/packages/cli/src/commands/local/local.run.ts index 43f14fd..c15ddaf 100644 --- a/packages/cli/src/commands/local/local.run.ts +++ b/packages/cli/src/commands/local/local.run.ts @@ -2,9 +2,8 @@ import { Command } from 'commander'; import { resolve } from 'path'; import { run as runLoad } from '@morten-olsen/mini-loader-runner'; import { bundle } from '../../bundler/bundler.js'; -import { step } from '../../utils/step.js'; import { readSecrets } from './local.utils.js'; -import { Config } from '../../config/config.js'; +import { getApi } from '../../utils/command.js'; const run = new Command('run'); @@ -12,8 +11,8 @@ run .option('-ai, --auto-install', 'Auto install dependencies', false) .argument('script') .action(async (script) => { + const { step, config } = getApi(run); const location = resolve(script); - const config = new Config(); const { autoInstall } = run.opts(); const secrets = await readSecrets(); diff --git a/packages/cli/src/commands/logs/logs.list.ts b/packages/cli/src/commands/logs/logs.list.ts index a87e8c6..f40bb73 100644 --- a/packages/cli/src/commands/logs/logs.list.ts +++ b/packages/cli/src/commands/logs/logs.list.ts @@ -1,8 +1,5 @@ import { Command } from 'commander'; -import { createClient } from '../../client/client.js'; -import { step } from '../../utils/step.js'; -import { Context } from '../../context/context.js'; -import { Config } from '../../config/config.js'; +import { getApi } from '../../utils/command.js'; const list = new Command('list'); @@ -24,11 +21,7 @@ list .option('-s, --sort ', 'Sort', 'desc') .action(async () => { const { runId, loadId, severities, offset, limit, order } = list.opts(); - const config = new Config(); - const context = new Context(config.context); - const client = await step('Connecting to server', async () => { - return createClient(context); - }); + const { step, output, client } = getApi(list); const logs = await step('Getting logs', async () => { return await client.logs.find.query({ runId, @@ -39,7 +32,7 @@ list order, }); }); - console.table(logs); + output(logs); }); export { list }; diff --git a/packages/cli/src/commands/logs/logs.remove.ts b/packages/cli/src/commands/logs/logs.remove.ts index 544fa79..dc985f0 100644 --- a/packages/cli/src/commands/logs/logs.remove.ts +++ b/packages/cli/src/commands/logs/logs.remove.ts @@ -1,9 +1,6 @@ import { Command } from 'commander'; -import { createClient } from '../../client/client.js'; -import { step } from '../../utils/step.js'; -import { Context } from '../../context/context.js'; import inquirer from 'inquirer'; -import { Config } from '../../config/config.js'; +import { getApi } from '../../utils/command.js'; const remove = new Command('remove'); @@ -24,12 +21,8 @@ remove .option('-a, --limit ', 'Limit', '1000') .option('-s, --sort ', 'Sort', 'desc') .action(async () => { + const { step, client } = getApi(remove); const { runId, loadId, severities, offset, limit, order } = remove.opts(); - const config = new Config(); - const context = new Context(config.context); - const client = await step('Connecting to server', async () => { - return createClient(context); - }); const response = await step('Preparing to delete', async () => { return await client.logs.prepareRemove.query({ runId, diff --git a/packages/cli/src/commands/runs/runs.create.ts b/packages/cli/src/commands/runs/runs.create.ts index 076a22b..0bc4c0b 100644 --- a/packages/cli/src/commands/runs/runs.create.ts +++ b/packages/cli/src/commands/runs/runs.create.ts @@ -1,8 +1,5 @@ import { Command } from 'commander'; -import { createClient } from '../../client/client.js'; -import { step } from '../../utils/step.js'; -import { Context } from '../../context/context.js'; -import { Config } from '../../config/config.js'; +import { getApi } from '../../utils/command.js'; const create = new Command('create'); @@ -10,11 +7,7 @@ create .description('Create a new run') .argument('load-id', 'Load ID') .action(async (loadId) => { - const config = new Config(); - const context = new Context(config.context); - const client = await step('Connecting to server', async () => { - return createClient(context); - }); + const { step, client } = getApi(create); await step('Creating run', async () => { await client.runs.create.mutate({ loadId }); }); diff --git a/packages/cli/src/commands/runs/runs.list.ts b/packages/cli/src/commands/runs/runs.list.ts index 7c973d8..780b2c5 100644 --- a/packages/cli/src/commands/runs/runs.list.ts +++ b/packages/cli/src/commands/runs/runs.list.ts @@ -1,8 +1,5 @@ import { Command } from 'commander'; -import { createClient } from '../../client/client.js'; -import { step } from '../../utils/step.js'; -import { Context } from '../../context/context.js'; -import { Config } from '../../config/config.js'; +import { getApi } from '../../utils/command.js'; const list = new Command('list'); @@ -11,15 +8,11 @@ list .description('Find a run') .argument('[load-id]', 'Load ID') .action(async (loadId) => { - const config = new Config(); - const context = new Context(config.context); - const client = await step('Connecting to server', async () => { - return createClient(context); - }); + const { step, output, client } = getApi(list); const runs = await step('Getting runs', async () => { return await client.runs.find.query({ loadId }); }); - console.table(runs); + await output(runs); }); export { list }; diff --git a/packages/cli/src/commands/runs/runs.remove.ts b/packages/cli/src/commands/runs/runs.remove.ts index 2670f03..a048156 100644 --- a/packages/cli/src/commands/runs/runs.remove.ts +++ b/packages/cli/src/commands/runs/runs.remove.ts @@ -1,9 +1,6 @@ import { Command } from 'commander'; -import { createClient } from '../../client/client.js'; -import { step } from '../../utils/step.js'; -import { Context } from '../../context/context.js'; import inquirer from 'inquirer'; -import { Config } from '../../config/config.js'; +import { getApi } from '../../utils/command.js'; const remove = new Command('remove'); @@ -21,12 +18,8 @@ remove .option('-o, --offset ', 'Offset') .option('-a, --limit ', 'Limit', '1000') .action(async () => { + const { step, client } = getApi(remove); const { loadId, offset, limit } = remove.opts(); - const config = new Config(); - const context = new Context(config.context); - const client = await step('Connecting to server', async () => { - return createClient(context); - }); const response = await step('Preparing to delete', async () => { return await client.runs.prepareRemove.query({ loadId, diff --git a/packages/cli/src/commands/runs/runs.terminate.ts b/packages/cli/src/commands/runs/runs.terminate.ts index 97ebba6..a449c66 100644 --- a/packages/cli/src/commands/runs/runs.terminate.ts +++ b/packages/cli/src/commands/runs/runs.terminate.ts @@ -1,8 +1,5 @@ import { Command } from 'commander'; -import { createClient } from '../../client/client.js'; -import { step } from '../../utils/step.js'; -import { Context } from '../../context/context.js'; -import { Config } from '../../config/config.js'; +import { getApi } from '../../utils/command.js'; const terminate = new Command('terminate'); @@ -10,11 +7,7 @@ terminate .description('Terminate an in progress run') .argument('run-id', 'Run ID') .action(async (runId) => { - const config = new Config(); - const context = new Context(config.context); - const client = await step('Connecting to server', async () => { - return createClient(context); - }); + const { step, client } = getApi(terminate); await step('Terminating run', async () => { await client.runs.terminate.mutate(runId); }); diff --git a/packages/cli/src/commands/schedules/schedules.add.ts b/packages/cli/src/commands/schedules/schedules.add.ts index b34aa8f..8c639e7 100644 --- a/packages/cli/src/commands/schedules/schedules.add.ts +++ b/packages/cli/src/commands/schedules/schedules.add.ts @@ -1,8 +1,5 @@ import { Command } from 'commander'; -import { createClient } from '../../client/client.js'; -import { step } from '../../utils/step.js'; -import { Context } from '../../context/context.js'; -import { Config } from '../../config/config.js'; +import { getApi } from '../../utils/command.js'; const add = new Command('add'); @@ -12,12 +9,8 @@ add .argument('', 'Cron') .option('-n, --name ', 'Name') .action(async (loadId, cron) => { - const config = new Config(); - const context = new Context(config.context); + const { step, client } = getApi(add); const { name } = add.opts(); - const client = await step('Connecting to server', async () => { - return createClient(context); - }); const id = await step('Adding schedule', async () => { return await client.schedules.add.mutate({ name, diff --git a/packages/cli/src/commands/schedules/schedules.list.ts b/packages/cli/src/commands/schedules/schedules.list.ts index 011c8f6..649d3a1 100644 --- a/packages/cli/src/commands/schedules/schedules.list.ts +++ b/packages/cli/src/commands/schedules/schedules.list.ts @@ -1,8 +1,5 @@ import { Command } from 'commander'; -import { createClient } from '../../client/client.js'; -import { step } from '../../utils/step.js'; -import { Context } from '../../context/context.js'; -import { Config } from '../../config/config.js'; +import { getApi } from '../../utils/command.js'; const list = new Command('list'); @@ -20,12 +17,8 @@ list .option('-o, --offset ', 'Offset') .option('-a, --limit ', 'Limit', '1000') .action(async () => { + const { step, output, client } = getApi(list); const { loadIds, offset, limit } = list.opts(); - const config = new Config(); - const context = new Context(config.context); - const client = await step('Connecting to server', async () => { - return createClient(context); - }); const schedules = await step('Getting schedules', async () => { return await client.schedules.find.query({ loadIds, @@ -33,7 +26,7 @@ list limit: toInt(limit), }); }); - console.table(schedules); + output(schedules); }); export { list }; diff --git a/packages/cli/src/commands/schedules/schedules.remove.ts b/packages/cli/src/commands/schedules/schedules.remove.ts index beb3d58..50f935b 100644 --- a/packages/cli/src/commands/schedules/schedules.remove.ts +++ b/packages/cli/src/commands/schedules/schedules.remove.ts @@ -1,9 +1,6 @@ import { Command } from 'commander'; -import { createClient } from '../../client/client.js'; -import { step } from '../../utils/step.js'; -import { Context } from '../../context/context.js'; import inquirer from 'inquirer'; -import { Config } from '../../config/config.js'; +import { getApi } from '../../utils/command.js'; const remove = new Command('remove'); @@ -22,12 +19,8 @@ remove .option('-o, --offset ', 'Offset') .option('-a, --limit ', 'Limit', '1000') .action(async () => { + const { step, client } = getApi(remove); const { ids, loadIds, offset, limit } = remove.opts(); - const config = new Config(); - const context = new Context(config.context); - const client = await step('Connecting to server', async () => { - return createClient(context); - }); const response = await step('Preparing to delete', async () => { return await client.schedules.prepareRemove.query({ ids, diff --git a/packages/cli/src/commands/secrets/secrets.list.ts b/packages/cli/src/commands/secrets/secrets.list.ts index c306dfd..72da5c3 100644 --- a/packages/cli/src/commands/secrets/secrets.list.ts +++ b/packages/cli/src/commands/secrets/secrets.list.ts @@ -1,8 +1,5 @@ import { Command } from 'commander'; -import { createClient } from '../../client/client.js'; -import { step } from '../../utils/step.js'; -import { Context } from '../../context/context.js'; -import { Config } from '../../config/config.js'; +import { getApi } from '../../utils/command.js'; const list = new Command('list'); @@ -15,16 +12,12 @@ const toInt = (value?: string) => { list .alias('ls') - .description('List logs') + .description('List secrets') .option('-o, --offset ', 'Offset') .option('-a, --limit ', 'Limit', '1000') .action(async () => { + const { step, client } = getApi(list); const { offset, limit } = list.opts(); - const config = new Config(); - const context = new Context(config.context); - const client = await step('Connecting to server', async () => { - return createClient(context); - }); const secrets = await step('Getting secrets', async () => { return await client.secrets.find.query({ offset: toInt(offset), diff --git a/packages/cli/src/commands/secrets/secrets.remove.ts b/packages/cli/src/commands/secrets/secrets.remove.ts index 5b9376d..8a2c59e 100644 --- a/packages/cli/src/commands/secrets/secrets.remove.ts +++ b/packages/cli/src/commands/secrets/secrets.remove.ts @@ -1,8 +1,5 @@ import { Command } from 'commander'; -import { createClient } from '../../client/client.js'; -import { step } from '../../utils/step.js'; -import { Context } from '../../context/context.js'; -import { Config } from '../../config/config.js'; +import { getApi } from '../../utils/command.js'; const remove = new Command('remove'); @@ -10,11 +7,7 @@ remove .alias('rm') .argument('') .action(async (id) => { - const config = new Config(); - const context = new Context(config.context); - const client = await step('Connecting to server', async () => { - return createClient(context); - }); + const { step, client } = getApi(remove); await step('Removing', async () => { await client.secrets.remove.mutate({ id, diff --git a/packages/cli/src/commands/secrets/secrets.set.ts b/packages/cli/src/commands/secrets/secrets.set.ts index 1da167c..7e19b80 100644 --- a/packages/cli/src/commands/secrets/secrets.set.ts +++ b/packages/cli/src/commands/secrets/secrets.set.ts @@ -1,8 +1,5 @@ import { Command } from 'commander'; -import { createClient } from '../../client/client.js'; -import { step } from '../../utils/step.js'; -import { Context } from '../../context/context.js'; -import { Config } from '../../config/config.js'; +import { getApi } from '../../utils/command.js'; const set = new Command('set'); @@ -10,11 +7,7 @@ set .argument('') .argument('[value]') .action(async (id, value) => { - const config = new Config(); - const context = new Context(config.context); - const client = await step('Connecting to server', async () => { - return createClient(context); - }); + const { step, client } = getApi(set); await step('Setting secret', async () => { await client.secrets.set.mutate({ id, diff --git a/packages/cli/src/config/config.ts b/packages/cli/src/config/config.ts index 0bbfb06..3def362 100644 --- a/packages/cli/src/config/config.ts +++ b/packages/cli/src/config/config.ts @@ -1,20 +1,22 @@ -import envPaths from 'env-paths'; -import { existsSync, readFileSync, writeFileSync } from 'fs'; -import { mkdir } from 'fs/promises'; +import { existsSync, readFileSync } from 'fs'; +import { mkdir, writeFile } from 'fs/promises'; import { join, dirname } from 'path'; +import { ContainerInstance, Service } from 'typedi'; +import { Paths } from '../paths/paths.js'; type ConfigValues = { context?: string; }; -const paths = envPaths('mini-loader'); - +@Service() class Config { + #paths: Paths; #location: string; #config?: ConfigValues; - constructor() { - this.#location = join(paths.config, 'config.json'); + constructor(contianer: ContainerInstance) { + this.#paths = contianer.get(Paths); + this.#location = join(this.#paths.config, 'config.json'); if (existsSync(this.#location)) { this.#config = JSON.parse(readFileSync(this.#location, 'utf-8')); } @@ -24,8 +26,12 @@ class Config { return this.#config?.context || 'default'; } + public get location() { + return this.#paths.config; + } + public get cacheLocation() { - return join(paths.cache, this.context); + return join(this.#paths.cache, this.context); } public setContext = (context: string) => { @@ -42,7 +48,7 @@ class Config { } const json = JSON.stringify(this.#config); mkdir(dirname(this.#location), { recursive: true }); - writeFileSync(this.#location, json); + writeFile(this.#location, json); }; } diff --git a/packages/cli/src/context/context.ts b/packages/cli/src/context/context.ts index 5630c84..63d7e33 100644 --- a/packages/cli/src/context/context.ts +++ b/packages/cli/src/context/context.ts @@ -2,6 +2,7 @@ import envPaths from 'env-paths'; import { existsSync, readFileSync } from 'fs'; import { mkdir, readdir, writeFile } from 'fs/promises'; import { dirname, join } from 'path'; +import { Config } from '../config/config.js'; type ContextValues = { host: string; @@ -12,9 +13,8 @@ class Context { #location: string; #config?: ContextValues; - constructor(name: string) { - const paths = envPaths('mini-loader'); - this.#location = join(paths.config, 'contexts', name); + constructor(config: Config) { + this.#location = join(config.location, 'contexts', config.context); if (existsSync(this.#location)) { this.#config = JSON.parse(readFileSync(this.#location, 'utf-8')); } @@ -28,13 +28,13 @@ class Context { return this.#config?.token; } - public saveLogin = (host: string, token: string) => { + public saveLogin = async (host: string, token: string) => { this.#config = { ...(this.#config || {}), host, token, }; - this.save(); + await this.save(); }; public save = async () => { diff --git a/packages/cli/src/index.ts b/packages/cli/src/index.ts index 364e892..b25bbc4 100644 --- a/packages/cli/src/index.ts +++ b/packages/cli/src/index.ts @@ -1,5 +1,4 @@ -import { Command, program } from 'commander'; -import { createRequire } from 'module'; +import { Command } from 'commander'; import { loads } from './commands/loads/loads.js'; import { runs } from './commands/runs/runs.js'; import { logs } from './commands/logs/logs.js'; @@ -9,28 +8,27 @@ import { local } from './commands/local/local.js'; import { auth } from './commands/auth/auth.js'; import { contexts } from './commands/contexts/contexts.js'; import { schedules } from './commands/schedules/schedules.js'; -import { readFile } from 'fs/promises'; +import { ContainerInstance } from 'typedi'; -const require = createRequire(import.meta.url); +const createClientCli = (container: ContainerInstance) => { + const program = new Command(); + program.exitOverride(); + program.setOptionValue('_container', container); + program.addCommand(loads); + program.addCommand(runs); + program.addCommand(logs); + program.addCommand(artifacts); + program.addCommand(secrets); + program.addCommand(local); + program.addCommand(auth); + program.addCommand(contexts); + program.addCommand(schedules); -const pkg = JSON.parse(await readFile(require.resolve('#pkg'), 'utf-8')); + return program; +}; -program.addCommand(loads); -program.addCommand(runs); -program.addCommand(logs); -program.addCommand(artifacts); -program.addCommand(secrets); -program.addCommand(local); -program.addCommand(auth); -program.addCommand(contexts); -program.addCommand(schedules); - -program.version(pkg.version); - -const version = new Command('version'); -version.action(() => { - console.log(pkg.version); -}); -program.addCommand(version); - -await program.parseAsync(); +export { CliApi } from './api/api.js'; +export { Context } from './context/context.js'; +export { Terminal } from './api/output.js'; +export { Paths } from './paths/paths.js'; +export { createClientCli }; diff --git a/packages/cli/src/paths/paths.ts b/packages/cli/src/paths/paths.ts new file mode 100644 index 0000000..075a0c2 --- /dev/null +++ b/packages/cli/src/paths/paths.ts @@ -0,0 +1,17 @@ +import envPaths from 'env-paths'; +import { Service } from 'typedi'; + +const paths = envPaths('mini-loader'); + +@Service() +class Paths { + public get config() { + return paths.config; + } + + public get cache() { + return paths.cache; + } +} + +export { Paths }; diff --git a/packages/cli/src/utils/command.ts b/packages/cli/src/utils/command.ts new file mode 100644 index 0000000..efa85bb --- /dev/null +++ b/packages/cli/src/utils/command.ts @@ -0,0 +1,11 @@ +import { Command } from 'commander'; +import { ContainerInstance } from 'typedi'; +import { CliApi } from '../api/api.js'; + +const getApi = (command: Command) => { + const { _container } = command.optsWithGlobals() as { _container: ContainerInstance }; + const api = _container.get(CliApi); + return api; +}; + +export { getApi }; diff --git a/packages/cli/src/utils/step.ts b/packages/cli/src/utils/step.ts deleted file mode 100644 index 2f63ff5..0000000 --- a/packages/cli/src/utils/step.ts +++ /dev/null @@ -1,15 +0,0 @@ -import ora from 'ora'; - -const step = async (message: string, fn: () => Promise): Promise => { - const spinner = ora(message).start(); - try { - const result = await fn(); - await spinner.succeed(); - return result; - } catch (err) { - await spinner.fail(); - throw err; - } -}; - -export { step }; diff --git a/packages/configs/tsconfig.esm.json b/packages/configs/tsconfig.esm.json index 6e43206..58db429 100644 --- a/packages/configs/tsconfig.esm.json +++ b/packages/configs/tsconfig.esm.json @@ -7,6 +7,7 @@ "declarationMap": true, "sourceMap": true, "esModuleInterop": true, + "experimentalDecorators": true, "strict": true, "resolveJsonModule": true, "allowSyntheticDefaultImports": true, diff --git a/packages/server/bin/index.mjs b/packages/server/bin/index.mjs index efb0ee3..a13dc09 100755 --- a/packages/server/bin/index.mjs +++ b/packages/server/bin/index.mjs @@ -1,4 +1,4 @@ #!/usr/bin/env node import 'source-map-support/register.js'; -import '../dist/esm/index.js'; +import '../dist/esm/bin.js'; diff --git a/packages/server/package.json b/packages/server/package.json index 25c7d20..47ce7a6 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -41,9 +41,11 @@ "jsonwebtoken": "^9.0.2", "knex": "^3.1.0", "nanoid": "^5.0.4", + "reflect-metadata": "^0.2.1", "source-map-support": "^0.5.21", "sqlite3": "^5.1.7", "superjson": "^2.2.1", + "typedi": "^0.10.0", "zod": "^3.22.4" }, "homepage": "https://github.com/morten-olsen/mini-loader", diff --git a/packages/server/src/auth/auth.ts b/packages/server/src/auth/auth.ts index f4b94ff..b85bc92 100644 --- a/packages/server/src/auth/auth.ts +++ b/packages/server/src/auth/auth.ts @@ -4,17 +4,21 @@ import { existsSync } from 'fs'; import { mkdir, readFile, writeFile } from 'fs/promises'; import jwt from 'jsonwebtoken'; import { Config } from '../config/config.js'; +import { ContainerInstance, Service } from 'typedi'; type AuthOptions = { config: Config; }; +@Service() class Auth { #options: AuthOptions; #data: Promise<{ secret: string }>; - constructor(options: AuthOptions) { - this.#options = options; + constructor(container: ContainerInstance) { + this.#options = { + config: container.get(Config), + }; this.#data = this.#setup(); } diff --git a/packages/server/src/bin.ts b/packages/server/src/bin.ts new file mode 100644 index 0000000..578f1ab --- /dev/null +++ b/packages/server/src/bin.ts @@ -0,0 +1,14 @@ +import { ContainerInstance } from 'typedi'; +import { createServerCli } from './index.js'; + +const program = createServerCli(new ContainerInstance('server')); + +program.setOptionValue('output', (data: unknown) => { + console.log('got data', data); +}); + +await program.parseAsync(process.argv); + +process.on('unhandledRejection', (reason, p) => { + console.log('Unhandled Rejection at: Promise', p, 'reason:', reason); +}); diff --git a/packages/server/src/config/config.ts b/packages/server/src/config/config.ts index d82551d..053e1b7 100644 --- a/packages/server/src/config/config.ts +++ b/packages/server/src/config/config.ts @@ -1,10 +1,22 @@ import { Knex } from 'knex'; +import { Service } from 'typedi'; +import envPaths from 'env-paths'; +import { join } from 'path'; -type Config = { - database: Omit; - files: { - data: string; - cache: string; +const paths = envPaths('mini-loader-server'); + +@Service() +class Config { + database: Omit = { + client: 'sqlite3', + connection: { + filename: join(paths.data, 'db.sqlite'), + }, + useNullAsDefault: true, + }; + files = { + data: paths.data, + cache: paths.cache, }; auth?: { oidc?: { @@ -15,6 +27,6 @@ type Config = { }; }; }; -}; +} -export type { Config }; +export { Config }; diff --git a/packages/server/src/database/database.ts b/packages/server/src/database/database.ts index acfe5eb..7210174 100644 --- a/packages/server/src/database/database.ts +++ b/packages/server/src/database/database.ts @@ -1,5 +1,7 @@ import knex, { Knex } from 'knex'; +import { Service, ContainerInstance } from 'typedi'; +import { Config } from '../config/config.js'; import { source } from './migrations/migrations.source.js'; import { mkdir } from 'fs/promises'; import { dirname } from 'path'; @@ -8,13 +10,15 @@ const tableNames = { loads: 'loads', }; +@Service() class Database { #instance?: Promise; #config: Knex.Config; - constructor(config: Knex.Config) { + constructor(container: ContainerInstance) { + const config = container.get(Config); this.#config = { - ...config, + ...config.database, migrations: { migrationSource: source, }, diff --git a/packages/server/src/id/id.ts b/packages/server/src/id/id.ts new file mode 100644 index 0000000..cafd515 --- /dev/null +++ b/packages/server/src/id/id.ts @@ -0,0 +1,9 @@ +import { nanoid } from 'nanoid'; +import { Service } from 'typedi'; + +@Service() +class IdGenerator { + public generate = () => nanoid(); +} + +export { IdGenerator }; diff --git a/packages/server/src/index.ts b/packages/server/src/index.ts index 9464004..5429a9f 100644 --- a/packages/server/src/index.ts +++ b/packages/server/src/index.ts @@ -1,40 +1,42 @@ -import { program, Command } from 'commander'; +import 'reflect-metadata'; +import { Command } from 'commander'; import { Runtime } from './runtime/runtime.js'; import { createServer } from './server/server.js'; +import { ContainerInstance } from 'typedi'; -const start = new Command('start'); -start.action(async () => { - const port = 4500; - const runtime = await Runtime.create(); - await runtime.scheduler.start(); - const server = await createServer(runtime); - await server.listen({ - port, - host: '0.0.0.0', +const createServerCli = (container: ContainerInstance) => { + const program = new Command(); + + const start = new Command('start'); + start.action(async () => { + const port = 4500; + const runtime = container.get(Runtime); + await runtime.scheduler.start(); + const server = await createServer(container); + await server.listen({ + port, + host: '0.0.0.0', + }); + + console.log(`Server listening on port ${port}`); }); - console.log(`Server listening on port ${port}`); -}); - -const createToken = new Command('create-token'); -createToken.action(async () => { - const runtime = await Runtime.create(); - const token = await runtime.auth.createToken({ - policy: { - '*:*': ['*'], - }, + const createToken = new Command('create-token'); + createToken.action(async () => { + const runtime = container.get(Runtime); + const token = await runtime.auth.createToken({ + policy: { + '*:*': ['*'], + }, + }); + console.log(token); }); - console.log(token); -}); -program.addCommand(start); -program.addCommand(createToken); + program.addCommand(start); + program.addCommand(createToken); + return program; +}; -await program.parseAsync(process.argv); - -process.on('unhandledRejection', (reason, p) => { - console.log('Unhandled Rejection at: Promise', p, 'reason:', reason); -}); - -export type { Runtime } from './runtime/runtime.js'; +export { createServerCli, createServer, Runtime }; +export { Config } from './config/config.js'; export type { RootRouter } from './router/router.js'; diff --git a/packages/server/src/repos/artifacts/artifacts.ts b/packages/server/src/repos/artifacts/artifacts.ts index 13544e4..42cb277 100644 --- a/packages/server/src/repos/artifacts/artifacts.ts +++ b/packages/server/src/repos/artifacts/artifacts.ts @@ -1,21 +1,27 @@ import { EventEmitter } from 'eventemitter3'; import { Database } from '../../database/database.js'; -import { nanoid } from 'nanoid'; import { AddArtifactOptions, FindArtifactsOptions } from './artifacts.schemas.js'; import { createHash } from 'crypto'; +import { ContainerInstance, Service } from 'typedi'; +import { IdGenerator } from '../../id/id.js'; type ArtifactRepoEvents = {}; type ArtifactRepoOptions = { database: Database; + idGenerator: IdGenerator; }; +@Service() class ArtifactRepo extends EventEmitter { #options: ArtifactRepoOptions; - constructor(options: ArtifactRepoOptions) { + constructor(container: ContainerInstance) { super(); - this.#options = options; + this.#options = { + database: container.get(Database), + idGenerator: container.get(IdGenerator), + }; } public get = async (id: string) => { @@ -26,9 +32,9 @@ class ArtifactRepo extends EventEmitter { }; public add = async (options: AddArtifactOptions) => { - const { database } = this.#options; + const { database, idGenerator } = this.#options; const db = await database.instance; - const id = nanoid(); + const id = idGenerator.generate(); await db('artifacts').insert({ id, diff --git a/packages/server/src/repos/loads/loads.ts b/packages/server/src/repos/loads/loads.ts index 6562ed7..39c70e2 100644 --- a/packages/server/src/repos/loads/loads.ts +++ b/packages/server/src/repos/loads/loads.ts @@ -1,11 +1,12 @@ import { EventEmitter } from 'eventemitter3'; import { Database } from '../../database/database.js'; import { FindLoadsOptions, SetLoadOptions } from './loads.schemas.js'; -import { nanoid } from 'nanoid'; import { createHash } from 'crypto'; import { Config } from '../../config/config.js'; import { mkdir, writeFile } from 'fs/promises'; import { resolve } from 'path'; +import { ContainerInstance, Service } from 'typedi'; +import { IdGenerator } from '../../id/id.js'; type LoadRepoEvents = { created: (id: string) => void; @@ -16,14 +17,20 @@ type LoadRepoEvents = { type LoadRepoOptions = { database: Database; config: Config; + idGenerator: IdGenerator; }; +@Service() class LoadRepo extends EventEmitter { #options: LoadRepoOptions; - constructor(options: LoadRepoOptions) { + constructor(container: ContainerInstance) { super(); - this.#options = options; + this.#options = { + database: container.get(Database), + config: container.get(Config), + idGenerator: container.get(IdGenerator), + }; } public getById = async (id: string) => { @@ -58,9 +65,9 @@ class LoadRepo extends EventEmitter { }; public set = async (options: SetLoadOptions) => { - const { database } = this.#options; + const { database, idGenerator } = this.#options; const db = await database.instance; - const id = options.id || nanoid(); + const id = options.id || idGenerator.generate(); const script = createHash('sha256').update(options.script).digest('hex'); const scriptDir = resolve(this.#options.config.files.data, 'scripts'); await mkdir(scriptDir, { recursive: true }); diff --git a/packages/server/src/repos/logs/logs.ts b/packages/server/src/repos/logs/logs.ts index ed090dd..b8dfe9b 100644 --- a/packages/server/src/repos/logs/logs.ts +++ b/packages/server/src/repos/logs/logs.ts @@ -1,27 +1,33 @@ import { EventEmitter } from 'eventemitter3'; import { Database } from '../../database/database.js'; import { AddLogOptions, FindLogsOptions } from './logs.schemas.js'; -import { nanoid } from 'nanoid'; import { createHash } from 'crypto'; +import { ContainerInstance, Service } from 'typedi'; +import { IdGenerator } from '../../id/id.js'; type LogRepoEvents = {}; type LogRepoOptions = { database: Database; + idGenerator: IdGenerator; }; +@Service() class LogRepo extends EventEmitter { #options: LogRepoOptions; - constructor(options: LogRepoOptions) { + constructor(container: ContainerInstance) { super(); - this.#options = options; + this.#options = { + database: container.get(Database), + idGenerator: container.get(IdGenerator), + }; } public add = async (options: AddLogOptions) => { - const { database } = this.#options; + const { database, idGenerator } = this.#options; const db = await database.instance; - const id = nanoid(); + const id = idGenerator.generate(); await db('logs').insert({ id, diff --git a/packages/server/src/repos/repos.ts b/packages/server/src/repos/repos.ts index 40c94c1..5221d86 100644 --- a/packages/server/src/repos/repos.ts +++ b/packages/server/src/repos/repos.ts @@ -1,5 +1,4 @@ -import { Config } from '../config/config.js'; -import { Database } from '../database/database.js'; +import { ContainerInstance, Service } from 'typedi'; import { ArtifactRepo } from './artifacts/artifacts.js'; import { LoadRepo } from './loads/loads.js'; import { LogRepo } from './logs/logs.js'; @@ -7,64 +6,36 @@ import { RunRepo } from './runs/runs.js'; import { ScheduleRepo } from './schedules/schedules.js'; import { SecretRepo } from './secrets/secrets.js'; -type ReposOptions = { - database: Database; - config: Config; -}; - +@Service() class Repos { - #loads: LoadRepo; - #runs: RunRepo; - #logs: LogRepo; - #artifacts: ArtifactRepo; - #secrets: SecretRepo; - #schedule: ScheduleRepo; + #container: ContainerInstance; - constructor({ database, config }: ReposOptions) { - this.#loads = new LoadRepo({ - database, - config, - }); - this.#runs = new RunRepo({ - database, - loads: this.#loads, - }); - this.#logs = new LogRepo({ - database, - }); - this.#artifacts = new ArtifactRepo({ - database, - }); - this.#secrets = new SecretRepo({ - database, - }); - this.#schedule = new ScheduleRepo({ - database, - }); + constructor(container: ContainerInstance) { + this.#container = container; } public get loads() { - return this.#loads; + return this.#container.get(LoadRepo); } public get runs() { - return this.#runs; + return this.#container.get(RunRepo); } public get logs() { - return this.#logs; + return this.#container.get(LogRepo); } public get artifacts() { - return this.#artifacts; + return this.#container.get(ArtifactRepo); } public get secrets() { - return this.#secrets; + return this.#container.get(SecretRepo); } public get schedules() { - return this.#schedule; + return this.#container.get(ScheduleRepo); } } diff --git a/packages/server/src/repos/runs/runs.ts b/packages/server/src/repos/runs/runs.ts index 46d867b..453b724 100644 --- a/packages/server/src/repos/runs/runs.ts +++ b/packages/server/src/repos/runs/runs.ts @@ -1,9 +1,10 @@ -import { nanoid } from 'nanoid'; import { EventEmitter } from 'eventemitter3'; import { Database } from '../../database/database.js'; import { CreateRunOptions, FindRunsOptions, UpdateRunOptions } from './runs.schemas.js'; import { LoadRepo } from '../loads/loads.js'; import { createHash } from 'crypto'; +import { ContainerInstance, Service } from 'typedi'; +import { IdGenerator } from '../../id/id.js'; type RunRepoEvents = { created: (args: { id: string; loadId: string }) => void; @@ -15,16 +16,21 @@ type RunRepoEvents = { type RunRepoOptions = { database: Database; loads: LoadRepo; + idGenerator: IdGenerator; }; +@Service() class RunRepo extends EventEmitter { #options: RunRepoOptions; - #isReady: Promise; + #isSetup?: Promise; - constructor(options: RunRepoOptions) { + constructor(container: ContainerInstance) { super(); - this.#options = options; - this.#isReady = this.#setup(); + this.#options = { + database: container.get(Database), + loads: container.get(LoadRepo), + idGenerator: container.get(IdGenerator), + }; } #setup = async () => { @@ -33,6 +39,13 @@ class RunRepo extends EventEmitter { await db('runs').update({ status: 'failed', error: 'server was shut down' }).where({ status: 'running' }); }; + get #isReady() { + if (!this.#isSetup) { + this.#isSetup = this.#setup(); + } + return this.#isSetup; + } + public getById = async (id: string) => { await this.#isReady; const { database } = this.#options; @@ -150,8 +163,8 @@ class RunRepo extends EventEmitter { public create = async (options: CreateRunOptions) => { await this.#isReady; - const { database, loads } = this.#options; - const id = nanoid(); + const { database, loads, idGenerator } = this.#options; + const id = idGenerator.generate(); const db = await database.instance; const script = await loads.getScript(options.loadId); diff --git a/packages/server/src/repos/schedules/schedules.ts b/packages/server/src/repos/schedules/schedules.ts index 9c25f50..d1a232a 100644 --- a/packages/server/src/repos/schedules/schedules.ts +++ b/packages/server/src/repos/schedules/schedules.ts @@ -1,8 +1,9 @@ import { EventEmitter } from 'eventemitter3'; import { Database } from '../../database/database.js'; -import { nanoid } from 'nanoid'; import { AddScheduleOptions, FindSchedulesOptions } from './schedules.schemas.js'; import { createHash } from 'crypto'; +import { ContainerInstance, Service } from 'typedi'; +import { IdGenerator } from '../../id/id.js'; type ScheduleRepoEvents = { added: (id: string) => void; @@ -11,14 +12,19 @@ type ScheduleRepoEvents = { type ScheduleRepoOptions = { database: Database; + idGenerator: IdGenerator; }; +@Service() class ScheduleRepo extends EventEmitter { #options: ScheduleRepoOptions; - constructor(options: ScheduleRepoOptions) { + constructor(container: ContainerInstance) { super(); - this.#options = options; + this.#options = { + database: container.get(Database), + idGenerator: container.get(IdGenerator), + }; } public get = async (id: string) => { @@ -29,9 +35,9 @@ class ScheduleRepo extends EventEmitter { }; public add = async (options: AddScheduleOptions) => { - const { database } = this.#options; + const { database, idGenerator } = this.#options; const db = await database.instance; - const id = nanoid(); + const id = idGenerator.generate(); await db('schedules').insert({ id, diff --git a/packages/server/src/repos/secrets/secrets.ts b/packages/server/src/repos/secrets/secrets.ts index 3fb2cff..9cd1c35 100644 --- a/packages/server/src/repos/secrets/secrets.ts +++ b/packages/server/src/repos/secrets/secrets.ts @@ -1,6 +1,7 @@ import { EventEmitter } from 'eventemitter3'; import { Database } from '../../database/database.js'; import { FindSecretOptions, SetSecretOptions } from './secrets.schemas.js'; +import { ContainerInstance, Service } from 'typedi'; type LogRepoEvents = {}; @@ -8,12 +9,15 @@ type LogRepoOptions = { database: Database; }; +@Service() class SecretRepo extends EventEmitter { #options: LogRepoOptions; - constructor(options: LogRepoOptions) { + constructor(container: ContainerInstance) { super(); - this.#options = options; + this.#options = { + database: container.get(Database), + }; } public set = async (options: SetSecretOptions) => { diff --git a/packages/server/src/router/router.utils.ts b/packages/server/src/router/router.utils.ts index dbc7fd0..236047d 100644 --- a/packages/server/src/router/router.utils.ts +++ b/packages/server/src/router/router.utils.ts @@ -2,13 +2,15 @@ import { initTRPC } from '@trpc/server'; import { CreateFastifyContextOptions } from '@trpc/server/adapters/fastify'; import superjson from 'superjson'; import { Runtime } from '../runtime/runtime.js'; +import { ContainerInstance } from 'typedi'; type ContextOptions = { - runtime: Runtime; + container: ContainerInstance; }; -const createContext = async ({ runtime }: ContextOptions) => { +const createContext = async ({ container }: ContextOptions) => { return async ({ req }: CreateFastifyContextOptions) => { + const runtime = container.get(Runtime); const { authorization } = req.headers; const { auth } = runtime; if (!authorization) { @@ -18,6 +20,7 @@ const createContext = async ({ runtime }: ContextOptions) => { await auth.validateToken(token); return { runtime, + container, }; }; }; diff --git a/packages/server/src/runner/runner.ts b/packages/server/src/runner/runner.ts index ec585ef..138f5b0 100644 --- a/packages/server/src/runner/runner.ts +++ b/packages/server/src/runner/runner.ts @@ -1,3 +1,4 @@ +import { ContainerInstance, Service } from 'typedi'; import { Config } from '../config/config.js'; import { Repos } from '../repos/repos.js'; import { RunnerInstance } from './runner.instance.js'; @@ -7,13 +8,17 @@ type RunnerOptions = { config: Config; }; +@Service() class Runner { #options: RunnerOptions; #instances: Map = new Map(); - constructor(options: RunnerOptions) { - this.#options = options; - const { repos } = options; + constructor(container: ContainerInstance) { + this.#options = { + repos: container.get(Repos), + config: container.get(Config), + }; + const { repos } = this.#options; repos.runs.on('created', this.#start); } diff --git a/packages/server/src/runtime/runtime.ts b/packages/server/src/runtime/runtime.ts index a33faa4..6a15823 100644 --- a/packages/server/src/runtime/runtime.ts +++ b/packages/server/src/runtime/runtime.ts @@ -1,26 +1,21 @@ -import { resolve } from 'path'; -import envPaths from 'env-paths'; -import { Database } from '../database/database.js'; +import { ContainerInstance, Service } from 'typedi'; import { Repos } from '../repos/repos.js'; import { Runner } from '../runner/runner.js'; -import { Config } from '../config/config.js'; import { Auth } from '../auth/auth.js'; import { Scheduler } from '../scheduler/scheduler.js'; -const paths = envPaths('mini-loader-server'); - +@Service() class Runtime { #repos: Repos; #runner: Runner; #auth: Auth; #scheduler: Scheduler; - constructor(options: Config) { - const database = new Database(options.database); - this.#repos = new Repos({ database, config: options }); - this.#runner = new Runner({ repos: this.#repos, config: options }); - this.#auth = new Auth({ config: options }); - this.#scheduler = new Scheduler({ runs: this.#repos.runs, schedules: this.#repos.schedules }); + constructor(container: ContainerInstance) { + this.#repos = container.get(Repos); + this.#runner = container.get(Runner); + this.#auth = container.get(Auth); + this.#scheduler = container.get(Scheduler); } public get repos() { @@ -38,24 +33,6 @@ class Runtime { public get scheduler() { return this.#scheduler; } - - public static create = async () => { - const runtime = new Runtime({ - database: { - client: 'sqlite3', - connection: { - filename: resolve(paths.data, 'database.sqlite'), - }, - useNullAsDefault: true, - }, - files: { - data: process.env.DATA_DIR || resolve(paths.data, 'data', 'files'), - cache: process.env.CACHE_DIR || resolve(paths.cache, 'data', 'cache'), - }, - }); - - return runtime; - }; } export { Runtime }; diff --git a/packages/server/src/scheduler/scheduler.ts b/packages/server/src/scheduler/scheduler.ts index fb53f02..90cbabf 100644 --- a/packages/server/src/scheduler/scheduler.ts +++ b/packages/server/src/scheduler/scheduler.ts @@ -1,6 +1,7 @@ import { CronJob } from 'cron'; import { ScheduleRepo } from '../repos/schedules/schedules.js'; import { RunRepo } from '../repos/runs/runs.js'; +import { ContainerInstance, Service } from 'typedi'; type SchedulerOptions = { runs: RunRepo; @@ -13,12 +14,16 @@ type RunningSchedule = { stop: () => Promise; }; +@Service() class Scheduler { #running: RunningSchedule[] = []; #options: SchedulerOptions; - constructor(options: SchedulerOptions) { - this.#options = options; + constructor(container: ContainerInstance) { + this.#options = { + runs: container.get(RunRepo), + schedules: container.get(ScheduleRepo), + }; const { schedules } = this.#options; schedules.on('added', this.#add); schedules.on('removed', this.#remove); diff --git a/packages/server/src/server/server.ts b/packages/server/src/server/server.ts index f4e7ab3..2e09761 100644 --- a/packages/server/src/server/server.ts +++ b/packages/server/src/server/server.ts @@ -2,17 +2,12 @@ import { fastifyTRPCPlugin, FastifyTRPCPluginOptions } from '@trpc/server/adapte import fastify from 'fastify'; import { RootRouter, rootRouter } from '../router/router.js'; import { createContext } from '../router/router.utils.js'; -import { Runtime } from '../runtime/runtime.js'; import { gateway } from '../gateway/gateway.js'; -import { createRequire } from 'module'; -import { readFile } from 'fs/promises'; - -const require = createRequire(import.meta.url); - -const createServer = async (runtime: Runtime) => { - const pkgLocation = require.resolve('#pkg'); - const pkg = JSON.parse(await readFile(pkgLocation, 'utf-8')); +import { ContainerInstance } from 'typedi'; +import { Runtime } from '../runtime/runtime.js'; +const createServer = async (container: ContainerInstance) => { + const runtime = container.get(Runtime); const server = fastify({ maxParamLength: 10000, bodyLimit: 30 * 1024 * 1024, @@ -31,14 +26,14 @@ const createServer = async (runtime: Runtime) => { authorized = true; } } catch (error) {} - return { authorized, status: 'ok', version: pkg.version }; + return { authorized, status: 'ok' }; }); server.register(fastifyTRPCPlugin, { prefix: '/trpc', trpcOptions: { router: rootRouter, - createContext: await createContext({ runtime }), + createContext: await createContext({ container }), onError({ error }) { console.error(error); }, diff --git a/packages/tests/.gitignore b/packages/tests/.gitignore new file mode 100644 index 0000000..a9acb1f --- /dev/null +++ b/packages/tests/.gitignore @@ -0,0 +1,4 @@ +/dist/ +/node_modules/ +/coverage/ +/e2e-tmp/ \ No newline at end of file diff --git a/packages/tests/README.md b/packages/tests/README.md new file mode 100644 index 0000000..5c0aaf7 --- /dev/null +++ b/packages/tests/README.md @@ -0,0 +1 @@ +[Go to documentation](https://github.com/morten-olsen/mini-loader) diff --git a/packages/tests/assets/simple.js b/packages/tests/assets/simple.js new file mode 100644 index 0000000..7e2984c --- /dev/null +++ b/packages/tests/assets/simple.js @@ -0,0 +1 @@ +console.log('simple'); diff --git a/packages/tests/package.json b/packages/tests/package.json new file mode 100644 index 0000000..933debf --- /dev/null +++ b/packages/tests/package.json @@ -0,0 +1,40 @@ +{ + "name": "@morten-olsen/mini-loader-tests", + "private": "true", + "version": "1.0.0", + "license": "GPL-3.0", + "main": "./dist/esm/index.js", + "types": "./dist/esm/index.d.ts", + "type": "module", + "files": [ + "./dist" + ], + "exports": { + ".": { + "import": "./dist/esm/index.js" + } + }, + "devDependencies": { + "@morten-olsen/mini-loader-configs": "workspace:^", + "@types/node": "^20.10.8", + "fastify": "^4.25.2", + "sqlite3": "^5.1.7", + "typescript": "^5.3.3", + "vite": "^5.0.11" + }, + "dependencies": { + "@morten-olsen/mini-loader": "workspace:^", + "@morten-olsen/mini-loader-cli": "workspace:^", + "@morten-olsen/mini-loader-server": "workspace:^", + "get-port": "^7.0.0", + "memfs": "^4.6.0", + "nanoid": "^5.0.4", + "typedi": "^0.10.0", + "vitest": "^1.2.0" + }, + "homepage": "https://github.com/morten-olsen/mini-loader", + "repository": { + "type": "git", + "url": "https://github.com/morten-olsen/mini-loader" + } +} diff --git a/packages/tests/src/quick-start.test.ts b/packages/tests/src/quick-start.test.ts new file mode 100644 index 0000000..03c45e3 --- /dev/null +++ b/packages/tests/src/quick-start.test.ts @@ -0,0 +1,56 @@ +import { describe, it, beforeAll, afterAll, vi } from 'vitest'; +import { TestEnv, createEnv } from './utils/env.js'; +import { writeFile } from 'fs/promises'; +import { resolve } from 'path'; + +const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); + +describe('Quick start', () => { + let env: TestEnv; + + beforeAll(async () => { + vi.mock('nanoid', () => { + let currentId = 0; + return { + nanoid: () => `id-${currentId++}`, + }; + }); + env = await createEnv(); + }); + + afterAll(async () => { + vi.clearAllMocks(); + await env.cleanup(); + }); + + it('should be able to start the server', async () => { + const { server, port } = env; + await server.listen({ port }); + }); + + it('should be able to login', async () => { + const { clientRun, port, token } = env; + await clientRun(['auth', 'login', '--host', `http://localhost:${port}`, '--token', token]); + }); + + it('should be able to push a load', async () => { + const { clientRun, location } = env; + const scriptPath = resolve(location, 'simple.js'); + await writeFile(scriptPath, 'console.log("hello world")', 'utf-8'); + await clientRun(['loads', 'push', scriptPath, '-i', 'demo', '-r']); + + await sleep(100); + }); + + it('should be able to get the run', async () => { + const { clientRun } = env; + await clientRun(['runs', 'ls', 'demo']); + }); + + it('should be able to get logs', async () => { + const { clientRun, clientOutput } = env; + await clientRun(['logs', 'ls', '-l', 'demo']); + + console.log(JSON.stringify(clientOutput, null, 2)); + }); +}); diff --git a/packages/tests/src/utils/env.ts b/packages/tests/src/utils/env.ts new file mode 100644 index 0000000..64dc328 --- /dev/null +++ b/packages/tests/src/utils/env.ts @@ -0,0 +1,136 @@ +import { Paths, Terminal, createClientCli } from '@morten-olsen/mini-loader-cli'; +import { Runtime, createServer, Config } from '@morten-olsen/mini-loader-server'; +import { FastifyInstance } from 'fastify'; +import { ContainerInstance } from 'typedi'; +import { join, resolve } from 'path'; +import getPort from 'get-port'; +import { rm } from 'fs/promises'; + +const cacheLocation = './e2e-tmp'; + +const getUniqueIdentifier = () => { + return Math.random().toString(36).substr(2, 9); +}; + +type CliActionOutput = + | { + type: 'stdout'; + data: string; + } + | { + type: 'stderr'; + data: string; + } + | { + type: 'step'; + message: string; + state: 'pending' | 'success' | 'error'; + } + | { + type: 'output'; + data: unknown; + }; + +const createEnv = async () => { + const location = resolve(cacheLocation, getUniqueIdentifier()); + const port = await getPort(); + + let clientOutput: CliActionOutput[] = []; + const serverContainer = new ContainerInstance(getUniqueIdentifier()); + + const clientRun = async (params: string[]) => { + const clientContainer = new ContainerInstance(getUniqueIdentifier()); + clientContainer.set(Paths, { + config: join(location, 'client', 'config'), + cache: join(location, 'client', 'cache'), + }); + clientContainer.set(Terminal, { + log: async (message: any) => { + clientOutput.push({ + type: 'stdout', + data: message, + }); + }, + output: async (data: any) => { + clientOutput.push({ + type: 'output', + data, + }); + }, + step: async (message: any, action: any) => { + clientOutput.push({ + type: 'step', + message, + state: 'pending', + }); + try { + const result = await action(); + clientOutput.push({ + type: 'step', + message, + state: 'success', + }); + return result; + } catch (err) { + clientOutput.push({ + type: 'step', + message, + state: 'error', + }); + throw err; + } + }, + }); + const client = createClientCli(clientContainer); + client.configureOutput({ + writeOut: (data) => { + clientOutput.push({ + type: 'stdout', + data, + }); + }, + writeErr: (data) => { + clientOutput.push({ + type: 'stderr', + data, + }); + throw new Error(`Error in client ${data}`); + }, + }); + + await client.parseAsync(['', '', ...params]); + }; + + serverContainer.set(Config, { + database: { + client: 'sqlite3', + connection: { + filename: join(location, 'server', 'data', 'db.sqlite'), + }, + useNullAsDefault: true, + }, + files: { + data: join(location, 'server', 'data'), + cache: join(location, 'server', 'cache'), + }, + }); + const server = await createServer(serverContainer); + const runtime = serverContainer.get(Runtime); + const token = await runtime.auth.createToken({ + policy: { + '*:*': ['*'], + }, + }); + + const cleanup = async () => { + await server.close(); + await rm(location, { recursive: true, force: true }); + }; + + return { clientRun, clientOutput, runtime, server, token, location, port, cleanup }; +}; + +type TestEnv = Awaited>; + +export type { TestEnv, FastifyInstance }; +export { createEnv }; diff --git a/packages/tests/tsconfig.json b/packages/tests/tsconfig.json new file mode 100644 index 0000000..067be8e --- /dev/null +++ b/packages/tests/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "@morten-olsen/mini-loader-configs/tsconfig.esm.json", + "compilerOptions": { + "outDir": "dist/esm", + }, + "include": [ + "src" + ], +} \ No newline at end of file diff --git a/packages/tests/vitest.config.ts b/packages/tests/vitest.config.ts new file mode 100644 index 0000000..d5c4d13 --- /dev/null +++ b/packages/tests/vitest.config.ts @@ -0,0 +1,22 @@ +/// + +import { createRequire } from 'module'; +import { defineConfig } from 'vite'; + +const require = createRequire(import.meta.url); + +const server = require.resolve('../server/src/index.ts'); +const cli = require.resolve('../cli/src/index.ts'); +const runner = require.resolve('../runner/src/index.ts'); +const sdk = require.resolve('../mini-loader/src/index.ts'); + +export default defineConfig({ + test: { + alias: { + '@morten-olsen/mini-loader-server': server, + '@morten-olsen/mini-loader-cli': cli, + '@morten-olsen/mini-loader-runner': runner, + '@morten-olsen/mini-loader': sdk, + }, + }, +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8a18692..73e9180 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -17,10 +17,16 @@ importers: ts-node: specifier: ^10.9.2 version: 10.9.2(@types/node@20.10.8)(typescript@5.3.3) + vitest: + specifier: ^1.2.0 + version: 1.2.0(@types/node@20.10.8) devDependencies: '@react-native-community/eslint-config': specifier: ^3.2.0 version: 3.2.0(eslint@8.56.0)(prettier@2.8.8)(typescript@5.3.3) + '@vitest/coverage-v8': + specifier: ^1.2.0 + version: 1.2.0(vitest@1.2.0) eslint: specifier: ^8.53.0 version: 8.56.0 @@ -33,6 +39,9 @@ importers: typescript: specifier: ^5.3.3 version: 5.3.3 + vite: + specifier: ^5.0.11 + version: 5.0.11(@types/node@20.10.8) packages/cli: dependencies: @@ -90,6 +99,9 @@ importers: superjson: specifier: ^2.2.1 version: 2.2.1 + typedi: + specifier: ^0.10.0 + version: 0.10.0 devDependencies: '@morten-olsen/mini-loader-configs': specifier: workspace:^ @@ -197,6 +209,9 @@ importers: nanoid: specifier: ^5.0.4 version: 5.0.4 + reflect-metadata: + specifier: ^0.2.1 + version: 0.2.1 source-map-support: specifier: ^0.5.21 version: 0.5.21 @@ -206,6 +221,9 @@ importers: superjson: specifier: ^2.2.1 version: 2.2.1 + typedi: + specifier: ^0.10.0 + version: 0.10.0 zod: specifier: ^3.22.4 version: 3.22.4 @@ -223,6 +241,52 @@ importers: specifier: ^5.3.3 version: 5.3.3 + packages/tests: + dependencies: + '@morten-olsen/mini-loader': + specifier: workspace:^ + version: link:../mini-loader + '@morten-olsen/mini-loader-cli': + specifier: workspace:^ + version: link:../cli + '@morten-olsen/mini-loader-server': + specifier: workspace:^ + version: link:../server + get-port: + specifier: ^7.0.0 + version: 7.0.0 + memfs: + specifier: ^4.6.0 + version: 4.6.0(quill-delta@5.1.0)(rxjs@7.8.1)(tslib@2.6.2) + nanoid: + specifier: ^5.0.4 + version: 5.0.4 + typedi: + specifier: ^0.10.0 + version: 0.10.0 + vitest: + specifier: ^1.2.0 + version: 1.2.0(@types/node@20.10.8) + devDependencies: + '@morten-olsen/mini-loader-configs': + specifier: workspace:^ + version: link:../configs + '@types/node': + specifier: ^20.10.8 + version: 20.10.8 + fastify: + specifier: ^4.25.2 + version: 4.25.2 + sqlite3: + specifier: ^5.1.7 + version: 5.1.7 + typescript: + specifier: ^5.3.3 + version: 5.3.3 + vite: + specifier: ^5.0.11 + version: 5.0.11(@types/node@20.10.8) + packages: /@aashutoshrathi/word-wrap@1.2.6: @@ -440,6 +504,10 @@ packages: to-fast-properties: 2.0.0 dev: true + /@bcoe/v8-coverage@0.2.3: + resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + dev: true + /@cspotcode/source-map-support@0.8.1: resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} @@ -447,6 +515,190 @@ packages: '@jridgewell/trace-mapping': 0.3.9 dev: false + /@esbuild/aix-ppc64@0.19.11: + resolution: {integrity: sha512-FnzU0LyE3ySQk7UntJO4+qIiQgI7KoODnZg5xzXIrFJlKd2P2gwHsHY4927xj9y5PJmJSzULiUCWmv7iWnNa7g==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + requiresBuild: true + optional: true + + /@esbuild/android-arm64@0.19.11: + resolution: {integrity: sha512-aiu7K/5JnLj//KOnOfEZ0D90obUkRzDMyqd/wNAUQ34m4YUPVhRZpnqKV9uqDGxT7cToSDnIHsGooyIczu9T+Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + optional: true + + /@esbuild/android-arm@0.19.11: + resolution: {integrity: sha512-5OVapq0ClabvKvQ58Bws8+wkLCV+Rxg7tUVbo9xu034Nm536QTII4YzhaFriQ7rMrorfnFKUsArD2lqKbFY4vw==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + optional: true + + /@esbuild/android-x64@0.19.11: + resolution: {integrity: sha512-eccxjlfGw43WYoY9QgB82SgGgDbibcqyDTlk3l3C0jOVHKxrjdc9CTwDUQd0vkvYg5um0OH+GpxYvp39r+IPOg==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + optional: true + + /@esbuild/darwin-arm64@0.19.11: + resolution: {integrity: sha512-ETp87DRWuSt9KdDVkqSoKoLFHYTrkyz2+65fj9nfXsaV3bMhTCjtQfw3y+um88vGRKRiF7erPrh/ZuIdLUIVxQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + optional: true + + /@esbuild/darwin-x64@0.19.11: + resolution: {integrity: sha512-fkFUiS6IUK9WYUO/+22omwetaSNl5/A8giXvQlcinLIjVkxwTLSktbF5f/kJMftM2MJp9+fXqZ5ezS7+SALp4g==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + optional: true + + /@esbuild/freebsd-arm64@0.19.11: + resolution: {integrity: sha512-lhoSp5K6bxKRNdXUtHoNc5HhbXVCS8V0iZmDvyWvYq9S5WSfTIHU2UGjcGt7UeS6iEYp9eeymIl5mJBn0yiuxA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + optional: true + + /@esbuild/freebsd-x64@0.19.11: + resolution: {integrity: sha512-JkUqn44AffGXitVI6/AbQdoYAq0TEullFdqcMY/PCUZ36xJ9ZJRtQabzMA+Vi7r78+25ZIBosLTOKnUXBSi1Kw==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + optional: true + + /@esbuild/linux-arm64@0.19.11: + resolution: {integrity: sha512-LneLg3ypEeveBSMuoa0kwMpCGmpu8XQUh+mL8XXwoYZ6Be2qBnVtcDI5azSvh7vioMDhoJFZzp9GWp9IWpYoUg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + optional: true + + /@esbuild/linux-arm@0.19.11: + resolution: {integrity: sha512-3CRkr9+vCV2XJbjwgzjPtO8T0SZUmRZla+UL1jw+XqHZPkPgZiyWvbDvl9rqAN8Zl7qJF0O/9ycMtjU67HN9/Q==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + optional: true + + /@esbuild/linux-ia32@0.19.11: + resolution: {integrity: sha512-caHy++CsD8Bgq2V5CodbJjFPEiDPq8JJmBdeyZ8GWVQMjRD0sU548nNdwPNvKjVpamYYVL40AORekgfIubwHoA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + optional: true + + /@esbuild/linux-loong64@0.19.11: + resolution: {integrity: sha512-ppZSSLVpPrwHccvC6nQVZaSHlFsvCQyjnvirnVjbKSHuE5N24Yl8F3UwYUUR1UEPaFObGD2tSvVKbvR+uT1Nrg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + optional: true + + /@esbuild/linux-mips64el@0.19.11: + resolution: {integrity: sha512-B5x9j0OgjG+v1dF2DkH34lr+7Gmv0kzX6/V0afF41FkPMMqaQ77pH7CrhWeR22aEeHKaeZVtZ6yFwlxOKPVFyg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + optional: true + + /@esbuild/linux-ppc64@0.19.11: + resolution: {integrity: sha512-MHrZYLeCG8vXblMetWyttkdVRjQlQUb/oMgBNurVEnhj4YWOr4G5lmBfZjHYQHHN0g6yDmCAQRR8MUHldvvRDA==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + optional: true + + /@esbuild/linux-riscv64@0.19.11: + resolution: {integrity: sha512-f3DY++t94uVg141dozDu4CCUkYW+09rWtaWfnb3bqe4w5NqmZd6nPVBm+qbz7WaHZCoqXqHz5p6CM6qv3qnSSQ==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + optional: true + + /@esbuild/linux-s390x@0.19.11: + resolution: {integrity: sha512-A5xdUoyWJHMMlcSMcPGVLzYzpcY8QP1RtYzX5/bS4dvjBGVxdhuiYyFwp7z74ocV7WDc0n1harxmpq2ePOjI0Q==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + optional: true + + /@esbuild/linux-x64@0.19.11: + resolution: {integrity: sha512-grbyMlVCvJSfxFQUndw5mCtWs5LO1gUlwP4CDi4iJBbVpZcqLVT29FxgGuBJGSzyOxotFG4LoO5X+M1350zmPA==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + optional: true + + /@esbuild/netbsd-x64@0.19.11: + resolution: {integrity: sha512-13jvrQZJc3P230OhU8xgwUnDeuC/9egsjTkXN49b3GcS5BKvJqZn86aGM8W9pd14Kd+u7HuFBMVtrNGhh6fHEQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + optional: true + + /@esbuild/openbsd-x64@0.19.11: + resolution: {integrity: sha512-ysyOGZuTp6SNKPE11INDUeFVVQFrhcNDVUgSQVDzqsqX38DjhPEPATpid04LCoUr2WXhQTEZ8ct/EgJCUDpyNw==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + optional: true + + /@esbuild/sunos-x64@0.19.11: + resolution: {integrity: sha512-Hf+Sad9nVwvtxy4DXCZQqLpgmRTQqyFyhT3bZ4F2XlJCjxGmRFF0Shwn9rzhOYRB61w9VMXUkxlBy56dk9JJiQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + optional: true + + /@esbuild/win32-arm64@0.19.11: + resolution: {integrity: sha512-0P58Sbi0LctOMOQbpEOvOL44Ne0sqbS0XWHMvvrg6NE5jQ1xguCSSw9jQeUk2lfrXYsKDdOe6K+oZiwKPilYPQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + optional: true + + /@esbuild/win32-ia32@0.19.11: + resolution: {integrity: sha512-6YOrWS+sDJDmshdBIQU+Uoyh7pQKrdykdefC1avn76ss5c+RN6gut3LZA4E2cH5xUEp5/cA0+YxRaVtRAb0xBg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + optional: true + + /@esbuild/win32-x64@0.19.11: + resolution: {integrity: sha512-vfkhltrjCAb603XaFhqhAF4LGDi2M4OrCRrFusyQ+iTLQ/o60QQXxc9cZC/FFpihBI9N1Grn6SMKVJ4KP7Fuiw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + optional: true + /@eslint-community/eslint-utils@4.4.0(eslint@8.56.0): resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -490,7 +742,6 @@ packages: ajv: 8.12.0 ajv-formats: 2.1.1(ajv@8.12.0) fast-uri: 2.3.0 - dev: false /@fastify/busboy@2.1.0: resolution: {integrity: sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA==} @@ -499,17 +750,14 @@ packages: /@fastify/deepmerge@1.3.0: resolution: {integrity: sha512-J8TOSBq3SoZbDhM9+R/u77hP93gz/rajSA+K2kGyijPpORPWUXHUpTaleoj+92As0S9uPRP7Oi8IqMf0u+ro6A==} - dev: false /@fastify/error@3.4.1: resolution: {integrity: sha512-wWSvph+29GR783IhmvdwWnN4bUxTD01Vm5Xad4i7i1VuAOItLvbPAb69sb0IQ2N57yprvhNIwAP5B6xfKTmjmQ==} - dev: false /@fastify/fast-json-stringify-compiler@4.3.0: resolution: {integrity: sha512-aZAXGYo6m22Fk1zZzEUKBvut/CIIQe/BapEORnxiD5Qr0kPHqqI69NtEMCme74h+at72sPhbkb4ZrLd1W3KRLA==} dependencies: fast-json-stringify: 5.10.0 - dev: false /@fastify/reply-from@9.7.0: resolution: {integrity: sha512-/F1QBl3FGlTqStjmiuoLRDchVxP967TZh6FZPwQteWhdLsDec8mqSACE+cRzw6qHUj3v9hfdd7JNgmb++fyFhQ==} @@ -527,7 +775,6 @@ packages: /@gar/promisify@1.1.3: resolution: {integrity: sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==} requiresBuild: true - dev: false optional: true /@gwhitney/detect-indent@7.0.1: @@ -567,6 +814,17 @@ packages: wrap-ansi-cjs: /wrap-ansi@7.0.0 dev: false + /@istanbuljs/schema@0.1.3: + resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} + engines: {node: '>=8'} + dev: true + + /@jest/schemas@29.6.3: + resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@sinclair/typebox': 0.27.8 + /@jridgewell/gen-mapping@0.3.3: resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==} engines: {node: '>=6.0.0'} @@ -636,7 +894,6 @@ packages: dependencies: '@gar/promisify': 1.1.3 semver: 7.5.4 - dev: false optional: true /@npmcli/move-file@1.1.2: @@ -647,7 +904,6 @@ packages: dependencies: mkdirp: 1.0.4 rimraf: 3.0.2 - dev: false optional: true /@pkgjs/parseargs@0.11.0: @@ -1139,7 +1395,6 @@ packages: cpu: [arm] os: [android] requiresBuild: true - dev: false optional: true /@rollup/rollup-android-arm64@4.9.4: @@ -1147,7 +1402,6 @@ packages: cpu: [arm64] os: [android] requiresBuild: true - dev: false optional: true /@rollup/rollup-darwin-arm64@4.9.4: @@ -1155,7 +1409,6 @@ packages: cpu: [arm64] os: [darwin] requiresBuild: true - dev: false optional: true /@rollup/rollup-darwin-x64@4.9.4: @@ -1163,7 +1416,6 @@ packages: cpu: [x64] os: [darwin] requiresBuild: true - dev: false optional: true /@rollup/rollup-linux-arm-gnueabihf@4.9.4: @@ -1171,7 +1423,6 @@ packages: cpu: [arm] os: [linux] requiresBuild: true - dev: false optional: true /@rollup/rollup-linux-arm64-gnu@4.9.4: @@ -1179,7 +1430,6 @@ packages: cpu: [arm64] os: [linux] requiresBuild: true - dev: false optional: true /@rollup/rollup-linux-arm64-musl@4.9.4: @@ -1187,7 +1437,6 @@ packages: cpu: [arm64] os: [linux] requiresBuild: true - dev: false optional: true /@rollup/rollup-linux-riscv64-gnu@4.9.4: @@ -1195,7 +1444,6 @@ packages: cpu: [riscv64] os: [linux] requiresBuild: true - dev: false optional: true /@rollup/rollup-linux-x64-gnu@4.9.4: @@ -1203,7 +1451,6 @@ packages: cpu: [x64] os: [linux] requiresBuild: true - dev: false optional: true /@rollup/rollup-linux-x64-musl@4.9.4: @@ -1211,7 +1458,6 @@ packages: cpu: [x64] os: [linux] requiresBuild: true - dev: false optional: true /@rollup/rollup-win32-arm64-msvc@4.9.4: @@ -1219,7 +1465,6 @@ packages: cpu: [arm64] os: [win32] requiresBuild: true - dev: false optional: true /@rollup/rollup-win32-ia32-msvc@4.9.4: @@ -1227,7 +1472,6 @@ packages: cpu: [ia32] os: [win32] requiresBuild: true - dev: false optional: true /@rollup/rollup-win32-x64-msvc@4.9.4: @@ -1235,14 +1479,15 @@ packages: cpu: [x64] os: [win32] requiresBuild: true - dev: false optional: true + /@sinclair/typebox@0.27.8: + resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + /@tootallnate/once@1.1.2: resolution: {integrity: sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==} engines: {node: '>= 6'} requiresBuild: true - dev: false optional: true /@trpc/client@10.45.0(@trpc/server@10.45.0): @@ -1275,7 +1520,6 @@ packages: /@types/estree@1.0.5: resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} - dev: false /@types/inquirer@9.0.7: resolution: {integrity: sha512-Q0zyBupO6NxGRZut/JdmqYKOnN95Eg5V8Csg3PGKkP+FnvsUZx1jAyK7fztIszxxMuoBA6E3KXWvdZVXIpx60g==} @@ -1284,6 +1528,10 @@ packages: rxjs: 7.8.1 dev: true + /@types/istanbul-lib-coverage@2.0.6: + resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} + dev: true + /@types/json-schema@7.0.15: resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} dev: true @@ -1457,6 +1705,63 @@ packages: resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} dev: true + /@vitest/coverage-v8@1.2.0(vitest@1.2.0): + resolution: {integrity: sha512-YvX8ULTUm1+zkvkl14IqXYGxE1h13OXKPoDsxazARKlp4YLrP28hHEBdplaU7ZTN/Yn6zy6Z3JadWNRJwcmyrQ==} + peerDependencies: + vitest: ^1.0.0 + dependencies: + '@ampproject/remapping': 2.2.1 + '@bcoe/v8-coverage': 0.2.3 + debug: 4.3.4 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 4.0.1 + istanbul-reports: 3.1.6 + magic-string: 0.30.5 + magicast: 0.3.3 + picocolors: 1.0.0 + std-env: 3.7.0 + test-exclude: 6.0.0 + v8-to-istanbul: 9.2.0 + vitest: 1.2.0(@types/node@20.10.8) + transitivePeerDependencies: + - supports-color + dev: true + + /@vitest/expect@1.2.0: + resolution: {integrity: sha512-H+2bHzhyvgp32o7Pgj2h9RTHN0pgYaoi26Oo3mE+dCi1PAqV31kIIVfTbqMO3Bvshd5mIrJLc73EwSRrbol9Lw==} + dependencies: + '@vitest/spy': 1.2.0 + '@vitest/utils': 1.2.0 + chai: 4.4.1 + + /@vitest/runner@1.2.0: + resolution: {integrity: sha512-vaJkDoQaNUTroT70OhM0NPznP7H3WyRwt4LvGwCVYs/llLaqhoSLnlIhUClZpbF5RgAee29KRcNz0FEhYcgxqA==} + dependencies: + '@vitest/utils': 1.2.0 + p-limit: 5.0.0 + pathe: 1.1.2 + + /@vitest/snapshot@1.2.0: + resolution: {integrity: sha512-P33EE7TrVgB3HDLllrjK/GG6WSnmUtWohbwcQqmm7TAk9AVHpdgf7M3F3qRHKm6vhr7x3eGIln7VH052Smo6Kw==} + dependencies: + magic-string: 0.30.5 + pathe: 1.1.2 + pretty-format: 29.7.0 + + /@vitest/spy@1.2.0: + resolution: {integrity: sha512-MNxSAfxUaCeowqyyGwC293yZgk7cECZU9wGb8N1pYQ0yOn/SIr8t0l9XnGRdQZvNV/ZHBYu6GO/W3tj5K3VN1Q==} + dependencies: + tinyspy: 2.2.0 + + /@vitest/utils@1.2.0: + resolution: {integrity: sha512-FyD5bpugsXlwVpTcGLDf3wSPYy8g541fQt14qtzo8mJ4LdEpDKZ9mQy2+qdJm2TZRpjY5JLXihXCgIxiRJgi5g==} + dependencies: + diff-sequences: 29.6.3 + estree-walker: 3.0.3 + loupe: 2.3.7 + pretty-format: 29.7.0 + /@zkochan/which@2.0.3: resolution: {integrity: sha512-C1ReN7vt2/2O0fyTsx5xnbQuxBrmG5NMSbcIkPKCCfCTJgpZBsuRYzFXHj3nVq8vTfK7vxHUmzfCpSHgO7j4rg==} engines: {node: '>= 8'} @@ -1468,7 +1773,6 @@ packages: /abbrev@1.1.1: resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} requiresBuild: true - dev: false optional: true /abort-controller@3.0.0: @@ -1476,11 +1780,9 @@ packages: engines: {node: '>=6.5'} dependencies: event-target-shim: 5.0.1 - dev: false /abstract-logging@2.0.1: resolution: {integrity: sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==} - dev: false /acorn-jsx@5.3.2(acorn@8.11.3): resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} @@ -1493,7 +1795,6 @@ packages: /acorn-walk@8.3.1: resolution: {integrity: sha512-TgUZgYvqZprrl7YldZNoa9OciCAyZR+Ejm9eXzKCmjsF5IKp/wgQ7Z/ZpjpGTIUPwrHQIcYeI8qDh4PsEwxMbw==} engines: {node: '>=0.4.0'} - dev: false /acorn@8.11.3: resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} @@ -1508,7 +1809,6 @@ packages: debug: 4.3.4 transitivePeerDependencies: - supports-color - dev: false optional: true /agentkeepalive@4.5.0: @@ -1517,7 +1817,6 @@ packages: requiresBuild: true dependencies: humanize-ms: 1.2.1 - dev: false optional: true /aggregate-error@3.1.0: @@ -1527,7 +1826,6 @@ packages: dependencies: clean-stack: 2.2.0 indent-string: 4.0.0 - dev: false optional: true /ajv-formats@2.1.1(ajv@8.12.0): @@ -1539,7 +1837,6 @@ packages: optional: true dependencies: ajv: 8.12.0 - dev: false /ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} @@ -1557,7 +1854,6 @@ packages: json-schema-traverse: 1.0.0 require-from-string: 2.0.2 uri-js: 4.4.1 - dev: false /ansi-align@3.0.1: resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==} @@ -1611,6 +1907,10 @@ packages: dependencies: color-convert: 2.0.1 + /ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + /ansi-styles@6.2.1: resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} engines: {node: '>=12'} @@ -1623,12 +1923,10 @@ packages: /aproba@2.0.0: resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==} requiresBuild: true - dev: false optional: true /archy@1.0.0: resolution: {integrity: sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==} - dev: false /are-we-there-yet@3.0.1: resolution: {integrity: sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==} @@ -1637,13 +1935,16 @@ packages: dependencies: delegates: 1.0.0 readable-stream: 3.6.2 - dev: false optional: true /arg@4.1.3: resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} dev: false + /arg@5.0.2: + resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + dev: false + /argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} @@ -1719,6 +2020,9 @@ packages: printable-characters: 1.0.42 dev: false + /assertion-error@1.1.0: + resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} + /asynciterator.prototype@1.0.0: resolution: {integrity: sha512-wwHYEIS0Q80f5mosx3L/dfG5t5rjEa9Ft51GTaNt862EnpyGHpgz2RkZvLPp1oF5TnAiTohkEKVEu8pQPJI7Vg==} dependencies: @@ -1728,7 +2032,6 @@ packages: /atomic-sleep@1.0.0: resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} engines: {node: '>=8.0.0'} - dev: false /available-typed-arrays@1.0.5: resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} @@ -1743,7 +2046,6 @@ packages: fastq: 1.16.0 transitivePeerDependencies: - supports-color - dev: false /balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -1751,7 +2053,6 @@ packages: /base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - dev: false /better-path-resolve@1.0.0: resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} @@ -1764,7 +2065,6 @@ packages: resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} dependencies: file-uri-to-path: 1.0.0 - dev: false /bl@4.1.0: resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} @@ -1772,7 +2072,6 @@ packages: buffer: 5.7.1 inherits: 2.0.4 readable-stream: 3.6.2 - dev: false /bole@5.0.10: resolution: {integrity: sha512-5IiUWQ8QRQ8yHf46VPQ7GH3nj0Jy7P4heaENBVmsGfHP1Gtd0wqkvK6C3iHLUMdG3SMFx2DD8FqoIQcnMpdIdQ==} @@ -1838,20 +2137,22 @@ packages: dependencies: base64-js: 1.5.1 ieee754: 1.2.1 - dev: false /buffer@6.0.3: resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} dependencies: base64-js: 1.5.1 ieee754: 1.2.1 - dev: false /builtin-modules@3.3.0: resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} engines: {node: '>=6'} dev: false + /cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + /cacache@15.3.0: resolution: {integrity: sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==} engines: {node: '>= 10'} @@ -1877,7 +2178,6 @@ packages: unique-filename: 1.1.1 transitivePeerDependencies: - bluebird - dev: false optional: true /call-bind@1.0.5: @@ -1922,6 +2222,18 @@ packages: resolution: {integrity: sha512-ff5BdakGe2P3SQsMsiqmt1Lc8221NR1VzHj5jXN5vBny9A6fpze94HiVV/n7XRosOlsShJcvMv5mdnpjOGCEgg==} dev: true + /chai@4.4.1: + resolution: {integrity: sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==} + engines: {node: '>=4'} + dependencies: + assertion-error: 1.1.0 + check-error: 1.0.3 + deep-eql: 4.1.3 + get-func-name: 2.0.2 + loupe: 2.3.7 + pathval: 1.1.1 + type-detect: 4.0.8 + /chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} engines: {node: '>=4'} @@ -1951,20 +2263,22 @@ packages: resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} dev: false + /check-error@1.0.3: + resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} + dependencies: + get-func-name: 2.0.2 + /chownr@1.1.4: resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} - dev: false /chownr@2.0.0: resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} engines: {node: '>=10'} - dev: false /clean-stack@2.2.0: resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} engines: {node: '>=6'} requiresBuild: true - dev: false optional: true /cli-boxes@2.2.1: @@ -2030,7 +2344,6 @@ packages: resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} hasBin: true requiresBuild: true - dev: false optional: true /colorette@2.0.19: @@ -2070,7 +2383,6 @@ packages: /console-control-strings@1.1.0: resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==} requiresBuild: true - dev: false optional: true /convert-source-map@2.0.0: @@ -2080,7 +2392,6 @@ packages: /cookie@0.5.0: resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} engines: {node: '>= 0.6'} - dev: false /copy-anything@3.0.5: resolution: {integrity: sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==} @@ -2133,12 +2444,16 @@ packages: engines: {node: '>=10'} dependencies: mimic-response: 3.1.0 - dev: false + + /deep-eql@4.1.3: + resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==} + engines: {node: '>=6'} + dependencies: + type-detect: 4.0.8 /deep-extend@0.6.0: resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} engines: {node: '>=4.0.0'} - dev: false /deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} @@ -2175,13 +2490,15 @@ packages: /delegates@1.0.0: resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==} requiresBuild: true - dev: false optional: true /detect-libc@2.0.2: resolution: {integrity: sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==} engines: {node: '>=8'} - dev: false + + /diff-sequences@29.6.3: + resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} /diff@4.0.2: resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} @@ -2235,7 +2552,6 @@ packages: /emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} requiresBuild: true - dev: false /emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} @@ -2246,20 +2562,17 @@ packages: requiresBuild: true dependencies: iconv-lite: 0.6.3 - dev: false optional: true /end-of-stream@1.4.4: resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} dependencies: once: 1.4.0 - dev: false /env-paths@2.2.1: resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} engines: {node: '>=6'} requiresBuild: true - dev: false optional: true /env-paths@3.0.0: @@ -2270,7 +2583,6 @@ packages: /err-code@2.0.3: resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==} requiresBuild: true - dev: false optional: true /error-ex@1.3.2: @@ -2367,6 +2679,36 @@ packages: is-symbol: 1.0.4 dev: true + /esbuild@0.19.11: + resolution: {integrity: sha512-HJ96Hev2hX/6i5cDVwcqiJBBtuo9+FeIJOtZ9W1kA5M6AMJRHUZlpYZ1/SbEwtO0ioNAW8rUooVpC/WehY2SfA==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/aix-ppc64': 0.19.11 + '@esbuild/android-arm': 0.19.11 + '@esbuild/android-arm64': 0.19.11 + '@esbuild/android-x64': 0.19.11 + '@esbuild/darwin-arm64': 0.19.11 + '@esbuild/darwin-x64': 0.19.11 + '@esbuild/freebsd-arm64': 0.19.11 + '@esbuild/freebsd-x64': 0.19.11 + '@esbuild/linux-arm': 0.19.11 + '@esbuild/linux-arm64': 0.19.11 + '@esbuild/linux-ia32': 0.19.11 + '@esbuild/linux-loong64': 0.19.11 + '@esbuild/linux-mips64el': 0.19.11 + '@esbuild/linux-ppc64': 0.19.11 + '@esbuild/linux-riscv64': 0.19.11 + '@esbuild/linux-s390x': 0.19.11 + '@esbuild/linux-x64': 0.19.11 + '@esbuild/netbsd-x64': 0.19.11 + '@esbuild/openbsd-x64': 0.19.11 + '@esbuild/sunos-x64': 0.19.11 + '@esbuild/win32-arm64': 0.19.11 + '@esbuild/win32-ia32': 0.19.11 + '@esbuild/win32-x64': 0.19.11 + /escalade@3.1.1: resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} engines: {node: '>=6'} @@ -2621,6 +2963,11 @@ packages: resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} dev: false + /estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + dependencies: + '@types/estree': 1.0.5 + /esutils@2.0.3: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} @@ -2629,7 +2976,6 @@ packages: /event-target-shim@5.0.1: resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} engines: {node: '>=6'} - dev: false /eventemitter3@5.0.1: resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} @@ -2638,7 +2984,6 @@ packages: /events@3.3.0: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} engines: {node: '>=0.8.x'} - dev: false /execa@5.1.1: resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} @@ -2655,10 +3000,23 @@ packages: strip-final-newline: 2.0.0 dev: false + /execa@8.0.1: + resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} + engines: {node: '>=16.17'} + dependencies: + cross-spawn: 7.0.3 + get-stream: 8.0.1 + human-signals: 5.0.0 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.2.0 + onetime: 6.0.0 + signal-exit: 4.1.0 + strip-final-newline: 3.0.0 + /expand-template@2.0.3: resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} engines: {node: '>=6'} - dev: false /external-editor@3.1.0: resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} @@ -2671,18 +3029,15 @@ packages: /fast-content-type-parse@1.1.0: resolution: {integrity: sha512-fBHHqSTFLVnR61C+gltJuE5GkVQMV0S2nqUO8TJ+5Z3qAKG8vAx4FKai1s5jq/inV1+sREynIWSuQ6HgoSXpDQ==} - dev: false /fast-decode-uri-component@1.0.1: resolution: {integrity: sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==} - dev: false /fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} /fast-diff@1.3.0: resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} - dev: true /fast-glob@3.3.2: resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} @@ -2708,7 +3063,6 @@ packages: fast-uri: 2.3.0 json-schema-ref-resolver: 1.0.1 rfdc: 1.3.0 - dev: false /fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} @@ -2718,12 +3072,10 @@ packages: resolution: {integrity: sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==} dependencies: fast-decode-uri-component: 1.0.1 - dev: false /fast-redact@3.3.0: resolution: {integrity: sha512-6T5V1QK1u4oF+ATxs1lWUmlEk6P2T9HqJG3e2DnHOdVgZy2rFJBoEnrIedcTXlkAHU/zKC+7KETJ+KGGKwxgMQ==} engines: {node: '>=6'} - dev: false /fast-safe-stringify@2.1.1: resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} @@ -2731,7 +3083,6 @@ packages: /fast-uri@2.3.0: resolution: {integrity: sha512-eel5UKGn369gGEWOqBShmFJWfq/xSJvsgDzgLYC845GneayWvXBf0lJCBn5qTABfewy1ZDPoaR5OZCP+kssfuw==} - dev: false /fastify-plugin@4.5.1: resolution: {integrity: sha512-stRHYGeuqpEZTL1Ef0Ovr2ltazUT9g844X5z/zEBFLG8RYlpDiOCIG+ATvYEp+/zmc7sN29mcIMp8gvYplYPIQ==} @@ -2758,7 +3109,6 @@ packages: toad-cache: 3.7.0 transitivePeerDependencies: - supports-color - dev: false /fastq@1.16.0: resolution: {integrity: sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA==} @@ -2782,7 +3132,6 @@ packages: /file-uri-to-path@1.0.0: resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} - dev: false /fill-range@7.0.1: resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} @@ -2797,7 +3146,6 @@ packages: fast-deep-equal: 3.1.3 fast-querystring: 1.1.2 safe-regex2: 2.0.0 - dev: false /find-up@5.0.0: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} @@ -2837,18 +3185,15 @@ packages: /forwarded@0.2.0: resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} engines: {node: '>= 0.6'} - dev: false /fs-constants@1.0.0: resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} - dev: false /fs-minipass@2.1.0: resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} engines: {node: '>= 8'} dependencies: minipass: 3.3.6 - dev: false /fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} @@ -2859,7 +3204,6 @@ packages: engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] requiresBuild: true - dev: false optional: true /function-bind@1.1.2: @@ -2892,7 +3236,6 @@ packages: string-width: 4.2.3 strip-ansi: 6.0.1 wide-align: 1.1.5 - dev: false optional: true /gensync@1.0.0-beta.2: @@ -2905,6 +3248,9 @@ packages: engines: {node: '>=18'} dev: false + /get-func-name@2.0.2: + resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} + /get-intrinsic@1.2.2: resolution: {integrity: sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==} dependencies: @@ -2918,6 +3264,11 @@ packages: engines: {node: '>=8.0.0'} dev: false + /get-port@7.0.0: + resolution: {integrity: sha512-mDHFgApoQd+azgMdwylJrv2DX47ywGq1i5VFJE7fZ0dttNq3iQMfsU4IvEgBHojA3KqEudyu7Vq+oN8kNaNkWw==} + engines: {node: '>=16'} + dev: false + /get-source@2.0.12: resolution: {integrity: sha512-X5+4+iD+HoSeEED+uwrQ07BOQr0kEDFMVqqpBuI+RaZBpBpHCuXxo70bjar6f0b0u/DQJsJ7ssurpP0V60Az+w==} dependencies: @@ -2930,6 +3281,10 @@ packages: engines: {node: '>=10'} dev: false + /get-stream@8.0.1: + resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} + engines: {node: '>=16'} + /get-symbol-description@1.0.0: resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} engines: {node: '>= 0.4'} @@ -2944,7 +3299,6 @@ packages: /github-from-package@0.0.0: resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} - dev: false /glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} @@ -3036,7 +3390,6 @@ packages: /graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} requiresBuild: true - dev: false /graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} @@ -3077,7 +3430,6 @@ packages: /has-unicode@2.0.1: resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==} requiresBuild: true - dev: false optional: true /hasown@2.0.0: @@ -3086,10 +3438,13 @@ packages: dependencies: function-bind: 1.1.2 + /html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + dev: true + /http-cache-semantics@4.1.1: resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==} requiresBuild: true - dev: false optional: true /http-proxy-agent@4.0.1: @@ -3102,7 +3457,6 @@ packages: debug: 4.3.4 transitivePeerDependencies: - supports-color - dev: false optional: true /https-proxy-agent@5.0.1: @@ -3114,7 +3468,6 @@ packages: debug: 4.3.4 transitivePeerDependencies: - supports-color - dev: false optional: true /human-signals@2.1.0: @@ -3122,14 +3475,22 @@ packages: engines: {node: '>=10.17.0'} dev: false + /human-signals@5.0.0: + resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} + engines: {node: '>=16.17.0'} + /humanize-ms@1.2.1: resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} requiresBuild: true dependencies: ms: 2.1.2 - dev: false optional: true + /hyperdyperid@1.2.0: + resolution: {integrity: sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==} + engines: {node: '>=10.18'} + dev: false + /iconv-lite@0.4.24: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} @@ -3143,12 +3504,10 @@ packages: requiresBuild: true dependencies: safer-buffer: 2.1.2 - dev: false optional: true /ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - dev: false /ignore@5.3.0: resolution: {integrity: sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==} @@ -3172,7 +3531,6 @@ packages: resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} engines: {node: '>=8'} requiresBuild: true - dev: false optional: true /individual@3.0.0: @@ -3182,7 +3540,6 @@ packages: /infer-owner@1.0.4: resolution: {integrity: sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==} requiresBuild: true - dev: false optional: true /inflight@1.0.6: @@ -3197,7 +3554,6 @@ packages: /ini@1.3.8: resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} - dev: false /ini@3.0.1: resolution: {integrity: sha512-it4HyVAUTKBc6m8e1iXWvXSTdndF7HbdN713+kvLrymxTaU4AUBWrJ4vEooP+V7fexnVD3LKcBshjGGPefSMUQ==} @@ -3242,13 +3598,11 @@ packages: /ip@2.0.0: resolution: {integrity: sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==} requiresBuild: true - dev: false optional: true /ipaddr.js@1.9.1: resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} engines: {node: '>= 0.10'} - dev: false /is-array-buffer@3.0.2: resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==} @@ -3321,7 +3675,6 @@ packages: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} requiresBuild: true - dev: false /is-generator-function@1.0.10: resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} @@ -3349,7 +3702,6 @@ packages: /is-lambda@1.0.1: resolution: {integrity: sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==} requiresBuild: true - dev: false optional: true /is-map@2.0.2: @@ -3415,6 +3767,10 @@ packages: engines: {node: '>=8'} dev: false + /is-stream@3.0.0: + resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + /is-string@1.0.7: resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} engines: {node: '>= 0.4'} @@ -3493,6 +3849,39 @@ packages: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} requiresBuild: true + /istanbul-lib-coverage@3.2.2: + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} + engines: {node: '>=8'} + dev: true + + /istanbul-lib-report@3.0.1: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} + dependencies: + istanbul-lib-coverage: 3.2.2 + make-dir: 4.0.0 + supports-color: 7.2.0 + dev: true + + /istanbul-lib-source-maps@4.0.1: + resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} + engines: {node: '>=10'} + dependencies: + debug: 4.3.4 + istanbul-lib-coverage: 3.2.2 + source-map: 0.6.1 + transitivePeerDependencies: + - supports-color + dev: true + + /istanbul-reports@3.1.6: + resolution: {integrity: sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==} + engines: {node: '>=8'} + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.1 + dev: true + /iterator.prototype@1.1.2: resolution: {integrity: sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==} dependencies: @@ -3531,6 +3920,22 @@ packages: resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} dev: true + /json-joy@9.9.1(quill-delta@5.1.0)(rxjs@7.8.1)(tslib@2.6.2): + resolution: {integrity: sha512-/d7th2nbQRBQ/nqTkBe6KjjvDciSwn9UICmndwk3Ed/Bk9AqkTRm4PnLVfXG4DKbT0rEY0nKnwE7NqZlqKE6kg==} + engines: {node: '>=10.0'} + hasBin: true + peerDependencies: + quill-delta: ^5 + rxjs: '7' + tslib: '2' + dependencies: + arg: 5.0.2 + hyperdyperid: 1.2.0 + quill-delta: 5.1.0 + rxjs: 7.8.1 + tslib: 2.6.2 + dev: false + /json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} dev: false @@ -3539,7 +3944,6 @@ packages: resolution: {integrity: sha512-EJAj1pgHc1hxF6vo2Z3s69fMjO1INq6eGHXZ8Z6wCQeldCuwxGK9Sxf4/cScGn3FZubCVUehfWtcDM/PLteCQw==} dependencies: fast-deep-equal: 3.1.3 - dev: false /json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} @@ -3547,7 +3951,6 @@ packages: /json-schema-traverse@1.0.0: resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} - dev: false /json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} @@ -3562,6 +3965,9 @@ packages: engines: {node: '>=6'} hasBin: true + /jsonc-parser@3.2.0: + resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} + /jsonwebtoken@9.0.2: resolution: {integrity: sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==} engines: {node: '>=12', npm: '>=6'} @@ -3670,7 +4076,6 @@ packages: cookie: 0.5.0 process-warning: 2.3.2 set-cookie-parser: 2.6.0 - dev: false /lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} @@ -3686,6 +4091,13 @@ packages: type-fest: 0.6.0 dev: false + /local-pkg@0.5.0: + resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==} + engines: {node: '>=14'} + dependencies: + mlly: 1.5.0 + pkg-types: 1.0.3 + /locate-path@6.0.0: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} @@ -3693,6 +4105,10 @@ packages: p-locate: 5.0.0 dev: true + /lodash.clonedeep@4.5.0: + resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==} + dev: false + /lodash.includes@4.3.0: resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==} dev: false @@ -3701,6 +4117,10 @@ packages: resolution: {integrity: sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==} dev: false + /lodash.isequal@4.5.0: + resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} + dev: false + /lodash.isinteger@4.0.4: resolution: {integrity: sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==} dev: false @@ -3751,6 +4171,11 @@ packages: js-tokens: 4.0.0 dev: true + /loupe@2.3.7: + resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} + dependencies: + get-func-name: 2.0.2 + /lru-cache@10.1.0: resolution: {integrity: sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==} engines: {node: 14 || >=16.14} @@ -3785,7 +4210,21 @@ packages: engines: {node: '>=12'} dependencies: '@jridgewell/sourcemap-codec': 1.4.15 - dev: false + + /magicast@0.3.3: + resolution: {integrity: sha512-ZbrP1Qxnpoes8sz47AM0z08U+jW6TyRgZzcWy3Ma3vDhJttwMwAFDMMQFobwdBxByBD46JYmxRzeF7w2+wJEuw==} + dependencies: + '@babel/parser': 7.23.6 + '@babel/types': 7.23.6 + source-map-js: 1.0.2 + dev: true + + /make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} + engines: {node: '>=10'} + dependencies: + semver: 7.5.4 + dev: true /make-error@1.3.6: resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} @@ -3815,7 +4254,6 @@ packages: transitivePeerDependencies: - bluebird - supports-color - dev: false optional: true /map-age-cleaner@0.1.3: @@ -3838,9 +4276,22 @@ packages: mimic-fn: 3.1.0 dev: false + /memfs@4.6.0(quill-delta@5.1.0)(rxjs@7.8.1)(tslib@2.6.2): + resolution: {integrity: sha512-I6mhA1//KEZfKRQT9LujyW6lRbX7RkC24xKododIDO3AGShcaFAMKElv1yFGWX8fD4UaSiwasr3NeQ5TdtHY1A==} + engines: {node: '>= 4.0.0'} + peerDependencies: + tslib: '2' + dependencies: + json-joy: 9.9.1(quill-delta@5.1.0)(rxjs@7.8.1)(tslib@2.6.2) + thingies: 1.16.0(tslib@2.6.2) + tslib: 2.6.2 + transitivePeerDependencies: + - quill-delta + - rxjs + dev: false + /merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} - dev: false /merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} @@ -3863,10 +4314,13 @@ packages: engines: {node: '>=8'} dev: false + /mimic-fn@4.0.0: + resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} + engines: {node: '>=12'} + /mimic-response@3.1.0: resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} engines: {node: '>=10'} - dev: false /minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} @@ -3890,7 +4344,6 @@ packages: /minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - dev: false /minipass-collect@1.0.2: resolution: {integrity: sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==} @@ -3898,7 +4351,6 @@ packages: requiresBuild: true dependencies: minipass: 3.3.6 - dev: false optional: true /minipass-fetch@1.4.1: @@ -3911,7 +4363,6 @@ packages: minizlib: 2.1.2 optionalDependencies: encoding: 0.1.13 - dev: false optional: true /minipass-flush@1.0.5: @@ -3920,7 +4371,6 @@ packages: requiresBuild: true dependencies: minipass: 3.3.6 - dev: false optional: true /minipass-pipeline@1.2.4: @@ -3929,7 +4379,6 @@ packages: requiresBuild: true dependencies: minipass: 3.3.6 - dev: false optional: true /minipass-sized@1.0.3: @@ -3938,7 +4387,6 @@ packages: requiresBuild: true dependencies: minipass: 3.3.6 - dev: false optional: true /minipass@3.3.6: @@ -3946,12 +4394,10 @@ packages: engines: {node: '>=8'} dependencies: yallist: 4.0.0 - dev: false /minipass@5.0.0: resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} engines: {node: '>=8'} - dev: false /minizlib@2.1.2: resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} @@ -3959,17 +4405,22 @@ packages: dependencies: minipass: 3.3.6 yallist: 4.0.0 - dev: false /mkdirp-classic@0.5.3: resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} - dev: false /mkdirp@1.0.4: resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} engines: {node: '>=10'} hasBin: true - dev: false + + /mlly@1.5.0: + resolution: {integrity: sha512-NPVQvAY1xr1QoVeG0cy8yUYC7FQcOx6evl/RjT1wL5FvzPnzOysoqB/jmx/DhssT2dYa8nxECLAaFI/+gVLhDQ==} + dependencies: + acorn: 8.11.3 + pathe: 1.1.2 + pkg-types: 1.0.3 + ufo: 1.3.2 /ms@2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} @@ -3987,6 +4438,11 @@ packages: thenify-all: 1.6.0 dev: false + /nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + /nanoid@5.0.4: resolution: {integrity: sha512-vAjmBf13gsmhXSgBrtIclinISzFFy22WwCYoyilZlsrRXNIHSwgFQ1bEdjRwMT3aoadeIF6HMuDRlOxzfXV8ig==} engines: {node: ^18 || >=20} @@ -3995,7 +4451,6 @@ packages: /napi-build-utils@1.0.2: resolution: {integrity: sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==} - dev: false /natural-compare-lite@1.4.0: resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} @@ -4021,7 +4476,6 @@ packages: resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} engines: {node: '>= 0.6'} requiresBuild: true - dev: false optional: true /node-abi@3.54.0: @@ -4029,11 +4483,9 @@ packages: engines: {node: '>=10'} dependencies: semver: 7.5.4 - dev: false /node-addon-api@7.0.0: resolution: {integrity: sha512-vgbBJTS4m5/KkE16t5Ly0WW9hz46swAstv0hYYwMtbG7AznRhNyfLRe8HZAiWIpcHzoO7HxhLuBQj9rJ/Ho0ZA==} - dev: false /node-gyp@8.4.1: resolution: {integrity: sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w==} @@ -4054,7 +4506,6 @@ packages: transitivePeerDependencies: - bluebird - supports-color - dev: false optional: true /node-releases@2.0.14: @@ -4068,7 +4519,6 @@ packages: requiresBuild: true dependencies: abbrev: 1.1.1 - dev: false optional: true /normalize-path@3.0.0: @@ -4087,6 +4537,12 @@ packages: path-key: 3.1.1 dev: false + /npm-run-path@5.2.0: + resolution: {integrity: sha512-W4/tgAXFqFA0iL7fk0+uQ3g7wkL8xJmx3XdK0VGb4cHW//eZTtKGvFBBoRKVTpY7n6ze4NL9ly7rgXcHufqXKg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + path-key: 4.0.0 + /npmlog@6.0.2: resolution: {integrity: sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} @@ -4096,7 +4552,6 @@ packages: console-control-strings: 1.1.0 gauge: 4.0.4 set-blocking: 2.0.0 - dev: false optional: true /object-assign@4.1.1: @@ -4159,7 +4614,6 @@ packages: /on-exit-leak-free@2.1.2: resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==} engines: {node: '>=14.0.0'} - dev: false /once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} @@ -4173,6 +4627,12 @@ packages: mimic-fn: 2.1.0 dev: false + /onetime@6.0.0: + resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} + engines: {node: '>=12'} + dependencies: + mimic-fn: 4.0.0 + /optionator@0.9.3: resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} engines: {node: '>= 0.8.0'} @@ -4239,6 +4699,12 @@ packages: yocto-queue: 0.1.0 dev: true + /p-limit@5.0.0: + resolution: {integrity: sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==} + engines: {node: '>=18'} + dependencies: + yocto-queue: 1.0.0 + /p-locate@5.0.0: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} @@ -4257,7 +4723,6 @@ packages: requiresBuild: true dependencies: aggregate-error: 3.1.0 - dev: false optional: true /parent-module@1.0.1: @@ -4301,6 +4766,10 @@ packages: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} + /path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + /path-name@1.0.0: resolution: {integrity: sha512-/dcAb5vMXH0f51yvMuSUqFpxUcA8JelbRmE5mW/p4CUJxrNgK24IkstnV7ENtg2IDGBOu6izKTG6eilbnbNKWQ==} dev: false @@ -4328,13 +4797,18 @@ packages: engines: {node: '>=8'} dev: true + /pathe@1.1.2: + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + + /pathval@1.1.1: + resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} + /pg-connection-string@2.6.2: resolution: {integrity: sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA==} dev: false /picocolors@1.0.0: resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} - dev: true /picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} @@ -4345,11 +4819,9 @@ packages: dependencies: readable-stream: 4.5.2 split2: 4.2.0 - dev: false /pino-std-serializers@6.2.2: resolution: {integrity: sha512-cHjPPsE+vhj/tnhCy/wiMh3M3z3h/j15zHQX+S9GkTBgqJuTuJzYJ4gUyACLhDaJ7kk9ba9iRDmbH2tJU03OiA==} - dev: false /pino@8.17.2: resolution: {integrity: sha512-LA6qKgeDMLr2ux2y/YiUt47EfgQ+S9LznBWOJdN3q1dx2sv0ziDLUBeVpyVv17TEcGCBuWf0zNtg3M5m1NhhWQ==} @@ -4366,13 +4838,27 @@ packages: safe-stable-stringify: 2.4.3 sonic-boom: 3.8.0 thread-stream: 2.4.1 - dev: false /pirates@4.0.6: resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} engines: {node: '>= 6'} dev: false + /pkg-types@1.0.3: + resolution: {integrity: sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==} + dependencies: + jsonc-parser: 3.2.0 + mlly: 1.5.0 + pathe: 1.1.2 + + /postcss@8.4.33: + resolution: {integrity: sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.7 + picocolors: 1.0.0 + source-map-js: 1.0.2 + /prebuild-install@7.1.1: resolution: {integrity: sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==} engines: {node: '>=10'} @@ -4390,7 +4876,6 @@ packages: simple-get: 4.0.1 tar-fs: 2.1.1 tunnel-agent: 0.6.0 - dev: false /prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} @@ -4415,6 +4900,14 @@ packages: engines: {node: '>=6'} dev: false + /pretty-format@29.7.0: + resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/schemas': 29.6.3 + ansi-styles: 5.2.0 + react-is: 18.2.0 + /pretty-ms@7.0.1: resolution: {integrity: sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q==} engines: {node: '>=10'} @@ -4428,16 +4921,13 @@ packages: /process-warning@2.3.2: resolution: {integrity: sha512-n9wh8tvBe5sFmsqlg+XQhaQLumwpqoAUruLwjCopgTmUBjJ/fjtBsJzKleCaIGBOMXYEhp1YfKl4d7rJ5ZKJGA==} - dev: false /process-warning@3.0.0: resolution: {integrity: sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ==} - dev: false /process@0.11.10: resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} engines: {node: '>= 0.6.0'} - dev: false /promise-inflight@1.0.1: resolution: {integrity: sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==} @@ -4447,7 +4937,6 @@ packages: peerDependenciesMeta: bluebird: optional: true - dev: false optional: true /promise-retry@2.0.1: @@ -4457,7 +4946,6 @@ packages: dependencies: err-code: 2.0.3 retry: 0.12.0 - dev: false optional: true /prop-types@15.8.1: @@ -4478,14 +4966,12 @@ packages: dependencies: forwarded: 0.2.0 ipaddr.js: 1.9.1 - dev: false /pump@3.0.0: resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} dependencies: end-of-stream: 1.4.4 once: 1.4.0 - dev: false /punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} @@ -4496,13 +4982,21 @@ packages: /quick-format-unescaped@4.0.4: resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} - dev: false /quick-lru@4.0.1: resolution: {integrity: sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==} engines: {node: '>=8'} dev: false + /quill-delta@5.1.0: + resolution: {integrity: sha512-X74oCeRI4/p0ucjb5Ma8adTXd9Scumz367kkMK5V/IatcX6A0vlgLgKbzXWy5nZmCGeNJm2oQX0d2Eqj+ZIlCA==} + engines: {node: '>= 12.0.0'} + dependencies: + fast-diff: 1.3.0 + lodash.clonedeep: 4.5.0 + lodash.isequal: 4.5.0 + dev: false + /rc@1.2.8: resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} hasBin: true @@ -4511,12 +5005,14 @@ packages: ini: 1.3.8 minimist: 1.2.8 strip-json-comments: 2.0.1 - dev: false /react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} dev: true + /react-is@18.2.0: + resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} + /read-ini-file@4.0.0: resolution: {integrity: sha512-zz4qv/sKETv7nAkATqSJ9YMbKD8NXRPuA8d17VdYCuNYrVstB1S6UAMU6aytf5vRa9MESbZN7jLZdcmrOxz4gg==} engines: {node: '>=14.6'} @@ -4540,7 +5036,6 @@ packages: inherits: 2.0.4 string_decoder: 1.3.0 util-deprecate: 1.0.2 - dev: false /readable-stream@4.5.2: resolution: {integrity: sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==} @@ -4551,12 +5046,10 @@ packages: events: 3.3.0 process: 0.11.10 string_decoder: 1.3.0 - dev: false /real-require@0.2.0: resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==} engines: {node: '>= 12.13.0'} - dev: false /realpath-missing@1.1.0: resolution: {integrity: sha512-wnWtnywepjg/eHIgWR97R7UuM5i+qHLA195qdN9UPKvcMqfn60+67S8sPPW3vDlSEfYHoFkKU8IvpCNty3zQvQ==} @@ -4570,6 +5063,10 @@ packages: resolve: 1.22.8 dev: false + /reflect-metadata@0.2.1: + resolution: {integrity: sha512-i5lLI6iw9AU3Uu4szRNPPEkomnkjRTaVt9hy/bn5g/oSzekBSMeLZblcjP74AW0vBabqERLLIrz+gR8QYR54Tw==} + dev: false + /reflect.getprototypeof@1.0.4: resolution: {integrity: sha512-ECkTw8TmJwW60lOTR+ZkODISW6RQ8+2CL3COqtiJKLd6MmB45hN51HprHFziKLGkAuTGQhBb91V8cy+KHlaCjw==} engines: {node: '>= 0.4'} @@ -4594,7 +5091,6 @@ packages: /require-from-string@2.0.2: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} - dev: false /resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} @@ -4643,13 +5139,11 @@ packages: /ret@0.2.2: resolution: {integrity: sha512-M0b3YWQs7R3Z917WRQy1HHA7Ba7D8hvZg6UE5mLykJxQVE2ju0IXbGlaHPPlkY+WN7wFP+wUMXmBFA0aV6vYGQ==} engines: {node: '>=4'} - dev: false /retry@0.12.0: resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} engines: {node: '>= 4'} requiresBuild: true - dev: false optional: true /reusify@1.0.4: @@ -4658,7 +5152,6 @@ packages: /rfdc@1.3.0: resolution: {integrity: sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==} - dev: false /right-pad@1.0.1: resolution: {integrity: sha512-bYBjgxmkvTAfgIYy328fmkwhp39v8lwVgWhhrzxPV3yHtcSqyYKe9/XOhvW48UFjATg3VuJbpsp5822ACNvkmw==} @@ -4714,7 +5207,6 @@ packages: '@rollup/rollup-win32-ia32-msvc': 4.9.4 '@rollup/rollup-win32-x64-msvc': 4.9.4 fsevents: 2.3.3 - dev: false /run-async@3.0.0: resolution: {integrity: sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==} @@ -4743,7 +5235,6 @@ packages: /safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - dev: false /safe-execa@0.1.2: resolution: {integrity: sha512-vdTshSQ2JsRCgT8eKZWNJIL26C6bVqy1SOmuCMlKHegVeo8KYRobRrefOdUq9OozSPUUiSxrylteeRmLOMFfWg==} @@ -4767,21 +5258,17 @@ packages: resolution: {integrity: sha512-PaUSFsUaNNuKwkBijoAPHAK6/eM6VirvyPWlZ7BAQy4D+hCvh4B6lIG+nPdhbFfIbP+gTGBcrdsOaUs0F+ZBOQ==} dependencies: ret: 0.2.2 - dev: false /safe-stable-stringify@2.4.3: resolution: {integrity: sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==} engines: {node: '>=10'} - dev: false /safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} requiresBuild: true - dev: false /secure-json-parse@2.7.0: resolution: {integrity: sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==} - dev: false /semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} @@ -4798,12 +5285,10 @@ packages: /set-blocking@2.0.0: resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} requiresBuild: true - dev: false optional: true /set-cookie-parser@2.6.0: resolution: {integrity: sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==} - dev: false /set-function-length@1.1.1: resolution: {integrity: sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==} @@ -4841,19 +5326,19 @@ packages: object-inspect: 1.13.1 dev: true + /siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + /signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} requiresBuild: true - dev: false /signal-exit@4.1.0: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} - dev: false /simple-concat@1.0.1: resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} - dev: false /simple-get@4.0.1: resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} @@ -4861,7 +5346,6 @@ packages: decompress-response: 6.0.0 once: 1.4.0 simple-concat: 1.0.1 - dev: false /slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} @@ -4872,7 +5356,6 @@ packages: resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} requiresBuild: true - dev: false optional: true /socks-proxy-agent@6.2.1: @@ -4885,7 +5368,6 @@ packages: socks: 2.7.1 transitivePeerDependencies: - supports-color - dev: false optional: true /socks@2.7.1: @@ -4895,14 +5377,12 @@ packages: dependencies: ip: 2.0.0 smart-buffer: 4.2.0 - dev: false optional: true /sonic-boom@3.8.0: resolution: {integrity: sha512-ybz6OYOUjoQQCQ/i4LU8kaToD8ACtYP+Cj5qd2AO36bwbdewxWJ3ArmJ2cr6AvxlL2o0PqnCcPGUgkILbfkaCA==} dependencies: atomic-sleep: 1.0.0 - dev: false /sort-keys@4.2.0: resolution: {integrity: sha512-aUYIEU/UviqPgc8mHR6IW1EGxkAXpeRETYcrzg8cLAvUPZcpAlleSXHV2mY7G12GphSH6Gzv+4MMVSSkbdteHg==} @@ -4911,6 +5391,10 @@ packages: is-plain-obj: 2.1.0 dev: false + /source-map-js@1.0.2: + resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} + engines: {node: '>=0.10.0'} + /source-map-support@0.5.21: resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} dependencies: @@ -4921,7 +5405,6 @@ packages: /source-map@0.6.1: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} - dev: false /sourcemap-codec@1.4.8: resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} @@ -4937,7 +5420,6 @@ packages: /split2@4.2.0: resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} engines: {node: '>= 10.x'} - dev: false /sqlite3@5.1.7: resolution: {integrity: sha512-GGIyOiFaG+TUra3JIfkI/zGP8yZYLPQ0pl1bH+ODjiX57sPhrLU5sQJn1y9bDKZUFYkX1crlrPfSYt0BKKdkog==} @@ -4955,7 +5437,6 @@ packages: transitivePeerDependencies: - bluebird - supports-color - dev: false /ssri@8.0.1: resolution: {integrity: sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==} @@ -4963,9 +5444,11 @@ packages: requiresBuild: true dependencies: minipass: 3.3.6 - dev: false optional: true + /stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + /stacktracey@2.1.8: resolution: {integrity: sha512-Kpij9riA+UNg7TnphqjH7/CzctQ/owJGNbFkfEeve4Z4uxT5+JapVLFXcsurIfN34gnTWZNJ/f7NMG0E8JDzTw==} dependencies: @@ -4973,6 +5456,9 @@ packages: get-source: 2.0.12 dev: false + /std-env@3.7.0: + resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} + /stdin-discarder@0.2.2: resolution: {integrity: sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==} engines: {node: '>=18'} @@ -4998,7 +5484,6 @@ packages: emoji-regex: 8.0.0 is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 - dev: false /string-width@5.1.2: resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} @@ -5062,7 +5547,6 @@ packages: requiresBuild: true dependencies: safe-buffer: 5.2.1 - dev: false /strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} @@ -5092,16 +5576,24 @@ packages: engines: {node: '>=6'} dev: false + /strip-final-newline@3.0.0: + resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} + engines: {node: '>=12'} + /strip-json-comments@2.0.1: resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} engines: {node: '>=0.10.0'} - dev: false /strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} dev: true + /strip-literal@1.3.0: + resolution: {integrity: sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==} + dependencies: + acorn: 8.11.3 + /sucrase@3.35.0: resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} engines: {node: '>=16 || 14 >=14.17'} @@ -5146,7 +5638,6 @@ packages: mkdirp-classic: 0.5.3 pump: 3.0.0 tar-stream: 2.2.0 - dev: false /tar-stream@2.2.0: resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} @@ -5157,7 +5648,6 @@ packages: fs-constants: 1.0.0 inherits: 2.0.4 readable-stream: 3.6.2 - dev: false /tar@6.2.0: resolution: {integrity: sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==} @@ -5169,13 +5659,21 @@ packages: minizlib: 2.1.2 mkdirp: 1.0.4 yallist: 4.0.0 - dev: false /tarn@3.0.2: resolution: {integrity: sha512-51LAVKUSZSVfI05vjPESNc5vwqqZpbXCsU+/+wxlOrUjk2SnFTt97v9ZgQrD4YmxYW1Px6w2KjaDitCfkvgxMQ==} engines: {node: '>=8.0.0'} dev: false + /test-exclude@6.0.0: + resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} + engines: {node: '>=8'} + dependencies: + '@istanbuljs/schema': 0.1.3 + glob: 7.2.3 + minimatch: 3.1.2 + dev: true + /text-table@0.2.0: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} dev: true @@ -5193,11 +5691,19 @@ packages: any-promise: 1.3.0 dev: false + /thingies@1.16.0(tslib@2.6.2): + resolution: {integrity: sha512-J23AVs11hSQxuJxvfQyMIaS9z1QpDxOCvMkL3ZxZl8/jmkgmnNGWrlyNxVz6Jbh0U6DuGmHqq6f7zUROfg/ncg==} + engines: {node: '>=10.18'} + peerDependencies: + tslib: ^2 + dependencies: + tslib: 2.6.2 + dev: false + /thread-stream@2.4.1: resolution: {integrity: sha512-d/Ex2iWd1whipbT681JmTINKw0ZwOUBZm7+Gjs64DHuX34mmw8vJL2bFAaNacaW72zYiTJxSHi5abUuOi5nsfg==} dependencies: real-require: 0.2.0 - dev: false /through2@4.0.2: resolution: {integrity: sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==} @@ -5215,6 +5721,17 @@ packages: engines: {node: '>=12'} dev: false + /tinybench@2.6.0: + resolution: {integrity: sha512-N8hW3PG/3aOoZAN5V/NSAEDz0ZixDSSt5b/a05iqtpgfLWMSVuCo7w0k2vVvEjdrIoeGqZzweX2WlyioNIHchA==} + + /tinypool@0.8.1: + resolution: {integrity: sha512-zBTCK0cCgRROxvs9c0CGK838sPkeokNGdQVUUwHAbynHFlmyJYj825f/oRs528HaIJ97lo0pLIlDUzwN+IorWg==} + engines: {node: '>=14.0.0'} + + /tinyspy@2.2.0: + resolution: {integrity: sha512-d2eda04AN/cPOR89F7Xv5bK/jrQEhmcLFe6HFldoeO9AJtps+fqEnh486vnT/8y4bw38pSyxDcTCAq+Ks2aJTg==} + engines: {node: '>=14.0.0'} + /tmp@0.0.33: resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} engines: {node: '>=0.6.0'} @@ -5236,7 +5753,6 @@ packages: /toad-cache@3.7.0: resolution: {integrity: sha512-/m8M+2BJUpoJdgAHoG+baCwBT+tf2VraSfkBgl0Y00qIWt41DJ8R5B8nsEw0I58YwF5IZH6z24/2TobDKnqSWw==} engines: {node: '>=12'} - dev: false /ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} @@ -5294,7 +5810,6 @@ packages: resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} dependencies: safe-buffer: 5.2.1 - dev: false /turbo-darwin-64@1.11.3: resolution: {integrity: sha512-IsOOg2bVbIt3o/X8Ew9fbQp5t1hTHN3fGNQYrPQwMR2W1kIAC6RfbVD4A9OeibPGyEPUpwOH79hZ9ydFH5kifw==} @@ -5363,6 +5878,10 @@ packages: prelude-ls: 1.2.1 dev: true + /type-detect@4.0.8: + resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} + engines: {node: '>=4'} + /type-fest@0.20.2: resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} engines: {node: '>=10'} @@ -5415,11 +5934,18 @@ packages: is-typed-array: 1.1.12 dev: true + /typedi@0.10.0: + resolution: {integrity: sha512-v3UJF8xm68BBj6AF4oQML3ikrfK2c9EmZUyLOfShpJuItAqVBHWP/KtpGinkSsIiP6EZyyb6Z3NXyW9dgS9X1w==} + dev: false + /typescript@5.3.3: resolution: {integrity: sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==} engines: {node: '>=14.17'} hasBin: true + /ufo@1.3.2: + resolution: {integrity: sha512-o+ORpgGwaYQXgqGDwd+hkS4PuZ3QnmqMMxRuajK/a38L6fTpcE5GPIfrf+L/KemFzfUpeUQc1rRS1iDBozvnFA==} + /unbox-primitive@1.0.2: resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} dependencies: @@ -5444,7 +5970,6 @@ packages: requiresBuild: true dependencies: unique-slug: 2.0.2 - dev: false optional: true /unique-slug@2.0.2: @@ -5452,7 +5977,6 @@ packages: requiresBuild: true dependencies: imurmurhash: 0.1.4 - dev: false optional: true /unique-string@2.0.0: @@ -5481,12 +6005,131 @@ packages: /util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} requiresBuild: true - dev: false /v8-compile-cache-lib@3.0.1: resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} dev: false + /v8-to-istanbul@9.2.0: + resolution: {integrity: sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==} + engines: {node: '>=10.12.0'} + dependencies: + '@jridgewell/trace-mapping': 0.3.20 + '@types/istanbul-lib-coverage': 2.0.6 + convert-source-map: 2.0.0 + dev: true + + /vite-node@1.2.0(@types/node@20.10.8): + resolution: {integrity: sha512-ETnQTHeAbbOxl7/pyBck9oAPZZZo+kYnFt1uQDD+hPReOc+wCjXw4r4jHriBRuVDB5isHmPXxrfc1yJnfBERqg==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + dependencies: + cac: 6.7.14 + debug: 4.3.4 + pathe: 1.1.2 + picocolors: 1.0.0 + vite: 5.0.11(@types/node@20.10.8) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + + /vite@5.0.11(@types/node@20.10.8): + resolution: {integrity: sha512-XBMnDjZcNAw/G1gEiskiM1v6yzM4GE5aMGvhWTlHAYYhxb7S3/V1s3m2LDHa8Vh6yIWYYB0iJwsEaS523c4oYA==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + dependencies: + '@types/node': 20.10.8 + esbuild: 0.19.11 + postcss: 8.4.33 + rollup: 4.9.4 + optionalDependencies: + fsevents: 2.3.3 + + /vitest@1.2.0(@types/node@20.10.8): + resolution: {integrity: sha512-Ixs5m7BjqvLHXcibkzKRQUvD/XLw0E3rvqaCMlrm/0LMsA0309ZqYvTlPzkhh81VlEyVZXFlwWnkhb6/UMtcaQ==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/node': ^18.0.0 || >=20.0.0 + '@vitest/browser': ^1.0.0 + '@vitest/ui': ^1.0.0 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + dependencies: + '@types/node': 20.10.8 + '@vitest/expect': 1.2.0 + '@vitest/runner': 1.2.0 + '@vitest/snapshot': 1.2.0 + '@vitest/spy': 1.2.0 + '@vitest/utils': 1.2.0 + acorn-walk: 8.3.1 + cac: 6.7.14 + chai: 4.4.1 + debug: 4.3.4 + execa: 8.0.1 + local-pkg: 0.5.0 + magic-string: 0.30.5 + pathe: 1.1.2 + picocolors: 1.0.0 + std-env: 3.7.0 + strip-literal: 1.3.0 + tinybench: 2.6.0 + tinypool: 0.8.1 + vite: 5.0.11(@types/node@20.10.8) + vite-node: 1.2.0(@types/node@20.10.8) + why-is-node-running: 2.2.2 + transitivePeerDependencies: + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + /wcwidth@1.0.1: resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} dependencies: @@ -5557,12 +6200,19 @@ packages: isexe: 2.0.0 dev: false + /why-is-node-running@2.2.2: + resolution: {integrity: sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==} + engines: {node: '>=8'} + hasBin: true + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + /wide-align@1.1.5: resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} requiresBuild: true dependencies: string-width: 4.2.3 - dev: false optional: true /widest-line@3.1.0: @@ -5636,6 +6286,10 @@ packages: engines: {node: '>=10'} dev: true + /yocto-queue@1.0.0: + resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==} + engines: {node: '>=12.20'} + /zod@3.22.4: resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} dev: false diff --git a/vitest.config.ts b/vitest.config.ts new file mode 100644 index 0000000..4f340b1 --- /dev/null +++ b/vitest.config.ts @@ -0,0 +1,14 @@ +/// + +import { defineConfig } from 'vite'; + +export default defineConfig({ + test: { + coverage: { + reporter: ['text', 'json-summary', 'json', 'html'], + reportOnFailure: true, + include: ['packages/*/src/**/*.ts'], + exclude: ['packages/examples/**/*', 'packages/tests/**/*'], + }, + }, +}); diff --git a/vitest.workspace.ts b/vitest.workspace.ts new file mode 100644 index 0000000..a971dee --- /dev/null +++ b/vitest.workspace.ts @@ -0,0 +1 @@ +export default ['packages/*'];