@elliots/typical 0.1.10 → 0.2.0-beta.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.
Files changed (55) hide show
  1. package/README.md +187 -208
  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.js +38 -38
  6. package/dist/src/config.js.map +1 -1
  7. package/dist/src/config.typical.ts +287 -0
  8. package/dist/src/esm-loader-register.js.map +1 -1
  9. package/dist/src/esm-loader.d.ts +1 -1
  10. package/dist/src/esm-loader.js +30 -17
  11. package/dist/src/esm-loader.js.map +1 -1
  12. package/dist/src/file-filter.d.ts +1 -1
  13. package/dist/src/file-filter.js.map +1 -1
  14. package/dist/src/index.d.ts +5 -4
  15. package/dist/src/index.js +1 -1
  16. package/dist/src/index.js.map +1 -1
  17. package/dist/src/program-manager.d.ts +27 -0
  18. package/dist/src/program-manager.js +121 -0
  19. package/dist/src/program-manager.js.map +1 -0
  20. package/dist/src/regex-hoister.d.ts +1 -1
  21. package/dist/src/regex-hoister.js +13 -19
  22. package/dist/src/regex-hoister.js.map +1 -1
  23. package/dist/src/setup.d.ts +1 -1
  24. package/dist/src/setup.js +3 -3
  25. package/dist/src/setup.js.map +1 -1
  26. package/dist/src/source-map.d.ts +1 -1
  27. package/dist/src/source-map.js +1 -1
  28. package/dist/src/source-map.js.map +1 -1
  29. package/dist/src/source-map.typical.ts +216 -0
  30. package/dist/src/timing.d.ts +19 -0
  31. package/dist/src/timing.js +65 -0
  32. package/dist/src/timing.js.map +1 -0
  33. package/dist/src/transformer.d.ts +28 -193
  34. package/dist/src/transformer.js +41 -1917
  35. package/dist/src/transformer.js.map +1 -1
  36. package/dist/src/transformer.typical.ts +2552 -0
  37. package/dist/src/tsc-plugin.d.ts +8 -1
  38. package/dist/src/tsc-plugin.js +11 -7
  39. package/dist/src/tsc-plugin.js.map +1 -1
  40. package/package.json +51 -47
  41. package/src/cli.ts +41 -128
  42. package/src/config.ts +92 -91
  43. package/src/esm-loader-register.ts +2 -2
  44. package/src/esm-loader.ts +44 -29
  45. package/src/index.ts +5 -10
  46. package/src/patch-fs.cjs +14 -14
  47. package/src/timing.ts +74 -0
  48. package/src/transformer.ts +47 -2592
  49. package/bin/ttsc +0 -12
  50. package/src/file-filter.ts +0 -49
  51. package/src/patch-tsconfig.cjs +0 -52
  52. package/src/regex-hoister.ts +0 -203
  53. package/src/setup.ts +0 -39
  54. package/src/source-map.ts +0 -202
  55. package/src/tsc-plugin.ts +0 -12
package/README.md CHANGED
@@ -1,113 +1,129 @@
1
1
  # Typical
2
2
 
3
- Typical adds runtime validation to typescript, making TypeScript type-safe at runtime *with no changes to your code*.
3
+ Typical makes TypeScript type-safe at runtime _with no changes to your code_.
4
4
 
5
- It can be used as a TSC plugin, ESM loader for Node.js, or with bundlers like Vite, Webpack, and Rollup via unplugin.
5
+ It transforms your code to inject runtime validation based on your existing type annotations. With source maps, so errors point to the right lines in your original code.
6
6
 
7
7
  ## Why?
8
8
 
9
- For some use cases it can mean you don't need to use zod, yup, ajv, or other runtime validation libraries, as your types are already validated automatically.
9
+ - Less need for zod, yup, ajv, or other runtime validation libraries - your types are already validated automatically. If you can express it in TypeScript, Typical can validate it at runtime.
10
+ - Protects against data leaks via `JSON.stringify` by ensuring only properties defined in your types are included
11
+ - Catches type mismatches at runtime that TypeScript can't catch at compile time (API responses, JSON parsing, un-typed/badly-typed libraries, vibe-coding coworkers etc.)
10
12
 
