diff --git a/.changeset/dry-jeans-ring.md b/.changeset/dry-jeans-ring.md new file mode 100644 index 000000000..f6fbade05 --- /dev/null +++ b/.changeset/dry-jeans-ring.md @@ -0,0 +1,10 @@ +--- +'@hey-api/openapi-ts': minor +'@hey-api/custom-client': patch +'@hey-api/codegen-core': patch +'@hey-api/vite-plugin': patch +'@hey-api/nuxt': patch +'@docs/openapi-ts': patch +--- + +feat: expand configuration by allowing multiple configs, inputs and outputs diff --git a/docs/openapi-ts/configuration.md b/docs/openapi-ts/configuration.md index c0d117a06..83abbf201 100644 --- a/docs/openapi-ts/configuration.md +++ b/docs/openapi-ts/configuration.md @@ -38,6 +38,40 @@ export default { Alternatively, you can use `openapi-ts.config.js` and configure the export statement depending on your project setup. +### Async config and factories + +You can also export a function (sync or async) if you need to compute configuration dynamically (e.g., read env vars): + +```js +import { defineConfig } from '@hey-api/openapi-ts'; + +export default defineConfig(async () => { + return { + input: 'hey-api/backend', + output: 'src/client', + }; +}); +``` + +### Multiple configurations + +You can also export an array to run multiple configurations in a single invocation (e.g., generate multiple clients): + +```js +import { defineConfig } from '@hey-api/openapi-ts'; + +export default defineConfig([ + { + input: 'path/to/openapi_one.json', + output: 'src/client_one', + }, + { + input: 'path/to/openapi_two.json', + output: 'src/client_two', + }, +]); +``` + +```js [array] +export default { + input: [ + // [!code ++] + 'hey-api/backend', // [!code ++] + './overrides/openapi.yaml', // [!code ++] + ], // [!code ++] +}; +// When you pass multiple inputs as an array, `@hey-api/openapi-ts` bundles them into a single resolved OpenAPI +// document. To avoid name collisions between files, component names may be prefixed with the input file’s base +// name when needed (for example, `users.yaml` ➜ `users.*`). References across files are resolved, and +// later inputs in the array can override earlier ones on conflict. +``` + ::: ::: info diff --git a/docs/openapi-ts/configuration/output.md b/docs/openapi-ts/configuration/output.md index 660b12097..ddce8ec86 100644 --- a/docs/openapi-ts/configuration/output.md +++ b/docs/openapi-ts/configuration/output.md @@ -32,6 +32,20 @@ export default { ``` +```js [array] +export default { + input: 'hey-api/backend', // sign up at app.heyapi.dev + output: [ + // [!code ++] + 'src/client', // [!code ++] + { path: 'src/client-formatted', format: 'prettier' }, // [!code ++] + { path: 'src/client-linted', lint: 'eslint', clean: false }, // [!code ++] + ], // [!code ++] +}; +``` + + + ::: ## Format diff --git a/packages/openapi-ts-tests/main/test/2.0.x.test.ts b/packages/openapi-ts-tests/main/test/2.0.x.test.ts index 4be3857bd..866befbbc 100644 --- a/packages/openapi-ts-tests/main/test/2.0.x.test.ts +++ b/packages/openapi-ts-tests/main/test/2.0.x.test.ts @@ -21,7 +21,9 @@ describe(`OpenAPI ${version}`, () => { version, typeof userConfig.input === 'string' ? userConfig.input - : (userConfig.input.path as string), + : userConfig.input instanceof Array + ? (userConfig.input[0] as any).path || userConfig.input[0] + : (userConfig.input as any).path, ); return { plugins: ['@hey-api/typescript'], @@ -409,4 +411,192 @@ describe(`OpenAPI ${version}`, () => { }), ); }); + + describe('multi config', () => { + it('generates outputs for all configs', async () => { + const configA = createConfig({ + input: 'external.yaml', + output: 'multi-external', + }); + const configB = createConfig({ + input: 'enum-names-values.json', + output: 'multi-enum-names-values', + }); + + await createClient([configA, configB]); + + const outputPathA = + typeof configA.output === 'string' + ? configA.output + : configA.output.path; + const outputPathB = + typeof configB.output === 'string' + ? configB.output + : configB.output.path; + + const filesA = getFilePaths(outputPathA); + const filesB = getFilePaths(outputPathB); + + await Promise.all( + filesA.map(async (filePath) => { + const fileContent = fs.readFileSync(filePath, 'utf-8'); + await expect(fileContent).toMatchFileSnapshot( + path.join( + __dirname, + '__snapshots__', + version, + filePath.slice(outputDir.length + 1), + ), + ); + }), + ); + + await Promise.all( + filesB.map(async (filePath) => { + const fileContent = fs.readFileSync(filePath, 'utf-8'); + await expect(fileContent).toMatchFileSnapshot( + path.join( + __dirname, + '__snapshots__', + version, + filePath.slice(outputDir.length + 1), + ), + ); + }), + ); + }); + }); + + describe('multi input', () => { + it('parses multiple inputs (object + string) without errors', async () => { + const specsBase = path.join(getSpecsPath(), version); + await expect( + createClient({ + dryRun: true, + input: [ + { path: path.join(specsBase, 'multi-a.json') }, + path.join(specsBase, 'multi-b.json'), + ], + logs: { level: 'silent' }, + output: path.join(outputDir, 'multi-input'), + plugins: ['@hey-api/typescript'], + }), + ).resolves.not.toThrow(); + }); + }); + + describe('multi output', () => { + it('generates multiple string outputs without errors', async () => { + const results = await createClient({ + input: path.join(getSpecsPath(), version, 'external.yaml'), + logs: { level: 'silent' }, + output: [ + path.join(outputDir, 'multi-output-string-1'), + path.join(outputDir, 'multi-output-string-2'), + ], + plugins: ['@hey-api/typescript'], + }); + + expect(results).toHaveLength(2); + + // Verify both output directories were created + expect(fs.existsSync(path.join(outputDir, 'multi-output-string-1'))).toBe( + true, + ); + expect(fs.existsSync(path.join(outputDir, 'multi-output-string-2'))).toBe( + true, + ); + }); + + it('generates multiple output objects with different configurations', async () => { + const results = await createClient({ + input: path.join(getSpecsPath(), version, 'external.yaml'), + logs: { level: 'silent' }, + output: [ + { + clean: true, + indexFile: true, + path: path.join(outputDir, 'multi-output-config-1'), + }, + { + clean: false, + indexFile: false, + path: path.join(outputDir, 'multi-output-config-2'), + }, + ], + plugins: ['@hey-api/typescript'], + }); + + expect(results).toHaveLength(2); + + // Verify both output directories were created + expect(fs.existsSync(path.join(outputDir, 'multi-output-config-1'))).toBe( + true, + ); + expect(fs.existsSync(path.join(outputDir, 'multi-output-config-2'))).toBe( + true, + ); + + // Verify index files are created/not created based on configuration + expect( + fs.existsSync( + path.join(outputDir, 'multi-output-config-1', 'index.ts'), + ), + ).toBe(true); + expect( + fs.existsSync( + path.join(outputDir, 'multi-output-config-2', 'index.ts'), + ), + ).toBe(false); + }); + + it('generates mixed string and object outputs', async () => { + const results = await createClient({ + input: path.join(getSpecsPath(), version, 'external.yaml'), + logs: { level: 'silent' }, + output: [ + path.join(outputDir, 'multi-output-mixed-string'), + { + indexFile: false, + path: path.join(outputDir, 'multi-output-mixed-object'), + }, + ], + plugins: ['@hey-api/typescript'], + }); + + expect(results).toHaveLength(2); + + // Verify both output directories were created + expect( + fs.existsSync(path.join(outputDir, 'multi-output-mixed-string')), + ).toBe(true); + expect( + fs.existsSync(path.join(outputDir, 'multi-output-mixed-object')), + ).toBe(true); + }); + + it('preserves global configuration across multiple outputs', async () => { + const results = await createClient({ + experimentalParser: true, + input: path.join(getSpecsPath(), version, 'external.yaml'), + logs: { level: 'silent' }, + output: [ + path.join(outputDir, 'multi-output-global-1'), + path.join(outputDir, 'multi-output-global-2'), + ], + plugins: ['@hey-api/typescript', '@hey-api/sdk'], + }); + + expect(results).toHaveLength(2); + + // Both results should have the same global configuration + results.forEach((result) => { + if ('config' in result) { + expect(result.config.experimentalParser).toBe(true); + expect(result.config.plugins['@hey-api/typescript']).toBeDefined(); + expect(result.config.plugins['@hey-api/sdk']).toBeDefined(); + } + }); + }); + }); }); diff --git a/packages/openapi-ts-tests/main/test/3.0.x.test.ts b/packages/openapi-ts-tests/main/test/3.0.x.test.ts index e54398c80..ec01870ce 100644 --- a/packages/openapi-ts-tests/main/test/3.0.x.test.ts +++ b/packages/openapi-ts-tests/main/test/3.0.x.test.ts @@ -21,7 +21,9 @@ describe(`OpenAPI ${version}`, () => { version, typeof userConfig.input === 'string' ? userConfig.input - : (userConfig.input.path as string), + : userConfig.input instanceof Array + ? (userConfig.input[0] as any).path || userConfig.input[0] + : (userConfig.input as any).path, ); return { plugins: ['@hey-api/typescript'], @@ -38,7 +40,9 @@ describe(`OpenAPI ${version}`, () => { }, output: path.join( outputDir, - typeof userConfig.output === 'string' ? userConfig.output : '', + typeof userConfig.output === 'string' + ? userConfig.output + : userConfig.output.path, ), }; }; @@ -673,4 +677,193 @@ describe(`OpenAPI ${version}`, () => { }), ); }); + + describe('multi config', () => { + it('generates outputs for all configs', async () => { + const configA = createConfig({ + input: 'external.yaml', + output: 'multi-external', + }); + const configB = createConfig({ + input: 'enum-inline.json', + output: 'multi-enum-inline', + parser: { transforms: { enums: 'root' } }, + }); + + await createClient([configA, configB]); + + const outputPathA = + typeof configA.output === 'string' + ? configA.output + : configA.output.path; + const outputPathB = + typeof configB.output === 'string' + ? configB.output + : configB.output.path; + + const filesA = getFilePaths(outputPathA); + const filesB = getFilePaths(outputPathB); + + await Promise.all( + filesA.map(async (filePath) => { + const fileContent = fs.readFileSync(filePath, 'utf-8'); + await expect(fileContent).toMatchFileSnapshot( + path.join( + __dirname, + '__snapshots__', + version, + filePath.slice(outputDir.length + 1), + ), + ); + }), + ); + + await Promise.all( + filesB.map(async (filePath) => { + const fileContent = fs.readFileSync(filePath, 'utf-8'); + await expect(fileContent).toMatchFileSnapshot( + path.join( + __dirname, + '__snapshots__', + version, + filePath.slice(outputDir.length + 1), + ), + ); + }), + ); + }); + }); + + describe('multi input', () => { + it('parses multiple inputs (object + string) without errors', async () => { + const specsBase = path.join(getSpecsPath(), version); + await expect( + createClient({ + dryRun: true, + input: [ + { path: path.join(specsBase, 'multi-a.yaml') }, + path.join(specsBase, 'multi-b.yaml'), + ], + logs: { level: 'silent' }, + output: path.join(outputDir, 'multi-input'), + plugins: ['@hey-api/typescript'], + }), + ).resolves.not.toThrow(); + }); + }); + + describe('multi output', () => { + it('generates multiple string outputs without errors', async () => { + const results = await createClient({ + input: path.join(getSpecsPath(), version, 'external.yaml'), + logs: { level: 'silent' }, + output: [ + path.join(outputDir, 'multi-output-string-1'), + path.join(outputDir, 'multi-output-string-2'), + ], + plugins: ['@hey-api/typescript'], + }); + + expect(results).toHaveLength(2); + + // Verify both output directories were created + expect(fs.existsSync(path.join(outputDir, 'multi-output-string-1'))).toBe( + true, + ); + expect(fs.existsSync(path.join(outputDir, 'multi-output-string-2'))).toBe( + true, + ); + }); + + it('generates multiple output objects with different configurations', async () => { + const results = await createClient({ + input: path.join(getSpecsPath(), version, 'external.yaml'), + logs: { level: 'silent' }, + output: [ + { + clean: true, + indexFile: true, + path: path.join(outputDir, 'multi-output-config-1'), + }, + { + clean: false, + indexFile: false, + path: path.join(outputDir, 'multi-output-config-2'), + }, + ], + plugins: ['@hey-api/typescript'], + }); + + expect(results).toHaveLength(2); + + // Verify both output directories were created + expect(fs.existsSync(path.join(outputDir, 'multi-output-config-1'))).toBe( + true, + ); + expect(fs.existsSync(path.join(outputDir, 'multi-output-config-2'))).toBe( + true, + ); + + // Verify index files are created/not created based on configuration + expect( + fs.existsSync( + path.join(outputDir, 'multi-output-config-1', 'index.ts'), + ), + ).toBe(true); + expect( + fs.existsSync( + path.join(outputDir, 'multi-output-config-2', 'index.ts'), + ), + ).toBe(false); + }); + + it('generates mixed string and object outputs', async () => { + const results = await createClient({ + input: path.join(getSpecsPath(), version, 'external.yaml'), + logs: { level: 'silent' }, + output: [ + path.join(outputDir, 'multi-output-mixed-string'), + { + indexFile: false, + path: path.join(outputDir, 'multi-output-mixed-object'), + }, + ], + plugins: ['@hey-api/typescript'], + }); + + expect(results).toHaveLength(2); + + // Verify both output directories were created + expect( + fs.existsSync(path.join(outputDir, 'multi-output-mixed-string')), + ).toBe(true); + expect( + fs.existsSync(path.join(outputDir, 'multi-output-mixed-object')), + ).toBe(true); + }); + + it('preserves global configuration across multiple outputs', async () => { + const results = await createClient({ + experimentalParser: true, + input: path.join(getSpecsPath(), version, 'external.yaml'), + logs: { level: 'silent' }, + output: [ + path.join(outputDir, 'multi-output-global-1'), + path.join(outputDir, 'multi-output-global-2'), + ], + plugins: ['@hey-api/typescript', '@hey-api/sdk'], + }); + + expect(results).toHaveLength(2); + + // Both results should have the same global configuration + results.forEach((result) => { + if ('config' in result) { + expect(result.config.experimentalParser).toBe(true); + expect(result.config.plugins['@hey-api/typescript']).toBeDefined(); + expect(result.config.plugins['@hey-api/sdk']).toBeDefined(); + } + }); + }); + }); }); diff --git a/packages/openapi-ts-tests/main/test/3.1.x.test.ts b/packages/openapi-ts-tests/main/test/3.1.x.test.ts index 8907d7ffe..b868761ca 100644 --- a/packages/openapi-ts-tests/main/test/3.1.x.test.ts +++ b/packages/openapi-ts-tests/main/test/3.1.x.test.ts @@ -21,7 +21,9 @@ describe(`OpenAPI ${version}`, () => { version, typeof userConfig.input === 'string' ? userConfig.input - : (userConfig.input.path as string), + : userConfig.input instanceof Array + ? (userConfig.input[0] as any).path || userConfig.input[0] + : (userConfig.input as any).path, ); return { plugins: ['@hey-api/typescript'], @@ -38,7 +40,9 @@ describe(`OpenAPI ${version}`, () => { }, output: path.join( outputDir, - typeof userConfig.output === 'string' ? userConfig.output : '', + typeof userConfig.output === 'string' + ? userConfig.output + : userConfig.output.path, ), }; }; @@ -972,4 +976,193 @@ describe(`OpenAPI ${version}`, () => { }), ); }); + + describe('multi config', () => { + it('generates outputs for all configs', async () => { + const configA = createConfig({ + input: 'external.yaml', + output: 'multi-external', + }); + const configB = createConfig({ + input: 'enum-inline.yaml', + output: 'multi-enum-inline', + parser: { transforms: { enums: 'root' } }, + }); + + await createClient([configA, configB]); + + const outputPathA = + typeof configA.output === 'string' + ? configA.output + : configA.output.path; + const outputPathB = + typeof configB.output === 'string' + ? configB.output + : configB.output.path; + + const filesA = getFilePaths(outputPathA); + const filesB = getFilePaths(outputPathB); + + await Promise.all( + filesA.map(async (filePath) => { + const fileContent = fs.readFileSync(filePath, 'utf-8'); + await expect(fileContent).toMatchFileSnapshot( + path.join( + __dirname, + '__snapshots__', + version, + filePath.slice(outputDir.length + 1), + ), + ); + }), + ); + + await Promise.all( + filesB.map(async (filePath) => { + const fileContent = fs.readFileSync(filePath, 'utf-8'); + await expect(fileContent).toMatchFileSnapshot( + path.join( + __dirname, + '__snapshots__', + version, + filePath.slice(outputDir.length + 1), + ), + ); + }), + ); + }); + }); + + describe('multi input', () => { + it('parses multiple inputs (object + string) without errors', async () => { + const specsBase = path.join(getSpecsPath(), version); + await expect( + createClient({ + dryRun: true, + input: [ + { path: path.join(specsBase, 'multi-a.yaml') }, + path.join(specsBase, 'multi-b.yaml'), + ], + logs: { level: 'silent' }, + output: path.join(outputDir, 'multi-input'), + plugins: ['@hey-api/typescript'], + }), + ).resolves.not.toThrow(); + }); + }); + + describe('multi output', () => { + it('generates multiple string outputs without errors', async () => { + const results = await createClient({ + input: path.join(getSpecsPath(), version, 'external.yaml'), + logs: { level: 'silent' }, + output: [ + path.join(outputDir, 'multi-output-string-1'), + path.join(outputDir, 'multi-output-string-2'), + ], + plugins: ['@hey-api/typescript'], + }); + + expect(results).toHaveLength(2); + + // Verify both output directories were created + expect(fs.existsSync(path.join(outputDir, 'multi-output-string-1'))).toBe( + true, + ); + expect(fs.existsSync(path.join(outputDir, 'multi-output-string-2'))).toBe( + true, + ); + }); + + it('generates multiple output objects with different configurations', async () => { + const results = await createClient({ + input: path.join(getSpecsPath(), version, 'external.yaml'), + logs: { level: 'silent' }, + output: [ + { + clean: true, + indexFile: true, + path: path.join(outputDir, 'multi-output-config-1'), + }, + { + clean: false, + indexFile: false, + path: path.join(outputDir, 'multi-output-config-2'), + }, + ], + plugins: ['@hey-api/typescript'], + }); + + expect(results).toHaveLength(2); + + // Verify both output directories were created + expect(fs.existsSync(path.join(outputDir, 'multi-output-config-1'))).toBe( + true, + ); + expect(fs.existsSync(path.join(outputDir, 'multi-output-config-2'))).toBe( + true, + ); + + // Verify index files are created/not created based on configuration + expect( + fs.existsSync( + path.join(outputDir, 'multi-output-config-1', 'index.ts'), + ), + ).toBe(true); + expect( + fs.existsSync( + path.join(outputDir, 'multi-output-config-2', 'index.ts'), + ), + ).toBe(false); + }); + + it('generates mixed string and object outputs', async () => { + const results = await createClient({ + input: path.join(getSpecsPath(), version, 'external.yaml'), + logs: { level: 'silent' }, + output: [ + path.join(outputDir, 'multi-output-mixed-string'), + { + indexFile: false, + path: path.join(outputDir, 'multi-output-mixed-object'), + }, + ], + plugins: ['@hey-api/typescript'], + }); + + expect(results).toHaveLength(2); + + // Verify both output directories were created + expect( + fs.existsSync(path.join(outputDir, 'multi-output-mixed-string')), + ).toBe(true); + expect( + fs.existsSync(path.join(outputDir, 'multi-output-mixed-object')), + ).toBe(true); + }); + + it('preserves global configuration across multiple outputs', async () => { + const results = await createClient({ + experimentalParser: true, + input: path.join(getSpecsPath(), version, 'external.yaml'), + logs: { level: 'silent' }, + output: [ + path.join(outputDir, 'multi-output-global-1'), + path.join(outputDir, 'multi-output-global-2'), + ], + plugins: ['@hey-api/typescript', '@hey-api/sdk'], + }); + + expect(results).toHaveLength(2); + + // Both results should have the same global configuration + results.forEach((result) => { + if ('config' in result) { + expect(result.config.experimentalParser).toBe(true); + expect(result.config.plugins['@hey-api/typescript']).toBeDefined(); + expect(result.config.plugins['@hey-api/sdk']).toBeDefined(); + } + }); + }); + }); }); diff --git a/packages/openapi-ts-tests/main/test/__snapshots__/2.0.x/multi-enum-names-values/index.ts b/packages/openapi-ts-tests/main/test/__snapshots__/2.0.x/multi-enum-names-values/index.ts new file mode 100644 index 000000000..0339b6e31 --- /dev/null +++ b/packages/openapi-ts-tests/main/test/__snapshots__/2.0.x/multi-enum-names-values/index.ts @@ -0,0 +1,3 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export * from './types.gen'; diff --git a/packages/openapi-ts-tests/main/test/__snapshots__/2.0.x/multi-enum-names-values/types.gen.ts b/packages/openapi-ts-tests/main/test/__snapshots__/2.0.x/multi-enum-names-values/types.gen.ts new file mode 100644 index 000000000..9452f2b9e --- /dev/null +++ b/packages/openapi-ts-tests/main/test/__snapshots__/2.0.x/multi-enum-names-values/types.gen.ts @@ -0,0 +1,23 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type _110 = '1-10' | '11-20'; + +export type MyFoo = 'myFoo' | 'myBar'; + +export type MyFoo2 = 'MyFoo' | 'MyBar'; + +export type Foo = 'foo' | 'bar' | '' | true | false; + +export type Numbers = 100 | 200 | 300 | -100 | -200 | -300; + +export type Arrays = [ + 'foo' +] | [ + 'bar' +] | [ + 'baz' +]; + +export type ClientOptions = { + baseUrl: string; +}; diff --git a/packages/openapi-ts-tests/main/test/__snapshots__/2.0.x/multi-external/index.ts b/packages/openapi-ts-tests/main/test/__snapshots__/2.0.x/multi-external/index.ts new file mode 100644 index 000000000..0339b6e31 --- /dev/null +++ b/packages/openapi-ts-tests/main/test/__snapshots__/2.0.x/multi-external/index.ts @@ -0,0 +1,3 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export * from './types.gen'; diff --git a/packages/openapi-ts-tests/main/test/__snapshots__/2.0.x/multi-external/types.gen.ts b/packages/openapi-ts-tests/main/test/__snapshots__/2.0.x/multi-external/types.gen.ts new file mode 100644 index 000000000..3d1e1fbe6 --- /dev/null +++ b/packages/openapi-ts-tests/main/test/__snapshots__/2.0.x/multi-external/types.gen.ts @@ -0,0 +1,394 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ExternalSchemaA = ExternalSharedExternalSharedModel; + +export type ExternalSchemaB = ExternalSharedExternalSharedModel; + +export type ExternalSchemaC = ExternalSharedExternalSharedModel; + +export type ExternalSchemaPathA = ExternalSharedExternalSharedModel; + +export type ExternalSchemaPathB = ExternalSharedExternalSharedModel; + +/** + * External schema property (A) + */ +export type ExternalSchemaPropertyA = { + uuid1?: ExternalSharedExternalSharedModelWithUuid; +}; + +/** + * External schema property (B) - second use of UUID + */ +export type ExternalSchemaPropertyB = { + uuid2?: ExternalSharedExternalSharedModelWithUuid; +}; + +/** + * External schema property (C) - third use of UUID + */ +export type ExternalSchemaPropertyC = { + uuid3?: ExternalSharedExternalSharedModelWithUuid; +}; + +/** + * External schema property with duplicate refs (D) + */ +export type ExternalSchemaPropertyD = { + uuid4?: ExternalSharedExternalSharedModelWithUuid; + uuid5?: ExternalSharedExternalSharedModelWithUuid; +}; + +/** + * External schema property via external property ref (id) + */ +export type ExternalSchemaExternalProp = { + id3?: ExternalSharedId; + id4?: ExternalSharedId; +}; + +/** + * Alias to external property via component property ref + */ +export type ExternalSchemaExternalPropAlias = { + id5?: ExternalSharedId; + id6?: ExternalSharedId; +}; + +/** + * External double nested prop via property ref + */ +export type ExternalDoubleNestedProp = { + deep1?: ExternalSharedDeep; + deep2?: ExternalSharedDeep; +}; + +/** + * External double nested numeric properties + */ +export type ExternalDoubleNestedNumeric = { + numeric1?: ExternalShared1; + numeric2?: ExternalShared1; +}; + +export type ExternalNestedObjectA = ExternalSharedExternalNested; + +export type ExternalNestedObjectB = ExternalSharedExternalNested; + +export type ExternalNestedNumericObjectA = ExternalSharedExternalNestedNumeric; + +export type ExternalNestedNumericObjectB = ExternalSharedExternalNestedNumeric; + +/** + * Mixed external property references + */ +export type ExternalMixedProperties = { + id7?: ExternalSharedId; + name1?: ExternalSharedName; + uuid6?: ExternalSharedExternalSharedModelWithUuid; + deep3?: ExternalSharedDeep; + numeric3?: ExternalShared1; +}; + +/** + * Array containing external references + */ +export type ExternalArraySchema = { + items?: Array; + uuidItems?: Array; +}; + +/** + * Union type with external references + */ +export type ExternalUnionSchema = unknown; + +/** + * AllOf with external references + */ +export type ExternalAllOfSchema = ExternalSharedExternalSharedModel & { + additional?: ExternalSharedExternalSharedModelWithUuid; +}; + +/** + * AnyOf with external references + */ +export type ExternalAnyOfSchema = unknown; + +export type ExternalSharedExternalNested = { + inner?: { + deep?: string; + }; +}; + +export type ExternalSharedDeep = string; + +export type ExternalSharedExternalNestedNumeric = { + 0?: { + 1?: string; + }; +}; + +export type ExternalShared1 = string; + +export type ExternalSharedExternalSharedModel = { + id: string; + name?: string; +}; + +export type ExternalSharedId = string; + +export type ExternalSharedName = string; + +export type ExternalSharedExternalSharedModelWithUuid = string; + +export type GetExternalModelData = { + body?: never; + path: { + id: unknown; + }; + query?: { + uuid?: unknown; + }; + url: '/external-model'; +}; + +export type GetExternalModelErrors = { + /** + * Response using external UUID + */ + 400: ExternalSharedExternalSharedModelWithUuid; +}; + +export type GetExternalModelError = GetExternalModelErrors[keyof GetExternalModelErrors]; + +export type GetExternalModelResponses = { + /** + * Response using external model + */ + 200: ExternalSharedExternalSharedModel; +}; + +export type GetExternalModelResponse = GetExternalModelResponses[keyof GetExternalModelResponses]; + +export type PostExternalModelData = { + body?: never; + path?: never; + query?: never; + url: '/external-model'; +}; + +export type PostExternalModelErrors = { + /** + * Response with union of external types + */ + 422: unknown; +}; + +export type PostExternalModelResponses = { + /** + * Response using external model + */ + 201: ExternalSharedExternalSharedModel; +}; + +export type PostExternalModelResponse = PostExternalModelResponses[keyof PostExternalModelResponses]; + +export type GetExternalUuidData = { + body?: never; + path?: never; + query?: { + uuid?: unknown; + }; + url: '/external-uuid'; +}; + +export type GetExternalUuidResponses = { + /** + * Response using external UUID + */ + 200: ExternalSharedExternalSharedModelWithUuid; +}; + +export type GetExternalUuidResponse = GetExternalUuidResponses[keyof GetExternalUuidResponses]; + +export type PutExternalUuidData = { + body?: never; + path?: never; + query?: never; + url: '/external-uuid'; +}; + +export type PutExternalUuidResponses = { + /** + * Response using external UUID + */ + 200: ExternalSharedExternalSharedModelWithUuid; +}; + +export type PutExternalUuidResponse = PutExternalUuidResponses[keyof PutExternalUuidResponses]; + +export type GetExternalNestedData = { + body?: never; + headers?: { + deep?: unknown; + }; + path?: never; + query?: never; + url: '/external-nested'; +}; + +export type GetExternalNestedResponses = { + /** + * Response using external nested object + */ + 200: ExternalSharedExternalNested; +}; + +export type GetExternalNestedResponse = GetExternalNestedResponses[keyof GetExternalNestedResponses]; + +export type PostExternalNestedData = { + body?: never; + path?: never; + query?: never; + url: '/external-nested'; +}; + +export type PostExternalNestedResponses = { + /** + * Response using external nested object + */ + 201: ExternalSharedExternalNested; +}; + +export type PostExternalNestedResponse = PostExternalNestedResponses[keyof PostExternalNestedResponses]; + +export type GetExternalMixedData = { + body?: never; + headers?: { + deep?: unknown; + }; + path: { + id: unknown; + }; + query?: { + uuid?: unknown; + numeric?: unknown; + }; + url: '/external-mixed'; +}; + +export type GetExternalMixedResponses = { + /** + * Response with array of external models + */ + 200: Array; +}; + +export type GetExternalMixedResponse = GetExternalMixedResponses[keyof GetExternalMixedResponses]; + +export type PostExternalMixedData = { + body?: never; + path?: never; + query?: never; + url: '/external-mixed'; +}; + +export type PostExternalMixedResponses = { + /** + * Response using external model + */ + 201: ExternalSharedExternalSharedModel; +}; + +export type PostExternalMixedResponse = PostExternalMixedResponses[keyof PostExternalMixedResponses]; + +export type GetExternalArrayData = { + body?: never; + path?: never; + query?: never; + url: '/external-array'; +}; + +export type GetExternalArrayResponses = { + /** + * Response with array of external models + */ + 200: Array; +}; + +export type GetExternalArrayResponse = GetExternalArrayResponses[keyof GetExternalArrayResponses]; + +export type PostExternalArrayData = { + body?: never; + path?: never; + query?: never; + url: '/external-array'; +}; + +export type PostExternalArrayResponses = { + /** + * Response with array of external models + */ + 201: Array; +}; + +export type PostExternalArrayResponse = PostExternalArrayResponses[keyof PostExternalArrayResponses]; + +export type GetExternalUnionData = { + body?: never; + path?: never; + query?: never; + url: '/external-union'; +}; + +export type GetExternalUnionResponses = { + /** + * Response with union of external types + */ + 200: unknown; +}; + +export type PostExternalUnionData = { + body?: never; + path?: never; + query?: never; + url: '/external-union'; +}; + +export type PostExternalUnionResponses = { + /** + * Response with union of external types + */ + 201: unknown; +}; + +export type GetExternalPropertiesByIdData = { + body?: never; + headers?: { + deep?: unknown; + }; + path: { + id: unknown; + }; + query?: { + uuid?: unknown; + }; + url: '/external-properties/{id}'; +}; + +export type GetExternalPropertiesByIdResponses = { + 200: { + id?: ExternalSharedId; + name?: ExternalSharedName; + uuid?: ExternalSharedExternalSharedModelWithUuid; + deep?: ExternalSharedDeep; + numeric?: ExternalShared1; + }; +}; + +export type GetExternalPropertiesByIdResponse = GetExternalPropertiesByIdResponses[keyof GetExternalPropertiesByIdResponses]; + +export type ClientOptions = { + baseUrl: string; +}; diff --git a/packages/openapi-ts-tests/main/test/__snapshots__/3.0.x/multi-enum-inline/index.ts b/packages/openapi-ts-tests/main/test/__snapshots__/3.0.x/multi-enum-inline/index.ts new file mode 100644 index 000000000..0339b6e31 --- /dev/null +++ b/packages/openapi-ts-tests/main/test/__snapshots__/3.0.x/multi-enum-inline/index.ts @@ -0,0 +1,3 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export * from './types.gen'; diff --git a/packages/openapi-ts-tests/main/test/__snapshots__/3.0.x/multi-enum-inline/types.gen.ts b/packages/openapi-ts-tests/main/test/__snapshots__/3.0.x/multi-enum-inline/types.gen.ts new file mode 100644 index 000000000..c1d043ba0 --- /dev/null +++ b/packages/openapi-ts-tests/main/test/__snapshots__/3.0.x/multi-enum-inline/types.gen.ts @@ -0,0 +1,11 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type Foo = { + type?: TypeEnum; +}; + +export type TypeEnum = 'foo' | 'bar'; + +export type ClientOptions = { + baseUrl: `${string}://${string}` | (string & {}); +}; diff --git a/packages/openapi-ts-tests/main/test/__snapshots__/3.0.x/multi-external/index.ts b/packages/openapi-ts-tests/main/test/__snapshots__/3.0.x/multi-external/index.ts new file mode 100644 index 000000000..0339b6e31 --- /dev/null +++ b/packages/openapi-ts-tests/main/test/__snapshots__/3.0.x/multi-external/index.ts @@ -0,0 +1,3 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export * from './types.gen'; diff --git a/packages/openapi-ts-tests/main/test/__snapshots__/3.0.x/multi-external/types.gen.ts b/packages/openapi-ts-tests/main/test/__snapshots__/3.0.x/multi-external/types.gen.ts new file mode 100644 index 000000000..2ab40752d --- /dev/null +++ b/packages/openapi-ts-tests/main/test/__snapshots__/3.0.x/multi-external/types.gen.ts @@ -0,0 +1,436 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type ExternalSchemaA = ExternalSharedExternalSharedModel; + +export type ExternalSchemaB = ExternalSharedExternalSharedModel; + +export type ExternalSchemaC = ExternalSharedExternalSharedModel; + +export type ExternalSchemaPathA = ExternalSharedExternalSharedModel; + +export type ExternalSchemaPathB = ExternalSharedExternalSharedModel; + +/** + * External schema property (A) + */ +export type ExternalSchemaPropertyA = { + uuid1?: ExternalSharedExternalSharedModelWithUuid; +}; + +/** + * External schema property (B) - second use of UUID + */ +export type ExternalSchemaPropertyB = { + uuid2?: ExternalSharedExternalSharedModelWithUuid; +}; + +/** + * External schema property (C) - third use of UUID + */ +export type ExternalSchemaPropertyC = { + uuid3?: ExternalSharedExternalSharedModelWithUuid; +}; + +/** + * External schema property with duplicate refs (D) + */ +export type ExternalSchemaPropertyD = { + uuid4?: ExternalSharedExternalSharedModelWithUuid; + uuid5?: ExternalSharedExternalSharedModelWithUuid; +}; + +/** + * External schema property via external property ref (id) + */ +export type ExternalSchemaExternalProp = { + id3?: ExternalSharedId; + id4?: ExternalSharedId; +}; + +/** + * Alias to external property via component property ref + */ +export type ExternalSchemaExternalPropAlias = { + id5?: ExternalSharedId; + id6?: ExternalSharedId; +}; + +/** + * External double nested prop via property ref + */ +export type ExternalDoubleNestedProp = { + deep1?: ExternalSharedDeep; + deep2?: ExternalSharedDeep; +}; + +/** + * External double nested numeric properties + */ +export type ExternalDoubleNestedNumeric = { + numeric1?: ExternalShared1; + numeric2?: ExternalShared1; +}; + +export type ExternalNestedObjectA = ExternalSharedExternalNested; + +export type ExternalNestedObjectB = ExternalSharedExternalNested; + +export type ExternalNestedNumericObjectA = ExternalSharedExternalNestedNumeric; + +export type ExternalNestedNumericObjectB = ExternalSharedExternalNestedNumeric; + +/** + * Mixed external property references + */ +export type ExternalMixedProperties = { + id7?: ExternalSharedId; + name1?: ExternalSharedName; + uuid6?: ExternalSharedExternalSharedModelWithUuid; + deep3?: ExternalSharedDeep; + numeric3?: ExternalShared1; +}; + +/** + * Array containing external references + */ +export type ExternalArraySchema = { + items?: Array; + uuidItems?: Array; +}; + +/** + * Union type with external references + */ +export type ExternalUnionSchema = ExternalSharedExternalSharedModel | ExternalSharedExternalSharedModelWithUuid; + +/** + * AllOf with external references + */ +export type ExternalAllOfSchema = ExternalSharedExternalSharedModel & { + additional?: ExternalSharedExternalSharedModelWithUuid; +}; + +/** + * AnyOf with external references + */ +export type ExternalAnyOfSchema = ExternalSharedExternalNested | ExternalSharedExternalNestedNumeric; + +export type ExternalSharedExternalNested = { + inner?: { + deep?: string; + }; +}; + +export type ExternalSharedDeep = string; + +export type ExternalSharedExternalNestedNumeric = { + 0?: { + 1?: string; + }; +}; + +export type ExternalShared1 = string; + +export type ExternalSharedExternalSharedModel = { + id: string; + name?: string; +}; + +export type ExternalSharedId = string; + +export type ExternalSharedName = string; + +export type ExternalSharedExternalSharedModelWithUuid = string; + +export type ExternalIdParam = ExternalSharedId; + +export type ExternalUuidParam = ExternalSharedExternalSharedModelWithUuid; + +export type ExternalDeepParam = ExternalSharedDeep; + +export type ExternalNumericParam = ExternalShared1; + +export type ExternalModelBody = ExternalSharedExternalSharedModel; + +export type ExternalUuidBody = ExternalSharedExternalSharedModelWithUuid; + +export type ExternalNestedBody = ExternalSharedExternalNested; + +/** + * Request body with mixed external properties + */ +export type ExternalMixedBody = { + id?: ExternalSharedId; + name?: ExternalSharedName; + uuid?: ExternalSharedExternalSharedModelWithUuid; + deep?: ExternalSharedDeep; +}; + +export type GetExternalModelData = { + body?: never; + path: { + id: ExternalSharedId; + }; + query?: { + uuid?: ExternalSharedExternalSharedModelWithUuid; + }; + url: '/external-model'; +}; + +export type GetExternalModelErrors = { + /** + * Response using external UUID + */ + 400: ExternalSharedExternalSharedModelWithUuid; +}; + +export type GetExternalModelError = GetExternalModelErrors[keyof GetExternalModelErrors]; + +export type GetExternalModelResponses = { + /** + * Response using external model + */ + 200: ExternalSharedExternalSharedModel; +}; + +export type GetExternalModelResponse = GetExternalModelResponses[keyof GetExternalModelResponses]; + +export type PostExternalModelData = { + /** + * Request body using external model + */ + body: ExternalModelBody; + path?: never; + query?: never; + url: '/external-model'; +}; + +export type PostExternalModelErrors = { + /** + * Response with union of external types + */ + 422: ExternalSharedExternalSharedModel | ExternalSharedExternalSharedModelWithUuid | ExternalSharedExternalNested; +}; + +export type PostExternalModelError = PostExternalModelErrors[keyof PostExternalModelErrors]; + +export type PostExternalModelResponses = { + /** + * Response using external model + */ + 201: ExternalSharedExternalSharedModel; +}; + +export type PostExternalModelResponse = PostExternalModelResponses[keyof PostExternalModelResponses]; + +export type GetExternalUuidData = { + body?: never; + path?: never; + query?: { + uuid?: ExternalSharedExternalSharedModelWithUuid; + }; + url: '/external-uuid'; +}; + +export type GetExternalUuidResponses = { + /** + * Response using external UUID + */ + 200: ExternalSharedExternalSharedModelWithUuid; +}; + +export type GetExternalUuidResponse = GetExternalUuidResponses[keyof GetExternalUuidResponses]; + +export type PutExternalUuidData = { + /** + * Request body using external UUID + */ + body?: ExternalUuidBody; + path?: never; + query?: never; + url: '/external-uuid'; +}; + +export type PutExternalUuidResponses = { + /** + * Response using external UUID + */ + 200: ExternalSharedExternalSharedModelWithUuid; +}; + +export type PutExternalUuidResponse = PutExternalUuidResponses[keyof PutExternalUuidResponses]; + +export type GetExternalNestedData = { + body?: never; + headers?: { + deep?: ExternalSharedDeep; + }; + path?: never; + query?: never; + url: '/external-nested'; +}; + +export type GetExternalNestedResponses = { + /** + * Response using external nested object + */ + 200: ExternalSharedExternalNested; +}; + +export type GetExternalNestedResponse = GetExternalNestedResponses[keyof GetExternalNestedResponses]; + +export type PostExternalNestedData = { + /** + * Request body using external nested object + */ + body?: ExternalNestedBody; + path?: never; + query?: never; + url: '/external-nested'; +}; + +export type PostExternalNestedResponses = { + /** + * Response using external nested object + */ + 201: ExternalSharedExternalNested; +}; + +export type PostExternalNestedResponse = PostExternalNestedResponses[keyof PostExternalNestedResponses]; + +export type GetExternalMixedData = { + body?: never; + headers?: { + deep?: ExternalSharedDeep; + }; + path: { + id: ExternalSharedId; + }; + query?: { + uuid?: ExternalSharedExternalSharedModelWithUuid; + numeric?: ExternalShared1; + }; + url: '/external-mixed'; +}; + +export type GetExternalMixedResponses = { + /** + * Response with array of external models + */ + 200: Array; +}; + +export type GetExternalMixedResponse = GetExternalMixedResponses[keyof GetExternalMixedResponses]; + +export type PostExternalMixedData = { + /** + * Request body with mixed external properties + */ + body?: ExternalMixedBody; + path?: never; + query?: never; + url: '/external-mixed'; +}; + +export type PostExternalMixedResponses = { + /** + * Response using external model + */ + 201: ExternalSharedExternalSharedModel; +}; + +export type PostExternalMixedResponse = PostExternalMixedResponses[keyof PostExternalMixedResponses]; + +export type GetExternalArrayData = { + body?: never; + path?: never; + query?: never; + url: '/external-array'; +}; + +export type GetExternalArrayResponses = { + /** + * Response with array of external models + */ + 200: Array; +}; + +export type GetExternalArrayResponse = GetExternalArrayResponses[keyof GetExternalArrayResponses]; + +export type PostExternalArrayData = { + body: Array; + path?: never; + query?: never; + url: '/external-array'; +}; + +export type PostExternalArrayResponses = { + /** + * Response with array of external models + */ + 201: Array; +}; + +export type PostExternalArrayResponse = PostExternalArrayResponses[keyof PostExternalArrayResponses]; + +export type GetExternalUnionData = { + body?: never; + path?: never; + query?: never; + url: '/external-union'; +}; + +export type GetExternalUnionResponses = { + /** + * Response with union of external types + */ + 200: ExternalSharedExternalSharedModel | ExternalSharedExternalSharedModelWithUuid | ExternalSharedExternalNested; +}; + +export type GetExternalUnionResponse = GetExternalUnionResponses[keyof GetExternalUnionResponses]; + +export type PostExternalUnionData = { + body: ExternalSharedExternalSharedModel | ExternalSharedExternalSharedModelWithUuid | ExternalSharedExternalNested; + path?: never; + query?: never; + url: '/external-union'; +}; + +export type PostExternalUnionResponses = { + /** + * Response with union of external types + */ + 201: ExternalSharedExternalSharedModel | ExternalSharedExternalSharedModelWithUuid | ExternalSharedExternalNested; +}; + +export type PostExternalUnionResponse = PostExternalUnionResponses[keyof PostExternalUnionResponses]; + +export type GetExternalPropertiesByIdData = { + body?: never; + headers?: { + deep?: ExternalSharedDeep; + }; + path: { + id: ExternalSharedId; + }; + query?: { + uuid?: ExternalSharedExternalSharedModelWithUuid; + }; + url: '/external-properties/{id}'; +}; + +export type GetExternalPropertiesByIdResponses = { + 200: { + id?: ExternalSharedId; + name?: ExternalSharedName; + uuid?: ExternalSharedExternalSharedModelWithUuid; + deep?: ExternalSharedDeep; + numeric?: ExternalShared1; + }; +}; + +export type GetExternalPropertiesByIdResponse = GetExternalPropertiesByIdResponses[keyof GetExternalPropertiesByIdResponses]; + +export type ClientOptions = { + baseUrl: `${string}://${string}` | (string & {}); +}; diff --git a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/multi-enum-inline/index.ts b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/multi-enum-inline/index.ts new file mode 100644 index 000000000..0339b6e31 --- /dev/null +++ b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/multi-enum-inline/index.ts @@ -0,0 +1,3 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export * from './types.gen'; diff --git a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/multi-enum-inline/types.gen.ts b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/multi-enum-inline/types.gen.ts new file mode 100644 index 000000000..9163b485e --- /dev/null +++ b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/multi-enum-inline/types.gen.ts @@ -0,0 +1,71 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export type Foo = { + type?: FooEnum; +}; + +export type Bar = { + type?: Baz; +}; + +export type Baz = 'qux' | 'quux'; + +export type FooEnum = 'foo' | 'bar'; + +export type FooEnum2 = 'baz'; + +export type GetFooData = { + body?: never; + path?: never; + query?: never; + url: '/foo'; +}; + +export type GetFooResponses = { + /** + * OK + */ + 200: { + foo?: FooEnum; + }; +}; + +export type GetFooResponse = GetFooResponses[keyof GetFooResponses]; + +export type PostFooData = { + body?: never; + path?: never; + query?: never; + url: '/foo'; +}; + +export type PostFooResponses = { + /** + * OK + */ + 200: { + foo?: FooEnum2; + }; +}; + +export type PostFooResponse = PostFooResponses[keyof PostFooResponses]; + +export type PutFooData = { + body?: never; + path?: never; + query?: never; + url: '/foo'; +}; + +export type PutFooResponses = { + /** + * OK + */ + 200: Baz; +}; + +export type PutFooResponse = PutFooResponses[keyof PutFooResponses]; + +export type ClientOptions = { + baseUrl: `${string}://${string}` | (string & {}); +}; diff --git a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/multi-external/index.ts b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/multi-external/index.ts new file mode 100644 index 000000000..0339b6e31 --- /dev/null +++ b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/multi-external/index.ts @@ -0,0 +1,3 @@ +// This file is auto-generated by @hey-api/openapi-ts + +export * from './types.gen'; diff --git a/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/multi-external/types.gen.ts b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/multi-external/types.gen.ts new file mode 100644 index 000000000..fb7cc6bd2 --- /dev/null +++ b/packages/openapi-ts-tests/main/test/__snapshots__/3.1.x/multi-external/types.gen.ts @@ -0,0 +1,472 @@ +// This file is auto-generated by @hey-api/openapi-ts + +/** + * External schema (A) + */ +export type ExternalSchemaA = ExternalSharedExternalSharedModel; + +/** + * External schema (B) - second use of ExternalSharedModel + */ +export type ExternalSchemaB = ExternalSharedExternalSharedModel; + +/** + * External schema (C) - third use of ExternalSharedModel + */ +export type ExternalSchemaC = ExternalSharedExternalSharedModel; + +/** + * External schema via path reference (A) + */ +export type ExternalSchemaPathA = ExternalSharedExternalSharedModel; + +/** + * External schema via path reference (B) - second use + */ +export type ExternalSchemaPathB = ExternalSharedExternalSharedModel; + +/** + * External schema property (A) + */ +export type ExternalSchemaPropertyA = { + uuid1?: ExternalSharedExternalSharedModelWithUuid; +}; + +/** + * External schema property (B) - second use of UUID + */ +export type ExternalSchemaPropertyB = { + uuid2?: ExternalSharedExternalSharedModelWithUuid; +}; + +/** + * External schema property (C) - third use of UUID + */ +export type ExternalSchemaPropertyC = { + uuid3?: ExternalSharedExternalSharedModelWithUuid; +}; + +/** + * External schema property with duplicate refs (D) + */ +export type ExternalSchemaPropertyD = { + uuid4?: ExternalSharedExternalSharedModelWithUuid; + uuid5?: ExternalSharedExternalSharedModelWithUuid; +}; + +/** + * External schema property via external property ref (id) + */ +export type ExternalSchemaExternalProp = { + id3?: ExternalSharedId; + id4?: ExternalSharedId; +}; + +/** + * Alias to external property via component property ref + */ +export type ExternalSchemaExternalPropAlias = { + id5?: ExternalSharedId; + id6?: ExternalSharedId; +}; + +/** + * External double nested prop via property ref + */ +export type ExternalDoubleNestedProp = { + deep1?: ExternalSharedDeep; + deep2?: ExternalSharedDeep; +}; + +/** + * External double nested numeric properties + */ +export type ExternalDoubleNestedNumeric = { + numeric1?: ExternalShared1; + numeric2?: ExternalShared1; +}; + +/** + * External nested object reference (A) + */ +export type ExternalNestedObjectA = ExternalSharedExternalNested; + +/** + * External nested object reference (B) - second use + */ +export type ExternalNestedObjectB = ExternalSharedExternalNested; + +/** + * External numeric nested object reference (A) + */ +export type ExternalNestedNumericObjectA = ExternalSharedExternalNestedNumeric; + +/** + * External numeric nested object reference (B) - second use + */ +export type ExternalNestedNumericObjectB = ExternalSharedExternalNestedNumeric; + +/** + * Mixed external property references + */ +export type ExternalMixedProperties = { + id7?: ExternalSharedId; + name1?: ExternalSharedName; + uuid6?: ExternalSharedExternalSharedModelWithUuid; + deep3?: ExternalSharedDeep; + numeric3?: ExternalShared1; +}; + +/** + * Array containing external references + */ +export type ExternalArraySchema = { + items?: Array; + uuidItems?: Array; +}; + +/** + * Union type with external references + */ +export type ExternalUnionSchema = ExternalSharedExternalSharedModel | ExternalSharedExternalSharedModelWithUuid; + +/** + * AllOf with external references + */ +export type ExternalAllOfSchema = ExternalSharedExternalSharedModel & { + additional?: ExternalSharedExternalSharedModelWithUuid; +}; + +/** + * AnyOf with external references + */ +export type ExternalAnyOfSchema = ExternalSharedExternalNested | ExternalSharedExternalNestedNumeric; + +export type ExternalSharedExternalNested = { + inner?: { + deep?: string; + }; +}; + +export type ExternalSharedDeep = string; + +export type ExternalSharedExternalNestedNumeric = { + 0?: { + 1?: string; + }; +}; + +export type ExternalShared1 = string; + +export type ExternalSharedExternalSharedModel = { + id: string; + name?: string; +}; + +export type ExternalSharedId = string; + +export type ExternalSharedName = string; + +export type ExternalSharedExternalSharedModelWithUuid = string; + +export type ExternalIdParam = ExternalSharedId; + +export type ExternalUuidParam = ExternalSharedExternalSharedModelWithUuid; + +export type ExternalDeepParam = ExternalSharedDeep; + +export type ExternalNumericParam = ExternalShared1; + +/** + * Request body using external model + */ +export type ExternalModelBody = ExternalSharedExternalSharedModel; + +/** + * Request body using external UUID + */ +export type ExternalUuidBody = ExternalSharedExternalSharedModelWithUuid; + +/** + * Request body using external nested object + */ +export type ExternalNestedBody = ExternalSharedExternalNested; + +/** + * Request body with mixed external properties + */ +export type ExternalMixedBody = { + id?: ExternalSharedId; + name?: ExternalSharedName; + uuid?: ExternalSharedExternalSharedModelWithUuid; + deep?: ExternalSharedDeep; +}; + +export type GetExternalModelData = { + body?: never; + path: { + id: ExternalSharedId; + }; + query?: { + uuid?: ExternalSharedExternalSharedModelWithUuid; + }; + url: '/external-model'; +}; + +export type GetExternalModelErrors = { + /** + * Response using external UUID + */ + 400: ExternalSharedExternalSharedModelWithUuid; +}; + +export type GetExternalModelError = GetExternalModelErrors[keyof GetExternalModelErrors]; + +export type GetExternalModelResponses = { + /** + * Response using external model + */ + 200: ExternalSharedExternalSharedModel; +}; + +export type GetExternalModelResponse = GetExternalModelResponses[keyof GetExternalModelResponses]; + +export type PostExternalModelData = { + /** + * Request body using external model + */ + body: ExternalModelBody; + path?: never; + query?: never; + url: '/external-model'; +}; + +export type PostExternalModelErrors = { + /** + * Response with union of external types + */ + 422: ExternalSharedExternalSharedModel | ExternalSharedExternalSharedModelWithUuid | ExternalSharedExternalNested; +}; + +export type PostExternalModelError = PostExternalModelErrors[keyof PostExternalModelErrors]; + +export type PostExternalModelResponses = { + /** + * Response using external model + */ + 201: ExternalSharedExternalSharedModel; +}; + +export type PostExternalModelResponse = PostExternalModelResponses[keyof PostExternalModelResponses]; + +export type GetExternalUuidData = { + body?: never; + path?: never; + query?: { + uuid?: ExternalSharedExternalSharedModelWithUuid; + }; + url: '/external-uuid'; +}; + +export type GetExternalUuidResponses = { + /** + * Response using external UUID + */ + 200: ExternalSharedExternalSharedModelWithUuid; +}; + +export type GetExternalUuidResponse = GetExternalUuidResponses[keyof GetExternalUuidResponses]; + +export type PutExternalUuidData = { + /** + * Request body using external UUID + */ + body?: ExternalUuidBody; + path?: never; + query?: never; + url: '/external-uuid'; +}; + +export type PutExternalUuidResponses = { + /** + * Response using external UUID + */ + 200: ExternalSharedExternalSharedModelWithUuid; +}; + +export type PutExternalUuidResponse = PutExternalUuidResponses[keyof PutExternalUuidResponses]; + +export type GetExternalNestedData = { + body?: never; + headers?: { + deep?: ExternalSharedDeep; + }; + path?: never; + query?: never; + url: '/external-nested'; +}; + +export type GetExternalNestedResponses = { + /** + * Response using external nested object + */ + 200: ExternalSharedExternalNested; +}; + +export type GetExternalNestedResponse = GetExternalNestedResponses[keyof GetExternalNestedResponses]; + +export type PostExternalNestedData = { + /** + * Request body using external nested object + */ + body?: ExternalNestedBody; + path?: never; + query?: never; + url: '/external-nested'; +}; + +export type PostExternalNestedResponses = { + /** + * Response using external nested object + */ + 201: ExternalSharedExternalNested; +}; + +export type PostExternalNestedResponse = PostExternalNestedResponses[keyof PostExternalNestedResponses]; + +export type GetExternalMixedData = { + body?: never; + headers?: { + deep?: ExternalSharedDeep; + }; + path: { + id: ExternalSharedId; + }; + query?: { + uuid?: ExternalSharedExternalSharedModelWithUuid; + numeric?: ExternalShared1; + }; + url: '/external-mixed'; +}; + +export type GetExternalMixedResponses = { + /** + * Response with array of external models + */ + 200: Array; +}; + +export type GetExternalMixedResponse = GetExternalMixedResponses[keyof GetExternalMixedResponses]; + +export type PostExternalMixedData = { + /** + * Request body with mixed external properties + */ + body?: ExternalMixedBody; + path?: never; + query?: never; + url: '/external-mixed'; +}; + +export type PostExternalMixedResponses = { + /** + * Response using external model + */ + 201: ExternalSharedExternalSharedModel; +}; + +export type PostExternalMixedResponse = PostExternalMixedResponses[keyof PostExternalMixedResponses]; + +export type GetExternalArrayData = { + body?: never; + path?: never; + query?: never; + url: '/external-array'; +}; + +export type GetExternalArrayResponses = { + /** + * Response with array of external models + */ + 200: Array; +}; + +export type GetExternalArrayResponse = GetExternalArrayResponses[keyof GetExternalArrayResponses]; + +export type PostExternalArrayData = { + body: Array; + path?: never; + query?: never; + url: '/external-array'; +}; + +export type PostExternalArrayResponses = { + /** + * Response with array of external models + */ + 201: Array; +}; + +export type PostExternalArrayResponse = PostExternalArrayResponses[keyof PostExternalArrayResponses]; + +export type GetExternalUnionData = { + body?: never; + path?: never; + query?: never; + url: '/external-union'; +}; + +export type GetExternalUnionResponses = { + /** + * Response with union of external types + */ + 200: ExternalSharedExternalSharedModel | ExternalSharedExternalSharedModelWithUuid | ExternalSharedExternalNested; +}; + +export type GetExternalUnionResponse = GetExternalUnionResponses[keyof GetExternalUnionResponses]; + +export type PostExternalUnionData = { + body: ExternalSharedExternalSharedModel | ExternalSharedExternalSharedModelWithUuid | ExternalSharedExternalNested; + path?: never; + query?: never; + url: '/external-union'; +}; + +export type PostExternalUnionResponses = { + /** + * Response with union of external types + */ + 201: ExternalSharedExternalSharedModel | ExternalSharedExternalSharedModelWithUuid | ExternalSharedExternalNested; +}; + +export type PostExternalUnionResponse = PostExternalUnionResponses[keyof PostExternalUnionResponses]; + +export type GetExternalPropertiesByIdData = { + body?: never; + headers?: { + deep?: ExternalSharedDeep; + }; + path: { + id: ExternalSharedId; + }; + query?: { + uuid?: ExternalSharedExternalSharedModelWithUuid; + }; + url: '/external-properties/{id}'; +}; + +export type GetExternalPropertiesByIdResponses = { + 200: { + id?: ExternalSharedId; + name?: ExternalSharedName; + uuid?: ExternalSharedExternalSharedModelWithUuid; + deep?: ExternalSharedDeep; + numeric?: ExternalShared1; + }; +}; + +export type GetExternalPropertiesByIdResponse = GetExternalPropertiesByIdResponses[keyof GetExternalPropertiesByIdResponses]; + +export type ClientOptions = { + baseUrl: `${string}://${string}` | (string & {}); +}; diff --git a/packages/openapi-ts-tests/main/test/clients.test.ts b/packages/openapi-ts-tests/main/test/clients.test.ts index af3a0b1b6..877597159 100644 --- a/packages/openapi-ts-tests/main/test/clients.test.ts +++ b/packages/openapi-ts-tests/main/test/clients.test.ts @@ -170,6 +170,7 @@ for (const client of clients) { const outputPath = typeof config.output === 'string' ? config.output : config.output.path; + const filePaths = getFilePaths(outputPath); await Promise.all( @@ -327,6 +328,7 @@ describe('custom-client', () => { const outputPath = typeof config.output === 'string' ? config.output : config.output.path; + const filePaths = getFilePaths(outputPath); await Promise.all( @@ -473,6 +475,7 @@ describe('my-client', () => { const outputPath = typeof config.output === 'string' ? config.output : config.output.path; + const filePaths = getFilePaths(outputPath); await Promise.all( diff --git a/packages/openapi-ts-tests/main/test/index.test.ts b/packages/openapi-ts-tests/main/test/index.test.ts index 0a787595e..29acc0b78 100644 --- a/packages/openapi-ts-tests/main/test/index.test.ts +++ b/packages/openapi-ts-tests/main/test/index.test.ts @@ -62,6 +62,68 @@ describe('OpenAPI v2', () => { }); }); +describe('Multi-output', () => { + it('generates multiple outputs with different configurations', async () => { + const results = await createClient({ + input: V3_SPEC_PATH, + logs: { level: 'silent' }, + output: [ + toOutputPath('multi-output-legacy-1'), + { + clean: true, + indexFile: false, + path: toOutputPath('multi-output-legacy-2'), + }, + ], + plugins: ['legacy/fetch', '@hey-api/typescript'], + }); + + expect(results).toHaveLength(2); + + // Verify that both results are client objects + results.forEach((result) => { + expect(result).toBeDefined(); + expect(result).toHaveProperty('services'); + }); + }); + + it('generates multiple outputs with different plugins', async () => { + const results = await createClient([ + { + input: V3_SPEC_PATH, + logs: { level: 'silent' }, + output: toOutputPath('multi-output-fetch'), + plugins: ['legacy/fetch', '@hey-api/typescript'], + }, + { + input: V3_SPEC_PATH, + logs: { level: 'silent' }, + output: toOutputPath('multi-output-sdk'), + plugins: ['@hey-api/typescript', '@hey-api/sdk'], + }, + ]); + + expect(results).toHaveLength(2); + + // Verify that both results are valid client/context objects + results.forEach((result) => { + expect(result).toBeDefined(); + }); + }); + + it('handles empty output array gracefully', async () => { + const results = await createClient({ + input: V3_SPEC_PATH, + logs: { level: 'silent' }, + output: [], + plugins: ['@hey-api/typescript'], + }); + + // Should result in no outputs + expect(results).toHaveLength(0); + }); +}); + describe('OpenAPI v3', () => { const config: UserConfig = { exportCore: true, diff --git a/packages/openapi-ts-tests/main/test/plugins.test.ts b/packages/openapi-ts-tests/main/test/plugins.test.ts index e3b47cda3..b6dad02f5 100644 --- a/packages/openapi-ts-tests/main/test/plugins.test.ts +++ b/packages/openapi-ts-tests/main/test/plugins.test.ts @@ -568,6 +568,7 @@ for (const version of versions) { const outputPath = typeof config.output === 'string' ? config.output : config.output.path; + const filePaths = getFilePaths(outputPath); await Promise.all( diff --git a/packages/openapi-ts-tests/specs/2.0.x/multi-a.json b/packages/openapi-ts-tests/specs/2.0.x/multi-a.json new file mode 100644 index 000000000..bf60a62e8 --- /dev/null +++ b/packages/openapi-ts-tests/specs/2.0.x/multi-a.json @@ -0,0 +1,22 @@ +{ + "swagger": "2.0", + "info": { + "title": "Multi A 2.0.x", + "version": "1.0.0" + }, + "paths": { + "/a": { + "get": { + "responses": { + "200": { + "description": "ok", + "schema": { + "type": "object", + "properties": { "a": { "type": "string" } } + } + } + } + } + } + } +} diff --git a/packages/openapi-ts-tests/specs/2.0.x/multi-b.json b/packages/openapi-ts-tests/specs/2.0.x/multi-b.json new file mode 100644 index 000000000..eb6db1779 --- /dev/null +++ b/packages/openapi-ts-tests/specs/2.0.x/multi-b.json @@ -0,0 +1,22 @@ +{ + "swagger": "2.0", + "info": { + "title": "Multi B 2.0.x", + "version": "1.0.0" + }, + "paths": { + "/b": { + "get": { + "responses": { + "200": { + "description": "ok", + "schema": { + "type": "object", + "properties": { "b": { "type": "string" } } + } + } + } + } + } + } +} diff --git a/packages/openapi-ts-tests/specs/3.0.x/multi-a.yaml b/packages/openapi-ts-tests/specs/3.0.x/multi-a.yaml new file mode 100644 index 000000000..f72cc3cd5 --- /dev/null +++ b/packages/openapi-ts-tests/specs/3.0.x/multi-a.yaml @@ -0,0 +1,18 @@ +openapi: 3.0.3 +info: + title: Multi A 3.0.x + version: 1.0.0 +paths: + /a: + get: + summary: Get A + responses: + '200': + description: ok + content: + application/json: + schema: + type: object + properties: + a: + type: string diff --git a/packages/openapi-ts-tests/specs/3.0.x/multi-b.yaml b/packages/openapi-ts-tests/specs/3.0.x/multi-b.yaml new file mode 100644 index 000000000..e279f4988 --- /dev/null +++ b/packages/openapi-ts-tests/specs/3.0.x/multi-b.yaml @@ -0,0 +1,18 @@ +openapi: 3.0.3 +info: + title: Multi B 3.0.x + version: 1.0.0 +paths: + /b: + get: + summary: Get B + responses: + '200': + description: ok + content: + application/json: + schema: + type: object + properties: + b: + type: string diff --git a/packages/openapi-ts-tests/specs/3.1.x/multi-a.yaml b/packages/openapi-ts-tests/specs/3.1.x/multi-a.yaml new file mode 100644 index 000000000..71c5288b5 --- /dev/null +++ b/packages/openapi-ts-tests/specs/3.1.x/multi-a.yaml @@ -0,0 +1,18 @@ +openapi: 3.1.1 +info: + title: Multi A 3.1.x + version: 1.0.0 +paths: + /a: + get: + summary: Get A + responses: + '200': + description: ok + content: + application/json: + schema: + type: object + properties: + a: + type: string diff --git a/packages/openapi-ts-tests/specs/3.1.x/multi-b.yaml b/packages/openapi-ts-tests/specs/3.1.x/multi-b.yaml new file mode 100644 index 000000000..e4f8b8305 --- /dev/null +++ b/packages/openapi-ts-tests/specs/3.1.x/multi-b.yaml @@ -0,0 +1,18 @@ +openapi: 3.1.1 +info: + title: Multi B 3.1.x + version: 1.0.0 +paths: + /b: + get: + summary: Get B + responses: + '200': + description: ok + content: + application/json: + schema: + type: object + properties: + b: + type: string diff --git a/packages/openapi-ts-tests/zod/v3/test/3.1.x.test.ts b/packages/openapi-ts-tests/zod/v3/test/3.1.x.test.ts index 8ec15f08d..bef41220f 100644 --- a/packages/openapi-ts-tests/zod/v3/test/3.1.x.test.ts +++ b/packages/openapi-ts-tests/zod/v3/test/3.1.x.test.ts @@ -145,6 +145,7 @@ for (const zodVersion of zodVersions) { const outputPath = typeof config.output === 'string' ? config.output : config.output.path; + const filePaths = getFilePaths(outputPath); await Promise.all( diff --git a/packages/openapi-ts-tests/zod/v3/test/utils.ts b/packages/openapi-ts-tests/zod/v3/test/utils.ts index d18918019..6962ca2b6 100644 --- a/packages/openapi-ts-tests/zod/v3/test/utils.ts +++ b/packages/openapi-ts-tests/zod/v3/test/utils.ts @@ -24,7 +24,11 @@ export const createZodConfig = openApiVersion, typeof userConfig.input === 'string' ? userConfig.input - : (userConfig.input.path as string), + : userConfig.input instanceof Array + ? typeof userConfig.input[0] === 'string' + ? (userConfig.input[0] as string) + : (userConfig.input[0] as any)?.path || '' + : (userConfig.input as any).path, ); return { plugins: [ diff --git a/packages/openapi-ts-tests/zod/v4/test/3.0.x.test.ts b/packages/openapi-ts-tests/zod/v4/test/3.0.x.test.ts index ed27c881f..ae522c67d 100644 --- a/packages/openapi-ts-tests/zod/v4/test/3.0.x.test.ts +++ b/packages/openapi-ts-tests/zod/v4/test/3.0.x.test.ts @@ -63,6 +63,7 @@ for (const zodVersion of zodVersions) { const outputPath = typeof config.output === 'string' ? config.output : config.output.path; + const filePaths = getFilePaths(outputPath); await Promise.all( diff --git a/packages/openapi-ts-tests/zod/v4/test/3.1.x.test.ts b/packages/openapi-ts-tests/zod/v4/test/3.1.x.test.ts index 8ec15f08d..bef41220f 100644 --- a/packages/openapi-ts-tests/zod/v4/test/3.1.x.test.ts +++ b/packages/openapi-ts-tests/zod/v4/test/3.1.x.test.ts @@ -145,6 +145,7 @@ for (const zodVersion of zodVersions) { const outputPath = typeof config.output === 'string' ? config.output : config.output.path; + const filePaths = getFilePaths(outputPath); await Promise.all( diff --git a/packages/openapi-ts-tests/zod/v4/test/utils.ts b/packages/openapi-ts-tests/zod/v4/test/utils.ts index d18918019..6962ca2b6 100644 --- a/packages/openapi-ts-tests/zod/v4/test/utils.ts +++ b/packages/openapi-ts-tests/zod/v4/test/utils.ts @@ -24,7 +24,11 @@ export const createZodConfig = openApiVersion, typeof userConfig.input === 'string' ? userConfig.input - : (userConfig.input.path as string), + : userConfig.input instanceof Array + ? typeof userConfig.input[0] === 'string' + ? (userConfig.input[0] as string) + : (userConfig.input[0] as any)?.path || '' + : (userConfig.input as any).path, ); return { plugins: [ diff --git a/packages/openapi-ts/package.json b/packages/openapi-ts/package.json index ebbd30121..9c28d3c91 100644 --- a/packages/openapi-ts/package.json +++ b/packages/openapi-ts/package.json @@ -89,10 +89,10 @@ "node": "^18.18.0 || ^20.9.0 || >=22.10.0" }, "dependencies": { + "@hey-api/c12": "1.0.3", + "@hey-api/json-schema-ref-parser": "1.2.0", "@hey-api/codegen-core": "workspace:^0.1.0", - "@hey-api/json-schema-ref-parser": "1.1.0", "ansi-colors": "4.1.3", - "c12": "2.0.1", "color-support": "1.1.3", "commander": "13.0.0", "handlebars": "4.7.8", diff --git a/packages/openapi-ts/src/__tests__/index.test.ts b/packages/openapi-ts/src/__tests__/index.test.ts index 66ef27b77..06341b451 100644 --- a/packages/openapi-ts/src/__tests__/index.test.ts +++ b/packages/openapi-ts/src/__tests__/index.test.ts @@ -1,10 +1,150 @@ +import { platform } from 'os'; import { describe, expect, it } from 'vitest'; -describe('main entry index', () => { - describe('createClient', () => { - it('should be exported', async () => { - const { createClient } = await import('../index'); - expect(createClient).toBeDefined(); +import type { UserConfig, UserConfigMultiOutputs } from '../types/config'; + +describe( + 'main entry index', + () => { + describe('createClient', () => { + it('should be exported', async () => { + const { createClient } = await import('../index'); + expect(createClient).toBeDefined(); + }); + + it('should handle single output configuration', async () => { + const { createClient } = await import('../index'); + + const config: UserConfig = { + dryRun: true, + input: { + info: { title: 'Test API', version: '1.0.0' }, + openapi: '3.0.0', + paths: {}, + }, + output: 'test-output', + plugins: ['@hey-api/typescript'], + }; + + const results = await createClient(config); + expect(results).toHaveLength(1); + }); + + it('should handle multiple string outputs', async () => { + const { createClient } = await import('../index'); + + const config: UserConfigMultiOutputs = { + dryRun: true, + input: { + info: { title: 'Test API', version: '1.0.0' }, + openapi: '3.0.0', + paths: {}, + }, + output: ['test-output-1', 'test-output-2', 'test-output-3'], + plugins: ['@hey-api/typescript'], + }; + + const results = await createClient(config); + expect(results).toHaveLength(3); + }); + + it('should handle multiple output objects with different configurations', async () => { + const { createClient } = await import('../index'); + + const config: UserConfigMultiOutputs = { + dryRun: true, + input: { + info: { title: 'Test API', version: '1.0.0' }, + openapi: '3.0.0', + paths: {}, + }, + output: [ + { + clean: true, + format: 'prettier', + path: 'test-output-formatted', + }, + { + clean: false, + lint: 'eslint', + path: 'test-output-linted', + }, + ], + plugins: ['@hey-api/typescript'], + }; + + const results = await createClient(config); + expect(results).toHaveLength(2); + }); + + it('should handle mixed string and object outputs', async () => { + const { createClient } = await import('../index'); + + const config: UserConfigMultiOutputs = { + dryRun: true, + input: { + info: { title: 'Test API', version: '1.0.0' }, + openapi: '3.0.0', + paths: {}, + }, + output: [ + 'test-simple-output', + { + format: 'prettier', + indexFile: false, + path: 'test-advanced-output', + }, + ], + plugins: ['@hey-api/typescript'], + }; + + const results = await createClient(config); + expect(results).toHaveLength(2); + }); + + it('should preserve global config across multiple outputs', async () => { + const { createClient } = await import('../index'); + + const config: UserConfigMultiOutputs = { + dryRun: true, + experimentalParser: true, + input: { + info: { title: 'Test API', version: '1.0.0' }, + openapi: '3.0.0', + paths: { + '/test': { + get: { + responses: { + '200': { + content: { + 'application/json': { + schema: { type: 'string' }, + }, + }, + description: 'Success', + }, + }, + }, + }, + }, + }, + output: ['output-1', 'output-2'], + plugins: ['@hey-api/typescript'], + }; + + const results = await createClient(config); + expect(results).toHaveLength(2); + + // Both results should be IR.Context objects (due to experimentalParser: true) + // and should have the same input specification + results.forEach((result) => { + if ('spec' in result) { + expect(result.spec.info.title).toBe('Test API'); + expect(result.config.experimentalParser).toBe(true); + } + }); + }); }); - }); -}); + }, + { timeout: platform() === 'win32' ? 12500 : 7500 }, +); diff --git a/packages/openapi-ts/src/config/init.ts b/packages/openapi-ts/src/config/init.ts index e779a8b12..e1d5ea15c 100644 --- a/packages/openapi-ts/src/config/init.ts +++ b/packages/openapi-ts/src/config/init.ts @@ -1,9 +1,13 @@ import path from 'node:path'; -import { loadConfig } from 'c12'; +import { loadConfig } from '@hey-api/c12'; import { ConfigError } from '../error'; -import type { Config, UserConfig } from '../types/config'; +import type { + Config, + UserConfig, + UserConfigMultiOutputs, +} from '../types/config'; import { isLegacyClient, setConfig } from '../utils/config'; import { getInput } from './input'; import { getLogs } from './logs'; @@ -13,11 +17,41 @@ import { getProjectDependencies } from './packages'; import { getParser } from './parser'; import { getPlugins } from './plugins'; +/** + * Expands a UserConfig with multiple outputs into multiple UserConfigs with single outputs + * @internal + */ +const expandMultiOutputConfigs = ( + userConfigs: ReadonlyArray, +): ReadonlyArray => { + const expandedConfigs: Array = []; + + for (const userConfig of userConfigs) { + if (Array.isArray(userConfig.output)) { + // Multi-output configuration - expand into multiple single-output configs + for (const output of userConfig.output) { + expandedConfigs.push({ + ...userConfig, + output, + }); + } + } else { + // Single output configuration - keep as is + expandedConfigs.push(userConfig as UserConfig); + } + } + + return expandedConfigs; +}; + /** * @internal */ export const initConfigs = async ( - userConfig: UserConfig | undefined, + userConfig: + | UserConfigMultiOutputs + | ReadonlyArray + | undefined, ): Promise<{ dependencies: Record; results: ReadonlyArray<{ @@ -26,13 +60,16 @@ export const initConfigs = async ( }>; }> => { let configurationFile: string | undefined = undefined; - if (userConfig?.configFile) { - const parts = userConfig.configFile.split('.'); - configurationFile = parts.slice(0, parts.length - 1).join('.'); + if (userConfig && !(userConfig instanceof Array)) { + const cf = userConfig.configFile; + if (cf) { + const parts = cf.split('.'); + configurationFile = parts.slice(0, parts.length - 1).join('.'); + } } const { config: configFromFile, configFile: loadedConfigFile } = - await loadConfig({ + await loadConfig({ configFile: configurationFile, name: 'openapi-ts', }); @@ -40,12 +77,23 @@ export const initConfigs = async ( const dependencies = getProjectDependencies( Object.keys(configFromFile).length ? loadedConfigFile : undefined, ); - - const userConfigs: ReadonlyArray = Array.isArray(userConfig) + const baseUserConfigs: ReadonlyArray = Array.isArray( + userConfig, + ) ? userConfig : Array.isArray(configFromFile) - ? configFromFile.map((config) => mergeConfigs(config, userConfig)) - : [mergeConfigs(configFromFile, userConfig)]; + ? configFromFile.map((config) => + mergeConfigs(config, userConfig as UserConfig | undefined), + ) + : [ + mergeConfigs( + (configFromFile as UserConfig) ?? ({} as UserConfig), + userConfig as UserConfig | undefined, + ), + ]; + + // Expand multi-output configurations into multiple single-output configurations + const userConfigs = expandMultiOutputConfigs(baseUserConfigs); const results: Array<{ config: Config; diff --git a/packages/openapi-ts/src/config/input.ts b/packages/openapi-ts/src/config/input.ts index b1d18adb8..7d6d1fb74 100644 --- a/packages/openapi-ts/src/config/input.ts +++ b/packages/openapi-ts/src/config/input.ts @@ -44,6 +44,7 @@ export const getInput = (userConfig: UserConfig): Config['input'] => { input.path = userConfig.input; } else if ( userConfig.input && + !(userConfig.input instanceof Array) && (userConfig.input.path !== undefined || userConfig.input.organization !== undefined) ) { diff --git a/packages/openapi-ts/src/createClient.ts b/packages/openapi-ts/src/createClient.ts index fc28ce4bb..9d1f3b1bd 100644 --- a/packages/openapi-ts/src/createClient.ts +++ b/packages/openapi-ts/src/createClient.ts @@ -182,20 +182,40 @@ export const createClient = async ({ */ watch?: WatchValues; }) => { - const inputPath = compileInputPath(config.input); - const { timeout } = config.input.watch; + // Support single or multiple input paths + const { watch: watchOptions, ...inputWithoutWatch } = config.input as Omit< + Config['input'], + 'watch' + > & { watch: Config['input']['watch'] }; + const inputPathsArray: Array = Array.isArray( + inputWithoutWatch.path, + ) + ? (inputWithoutWatch.path as Array) + : [inputWithoutWatch.path as unknown as Config['input']['path']]; + const compiledInputs = inputPathsArray.map((p) => { + if (typeof p === 'string') { + return compileInputPath({ ...inputWithoutWatch, path: p }); + } + if (p && typeof p === 'object') { + // If the entry is an object (Input), spread it at the top level so we + // don't end up with a double-nested `path: { path: '...' }`. + return compileInputPath({ ...inputWithoutWatch, ...(p as any) }); + } + return compileInputPath({ ...inputWithoutWatch, path: p as any }); + }); + const { timeout } = watchOptions; - const watch: WatchValues = _watch || { headers: new Headers() }; + const watch: WatchValues = _watch || { headers: new Headers(), inputs: {} }; // on first run, print the message as soon as possible if (config.logs.level !== 'silent' && !_watch) { - logInputPath(inputPath); + compiledInputs.forEach((ci) => logInputPath(ci)); } const eventSpec = logger.timeEvent('spec'); const { data, error, response } = await getSpec({ fetchOptions: config.input.fetch, - inputPath: inputPath.path, + inputPaths: compiledInputs.map((ci) => ci.path), timeout, watch, }); @@ -218,7 +238,7 @@ export const createClient = async ({ // generating the output if (config.logs.level !== 'silent' && _watch) { console.clear(); - logInputPath(inputPath); + compiledInputs.forEach((ci) => logInputPath(ci)); } const eventInputPatch = logger.timeEvent('input.patch'); @@ -265,7 +285,10 @@ export const createClient = async ({ eventPostprocess.timeEnd(); } - if (config.input.watch.enabled && typeof inputPath.path === 'string') { + if ( + config.input.watch.enabled && + compiledInputs.some((ci) => typeof ci.path === 'string') + ) { setTimeout(() => { createClient({ config, dependencies, logger, templates, watch }); }, config.input.watch.interval); diff --git a/packages/openapi-ts/src/getSpec.ts b/packages/openapi-ts/src/getSpec.ts index aac442a6f..61245a101 100644 --- a/packages/openapi-ts/src/getSpec.ts +++ b/packages/openapi-ts/src/getSpec.ts @@ -26,37 +26,126 @@ interface SpecError { */ export const getSpec = async ({ fetchOptions, - inputPath, + inputPaths, timeout, watch, }: { fetchOptions?: RequestInit; - inputPath: Config['input']['path']; + inputPaths: Array; timeout: number; watch: WatchValues; }): Promise => { const refParser = new $RefParser(); - const resolvedInput = getResolvedInput({ pathOrUrlOrSchema: inputPath }); + const resolvedInputs = inputPaths.map((inputPath) => + getResolvedInput({ pathOrUrlOrSchema: inputPath }), + ); + + const arrayBuffer: ArrayBuffer[] = []; + let anyChanged = false; + let lastResponse: Response | undefined; + watch.inputs = watch.inputs || {}; + + for (const resolvedInput of resolvedInputs) { + let hasChanged: boolean | undefined; + let response: Response | undefined; + + const key = `${resolvedInput.type}:${resolvedInput.path ?? ''}`; + const state = (watch.inputs[key] = watch.inputs[key] || { + headers: new Headers(), + }); + + if (resolvedInput.type === 'url') { + if (state.lastValue && state.isHeadMethodSupported !== false) { + try { + const request = await sendRequest({ + fetchOptions: { + method: 'HEAD', + ...fetchOptions, + headers: mergeHeaders(fetchOptions?.headers, state.headers), + }, + timeout, + url: resolvedInput.path, + }); + + lastResponse = request.response; + + if (request.response.status >= 300) { + return { + error: 'not-ok', + response: request.response, + }; + } + + response = request.response; + } catch (error) { + return { + error: 'not-ok', + response: new Response((error as Error).message), + }; + } - let arrayBuffer: ArrayBuffer | undefined; - // boolean signals whether the file has **definitely** changed - let hasChanged: boolean | undefined; - let response: Response | undefined; + if (response.status === 304) { + hasChanged = false; + } else if (!response.ok && state.isHeadMethodSupported) { + return { + error: 'not-ok', + response, + }; + } + + if (state.isHeadMethodSupported === undefined) { + state.isHeadMethodSupported = response.ok; + } + + if (hasChanged === undefined) { + const eTag = response.headers.get('ETag'); + if (eTag) { + hasChanged = eTag !== state.headers.get('If-None-Match'); + if (hasChanged) { + state.headers.set('If-None-Match', eTag); + } else { + // Definitely not changed based on ETag + hasChanged = false; + } + } + } + + if (hasChanged === undefined) { + const lastModified = response.headers.get('Last-Modified'); + if (lastModified) { + hasChanged = + lastModified !== state.headers.get('If-Modified-Since'); + if (hasChanged) { + state.headers.set('If-Modified-Since', lastModified); + } else { + hasChanged = false; + } + } + } + + if (hasChanged === false && state.lastValue !== undefined) { + // Use cached content without GET + const encoded = new TextEncoder().encode(state.lastValue); + const cachedBuffer = new ArrayBuffer(encoded.byteLength); + new Uint8Array(cachedBuffer).set(encoded); + arrayBuffer.push(cachedBuffer); + anyChanged = anyChanged || false; + continue; + } + } - if (resolvedInput.type === 'url') { - // do NOT send HEAD request on first run or if unsupported - if (watch.lastValue && watch.isHeadMethodSupported !== false) { try { const request = await sendRequest({ fetchOptions: { - method: 'HEAD', + method: 'GET', ...fetchOptions, - headers: mergeHeaders(fetchOptions?.headers, watch.headers), }, timeout, url: resolvedInput.path, }); + lastResponse = request.response; + if (request.response.status >= 300) { return { error: 'not-ok', @@ -68,127 +157,76 @@ export const getSpec = async ({ } catch (error) { return { error: 'not-ok', - response: new Response(error.message), + response: new Response((error as Error).message), }; } - if (!response.ok && watch.isHeadMethodSupported) { - // assume the server is no longer running - // do nothing, it might be restarted later + if (!response.ok) { return { error: 'not-ok', response, }; } - if (watch.isHeadMethodSupported === undefined) { - watch.isHeadMethodSupported = response.ok; - } - - if (response.status === 304) { - return { - error: 'not-modified', - response, - }; - } - - if (hasChanged === undefined) { - const eTag = response.headers.get('ETag'); - if (eTag) { - hasChanged = eTag !== watch.headers.get('If-None-Match'); - - if (hasChanged) { - watch.headers.set('If-None-Match', eTag); - } - } - } + const lastBuffer = response.body + ? await response.arrayBuffer() + : new ArrayBuffer(0); + arrayBuffer.push(lastBuffer); if (hasChanged === undefined) { - const lastModified = response.headers.get('Last-Modified'); - if (lastModified) { - hasChanged = lastModified !== watch.headers.get('If-Modified-Since'); - - if (hasChanged) { - watch.headers.set('If-Modified-Since', lastModified); - } - } + const content = new TextDecoder().decode(lastBuffer); + hasChanged = content !== state.lastValue; + state.lastValue = content; + } else if (hasChanged) { + // Update lastValue since it changed + const content = new TextDecoder().decode(lastBuffer); + state.lastValue = content; } - - // we definitely know the input has not changed - if (hasChanged === false) { - return { - error: 'not-modified', - response, - }; - } - } - - try { - const request = await sendRequest({ - fetchOptions: { - method: 'GET', - ...fetchOptions, - }, - timeout, - url: resolvedInput.path, - }); - - if (request.response.status >= 300) { - return { - error: 'not-ok', - response: request.response, - }; + } else { + // we do not support watch mode for files or raw spec data + if (!state.lastValue) { + state.lastValue = resolvedInput.type; + } else { + hasChanged = false; } - - response = request.response; - } catch (error) { - return { - error: 'not-ok', - response: new Response(error.message), - }; - } - - if (!response.ok) { - // assume the server is no longer running - // do nothing, it might be restarted later - return { - error: 'not-ok', - response, - }; + // Maintain alignment with resolvedInputs + arrayBuffer.push(new ArrayBuffer(0)); } - arrayBuffer = response.body - ? await response.arrayBuffer() - : new ArrayBuffer(0); + anyChanged = anyChanged || hasChanged !== false; + } - if (hasChanged === undefined) { - const content = new TextDecoder().decode(arrayBuffer); - hasChanged = content !== watch.lastValue; - watch.lastValue = content; - } + let data: JSONSchema; + if (resolvedInputs.length === 1) { + data = await refParser.bundle({ + arrayBuffer: arrayBuffer[0], + pathOrUrlOrSchema: undefined, + resolvedInput: resolvedInputs[0], + }); } else { - // we do not support watch mode for files or raw spec data - if (!watch.lastValue) { - watch.lastValue = resolvedInput.type; - } else { - hasChanged = false; - } + data = await refParser.bundleMany({ + arrayBuffer, + pathOrUrlOrSchemas: [], + resolvedInputs, + // : [ + // { + // path: 'c:/Users/olafk/DEV/openapi-ts-demo/openapi1.yaml', + // schema: undefined, + // type: 'file', + // }, + // { + // path: 'c:/Users/olafk/DEV/openapi-ts-demo/openapi2.yaml', + // schema: undefined, + // type: 'file', + // }, + // ], + }); } - - if (hasChanged === false) { + if (!anyChanged) { return { error: 'not-modified', - response: response!, - }; + response: lastResponse || new Response('', { status: 304 }), + } as SpecError; } - - const data = await refParser.bundle({ - arrayBuffer, - pathOrUrlOrSchema: undefined, - resolvedInput, - }); - - return { - data, - }; + return { data }; }; diff --git a/packages/openapi-ts/src/index.ts b/packages/openapi-ts/src/index.ts index face419d9..9c9820fd4 100644 --- a/packages/openapi-ts/src/index.ts +++ b/packages/openapi-ts/src/index.ts @@ -14,21 +14,29 @@ import { } from './error'; import type { IR } from './ir/types'; import type { Client } from './types/client'; -import type { Config, UserConfig } from './types/config'; +import type { + Config, + UserConfig, + UserConfigMultiOutputs, +} from './types/config'; import { registerHandlebarTemplates } from './utils/handlebars'; import { Logger } from './utils/logger'; -type Configs = UserConfig | (() => UserConfig) | (() => Promise); +type ConfigValue = + | UserConfigMultiOutputs + | ReadonlyArray; +// Generic input shape for config that may be a value or a (possibly async) factory +type ConfigInput = T | (() => T) | (() => Promise); colors.enabled = colorSupport().hasBasic; /** * Generate a client from the provided configuration. * - * @param userConfig User provided {@link UserConfig} configuration. + * @param userConfig User provided {@link UserConfigMultiOutputs} configuration. */ export const createClient = async ( - userConfig?: Configs, + userConfig?: ConfigInput, logger = new Logger(), ): Promise> => { const resolvedConfig = @@ -77,11 +85,15 @@ export const createClient = async ( return result; } catch (error) { const config = configs[0] as Config | undefined; - const dryRun = config ? config.dryRun : resolvedConfig?.dryRun; + // TODO: Improve error handling for multi-output configs + const resolvedSingle = ( + Array.isArray(resolvedConfig) ? resolvedConfig[0] : resolvedConfig + ) as UserConfigMultiOutputs | undefined; + const dryRun = config ? config.dryRun : resolvedSingle?.dryRun; const isInteractive = config ? config.interactive - : resolvedConfig?.interactive; - const logs = config?.logs ?? getLogs(resolvedConfig); + : resolvedSingle?.interactive; + const logs = config?.logs ?? getLogs(resolvedSingle as UserConfig); let logPath: string | undefined; @@ -101,10 +113,14 @@ export const createClient = async ( }; /** - * Type helper for openapi-ts.config.ts, returns {@link UserConfig} object + * Type helper for openapi-ts.config.ts, preserves input shape (object vs array) */ -export const defineConfig = async (config: Configs): Promise => - typeof config === 'function' ? await config() : config; +export const defineConfig = async ( + config: ConfigInput, +): Promise => + typeof config === 'function' + ? await (config as () => T | Promise)() + : (config as T); export { defaultPaginationKeywords } from './config/parser'; export { defaultPlugins } from './config/plugins'; diff --git a/packages/openapi-ts/src/types/config.d.ts b/packages/openapi-ts/src/types/config.d.ts index a762bc8c3..918140ee5 100644 --- a/packages/openapi-ts/src/types/config.d.ts +++ b/packages/openapi-ts/src/types/config.d.ts @@ -1,10 +1,13 @@ import type { PluginConfigMap } from '../plugins/config'; import type { Plugin, PluginNames } from '../plugins/types'; -import type { Input, Watch } from './input'; +import type { Input, InputPath, Watch } from './input'; import type { Logs } from './logs'; import type { Output } from './output'; import type { Parser, ResolvedParser } from './parser'; +export interface UserConfigMultiOutputs extends UserConfig { + output: string | Output | ReadonlyArray; +} export interface UserConfig { /** * Path to the config file. Set this value if you don't use the default @@ -28,15 +31,7 @@ export interface UserConfig { * * Alternatively, you can define a configuration object with more options. */ - input: - | `https://get.heyapi.dev/${string}/${string}` - | `${string}/${string}` - | `readme:@${string}/${string}#${string}` - | `readme:${string}` - | `scalar:@${string}/${string}` - | (string & {}) - | (Record & { path?: never }) - | Input; + input: InputPath | Input | ReadonlyArray; /** * Show an interactive error reporting tool when the program crashes? You * generally want to keep this disabled (default). @@ -51,7 +46,9 @@ export interface UserConfig { */ logs?: string | Logs; /** - * The relative location of the output folder. + * The relative location of the output folder. You can specify multiple + * outputs to generate different versions of your SDK with different + * configurations (e.g., different plugins, formatters, or paths). */ output: string | Output; /** @@ -147,7 +144,7 @@ export type Config = Omit< watch: Extract['watch']>, object>; }; logs: Extract, object>; - output: Extract; + output: Output; /** * Customize how the input is parsed and transformed before it's passed to * plugins. diff --git a/packages/openapi-ts/src/types/input.d.ts b/packages/openapi-ts/src/types/input.d.ts index e5b26e5ff..139d91bb3 100644 --- a/packages/openapi-ts/src/types/input.d.ts +++ b/packages/openapi-ts/src/types/input.d.ts @@ -1,3 +1,12 @@ +export type InputPath = + | `https://get.heyapi.dev/${string}/${string}` + | `${string}/${string}` + | `readme:@${string}/${string}#${string}` + | `readme:${string}` + | `scalar:@${string}/${string}` + | (string & {}) + | Record; + export type Input = { /** * **Requires `path` to start with `https://get.heyapi.dev` or be undefined** @@ -44,14 +53,7 @@ export type Input = { * Both JSON and YAML file formats are supported. You can also pass the parsed * object directly if you're fetching the file yourself. */ - path?: - | `https://get.heyapi.dev/${string}/${string}` - | `${string}/${string}` - | `readme:@${string}/${string}#${string}` - | `readme:${string}` - | `scalar:@${string}/${string}` - | (string & {}) - | Record; + path?: InputPath; /** * **Requires `path` to start with `https://get.heyapi.dev` or be undefined** * diff --git a/packages/openapi-ts/src/types/types.d.ts b/packages/openapi-ts/src/types/types.d.ts index dfa6fc258..75043f7bb 100644 --- a/packages/openapi-ts/src/types/types.d.ts +++ b/packages/openapi-ts/src/types/types.d.ts @@ -11,6 +11,18 @@ export interface WatchValues { * into comparing the specifications using that method. */ headers: Headers; + /** + * Per-input watch state for multi-input mode. Keys should be a stable + * identifier for the input (typically the URL or file path). + */ + inputs?: Record< + string, + { + headers: Headers; + isHeadMethodSupported?: boolean; + lastValue?: string; + } + >; /** * Can we send a HEAD request instead of fetching the whole specification? * This value will be set after the first successful fetch. diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4cd86ec6c..706807f52 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -170,7 +170,7 @@ importers: devDependencies: '@angular-devkit/build-angular': specifier: 19.2.0 - version: 19.2.0(696c3532ef15b073c21785e1bc79a040) + version: 19.2.0(2d14940f40ec266edc773a5f5d918fb0) '@angular/cli': specifier: 19.2.0 version: 19.2.0(@types/node@22.10.5)(chokidar@4.0.3) @@ -264,7 +264,7 @@ importers: devDependencies: '@angular-devkit/build-angular': specifier: 19.2.0 - version: 19.2.0(b57b04a4dfd0d7238fcb437f41884422) + version: 19.2.0(c051f58b50ee906cd14109939270cbce) '@angular/cli': specifier: 19.2.0 version: 19.2.0(@types/node@22.10.5)(chokidar@4.0.3) @@ -825,7 +825,7 @@ importers: devDependencies: '@angular-devkit/build-angular': specifier: ^19.2.15 - version: 19.2.15(@angular/compiler-cli@19.2.14(@angular/compiler@19.2.14)(typescript@5.8.3))(@angular/compiler@19.2.14)(@angular/platform-server@19.2.0(@angular/common@19.2.14(@angular/core@19.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/compiler@19.2.14)(@angular/core@19.2.14(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.14(@angular/animations@19.2.14(@angular/common@19.2.14(@angular/core@19.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.14(@angular/core@19.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.14(rxjs@7.8.2)(zone.js@0.15.1))))(@angular/ssr@19.2.15(fc183c600d5538ac11e1814ee07b5dfc))(@types/node@22.10.5)(chokidar@4.0.3)(jiti@2.5.1)(karma@6.4.4)(tailwindcss@3.4.9(ts-node@10.9.2(@types/node@22.10.5)(typescript@5.8.3)))(typescript@5.8.3)(vite@7.1.2(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.0))(yaml@2.8.0) + version: 19.2.15(@angular/compiler-cli@19.2.14(@angular/compiler@19.2.14)(typescript@5.8.3))(@angular/compiler@19.2.14)(@angular/platform-server@19.2.0(@angular/common@19.2.14(@angular/core@19.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/compiler@19.2.14)(@angular/core@19.2.14(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.14(@angular/animations@19.2.14(@angular/common@19.2.14(@angular/core@19.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.14(@angular/core@19.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.14(rxjs@7.8.2)(zone.js@0.15.1))))(@angular/ssr@19.2.15(fc183c600d5538ac11e1814ee07b5dfc))(@types/node@22.10.5)(chokidar@4.0.3)(jiti@2.5.1)(karma@6.4.4)(tailwindcss@3.4.9(ts-node@10.9.2(@types/node@22.10.5)(typescript@5.8.3)))(typescript@5.8.3)(vite@6.3.5(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.0))(yaml@2.8.0) '@angular/cli': specifier: ^19.2.15 version: 19.2.15(@types/node@22.10.5)(chokidar@4.0.3) @@ -1173,18 +1173,18 @@ importers: packages/openapi-ts: dependencies: + '@hey-api/c12': + specifier: 1.0.3 + version: 1.0.3(magicast@0.3.5) '@hey-api/codegen-core': specifier: workspace:^0.1.0 version: link:../codegen-core '@hey-api/json-schema-ref-parser': - specifier: 1.1.0 - version: 1.1.0 + specifier: 1.2.0 + version: 1.2.0 ansi-colors: specifier: 4.1.3 version: 4.1.3 - c12: - specifier: 2.0.1 - version: 2.0.1(magicast@0.3.5) color-support: specifier: 1.1.3 version: 1.1.3 @@ -1257,7 +1257,7 @@ importers: version: 3.3.2 nuxt: specifier: 3.14.1592 - version: 3.14.1592(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.1)(@types/node@22.10.5)(db0@0.3.2)(encoding@0.1.13)(eslint@9.17.0(jiti@2.5.1))(ioredis@5.7.0)(less@4.2.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.50.0)(sass@1.85.0)(terser@5.43.1)(typescript@5.8.3)(vite@7.1.2(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0)) + version: 3.14.1592(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.1)(@types/node@22.10.5)(db0@0.3.2)(encoding@0.1.13)(eslint@9.17.0(jiti@2.5.1))(ioredis@5.7.0)(less@4.2.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.50.0)(sass@1.85.0)(terser@5.43.1)(typescript@5.8.3)(vite@5.4.19(@types/node@22.10.5)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)) prettier: specifier: 3.4.2 version: 3.4.2 @@ -1287,7 +1287,7 @@ importers: devDependencies: '@angular-devkit/build-angular': specifier: 19.2.0 - version: 19.2.0(ac4ffa91faa637dff4fd6a93b49aaa4c) + version: 19.2.0(15a86fe5dd2abc83e2961d572f8e7511) '@angular/animations': specifier: 19.2.0 version: 19.2.0(@angular/core@19.2.0(rxjs@7.8.1)(zone.js@0.15.1)) @@ -1371,7 +1371,7 @@ importers: version: 3.3.2 nuxt: specifier: 3.14.1592 - version: 3.14.1592(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.1)(@types/node@22.10.5)(db0@0.3.2)(encoding@0.1.13)(eslint@9.17.0(jiti@2.5.1))(ioredis@5.7.0)(less@4.2.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.50.0)(sass@1.85.0)(terser@5.43.1)(typescript@5.8.3)(vite@7.1.2(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0)) + version: 3.14.1592(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.1)(@types/node@22.10.5)(db0@0.3.2)(encoding@0.1.13)(eslint@9.17.0(jiti@2.5.1))(ioredis@5.7.0)(less@4.2.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.50.0)(sass@1.85.0)(terser@5.43.1)(typescript@5.8.3)(vite@6.3.5(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0)) prettier: specifier: 3.4.2 version: 3.4.2 @@ -3673,8 +3673,16 @@ packages: '@fontsource/fira-mono@5.0.0': resolution: {integrity: sha512-IsinH/oLYJyv/sQv7SbKmjoAXZsSjm6Q1Tz5GBBXCXi3Jg9MzXmKvWm9bSLC8lFI6CDsi8GkH/DAgZ98t8bhTQ==} - '@hey-api/json-schema-ref-parser@1.1.0': - resolution: {integrity: sha512-+5eg9pgAAM9oSqJQuUtfTKbLz8yieFKN91myyXiLnprqFj8ROfxUKJLr9DKq/hGKyybKT1WxFSetDqCFm80pCA==} + '@hey-api/c12@1.0.3': + resolution: {integrity: sha512-nqmZ/i+U8a8QZxhRjq87Nigp18jrVAfCQ2VYYpIAMbyc7iIvEvlWjneDdv9ax9u7T0F4bhTDV6qhv5da+7qCJw==} + peerDependencies: + magicast: ^0.3.5 + peerDependenciesMeta: + magicast: + optional: true + + '@hey-api/json-schema-ref-parser@1.2.0': + resolution: {integrity: sha512-BMnIuhVgNmSudadw1GcTsP18Yk5l8FrYrg/OSYNxz0D2E0vf4D5e4j5nUbuY8MU6p1vp7ev0xrfP6A/NWazkzQ==} engines: {node: '>= 16'} '@humanfs/core@0.19.1': @@ -13647,14 +13655,14 @@ snapshots: transitivePeerDependencies: - chokidar - '@angular-devkit/build-angular@19.2.0(696c3532ef15b073c21785e1bc79a040)': + '@angular-devkit/build-angular@19.2.0(15a86fe5dd2abc83e2961d572f8e7511)': dependencies: '@ampproject/remapping': 2.3.0 '@angular-devkit/architect': 0.1902.0(chokidar@4.0.3) - '@angular-devkit/build-webpack': 0.1902.0(chokidar@4.0.3)(webpack-dev-server@5.2.0(webpack@5.98.0(esbuild@0.25.0)))(webpack@5.98.0(esbuild@0.25.0)) + '@angular-devkit/build-webpack': 0.1902.0(chokidar@4.0.3)(webpack-dev-server@5.2.0(webpack@5.98.0(esbuild@0.25.9)))(webpack@5.98.0(esbuild@0.25.0)) '@angular-devkit/core': 19.2.0(chokidar@4.0.3) - '@angular/build': 19.2.0(@angular/compiler-cli@19.2.0(@angular/compiler@19.2.0(@angular/core@19.2.0(rxjs@7.8.2)(zone.js@0.15.1)))(typescript@5.8.3))(@angular/compiler@19.2.0(@angular/core@19.2.0(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/platform-server@19.2.0(@angular/common@19.2.0(@angular/core@19.2.0(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/compiler@19.2.0(@angular/core@19.2.0(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/core@19.2.0(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.0(@angular/animations@19.2.0(@angular/core@19.2.0(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.0(@angular/core@19.2.0(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.0(rxjs@7.8.2)(zone.js@0.15.1))))(@angular/ssr@19.2.15(5c03da8199d2fcdf9ff93b70f9349edd))(@types/node@22.10.5)(chokidar@4.0.3)(jiti@2.5.1)(karma@6.4.4)(less@4.2.2)(postcss@8.5.2)(tailwindcss@3.4.9(ts-node@10.9.2(@types/node@22.10.5)(typescript@5.8.3)))(terser@5.39.0)(typescript@5.8.3)(yaml@2.8.0) - '@angular/compiler-cli': 19.2.0(@angular/compiler@19.2.0(@angular/core@19.2.0(rxjs@7.8.2)(zone.js@0.15.1)))(typescript@5.8.3) + '@angular/build': 19.2.0(@angular/compiler-cli@19.2.0(@angular/compiler@19.2.0(@angular/core@19.2.0(rxjs@7.8.1)(zone.js@0.15.1)))(typescript@5.8.3))(@angular/compiler@19.2.0(@angular/core@19.2.0(rxjs@7.8.1)(zone.js@0.15.1)))(@angular/platform-server@19.2.0(@angular/common@19.2.0(@angular/core@19.2.0(rxjs@7.8.1)(zone.js@0.15.1))(rxjs@7.8.1))(@angular/compiler@19.2.0(@angular/core@19.2.0(rxjs@7.8.1)(zone.js@0.15.1)))(@angular/core@19.2.0(rxjs@7.8.1)(zone.js@0.15.1))(@angular/platform-browser@19.2.0(@angular/animations@19.2.0(@angular/core@19.2.0(rxjs@7.8.1)(zone.js@0.15.1)))(@angular/common@19.2.0(@angular/core@19.2.0(rxjs@7.8.1)(zone.js@0.15.1))(rxjs@7.8.1))(@angular/core@19.2.0(rxjs@7.8.1)(zone.js@0.15.1))))(@angular/ssr@19.2.15(9944558d2409a9f62c85c46d55b3507e))(@types/node@22.10.5)(chokidar@4.0.3)(jiti@2.5.1)(karma@6.4.4)(less@4.2.2)(postcss@8.5.2)(tailwindcss@3.4.9(ts-node@10.9.2(@types/node@22.10.5)(typescript@5.8.3)))(terser@5.39.0)(typescript@5.8.3)(yaml@2.8.0) + '@angular/compiler-cli': 19.2.0(@angular/compiler@19.2.0(@angular/core@19.2.0(rxjs@7.8.1)(zone.js@0.15.1)))(typescript@5.8.3) '@babel/core': 7.26.9 '@babel/generator': 7.26.9 '@babel/helper-annotate-as-pure': 7.25.9 @@ -13665,8 +13673,8 @@ snapshots: '@babel/preset-env': 7.26.9(@babel/core@7.26.9) '@babel/runtime': 7.26.9 '@discoveryjs/json-ext': 0.6.3 - '@ngtools/webpack': 19.2.0(@angular/compiler-cli@19.2.0(@angular/compiler@19.2.0(@angular/core@19.2.0(rxjs@7.8.2)(zone.js@0.15.1)))(typescript@5.8.3))(typescript@5.8.3)(webpack@5.98.0(esbuild@0.25.0)) - '@vitejs/plugin-basic-ssl': 1.2.0(vite@7.1.2(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.0)) + '@ngtools/webpack': 19.2.0(@angular/compiler-cli@19.2.0(@angular/compiler@19.2.0(@angular/core@19.2.0(rxjs@7.8.1)(zone.js@0.15.1)))(typescript@5.8.3))(typescript@5.8.3)(webpack@5.98.0(esbuild@0.25.0)) + '@vitejs/plugin-basic-ssl': 1.2.0(vite@6.3.5(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0)) ansi-colors: 4.1.3 autoprefixer: 10.4.20(postcss@8.5.2) babel-loader: 9.2.1(@babel/core@7.26.9)(webpack@5.98.0(esbuild@0.25.0)) @@ -13703,12 +13711,12 @@ snapshots: typescript: 5.8.3 webpack: 5.98.0(esbuild@0.25.9) webpack-dev-middleware: 7.4.2(webpack@5.98.0(esbuild@0.25.9)) - webpack-dev-server: 5.2.0(webpack@5.98.0(esbuild@0.25.0)) + webpack-dev-server: 5.2.0(webpack@5.98.0(esbuild@0.25.9)) webpack-merge: 6.0.1 webpack-subresource-integrity: 5.1.0(webpack@5.98.0(esbuild@0.25.9)) optionalDependencies: - '@angular/platform-server': 19.2.0(@angular/common@19.2.0(@angular/core@19.2.0(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/compiler@19.2.0(@angular/core@19.2.0(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/core@19.2.0(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.0(@angular/animations@19.2.0(@angular/core@19.2.0(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.0(@angular/core@19.2.0(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.0(rxjs@7.8.2)(zone.js@0.15.1))) - '@angular/ssr': 19.2.15(5c03da8199d2fcdf9ff93b70f9349edd) + '@angular/platform-server': 19.2.0(@angular/common@19.2.0(@angular/core@19.2.0(rxjs@7.8.1)(zone.js@0.15.1))(rxjs@7.8.1))(@angular/compiler@19.2.0(@angular/core@19.2.0(rxjs@7.8.1)(zone.js@0.15.1)))(@angular/core@19.2.0(rxjs@7.8.1)(zone.js@0.15.1))(@angular/platform-browser@19.2.0(@angular/animations@19.2.0(@angular/core@19.2.0(rxjs@7.8.1)(zone.js@0.15.1)))(@angular/common@19.2.0(@angular/core@19.2.0(rxjs@7.8.1)(zone.js@0.15.1))(rxjs@7.8.1))(@angular/core@19.2.0(rxjs@7.8.1)(zone.js@0.15.1))) + '@angular/ssr': 19.2.15(9944558d2409a9f62c85c46d55b3507e) esbuild: 0.25.0 karma: 6.4.4 tailwindcss: 3.4.9(ts-node@10.9.2(@types/node@22.10.5)(typescript@5.8.3)) @@ -13735,14 +13743,14 @@ snapshots: - webpack-cli - yaml - '@angular-devkit/build-angular@19.2.0(ac4ffa91faa637dff4fd6a93b49aaa4c)': + '@angular-devkit/build-angular@19.2.0(2d14940f40ec266edc773a5f5d918fb0)': dependencies: '@ampproject/remapping': 2.3.0 '@angular-devkit/architect': 0.1902.0(chokidar@4.0.3) - '@angular-devkit/build-webpack': 0.1902.0(chokidar@4.0.3)(webpack-dev-server@5.2.0(webpack@5.98.0(esbuild@0.25.0)))(webpack@5.98.0(esbuild@0.25.0)) + '@angular-devkit/build-webpack': 0.1902.0(chokidar@4.0.3)(webpack-dev-server@5.2.0(webpack@5.98.0(esbuild@0.25.9)))(webpack@5.98.0(esbuild@0.25.0)) '@angular-devkit/core': 19.2.0(chokidar@4.0.3) - '@angular/build': 19.2.0(@angular/compiler-cli@19.2.0(@angular/compiler@19.2.0(@angular/core@19.2.0(rxjs@7.8.1)(zone.js@0.15.1)))(typescript@5.8.3))(@angular/compiler@19.2.0(@angular/core@19.2.0(rxjs@7.8.1)(zone.js@0.15.1)))(@angular/platform-server@19.2.0(@angular/common@19.2.0(@angular/core@19.2.0(rxjs@7.8.1)(zone.js@0.15.1))(rxjs@7.8.1))(@angular/compiler@19.2.0(@angular/core@19.2.0(rxjs@7.8.1)(zone.js@0.15.1)))(@angular/core@19.2.0(rxjs@7.8.1)(zone.js@0.15.1))(@angular/platform-browser@19.2.0(@angular/animations@19.2.0(@angular/core@19.2.0(rxjs@7.8.1)(zone.js@0.15.1)))(@angular/common@19.2.0(@angular/core@19.2.0(rxjs@7.8.1)(zone.js@0.15.1))(rxjs@7.8.1))(@angular/core@19.2.0(rxjs@7.8.1)(zone.js@0.15.1))))(@angular/ssr@19.2.15(9944558d2409a9f62c85c46d55b3507e))(@types/node@22.10.5)(chokidar@4.0.3)(jiti@2.5.1)(karma@6.4.4)(less@4.2.2)(postcss@8.5.2)(tailwindcss@3.4.9(ts-node@10.9.2(@types/node@22.10.5)(typescript@5.8.3)))(terser@5.39.0)(typescript@5.8.3)(yaml@2.8.0) - '@angular/compiler-cli': 19.2.0(@angular/compiler@19.2.0(@angular/core@19.2.0(rxjs@7.8.1)(zone.js@0.15.1)))(typescript@5.8.3) + '@angular/build': 19.2.0(@angular/compiler-cli@19.2.0(@angular/compiler@19.2.0(@angular/core@19.2.0(rxjs@7.8.2)(zone.js@0.15.1)))(typescript@5.8.3))(@angular/compiler@19.2.0(@angular/core@19.2.0(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/platform-server@19.2.0(@angular/common@19.2.0(@angular/core@19.2.0(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/compiler@19.2.0(@angular/core@19.2.0(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/core@19.2.0(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.0(@angular/animations@19.2.0(@angular/core@19.2.0(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.0(@angular/core@19.2.0(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.0(rxjs@7.8.2)(zone.js@0.15.1))))(@angular/ssr@19.2.15(5c03da8199d2fcdf9ff93b70f9349edd))(@types/node@22.10.5)(chokidar@4.0.3)(jiti@2.5.1)(karma@6.4.4)(less@4.2.2)(postcss@8.5.2)(tailwindcss@3.4.9(ts-node@10.9.2(@types/node@22.10.5)(typescript@5.8.3)))(terser@5.39.0)(typescript@5.8.3)(yaml@2.8.0) + '@angular/compiler-cli': 19.2.0(@angular/compiler@19.2.0(@angular/core@19.2.0(rxjs@7.8.2)(zone.js@0.15.1)))(typescript@5.8.3) '@babel/core': 7.26.9 '@babel/generator': 7.26.9 '@babel/helper-annotate-as-pure': 7.25.9 @@ -13753,8 +13761,8 @@ snapshots: '@babel/preset-env': 7.26.9(@babel/core@7.26.9) '@babel/runtime': 7.26.9 '@discoveryjs/json-ext': 0.6.3 - '@ngtools/webpack': 19.2.0(@angular/compiler-cli@19.2.0(@angular/compiler@19.2.0(@angular/core@19.2.0(rxjs@7.8.1)(zone.js@0.15.1)))(typescript@5.8.3))(typescript@5.8.3)(webpack@5.98.0(esbuild@0.25.0)) - '@vitejs/plugin-basic-ssl': 1.2.0(vite@7.1.2(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0)) + '@ngtools/webpack': 19.2.0(@angular/compiler-cli@19.2.0(@angular/compiler@19.2.0(@angular/core@19.2.0(rxjs@7.8.2)(zone.js@0.15.1)))(typescript@5.8.3))(typescript@5.8.3)(webpack@5.98.0(esbuild@0.25.0)) + '@vitejs/plugin-basic-ssl': 1.2.0(vite@6.3.5(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.0)) ansi-colors: 4.1.3 autoprefixer: 10.4.20(postcss@8.5.2) babel-loader: 9.2.1(@babel/core@7.26.9)(webpack@5.98.0(esbuild@0.25.0)) @@ -13791,12 +13799,12 @@ snapshots: typescript: 5.8.3 webpack: 5.98.0(esbuild@0.25.9) webpack-dev-middleware: 7.4.2(webpack@5.98.0(esbuild@0.25.9)) - webpack-dev-server: 5.2.0(webpack@5.98.0(esbuild@0.25.0)) + webpack-dev-server: 5.2.0(webpack@5.98.0(esbuild@0.25.9)) webpack-merge: 6.0.1 webpack-subresource-integrity: 5.1.0(webpack@5.98.0(esbuild@0.25.9)) optionalDependencies: - '@angular/platform-server': 19.2.0(@angular/common@19.2.0(@angular/core@19.2.0(rxjs@7.8.1)(zone.js@0.15.1))(rxjs@7.8.1))(@angular/compiler@19.2.0(@angular/core@19.2.0(rxjs@7.8.1)(zone.js@0.15.1)))(@angular/core@19.2.0(rxjs@7.8.1)(zone.js@0.15.1))(@angular/platform-browser@19.2.0(@angular/animations@19.2.0(@angular/core@19.2.0(rxjs@7.8.1)(zone.js@0.15.1)))(@angular/common@19.2.0(@angular/core@19.2.0(rxjs@7.8.1)(zone.js@0.15.1))(rxjs@7.8.1))(@angular/core@19.2.0(rxjs@7.8.1)(zone.js@0.15.1))) - '@angular/ssr': 19.2.15(9944558d2409a9f62c85c46d55b3507e) + '@angular/platform-server': 19.2.0(@angular/common@19.2.0(@angular/core@19.2.0(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/compiler@19.2.0(@angular/core@19.2.0(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/core@19.2.0(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.0(@angular/animations@19.2.0(@angular/core@19.2.0(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.0(@angular/core@19.2.0(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.0(rxjs@7.8.2)(zone.js@0.15.1))) + '@angular/ssr': 19.2.15(5c03da8199d2fcdf9ff93b70f9349edd) esbuild: 0.25.0 karma: 6.4.4 tailwindcss: 3.4.9(ts-node@10.9.2(@types/node@22.10.5)(typescript@5.8.3)) @@ -13823,11 +13831,11 @@ snapshots: - webpack-cli - yaml - '@angular-devkit/build-angular@19.2.0(b57b04a4dfd0d7238fcb437f41884422)': + '@angular-devkit/build-angular@19.2.0(c051f58b50ee906cd14109939270cbce)': dependencies: '@ampproject/remapping': 2.3.0 '@angular-devkit/architect': 0.1902.0(chokidar@4.0.3) - '@angular-devkit/build-webpack': 0.1902.0(chokidar@4.0.3)(webpack-dev-server@5.2.0(webpack@5.98.0(esbuild@0.25.0)))(webpack@5.98.0(esbuild@0.25.0)) + '@angular-devkit/build-webpack': 0.1902.0(chokidar@4.0.3)(webpack-dev-server@5.2.0(webpack@5.98.0(esbuild@0.25.9)))(webpack@5.98.0(esbuild@0.25.0)) '@angular-devkit/core': 19.2.0(chokidar@4.0.3) '@angular/build': 19.2.0(@angular/compiler-cli@19.2.0(@angular/compiler@19.2.0(@angular/core@19.2.0(rxjs@7.8.2)(zone.js@0.15.1)))(typescript@5.8.3))(@angular/compiler@19.2.0(@angular/core@19.2.0(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/platform-server@19.2.0(@angular/common@19.2.0(@angular/core@19.2.0(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/compiler@19.2.0(@angular/core@19.2.0(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/core@19.2.0(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.0(@angular/animations@19.2.0(@angular/core@19.2.0(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.0(@angular/core@19.2.0(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.0(rxjs@7.8.2)(zone.js@0.15.1))))(@angular/ssr@19.2.15(5c03da8199d2fcdf9ff93b70f9349edd))(@types/node@22.10.5)(chokidar@4.0.3)(jiti@2.5.1)(karma@6.4.4)(less@4.2.2)(postcss@8.5.2)(tailwindcss@3.4.9(ts-node@10.9.2(@types/node@22.10.5)(typescript@5.8.3)))(terser@5.39.0)(typescript@5.8.3)(yaml@2.8.0) '@angular/compiler-cli': 19.2.0(@angular/compiler@19.2.0(@angular/core@19.2.0(rxjs@7.8.2)(zone.js@0.15.1)))(typescript@5.8.3) @@ -13842,7 +13850,7 @@ snapshots: '@babel/runtime': 7.26.9 '@discoveryjs/json-ext': 0.6.3 '@ngtools/webpack': 19.2.0(@angular/compiler-cli@19.2.0(@angular/compiler@19.2.0(@angular/core@19.2.0(rxjs@7.8.2)(zone.js@0.15.1)))(typescript@5.8.3))(typescript@5.8.3)(webpack@5.98.0(esbuild@0.25.0)) - '@vitejs/plugin-basic-ssl': 1.2.0(vite@7.1.2(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0)) + '@vitejs/plugin-basic-ssl': 1.2.0(vite@6.3.5(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0)) ansi-colors: 4.1.3 autoprefixer: 10.4.20(postcss@8.5.2) babel-loader: 9.2.1(@babel/core@7.26.9)(webpack@5.98.0(esbuild@0.25.0)) @@ -13879,7 +13887,7 @@ snapshots: typescript: 5.8.3 webpack: 5.98.0(esbuild@0.25.9) webpack-dev-middleware: 7.4.2(webpack@5.98.0(esbuild@0.25.9)) - webpack-dev-server: 5.2.0(webpack@5.98.0(esbuild@0.25.0)) + webpack-dev-server: 5.2.0(webpack@5.98.0(esbuild@0.25.9)) webpack-merge: 6.0.1 webpack-subresource-integrity: 5.1.0(webpack@5.98.0(esbuild@0.25.9)) optionalDependencies: @@ -13911,7 +13919,7 @@ snapshots: - webpack-cli - yaml - '@angular-devkit/build-angular@19.2.15(@angular/compiler-cli@19.2.14(@angular/compiler@19.2.14)(typescript@5.8.3))(@angular/compiler@19.2.14)(@angular/platform-server@19.2.0(@angular/common@19.2.14(@angular/core@19.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/compiler@19.2.14)(@angular/core@19.2.14(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.14(@angular/animations@19.2.14(@angular/common@19.2.14(@angular/core@19.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.14(@angular/core@19.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.14(rxjs@7.8.2)(zone.js@0.15.1))))(@angular/ssr@19.2.15(fc183c600d5538ac11e1814ee07b5dfc))(@types/node@22.10.5)(chokidar@4.0.3)(jiti@2.5.1)(karma@6.4.4)(tailwindcss@3.4.9(ts-node@10.9.2(@types/node@22.10.5)(typescript@5.8.3)))(typescript@5.8.3)(vite@7.1.2(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.0))(yaml@2.8.0)': + '@angular-devkit/build-angular@19.2.15(@angular/compiler-cli@19.2.14(@angular/compiler@19.2.14)(typescript@5.8.3))(@angular/compiler@19.2.14)(@angular/platform-server@19.2.0(@angular/common@19.2.14(@angular/core@19.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/compiler@19.2.14)(@angular/core@19.2.14(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@19.2.14(@angular/animations@19.2.14(@angular/common@19.2.14(@angular/core@19.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.14(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@19.2.14(@angular/core@19.2.14(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@19.2.14(rxjs@7.8.2)(zone.js@0.15.1))))(@angular/ssr@19.2.15(fc183c600d5538ac11e1814ee07b5dfc))(@types/node@22.10.5)(chokidar@4.0.3)(jiti@2.5.1)(karma@6.4.4)(tailwindcss@3.4.9(ts-node@10.9.2(@types/node@22.10.5)(typescript@5.8.3)))(typescript@5.8.3)(vite@6.3.5(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.0))(yaml@2.8.0)': dependencies: '@ampproject/remapping': 2.3.0 '@angular-devkit/architect': 0.1902.15(chokidar@4.0.3) @@ -13930,7 +13938,7 @@ snapshots: '@babel/runtime': 7.26.10 '@discoveryjs/json-ext': 0.6.3 '@ngtools/webpack': 19.2.15(@angular/compiler-cli@19.2.14(@angular/compiler@19.2.14)(typescript@5.8.3))(typescript@5.8.3)(webpack@5.98.0(esbuild@0.25.9)) - '@vitejs/plugin-basic-ssl': 1.2.0(vite@7.1.2(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.0)) + '@vitejs/plugin-basic-ssl': 1.2.0(vite@6.3.5(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.0)) ansi-colors: 4.1.3 autoprefixer: 10.4.20(postcss@8.5.2) babel-loader: 9.2.1(@babel/core@7.26.10)(webpack@5.98.0(esbuild@0.25.9)) @@ -13999,12 +14007,12 @@ snapshots: - webpack-cli - yaml - '@angular-devkit/build-webpack@0.1902.0(chokidar@4.0.3)(webpack-dev-server@5.2.0(webpack@5.98.0(esbuild@0.25.0)))(webpack@5.98.0(esbuild@0.25.0))': + '@angular-devkit/build-webpack@0.1902.0(chokidar@4.0.3)(webpack-dev-server@5.2.0(webpack@5.98.0(esbuild@0.25.9)))(webpack@5.98.0(esbuild@0.25.0))': dependencies: '@angular-devkit/architect': 0.1902.0(chokidar@4.0.3) rxjs: 7.8.1 webpack: 5.98.0(esbuild@0.25.9) - webpack-dev-server: 5.2.0(webpack@5.98.0(esbuild@0.25.0)) + webpack-dev-server: 5.2.0(webpack@5.98.0(esbuild@0.25.9)) transitivePeerDependencies: - chokidar @@ -16800,7 +16808,24 @@ snapshots: '@fontsource/fira-mono@5.0.0': {} - '@hey-api/json-schema-ref-parser@1.1.0': + '@hey-api/c12@1.0.3(magicast@0.3.5)': + dependencies: + chokidar: 4.0.3 + confbox: 0.2.2 + defu: 6.1.4 + dotenv: 17.2.1 + exsolve: 1.0.7 + giget: 2.0.0 + jiti: 2.5.1 + ohash: 2.0.11 + pathe: 2.0.3 + perfect-debounce: 1.0.0 + pkg-types: 2.3.0 + rc9: 2.1.2 + optionalDependencies: + magicast: 0.3.5 + + '@hey-api/json-schema-ref-parser@1.2.0': dependencies: '@jsdevtools/ono': 7.1.3 '@types/json-schema': 7.0.15 @@ -17500,6 +17525,26 @@ snapshots: '@nuxt/devalue@2.0.2': {} + '@nuxt/devtools-kit@1.7.0(magicast@0.3.5)(vite@5.4.19(@types/node@22.10.5)(less@4.2.2)(sass@1.85.0)(terser@5.43.1))': + dependencies: + '@nuxt/kit': 3.15.4(magicast@0.3.5) + '@nuxt/schema': 3.16.2 + execa: 7.2.0 + vite: 5.4.19(@types/node@22.10.5)(less@4.2.2)(sass@1.85.0)(terser@5.43.1) + transitivePeerDependencies: + - magicast + - supports-color + + '@nuxt/devtools-kit@1.7.0(magicast@0.3.5)(vite@6.3.5(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0))': + dependencies: + '@nuxt/kit': 3.15.4(magicast@0.3.5) + '@nuxt/schema': 3.16.2 + execa: 7.2.0 + vite: 6.3.5(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0) + transitivePeerDependencies: + - magicast + - supports-color + '@nuxt/devtools-kit@1.7.0(magicast@0.3.5)(vite@7.1.2(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0))': dependencies: '@nuxt/kit': 3.15.4(magicast@0.3.5) @@ -17570,13 +17615,13 @@ snapshots: - utf-8-validate - vue - '@nuxt/devtools@1.7.0(rollup@4.50.0)(vite@7.1.2(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0))(vue@3.5.13(typescript@5.8.3))': + '@nuxt/devtools@1.7.0(rollup@4.50.0)(vite@5.4.19(@types/node@22.10.5)(less@4.2.2)(sass@1.85.0)(terser@5.43.1))(vue@3.5.13(typescript@5.8.3))': dependencies: '@antfu/utils': 0.7.10 - '@nuxt/devtools-kit': 1.7.0(magicast@0.3.5)(vite@7.1.2(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0)) + '@nuxt/devtools-kit': 1.7.0(magicast@0.3.5)(vite@5.4.19(@types/node@22.10.5)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)) '@nuxt/devtools-wizard': 1.7.0 '@nuxt/kit': 3.15.4(magicast@0.3.5) - '@vue/devtools-core': 7.6.8(vite@7.1.2(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0))(vue@3.5.13(typescript@5.8.3)) + '@vue/devtools-core': 7.6.8(vite@5.4.19(@types/node@22.10.5)(less@4.2.2)(sass@1.85.0)(terser@5.43.1))(vue@3.5.13(typescript@5.8.3)) '@vue/devtools-kit': 7.6.8 birpc: 0.2.19 consola: 3.4.2 @@ -17605,9 +17650,56 @@ snapshots: sirv: 3.0.1 tinyglobby: 0.2.10 unimport: 3.14.6(rollup@4.50.0) - vite: 7.1.2(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0) - vite-plugin-inspect: 0.8.9(@nuxt/kit@3.15.4(magicast@0.3.5))(rollup@4.50.0)(vite@7.1.2(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0)) - vite-plugin-vue-inspector: 5.3.2(vite@7.1.2(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0)) + vite: 5.4.19(@types/node@22.10.5)(less@4.2.2)(sass@1.85.0)(terser@5.43.1) + vite-plugin-inspect: 0.8.9(@nuxt/kit@3.15.4(magicast@0.3.5))(rollup@4.50.0)(vite@5.4.19(@types/node@22.10.5)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)) + vite-plugin-vue-inspector: 5.3.2(vite@5.4.19(@types/node@22.10.5)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)) + which: 3.0.1 + ws: 8.18.3 + transitivePeerDependencies: + - bufferutil + - rollup + - supports-color + - utf-8-validate + - vue + + '@nuxt/devtools@1.7.0(rollup@4.50.0)(vite@6.3.5(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0))(vue@3.5.13(typescript@5.8.3))': + dependencies: + '@antfu/utils': 0.7.10 + '@nuxt/devtools-kit': 1.7.0(magicast@0.3.5)(vite@6.3.5(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0)) + '@nuxt/devtools-wizard': 1.7.0 + '@nuxt/kit': 3.15.4(magicast@0.3.5) + '@vue/devtools-core': 7.6.8(vite@6.3.5(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0))(vue@3.5.13(typescript@5.8.3)) + '@vue/devtools-kit': 7.6.8 + birpc: 0.2.19 + consola: 3.4.2 + cronstrue: 2.59.0 + destr: 2.0.5 + error-stack-parser-es: 0.1.5 + execa: 7.2.0 + fast-npm-meta: 0.2.2 + flatted: 3.3.3 + get-port-please: 3.2.0 + hookable: 5.5.3 + image-meta: 0.2.1 + is-installed-globally: 1.0.0 + launch-editor: 2.11.1 + local-pkg: 0.5.1 + magicast: 0.3.5 + nypm: 0.4.1 + ohash: 1.1.6 + pathe: 1.1.2 + perfect-debounce: 1.0.0 + pkg-types: 1.3.1 + rc9: 2.1.2 + scule: 1.3.0 + semver: 7.7.2 + simple-git: 3.28.0 + sirv: 3.0.1 + tinyglobby: 0.2.10 + unimport: 3.14.6(rollup@4.50.0) + vite: 6.3.5(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0) + vite-plugin-inspect: 0.8.9(@nuxt/kit@3.15.4(magicast@0.3.5))(rollup@4.50.0)(vite@6.3.5(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0)) + vite-plugin-vue-inspector: 5.3.2(vite@6.3.5(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0)) which: 3.0.1 ws: 8.18.3 transitivePeerDependencies: @@ -19916,13 +20008,13 @@ snapshots: dependencies: vite: 6.2.7(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.0) - '@vitejs/plugin-basic-ssl@1.2.0(vite@7.1.2(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.0))': + '@vitejs/plugin-basic-ssl@1.2.0(vite@6.3.5(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.0))': dependencies: - vite: 7.1.2(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.0) + vite: 6.3.5(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.0) - '@vitejs/plugin-basic-ssl@1.2.0(vite@7.1.2(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0))': + '@vitejs/plugin-basic-ssl@1.2.0(vite@6.3.5(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0))': dependencies: - vite: 7.1.2(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0) + vite: 6.3.5(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0) '@vitejs/plugin-react@4.4.0-beta.1(vite@7.1.2(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0))': dependencies: @@ -20220,6 +20312,30 @@ snapshots: dependencies: '@vue/devtools-kit': 8.0.1 + '@vue/devtools-core@7.6.8(vite@5.4.19(@types/node@22.10.5)(less@4.2.2)(sass@1.85.0)(terser@5.43.1))(vue@3.5.13(typescript@5.8.3))': + dependencies: + '@vue/devtools-kit': 7.6.8 + '@vue/devtools-shared': 7.7.7 + mitt: 3.0.1 + nanoid: 5.1.5 + pathe: 1.1.2 + vite-hot-client: 0.2.4(vite@5.4.19(@types/node@22.10.5)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)) + vue: 3.5.13(typescript@5.8.3) + transitivePeerDependencies: + - vite + + '@vue/devtools-core@7.6.8(vite@6.3.5(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0))(vue@3.5.13(typescript@5.8.3))': + dependencies: + '@vue/devtools-kit': 7.6.8 + '@vue/devtools-shared': 7.7.7 + mitt: 3.0.1 + nanoid: 5.1.5 + pathe: 1.1.2 + vite-hot-client: 0.2.4(vite@6.3.5(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0)) + vue: 3.5.13(typescript@5.8.3) + transitivePeerDependencies: + - vite + '@vue/devtools-core@7.6.8(vite@7.1.2(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0))(vue@3.5.13(typescript@5.8.3))': dependencies: '@vue/devtools-kit': 7.6.8 @@ -22245,7 +22361,7 @@ snapshots: '@typescript-eslint/parser': 8.29.1(eslint@9.17.0(jiti@2.5.1))(typescript@5.8.3) eslint: 9.17.0(jiti@2.5.1) eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.29.1(eslint@9.17.0(jiti@2.5.1))(typescript@5.8.3))(eslint@9.17.0(jiti@2.5.1)))(eslint@9.17.0(jiti@2.5.1)) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.17.0(jiti@2.5.1)) eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.29.1(eslint@9.17.0(jiti@2.5.1))(typescript@5.8.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.17.0(jiti@2.5.1)) eslint-plugin-jsx-a11y: 6.10.2(eslint@9.17.0(jiti@2.5.1)) eslint-plugin-react: 7.37.5(eslint@9.17.0(jiti@2.5.1)) @@ -22269,7 +22385,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.29.1(eslint@9.17.0(jiti@2.5.1))(typescript@5.8.3))(eslint@9.17.0(jiti@2.5.1)))(eslint@9.17.0(jiti@2.5.1)): + eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@9.17.0(jiti@2.5.1)): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.4.1 @@ -22284,14 +22400,14 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@8.29.1(eslint@9.17.0(jiti@2.5.1))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.29.1(eslint@9.17.0(jiti@2.5.1))(typescript@5.8.3))(eslint@9.17.0(jiti@2.5.1)))(eslint@9.17.0(jiti@2.5.1)))(eslint@9.17.0(jiti@2.5.1)): + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.29.1(eslint@9.17.0(jiti@2.5.1))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.17.0(jiti@2.5.1)): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 8.29.1(eslint@9.17.0(jiti@2.5.1))(typescript@5.8.3) eslint: 9.17.0(jiti@2.5.1) eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.29.1(eslint@9.17.0(jiti@2.5.1))(typescript@5.8.3))(eslint@9.17.0(jiti@2.5.1)))(eslint@9.17.0(jiti@2.5.1)) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.17.0(jiti@2.5.1)) transitivePeerDependencies: - supports-color @@ -22306,7 +22422,7 @@ snapshots: doctrine: 2.1.0 eslint: 9.17.0(jiti@2.5.1) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.29.1(eslint@9.17.0(jiti@2.5.1))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.29.1(eslint@9.17.0(jiti@2.5.1))(typescript@5.8.3))(eslint@9.17.0(jiti@2.5.1)))(eslint@9.17.0(jiti@2.5.1)))(eslint@9.17.0(jiti@2.5.1)) + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.29.1(eslint@9.17.0(jiti@2.5.1))(typescript@5.8.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.1)(eslint@9.17.0(jiti@2.5.1)) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -25178,10 +25294,131 @@ snapshots: - vue-tsc - xml2js - nuxt@3.14.1592(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.1)(@types/node@22.10.5)(db0@0.3.2)(encoding@0.1.13)(eslint@9.17.0(jiti@2.5.1))(ioredis@5.7.0)(less@4.2.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.50.0)(sass@1.85.0)(terser@5.43.1)(typescript@5.8.3)(vite@7.1.2(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0)): + nuxt@3.14.1592(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.1)(@types/node@22.10.5)(db0@0.3.2)(encoding@0.1.13)(eslint@9.17.0(jiti@2.5.1))(ioredis@5.7.0)(less@4.2.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.50.0)(sass@1.85.0)(terser@5.43.1)(typescript@5.8.3)(vite@5.4.19(@types/node@22.10.5)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)): + dependencies: + '@nuxt/devalue': 2.0.2 + '@nuxt/devtools': 1.7.0(rollup@4.50.0)(vite@5.4.19(@types/node@22.10.5)(less@4.2.2)(sass@1.85.0)(terser@5.43.1))(vue@3.5.13(typescript@5.8.3)) + '@nuxt/kit': 3.14.1592(magicast@0.3.5)(rollup@4.50.0) + '@nuxt/schema': 3.14.1592(magicast@0.3.5)(rollup@4.50.0) + '@nuxt/telemetry': 2.6.6(magicast@0.3.5) + '@nuxt/vite-builder': 3.14.1592(@types/node@22.10.5)(eslint@9.17.0(jiti@2.5.1))(less@4.2.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.50.0)(sass@1.85.0)(terser@5.43.1)(typescript@5.8.3)(vue@3.5.13(typescript@5.8.3)) + '@unhead/dom': 1.11.20 + '@unhead/shared': 1.11.20 + '@unhead/ssr': 1.11.20 + '@unhead/vue': 1.11.20(vue@3.5.13(typescript@5.8.3)) + '@vue/shared': 3.5.20 + acorn: 8.14.0 + c12: 2.0.1(magicast@0.3.5) + chokidar: 4.0.3 + compatx: 0.1.8 + consola: 3.4.2 + cookie-es: 1.2.2 + defu: 6.1.4 + destr: 2.0.5 + devalue: 5.3.2 + errx: 0.1.0 + esbuild: 0.24.2 + escape-string-regexp: 5.0.0 + estree-walker: 3.0.3 + globby: 14.1.0 + h3: 1.15.4 + hookable: 5.5.3 + ignore: 6.0.2 + impound: 0.2.2(rollup@4.50.0) + jiti: 2.5.1 + klona: 2.0.6 + knitwork: 1.2.0 + magic-string: 0.30.18 + mlly: 1.7.4 + nanotar: 0.1.1 + nitropack: 2.12.4(@netlify/blobs@9.1.2)(encoding@0.1.13) + nuxi: 3.28.0 + nypm: 0.3.12 + ofetch: 1.4.1 + ohash: 1.1.6 + pathe: 1.1.2 + perfect-debounce: 1.0.0 + pkg-types: 1.3.1 + radix3: 1.1.2 + scule: 1.3.0 + semver: 7.7.2 + std-env: 3.9.0 + strip-literal: 2.1.1 + tinyglobby: 0.2.10 + ufo: 1.6.1 + ultrahtml: 1.6.0 + uncrypto: 0.1.3 + unctx: 2.4.1 + unenv: 1.10.0 + unhead: 1.11.20 + unimport: 3.14.6(rollup@4.50.0) + unplugin: 1.16.1 + unplugin-vue-router: 0.10.9(rollup@4.50.0)(vue-router@4.5.0(vue@3.5.13(typescript@5.8.3)))(vue@3.5.13(typescript@5.8.3)) + unstorage: 1.17.0(@netlify/blobs@9.1.2)(db0@0.3.2)(ioredis@5.7.0) + untyped: 1.5.2 + vue: 3.5.13(typescript@5.8.3) + vue-bundle-renderer: 2.1.2 + vue-devtools-stub: 0.1.0 + vue-router: 4.5.0(vue@3.5.13(typescript@5.8.3)) + optionalDependencies: + '@parcel/watcher': 2.5.1 + '@types/node': 22.10.5 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@biomejs/biome' + - '@capacitor/preferences' + - '@deno/kv' + - '@electric-sql/pglite' + - '@libsql/client' + - '@netlify/blobs' + - '@planetscale/database' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - better-sqlite3 + - bufferutil + - db0 + - drizzle-orm + - encoding + - eslint + - idb-keyval + - ioredis + - less + - lightningcss + - magicast + - meow + - mysql2 + - optionator + - rolldown + - rollup + - sass + - sass-embedded + - sqlite3 + - stylelint + - stylus + - sugarss + - supports-color + - terser + - typescript + - uploadthing + - utf-8-validate + - vite + - vls + - vti + - vue-tsc + - xml2js + + nuxt@3.14.1592(@netlify/blobs@9.1.2)(@parcel/watcher@2.5.1)(@types/node@22.10.5)(db0@0.3.2)(encoding@0.1.13)(eslint@9.17.0(jiti@2.5.1))(ioredis@5.7.0)(less@4.2.2)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.50.0)(sass@1.85.0)(terser@5.43.1)(typescript@5.8.3)(vite@6.3.5(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0)): dependencies: '@nuxt/devalue': 2.0.2 - '@nuxt/devtools': 1.7.0(rollup@4.50.0)(vite@7.1.2(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0))(vue@3.5.13(typescript@5.8.3)) + '@nuxt/devtools': 1.7.0(rollup@4.50.0)(vite@6.3.5(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0))(vue@3.5.13(typescript@5.8.3)) '@nuxt/kit': 3.14.1592(magicast@0.3.5)(rollup@4.50.0) '@nuxt/schema': 3.14.1592(magicast@0.3.5)(rollup@4.50.0) '@nuxt/telemetry': 2.6.6(magicast@0.3.5) @@ -27467,7 +27704,7 @@ snapshots: term-size@2.2.1: {} - terser-webpack-plugin@5.3.14(esbuild@0.25.4)(webpack@5.98.0(esbuild@0.25.9)): + terser-webpack-plugin@5.3.14(esbuild@0.25.0)(webpack@5.98.0(esbuild@0.25.9)): dependencies: '@jridgewell/trace-mapping': 0.3.30 jest-worker: 27.5.1 @@ -27476,9 +27713,9 @@ snapshots: terser: 5.39.0 webpack: 5.98.0(esbuild@0.25.9) optionalDependencies: - esbuild: 0.25.4 + esbuild: 0.25.0 - terser-webpack-plugin@5.3.14(esbuild@0.25.9)(webpack@5.98.0(esbuild@0.25.0)): + terser-webpack-plugin@5.3.14(esbuild@0.25.4)(webpack@5.98.0(esbuild@0.25.9)): dependencies: '@jridgewell/trace-mapping': 0.3.30 jest-worker: 27.5.1 @@ -27487,7 +27724,7 @@ snapshots: terser: 5.39.0 webpack: 5.98.0(esbuild@0.25.9) optionalDependencies: - esbuild: 0.25.9 + esbuild: 0.25.4 terser@5.39.0: dependencies: @@ -28261,6 +28498,14 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.3 + vite-hot-client@0.2.4(vite@5.4.19(@types/node@22.10.5)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)): + dependencies: + vite: 5.4.19(@types/node@22.10.5)(less@4.2.2)(sass@1.85.0)(terser@5.43.1) + + vite-hot-client@0.2.4(vite@6.3.5(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0)): + dependencies: + vite: 6.3.5(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0) + vite-hot-client@0.2.4(vite@7.1.2(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0)): dependencies: vite: 7.1.2(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0) @@ -28391,6 +28636,42 @@ snapshots: - rollup - supports-color + vite-plugin-inspect@0.8.9(@nuxt/kit@3.15.4(magicast@0.3.5))(rollup@4.50.0)(vite@5.4.19(@types/node@22.10.5)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)): + dependencies: + '@antfu/utils': 0.7.10 + '@rollup/pluginutils': 5.2.0(rollup@4.50.0) + debug: 4.4.1 + error-stack-parser-es: 0.1.5 + fs-extra: 11.3.1 + open: 10.1.2 + perfect-debounce: 1.0.0 + picocolors: 1.1.1 + sirv: 3.0.1 + vite: 5.4.19(@types/node@22.10.5)(less@4.2.2)(sass@1.85.0)(terser@5.43.1) + optionalDependencies: + '@nuxt/kit': 3.15.4(magicast@0.3.5) + transitivePeerDependencies: + - rollup + - supports-color + + vite-plugin-inspect@0.8.9(@nuxt/kit@3.15.4(magicast@0.3.5))(rollup@4.50.0)(vite@6.3.5(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0)): + dependencies: + '@antfu/utils': 0.7.10 + '@rollup/pluginutils': 5.2.0(rollup@4.50.0) + debug: 4.4.1 + error-stack-parser-es: 0.1.5 + fs-extra: 11.3.1 + open: 10.1.2 + perfect-debounce: 1.0.0 + picocolors: 1.1.1 + sirv: 3.0.1 + vite: 6.3.5(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0) + optionalDependencies: + '@nuxt/kit': 3.15.4(magicast@0.3.5) + transitivePeerDependencies: + - rollup + - supports-color + vite-plugin-inspect@0.8.9(@nuxt/kit@3.15.4(magicast@0.3.5))(rollup@4.50.0)(vite@7.1.2(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0)): dependencies: '@antfu/utils': 0.7.10 @@ -28425,6 +28706,36 @@ snapshots: - supports-color - vue + vite-plugin-vue-inspector@5.3.2(vite@5.4.19(@types/node@22.10.5)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)): + dependencies: + '@babel/core': 7.28.3 + '@babel/plugin-proposal-decorators': 7.28.0(@babel/core@7.28.3) + '@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.28.3) + '@babel/plugin-transform-typescript': 7.28.0(@babel/core@7.28.3) + '@vue/babel-plugin-jsx': 1.5.0(@babel/core@7.28.3) + '@vue/compiler-dom': 3.5.20 + kolorist: 1.8.0 + magic-string: 0.30.18 + vite: 5.4.19(@types/node@22.10.5)(less@4.2.2)(sass@1.85.0)(terser@5.43.1) + transitivePeerDependencies: + - supports-color + + vite-plugin-vue-inspector@5.3.2(vite@6.3.5(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0)): + dependencies: + '@babel/core': 7.28.3 + '@babel/plugin-proposal-decorators': 7.28.0(@babel/core@7.28.3) + '@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.28.3) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.28.3) + '@babel/plugin-transform-typescript': 7.28.0(@babel/core@7.28.3) + '@vue/babel-plugin-jsx': 1.5.0(@babel/core@7.28.3) + '@vue/compiler-dom': 3.5.20 + kolorist: 1.8.0 + magic-string: 0.30.18 + vite: 6.3.5(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0) + transitivePeerDependencies: + - supports-color + vite-plugin-vue-inspector@5.3.2(vite@7.1.2(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0)): dependencies: '@babel/core': 7.28.3 @@ -28480,7 +28791,7 @@ snapshots: terser: 5.39.0 yaml: 2.8.0 - vite@6.3.5(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0): + vite@6.3.5(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.0): dependencies: esbuild: 0.25.9 fdir: 6.5.0(picomatch@4.0.3) @@ -28494,10 +28805,10 @@ snapshots: jiti: 2.5.1 less: 4.2.2 sass: 1.85.0 - terser: 5.43.1 + terser: 5.39.0 yaml: 2.8.0 - vite@7.1.2(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.39.0)(yaml@2.8.0): + vite@6.3.5(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0): dependencies: esbuild: 0.25.9 fdir: 6.5.0(picomatch@4.0.3) @@ -28511,7 +28822,7 @@ snapshots: jiti: 2.5.1 less: 4.2.2 sass: 1.85.0 - terser: 5.39.0 + terser: 5.43.1 yaml: 2.8.0 vite@7.1.2(@types/node@22.10.5)(jiti@2.5.1)(less@4.2.2)(sass@1.85.0)(terser@5.43.1)(yaml@2.8.0): @@ -28858,7 +29169,7 @@ snapshots: optionalDependencies: webpack: 5.98.0(esbuild@0.25.9) - webpack-dev-server@5.2.0(webpack@5.98.0(esbuild@0.25.0)): + webpack-dev-server@5.2.0(webpack@5.98.0(esbuild@0.25.9)): dependencies: '@types/bonjour': 3.5.13 '@types/connect-history-api-fallback': 1.5.4 @@ -29000,7 +29311,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 4.3.2 tapable: 2.2.3 - terser-webpack-plugin: 5.3.14(esbuild@0.25.9)(webpack@5.98.0(esbuild@0.25.0)) + terser-webpack-plugin: 5.3.14(esbuild@0.25.0)(webpack@5.98.0(esbuild@0.25.9)) watchpack: 2.4.4 webpack-sources: 3.3.3 transitivePeerDependencies: