@elliots/typical 0.1.10 → 0.2.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.
Files changed (56) hide show
  1. package/README.md +234 -200
  2. package/dist/src/cli.js +12 -85
  3. package/dist/src/cli.js.map +1 -1
  4. package/dist/src/cli.typical.ts +136 -0
  5. package/dist/src/config.d.ts +12 -0
  6. package/dist/src/config.js +40 -38
  7. package/dist/src/config.js.map +1 -1
  8. package/dist/src/config.typical.ts +287 -0
  9. package/dist/src/esm-loader-register.js.map +1 -1
  10. package/dist/src/esm-loader.d.ts +1 -1
  11. package/dist/src/esm-loader.js +30 -17
  12. package/dist/src/esm-loader.js.map +1 -1
  13. package/dist/src/file-filter.d.ts +1 -1
  14. package/dist/src/file-filter.js.map +1 -1
  15. package/dist/src/index.d.ts +5 -4
  16. package/dist/src/index.js +1 -1
  17. package/dist/src/index.js.map +1 -1
  18. package/dist/src/program-manager.d.ts +27 -0
  19. package/dist/src/program-manager.js +121 -0
  20. package/dist/src/program-manager.js.map +1 -0
  21. package/dist/src/regex-hoister.d.ts +1 -1
  22. package/dist/src/regex-hoister.js +13 -19
  23. package/dist/src/regex-hoister.js.map +1 -1
  24. package/dist/src/setup.d.ts +1 -1
  25. package/dist/src/setup.js +3 -3
  26. package/dist/src/setup.js.map +1 -1
  27. package/dist/src/source-map.d.ts +1 -1
  28. package/dist/src/source-map.js +1 -1
  29. package/dist/src/source-map.js.map +1 -1
  30. package/dist/src/source-map.typical.ts +216 -0
  31. package/dist/src/timing.d.ts +19 -0
  32. package/dist/src/timing.js +65 -0
  33. package/dist/src/timing.js.map +1 -0
  34. package/dist/src/transformer.d.ts +28 -193
  35. package/dist/src/transformer.js +41 -1917
  36. package/dist/src/transformer.js.map +1 -1
  37. package/dist/src/transformer.typical.ts +2552 -0
  38. package/dist/src/tsc-plugin.d.ts +8 -1
  39. package/dist/src/tsc-plugin.js +11 -7
  40. package/dist/src/tsc-plugin.js.map +1 -1
  41. package/package.json +51 -47
  42. package/src/cli.ts +41 -128
  43. package/src/config.ts +106 -91
  44. package/src/esm-loader-register.ts +2 -2
  45. package/src/esm-loader.ts +44 -29
  46. package/src/index.ts +5 -10
  47. package/src/patch-fs.cjs +14 -14
  48. package/src/timing.ts +74 -0
  49. package/src/transformer.ts +47 -2592
  50. package/bin/ttsc +0 -12
  51. package/src/file-filter.ts +0 -49
  52. package/src/patch-tsconfig.cjs +0 -52
  53. package/src/regex-hoister.ts +0 -203
  54. package/src/setup.ts +0 -39
  55. package/src/source-map.ts +0 -202
  56. package/src/tsc-plugin.ts +0 -12
