@fixback/sdk-core 0.2.0 → 0.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 +28 -9
- package/{src/annotation.ts → dist/annotation.d.ts} +36 -47
- package/dist/anonymous-id.d.ts +23 -0
- package/dist/anonymous-id.js +39 -0
- package/dist/anonymous-id.js.map +1 -0
- package/dist/auto-capture.d.ts +129 -0
- package/dist/auto-capture.js +210 -0
- package/dist/auto-capture.js.map +1 -0
- package/{src/backoff.ts → dist/backoff.d.ts} +17 -52
- package/dist/boot.d.ts +148 -0
- package/dist/boot.js +113 -0
- package/dist/boot.js.map +1 -0
- package/dist/breadcrumb.d.ts +133 -0
- package/dist/connect.d.ts +110 -0
- package/dist/connect.js +147 -0
- package/dist/connect.js.map +1 -0
- package/dist/env.d.ts +37 -0
- package/dist/env.js +83 -0
- package/dist/env.js.map +1 -0
- package/dist/fingerprint.d.ts +39 -0
- package/dist/fingerprint.js +10 -15
- package/dist/fingerprint.js.map +1 -1
- package/dist/http.d.ts +51 -0
- package/dist/http.js +42 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.js +115 -3
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1057 -0
- package/dist/index.mjs.map +7 -0
- package/dist/options.d.ts +82 -0
- package/dist/options.js +22 -0
- package/dist/options.js.map +1 -0
- package/dist/release.d.ts +19 -0
- package/dist/release.js +36 -0
- package/dist/release.js.map +1 -0
- package/dist/scrub.d.ts +62 -0
- package/dist/stack.d.ts +51 -0
- package/dist/stack.js +97 -0
- package/dist/stack.js.map +1 -0
- package/dist/trace/buffer.d.ts +121 -0
- package/dist/trace/buffer.js +230 -0
- package/dist/trace/buffer.js.map +1 -0
- package/dist/trace/console-args.d.ts +60 -0
- package/dist/trace/console-args.js +189 -0
- package/dist/trace/console-args.js.map +1 -0
- package/dist/trace/console.d.ts +42 -0
- package/dist/trace/console.js +71 -0
- package/dist/trace/console.js.map +1 -0
- package/dist/trace/crumbs.d.ts +88 -0
- package/dist/trace/crumbs.js +164 -0
- package/dist/trace/crumbs.js.map +1 -0
- package/dist/trace/source.d.ts +30 -0
- package/dist/trace/source.js +59 -0
- package/dist/trace/source.js.map +1 -0
- package/dist/version.d.ts +13 -0
- package/dist/version.js +17 -0
- package/dist/version.js.map +1 -0
- package/dist/wire.d.ts +101 -0
- package/package.json +12 -8
- package/src/backoff.test.ts +0 -94
- package/src/breadcrumb.ts +0 -169
- package/src/fingerprint.test.ts +0 -96
- package/src/fingerprint.ts +0 -112
- package/src/index.ts +0 -63
- package/src/scrub.test.ts +0 -215
- package/src/scrub.ts +0 -226
- package/src/wire.ts +0 -116
package/dist/connect.js
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* The **Connect** wire contract (ADR-0032, CONTEXT.md "Connect") — the one copy every
|
|
4
|
+
* capture SDK speaks, kept in the shared core beside the boot contract for the same
|
|
5
|
+
* reason (`@fixback/shared` is server-shaped and private, ticket #47).
|
|
6
|
+
*
|
|
7
|
+
* Connect is the round trip that binds an Account to a site: the SDK opens the
|
|
8
|
+
* platform's connect page ({@link BootAnswer.connectUrl}), the person signs in, the
|
|
9
|
+
* page hands back a **one-time code**, and the SDK exchanges it here for a **Reporter
|
|
10
|
+
* session** — a compact token it stores per origin and forwards on every boot. Keep
|
|
11
|
+
* this in lock-step with the server: `POST /api/connect/exchange` and
|
|
12
|
+
* `POST /api/connect/signout` (`apps/api/src/connect/*`).
|
|
13
|
+
*/
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.CONNECT_RETURN_PARAM = exports.CONNECT_MESSAGE_SOURCE = void 0;
|
|
16
|
+
exports.connectExchangeEndpoint = connectExchangeEndpoint;
|
|
17
|
+
exports.connectSignOutEndpoint = connectSignOutEndpoint;
|
|
18
|
+
exports.buildConnectUrl = buildConnectUrl;
|
|
19
|
+
exports.reporterSessionStorageKey = reporterSessionStorageKey;
|
|
20
|
+
exports.parseConnectMessage = parseConnectMessage;
|
|
21
|
+
exports.isConnectExchangeResponse = isConnectExchangeResponse;
|
|
22
|
+
exports.exchangeConnectCode = exchangeConnectCode;
|
|
23
|
+
exports.revokeReporterSession = revokeReporterSession;
|
|
24
|
+
const http_1 = require("./http");
|
|
25
|
+
/**
|
|
26
|
+
* The `postMessage` a connect page in a popup sends back to the opener. `source`
|
|
27
|
+
* pins it to Fixback so an unrelated message on the window is ignored; `code` is the
|
|
28
|
+
* one-time Connect code to exchange. Read with {@link parseConnectMessage}.
|
|
29
|
+
*/
|
|
30
|
+
exports.CONNECT_MESSAGE_SOURCE = "fixback-connect";
|
|
31
|
+
/**
|
|
32
|
+
* The query parameter a Fixback link — and the connect page's **redirect fallback** —
|
|
33
|
+
* carries the one-time code back on, when a popup could not be used (ADR-0032,
|
|
34
|
+
* "arriving with the `fixback` query parameter"). The SDK detects it on boot, exchanges
|
|
35
|
+
* it, and strips it from the URL.
|
|
36
|
+
*/
|
|
37
|
+
exports.CONNECT_RETURN_PARAM = "fixback";
|
|
38
|
+
/** Join an API base URL with the Connect exchange path, tolerating a trailing slash. */
|
|
39
|
+
function connectExchangeEndpoint(apiUrl) {
|
|
40
|
+
return `${apiUrl.replace(/\/+$/, "")}/api/connect/exchange`;
|
|
41
|
+
}
|
|
42
|
+
/** Join an API base URL with the Connect sign-out path, tolerating a trailing slash. */
|
|
43
|
+
function connectSignOutEndpoint(apiUrl) {
|
|
44
|
+
return `${apiUrl.replace(/\/+$/, "")}/api/connect/signout`;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Build the connect-page URL the SDK opens (popup or redirect). `connectUrl` is the
|
|
48
|
+
* base the boot answer carried; `key` identifies the Project and `returnUrl` is where
|
|
49
|
+
* the person is sent back — validated server-side against the Project's allowed
|
|
50
|
+
* origins, so a hostile page cannot redirect the code anywhere else.
|
|
51
|
+
*/
|
|
52
|
+
function buildConnectUrl(connectUrl, params) {
|
|
53
|
+
// Built with `encodeURIComponent` rather than `URLSearchParams`/`URL` so the
|
|
54
|
+
// runtime-agnostic core needs no DOM lib (it runs on web, Expo, and Node alike).
|
|
55
|
+
const base = connectUrl.split("#")[0] ?? connectUrl;
|
|
56
|
+
const sep = base.includes("?") ? "&" : "?";
|
|
57
|
+
const query = `key=${encodeURIComponent(params.key)}` +
|
|
58
|
+
`&return=${encodeURIComponent(params.returnUrl)}`;
|
|
59
|
+
return `${base}${sep}${query}`;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* The `localStorage` key a browser SDK stores its Reporter session token under,
|
|
63
|
+
* **scoped by publishable key** so two Fixback Projects on one origin keep separate
|
|
64
|
+
* sessions (ADR-0032). The storage binding is per-runtime; the key format is shared.
|
|
65
|
+
*/
|
|
66
|
+
function reporterSessionStorageKey(publishableKey) {
|
|
67
|
+
return `fixback.reporterSession.${publishableKey}`;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Narrow an unknown `message.data` to the Connect code it carries, or `null`. Guards
|
|
71
|
+
* `source` so an unrelated `postMessage` — the web is noisy — is ignored.
|
|
72
|
+
*/
|
|
73
|
+
function parseConnectMessage(data) {
|
|
74
|
+
if (typeof data !== "object" || data === null)
|
|
75
|
+
return null;
|
|
76
|
+
const v = data;
|
|
77
|
+
if (v.source !== exports.CONNECT_MESSAGE_SOURCE)
|
|
78
|
+
return null;
|
|
79
|
+
return typeof v.code === "string" && v.code.length > 0 ? v.code : null;
|
|
80
|
+
}
|
|
81
|
+
/** Narrow an unknown JSON body to a {@link ConnectExchangeResponse}. */
|
|
82
|
+
function isConnectExchangeResponse(value) {
|
|
83
|
+
if (typeof value !== "object" || value === null)
|
|
84
|
+
return false;
|
|
85
|
+
const v = value;
|
|
86
|
+
if (typeof v.reporterSession !== "string" || v.reporterSession.length === 0) {
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
const account = v.account;
|
|
90
|
+
return (typeof account === "object" &&
|
|
91
|
+
account !== null &&
|
|
92
|
+
typeof account.name === "string" &&
|
|
93
|
+
typeof account.email === "string");
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Exchange a one-time code for a Reporter session. Resolves to the response, or `null`
|
|
97
|
+
* when Fixback was unreachable, the code was refused, or the body was not a valid
|
|
98
|
+
* response — the caller stays anonymous rather than surfacing an error into the host
|
|
99
|
+
* page (ticket #47: "fails quietly").
|
|
100
|
+
*/
|
|
101
|
+
async function exchangeConnectCode(apiUrl, request, deps = {}) {
|
|
102
|
+
const doFetch = deps.fetch ?? (0, http_1.resolveFetch)();
|
|
103
|
+
if (!doFetch)
|
|
104
|
+
return null;
|
|
105
|
+
let response;
|
|
106
|
+
try {
|
|
107
|
+
response = await doFetch(connectExchangeEndpoint(apiUrl), {
|
|
108
|
+
method: "POST",
|
|
109
|
+
headers: { "content-type": "application/json" },
|
|
110
|
+
body: JSON.stringify(request),
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
if (!response.ok)
|
|
117
|
+
return null;
|
|
118
|
+
let body;
|
|
119
|
+
try {
|
|
120
|
+
body = await response.json?.();
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
return isConnectExchangeResponse(body) ? body : null;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Revoke a Reporter session server-side ("sign out"). Best-effort: a network failure
|
|
129
|
+
* still lets the SDK clear its stored token locally, and a revoked-anyway token is
|
|
130
|
+
* refused at the next boot regardless.
|
|
131
|
+
*/
|
|
132
|
+
async function revokeReporterSession(apiUrl, token, deps = {}) {
|
|
133
|
+
const doFetch = deps.fetch ?? (0, http_1.resolveFetch)();
|
|
134
|
+
if (!doFetch)
|
|
135
|
+
return;
|
|
136
|
+
try {
|
|
137
|
+
await doFetch(connectSignOutEndpoint(apiUrl), {
|
|
138
|
+
method: "POST",
|
|
139
|
+
headers: { "content-type": "application/json" },
|
|
140
|
+
body: JSON.stringify({ reporterSession: token }),
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
// Best-effort: the local token is cleared by the caller regardless.
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=connect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connect.js","sourceRoot":"","sources":["../src/connect.ts"],"names":[],"mappings":"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"}
|
package/dist/env.d.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The **runtime probes** every capture SDK shares (ADR-0028): a high-res clock and
|
|
3
|
+
* the three byte-measuring helpers, written against `globalThis` alone so one
|
|
4
|
+
* implementation serves the browser, React Native, and Node.
|
|
5
|
+
*
|
|
6
|
+
* Each probe reads its global defensively — `performance`, `TextEncoder`, `Blob`
|
|
7
|
+
* and `ArrayBuffer` are all optional here — and falls back rather than throwing, so
|
|
8
|
+
* a runtime missing one of them degrades to a coarser measurement instead of
|
|
9
|
+
* breaking capture. Nothing in this module reads a body's *content*: a size is
|
|
10
|
+
* taken only when it is trivially known (spec #122 §D).
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* A high-res monotonic timestamp: `performance.now()` where the runtime offers it
|
|
14
|
+
* (browsers and React Native both do), else `Date.now()`. Used to order trace
|
|
15
|
+
* entries across streams and to measure request durations as a delta.
|
|
16
|
+
*/
|
|
17
|
+
export declare function nowMono(): number;
|
|
18
|
+
/**
|
|
19
|
+
* A string's UTF-8 byte length, measured with `TextEncoder` when available and
|
|
20
|
+
* falling back to the UTF-16 code-unit count otherwise. Never throws — the
|
|
21
|
+
* fallback is an approximation, not an error.
|
|
22
|
+
*/
|
|
23
|
+
export declare function utf8ByteLength(value: string): number;
|
|
24
|
+
/**
|
|
25
|
+
* The serialized UTF-8 byte length of a value; `Infinity` when it cannot be
|
|
26
|
+
* serialized at all. The cap helpers use it to bound what a single entry may
|
|
27
|
+
* carry, so an unserializable value is treated as over budget rather than shipped.
|
|
28
|
+
*/
|
|
29
|
+
export declare function serializedBytes(value: unknown): number;
|
|
30
|
+
/**
|
|
31
|
+
* The trivially-known byte size of a request body (spec #122 §D) — a string's
|
|
32
|
+
* UTF-8 length, a `Blob`'s `.size`, or an `ArrayBuffer`/typed-array `.byteLength`.
|
|
33
|
+
* Anything that would require **reading** the body (a `ReadableStream`, `FormData`,
|
|
34
|
+
* a `Request` with a stream body) returns `undefined` — the "never read the body"
|
|
35
|
+
* line holds.
|
|
36
|
+
*/
|
|
37
|
+
export declare function trivialBodySize(body: unknown): number | undefined;
|
package/dist/env.js
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* The **runtime probes** every capture SDK shares (ADR-0028): a high-res clock and
|
|
4
|
+
* the three byte-measuring helpers, written against `globalThis` alone so one
|
|
5
|
+
* implementation serves the browser, React Native, and Node.
|
|
6
|
+
*
|
|
7
|
+
* Each probe reads its global defensively — `performance`, `TextEncoder`, `Blob`
|
|
8
|
+
* and `ArrayBuffer` are all optional here — and falls back rather than throwing, so
|
|
9
|
+
* a runtime missing one of them degrades to a coarser measurement instead of
|
|
10
|
+
* breaking capture. Nothing in this module reads a body's *content*: a size is
|
|
11
|
+
* taken only when it is trivially known (spec #122 §D).
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.nowMono = nowMono;
|
|
15
|
+
exports.utf8ByteLength = utf8ByteLength;
|
|
16
|
+
exports.serializedBytes = serializedBytes;
|
|
17
|
+
exports.trivialBodySize = trivialBodySize;
|
|
18
|
+
/**
|
|
19
|
+
* A high-res monotonic timestamp: `performance.now()` where the runtime offers it
|
|
20
|
+
* (browsers and React Native both do), else `Date.now()`. Used to order trace
|
|
21
|
+
* entries across streams and to measure request durations as a delta.
|
|
22
|
+
*/
|
|
23
|
+
function nowMono() {
|
|
24
|
+
const perf = globalThis.performance;
|
|
25
|
+
return perf && typeof perf.now === "function" ? perf.now() : Date.now();
|
|
26
|
+
}
|
|
27
|
+
/** The `TextEncoder` constructor, when the runtime provides one. */
|
|
28
|
+
function textEncoder() {
|
|
29
|
+
return globalThis.TextEncoder;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* A string's UTF-8 byte length, measured with `TextEncoder` when available and
|
|
33
|
+
* falling back to the UTF-16 code-unit count otherwise. Never throws — the
|
|
34
|
+
* fallback is an approximation, not an error.
|
|
35
|
+
*/
|
|
36
|
+
function utf8ByteLength(value) {
|
|
37
|
+
try {
|
|
38
|
+
const Encoder = textEncoder();
|
|
39
|
+
return Encoder ? new Encoder().encode(value).length : value.length;
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return value.length;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* The serialized UTF-8 byte length of a value; `Infinity` when it cannot be
|
|
47
|
+
* serialized at all. The cap helpers use it to bound what a single entry may
|
|
48
|
+
* carry, so an unserializable value is treated as over budget rather than shipped.
|
|
49
|
+
*/
|
|
50
|
+
function serializedBytes(value) {
|
|
51
|
+
try {
|
|
52
|
+
const json = JSON.stringify(value) ?? "";
|
|
53
|
+
return utf8ByteLength(json);
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
return Number.POSITIVE_INFINITY;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* The trivially-known byte size of a request body (spec #122 §D) — a string's
|
|
61
|
+
* UTF-8 length, a `Blob`'s `.size`, or an `ArrayBuffer`/typed-array `.byteLength`.
|
|
62
|
+
* Anything that would require **reading** the body (a `ReadableStream`, `FormData`,
|
|
63
|
+
* a `Request` with a stream body) returns `undefined` — the "never read the body"
|
|
64
|
+
* line holds.
|
|
65
|
+
*/
|
|
66
|
+
function trivialBodySize(body) {
|
|
67
|
+
if (typeof body === "string")
|
|
68
|
+
return utf8ByteLength(body);
|
|
69
|
+
// `Blob` is optional here (the core compiles without the DOM lib) and its real
|
|
70
|
+
// constructor takes arguments, so the probe is read through `unknown` and only
|
|
71
|
+
// ever used as an `instanceof` right-hand side.
|
|
72
|
+
const BlobCtor = globalThis.Blob;
|
|
73
|
+
if (BlobCtor && body instanceof BlobCtor)
|
|
74
|
+
return body.size;
|
|
75
|
+
if (typeof ArrayBuffer !== "undefined") {
|
|
76
|
+
if (body instanceof ArrayBuffer)
|
|
77
|
+
return body.byteLength;
|
|
78
|
+
if (ArrayBuffer.isView(body))
|
|
79
|
+
return body.byteLength;
|
|
80
|
+
}
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=env.js.map
|
package/dist/env.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.js","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;AAOH,0BAGC;AAkBD,wCAOC;AAOD,0CAOC;AASD,0CAgBC;AAxED;;;;GAIG;AACH,SAAgB,OAAO;IACrB,MAAM,IAAI,GAAI,UAAuD,CAAC,WAAW,CAAC;IAClF,OAAO,IAAI,IAAI,OAAO,IAAI,CAAC,GAAG,KAAK,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;AAC1E,CAAC;AAED,oEAAoE;AACpE,SAAS,WAAW;IAGlB,OACE,UAGD,CAAC,WAAW,CAAC;AAChB,CAAC;AAED;;;;GAIG;AACH,SAAgB,cAAc,CAAC,KAAa;IAC1C,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,WAAW,EAAE,CAAC;QAC9B,OAAO,OAAO,CAAC,CAAC,CAAC,IAAI,OAAO,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC;IACrE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC,MAAM,CAAC;IACtB,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,SAAgB,eAAe,CAAC,KAAc;IAC5C,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QACzC,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,MAAM,CAAC,iBAAiB,CAAC;IAClC,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,eAAe,CAAC,IAAa;IAC3C,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC;IAC1D,+EAA+E;IAC/E,+EAA+E;IAC/E,gDAAgD;IAChD,MAAM,QAAQ,GACZ,UAGD,CAAC,IAAI,CAAC;IACP,IAAI,QAAQ,IAAI,IAAI,YAAY,QAAQ;QAAE,OAAO,IAAI,CAAC,IAAI,CAAC;IAC3D,IAAI,OAAO,WAAW,KAAK,WAAW,EAAE,CAAC;QACvC,IAAI,IAAI,YAAY,WAAW;YAAE,OAAO,IAAI,CAAC,UAAU,CAAC;QACxD,IAAI,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC;YAAE,OAAQ,IAAwB,CAAC,UAAU,CAAC;IAC5E,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The cross-surface error **fingerprint** (research `sentry-error-capture-findings.md`
|
|
3
|
+
* §7.2; ADR-0027/0028) — the pure, runtime-agnostic key by which the same logical
|
|
4
|
+
* error groups together, computed the **same way** on every SDK.
|
|
5
|
+
*
|
|
6
|
+
* `computeFingerprint(type, value, stack)` hashes the error type, a normalised
|
|
7
|
+
* message, and a compact top-frames signature. It only has to be stable and
|
|
8
|
+
* well-distributed (the client key is a flood guard; the server does canonical
|
|
9
|
+
* cross-session clustering), so a dependency-free FNV-1a hash is right. The
|
|
10
|
+
* `normalize` shape and the frame limit are **starting points** from research
|
|
11
|
+
* (ticket #92), tunable — never a frozen magic set.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Collapse the volatile parts of an error message so a changing string doesn't
|
|
15
|
+
* split one bug: UUIDs, URLs, `0x…` and long hex runs, and long digit runs are
|
|
16
|
+
* replaced with stable placeholders. Short numbers and stable text are kept so
|
|
17
|
+
* genuinely distinct bugs stay distinct. A small, dependency-free regex set —
|
|
18
|
+
* tunable per ticket #92, never a frozen magic set.
|
|
19
|
+
*/
|
|
20
|
+
export declare function normalize(value: string): string;
|
|
21
|
+
/**
|
|
22
|
+
* A dependency-free FNV-1a hash rendered in base-36. It only has to be stable and
|
|
23
|
+
* well-distributed within one session (the client key is a flood guard; the server
|
|
24
|
+
* does canonical cross-session clustering), so a non-cryptographic hash is right.
|
|
25
|
+
*/
|
|
26
|
+
export declare function hashString(input: string): string;
|
|
27
|
+
/**
|
|
28
|
+
* Extract a compact, stable signature of the top in-app frames of a stack: up to
|
|
29
|
+
* {@link FINGERPRINT_FRAME_LIMIT} frames as `function@basename:line:col`, origin
|
|
30
|
+
* and cache-busting query stripped so a per-deploy asset hash doesn't matter within
|
|
31
|
+
* a session. Returns `""` when there is no usable stack (message-only fallback).
|
|
32
|
+
*/
|
|
33
|
+
export declare function extractTopFrames(stack: string | undefined, limit?: number): string;
|
|
34
|
+
/**
|
|
35
|
+
* The per-session fingerprint (research §7.2):
|
|
36
|
+
* `hash(errorType + "|" + normalize(value) + "|" + topFrames)`. Stack frames
|
|
37
|
+
* dominate when present; otherwise it falls back to type + normalized value.
|
|
38
|
+
*/
|
|
39
|
+
export declare function computeFingerprint(type: string, value: string, stack?: string): string;
|
package/dist/fingerprint.js
CHANGED
|
@@ -16,6 +16,7 @@ exports.normalize = normalize;
|
|
|
16
16
|
exports.hashString = hashString;
|
|
17
17
|
exports.extractTopFrames = extractTopFrames;
|
|
18
18
|
exports.computeFingerprint = computeFingerprint;
|
|
19
|
+
const stack_1 = require("./stack");
|
|
19
20
|
const UUID_RE = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi;
|
|
20
21
|
const URL_RE = /\bhttps?:\/\/[^\s"')]+/gi;
|
|
21
22
|
const HEX_0X_RE = /\b0x[0-9a-f]+\b/gi;
|
|
@@ -60,22 +61,16 @@ function compactLocation(location) {
|
|
|
60
61
|
const lastSlash = noQuery.lastIndexOf("/");
|
|
61
62
|
return lastSlash >= 0 ? noQuery.slice(lastSlash + 1) : noQuery;
|
|
62
63
|
}
|
|
63
|
-
/**
|
|
64
|
+
/**
|
|
65
|
+
* Reduce one stack line to a compact `function@basename:line:col` frame id, using
|
|
66
|
+
* the core's single frame tokenizer (`stack.ts`) so the fingerprint sees exactly
|
|
67
|
+
* the frames every other stack reader does.
|
|
68
|
+
*/
|
|
64
69
|
function parseFrame(line) {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
const v8Bare = line.match(/^at\s+(.+)$/);
|
|
70
|
-
if (v8Bare)
|
|
71
|
-
return `@${compactLocation(v8Bare[1] ?? "")}`;
|
|
72
|
-
// Firefox / Safari: "fn@loc" | "@loc"
|
|
73
|
-
const at = line.indexOf("@");
|
|
74
|
-
if (at >= 0) {
|
|
75
|
-
const fn = line.slice(0, at);
|
|
76
|
-
return `${fn}@${compactLocation(line.slice(at + 1))}`;
|
|
77
|
-
}
|
|
78
|
-
return null;
|
|
70
|
+
const tokens = (0, stack_1.parseStackLine)(line);
|
|
71
|
+
if (!tokens)
|
|
72
|
+
return null;
|
|
73
|
+
return `${tokens.fn ?? ""}@${compactLocation(tokens.location)}`;
|
|
79
74
|
}
|
|
80
75
|
/**
|
|
81
76
|
* Extract a compact, stable signature of the top in-app frames of a stack: up to
|
package/dist/fingerprint.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fingerprint.js","sourceRoot":"","sources":["../src/fingerprint.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;GAWG;;
|
|
1
|
+
{"version":3,"file":"fingerprint.js","sourceRoot":"","sources":["../src/fingerprint.ts"],"names":[],"mappings":"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"}
|
package/dist/http.d.ts
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The **structural HTTP surface** every Fixback SDK talks to ingest through
|
|
3
|
+
* (ADR-0028) — one description of the `fetch` slice the transports use, shared by
|
|
4
|
+
* the browser, Expo, and Node SDKs.
|
|
5
|
+
*
|
|
6
|
+
* Described structurally rather than against the DOM lib: the core typechecks with
|
|
7
|
+
* `types: []` and no `lib.dom`, React Native is not a browser, and Node's `fetch`
|
|
8
|
+
* is a global with its own types. Every runtime satisfies these shapes at runtime,
|
|
9
|
+
* and tests inject plain fakes through the same seams. Only what the SDKs actually
|
|
10
|
+
* read is described — status, `ok`, one header at a time, and an optional JSON body.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* The response slice the transports read: the outcome, the status, the header bag
|
|
14
|
+
* (for `Retry-After` / `content-length`), and — for the endpoints that answer with
|
|
15
|
+
* JSON — the parsed body. `json()` is **optional**: the batched Node transport
|
|
16
|
+
* never reads a body, so a fake need not provide one.
|
|
17
|
+
*/
|
|
18
|
+
export interface FetchResponseLike {
|
|
19
|
+
readonly ok: boolean;
|
|
20
|
+
readonly status: number;
|
|
21
|
+
readonly headers?: {
|
|
22
|
+
get(name: string): string | null;
|
|
23
|
+
} | null;
|
|
24
|
+
json?(): Promise<unknown>;
|
|
25
|
+
}
|
|
26
|
+
/** The request init the SDKs send — a method, plain headers, and a body. */
|
|
27
|
+
export interface FetchRequestInit {
|
|
28
|
+
readonly method: string;
|
|
29
|
+
readonly headers?: Record<string, string>;
|
|
30
|
+
/**
|
|
31
|
+
* The request body: a JSON string, or a runtime-specific multipart form (a
|
|
32
|
+
* browser `FormData`, React Native's `FormData`). Deliberately `unknown` — the
|
|
33
|
+
* core never inspects it, it only hands it to the runtime's `fetch`.
|
|
34
|
+
*/
|
|
35
|
+
readonly body?: unknown;
|
|
36
|
+
}
|
|
37
|
+
/** A `fetch`-shaped function, injectable for tests. */
|
|
38
|
+
export type FetchLike = (url: string, init: FetchRequestInit) => Promise<FetchResponseLike>;
|
|
39
|
+
/**
|
|
40
|
+
* The runtime's global `fetch` adapted to {@link FetchLike}, or `undefined` when
|
|
41
|
+
* the runtime has none. Bound to `globalThis` so a `this`-less call never throws
|
|
42
|
+
* an "illegal invocation", and adapted through one cast here so no call site has
|
|
43
|
+
* to reconcile the runtime's own `fetch` types with the structural slice.
|
|
44
|
+
*/
|
|
45
|
+
export declare function resolveFetch(): FetchLike | undefined;
|
|
46
|
+
/**
|
|
47
|
+
* Read one response header defensively — `null` when the response carries no
|
|
48
|
+
* header bag, the header is absent, or the getter throws (an opaque cross-origin
|
|
49
|
+
* response). A transport must never fail because a header could not be read.
|
|
50
|
+
*/
|
|
51
|
+
export declare function safeHeader(response: FetchResponseLike, name: string): string | null;
|
package/dist/http.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* The **structural HTTP surface** every Fixback SDK talks to ingest through
|
|
4
|
+
* (ADR-0028) — one description of the `fetch` slice the transports use, shared by
|
|
5
|
+
* the browser, Expo, and Node SDKs.
|
|
6
|
+
*
|
|
7
|
+
* Described structurally rather than against the DOM lib: the core typechecks with
|
|
8
|
+
* `types: []` and no `lib.dom`, React Native is not a browser, and Node's `fetch`
|
|
9
|
+
* is a global with its own types. Every runtime satisfies these shapes at runtime,
|
|
10
|
+
* and tests inject plain fakes through the same seams. Only what the SDKs actually
|
|
11
|
+
* read is described — status, `ok`, one header at a time, and an optional JSON body.
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.resolveFetch = resolveFetch;
|
|
15
|
+
exports.safeHeader = safeHeader;
|
|
16
|
+
/**
|
|
17
|
+
* The runtime's global `fetch` adapted to {@link FetchLike}, or `undefined` when
|
|
18
|
+
* the runtime has none. Bound to `globalThis` so a `this`-less call never throws
|
|
19
|
+
* an "illegal invocation", and adapted through one cast here so no call site has
|
|
20
|
+
* to reconcile the runtime's own `fetch` types with the structural slice.
|
|
21
|
+
*/
|
|
22
|
+
function resolveFetch() {
|
|
23
|
+
const g = globalThis;
|
|
24
|
+
if (typeof g.fetch !== "function")
|
|
25
|
+
return undefined;
|
|
26
|
+
const bound = g.fetch.bind(globalThis);
|
|
27
|
+
return (url, init) => bound(url, init);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Read one response header defensively — `null` when the response carries no
|
|
31
|
+
* header bag, the header is absent, or the getter throws (an opaque cross-origin
|
|
32
|
+
* response). A transport must never fail because a header could not be read.
|
|
33
|
+
*/
|
|
34
|
+
function safeHeader(response, name) {
|
|
35
|
+
try {
|
|
36
|
+
return response.headers?.get?.(name) ?? null;
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=http.js.map
|
package/dist/http.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;AAuCH,oCAOC;AAOD,gCAMC;AA1BD;;;;;GAKG;AACH,SAAgB,YAAY;IAC1B,MAAM,CAAC,GAAG,UAET,CAAC;IACF,IAAI,OAAO,CAAC,CAAC,KAAK,KAAK,UAAU;QAAE,OAAO,SAAS,CAAC;IACpD,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACvC,OAAO,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,CAA+B,CAAC;AACvE,CAAC;AAED;;;;GAIG;AACH,SAAgB,UAAU,CAAC,QAA2B,EAAE,IAAY;IAClE,IAAI,CAAC;QACH,OAAO,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC;IAC/C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@fixback/sdk-core` — the runtime-agnostic core shared by the Fixback capture
|
|
3
|
+
* SDKs (ADR-0028). Fingerprinting, stack parsing, scrubbing, backoff, the trace
|
|
4
|
+
* buffer and its crumb builders, the automatic-capture state machine, the ingest
|
|
5
|
+
* boot contract, and the shared wire shapes — with no DOM, no Node built-ins, and
|
|
6
|
+
* no rrweb. Every runtime touchpoint is either injected or probed off `globalThis`.
|
|
7
|
+
*/
|
|
8
|
+
export { SDK_CORE_VERSION } from "./version";
|
|
9
|
+
export { computeFingerprint, extractTopFrames, hashString, normalize } from "./fingerprint";
|
|
10
|
+
export { extractStructuredFrames, parseFrameLocation, parseStackLine, type StackFrameTokens, } from "./stack";
|
|
11
|
+
export { applyDefaultScrub, type BeforeSend, type BeforeSendOptions, redactPii, runBeforeSend, scrubUrl, } from "./scrub";
|
|
12
|
+
export { AutoReportBackoff, type Clock, DEFAULT_RETRY_AFTER_SECONDS, parseRetryAfter, } from "./backoff";
|
|
13
|
+
export { nowMono, serializedBytes, trivialBodySize, utf8ByteLength } from "./env";
|
|
14
|
+
export { type FetchLike, type FetchRequestInit, type FetchResponseLike, resolveFetch, safeHeader, } from "./http";
|
|
15
|
+
export { type BootAnswer, type BootDeps, bootEndpoint, type BootRequest, type CaptureConfig, compactIdentity, type ConnectedAccount, feedbackEndpoint, type IdentityInputs, isBootAnswer, isFixbackApiRequest, type ProjectGate, type ReporterTier, requestBoot, } from "./boot";
|
|
16
|
+
export { buildConnectUrl, CONNECT_MESSAGE_SOURCE, CONNECT_RETURN_PARAM, type ConnectDeps, type ConnectExchangeRequest, type ConnectExchangeResponse, type ConnectMessage, connectExchangeEndpoint, connectSignOutEndpoint, exchangeConnectCode, isConnectExchangeResponse, parseConnectMessage, type ReporterIdentity, reporterSessionStorageKey, revokeReporterSession, } from "./connect";
|
|
17
|
+
export { ANONYMOUS_ID_STORAGE_KEY, generateAnonymousId } from "./anonymous-id";
|
|
18
|
+
export { normaliseRelease, RELEASE_MAX_LENGTH } from "./release";
|
|
19
|
+
export { type CaptureToggles, type CommonCaptureInitOptions, type CommonInitOptions, DEFAULT_API_URL, } from "./options";
|
|
20
|
+
export { type AutoCaptureCore, type AutoCaptureCoreConfig, type AutoReport, asString, CAUSED_BY_LIMIT, createAutoCapture, DEFAULT_BURST_CAPACITY, DEFAULT_BURST_REFILL_MS, DEFAULT_MAX_DISTINCT_AUTO, type ExtractedError, precedingIds, TokenBucket, type TokenBucketOptions, } from "./auto-capture";
|
|
21
|
+
export { type BeforeBreadcrumb, type BreadcrumbBuffer, type BreadcrumbBufferConfig, capturesSource, createBreadcrumbBuffer, createIdFactory, DEFAULT_CONSOLE_LEVELS, DEFAULT_MAX_AGE_MS, DEFAULT_STREAM_BUDGETS, isPinnedConsoleLevel, normalizeBudget, PINNED_CONSOLE_LEVELS, SOURCE_CAPTURE_LEVELS, streamOf, type TraceStream, trimConsoleStream, } from "./trace/buffer";
|
|
22
|
+
export { capConsoleArgs, capLength, describeErrorValue, joinArgs, MAX_ARG_DEPTH, MAX_ARG_ITEMS, MAX_ARG_STRING_LENGTH, MAX_CONSOLE_ARGS_BYTES, MAX_MESSAGE_LENGTH, safeCloneValue, stringifyArg, toConsoleArg, } from "./trace/console-args";
|
|
23
|
+
export { consoleCrumb, contentTypeOf, describeError, errorCrumb, fetchCrumb, MAX_URL_LENGTH, navigationCrumb, type NetworkCrumbInput, networkCrumb, outcomeFromStatus, parseContentLength, xhrCrumb, } from "./trace/crumbs";
|
|
24
|
+
export { CONSOLE_SOURCE_SKIP_FRAMES, parseStackFrame, sourceFromStack, } from "./trace/source";
|
|
25
|
+
export { type ConsoleLike, instrumentConsole, type Teardown } from "./trace/console";
|
|
26
|
+
export type { CaptureEnvironment, CapturedFrame, FeedbackSource, Platform, ReportContent, } from "./wire";
|
|
27
|
+
export type { Annotation, ArrowMark, BoxMark, DrawTool, ElementRect, Mark, PenMark, Point, Rect, SelectedElement, TextMark, } from "./annotation";
|
|
28
|
+
export type { Breadcrumb, BreadcrumbCategory, BreadcrumbData, BreadcrumbLevel, ConsoleArg, ConsoleArgType, NetworkApi, NetworkOutcome, SourceLocation, } from "./breadcrumb";
|