@autter/runtime-cli 1.2.0 → 1.3.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 +47 -18
- package/dist/{build-BqjqqeLg.d.cts → build-DGeoDkTh.d.cts} +48 -5
- package/dist/{build-BqjqqeLg.d.ts → build-DGeoDkTh.d.ts} +48 -5
- package/dist/{chunk-KIQRQY3X.js → chunk-Q23FB5X3.js} +65 -9
- package/dist/{chunk-SIL3WZZ3.js → chunk-V66S2YHN.js} +13 -3
- package/dist/cli.js +92 -22
- package/dist/index.cjs +80 -13
- package/dist/index.d.cts +14 -5
- package/dist/index.d.ts +14 -5
- package/dist/index.js +20 -6
- package/dist/next.cjs +109 -12
- package/dist/next.d.cts +6 -3
- package/dist/next.d.ts +6 -3
- package/dist/next.js +41 -4
- package/dist/vite.cjs +81 -11
- package/dist/vite.d.cts +5 -1
- package/dist/vite.d.ts +5 -1
- package/dist/vite.js +22 -4
- package/dist/webpack.cjs +75 -12
- package/dist/webpack.d.cts +18 -4
- package/dist/webpack.d.ts +18 -4
- package/dist/webpack.js +5 -3
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
hasDebugIdSnippet,
|
|
25
25
|
injectBundle,
|
|
26
26
|
injectDir,
|
|
27
|
+
isInAppSource,
|
|
27
28
|
mapPathFor,
|
|
28
29
|
normalizeDebugId,
|
|
29
30
|
processBuildOutput,
|
|
@@ -32,12 +33,14 @@ import {
|
|
|
32
33
|
resolveEndpoint,
|
|
33
34
|
resolveRelease,
|
|
34
35
|
servedFilename,
|
|
36
|
+
serverUrlPrefix,
|
|
35
37
|
shiftMappings,
|
|
36
38
|
snippetLine,
|
|
37
39
|
storedMapJson,
|
|
40
|
+
storedSourcesContent,
|
|
38
41
|
stripSourceMappingUrl,
|
|
39
42
|
uploadDir
|
|
40
|
-
} from "./chunk-
|
|
43
|
+
} from "./chunk-Q23FB5X3.js";
|
|
41
44
|
|
|
42
45
|
// src/verify.ts
|
|
43
46
|
import { existsSync } from "fs";
|
|
@@ -47,6 +50,9 @@ var CHECK_BATCH = 500;
|
|
|
47
50
|
var SNIPPET_ID_RE = /\(g\._autterDebugIds=g\._autterDebugIds\|\|\{\}\)\[s\]="([0-9a-f-]{36})"/;
|
|
48
51
|
var NOT_BUNDLES = [
|
|
49
52
|
[/(^|\/)_(build|ssg|middleware|clientMiddleware)Manifest\.js$/, "Next.js build manifest"],
|
|
53
|
+
// .next/server: middleware-build-manifest.js, next-font-manifest.js,
|
|
54
|
+
// server-reference-manifest.js, page_client-reference-manifest.js, …
|
|
55
|
+
[/(^|\/)[\w.-]*[-_]manifest\.js$/, "Next.js server manifest"],
|
|
50
56
|
[/(^|\/)chunks\/polyfills-[\w-]+\.js$/, "Next.js polyfills, copied prebuilt without a source map"],
|
|
51
57
|
[/(^|\/)(sw|service-worker|serviceWorker|firebase-messaging-sw|mockServiceWorker)\.js$/, "service worker (the browser SDK doesn't run there)"],
|
|
52
58
|
[/(^|\/)workbox-[\w-]+\.js$/, "service worker runtime (the browser SDK doesn't run there)"]
|
|
@@ -98,6 +104,7 @@ async function verifyDir(dir, options = {}) {
|
|
|
98
104
|
ok: true,
|
|
99
105
|
bundles: [],
|
|
100
106
|
maps: [],
|
|
107
|
+
...options.server ? { server: true } : {},
|
|
101
108
|
upload: { status: "unverified", endpoint: null, reason: null, checked: 0, missing: 0 },
|
|
102
109
|
failures: []
|
|
103
110
|
};
|
|
@@ -106,7 +113,7 @@ async function verifyDir(dir, options = {}) {
|
|
|
106
113
|
const path = relPath(file);
|
|
107
114
|
if (file.endsWith(".map")) {
|
|
108
115
|
result.maps.push(path);
|
|
109
|
-
if (!options.allowMaps) {
|
|
116
|
+
if (!options.allowMaps && !options.server) {
|
|
110
117
|
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
118
|
}
|
|
112
119
|
continue;
|
|
@@ -149,14 +156,16 @@ async function verifyDir(dir, options = {}) {
|
|
|
149
156
|
bundle.reasons.push("has the debug id snippet but no //# debugId= comment: run `autter-runtime sourcemaps inject` on it again");
|
|
150
157
|
} else if (!hasDebugIdSnippet(code)) {
|
|
151
158
|
bundle.reasons.push(
|
|
152
|
-
"has a //# debugId= comment but no registration snippet, so the
|
|
159
|
+
"has a //# debugId= comment but no registration snippet, so the SDK can't report its id: run `autter-runtime sourcemaps inject` on it"
|
|
153
160
|
);
|
|
154
161
|
} else if (snippetId && snippetId !== commentId) {
|
|
155
162
|
bundle.reasons.push(`its snippet registers debug id ${snippetId} but its comment says ${commentId}: run inject on the original build output`);
|
|
156
163
|
}
|
|
157
164
|
const url = readSourceMappingUrl(code);
|
|
158
165
|
if (url?.startsWith("data:")) {
|
|
159
|
-
|
|
166
|
+
if (!options.server) {
|
|
167
|
+
bundle.reasons.push("carries an inline source map (data: URL): your original source ships with the bundle. Use hidden or external maps");
|
|
168
|
+
}
|
|
160
169
|
} else if (url && !/^[a-z][\w+.-]*:/i.test(url) && !url.startsWith("/")) {
|
|
161
170
|
let target = url.split(/[?#]/)[0];
|
|
162
171
|
try {
|
|
@@ -265,7 +274,9 @@ function formatVerify(result) {
|
|
|
265
274
|
}
|
|
266
275
|
for (const map of result.maps) {
|
|
267
276
|
const failure = result.failures.find((f) => f.path === map);
|
|
268
|
-
lines.push(
|
|
277
|
+
lines.push(
|
|
278
|
+
failure ? `FAILED ${map}: ${failure.reason}` : result.server ? `note ${map}: source map in the server output (browsers never load it)` : `warning ${map}: source map in the output (allowed by --allow-maps; remove it before deploying)`
|
|
279
|
+
);
|
|
269
280
|
}
|
|
270
281
|
for (const failure of result.failures.filter((f) => f.path === ".")) lines.push(`FAILED ${failure.reason}`);
|
|
271
282
|
const u = result.upload;
|
|
@@ -274,7 +285,7 @@ function formatVerify(result) {
|
|
|
274
285
|
);
|
|
275
286
|
const counted = result.bundles.filter((b) => b.status !== "skipped");
|
|
276
287
|
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}`
|
|
288
|
+
result.ok ? `ok: ${counted.length} bundle(s) with debug ids, ${result.maps.length ? `${result.maps.length} source map(s) left (${result.server ? "server output" : "--allow-maps"})` : "no source maps left"}${u.status === "unverified" ? ", upload not verified" : ""}` : `${result.failures.length} problem(s) in ${result.dir}`
|
|
278
289
|
);
|
|
279
290
|
return lines;
|
|
280
291
|
}
|
|
@@ -306,6 +317,7 @@ export {
|
|
|
306
317
|
hasDebugIdSnippet,
|
|
307
318
|
injectBundle,
|
|
308
319
|
injectDir,
|
|
320
|
+
isInAppSource,
|
|
309
321
|
mapPathFor,
|
|
310
322
|
normalizeDebugId,
|
|
311
323
|
processBuildOutput,
|
|
@@ -314,9 +326,11 @@ export {
|
|
|
314
326
|
resolveEndpoint,
|
|
315
327
|
resolveRelease,
|
|
316
328
|
servedFilename,
|
|
329
|
+
serverUrlPrefix,
|
|
317
330
|
shiftMappings,
|
|
318
331
|
snippetLine,
|
|
319
332
|
storedMapJson,
|
|
333
|
+
storedSourcesContent,
|
|
320
334
|
stripSourceMappingUrl,
|
|
321
335
|
uploadDir,
|
|
322
336
|
verifyDir
|
package/dist/next.cjs
CHANGED
|
@@ -721,9 +721,56 @@ function servedFilename(urlPrefix, path) {
|
|
|
721
721
|
if (!/^[a-z][\w+.-]*:\/\//i.test(prefix) && !prefix.startsWith("/")) prefix = `/${prefix}`;
|
|
722
722
|
return `${prefix.replace(/\/+$/, "")}/${path.replace(/^\/+/, "")}`;
|
|
723
723
|
}
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
724
|
+
var NOT_IN_APP_PATH_PARTS = ["node_modules/", "/site-packages/", "/dist-packages/", "/vendor/", "/.pnpm/"];
|
|
725
|
+
var NOT_IN_APP_PATH_PREFIXES = ["node:", "internal/"];
|
|
726
|
+
var EXTENSION_SCHEMES = ["chrome-extension:", "moz-extension:", "safari-extension:", "safari-web-extension:", "webkit-masked-url:"];
|
|
727
|
+
function isInAppSource(path) {
|
|
728
|
+
if (!path) return true;
|
|
729
|
+
const normalized = path.replace(/\\/g, "/");
|
|
730
|
+
if (NOT_IN_APP_PATH_PARTS.some((part) => normalized.includes(part))) return false;
|
|
731
|
+
if (NOT_IN_APP_PATH_PREFIXES.some((prefix) => normalized.startsWith(prefix))) return false;
|
|
732
|
+
const lower = normalized.toLowerCase();
|
|
733
|
+
return !EXTENSION_SCHEMES.some((scheme) => lower.startsWith(scheme));
|
|
734
|
+
}
|
|
735
|
+
var SOURCES_CONTENT_WRAPPER_BYTES = Buffer.byteLength(',"sourcesContent":[]');
|
|
736
|
+
var NULL_ENTRY_BYTES = 4;
|
|
737
|
+
function storedSourcesContent(fields, baseBytes, limit = MAX_MAP_CHARS) {
|
|
738
|
+
const { sources, sourcesContent } = fields;
|
|
739
|
+
if (!Array.isArray(sources) || !Array.isArray(sourcesContent) || sources.length === 0) return null;
|
|
740
|
+
const ignored = /* @__PURE__ */ new Set();
|
|
741
|
+
for (const list of [fields.ignoreList, fields.x_google_ignoreList]) {
|
|
742
|
+
if (!Array.isArray(list)) continue;
|
|
743
|
+
for (const index of list) if (Number.isInteger(index)) ignored.add(index);
|
|
744
|
+
}
|
|
745
|
+
const count = sources.length;
|
|
746
|
+
const candidates = [];
|
|
747
|
+
for (let index = 0; index < count; index++) {
|
|
748
|
+
const source = sources[index];
|
|
749
|
+
const content = sourcesContent[index];
|
|
750
|
+
if (typeof source !== "string" || typeof content !== "string") continue;
|
|
751
|
+
if (ignored.has(index) || !isInAppSource(source)) continue;
|
|
752
|
+
candidates.push({ index, content, bytes: Buffer.byteLength(JSON.stringify(content)) });
|
|
753
|
+
}
|
|
754
|
+
if (candidates.length === 0) return null;
|
|
755
|
+
candidates.sort((a, b) => a.bytes - b.bytes || a.index - b.index);
|
|
756
|
+
let remaining = limit - baseBytes - SOURCES_CONTENT_WRAPPER_BYTES - NULL_ENTRY_BYTES * count - (count - 1);
|
|
757
|
+
const kept = new Array(count).fill(null);
|
|
758
|
+
let any = false;
|
|
759
|
+
for (const candidate of candidates) {
|
|
760
|
+
const extra = candidate.bytes - NULL_ENTRY_BYTES;
|
|
761
|
+
if (extra > remaining) break;
|
|
762
|
+
remaining -= extra;
|
|
763
|
+
kept[candidate.index] = candidate.content;
|
|
764
|
+
any = true;
|
|
765
|
+
}
|
|
766
|
+
return any ? kept : null;
|
|
767
|
+
}
|
|
768
|
+
function storedMapJson(map, options = {}) {
|
|
769
|
+
const { sourcesContent: _content, ...rest } = map;
|
|
770
|
+
const base = JSON.stringify(rest);
|
|
771
|
+
if (options.sourcesContent === false) return base;
|
|
772
|
+
const content = storedSourcesContent(map, Buffer.byteLength(base));
|
|
773
|
+
return content ? JSON.stringify({ ...rest, sourcesContent: content }) : base;
|
|
727
774
|
}
|
|
728
775
|
function bytesOf(buffer) {
|
|
729
776
|
return new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength);
|
|
@@ -734,7 +781,7 @@ function fits(json, body) {
|
|
|
734
781
|
function uploadBody(release, filename, debugId, json) {
|
|
735
782
|
return `{"release":${JSON.stringify(release)},"filename":${JSON.stringify(filename)},${debugId ? `"debugId":${JSON.stringify(debugId)},` : ""}"map":${json}}`;
|
|
736
783
|
}
|
|
737
|
-
async function prepare(bundle, urlPrefix, release, log, compress) {
|
|
784
|
+
async function prepare(bundle, urlPrefix, release, log, compress, sourcesContent) {
|
|
738
785
|
let map;
|
|
739
786
|
try {
|
|
740
787
|
map = JSON.parse(await (0, import_promises3.readFile)(bundle.map, "utf8"));
|
|
@@ -749,9 +796,10 @@ async function prepare(bundle, urlPrefix, release, log, compress) {
|
|
|
749
796
|
const filename = servedFilename(urlPrefix, bundle.path);
|
|
750
797
|
const { [SCOPES_KEY]: _stale, ...plain } = map;
|
|
751
798
|
const scopes = computeScopes(code, map);
|
|
752
|
-
|
|
799
|
+
const stored = { sourcesContent };
|
|
800
|
+
let json = storedMapJson(plain, stored);
|
|
753
801
|
if ("scopes" in scopes) {
|
|
754
|
-
const scoped = storedMapJson({ ...plain, [SCOPES_KEY]: scopes.scopes });
|
|
802
|
+
const scoped = storedMapJson({ ...plain, [SCOPES_KEY]: scopes.scopes }, stored);
|
|
755
803
|
if (fits(scoped, uploadBody(release, filename, debugId, scoped))) json = scoped;
|
|
756
804
|
else if (fits(json, uploadBody(release, filename, debugId, json))) {
|
|
757
805
|
log(`warning: ${bundle.path}: its map is over 32 MB with function scopes, so it is uploaded without them (frames keep call-site names)`);
|
|
@@ -798,7 +846,7 @@ async function uploadDir(dir, options = {}) {
|
|
|
798
846
|
};
|
|
799
847
|
const items = [];
|
|
800
848
|
for (const bundle of await findBundles(dir, options.files)) {
|
|
801
|
-
const prepared = await prepare(bundle, options.urlPrefix, release, log, !options.dryRun);
|
|
849
|
+
const prepared = await prepare(bundle, options.urlPrefix, release, log, !options.dryRun, options.sourcesContent !== false);
|
|
802
850
|
if ("error" in prepared) {
|
|
803
851
|
summary.failed.push({ path: bundle.path, filename: servedFilename(options.urlPrefix, bundle.path), error: prepared.error });
|
|
804
852
|
} else if (prepared.mapChars > MAX_MAP_CHARS || prepared.bytes > MAX_UPLOAD_BYTES) {
|
|
@@ -917,6 +965,10 @@ function strip(item) {
|
|
|
917
965
|
}
|
|
918
966
|
|
|
919
967
|
// src/build.ts
|
|
968
|
+
function serverUrlPrefix(projectRoot, dir) {
|
|
969
|
+
const rel = (0, import_node_path2.relative)(projectRoot, dir).split(import_node_path2.sep).join("/");
|
|
970
|
+
return !rel || rel.startsWith("..") || (0, import_node_path2.isAbsolute)(rel) ? "/" : `/${rel.replace(/\/+$/, "")}/`;
|
|
971
|
+
}
|
|
920
972
|
function buildKey(options) {
|
|
921
973
|
const key = (options.key ?? process.env.AUTTER_RUNTIME_KEY ?? "").trim();
|
|
922
974
|
return key || null;
|
|
@@ -979,12 +1031,13 @@ async function processBuildOutput(input) {
|
|
|
979
1031
|
result.upload = await uploadDir(input.dir, {
|
|
980
1032
|
files: input.files,
|
|
981
1033
|
release: options.release,
|
|
982
|
-
urlPrefix: options.urlPrefix ?? input.urlPrefix,
|
|
1034
|
+
urlPrefix: input.server ? input.urlPrefix : options.urlPrefix ?? input.urlPrefix,
|
|
983
1035
|
endpoint: options.endpoint,
|
|
984
1036
|
key: key ?? void 0,
|
|
985
1037
|
dryRun: options.dryRun,
|
|
986
1038
|
concurrency: options.concurrency,
|
|
987
1039
|
deleteAfterUpload: options.deleteAfterUpload ?? input.deleteAfterUpload,
|
|
1040
|
+
...options.sourcesContent === false ? { sourcesContent: false } : {},
|
|
988
1041
|
log
|
|
989
1042
|
});
|
|
990
1043
|
for (const line of formatUploadSummary(result.upload)) log(line);
|
|
@@ -1036,6 +1089,11 @@ async function processBuildOutput(input) {
|
|
|
1036
1089
|
// src/webpack.ts
|
|
1037
1090
|
var import_node_path3 = require("path");
|
|
1038
1091
|
var PLUGIN_NAME = "AutterSourceMapsWebpackPlugin";
|
|
1092
|
+
var SERVER_TARGET_RE = /^(?:async-)?node|^electron-(?:main|preload)/;
|
|
1093
|
+
function isServerTarget(target) {
|
|
1094
|
+
const targets = Array.isArray(target) ? target : [target];
|
|
1095
|
+
return targets.some((value) => typeof value === "string" && SERVER_TARGET_RE.test(value));
|
|
1096
|
+
}
|
|
1039
1097
|
var AutterSourceMapsWebpackPlugin = class {
|
|
1040
1098
|
constructor(options = {}, internal = {}) {
|
|
1041
1099
|
this.options = options;
|
|
@@ -1046,6 +1104,8 @@ var AutterSourceMapsWebpackPlugin = class {
|
|
|
1046
1104
|
apply(compiler) {
|
|
1047
1105
|
const mode = compiler.options.mode ?? (process.env.NODE_ENV === "development" ? "development" : void 0);
|
|
1048
1106
|
if (mode === "development") return;
|
|
1107
|
+
const server = this.internal.server ?? isServerTarget(compiler.options.target);
|
|
1108
|
+
if (server && this.options.serverBundles === false) return;
|
|
1049
1109
|
let enabledMaps = this.internal.ownMaps ?? false;
|
|
1050
1110
|
if (!compiler.options.devtool) {
|
|
1051
1111
|
if (shouldGenerateMaps(this.options)) {
|
|
@@ -1059,7 +1119,7 @@ var AutterSourceMapsWebpackPlugin = class {
|
|
|
1059
1119
|
const dir = compilation.outputOptions.path ?? compiler.outputPath;
|
|
1060
1120
|
if (!dir) return;
|
|
1061
1121
|
const publicPath = compilation.outputOptions.publicPath;
|
|
1062
|
-
const urlPrefix = typeof publicPath === "string" && publicPath !== "auto" && publicPath !== "" ? publicPath : "/";
|
|
1122
|
+
const urlPrefix = server ? serverUrlPrefix(compiler.context ?? process.cwd(), dir) : typeof publicPath === "string" && publicPath !== "auto" && publicPath !== "" ? publicPath : "/";
|
|
1063
1123
|
const assets = compilation.getAssets().map((asset) => asset.name);
|
|
1064
1124
|
const files = assets.filter((name) => BUNDLE_RE.test(name)).map((name) => (0, import_node_path3.resolve)(dir, name));
|
|
1065
1125
|
const maps = assets.filter((name) => name.endsWith(".map")).map((name) => (0, import_node_path3.resolve)(dir, name));
|
|
@@ -1070,7 +1130,8 @@ var AutterSourceMapsWebpackPlugin = class {
|
|
|
1070
1130
|
urlPrefix,
|
|
1071
1131
|
options: this.options,
|
|
1072
1132
|
deleteAfterUpload: enabledMaps,
|
|
1073
|
-
ownMaps: enabledMaps
|
|
1133
|
+
ownMaps: enabledMaps,
|
|
1134
|
+
...server ? { server: true } : {}
|
|
1074
1135
|
});
|
|
1075
1136
|
});
|
|
1076
1137
|
}
|
|
@@ -1099,6 +1160,10 @@ function wrapConfig(config, options) {
|
|
|
1099
1160
|
const publicMaps = config.productionBrowserSourceMaps === true;
|
|
1100
1161
|
const ownMaps = !publicMaps && shouldGenerateMaps(options);
|
|
1101
1162
|
const deleteAfterUpload = options.deleteAfterUpload ?? !publicMaps;
|
|
1163
|
+
const serverBundles = options.serverBundles !== false;
|
|
1164
|
+
const userServerMaps = config.experimental?.serverSourceMaps !== void 0;
|
|
1165
|
+
const ownServerMaps = serverBundles && !userServerMaps && shouldGenerateMaps(options);
|
|
1166
|
+
let serverDevtoolPreset = false;
|
|
1102
1167
|
let notified = false;
|
|
1103
1168
|
const notifyNoMaps = () => {
|
|
1104
1169
|
if (!publicMaps && !ownMaps && !notified) {
|
|
@@ -1113,8 +1178,10 @@ function wrapConfig(config, options) {
|
|
|
1113
1178
|
const wrapped = {
|
|
1114
1179
|
...config,
|
|
1115
1180
|
webpack(webpackConfig, context) {
|
|
1181
|
+
const nextDevtool = webpackConfig.devtool;
|
|
1116
1182
|
const result = typeof userWebpack === "function" ? userWebpack(webpackConfig, context) : webpackConfig;
|
|
1117
|
-
if (
|
|
1183
|
+
if (context.dev) return result;
|
|
1184
|
+
if (!context.isServer) {
|
|
1118
1185
|
if (ownMaps) result.devtool = "hidden-source-map";
|
|
1119
1186
|
if (!useHook) {
|
|
1120
1187
|
result.plugins = [
|
|
@@ -1125,18 +1192,35 @@ function wrapConfig(config, options) {
|
|
|
1125
1192
|
)
|
|
1126
1193
|
];
|
|
1127
1194
|
}
|
|
1195
|
+
return result;
|
|
1196
|
+
}
|
|
1197
|
+
if (!serverBundles) return result;
|
|
1198
|
+
const preset = Boolean(result.devtool) && (result.devtool !== nextDevtool || !ownServerMaps);
|
|
1199
|
+
if (preset) serverDevtoolPreset = true;
|
|
1200
|
+
const turnedOn = !preset && ownServerMaps;
|
|
1201
|
+
if (turnedOn) result.devtool = "hidden-source-map";
|
|
1202
|
+
if (!useHook && (turnedOn || preset)) {
|
|
1203
|
+
result.plugins = [
|
|
1204
|
+
...result.plugins ?? [],
|
|
1205
|
+
new AutterSourceMapsWebpackPlugin(
|
|
1206
|
+
{ ...options, deleteAfterUpload: options.deleteAfterUpload ?? turnedOn },
|
|
1207
|
+
{ ownMaps: turnedOn, server: true }
|
|
1208
|
+
)
|
|
1209
|
+
];
|
|
1128
1210
|
}
|
|
1129
1211
|
return result;
|
|
1130
1212
|
}
|
|
1131
1213
|
};
|
|
1132
1214
|
if (useHook) {
|
|
1133
1215
|
if (ownMaps) wrapped.productionBrowserSourceMaps = true;
|
|
1216
|
+
if (ownServerMaps) wrapped.experimental = { ...config.experimental, serverSourceMaps: true };
|
|
1134
1217
|
const userHook = config.compiler?.runAfterProductionCompile;
|
|
1135
1218
|
wrapped.compiler = {
|
|
1136
1219
|
...config.compiler,
|
|
1137
1220
|
async runAfterProductionCompile(ctx = {}) {
|
|
1138
1221
|
if (typeof userHook === "function") await userHook(ctx);
|
|
1139
|
-
const
|
|
1222
|
+
const projectDir = ctx.projectDir ?? process.cwd();
|
|
1223
|
+
const distDir = ctx.distDir ?? (0, import_node_path4.resolve)(projectDir, String(config.distDir ?? ".next"));
|
|
1140
1224
|
const staticDir = (0, import_node_path4.join)(distDir, "static");
|
|
1141
1225
|
notifyNoMaps();
|
|
1142
1226
|
await processBuildOutput({
|
|
@@ -1149,6 +1233,19 @@ function wrapConfig(config, options) {
|
|
|
1149
1233
|
// Every client map (JS and CSS): .next/static is deployed as is.
|
|
1150
1234
|
maps: ownMaps ? await findMapFiles(staticDir) : void 0
|
|
1151
1235
|
});
|
|
1236
|
+
if (!serverBundles) return;
|
|
1237
|
+
const serverDir = (0, import_node_path4.join)(distDir, "server");
|
|
1238
|
+
const ownServer = ownServerMaps && !serverDevtoolPreset;
|
|
1239
|
+
await processBuildOutput({
|
|
1240
|
+
dir: serverDir,
|
|
1241
|
+
urlPrefix: serverUrlPrefix(projectDir, serverDir),
|
|
1242
|
+
options: { ...options, deleteAfterUpload: options.deleteAfterUpload ?? ownServer },
|
|
1243
|
+
deleteAfterUpload: ownServer,
|
|
1244
|
+
stripSourceMappingUrl: ownServer,
|
|
1245
|
+
ownMaps: ownServer,
|
|
1246
|
+
maps: ownServer ? await findMapFiles(serverDir) : void 0,
|
|
1247
|
+
server: true
|
|
1248
|
+
});
|
|
1152
1249
|
}
|
|
1153
1250
|
};
|
|
1154
1251
|
}
|
package/dist/next.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as AutterSourceMapsOptions } from './build-
|
|
1
|
+
import { A as AutterSourceMapsOptions } from './build-DGeoDkTh.cjs';
|
|
2
2
|
|
|
3
3
|
type NextConfigObject = Record<string, any>;
|
|
4
4
|
type NextConfigFunction = (phase: string, context: {
|
|
@@ -10,8 +10,11 @@ declare function installedNextVersion(cwd?: string): string | null;
|
|
|
10
10
|
* Next.js config wrapper: hidden source maps for client production builds,
|
|
11
11
|
* debug ids injected into every client chunk, maps uploaded after the build
|
|
12
12
|
* when AUTTER_RUNTIME_KEY (or `key`) is set, then deleted whatever the
|
|
13
|
-
* upload's outcome (without a key, no maps are turned on at all).
|
|
14
|
-
*
|
|
13
|
+
* upload's outcome (without a key, no maps are turned on at all). The server
|
|
14
|
+
* output (`.next/server`, Node and edge) gets the same, stored under
|
|
15
|
+
* `/.next/server/` (RF-05; `serverBundles: false` leaves it alone). Works
|
|
16
|
+
* with webpack builds, and with Turbopack builds on Next.js 15.4.1+
|
|
17
|
+
* (`compiler.runAfterProductionCompile`).
|
|
15
18
|
*
|
|
16
19
|
* ```js
|
|
17
20
|
* // next.config.mjs
|
package/dist/next.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as AutterSourceMapsOptions } from './build-
|
|
1
|
+
import { A as AutterSourceMapsOptions } from './build-DGeoDkTh.js';
|
|
2
2
|
|
|
3
3
|
type NextConfigObject = Record<string, any>;
|
|
4
4
|
type NextConfigFunction = (phase: string, context: {
|
|
@@ -10,8 +10,11 @@ declare function installedNextVersion(cwd?: string): string | null;
|
|
|
10
10
|
* Next.js config wrapper: hidden source maps for client production builds,
|
|
11
11
|
* debug ids injected into every client chunk, maps uploaded after the build
|
|
12
12
|
* when AUTTER_RUNTIME_KEY (or `key`) is set, then deleted whatever the
|
|
13
|
-
* upload's outcome (without a key, no maps are turned on at all).
|
|
14
|
-
*
|
|
13
|
+
* upload's outcome (without a key, no maps are turned on at all). The server
|
|
14
|
+
* output (`.next/server`, Node and edge) gets the same, stored under
|
|
15
|
+
* `/.next/server/` (RF-05; `serverBundles: false` leaves it alone). Works
|
|
16
|
+
* with webpack builds, and with Turbopack builds on Next.js 15.4.1+
|
|
17
|
+
* (`compiler.runAfterProductionCompile`).
|
|
15
18
|
*
|
|
16
19
|
* ```js
|
|
17
20
|
* // next.config.mjs
|
package/dist/next.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AutterSourceMapsWebpackPlugin
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-V66S2YHN.js";
|
|
4
4
|
import {
|
|
5
5
|
findMapFiles,
|
|
6
6
|
logMapsNotGenerated,
|
|
7
7
|
processBuildOutput,
|
|
8
|
+
serverUrlPrefix,
|
|
8
9
|
shouldGenerateMaps
|
|
9
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-Q23FB5X3.js";
|
|
10
11
|
|
|
11
12
|
// src/next.ts
|
|
12
13
|
import { createRequire } from "module";
|
|
@@ -33,6 +34,10 @@ function wrapConfig(config, options) {
|
|
|
33
34
|
const publicMaps = config.productionBrowserSourceMaps === true;
|
|
34
35
|
const ownMaps = !publicMaps && shouldGenerateMaps(options);
|
|
35
36
|
const deleteAfterUpload = options.deleteAfterUpload ?? !publicMaps;
|
|
37
|
+
const serverBundles = options.serverBundles !== false;
|
|
38
|
+
const userServerMaps = config.experimental?.serverSourceMaps !== void 0;
|
|
39
|
+
const ownServerMaps = serverBundles && !userServerMaps && shouldGenerateMaps(options);
|
|
40
|
+
let serverDevtoolPreset = false;
|
|
36
41
|
let notified = false;
|
|
37
42
|
const notifyNoMaps = () => {
|
|
38
43
|
if (!publicMaps && !ownMaps && !notified) {
|
|
@@ -47,8 +52,10 @@ function wrapConfig(config, options) {
|
|
|
47
52
|
const wrapped = {
|
|
48
53
|
...config,
|
|
49
54
|
webpack(webpackConfig, context) {
|
|
55
|
+
const nextDevtool = webpackConfig.devtool;
|
|
50
56
|
const result = typeof userWebpack === "function" ? userWebpack(webpackConfig, context) : webpackConfig;
|
|
51
|
-
if (
|
|
57
|
+
if (context.dev) return result;
|
|
58
|
+
if (!context.isServer) {
|
|
52
59
|
if (ownMaps) result.devtool = "hidden-source-map";
|
|
53
60
|
if (!useHook) {
|
|
54
61
|
result.plugins = [
|
|
@@ -59,18 +66,35 @@ function wrapConfig(config, options) {
|
|
|
59
66
|
)
|
|
60
67
|
];
|
|
61
68
|
}
|
|
69
|
+
return result;
|
|
70
|
+
}
|
|
71
|
+
if (!serverBundles) return result;
|
|
72
|
+
const preset = Boolean(result.devtool) && (result.devtool !== nextDevtool || !ownServerMaps);
|
|
73
|
+
if (preset) serverDevtoolPreset = true;
|
|
74
|
+
const turnedOn = !preset && ownServerMaps;
|
|
75
|
+
if (turnedOn) result.devtool = "hidden-source-map";
|
|
76
|
+
if (!useHook && (turnedOn || preset)) {
|
|
77
|
+
result.plugins = [
|
|
78
|
+
...result.plugins ?? [],
|
|
79
|
+
new AutterSourceMapsWebpackPlugin(
|
|
80
|
+
{ ...options, deleteAfterUpload: options.deleteAfterUpload ?? turnedOn },
|
|
81
|
+
{ ownMaps: turnedOn, server: true }
|
|
82
|
+
)
|
|
83
|
+
];
|
|
62
84
|
}
|
|
63
85
|
return result;
|
|
64
86
|
}
|
|
65
87
|
};
|
|
66
88
|
if (useHook) {
|
|
67
89
|
if (ownMaps) wrapped.productionBrowserSourceMaps = true;
|
|
90
|
+
if (ownServerMaps) wrapped.experimental = { ...config.experimental, serverSourceMaps: true };
|
|
68
91
|
const userHook = config.compiler?.runAfterProductionCompile;
|
|
69
92
|
wrapped.compiler = {
|
|
70
93
|
...config.compiler,
|
|
71
94
|
async runAfterProductionCompile(ctx = {}) {
|
|
72
95
|
if (typeof userHook === "function") await userHook(ctx);
|
|
73
|
-
const
|
|
96
|
+
const projectDir = ctx.projectDir ?? process.cwd();
|
|
97
|
+
const distDir = ctx.distDir ?? resolve(projectDir, String(config.distDir ?? ".next"));
|
|
74
98
|
const staticDir = join(distDir, "static");
|
|
75
99
|
notifyNoMaps();
|
|
76
100
|
await processBuildOutput({
|
|
@@ -83,6 +107,19 @@ function wrapConfig(config, options) {
|
|
|
83
107
|
// Every client map (JS and CSS): .next/static is deployed as is.
|
|
84
108
|
maps: ownMaps ? await findMapFiles(staticDir) : void 0
|
|
85
109
|
});
|
|
110
|
+
if (!serverBundles) return;
|
|
111
|
+
const serverDir = join(distDir, "server");
|
|
112
|
+
const ownServer = ownServerMaps && !serverDevtoolPreset;
|
|
113
|
+
await processBuildOutput({
|
|
114
|
+
dir: serverDir,
|
|
115
|
+
urlPrefix: serverUrlPrefix(projectDir, serverDir),
|
|
116
|
+
options: { ...options, deleteAfterUpload: options.deleteAfterUpload ?? ownServer },
|
|
117
|
+
deleteAfterUpload: ownServer,
|
|
118
|
+
stripSourceMappingUrl: ownServer,
|
|
119
|
+
ownMaps: ownServer,
|
|
120
|
+
maps: ownServer ? await findMapFiles(serverDir) : void 0,
|
|
121
|
+
server: true
|
|
122
|
+
});
|
|
86
123
|
}
|
|
87
124
|
};
|
|
88
125
|
}
|
package/dist/vite.cjs
CHANGED
|
@@ -714,9 +714,56 @@ function servedFilename(urlPrefix, path) {
|
|
|
714
714
|
if (!/^[a-z][\w+.-]*:\/\//i.test(prefix) && !prefix.startsWith("/")) prefix = `/${prefix}`;
|
|
715
715
|
return `${prefix.replace(/\/+$/, "")}/${path.replace(/^\/+/, "")}`;
|
|
716
716
|
}
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
717
|
+
var NOT_IN_APP_PATH_PARTS = ["node_modules/", "/site-packages/", "/dist-packages/", "/vendor/", "/.pnpm/"];
|
|
718
|
+
var NOT_IN_APP_PATH_PREFIXES = ["node:", "internal/"];
|
|
719
|
+
var EXTENSION_SCHEMES = ["chrome-extension:", "moz-extension:", "safari-extension:", "safari-web-extension:", "webkit-masked-url:"];
|
|
720
|
+
function isInAppSource(path) {
|
|
721
|
+
if (!path) return true;
|
|
722
|
+
const normalized = path.replace(/\\/g, "/");
|
|
723
|
+
if (NOT_IN_APP_PATH_PARTS.some((part) => normalized.includes(part))) return false;
|
|
724
|
+
if (NOT_IN_APP_PATH_PREFIXES.some((prefix) => normalized.startsWith(prefix))) return false;
|
|
725
|
+
const lower = normalized.toLowerCase();
|
|
726
|
+
return !EXTENSION_SCHEMES.some((scheme) => lower.startsWith(scheme));
|
|
727
|
+
}
|
|
728
|
+
var SOURCES_CONTENT_WRAPPER_BYTES = Buffer.byteLength(',"sourcesContent":[]');
|
|
729
|
+
var NULL_ENTRY_BYTES = 4;
|
|
730
|
+
function storedSourcesContent(fields, baseBytes, limit = MAX_MAP_CHARS) {
|
|
731
|
+
const { sources, sourcesContent } = fields;
|
|
732
|
+
if (!Array.isArray(sources) || !Array.isArray(sourcesContent) || sources.length === 0) return null;
|
|
733
|
+
const ignored = /* @__PURE__ */ new Set();
|
|
734
|
+
for (const list of [fields.ignoreList, fields.x_google_ignoreList]) {
|
|
735
|
+
if (!Array.isArray(list)) continue;
|
|
736
|
+
for (const index of list) if (Number.isInteger(index)) ignored.add(index);
|
|
737
|
+
}
|
|
738
|
+
const count = sources.length;
|
|
739
|
+
const candidates = [];
|
|
740
|
+
for (let index = 0; index < count; index++) {
|
|
741
|
+
const source = sources[index];
|
|
742
|
+
const content = sourcesContent[index];
|
|
743
|
+
if (typeof source !== "string" || typeof content !== "string") continue;
|
|
744
|
+
if (ignored.has(index) || !isInAppSource(source)) continue;
|
|
745
|
+
candidates.push({ index, content, bytes: Buffer.byteLength(JSON.stringify(content)) });
|
|
746
|
+
}
|
|
747
|
+
if (candidates.length === 0) return null;
|
|
748
|
+
candidates.sort((a, b) => a.bytes - b.bytes || a.index - b.index);
|
|
749
|
+
let remaining = limit - baseBytes - SOURCES_CONTENT_WRAPPER_BYTES - NULL_ENTRY_BYTES * count - (count - 1);
|
|
750
|
+
const kept = new Array(count).fill(null);
|
|
751
|
+
let any = false;
|
|
752
|
+
for (const candidate of candidates) {
|
|
753
|
+
const extra = candidate.bytes - NULL_ENTRY_BYTES;
|
|
754
|
+
if (extra > remaining) break;
|
|
755
|
+
remaining -= extra;
|
|
756
|
+
kept[candidate.index] = candidate.content;
|
|
757
|
+
any = true;
|
|
758
|
+
}
|
|
759
|
+
return any ? kept : null;
|
|
760
|
+
}
|
|
761
|
+
function storedMapJson(map, options = {}) {
|
|
762
|
+
const { sourcesContent: _content, ...rest } = map;
|
|
763
|
+
const base = JSON.stringify(rest);
|
|
764
|
+
if (options.sourcesContent === false) return base;
|
|
765
|
+
const content = storedSourcesContent(map, Buffer.byteLength(base));
|
|
766
|
+
return content ? JSON.stringify({ ...rest, sourcesContent: content }) : base;
|
|
720
767
|
}
|
|
721
768
|
function bytesOf(buffer) {
|
|
722
769
|
return new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength);
|
|
@@ -727,7 +774,7 @@ function fits(json, body) {
|
|
|
727
774
|
function uploadBody(release, filename, debugId, json) {
|
|
728
775
|
return `{"release":${JSON.stringify(release)},"filename":${JSON.stringify(filename)},${debugId ? `"debugId":${JSON.stringify(debugId)},` : ""}"map":${json}}`;
|
|
729
776
|
}
|
|
730
|
-
async function prepare(bundle, urlPrefix, release, log, compress) {
|
|
777
|
+
async function prepare(bundle, urlPrefix, release, log, compress, sourcesContent) {
|
|
731
778
|
let map;
|
|
732
779
|
try {
|
|
733
780
|
map = JSON.parse(await (0, import_promises3.readFile)(bundle.map, "utf8"));
|
|
@@ -742,9 +789,10 @@ async function prepare(bundle, urlPrefix, release, log, compress) {
|
|
|
742
789
|
const filename = servedFilename(urlPrefix, bundle.path);
|
|
743
790
|
const { [SCOPES_KEY]: _stale, ...plain } = map;
|
|
744
791
|
const scopes = computeScopes(code, map);
|
|
745
|
-
|
|
792
|
+
const stored = { sourcesContent };
|
|
793
|
+
let json = storedMapJson(plain, stored);
|
|
746
794
|
if ("scopes" in scopes) {
|
|
747
|
-
const scoped = storedMapJson({ ...plain, [SCOPES_KEY]: scopes.scopes });
|
|
795
|
+
const scoped = storedMapJson({ ...plain, [SCOPES_KEY]: scopes.scopes }, stored);
|
|
748
796
|
if (fits(scoped, uploadBody(release, filename, debugId, scoped))) json = scoped;
|
|
749
797
|
else if (fits(json, uploadBody(release, filename, debugId, json))) {
|
|
750
798
|
log(`warning: ${bundle.path}: its map is over 32 MB with function scopes, so it is uploaded without them (frames keep call-site names)`);
|
|
@@ -791,7 +839,7 @@ async function uploadDir(dir, options = {}) {
|
|
|
791
839
|
};
|
|
792
840
|
const items = [];
|
|
793
841
|
for (const bundle of await findBundles(dir, options.files)) {
|
|
794
|
-
const prepared = await prepare(bundle, options.urlPrefix, release, log, !options.dryRun);
|
|
842
|
+
const prepared = await prepare(bundle, options.urlPrefix, release, log, !options.dryRun, options.sourcesContent !== false);
|
|
795
843
|
if ("error" in prepared) {
|
|
796
844
|
summary.failed.push({ path: bundle.path, filename: servedFilename(options.urlPrefix, bundle.path), error: prepared.error });
|
|
797
845
|
} else if (prepared.mapChars > MAX_MAP_CHARS || prepared.bytes > MAX_UPLOAD_BYTES) {
|
|
@@ -910,6 +958,10 @@ function strip(item) {
|
|
|
910
958
|
}
|
|
911
959
|
|
|
912
960
|
// src/build.ts
|
|
961
|
+
function serverUrlPrefix(projectRoot, dir) {
|
|
962
|
+
const rel = (0, import_node_path2.relative)(projectRoot, dir).split(import_node_path2.sep).join("/");
|
|
963
|
+
return !rel || rel.startsWith("..") || (0, import_node_path2.isAbsolute)(rel) ? "/" : `/${rel.replace(/\/+$/, "")}/`;
|
|
964
|
+
}
|
|
913
965
|
function buildKey(options) {
|
|
914
966
|
const key = (options.key ?? process.env.AUTTER_RUNTIME_KEY ?? "").trim();
|
|
915
967
|
return key || null;
|
|
@@ -972,12 +1024,13 @@ async function processBuildOutput(input) {
|
|
|
972
1024
|
result.upload = await uploadDir(input.dir, {
|
|
973
1025
|
files: input.files,
|
|
974
1026
|
release: options.release,
|
|
975
|
-
urlPrefix: options.urlPrefix ?? input.urlPrefix,
|
|
1027
|
+
urlPrefix: input.server ? input.urlPrefix : options.urlPrefix ?? input.urlPrefix,
|
|
976
1028
|
endpoint: options.endpoint,
|
|
977
1029
|
key: key ?? void 0,
|
|
978
1030
|
dryRun: options.dryRun,
|
|
979
1031
|
concurrency: options.concurrency,
|
|
980
1032
|
deleteAfterUpload: options.deleteAfterUpload ?? input.deleteAfterUpload,
|
|
1033
|
+
...options.sourcesContent === false ? { sourcesContent: false } : {},
|
|
981
1034
|
log
|
|
982
1035
|
});
|
|
983
1036
|
for (const line of formatUploadSummary(result.upload)) log(line);
|
|
@@ -1032,6 +1085,8 @@ function autterSourceMaps(options = {}) {
|
|
|
1032
1085
|
let enabledMaps = false;
|
|
1033
1086
|
let ssr = false;
|
|
1034
1087
|
let base = "/";
|
|
1088
|
+
let root = process.cwd();
|
|
1089
|
+
const serverBundles = options.serverBundles !== false;
|
|
1035
1090
|
return {
|
|
1036
1091
|
name: "autter-runtime-sourcemaps",
|
|
1037
1092
|
apply: "build",
|
|
@@ -1039,7 +1094,7 @@ function autterSourceMaps(options = {}) {
|
|
|
1039
1094
|
config(config) {
|
|
1040
1095
|
isVite = true;
|
|
1041
1096
|
const current = config.build?.sourcemap;
|
|
1042
|
-
if ((current === void 0 || current === false) && !config.build?.ssr) {
|
|
1097
|
+
if ((current === void 0 || current === false) && (serverBundles || !config.build?.ssr)) {
|
|
1043
1098
|
if (!shouldGenerateMaps(options)) {
|
|
1044
1099
|
logMapsNotGenerated(options);
|
|
1045
1100
|
return void 0;
|
|
@@ -1051,6 +1106,7 @@ function autterSourceMaps(options = {}) {
|
|
|
1051
1106
|
},
|
|
1052
1107
|
configResolved(config) {
|
|
1053
1108
|
ssr = Boolean(config.build?.ssr);
|
|
1109
|
+
if (config.root) root = config.root;
|
|
1054
1110
|
if (config.base && /^(\/|[a-z][\w+.-]*:\/\/)/i.test(config.base)) base = config.base;
|
|
1055
1111
|
if (config.build?.sourcemap === "inline" && !options.silent) {
|
|
1056
1112
|
console.warn('[autter-runtime] build.sourcemap is "inline": there are no map files to upload; use "hidden"');
|
|
@@ -1069,8 +1125,23 @@ function autterSourceMaps(options = {}) {
|
|
|
1069
1125
|
const dir = output.dir ?? (output.file ? (0, import_node_path3.dirname)(output.file) : void 0);
|
|
1070
1126
|
if (!dir) return;
|
|
1071
1127
|
const maps = Object.values(bundle).filter((file) => file.fileName.endsWith(".map")).map((file) => (0, import_node_path3.resolve)(dir, file.fileName));
|
|
1128
|
+
const files = Object.values(bundle).filter((file) => file.type === "chunk").map((file) => (0, import_node_path3.resolve)(dir, file.fileName));
|
|
1072
1129
|
const environment = this?.environment;
|
|
1073
|
-
|
|
1130
|
+
const server = ssr || environment?.config?.consumer === "server";
|
|
1131
|
+
if (server && serverBundles) {
|
|
1132
|
+
await processBuildOutput({
|
|
1133
|
+
dir,
|
|
1134
|
+
files,
|
|
1135
|
+
maps,
|
|
1136
|
+
urlPrefix: serverUrlPrefix(root, dir),
|
|
1137
|
+
options,
|
|
1138
|
+
deleteAfterUpload: enabledMaps,
|
|
1139
|
+
ownMaps: enabledMaps,
|
|
1140
|
+
server: true
|
|
1141
|
+
});
|
|
1142
|
+
return;
|
|
1143
|
+
}
|
|
1144
|
+
if (server) {
|
|
1074
1145
|
if (enabledMaps && options.deleteAfterUpload !== false) {
|
|
1075
1146
|
try {
|
|
1076
1147
|
const removed = await removeSourceMaps(maps);
|
|
@@ -1083,7 +1154,6 @@ function autterSourceMaps(options = {}) {
|
|
|
1083
1154
|
}
|
|
1084
1155
|
return;
|
|
1085
1156
|
}
|
|
1086
|
-
const files = Object.values(bundle).filter((file) => file.type === "chunk").map((file) => (0, import_node_path3.resolve)(dir, file.fileName));
|
|
1087
1157
|
await processBuildOutput({
|
|
1088
1158
|
dir,
|
|
1089
1159
|
files,
|