diff --git a/.changeset/silent-beds-greet.md b/.changeset/silent-beds-greet.md new file mode 100644 index 000000000..804d0928f --- /dev/null +++ b/.changeset/silent-beds-greet.md @@ -0,0 +1,5 @@ +--- +"swagger-typescript-api": minor +--- + +partial support external paths by ref (#447) diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..3ecf57cc7 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,19 @@ +{ + "editor.defaultFormatter": "biomejs.biome", + "[typescript]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[typescriptreact]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[javascript]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[javascriptreact]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "editor.codeActionsOnSave": { + "source.fixAll.biome": "explicit", + "source.organizeImports.biome": "explicit" + } +} diff --git a/package.json b/package.json index ae6afc319..304fbff3a 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,7 @@ "typedoc": "typedoc" }, "dependencies": { + "@apidevtools/swagger-parser": "12.0.0", "@biomejs/js-api": "3.0.0", "@biomejs/wasm-nodejs": "2.2.5", "@types/lodash": "^4.17.20", @@ -60,7 +61,8 @@ "swagger-schema-official": "2.0.0-bab6bed", "swagger2openapi": "^7.0.8", "typescript": "~5.9.3", - "yaml": "^2.8.1" + "yaml": "^2.8.1", + "yummies": "5.7.0" }, "devDependencies": { "@biomejs/biome": "2.2.5", diff --git a/src/code-gen-process.ts b/src/code-gen-process.ts index 8793b0e8c..45e93756a 100644 --- a/src/code-gen-process.ts +++ b/src/code-gen-process.ts @@ -1,3 +1,4 @@ +import type { resolve } from "@apidevtools/swagger-parser"; import { consola } from "consola"; import lodash from "lodash"; import * as typescript from "typescript"; @@ -10,7 +11,6 @@ import { CodeGenConfig } from "./configuration.js"; import { SchemaComponentsMap } from "./schema-components-map.js"; import { SchemaParserFabric } from "./schema-parser/schema-parser-fabric.js"; import { SchemaRoutes } from "./schema-routes/schema-routes.js"; -import { SchemaWalker } from "./schema-walker.js"; import { SwaggerSchemaResolver } from "./swagger-schema-resolver.js"; import { TemplatesWorker } from "./templates-worker.js"; import { JavascriptTranslator } from "./translators/javascript.js"; @@ -44,8 +44,8 @@ export class CodeGenProcess { fileSystem: FileSystem; codeFormatter: CodeFormatter; templatesWorker: TemplatesWorker; - schemaWalker: SchemaWalker; javascriptTranslator: JavascriptTranslator; + swaggerRefs: Awaited> | undefined | null; constructor(config: Partial) { this.config = new CodeGenConfig(config); @@ -54,10 +54,6 @@ export class CodeGenProcess { this.config, this.fileSystem, ); - this.schemaWalker = new SchemaWalker( - this.config, - this.swaggerSchemaResolver, - ); this.schemaComponentsMap = new SchemaComponentsMap(this.config); this.typeNameFormatter = new TypeNameFormatter(this.config); this.templatesWorker = new TemplatesWorker( @@ -71,7 +67,6 @@ export class CodeGenProcess { this.templatesWorker, this.schemaComponentsMap, this.typeNameFormatter, - this.schemaWalker, ); this.schemaRoutes = new SchemaRoutes( this.config, @@ -94,37 +89,35 @@ export class CodeGenProcess { templatesToRender: this.templatesWorker.getTemplates(this.config), }); - const swagger = await this.swaggerSchemaResolver.create(); - - this.swaggerSchemaResolver.fixSwaggerSchema(swagger); + const resolvedSwaggerSchema = await this.swaggerSchemaResolver.create(); this.config.update({ - swaggerSchema: swagger.usageSchema, - originalSchema: swagger.originalSchema, + resolvedSwaggerSchema: resolvedSwaggerSchema, + swaggerSchema: resolvedSwaggerSchema.usageSchema, + originalSchema: resolvedSwaggerSchema.originalSchema, }); - this.schemaWalker.addSchema("$usage", swagger.usageSchema); - this.schemaWalker.addSchema("$original", swagger.originalSchema); - consola.info("start generating your typescript api"); this.config.update( - this.config.hooks.onInit(this.config, this) || this.config, + this.config.hooks.onInit?.(this.config, this) || this.config, ); this.schemaComponentsMap.clear(); - lodash.each(swagger.usageSchema.components, (component, componentName) => - lodash.each(component, (rawTypeData, typeName) => { - this.schemaComponentsMap.createComponent( - this.schemaComponentsMap.createRef([ - "components", - componentName, - typeName, - ]), - rawTypeData, - ); - }), + lodash.each( + resolvedSwaggerSchema.usageSchema.components, + (component, componentName) => + lodash.each(component, (rawTypeData, typeName) => { + this.schemaComponentsMap.createComponent( + this.schemaComponentsMap.createRef([ + "components", + componentName, + typeName, + ]), + rawTypeData, + ); + }), ); // Set all discriminators at the top @@ -149,13 +142,10 @@ export class CodeGenProcess { return parsed; }); - this.schemaRoutes.attachSchema({ - usageSchema: swagger.usageSchema, - parsedSchemas, - }); + this.schemaRoutes.attachSchema(resolvedSwaggerSchema, parsedSchemas); const rawConfiguration = { - apiConfig: this.createApiConfig(swagger.usageSchema), + apiConfig: this.createApiConfig(resolvedSwaggerSchema.usageSchema), config: this.config, modelTypes: this.collectModelTypes(), hasSecurityRoutes: this.schemaRoutes.hasSecurityRoutes, @@ -173,7 +163,7 @@ export class CodeGenProcess { }; const configuration = - this.config.hooks.onPrepareConfig(rawConfiguration) || rawConfiguration; + this.config.hooks.onPrepareConfig?.(rawConfiguration) || rawConfiguration; if (this.fileSystem.pathIsExist(this.config.output)) { if (this.config.cleanOutput) { diff --git a/src/configuration.ts b/src/configuration.ts index ea3f48b38..1becab217 100644 --- a/src/configuration.ts +++ b/src/configuration.ts @@ -9,6 +9,7 @@ import type { } from "../types/index.js"; import { ComponentTypeNameResolver } from "./component-type-name-resolver.js"; import * as CONSTANTS from "./constants.js"; +import type { ResolvedSwaggerSchema } from "./resolved-swagger-schema.js"; import type { MonoSchemaParser } from "./schema-parser/mono-schema-parser.js"; import type { SchemaParser } from "./schema-parser/schema-parser.js"; import type { Translator } from "./translators/translator.js"; @@ -110,6 +111,7 @@ export class CodeGenConfig { ) => {}, onFormatRouteName: (_routeInfo: unknown, _templateRouteName: unknown) => {}, }; + resolvedSwaggerSchema!: ResolvedSwaggerSchema; defaultResponseType; singleHttpClient = false; httpClientType = CONSTANTS.HTTP_CLIENT.FETCH; @@ -167,7 +169,7 @@ export class CodeGenConfig { spec: OpenAPI.Document | null = null; fileName = "Api.ts"; authorizationToken: string | undefined; - requestOptions = null; + requestOptions: Record | null = null; jsPrimitiveTypes: string[] = []; jsEmptyTypes: string[] = []; @@ -439,7 +441,13 @@ export class CodeGenConfig { this.componentTypeNameResolver = new ComponentTypeNameResolver(this, []); } - update = (update: Partial) => { + update = ( + update: Partial< + GenerateApiConfiguration["config"] & { + resolvedSwaggerSchema: ResolvedSwaggerSchema; + } + >, + ) => { objectAssign(this, update); if (this.enumNamesAsValues) { this.extractEnums = true; diff --git a/src/resolved-swagger-schema.ts b/src/resolved-swagger-schema.ts new file mode 100644 index 000000000..a56bbf100 --- /dev/null +++ b/src/resolved-swagger-schema.ts @@ -0,0 +1,175 @@ +import type { resolve } from "@apidevtools/swagger-parser"; +import SwaggerParser from "@apidevtools/swagger-parser"; +import consola from "consola"; +import type { OpenAPI } from "openapi-types"; +import type { AnyObject, Maybe, Primitive } from "yummies/utils/types"; +import type { CodeGenConfig } from "./configuration.js"; + +export interface RefDetails { + ref: string; + isLocal: boolean; + externalUrlOrPath: Maybe; + externalOpenapiFileName?: string; +} + +export class ResolvedSwaggerSchema { + private parsedRefsCache = new Map(); + + private constructor( + private config: CodeGenConfig, + public usageSchema: OpenAPI.Document, + public originalSchema: OpenAPI.Document, + private resolvers: Awaited>[], + ) { + this.usageSchema = usageSchema; + this.originalSchema = originalSchema; + } + + getRefDetails(ref: string): RefDetails { + if (!this.parsedRefsCache.has(ref)) { + const isLocal = ref.startsWith("#"); + + if (isLocal) { + this.parsedRefsCache.set(ref, { + ref, + isLocal, + externalUrlOrPath: null, + }); + } else { + const externalUrlOrPath = ref.split("#")[0]!; + let externalOpenapiFileName = externalUrlOrPath.split("/").at(-1) || ""; + + if ( + externalOpenapiFileName.endsWith(".json") || + externalOpenapiFileName.endsWith(".yaml") + ) { + externalOpenapiFileName = externalOpenapiFileName.slice(0, -5); + } else if (externalOpenapiFileName.endsWith(".yml")) { + externalOpenapiFileName = externalOpenapiFileName.slice(0, -4); + } + + this.parsedRefsCache.set(ref, { + ref, + isLocal, + externalUrlOrPath, + externalOpenapiFileName, + }); + } + } + + return this.parsedRefsCache.get(ref)!; + } + + isLocalRef(ref: string): boolean { + return this.getRefDetails(ref).isLocal; + } + + getRef(ref: Maybe): Maybe { + if (!ref) { + return null; + } + + const resolvedByOrigRef = this.tryToResolveRef(ref); + + if (resolvedByOrigRef) { + return resolvedByOrigRef; + } + + // const ref.match(/\#[a-z]/) + if (/#[a-z]/.test(ref)) { + const fixedRef = ref.replace(/#[a-z]/, (match) => { + const [hashtag, char] = match.split(""); + return `${hashtag}/${char}`; + }); + + return this.tryToResolveRef(fixedRef); + } + + // this.tryToResolveRef(`@usage${ref}`) ?? + // this.tryToResolveRef(`@original${ref}`) + } + + private tryToResolveRef(ref: Maybe) { + if (!this.resolvers || !ref) { + return null; + } + + for (const resolver of this.resolvers) { + try { + const resolvedAsIs = resolver.get(ref); + return resolvedAsIs; + } catch (e) { + consola.debug(e); + } + } + + return null; + } + + static async create( + config: CodeGenConfig, + usageSchema: OpenAPI.Document, + originalSchema: OpenAPI.Document, + ) { + const resolvers: Awaited>[] = []; + + const options: SwaggerParser.Options = { + continueOnError: true, + mutateInputSchema: true, + dereference: {}, + validate: { + schema: false, + spec: false, + }, + resolve: { + external: true, + http: { + ...config.requestOptions, + headers: Object.assign( + {}, + config.authorizationToken + ? { + Authorization: config.authorizationToken, + } + : {}, + config.requestOptions?.headers ?? {}, + ), + }, + }, + }; + + try { + resolvers.push( + await SwaggerParser.resolve( + originalSchema, + // this.config.url || this.config.input || (this.config.spec as any), + options, + ), + ); + } catch (e) { + consola.debug(e); + } + try { + resolvers.push(await SwaggerParser.resolve(usageSchema, options)); + } catch (e) { + consola.debug(e); + } + try { + resolvers.push( + await SwaggerParser.resolve( + config.url || config.input || (config.spec as any), + options, + ), + ); + } catch (e) { + consola.debug(e); + } + + return new ResolvedSwaggerSchema( + config, + usageSchema, + originalSchema, + resolvers, + ); + } +} diff --git a/src/schema-components-map.ts b/src/schema-components-map.ts index e27573edf..6f011733c 100644 --- a/src/schema-components-map.ts +++ b/src/schema-components-map.ts @@ -1,13 +1,13 @@ +import { typeGuard } from "yummies/type-guard"; +import type { AnyObject, Maybe } from "yummies/utils/types"; import type { SchemaComponent } from "../types/index.js"; import type { CodeGenConfig } from "./configuration.js"; +import { pascalCase } from "./util/pascal-case.js"; export class SchemaComponentsMap { _data: SchemaComponent[] = []; - config: CodeGenConfig; - constructor(config: CodeGenConfig) { - this.config = config; - } + constructor(public config: CodeGenConfig) {} clear() { this._data = []; @@ -21,31 +21,52 @@ export class SchemaComponentsMap { return ref.split("/"); }; - createComponent( + private createComponentDraft( $ref: string, - rawTypeData: SchemaComponent["rawTypeData"], + rawTypeData: Maybe | SchemaComponent, ): SchemaComponent { + if ( + typeGuard.isObject(rawTypeData) && + rawTypeData.typeName && + rawTypeData.rawTypeData && + rawTypeData.$ref + ) { + return rawTypeData as SchemaComponent; + } + const parsed = this.parseRef($ref); - const typeName = parsed[parsed.length - 1]!; + const typeName = parsed.at(-1)!; const componentName = parsed[ parsed.length - 2 ] as SchemaComponent["componentName"]; - const componentSchema: SchemaComponent = { + + return { $ref, typeName, - rawTypeData, + rawTypeData: rawTypeData as SchemaComponent["rawTypeData"], componentName, /** result from schema parser */ typeData: null, }; + } + createComponent( + $ref: string, + rawTypeData: SchemaComponent["rawTypeData"] | SchemaComponent, + addAtStart?: boolean, + ): SchemaComponent { + const componentSchema = this.createComponentDraft($ref, rawTypeData); const usageComponent = this.config.hooks.onCreateComponent(componentSchema) || componentSchema; const refIndex = this._data.findIndex((c) => c.$ref === $ref); if (refIndex === -1) { - this._data.push(usageComponent); + if (addAtStart) { + this._data.unshift(usageComponent); + } else { + this._data.push(usageComponent); + } } else { this._data[refIndex] = usageComponent; } @@ -66,7 +87,52 @@ export class SchemaComponentsMap { } get = ($ref: string) => { - return this._data.find((c) => c.$ref === $ref) || null; + const localFound = this._data.find((c) => c.$ref === $ref) || null; + + if (localFound != null) { + return localFound; + } + + const { resolvedSwaggerSchema } = this.config; + + if (resolvedSwaggerSchema.isLocalRef($ref)) { + return null; + } + + const foundByRef = resolvedSwaggerSchema.getRef($ref); + const refDetails = resolvedSwaggerSchema.getRefDetails($ref); + + if (foundByRef != null) { + const componentDraft = this.createComponentDraft( + $ref, + foundByRef as AnyObject, + ); + + componentDraft.typeName = + this.config.hooks.onFormatExternalTypeName?.( + componentDraft.typeName, + refDetails, + ) || componentDraft.typeName; + + if ( + // duplicate name + this._data.some( + (component) => component.typeName === componentDraft.typeName, + ) + ) { + componentDraft.typeName = + this.config.hooks.onFixDuplicateExternalTypeName?.( + componentDraft.typeName, + refDetails, + this._data.map((it) => it.typeName), + ) ?? + `${pascalCase(refDetails.externalOpenapiFileName || "External")}${componentDraft.typeName}`; + } + + return this.createComponent($ref, componentDraft); + } + + return null; }; // Ensure enums are at the top of components list diff --git a/src/schema-parser/schema-parser-fabric.ts b/src/schema-parser/schema-parser-fabric.ts index 1e1ad4efd..68377a992 100644 --- a/src/schema-parser/schema-parser-fabric.ts +++ b/src/schema-parser/schema-parser-fabric.ts @@ -7,7 +7,6 @@ import type { } from "../../types/index.js"; import type { CodeGenConfig } from "../configuration.js"; import type { SchemaComponentsMap } from "../schema-components-map.js"; -import type { SchemaWalker } from "../schema-walker.js"; import type { TemplatesWorker } from "../templates-worker.js"; import type { TypeNameFormatter } from "../type-name-formatter.js"; import { SchemaFormatters } from "./schema-formatters.js"; @@ -21,21 +20,22 @@ export class SchemaParserFabric { schemaFormatters: SchemaFormatters; templatesWorker: TemplatesWorker; schemaUtils: SchemaUtils; - schemaWalker: SchemaWalker; constructor( config: CodeGenConfig, templatesWorker: TemplatesWorker, schemaComponentsMap: SchemaComponentsMap, typeNameFormatter: TypeNameFormatter, - schemaWalker: SchemaWalker, ) { this.config = config; this.schemaComponentsMap = schemaComponentsMap; this.typeNameFormatter = typeNameFormatter; this.templatesWorker = templatesWorker; - this.schemaWalker = schemaWalker; - this.schemaUtils = new SchemaUtils(this); + this.schemaUtils = new SchemaUtils( + this.config, + this.schemaComponentsMap, + this.typeNameFormatter, + ); this.schemaFormatters = new SchemaFormatters(this); } diff --git a/src/schema-parser/schema-parser.ts b/src/schema-parser/schema-parser.ts index fc8e45878..a6f89acfe 100644 --- a/src/schema-parser/schema-parser.ts +++ b/src/schema-parser/schema-parser.ts @@ -3,7 +3,6 @@ import lodash from "lodash"; import type { CodeGenConfig } from "../configuration.js"; import { SCHEMA_TYPES } from "../constants.js"; import type { SchemaComponentsMap } from "../schema-components-map.js"; -import type { SchemaWalker } from "../schema-walker.js"; import type { TemplatesWorker } from "../templates-worker.js"; import type { TypeNameFormatter } from "../type-name-formatter.js"; import { sortByProperty } from "../util/sort-by-property.js"; @@ -29,7 +28,6 @@ export class SchemaParser { schemaFormatters: SchemaFormatters; schemaUtils: SchemaUtils; templatesWorker: TemplatesWorker; - schemaWalker: SchemaWalker; typeName; schema; @@ -42,7 +40,6 @@ export class SchemaParser { this.templatesWorker = schemaParserFabric.templatesWorker; this.schemaComponentsMap = schemaParserFabric.schemaComponentsMap; this.typeNameFormatter = schemaParserFabric.typeNameFormatter; - this.schemaWalker = schemaParserFabric.schemaWalker; this.schemaFormatters = schemaParserFabric.schemaFormatters; this.schemaUtils = schemaParserFabric.schemaUtils; diff --git a/src/schema-parser/schema-utils.ts b/src/schema-parser/schema-utils.ts index bf7614e33..f663b4645 100644 --- a/src/schema-parser/schema-utils.ts +++ b/src/schema-parser/schema-utils.ts @@ -2,28 +2,16 @@ import lodash from "lodash"; import type { CodeGenConfig } from "../configuration.js"; import { SCHEMA_TYPES } from "../constants.js"; import type { SchemaComponentsMap } from "../schema-components-map.js"; -import type { SchemaWalker } from "../schema-walker.js"; import type { TypeNameFormatter } from "../type-name-formatter.js"; import { internalCase } from "../util/internal-case.js"; import { pascalCase } from "../util/pascal-case.js"; export class SchemaUtils { - config: CodeGenConfig; - schemaComponentsMap: SchemaComponentsMap; - typeNameFormatter: TypeNameFormatter; - schemaWalker: SchemaWalker; - - constructor({ - config, - schemaComponentsMap, - typeNameFormatter, - schemaWalker, - }) { - this.config = config; - this.schemaComponentsMap = schemaComponentsMap; - this.typeNameFormatter = typeNameFormatter; - this.schemaWalker = schemaWalker; - } + constructor( + public config: CodeGenConfig, + public schemaComponentsMap: SchemaComponentsMap, + public typeNameFormatter: TypeNameFormatter, + ) {} getRequiredProperties = (schema) => { return lodash.uniq( diff --git a/src/schema-routes/schema-routes.ts b/src/schema-routes/schema-routes.ts index b570502e9..50d40d373 100644 --- a/src/schema-routes/schema-routes.ts +++ b/src/schema-routes/schema-routes.ts @@ -1,9 +1,16 @@ import { consola } from "consola"; import lodash from "lodash"; +import { typeGuard } from "yummies/type-guard"; +import type { AnyObject } from "yummies/utils/types"; import type { GenerateApiConfiguration, ParsedRoute, + ParsedSchema, + SchemaTypeEnumContent, + SchemaTypeObjectContent, + SchemaTypePrimitiveContent, } from "../../types/index.js"; +import type { CodeGenProcess } from "../code-gen-process.js"; import type { CodeGenConfig } from "../configuration.js"; import { DEFAULT_BODY_ARG_NAME, @@ -12,6 +19,7 @@ import { RESERVED_PATH_ARG_NAMES, RESERVED_QUERY_ARG_NAMES, } from "../constants.js"; +import type { ResolvedSwaggerSchema } from "../resolved-swagger-schema.js"; import type { SchemaComponentsMap } from "../schema-components-map.js"; import type { SchemaParserFabric } from "../schema-parser/schema-parser-fabric.js"; import type { SchemaUtils } from "../schema-parser/schema-utils.js"; @@ -31,13 +39,7 @@ const CONTENT_KIND = { }; export class SchemaRoutes { - config: CodeGenConfig; - schemaParserFabric: SchemaParserFabric; schemaUtils: SchemaUtils; - typeNameFormatter: TypeNameFormatter; - schemaComponentsMap: SchemaComponentsMap; - templatesWorker: TemplatesWorker; - FORM_DATA_TYPES: string[] = []; routes: ParsedRoute[] = []; @@ -46,18 +48,13 @@ export class SchemaRoutes { hasFormDataRoutes = false; constructor( - config: CodeGenConfig, - schemaParserFabric: SchemaParserFabric, - schemaComponentsMap: SchemaComponentsMap, - templatesWorker: TemplatesWorker, - typeNameFormatter: TypeNameFormatter, + public config: CodeGenConfig, + public schemaParserFabric: SchemaParserFabric, + public schemaComponentsMap: SchemaComponentsMap, + public templatesWorker: TemplatesWorker, + public typeNameFormatter: TypeNameFormatter, ) { - this.config = config; - this.schemaParserFabric = schemaParserFabric; this.schemaUtils = this.schemaParserFabric.schemaUtils; - this.typeNameFormatter = typeNameFormatter; - this.schemaComponentsMap = schemaComponentsMap; - this.templatesWorker = templatesWorker; this.FORM_DATA_TYPES = lodash.uniq([ this.schemaUtils.getSchemaType({ type: "string", format: "file" }), @@ -65,23 +62,34 @@ export class SchemaRoutes { ]); } - createRequestsMap = (routeInfoByMethodsMap) => { + createRequestsMap = ( + resolvedSwaggerSchema: ResolvedSwaggerSchema, + routeInfoByMethodsMap: AnyObject, + ) => { const parameters = lodash.get(routeInfoByMethodsMap, "parameters"); return lodash.reduce( routeInfoByMethodsMap, - (acc, requestInfo, method) => { - if ( - method.startsWith("x-") || - ["parameters", "$ref"].includes(method) - ) { + (acc, anything, property) => { + if (property.startsWith("x-") || ["parameters"].includes(property)) { + return acc; + } + + if (property === "$ref") { + const refData = resolvedSwaggerSchema.getRef(anything); + if (typeGuard.isObject(refData)) { + Object.assign( + acc, + this.createRequestsMap(resolvedSwaggerSchema, refData), + ); + } return acc; } - acc[method] = { - ...requestInfo, + acc[property] = { + ...anything, parameters: lodash.compact( - lodash.concat(parameters, requestInfo.parameters), + lodash.concat(parameters, anything.parameters), ), }; @@ -91,7 +99,7 @@ export class SchemaRoutes { ); }; - parseRouteName = (originalRouteName) => { + parseRouteName = (originalRouteName: string) => { const routeName = this.config.hooks.onPreBuildRoutePath(originalRouteName) || originalRouteName; @@ -209,7 +217,11 @@ export class SchemaRoutes { let routeParam = null; - if (refTypeInfo?.rawTypeData.in && refTypeInfo.rawTypeData) { + if ( + !!refTypeInfo?.rawTypeData && + typeof refTypeInfo === "object" && + refTypeInfo?.rawTypeData.in + ) { if (!routeParams[refTypeInfo.rawTypeData.in]) { routeParams[refTypeInfo.rawTypeData.in] = []; } @@ -815,7 +827,7 @@ export class SchemaRoutes { ); const routeName = - this.config.hooks.onFormatRouteName( + this.config.hooks.onFormatRouteName?.( rawRouteInfo, routeNameFromTemplate, ) || routeNameFromTemplate; @@ -847,7 +859,7 @@ export class SchemaRoutes { }; return ( - this.config.hooks.onCreateRouteName(routeNameInfo, rawRouteInfo) || + this.config.hooks.onCreateRouteName?.(routeNameInfo, rawRouteInfo) || routeNameInfo ); }; @@ -1094,20 +1106,32 @@ export class SchemaRoutes { }; }; - attachSchema = ({ usageSchema, parsedSchemas }) => { + attachSchema = ( + resolvedSwaggerSchema: ResolvedSwaggerSchema, + parsedSchemas: ParsedSchema< + | SchemaTypeObjectContent + | SchemaTypeEnumContent + | SchemaTypePrimitiveContent + >[], + ) => { this.config.routeNameDuplicatesMap.clear(); - const pathsEntries = lodash.entries(usageSchema.paths); + const pathsEntries = lodash.entries( + resolvedSwaggerSchema.usageSchema.paths, + ); for (const [rawRouteName, routeInfoByMethodsMap] of pathsEntries) { - const routeInfosMap = this.createRequestsMap(routeInfoByMethodsMap); + const routeInfosMap = this.createRequestsMap( + resolvedSwaggerSchema, + routeInfoByMethodsMap, + ); for (const [method, routeInfo] of Object.entries(routeInfosMap)) { const parsedRouteInfo = this.parseRouteInfo( rawRouteName, routeInfo, method, - usageSchema, + resolvedSwaggerSchema.usageSchema, parsedSchemas, ); const processedRouteInfo = diff --git a/src/schema-walker.ts b/src/schema-walker.ts deleted file mode 100644 index 9c8248415..000000000 --- a/src/schema-walker.ts +++ /dev/null @@ -1,42 +0,0 @@ -import lodash from "lodash"; -import type { OpenAPI } from "openapi-types"; -import type { CodeGenConfig } from "./configuration.js"; -import type { SwaggerSchemaResolver } from "./swagger-schema-resolver.js"; - -// TODO: WIP -// this class will be needed to walk by schema everywhere -export class SchemaWalker { - config: CodeGenConfig; - swaggerSchemaResolver: SwaggerSchemaResolver; - schemas = new Map(); - caches = new Map(); - - constructor( - config: CodeGenConfig, - swaggerSchemaResolver: SwaggerSchemaResolver, - ) { - this.config = config; - this.swaggerSchemaResolver = swaggerSchemaResolver; - } - - addSchema = (name: string, schema: OpenAPI.Document) => { - this.schemas.set(name, structuredClone(schema)); - }; - - _isLocalRef = (ref: string) => { - return ref.startsWith("#"); - }; - - _isRemoteRef = (ref: string) => { - return ref.startsWith("http://") || ref.startsWith("https://"); - }; - - _getRefDataFromSchema = (schema: Record, ref: string) => { - const path = ref.replace("#", "").split("/"); - const refData = lodash.get(schema, path); - if (refData) { - this.caches.set(ref, refData); - } - return refData; - }; -} diff --git a/src/swagger-schema-resolver.ts b/src/swagger-schema-resolver.ts index 20a1efe17..193115fd3 100644 --- a/src/swagger-schema-resolver.ts +++ b/src/swagger-schema-resolver.ts @@ -1,12 +1,18 @@ import { consola } from "consola"; import lodash from "lodash"; -import type { OpenAPI, OpenAPIV2 } from "openapi-types"; +import type { OpenAPI, OpenAPIV2, OpenAPIV3 } from "openapi-types"; import * as swagger2openapi from "swagger2openapi"; import * as YAML from "yaml"; import type { CodeGenConfig } from "./configuration.js"; +import { ResolvedSwaggerSchema } from "./resolved-swagger-schema.js"; import type { FileSystem } from "./util/file-system.js"; import { Request } from "./util/request.js"; +interface SwaggerSchemas { + usageSchema: OpenAPI.Document; + originalSchema: OpenAPI.Document; +} + export class SwaggerSchemaResolver { config: CodeGenConfig; fileSystem: FileSystem; @@ -18,30 +24,41 @@ export class SwaggerSchemaResolver { this.request = new Request(config); } - async create() { + async create(): Promise { const { spec, patch, input, url, authorizationToken } = this.config; + let swaggerSchemas: SwaggerSchemas; if (spec) { - return await this.convertSwaggerObject(spec, { patch }); + swaggerSchemas = await this.convertSwaggerObject(spec, { patch }); + } else { + const swaggerSchemaFile = await this.fetchSwaggerSchemaFile( + input, + url, + authorizationToken, + ); + const swaggerSchemaObject = + this.processSwaggerSchemaFile(swaggerSchemaFile); + + swaggerSchemas = await this.convertSwaggerObject(swaggerSchemaObject, { + patch, + }); } - const swaggerSchemaFile = await this.fetchSwaggerSchemaFile( - input, - url, - authorizationToken, + this.fixSwaggerSchemas(swaggerSchemas); + + const resolvedSwaggerSchema = ResolvedSwaggerSchema.create( + this.config, + swaggerSchemas.usageSchema, + swaggerSchemas.originalSchema, ); - const swaggerSchemaObject = - this.processSwaggerSchemaFile(swaggerSchemaFile); - return await this.convertSwaggerObject(swaggerSchemaObject, { patch }); + + return resolvedSwaggerSchema; } convertSwaggerObject( swaggerSchema: OpenAPI.Document, converterOptions: { patch?: boolean }, - ): Promise<{ - usageSchema: OpenAPI.Document; - originalSchema: OpenAPI.Document; - }> { + ): Promise { return new Promise((resolve) => { const result = structuredClone(swaggerSchema); result.info = lodash.merge( @@ -119,7 +136,7 @@ export class SwaggerSchemaResolver { } } - fixSwaggerSchema({ usageSchema, originalSchema }) { + private fixSwaggerSchemas({ usageSchema, originalSchema }: SwaggerSchemas) { const usagePaths = lodash.get(usageSchema, "paths"); const originalPaths = lodash.get(originalSchema, "paths"); @@ -130,23 +147,30 @@ export class SwaggerSchemaResolver { // walk by methods lodash.each(usagePathObject, (usageRouteInfo, methodName) => { const originalRouteInfo = lodash.get(originalPathObject, methodName); - const usageRouteParams = lodash.get(usageRouteInfo, "parameters", []); + const usageRouteParams = lodash.get( + usageRouteInfo, + "parameters", + [], + ) as OpenAPIV3.ParameterObject[]; const originalRouteParams = lodash.get( originalRouteInfo, "parameters", [], ); + const usageAsOpenapiv2 = + usageRouteInfo as unknown as OpenAPIV2.Document; + if (typeof usageRouteInfo === "object") { - usageRouteInfo.consumes = lodash.uniq( + usageAsOpenapiv2.consumes = lodash.uniq( lodash.compact([ - ...(usageRouteInfo.consumes || []), + ...(usageAsOpenapiv2.consumes || []), ...(originalRouteInfo.consumes || []), ]), ); - usageRouteInfo.produces = lodash.uniq( + usageAsOpenapiv2.produces = lodash.uniq( lodash.compact([ - ...(usageRouteInfo.produces || []), + ...(usageAsOpenapiv2.produces || []), ...(originalRouteInfo.produces || []), ]), ); @@ -154,7 +178,7 @@ export class SwaggerSchemaResolver { lodash.each(originalRouteParams, (originalRouteParam) => { const existUsageParam = usageRouteParams.find( - (param) => + (param: OpenAPIV3.ParameterObject) => originalRouteParam.in === param.in && originalRouteParam.name === param.name, ); diff --git a/src/type-name-formatter.ts b/src/type-name-formatter.ts index 58743a863..9dd5aefac 100644 --- a/src/type-name-formatter.ts +++ b/src/type-name-formatter.ts @@ -46,7 +46,7 @@ export class TypeNameFormatter { .startCase(`${typePrefix}_${fixedModelName}_${typeSuffix}`) .replace(/\s/g, ""); const formattedResultName = - this.config.hooks.onFormatTypeName(formattedName, name, schemaType) || + this.config.hooks.onFormatTypeName?.(formattedName, name, schemaType) || formattedName; this.formattedModelNamesMap.set(hashKey, formattedResultName); diff --git a/tests/spec/paths/__snapshots__/basic.test.ts.snap b/tests/spec/paths/__snapshots__/basic.test.ts.snap new file mode 100644 index 000000000..cc7ab35e5 --- /dev/null +++ b/tests/spec/paths/__snapshots__/basic.test.ts.snap @@ -0,0 +1,358 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`basic > paths(simplest-1-path) 1`] = ` +"/* eslint-disable */ +/* tslint:disable */ +// @ts-nocheck +/* + * --------------------------------------------------------------- + * ## THIS FILE WAS GENERATED VIA SWAGGER-TYPESCRIPT-API ## + * ## ## + * ## AUTHOR: acacode ## + * ## SOURCE: https://github.com/acacode/swagger-typescript-api ## + * --------------------------------------------------------------- + */ + +export type ReportSchema = ReproReportSchema; + +/** Weather */ +export interface Weather { + /** + * Weather condition id + * @format int32 + * @example 803 + */ + id?: number; + /** + * Group of weather parameters (Rain, Snow, Extreme etc.) + * @example "Clouds" + */ + main?: string; + /** + * Weather condition within the group + * @example "broken clouds" + */ + description?: string; + /** + * Weather icon id + * @example "04n" + */ + icon?: string; +} + +export type HelloListData = object; + +export interface GetRepositoryParams { + username: string; + slug: string; +} + +export type GetRepositoryData = any; + +/** ReportSchema */ +export interface ReproReportSchema { + /** + * Weather condition id + * @format int32 + * @example 803 + */ + id?: number; +} + +export type QueryParamsType = Record; +export type ResponseFormat = keyof Omit; + +export interface FullRequestParams extends Omit { + /** set parameter to \`true\` for call \`securityWorker\` for this request */ + secure?: boolean; + /** request path */ + path: string; + /** content type of request body */ + type?: ContentType; + /** query params */ + query?: QueryParamsType; + /** format of response (i.e. response.json() -> format: "json") */ + format?: ResponseFormat; + /** request body */ + body?: unknown; + /** base url */ + baseUrl?: string; + /** request cancellation token */ + cancelToken?: CancelToken; +} + +export type RequestParams = Omit< + FullRequestParams, + "body" | "method" | "query" | "path" +>; + +export interface ApiConfig { + baseUrl?: string; + baseApiParams?: Omit; + securityWorker?: ( + securityData: SecurityDataType | null, + ) => Promise | RequestParams | void; + customFetch?: typeof fetch; +} + +export interface HttpResponse + extends Response { + data: D; + error: E; +} + +type CancelToken = Symbol | string | number; + +export enum ContentType { + Json = "application/json", + JsonApi = "application/vnd.api+json", + FormData = "multipart/form-data", + UrlEncoded = "application/x-www-form-urlencoded", + Text = "text/plain", +} + +export class HttpClient { + public baseUrl: string = ""; + private securityData: SecurityDataType | null = null; + private securityWorker?: ApiConfig["securityWorker"]; + private abortControllers = new Map(); + private customFetch = (...fetchParams: Parameters) => + fetch(...fetchParams); + + private baseApiParams: RequestParams = { + credentials: "same-origin", + headers: {}, + redirect: "follow", + referrerPolicy: "no-referrer", + }; + + constructor(apiConfig: ApiConfig = {}) { + Object.assign(this, apiConfig); + } + + public setSecurityData = (data: SecurityDataType | null) => { + this.securityData = data; + }; + + protected encodeQueryParam(key: string, value: any) { + const encodedKey = encodeURIComponent(key); + return \`\${encodedKey}=\${encodeURIComponent(typeof value === "number" ? value : \`\${value}\`)}\`; + } + + protected addQueryParam(query: QueryParamsType, key: string) { + return this.encodeQueryParam(key, query[key]); + } + + protected addArrayQueryParam(query: QueryParamsType, key: string) { + const value = query[key]; + return value.map((v: any) => this.encodeQueryParam(key, v)).join("&"); + } + + protected toQueryString(rawQuery?: QueryParamsType): string { + const query = rawQuery || {}; + const keys = Object.keys(query).filter( + (key) => "undefined" !== typeof query[key], + ); + return keys + .map((key) => + Array.isArray(query[key]) + ? this.addArrayQueryParam(query, key) + : this.addQueryParam(query, key), + ) + .join("&"); + } + + protected addQueryParams(rawQuery?: QueryParamsType): string { + const queryString = this.toQueryString(rawQuery); + return queryString ? \`?\${queryString}\` : ""; + } + + private contentFormatters: Record any> = { + [ContentType.Json]: (input: any) => + input !== null && (typeof input === "object" || typeof input === "string") + ? JSON.stringify(input) + : input, + [ContentType.JsonApi]: (input: any) => + input !== null && (typeof input === "object" || typeof input === "string") + ? JSON.stringify(input) + : input, + [ContentType.Text]: (input: any) => + input !== null && typeof input !== "string" + ? JSON.stringify(input) + : input, + [ContentType.FormData]: (input: any) => { + if (input instanceof FormData) { + return input; + } + + return Object.keys(input || {}).reduce((formData, key) => { + const property = input[key]; + formData.append( + key, + property instanceof Blob + ? property + : typeof property === "object" && property !== null + ? JSON.stringify(property) + : \`\${property}\`, + ); + return formData; + }, new FormData()); + }, + [ContentType.UrlEncoded]: (input: any) => this.toQueryString(input), + }; + + protected mergeRequestParams( + params1: RequestParams, + params2?: RequestParams, + ): RequestParams { + return { + ...this.baseApiParams, + ...params1, + ...(params2 || {}), + headers: { + ...(this.baseApiParams.headers || {}), + ...(params1.headers || {}), + ...((params2 && params2.headers) || {}), + }, + }; + } + + protected createAbortSignal = ( + cancelToken: CancelToken, + ): AbortSignal | undefined => { + if (this.abortControllers.has(cancelToken)) { + const abortController = this.abortControllers.get(cancelToken); + if (abortController) { + return abortController.signal; + } + return void 0; + } + + const abortController = new AbortController(); + this.abortControllers.set(cancelToken, abortController); + return abortController.signal; + }; + + public abortRequest = (cancelToken: CancelToken) => { + const abortController = this.abortControllers.get(cancelToken); + + if (abortController) { + abortController.abort(); + this.abortControllers.delete(cancelToken); + } + }; + + public request = async ({ + body, + secure, + path, + type, + query, + format, + baseUrl, + cancelToken, + ...params + }: FullRequestParams): Promise> => { + const secureParams = + ((typeof secure === "boolean" ? secure : this.baseApiParams.secure) && + this.securityWorker && + (await this.securityWorker(this.securityData))) || + {}; + const requestParams = this.mergeRequestParams(params, secureParams); + const queryString = query && this.toQueryString(query); + const payloadFormatter = this.contentFormatters[type || ContentType.Json]; + const responseFormat = format || requestParams.format; + + return this.customFetch( + \`\${baseUrl || this.baseUrl || ""}\${path}\${queryString ? \`?\${queryString}\` : ""}\`, + { + ...requestParams, + headers: { + ...(requestParams.headers || {}), + ...(type && type !== ContentType.FormData + ? { "Content-Type": type } + : {}), + }, + signal: + (cancelToken + ? this.createAbortSignal(cancelToken) + : requestParams.signal) || null, + body: + typeof body === "undefined" || body === null + ? null + : payloadFormatter(body), + }, + ).then(async (response) => { + const r = response as HttpResponse; + r.data = null as unknown as T; + r.error = null as unknown as E; + + const responseToParse = responseFormat ? response.clone() : response; + const data = !responseFormat + ? r + : await responseToParse[responseFormat]() + .then((data) => { + if (r.ok) { + r.data = data; + } else { + r.error = data; + } + return r; + }) + .catch((e) => { + r.error = e; + return r; + }); + + if (cancelToken) { + this.abortControllers.delete(cancelToken); + } + + if (!response.ok) throw data; + return data; + }); + }; +} + +/** + * @title repro + * @version 2.0.0 + */ +export class Api< + SecurityDataType extends unknown, +> extends HttpClient { + hello = { + /** + * No description + * + * @name HelloList + * @request GET:/hello + */ + helloList: (params: RequestParams = {}) => + this.request({ + path: \`/hello\`, + method: "GET", + format: "json", + ...params, + }), + + /** + * No description + * + * @name GetRepository + * @request PUT:/hello + */ + getRepository: ( + { username, slug, ...query }: GetRepositoryParams, + params: RequestParams = {}, + ) => + this.request({ + path: \`/hello\`, + method: "PUT", + format: "json", + ...params, + }), + }; +} +" +`; diff --git a/tests/spec/paths/basic.test.ts b/tests/spec/paths/basic.test.ts new file mode 100644 index 000000000..4674a44c1 --- /dev/null +++ b/tests/spec/paths/basic.test.ts @@ -0,0 +1,39 @@ +import * as fs from "node:fs/promises"; +import * as os from "node:os"; +import * as path from "node:path"; +import { afterAll, beforeAll, describe, expect, test } from "vitest"; +import { generateApi } from "../../../src/index.js"; + +describe("basic", async () => { + let tmpdir = ""; + + beforeAll(async () => { + tmpdir = await fs.mkdtemp(path.join(os.tmpdir(), "swagger-typescript-api")); + }); + + afterAll(async () => { + await fs.rm(tmpdir, { recursive: true }); + }); + + test("paths(simplest-1-path)", async () => { + await generateApi({ + fileName: "schema", + input: path.resolve(import.meta.dirname, "schema.yaml"), + output: tmpdir, + silent: true, + extractRequestBody: true, + extractRequestParams: true, + extractResponses: true, + extractResponseError: true, + extractResponseBody: true, + extractEnums: true, + generateClient: true, + }); + + const content = await fs.readFile(path.join(tmpdir, "schema.ts"), { + encoding: "utf8", + }); + + expect(content).toMatchSnapshot(); + }); +}); diff --git a/tests/spec/paths/paths/repro.yaml b/tests/spec/paths/paths/repro.yaml new file mode 100644 index 000000000..42d3b6675 --- /dev/null +++ b/tests/spec/paths/paths/repro.yaml @@ -0,0 +1,42 @@ +hello: + get: + responses: + '200': + content: + application/json: + schema: + type: object + put: + operationId: getRepository + parameters: + - name: username + in: path + required: true + schema: + type: string + - name: slug + in: path + required: true + schema: + type: string + responses: + "200": + description: The repository + content: + application/json: + schema: + $ref: "./third.yaml/#/components/schemas/repository" + links: + repositoryPullRequests: + $ref: "./third.yaml/#/components/links/RepositoryPullRequests" +components: + schemas: + ReportSchema: + title: ReportSchema + type: object + properties: + id: + type: integer + description: Weather condition id + format: int32 + example: 803 \ No newline at end of file diff --git a/tests/spec/paths/paths/third.yaml b/tests/spec/paths/paths/third.yaml new file mode 100644 index 000000000..acc09ff7f --- /dev/null +++ b/tests/spec/paths/paths/third.yaml @@ -0,0 +1,23 @@ +components: + schemas: + user: + type: object + properties: + username: + type: string + uuid: + type: string + repository: + type: object + properties: + slug: + type: string + owner: + $ref: "#/components/schemas/user" + links: + RepositoryPullRequests: + # returns '#/components/schemas/pullrequest' + operationId: getPullRequestsByRepository + parameters: + username: $response.body#/owner/username + slug: $response.body#/slug \ No newline at end of file diff --git a/tests/spec/paths/schema.yaml b/tests/spec/paths/schema.yaml new file mode 100644 index 000000000..d86dc54e5 --- /dev/null +++ b/tests/spec/paths/schema.yaml @@ -0,0 +1,34 @@ +openapi: 3.0.2 +info: + version: 2.0.0 + title: repro + +paths: + /hello: + $ref: './paths/repro.yaml#/hello' + +components: + schemas: + ReportSchema: + $ref: './paths/repro.yaml#components/schemas/ReportSchema' + Weather: + title: Weather + type: object + properties: + id: + type: integer + description: Weather condition id + format: int32 + example: 803 + main: + type: string + description: Group of weather parameters (Rain, Snow, Extreme etc.) + example: Clouds + description: + type: string + description: Weather condition within the group + example: broken clouds + icon: + type: string + description: Weather icon id + example: 04n \ No newline at end of file diff --git a/types/index.ts b/types/index.ts index 48f5632f0..323df34d5 100644 --- a/types/index.ts +++ b/types/index.ts @@ -1,5 +1,6 @@ import type { ComponentTypeNameResolver } from "../src/component-type-name-resolver.js"; import type * as CONSTANTS from "../src/constants.js"; +import type { RefDetails } from "../src/resolved-swagger-schema.js"; import type { MonoSchemaParser } from "../src/schema-parser/mono-schema-parser.js"; import type { Translator } from "../src/translators/translator.js"; @@ -176,6 +177,15 @@ export interface Hooks { routeInfo: RawRouteInfo, templateRouteName: string, ) => string | undefined; + onFormatExternalTypeName?: ( + typeName: string, + refInfo: RefDetails, + ) => string | undefined; + onFixDuplicateExternalTypeName?: ( + typeName: string, + refInfo: RefDetails, + existedTypeNames: string[], + ) => string | undefined; } export type RouteNameRouteInfo = Record; diff --git a/vitest.config.ts b/vitest.config.ts index 797541199..5d11c8f83 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -2,7 +2,7 @@ import { defineConfig } from "vitest/config"; export default defineConfig({ test: { - testTimeout: 10000, + testTimeout: 100_000, typecheck: { enabled: true, }, diff --git a/yarn.lock b/yarn.lock index 0a7bc8989..12a14470e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5,6 +5,46 @@ __metadata: version: 8 cacheKey: 10c0 +"@apidevtools/json-schema-ref-parser@npm:14.0.1": + version: 14.0.1 + resolution: "@apidevtools/json-schema-ref-parser@npm:14.0.1" + dependencies: + "@types/json-schema": "npm:^7.0.15" + js-yaml: "npm:^4.1.0" + checksum: 10c0/f8aff4d32f66b81be0e641da175d359ec3e4191f9c65343b30f90cfbcfdbdb78b13e57c4a0a8d0574c828294abde56400a031858f61cf38b3309a4213698dc0c + languageName: node + linkType: hard + +"@apidevtools/openapi-schemas@npm:^2.1.0": + version: 2.1.0 + resolution: "@apidevtools/openapi-schemas@npm:2.1.0" + checksum: 10c0/f4aa0f9df32e474d166c84ef91bceb18fa1c4f44b5593879529154ef340846811ea57dc2921560f157f692262827d28d988dd6e19fb21f00320e9961964176b4 + languageName: node + linkType: hard + +"@apidevtools/swagger-methods@npm:^3.0.2": + version: 3.0.2 + resolution: "@apidevtools/swagger-methods@npm:3.0.2" + checksum: 10c0/8c390e8e50c0be7787ba0ba4c3758488bde7c66c2d995209b4b48c1f8bc988faf393cbb24a4bd1cd2d42ce5167c26538e8adea5c85eb922761b927e4dab9fa1c + languageName: node + linkType: hard + +"@apidevtools/swagger-parser@npm:12.0.0": + version: 12.0.0 + resolution: "@apidevtools/swagger-parser@npm:12.0.0" + dependencies: + "@apidevtools/json-schema-ref-parser": "npm:14.0.1" + "@apidevtools/openapi-schemas": "npm:^2.1.0" + "@apidevtools/swagger-methods": "npm:^3.0.2" + ajv: "npm:^8.17.1" + ajv-draft-04: "npm:^1.0.0" + call-me-maybe: "npm:^1.0.2" + peerDependencies: + openapi-types: ">=7" + checksum: 10c0/c905c49dc54788e8c697a61072b05dc3b51ba57b428ddbc683d364dc9981a1d07a5799d70c607858192d54b98b1256c380b2580d9b0f4fd55ff8400f6f285cd7 + languageName: node + linkType: hard + "@babel/generator@npm:^7.28.3": version: 7.28.3 resolution: "@babel/generator@npm:7.28.3" @@ -760,13 +800,13 @@ __metadata: linkType: hard "@napi-rs/wasm-runtime@npm:^1.0.5": - version: 1.0.6 - resolution: "@napi-rs/wasm-runtime@npm:1.0.6" + version: 1.0.5 + resolution: "@napi-rs/wasm-runtime@npm:1.0.5" dependencies: "@emnapi/core": "npm:^1.5.0" "@emnapi/runtime": "npm:^1.5.0" "@tybys/wasm-util": "npm:^0.10.1" - checksum: 10c0/af48168c6e13c970498fda3ce7238234a906bc69dd474dc9abd560cdf8a7dea6410147afec8f0191a1d19767c8347d8ec0125a8a93225312f7ac37e06e8c15ad + checksum: 10c0/8d29299933c57b6ead61f46fad5c3dfabc31e1356bbaf25c3a8ae57be0af0db0006a808f2c1bb16e28925e027f20e0856550dac94e015f56dd6ed53b38f9a385 languageName: node linkType: hard @@ -819,10 +859,10 @@ __metadata: languageName: node linkType: hard -"@oxc-project/types@npm:=0.93.0": - version: 0.93.0 - resolution: "@oxc-project/types@npm:0.93.0" - checksum: 10c0/29234a2bbbfb8095b1122709cf9e65e9969679e35435a379c612e671ca890b9db3f5b9c58043117346222662e11f80004829fb0da48aa3d8c74e9d32ec22e414 +"@oxc-project/types@npm:=0.90.0": + version: 0.90.0 + resolution: "@oxc-project/types@npm:0.90.0" + checksum: 10c0/ef684bda9ae220bcc9d9dbdc29d2b0645f229ee27f09459b29276513987be23e29244e07fb9ad3febae91139eb1fe38cd1eba66451fa7793b861af6be708eba7 languageName: node linkType: hard @@ -842,263 +882,263 @@ __metadata: languageName: node linkType: hard -"@rolldown/binding-android-arm64@npm:1.0.0-beta.41": - version: 1.0.0-beta.41 - resolution: "@rolldown/binding-android-arm64@npm:1.0.0-beta.41" +"@rolldown/binding-android-arm64@npm:1.0.0-beta.39": + version: 1.0.0-beta.39 + resolution: "@rolldown/binding-android-arm64@npm:1.0.0-beta.39" conditions: os=android & cpu=arm64 languageName: node linkType: hard -"@rolldown/binding-darwin-arm64@npm:1.0.0-beta.41": - version: 1.0.0-beta.41 - resolution: "@rolldown/binding-darwin-arm64@npm:1.0.0-beta.41" +"@rolldown/binding-darwin-arm64@npm:1.0.0-beta.39": + version: 1.0.0-beta.39 + resolution: "@rolldown/binding-darwin-arm64@npm:1.0.0-beta.39" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@rolldown/binding-darwin-x64@npm:1.0.0-beta.41": - version: 1.0.0-beta.41 - resolution: "@rolldown/binding-darwin-x64@npm:1.0.0-beta.41" +"@rolldown/binding-darwin-x64@npm:1.0.0-beta.39": + version: 1.0.0-beta.39 + resolution: "@rolldown/binding-darwin-x64@npm:1.0.0-beta.39" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@rolldown/binding-freebsd-x64@npm:1.0.0-beta.41": - version: 1.0.0-beta.41 - resolution: "@rolldown/binding-freebsd-x64@npm:1.0.0-beta.41" +"@rolldown/binding-freebsd-x64@npm:1.0.0-beta.39": + version: 1.0.0-beta.39 + resolution: "@rolldown/binding-freebsd-x64@npm:1.0.0-beta.39" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"@rolldown/binding-linux-arm-gnueabihf@npm:1.0.0-beta.41": - version: 1.0.0-beta.41 - resolution: "@rolldown/binding-linux-arm-gnueabihf@npm:1.0.0-beta.41" +"@rolldown/binding-linux-arm-gnueabihf@npm:1.0.0-beta.39": + version: 1.0.0-beta.39 + resolution: "@rolldown/binding-linux-arm-gnueabihf@npm:1.0.0-beta.39" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@rolldown/binding-linux-arm64-gnu@npm:1.0.0-beta.41": - version: 1.0.0-beta.41 - resolution: "@rolldown/binding-linux-arm64-gnu@npm:1.0.0-beta.41" +"@rolldown/binding-linux-arm64-gnu@npm:1.0.0-beta.39": + version: 1.0.0-beta.39 + resolution: "@rolldown/binding-linux-arm64-gnu@npm:1.0.0-beta.39" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@rolldown/binding-linux-arm64-musl@npm:1.0.0-beta.41": - version: 1.0.0-beta.41 - resolution: "@rolldown/binding-linux-arm64-musl@npm:1.0.0-beta.41" +"@rolldown/binding-linux-arm64-musl@npm:1.0.0-beta.39": + version: 1.0.0-beta.39 + resolution: "@rolldown/binding-linux-arm64-musl@npm:1.0.0-beta.39" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@rolldown/binding-linux-x64-gnu@npm:1.0.0-beta.41": - version: 1.0.0-beta.41 - resolution: "@rolldown/binding-linux-x64-gnu@npm:1.0.0-beta.41" +"@rolldown/binding-linux-x64-gnu@npm:1.0.0-beta.39": + version: 1.0.0-beta.39 + resolution: "@rolldown/binding-linux-x64-gnu@npm:1.0.0-beta.39" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@rolldown/binding-linux-x64-musl@npm:1.0.0-beta.41": - version: 1.0.0-beta.41 - resolution: "@rolldown/binding-linux-x64-musl@npm:1.0.0-beta.41" +"@rolldown/binding-linux-x64-musl@npm:1.0.0-beta.39": + version: 1.0.0-beta.39 + resolution: "@rolldown/binding-linux-x64-musl@npm:1.0.0-beta.39" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@rolldown/binding-openharmony-arm64@npm:1.0.0-beta.41": - version: 1.0.0-beta.41 - resolution: "@rolldown/binding-openharmony-arm64@npm:1.0.0-beta.41" +"@rolldown/binding-openharmony-arm64@npm:1.0.0-beta.39": + version: 1.0.0-beta.39 + resolution: "@rolldown/binding-openharmony-arm64@npm:1.0.0-beta.39" conditions: os=openharmony & cpu=arm64 languageName: node linkType: hard -"@rolldown/binding-wasm32-wasi@npm:1.0.0-beta.41": - version: 1.0.0-beta.41 - resolution: "@rolldown/binding-wasm32-wasi@npm:1.0.0-beta.41" +"@rolldown/binding-wasm32-wasi@npm:1.0.0-beta.39": + version: 1.0.0-beta.39 + resolution: "@rolldown/binding-wasm32-wasi@npm:1.0.0-beta.39" dependencies: "@napi-rs/wasm-runtime": "npm:^1.0.5" conditions: cpu=wasm32 languageName: node linkType: hard -"@rolldown/binding-win32-arm64-msvc@npm:1.0.0-beta.41": - version: 1.0.0-beta.41 - resolution: "@rolldown/binding-win32-arm64-msvc@npm:1.0.0-beta.41" +"@rolldown/binding-win32-arm64-msvc@npm:1.0.0-beta.39": + version: 1.0.0-beta.39 + resolution: "@rolldown/binding-win32-arm64-msvc@npm:1.0.0-beta.39" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@rolldown/binding-win32-ia32-msvc@npm:1.0.0-beta.41": - version: 1.0.0-beta.41 - resolution: "@rolldown/binding-win32-ia32-msvc@npm:1.0.0-beta.41" +"@rolldown/binding-win32-ia32-msvc@npm:1.0.0-beta.39": + version: 1.0.0-beta.39 + resolution: "@rolldown/binding-win32-ia32-msvc@npm:1.0.0-beta.39" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@rolldown/binding-win32-x64-msvc@npm:1.0.0-beta.41": - version: 1.0.0-beta.41 - resolution: "@rolldown/binding-win32-x64-msvc@npm:1.0.0-beta.41" +"@rolldown/binding-win32-x64-msvc@npm:1.0.0-beta.39": + version: 1.0.0-beta.39 + resolution: "@rolldown/binding-win32-x64-msvc@npm:1.0.0-beta.39" conditions: os=win32 & cpu=x64 languageName: node linkType: hard -"@rolldown/pluginutils@npm:1.0.0-beta.41": - version: 1.0.0-beta.41 - resolution: "@rolldown/pluginutils@npm:1.0.0-beta.41" - checksum: 10c0/2816175414341da4625928007774bfc65569437722806133fc33f0678a015555304009007f5fb88b979db96a9235b3f0c48c55bdc86fc05919e202a2347ecee9 +"@rolldown/pluginutils@npm:1.0.0-beta.39": + version: 1.0.0-beta.39 + resolution: "@rolldown/pluginutils@npm:1.0.0-beta.39" + checksum: 10c0/7158e897a674d89c9d9909cb472d71a50e8497b4189a521ae8e58c63ad9273ab53b4b7693f0ba4acc7bc966784af8a8f2998c59288182bcc6f7527bc11fb075f languageName: node linkType: hard -"@rollup/rollup-android-arm-eabi@npm:4.52.4": - version: 4.52.4 - resolution: "@rollup/rollup-android-arm-eabi@npm:4.52.4" +"@rollup/rollup-android-arm-eabi@npm:4.52.2": + version: 4.52.2 + resolution: "@rollup/rollup-android-arm-eabi@npm:4.52.2" conditions: os=android & cpu=arm languageName: node linkType: hard -"@rollup/rollup-android-arm64@npm:4.52.4": - version: 4.52.4 - resolution: "@rollup/rollup-android-arm64@npm:4.52.4" +"@rollup/rollup-android-arm64@npm:4.52.2": + version: 4.52.2 + resolution: "@rollup/rollup-android-arm64@npm:4.52.2" conditions: os=android & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-darwin-arm64@npm:4.52.4": - version: 4.52.4 - resolution: "@rollup/rollup-darwin-arm64@npm:4.52.4" +"@rollup/rollup-darwin-arm64@npm:4.52.2": + version: 4.52.2 + resolution: "@rollup/rollup-darwin-arm64@npm:4.52.2" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-darwin-x64@npm:4.52.4": - version: 4.52.4 - resolution: "@rollup/rollup-darwin-x64@npm:4.52.4" +"@rollup/rollup-darwin-x64@npm:4.52.2": + version: 4.52.2 + resolution: "@rollup/rollup-darwin-x64@npm:4.52.2" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@rollup/rollup-freebsd-arm64@npm:4.52.4": - version: 4.52.4 - resolution: "@rollup/rollup-freebsd-arm64@npm:4.52.4" +"@rollup/rollup-freebsd-arm64@npm:4.52.2": + version: 4.52.2 + resolution: "@rollup/rollup-freebsd-arm64@npm:4.52.2" conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-freebsd-x64@npm:4.52.4": - version: 4.52.4 - resolution: "@rollup/rollup-freebsd-x64@npm:4.52.4" +"@rollup/rollup-freebsd-x64@npm:4.52.2": + version: 4.52.2 + resolution: "@rollup/rollup-freebsd-x64@npm:4.52.2" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"@rollup/rollup-linux-arm-gnueabihf@npm:4.52.4": - version: 4.52.4 - resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.52.4" +"@rollup/rollup-linux-arm-gnueabihf@npm:4.52.2": + version: 4.52.2 + resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.52.2" conditions: os=linux & cpu=arm & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-arm-musleabihf@npm:4.52.4": - version: 4.52.4 - resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.52.4" +"@rollup/rollup-linux-arm-musleabihf@npm:4.52.2": + version: 4.52.2 + resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.52.2" conditions: os=linux & cpu=arm & libc=musl languageName: node linkType: hard -"@rollup/rollup-linux-arm64-gnu@npm:4.52.4": - version: 4.52.4 - resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.52.4" +"@rollup/rollup-linux-arm64-gnu@npm:4.52.2": + version: 4.52.2 + resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.52.2" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-arm64-musl@npm:4.52.4": - version: 4.52.4 - resolution: "@rollup/rollup-linux-arm64-musl@npm:4.52.4" +"@rollup/rollup-linux-arm64-musl@npm:4.52.2": + version: 4.52.2 + resolution: "@rollup/rollup-linux-arm64-musl@npm:4.52.2" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@rollup/rollup-linux-loong64-gnu@npm:4.52.4": - version: 4.52.4 - resolution: "@rollup/rollup-linux-loong64-gnu@npm:4.52.4" +"@rollup/rollup-linux-loong64-gnu@npm:4.52.2": + version: 4.52.2 + resolution: "@rollup/rollup-linux-loong64-gnu@npm:4.52.2" conditions: os=linux & cpu=loong64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-ppc64-gnu@npm:4.52.4": - version: 4.52.4 - resolution: "@rollup/rollup-linux-ppc64-gnu@npm:4.52.4" +"@rollup/rollup-linux-ppc64-gnu@npm:4.52.2": + version: 4.52.2 + resolution: "@rollup/rollup-linux-ppc64-gnu@npm:4.52.2" conditions: os=linux & cpu=ppc64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-riscv64-gnu@npm:4.52.4": - version: 4.52.4 - resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.52.4" +"@rollup/rollup-linux-riscv64-gnu@npm:4.52.2": + version: 4.52.2 + resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.52.2" conditions: os=linux & cpu=riscv64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-riscv64-musl@npm:4.52.4": - version: 4.52.4 - resolution: "@rollup/rollup-linux-riscv64-musl@npm:4.52.4" +"@rollup/rollup-linux-riscv64-musl@npm:4.52.2": + version: 4.52.2 + resolution: "@rollup/rollup-linux-riscv64-musl@npm:4.52.2" conditions: os=linux & cpu=riscv64 & libc=musl languageName: node linkType: hard -"@rollup/rollup-linux-s390x-gnu@npm:4.52.4": - version: 4.52.4 - resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.52.4" +"@rollup/rollup-linux-s390x-gnu@npm:4.52.2": + version: 4.52.2 + resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.52.2" conditions: os=linux & cpu=s390x & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-x64-gnu@npm:4.52.4": - version: 4.52.4 - resolution: "@rollup/rollup-linux-x64-gnu@npm:4.52.4" +"@rollup/rollup-linux-x64-gnu@npm:4.52.2": + version: 4.52.2 + resolution: "@rollup/rollup-linux-x64-gnu@npm:4.52.2" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-x64-musl@npm:4.52.4": - version: 4.52.4 - resolution: "@rollup/rollup-linux-x64-musl@npm:4.52.4" +"@rollup/rollup-linux-x64-musl@npm:4.52.2": + version: 4.52.2 + resolution: "@rollup/rollup-linux-x64-musl@npm:4.52.2" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@rollup/rollup-openharmony-arm64@npm:4.52.4": - version: 4.52.4 - resolution: "@rollup/rollup-openharmony-arm64@npm:4.52.4" +"@rollup/rollup-openharmony-arm64@npm:4.52.2": + version: 4.52.2 + resolution: "@rollup/rollup-openharmony-arm64@npm:4.52.2" conditions: os=openharmony & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-win32-arm64-msvc@npm:4.52.4": - version: 4.52.4 - resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.52.4" +"@rollup/rollup-win32-arm64-msvc@npm:4.52.2": + version: 4.52.2 + resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.52.2" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-win32-ia32-msvc@npm:4.52.4": - version: 4.52.4 - resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.52.4" +"@rollup/rollup-win32-ia32-msvc@npm:4.52.2": + version: 4.52.2 + resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.52.2" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@rollup/rollup-win32-x64-gnu@npm:4.52.4": - version: 4.52.4 - resolution: "@rollup/rollup-win32-x64-gnu@npm:4.52.4" +"@rollup/rollup-win32-x64-gnu@npm:4.52.2": + version: 4.52.2 + resolution: "@rollup/rollup-win32-x64-gnu@npm:4.52.2" conditions: os=win32 & cpu=x64 languageName: node linkType: hard -"@rollup/rollup-win32-x64-msvc@npm:4.52.4": - version: 4.52.4 - resolution: "@rollup/rollup-win32-x64-msvc@npm:4.52.4" +"@rollup/rollup-win32-x64-msvc@npm:4.52.2": + version: 4.52.2 + resolution: "@rollup/rollup-win32-x64-msvc@npm:4.52.2" conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -1203,6 +1243,13 @@ __metadata: languageName: node linkType: hard +"@types/json-schema@npm:^7.0.15": + version: 7.0.15 + resolution: "@types/json-schema@npm:7.0.15" + checksum: 10c0/a996a745e6c5d60292f36731dd41341339d4eeed8180bb09226e5c8d23759067692b1d88e5d91d72ee83dfc00d3aca8e7bd43ea120516c17922cbcb7c3e252db + languageName: node + linkType: hard + "@types/lodash@npm:^4.17.20": version: 4.17.20 resolution: "@types/lodash@npm:4.17.20" @@ -1243,6 +1290,13 @@ __metadata: languageName: node linkType: hard +"@types/trusted-types@npm:^2.0.7": + version: 2.0.7 + resolution: "@types/trusted-types@npm:2.0.7" + checksum: 10c0/4c4855f10de7c6c135e0d32ce462419d8abbbc33713b31d294596c0cc34ae1fa6112a2f9da729c8f7a20707782b0d69da3b1f8df6645b0366d08825ca1522e0c + languageName: node + linkType: hard + "@types/unist@npm:*": version: 3.0.3 resolution: "@types/unist@npm:3.0.3" @@ -1347,6 +1401,30 @@ __metadata: languageName: node linkType: hard +"ajv-draft-04@npm:^1.0.0": + version: 1.0.0 + resolution: "ajv-draft-04@npm:1.0.0" + peerDependencies: + ajv: ^8.5.0 + peerDependenciesMeta: + ajv: + optional: true + checksum: 10c0/6044310bd38c17d77549fd326bd40ce1506fa10b0794540aa130180808bf94117fac8c9b448c621512bea60e4a947278f6a978e87f10d342950c15b33ddd9271 + languageName: node + linkType: hard + +"ajv@npm:^8.17.1": + version: 8.17.1 + resolution: "ajv@npm:8.17.1" + dependencies: + fast-deep-equal: "npm:^3.1.3" + fast-uri: "npm:^3.0.1" + json-schema-traverse: "npm:^1.0.0" + require-from-string: "npm:^2.0.2" + checksum: 10c0/ec3ba10a573c6b60f94639ffc53526275917a2df6810e4ab5a6b959d87459f9ef3f00d5e7865b82677cb7d21590355b34da14d1d0b9c32d75f95a187e76fff35 + languageName: node + linkType: hard + "ansi-colors@npm:^4.1.1, ansi-colors@npm:^4.1.3": version: 4.1.3 resolution: "ansi-colors@npm:4.1.3" @@ -1384,10 +1462,10 @@ __metadata: languageName: node linkType: hard -"ansis@npm:=4.2.0, ansis@npm:^4.1.0": - version: 4.2.0 - resolution: "ansis@npm:4.2.0" - checksum: 10c0/cd6a7a681ecd36e72e0d79c1e34f1f3bcb1b15bcbb6f0f8969b4228062d3bfebbef468e09771b00d93b2294370b34f707599d4a113542a876de26823b795b5d2 +"ansis@npm:^4.0.0, ansis@npm:^4.1.0": + version: 4.1.0 + resolution: "ansis@npm:4.1.0" + checksum: 10c0/df62d017a7791babdaf45b93f930d2cfd6d1dab5568b610735c11434c9a5ef8f513740e7cfd80bcbc3530fc8bd892b88f8476f26621efc251230e53cbd1a2c24 languageName: node linkType: hard @@ -1431,20 +1509,6 @@ __metadata: languageName: node linkType: hard -"async-function@npm:^1.0.0": - version: 1.0.0 - resolution: "async-function@npm:1.0.0" - checksum: 10c0/669a32c2cb7e45091330c680e92eaeb791bc1d4132d827591e499cd1f776ff5a873e77e5f92d0ce795a8d60f10761dec9ddfe7225a5de680f5d357f67b1aac73 - languageName: node - linkType: hard - -"async-generator-function@npm:^1.0.0": - version: 1.0.0 - resolution: "async-generator-function@npm:1.0.0" - checksum: 10c0/2c50ef856c543ad500d8d8777d347e3c1ba623b93e99c9263ecc5f965c1b12d2a140e2ab6e43c3d0b85366110696f28114649411cbcd10b452a92a2318394186 - languageName: node - linkType: hard - "asynckit@npm:^0.4.0": version: 0.4.0 resolution: "asynckit@npm:0.4.0" @@ -1566,7 +1630,7 @@ __metadata: languageName: node linkType: hard -"call-me-maybe@npm:^1.0.1": +"call-me-maybe@npm:^1.0.1, call-me-maybe@npm:^1.0.2": version: 1.0.2 resolution: "call-me-maybe@npm:1.0.2" checksum: 10c0/8eff5dbb61141ebb236ed71b4e9549e488bcb5451c48c11e5667d5c75b0532303788a1101e6978cafa2d0c8c1a727805599c2741e3e0982855c9f1d78cd06c9f @@ -1632,6 +1696,15 @@ __metadata: languageName: node linkType: hard +"class-variance-authority@npm:^0.7.1": + version: 0.7.1 + resolution: "class-variance-authority@npm:0.7.1" + dependencies: + clsx: "npm:^2.1.1" + checksum: 10c0/0f438cea22131808b99272de0fa933c2532d5659773bfec0c583de7b3f038378996d3350683426b8e9c74a6286699382106d71fbec52f0dd5fbb191792cccb5b + languageName: node + linkType: hard + "cliui@npm:^8.0.1": version: 8.0.1 resolution: "cliui@npm:8.0.1" @@ -1643,6 +1716,13 @@ __metadata: languageName: node linkType: hard +"clsx@npm:^2.1.1": + version: 2.1.1 + resolution: "clsx@npm:2.1.1" + checksum: 10c0/c4c8eb865f8c82baab07e71bfa8897c73454881c4f99d6bc81585aecd7c441746c1399d08363dc096c550cceaf97bd4ce1e8854e1771e9998d9f94c4fe075839 + languageName: node + linkType: hard + "color-convert@npm:^2.0.1": version: 2.0.1 resolution: "color-convert@npm:2.0.1" @@ -1700,6 +1780,13 @@ __metadata: languageName: node linkType: hard +"dayjs@npm:^1.11.13": + version: 1.11.18 + resolution: "dayjs@npm:1.11.18" + checksum: 10c0/83b67f5d977e2634edf4f5abdd91d9041a696943143638063016915d2cd8c7e57e0751e40379a07ebca8be7a48dd380bef8752d22a63670f2d15970e34f96d7a + languageName: node + linkType: hard + "debug@npm:4, debug@npm:^4.3.4, debug@npm:^4.4.1, debug@npm:^4.4.3": version: 4.4.3 resolution: "debug@npm:4.4.3" @@ -1763,10 +1850,22 @@ __metadata: languageName: node linkType: hard +"dompurify@npm:^3.2.6": + version: 3.2.7 + resolution: "dompurify@npm:3.2.7" + dependencies: + "@types/trusted-types": "npm:^2.0.7" + dependenciesMeta: + "@types/trusted-types": + optional: true + checksum: 10c0/d41bb31a72f1acdf9b84c56723c549924b05d92a39a15bd8c40bec9007ff80d5fccf844bc53ee12af5b69044f9a7ce24a1e71c267a4f49cf38711379ed8c1363 + languageName: node + linkType: hard + "dotenv@npm:^17.2.2": - version: 17.2.3 - resolution: "dotenv@npm:17.2.3" - checksum: 10c0/c884403209f713214a1b64d4d1defa4934c2aa5b0002f5a670ae298a51e3c3ad3ba79dfee2f8df49f01ae74290fcd9acdb1ab1d09c7bfb42b539036108bb2ba0 + version: 17.2.2 + resolution: "dotenv@npm:17.2.2" + checksum: 10c0/be66513504590aff6eccb14167625aed9bd42ce80547f4fe5d195860211971a7060949b57108dfaeaf90658f79e40edccd3f233f0a978bff507b5b1565ae162b languageName: node linkType: hard @@ -2067,6 +2166,13 @@ __metadata: languageName: node linkType: hard +"fast-deep-equal@npm:^3.1.3": + version: 3.1.3 + resolution: "fast-deep-equal@npm:3.1.3" + checksum: 10c0/40dedc862eb8992c54579c66d914635afbec43350afbbe991235fdcb4e3a8d5af1b23ae7e79bef7d4882d0ecee06c3197488026998fb19f72dc95acff1d1b1d0 + languageName: node + linkType: hard + "fast-glob@npm:^3.2.9": version: 3.3.3 resolution: "fast-glob@npm:3.3.3" @@ -2087,6 +2193,13 @@ __metadata: languageName: node linkType: hard +"fast-uri@npm:^3.0.1": + version: 3.1.0 + resolution: "fast-uri@npm:3.1.0" + checksum: 10c0/44364adca566f70f40d1e9b772c923138d47efeac2ae9732a872baafd77061f26b097ba2f68f0892885ad177becd065520412b8ffeec34b16c99433c5b9e2de7 + languageName: node + linkType: hard + "fastq@npm:^1.6.0": version: 1.19.1 resolution: "fastq@npm:1.19.1" @@ -2217,13 +2330,6 @@ __metadata: languageName: node linkType: hard -"generator-function@npm:^2.0.0": - version: 2.0.1 - resolution: "generator-function@npm:2.0.1" - checksum: 10c0/8a9f59df0f01cfefafdb3b451b80555e5cf6d76487095db91ac461a0e682e4ff7a9dbce15f4ecec191e53586d59eece01949e05a4b4492879600bbbe8e28d6b8 - languageName: node - linkType: hard - "get-caller-file@npm:^2.0.5": version: 2.0.5 resolution: "get-caller-file@npm:2.0.5" @@ -2232,23 +2338,20 @@ __metadata: linkType: hard "get-intrinsic@npm:^1.2.6": - version: 1.3.1 - resolution: "get-intrinsic@npm:1.3.1" + version: 1.3.0 + resolution: "get-intrinsic@npm:1.3.0" dependencies: - async-function: "npm:^1.0.0" - async-generator-function: "npm:^1.0.0" call-bind-apply-helpers: "npm:^1.0.2" es-define-property: "npm:^1.0.1" es-errors: "npm:^1.3.0" es-object-atoms: "npm:^1.1.1" function-bind: "npm:^1.1.2" - generator-function: "npm:^2.0.0" get-proto: "npm:^1.0.1" gopd: "npm:^1.2.0" has-symbols: "npm:^1.1.0" hasown: "npm:^2.0.2" math-intrinsics: "npm:^1.1.0" - checksum: 10c0/9f4ab0cf7efe0fd2c8185f52e6f637e708f3a112610c88869f8f041bb9ecc2ce44bf285dfdbdc6f4f7c277a5b88d8e94a432374d97cca22f3de7fc63795deb5d + checksum: 10c0/52c81808af9a8130f581e6a6a83e1ba4a9f703359e7a438d1369a5267a25412322f03dcbd7c549edaef0b6214a0630a28511d7df0130c93cfd380f4fa0b5b66a languageName: node linkType: hard @@ -2528,11 +2631,11 @@ __metadata: linkType: hard "jiti@npm:^2.5.1": - version: 2.6.1 - resolution: "jiti@npm:2.6.1" + version: 2.6.0 + resolution: "jiti@npm:2.6.0" bin: jiti: lib/jiti-cli.mjs - checksum: 10c0/79b2e96a8e623f66c1b703b98ec1b8be4500e1d217e09b09e343471bbb9c105381b83edbb979d01cef18318cc45ce6e153571b6c83122170eefa531c64b6789b + checksum: 10c0/5002ccecdb02e85413e5bfe3819a5ac458dcce12b358c556b6cf17b5b6cbedd36514f6a67d4aa2b290caa2b933406502a1985d0bfee784ece788e90a0392d534 languageName: node linkType: hard @@ -2555,6 +2658,17 @@ __metadata: languageName: node linkType: hard +"js-yaml@npm:^4.1.0": + version: 4.1.0 + resolution: "js-yaml@npm:4.1.0" + dependencies: + argparse: "npm:^2.0.1" + bin: + js-yaml: bin/js-yaml.js + checksum: 10c0/184a24b4eaacfce40ad9074c64fd42ac83cf74d8c8cd137718d456ced75051229e5061b8633c3366b8aada17945a7a356b337828c19da92b51ae62126575018f + languageName: node + linkType: hard + "jsesc@npm:^3.0.2": version: 3.1.0 resolution: "jsesc@npm:3.1.0" @@ -2564,6 +2678,13 @@ __metadata: languageName: node linkType: hard +"json-schema-traverse@npm:^1.0.0": + version: 1.0.0 + resolution: "json-schema-traverse@npm:1.0.0" + checksum: 10c0/71e30015d7f3d6dc1c316d6298047c8ef98a06d31ad064919976583eb61e1018a60a0067338f0f79cabc00d84af3fcc489bd48ce8a46ea165d9541ba17fb30c6 + languageName: node + linkType: hard + "jsonfile@npm:^4.0.0": version: 4.0.0 resolution: "jsonfile@npm:4.0.0" @@ -2828,7 +2949,7 @@ __metadata: languageName: node linkType: hard -"nanoid@npm:^5.1.6": +"nanoid@npm:^5.1.5, nanoid@npm:^5.1.6": version: 5.1.6 resolution: "nanoid@npm:5.1.6" bin: @@ -3271,6 +3392,13 @@ __metadata: languageName: node linkType: hard +"require-from-string@npm:^2.0.2": + version: 2.0.2 + resolution: "require-from-string@npm:2.0.2" + checksum: 10c0/aaa267e0c5b022fc5fd4eef49d8285086b15f2a1c54b28240fdf03599cbd9c26049fee3eab894f2e1f6ca65e513b030a7c264201e3f005601e80c49fb2937ce2 + languageName: node + linkType: hard + "resolve-from@npm:^5.0.0": version: 5.0.0 resolution: "resolve-from@npm:5.0.0" @@ -3332,26 +3460,26 @@ __metadata: linkType: hard "rolldown@npm:latest": - version: 1.0.0-beta.41 - resolution: "rolldown@npm:1.0.0-beta.41" - dependencies: - "@oxc-project/types": "npm:=0.93.0" - "@rolldown/binding-android-arm64": "npm:1.0.0-beta.41" - "@rolldown/binding-darwin-arm64": "npm:1.0.0-beta.41" - "@rolldown/binding-darwin-x64": "npm:1.0.0-beta.41" - "@rolldown/binding-freebsd-x64": "npm:1.0.0-beta.41" - "@rolldown/binding-linux-arm-gnueabihf": "npm:1.0.0-beta.41" - "@rolldown/binding-linux-arm64-gnu": "npm:1.0.0-beta.41" - "@rolldown/binding-linux-arm64-musl": "npm:1.0.0-beta.41" - "@rolldown/binding-linux-x64-gnu": "npm:1.0.0-beta.41" - "@rolldown/binding-linux-x64-musl": "npm:1.0.0-beta.41" - "@rolldown/binding-openharmony-arm64": "npm:1.0.0-beta.41" - "@rolldown/binding-wasm32-wasi": "npm:1.0.0-beta.41" - "@rolldown/binding-win32-arm64-msvc": "npm:1.0.0-beta.41" - "@rolldown/binding-win32-ia32-msvc": "npm:1.0.0-beta.41" - "@rolldown/binding-win32-x64-msvc": "npm:1.0.0-beta.41" - "@rolldown/pluginutils": "npm:1.0.0-beta.41" - ansis: "npm:=4.2.0" + version: 1.0.0-beta.39 + resolution: "rolldown@npm:1.0.0-beta.39" + dependencies: + "@oxc-project/types": "npm:=0.90.0" + "@rolldown/binding-android-arm64": "npm:1.0.0-beta.39" + "@rolldown/binding-darwin-arm64": "npm:1.0.0-beta.39" + "@rolldown/binding-darwin-x64": "npm:1.0.0-beta.39" + "@rolldown/binding-freebsd-x64": "npm:1.0.0-beta.39" + "@rolldown/binding-linux-arm-gnueabihf": "npm:1.0.0-beta.39" + "@rolldown/binding-linux-arm64-gnu": "npm:1.0.0-beta.39" + "@rolldown/binding-linux-arm64-musl": "npm:1.0.0-beta.39" + "@rolldown/binding-linux-x64-gnu": "npm:1.0.0-beta.39" + "@rolldown/binding-linux-x64-musl": "npm:1.0.0-beta.39" + "@rolldown/binding-openharmony-arm64": "npm:1.0.0-beta.39" + "@rolldown/binding-wasm32-wasi": "npm:1.0.0-beta.39" + "@rolldown/binding-win32-arm64-msvc": "npm:1.0.0-beta.39" + "@rolldown/binding-win32-ia32-msvc": "npm:1.0.0-beta.39" + "@rolldown/binding-win32-x64-msvc": "npm:1.0.0-beta.39" + "@rolldown/pluginutils": "npm:1.0.0-beta.39" + ansis: "npm:^4.0.0" dependenciesMeta: "@rolldown/binding-android-arm64": optional: true @@ -3383,36 +3511,36 @@ __metadata: optional: true bin: rolldown: bin/cli.mjs - checksum: 10c0/3c375d0d74a898d18f6c047a83d1d7416ef5e5672783ad604ee26c644329028caa1bd270c62238beb2cf978385043a2a182e4aa5aded9fa3225bc8162ca081e1 + checksum: 10c0/21de370b1f79263421f1435ab3e151ac73aa1b933dcd5250e0257b99d50cb8ba5daa45726db2eb0752981c97fc2340d2107464d411377fe2ae0f54ac7f4371c2 languageName: node linkType: hard "rollup@npm:^4.43.0": - version: 4.52.4 - resolution: "rollup@npm:4.52.4" - dependencies: - "@rollup/rollup-android-arm-eabi": "npm:4.52.4" - "@rollup/rollup-android-arm64": "npm:4.52.4" - "@rollup/rollup-darwin-arm64": "npm:4.52.4" - "@rollup/rollup-darwin-x64": "npm:4.52.4" - "@rollup/rollup-freebsd-arm64": "npm:4.52.4" - "@rollup/rollup-freebsd-x64": "npm:4.52.4" - "@rollup/rollup-linux-arm-gnueabihf": "npm:4.52.4" - "@rollup/rollup-linux-arm-musleabihf": "npm:4.52.4" - "@rollup/rollup-linux-arm64-gnu": "npm:4.52.4" - "@rollup/rollup-linux-arm64-musl": "npm:4.52.4" - "@rollup/rollup-linux-loong64-gnu": "npm:4.52.4" - "@rollup/rollup-linux-ppc64-gnu": "npm:4.52.4" - "@rollup/rollup-linux-riscv64-gnu": "npm:4.52.4" - "@rollup/rollup-linux-riscv64-musl": "npm:4.52.4" - "@rollup/rollup-linux-s390x-gnu": "npm:4.52.4" - "@rollup/rollup-linux-x64-gnu": "npm:4.52.4" - "@rollup/rollup-linux-x64-musl": "npm:4.52.4" - "@rollup/rollup-openharmony-arm64": "npm:4.52.4" - "@rollup/rollup-win32-arm64-msvc": "npm:4.52.4" - "@rollup/rollup-win32-ia32-msvc": "npm:4.52.4" - "@rollup/rollup-win32-x64-gnu": "npm:4.52.4" - "@rollup/rollup-win32-x64-msvc": "npm:4.52.4" + version: 4.52.2 + resolution: "rollup@npm:4.52.2" + dependencies: + "@rollup/rollup-android-arm-eabi": "npm:4.52.2" + "@rollup/rollup-android-arm64": "npm:4.52.2" + "@rollup/rollup-darwin-arm64": "npm:4.52.2" + "@rollup/rollup-darwin-x64": "npm:4.52.2" + "@rollup/rollup-freebsd-arm64": "npm:4.52.2" + "@rollup/rollup-freebsd-x64": "npm:4.52.2" + "@rollup/rollup-linux-arm-gnueabihf": "npm:4.52.2" + "@rollup/rollup-linux-arm-musleabihf": "npm:4.52.2" + "@rollup/rollup-linux-arm64-gnu": "npm:4.52.2" + "@rollup/rollup-linux-arm64-musl": "npm:4.52.2" + "@rollup/rollup-linux-loong64-gnu": "npm:4.52.2" + "@rollup/rollup-linux-ppc64-gnu": "npm:4.52.2" + "@rollup/rollup-linux-riscv64-gnu": "npm:4.52.2" + "@rollup/rollup-linux-riscv64-musl": "npm:4.52.2" + "@rollup/rollup-linux-s390x-gnu": "npm:4.52.2" + "@rollup/rollup-linux-x64-gnu": "npm:4.52.2" + "@rollup/rollup-linux-x64-musl": "npm:4.52.2" + "@rollup/rollup-openharmony-arm64": "npm:4.52.2" + "@rollup/rollup-win32-arm64-msvc": "npm:4.52.2" + "@rollup/rollup-win32-ia32-msvc": "npm:4.52.2" + "@rollup/rollup-win32-x64-gnu": "npm:4.52.2" + "@rollup/rollup-win32-x64-msvc": "npm:4.52.2" "@types/estree": "npm:1.0.8" fsevents: "npm:~2.3.2" dependenciesMeta: @@ -3464,7 +3592,7 @@ __metadata: optional: true bin: rollup: dist/bin/rollup - checksum: 10c0/aaec0f57e887d4fb37d152f93cf7133954eec79d11643e95de768ec9a377f08793b1745c648ca65a0dcc6c795c4d9ca398724d013e5745de270e88a543782aea + checksum: 10c0/2d457b11bbb904f40bde943acb1a784732ef8d8ce7d528e1dc955f6d11df4f9c6ac7885675bac677cface13e420b63dfc8eea959446fbb3329841e49767f7e7d languageName: node linkType: hard @@ -3709,11 +3837,11 @@ __metadata: linkType: hard "strip-literal@npm:^3.0.0": - version: 3.1.0 - resolution: "strip-literal@npm:3.1.0" + version: 3.0.0 + resolution: "strip-literal@npm:3.0.0" dependencies: js-tokens: "npm:^9.0.1" - checksum: 10c0/50918f669915d9ad0fe4b7599902b735f853f2201c97791ead00104a654259c0c61bc2bc8fa3db05109339b61f4cf09e47b94ecc874ffbd0e013965223893af8 + checksum: 10c0/d81657f84aba42d4bbaf2a677f7e7f34c1f3de5a6726db8bc1797f9c0b303ba54d4660383a74bde43df401cf37cce1dff2c842c55b077a4ceee11f9e31fba828 languageName: node linkType: hard @@ -3728,6 +3856,7 @@ __metadata: version: 0.0.0-use.local resolution: "swagger-typescript-api@workspace:." dependencies: + "@apidevtools/swagger-parser": "npm:12.0.0" "@biomejs/biome": "npm:2.2.5" "@biomejs/js-api": "npm:3.0.0" "@biomejs/wasm-nodejs": "npm:2.2.5" @@ -3754,6 +3883,7 @@ __metadata: typescript: "npm:~5.9.3" vitest: "npm:3.2.4" yaml: "npm:^2.8.1" + yummies: "npm:5.7.0" bin: sta: ./dist/cli.js swagger-typescript-api: ./dist/cli.js @@ -3783,6 +3913,13 @@ __metadata: languageName: node linkType: hard +"tailwind-merge@npm:^3.3.1": + version: 3.3.1 + resolution: "tailwind-merge@npm:3.3.1" + checksum: 10c0/b84c6a78d4669fa12bf5ab8f0cdc4400a3ce0a7c006511af4af4be70bb664a27466dbe13ee9e3b31f50ddf6c51d380e8192ce0ec9effce23ca729d71a9f63818 + languageName: node + linkType: hard + "tar@npm:^7.4.3": version: 7.5.1 resolution: "tar@npm:7.5.1" @@ -4032,8 +4169,8 @@ __metadata: linkType: hard "vite@npm:^5.0.0 || ^6.0.0 || ^7.0.0-0": - version: 7.1.9 - resolution: "vite@npm:7.1.9" + version: 7.1.7 + resolution: "vite@npm:7.1.7" dependencies: esbuild: "npm:^0.25.0" fdir: "npm:^6.5.0" @@ -4082,7 +4219,7 @@ __metadata: optional: true bin: vite: bin/vite.js - checksum: 10c0/f628f903a137c1410232558bde99c223ea00a090bda6af77752c61f912955f0050aac12d3cfe024d08a0f150ff6fab61b3d0be75d634a59b94d49f525392e1f7 + checksum: 10c0/3f6bd61a65aaa81368f4dda804f0e23b103664724218ccb5a0b1a0c7e284df498107b57ced951dc40ae4c5d472435bc8fb5c836414e729ee7e102809eaf6ff80 languageName: node linkType: hard @@ -4273,3 +4410,25 @@ __metadata: checksum: 10c0/ccd7e723e61ad5965fffbb791366db689572b80cca80e0f96aad968dfff4156cd7cd1ad18607afe1046d8241e6fb2d6c08bf7fa7bfb5eaec818735d8feac8f05 languageName: node linkType: hard + +"yummies@npm:5.7.0": + version: 5.7.0 + resolution: "yummies@npm:5.7.0" + dependencies: + class-variance-authority: "npm:^0.7.1" + clsx: "npm:^2.1.1" + dayjs: "npm:^1.11.13" + dompurify: "npm:^3.2.6" + nanoid: "npm:^5.1.5" + tailwind-merge: "npm:^3.3.1" + peerDependencies: + mobx: ^6.12.4 + react: ^18 || ^19 + peerDependenciesMeta: + mobx: + optional: true + react: + optional: true + checksum: 10c0/e7b107de6c7a27b68cf89f8583b79922cefde38065110a5c6031e4c8963be91ce4479ecfc7c11089f9e173f14717d0e95bf4d8daa4d3229a96fa55c39c25bb12 + languageName: node + linkType: hard