@autter/runtime-cli 1.1.0 → 1.2.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 +85 -13
- package/dist/{build-CPXR9Xd3.d.cts → build-BqjqqeLg.d.cts} +10 -3
- package/dist/{build-CPXR9Xd3.d.ts → build-BqjqqeLg.d.ts} +10 -3
- package/dist/{chunk-DQLLM2NT.js → chunk-KIQRQY3X.js} +16 -7
- package/dist/{chunk-I2743JCN.js → chunk-SIL3WZZ3.js} +1 -1
- package/dist/cli.js +1867 -36
- package/dist/index.cjs +273 -14
- package/dist/index.d.cts +56 -2
- package/dist/index.d.ts +56 -2
- package/dist/index.js +253 -2
- package/dist/next.cjs +11 -7
- package/dist/next.d.cts +1 -1
- package/dist/next.d.ts +1 -1
- package/dist/next.js +2 -2
- package/dist/vite.cjs +11 -7
- package/dist/vite.d.cts +1 -1
- package/dist/vite.d.ts +1 -1
- package/dist/vite.js +1 -1
- package/dist/webpack.cjs +11 -7
- package/dist/webpack.d.cts +1 -1
- package/dist/webpack.d.ts +1 -1
- package/dist/webpack.js +2 -2
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
import {
|
|
2
2
|
BUNDLE_RE,
|
|
3
|
+
CLIENT_KEY_PREFIX,
|
|
3
4
|
DEBUG_ID_RE,
|
|
4
5
|
DEBUG_ID_REGISTRY,
|
|
5
6
|
DEFAULT_ENDPOINT,
|
|
6
7
|
FatalUploadError,
|
|
8
|
+
KEY_ADVICE,
|
|
7
9
|
MAX_MAP_CHARS,
|
|
8
10
|
MAX_UPLOAD_BYTES,
|
|
9
11
|
RELEASE_ENV_VARS,
|
|
10
12
|
RELEASE_RE,
|
|
11
13
|
SCOPES_KEY,
|
|
12
14
|
SCOPES_VERSION,
|
|
15
|
+
SERVER_KEY_PREFIX,
|
|
13
16
|
SNIPPET_LINE_KEY,
|
|
17
|
+
UPLOAD_KEY_PREFIX,
|
|
14
18
|
computeScopes,
|
|
15
19
|
debugIdFor,
|
|
16
20
|
debugIdSnippet,
|
|
@@ -33,26 +37,272 @@ import {
|
|
|
33
37
|
storedMapJson,
|
|
34
38
|
stripSourceMappingUrl,
|
|
35
39
|
uploadDir
|
|
36
|
-
} from "./chunk-
|
|
40
|
+
} from "./chunk-KIQRQY3X.js";
|
|
41
|
+
|
|
42
|
+
// src/verify.ts
|
|
43
|
+
import { existsSync } from "fs";
|
|
44
|
+
import { readdir, readFile } from "fs/promises";
|
|
45
|
+
import { dirname, join, relative, resolve, sep } from "path";
|
|
46
|
+
var CHECK_BATCH = 500;
|
|
47
|
+
var SNIPPET_ID_RE = /\(g\._autterDebugIds=g\._autterDebugIds\|\|\{\}\)\[s\]="([0-9a-f-]{36})"/;
|
|
48
|
+
var NOT_BUNDLES = [
|
|
49
|
+
[/(^|\/)_(build|ssg|middleware|clientMiddleware)Manifest\.js$/, "Next.js build manifest"],
|
|
50
|
+
[/(^|\/)chunks\/polyfills-[\w-]+\.js$/, "Next.js polyfills, copied prebuilt without a source map"],
|
|
51
|
+
[/(^|\/)(sw|service-worker|serviceWorker|firebase-messaging-sw|mockServiceWorker)\.js$/, "service worker (the browser SDK doesn't run there)"],
|
|
52
|
+
[/(^|\/)workbox-[\w-]+\.js$/, "service worker runtime (the browser SDK doesn't run there)"]
|
|
53
|
+
];
|
|
54
|
+
function globToRegExp(glob) {
|
|
55
|
+
let re = "";
|
|
56
|
+
for (let i = 0; i < glob.length; i++) {
|
|
57
|
+
const ch = glob[i];
|
|
58
|
+
if (ch === "*" && glob[i + 1] === "*") {
|
|
59
|
+
re += glob[i + 2] === "/" ? "(?:.*/)?" : ".*";
|
|
60
|
+
i += glob[i + 2] === "/" ? 2 : 1;
|
|
61
|
+
} else if (ch === "*") re += "[^/]*";
|
|
62
|
+
else if (ch === "?") re += "[^/]";
|
|
63
|
+
else re += ch.replace(/[.+^${}()|[\]\\]/g, "\\$&");
|
|
64
|
+
}
|
|
65
|
+
return new RegExp(glob.includes("/") ? `^${re.replace(/^\.\//, "")}$` : `(^|/)${re}$`);
|
|
66
|
+
}
|
|
67
|
+
async function walk(dir, out) {
|
|
68
|
+
let entries;
|
|
69
|
+
try {
|
|
70
|
+
entries = await readdir(dir, { withFileTypes: true });
|
|
71
|
+
} catch {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
for (const entry of entries) {
|
|
75
|
+
if (entry.name === "node_modules") continue;
|
|
76
|
+
const full = join(dir, entry.name);
|
|
77
|
+
if (entry.isDirectory()) await walk(full, out);
|
|
78
|
+
else if (entry.isFile()) out.push(full);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
function staticRoots(dir) {
|
|
82
|
+
for (let current = dirname(dir); dirname(current) !== current; current = dirname(current)) {
|
|
83
|
+
if (existsSync(join(current, "package.json"))) return ["public", "static", "src"].map((name) => join(current, name));
|
|
84
|
+
}
|
|
85
|
+
return [];
|
|
86
|
+
}
|
|
87
|
+
async function verifyDir(dir, options = {}) {
|
|
88
|
+
const root = resolve(dir);
|
|
89
|
+
const env = options.env ?? process.env;
|
|
90
|
+
const files = [];
|
|
91
|
+
await walk(root, files);
|
|
92
|
+
files.sort();
|
|
93
|
+
const relPath = (path) => relative(root, path).split(sep).join("/");
|
|
94
|
+
const ignore = (options.ignore ?? []).map(globToRegExp);
|
|
95
|
+
const roots = staticRoots(root);
|
|
96
|
+
const result = {
|
|
97
|
+
dir: root,
|
|
98
|
+
ok: true,
|
|
99
|
+
bundles: [],
|
|
100
|
+
maps: [],
|
|
101
|
+
upload: { status: "unverified", endpoint: null, reason: null, checked: 0, missing: 0 },
|
|
102
|
+
failures: []
|
|
103
|
+
};
|
|
104
|
+
const fail = (path, reason) => result.failures.push({ path, reason });
|
|
105
|
+
for (const file of files) {
|
|
106
|
+
const path = relPath(file);
|
|
107
|
+
if (file.endsWith(".map")) {
|
|
108
|
+
result.maps.push(path);
|
|
109
|
+
if (!options.allowMaps) {
|
|
110
|
+
fail(path, "source map in the deploy output: it exposes your original source. Delete it after upload (upload --delete-after-upload, or the bundler plugin) or keep it out of the deploy");
|
|
111
|
+
}
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
if (!BUNDLE_RE.test(file)) continue;
|
|
115
|
+
const bytes = await readFile(file);
|
|
116
|
+
const bundle = { path, status: "ok", debugId: null, reasons: [], uploaded: null };
|
|
117
|
+
result.bundles.push(bundle);
|
|
118
|
+
const skip = (reason) => {
|
|
119
|
+
bundle.status = "skipped";
|
|
120
|
+
bundle.reasons.push(reason);
|
|
121
|
+
};
|
|
122
|
+
if (ignore.some((re) => re.test(path))) {
|
|
123
|
+
skip("matches --ignore");
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
const known = NOT_BUNDLES.find(([re]) => re.test(path));
|
|
127
|
+
if (known) {
|
|
128
|
+
skip(known[1]);
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
let copied = null;
|
|
132
|
+
for (const staticRoot of roots) {
|
|
133
|
+
const candidate = join(staticRoot, path);
|
|
134
|
+
if (existsSync(candidate) && (await readFile(candidate)).equals(bytes)) copied = relative(dirname(staticRoot), candidate).split(sep).join("/");
|
|
135
|
+
}
|
|
136
|
+
if (copied) {
|
|
137
|
+
skip(`copied unchanged from ${copied}, not built`);
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
const code = bytes.toString("utf8");
|
|
141
|
+
const commentId = readDebugIdComment(code);
|
|
142
|
+
const snippetId = SNIPPET_ID_RE.exec(code)?.[1] ?? null;
|
|
143
|
+
bundle.debugId = commentId;
|
|
144
|
+
if (!commentId && !hasDebugIdSnippet(code)) {
|
|
145
|
+
bundle.reasons.push(
|
|
146
|
+
"no debug id: its errors can't be matched to a source map. Run `autter-runtime sourcemaps inject` on the build output (or use the bundler plugin with AUTTER_RUNTIME_KEY set) before deploying"
|
|
147
|
+
);
|
|
148
|
+
} else if (!commentId) {
|
|
149
|
+
bundle.reasons.push("has the debug id snippet but no //# debugId= comment: run `autter-runtime sourcemaps inject` on it again");
|
|
150
|
+
} else if (!hasDebugIdSnippet(code)) {
|
|
151
|
+
bundle.reasons.push(
|
|
152
|
+
"has a //# debugId= comment but no registration snippet, so the browser SDK can't report its id: run `autter-runtime sourcemaps inject` on it"
|
|
153
|
+
);
|
|
154
|
+
} else if (snippetId && snippetId !== commentId) {
|
|
155
|
+
bundle.reasons.push(`its snippet registers debug id ${snippetId} but its comment says ${commentId}: run inject on the original build output`);
|
|
156
|
+
}
|
|
157
|
+
const url = readSourceMappingUrl(code);
|
|
158
|
+
if (url?.startsWith("data:")) {
|
|
159
|
+
bundle.reasons.push("carries an inline source map (data: URL): your original source ships with the bundle. Use hidden or external maps");
|
|
160
|
+
} else if (url && !/^[a-z][\w+.-]*:/i.test(url) && !url.startsWith("/")) {
|
|
161
|
+
let target = url.split(/[?#]/)[0];
|
|
162
|
+
try {
|
|
163
|
+
target = decodeURIComponent(target);
|
|
164
|
+
} catch {
|
|
165
|
+
}
|
|
166
|
+
if (!existsSync(resolve(dirname(file), target))) {
|
|
167
|
+
bundle.reasons.push(
|
|
168
|
+
`its sourceMappingURL points at ${url}, which is not in the output (browsers' devtools request it and get a 404). Remove the comment: upload --delete-after-upload does`
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
if (bundle.reasons.length) {
|
|
173
|
+
bundle.status = "failed";
|
|
174
|
+
for (const reason of bundle.reasons) fail(path, reason);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
const counted = result.bundles.filter((b) => b.status !== "skipped");
|
|
178
|
+
if (!counted.length) fail(".", `no .js/.mjs/.cjs bundles under ${dir}: is this the build output?`);
|
|
179
|
+
await checkUploads(result, counted, options, env);
|
|
180
|
+
result.ok = result.failures.length === 0;
|
|
181
|
+
return result;
|
|
182
|
+
}
|
|
183
|
+
async function checkUploads(result, bundles, options, env) {
|
|
184
|
+
const upload = result.upload;
|
|
185
|
+
const key = (options.key ?? env.AUTTER_RUNTIME_KEY ?? "").trim();
|
|
186
|
+
if (!key) {
|
|
187
|
+
upload.reason = "AUTTER_RUNTIME_KEY is not set: only the local checks ran";
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
upload.endpoint = resolveEndpoint(options.endpoint, env);
|
|
191
|
+
if (key.startsWith(CLIENT_KEY_PREFIX)) {
|
|
192
|
+
upload.status = "error";
|
|
193
|
+
upload.reason = "AUTTER_RUNTIME_KEY is a publishable client key (autter_rtc_\u2026), which can't check source maps: use an upload key (autter_rtu_\u2026) or the server key (autter_rt_\u2026)";
|
|
194
|
+
result.failures.push({ path: ".", reason: upload.reason });
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
const withIds = bundles.filter((b) => b.debugId);
|
|
198
|
+
if (!withIds.length) {
|
|
199
|
+
upload.reason = "no bundle has a debug id to check";
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
let release = "verify";
|
|
203
|
+
try {
|
|
204
|
+
release = resolveRelease(options.release, env, options.cwd).release;
|
|
205
|
+
} catch {
|
|
206
|
+
}
|
|
207
|
+
const doFetch = options.fetch ?? fetch;
|
|
208
|
+
const missing = [];
|
|
209
|
+
for (let start = 0; start < withIds.length; start += CHECK_BATCH) {
|
|
210
|
+
const batch = withIds.slice(start, start + CHECK_BATCH);
|
|
211
|
+
let res;
|
|
212
|
+
try {
|
|
213
|
+
res = await doFetch(`${upload.endpoint}/v1/sourcemaps/check`, {
|
|
214
|
+
method: "POST",
|
|
215
|
+
headers: { "content-type": "application/json", authorization: `Bearer ${key}` },
|
|
216
|
+
body: JSON.stringify({ release, files: batch.map((b) => ({ filename: servedFilename(options.urlPrefix, b.path), debugId: b.debugId })) })
|
|
217
|
+
});
|
|
218
|
+
} catch (err) {
|
|
219
|
+
upload.status = "error";
|
|
220
|
+
upload.reason = `could not reach the ingester: ${err.message}`;
|
|
221
|
+
result.failures.push({ path: ".", reason: upload.reason });
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
if (res.status === 404 || res.status === 400) {
|
|
225
|
+
upload.status = "unverified";
|
|
226
|
+
upload.reason = res.status === 404 ? "the ingester predates 1.6.0 (no /v1/sourcemaps/check), so uploads can't be checked: upgrade it" : "the ingester predates 1.7.0, which checks maps by debug id alone, so uploads can't be checked after the maps were deleted: upgrade it";
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
if (res.status === 401 || res.status === 403) {
|
|
230
|
+
upload.status = "error";
|
|
231
|
+
upload.reason = `the ingester rejected the key (${res.status}): ${(await res.text()).slice(0, 300)}` + (key.startsWith(UPLOAD_KEY_PREFIX) ? " (upload keys, autter_rtu_\u2026, need ingester 1.7.0 or later)" : "");
|
|
232
|
+
result.failures.push({ path: ".", reason: upload.reason });
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
if (!res.ok) {
|
|
236
|
+
upload.status = "error";
|
|
237
|
+
upload.reason = `the source map check failed: HTTP ${res.status}`;
|
|
238
|
+
result.failures.push({ path: ".", reason: upload.reason });
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
const body = await res.json();
|
|
242
|
+
const present = new Set(Array.isArray(body.present) ? body.present : []);
|
|
243
|
+
batch.forEach((bundle, index) => {
|
|
244
|
+
bundle.uploaded = present.has(index);
|
|
245
|
+
if (!bundle.uploaded) missing.push(bundle);
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
upload.checked = withIds.length;
|
|
249
|
+
upload.missing = missing.length;
|
|
250
|
+
upload.status = missing.length ? "missing" : "verified";
|
|
251
|
+
upload.reason = missing.length ? `${missing.length} of ${withIds.length} bundle(s) have no map on the ingester` : null;
|
|
252
|
+
for (const bundle of missing) {
|
|
253
|
+
const reason = `no map with debug id ${bundle.debugId} on the ingester for this key's repository: upload this build's maps (autter-runtime sourcemaps upload, or the bundler plugin with AUTTER_RUNTIME_KEY set)`;
|
|
254
|
+
bundle.status = "failed";
|
|
255
|
+
bundle.reasons.push(reason);
|
|
256
|
+
result.failures.push({ path: bundle.path, reason });
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
function formatVerify(result) {
|
|
260
|
+
const lines = [];
|
|
261
|
+
for (const bundle of result.bundles) {
|
|
262
|
+
if (bundle.status === "ok") lines.push(`ok ${bundle.path} (debug id ${bundle.debugId}${bundle.uploaded ? ", map uploaded" : ""})`);
|
|
263
|
+
else if (bundle.status === "skipped") lines.push(`skipped ${bundle.path}: ${bundle.reasons.join("; ")}`);
|
|
264
|
+
else for (const reason of bundle.reasons) lines.push(`FAILED ${bundle.path}: ${reason}`);
|
|
265
|
+
}
|
|
266
|
+
for (const map of result.maps) {
|
|
267
|
+
const failure = result.failures.find((f) => f.path === map);
|
|
268
|
+
lines.push(failure ? `FAILED ${map}: ${failure.reason}` : `warning ${map}: source map in the output (allowed by --allow-maps; remove it before deploying)`);
|
|
269
|
+
}
|
|
270
|
+
for (const failure of result.failures.filter((f) => f.path === ".")) lines.push(`FAILED ${failure.reason}`);
|
|
271
|
+
const u = result.upload;
|
|
272
|
+
lines.push(
|
|
273
|
+
u.status === "verified" ? `upload: verified, ${u.checked} bundle map(s) on the ingester (${u.endpoint})` : u.status === "missing" ? `upload: ${u.reason} (${u.endpoint})` : `upload: ${u.status}${u.reason ? `, ${u.reason}` : ""}`
|
|
274
|
+
);
|
|
275
|
+
const counted = result.bundles.filter((b) => b.status !== "skipped");
|
|
276
|
+
lines.push(
|
|
277
|
+
result.ok ? `ok: ${counted.length} bundle(s) with debug ids, ${result.maps.length ? `${result.maps.length} source map(s) left (--allow-maps)` : "no source maps left"}${u.status === "unverified" ? ", upload not verified" : ""}` : `${result.failures.length} problem(s) in ${result.dir}`
|
|
278
|
+
);
|
|
279
|
+
return lines;
|
|
280
|
+
}
|
|
37
281
|
export {
|
|
38
282
|
BUNDLE_RE,
|
|
283
|
+
CLIENT_KEY_PREFIX,
|
|
39
284
|
DEBUG_ID_RE,
|
|
40
285
|
DEBUG_ID_REGISTRY,
|
|
41
286
|
DEFAULT_ENDPOINT,
|
|
42
287
|
FatalUploadError,
|
|
288
|
+
KEY_ADVICE,
|
|
43
289
|
MAX_MAP_CHARS,
|
|
44
290
|
MAX_UPLOAD_BYTES,
|
|
45
291
|
RELEASE_ENV_VARS,
|
|
46
292
|
RELEASE_RE,
|
|
47
293
|
SCOPES_KEY,
|
|
48
294
|
SCOPES_VERSION,
|
|
295
|
+
SERVER_KEY_PREFIX,
|
|
49
296
|
SNIPPET_LINE_KEY,
|
|
297
|
+
UPLOAD_KEY_PREFIX,
|
|
50
298
|
computeScopes,
|
|
51
299
|
debugIdFor,
|
|
52
300
|
debugIdSnippet,
|
|
53
301
|
findBundles,
|
|
54
302
|
formatUploadSummary,
|
|
303
|
+
formatVerify,
|
|
55
304
|
gitHead,
|
|
305
|
+
globToRegExp,
|
|
56
306
|
hasDebugIdSnippet,
|
|
57
307
|
injectBundle,
|
|
58
308
|
injectDir,
|
|
@@ -68,5 +318,6 @@ export {
|
|
|
68
318
|
snippetLine,
|
|
69
319
|
storedMapJson,
|
|
70
320
|
stripSourceMappingUrl,
|
|
71
|
-
uploadDir
|
|
321
|
+
uploadDir,
|
|
322
|
+
verifyDir
|
|
72
323
|
};
|
package/dist/next.cjs
CHANGED
|
@@ -705,6 +705,9 @@ var DEFAULT_ENDPOINT = "https://otlp.autter.dev";
|
|
|
705
705
|
var MAX_MAP_CHARS = 32 * 1024 * 1024;
|
|
706
706
|
var MAX_UPLOAD_BYTES = MAX_MAP_CHARS + 1024 * 1024;
|
|
707
707
|
var LEGACY_MAX_BYTES = 5 * 1024 * 1024;
|
|
708
|
+
var UPLOAD_KEY_PREFIX = "autter_rtu_";
|
|
709
|
+
var CLIENT_KEY_PREFIX = "autter_rtc_";
|
|
710
|
+
var KEY_ADVICE = "set AUTTER_RUNTIME_KEY to an upload-only key (autter_rtu_\u2026, recommended for CI: it can only upload source maps) or the full server key (autter_rt_\u2026, also works)";
|
|
708
711
|
var gzip = (0, import_node_util.promisify)(import_node_zlib.gzip);
|
|
709
712
|
var CHECK_BATCH = 500;
|
|
710
713
|
var MAX_ATTEMPTS = 3;
|
|
@@ -813,10 +816,13 @@ async function uploadDir(dir, options = {}) {
|
|
|
813
816
|
return summary;
|
|
814
817
|
}
|
|
815
818
|
const key = (options.key ?? env.AUTTER_RUNTIME_KEY ?? "").trim();
|
|
816
|
-
if (!key) throw new FatalUploadError(
|
|
817
|
-
if (key.startsWith(
|
|
818
|
-
throw new FatalUploadError(
|
|
819
|
+
if (!key) throw new FatalUploadError(`no ingest key: ${KEY_ADVICE}`);
|
|
820
|
+
if (key.startsWith(CLIENT_KEY_PREFIX)) {
|
|
821
|
+
throw new FatalUploadError(`AUTTER_RUNTIME_KEY is a publishable client key (autter_rtc_\u2026), which cannot upload source maps: ${KEY_ADVICE}`);
|
|
819
822
|
}
|
|
823
|
+
const rejected = (status, detail) => new FatalUploadError(
|
|
824
|
+
`the ingester rejected the key (${status}): ${detail}` + (key.startsWith(UPLOAD_KEY_PREFIX) ? " (upload keys, autter_rtu_\u2026, need ingester 1.7.0 or later; the server key works with any)" : "")
|
|
825
|
+
);
|
|
820
826
|
const headers = { "content-type": "application/json", authorization: `Bearer ${key}` };
|
|
821
827
|
const uploadHeaders = { ...headers, "content-encoding": "gzip" };
|
|
822
828
|
const skipped = /* @__PURE__ */ new Set();
|
|
@@ -838,9 +844,7 @@ async function uploadDir(dir, options = {}) {
|
|
|
838
844
|
);
|
|
839
845
|
break;
|
|
840
846
|
}
|
|
841
|
-
if (res.status === 401 || res.status === 403)
|
|
842
|
-
throw new FatalUploadError(`the ingester rejected the key (${res.status}): ${(await res.text()).slice(0, 300)}`);
|
|
843
|
-
}
|
|
847
|
+
if (res.status === 401 || res.status === 403) throw rejected(res.status, (await res.text()).slice(0, 300));
|
|
844
848
|
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
845
849
|
const body = await res.json();
|
|
846
850
|
const present = new Set(Array.isArray(body.present) ? body.present : []);
|
|
@@ -871,7 +875,7 @@ async function uploadDir(dir, options = {}) {
|
|
|
871
875
|
detail = err.message;
|
|
872
876
|
}
|
|
873
877
|
if (status === 401 || status === 403) {
|
|
874
|
-
fatal =
|
|
878
|
+
fatal = rejected(status, detail);
|
|
875
879
|
return;
|
|
876
880
|
}
|
|
877
881
|
const retryable = status === 0 || status === 429 || status >= 500;
|
package/dist/next.d.cts
CHANGED
package/dist/next.d.ts
CHANGED
package/dist/next.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AutterSourceMapsWebpackPlugin
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-SIL3WZZ3.js";
|
|
4
4
|
import {
|
|
5
5
|
findMapFiles,
|
|
6
6
|
logMapsNotGenerated,
|
|
7
7
|
processBuildOutput,
|
|
8
8
|
shouldGenerateMaps
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-KIQRQY3X.js";
|
|
10
10
|
|
|
11
11
|
// src/next.ts
|
|
12
12
|
import { createRequire } from "module";
|
package/dist/vite.cjs
CHANGED
|
@@ -698,6 +698,9 @@ var DEFAULT_ENDPOINT = "https://otlp.autter.dev";
|
|
|
698
698
|
var MAX_MAP_CHARS = 32 * 1024 * 1024;
|
|
699
699
|
var MAX_UPLOAD_BYTES = MAX_MAP_CHARS + 1024 * 1024;
|
|
700
700
|
var LEGACY_MAX_BYTES = 5 * 1024 * 1024;
|
|
701
|
+
var UPLOAD_KEY_PREFIX = "autter_rtu_";
|
|
702
|
+
var CLIENT_KEY_PREFIX = "autter_rtc_";
|
|
703
|
+
var KEY_ADVICE = "set AUTTER_RUNTIME_KEY to an upload-only key (autter_rtu_\u2026, recommended for CI: it can only upload source maps) or the full server key (autter_rt_\u2026, also works)";
|
|
701
704
|
var gzip = (0, import_node_util.promisify)(import_node_zlib.gzip);
|
|
702
705
|
var CHECK_BATCH = 500;
|
|
703
706
|
var MAX_ATTEMPTS = 3;
|
|
@@ -806,10 +809,13 @@ async function uploadDir(dir, options = {}) {
|
|
|
806
809
|
return summary;
|
|
807
810
|
}
|
|
808
811
|
const key = (options.key ?? env.AUTTER_RUNTIME_KEY ?? "").trim();
|
|
809
|
-
if (!key) throw new FatalUploadError(
|
|
810
|
-
if (key.startsWith(
|
|
811
|
-
throw new FatalUploadError(
|
|
812
|
+
if (!key) throw new FatalUploadError(`no ingest key: ${KEY_ADVICE}`);
|
|
813
|
+
if (key.startsWith(CLIENT_KEY_PREFIX)) {
|
|
814
|
+
throw new FatalUploadError(`AUTTER_RUNTIME_KEY is a publishable client key (autter_rtc_\u2026), which cannot upload source maps: ${KEY_ADVICE}`);
|
|
812
815
|
}
|
|
816
|
+
const rejected = (status, detail) => new FatalUploadError(
|
|
817
|
+
`the ingester rejected the key (${status}): ${detail}` + (key.startsWith(UPLOAD_KEY_PREFIX) ? " (upload keys, autter_rtu_\u2026, need ingester 1.7.0 or later; the server key works with any)" : "")
|
|
818
|
+
);
|
|
813
819
|
const headers = { "content-type": "application/json", authorization: `Bearer ${key}` };
|
|
814
820
|
const uploadHeaders = { ...headers, "content-encoding": "gzip" };
|
|
815
821
|
const skipped = /* @__PURE__ */ new Set();
|
|
@@ -831,9 +837,7 @@ async function uploadDir(dir, options = {}) {
|
|
|
831
837
|
);
|
|
832
838
|
break;
|
|
833
839
|
}
|
|
834
|
-
if (res.status === 401 || res.status === 403)
|
|
835
|
-
throw new FatalUploadError(`the ingester rejected the key (${res.status}): ${(await res.text()).slice(0, 300)}`);
|
|
836
|
-
}
|
|
840
|
+
if (res.status === 401 || res.status === 403) throw rejected(res.status, (await res.text()).slice(0, 300));
|
|
837
841
|
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
838
842
|
const body = await res.json();
|
|
839
843
|
const present = new Set(Array.isArray(body.present) ? body.present : []);
|
|
@@ -864,7 +868,7 @@ async function uploadDir(dir, options = {}) {
|
|
|
864
868
|
detail = err.message;
|
|
865
869
|
}
|
|
866
870
|
if (status === 401 || status === 403) {
|
|
867
|
-
fatal =
|
|
871
|
+
fatal = rejected(status, detail);
|
|
868
872
|
return;
|
|
869
873
|
}
|
|
870
874
|
const retryable = status === 0 || status === 429 || status >= 500;
|
package/dist/vite.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as AutterSourceMapsOptions } from './build-
|
|
1
|
+
import { A as AutterSourceMapsOptions } from './build-BqjqqeLg.cjs';
|
|
2
2
|
|
|
3
3
|
type SourcemapSetting = boolean | "inline" | "hidden";
|
|
4
4
|
/** The parts of Vite's / Rollup's types this plugin touches (structural, so
|
package/dist/vite.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as AutterSourceMapsOptions } from './build-
|
|
1
|
+
import { A as AutterSourceMapsOptions } from './build-BqjqqeLg.js';
|
|
2
2
|
|
|
3
3
|
type SourcemapSetting = boolean | "inline" | "hidden";
|
|
4
4
|
/** The parts of Vite's / Rollup's types this plugin touches (structural, so
|
package/dist/vite.js
CHANGED
package/dist/webpack.cjs
CHANGED
|
@@ -699,6 +699,9 @@ var DEFAULT_ENDPOINT = "https://otlp.autter.dev";
|
|
|
699
699
|
var MAX_MAP_CHARS = 32 * 1024 * 1024;
|
|
700
700
|
var MAX_UPLOAD_BYTES = MAX_MAP_CHARS + 1024 * 1024;
|
|
701
701
|
var LEGACY_MAX_BYTES = 5 * 1024 * 1024;
|
|
702
|
+
var UPLOAD_KEY_PREFIX = "autter_rtu_";
|
|
703
|
+
var CLIENT_KEY_PREFIX = "autter_rtc_";
|
|
704
|
+
var KEY_ADVICE = "set AUTTER_RUNTIME_KEY to an upload-only key (autter_rtu_\u2026, recommended for CI: it can only upload source maps) or the full server key (autter_rt_\u2026, also works)";
|
|
702
705
|
var gzip = (0, import_node_util.promisify)(import_node_zlib.gzip);
|
|
703
706
|
var CHECK_BATCH = 500;
|
|
704
707
|
var MAX_ATTEMPTS = 3;
|
|
@@ -807,10 +810,13 @@ async function uploadDir(dir, options = {}) {
|
|
|
807
810
|
return summary;
|
|
808
811
|
}
|
|
809
812
|
const key = (options.key ?? env.AUTTER_RUNTIME_KEY ?? "").trim();
|
|
810
|
-
if (!key) throw new FatalUploadError(
|
|
811
|
-
if (key.startsWith(
|
|
812
|
-
throw new FatalUploadError(
|
|
813
|
+
if (!key) throw new FatalUploadError(`no ingest key: ${KEY_ADVICE}`);
|
|
814
|
+
if (key.startsWith(CLIENT_KEY_PREFIX)) {
|
|
815
|
+
throw new FatalUploadError(`AUTTER_RUNTIME_KEY is a publishable client key (autter_rtc_\u2026), which cannot upload source maps: ${KEY_ADVICE}`);
|
|
813
816
|
}
|
|
817
|
+
const rejected = (status, detail) => new FatalUploadError(
|
|
818
|
+
`the ingester rejected the key (${status}): ${detail}` + (key.startsWith(UPLOAD_KEY_PREFIX) ? " (upload keys, autter_rtu_\u2026, need ingester 1.7.0 or later; the server key works with any)" : "")
|
|
819
|
+
);
|
|
814
820
|
const headers = { "content-type": "application/json", authorization: `Bearer ${key}` };
|
|
815
821
|
const uploadHeaders = { ...headers, "content-encoding": "gzip" };
|
|
816
822
|
const skipped = /* @__PURE__ */ new Set();
|
|
@@ -832,9 +838,7 @@ async function uploadDir(dir, options = {}) {
|
|
|
832
838
|
);
|
|
833
839
|
break;
|
|
834
840
|
}
|
|
835
|
-
if (res.status === 401 || res.status === 403)
|
|
836
|
-
throw new FatalUploadError(`the ingester rejected the key (${res.status}): ${(await res.text()).slice(0, 300)}`);
|
|
837
|
-
}
|
|
841
|
+
if (res.status === 401 || res.status === 403) throw rejected(res.status, (await res.text()).slice(0, 300));
|
|
838
842
|
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
839
843
|
const body = await res.json();
|
|
840
844
|
const present = new Set(Array.isArray(body.present) ? body.present : []);
|
|
@@ -865,7 +869,7 @@ async function uploadDir(dir, options = {}) {
|
|
|
865
869
|
detail = err.message;
|
|
866
870
|
}
|
|
867
871
|
if (status === 401 || status === 403) {
|
|
868
|
-
fatal =
|
|
872
|
+
fatal = rejected(status, detail);
|
|
869
873
|
return;
|
|
870
874
|
}
|
|
871
875
|
const retryable = status === 0 || status === 429 || status >= 500;
|
package/dist/webpack.d.cts
CHANGED
package/dist/webpack.d.ts
CHANGED
package/dist/webpack.js
CHANGED
|
@@ -2,8 +2,8 @@ import {
|
|
|
2
2
|
AutterSourceMapsWebpackPlugin,
|
|
3
3
|
autterSourceMapsWebpack,
|
|
4
4
|
webpack_default
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-SIL3WZZ3.js";
|
|
6
|
+
import "./chunk-KIQRQY3X.js";
|
|
7
7
|
export {
|
|
8
8
|
AutterSourceMapsWebpackPlugin,
|
|
9
9
|
autterSourceMapsWebpack,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@autter/runtime-cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Readable stack traces for Autter Runtime: inject debug ids into JS bundles and upload their source maps (CLI, Vite/Rollup, webpack and Next.js plugins)",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -51,6 +51,7 @@
|
|
|
51
51
|
"test": "npm run build -w @autter/otlp-ingester && npm run build && node --test test/*.test.mjs"
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
|
+
"@sveltejs/acorn-typescript": "^1.0.13",
|
|
54
55
|
"acorn": "^8.17.0"
|
|
55
56
|
},
|
|
56
57
|
"peerDependencies": {
|