11
- It protects you from leaking data via JSON.stringify by making sure only the properties defined in your types are included in the output.
13
+ ## Features
12
14
 
13
- Why not.
15
+ - Validation of function parameters and return types
16
+ - Safe `JSON.parse` with type validation
17
+ - Safe `JSON.stringify` that only includes defined properties
18
+ - Validation of type casts (`as Type`)
19
+ - Configurable include/exclude patterns
14
20
 
15
- ## Features
21
+ ## Example
16
22
 
17
- - Automatic validation of function parameters
18
- - ✅ Automatic validation of return types
19
- - ✅ Replace `JSON.stringify` with a custom stringifier (very fast!)
20
- - ✅ Replace `JSON.parse` with a custom parser and validator (very fast!)
21
- - ✅ Configurable include/exclude patterns
22
- - ✅ Optionally reuse validation logic for identical types to optimize performance (enabled by default)
23
- - ✅ TSC plugin
24
- - ✅ ESM loader for runtime transformation with `node --import @elliots/typical/esm` (or `node --loader @elliots/typical/esm-loader` for older Node versions)
25
- - ✅ tsx wrapper (ttsx) for easy use like `npx ttsx script.ts`
26
- - ✅ Unplugin for Vite, Webpack, Rollup, esbuild, and more
23
+ This code runs without errors in normal TypeScript, but Typical catches the invalid data:
27
24
 
28
- ## Installation
25
+ ```ts
26
+ interface User {
27
+ name: string;
28
+ email: `${string}@${string}`;
29
+ }
29
30
 
30
- ```bash
31
- npm add typical
31
+ // This will throw - email doesn't match the template literal type
32
+ const user = JSON.parse('{"name":"Alice","email":"not-an-email"}') as User;
32
33
  ```
33
34
 
34
- ## Configuration
35
+ ---
36
+
37
+ ## Usage Options
38
+
39
+ Choose the integration that fits your workflow:
40
+
41
+ | Method | Best For | Package |
42
+ | --------------------------------------------------------- | ------------------------------- | ----------------------------- |
43
+ | [ESM Loader](#nodejs-esm-loader) | Node.js scripts, development | `@elliots/typical` |
44
+ | [ttsx](#ttsx-tsx-wrapper) | Quick scripts with tsx | `@elliots/typical` + `tsx` |
45
+ | [Bun Plugin](#bun) | Bun projects | `@elliots/bun-plugin-typical` |
46
+ | [Vite/Webpack/etc](#bundlers-vite-webpack-rollup-esbuild) | Frontend apps, bundled projects | `@elliots/unplugin-typical` |
47
+ | [tsc Plugin](#typescript-compiler-tsc) | Pure TypeScript compilation | `@elliots/typical-tsc-plugin` |
48
+
49
+ ---
35
50
 
36
- Optional: Create a `typical.json` file in your project root.
51
+ ## Node.js (ESM Loader)
37
52
 
38
- If not provided, these default settings will be used (optimized for development):
53
+ The simplest way to run TypeScript with Typical validation.
54
+
55
+ ```bash
56
+ npm add @elliots/typical
57
+ ```
58
+
59
+ ```bash
60
+ node --import @elliots/typical/esm src/index.ts
61
+ ```
62
+
63
+ Add to `package.json` scripts:
39
64
 
40
65
  ```json
