@elliots/typical 0.1.9 → 0.1.10

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 CHANGED
@@ -35,18 +35,23 @@ npm add typical
35
35
 
36
36
  Optional: Create a `typical.json` file in your project root.
37
37
 
38
- If not provided, these default settings will be used.
38
+ If not provided, these default settings will be used (optimized for development):
39
39
 
40
40
  ```json
41
41
  {
42
42
  "include": ["**/*.ts", "**/*.tsx"],
43
43
  "exclude": ["node_modules/**", "**/*.d.ts", "dist/**", "build/**"],
44
- "reusableValidators": true,
44
+ "reusableValidators": false,
45
45
  "validateFunctions": true,
46
46
  "validateCasts": false,
47
47
  "hoistRegex": true,
48
48
  "ignoreDOMTypes": true,
49
- "ignoreTypes": []
49
+ "ignoreTypes": [],
50
+ "sourceMap": {
51
+ "enabled": true,
52
+ "includeContent": true,
53
+ "inline": false
54
+ }
50
55
  }
51
56
  ```
52
57
 
@@ -56,12 +61,31 @@ If not provided, these default settings will be used.
56
61
  |--------|---------|-------------|
57
62
  | `include` | `["**/*.ts", "**/*.tsx"]` | Glob patterns for files to transform |
58
63
  | `exclude` | `["node_modules/**", "**/*.d.ts", "dist/**", "build/**"]` | Glob patterns for files to skip |
59
- | `reusableValidators` | `true` | Create shared validators for identical types (smaller output, allows reuse) |
64
+ | `reusableValidators` | `false` | Create shared validators for identical types (smaller output). Incompatible with source maps. |
60
65
  | `validateFunctions` | `true` | Validate function parameters and return types at runtime |
61
66
  | `validateCasts` | `false` | Validate type assertions (`as Type`) at runtime |
62
67
  | `hoistRegex` | `true` | Hoist regex patterns to top-level constants (improves performance) |
63
68
  | `ignoreDOMTypes` | `true` | Skip validation for DOM types (Document, Element, etc.) |
64
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 |
74
+
75
+ ### Production Configuration
76
+
77
+ For production builds, disable source maps and enable reusable validators for smaller output:
78
+
79
+ ```json
80
+ {
81
+ "reusableValidators": true,
82
+ "sourceMap": {
83
+ "enabled": false
84
+ }
85
+ }
86
+ ```
87
+
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.
65
89
 
66
90
  ## Usage
67
91
 
@@ -174,6 +198,139 @@ But basically you shouldn't need to care about how it works internally, it makes
174
198
 
175
199
  * sort of. probably. something like it anyway.
176
200
 
