@buildvision/nest-sdk-generator 2.3.1 → 3.0.0
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/.eslintrc.js +1 -1
- package/.github/workflows/test.yml +35 -0
- package/README.md +402 -239
- package/build/analyzer/classdeps.js +36 -4
- package/build/analyzer/controller.d.ts +2 -14
- package/build/analyzer/controller.js +38 -18
- package/build/analyzer/controllers.d.ts +2 -2
- package/build/analyzer/controllers.js +37 -5
- package/build/analyzer/extractor.d.ts +2 -41
- package/build/analyzer/extractor.js +63 -66
- package/build/analyzer/index.d.ts +2 -6
- package/build/analyzer/index.js +107 -86
- package/build/analyzer/methods.d.ts +2 -30
- package/build/analyzer/methods.js +7 -16
- package/build/analyzer/module.js +36 -4
- package/build/analyzer/params.d.ts +3 -39
- package/build/analyzer/params.js +17 -37
- package/build/analyzer/route.js +8 -9
- package/build/analyzer/sdk.d.ts +146 -0
- package/build/analyzer/sdk.js +120 -0
- package/build/analyzer/typedeps.d.ts +15 -0
- package/build/analyzer/typedeps.js +62 -10
- package/build/bin.js +72 -26
- package/build/config.d.ts +13 -0
- package/build/config.js +36 -3
- package/build/engine/analyze.d.ts +16 -0
- package/build/engine/analyze.js +786 -0
- package/build/engine/ast.d.ts +24 -0
- package/build/engine/ast.js +100 -0
- package/build/engine/file-order.d.ts +17 -0
- package/build/engine/file-order.js +97 -0
- package/build/engine/host.d.ts +63 -0
- package/build/engine/host.js +16 -0
- package/build/engine/index.d.ts +15 -0
- package/build/engine/index.js +93 -0
- package/build/engine/ts-morph-compat-host.d.ts +8 -0
- package/build/engine/ts-morph-compat-host.js +18 -0
- package/build/engine/tsgo-host.d.ts +9 -0
- package/build/engine/tsgo-host.js +136 -0
- package/build/engine/typescript-host.d.ts +26 -0
- package/build/engine/typescript-host.js +142 -0
- package/build/generator/genmodules.d.ts +1 -4
- package/build/generator/genmodules.js +23 -27
- package/build/generator/gentypes.d.ts +1 -1
- package/build/generator/gentypes.js +36 -4
- package/build/generator/index.d.ts +1 -1
- package/build/generator/index.js +91 -69
- package/build/generator/prettier.js +43 -9
- package/build/generator/sdk-interface.d.ts +1 -1
- package/build/generator/sdk-interface.js +5 -5
- package/build/logging.d.ts +2 -0
- package/build/logging.js +14 -11
- package/build/rtk-query-generator/genmodules.d.ts +1 -4
- package/build/rtk-query-generator/genmodules.js +27 -31
- package/build/rtk-query-generator/index.d.ts +1 -1
- package/build/rtk-query-generator/index.js +87 -65
- package/build/rtk-query-generator/prettier.js +43 -9
- package/build/rtk-query-generator/sdk-interface.js +3 -4
- package/build/utils.js +38 -6
- package/package.json +29 -11
- package/src/analyzer/controller.ts +3 -31
- package/src/analyzer/controllers.ts +3 -2
- package/src/analyzer/extractor.ts +17 -86
- package/src/analyzer/index.ts +5 -11
- package/src/analyzer/methods.ts +5 -36
- package/src/analyzer/params.ts +13 -55
- package/src/analyzer/sdk.ts +247 -0
- package/src/analyzer/typedeps.ts +22 -4
- package/src/bin.ts +29 -5
- package/src/config.ts +15 -0
- package/src/engine/analyze.ts +1110 -0
- package/src/engine/ast.ts +105 -0
- package/src/engine/file-order.ts +104 -0
- package/src/engine/host.ts +79 -0
- package/src/engine/index.ts +79 -0
- package/src/engine/ts-morph-compat-host.ts +20 -0
- package/src/engine/tsgo-host.ts +119 -0
- package/src/engine/typescript-host.ts +159 -0
- package/src/generator/genmodules.ts +9 -4
- package/src/generator/gentypes.ts +1 -1
- package/src/generator/index.ts +1 -1
- package/src/logging.ts +6 -1
- package/src/rtk-query-generator/genmodules.ts +9 -4
- package/src/rtk-query-generator/index.ts +1 -2
- package/src/rtk-query-generator/sdk-interface.ts +2 -3
- package/tsconfig.json +7 -6
- package/build/analyzer/decorator.d.ts +0 -10
- package/build/analyzer/decorator.js +0 -29
- package/build/rtk-query-generator/gentypes.d.ts +0 -10
- package/build/rtk-query-generator/gentypes.js +0 -62
- package/build/tsconfig.tsbuildinfo +0 -1
- package/bun.lockb +0 -0
- package/tsconfig.tsbuildinfo +0 -1
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file AST helpers reproducing the semantics of the ts-morph methods used by the legacy analyzer
|
|
3
|
+
*/
|
|
4
|
+
import { AnalysisHost, TsNode } from './host';
|
|
5
|
+
/** ts-morph's `node.getText()`: the node's source text, without leading trivia */
|
|
6
|
+
export declare function nodeText(node: TsNode, sourceFile: TsNode): string;
|
|
7
|
+
/** ts-morph's `node.getName()` for named and nameable declarations (class, function, method, parameter...) */
|
|
8
|
+
export declare function nodeName(node: TsNode, sourceFile: TsNode): string | undefined;
|
|
9
|
+
/** ts-morph's `node.getDecorators()` */
|
|
10
|
+
export declare function getDecorators(host: AnalysisHost, node: TsNode): TsNode[];
|
|
11
|
+
/** ts-morph's `decorator.getCallExpression()` */
|
|
12
|
+
export declare function decoratorCallExpression(host: AnalysisHost, decorator: TsNode): TsNode | undefined;
|
|
13
|
+
/** ts-morph's `decorator.getArguments()` */
|
|
14
|
+
export declare function decoratorArguments(host: AnalysisHost, decorator: TsNode): TsNode[];
|
|
15
|
+
/** ts-morph's `decorator.getName()` */
|
|
16
|
+
export declare function decoratorName(host: AnalysisHost, decorator: TsNode, sourceFile: TsNode): string;
|
|
17
|
+
/** ts-morph's `Node.isStringLiteral()` */
|
|
18
|
+
export declare function isStringLiteral(host: AnalysisHost, node: TsNode): boolean;
|
|
19
|
+
/** ts-morph's `classDeclaration.getMembers()` */
|
|
20
|
+
export declare function getClassMembers(host: AnalysisHost, decl: TsNode, sourceFile: TsNode): TsNode[];
|
|
21
|
+
/** ts-morph's `classDeclaration.getProperties()` / `interfaceDeclaration.getProperties()` */
|
|
22
|
+
export declare function getDeclarationProperties(host: AnalysisHost, decl: TsNode, sourceFile: TsNode): TsNode[];
|
|
23
|
+
/** ts-morph's `classDeclaration.getExtends()` (first type only) / `interfaceDeclaration.getExtends()` (all types) */
|
|
24
|
+
export declare function getExtendsTypeNodes(host: AnalysisHost, decl: TsNode): TsNode[];
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @file AST helpers reproducing the semantics of the ts-morph methods used by the legacy analyzer
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.nodeText = nodeText;
|
|
7
|
+
exports.nodeName = nodeName;
|
|
8
|
+
exports.getDecorators = getDecorators;
|
|
9
|
+
exports.decoratorCallExpression = decoratorCallExpression;
|
|
10
|
+
exports.decoratorArguments = decoratorArguments;
|
|
11
|
+
exports.decoratorName = decoratorName;
|
|
12
|
+
exports.isStringLiteral = isStringLiteral;
|
|
13
|
+
exports.getClassMembers = getClassMembers;
|
|
14
|
+
exports.getDeclarationProperties = getDeclarationProperties;
|
|
15
|
+
exports.getExtendsTypeNodes = getExtendsTypeNodes;
|
|
16
|
+
/** ts-morph's `node.getText()`: the node's source text, without leading trivia */
|
|
17
|
+
function nodeText(node, sourceFile) {
|
|
18
|
+
return sourceFile.text.substring(node.getStart(sourceFile), node.end);
|
|
19
|
+
}
|
|
20
|
+
/** ts-morph's `node.getName()` for named and nameable declarations (class, function, method, parameter...) */
|
|
21
|
+
function nodeName(node, sourceFile) {
|
|
22
|
+
return node.name ? nodeText(node.name, sourceFile) : undefined;
|
|
23
|
+
}
|
|
24
|
+
/** ts-morph's `node.getDecorators()` */
|
|
25
|
+
function getDecorators(host, node) {
|
|
26
|
+
return (node.modifiers ?? []).filter((m) => m.kind === host.SyntaxKind.Decorator);
|
|
27
|
+
}
|
|
28
|
+
/** ts-morph's `decorator._getInnerExpression()` */
|
|
29
|
+
function decoratorInnerExpression(host, decorator) {
|
|
30
|
+
let expr = decorator.expression;
|
|
31
|
+
while (expr.kind === host.SyntaxKind.ParenthesizedExpression)
|
|
32
|
+
expr = expr.expression;
|
|
33
|
+
return expr;
|
|
34
|
+
}
|
|
35
|
+
/** ts-morph's `decorator.getCallExpression()` */
|
|
36
|
+
function decoratorCallExpression(host, decorator) {
|
|
37
|
+
const expr = decoratorInnerExpression(host, decorator);
|
|
38
|
+
return expr.kind === host.SyntaxKind.CallExpression ? expr : undefined;
|
|
39
|
+
}
|
|
40
|
+
/** ts-morph's `decorator.getArguments()` */
|
|
41
|
+
function decoratorArguments(host, decorator) {
|
|
42
|
+
return decoratorCallExpression(host, decorator)?.arguments ?? [];
|
|
43
|
+
}
|
|
44
|
+
/** ts-morph's `decorator.getName()` */
|
|
45
|
+
function decoratorName(host, decorator, sourceFile) {
|
|
46
|
+
const callExpression = decoratorCallExpression(host, decorator);
|
|
47
|
+
let identifier = callExpression ? callExpression.expression : decoratorInnerExpression(host, decorator);
|
|
48
|
+
if (identifier.kind === host.SyntaxKind.PropertyAccessExpression) {
|
|
49
|
+
identifier = identifier.name;
|
|
50
|
+
}
|
|
51
|
+
if (identifier.kind !== host.SyntaxKind.Identifier) {
|
|
52
|
+
throw new Error(`Expected the decorator expression '${nodeText(identifier, sourceFile)}' to be an identifier. ` +
|
|
53
|
+
`Please deal directly with 'getExpression()' on the decorator to handle more complex scenarios.`);
|
|
54
|
+
}
|
|
55
|
+
return nodeText(identifier, sourceFile);
|
|
56
|
+
}
|
|
57
|
+
/** ts-morph's `Node.isStringLiteral()` */
|
|
58
|
+
function isStringLiteral(host, node) {
|
|
59
|
+
return node.kind === host.SyntaxKind.StringLiteral;
|
|
60
|
+
}
|
|
61
|
+
function hasModifier(node, kind) {
|
|
62
|
+
return (node.modifiers ?? []).some((m) => m.kind === kind);
|
|
63
|
+
}
|
|
64
|
+
/** ts-morph's `classDeclaration.getMembers()` */
|
|
65
|
+
function getClassMembers(host, decl, sourceFile) {
|
|
66
|
+
const SK = host.SyntaxKind;
|
|
67
|
+
const isAmbient = hasModifier(decl, SK.DeclareKeyword) || sourceFile.isDeclarationFile;
|
|
68
|
+
return decl.members
|
|
69
|
+
.filter((m) => {
|
|
70
|
+
if (isAmbient)
|
|
71
|
+
return true;
|
|
72
|
+
if (m.kind !== SK.Constructor && m.kind !== SK.MethodDeclaration)
|
|
73
|
+
return true;
|
|
74
|
+
if (m.kind === SK.MethodDeclaration && hasModifier(m, SK.AbstractKeyword))
|
|
75
|
+
return true;
|
|
76
|
+
return m.body != null;
|
|
77
|
+
})
|
|
78
|
+
.filter((m) => [
|
|
79
|
+
SK.MethodDeclaration,
|
|
80
|
+
SK.PropertyDeclaration,
|
|
81
|
+
SK.GetAccessor,
|
|
82
|
+
SK.SetAccessor,
|
|
83
|
+
SK.Constructor,
|
|
84
|
+
SK.ClassStaticBlockDeclaration,
|
|
85
|
+
].includes(m.kind));
|
|
86
|
+
}
|
|
87
|
+
/** ts-morph's `classDeclaration.getProperties()` / `interfaceDeclaration.getProperties()` */
|
|
88
|
+
function getDeclarationProperties(host, decl, sourceFile) {
|
|
89
|
+
const SK = host.SyntaxKind;
|
|
90
|
+
return decl.kind === SK.ClassDeclaration
|
|
91
|
+
? getClassMembers(host, decl, sourceFile).filter((m) => m.kind === SK.PropertyDeclaration)
|
|
92
|
+
: decl.members.filter((m) => m.kind === SK.PropertySignature);
|
|
93
|
+
}
|
|
94
|
+
/** ts-morph's `classDeclaration.getExtends()` (first type only) / `interfaceDeclaration.getExtends()` (all types) */
|
|
95
|
+
function getExtendsTypeNodes(host, decl) {
|
|
96
|
+
const clause = (decl.heritageClauses ?? []).find((c) => c.token === host.SyntaxKind.ExtendsKeyword);
|
|
97
|
+
const types = clause?.types ?? [];
|
|
98
|
+
return decl.kind === host.SyntaxKind.ClassDeclaration ? types.slice(0, 1) : types;
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2VuZ2luZS9hc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOztHQUVHOzs7Ozs7Ozs7Ozs7QUFJSCxrRkFBa0Y7QUFDbEYsa0JBQXlCLElBQVksRUFBRSxVQUFrQjtJQUN2RCxPQUFPLFVBQVUsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFBO0FBQ3ZFLENBQUM7QUFFRCw4R0FBOEc7QUFDOUcsa0JBQXlCLElBQVksRUFBRSxVQUFrQjtJQUN2RCxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUE7QUFDaEUsQ0FBQztBQUVELHdDQUF3QztBQUN4Qyx1QkFBOEIsSUFBa0IsRUFBRSxJQUFZO0lBQzVELE9BQU8sQ0FBQyxJQUFJLENBQUMsU0FBUyxJQUFJLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQVMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxJQUFJLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxDQUFBO0FBQzNGLENBQUM7QUFFRCxtREFBbUQ7QUFDbkQsU0FBUyx3QkFBd0IsQ0FBQyxJQUFrQixFQUFFLFNBQWlCO0lBQ3JFLElBQUksSUFBSSxHQUFHLFNBQVMsQ0FBQyxVQUFVLENBQUE7SUFDL0IsT0FBTyxJQUFJLENBQUMsSUFBSSxLQUFLLElBQUksQ0FBQyxVQUFVLENBQUMsdUJBQXVCO1FBQUUsSUFBSSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUE7SUFDcEYsT0FBTyxJQUFJLENBQUE7QUFDYixDQUFDO0FBRUQsaURBQWlEO0FBQ2pELGlDQUF3QyxJQUFrQixFQUFFLFNBQWlCO0lBQzNFLE1BQU0sSUFBSSxHQUFHLHdCQUF3QixDQUFDLElBQUksRUFBRSxTQUFTLENBQUMsQ0FBQTtJQUN0RCxPQUFPLElBQUksQ0FBQyxJQUFJLEtBQUssSUFBSSxDQUFDLFVBQVUsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFBO0FBQ3hFLENBQUM7QUFFRCw0Q0FBNEM7QUFDNUMsNEJBQW1DLElBQWtCLEVBQUUsU0FBaUI7SUFDdEUsT0FBTyx1QkFBdUIsQ0FBQyxJQUFJLEVBQUUsU0FBUyxDQUFDLEVBQUUsU0FBUyxJQUFJLEVBQUUsQ0FBQTtBQUNsRSxDQUFDO0FBRUQsdUNBQXVDO0FBQ3ZDLHVCQUE4QixJQUFrQixFQUFFLFNBQWlCLEVBQUUsVUFBa0I7SUFDckYsTUFBTSxjQUFjLEdBQUcsdUJBQXVCLENBQUMsSUFBSSxFQUFFLFNBQVMsQ0FBQyxDQUFBO0lBQy9ELElBQUksVUFBVSxHQUFHLGNBQWMsQ0FBQyxDQUFDLENBQUMsY0FBYyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsd0JBQXdCLENBQUMsSUFBSSxFQUFFLFNBQVMsQ0FBQyxDQUFBO0lBRXZHLElBQUksVUFBVSxDQUFDLElBQUksS0FBSyxJQUFJLENBQUMsVUFBVSxDQUFDLHdCQUF3QixFQUFFLENBQUM7UUFDakUsVUFBVSxHQUFHLFVBQVUsQ0FBQyxJQUFJLENBQUE7SUFDOUIsQ0FBQztJQUVELElBQUksVUFBVSxDQUFDLElBQUksS0FBSyxJQUFJLENBQUMsVUFBVSxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQ25ELE1BQU0sSUFBSSxLQUFLLENBQ2Isc0NBQXNDLFFBQVEsQ0FBQyxVQUFVLEVBQUUsVUFBVSxDQUFDLHlCQUF5QjtZQUM3RixnR0FBZ0csQ0FDbkcsQ0FBQTtJQUNILENBQUM7SUFFRCxPQUFPLFFBQVEsQ0FBQyxVQUFVLEVBQUUsVUFBVSxDQUFDLENBQUE7QUFDekMsQ0FBQztBQUVELDBDQUEwQztBQUMxQyx5QkFBZ0MsSUFBa0IsRUFBRSxJQUFZO0lBQzlELE9BQU8sSUFBSSxDQUFDLElBQUksS0FBSyxJQUFJLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQTtBQUNwRCxDQUFDO0FBRUQsU0FBUyxXQUFXLENBQUMsSUFBWSxFQUFFLElBQVk7SUFDN0MsT0FBTyxDQUFDLElBQUksQ0FBQyxTQUFTLElBQUksRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBUyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxLQUFLLElBQUksQ0FBQyxDQUFBO0FBQ3BFLENBQUM7QUFFRCxpREFBaUQ7QUFDakQseUJBQWdDLElBQWtCLEVBQUUsSUFBWSxFQUFFLFVBQWtCO0lBQ2xGLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUE7SUFDMUIsTUFBTSxTQUFTLEdBQUcsV0FBVyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsY0FBYyxDQUFDLElBQUksVUFBVSxDQUFDLGlCQUFpQixDQUFBO0lBRXRGLE9BQVEsSUFBSSxDQUFDLE9BQW9CO1NBQzlCLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFO1FBQ1osSUFBSSxTQUFTO1lBQUUsT0FBTyxJQUFJLENBQUE7UUFDMUIsSUFBSSxDQUFDLENBQUMsSUFBSSxLQUFLLEVBQUUsQ0FBQyxXQUFXLElBQUksQ0FBQyxDQUFDLElBQUksS0FBSyxFQUFFLENBQUMsaUJBQWlCO1lBQUUsT0FBTyxJQUFJLENBQUE7UUFDN0UsSUFBSSxDQUFDLENBQUMsSUFBSSxLQUFLLEVBQUUsQ0FBQyxpQkFBaUIsSUFBSSxXQUFXLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxlQUFlLENBQUM7WUFBRSxPQUFPLElBQUksQ0FBQTtRQUN0RixPQUFPLENBQUMsQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFBO0lBQ3ZCLENBQUMsQ0FBQztTQUNELE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQ1o7UUFDRSxFQUFFLENBQUMsaUJBQWlCO1FBQ3BCLEVBQUUsQ0FBQyxtQkFBbUI7UUFDdEIsRUFBRSxDQUFDLFdBQVc7UUFDZCxFQUFFLENBQUMsV0FBVztRQUNkLEVBQUUsQ0FBQyxXQUFXO1FBQ2QsRUFBRSxDQUFDLDJCQUEyQjtLQUMvQixDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQ25CLENBQUE7QUFDTCxDQUFDO0FBRUQsNkZBQTZGO0FBQzdGLGtDQUF5QyxJQUFrQixFQUFFLElBQVksRUFBRSxVQUFrQjtJQUMzRixNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFBO0lBQzFCLE9BQU8sSUFBSSxDQUFDLElBQUksS0FBSyxFQUFFLENBQUMsZ0JBQWdCO1FBQ3RDLENBQUMsQ0FBQyxlQUFlLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxVQUFVLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLEtBQUssRUFBRSxDQUFDLG1CQUFtQixDQUFDO1FBQzFGLENBQUMsQ0FBRSxJQUFJLENBQUMsT0FBb0IsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLEtBQUssRUFBRSxDQUFDLGlCQUFpQixDQUFDLENBQUE7QUFDL0UsQ0FBQztBQUVELHFIQUFxSDtBQUNySCw2QkFBb0MsSUFBa0IsRUFBRSxJQUFZO0lBQ2xFLE1BQU0sTUFBTSxHQUFHLENBQUMsSUFBSSxDQUFDLGVBQWUsSUFBSSxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFTLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLEtBQUssSUFBSSxDQUFDLFVBQVUsQ0FBQyxjQUFjLENBQUMsQ0FBQTtJQUMzRyxNQUFNLEtBQUssR0FBYSxNQUFNLEVBQUUsS0FBSyxJQUFJLEVBQUUsQ0FBQTtJQUMzQyxPQUFPLElBQUksQ0FBQyxJQUFJLEtBQUssSUFBSSxDQUFDLFVBQVUsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQTtBQUNuRixDQUFDIn0=
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Order project files the way ts-morph's `project.getSourceFiles()` does
|
|
3
|
+
*
|
|
4
|
+
* The order of the source files determines the order controllers are analyzed in, which in turn determines the order
|
|
5
|
+
* of the generated modules and types.
|
|
6
|
+
*
|
|
7
|
+
* ts-morph keeps a tree of the directories containing source files. Directories without a parent in the tree are
|
|
8
|
+
* "roots", kept in the order they were created (i.e. the order files were added: the tsconfig's files, then the files
|
|
9
|
+
* they import). The tree is walked breadth-first by depth: at each depth, the roots at that depth come first, then the
|
|
10
|
+
* children of the previous depth's directories, sorted by name. The files of each directory are sorted by name.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Get the project's files, in ts-morph's order
|
|
14
|
+
* @param rootFiles The tsconfig's files, in the tsconfig's order (absolute paths, forward slashes)
|
|
15
|
+
* @param programFiles All files of the program (absolute paths, forward slashes)
|
|
16
|
+
*/
|
|
17
|
+
export declare function orderProjectFiles(rootFiles: string[], programFiles: string[]): string[];
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @file Order project files the way ts-morph's `project.getSourceFiles()` does
|
|
4
|
+
*
|
|
5
|
+
* The order of the source files determines the order controllers are analyzed in, which in turn determines the order
|
|
6
|
+
* of the generated modules and types.
|
|
7
|
+
*
|
|
8
|
+
* ts-morph keeps a tree of the directories containing source files. Directories without a parent in the tree are
|
|
9
|
+
* "roots", kept in the order they were created (i.e. the order files were added: the tsconfig's files, then the files
|
|
10
|
+
* they import). The tree is walked breadth-first by depth: at each depth, the roots at that depth come first, then the
|
|
11
|
+
* children of the previous depth's directories, sorted by name. The files of each directory are sorted by name.
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.orderProjectFiles = orderProjectFiles;
|
|
15
|
+
function compareNames(a, b) {
|
|
16
|
+
// Same comparison as ts-morph's `LocaleStringComparer`
|
|
17
|
+
const result = a.localeCompare(b, 'en-us-u-kf-upper');
|
|
18
|
+
return result < 0 ? -1 : result === 0 ? 0 : 1;
|
|
19
|
+
}
|
|
20
|
+
function dirname(file) {
|
|
21
|
+
const index = file.lastIndexOf('/');
|
|
22
|
+
return index <= 0 ? '/' : file.substring(0, index);
|
|
23
|
+
}
|
|
24
|
+
function depth(dir) {
|
|
25
|
+
return dir.split('/').filter((part) => part.length > 0).length;
|
|
26
|
+
}
|
|
27
|
+
function isProjectFile(file) {
|
|
28
|
+
// Files ts-morph considers part of the project: anything outside of `node_modules` (and outside of TypeScript's
|
|
29
|
+
// bundled libraries, which tsgo exposes with non-absolute paths)
|
|
30
|
+
return (file.startsWith('/') || /^[a-zA-Z]:\//.test(file)) && file.toLowerCase().lastIndexOf('/node_modules/') === -1;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Get the project's files, in ts-morph's order
|
|
34
|
+
* @param rootFiles The tsconfig's files, in the tsconfig's order (absolute paths, forward slashes)
|
|
35
|
+
* @param programFiles All files of the program (absolute paths, forward slashes)
|
|
36
|
+
*/
|
|
37
|
+
function orderProjectFiles(rootFiles, programFiles) {
|
|
38
|
+
// ts-morph adds the tsconfig's files first, then the files the compiler requested while building the program.
|
|
39
|
+
// The latter only affect the order of directories outside of the tsconfig's ones: sort them for determinism.
|
|
40
|
+
const rootFilesSet = new Set(rootFiles);
|
|
41
|
+
const files = [...new Set([...rootFiles, ...programFiles.filter((file) => !rootFilesSet.has(file)).sort()])].filter(isProjectFile);
|
|
42
|
+
const filesByDir = new Map();
|
|
43
|
+
for (const file of files) {
|
|
44
|
+
const dir = dirname(file);
|
|
45
|
+
const dirFiles = filesByDir.get(dir);
|
|
46
|
+
if (dirFiles)
|
|
47
|
+
dirFiles.push(file);
|
|
48
|
+
else
|
|
49
|
+
filesByDir.set(dir, [file]);
|
|
50
|
+
}
|
|
51
|
+
// Directories, in creation order
|
|
52
|
+
const dirs = [...filesByDir.keys()];
|
|
53
|
+
const dirsSet = new Set(dirs);
|
|
54
|
+
const hasAncestorInTree = (dir) => {
|
|
55
|
+
for (let parent = dirname(dir);; parent = dirname(parent)) {
|
|
56
|
+
if (dirsSet.has(parent))
|
|
57
|
+
return true;
|
|
58
|
+
if (parent === '/' || parent === dirname(parent))
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
const roots = dirs.filter((dir) => !hasAncestorInTree(dir));
|
|
63
|
+
// Link every directory to its parent, creating the intermediate directories up to the nearest directory in the tree
|
|
64
|
+
const children = new Map();
|
|
65
|
+
for (const dir of dirs) {
|
|
66
|
+
if (roots.includes(dir))
|
|
67
|
+
continue;
|
|
68
|
+
for (let current = dir; !roots.includes(current) && !children.get(dirname(current))?.has(current); current = dirname(current)) {
|
|
69
|
+
const parent = dirname(current);
|
|
70
|
+
const siblings = children.get(parent);
|
|
71
|
+
if (siblings)
|
|
72
|
+
siblings.add(current);
|
|
73
|
+
else
|
|
74
|
+
children.set(parent, new Set([current]));
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// Breadth-first walk, like ts-morph's `DirectoryCache.getAllByDepth()`
|
|
78
|
+
const levels = new Map();
|
|
79
|
+
const addToLevel = (dir) => {
|
|
80
|
+
const level = levels.get(depth(dir));
|
|
81
|
+
if (level)
|
|
82
|
+
level.push(dir);
|
|
83
|
+
else
|
|
84
|
+
levels.set(depth(dir), [dir]);
|
|
85
|
+
};
|
|
86
|
+
roots.forEach(addToLevel);
|
|
87
|
+
const ordered = [];
|
|
88
|
+
for (let currentDepth = Math.min(...levels.keys()); levels.size > 0; currentDepth++) {
|
|
89
|
+
for (const dir of levels.get(currentDepth) ?? []) {
|
|
90
|
+
ordered.push(...(filesByDir.get(dir) ?? []).sort((a, b) => compareNames(a.substring(dir.length), b.substring(dir.length))));
|
|
91
|
+
[...(children.get(dir) ?? [])].sort((a, b) => compareNames(a.substring(dir.length), b.substring(dir.length))).forEach(addToLevel);
|
|
92
|
+
}
|
|
93
|
+
levels.delete(currentDepth);
|
|
94
|
+
}
|
|
95
|
+
return ordered;
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsZS1vcmRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9lbmdpbmUvZmlsZS1vcmRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7Ozs7Ozs7R0FVRzs7O0FBRUgsU0FBUyxZQUFZLENBQUMsQ0FBUyxFQUFFLENBQVM7SUFDeEMsdURBQXVEO0lBQ3ZELE1BQU0sTUFBTSxHQUFHLENBQUMsQ0FBQyxhQUFhLENBQUMsQ0FBQyxFQUFFLGtCQUFrQixDQUFDLENBQUE7SUFDckQsT0FBTyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUE7QUFDL0MsQ0FBQztBQUVELFNBQVMsT0FBTyxDQUFDLElBQVk7SUFDM0IsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQTtJQUNuQyxPQUFPLEtBQUssSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUE7QUFDcEQsQ0FBQztBQUVELFNBQVMsS0FBSyxDQUFDLEdBQVc7SUFDeEIsT0FBTyxHQUFHLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUE7QUFDaEUsQ0FBQztBQUVELFNBQVMsYUFBYSxDQUFDLElBQVk7SUFDakMsZ0hBQWdIO0lBQ2hILGlFQUFpRTtJQUNqRSxPQUFPLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsSUFBSSxjQUFjLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksSUFB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
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Minimal compiler interface the analyzer needs from a TypeScript engine
|
|
3
|
+
*
|
|
4
|
+
* Both the in-process TypeScript compiler API and the TypeScript 7 native (tsgo) API expose the same AST shapes
|
|
5
|
+
* (`kind`, `statements`, `members`, `modifiers`...) and the same checker operations, so the analyzer is written once
|
|
6
|
+
* against this interface. Syntax kinds differ between TypeScript versions, so they are provided by the host.
|
|
7
|
+
*/
|
|
8
|
+
/** A compiler AST node (TypeScript JS API or TypeScript 7 API) */
|
|
9
|
+
export type TsNode = any;
|
|
10
|
+
/** A compiler type (TypeScript JS API or TypeScript 7 API) */
|
|
11
|
+
export type TsType = any;
|
|
12
|
+
/**
|
|
13
|
+
* Flags ts-morph uses by default when printing a type with `Type.getText()`:
|
|
14
|
+
* UseTypeOfFunction (4096) | NoTruncation (1) | UseFullyQualifiedType (64) | WriteTypeArgumentsOfSignature (32)
|
|
15
|
+
*/
|
|
16
|
+
export declare const TYPE_FORMAT_FLAGS = 4193;
|
|
17
|
+
export interface SyntaxKinds {
|
|
18
|
+
readonly AbstractKeyword: number;
|
|
19
|
+
readonly CallExpression: number;
|
|
20
|
+
readonly ClassDeclaration: number;
|
|
21
|
+
readonly ClassStaticBlockDeclaration: number;
|
|
22
|
+
readonly Constructor: number;
|
|
23
|
+
readonly DeclareKeyword: number;
|
|
24
|
+
readonly Decorator: number;
|
|
25
|
+
readonly EnumDeclaration: number;
|
|
26
|
+
readonly ExtendsKeyword: number;
|
|
27
|
+
readonly FunctionDeclaration: number;
|
|
28
|
+
readonly GetAccessor: number;
|
|
29
|
+
readonly Identifier: number;
|
|
30
|
+
readonly InterfaceDeclaration: number;
|
|
31
|
+
readonly MethodDeclaration: number;
|
|
32
|
+
readonly ParenthesizedExpression: number;
|
|
33
|
+
readonly PropertyAccessExpression: number;
|
|
34
|
+
readonly PropertyDeclaration: number;
|
|
35
|
+
readonly PropertySignature: number;
|
|
36
|
+
readonly SetAccessor: number;
|
|
37
|
+
readonly StringLiteral: number;
|
|
38
|
+
readonly TypeAliasDeclaration: number;
|
|
39
|
+
}
|
|
40
|
+
export interface AnalysisHost {
|
|
41
|
+
readonly SyntaxKind: SyntaxKinds;
|
|
42
|
+
/** Release the engine's resources */
|
|
43
|
+
dispose(): void;
|
|
44
|
+
/** Equivalent of ts-morph's `type.getStringIndexType()` / `type.getNumberIndexType()` */
|
|
45
|
+
getIndexType(type: TsType, keyKind: 'string' | 'number'): TsType | undefined;
|
|
46
|
+
/**
|
|
47
|
+
* Absolute paths of the project's source files: the files ts-morph would consider part of the project (the tsconfig's
|
|
48
|
+
* files and the non-`node_modules` files they import), in the order of ts-morph's `project.getSourceFiles()`
|
|
49
|
+
*/
|
|
50
|
+
getProjectFilePaths(): string[];
|
|
51
|
+
/** Equivalent of ts-morph's `method.getReturnType()` */
|
|
52
|
+
getReturnTypeOfDeclaration(node: TsNode): TsType;
|
|
53
|
+
/** Get a source file of the program, if it exists */
|
|
54
|
+
getSourceFile(absolutePath: string): TsNode | undefined;
|
|
55
|
+
/** Equivalent of ts-morph's `node.getType()` */
|
|
56
|
+
getTypeAtLocation(node: TsNode): TsType;
|
|
57
|
+
/** Equivalent of ts-morph's `type.isObject()` */
|
|
58
|
+
isObjectType(type: TsType): boolean;
|
|
59
|
+
/** Engine name, for logging */
|
|
60
|
+
readonly name: string;
|
|
61
|
+
/** Equivalent of ts-morph's `type.getText()` */
|
|
62
|
+
typeToString(type: TsType): string;
|
|
63
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @file Minimal compiler interface the analyzer needs from a TypeScript engine
|
|
4
|
+
*
|
|
5
|
+
* Both the in-process TypeScript compiler API and the TypeScript 7 native (tsgo) API expose the same AST shapes
|
|
6
|
+
* (`kind`, `statements`, `members`, `modifiers`...) and the same checker operations, so the analyzer is written once
|
|
7
|
+
* against this interface. Syntax kinds differ between TypeScript versions, so they are provided by the host.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.TYPE_FORMAT_FLAGS = void 0;
|
|
11
|
+
/**
|
|
12
|
+
* Flags ts-morph uses by default when printing a type with `Type.getText()`:
|
|
13
|
+
* UseTypeOfFunction (4096) | NoTruncation (1) | UseFullyQualifiedType (64) | WriteTypeArgumentsOfSignature (32)
|
|
14
|
+
*/
|
|
15
|
+
exports.TYPE_FORMAT_FLAGS = 4193;
|
|
16
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaG9zdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9lbmdpbmUvaG9zdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7OztHQU1HOzs7QUFVSDs7O0dBR0c7QUFDVSxRQUFBLGlCQUFpQixHQUFHLElBQUksQ0FBQSJ9
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Analysis engines
|
|
3
|
+
*
|
|
4
|
+
* - `tsgo` (default): TypeScript 7's native compiler, through its API. Fastest.
|
|
5
|
+
* - `typescript`: the TypeScript compiler installed for the analyzed API (6.x), running in-process. Generates the same SDK
|
|
6
|
+
* as `tsgo`, and is used automatically if `tsgo` can't be started.
|
|
7
|
+
* - `ts-morph`: the original analyzer, running on the TypeScript 4.8 compiler bundled with ts-morph. Slowest; generates
|
|
8
|
+
* the same SDK as previous versions of this tool (which may differ from TypeScript 6+ on some inferred types).
|
|
9
|
+
*/
|
|
10
|
+
import type { SdkContent } from '../analyzer/sdk';
|
|
11
|
+
import { Config } from '../config';
|
|
12
|
+
export declare const ENGINES: readonly ['tsgo', 'typescript', 'ts-morph'];
|
|
13
|
+
export type EngineName = (typeof ENGINES)[number];
|
|
14
|
+
export declare function isEngineName(name: string): name is EngineName;
|
|
15
|
+
export declare function analyze(config: Config, engine: EngineName): Promise<SdkContent>;
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @file Analysis engines
|
|
4
|
+
*
|
|
5
|
+
* - `tsgo` (default): TypeScript 7's native compiler, through its API. Fastest.
|
|
6
|
+
* - `typescript`: the TypeScript compiler installed for the analyzed API (6.x), running in-process. Generates the same SDK
|
|
7
|
+
* as `tsgo`, and is used automatically if `tsgo` can't be started.
|
|
8
|
+
* - `ts-morph`: the original analyzer, running on the TypeScript 4.8 compiler bundled with ts-morph. Slowest; generates
|
|
9
|
+
* the same SDK as previous versions of this tool (which may differ from TypeScript 6+ on some inferred types).
|
|
10
|
+
*/
|
|
11
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
12
|
+
if (k2 === undefined) k2 = k;
|
|
13
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
14
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
15
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
16
|
+
}
|
|
17
|
+
Object.defineProperty(o, k2, desc);
|
|
18
|
+
}) : (function(o, m, k, k2) {
|
|
19
|
+
if (k2 === undefined) k2 = k;
|
|
20
|
+
o[k2] = m[k];
|
|
21
|
+
}));
|
|
22
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
23
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
24
|
+
}) : function(o, v) {
|
|
25
|
+
o["default"] = v;
|
|
26
|
+
});
|
|
27
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
28
|
+
var ownKeys = function(o) {
|
|
29
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
30
|
+
var ar = [];
|
|
31
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
32
|
+
return ar;
|
|
33
|
+
};
|
|
34
|
+
return ownKeys(o);
|
|
35
|
+
};
|
|
36
|
+
return function (mod) {
|
|
37
|
+
if (mod && mod.__esModule) return mod;
|
|
38
|
+
var result = {};
|
|
39
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
40
|
+
__setModuleDefault(result, mod);
|
|
41
|
+
return result;
|
|
42
|
+
};
|
|
43
|
+
})();
|
|
44
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
+
exports.ENGINES = void 0;
|
|
46
|
+
exports.isEngineName = isEngineName;
|
|
47
|
+
exports.analyze = analyze;
|
|
48
|
+
/* eslint-disable @typescript-eslint/no-var-requires -- engines are loaded lazily, as loading a compiler is expensive */
|
|
49
|
+
const path = __importStar(require("path"));
|
|
50
|
+
const logging_1 = require("../logging");
|
|
51
|
+
const analyze_1 = require("./analyze");
|
|
52
|
+
exports.ENGINES = ['tsgo', 'typescript', 'ts-morph'];
|
|
53
|
+
/** Internal engine running this analyzer on ts-morph's program, used to verify it matches the legacy analyzer */
|
|
54
|
+
const TS_MORPH_COMPAT_ENGINE = 'ts-morph-compat';
|
|
55
|
+
function isEngineName(name) {
|
|
56
|
+
return exports.ENGINES.includes(name) || name === TS_MORPH_COMPAT_ENGINE;
|
|
57
|
+
}
|
|
58
|
+
async function analyze(config, engine) {
|
|
59
|
+
(0, logging_1.debug)('Analysis engine: {yellow}', engine);
|
|
60
|
+
const sourcePath = path.resolve(process.cwd(), config.apiInputPath);
|
|
61
|
+
switch (engine) {
|
|
62
|
+
// Engines are loaded lazily: loading a compiler is expensive
|
|
63
|
+
case 'ts-morph': {
|
|
64
|
+
const { analyzerCli } = require('../analyzer');
|
|
65
|
+
return analyzerCli(config);
|
|
66
|
+
}
|
|
67
|
+
case TS_MORPH_COMPAT_ENGINE: {
|
|
68
|
+
const { createTsMorphCompatHost } = require('./ts-morph-compat-host');
|
|
69
|
+
return (0, analyze_1.analyzeWithHost)(config, createTsMorphCompatHost);
|
|
70
|
+
}
|
|
71
|
+
case 'typescript': {
|
|
72
|
+
const { createTypeScriptHost, loadTypeScript } = require('./typescript-host');
|
|
73
|
+
return (0, analyze_1.analyzeWithHost)(config, (tsConfigFilePath) => createTypeScriptHost(loadTypeScript(sourcePath, config.typescriptPath), tsConfigFilePath));
|
|
74
|
+
}
|
|
75
|
+
case 'tsgo': {
|
|
76
|
+
const { createTsgoHost } = require('./tsgo-host');
|
|
77
|
+
const { createTypeScriptHost, loadTypeScript } = require('./typescript-host');
|
|
78
|
+
return (0, analyze_1.analyzeWithHost)(config, (tsConfigFilePath) => {
|
|
79
|
+
try {
|
|
80
|
+
return createTsgoHost(tsConfigFilePath);
|
|
81
|
+
}
|
|
82
|
+
catch (e) {
|
|
83
|
+
// Only startup failures end up here (e.g. no native binary for this platform): analysis errors happen later on
|
|
84
|
+
(0, logging_1.notice)('Could not start the {yellow} engine, falling back to the {yellow} engine (same output, slower):\n{}', 'tsgo', 'typescript', e instanceof Error ? e.message : String(e));
|
|
85
|
+
return createTypeScriptHost(loadTypeScript(sourcePath, config.typescriptPath), tsConfigFilePath);
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
default:
|
|
90
|
+
(0, logging_1.panic)('Unknown analysis engine {yellow} (expected one of: {})', engine, exports.ENGINES.join(', '));
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZW5naW5lL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7Ozs7Ozs7R0FRRzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFFSCx3SEFBd0g7QUFFeEgsTUFBWSxJQUFJLGlDQUFZO0FBSTVCLHdDQUFpRDtBQUVqRCx1Q0FBMkM7QUFFOUIsUUFBQSxPQUFPLEdBQUcsQ0FBQyxNQUFNLEVBQUUsWUFBWSxFQUFFLFVBQVUsQ0FBVSxDQUFBO0FBSWxFLGlIQUFpSDtBQUNqSCxNQUFNLHNCQUFzQixHQUFHLGlCQUFpQixDQUFBO0FBRWhELHNCQUE2QixJQUFZO0lBQ3ZDLE9BQVEsUUFBQSxPQUE2QixDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLEtBQUssc0JBQXNCLENBQUE7QUFDekYsQ0FBQztBQUVNLEtBQUssa0JBQWtCLE1BQWMsRUFBRSxNQUFrQjtJQUM5RCxJQUFBLGVBQUssRUFBQywyQkFBMkIsRUFBRSxNQUFNLENBQUMsQ0FBQTtJQUUxQyxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsRUFBRSxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUE7SUFFbkUsUUFBUSxNQUFnQixFQUFFLENBQUM7UUFDekIsNkRBQTZEO1FBQzdELEtBQUssVUFBVSxFQUFFLENBQUM7WUFDaEIsTUFBTSxFQUFFLFdBQVcsRUFBRSxHQUFpQyxPQUFPLENBQUMsYUFBYSxDQUFDLENBQUE7WUFDNUUsT0FBTyxXQUFXLENBQUMsTUFBTSxDQUFDLENBQUE7UUFDNUIsQ0FBQztRQUVELEtBQUssc0JBQXNCLEVBQUUsQ0FBQztZQUM1QixNQUFNLEVBQUUsdUJBQXVCLEVBQUUsR0FBNEMsT0FBTyxDQUFDLHdCQUF3QixDQUFDLENBQUE7WUFDOUcsT0FBTyxJQUFBLHlCQUFlLEVBQUMsTUFBTSxFQUFFLHVCQUF1QixDQUFDLENBQUE7UUFDekQsQ0FBQztRQUVELEtBQUssWUFBWSxFQUFFLENBQUM7WUFDbEIsTUFBTSxFQUFFLG9CQUFvQixFQUFFLGNBQWMsRUFBRSxHQUF1QyxPQUFPLENBQUMsbUJBQW1CLENBQUMsQ0FBQTtZQUNqSCxPQUFPLElBQUEseUJBQWUsRUFBQyxNQUFNLEVBQUUsQ0FBQyxnQkFBZ0IsRUFBRSxFQUFFLENBQ2xELG9CQUFvQixDQUFDLGNBQWMsQ0FBQyxVQUFVLEVBQUUsTUFBTSxDQUFDLGNBQWMsQ0FBQyxFQUFFLGdCQUFnQixDQUFDLENBQzFGLENBQUE7UUFDSCxDQUFDO1FBRUQsS0FBSyxNQUFNLEVBQUUsQ0FBQztZQUNaLE1BQU0sRUFBRSxjQUFjLEVBQUUsR0FBaUMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxDQUFBO1lBQy9FLE1BQU0sRUFBRSxvQkFBb0IsRUFBRSxjQUFjLEVBQUUsR0FBdUMsT0FBTyxDQUFDLG1CQUFtQixDQUFDLENBQUE7WUFFakgsT0FBTyxJQUFBLHlCQUFlLEVBQUMsTUFBTSxFQUFFLENBQUMsZ0JBQWdCLEVBQUUsRUFBRTtnQkFDbEQsSUFBSSxDQUFDO29CQUNILE9BQU8sY0FBYyxDQUFDLGdCQUFnQixDQUFDLENBQUE7Z0JBQ3pDLENBQUM7Z0JBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztvQkFDWCwrR0FBK0c7b0JBQy9HLElBQUEsZ0JBQU0sRUFDSixxR0FBcUcsRUFDckcsTUFBTSxFQUNOLFlBQVksRUFDWixDQUFDLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQzNDLENBQUE7b0JBQ0QsT0FBTyxvQkFBb0IsQ0FBQyxjQUFjLENBQUMsVUFBVSxFQUFFLE1BQU0sQ0FBQyxjQUFjLENBQUMsRUFBRSxnQkFBZ0IsQ0FBQyxDQUFBO2dCQUNsRyxDQUFDO1lBQ0gsQ0FBQyxDQUFDLENBQUE7UUFDSixDQUFDO1FBRUQ7WUFDRSxJQUFBLGVBQUssRUFBQyx3REFBd0QsRUFBRSxNQUFNLEVBQUUsUUFBQSxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUE7SUFDL0YsQ0FBQztBQUNILENBQUMifQ==
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Analysis host running on the TypeScript program built by ts-morph (TypeScript 4.8)
|
|
3
|
+
*
|
|
4
|
+
* This is not meant for users: it runs the engine-independent analyzer against the exact same program, type checker
|
|
5
|
+
* and file order as the legacy ts-morph analyzer, which lets the parity tests verify both analyzers are equivalent.
|
|
6
|
+
*/
|
|
7
|
+
import { AnalysisHost } from './host';
|
|
8
|
+
export declare function createTsMorphCompatHost(tsConfigFilePath: string): AnalysisHost;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @file Analysis host running on the TypeScript program built by ts-morph (TypeScript 4.8)
|
|
4
|
+
*
|
|
5
|
+
* This is not meant for users: it runs the engine-independent analyzer against the exact same program, type checker
|
|
6
|
+
* and file order as the legacy ts-morph analyzer, which lets the parity tests verify both analyzers are equivalent.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.createTsMorphCompatHost = createTsMorphCompatHost;
|
|
10
|
+
const ts_morph_1 = require("ts-morph");
|
|
11
|
+
const typescript_host_1 = require("./typescript-host");
|
|
12
|
+
function createTsMorphCompatHost(tsConfigFilePath) {
|
|
13
|
+
// Same project setup as the legacy analyzer (src/analyzer/index.ts)
|
|
14
|
+
const project = new ts_morph_1.Project({ tsConfigFilePath });
|
|
15
|
+
const projectFilePaths = project.getSourceFiles().map((file) => file.getFilePath());
|
|
16
|
+
return (0, typescript_host_1.createProgramHost)('ts-morph-compat', ts_morph_1.ts, project.getProgram().compilerObject, projectFilePaths);
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHMtbW9ycGgtY29tcGF0LWhvc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZW5naW5lL3RzLW1vcnBoLWNvbXBhdC1ob3N0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7Ozs7R0FLRzs7O0FBRUgsdUNBQXNDO0FBR3RDLHVEQUFxRDtBQUVyRCxpQ0FBd0MsZ0JBQXdCO0lBQzlELG9FQUFvRTtJQUNwRSxNQUFNLE9BQU8sR0FBRyxJQUFJLGtCQUFPLENBQUMsRUFBRSxnQkFBZ0IsRUFBRSxDQUFDLENBQUE7SUFFakQsTUFBTSxnQkFBZ0IsR0FBRyxPQUFPLENBQUMsY0FBYyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFZLENBQUMsQ0FBQTtJQUU3RixPQUFPLElBQUEsbUNBQWlCLEVBQUMsaUJBQWlCLEVBQUUsYUFBRSxFQUFFLE9BQU8sQ0FBQyxVQUFVLEVBQUUsQ0FBQyxjQUFjLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQTtBQUN4RyxDQUFDIn0=
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Analysis host backed by the TypeScript 7 native compiler (tsgo), through its synchronous API
|
|
3
|
+
*/
|
|
4
|
+
import { AnalysisHost } from './host';
|
|
5
|
+
/**
|
|
6
|
+
* Load the TypeScript 7 API and start a tsgo process
|
|
7
|
+
* Throws if the API can't be loaded or tsgo can't be started (e.g. unsupported platform)
|
|
8
|
+
*/
|
|
9
|
+
export declare function createTsgoHost(tsConfigFilePath: string): AnalysisHost;
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @file Analysis host backed by the TypeScript 7 native compiler (tsgo), through its synchronous API
|
|
4
|
+
*/
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
17
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
18
|
+
}) : function(o, v) {
|
|
19
|
+
o["default"] = v;
|
|
20
|
+
});
|
|
21
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
22
|
+
var ownKeys = function(o) {
|
|
23
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
24
|
+
var ar = [];
|
|
25
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
26
|
+
return ar;
|
|
27
|
+
};
|
|
28
|
+
return ownKeys(o);
|
|
29
|
+
};
|
|
30
|
+
return function (mod) {
|
|
31
|
+
if (mod && mod.__esModule) return mod;
|
|
32
|
+
var result = {};
|
|
33
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
34
|
+
__setModuleDefault(result, mod);
|
|
35
|
+
return result;
|
|
36
|
+
};
|
|
37
|
+
})();
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.createTsgoHost = createTsgoHost;
|
|
40
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
41
|
+
/* eslint-disable @typescript-eslint/no-var-requires -- the TypeScript 7 API is loaded lazily, and can fail to load */
|
|
42
|
+
const fs = __importStar(require("fs"));
|
|
43
|
+
const path = __importStar(require("path"));
|
|
44
|
+
const logging_1 = require("../logging");
|
|
45
|
+
const file_order_1 = require("./file-order");
|
|
46
|
+
const host_1 = require("./host");
|
|
47
|
+
/**
|
|
48
|
+
* The API throws synchronously when the native executable is missing, but if it exists and can't be executed, the
|
|
49
|
+
* failure surfaces as an unhandled 'error' event of the child process, which would crash instead of falling back
|
|
50
|
+
*/
|
|
51
|
+
function assertTsgoIsExecutable() {
|
|
52
|
+
if (process.platform === 'win32')
|
|
53
|
+
return;
|
|
54
|
+
// Same resolution as TypeScript's lib/getExePath.js
|
|
55
|
+
const platformPackage = `@typescript/typescript-${process.platform}-${process.arch}`;
|
|
56
|
+
const packageJson = require.resolve(`${platformPackage}/package.json`, {
|
|
57
|
+
paths: [path.dirname(require.resolve('typescript/package.json'))],
|
|
58
|
+
});
|
|
59
|
+
fs.accessSync(path.join(path.dirname(packageJson), 'lib', 'tsc'), fs.constants.X_OK);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Stop tsgo
|
|
63
|
+
* The API's `close()` sends SIGTERM, to which a busy tsgo process responds by logging "context canceled" to the stderr
|
|
64
|
+
* it shares with this process. tsgo holds no state worth a graceful shutdown, so it is killed with SIGKILL first.
|
|
65
|
+
*/
|
|
66
|
+
function terminate(api) {
|
|
67
|
+
// Private fields of TypeScript 7.0's synchronous API (the dependency's version is pinned)
|
|
68
|
+
const client = api.client;
|
|
69
|
+
const child = client?.channel?.child;
|
|
70
|
+
if (!child) {
|
|
71
|
+
api.close();
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
if (child.exitCode === null && child.signalCode === null) {
|
|
75
|
+
child.kill('SIGKILL');
|
|
76
|
+
}
|
|
77
|
+
// Only close the channel: `api.close()` would first ask the (now dead) process to release its snapshots
|
|
78
|
+
client.close();
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Load the TypeScript 7 API and start a tsgo process
|
|
82
|
+
* Throws if the API can't be loaded or tsgo can't be started (e.g. unsupported platform)
|
|
83
|
+
*/
|
|
84
|
+
function createTsgoHost(tsConfigFilePath) {
|
|
85
|
+
// The synchronous API relies on Node.js internals (and the tsgo process it spawns would then never exit)
|
|
86
|
+
if (process.versions['bun']) {
|
|
87
|
+
throw new Error("TypeScript 7's API requires the Node.js runtime (run the generator with `bun x` or `npx`, without `--bun`)");
|
|
88
|
+
}
|
|
89
|
+
// The API is published as ES modules: this relies on `require(esm)` (Node.js 20.19+ / 22.12+, Bun)
|
|
90
|
+
const { API, TypeFlags } = require('typescript/unstable/sync');
|
|
91
|
+
const { SyntaxKind } = require('typescript/unstable/ast');
|
|
92
|
+
assertTsgoIsExecutable();
|
|
93
|
+
const api = new API({ cwd: path.dirname(tsConfigFilePath) });
|
|
94
|
+
// Errors exit the process right away: stop tsgo then too. Prepended, to run before the API's own exit handler.
|
|
95
|
+
const onExit = () => terminate(api);
|
|
96
|
+
process.prependListener('exit', onExit);
|
|
97
|
+
try {
|
|
98
|
+
const snapshot = api.updateSnapshot({ openProjects: [tsConfigFilePath] });
|
|
99
|
+
const project = snapshot.getProject(tsConfigFilePath);
|
|
100
|
+
if (!project) {
|
|
101
|
+
throw new Error(`tsgo did not load the project for ${tsConfigFilePath}`);
|
|
102
|
+
}
|
|
103
|
+
const { checker, program } = project;
|
|
104
|
+
(0, logging_1.debug)('Using TypeScript {yellow} (native)', String(require('typescript/package.json').version));
|
|
105
|
+
return {
|
|
106
|
+
name: 'tsgo',
|
|
107
|
+
SyntaxKind: SyntaxKind,
|
|
108
|
+
getProjectFilePaths: () => (0, file_order_1.orderProjectFiles)(project.rootFiles, program.getSourceFileNames()),
|
|
109
|
+
getSourceFile: (absolutePath) => program.getSourceFile(absolutePath),
|
|
110
|
+
getTypeAtLocation: (node) => checker.getTypeAtLocation(node),
|
|
111
|
+
getReturnTypeOfDeclaration(node) {
|
|
112
|
+
const signature = checker.getSignatureFromDeclaration(node);
|
|
113
|
+
if (!signature) {
|
|
114
|
+
throw new Error('Expected the node to have a signature.');
|
|
115
|
+
}
|
|
116
|
+
return checker.getReturnTypeOfSignature(signature);
|
|
117
|
+
},
|
|
118
|
+
typeToString: (type) => checker.typeToString(type, undefined, host_1.TYPE_FORMAT_FLAGS),
|
|
119
|
+
isObjectType: (type) => (type.flags & TypeFlags.Object) !== 0,
|
|
120
|
+
getIndexType(type, keyKind) {
|
|
121
|
+
const keyFlag = keyKind === 'string' ? TypeFlags.String : TypeFlags.Number;
|
|
122
|
+
return checker.getIndexInfosOfType(type).find((info) => (info.keyType.flags & keyFlag) !== 0)?.valueType;
|
|
123
|
+
},
|
|
124
|
+
dispose() {
|
|
125
|
+
process.removeListener('exit', onExit);
|
|
126
|
+
terminate(api);
|
|
127
|
+
},
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
catch (e) {
|
|
131
|
+
process.removeListener('exit', onExit);
|
|
132
|
+
terminate(api);
|
|
133
|
+
throw e;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHNnby1ob3N0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2VuZ2luZS90c2dvLWhvc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOztHQUVHOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFFSCx1REFBdUQ7QUFDdkQsc0hBQXNIO0FBRXRILE1BQVksRUFBRSwrQkFBVTtBQUN4QixNQUFZLElBQUksaUNBQVk7QUFFNUIsd0NBQWtDO0FBRWxDLDZDQUFnRDtBQUNoRCxpQ0FBcUY7QUFFckY7OztHQUdHO0FBQ0gsU0FBUyxzQkFBc0I7SUFDN0IsSUFBSSxPQUFPLENBQUMsUUFBUSxLQUFLLE9BQU87UUFBRSxPQUFNO0lBRXhDLG9EQUFvRDtJQUNwRCxNQUFNLGVBQWUsR0FBRywwQkFBMEIsT0FBTyxDQUFDLFFBQVEsSUFBSSxPQUFPLENBQUMsSUFBSSxFQUFFLENBQUE7SUFDcEYsTUFBTSxXQUFXLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxHQUFHLGVBQWUsZUFBZSxFQUFFO1FBQ3JFLEtBQUssRUFBRSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDLENBQUM7S0FDbEUsQ0FBQyxDQUFBO0lBQ0YsRUFBRSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQyxFQUFFLEVBQUUsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUE7QUFDdEYsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxTQUFTLFNBQVMsQ0FBQyxHQUFRO0lBQ3pCLDBGQUEwRjtJQUMxRixNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFBO0lBQ3pCLE1BQU0sS0FBSyxHQUFHLE1BQU0sRUFBRSxPQUFPLEVBQUUsS0FBSyxDQUFBO0lBRXBDLElBQUks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
|