41
66
  {
42
- "include": ["**/*.ts", "**/*.tsx"],
43
- "exclude": ["node_modules/**", "**/*.d.ts", "dist/**", "build/**"],
44
- "reusableValidators": false,
45
- "validateFunctions": true,
46
- "validateCasts": false,
47
- "hoistRegex": true,
48
- "ignoreDOMTypes": true,
49
- "ignoreTypes": [],
50
- "sourceMap": {
51
- "enabled": true,
52
- "includeContent": true,
53
- "inline": false
67
+ "scripts": {
68
+ "start": "node --import @elliots/typical/esm src/index.ts"
54
69
  }
55
70
  }
56
71
  ```
57
72
 
58
- ### Configuration Options
73
+ ---
59
74
 
60
- | Option | Default | Description |
61
- |--------|---------|-------------|
62
- | `include` | `["**/*.ts", "**/*.tsx"]` | Glob patterns for files to transform |
63
- | `exclude` | `["node_modules/**", "**/*.d.ts", "dist/**", "build/**"]` | Glob patterns for files to skip |
64
- | `reusableValidators` | `false` | Create shared validators for identical types (smaller output). Incompatible with source maps. |
65
- | `validateFunctions` | `true` | Validate function parameters and return types at runtime |
66
- | `validateCasts` | `false` | Validate type assertions (`as Type`) at runtime |
67
- | `hoistRegex` | `true` | Hoist regex patterns to top-level constants (improves performance) |
68
- | `ignoreDOMTypes` | `true` | Skip validation for DOM types (Document, Element, etc.) |
69
- | `ignoreTypes` | `[]` | Type patterns to skip validation for (supports wildcards, e.g., `["React.*"]`) |
70
- | `sourceMap.enabled` | `true` | Generate source maps for transformed code |
71
- | `sourceMap.includeContent` | `true` | Include original source content in source maps |
72
- | `sourceMap.inline` | `false` | Use inline source maps (data URL) instead of external files |
73
- | `debug.writeIntermediateFiles` | `false` | Write `.typical.ts` files showing code before typia transform |
75
+ ## ttsx (tsx wrapper)
74
76
 
75
- ### Production Configuration
77
+ A convenience wrapper that combines [tsx](https://github.com/privatenumber/tsx) with Typical.
76
78
 
77
- For production builds, disable source maps and enable reusable validators for smaller output:
79
+ ```bash
80
+ npm add @elliots/typical tsx
81
+ ```
78
82
 
79
- ```json
80
- {
81
- "reusableValidators": true,
82
- "sourceMap": {
83
- "enabled": false
84
- }
85
- }
83
+ ```bash
84
+ npx ttsx script.ts
86
85
  ```
87
86
 
88
- Note: `reusableValidators` and `sourceMap.enabled` are mutually exclusive. Source maps require inline validators so each validation call can map back to its original type annotation. If both are enabled, `reusableValidators` will be automatically disabled with a warning.
87
+ Or install globally:
88
+
89
+ ```bash
90
+ npm add -g @elliots/typical tsx
91
+ ttsx script.ts
92
+ ```
89
93
 
90
- ## Usage
94
+ > **Note:** `tsx` must be installed separately. The `ttsx` command is a thin wrapper that runs `tsx` with the Typical ESM loader.
91
95
 
92
- See ./samples/esm and ./samples/tsc and ./samples/ttsx
96
+ ---
93
97
 
94
- Quickest way to try it out is to use ttsx:
98
+ ## Bun
95
99
 
96
100
  ```bash
97
- npm add @elliots/typical
98
- npx ttsx your-script.ts
101
+ bun add @elliots/bun-plugin-typical
102
+ ```
103
+
104
+ Create `bunfig.toml`:
105
+
106
+ ```toml
107
+ preload = ["./preload.ts"]
99
108
  ```
100
109
 
101
- or globally:
110
+ Create `preload.ts`:
111
+
112
+ ```ts
113
+ import { typicalPlugin } from "@elliots/bun-plugin-typical";
114
+
115
+ Bun.plugin(typicalPlugin());
116
+ ```
117
+
118
+ Then run:
102
119
 
103
120
  ```bash
104
- npm add -g @elliots/typical
105
- ttsx your-script.ts
121
+ bun run src/index.ts
106
122
  ```
107
123
 
108
- ## Vite / Webpack / Rollup (unplugin)
124
+ ---
109
125
 
110
- Install the unplugin:
126
+ ## Bundlers (Vite, Webpack, Rollup, esbuild)
111
127
 
112
128
  ```bash
113
129
  npm add @elliots/unplugin-typical
@@ -115,224 +131,187 @@ npm add @elliots/unplugin-typical
115
131
 
116
132
  ### Vite
117
133
 
118
- ```typescript
134
+ ```ts
119
135
  // vite.config.ts
120
- import Typical from '@elliots/unplugin-typical/vite'
136
+ import Typical from "@elliots/unplugin-typical/vite";
121
137
 
122
138
  export default defineConfig({
123
- plugins: [
124
- Typical(),
125
- ],
126
- })
139
+ plugins: [Typical()],
140
+ });
127
141
  ```
128
142
 
129
143
  ### Webpack
130
144
 
131
- ```typescript
145
+ ```js
132
146
  // webpack.config.js
133
- const Typical = require('@elliots/unplugin-typical/webpack').default
147
+ const Typical = require("@elliots/unplugin-typical/webpack").default;
134
148
 
135
149
  module.exports = {
136
- plugins: [
137
- Typical(),
138
- ],
139
- }
150
+ plugins: [Typical()],
151
+ };
140
152
  ```
141
153
 
142
154
  ### Rollup
143
155
 
144
- ```typescript
156
+ ```js
145
157
  // rollup.config.js
146
- import Typical from '@elliots/unplugin-typical/rollup'
158
+ import Typical from "@elliots/unplugin-typical/rollup";
147
159
 
148
160
  export default {
149
- plugins: [
150
- Typical(),
151
- ],
152
- }
161
+ plugins: [Typical()],
162
+ };
153
163
  ```