201
+ ## Flow Analysis
202
+
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.
204
+
205
+ ### When return validation is skipped:
206
+
207
+ ```typescript
208
+ interface User { name: string; }
209
+
210
+ // Direct parameter return - no redundant validation
211
+ function validate(user: User): User {
212
+ return user; // Already validated on entry, skip return validation
213
+ }
214
+
215
+ // Property access from validated parameter
216
+ function getAddress(user: User): Address {
217
+ return user.address; // user was validated, address is safe
218
+ }
219
+
220
+ // Type-annotated const
221
+ function getUser(): User {
222
+ const user: User = fetchData(); // const is validated here
223
+ return user; // skip redundant validation
224
+ }
225
+ ```
226
+
227
+ ### When return validation IS applied (tainting):
228
+
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
+ }
235
+
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
+ }
241
+
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
+ }
247
+
248
+ // Spread into new object
249
+ function cloneUser(user: User): User {
250
+ return { ...user }; // New object, must validate
251
+ }
252
+ ```
253
+
254
+ ## Debugging
255
+
256
+ ### Intermediate Files
257
+
258
+ To see what code Typical generates before typia processes it, enable intermediate file output:
259
+
260
+ ```json
261
+ {
262
+ "debug": {
263
+ "writeIntermediateFiles": true
264
+ }
265
+ }
266
+ ```
267
+
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:
273
+
274
+ ```bash
275
+ DEBUG=1 npm run build
276
+ ```
277
+
278
+ ## Troubleshooting
279
+
280
+ ### "Failed to transform the following types"
281
+
282
+ This error means typia couldn't generate validation code for certain types. Common causes:
283
+
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`
286
+
287
+ 2. **React types**: Event handlers, refs, and other React types often can't be validated.
288
+ - Solution: Add `"React.*"` to `ignoreTypes`
289
+
290
+ 3. **Third-party library types**: Some library types are too complex.
291
+ - Solution: Add the specific type patterns to `ignoreTypes`
292
+
293
+ ```json
294
+ {
295
+ "ignoreTypes": ["React.*", "Express.Request", "Prisma.*"]
296
+ }
297
+ ```
298
+
299
+ ### "Window & typeof globalThis" errors
300
+
301
+ This occurs when a type includes DOM globals. Enable `ignoreDOMTypes: true` or add the specific type to `ignoreTypes`.
302
+
303
+ ### Generic type parameters not validated
304
+
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:
306
+
307
+ ```typescript
308
+ function identity<T>(value: T): T {
309
+ return value; // T is not validated - no runtime type info
310
+ }
311
+ ```
312
+
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
+ ```
320
+
321
+ ### Constructor parameters not validated
322
+
323
+ Currently, class constructors are not transformed. This is a known limitation. Validate in the constructor body if needed:
324
+
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
+ }
332
+ ```
333
+
177
334
  ## Credits
178
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.
179
336
 
package/dist/src/cli.js CHANGED
@@ -3,7 +3,8 @@ import { Command } from 'commander';
3
3
  import * as fs from 'fs';
4
4
  import * as path from 'path';
5
5
  import { TypicalTransformer } from './transformer.js';
6
- import { loadConfig } from './config.js';
6
+ import { loadConfig, validateConfig } from './config.js';
7
+ import { inlineSourceMapComment, externalSourceMapComment } from './source-map.js';
7
8
  const program = new Command();
8
9
  program
9
10
  .name('typical')
@@ -16,19 +17,45 @@ program
16
17
  .option('-o, --output <file>', 'Output file')
17
18
  .option('-c, --config <file>', 'Config file path', 'typical.json')
