@webpieces/api-doc-model 0.4.803 → 0.4.804
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 +1 -1
- package/package.json +2 -1
- package/src/extract/ApiDocExtractor.d.ts +61 -7
- package/src/extract/ApiDocExtractor.js +235 -39
- package/src/extract/ApiDocExtractor.js.map +1 -1
- package/src/extract/ConstantFolder.d.ts +16 -3
- package/src/extract/ConstantFolder.js +42 -3
- package/src/extract/ConstantFolder.js.map +1 -1
- package/src/extract/TypeResolver.d.ts +9 -0
- package/src/extract/TypeResolver.js +31 -6
- package/src/extract/TypeResolver.js.map +1 -1
- package/src/index.d.ts +5 -4
- package/src/index.js +7 -4
- package/src/index.js.map +1 -1
- package/src/model/ApiDocModel.d.ts +139 -12
- package/src/model/ApiDocModel.js +115 -13
- package/src/model/ApiDocModel.js.map +1 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as ts from 'typescript';
|
|
2
2
|
/**
|
|
3
|
-
* Decorator arguments are constants as often as they are literals — `@Endpoint(SAVE_PATH,
|
|
4
|
-
* `@ApiPath(PATHS.SAVE)` — and a document that printed `SAVE_PATH` as the path
|
|
5
|
-
* no document.
|
|
3
|
+
* Decorator arguments are constants as often as they are literals — `@Endpoint(POST, SAVE_PATH, READ,
|
|
4
|
+
* RPC)`, `@ApiPath(PATHS.SAVE)` — and a document that printed `SAVE_PATH` as the path, or `RPC` as the
|
|
5
|
+
* trigger, would be worse than no document.
|
|
6
6
|
*
|
|
7
7
|
* So the folder resolves them, and where it CANNOT it FAILS. There is deliberately no fallback to
|
|
8
8
|
* the source text and no "best effort" path: a partner-grade document that is quietly wrong about a
|
|
@@ -24,6 +24,19 @@ export declare class ConstantFolder {
|
|
|
24
24
|
foldString(expression: ts.Expression, what: string): string;
|
|
25
25
|
/** The string this expression denotes, or undefined. No throw — for optional arguments. */
|
|
26
26
|
tryFoldString(expression: ts.Expression): string | undefined;
|
|
27
|
+
/**
|
|
28
|
+
* The expression a name ultimately DENOTES, following `const` declarations through imports.
|
|
29
|
+
*
|
|
30
|
+
* A decorator argument is a constant as often as it is a literal, and that is true of structures
|
|
31
|
+
* too: a credential list shared by every method of a contract is written once as a `const` and
|
|
32
|
+
* named five times, which is better source than five copies. A reader that only understood a
|
|
33
|
+
* literal would force the copies — so the copies would happen, and one of them would drift.
|
|
34
|
+
*
|
|
35
|
+
* Returns the expression unchanged when it is not a name, so a caller can follow first and then
|
|
36
|
+
* ask what shape it is.
|
|
37
|
+
*/
|
|
38
|
+
follow(expression: ts.Expression): ts.Expression;
|
|
39
|
+
private followThrough;
|
|
27
40
|
private tryFold;
|
|
28
41
|
/** Follow an identifier / `Obj.MEMBER` to its declaration's initializer and fold that. */
|
|
29
42
|
private foldThroughSymbol;
|
|
@@ -6,9 +6,9 @@ const ts = tslib_1.__importStar(require("typescript"));
|
|
|
6
6
|
const ApiDocExtractionError_1 = require("./ApiDocExtractionError");
|
|
7
7
|
const SourceLocation_1 = require("./SourceLocation");
|
|
8
8
|
/**
|
|
9
|
-
* Decorator arguments are constants as often as they are literals — `@Endpoint(SAVE_PATH,
|
|
10
|
-
* `@ApiPath(PATHS.SAVE)` — and a document that printed `SAVE_PATH` as the path
|
|
11
|
-
* no document.
|
|
9
|
+
* Decorator arguments are constants as often as they are literals — `@Endpoint(POST, SAVE_PATH, READ,
|
|
10
|
+
* RPC)`, `@ApiPath(PATHS.SAVE)` — and a document that printed `SAVE_PATH` as the path, or `RPC` as the
|
|
11
|
+
* trigger, would be worse than no document.
|
|
12
12
|
*
|
|
13
13
|
* So the folder resolves them, and where it CANNOT it FAILS. There is deliberately no fallback to
|
|
14
14
|
* the source text and no "best effort" path: a partner-grade document that is quietly wrong about a
|
|
@@ -41,6 +41,45 @@ class ConstantFolder {
|
|
|
41
41
|
tryFoldString(expression) {
|
|
42
42
|
return this.tryFold(expression, new Set());
|
|
43
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* The expression a name ultimately DENOTES, following `const` declarations through imports.
|
|
46
|
+
*
|
|
47
|
+
* A decorator argument is a constant as often as it is a literal, and that is true of structures
|
|
48
|
+
* too: a credential list shared by every method of a contract is written once as a `const` and
|
|
49
|
+
* named five times, which is better source than five copies. A reader that only understood a
|
|
50
|
+
* literal would force the copies — so the copies would happen, and one of them would drift.
|
|
51
|
+
*
|
|
52
|
+
* Returns the expression unchanged when it is not a name, so a caller can follow first and then
|
|
53
|
+
* ask what shape it is.
|
|
54
|
+
*/
|
|
55
|
+
follow(expression) {
|
|
56
|
+
return this.followThrough(expression, new Set());
|
|
57
|
+
}
|
|
58
|
+
followThrough(expression, seen) {
|
|
59
|
+
if (seen.has(expression)) {
|
|
60
|
+
return expression;
|
|
61
|
+
}
|
|
62
|
+
seen.add(expression);
|
|
63
|
+
if (ts.isParenthesizedExpression(expression) || ts.isAsExpression(expression)) {
|
|
64
|
+
return this.followThrough(expression.expression, seen);
|
|
65
|
+
}
|
|
66
|
+
if (!ts.isIdentifier(expression) && !ts.isPropertyAccessExpression(expression)) {
|
|
67
|
+
return expression;
|
|
68
|
+
}
|
|
69
|
+
const symbol = this.checker.getSymbolAtLocation(expression);
|
|
70
|
+
const resolved = symbol !== undefined && (symbol.flags & ts.SymbolFlags.Alias) !== 0
|
|
71
|
+
? this.checker.getAliasedSymbol(symbol)
|
|
72
|
+
: symbol;
|
|
73
|
+
for (const declaration of resolved?.declarations ?? []) {
|
|
74
|
+
if (ts.isVariableDeclaration(declaration) && declaration.initializer) {
|
|
75
|
+
return this.followThrough(declaration.initializer, seen);
|
|
76
|
+
}
|
|
77
|
+
if (ts.isPropertyAssignment(declaration) && ts.isExpression(declaration.initializer)) {
|
|
78
|
+
return this.followThrough(declaration.initializer, seen);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return expression;
|
|
82
|
+
}
|
|
44
83
|
tryFold(expression, seen) {
|
|
45
84
|
if (seen.has(expression)) {
|
|
46
85
|
return undefined; // a const initialised from itself; not our problem to diagnose
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConstantFolder.js","sourceRoot":"","sources":["../../../../../../packages/docs/api-doc-model/src/extract/ConstantFolder.ts"],"names":[],"mappings":"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","sourcesContent":["import * as ts from 'typescript';\nimport { ApiDocExtractionError } from './ApiDocExtractionError';\nimport { SourceLocation } from './SourceLocation';\n\n/**\n * Decorator arguments are constants as often as they are literals — `@Endpoint(SAVE_PATH, 'rpc')`,\n * `@ApiPath(PATHS.SAVE)` — and a document that printed `SAVE_PATH` as the path would be worse than\n * no document.\n *\n * So the folder resolves them, and where it CANNOT it FAILS. There is deliberately no fallback to\n * the source text and no \"best effort\" path: a partner-grade document that is quietly wrong about a\n * URL is the one failure mode nobody catches by reading it.\n *\n * It asks the CHECKER first, which is what makes this robust across re-exports, imports and\n * `as const` objects: a `const` initialised with a string has a string-LITERAL type, and the checker\n * has already done the resolution. The syntactic walk below it exists only for the shapes the\n * checker widens.\n */\nexport class ConstantFolder {\n constructor(private readonly checker: ts.TypeChecker) {}\n\n /**\n * The string this expression denotes.\n *\n * @throws ApiDocExtractionError when it cannot be established — never a guess.\n */\n foldString(expression: ts.Expression, what: string): string {\n const folded = this.tryFold(expression, new Set<ts.Node>());\n if (folded === undefined) {\n throw new ApiDocExtractionError(\n `${what} is not a foldable constant: '${expression.getText()}'`,\n SourceLocation.of(expression),\n 'Declare it as a `const` initialised with a string literal (or write the literal inline). ' +\n 'A value only known at runtime cannot appear in a published document.',\n );\n }\n return folded;\n }\n\n /** The string this expression denotes, or undefined. No throw — for optional arguments. */\n tryFoldString(expression: ts.Expression): string | undefined {\n return this.tryFold(expression, new Set<ts.Node>());\n }\n\n private tryFold(expression: ts.Expression, seen: Set<ts.Node>): string | undefined {\n if (seen.has(expression)) {\n return undefined; // a const initialised from itself; not our problem to diagnose\n }\n seen.add(expression);\n\n if (ts.isStringLiteralLike(expression)) {\n return expression.text;\n }\n\n // The checker's answer, which already resolved imports, re-exports and `as const`.\n const type = this.checker.getTypeAtLocation(expression);\n if (type.isStringLiteral()) {\n return type.value;\n }\n\n if (ts.isTemplateExpression(expression)) {\n let out = expression.head.text;\n for (const span of expression.templateSpans) {\n const part = this.tryFold(span.expression, seen);\n if (part === undefined) {\n return undefined;\n }\n out += part + span.literal.text;\n }\n return out;\n }\n\n if (\n ts.isBinaryExpression(expression) &&\n expression.operatorToken.kind === ts.SyntaxKind.PlusToken\n ) {\n const left = this.tryFold(expression.left, seen);\n const right = this.tryFold(expression.right, seen);\n return left === undefined || right === undefined ? undefined : left + right;\n }\n\n if (ts.isIdentifier(expression) || ts.isPropertyAccessExpression(expression)) {\n return this.foldThroughSymbol(expression, seen);\n }\n\n if (ts.isParenthesizedExpression(expression) || ts.isAsExpression(expression)) {\n return this.tryFold(expression.expression, seen);\n }\n\n return undefined;\n }\n\n /** Follow an identifier / `Obj.MEMBER` to its declaration's initializer and fold that. */\n private foldThroughSymbol(expression: ts.Expression, seen: Set<ts.Node>): string | undefined {\n const symbol = this.checker.getSymbolAtLocation(expression);\n const resolved =\n symbol !== undefined && (symbol.flags & ts.SymbolFlags.Alias) !== 0\n ? this.checker.getAliasedSymbol(symbol)\n : symbol;\n for (const declaration of resolved?.declarations ?? []) {\n if (ts.isVariableDeclaration(declaration) && declaration.initializer) {\n return this.tryFold(declaration.initializer, seen);\n }\n if (ts.isPropertyAssignment(declaration) && ts.isExpression(declaration.initializer)) {\n return this.tryFold(declaration.initializer, seen);\n }\n if (ts.isPropertyDeclaration(declaration) && declaration.initializer) {\n return this.tryFold(declaration.initializer, seen);\n }\n }\n return undefined;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ConstantFolder.js","sourceRoot":"","sources":["../../../../../../packages/docs/api-doc-model/src/extract/ConstantFolder.ts"],"names":[],"mappings":"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","sourcesContent":["import * as ts from 'typescript';\nimport { ApiDocExtractionError } from './ApiDocExtractionError';\nimport { SourceLocation } from './SourceLocation';\n\n/**\n * Decorator arguments are constants as often as they are literals — `@Endpoint(POST, SAVE_PATH, READ,\n * RPC)`, `@ApiPath(PATHS.SAVE)` — and a document that printed `SAVE_PATH` as the path, or `RPC` as the\n * trigger, would be worse than no document.\n *\n * So the folder resolves them, and where it CANNOT it FAILS. There is deliberately no fallback to\n * the source text and no \"best effort\" path: a partner-grade document that is quietly wrong about a\n * URL is the one failure mode nobody catches by reading it.\n *\n * It asks the CHECKER first, which is what makes this robust across re-exports, imports and\n * `as const` objects: a `const` initialised with a string has a string-LITERAL type, and the checker\n * has already done the resolution. The syntactic walk below it exists only for the shapes the\n * checker widens.\n */\nexport class ConstantFolder {\n constructor(private readonly checker: ts.TypeChecker) {}\n\n /**\n * The string this expression denotes.\n *\n * @throws ApiDocExtractionError when it cannot be established — never a guess.\n */\n foldString(expression: ts.Expression, what: string): string {\n const folded = this.tryFold(expression, new Set<ts.Node>());\n if (folded === undefined) {\n throw new ApiDocExtractionError(\n `${what} is not a foldable constant: '${expression.getText()}'`,\n SourceLocation.of(expression),\n 'Declare it as a `const` initialised with a string literal (or write the literal inline). ' +\n 'A value only known at runtime cannot appear in a published document.',\n );\n }\n return folded;\n }\n\n /** The string this expression denotes, or undefined. No throw — for optional arguments. */\n tryFoldString(expression: ts.Expression): string | undefined {\n return this.tryFold(expression, new Set<ts.Node>());\n }\n\n /**\n * The expression a name ultimately DENOTES, following `const` declarations through imports.\n *\n * A decorator argument is a constant as often as it is a literal, and that is true of structures\n * too: a credential list shared by every method of a contract is written once as a `const` and\n * named five times, which is better source than five copies. A reader that only understood a\n * literal would force the copies — so the copies would happen, and one of them would drift.\n *\n * Returns the expression unchanged when it is not a name, so a caller can follow first and then\n * ask what shape it is.\n */\n follow(expression: ts.Expression): ts.Expression {\n return this.followThrough(expression, new Set<ts.Node>());\n }\n\n private followThrough(expression: ts.Expression, seen: Set<ts.Node>): ts.Expression {\n if (seen.has(expression)) {\n return expression;\n }\n seen.add(expression);\n if (ts.isParenthesizedExpression(expression) || ts.isAsExpression(expression)) {\n return this.followThrough(expression.expression, seen);\n }\n if (!ts.isIdentifier(expression) && !ts.isPropertyAccessExpression(expression)) {\n return expression;\n }\n const symbol = this.checker.getSymbolAtLocation(expression);\n const resolved =\n symbol !== undefined && (symbol.flags & ts.SymbolFlags.Alias) !== 0\n ? this.checker.getAliasedSymbol(symbol)\n : symbol;\n for (const declaration of resolved?.declarations ?? []) {\n if (ts.isVariableDeclaration(declaration) && declaration.initializer) {\n return this.followThrough(declaration.initializer, seen);\n }\n if (ts.isPropertyAssignment(declaration) && ts.isExpression(declaration.initializer)) {\n return this.followThrough(declaration.initializer, seen);\n }\n }\n return expression;\n }\n\n private tryFold(expression: ts.Expression, seen: Set<ts.Node>): string | undefined {\n if (seen.has(expression)) {\n return undefined; // a const initialised from itself; not our problem to diagnose\n }\n seen.add(expression);\n\n if (ts.isStringLiteralLike(expression)) {\n return expression.text;\n }\n\n // The checker's answer, which already resolved imports, re-exports and `as const`.\n const type = this.checker.getTypeAtLocation(expression);\n if (type.isStringLiteral()) {\n return type.value;\n }\n\n if (ts.isTemplateExpression(expression)) {\n let out = expression.head.text;\n for (const span of expression.templateSpans) {\n const part = this.tryFold(span.expression, seen);\n if (part === undefined) {\n return undefined;\n }\n out += part + span.literal.text;\n }\n return out;\n }\n\n if (\n ts.isBinaryExpression(expression) &&\n expression.operatorToken.kind === ts.SyntaxKind.PlusToken\n ) {\n const left = this.tryFold(expression.left, seen);\n const right = this.tryFold(expression.right, seen);\n return left === undefined || right === undefined ? undefined : left + right;\n }\n\n if (ts.isIdentifier(expression) || ts.isPropertyAccessExpression(expression)) {\n return this.foldThroughSymbol(expression, seen);\n }\n\n if (ts.isParenthesizedExpression(expression) || ts.isAsExpression(expression)) {\n return this.tryFold(expression.expression, seen);\n }\n\n return undefined;\n }\n\n /** Follow an identifier / `Obj.MEMBER` to its declaration's initializer and fold that. */\n private foldThroughSymbol(expression: ts.Expression, seen: Set<ts.Node>): string | undefined {\n const symbol = this.checker.getSymbolAtLocation(expression);\n const resolved =\n symbol !== undefined && (symbol.flags & ts.SymbolFlags.Alias) !== 0\n ? this.checker.getAliasedSymbol(symbol)\n : symbol;\n for (const declaration of resolved?.declarations ?? []) {\n if (ts.isVariableDeclaration(declaration) && declaration.initializer) {\n return this.tryFold(declaration.initializer, seen);\n }\n if (ts.isPropertyAssignment(declaration) && ts.isExpression(declaration.initializer)) {\n return this.tryFold(declaration.initializer, seen);\n }\n if (ts.isPropertyDeclaration(declaration) && declaration.initializer) {\n return this.tryFold(declaration.initializer, seen);\n }\n }\n return undefined;\n }\n}\n"]}
|
|
@@ -70,6 +70,15 @@ export declare class TypeResolver {
|
|
|
70
70
|
* rather than guessed at.
|
|
71
71
|
*/
|
|
72
72
|
private resolveReference;
|
|
73
|
+
/**
|
|
74
|
+
* Resolve a type by its DECLARATION rather than by a reference to it.
|
|
75
|
+
*
|
|
76
|
+
* The reference path above is the normal one — a field says `Customer` and the resolver follows
|
|
77
|
+
* it. This entry point exists for a type that is named from OUTSIDE the source: a manifest naming
|
|
78
|
+
* the document-wide error body, which no field in the contract points at. Same registration, same
|
|
79
|
+
* cycle story, so the two cannot disagree about what a type IS.
|
|
80
|
+
*/
|
|
81
|
+
resolveDeclaration(name: string, declaration: ts.Declaration, ownerName: string): TypeRef;
|
|
73
82
|
/** `type X = ...` — registered under X when it has a shape of its own, else transparent. */
|
|
74
83
|
private resolveAlias;
|
|
75
84
|
/** A TS `enum` of string members — the one non-union enum shape a document can carry. */
|
|
@@ -3,16 +3,30 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.TypeResolver = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const ts = tslib_1.__importStar(require("typescript"));
|
|
6
|
+
const core_util_1 = require("@webpieces/core-util");
|
|
6
7
|
const ApiDocModel_1 = require("../model/ApiDocModel");
|
|
7
8
|
const TypeRef_1 = require("../model/TypeRef");
|
|
8
9
|
const ApiDocExtractionError_1 = require("./ApiDocExtractionError");
|
|
9
10
|
const JsDoc_1 = require("./JsDoc");
|
|
10
11
|
const SourceLocation_1 = require("./SourceLocation");
|
|
11
|
-
/**
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
/**
|
|
13
|
+
* The decorators this resolver reads off a DTO property, named from the REAL SYMBOLS — a rename in
|
|
14
|
+
* `core-util` is a compile error here rather than a literal that quietly stops matching. See
|
|
15
|
+
* {@link ApiDocExtractor}'s constants for the full argument (issue #1001).
|
|
16
|
+
*/
|
|
17
|
+
const INT_DECORATOR = core_util_1.WpInt.name;
|
|
18
|
+
const MIN_DECORATOR = core_util_1.WpMin.name;
|
|
19
|
+
const MAX_DECORATOR = core_util_1.WpMax.name;
|
|
20
|
+
/**
|
|
21
|
+
* The type-alias name that DECLARES integer-ness.
|
|
22
|
+
*
|
|
23
|
+
* This one is a LITERAL and cannot be anything else: `Integer` is a TYPE ALIAS, so there is no
|
|
24
|
+
* runtime symbol whose `.name` could be read — `.name` is a property of a function, and a type has
|
|
25
|
+
* erased by then. It is the one name in this package that a rename in `core-util` would not break at
|
|
26
|
+
* compile time; the cure if that ever bites is to make integer-ness a decorator here too, not to
|
|
27
|
+
* pretend a type has a runtime identity. See {@link ApiDocExtractor}'s constants for the argument
|
|
28
|
+
* everywhere else (issue #1001).
|
|
29
|
+
*/
|
|
16
30
|
const INTEGER_ALIAS = 'Integer';
|
|
17
31
|
/**
|
|
18
32
|
* Resolve declared TypeScript types into {@link TypeRef}s, registering every NAMED type it meets as
|
|
@@ -231,6 +245,17 @@ class TypeResolver {
|
|
|
231
245
|
if (declaration === undefined) {
|
|
232
246
|
return this.recordUnmapped(node, `no declaration found for '${name}'`);
|
|
233
247
|
}
|
|
248
|
+
return this.resolveDeclaration(name, declaration, ownerName);
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Resolve a type by its DECLARATION rather than by a reference to it.
|
|
252
|
+
*
|
|
253
|
+
* The reference path above is the normal one — a field says `Customer` and the resolver follows
|
|
254
|
+
* it. This entry point exists for a type that is named from OUTSIDE the source: a manifest naming
|
|
255
|
+
* the document-wide error body, which no field in the contract points at. Same registration, same
|
|
256
|
+
* cycle story, so the two cannot disagree about what a type IS.
|
|
257
|
+
*/
|
|
258
|
+
resolveDeclaration(name, declaration, ownerName) {
|
|
234
259
|
if (ts.isInterfaceDeclaration(declaration) || ts.isClassDeclaration(declaration)) {
|
|
235
260
|
return this.registerNamedObject(name, declaration);
|
|
236
261
|
}
|
|
@@ -240,7 +265,7 @@ class TypeResolver {
|
|
|
240
265
|
if (ts.isEnumDeclaration(declaration)) {
|
|
241
266
|
return this.registerStringEnum(name, declaration);
|
|
242
267
|
}
|
|
243
|
-
return this.recordUnmapped(
|
|
268
|
+
return this.recordUnmapped(declaration, `'${name}' is declared as something with no document shape`);
|
|
244
269
|
}
|
|
245
270
|
/** `type X = ...` — registered under X when it has a shape of its own, else transparent. */
|
|
246
271
|
resolveAlias(name, alias, ownerName) {
|
|
@@ -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 {\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/** The decorators this resolver reads off a DTO property, by NAME — it imports none of them. */\nconst INT_DECORATOR = 'WpInt';\nconst MIN_DECORATOR = 'WpMin';\nconst MAX_DECORATOR = 'WpMax';\n\n/** The type-alias name that DECLARES integer-ness. See the class doc and `responsibilities.md`. */\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 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 node,\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":"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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"]}
|
package/src/index.d.ts
CHANGED
|
@@ -3,12 +3,13 @@
|
|
|
3
3
|
* produce ONE in-memory {@link ApiDocModel}.
|
|
4
4
|
*
|
|
5
5
|
* This is the single extraction pass both the OpenAPI documents and the MCP tool list (#982) are
|
|
6
|
-
* rendered from. It emits nothing itself, and it
|
|
7
|
-
*
|
|
8
|
-
*
|
|
6
|
+
* rendered from. It emits nothing itself, and it takes every decorator NAME it matches on from the
|
|
7
|
+
* real `@webpieces/core-util` symbol — so renaming a decorator is a compile error here rather than a
|
|
8
|
+
* literal that quietly stops matching and empties a document (issue #1001). See
|
|
9
|
+
* `responsibilities.md` for why that import is not the coupling it looks like.
|
|
9
10
|
*/
|
|
10
11
|
export { ApiDocExtractor } from './extract/ApiDocExtractor';
|
|
11
12
|
export { ApiDocExtractionError } from './extract/ApiDocExtractionError';
|
|
12
|
-
export { ApiDocModel, DocumentedAuth, DocumentedEndpoint, DocumentedEndpointOptions, DocumentedField, DocumentedMcpTool, DocumentedType, UnionDiscriminator, UnmappedType, } from './model/ApiDocModel';
|
|
13
|
+
export { ApiDocModel, DocumentedApiKey, DocumentedApiKeyCredential, DocumentedAuth, DocumentedEndpoint, DocumentedEndpointOptions, DocumentedField, DocumentedMcpTool, DocumentedType, UnionDiscriminator, UnmappedType, } from './model/ApiDocModel';
|
|
13
14
|
export { TypeRef } from './model/TypeRef';
|
|
14
15
|
export type { PrimitiveKind, TypeRefKind } from './model/TypeRef';
|
package/src/index.js
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
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.ApiDocModel = exports.ApiDocExtractionError = exports.ApiDocExtractor = void 0;
|
|
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;
|
|
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}.
|
|
7
7
|
*
|
|
8
8
|
* This is the single extraction pass both the OpenAPI documents and the MCP tool list (#982) are
|
|
9
|
-
* rendered from. It emits nothing itself, and it
|
|
10
|
-
*
|
|
11
|
-
*
|
|
9
|
+
* rendered from. It emits nothing itself, and it takes every decorator NAME it matches on from the
|
|
10
|
+
* real `@webpieces/core-util` symbol — so renaming a decorator is a compile error here rather than a
|
|
11
|
+
* literal that quietly stops matching and empties a document (issue #1001). See
|
|
12
|
+
* `responsibilities.md` for why that import is not the coupling it looks like.
|
|
12
13
|
*/
|
|
13
14
|
var ApiDocExtractor_1 = require("./extract/ApiDocExtractor");
|
|
14
15
|
Object.defineProperty(exports, "ApiDocExtractor", { enumerable: true, get: function () { return ApiDocExtractor_1.ApiDocExtractor; } });
|
|
@@ -16,6 +17,8 @@ var ApiDocExtractionError_1 = require("./extract/ApiDocExtractionError");
|
|
|
16
17
|
Object.defineProperty(exports, "ApiDocExtractionError", { enumerable: true, get: function () { return ApiDocExtractionError_1.ApiDocExtractionError; } });
|
|
17
18
|
var ApiDocModel_1 = require("./model/ApiDocModel");
|
|
18
19
|
Object.defineProperty(exports, "ApiDocModel", { enumerable: true, get: function () { return ApiDocModel_1.ApiDocModel; } });
|
|
20
|
+
Object.defineProperty(exports, "DocumentedApiKey", { enumerable: true, get: function () { return ApiDocModel_1.DocumentedApiKey; } });
|
|
21
|
+
Object.defineProperty(exports, "DocumentedApiKeyCredential", { enumerable: true, get: function () { return ApiDocModel_1.DocumentedApiKeyCredential; } });
|
|
19
22
|
Object.defineProperty(exports, "DocumentedAuth", { enumerable: true, get: function () { return ApiDocModel_1.DocumentedAuth; } });
|
|
20
23
|
Object.defineProperty(exports, "DocumentedEndpoint", { enumerable: true, get: function () { return ApiDocModel_1.DocumentedEndpoint; } });
|
|
21
24
|
Object.defineProperty(exports, "DocumentedEndpointOptions", { enumerable: true, get: function () { return ApiDocModel_1.DocumentedEndpointOptions; } });
|
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
|
|
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"]}
|