154
164
 
155
165
  ### esbuild
156
166
 
157
- ```typescript
158
- import { build } from 'esbuild'
159
- import Typical from '@elliots/unplugin-typical/esbuild'
167
+ ```ts
168
+ import { build } from "esbuild";
169
+ import Typical from "@elliots/unplugin-typical/esbuild";
160
170
 
161
171
  build({
162
172
  plugins: [Typical()],
163
- })
173
+ });
164
174
  ```
165
175
 
166
- ### Plugin Configuration
176
+ ### Rolldown
167
177
 
168
- Pass options directly to the plugin:
178
+ ```ts
179
+ // rolldown.config.ts
180
+ import Typical from "@elliots/unplugin-typical/rolldown";
169
181
 
170
- ```typescript
171
- Typical({
172
- validateFunctions: true,
173
- validateCasts: false,
174
- // ... other options
175
- })
182
+ export default {
183
+ plugins: [Typical()],
184
+ };
176
185
  ```
177
186
 
178
- Or use a `typical.json` file in your project root (shared with other entry points like TSC plugin and ESM loader).
179
-
180
- ## Example
181
-
182
- This code will run without errors when compiled normally, but will throw an error when using Typical.
183
-
187
+ ### Farm
184
188
 
185
189
  ```ts
186
- interface User {
187
- name: string;
188
- email: `${string}@${string}`;
189
- }
190
- const u = JSON.parse('{"name":"Alice","email":"oops-not-an-email"}') as User;
191
- ```
190
+ // farm.config.ts
191
+ import Typical from "@elliots/unplugin-typical/farm";
192
192
 
