@bytecodealliance/jco 1.24.1 → 1.24.3

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 (42) hide show
  1. package/package.json +4 -7
  2. package/src/api.js +9 -61
  3. package/src/cmd/componentize.js +2 -7
  4. package/src/cmd/opt.js +5 -7
  5. package/src/cmd/run.js +2 -2
  6. package/src/cmd/transpile.js +36 -604
  7. package/src/cmd/types.js +18 -9
  8. package/src/cmd/wasm-tools.js +17 -24
  9. package/src/jco.js +3 -3
  10. package/types/api.d.ts +1 -31
  11. package/types/api.d.ts.map +1 -1
  12. package/types/cmd/componentize.d.ts.map +1 -1
  13. package/types/cmd/opt.d.ts.map +1 -1
  14. package/types/cmd/transpile.d.ts +25 -15
  15. package/types/cmd/transpile.d.ts.map +1 -1
  16. package/types/cmd/types.d.ts.map +1 -1
  17. package/types/cmd/wasm-tools.d.ts.map +1 -1
  18. package/obj/interfaces/local-wasm-tools-tools.d.ts +0 -79
  19. package/obj/interfaces/wasi-cli-environment.d.ts +0 -2
  20. package/obj/interfaces/wasi-cli-exit.d.ts +0 -3
  21. package/obj/interfaces/wasi-cli-stderr.d.ts +0 -3
  22. package/obj/interfaces/wasi-cli-stdin.d.ts +0 -3
  23. package/obj/interfaces/wasi-cli-stdout.d.ts +0 -3
  24. package/obj/interfaces/wasi-cli-terminal-input.d.ts +0 -8
  25. package/obj/interfaces/wasi-cli-terminal-output.d.ts +0 -8
  26. package/obj/interfaces/wasi-cli-terminal-stderr.d.ts +0 -3
  27. package/obj/interfaces/wasi-cli-terminal-stdin.d.ts +0 -3
  28. package/obj/interfaces/wasi-cli-terminal-stdout.d.ts +0 -3
  29. package/obj/interfaces/wasi-clocks-wall-clock.d.ts +0 -5
  30. package/obj/interfaces/wasi-filesystem-preopens.d.ts +0 -3
  31. package/obj/interfaces/wasi-filesystem-types.d.ts +0 -165
  32. package/obj/interfaces/wasi-io-error.d.ts +0 -8
  33. package/obj/interfaces/wasi-io-streams.d.ts +0 -30
  34. package/obj/interfaces/wasi-random-random.d.ts +0 -2
  35. package/obj/js-component-bindgen-component.core.wasm +0 -0
  36. package/obj/js-component-bindgen-component.core2.wasm +0 -0
  37. package/obj/js-component-bindgen-component.d.ts +0 -120
  38. package/obj/js-component-bindgen-component.js +0 -13637
  39. package/obj/wasm-tools.core.wasm +0 -0
  40. package/obj/wasm-tools.core2.wasm +0 -0
  41. package/obj/wasm-tools.d.ts +0 -20
  42. package/obj/wasm-tools.js +0 -14389
@@ -1,100 +1,14 @@
1
1
  /* global Buffer */
2
2
 
3
- import { extname, basename, resolve } from "node:path";
4
- import { fileURLToPath } from "node:url";
3
+ import { transpile, transpileBytes } from "@bytecodealliance/jco-transpile";
5
4
 
6
- import { minify } from "terser";
7
-
8
- import { optimizeComponent } from "./opt.js";
9
-
10
- import { $init, generate } from "../../obj/js-component-bindgen-component.js";
11
- import {
12
- readFile,
13
- spawnIOTmp,
14
- setShowSpinner,
15
- getShowSpinner,
16
- writeFiles,
17
- styleText,
18
- ASYNC_WASI_IMPORTS,
19
- ASYNC_WASI_EXPORTS,
20
- DEFAULT_ASYNC_MODE,
21
- } from "../common.js";
22
- import { $init as wasmToolsInit, tools } from "../../obj/wasm-tools.js";
23
- const { componentEmbed, componentNew } = tools;
24
-
25
- import ora from "#ora";
26
-
27
- import { isWindows } from "../common.js";
5
+ import { setShowSpinner, writeFiles } from "../common.js";
28
6
 
