@kubb/ast 4.35.0 → 4.35.1
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/index.cjs +15 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +15 -16
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +2 -2
- package/dist/{visitor-8N3AiSUr.d.ts → visitor-CmsfJzro.d.ts} +12 -4
- package/package.json +1 -1
- package/src/factory.ts +13 -3
- package/src/nodes/schema.ts +1 -1
- package/src/printer.ts +13 -11
- package/src/types.ts +1 -1
- package/src/visitor.ts +2 -2
package/dist/index.cjs
CHANGED
|
@@ -95,10 +95,12 @@ function createOperation(props) {
|
|
|
95
95
|
kind: "Operation"
|
|
96
96
|
};
|
|
97
97
|
}
|
|
98
|
-
/**
|
|
99
|
-
* Creates a `SchemaNode`, narrowed to the variant of `props.type`.
|
|
100
|
-
*/
|
|
101
98
|
function createSchema(props) {
|
|
99
|
+
if (props["type"] === "object") return {
|
|
100
|
+
properties: [],
|
|
101
|
+
...props,
|
|
102
|
+
kind: "Schema"
|
|
103
|
+
};
|
|
102
104
|
return {
|
|
103
105
|
...props,
|
|
104
106
|
kind: "Schema"
|
|
@@ -207,21 +209,18 @@ const isResponseNode = isKind("Response");
|
|
|
207
209
|
function definePrinter(build) {
|
|
208
210
|
return (options) => {
|
|
209
211
|
const { name, options: resolvedOptions, nodes } = build(options ?? {});
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
const
|
|
214
|
-
|
|
215
|
-
options: resolvedOptions
|
|
216
|
-
};
|
|
217
|
-
return handler.call(context, node);
|
|
212
|
+
const context = {
|
|
213
|
+
options: resolvedOptions,
|
|
214
|
+
print: (node) => {
|
|
215
|
+
const handler = nodes[node.type];
|
|
216
|
+
return handler ? handler.call(context, node) : void 0;
|
|
218
217
|
}
|
|
219
|
-
}
|
|
218
|
+
};
|
|
220
219
|
return {
|
|
221
220
|
name,
|
|
222
221
|
options: resolvedOptions,
|
|
223
|
-
print,
|
|
224
|
-
for: (nodes) => nodes.map(print)
|
|
222
|
+
print: context.print,
|
|
223
|
+
for: (nodes) => nodes.map(context.print)
|
|
225
224
|
};
|
|
226
225
|
};
|
|
227
226
|
}
|
|
@@ -284,7 +283,7 @@ function getChildren(node, recurse) {
|
|
|
284
283
|
case "Schema": {
|
|
285
284
|
const children = [];
|
|
286
285
|
if (!recurse) return [];
|
|
287
|
-
if ("properties" in node && node.properties) children.push(...node.properties);
|
|
286
|
+
if ("properties" in node && node.properties.length > 0) children.push(...node.properties);
|
|
288
287
|
if ("items" in node && node.items) children.push(...node.items);
|
|
289
288
|
if ("members" in node && node.members) children.push(...node.members);
|
|
290
289
|
return children;
|
|
@@ -355,7 +354,7 @@ function transform(node, visitor, options = {}) {
|
|
|
355
354
|
if (replaced) schema = replaced;
|
|
356
355
|
return {
|
|
357
356
|
...schema,
|
|
358
|
-
..."properties" in schema && recurse ? { properties: schema.properties
|
|
357
|
+
..."properties" in schema && recurse ? { properties: schema.properties.map((p) => transform(p, visitor, options)) } : {},
|
|
359
358
|
..."items" in schema && recurse ? { items: schema.items?.map((i) => transform(i, visitor, options)) } : {},
|
|
360
359
|
..."members" in schema && recurse ? { members: schema.members?.map((m) => transform(m, visitor, options)) } : {}
|
|
361
360
|
};
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":[],"sources":["../src/constants.ts","../src/factory.ts","../src/guards.ts","../src/printer.ts","../src/refs.ts","../src/visitor.ts"],"sourcesContent":["import type { NodeKind } from './nodes/base.ts'\nimport type { MediaType } from './nodes/http.ts'\nimport type { HttpMethod } from './nodes/operation.ts'\nimport type { ParameterLocation } from './nodes/parameter.ts'\nimport type { SchemaType } from './nodes/schema.ts'\n\n/**\n * Depth for schema traversal in visitor functions.\n */\nexport type VisitorDepth = 'shallow' | 'deep'\n\nexport const visitorDepths = {\n shallow: 'shallow',\n deep: 'deep',\n} as const satisfies Record<VisitorDepth, VisitorDepth>\n\nexport const nodeKinds = {\n root: 'Root',\n operation: 'Operation',\n schema: 'Schema',\n property: 'Property',\n parameter: 'Parameter',\n response: 'Response',\n} as const satisfies Record<Lowercase<NodeKind>, NodeKind>\n\nexport const schemaTypes = {\n string: 'string',\n /**\n * Floating-point number (`float`, `double`).\n */\n number: 'number',\n /**\n * Whole number (`int32`). Use `bigint` for `int64`.\n */\n integer: 'integer',\n /**\n * 64-bit integer (`int64`). Only used when `integerType` is set to `'bigint'`.\n */\n bigint: 'bigint',\n boolean: 'boolean',\n null: 'null',\n any: 'any',\n unknown: 'unknown',\n void: 'void',\n object: 'object',\n array: 'array',\n tuple: 'tuple',\n union: 'union',\n intersection: 'intersection',\n enum: 'enum',\n ref: 'ref',\n date: 'date',\n datetime: 'datetime',\n time: 'time',\n uuid: 'uuid',\n email: 'email',\n url: 'url',\n blob: 'blob',\n} as const satisfies Record<SchemaType, SchemaType>\n\nexport const httpMethods = {\n get: 'GET',\n post: 'POST',\n put: 'PUT',\n patch: 'PATCH',\n delete: 'DELETE',\n head: 'HEAD',\n options: 'OPTIONS',\n trace: 'TRACE',\n} as const satisfies Record<Lowercase<HttpMethod>, HttpMethod>\n\nexport const parameterLocations = {\n path: 'path',\n query: 'query',\n header: 'header',\n cookie: 'cookie',\n} as const satisfies Record<ParameterLocation, ParameterLocation>\n\n/**\n * Default max concurrent visitor calls in `walk`.\n */\nexport const WALK_CONCURRENCY = 30\n\n/**\n * Fallback status code string for API spec responses.\n */\nexport const DEFAULT_STATUS_CODE = 'default' as const\n\nexport const mediaTypes = {\n applicationJson: 'application/json',\n applicationXml: 'application/xml',\n applicationFormUrlEncoded: 'application/x-www-form-urlencoded',\n applicationOctetStream: 'application/octet-stream',\n applicationPdf: 'application/pdf',\n applicationZip: 'application/zip',\n applicationGraphql: 'application/graphql',\n multipartFormData: 'multipart/form-data',\n textPlain: 'text/plain',\n textHtml: 'text/html',\n textCsv: 'text/csv',\n textXml: 'text/xml',\n imagePng: 'image/png',\n imageJpeg: 'image/jpeg',\n imageGif: 'image/gif',\n imageWebp: 'image/webp',\n imageSvgXml: 'image/svg+xml',\n audioMpeg: 'audio/mpeg',\n videoMp4: 'video/mp4',\n} as const satisfies Record<string, MediaType>\n","import type { OperationNode, ParameterNode, PropertyNode, ResponseNode, RootNode, SchemaNode } from './nodes/index.ts'\n\n/**\n * Distributive variant of `Omit` that preserves union members.\n */\nexport type DistributiveOmit<T, K extends PropertyKey> = T extends unknown ? Omit<T, K> : never\n\n/**\n * Creates a `RootNode`.\n */\nexport function createRoot(overrides: Partial<Omit<RootNode, 'kind'>> = {}): RootNode {\n return {\n schemas: [],\n operations: [],\n ...overrides,\n kind: 'Root',\n }\n}\n\n/**\n * Creates an `OperationNode`.\n */\nexport function createOperation(\n props: Pick<OperationNode, 'operationId' | 'method' | 'path'> & Partial<Omit<OperationNode, 'kind' | 'operationId' | 'method' | 'path'>>,\n): OperationNode {\n return {\n tags: [],\n parameters: [],\n responses: [],\n ...props,\n kind: 'Operation',\n }\n}\n\n/**\n * Creates a `SchemaNode`, narrowed to the variant of `props.type`.\n */\nexport function createSchema<T extends DistributiveOmit<SchemaNode, 'kind'>>(props: T): T & { kind: 'Schema' } {\n return { ...props, kind: 'Schema' } as T & { kind: 'Schema' }\n}\n\n/**\n * Creates a `PropertyNode`. `required` defaults to `false`.\n */\nexport function createProperty(props: Pick<PropertyNode, 'name' | 'schema'> & Partial<Omit<PropertyNode, 'kind' | 'name' | 'schema'>>): PropertyNode {\n return {\n required: false,\n ...props,\n kind: 'Property',\n }\n}\n\n/**\n * Creates a `ParameterNode`. `required` defaults to `false`.\n */\nexport function createParameter(\n props: Pick<ParameterNode, 'name' | 'in' | 'schema'> & Partial<Omit<ParameterNode, 'kind' | 'name' | 'in' | 'schema'>>,\n): ParameterNode {\n return {\n required: false,\n ...props,\n kind: 'Parameter',\n }\n}\n\n/**\n * Creates a `ResponseNode`.\n */\nexport function createResponse(props: Pick<ResponseNode, 'statusCode'> & Partial<Omit<ResponseNode, 'kind' | 'statusCode'>>): ResponseNode {\n return {\n ...props,\n kind: 'Response',\n }\n}\n","import type { Node, NodeKind, OperationNode, ParameterNode, PropertyNode, ResponseNode, RootNode, SchemaNode, SchemaNodeByType } from './nodes/index.ts'\n\n/**\n * Narrows a `SchemaNode` to the specific variant matching `type`.\n */\nexport function narrowSchema<T extends SchemaNode['type']>(node: SchemaNode | undefined, type: T): SchemaNodeByType[T] | undefined {\n return node?.type === type ? (node as SchemaNodeByType[T]) : undefined\n}\n\nfunction isKind<T extends Node>(kind: NodeKind) {\n return (node: unknown): node is T => (node as Node).kind === kind\n}\n\n/**\n * Type guard for `RootNode`.\n */\nexport const isRootNode = isKind<RootNode>('Root')\n\n/**\n * Type guard for `OperationNode`.\n */\nexport const isOperationNode = isKind<OperationNode>('Operation')\n\n/**\n * Type guard for `SchemaNode`.\n */\nexport const isSchemaNode = isKind<SchemaNode>('Schema')\n\n/**\n * Type guard for `PropertyNode`.\n */\nexport const isPropertyNode = isKind<PropertyNode>('Property')\n\n/**\n * Type guard for `ParameterNode`.\n */\nexport const isParameterNode = isKind<ParameterNode>('Parameter')\n\n/**\n * Type guard for `ResponseNode`.\n */\nexport const isResponseNode = isKind<ResponseNode>('Response')\n","import type { SchemaNode, SchemaNodeByType, SchemaType } from './nodes/index.ts'\n\n/**\n * Handler context for `definePrinter` — mirrors `PluginContext` from `@kubb/core`.\n * Available as `this` inside each node handler.\n */\nexport type PrinterHandlerContext<TOutput, TOptions extends object> = {\n /**\n * Recursively print a nested `SchemaNode`.\n */\n print: (node: SchemaNode) => TOutput | null | undefined\n /**\n * Options for this printer instance.\n */\n options: TOptions\n}\n\n/**\n * Handler for a specific `SchemaNode` variant identified by `SchemaType` key `T`.\n * Use a regular function (not an arrow function) so that `this` is available.\n */\nexport type PrinterHandler<TOutput, TOptions extends object, T extends SchemaType = SchemaType> = (\n this: PrinterHandlerContext<TOutput, TOptions>,\n node: SchemaNodeByType[T],\n) => TOutput | null | undefined\n\n/**\n * Shape of the type parameter passed to `definePrinter`.\n * Mirrors `AdapterFactoryOptions` / `PluginFactoryOptions` from `@kubb/core`.\n *\n * - `TName` — unique string identifier (e.g. `'zod'`, `'ts'`)\n * - `TOptions` — options passed to and stored on the printer\n * - `TOutput` — the type emitted by `print` (typically `string`)\n */\nexport type PrinterFactoryOptions<TName extends string = string, TOptions extends object = object, TOutput = unknown> = {\n name: TName\n options: TOptions\n output: TOutput\n}\n\n/**\n * The object returned by calling a `definePrinter` instance.\n * Mirrors the shape of `Adapter` from `@kubb/core`.\n */\nexport type Printer<T extends PrinterFactoryOptions = PrinterFactoryOptions> = {\n /**\n * Unique identifier supplied at creation time.\n */\n name: T['name']\n /**\n * Options for this printer instance.\n */\n options: T['options']\n /**\n * Emits `TOutput` from a `SchemaNode`. Returns `null | undefined` when no handler matches.\n */\n print: (node: SchemaNode) => T['output'] | null | undefined\n /**\n * Maps `print` over an array of `SchemaNode`s.\n */\n for: (nodes: Array<SchemaNode>) => Array<T['output'] | null | undefined>\n}\n\ntype PrinterBuilder<T extends PrinterFactoryOptions> = (options: T['options']) => {\n name: T['name']\n /**\n * Options to store on the printer.\n */\n options: T['options']\n nodes: Partial<{\n [K in SchemaType]: PrinterHandler<T['output'], T['options'], K>\n }>\n}\n\n/**\n * Creates a named printer factory. Mirrors the `definePlugin` / `defineAdapter` pattern\n * from `@kubb/core` — wraps a builder to make options optional and separates raw options\n * from resolved options.\n *\n * @example\n * ```ts\n * type ZodPrinter = PrinterFactoryOptions<'zod', { strict?: boolean }, { strict: boolean }, string>\n *\n * export const zodPrinter = definePrinter<ZodPrinter>((options) => {\n * const { strict = true } = options\n * return {\n * name: 'zod',\n * options: { strict },\n * nodes: {\n * string(node) {\n * return `z.string()`\n * },\n * object(node) {\n * const props = node.properties\n * ?.map(p => `${p.name}: ${this.print(p)}`)\n * .join(', ') ?? ''\n * return `z.object({ ${props} })`\n * },\n * },\n * }\n * })\n *\n * const printer = zodPrinter({ strict: false })\n * printer.name // 'zod'\n * printer.options // { strict: false }\n * printer.print(node) // 'z.string()'\n * ```\n */\nexport function definePrinter<T extends PrinterFactoryOptions = PrinterFactoryOptions>(build: PrinterBuilder<T>): (options?: T['options']) => Printer<T> {\n return (options) => {\n const { name, options: resolvedOptions, nodes } = build(options ?? ({} as T['options']))\n\n function print(node: SchemaNode): T['output'] | null | undefined {\n const type = node.type as SchemaType\n\n const handler = nodes[type]\n if (handler) {\n const context: PrinterHandlerContext<T['output'], T['options']> = { print, options: resolvedOptions }\n return (handler as PrinterHandler<T['output'], T['options']>).call(context, node as SchemaNodeByType[SchemaType])\n }\n\n return undefined\n }\n\n return { name, options: resolvedOptions, print, for: (nodes) => nodes.map(print) }\n }\n}\n","import type { RootNode } from './nodes/root.ts'\nimport type { SchemaNode } from './nodes/schema.ts'\n\n/**\n * Schema name to `SchemaNode` mapping.\n */\nexport type RefMap = Map<string, SchemaNode>\n\n/**\n * Indexes named schemas from `root.schemas` by name. Unnamed schemas are skipped.\n */\nexport function buildRefMap(root: RootNode): RefMap {\n const map: RefMap = new Map()\n\n for (const schema of root.schemas) {\n if (schema.name) {\n map.set(schema.name, schema)\n }\n }\n return map\n}\n\n/**\n * Looks up a schema by name. Prefer over `RefMap.get()` to keep the resolution strategy swappable.\n */\nexport function resolveRef(refMap: RefMap, ref: string): SchemaNode | undefined {\n return refMap.get(ref)\n}\n\n/**\n * Converts a `RefMap` to a plain object.\n */\nexport function refMapToObject(refMap: RefMap): Record<string, SchemaNode> {\n return Object.fromEntries(refMap)\n}\n","import type { VisitorDepth } from './constants.ts'\nimport { visitorDepths, WALK_CONCURRENCY } from './constants.ts'\nimport type { Node, OperationNode, ParameterNode, PropertyNode, ResponseNode, RootNode, SchemaNode } from './nodes/index.ts'\n\nfunction createLimit(concurrency: number) {\n let active = 0\n const queue: Array<() => void> = []\n\n function next() {\n if (active < concurrency && queue.length > 0) {\n active++\n queue.shift()!()\n }\n }\n\n return function limit<T>(fn: () => Promise<T> | T): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n queue.push(() => {\n Promise.resolve(fn())\n .then(resolve, reject)\n .finally(() => {\n active--\n next()\n })\n })\n next()\n })\n }\n}\n\ntype LimitFn = ReturnType<typeof createLimit>\n\n/**\n * Shared options for `walk`, `transform`, and `collect`.\n */\nexport type VisitorOptions = {\n depth?: VisitorDepth\n /**\n * Maximum number of sibling nodes visited concurrently inside `walk`.\n * @default 30\n */\n concurrency?: number\n}\n\n/**\n * Synchronous visitor for `transform` and `walk`.\n */\nexport type Visitor = {\n root?(node: RootNode): void | RootNode\n operation?(node: OperationNode): void | OperationNode\n schema?(node: SchemaNode): void | SchemaNode\n property?(node: PropertyNode): void | PropertyNode\n parameter?(node: ParameterNode): void | ParameterNode\n response?(node: ResponseNode): void | ResponseNode\n}\n\ntype MaybePromise<T> = T | Promise<T>\n\n/**\n * Async visitor for `walk`. Synchronous `Visitor` objects are compatible.\n */\nexport type AsyncVisitor = {\n root?(node: RootNode): MaybePromise<void | RootNode>\n operation?(node: OperationNode): MaybePromise<void | OperationNode>\n schema?(node: SchemaNode): MaybePromise<void | SchemaNode>\n property?(node: PropertyNode): MaybePromise<void | PropertyNode>\n parameter?(node: ParameterNode): MaybePromise<void | ParameterNode>\n response?(node: ResponseNode): MaybePromise<void | ResponseNode>\n}\n\n/**\n * Visitor for `collect`.\n */\nexport type CollectVisitor<T> = {\n root?(node: RootNode): T | undefined\n operation?(node: OperationNode): T | undefined\n schema?(node: SchemaNode): T | undefined\n property?(node: PropertyNode): T | undefined\n parameter?(node: ParameterNode): T | undefined\n response?(node: ResponseNode): T | undefined\n}\n\n/**\n * Traversable children of `node`, respecting `recurse` for schema nodes.\n */\nfunction getChildren(node: Node, recurse: boolean): Array<Node> {\n switch (node.kind) {\n case 'Root':\n return [...node.schemas, ...node.operations]\n case 'Operation':\n return [...node.parameters, ...(node.requestBody ? [node.requestBody] : []), ...node.responses]\n case 'Schema': {\n const children: Array<Node> = []\n\n if (!recurse) return []\n\n if ('properties' in node && node.properties) children.push(...node.properties)\n if ('items' in node && node.items) children.push(...node.items)\n if ('members' in node && node.members) children.push(...node.members)\n\n return children\n }\n case 'Property':\n return [node.schema]\n case 'Parameter':\n return [node.schema]\n case 'Response':\n return node.schema ? [node.schema] : []\n }\n}\n\n/**\n * Depth-first traversal for side effects. Visitor return values are ignored.\n * Sibling nodes at each level are visited concurrently up to `options.concurrency` (default: 30).\n */\nexport async function walk(node: Node, visitor: AsyncVisitor, options: VisitorOptions = {}): Promise<void> {\n const recurse = (options.depth ?? visitorDepths.deep) === visitorDepths.deep\n const limit = createLimit(options.concurrency ?? WALK_CONCURRENCY)\n return _walk(node, visitor, recurse, limit)\n}\n\nasync function _walk(node: Node, visitor: AsyncVisitor, recurse: boolean, limit: LimitFn): Promise<void> {\n switch (node.kind) {\n case 'Root':\n await limit(() => visitor.root?.(node))\n break\n case 'Operation':\n await limit(() => visitor.operation?.(node))\n break\n case 'Schema':\n await limit(() => visitor.schema?.(node))\n break\n case 'Property':\n await limit(() => visitor.property?.(node))\n break\n case 'Parameter':\n await limit(() => visitor.parameter?.(node))\n break\n case 'Response':\n await limit(() => visitor.response?.(node))\n break\n }\n\n const children = getChildren(node, recurse)\n await Promise.all(children.map((child) => _walk(child, visitor, recurse, limit)))\n}\n\n/**\n * Depth-first immutable transformation. Visitor return values replace nodes; `undefined` keeps the original.\n */\nexport function transform(node: RootNode, visitor: Visitor, options?: VisitorOptions): RootNode\nexport function transform(node: OperationNode, visitor: Visitor, options?: VisitorOptions): OperationNode\nexport function transform(node: SchemaNode, visitor: Visitor, options?: VisitorOptions): SchemaNode\nexport function transform(node: PropertyNode, visitor: Visitor, options?: VisitorOptions): PropertyNode\nexport function transform(node: ParameterNode, visitor: Visitor, options?: VisitorOptions): ParameterNode\nexport function transform(node: ResponseNode, visitor: Visitor, options?: VisitorOptions): ResponseNode\nexport function transform(node: Node, visitor: Visitor, options?: VisitorOptions): Node\nexport function transform(node: Node, visitor: Visitor, options: VisitorOptions = {}): Node {\n const recurse = (options.depth ?? visitorDepths.deep) === visitorDepths.deep\n\n switch (node.kind) {\n case 'Root': {\n let root = node\n const replaced = visitor.root?.(root)\n if (replaced) root = replaced\n\n return {\n ...root,\n schemas: root.schemas.map((s) => transform(s, visitor, options)),\n operations: root.operations.map((op) => transform(op, visitor, options)),\n }\n }\n case 'Operation': {\n let op = node\n const replaced = visitor.operation?.(op)\n if (replaced) op = replaced\n\n return {\n ...op,\n parameters: op.parameters.map((p) => transform(p, visitor, options)),\n requestBody: op.requestBody ? transform(op.requestBody, visitor, options) : undefined,\n responses: op.responses.map((r) => transform(r, visitor, options)),\n }\n }\n case 'Schema': {\n let schema = node\n const replaced = visitor.schema?.(schema)\n if (replaced) schema = replaced\n\n return {\n ...schema,\n ...('properties' in schema && recurse ? { properties: schema.properties?.map((p) => transform(p, visitor, options)) } : {}),\n ...('items' in schema && recurse ? { items: schema.items?.map((i) => transform(i, visitor, options)) } : {}),\n ...('members' in schema && recurse ? { members: schema.members?.map((m) => transform(m, visitor, options)) } : {}),\n }\n }\n case 'Property': {\n let prop = node\n const replaced = visitor.property?.(prop)\n if (replaced) prop = replaced\n\n return {\n ...prop,\n schema: transform(prop.schema, visitor, options),\n }\n }\n case 'Parameter': {\n let param = node\n const replaced = visitor.parameter?.(param)\n if (replaced) param = replaced\n\n return {\n ...param,\n schema: transform(param.schema, visitor, options),\n }\n }\n case 'Response': {\n let response = node\n const replaced = visitor.response?.(response)\n if (replaced) response = replaced\n\n return {\n ...response,\n schema: response.schema ? transform(response.schema, visitor, options) : undefined,\n }\n }\n }\n}\n\n/**\n * Depth-first synchronous reduction. Collects non-`undefined` visitor return values into an array.\n */\nexport function collect<T>(node: Node, visitor: CollectVisitor<T>, options: VisitorOptions = {}): Array<T> {\n const recurse = (options.depth ?? visitorDepths.deep) === visitorDepths.deep\n const results: Array<T> = []\n\n let v: T | undefined\n switch (node.kind) {\n case 'Root':\n v = visitor.root?.(node)\n break\n case 'Operation':\n v = visitor.operation?.(node)\n break\n case 'Schema':\n v = visitor.schema?.(node)\n break\n case 'Property':\n v = visitor.property?.(node)\n break\n case 'Parameter':\n v = visitor.parameter?.(node)\n break\n case 'Response':\n v = visitor.response?.(node)\n break\n }\n if (v !== undefined) results.push(v)\n\n for (const child of getChildren(node, recurse)) {\n for (const item of collect(child, visitor, options)) {\n results.push(item)\n }\n }\n\n return results\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":[],"sources":["../src/constants.ts","../src/factory.ts","../src/guards.ts","../src/printer.ts","../src/refs.ts","../src/visitor.ts"],"sourcesContent":["import type { NodeKind } from './nodes/base.ts'\nimport type { MediaType } from './nodes/http.ts'\nimport type { HttpMethod } from './nodes/operation.ts'\nimport type { ParameterLocation } from './nodes/parameter.ts'\nimport type { SchemaType } from './nodes/schema.ts'\n\n/**\n * Depth for schema traversal in visitor functions.\n */\nexport type VisitorDepth = 'shallow' | 'deep'\n\nexport const visitorDepths = {\n shallow: 'shallow',\n deep: 'deep',\n} as const satisfies Record<VisitorDepth, VisitorDepth>\n\nexport const nodeKinds = {\n root: 'Root',\n operation: 'Operation',\n schema: 'Schema',\n property: 'Property',\n parameter: 'Parameter',\n response: 'Response',\n} as const satisfies Record<Lowercase<NodeKind>, NodeKind>\n\nexport const schemaTypes = {\n string: 'string',\n /**\n * Floating-point number (`float`, `double`).\n */\n number: 'number',\n /**\n * Whole number (`int32`). Use `bigint` for `int64`.\n */\n integer: 'integer',\n /**\n * 64-bit integer (`int64`). Only used when `integerType` is set to `'bigint'`.\n */\n bigint: 'bigint',\n boolean: 'boolean',\n null: 'null',\n any: 'any',\n unknown: 'unknown',\n void: 'void',\n object: 'object',\n array: 'array',\n tuple: 'tuple',\n union: 'union',\n intersection: 'intersection',\n enum: 'enum',\n ref: 'ref',\n date: 'date',\n datetime: 'datetime',\n time: 'time',\n uuid: 'uuid',\n email: 'email',\n url: 'url',\n blob: 'blob',\n} as const satisfies Record<SchemaType, SchemaType>\n\nexport const httpMethods = {\n get: 'GET',\n post: 'POST',\n put: 'PUT',\n patch: 'PATCH',\n delete: 'DELETE',\n head: 'HEAD',\n options: 'OPTIONS',\n trace: 'TRACE',\n} as const satisfies Record<Lowercase<HttpMethod>, HttpMethod>\n\nexport const parameterLocations = {\n path: 'path',\n query: 'query',\n header: 'header',\n cookie: 'cookie',\n} as const satisfies Record<ParameterLocation, ParameterLocation>\n\n/**\n * Default max concurrent visitor calls in `walk`.\n */\nexport const WALK_CONCURRENCY = 30\n\n/**\n * Fallback status code string for API spec responses.\n */\nexport const DEFAULT_STATUS_CODE = 'default' as const\n\nexport const mediaTypes = {\n applicationJson: 'application/json',\n applicationXml: 'application/xml',\n applicationFormUrlEncoded: 'application/x-www-form-urlencoded',\n applicationOctetStream: 'application/octet-stream',\n applicationPdf: 'application/pdf',\n applicationZip: 'application/zip',\n applicationGraphql: 'application/graphql',\n multipartFormData: 'multipart/form-data',\n textPlain: 'text/plain',\n textHtml: 'text/html',\n textCsv: 'text/csv',\n textXml: 'text/xml',\n imagePng: 'image/png',\n imageJpeg: 'image/jpeg',\n imageGif: 'image/gif',\n imageWebp: 'image/webp',\n imageSvgXml: 'image/svg+xml',\n audioMpeg: 'audio/mpeg',\n videoMp4: 'video/mp4',\n} as const satisfies Record<string, MediaType>\n","import type { ObjectSchemaNode, OperationNode, ParameterNode, PropertyNode, ResponseNode, RootNode, SchemaNode } from './nodes/index.ts'\n\n/**\n * Distributive variant of `Omit` that preserves union members.\n */\nexport type DistributiveOmit<T, K extends PropertyKey> = T extends unknown ? Omit<T, K> : never\n\n/**\n * Creates a `RootNode`.\n */\nexport function createRoot(overrides: Partial<Omit<RootNode, 'kind'>> = {}): RootNode {\n return {\n schemas: [],\n operations: [],\n ...overrides,\n kind: 'Root',\n }\n}\n\n/**\n * Creates an `OperationNode`.\n */\nexport function createOperation(\n props: Pick<OperationNode, 'operationId' | 'method' | 'path'> & Partial<Omit<OperationNode, 'kind' | 'operationId' | 'method' | 'path'>>,\n): OperationNode {\n return {\n tags: [],\n parameters: [],\n responses: [],\n ...props,\n kind: 'Operation',\n }\n}\n\n/**\n * Creates a `SchemaNode`, narrowed to the variant of `props.type`.\n * For object schemas, `properties` defaults to `[]` when not provided.\n */\nexport function createSchema<T extends Omit<ObjectSchemaNode, 'kind' | 'properties'> & { properties?: Array<PropertyNode> }>(\n props: T,\n): Omit<T, 'properties'> & { properties: Array<PropertyNode>; kind: 'Schema' }\nexport function createSchema<T extends DistributiveOmit<Exclude<SchemaNode, ObjectSchemaNode>, 'kind'>>(props: T): T & { kind: 'Schema' }\nexport function createSchema(props: DistributiveOmit<SchemaNode, 'kind'>): SchemaNode\nexport function createSchema(props: Record<string, unknown>): Record<string, unknown> {\n if (props['type'] === 'object') {\n return { properties: [], ...props, kind: 'Schema' }\n }\n\n return { ...props, kind: 'Schema' }\n}\n\n/**\n * Creates a `PropertyNode`. `required` defaults to `false`.\n */\nexport function createProperty(props: Pick<PropertyNode, 'name' | 'schema'> & Partial<Omit<PropertyNode, 'kind' | 'name' | 'schema'>>): PropertyNode {\n return {\n required: false,\n ...props,\n kind: 'Property',\n }\n}\n\n/**\n * Creates a `ParameterNode`. `required` defaults to `false`.\n */\nexport function createParameter(\n props: Pick<ParameterNode, 'name' | 'in' | 'schema'> & Partial<Omit<ParameterNode, 'kind' | 'name' | 'in' | 'schema'>>,\n): ParameterNode {\n return {\n required: false,\n ...props,\n kind: 'Parameter',\n }\n}\n\n/**\n * Creates a `ResponseNode`.\n */\nexport function createResponse(props: Pick<ResponseNode, 'statusCode'> & Partial<Omit<ResponseNode, 'kind' | 'statusCode'>>): ResponseNode {\n return {\n ...props,\n kind: 'Response',\n }\n}\n","import type { Node, NodeKind, OperationNode, ParameterNode, PropertyNode, ResponseNode, RootNode, SchemaNode, SchemaNodeByType } from './nodes/index.ts'\n\n/**\n * Narrows a `SchemaNode` to the specific variant matching `type`.\n */\nexport function narrowSchema<T extends SchemaNode['type']>(node: SchemaNode | undefined, type: T): SchemaNodeByType[T] | undefined {\n return node?.type === type ? (node as SchemaNodeByType[T]) : undefined\n}\n\nfunction isKind<T extends Node>(kind: NodeKind) {\n return (node: unknown): node is T => (node as Node).kind === kind\n}\n\n/**\n * Type guard for `RootNode`.\n */\nexport const isRootNode = isKind<RootNode>('Root')\n\n/**\n * Type guard for `OperationNode`.\n */\nexport const isOperationNode = isKind<OperationNode>('Operation')\n\n/**\n * Type guard for `SchemaNode`.\n */\nexport const isSchemaNode = isKind<SchemaNode>('Schema')\n\n/**\n * Type guard for `PropertyNode`.\n */\nexport const isPropertyNode = isKind<PropertyNode>('Property')\n\n/**\n * Type guard for `ParameterNode`.\n */\nexport const isParameterNode = isKind<ParameterNode>('Parameter')\n\n/**\n * Type guard for `ResponseNode`.\n */\nexport const isResponseNode = isKind<ResponseNode>('Response')\n","import type { SchemaNode, SchemaNodeByType, SchemaType } from './nodes/index.ts'\n\n/**\n * Handler context for `definePrinter` — mirrors `PluginContext` from `@kubb/core`.\n * Available as `this` inside each node handler.\n */\nexport type PrinterHandlerContext<TOutput, TOptions extends object> = {\n /**\n * Recursively print a nested `SchemaNode`.\n */\n print: (node: SchemaNode) => TOutput | null | undefined\n /**\n * Options for this printer instance.\n */\n options: TOptions\n}\n\n/**\n * Handler for a specific `SchemaNode` variant identified by `SchemaType` key `T`.\n * Use a regular function (not an arrow function) so that `this` is available.\n */\nexport type PrinterHandler<TOutput, TOptions extends object, T extends SchemaType = SchemaType> = (\n this: PrinterHandlerContext<TOutput, TOptions>,\n node: SchemaNodeByType[T],\n) => TOutput | null | undefined\n\n/**\n * Shape of the type parameter passed to `definePrinter`.\n * Mirrors `AdapterFactoryOptions` / `PluginFactoryOptions` from `@kubb/core`.\n *\n * - `TName` — unique string identifier (e.g. `'zod'`, `'ts'`)\n * - `TOptions` — options passed to and stored on the printer\n * - `TOutput` — the type emitted by `print` (typically `string`)\n */\nexport type PrinterFactoryOptions<TName extends string = string, TOptions extends object = object, TOutput = unknown> = {\n name: TName\n options: TOptions\n output: TOutput\n}\n\n/**\n * The object returned by calling a `definePrinter` instance.\n * Mirrors the shape of `Adapter` from `@kubb/core`.\n */\nexport type Printer<T extends PrinterFactoryOptions = PrinterFactoryOptions> = {\n /**\n * Unique identifier supplied at creation time.\n */\n name: T['name']\n /**\n * Options for this printer instance.\n */\n options: T['options']\n /**\n * Emits `TOutput` from a `SchemaNode`. Returns `null | undefined` when no handler matches.\n */\n print: (node: SchemaNode) => T['output'] | null | undefined\n /**\n * Maps `print` over an array of `SchemaNode`s.\n */\n for: (nodes: Array<SchemaNode>) => Array<T['output'] | null | undefined>\n}\n\ntype PrinterBuilder<T extends PrinterFactoryOptions> = (options: T['options']) => {\n name: T['name']\n /**\n * Options to store on the printer.\n */\n options: T['options']\n nodes: Partial<{\n [K in SchemaType]: PrinterHandler<T['output'], T['options'], K>\n }>\n}\n\n/**\n * Creates a named printer factory. Mirrors the `definePlugin` / `defineAdapter` pattern\n * from `@kubb/core` — wraps a builder to make options optional and separates raw options\n * from resolved options.\n *\n * @example\n * ```ts\n * type ZodPrinter = PrinterFactoryOptions<'zod', { strict?: boolean }, { strict: boolean }, string>\n *\n * export const zodPrinter = definePrinter<ZodPrinter>((options) => {\n * const { strict = true } = options\n * return {\n * name: 'zod',\n * options: { strict },\n * nodes: {\n * string(node) {\n * return `z.string()`\n * },\n * object(node) {\n * const props = node.properties\n * ?.map(p => `${p.name}: ${this.print(p)}`)\n * .join(', ') ?? ''\n * return `z.object({ ${props} })`\n * },\n * },\n * }\n * })\n *\n * const printer = zodPrinter({ strict: false })\n * printer.name // 'zod'\n * printer.options // { strict: false }\n * printer.print(node) // 'z.string()'\n * ```\n */\nexport function definePrinter<T extends PrinterFactoryOptions = PrinterFactoryOptions>(build: PrinterBuilder<T>): (options?: T['options']) => Printer<T> {\n return (options) => {\n const { name, options: resolvedOptions, nodes } = build(options ?? ({} as T['options']))\n\n const context: PrinterHandlerContext<T['output'], T['options']> = {\n options: resolvedOptions,\n print: (node: SchemaNode) => {\n const type = node.type as SchemaType\n const handler = nodes[type]\n return handler ? (handler as PrinterHandler<T['output'], T['options']>).call(context, node as SchemaNodeByType[SchemaType]) : undefined\n },\n }\n\n return {\n name,\n options: resolvedOptions,\n print: context.print,\n for: (nodes) => nodes.map(context.print),\n }\n }\n}\n","import type { RootNode } from './nodes/root.ts'\nimport type { SchemaNode } from './nodes/schema.ts'\n\n/**\n * Schema name to `SchemaNode` mapping.\n */\nexport type RefMap = Map<string, SchemaNode>\n\n/**\n * Indexes named schemas from `root.schemas` by name. Unnamed schemas are skipped.\n */\nexport function buildRefMap(root: RootNode): RefMap {\n const map: RefMap = new Map()\n\n for (const schema of root.schemas) {\n if (schema.name) {\n map.set(schema.name, schema)\n }\n }\n return map\n}\n\n/**\n * Looks up a schema by name. Prefer over `RefMap.get()` to keep the resolution strategy swappable.\n */\nexport function resolveRef(refMap: RefMap, ref: string): SchemaNode | undefined {\n return refMap.get(ref)\n}\n\n/**\n * Converts a `RefMap` to a plain object.\n */\nexport function refMapToObject(refMap: RefMap): Record<string, SchemaNode> {\n return Object.fromEntries(refMap)\n}\n","import type { VisitorDepth } from './constants.ts'\nimport { visitorDepths, WALK_CONCURRENCY } from './constants.ts'\nimport type { Node, OperationNode, ParameterNode, PropertyNode, ResponseNode, RootNode, SchemaNode } from './nodes/index.ts'\n\nfunction createLimit(concurrency: number) {\n let active = 0\n const queue: Array<() => void> = []\n\n function next() {\n if (active < concurrency && queue.length > 0) {\n active++\n queue.shift()!()\n }\n }\n\n return function limit<T>(fn: () => Promise<T> | T): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n queue.push(() => {\n Promise.resolve(fn())\n .then(resolve, reject)\n .finally(() => {\n active--\n next()\n })\n })\n next()\n })\n }\n}\n\ntype LimitFn = ReturnType<typeof createLimit>\n\n/**\n * Shared options for `walk`, `transform`, and `collect`.\n */\nexport type VisitorOptions = {\n depth?: VisitorDepth\n /**\n * Maximum number of sibling nodes visited concurrently inside `walk`.\n * @default 30\n */\n concurrency?: number\n}\n\n/**\n * Synchronous visitor for `transform` and `walk`.\n */\nexport type Visitor = {\n root?(node: RootNode): void | RootNode\n operation?(node: OperationNode): void | OperationNode\n schema?(node: SchemaNode): void | SchemaNode\n property?(node: PropertyNode): void | PropertyNode\n parameter?(node: ParameterNode): void | ParameterNode\n response?(node: ResponseNode): void | ResponseNode\n}\n\ntype MaybePromise<T> = T | Promise<T>\n\n/**\n * Async visitor for `walk`. Synchronous `Visitor` objects are compatible.\n */\nexport type AsyncVisitor = {\n root?(node: RootNode): MaybePromise<void | RootNode>\n operation?(node: OperationNode): MaybePromise<void | OperationNode>\n schema?(node: SchemaNode): MaybePromise<void | SchemaNode>\n property?(node: PropertyNode): MaybePromise<void | PropertyNode>\n parameter?(node: ParameterNode): MaybePromise<void | ParameterNode>\n response?(node: ResponseNode): MaybePromise<void | ResponseNode>\n}\n\n/**\n * Visitor for `collect`.\n */\nexport type CollectVisitor<T> = {\n root?(node: RootNode): T | undefined\n operation?(node: OperationNode): T | undefined\n schema?(node: SchemaNode): T | undefined\n property?(node: PropertyNode): T | undefined\n parameter?(node: ParameterNode): T | undefined\n response?(node: ResponseNode): T | undefined\n}\n\n/**\n * Traversable children of `node`, respecting `recurse` for schema nodes.\n */\nfunction getChildren(node: Node, recurse: boolean): Array<Node> {\n switch (node.kind) {\n case 'Root':\n return [...node.schemas, ...node.operations]\n case 'Operation':\n return [...node.parameters, ...(node.requestBody ? [node.requestBody] : []), ...node.responses]\n case 'Schema': {\n const children: Array<Node> = []\n\n if (!recurse) return []\n\n if ('properties' in node && node.properties.length > 0) children.push(...node.properties)\n if ('items' in node && node.items) children.push(...node.items)\n if ('members' in node && node.members) children.push(...node.members)\n\n return children\n }\n case 'Property':\n return [node.schema]\n case 'Parameter':\n return [node.schema]\n case 'Response':\n return node.schema ? [node.schema] : []\n }\n}\n\n/**\n * Depth-first traversal for side effects. Visitor return values are ignored.\n * Sibling nodes at each level are visited concurrently up to `options.concurrency` (default: 30).\n */\nexport async function walk(node: Node, visitor: AsyncVisitor, options: VisitorOptions = {}): Promise<void> {\n const recurse = (options.depth ?? visitorDepths.deep) === visitorDepths.deep\n const limit = createLimit(options.concurrency ?? WALK_CONCURRENCY)\n return _walk(node, visitor, recurse, limit)\n}\n\nasync function _walk(node: Node, visitor: AsyncVisitor, recurse: boolean, limit: LimitFn): Promise<void> {\n switch (node.kind) {\n case 'Root':\n await limit(() => visitor.root?.(node))\n break\n case 'Operation':\n await limit(() => visitor.operation?.(node))\n break\n case 'Schema':\n await limit(() => visitor.schema?.(node))\n break\n case 'Property':\n await limit(() => visitor.property?.(node))\n break\n case 'Parameter':\n await limit(() => visitor.parameter?.(node))\n break\n case 'Response':\n await limit(() => visitor.response?.(node))\n break\n }\n\n const children = getChildren(node, recurse)\n await Promise.all(children.map((child) => _walk(child, visitor, recurse, limit)))\n}\n\n/**\n * Depth-first immutable transformation. Visitor return values replace nodes; `undefined` keeps the original.\n */\nexport function transform(node: RootNode, visitor: Visitor, options?: VisitorOptions): RootNode\nexport function transform(node: OperationNode, visitor: Visitor, options?: VisitorOptions): OperationNode\nexport function transform(node: SchemaNode, visitor: Visitor, options?: VisitorOptions): SchemaNode\nexport function transform(node: PropertyNode, visitor: Visitor, options?: VisitorOptions): PropertyNode\nexport function transform(node: ParameterNode, visitor: Visitor, options?: VisitorOptions): ParameterNode\nexport function transform(node: ResponseNode, visitor: Visitor, options?: VisitorOptions): ResponseNode\nexport function transform(node: Node, visitor: Visitor, options?: VisitorOptions): Node\nexport function transform(node: Node, visitor: Visitor, options: VisitorOptions = {}): Node {\n const recurse = (options.depth ?? visitorDepths.deep) === visitorDepths.deep\n\n switch (node.kind) {\n case 'Root': {\n let root = node\n const replaced = visitor.root?.(root)\n if (replaced) root = replaced\n\n return {\n ...root,\n schemas: root.schemas.map((s) => transform(s, visitor, options)),\n operations: root.operations.map((op) => transform(op, visitor, options)),\n }\n }\n case 'Operation': {\n let op = node\n const replaced = visitor.operation?.(op)\n if (replaced) op = replaced\n\n return {\n ...op,\n parameters: op.parameters.map((p) => transform(p, visitor, options)),\n requestBody: op.requestBody ? transform(op.requestBody, visitor, options) : undefined,\n responses: op.responses.map((r) => transform(r, visitor, options)),\n }\n }\n case 'Schema': {\n let schema = node\n const replaced = visitor.schema?.(schema)\n if (replaced) schema = replaced\n\n return {\n ...schema,\n ...('properties' in schema && recurse ? { properties: schema.properties.map((p) => transform(p, visitor, options)) } : {}),\n ...('items' in schema && recurse ? { items: schema.items?.map((i) => transform(i, visitor, options)) } : {}),\n ...('members' in schema && recurse ? { members: schema.members?.map((m) => transform(m, visitor, options)) } : {}),\n }\n }\n case 'Property': {\n let prop = node\n const replaced = visitor.property?.(prop)\n if (replaced) prop = replaced\n\n return {\n ...prop,\n schema: transform(prop.schema, visitor, options),\n }\n }\n case 'Parameter': {\n let param = node\n const replaced = visitor.parameter?.(param)\n if (replaced) param = replaced\n\n return {\n ...param,\n schema: transform(param.schema, visitor, options),\n }\n }\n case 'Response': {\n let response = node\n const replaced = visitor.response?.(response)\n if (replaced) response = replaced\n\n return {\n ...response,\n schema: response.schema ? transform(response.schema, visitor, options) : undefined,\n }\n }\n }\n}\n\n/**\n * Depth-first synchronous reduction. Collects non-`undefined` visitor return values into an array.\n */\nexport function collect<T>(node: Node, visitor: CollectVisitor<T>, options: VisitorOptions = {}): Array<T> {\n const recurse = (options.depth ?? visitorDepths.deep) === visitorDepths.deep\n const results: Array<T> = []\n\n let v: T | undefined\n switch (node.kind) {\n case 'Root':\n v = visitor.root?.(node)\n break\n case 'Operation':\n v = visitor.operation?.(node)\n break\n case 'Schema':\n v = visitor.schema?.(node)\n break\n case 'Property':\n v = visitor.property?.(node)\n break\n case 'Parameter':\n v = visitor.parameter?.(node)\n break\n case 'Response':\n v = visitor.response?.(node)\n break\n }\n if (v !== undefined) results.push(v)\n\n for (const child of getChildren(node, recurse)) {\n for (const item of collect(child, visitor, options)) {\n results.push(item)\n }\n }\n\n return results\n}\n"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as __name } from "./chunk--u3MIqq1.js";
|
|
2
|
-
import {
|
|
2
|
+
import { D as OperationNode, J as SchemaNodeByType, N as ParameterNode, O as ResponseNode, S as createSchema, T as RootNode, _ as createOperation, a as transform, at as mediaTypes, b as createResponse, c as buildRefMap, et as PropertyNode, h as definePrinter, i as collect, it as httpMethods, l as refMapToObject, o as walk, ot as nodeKinds, q as SchemaNode, st as schemaTypes, u as resolveRef, v as createParameter, x as createRoot, y as createProperty } from "./visitor-CmsfJzro.js";
|
|
3
3
|
|
|
4
4
|
//#region src/guards.d.ts
|
|
5
5
|
/**
|
package/dist/index.js
CHANGED
|
@@ -93,10 +93,12 @@ function createOperation(props) {
|
|
|
93
93
|
kind: "Operation"
|
|
94
94
|
};
|
|
95
95
|
}
|
|
96
|
-
/**
|
|
97
|
-
* Creates a `SchemaNode`, narrowed to the variant of `props.type`.
|
|
98
|
-
*/
|
|
99
96
|
function createSchema(props) {
|
|
97
|
+
if (props["type"] === "object") return {
|
|
98
|
+
properties: [],
|
|
99
|
+
...props,
|
|
100
|
+
kind: "Schema"
|
|
101
|
+
};
|
|
100
102
|
return {
|
|
101
103
|
...props,
|
|
102
104
|
kind: "Schema"
|
|
@@ -205,21 +207,18 @@ const isResponseNode = isKind("Response");
|
|
|
205
207
|
function definePrinter(build) {
|
|
206
208
|
return (options) => {
|
|
207
209
|
const { name, options: resolvedOptions, nodes } = build(options ?? {});
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
const
|
|
212
|
-
|
|
213
|
-
options: resolvedOptions
|
|
214
|
-
};
|
|
215
|
-
return handler.call(context, node);
|
|
210
|
+
const context = {
|
|
211
|
+
options: resolvedOptions,
|
|
212
|
+
print: (node) => {
|
|
213
|
+
const handler = nodes[node.type];
|
|
214
|
+
return handler ? handler.call(context, node) : void 0;
|
|
216
215
|
}
|
|
217
|
-
}
|
|
216
|
+
};
|
|
218
217
|
return {
|
|
219
218
|
name,
|
|
220
219
|
options: resolvedOptions,
|
|
221
|
-
print,
|
|
222
|
-
for: (nodes) => nodes.map(print)
|
|
220
|
+
print: context.print,
|
|
221
|
+
for: (nodes) => nodes.map(context.print)
|
|
223
222
|
};
|
|
224
223
|
};
|
|
225
224
|
}
|
|
@@ -282,7 +281,7 @@ function getChildren(node, recurse) {
|
|
|
282
281
|
case "Schema": {
|
|
283
282
|
const children = [];
|
|
284
283
|
if (!recurse) return [];
|
|
285
|
-
if ("properties" in node && node.properties) children.push(...node.properties);
|
|
284
|
+
if ("properties" in node && node.properties.length > 0) children.push(...node.properties);
|
|
286
285
|
if ("items" in node && node.items) children.push(...node.items);
|
|
287
286
|
if ("members" in node && node.members) children.push(...node.members);
|
|
288
287
|
return children;
|
|
@@ -353,7 +352,7 @@ function transform(node, visitor, options = {}) {
|
|
|
353
352
|
if (replaced) schema = replaced;
|
|
354
353
|
return {
|
|
355
354
|
...schema,
|
|
356
|
-
..."properties" in schema && recurse ? { properties: schema.properties
|
|
355
|
+
..."properties" in schema && recurse ? { properties: schema.properties.map((p) => transform(p, visitor, options)) } : {},
|
|
357
356
|
..."items" in schema && recurse ? { items: schema.items?.map((i) => transform(i, visitor, options)) } : {},
|
|
358
357
|
..."members" in schema && recurse ? { members: schema.members?.map((m) => transform(m, visitor, options)) } : {}
|
|
359
358
|
};
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/constants.ts","../src/factory.ts","../src/guards.ts","../src/printer.ts","../src/refs.ts","../src/visitor.ts"],"sourcesContent":["import type { NodeKind } from './nodes/base.ts'\nimport type { MediaType } from './nodes/http.ts'\nimport type { HttpMethod } from './nodes/operation.ts'\nimport type { ParameterLocation } from './nodes/parameter.ts'\nimport type { SchemaType } from './nodes/schema.ts'\n\n/**\n * Depth for schema traversal in visitor functions.\n */\nexport type VisitorDepth = 'shallow' | 'deep'\n\nexport const visitorDepths = {\n shallow: 'shallow',\n deep: 'deep',\n} as const satisfies Record<VisitorDepth, VisitorDepth>\n\nexport const nodeKinds = {\n root: 'Root',\n operation: 'Operation',\n schema: 'Schema',\n property: 'Property',\n parameter: 'Parameter',\n response: 'Response',\n} as const satisfies Record<Lowercase<NodeKind>, NodeKind>\n\nexport const schemaTypes = {\n string: 'string',\n /**\n * Floating-point number (`float`, `double`).\n */\n number: 'number',\n /**\n * Whole number (`int32`). Use `bigint` for `int64`.\n */\n integer: 'integer',\n /**\n * 64-bit integer (`int64`). Only used when `integerType` is set to `'bigint'`.\n */\n bigint: 'bigint',\n boolean: 'boolean',\n null: 'null',\n any: 'any',\n unknown: 'unknown',\n void: 'void',\n object: 'object',\n array: 'array',\n tuple: 'tuple',\n union: 'union',\n intersection: 'intersection',\n enum: 'enum',\n ref: 'ref',\n date: 'date',\n datetime: 'datetime',\n time: 'time',\n uuid: 'uuid',\n email: 'email',\n url: 'url',\n blob: 'blob',\n} as const satisfies Record<SchemaType, SchemaType>\n\nexport const httpMethods = {\n get: 'GET',\n post: 'POST',\n put: 'PUT',\n patch: 'PATCH',\n delete: 'DELETE',\n head: 'HEAD',\n options: 'OPTIONS',\n trace: 'TRACE',\n} as const satisfies Record<Lowercase<HttpMethod>, HttpMethod>\n\nexport const parameterLocations = {\n path: 'path',\n query: 'query',\n header: 'header',\n cookie: 'cookie',\n} as const satisfies Record<ParameterLocation, ParameterLocation>\n\n/**\n * Default max concurrent visitor calls in `walk`.\n */\nexport const WALK_CONCURRENCY = 30\n\n/**\n * Fallback status code string for API spec responses.\n */\nexport const DEFAULT_STATUS_CODE = 'default' as const\n\nexport const mediaTypes = {\n applicationJson: 'application/json',\n applicationXml: 'application/xml',\n applicationFormUrlEncoded: 'application/x-www-form-urlencoded',\n applicationOctetStream: 'application/octet-stream',\n applicationPdf: 'application/pdf',\n applicationZip: 'application/zip',\n applicationGraphql: 'application/graphql',\n multipartFormData: 'multipart/form-data',\n textPlain: 'text/plain',\n textHtml: 'text/html',\n textCsv: 'text/csv',\n textXml: 'text/xml',\n imagePng: 'image/png',\n imageJpeg: 'image/jpeg',\n imageGif: 'image/gif',\n imageWebp: 'image/webp',\n imageSvgXml: 'image/svg+xml',\n audioMpeg: 'audio/mpeg',\n videoMp4: 'video/mp4',\n} as const satisfies Record<string, MediaType>\n","import type { OperationNode, ParameterNode, PropertyNode, ResponseNode, RootNode, SchemaNode } from './nodes/index.ts'\n\n/**\n * Distributive variant of `Omit` that preserves union members.\n */\nexport type DistributiveOmit<T, K extends PropertyKey> = T extends unknown ? Omit<T, K> : never\n\n/**\n * Creates a `RootNode`.\n */\nexport function createRoot(overrides: Partial<Omit<RootNode, 'kind'>> = {}): RootNode {\n return {\n schemas: [],\n operations: [],\n ...overrides,\n kind: 'Root',\n }\n}\n\n/**\n * Creates an `OperationNode`.\n */\nexport function createOperation(\n props: Pick<OperationNode, 'operationId' | 'method' | 'path'> & Partial<Omit<OperationNode, 'kind' | 'operationId' | 'method' | 'path'>>,\n): OperationNode {\n return {\n tags: [],\n parameters: [],\n responses: [],\n ...props,\n kind: 'Operation',\n }\n}\n\n/**\n * Creates a `SchemaNode`, narrowed to the variant of `props.type`.\n */\nexport function createSchema<T extends DistributiveOmit<SchemaNode, 'kind'>>(props: T): T & { kind: 'Schema' } {\n return { ...props, kind: 'Schema' } as T & { kind: 'Schema' }\n}\n\n/**\n * Creates a `PropertyNode`. `required` defaults to `false`.\n */\nexport function createProperty(props: Pick<PropertyNode, 'name' | 'schema'> & Partial<Omit<PropertyNode, 'kind' | 'name' | 'schema'>>): PropertyNode {\n return {\n required: false,\n ...props,\n kind: 'Property',\n }\n}\n\n/**\n * Creates a `ParameterNode`. `required` defaults to `false`.\n */\nexport function createParameter(\n props: Pick<ParameterNode, 'name' | 'in' | 'schema'> & Partial<Omit<ParameterNode, 'kind' | 'name' | 'in' | 'schema'>>,\n): ParameterNode {\n return {\n required: false,\n ...props,\n kind: 'Parameter',\n }\n}\n\n/**\n * Creates a `ResponseNode`.\n */\nexport function createResponse(props: Pick<ResponseNode, 'statusCode'> & Partial<Omit<ResponseNode, 'kind' | 'statusCode'>>): ResponseNode {\n return {\n ...props,\n kind: 'Response',\n }\n}\n","import type { Node, NodeKind, OperationNode, ParameterNode, PropertyNode, ResponseNode, RootNode, SchemaNode, SchemaNodeByType } from './nodes/index.ts'\n\n/**\n * Narrows a `SchemaNode` to the specific variant matching `type`.\n */\nexport function narrowSchema<T extends SchemaNode['type']>(node: SchemaNode | undefined, type: T): SchemaNodeByType[T] | undefined {\n return node?.type === type ? (node as SchemaNodeByType[T]) : undefined\n}\n\nfunction isKind<T extends Node>(kind: NodeKind) {\n return (node: unknown): node is T => (node as Node).kind === kind\n}\n\n/**\n * Type guard for `RootNode`.\n */\nexport const isRootNode = isKind<RootNode>('Root')\n\n/**\n * Type guard for `OperationNode`.\n */\nexport const isOperationNode = isKind<OperationNode>('Operation')\n\n/**\n * Type guard for `SchemaNode`.\n */\nexport const isSchemaNode = isKind<SchemaNode>('Schema')\n\n/**\n * Type guard for `PropertyNode`.\n */\nexport const isPropertyNode = isKind<PropertyNode>('Property')\n\n/**\n * Type guard for `ParameterNode`.\n */\nexport const isParameterNode = isKind<ParameterNode>('Parameter')\n\n/**\n * Type guard for `ResponseNode`.\n */\nexport const isResponseNode = isKind<ResponseNode>('Response')\n","import type { SchemaNode, SchemaNodeByType, SchemaType } from './nodes/index.ts'\n\n/**\n * Handler context for `definePrinter` — mirrors `PluginContext` from `@kubb/core`.\n * Available as `this` inside each node handler.\n */\nexport type PrinterHandlerContext<TOutput, TOptions extends object> = {\n /**\n * Recursively print a nested `SchemaNode`.\n */\n print: (node: SchemaNode) => TOutput | null | undefined\n /**\n * Options for this printer instance.\n */\n options: TOptions\n}\n\n/**\n * Handler for a specific `SchemaNode` variant identified by `SchemaType` key `T`.\n * Use a regular function (not an arrow function) so that `this` is available.\n */\nexport type PrinterHandler<TOutput, TOptions extends object, T extends SchemaType = SchemaType> = (\n this: PrinterHandlerContext<TOutput, TOptions>,\n node: SchemaNodeByType[T],\n) => TOutput | null | undefined\n\n/**\n * Shape of the type parameter passed to `definePrinter`.\n * Mirrors `AdapterFactoryOptions` / `PluginFactoryOptions` from `@kubb/core`.\n *\n * - `TName` — unique string identifier (e.g. `'zod'`, `'ts'`)\n * - `TOptions` — options passed to and stored on the printer\n * - `TOutput` — the type emitted by `print` (typically `string`)\n */\nexport type PrinterFactoryOptions<TName extends string = string, TOptions extends object = object, TOutput = unknown> = {\n name: TName\n options: TOptions\n output: TOutput\n}\n\n/**\n * The object returned by calling a `definePrinter` instance.\n * Mirrors the shape of `Adapter` from `@kubb/core`.\n */\nexport type Printer<T extends PrinterFactoryOptions = PrinterFactoryOptions> = {\n /**\n * Unique identifier supplied at creation time.\n */\n name: T['name']\n /**\n * Options for this printer instance.\n */\n options: T['options']\n /**\n * Emits `TOutput` from a `SchemaNode`. Returns `null | undefined` when no handler matches.\n */\n print: (node: SchemaNode) => T['output'] | null | undefined\n /**\n * Maps `print` over an array of `SchemaNode`s.\n */\n for: (nodes: Array<SchemaNode>) => Array<T['output'] | null | undefined>\n}\n\ntype PrinterBuilder<T extends PrinterFactoryOptions> = (options: T['options']) => {\n name: T['name']\n /**\n * Options to store on the printer.\n */\n options: T['options']\n nodes: Partial<{\n [K in SchemaType]: PrinterHandler<T['output'], T['options'], K>\n }>\n}\n\n/**\n * Creates a named printer factory. Mirrors the `definePlugin` / `defineAdapter` pattern\n * from `@kubb/core` — wraps a builder to make options optional and separates raw options\n * from resolved options.\n *\n * @example\n * ```ts\n * type ZodPrinter = PrinterFactoryOptions<'zod', { strict?: boolean }, { strict: boolean }, string>\n *\n * export const zodPrinter = definePrinter<ZodPrinter>((options) => {\n * const { strict = true } = options\n * return {\n * name: 'zod',\n * options: { strict },\n * nodes: {\n * string(node) {\n * return `z.string()`\n * },\n * object(node) {\n * const props = node.properties\n * ?.map(p => `${p.name}: ${this.print(p)}`)\n * .join(', ') ?? ''\n * return `z.object({ ${props} })`\n * },\n * },\n * }\n * })\n *\n * const printer = zodPrinter({ strict: false })\n * printer.name // 'zod'\n * printer.options // { strict: false }\n * printer.print(node) // 'z.string()'\n * ```\n */\nexport function definePrinter<T extends PrinterFactoryOptions = PrinterFactoryOptions>(build: PrinterBuilder<T>): (options?: T['options']) => Printer<T> {\n return (options) => {\n const { name, options: resolvedOptions, nodes } = build(options ?? ({} as T['options']))\n\n function print(node: SchemaNode): T['output'] | null | undefined {\n const type = node.type as SchemaType\n\n const handler = nodes[type]\n if (handler) {\n const context: PrinterHandlerContext<T['output'], T['options']> = { print, options: resolvedOptions }\n return (handler as PrinterHandler<T['output'], T['options']>).call(context, node as SchemaNodeByType[SchemaType])\n }\n\n return undefined\n }\n\n return { name, options: resolvedOptions, print, for: (nodes) => nodes.map(print) }\n }\n}\n","import type { RootNode } from './nodes/root.ts'\nimport type { SchemaNode } from './nodes/schema.ts'\n\n/**\n * Schema name to `SchemaNode` mapping.\n */\nexport type RefMap = Map<string, SchemaNode>\n\n/**\n * Indexes named schemas from `root.schemas` by name. Unnamed schemas are skipped.\n */\nexport function buildRefMap(root: RootNode): RefMap {\n const map: RefMap = new Map()\n\n for (const schema of root.schemas) {\n if (schema.name) {\n map.set(schema.name, schema)\n }\n }\n return map\n}\n\n/**\n * Looks up a schema by name. Prefer over `RefMap.get()` to keep the resolution strategy swappable.\n */\nexport function resolveRef(refMap: RefMap, ref: string): SchemaNode | undefined {\n return refMap.get(ref)\n}\n\n/**\n * Converts a `RefMap` to a plain object.\n */\nexport function refMapToObject(refMap: RefMap): Record<string, SchemaNode> {\n return Object.fromEntries(refMap)\n}\n","import type { VisitorDepth } from './constants.ts'\nimport { visitorDepths, WALK_CONCURRENCY } from './constants.ts'\nimport type { Node, OperationNode, ParameterNode, PropertyNode, ResponseNode, RootNode, SchemaNode } from './nodes/index.ts'\n\nfunction createLimit(concurrency: number) {\n let active = 0\n const queue: Array<() => void> = []\n\n function next() {\n if (active < concurrency && queue.length > 0) {\n active++\n queue.shift()!()\n }\n }\n\n return function limit<T>(fn: () => Promise<T> | T): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n queue.push(() => {\n Promise.resolve(fn())\n .then(resolve, reject)\n .finally(() => {\n active--\n next()\n })\n })\n next()\n })\n }\n}\n\ntype LimitFn = ReturnType<typeof createLimit>\n\n/**\n * Shared options for `walk`, `transform`, and `collect`.\n */\nexport type VisitorOptions = {\n depth?: VisitorDepth\n /**\n * Maximum number of sibling nodes visited concurrently inside `walk`.\n * @default 30\n */\n concurrency?: number\n}\n\n/**\n * Synchronous visitor for `transform` and `walk`.\n */\nexport type Visitor = {\n root?(node: RootNode): void | RootNode\n operation?(node: OperationNode): void | OperationNode\n schema?(node: SchemaNode): void | SchemaNode\n property?(node: PropertyNode): void | PropertyNode\n parameter?(node: ParameterNode): void | ParameterNode\n response?(node: ResponseNode): void | ResponseNode\n}\n\ntype MaybePromise<T> = T | Promise<T>\n\n/**\n * Async visitor for `walk`. Synchronous `Visitor` objects are compatible.\n */\nexport type AsyncVisitor = {\n root?(node: RootNode): MaybePromise<void | RootNode>\n operation?(node: OperationNode): MaybePromise<void | OperationNode>\n schema?(node: SchemaNode): MaybePromise<void | SchemaNode>\n property?(node: PropertyNode): MaybePromise<void | PropertyNode>\n parameter?(node: ParameterNode): MaybePromise<void | ParameterNode>\n response?(node: ResponseNode): MaybePromise<void | ResponseNode>\n}\n\n/**\n * Visitor for `collect`.\n */\nexport type CollectVisitor<T> = {\n root?(node: RootNode): T | undefined\n operation?(node: OperationNode): T | undefined\n schema?(node: SchemaNode): T | undefined\n property?(node: PropertyNode): T | undefined\n parameter?(node: ParameterNode): T | undefined\n response?(node: ResponseNode): T | undefined\n}\n\n/**\n * Traversable children of `node`, respecting `recurse` for schema nodes.\n */\nfunction getChildren(node: Node, recurse: boolean): Array<Node> {\n switch (node.kind) {\n case 'Root':\n return [...node.schemas, ...node.operations]\n case 'Operation':\n return [...node.parameters, ...(node.requestBody ? [node.requestBody] : []), ...node.responses]\n case 'Schema': {\n const children: Array<Node> = []\n\n if (!recurse) return []\n\n if ('properties' in node && node.properties) children.push(...node.properties)\n if ('items' in node && node.items) children.push(...node.items)\n if ('members' in node && node.members) children.push(...node.members)\n\n return children\n }\n case 'Property':\n return [node.schema]\n case 'Parameter':\n return [node.schema]\n case 'Response':\n return node.schema ? [node.schema] : []\n }\n}\n\n/**\n * Depth-first traversal for side effects. Visitor return values are ignored.\n * Sibling nodes at each level are visited concurrently up to `options.concurrency` (default: 30).\n */\nexport async function walk(node: Node, visitor: AsyncVisitor, options: VisitorOptions = {}): Promise<void> {\n const recurse = (options.depth ?? visitorDepths.deep) === visitorDepths.deep\n const limit = createLimit(options.concurrency ?? WALK_CONCURRENCY)\n return _walk(node, visitor, recurse, limit)\n}\n\nasync function _walk(node: Node, visitor: AsyncVisitor, recurse: boolean, limit: LimitFn): Promise<void> {\n switch (node.kind) {\n case 'Root':\n await limit(() => visitor.root?.(node))\n break\n case 'Operation':\n await limit(() => visitor.operation?.(node))\n break\n case 'Schema':\n await limit(() => visitor.schema?.(node))\n break\n case 'Property':\n await limit(() => visitor.property?.(node))\n break\n case 'Parameter':\n await limit(() => visitor.parameter?.(node))\n break\n case 'Response':\n await limit(() => visitor.response?.(node))\n break\n }\n\n const children = getChildren(node, recurse)\n await Promise.all(children.map((child) => _walk(child, visitor, recurse, limit)))\n}\n\n/**\n * Depth-first immutable transformation. Visitor return values replace nodes; `undefined` keeps the original.\n */\nexport function transform(node: RootNode, visitor: Visitor, options?: VisitorOptions): RootNode\nexport function transform(node: OperationNode, visitor: Visitor, options?: VisitorOptions): OperationNode\nexport function transform(node: SchemaNode, visitor: Visitor, options?: VisitorOptions): SchemaNode\nexport function transform(node: PropertyNode, visitor: Visitor, options?: VisitorOptions): PropertyNode\nexport function transform(node: ParameterNode, visitor: Visitor, options?: VisitorOptions): ParameterNode\nexport function transform(node: ResponseNode, visitor: Visitor, options?: VisitorOptions): ResponseNode\nexport function transform(node: Node, visitor: Visitor, options?: VisitorOptions): Node\nexport function transform(node: Node, visitor: Visitor, options: VisitorOptions = {}): Node {\n const recurse = (options.depth ?? visitorDepths.deep) === visitorDepths.deep\n\n switch (node.kind) {\n case 'Root': {\n let root = node\n const replaced = visitor.root?.(root)\n if (replaced) root = replaced\n\n return {\n ...root,\n schemas: root.schemas.map((s) => transform(s, visitor, options)),\n operations: root.operations.map((op) => transform(op, visitor, options)),\n }\n }\n case 'Operation': {\n let op = node\n const replaced = visitor.operation?.(op)\n if (replaced) op = replaced\n\n return {\n ...op,\n parameters: op.parameters.map((p) => transform(p, visitor, options)),\n requestBody: op.requestBody ? transform(op.requestBody, visitor, options) : undefined,\n responses: op.responses.map((r) => transform(r, visitor, options)),\n }\n }\n case 'Schema': {\n let schema = node\n const replaced = visitor.schema?.(schema)\n if (replaced) schema = replaced\n\n return {\n ...schema,\n ...('properties' in schema && recurse ? { properties: schema.properties?.map((p) => transform(p, visitor, options)) } : {}),\n ...('items' in schema && recurse ? { items: schema.items?.map((i) => transform(i, visitor, options)) } : {}),\n ...('members' in schema && recurse ? { members: schema.members?.map((m) => transform(m, visitor, options)) } : {}),\n }\n }\n case 'Property': {\n let prop = node\n const replaced = visitor.property?.(prop)\n if (replaced) prop = replaced\n\n return {\n ...prop,\n schema: transform(prop.schema, visitor, options),\n }\n }\n case 'Parameter': {\n let param = node\n const replaced = visitor.parameter?.(param)\n if (replaced) param = replaced\n\n return {\n ...param,\n schema: transform(param.schema, visitor, options),\n }\n }\n case 'Response': {\n let response = node\n const replaced = visitor.response?.(response)\n if (replaced) response = replaced\n\n return {\n ...response,\n schema: response.schema ? transform(response.schema, visitor, options) : undefined,\n }\n }\n }\n}\n\n/**\n * Depth-first synchronous reduction. Collects non-`undefined` visitor return values into an array.\n */\nexport function collect<T>(node: Node, visitor: CollectVisitor<T>, options: VisitorOptions = {}): Array<T> {\n const recurse = (options.depth ?? visitorDepths.deep) === visitorDepths.deep\n const results: Array<T> = []\n\n let v: T | undefined\n switch (node.kind) {\n case 'Root':\n v = visitor.root?.(node)\n break\n case 'Operation':\n v = visitor.operation?.(node)\n break\n case 'Schema':\n v = visitor.schema?.(node)\n break\n case 'Property':\n v = visitor.property?.(node)\n break\n case 'Parameter':\n v = visitor.parameter?.(node)\n break\n case 'Response':\n v = visitor.response?.(node)\n break\n }\n if (v !== undefined) results.push(v)\n\n for (const child of getChildren(node, recurse)) {\n for (const item of collect(child, visitor, options)) {\n results.push(item)\n }\n }\n\n return results\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/constants.ts","../src/factory.ts","../src/guards.ts","../src/printer.ts","../src/refs.ts","../src/visitor.ts"],"sourcesContent":["import type { NodeKind } from './nodes/base.ts'\nimport type { MediaType } from './nodes/http.ts'\nimport type { HttpMethod } from './nodes/operation.ts'\nimport type { ParameterLocation } from './nodes/parameter.ts'\nimport type { SchemaType } from './nodes/schema.ts'\n\n/**\n * Depth for schema traversal in visitor functions.\n */\nexport type VisitorDepth = 'shallow' | 'deep'\n\nexport const visitorDepths = {\n shallow: 'shallow',\n deep: 'deep',\n} as const satisfies Record<VisitorDepth, VisitorDepth>\n\nexport const nodeKinds = {\n root: 'Root',\n operation: 'Operation',\n schema: 'Schema',\n property: 'Property',\n parameter: 'Parameter',\n response: 'Response',\n} as const satisfies Record<Lowercase<NodeKind>, NodeKind>\n\nexport const schemaTypes = {\n string: 'string',\n /**\n * Floating-point number (`float`, `double`).\n */\n number: 'number',\n /**\n * Whole number (`int32`). Use `bigint` for `int64`.\n */\n integer: 'integer',\n /**\n * 64-bit integer (`int64`). Only used when `integerType` is set to `'bigint'`.\n */\n bigint: 'bigint',\n boolean: 'boolean',\n null: 'null',\n any: 'any',\n unknown: 'unknown',\n void: 'void',\n object: 'object',\n array: 'array',\n tuple: 'tuple',\n union: 'union',\n intersection: 'intersection',\n enum: 'enum',\n ref: 'ref',\n date: 'date',\n datetime: 'datetime',\n time: 'time',\n uuid: 'uuid',\n email: 'email',\n url: 'url',\n blob: 'blob',\n} as const satisfies Record<SchemaType, SchemaType>\n\nexport const httpMethods = {\n get: 'GET',\n post: 'POST',\n put: 'PUT',\n patch: 'PATCH',\n delete: 'DELETE',\n head: 'HEAD',\n options: 'OPTIONS',\n trace: 'TRACE',\n} as const satisfies Record<Lowercase<HttpMethod>, HttpMethod>\n\nexport const parameterLocations = {\n path: 'path',\n query: 'query',\n header: 'header',\n cookie: 'cookie',\n} as const satisfies Record<ParameterLocation, ParameterLocation>\n\n/**\n * Default max concurrent visitor calls in `walk`.\n */\nexport const WALK_CONCURRENCY = 30\n\n/**\n * Fallback status code string for API spec responses.\n */\nexport const DEFAULT_STATUS_CODE = 'default' as const\n\nexport const mediaTypes = {\n applicationJson: 'application/json',\n applicationXml: 'application/xml',\n applicationFormUrlEncoded: 'application/x-www-form-urlencoded',\n applicationOctetStream: 'application/octet-stream',\n applicationPdf: 'application/pdf',\n applicationZip: 'application/zip',\n applicationGraphql: 'application/graphql',\n multipartFormData: 'multipart/form-data',\n textPlain: 'text/plain',\n textHtml: 'text/html',\n textCsv: 'text/csv',\n textXml: 'text/xml',\n imagePng: 'image/png',\n imageJpeg: 'image/jpeg',\n imageGif: 'image/gif',\n imageWebp: 'image/webp',\n imageSvgXml: 'image/svg+xml',\n audioMpeg: 'audio/mpeg',\n videoMp4: 'video/mp4',\n} as const satisfies Record<string, MediaType>\n","import type { ObjectSchemaNode, OperationNode, ParameterNode, PropertyNode, ResponseNode, RootNode, SchemaNode } from './nodes/index.ts'\n\n/**\n * Distributive variant of `Omit` that preserves union members.\n */\nexport type DistributiveOmit<T, K extends PropertyKey> = T extends unknown ? Omit<T, K> : never\n\n/**\n * Creates a `RootNode`.\n */\nexport function createRoot(overrides: Partial<Omit<RootNode, 'kind'>> = {}): RootNode {\n return {\n schemas: [],\n operations: [],\n ...overrides,\n kind: 'Root',\n }\n}\n\n/**\n * Creates an `OperationNode`.\n */\nexport function createOperation(\n props: Pick<OperationNode, 'operationId' | 'method' | 'path'> & Partial<Omit<OperationNode, 'kind' | 'operationId' | 'method' | 'path'>>,\n): OperationNode {\n return {\n tags: [],\n parameters: [],\n responses: [],\n ...props,\n kind: 'Operation',\n }\n}\n\n/**\n * Creates a `SchemaNode`, narrowed to the variant of `props.type`.\n * For object schemas, `properties` defaults to `[]` when not provided.\n */\nexport function createSchema<T extends Omit<ObjectSchemaNode, 'kind' | 'properties'> & { properties?: Array<PropertyNode> }>(\n props: T,\n): Omit<T, 'properties'> & { properties: Array<PropertyNode>; kind: 'Schema' }\nexport function createSchema<T extends DistributiveOmit<Exclude<SchemaNode, ObjectSchemaNode>, 'kind'>>(props: T): T & { kind: 'Schema' }\nexport function createSchema(props: DistributiveOmit<SchemaNode, 'kind'>): SchemaNode\nexport function createSchema(props: Record<string, unknown>): Record<string, unknown> {\n if (props['type'] === 'object') {\n return { properties: [], ...props, kind: 'Schema' }\n }\n\n return { ...props, kind: 'Schema' }\n}\n\n/**\n * Creates a `PropertyNode`. `required` defaults to `false`.\n */\nexport function createProperty(props: Pick<PropertyNode, 'name' | 'schema'> & Partial<Omit<PropertyNode, 'kind' | 'name' | 'schema'>>): PropertyNode {\n return {\n required: false,\n ...props,\n kind: 'Property',\n }\n}\n\n/**\n * Creates a `ParameterNode`. `required` defaults to `false`.\n */\nexport function createParameter(\n props: Pick<ParameterNode, 'name' | 'in' | 'schema'> & Partial<Omit<ParameterNode, 'kind' | 'name' | 'in' | 'schema'>>,\n): ParameterNode {\n return {\n required: false,\n ...props,\n kind: 'Parameter',\n }\n}\n\n/**\n * Creates a `ResponseNode`.\n */\nexport function createResponse(props: Pick<ResponseNode, 'statusCode'> & Partial<Omit<ResponseNode, 'kind' | 'statusCode'>>): ResponseNode {\n return {\n ...props,\n kind: 'Response',\n }\n}\n","import type { Node, NodeKind, OperationNode, ParameterNode, PropertyNode, ResponseNode, RootNode, SchemaNode, SchemaNodeByType } from './nodes/index.ts'\n\n/**\n * Narrows a `SchemaNode` to the specific variant matching `type`.\n */\nexport function narrowSchema<T extends SchemaNode['type']>(node: SchemaNode | undefined, type: T): SchemaNodeByType[T] | undefined {\n return node?.type === type ? (node as SchemaNodeByType[T]) : undefined\n}\n\nfunction isKind<T extends Node>(kind: NodeKind) {\n return (node: unknown): node is T => (node as Node).kind === kind\n}\n\n/**\n * Type guard for `RootNode`.\n */\nexport const isRootNode = isKind<RootNode>('Root')\n\n/**\n * Type guard for `OperationNode`.\n */\nexport const isOperationNode = isKind<OperationNode>('Operation')\n\n/**\n * Type guard for `SchemaNode`.\n */\nexport const isSchemaNode = isKind<SchemaNode>('Schema')\n\n/**\n * Type guard for `PropertyNode`.\n */\nexport const isPropertyNode = isKind<PropertyNode>('Property')\n\n/**\n * Type guard for `ParameterNode`.\n */\nexport const isParameterNode = isKind<ParameterNode>('Parameter')\n\n/**\n * Type guard for `ResponseNode`.\n */\nexport const isResponseNode = isKind<ResponseNode>('Response')\n","import type { SchemaNode, SchemaNodeByType, SchemaType } from './nodes/index.ts'\n\n/**\n * Handler context for `definePrinter` — mirrors `PluginContext` from `@kubb/core`.\n * Available as `this` inside each node handler.\n */\nexport type PrinterHandlerContext<TOutput, TOptions extends object> = {\n /**\n * Recursively print a nested `SchemaNode`.\n */\n print: (node: SchemaNode) => TOutput | null | undefined\n /**\n * Options for this printer instance.\n */\n options: TOptions\n}\n\n/**\n * Handler for a specific `SchemaNode` variant identified by `SchemaType` key `T`.\n * Use a regular function (not an arrow function) so that `this` is available.\n */\nexport type PrinterHandler<TOutput, TOptions extends object, T extends SchemaType = SchemaType> = (\n this: PrinterHandlerContext<TOutput, TOptions>,\n node: SchemaNodeByType[T],\n) => TOutput | null | undefined\n\n/**\n * Shape of the type parameter passed to `definePrinter`.\n * Mirrors `AdapterFactoryOptions` / `PluginFactoryOptions` from `@kubb/core`.\n *\n * - `TName` — unique string identifier (e.g. `'zod'`, `'ts'`)\n * - `TOptions` — options passed to and stored on the printer\n * - `TOutput` — the type emitted by `print` (typically `string`)\n */\nexport type PrinterFactoryOptions<TName extends string = string, TOptions extends object = object, TOutput = unknown> = {\n name: TName\n options: TOptions\n output: TOutput\n}\n\n/**\n * The object returned by calling a `definePrinter` instance.\n * Mirrors the shape of `Adapter` from `@kubb/core`.\n */\nexport type Printer<T extends PrinterFactoryOptions = PrinterFactoryOptions> = {\n /**\n * Unique identifier supplied at creation time.\n */\n name: T['name']\n /**\n * Options for this printer instance.\n */\n options: T['options']\n /**\n * Emits `TOutput` from a `SchemaNode`. Returns `null | undefined` when no handler matches.\n */\n print: (node: SchemaNode) => T['output'] | null | undefined\n /**\n * Maps `print` over an array of `SchemaNode`s.\n */\n for: (nodes: Array<SchemaNode>) => Array<T['output'] | null | undefined>\n}\n\ntype PrinterBuilder<T extends PrinterFactoryOptions> = (options: T['options']) => {\n name: T['name']\n /**\n * Options to store on the printer.\n */\n options: T['options']\n nodes: Partial<{\n [K in SchemaType]: PrinterHandler<T['output'], T['options'], K>\n }>\n}\n\n/**\n * Creates a named printer factory. Mirrors the `definePlugin` / `defineAdapter` pattern\n * from `@kubb/core` — wraps a builder to make options optional and separates raw options\n * from resolved options.\n *\n * @example\n * ```ts\n * type ZodPrinter = PrinterFactoryOptions<'zod', { strict?: boolean }, { strict: boolean }, string>\n *\n * export const zodPrinter = definePrinter<ZodPrinter>((options) => {\n * const { strict = true } = options\n * return {\n * name: 'zod',\n * options: { strict },\n * nodes: {\n * string(node) {\n * return `z.string()`\n * },\n * object(node) {\n * const props = node.properties\n * ?.map(p => `${p.name}: ${this.print(p)}`)\n * .join(', ') ?? ''\n * return `z.object({ ${props} })`\n * },\n * },\n * }\n * })\n *\n * const printer = zodPrinter({ strict: false })\n * printer.name // 'zod'\n * printer.options // { strict: false }\n * printer.print(node) // 'z.string()'\n * ```\n */\nexport function definePrinter<T extends PrinterFactoryOptions = PrinterFactoryOptions>(build: PrinterBuilder<T>): (options?: T['options']) => Printer<T> {\n return (options) => {\n const { name, options: resolvedOptions, nodes } = build(options ?? ({} as T['options']))\n\n const context: PrinterHandlerContext<T['output'], T['options']> = {\n options: resolvedOptions,\n print: (node: SchemaNode) => {\n const type = node.type as SchemaType\n const handler = nodes[type]\n return handler ? (handler as PrinterHandler<T['output'], T['options']>).call(context, node as SchemaNodeByType[SchemaType]) : undefined\n },\n }\n\n return {\n name,\n options: resolvedOptions,\n print: context.print,\n for: (nodes) => nodes.map(context.print),\n }\n }\n}\n","import type { RootNode } from './nodes/root.ts'\nimport type { SchemaNode } from './nodes/schema.ts'\n\n/**\n * Schema name to `SchemaNode` mapping.\n */\nexport type RefMap = Map<string, SchemaNode>\n\n/**\n * Indexes named schemas from `root.schemas` by name. Unnamed schemas are skipped.\n */\nexport function buildRefMap(root: RootNode): RefMap {\n const map: RefMap = new Map()\n\n for (const schema of root.schemas) {\n if (schema.name) {\n map.set(schema.name, schema)\n }\n }\n return map\n}\n\n/**\n * Looks up a schema by name. Prefer over `RefMap.get()` to keep the resolution strategy swappable.\n */\nexport function resolveRef(refMap: RefMap, ref: string): SchemaNode | undefined {\n return refMap.get(ref)\n}\n\n/**\n * Converts a `RefMap` to a plain object.\n */\nexport function refMapToObject(refMap: RefMap): Record<string, SchemaNode> {\n return Object.fromEntries(refMap)\n}\n","import type { VisitorDepth } from './constants.ts'\nimport { visitorDepths, WALK_CONCURRENCY } from './constants.ts'\nimport type { Node, OperationNode, ParameterNode, PropertyNode, ResponseNode, RootNode, SchemaNode } from './nodes/index.ts'\n\nfunction createLimit(concurrency: number) {\n let active = 0\n const queue: Array<() => void> = []\n\n function next() {\n if (active < concurrency && queue.length > 0) {\n active++\n queue.shift()!()\n }\n }\n\n return function limit<T>(fn: () => Promise<T> | T): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n queue.push(() => {\n Promise.resolve(fn())\n .then(resolve, reject)\n .finally(() => {\n active--\n next()\n })\n })\n next()\n })\n }\n}\n\ntype LimitFn = ReturnType<typeof createLimit>\n\n/**\n * Shared options for `walk`, `transform`, and `collect`.\n */\nexport type VisitorOptions = {\n depth?: VisitorDepth\n /**\n * Maximum number of sibling nodes visited concurrently inside `walk`.\n * @default 30\n */\n concurrency?: number\n}\n\n/**\n * Synchronous visitor for `transform` and `walk`.\n */\nexport type Visitor = {\n root?(node: RootNode): void | RootNode\n operation?(node: OperationNode): void | OperationNode\n schema?(node: SchemaNode): void | SchemaNode\n property?(node: PropertyNode): void | PropertyNode\n parameter?(node: ParameterNode): void | ParameterNode\n response?(node: ResponseNode): void | ResponseNode\n}\n\ntype MaybePromise<T> = T | Promise<T>\n\n/**\n * Async visitor for `walk`. Synchronous `Visitor` objects are compatible.\n */\nexport type AsyncVisitor = {\n root?(node: RootNode): MaybePromise<void | RootNode>\n operation?(node: OperationNode): MaybePromise<void | OperationNode>\n schema?(node: SchemaNode): MaybePromise<void | SchemaNode>\n property?(node: PropertyNode): MaybePromise<void | PropertyNode>\n parameter?(node: ParameterNode): MaybePromise<void | ParameterNode>\n response?(node: ResponseNode): MaybePromise<void | ResponseNode>\n}\n\n/**\n * Visitor for `collect`.\n */\nexport type CollectVisitor<T> = {\n root?(node: RootNode): T | undefined\n operation?(node: OperationNode): T | undefined\n schema?(node: SchemaNode): T | undefined\n property?(node: PropertyNode): T | undefined\n parameter?(node: ParameterNode): T | undefined\n response?(node: ResponseNode): T | undefined\n}\n\n/**\n * Traversable children of `node`, respecting `recurse` for schema nodes.\n */\nfunction getChildren(node: Node, recurse: boolean): Array<Node> {\n switch (node.kind) {\n case 'Root':\n return [...node.schemas, ...node.operations]\n case 'Operation':\n return [...node.parameters, ...(node.requestBody ? [node.requestBody] : []), ...node.responses]\n case 'Schema': {\n const children: Array<Node> = []\n\n if (!recurse) return []\n\n if ('properties' in node && node.properties.length > 0) children.push(...node.properties)\n if ('items' in node && node.items) children.push(...node.items)\n if ('members' in node && node.members) children.push(...node.members)\n\n return children\n }\n case 'Property':\n return [node.schema]\n case 'Parameter':\n return [node.schema]\n case 'Response':\n return node.schema ? [node.schema] : []\n }\n}\n\n/**\n * Depth-first traversal for side effects. Visitor return values are ignored.\n * Sibling nodes at each level are visited concurrently up to `options.concurrency` (default: 30).\n */\nexport async function walk(node: Node, visitor: AsyncVisitor, options: VisitorOptions = {}): Promise<void> {\n const recurse = (options.depth ?? visitorDepths.deep) === visitorDepths.deep\n const limit = createLimit(options.concurrency ?? WALK_CONCURRENCY)\n return _walk(node, visitor, recurse, limit)\n}\n\nasync function _walk(node: Node, visitor: AsyncVisitor, recurse: boolean, limit: LimitFn): Promise<void> {\n switch (node.kind) {\n case 'Root':\n await limit(() => visitor.root?.(node))\n break\n case 'Operation':\n await limit(() => visitor.operation?.(node))\n break\n case 'Schema':\n await limit(() => visitor.schema?.(node))\n break\n case 'Property':\n await limit(() => visitor.property?.(node))\n break\n case 'Parameter':\n await limit(() => visitor.parameter?.(node))\n break\n case 'Response':\n await limit(() => visitor.response?.(node))\n break\n }\n\n const children = getChildren(node, recurse)\n await Promise.all(children.map((child) => _walk(child, visitor, recurse, limit)))\n}\n\n/**\n * Depth-first immutable transformation. Visitor return values replace nodes; `undefined` keeps the original.\n */\nexport function transform(node: RootNode, visitor: Visitor, options?: VisitorOptions): RootNode\nexport function transform(node: OperationNode, visitor: Visitor, options?: VisitorOptions): OperationNode\nexport function transform(node: SchemaNode, visitor: Visitor, options?: VisitorOptions): SchemaNode\nexport function transform(node: PropertyNode, visitor: Visitor, options?: VisitorOptions): PropertyNode\nexport function transform(node: ParameterNode, visitor: Visitor, options?: VisitorOptions): ParameterNode\nexport function transform(node: ResponseNode, visitor: Visitor, options?: VisitorOptions): ResponseNode\nexport function transform(node: Node, visitor: Visitor, options?: VisitorOptions): Node\nexport function transform(node: Node, visitor: Visitor, options: VisitorOptions = {}): Node {\n const recurse = (options.depth ?? visitorDepths.deep) === visitorDepths.deep\n\n switch (node.kind) {\n case 'Root': {\n let root = node\n const replaced = visitor.root?.(root)\n if (replaced) root = replaced\n\n return {\n ...root,\n schemas: root.schemas.map((s) => transform(s, visitor, options)),\n operations: root.operations.map((op) => transform(op, visitor, options)),\n }\n }\n case 'Operation': {\n let op = node\n const replaced = visitor.operation?.(op)\n if (replaced) op = replaced\n\n return {\n ...op,\n parameters: op.parameters.map((p) => transform(p, visitor, options)),\n requestBody: op.requestBody ? transform(op.requestBody, visitor, options) : undefined,\n responses: op.responses.map((r) => transform(r, visitor, options)),\n }\n }\n case 'Schema': {\n let schema = node\n const replaced = visitor.schema?.(schema)\n if (replaced) schema = replaced\n\n return {\n ...schema,\n ...('properties' in schema && recurse ? { properties: schema.properties.map((p) => transform(p, visitor, options)) } : {}),\n ...('items' in schema && recurse ? { items: schema.items?.map((i) => transform(i, visitor, options)) } : {}),\n ...('members' in schema && recurse ? { members: schema.members?.map((m) => transform(m, visitor, options)) } : {}),\n }\n }\n case 'Property': {\n let prop = node\n const replaced = visitor.property?.(prop)\n if (replaced) prop = replaced\n\n return {\n ...prop,\n schema: transform(prop.schema, visitor, options),\n }\n }\n case 'Parameter': {\n let param = node\n const replaced = visitor.parameter?.(param)\n if (replaced) param = replaced\n\n return {\n ...param,\n schema: transform(param.schema, visitor, options),\n }\n }\n case 'Response': {\n let response = node\n const replaced = visitor.response?.(response)\n if (replaced) response = replaced\n\n return {\n ...response,\n schema: response.schema ? transform(response.schema, visitor, options) : undefined,\n }\n }\n }\n}\n\n/**\n * Depth-first synchronous reduction. Collects non-`undefined` visitor return values into an array.\n */\nexport function collect<T>(node: Node, visitor: CollectVisitor<T>, options: VisitorOptions = {}): Array<T> {\n const recurse = (options.depth ?? visitorDepths.deep) === visitorDepths.deep\n const results: Array<T> = []\n\n let v: T | undefined\n switch (node.kind) {\n case 'Root':\n v = visitor.root?.(node)\n break\n case 'Operation':\n v = visitor.operation?.(node)\n break\n case 'Schema':\n v = visitor.schema?.(node)\n break\n case 'Property':\n v = visitor.property?.(node)\n break\n case 'Parameter':\n v = visitor.parameter?.(node)\n break\n case 'Response':\n v = visitor.response?.(node)\n break\n }\n if (v !== undefined) results.push(v)\n\n for (const child of getChildren(node, recurse)) {\n for (const item of collect(child, visitor, options)) {\n results.push(item)\n }\n }\n\n return results\n}\n"],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { $ as
|
|
2
|
-
export { type ArraySchemaNode, type AsyncVisitor, type BaseNode, type CollectVisitor, type ComplexSchemaType, type DateSchemaNode, type DatetimeSchemaNode, type DistributiveOmit, type EnumSchemaNode, type EnumValueNode, type HttpMethod, type HttpStatusCode, type IntersectionSchemaNode, type MediaType, type Node, type NodeKind, type NumberSchemaNode, type ObjectSchemaNode, type OperationNode, type ParameterLocation, type ParameterNode, type PrimitiveSchemaType, type Printer, type PropertyNode, type RefMap, type RefSchemaNode, type ResponseNode, type RootMeta, type RootNode, type ScalarSchemaNode, type ScalarSchemaType, type SchemaNode, type SchemaNodeByType, type SchemaType, type SpecialSchemaType, type StatusCode, type StringSchemaNode, type TimeSchemaNode, type UnionSchemaNode, type Visitor, type VisitorDepth };
|
|
1
|
+
import { $ as UnionSchemaNode, A as MediaType, B as IntersectionSchemaNode, C as Node, D as OperationNode, E as HttpMethod, F as ComplexSchemaType, G as ScalarSchemaNode, H as ObjectSchemaNode, I as DateSchemaNode, J as SchemaNodeByType, K as ScalarSchemaType, L as DatetimeSchemaNode, M as ParameterLocation, N as ParameterNode, O as ResponseNode, P as ArraySchemaNode, Q as TimeSchemaNode, R as EnumSchemaNode, T as RootNode, U as PrimitiveSchemaType, V as NumberSchemaNode, W as RefSchemaNode, X as SpecialSchemaType, Y as SchemaType, Z as StringSchemaNode, d as Printer, et as PropertyNode, f as PrinterFactoryOptions, g as DistributiveOmit, j as StatusCode, k as HttpStatusCode, m as PrinterHandlerContext, n as CollectVisitor, nt as NodeKind, p as PrinterHandler, q as SchemaNode, r as Visitor, rt as VisitorDepth, s as RefMap, t as AsyncVisitor, tt as BaseNode, w as RootMeta, z as EnumValueNode } from "./visitor-CmsfJzro.js";
|
|
2
|
+
export { type ArraySchemaNode, type AsyncVisitor, type BaseNode, type CollectVisitor, type ComplexSchemaType, type DateSchemaNode, type DatetimeSchemaNode, type DistributiveOmit, type EnumSchemaNode, type EnumValueNode, type HttpMethod, type HttpStatusCode, type IntersectionSchemaNode, type MediaType, type Node, type NodeKind, type NumberSchemaNode, type ObjectSchemaNode, type OperationNode, type ParameterLocation, type ParameterNode, type PrimitiveSchemaType, type Printer, type PrinterFactoryOptions, type PrinterHandler, type PrinterHandlerContext, type PropertyNode, type RefMap, type RefSchemaNode, type ResponseNode, type RootMeta, type RootNode, type ScalarSchemaNode, type ScalarSchemaType, type SchemaNode, type SchemaNodeByType, type SchemaType, type SpecialSchemaType, type StatusCode, type StringSchemaNode, type TimeSchemaNode, type UnionSchemaNode, type Visitor, type VisitorDepth };
|
|
@@ -143,7 +143,7 @@ type SchemaNodeBase = BaseNode & {
|
|
|
143
143
|
*/
|
|
144
144
|
type ObjectSchemaNode = SchemaNodeBase & {
|
|
145
145
|
type: 'object';
|
|
146
|
-
properties
|
|
146
|
+
properties: Array<PropertyNode>;
|
|
147
147
|
/**
|
|
148
148
|
* `true` allows any value; a `SchemaNode` constrains it; absent means not permitted.
|
|
149
149
|
*/
|
|
@@ -437,10 +437,18 @@ declare function createRoot(overrides?: Partial<Omit<RootNode, 'kind'>>): RootNo
|
|
|
437
437
|
declare function createOperation(props: Pick<OperationNode, 'operationId' | 'method' | 'path'> & Partial<Omit<OperationNode, 'kind' | 'operationId' | 'method' | 'path'>>): OperationNode;
|
|
438
438
|
/**
|
|
439
439
|
* Creates a `SchemaNode`, narrowed to the variant of `props.type`.
|
|
440
|
+
* For object schemas, `properties` defaults to `[]` when not provided.
|
|
440
441
|
*/
|
|
441
|
-
declare function createSchema<T extends
|
|
442
|
+
declare function createSchema<T extends Omit<ObjectSchemaNode, 'kind' | 'properties'> & {
|
|
443
|
+
properties?: Array<PropertyNode>;
|
|
444
|
+
}>(props: T): Omit<T, 'properties'> & {
|
|
445
|
+
properties: Array<PropertyNode>;
|
|
446
|
+
kind: 'Schema';
|
|
447
|
+
};
|
|
448
|
+
declare function createSchema<T extends DistributiveOmit<Exclude<SchemaNode, ObjectSchemaNode>, 'kind'>>(props: T): T & {
|
|
442
449
|
kind: 'Schema';
|
|
443
450
|
};
|
|
451
|
+
declare function createSchema(props: DistributiveOmit<SchemaNode, 'kind'>): SchemaNode;
|
|
444
452
|
/**
|
|
445
453
|
* Creates a `PropertyNode`. `required` defaults to `false`.
|
|
446
454
|
*/
|
|
@@ -637,5 +645,5 @@ declare function transform(node: Node, visitor: Visitor, options?: VisitorOption
|
|
|
637
645
|
*/
|
|
638
646
|
declare function collect<T>(node: Node, visitor: CollectVisitor<T>, options?: VisitorOptions): Array<T>;
|
|
639
647
|
//#endregion
|
|
640
|
-
export {
|
|
641
|
-
//# sourceMappingURL=visitor-
|
|
648
|
+
export { UnionSchemaNode as $, MediaType as A, IntersectionSchemaNode as B, Node as C, OperationNode as D, HttpMethod as E, ComplexSchemaType as F, ScalarSchemaNode as G, ObjectSchemaNode as H, DateSchemaNode as I, SchemaNodeByType as J, ScalarSchemaType as K, DatetimeSchemaNode as L, ParameterLocation as M, ParameterNode as N, ResponseNode as O, ArraySchemaNode as P, TimeSchemaNode as Q, EnumSchemaNode as R, createSchema as S, RootNode as T, PrimitiveSchemaType as U, NumberSchemaNode as V, RefSchemaNode as W, SpecialSchemaType as X, SchemaType as Y, StringSchemaNode as Z, createOperation as _, transform as a, mediaTypes as at, createResponse as b, buildRefMap as c, Printer as d, PropertyNode as et, PrinterFactoryOptions as f, DistributiveOmit as g, definePrinter as h, collect as i, httpMethods as it, StatusCode as j, HttpStatusCode as k, refMapToObject as l, PrinterHandlerContext as m, CollectVisitor as n, NodeKind as nt, walk as o, nodeKinds as ot, PrinterHandler as p, SchemaNode as q, Visitor as r, VisitorDepth as rt, RefMap as s, schemaTypes as st, AsyncVisitor as t, BaseNode as tt, resolveRef as u, createParameter as v, RootMeta as w, createRoot as x, createProperty as y, EnumValueNode as z };
|
|
649
|
+
//# sourceMappingURL=visitor-CmsfJzro.d.ts.map
|
package/package.json
CHANGED
package/src/factory.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { OperationNode, ParameterNode, PropertyNode, ResponseNode, RootNode, SchemaNode } from './nodes/index.ts'
|
|
1
|
+
import type { ObjectSchemaNode, OperationNode, ParameterNode, PropertyNode, ResponseNode, RootNode, SchemaNode } from './nodes/index.ts'
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Distributive variant of `Omit` that preserves union members.
|
|
@@ -34,9 +34,19 @@ export function createOperation(
|
|
|
34
34
|
|
|
35
35
|
/**
|
|
36
36
|
* Creates a `SchemaNode`, narrowed to the variant of `props.type`.
|
|
37
|
+
* For object schemas, `properties` defaults to `[]` when not provided.
|
|
37
38
|
*/
|
|
38
|
-
export function createSchema<T extends
|
|
39
|
-
|
|
39
|
+
export function createSchema<T extends Omit<ObjectSchemaNode, 'kind' | 'properties'> & { properties?: Array<PropertyNode> }>(
|
|
40
|
+
props: T,
|
|
41
|
+
): Omit<T, 'properties'> & { properties: Array<PropertyNode>; kind: 'Schema' }
|
|
42
|
+
export function createSchema<T extends DistributiveOmit<Exclude<SchemaNode, ObjectSchemaNode>, 'kind'>>(props: T): T & { kind: 'Schema' }
|
|
43
|
+
export function createSchema(props: DistributiveOmit<SchemaNode, 'kind'>): SchemaNode
|
|
44
|
+
export function createSchema(props: Record<string, unknown>): Record<string, unknown> {
|
|
45
|
+
if (props['type'] === 'object') {
|
|
46
|
+
return { properties: [], ...props, kind: 'Schema' }
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return { ...props, kind: 'Schema' }
|
|
40
50
|
}
|
|
41
51
|
|
|
42
52
|
/**
|
package/src/nodes/schema.ts
CHANGED
|
@@ -50,7 +50,7 @@ type SchemaNodeBase = BaseNode & {
|
|
|
50
50
|
*/
|
|
51
51
|
export type ObjectSchemaNode = SchemaNodeBase & {
|
|
52
52
|
type: 'object'
|
|
53
|
-
properties
|
|
53
|
+
properties: Array<PropertyNode>
|
|
54
54
|
/**
|
|
55
55
|
* `true` allows any value; a `SchemaNode` constrains it; absent means not permitted.
|
|
56
56
|
*/
|
package/src/printer.ts
CHANGED
|
@@ -110,18 +110,20 @@ export function definePrinter<T extends PrinterFactoryOptions = PrinterFactoryOp
|
|
|
110
110
|
return (options) => {
|
|
111
111
|
const { name, options: resolvedOptions, nodes } = build(options ?? ({} as T['options']))
|
|
112
112
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
return undefined
|
|
113
|
+
const context: PrinterHandlerContext<T['output'], T['options']> = {
|
|
114
|
+
options: resolvedOptions,
|
|
115
|
+
print: (node: SchemaNode) => {
|
|
116
|
+
const type = node.type as SchemaType
|
|
117
|
+
const handler = nodes[type]
|
|
118
|
+
return handler ? (handler as PrinterHandler<T['output'], T['options']>).call(context, node as SchemaNodeByType[SchemaType]) : undefined
|
|
119
|
+
},
|
|
123
120
|
}
|
|
124
121
|
|
|
125
|
-
return {
|
|
122
|
+
return {
|
|
123
|
+
name,
|
|
124
|
+
options: resolvedOptions,
|
|
125
|
+
print: context.print,
|
|
126
|
+
for: (nodes) => nodes.map(context.print),
|
|
127
|
+
}
|
|
126
128
|
}
|
|
127
129
|
}
|
package/src/types.ts
CHANGED
|
@@ -36,6 +36,6 @@ export type {
|
|
|
36
36
|
TimeSchemaNode,
|
|
37
37
|
UnionSchemaNode,
|
|
38
38
|
} from './nodes/index.ts'
|
|
39
|
-
export type { Printer } from './printer.ts'
|
|
39
|
+
export type { Printer, PrinterFactoryOptions, PrinterHandler, PrinterHandlerContext } from './printer.ts'
|
|
40
40
|
export type { RefMap } from './refs.ts'
|
|
41
41
|
export type { AsyncVisitor, CollectVisitor, Visitor } from './visitor.ts'
|
package/src/visitor.ts
CHANGED
|
@@ -94,7 +94,7 @@ function getChildren(node: Node, recurse: boolean): Array<Node> {
|
|
|
94
94
|
|
|
95
95
|
if (!recurse) return []
|
|
96
96
|
|
|
97
|
-
if ('properties' in node && node.properties) children.push(...node.properties)
|
|
97
|
+
if ('properties' in node && node.properties.length > 0) children.push(...node.properties)
|
|
98
98
|
if ('items' in node && node.items) children.push(...node.items)
|
|
99
99
|
if ('members' in node && node.members) children.push(...node.members)
|
|
100
100
|
|
|
@@ -189,7 +189,7 @@ export function transform(node: Node, visitor: Visitor, options: VisitorOptions
|
|
|
189
189
|
|
|
190
190
|
return {
|
|
191
191
|
...schema,
|
|
192
|
-
...('properties' in schema && recurse ? { properties: schema.properties
|
|
192
|
+
...('properties' in schema && recurse ? { properties: schema.properties.map((p) => transform(p, visitor, options)) } : {}),
|
|
193
193
|
...('items' in schema && recurse ? { items: schema.items?.map((i) => transform(i, visitor, options)) } : {}),
|
|
194
194
|
...('members' in schema && recurse ? { members: schema.members?.map((m) => transform(m, visitor, options)) } : {}),
|
|
195
195
|
}
|