193
- ## How it works
194
-
195
- Typical uses the TypeScript Compiler API to parse and transform your TypeScript code. It analyzes function signatures, return types, and JSON operations to inject appropriate typia validation calls.
196
-
197
- But basically you shouldn't need to care about how it works internally, it makes typescript strongly typed*. You can still use `any` and `unknown` if you want to opt out of type safety.
198
-
199
- * sort of. probably. something like it anyway.
193
+ export default {
194
+ plugins: [Typical()],
195
+ };
196
+ ```
200
197
 
201
- ## Flow Analysis
198
+ ### Rspack
202
199
 
203
- Typical includes smart flow analysis to avoid redundant validations. When you return a value that was already validated (either as a parameter or via a type-annotated const), the return statement won't be wrapped in another validation call.
200
+ ```ts
201
+ // rspack.config.ts
202
+ import Typical from "@elliots/unplugin-typical/rspack";
204
203
 
205
- ### When return validation is skipped:
204
+ export default {
205
+ plugins: [Typical()],
206
+ };
207
+ ```
206
208
 
207
- ```typescript
208
- interface User { name: string; }
209
+ ---
209
210
 
210
- // Direct parameter return - no redundant validation
211
- function validate(user: User): User {
212
- return user; // Already validated on entry, skip return validation
213
- }
211
+ ## TypeScript Compiler (tsc)
214
212
 