18
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')
19
23
  .action(async (file, options) => {
20
24
  try {
21
- const config = loadConfig(options.config);
25
+ const config = validateConfig(loadConfig(options.config));
22
26
  const transformer = new TypicalTransformer(config);
23
27
  if (!fs.existsSync(file)) {
24
28
  console.error(`File not found: ${file}`);
25
29
  process.exit(1);
26
30
  }
31
+ // Determine source map behavior
32
+ const generateSourceMap = options.inlineSourceMap || options.sourceMap !== false;
27
33
  console.log(`Transforming ${file}...`);
28
- const transformedCode = transformer.transform(path.resolve(file), options.mode ?? 'basic');
29
- const outputFilename = options.output ? path.resolve(options.output) : options.mode === 'js' ? file + '.js' : file + '.transformed.ts';
30
- const outputFile = options.output ? path.resolve(options.output) : file + '.transformed.ts';
31
- fs.writeFileSync(outputFile, transformedCode);
34
+ const result = transformer.transform(path.resolve(file), options.mode ?? 'basic', {
35
+ sourceMap: generateSourceMap,
36
+ });
37
+ // 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);
32
59
  console.log(`Transformed code written to ${outputFile}`);
33
60
  }
34
61
  catch (error) {
@@ -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":"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"}
@@ -1,6 +1,23 @@
1
1
  export interface TypicalDebugConfig {
2
2
  writeIntermediateFiles?: boolean;
3
3
  }
4
+ /**
5
+ * Configuration options for source map generation.
6
+ */
7
+ export interface TypicalSourceMapConfig {
8
+ /**
9
+ * Generate source maps. Default: true
10
+ */
11
+ enabled?: boolean;
12
+ /**
13
+ * Include original source content in the map. Default: true
14
+ */
15
+ includeContent?: boolean;
16
+ /**
17
+ * Use inline source maps (data URL) instead of external files. Default: false
18
+ */
19
+ inline?: boolean;
20
+ }
4
21
  export interface TypicalConfig {
5
22
  include?: string[];
6
23
  exclude?: string[];
@@ -26,6 +43,23 @@ export interface TypicalConfig {
26
43
  * Default: true
27
44
  */
28
45
  validateFunctions?: boolean;
46
+ /**
47
+ * Source map generation settings.
48
+ * Controls whether and how source maps are generated for transformed code.
49
+ */
50
+ sourceMap?: TypicalSourceMapConfig;
51
+ }
52
+ /**
53
+ * Pre-compiled regex patterns for ignore type matching.
54
+ * This is populated during config loading for performance.
55
+ */
56
+ export interface CompiledIgnorePatterns {
57
+ /** Compiled patterns from user ignoreTypes config */
58
+ userPatterns: RegExp[];
59
+ /** Compiled patterns from DOM_TYPES_TO_IGNORE (when ignoreDOMTypes is true) */
60
+ domPatterns: RegExp[];
61
+ /** All patterns combined for quick checking */
62
+ allPatterns: RegExp[];
29
63
  }
30
64
  export declare const defaultConfig: TypicalConfig;
31
65
  /**
@@ -33,4 +67,26 @@ export declare const defaultConfig: TypicalConfig;
33
67
  * These are the base DOM types - classes extending them are checked separately.
34
68
  */
35
69
  export declare const DOM_TYPES_TO_IGNORE: string[];
70
+ /**
71
+ * Convert a glob pattern to a RegExp for type matching.
72
+ * Supports wildcards: "React.*" -> /^React\..*$/
73
+ */
74
+ export declare function compileIgnorePattern(pattern: string): RegExp | null;
75
+ /**
76
+ * Pre-compile all ignore patterns for efficient matching.
77
+ */
78
+ export declare function compileIgnorePatterns(config: TypicalConfig): CompiledIgnorePatterns;
79
+ /**
80
+ * Get compiled ignore patterns, using cache if config hasn't changed.
81
+ */
82
+ export declare function getCompiledIgnorePatterns(config: TypicalConfig): CompiledIgnorePatterns;
36
83
  export declare function loadConfig(configPath?: string): TypicalConfig;
84
+ /**
85
+ * Validate and adjust config for consistency.
86
+ * Currently handles:
87
+ * - Disabling reusableValidators when source maps are enabled (required for accurate mappings)
88
+ *
89
+ * @param config The config to validate
90
+ * @returns Validated/adjusted config
91
+ */
92
+ export declare function validateConfig(config: TypicalConfig): TypicalConfig;
@@ -1,7 +1,7 @@
1
1
  export const defaultConfig = {
2
2
  include: ["**/*.ts", "**/*.tsx"],
3
3
  exclude: ["node_modules/**", "**/*.d.ts", "dist/**", "build/**"],
4
- reusableValidators: true,
4
+ reusableValidators: false, // Off by default for accurate source maps (set to true for production)
5
5
  validateCasts: false,
6
6
  validateFunctions: true,
7
7
  hoistRegex: true,
@@ -9,6 +9,11 @@ export const defaultConfig = {
9
9
  debug: {
10
10
  writeIntermediateFiles: false,
11
11
  },
12
+ sourceMap: {
13
+ enabled: true, // On by default for debugging (set to false for production)
14
+ includeContent: true,
15
+ inline: false,
16
+ },
12
17
  };
13
18
  // FIXME: find a better way to work out which types to ignore
14
19
  /**
@@ -53,6 +58,65 @@ export const DOM_TYPES_TO_IGNORE = [
53
58
  ];
54
59
  import fs from 'fs';
55
60
  import path from 'path';
61
+ /**
62
+ * Convert a glob pattern to a RegExp for type matching.
63
+ * Supports wildcards: "React.*" -> /^React\..*$/
64
+ */
65
+ export function compileIgnorePattern(pattern) {
66
+ try {
67
+ const regexStr = '^' + pattern
68
+ .replace(/[.+^${}()|[\]\\]/g, '\\$&') // Escape special regex chars except *
69
+ .replace(/\*/g, '.*') + '$';
70
+ return new RegExp(regexStr);
71
+ }
72
+ catch (error) {
73
+ console.warn(`TYPICAL: Invalid ignoreTypes pattern "${pattern}": ${error}`);
74
+ return null;
75
+ }
76
+ }
77
+ /**
78
+ * Pre-compile all ignore patterns for efficient matching.
79
+ */
80
+ export function compileIgnorePatterns(config) {
81
+ const userPatterns = [];
82
+ const domPatterns = [];
83
+ // Compile user patterns
84
+ for (const pattern of config.ignoreTypes ?? []) {
85
+ const compiled = compileIgnorePattern(pattern);
86
+ if (compiled) {
87
+ userPatterns.push(compiled);
88
+ }
89
+ }
90
+ // Compile DOM patterns if enabled (default: true)
91
+ if (config.ignoreDOMTypes !== false) {
92
+ for (const pattern of DOM_TYPES_TO_IGNORE) {
93
+ const compiled = compileIgnorePattern(pattern);
94
+ if (compiled) {
95
+ domPatterns.push(compiled);
96
+ }
97
+ }
98
+ }
99
+ return {
100
+ userPatterns,
101
+ domPatterns,
102
+ allPatterns: [...userPatterns, ...domPatterns],
103
+ };
104
+ }
105
+ // Cache for compiled patterns, keyed by config identity
106
+ let cachedPatterns = null;
107
+ let cachedConfig = null;
108
+ /**
109
+ * Get compiled ignore patterns, using cache if config hasn't changed.
110
+ */
111
+ export function getCompiledIgnorePatterns(config) {
112
+ // Simple identity check - if same config object, use cache
113
+ if (cachedConfig === config && cachedPatterns) {
114
+ return cachedPatterns;
115
+ }
116
+ cachedConfig = config;
117
+ cachedPatterns = compileIgnorePatterns(config);
118
+ return cachedPatterns;
119
+ }
56
120
  export function loadConfig(configPath) {
57
121
  const configFile = configPath || path.join(process.cwd(), 'typical.json');
58
122
  if (fs.existsSync(configFile)) {
@@ -71,4 +135,32 @@ export function loadConfig(configPath) {
71
135
  }
72
136
  return defaultConfig;
73
137
  }
138
+ let warnedAboutSourceMaps = false;
139
+ /**
140
+ * Validate and adjust config for consistency.
141
+ * Currently handles:
142
+ * - Disabling reusableValidators when source maps are enabled (required for accurate mappings)
143
+ *
144
+ * @param config The config to validate
145
+ * @returns Validated/adjusted config
146
+ */
147
+ export function validateConfig(config) {
148
+ let result = config;
149
+ // Source maps require inline validators (not reusable) because each validation
150
+ // call needs its own source map marker pointing to the correct type annotation.
151
+ // With reusable validators, the expanded typia code would all map to the validator
152
+ // declaration rather than the individual usage sites.
153
+ const sourceMapEnabled = config.sourceMap?.enabled !== false;
154
+ const reusableValidatorsEnabled = config.reusableValidators === true;
155
+ if (sourceMapEnabled && reusableValidatorsEnabled) {
156
+ if (!warnedAboutSourceMaps) {
157
+ warnedAboutSourceMaps = true;
158
+ console.warn("TYPICAL: Both sourceMap and reusableValidators are enabled. " +
159
+ "Disabling reusableValidators for accurate source mapping. " +
160
+ "For production builds, set sourceMap.enabled: false to use reusableValidators.");
161
+ }
162
+ result = { ...result, reusableValidators: false };
163
+ }
164
+ return result;
165
+ }
74
166
  //# sourceMappingURL=config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AA+BA,MAAM,CAAC,MAAM,aAAa,GAAkB;IAC1C,OAAO,EAAE,CAAC,SAAS,EAAE,UAAU,CAAC;IAChC,OAAO,EAAE,CAAC,iBAAiB,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,CAAC;IAChE,kBAAkB,EAAE,IAAI;IACxB,aAAa,EAAE,KAAK;IACpB,iBAAiB,EAAE,IAAI;IACvB,UAAU,EAAE,IAAI;IAChB,cAAc,EAAE,IAAI;IACpB,KAAK,EAAE;QACL,sBAAsB,EAAE,KAAK;KAC9B;CACF,CAAC;AAEF,6DAA6D;AAC7D;;;GAGG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,iBAAiB;IACjB,UAAU;IACV,kBAAkB;IAClB,SAAS;IACT,MAAM;IACN,YAAY;IACZ,QAAQ;IACR,aAAa;IACb,gBAAgB;IAChB,cAAc;IACd,aAAa;IACb,gBAAgB;IAChB,eAAe;IACf,aAAa;IACb,YAAY;IACZ,SAAS;IACT,QAAQ;IACR,yBAAyB;IACzB,UAAU;IACV,cAAc;IACd,cAAc;IACd,qBAAqB;IACrB,WAAW;IACX,OAAO;IACP,MAAM;IACN,SAAS;IACT,cAAc;IACd,uBAAuB;IACvB,cAAc;IACd,MAAM;IACN,OAAO;IACP,UAAU;IACV,WAAW;IACX,YAAY;CACb,CAAC;AAEF,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,MAAM,UAAU,UAAU,CAAC,UAAmB;IAC5C,MAAM,UAAU,GAAG,UAAU,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,cAAc,CAAC,CAAC;IAE1E,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC9B,IAAI,CAAC;YACH,MAAM,aAAa,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;YAC1D,MAAM,UAAU,GAA2B,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;YAErE,OAAO;gBACL,GAAG,aAAa;gBAChB,GAAG,UAAU;aACd,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,+BAA+B,UAAU,GAAG,EAAE,KAAK,CAAC,CAAC;YAClE,OAAO,aAAa,CAAC;QACvB,CAAC;IACH,CAAC;IAED,OAAO,aAAa,CAAC;AACvB,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"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"}
@@ -4,5 +4,6 @@
4
4
  export declare function resolve(specifier: string, context: any, nextResolve: any): Promise<any>;
5
5
  /**
6
6
  * Load hook - transforms TypeScript files on the fly
7
+ * Includes inline source maps for proper error stack traces in Node.js
7
8
  */
8
9
  export declare function load(url: string, context: any, nextLoad: any): Promise<any>;
@@ -1,7 +1,10 @@
1
1
  import { fileURLToPath, pathToFileURL } from "url";
2
2
  import { existsSync } from "fs";
3
3
  import { TypicalTransformer } from "./transformer.js";
4
- const transformer = new TypicalTransformer();
4
+ import { inlineSourceMapComment } from "./source-map.js";
5
+ import { loadConfig, validateConfig } from "./config.js";
6
+ const config = validateConfig(loadConfig());
7
+ const transformer = new TypicalTransformer(config);
5
8
  /**
6
9
  * Resolve hook - rewrites .js imports to .ts if the .ts file exists
7
10
  */
@@ -25,6 +28,7 @@ export async function resolve(specifier, context, nextResolve) {
25
28
  }
26
29
  /**
27
30
  * Load hook - transforms TypeScript files on the fly
31
+ * Includes inline source maps for proper error stack traces in Node.js
28
32
  */
29
33
  export async function load(url, context, nextLoad) {
30
34
  if (!url.endsWith(".ts")) {
@@ -32,10 +36,16 @@ export async function load(url, context, nextLoad) {
32
36
  }
33
37
  const filePath = fileURLToPath(url);
34
38
  try {
35
- const transformedCode = transformer.transform(filePath, 'js');
39
+ // Transform with source map support enabled
40
+ const result = transformer.transform(filePath, 'js', { sourceMap: true });
41
+ // Append inline source map for Node.js source map support
42
+ let source = result.code;
43
+ if (result.map) {
44
+ source += '\n' + inlineSourceMapComment(result.map);
45
+ }
36
46
  return {
37
47
  format: "module",
38
- source: transformedCode,
48
+ source,
39
49
  shortCircuit: true,
40
50
  };
41
51
  }
@@ -1 +1 @@
1
- {"version":3,"file":"esm-loader.js","sourceRoot":"","sources":["../../src/esm-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAEtD,MAAM,WAAW,GAAG,IAAI,kBAAkB,EAAE,CAAC;AAE7C;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,SAAiB,EAAE,OAAY,EAAE,WAAgB;IAC7E,6CAA6C;IAC7C,IAAI,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3D,MAAM,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;QAC9B,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,UAAU,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC;YAC5C,MAAM,GAAG,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,EAAE,UAAU,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;YACjE,MAAM,MAAM,GAAG,GAAG,GAAG,GAAG,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;YAE1D,IAAI,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;gBACvB,OAAO;oBACL,GAAG,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,IAAI;oBAC/B,YAAY,EAAE,IAAI;iBACnB,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,WAAW,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;AACzC,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,GAAW,EAAE,OAAY,EAAE,QAAa;IACjE,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAChC,CAAC;IACD,MAAM,QAAQ,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;IAEpC,IAAI,CAAC;QACH,MAAM,eAAe,GAAG,WAAW,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QAC9D,OAAO;YACL,MAAM,EAAE,QAAQ;YAChB,MAAM,EAAE,eAAe;YACvB,YAAY,EAAE,IAAI;SACnB,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,sBAAsB,QAAQ,GAAG,EAAE,KAAK,CAAC,CAAC;QACxD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"esm-loader.js","sourceRoot":"","sources":["../../src/esm-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAEzD,MAAM,MAAM,GAAG,cAAc,CAAC,UAAU,EAAE,CAAC,CAAC;AAC5C,MAAM,WAAW,GAAG,IAAI,kBAAkB,CAAC,MAAM,CAAC,CAAC;AAEnD;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,SAAiB,EAAE,OAAY,EAAE,WAAgB;IAC7E,6CAA6C;IAC7C,IAAI,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3D,MAAM,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC;QAC9B,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,UAAU,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC;YAC5C,MAAM,GAAG,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,EAAE,UAAU,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;YACjE,MAAM,MAAM,GAAG,GAAG,GAAG,GAAG,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;YAE1D,IAAI,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;gBACvB,OAAO;oBACL,GAAG,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,IAAI;oBAC/B,YAAY,EAAE,IAAI;iBACnB,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,WAAW,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;AACzC,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,GAAW,EAAE,OAAY,EAAE,QAAa;IACjE,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAChC,CAAC;IACD,MAAM,QAAQ,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;IAEpC,IAAI,CAAC;QACH,4CAA4C;QAC5C,MAAM,MAAM,GAAG,WAAW,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAE1E,0DAA0D;QAC1D,IAAI,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC;QACzB,IAAI,MAAM,CAAC,GAAG,EAAE,CAAC;YACf,MAAM,IAAI,IAAI,GAAG,sBAAsB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACtD,CAAC;QAED,OAAO;YACL,MAAM,EAAE,QAAQ;YAChB,MAAM;YACN,YAAY,EAAE,IAAI;SACnB,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,sBAAsB,QAAQ,GAAG,EAAE,KAAK,CAAC,CAAC;QACxD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC"}
@@ -1,2 +1,4 @@
1
- export { TypicalTransformer } from './transformer.js';
2
- export { loadConfig, defaultConfig, TypicalConfig } from './config.js';
1
+ export { TypicalTransformer, TransformResult } from './transformer.js';
2
+ export { loadConfig, validateConfig, defaultConfig, TypicalConfig, TypicalSourceMapConfig } from './config.js';
3
+ export { composeSourceMaps, inlineSourceMapComment, externalSourceMapComment, createIdentityMap, stripSourceMapComment, } from './source-map.js';
4
+ export type { SourceMapOptions } from './source-map.js';
package/dist/src/index.js CHANGED
@@ -1,3 +1,4 @@
1
1
  export { TypicalTransformer } from './transformer.js';
2
- export { loadConfig, defaultConfig } from './config.js';
2
+ export { loadConfig, validateConfig, defaultConfig } from './config.js';
3
+ export { composeSourceMaps, inlineSourceMapComment, externalSourceMapComment, createIdentityMap, stripSourceMapComment, } from './source-map.js';
3
4
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,aAAa,EAAiB,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAmB,MAAM,kBAAkB,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,aAAa,EAAyC,MAAM,aAAa,CAAC;AAC/G,OAAO,EACL,iBAAiB,EACjB,sBAAsB,EACtB,wBAAwB,EACxB,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,78 @@
1
+ import MagicString from 'magic-string';
2
+ import type { DecodedSourceMap, EncodedSourceMap } from '@ampproject/remapping';
3
+ /**
4
+ * Result of a transformation that includes source map information.
5
+ */
6
+ export interface TransformResult {
7
+ code: string;
8
+ map: EncodedSourceMap | null;
9
+ }
10
+ /**
11
+ * Configuration options for source map generation.
12
+ */
13
+ export interface SourceMapOptions {
14
+ /** Generate source maps. Default: true */
15
+ enabled?: boolean;
16
+ /** Include source content in map. Default: true */
17
+ includeContent?: boolean;
18
+ /** Use inline source maps (data URL). Default: false */
19
+ inline?: boolean;
20
+ }
21
+ /**
22
+ * Default source map options.
23
+ */
24
+ export declare const defaultSourceMapOptions: Required<SourceMapOptions>;
25
+ /**
26
+ * Compose multiple source maps together.
27
+ * Given maps [A->B, B->C], produces A->C.
28
+ * Maps are applied in order: first map is closest to original source.
29
+ */
30
+ export declare function composeSourceMaps(maps: (EncodedSourceMap | DecodedSourceMap | string | null | undefined)[], originalFileName: string): EncodedSourceMap | null;
31
+ /**
32
+ * Generate an inline source map comment (data URL).
33
+ */
34
+ export declare function inlineSourceMapComment(map: EncodedSourceMap | string): string;
35
+ /**
36
+ * Generate an external source map URL comment.
37
+ */
38
+ export declare function externalSourceMapComment(mapFileName: string): string;
39
+ /**
40
+ * Create a MagicString instance for tracking source modifications.
41
+ */
42
+ export declare function createMagicString(source: string, filename?: string): MagicString;
43
+ /**
44
+ * Generate a source map from a MagicString instance.
45
+ */
46
+ export declare function generateSourceMap(ms: MagicString, options: {
47
+ source: string;
48
+ file?: string;
49
+ includeContent?: boolean;
50
+ hires?: boolean | 'boundary';
51
+ }): EncodedSourceMap;
52
+ /**
53
+ * Create an identity source map (maps each position to itself).
54
+ * Useful as a placeholder when no transformation occurred.
55
+ */
56
+ export declare function createIdentityMap(source: string, fileName: string, includeContent?: boolean): EncodedSourceMap;
57
+ /**
58
+ * Represents a tracked modification to source code.
59
+ */
60
+ export interface SourceModification {
61
+ /** Start position in original source */
62
+ start: number;
63
+ /** End position in original source */
64
+ end: number;
65
+ /** The replacement text */
66
+ replacement: string;
67
+ /** Type of modification */
68
+ type: 'insert-before' | 'insert-after' | 'replace' | 'prepend' | 'append';
69
+ }
70
+ /**
71
+ * Apply a list of modifications to source code using MagicString.
72
+ * Returns the modified code and source map.
73
+ */
74
+ export declare function applyModifications(source: string, fileName: string, modifications: SourceModification[], includeContent?: boolean): TransformResult;
75
+ /**
76
+ * Strip any existing source map comments from code.
77
+ */
78
+ export declare function stripSourceMapComment(code: string): string;