@kubb/plugin-oas 5.0.0-alpha.3 → 5.0.0-alpha.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/SchemaMapper-CeavHZlp.cjs.map +1 -1
- package/dist/SchemaMapper-CqMkO2T1.js.map +1 -1
- package/dist/{SchemaMapper-SneuY1wg.d.ts → SchemaMapper-gGBRHCTB.d.ts} +2 -2
- package/dist/{createGenerator-jtR_okrd.d.ts → createGenerator-eLDSS4c0.d.ts} +114 -63
- package/dist/{generators-vAAte6w6.cjs → generators-85sP4GIS.cjs} +7 -7
- package/dist/generators-85sP4GIS.cjs.map +1 -0
- package/dist/{generators-B8HiBWvT.js → generators-hPE06pZB.js} +7 -7
- package/dist/generators-hPE06pZB.js.map +1 -0
- package/dist/generators.cjs +1 -1
- package/dist/generators.d.ts +4 -3
- package/dist/generators.js +1 -1
- package/dist/{getFooter-Pw3tLCiV.js → getFooter-Dz4u5Mg4.js} +5 -2
- package/dist/getFooter-Dz4u5Mg4.js.map +1 -0
- package/dist/{getFooter-BBzsC616.cjs → getFooter-gshcRE1-.cjs} +5 -2
- package/dist/getFooter-gshcRE1-.cjs.map +1 -0
- package/dist/hooks.cjs +25 -21
- package/dist/hooks.cjs.map +1 -1
- package/dist/hooks.d.ts +5 -3
- package/dist/hooks.js +27 -23
- package/dist/hooks.js.map +1 -1
- package/dist/index.cjs +50 -45
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +26 -52
- package/dist/index.js +49 -44
- package/dist/index.js.map +1 -1
- package/dist/mocks.d.ts +1 -1
- package/dist/{requestBody-BJJL0mpy.cjs → requestBody-94hwM4b-.cjs} +115 -304
- package/dist/requestBody-94hwM4b-.cjs.map +1 -0
- package/dist/{requestBody-CSL-jLGQ.js → requestBody-BO3N7fWH.js} +107 -290
- package/dist/requestBody-BO3N7fWH.js.map +1 -0
- package/dist/utils.cjs +61 -11
- package/dist/utils.cjs.map +1 -1
- package/dist/utils.d.ts +3 -4
- package/dist/utils.js +61 -11
- package/dist/utils.js.map +1 -1
- package/package.json +8 -12
- package/src/OperationGenerator.ts +70 -84
- package/src/SchemaGenerator.ts +59 -80
- package/src/SchemaMapper.ts +1 -1
- package/src/generators/createGenerator.ts +13 -17
- package/src/generators/createReactGenerator.ts +12 -15
- package/src/generators/index.ts +2 -2
- package/src/generators/jsonGenerator.ts +3 -3
- package/src/generators/types.ts +5 -43
- package/src/hooks/useOas.ts +5 -2
- package/src/hooks/useOperationManager.ts +20 -20
- package/src/hooks/useSchemaManager.ts +5 -6
- package/src/index.ts +2 -2
- package/src/plugin.ts +13 -9
- package/src/types.ts +11 -5
- package/src/utils/getBanner.ts +1 -1
- package/src/utils/getFooter.ts +1 -1
- package/src/utils/getImports.ts +1 -1
- package/src/utils/getParams.ts +2 -2
- package/src/utils.tsx +51 -151
- package/dist/generators-B8HiBWvT.js.map +0 -1
- package/dist/generators-vAAte6w6.cjs.map +0 -1
- package/dist/getFooter-BBzsC616.cjs.map +0 -1
- package/dist/getFooter-Pw3tLCiV.js.map +0 -1
- package/dist/requestBody-BJJL0mpy.cjs.map +0 -1
- package/dist/requestBody-CSL-jLGQ.js.map +0 -1
package/dist/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","names":["#options","#transformParam","#eachParam"],"sources":["../../../internals/utils/src/reserved.ts","../../../internals/utils/src/urlPath.ts","../src/utils/getComments.ts","../src/utils/getImports.ts","../src/utils/getParams.ts","../src/utils/getSchemas.ts","../src/utils/paramsCasing.ts"],"sourcesContent":["/**\n * JavaScript and Java reserved words.\n * @link https://github.com/jonschlinkert/reserved/blob/master/index.js\n */\nconst reservedWords = [\n 'abstract',\n 'arguments',\n 'boolean',\n 'break',\n 'byte',\n 'case',\n 'catch',\n 'char',\n 'class',\n 'const',\n 'continue',\n 'debugger',\n 'default',\n 'delete',\n 'do',\n 'double',\n 'else',\n 'enum',\n 'eval',\n 'export',\n 'extends',\n 'false',\n 'final',\n 'finally',\n 'float',\n 'for',\n 'function',\n 'goto',\n 'if',\n 'implements',\n 'import',\n 'in',\n 'instanceof',\n 'int',\n 'interface',\n 'let',\n 'long',\n 'native',\n 'new',\n 'null',\n 'package',\n 'private',\n 'protected',\n 'public',\n 'return',\n 'short',\n 'static',\n 'super',\n 'switch',\n 'synchronized',\n 'this',\n 'throw',\n 'throws',\n 'transient',\n 'true',\n 'try',\n 'typeof',\n 'var',\n 'void',\n 'volatile',\n 'while',\n 'with',\n 'yield',\n 'Array',\n 'Date',\n 'hasOwnProperty',\n 'Infinity',\n 'isFinite',\n 'isNaN',\n 'isPrototypeOf',\n 'length',\n 'Math',\n 'name',\n 'NaN',\n 'Number',\n 'Object',\n 'prototype',\n 'String',\n 'toString',\n 'undefined',\n 'valueOf',\n]\n\n/**\n * Prefixes a word with `_` when it is a reserved JavaScript/Java identifier\n * or starts with a digit.\n */\nexport function transformReservedWord(word: string): string {\n const firstChar = word.charCodeAt(0)\n if (word && (reservedWords.includes(word) || (firstChar >= 48 && firstChar <= 57))) {\n return `_${word}`\n }\n return word\n}\n\n/**\n * Returns `true` when `name` is a syntactically valid JavaScript variable name.\n */\nexport function isValidVarName(name: string): boolean {\n try {\n new Function(`var ${name}`)\n } catch {\n return false\n }\n return true\n}\n","import { camelCase } from './casing.ts'\nimport { isValidVarName } from './reserved.ts'\n\nexport type URLObject = {\n /** The resolved URL string (Express-style or template literal, depending on context). */\n url: string\n /** Extracted path parameters as a key-value map, or `undefined` when the path has none. */\n params?: Record<string, string>\n}\n\ntype ObjectOptions = {\n /** Controls whether the `url` is rendered as an Express path or a template literal. Defaults to `'path'`. */\n type?: 'path' | 'template'\n /** Optional transform applied to each extracted parameter name. */\n replacer?: (pathParam: string) => string\n /** When `true`, the result is serialized to a string expression instead of a plain object. */\n stringify?: boolean\n}\n\n/** Supported identifier casing strategies for path parameters. */\ntype PathCasing = 'camelcase'\n\ntype Options = {\n /** Casing strategy applied to path parameter names. Defaults to the original identifier. */\n casing?: PathCasing\n}\n\n/**\n * Parses and transforms an OpenAPI/Swagger path string into various URL formats.\n *\n * @example\n * const p = new URLPath('/pet/{petId}')\n * p.URL // '/pet/:petId'\n * p.template // '`/pet/${petId}`'\n */\nexport class URLPath {\n /** The raw OpenAPI/Swagger path string, e.g. `/pet/{petId}`. */\n path: string\n\n #options: Options\n\n constructor(path: string, options: Options = {}) {\n this.path = path\n this.#options = options\n }\n\n /** Converts the OpenAPI path to Express-style colon syntax, e.g. `/pet/{petId}` → `/pet/:petId`. */\n get URL(): string {\n return this.toURLPath()\n }\n\n /** Returns `true` when `path` is a fully-qualified URL (e.g. starts with `https://`). */\n get isURL(): boolean {\n try {\n return !!new URL(this.path).href\n } catch {\n return false\n }\n }\n\n /**\n * Converts the OpenAPI path to a TypeScript template literal string.\n *\n * @example\n * new URLPath('/pet/{petId}').template // '`/pet/${petId}`'\n * new URLPath('/account/monetary-accountID').template // '`/account/${monetaryAccountId}`'\n */\n get template(): string {\n return this.toTemplateString()\n }\n\n /** Returns the path and its extracted params as a structured `URLObject`, or as a stringified expression when `stringify` is set. */\n get object(): URLObject | string {\n return this.toObject()\n }\n\n /** Returns a map of path parameter names, or `undefined` when the path has no parameters. */\n get params(): Record<string, string> | undefined {\n return this.getParams()\n }\n\n #transformParam(raw: string): string {\n const param = isValidVarName(raw) ? raw : camelCase(raw)\n return this.#options.casing === 'camelcase' ? camelCase(param) : param\n }\n\n /** Iterates over every `{param}` token in `path`, calling `fn` with the raw token and transformed name. */\n #eachParam(fn: (raw: string, param: string) => void): void {\n for (const match of this.path.matchAll(/\\{([^}]+)\\}/g)) {\n const raw = match[1]!\n fn(raw, this.#transformParam(raw))\n }\n }\n\n toObject({ type = 'path', replacer, stringify }: ObjectOptions = {}): URLObject | string {\n const object = {\n url: type === 'path' ? this.toURLPath() : this.toTemplateString({ replacer }),\n params: this.getParams(),\n }\n\n if (stringify) {\n if (type === 'template') {\n return JSON.stringify(object).replaceAll(\"'\", '').replaceAll(`\"`, '')\n }\n\n if (object.params) {\n return `{ url: '${object.url}', params: ${JSON.stringify(object.params).replaceAll(\"'\", '').replaceAll(`\"`, '')} }`\n }\n\n return `{ url: '${object.url}' }`\n }\n\n return object\n }\n\n /**\n * Converts the OpenAPI path to a TypeScript template literal string.\n * An optional `replacer` can transform each extracted parameter name before interpolation.\n *\n * @example\n * new URLPath('/pet/{petId}').toTemplateString() // '`/pet/${petId}`'\n */\n toTemplateString({ prefix = '', replacer }: { prefix?: string; replacer?: (pathParam: string) => string } = {}): string {\n const parts = this.path.split(/\\{([^}]+)\\}/)\n const result = parts\n .map((part, i) => {\n if (i % 2 === 0) return part\n const param = this.#transformParam(part)\n return `\\${${replacer ? replacer(param) : param}}`\n })\n .join('')\n\n return `\\`${prefix}${result}\\``\n }\n\n /**\n * Extracts all `{param}` segments from the path and returns them as a key-value map.\n * An optional `replacer` transforms each parameter name in both key and value positions.\n * Returns `undefined` when no path parameters are found.\n */\n getParams(replacer?: (pathParam: string) => string): Record<string, string> | undefined {\n const params: Record<string, string> = {}\n\n this.#eachParam((_raw, param) => {\n const key = replacer ? replacer(param) : param\n params[key] = key\n })\n\n return Object.keys(params).length > 0 ? params : undefined\n }\n\n /** Converts the OpenAPI path to Express-style colon syntax, e.g. `/pet/{petId}` → `/pet/:petId`. */\n toURLPath(): string {\n return this.path.replace(/\\{([^}]+)\\}/g, ':$1')\n }\n}\n","import { URLPath } from '@internals/utils'\nimport type { Operation } from '@kubb/oas'\n\nexport function getComments(operation: Operation): string[] {\n return [\n operation.getDescription() && `@description ${operation.getDescription()}`,\n operation.getSummary() && `@summary ${operation.getSummary()}`,\n operation.path && `{@link ${new URLPath(operation.path).URL}}`,\n operation.isDeprecated() && '@deprecated',\n ]\n .filter((x): x is string => Boolean(x))\n .flatMap((text) => {\n return text.split(/\\r?\\n/).map((line) => line.trim())\n })\n .filter((x): x is string => Boolean(x))\n}\n","import type { KubbFile } from '@kubb/fabric-core/types'\nimport { SchemaGenerator } from '../SchemaGenerator.ts'\nimport type { Schema } from '../SchemaMapper'\nimport { schemaKeywords } from '../SchemaMapper'\n\n/**\n * Get imports from a schema tree by extracting all ref schemas that are importable\n */\nexport function getImports(tree: Array<Schema>): Array<KubbFile.Import> {\n const refs = SchemaGenerator.deepSearch(tree, schemaKeywords.ref)\n\n if (!refs) return []\n\n return refs\n .map((item) => {\n if (!item.args.path || !item.args.isImportable) {\n return undefined\n }\n\n return {\n name: [item.args.name],\n path: item.args.path,\n } satisfies KubbFile.Import\n })\n .filter((x): x is NonNullable<typeof x> => x !== undefined)\n}\n","import { camelCase, isValidVarName } from '@internals/utils'\nimport type { FunctionParamsAST } from '@kubb/core'\nimport type { OasTypes } from '@kubb/oas'\nimport type { Params } from '@kubb/react-fabric/types'\nimport type { OperationSchema } from '../types.ts'\n/**\n *\n * @deprecated\n * TODO move to operationManager hook\n */\nexport function getASTParams(\n operationSchema: OperationSchema | undefined,\n {\n typed = false,\n casing,\n override,\n }: {\n typed?: boolean\n casing?: 'camelcase'\n override?: (data: FunctionParamsAST) => FunctionParamsAST\n } = {},\n): FunctionParamsAST[] {\n if (!operationSchema || !operationSchema.schema.properties || !operationSchema.name) {\n return []\n }\n\n const requiredFields = Array.isArray(operationSchema.schema.required) ? operationSchema.schema.required : []\n\n return Object.entries(operationSchema.schema.properties).map(([name]: [string, OasTypes.SchemaObject]) => {\n // Use camelCase name for indexed access if casing is enabled\n const accessName = casing === 'camelcase' ? camelCase(name) : name\n\n const data: FunctionParamsAST = {\n name,\n enabled: !!name,\n required: requiredFields.includes(name),\n type: typed ? `${operationSchema.name}[\"${accessName}\"]` : undefined,\n }\n\n return override ? override(data) : data\n })\n}\n\nexport function getPathParams(\n operationSchema: OperationSchema | undefined,\n options: {\n typed?: boolean\n casing?: 'camelcase'\n override?: (data: FunctionParamsAST) => FunctionParamsAST\n } = {},\n) {\n return getASTParams(operationSchema, options).reduce((acc, curr) => {\n if (curr.name && curr.enabled) {\n let name = curr.name\n\n // Only transform to camelCase if explicitly requested\n if (options.casing === 'camelcase') {\n name = camelCase(name)\n } else if (!isValidVarName(name)) {\n // If not valid variable name and casing not set, still need to make it valid\n name = camelCase(name)\n }\n\n acc[name] = {\n default: curr.default,\n type: curr.type,\n optional: !curr.required,\n }\n }\n\n return acc\n }, {} as Params)\n}\n\n/**\n * Get a mapping of camelCase parameter names to their original names\n * Used for mapping function parameters to backend parameter names\n */\nexport function getParamsMapping(\n operationSchema: OperationSchema | undefined,\n options: {\n casing?: 'camelcase'\n } = {},\n): Record<string, string> | undefined {\n if (!operationSchema || !operationSchema.schema.properties) {\n return undefined\n }\n\n const allEntries: Array<[string, string]> = []\n let hasTransformation = false\n\n Object.entries(operationSchema.schema.properties).forEach(([originalName]) => {\n let transformedName = originalName\n\n // Only transform to camelCase if explicitly requested\n if (options.casing === 'camelcase') {\n transformedName = camelCase(originalName)\n } else if (!isValidVarName(originalName)) {\n // If not valid variable name and casing not set, still need to make it valid\n transformedName = camelCase(originalName)\n }\n\n allEntries.push([originalName, transformedName])\n\n if (transformedName !== originalName) {\n hasTransformation = true\n }\n })\n\n // When using explicit casing and there are transformations, include ALL params so that\n // mappedParams contains every parameter (not just the ones whose names changed).\n // This prevents params with already-camelCase names (e.g. 'page', 'search') from being\n // silently dropped when other params in the same schema do need transformation.\n if (options.casing === 'camelcase' && hasTransformation) {\n return Object.fromEntries(allEntries)\n }\n\n // When casing is not specified or no transformations are needed, only return changed entries\n const mapping: Record<string, string> = {}\n allEntries.forEach(([originalName, transformedName]) => {\n if (transformedName !== originalName) {\n mapping[originalName] = transformedName\n }\n })\n\n return Object.keys(mapping).length > 0 ? mapping : undefined\n}\n","import type { contentType, Oas, OasTypes } from '@kubb/oas'\n\nexport type GetSchemasResult = {\n schemas: Record<string, OasTypes.SchemaObject>\n /**\n * Mapping from original component name to resolved name after collision handling\n * e.g., { 'Order': 'OrderSchema', 'variant': 'variant2' }\n */\n nameMapping: Map<string, string>\n}\n\ntype Mode = 'schemas' | 'responses' | 'requestBodies'\n\ntype GetSchemasProps = {\n oas: Oas\n contentType?: contentType\n includes?: Mode[]\n /**\n * Whether to resolve name collisions with suffixes.\n * If not provided, uses oas.options.collisionDetection\n * @default false (from oas.options or fallback)\n */\n collisionDetection?: boolean\n}\n\n/**\n * Collect schemas from OpenAPI components (schemas, responses, requestBodies)\n * and return them in dependency order along with name mapping for collision resolution.\n *\n * This function is a wrapper around the oas.getSchemas() method for backward compatibility.\n * New code should use oas.getSchemas() directly.\n *\n * @deprecated Use oas.getSchemas() instead\n */\nexport function getSchemas({ oas, contentType, includes = ['schemas', 'requestBodies', 'responses'], collisionDetection }: GetSchemasProps): GetSchemasResult {\n return oas.getSchemas({\n contentType,\n includes,\n collisionDetection,\n })\n}\n","import { camelCase, isValidVarName } from '@internals/utils'\nimport type { SchemaObject } from '@kubb/oas'\n\n/**\n * Apply casing transformation to schema properties\n * Only transforms property names, not nested schemas\n */\nexport function applyParamsCasing(schema: SchemaObject, casing: 'camelcase' | undefined): SchemaObject {\n if (!casing || !schema.properties) {\n return schema\n }\n\n const transformedProperties: Record<string, any> = {}\n const transformedRequired: string[] = []\n\n // Transform property names\n Object.entries(schema.properties).forEach(([originalName, propertySchema]) => {\n let transformedName = originalName\n\n if (casing === 'camelcase') {\n transformedName = camelCase(originalName)\n } else if (!isValidVarName(originalName)) {\n // If not valid variable name, make it valid\n transformedName = camelCase(originalName)\n }\n\n transformedProperties[transformedName] = propertySchema\n })\n\n // Transform required field names\n if (Array.isArray(schema.required)) {\n schema.required.forEach((originalName) => {\n let transformedName = originalName\n\n if (casing === 'camelcase') {\n transformedName = camelCase(originalName)\n } else if (!isValidVarName(originalName)) {\n transformedName = camelCase(originalName)\n }\n\n transformedRequired.push(transformedName)\n })\n }\n\n // Return a new schema with transformed properties and required fields\n return {\n ...schema,\n properties: transformedProperties,\n ...(transformedRequired.length > 0 && { required: transformedRequired }),\n } as SchemaObject\n}\n\n/**\n * Check if this schema is a parameter schema (pathParams, queryParams, or headerParams)\n * Only these should be transformed, not response/data/body\n */\nexport function isParameterSchema(schemaName: string): boolean {\n const lowerName = schemaName.toLowerCase()\n return lowerName.includes('pathparams') || lowerName.includes('queryparams') || lowerName.includes('headerparams')\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"utils.js","names":["#options","#transformParam","#eachParam"],"sources":["../../../internals/utils/src/reserved.ts","../../../internals/utils/src/urlPath.ts","../src/utils/getComments.ts","../src/utils/getImports.ts","../src/utils/getParams.ts","../src/utils/getSchemas.ts","../src/utils/paramsCasing.ts"],"sourcesContent":["/**\n * JavaScript and Java reserved words.\n * @link https://github.com/jonschlinkert/reserved/blob/master/index.js\n */\nconst reservedWords = new Set([\n 'abstract',\n 'arguments',\n 'boolean',\n 'break',\n 'byte',\n 'case',\n 'catch',\n 'char',\n 'class',\n 'const',\n 'continue',\n 'debugger',\n 'default',\n 'delete',\n 'do',\n 'double',\n 'else',\n 'enum',\n 'eval',\n 'export',\n 'extends',\n 'false',\n 'final',\n 'finally',\n 'float',\n 'for',\n 'function',\n 'goto',\n 'if',\n 'implements',\n 'import',\n 'in',\n 'instanceof',\n 'int',\n 'interface',\n 'let',\n 'long',\n 'native',\n 'new',\n 'null',\n 'package',\n 'private',\n 'protected',\n 'public',\n 'return',\n 'short',\n 'static',\n 'super',\n 'switch',\n 'synchronized',\n 'this',\n 'throw',\n 'throws',\n 'transient',\n 'true',\n 'try',\n 'typeof',\n 'var',\n 'void',\n 'volatile',\n 'while',\n 'with',\n 'yield',\n 'Array',\n 'Date',\n 'hasOwnProperty',\n 'Infinity',\n 'isFinite',\n 'isNaN',\n 'isPrototypeOf',\n 'length',\n 'Math',\n 'name',\n 'NaN',\n 'Number',\n 'Object',\n 'prototype',\n 'String',\n 'toString',\n 'undefined',\n 'valueOf',\n] as const)\n\n/**\n * Prefixes `word` with `_` when it is a reserved JavaScript/Java identifier or starts with a digit.\n *\n * @example\n * ```ts\n * transformReservedWord('class') // '_class'\n * transformReservedWord('42foo') // '_42foo'\n * transformReservedWord('status') // 'status'\n * ```\n */\nexport function transformReservedWord(word: string): string {\n const firstChar = word.charCodeAt(0)\n if (word && (reservedWords.has(word as 'valueOf') || (firstChar >= 48 && firstChar <= 57))) {\n return `_${word}`\n }\n return word\n}\n\n/**\n * Returns `true` when `name` is a syntactically valid JavaScript variable name.\n *\n * @example\n * ```ts\n * isValidVarName('status') // true\n * isValidVarName('class') // false (reserved word)\n * isValidVarName('42foo') // false (starts with digit)\n * ```\n */\nexport function isValidVarName(name: string): boolean {\n try {\n new Function(`var ${name}`)\n } catch {\n return false\n }\n return true\n}\n","import { camelCase } from './casing.ts'\nimport { isValidVarName } from './reserved.ts'\n\nexport type URLObject = {\n /**\n * The resolved URL string (Express-style or template literal, depending on context).\n */\n url: string\n /**\n * Extracted path parameters as a key-value map, or `undefined` when the path has none.\n */\n params?: Record<string, string>\n}\n\ntype ObjectOptions = {\n /**\n * Controls whether the `url` is rendered as an Express path or a template literal.\n * @default 'path'\n */\n type?: 'path' | 'template'\n /**\n * Optional transform applied to each extracted parameter name.\n */\n replacer?: (pathParam: string) => string\n /**\n * When `true`, the result is serialized to a string expression instead of a plain object.\n */\n stringify?: boolean\n}\n\n/**\n * Supported identifier casing strategies for path parameters.\n */\ntype PathCasing = 'camelcase'\n\ntype Options = {\n /**\n * Casing strategy applied to path parameter names.\n * @default undefined (original identifier preserved)\n */\n casing?: PathCasing\n}\n\n/**\n * Parses and transforms an OpenAPI/Swagger path string into various URL formats.\n *\n * @example\n * const p = new URLPath('/pet/{petId}')\n * p.URL // '/pet/:petId'\n * p.template // '`/pet/${petId}`'\n */\nexport class URLPath {\n /**\n * The raw OpenAPI/Swagger path string, e.g. `/pet/{petId}`.\n */\n path: string\n\n #options: Options\n\n constructor(path: string, options: Options = {}) {\n this.path = path\n this.#options = options\n }\n\n /** Converts the OpenAPI path to Express-style colon syntax, e.g. `/pet/{petId}` → `/pet/:petId`.\n *\n * @example\n * ```ts\n * new URLPath('/pet/{petId}').URL // '/pet/:petId'\n * ```\n */\n get URL(): string {\n return this.toURLPath()\n }\n\n /** Returns `true` when `path` is a fully-qualified URL (e.g. starts with `https://`).\n *\n * @example\n * ```ts\n * new URLPath('https://petstore.swagger.io/v2/pet').isURL // true\n * new URLPath('/pet/{petId}').isURL // false\n * ```\n */\n get isURL(): boolean {\n try {\n return !!new URL(this.path).href\n } catch {\n return false\n }\n }\n\n /**\n * Converts the OpenAPI path to a TypeScript template literal string.\n *\n * @example\n * new URLPath('/pet/{petId}').template // '`/pet/${petId}`'\n * new URLPath('/account/monetary-accountID').template // '`/account/${monetaryAccountId}`'\n */\n get template(): string {\n return this.toTemplateString()\n }\n\n /** Returns the path and its extracted params as a structured `URLObject`, or as a stringified expression when `stringify` is set.\n *\n * @example\n * ```ts\n * new URLPath('/pet/{petId}').object\n * // { url: '/pet/:petId', params: { petId: 'petId' } }\n * ```\n */\n get object(): URLObject | string {\n return this.toObject()\n }\n\n /** Returns a map of path parameter names, or `undefined` when the path has no parameters.\n *\n * @example\n * ```ts\n * new URLPath('/pet/{petId}').params // { petId: 'petId' }\n * new URLPath('/pet').params // undefined\n * ```\n */\n get params(): Record<string, string> | undefined {\n return this.getParams()\n }\n\n #transformParam(raw: string): string {\n const param = isValidVarName(raw) ? raw : camelCase(raw)\n return this.#options.casing === 'camelcase' ? camelCase(param) : param\n }\n\n /**\n * Iterates over every `{param}` token in `path`, calling `fn` with the raw token and transformed name.\n */\n #eachParam(fn: (raw: string, param: string) => void): void {\n for (const match of this.path.matchAll(/\\{([^}]+)\\}/g)) {\n const raw = match[1]!\n fn(raw, this.#transformParam(raw))\n }\n }\n\n toObject({ type = 'path', replacer, stringify }: ObjectOptions = {}): URLObject | string {\n const object = {\n url: type === 'path' ? this.toURLPath() : this.toTemplateString({ replacer }),\n params: this.getParams(),\n }\n\n if (stringify) {\n if (type === 'template') {\n return JSON.stringify(object).replaceAll(\"'\", '').replaceAll(`\"`, '')\n }\n\n if (object.params) {\n return `{ url: '${object.url}', params: ${JSON.stringify(object.params).replaceAll(\"'\", '').replaceAll(`\"`, '')} }`\n }\n\n return `{ url: '${object.url}' }`\n }\n\n return object\n }\n\n /**\n * Converts the OpenAPI path to a TypeScript template literal string.\n * An optional `replacer` can transform each extracted parameter name before interpolation.\n *\n * @example\n * new URLPath('/pet/{petId}').toTemplateString() // '`/pet/${petId}`'\n */\n toTemplateString({ prefix = '', replacer }: { prefix?: string; replacer?: (pathParam: string) => string } = {}): string {\n const parts = this.path.split(/\\{([^}]+)\\}/)\n const result = parts\n .map((part, i) => {\n if (i % 2 === 0) return part\n const param = this.#transformParam(part)\n return `\\${${replacer ? replacer(param) : param}}`\n })\n .join('')\n\n return `\\`${prefix}${result}\\``\n }\n\n /**\n * Extracts all `{param}` segments from the path and returns them as a key-value map.\n * An optional `replacer` transforms each parameter name in both key and value positions.\n * Returns `undefined` when no path parameters are found.\n *\n * @example\n * ```ts\n * new URLPath('/pet/{petId}/tag/{tagId}').getParams()\n * // { petId: 'petId', tagId: 'tagId' }\n * ```\n */\n getParams(replacer?: (pathParam: string) => string): Record<string, string> | undefined {\n const params: Record<string, string> = {}\n\n this.#eachParam((_raw, param) => {\n const key = replacer ? replacer(param) : param\n params[key] = key\n })\n\n return Object.keys(params).length > 0 ? params : undefined\n }\n\n /** Converts the OpenAPI path to Express-style colon syntax.\n *\n * @example\n * ```ts\n * new URLPath('/pet/{petId}').toURLPath() // '/pet/:petId'\n * ```\n */\n toURLPath(): string {\n return this.path.replace(/\\{([^}]+)\\}/g, ':$1')\n }\n}\n","import { URLPath } from '@internals/utils'\nimport type { Operation } from '@kubb/oas'\n\nexport function getComments(operation: Operation): string[] {\n return [\n operation.getDescription() && `@description ${operation.getDescription()}`,\n operation.getSummary() && `@summary ${operation.getSummary()}`,\n operation.path && `{@link ${new URLPath(operation.path).URL}}`,\n operation.isDeprecated() && '@deprecated',\n ]\n .filter((x): x is string => Boolean(x))\n .flatMap((text) => {\n return text.split(/\\r?\\n/).map((line) => line.trim())\n })\n .filter((x): x is string => Boolean(x))\n}\n","import type { KubbFile } from '@kubb/core'\nimport { SchemaGenerator } from '../SchemaGenerator.ts'\nimport type { Schema } from '../SchemaMapper'\nimport { schemaKeywords } from '../SchemaMapper'\n\n/**\n * Get imports from a schema tree by extracting all ref schemas that are importable\n */\nexport function getImports(tree: Array<Schema>): Array<KubbFile.Import> {\n const refs = SchemaGenerator.deepSearch(tree, schemaKeywords.ref)\n\n if (!refs) return []\n\n return refs\n .map((item) => {\n if (!item.args.path || !item.args.isImportable) {\n return undefined\n }\n\n return {\n name: [item.args.name],\n path: item.args.path,\n } satisfies KubbFile.Import\n })\n .filter((x): x is NonNullable<typeof x> => x !== undefined)\n}\n","import { camelCase, isValidVarName } from '@internals/utils'\nimport type { FunctionParamsAST } from '@kubb/core'\nimport type { OasTypes } from '@kubb/oas'\nimport type { Params } from '@kubb/react-fabric/types'\nimport type { OperationSchema } from '../types.ts'\n/**\n *\n * @deprecated\n * TODO move to operationManager hook\n */\nexport function getASTParams(\n operationSchema: OperationSchema | undefined,\n {\n typed = false,\n casing,\n override,\n }: {\n typed?: boolean\n casing?: 'camelcase'\n override?: (data: FunctionParamsAST) => FunctionParamsAST\n } = {},\n): FunctionParamsAST[] {\n if (!operationSchema?.schema.properties || !operationSchema.name) {\n return []\n }\n\n const requiredFields = Array.isArray(operationSchema.schema.required) ? operationSchema.schema.required : []\n\n return Object.entries(operationSchema.schema.properties).map(([name]: [string, OasTypes.SchemaObject]) => {\n // Use camelCase name for indexed access if casing is enabled\n const accessName = casing === 'camelcase' ? camelCase(name) : name\n\n const data: FunctionParamsAST = {\n name,\n enabled: !!name,\n required: requiredFields.includes(name),\n type: typed ? `${operationSchema.name}[\"${accessName}\"]` : undefined,\n }\n\n return override ? override(data) : data\n })\n}\n\nexport function getPathParams(\n operationSchema: OperationSchema | undefined,\n options: {\n typed?: boolean\n casing?: 'camelcase'\n override?: (data: FunctionParamsAST) => FunctionParamsAST\n } = {},\n) {\n return getASTParams(operationSchema, options).reduce((acc, curr) => {\n if (curr.name && curr.enabled) {\n let name = curr.name\n\n // Only transform to camelCase if explicitly requested\n if (options.casing === 'camelcase') {\n name = camelCase(name)\n } else if (!isValidVarName(name)) {\n // If not valid variable name and casing not set, still need to make it valid\n name = camelCase(name)\n }\n\n acc[name] = {\n default: curr.default,\n type: curr.type,\n optional: !curr.required,\n }\n }\n\n return acc\n }, {} as Params)\n}\n\n/**\n * Get a mapping of camelCase parameter names to their original names\n * Used for mapping function parameters to backend parameter names\n */\nexport function getParamsMapping(\n operationSchema: OperationSchema | undefined,\n options: {\n casing?: 'camelcase'\n } = {},\n): Record<string, string> | undefined {\n if (!operationSchema?.schema.properties) {\n return undefined\n }\n\n const allEntries: Array<[string, string]> = []\n let hasTransformation = false\n\n Object.entries(operationSchema.schema.properties).forEach(([originalName]) => {\n let transformedName = originalName\n\n // Only transform to camelCase if explicitly requested\n if (options.casing === 'camelcase') {\n transformedName = camelCase(originalName)\n } else if (!isValidVarName(originalName)) {\n // If not valid variable name and casing not set, still need to make it valid\n transformedName = camelCase(originalName)\n }\n\n allEntries.push([originalName, transformedName])\n\n if (transformedName !== originalName) {\n hasTransformation = true\n }\n })\n\n // When using explicit casing and there are transformations, include ALL params so that\n // mappedParams contains every parameter (not just the ones whose names changed).\n // This prevents params with already-camelCase names (e.g. 'page', 'search') from being\n // silently dropped when other params in the same schema do need transformation.\n if (options.casing === 'camelcase' && hasTransformation) {\n return Object.fromEntries(allEntries)\n }\n\n // When casing is not specified or no transformations are needed, only return changed entries\n const mapping: Record<string, string> = {}\n allEntries.forEach(([originalName, transformedName]) => {\n if (transformedName !== originalName) {\n mapping[originalName] = transformedName\n }\n })\n\n return Object.keys(mapping).length > 0 ? mapping : undefined\n}\n","import type { contentType, Oas, OasTypes } from '@kubb/oas'\n\nexport type GetSchemasResult = {\n schemas: Record<string, OasTypes.SchemaObject>\n /**\n * Mapping from original component name to resolved name after collision handling\n * e.g., { 'Order': 'OrderSchema', 'variant': 'variant2' }\n */\n nameMapping: Map<string, string>\n}\n\ntype Mode = 'schemas' | 'responses' | 'requestBodies'\n\ntype GetSchemasProps = {\n oas: Oas\n contentType?: contentType\n includes?: Mode[]\n /**\n * Whether to resolve name collisions with suffixes.\n * If not provided, uses oas.options.collisionDetection\n * @default false (from oas.options or fallback)\n */\n collisionDetection?: boolean\n}\n\n/**\n * Collect schemas from OpenAPI components (schemas, responses, requestBodies)\n * and return them in dependency order along with name mapping for collision resolution.\n *\n * This function is a wrapper around the oas.getSchemas() method for backward compatibility.\n * New code should use oas.getSchemas() directly.\n *\n * @deprecated Use oas.getSchemas() instead\n */\nexport function getSchemas({ oas, contentType, includes = ['schemas', 'requestBodies', 'responses'], collisionDetection }: GetSchemasProps): GetSchemasResult {\n return oas.getSchemas({\n contentType,\n includes,\n collisionDetection,\n })\n}\n","import { camelCase, isValidVarName } from '@internals/utils'\nimport type { SchemaObject } from '@kubb/oas'\n\n/**\n * Apply casing transformation to schema properties\n * Only transforms property names, not nested schemas\n */\nexport function applyParamsCasing(schema: SchemaObject, casing: 'camelcase' | undefined): SchemaObject {\n if (!casing || !schema.properties) {\n return schema\n }\n\n const transformedProperties: Record<string, any> = {}\n const transformedRequired: string[] = []\n\n // Transform property names\n Object.entries(schema.properties).forEach(([originalName, propertySchema]) => {\n let transformedName = originalName\n\n if (casing === 'camelcase') {\n transformedName = camelCase(originalName)\n } else if (!isValidVarName(originalName)) {\n // If not valid variable name, make it valid\n transformedName = camelCase(originalName)\n }\n\n transformedProperties[transformedName] = propertySchema\n })\n\n // Transform required field names\n if (Array.isArray(schema.required)) {\n schema.required.forEach((originalName) => {\n let transformedName = originalName\n\n if (casing === 'camelcase') {\n transformedName = camelCase(originalName)\n } else if (!isValidVarName(originalName)) {\n transformedName = camelCase(originalName)\n }\n\n transformedRequired.push(transformedName)\n })\n }\n\n // Return a new schema with transformed properties and required fields\n return {\n ...schema,\n properties: transformedProperties,\n ...(transformedRequired.length > 0 && { required: transformedRequired }),\n } as SchemaObject\n}\n\n/**\n * Check if this schema is a parameter schema (pathParams, queryParams, or headerParams)\n * Only these should be transformed, not response/data/body\n */\nexport function isParameterSchema(schemaName: string): boolean {\n const lowerName = schemaName.toLowerCase()\n return lowerName.includes('pathparams') || lowerName.includes('queryparams') || lowerName.includes('headerparams')\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kubb/plugin-oas",
|
|
3
|
-
"version": "5.0.0-alpha.
|
|
3
|
+
"version": "5.0.0-alpha.31",
|
|
4
4
|
"description": "OpenAPI Specification (OAS) plugin for Kubb, providing core functionality for parsing and processing OpenAPI/Swagger schemas for code generation.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"openapi",
|
|
@@ -81,15 +81,15 @@
|
|
|
81
81
|
}
|
|
82
82
|
],
|
|
83
83
|
"dependencies": {
|
|
84
|
-
"@kubb/fabric-core": "0.
|
|
85
|
-
"@kubb/react-fabric": "0.
|
|
86
|
-
"remeda": "^2.33.
|
|
87
|
-
"@kubb/core": "5.0.0-alpha.
|
|
88
|
-
"@kubb/oas": "5.0.0-alpha.
|
|
84
|
+
"@kubb/fabric-core": "0.15.1",
|
|
85
|
+
"@kubb/react-fabric": "0.15.1",
|
|
86
|
+
"remeda": "^2.33.7",
|
|
87
|
+
"@kubb/core": "5.0.0-alpha.31",
|
|
88
|
+
"@kubb/oas": "5.0.0-alpha.31"
|
|
89
89
|
},
|
|
90
90
|
"peerDependencies": {
|
|
91
|
-
"@kubb/fabric-core": "0.
|
|
92
|
-
"@kubb/react-fabric": "0.
|
|
91
|
+
"@kubb/fabric-core": "0.15.1",
|
|
92
|
+
"@kubb/react-fabric": "0.15.1"
|
|
93
93
|
},
|
|
94
94
|
"engines": {
|
|
95
95
|
"node": ">=22"
|
|
@@ -104,10 +104,6 @@
|
|
|
104
104
|
},
|
|
105
105
|
"main": "./dist/index.cjs",
|
|
106
106
|
"module": "./dist/index.js",
|
|
107
|
-
"inlinedDependencies": {
|
|
108
|
-
"p-limit": "7.3.0",
|
|
109
|
-
"yocto-queue": "1.2.2"
|
|
110
|
-
},
|
|
111
107
|
"scripts": {
|
|
112
108
|
"build": "tsdown && size-limit",
|
|
113
109
|
"clean": "npx rimraf ./dist",
|
|
@@ -1,26 +1,25 @@
|
|
|
1
|
+
import type { AsyncEventEmitter } from '@internals/utils'
|
|
1
2
|
import { pascalCase } from '@internals/utils'
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
3
|
+
import type { FileMetaBase, KubbEvents, KubbFile, Plugin, PluginDriver, PluginFactoryOptions } from '@kubb/core'
|
|
4
|
+
import type { Fabric as FabricType } from '@kubb/fabric-core/types'
|
|
4
5
|
import type { contentType, HttpMethod, Oas, OasTypes, Operation, SchemaObject } from '@kubb/oas'
|
|
5
|
-
import type { Fabric } from '@kubb/react-fabric'
|
|
6
|
-
import pLimit from 'p-limit'
|
|
7
6
|
import type { CoreGenerator } from './generators/createGenerator.ts'
|
|
8
7
|
import type { ReactGenerator } from './generators/createReactGenerator.ts'
|
|
9
|
-
import type { Generator
|
|
8
|
+
import type { Generator } from './generators/types.ts'
|
|
10
9
|
import type { Exclude, Include, OperationSchemas, Override } from './types.ts'
|
|
11
10
|
import { withRequiredRequestBodySchema } from './utils/requestBody.ts'
|
|
12
|
-
import {
|
|
11
|
+
import { renderOperation, renderOperations } from './utils.tsx'
|
|
13
12
|
|
|
14
13
|
export type OperationMethodResult<TFileMeta extends FileMetaBase> = Promise<KubbFile.File<TFileMeta> | Array<KubbFile.File<TFileMeta>> | null>
|
|
15
14
|
|
|
16
15
|
type Context<TOptions, TPluginOptions extends PluginFactoryOptions> = {
|
|
17
|
-
fabric:
|
|
16
|
+
fabric: FabricType
|
|
18
17
|
oas: Oas
|
|
19
18
|
exclude: Array<Exclude> | undefined
|
|
20
19
|
include: Array<Include> | undefined
|
|
21
20
|
override: Array<Override<TOptions>> | undefined
|
|
22
21
|
contentType: contentType | undefined
|
|
23
|
-
|
|
22
|
+
driver: PluginDriver
|
|
24
23
|
events?: AsyncEventEmitter<KubbEvents>
|
|
25
24
|
/**
|
|
26
25
|
* Current plugin
|
|
@@ -206,99 +205,86 @@ export class OperationGenerator<TPluginOptions extends PluginFactoryOptions = Pl
|
|
|
206
205
|
)
|
|
207
206
|
}
|
|
208
207
|
|
|
209
|
-
async build(...generators: Array<Generator<TPluginOptions
|
|
208
|
+
async build(...generators: Array<Generator<TPluginOptions>>): Promise<Array<KubbFile.File<TFileMeta>>> {
|
|
210
209
|
const operations = await this.getOperations()
|
|
211
210
|
|
|
212
|
-
// Increased parallelism for better performance
|
|
213
|
-
// - generatorLimit increased from 1 to 3 to allow parallel generator processing
|
|
214
|
-
// - operationLimit increased from 10 to 30 to process more operations concurrently
|
|
215
|
-
const generatorLimit = pLimit(3)
|
|
216
|
-
const operationLimit = pLimit(30)
|
|
217
|
-
|
|
218
211
|
this.context.events?.emit('debug', {
|
|
219
212
|
date: new Date(),
|
|
220
213
|
logs: [`Building ${operations.length} operations`, ` • Generators: ${generators.length}`],
|
|
221
214
|
})
|
|
222
215
|
|
|
223
|
-
const
|
|
224
|
-
generatorLimit(async () => {
|
|
225
|
-
if (generator.version === '2') {
|
|
226
|
-
return []
|
|
227
|
-
}
|
|
216
|
+
const results: Array<KubbFile.File<TFileMeta>> = []
|
|
228
217
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
operationLimit(async () => {
|
|
234
|
-
const options = this.getOptions(operation, method)
|
|
235
|
-
|
|
236
|
-
if (v1Generator.type === 'react') {
|
|
237
|
-
await buildOperation(operation, {
|
|
238
|
-
config: this.context.pluginManager.config,
|
|
239
|
-
fabric: this.context.fabric,
|
|
240
|
-
Component: v1Generator.Operation,
|
|
241
|
-
generator: this,
|
|
242
|
-
plugin: {
|
|
243
|
-
...this.context.plugin,
|
|
244
|
-
options: {
|
|
245
|
-
...this.options,
|
|
246
|
-
...options,
|
|
247
|
-
},
|
|
248
|
-
},
|
|
249
|
-
})
|
|
250
|
-
|
|
251
|
-
return []
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
const result = await v1Generator.operation?.({
|
|
255
|
-
generator: this,
|
|
256
|
-
config: this.context.pluginManager.config,
|
|
257
|
-
operation,
|
|
258
|
-
plugin: {
|
|
259
|
-
...this.context.plugin,
|
|
260
|
-
options: {
|
|
261
|
-
...this.options,
|
|
262
|
-
...options,
|
|
263
|
-
},
|
|
264
|
-
},
|
|
265
|
-
})
|
|
266
|
-
|
|
267
|
-
return result ?? []
|
|
268
|
-
}),
|
|
269
|
-
)
|
|
218
|
+
for (const generator of generators) {
|
|
219
|
+
if (!('type' in generator)) {
|
|
220
|
+
continue
|
|
221
|
+
}
|
|
270
222
|
|
|
271
|
-
|
|
272
|
-
|
|
223
|
+
// After the v2 guard above, all generators here are v1
|
|
224
|
+
const v1Generator = generator as ReactGenerator<TPluginOptions> | CoreGenerator<TPluginOptions>
|
|
225
|
+
|
|
226
|
+
const opResultsFlat: Array<KubbFile.File<TFileMeta>> = []
|
|
227
|
+
|
|
228
|
+
for (const { operation, method } of operations) {
|
|
229
|
+
const options = this.getOptions(operation, method)
|
|
273
230
|
|
|
274
231
|
if (v1Generator.type === 'react') {
|
|
275
|
-
await
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
232
|
+
await renderOperation(operation, {
|
|
233
|
+
config: this.context.driver.config,
|
|
234
|
+
fabric: this.context.fabric,
|
|
235
|
+
Component: v1Generator.Operation,
|
|
236
|
+
generator: this,
|
|
237
|
+
plugin: {
|
|
238
|
+
...this.context.plugin,
|
|
239
|
+
options: {
|
|
240
|
+
...this.options,
|
|
241
|
+
...options,
|
|
242
|
+
} as Plugin<TPluginOptions>['options'],
|
|
243
|
+
},
|
|
244
|
+
})
|
|
245
|
+
} else {
|
|
246
|
+
const result = await v1Generator.operation?.({
|
|
247
|
+
generator: this,
|
|
248
|
+
config: this.context.driver.config,
|
|
249
|
+
operation,
|
|
250
|
+
plugin: {
|
|
251
|
+
...this.context.plugin,
|
|
252
|
+
options: {
|
|
253
|
+
...this.options,
|
|
254
|
+
...options,
|
|
255
|
+
} as Plugin<TPluginOptions>['options'],
|
|
283
256
|
},
|
|
284
|
-
)
|
|
257
|
+
})
|
|
285
258
|
|
|
286
|
-
|
|
259
|
+
opResultsFlat.push(...([result ?? []].flat() as Array<KubbFile.File<TFileMeta>>))
|
|
287
260
|
}
|
|
261
|
+
}
|
|
288
262
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
263
|
+
if (v1Generator.type === 'react') {
|
|
264
|
+
await renderOperations(
|
|
265
|
+
operations.map((op) => op.operation),
|
|
266
|
+
{
|
|
267
|
+
fabric: this.context.fabric,
|
|
268
|
+
config: this.context.driver.config,
|
|
269
|
+
Component: v1Generator.Operations,
|
|
270
|
+
generator: this,
|
|
271
|
+
plugin: this.context.plugin,
|
|
272
|
+
},
|
|
273
|
+
)
|
|
295
274
|
|
|
296
|
-
|
|
297
|
-
}
|
|
298
|
-
|
|
275
|
+
continue
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
const operationsResult = await v1Generator.operations?.({
|
|
279
|
+
generator: this,
|
|
280
|
+
config: this.context.driver.config,
|
|
281
|
+
operations: operations.map((op) => op.operation),
|
|
282
|
+
plugin: this.context.plugin,
|
|
283
|
+
})
|
|
299
284
|
|
|
300
|
-
|
|
285
|
+
results.push(...opResultsFlat, ...((operationsResult ?? []) as unknown as Array<KubbFile.File<TFileMeta>>))
|
|
286
|
+
}
|
|
301
287
|
|
|
302
|
-
return
|
|
288
|
+
return results
|
|
303
289
|
}
|
|
304
290
|
}
|
package/src/SchemaGenerator.ts
CHANGED
|
@@ -1,32 +1,26 @@
|
|
|
1
|
+
import type { AsyncEventEmitter } from '@internals/utils'
|
|
1
2
|
import { getUniqueName, pascalCase, stringify } from '@internals/utils'
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
3
|
+
import type { FileMetaBase, KubbEvents, KubbFile, Plugin, PluginDriver, PluginFactoryOptions, ResolveNameParams } from '@kubb/core'
|
|
4
|
+
import type { Fabric as FabricType } from '@kubb/fabric-core/types'
|
|
4
5
|
import type { contentType, Oas, OasTypes, OpenAPIV3, SchemaObject } from '@kubb/oas'
|
|
5
6
|
import { isDiscriminator, isNullable, isReference, KUBB_INLINE_REF_PREFIX } from '@kubb/oas'
|
|
6
|
-
import type { Fabric } from '@kubb/react-fabric'
|
|
7
|
-
import pLimit from 'p-limit'
|
|
8
7
|
import { isDeepEqual, isNumber, uniqueWith } from 'remeda'
|
|
9
8
|
import type { CoreGenerator } from './generators/createGenerator.ts'
|
|
10
9
|
import type { ReactGenerator } from './generators/createReactGenerator.ts'
|
|
11
|
-
import type { Generator
|
|
10
|
+
import type { Generator } from './generators/types.ts'
|
|
12
11
|
import { isKeyword, type Schema, type SchemaKeywordMapper, schemaKeywords } from './SchemaMapper.ts'
|
|
13
12
|
import type { OperationSchema, Override, Refs } from './types.ts'
|
|
14
13
|
import { getSchemaFactory } from './utils/getSchemaFactory.ts'
|
|
15
|
-
import {
|
|
14
|
+
import { renderSchema } from './utils.tsx'
|
|
16
15
|
|
|
17
16
|
export type GetSchemaGeneratorOptions<T extends SchemaGenerator<any, any, any>> = T extends SchemaGenerator<infer Options, any, any> ? Options : never
|
|
18
17
|
|
|
19
18
|
export type SchemaMethodResult<TFileMeta extends FileMetaBase> = Promise<KubbFile.File<TFileMeta> | Array<KubbFile.File<TFileMeta>> | null>
|
|
20
19
|
|
|
21
|
-
/** Max concurrent generator tasks (across generators). */
|
|
22
|
-
const GENERATOR_CONCURRENCY = 3
|
|
23
|
-
/** Max concurrent schema parsing tasks (per generator). */
|
|
24
|
-
const SCHEMA_CONCURRENCY = 30
|
|
25
|
-
|
|
26
20
|
type Context<TOptions, TPluginOptions extends PluginFactoryOptions> = {
|
|
27
|
-
fabric:
|
|
21
|
+
fabric: FabricType
|
|
28
22
|
oas: Oas
|
|
29
|
-
|
|
23
|
+
driver: PluginDriver
|
|
30
24
|
events?: AsyncEventEmitter<KubbEvents>
|
|
31
25
|
/**
|
|
32
26
|
* Current plugin
|
|
@@ -524,18 +518,18 @@ export class SchemaGenerator<
|
|
|
524
518
|
// Use the full $ref path to look up the collision-resolved name
|
|
525
519
|
const resolvedName = this.#schemaNameMapping.get($ref) || originalName
|
|
526
520
|
|
|
527
|
-
const propertyName = this.context.
|
|
521
|
+
const propertyName = this.context.driver.resolveName({
|
|
528
522
|
name: resolvedName,
|
|
529
523
|
pluginName: this.context.plugin.name,
|
|
530
524
|
type: 'function',
|
|
531
525
|
})
|
|
532
526
|
|
|
533
|
-
const fileName = this.context.
|
|
527
|
+
const fileName = this.context.driver.resolveName({
|
|
534
528
|
name: resolvedName,
|
|
535
529
|
pluginName: this.context.plugin.name,
|
|
536
530
|
type: 'file',
|
|
537
531
|
})
|
|
538
|
-
const file = this.context.
|
|
532
|
+
const file = this.context.driver.getFile({
|
|
539
533
|
name: fileName,
|
|
540
534
|
pluginName: this.context.plugin.name,
|
|
541
535
|
extname: '.ts',
|
|
@@ -968,7 +962,7 @@ export class SchemaGenerator<
|
|
|
968
962
|
const enumName = useCollisionDetection
|
|
969
963
|
? pascalCase(enumNameParts.join(' '))
|
|
970
964
|
: getUniqueName(pascalCase(enumNameParts.join(' ')), this.options.usedEnumNames || {})
|
|
971
|
-
const typeName = this.context.
|
|
965
|
+
const typeName = this.context.driver.resolveName({
|
|
972
966
|
name: enumName,
|
|
973
967
|
pluginName: this.context.plugin.name,
|
|
974
968
|
type: 'type',
|
|
@@ -1337,7 +1331,7 @@ export class SchemaGenerator<
|
|
|
1337
1331
|
return [{ keyword: emptyType }, ...baseItems]
|
|
1338
1332
|
}
|
|
1339
1333
|
|
|
1340
|
-
async build(...generators: Array<Generator<TPluginOptions
|
|
1334
|
+
async build(...generators: Array<Generator<TPluginOptions>>): Promise<Array<KubbFile.File<TFileMeta>>> {
|
|
1341
1335
|
const { oas, contentType, include } = this.context
|
|
1342
1336
|
|
|
1343
1337
|
// Initialize the name mapping if not already done
|
|
@@ -1360,83 +1354,68 @@ export class SchemaGenerator<
|
|
|
1360
1354
|
return this.#doBuild(schemas, generators)
|
|
1361
1355
|
}
|
|
1362
1356
|
|
|
1363
|
-
async #doBuild(
|
|
1364
|
-
schemas: Record<string, OasTypes.SchemaObject>,
|
|
1365
|
-
generators: Array<Generator<TPluginOptions, Version>>,
|
|
1366
|
-
): Promise<Array<KubbFile.File<TFileMeta>>> {
|
|
1357
|
+
async #doBuild(schemas: Record<string, OasTypes.SchemaObject>, generators: Array<Generator<TPluginOptions>>): Promise<Array<KubbFile.File<TFileMeta>>> {
|
|
1367
1358
|
const schemaEntries = Object.entries(schemas)
|
|
1368
1359
|
|
|
1369
|
-
const
|
|
1370
|
-
const schemaLimit = pLimit(SCHEMA_CONCURRENCY)
|
|
1360
|
+
const results: Array<KubbFile.File<TFileMeta>> = []
|
|
1371
1361
|
|
|
1372
|
-
const
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
}
|
|
1362
|
+
for (const generator of generators) {
|
|
1363
|
+
if (!('type' in generator)) {
|
|
1364
|
+
continue
|
|
1365
|
+
}
|
|
1377
1366
|
|
|
1378
|
-
|
|
1379
|
-
|
|
1367
|
+
// After the v2 guard above, all generators here are v1
|
|
1368
|
+
const v1Generator = generator as ReactGenerator<TPluginOptions> | CoreGenerator<TPluginOptions>
|
|
1380
1369
|
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
const options = this.#getOptions(name)
|
|
1370
|
+
for (const [name, schemaObject] of schemaEntries) {
|
|
1371
|
+
const options = this.#getOptions(name)
|
|
1384
1372
|
|
|
1385
|
-
|
|
1373
|
+
const tree = this.parse({ schema: schemaObject as SchemaObject, name, parentName: null, rootName: name })
|
|
1386
1374
|
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
generator: this,
|
|
1399
|
-
plugin: {
|
|
1400
|
-
...this.context.plugin,
|
|
1401
|
-
options: {
|
|
1402
|
-
...this.options,
|
|
1403
|
-
...options,
|
|
1404
|
-
},
|
|
1405
|
-
},
|
|
1406
|
-
},
|
|
1407
|
-
)
|
|
1408
|
-
|
|
1409
|
-
return []
|
|
1410
|
-
}
|
|
1411
|
-
|
|
1412
|
-
const result = await v1Generator.schema?.({
|
|
1413
|
-
config: this.context.pluginManager.config,
|
|
1375
|
+
if (v1Generator.type === 'react') {
|
|
1376
|
+
await renderSchema(
|
|
1377
|
+
{
|
|
1378
|
+
name,
|
|
1379
|
+
value: schemaObject as SchemaObject,
|
|
1380
|
+
tree,
|
|
1381
|
+
},
|
|
1382
|
+
{
|
|
1383
|
+
config: this.context.driver.config,
|
|
1384
|
+
fabric: this.context.fabric,
|
|
1385
|
+
Component: v1Generator.Schema,
|
|
1414
1386
|
generator: this,
|
|
1415
|
-
schema: {
|
|
1416
|
-
name,
|
|
1417
|
-
value: schemaObject as SchemaObject,
|
|
1418
|
-
tree,
|
|
1419
|
-
},
|
|
1420
1387
|
plugin: {
|
|
1421
1388
|
...this.context.plugin,
|
|
1422
1389
|
options: {
|
|
1423
1390
|
...this.options,
|
|
1424
1391
|
...options,
|
|
1425
|
-
},
|
|
1392
|
+
} as unknown as Plugin<TPluginOptions>['options'],
|
|
1426
1393
|
},
|
|
1427
|
-
}
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1394
|
+
},
|
|
1395
|
+
)
|
|
1396
|
+
} else {
|
|
1397
|
+
const result = await v1Generator.schema?.({
|
|
1398
|
+
config: this.context.driver.config,
|
|
1399
|
+
generator: this,
|
|
1400
|
+
schema: {
|
|
1401
|
+
name,
|
|
1402
|
+
value: schemaObject as SchemaObject,
|
|
1403
|
+
tree,
|
|
1404
|
+
},
|
|
1405
|
+
plugin: {
|
|
1406
|
+
...this.context.plugin,
|
|
1407
|
+
options: {
|
|
1408
|
+
...this.options,
|
|
1409
|
+
...options,
|
|
1410
|
+
} as unknown as Plugin<TPluginOptions>['options'],
|
|
1411
|
+
},
|
|
1412
|
+
})
|
|
1437
1413
|
|
|
1438
|
-
|
|
1414
|
+
results.push(...([result ?? []].flat() as Array<KubbFile.File<TFileMeta>>))
|
|
1415
|
+
}
|
|
1416
|
+
}
|
|
1417
|
+
}
|
|
1439
1418
|
|
|
1440
|
-
return
|
|
1419
|
+
return results
|
|
1441
1420
|
}
|
|
1442
1421
|
}
|
package/src/SchemaMapper.ts
CHANGED
|
@@ -1,30 +1,26 @@
|
|
|
1
|
-
import type { PluginFactoryOptions } from '@kubb/core'
|
|
2
|
-
import type {
|
|
3
|
-
import type { OperationProps, OperationsProps, SchemaProps, Version } from './types.ts'
|
|
1
|
+
import type { KubbFile, PluginFactoryOptions } from '@kubb/core'
|
|
2
|
+
import type { OperationProps, OperationsProps, SchemaProps } from './types.ts'
|
|
4
3
|
|
|
5
|
-
type UserGenerator<TOptions extends PluginFactoryOptions
|
|
4
|
+
type UserGenerator<TOptions extends PluginFactoryOptions> = {
|
|
6
5
|
name: string
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
schema?: (props: SchemaProps<TOptions, TVersion>) => Promise<KubbFile.File[]>
|
|
6
|
+
operations?: (props: OperationsProps<TOptions>) => Promise<KubbFile.File[]>
|
|
7
|
+
operation?: (props: OperationProps<TOptions>) => Promise<KubbFile.File[]>
|
|
8
|
+
schema?: (props: SchemaProps<TOptions>) => Promise<KubbFile.File[]>
|
|
11
9
|
}
|
|
12
10
|
|
|
13
|
-
export type CoreGenerator<TOptions extends PluginFactoryOptions
|
|
11
|
+
export type CoreGenerator<TOptions extends PluginFactoryOptions> = {
|
|
14
12
|
name: string
|
|
15
13
|
type: 'core'
|
|
16
|
-
version:
|
|
17
|
-
operations: (props: OperationsProps<TOptions
|
|
18
|
-
operation: (props: OperationProps<TOptions
|
|
19
|
-
schema: (props: SchemaProps<TOptions
|
|
14
|
+
version: '1'
|
|
15
|
+
operations: (props: OperationsProps<TOptions>) => Promise<KubbFile.File[]>
|
|
16
|
+
operation: (props: OperationProps<TOptions>) => Promise<KubbFile.File[]>
|
|
17
|
+
schema: (props: SchemaProps<TOptions>) => Promise<KubbFile.File[]>
|
|
20
18
|
}
|
|
21
19
|
|
|
22
|
-
export function createGenerator<TOptions extends PluginFactoryOptions
|
|
23
|
-
generator: UserGenerator<TOptions, TVersion>,
|
|
24
|
-
): CoreGenerator<TOptions, TVersion> {
|
|
20
|
+
export function createGenerator<TOptions extends PluginFactoryOptions>(generator: UserGenerator<TOptions>): CoreGenerator<TOptions> {
|
|
25
21
|
return {
|
|
26
22
|
type: 'core',
|
|
27
|
-
version:
|
|
23
|
+
version: '1',
|
|
28
24
|
async operations() {
|
|
29
25
|
return []
|
|
30
26
|
},
|