29
7
  // These re-exports exist to avoid breaking backwards compatibility
30
8
  export { types, guestTypes, typesComponent } from "./types.js";
31
9
 
32
- const SUPPORTED_P3_VERSIONS = ["0.3.0-rc-2026-03-15", "0.3.0"];
33
-
34
- export async function transpile(witPath, opts, program) {
35
- const varIdx = program?.parent.rawArgs.indexOf("--");
36
- if (varIdx !== undefined && varIdx !== -1) {
37
- opts.optArgs = program.parent.rawArgs.slice(varIdx + 1);
38
- }
39
-
40
- let component;
41
- if (!opts.stub) {
42
- component = await readFile(witPath);
43
- } else {
44
- await wasmToolsInit;
45
- component = componentNew(
46
- componentEmbed({
47
- dummy: true,
48
- witPath: (isWindows ? "//?/" : "") + resolve(witPath),
49
- }),
50
- [],
51
- );
52
- }
53
-
54
- if (!opts.quiet) {
55
- setShowSpinner(true);
56
- }
57
- if (!opts.name) {
58
- opts.name = basename(witPath.slice(0, -extname(witPath).length || Infinity));
59
- }
60
- if (opts.map) {
61
- opts.map = Object.fromEntries(opts.map.map((mapping) => mapping.split("=")));
62
- }
63
-
64
- if (opts.asyncWasiImports) {
65
- opts.asyncImports = ASYNC_WASI_IMPORTS.concat(opts.asyncImports || []);
66
- }
67
- if (opts.asyncWasiExports) {
68
- opts.asyncExports = ASYNC_WASI_EXPORTS.concat(opts.asyncExports || []);
69
- }
70
-
71
- const { files } = await transpileComponent(component, opts);
72
- await writeFiles(files, opts.quiet ? false : "Transpiled JS Component Files");
73
- }
74
-
75
10
  /**
76
- * @param {Uint8Array} source
77
- * @returns {Promise<Uint8Array>}
78
- */
79
- async function wasm2Js(source) {
80
- const wasm2jsPath = fileURLToPath(import.meta.resolve("binaryen/bin/wasm2js"));
81
-
82
- try {
83
- return await spawnIOTmp(wasm2jsPath, source, ["-Oz", "-o"]);
84
- } catch (e) {
85
- if (e.toString().includes("BasicBlock requested")) {
86
- return wasm2Js(source);
87
- }
88
- throw e;
89
- }
90
- }
91
-
92
- /**
93
- * Execute the bundled pre-transpiled component that can perform component transpilation,
94
- * for the given component.
95
- *
96
- * @param {Uint8Array} component
97
- * @param {{
11
+ * @typedef {{
98
12
  * name: string,
99
13
  * instantiation?: 'async' | 'sync',
100
14
  * importBindings?: 'js' | 'optimized' | 'hybrid' | 'direct-optimized',
@@ -116,534 +30,52 @@ async function wasm2Js(source) {
116
30
  * experimentalIdlImports?: bool,
117
31
  * optArgs?: string[],
118
32
  * wasmOptBin?: string[],
119
- * }} opts
120
- * @returns {Promise<{ files: { [filename: string]: Uint8Array }, imports: string[], exports: [string, 'function' | 'instance'][] }>}
33
+ * }} TranspileOpts
121
34
  */
