zinfer 0.0.1 → 0.1.2
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 +477 -28
- package/bin/zinfer +2 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +486 -0
- package/dist/cli.js.map +1 -0
- package/dist/core/brand-detector.d.ts +32 -0
- package/dist/core/brand-detector.d.ts.map +1 -0
- package/dist/core/brand-detector.js +121 -0
- package/dist/core/brand-detector.js.map +1 -0
- package/dist/core/config-loader.d.ts +87 -0
- package/dist/core/config-loader.d.ts.map +1 -0
- package/dist/core/config-loader.js +105 -0
- package/dist/core/config-loader.js.map +1 -0
- package/dist/core/description-extractor.d.ts +54 -0
- package/dist/core/description-extractor.d.ts.map +1 -0
- package/dist/core/description-extractor.js +180 -0
- package/dist/core/description-extractor.js.map +1 -0
- package/dist/core/errors.d.ts +35 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +96 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/extractor.d.ts +121 -0
- package/dist/core/extractor.d.ts.map +1 -0
- package/dist/core/extractor.js +504 -0
- package/dist/core/extractor.js.map +1 -0
- package/dist/core/file-resolver.d.ts +41 -0
- package/dist/core/file-resolver.d.ts.map +1 -0
- package/dist/core/file-resolver.js +95 -0
- package/dist/core/file-resolver.js.map +1 -0
- package/dist/core/getter-resolver.d.ts +67 -0
- package/dist/core/getter-resolver.d.ts.map +1 -0
- package/dist/core/getter-resolver.js +234 -0
- package/dist/core/getter-resolver.js.map +1 -0
- package/dist/core/import-resolver.d.ts +51 -0
- package/dist/core/import-resolver.d.ts.map +1 -0
- package/dist/core/import-resolver.js +158 -0
- package/dist/core/import-resolver.js.map +1 -0
- package/dist/core/index.d.ts +14 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +13 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/logger.d.ts +20 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/logger.js +36 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/name-mapper.d.ts +45 -0
- package/dist/core/name-mapper.d.ts.map +1 -0
- package/dist/core/name-mapper.js +82 -0
- package/dist/core/name-mapper.js.map +1 -0
- package/dist/core/normalizer.d.ts +24 -0
- package/dist/core/normalizer.d.ts.map +1 -0
- package/dist/core/normalizer.js +50 -0
- package/dist/core/normalizer.js.map +1 -0
- package/dist/core/schema-detector.d.ts +49 -0
- package/dist/core/schema-detector.d.ts.map +1 -0
- package/dist/core/schema-detector.js +272 -0
- package/dist/core/schema-detector.js.map +1 -0
- package/dist/core/schema-reference-analyzer.d.ts +77 -0
- package/dist/core/schema-reference-analyzer.d.ts.map +1 -0
- package/dist/core/schema-reference-analyzer.js +269 -0
- package/dist/core/schema-reference-analyzer.js.map +1 -0
- package/dist/core/test-generator.d.ts +97 -0
- package/dist/core/test-generator.d.ts.map +1 -0
- package/dist/core/test-generator.js +177 -0
- package/dist/core/test-generator.js.map +1 -0
- package/dist/core/type-printer.d.ts +46 -0
- package/dist/core/type-printer.d.ts.map +1 -0
- package/dist/core/type-printer.js +519 -0
- package/dist/core/type-printer.js.map +1 -0
- package/dist/core/types.d.ts +124 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +5 -0
- package/dist/core/types.js.map +1 -0
- package/dist/index.d.ts +66 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +79 -0
- package/dist/index.js.map +1 -0
- package/package.json +63 -7
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { OutputOptions } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Resolves file paths from glob patterns and generates output paths.
|
|
4
|
+
*/
|
|
5
|
+
export declare class FileResolver {
|
|
6
|
+
/**
|
|
7
|
+
* Resolves input file paths from a glob pattern or array of patterns.
|
|
8
|
+
*
|
|
9
|
+
* @param pattern - Glob pattern(s) to match
|
|
10
|
+
* @param cwd - Current working directory (default: process.cwd())
|
|
11
|
+
* @returns Array of absolute file paths
|
|
12
|
+
*/
|
|
13
|
+
resolveInputFiles(pattern: string | string[], cwd?: string): Promise<string[]>;
|
|
14
|
+
/**
|
|
15
|
+
* Resolves the output path for a given input file.
|
|
16
|
+
*
|
|
17
|
+
* @param inputPath - Absolute path to the input file
|
|
18
|
+
* @param options - Output options
|
|
19
|
+
* @param cwd - Current working directory
|
|
20
|
+
* @returns Absolute path to the output file
|
|
21
|
+
*/
|
|
22
|
+
resolveOutputPath(inputPath: string, options: OutputOptions, cwd?: string): string;
|
|
23
|
+
/**
|
|
24
|
+
* Applies a pattern template to generate an output filename.
|
|
25
|
+
*
|
|
26
|
+
* Supported placeholders:
|
|
27
|
+
* - [name]: Input filename without extension
|
|
28
|
+
* - [dir]: Parent directory name of the input file
|
|
29
|
+
* - [ext]: Output extension (including dot)
|
|
30
|
+
*
|
|
31
|
+
* @param pattern - Pattern template (e.g., "[name].types[ext]")
|
|
32
|
+
* @param vars - Variables to substitute
|
|
33
|
+
* @returns Generated filename
|
|
34
|
+
*/
|
|
35
|
+
applyPattern(pattern: string, vars: {
|
|
36
|
+
name: string;
|
|
37
|
+
dir?: string;
|
|
38
|
+
ext: string;
|
|
39
|
+
}): string;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=file-resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-resolver.d.ts","sourceRoot":"","sources":["../../src/core/file-resolver.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD;;GAEG;AACH,qBAAa,YAAY;IACvB;;;;;;OAMG;IACG,iBAAiB,CACrB,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,EAC1B,GAAG,GAAE,MAAsB,GAC1B,OAAO,CAAC,MAAM,EAAE,CAAC;IAiBpB;;;;;;;OAOG;IACH,iBAAiB,CACf,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,aAAa,EACtB,GAAG,GAAE,MAAsB,GAC1B,MAAM;IAsCT;;;;;;;;;;;OAWG;IACH,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM;CAWzF"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { glob } from "glob";
|
|
2
|
+
import { resolve, dirname, basename, extname, join } from "pathe";
|
|
3
|
+
/**
|
|
4
|
+
* Resolves file paths from glob patterns and generates output paths.
|
|
5
|
+
*/
|
|
6
|
+
export class FileResolver {
|
|
7
|
+
/**
|
|
8
|
+
* Resolves input file paths from a glob pattern or array of patterns.
|
|
9
|
+
*
|
|
10
|
+
* @param pattern - Glob pattern(s) to match
|
|
11
|
+
* @param cwd - Current working directory (default: process.cwd())
|
|
12
|
+
* @returns Array of absolute file paths
|
|
13
|
+
*/
|
|
14
|
+
async resolveInputFiles(pattern, cwd = process.cwd()) {
|
|
15
|
+
const patterns = Array.isArray(pattern) ? pattern : [pattern];
|
|
16
|
+
const allFiles = [];
|
|
17
|
+
for (const p of patterns) {
|
|
18
|
+
const files = await glob(p, {
|
|
19
|
+
cwd,
|
|
20
|
+
absolute: true,
|
|
21
|
+
nodir: true,
|
|
22
|
+
});
|
|
23
|
+
allFiles.push(...files);
|
|
24
|
+
}
|
|
25
|
+
// Remove duplicates and sort
|
|
26
|
+
return [...new Set(allFiles)].sort();
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Resolves the output path for a given input file.
|
|
30
|
+
*
|
|
31
|
+
* @param inputPath - Absolute path to the input file
|
|
32
|
+
* @param options - Output options
|
|
33
|
+
* @param cwd - Current working directory
|
|
34
|
+
* @returns Absolute path to the output file
|
|
35
|
+
*/
|
|
36
|
+
resolveOutputPath(inputPath, options, cwd = process.cwd()) {
|
|
37
|
+
// If outFile is specified, use it directly
|
|
38
|
+
if (options.outFile) {
|
|
39
|
+
return resolve(cwd, options.outFile);
|
|
40
|
+
}
|
|
41
|
+
// Determine base name, extension, and parent directory name
|
|
42
|
+
const inputBasename = basename(inputPath);
|
|
43
|
+
const inputExt = extname(inputPath);
|
|
44
|
+
const inputName = inputBasename.slice(0, -inputExt.length);
|
|
45
|
+
const inputDir = basename(dirname(inputPath));
|
|
46
|
+
// Apply output pattern
|
|
47
|
+
let outputName;
|
|
48
|
+
if (options.outPattern) {
|
|
49
|
+
outputName = this.applyPattern(options.outPattern, {
|
|
50
|
+
name: inputName,
|
|
51
|
+
dir: inputDir,
|
|
52
|
+
ext: options.declaration ? ".d.ts" : ".ts",
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
// Default pattern: [name].types.ts or [name].types.d.ts
|
|
57
|
+
const ext = options.declaration ? ".d.ts" : ".ts";
|
|
58
|
+
outputName = `${inputName}.types${ext}`;
|
|
59
|
+
}
|
|
60
|
+
// Determine output directory
|
|
61
|
+
let outputDir;
|
|
62
|
+
if (options.outDir) {
|
|
63
|
+
outputDir = resolve(cwd, options.outDir);
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
// Same directory as input
|
|
67
|
+
outputDir = dirname(inputPath);
|
|
68
|
+
}
|
|
69
|
+
return join(outputDir, outputName);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Applies a pattern template to generate an output filename.
|
|
73
|
+
*
|
|
74
|
+
* Supported placeholders:
|
|
75
|
+
* - [name]: Input filename without extension
|
|
76
|
+
* - [dir]: Parent directory name of the input file
|
|
77
|
+
* - [ext]: Output extension (including dot)
|
|
78
|
+
*
|
|
79
|
+
* @param pattern - Pattern template (e.g., "[name].types[ext]")
|
|
80
|
+
* @param vars - Variables to substitute
|
|
81
|
+
* @returns Generated filename
|
|
82
|
+
*/
|
|
83
|
+
applyPattern(pattern, vars) {
|
|
84
|
+
// Escape $ in replacement strings to prevent regex special character interpretation
|
|
85
|
+
// In String.replace(), $& means the matched substring, $1 means first capture group, etc.
|
|
86
|
+
const escapedName = vars.name.replace(/\$/g, "$$$$");
|
|
87
|
+
const escapedDir = (vars.dir ?? vars.name).replace(/\$/g, "$$$$");
|
|
88
|
+
const escapedExt = vars.ext.replace(/\$/g, "$$$$");
|
|
89
|
+
return pattern
|
|
90
|
+
.replace(/\[name\]/g, escapedName)
|
|
91
|
+
.replace(/\[dir\]/g, escapedDir)
|
|
92
|
+
.replace(/\[ext\]/g, escapedExt);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=file-resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-resolver.js","sourceRoot":"","sources":["../../src/core/file-resolver.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { SourceFile } from "ts-morph";
|
|
2
|
+
/**
|
|
3
|
+
* Information about a getter field in a z.object schema.
|
|
4
|
+
*/
|
|
5
|
+
export interface GetterFieldInfo {
|
|
6
|
+
/** Referenced schema name */
|
|
7
|
+
refSchema: string;
|
|
8
|
+
/** Whether the reference is wrapped in z.array() */
|
|
9
|
+
isArray: boolean;
|
|
10
|
+
/** Whether the reference is wrapped in z.record() */
|
|
11
|
+
isRecord: boolean;
|
|
12
|
+
/** Whether the field is optional (.optional() or .nullable()) */
|
|
13
|
+
isOptional: boolean;
|
|
14
|
+
/** Whether this is a self-reference */
|
|
15
|
+
isSelfRef: boolean;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Mapping of schema name to its getter field information.
|
|
19
|
+
*/
|
|
20
|
+
export type GetterFieldMap = Map<string, Map<string, GetterFieldInfo>>;
|
|
21
|
+
/**
|
|
22
|
+
* Detects and resolves getter-based recursive patterns in Zod schemas.
|
|
23
|
+
*/
|
|
24
|
+
export declare class GetterResolver {
|
|
25
|
+
/**
|
|
26
|
+
* Analyzes a source file to find getter field mappings.
|
|
27
|
+
*
|
|
28
|
+
* @param sourceFile - The ts-morph SourceFile to analyze
|
|
29
|
+
* @returns Map of schema name to field info
|
|
30
|
+
*/
|
|
31
|
+
analyzeGetterFields(sourceFile: SourceFile): GetterFieldMap;
|
|
32
|
+
/**
|
|
33
|
+
* Extracts getter field info from AST nodes.
|
|
34
|
+
*/
|
|
35
|
+
private extractGetterFieldsFromAST;
|
|
36
|
+
/**
|
|
37
|
+
* Parses the return expression AST to extract schema reference info.
|
|
38
|
+
*/
|
|
39
|
+
private parseReturnExpressionAST;
|
|
40
|
+
/**
|
|
41
|
+
* Extracts schema reference from an argument node.
|
|
42
|
+
*/
|
|
43
|
+
private extractSchemaRef;
|
|
44
|
+
/**
|
|
45
|
+
* Resolves `any` types in extracted type string by replacing with self-references.
|
|
46
|
+
* Uses structured parsing instead of regex.
|
|
47
|
+
*
|
|
48
|
+
* @param typeStr - The extracted type string with `any` placeholders
|
|
49
|
+
* @param getterFields - Map of field name to getter field info
|
|
50
|
+
* @param typeName - The generated type name to use for self-references
|
|
51
|
+
* @returns The resolved type string with proper self-references
|
|
52
|
+
*/
|
|
53
|
+
resolveAnyTypes(typeStr: string, getterFields: Map<string, GetterFieldInfo>, typeName: string): string;
|
|
54
|
+
/**
|
|
55
|
+
* Replaces any type in a record field.
|
|
56
|
+
*/
|
|
57
|
+
private replaceRecordAny;
|
|
58
|
+
/**
|
|
59
|
+
* Replaces any type in a regular field.
|
|
60
|
+
*/
|
|
61
|
+
private replaceFieldAny;
|
|
62
|
+
/**
|
|
63
|
+
* Checks if a schema has getter-based self-references.
|
|
64
|
+
*/
|
|
65
|
+
hasSelfReferences(getterFields: Map<string, GetterFieldInfo>): boolean;
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=getter-resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getter-resolver.d.ts","sourceRoot":"","sources":["../../src/core/getter-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAA8D,MAAM,UAAU,CAAC;AAElG;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,6BAA6B;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,oDAAoD;IACpD,OAAO,EAAE,OAAO,CAAC;IACjB,qDAAqD;IACrD,QAAQ,EAAE,OAAO,CAAC;IAClB,iEAAiE;IACjE,UAAU,EAAE,OAAO,CAAC;IACpB,uCAAuC;IACvC,SAAS,EAAE,OAAO,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC;AAEvE;;GAEG;AACH,qBAAa,cAAc;IACzB;;;;;OAKG;IACH,mBAAmB,CAAC,UAAU,EAAE,UAAU,GAAG,cAAc;IAqB3D;;OAEG;IACH,OAAO,CAAC,0BAA0B;IA2BlC;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAyEhC;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAOxB;;;;;;;;OAQG;IACH,eAAe,CACb,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,EAC1C,QAAQ,EAAE,MAAM,GACf,MAAM;IAoBT;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAkCxB;;OAEG;IACH,OAAO,CAAC,eAAe;IAuDvB;;OAEG;IACH,iBAAiB,CAAC,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,GAAG,OAAO;CAGvE"}
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import { SyntaxKind, Node } from "ts-morph";
|
|
2
|
+
/**
|
|
3
|
+
* Detects and resolves getter-based recursive patterns in Zod schemas.
|
|
4
|
+
*/
|
|
5
|
+
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
|
+
analyzeGetterFields(sourceFile) {
|
|
13
|
+
const result = new Map();
|
|
14
|
+
const statements = sourceFile.getVariableStatements();
|
|
15
|
+
for (const stmt of statements) {
|
|
16
|
+
for (const decl of stmt.getDeclarations()) {
|
|
17
|
+
const schemaName = decl.getName();
|
|
18
|
+
const init = decl.getInitializer();
|
|
19
|
+
if (!init)
|
|
20
|
+
continue;
|
|
21
|
+
const fieldMap = this.extractGetterFieldsFromAST(init, schemaName);
|
|
22
|
+
if (fieldMap.size > 0) {
|
|
23
|
+
result.set(schemaName, fieldMap);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return result;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Extracts getter field info from AST nodes.
|
|
31
|
+
*/
|
|
32
|
+
extractGetterFieldsFromAST(node, schemaName) {
|
|
33
|
+
const fieldMap = new Map();
|
|
34
|
+
// Find all getter declarations within the node
|
|
35
|
+
const getters = node.getDescendantsOfKind(SyntaxKind.GetAccessor);
|
|
36
|
+
for (const getter of getters) {
|
|
37
|
+
const fieldName = getter.getName();
|
|
38
|
+
const body = getter.getBody();
|
|
39
|
+
if (!body)
|
|
40
|
+
continue;
|
|
41
|
+
// Find return statement
|
|
42
|
+
const returnStmt = body.getFirstDescendantByKind(SyntaxKind.ReturnStatement);
|
|
43
|
+
if (!returnStmt)
|
|
44
|
+
continue;
|
|
45
|
+
const returnExpr = returnStmt.getExpression();
|
|
46
|
+
if (!returnExpr)
|
|
47
|
+
continue;
|
|
48
|
+
const info = this.parseReturnExpressionAST(returnExpr, schemaName);
|
|
49
|
+
if (info) {
|
|
50
|
+
fieldMap.set(fieldName, info);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return fieldMap;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Parses the return expression AST to extract schema reference info.
|
|
57
|
+
*/
|
|
58
|
+
parseReturnExpressionAST(expr, schemaName) {
|
|
59
|
+
let isArray = false;
|
|
60
|
+
let isRecord = false;
|
|
61
|
+
let isOptional = false;
|
|
62
|
+
let refSchema = null;
|
|
63
|
+
// Unwrap method chains like .optional(), .nullable(), .array()
|
|
64
|
+
let currentExpr = expr;
|
|
65
|
+
while (Node.isCallExpression(currentExpr)) {
|
|
66
|
+
const callExpr = currentExpr;
|
|
67
|
+
const exprNode = callExpr.getExpression();
|
|
68
|
+
if (Node.isPropertyAccessExpression(exprNode)) {
|
|
69
|
+
const propAccess = exprNode;
|
|
70
|
+
const methodName = propAccess.getName();
|
|
71
|
+
const baseExpr = propAccess.getExpression();
|
|
72
|
+
// Check for .optional() or .nullable() on a schema
|
|
73
|
+
if (methodName === "optional" || methodName === "nullable") {
|
|
74
|
+
isOptional = true;
|
|
75
|
+
currentExpr = baseExpr;
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
// Check for SchemaName.array() pattern
|
|
79
|
+
if (methodName === "array" && Node.isIdentifier(baseExpr)) {
|
|
80
|
+
const baseName = baseExpr.getText();
|
|
81
|
+
if (baseName !== "z") {
|
|
82
|
+
isArray = true;
|
|
83
|
+
refSchema = baseName;
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
// Check for z.array(SchemaName) or z.record(key, SchemaName)
|
|
88
|
+
if (Node.isIdentifier(baseExpr) && baseExpr.getText() === "z") {
|
|
89
|
+
const args = callExpr.getArguments();
|
|
90
|
+
if (methodName === "array" && args.length > 0) {
|
|
91
|
+
isArray = true;
|
|
92
|
+
refSchema = this.extractSchemaRef(args[0]);
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
if (methodName === "record" && args.length >= 2) {
|
|
96
|
+
isRecord = true;
|
|
97
|
+
refSchema = this.extractSchemaRef(args[1]);
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
// If we haven't found a ref yet, check if currentExpr is an identifier
|
|
105
|
+
if (!refSchema && Node.isIdentifier(currentExpr)) {
|
|
106
|
+
refSchema = currentExpr.getText();
|
|
107
|
+
}
|
|
108
|
+
if (!refSchema) {
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
return {
|
|
112
|
+
refSchema,
|
|
113
|
+
isArray,
|
|
114
|
+
isRecord,
|
|
115
|
+
isOptional,
|
|
116
|
+
isSelfRef: refSchema === schemaName,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Extracts schema reference from an argument node.
|
|
121
|
+
*/
|
|
122
|
+
extractSchemaRef(node) {
|
|
123
|
+
if (Node.isIdentifier(node)) {
|
|
124
|
+
return node.getText();
|
|
125
|
+
}
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Resolves `any` types in extracted type string by replacing with self-references.
|
|
130
|
+
* Uses structured parsing instead of regex.
|
|
131
|
+
*
|
|
132
|
+
* @param typeStr - The extracted type string with `any` placeholders
|
|
133
|
+
* @param getterFields - Map of field name to getter field info
|
|
134
|
+
* @param typeName - The generated type name to use for self-references
|
|
135
|
+
* @returns The resolved type string with proper self-references
|
|
136
|
+
*/
|
|
137
|
+
resolveAnyTypes(typeStr, getterFields, typeName) {
|
|
138
|
+
let result = typeStr;
|
|
139
|
+
for (const [fieldName, info] of getterFields) {
|
|
140
|
+
if (!info.isSelfRef) {
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
// For z.record pattern: { [x: string]: any } -> { [x: string]: TypeName }
|
|
144
|
+
if (info.isRecord) {
|
|
145
|
+
result = this.replaceRecordAny(result, fieldName, typeName);
|
|
146
|
+
}
|
|
147
|
+
// Handle any field (array or single reference)
|
|
148
|
+
result = this.replaceFieldAny(result, fieldName, typeName, info.isArray);
|
|
149
|
+
}
|
|
150
|
+
return result;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Replaces any type in a record field.
|
|
154
|
+
*/
|
|
155
|
+
replaceRecordAny(typeStr, fieldName, typeName) {
|
|
156
|
+
// Find "fieldName: { [x: string]: any" or "fieldName?: { [x: string]: any"
|
|
157
|
+
const fieldPatterns = [`${fieldName}: {`, `${fieldName}?: {`];
|
|
158
|
+
const indexSigPattern = "[x: string]:";
|
|
159
|
+
for (const pattern of fieldPatterns) {
|
|
160
|
+
let idx = typeStr.indexOf(pattern);
|
|
161
|
+
while (idx !== -1) {
|
|
162
|
+
// Find the index signature pattern
|
|
163
|
+
const afterBrace = idx + pattern.length;
|
|
164
|
+
const indexSigStart = typeStr.indexOf(indexSigPattern, afterBrace);
|
|
165
|
+
if (indexSigStart !== -1 && indexSigStart < afterBrace + 20) {
|
|
166
|
+
const colonPos = indexSigStart + indexSigPattern.length;
|
|
167
|
+
// Find "any" after the colon - count whitespace explicitly
|
|
168
|
+
let scanPos = colonPos;
|
|
169
|
+
while (scanPos < typeStr.length && /\s/.test(typeStr[scanPos])) {
|
|
170
|
+
scanPos++;
|
|
171
|
+
}
|
|
172
|
+
if (typeStr.substring(scanPos, scanPos + 3) === "any") {
|
|
173
|
+
const anyStart = scanPos;
|
|
174
|
+
const anyEnd = anyStart + 3;
|
|
175
|
+
typeStr = typeStr.substring(0, anyStart) + typeName + typeStr.substring(anyEnd);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
idx = typeStr.indexOf(pattern, idx + 1);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return typeStr;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Replaces any type in a regular field.
|
|
185
|
+
*/
|
|
186
|
+
replaceFieldAny(typeStr, fieldName, typeName, isArray) {
|
|
187
|
+
// Find "fieldName: any" or "fieldName?: any" patterns
|
|
188
|
+
const fieldPatterns = [`${fieldName}: `, `${fieldName}?: `];
|
|
189
|
+
for (const pattern of fieldPatterns) {
|
|
190
|
+
let idx = typeStr.indexOf(pattern);
|
|
191
|
+
while (idx !== -1) {
|
|
192
|
+
const valueStart = idx + pattern.length;
|
|
193
|
+
const restOfType = typeStr.substring(valueStart);
|
|
194
|
+
// Check for "readonly any" or just "any"
|
|
195
|
+
let anyIdx = -1;
|
|
196
|
+
let prefixLen = 0;
|
|
197
|
+
if (restOfType.startsWith("readonly ")) {
|
|
198
|
+
prefixLen = "readonly ".length;
|
|
199
|
+
if (restOfType.substring(prefixLen).startsWith("any")) {
|
|
200
|
+
anyIdx = valueStart + prefixLen;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
else if (restOfType.startsWith("any")) {
|
|
204
|
+
anyIdx = valueStart;
|
|
205
|
+
}
|
|
206
|
+
if (anyIdx !== -1) {
|
|
207
|
+
// Check what comes after "any"
|
|
208
|
+
const afterAny = typeStr.substring(anyIdx + 3);
|
|
209
|
+
const hasArrayBrackets = afterAny.startsWith("[]");
|
|
210
|
+
// Build replacement
|
|
211
|
+
let replacement = typeName;
|
|
212
|
+
if (isArray || hasArrayBrackets) {
|
|
213
|
+
replacement = `${typeName}[]`;
|
|
214
|
+
}
|
|
215
|
+
// Calculate end position (include [] if present)
|
|
216
|
+
let endPos = anyIdx + 3;
|
|
217
|
+
if (hasArrayBrackets) {
|
|
218
|
+
endPos += 2;
|
|
219
|
+
}
|
|
220
|
+
typeStr = typeStr.substring(0, anyIdx) + replacement + typeStr.substring(endPos);
|
|
221
|
+
}
|
|
222
|
+
idx = typeStr.indexOf(pattern, idx + 1);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return typeStr;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Checks if a schema has getter-based self-references.
|
|
229
|
+
*/
|
|
230
|
+
hasSelfReferences(getterFields) {
|
|
231
|
+
return Array.from(getterFields.values()).some((info) => info.isSelfRef);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
//# sourceMappingURL=getter-resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getter-resolver.js","sourceRoot":"","sources":["../../src/core/getter-resolver.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { SourceFile, Project } from "ts-morph";
|
|
2
|
+
/**
|
|
3
|
+
* Information about an imported schema.
|
|
4
|
+
*/
|
|
5
|
+
export interface ImportedSchemaInfo {
|
|
6
|
+
/** Local name used in the importing file */
|
|
7
|
+
localName: string;
|
|
8
|
+
/** Original name in the source file */
|
|
9
|
+
originalName: string;
|
|
10
|
+
/** Resolved source file path */
|
|
11
|
+
sourceFilePath: string;
|
|
12
|
+
/** Whether the schema was successfully resolved */
|
|
13
|
+
resolved: boolean;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Map of local schema name to imported schema info.
|
|
17
|
+
*/
|
|
18
|
+
export type ImportedSchemaMap = Map<string, ImportedSchemaInfo>;
|
|
19
|
+
/**
|
|
20
|
+
* Resolves imported schemas from other files.
|
|
21
|
+
*/
|
|
22
|
+
export declare class ImportResolver {
|
|
23
|
+
private schemaDetector;
|
|
24
|
+
constructor();
|
|
25
|
+
/**
|
|
26
|
+
* Finds all imported schemas in a source file.
|
|
27
|
+
*
|
|
28
|
+
* @param sourceFile - The source file to analyze
|
|
29
|
+
* @param project - The ts-morph project for module resolution
|
|
30
|
+
* @returns Map of local names to imported schema info
|
|
31
|
+
*/
|
|
32
|
+
findImportedSchemas(sourceFile: SourceFile, project: Project): ImportedSchemaMap;
|
|
33
|
+
/**
|
|
34
|
+
* Finds the actual source file containing a schema definition.
|
|
35
|
+
* Follows re-exports (export * from "./other") to find the original.
|
|
36
|
+
*/
|
|
37
|
+
private findSchemaSource;
|
|
38
|
+
/**
|
|
39
|
+
* Resolves a module specifier to a source file.
|
|
40
|
+
*/
|
|
41
|
+
private resolveModuleSpecifier;
|
|
42
|
+
/**
|
|
43
|
+
* Generates possible file paths for a module specifier and resolves to a source file.
|
|
44
|
+
*/
|
|
45
|
+
private resolveFromPossiblePaths;
|
|
46
|
+
/**
|
|
47
|
+
* Resolves an import declaration to its source file.
|
|
48
|
+
*/
|
|
49
|
+
private resolveImportedFile;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=import-resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"import-resolver.d.ts","sourceRoot":"","sources":["../../src/core/import-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAqB,OAAO,EAAE,MAAM,UAAU,CAAC;AAKlE;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,4CAA4C;IAC5C,SAAS,EAAE,MAAM,CAAC;IAClB,uCAAuC;IACvC,YAAY,EAAE,MAAM,CAAC;IACrB,gCAAgC;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB,mDAAmD;IACnD,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;AAEhE;;GAEG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,cAAc,CAAiB;;IAMvC;;;;;;OAMG;IACH,mBAAmB,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,GAAG,iBAAiB;IA2ChF;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IA4DxB;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAS9B;;OAEG;IACH,OAAO,CAAC,wBAAwB;IA8BhC;;OAEG;IACH,OAAO,CAAC,mBAAmB;CAwB5B"}
|