@webpieces/api-doc-model 0.4.804 → 0.4.806
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/README.md +18 -1
- package/package.json +2 -2
- package/src/extract/ApiDocExtractor.d.ts +19 -0
- package/src/extract/ApiDocExtractor.js +37 -1
- package/src/extract/ApiDocExtractor.js.map +1 -1
- package/src/extract/JsDoc.d.ts +10 -0
- package/src/extract/JsDoc.js +18 -2
- package/src/extract/JsDoc.js.map +1 -1
- package/src/extract/TypeResolver.js +1 -1
- package/src/extract/TypeResolver.js.map +1 -1
- package/src/index.d.ts +3 -0
- package/src/index.js +7 -1
- package/src/index.js.map +1 -1
- package/src/model/ApiDocModel.d.ts +23 -1
- package/src/model/ApiDocModel.js +14 -1
- package/src/model/ApiDocModel.js.map +1 -1
- package/src/render/McpRenderError.d.ts +27 -0
- package/src/render/McpRenderError.js +36 -0
- package/src/render/McpRenderError.js.map +1 -0
- package/src/render/McpSchemaRenderer.d.ts +79 -0
- package/src/render/McpSchemaRenderer.js +235 -0
- package/src/render/McpSchemaRenderer.js.map +1 -0
- package/src/render/McpToolDefinition.d.ts +44 -0
- package/src/render/McpToolDefinition.js +44 -0
- package/src/render/McpToolDefinition.js.map +1 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TypeResolver.js","sourceRoot":"","sources":["../../../../../../packages/docs/api-doc-model/src/extract/TypeResolver.ts"],"names":[],"mappings":"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","sourcesContent":["import * as ts from 'typescript';\nimport { WpInt, WpMax, WpMin } from '@webpieces/core-util';\nimport {\n DocumentedField,\n DocumentedType,\n UnionDiscriminator,\n UnmappedType,\n} from '../model/ApiDocModel';\nimport { PrimitiveKind, TypeRef } from '../model/TypeRef';\nimport { ApiDocExtractionError } from './ApiDocExtractionError';\nimport { JsDoc } from './JsDoc';\nimport { SourceLocation } from './SourceLocation';\n\n/**\n * The decorators this resolver reads off a DTO property, named from the REAL SYMBOLS — a rename in\n * `core-util` is a compile error here rather than a literal that quietly stops matching. See\n * {@link ApiDocExtractor}'s constants for the full argument (issue #1001).\n */\nconst INT_DECORATOR = WpInt.name;\nconst MIN_DECORATOR = WpMin.name;\nconst MAX_DECORATOR = WpMax.name;\n\n/**\n * The type-alias name that DECLARES integer-ness.\n *\n * This one is a LITERAL and cannot be anything else: `Integer` is a TYPE ALIAS, so there is no\n * runtime symbol whose `.name` could be read — `.name` is a property of a function, and a type has\n * erased by then. It is the one name in this package that a rename in `core-util` would not break at\n * compile time; the cure if that ever bites is to make integer-ness a decorator here too, not to\n * pretend a type has a runtime identity. See {@link ApiDocExtractor}'s constants for the argument\n * everywhere else (issue #1001).\n */\nconst INTEGER_ALIAS = 'Integer';\n\n/**\n * Resolve declared TypeScript types into {@link TypeRef}s, registering every NAMED type it meets as\n * a {@link DocumentedType} a renderer can `$ref`.\n *\n * ## It walks TYPE NODES, not checker types, and that is load-bearing\n *\n * `type Integer = number` resolves, in the checker, to `number` — the alias is gone. Integer-ness is\n * therefore invisible to a checker-driven walk, and the whole reason `Integer` is the PREFERRED\n * spelling is that it COMPOSES: `Integer[]` and `Record<string, Integer>` say exactly which thing is\n * an integer, where a decorator on `counts?: number[]` cannot (the same ambiguity the deleted\n * `arrayItems` argument had). Walking the written syntax is what keeps that composition readable.\n *\n * ## Cycles terminate BY CONSTRUCTION\n *\n * Every named type is ONE entry in the model, registered before its fields are walked, so a type\n * that refers back to itself resolves to a `$ref` at the second visit and stops. There is NO depth\n * counter anywhere — a deep-but-finite graph of 7, 20 or 200 named hops is fully expanded, because\n * truncating one would silently publish an incomplete document. The ONLY thing that is cut is a\n * self-referential ANONYMOUS type, and it is cut by NODE IDENTITY (it has no name to `$ref`), with an\n * {@link UnmappedType} recorded so #982's guard has something to name.\n */\nexport class TypeResolver {\n private readonly types = new Map<string, DocumentedType>();\n private readonly unmapped: UnmappedType[] = [];\n /** Named types already registered (or mid-registration) — the cycle stop for the NAMED case. */\n private readonly registered = new Set<string>();\n /** Anonymous type literals currently being expanded — the cycle stop for the ANONYMOUS case. */\n private readonly expandingAnonymous = new Set<ts.TypeNode>();\n\n constructor(private readonly checker: ts.TypeChecker) {}\n\n /** Every named type reached so far, by name. */\n collectedTypes(): ReadonlyMap<string, DocumentedType> {\n return this.types;\n }\n\n /** Everything that could not be represented — recorded, never dropped. */\n collectedUnmapped(): readonly UnmappedType[] {\n return this.unmapped;\n }\n\n /** Resolve one written type, registering whatever named types it reaches. */\n resolve(node: ts.TypeNode, ownerName: string): TypeRef {\n if (ts.isParenthesizedTypeNode(node)) {\n return this.resolve(node.type, ownerName);\n }\n if (ts.isArrayTypeNode(node)) {\n return TypeRef.array(this.resolve(node.elementType, ownerName));\n }\n if (ts.isUnionTypeNode(node)) {\n return this.resolveUnion(node, ownerName);\n }\n if (ts.isTypeLiteralNode(node)) {\n return this.resolveAnonymousObject(node, ownerName);\n }\n if (ts.isLiteralTypeNode(node)) {\n return this.resolveLiteral(node);\n }\n if (ts.isTypeReferenceNode(node)) {\n return this.resolveReference(node, ownerName);\n }\n const primitive = TypeResolver.keywordOf(node.kind);\n if (primitive !== undefined) {\n return TypeRef.primitiveOf(primitive);\n }\n return this.recordUnmapped(node, 'no model representation for this type form');\n }\n\n /** `string` / `number` / `boolean` / `null` / `unknown`, or undefined for anything else. */\n // webpieces-disable no-function-outside-class -- private static lookup table of this class\n private static keywordOf(kind: ts.SyntaxKind): PrimitiveKind | undefined {\n switch (kind) {\n case ts.SyntaxKind.StringKeyword:\n return 'string';\n case ts.SyntaxKind.NumberKeyword:\n return 'number';\n case ts.SyntaxKind.BooleanKeyword:\n return 'boolean';\n case ts.SyntaxKind.NullKeyword:\n return 'null';\n case ts.SyntaxKind.UnknownKeyword:\n case ts.SyntaxKind.AnyKeyword:\n case ts.SyntaxKind.VoidKeyword:\n return 'unknown';\n default:\n return undefined;\n }\n }\n\n private resolveLiteral(node: ts.LiteralTypeNode): TypeRef {\n if (ts.isStringLiteral(node.literal)) {\n return TypeRef.enumOf([node.literal.text]);\n }\n if (node.literal.kind === ts.SyntaxKind.NullKeyword) {\n return TypeRef.primitiveOf('null');\n }\n if (\n node.literal.kind === ts.SyntaxKind.TrueKeyword ||\n node.literal.kind === ts.SyntaxKind.FalseKeyword\n ) {\n return TypeRef.primitiveOf('boolean');\n }\n if (ts.isNumericLiteral(node.literal)) {\n return TypeRef.primitiveOf('number');\n }\n return this.recordUnmapped(\n node,\n 'literal type is neither a string, a number nor a boolean',\n );\n }\n\n /**\n * A union, after `null` / `undefined` have been dropped (the FIELD records those as nullable /\n * optional — see {@link fieldOf} — because `{}` and `{x: null}` are different wire documents).\n *\n * Three outcomes, in this order:\n * - every branch a string literal -> an ENUM\n * - one branch left -> that branch\n * - every branch a named object -> a UNION, with a DERIVED discriminator when every branch\n * carries the same property typed as ONE string literal\n * - anything else -> an {@link UnmappedType}. No invented discriminator, ever:\n * a union TypeScript itself cannot narrow is not one a\n * renderer may claim to.\n */\n private resolveUnion(node: ts.UnionTypeNode, ownerName: string): TypeRef {\n const branches = node.types.filter((t: ts.TypeNode) => !TypeResolver.isNullish(t));\n\n const literals = branches.filter(\n (t: ts.TypeNode) => ts.isLiteralTypeNode(t) && ts.isStringLiteral(t.literal),\n );\n if (literals.length === branches.length && branches.length > 0) {\n return TypeRef.enumOf(\n literals.map(\n (t: ts.TypeNode) =>\n ((t as ts.LiteralTypeNode).literal as ts.StringLiteral).text,\n ),\n );\n }\n\n if (branches.length === 1) {\n return this.resolve(branches[0], ownerName);\n }\n if (branches.length === 0) {\n return TypeRef.primitiveOf('null');\n }\n\n const refs: TypeRef[] = branches.map((t: ts.TypeNode) => this.resolve(t, ownerName));\n if (!refs.every((r: TypeRef) => r.kind === 'ref')) {\n return this.recordUnmapped(\n node,\n 'a union whose branches are not all NAMED object types has no discriminator a renderer could narrow on',\n );\n }\n\n const names = refs.map((r: TypeRef) => r.refName!);\n const discriminator = this.deriveDiscriminator(names);\n if (discriminator === undefined) {\n return this.recordUnmapped(\n node,\n 'no property is typed as a single string literal on EVERY branch, so this union has no derivable discriminator',\n );\n }\n this.registerUnionAlias(node, names, discriminator);\n return TypeRef.union(names);\n }\n\n /** `null` and `undefined` branches — recorded as nullable/optional on the FIELD, not in the union. */\n // webpieces-disable no-function-outside-class -- private static predicate of this class\n private static isNullish(node: ts.TypeNode): boolean {\n if (\n node.kind === ts.SyntaxKind.UndefinedKeyword ||\n node.kind === ts.SyntaxKind.NullKeyword\n ) {\n return true;\n }\n return ts.isLiteralTypeNode(node) && node.literal.kind === ts.SyntaxKind.NullKeyword;\n }\n\n /**\n * The DERIVED discriminator: the property every branch declares as exactly ONE string literal,\n * with a value no two branches share. Derived, never invented — if the source does not narrow,\n * neither does the document.\n */\n private deriveDiscriminator(branchNames: readonly string[]): UnionDiscriminator | undefined {\n const branches = branchNames.map((name: string) => this.types.get(name));\n if (branches.some((b: DocumentedType | undefined) => b === undefined)) {\n return undefined;\n }\n const first = branches[0]!;\n for (const field of first.fields) {\n const values = new Map<string, string>();\n for (let i = 0; i < branches.length; i++) {\n const candidate = branches[i]!.fields.find(\n (f: DocumentedField) => f.name === field.name,\n );\n const literal =\n candidate !== undefined &&\n candidate.type.kind === 'enum' &&\n candidate.type.enumValues.length === 1\n ? candidate.type.enumValues[0]\n : undefined;\n if (literal === undefined) {\n values.clear();\n break;\n }\n values.set(branchNames[i], literal);\n }\n if (values.size === branches.length && new Set(values.values()).size === values.size) {\n return new UnionDiscriminator(field.name, values);\n }\n }\n return undefined;\n }\n\n /** A union written as a named `type X = A | B` becomes its own model entry, so #982 can `$ref` it. */\n private registerUnionAlias(\n node: ts.UnionTypeNode,\n branchNames: readonly string[],\n discriminator: UnionDiscriminator,\n ): void {\n const alias = node.parent;\n if (!ts.isTypeAliasDeclaration(alias)) {\n return;\n }\n const name = alias.name.text;\n if (this.registered.has(name)) {\n return;\n }\n this.registered.add(name);\n this.types.set(\n name,\n new DocumentedType(\n name,\n JsDoc.read(alias).description,\n [],\n [],\n branchNames,\n discriminator,\n undefined,\n ),\n );\n }\n\n /**\n * `Integer`, `Array<T>`, `Record<string, V>`, `Promise<T>`, and everything named — an interface,\n * a class, or a type alias. Anything else (a `Map`, a `Date`, a generic parameter) is recorded\n * rather than guessed at.\n */\n private resolveReference(node: ts.TypeReferenceNode, ownerName: string): TypeRef {\n const name = ts.isIdentifier(node.typeName) ? node.typeName.text : node.typeName.right.text;\n const args = node.typeArguments ?? [];\n\n if (name === INTEGER_ALIAS) {\n return TypeRef.primitiveOf('number', /*integer*/ true);\n }\n if ((name === 'Array' || name === 'ReadonlyArray') && args.length === 1) {\n return TypeRef.array(this.resolve(args[0], ownerName));\n }\n if ((name === 'Record' || name === 'Partial') && args.length === 2) {\n return TypeRef.openMap(this.resolve(args[1], ownerName));\n }\n if (name === 'Promise' && args.length === 1) {\n return this.resolve(args[0], ownerName);\n }\n\n const declaration = this.declarationOf(node.typeName);\n if (declaration === undefined) {\n return this.recordUnmapped(node, `no declaration found for '${name}'`);\n }\n return this.resolveDeclaration(name, declaration, ownerName);\n }\n\n /**\n * Resolve a type by its DECLARATION rather than by a reference to it.\n *\n * The reference path above is the normal one — a field says `Customer` and the resolver follows\n * it. This entry point exists for a type that is named from OUTSIDE the source: a manifest naming\n * the document-wide error body, which no field in the contract points at. Same registration, same\n * cycle story, so the two cannot disagree about what a type IS.\n */\n resolveDeclaration(name: string, declaration: ts.Declaration, ownerName: string): TypeRef {\n if (ts.isInterfaceDeclaration(declaration) || ts.isClassDeclaration(declaration)) {\n return this.registerNamedObject(name, declaration);\n }\n if (ts.isTypeAliasDeclaration(declaration)) {\n return this.resolveAlias(name, declaration, ownerName);\n }\n if (ts.isEnumDeclaration(declaration)) {\n return this.registerStringEnum(name, declaration);\n }\n return this.recordUnmapped(\n declaration,\n `'${name}' is declared as something with no document shape`,\n );\n }\n\n /** `type X = ...` — registered under X when it has a shape of its own, else transparent. */\n private resolveAlias(name: string, alias: ts.TypeAliasDeclaration, ownerName: string): TypeRef {\n if (this.registered.has(name)) {\n return this.types.get(name)?.unionRefNames.length\n ? TypeRef.union(this.types.get(name)!.unionRefNames)\n : TypeRef.ref(name);\n }\n\n if (ts.isUnionTypeNode(alias.type)) {\n const resolved = this.resolve(alias.type, ownerName);\n if (resolved.kind === 'enum') {\n this.registered.add(name);\n this.types.set(\n name,\n new DocumentedType(\n name,\n JsDoc.read(alias).description,\n [],\n resolved.enumValues,\n [],\n undefined,\n undefined,\n ),\n );\n return TypeRef.ref(name);\n }\n return resolved;\n }\n\n if (ts.isTypeLiteralNode(alias.type)) {\n return this.registerNamedObject(name, alias.type, alias);\n }\n return this.resolve(alias.type, ownerName);\n }\n\n /** A TS `enum` of string members — the one non-union enum shape a document can carry. */\n private registerStringEnum(name: string, declaration: ts.EnumDeclaration): TypeRef {\n if (this.registered.has(name)) {\n return TypeRef.ref(name);\n }\n const values: string[] = [];\n for (const member of declaration.members) {\n if (member.initializer && ts.isStringLiteral(member.initializer)) {\n values.push(member.initializer.text);\n }\n }\n if (values.length !== declaration.members.length) {\n return this.recordUnmapped(\n declaration,\n `enum '${name}' has members that are not string literals`,\n );\n }\n this.registered.add(name);\n this.types.set(\n name,\n new DocumentedType(\n name,\n JsDoc.read(declaration).description,\n [],\n values,\n [],\n undefined,\n undefined,\n ),\n );\n return TypeRef.ref(name);\n }\n\n /**\n * Register a named object shape, RESERVING THE NAME BEFORE walking its fields. That order is the\n * whole cycle story: a type that refers back to itself meets `registered.has(name)` on the second\n * visit and resolves to a `$ref`, so the walk terminates with no counter and no truncation.\n */\n private registerNamedObject(\n name: string,\n shape: ts.InterfaceDeclaration | ts.ClassDeclaration | ts.TypeLiteralNode,\n docSource?: ts.Node,\n ): TypeRef {\n if (this.registered.has(name)) {\n return TypeRef.ref(name);\n }\n this.registered.add(name);\n\n const fields: DocumentedField[] = [];\n let indexSignature: TypeRef | undefined;\n for (const member of shape.members) {\n if (ts.isIndexSignatureDeclaration(member)) {\n indexSignature = this.resolve(member.type, name);\n continue;\n }\n const field = this.fieldOf(member, name);\n if (field !== undefined) {\n fields.push(field);\n }\n }\n\n this.types.set(\n name,\n new DocumentedType(\n name,\n JsDoc.read(docSource ?? shape).description,\n fields,\n [],\n [],\n undefined,\n indexSignature,\n ),\n );\n return TypeRef.ref(name);\n }\n\n /**\n * An inline `{ ... }`. It has no name to `$ref`, so it is registered under an OWNER-DERIVED one\n * (`Parent.field`) — a renderer needs a target, and a name derived from where the shape is\n * written is the only honest one available.\n *\n * A self-referential anonymous type is cut HERE, by NODE IDENTITY. It cannot be a `$ref` (there\n * is no declared name to point at) and it cannot be expanded (it would never end), so it is\n * recorded as unmapped and the walk returns.\n */\n private resolveAnonymousObject(node: ts.TypeLiteralNode, ownerName: string): TypeRef {\n if (this.expandingAnonymous.has(node)) {\n return this.recordUnmapped(\n node,\n 'a self-referential ANONYMOUS object type has no name a renderer could $ref; give it a name',\n );\n }\n const indexOnly =\n node.members.length === 1 && ts.isIndexSignatureDeclaration(node.members[0]);\n if (indexOnly) {\n const signature = node.members[0] as ts.IndexSignatureDeclaration;\n return TypeRef.openMap(this.resolve(signature.type, ownerName));\n }\n\n this.expandingAnonymous.add(node);\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions -- the stack entry must be dropped whatever the walk does\n try {\n return this.registerNamedObject(ownerName, node);\n } finally {\n this.expandingAnonymous.delete(node);\n }\n }\n\n /** ONE property of a DTO — its type, its optionality, its prose and its numeric constraints. */\n private fieldOf(\n member: ts.TypeElement | ts.ClassElement,\n ownerName: string,\n ): DocumentedField | undefined {\n if (!ts.isPropertySignature(member) && !ts.isPropertyDeclaration(member)) {\n return undefined;\n }\n if (!ts.isIdentifier(member.name) && !ts.isStringLiteral(member.name)) {\n return undefined;\n }\n const name = member.name.text;\n if (member.type === undefined) {\n return undefined;\n }\n\n const optional =\n member.questionToken !== undefined || TypeResolver.declaresUndefined(member.type);\n const nullable = TypeResolver.declaresNull(member.type);\n\n let type = this.resolve(member.type, `${ownerName}.${name}`);\n if (TypeResolver.hasDecorator(member, INT_DECORATOR)) {\n type = TypeResolver.markInteger(type);\n }\n\n const doc = JsDoc.read(member);\n const min = this.numericArgument(member, MIN_DECORATOR);\n const max = this.numericArgument(member, MAX_DECORATOR);\n this.assertNumericConstraintsFit(member, name, type, min, max);\n\n return new DocumentedField(\n name,\n type,\n optional,\n nullable,\n doc.description,\n doc.mcp,\n doc.format,\n min,\n max,\n );\n }\n\n /**\n * `@WpMin` / `@WpMax` on a non-numeric field is a BUILD FAILURE, not a warning. A minimum on a\n * string is not something a renderer can emit sensibly, and a document that silently dropped it\n * would publish a contract weaker than the one its author wrote down.\n */\n private assertNumericConstraintsFit(\n member: ts.Node,\n name: string,\n type: TypeRef,\n min: number | undefined,\n max: number | undefined,\n ): void {\n if (min === undefined && max === undefined) {\n return;\n }\n const numeric = type.isNumeric() || (type.kind === 'array' && type.items!.isNumeric());\n if (numeric) {\n return;\n }\n throw new ApiDocExtractionError(\n `@${MIN_DECORATOR}/@${MAX_DECORATOR} on non-numeric field '${name}'`,\n SourceLocation.of(member),\n 'Put the constraint on a `number` / `Integer` field, or drop it.',\n );\n }\n\n /** `@WpInt()` decorates the FIELD, so the integer flag is pushed onto the right leaf. */\n // webpieces-disable no-function-outside-class -- private static helper of this class\n private static markInteger(type: TypeRef): TypeRef {\n if (type.kind === 'array') {\n return TypeRef.array(type.items!.asInteger());\n }\n if (type.kind === 'openMap') {\n return TypeRef.openMap(type.values!.asInteger());\n }\n return type.asInteger();\n }\n\n // webpieces-disable no-function-outside-class -- private static helper of this class\n private static declaresUndefined(node: ts.TypeNode): boolean {\n return (\n ts.isUnionTypeNode(node) &&\n node.types.some((t: ts.TypeNode) => t.kind === ts.SyntaxKind.UndefinedKeyword)\n );\n }\n\n // webpieces-disable no-function-outside-class -- private static helper of this class\n private static declaresNull(node: ts.TypeNode): boolean {\n return (\n ts.isUnionTypeNode(node) &&\n node.types.some(\n (t: ts.TypeNode) =>\n t.kind === ts.SyntaxKind.NullKeyword ||\n (ts.isLiteralTypeNode(t) && t.literal.kind === ts.SyntaxKind.NullKeyword),\n )\n );\n }\n\n // webpieces-disable no-function-outside-class -- private static helper of this class\n private static hasDecorator(node: ts.Node, decoratorName: string): boolean {\n return TypeResolver.decoratorCall(node, decoratorName) !== undefined;\n }\n\n // webpieces-disable no-function-outside-class -- private static helper of this class\n private static decoratorCall(\n node: ts.Node,\n decoratorName: string,\n ): ts.CallExpression | undefined {\n const decorators = ts.canHaveDecorators(node) ? (ts.getDecorators(node) ?? []) : [];\n for (const decorator of decorators) {\n const call = decorator.expression;\n if (\n ts.isCallExpression(call) &&\n ts.isIdentifier(call.expression) &&\n call.expression.text === decoratorName\n ) {\n return call;\n }\n }\n return undefined;\n }\n\n private numericArgument(node: ts.Node, decoratorName: string): number | undefined {\n const call = TypeResolver.decoratorCall(node, decoratorName);\n const argument = call?.arguments[0];\n if (argument === undefined) {\n return undefined;\n }\n if (ts.isNumericLiteral(argument)) {\n return Number(argument.text);\n }\n if (\n ts.isPrefixUnaryExpression(argument) &&\n argument.operator === ts.SyntaxKind.MinusToken &&\n ts.isNumericLiteral(argument.operand)\n ) {\n return -Number(argument.operand.text);\n }\n throw new ApiDocExtractionError(\n `@${decoratorName} argument is not a numeric literal: '${argument.getText()}'`,\n SourceLocation.of(argument),\n 'Write the bound as a numeric literal. A value only known at runtime cannot be published.',\n );\n }\n\n /** The declaration a type name points at, through imports and aliases. */\n private declarationOf(name: ts.EntityName): ts.Declaration | undefined {\n const symbol = this.checker.getSymbolAtLocation(name);\n const resolved =\n symbol !== undefined && (symbol.flags & ts.SymbolFlags.Alias) !== 0\n ? this.checker.getAliasedSymbol(symbol)\n : symbol;\n return resolved?.declarations?.[0];\n }\n\n private recordUnmapped(node: ts.Node, reason: string): TypeRef {\n const text = node.getText();\n this.unmapped.push(new UnmappedType(text, SourceLocation.of(node), reason));\n return TypeRef.unmapped(text);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"TypeResolver.js","sourceRoot":"","sources":["../../../../../../packages/docs/api-doc-model/src/extract/TypeResolver.ts"],"names":[],"mappings":";;;;AAAA,uDAAiC;AACjC,oDAA2D;AAC3D,sDAK8B;AAC9B,8CAA0D;AAC1D,mEAAgE;AAChE,mCAAgC;AAChC,qDAAkD;AAElD;;;;GAIG;AACH,MAAM,aAAa,GAAG,iBAAK,CAAC,IAAI,CAAC;AACjC,MAAM,aAAa,GAAG,iBAAK,CAAC,IAAI,CAAC;AACjC,MAAM,aAAa,GAAG,iBAAK,CAAC,IAAI,CAAC;AAEjC;;;;;;;;;GASG;AACH,MAAM,aAAa,GAAG,SAAS,CAAC;AAEhC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAa,YAAY;IAQQ;IAPZ,KAAK,GAAG,IAAI,GAAG,EAA0B,CAAC;IAC1C,QAAQ,GAAmB,EAAE,CAAC;IAC/C,gGAAgG;IAC/E,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;IAChD,gGAAgG;IAC/E,kBAAkB,GAAG,IAAI,GAAG,EAAe,CAAC;IAE7D,YAA6B,OAAuB;QAAvB,YAAO,GAAP,OAAO,CAAgB;IAAG,CAAC;IAExD,gDAAgD;IAChD,cAAc;QACV,OAAO,IAAI,CAAC,KAAK,CAAC;IACtB,CAAC;IAED,0EAA0E;IAC1E,iBAAiB;QACb,OAAO,IAAI,CAAC,QAAQ,CAAC;IACzB,CAAC;IAED,6EAA6E;IAC7E,OAAO,CAAC,IAAiB,EAAE,SAAiB;QACxC,IAAI,EAAE,CAAC,uBAAuB,CAAC,IAAI,CAAC,EAAE,CAAC;YACnC,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QAC9C,CAAC;QACD,IAAI,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3B,OAAO,iBAAO,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC,CAAC;QACpE,CAAC;QACD,IAAI,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3B,OAAO,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QAC9C,CAAC;QACD,IAAI,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7B,OAAO,IAAI,CAAC,sBAAsB,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QACxD,CAAC;QACD,IAAI,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7B,OAAO,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;QACrC,CAAC;QACD,IAAI,EAAE,CAAC,mBAAmB,CAAC,IAAI,CAAC,EAAE,CAAC;YAC/B,OAAO,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QAClD,CAAC;QACD,MAAM,SAAS,GAAG,YAAY,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpD,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAC1B,OAAO,iBAAO,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;QAC1C,CAAC;QACD,OAAO,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,4CAA4C,CAAC,CAAC;IACnF,CAAC;IAED,4FAA4F;IAC5F,2FAA2F;IACnF,MAAM,CAAC,SAAS,CAAC,IAAmB;QACxC,QAAQ,IAAI,EAAE,CAAC;YACX,KAAK,EAAE,CAAC,UAAU,CAAC,aAAa;gBAC5B,OAAO,QAAQ,CAAC;YACpB,KAAK,EAAE,CAAC,UAAU,CAAC,aAAa;gBAC5B,OAAO,QAAQ,CAAC;YACpB,KAAK,EAAE,CAAC,UAAU,CAAC,cAAc;gBAC7B,OAAO,SAAS,CAAC;YACrB,KAAK,EAAE,CAAC,UAAU,CAAC,WAAW;gBAC1B,OAAO,MAAM,CAAC;YAClB,KAAK,EAAE,CAAC,UAAU,CAAC,cAAc,CAAC;YAClC,KAAK,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC;YAC9B,KAAK,EAAE,CAAC,UAAU,CAAC,WAAW;gBAC1B,OAAO,SAAS,CAAC;YACrB;gBACI,OAAO,SAAS,CAAC;QACzB,CAAC;IACL,CAAC;IAEO,cAAc,CAAC,IAAwB;QAC3C,IAAI,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YACnC,OAAO,iBAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QAC/C,CAAC;QACD,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,KAAK,EAAE,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC;YAClD,OAAO,iBAAO,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QACvC,CAAC;QACD,IACI,IAAI,CAAC,OAAO,CAAC,IAAI,KAAK,EAAE,CAAC,UAAU,CAAC,WAAW;YAC/C,IAAI,CAAC,OAAO,CAAC,IAAI,KAAK,EAAE,CAAC,UAAU,CAAC,YAAY,EAClD,CAAC;YACC,OAAO,iBAAO,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;QAC1C,CAAC;QACD,IAAI,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YACpC,OAAO,iBAAO,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;QACzC,CAAC;QACD,OAAO,IAAI,CAAC,cAAc,CACtB,IAAI,EACJ,0DAA0D,CAC7D,CAAC;IACN,CAAC;IAED;;;;;;;;;;;;OAYG;IACK,YAAY,CAAC,IAAsB,EAAE,SAAiB;QAC1D,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAc,EAAE,EAAE,CAAC,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;QAEnF,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAC5B,CAAC,CAAc,EAAE,EAAE,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,OAAO,CAAC,CAC/E,CAAC;QACF,IAAI,QAAQ,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7D,OAAO,iBAAO,CAAC,MAAM,CACjB,QAAQ,CAAC,GAAG,CACR,CAAC,CAAc,EAAE,EAAE,CACb,CAAwB,CAAC,OAA4B,CAAC,IAAI,CACnE,CACJ,CAAC;QACN,CAAC;QAED,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;QAChD,CAAC;QACD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,OAAO,iBAAO,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QACvC,CAAC;QAED,MAAM,IAAI,GAAc,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAc,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC;QACrF,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAU,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;YAChD,OAAO,IAAI,CAAC,cAAc,CACtB,IAAI,EACJ,uGAAuG,CAC1G,CAAC;QACN,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAU,EAAE,EAAE,CAAC,CAAC,CAAC,OAAQ,CAAC,CAAC;QACnD,MAAM,aAAa,GAAG,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC;QACtD,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;YAC9B,OAAO,IAAI,CAAC,cAAc,CACtB,IAAI,EACJ,+GAA+G,CAClH,CAAC;QACN,CAAC;QACD,IAAI,CAAC,kBAAkB,CAAC,IAAI,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC;QACpD,OAAO,iBAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAChC,CAAC;IAED,sGAAsG;IACtG,wFAAwF;IAChF,MAAM,CAAC,SAAS,CAAC,IAAiB;QACtC,IACI,IAAI,CAAC,IAAI,KAAK,EAAE,CAAC,UAAU,CAAC,gBAAgB;YAC5C,IAAI,CAAC,IAAI,KAAK,EAAE,CAAC,UAAU,CAAC,WAAW,EACzC,CAAC;YACC,OAAO,IAAI,CAAC;QAChB,CAAC;QACD,OAAO,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,KAAK,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC;IACzF,CAAC;IAED;;;;OAIG;IACK,mBAAmB,CAAC,WAA8B;QACtD,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;QACzE,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,CAA6B,EAAE,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC,EAAE,CAAC;YACpE,OAAO,SAAS,CAAC;QACrB,CAAC;QACD,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAE,CAAC;QAC3B,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;YAC/B,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;YACzC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACvC,MAAM,SAAS,GAAG,QAAQ,CAAC,CAAC,CAAE,CAAC,MAAM,CAAC,IAAI,CACtC,CAAC,CAAkB,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,CAChD,CAAC;gBACF,MAAM,OAAO,GACT,SAAS,KAAK,SAAS;oBACvB,SAAS,CAAC,IAAI,CAAC,IAAI,KAAK,MAAM;oBAC9B,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC;oBAClC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;oBAC9B,CAAC,CAAC,SAAS,CAAC;gBACpB,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;oBACxB,MAAM,CAAC,KAAK,EAAE,CAAC;oBACf,MAAM;gBACV,CAAC;gBACD,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;YACxC,CAAC;YACD,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,CAAC,MAAM,IAAI,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC;gBACnF,OAAO,IAAI,gCAAkB,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YACtD,CAAC;QACL,CAAC;QACD,OAAO,SAAS,CAAC;IACrB,CAAC;IAED,sGAAsG;IAC9F,kBAAkB,CACtB,IAAsB,EACtB,WAA8B,EAC9B,aAAiC;QAEjC,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC;QAC1B,IAAI,CAAC,EAAE,CAAC,sBAAsB,CAAC,KAAK,CAAC,EAAE,CAAC;YACpC,OAAO;QACX,CAAC;QACD,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;QAC7B,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC5B,OAAO;QACX,CAAC;QACD,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC1B,IAAI,CAAC,KAAK,CAAC,GAAG,CACV,IAAI,EACJ,IAAI,4BAAc,CACd,IAAI,EACJ,aAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,WAAW,EAC7B,EAAE,EACF,EAAE,EACF,WAAW,EACX,aAAa,EACb,SAAS,CACZ,CACJ,CAAC;IACN,CAAC;IAED;;;;OAIG;IACK,gBAAgB,CAAC,IAA0B,EAAE,SAAiB;QAClE,MAAM,IAAI,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC;QAC5F,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,IAAI,EAAE,CAAC;QAEtC,IAAI,IAAI,KAAK,aAAa,EAAE,CAAC;YACzB,OAAO,iBAAO,CAAC,WAAW,CAAC,QAAQ,EAAE,WAAW,CAAC,IAAI,CAAC,CAAC;QAC3D,CAAC;QACD,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,eAAe,CAAC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtE,OAAO,iBAAO,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC;QAC3D,CAAC;QACD,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,SAAS,CAAC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACjE,OAAO,iBAAO,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC;QAC7D,CAAC;QACD,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1C,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;QAC5C,CAAC;QAED,MAAM,WAAW,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACtD,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;YAC5B,OAAO,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,6BAA6B,IAAI,GAAG,CAAC,CAAC;QAC3E,CAAC;QACD,OAAO,IAAI,CAAC,kBAAkB,CAAC,IAAI,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;IACjE,CAAC;IAED;;;;;;;OAOG;IACH,kBAAkB,CAAC,IAAY,EAAE,WAA2B,EAAE,SAAiB;QAC3E,IAAI,EAAE,CAAC,sBAAsB,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,kBAAkB,CAAC,WAAW,CAAC,EAAE,CAAC;YAC/E,OAAO,IAAI,CAAC,mBAAmB,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QACvD,CAAC;QACD,IAAI,EAAE,CAAC,sBAAsB,CAAC,WAAW,CAAC,EAAE,CAAC;YACzC,OAAO,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,WAAW,EAAE,SAAS,CAAC,CAAC;QAC3D,CAAC;QACD,IAAI,EAAE,CAAC,iBAAiB,CAAC,WAAW,CAAC,EAAE,CAAC;YACpC,OAAO,IAAI,CAAC,kBAAkB,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QACtD,CAAC;QACD,OAAO,IAAI,CAAC,cAAc,CACtB,WAAW,EACX,IAAI,IAAI,mDAAmD,CAC9D,CAAC;IACN,CAAC;IAED,4FAA4F;IACpF,YAAY,CAAC,IAAY,EAAE,KAA8B,EAAE,SAAiB;QAChF,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC5B,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,aAAa,CAAC,MAAM;gBAC7C,CAAC,CAAC,iBAAO,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAE,CAAC,aAAa,CAAC;gBACpD,CAAC,CAAC,iBAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;QAED,IAAI,EAAE,CAAC,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACjC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;YACrD,IAAI,QAAQ,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;gBAC3B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBAC1B,IAAI,CAAC,KAAK,CAAC,GAAG,CACV,IAAI,EACJ,IAAI,4BAAc,CACd,IAAI,EACJ,aAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,WAAW,EAC7B,EAAE,EACF,QAAQ,CAAC,UAAU,EACnB,EAAE,EACF,SAAS,EACT,SAAS,CACZ,CACJ,CAAC;gBACF,OAAO,iBAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAC7B,CAAC;YACD,OAAO,QAAQ,CAAC;QACpB,CAAC;QAED,IAAI,EAAE,CAAC,iBAAiB,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACnC,OAAO,IAAI,CAAC,mBAAmB,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC7D,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAC/C,CAAC;IAED,yFAAyF;IACjF,kBAAkB,CAAC,IAAY,EAAE,WAA+B;QACpE,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC5B,OAAO,iBAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC7B,CAAC;QACD,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,KAAK,MAAM,MAAM,IAAI,WAAW,CAAC,OAAO,EAAE,CAAC;YACvC,IAAI,MAAM,CAAC,WAAW,IAAI,EAAE,CAAC,eAAe,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC;gBAC/D,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;YACzC,CAAC;QACL,CAAC;QACD,IAAI,MAAM,CAAC,MAAM,KAAK,WAAW,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;YAC/C,OAAO,IAAI,CAAC,cAAc,CACtB,WAAW,EACX,SAAS,IAAI,4CAA4C,CAC5D,CAAC;QACN,CAAC;QACD,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC1B,IAAI,CAAC,KAAK,CAAC,GAAG,CACV,IAAI,EACJ,IAAI,4BAAc,CACd,IAAI,EACJ,aAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,WAAW,EACnC,EAAE,EACF,MAAM,EACN,EAAE,EACF,SAAS,EACT,SAAS,CACZ,CACJ,CAAC;QACF,OAAO,iBAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IAED;;;;OAIG;IACK,mBAAmB,CACvB,IAAY,EACZ,KAAyE,EACzE,SAAmB;QAEnB,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC5B,OAAO,iBAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC7B,CAAC;QACD,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAE1B,MAAM,MAAM,GAAsB,EAAE,CAAC;QACrC,IAAI,cAAmC,CAAC;QACxC,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YACjC,IAAI,EAAE,CAAC,2BAA2B,CAAC,MAAM,CAAC,EAAE,CAAC;gBACzC,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;gBACjD,SAAS;YACb,CAAC;YACD,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;YACzC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACtB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACvB,CAAC;QACL,CAAC;QAED,IAAI,CAAC,KAAK,CAAC,GAAG,CACV,IAAI,EACJ,IAAI,4BAAc,CACd,IAAI,EACJ,aAAK,CAAC,IAAI,CAAC,SAAS,IAAI,KAAK,CAAC,CAAC,WAAW,EAC1C,MAAM,EACN,EAAE,EACF,EAAE,EACF,SAAS,EACT,cAAc,CACjB,CACJ,CAAC;QACF,OAAO,iBAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IAED;;;;;;;;OAQG;IACK,sBAAsB,CAAC,IAAwB,EAAE,SAAiB;QACtE,IAAI,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACpC,OAAO,IAAI,CAAC,cAAc,CACtB,IAAI,EACJ,4FAA4F,CAC/F,CAAC;QACN,CAAC;QACD,MAAM,SAAS,GACX,IAAI,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC,2BAA2B,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;QACjF,IAAI,SAAS,EAAE,CAAC;YACZ,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAiC,CAAC;YAClE,OAAO,iBAAO,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC;QACpE,CAAC;QAED,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAClC,wHAAwH;QACxH,IAAI,CAAC;YACD,OAAO,IAAI,CAAC,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QACrD,CAAC;gBAAS,CAAC;YACP,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACzC,CAAC;IACL,CAAC;IAED,gGAAgG;IACxF,OAAO,CACX,MAAwC,EACxC,SAAiB;QAEjB,IAAI,CAAC,EAAE,CAAC,mBAAmB,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,qBAAqB,CAAC,MAAM,CAAC,EAAE,CAAC;YACvE,OAAO,SAAS,CAAC;QACrB,CAAC;QACD,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;YACpE,OAAO,SAAS,CAAC;QACrB,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;QAC9B,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC5B,OAAO,SAAS,CAAC;QACrB,CAAC;QAED,MAAM,QAAQ,GACV,MAAM,CAAC,aAAa,KAAK,SAAS,IAAI,YAAY,CAAC,iBAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACtF,MAAM,QAAQ,GAAG,YAAY,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAExD,IAAI,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,SAAS,IAAI,IAAI,EAAE,CAAC,CAAC;QAC7D,IAAI,YAAY,CAAC,YAAY,CAAC,MAAM,EAAE,aAAa,CAAC,EAAE,CAAC;YACnD,IAAI,GAAG,YAAY,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAC1C,CAAC;QAED,MAAM,GAAG,GAAG,aAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC/B,MAAM,GAAG,GAAG,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;QACxD,MAAM,GAAG,GAAG,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;QACxD,IAAI,CAAC,2BAA2B,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;QAE/D,OAAO,IAAI,6BAAe,CACtB,IAAI,EACJ,IAAI,EACJ,QAAQ,EACR,QAAQ,EACR,GAAG,CAAC,WAAW,EACf,GAAG,CAAC,GAAG,EACP,GAAG,CAAC,MAAM,EACV,GAAG,EACH,GAAG,EACH,GAAG,CAAC,SAAS,CAChB,CAAC;IACN,CAAC;IAED;;;;OAIG;IACK,2BAA2B,CAC/B,MAAe,EACf,IAAY,EACZ,IAAa,EACb,GAAuB,EACvB,GAAuB;QAEvB,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YACzC,OAAO;QACX,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,IAAI,CAAC,KAAM,CAAC,SAAS,EAAE,CAAC,CAAC;QACvF,IAAI,OAAO,EAAE,CAAC;YACV,OAAO;QACX,CAAC;QACD,MAAM,IAAI,6CAAqB,CAC3B,IAAI,aAAa,KAAK,aAAa,0BAA0B,IAAI,GAAG,EACpE,+BAAc,CAAC,EAAE,CAAC,MAAM,CAAC,EACzB,iEAAiE,CACpE,CAAC;IACN,CAAC;IAED,yFAAyF;IACzF,qFAAqF;IAC7E,MAAM,CAAC,WAAW,CAAC,IAAa;QACpC,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YACxB,OAAO,iBAAO,CAAC,KAAK,CAAC,IAAI,CAAC,KAAM,CAAC,SAAS,EAAE,CAAC,CAAC;QAClD,CAAC;QACD,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC1B,OAAO,iBAAO,CAAC,OAAO,CAAC,IAAI,CAAC,MAAO,CAAC,SAAS,EAAE,CAAC,CAAC;QACrD,CAAC;QACD,OAAO,IAAI,CAAC,SAAS,EAAE,CAAC;IAC5B,CAAC;IAED,qFAAqF;IAC7E,MAAM,CAAC,iBAAiB,CAAC,IAAiB;QAC9C,OAAO,CACH,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC;YACxB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAc,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,UAAU,CAAC,gBAAgB,CAAC,CACjF,CAAC;IACN,CAAC;IAED,qFAAqF;IAC7E,MAAM,CAAC,YAAY,CAAC,IAAiB;QACzC,OAAO,CACH,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC;YACxB,IAAI,CAAC,KAAK,CAAC,IAAI,CACX,CAAC,CAAc,EAAE,EAAE,CACf,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,UAAU,CAAC,WAAW;gBACpC,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,KAAK,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,CAChF,CACJ,CAAC;IACN,CAAC;IAED,qFAAqF;IAC7E,MAAM,CAAC,YAAY,CAAC,IAAa,EAAE,aAAqB;QAC5D,OAAO,YAAY,CAAC,aAAa,CAAC,IAAI,EAAE,aAAa,CAAC,KAAK,SAAS,CAAC;IACzE,CAAC;IAED,qFAAqF;IAC7E,MAAM,CAAC,aAAa,CACxB,IAAa,EACb,aAAqB;QAErB,MAAM,UAAU,GAAG,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACpF,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACjC,MAAM,IAAI,GAAG,SAAS,CAAC,UAAU,CAAC;YAClC,IACI,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC;gBACzB,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC;gBAChC,IAAI,CAAC,UAAU,CAAC,IAAI,KAAK,aAAa,EACxC,CAAC;gBACC,OAAO,IAAI,CAAC;YAChB,CAAC;QACL,CAAC;QACD,OAAO,SAAS,CAAC;IACrB,CAAC;IAEO,eAAe,CAAC,IAAa,EAAE,aAAqB;QACxD,MAAM,IAAI,GAAG,YAAY,CAAC,aAAa,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;QAC7D,MAAM,QAAQ,GAAG,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;QACpC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YACzB,OAAO,SAAS,CAAC;QACrB,CAAC;QACD,IAAI,EAAE,CAAC,gBAAgB,CAAC,QAAQ,CAAC,EAAE,CAAC;YAChC,OAAO,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACjC,CAAC;QACD,IACI,EAAE,CAAC,uBAAuB,CAAC,QAAQ,CAAC;YACpC,QAAQ,CAAC,QAAQ,KAAK,EAAE,CAAC,UAAU,CAAC,UAAU;YAC9C,EAAE,CAAC,gBAAgB,CAAC,QAAQ,CAAC,OAAO,CAAC,EACvC,CAAC;YACC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC1C,CAAC;QACD,MAAM,IAAI,6CAAqB,CAC3B,IAAI,aAAa,wCAAwC,QAAQ,CAAC,OAAO,EAAE,GAAG,EAC9E,+BAAc,CAAC,EAAE,CAAC,QAAQ,CAAC,EAC3B,0FAA0F,CAC7F,CAAC;IACN,CAAC;IAED,0EAA0E;IAClE,aAAa,CAAC,IAAmB;QACrC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC;QACtD,MAAM,QAAQ,GACV,MAAM,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,KAAK,GAAG,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC;YAC/D,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,MAAM,CAAC;YACvC,CAAC,CAAC,MAAM,CAAC;QACjB,OAAO,QAAQ,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,CAAC;IACvC,CAAC;IAEO,cAAc,CAAC,IAAa,EAAE,MAAc;QAChD,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;QAC5B,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,0BAAY,CAAC,IAAI,EAAE,+BAAc,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;QAC5E,OAAO,iBAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC;CACJ;AAtkBD,oCAskBC","sourcesContent":["import * as ts from 'typescript';\nimport { WpInt, WpMax, WpMin } from '@webpieces/core-util';\nimport {\n DocumentedField,\n DocumentedType,\n UnionDiscriminator,\n UnmappedType,\n} from '../model/ApiDocModel';\nimport { PrimitiveKind, TypeRef } from '../model/TypeRef';\nimport { ApiDocExtractionError } from './ApiDocExtractionError';\nimport { JsDoc } from './JsDoc';\nimport { SourceLocation } from './SourceLocation';\n\n/**\n * The decorators this resolver reads off a DTO property, named from the REAL SYMBOLS — a rename in\n * `core-util` is a compile error here rather than a literal that quietly stops matching. See\n * {@link ApiDocExtractor}'s constants for the full argument (issue #1001).\n */\nconst INT_DECORATOR = WpInt.name;\nconst MIN_DECORATOR = WpMin.name;\nconst MAX_DECORATOR = WpMax.name;\n\n/**\n * The type-alias name that DECLARES integer-ness.\n *\n * This one is a LITERAL and cannot be anything else: `Integer` is a TYPE ALIAS, so there is no\n * runtime symbol whose `.name` could be read — `.name` is a property of a function, and a type has\n * erased by then. It is the one name in this package that a rename in `core-util` would not break at\n * compile time; the cure if that ever bites is to make integer-ness a decorator here too, not to\n * pretend a type has a runtime identity. See {@link ApiDocExtractor}'s constants for the argument\n * everywhere else (issue #1001).\n */\nconst INTEGER_ALIAS = 'Integer';\n\n/**\n * Resolve declared TypeScript types into {@link TypeRef}s, registering every NAMED type it meets as\n * a {@link DocumentedType} a renderer can `$ref`.\n *\n * ## It walks TYPE NODES, not checker types, and that is load-bearing\n *\n * `type Integer = number` resolves, in the checker, to `number` — the alias is gone. Integer-ness is\n * therefore invisible to a checker-driven walk, and the whole reason `Integer` is the PREFERRED\n * spelling is that it COMPOSES: `Integer[]` and `Record<string, Integer>` say exactly which thing is\n * an integer, where a decorator on `counts?: number[]` cannot (the same ambiguity the deleted\n * `arrayItems` argument had). Walking the written syntax is what keeps that composition readable.\n *\n * ## Cycles terminate BY CONSTRUCTION\n *\n * Every named type is ONE entry in the model, registered before its fields are walked, so a type\n * that refers back to itself resolves to a `$ref` at the second visit and stops. There is NO depth\n * counter anywhere — a deep-but-finite graph of 7, 20 or 200 named hops is fully expanded, because\n * truncating one would silently publish an incomplete document. The ONLY thing that is cut is a\n * self-referential ANONYMOUS type, and it is cut by NODE IDENTITY (it has no name to `$ref`), with an\n * {@link UnmappedType} recorded so #982's guard has something to name.\n */\nexport class TypeResolver {\n private readonly types = new Map<string, DocumentedType>();\n private readonly unmapped: UnmappedType[] = [];\n /** Named types already registered (or mid-registration) — the cycle stop for the NAMED case. */\n private readonly registered = new Set<string>();\n /** Anonymous type literals currently being expanded — the cycle stop for the ANONYMOUS case. */\n private readonly expandingAnonymous = new Set<ts.TypeNode>();\n\n constructor(private readonly checker: ts.TypeChecker) {}\n\n /** Every named type reached so far, by name. */\n collectedTypes(): ReadonlyMap<string, DocumentedType> {\n return this.types;\n }\n\n /** Everything that could not be represented — recorded, never dropped. */\n collectedUnmapped(): readonly UnmappedType[] {\n return this.unmapped;\n }\n\n /** Resolve one written type, registering whatever named types it reaches. */\n resolve(node: ts.TypeNode, ownerName: string): TypeRef {\n if (ts.isParenthesizedTypeNode(node)) {\n return this.resolve(node.type, ownerName);\n }\n if (ts.isArrayTypeNode(node)) {\n return TypeRef.array(this.resolve(node.elementType, ownerName));\n }\n if (ts.isUnionTypeNode(node)) {\n return this.resolveUnion(node, ownerName);\n }\n if (ts.isTypeLiteralNode(node)) {\n return this.resolveAnonymousObject(node, ownerName);\n }\n if (ts.isLiteralTypeNode(node)) {\n return this.resolveLiteral(node);\n }\n if (ts.isTypeReferenceNode(node)) {\n return this.resolveReference(node, ownerName);\n }\n const primitive = TypeResolver.keywordOf(node.kind);\n if (primitive !== undefined) {\n return TypeRef.primitiveOf(primitive);\n }\n return this.recordUnmapped(node, 'no model representation for this type form');\n }\n\n /** `string` / `number` / `boolean` / `null` / `unknown`, or undefined for anything else. */\n // webpieces-disable no-function-outside-class -- private static lookup table of this class\n private static keywordOf(kind: ts.SyntaxKind): PrimitiveKind | undefined {\n switch (kind) {\n case ts.SyntaxKind.StringKeyword:\n return 'string';\n case ts.SyntaxKind.NumberKeyword:\n return 'number';\n case ts.SyntaxKind.BooleanKeyword:\n return 'boolean';\n case ts.SyntaxKind.NullKeyword:\n return 'null';\n case ts.SyntaxKind.UnknownKeyword:\n case ts.SyntaxKind.AnyKeyword:\n case ts.SyntaxKind.VoidKeyword:\n return 'unknown';\n default:\n return undefined;\n }\n }\n\n private resolveLiteral(node: ts.LiteralTypeNode): TypeRef {\n if (ts.isStringLiteral(node.literal)) {\n return TypeRef.enumOf([node.literal.text]);\n }\n if (node.literal.kind === ts.SyntaxKind.NullKeyword) {\n return TypeRef.primitiveOf('null');\n }\n if (\n node.literal.kind === ts.SyntaxKind.TrueKeyword ||\n node.literal.kind === ts.SyntaxKind.FalseKeyword\n ) {\n return TypeRef.primitiveOf('boolean');\n }\n if (ts.isNumericLiteral(node.literal)) {\n return TypeRef.primitiveOf('number');\n }\n return this.recordUnmapped(\n node,\n 'literal type is neither a string, a number nor a boolean',\n );\n }\n\n /**\n * A union, after `null` / `undefined` have been dropped (the FIELD records those as nullable /\n * optional — see {@link fieldOf} — because `{}` and `{x: null}` are different wire documents).\n *\n * Three outcomes, in this order:\n * - every branch a string literal -> an ENUM\n * - one branch left -> that branch\n * - every branch a named object -> a UNION, with a DERIVED discriminator when every branch\n * carries the same property typed as ONE string literal\n * - anything else -> an {@link UnmappedType}. No invented discriminator, ever:\n * a union TypeScript itself cannot narrow is not one a\n * renderer may claim to.\n */\n private resolveUnion(node: ts.UnionTypeNode, ownerName: string): TypeRef {\n const branches = node.types.filter((t: ts.TypeNode) => !TypeResolver.isNullish(t));\n\n const literals = branches.filter(\n (t: ts.TypeNode) => ts.isLiteralTypeNode(t) && ts.isStringLiteral(t.literal),\n );\n if (literals.length === branches.length && branches.length > 0) {\n return TypeRef.enumOf(\n literals.map(\n (t: ts.TypeNode) =>\n ((t as ts.LiteralTypeNode).literal as ts.StringLiteral).text,\n ),\n );\n }\n\n if (branches.length === 1) {\n return this.resolve(branches[0], ownerName);\n }\n if (branches.length === 0) {\n return TypeRef.primitiveOf('null');\n }\n\n const refs: TypeRef[] = branches.map((t: ts.TypeNode) => this.resolve(t, ownerName));\n if (!refs.every((r: TypeRef) => r.kind === 'ref')) {\n return this.recordUnmapped(\n node,\n 'a union whose branches are not all NAMED object types has no discriminator a renderer could narrow on',\n );\n }\n\n const names = refs.map((r: TypeRef) => r.refName!);\n const discriminator = this.deriveDiscriminator(names);\n if (discriminator === undefined) {\n return this.recordUnmapped(\n node,\n 'no property is typed as a single string literal on EVERY branch, so this union has no derivable discriminator',\n );\n }\n this.registerUnionAlias(node, names, discriminator);\n return TypeRef.union(names);\n }\n\n /** `null` and `undefined` branches — recorded as nullable/optional on the FIELD, not in the union. */\n // webpieces-disable no-function-outside-class -- private static predicate of this class\n private static isNullish(node: ts.TypeNode): boolean {\n if (\n node.kind === ts.SyntaxKind.UndefinedKeyword ||\n node.kind === ts.SyntaxKind.NullKeyword\n ) {\n return true;\n }\n return ts.isLiteralTypeNode(node) && node.literal.kind === ts.SyntaxKind.NullKeyword;\n }\n\n /**\n * The DERIVED discriminator: the property every branch declares as exactly ONE string literal,\n * with a value no two branches share. Derived, never invented — if the source does not narrow,\n * neither does the document.\n */\n private deriveDiscriminator(branchNames: readonly string[]): UnionDiscriminator | undefined {\n const branches = branchNames.map((name: string) => this.types.get(name));\n if (branches.some((b: DocumentedType | undefined) => b === undefined)) {\n return undefined;\n }\n const first = branches[0]!;\n for (const field of first.fields) {\n const values = new Map<string, string>();\n for (let i = 0; i < branches.length; i++) {\n const candidate = branches[i]!.fields.find(\n (f: DocumentedField) => f.name === field.name,\n );\n const literal =\n candidate !== undefined &&\n candidate.type.kind === 'enum' &&\n candidate.type.enumValues.length === 1\n ? candidate.type.enumValues[0]\n : undefined;\n if (literal === undefined) {\n values.clear();\n break;\n }\n values.set(branchNames[i], literal);\n }\n if (values.size === branches.length && new Set(values.values()).size === values.size) {\n return new UnionDiscriminator(field.name, values);\n }\n }\n return undefined;\n }\n\n /** A union written as a named `type X = A | B` becomes its own model entry, so #982 can `$ref` it. */\n private registerUnionAlias(\n node: ts.UnionTypeNode,\n branchNames: readonly string[],\n discriminator: UnionDiscriminator,\n ): void {\n const alias = node.parent;\n if (!ts.isTypeAliasDeclaration(alias)) {\n return;\n }\n const name = alias.name.text;\n if (this.registered.has(name)) {\n return;\n }\n this.registered.add(name);\n this.types.set(\n name,\n new DocumentedType(\n name,\n JsDoc.read(alias).description,\n [],\n [],\n branchNames,\n discriminator,\n undefined,\n ),\n );\n }\n\n /**\n * `Integer`, `Array<T>`, `Record<string, V>`, `Promise<T>`, and everything named — an interface,\n * a class, or a type alias. Anything else (a `Map`, a `Date`, a generic parameter) is recorded\n * rather than guessed at.\n */\n private resolveReference(node: ts.TypeReferenceNode, ownerName: string): TypeRef {\n const name = ts.isIdentifier(node.typeName) ? node.typeName.text : node.typeName.right.text;\n const args = node.typeArguments ?? [];\n\n if (name === INTEGER_ALIAS) {\n return TypeRef.primitiveOf('number', /*integer*/ true);\n }\n if ((name === 'Array' || name === 'ReadonlyArray') && args.length === 1) {\n return TypeRef.array(this.resolve(args[0], ownerName));\n }\n if ((name === 'Record' || name === 'Partial') && args.length === 2) {\n return TypeRef.openMap(this.resolve(args[1], ownerName));\n }\n if (name === 'Promise' && args.length === 1) {\n return this.resolve(args[0], ownerName);\n }\n\n const declaration = this.declarationOf(node.typeName);\n if (declaration === undefined) {\n return this.recordUnmapped(node, `no declaration found for '${name}'`);\n }\n return this.resolveDeclaration(name, declaration, ownerName);\n }\n\n /**\n * Resolve a type by its DECLARATION rather than by a reference to it.\n *\n * The reference path above is the normal one — a field says `Customer` and the resolver follows\n * it. This entry point exists for a type that is named from OUTSIDE the source: a manifest naming\n * the document-wide error body, which no field in the contract points at. Same registration, same\n * cycle story, so the two cannot disagree about what a type IS.\n */\n resolveDeclaration(name: string, declaration: ts.Declaration, ownerName: string): TypeRef {\n if (ts.isInterfaceDeclaration(declaration) || ts.isClassDeclaration(declaration)) {\n return this.registerNamedObject(name, declaration);\n }\n if (ts.isTypeAliasDeclaration(declaration)) {\n return this.resolveAlias(name, declaration, ownerName);\n }\n if (ts.isEnumDeclaration(declaration)) {\n return this.registerStringEnum(name, declaration);\n }\n return this.recordUnmapped(\n declaration,\n `'${name}' is declared as something with no document shape`,\n );\n }\n\n /** `type X = ...` — registered under X when it has a shape of its own, else transparent. */\n private resolveAlias(name: string, alias: ts.TypeAliasDeclaration, ownerName: string): TypeRef {\n if (this.registered.has(name)) {\n return this.types.get(name)?.unionRefNames.length\n ? TypeRef.union(this.types.get(name)!.unionRefNames)\n : TypeRef.ref(name);\n }\n\n if (ts.isUnionTypeNode(alias.type)) {\n const resolved = this.resolve(alias.type, ownerName);\n if (resolved.kind === 'enum') {\n this.registered.add(name);\n this.types.set(\n name,\n new DocumentedType(\n name,\n JsDoc.read(alias).description,\n [],\n resolved.enumValues,\n [],\n undefined,\n undefined,\n ),\n );\n return TypeRef.ref(name);\n }\n return resolved;\n }\n\n if (ts.isTypeLiteralNode(alias.type)) {\n return this.registerNamedObject(name, alias.type, alias);\n }\n return this.resolve(alias.type, ownerName);\n }\n\n /** A TS `enum` of string members — the one non-union enum shape a document can carry. */\n private registerStringEnum(name: string, declaration: ts.EnumDeclaration): TypeRef {\n if (this.registered.has(name)) {\n return TypeRef.ref(name);\n }\n const values: string[] = [];\n for (const member of declaration.members) {\n if (member.initializer && ts.isStringLiteral(member.initializer)) {\n values.push(member.initializer.text);\n }\n }\n if (values.length !== declaration.members.length) {\n return this.recordUnmapped(\n declaration,\n `enum '${name}' has members that are not string literals`,\n );\n }\n this.registered.add(name);\n this.types.set(\n name,\n new DocumentedType(\n name,\n JsDoc.read(declaration).description,\n [],\n values,\n [],\n undefined,\n undefined,\n ),\n );\n return TypeRef.ref(name);\n }\n\n /**\n * Register a named object shape, RESERVING THE NAME BEFORE walking its fields. That order is the\n * whole cycle story: a type that refers back to itself meets `registered.has(name)` on the second\n * visit and resolves to a `$ref`, so the walk terminates with no counter and no truncation.\n */\n private registerNamedObject(\n name: string,\n shape: ts.InterfaceDeclaration | ts.ClassDeclaration | ts.TypeLiteralNode,\n docSource?: ts.Node,\n ): TypeRef {\n if (this.registered.has(name)) {\n return TypeRef.ref(name);\n }\n this.registered.add(name);\n\n const fields: DocumentedField[] = [];\n let indexSignature: TypeRef | undefined;\n for (const member of shape.members) {\n if (ts.isIndexSignatureDeclaration(member)) {\n indexSignature = this.resolve(member.type, name);\n continue;\n }\n const field = this.fieldOf(member, name);\n if (field !== undefined) {\n fields.push(field);\n }\n }\n\n this.types.set(\n name,\n new DocumentedType(\n name,\n JsDoc.read(docSource ?? shape).description,\n fields,\n [],\n [],\n undefined,\n indexSignature,\n ),\n );\n return TypeRef.ref(name);\n }\n\n /**\n * An inline `{ ... }`. It has no name to `$ref`, so it is registered under an OWNER-DERIVED one\n * (`Parent.field`) — a renderer needs a target, and a name derived from where the shape is\n * written is the only honest one available.\n *\n * A self-referential anonymous type is cut HERE, by NODE IDENTITY. It cannot be a `$ref` (there\n * is no declared name to point at) and it cannot be expanded (it would never end), so it is\n * recorded as unmapped and the walk returns.\n */\n private resolveAnonymousObject(node: ts.TypeLiteralNode, ownerName: string): TypeRef {\n if (this.expandingAnonymous.has(node)) {\n return this.recordUnmapped(\n node,\n 'a self-referential ANONYMOUS object type has no name a renderer could $ref; give it a name',\n );\n }\n const indexOnly =\n node.members.length === 1 && ts.isIndexSignatureDeclaration(node.members[0]);\n if (indexOnly) {\n const signature = node.members[0] as ts.IndexSignatureDeclaration;\n return TypeRef.openMap(this.resolve(signature.type, ownerName));\n }\n\n this.expandingAnonymous.add(node);\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions -- the stack entry must be dropped whatever the walk does\n try {\n return this.registerNamedObject(ownerName, node);\n } finally {\n this.expandingAnonymous.delete(node);\n }\n }\n\n /** ONE property of a DTO — its type, its optionality, its prose and its numeric constraints. */\n private fieldOf(\n member: ts.TypeElement | ts.ClassElement,\n ownerName: string,\n ): DocumentedField | undefined {\n if (!ts.isPropertySignature(member) && !ts.isPropertyDeclaration(member)) {\n return undefined;\n }\n if (!ts.isIdentifier(member.name) && !ts.isStringLiteral(member.name)) {\n return undefined;\n }\n const name = member.name.text;\n if (member.type === undefined) {\n return undefined;\n }\n\n const optional =\n member.questionToken !== undefined || TypeResolver.declaresUndefined(member.type);\n const nullable = TypeResolver.declaresNull(member.type);\n\n let type = this.resolve(member.type, `${ownerName}.${name}`);\n if (TypeResolver.hasDecorator(member, INT_DECORATOR)) {\n type = TypeResolver.markInteger(type);\n }\n\n const doc = JsDoc.read(member);\n const min = this.numericArgument(member, MIN_DECORATOR);\n const max = this.numericArgument(member, MAX_DECORATOR);\n this.assertNumericConstraintsFit(member, name, type, min, max);\n\n return new DocumentedField(\n name,\n type,\n optional,\n nullable,\n doc.description,\n doc.mcp,\n doc.format,\n min,\n max,\n doc.mcpHeader,\n );\n }\n\n /**\n * `@WpMin` / `@WpMax` on a non-numeric field is a BUILD FAILURE, not a warning. A minimum on a\n * string is not something a renderer can emit sensibly, and a document that silently dropped it\n * would publish a contract weaker than the one its author wrote down.\n */\n private assertNumericConstraintsFit(\n member: ts.Node,\n name: string,\n type: TypeRef,\n min: number | undefined,\n max: number | undefined,\n ): void {\n if (min === undefined && max === undefined) {\n return;\n }\n const numeric = type.isNumeric() || (type.kind === 'array' && type.items!.isNumeric());\n if (numeric) {\n return;\n }\n throw new ApiDocExtractionError(\n `@${MIN_DECORATOR}/@${MAX_DECORATOR} on non-numeric field '${name}'`,\n SourceLocation.of(member),\n 'Put the constraint on a `number` / `Integer` field, or drop it.',\n );\n }\n\n /** `@WpInt()` decorates the FIELD, so the integer flag is pushed onto the right leaf. */\n // webpieces-disable no-function-outside-class -- private static helper of this class\n private static markInteger(type: TypeRef): TypeRef {\n if (type.kind === 'array') {\n return TypeRef.array(type.items!.asInteger());\n }\n if (type.kind === 'openMap') {\n return TypeRef.openMap(type.values!.asInteger());\n }\n return type.asInteger();\n }\n\n // webpieces-disable no-function-outside-class -- private static helper of this class\n private static declaresUndefined(node: ts.TypeNode): boolean {\n return (\n ts.isUnionTypeNode(node) &&\n node.types.some((t: ts.TypeNode) => t.kind === ts.SyntaxKind.UndefinedKeyword)\n );\n }\n\n // webpieces-disable no-function-outside-class -- private static helper of this class\n private static declaresNull(node: ts.TypeNode): boolean {\n return (\n ts.isUnionTypeNode(node) &&\n node.types.some(\n (t: ts.TypeNode) =>\n t.kind === ts.SyntaxKind.NullKeyword ||\n (ts.isLiteralTypeNode(t) && t.literal.kind === ts.SyntaxKind.NullKeyword),\n )\n );\n }\n\n // webpieces-disable no-function-outside-class -- private static helper of this class\n private static hasDecorator(node: ts.Node, decoratorName: string): boolean {\n return TypeResolver.decoratorCall(node, decoratorName) !== undefined;\n }\n\n // webpieces-disable no-function-outside-class -- private static helper of this class\n private static decoratorCall(\n node: ts.Node,\n decoratorName: string,\n ): ts.CallExpression | undefined {\n const decorators = ts.canHaveDecorators(node) ? (ts.getDecorators(node) ?? []) : [];\n for (const decorator of decorators) {\n const call = decorator.expression;\n if (\n ts.isCallExpression(call) &&\n ts.isIdentifier(call.expression) &&\n call.expression.text === decoratorName\n ) {\n return call;\n }\n }\n return undefined;\n }\n\n private numericArgument(node: ts.Node, decoratorName: string): number | undefined {\n const call = TypeResolver.decoratorCall(node, decoratorName);\n const argument = call?.arguments[0];\n if (argument === undefined) {\n return undefined;\n }\n if (ts.isNumericLiteral(argument)) {\n return Number(argument.text);\n }\n if (\n ts.isPrefixUnaryExpression(argument) &&\n argument.operator === ts.SyntaxKind.MinusToken &&\n ts.isNumericLiteral(argument.operand)\n ) {\n return -Number(argument.operand.text);\n }\n throw new ApiDocExtractionError(\n `@${decoratorName} argument is not a numeric literal: '${argument.getText()}'`,\n SourceLocation.of(argument),\n 'Write the bound as a numeric literal. A value only known at runtime cannot be published.',\n );\n }\n\n /** The declaration a type name points at, through imports and aliases. */\n private declarationOf(name: ts.EntityName): ts.Declaration | undefined {\n const symbol = this.checker.getSymbolAtLocation(name);\n const resolved =\n symbol !== undefined && (symbol.flags & ts.SymbolFlags.Alias) !== 0\n ? this.checker.getAliasedSymbol(symbol)\n : symbol;\n return resolved?.declarations?.[0];\n }\n\n private recordUnmapped(node: ts.Node, reason: string): TypeRef {\n const text = node.getText();\n this.unmapped.push(new UnmappedType(text, SourceLocation.of(node), reason));\n return TypeRef.unmapped(text);\n }\n}\n"]}
|
package/src/index.d.ts
CHANGED
|
@@ -11,5 +11,8 @@
|
|
|
11
11
|
export { ApiDocExtractor } from './extract/ApiDocExtractor';
|
|
12
12
|
export { ApiDocExtractionError } from './extract/ApiDocExtractionError';
|
|
13
13
|
export { ApiDocModel, DocumentedApiKey, DocumentedApiKeyCredential, DocumentedAuth, DocumentedEndpoint, DocumentedEndpointOptions, DocumentedField, DocumentedMcpTool, DocumentedType, UnionDiscriminator, UnmappedType, } from './model/ApiDocModel';
|
|
14
|
+
export { McpRenderError } from './render/McpRenderError';
|
|
15
|
+
export { McpSchemaRenderer } from './render/McpSchemaRenderer';
|
|
16
|
+
export { McpToolDefinition } from './render/McpToolDefinition';
|
|
14
17
|
export { TypeRef } from './model/TypeRef';
|
|
15
18
|
export type { PrimitiveKind, TypeRefKind } from './model/TypeRef';
|
package/src/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.TypeRef = exports.UnmappedType = exports.UnionDiscriminator = exports.DocumentedType = exports.DocumentedMcpTool = exports.DocumentedField = exports.DocumentedEndpointOptions = exports.DocumentedEndpoint = exports.DocumentedAuth = exports.DocumentedApiKeyCredential = exports.DocumentedApiKey = exports.ApiDocModel = exports.ApiDocExtractionError = exports.ApiDocExtractor = void 0;
|
|
3
|
+
exports.TypeRef = exports.McpToolDefinition = exports.McpSchemaRenderer = exports.McpRenderError = exports.UnmappedType = exports.UnionDiscriminator = exports.DocumentedType = exports.DocumentedMcpTool = exports.DocumentedField = exports.DocumentedEndpointOptions = exports.DocumentedEndpoint = exports.DocumentedAuth = exports.DocumentedApiKeyCredential = exports.DocumentedApiKey = exports.ApiDocModel = exports.ApiDocExtractionError = exports.ApiDocExtractor = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* `@webpieces/api-doc-model` — read a webpieces API contract with the TypeScript compiler API and
|
|
6
6
|
* produce ONE in-memory {@link ApiDocModel}.
|
|
@@ -27,6 +27,12 @@ Object.defineProperty(exports, "DocumentedMcpTool", { enumerable: true, get: fun
|
|
|
27
27
|
Object.defineProperty(exports, "DocumentedType", { enumerable: true, get: function () { return ApiDocModel_1.DocumentedType; } });
|
|
28
28
|
Object.defineProperty(exports, "UnionDiscriminator", { enumerable: true, get: function () { return ApiDocModel_1.UnionDiscriminator; } });
|
|
29
29
|
Object.defineProperty(exports, "UnmappedType", { enumerable: true, get: function () { return ApiDocModel_1.UnmappedType; } });
|
|
30
|
+
var McpRenderError_1 = require("./render/McpRenderError");
|
|
31
|
+
Object.defineProperty(exports, "McpRenderError", { enumerable: true, get: function () { return McpRenderError_1.McpRenderError; } });
|
|
32
|
+
var McpSchemaRenderer_1 = require("./render/McpSchemaRenderer");
|
|
33
|
+
Object.defineProperty(exports, "McpSchemaRenderer", { enumerable: true, get: function () { return McpSchemaRenderer_1.McpSchemaRenderer; } });
|
|
34
|
+
var McpToolDefinition_1 = require("./render/McpToolDefinition");
|
|
35
|
+
Object.defineProperty(exports, "McpToolDefinition", { enumerable: true, get: function () { return McpToolDefinition_1.McpToolDefinition; } });
|
|
30
36
|
var TypeRef_1 = require("./model/TypeRef");
|
|
31
37
|
Object.defineProperty(exports, "TypeRef", { enumerable: true, get: function () { return TypeRef_1.TypeRef; } });
|
|
32
38
|
//# sourceMappingURL=index.js.map
|
package/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../packages/docs/api-doc-model/src/index.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;;GASG;AACH,6DAA4D;AAAnD,kHAAA,eAAe,OAAA;AACxB,yEAAwE;AAA/D,8HAAA,qBAAqB,OAAA;AAC9B,mDAY6B;AAXzB,0GAAA,WAAW,OAAA;AACX,+GAAA,gBAAgB,OAAA;AAChB,yHAAA,0BAA0B,OAAA;AAC1B,6GAAA,cAAc,OAAA;AACd,iHAAA,kBAAkB,OAAA;AAClB,wHAAA,yBAAyB,OAAA;AACzB,8GAAA,eAAe,OAAA;AACf,gHAAA,iBAAiB,OAAA;AACjB,6GAAA,cAAc,OAAA;AACd,iHAAA,kBAAkB,OAAA;AAClB,2GAAA,YAAY,OAAA;AAEhB,2CAA0C;AAAjC,kGAAA,OAAO,OAAA","sourcesContent":["/**\n * `@webpieces/api-doc-model` — read a webpieces API contract with the TypeScript compiler API and\n * produce ONE in-memory {@link ApiDocModel}.\n *\n * This is the single extraction pass both the OpenAPI documents and the MCP tool list (#982) are\n * rendered from. It emits nothing itself, and it takes every decorator NAME it matches on from the\n * real `@webpieces/core-util` symbol — so renaming a decorator is a compile error here rather than a\n * literal that quietly stops matching and empties a document (issue #1001). See\n * `responsibilities.md` for why that import is not the coupling it looks like.\n */\nexport { ApiDocExtractor } from './extract/ApiDocExtractor';\nexport { ApiDocExtractionError } from './extract/ApiDocExtractionError';\nexport {\n ApiDocModel,\n DocumentedApiKey,\n DocumentedApiKeyCredential,\n DocumentedAuth,\n DocumentedEndpoint,\n DocumentedEndpointOptions,\n DocumentedField,\n DocumentedMcpTool,\n DocumentedType,\n UnionDiscriminator,\n UnmappedType,\n} from './model/ApiDocModel';\nexport { TypeRef } from './model/TypeRef';\nexport type { PrimitiveKind, TypeRefKind } from './model/TypeRef';\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../packages/docs/api-doc-model/src/index.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;;GASG;AACH,6DAA4D;AAAnD,kHAAA,eAAe,OAAA;AACxB,yEAAwE;AAA/D,8HAAA,qBAAqB,OAAA;AAC9B,mDAY6B;AAXzB,0GAAA,WAAW,OAAA;AACX,+GAAA,gBAAgB,OAAA;AAChB,yHAAA,0BAA0B,OAAA;AAC1B,6GAAA,cAAc,OAAA;AACd,iHAAA,kBAAkB,OAAA;AAClB,wHAAA,yBAAyB,OAAA;AACzB,8GAAA,eAAe,OAAA;AACf,gHAAA,iBAAiB,OAAA;AACjB,6GAAA,cAAc,OAAA;AACd,iHAAA,kBAAkB,OAAA;AAClB,2GAAA,YAAY,OAAA;AAEhB,0DAAyD;AAAhD,gHAAA,cAAc,OAAA;AACvB,gEAA+D;AAAtD,sHAAA,iBAAiB,OAAA;AAC1B,gEAA+D;AAAtD,sHAAA,iBAAiB,OAAA;AAC1B,2CAA0C;AAAjC,kGAAA,OAAO,OAAA","sourcesContent":["/**\n * `@webpieces/api-doc-model` — read a webpieces API contract with the TypeScript compiler API and\n * produce ONE in-memory {@link ApiDocModel}.\n *\n * This is the single extraction pass both the OpenAPI documents and the MCP tool list (#982) are\n * rendered from. It emits nothing itself, and it takes every decorator NAME it matches on from the\n * real `@webpieces/core-util` symbol — so renaming a decorator is a compile error here rather than a\n * literal that quietly stops matching and empties a document (issue #1001). See\n * `responsibilities.md` for why that import is not the coupling it looks like.\n */\nexport { ApiDocExtractor } from './extract/ApiDocExtractor';\nexport { ApiDocExtractionError } from './extract/ApiDocExtractionError';\nexport {\n ApiDocModel,\n DocumentedApiKey,\n DocumentedApiKeyCredential,\n DocumentedAuth,\n DocumentedEndpoint,\n DocumentedEndpointOptions,\n DocumentedField,\n DocumentedMcpTool,\n DocumentedType,\n UnionDiscriminator,\n UnmappedType,\n} from './model/ApiDocModel';\nexport { McpRenderError } from './render/McpRenderError';\nexport { McpSchemaRenderer } from './render/McpSchemaRenderer';\nexport { McpToolDefinition } from './render/McpToolDefinition';\nexport { TypeRef } from './model/TypeRef';\nexport type { PrimitiveKind, TypeRefKind } from './model/TypeRef';\n"]}
|
|
@@ -62,6 +62,17 @@ export declare class DocumentedField {
|
|
|
62
62
|
readonly min: number | undefined;
|
|
63
63
|
/** `@WpMax(n)` — numeric fields only; anything else is a build failure. */
|
|
64
64
|
readonly max: number | undefined;
|
|
65
|
+
/**
|
|
66
|
+
* The `@mcpHeader <token>` JSDoc tag — the MCP 2026 SEP-2243 header this PRIMITIVE field is
|
|
67
|
+
* mirrored into (`Mcp-Param-{token}`). Undefined for every field that is not mirrored, which
|
|
68
|
+
* is nearly all of them.
|
|
69
|
+
*
|
|
70
|
+
* It is documentation and therefore lives in JSDoc, next to the sentence describing the
|
|
71
|
+
* field, rather than in a decorator argument. The runtime spells it `WpMcpHeader` inside
|
|
72
|
+
* `@WpDtoField`; the two are proved identical by the equivalence gate (#983) before #984
|
|
73
|
+
* deletes the decorator spelling.
|
|
74
|
+
*/
|
|
75
|
+
readonly mcpHeader: string | undefined;
|
|
65
76
|
constructor(name: string, type: TypeRef,
|
|
66
77
|
/**
|
|
67
78
|
* OPTIONAL (`name?: string`) — the property may be ABSENT. Distinguished from
|
|
@@ -84,7 +95,18 @@ export declare class DocumentedField {
|
|
|
84
95
|
/** `@WpMin(n)` — numeric fields only; anything else is a build failure. */
|
|
85
96
|
min: number | undefined,
|
|
86
97
|
/** `@WpMax(n)` — numeric fields only; anything else is a build failure. */
|
|
87
|
-
max: number | undefined
|
|
98
|
+
max: number | undefined,
|
|
99
|
+
/**
|
|
100
|
+
* The `@mcpHeader <token>` JSDoc tag — the MCP 2026 SEP-2243 header this PRIMITIVE field is
|
|
101
|
+
* mirrored into (`Mcp-Param-{token}`). Undefined for every field that is not mirrored, which
|
|
102
|
+
* is nearly all of them.
|
|
103
|
+
*
|
|
104
|
+
* It is documentation and therefore lives in JSDoc, next to the sentence describing the
|
|
105
|
+
* field, rather than in a decorator argument. The runtime spells it `WpMcpHeader` inside
|
|
106
|
+
* `@WpDtoField`; the two are proved identical by the equivalence gate (#983) before #984
|
|
107
|
+
* deletes the decorator spelling.
|
|
108
|
+
*/
|
|
109
|
+
mcpHeader: string | undefined);
|
|
88
110
|
}
|
|
89
111
|
/** One named type reachable from a contract: an object DTO, a string-literal enum, or a union. */
|
|
90
112
|
export declare class DocumentedType {
|
package/src/model/ApiDocModel.js
CHANGED
|
@@ -53,6 +53,7 @@ class DocumentedField {
|
|
|
53
53
|
format;
|
|
54
54
|
min;
|
|
55
55
|
max;
|
|
56
|
+
mcpHeader;
|
|
56
57
|
constructor(name, type,
|
|
57
58
|
/**
|
|
58
59
|
* OPTIONAL (`name?: string`) — the property may be ABSENT. Distinguished from
|
|
@@ -75,7 +76,18 @@ class DocumentedField {
|
|
|
75
76
|
/** `@WpMin(n)` — numeric fields only; anything else is a build failure. */
|
|
76
77
|
min,
|
|
77
78
|
/** `@WpMax(n)` — numeric fields only; anything else is a build failure. */
|
|
78
|
-
max
|
|
79
|
+
max,
|
|
80
|
+
/**
|
|
81
|
+
* The `@mcpHeader <token>` JSDoc tag — the MCP 2026 SEP-2243 header this PRIMITIVE field is
|
|
82
|
+
* mirrored into (`Mcp-Param-{token}`). Undefined for every field that is not mirrored, which
|
|
83
|
+
* is nearly all of them.
|
|
84
|
+
*
|
|
85
|
+
* It is documentation and therefore lives in JSDoc, next to the sentence describing the
|
|
86
|
+
* field, rather than in a decorator argument. The runtime spells it `WpMcpHeader` inside
|
|
87
|
+
* `@WpDtoField`; the two are proved identical by the equivalence gate (#983) before #984
|
|
88
|
+
* deletes the decorator spelling.
|
|
89
|
+
*/
|
|
90
|
+
mcpHeader) {
|
|
79
91
|
this.name = name;
|
|
80
92
|
this.type = type;
|
|
81
93
|
this.optional = optional;
|
|
@@ -85,6 +97,7 @@ class DocumentedField {
|
|
|
85
97
|
this.format = format;
|
|
86
98
|
this.min = min;
|
|
87
99
|
this.max = max;
|
|
100
|
+
this.mcpHeader = mcpHeader;
|
|
88
101
|
}
|
|
89
102
|
}
|
|
90
103
|
exports.DocumentedField = DocumentedField;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ApiDocModel.js","sourceRoot":"","sources":["../../../../../../packages/docs/api-doc-model/src/model/ApiDocModel.ts"],"names":[],"mappings":"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","sourcesContent":["import { TypeRef } from './TypeRef';\n\n/**\n * The model classes. Every one of them is a CLASS with an explicit constructor per `CLAUDE.md` §1 —\n * these are data-only structures, and a renderer (#982) builds nothing, it only reads.\n *\n * Nothing in this file imports anything but {@link TypeRef}: the package depends on `typescript` and\n * NOTHING else, so it can be pointed at any upstream project's contract. One app-specific import\n * here would end that, which is why `responsibilities.md` states the constraint rather than leaving\n * it to be discovered.\n */\n\n/** A type the extractor could not represent. RECORDED, never dropped — #982's guard needs a name. */\nexport class UnmappedType {\n constructor(\n /** The verbatim TypeScript type text, e.g. `Map<string, Widget>`. */\n readonly typeText: string,\n /** Pointer-style location: `path/to/File.ts:12:5`. */\n readonly location: string,\n /** Why it could not be mapped, in one sentence a renderer can print. */\n readonly reason: string,\n ) {}\n}\n\n/** The DERIVED discriminator of a union — never invented, only observed. See {@link DocumentedType}. */\nexport class UnionDiscriminator {\n constructor(\n /** The property every branch carries. */\n readonly propertyName: string,\n /** branch type name -> the single string literal that branch's property holds. */\n readonly branchValues: ReadonlyMap<string, string>,\n ) {}\n}\n\n/** One field of one DTO. */\nexport class DocumentedField {\n constructor(\n readonly name: string,\n readonly type: TypeRef,\n /**\n * OPTIONAL (`name?: string`) — the property may be ABSENT. Distinguished from\n * {@link nullable} on purpose: `{}` and `{name: null}` are different wire documents, and a\n * renderer that conflates them emits a schema that rejects one of them.\n */\n readonly optional: boolean,\n /** NULLABLE (`name: string | null`) — the property is present and may hold `null`. */\n readonly nullable: boolean,\n /** The JSDoc body, links flattened. Empty string when undocumented. */\n readonly description: string,\n /**\n * The `@mcp` block tag — an OPTIONAL agent-facing override. Undefined means \"no override\",\n * and a renderer falls back to {@link description}; the fallback is NOT applied here so a\n * renderer can tell a deliberate agent-facing sentence from a reused human one.\n */\n readonly mcpDescription: string | undefined,\n /** The `@format` tag, lifted onto the SCALAR (on an array, onto the ITEM). */\n readonly format: string | undefined,\n /** `@WpMin(n)` — numeric fields only; anything else is a build failure. */\n readonly min: number | undefined,\n /** `@WpMax(n)` — numeric fields only; anything else is a build failure. */\n readonly max: number | undefined,\n ) {}\n}\n\n/** One named type reachable from a contract: an object DTO, a string-literal enum, or a union. */\nexport class DocumentedType {\n constructor(\n readonly name: string,\n readonly description: string,\n /** Object shape. Empty for an enum or a union. */\n readonly fields: readonly DocumentedField[],\n /** Set for a string-literal union that has a name. */\n readonly enumValues: readonly string[],\n /** Set for a union of named object types. */\n readonly unionRefNames: readonly string[],\n /** Set only when EVERY branch carries the same property typed as one string literal. */\n readonly discriminator: UnionDiscriminator | undefined,\n /** An index signature (`[k: string]: X`) — the OPEN-MAP half of an object that also has fields. */\n readonly indexSignatureValue: TypeRef | undefined,\n ) {}\n}\n\n/** `@Endpoint(httpMethod, path, operation, kind, options?)`'s LAST argument, as a document sees it. */\nexport class DocumentedEndpointOptions {\n constructor(\n readonly formPost: boolean,\n /** `calledBy` — REQUIRED by the decorator for `external`, absent otherwise. */\n readonly calledBy: string | undefined,\n readonly callerKind: string | undefined,\n ) {}\n}\n\n/**\n * The `@WpMcpTool(...)` declaration, when the method carries one — the TWO facts the source cannot\n * otherwise state, and nothing else.\n *\n * `description` is deliberately NOT read off the decorator. The method's JSDoc is the description, for\n * the agent and for the partner alike, byte-identical: two authored copies of one paragraph is the\n * two-spellings shim, and its failure mode is concrete — the partner reads the JSDoc in the OpenAPI\n * document while the agent reads the decorator string in `tools/list`, and they drift the first time\n * somebody edits one. (The field still exists on the decorator; #984 deletes it across its 29 call\n * sites. Nothing here reads it, so nothing here depends on a field that is about to disappear.)\n *\n * The three side-effect hints are not read either: they are COMPUTED from the endpoint's `operation`\n * by `mcpHintsForOperation` in `@webpieces/core-util`, which is the one place that mapping lives.\n * `READ | WRITE_IDEMPOTENT | WRITE` already says whether repeating a call is safe, so a hand-declared\n * hint would be a second answer to a question the contract has answered.\n */\nexport class DocumentedMcpTool {\n constructor(\n /**\n * The STABLE protocol name. Deliberately independent of the method name, because renaming a\n * method must not break a saved agent workflow.\n */\n readonly name: string,\n ) {}\n}\n\n/**\n * ONE credential of an api-key regime, PARSED — `{ in: 'header', name: 'x-api-key' }` or\n * `{ in: 'bearer' }`.\n *\n * Parsed rather than left as source text because it is the one auth argument a renderer must turn\n * into a STRUCTURE: an OpenAPI `securityScheme` is `{type: apiKey, in, name}` or\n * `{type: http, scheme: bearer}`, and those are different documents. A renderer handed the string\n * `\"{ in: 'header', name: 'x-api-key' }\"` would have to parse TypeScript to emit either one, which\n * is this package's job and not a renderer's.\n */\nexport class DocumentedApiKeyCredential {\n constructor(\n /** `header` or `bearer`, verbatim from the declaration. */\n readonly location: string,\n /** The header name. Undefined for `bearer`, whose location IS `Authorization`. */\n readonly name: string | undefined,\n /** The prose a docs site renders on its authorization card. */\n readonly description: string | undefined,\n ) {}\n}\n\n/** `@WpAuthApiKey(regime, credentials)`, parsed. See {@link DocumentedApiKeyCredential}. */\nexport class DocumentedApiKey {\n constructor(\n readonly regime: string,\n /**\n * Every credential the regime requires, IN DECLARATION ORDER. They are an AND — all of them\n * are presented together — and the order is the order a published document lists them in.\n */\n readonly credentials: readonly DocumentedApiKeyCredential[],\n ) {}\n}\n\n/** WHICH credential an endpoint demands — `@WpAuthPublic`, `@WpAuthJwt`, … — verbatim from the source. */\nexport class DocumentedAuth {\n constructor(\n /** The decorator name as written, e.g. `WpAuthJwt`. */\n readonly decorator: string,\n /** Every argument's text, verbatim and in order. Empty for `@WpAuthPublic()`. */\n readonly argumentTexts: readonly string[],\n /**\n * The PARSED api-key declaration, set only for `@WpAuthApiKey`. Every other decorator's\n * argument is prose or a role list that a document quotes rather than restructures, so\n * {@link argumentTexts} is all they need — see {@link DocumentedApiKeyCredential} for why\n * this one is different.\n */\n readonly apiKey: DocumentedApiKey | undefined,\n ) {}\n}\n\n/** One `@Endpoint` method of one contract. */\nexport class DocumentedEndpoint {\n constructor(\n readonly methodName: string,\n /**\n * `GET` or `POST`, constant-folded from `@Endpoint`'s FIRST argument. A document cannot be\n * written without it — the verb is the key an operation hangs under in `paths`.\n */\n readonly httpMethod: string,\n /** The path, constant-folded. A const that cannot be folded is a HARD FAILURE, never a guess. */\n readonly path: string,\n /**\n * `read` | `write-idempotent` | `write`, verbatim. The SIDE-EFFECT contract, which is\n * independent of the verb: webpieces POSTs a read. A renderer publishes it rather than\n * inferring safety from the verb, which for this framework would be wrong.\n */\n readonly operation: string,\n /** `rpc` | `cloudtasks` | `cron` | `external`, verbatim — this package invents no taxonomy. */\n readonly kind: string,\n /**\n * `{ hidden: true }` — this method is absent from the CUSTOMER document. It stays in the\n * private one, and in the MCP one when it is a tool. WHICH documents the CONTRACT feeds at\n * all is a different, class-level decision; see {@link ApiDocModel.apiTypes}.\n */\n readonly hidden: boolean,\n /** `{ openWorld: true }` — this operation may touch systems outside this service. */\n readonly openWorld: boolean,\n readonly options: DocumentedEndpointOptions,\n readonly auth: DocumentedAuth | undefined,\n readonly mcpTool: DocumentedMcpTool | undefined,\n /** `@WpMcpAuthJwt(...)`'s argument text, when present. */\n readonly mcpAuthText: string | undefined,\n /** `@MaskLog({...})` — field name -> mask mode. */\n readonly maskLog: ReadonlyMap<string, string>,\n readonly description: string,\n /** The `@mcp` override. See {@link DocumentedField.mcpDescription}. */\n readonly mcpDescription: string | undefined,\n readonly request: TypeRef | undefined,\n readonly response: TypeRef | undefined,\n ) {}\n}\n\n/** ONE extraction pass over ONE contract file. Both #982's renderers read exactly this. */\nexport class ApiDocModel {\n constructor(\n /** The contract class name, e.g. `SaveApi`. */\n readonly contractName: string,\n /**\n * WHICH generated documents this contract feeds — `svc-to-svc`, `external-customer`, `mcp`,\n * verbatim from `@ApiType(...)`, defaulting to `svc-to-svc` alone when it declares nothing.\n *\n * A named list rather than a falsy default, because the grant has to be the TOKEN: a default\n * that reached customers would publish a contract whose author typed nothing about it.\n */\n readonly apiTypes: readonly string[],\n /** `@ApiPath(...)`, constant-folded. */\n readonly basePath: string,\n /** The JSDoc on the contract class, links flattened. */\n readonly description: string,\n readonly endpoints: readonly DocumentedEndpoint[],\n /** Every named type reachable from the endpoints, by name. A `$ref` target for a renderer. */\n readonly types: ReadonlyMap<string, DocumentedType>,\n /** Everything that could not be represented — recorded, not dropped. */\n readonly unmapped: readonly UnmappedType[],\n ) {}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ApiDocModel.js","sourceRoot":"","sources":["../../../../../../packages/docs/api-doc-model/src/model/ApiDocModel.ts"],"names":[],"mappings":"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","sourcesContent":["import { TypeRef } from './TypeRef';\n\n/**\n * The model classes. Every one of them is a CLASS with an explicit constructor per `CLAUDE.md` §1 —\n * these are data-only structures, and a renderer (#982) builds nothing, it only reads.\n *\n * Nothing in this file imports anything but {@link TypeRef}: the package depends on `typescript` and\n * NOTHING else, so it can be pointed at any upstream project's contract. One app-specific import\n * here would end that, which is why `responsibilities.md` states the constraint rather than leaving\n * it to be discovered.\n */\n\n/** A type the extractor could not represent. RECORDED, never dropped — #982's guard needs a name. */\nexport class UnmappedType {\n constructor(\n /** The verbatim TypeScript type text, e.g. `Map<string, Widget>`. */\n readonly typeText: string,\n /** Pointer-style location: `path/to/File.ts:12:5`. */\n readonly location: string,\n /** Why it could not be mapped, in one sentence a renderer can print. */\n readonly reason: string,\n ) {}\n}\n\n/** The DERIVED discriminator of a union — never invented, only observed. See {@link DocumentedType}. */\nexport class UnionDiscriminator {\n constructor(\n /** The property every branch carries. */\n readonly propertyName: string,\n /** branch type name -> the single string literal that branch's property holds. */\n readonly branchValues: ReadonlyMap<string, string>,\n ) {}\n}\n\n/** One field of one DTO. */\nexport class DocumentedField {\n constructor(\n readonly name: string,\n readonly type: TypeRef,\n /**\n * OPTIONAL (`name?: string`) — the property may be ABSENT. Distinguished from\n * {@link nullable} on purpose: `{}` and `{name: null}` are different wire documents, and a\n * renderer that conflates them emits a schema that rejects one of them.\n */\n readonly optional: boolean,\n /** NULLABLE (`name: string | null`) — the property is present and may hold `null`. */\n readonly nullable: boolean,\n /** The JSDoc body, links flattened. Empty string when undocumented. */\n readonly description: string,\n /**\n * The `@mcp` block tag — an OPTIONAL agent-facing override. Undefined means \"no override\",\n * and a renderer falls back to {@link description}; the fallback is NOT applied here so a\n * renderer can tell a deliberate agent-facing sentence from a reused human one.\n */\n readonly mcpDescription: string | undefined,\n /** The `@format` tag, lifted onto the SCALAR (on an array, onto the ITEM). */\n readonly format: string | undefined,\n /** `@WpMin(n)` — numeric fields only; anything else is a build failure. */\n readonly min: number | undefined,\n /** `@WpMax(n)` — numeric fields only; anything else is a build failure. */\n readonly max: number | undefined,\n /**\n * The `@mcpHeader <token>` JSDoc tag — the MCP 2026 SEP-2243 header this PRIMITIVE field is\n * mirrored into (`Mcp-Param-{token}`). Undefined for every field that is not mirrored, which\n * is nearly all of them.\n *\n * It is documentation and therefore lives in JSDoc, next to the sentence describing the\n * field, rather than in a decorator argument. The runtime spells it `WpMcpHeader` inside\n * `@WpDtoField`; the two are proved identical by the equivalence gate (#983) before #984\n * deletes the decorator spelling.\n */\n readonly mcpHeader: string | undefined,\n ) {}\n}\n\n/** One named type reachable from a contract: an object DTO, a string-literal enum, or a union. */\nexport class DocumentedType {\n constructor(\n readonly name: string,\n readonly description: string,\n /** Object shape. Empty for an enum or a union. */\n readonly fields: readonly DocumentedField[],\n /** Set for a string-literal union that has a name. */\n readonly enumValues: readonly string[],\n /** Set for a union of named object types. */\n readonly unionRefNames: readonly string[],\n /** Set only when EVERY branch carries the same property typed as one string literal. */\n readonly discriminator: UnionDiscriminator | undefined,\n /** An index signature (`[k: string]: X`) — the OPEN-MAP half of an object that also has fields. */\n readonly indexSignatureValue: TypeRef | undefined,\n ) {}\n}\n\n/** `@Endpoint(httpMethod, path, operation, kind, options?)`'s LAST argument, as a document sees it. */\nexport class DocumentedEndpointOptions {\n constructor(\n readonly formPost: boolean,\n /** `calledBy` — REQUIRED by the decorator for `external`, absent otherwise. */\n readonly calledBy: string | undefined,\n readonly callerKind: string | undefined,\n ) {}\n}\n\n/**\n * The `@WpMcpTool(...)` declaration, when the method carries one — the TWO facts the source cannot\n * otherwise state, and nothing else.\n *\n * `description` is deliberately NOT read off the decorator. The method's JSDoc is the description, for\n * the agent and for the partner alike, byte-identical: two authored copies of one paragraph is the\n * two-spellings shim, and its failure mode is concrete — the partner reads the JSDoc in the OpenAPI\n * document while the agent reads the decorator string in `tools/list`, and they drift the first time\n * somebody edits one. (The field still exists on the decorator; #984 deletes it across its 29 call\n * sites. Nothing here reads it, so nothing here depends on a field that is about to disappear.)\n *\n * The three side-effect hints are not read either: they are COMPUTED from the endpoint's `operation`\n * by `mcpHintsForOperation` in `@webpieces/core-util`, which is the one place that mapping lives.\n * `READ | WRITE_IDEMPOTENT | WRITE` already says whether repeating a call is safe, so a hand-declared\n * hint would be a second answer to a question the contract has answered.\n */\nexport class DocumentedMcpTool {\n constructor(\n /**\n * The STABLE protocol name. Deliberately independent of the method name, because renaming a\n * method must not break a saved agent workflow.\n */\n readonly name: string,\n ) {}\n}\n\n/**\n * ONE credential of an api-key regime, PARSED — `{ in: 'header', name: 'x-api-key' }` or\n * `{ in: 'bearer' }`.\n *\n * Parsed rather than left as source text because it is the one auth argument a renderer must turn\n * into a STRUCTURE: an OpenAPI `securityScheme` is `{type: apiKey, in, name}` or\n * `{type: http, scheme: bearer}`, and those are different documents. A renderer handed the string\n * `\"{ in: 'header', name: 'x-api-key' }\"` would have to parse TypeScript to emit either one, which\n * is this package's job and not a renderer's.\n */\nexport class DocumentedApiKeyCredential {\n constructor(\n /** `header` or `bearer`, verbatim from the declaration. */\n readonly location: string,\n /** The header name. Undefined for `bearer`, whose location IS `Authorization`. */\n readonly name: string | undefined,\n /** The prose a docs site renders on its authorization card. */\n readonly description: string | undefined,\n ) {}\n}\n\n/** `@WpAuthApiKey(regime, credentials)`, parsed. See {@link DocumentedApiKeyCredential}. */\nexport class DocumentedApiKey {\n constructor(\n readonly regime: string,\n /**\n * Every credential the regime requires, IN DECLARATION ORDER. They are an AND — all of them\n * are presented together — and the order is the order a published document lists them in.\n */\n readonly credentials: readonly DocumentedApiKeyCredential[],\n ) {}\n}\n\n/** WHICH credential an endpoint demands — `@WpAuthPublic`, `@WpAuthJwt`, … — verbatim from the source. */\nexport class DocumentedAuth {\n constructor(\n /** The decorator name as written, e.g. `WpAuthJwt`. */\n readonly decorator: string,\n /** Every argument's text, verbatim and in order. Empty for `@WpAuthPublic()`. */\n readonly argumentTexts: readonly string[],\n /**\n * The PARSED api-key declaration, set only for `@WpAuthApiKey`. Every other decorator's\n * argument is prose or a role list that a document quotes rather than restructures, so\n * {@link argumentTexts} is all they need — see {@link DocumentedApiKeyCredential} for why\n * this one is different.\n */\n readonly apiKey: DocumentedApiKey | undefined,\n ) {}\n}\n\n/** One `@Endpoint` method of one contract. */\nexport class DocumentedEndpoint {\n constructor(\n readonly methodName: string,\n /**\n * `GET` or `POST`, constant-folded from `@Endpoint`'s FIRST argument. A document cannot be\n * written without it — the verb is the key an operation hangs under in `paths`.\n */\n readonly httpMethod: string,\n /** The path, constant-folded. A const that cannot be folded is a HARD FAILURE, never a guess. */\n readonly path: string,\n /**\n * `read` | `write-idempotent` | `write`, verbatim. The SIDE-EFFECT contract, which is\n * independent of the verb: webpieces POSTs a read. A renderer publishes it rather than\n * inferring safety from the verb, which for this framework would be wrong.\n */\n readonly operation: string,\n /** `rpc` | `cloudtasks` | `cron` | `external`, verbatim — this package invents no taxonomy. */\n readonly kind: string,\n /**\n * `{ hidden: true }` — this method is absent from the CUSTOMER document. It stays in the\n * private one, and in the MCP one when it is a tool. WHICH documents the CONTRACT feeds at\n * all is a different, class-level decision; see {@link ApiDocModel.apiTypes}.\n */\n readonly hidden: boolean,\n /** `{ openWorld: true }` — this operation may touch systems outside this service. */\n readonly openWorld: boolean,\n readonly options: DocumentedEndpointOptions,\n readonly auth: DocumentedAuth | undefined,\n readonly mcpTool: DocumentedMcpTool | undefined,\n /** `@WpMcpAuthJwt(...)`'s argument text, when present. */\n readonly mcpAuthText: string | undefined,\n /** `@MaskLog({...})` — field name -> mask mode. */\n readonly maskLog: ReadonlyMap<string, string>,\n readonly description: string,\n /** The `@mcp` override. See {@link DocumentedField.mcpDescription}. */\n readonly mcpDescription: string | undefined,\n readonly request: TypeRef | undefined,\n readonly response: TypeRef | undefined,\n ) {}\n}\n\n/** ONE extraction pass over ONE contract file. Both #982's renderers read exactly this. */\nexport class ApiDocModel {\n constructor(\n /** The contract class name, e.g. `SaveApi`. */\n readonly contractName: string,\n /**\n * WHICH generated documents this contract feeds — `svc-to-svc`, `external-customer`, `mcp`,\n * verbatim from `@ApiType(...)`, defaulting to `svc-to-svc` alone when it declares nothing.\n *\n * A named list rather than a falsy default, because the grant has to be the TOKEN: a default\n * that reached customers would publish a contract whose author typed nothing about it.\n */\n readonly apiTypes: readonly string[],\n /** `@ApiPath(...)`, constant-folded. */\n readonly basePath: string,\n /** The JSDoc on the contract class, links flattened. */\n readonly description: string,\n readonly endpoints: readonly DocumentedEndpoint[],\n /** Every named type reachable from the endpoints, by name. A `$ref` target for a renderer. */\n readonly types: ReadonlyMap<string, DocumentedType>,\n /** Everything that could not be represented — recorded, not dropped. */\n readonly unmapped: readonly UnmappedType[],\n ) {}\n}\n"]}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The ONE failure type the MCP renderer throws. A render either produces a COMPLETE set of tool
|
|
3
|
+
* definitions or throws this — it never emits a schema with a hole in it.
|
|
4
|
+
*
|
|
5
|
+
* An empty JSON Schema means "anything", so a field the renderer could not give a shape to would be
|
|
6
|
+
* published to agents as an unconstrained parameter. That is the same green-build-publishes-a-
|
|
7
|
+
* shapeless-field defect `SchemaRenderer`'s unmapped guard exists to stop, and here it is a THROW
|
|
8
|
+
* because the MCP projection has no document-level place to collect them into: a tool list is a flat
|
|
9
|
+
* array, and a tool with one shapeless parameter is a tool an agent will call wrongly.
|
|
10
|
+
*
|
|
11
|
+
* It carries `location` and `cure` as FIELDS, per `.claude/review/error-output.md`, and hand-numbers
|
|
12
|
+
* nothing. It is a sibling of `ApiDocExtractionError` rather than the same class because the two
|
|
13
|
+
* failures have different cures: an extraction failure is answered by editing the CONTRACT, and a
|
|
14
|
+
* render failure by editing the contract OR by accepting that MCP's schema subset cannot carry that
|
|
15
|
+
* shape at all.
|
|
16
|
+
*/
|
|
17
|
+
export declare class McpRenderError extends Error {
|
|
18
|
+
/** `Contract.method` or `Dto.field` — the declaration to open, not a file offset. */
|
|
19
|
+
readonly location: string;
|
|
20
|
+
/** What to do instead, in one sentence. No numbering — the caller's renderer owns that. */
|
|
21
|
+
readonly cure: string;
|
|
22
|
+
constructor(message: string,
|
|
23
|
+
/** `Contract.method` or `Dto.field` — the declaration to open, not a file offset. */
|
|
24
|
+
location: string,
|
|
25
|
+
/** What to do instead, in one sentence. No numbering — the caller's renderer owns that. */
|
|
26
|
+
cure: string);
|
|
27
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.McpRenderError = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* The ONE failure type the MCP renderer throws. A render either produces a COMPLETE set of tool
|
|
6
|
+
* definitions or throws this — it never emits a schema with a hole in it.
|
|
7
|
+
*
|
|
8
|
+
* An empty JSON Schema means "anything", so a field the renderer could not give a shape to would be
|
|
9
|
+
* published to agents as an unconstrained parameter. That is the same green-build-publishes-a-
|
|
10
|
+
* shapeless-field defect `SchemaRenderer`'s unmapped guard exists to stop, and here it is a THROW
|
|
11
|
+
* because the MCP projection has no document-level place to collect them into: a tool list is a flat
|
|
12
|
+
* array, and a tool with one shapeless parameter is a tool an agent will call wrongly.
|
|
13
|
+
*
|
|
14
|
+
* It carries `location` and `cure` as FIELDS, per `.claude/review/error-output.md`, and hand-numbers
|
|
15
|
+
* nothing. It is a sibling of `ApiDocExtractionError` rather than the same class because the two
|
|
16
|
+
* failures have different cures: an extraction failure is answered by editing the CONTRACT, and a
|
|
17
|
+
* render failure by editing the contract OR by accepting that MCP's schema subset cannot carry that
|
|
18
|
+
* shape at all.
|
|
19
|
+
*/
|
|
20
|
+
class McpRenderError extends Error {
|
|
21
|
+
location;
|
|
22
|
+
cure;
|
|
23
|
+
constructor(message,
|
|
24
|
+
/** `Contract.method` or `Dto.field` — the declaration to open, not a file offset. */
|
|
25
|
+
location,
|
|
26
|
+
/** What to do instead, in one sentence. No numbering — the caller's renderer owns that. */
|
|
27
|
+
cure) {
|
|
28
|
+
super(`${message} (${location})`);
|
|
29
|
+
this.location = location;
|
|
30
|
+
this.cure = cure;
|
|
31
|
+
this.name = 'McpRenderError';
|
|
32
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
exports.McpRenderError = McpRenderError;
|
|
36
|
+
//# sourceMappingURL=McpRenderError.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"McpRenderError.js","sourceRoot":"","sources":["../../../../../../packages/docs/api-doc-model/src/render/McpRenderError.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;;;;;;;;GAeG;AACH,MAAa,cAAe,SAAQ,KAAK;IAIxB;IAEA;IALb,YACI,OAAe;IACf,qFAAqF;IAC5E,QAAgB;IACzB,2FAA2F;IAClF,IAAY;QAErB,KAAK,CAAC,GAAG,OAAO,KAAK,QAAQ,GAAG,CAAC,CAAC;QAJzB,aAAQ,GAAR,QAAQ,CAAQ;QAEhB,SAAI,GAAJ,IAAI,CAAQ;QAGrB,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;QAC7B,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACtD,CAAC;CACJ;AAZD,wCAYC","sourcesContent":["/**\n * The ONE failure type the MCP renderer throws. A render either produces a COMPLETE set of tool\n * definitions or throws this — it never emits a schema with a hole in it.\n *\n * An empty JSON Schema means \"anything\", so a field the renderer could not give a shape to would be\n * published to agents as an unconstrained parameter. That is the same green-build-publishes-a-\n * shapeless-field defect `SchemaRenderer`'s unmapped guard exists to stop, and here it is a THROW\n * because the MCP projection has no document-level place to collect them into: a tool list is a flat\n * array, and a tool with one shapeless parameter is a tool an agent will call wrongly.\n *\n * It carries `location` and `cure` as FIELDS, per `.claude/review/error-output.md`, and hand-numbers\n * nothing. It is a sibling of `ApiDocExtractionError` rather than the same class because the two\n * failures have different cures: an extraction failure is answered by editing the CONTRACT, and a\n * render failure by editing the contract OR by accepting that MCP's schema subset cannot carry that\n * shape at all.\n */\nexport class McpRenderError extends Error {\n constructor(\n message: string,\n /** `Contract.method` or `Dto.field` — the declaration to open, not a file offset. */\n readonly location: string,\n /** What to do instead, in one sentence. No numbering — the caller's renderer owns that. */\n readonly cure: string,\n ) {\n super(`${message} (${location})`);\n this.name = 'McpRenderError';\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n"]}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { ApiDocModel } from '../model/ApiDocModel';
|
|
2
|
+
import { McpToolDefinition } from './McpToolDefinition';
|
|
3
|
+
/**
|
|
4
|
+
* `ApiDocModel` -> the MCP tool list, in exactly the shape `DtoSchemaBuilder` produces at boot from
|
|
5
|
+
* reflect-metadata.
|
|
6
|
+
*
|
|
7
|
+
* ## Why this exists at all, and why it is READ-ONLY
|
|
8
|
+
*
|
|
9
|
+
* #984 wants the MCP runtime off reflect-metadata, which deletes every erasure-repair argument of
|
|
10
|
+
* `@WpDtoField` — `required`, `arrayItems`, `integer`, `minimum`, `maximum`, `enumValues`. That is a
|
|
11
|
+
* behaviour change on a live protocol surface, and its failure mode is silent: a tool whose input
|
|
12
|
+
* schema quietly loses a `required` entry or an `enum` starts failing agent calls at RUNTIME, not at
|
|
13
|
+
* build. This renderer plus the equivalence spec beside it turn "the compiler can obviously replace
|
|
14
|
+
* those arguments" from a plausible argument into a MEASURED one (#983).
|
|
15
|
+
*
|
|
16
|
+
* ## It deliberately reproduces `DtoSchemaBuilder`, defect-for-defect
|
|
17
|
+
*
|
|
18
|
+
* Where MCP's `ApiJsonSchema` subset could express MORE than the runtime does, this renderer emits
|
|
19
|
+
* what the RUNTIME emits, and the gate's report names the difference. Three concrete cases:
|
|
20
|
+
*
|
|
21
|
+
* - **NULLABLE is not rendered.** `ApiJsonSchema.type` holds one string, so `type: [T, "null"]` is
|
|
22
|
+
* not expressible in the type the runtime publishes. The compiler can SEE `externalId: string | null`
|
|
23
|
+
* and the runtime cannot; emitting it here would fail the gate on a difference that is a runtime
|
|
24
|
+
* capability GAP rather than an extractor bug, and hide the real mismatches under it.
|
|
25
|
+
* - **A nested DTO is INLINED**, with the FIELD's prose on it, because `buildAt` inlines and then
|
|
26
|
+
* `fieldSchema` overwrites `description`. MCP has no `$ref`.
|
|
27
|
+
* - **A bound on an ARRAY of numbers** is put on the ITEM, where OpenAPI puts it; the runtime cannot
|
|
28
|
+
* express it at all (`@WpDtoField` rejects numeric constraints on a non-`Number` field).
|
|
29
|
+
*
|
|
30
|
+
* Making the comparison agree by WEAKENING it would destroy the only thing the gate is for, so every
|
|
31
|
+
* one of those is a documented, deliberate reproduction rather than a relaxation.
|
|
32
|
+
*/
|
|
33
|
+
export declare class McpSchemaRenderer {
|
|
34
|
+
private readonly model;
|
|
35
|
+
constructor(model: ApiDocModel);
|
|
36
|
+
/** Every `@WpMcpTool` method of the contract, in declaration order. */
|
|
37
|
+
render(): readonly McpToolDefinition[];
|
|
38
|
+
private tool;
|
|
39
|
+
/**
|
|
40
|
+
* `operation` verbatim from the model, mapped back onto the REAL constant.
|
|
41
|
+
*
|
|
42
|
+
* A `switch` and not a cast, because the model carries the operation as a string and a cast would
|
|
43
|
+
* hand `mcpHintsForOperation` a value it has no case for — which, for a function whose three arms
|
|
44
|
+
* are exhaustive, means falling off the end and publishing a tool with NO hints.
|
|
45
|
+
*/
|
|
46
|
+
private static operationOf;
|
|
47
|
+
/** A tool's input/output schema: always a closed object, exactly as `DtoSchemaBuilder.build` is. */
|
|
48
|
+
private rootSchema;
|
|
49
|
+
private namedType;
|
|
50
|
+
/**
|
|
51
|
+
* One object DTO. CLOSED (`additionalProperties: false`), `required` only when non-empty — both
|
|
52
|
+
* exactly as `DtoSchemaBuilder.buildAt` writes them, because that is what is being compared.
|
|
53
|
+
*
|
|
54
|
+
* The cycle stop is `parents`, and it THROWS rather than truncating, which is again what the
|
|
55
|
+
* runtime does: an inline schema cannot express a recursive DTO, and one that silently stopped a
|
|
56
|
+
* level down would publish a shape the server does not accept.
|
|
57
|
+
*/
|
|
58
|
+
private objectSchema;
|
|
59
|
+
/**
|
|
60
|
+
* One FIELD: its type, then the prose and the constraints that hang off the field.
|
|
61
|
+
*
|
|
62
|
+
* The ORDER matters and mirrors `fieldSchema`: the type is built first and `description` is
|
|
63
|
+
* written over whatever the type produced, so a nested DTO carries the FIELD's sentence rather
|
|
64
|
+
* than the DTO's. `@WpMin` / `@WpMax` land on the numeric LEAF — on an array, on the item — for
|
|
65
|
+
* the same reason `SchemaRenderer` puts them there: a `minimum` on an array means nothing.
|
|
66
|
+
*/
|
|
67
|
+
private fieldSchema;
|
|
68
|
+
/**
|
|
69
|
+
* `@mcpHeader` mirrors a PRIMITIVE parameter into `Mcp-Param-{name}` (MCP 2026 SEP-2243). The
|
|
70
|
+
* three conditions are the runtime's, restated against the compiler's view of the field, so a
|
|
71
|
+
* declaration the server would reject at boot fails the document build instead.
|
|
72
|
+
*/
|
|
73
|
+
private static assertHeaderFits;
|
|
74
|
+
/** One resolved type, with no field-level prose or constraints on it. */
|
|
75
|
+
private typeSchema;
|
|
76
|
+
/** A named type: a string enum becomes `enum`, an object DTO is INLINED (MCP has no `$ref`). */
|
|
77
|
+
private referencedSchema;
|
|
78
|
+
private static primitive;
|
|
79
|
+
}
|