From 0feb69abd555f3620803b132374b42538b66bdb7 Mon Sep 17 00:00:00 2001 From: Lubos Date: Wed, 22 Jan 2025 12:41:53 +0000 Subject: [PATCH 1/2] feat: add msw plugin --- packages/openapi-ts/package.json | 1 + packages/openapi-ts/src/compiler/index.ts | 3 + packages/openapi-ts/src/compiler/types.ts | 84 +- packages/openapi-ts/src/index.ts | 22 +- .../src/plugins/@hey-api/schemas/types.d.ts | 2 + .../src/plugins/@hey-api/sdk/types.d.ts | 4 +- .../plugins/@hey-api/transformers/plugin.ts | 5 +- .../src/plugins/@hey-api/typescript/ref.ts | 12 +- .../angular-query-experimental/types.d.ts | 4 + .../plugins/@tanstack/react-query/types.d.ts | 4 + .../plugins/@tanstack/solid-query/types.d.ts | 4 + .../plugins/@tanstack/svelte-query/types.d.ts | 4 + .../plugins/@tanstack/vue-query/types.d.ts | 4 + .../openapi-ts/src/plugins/fastify/plugin.ts | 19 +- .../openapi-ts/src/plugins/fastify/types.d.ts | 1 + packages/openapi-ts/src/plugins/index.ts | 4 + packages/openapi-ts/src/plugins/msw/config.ts | 18 + packages/openapi-ts/src/plugins/msw/index.ts | 2 + .../openapi-ts/src/plugins/msw/interfaces.ts | 126 +++ packages/openapi-ts/src/plugins/msw/plugin.ts | 182 ++++ .../openapi-ts/src/plugins/msw/types.d.ts | 10 + packages/openapi-ts/src/plugins/types.d.ts | 1 + .../openapi-ts/src/plugins/zod/types.d.ts | 1 + packages/openapi-ts/src/types/config.ts | 18 +- packages/openapi-ts/test/openapi-ts.config.ts | 6 +- .../test/spec/3.1.x/body-nested-array.yaml | 25 - pnpm-lock.yaml | 922 +++--------------- 27 files changed, 630 insertions(+), 858 deletions(-) create mode 100644 packages/openapi-ts/src/plugins/msw/config.ts create mode 100644 packages/openapi-ts/src/plugins/msw/index.ts create mode 100644 packages/openapi-ts/src/plugins/msw/interfaces.ts create mode 100644 packages/openapi-ts/src/plugins/msw/plugin.ts create mode 100644 packages/openapi-ts/src/plugins/msw/types.d.ts delete mode 100644 packages/openapi-ts/test/spec/3.1.x/body-nested-array.yaml diff --git a/packages/openapi-ts/package.json b/packages/openapi-ts/package.json index 6673a7c18..55a521af4 100644 --- a/packages/openapi-ts/package.json +++ b/packages/openapi-ts/package.json @@ -112,6 +112,7 @@ "express": "4.21.0", "fastify": "5.2.0", "glob": "10.4.3", + "msw": "2.7.0", "node-fetch": "3.3.2", "nuxt": "3.15.1", "prettier": "3.4.2", diff --git a/packages/openapi-ts/src/compiler/index.ts b/packages/openapi-ts/src/compiler/index.ts index 56a85cdb9..486533916 100644 --- a/packages/openapi-ts/src/compiler/index.ts +++ b/packages/openapi-ts/src/compiler/index.ts @@ -38,6 +38,7 @@ export const compiler = { isTsNode: utils.isTsNode, keywordTypeNode: types.createKeywordTypeNode, literalTypeNode: types.createLiteralTypeNode, + mappedTypeNode: types.createMappedTypeNode, methodDeclaration: classes.createMethodDeclaration, namedImportDeclarations: module.createNamedImportDeclarations, namespaceDeclaration: types.createNamespaceDeclaration, @@ -68,6 +69,8 @@ export const compiler = { typeIntersectionNode: typedef.createTypeIntersectionNode, typeNode: types.createTypeNode, typeOfExpression: types.createTypeOfExpression, + typeOperatorNode: types.createTypeOperatorNode, + typeParameterDeclaration: types.createTypeParameterDeclaration, typeParenthesizedNode: types.createTypeParenthesizedNode, typeRecordNode: typedef.createTypeRecordNode, typeReferenceNode: types.createTypeReferenceNode, diff --git a/packages/openapi-ts/src/compiler/types.ts b/packages/openapi-ts/src/compiler/types.ts index cca3b9a20..4334530f6 100644 --- a/packages/openapi-ts/src/compiler/types.ts +++ b/packages/openapi-ts/src/compiler/types.ts @@ -287,24 +287,84 @@ export const createKeywordTypeNode = ({ export const toTypeParameters = (types: FunctionTypeParameter[]) => types.map((type) => - ts.factory.createTypeParameterDeclaration( - undefined, - type.name, + createTypeParameterDeclaration({ // TODO: support other extends values - type.extends + constraint: type.extends ? typeof type.extends === 'string' ? createKeywordTypeNode({ keyword: 'boolean' }) : type.extends : undefined, // TODO: support other default types - type.default !== undefined - ? isTsNode(type.default) - ? (type.default as unknown as ts.TypeNode) - : ts.factory.createLiteralTypeNode( - type.default ? ts.factory.createTrue() : ts.factory.createFalse(), - ) - : undefined, - ), + defaultType: + type.default !== undefined + ? isTsNode(type.default) + ? (type.default as unknown as ts.TypeNode) + : ts.factory.createLiteralTypeNode( + type.default + ? ts.factory.createTrue() + : ts.factory.createFalse(), + ) + : undefined, + name: type.name, + }), + ); + +export const createTypeOperatorNode = ({ + operator, + type, +}: { + operator: 'keyof' | 'readonly' | 'unique'; + type: ts.TypeNode; +}) => { + const operatorKeyword = + operator === 'keyof' + ? ts.SyntaxKind.KeyOfKeyword + : operator === 'readonly' + ? ts.SyntaxKind.ReadonlyKeyword + : ts.SyntaxKind.UniqueKeyword; + return ts.factory.createTypeOperatorNode(operatorKeyword, type); +}; + +export const createTypeParameterDeclaration = ({ + constraint, + defaultType, + modifiers, + name, +}: { + constraint?: ts.TypeNode; + defaultType?: ts.TypeNode; + modifiers?: Array; + name: string | ts.Identifier; +}) => + ts.factory.createTypeParameterDeclaration( + modifiers, + name, + constraint, + defaultType, + ); + +export const createMappedTypeNode = ({ + members, + nameType, + questionToken, + readonlyToken, + type, + typeParameter, +}: { + members?: ts.NodeArray; + nameType?: ts.TypeNode; + questionToken?: ts.QuestionToken | ts.PlusToken | ts.MinusToken; + readonlyToken?: ts.ReadonlyKeyword | ts.PlusToken | ts.MinusToken; + type?: ts.TypeNode; + typeParameter: ts.TypeParameterDeclaration; +}) => + ts.factory.createMappedTypeNode( + readonlyToken, + typeParameter, + nameType, + questionToken, + type, + members, ); export const createLiteralTypeNode = ({ diff --git a/packages/openapi-ts/src/index.ts b/packages/openapi-ts/src/index.ts index ea5f2f859..d2f543923 100644 --- a/packages/openapi-ts/src/index.ts +++ b/packages/openapi-ts/src/index.ts @@ -23,13 +23,7 @@ import type { PluginNames, } from './plugins/types'; import type { Client } from './types/client'; -import type { - ClientConfig, - Config, - Formatters, - Linters, - UserConfig, -} from './types/config'; +import type { Config, Formatters, Linters, UserConfig } from './types/config'; import { CLIENTS } from './types/config'; import { isLegacyClient, @@ -103,7 +97,7 @@ const processOutput = ({ config }: { config: Config }) => { } }; -const getClient = (userConfig: ClientConfig): Config['client'] => { +const getClient = (userConfig: UserConfig): Config['client'] => { let client: Config['client'] = { bundle: false, name: '' as Config['client']['name'], @@ -119,7 +113,7 @@ const getClient = (userConfig: ClientConfig): Config['client'] => { return client; }; -const getInput = (userConfig: ClientConfig): Config['input'] => { +const getInput = (userConfig: UserConfig): Config['input'] => { let input: Config['input'] = { path: '', }; @@ -139,7 +133,7 @@ const getInput = (userConfig: ClientConfig): Config['input'] => { return input; }; -const getLogs = (userConfig: ClientConfig): Config['logs'] => { +const getLogs = (userConfig: UserConfig): Config['logs'] => { let logs: Config['logs'] = { level: 'info', path: process.cwd(), @@ -155,7 +149,7 @@ const getLogs = (userConfig: ClientConfig): Config['logs'] => { return logs; }; -const getOutput = (userConfig: ClientConfig): Config['output'] => { +const getOutput = (userConfig: UserConfig): Config['output'] => { let output: Config['output'] = { clean: true, format: false, @@ -271,7 +265,7 @@ const getPluginsConfig = ({ }; const getPlugins = ( - userConfig: ClientConfig, + userConfig: UserConfig, ): Pick => { const userPluginsConfig: Config['plugins'] = {}; @@ -438,7 +432,7 @@ const getSpec = async ({ }; const getWatch = ( - userConfig: Pick & Pick, + userConfig: Pick & Pick, ): Config['watch'] => { let watch: Config['watch'] = { enabled: false, @@ -476,7 +470,7 @@ const initConfigs = async (userConfig: UserConfig): Promise => { name: 'openapi-ts', }); - const userConfigs: ClientConfig[] = Array.isArray(userConfig) + const userConfigs: UserConfig[] = Array.isArray(userConfig) ? userConfig : Array.isArray(configFromFile) ? configFromFile.map((config) => ({ diff --git a/packages/openapi-ts/src/plugins/@hey-api/schemas/types.d.ts b/packages/openapi-ts/src/plugins/@hey-api/schemas/types.d.ts index c95c1182c..af389af5a 100644 --- a/packages/openapi-ts/src/plugins/@hey-api/schemas/types.d.ts +++ b/packages/openapi-ts/src/plugins/@hey-api/schemas/types.d.ts @@ -25,6 +25,7 @@ export interface Config extends Plugin.Name<'@hey-api/schemas'> { ) => string; /** * Name of the generated file. + * * @default 'schemas' */ output?: string; @@ -32,6 +33,7 @@ export interface Config extends Plugin.Name<'@hey-api/schemas'> { * Choose schema type to generate. Select 'form' if you don't want * descriptions to reduce bundle size and you plan to use schemas * for form validation + * * @default 'json' */ type?: 'form' | 'json'; diff --git a/packages/openapi-ts/src/plugins/@hey-api/sdk/types.d.ts b/packages/openapi-ts/src/plugins/@hey-api/sdk/types.d.ts index 497e16e3e..6006db77e 100644 --- a/packages/openapi-ts/src/plugins/@hey-api/sdk/types.d.ts +++ b/packages/openapi-ts/src/plugins/@hey-api/sdk/types.d.ts @@ -59,11 +59,11 @@ export interface Config extends Plugin.Name<'@hey-api/sdk'> { */ output?: string; /** + * @deprecated + * * Define shape of returned value from service calls * * @default 'body' - * - * @deprecated */ response?: 'body' | 'response'; /** diff --git a/packages/openapi-ts/src/plugins/@hey-api/transformers/plugin.ts b/packages/openapi-ts/src/plugins/@hey-api/transformers/plugin.ts index 75bfeb5c2..8ca1b0c85 100644 --- a/packages/openapi-ts/src/plugins/@hey-api/transformers/plugin.ts +++ b/packages/openapi-ts/src/plugins/@hey-api/transformers/plugin.ts @@ -7,6 +7,7 @@ import { irRef } from '../../../utils/ref'; import { stringCase } from '../../../utils/stringCase'; import { operationIrRef } from '../../shared/utils/ref'; import type { Plugin } from '../../types'; +import { typesId } from '../typescript/ref'; import type { Config } from './types'; interface OperationIRRef { @@ -460,7 +461,7 @@ export const handler: Plugin.Handler = ({ context, plugin }) => { return; } - const identifierResponse = context.file({ id: 'types' })!.identifier({ + const identifierResponse = context.file({ id: typesId })!.identifier({ $ref: operationIrRef({ id: operation.id, type: 'response' }), namespace: 'type', }); @@ -486,7 +487,7 @@ export const handler: Plugin.Handler = ({ context, plugin }) => { if (nodes.length) { file.import({ asType: true, - module: file.relativePathToFile({ context, id: 'types' }), + module: file.relativePathToFile({ context, id: typesId }), name: identifierResponse.name, }); const responseTransformerNode = compiler.constVariable({ diff --git a/packages/openapi-ts/src/plugins/@hey-api/typescript/ref.ts b/packages/openapi-ts/src/plugins/@hey-api/typescript/ref.ts index c18ca6b45..7a5bff633 100644 --- a/packages/openapi-ts/src/plugins/@hey-api/typescript/ref.ts +++ b/packages/openapi-ts/src/plugins/@hey-api/typescript/ref.ts @@ -26,7 +26,7 @@ export const importIdentifierData = ({ file: TypeScriptFile; operation: IR.OperationObject; }): Identifier => { - const identifierData = context.file({ id: 'types' })!.identifier({ + const identifierData = context.file({ id: typesId })!.identifier({ $ref: operationIrRef({ id: operation.id, type: 'data' }), namespace: 'type', }); @@ -34,7 +34,7 @@ export const importIdentifierData = ({ if (identifier.name) { file.import({ asType: true, - module: file.relativePathToFile({ context, id: 'types' }), + module: file.relativePathToFile({ context, id: typesId }), name: identifier.name, }); } @@ -50,7 +50,7 @@ export const importIdentifierError = ({ file: TypeScriptFile; operation: IR.OperationObject; }): Identifier => { - const identifierError = context.file({ id: 'types' })!.identifier({ + const identifierError = context.file({ id: typesId })!.identifier({ $ref: operationIrRef({ id: operation.id, type: 'error' }), namespace: 'type', }); @@ -58,7 +58,7 @@ export const importIdentifierError = ({ if (identifier.name) { file.import({ asType: true, - module: file.relativePathToFile({ context, id: 'types' }), + module: file.relativePathToFile({ context, id: typesId }), name: identifier.name, }); } @@ -74,7 +74,7 @@ export const importIdentifierResponse = ({ file: TypeScriptFile; operation: IR.OperationObject; }): Identifier => { - const identifierResponse = context.file({ id: 'types' })!.identifier({ + const identifierResponse = context.file({ id: typesId })!.identifier({ $ref: operationIrRef({ id: operation.id, type: 'response' }), namespace: 'type', }); @@ -82,7 +82,7 @@ export const importIdentifierResponse = ({ if (identifier.name) { file.import({ asType: true, - module: file.relativePathToFile({ context, id: 'types' }), + module: file.relativePathToFile({ context, id: typesId }), name: identifier.name, }); } diff --git a/packages/openapi-ts/src/plugins/@tanstack/angular-query-experimental/types.d.ts b/packages/openapi-ts/src/plugins/@tanstack/angular-query-experimental/types.d.ts index 07120bd81..b7e1afd59 100644 --- a/packages/openapi-ts/src/plugins/@tanstack/angular-query-experimental/types.d.ts +++ b/packages/openapi-ts/src/plugins/@tanstack/angular-query-experimental/types.d.ts @@ -4,22 +4,26 @@ export interface Config extends Plugin.Name<'@tanstack/angular-query-experimental'> { /** * Generate {@link https://tanstack.com/query/v5/docs/framework/angular/reference/infiniteQueryOptions `infiniteQueryOptions()`} helpers? These will be generated from GET and POST requests where a pagination parameter is detected. + * * @default true */ infiniteQueryOptions?: boolean; /** * Generate {@link https://tanstack.com/query/v5/docs/framework/angular/reference/useMutation `useMutation()`} helpers? These will be generated from DELETE, PATCH, POST, and PUT requests. + * * @default true */ mutationOptions?: boolean; /** * Name of the generated file. + * * @default '@tanstack/angular-query-experimental' */ output?: string; /** * Generate {@link https://tanstack.com/query/v5/docs/framework/angular/reference/queryOptions `queryOptions()`} helpers? * These will be generated from all requests. + * * @default true */ queryOptions?: boolean; diff --git a/packages/openapi-ts/src/plugins/@tanstack/react-query/types.d.ts b/packages/openapi-ts/src/plugins/@tanstack/react-query/types.d.ts index c533e429b..edf92328f 100644 --- a/packages/openapi-ts/src/plugins/@tanstack/react-query/types.d.ts +++ b/packages/openapi-ts/src/plugins/@tanstack/react-query/types.d.ts @@ -3,22 +3,26 @@ import type { Plugin } from '../../types'; export interface Config extends Plugin.Name<'@tanstack/react-query'> { /** * Generate {@link https://tanstack.com/query/v5/docs/framework/react/reference/infiniteQueryOptions `infiniteQueryOptions()`} helpers? These will be generated from GET and POST requests where a pagination parameter is detected. + * * @default true */ infiniteQueryOptions?: boolean; /** * Generate {@link https://tanstack.com/query/v5/docs/framework/react/reference/useMutation `useMutation()`} helpers? These will be generated from DELETE, PATCH, POST, and PUT requests. + * * @default true */ mutationOptions?: boolean; /** * Name of the generated file. + * * @default '@tanstack/react-query' */ output?: string; /** * Generate {@link https://tanstack.com/query/v5/docs/framework/react/reference/queryOptions `queryOptions()`} helpers? * These will be generated from all requests. + * * @default true */ queryOptions?: boolean; diff --git a/packages/openapi-ts/src/plugins/@tanstack/solid-query/types.d.ts b/packages/openapi-ts/src/plugins/@tanstack/solid-query/types.d.ts index 783382b04..3190b99cc 100644 --- a/packages/openapi-ts/src/plugins/@tanstack/solid-query/types.d.ts +++ b/packages/openapi-ts/src/plugins/@tanstack/solid-query/types.d.ts @@ -3,22 +3,26 @@ import type { Plugin } from '../../types'; export interface Config extends Plugin.Name<'@tanstack/solid-query'> { /** * Generate `createInfiniteQuery()` helpers? These will be generated from GET and POST requests where a pagination parameter is detected. + * * @default true */ infiniteQueryOptions?: boolean; /** * Generate `createMutation()` helpers? These will be generated from DELETE, PATCH, POST, and PUT requests. + * * @default true */ mutationOptions?: boolean; /** * Name of the generated file. + * * @default '@tanstack/solid-query' */ output?: string; /** * Generate {@link https://tanstack.com/query/v5/docs/framework/solid/reference/createQuery `createQuery()`} helpers? * These will be generated from all requests. + * * @default true */ queryOptions?: boolean; diff --git a/packages/openapi-ts/src/plugins/@tanstack/svelte-query/types.d.ts b/packages/openapi-ts/src/plugins/@tanstack/svelte-query/types.d.ts index 2e8637037..43b57669c 100644 --- a/packages/openapi-ts/src/plugins/@tanstack/svelte-query/types.d.ts +++ b/packages/openapi-ts/src/plugins/@tanstack/svelte-query/types.d.ts @@ -3,22 +3,26 @@ import type { Plugin } from '../../types'; export interface Config extends Plugin.Name<'@tanstack/svelte-query'> { /** * Generate `createInfiniteQuery()` helpers? These will be generated from GET and POST requests where a pagination parameter is detected. + * * @default true */ infiniteQueryOptions?: boolean; /** * Generate {@link https://tanstack.com/query/v5/docs/framework/svelte/reference/functions/createmutation `createMutation()`} helpers? These will be generated from DELETE, PATCH, POST, and PUT requests. + * * @default true */ mutationOptions?: boolean; /** * Name of the generated file. + * * @default '@tanstack/svelte-query' */ output?: string; /** * Generate {@link https://tanstack.com/query/v5/docs/framework/svelte/reference/functions/createquery `createQuery()`} helpers? * These will be generated from all requests. + * * @default true */ queryOptions?: boolean; diff --git a/packages/openapi-ts/src/plugins/@tanstack/vue-query/types.d.ts b/packages/openapi-ts/src/plugins/@tanstack/vue-query/types.d.ts index b688aed38..4aab0a5d9 100644 --- a/packages/openapi-ts/src/plugins/@tanstack/vue-query/types.d.ts +++ b/packages/openapi-ts/src/plugins/@tanstack/vue-query/types.d.ts @@ -3,22 +3,26 @@ import type { Plugin } from '../../types'; export interface Config extends Plugin.Name<'@tanstack/vue-query'> { /** * Generate {@link https://tanstack.com/query/v5/docs/framework/vue/reference/infiniteQueryOptions `infiniteQueryOptions()`} helpers? These will be generated from GET and POST requests where a pagination parameter is detected. + * * @default true */ infiniteQueryOptions?: boolean; /** * Generate {@link https://tanstack.com/query/v5/docs/framework/vue/reference/useMutation `useMutation()`} helpers? These will be generated from DELETE, PATCH, POST, and PUT requests. + * * @default true */ mutationOptions?: boolean; /** * Name of the generated file. + * * @default '@tanstack/vue-query' */ output?: string; /** * Generate {@link https://tanstack.com/query/v5/docs/framework/vue/guides/query-options `queryOptions()`} helpers? * These will be generated from all requests. + * * @default true */ queryOptions?: boolean; diff --git a/packages/openapi-ts/src/plugins/fastify/plugin.ts b/packages/openapi-ts/src/plugins/fastify/plugin.ts index 2bd789486..ed197e57f 100644 --- a/packages/openapi-ts/src/plugins/fastify/plugin.ts +++ b/packages/openapi-ts/src/plugins/fastify/plugin.ts @@ -4,6 +4,7 @@ import { compiler, type Property } from '../../compiler'; import { operationResponsesMap } from '../../ir/operation'; import { hasParameterGroupObjectRequired } from '../../ir/parameter'; import type { IR } from '../../ir/types'; +import { typesId } from '../@hey-api/typescript/ref'; import { operationIrRef } from '../shared/utils/ref'; import type { Plugin } from '../types'; import type { Config } from './types'; @@ -18,7 +19,7 @@ const operationToRouteHandler = ({ operation: IR.OperationObject; }): Property | undefined => { const file = context.file({ id: fastifyId })!; - const fileTypes = context.file({ id: 'types' })!; + const fileTypes = context.file({ id: typesId })!; const properties: Array = []; @@ -30,7 +31,7 @@ const operationToRouteHandler = ({ if (operation.body) { file.import({ asType: true, - module: file.relativePathToFile({ context, id: 'types' }), + module: file.relativePathToFile({ context, id: typesId }), name: identifierData.name, }); properties.push({ @@ -44,7 +45,7 @@ const operationToRouteHandler = ({ if (operation.parameters.header) { file.import({ asType: true, - module: file.relativePathToFile({ context, id: 'types' }), + module: file.relativePathToFile({ context, id: typesId }), name: identifierData.name, }); properties.push({ @@ -59,7 +60,7 @@ const operationToRouteHandler = ({ if (operation.parameters.path) { file.import({ asType: true, - module: file.relativePathToFile({ context, id: 'types' }), + module: file.relativePathToFile({ context, id: typesId }), name: identifierData.name, }); properties.push({ @@ -74,7 +75,7 @@ const operationToRouteHandler = ({ if (operation.parameters.query) { file.import({ asType: true, - module: file.relativePathToFile({ context, id: 'types' }), + module: file.relativePathToFile({ context, id: typesId }), name: identifierData.name, }); properties.push({ @@ -102,7 +103,7 @@ const operationToRouteHandler = ({ if (!hasDefaultResponse) { file.import({ asType: true, - module: file.relativePathToFile({ context, id: 'types' }), + module: file.relativePathToFile({ context, id: typesId }), name: identifierErrors.name, }); errorsTypeReference = compiler.typeReferenceNode({ @@ -111,7 +112,7 @@ const operationToRouteHandler = ({ } else if (keys.length > 1) { file.import({ asType: true, - module: file.relativePathToFile({ context, id: 'types' }), + module: file.relativePathToFile({ context, id: typesId }), name: identifierErrors.name, }); const errorsType = compiler.typeReferenceNode({ @@ -140,7 +141,7 @@ const operationToRouteHandler = ({ if (!hasDefaultResponse) { file.import({ asType: true, - module: file.relativePathToFile({ context, id: 'types' }), + module: file.relativePathToFile({ context, id: typesId }), name: identifierResponses.name, }); responsesTypeReference = compiler.typeReferenceNode({ @@ -149,7 +150,7 @@ const operationToRouteHandler = ({ } else if (keys.length > 1) { file.import({ asType: true, - module: file.relativePathToFile({ context, id: 'types' }), + module: file.relativePathToFile({ context, id: typesId }), name: identifierResponses.name, }); const responsesType = compiler.typeReferenceNode({ diff --git a/packages/openapi-ts/src/plugins/fastify/types.d.ts b/packages/openapi-ts/src/plugins/fastify/types.d.ts index e4860b611..c701bc7de 100644 --- a/packages/openapi-ts/src/plugins/fastify/types.d.ts +++ b/packages/openapi-ts/src/plugins/fastify/types.d.ts @@ -3,6 +3,7 @@ import type { Plugin } from '../types'; export interface Config extends Plugin.Name<'fastify'> { /** * Name of the generated file. + * * @default 'fastify' */ output?: string; diff --git a/packages/openapi-ts/src/plugins/index.ts b/packages/openapi-ts/src/plugins/index.ts index 63985a69b..db42b6565 100644 --- a/packages/openapi-ts/src/plugins/index.ts +++ b/packages/openapi-ts/src/plugins/index.ts @@ -35,6 +35,7 @@ import { defaultConfig as tanStackVueQuery, } from './@tanstack/vue-query'; import { type Config as Fastify, defaultConfig as fastify } from './fastify'; +import { type Config as Msw, defaultConfig as msw } from './msw'; import type { DefaultPluginConfigs, Plugin } from './types'; import { type Config as Zod, defaultConfig as zod } from './zod'; @@ -52,6 +53,7 @@ export type UserPlugins = | Plugin.UserConfig | Plugin.UserConfig | Plugin.UserConfig + | Plugin.UserConfig | Plugin.UserConfig; /** @@ -68,6 +70,7 @@ export type ClientPlugins = | Plugin.Config | Plugin.Config | Plugin.Config + | Plugin.Config | Plugin.Config; export const defaultPluginConfigs: DefaultPluginConfigs = { @@ -81,5 +84,6 @@ export const defaultPluginConfigs: DefaultPluginConfigs = { '@tanstack/svelte-query': tanStackSvelteQuery, '@tanstack/vue-query': tanStackVueQuery, fastify, + msw, zod, }; diff --git a/packages/openapi-ts/src/plugins/msw/config.ts b/packages/openapi-ts/src/plugins/msw/config.ts new file mode 100644 index 000000000..cc5320a81 --- /dev/null +++ b/packages/openapi-ts/src/plugins/msw/config.ts @@ -0,0 +1,18 @@ +import type { Plugin } from '../types'; +import { handler } from './plugin'; +import type { Config } from './types'; + +export const defaultConfig: Plugin.Config = { + _handler: handler, + _handlerLegacy: () => {}, + name: 'msw', + output: 'msw', +}; + +/** + * Type helper for MSW plugin, returns {@link Plugin.Config} object + */ +export const defineConfig: Plugin.DefineConfig = (config) => ({ + ...defaultConfig, + ...config, +}); diff --git a/packages/openapi-ts/src/plugins/msw/index.ts b/packages/openapi-ts/src/plugins/msw/index.ts new file mode 100644 index 000000000..3a85a1be8 --- /dev/null +++ b/packages/openapi-ts/src/plugins/msw/index.ts @@ -0,0 +1,2 @@ +export { defaultConfig, defineConfig } from './config'; +export type { Config } from './types'; diff --git a/packages/openapi-ts/src/plugins/msw/interfaces.ts b/packages/openapi-ts/src/plugins/msw/interfaces.ts new file mode 100644 index 000000000..317a818c2 --- /dev/null +++ b/packages/openapi-ts/src/plugins/msw/interfaces.ts @@ -0,0 +1,126 @@ +import ts from 'typescript'; + +import { compiler } from '../../compiler'; + +const objectReference = compiler.typeReferenceNode({ typeName: 'object' }); +const tReference = compiler.typeReferenceNode({ typeName: 'T' }); +const uReference = compiler.typeReferenceNode({ typeName: 'U' }); +export const undefinedReference = compiler.typeReferenceNode({ + typeName: 'undefined', +}); +export const neverReference = compiler.typeReferenceNode({ typeName: 'never' }); + +export const pathParamsTypeName = 'PathParams'; +export const responseBodyTypeTypeName = 'ResponseBodyType'; +const transformObjectTypeName = 'TransformObject'; + +export const createTransformObjectType = () => { + const tkType = compiler.indexedAccessTypeNode({ + indexType: compiler.typeReferenceNode({ typeName: 'K' }), + objectType: tReference, + }); + const nullType = compiler.literalTypeNode({ literal: compiler.null() }); + const type = compiler.typeAliasDeclaration({ + name: transformObjectTypeName, + type: compiler.mappedTypeNode({ + type: ts.factory.createConditionalTypeNode( + tkType, + objectReference, + compiler.typeReferenceNode({ + typeArguments: [tkType], + typeName: transformObjectTypeName, + }), + compiler.typeUnionNode({ + types: [ + compiler.typeReferenceNode({ typeName: 'string' }), + ts.factory.createConditionalTypeNode( + nullType, + tkType, + undefinedReference, + neverReference, + ), + ], + }), + ), + typeParameter: compiler.typeParameterDeclaration({ + constraint: compiler.typeOperatorNode({ + operator: 'keyof', + type: tReference, + }), + name: 'K', + }), + }), + typeParameters: [ + compiler.typeParameterDeclaration({ + name: 'T', + }), + ], + }); + return type; +}; + +export const createPathParamsType = () => { + const type = compiler.typeAliasDeclaration({ + name: pathParamsTypeName, + type: ts.factory.createConditionalTypeNode( + tReference, + ts.factory.createTypeLiteralNode([ + ts.factory.createPropertySignature( + undefined, + ts.factory.createIdentifier('path'), + ts.factory.createToken(ts.SyntaxKind.QuestionToken), + ts.factory.createInferTypeNode( + compiler.typeParameterDeclaration({ + name: 'U', + }), + ), + ), + ]), + ts.factory.createConditionalTypeNode( + uReference, + objectReference, + compiler.typeReferenceNode({ + typeArguments: [uReference], + typeName: transformObjectTypeName, + }), + neverReference, + ), + neverReference, + ), + typeParameters: [ + compiler.typeParameterDeclaration({ + name: 'T', + }), + ], + }); + return type; +}; + +export const createResponseBodyTypeType = () => { + const type = compiler.typeAliasDeclaration({ + name: responseBodyTypeTypeName, + type: ts.factory.createConditionalTypeNode( + compiler.typeReferenceNode({ typeName: 'void' }), + tReference, + compiler.typeUnionNode({ + types: [ + compiler.typeReferenceNode({ + typeArguments: [ + tReference, + compiler.keywordTypeNode({ keyword: 'void' }), + ], + typeName: 'Exclude', + }), + undefinedReference, + ], + }), + tReference, + ), + typeParameters: [ + compiler.typeParameterDeclaration({ + name: 'T', + }), + ], + }); + return type; +}; diff --git a/packages/openapi-ts/src/plugins/msw/plugin.ts b/packages/openapi-ts/src/plugins/msw/plugin.ts new file mode 100644 index 000000000..00abf2433 --- /dev/null +++ b/packages/openapi-ts/src/plugins/msw/plugin.ts @@ -0,0 +1,182 @@ +import type ts from 'typescript'; + +import { compiler } from '../../compiler'; +import type { IR } from '../../ir/types'; +import { irRef } from '../../utils/ref'; +import { stringCase } from '../../utils/stringCase'; +import { + importIdentifierData, + importIdentifierResponse, +} from '../@hey-api/typescript/ref'; +import type { Plugin } from '../types'; +import { + createPathParamsType, + createResponseBodyTypeType, + createTransformObjectType, + neverReference, + pathParamsTypeName, + responseBodyTypeTypeName, + undefinedReference, +} from './interfaces'; +import type { Config } from './types'; + +export const mswId = 'msw'; + +const nameTransformer = (name: string) => `${name}-handler`; + +const resolverStatements = ({ + // context, + operation, +}: { + context: IR.Context; + operation: IR.OperationObject; +}) => { + const statements: Array = []; + + // TODO: get any of the 2xx status codes + console.log(operation.responses); + + const response = compiler.constVariable({ + expression: compiler.callExpression({ + functionName: compiler.propertyAccessExpression({ + expression: 'HttpResponse', + name: compiler.identifier({ text: 'json' }), + }), + parameters: [ + compiler.objectExpression({ + obj: [], + }), + ], + types: [], + }), + name: 'response', + }); + statements.push(response); + + statements.push( + compiler.returnStatement({ + expression: compiler.identifier({ text: 'response' }), + }), + ); + + return statements; +}; + +const operationToMswHandler = ({ + context, + operation, +}: { + context: IR.Context; + operation: IR.OperationObject; +}) => { + const file = context.file({ id: mswId })!; + + const identifier = file.identifier({ + $ref: `${irRef}${stringCase({ + case: 'camelCase', + value: operation.id, + })}`, + create: true, + nameTransformer, + namespace: 'value', + }); + + if (!identifier.name) { + return; + } + + const identifierData = importIdentifierData({ context, file, operation }); + const identifierResponse = importIdentifierResponse({ + context, + file, + operation, + }); + + // TODO: add support for baseUrl/servers + // replace our curly brackets with colon + const handlerPath = `*${operation.path.replace(/{([^}]+)}/g, ':$1')}`; + + const statement = compiler.constVariable({ + exportConst: true, + expression: compiler.callExpression({ + functionName: compiler.propertyAccessExpression({ + expression: compiler.identifier({ text: 'http' }), + name: operation.method, + }), + parameters: [ + compiler.ots.string(handlerPath), + compiler.arrowFunction({ + async: true, + parameters: [ + // TODO: use cookies, params, request, requestId + ], + statements: resolverStatements({ + context, + operation, + }), + }), + ], + types: [ + identifierData.name + ? compiler.typeReferenceNode({ + typeArguments: [ + compiler.typeReferenceNode({ typeName: identifierData.name }), + ], + typeName: pathParamsTypeName, + }) + : neverReference, + identifierData.name + ? compiler.indexedAccessTypeNode({ + indexType: compiler.literalTypeNode({ + literal: compiler.stringLiteral({ text: 'body' }), + }), + objectType: compiler.typeReferenceNode({ + typeName: identifierData.name, + }), + }) + : neverReference, + identifierResponse.name + ? compiler.typeReferenceNode({ + typeArguments: [ + compiler.typeReferenceNode({ + typeName: identifierResponse.name, + }), + ], + typeName: responseBodyTypeTypeName, + }) + : undefinedReference, + ], + }), + name: identifier.name, + }); + file.add(statement); +}; + +export const handler: Plugin.Handler = ({ context, plugin }) => { + const file = context.createFile({ + exportFromIndex: plugin.exportFromIndex, + id: mswId, + identifierCase: 'camelCase', + path: plugin.output, + }); + + file.import({ + module: 'msw', + name: 'http', + }); + file.import({ + module: 'msw', + name: 'HttpResponse', + }); + + file.add(createTransformObjectType()); + file.add(createPathParamsType()); + file.add(createResponseBodyTypeType()); + + context.subscribe('operation', ({ operation }) => { + operationToMswHandler({ + context, + operation, + }); + }); +}; diff --git a/packages/openapi-ts/src/plugins/msw/types.d.ts b/packages/openapi-ts/src/plugins/msw/types.d.ts new file mode 100644 index 000000000..d1e6fcd8c --- /dev/null +++ b/packages/openapi-ts/src/plugins/msw/types.d.ts @@ -0,0 +1,10 @@ +import type { Plugin } from '../types'; + +export interface Config extends Plugin.Name<'msw'> { + /** + * Name of the generated file. + * + * @default 'msw' + */ + output?: string; +} diff --git a/packages/openapi-ts/src/plugins/types.d.ts b/packages/openapi-ts/src/plugins/types.d.ts index 396b33364..11a2d5cec 100644 --- a/packages/openapi-ts/src/plugins/types.d.ts +++ b/packages/openapi-ts/src/plugins/types.d.ts @@ -19,6 +19,7 @@ export type PluginNames = | '@tanstack/svelte-query' | '@tanstack/vue-query' | 'fastify' + | 'msw' | 'zod'; export type AnyPluginName = PluginNames | (string & {}); diff --git a/packages/openapi-ts/src/plugins/zod/types.d.ts b/packages/openapi-ts/src/plugins/zod/types.d.ts index 3631e7d46..63c595c6c 100644 --- a/packages/openapi-ts/src/plugins/zod/types.d.ts +++ b/packages/openapi-ts/src/plugins/zod/types.d.ts @@ -9,6 +9,7 @@ export interface Config extends Plugin.Name<'zod'> { // nameBuilder?: (model: IR.OperationObject | IR.SchemaObject) => string; /** * Name of the generated file. + * * @default 'zod' */ output?: string; diff --git a/packages/openapi-ts/src/types/config.ts b/packages/openapi-ts/src/types/config.ts index 07aa3ab68..33a774270 100644 --- a/packages/openapi-ts/src/types/config.ts +++ b/packages/openapi-ts/src/types/config.ts @@ -29,7 +29,7 @@ export type StringCase = | 'snake_case' | 'SCREAMING_SNAKE_CASE'; -export interface ClientConfig { +export interface UserConfig { /** * HTTP client to generate */ @@ -274,10 +274,8 @@ export interface ClientConfig { useOptions?: boolean; } -export type UserConfig = ClientConfig; - export type Config = Omit< - Required, + Required, | 'base' | 'client' | 'input' @@ -288,15 +286,15 @@ export type Config = Omit< | 'request' | 'watch' > & - Pick & { - client: Extract['client'], object>; - input: ExtractWithDiscriminator; - logs: Extract, object>; - output: Extract; + Pick & { + client: Extract['client'], object>; + input: ExtractWithDiscriminator; + logs: Extract, object>; + output: Extract; pluginOrder: ReadonlyArray; plugins: ArrayOfObjectsToObjectMap< ExtractArrayOfObjects, { name: string }>, 'name' >; - watch: Extract; + watch: Extract; }; diff --git a/packages/openapi-ts/test/openapi-ts.config.ts b/packages/openapi-ts/test/openapi-ts.config.ts index cb450d46f..e8c9a787b 100644 --- a/packages/openapi-ts/test/openapi-ts.config.ts +++ b/packages/openapi-ts/test/openapi-ts.config.ts @@ -11,7 +11,7 @@ export default defineConfig({ // exclude: '^#/components/schemas/ModelWithCircularReference$', // include: // '^(#/components/schemas/import|#/paths/api/v{api-version}/simple/options)$', - path: './packages/openapi-ts/test/spec/3.1.x/body-nested-array.yaml', + path: './packages/openapi-ts/test/spec/3.1.x/full.json', // path: './test/spec/v3-transforms.json', // path: 'https://mongodb-mms-prod-build-server.s3.amazonaws.com/openapi/2caffd88277a4e27c95dcefc7e3b6a63a3b03297-v2-2023-11-15.json', // path: 'https://raw.githubusercontent.com/swagger-api/swagger-petstore/master/src/main/resources/openapi.yaml', @@ -73,6 +73,10 @@ export default defineConfig({ // name: '@tanstack/react-query', }, // @ts-ignore + { + name: 'msw', + }, + // @ts-ignore { // name: 'zod', }, diff --git a/packages/openapi-ts/test/spec/3.1.x/body-nested-array.yaml b/packages/openapi-ts/test/spec/3.1.x/body-nested-array.yaml deleted file mode 100644 index 4af61c5fc..000000000 --- a/packages/openapi-ts/test/spec/3.1.x/body-nested-array.yaml +++ /dev/null @@ -1,25 +0,0 @@ -openapi: 3.1.1 -info: - title: OpenAPI 3.1.1 body nested array example - version: 1 -paths: - /foo: - post: - requestBody: - content: - 'multipart/form-data': - schema: - properties: - foo: - items: - items: - type: integer - type: array - type: array - required: - - foo - type: object - required: true - responses: - '200': - description: OK diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 29099a09d..ad0f453a2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -266,13 +266,13 @@ importers: version: link:../../packages/client-nuxt nuxt: specifier: 3.15.1 - version: 3.15.1(@parcel/watcher@2.5.0)(@types/node@22.10.5)(db0@0.2.1)(encoding@0.1.13)(eslint@9.17.0(jiti@2.4.2))(ioredis@5.4.2)(less@4.2.0)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.31.0)(sass@1.80.7)(terser@5.36.0)(typescript@5.6.1-rc)(yaml@2.7.0) + version: 3.15.1(@parcel/watcher@2.5.0)(@types/node@22.10.5)(db0@0.2.1)(encoding@0.1.13)(eslint@9.17.0(jiti@2.4.2))(ioredis@5.4.2)(less@4.2.0)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.31.0)(sass@1.80.7)(terser@5.36.0)(typescript@5.5.3)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)(yaml@2.7.0))(yaml@2.7.0) vue: specifier: 3.5.13 - version: 3.5.13(typescript@5.6.1-rc) + version: 3.5.13(typescript@5.5.3) vue-router: specifier: 4.5.0 - version: 4.5.0(vue@3.5.13(typescript@5.6.1-rc)) + version: 4.5.0(vue@3.5.13(typescript@5.5.3)) zod: specifier: 3.23.8 version: 3.23.8 @@ -688,17 +688,17 @@ importers: dependencies: nuxt: specifier: '>= 3.0.0 < 4' - version: 3.15.1(@parcel/watcher@2.5.0)(@types/node@22.10.5)(db0@0.2.1)(encoding@0.1.13)(eslint@9.17.0(jiti@2.4.2))(ioredis@5.4.2)(less@4.2.0)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.31.0)(sass@1.80.7)(terser@5.36.0)(typescript@5.6.1-rc)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)(yaml@2.7.0))(yaml@2.7.0) + version: 3.15.1(@parcel/watcher@2.5.0)(@types/node@22.10.5)(db0@0.2.1)(encoding@0.1.13)(eslint@9.17.0(jiti@2.4.2))(ioredis@5.4.2)(less@4.2.0)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.31.0)(sass@1.80.7)(terser@5.36.0)(typescript@5.5.3)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)(yaml@2.7.0))(yaml@2.7.0) vue: specifier: '>= 3.5.13 < 4' - version: 3.5.13(typescript@5.6.1-rc) + version: 3.5.13(typescript@5.5.3) devDependencies: '@hey-api/client-core': specifier: workspace:* version: link:../client-core '@nuxt/test-utils': specifier: 3.15.1 - version: 3.15.1(@types/node@22.10.5)(@vue/test-utils@2.4.6)(jsdom@24.1.0)(less@4.2.0)(magicast@0.3.5)(rollup@4.31.0)(sass@1.80.7)(terser@5.36.0)(typescript@5.6.1-rc)(vitest@1.6.0(@types/node@22.10.5)(jsdom@24.1.0)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)) + version: 3.15.1(@types/node@22.10.5)(@vue/test-utils@2.4.6)(jsdom@24.1.0)(less@4.2.0)(magicast@0.3.5)(rollup@4.31.0)(sass@1.80.7)(terser@5.36.0)(typescript@5.5.3)(vitest@1.6.0(@types/node@22.10.5)(jsdom@24.1.0)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)) packages/openapi-ts: dependencies: @@ -717,7 +717,7 @@ importers: devDependencies: '@angular-devkit/build-angular': specifier: 19.0.6 - version: 19.0.6(@angular/compiler-cli@19.0.5(@angular/compiler@19.0.5(@angular/core@19.0.5(rxjs@7.8.1)(zone.js@0.15.0)))(typescript@5.5.3))(@angular/compiler@19.0.5(@angular/core@19.0.5(rxjs@7.8.1)(zone.js@0.15.0)))(@types/node@22.10.5)(chokidar@4.0.3)(karma@6.4.4)(tailwindcss@3.4.17(ts-node@10.9.2(@types/node@22.10.5)(typescript@5.5.3)))(typescript@5.5.3)(vite@5.4.11(@types/node@22.10.5)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)) + version: 19.0.6(@angular/compiler-cli@19.0.5(@angular/compiler@19.0.5(@angular/core@19.0.5(rxjs@7.8.1)(zone.js@0.15.0)))(typescript@5.5.3))(@angular/compiler@19.0.5(@angular/core@19.0.5(rxjs@7.8.1)(zone.js@0.15.0)))(@types/node@22.10.5)(chokidar@4.0.3)(karma@6.4.4)(tailwindcss@3.4.17(ts-node@10.9.2(@types/node@22.10.5)(typescript@5.5.3)))(typescript@5.5.3)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)(yaml@2.7.0)) '@angular/animations': specifier: 19.0.5 version: 19.0.5(@angular/core@19.0.5(rxjs@7.8.1)(zone.js@0.15.0)) @@ -796,12 +796,15 @@ importers: glob: specifier: 10.4.3 version: 10.4.3 + msw: + specifier: 2.7.0 + version: 2.7.0(@types/node@22.10.5)(typescript@5.5.3) node-fetch: specifier: 3.3.2 version: 3.3.2 nuxt: specifier: 3.15.1 - version: 3.15.1(@parcel/watcher@2.5.0)(@types/node@22.10.5)(db0@0.2.1)(encoding@0.1.13)(eslint@9.17.0(jiti@2.4.2))(ioredis@5.4.2)(less@4.2.0)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.31.0)(sass@1.80.7)(terser@5.36.0)(typescript@5.5.3)(vite@5.4.11(@types/node@22.10.5)(less@4.2.0)(sass@1.80.7)(terser@5.36.0))(yaml@2.7.0) + version: 3.15.1(@parcel/watcher@2.5.0)(@types/node@22.10.5)(db0@0.2.1)(encoding@0.1.13)(eslint@9.17.0(jiti@2.4.2))(ioredis@5.4.2)(less@4.2.0)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.31.0)(sass@1.80.7)(terser@5.36.0)(typescript@5.5.3)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)(yaml@2.7.0))(yaml@2.7.0) prettier: specifier: 3.4.2 version: 3.4.2 @@ -1676,6 +1679,15 @@ packages: '@bcoe/v8-coverage@0.2.3': resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + '@bundled-es-modules/cookie@2.0.1': + resolution: {integrity: sha512-8o+5fRPLNbjbdGRRmJj3h6Hh1AQJf2dk3qQ/5ZFb+PXkRNiSoMGGUKlsgLfrxneb72axVJyIYji64E2+nNfYyw==} + + '@bundled-es-modules/statuses@1.0.1': + resolution: {integrity: sha512-yn7BklA5acgcBr+7w064fGV+SGIFySjCKpqjcWgBAIfrAkY+4GQTJJHQMeT3V/sgz23VTEVV8TtOmkvJAhFVfg==} + + '@bundled-es-modules/tough-cookie@0.1.6': + resolution: {integrity: sha512-dvMHbL464C0zI+Yqxbz6kZ5TOEp7GLW+pry/RWndAR8MJQAXZ2rPmIs8tziTZjeIyhSNZgZbCePtfSbdWqStJw==} + '@changesets/apply-release-plan@7.0.7': resolution: {integrity: sha512-qnPOcmmmnD0MfMg9DjU1/onORFyRpDXkMMl2IJg9mECY6RnxL3wN0TCCc92b2sXt1jt8DgjAUUsZYGUGTdYIXA==} @@ -2672,6 +2684,10 @@ packages: cpu: [x64] os: [win32] + '@mswjs/interceptors@0.37.5': + resolution: {integrity: sha512-AAwRb5vXFcY4L+FvZ7LZusDuZ0vEe0Zm8ohn1FM6/X7A3bj4mqmkAcGRWuvC2JwSygNwHAAmMnAI73vPHeqsHA==} + engines: {node: '>=18'} + '@napi-rs/nice-android-arm-eabi@1.0.1': resolution: {integrity: sha512-5qpvOu5IGwDo7MEKVqqyAxF90I6aLj4n07OzpARdgDRfz8UbBztTByBp0RC59r3J1Ij8uzYi6jI7r5Lws7nn6w==} engines: {node: '>= 10'} @@ -2920,6 +2936,15 @@ packages: '@one-ini/wasm@0.1.1': resolution: {integrity: sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==} + '@open-draft/deferred-promise@2.2.0': + resolution: {integrity: sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==} + + '@open-draft/logger@0.3.0': + resolution: {integrity: sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==} + + '@open-draft/until@2.1.0': + resolution: {integrity: sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==} + '@parcel/watcher-android-arm64@2.5.0': resolution: {integrity: sha512-qlX4eS28bUcQCdribHkg/herLe+0A9RyYC+mm2PXpncit8z5b3nSqGVzMNR3CmtAOgRutiZ02eIJJgP/b1iEFQ==} engines: {node: '>= 10.0.0'} @@ -4215,6 +4240,9 @@ packages: '@types/sockjs@0.3.36': resolution: {integrity: sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==} + '@types/statuses@2.0.5': + resolution: {integrity: sha512-jmIUGWrAiwu3dZpxntxieC+1n/5c3mjrImkmOSQ2NC5uP6cYO4aAZDdSmRcI5C1oiTmqlZGHC+/NmJrKogbP5A==} + '@types/tough-cookie@4.0.5': resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==} @@ -6430,6 +6458,10 @@ packages: graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + graphql@16.10.0: + resolution: {integrity: sha512-AjqGKbDGUFRKIRCP9tCKiIGHyriz2oHEbPIbEtcSLSs4YjReZOIPQQWek4+6hjw62H9QShXHyaGivGiYVLeYFQ==} + engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} + gzip-size@7.0.0: resolution: {integrity: sha512-O1Ld7Dr+nqPnmGpdhzLmMTQ4vAsD+rHwMm1NLUmoUFFymBOMKxCCrtDxqdBRYXdeEPEi3SyoR4TizJLQrnKBNA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -6474,6 +6506,9 @@ packages: resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} hasBin: true + headers-polyfill@4.0.3: + resolution: {integrity: sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ==} + highlight.js@10.7.3: resolution: {integrity: sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==} @@ -6746,6 +6781,9 @@ packages: resolution: {integrity: sha512-tUdRRAnhT+OtCZR/LxZelH/C7QtjtFrTu5tXCA8pl55eTUElUHT+GPYV8MBMBvea/j+NxQqVt3LbWMRir7Gx9g==} engines: {node: '>=16'} + is-node-process@1.2.0: + resolution: {integrity: sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==} + is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} @@ -7493,6 +7531,16 @@ packages: msgpackr@1.11.2: resolution: {integrity: sha512-F9UngXRlPyWCDEASDpTf6c9uNhGPTqnTeLVt7bN+bU1eajoR/8V9ys2BRaV5C/e5ihE6sJ9uPIKaYt6bFuO32g==} + msw@2.7.0: + resolution: {integrity: sha512-BIodwZ19RWfCbYTxWTUfTXc+sg4OwjCAgxU1ZsgmggX/7S3LdUifsbUPJs61j0rWb19CZRGY5if77duhc0uXzw==} + engines: {node: '>=18'} + hasBin: true + peerDependencies: + typescript: '>= 4.8.x' + peerDependenciesMeta: + typescript: + optional: true + muggle-string@0.4.1: resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==} @@ -7806,6 +7854,9 @@ packages: outdent@0.5.0: resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==} + outvariant@1.4.3: + resolution: {integrity: sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==} + p-filter@2.1.0: resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==} engines: {node: '>=8'} @@ -7962,6 +8013,9 @@ packages: path-to-regexp@0.1.10: resolution: {integrity: sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==} + path-to-regexp@6.3.0: + resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} + path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} @@ -9133,6 +9187,9 @@ packages: streamx@2.21.1: resolution: {integrity: sha512-PhP9wUnFLa+91CPy3N6tiQsK+gnYyUNuk15S3YG/zjYE7RuPeCjJngqnzpC31ow0lzBHQ+QGO4cNJnd0djYUsw==} + strict-event-emitter@0.5.1: + resolution: {integrity: sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==} + string-argv@0.3.2: resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} engines: {node: '>=0.6.19'} @@ -10557,89 +10614,6 @@ snapshots: transitivePeerDependencies: - chokidar - '@angular-devkit/build-angular@19.0.6(@angular/compiler-cli@19.0.5(@angular/compiler@19.0.5(@angular/core@19.0.5(rxjs@7.8.1)(zone.js@0.15.0)))(typescript@5.5.3))(@angular/compiler@19.0.5(@angular/core@19.0.5(rxjs@7.8.1)(zone.js@0.15.0)))(@types/node@22.10.5)(chokidar@4.0.3)(karma@6.4.4)(tailwindcss@3.4.17(ts-node@10.9.2(@types/node@22.10.5)(typescript@5.5.3)))(typescript@5.5.3)(vite@5.4.11(@types/node@22.10.5)(less@4.2.0)(sass@1.80.7)(terser@5.36.0))': - dependencies: - '@ampproject/remapping': 2.3.0 - '@angular-devkit/architect': 0.1900.6(chokidar@4.0.3) - '@angular-devkit/build-webpack': 0.1900.6(chokidar@4.0.3)(webpack-dev-server@5.1.0(webpack@5.96.1(esbuild@0.24.0)))(webpack@5.96.1(esbuild@0.24.0)) - '@angular-devkit/core': 19.0.6(chokidar@4.0.3) - '@angular/build': 19.0.6(@angular/compiler-cli@19.0.5(@angular/compiler@19.0.5(@angular/core@19.0.5(rxjs@7.8.1)(zone.js@0.15.0)))(typescript@5.5.3))(@angular/compiler@19.0.5(@angular/core@19.0.5(rxjs@7.8.1)(zone.js@0.15.0)))(@types/node@22.10.5)(chokidar@4.0.3)(less@4.2.0)(postcss@8.4.49)(tailwindcss@3.4.17(ts-node@10.9.2(@types/node@22.10.5)(typescript@5.5.3)))(terser@5.36.0)(typescript@5.5.3) - '@angular/compiler-cli': 19.0.5(@angular/compiler@19.0.5(@angular/core@19.0.5(rxjs@7.8.1)(zone.js@0.15.0)))(typescript@5.5.3) - '@babel/core': 7.26.0 - '@babel/generator': 7.26.2 - '@babel/helper-annotate-as-pure': 7.25.9 - '@babel/helper-split-export-declaration': 7.24.7 - '@babel/plugin-transform-async-generator-functions': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-async-to-generator': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-runtime': 7.25.9(@babel/core@7.26.0) - '@babel/preset-env': 7.26.0(@babel/core@7.26.0) - '@babel/runtime': 7.26.0 - '@discoveryjs/json-ext': 0.6.3 - '@ngtools/webpack': 19.0.6(@angular/compiler-cli@19.0.5(@angular/compiler@19.0.5(@angular/core@19.0.5(rxjs@7.8.1)(zone.js@0.15.0)))(typescript@5.5.3))(typescript@5.5.3)(webpack@5.96.1(esbuild@0.24.0)) - '@vitejs/plugin-basic-ssl': 1.1.0(vite@5.4.11(@types/node@22.10.5)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)) - ansi-colors: 4.1.3 - autoprefixer: 10.4.20(postcss@8.4.49) - babel-loader: 9.2.1(@babel/core@7.26.0)(webpack@5.96.1(esbuild@0.24.0)) - browserslist: 4.24.4 - copy-webpack-plugin: 12.0.2(webpack@5.96.1(esbuild@0.24.0)) - css-loader: 7.1.2(webpack@5.96.1(esbuild@0.24.0)) - esbuild-wasm: 0.24.0 - fast-glob: 3.3.2 - http-proxy-middleware: 3.0.3 - istanbul-lib-instrument: 6.0.3 - jsonc-parser: 3.3.1 - karma-source-map-support: 1.4.0 - less: 4.2.0 - less-loader: 12.2.0(less@4.2.0)(webpack@5.96.1(esbuild@0.24.0)) - license-webpack-plugin: 4.0.2(webpack@5.96.1(esbuild@0.24.0)) - loader-utils: 3.3.1 - mini-css-extract-plugin: 2.9.2(webpack@5.96.1(esbuild@0.24.0)) - open: 10.1.0 - ora: 5.4.1 - picomatch: 4.0.2 - piscina: 4.7.0 - postcss: 8.4.49 - postcss-loader: 8.1.1(postcss@8.4.49)(typescript@5.5.3)(webpack@5.96.1(esbuild@0.24.0)) - resolve-url-loader: 5.0.0 - rxjs: 7.8.1 - sass: 1.80.7 - sass-loader: 16.0.3(sass@1.80.7)(webpack@5.96.1(esbuild@0.24.0)) - semver: 7.6.3 - source-map-loader: 5.0.0(webpack@5.96.1(esbuild@0.24.0)) - source-map-support: 0.5.21 - terser: 5.36.0 - tree-kill: 1.2.2 - tslib: 2.8.1 - typescript: 5.5.3 - webpack: 5.96.1(esbuild@0.24.0) - webpack-dev-middleware: 7.4.2(webpack@5.96.1(esbuild@0.24.0)) - webpack-dev-server: 5.1.0(webpack@5.96.1(esbuild@0.24.0)) - webpack-merge: 6.0.1 - webpack-subresource-integrity: 5.1.0(webpack@5.96.1(esbuild@0.24.0)) - optionalDependencies: - esbuild: 0.24.0 - karma: 6.4.4 - tailwindcss: 3.4.17(ts-node@10.9.2(@types/node@22.10.5)(typescript@5.5.3)) - transitivePeerDependencies: - - '@angular/compiler' - - '@rspack/core' - - '@swc/core' - - '@types/node' - - bufferutil - - chokidar - - debug - - html-webpack-plugin - - lightningcss - - node-sass - - sass-embedded - - stylus - - sugarss - - supports-color - - uglify-js - - utf-8-validate - - vite - - webpack-cli - '@angular-devkit/build-angular@19.0.6(@angular/compiler-cli@19.0.5(@angular/compiler@19.0.5(@angular/core@19.0.5(rxjs@7.8.1)(zone.js@0.15.0)))(typescript@5.5.3))(@angular/compiler@19.0.5(@angular/core@19.0.5(rxjs@7.8.1)(zone.js@0.15.0)))(@types/node@22.10.5)(chokidar@4.0.3)(karma@6.4.4)(tailwindcss@3.4.17(ts-node@10.9.2(@types/node@22.10.5)(typescript@5.5.3)))(typescript@5.5.3)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)(yaml@2.7.0))': dependencies: '@ampproject/remapping': 2.3.0 @@ -11661,6 +11635,19 @@ snapshots: '@bcoe/v8-coverage@0.2.3': {} + '@bundled-es-modules/cookie@2.0.1': + dependencies: + cookie: 0.7.2 + + '@bundled-es-modules/statuses@1.0.1': + dependencies: + statuses: 2.0.1 + + '@bundled-es-modules/tough-cookie@0.1.6': + dependencies: + '@types/tough-cookie': 4.0.5 + tough-cookie: 4.1.4 + '@changesets/apply-release-plan@7.0.7': dependencies: '@changesets/config': 3.0.5 @@ -12534,6 +12521,15 @@ snapshots: '@msgpackr-extract/msgpackr-extract-win32-x64@3.0.3': optional: true + '@mswjs/interceptors@0.37.5': + dependencies: + '@open-draft/deferred-promise': 2.2.0 + '@open-draft/logger': 0.3.0 + '@open-draft/until': 2.1.0 + is-node-process: 1.2.0 + outvariant: 1.4.3 + strict-event-emitter: 0.5.1 + '@napi-rs/nice-android-arm-eabi@1.0.1': optional: true @@ -12700,17 +12696,6 @@ snapshots: '@nuxt/devalue@2.0.2': {} - '@nuxt/devtools-kit@1.7.0(magicast@0.3.5)(rollup@4.31.0)(vite@5.4.11(@types/node@22.10.5)(less@4.2.0)(sass@1.80.7)(terser@5.36.0))': - dependencies: - '@nuxt/kit': 3.15.1(magicast@0.3.5)(rollup@4.31.0) - '@nuxt/schema': 3.15.1 - execa: 7.2.0 - vite: 5.4.11(@types/node@22.10.5)(less@4.2.0)(sass@1.80.7)(terser@5.36.0) - transitivePeerDependencies: - - magicast - - rollup - - supports-color - '@nuxt/devtools-kit@1.7.0(magicast@0.3.5)(rollup@4.31.0)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)(yaml@2.7.0))': dependencies: '@nuxt/kit': 3.15.1(magicast@0.3.5)(rollup@4.31.0) @@ -12735,60 +12720,13 @@ snapshots: rc9: 2.1.2 semver: 7.6.3 - '@nuxt/devtools@1.7.0(rollup@4.31.0)(vite@5.4.11(@types/node@22.10.5)(less@4.2.0)(sass@1.80.7)(terser@5.36.0))(vue@3.5.13(typescript@5.5.3))': - dependencies: - '@antfu/utils': 0.7.10 - '@nuxt/devtools-kit': 1.7.0(magicast@0.3.5)(rollup@4.31.0)(vite@5.4.11(@types/node@22.10.5)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)) - '@nuxt/devtools-wizard': 1.7.0 - '@nuxt/kit': 3.15.1(magicast@0.3.5)(rollup@4.31.0) - '@vue/devtools-core': 7.6.8(vite@5.4.11(@types/node@22.10.5)(less@4.2.0)(sass@1.80.7)(terser@5.36.0))(vue@3.5.13(typescript@5.5.3)) - '@vue/devtools-kit': 7.6.8 - birpc: 0.2.19 - consola: 3.3.3 - cronstrue: 2.52.0 - destr: 2.0.3 - error-stack-parser-es: 0.1.5 - execa: 7.2.0 - fast-npm-meta: 0.2.2 - flatted: 3.3.2 - get-port-please: 3.1.2 - hookable: 5.5.3 - image-meta: 0.2.1 - is-installed-globally: 1.0.0 - launch-editor: 2.9.1 - local-pkg: 0.5.1 - magicast: 0.3.5 - nypm: 0.4.1 - ohash: 1.1.4 - pathe: 1.1.2 - perfect-debounce: 1.0.0 - pkg-types: 1.3.0 - rc9: 2.1.2 - scule: 1.3.0 - semver: 7.6.3 - simple-git: 3.27.0 - sirv: 3.0.0 - tinyglobby: 0.2.10 - unimport: 3.14.5(rollup@4.31.0) - vite: 5.4.11(@types/node@22.10.5)(less@4.2.0)(sass@1.80.7)(terser@5.36.0) - vite-plugin-inspect: 0.8.9(@nuxt/kit@3.15.1(magicast@0.3.5)(rollup@4.31.0))(rollup@4.31.0)(vite@5.4.11(@types/node@22.10.5)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)) - vite-plugin-vue-inspector: 5.3.1(vite@5.4.11(@types/node@22.10.5)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)) - which: 3.0.1 - ws: 8.18.0 - transitivePeerDependencies: - - bufferutil - - rollup - - supports-color - - utf-8-validate - - vue - - '@nuxt/devtools@1.7.0(rollup@4.31.0)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)(yaml@2.7.0))(vue@3.5.13(typescript@5.6.1-rc))': + '@nuxt/devtools@1.7.0(rollup@4.31.0)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)(yaml@2.7.0))(vue@3.5.13(typescript@5.5.3))': dependencies: '@antfu/utils': 0.7.10 '@nuxt/devtools-kit': 1.7.0(magicast@0.3.5)(rollup@4.31.0)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)(yaml@2.7.0)) '@nuxt/devtools-wizard': 1.7.0 '@nuxt/kit': 3.15.1(magicast@0.3.5)(rollup@4.31.0) - '@vue/devtools-core': 7.6.8(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)(yaml@2.7.0))(vue@3.5.13(typescript@5.6.1-rc)) + '@vue/devtools-core': 7.6.8(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)(yaml@2.7.0))(vue@3.5.13(typescript@5.5.3)) '@vue/devtools-kit': 7.6.8 birpc: 0.2.19 consola: 3.3.3 @@ -12829,52 +12767,6 @@ snapshots: - utf-8-validate - vue - '@nuxt/devtools@1.7.0(rollup@4.31.0)(vue@3.5.13(typescript@5.6.1-rc))': - dependencies: - '@antfu/utils': 0.7.10 - '@nuxt/devtools-kit': 1.7.0(magicast@0.3.5)(rollup@4.31.0)(vite@5.4.11(@types/node@22.10.5)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)) - '@nuxt/devtools-wizard': 1.7.0 - '@nuxt/kit': 3.15.1(magicast@0.3.5)(rollup@4.31.0) - '@vue/devtools-core': 7.6.8(vue@3.5.13(typescript@5.6.1-rc)) - '@vue/devtools-kit': 7.6.8 - birpc: 0.2.19 - consola: 3.3.3 - cronstrue: 2.52.0 - destr: 2.0.3 - error-stack-parser-es: 0.1.5 - execa: 7.2.0 - fast-npm-meta: 0.2.2 - flatted: 3.3.2 - get-port-please: 3.1.2 - hookable: 5.5.3 - image-meta: 0.2.1 - is-installed-globally: 1.0.0 - launch-editor: 2.9.1 - local-pkg: 0.5.1 - magicast: 0.3.5 - nypm: 0.4.1 - ohash: 1.1.4 - pathe: 1.1.2 - perfect-debounce: 1.0.0 - pkg-types: 1.3.0 - rc9: 2.1.2 - scule: 1.3.0 - semver: 7.6.3 - simple-git: 3.27.0 - sirv: 3.0.0 - tinyglobby: 0.2.10 - unimport: 3.14.5(rollup@4.31.0) - vite-plugin-inspect: 0.8.9(@nuxt/kit@3.15.1(magicast@0.3.5)(rollup@4.31.0))(rollup@4.31.0)(vite@5.4.11(@types/node@22.10.5)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)) - vite-plugin-vue-inspector: 5.3.1(vite@5.4.11(@types/node@22.10.5)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)) - which: 3.0.1 - ws: 8.18.0 - transitivePeerDependencies: - - bufferutil - - rollup - - supports-color - - utf-8-validate - - vue - '@nuxt/kit@3.15.1(magicast@0.3.5)(rollup@4.31.0)': dependencies: '@nuxt/schema': 3.15.1 @@ -12929,7 +12821,7 @@ snapshots: - rollup - supports-color - '@nuxt/test-utils@3.15.1(@types/node@22.10.5)(@vue/test-utils@2.4.6)(jsdom@24.1.0)(less@4.2.0)(magicast@0.3.5)(rollup@4.31.0)(sass@1.80.7)(terser@5.36.0)(typescript@5.6.1-rc)(vitest@1.6.0(@types/node@22.10.5)(jsdom@24.1.0)(less@4.2.0)(sass@1.80.7)(terser@5.36.0))': + '@nuxt/test-utils@3.15.1(@types/node@22.10.5)(@vue/test-utils@2.4.6)(jsdom@24.1.0)(less@4.2.0)(magicast@0.3.5)(rollup@4.31.0)(sass@1.80.7)(terser@5.36.0)(typescript@5.5.3)(vitest@1.6.0(@types/node@22.10.5)(jsdom@24.1.0)(less@4.2.0)(sass@1.80.7)(terser@5.36.0))': dependencies: '@nuxt/kit': 3.15.1(magicast@0.3.5)(rollup@4.31.0) '@nuxt/schema': 3.15.1 @@ -12955,8 +12847,8 @@ snapshots: unenv: 1.10.0 unplugin: 2.1.2 vite: 5.4.11(@types/node@22.10.5)(less@4.2.0)(sass@1.80.7)(terser@5.36.0) - vitest-environment-nuxt: 1.0.1(@types/node@22.10.5)(@vue/test-utils@2.4.6)(jsdom@24.1.0)(less@4.2.0)(magicast@0.3.5)(rollup@4.31.0)(sass@1.80.7)(terser@5.36.0)(typescript@5.6.1-rc)(vitest@1.6.0(@types/node@22.10.5)(jsdom@24.1.0)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)) - vue: 3.5.13(typescript@5.6.1-rc) + vitest-environment-nuxt: 1.0.1(@types/node@22.10.5)(@vue/test-utils@2.4.6)(jsdom@24.1.0)(less@4.2.0)(magicast@0.3.5)(rollup@4.31.0)(sass@1.80.7)(terser@5.36.0)(typescript@5.5.3)(vitest@1.6.0(@types/node@22.10.5)(jsdom@24.1.0)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)) + vue: 3.5.13(typescript@5.5.3) optionalDependencies: '@vue/test-utils': 2.4.6 jsdom: 24.1.0 @@ -13034,66 +12926,16 @@ snapshots: - vue-tsc - yaml - '@nuxt/vite-builder@3.15.1(@types/node@22.10.5)(eslint@9.17.0(jiti@2.4.2))(less@4.2.0)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.31.0)(sass@1.80.7)(terser@5.36.0)(typescript@5.6.1-rc)(vue@3.5.13(typescript@5.6.1-rc))(yaml@2.7.0)': + '@one-ini/wasm@0.1.1': {} + + '@open-draft/deferred-promise@2.2.0': {} + + '@open-draft/logger@0.3.0': dependencies: - '@nuxt/kit': 3.15.1(magicast@0.3.5)(rollup@4.31.0) - '@rollup/plugin-replace': 6.0.2(rollup@4.31.0) - '@vitejs/plugin-vue': 5.2.1(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)(yaml@2.7.0))(vue@3.5.13(typescript@5.6.1-rc)) - '@vitejs/plugin-vue-jsx': 4.1.1(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)(yaml@2.7.0))(vue@3.5.13(typescript@5.6.1-rc)) - autoprefixer: 10.4.20(postcss@8.4.49) - consola: 3.3.3 - cssnano: 7.0.6(postcss@8.4.49) - defu: 6.1.4 - esbuild: 0.24.2 - escape-string-regexp: 5.0.0 - externality: 1.0.2 - get-port-please: 3.1.2 - h3: 1.13.1 - jiti: 2.4.2 - knitwork: 1.2.0 - magic-string: 0.30.17 - mlly: 1.7.3 - ohash: 1.1.4 - pathe: 2.0.1 - perfect-debounce: 1.0.0 - pkg-types: 1.3.0 - postcss: 8.4.49 - rollup-plugin-visualizer: 5.14.0(rollup@4.31.0) - std-env: 3.8.0 - ufo: 1.5.4 - unenv: 1.10.0 - unplugin: 2.1.2 - vite: 6.0.7(@types/node@22.10.5)(jiti@2.4.2)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)(yaml@2.7.0) - vite-node: 2.1.8(@types/node@22.10.5)(less@4.2.0)(sass@1.80.7)(terser@5.36.0) - vite-plugin-checker: 0.8.0(eslint@9.17.0(jiti@2.4.2))(optionator@0.9.4)(typescript@5.6.1-rc)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)(yaml@2.7.0)) - vue: 3.5.13(typescript@5.6.1-rc) - vue-bundle-renderer: 2.1.1 - transitivePeerDependencies: - - '@biomejs/biome' - - '@types/node' - - eslint - - less - - lightningcss - - magicast - - meow - - optionator - - rolldown - - rollup - - sass - - sass-embedded - - stylelint - - stylus - - sugarss - - supports-color - - terser - - tsx - - typescript - - vls - - vti - - vue-tsc - - yaml + is-node-process: 1.2.0 + outvariant: 1.4.3 - '@one-ini/wasm@0.1.1': {} + '@open-draft/until@2.1.0': {} '@parcel/watcher-android-arm64@2.5.0': optional: true @@ -14421,6 +14263,8 @@ snapshots: dependencies: '@types/node': 22.10.5 + '@types/statuses@2.0.5': {} + '@types/tough-cookie@4.0.5': {} '@types/unist@3.0.3': {} @@ -14718,14 +14562,6 @@ snapshots: unhead: 1.11.15 vue: 3.5.13(typescript@5.5.3) - '@unhead/vue@1.11.15(vue@3.5.13(typescript@5.6.1-rc))': - dependencies: - '@unhead/schema': 1.11.15 - '@unhead/shared': 1.11.15 - hookable: 5.5.3 - unhead: 1.11.15 - vue: 3.5.13(typescript@5.6.1-rc) - '@vercel/nft@0.27.10(encoding@0.1.13)(rollup@4.31.0)': dependencies: '@mapbox/node-pre-gyp': 2.0.0-rc.0(encoding@0.1.13) @@ -14774,16 +14610,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@vitejs/plugin-vue-jsx@4.1.1(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)(yaml@2.7.0))(vue@3.5.13(typescript@5.6.1-rc))': - dependencies: - '@babel/core': 7.26.0 - '@babel/plugin-transform-typescript': 7.26.3(@babel/core@7.26.0) - '@vue/babel-plugin-jsx': 1.2.5(@babel/core@7.26.0) - vite: 6.0.7(@types/node@22.10.5)(jiti@2.4.2)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)(yaml@2.7.0) - vue: 3.5.13(typescript@5.6.1-rc) - transitivePeerDependencies: - - supports-color - '@vitejs/plugin-vue@5.0.5(vite@5.4.6(@types/node@22.10.5)(less@4.2.0)(sass@1.80.7)(terser@5.36.0))(vue@3.5.13(typescript@5.5.3))': dependencies: vite: 5.4.6(@types/node@22.10.5)(less@4.2.0)(sass@1.80.7)(terser@5.36.0) @@ -14794,11 +14620,6 @@ snapshots: vite: 6.0.7(@types/node@22.10.5)(jiti@2.4.2)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)(yaml@2.7.0) vue: 3.5.13(typescript@5.5.3) - '@vitejs/plugin-vue@5.2.1(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)(yaml@2.7.0))(vue@3.5.13(typescript@5.6.1-rc))': - dependencies: - vite: 6.0.7(@types/node@22.10.5)(jiti@2.4.2)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)(yaml@2.7.0) - vue: 3.5.13(typescript@5.6.1-rc) - '@vitest/coverage-v8@1.6.0(vitest@1.6.0(@types/node@22.10.5)(jsdom@24.1.0)(less@4.2.0)(sass@1.80.7)(terser@5.36.0))': dependencies: '@ampproject/remapping': 2.3.0 @@ -14872,19 +14693,6 @@ snapshots: transitivePeerDependencies: - rollup - '@vue-macros/common@1.15.1(rollup@4.31.0)(vue@3.5.13(typescript@5.6.1-rc))': - dependencies: - '@babel/types': 7.26.3 - '@rollup/pluginutils': 5.1.4(rollup@4.31.0) - '@vue/compiler-sfc': 3.5.13 - ast-kit: 1.3.2 - local-pkg: 0.5.1 - magic-string-ast: 0.6.3 - optionalDependencies: - vue: 3.5.13(typescript@5.6.1-rc) - transitivePeerDependencies: - - rollup - '@vue/babel-helper-vue-transform-on@1.2.5': {} '@vue/babel-plugin-jsx@1.2.5(@babel/core@7.26.0)': @@ -14956,19 +14764,7 @@ snapshots: dependencies: '@vue/devtools-kit': 7.7.0 - '@vue/devtools-core@7.6.8(vite@5.4.11(@types/node@22.10.5)(less@4.2.0)(sass@1.80.7)(terser@5.36.0))(vue@3.5.13(typescript@5.5.3))': - dependencies: - '@vue/devtools-kit': 7.7.0 - '@vue/devtools-shared': 7.7.0 - mitt: 3.0.1 - nanoid: 5.0.9 - pathe: 1.1.2 - vite-hot-client: 0.2.4(vite@5.4.11(@types/node@22.10.5)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)) - vue: 3.5.13(typescript@5.5.3) - transitivePeerDependencies: - - vite - - '@vue/devtools-core@7.6.8(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)(yaml@2.7.0))(vue@3.5.13(typescript@5.6.1-rc))': + '@vue/devtools-core@7.6.8(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)(yaml@2.7.0))(vue@3.5.13(typescript@5.5.3))': dependencies: '@vue/devtools-kit': 7.7.0 '@vue/devtools-shared': 7.7.0 @@ -14976,19 +14772,7 @@ snapshots: nanoid: 5.0.9 pathe: 1.1.2 vite-hot-client: 0.2.4(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)(yaml@2.7.0)) - vue: 3.5.13(typescript@5.6.1-rc) - transitivePeerDependencies: - - vite - - '@vue/devtools-core@7.6.8(vue@3.5.13(typescript@5.6.1-rc))': - dependencies: - '@vue/devtools-kit': 7.7.0 - '@vue/devtools-shared': 7.7.0 - mitt: 3.0.1 - nanoid: 5.0.9 - pathe: 1.1.2 - vite-hot-client: 0.2.4(vite@5.4.11(@types/node@22.10.5)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)) - vue: 3.5.13(typescript@5.6.1-rc) + vue: 3.5.13(typescript@5.5.3) transitivePeerDependencies: - vite @@ -15084,12 +14868,6 @@ snapshots: '@vue/shared': 3.5.13 vue: 3.5.13(typescript@5.5.3) - '@vue/server-renderer@3.5.13(vue@3.5.13(typescript@5.6.1-rc))': - dependencies: - '@vue/compiler-ssr': 3.5.13 - '@vue/shared': 3.5.13 - vue: 3.5.13(typescript@5.6.1-rc) - '@vue/shared@3.5.13': {} '@vue/test-utils@2.4.6': @@ -17155,6 +16933,8 @@ snapshots: graphemer@1.4.0: {} + graphql@16.10.0: {} + gzip-size@7.0.0: dependencies: duplexer: 0.1.2 @@ -17228,6 +17008,8 @@ snapshots: he@1.2.0: {} + headers-polyfill@4.0.3: {} + highlight.js@10.7.3: {} hookable@5.5.3: {} @@ -17486,6 +17268,8 @@ snapshots: is-network-error@1.1.0: {} + is-node-process@1.2.0: {} + is-number@7.0.0: {} is-path-inside@4.0.0: {} @@ -18305,6 +18089,31 @@ snapshots: msgpackr-extract: 3.0.3 optional: true + msw@2.7.0(@types/node@22.10.5)(typescript@5.5.3): + dependencies: + '@bundled-es-modules/cookie': 2.0.1 + '@bundled-es-modules/statuses': 1.0.1 + '@bundled-es-modules/tough-cookie': 0.1.6 + '@inquirer/confirm': 5.1.1(@types/node@22.10.5) + '@mswjs/interceptors': 0.37.5 + '@open-draft/deferred-promise': 2.2.0 + '@open-draft/until': 2.1.0 + '@types/cookie': 0.6.0 + '@types/statuses': 2.0.5 + graphql: 16.10.0 + headers-polyfill: 4.0.3 + is-node-process: 1.2.0 + outvariant: 1.4.3 + path-to-regexp: 6.3.0 + picocolors: 1.1.1 + strict-event-emitter: 0.5.1 + type-fest: 4.32.0 + yargs: 17.7.2 + optionalDependencies: + typescript: 5.5.3 + transitivePeerDependencies: + - '@types/node' + muggle-string@0.4.1: {} multicast-dns@7.2.5: @@ -18445,103 +18254,6 @@ snapshots: - typescript - uploadthing - nitropack@2.10.4(encoding@0.1.13)(typescript@5.6.1-rc): - dependencies: - '@cloudflare/kv-asset-handler': 0.3.4 - '@netlify/functions': 2.8.2 - '@rollup/plugin-alias': 5.1.1(rollup@4.31.0) - '@rollup/plugin-commonjs': 28.0.2(rollup@4.31.0) - '@rollup/plugin-inject': 5.0.5(rollup@4.31.0) - '@rollup/plugin-json': 6.1.0(rollup@4.31.0) - '@rollup/plugin-node-resolve': 15.3.1(rollup@4.31.0) - '@rollup/plugin-replace': 6.0.2(rollup@4.31.0) - '@rollup/plugin-terser': 0.4.4(rollup@4.31.0) - '@rollup/pluginutils': 5.1.4(rollup@4.31.0) - '@types/http-proxy': 1.17.15 - '@vercel/nft': 0.27.10(encoding@0.1.13)(rollup@4.31.0) - archiver: 7.0.1 - c12: 2.0.1(magicast@0.3.5) - chokidar: 3.6.0 - citty: 0.1.6 - compatx: 0.1.8 - confbox: 0.1.8 - consola: 3.3.3 - cookie-es: 1.2.2 - croner: 9.0.0 - crossws: 0.3.1 - db0: 0.2.1 - defu: 6.1.4 - destr: 2.0.3 - dot-prop: 9.0.0 - esbuild: 0.24.2 - escape-string-regexp: 5.0.0 - etag: 1.8.1 - fs-extra: 11.2.0 - globby: 14.0.2 - gzip-size: 7.0.0 - h3: 1.13.1 - hookable: 5.5.3 - httpxy: 0.1.5 - ioredis: 5.4.2 - jiti: 2.4.2 - klona: 2.0.6 - knitwork: 1.2.0 - listhen: 1.9.0 - magic-string: 0.30.17 - magicast: 0.3.5 - mime: 4.0.6 - mlly: 1.7.3 - node-fetch-native: 1.6.4 - ofetch: 1.4.1 - ohash: 1.1.4 - openapi-typescript: 7.5.2(encoding@0.1.13)(typescript@5.6.1-rc) - pathe: 1.1.2 - perfect-debounce: 1.0.0 - pkg-types: 1.3.0 - pretty-bytes: 6.1.1 - radix3: 1.1.2 - rollup: 4.31.0 - rollup-plugin-visualizer: 5.14.0(rollup@4.31.0) - scule: 1.3.0 - semver: 7.6.3 - serve-placeholder: 2.0.2 - serve-static: 1.16.2 - std-env: 3.8.0 - ufo: 1.5.4 - uncrypto: 0.1.3 - unctx: 2.4.1 - unenv: 1.10.0 - unimport: 3.14.5(rollup@4.31.0) - unstorage: 1.14.4(db0@0.2.1)(ioredis@5.4.2) - untyped: 1.5.2 - unwasm: 0.3.9 - transitivePeerDependencies: - - '@azure/app-configuration' - - '@azure/cosmos' - - '@azure/data-tables' - - '@azure/identity' - - '@azure/keyvault-secrets' - - '@azure/storage-blob' - - '@capacitor/preferences' - - '@deno/kv' - - '@electric-sql/pglite' - - '@libsql/client' - - '@netlify/blobs' - - '@planetscale/database' - - '@upstash/redis' - - '@vercel/blob' - - '@vercel/kv' - - aws4fetch - - better-sqlite3 - - drizzle-orm - - encoding - - idb-keyval - - mysql2 - - rolldown - - supports-color - - typescript - - uploadthing - node-addon-api@6.1.0: optional: true @@ -18686,10 +18398,10 @@ snapshots: nuxi@3.19.1: {} - nuxt@3.15.1(@parcel/watcher@2.5.0)(@types/node@22.10.5)(db0@0.2.1)(encoding@0.1.13)(eslint@9.17.0(jiti@2.4.2))(ioredis@5.4.2)(less@4.2.0)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.31.0)(sass@1.80.7)(terser@5.36.0)(typescript@5.5.3)(vite@5.4.11(@types/node@22.10.5)(less@4.2.0)(sass@1.80.7)(terser@5.36.0))(yaml@2.7.0): + nuxt@3.15.1(@parcel/watcher@2.5.0)(@types/node@22.10.5)(db0@0.2.1)(encoding@0.1.13)(eslint@9.17.0(jiti@2.4.2))(ioredis@5.4.2)(less@4.2.0)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.31.0)(sass@1.80.7)(terser@5.36.0)(typescript@5.5.3)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)(yaml@2.7.0))(yaml@2.7.0): dependencies: '@nuxt/devalue': 2.0.2 - '@nuxt/devtools': 1.7.0(rollup@4.31.0)(vite@5.4.11(@types/node@22.10.5)(less@4.2.0)(sass@1.80.7)(terser@5.36.0))(vue@3.5.13(typescript@5.5.3)) + '@nuxt/devtools': 1.7.0(rollup@4.31.0)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)(yaml@2.7.0))(vue@3.5.13(typescript@5.5.3)) '@nuxt/kit': 3.15.1(magicast@0.3.5)(rollup@4.31.0) '@nuxt/schema': 3.15.1 '@nuxt/telemetry': 2.6.4(magicast@0.3.5)(rollup@4.31.0) @@ -18807,248 +18519,6 @@ snapshots: - xml2js - yaml - nuxt@3.15.1(@parcel/watcher@2.5.0)(@types/node@22.10.5)(db0@0.2.1)(encoding@0.1.13)(eslint@9.17.0(jiti@2.4.2))(ioredis@5.4.2)(less@4.2.0)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.31.0)(sass@1.80.7)(terser@5.36.0)(typescript@5.6.1-rc)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)(yaml@2.7.0))(yaml@2.7.0): - dependencies: - '@nuxt/devalue': 2.0.2 - '@nuxt/devtools': 1.7.0(rollup@4.31.0)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)(yaml@2.7.0))(vue@3.5.13(typescript@5.6.1-rc)) - '@nuxt/kit': 3.15.1(magicast@0.3.5)(rollup@4.31.0) - '@nuxt/schema': 3.15.1 - '@nuxt/telemetry': 2.6.4(magicast@0.3.5)(rollup@4.31.0) - '@nuxt/vite-builder': 3.15.1(@types/node@22.10.5)(eslint@9.17.0(jiti@2.4.2))(less@4.2.0)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.31.0)(sass@1.80.7)(terser@5.36.0)(typescript@5.6.1-rc)(vue@3.5.13(typescript@5.6.1-rc))(yaml@2.7.0) - '@unhead/dom': 1.11.15 - '@unhead/shared': 1.11.15 - '@unhead/ssr': 1.11.15 - '@unhead/vue': 1.11.15(vue@3.5.13(typescript@5.6.1-rc)) - '@vue/shared': 3.5.13 - acorn: 8.14.0 - c12: 2.0.1(magicast@0.3.5) - chokidar: 4.0.3 - compatx: 0.1.8 - consola: 3.3.3 - cookie-es: 1.2.2 - defu: 6.1.4 - destr: 2.0.3 - devalue: 5.1.1 - errx: 0.1.0 - esbuild: 0.24.2 - escape-string-regexp: 5.0.0 - estree-walker: 3.0.3 - globby: 14.0.2 - h3: 1.13.1 - hookable: 5.5.3 - ignore: 7.0.0 - impound: 0.2.0(rollup@4.31.0) - jiti: 2.4.2 - klona: 2.0.6 - knitwork: 1.2.0 - magic-string: 0.30.17 - mlly: 1.7.3 - nanotar: 0.1.1 - nitropack: 2.10.4(encoding@0.1.13)(typescript@5.6.1-rc) - nuxi: 3.19.1 - nypm: 0.4.1 - ofetch: 1.4.1 - ohash: 1.1.4 - pathe: 2.0.1 - perfect-debounce: 1.0.0 - pkg-types: 1.3.0 - radix3: 1.1.2 - scule: 1.3.0 - semver: 7.6.3 - std-env: 3.8.0 - strip-literal: 2.1.1 - tinyglobby: 0.2.10 - ufo: 1.5.4 - ultrahtml: 1.5.3 - uncrypto: 0.1.3 - unctx: 2.4.1 - unenv: 1.10.0 - unhead: 1.11.15 - unimport: 3.14.5(rollup@4.31.0) - unplugin: 2.1.2 - unplugin-vue-router: 0.10.9(rollup@4.31.0)(vue-router@4.5.0(vue@3.5.13(typescript@5.6.1-rc)))(vue@3.5.13(typescript@5.6.1-rc)) - unstorage: 1.14.4(db0@0.2.1)(ioredis@5.4.2) - untyped: 1.5.2 - vue: 3.5.13(typescript@5.6.1-rc) - vue-bundle-renderer: 2.1.1 - vue-devtools-stub: 0.1.0 - vue-router: 4.5.0(vue@3.5.13(typescript@5.6.1-rc)) - optionalDependencies: - '@parcel/watcher': 2.5.0 - '@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/kv' - - aws4fetch - - better-sqlite3 - - bufferutil - - db0 - - drizzle-orm - - encoding - - eslint - - idb-keyval - - ioredis - - less - - lightningcss - - magicast - - meow - - mysql2 - - optionator - - rolldown - - rollup - - sass - - sass-embedded - - stylelint - - stylus - - sugarss - - supports-color - - terser - - tsx - - typescript - - uploadthing - - utf-8-validate - - vite - - vls - - vti - - vue-tsc - - xml2js - - yaml - - nuxt@3.15.1(@parcel/watcher@2.5.0)(@types/node@22.10.5)(db0@0.2.1)(encoding@0.1.13)(eslint@9.17.0(jiti@2.4.2))(ioredis@5.4.2)(less@4.2.0)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.31.0)(sass@1.80.7)(terser@5.36.0)(typescript@5.6.1-rc)(yaml@2.7.0): - dependencies: - '@nuxt/devalue': 2.0.2 - '@nuxt/devtools': 1.7.0(rollup@4.31.0)(vue@3.5.13(typescript@5.6.1-rc)) - '@nuxt/kit': 3.15.1(magicast@0.3.5)(rollup@4.31.0) - '@nuxt/schema': 3.15.1 - '@nuxt/telemetry': 2.6.4(magicast@0.3.5)(rollup@4.31.0) - '@nuxt/vite-builder': 3.15.1(@types/node@22.10.5)(eslint@9.17.0(jiti@2.4.2))(less@4.2.0)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.31.0)(sass@1.80.7)(terser@5.36.0)(typescript@5.6.1-rc)(vue@3.5.13(typescript@5.6.1-rc))(yaml@2.7.0) - '@unhead/dom': 1.11.15 - '@unhead/shared': 1.11.15 - '@unhead/ssr': 1.11.15 - '@unhead/vue': 1.11.15(vue@3.5.13(typescript@5.6.1-rc)) - '@vue/shared': 3.5.13 - acorn: 8.14.0 - c12: 2.0.1(magicast@0.3.5) - chokidar: 4.0.3 - compatx: 0.1.8 - consola: 3.3.3 - cookie-es: 1.2.2 - defu: 6.1.4 - destr: 2.0.3 - devalue: 5.1.1 - errx: 0.1.0 - esbuild: 0.24.2 - escape-string-regexp: 5.0.0 - estree-walker: 3.0.3 - globby: 14.0.2 - h3: 1.13.1 - hookable: 5.5.3 - ignore: 7.0.0 - impound: 0.2.0(rollup@4.31.0) - jiti: 2.4.2 - klona: 2.0.6 - knitwork: 1.2.0 - magic-string: 0.30.17 - mlly: 1.7.3 - nanotar: 0.1.1 - nitropack: 2.10.4(encoding@0.1.13)(typescript@5.6.1-rc) - nuxi: 3.19.1 - nypm: 0.4.1 - ofetch: 1.4.1 - ohash: 1.1.4 - pathe: 2.0.1 - perfect-debounce: 1.0.0 - pkg-types: 1.3.0 - radix3: 1.1.2 - scule: 1.3.0 - semver: 7.6.3 - std-env: 3.8.0 - strip-literal: 2.1.1 - tinyglobby: 0.2.10 - ufo: 1.5.4 - ultrahtml: 1.5.3 - uncrypto: 0.1.3 - unctx: 2.4.1 - unenv: 1.10.0 - unhead: 1.11.15 - unimport: 3.14.5(rollup@4.31.0) - unplugin: 2.1.2 - unplugin-vue-router: 0.10.9(rollup@4.31.0)(vue-router@4.5.0(vue@3.5.13(typescript@5.6.1-rc)))(vue@3.5.13(typescript@5.6.1-rc)) - unstorage: 1.14.4(db0@0.2.1)(ioredis@5.4.2) - untyped: 1.5.2 - vue: 3.5.13(typescript@5.6.1-rc) - vue-bundle-renderer: 2.1.1 - vue-devtools-stub: 0.1.0 - vue-router: 4.5.0(vue@3.5.13(typescript@5.6.1-rc)) - optionalDependencies: - '@parcel/watcher': 2.5.0 - '@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/kv' - - aws4fetch - - better-sqlite3 - - bufferutil - - db0 - - drizzle-orm - - encoding - - eslint - - idb-keyval - - ioredis - - less - - lightningcss - - magicast - - meow - - mysql2 - - optionator - - rolldown - - rollup - - sass - - sass-embedded - - stylelint - - stylus - - sugarss - - supports-color - - terser - - tsx - - typescript - - uploadthing - - utf-8-validate - - vite - - vls - - vti - - vue-tsc - - xml2js - - yaml - nwsapi@2.2.16: {} nypm@0.3.12: @@ -19144,18 +18614,6 @@ snapshots: transitivePeerDependencies: - encoding - openapi-typescript@7.5.2(encoding@0.1.13)(typescript@5.6.1-rc): - dependencies: - '@redocly/openapi-core': 1.27.1(encoding@0.1.13)(supports-color@9.4.0) - ansi-colors: 4.1.3 - change-case: 5.4.4 - parse-json: 8.1.0 - supports-color: 9.4.0 - typescript: 5.6.1-rc - yargs-parser: 21.1.1 - transitivePeerDependencies: - - encoding - optionator@0.9.4: dependencies: deep-is: 0.1.4 @@ -19184,6 +18642,8 @@ snapshots: outdent@0.5.0: {} + outvariant@1.4.3: {} + p-filter@2.1.0: dependencies: p-map: 2.1.0 @@ -19355,6 +18815,8 @@ snapshots: path-to-regexp@0.1.10: {} + path-to-regexp@6.3.0: {} + path-type@4.0.0: {} path-type@5.0.0: {} @@ -20630,6 +20092,8 @@ snapshots: optionalDependencies: bare-events: 2.5.3 + strict-event-emitter@0.5.1: {} + string-argv@0.3.2: {} string-width@4.2.3: @@ -21287,28 +20751,6 @@ snapshots: - rollup - vue - unplugin-vue-router@0.10.9(rollup@4.31.0)(vue-router@4.5.0(vue@3.5.13(typescript@5.6.1-rc)))(vue@3.5.13(typescript@5.6.1-rc)): - dependencies: - '@babel/types': 7.26.3 - '@rollup/pluginutils': 5.1.4(rollup@4.31.0) - '@vue-macros/common': 1.15.1(rollup@4.31.0)(vue@3.5.13(typescript@5.6.1-rc)) - ast-walker-scope: 0.6.2 - chokidar: 3.6.0 - fast-glob: 3.3.3 - json5: 2.2.3 - local-pkg: 0.5.1 - magic-string: 0.30.17 - mlly: 1.7.3 - pathe: 1.1.2 - scule: 1.3.0 - unplugin: 2.0.0-beta.1 - yaml: 2.7.0 - optionalDependencies: - vue-router: 4.5.0(vue@3.5.13(typescript@5.6.1-rc)) - transitivePeerDependencies: - - rollup - - vue - unplugin@1.16.1: dependencies: acorn: 8.14.0 @@ -21433,10 +20875,6 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.2 - vite-hot-client@0.2.4(vite@5.4.11(@types/node@22.10.5)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)): - dependencies: - vite: 5.4.11(@types/node@22.10.5)(less@4.2.0)(sass@1.80.7)(terser@5.36.0) - vite-hot-client@0.2.4(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)(yaml@2.7.0)): dependencies: vite: 6.0.7(@types/node@22.10.5)(jiti@2.4.2)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)(yaml@2.7.0) @@ -21499,46 +20937,6 @@ snapshots: optionator: 0.9.4 typescript: 5.5.3 - vite-plugin-checker@0.8.0(eslint@9.17.0(jiti@2.4.2))(optionator@0.9.4)(typescript@5.6.1-rc)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)(yaml@2.7.0)): - dependencies: - '@babel/code-frame': 7.26.2 - ansi-escapes: 4.3.2 - chalk: 4.1.2 - chokidar: 3.6.0 - commander: 8.3.0 - fast-glob: 3.3.3 - fs-extra: 11.2.0 - npm-run-path: 4.0.1 - strip-ansi: 6.0.1 - tiny-invariant: 1.3.3 - vite: 6.0.7(@types/node@22.10.5)(jiti@2.4.2)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)(yaml@2.7.0) - vscode-languageclient: 7.0.0 - vscode-languageserver: 7.0.0 - vscode-languageserver-textdocument: 1.0.12 - vscode-uri: 3.0.8 - optionalDependencies: - eslint: 9.17.0(jiti@2.4.2) - optionator: 0.9.4 - typescript: 5.6.1-rc - - vite-plugin-inspect@0.8.9(@nuxt/kit@3.15.1(magicast@0.3.5)(rollup@4.31.0))(rollup@4.31.0)(vite@5.4.11(@types/node@22.10.5)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)): - dependencies: - '@antfu/utils': 0.7.10 - '@rollup/pluginutils': 5.1.4(rollup@4.31.0) - debug: 4.4.0(supports-color@9.4.0) - error-stack-parser-es: 0.1.5 - fs-extra: 11.2.0 - open: 10.1.0 - perfect-debounce: 1.0.0 - picocolors: 1.1.1 - sirv: 3.0.0 - vite: 5.4.11(@types/node@22.10.5)(less@4.2.0)(sass@1.80.7)(terser@5.36.0) - optionalDependencies: - '@nuxt/kit': 3.15.1(magicast@0.3.5)(rollup@4.31.0) - transitivePeerDependencies: - - rollup - - supports-color - vite-plugin-inspect@0.8.9(@nuxt/kit@3.15.1(magicast@0.3.5)(rollup@4.31.0))(rollup@4.31.0)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)(yaml@2.7.0)): dependencies: '@antfu/utils': 0.7.10 @@ -21573,21 +20971,6 @@ snapshots: - supports-color - vue - vite-plugin-vue-inspector@5.3.1(vite@5.4.11(@types/node@22.10.5)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)): - dependencies: - '@babel/core': 7.26.0 - '@babel/plugin-proposal-decorators': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-syntax-import-attributes': 7.26.0(@babel/core@7.26.0) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.26.0) - '@babel/plugin-transform-typescript': 7.26.3(@babel/core@7.26.0) - '@vue/babel-plugin-jsx': 1.2.5(@babel/core@7.26.0) - '@vue/compiler-dom': 3.5.13 - kolorist: 1.8.0 - magic-string: 0.30.17 - vite: 5.4.11(@types/node@22.10.5)(less@4.2.0)(sass@1.80.7)(terser@5.36.0) - transitivePeerDependencies: - - supports-color - vite-plugin-vue-inspector@5.3.1(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)(yaml@2.7.0)): dependencies: '@babel/core': 7.26.0 @@ -21693,9 +21076,9 @@ snapshots: - typescript - universal-cookie - vitest-environment-nuxt@1.0.1(@types/node@22.10.5)(@vue/test-utils@2.4.6)(jsdom@24.1.0)(less@4.2.0)(magicast@0.3.5)(rollup@4.31.0)(sass@1.80.7)(terser@5.36.0)(typescript@5.6.1-rc)(vitest@1.6.0(@types/node@22.10.5)(jsdom@24.1.0)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)): + vitest-environment-nuxt@1.0.1(@types/node@22.10.5)(@vue/test-utils@2.4.6)(jsdom@24.1.0)(less@4.2.0)(magicast@0.3.5)(rollup@4.31.0)(sass@1.80.7)(terser@5.36.0)(typescript@5.5.3)(vitest@1.6.0(@types/node@22.10.5)(jsdom@24.1.0)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)): dependencies: - '@nuxt/test-utils': 3.15.1(@types/node@22.10.5)(@vue/test-utils@2.4.6)(jsdom@24.1.0)(less@4.2.0)(magicast@0.3.5)(rollup@4.31.0)(sass@1.80.7)(terser@5.36.0)(typescript@5.6.1-rc)(vitest@1.6.0(@types/node@22.10.5)(jsdom@24.1.0)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)) + '@nuxt/test-utils': 3.15.1(@types/node@22.10.5)(@vue/test-utils@2.4.6)(jsdom@24.1.0)(less@4.2.0)(magicast@0.3.5)(rollup@4.31.0)(sass@1.80.7)(terser@5.36.0)(typescript@5.5.3)(vitest@1.6.0(@types/node@22.10.5)(jsdom@24.1.0)(less@4.2.0)(sass@1.80.7)(terser@5.36.0)) transitivePeerDependencies: - '@cucumber/cucumber' - '@jest/globals' @@ -21845,11 +21228,6 @@ snapshots: '@vue/devtools-api': 6.6.4 vue: 3.5.13(typescript@5.5.3) - vue-router@4.5.0(vue@3.5.13(typescript@5.6.1-rc)): - dependencies: - '@vue/devtools-api': 6.6.4 - vue: 3.5.13(typescript@5.6.1-rc) - vue-tsc@2.2.0(typescript@5.5.3): dependencies: '@volar/typescript': 2.4.11 @@ -21866,16 +21244,6 @@ snapshots: optionalDependencies: typescript: 5.5.3 - vue@3.5.13(typescript@5.6.1-rc): - dependencies: - '@vue/compiler-dom': 3.5.13 - '@vue/compiler-sfc': 3.5.13 - '@vue/runtime-dom': 3.5.13 - '@vue/server-renderer': 3.5.13(vue@3.5.13(typescript@5.6.1-rc)) - '@vue/shared': 3.5.13 - optionalDependencies: - typescript: 5.6.1-rc - w3c-xmlserializer@5.0.0: dependencies: xml-name-validator: 5.0.0 From 67d86783385efd5a911f0fc9c9088317f39f18b7 Mon Sep 17 00:00:00 2001 From: Lubos Date: Fri, 24 Jan 2025 03:37:38 +0000 Subject: [PATCH 2/2] chore: generate skeleton of msw responses --- packages/openapi-ts/src/ir/operation.ts | 1 + .../src/openApi/shared/types/schema.d.ts | 5 + .../src/plugins/@hey-api/typescript/plugin.ts | 6 +- packages/openapi-ts/src/plugins/msw/plugin.ts | 32 +++- .../openapi-ts/src/plugins/msw/response.ts | 46 ++++++ packages/openapi-ts/src/plugins/msw/schema.ts | 143 ++++++++++++++++++ packages/openapi-ts/src/plugins/zod/plugin.ts | 6 +- packages/openapi-ts/test/openapi-ts.config.ts | 4 +- 8 files changed, 224 insertions(+), 19 deletions(-) create mode 100644 packages/openapi-ts/src/plugins/msw/response.ts create mode 100644 packages/openapi-ts/src/plugins/msw/schema.ts diff --git a/packages/openapi-ts/src/ir/operation.ts b/packages/openapi-ts/src/ir/operation.ts index 17d52a769..84f14a272 100644 --- a/packages/openapi-ts/src/ir/operation.ts +++ b/packages/openapi-ts/src/ir/operation.ts @@ -97,6 +97,7 @@ interface OperationResponsesMap { responses?: IR.SchemaObject; } +// TODO: handle multiple content types export const operationResponsesMap = ( operation: IR.OperationObject, ): OperationResponsesMap => { diff --git a/packages/openapi-ts/src/openApi/shared/types/schema.d.ts b/packages/openapi-ts/src/openApi/shared/types/schema.d.ts index 5a9883043..3b4fbe168 100644 --- a/packages/openapi-ts/src/openApi/shared/types/schema.d.ts +++ b/packages/openapi-ts/src/openApi/shared/types/schema.d.ts @@ -20,6 +20,11 @@ export type SchemaWithRequired< [P in K]-?: S[P]; }; +export interface SchemaWithType['type']> + extends Omit { + type: Extract['type'], T>; +} + export type SchemaType< S extends { type?: unknown; diff --git a/packages/openapi-ts/src/plugins/@hey-api/typescript/plugin.ts b/packages/openapi-ts/src/plugins/@hey-api/typescript/plugin.ts index 074b5e71a..8b0a46b1e 100644 --- a/packages/openapi-ts/src/plugins/@hey-api/typescript/plugin.ts +++ b/packages/openapi-ts/src/plugins/@hey-api/typescript/plugin.ts @@ -5,6 +5,7 @@ import { compiler } from '../../../compiler'; import { operationResponsesMap } from '../../../ir/operation'; import { deduplicateSchema } from '../../../ir/schema'; import type { IR } from '../../../ir/types'; +import type { SchemaWithType } from '../../../openApi/shared/types/schema'; import { escapeComment } from '../../../utils/escape'; import { irRef, isRefOpenApiComponent } from '../../../utils/ref'; import { numberRegExp } from '../../../utils/regexp'; @@ -15,11 +16,6 @@ import type { Plugin } from '../../types'; import { typesId } from './ref'; import type { Config } from './types'; -interface SchemaWithType['type']> - extends Omit { - type: Extract['type'], T>; -} - const parseSchemaJsDoc = ({ schema }: { schema: IR.SchemaObject }) => { const comments = [ schema.description && escapeComment(schema.description), diff --git a/packages/openapi-ts/src/plugins/msw/plugin.ts b/packages/openapi-ts/src/plugins/msw/plugin.ts index 00abf2433..1d99e0c62 100644 --- a/packages/openapi-ts/src/plugins/msw/plugin.ts +++ b/packages/openapi-ts/src/plugins/msw/plugin.ts @@ -1,6 +1,7 @@ import type ts from 'typescript'; import { compiler } from '../../compiler'; +import type { Identifier } from '../../generate/files'; import type { IR } from '../../ir/types'; import { irRef } from '../../utils/ref'; import { stringCase } from '../../utils/stringCase'; @@ -18,6 +19,8 @@ import { responseBodyTypeTypeName, undefinedReference, } from './interfaces'; +import { getSuccessResponse, responseOptions } from './response'; +import { schemaToExpression } from './schema'; import type { Config } from './types'; export const mswId = 'msw'; @@ -25,16 +28,17 @@ export const mswId = 'msw'; const nameTransformer = (name: string) => `${name}-handler`; const resolverStatements = ({ - // context, + context, + identifierResponse, operation, }: { context: IR.Context; + identifierResponse: Identifier; operation: IR.OperationObject; }) => { const statements: Array = []; - // TODO: get any of the 2xx status codes - console.log(operation.responses); + const successResponse = getSuccessResponse(operation) const response = compiler.constVariable({ expression: compiler.callExpression({ @@ -43,11 +47,24 @@ const resolverStatements = ({ name: compiler.identifier({ text: 'json' }), }), parameters: [ - compiler.objectExpression({ - obj: [], + identifierResponse.name && successResponse?.schema ? schemaToExpression({ + context, + schema: successResponse.schema, + }) : compiler.identifier({ text: 'undefined' }), + responseOptions({ + responseSchema: successResponse, }), ], - types: [], + types: [ + identifierResponse.name ? compiler.typeReferenceNode({ + typeArguments: [ + compiler.typeReferenceNode({ + typeName: identifierResponse.name, + }), + ], + typeName: responseBodyTypeTypeName, + }) : undefinedReference, + ], }), name: 'response', }); @@ -94,7 +111,7 @@ const operationToMswHandler = ({ // TODO: add support for baseUrl/servers // replace our curly brackets with colon - const handlerPath = `*${operation.path.replace(/{([^}]+)}/g, ':$1')}`; + const handlerPath = `*${operation.path.replace(/\{(.+?)\}/g, ':$1')}`; const statement = compiler.constVariable({ exportConst: true, @@ -112,6 +129,7 @@ const operationToMswHandler = ({ ], statements: resolverStatements({ context, + identifierResponse, operation, }), }), diff --git a/packages/openapi-ts/src/plugins/msw/response.ts b/packages/openapi-ts/src/plugins/msw/response.ts new file mode 100644 index 000000000..0bad68d0e --- /dev/null +++ b/packages/openapi-ts/src/plugins/msw/response.ts @@ -0,0 +1,46 @@ +import { compiler } from "../../compiler"; +import { operationResponsesMap } from "../../ir/operation"; +import type { IR } from "../../ir/types"; + +interface ResponseSchema { + schema: IR.SchemaObject | undefined; + statusCode: string; +} + +export const getSuccessResponse = (operation: IR.OperationObject): ResponseSchema | undefined => { + const { responses } = operationResponsesMap(operation); + if (!responses?.properties) { + return; + } + const statusCode = Object.keys(responses.properties)[0] + if (!statusCode) { + return; + } + return { + schema: responses.properties[statusCode], + statusCode, + } +} + +const getResponseStatus = (statusCode: string | undefined): number => { + if (!statusCode || statusCode === '2XX') { + return 200; + } + return Number.parseInt(statusCode, 10) +} + +export const responseOptions = ({ + responseSchema, +}: { + responseSchema: ResponseSchema | undefined; +}) => { + const status = getResponseStatus(responseSchema?.statusCode) + return compiler.objectExpression({ + obj: [ + { + key: 'status', + value: status, + }, + ], + }) +} diff --git a/packages/openapi-ts/src/plugins/msw/schema.ts b/packages/openapi-ts/src/plugins/msw/schema.ts new file mode 100644 index 000000000..6dd75538a --- /dev/null +++ b/packages/openapi-ts/src/plugins/msw/schema.ts @@ -0,0 +1,143 @@ +import type ts from "typescript"; + +import { compiler } from "../../compiler"; +import type { IR } from "../../ir/types" +import type { SchemaWithRequired, SchemaWithType } from "../../openApi/shared/types/schema"; + +const arrayTypeToExpression = ({ + // eslint-disable-next-line @typescript-eslint/no-unused-vars + schema, +}: { + context: IR.Context; + schema: SchemaWithType<'array'>; +}) => { + // TODO: inject no/a few items based on argument + const elements: Array = []; + return compiler.arrayLiteralExpression({ + elements, + }) +} + +const objectTypeToExpression = ({ + context, + schema, +}: { + context: IR.Context; + schema: SchemaWithType<'object'>; +}) => { + const keys: Array = []; + for (const name in schema.properties) { + const property = schema.properties[name]! + const expression = schemaToExpression({ + context, + schema: property, + }) + keys.push({ + key: name, + value: expression, + }) + } + return compiler.objectExpression({ + obj: keys, + }) +} + +const stringTypeToExpression = ({ + schema, +}: { + context: IR.Context; + schema: SchemaWithType<'string'>; +}) => { + // TODO: handle enums, need to either set a random value or import enum if TypeScript + if (typeof schema.const === 'string') { + return compiler.ots.string(schema.const); + } + return compiler.ots.string(''); +} + +// TODO: use faker + examples +const schemaTypeToExpression = ({ + context, + schema, +}: { + context: IR.Context; + schema: SchemaWithRequired +}) => { + // TODO: handle enum and tuple + switch (schema.type) { + // TODO: handle array + case 'array': + return arrayTypeToExpression({ + context, + schema: schema as SchemaWithType<'array'>, + }) + case 'boolean': + return compiler.ots.boolean(true); + case 'integer': + case 'number': + return compiler.ots.number(0); + case 'null': + return compiler.null() + // TODO: handle object + case 'object': + return objectTypeToExpression({ + context, + schema: schema as SchemaWithType<'object'>, + }) + case 'string': + return stringTypeToExpression({ + context, + schema: schema as SchemaWithType<'string'>, + }) + case 'never': + case 'undefined': + case 'unknown': + case 'void': + default: + return compiler.identifier({ text: 'undefined' }) + } +} + +export const schemaToExpression = ({ + context, + schema, +}: { + context: IR.Context; + schema: IR.SchemaObject; +}) => { + let expression: ts.Expression; + + if (schema.$ref) { + const ref = context.resolveIrRef(schema.$ref); + expression = schemaToExpression({ + context, + schema: ref, + }) + } else if (schema.type) { + expression = schemaTypeToExpression({ + context, + schema: schema as SchemaWithRequired, + }) + } else if (schema.items) { + if (schema.logicalOperator === 'or' && schema.items[0]) { + expression = schemaToExpression({ + context, + schema: schema.items[0], + }) + } else { + console.warn( + '🚨', + `unhandled schema items with logical operator "${schema.logicalOperator}"`, + JSON.stringify(schema), + ); + } + } else { + console.warn( + '🚨', + 'unhandled schema', + JSON.stringify(schema), + ); + } + + return expression!; +} diff --git a/packages/openapi-ts/src/plugins/zod/plugin.ts b/packages/openapi-ts/src/plugins/zod/plugin.ts index 9c5321ee2..efea067f1 100644 --- a/packages/openapi-ts/src/plugins/zod/plugin.ts +++ b/packages/openapi-ts/src/plugins/zod/plugin.ts @@ -4,16 +4,12 @@ import { compiler } from '../../compiler'; import { operationResponsesMap } from '../../ir/operation'; import { deduplicateSchema } from '../../ir/schema'; import type { IR } from '../../ir/types'; +import type { SchemaWithType } from '../../openApi/shared/types/schema'; import { numberRegExp } from '../../utils/regexp'; import { operationIrRef } from '../shared/utils/ref'; import type { Plugin } from '../types'; import type { Config } from './types'; -interface SchemaWithType['type']> - extends Omit { - type: Extract['type'], T>; -} - interface Result { circularReferenceTracker: Set; hasCircularReference: boolean; diff --git a/packages/openapi-ts/test/openapi-ts.config.ts b/packages/openapi-ts/test/openapi-ts.config.ts index e8c9a787b..bfedcdf80 100644 --- a/packages/openapi-ts/test/openapi-ts.config.ts +++ b/packages/openapi-ts/test/openapi-ts.config.ts @@ -55,9 +55,9 @@ export default defineConfig({ }, // @ts-ignore { - enums: 'typescript', + // enums: 'typescript', // enums: 'typescript+namespace', - // enums: 'javascript', + enums: 'javascript', enumsCase: 'camelCase', // exportInlineEnums: true, // identifierCase: 'preserve',