@webpieces/api-doc-model 0.4.807 → 0.4.809

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.
@@ -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 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"]}
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 doc.mcpHeader,\n SourceLocation.of(member),\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"]}
@@ -72,6 +72,16 @@ export declare class DocumentedField {
72
72
  * fact at all.
73
73
  */
74
74
  readonly mcpHeader: string | undefined;
75
+ /**
76
+ * Pointer-style `path/to/File.ts:12:5` for the property declaration itself.
77
+ *
78
+ * A renderer never needs it — it publishes a schema, not a file offset. The build RULES do:
79
+ * `api-rules-for-openapi` refuses a field whose value type is `unknown`, and a refusal that
80
+ * cannot say WHERE costs the author a grep over every DTO the contract reaches. It is
81
+ * carried on the FIELD rather than recomputed because only the extractor still has the
82
+ * syntax node, and a second reader deriving it would be a second answer to "where is this".
83
+ */
84
+ readonly location: string;
75
85
  constructor(name: string, type: TypeRef,
76
86
  /**
77
87
  * OPTIONAL (`name?: string`) — the property may be ABSENT. Distinguished from
@@ -104,7 +114,17 @@ export declare class DocumentedField {
104
114
  * field, rather than in a decorator argument — and since #984 it is the only spelling of the
105
115
  * fact at all.
106
116
  */
107
- mcpHeader: string | undefined);
117
+ mcpHeader: string | undefined,
118
+ /**
119
+ * Pointer-style `path/to/File.ts:12:5` for the property declaration itself.
120
+ *
121
+ * A renderer never needs it — it publishes a schema, not a file offset. The build RULES do:
122
+ * `api-rules-for-openapi` refuses a field whose value type is `unknown`, and a refusal that
123
+ * cannot say WHERE costs the author a grep over every DTO the contract reaches. It is
124
+ * carried on the FIELD rather than recomputed because only the extractor still has the
125
+ * syntax node, and a second reader deriving it would be a second answer to "where is this".
126
+ */
127
+ location: string);
108
128
  }
109
129
  /** One named type reachable from a contract: an object DTO, a string-literal enum, or a union. */
