diff --git a/.gitignore b/.gitignore index 59ab18a925..02554be26a 100644 --- a/.gitignore +++ b/.gitignore @@ -18,7 +18,6 @@ lerna-debug.log # forest-bff openapi --output default destination openapi.json - # yarn yarn-error.log .vscode/settings.json diff --git a/packages/agent-bff/.gitignore b/packages/agent-bff/.gitignore new file mode 100644 index 0000000000..e8613505a6 --- /dev/null +++ b/packages/agent-bff/.gitignore @@ -0,0 +1,2 @@ +# document and client written by the OpenAPI codegen verification test +test/openapi/.generated diff --git a/packages/agent-bff/package.json b/packages/agent-bff/package.json index 14d0446677..97b3c1ac5c 100644 --- a/packages/agent-bff/package.json +++ b/packages/agent-bff/package.json @@ -41,6 +41,7 @@ "zod": "4.3.6" }, "devDependencies": { + "@hey-api/openapi-ts": "0.99.0", "@redocly/cli": "2.35.1", "@types/jsonwebtoken": "^9.0.1", "@types/koa": "^2.13.5", diff --git a/packages/agent-bff/test/openapi/openapi-generated-client.test.ts b/packages/agent-bff/test/openapi/openapi-generated-client.test.ts new file mode 100644 index 0000000000..09c7f80911 --- /dev/null +++ b/packages/agent-bff/test/openapi/openapi-generated-client.test.ts @@ -0,0 +1,460 @@ +import type { Action, AgentActionClient } from '../../src/action/agent-action-client'; +import type { AgentDataClient } from '../../src/data/agent-data-client'; +import type { Logger } from '../../src/ports/logger-port'; +import type ReadModelStore from '../../src/read-model/read-model-store'; +import type { Server } from 'http'; + +import { bodyParser } from '@koa/bodyparser'; +import { spawnSync } from 'child_process'; +import { existsSync, readFileSync, rmSync } from 'fs'; +import Koa from 'koa'; +import path from 'path'; + +import createActionRoutesMiddleware from '../../src/action/action-routes-middleware'; +import dispatchCli from '../../src/cli-dispatch'; +import createDataRoutesMiddleware from '../../src/data/data-routes-middleware'; +import createErrorMiddleware from '../../src/http/error-middleware'; +import ReadModel from '../../src/read-model/read-model'; +import createTimezoneMiddleware, { TIMEZONE_HEADER } from '../../src/timezone/timezone-middleware'; +import { action, collection, column, relation } from '../read-model/fixtures'; + +const MARK_AS_PAID = 'Mark as paid'; +const GENERATE_INVOICE = 'Générer la facture'; +// A name carrying the path separator: raw in the document it would not resolve to any route. +const SPLIT_INVOICE = 'Facture 50/50'; + +// One fixture for both sides: the document is generated from this schema and these capabilities, and +// the chain the generated client calls runs on the very same ones. Two sources would let the test go +// green while the document described a surface the runtime does not have. +const SCHEMA = [ + collection( + 'users', + [column('id'), column('email'), relation('orders', 'HasMany', 'orders.userId')], + [ + action(MARK_AS_PAID, '/forest/users/actions/mark-as-paid'), + action(GENERATE_INVOICE, '/forest/users/actions/generer-la-facture'), + action(SPLIT_INVOICE, '/forest/users/actions/facture-50-50'), + ], + ), + collection('orders', [column('id')]), +]; + +// Deliberately a single operator: it makes the negative control below unambiguous, since any other +// operator is then out of the documented set without being unmappable (which would answer 500). +const CAPABILITIES = { fields: [{ name: 'id', type: 'Number', operators: ['equal'] }] }; + +const DOCUMENTED_OPERATOR = 'Equal'; +const UNDOCUMENTED_OPERATOR = 'GreaterThan'; + +const fetchSchema = jest.fn().mockResolvedValue(SCHEMA); +const fetchCapabilities = jest.fn().mockResolvedValue(CAPABILITIES); + +jest.mock('../../src/read-model/forest-schema-client', () => ({ + __esModule: true, + default: class { + // eslint-disable-next-line class-methods-use-this + fetchSchema() { + return fetchSchema(); + } + }, +})); + +jest.mock('../../src/read-model/agent-capabilities-fetcher', () => ({ + __esModule: true, + default: () => fetchCapabilities, +})); + +const ENV = { + FOREST_AUTH_SECRET: 'auth-secret', + FOREST_ENV_SECRET: 'env-secret', + FOREST_SERVER_URL: 'https://api.forestadmin.com', + AGENT_URL: 'https://agent.example.com', + HTTP_PORT: '0', +} satisfies NodeJS.ProcessEnv; + +const TIMEZONE = 'Europe/Paris'; +const API_KEY = 'fixture-bff-key'; +const RECORD_ID = '1'; + +const GENERATED_DIR = path.join(__dirname, '.generated'); +const DOCUMENT_FILE = path.join(GENERATED_DIR, 'openapi.json'); +const CLIENT_DIR = path.join(GENERATED_DIR, 'client'); +const SDK_FILE = path.join(CLIENT_DIR, 'sdk.gen.ts'); + +const CODEGEN_BIN = path.join( + path.dirname(require.resolve('@hey-api/openapi-ts/package.json')), + 'bin/run.js', +); + +const CODEGEN_TIMEOUT_MS = 60_000; + +const noopLogger: Logger = () => undefined; + +interface CallResult { + response: { status: number }; + data?: unknown; + error?: unknown; +} + +type Call = (options?: Record) => Promise; + +interface GeneratedClient { + setConfig: (config: Record) => unknown; +} + +const OPERATIONS = [ + 'listRecordsUsers', + 'countRecordsUsers', + 'listRecordsOrders', + 'countRecordsOrders', + 'listRelatedRecordsUsersOrders', + 'countRelatedRecordsUsersOrders', + 'getActionFormUsersMarkAsPaid', + 'executeActionUsersMarkAsPaid', + 'getActionFormUsersGNRerLaFacture', + 'executeActionUsersGNRerLaFacture', + 'getActionFormUsersFacture5050', + 'executeActionUsersFacture5050', +] as const; + +const dataClient: AgentDataClient = { + list: async () => [{ id: 1, email: 'someone@example.com' }], + countRaw: async () => ({ count: 1 }), + listRelation: async () => [{ id: 7 }], + countRelationRaw: async () => ({ count: 1 }), +}; + +function makeAction(): Action { + return { + tryToSetFields: async () => [], + setFields: async () => undefined, + execute: async () => ({ success: 'Done' }), + getFields: () => [ + { + getName: () => 'comment', + getType: () => 'String', + getValue: () => null, + isRequired: () => false, + }, + ], + getEnumField: () => ({ getOptions: () => undefined }), + getLayout: () => ({ layout: [] }), + }; +} + +const actionClient: AgentActionClient = { loadAction: async () => makeAction() }; + +function storeOf(readModel: ReadModel): ReadModelStore { + return { + getReadModel: async () => readModel, + getCapabilities: async () => ({ capabilities: CAPABILITIES, readModel }), + } as unknown as ReadModelStore; +} + +const receivedKeys: string[] = []; + +function buildApp(): Koa { + const store = storeOf(new ReadModel(SCHEMA)); + const app = new Koa(); + app.silent = true; + app.use(createErrorMiddleware({ logger: noopLogger })); + app.use(bodyParser()); + app.use(async (ctx, next) => { + receivedKeys.push(ctx.get('X-Forest-Bff-Key')); + // Auth is out of this test's scope (the gate is its own ticket): the request arrives with agent + // credentials already resolved, exactly as the auth chain would have left it. + ctx.state.agentToken = 'agent-jwt'; + await next(); + }); + app.use(createTimezoneMiddleware({ defaultTimezone: TIMEZONE })); + app.use( + createDataRoutesMiddleware({ + store, + agentUrl: ENV.AGENT_URL, + logger: noopLogger, + createClient: () => dataClient, + }), + ); + app.use( + createActionRoutesMiddleware({ + store, + agentUrl: ENV.AGENT_URL, + logger: noopLogger, + createClient: () => actionClient, + }), + ); + + return app; +} + +function documentedOperators(document: { + components: { schemas: Record }; +}): string[] { + const leaf = document.components.schemas['FilterLeaf_users-1']; + + return leaf?.properties?.operator?.enum ?? []; +} + +describe('a client generated from the emitted OpenAPI document', () => { + let codegenOutput: string; + let document: ReturnType; + let sdk: Record; + let server: Server; + + beforeAll(async () => { + rmSync(GENERATED_DIR, { recursive: true, force: true }); + + // The command writes its own progress to stderr. Silenced so the run stays readable, but kept: + // it is the only account of why an emission failed. + // Read out before restoring, not after: `mockRestore` clears `mock.calls`, so a message built + // from the spy afterwards would always be empty — which is the whole account of a failure here. + const stderr = jest.spyOn(process.stderr, 'write').mockReturnValue(true); + let written = ''; + const emitted = await dispatchCli( + ['openapi', '--output', DOCUMENT_FILE], + ENV, + noopLogger, + ).finally(() => { + written = stderr.mock.calls.flat().join(''); + stderr.mockRestore(); + }); + + if (emitted.exitCode !== 0) { + throw new Error(`The CLI could not emit the document: ${written}`.trim()); + } + + // Timed out rather than left to the `beforeAll` deadline: `spawnSync` blocks the event loop, so a + // codegen child that hangs would hang the whole Jest run until CI kills the job. `--no-log-file` + // because a failing run otherwise drops an `openapi-ts-error-*.log` in the working directory. + const result = spawnSync( + process.execPath, + [CODEGEN_BIN, '--input', DOCUMENT_FILE, '--output', CLIENT_DIR, '--silent', '--no-log-file'], + { + encoding: 'utf8', + timeout: CODEGEN_TIMEOUT_MS, + // Cleared so a Node warning inherited from the parent cannot land in the output this file + // asserts on: what is measured here is the document, not the runner's flags. + env: { ...process.env, NODE_OPTIONS: '' }, + }, + ); + codegenOutput = `${result.stdout ?? ''}${result.stderr ?? ''}`; + + // Before requiring anything it generated: a failed codegen leaves no `sdk.gen.ts`, and the + // MODULE_NOT_FOUND that follows would bury the tool's own account of what it choked on. The file + // is checked as well as the status, because this codegen reports some failures — a missing input + // among them — on its output while still exiting 0. + if (result.status !== 0 || !existsSync(SDK_FILE)) { + throw new Error( + `The codegen could not consume the document (status ${result.status}${ + result.error ? `, ${result.error.message}` : '' + }): ${codegenOutput || `nothing was written to ${SDK_FILE}`}`.trim(), + ); + } + + document = JSON.parse(readFileSync(DOCUMENT_FILE, 'utf8')); + + // eslint-disable-next-line global-require, import/no-dynamic-require + sdk = require(SDK_FILE); + // eslint-disable-next-line global-require, import/no-dynamic-require, @typescript-eslint/no-var-requires + const { client } = require(path.join(CLIENT_DIR, 'client.gen.ts')) as { + client: GeneratedClient; + }; + + server = buildApp().listen(0); + const { port } = server.address() as { port: number }; + + client.setConfig({ + baseUrl: `http://127.0.0.1:${port}`, + auth: () => API_KEY, + headers: { [TIMEZONE_HEADER]: TIMEZONE }, + }); + }, CODEGEN_TIMEOUT_MS * 2); + + afterAll(async () => { + // Awaited: a fire-and-forget close can leave the port open into the next suite. + if (server?.listening) { + await new Promise((resolve, reject) => { + server.close(error => (error ? reject(error) : resolve())); + }); + } + + rmSync(GENERATED_DIR, { recursive: true, force: true }); + }); + + beforeEach(() => { + receivedKeys.length = 0; + }); + + describe('when a standard codegen reads the document', () => { + it('should generate without a warning, since a warning is the document confusing the tool', () => { + expect(codegenOutput).toBe(''); + }); + + it('should expose one function per documented operation, named after its operationId', () => { + expect(OPERATIONS.filter(name => typeof sdk[name] !== 'function')).toEqual([]); + }); + + it('should carry the documented operator set into the generated types', () => { + const types = readFileSync(path.join(CLIENT_DIR, 'types.gen.ts'), 'utf8'); + + const operators = documentedOperators(document); + + // Asserted against the literal first: both sides of the filter below derive from the document, + // so an empty enum would satisfy it vacuously. + expect(operators).toEqual([DOCUMENTED_OPERATOR]); + expect(operators.filter(operator => !types.includes(`'${operator}'`))).toEqual([]); + }); + }); + + describe('when the generated client lists and counts a collection', () => { + it('should reach the collection list endpoint', async () => { + const { response, data } = await sdk.listRecordsUsers({ + body: { projection: ['id'], sort: [{ field: 'id', direction: 'asc' }] }, + }); + + expect({ status: response.status, data }).toEqual({ + status: 200, + data: { + data: [ + { + id: 1, + email: 'someone@example.com', + __forest: { collection: 'users', primaryKey: { id: '1' } }, + }, + ], + meta: { countStatus: 'not_requested' }, + }, + }); + }); + + it('should reach the collection count endpoint', async () => { + const { response, data } = await sdk.countRecordsUsers({ body: {} }); + + expect({ status: response.status, data }).toEqual({ + status: 200, + data: { count: 1, countStatus: 'available' }, + }); + }); + + it('should send the credential under the documented security scheme', async () => { + await sdk.countRecordsUsers({ body: {} }); + + expect(receivedKeys).toEqual([API_KEY]); + }); + }); + + describe('when the generated client lists and counts a relation', () => { + it('should reach the relation list endpoint', async () => { + const { response, data } = await sdk.listRelatedRecordsUsersOrders({ + body: { parentId: RECORD_ID, projection: ['id'] }, + }); + + expect({ status: response.status, data }).toEqual({ + status: 200, + data: { + data: [{ id: 7, __forest: { collection: 'orders', primaryKey: { id: '7' } } }], + meta: { countStatus: 'not_requested' }, + }, + }); + }); + + it('should reach the relation count endpoint', async () => { + const { response, data } = await sdk.countRelatedRecordsUsersOrders({ + body: { parentId: RECORD_ID }, + }); + + expect({ status: response.status, data }).toEqual({ + status: 200, + data: { count: 1, countStatus: 'available' }, + }); + }); + }); + + describe('when the generated client drives an action', () => { + it('should load the form', async () => { + const { response, data } = await sdk.getActionFormUsersMarkAsPaid({ + body: { recordIds: [RECORD_ID] }, + }); + + expect({ status: response.status, data }).toEqual({ + status: 200, + data: { + fields: [{ name: 'comment', type: 'String', value: null, isRequired: false }], + canExecute: true, + requiredFields: [], + skippedFields: [], + layout: [], + }, + }); + }); + + it('should execute the action', async () => { + const { response, data } = await sdk.executeActionUsersMarkAsPaid({ + body: { recordIds: [RECORD_ID], values: { comment: 'paid' } }, + }); + + expect({ status: response.status, data }).toEqual({ + status: 200, + data: { type: 'success', message: 'Done', invalidated: [], html: null }, + }); + }); + + it('should reach an action whose name carries an accent', async () => { + const form = await sdk.getActionFormUsersGNRerLaFacture({ body: { recordIds: [RECORD_ID] } }); + const executed = await sdk.executeActionUsersGNRerLaFacture({ + body: { recordIds: [RECORD_ID] }, + }); + + expect([form.response.status, executed.response.status]).toEqual([200, 200]); + }); + + // The separator is what makes this more than a formality: a raw name would split the path into + // segments the route cannot match, so only a percent-encoded document resolves here. + it('should reach an action whose name carries the path separator', async () => { + const form = await sdk.getActionFormUsersFacture5050({ body: { recordIds: [RECORD_ID] } }); + const executed = await sdk.executeActionUsersFacture5050({ + body: { recordIds: [RECORD_ID] }, + }); + + expect([form.response.status, executed.response.status]).toEqual([200, 200]); + }); + }); + + describe("when the generated client filters on a documented field's operator", () => { + it('should document exactly the capabilities operator, normalized', () => { + expect(documentedOperators(document)).toEqual([DOCUMENTED_OPERATOR]); + }); + + it('should be accepted for every operator the document advertises', async () => { + const statuses = await Promise.all( + documentedOperators(document).map(async operator => { + const { response } = await sdk.listRecordsUsers({ + body: { filter: { field: 'id', operator, value: 1 } }, + }); + + return [operator, response.status]; + }), + ); + + expect(statuses).toEqual([[DOCUMENTED_OPERATOR, 200]]); + }); + + it('should be rejected for an operator the document leaves out, so the enum means something', async () => { + const { response, error } = await sdk.listRecordsUsers({ + body: { filter: { field: 'id', operator: UNDOCUMENTED_OPERATOR, value: 1 } }, + }); + + expect({ status: response.status, error }).toEqual({ + status: 400, + error: { + error: { + type: 'invalid_filter_operator', + status: 400, + message: expect.stringContaining('id'), + details: { field: 'id', validOperators: [DOCUMENTED_OPERATOR] }, + }, + }, + }); + }); + }); +}); diff --git a/yarn.lock b/yarn.lock index a38e6baca2..3dfb58df22 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1844,6 +1844,67 @@ dependencies: "@hapi/hoek" "^9.0.0" +"@hey-api/codegen-core@0.9.1": + version "0.9.1" + resolved "https://registry.yarnpkg.com/@hey-api/codegen-core/-/codegen-core-0.9.1.tgz#e66bcc294ee16c4dcb8b8750b70e62d3b53f5fea" + integrity sha512-s97jL1dgTMuiMHv2BZ1X4Tgd99Mf9GOvGdNqNcGwIMmnR+PgYNoraj4Zvp134MKsNCap/m7k0r0vKKnl56pj4w== + dependencies: + "@hey-api/types" "0.1.4" + ansi-colors "4.1.3" + c12 "3.3.4" + color-support "1.1.3" + +"@hey-api/json-schema-ref-parser@1.4.4": + version "1.4.4" + resolved "https://registry.yarnpkg.com/@hey-api/json-schema-ref-parser/-/json-schema-ref-parser-1.4.4.tgz#d5108418ab5af0bffbace5813256248662f32039" + integrity sha512-otmd+zCxbYVBIp/mlMTnGkvlNYLkVKgs3VOIq0kSnenhB1+fRwLPQIeSwyWM6E51oXhUedkYjVsVpkVexeuJOA== + dependencies: + "@jsdevtools/ono" "7.1.3" + "@types/json-schema" "7.0.15" + js-yaml "4.2.0" + +"@hey-api/openapi-ts@0.99.0": + version "0.99.0" + resolved "https://registry.yarnpkg.com/@hey-api/openapi-ts/-/openapi-ts-0.99.0.tgz#d55d0636f40490000aa0efbe1b193610fc2c4992" + integrity sha512-SePU/5oEWWkvUBYmvzdYRctseoLuskyhs4ET0RvLIcmzc8yLQoA2R+KtBIQ8bPsoSUB0m4E5SmBnl6aGSA0szQ== + dependencies: + "@hey-api/codegen-core" "0.9.1" + "@hey-api/json-schema-ref-parser" "1.4.4" + "@hey-api/shared" "0.5.0" + "@hey-api/spec-types" "0.2.0" + "@hey-api/types" "0.1.4" + "@lukeed/ms" "2.0.2" + ansi-colors "4.1.3" + color-support "1.1.3" + commander "15.0.0" + get-tsconfig "4.14.0" + +"@hey-api/shared@0.5.0": + version "0.5.0" + resolved "https://registry.yarnpkg.com/@hey-api/shared/-/shared-0.5.0.tgz#89a07225eb15d69b0881a106109158861ea8b46a" + integrity sha512-JN/j4Ebh4cJGYIQ5cwWuqe7GeSUyQoz7oC51WqyhKOcrejK6DKZMDkshc5d1eKTRuRL+rjozuRcoUaZZn2DGPw== + dependencies: + "@hey-api/codegen-core" "0.9.1" + "@hey-api/json-schema-ref-parser" "1.4.4" + "@hey-api/spec-types" "0.2.0" + "@hey-api/types" "0.1.4" + ansi-colors "4.1.3" + cross-spawn "7.0.6" + open "11.0.0" + semver "7.8.4" + +"@hey-api/spec-types@0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@hey-api/spec-types/-/spec-types-0.2.0.tgz#5b6dcdd1bdeb978033f0d250654ec4d440e90030" + integrity sha512-ibQ8Is7evMavzr8GNyJCcTg975d8DpaMUyLmOrQ85UBdy1l6t1KuRAwgChAbesJsIlNV6gjmlXruWyegDX18Fg== + dependencies: + "@hey-api/types" "0.1.4" + +"@hey-api/types@0.1.4": + version "0.1.4" + resolved "https://registry.yarnpkg.com/@hey-api/types/-/types-0.1.4.tgz#d73731c8ffb5d5b898c01288ca7dfbc367b561ea" + integrity sha512-thWfawrDIP7wSI9ioT13I5soaaqB5vAPIiZmgD8PbeEVKNrkonc0N/Sjj97ezl7oQgusZmaNphGdMKipPO6IBg== + "@hono/node-server@^1.19.9 || ^2.0.5": version "2.1.1" resolved "https://registry.yarnpkg.com/@hono/node-server/-/node-server-2.1.1.tgz#9cfa8649e9ecbcd48edf505b103002402ea51e70" @@ -2466,6 +2527,11 @@ resolved "https://registry.yarnpkg.com/@js-joda/core/-/core-5.6.3.tgz#41ae1c07de1ebe0f6dde1abcbc9700a09b9c6056" integrity sha512-T1rRxzdqkEXcou0ZprN1q9yDRlvzCPLqmlNt5IIsGBzoEVgLCCYrKEwc84+TvsXuAc95VAZwtWD2zVsKPY4bcA== +"@jsdevtools/ono@7.1.3": + version "7.1.3" + resolved "https://registry.yarnpkg.com/@jsdevtools/ono/-/ono-7.1.3.tgz#9df03bbd7c696a5c58885c34aa06da41c8543796" + integrity sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg== + "@koa/bodyparser@^6.0.0": version "6.0.0" resolved "https://registry.yarnpkg.com/@koa/bodyparser/-/bodyparser-6.0.0.tgz#e362ddb3691276064f36e8cbf79b66f5873360a0" @@ -2592,6 +2658,11 @@ resolved "https://registry.yarnpkg.com/@lukeed/csprng/-/csprng-1.1.0.tgz#1e3e4bd05c1cc7a0b2ddbd8a03f39f6e4b5e6cfe" integrity sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA== +"@lukeed/ms@2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@lukeed/ms/-/ms-2.0.2.tgz#07f09e59a74c52f4d88c6db5c1054e819538e2a8" + integrity sha512-9I2Zn6+NJLfaGoz9jN3lpwDgAYvfGeNYdbAIjJOqzs4Tpc+VU3Jqq4IofSUBKajiDS8k9fZIg18/z13mpk1bsA== + "@mapbox/node-pre-gyp@^1.0.0": version "1.0.11" resolved "https://registry.yarnpkg.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz#417db42b7f5323d79e93b34a6d7a2a12c0df43fa" @@ -4546,7 +4617,7 @@ resolved "https://registry.yarnpkg.com/@types/json-api-serializer/-/json-api-serializer-2.6.6.tgz#26b5381214aa19bb98a6931fe41c3a336fc7f169" integrity sha512-8XVIVyMNoFMz3pfR3tPHnJ9YlgUQDEWvTxajVakmOjSxWekJvmi2GRFbtaREQiOGtffnHImD0jbR80NQtpib9g== -"@types/json-schema@*", "@types/json-schema@^7.0.15", "@types/json-schema@^7.0.9": +"@types/json-schema@*", "@types/json-schema@7.0.15", "@types/json-schema@^7.0.15", "@types/json-schema@^7.0.9": version "7.0.15" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== @@ -5938,6 +6009,13 @@ builtins@^1.0.3: resolved "https://registry.yarnpkg.com/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88" integrity sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ== +bundle-name@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/bundle-name/-/bundle-name-4.1.0.tgz#f3b96b34160d6431a19d7688135af7cfb8797889" + integrity sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q== + dependencies: + run-applescript "^7.0.0" + busboy@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/busboy/-/busboy-1.6.0.tgz#966ea36a9502e43cdb9146962523b92f531f6893" @@ -5955,6 +6033,24 @@ bytes@3.1.2, bytes@^3.1.2, bytes@~3.1.2: resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== +c12@3.3.4: + version "3.3.4" + resolved "https://registry.yarnpkg.com/c12/-/c12-3.3.4.tgz#1253a5faf8b61244884d42459b4a6412571fe9f3" + integrity sha512-cM0ApFQSBXuourJejzwv/AuPRvAxordTyParRVcHjjtXirtkzM0uK2L9TTn9s0cXZbG7E55jCivRQzoxYmRAlA== + dependencies: + chokidar "^5.0.0" + confbox "^0.2.4" + defu "^6.1.6" + dotenv "^17.3.1" + exsolve "^1.0.8" + giget "^3.2.0" + jiti "^2.6.1" + ohash "^2.0.11" + pathe "^2.0.3" + perfect-debounce "^2.1.0" + pkg-types "^2.3.0" + rc9 "^3.0.1" + cacache@^15.2.0: version "15.3.0" resolved "https://registry.yarnpkg.com/cacache/-/cacache-15.3.0.tgz#dc85380fb2f556fe3dda4c719bfa0ec875a7f1eb" @@ -6208,6 +6304,13 @@ chokidar@^3.5.2: optionalDependencies: fsevents "~2.3.2" +chokidar@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-5.0.0.tgz#949c126a9238a80792be9a0265934f098af369a5" + integrity sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw== + dependencies: + readdirp "^5.0.0" + chownr@^1.1.1: version "1.1.4" resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" @@ -6516,6 +6619,11 @@ combined-stream@1.0.8, combined-stream@^1.0.8: dependencies: delayed-stream "~1.0.0" +commander@15.0.0: + version "15.0.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-15.0.0.tgz#96f3961f12adac1799ef3fbd8bc61d40572d1b11" + integrity sha512-z67u4ZhzCL/Tydu1lJARtEZYWbWaN7oYLHbsuzocr6y4N6WZAagG3RQ4FW61V1/0+jImpj293XfrcYnd1qxtPg== + commander@2.9.0: version "2.9.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" @@ -6583,6 +6691,11 @@ concurrently@^9.0.0: tree-kill "1.2.2" yargs "17.7.2" +confbox@^0.2.4: + version "0.2.4" + resolved "https://registry.yarnpkg.com/confbox/-/confbox-0.2.4.tgz#592e7be71f882a4a874e3c88f0ac1ef6f7da1ce5" + integrity sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ== + config-chain@^1.1.11: version "1.1.13" resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.13.tgz#fad0795aa6a6cdaff9ed1b68e9dff94372c232f4" @@ -6876,6 +6989,15 @@ cross-fetch@^4.0.0: dependencies: node-fetch "^2.7.0" +cross-spawn@7.0.6, cross-spawn@^7.0.2, cross-spawn@^7.0.3, cross-spawn@^7.0.5, cross-spawn@^7.0.6: + version "7.0.6" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" + integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + cross-spawn@^6.0.0: version "6.0.6" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.6.tgz#30d0efa0712ddb7eb5a76e1e8721bffafa6b5d57" @@ -6887,15 +7009,6 @@ cross-spawn@^6.0.0: shebang-command "^1.2.0" which "^1.2.9" -cross-spawn@^7.0.2, cross-spawn@^7.0.3, cross-spawn@^7.0.5, cross-spawn@^7.0.6: - version "7.0.6" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" - integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - crypto-random-string@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-4.0.0.tgz#5a3cc53d7dd86183df5da0312816ceeeb5bb1fc2" @@ -7068,6 +7181,19 @@ deepmerge@^4.2.2: resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== +default-browser-id@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/default-browser-id/-/default-browser-id-5.0.1.tgz#f7a7ccb8f5104bf8e0f71ba3b1ccfa5eafdb21e8" + integrity sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q== + +default-browser@^5.4.0: + version "5.5.1" + resolved "https://registry.yarnpkg.com/default-browser/-/default-browser-5.5.1.tgz#1790affc52680fbb11e17cab2752d69aa2a37d2c" + integrity sha512-m1pAzaJgZ/gssEqlOhJkPJp8Xly7QyW6xcrkUa2KKcDeDSEMP7X8xipU3snUcfisTQx0w1AGae+9UtJSfVnXGw== + dependencies: + bundle-name "^4.1.0" + default-browser-id "^5.0.0" + defaults@1.0.4, defaults@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.4.tgz#b0b02062c1e2aa62ff5d9528f0f98baa90978d7a" @@ -7098,6 +7224,11 @@ define-lazy-prop@2.0.0, define-lazy-prop@^2.0.0: resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== +define-lazy-prop@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz#dbb19adfb746d7fc6d734a06b72f4a00d021255f" + integrity sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg== + define-properties@^1.1.3, define-properties@^1.1.4, define-properties@^1.2.0, define-properties@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c" @@ -7107,6 +7238,11 @@ define-properties@^1.1.3, define-properties@^1.1.4, define-properties@^1.2.0, de has-property-descriptors "^1.0.0" object-keys "^1.1.1" +defu@^6.1.6: + version "6.1.7" + resolved "https://registry.yarnpkg.com/defu/-/defu-6.1.7.tgz#72543567c8e9f97ff13ce402b6dbe09ac5ae4d23" + integrity sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ== + delayed-stream@1.0.0, delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" @@ -7142,6 +7278,11 @@ dequal@^2.0.3: resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be" integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA== +destr@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/destr/-/destr-2.0.5.tgz#7d112ff1b925fb8d2079fac5bdb4a90973b51fdb" + integrity sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA== + destroy@1.2.0, destroy@^1.0.4, destroy@^1.2.0, destroy@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" @@ -7285,6 +7426,11 @@ dotenv@^16.4.5: resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.5.0.tgz#092b49f25f808f020050051d1ff258e404c78692" integrity sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg== +dotenv@^17.3.1: + version "17.4.2" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-17.4.2.tgz#c07e54a746e11eba021dd9e1047ced5afdc1c034" + integrity sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw== + dottie@^2.0.6: version "2.0.7" resolved "https://registry.yarnpkg.com/dottie/-/dottie-2.0.7.tgz#fd1b465a1211b35d5660e95b69bb6d5b5809b3c4" @@ -8250,6 +8396,11 @@ express@^4.17.1, express@^4.18.2: utils-merge "1.0.1" vary "~1.1.2" +exsolve@^1.0.8: + version "1.1.1" + resolved "https://registry.yarnpkg.com/exsolve/-/exsolve-1.1.1.tgz#c055418255459b6ecde4e59de0060a3e97bc7572" + integrity sha512-9U/jZUgjnSGyntRr6y5Muu1MJcwFl6kPu7k8qLF0IMNfLqvw0NZ4nnVDq0RVoZ0RvCyumib4Ez3KYrVfilrw+g== + ext@^1.1.2: version "1.7.0" resolved "https://registry.yarnpkg.com/ext/-/ext-1.7.0.tgz#0ea4383c0103d60e70be99e9a7f11027a33c4f5f" @@ -9138,11 +9289,23 @@ get-symbol-description@^1.1.0: es-errors "^1.3.0" get-intrinsic "^1.2.6" +get-tsconfig@4.14.0: + version "4.14.0" + resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.14.0.tgz#985d85c52a9903864280ccc2448d413fbf1efed8" + integrity sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA== + dependencies: + resolve-pkg-maps "^1.0.0" + getopts@2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/getopts/-/getopts-2.3.0.tgz#71e5593284807e03e2427449d4f6712a268666f4" integrity sha512-5eDf9fuSXwxBL6q5HX+dhDj+dslFGWzU5thZ9kNKUkcPtaPdatmUFKwHFrLb/uf/WpA4BHET+AX3Scl56cAjpA== +giget@^3.2.0: + version "3.3.1" + resolved "https://registry.yarnpkg.com/giget/-/giget-3.3.1.tgz#4a4e610cd112e5dc478c6035986fdc19c76dad73" + integrity sha512-r+mvuDjrjMpsdw46Kmeydb8bdHm7wOKw8wNBtTndkjbPjgAp5oUJUxRE76wZFknxIPokfWvep2qSXK37aXE6zg== + git-log-parser@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/git-log-parser/-/git-log-parser-1.2.0.tgz#2e6a4c1b13fc00028207ba795a7ac31667b9fd4a" @@ -10162,6 +10325,11 @@ is-docker@2.2.1, is-docker@^2.0.0, is-docker@^2.1.1: resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== +is-docker@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-3.0.0.tgz#90093aa3106277d8a77a5910dbae71747e15a200" + integrity sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ== + is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" @@ -10212,6 +10380,18 @@ is-hexadecimal@^1.0.0: resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz#cc35c97588da4bd49a8eedd6bc4082d44dcb23a7" integrity sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw== +is-in-ssh@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-in-ssh/-/is-in-ssh-1.0.0.tgz#8eb73c1cabba77748d389588eeea132a63057622" + integrity sha512-jYa6Q9rH90kR1vKB6NM7qqd1mge3Fx4Dhw5TVlK1MUBqhEOuCagrEHMevNuCcbECmXZ0ThXkRm+Ymr51HwEPAw== + +is-inside-container@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-inside-container/-/is-inside-container-1.0.0.tgz#e81fba699662eb31dbdaf26766a61d4814717ea4" + integrity sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA== + dependencies: + is-docker "^3.0.0" + is-interactive@1.0.0, is-interactive@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" @@ -10481,6 +10661,13 @@ is-wsl@2.2.0, is-wsl@^2.1.1, is-wsl@^2.2.0: dependencies: is-docker "^2.0.0" +is-wsl@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-3.1.1.tgz#327897b26832a3eb117da6c27492d04ca132594f" + integrity sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw== + dependencies: + is-inside-container "^1.0.0" + isarray@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" @@ -10973,6 +11160,11 @@ jest@^29.3.1: import-local "^3.0.2" jest-cli "^29.7.0" +jiti@^2.6.1: + version "2.7.0" + resolved "https://registry.yarnpkg.com/jiti/-/jiti-2.7.0.tgz#974228f2f4ca2bc21885a1797b45fea68e950c64" + integrity sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ== + jju@~1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/jju/-/jju-1.4.0.tgz#a3abe2718af241a2b2904f84a625970f389ae32a" @@ -11023,6 +11215,13 @@ js-yaml@4.1.1, js-yaml@^4.1.0, js-yaml@^4.3.1: dependencies: argparse "^2.0.1" +js-yaml@4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.2.0.tgz#2bd9e85682dd91bd469afb809d816043b3d49524" + integrity sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw== + dependencies: + argparse "^2.0.1" + js-yaml@^3.13.1, js-yaml@^3.14.1, js-yaml@^3.15.1: version "3.15.1" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.15.1.tgz#24bc95028f361cdaaa84745b06a109c4486773c0" @@ -13642,6 +13841,11 @@ object.values@^1.2.1: define-properties "^1.2.1" es-object-atoms "^1.0.0" +ohash@^2.0.11: + version "2.0.12" + resolved "https://registry.yarnpkg.com/ohash/-/ohash-2.0.12.tgz#cb97c19888ff31e7b22214cd7924187fc97ef05c" + integrity sha512-65S/5gk9YSsaRjcyf7Nfa6h/d3E8/1gslpXfI4W7Dxn/oap8IKRuNT5VXkLQ1YFKIEg4apRY4Pj6aiwFzrDdmw== + oidc-token-hash@^5.0.3: version "5.0.3" resolved "https://registry.yarnpkg.com/oidc-token-hash/-/oidc-token-hash-5.0.3.tgz#9a229f0a1ce9d4fc89bcaee5478c97a889e7b7b6" @@ -13692,6 +13896,18 @@ only@~0.0.2: resolved "https://registry.yarnpkg.com/only/-/only-0.0.2.tgz#2afde84d03e50b9a8edc444e30610a70295edfb4" integrity sha512-Fvw+Jemq5fjjyWz6CpKx6w9s7xxqo3+JCyM0WXWeCSOboZ8ABkyvP8ID4CZuChA/wxSx+XSJmdOm8rGVyJ1hdQ== +open@11.0.0: + version "11.0.0" + resolved "https://registry.yarnpkg.com/open/-/open-11.0.0.tgz#897e6132f994d3554cbcf72e0df98f176a7e5f62" + integrity sha512-smsWv2LzFjP03xmvFoJ331ss6h+jixfA4UUV/Bsiyuu4YJPfN+FIQGOIiv4w9/+MoHkfkJ22UIaQWRVFRfH6Vw== + dependencies: + default-browser "^5.4.0" + define-lazy-prop "^3.0.0" + is-in-ssh "^1.0.0" + is-inside-container "^1.0.0" + powershell-utils "^0.1.0" + wsl-utils "^0.3.0" + open@7.3.0: version "7.3.0" resolved "https://registry.yarnpkg.com/open/-/open-7.3.0.tgz#45461fdee46444f3645b6e14eb3ca94b82e1be69" @@ -14249,6 +14465,16 @@ path-type@^4.0.0: resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== +pathe@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/pathe/-/pathe-2.0.3.tgz#3ecbec55421685b70a9da872b2cff3e1cbed1716" + integrity sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w== + +perfect-debounce@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/perfect-debounce/-/perfect-debounce-2.1.0.tgz#e7078e38f231cb191855c3136a4423aef725d261" + integrity sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g== + pg-cloudflare@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz#e6d5833015b170e23ae819e8c5d7eaedb472ca98" @@ -14483,6 +14709,15 @@ pkg-dir@^4.2.0: dependencies: find-up "^4.0.0" +pkg-types@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/pkg-types/-/pkg-types-2.3.1.tgz#fa27ed0940efcf40bba453b0e5cab41217b0d442" + integrity sha512-y+ichcgc2LrADuhLNAx8DFjVfgz91pRxfZdI3UDhxHvcVEZsenLO+7XaU5vOp0u/7V/wZ+plyuQxtrDlZJ+yeg== + dependencies: + confbox "^0.2.4" + exsolve "^1.0.8" + pathe "^2.0.3" + pluralize@8.0.0, pluralize@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-8.0.0.tgz#1a6fa16a38d12a1901e0320fa017051c539ce3b1" @@ -14528,6 +14763,11 @@ postgres-interval@^1.1.0: dependencies: xtend "^4.0.0" +powershell-utils@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/powershell-utils/-/powershell-utils-0.1.0.tgz#5a42c9a824fb4f2f251ccb41aaae73314f5d6ac2" + integrity sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A== + prebuild-install@^7.1.1, prebuild-install@^7.1.3: version "7.1.3" resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.1.3.tgz#d630abad2b147443f20a212917beae68b8092eec" @@ -14852,6 +15092,14 @@ raw-body@~2.5.3: iconv-lite "~0.4.24" unpipe "~1.0.0" +rc9@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/rc9/-/rc9-3.0.1.tgz#3895e5834a2b5c2d8fb76d93e802fbcbc2579bc7" + integrity sha512-gMDyleLWVE+i6Sgtc0QbbY6pEKqYs97NGi6isHQPqYlLemPoO8dxQ3uGi0f4NiP98c+jMW6cG1Kx9dDwfvqARQ== + dependencies: + defu "^6.1.6" + destr "^2.0.5" + rc@^1.2.7, rc@^1.2.8: version "1.2.8" resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" @@ -15015,6 +15263,11 @@ readable-stream@^4.2.0: process "^0.11.10" string_decoder "^1.3.0" +readdirp@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-5.1.1.tgz#520bca06f9d1ae1b96cc0800dbe84b983d19422c" + integrity sha512-Kko+Y5XQ6fM+Ce3dq3m9YGxnacYZYl9cA1wZjaF3Vbry2L3i1qVg8+CAgNPsXRArPMUMCaOR7oa9Nqntc43JKA== + readdirp@~3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" @@ -15186,6 +15439,11 @@ resolve-global@1.0.0, resolve-global@^1.0.0: dependencies: global-dirs "^0.1.1" +resolve-pkg-maps@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz#616b3dc2c57056b5588c31cdf4b3d64db133720f" + integrity sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw== + resolve.exports@2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-2.0.3.tgz#41955e6f1b4013b7586f873749a635dea07ebe3f" @@ -15294,6 +15552,11 @@ router@^2.2.0: parseurl "^1.3.3" path-to-regexp "^8.0.0" +run-applescript@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/run-applescript/-/run-applescript-7.1.0.tgz#2e9e54c4664ec3106c5b5630e249d3d6595c4911" + integrity sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q== + run-async@^2.2.0: version "2.4.1" resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" @@ -15526,6 +15789,11 @@ semver@7.7.4: resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.4.tgz#28464e36060e991fa7a11d0279d2d3f3b57a7e8a" integrity sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA== +semver@7.8.4: + version "7.8.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.8.4.tgz#c73eceebae0616934be8dff28a7fd70757c8e696" + integrity sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA== + semver@^6.0.0, semver@^6.3.0, semver@^6.3.1: version "6.3.1" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" @@ -17836,6 +18104,14 @@ ws@^8.20.1: resolved "https://registry.yarnpkg.com/ws/-/ws-8.21.0.tgz#012e413fc07429945121b0c153158c4343086951" integrity sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g== +wsl-utils@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/wsl-utils/-/wsl-utils-0.3.1.tgz#9479836ddf03be267aad3abfc3cb1f6e0c9f1ed1" + integrity sha512-g/eziiSUNBSsdDJtCLB8bdYEUMj4jR7AGeUo96p/3dTafgjHhpF4RiCFPiRILwjQoDXx5MqkBr4fwWtR3Ky4Wg== + dependencies: + is-wsl "^3.1.0" + powershell-utils "^0.1.0" + xml-naming@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/xml-naming/-/xml-naming-0.1.0.tgz#8ab7106c5b8d23caa2fabac1cadf17136379fbd8"