@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/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-DQLLM2NT.js";
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("no ingest key: set AUTTER_RUNTIME_KEY to a server key (autter_rt_\u2026)");
817
- if (key.startsWith("autter_rtc_")) {
818
- throw new FatalUploadError("AUTTER_RUNTIME_KEY is a publishable client key (autter_rtc_\u2026); uploads need a server key (autter_rt_\u2026)");
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 = new FatalUploadError(`the ingester rejected the key (${status}): ${detail}`);
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
@@ -1,4 +1,4 @@
1
- import { A as AutterSourceMapsOptions } from './build-CPXR9Xd3.cjs';
1
+ import { A as AutterSourceMapsOptions } from './build-BqjqqeLg.cjs';
2
2
 
3
3
  type NextConfigObject = Record<string, any>;
4
4
  type NextConfigFunction = (phase: string, context: {
package/dist/next.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { A as AutterSourceMapsOptions } from './build-CPXR9Xd3.js';
1
+ import { A as AutterSourceMapsOptions } from './build-BqjqqeLg.js';
2
2
 
3
3
  type NextConfigObject = Record<string, any>;
4
4
  type NextConfigFunction = (phase: string, context: {
package/dist/next.js CHANGED
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  AutterSourceMapsWebpackPlugin
3
- } from "./chunk-I2743JCN.js";
3
+ } from "./chunk-SIL3WZZ3.js";
4
4
  import {
5
5
  findMapFiles,
6
6
  logMapsNotGenerated,
7
7
  processBuildOutput,
8
8
  shouldGenerateMaps
9
- } from "./chunk-DQLLM2NT.js";
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("no ingest key: set AUTTER_RUNTIME_KEY to a server key (autter_rt_\u2026)");
810
- if (key.startsWith("autter_rtc_")) {
811
- throw new FatalUploadError("AUTTER_RUNTIME_KEY is a publishable client key (autter_rtc_\u2026); uploads need a server key (autter_rt_\u2026)");
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 = new FatalUploadError(`the ingester rejected the key (${status}): ${detail}`);
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-CPXR9Xd3.cjs';
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-CPXR9Xd3.js';
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
@@ -3,7 +3,7 @@ import {
3
3
  processBuildOutput,
4
4
  removeSourceMaps,
5
5
  shouldGenerateMaps
6
- } from "./chunk-DQLLM2NT.js";
6
+ } from "./chunk-KIQRQY3X.js";
7
7
 
8
8
  // src/vite.ts
9
9
  import { dirname, resolve } from "path";
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("no ingest key: set AUTTER_RUNTIME_KEY to a server key (autter_rt_\u2026)");
811
- if (key.startsWith("autter_rtc_")) {
812
- throw new FatalUploadError("AUTTER_RUNTIME_KEY is a publishable client key (autter_rtc_\u2026); uploads need a server key (autter_rt_\u2026)");
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 = new FatalUploadError(`the ingester rejected the key (${status}): ${detail}`);
872
+ fatal = rejected(status, detail);
869
873
  return;
870
874
  }
871
875
  const retryable = status === 0 || status === 429 || status >= 500;
@@ -1,4 +1,4 @@
1
- import { A as AutterSourceMapsOptions } from './build-CPXR9Xd3.cjs';
1
+ import { A as AutterSourceMapsOptions } from './build-BqjqqeLg.cjs';
2
2
 
3
3
  /** The parts of webpack's types this plugin touches (structural, so webpack
4
4
  * is not a dependency). */
package/dist/webpack.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { A as AutterSourceMapsOptions } from './build-CPXR9Xd3.js';
1
+ import { A as AutterSourceMapsOptions } from './build-BqjqqeLg.js';
2
2
 
3
3
  /** The parts of webpack's types this plugin touches (structural, so webpack
4
4
  * is not a dependency). */
package/dist/webpack.js CHANGED
@@ -2,8 +2,8 @@ import {
2
2
  AutterSourceMapsWebpackPlugin,
3
3
  autterSourceMapsWebpack,
4
4
  webpack_default
5
- } from "./chunk-I2743JCN.js";
6
- import "./chunk-DQLLM2NT.js";
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.1.0",
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": {