zinfer 0.2.7 → 1.0.0-next.1
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/dist/core/brand-detector.d.ts +2 -21
- package/dist/core/brand-detector.d.ts.map +1 -1
- package/dist/core/brand-detector.js +40 -67
- package/dist/core/brand-detector.js.map +1 -1
- package/dist/core/config-loader.d.ts.map +1 -1
- package/dist/core/description-extractor.d.ts +0 -22
- package/dist/core/description-extractor.d.ts.map +1 -1
- package/dist/core/description-extractor.js +21 -110
- package/dist/core/description-extractor.js.map +1 -1
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core/errors.js +1 -28
- package/dist/core/errors.js.map +1 -1
- package/dist/core/extractor.d.ts +3 -37
- package/dist/core/extractor.d.ts.map +1 -1
- package/dist/core/extractor.js +42 -178
- package/dist/core/extractor.js.map +1 -1
- package/dist/core/file-resolver.d.ts.map +1 -1
- package/dist/core/file-resolver.js.map +1 -1
- package/dist/core/getter-resolver.d.ts +2 -46
- package/dist/core/getter-resolver.d.ts.map +1 -1
- package/dist/core/getter-resolver.js +33 -85
- package/dist/core/getter-resolver.js.map +1 -1
- package/dist/core/import-resolver.d.ts +10 -30
- package/dist/core/import-resolver.d.ts.map +1 -1
- package/dist/core/import-resolver.js +59 -112
- package/dist/core/import-resolver.js.map +1 -1
- package/dist/core/index.d.ts +0 -2
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +0 -2
- package/dist/core/index.js.map +1 -1
- package/dist/core/logger.d.ts +0 -6
- package/dist/core/logger.d.ts.map +1 -1
- package/dist/core/logger.js +2 -9
- package/dist/core/logger.js.map +1 -1
- package/dist/core/name-mapper.d.ts.map +1 -1
- package/dist/core/name-mapper.js.map +1 -1
- package/dist/core/schema-detector.d.ts +10 -30
- package/dist/core/schema-detector.d.ts.map +1 -1
- package/dist/core/schema-detector.js +60 -82
- package/dist/core/schema-detector.js.map +1 -1
- package/dist/core/schema-reference-analyzer.d.ts +2 -56
- package/dist/core/schema-reference-analyzer.d.ts.map +1 -1
- package/dist/core/schema-reference-analyzer.js +89 -137
- package/dist/core/schema-reference-analyzer.js.map +1 -1
- package/dist/core/test-generator.d.ts.map +1 -1
- package/dist/core/test-generator.js.map +1 -1
- package/dist/core/ts-host.d.ts +38 -0
- package/dist/core/ts-host.d.ts.map +1 -0
- package/dist/core/ts-host.js +2 -0
- package/dist/core/ts-host.js.map +1 -0
- package/dist/core/tsgo-ast-utils.d.ts +12 -0
- package/dist/core/tsgo-ast-utils.d.ts.map +1 -0
- package/dist/core/tsgo-ast-utils.js +43 -0
- package/dist/core/tsgo-ast-utils.js.map +1 -0
- package/dist/core/tsgo-host.d.ts +72 -0
- package/dist/core/tsgo-host.d.ts.map +1 -0
- package/dist/core/tsgo-host.js +232 -0
- package/dist/core/tsgo-host.js.map +1 -0
- package/dist/core/type-printer.d.ts.map +1 -1
- package/dist/core/type-printer.js +8 -13
- package/dist/core/type-printer.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
|
@@ -1,26 +1,19 @@
|
|
|
1
|
-
import { SyntaxKind,
|
|
2
|
-
|
|
3
|
-
* Detects and resolves getter-based recursive patterns in Zod schemas.
|
|
4
|
-
*/
|
|
1
|
+
import { SyntaxKind, isCallExpression, isIdentifier, isPropertyAccessExpression, } from "@typescript/native-preview/unstable/ast";
|
|
2
|
+
import { findFirstDescendantByKind, getDescendantsOfKind } from "./tsgo-ast-utils.js";
|
|
5
3
|
export class GetterResolver {
|
|
6
|
-
/**
|
|
7
|
-
* Analyzes a source file to find getter field mappings.
|
|
8
|
-
*
|
|
9
|
-
* @param sourceFile - The ts-morph SourceFile to analyze
|
|
10
|
-
* @returns Map of schema name to field info
|
|
11
|
-
*/
|
|
12
4
|
analyzeGetterFields(sourceFile, schemaNames) {
|
|
13
5
|
const result = new Map();
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
6
|
+
for (const statement of sourceFile.statements) {
|
|
7
|
+
if (statement.kind !== SyntaxKind.VariableStatement)
|
|
8
|
+
continue;
|
|
9
|
+
for (const decl of statement.declarationList.declarations) {
|
|
10
|
+
const schemaName = decl.name.getText(sourceFile);
|
|
18
11
|
if (schemaNames && !schemaNames.has(schemaName))
|
|
19
12
|
continue;
|
|
20
|
-
const init = decl.
|
|
13
|
+
const init = decl.initializer;
|
|
21
14
|
if (!init)
|
|
22
15
|
continue;
|
|
23
|
-
const fieldMap = this.extractGetterFieldsFromAST(init, schemaName);
|
|
16
|
+
const fieldMap = this.extractGetterFieldsFromAST(init, schemaName, sourceFile);
|
|
24
17
|
if (fieldMap.size > 0) {
|
|
25
18
|
result.set(schemaName, fieldMap);
|
|
26
19
|
}
|
|
@@ -28,84 +21,70 @@ export class GetterResolver {
|
|
|
28
21
|
}
|
|
29
22
|
return result;
|
|
30
23
|
}
|
|
31
|
-
|
|
32
|
-
* Extracts getter field info from AST nodes.
|
|
33
|
-
*/
|
|
34
|
-
extractGetterFieldsFromAST(node, schemaName) {
|
|
24
|
+
extractGetterFieldsFromAST(node, schemaName, sourceFile) {
|
|
35
25
|
const fieldMap = new Map();
|
|
36
|
-
|
|
37
|
-
const getters = node.getDescendantsOfKind(SyntaxKind.GetAccessor);
|
|
26
|
+
const getters = getDescendantsOfKind(node, SyntaxKind.GetAccessor);
|
|
38
27
|
for (const getter of getters) {
|
|
39
|
-
const fieldName = getter.
|
|
40
|
-
const body = getter.
|
|
28
|
+
const fieldName = getter.name.getText(sourceFile);
|
|
29
|
+
const body = getter.body;
|
|
41
30
|
if (!body)
|
|
42
31
|
continue;
|
|
43
|
-
|
|
44
|
-
const returnStmt = body.getFirstDescendantByKind(SyntaxKind.ReturnStatement);
|
|
32
|
+
const returnStmt = findFirstDescendantByKind(body, SyntaxKind.ReturnStatement);
|
|
45
33
|
if (!returnStmt)
|
|
46
34
|
continue;
|
|
47
|
-
const returnExpr = returnStmt.
|
|
35
|
+
const returnExpr = returnStmt.expression;
|
|
48
36
|
if (!returnExpr)
|
|
49
37
|
continue;
|
|
50
|
-
const info = this.parseReturnExpressionAST(returnExpr, schemaName);
|
|
38
|
+
const info = this.parseReturnExpressionAST(returnExpr, schemaName, sourceFile);
|
|
51
39
|
if (info) {
|
|
52
40
|
fieldMap.set(fieldName, info);
|
|
53
41
|
}
|
|
54
42
|
}
|
|
55
43
|
return fieldMap;
|
|
56
44
|
}
|
|
57
|
-
|
|
58
|
-
* Parses the return expression AST to extract schema reference info.
|
|
59
|
-
*/
|
|
60
|
-
parseReturnExpressionAST(expr, schemaName) {
|
|
45
|
+
parseReturnExpressionAST(expr, schemaName, sourceFile) {
|
|
61
46
|
let isArray = false;
|
|
62
47
|
let isRecord = false;
|
|
63
48
|
let isOptional = false;
|
|
64
49
|
let refSchema = null;
|
|
65
|
-
// Unwrap method chains like .optional(), .nullable(), .array()
|
|
66
50
|
let currentExpr = expr;
|
|
67
|
-
while (
|
|
51
|
+
while (isCallExpression(currentExpr)) {
|
|
68
52
|
const callExpr = currentExpr;
|
|
69
|
-
const exprNode = callExpr.
|
|
70
|
-
if (
|
|
71
|
-
const
|
|
72
|
-
const
|
|
73
|
-
const baseExpr = propAccess.getExpression();
|
|
74
|
-
// Check for .optional() or .nullable() on a schema
|
|
53
|
+
const exprNode = callExpr.expression;
|
|
54
|
+
if (isPropertyAccessExpression(exprNode)) {
|
|
55
|
+
const methodName = exprNode.name.getText(sourceFile);
|
|
56
|
+
const baseExpr = exprNode.expression;
|
|
75
57
|
if (methodName === "optional" || methodName === "nullable") {
|
|
76
58
|
isOptional = true;
|
|
77
59
|
currentExpr = baseExpr;
|
|
78
60
|
continue;
|
|
79
61
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
const baseName = baseExpr.getText();
|
|
62
|
+
if (methodName === "array" && isIdentifier(baseExpr)) {
|
|
63
|
+
const baseName = baseExpr.getText(sourceFile);
|
|
83
64
|
if (baseName !== "z") {
|
|
84
65
|
isArray = true;
|
|
85
66
|
refSchema = baseName;
|
|
86
67
|
break;
|
|
87
68
|
}
|
|
88
69
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
const args = callExpr.getArguments();
|
|
70
|
+
if (isIdentifier(baseExpr) && baseExpr.getText(sourceFile) === "z") {
|
|
71
|
+
const args = callExpr.arguments;
|
|
92
72
|
if (methodName === "array" && args.length > 0) {
|
|
93
73
|
isArray = true;
|
|
94
|
-
refSchema = this.extractSchemaRef(args[0]);
|
|
74
|
+
refSchema = this.extractSchemaRef(args[0], sourceFile);
|
|
95
75
|
break;
|
|
96
76
|
}
|
|
97
77
|
if (methodName === "record" && args.length >= 2) {
|
|
98
78
|
isRecord = true;
|
|
99
|
-
refSchema = this.extractSchemaRef(args[1]);
|
|
79
|
+
refSchema = this.extractSchemaRef(args[1], sourceFile);
|
|
100
80
|
break;
|
|
101
81
|
}
|
|
102
82
|
}
|
|
103
83
|
}
|
|
104
84
|
break;
|
|
105
85
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
refSchema = currentExpr.getText();
|
|
86
|
+
if (!refSchema && isIdentifier(currentExpr)) {
|
|
87
|
+
refSchema = currentExpr.getText(sourceFile);
|
|
109
88
|
}
|
|
110
89
|
if (!refSchema) {
|
|
111
90
|
return null;
|
|
@@ -118,55 +97,35 @@ export class GetterResolver {
|
|
|
118
97
|
isSelfRef: refSchema === schemaName,
|
|
119
98
|
};
|
|
120
99
|
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
extractSchemaRef(node) {
|
|
125
|
-
if (Node.isIdentifier(node)) {
|
|
126
|
-
return node.getText();
|
|
100
|
+
extractSchemaRef(node, sourceFile) {
|
|
101
|
+
if (isIdentifier(node)) {
|
|
102
|
+
return node.getText(sourceFile);
|
|
127
103
|
}
|
|
128
104
|
return null;
|
|
129
105
|
}
|
|
130
|
-
/**
|
|
131
|
-
* Resolves `any` types in extracted type string by replacing with self-references.
|
|
132
|
-
* Uses structured parsing instead of regex.
|
|
133
|
-
*
|
|
134
|
-
* @param typeStr - The extracted type string with `any` placeholders
|
|
135
|
-
* @param getterFields - Map of field name to getter field info
|
|
136
|
-
* @param typeName - The generated type name to use for self-references
|
|
137
|
-
* @returns The resolved type string with proper self-references
|
|
138
|
-
*/
|
|
139
106
|
resolveAnyTypes(typeStr, getterFields, typeName) {
|
|
140
107
|
let result = typeStr;
|
|
141
108
|
for (const [fieldName, info] of getterFields) {
|
|
142
109
|
if (!info.isSelfRef) {
|
|
143
110
|
continue;
|
|
144
111
|
}
|
|
145
|
-
// For z.record pattern: { [x: string]: any } -> { [x: string]: TypeName }
|
|
146
112
|
if (info.isRecord) {
|
|
147
113
|
result = this.replaceRecordAny(result, fieldName, typeName);
|
|
148
114
|
}
|
|
149
|
-
// Handle any field (array or single reference)
|
|
150
115
|
result = this.replaceFieldAny(result, fieldName, typeName, info.isArray);
|
|
151
116
|
}
|
|
152
117
|
return result;
|
|
153
118
|
}
|
|
154
|
-
/**
|
|
155
|
-
* Replaces any type in a record field.
|
|
156
|
-
*/
|
|
157
119
|
replaceRecordAny(typeStr, fieldName, typeName) {
|
|
158
|
-
// Find "fieldName: { [x: string]: any" or "fieldName?: { [x: string]: any"
|
|
159
120
|
const fieldPatterns = [`${fieldName}: {`, `${fieldName}?: {`];
|
|
160
121
|
const indexSigPattern = "[x: string]:";
|
|
161
122
|
for (const pattern of fieldPatterns) {
|
|
162
123
|
let idx = typeStr.indexOf(pattern);
|
|
163
124
|
while (idx !== -1) {
|
|
164
|
-
// Find the index signature pattern
|
|
165
125
|
const afterBrace = idx + pattern.length;
|
|
166
126
|
const indexSigStart = typeStr.indexOf(indexSigPattern, afterBrace);
|
|
167
127
|
if (indexSigStart !== -1 && indexSigStart < afterBrace + 20) {
|
|
168
128
|
const colonPos = indexSigStart + indexSigPattern.length;
|
|
169
|
-
// Find "any" after the colon - count whitespace explicitly
|
|
170
129
|
let scanPos = colonPos;
|
|
171
130
|
while (scanPos < typeStr.length && /\s/.test(typeStr[scanPos])) {
|
|
172
131
|
scanPos++;
|
|
@@ -182,18 +141,13 @@ export class GetterResolver {
|
|
|
182
141
|
}
|
|
183
142
|
return typeStr;
|
|
184
143
|
}
|
|
185
|
-
/**
|
|
186
|
-
* Replaces any type in a regular field.
|
|
187
|
-
*/
|
|
188
144
|
replaceFieldAny(typeStr, fieldName, typeName, isArray) {
|
|
189
|
-
// Find "fieldName: any" or "fieldName?: any" patterns
|
|
190
145
|
const fieldPatterns = [`${fieldName}: `, `${fieldName}?: `];
|
|
191
146
|
for (const pattern of fieldPatterns) {
|
|
192
147
|
let idx = typeStr.indexOf(pattern);
|
|
193
148
|
while (idx !== -1) {
|
|
194
149
|
const valueStart = idx + pattern.length;
|
|
195
150
|
const restOfType = typeStr.substring(valueStart);
|
|
196
|
-
// Check for "readonly any" or just "any"
|
|
197
151
|
let anyIdx = -1;
|
|
198
152
|
let prefixLen = 0;
|
|
199
153
|
if (restOfType.startsWith("readonly ")) {
|
|
@@ -206,15 +160,12 @@ export class GetterResolver {
|
|
|
206
160
|
anyIdx = valueStart;
|
|
207
161
|
}
|
|
208
162
|
if (anyIdx !== -1) {
|
|
209
|
-
// Check what comes after "any"
|
|
210
163
|
const afterAny = typeStr.substring(anyIdx + 3);
|
|
211
164
|
const hasArrayBrackets = afterAny.startsWith("[]");
|
|
212
|
-
// Build replacement
|
|
213
165
|
let replacement = typeName;
|
|
214
166
|
if (isArray || hasArrayBrackets) {
|
|
215
167
|
replacement = `${typeName}[]`;
|
|
216
168
|
}
|
|
217
|
-
// Calculate end position (include [] if present)
|
|
218
169
|
let endPos = anyIdx + 3;
|
|
219
170
|
if (hasArrayBrackets) {
|
|
220
171
|
endPos += 2;
|
|
@@ -226,9 +177,6 @@ export class GetterResolver {
|
|
|
226
177
|
}
|
|
227
178
|
return typeStr;
|
|
228
179
|
}
|
|
229
|
-
/**
|
|
230
|
-
* Checks if a schema has getter-based self-references.
|
|
231
|
-
*/
|
|
232
180
|
hasSelfReferences(getterFields) {
|
|
233
181
|
return Array.from(getterFields.values()).some((info) => info.isSelfRef);
|
|
234
182
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getter-resolver.js","sourceRoot":"","sources":["../../src/core/getter-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"getter-resolver.js","sourceRoot":"","sources":["../../src/core/getter-resolver.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,37 +1,23 @@
|
|
|
1
|
-
import { SourceFile
|
|
1
|
+
import type { SourceFile } from "@typescript/native-preview/unstable/ast";
|
|
2
|
+
import type { Project } from "@typescript/native-preview/unstable/sync";
|
|
2
3
|
import { SchemaDetector } from "./schema-detector.js";
|
|
3
4
|
/**
|
|
4
|
-
*
|
|
5
|
+
* ImportResolver, implemented against the tsgo/Corsa API. Cross-file module
|
|
6
|
+
* resolution goes through `Checker.getSymbolAtLocation` on the module
|
|
7
|
+
* specifier expression instead of ts-morph's `getModuleSpecifierSourceFile`.
|
|
8
|
+
* See issue #200.
|
|
5
9
|
*/
|
|
6
10
|
export interface ImportedSchemaInfo {
|
|
7
|
-
/** Local name used in the importing file */
|
|
8
11
|
localName: string;
|
|
9
|
-
/** Original name in the source file */
|
|
10
12
|
originalName: string;
|
|
11
|
-
/** Resolved source file path */
|
|
12
13
|
sourceFilePath: string;
|
|
13
|
-
/** Whether the schema was successfully resolved */
|
|
14
14
|
resolved: boolean;
|
|
15
15
|
}
|
|
16
|
-
/**
|
|
17
|
-
* Map of local schema name to imported schema info.
|
|
18
|
-
*/
|
|
19
16
|
export type ImportedSchemaMap = Map<string, ImportedSchemaInfo>;
|
|
20
|
-
/**
|
|
21
|
-
* Resolves imported schemas from other files.
|
|
22
|
-
*/
|
|
23
17
|
export declare class ImportResolver {
|
|
24
18
|
private schemaDetector;
|
|
25
|
-
private moduleResolutionCache;
|
|
26
19
|
private schemaSourceCache;
|
|
27
20
|
constructor(schemaDetector?: SchemaDetector);
|
|
28
|
-
/**
|
|
29
|
-
* Finds all imported schemas in a source file.
|
|
30
|
-
*
|
|
31
|
-
* @param sourceFile - The source file to analyze
|
|
32
|
-
* @param project - The ts-morph project for module resolution
|
|
33
|
-
* @returns Map of local names to imported schema info
|
|
34
|
-
*/
|
|
35
21
|
findImportedSchemas(sourceFile: SourceFile, project: Project): ImportedSchemaMap;
|
|
36
22
|
/**
|
|
37
23
|
* Finds the actual source file containing a schema definition.
|
|
@@ -39,16 +25,10 @@ export declare class ImportResolver {
|
|
|
39
25
|
*/
|
|
40
26
|
private findSchemaSource;
|
|
41
27
|
/**
|
|
42
|
-
* Resolves a module specifier to
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Generates possible file paths for a module specifier and resolves to a source file.
|
|
47
|
-
*/
|
|
48
|
-
private resolveFromPossiblePaths;
|
|
49
|
-
/**
|
|
50
|
-
* Resolves an import declaration to its source file.
|
|
28
|
+
* Resolves a module specifier expression node to its target source file via
|
|
29
|
+
* the checker's symbol resolution (respects the project's configured
|
|
30
|
+
* module resolution, including package.json "imports" subpath mappings).
|
|
51
31
|
*/
|
|
52
|
-
private
|
|
32
|
+
private resolveModuleSpecifierNode;
|
|
53
33
|
}
|
|
54
34
|
//# sourceMappingURL=import-resolver.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"import-resolver.d.ts","sourceRoot":"","sources":["../../src/core/import-resolver.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"import-resolver.d.ts","sourceRoot":"","sources":["../../src/core/import-resolver.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAIV,UAAU,EACX,MAAM,yCAAyC,CAAC;AACjD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,0CAA0C,CAAC;AACxE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAGtD;;;;;GAKG;AACH,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,MAAM,iBAAiB,GAAG,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;AAEhE,qBAAa,cAAc;IACzB,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,iBAAiB,CAGrB;gBAEQ,cAAc,CAAC,EAAE,cAAc;IAI3C,mBAAmB,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,GAAG,iBAAiB;IAkDhF;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAmExB;;;;OAIG;IACH,OAAO,CAAC,0BAA0B;CAiBnC"}
|
|
@@ -1,56 +1,46 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { SyntaxKind, isNamedExports, isNamedImports, isStringLiteral, } from "@typescript/native-preview/unstable/ast";
|
|
2
2
|
import { SchemaDetector } from "./schema-detector.js";
|
|
3
3
|
import { logDebugError } from "./logger.js";
|
|
4
|
-
/**
|
|
5
|
-
* Resolves imported schemas from other files.
|
|
6
|
-
*/
|
|
7
4
|
export class ImportResolver {
|
|
8
5
|
schemaDetector;
|
|
9
|
-
moduleResolutionCache = new Map();
|
|
10
6
|
schemaSourceCache = new Map();
|
|
11
7
|
constructor(schemaDetector) {
|
|
12
8
|
this.schemaDetector = schemaDetector ?? new SchemaDetector();
|
|
13
9
|
}
|
|
14
|
-
/**
|
|
15
|
-
* Finds all imported schemas in a source file.
|
|
16
|
-
*
|
|
17
|
-
* @param sourceFile - The source file to analyze
|
|
18
|
-
* @param project - The ts-morph project for module resolution
|
|
19
|
-
* @returns Map of local names to imported schema info
|
|
20
|
-
*/
|
|
21
10
|
findImportedSchemas(sourceFile, project) {
|
|
22
11
|
const result = new Map();
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
12
|
+
for (const statement of sourceFile.statements) {
|
|
13
|
+
if (statement.kind !== SyntaxKind.ImportDeclaration)
|
|
14
|
+
continue;
|
|
15
|
+
const importDecl = statement;
|
|
16
|
+
const moduleSpecifierNode = importDecl.moduleSpecifier;
|
|
17
|
+
const moduleSpecifier = isStringLiteral(moduleSpecifierNode) ? moduleSpecifierNode.text : "";
|
|
26
18
|
// Skip bare module specifiers (node_modules), but allow relative,
|
|
27
|
-
// absolute, and subpath imports (package.json "imports" field
|
|
28
|
-
// "#/schemas/user.js"). Subpath imports — including the "#/*" form — are
|
|
29
|
-
// resolved by TypeScript's own module resolution (requires the
|
|
30
|
-
// TypeScript 6 bundled by ts-morph).
|
|
19
|
+
// absolute, and subpath imports (package.json "imports" field).
|
|
31
20
|
if (!moduleSpecifier.startsWith(".") &&
|
|
32
21
|
!moduleSpecifier.startsWith("/") &&
|
|
33
22
|
!moduleSpecifier.startsWith("#")) {
|
|
34
23
|
continue;
|
|
35
24
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
if (!resolvedSourceFile) {
|
|
25
|
+
const resolvedSourceFile = this.resolveModuleSpecifierNode(moduleSpecifierNode, project);
|
|
26
|
+
if (!resolvedSourceFile)
|
|
39
27
|
continue;
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
for (const namedImport of
|
|
44
|
-
const importedName = namedImport.
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
28
|
+
const namedBindings = importDecl.importClause?.namedBindings;
|
|
29
|
+
if (!namedBindings || !isNamedImports(namedBindings))
|
|
30
|
+
continue;
|
|
31
|
+
for (const namedImport of namedBindings.elements) {
|
|
32
|
+
const importedName = namedImport.propertyName
|
|
33
|
+
? namedImport.propertyName.getText(sourceFile)
|
|
34
|
+
: namedImport.name.getText(sourceFile);
|
|
35
|
+
const localName = namedImport.name.getText(sourceFile);
|
|
36
|
+
// Find the actual source file containing the schema definition.
|
|
37
|
+
// This handles re-exports from index.ts files.
|
|
48
38
|
const actualSource = this.findSchemaSource(resolvedSourceFile, importedName, project);
|
|
49
39
|
if (actualSource) {
|
|
50
40
|
result.set(localName, {
|
|
51
41
|
localName,
|
|
52
42
|
originalName: actualSource.schemaName,
|
|
53
|
-
sourceFilePath: actualSource.sourceFile.
|
|
43
|
+
sourceFilePath: actualSource.sourceFile.fileName,
|
|
54
44
|
resolved: true,
|
|
55
45
|
});
|
|
56
46
|
}
|
|
@@ -63,35 +53,30 @@ export class ImportResolver {
|
|
|
63
53
|
* Follows re-exports (export * from "./other") to find the original.
|
|
64
54
|
*/
|
|
65
55
|
findSchemaSource(sourceFile, schemaName, project, visited = new Set()) {
|
|
66
|
-
const filePath = sourceFile.
|
|
67
|
-
// Check cross-call cache first
|
|
56
|
+
const filePath = sourceFile.fileName;
|
|
68
57
|
const cacheKey = `${filePath}:${schemaName}`;
|
|
69
58
|
if (this.schemaSourceCache.has(cacheKey)) {
|
|
70
59
|
return this.schemaSourceCache.get(cacheKey);
|
|
71
60
|
}
|
|
72
|
-
// Prevent infinite loops
|
|
73
61
|
if (visited.has(filePath)) {
|
|
74
62
|
return undefined;
|
|
75
63
|
}
|
|
76
64
|
visited.add(filePath);
|
|
77
|
-
// Check if the schema is defined directly in this file
|
|
78
65
|
const schemas = this.schemaDetector.detectExportedSchemas(sourceFile);
|
|
79
66
|
if (schemas.some((s) => s.name === schemaName)) {
|
|
80
67
|
const result = { sourceFile, schemaName };
|
|
81
68
|
this.schemaSourceCache.set(cacheKey, result);
|
|
82
69
|
return result;
|
|
83
70
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
const
|
|
88
|
-
if (!moduleSpecifier)
|
|
71
|
+
for (const statement of sourceFile.statements) {
|
|
72
|
+
if (statement.kind !== SyntaxKind.ExportDeclaration)
|
|
73
|
+
continue;
|
|
74
|
+
const exportDecl = statement;
|
|
75
|
+
if (!exportDecl.moduleSpecifier)
|
|
89
76
|
continue;
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
// This is "export * from './module'" - follow it
|
|
94
|
-
const reExportedFile = this.resolveModuleSpecifier(sourceFile, moduleSpecifier, project);
|
|
77
|
+
if (!exportDecl.exportClause) {
|
|
78
|
+
// "export * from './module'" - follow it
|
|
79
|
+
const reExportedFile = this.resolveModuleSpecifierNode(exportDecl.moduleSpecifier, project);
|
|
95
80
|
if (reExportedFile) {
|
|
96
81
|
const found = this.findSchemaSource(reExportedFile, schemaName, project, visited);
|
|
97
82
|
if (found) {
|
|
@@ -99,21 +84,23 @@ export class ImportResolver {
|
|
|
99
84
|
return found;
|
|
100
85
|
}
|
|
101
86
|
}
|
|
87
|
+
continue;
|
|
102
88
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
89
|
+
if (!isNamedExports(exportDecl.exportClause))
|
|
90
|
+
continue;
|
|
91
|
+
for (const namedExport of exportDecl.exportClause.elements) {
|
|
92
|
+
const exportedName = namedExport.name.getText(sourceFile);
|
|
93
|
+
if (exportedName !== schemaName)
|
|
94
|
+
continue;
|
|
95
|
+
const originalName = namedExport.propertyName
|
|
96
|
+
? namedExport.propertyName.getText(sourceFile)
|
|
97
|
+
: exportedName;
|
|
98
|
+
const reExportedFile = this.resolveModuleSpecifierNode(exportDecl.moduleSpecifier, project);
|
|
99
|
+
if (reExportedFile) {
|
|
100
|
+
const found = this.findSchemaSource(reExportedFile, originalName, project, visited);
|
|
101
|
+
if (found) {
|
|
102
|
+
this.schemaSourceCache.set(cacheKey, found);
|
|
103
|
+
return found;
|
|
117
104
|
}
|
|
118
105
|
}
|
|
119
106
|
}
|
|
@@ -122,64 +109,24 @@ export class ImportResolver {
|
|
|
122
109
|
return undefined;
|
|
123
110
|
}
|
|
124
111
|
/**
|
|
125
|
-
* Resolves a module specifier to
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
const sourceDir = fromFile.getDirectoryPath();
|
|
129
|
-
return this.resolveFromPossiblePaths(sourceDir, moduleSpecifier, project);
|
|
130
|
-
}
|
|
131
|
-
/**
|
|
132
|
-
* Generates possible file paths for a module specifier and resolves to a source file.
|
|
133
|
-
*/
|
|
134
|
-
resolveFromPossiblePaths(sourceDir, moduleSpecifier, project) {
|
|
135
|
-
const cacheKey = `${sourceDir}:${moduleSpecifier}`;
|
|
136
|
-
if (this.moduleResolutionCache.has(cacheKey)) {
|
|
137
|
-
return this.moduleResolutionCache.get(cacheKey);
|
|
138
|
-
}
|
|
139
|
-
const possiblePaths = [
|
|
140
|
-
join(sourceDir, `${moduleSpecifier}.ts`),
|
|
141
|
-
join(sourceDir, moduleSpecifier, "index.ts"),
|
|
142
|
-
join(sourceDir, `${moduleSpecifier}.js`),
|
|
143
|
-
join(sourceDir, moduleSpecifier, "index.js"),
|
|
144
|
-
];
|
|
145
|
-
for (const possiblePath of possiblePaths) {
|
|
146
|
-
let resolved = project.getSourceFile(possiblePath);
|
|
147
|
-
if (!resolved) {
|
|
148
|
-
try {
|
|
149
|
-
resolved = project.addSourceFileAtPathIfExists(possiblePath);
|
|
150
|
-
}
|
|
151
|
-
catch (error) {
|
|
152
|
-
logDebugError(`Failed to add source file at ${possiblePath}`, error);
|
|
153
|
-
continue;
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
if (resolved) {
|
|
157
|
-
this.moduleResolutionCache.set(cacheKey, resolved);
|
|
158
|
-
return resolved;
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
this.moduleResolutionCache.set(cacheKey, undefined);
|
|
162
|
-
return undefined;
|
|
163
|
-
}
|
|
164
|
-
/**
|
|
165
|
-
* Resolves an import declaration to its source file.
|
|
112
|
+
* Resolves a module specifier expression node to its target source file via
|
|
113
|
+
* the checker's symbol resolution (respects the project's configured
|
|
114
|
+
* module resolution, including package.json "imports" subpath mappings).
|
|
166
115
|
*/
|
|
167
|
-
|
|
168
|
-
const moduleSpecifier = importDecl.getModuleSpecifierValue();
|
|
116
|
+
resolveModuleSpecifierNode(moduleSpecifierNode, project) {
|
|
169
117
|
try {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
return this.resolveFromPossiblePaths(sourceDir, moduleSpecifier, project);
|
|
118
|
+
const symbol = project.checker.getSymbolAtLocation(moduleSpecifierNode);
|
|
119
|
+
if (!symbol)
|
|
120
|
+
return undefined;
|
|
121
|
+
const decl = symbol.declarations[0];
|
|
122
|
+
if (!decl)
|
|
123
|
+
return undefined;
|
|
124
|
+
return project.program.getSourceFile(decl.path);
|
|
178
125
|
}
|
|
179
126
|
catch (error) {
|
|
180
|
-
logDebugError(
|
|
127
|
+
logDebugError("Module resolution failed", error);
|
|
128
|
+
return undefined;
|
|
181
129
|
}
|
|
182
|
-
return undefined;
|
|
183
130
|
}
|
|
184
131
|
}
|
|
185
132
|
//# sourceMappingURL=import-resolver.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"import-resolver.js","sourceRoot":"","sources":["../../src/core/import-resolver.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"import-resolver.js","sourceRoot":"","sources":["../../src/core/import-resolver.ts"],"names":[],"mappings":"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"}
|