110
130
  export declare class DocumentedType {
@@ -266,6 +286,17 @@ export declare class DocumentedEndpoint {
266
286
  readonly options: DocumentedEndpointOptions;
267
287
  readonly auth: DocumentedAuth | undefined;
268
288
  readonly mcpTool: DocumentedMcpTool | undefined;
289
+ /**
290
+ * `@InvalidEndpointForMcp('<reason>')`'s reason, when the method carries one — this endpoint
291
+ * is PERMANENTLY outside MCP and was never a tool candidate.
292
+ *
293
+ * Distinct from "has no `@WpMcpTool`", which only says "not a tool yet". A renderer must not
294
+ * report one of these as a SKIPPED tool, and `api-rules-for-mcp` stops asking a method with
295
+ * one whether it could be served — the declaration is the answer. Carrying the reason rather
296
+ * than a boolean is the point: the rule restates the list of exclusions with their arguments
297
+ * on every run.
298
+ */
299
+ readonly invalidForMcp: string | undefined;
269
300
  /** `@WpMcpAuthJwt(...)`'s argument text, when present. */
270
301
  readonly mcpAuthText: string | undefined;
271
302
  /** `@MaskLog({...})` — field name -> mask mode. */
@@ -299,6 +330,17 @@ export declare class DocumentedEndpoint {
299
330
  hidden: boolean,
300
331
  /** `{ openWorld: true }` — this operation may touch systems outside this service. */
301
332
  openWorld: boolean, options: DocumentedEndpointOptions, auth: DocumentedAuth | undefined, mcpTool: DocumentedMcpTool | undefined,
333
+ /**
334
+ * `@InvalidEndpointForMcp('<reason>')`'s reason, when the method carries one — this endpoint
335
+ * is PERMANENTLY outside MCP and was never a tool candidate.
336
+ *
337
+ * Distinct from "has no `@WpMcpTool`", which only says "not a tool yet". A renderer must not
338
+ * report one of these as a SKIPPED tool, and `api-rules-for-mcp` stops asking a method with
339
+ * one whether it could be served — the declaration is the answer. Carrying the reason rather
340
+ * than a boolean is the point: the rule restates the list of exclusions with their arguments
341
+ * on every run.
342
+ */
343
+ invalidForMcp: string | undefined,
302
344
  /** `@WpMcpAuthJwt(...)`'s argument text, when present. */
303
345
  mcpAuthText: string | undefined,
304
346
  /** `@MaskLog({...})` — field name -> mask mode. */
@@ -54,6 +54,7 @@ class DocumentedField {
54
54
  min;
55
55
  max;
56
56
  mcpHeader;
57
+ location;
57
58
  constructor(name, type,
58
59
  /**
59
60
  * OPTIONAL (`name?: string`) — the property may be ABSENT. Distinguished from
@@ -86,7 +87,17 @@ class DocumentedField {
86
87
  * field, rather than in a decorator argument — and since #984 it is the only spelling of the
87
88
  * fact at all.
88
89
  */
89
- mcpHeader) {
90
+ mcpHeader,
91
+ /**
92
+ * Pointer-style `path/to/File.ts:12:5` for the property declaration itself.
93
+ *
94
+ * A renderer never needs it — it publishes a schema, not a file offset. The build RULES do:
95
+ * `api-rules-for-openapi` refuses a field whose value type is `unknown`, and a refusal that
96
+ * cannot say WHERE costs the author a grep over every DTO the contract reaches. It is
97
+ * carried on the FIELD rather than recomputed because only the extractor still has the
98
+ * syntax node, and a second reader deriving it would be a second answer to "where is this".
99
+ */
100
+ location) {
90
101
  this.name = name;
91
102
  this.type = type;
92
103
  this.optional = optional;
@@ -97,6 +108,7 @@ class DocumentedField {
97
108
  this.min = min;
98
109
  this.max = max;
99
110
  this.mcpHeader = mcpHeader;
111
+ this.location = location;
100
112
  }
101
113
  }
102
114
  exports.DocumentedField = DocumentedField;
@@ -249,6 +261,7 @@ class DocumentedEndpoint {
249
261
  options;
250
262
  auth;
251
263
  mcpTool;
264
+ invalidForMcp;
252
265
  mcpAuthText;
253
266
  maskLog;
254
267
  description;
@@ -279,6 +292,17 @@ class DocumentedEndpoint {
279
292
  hidden,
280
293
  /** `{ openWorld: true }` — this operation may touch systems outside this service. */
281
294
  openWorld, options, auth, mcpTool,
295
+ /**
296
+ * `@InvalidEndpointForMcp('<reason>')`'s reason, when the method carries one — this endpoint
297
+ * is PERMANENTLY outside MCP and was never a tool candidate.
298
+ *
299
+ * Distinct from "has no `@WpMcpTool`", which only says "not a tool yet". A renderer must not
300
+ * report one of these as a SKIPPED tool, and `api-rules-for-mcp` stops asking a method with
301
+ * one whether it could be served — the declaration is the answer. Carrying the reason rather
302
+ * than a boolean is the point: the rule restates the list of exclusions with their arguments
303
+ * on every run.
304
+ */
305
+ invalidForMcp,
282
306
  /** `@WpMcpAuthJwt(...)`'s argument text, when present. */
283
307
  mcpAuthText,
284
308
  /** `@MaskLog({...})` — field name -> mask mode. */
@@ -295,6 +319,7 @@ class DocumentedEndpoint {
295
319
  this.options = options;
296
320
  this.auth = auth;
297
321
  this.mcpTool = mcpTool;
322
+ this.invalidForMcp = invalidForMcp;
298
323
  this.mcpAuthText = mcpAuthText;
299
324
  this.maskLog = maskLog;
300
325
  this.description = description;
@@ -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 * 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 — and since #984 it is the only spelling of the\n * fact at all.\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('search_stores')` declaration, when the method carries one — the ONE fact the\n * source cannot otherwise state, and nothing else.\n *\n * `description` used to sit on the decorator too. The method's JSDoc is the description, for the\n * 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. #984 deleted it, which left the decorator holding one field, so it takes the\n * name as a plain string.\n *\n * The three side-effect hints are COMPUTED from the endpoint's `operation` by `mcpHintsForOperation`\n * in `@webpieces/core-util`, which is the one place that mapping lives — `READ | WRITE_IDEMPOTENT |\n * WRITE` already says whether repeating a call is safe, so a hand-declared hint would be a second\n * answer to a question the contract has answered. `openWorldHint` is `@Endpoint`'s `openWorld`.\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":";;;AAEA;;;;;;;;GAQG;AAEH,qGAAqG;AACrG,MAAa,YAAY;IAGR;IAEA;IAEA;IANb;IACI,qEAAqE;IAC5D,QAAgB;IACzB,sDAAsD;IAC7C,QAAgB;IACzB,wEAAwE;IAC/D,MAAc;QAJd,aAAQ,GAAR,QAAQ,CAAQ;QAEhB,aAAQ,GAAR,QAAQ,CAAQ;QAEhB,WAAM,GAAN,MAAM,CAAQ;IACxB,CAAC;CACP;AATD,oCASC;AAED,wGAAwG;AACxG,MAAa,kBAAkB;IAGd;IAEA;IAJb;IACI,yCAAyC;IAChC,YAAoB;IAC7B,kFAAkF;IACzE,YAAyC;QAFzC,iBAAY,GAAZ,YAAY,CAAQ;QAEpB,iBAAY,GAAZ,YAAY,CAA6B;IACnD,CAAC;CACP;AAPD,gDAOC;AAED,4BAA4B;AAC5B,MAAa,eAAe;IAEX;IACA;IAMA;IAEA;IAEA;IAMA;IAEA;IAEA;IAEA;IAUA;IAUA;IA5Cb,YACa,IAAY,EACZ,IAAa;IACtB;;;;OAIG;IACM,QAAiB;IAC1B,sFAAsF;IAC7E,QAAiB;IAC1B,uEAAuE;IAC9D,WAAmB;IAC5B;;;;OAIG;IACM,cAAkC;IAC3C,8EAA8E;IACrE,MAA0B;IACnC,2EAA2E;IAClE,GAAuB;IAChC,2EAA2E;IAClE,GAAuB;IAChC;;;;;;;;OAQG;IACM,SAA6B;IACtC;;;;;;;;OAQG;IACM,QAAgB;QA3ChB,SAAI,GAAJ,IAAI,CAAQ;QACZ,SAAI,GAAJ,IAAI,CAAS;QAMb,aAAQ,GAAR,QAAQ,CAAS;QAEjB,aAAQ,GAAR,QAAQ,CAAS;QAEjB,gBAAW,GAAX,WAAW,CAAQ;QAMnB,mBAAc,GAAd,cAAc,CAAoB;QAElC,WAAM,GAAN,MAAM,CAAoB;QAE1B,QAAG,GAAH,GAAG,CAAoB;QAEvB,QAAG,GAAH,GAAG,CAAoB;QAUvB,cAAS,GAAT,SAAS,CAAoB;QAU7B,aAAQ,GAAR,QAAQ,CAAQ;IAC1B,CAAC;CACP;AA/CD,0CA+CC;AAED,kGAAkG;AAClG,MAAa,cAAc;IAEV;IACA;IAEA;IAEA;IAEA;IAEA;IAEA;IAZb,YACa,IAAY,EACZ,WAAmB;IAC5B,kDAAkD;IACzC,MAAkC;IAC3C,sDAAsD;IAC7C,UAA6B;IACtC,6CAA6C;IACpC,aAAgC;IACzC,wFAAwF;IAC/E,aAA6C;IACtD,mGAAmG;IAC1F,mBAAwC;QAXxC,SAAI,GAAJ,IAAI,CAAQ;QACZ,gBAAW,GAAX,WAAW,CAAQ;QAEnB,WAAM,GAAN,MAAM,CAA4B;QAElC,eAAU,GAAV,UAAU,CAAmB;QAE7B,kBAAa,GAAb,aAAa,CAAmB;QAEhC,kBAAa,GAAb,aAAa,CAAgC;QAE7C,wBAAmB,GAAnB,mBAAmB,CAAqB;IAClD,CAAC;CACP;AAfD,wCAeC;AAED,uGAAuG;AACvG,MAAa,yBAAyB;IAErB;IAEA;IACA;IAJb,YACa,QAAiB;IAC1B,+EAA+E;IACtE,QAA4B,EAC5B,UAA8B;QAH9B,aAAQ,GAAR,QAAQ,CAAS;QAEjB,aAAQ,GAAR,QAAQ,CAAoB;QAC5B,eAAU,GAAV,UAAU,CAAoB;IACxC,CAAC;CACP;AAPD,8DAOC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAa,iBAAiB;IAMb;IALb;IACI;;;OAGG;IACM,IAAY;QAAZ,SAAI,GAAJ,IAAI,CAAQ;IACtB,CAAC;CACP;AARD,8CAQC;AAED;;;;;;;;;GASG;AACH,MAAa,0BAA0B;IAGtB;IAEA;IAEA;IANb;IACI,2DAA2D;IAClD,QAAgB;IACzB,kFAAkF;IACzE,IAAwB;IACjC,+DAA+D;IACtD,WAA+B;QAJ/B,aAAQ,GAAR,QAAQ,CAAQ;QAEhB,SAAI,GAAJ,IAAI,CAAoB;QAExB,gBAAW,GAAX,WAAW,CAAoB;IACzC,CAAC;CACP;AATD,gEASC;AAED,4FAA4F;AAC5F,MAAa,gBAAgB;IAEZ;IAKA;IANb,YACa,MAAc;IACvB;;;OAGG;IACM,WAAkD;QALlD,WAAM,GAAN,MAAM,CAAQ;QAKd,gBAAW,GAAX,WAAW,CAAuC;IAC5D,CAAC;CACP;AATD,4CASC;AAED,0GAA0G;AAC1G,MAAa,cAAc;IAGV;IAEA;IAOA;IAXb;IACI,uDAAuD;IAC9C,SAAiB;IAC1B,iFAAiF;IACxE,aAAgC;IACzC;;;;;OAKG;IACM,MAAoC;QATpC,cAAS,GAAT,SAAS,CAAQ;QAEjB,kBAAa,GAAb,aAAa,CAAmB;QAOhC,WAAM,GAAN,MAAM,CAA8B;IAC9C,CAAC;CACP;AAdD,wCAcC;AAED,8CAA8C;AAC9C,MAAa,kBAAkB;IAEd;IAKA;IAEA;IAMA;IAEA;IAMA;IAEA;IACA;IACA;IACA;IAWA;IAEA;IAEA;IACA;IAEA;IACA;IACA;IA/Cb,YACa,UAAkB;IAC3B;;;OAGG;IACM,UAAkB;IAC3B,iGAAiG;IACxF,IAAY;IACrB;;;;OAIG;IACM,SAAiB;IAC1B,+FAA+F;IACtF,IAAY;IACrB;;;;OAIG;IACM,MAAe;IACxB,qFAAqF;IAC5E,SAAkB,EAClB,OAAkC,EAClC,IAAgC,EAChC,OAAsC;IAC/C;;;;;;;;;OASG;IACM,aAAiC;IAC1C,0DAA0D;IACjD,WAA+B;IACxC,mDAAmD;IAC1C,OAAoC,EACpC,WAAmB;IAC5B,uEAAuE;IAC9D,cAAkC,EAClC,OAA4B,EAC5B,QAA6B;QA9C7B,eAAU,GAAV,UAAU,CAAQ;QAKlB,eAAU,GAAV,UAAU,CAAQ;QAElB,SAAI,GAAJ,IAAI,CAAQ;QAMZ,cAAS,GAAT,SAAS,CAAQ;QAEjB,SAAI,GAAJ,IAAI,CAAQ;QAMZ,WAAM,GAAN,MAAM,CAAS;QAEf,cAAS,GAAT,SAAS,CAAS;QAClB,YAAO,GAAP,OAAO,CAA2B;QAClC,SAAI,GAAJ,IAAI,CAA4B;QAChC,YAAO,GAAP,OAAO,CAA+B;QAWtC,kBAAa,GAAb,aAAa,CAAoB;QAEjC,gBAAW,GAAX,WAAW,CAAoB;QAE/B,YAAO,GAAP,OAAO,CAA6B;QACpC,gBAAW,GAAX,WAAW,CAAQ;QAEnB,mBAAc,GAAd,cAAc,CAAoB;QAClC,YAAO,GAAP,OAAO,CAAqB;QAC5B,aAAQ,GAAR,QAAQ,CAAqB;IACvC,CAAC;CACP;AAlDD,gDAkDC;AAED,2FAA2F;AAC3F,MAAa,WAAW;IAGP;IAQA;IAEA;IAEA;IACA;IAEA;IAEA;IAnBb;IACI,+CAA+C;IACtC,YAAoB;IAC7B;;;;;;OAMG;IACM,QAA2B;IACpC,wCAAwC;IAC/B,QAAgB;IACzB,wDAAwD;IAC/C,WAAmB,EACnB,SAAwC;IACjD,8FAA8F;IACrF,KAA0C;IACnD,wEAAwE;IAC/D,QAAiC;QAjBjC,iBAAY,GAAZ,YAAY,CAAQ;QAQpB,aAAQ,GAAR,QAAQ,CAAmB;QAE3B,aAAQ,GAAR,QAAQ,CAAQ;QAEhB,gBAAW,GAAX,WAAW,CAAQ;QACnB,cAAS,GAAT,SAAS,CAA+B;QAExC,UAAK,GAAL,KAAK,CAAqC;QAE1C,aAAQ,GAAR,QAAQ,CAAyB;IAC3C,CAAC;CACP;AAtBD,kCAsBC","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 — and since #984 it is the only spelling of the\n * fact at all.\n */\n readonly mcpHeader: string | undefined,\n /**\n * Pointer-style `path/to/File.ts:12:5` for the property declaration itself.\n *\n * A renderer never needs it — it publishes a schema, not a file offset. The build RULES do:\n * `api-rules-for-openapi` refuses a field whose value type is `unknown`, and a refusal that\n * cannot say WHERE costs the author a grep over every DTO the contract reaches. It is\n * carried on the FIELD rather than recomputed because only the extractor still has the\n * syntax node, and a second reader deriving it would be a second answer to \"where is this\".\n */\n readonly location: string,\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('search_stores')` declaration, when the method carries one — the ONE fact the\n * source cannot otherwise state, and nothing else.\n *\n * `description` used to sit on the decorator too. The method's JSDoc is the description, for the\n * 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. #984 deleted it, which left the decorator holding one field, so it takes the\n * name as a plain string.\n *\n * The three side-effect hints are COMPUTED from the endpoint's `operation` by `mcpHintsForOperation`\n * in `@webpieces/core-util`, which is the one place that mapping lives — `READ | WRITE_IDEMPOTENT |\n * WRITE` already says whether repeating a call is safe, so a hand-declared hint would be a second\n * answer to a question the contract has answered. `openWorldHint` is `@Endpoint`'s `openWorld`.\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 /**\n * `@InvalidEndpointForMcp('<reason>')`'s reason, when the method carries one — this endpoint\n * is PERMANENTLY outside MCP and was never a tool candidate.\n *\n * Distinct from \"has no `@WpMcpTool`\", which only says \"not a tool yet\". A renderer must not\n * report one of these as a SKIPPED tool, and `api-rules-for-mcp` stops asking a method with\n * one whether it could be served — the declaration is the answer. Carrying the reason rather\n * than a boolean is the point: the rule restates the list of exclusions with their arguments\n * on every run.\n */\n readonly invalidForMcp: string | 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"]}
@@ -60,8 +60,10 @@ export declare class McpSchemaRenderer {
60
60
  *
61
61
  * ## Why an unrenderable tool is REPORTED here rather than throwing
62
62
  *
63
- * Some shapes have no MCP schema at all — a discriminated union, a recursive DTO and that is a
64
- * limit of the PROTOCOL, not a defect in a contract that is otherwise perfectly good HTTP. Such a
63
+ * Some shapes have no MCP schema at all — a recursive DTO, an undocumented tool, a request that
64
+ * is not a named object and the first of those is a limit of the PROTOCOL rather than a defect
65
+ * in a contract that is otherwise perfectly good HTTP. (A DISCRIMINATED UNION used to be on this
66
+ * list and no longer is: #1009 taught `ApiJsonSchema` `oneOf`, so one publishes.) Such a
65
67
  * tool was never servable: the reflect-metadata runtime refused it too, for its own reasons. So
66
68
  * failing the whole document build over one would stop a repo publishing its OpenAPI over a tool
67
69
  * nobody could ever have called.
@@ -82,7 +84,17 @@ export declare class McpSchemaRenderer {
82
84
  * are exhaustive, means falling off the end and publishing a tool with NO hints.
83
85
  */
84
86
  private static operationOf;
85
- /** A tool's input/output schema: always a CLOSED object, because MCP publishes objects. */
87
+ /**
88
+ * A tool's input/output schema: always a CLOSED OBJECT, because MCP publishes objects — and
89
+ * because a union at the ROOT of a tool schema is refused by the function-calling APIs that
90
+ * consume it. Both OpenAI and Anthropic reject a top-level `oneOf`/`anyOf`/`allOf`, and a server
91
+ * sends its WHOLE tool list on every request, so one such tool makes every request 400 and bricks
92
+ * the session — not just that tool. Nested composition, inside a property, is fine.
93
+ *
94
+ * The build-time rule `no-root-union-api-type` refuses the same shape across every `@ApiPath`
95
+ * contract in the workspace, `@ApiType` or not. This is the renderer's own backstop, so a catalog
96
+ * can never carry one even if it is reached some other way.
97
+ */
86
98
  private rootSchema;
87
99
  private namedType;
88
100
  /**
@@ -94,6 +106,29 @@ export declare class McpSchemaRenderer {
94
106
  * server does not accept.
95
107
  */
96
108
  private objectSchema;
109
+ /**
110
+ * A UNION, as `oneOf` with its branches INLINE and its DERIVED discriminator.
111
+ *
112
+ * MCP tool schemas are JSON Schema 2020-12 — the same dialect OpenAPI 3.1 uses — so `oneOf` was
113
+ * never the obstacle; the obstacle was this repo's own subset, which had no spelling for it
114
+ * (#1009). The shape written here MIRRORS `SchemaRenderer.union` in `@webpieces/openapi-generator`
115
+ * branch for branch, because a union has ONE published spelling and that renderer is the
116
+ * reference implementation of it. The only difference is the absence of `$ref`: a tool schema is
117
+ * inline, so each branch is rendered in full and the discriminator maps to branch NAMES.
118
+ *
119
+ * `discriminator` is written ONLY when the model DERIVED one. A union TypeScript itself cannot
120
+ * narrow is published as a bare `oneOf` rather than with an invented discriminator — claiming a
121
+ * narrowing the source does not have is worse than admitting there is none.
122
+ */
123
+ private unionSchema;
124
+ /**
125
+ * A FIELD whose type is a union: the model registers `type X = A | B` as its OWN entry carrying
126
+ * the derived discriminator, while the field holds a bare list of branch names. Rendering that
127
+ * list directly would publish the `oneOf` and silently DROP the discriminator — the one part of a
128
+ * union a client needs to narrow on — so the alias is looked up by its branch list first. This is
129
+ * the same lookup `SchemaRenderer.namedUnion` does to emit its `$ref`.
130
+ */
131
+ private fieldUnion;
97
132
  /**
98
133
  * One FIELD: its type, then the prose and the constraints that hang off the field.
99
134
  *
@@ -84,8 +84,10 @@ class McpSchemaRenderer {
84
84
  *
85
85
  * ## Why an unrenderable tool is REPORTED here rather than throwing
86
86
  *
87
- * Some shapes have no MCP schema at all — a discriminated union, a recursive DTO and that is a
88
- * limit of the PROTOCOL, not a defect in a contract that is otherwise perfectly good HTTP. Such a
87
+ * Some shapes have no MCP schema at all — a recursive DTO, an undocumented tool, a request that
88
+ * is not a named object and the first of those is a limit of the PROTOCOL rather than a defect
89
+ * in a contract that is otherwise perfectly good HTTP. (A DISCRIMINATED UNION used to be on this
90
+ * list and no longer is: #1009 taught `ApiJsonSchema` `oneOf`, so one publishes.) Such a
89
91
  * tool was never servable: the reflect-metadata runtime refused it too, for its own reasons. So
90
92
  * failing the whole document build over one would stop a repo publishing its OpenAPI over a tool
91
93
  * nobody could ever have called.
@@ -152,13 +154,34 @@ class McpSchemaRenderer {
152
154
  throw new McpRenderError_1.McpRenderError(`@Endpoint declares operation '${endpoint.operation}', which has no MCP hints`, where, `Use one of the exported constants: ${core_util_1.READ}, ${core_util_1.WRITE_IDEMPOTENT}, ${core_util_1.WRITE}.`);
153
155
  }
154
156
  }
155
- /** A tool's input/output schema: always a CLOSED object, because MCP publishes objects. */
157
+ /**
158
+ * A tool's input/output schema: always a CLOSED OBJECT, because MCP publishes objects — and
159
+ * because a union at the ROOT of a tool schema is refused by the function-calling APIs that
160
+ * consume it. Both OpenAI and Anthropic reject a top-level `oneOf`/`anyOf`/`allOf`, and a server
161
+ * sends its WHOLE tool list on every request, so one such tool makes every request 400 and bricks
162
+ * the session — not just that tool. Nested composition, inside a property, is fine.
163
+ *
164
+ * The build-time rule `no-root-union-api-type` refuses the same shape across every `@ApiPath`
165
+ * contract in the workspace, `@ApiType` or not. This is the renderer's own backstop, so a catalog
166
+ * can never carry one even if it is reached some other way.
167
+ */
156
168
  rootSchema(ref, where, side) {
169
+ if (ref.kind === 'union') {
170
+ throw new McpRenderError_1.McpRenderError(`an MCP tool's ${side} is itself a union`, where, `Wrap it in a property of an object ${side} — a top-level oneOf is rejected by the ` +
171
+ 'OpenAI and Anthropic function-calling APIs, and one such tool 400s every ' +
172
+ 'request in the session.');
173
+ }
157
174
  if (ref.kind !== 'ref') {
158
175
  throw new McpRenderError_1.McpRenderError(`an MCP tool's ${side} is not a named DTO`, where, 'Give it a named interface or class. An inline or primitive ' +
159
176
  `${side} has no object schema, and MCP publishes objects.`);
160
177
  }
161
- return this.objectSchema(this.namedType(ref.refName, where), new Set());
178
+ const type = this.namedType(ref.refName, where);
179
+ if (type.unionRefNames.length > 0) {
180
+ throw new McpRenderError_1.McpRenderError(`an MCP tool's ${side} '${type.name}' is itself a union`, where, `Wrap it in a property of an object ${side} — a top-level oneOf is rejected by the ` +
181
+ 'OpenAI and Anthropic function-calling APIs, and one such tool 400s every ' +
182
+ 'request in the session.');
183
+ }
184
+ return this.objectSchema(type, new Set());
162
185
  }
163
186
  namedType(name, where) {
164
187
  const type = this.model.types.get(name);
@@ -181,7 +204,7 @@ class McpSchemaRenderer {
181
204
  'inline and has no $ref to close a loop with.');
182
205
  }
183
206
  if (type.unionRefNames.length > 0) {
184
- throw new McpRenderError_1.McpRenderError(`'${type.name}' is a union, which an MCP input schema cannot express`, type.name, 'Publish a single object shape to agents, or keep this contract off MCP.');
207
+ return this.unionSchema(type, parents);
185
208
  }
186
209
  if (type.indexSignatureValue !== undefined && type.fields.length > 0) {
187
210
  throw new McpRenderError_1.McpRenderError(`'${type.name}' has both named fields and an index signature`, type.name, 'Split the open map into a field of its own: a schema is either closed or a typed ' +
@@ -204,6 +227,59 @@ class McpSchemaRenderer {
204
227
  }
205
228
  return schema;
206
229
  }
230
+ /**
231
+ * A UNION, as `oneOf` with its branches INLINE and its DERIVED discriminator.
232
+ *
233
+ * MCP tool schemas are JSON Schema 2020-12 — the same dialect OpenAPI 3.1 uses — so `oneOf` was
234
+ * never the obstacle; the obstacle was this repo's own subset, which had no spelling for it
235
+ * (#1009). The shape written here MIRRORS `SchemaRenderer.union` in `@webpieces/openapi-generator`
236
+ * branch for branch, because a union has ONE published spelling and that renderer is the
237
+ * reference implementation of it. The only difference is the absence of `$ref`: a tool schema is
238
+ * inline, so each branch is rendered in full and the discriminator maps to branch NAMES.
239
+ *
240
+ * `discriminator` is written ONLY when the model DERIVED one. A union TypeScript itself cannot
241
+ * narrow is published as a bare `oneOf` rather than with an invented discriminator — claiming a
242
+ * narrowing the source does not have is worse than admitting there is none.
243
+ */
244
+ unionSchema(type, parents) {
245
+ const nested = new Set(parents);
246
+ nested.add(type.name);
247
+ const schema = new core_util_1.ApiJsonSchema();
248
+ schema.oneOf = type.unionRefNames.map((name) => this.objectSchema(this.namedType(name, type.name), nested));
249
+ if (type.description.trim() !== '') {
250
+ schema.description = type.description;
251
+ }
252
+ if (type.discriminator !== undefined) {
253
+ const mapping = {};
254
+ for (const branch of type.unionRefNames) {
255
+ const value = type.discriminator.branchValues.get(branch);
256
+ if (value !== undefined) {
257
+ mapping[value] = branch;
258
+ }
259
+ }
260
+ schema.discriminator = new core_util_1.ApiJsonSchemaDiscriminator(type.discriminator.propertyName, mapping);
261
+ }
262
+ return schema;
263
+ }
264
+ /**
265
+ * A FIELD whose type is a union: the model registers `type X = A | B` as its OWN entry carrying
266
+ * the derived discriminator, while the field holds a bare list of branch names. Rendering that
267
+ * list directly would publish the `oneOf` and silently DROP the discriminator — the one part of a
268
+ * union a client needs to narrow on — so the alias is looked up by its branch list first. This is
269
+ * the same lookup `SchemaRenderer.namedUnion` does to emit its `$ref`.
270
+ */
271
+ fieldUnion(branchNames, where, parents) {
272
+ const key = branchNames.join(',');
273
+ for (const name of this.model.types.keys()) {
274
+ const candidate = this.model.types.get(name);
275
+ if (candidate.unionRefNames.length > 0 && candidate.unionRefNames.join(',') === key) {
276
+ return this.unionSchema(candidate, parents);
277
+ }
278
+ }
279
+ const schema = new core_util_1.ApiJsonSchema();
280
+ schema.oneOf = branchNames.map((name) => this.objectSchema(this.namedType(name, where), parents));
281
+ return schema;
282
+ }
207
283
  /**
208
284
  * One FIELD: its type, then the prose and the constraints that hang off the field.
209
285
  *
@@ -288,7 +364,7 @@ class McpSchemaRenderer {
288
364
  case 'ref':
289
365
  return this.referencedSchema(ref.refName, where, parents);
290
366
  case 'union':
291
- throw new McpRenderError_1.McpRenderError('a union has no MCP input-schema shape', where, 'Publish one object shape to agents, or keep this method off MCP.');
367
+ return this.fieldUnion(ref.unionRefNames, where, parents);
292
368
  default:
293
369
  throw new McpRenderError_1.McpRenderError(`no MCP schema for the declared type '${ref.unmappedText ?? '<unknown>'}'`, where, 'Give the field a shape the model can represent — a named DTO, an array of one, ' +
294
370
  'a string-literal union, a Record, or a primitive.');