vouchington-tooling 0.33.0 → 0.34.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/README.md +181 -1
- package/dist/api-contract-discovery/index.d.mts +4 -1
- package/dist/api-contract-discovery/index.mjs +1 -0
- package/dist/api-contract-discovery/protocol-analysis-cache.d.mts +21 -0
- package/dist/api-contract-discovery/protocol-analysis-cache.mjs +7 -0
- package/dist/api-contract-discovery/protocol-callback-invocation.d.mts +2 -1
- package/dist/api-contract-discovery/protocol-callback-invocation.mjs +12 -4
- package/dist/api-contract-discovery/protocol-callback-values.d.mts +2 -1
- package/dist/api-contract-discovery/protocol-callback-values.mjs +3 -3
- package/dist/api-contract-discovery/protocol-execution-path.d.mts +2 -1
- package/dist/api-contract-discovery/protocol-execution-path.mjs +2 -2
- package/dist/api-contract-discovery/protocol-http-context-callers.d.mts +2 -1
- package/dist/api-contract-discovery/protocol-http-context-callers.mjs +13 -7
- package/dist/api-contract-discovery/query-contract-extraction.mjs +20 -3
- package/dist/api-contract-discovery/query-contract-literals.d.mts +5 -0
- package/dist/api-contract-discovery/query-contract-literals.mjs +29 -0
- package/dist/api-contract-discovery/registered-route-binding-writes.d.mts +2 -1
- package/dist/api-contract-discovery/registered-route-binding-writes.mjs +20 -11
- package/dist/api-contract-discovery/registered-route-handler-analysis.d.mts +7 -1
- package/dist/api-contract-discovery/registered-route-handler-analysis.mjs +27 -26
- package/dist/api-contract-discovery/registered-route-handler-helpers.d.mts +3 -0
- package/dist/api-contract-discovery/registered-route-handler-helpers.mjs +16 -0
- package/dist/api-contract-discovery/request-validation-callbacks.d.mts +9 -0
- package/dist/api-contract-discovery/request-validation-callbacks.mjs +27 -0
- package/dist/api-contract-discovery/request-validation-checker.d.mts +7 -0
- package/dist/api-contract-discovery/request-validation-checker.mjs +25 -0
- package/dist/api-contract-discovery/request-validation-conditional.d.mts +6 -0
- package/dist/api-contract-discovery/request-validation-conditional.mjs +31 -0
- package/dist/api-contract-discovery/request-validation-factory-calls.d.mts +11 -0
- package/dist/api-contract-discovery/request-validation-factory-calls.mjs +23 -0
- package/dist/api-contract-discovery/request-validation-facts.d.mts +16 -0
- package/dist/api-contract-discovery/request-validation-facts.mjs +64 -0
- package/dist/api-contract-discovery/request-validation-follow.d.mts +24 -0
- package/dist/api-contract-discovery/request-validation-follow.mjs +38 -0
- package/dist/api-contract-discovery/request-validation-handler-state.d.mts +8 -0
- package/dist/api-contract-discovery/request-validation-handler-state.mjs +35 -0
- package/dist/api-contract-discovery/request-validation-input.d.mts +12 -0
- package/dist/api-contract-discovery/request-validation-input.mjs +43 -0
- package/dist/api-contract-discovery/request-validation-keys.d.mts +25 -0
- package/dist/api-contract-discovery/request-validation-keys.mjs +119 -0
- package/dist/api-contract-discovery/request-validation-match.d.mts +11 -0
- package/dist/api-contract-discovery/request-validation-match.mjs +47 -0
- package/dist/api-contract-discovery/request-validation-mutation.d.mts +7 -0
- package/dist/api-contract-discovery/request-validation-mutation.mjs +80 -0
- package/dist/api-contract-discovery/request-validation-origin.d.mts +20 -0
- package/dist/api-contract-discovery/request-validation-origin.mjs +71 -0
- package/dist/api-contract-discovery/request-validation-reads.d.mts +13 -0
- package/dist/api-contract-discovery/request-validation-reads.mjs +88 -0
- package/dist/api-contract-discovery/request-validation-registration.d.mts +9 -0
- package/dist/api-contract-discovery/request-validation-registration.mjs +32 -0
- package/dist/api-contract-discovery/request-validation-report.d.mts +3 -0
- package/dist/api-contract-discovery/request-validation-report.mjs +21 -0
- package/dist/api-contract-discovery/request-validation-request-origin.d.mts +5 -0
- package/dist/api-contract-discovery/request-validation-request-origin.mjs +13 -0
- package/dist/api-contract-discovery/request-validation-select.d.mts +9 -0
- package/dist/api-contract-discovery/request-validation-select.mjs +36 -0
- package/dist/api-contract-discovery/request-validation-sites.d.mts +9 -0
- package/dist/api-contract-discovery/request-validation-sites.mjs +77 -0
- package/dist/api-contract-discovery/request-validation-state-key.d.mts +13 -0
- package/dist/api-contract-discovery/request-validation-state-key.mjs +30 -0
- package/dist/api-contract-discovery/request-validation-trace-helpers.d.mts +14 -0
- package/dist/api-contract-discovery/request-validation-trace-helpers.mjs +80 -0
- package/dist/api-contract-discovery/request-validation-trace-select.d.mts +23 -0
- package/dist/api-contract-discovery/request-validation-trace-select.mjs +45 -0
- package/dist/api-contract-discovery/request-validation-trace.d.mts +8 -0
- package/dist/api-contract-discovery/request-validation-trace.mjs +130 -0
- package/dist/api-contract-discovery/request-validation-types.d.mts +84 -0
- package/dist/api-contract-discovery/request-validation-types.mjs +1 -0
- package/dist/api-contract-discovery/request-validation-walker.d.mts +26 -0
- package/dist/api-contract-discovery/request-validation-walker.mjs +143 -0
- package/dist/api-contract-discovery/request-validation.test-helpers.d.mts +39 -0
- package/dist/api-contract-discovery/request-validation.test-helpers.mjs +108 -0
- package/dist/api-contract-discovery/response-contract-attribution-facts.d.mts +2 -0
- package/dist/api-contract-discovery/response-contract-attribution-facts.mjs +18 -0
- package/dist/api-contract-discovery/response-contract-attribution.d.mts +3 -0
- package/dist/api-contract-discovery/response-contract-attribution.mjs +23 -0
- package/dist/api-contract-discovery/response-contract-call-classification.d.mts +3 -0
- package/dist/api-contract-discovery/response-contract-call-classification.mjs +37 -0
- package/dist/api-contract-discovery/response-contract-error-branch.d.mts +1 -1
- package/dist/api-contract-discovery/response-contract-error-branch.mjs +109 -6
- package/dist/api-contract-discovery/response-contract-handler-bindings.d.mts +3 -0
- package/dist/api-contract-discovery/response-contract-handler-bindings.mjs +126 -0
- package/dist/api-contract-discovery/response-contract-handler-calls.d.mts +3 -0
- package/dist/api-contract-discovery/response-contract-handler-calls.mjs +81 -0
- package/dist/api-contract-discovery/response-contract-implicit-variants.d.mts +2 -0
- package/dist/api-contract-discovery/response-contract-implicit-variants.mjs +6 -0
- package/dist/api-contract-discovery/response-contract-implicit.d.mts +2 -1
- package/dist/api-contract-discovery/response-contract-implicit.mjs +9 -17
- package/dist/api-contract-discovery/response-contract-lenient.d.mts +18 -0
- package/dist/api-contract-discovery/response-contract-object-symbols.d.mts +3 -0
- package/dist/api-contract-discovery/response-contract-object-symbols.mjs +80 -0
- package/dist/api-contract-discovery/response-contract-property-mutations.d.mts +5 -0
- package/dist/api-contract-discovery/response-contract-property-mutations.mjs +84 -0
- package/dist/api-contract-discovery/response-contract-registration.d.mts +1 -1
- package/dist/api-contract-discovery/response-contract-registration.mjs +7 -3
- package/dist/api-contract-discovery/response-contract-registry.mjs +43 -8
- package/dist/api-contract-discovery/response-contract-route-analysis.d.mts +3 -4
- package/dist/api-contract-discovery/response-contract-route-analysis.mjs +4 -101
- package/dist/api-contract-discovery/response-contract-route-syntax.d.mts +7 -0
- package/dist/api-contract-discovery/response-contract-route-syntax.mjs +41 -0
- package/dist/api-contract-discovery/response-contract-symbols.d.mts +5 -0
- package/dist/api-contract-discovery/response-contract-symbols.mjs +82 -0
- package/dist/compiler-build/index.d.mts +2 -0
- package/dist/compiler-build/index.mjs +1 -0
- package/dist/compiler-build/program-configuration.d.mts +9 -0
- package/dist/compiler-build/program-configuration.mjs +28 -0
- package/dist/compiler-build/program-types.d.mts +29 -0
- package/dist/compiler-build/program-types.mjs +1 -0
- package/dist/compiler-build/program.d.mts +7 -0
- package/dist/compiler-build/program.mjs +78 -0
- package/dist/contract-schema/index.d.mts +4 -0
- package/dist/contract-schema/index.mjs +2 -0
- package/dist/contract-schema/type-query-api.d.mts +44 -0
- package/dist/contract-schema/type-query-api.mjs +10 -0
- package/dist/contract-schema/type-query-call.d.mts +16 -0
- package/dist/contract-schema/type-query-call.mjs +52 -0
- package/dist/contract-schema/type-query-export.d.mts +10 -0
- package/dist/contract-schema/type-query-export.mjs +91 -0
- package/dist/contract-schema/type-query.d.mts +22 -0
- package/dist/contract-schema/type-query.mjs +39 -0
- package/dist/finite-enum-ripple/ast.d.mts +9 -0
- package/dist/finite-enum-ripple/ast.mjs +94 -0
- package/dist/finite-enum-ripple/check.d.mts +3 -0
- package/dist/finite-enum-ripple/check.mjs +62 -0
- package/dist/finite-enum-ripple/compare.d.mts +20 -0
- package/dist/finite-enum-ripple/compare.mjs +90 -0
- package/dist/finite-enum-ripple/component-paths.d.mts +8 -0
- package/dist/finite-enum-ripple/component-paths.mjs +30 -0
- package/dist/finite-enum-ripple/configured-object-mutations.d.mts +1 -0
- package/dist/finite-enum-ripple/configured-object-mutations.mjs +78 -0
- package/dist/finite-enum-ripple/create-page-jsx.d.mts +3 -0
- package/dist/finite-enum-ripple/create-page-jsx.mjs +28 -0
- package/dist/finite-enum-ripple/create-page-literals.d.mts +2 -0
- package/dist/finite-enum-ripple/create-page-literals.mjs +83 -0
- package/dist/finite-enum-ripple/create-page-object-visitor.d.mts +2 -0
- package/dist/finite-enum-ripple/create-page-object-visitor.mjs +57 -0
- package/dist/finite-enum-ripple/create-page-properties.d.mts +4 -0
- package/dist/finite-enum-ripple/create-page-properties.mjs +35 -0
- package/dist/finite-enum-ripple/index.d.mts +2 -0
- package/dist/finite-enum-ripple/index.mjs +1 -0
- package/dist/finite-enum-ripple/model.d.mts +74 -0
- package/dist/finite-enum-ripple/model.mjs +1 -0
- package/dist/finite-enum-ripple/parser-support.d.mts +11 -0
- package/dist/finite-enum-ripple/parser-support.mjs +86 -0
- package/dist/finite-enum-ripple/parsers.d.mts +32 -0
- package/dist/finite-enum-ripple/parsers.mjs +113 -0
- package/dist/finite-enum-ripple/pattern-captures.d.mts +2 -0
- package/dist/finite-enum-ripple/pattern-captures.mjs +45 -0
- package/dist/finite-enum-ripple/structured-route-check.d.mts +3 -0
- package/dist/finite-enum-ripple/structured-route-check.mjs +94 -0
- package/dist/finite-enum-ripple/types.d.mts +2 -0
- package/dist/finite-enum-ripple/types.mjs +60 -0
- package/dist/finite-enum-ripple/union-factory-check.d.mts +2 -0
- package/dist/finite-enum-ripple/union-factory-check.mjs +34 -0
- package/dist/finite-enum-ripple/union-types.d.mts +2 -0
- package/dist/finite-enum-ripple/union-types.mjs +129 -0
- package/dist/openapi-document/build-openapi-query.mjs +1 -1
- package/dist/openapi-document/openapi-types.d.mts +1 -1
- package/dist/openapi-document/query-types.d.mts +8 -2
- package/dist/post-publication-inventory/index.d.mts +5 -0
- package/dist/post-publication-inventory/index.mjs +2 -0
- package/dist/post-publication-inventory/readers/sql-executors.d.mts +3 -0
- package/dist/post-publication-inventory/readers/sql-executors.mjs +32 -0
- package/dist/post-publication-inventory/readers/sql-source.d.mts +7 -0
- package/dist/post-publication-inventory/readers/sql-source.mjs +87 -0
- package/dist/post-publication-inventory/readers/sql-template.d.mts +12 -0
- package/dist/post-publication-inventory/readers/sql-template.mjs +119 -0
- package/dist/post-publication-inventory/writers/source.d.mts +9 -0
- package/dist/post-publication-inventory/writers/source.mjs +128 -0
- package/dist/post-publication-inventory/writers/types.d.mts +19 -0
- package/dist/post-publication-inventory/writers/types.mjs +1 -0
- package/package.json +13 -2
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import ts from '../contract-schema/typescript-api.mjs';
|
|
2
|
+
import { functionSymbol, resolveSymbol } from './response-contract-symbols.mjs';
|
|
2
3
|
import { executableProtocolPath } from './protocol-execution-path.mjs';
|
|
4
|
+
import { HTTP_METHODS, propertyName, routeTemplateFromExpression, } from './response-contract-route-syntax.mjs';
|
|
5
|
+
export { collectHandlerBindings } from './response-contract-handler-bindings.mjs';
|
|
6
|
+
export { propertyName, routeTemplateFromExpression, visit, } from './response-contract-route-syntax.mjs';
|
|
3
7
|
export { isContextMethod, isContextResponseBufferCall, isContextResponseEmptyCall, responseMarker, } from './response-contract-ctx-analysis.mjs';
|
|
4
|
-
const HTTP_METHODS = new Set(['GET', 'POST', 'PUT', 'PATCH', 'DELETE']);
|
|
5
8
|
export function requestedKeyForBinding(binding, requestedKeys) {
|
|
6
9
|
if (!requestedKeys)
|
|
7
10
|
return `${binding.method}:${binding.routeTemplate}`;
|
|
@@ -57,106 +60,6 @@ export function enclosingRouteBinding(node, checker, handlerBindings, proveCallb
|
|
|
57
60
|
}
|
|
58
61
|
return undefined;
|
|
59
62
|
}
|
|
60
|
-
export function collectHandlerBindings(sourceFiles, checker) {
|
|
61
|
-
const bindingsBySymbol = new Map();
|
|
62
|
-
for (const sourceFile of sourceFiles) {
|
|
63
|
-
visit(sourceFile, (node) => {
|
|
64
|
-
if (!ts.isCallExpression(node))
|
|
65
|
-
return;
|
|
66
|
-
const method = propertyName(node.expression)?.toUpperCase();
|
|
67
|
-
if (!method || !HTTP_METHODS.has(method))
|
|
68
|
-
return;
|
|
69
|
-
const routeTemplate = routeTemplateFromExpression(node.expression);
|
|
70
|
-
if (!routeTemplate)
|
|
71
|
-
return;
|
|
72
|
-
const binding = { method, routeTemplate };
|
|
73
|
-
for (const symbol of handlerArgumentSymbols(node, checker)) {
|
|
74
|
-
const resolved = resolveSymbol(symbol, checker);
|
|
75
|
-
const candidates = bindingsBySymbol.get(resolved) ?? [];
|
|
76
|
-
candidates.push(binding);
|
|
77
|
-
bindingsBySymbol.set(resolved, candidates);
|
|
78
|
-
}
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
const bindings = new Map();
|
|
82
|
-
for (const [symbol, candidates] of bindingsBySymbol) {
|
|
83
|
-
const [first] = candidates;
|
|
84
|
-
const unambiguous = candidates.every((candidate) => candidate.method === first.method && candidate.routeTemplate === first.routeTemplate);
|
|
85
|
-
// A symbol bound to more than one distinct route (a genuinely shared handler function) can't
|
|
86
|
-
// be attributed to either one — recording an arbitrary winner would misdocument whichever
|
|
87
|
-
// route lost.
|
|
88
|
-
if (unambiguous)
|
|
89
|
-
bindings.set(symbol, first);
|
|
90
|
-
}
|
|
91
|
-
return bindings;
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* Symbols a route registration call directly implicates: identifiers passed by reference
|
|
95
|
-
* (`app.route(...).post(handleThing)`), and — for an inline handler argument — every plain named
|
|
96
|
-
* function it calls directly, e.g. `app.route(...).post(async ctx => { await handleThing(ctx) })`.
|
|
97
|
-
* `enclosingRouteBinding`'s lexical walk can't see through the latter case on its own, since
|
|
98
|
-
* `handleThing`'s body isn't lexically nested inside the route registration at all; recording its
|
|
99
|
-
* symbol here lets the same `handlerBindings` lookup resolve it.
|
|
100
|
-
*/
|
|
101
|
-
function handlerArgumentSymbols(node, checker) {
|
|
102
|
-
const symbols = [];
|
|
103
|
-
for (const argument of node.arguments) {
|
|
104
|
-
if (ts.isIdentifier(argument)) {
|
|
105
|
-
const symbol = checker.getSymbolAtLocation(argument);
|
|
106
|
-
if (symbol)
|
|
107
|
-
symbols.push(symbol);
|
|
108
|
-
continue;
|
|
109
|
-
}
|
|
110
|
-
if (isFunctionLike(argument)) {
|
|
111
|
-
visit(argument, (child) => {
|
|
112
|
-
if (!ts.isCallExpression(child) ||
|
|
113
|
-
!ts.isIdentifier(child.expression) ||
|
|
114
|
-
!executableProtocolPath(child, checker))
|
|
115
|
-
return;
|
|
116
|
-
const symbol = checker.getSymbolAtLocation(child.expression);
|
|
117
|
-
if (symbol)
|
|
118
|
-
symbols.push(symbol);
|
|
119
|
-
});
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
return symbols;
|
|
123
|
-
}
|
|
124
|
-
function functionSymbol(node, checker) {
|
|
125
|
-
if (ts.isFunctionDeclaration(node) && node.name)
|
|
126
|
-
return checker.getSymbolAtLocation(node.name);
|
|
127
|
-
if ((ts.isArrowFunction(node) || ts.isFunctionExpression(node)) &&
|
|
128
|
-
ts.isVariableDeclaration(node.parent) &&
|
|
129
|
-
ts.isIdentifier(node.parent.name)) {
|
|
130
|
-
return checker.getSymbolAtLocation(node.parent.name);
|
|
131
|
-
}
|
|
132
|
-
return undefined;
|
|
133
|
-
}
|
|
134
|
-
function resolveSymbol(symbol, checker) {
|
|
135
|
-
return symbol.flags & ts.SymbolFlags.Alias ? checker.getAliasedSymbol(symbol) : symbol;
|
|
136
|
-
}
|
|
137
|
-
export function routeTemplateFromExpression(expression) {
|
|
138
|
-
if (!ts.isPropertyAccessExpression(expression))
|
|
139
|
-
return undefined;
|
|
140
|
-
return findRouteCall(expression.expression);
|
|
141
|
-
}
|
|
142
|
-
function findRouteCall(expression) {
|
|
143
|
-
if (!ts.isCallExpression(expression))
|
|
144
|
-
return undefined;
|
|
145
|
-
if (!ts.isPropertyAccessExpression(expression.expression))
|
|
146
|
-
return undefined;
|
|
147
|
-
if (expression.expression.name.text === 'route') {
|
|
148
|
-
const route = expression.arguments[0];
|
|
149
|
-
return route && ts.isStringLiteral(route) ? route.text : undefined;
|
|
150
|
-
}
|
|
151
|
-
return findRouteCall(expression.expression.expression);
|
|
152
|
-
}
|
|
153
|
-
export function propertyName(expression) {
|
|
154
|
-
return ts.isPropertyAccessExpression(expression) ? expression.name.text : undefined;
|
|
155
|
-
}
|
|
156
63
|
function isFunctionLike(node) {
|
|
157
64
|
return ts.isArrowFunction(node) || ts.isFunctionExpression(node);
|
|
158
65
|
}
|
|
159
|
-
export function visit(node, callback) {
|
|
160
|
-
callback(node);
|
|
161
|
-
node.forEachChild((child) => visit(child, callback));
|
|
162
|
-
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import ts from '../contract-schema/typescript-api.mts';
|
|
2
|
+
export declare const HTTP_METHODS: Set<string>;
|
|
3
|
+
export declare function isInlineRouteHandler(node: ts.Node): boolean;
|
|
4
|
+
export declare function routeTemplateFromExpression(expression: ts.Expression): string | undefined;
|
|
5
|
+
export declare function propertyName(expression: ts.Expression): string | undefined;
|
|
6
|
+
export declare function unwrapTransparentExpression(expression: ts.Expression): ts.Expression;
|
|
7
|
+
export declare function visit(node: ts.Node, callback: (node: ts.Node) => void): void;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import ts from '../contract-schema/typescript-api.mjs';
|
|
2
|
+
export const HTTP_METHODS = new Set(['GET', 'POST', 'PUT', 'PATCH', 'DELETE']);
|
|
3
|
+
export function isInlineRouteHandler(node) {
|
|
4
|
+
if ((!ts.isArrowFunction(node) && !ts.isFunctionExpression(node)) ||
|
|
5
|
+
!ts.isCallExpression(node.parent))
|
|
6
|
+
return false;
|
|
7
|
+
const method = propertyName(node.parent.expression)?.toUpperCase();
|
|
8
|
+
return (!!method && HTTP_METHODS.has(method) && !!routeTemplateFromExpression(node.parent.expression));
|
|
9
|
+
}
|
|
10
|
+
export function routeTemplateFromExpression(expression) {
|
|
11
|
+
if (!ts.isPropertyAccessExpression(expression))
|
|
12
|
+
return undefined;
|
|
13
|
+
return findRouteCall(expression.expression);
|
|
14
|
+
}
|
|
15
|
+
function findRouteCall(expression) {
|
|
16
|
+
if (!ts.isCallExpression(expression))
|
|
17
|
+
return undefined;
|
|
18
|
+
if (!ts.isPropertyAccessExpression(expression.expression))
|
|
19
|
+
return undefined;
|
|
20
|
+
if (expression.expression.name.text === 'route') {
|
|
21
|
+
const route = expression.arguments[0];
|
|
22
|
+
return route && ts.isStringLiteral(route) ? route.text : undefined;
|
|
23
|
+
}
|
|
24
|
+
return findRouteCall(expression.expression.expression);
|
|
25
|
+
}
|
|
26
|
+
export function propertyName(expression) {
|
|
27
|
+
return ts.isPropertyAccessExpression(expression) ? expression.name.text : undefined;
|
|
28
|
+
}
|
|
29
|
+
export function unwrapTransparentExpression(expression) {
|
|
30
|
+
while (ts.isParenthesizedExpression(expression) ||
|
|
31
|
+
ts.isAsExpression(expression) ||
|
|
32
|
+
ts.isTypeAssertionExpression(expression) ||
|
|
33
|
+
ts.isSatisfiesExpression(expression) ||
|
|
34
|
+
ts.isNonNullExpression(expression))
|
|
35
|
+
expression = expression.expression;
|
|
36
|
+
return expression;
|
|
37
|
+
}
|
|
38
|
+
export function visit(node, callback) {
|
|
39
|
+
callback(node);
|
|
40
|
+
node.forEachChild((child) => visit(child, callback));
|
|
41
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import ts from '../contract-schema/typescript-api.mts';
|
|
2
|
+
export declare function functionSymbol(node: ts.Node, checker: ts.TypeChecker): ts.Symbol | undefined;
|
|
3
|
+
export declare function attributionFunctionSymbol(node: ts.Node, checker: ts.TypeChecker): ts.Symbol | undefined;
|
|
4
|
+
export declare function resolveSymbol(symbol: ts.Symbol, checker: ts.TypeChecker): ts.Symbol;
|
|
5
|
+
export declare function attributionSymbol(symbol: ts.Symbol, checker: ts.TypeChecker): ts.Symbol;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import ts from '../contract-schema/typescript-api.mjs';
|
|
2
|
+
export function functionSymbol(node, checker) {
|
|
3
|
+
if (ts.isFunctionDeclaration(node) && node.name)
|
|
4
|
+
return checker.getSymbolAtLocation(node.name);
|
|
5
|
+
if ((ts.isArrowFunction(node) || ts.isFunctionExpression(node)) &&
|
|
6
|
+
ts.isVariableDeclaration(node.parent) &&
|
|
7
|
+
ts.isIdentifier(node.parent.name)) {
|
|
8
|
+
return checker.getSymbolAtLocation(node.parent.name);
|
|
9
|
+
}
|
|
10
|
+
return undefined;
|
|
11
|
+
}
|
|
12
|
+
export function attributionFunctionSymbol(node, checker) {
|
|
13
|
+
const existing = functionSymbol(node, checker);
|
|
14
|
+
if (existing)
|
|
15
|
+
return existing;
|
|
16
|
+
if (ts.isMethodDeclaration(node) && node.name)
|
|
17
|
+
return checker.getSymbolAtLocation(node.name);
|
|
18
|
+
if (ts.isArrowFunction(node) || ts.isFunctionExpression(node)) {
|
|
19
|
+
const owner = wrappedFunctionOwner(node);
|
|
20
|
+
if (owner &&
|
|
21
|
+
(ts.isVariableDeclaration(owner) ||
|
|
22
|
+
ts.isPropertyAssignment(owner) ||
|
|
23
|
+
ts.isPropertyDeclaration(owner))) {
|
|
24
|
+
return checker.getSymbolAtLocation(owner.name);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
if (ts.isFunctionDeclaration(node) &&
|
|
28
|
+
!node.name &&
|
|
29
|
+
ts.getCombinedModifierFlags(node) & ts.ModifierFlags.Default)
|
|
30
|
+
return defaultExportSymbol(node.getSourceFile(), checker);
|
|
31
|
+
if ((ts.isArrowFunction(node) || ts.isFunctionExpression(node)) &&
|
|
32
|
+
isDefaultExportExpression(node))
|
|
33
|
+
return defaultExportSymbol(node.getSourceFile(), checker);
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
function wrappedFunctionOwner(node) {
|
|
37
|
+
let current = node;
|
|
38
|
+
let parent = current.parent;
|
|
39
|
+
while (ts.isParenthesizedExpression(parent) ||
|
|
40
|
+
ts.isAsExpression(parent) ||
|
|
41
|
+
ts.isTypeAssertionExpression(parent) ||
|
|
42
|
+
ts.isSatisfiesExpression(parent) ||
|
|
43
|
+
ts.isNonNullExpression(parent)) {
|
|
44
|
+
current = parent;
|
|
45
|
+
parent = current.parent;
|
|
46
|
+
}
|
|
47
|
+
if ((ts.isVariableDeclaration(parent) ||
|
|
48
|
+
ts.isPropertyAssignment(parent) ||
|
|
49
|
+
ts.isPropertyDeclaration(parent)) &&
|
|
50
|
+
parent.initializer === current)
|
|
51
|
+
return parent;
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
function isDefaultExportExpression(node) {
|
|
55
|
+
let current = node;
|
|
56
|
+
let parent = current.parent;
|
|
57
|
+
while ((ts.isParenthesizedExpression(parent) ||
|
|
58
|
+
ts.isAsExpression(parent) ||
|
|
59
|
+
ts.isTypeAssertionExpression(parent) ||
|
|
60
|
+
ts.isSatisfiesExpression(parent) ||
|
|
61
|
+
ts.isNonNullExpression(parent)) &&
|
|
62
|
+
parent.expression === current) {
|
|
63
|
+
current = parent;
|
|
64
|
+
parent = current.parent;
|
|
65
|
+
}
|
|
66
|
+
return ts.isExportAssignment(parent) && !parent.isExportEquals && parent.expression === current;
|
|
67
|
+
}
|
|
68
|
+
function defaultExportSymbol(sourceFile, checker) {
|
|
69
|
+
const moduleSymbol = checker.getSymbolAtLocation(sourceFile);
|
|
70
|
+
return (moduleSymbol &&
|
|
71
|
+
checker.getExportsOfModule(moduleSymbol).find((symbol) => symbol.getName() === 'default'));
|
|
72
|
+
}
|
|
73
|
+
export function resolveSymbol(symbol, checker) {
|
|
74
|
+
return symbol.flags & ts.SymbolFlags.Alias ? checker.getAliasedSymbol(symbol) : symbol;
|
|
75
|
+
}
|
|
76
|
+
export function attributionSymbol(symbol, checker) {
|
|
77
|
+
const resolved = resolveSymbol(symbol, checker);
|
|
78
|
+
const name = resolved.valueDeclaration?.name;
|
|
79
|
+
if (!name || !ts.isIdentifier(name))
|
|
80
|
+
return resolved;
|
|
81
|
+
return checker.getSymbolAtLocation(name) ?? resolved;
|
|
82
|
+
}
|
|
@@ -1,2 +1,4 @@
|
|
|
1
1
|
export { compilerHostProbesAreFresh, trackCompilerHost, type CompilerFilesystemHost, type CompilerHostProbeSnapshot, type CompilerHostTrackingOptions, } from './freshness.mts';
|
|
2
2
|
export { settleBuild, type SettlementCallbacks, type SettlementConfirmation, } from './settlement.mts';
|
|
3
|
+
export { createCompilerProgramCache } from './program.mts';
|
|
4
|
+
export type { CompilerProgramCache, CompilerProgramCacheOptions, CompilerProgramGeneration, CompilerProgramSnapshot, } from './program-types.mts';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type ts from '@typescript/typescript6';
|
|
2
|
+
import type { CompilerProgramCacheOptions } from './program-types.mts';
|
|
3
|
+
export interface CompilerProgramConfiguration {
|
|
4
|
+
parsed: ts.ParsedCommandLine;
|
|
5
|
+
roots: string[];
|
|
6
|
+
selectedSources: Set<string> | undefined;
|
|
7
|
+
signature: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function readProgramConfiguration(api: typeof ts, input: CompilerProgramCacheOptions): CompilerProgramConfiguration;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { dirname, resolve } from 'node:path';
|
|
2
|
+
export function readProgramConfiguration(api, input) {
|
|
3
|
+
const configPath = resolve(input.configPath);
|
|
4
|
+
const directory = dirname(configPath);
|
|
5
|
+
const config = api.readConfigFile(configPath, (file) => api.sys.readFile(file));
|
|
6
|
+
const format = (diagnostics) => api.formatDiagnosticsWithColorAndContext(diagnostics, {
|
|
7
|
+
getCanonicalFileName: (file) => file,
|
|
8
|
+
getCurrentDirectory: () => directory,
|
|
9
|
+
getNewLine: () => '\n',
|
|
10
|
+
});
|
|
11
|
+
if (config.error)
|
|
12
|
+
throw new Error(format([config.error]));
|
|
13
|
+
const parsed = api.parseJsonConfigFileContent(config.config, api.sys, directory, undefined, configPath);
|
|
14
|
+
if (parsed.errors.length > 0)
|
|
15
|
+
throw new Error(format(parsed.errors));
|
|
16
|
+
const rootNames = typeof input.rootNames === 'function' ? input.rootNames(parsed) : input.rootNames;
|
|
17
|
+
const roots = (rootNames ?? parsed.fileNames).map((file) => resolve(directory, file));
|
|
18
|
+
const names = typeof input.sourceFilePaths === 'function' ? input.sourceFilePaths() : input.sourceFilePaths;
|
|
19
|
+
const selectedSources = names && new Set(names.map((file) => resolve(directory, file)));
|
|
20
|
+
const signature = JSON.stringify({
|
|
21
|
+
config: config.config,
|
|
22
|
+
options: parsed.options,
|
|
23
|
+
projectReferences: parsed.projectReferences?.map((reference) => reference.path),
|
|
24
|
+
roots,
|
|
25
|
+
sources: selectedSources && [...selectedSources].toSorted(),
|
|
26
|
+
});
|
|
27
|
+
return { parsed, roots, selectedSources, signature };
|
|
28
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type ts from '@typescript/typescript6';
|
|
2
|
+
import type { CompilerHostTrackingOptions } from './freshness.mts';
|
|
3
|
+
declare const generationBrand: unique symbol;
|
|
4
|
+
/** Identity changes on each rebuild, including after clear(). */
|
|
5
|
+
export type CompilerProgramGeneration = {
|
|
6
|
+
readonly [generationBrand]: true;
|
|
7
|
+
};
|
|
8
|
+
export interface CompilerProgramSnapshot {
|
|
9
|
+
readonly generation: CompilerProgramGeneration;
|
|
10
|
+
readonly program: ts.Program;
|
|
11
|
+
readonly sourceFiles: readonly ts.SourceFile[];
|
|
12
|
+
}
|
|
13
|
+
export interface CompilerProgramCache {
|
|
14
|
+
load(): CompilerProgramSnapshot;
|
|
15
|
+
clear(): void;
|
|
16
|
+
readonly buildCount: number;
|
|
17
|
+
}
|
|
18
|
+
export interface CompilerProgramCacheOptions {
|
|
19
|
+
/** Inject a compiler; otherwise load the optional peer when constructing this cache. */
|
|
20
|
+
ts?: typeof ts;
|
|
21
|
+
configPath: string;
|
|
22
|
+
/** Relative names resolve beside configPath; the callback selects parsed roots on each load. */
|
|
23
|
+
rootNames?: readonly string[] | ((configuration: ts.ParsedCommandLine) => readonly string[]);
|
|
24
|
+
/** Omit to return all sources; relative paths resolve beside configPath. */
|
|
25
|
+
sourceFilePaths?: readonly string[] | (() => readonly string[]);
|
|
26
|
+
maximumAttempts?: number;
|
|
27
|
+
tracking?: CompilerHostTrackingOptions;
|
|
28
|
+
}
|
|
29
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { CompilerProgramCache, CompilerProgramCacheOptions } from './program-types.mts';
|
|
2
|
+
/**
|
|
3
|
+
* Reuses a real Program while configuration, roots and recorded filesystem probes are unchanged.
|
|
4
|
+
* Rebuilds release the cache's old generation before allocating another Program. Callers retaining
|
|
5
|
+
* old snapshots still own those references; clear() cannot release caller data.
|
|
6
|
+
*/
|
|
7
|
+
export declare function createCompilerProgramCache(input: CompilerProgramCacheOptions): CompilerProgramCache;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';
|
|
2
|
+
import { resolve } from 'node:path';
|
|
3
|
+
import { compilerHostProbesAreFresh, trackCompilerHost, } from './freshness.mjs';
|
|
4
|
+
import { readProgramConfiguration } from './program-configuration.mjs';
|
|
5
|
+
import { settleBuild } from './settlement.mjs';
|
|
6
|
+
/**
|
|
7
|
+
* Reuses a real Program while configuration, roots and recorded filesystem probes are unchanged.
|
|
8
|
+
* Rebuilds release the cache's old generation before allocating another Program. Callers retaining
|
|
9
|
+
* old snapshots still own those references; clear() cannot release caller data.
|
|
10
|
+
*/
|
|
11
|
+
export function createCompilerProgramCache(input) {
|
|
12
|
+
const api = input.ts ?? createRequire(import.meta.url)('@typescript/typescript6');
|
|
13
|
+
const maximumAttempts = input.maximumAttempts ?? 3;
|
|
14
|
+
let cached;
|
|
15
|
+
let buildCount = 0;
|
|
16
|
+
const readConfiguration = () => {
|
|
17
|
+
try {
|
|
18
|
+
return readProgramConfiguration(api, input);
|
|
19
|
+
}
|
|
20
|
+
catch (error) {
|
|
21
|
+
cached = undefined;
|
|
22
|
+
throw error;
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
return {
|
|
26
|
+
get buildCount() {
|
|
27
|
+
return buildCount;
|
|
28
|
+
},
|
|
29
|
+
clear() {
|
|
30
|
+
cached = undefined;
|
|
31
|
+
},
|
|
32
|
+
load() {
|
|
33
|
+
const configuration = readConfiguration();
|
|
34
|
+
if (cached?.signature === configuration.signature &&
|
|
35
|
+
compilerHostProbesAreFresh(cached.probes()))
|
|
36
|
+
return cached;
|
|
37
|
+
cached = undefined;
|
|
38
|
+
const settled = settleBuild(configuration, maximumAttempts, {
|
|
39
|
+
buildAttempt(current) {
|
|
40
|
+
const tracker = trackCompilerHost(api.createCompilerHost(current.parsed.options, true), {
|
|
41
|
+
readFileReplay: 'when-filesystem-metadata-stable',
|
|
42
|
+
...input.tracking,
|
|
43
|
+
});
|
|
44
|
+
buildCount += 1;
|
|
45
|
+
const program = api.createProgram({
|
|
46
|
+
host: tracker.host,
|
|
47
|
+
options: current.parsed.options,
|
|
48
|
+
rootNames: current.roots,
|
|
49
|
+
...(current.parsed.projectReferences && {
|
|
50
|
+
projectReferences: current.parsed.projectReferences,
|
|
51
|
+
}),
|
|
52
|
+
});
|
|
53
|
+
// Compiler consumers may issue more host reads after construction; retain their probes.
|
|
54
|
+
return { configuration: current, probes: () => tracker.snapshot(), program };
|
|
55
|
+
},
|
|
56
|
+
confirmAttempt(current, value) {
|
|
57
|
+
const confirmed = readConfiguration();
|
|
58
|
+
return {
|
|
59
|
+
configuration: confirmed,
|
|
60
|
+
settled: current.signature === confirmed.signature &&
|
|
61
|
+
compilerHostProbesAreFresh(value.probes()),
|
|
62
|
+
};
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
const selected = settled.configuration.selectedSources;
|
|
66
|
+
cached = {
|
|
67
|
+
generation: Object.freeze({}),
|
|
68
|
+
program: settled.program,
|
|
69
|
+
sourceFiles: settled.program
|
|
70
|
+
.getSourceFiles()
|
|
71
|
+
.filter((file) => !selected || selected.has(resolve(file.fileName))),
|
|
72
|
+
signature: settled.configuration.signature,
|
|
73
|
+
probes: settled.probes,
|
|
74
|
+
};
|
|
75
|
+
return cached;
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
}
|
|
@@ -7,3 +7,7 @@ export { validateResponseContract } from './contract-schema-validator.mts';
|
|
|
7
7
|
export type { ContractValidationIssue, ExtractContractSchemaOptions, ExtractedResponseContract, } from './types.mts';
|
|
8
8
|
export { buildVirtualProgramMatrix, virtualProgramBuildCountForTest } from './virtual-program.mts';
|
|
9
9
|
export type { VirtualProgramMatrix } from './virtual-program.mts';
|
|
10
|
+
export { getExportedTypeFacts } from './type-query.mts';
|
|
11
|
+
export type { ExportedTypeFactsRequest, TypeFacts, TypeFactsRequest, ExportedTypeSelector, TypeScriptApi, TypeScriptProgram, } from './type-query.mts';
|
|
12
|
+
export { getCallRowTypeFacts } from './type-query-call.mts';
|
|
13
|
+
export type { CallRowTypeFacts, CallRowTypeFactsRequest } from './type-query-call.mts';
|
|
@@ -3,3 +3,5 @@ export { extractResponseContracts } from './contract-schema-extractor.mjs';
|
|
|
3
3
|
export { extractContractSchema } from './contract-schema-type-extractor.mjs';
|
|
4
4
|
export { validateResponseContract } from './contract-schema-validator.mjs';
|
|
5
5
|
export { buildVirtualProgramMatrix, virtualProgramBuildCountForTest } from './virtual-program.mjs';
|
|
6
|
+
export { getExportedTypeFacts } from './type-query.mjs';
|
|
7
|
+
export { getCallRowTypeFacts } from './type-query-call.mjs';
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type ts from './typescript-api.mts';
|
|
2
|
+
type NodePredicate<Node extends ts.Node> = {
|
|
3
|
+
check(node: ts.Node): node is Node;
|
|
4
|
+
}['check'];
|
|
5
|
+
type ForEachChild = {
|
|
6
|
+
visit(node: ts.Node, callback: (child: ts.Node) => void): void;
|
|
7
|
+
}['visit'];
|
|
8
|
+
export interface TypeScriptApi {
|
|
9
|
+
readonly IndexKind: {
|
|
10
|
+
readonly Number: number;
|
|
11
|
+
readonly String: number;
|
|
12
|
+
};
|
|
13
|
+
readonly SymbolFlags: {
|
|
14
|
+
readonly Alias: number;
|
|
15
|
+
readonly Type: number;
|
|
16
|
+
readonly Value: number;
|
|
17
|
+
};
|
|
18
|
+
readonly SyntaxKind: {
|
|
19
|
+
readonly SourceFile: number;
|
|
20
|
+
};
|
|
21
|
+
readonly TypeFlags: {
|
|
22
|
+
readonly Any: number;
|
|
23
|
+
readonly Never: number;
|
|
24
|
+
};
|
|
25
|
+
readonly TypeFormatFlags: {
|
|
26
|
+
readonly NoTruncation: ts.TypeFormatFlags.NoTruncation;
|
|
27
|
+
};
|
|
28
|
+
readonly forEachChild: ForEachChild;
|
|
29
|
+
readonly isClassDeclaration: NodePredicate<ts.ClassDeclaration>;
|
|
30
|
+
readonly isCallExpression: NodePredicate<ts.CallExpression>;
|
|
31
|
+
readonly isFunctionDeclaration: NodePredicate<ts.FunctionDeclaration>;
|
|
32
|
+
readonly isInterfaceDeclaration: NodePredicate<ts.InterfaceDeclaration>;
|
|
33
|
+
readonly isIdentifier: NodePredicate<ts.Identifier>;
|
|
34
|
+
readonly isSourceFile: NodePredicate<ts.SourceFile>;
|
|
35
|
+
readonly isTypeReferenceNode: NodePredicate<ts.TypeReferenceNode>;
|
|
36
|
+
readonly isTypeAliasDeclaration: NodePredicate<ts.TypeAliasDeclaration>;
|
|
37
|
+
}
|
|
38
|
+
export interface TypeScriptProgram {
|
|
39
|
+
getSourceFile(fileName: string): unknown;
|
|
40
|
+
getTypeChecker(): unknown;
|
|
41
|
+
}
|
|
42
|
+
export declare function programForQuery(program: TypeScriptProgram): ts.Program;
|
|
43
|
+
export declare function validateTypeScriptApi(typescript: TypeScriptApi, program: TypeScriptProgram, sourceFile: ts.SourceFile): void;
|
|
44
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export function programForQuery(program) {
|
|
2
|
+
return program;
|
|
3
|
+
}
|
|
4
|
+
export function validateTypeScriptApi(typescript, program, sourceFile) {
|
|
5
|
+
if (!typescript.isSourceFile(sourceFile) ||
|
|
6
|
+
sourceFile.kind !== typescript.SyntaxKind.SourceFile) {
|
|
7
|
+
throw new Error('TypeScript API does not recognize the supplied Program source file; pass the same compiler API instance that created the Program');
|
|
8
|
+
}
|
|
9
|
+
program.getTypeChecker();
|
|
10
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type TypeFacts, type TypeFactsRequest } from './type-query.mts';
|
|
2
|
+
import { type TypeScriptApi, type TypeScriptProgram } from './type-query-api.mts';
|
|
3
|
+
export interface CallRowTypeFactsRequest extends TypeFactsRequest {
|
|
4
|
+
readonly program: TypeScriptProgram;
|
|
5
|
+
readonly typescript: TypeScriptApi;
|
|
6
|
+
readonly fileName: string;
|
|
7
|
+
readonly calleeText: string;
|
|
8
|
+
readonly rowSource: 'typeArgument' | 'awaitedRows';
|
|
9
|
+
readonly typeArgumentIndex?: number;
|
|
10
|
+
readonly typeArgumentText?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface CallRowTypeFacts extends TypeFacts {
|
|
13
|
+
readonly line: number;
|
|
14
|
+
readonly column: number;
|
|
15
|
+
}
|
|
16
|
+
export declare function getCallRowTypeFacts(request: CallRowTypeFactsRequest): CallRowTypeFacts[];
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { sourceFileForQuery } from './type-query-export.mjs';
|
|
2
|
+
import { factsForType } from './type-query.mjs';
|
|
3
|
+
import { programForQuery, validateTypeScriptApi, } from './type-query-api.mjs';
|
|
4
|
+
function rowType(typescript, checker, sourceFile, call, request) {
|
|
5
|
+
if (request.rowSource === 'typeArgument') {
|
|
6
|
+
const typeArgument = call.typeArguments?.[request.typeArgumentIndex ?? 0];
|
|
7
|
+
if (!typeArgument) {
|
|
8
|
+
throw new Error(`Missing row type argument for call "${request.calleeText}" in "${sourceFile.fileName}"`);
|
|
9
|
+
}
|
|
10
|
+
return { type: checker.getTypeFromTypeNode(typeArgument), at: typeArgument };
|
|
11
|
+
}
|
|
12
|
+
const result = checker.getAwaitedType(checker.getTypeAtLocation(call));
|
|
13
|
+
if (result && result.flags & (typescript.TypeFlags.Any | typescript.TypeFlags.Never))
|
|
14
|
+
return { type: result, at: call };
|
|
15
|
+
const rowsProperty = result && checker.getPropertyOfType(result, 'rows');
|
|
16
|
+
const rows = rowsProperty
|
|
17
|
+
? checker.getTypeOfSymbolAtLocation(rowsProperty, call)
|
|
18
|
+
: result && checker.getIndexTypeOfType(result, typescript.IndexKind.String);
|
|
19
|
+
if (rows && rows.flags & (typescript.TypeFlags.Any | typescript.TypeFlags.Never)) {
|
|
20
|
+
return { type: rows, at: call };
|
|
21
|
+
}
|
|
22
|
+
const element = rows && checker.getIndexTypeOfType(rows, typescript.IndexKind.Number);
|
|
23
|
+
if (!element) {
|
|
24
|
+
throw new Error(`Missing awaited rows element for call "${request.calleeText}" in "${sourceFile.fileName}"`);
|
|
25
|
+
}
|
|
26
|
+
return { type: element, at: call };
|
|
27
|
+
}
|
|
28
|
+
export function getCallRowTypeFacts(request) {
|
|
29
|
+
const program = programForQuery(request.program);
|
|
30
|
+
const sourceFile = sourceFileForQuery(program, request.fileName);
|
|
31
|
+
validateTypeScriptApi(request.typescript, request.program, sourceFile);
|
|
32
|
+
const checker = program.getTypeChecker();
|
|
33
|
+
const facts = [];
|
|
34
|
+
function visit(node) {
|
|
35
|
+
if (request.typescript.isCallExpression(node) &&
|
|
36
|
+
node.expression.getText(sourceFile) === request.calleeText) {
|
|
37
|
+
const selectedText = node.typeArguments?.[request.typeArgumentIndex ?? 0]?.getText(sourceFile);
|
|
38
|
+
if (request.typeArgumentText === undefined || selectedText === request.typeArgumentText) {
|
|
39
|
+
const row = rowType(request.typescript, checker, sourceFile, node, request);
|
|
40
|
+
const location = sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile));
|
|
41
|
+
facts.push({
|
|
42
|
+
line: location.line + 1,
|
|
43
|
+
column: location.character + 1,
|
|
44
|
+
...factsForType(request.typescript, program, checker, row.type, row.at, request),
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
request.typescript.forEachChild(node, visit);
|
|
49
|
+
}
|
|
50
|
+
visit(sourceFile);
|
|
51
|
+
return facts;
|
|
52
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type ts from './typescript-api.mts';
|
|
2
|
+
import type { TypeScriptApi } from './type-query-api.mts';
|
|
3
|
+
export interface ExportedTypeSelector {
|
|
4
|
+
readonly fileName: string;
|
|
5
|
+
readonly exportName: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function sourceFileForQuery(program: ts.Program, fileName: string): ts.SourceFile;
|
|
8
|
+
export declare function exportedType(typescript: TypeScriptApi, program: ts.Program, checker: ts.TypeChecker, selector: ExportedTypeSelector): ts.Type;
|
|
9
|
+
export declare function exportedAssignableType(typescript: TypeScriptApi, program: ts.Program, checker: ts.TypeChecker, selector: ExportedTypeSelector): ts.Type;
|
|
10
|
+
export declare function exportedDefaultType(typescript: TypeScriptApi, program: ts.Program, checker: ts.TypeChecker, selector: ExportedTypeSelector, parameterIndex: number): ts.Type;
|