@autter/runtime-cli 0.0.0-stage → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +97 -2
- package/dist/build-CPXR9Xd3.d.cts +206 -0
- package/dist/build-CPXR9Xd3.d.ts +206 -0
- package/dist/chunk-DQLLM2NT.js +1035 -0
- package/dist/chunk-I2743JCN.js +59 -0
- package/dist/cli.js +1031 -0
- package/dist/index.cjs +1079 -0
- package/dist/index.d.cts +105 -0
- package/dist/index.d.ts +105 -0
- package/dist/index.js +72 -0
- package/dist/next.cjs +1165 -0
- package/dist/next.d.cts +24 -0
- package/dist/next.d.ts +24 -0
- package/dist/next.js +103 -0
- package/dist/vite.cjs +1099 -0
- package/dist/vite.d.cts +55 -0
- package/dist/vite.d.ts +55 -0
- package/dist/vite.js +83 -0
- package/dist/webpack.cjs +1075 -0
- package/dist/webpack.d.cts +53 -0
- package/dist/webpack.d.ts +53 -0
- package/dist/webpack.js +11 -0
- package/package.json +101 -5
package/README.md
CHANGED
|
@@ -1,3 +1,98 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @autter/runtime-cli
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Readable stack traces for Autter Runtime. Gives every JS bundle a
|
|
4
|
+
content-addressed **debug id** and uploads its **source map** to the ingester,
|
|
5
|
+
so minified browser frames resolve to your original source, even when the
|
|
6
|
+
release your SDK reports doesn't match the upload.
|
|
7
|
+
|
|
8
|
+
- `autter-runtime sourcemaps inject <dir>` / `upload <dir>` CLI
|
|
9
|
+
- Vite/Rollup plugin: `@autter/runtime-cli/vite`
|
|
10
|
+
- webpack 5 plugin: `@autter/runtime-cli/webpack`
|
|
11
|
+
- Next.js wrapper: `withAutterSourceMaps` from `@autter/runtime-cli/next`
|
|
12
|
+
|
|
13
|
+
No runtime dependencies; bundlers are optional peer dependencies. Debug ids
|
|
14
|
+
need ingester 1.6.0+ and `@autter/runtime-browser` 1.6.0+ (older ingesters
|
|
15
|
+
still match `.js` maps by release + path). Full guide:
|
|
16
|
+
[docs/SOURCE-MAPS.md](../../docs/SOURCE-MAPS.md).
|
|
17
|
+
|
|
18
|
+
## Install
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install -D @autter/runtime-cli
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Set `AUTTER_RUNTIME_KEY` to a **server** ingest key (`autter_rt_…`) where your
|
|
25
|
+
build runs. Without it, the plugins turn no source maps on and change nothing.
|
|
26
|
+
|
|
27
|
+
## Vite / Rollup
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
import { autterSourceMaps } from "@autter/runtime-cli/vite";
|
|
31
|
+
|
|
32
|
+
export default defineConfig({ plugins: [autterSourceMaps()] });
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## webpack
|
|
36
|
+
|
|
37
|
+
```js
|
|
38
|
+
const { AutterSourceMapsWebpackPlugin } = require("@autter/runtime-cli/webpack");
|
|
39
|
+
|
|
40
|
+
module.exports = { plugins: [new AutterSourceMapsWebpackPlugin()] };
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Next.js
|
|
44
|
+
|
|
45
|
+
```js
|
|
46
|
+
// next.config.mjs
|
|
47
|
+
import { withAutterSourceMaps } from "@autter/runtime-cli/next";
|
|
48
|
+
|
|
49
|
+
export default withAutterSourceMaps({ reactStrictMode: true });
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
All three turn on hidden source maps when you haven't configured maps, inject
|
|
53
|
+
debug ids after the build, upload when a key is present, and then delete the
|
|
54
|
+
maps they created whether or not the upload succeeded (a rejected upload, an
|
|
55
|
+
unreachable ingester, a dry run), printing one line that says why; without a
|
|
56
|
+
key they turn none on. Maps you configured yourself are left alone. Options (all optional): `release`, `urlPrefix`,
|
|
57
|
+
`endpoint`, `key`, `upload: false`, `deleteAfterUpload`, `dryRun`,
|
|
58
|
+
`concurrency`, `failOnError` (default `false`: a failed upload is logged and
|
|
59
|
+
never fails the build), `silent`.
|
|
60
|
+
|
|
61
|
+
## CLI
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
npx autter-runtime sourcemaps inject dist
|
|
65
|
+
npx autter-runtime sourcemaps upload dist --url-prefix / --release "$GIT_SHA"
|
|
66
|
+
npx autter-runtime sourcemaps upload dist --dry-run
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
autter-runtime sourcemaps inject <dir> [--dry-run]
|
|
71
|
+
autter-runtime sourcemaps upload <dir> [--release <r>] [--url-prefix <prefix>]
|
|
72
|
+
[--endpoint <url>] [--concurrency <n>] [--delete-after-upload] [--dry-run] [--json]
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
- **inject** writes `//# debugId=<id>`, a one-line snippet that registers
|
|
76
|
+
`globalThis._autterDebugIds[new Error().stack] = "<id>"`, and `"debugId"` in
|
|
77
|
+
the `.map`, for each `.js`/`.mjs`/`.cjs` with a map. The id is derived from
|
|
78
|
+
sha256 of the bundle bytes; running it again changes nothing.
|
|
79
|
+
- **upload** posts each map (without `sourcesContent`, gzipped, up to 32 MB)
|
|
80
|
+
to `<endpoint>/v1/sourcemaps`, in parallel, skipping maps the ingester
|
|
81
|
+
already has. Each map carries the bundle's function scopes (`x_autter_scopes`),
|
|
82
|
+
parsed from the file as served, so frames are named after the function they
|
|
83
|
+
are in rather than their call site; a bundle that does not parse is uploaded
|
|
84
|
+
without them, with a warning. Release: `--release`, else `GITHUB_SHA`,
|
|
85
|
+
`VERCEL_GIT_COMMIT_SHA`, `CF_PAGES_COMMIT_SHA`, `GIT_SHA`, then
|
|
86
|
+
`git rev-parse HEAD`.
|
|
87
|
+
|
|
88
|
+
Exit codes: `0` ok, `1` some maps failed, `2` no key / no release / key
|
|
89
|
+
rejected, `64` usage error.
|
|
90
|
+
|
|
91
|
+
## Programmatic API
|
|
92
|
+
|
|
93
|
+
```ts
|
|
94
|
+
import { injectDir, uploadDir } from "@autter/runtime-cli";
|
|
95
|
+
|
|
96
|
+
await injectDir("dist");
|
|
97
|
+
const summary = await uploadDir("dist", { urlPrefix: "/", release: process.env.GIT_SHA });
|
|
98
|
+
```
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
/** A JS bundle and the source map that belongs to it. */
|
|
2
|
+
interface BundleWithMap {
|
|
3
|
+
/** Absolute path of the bundle. */
|
|
4
|
+
js: string;
|
|
5
|
+
/** Absolute path of its `.map`. */
|
|
6
|
+
map: string;
|
|
7
|
+
/** Bundle path relative to the scanned directory, with `/` separators. */
|
|
8
|
+
path: string;
|
|
9
|
+
}
|
|
10
|
+
/** Bundles a map can be uploaded for. */
|
|
11
|
+
declare const BUNDLE_RE: RegExp;
|
|
12
|
+
/** The last `//# sourceMappingURL=` value in a bundle, or null. */
|
|
13
|
+
declare function readSourceMappingUrl(code: string): string | null;
|
|
14
|
+
/**
|
|
15
|
+
* Remove a trailing `//# sourceMappingURL=` comment (one that is followed by
|
|
16
|
+
* nothing but whitespace or other `//#` comments), so the map is no longer
|
|
17
|
+
* referenced by the served bundle. Line positions above it don't move.
|
|
18
|
+
*/
|
|
19
|
+
declare function stripSourceMappingUrl(code: string): string;
|
|
20
|
+
/** The map file for a bundle: its relative `sourceMappingURL`, else `<file>.map`. */
|
|
21
|
+
declare function mapPathFor(js: string, code: string): string | null;
|
|
22
|
+
/**
|
|
23
|
+
* Every `.js`/`.mjs`/`.cjs` bundle under `dir` that has a source map, sorted
|
|
24
|
+
* by path. `files` restricts the scan to those bundles (as a bundler plugin
|
|
25
|
+
* knows exactly what it emitted).
|
|
26
|
+
*/
|
|
27
|
+
declare function findBundles(dir: string, files?: string[]): Promise<BundleWithMap[]>;
|
|
28
|
+
|
|
29
|
+
interface InjectOptions {
|
|
30
|
+
/** Only these bundles (absolute, or relative to the directory). */
|
|
31
|
+
files?: string[];
|
|
32
|
+
/** Report what would change without writing anything. */
|
|
33
|
+
dryRun?: boolean;
|
|
34
|
+
/** Also drop the bundle's `//# sourceMappingURL=` comment (hidden maps). */
|
|
35
|
+
stripSourceMappingUrl?: boolean;
|
|
36
|
+
}
|
|
37
|
+
interface InjectResult {
|
|
38
|
+
/** Bundle path relative to the directory. */
|
|
39
|
+
path: string;
|
|
40
|
+
js: string;
|
|
41
|
+
map: string;
|
|
42
|
+
debugId: string;
|
|
43
|
+
/** "injected": files were (or, in a dry run, would be) changed. */
|
|
44
|
+
status: "injected" | "unchanged" | "invalid-map";
|
|
45
|
+
}
|
|
46
|
+
/** Source map extension field recording the generated line our snippet was
|
|
47
|
+
* inserted on (its mappings were shifted down by one line from there). */
|
|
48
|
+
declare const SNIPPET_LINE_KEY = "x_autter_snippet_line";
|
|
49
|
+
/**
|
|
50
|
+
* Index of the generated line the snippet goes on, or -1 to append it at the
|
|
51
|
+
* end instead. Line 0 normally (line 1 after a `#!` shebang), so the snippet
|
|
52
|
+
* runs before the bundle's own code and registers its id even when that
|
|
53
|
+
* code throws while loading. A leading directive prologue ("use strict",
|
|
54
|
+
* "use client") must stay first, so those bundles get the snippet appended.
|
|
55
|
+
*/
|
|
56
|
+
declare function snippetLine(code: string): number;
|
|
57
|
+
/** Insert `count` empty generated lines before line `at` of a VLQ `mappings`
|
|
58
|
+
* string. Segment fields other than the column are relative across lines,
|
|
59
|
+
* so empty lines need no other change. */
|
|
60
|
+
declare function shiftMappings(mappings: string, at: number, count?: number): string;
|
|
61
|
+
/**
|
|
62
|
+
* Give one bundle its debug id. Idempotent: a bundle that already has our
|
|
63
|
+
* snippet and a `//# debugId=` comment is left byte-for-byte alone (its map
|
|
64
|
+
* only gains `debugId` if it lacks it). A bundle whose bundler already wrote
|
|
65
|
+
* a debug id comment keeps that id and only gains the snippet.
|
|
66
|
+
*/
|
|
67
|
+
declare function injectBundle(bundle: BundleWithMap, options?: InjectOptions): Promise<InjectResult>;
|
|
68
|
+
/** Inject every bundle with a map under `dir` (see injectBundle). */
|
|
69
|
+
declare function injectDir(dir: string, options?: InjectOptions): Promise<InjectResult[]>;
|
|
70
|
+
|
|
71
|
+
declare const DEFAULT_ENDPOINT = "https://otlp.autter.dev";
|
|
72
|
+
/** Largest map the ingester stores: characters of JSON without
|
|
73
|
+
* `sourcesContent` (otlp-ingester's SOURCE_MAP_MAX_CHARS). */
|
|
74
|
+
declare const MAX_MAP_CHARS: number;
|
|
75
|
+
/** The ingester's `/v1/sourcemaps` body limit, counted after the gzip body
|
|
76
|
+
* is inflated: the map plus room for the rest of the request. */
|
|
77
|
+
declare const MAX_UPLOAD_BYTES: number;
|
|
78
|
+
interface UploadOptions {
|
|
79
|
+
/** Only these bundles (absolute, or relative to the directory). */
|
|
80
|
+
files?: string[];
|
|
81
|
+
/** Default: --release resolution (see resolveRelease). */
|
|
82
|
+
release?: string;
|
|
83
|
+
/** Where the directory is served from: "/" (default), "/static/", or
|
|
84
|
+
* "https://cdn.example.com/app/". Each map is stored under prefix + path. */
|
|
85
|
+
urlPrefix?: string;
|
|
86
|
+
/** Ingester base URL. Default: $AUTTER_ENDPOINT, $AUTTER_RUNTIME_ENDPOINT,
|
|
87
|
+
* $OTEL_EXPORTER_OTLP_ENDPOINT, else https://otlp.autter.dev. */
|
|
88
|
+
endpoint?: string;
|
|
89
|
+
/** Server ingest key. Default: $AUTTER_RUNTIME_KEY. */
|
|
90
|
+
key?: string;
|
|
91
|
+
/** List what would be uploaded; no network, no key needed. */
|
|
92
|
+
dryRun?: boolean;
|
|
93
|
+
/** Parallel uploads (default 8). */
|
|
94
|
+
concurrency?: number;
|
|
95
|
+
/** Delete each `.map` (and its `sourceMappingURL` comment) once the
|
|
96
|
+
* ingester has it, so maps are never deployed. */
|
|
97
|
+
deleteAfterUpload?: boolean;
|
|
98
|
+
log?: (line: string) => void;
|
|
99
|
+
env?: NodeJS.ProcessEnv;
|
|
100
|
+
cwd?: string;
|
|
101
|
+
fetch?: typeof fetch;
|
|
102
|
+
}
|
|
103
|
+
interface UploadItem {
|
|
104
|
+
/** Bundle path relative to the directory. */
|
|
105
|
+
path: string;
|
|
106
|
+
/** Stored filename: urlPrefix + path. */
|
|
107
|
+
filename: string;
|
|
108
|
+
debugId: string | null;
|
|
109
|
+
/** sha256 of the uploaded map JSON (what the ingester stores). */
|
|
110
|
+
hash: string;
|
|
111
|
+
bytes: number;
|
|
112
|
+
}
|
|
113
|
+
interface UploadSummary {
|
|
114
|
+
release: string;
|
|
115
|
+
releaseSource: string;
|
|
116
|
+
endpoint: string;
|
|
117
|
+
dryRun: boolean;
|
|
118
|
+
uploaded: UploadItem[];
|
|
119
|
+
/** Already on the ingester with the same content: not sent again. */
|
|
120
|
+
skipped: UploadItem[];
|
|
121
|
+
failed: Array<{
|
|
122
|
+
path: string;
|
|
123
|
+
filename: string;
|
|
124
|
+
error: string;
|
|
125
|
+
}>;
|
|
126
|
+
/** True when the ingester predates 1.6.0 (no `/v1/sourcemaps/check`). */
|
|
127
|
+
legacyIngester: boolean;
|
|
128
|
+
deletedMaps: string[];
|
|
129
|
+
}
|
|
130
|
+
/** Ingester base URL from a flag or the environment, without a trailing
|
|
131
|
+
* slash or a `/v1/...` route someone pasted in. */
|
|
132
|
+
declare function resolveEndpoint(flag?: string, env?: NodeJS.ProcessEnv): string;
|
|
133
|
+
/** prefix + path, with exactly one "/" between. "~/" (Sentry's spelling) means "/". */
|
|
134
|
+
declare function servedFilename(urlPrefix: string | undefined, path: string): string;
|
|
135
|
+
/** The map as the ingester stores it: `sourcesContent` removed, compact JSON. */
|
|
136
|
+
declare function storedMapJson(map: Record<string, unknown>): string;
|
|
137
|
+
declare class FatalUploadError extends Error {
|
|
138
|
+
}
|
|
139
|
+
/** Upload every source map under `dir` to the ingester's `/v1/sourcemaps`. */
|
|
140
|
+
declare function uploadDir(dir: string, options?: UploadOptions): Promise<UploadSummary>;
|
|
141
|
+
|
|
142
|
+
/** Options shared by the Vite/Rollup, webpack and Next.js integrations. */
|
|
143
|
+
interface AutterSourceMapsOptions {
|
|
144
|
+
/** Default: GITHUB_SHA, VERCEL_GIT_COMMIT_SHA, CF_PAGES_COMMIT_SHA, GIT_SHA, then `git rev-parse HEAD`. */
|
|
145
|
+
release?: string;
|
|
146
|
+
/** Where the build output is served from. Default: the bundler's public
|
|
147
|
+
* path (Vite `base`, webpack `output.publicPath`, Next `/_next/`), else "/". */
|
|
148
|
+
urlPrefix?: string;
|
|
149
|
+
/** Ingester base URL. Default: $AUTTER_ENDPOINT, $AUTTER_RUNTIME_ENDPOINT,
|
|
150
|
+
* $OTEL_EXPORTER_OTLP_ENDPOINT, else https://otlp.autter.dev. */
|
|
151
|
+
endpoint?: string;
|
|
152
|
+
/** Server ingest key. Default: $AUTTER_RUNTIME_KEY. Without one (and
|
|
153
|
+
* without `upload: false` or `dryRun`), the plugin generates no source
|
|
154
|
+
* maps it would have to delete again: the build is left as it was. */
|
|
155
|
+
key?: string;
|
|
156
|
+
/** Set false to inject debug ids only (upload later with the CLI). Maps
|
|
157
|
+
* the plugin generated are then kept for that upload: don't deploy them. */
|
|
158
|
+
upload?: boolean;
|
|
159
|
+
/** Maps the plugin generated itself are always deleted after the upload
|
|
160
|
+
* step, uploaded or not, so they are never deployed; set false to keep
|
|
161
|
+
* them (you must then keep them out of the deploy). Maps you configured
|
|
162
|
+
* yourself are deleted only when this is true, and only once uploaded. */
|
|
163
|
+
deleteAfterUpload?: boolean;
|
|
164
|
+
/** Log what would be uploaded without sending anything. */
|
|
165
|
+
dryRun?: boolean;
|
|
166
|
+
/** Parallel uploads (default 8). */
|
|
167
|
+
concurrency?: number;
|
|
168
|
+
/** Fail the build when injecting or uploading fails (default false:
|
|
169
|
+
* telemetry never breaks a deploy; the failure is logged). */
|
|
170
|
+
failOnError?: boolean;
|
|
171
|
+
/** No log output. */
|
|
172
|
+
silent?: boolean;
|
|
173
|
+
}
|
|
174
|
+
interface BuildOutputResult {
|
|
175
|
+
injected: InjectResult[];
|
|
176
|
+
upload: UploadSummary | null;
|
|
177
|
+
/** Maps the plugin generated and deleted (paths relative to the directory). */
|
|
178
|
+
removedMaps: string[];
|
|
179
|
+
}
|
|
180
|
+
/** Human-readable lines for an upload summary (CLI and plugins). */
|
|
181
|
+
declare function formatUploadSummary(summary: UploadSummary): string[];
|
|
182
|
+
/**
|
|
183
|
+
* What every bundler integration does after a build: inject debug ids into
|
|
184
|
+
* the emitted bundles, then upload their maps when a key is present.
|
|
185
|
+
* Failures are logged, and thrown only with `failOnError`. When the
|
|
186
|
+
* integration turned source maps on itself (`ownMaps`), every map it made
|
|
187
|
+
* is deleted afterwards whatever happened to the upload (no key, a failed
|
|
188
|
+
* or partial upload, an unreachable ingester, a dry run), with the
|
|
189
|
+
* sourceMappingURL comments that name them, so none is deployed.
|
|
190
|
+
*/
|
|
191
|
+
declare function processBuildOutput(input: {
|
|
192
|
+
dir: string;
|
|
193
|
+
files?: string[];
|
|
194
|
+
urlPrefix: string;
|
|
195
|
+
options: AutterSourceMapsOptions;
|
|
196
|
+
/** Default for `deleteAfterUpload` (true when the plugin enabled maps). */
|
|
197
|
+
deleteAfterUpload: boolean;
|
|
198
|
+
stripSourceMappingUrl?: boolean;
|
|
199
|
+
/** The integration turned source maps on itself: none may be deployed. */
|
|
200
|
+
ownMaps?: boolean;
|
|
201
|
+
/** Map files the build emitted (absolute), when the bundler lists them;
|
|
202
|
+
* the maps of `files` (or of every bundle under `dir`) are added. */
|
|
203
|
+
maps?: string[];
|
|
204
|
+
}): Promise<BuildOutputResult>;
|
|
205
|
+
|
|
206
|
+
export { type AutterSourceMapsOptions as A, BUNDLE_RE as B, DEFAULT_ENDPOINT as D, FatalUploadError as F, type InjectOptions as I, MAX_MAP_CHARS as M, SNIPPET_LINE_KEY as S, type UploadItem as U, type BuildOutputResult as a, type BundleWithMap as b, type InjectResult as c, MAX_UPLOAD_BYTES as d, type UploadOptions as e, type UploadSummary as f, findBundles as g, formatUploadSummary as h, injectBundle as i, injectDir as j, resolveEndpoint as k, shiftMappings as l, mapPathFor as m, snippetLine as n, storedMapJson as o, processBuildOutput as p, stripSourceMappingUrl as q, readSourceMappingUrl as r, servedFilename as s, uploadDir as u };
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
/** A JS bundle and the source map that belongs to it. */
|
|
2
|
+
interface BundleWithMap {
|
|
3
|
+
/** Absolute path of the bundle. */
|
|
4
|
+
js: string;
|
|
5
|
+
/** Absolute path of its `.map`. */
|
|
6
|
+
map: string;
|
|
7
|
+
/** Bundle path relative to the scanned directory, with `/` separators. */
|
|
8
|
+
path: string;
|
|
9
|
+
}
|
|
10
|
+
/** Bundles a map can be uploaded for. */
|
|
11
|
+
declare const BUNDLE_RE: RegExp;
|
|
12
|
+
/** The last `//# sourceMappingURL=` value in a bundle, or null. */
|
|
13
|
+
declare function readSourceMappingUrl(code: string): string | null;
|
|
14
|
+
/**
|
|
15
|
+
* Remove a trailing `//# sourceMappingURL=` comment (one that is followed by
|
|
16
|
+
* nothing but whitespace or other `//#` comments), so the map is no longer
|
|
17
|
+
* referenced by the served bundle. Line positions above it don't move.
|
|
18
|
+
*/
|
|
19
|
+
declare function stripSourceMappingUrl(code: string): string;
|
|
20
|
+
/** The map file for a bundle: its relative `sourceMappingURL`, else `<file>.map`. */
|
|
21
|
+
declare function mapPathFor(js: string, code: string): string | null;
|
|
22
|
+
/**
|
|
23
|
+
* Every `.js`/`.mjs`/`.cjs` bundle under `dir` that has a source map, sorted
|
|
24
|
+
* by path. `files` restricts the scan to those bundles (as a bundler plugin
|
|
25
|
+
* knows exactly what it emitted).
|
|
26
|
+
*/
|
|
27
|
+
declare function findBundles(dir: string, files?: string[]): Promise<BundleWithMap[]>;
|
|
28
|
+
|
|
29
|
+
interface InjectOptions {
|
|
30
|
+
/** Only these bundles (absolute, or relative to the directory). */
|
|
31
|
+
files?: string[];
|
|
32
|
+
/** Report what would change without writing anything. */
|
|
33
|
+
dryRun?: boolean;
|
|
34
|
+
/** Also drop the bundle's `//# sourceMappingURL=` comment (hidden maps). */
|
|
35
|
+
stripSourceMappingUrl?: boolean;
|
|
36
|
+
}
|
|
37
|
+
interface InjectResult {
|
|
38
|
+
/** Bundle path relative to the directory. */
|
|
39
|
+
path: string;
|
|
40
|
+
js: string;
|
|
41
|
+
map: string;
|
|
42
|
+
debugId: string;
|
|
43
|
+
/** "injected": files were (or, in a dry run, would be) changed. */
|
|
44
|
+
status: "injected" | "unchanged" | "invalid-map";
|
|
45
|
+
}
|
|
46
|
+
/** Source map extension field recording the generated line our snippet was
|
|
47
|
+
* inserted on (its mappings were shifted down by one line from there). */
|
|
48
|
+
declare const SNIPPET_LINE_KEY = "x_autter_snippet_line";
|
|
49
|
+
/**
|
|
50
|
+
* Index of the generated line the snippet goes on, or -1 to append it at the
|
|
51
|
+
* end instead. Line 0 normally (line 1 after a `#!` shebang), so the snippet
|
|
52
|
+
* runs before the bundle's own code and registers its id even when that
|
|
53
|
+
* code throws while loading. A leading directive prologue ("use strict",
|
|
54
|
+
* "use client") must stay first, so those bundles get the snippet appended.
|
|
55
|
+
*/
|
|
56
|
+
declare function snippetLine(code: string): number;
|
|
57
|
+
/** Insert `count` empty generated lines before line `at` of a VLQ `mappings`
|
|
58
|
+
* string. Segment fields other than the column are relative across lines,
|
|
59
|
+
* so empty lines need no other change. */
|
|
60
|
+
declare function shiftMappings(mappings: string, at: number, count?: number): string;
|
|
61
|
+
/**
|
|
62
|
+
* Give one bundle its debug id. Idempotent: a bundle that already has our
|
|
63
|
+
* snippet and a `//# debugId=` comment is left byte-for-byte alone (its map
|
|
64
|
+
* only gains `debugId` if it lacks it). A bundle whose bundler already wrote
|
|
65
|
+
* a debug id comment keeps that id and only gains the snippet.
|
|
66
|
+
*/
|
|
67
|
+
declare function injectBundle(bundle: BundleWithMap, options?: InjectOptions): Promise<InjectResult>;
|
|
68
|
+
/** Inject every bundle with a map under `dir` (see injectBundle). */
|
|
69
|
+
declare function injectDir(dir: string, options?: InjectOptions): Promise<InjectResult[]>;
|
|
70
|
+
|
|
71
|
+
declare const DEFAULT_ENDPOINT = "https://otlp.autter.dev";
|
|
72
|
+
/** Largest map the ingester stores: characters of JSON without
|
|
73
|
+
* `sourcesContent` (otlp-ingester's SOURCE_MAP_MAX_CHARS). */
|
|
74
|
+
declare const MAX_MAP_CHARS: number;
|
|
75
|
+
/** The ingester's `/v1/sourcemaps` body limit, counted after the gzip body
|
|
76
|
+
* is inflated: the map plus room for the rest of the request. */
|
|
77
|
+
declare const MAX_UPLOAD_BYTES: number;
|
|
78
|
+
interface UploadOptions {
|
|
79
|
+
/** Only these bundles (absolute, or relative to the directory). */
|
|
80
|
+
files?: string[];
|
|
81
|
+
/** Default: --release resolution (see resolveRelease). */
|
|
82
|
+
release?: string;
|
|
83
|
+
/** Where the directory is served from: "/" (default), "/static/", or
|
|
84
|
+
* "https://cdn.example.com/app/". Each map is stored under prefix + path. */
|
|
85
|
+
urlPrefix?: string;
|
|
86
|
+
/** Ingester base URL. Default: $AUTTER_ENDPOINT, $AUTTER_RUNTIME_ENDPOINT,
|
|
87
|
+
* $OTEL_EXPORTER_OTLP_ENDPOINT, else https://otlp.autter.dev. */
|
|
88
|
+
endpoint?: string;
|
|
89
|
+
/** Server ingest key. Default: $AUTTER_RUNTIME_KEY. */
|
|
90
|
+
key?: string;
|
|
91
|
+
/** List what would be uploaded; no network, no key needed. */
|
|
92
|
+
dryRun?: boolean;
|
|
93
|
+
/** Parallel uploads (default 8). */
|
|
94
|
+
concurrency?: number;
|
|
95
|
+
/** Delete each `.map` (and its `sourceMappingURL` comment) once the
|
|
96
|
+
* ingester has it, so maps are never deployed. */
|
|
97
|
+
deleteAfterUpload?: boolean;
|
|
98
|
+
log?: (line: string) => void;
|
|
99
|
+
env?: NodeJS.ProcessEnv;
|
|
100
|
+
cwd?: string;
|
|
101
|
+
fetch?: typeof fetch;
|
|
102
|
+
}
|
|
103
|
+
interface UploadItem {
|
|
104
|
+
/** Bundle path relative to the directory. */
|
|
105
|
+
path: string;
|
|
106
|
+
/** Stored filename: urlPrefix + path. */
|
|
107
|
+
filename: string;
|
|
108
|
+
debugId: string | null;
|
|
109
|
+
/** sha256 of the uploaded map JSON (what the ingester stores). */
|
|
110
|
+
hash: string;
|
|
111
|
+
bytes: number;
|
|
112
|
+
}
|
|
113
|
+
interface UploadSummary {
|
|
114
|
+
release: string;
|
|
115
|
+
releaseSource: string;
|
|
116
|
+
endpoint: string;
|
|
117
|
+
dryRun: boolean;
|
|
118
|
+
uploaded: UploadItem[];
|
|
119
|
+
/** Already on the ingester with the same content: not sent again. */
|
|
120
|
+
skipped: UploadItem[];
|
|
121
|
+
failed: Array<{
|
|
122
|
+
path: string;
|
|
123
|
+
filename: string;
|
|
124
|
+
error: string;
|
|
125
|
+
}>;
|
|
126
|
+
/** True when the ingester predates 1.6.0 (no `/v1/sourcemaps/check`). */
|
|
127
|
+
legacyIngester: boolean;
|
|
128
|
+
deletedMaps: string[];
|
|
129
|
+
}
|
|
130
|
+
/** Ingester base URL from a flag or the environment, without a trailing
|
|
131
|
+
* slash or a `/v1/...` route someone pasted in. */
|
|
132
|
+
declare function resolveEndpoint(flag?: string, env?: NodeJS.ProcessEnv): string;
|
|
133
|
+
/** prefix + path, with exactly one "/" between. "~/" (Sentry's spelling) means "/". */
|
|
134
|
+
declare function servedFilename(urlPrefix: string | undefined, path: string): string;
|
|
135
|
+
/** The map as the ingester stores it: `sourcesContent` removed, compact JSON. */
|
|
136
|
+
declare function storedMapJson(map: Record<string, unknown>): string;
|
|
137
|
+
declare class FatalUploadError extends Error {
|
|
138
|
+
}
|
|
139
|
+
/** Upload every source map under `dir` to the ingester's `/v1/sourcemaps`. */
|
|
140
|
+
declare function uploadDir(dir: string, options?: UploadOptions): Promise<UploadSummary>;
|
|
141
|
+
|
|
142
|
+
/** Options shared by the Vite/Rollup, webpack and Next.js integrations. */
|
|
143
|
+
interface AutterSourceMapsOptions {
|
|
144
|
+
/** Default: GITHUB_SHA, VERCEL_GIT_COMMIT_SHA, CF_PAGES_COMMIT_SHA, GIT_SHA, then `git rev-parse HEAD`. */
|
|
145
|
+
release?: string;
|
|
146
|
+
/** Where the build output is served from. Default: the bundler's public
|
|
147
|
+
* path (Vite `base`, webpack `output.publicPath`, Next `/_next/`), else "/". */
|
|
148
|
+
urlPrefix?: string;
|
|
149
|
+
/** Ingester base URL. Default: $AUTTER_ENDPOINT, $AUTTER_RUNTIME_ENDPOINT,
|
|
150
|
+
* $OTEL_EXPORTER_OTLP_ENDPOINT, else https://otlp.autter.dev. */
|
|
151
|
+
endpoint?: string;
|
|
152
|
+
/** Server ingest key. Default: $AUTTER_RUNTIME_KEY. Without one (and
|
|
153
|
+
* without `upload: false` or `dryRun`), the plugin generates no source
|
|
154
|
+
* maps it would have to delete again: the build is left as it was. */
|
|
155
|
+
key?: string;
|
|
156
|
+
/** Set false to inject debug ids only (upload later with the CLI). Maps
|
|
157
|
+
* the plugin generated are then kept for that upload: don't deploy them. */
|
|
158
|
+
upload?: boolean;
|
|
159
|
+
/** Maps the plugin generated itself are always deleted after the upload
|
|
160
|
+
* step, uploaded or not, so they are never deployed; set false to keep
|
|
161
|
+
* them (you must then keep them out of the deploy). Maps you configured
|
|
162
|
+
* yourself are deleted only when this is true, and only once uploaded. */
|
|
163
|
+
deleteAfterUpload?: boolean;
|
|
164
|
+
/** Log what would be uploaded without sending anything. */
|
|
165
|
+
dryRun?: boolean;
|
|
166
|
+
/** Parallel uploads (default 8). */
|
|
167
|
+
concurrency?: number;
|
|
168
|
+
/** Fail the build when injecting or uploading fails (default false:
|
|
169
|
+
* telemetry never breaks a deploy; the failure is logged). */
|
|
170
|
+
failOnError?: boolean;
|
|
171
|
+
/** No log output. */
|
|
172
|
+
silent?: boolean;
|
|
173
|
+
}
|
|
174
|
+
interface BuildOutputResult {
|
|
175
|
+
injected: InjectResult[];
|
|
176
|
+
upload: UploadSummary | null;
|
|
177
|
+
/** Maps the plugin generated and deleted (paths relative to the directory). */
|
|
178
|
+
removedMaps: string[];
|
|
179
|
+
}
|
|
180
|
+
/** Human-readable lines for an upload summary (CLI and plugins). */
|
|
181
|
+
declare function formatUploadSummary(summary: UploadSummary): string[];
|
|
182
|
+
/**
|
|
183
|
+
* What every bundler integration does after a build: inject debug ids into
|
|
184
|
+
* the emitted bundles, then upload their maps when a key is present.
|
|
185
|
+
* Failures are logged, and thrown only with `failOnError`. When the
|
|
186
|
+
* integration turned source maps on itself (`ownMaps`), every map it made
|
|
187
|
+
* is deleted afterwards whatever happened to the upload (no key, a failed
|
|
188
|
+
* or partial upload, an unreachable ingester, a dry run), with the
|
|
189
|
+
* sourceMappingURL comments that name them, so none is deployed.
|
|
190
|
+
*/
|
|
191
|
+
declare function processBuildOutput(input: {
|
|
192
|
+
dir: string;
|
|
193
|
+
files?: string[];
|
|
194
|
+
urlPrefix: string;
|
|
195
|
+
options: AutterSourceMapsOptions;
|
|
196
|
+
/** Default for `deleteAfterUpload` (true when the plugin enabled maps). */
|
|
197
|
+
deleteAfterUpload: boolean;
|
|
198
|
+
stripSourceMappingUrl?: boolean;
|
|
199
|
+
/** The integration turned source maps on itself: none may be deployed. */
|
|
200
|
+
ownMaps?: boolean;
|
|
201
|
+
/** Map files the build emitted (absolute), when the bundler lists them;
|
|
202
|
+
* the maps of `files` (or of every bundle under `dir`) are added. */
|
|
203
|
+
maps?: string[];
|
|
204
|
+
}): Promise<BuildOutputResult>;
|
|
205
|
+
|
|
206
|
+
export { type AutterSourceMapsOptions as A, BUNDLE_RE as B, DEFAULT_ENDPOINT as D, FatalUploadError as F, type InjectOptions as I, MAX_MAP_CHARS as M, SNIPPET_LINE_KEY as S, type UploadItem as U, type BuildOutputResult as a, type BundleWithMap as b, type InjectResult as c, MAX_UPLOAD_BYTES as d, type UploadOptions as e, type UploadSummary as f, findBundles as g, formatUploadSummary as h, injectBundle as i, injectDir as j, resolveEndpoint as k, shiftMappings as l, mapPathFor as m, snippetLine as n, storedMapJson as o, processBuildOutput as p, stripSourceMappingUrl as q, readSourceMappingUrl as r, servedFilename as s, uploadDir as u };
|