@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/README.md
CHANGED
|
@@ -2,18 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
Readable stack traces for Autter Runtime. Gives every JS bundle a
|
|
4
4
|
content-addressed **debug id** and uploads its **source map** to the ingester,
|
|
5
|
-
so minified browser frames
|
|
5
|
+
so minified browser frames and bundled Node and edge frames resolve to your
|
|
6
|
+
original source, with the lines around each frame of your code, even when the
|
|
6
7
|
release your SDK reports doesn't match the upload.
|
|
7
8
|
|
|
8
9
|
- `autter-runtime sourcemaps setup` wires it into a project; `verify` checks a build
|
|
9
|
-
- `autter-runtime sourcemaps inject <dir>` / `upload <dir>` CLI
|
|
10
|
-
|
|
11
|
-
-
|
|
10
|
+
- `autter-runtime sourcemaps inject <dir>` / `upload <dir>` CLI, for browser
|
|
11
|
+
and server output alike (tsup, esbuild, a Worker)
|
|
12
|
+
- Vite/Rollup plugin: `@autter/runtime-cli/vite` (SSR builds and server
|
|
13
|
+
environments too)
|
|
14
|
+
- webpack 5 plugin: `@autter/runtime-cli/webpack` (Node targets too)
|
|
12
15
|
- Next.js wrapper: `withAutterSourceMaps` from `@autter/runtime-cli/next`
|
|
16
|
+
(client and `.next/server` output)
|
|
13
17
|
|
|
14
18
|
Bundlers are optional peer dependencies. Debug ids need ingester 1.6.0+ and
|
|
15
19
|
`@autter/runtime-browser` 1.6.0+ (older ingesters still match `.js` maps by
|
|
16
|
-
release + path).
|
|
20
|
+
release + path). Server bundles and source contents need the current
|
|
21
|
+
ingester. Full guide: [docs/SOURCE-MAPS.md](../../docs/SOURCE-MAPS.md).
|
|
17
22
|
|
|
18
23
|
## Quick start (people and coding agents)
|
|
19
24
|
|
|
@@ -66,8 +71,10 @@ and, when `AUTTER_RUNTIME_KEY` is set, every bundle's map is on the ingester
|
|
|
66
71
|
local checks still run and the upload is reported as unverified. Files copied
|
|
67
72
|
unchanged from `public/`, Next.js build manifests and polyfills, and service workers are
|
|
68
73
|
skipped; `--ignore <glob>` skips more. `--allow-maps` reports leftover maps
|
|
69
|
-
without failing. `--
|
|
70
|
-
|
|
74
|
+
without failing. `--server` checks server output (a tsup or esbuild `dist/`,
|
|
75
|
+
`.next/server`), where leftover maps are a note, not a failure, and Next.js
|
|
76
|
+
server manifests are skipped. `--json` for machines; exit `1` on any failure,
|
|
77
|
+
with the reason per file.
|
|
71
78
|
|
|
72
79
|
## Keys
|
|
73
80
|
|
|
@@ -114,10 +121,20 @@ All three turn on hidden source maps when you haven't configured maps, inject
|
|
|
114
121
|
debug ids after the build, upload when a key is present, and then delete the
|
|
115
122
|
maps they created whether or not the upload succeeded (a rejected upload, an
|
|
116
123
|
unreachable ingester, a dry run), printing one line that says why; without a
|
|
117
|
-
key they turn none on. Maps you configured yourself are left alone.
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
124
|
+
key they turn none on. Maps you configured yourself are left alone.
|
|
125
|
+
|
|
126
|
+
Server bundles get the same: Vite SSR builds and Vite 6 server environments,
|
|
127
|
+
webpack builds for a Node target, and Next.js `.next/server` (Node and edge,
|
|
128
|
+
webpack and Turbopack). Their maps are stored under the output directory's
|
|
129
|
+
path in the project (`/dist/server/`, `/.next/server/`), which the ingester
|
|
130
|
+
matches against the path the server runs them from, never under the public
|
|
131
|
+
URL prefix.
|
|
132
|
+
|
|
133
|
+
Options (all optional): `release`, `urlPrefix`, `endpoint`, `key`,
|
|
134
|
+
`upload: false`, `deleteAfterUpload`, `dryRun`, `concurrency`, `failOnError`
|
|
135
|
+
(default `false`: a failed upload is logged and never fails the build),
|
|
136
|
+
`silent`, `sourcesContent: false` (upload maps without your files' source),
|
|
137
|
+
`serverBundles: false` (leave server output exactly as the bundler wrote it).
|
|
121
138
|
|
|
122
139
|
## CLI
|
|
123
140
|
|
|
@@ -125,28 +142,40 @@ never fails the build), `silent`.
|
|
|
125
142
|
npx autter-runtime sourcemaps inject dist
|
|
126
143
|
npx autter-runtime sourcemaps upload dist --url-prefix / --release "$GIT_SHA"
|
|
127
144
|
npx autter-runtime sourcemaps upload dist --dry-run
|
|
145
|
+
|
|
146
|
+
# A bundled Node server (tsup, esbuild): the same commands
|
|
147
|
+
npx autter-runtime sourcemaps inject dist
|
|
148
|
+
npx autter-runtime sourcemaps upload dist --url-prefix /dist/
|
|
149
|
+
npx autter-runtime sourcemaps verify dist --server
|
|
128
150
|
```
|
|
129
151
|
|
|
130
152
|
```
|
|
131
153
|
autter-runtime sourcemaps setup [dir] [--dry-run] [--install] [--json]
|
|
132
154
|
autter-runtime sourcemaps verify <dir> [--endpoint <url>] [--url-prefix <prefix>]
|
|
133
|
-
[--ignore <glob>]... [--allow-maps] [--json]
|
|
155
|
+
[--ignore <glob>]... [--allow-maps] [--server] [--json]
|
|
134
156
|
autter-runtime sourcemaps inject <dir> [--dry-run] [--json]
|
|
135
157
|
autter-runtime sourcemaps upload <dir> [--release <r>] [--url-prefix <prefix>]
|
|
136
158
|
[--endpoint <url>] [--concurrency <n>] [--delete-after-upload]
|
|
137
|
-
[--best-effort] [--dry-run] [--json]
|
|
159
|
+
[--no-sources-content] [--best-effort] [--dry-run] [--json]
|
|
138
160
|
```
|
|
139
161
|
|
|
140
162
|
- **inject** writes `//# debugId=<id>`, a one-line snippet that registers
|
|
141
163
|
`globalThis._autterDebugIds[new Error().stack] = "<id>"`, and `"debugId"` in
|
|
142
164
|
the `.map`, for each `.js`/`.mjs`/`.cjs` with a map. The id is derived from
|
|
143
|
-
sha256 of the bundle bytes; running it again changes nothing.
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
165
|
+
sha256 of the bundle bytes; running it again changes nothing. The browser
|
|
166
|
+
SDK and the Node and edge SDKs read the snippet's registry and send the ids
|
|
167
|
+
of the bundles in each exception's stack.
|
|
168
|
+
- **upload** posts each map (gzipped, up to 32 MB) to
|
|
169
|
+
`<endpoint>/v1/sourcemaps`, in parallel, skipping maps the ingester already
|
|
170
|
+
has. Each map carries the bundle's function scopes (`x_autter_scopes`),
|
|
147
171
|
parsed from the file as served, so frames are named after the function they
|
|
148
172
|
are in rather than their call site; a bundle that does not parse is uploaded
|
|
149
|
-
without them, with a warning.
|
|
173
|
+
without them, with a warning. It also carries the original source of your own
|
|
174
|
+
files (`sourcesContent`; never your dependencies', whole files only, as many
|
|
175
|
+
as fit the 32 MB limit), so issues show the lines around each frame;
|
|
176
|
+
`--no-sources-content` leaves it out. For server output, `--url-prefix` is
|
|
177
|
+
any tail of the path the server runs the files from (`/dist/` for
|
|
178
|
+
`/app/dist/server.js`), or `/`. Release: `--release`, else `GITHUB_SHA`,
|
|
150
179
|
`VERCEL_GIT_COMMIT_SHA`, `CF_PAGES_COMMIT_SHA`, `GIT_SHA`, then
|
|
151
180
|
`git rev-parse HEAD`.
|
|
152
181
|
- **upload --best-effort** is for build scripts that also run locally and in
|
|
@@ -69,8 +69,9 @@ declare function injectBundle(bundle: BundleWithMap, options?: InjectOptions): P
|
|
|
69
69
|
declare function injectDir(dir: string, options?: InjectOptions): Promise<InjectResult[]>;
|
|
70
70
|
|
|
71
71
|
declare const DEFAULT_ENDPOINT = "https://otlp.autter.dev";
|
|
72
|
-
/** Largest map the ingester stores
|
|
73
|
-
* `sourcesContent
|
|
72
|
+
/** Largest map the ingester stores (otlp-ingester's SOURCE_MAP_MAX_CHARS):
|
|
73
|
+
* characters of JSON without `sourcesContent`; the in-app sources' content
|
|
74
|
+
* that is sent fits in what is left of it, in UTF-8 bytes (storedMapJson). */
|
|
74
75
|
declare const MAX_MAP_CHARS: number;
|
|
75
76
|
/** The ingester's `/v1/sourcemaps` body limit, counted after the gzip body
|
|
76
77
|
* is inflated: the map plus room for the rest of the request. */
|
|
@@ -101,6 +102,11 @@ interface UploadOptions {
|
|
|
101
102
|
/** Delete each `.map` (and its `sourceMappingURL` comment) once the
|
|
102
103
|
* ingester has it, so maps are never deployed. */
|
|
103
104
|
deleteAfterUpload?: boolean;
|
|
105
|
+
/** Send the original source of your own files (`sourcesContent`, when the
|
|
106
|
+
* bundler wrote it), so issues show the lines around each frame of your
|
|
107
|
+
* code. Dependencies' sources are never sent. Default true; false sends
|
|
108
|
+
* maps without it (`--no-sources-content`). */
|
|
109
|
+
sourcesContent?: boolean;
|
|
104
110
|
log?: (line: string) => void;
|
|
105
111
|
env?: NodeJS.ProcessEnv;
|
|
106
112
|
cwd?: string;
|
|
@@ -138,8 +144,23 @@ interface UploadSummary {
|
|
|
138
144
|
declare function resolveEndpoint(flag?: string, env?: NodeJS.ProcessEnv): string;
|
|
139
145
|
/** prefix + path, with exactly one "/" between. "~/" (Sentry's spelling) means "/". */
|
|
140
146
|
declare function servedFilename(urlPrefix: string | undefined, path: string): string;
|
|
141
|
-
/**
|
|
142
|
-
declare function
|
|
147
|
+
/** Whether a map's `sources` entry is the app's own code (the ingester's in-app path rule). */
|
|
148
|
+
declare function isInAppSource(path: string): boolean;
|
|
149
|
+
/**
|
|
150
|
+
* The `sourcesContent` the ingester keeps, or null to leave it out: in-app
|
|
151
|
+
* sources only (not ignore-listed, not under node_modules/ etc.), whole
|
|
152
|
+
* files, smallest first, while the JSON fits `limit` UTF-8 bytes given the
|
|
153
|
+
* `baseBytes` of the map without it.
|
|
154
|
+
*/
|
|
155
|
+
declare function storedSourcesContent(fields: Record<string, unknown>, baseBytes: number, limit?: number): Array<string | null> | null;
|
|
156
|
+
/**
|
|
157
|
+
* The map as the ingester stores it, compact JSON: every field as given,
|
|
158
|
+
* then `sourcesContent` bounded by storedSourcesContent (left out when
|
|
159
|
+
* nothing is kept, or with `sourcesContent: false`).
|
|
160
|
+
*/
|
|
161
|
+
declare function storedMapJson(map: Record<string, unknown>, options?: {
|
|
162
|
+
sourcesContent?: boolean;
|
|
163
|
+
}): string;
|
|
143
164
|
declare class FatalUploadError extends Error {
|
|
144
165
|
}
|
|
145
166
|
/** Upload every source map under `dir` to the ingester's `/v1/sourcemaps`. */
|
|
@@ -177,7 +198,26 @@ interface AutterSourceMapsOptions {
|
|
|
177
198
|
failOnError?: boolean;
|
|
178
199
|
/** No log output. */
|
|
179
200
|
silent?: boolean;
|
|
201
|
+
/** Send your own files' original source with each map (`sourcesContent`,
|
|
202
|
+
* when the bundler wrote it), so issues show the lines around each frame
|
|
203
|
+
* of your code. Dependencies' sources are never sent. Default true. */
|
|
204
|
+
sourcesContent?: boolean;
|
|
205
|
+
/** Server bundles too (default true): Vite SSR builds and server
|
|
206
|
+
* environments, webpack builds for a Node target, and Next.js server
|
|
207
|
+
* output get debug ids and their maps uploaded, so errors in your backend
|
|
208
|
+
* resolve to its original files and lines. False leaves server output
|
|
209
|
+
* exactly as the bundler wrote it. */
|
|
210
|
+
serverBundles?: boolean;
|
|
180
211
|
}
|
|
212
|
+
/**
|
|
213
|
+
* Where a server bundle directory's maps are stored: its path relative to
|
|
214
|
+
* the project (`/dist/server/`, `/.next/server/`), never the public URL
|
|
215
|
+
* prefix. The ingester matches a stored path as a suffix of the path the
|
|
216
|
+
* process runs the bundle from (`/app/dist/server/entry.js`,
|
|
217
|
+
* `/var/task/.next/server/app/page.js`), and the directory keeps server and
|
|
218
|
+
* browser maps of one release apart. "/" for a directory outside the project.
|
|
219
|
+
*/
|
|
220
|
+
declare function serverUrlPrefix(projectRoot: string, dir: string): string;
|
|
181
221
|
interface BuildOutputResult {
|
|
182
222
|
injected: InjectResult[];
|
|
183
223
|
upload: UploadSummary | null;
|
|
@@ -208,6 +248,9 @@ declare function processBuildOutput(input: {
|
|
|
208
248
|
/** Map files the build emitted (absolute), when the bundler lists them;
|
|
209
249
|
* the maps of `files` (or of every bundle under `dir`) are added. */
|
|
210
250
|
maps?: string[];
|
|
251
|
+
/** Server output (RF-05): `urlPrefix` is serverUrlPrefix(), which the
|
|
252
|
+
* public `options.urlPrefix` never overrides. */
|
|
253
|
+
server?: boolean;
|
|
211
254
|
}): Promise<BuildOutputResult>;
|
|
212
255
|
|
|
213
|
-
export { type AutterSourceMapsOptions as A, BUNDLE_RE as B, CLIENT_KEY_PREFIX as C, DEFAULT_ENDPOINT as D, FatalUploadError as F, type InjectOptions as I, KEY_ADVICE as K, MAX_MAP_CHARS as M, SERVER_KEY_PREFIX as S, UPLOAD_KEY_PREFIX as U, type BuildOutputResult as a, type BundleWithMap as b, type InjectResult as c, MAX_UPLOAD_BYTES as d, SNIPPET_LINE_KEY as e, type UploadItem as f, type UploadOptions as g, type UploadSummary as h, findBundles as i, formatUploadSummary as j, injectBundle as k, injectDir as l,
|
|
256
|
+
export { type AutterSourceMapsOptions as A, BUNDLE_RE as B, CLIENT_KEY_PREFIX as C, DEFAULT_ENDPOINT as D, FatalUploadError as F, type InjectOptions as I, KEY_ADVICE as K, MAX_MAP_CHARS as M, SERVER_KEY_PREFIX as S, UPLOAD_KEY_PREFIX as U, type BuildOutputResult as a, type BundleWithMap as b, type InjectResult as c, MAX_UPLOAD_BYTES as d, SNIPPET_LINE_KEY as e, type UploadItem as f, type UploadOptions as g, type UploadSummary as h, findBundles as i, formatUploadSummary as j, injectBundle as k, injectDir as l, isInAppSource as m, mapPathFor as n, resolveEndpoint as o, processBuildOutput as p, serverUrlPrefix as q, readSourceMappingUrl as r, servedFilename as s, shiftMappings as t, snippetLine as u, storedMapJson as v, storedSourcesContent as w, stripSourceMappingUrl as x, uploadDir as y };
|
|
@@ -69,8 +69,9 @@ declare function injectBundle(bundle: BundleWithMap, options?: InjectOptions): P
|
|
|
69
69
|
declare function injectDir(dir: string, options?: InjectOptions): Promise<InjectResult[]>;
|
|
70
70
|
|
|
71
71
|
declare const DEFAULT_ENDPOINT = "https://otlp.autter.dev";
|
|
72
|
-
/** Largest map the ingester stores
|
|
73
|
-
* `sourcesContent
|
|
72
|
+
/** Largest map the ingester stores (otlp-ingester's SOURCE_MAP_MAX_CHARS):
|
|
73
|
+
* characters of JSON without `sourcesContent`; the in-app sources' content
|
|
74
|
+
* that is sent fits in what is left of it, in UTF-8 bytes (storedMapJson). */
|
|
74
75
|
declare const MAX_MAP_CHARS: number;
|
|
75
76
|
/** The ingester's `/v1/sourcemaps` body limit, counted after the gzip body
|
|
76
77
|
* is inflated: the map plus room for the rest of the request. */
|
|
@@ -101,6 +102,11 @@ interface UploadOptions {
|
|
|
101
102
|
/** Delete each `.map` (and its `sourceMappingURL` comment) once the
|
|
102
103
|
* ingester has it, so maps are never deployed. */
|
|
103
104
|
deleteAfterUpload?: boolean;
|
|
105
|
+
/** Send the original source of your own files (`sourcesContent`, when the
|
|
106
|
+
* bundler wrote it), so issues show the lines around each frame of your
|
|
107
|
+
* code. Dependencies' sources are never sent. Default true; false sends
|
|
108
|
+
* maps without it (`--no-sources-content`). */
|
|
109
|
+
sourcesContent?: boolean;
|
|
104
110
|
log?: (line: string) => void;
|
|
105
111
|
env?: NodeJS.ProcessEnv;
|
|
106
112
|
cwd?: string;
|
|
@@ -138,8 +144,23 @@ interface UploadSummary {
|
|
|
138
144
|
declare function resolveEndpoint(flag?: string, env?: NodeJS.ProcessEnv): string;
|
|
139
145
|
/** prefix + path, with exactly one "/" between. "~/" (Sentry's spelling) means "/". */
|
|
140
146
|
declare function servedFilename(urlPrefix: string | undefined, path: string): string;
|
|
141
|
-
/**
|
|
142
|
-
declare function
|
|
147
|
+
/** Whether a map's `sources` entry is the app's own code (the ingester's in-app path rule). */
|
|
148
|
+
declare function isInAppSource(path: string): boolean;
|
|
149
|
+
/**
|
|
150
|
+
* The `sourcesContent` the ingester keeps, or null to leave it out: in-app
|
|
151
|
+
* sources only (not ignore-listed, not under node_modules/ etc.), whole
|
|
152
|
+
* files, smallest first, while the JSON fits `limit` UTF-8 bytes given the
|
|
153
|
+
* `baseBytes` of the map without it.
|
|
154
|
+
*/
|
|
155
|
+
declare function storedSourcesContent(fields: Record<string, unknown>, baseBytes: number, limit?: number): Array<string | null> | null;
|
|
156
|
+
/**
|
|
157
|
+
* The map as the ingester stores it, compact JSON: every field as given,
|
|
158
|
+
* then `sourcesContent` bounded by storedSourcesContent (left out when
|
|
159
|
+
* nothing is kept, or with `sourcesContent: false`).
|
|
160
|
+
*/
|
|
161
|
+
declare function storedMapJson(map: Record<string, unknown>, options?: {
|
|
162
|
+
sourcesContent?: boolean;
|
|
163
|
+
}): string;
|
|
143
164
|
declare class FatalUploadError extends Error {
|
|
144
165
|
}
|
|
145
166
|
/** Upload every source map under `dir` to the ingester's `/v1/sourcemaps`. */
|
|
@@ -177,7 +198,26 @@ interface AutterSourceMapsOptions {
|
|
|
177
198
|
failOnError?: boolean;
|
|
178
199
|
/** No log output. */
|
|
179
200
|
silent?: boolean;
|
|
201
|
+
/** Send your own files' original source with each map (`sourcesContent`,
|
|
202
|
+
* when the bundler wrote it), so issues show the lines around each frame
|
|
203
|
+
* of your code. Dependencies' sources are never sent. Default true. */
|
|
204
|
+
sourcesContent?: boolean;
|
|
205
|
+
/** Server bundles too (default true): Vite SSR builds and server
|
|
206
|
+
* environments, webpack builds for a Node target, and Next.js server
|
|
207
|
+
* output get debug ids and their maps uploaded, so errors in your backend
|
|
208
|
+
* resolve to its original files and lines. False leaves server output
|
|
209
|
+
* exactly as the bundler wrote it. */
|
|
210
|
+
serverBundles?: boolean;
|
|
180
211
|
}
|
|
212
|
+
/**
|
|
213
|
+
* Where a server bundle directory's maps are stored: its path relative to
|
|
214
|
+
* the project (`/dist/server/`, `/.next/server/`), never the public URL
|
|
215
|
+
* prefix. The ingester matches a stored path as a suffix of the path the
|
|
216
|
+
* process runs the bundle from (`/app/dist/server/entry.js`,
|
|
217
|
+
* `/var/task/.next/server/app/page.js`), and the directory keeps server and
|
|
218
|
+
* browser maps of one release apart. "/" for a directory outside the project.
|
|
219
|
+
*/
|
|
220
|
+
declare function serverUrlPrefix(projectRoot: string, dir: string): string;
|
|
181
221
|
interface BuildOutputResult {
|
|
182
222
|
injected: InjectResult[];
|
|
183
223
|
upload: UploadSummary | null;
|
|
@@ -208,6 +248,9 @@ declare function processBuildOutput(input: {
|
|
|
208
248
|
/** Map files the build emitted (absolute), when the bundler lists them;
|
|
209
249
|
* the maps of `files` (or of every bundle under `dir`) are added. */
|
|
210
250
|
maps?: string[];
|
|
251
|
+
/** Server output (RF-05): `urlPrefix` is serverUrlPrefix(), which the
|
|
252
|
+
* public `options.urlPrefix` never overrides. */
|
|
253
|
+
server?: boolean;
|
|
211
254
|
}): Promise<BuildOutputResult>;
|
|
212
255
|
|
|
213
|
-
export { type AutterSourceMapsOptions as A, BUNDLE_RE as B, CLIENT_KEY_PREFIX as C, DEFAULT_ENDPOINT as D, FatalUploadError as F, type InjectOptions as I, KEY_ADVICE as K, MAX_MAP_CHARS as M, SERVER_KEY_PREFIX as S, UPLOAD_KEY_PREFIX as U, type BuildOutputResult as a, type BundleWithMap as b, type InjectResult as c, MAX_UPLOAD_BYTES as d, SNIPPET_LINE_KEY as e, type UploadItem as f, type UploadOptions as g, type UploadSummary as h, findBundles as i, formatUploadSummary as j, injectBundle as k, injectDir as l,
|
|
256
|
+
export { type AutterSourceMapsOptions as A, BUNDLE_RE as B, CLIENT_KEY_PREFIX as C, DEFAULT_ENDPOINT as D, FatalUploadError as F, type InjectOptions as I, KEY_ADVICE as K, MAX_MAP_CHARS as M, SERVER_KEY_PREFIX as S, UPLOAD_KEY_PREFIX as U, type BuildOutputResult as a, type BundleWithMap as b, type InjectResult as c, MAX_UPLOAD_BYTES as d, SNIPPET_LINE_KEY as e, type UploadItem as f, type UploadOptions as g, type UploadSummary as h, findBundles as i, formatUploadSummary as j, injectBundle as k, injectDir as l, isInAppSource as m, mapPathFor as n, resolveEndpoint as o, processBuildOutput as p, serverUrlPrefix as q, readSourceMappingUrl as r, servedFilename as s, shiftMappings as t, snippetLine as u, storedMapJson as v, storedSourcesContent as w, stripSourceMappingUrl as x, uploadDir as y };
|
|
@@ -684,9 +684,56 @@ function servedFilename(urlPrefix, path) {
|
|
|
684
684
|
if (!/^[a-z][\w+.-]*:\/\//i.test(prefix) && !prefix.startsWith("/")) prefix = `/${prefix}`;
|
|
685
685
|
return `${prefix.replace(/\/+$/, "")}/${path.replace(/^\/+/, "")}`;
|
|
686
686
|
}
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
687
|
+
var NOT_IN_APP_PATH_PARTS = ["node_modules/", "/site-packages/", "/dist-packages/", "/vendor/", "/.pnpm/"];
|
|
688
|
+
var NOT_IN_APP_PATH_PREFIXES = ["node:", "internal/"];
|
|
689
|
+
var EXTENSION_SCHEMES = ["chrome-extension:", "moz-extension:", "safari-extension:", "safari-web-extension:", "webkit-masked-url:"];
|
|
690
|
+
function isInAppSource(path) {
|
|
691
|
+
if (!path) return true;
|
|
692
|
+
const normalized = path.replace(/\\/g, "/");
|
|
693
|
+
if (NOT_IN_APP_PATH_PARTS.some((part) => normalized.includes(part))) return false;
|
|
694
|
+
if (NOT_IN_APP_PATH_PREFIXES.some((prefix) => normalized.startsWith(prefix))) return false;
|
|
695
|
+
const lower = normalized.toLowerCase();
|
|
696
|
+
return !EXTENSION_SCHEMES.some((scheme) => lower.startsWith(scheme));
|
|
697
|
+
}
|
|
698
|
+
var SOURCES_CONTENT_WRAPPER_BYTES = Buffer.byteLength(',"sourcesContent":[]');
|
|
699
|
+
var NULL_ENTRY_BYTES = 4;
|
|
700
|
+
function storedSourcesContent(fields, baseBytes, limit = MAX_MAP_CHARS) {
|
|
701
|
+
const { sources, sourcesContent } = fields;
|
|
702
|
+
if (!Array.isArray(sources) || !Array.isArray(sourcesContent) || sources.length === 0) return null;
|
|
703
|
+
const ignored = /* @__PURE__ */ new Set();
|
|
704
|
+
for (const list of [fields.ignoreList, fields.x_google_ignoreList]) {
|
|
705
|
+
if (!Array.isArray(list)) continue;
|
|
706
|
+
for (const index of list) if (Number.isInteger(index)) ignored.add(index);
|
|
707
|
+
}
|
|
708
|
+
const count = sources.length;
|
|
709
|
+
const candidates = [];
|
|
710
|
+
for (let index = 0; index < count; index++) {
|
|
711
|
+
const source = sources[index];
|
|
712
|
+
const content = sourcesContent[index];
|
|
713
|
+
if (typeof source !== "string" || typeof content !== "string") continue;
|
|
714
|
+
if (ignored.has(index) || !isInAppSource(source)) continue;
|
|
715
|
+
candidates.push({ index, content, bytes: Buffer.byteLength(JSON.stringify(content)) });
|
|
716
|
+
}
|
|
717
|
+
if (candidates.length === 0) return null;
|
|
718
|
+
candidates.sort((a, b) => a.bytes - b.bytes || a.index - b.index);
|
|
719
|
+
let remaining = limit - baseBytes - SOURCES_CONTENT_WRAPPER_BYTES - NULL_ENTRY_BYTES * count - (count - 1);
|
|
720
|
+
const kept = new Array(count).fill(null);
|
|
721
|
+
let any = false;
|
|
722
|
+
for (const candidate of candidates) {
|
|
723
|
+
const extra = candidate.bytes - NULL_ENTRY_BYTES;
|
|
724
|
+
if (extra > remaining) break;
|
|
725
|
+
remaining -= extra;
|
|
726
|
+
kept[candidate.index] = candidate.content;
|
|
727
|
+
any = true;
|
|
728
|
+
}
|
|
729
|
+
return any ? kept : null;
|
|
730
|
+
}
|
|
731
|
+
function storedMapJson(map, options = {}) {
|
|
732
|
+
const { sourcesContent: _content, ...rest } = map;
|
|
733
|
+
const base = JSON.stringify(rest);
|
|
734
|
+
if (options.sourcesContent === false) return base;
|
|
735
|
+
const content = storedSourcesContent(map, Buffer.byteLength(base));
|
|
736
|
+
return content ? JSON.stringify({ ...rest, sourcesContent: content }) : base;
|
|
690
737
|
}
|
|
691
738
|
function bytesOf(buffer) {
|
|
692
739
|
return new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength);
|
|
@@ -697,7 +744,7 @@ function fits(json, body) {
|
|
|
697
744
|
function uploadBody(release, filename, debugId, json) {
|
|
698
745
|
return `{"release":${JSON.stringify(release)},"filename":${JSON.stringify(filename)},${debugId ? `"debugId":${JSON.stringify(debugId)},` : ""}"map":${json}}`;
|
|
699
746
|
}
|
|
700
|
-
async function prepare(bundle, urlPrefix, release, log, compress) {
|
|
747
|
+
async function prepare(bundle, urlPrefix, release, log, compress, sourcesContent) {
|
|
701
748
|
let map;
|
|
702
749
|
try {
|
|
703
750
|
map = JSON.parse(await readFile3(bundle.map, "utf8"));
|
|
@@ -712,9 +759,10 @@ async function prepare(bundle, urlPrefix, release, log, compress) {
|
|
|
712
759
|
const filename = servedFilename(urlPrefix, bundle.path);
|
|
713
760
|
const { [SCOPES_KEY]: _stale, ...plain } = map;
|
|
714
761
|
const scopes = computeScopes(code, map);
|
|
715
|
-
|
|
762
|
+
const stored = { sourcesContent };
|
|
763
|
+
let json = storedMapJson(plain, stored);
|
|
716
764
|
if ("scopes" in scopes) {
|
|
717
|
-
const scoped = storedMapJson({ ...plain, [SCOPES_KEY]: scopes.scopes });
|
|
765
|
+
const scoped = storedMapJson({ ...plain, [SCOPES_KEY]: scopes.scopes }, stored);
|
|
718
766
|
if (fits(scoped, uploadBody(release, filename, debugId, scoped))) json = scoped;
|
|
719
767
|
else if (fits(json, uploadBody(release, filename, debugId, json))) {
|
|
720
768
|
log(`warning: ${bundle.path}: its map is over 32 MB with function scopes, so it is uploaded without them (frames keep call-site names)`);
|
|
@@ -761,7 +809,7 @@ async function uploadDir(dir, options = {}) {
|
|
|
761
809
|
};
|
|
762
810
|
const items = [];
|
|
763
811
|
for (const bundle of await findBundles(dir, options.files)) {
|
|
764
|
-
const prepared = await prepare(bundle, options.urlPrefix, release, log, !options.dryRun);
|
|
812
|
+
const prepared = await prepare(bundle, options.urlPrefix, release, log, !options.dryRun, options.sourcesContent !== false);
|
|
765
813
|
if ("error" in prepared) {
|
|
766
814
|
summary.failed.push({ path: bundle.path, filename: servedFilename(options.urlPrefix, bundle.path), error: prepared.error });
|
|
767
815
|
} else if (prepared.mapChars > MAX_MAP_CHARS || prepared.bytes > MAX_UPLOAD_BYTES) {
|
|
@@ -881,7 +929,11 @@ function strip(item) {
|
|
|
881
929
|
|
|
882
930
|
// src/build.ts
|
|
883
931
|
import { existsSync as existsSync2 } from "fs";
|
|
884
|
-
import { relative as relative2, sep as sep2 } from "path";
|
|
932
|
+
import { isAbsolute, relative as relative2, sep as sep2 } from "path";
|
|
933
|
+
function serverUrlPrefix(projectRoot, dir) {
|
|
934
|
+
const rel = relative2(projectRoot, dir).split(sep2).join("/");
|
|
935
|
+
return !rel || rel.startsWith("..") || isAbsolute(rel) ? "/" : `/${rel.replace(/\/+$/, "")}/`;
|
|
936
|
+
}
|
|
885
937
|
function buildKey(options) {
|
|
886
938
|
const key = (options.key ?? process.env.AUTTER_RUNTIME_KEY ?? "").trim();
|
|
887
939
|
return key || null;
|
|
@@ -944,12 +996,13 @@ async function processBuildOutput(input) {
|
|
|
944
996
|
result.upload = await uploadDir(input.dir, {
|
|
945
997
|
files: input.files,
|
|
946
998
|
release: options.release,
|
|
947
|
-
urlPrefix: options.urlPrefix ?? input.urlPrefix,
|
|
999
|
+
urlPrefix: input.server ? input.urlPrefix : options.urlPrefix ?? input.urlPrefix,
|
|
948
1000
|
endpoint: options.endpoint,
|
|
949
1001
|
key: key ?? void 0,
|
|
950
1002
|
dryRun: options.dryRun,
|
|
951
1003
|
concurrency: options.concurrency,
|
|
952
1004
|
deleteAfterUpload: options.deleteAfterUpload ?? input.deleteAfterUpload,
|
|
1005
|
+
...options.sourcesContent === false ? { sourcesContent: false } : {},
|
|
953
1006
|
log
|
|
954
1007
|
});
|
|
955
1008
|
for (const line of formatUploadSummary(result.upload)) log(line);
|
|
@@ -1034,9 +1087,12 @@ export {
|
|
|
1034
1087
|
KEY_ADVICE,
|
|
1035
1088
|
resolveEndpoint,
|
|
1036
1089
|
servedFilename,
|
|
1090
|
+
isInAppSource,
|
|
1091
|
+
storedSourcesContent,
|
|
1037
1092
|
storedMapJson,
|
|
1038
1093
|
FatalUploadError,
|
|
1039
1094
|
uploadDir,
|
|
1095
|
+
serverUrlPrefix,
|
|
1040
1096
|
shouldGenerateMaps,
|
|
1041
1097
|
logMapsNotGenerated,
|
|
1042
1098
|
formatUploadSummary,
|
|
@@ -2,12 +2,18 @@ import {
|
|
|
2
2
|
BUNDLE_RE,
|
|
3
3
|
logMapsNotGenerated,
|
|
4
4
|
processBuildOutput,
|
|
5
|
+
serverUrlPrefix,
|
|
5
6
|
shouldGenerateMaps
|
|
6
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-Q23FB5X3.js";
|
|
7
8
|
|
|
8
9
|
// src/webpack.ts
|
|
9
10
|
import { resolve } from "path";
|
|
10
11
|
var PLUGIN_NAME = "AutterSourceMapsWebpackPlugin";
|
|
12
|
+
var SERVER_TARGET_RE = /^(?:async-)?node|^electron-(?:main|preload)/;
|
|
13
|
+
function isServerTarget(target) {
|
|
14
|
+
const targets = Array.isArray(target) ? target : [target];
|
|
15
|
+
return targets.some((value) => typeof value === "string" && SERVER_TARGET_RE.test(value));
|
|
16
|
+
}
|
|
11
17
|
var AutterSourceMapsWebpackPlugin = class {
|
|
12
18
|
constructor(options = {}, internal = {}) {
|
|
13
19
|
this.options = options;
|
|
@@ -18,6 +24,8 @@ var AutterSourceMapsWebpackPlugin = class {
|
|
|
18
24
|
apply(compiler) {
|
|
19
25
|
const mode = compiler.options.mode ?? (process.env.NODE_ENV === "development" ? "development" : void 0);
|
|
20
26
|
if (mode === "development") return;
|
|
27
|
+
const server = this.internal.server ?? isServerTarget(compiler.options.target);
|
|
28
|
+
if (server && this.options.serverBundles === false) return;
|
|
21
29
|
let enabledMaps = this.internal.ownMaps ?? false;
|
|
22
30
|
if (!compiler.options.devtool) {
|
|
23
31
|
if (shouldGenerateMaps(this.options)) {
|
|
@@ -31,7 +39,7 @@ var AutterSourceMapsWebpackPlugin = class {
|
|
|
31
39
|
const dir = compilation.outputOptions.path ?? compiler.outputPath;
|
|
32
40
|
if (!dir) return;
|
|
33
41
|
const publicPath = compilation.outputOptions.publicPath;
|
|
34
|
-
const urlPrefix = typeof publicPath === "string" && publicPath !== "auto" && publicPath !== "" ? publicPath : "/";
|
|
42
|
+
const urlPrefix = server ? serverUrlPrefix(compiler.context ?? process.cwd(), dir) : typeof publicPath === "string" && publicPath !== "auto" && publicPath !== "" ? publicPath : "/";
|
|
35
43
|
const assets = compilation.getAssets().map((asset) => asset.name);
|
|
36
44
|
const files = assets.filter((name) => BUNDLE_RE.test(name)).map((name) => resolve(dir, name));
|
|
37
45
|
const maps = assets.filter((name) => name.endsWith(".map")).map((name) => resolve(dir, name));
|
|
@@ -42,7 +50,8 @@ var AutterSourceMapsWebpackPlugin = class {
|
|
|
42
50
|
urlPrefix,
|
|
43
51
|
options: this.options,
|
|
44
52
|
deleteAfterUpload: enabledMaps,
|
|
45
|
-
ownMaps: enabledMaps
|
|
53
|
+
ownMaps: enabledMaps,
|
|
54
|
+
...server ? { server: true } : {}
|
|
46
55
|
});
|
|
47
56
|
});
|
|
48
57
|
}
|
|
@@ -53,6 +62,7 @@ function autterSourceMapsWebpack(options = {}) {
|
|
|
53
62
|
var webpack_default = AutterSourceMapsWebpackPlugin;
|
|
54
63
|
|
|
55
64
|
export {
|
|
65
|
+
isServerTarget,
|
|
56
66
|
AutterSourceMapsWebpackPlugin,
|
|
57
67
|
autterSourceMapsWebpack,
|
|
58
68
|
webpack_default
|