@@ -1,204 +1,39 @@
1
- import ts from "typescript";
2
- import { TypicalConfig } from "./config.js";
3
- import { TransformResult } from "./source-map.js";
4
- export type { TransformResult } from "./source-map.js";
5
- export interface TransformContext {
6
- ts: typeof ts;
7
- factory: ts.NodeFactory;
8
- context: ts.TransformationContext;
9
- sourceFile: ts.SourceFile;
1
+ /**
2
+ * TypicalTransformer - Thin wrapper around the Go compiler.
3
+ *
4
+ * The Go compiler (compiler) handles all TypeScript analysis
5
+ * and validation code generation. This class just manages the lifecycle
6
+ * and communication with the Go process.
7
+ */
8
+ import { type RawSourceMap } from '@elliots/typical-compiler';
9
+ import type { TypicalConfig } from './config.js';
10
+ export interface TransformResult {
11
+ code: string;
12
+ map: RawSourceMap | null;
10
13
  }
11
14
  export declare class TypicalTransformer {
12
15
  config: TypicalConfig;
13
- private program;
14
- private ts;
15
- private compiledPatterns;
16
- private typeValidators;
17
- private typeStringifiers;
18
- private typeParsers;
19
- constructor(config?: TypicalConfig, program?: ts.Program, tsInstance?: typeof ts);
16
+ private compiler;
17
+ private projectHandle;
18
+ private initPromise;
19
+ private configFile;
20
+ constructor(config?: TypicalConfig, configFile?: string);
20
21
  /**
21
- * Create a new TypeScript program with transformed source code.
22
- * This is needed so typia can resolve types from our generated typia.createAssert<T>() calls.
22
+ * Ensure the Go compiler is started and project is loaded.
23
+ * Uses lazy initialization - only starts on first transform.
23
24
  */
24
- private createTypiaProgram;
25
+ private ensureInitialized;
25
26
  /**
26
- * Write intermediate file for debugging purposes.
27
- * Creates a .typical.ts file showing the code after typical's transformations
28
- * but before typia processes it.
29
- */
30
- private writeIntermediateFile;
31
- /**
32
- * Format typia diagnostic errors into readable error messages.
33
- */
34
- private formatTypiaErrors;
35
- /**
36
- * Check for untransformed typia calls and throw an error if found.
37
- * This is a fallback in case typia silently fails without reporting a diagnostic.
38
- */
39
- private checkUntransformedTypiaCalls;
40
- createSourceFile(fileName: string, content: string): ts.SourceFile;
41
- /**
42
- * Transform options for controlling source map generation.
43
- */
44
- transform(sourceFile: ts.SourceFile | string, mode: "basic" | "typia" | "js", options?: {
45
- sourceMap?: boolean;
46
- skippedTypes?: Set<string>;
47
- }): TransformResult;
48
- /**
49
- * Legacy transform method that returns just the code string.
50
- * @deprecated Use transform() with options.sourceMap instead
51
- */
52
- transformCode(sourceFile: ts.SourceFile | string, mode: "basic" | "typia" | "js", skippedTypes?: Set<string>): string;
53
- /**
54
- * Apply typia transformation in a separate ts.transform() context.
55
- * This avoids mixing program contexts and eliminates the need for import recreation.
56
- * Returns either the transformed code, or a retry signal with the failed type.
57
- * Source map markers in the code are preserved through the typia transformation.
58
- */
59
- private applyTypiaTransform;
60
- /**
61
- * Get a transformer that only applies typical's transformations (no typia).
62
- * @param skippedTypes Set of type strings to skip validation for (used for retry after typia errors)
63
- */
64
- private getTypicalOnlyTransformer;
65
- /**
66
- * Get a combined transformer for use with ts-patch/ttsc.
67
- * This is used by the TSC plugin where we need a single transformer factory.
68
- *
69
- * Note: Even for ts-patch, we need to create a new program with the transformed
70
- * source so typia can resolve the types from our generated typia.createAssert<T>() calls.
71
- */
72
- getTransformer(withTypia: boolean): ts.TransformerFactory<ts.SourceFile>;
73
- /**
74
- * Transform JSON.stringify or JSON.parse calls to use typia's validated versions.
75
- * Returns the transformed node if applicable, or undefined to indicate no transformation.
76
- */
77
- private transformJSONCall;
78
- /**
79
- * Check if a type should be skipped (failed in typia on previous attempt).
80
- */
81
- private shouldSkipType;
82
- /**
83
- * Create an AST visitor function for transforming a source file.
84
- * The visitor handles JSON calls, type casts, and function declarations.
85
- */
86
- private createVisitor;
87
- /**
88
- * Transform a single source file with TypeScript AST
89
- */
90
- private transformSourceFile;
91
- /**
92
- * Add @L line markers to nodes that have original source positions.
93
- * This preserves identity mappings for original code, so lines from the source
94
- * file map back to themselves rather than inheriting from generated code markers.
95
- *
96
- * We need to add markers to every node that will be printed on its own line,
97
- * including nested members of interfaces, classes, etc.
98
- */
99
- private addLineMarkersToStatements;
100
- shouldTransformFile(fileName: string): boolean;
101
- /**
102
- * Get pre-compiled ignore patterns, caching them for performance.
103
- */
104
- private getCompiledPatterns;
105
- /**
106
- * Check if a TypeNode represents a type that shouldn't be validated.
107
- * This includes:
108
- * - any/unknown (intentional escape hatches)
109
- * - Type parameters (generics like T)
110
- * - Constructor types (new (...args: any[]) => T)
111
- * - Function types ((...args) => T)
112
- */
113
- private isAnyOrUnknownType;
114
- /**
115
- * Check if a type contains any unvalidatable parts (type parameters, constructor types, etc.)
116
- * This recursively checks intersection and union types.
117
- */
118
- private containsUnvalidatableType;
119
- /**
120
- * Check if a Type has any or unknown flags, or is a type parameter or function/constructor.
121
- */
122
- private isAnyOrUnknownTypeFlags;
123
- /**
124
- * Check if a type name matches any of the ignoreTypes patterns.
125
- * Supports wildcards: "React.*" matches "React.FormEvent", "React.ChangeEvent", etc.
126
- * Also handles union types: "Document | Element" is ignored if "Document" or "Element" is in ignoreTypes.
127
- */
128
- private isIgnoredType;
129
- /**
130
- * Check if a single type (not a union) should be ignored.
131
- * Checks both the type name and its base classes.
132
- * Uses Set-based cycle detection to handle recursive type hierarchies.
133
- * @param patterns Pre-compiled RegExp patterns
134
- * @param visited Set of type IDs already visited (for cycle detection)
135
- */
136
- private isIgnoredSingleType;
137
- /**
138
- * Check if a single type name matches any pre-compiled ignore pattern.
139
- * @param patterns Pre-compiled RegExp patterns
140
- */
141
- private matchesIgnorePatternCompiled;
142
- /**
143
- * Find untransformed typia calls in the output code.
144
- * These indicate types that typia could not process.
145
- */
146
- private findUntransformedTypiaCalls;
147
- /**
148
- * Infer type information from a JSON.stringify argument for creating a reusable stringifier.
149
- */
150
- private inferStringifyType;
151
- /**
152
- * Gets the root identifier from an expression.
153
- * e.g., `user.address.city` -> "user"
154
- */
155
- private getRootIdentifier;
156
- /**
157
- * Check if a validated variable has been tainted (mutated) in the function body.
158
- * A variable is tainted if it's reassigned, has properties modified, is passed
159
- * to a function, has methods called on it, or if an await occurs.
160
- */
161
- private isTainted;
162
- private addTypiaImport;
163
- /**
164
- * Gets type text for use as a validator map key.
165
- * Uses getText() to preserve local aliases (e.g., "User1" vs "User2"),
166
- * but falls back to typeToString() for synthesized nodes without source positions.
27
+ * Transform a TypeScript file by adding runtime validation.
167
28
  *
168
- * @param typeNode The TypeNode to get a key for
169
- * @param typeChecker The TypeChecker to use
170
- * @param typeObj Optional Type object - use this for synthesized nodes since
171
- * getTypeFromTypeNode doesn't work correctly on them
172
- */
173
- private getTypeKey;
174
- /**
175
- * Simple string hash for creating unique identifiers from type strings.
176
- */
177
- private hashString;
178
- /**
179
- * Format typia's error message into a cleaner list format.
180
- * Typia outputs verbose messages like:
181
- * "unsupported type detected\n\n- Window.ondevicemotion: unknown\n - nonsensible intersection\n\n- Window.ondeviceorientation..."
182
- * We want to extract just the problematic types and their issues.
183
- */
184
- private formatTypiaError;
185
- /**
186
- * Creates a readable name suffix from a type string.
187
- * For simple identifiers like "User" or "string", returns the name directly.
188
- * For complex types, returns a numeric index.
189
- */
190
- private getTypeNameSuffix;
191
- /**
192
- * Generic method to get or create a typed function (validator, stringifier, or parser).
29
+ * @param fileName - Path to the TypeScript file
30
+ * @param mode - Output mode: 'ts' returns TypeScript, 'js' would transpile (not yet supported)
31
+ * @returns Transformed code with validation
193
32
  */
194
- private getOrCreateTypedFunction;
195
- private getOrCreateValidator;
196
- private getOrCreateStringifier;
197
- private getOrCreateParser;
33
+ transform(fileName: string, mode?: 'ts' | 'js'): Promise<TransformResult>;
198
34
  /**
199
- * Creates a nested property access expression from an array of identifiers.
200
- * e.g., ['typia', 'json', 'createStringify'] -> typia.json.createStringify
35
+ * Close the Go compiler process and release resources.
36
+ * This immediately kills the process without waiting for pending operations.
201
37
  */
202
- private createPropertyAccessChain;
203
- private createValidatorStatements;
38
+ close(): Promise<void>;
204
39
  }