@knighted/module 1.4.0 → 1.5.0-rc.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.
- package/README.md +2 -0
- package/dist/cjs/cli.cjs +103 -7
- package/dist/cjs/format.cjs +12 -17
- package/dist/cjs/format.d.cts +5 -6
- package/dist/cjs/module.cjs +37 -8
- package/dist/cjs/module.d.cts +14 -1
- package/dist/cjs/specifier.cjs +10 -5
- package/dist/cjs/specifier.d.cts +3 -1
- package/dist/cjs/types.d.cts +2 -0
- package/dist/cli.js +105 -9
- package/dist/format.d.ts +5 -6
- package/dist/format.js +10 -15
- package/dist/module.d.ts +14 -1
- package/dist/module.js +35 -6
- package/dist/specifier.d.ts +3 -1
- package/dist/specifier.js +10 -5
- package/dist/types.d.ts +2 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -114,6 +114,7 @@ type ModuleOptions = {
|
|
|
114
114
|
target: 'module' | 'commonjs'
|
|
115
115
|
sourceType?: 'auto' | 'module' | 'commonjs'
|
|
116
116
|
transformSyntax?: boolean | 'globals-only'
|
|
117
|
+
sourceMap?: boolean
|
|
117
118
|
liveBindings?: 'strict' | 'loose' | 'off'
|
|
118
119
|
appendJsExtension?: 'off' | 'relative-only' | 'all'
|
|
119
120
|
appendDirectoryIndex?: string | false
|
|
@@ -167,6 +168,7 @@ type ModuleOptions = {
|
|
|
167
168
|
- `cjsDefault` (`auto`): bundler-style default interop vs direct `module.exports`.
|
|
168
169
|
- `idiomaticExports` (`safe`): when raising CJS to ESM, attempt to synthesize `export` statements directly when it is safe. `off` always uses the helper bag; `aggressive` currently matches `safe` heuristics.
|
|
169
170
|
- `out`/`inPlace`: choose output location. Default returns the transformed string (CLI emits to stdout). `out` writes to the provided path. `inPlace` overwrites the input files on disk and does not return/emit the code.
|
|
171
|
+
- `sourceMap` (`false`): when true, returns `{ code, map }` from `transform` and writes the map if you also set `out`/`inPlace`. Maps are generated from the same MagicString pipeline used for the code.
|
|
170
172
|
- `cwd` (`process.cwd()`): Base directory used to resolve relative `out` paths.
|
|
171
173
|
|
|
172
174
|
> [!NOTE]
|
package/dist/cjs/cli.cjs
CHANGED
|
@@ -38,6 +38,7 @@ const defaultOptions = {
|
|
|
38
38
|
idiomaticExports: 'safe',
|
|
39
39
|
importMetaPrelude: 'auto',
|
|
40
40
|
topLevelAwait: 'error',
|
|
41
|
+
sourceMap: false,
|
|
41
42
|
cwd: undefined,
|
|
42
43
|
out: undefined,
|
|
43
44
|
inPlace: false
|
|
@@ -183,6 +184,11 @@ const optionsTable = [{
|
|
|
183
184
|
short: 'm',
|
|
184
185
|
type: 'string',
|
|
185
186
|
desc: 'Emit import.meta prelude (off|auto|on)'
|
|
187
|
+
}, {
|
|
188
|
+
long: 'source-map',
|
|
189
|
+
short: undefined,
|
|
190
|
+
type: 'boolean',
|
|
191
|
+
desc: 'Emit a source map alongside transformed output (use --source-map=inline for stdout)'
|
|
186
192
|
}, {
|
|
187
193
|
long: 'nested-require-strategy',
|
|
188
194
|
short: 'n',
|
|
@@ -305,6 +311,7 @@ const toModuleOptions = values => {
|
|
|
305
311
|
nestedRequireStrategy: parseEnum(values['nested-require-strategy'], ['create-require', 'dynamic-import']) ?? defaultOptions.nestedRequireStrategy,
|
|
306
312
|
requireMainStrategy: parseEnum(values['require-main-strategy'], ['import-meta-main', 'realpath']) ?? defaultOptions.requireMainStrategy,
|
|
307
313
|
liveBindings: parseEnum(values['live-bindings'], ['strict', 'loose', 'off']) ?? defaultOptions.liveBindings,
|
|
314
|
+
sourceMap: Boolean(values['source-map']),
|
|
308
315
|
cwd: values.cwd ? (0, _nodePath.resolve)(String(values.cwd)) : defaultOptions.cwd
|
|
309
316
|
};
|
|
310
317
|
return opts;
|
|
@@ -316,6 +323,55 @@ const readStdin = async stdin => {
|
|
|
316
323
|
}
|
|
317
324
|
return Buffer.concat(chunks).toString('utf8');
|
|
318
325
|
};
|
|
326
|
+
const normalizeSourceMapArgv = argv => {
|
|
327
|
+
let sourceMapInline = false;
|
|
328
|
+
let invalidSourceMapValue = null;
|
|
329
|
+
const normalized = [];
|
|
330
|
+
const recordInvalid = value => {
|
|
331
|
+
if (!invalidSourceMapValue) invalidSourceMapValue = value;
|
|
332
|
+
};
|
|
333
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
334
|
+
const arg = argv[i];
|
|
335
|
+
if (arg === '--source-map') {
|
|
336
|
+
const next = argv[i + 1];
|
|
337
|
+
if (next === 'inline') {
|
|
338
|
+
sourceMapInline = true;
|
|
339
|
+
normalized.push('--source-map');
|
|
340
|
+
i += 1;
|
|
341
|
+
continue;
|
|
342
|
+
}
|
|
343
|
+
if (next === 'true' || next === 'false') {
|
|
344
|
+
normalized.push(`--source-map=${next}`);
|
|
345
|
+
i += 1;
|
|
346
|
+
continue;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
if (arg.startsWith('--source-map=')) {
|
|
350
|
+
const value = arg.slice('--source-map='.length);
|
|
351
|
+
if (value === 'inline') {
|
|
352
|
+
sourceMapInline = true;
|
|
353
|
+
normalized.push('--source-map');
|
|
354
|
+
continue;
|
|
355
|
+
}
|
|
356
|
+
if (value === 'true' || value === 'false') {
|
|
357
|
+
normalized.push(arg);
|
|
358
|
+
continue;
|
|
359
|
+
}
|
|
360
|
+
recordInvalid(value);
|
|
361
|
+
continue;
|
|
362
|
+
}
|
|
363
|
+
if (arg === '--source-map' && argv[i + 1] && argv[i + 1].startsWith('--')) {
|
|
364
|
+
normalized.push('--source-map');
|
|
365
|
+
continue;
|
|
366
|
+
}
|
|
367
|
+
normalized.push(arg);
|
|
368
|
+
}
|
|
369
|
+
return {
|
|
370
|
+
argv: normalized,
|
|
371
|
+
sourceMapInline,
|
|
372
|
+
invalidSourceMapValue
|
|
373
|
+
};
|
|
374
|
+
};
|
|
319
375
|
const expandFiles = async (patterns, cwd, ignore) => {
|
|
320
376
|
const files = new Set();
|
|
321
377
|
for (const pattern of patterns) {
|
|
@@ -403,8 +459,10 @@ const runFiles = async (files, moduleOpts, io, flags) => {
|
|
|
403
459
|
filePath: file,
|
|
404
460
|
detectDualPackageHazard: hazardScope === 'project' ? 'off' : moduleOpts.detectDualPackageHazard
|
|
405
461
|
};
|
|
462
|
+
const allowWrites = !flags.dryRun && !flags.list;
|
|
463
|
+
const writeInPlace = allowWrites && flags.inPlace;
|
|
406
464
|
let writeTarget;
|
|
407
|
-
if (
|
|
465
|
+
if (allowWrites) {
|
|
408
466
|
if (flags.inPlace) {
|
|
409
467
|
perFileOpts.inPlace = true;
|
|
410
468
|
} else if (outPath) {
|
|
@@ -421,8 +479,15 @@ const runFiles = async (files, moduleOpts, io, flags) => {
|
|
|
421
479
|
};
|
|
422
480
|
}
|
|
423
481
|
}
|
|
424
|
-
|
|
482
|
+
if (moduleOpts.sourceMap && (writeTarget || writeInPlace)) {
|
|
483
|
+
perFileOpts.out = undefined;
|
|
484
|
+
perFileOpts.inPlace = false;
|
|
485
|
+
}
|
|
486
|
+
const transformed = await (0, _module.transform)(file, perFileOpts);
|
|
487
|
+
const output = typeof transformed === 'string' ? transformed : transformed.code;
|
|
488
|
+
const map = typeof transformed === 'string' ? null : transformed.map;
|
|
425
489
|
const changed = output !== original;
|
|
490
|
+
let finalOutput = output;
|
|
426
491
|
if (projectHazards) {
|
|
427
492
|
const extras = projectHazards.get(file);
|
|
428
493
|
if (extras?.length) diagnostics.push(...extras);
|
|
@@ -430,8 +495,24 @@ const runFiles = async (files, moduleOpts, io, flags) => {
|
|
|
430
495
|
if (flags.list && changed) {
|
|
431
496
|
logger.info(file);
|
|
432
497
|
}
|
|
433
|
-
if (
|
|
434
|
-
|
|
498
|
+
if (map && flags.sourceMapInline && !writeTarget && !writeInPlace) {
|
|
499
|
+
const mapUri = Buffer.from(JSON.stringify(map)).toString('base64');
|
|
500
|
+
finalOutput = `${output.replace(/\/\/# sourceMappingURL=.*/g, '').trimEnd()}\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,${mapUri}\n`;
|
|
501
|
+
} else if (map && (writeTarget || writeInPlace)) {
|
|
502
|
+
const target = writeTarget ?? file;
|
|
503
|
+
const mapPath = `${target}.map`;
|
|
504
|
+
const mapFile = (0, _nodePath.basename)(mapPath);
|
|
505
|
+
map.file = (0, _nodePath.basename)(target);
|
|
506
|
+
const updated = `${output.replace(/\/\/# sourceMappingURL=.*/g, '').trimEnd()}\n//# sourceMappingURL=${mapFile}\n`;
|
|
507
|
+
await (0, _promises.writeFile)(mapPath, JSON.stringify(map));
|
|
508
|
+
if (writeTarget) {
|
|
509
|
+
await (0, _promises.writeFile)(writeTarget, updated);
|
|
510
|
+
} else if (writeInPlace) {
|
|
511
|
+
await (0, _promises.writeFile)(file, updated);
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
if (!flags.dryRun && !flags.list && !writeTarget && !writeInPlace) {
|
|
515
|
+
io.stdout.write(finalOutput);
|
|
435
516
|
}
|
|
436
517
|
results.push({
|
|
437
518
|
filePath: file,
|
|
@@ -468,11 +549,21 @@ const runCli = async ({
|
|
|
468
549
|
stdout = _nodeProcess.stdout,
|
|
469
550
|
stderr = _nodeProcess.stderr
|
|
470
551
|
} = {}) => {
|
|
552
|
+
const logger = makeLogger(stdout, stderr);
|
|
553
|
+
const {
|
|
554
|
+
argv: normalizedArgv,
|
|
555
|
+
sourceMapInline,
|
|
556
|
+
invalidSourceMapValue
|
|
557
|
+
} = normalizeSourceMapArgv(argv);
|
|
558
|
+
if (invalidSourceMapValue) {
|
|
559
|
+
logger.error(`Invalid --source-map value: ${invalidSourceMapValue}`);
|
|
560
|
+
return 2;
|
|
561
|
+
}
|
|
471
562
|
const {
|
|
472
563
|
values,
|
|
473
564
|
positionals
|
|
474
565
|
} = (0, _nodeUtil.parseArgs)({
|
|
475
|
-
args:
|
|
566
|
+
args: normalizedArgv,
|
|
476
567
|
allowPositionals: true,
|
|
477
568
|
options: Object.fromEntries(optionsTable.map(opt => [opt.long, {
|
|
478
569
|
type: opt.type,
|
|
@@ -481,7 +572,6 @@ const runCli = async ({
|
|
|
481
572
|
} : {})
|
|
482
573
|
}]))
|
|
483
574
|
});
|
|
484
|
-
const logger = makeLogger(stdout, stderr);
|
|
485
575
|
if (values.help) {
|
|
486
576
|
stdout.write(buildHelp(stdout.isTTY ?? false));
|
|
487
577
|
return 0;
|
|
@@ -492,6 +582,7 @@ const runCli = async ({
|
|
|
492
582
|
return 0;
|
|
493
583
|
}
|
|
494
584
|
const moduleOpts = toModuleOptions(values);
|
|
585
|
+
if (sourceMapInline) moduleOpts.sourceMap = true;
|
|
495
586
|
const cwd = moduleOpts.cwd ?? process.cwd();
|
|
496
587
|
const allowStdout = positionals.length <= 1;
|
|
497
588
|
const fromStdin = positionals.length === 0 || positionals.includes('-');
|
|
@@ -504,6 +595,10 @@ const runCli = async ({
|
|
|
504
595
|
const list = Boolean(values.list);
|
|
505
596
|
const summary = Boolean(values.summary);
|
|
506
597
|
const json = Boolean(values.json);
|
|
598
|
+
if (sourceMapInline && (outDir || inPlace)) {
|
|
599
|
+
logger.error('Inline source maps are only supported when writing to stdout');
|
|
600
|
+
return 2;
|
|
601
|
+
}
|
|
507
602
|
if (outDir && inPlace) {
|
|
508
603
|
logger.error('Choose either --out-dir or --in-place, not both');
|
|
509
604
|
return 2;
|
|
@@ -558,7 +653,8 @@ const runCli = async ({
|
|
|
558
653
|
json,
|
|
559
654
|
outDir,
|
|
560
655
|
inPlace,
|
|
561
|
-
allowStdout
|
|
656
|
+
allowStdout,
|
|
657
|
+
sourceMapInline
|
|
562
658
|
});
|
|
563
659
|
if (typeof result.code === 'number' && result.code !== 0) return result.code;
|
|
564
660
|
tasks.push(...result.results);
|
package/dist/cjs/format.cjs
CHANGED
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.
|
|
6
|
+
exports.dualPackageHazardDiagnostics = exports.collectDualPackageUsage = void 0;
|
|
7
|
+
exports.format = format;
|
|
7
8
|
var _nodePath = require("node:path");
|
|
8
9
|
var _promises = require("node:fs/promises");
|
|
9
10
|
var _magicString = _interopRequireDefault(require("magic-string"));
|
|
@@ -291,13 +292,7 @@ const detectDualPackageHazards = async params => {
|
|
|
291
292
|
diagOnce(diag.level, diag.code, diag.message, diag.loc);
|
|
292
293
|
}
|
|
293
294
|
};
|
|
294
|
-
|
|
295
|
-
/**
|
|
296
|
-
* Node added support for import.meta.main.
|
|
297
|
-
* Added in: v24.2.0, v22.18.0
|
|
298
|
-
* @see https://nodejs.org/api/esm.html#importmetamain
|
|
299
|
-
*/
|
|
300
|
-
const format = async (src, ast, opts) => {
|
|
295
|
+
async function format(src, ast, opts) {
|
|
301
296
|
const code = new _magicString.default(src);
|
|
302
297
|
const exportsMeta = {
|
|
303
298
|
hasExportsBeenReassigned: false,
|
|
@@ -522,15 +517,15 @@ const format = async (src, ast, opts) => {
|
|
|
522
517
|
code.prepend(prelude);
|
|
523
518
|
}
|
|
524
519
|
if (opts.target === 'commonjs' && fullTransform && containsTopLevelAwait) {
|
|
525
|
-
const body = code.toString();
|
|
526
520
|
if (opts.topLevelAwait === 'wrap') {
|
|
527
|
-
const
|
|
528
|
-
|
|
529
|
-
const
|
|
530
|
-
|
|
521
|
+
code.prepend('const __tla = (async () => {\n');
|
|
522
|
+
code.append('\nreturn module.exports;\n})();\n');
|
|
523
|
+
code.append('const __setTla = target => {\n if (!target) return;\n const type = typeof target;\n if (type !== "object" && type !== "function") return;\n target.__tla = __tla;\n};\n');
|
|
524
|
+
code.append('__setTla(module.exports);\n__tla.then(resolved => __setTla(resolved), err => { throw err; });\n');
|
|
525
|
+
} else {
|
|
526
|
+
code.prepend(';(async () => {\n');
|
|
527
|
+
code.append('\n})();\n');
|
|
531
528
|
}
|
|
532
|
-
return `;(async () => {\n${body}\n})();\n`;
|
|
533
529
|
}
|
|
534
|
-
return code.toString();
|
|
535
|
-
}
|
|
536
|
-
exports.format = format;
|
|
530
|
+
return opts.sourceMap ? code : code.toString();
|
|
531
|
+
}
|
package/dist/cjs/format.d.cts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Node, ParseResult } from 'oxc-parser';
|
|
2
|
+
import MagicString from 'magic-string';
|
|
2
3
|
import type { Diagnostic, FormatterOptions } from './types.cjs';
|
|
3
4
|
type HazardLevel = 'warning' | 'error';
|
|
4
5
|
export type PackageUse = {
|
|
@@ -22,10 +23,8 @@ declare const dualPackageHazardDiagnostics: (params: {
|
|
|
22
23
|
cwd?: string;
|
|
23
24
|
manifestCache?: Map<string, any | null>;
|
|
24
25
|
}) => Promise<Diagnostic[]>;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
*/
|
|
30
|
-
declare const format: (src: string, ast: ParseResult, opts: FormatterOptions) => Promise<string>;
|
|
26
|
+
declare function format(src: string, ast: ParseResult, opts: FormatterOptions & {
|
|
27
|
+
sourceMap: true;
|
|
28
|
+
}): Promise<MagicString>;
|
|
29
|
+
declare function format(src: string, ast: ParseResult, opts: FormatterOptions): Promise<string>;
|
|
31
30
|
export { format, collectDualPackageUsage, dualPackageHazardDiagnostics };
|
package/dist/cjs/module.cjs
CHANGED
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.
|
|
6
|
+
exports.collectProjectDualPackageHazards = void 0;
|
|
7
|
+
exports.transform = transform;
|
|
7
8
|
var _nodePath = require("node:path");
|
|
8
9
|
var _promises = require("node:fs/promises");
|
|
9
10
|
var _specifier = require("./specifier.cjs");
|
|
@@ -205,11 +206,12 @@ const createDefaultOptions = () => ({
|
|
|
205
206
|
idiomaticExports: 'safe',
|
|
206
207
|
importMetaPrelude: 'auto',
|
|
207
208
|
topLevelAwait: 'error',
|
|
209
|
+
sourceMap: false,
|
|
208
210
|
cwd: undefined,
|
|
209
211
|
out: undefined,
|
|
210
212
|
inPlace: false
|
|
211
213
|
});
|
|
212
|
-
|
|
214
|
+
async function transform(filename, options) {
|
|
213
215
|
const base = createDefaultOptions();
|
|
214
216
|
const opts = options ? {
|
|
215
217
|
...base,
|
|
@@ -226,9 +228,19 @@ const transform = async (filename, options) => {
|
|
|
226
228
|
const file = (0, _nodePath.resolve)(cwdBase, filename);
|
|
227
229
|
const code = (await (0, _promises.readFile)(file)).toString();
|
|
228
230
|
const ast = (0, _parse.parse)(filename, code);
|
|
229
|
-
let
|
|
231
|
+
let sourceCode = null;
|
|
232
|
+
let source;
|
|
233
|
+
if (opts.sourceMap) {
|
|
234
|
+
sourceCode = await (0, _format.format)(code, ast, {
|
|
235
|
+
...opts,
|
|
236
|
+
sourceMap: true
|
|
237
|
+
});
|
|
238
|
+
source = sourceCode.toString();
|
|
239
|
+
} else {
|
|
240
|
+
source = await (0, _format.format)(code, ast, opts);
|
|
241
|
+
}
|
|
230
242
|
if (opts.rewriteSpecifier || appendMode !== 'off' || dirIndex) {
|
|
231
|
-
const
|
|
243
|
+
const applyRewrite = spec => {
|
|
232
244
|
if (spec.type === 'TemplateLiteral' && opts.rewriteTemplateLiterals === 'static-only') {
|
|
233
245
|
const node = spec.node;
|
|
234
246
|
if (node.expressions.length > 0) return;
|
|
@@ -238,8 +250,14 @@ const transform = async (filename, options) => {
|
|
|
238
250
|
const baseValue = rewritten ?? normalized ?? spec.value;
|
|
239
251
|
const appended = appendExtensionIfNeeded(spec, appendMode, dirIndex, baseValue);
|
|
240
252
|
return appended ?? rewritten ?? normalized ?? undefined;
|
|
241
|
-
}
|
|
242
|
-
|
|
253
|
+
};
|
|
254
|
+
if (opts.sourceMap && sourceCode) {
|
|
255
|
+
await _specifier.specifier.updateMagicString(sourceCode, code, ast, applyRewrite);
|
|
256
|
+
source = sourceCode.toString();
|
|
257
|
+
} else {
|
|
258
|
+
const rewritten = await _specifier.specifier.updateSrc(source, (0, _lang.getLangFromExt)(filename), applyRewrite);
|
|
259
|
+
source = rewritten;
|
|
260
|
+
}
|
|
243
261
|
}
|
|
244
262
|
if (detectCycles !== 'off' && opts.target === 'module' && opts.transformSyntax) {
|
|
245
263
|
await detectCircularRequireGraph(file, detectCycles, dirIndex || 'index.js');
|
|
@@ -248,6 +266,17 @@ const transform = async (filename, options) => {
|
|
|
248
266
|
if (outputPath) {
|
|
249
267
|
await (0, _promises.writeFile)(outputPath, source);
|
|
250
268
|
}
|
|
269
|
+
if (opts.sourceMap && sourceCode) {
|
|
270
|
+
const map = sourceCode.generateMap({
|
|
271
|
+
hires: true,
|
|
272
|
+
includeContent: true,
|
|
273
|
+
file: outputPath ?? filename,
|
|
274
|
+
source: opts.filePath ?? filename
|
|
275
|
+
});
|
|
276
|
+
return {
|
|
277
|
+
code: source,
|
|
278
|
+
map
|
|
279
|
+
};
|
|
280
|
+
}
|
|
251
281
|
return source;
|
|
252
|
-
}
|
|
253
|
-
exports.transform = transform;
|
|
282
|
+
}
|
package/dist/cjs/module.d.cts
CHANGED
|
@@ -1,4 +1,17 @@
|
|
|
1
1
|
import type { ModuleOptions, Diagnostic } from './types.cjs';
|
|
2
|
+
import type { SourceMap } from 'magic-string';
|
|
2
3
|
declare const collectProjectDualPackageHazards: (files: string[], opts: ModuleOptions) => Promise<Map<string, Diagnostic[]>>;
|
|
3
|
-
declare
|
|
4
|
+
declare function transform(filename: string, options: ModuleOptions & {
|
|
5
|
+
sourceMap: true;
|
|
6
|
+
}): Promise<{
|
|
7
|
+
code: string;
|
|
8
|
+
map: SourceMap;
|
|
9
|
+
}>;
|
|
10
|
+
declare function transform(filename: string, options?: ModuleOptions & {
|
|
11
|
+
sourceMap?: false | undefined;
|
|
12
|
+
}): Promise<string>;
|
|
13
|
+
declare function transform(filename: string, options?: ModuleOptions): Promise<string | {
|
|
14
|
+
code: string;
|
|
15
|
+
map: SourceMap;
|
|
16
|
+
}>;
|
|
4
17
|
export { transform, collectProjectDualPackageHazards };
|
package/dist/cjs/specifier.cjs
CHANGED
|
@@ -20,8 +20,7 @@ const isBinaryExpression = node => {
|
|
|
20
20
|
const isCallExpression = node => {
|
|
21
21
|
return node.type === 'CallExpression' && node.callee !== undefined;
|
|
22
22
|
};
|
|
23
|
-
const formatSpecifiers = async (src, ast, cb) => {
|
|
24
|
-
const code = new _magicString.default(src);
|
|
23
|
+
const formatSpecifiers = async (src, ast, cb, code = new _magicString.default(src)) => {
|
|
25
24
|
const formatExpression = expression => {
|
|
26
25
|
const node = isCallExpression(expression) ? expression.arguments[0] : expression.source;
|
|
27
26
|
const {
|
|
@@ -235,7 +234,7 @@ const formatSpecifiers = async (src, ast, cb) => {
|
|
|
235
234
|
}
|
|
236
235
|
}
|
|
237
236
|
});
|
|
238
|
-
return code
|
|
237
|
+
return code;
|
|
239
238
|
};
|
|
240
239
|
const isValidFilename = async filename => {
|
|
241
240
|
let stats;
|
|
@@ -258,11 +257,17 @@ const specifier = exports.specifier = {
|
|
|
258
257
|
}
|
|
259
258
|
const src = (await (0, _promises.readFile)(filename)).toString();
|
|
260
259
|
const ast = (0, _oxcParser.parseSync)(filename, src);
|
|
261
|
-
|
|
260
|
+
const code = await formatSpecifiers(src, ast, callback);
|
|
261
|
+
return code.toString();
|
|
262
262
|
},
|
|
263
263
|
async updateSrc(src, lang, callback) {
|
|
264
264
|
const filename = lang === 'ts' ? 'file.ts' : lang === 'tsx' ? 'file.tsx' : lang === 'js' ? 'file.js' : 'file.jsx';
|
|
265
265
|
const ast = (0, _oxcParser.parseSync)(filename, src);
|
|
266
|
-
|
|
266
|
+
const code = await formatSpecifiers(src, ast, callback);
|
|
267
|
+
return code.toString();
|
|
268
|
+
},
|
|
269
|
+
async updateMagicString(code, src, ast, callback) {
|
|
270
|
+
await formatSpecifiers(src, ast, callback, code);
|
|
271
|
+
return code;
|
|
267
272
|
}
|
|
268
273
|
};
|
package/dist/cjs/specifier.d.cts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import MagicString from 'magic-string';
|
|
2
|
+
import type { ParserOptions, ParseResult, StringLiteral, TemplateLiteral, BinaryExpression, NewExpression, ImportDeclaration, ExportNamedDeclaration, ExportAllDeclaration, TSImportType, ImportExpression, CallExpression } from 'oxc-parser';
|
|
2
3
|
type Spec = {
|
|
3
4
|
type: 'StringLiteral' | 'TemplateLiteral' | 'BinaryExpression' | 'NewExpression';
|
|
4
5
|
node: StringLiteral | TemplateLiteral | BinaryExpression | NewExpression;
|
|
@@ -11,6 +12,7 @@ type Callback = (spec: Spec) => string | void;
|
|
|
11
12
|
declare const specifier: {
|
|
12
13
|
update(path: string, callback: Callback): Promise<string>;
|
|
13
14
|
updateSrc(src: string, lang: ParserOptions["lang"], callback: Callback): Promise<string>;
|
|
15
|
+
updateMagicString(code: MagicString, src: string, ast: ParseResult, callback: Callback): Promise<MagicString>;
|
|
14
16
|
};
|
|
15
17
|
export { specifier };
|
|
16
18
|
export type { Spec, Callback };
|
package/dist/cjs/types.d.cts
CHANGED
|
@@ -6,6 +6,8 @@ export type ModuleOptions = {
|
|
|
6
6
|
target: 'module' | 'commonjs';
|
|
7
7
|
/** Explicit source type; auto infers from file extension. */
|
|
8
8
|
sourceType?: 'auto' | 'module' | 'commonjs';
|
|
9
|
+
/** Emit a source map alongside the transformed code. */
|
|
10
|
+
sourceMap?: boolean;
|
|
9
11
|
/**
|
|
10
12
|
* Enable syntax transforms beyond parsing.
|
|
11
13
|
* - true: full CJS↔ESM lowering/raising
|
package/dist/cli.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { stdin as defaultStdin, stdout as defaultStdout, stderr as defaultStderr } from 'node:process';
|
|
3
3
|
import { parseArgs } from 'node:util';
|
|
4
|
-
import { readFile, mkdir } from 'node:fs/promises';
|
|
5
|
-
import { dirname, resolve, relative, join } from 'node:path';
|
|
4
|
+
import { readFile, mkdir, writeFile } from 'node:fs/promises';
|
|
5
|
+
import { dirname, resolve, relative, join, basename } from 'node:path';
|
|
6
6
|
import { glob } from 'glob';
|
|
7
7
|
import { transform, collectProjectDualPackageHazards } from './module.js';
|
|
8
8
|
import { parse } from './parse.js';
|
|
@@ -32,6 +32,7 @@ const defaultOptions = {
|
|
|
32
32
|
idiomaticExports: 'safe',
|
|
33
33
|
importMetaPrelude: 'auto',
|
|
34
34
|
topLevelAwait: 'error',
|
|
35
|
+
sourceMap: false,
|
|
35
36
|
cwd: undefined,
|
|
36
37
|
out: undefined,
|
|
37
38
|
inPlace: false
|
|
@@ -177,6 +178,11 @@ const optionsTable = [{
|
|
|
177
178
|
short: 'm',
|
|
178
179
|
type: 'string',
|
|
179
180
|
desc: 'Emit import.meta prelude (off|auto|on)'
|
|
181
|
+
}, {
|
|
182
|
+
long: 'source-map',
|
|
183
|
+
short: undefined,
|
|
184
|
+
type: 'boolean',
|
|
185
|
+
desc: 'Emit a source map alongside transformed output (use --source-map=inline for stdout)'
|
|
180
186
|
}, {
|
|
181
187
|
long: 'nested-require-strategy',
|
|
182
188
|
short: 'n',
|
|
@@ -299,6 +305,7 @@ const toModuleOptions = values => {
|
|
|
299
305
|
nestedRequireStrategy: parseEnum(values['nested-require-strategy'], ['create-require', 'dynamic-import']) ?? defaultOptions.nestedRequireStrategy,
|
|
300
306
|
requireMainStrategy: parseEnum(values['require-main-strategy'], ['import-meta-main', 'realpath']) ?? defaultOptions.requireMainStrategy,
|
|
301
307
|
liveBindings: parseEnum(values['live-bindings'], ['strict', 'loose', 'off']) ?? defaultOptions.liveBindings,
|
|
308
|
+
sourceMap: Boolean(values['source-map']),
|
|
302
309
|
cwd: values.cwd ? resolve(String(values.cwd)) : defaultOptions.cwd
|
|
303
310
|
};
|
|
304
311
|
return opts;
|
|
@@ -310,6 +317,55 @@ const readStdin = async stdin => {
|
|
|
310
317
|
}
|
|
311
318
|
return Buffer.concat(chunks).toString('utf8');
|
|
312
319
|
};
|
|
320
|
+
const normalizeSourceMapArgv = argv => {
|
|
321
|
+
let sourceMapInline = false;
|
|
322
|
+
let invalidSourceMapValue = null;
|
|
323
|
+
const normalized = [];
|
|
324
|
+
const recordInvalid = value => {
|
|
325
|
+
if (!invalidSourceMapValue) invalidSourceMapValue = value;
|
|
326
|
+
};
|
|
327
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
328
|
+
const arg = argv[i];
|
|
329
|
+
if (arg === '--source-map') {
|
|
330
|
+
const next = argv[i + 1];
|
|
331
|
+
if (next === 'inline') {
|
|
332
|
+
sourceMapInline = true;
|
|
333
|
+
normalized.push('--source-map');
|
|
334
|
+
i += 1;
|
|
335
|
+
continue;
|
|
336
|
+
}
|
|
337
|
+
if (next === 'true' || next === 'false') {
|
|
338
|
+
normalized.push(`--source-map=${next}`);
|
|
339
|
+
i += 1;
|
|
340
|
+
continue;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
if (arg.startsWith('--source-map=')) {
|
|
344
|
+
const value = arg.slice('--source-map='.length);
|
|
345
|
+
if (value === 'inline') {
|
|
346
|
+
sourceMapInline = true;
|
|
347
|
+
normalized.push('--source-map');
|
|
348
|
+
continue;
|
|
349
|
+
}
|
|
350
|
+
if (value === 'true' || value === 'false') {
|
|
351
|
+
normalized.push(arg);
|
|
352
|
+
continue;
|
|
353
|
+
}
|
|
354
|
+
recordInvalid(value);
|
|
355
|
+
continue;
|
|
356
|
+
}
|
|
357
|
+
if (arg === '--source-map' && argv[i + 1] && argv[i + 1].startsWith('--')) {
|
|
358
|
+
normalized.push('--source-map');
|
|
359
|
+
continue;
|
|
360
|
+
}
|
|
361
|
+
normalized.push(arg);
|
|
362
|
+
}
|
|
363
|
+
return {
|
|
364
|
+
argv: normalized,
|
|
365
|
+
sourceMapInline,
|
|
366
|
+
invalidSourceMapValue
|
|
367
|
+
};
|
|
368
|
+
};
|
|
313
369
|
const expandFiles = async (patterns, cwd, ignore) => {
|
|
314
370
|
const files = new Set();
|
|
315
371
|
for (const pattern of patterns) {
|
|
@@ -397,8 +453,10 @@ const runFiles = async (files, moduleOpts, io, flags) => {
|
|
|
397
453
|
filePath: file,
|
|
398
454
|
detectDualPackageHazard: hazardScope === 'project' ? 'off' : moduleOpts.detectDualPackageHazard
|
|
399
455
|
};
|
|
456
|
+
const allowWrites = !flags.dryRun && !flags.list;
|
|
457
|
+
const writeInPlace = allowWrites && flags.inPlace;
|
|
400
458
|
let writeTarget;
|
|
401
|
-
if (
|
|
459
|
+
if (allowWrites) {
|
|
402
460
|
if (flags.inPlace) {
|
|
403
461
|
perFileOpts.inPlace = true;
|
|
404
462
|
} else if (outPath) {
|
|
@@ -415,8 +473,15 @@ const runFiles = async (files, moduleOpts, io, flags) => {
|
|
|
415
473
|
};
|
|
416
474
|
}
|
|
417
475
|
}
|
|
418
|
-
|
|
476
|
+
if (moduleOpts.sourceMap && (writeTarget || writeInPlace)) {
|
|
477
|
+
perFileOpts.out = undefined;
|
|
478
|
+
perFileOpts.inPlace = false;
|
|
479
|
+
}
|
|
480
|
+
const transformed = await transform(file, perFileOpts);
|
|
481
|
+
const output = typeof transformed === 'string' ? transformed : transformed.code;
|
|
482
|
+
const map = typeof transformed === 'string' ? null : transformed.map;
|
|
419
483
|
const changed = output !== original;
|
|
484
|
+
let finalOutput = output;
|
|
420
485
|
if (projectHazards) {
|
|
421
486
|
const extras = projectHazards.get(file);
|
|
422
487
|
if (extras?.length) diagnostics.push(...extras);
|
|
@@ -424,8 +489,24 @@ const runFiles = async (files, moduleOpts, io, flags) => {
|
|
|
424
489
|
if (flags.list && changed) {
|
|
425
490
|
logger.info(file);
|
|
426
491
|
}
|
|
427
|
-
if (
|
|
428
|
-
|
|
492
|
+
if (map && flags.sourceMapInline && !writeTarget && !writeInPlace) {
|
|
493
|
+
const mapUri = Buffer.from(JSON.stringify(map)).toString('base64');
|
|
494
|
+
finalOutput = `${output.replace(/\/\/# sourceMappingURL=.*/g, '').trimEnd()}\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,${mapUri}\n`;
|
|
495
|
+
} else if (map && (writeTarget || writeInPlace)) {
|
|
496
|
+
const target = writeTarget ?? file;
|
|
497
|
+
const mapPath = `${target}.map`;
|
|
498
|
+
const mapFile = basename(mapPath);
|
|
499
|
+
map.file = basename(target);
|
|
500
|
+
const updated = `${output.replace(/\/\/# sourceMappingURL=.*/g, '').trimEnd()}\n//# sourceMappingURL=${mapFile}\n`;
|
|
501
|
+
await writeFile(mapPath, JSON.stringify(map));
|
|
502
|
+
if (writeTarget) {
|
|
503
|
+
await writeFile(writeTarget, updated);
|
|
504
|
+
} else if (writeInPlace) {
|
|
505
|
+
await writeFile(file, updated);
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
if (!flags.dryRun && !flags.list && !writeTarget && !writeInPlace) {
|
|
509
|
+
io.stdout.write(finalOutput);
|
|
429
510
|
}
|
|
430
511
|
results.push({
|
|
431
512
|
filePath: file,
|
|
@@ -462,11 +543,21 @@ const runCli = async ({
|
|
|
462
543
|
stdout = defaultStdout,
|
|
463
544
|
stderr = defaultStderr
|
|
464
545
|
} = {}) => {
|
|
546
|
+
const logger = makeLogger(stdout, stderr);
|
|
547
|
+
const {
|
|
548
|
+
argv: normalizedArgv,
|
|
549
|
+
sourceMapInline,
|
|
550
|
+
invalidSourceMapValue
|
|
551
|
+
} = normalizeSourceMapArgv(argv);
|
|
552
|
+
if (invalidSourceMapValue) {
|
|
553
|
+
logger.error(`Invalid --source-map value: ${invalidSourceMapValue}`);
|
|
554
|
+
return 2;
|
|
555
|
+
}
|
|
465
556
|
const {
|
|
466
557
|
values,
|
|
467
558
|
positionals
|
|
468
559
|
} = parseArgs({
|
|
469
|
-
args:
|
|
560
|
+
args: normalizedArgv,
|
|
470
561
|
allowPositionals: true,
|
|
471
562
|
options: Object.fromEntries(optionsTable.map(opt => [opt.long, {
|
|
472
563
|
type: opt.type,
|
|
@@ -475,7 +566,6 @@ const runCli = async ({
|
|
|
475
566
|
} : {})
|
|
476
567
|
}]))
|
|
477
568
|
});
|
|
478
|
-
const logger = makeLogger(stdout, stderr);
|
|
479
569
|
if (values.help) {
|
|
480
570
|
stdout.write(buildHelp(stdout.isTTY ?? false));
|
|
481
571
|
return 0;
|
|
@@ -486,6 +576,7 @@ const runCli = async ({
|
|
|
486
576
|
return 0;
|
|
487
577
|
}
|
|
488
578
|
const moduleOpts = toModuleOptions(values);
|
|
579
|
+
if (sourceMapInline) moduleOpts.sourceMap = true;
|
|
489
580
|
const cwd = moduleOpts.cwd ?? process.cwd();
|
|
490
581
|
const allowStdout = positionals.length <= 1;
|
|
491
582
|
const fromStdin = positionals.length === 0 || positionals.includes('-');
|
|
@@ -498,6 +589,10 @@ const runCli = async ({
|
|
|
498
589
|
const list = Boolean(values.list);
|
|
499
590
|
const summary = Boolean(values.summary);
|
|
500
591
|
const json = Boolean(values.json);
|
|
592
|
+
if (sourceMapInline && (outDir || inPlace)) {
|
|
593
|
+
logger.error('Inline source maps are only supported when writing to stdout');
|
|
594
|
+
return 2;
|
|
595
|
+
}
|
|
501
596
|
if (outDir && inPlace) {
|
|
502
597
|
logger.error('Choose either --out-dir or --in-place, not both');
|
|
503
598
|
return 2;
|
|
@@ -552,7 +647,8 @@ const runCli = async ({
|
|
|
552
647
|
json,
|
|
553
648
|
outDir,
|
|
554
649
|
inPlace,
|
|
555
|
-
allowStdout
|
|
650
|
+
allowStdout,
|
|
651
|
+
sourceMapInline
|
|
556
652
|
});
|
|
557
653
|
if (typeof result.code === 'number' && result.code !== 0) return result.code;
|
|
558
654
|
tasks.push(...result.results);
|
package/dist/format.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Node, ParseResult } from 'oxc-parser';
|
|
2
|
+
import MagicString from 'magic-string';
|
|
2
3
|
import type { Diagnostic, FormatterOptions } from './types.js';
|
|
3
4
|
type HazardLevel = 'warning' | 'error';
|
|
4
5
|
export type PackageUse = {
|
|
@@ -22,10 +23,8 @@ declare const dualPackageHazardDiagnostics: (params: {
|
|
|
22
23
|
cwd?: string;
|
|
23
24
|
manifestCache?: Map<string, any | null>;
|
|
24
25
|
}) => Promise<Diagnostic[]>;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
*/
|
|
30
|
-
declare const format: (src: string, ast: ParseResult, opts: FormatterOptions) => Promise<string>;
|
|
26
|
+
declare function format(src: string, ast: ParseResult, opts: FormatterOptions & {
|
|
27
|
+
sourceMap: true;
|
|
28
|
+
}): Promise<MagicString>;
|
|
29
|
+
declare function format(src: string, ast: ParseResult, opts: FormatterOptions): Promise<string>;
|
|
31
30
|
export { format, collectDualPackageUsage, dualPackageHazardDiagnostics };
|
package/dist/format.js
CHANGED
|
@@ -282,13 +282,7 @@ const detectDualPackageHazards = async params => {
|
|
|
282
282
|
diagOnce(diag.level, diag.code, diag.message, diag.loc);
|
|
283
283
|
}
|
|
284
284
|
};
|
|
285
|
-
|
|
286
|
-
/**
|
|
287
|
-
* Node added support for import.meta.main.
|
|
288
|
-
* Added in: v24.2.0, v22.18.0
|
|
289
|
-
* @see https://nodejs.org/api/esm.html#importmetamain
|
|
290
|
-
*/
|
|
291
|
-
const format = async (src, ast, opts) => {
|
|
285
|
+
async function format(src, ast, opts) {
|
|
292
286
|
const code = new MagicString(src);
|
|
293
287
|
const exportsMeta = {
|
|
294
288
|
hasExportsBeenReassigned: false,
|
|
@@ -513,15 +507,16 @@ const format = async (src, ast, opts) => {
|
|
|
513
507
|
code.prepend(prelude);
|
|
514
508
|
}
|
|
515
509
|
if (opts.target === 'commonjs' && fullTransform && containsTopLevelAwait) {
|
|
516
|
-
const body = code.toString();
|
|
517
510
|
if (opts.topLevelAwait === 'wrap') {
|
|
518
|
-
const
|
|
519
|
-
|
|
520
|
-
const
|
|
521
|
-
|
|
511
|
+
code.prepend('const __tla = (async () => {\n');
|
|
512
|
+
code.append('\nreturn module.exports;\n})();\n');
|
|
513
|
+
code.append('const __setTla = target => {\n if (!target) return;\n const type = typeof target;\n if (type !== "object" && type !== "function") return;\n target.__tla = __tla;\n};\n');
|
|
514
|
+
code.append('__setTla(module.exports);\n__tla.then(resolved => __setTla(resolved), err => { throw err; });\n');
|
|
515
|
+
} else {
|
|
516
|
+
code.prepend(';(async () => {\n');
|
|
517
|
+
code.append('\n})();\n');
|
|
522
518
|
}
|
|
523
|
-
return `;(async () => {\n${body}\n})();\n`;
|
|
524
519
|
}
|
|
525
|
-
return code.toString();
|
|
526
|
-
}
|
|
520
|
+
return opts.sourceMap ? code : code.toString();
|
|
521
|
+
}
|
|
527
522
|
export { format, collectDualPackageUsage, dualPackageHazardDiagnostics };
|
package/dist/module.d.ts
CHANGED
|
@@ -1,4 +1,17 @@
|
|
|
1
1
|
import type { ModuleOptions, Diagnostic } from './types.js';
|
|
2
|
+
import type { SourceMap } from 'magic-string';
|
|
2
3
|
declare const collectProjectDualPackageHazards: (files: string[], opts: ModuleOptions) => Promise<Map<string, Diagnostic[]>>;
|
|
3
|
-
declare
|
|
4
|
+
declare function transform(filename: string, options: ModuleOptions & {
|
|
5
|
+
sourceMap: true;
|
|
6
|
+
}): Promise<{
|
|
7
|
+
code: string;
|
|
8
|
+
map: SourceMap;
|
|
9
|
+
}>;
|
|
10
|
+
declare function transform(filename: string, options?: ModuleOptions & {
|
|
11
|
+
sourceMap?: false | undefined;
|
|
12
|
+
}): Promise<string>;
|
|
13
|
+
declare function transform(filename: string, options?: ModuleOptions): Promise<string | {
|
|
14
|
+
code: string;
|
|
15
|
+
map: SourceMap;
|
|
16
|
+
}>;
|
|
4
17
|
export { transform, collectProjectDualPackageHazards };
|
package/dist/module.js
CHANGED
|
@@ -201,11 +201,12 @@ const createDefaultOptions = () => ({
|
|
|
201
201
|
idiomaticExports: 'safe',
|
|
202
202
|
importMetaPrelude: 'auto',
|
|
203
203
|
topLevelAwait: 'error',
|
|
204
|
+
sourceMap: false,
|
|
204
205
|
cwd: undefined,
|
|
205
206
|
out: undefined,
|
|
206
207
|
inPlace: false
|
|
207
208
|
});
|
|
208
|
-
|
|
209
|
+
async function transform(filename, options) {
|
|
209
210
|
const base = createDefaultOptions();
|
|
210
211
|
const opts = options ? {
|
|
211
212
|
...base,
|
|
@@ -222,9 +223,19 @@ const transform = async (filename, options) => {
|
|
|
222
223
|
const file = resolve(cwdBase, filename);
|
|
223
224
|
const code = (await readFile(file)).toString();
|
|
224
225
|
const ast = parse(filename, code);
|
|
225
|
-
let
|
|
226
|
+
let sourceCode = null;
|
|
227
|
+
let source;
|
|
228
|
+
if (opts.sourceMap) {
|
|
229
|
+
sourceCode = await format(code, ast, {
|
|
230
|
+
...opts,
|
|
231
|
+
sourceMap: true
|
|
232
|
+
});
|
|
233
|
+
source = sourceCode.toString();
|
|
234
|
+
} else {
|
|
235
|
+
source = await format(code, ast, opts);
|
|
236
|
+
}
|
|
226
237
|
if (opts.rewriteSpecifier || appendMode !== 'off' || dirIndex) {
|
|
227
|
-
const
|
|
238
|
+
const applyRewrite = spec => {
|
|
228
239
|
if (spec.type === 'TemplateLiteral' && opts.rewriteTemplateLiterals === 'static-only') {
|
|
229
240
|
const node = spec.node;
|
|
230
241
|
if (node.expressions.length > 0) return;
|
|
@@ -234,8 +245,14 @@ const transform = async (filename, options) => {
|
|
|
234
245
|
const baseValue = rewritten ?? normalized ?? spec.value;
|
|
235
246
|
const appended = appendExtensionIfNeeded(spec, appendMode, dirIndex, baseValue);
|
|
236
247
|
return appended ?? rewritten ?? normalized ?? undefined;
|
|
237
|
-
}
|
|
238
|
-
|
|
248
|
+
};
|
|
249
|
+
if (opts.sourceMap && sourceCode) {
|
|
250
|
+
await specifier.updateMagicString(sourceCode, code, ast, applyRewrite);
|
|
251
|
+
source = sourceCode.toString();
|
|
252
|
+
} else {
|
|
253
|
+
const rewritten = await specifier.updateSrc(source, getLangFromExt(filename), applyRewrite);
|
|
254
|
+
source = rewritten;
|
|
255
|
+
}
|
|
239
256
|
}
|
|
240
257
|
if (detectCycles !== 'off' && opts.target === 'module' && opts.transformSyntax) {
|
|
241
258
|
await detectCircularRequireGraph(file, detectCycles, dirIndex || 'index.js');
|
|
@@ -244,6 +261,18 @@ const transform = async (filename, options) => {
|
|
|
244
261
|
if (outputPath) {
|
|
245
262
|
await writeFile(outputPath, source);
|
|
246
263
|
}
|
|
264
|
+
if (opts.sourceMap && sourceCode) {
|
|
265
|
+
const map = sourceCode.generateMap({
|
|
266
|
+
hires: true,
|
|
267
|
+
includeContent: true,
|
|
268
|
+
file: outputPath ?? filename,
|
|
269
|
+
source: opts.filePath ?? filename
|
|
270
|
+
});
|
|
271
|
+
return {
|
|
272
|
+
code: source,
|
|
273
|
+
map
|
|
274
|
+
};
|
|
275
|
+
}
|
|
247
276
|
return source;
|
|
248
|
-
}
|
|
277
|
+
}
|
|
249
278
|
export { transform, collectProjectDualPackageHazards };
|
package/dist/specifier.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import MagicString from 'magic-string';
|
|
2
|
+
import type { ParserOptions, ParseResult, StringLiteral, TemplateLiteral, BinaryExpression, NewExpression, ImportDeclaration, ExportNamedDeclaration, ExportAllDeclaration, TSImportType, ImportExpression, CallExpression } from 'oxc-parser';
|
|
2
3
|
type Spec = {
|
|
3
4
|
type: 'StringLiteral' | 'TemplateLiteral' | 'BinaryExpression' | 'NewExpression';
|
|
4
5
|
node: StringLiteral | TemplateLiteral | BinaryExpression | NewExpression;
|
|
@@ -11,6 +12,7 @@ type Callback = (spec: Spec) => string | void;
|
|
|
11
12
|
declare const specifier: {
|
|
12
13
|
update(path: string, callback: Callback): Promise<string>;
|
|
13
14
|
updateSrc(src: string, lang: ParserOptions["lang"], callback: Callback): Promise<string>;
|
|
15
|
+
updateMagicString(code: MagicString, src: string, ast: ParseResult, callback: Callback): Promise<MagicString>;
|
|
14
16
|
};
|
|
15
17
|
export { specifier };
|
|
16
18
|
export type { Spec, Callback };
|
package/dist/specifier.js
CHANGED
|
@@ -13,8 +13,7 @@ const isBinaryExpression = node => {
|
|
|
13
13
|
const isCallExpression = node => {
|
|
14
14
|
return node.type === 'CallExpression' && node.callee !== undefined;
|
|
15
15
|
};
|
|
16
|
-
const formatSpecifiers = async (src, ast, cb) => {
|
|
17
|
-
const code = new MagicString(src);
|
|
16
|
+
const formatSpecifiers = async (src, ast, cb, code = new MagicString(src)) => {
|
|
18
17
|
const formatExpression = expression => {
|
|
19
18
|
const node = isCallExpression(expression) ? expression.arguments[0] : expression.source;
|
|
20
19
|
const {
|
|
@@ -228,7 +227,7 @@ const formatSpecifiers = async (src, ast, cb) => {
|
|
|
228
227
|
}
|
|
229
228
|
}
|
|
230
229
|
});
|
|
231
|
-
return code
|
|
230
|
+
return code;
|
|
232
231
|
};
|
|
233
232
|
const isValidFilename = async filename => {
|
|
234
233
|
let stats;
|
|
@@ -251,12 +250,18 @@ const specifier = {
|
|
|
251
250
|
}
|
|
252
251
|
const src = (await readFile(filename)).toString();
|
|
253
252
|
const ast = parseSync(filename, src);
|
|
254
|
-
|
|
253
|
+
const code = await formatSpecifiers(src, ast, callback);
|
|
254
|
+
return code.toString();
|
|
255
255
|
},
|
|
256
256
|
async updateSrc(src, lang, callback) {
|
|
257
257
|
const filename = lang === 'ts' ? 'file.ts' : lang === 'tsx' ? 'file.tsx' : lang === 'js' ? 'file.js' : 'file.jsx';
|
|
258
258
|
const ast = parseSync(filename, src);
|
|
259
|
-
|
|
259
|
+
const code = await formatSpecifiers(src, ast, callback);
|
|
260
|
+
return code.toString();
|
|
261
|
+
},
|
|
262
|
+
async updateMagicString(code, src, ast, callback) {
|
|
263
|
+
await formatSpecifiers(src, ast, callback, code);
|
|
264
|
+
return code;
|
|
260
265
|
}
|
|
261
266
|
};
|
|
262
267
|
export { specifier };
|
package/dist/types.d.ts
CHANGED
|
@@ -6,6 +6,8 @@ export type ModuleOptions = {
|
|
|
6
6
|
target: 'module' | 'commonjs';
|
|
7
7
|
/** Explicit source type; auto infers from file extension. */
|
|
8
8
|
sourceType?: 'auto' | 'module' | 'commonjs';
|
|
9
|
+
/** Emit a source map alongside the transformed code. */
|
|
10
|
+
sourceMap?: boolean;
|
|
9
11
|
/**
|
|
10
12
|
* Enable syntax transforms beyond parsing.
|
|
11
13
|
* - true: full CJS↔ESM lowering/raising
|