@autter/runtime-cli 1.0.0 → 1.1.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 +13 -7
- package/dist/{build-BXFh_jbP.d.cts → build-CPXR9Xd3.d.cts} +27 -8
- package/dist/{build-BXFh_jbP.d.ts → build-CPXR9Xd3.d.ts} +27 -8
- package/dist/chunk-DQLLM2NT.js +1035 -0
- package/dist/{chunk-GGHHEUPQ.js → chunk-I2743JCN.js} +26 -8
- package/dist/cli.js +468 -59
- package/dist/index.cjs +547 -49
- package/dist/index.d.cts +57 -2
- package/dist/index.d.ts +57 -2
- package/dist/index.js +9 -1
- package/dist/next.cjs +634 -97
- package/dist/next.d.cts +3 -2
- package/dist/next.d.ts +3 -2
- package/dist/next.js +27 -8
- package/dist/vite.cjs +611 -88
- package/dist/vite.d.cts +3 -2
- package/dist/vite.d.ts +3 -2
- package/dist/vite.js +32 -6
- package/dist/webpack.cjs +604 -88
- package/dist/webpack.d.cts +11 -4
- package/dist/webpack.d.ts +11 -4
- package/dist/webpack.js +2 -2
- package/package.json +5 -1
- package/dist/chunk-SIRFO2QU.js +0 -524
package/dist/cli.js
CHANGED
|
@@ -2,47 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
// src/cli.ts
|
|
4
4
|
import { spawnSync } from "child_process";
|
|
5
|
-
import { existsSync as
|
|
5
|
+
import { existsSync as existsSync3, readFileSync } from "fs";
|
|
6
6
|
import { createRequire } from "module";
|
|
7
7
|
import { dirname as dirname2, join as join2, resolve as resolve2 } from "path";
|
|
8
8
|
import { parseArgs } from "util";
|
|
9
9
|
|
|
10
|
-
// src/
|
|
11
|
-
import {
|
|
12
|
-
|
|
13
|
-
// src/debug-id.ts
|
|
14
|
-
import { createHash } from "crypto";
|
|
15
|
-
var DEBUG_ID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
|
|
16
|
-
function normalizeDebugId(value) {
|
|
17
|
-
if (typeof value !== "string") return null;
|
|
18
|
-
const id = value.trim().toLowerCase();
|
|
19
|
-
return DEBUG_ID_RE.test(id) ? id : null;
|
|
20
|
-
}
|
|
21
|
-
function debugIdFor(bytes) {
|
|
22
|
-
const hash = createHash("sha256").update(bytes).digest();
|
|
23
|
-
hash[6] = hash[6] & 15 | 64;
|
|
24
|
-
hash[8] = hash[8] & 63 | 128;
|
|
25
|
-
const hex = hash.subarray(0, 16).toString("hex");
|
|
26
|
-
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20, 32)}`;
|
|
27
|
-
}
|
|
28
|
-
var DEBUG_ID_COMMENT_RE = /^\/\/# debugId=([0-9a-fA-F-]{36})[ \t]*\r?$/gm;
|
|
29
|
-
function readDebugIdComment(code) {
|
|
30
|
-
let found = null;
|
|
31
|
-
for (const match of code.matchAll(DEBUG_ID_COMMENT_RE)) found = normalizeDebugId(match[1]) ?? found;
|
|
32
|
-
return found;
|
|
33
|
-
}
|
|
34
|
-
var DEBUG_ID_REGISTRY = "_autterDebugIds";
|
|
35
|
-
function debugIdSnippet(id) {
|
|
36
|
-
return `;!function(){try{var g="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof self?self:{},s=(new g.Error).stack;s&&((g.${DEBUG_ID_REGISTRY}=g.${DEBUG_ID_REGISTRY}||{})[s]="${id}")}catch(e){}}();`;
|
|
37
|
-
}
|
|
38
|
-
var SNIPPET_RE = /\(g\._autterDebugIds=g\._autterDebugIds\|\|\{\}\)\[s\]="[0-9a-f]{8}-/;
|
|
39
|
-
function hasDebugIdSnippet(code) {
|
|
40
|
-
return SNIPPET_RE.test(code);
|
|
41
|
-
}
|
|
10
|
+
// src/build.ts
|
|
11
|
+
import { existsSync as existsSync2 } from "fs";
|
|
12
|
+
import { relative as relative2, sep as sep2 } from "path";
|
|
42
13
|
|
|
43
14
|
// src/files.ts
|
|
44
15
|
import { existsSync } from "fs";
|
|
45
|
-
import { readdir, readFile } from "fs/promises";
|
|
16
|
+
import { readdir, readFile, rm, writeFile } from "fs/promises";
|
|
46
17
|
import { dirname, join, relative, resolve, sep } from "path";
|
|
47
18
|
var BUNDLE_RE = /\.[cm]?js$/;
|
|
48
19
|
var SOURCE_MAPPING_URL_RE = /^[ \t]*\/\/[#@] sourceMappingURL=([^\s'"]+)[ \t]*\r?$/gm;
|
|
@@ -78,7 +49,7 @@ function mapPathFor(js, code) {
|
|
|
78
49
|
const sibling = `${js}.map`;
|
|
79
50
|
return existsSync(sibling) ? sibling : null;
|
|
80
51
|
}
|
|
81
|
-
async function walk(dir, out) {
|
|
52
|
+
async function walk(dir, out, pattern = BUNDLE_RE) {
|
|
82
53
|
let entries;
|
|
83
54
|
try {
|
|
84
55
|
entries = await readdir(dir, { withFileTypes: true });
|
|
@@ -88,8 +59,8 @@ async function walk(dir, out) {
|
|
|
88
59
|
for (const entry of entries) {
|
|
89
60
|
if (entry.name === "node_modules") continue;
|
|
90
61
|
const full = join(dir, entry.name);
|
|
91
|
-
if (entry.isDirectory()) await walk(full, out);
|
|
92
|
-
else if (entry.isFile() &&
|
|
62
|
+
if (entry.isDirectory()) await walk(full, out, pattern);
|
|
63
|
+
else if (entry.isFile() && pattern.test(entry.name)) out.push(full);
|
|
93
64
|
}
|
|
94
65
|
}
|
|
95
66
|
async function findBundles(dir, files) {
|
|
@@ -114,6 +85,39 @@ async function findBundles(dir, files) {
|
|
|
114
85
|
return bundles;
|
|
115
86
|
}
|
|
116
87
|
|
|
88
|
+
// src/inject.ts
|
|
89
|
+
import { readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
|
|
90
|
+
|
|
91
|
+
// src/debug-id.ts
|
|
92
|
+
import { createHash } from "crypto";
|
|
93
|
+
var DEBUG_ID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
|
|
94
|
+
function normalizeDebugId(value) {
|
|
95
|
+
if (typeof value !== "string") return null;
|
|
96
|
+
const id = value.trim().toLowerCase();
|
|
97
|
+
return DEBUG_ID_RE.test(id) ? id : null;
|
|
98
|
+
}
|
|
99
|
+
function debugIdFor(bytes) {
|
|
100
|
+
const hash = createHash("sha256").update(bytes).digest();
|
|
101
|
+
hash[6] = hash[6] & 15 | 64;
|
|
102
|
+
hash[8] = hash[8] & 63 | 128;
|
|
103
|
+
const hex = hash.subarray(0, 16).toString("hex");
|
|
104
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20, 32)}`;
|
|
105
|
+
}
|
|
106
|
+
var DEBUG_ID_COMMENT_RE = /^\/\/# debugId=([0-9a-fA-F-]{36})[ \t]*\r?$/gm;
|
|
107
|
+
function readDebugIdComment(code) {
|
|
108
|
+
let found = null;
|
|
109
|
+
for (const match of code.matchAll(DEBUG_ID_COMMENT_RE)) found = normalizeDebugId(match[1]) ?? found;
|
|
110
|
+
return found;
|
|
111
|
+
}
|
|
112
|
+
var DEBUG_ID_REGISTRY = "_autterDebugIds";
|
|
113
|
+
function debugIdSnippet(id) {
|
|
114
|
+
return `;!function(){try{var g="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof self?self:{},s=(new g.Error).stack;s&&((g.${DEBUG_ID_REGISTRY}=g.${DEBUG_ID_REGISTRY}||{})[s]="${id}")}catch(e){}}();`;
|
|
115
|
+
}
|
|
116
|
+
var SNIPPET_RE = /\(g\._autterDebugIds=g\._autterDebugIds\|\|\{\}\)\[s\]="[0-9a-f]{8}-/;
|
|
117
|
+
function hasDebugIdSnippet(code) {
|
|
118
|
+
return SNIPPET_RE.test(code);
|
|
119
|
+
}
|
|
120
|
+
|
|
117
121
|
// src/inject.ts
|
|
118
122
|
var SNIPPET_LINE_KEY = "x_autter_snippet_line";
|
|
119
123
|
function snippetLine(code) {
|
|
@@ -202,8 +206,8 @@ ${out.slice(offset)}`;
|
|
|
202
206
|
}
|
|
203
207
|
const changed = mapDirty || out !== code;
|
|
204
208
|
if (changed && !options.dryRun) {
|
|
205
|
-
if (mapDirty) await
|
|
206
|
-
if (out !== code) await
|
|
209
|
+
if (mapDirty) await writeFile2(bundle.map, JSON.stringify(map));
|
|
210
|
+
if (out !== code) await writeFile2(bundle.js, out);
|
|
207
211
|
}
|
|
208
212
|
return { ...base, debugId, status: changed ? "injected" : "unchanged" };
|
|
209
213
|
}
|
|
@@ -215,7 +219,9 @@ async function injectDir(dir, options = {}) {
|
|
|
215
219
|
|
|
216
220
|
// src/upload.ts
|
|
217
221
|
import { createHash as createHash2 } from "crypto";
|
|
218
|
-
import { readFile as readFile3, rm, writeFile as
|
|
222
|
+
import { readFile as readFile3, rm as rm2, writeFile as writeFile3 } from "fs/promises";
|
|
223
|
+
import { promisify } from "util";
|
|
224
|
+
import { gzip as gzipCallback } from "zlib";
|
|
219
225
|
|
|
220
226
|
// src/release.ts
|
|
221
227
|
import { execFileSync } from "child_process";
|
|
@@ -261,9 +267,382 @@ function resolveRelease(explicit, env = process.env, cwd = process.cwd()) {
|
|
|
261
267
|
);
|
|
262
268
|
}
|
|
263
269
|
|
|
270
|
+
// src/scopes.ts
|
|
271
|
+
import { parse } from "acorn";
|
|
272
|
+
var SCOPES_KEY = "x_autter_scopes";
|
|
273
|
+
var SCOPES_VERSION = 1;
|
|
274
|
+
var BASE_OPTIONS = {
|
|
275
|
+
ecmaVersion: "latest",
|
|
276
|
+
allowHashBang: true,
|
|
277
|
+
allowReturnOutsideFunction: true,
|
|
278
|
+
allowReserved: true
|
|
279
|
+
};
|
|
280
|
+
function parseBundle(code) {
|
|
281
|
+
try {
|
|
282
|
+
return parse(code, {
|
|
283
|
+
...BASE_OPTIONS,
|
|
284
|
+
sourceType: "module",
|
|
285
|
+
allowAwaitOutsideFunction: true,
|
|
286
|
+
allowImportExportEverywhere: true
|
|
287
|
+
});
|
|
288
|
+
} catch (moduleError) {
|
|
289
|
+
try {
|
|
290
|
+
return parse(code, { ...BASE_OPTIONS, sourceType: "script" });
|
|
291
|
+
} catch (scriptError) {
|
|
292
|
+
const pos = (err) => typeof err.pos === "number" ? err.pos : -1;
|
|
293
|
+
throw pos(scriptError) > pos(moduleError) ? scriptError : moduleError;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
function isNode(value) {
|
|
298
|
+
return typeof value === "object" && value !== null && typeof value.type === "string";
|
|
299
|
+
}
|
|
300
|
+
var IDENTIFIER_NAME_RE = /^[$_\p{ID_Start}][$\u200c\u200d\p{ID_Continue}]*$/u;
|
|
301
|
+
function identifierToken(node) {
|
|
302
|
+
if (!isNode(node)) return null;
|
|
303
|
+
if (node.type === "Identifier") return { offset: node.start, name: node.name, literal: false };
|
|
304
|
+
if (node.type === "PrivateIdentifier") return { offset: node.start, name: `#${node.name}`, literal: false };
|
|
305
|
+
return null;
|
|
306
|
+
}
|
|
307
|
+
function literalToken(node) {
|
|
308
|
+
if (!isNode(node) || node.type !== "Literal" || typeof node.value !== "string") return null;
|
|
309
|
+
return IDENTIFIER_NAME_RE.test(node.value) ? { offset: node.start, name: node.value, literal: true } : null;
|
|
310
|
+
}
|
|
311
|
+
function keyToken(property) {
|
|
312
|
+
if (!property.computed) {
|
|
313
|
+
const id = identifierToken(property.key);
|
|
314
|
+
if (id) return id;
|
|
315
|
+
}
|
|
316
|
+
return literalToken(property.key);
|
|
317
|
+
}
|
|
318
|
+
function bindingToken(target) {
|
|
319
|
+
if (!isNode(target)) return null;
|
|
320
|
+
if (target.type === "Identifier") return identifierToken(target);
|
|
321
|
+
if (target.type === "MemberExpression") {
|
|
322
|
+
return target.computed ? literalToken(target.property) : identifierToken(target.property);
|
|
323
|
+
}
|
|
324
|
+
return null;
|
|
325
|
+
}
|
|
326
|
+
function contextTokens(node, parent) {
|
|
327
|
+
let token = null;
|
|
328
|
+
switch (parent?.type) {
|
|
329
|
+
case "VariableDeclarator":
|
|
330
|
+
if (parent.init === node) token = bindingToken(parent.id);
|
|
331
|
+
break;
|
|
332
|
+
case "AssignmentExpression":
|
|
333
|
+
case "AssignmentPattern":
|
|
334
|
+
if (parent.right === node) token = bindingToken(parent.left);
|
|
335
|
+
break;
|
|
336
|
+
case "Property":
|
|
337
|
+
case "PropertyDefinition":
|
|
338
|
+
case "MethodDefinition":
|
|
339
|
+
if (parent.value === node) token = keyToken(parent);
|
|
340
|
+
break;
|
|
341
|
+
}
|
|
342
|
+
return token ? [token] : [];
|
|
343
|
+
}
|
|
344
|
+
function classTokens(path) {
|
|
345
|
+
if (!path || path.node.type !== "ClassDeclaration" && path.node.type !== "ClassExpression") return [];
|
|
346
|
+
const own = identifierToken(path.node.id);
|
|
347
|
+
return [...own ? [own] : [], ...contextTokens(path.node, path.parent?.node)];
|
|
348
|
+
}
|
|
349
|
+
function describe(path) {
|
|
350
|
+
const fn = path.node;
|
|
351
|
+
const parent = path.parent?.node;
|
|
352
|
+
const own = identifierToken(fn.id);
|
|
353
|
+
const isMethod = parent?.type === "MethodDefinition" || parent?.type === "Property" && parent.value === fn && (parent.method === true || parent.kind !== "init");
|
|
354
|
+
let context;
|
|
355
|
+
if (parent?.type === "MethodDefinition" && parent.kind === "constructor") {
|
|
356
|
+
context = classTokens(path.parent?.parent?.parent ?? null);
|
|
357
|
+
} else {
|
|
358
|
+
context = contextTokens(fn, parent);
|
|
359
|
+
}
|
|
360
|
+
return {
|
|
361
|
+
start: fn.start,
|
|
362
|
+
end: fn.end,
|
|
363
|
+
own,
|
|
364
|
+
recoverAt: !own && fn.type !== "ArrowFunctionExpression" && !isMethod ? fn.start : null,
|
|
365
|
+
context
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
var FUNCTION_TYPES = /* @__PURE__ */ new Set(["FunctionDeclaration", "FunctionExpression", "ArrowFunctionExpression"]);
|
|
369
|
+
function classInitializer(path) {
|
|
370
|
+
const node = path.node;
|
|
371
|
+
let range = null;
|
|
372
|
+
if (node.type === "StaticBlock") range = node;
|
|
373
|
+
else if (node.type === "PropertyDefinition" && isNode(node.value) && !FUNCTION_TYPES.has(node.value.type)) range = node.value;
|
|
374
|
+
if (!range) return null;
|
|
375
|
+
return { start: range.start, end: range.end, own: null, recoverAt: null, context: classTokens(path.parent?.parent ?? null) };
|
|
376
|
+
}
|
|
377
|
+
function collectFunctions(program) {
|
|
378
|
+
const found = [];
|
|
379
|
+
const stack = [{ node: program, parent: null }];
|
|
380
|
+
for (let path = stack.pop(); path; path = stack.pop()) {
|
|
381
|
+
const node = path.node;
|
|
382
|
+
if (FUNCTION_TYPES.has(node.type)) found.push(describe(path));
|
|
383
|
+
else {
|
|
384
|
+
const initializer = classInitializer(path);
|
|
385
|
+
if (initializer) found.push(initializer);
|
|
386
|
+
}
|
|
387
|
+
for (const key in node) {
|
|
388
|
+
const value = node[key];
|
|
389
|
+
if (Array.isArray(value)) {
|
|
390
|
+
for (let i = value.length - 1; i >= 0; i--) if (isNode(value[i])) stack.push({ node: value[i], parent: path });
|
|
391
|
+
} else if (isNode(value)) {
|
|
392
|
+
stack.push({ node: value, parent: path });
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
return found;
|
|
397
|
+
}
|
|
398
|
+
function lineStarts(code) {
|
|
399
|
+
const starts = [0];
|
|
400
|
+
for (let i = 0; i < code.length; i++) {
|
|
401
|
+
const c = code.charCodeAt(i);
|
|
402
|
+
if (c === 10 || c === 8232 || c === 8233) starts.push(i + 1);
|
|
403
|
+
else if (c === 13) {
|
|
404
|
+
if (code.charCodeAt(i + 1) === 10) i++;
|
|
405
|
+
starts.push(i + 1);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
return starts;
|
|
409
|
+
}
|
|
410
|
+
function positionOf(starts, offset) {
|
|
411
|
+
let lo = 0;
|
|
412
|
+
let hi = starts.length - 1;
|
|
413
|
+
while (lo < hi) {
|
|
414
|
+
const mid = lo + hi + 1 >> 1;
|
|
415
|
+
if (starts[mid] <= offset) lo = mid;
|
|
416
|
+
else hi = mid - 1;
|
|
417
|
+
}
|
|
418
|
+
return [lo, offset - starts[lo]];
|
|
419
|
+
}
|
|
420
|
+
var BASE64 = new Int8Array(128).fill(-1);
|
|
421
|
+
for (const [i, ch] of [..."ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"].entries()) BASE64[ch.charCodeAt(0)] = i;
|
|
422
|
+
function findSegments(mappings, wanted) {
|
|
423
|
+
let line = 0;
|
|
424
|
+
let column = 0;
|
|
425
|
+
let source = 0;
|
|
426
|
+
let originalLine = 0;
|
|
427
|
+
let originalColumn = 0;
|
|
428
|
+
let name = 0;
|
|
429
|
+
let want = wanted.get(0);
|
|
430
|
+
const fields = [0, 0, 0, 0, 0];
|
|
431
|
+
let i = 0;
|
|
432
|
+
while (i < mappings.length) {
|
|
433
|
+
const ch = mappings.charCodeAt(i);
|
|
434
|
+
if (ch === 59) {
|
|
435
|
+
line++;
|
|
436
|
+
column = 0;
|
|
437
|
+
want = wanted.get(line);
|
|
438
|
+
i++;
|
|
439
|
+
continue;
|
|
440
|
+
}
|
|
441
|
+
if (ch === 44) {
|
|
442
|
+
i++;
|
|
443
|
+
continue;
|
|
444
|
+
}
|
|
445
|
+
let count = 0;
|
|
446
|
+
while (i < mappings.length) {
|
|
447
|
+
const next = mappings.charCodeAt(i);
|
|
448
|
+
if (next === 44 || next === 59) break;
|
|
449
|
+
let value = 0;
|
|
450
|
+
let shift = 0;
|
|
451
|
+
let digit;
|
|
452
|
+
do {
|
|
453
|
+
const code = mappings.charCodeAt(i++);
|
|
454
|
+
digit = code < 128 ? BASE64[code] : -1;
|
|
455
|
+
if (digit < 0 || shift > 30) throw new Error("invalid mappings");
|
|
456
|
+
value |= (digit & 31) << shift;
|
|
457
|
+
shift += 5;
|
|
458
|
+
} while (digit & 32);
|
|
459
|
+
const decoded = value & 1 ? -(value >>> 1) : value >>> 1;
|
|
460
|
+
if (count < 5) fields[count] = decoded;
|
|
461
|
+
count++;
|
|
462
|
+
}
|
|
463
|
+
column += fields[0];
|
|
464
|
+
if (count >= 4) {
|
|
465
|
+
source += fields[1];
|
|
466
|
+
originalLine += fields[2];
|
|
467
|
+
originalColumn += fields[3];
|
|
468
|
+
}
|
|
469
|
+
if (count >= 5) name += fields[4];
|
|
470
|
+
if (want && want.get(column) === null) {
|
|
471
|
+
want.set(column, {
|
|
472
|
+
source: count >= 4 ? source : -1,
|
|
473
|
+
line: originalLine,
|
|
474
|
+
column: originalColumn,
|
|
475
|
+
name: count >= 5 ? name : -1
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
function looksMangled(name) {
|
|
481
|
+
return name.replace(/^#/, "").length <= 2;
|
|
482
|
+
}
|
|
483
|
+
var IDENTIFIER_AT_RE = /[$_\p{ID_Start}][$\u200c\u200d\p{ID_Continue}]*/uy;
|
|
484
|
+
var OWN_NAME_AT_RE = /(?:async\s+)?function\b\s*\*?\s*([$_\p{ID_Start}][$\u200c\u200d\p{ID_Continue}]*)/uy;
|
|
485
|
+
var NOT_A_NAME = new Set(
|
|
486
|
+
"abstract async await break case catch class const continue debugger declare default delete do else enum export extends false finally for function get if implements import in instanceof interface let new null of override package private protected public readonly return set static super switch this throw true try typeof var void while with yield".split(" ")
|
|
487
|
+
);
|
|
488
|
+
var NameResolver = class {
|
|
489
|
+
constructor(map, segmentAt) {
|
|
490
|
+
this.segmentAt = segmentAt;
|
|
491
|
+
this.names = Array.isArray(map.names) ? map.names : [];
|
|
492
|
+
this.sourcesContent = Array.isArray(map.sourcesContent) ? map.sourcesContent : [];
|
|
493
|
+
}
|
|
494
|
+
segmentAt;
|
|
495
|
+
names;
|
|
496
|
+
sourcesContent;
|
|
497
|
+
sourceLines = /* @__PURE__ */ new Map();
|
|
498
|
+
originalLine(segment) {
|
|
499
|
+
if (segment.source < 0) return null;
|
|
500
|
+
let lines = this.sourceLines.get(segment.source);
|
|
501
|
+
if (lines === void 0) {
|
|
502
|
+
const content = this.sourcesContent[segment.source];
|
|
503
|
+
lines = typeof content === "string" ? content.split(/\r\n|[\n\r\u2028\u2029]/) : null;
|
|
504
|
+
this.sourceLines.set(segment.source, lines);
|
|
505
|
+
}
|
|
506
|
+
return lines?.[segment.line] ?? null;
|
|
507
|
+
}
|
|
508
|
+
/** The original identifier at a segment's source position. */
|
|
509
|
+
identifierAt(segment, re, group = 0) {
|
|
510
|
+
const text = this.originalLine(segment);
|
|
511
|
+
if (text === null) return null;
|
|
512
|
+
re.lastIndex = segment.column;
|
|
513
|
+
const found = re.exec(text)?.[group];
|
|
514
|
+
return found && !NOT_A_NAME.has(found) ? found : null;
|
|
515
|
+
}
|
|
516
|
+
/** Original name of a token: the map's `names` at its exact position;
|
|
517
|
+
* else the generated name when it isn't mangled; else the identifier
|
|
518
|
+
* at the mapped position in `sourcesContent`. Null when unknown. */
|
|
519
|
+
resolve(token) {
|
|
520
|
+
if (token.literal) return token.name;
|
|
521
|
+
const segment = this.segmentAt(token.offset);
|
|
522
|
+
if (segment && segment.name >= 0) {
|
|
523
|
+
const name = this.names[segment.name];
|
|
524
|
+
if (typeof name === "string" && name) return name;
|
|
525
|
+
}
|
|
526
|
+
if (!looksMangled(token.name)) return token.name;
|
|
527
|
+
return segment ? this.identifierAt(segment, IDENTIFIER_AT_RE) : null;
|
|
528
|
+
}
|
|
529
|
+
/** The name a minifier removed from `function name() {}`, read from the
|
|
530
|
+
* original source at the function's mapped start. */
|
|
531
|
+
recover(offset) {
|
|
532
|
+
const segment = this.segmentAt(offset);
|
|
533
|
+
return segment ? this.identifierAt(segment, OWN_NAME_AT_RE, 1) : null;
|
|
534
|
+
}
|
|
535
|
+
};
|
|
536
|
+
var BASE64_DIGITS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
537
|
+
function vlq(value) {
|
|
538
|
+
let rest = value < 0 ? -value << 1 | 1 : value << 1;
|
|
539
|
+
let out = "";
|
|
540
|
+
do {
|
|
541
|
+
let digit = rest & 31;
|
|
542
|
+
rest >>>= 5;
|
|
543
|
+
if (rest > 0) digit |= 32;
|
|
544
|
+
out += BASE64_DIGITS[digit];
|
|
545
|
+
} while (rest > 0);
|
|
546
|
+
return out;
|
|
547
|
+
}
|
|
548
|
+
function encodeScopes(entries) {
|
|
549
|
+
const parts = [];
|
|
550
|
+
let line = 0;
|
|
551
|
+
let previousStart = 0;
|
|
552
|
+
let previousName = 0;
|
|
553
|
+
let firstOnLine = true;
|
|
554
|
+
for (const [startLine, startColumn, endLine, endColumn, nameIndex] of entries) {
|
|
555
|
+
if (startLine > line) {
|
|
556
|
+
parts.push(";".repeat(startLine - line));
|
|
557
|
+
line = startLine;
|
|
558
|
+
previousStart = 0;
|
|
559
|
+
firstOnLine = true;
|
|
560
|
+
}
|
|
561
|
+
if (!firstOnLine) parts.push(",");
|
|
562
|
+
firstOnLine = false;
|
|
563
|
+
let segment = vlq(startColumn - previousStart) + vlq(endLine - startLine) + vlq(endLine === startLine ? endColumn - startColumn : endColumn);
|
|
564
|
+
previousStart = startColumn;
|
|
565
|
+
if (nameIndex >= 0) {
|
|
566
|
+
segment += vlq(nameIndex - previousName);
|
|
567
|
+
previousName = nameIndex;
|
|
568
|
+
}
|
|
569
|
+
parts.push(segment);
|
|
570
|
+
}
|
|
571
|
+
return parts.join("");
|
|
572
|
+
}
|
|
573
|
+
function computeScopes(code, map) {
|
|
574
|
+
try {
|
|
575
|
+
return scopesOf(code, map);
|
|
576
|
+
} catch (err) {
|
|
577
|
+
return { error: err instanceof Error ? err.message : String(err) };
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
function scopesOf(code, map) {
|
|
581
|
+
if (typeof map.mappings !== "string") return { error: "the map has no mappings string" };
|
|
582
|
+
let functions;
|
|
583
|
+
try {
|
|
584
|
+
functions = collectFunctions(parseBundle(code));
|
|
585
|
+
} catch (err) {
|
|
586
|
+
return { error: `could not parse the bundle: ${err instanceof Error ? err.message : String(err)}` };
|
|
587
|
+
}
|
|
588
|
+
const starts = lineStarts(code);
|
|
589
|
+
const wanted = /* @__PURE__ */ new Map();
|
|
590
|
+
const want = (offset) => {
|
|
591
|
+
const [line, column] = positionOf(starts, offset);
|
|
592
|
+
let columns = wanted.get(line);
|
|
593
|
+
if (!columns) wanted.set(line, columns = /* @__PURE__ */ new Map());
|
|
594
|
+
columns.set(column, null);
|
|
595
|
+
};
|
|
596
|
+
for (const fn of functions) {
|
|
597
|
+
if (fn.own && !fn.own.literal) want(fn.own.offset);
|
|
598
|
+
if (fn.recoverAt !== null) want(fn.recoverAt);
|
|
599
|
+
for (const token of fn.context) if (!token.literal) want(token.offset);
|
|
600
|
+
}
|
|
601
|
+
try {
|
|
602
|
+
findSegments(map.mappings, wanted);
|
|
603
|
+
} catch (err) {
|
|
604
|
+
return { error: `could not read the map: ${err instanceof Error ? err.message : String(err)}` };
|
|
605
|
+
}
|
|
606
|
+
const resolver = new NameResolver(map, (offset) => {
|
|
607
|
+
const [line, column] = positionOf(starts, offset);
|
|
608
|
+
return wanted.get(line)?.get(column) ?? null;
|
|
609
|
+
});
|
|
610
|
+
functions.sort((a, b) => a.start - b.start || b.end - a.end);
|
|
611
|
+
const mapNames = Array.isArray(map.names) ? map.names : [];
|
|
612
|
+
const nameIndex = /* @__PURE__ */ new Map();
|
|
613
|
+
mapNames.forEach((name, index) => {
|
|
614
|
+
if (typeof name === "string" && !nameIndex.has(name)) nameIndex.set(name, index);
|
|
615
|
+
});
|
|
616
|
+
const extraNames = [];
|
|
617
|
+
const indexOf = (name) => {
|
|
618
|
+
let index = nameIndex.get(name);
|
|
619
|
+
if (index === void 0) {
|
|
620
|
+
index = mapNames.length + extraNames.push(name) - 1;
|
|
621
|
+
nameIndex.set(name, index);
|
|
622
|
+
}
|
|
623
|
+
return index;
|
|
624
|
+
};
|
|
625
|
+
const entries = functions.map((fn) => {
|
|
626
|
+
let name = fn.own ? resolver.resolve(fn.own) : null;
|
|
627
|
+
if (name === null && fn.recoverAt !== null) name = resolver.recover(fn.recoverAt);
|
|
628
|
+
for (const token of fn.context) {
|
|
629
|
+
if (name !== null) break;
|
|
630
|
+
name = resolver.resolve(token);
|
|
631
|
+
}
|
|
632
|
+
const index = name !== null ? indexOf(name) : fn.own || fn.context.length > 0 ? indexOf(null) : -1;
|
|
633
|
+
const [startLine, startColumn] = positionOf(starts, fn.start);
|
|
634
|
+
const [endLine, endColumn] = positionOf(starts, fn.end);
|
|
635
|
+
return [startLine, startColumn, endLine, endColumn, index];
|
|
636
|
+
});
|
|
637
|
+
return { scopes: { version: SCOPES_VERSION, names: extraNames, scopes: encodeScopes(entries) } };
|
|
638
|
+
}
|
|
639
|
+
|
|
264
640
|
// src/upload.ts
|
|
265
641
|
var DEFAULT_ENDPOINT = "https://otlp.autter.dev";
|
|
266
|
-
var
|
|
642
|
+
var MAX_MAP_CHARS = 32 * 1024 * 1024;
|
|
643
|
+
var MAX_UPLOAD_BYTES = MAX_MAP_CHARS + 1024 * 1024;
|
|
644
|
+
var LEGACY_MAX_BYTES = 5 * 1024 * 1024;
|
|
645
|
+
var gzip = promisify(gzipCallback);
|
|
267
646
|
var CHECK_BATCH = 500;
|
|
268
647
|
var MAX_ATTEMPTS = 3;
|
|
269
648
|
function resolveEndpoint(flag, env = process.env) {
|
|
@@ -280,7 +659,16 @@ function storedMapJson(map) {
|
|
|
280
659
|
const { sourcesContent: _omitted, ...safe } = map;
|
|
281
660
|
return JSON.stringify(safe);
|
|
282
661
|
}
|
|
283
|
-
|
|
662
|
+
function bytesOf(buffer) {
|
|
663
|
+
return new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength);
|
|
664
|
+
}
|
|
665
|
+
function fits(json, body) {
|
|
666
|
+
return json.length <= MAX_MAP_CHARS && Buffer.byteLength(body) <= MAX_UPLOAD_BYTES;
|
|
667
|
+
}
|
|
668
|
+
function uploadBody(release, filename, debugId, json) {
|
|
669
|
+
return `{"release":${JSON.stringify(release)},"filename":${JSON.stringify(filename)},${debugId ? `"debugId":${JSON.stringify(debugId)},` : ""}"map":${json}}`;
|
|
670
|
+
}
|
|
671
|
+
async function prepare(bundle, urlPrefix, release, log, compress) {
|
|
284
672
|
let map;
|
|
285
673
|
try {
|
|
286
674
|
map = JSON.parse(await readFile3(bundle.map, "utf8"));
|
|
@@ -292,17 +680,31 @@ async function prepare(bundle, urlPrefix, release) {
|
|
|
292
680
|
}
|
|
293
681
|
const code = await readFile3(bundle.js, "utf8");
|
|
294
682
|
const debugId = readDebugIdComment(code) ?? normalizeDebugId(map.debugId);
|
|
295
|
-
const json = storedMapJson(map);
|
|
296
683
|
const filename = servedFilename(urlPrefix, bundle.path);
|
|
297
|
-
const
|
|
684
|
+
const { [SCOPES_KEY]: _stale, ...plain } = map;
|
|
685
|
+
const scopes = computeScopes(code, map);
|
|
686
|
+
let json = storedMapJson(plain);
|
|
687
|
+
if ("scopes" in scopes) {
|
|
688
|
+
const scoped = storedMapJson({ ...plain, [SCOPES_KEY]: scopes.scopes });
|
|
689
|
+
if (fits(scoped, uploadBody(release, filename, debugId, scoped))) json = scoped;
|
|
690
|
+
else if (fits(json, uploadBody(release, filename, debugId, json))) {
|
|
691
|
+
log(`warning: ${bundle.path}: its map is over 32 MB with function scopes, so it is uploaded without them (frames keep call-site names)`);
|
|
692
|
+
}
|
|
693
|
+
} else {
|
|
694
|
+
log(`warning: ${bundle.path}: no function scopes (${scopes.error}); its map is uploaded without them (frames keep call-site names)`);
|
|
695
|
+
}
|
|
696
|
+
const body = uploadBody(release, filename, debugId, json);
|
|
298
697
|
return {
|
|
299
698
|
bundle,
|
|
300
|
-
|
|
699
|
+
// Maps are text that compresses several times over; the ingester
|
|
700
|
+
// inflates the body (Content-Encoding: gzip).
|
|
701
|
+
body: compress && fits(json, body) ? bytesOf(await gzip(body)) : new Uint8Array(0),
|
|
301
702
|
path: bundle.path,
|
|
302
703
|
filename,
|
|
303
704
|
debugId,
|
|
304
705
|
hash: createHash2("sha256").update(json).digest("hex"),
|
|
305
|
-
bytes: Buffer.byteLength(body)
|
|
706
|
+
bytes: Buffer.byteLength(body),
|
|
707
|
+
mapChars: json.length
|
|
306
708
|
};
|
|
307
709
|
}
|
|
308
710
|
var FatalUploadError = class extends Error {
|
|
@@ -330,14 +732,14 @@ async function uploadDir(dir, options = {}) {
|
|
|
330
732
|
};
|
|
331
733
|
const items = [];
|
|
332
734
|
for (const bundle of await findBundles(dir, options.files)) {
|
|
333
|
-
const prepared = await prepare(bundle, options.urlPrefix, release);
|
|
735
|
+
const prepared = await prepare(bundle, options.urlPrefix, release, log, !options.dryRun);
|
|
334
736
|
if ("error" in prepared) {
|
|
335
737
|
summary.failed.push({ path: bundle.path, filename: servedFilename(options.urlPrefix, bundle.path), error: prepared.error });
|
|
336
|
-
} else if (prepared.bytes > MAX_UPLOAD_BYTES) {
|
|
738
|
+
} else if (prepared.mapChars > MAX_MAP_CHARS || prepared.bytes > MAX_UPLOAD_BYTES) {
|
|
337
739
|
summary.failed.push({
|
|
338
740
|
path: prepared.path,
|
|
339
741
|
filename: prepared.filename,
|
|
340
|
-
error: `map is ${(prepared.
|
|
742
|
+
error: `map is ${(prepared.mapChars / 1048576).toFixed(1)} MB without sourcesContent; the ingester accepts up to 32 MB`
|
|
341
743
|
});
|
|
342
744
|
} else {
|
|
343
745
|
items.push(prepared);
|
|
@@ -353,6 +755,7 @@ async function uploadDir(dir, options = {}) {
|
|
|
353
755
|
throw new FatalUploadError("AUTTER_RUNTIME_KEY is a publishable client key (autter_rtc_\u2026); uploads need a server key (autter_rt_\u2026)");
|
|
354
756
|
}
|
|
355
757
|
const headers = { "content-type": "application/json", authorization: `Bearer ${key}` };
|
|
758
|
+
const uploadHeaders = { ...headers, "content-encoding": "gzip" };
|
|
356
759
|
const skipped = /* @__PURE__ */ new Set();
|
|
357
760
|
for (let start = 0; start < items.length && !summary.legacyIngester; start += CHECK_BATCH) {
|
|
358
761
|
const batch = items.slice(start, start + CHECK_BATCH);
|
|
@@ -394,7 +797,7 @@ async function uploadDir(dir, options = {}) {
|
|
|
394
797
|
let status = 0;
|
|
395
798
|
let detail = "";
|
|
396
799
|
try {
|
|
397
|
-
const res = await doFetch(`${endpoint}/v1/sourcemaps`, { method: "POST", headers, body: item.body });
|
|
800
|
+
const res = await doFetch(`${endpoint}/v1/sourcemaps`, { method: "POST", headers: uploadHeaders, body: item.body });
|
|
398
801
|
status = res.status;
|
|
399
802
|
if (res.ok) {
|
|
400
803
|
uploaded.push(item);
|
|
@@ -410,7 +813,11 @@ async function uploadDir(dir, options = {}) {
|
|
|
410
813
|
}
|
|
411
814
|
const retryable = status === 0 || status === 429 || status >= 500;
|
|
412
815
|
if (!retryable || attempt >= MAX_ATTEMPTS) {
|
|
413
|
-
|
|
816
|
+
let error = status ? `HTTP ${status}: ${detail}` : detail;
|
|
817
|
+
if (status === 413 && item.bytes > LEGACY_MAX_BYTES) {
|
|
818
|
+
error += ` (this map is ${(item.bytes / 1048576).toFixed(1)} MB; ingester 1.6.0 and older accept up to 5 MB, newer ones 32 MB)`;
|
|
819
|
+
}
|
|
820
|
+
summary.failed.push({ path: item.path, filename: item.filename, error });
|
|
414
821
|
return;
|
|
415
822
|
}
|
|
416
823
|
await sleep(500 * 2 ** (attempt - 1));
|
|
@@ -426,10 +833,10 @@ async function uploadDir(dir, options = {}) {
|
|
|
426
833
|
uploaded.sort(order);
|
|
427
834
|
if (options.deleteAfterUpload) {
|
|
428
835
|
for (const item of [...uploaded, ...skipped]) {
|
|
429
|
-
await
|
|
836
|
+
await rm2(item.bundle.map, { force: true });
|
|
430
837
|
const code = await readFile3(item.bundle.js, "utf8");
|
|
431
838
|
const stripped = stripSourceMappingUrl(code);
|
|
432
|
-
if (stripped !== code) await
|
|
839
|
+
if (stripped !== code) await writeFile3(item.bundle.js, stripped);
|
|
433
840
|
summary.deletedMaps.push(item.bundle.map);
|
|
434
841
|
}
|
|
435
842
|
}
|
|
@@ -471,7 +878,9 @@ inject Gives every .js/.mjs/.cjs bundle that has a source map a debug id
|
|
|
471
878
|
that registers it for @autter/runtime-browser, and "debugId" in the
|
|
472
879
|
.map. Running it again changes nothing.
|
|
473
880
|
upload Sends every map to <endpoint>/v1/sourcemaps with AUTTER_RUNTIME_KEY,
|
|
474
|
-
in parallel, skipping maps the ingester already has.
|
|
881
|
+
in parallel, skipping maps the ingester already has. Each map carries
|
|
882
|
+
the bundle's function scopes ("x_autter_scopes"), so stack frames are
|
|
883
|
+
named after the function they are in, not the call site.
|
|
475
884
|
|
|
476
885
|
Options:
|
|
477
886
|
--release <r> Default: $GITHUB_SHA, $VERCEL_GIT_COMMIT_SHA,
|
|
@@ -505,10 +914,10 @@ function delegate(pkg, args) {
|
|
|
505
914
|
return null;
|
|
506
915
|
}
|
|
507
916
|
const bin = JSON.parse(readFileSync(manifest, "utf8")).bin;
|
|
508
|
-
const
|
|
509
|
-
if (!
|
|
510
|
-
const script = resolve2(dirname2(manifest),
|
|
511
|
-
if (!
|
|
917
|
+
const relative3 = typeof bin === "string" ? bin : bin?.["autter-runtime"];
|
|
918
|
+
if (!relative3) return null;
|
|
919
|
+
const script = resolve2(dirname2(manifest), relative3);
|
|
920
|
+
if (!existsSync3(script)) return null;
|
|
512
921
|
const result = spawnSync(process.execPath, [script, ...args], { stdio: "inherit" });
|
|
513
922
|
return result.status ?? 1;
|
|
514
923
|
}
|
|
@@ -544,7 +953,7 @@ ${USAGE}`);
|
|
|
544
953
|
` : ""}${USAGE}`);
|
|
545
954
|
return 64;
|
|
546
955
|
}
|
|
547
|
-
if (!
|
|
956
|
+
if (!existsSync3(dir)) {
|
|
548
957
|
console.error(`autter-runtime: ${dir} does not exist`);
|
|
549
958
|
return 64;
|
|
550
959
|
}
|