215
- // Property access from validated parameter
216
- function getAddress(user: User): Address {
217
- return user.address; // user was validated, address is safe
218
- }
213
+ For projects that compile with `tsc` directly using [ts-patch](https://github.com/nonara/ts-patch).
219
214
 
220
- // Type-annotated const
221
- function getUser(): User {
222
- const user: User = fetchData(); // const is validated here
223
- return user; // skip redundant validation
224
- }
215
+ ```bash
216
+ npm add @elliots/typical-tsc-plugin ts-patch
225
217
  ```
226
218
 
227
- ### When return validation IS applied (tainting):
219
+ ### Option 1: ttsc (auto-injects plugin)
228
220
 
229
- ```typescript
230
- // After mutation
231
- function updateUser(user: User): User {
232
- user.name = "modified"; // Mutation taints the value
233
- return user; // Must re-validate
234
- }
221
+ The `ttsc` command automatically injects the plugin - no config needed:
235
222
 
236
- // After passing to another function
237
- function processUser(user: User): User {
238
- someFunction(user); // Could have mutated user
239
- return user; // Must re-validate
240
- }
223
+ ```bash
224
+ npx ttsc
225
+ ```
241
226
 
242
- // After await (async boundary)
243
- async function asyncProcess(user: User): Promise<User> {
244
- await delay(); // Async boundary taints values
245
- return user; // Must re-validate
246
- }
227
+ Add to `package.json`:
247
228
 
248
- // Spread into new object
249
- function cloneUser(user: User): User {
250
- return { ...user }; // New object, must validate
229
+ ```json
230
+ {
231
+ "scripts": {
232
+ "build": "ttsc"
233
+ }
251
234
  }
252
235
  ```
253
236
 
254
- ## Debugging
255
-
256
- ### Intermediate Files
237
+ ### Option 2: Manual tsconfig.json
257
238
 
258
- To see what code Typical generates before typia processes it, enable intermediate file output:
239
+ Add to your `tsconfig.json`:
259
240
 
260
241
  ```json
261
242
  {
262
- "debug": {
263
- "writeIntermediateFiles": true
243
+ "compilerOptions": {
244
+ "plugins": [
245
+ {
246
+ "transform": "@elliots/typical-tsc-plugin",
247
+ "transformProgram": true
248
+ }
249
+ ]
264
250
  }
265
251
  }
266
252
  ```
267
253
 
268
- This creates `.typical.ts` files alongside your output showing the code with typia calls injected but not yet transformed.
269
-
270
- ### Verbose Logging
271
-
272
- Set `DEBUG=1` environment variable for detailed logging:
254
+ Then run ts-patch's tsc:
273
255
 
274
256
  ```bash
275
- DEBUG=1 npm run build
257
+ npx ts-patch install
258
+ npx tsc
276
259
  ```
277
260
 
278
- ## Troubleshooting
261
+ Or add a prepare script:
279
262
 
280
- ### "Failed to transform the following types"
281
-
282
- This error means typia couldn't generate validation code for certain types. Common causes:
263
+ ```json
264
+ {
265
+ "scripts": {
266
+ "prepare": "ts-patch install -s",
267
+ "build": "tsc"
268
+ }
269
+ }
270
+ ```
283
271
 
284
- 1. **DOM types**: Types like `HTMLElement`, `Document`, etc. have complex intersections typia can't process.
285
- - Solution: Enable `ignoreDOMTypes: true` (default) or add specific types to `ignoreTypes`
272
+ ---
286
273
 
287
- 2. **React types**: Event handlers, refs, and other React types often can't be validated.
288
- - Solution: Add `"React.*"` to `ignoreTypes`
274
+ ## Configuration
289
275
 
290
- 3. **Third-party library types**: Some library types are too complex.
291
- - Solution: Add the specific type patterns to `ignoreTypes`
276
+ Create a `typical.json` file in your project root (optional):
292
277
 
293
278
  ```json
294
279
  {
295
- "ignoreTypes": ["React.*", "Express.Request", "Prisma.*"]
280
+ "include": ["**/*.ts", "**/*.tsx"],
281
+ "exclude": ["node_modules/**", "**/*.d.ts"],
282
+ "validateFunctions": true,
283
+ "validateCasts": false
296
284
  }
297
285
  ```
298
286
 
299
- ### "Window & typeof globalThis" errors
287
+ ### Options
300
288
 
301
- This occurs when a type includes DOM globals. Enable `ignoreDOMTypes: true` or add the specific type to `ignoreTypes`.
289
+ | Option | Default | Description |
290
+ | ------------------- | --------------------------------------------------------- | --------------------------------------------- |
291
+ | `include` | `["**/*.ts", "**/*.tsx"]` | Files to transform |
292
+ | `exclude` | `["node_modules/**", "**/*.d.ts", "dist/**", "build/**"]` | Files to skip |
293
+ | `validateFunctions` | `true` | Validate function parameters and return types |
294
+ | `validateCasts` | `false` | Validate type assertions (`as Type`) |
302
295
 
303
- ### Generic type parameters not validated
296
+ ---
304
297
 
305
- Type parameters (`T`, `U`, etc.) cannot be validated at runtime because the actual type isn't known until the function is called. This is by design:
298
+ ## How It Works
306
299
 
307
- ```typescript
308
- function identity<T>(value: T): T {
309
- return value; // T is not validated - no runtime type info
310
- }
311
- ```
300
+ Typical uses a Go-based compiler that leverages the TypeScript type checker to analyze your code. It generates runtime validators that check values against their declared types.
312
301
 
313
- Concrete types in the same function ARE validated:
314
-
315
- ```typescript
316
- function process<T>(value: T, user: User): User {
317
- return user; // User IS validated
318
- }
319
- ```
302
+ Types that can't be validated at runtime (like generic type parameters `T`) are skipped. You can still use `any` and `unknown` to opt out of validation.
320
303
 
321
- ### Constructor parameters not validated
304
+ ## Debugging
322
305
 
323
- Currently, class constructors are not transformed. This is a known limitation. Validate in the constructor body if needed:
306
+ Set `DEBUG=1` for verbose logging:
324
307
 
325
- ```typescript
326
- class Client {
327
- constructor(options: Options) {
328
- // Manual validation if needed
329
- if (!options.timeout) throw new Error("timeout required");
330
- }
331
- }
308
+ ```bash
309
+ DEBUG=1 npm run build
332
310
  ```
333
311
 
334
- ## Credits
335
- The actual validation work is done by [typia](https://github.com/samchon/typia). This package just generates the necessary code to call typia's functions based on your TypeScript types.
336
-
337
- > NOTE: The whole package was all mostly LLM. Feel free to improve it without care for the author's feelings.
312
+ ## Limitations
338
313
 
314
+ - Generic type parameters (`T`) cannot be validated - no runtime type information
315
+ - Type-only imports of classes aren't checked (can't do instanceof on type-only imports)
316
+ - Validation of functions is just not done. Need to think about that one.
317
+ - Some complex types may not be fully supported yet. If you find any that fail, please open an issue!
package/dist/src/cli.js CHANGED
@@ -4,113 +4,40 @@ import * as fs from 'fs';
4
4
  import * as path from 'path';
5
5
  import { TypicalTransformer } from './transformer.js';
6
6
  import { loadConfig, validateConfig } from './config.js';
7
- import { inlineSourceMapComment, externalSourceMapComment } from './source-map.js';
8
7
  const program = new Command();
9
- program
10
- .name('typical')
11
- .description('Runtime safe TypeScript transformer using typia')
12
- .version('0.1.0');
8
+ program.name('typical').description('Runtime safe TypeScript transformer').version('0.1.0');
13
9
  program
14
10
  .command('transform')
15
11
  .description('Transform a TypeScript file with runtime validation')
16
12
  .argument('<file>', 'TypeScript file to transform')
17
13
  .option('-o, --output <file>', 'Output file')
18
14
  .option('-c, --config <file>', 'Config file path', 'typical.json')
19
- .option('-m, --mode <mode>', 'Transformation mode: basic, typia, js', 'basic')
20
- .option('--source-map', 'Generate external source map file')
21
- .option('--inline-source-map', 'Include inline source map in output')
22
- .option('--no-source-map', 'Disable source map generation')
15
+ .option('-p, --project <file>', 'TypeScript config file path', 'tsconfig.json')
23
16
  .action(async (file, options) => {
17
+ let transformer = null;
24
18
  try {
25
19
  const config = validateConfig(loadConfig(options.config));
26
- const transformer = new TypicalTransformer(config);
20
+ transformer = new TypicalTransformer(config, options.project);
27
21
  if (!fs.existsSync(file)) {
28
22
  console.error(`File not found: ${file}`);
29
23
  process.exit(1);
30
24
  }
31
- // Determine source map behavior
32
- const generateSourceMap = options.inlineSourceMap || options.sourceMap !== false;
33
25
  console.log(`Transforming ${file}...`);
34
- const result = transformer.transform(path.resolve(file), options.mode ?? 'basic', {
35
- sourceMap: generateSourceMap,
36
- });
26
+ const result = await transformer.transform(path.resolve(file), 'ts');
37
27
  // Determine output file path
38
- const outputFile = options.output
39
- ? path.resolve(options.output)
40
- : options.mode === 'js'
41
- ? file.replace(/\.tsx?$/, '.js')
42
- : file + '.transformed.ts';
43
- let outputCode = result.code;
44
- // Handle source maps
45
- if (result.map) {
46
- if (options.inlineSourceMap) {
47
- // Inline source map as data URL
48
- outputCode += '\n' + inlineSourceMapComment(result.map);
49
- }
50
- else if (options.sourceMap !== false) {
51
- // Write external source map file
52
- const mapFile = outputFile + '.map';
53
- fs.writeFileSync(mapFile, JSON.stringify(result.map, null, 2));
54
- outputCode += '\n' + externalSourceMapComment(path.basename(mapFile));
55
- console.log(`Source map written to ${mapFile}`);
56
- }
57
- }
58
- fs.writeFileSync(outputFile, outputCode);
28
+ const outputFile = options.output ? path.resolve(options.output) : file + '.transformed.ts';
29
+ fs.writeFileSync(outputFile, result.code);
59
30
  console.log(`Transformed code written to ${outputFile}`);
60
31
  }
61
32
  catch (error) {
62
33
  console.error('Transformation failed:', error);
63
34
  process.exit(1);
64
35
  }
36
+ finally {
37
+ if (transformer) {
38
+ await transformer.close();
39
+ }
40
+ }
65
41
  });
66
- // program
67
- // .command('build')
68
- // .description('Transform all TypeScript files in the project')
69
- // .option('-c, --config <file>', 'Config file path')
70
- // .option('--dry-run', 'Show what would be transformed without making changes')
71
- // .action(async (options: { config?: string, dryRun?: boolean }) => {
72
- // try {
73
- // const transformer = new TypicalTransformer();
74
- // const { glob } = await import('glob');
75
- // const config = loadConfig(options.config);
76
- // if (!config.include || config.include.length === 0) {
77
- // console.error('No include patterns specified in config');
78
- // process.exit(1);
79
- // }
80
- // const files: string[] = [];
81
- // for (const pattern of config.include) {
82
- // const matched = await glob(pattern, {
83
- // ignore: config.exclude,
84
- // absolute: true
85
- // });
86
- // files.push(...matched);
87
- // }
88
- // console.log(`Found ${files.length} files to transform`);
89
- // if (options.dryRun) {
90
- // files.forEach(file => console.log(`Would transform: ${file}`));
91
- // return;
92
- // }
93
- // let transformed = 0;
94
- // for (const file of files) {
95
- // // Double-check with our shared filtering logic
96
- // if (!shouldIncludeFile(file, config)) {
97
- // console.log(`Skipping ${file} (excluded by filters)`);
98
- // continue;
99
- // }
100
- // try {
101
- // console.log(`Transforming ${file}...`);
102
- // const transformedCode = transformer.transformFile(file, ts);
103
- // fs.writeFileSync(file, transformedCode);
104
- // transformed++;
105
- // } catch (error) {
106
- // console.error(`Failed to transform ${file}:`, error);
107
- // }
108
- // }
109
- // console.log(`Successfully transformed ${transformed}/${files.length} files`);
110
- // } catch (error) {
111
- // console.error('Build failed:', error);
112
- // process.exit(1);
113
- // }
114
- // });
115
42
  program.parse();
116
43
  //# sourceMappingURL=cli.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,KAAK,EAAE,MAAM,IAAI,CAAA;AACxB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAA;AAC5B,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AACrD,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAExD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAA;AAE7B,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,WAAW,CAAC,qCAAqC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;AAE3F,OAAO;KACJ,OAAO,CAAC,WAAW,CAAC;KACpB,WAAW,CAAC,qDAAqD,CAAC;KAClE,QAAQ,CAAC,QAAQ,EAAE,8BAA8B,CAAC;KAClD,MAAM,CAAC,qBAAqB,EAAE,aAAa,CAAC;KAC5C,MAAM,CAAC,qBAAqB,EAAE,kBAAkB,EAAE,cAAc,CAAC;KACjE,MAAM,CAAC,sBAAsB,EAAE,6BAA6B,EAAE,eAAe,CAAC;KAC9E,MAAM,CACL,KAAK,EACH,IAAY,EACZ,OAIC,EACD,EAAE;IACF,IAAI,WAAW,GAA8B,IAAI,CAAA;IACjD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,cAAc,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAA;QACzD,WAAW,GAAG,IAAI,kBAAkB,CAAC,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,CAAA;QAE7D,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACzB,OAAO,CAAC,KAAK,CAAC,mBAAmB,IAAI,EAAE,CAAC,CAAA;YACxC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjB,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,KAAK,CAAC,CAAA;QACtC,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,CAAA;QAEpE,6BAA6B;QAC7B,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,iBAAiB,CAAA;QAE3F,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,CAAA;QACzC,OAAO,CAAC,GAAG,CAAC,+BAA+B,UAAU,EAAE,CAAC,CAAA;IAC1D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,wBAAwB,EAAE,KAAK,CAAC,CAAA;QAC9C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;YAAS,CAAC;QACT,IAAI,WAAW,EAAE,CAAC;YAChB,MAAM,WAAW,CAAC,KAAK,EAAE,CAAA;QAC3B,CAAC;IACH,CAAC;AACH,CAAC,CACF,CAAA;AAEH,OAAO,CAAC,KAAK,EAAE,CAAA"}