122
- export async function transpileComponent(component, opts = {}) {
123
- await $init;
124
- if (opts.instantiation) {
125
- opts.wasiShim = false;
126
- }
127
-
128
- let spinner;
129
- const showSpinner = getShowSpinner();
130
-
131
- if (opts.optimize) {
132
- if (showSpinner) {
133
- setShowSpinner(true);
134
- }
135
- ({ component } = await optimizeComponent(component, opts));
136
- }
137
-
138
- if (opts.wasiShim !== false) {
139
- const shims = {
140
- "wasi:cli/*": "@bytecodealliance/preview2-shim/cli#*",
141
- "wasi:clocks/*": "@bytecodealliance/preview2-shim/clocks#*",
142
- "wasi:filesystem/*": "@bytecodealliance/preview2-shim/filesystem#*",
143
- "wasi:http/*": "@bytecodealliance/preview2-shim/http#*",
144
- "wasi:io/*": "@bytecodealliance/preview2-shim/io#*",
145
- "wasi:random/*": "@bytecodealliance/preview2-shim/random#*",
146
- "wasi:sockets/*": "@bytecodealliance/preview2-shim/sockets#*",
147
- };
148
-
149
- // To avoid breaking compatibility with earlier version of p3 (including draft versions),
150
- // we over-populate the map with references to the *current* preview3-shim that has been
151
- // imported.
152
- //
153
- // This implicitly upgrades versions of P3 in use (a component that asks for 0.3.0 will get 0.3.1 if that
154
- // is the current version in preview3-shim0, but that should be acceptable as p3 should not have breaking
155
- // changes going forward.
156
- //
157
- for (const version of SUPPORTED_P3_VERSIONS) {
158
- Object.assign(shims, {
159
- [`wasi:cli/*@${version}`]: "@bytecodealliance/preview3-shim/cli#*",
160
- [`wasi:clocks/*@${version}`]: "@bytecodealliance/preview3-shim/clocks#*",
161
- [`wasi:filesystem/*@${version}`]: "@bytecodealliance/preview3-shim/filesystem#*",
162
- [`wasi:http/*@${version}`]: "@bytecodealliance/preview3-shim/http#*",
163
- [`wasi:random/*@${version}`]: "@bytecodealliance/preview3-shim/random#*",
164
- [`wasi:sockets/*@${version}`]: "@bytecodealliance/preview3-shim/sockets#*",
165
- });
166
- }
167
-
168
- opts.map = Object.assign(shims, opts.map || {});
169
- }
170
-
171
- let instantiation = null;
172
-
173
- // Let's define `instantiation` from `--instantiation` if it's present.
174
- if (opts.instantiation) {
175
- instantiation = { tag: opts.instantiation };
176
- } else if (opts.js) {
177
- // Otherwise, if `--js` is present, an `instantiate` function is required.
178
- instantiation = { tag: "async" };
179
- }
180
-
181
- // Get the configured async mode then transform it into what the types component expects
182
- // Build list of async imports/exports
183
- let asyncImports = new Set([...(opts.asyncImports ?? [])]);
184
- let asyncExports = new Set([...(opts.asyncExports ?? [])]);
185
- let asyncMode = opts.asyncMode ?? DEFAULT_ASYNC_MODE;
186
- if (asyncMode === "sync" && asyncExports.size > 0) {
187
- throw new Error("async exports cannot be specified in sync mode (consider adding --async-mode=jspi)");
188
- }
189
- if (asyncMode === "sync" && asyncImports.size > 0) {
190
- throw new Error("async imports cannot be specified in sync mode (consider adding --async-mode=jspi)");
191
- }
192
- let asyncModeObj;
193
- if (asyncMode === "sync") {
194
- asyncModeObj = null;
195
- } else if (asyncMode === "jspi") {
196
- asyncModeObj = {
197
- tag: "jspi",
198
- val: {
199
- imports: [...asyncImports],
200
- exports: [...asyncExports],
201
- },
202
- };
203
- } else {
204
- throw new Error(`invalid/unrecognized async mode [${asyncMode}]`);
205
- }
206
-
207
- let { files, imports, exports } = generate(component, {
208
- name: opts.name ?? "component",
209
- map: Object.entries(opts.map ?? {}),
210
- instantiation,
211
- asyncMode: asyncModeObj,
212
- importBindings: opts.importBindings ? { tag: opts.importBindings } : null,
213
- validLiftingOptimization: opts.validLiftingOptimization ?? false,
214
- tracing: opts.tracing ?? false,
215
- noNodejsCompat: opts.nodejsCompat === false,
216
- noTypescript: opts.typescript === false,
217
- tlaCompat: opts.tlaCompat ?? false,
218
- base64Cutoff: opts.js ? 0 : (opts.base64Cutoff ?? 5000),
219
- noNamespacedExports: opts.namespacedExports === false,
220
- multiMemory: opts.multiMemory === true,
221
- idlImports: opts.experimentalIdlImports === true,
222
- strict: opts.strict === true,
223
- asmjs: opts.js === true,
224
- });
225
-
226
- let outDir = (opts.outDir ?? "").replace(/\\/g, "/");
227
- if (!outDir.endsWith("/") && outDir !== "") {
228
- outDir += "/";
229
- }
230
- files = files.map(([name, source]) => [`${outDir}${name}`, source]);
231
-
232
- const jsFile = files.find(([name]) => name.endsWith(".js"));
233
-
234
- // Generate code for the `--js` option.
235
- //
236
- // `--js` can be called with or without `--instantiation`. The generated code
237
- // isn't exactly the same!
238
- //
239
- // `--js` needs an `instantiate` function to work, so it might look like
240
- // `--instantiation` is always implied, but actually no. It is correct
241
- // that when `--js` is present, an `instantiate` function _is_ generated,
242
- // but it doesn't mean that we expect the function to be used, it's simply
243
- // not exported, plus `instantiate` is automatically called (if `--tla-compat`
244
- // is `false`). When `--instantiation` is missing, functions are exported
245
- // with the `export` directive, and imports are imported with the `import`
246
- // directive. When `--instantiation` is present, there is no `export` and no
247
- // `import`: only a single exported `instantiate` function.
248
- //
249
- // Basically, we get this:
250
- //
251
- // * `--js` only:
252
- // * `instantiate` is renamed to `_instantiate`,
253
- // * A new `instantiate` function is created, that calls `_instantiate` with
254
- // the correct imports (which are ASM.js code) and returns the exports,
255
- // * A new `$init` function is created, that calls `instantiate` and maps
256
- // the returned exports to their respective trampolines,
257
- // * Trampolines are exported,
258
- // * `$init` is called automatically.
259
- //
260
- // * `--js` with `--tla-compat`:
261
- // * Same as with `--js` only, except that `$init` is exported instead of
262
- // being called immediately.
263
- //
264
- // * `--js` with `--instantiation[=async]`:
265
- // * `instantiate` is renamed to `_instantiate`,
266
- // * A new `instantiate` function is created, that calls `_instantiate` with
267
- // the correct imports (which are ASM.js code) and returns the exports,
268
- // * `instantiate` is exported.
269
- //
270
- // * `--js` with `--instantiation=sync`:
271
- // * Same as `--js` with `--instantiation[=async]`, except that
272
- // `_instantiate` and `instantiate` are non-async.
273
- //
274
- // Be careful with the variables: `opts.instantiation` reflects the presence
275
- // or the absence of the `--instantiation` flag, whilst `instantiation`
276
- // reflects how the `instantiate` function must be generated. We also use
277
- // `instantiation` to know whether the generated code must be async or
278
- // non-async.
279
- if (opts.js) {
280
- const withInstantiation = opts.instantiation !== undefined;
281
- const async_ = instantiation.tag == "async" ? "async " : "";
282
- const await_ = instantiation.tag == "async" ? "await " : "";
283
-
284
- // Format the previously generated code.
285
- const source = Buffer.from(jsFile[1])
286
- .toString("utf8")
287
- // update imports manging to match emscripten asm
288
- .replace(/exports(\d+)\['([^']+)']/g, (_, i, s) => `exports${i}['${asmMangle(s)}']`)
289
- .replace(/export (async )?function instantiate/, "$1function _instantiate");
290
-
291
- // Collect all Wasm files.
292
- const wasmFiles = files.filter(([name]) => name.endsWith(".wasm"));
293
- files = files.filter(([name]) => !name.endsWith(".wasm"));
294
-
295
- // Configure the spinner.
296
- let completed = 0;
297
- const spinnerText = () =>
298
- `${styleText("cyan", `${completed} / ${wasmFiles.length}`)} Running Binaryen wasm2js on Wasm core modules (this takes a while)...\n`;
299
- if (showSpinner) {
300
- spinner = ora({
301
- color: "cyan",
302
- spinner: "bouncingBar",
303
- }).start();
304
- spinner.text = spinnerText();
305
- }
306
-
307
- // Compile all Wasm modules into ASM.js codes.
308
- try {
309
- const asmFiles = await Promise.all(
310
- wasmFiles.map(async ([, source]) => {
311
- const output = (await wasm2Js(source)).toString("utf8");
312
- if (spinner) {
313
- completed++;
314
- spinner.text = spinnerText();
315
- }
316
- return output;
317
- }),
318
- );
319
-
320
- const asms = asmFiles
321
- .map(
322
- (asm, nth) => `function asm${nth}(imports) {
323
- ${
324
- // strip and replace the asm instantiation wrapper
325
- asm
326
- .replace(/import \* as [^ ]+ from '[^']*';/g, "")
327
- .replace("function asmFunc(imports) {", "")
328
- .replace(/export var ([^ ]+) = ([^. ]+)\.([^ ]+);/g, "")
329
- .replace(/var retasmFunc = [\s\S]*$/, "")
330
- .replace(/var memasmFunc = new ArrayBuffer\(0\);/g, "")
331
- .replace("memory.grow = __wasm_memory_grow;", "")
332
- .trim()
333
- }`,
334
- )
335
- .join(",\n");
336
-
337
- // The `instantiate` function.
338
- const instantiateFunction = `${withInstantiation ? "export " : ""}${async_}function instantiate(imports) {
339
- const wasm_file_to_asm_index = {
340
- ${wasmFiles.map(([path], nth) => `'${basename(path)}': ${nth}`).join(",\n ")}
341
- };
342
-
343
- return ${await_}_instantiate(
344
- module_name => wasm_file_to_asm_index[module_name],
345
- imports,
346
- (module_index, imports) => ({ exports: asmInit[module_index](imports) })
347
- );
348
- }`;
349
-
350
- // If `--js` is used without `--instantiation`.
351
- let importDirectives = "";
352
- let exportDirectives = "";
353
- let exportTrampolines = "";
354
- let autoInstantiate = "";
355
-
356
- if (!withInstantiation) {
357
- importDirectives = imports
358
- .map((import_file, nth) => `import * as import${nth} from '${import_file}';`)
359
- .join("\n");
360
-
361
- if (exports.length > 0 || opts.tlaCompat) {
362
- exportDirectives = `export {
363
- ${
364
- // Exporting `$init` must come first to not break the transpiling tests.
365
- opts.tlaCompat ? " $init,\n" : ""
366
- }${exports
367
- .map(([name]) => {
368
- if (name === asmMangle(name)) {
369
- return ` ${name},`;
370
- } else {
371
- return ` ${asmMangle(name)} as '${name}',`;
372
- }
373
- })
374
- .join("\n")}
375
- }`;
376
- }
377
35
 
378
- exportTrampolines = `let ${exports
379
- .filter(([, ty]) => ty === "function")
380
- .map(([name]) => `_${asmMangle(name)}`)
381
- .join(", ")};
382
- ${exports
383
- .map(([name, ty]) => {
384
- if (ty === "function") {
385
- return `\nfunction ${asmMangle(name)} () {
386
- return _${asmMangle(name)}.apply(this, arguments);
387
- }`;
388
- } else {
389
- return `\nlet ${asmMangle(name)};`;
390
- }
391
- })
392
- .join("\n")}`;
393
-
394
- autoInstantiate = `${async_}function $init() {
395
- ( {
396
- ${exports
397
- .map(([name, ty]) => {
398
- if (ty === "function") {
399
- return ` '${name}': _${asmMangle(name)},`;
400
- } else if (asmMangle(name) === name) {
401
- return ` ${name},`;
402
- } else {
403
- return ` '${name}': ${asmMangle(name)},`;
404
- }
405
- })
406
- .join("\n")}
407
- } = ${await_}instantiate(
408
- {
409
- ${imports.map((import_file, nth) => ` '${import_file}': import${nth},`).join("\n")}
410
- }
411
- ) )
36
+ /**
37
+ * Transpile a component, given a path.
38
+ *
39
+ * @param {string} componentPath
40
+ * @param {TranspileOpts} opts
41
+ * @param {object} comander `Program` object
42
+ */
43
+ export async function transpileCmd(componentPath, opts, program) {
44
+ const { files } = await transpile(componentPath, prepOpts(opts, program));
45
+ await writeFiles(files, opts.quiet ? false : "Transpiled JS Component Files");
412
46
  }
413
47
 
414
- ${opts.tlaCompat ? "" : `${await_}$init();`}`;
415
- }
416
-
417
- // Prepare the final generated code.
418
- const outSource = `${importDirectives}
419
-
420
- ${source}
421
-
422
- const asmInit = [${asms}];
423
-
424
- ${exportTrampolines}
425
-
426
- ${instantiateFunction}
427
-
428
- ${exportDirectives}
429
-
430
- ${autoInstantiate}`;
431
-
432
- // Save the final generated code.
433
- jsFile[1] = Buffer.from(outSource);
434
- } finally {
435
- if (spinner) {
436
- spinner.stop();
437
- }
438
- }
439
- }
440
-
441
- if (opts.minify) {
442
- try {
443
- ({ code: jsFile[1] } = await minify(Buffer.from(jsFile[1]).toString("utf8"), {
444
- module: true,
445
- compress: {
446
- ecma: 9,
447
- unsafe: true,
448
- },
449
- mangle: {
450
- keep_classnames: true,
451
- },
452
- }));
453
- } catch (err) {
454
- console.error(`error while minifying JS: ${err}`);
455
- throw err;
456
- }
457
- }
458
-
459
- return { files: Object.fromEntries(files), imports, exports };
48
+ /**
49
+ * Transpile a component, given WebAssembly bytes.
50
+ *
51
+ * @param {Uint8Array} component
52
+ * @param {TranspileOpts} [opts]
53
+ * @returns {Promise<{ files: { [filename: string]: Uint8Array }, imports: string[], exports: [string, 'function' | 'instance'][] }>}
54
+ */
55
+ export async function transpileComponent(component, opts = {}) {
56
+ return transpileBytes(component, prepOpts(opts));
460
57
  }
461
58
 
462
- // emscripten asm mangles specifiers to be valid identifiers
463
- // for imports to match up we must do the same
464
- // See https://github.com/WebAssembly/binaryen/blob/main/src/asmjs/asmangle.cpp
465
- function asmMangle(name) {
466
- if (name === "") {
467
- return "$";
59
+ function prepOpts(opts, program) {
60
+ const varIdx = program?.parent.rawArgs.indexOf("--");
61
+ if (varIdx !== undefined && varIdx !== -1) {
62
+ opts.optArgs = program.parent.rawArgs.slice(varIdx + 1);
468
63
  }
469
64
 
470
- let mightBeKeyword = true;
471
- let i = 1;
472
-
473
- // Names must start with a character, $ or _
474
- switch (name[0]) {
475
- case "0":
476
- case "1":
477
- case "2":
478
- case "3":
479
- case "4":
480
- case "5":
481
- case "6":
482
- case "7":
483
- case "8":
484
- case "9": {
485
- name = "$" + name;
486
- i = 2;
487
- // fallthrough
488
- }
489
- case "$":
490
- case "_": {
491
- mightBeKeyword = false;
492
- break;
493
- }
494
- default: {
495
- let chNum = name.charCodeAt(0);
496
- if (!(chNum >= 97 && chNum <= 122) && !(chNum >= 65 && chNum <= 90)) {
497
- name = "$" + name.substr(1);
498
- mightBeKeyword = false;
499
- }
500
- }
65
+ if (!opts.quiet) {
66
+ setShowSpinner(true);
501
67
  }
502
68
 
503
- // Names must contain only characters, digits, $ or _
504
- let len = name.length;
505
- for (; i < len; ++i) {
506
- switch (name[i]) {
507
- case "0":
508
- case "1":
509
- case "2":
510
- case "3":
511
- case "4":
512
- case "5":
513
- case "6":
514
- case "7":
515
- case "8":
516
- case "9":
517
- case "$":
518
- case "_": {
519
- mightBeKeyword = false;
520
- break;
521
- }
522
- default: {
523
- let chNum = name.charCodeAt(i);
524
- if (!(chNum >= 97 && chNum <= 122) && !(chNum >= 65 && chNum <= 90)) {
525
- name = name.substr(0, i) + "_" + name.substr(i + 1);
526
- mightBeKeyword = false;
527
- }
528
- }
69
+ if (opts.map) {
70
+ if (typeof opts.map === "string") {
71
+ opts.map = opts.map.split(",");
529
72
  }
530
- }
531
-
532
- // Names must not collide with keywords
533
- if (mightBeKeyword && len >= 2 && len <= 10) {
534
- switch (name[0]) {
535
- case "a": {
536
- if (name == "arguments") {
537
- return name + "_";
538
- }
539
- break;
540
- }
541
- case "b": {
542
- if (name == "break") {
543
- return name + "_";
544
- }
545
- break;
546
- }
547
- case "c": {
548
- if (name == "case" || name == "continue" || name == "catch" || name == "const" || name == "class") {
549
- return name + "_";
550
- }
551
- break;
552
- }
553
- case "d": {
554
- if (name == "do" || name == "default" || name == "debugger") {
555
- return name + "_";
556
- }
557
- break;
558
- }
559
- case "e": {
560
- if (
561
- name == "else" ||
562
- name == "enum" ||
563
- name == "eval" || // to be sure
564
- name == "export" ||
565
- name == "extends"
566
- ) {
567
- return name + "_";
568
- }
569
- break;
570
- }
571
- case "f": {
572
- if (name == "for" || name == "false" || name == "finally" || name == "function") {
573
- return name + "_";
574
- }
575
- break;
576
- }
577
- case "i": {
578
- if (
579
- name == "if" ||
580
- name == "in" ||
581
- name == "import" ||
582
- name == "interface" ||
583
- name == "implements" ||
584
- name == "instanceof"
585
- ) {
586
- return name + "_";
587
- }
588
- break;
589
- }
590
- case "l": {
591
- if (name == "let") {
592
- return name + "_";
593
- }
594
- break;
595
- }
596
- case "n": {
597
- if (name == "new" || name == "null") {
598
- return name + "_";
599
- }
600
- break;
601
- }
602
- case "p": {
603
- if (name == "public" || name == "package" || name == "private" || name == "protected") {
604
- return name + "_";
605
- }
606
- break;
607
- }
608
- case "r": {
609
- if (name == "return") {
610
- return name + "_";
611
- }
612
- break;
613
- }
614
- case "s": {
615
- if (name == "super" || name == "static" || name == "switch") {
616
- return name + "_";
617
- }
618
- break;
619
- }
620
- case "t": {
621
- if (name == "try" || name == "this" || name == "true" || name == "throw" || name == "typeof") {
622
- return name + "_";
623
- }
624
- break;
625
- }
626
- case "v": {
627
- if (name == "var" || name == "void") {
628
- return name + "_";
629
- }
630
- break;
631
- }
632
- case "w": {
633
- if (name == "with" || name == "while") {
634
- return name + "_";
635
- }
636
- break;
637
- }
638
- case "y": {
639
- if (name == "yield") {
640
- return name + "_";
641
- }
642
- break;
643
- }
73
+ if (Array.isArray(opts.map)) {
74
+ opts.map = Object.fromEntries(opts.map.map((s) => s.split("=")));
644
75
  }
645
76
  }
646
- return name;
77
+
78
+ return opts;
647
79
  }
648
80
 
649
81
  // see: https://github.com/vitest-dev/vitest/issues/6953#issuecomment-2505310022