@fixprompt/browser 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/console.d.ts +2 -0
- package/dist/fetch.d.ts +8 -0
- package/dist/handlers.d.ts +5 -0
- package/dist/index.cjs +422 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.global.js +416 -0
- package/dist/index.global.js.map +1 -0
- package/dist/index.js +390 -0
- package/dist/index.js.map +1 -0
- package/dist/init.d.ts +16 -0
- package/dist/init.spec.d.ts +1 -0
- package/dist/react.cjs +182 -0
- package/dist/react.cjs.map +1 -0
- package/dist/react.d.ts +16 -0
- package/dist/react.js +147 -0
- package/dist/react.js.map +1 -0
- package/dist/release.d.ts +14 -0
- package/dist/session.d.ts +1 -0
- package/dist/state.d.ts +16 -0
- package/dist/transport.d.ts +12 -0
- package/dist/types.d.ts +43 -0
- package/dist/version.d.ts +2 -0
- package/package.json +61 -0
|
@@ -0,0 +1,416 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var FixPrompt = (() => {
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
|
|
21
|
+
// src/index.ts
|
|
22
|
+
var src_exports = {};
|
|
23
|
+
__export(src_exports, {
|
|
24
|
+
SDK_NAME: () => SDK_NAME,
|
|
25
|
+
SDK_VERSION: () => SDK_VERSION,
|
|
26
|
+
_resetForTests: () => _resetForTests,
|
|
27
|
+
captureException: () => captureException,
|
|
28
|
+
initFixPrompt: () => initFixPrompt
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
// src/version.ts
|
|
32
|
+
var SDK_NAME = "@fixprompt/browser";
|
|
33
|
+
var SDK_VERSION = "0.0.1";
|
|
34
|
+
|
|
35
|
+
// src/session.ts
|
|
36
|
+
var STORAGE_KEY = "fixprompt_sid";
|
|
37
|
+
function uuid() {
|
|
38
|
+
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
39
|
+
return crypto.randomUUID();
|
|
40
|
+
}
|
|
41
|
+
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
|
|
42
|
+
const r = Math.random() * 16 | 0;
|
|
43
|
+
const v = c === "x" ? r : r & 3 | 8;
|
|
44
|
+
return v.toString(16);
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
function getSessionId() {
|
|
48
|
+
try {
|
|
49
|
+
if (typeof sessionStorage !== "undefined") {
|
|
50
|
+
const existing = sessionStorage.getItem(STORAGE_KEY);
|
|
51
|
+
if (existing) return existing;
|
|
52
|
+
const sid = uuid();
|
|
53
|
+
sessionStorage.setItem(STORAGE_KEY, sid);
|
|
54
|
+
return sid;
|
|
55
|
+
}
|
|
56
|
+
} catch {
|
|
57
|
+
}
|
|
58
|
+
return uuid();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// src/transport.ts
|
|
62
|
+
function sendEvent(config, payload) {
|
|
63
|
+
try {
|
|
64
|
+
const body = {
|
|
65
|
+
service: payload.service ?? config.service,
|
|
66
|
+
app: payload.app ?? config.app,
|
|
67
|
+
env: payload.env ?? config.env,
|
|
68
|
+
level: payload.level,
|
|
69
|
+
message: payload.message,
|
|
70
|
+
stack: payload.stack,
|
|
71
|
+
attrs: {
|
|
72
|
+
...payload.attrs,
|
|
73
|
+
sdk: SDK_NAME,
|
|
74
|
+
sdk_version: SDK_VERSION,
|
|
75
|
+
session_id: getSessionId(),
|
|
76
|
+
release: config.release,
|
|
77
|
+
page_url: typeof location !== "undefined" ? location.href : void 0,
|
|
78
|
+
user_agent: typeof navigator !== "undefined" ? navigator.userAgent : void 0
|
|
79
|
+
},
|
|
80
|
+
synthetic: payload.synthetic
|
|
81
|
+
};
|
|
82
|
+
const url = `${config.endpoint.replace(/\/$/, "")}/ingest/log`;
|
|
83
|
+
const json = JSON.stringify(body);
|
|
84
|
+
const headers = {
|
|
85
|
+
"Content-Type": "application/json",
|
|
86
|
+
"x-loghub-source": config.source,
|
|
87
|
+
"x-loghub-key": config.projectKey
|
|
88
|
+
};
|
|
89
|
+
if (typeof navigator !== "undefined" && typeof navigator.sendBeacon === "function" && // sendBeacon does not allow custom headers, so we use it only as
|
|
90
|
+
// a last-resort fallback once we add a URL-token path. Until then,
|
|
91
|
+
// prefer fetch+keepalive so auth headers are honored.
|
|
92
|
+
false) {
|
|
93
|
+
const blob = new Blob([json], { type: "application/json" });
|
|
94
|
+
navigator.sendBeacon(url, blob);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
if (typeof fetch === "function") {
|
|
98
|
+
void fetch(url, {
|
|
99
|
+
method: "POST",
|
|
100
|
+
headers,
|
|
101
|
+
body: json,
|
|
102
|
+
keepalive: true,
|
|
103
|
+
mode: "cors",
|
|
104
|
+
credentials: "omit"
|
|
105
|
+
}).catch(() => void 0);
|
|
106
|
+
}
|
|
107
|
+
} catch (err) {
|
|
108
|
+
if (config.debug) {
|
|
109
|
+
console.warn("[fixprompt] transport error", err);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// src/handlers.ts
|
|
115
|
+
function installGlobalHandlers(config) {
|
|
116
|
+
const onError = (ev) => {
|
|
117
|
+
const err = ev.error;
|
|
118
|
+
sendEvent(config, {
|
|
119
|
+
level: "error",
|
|
120
|
+
message: ev.message ?? (err && err.message) ?? "Unknown error",
|
|
121
|
+
stack: err && typeof err.stack === "string" ? err.stack : void 0,
|
|
122
|
+
attrs: {
|
|
123
|
+
kind: "window.error",
|
|
124
|
+
severity: "error",
|
|
125
|
+
filename: ev.filename,
|
|
126
|
+
line: ev.lineno,
|
|
127
|
+
column: ev.colno,
|
|
128
|
+
error_name: err && err.name
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
};
|
|
132
|
+
const onRejection = (ev) => {
|
|
133
|
+
const reason = ev.reason;
|
|
134
|
+
const isErr = reason instanceof Error;
|
|
135
|
+
sendEvent(config, {
|
|
136
|
+
level: "error",
|
|
137
|
+
message: isErr ? reason.message : typeof reason === "string" ? reason : safeJson(reason),
|
|
138
|
+
stack: isErr && typeof reason.stack === "string" ? reason.stack : void 0,
|
|
139
|
+
attrs: {
|
|
140
|
+
kind: "unhandledrejection",
|
|
141
|
+
severity: "error",
|
|
142
|
+
error_name: isErr ? reason.name : typeof reason
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
};
|
|
146
|
+
window.addEventListener("error", onError);
|
|
147
|
+
window.addEventListener("unhandledrejection", onRejection);
|
|
148
|
+
return {
|
|
149
|
+
removeErrorListener: () => window.removeEventListener("error", onError),
|
|
150
|
+
removeRejectionListener: () => window.removeEventListener("unhandledrejection", onRejection)
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
function safeJson(v) {
|
|
154
|
+
try {
|
|
155
|
+
return JSON.stringify(v);
|
|
156
|
+
} catch {
|
|
157
|
+
return String(v);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// src/console.ts
|
|
162
|
+
function patchConsoleError(config) {
|
|
163
|
+
const original = console.error;
|
|
164
|
+
console.error = function patchedError(...args) {
|
|
165
|
+
try {
|
|
166
|
+
const stackFrom = args.find((a) => a instanceof Error);
|
|
167
|
+
sendEvent(config, {
|
|
168
|
+
level: "warn",
|
|
169
|
+
message: args.map(
|
|
170
|
+
(a) => a instanceof Error ? a.message : typeof a === "string" ? a : safeJson2(a)
|
|
171
|
+
).join(" "),
|
|
172
|
+
stack: stackFrom && typeof stackFrom.stack === "string" ? stackFrom.stack : void 0,
|
|
173
|
+
attrs: {
|
|
174
|
+
kind: "console.error",
|
|
175
|
+
severity: "warning"
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
} catch {
|
|
179
|
+
}
|
|
180
|
+
return original.apply(console, args);
|
|
181
|
+
};
|
|
182
|
+
return () => {
|
|
183
|
+
console.error = original;
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
function safeJson2(v) {
|
|
187
|
+
try {
|
|
188
|
+
return JSON.stringify(v);
|
|
189
|
+
} catch {
|
|
190
|
+
return String(v);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// src/fetch.ts
|
|
195
|
+
function wrapFetch(config) {
|
|
196
|
+
if (typeof fetch !== "function") return () => void 0;
|
|
197
|
+
const original = fetch.bind(globalThis);
|
|
198
|
+
const brokerHost = safeHost(config.endpoint);
|
|
199
|
+
const patched = async (...args) => {
|
|
200
|
+
const t0 = nowMs();
|
|
201
|
+
const [input, init] = args;
|
|
202
|
+
const method = init && init.method || (input instanceof Request ? input.method : "GET");
|
|
203
|
+
const url = urlString(input);
|
|
204
|
+
if (url.startsWith(config.endpoint) || safeHost(url) === brokerHost) {
|
|
205
|
+
return original(...args);
|
|
206
|
+
}
|
|
207
|
+
try {
|
|
208
|
+
const response = await original(...args);
|
|
209
|
+
const status = response.status;
|
|
210
|
+
const latency = Math.round(nowMs() - t0);
|
|
211
|
+
if (status >= 400) {
|
|
212
|
+
sendEvent(config, {
|
|
213
|
+
level: status >= 500 ? "error" : "warn",
|
|
214
|
+
message: `fetch ${method} ${stripQuery(url)} \u2192 ${status}`,
|
|
215
|
+
attrs: {
|
|
216
|
+
kind: "fetch",
|
|
217
|
+
severity: status >= 500 ? "critical" : "warning",
|
|
218
|
+
method,
|
|
219
|
+
url: stripQuery(url),
|
|
220
|
+
status,
|
|
221
|
+
latency_ms: latency
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
return response;
|
|
226
|
+
} catch (err) {
|
|
227
|
+
const latency = Math.round(nowMs() - t0);
|
|
228
|
+
sendEvent(config, {
|
|
229
|
+
level: "error",
|
|
230
|
+
message: `fetch ${method} ${stripQuery(url)} failed: ${err?.message ?? String(err)}`,
|
|
231
|
+
stack: err?.stack,
|
|
232
|
+
attrs: {
|
|
233
|
+
kind: "fetch",
|
|
234
|
+
severity: "critical",
|
|
235
|
+
method,
|
|
236
|
+
url: stripQuery(url),
|
|
237
|
+
latency_ms: latency,
|
|
238
|
+
error_name: err?.name
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
throw err;
|
|
242
|
+
}
|
|
243
|
+
};
|
|
244
|
+
globalThis.fetch = patched;
|
|
245
|
+
return () => {
|
|
246
|
+
globalThis.fetch = original;
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
function urlString(input) {
|
|
250
|
+
if (typeof input === "string") return input;
|
|
251
|
+
if (input instanceof URL) return input.toString();
|
|
252
|
+
if (input instanceof Request) return input.url;
|
|
253
|
+
return String(input);
|
|
254
|
+
}
|
|
255
|
+
function stripQuery(url) {
|
|
256
|
+
const q = url.indexOf("?");
|
|
257
|
+
return q === -1 ? url : url.slice(0, q);
|
|
258
|
+
}
|
|
259
|
+
function safeHost(url) {
|
|
260
|
+
try {
|
|
261
|
+
return new URL(url).host;
|
|
262
|
+
} catch {
|
|
263
|
+
return "";
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
function nowMs() {
|
|
267
|
+
if (typeof performance !== "undefined" && typeof performance.now === "function") {
|
|
268
|
+
return performance.now();
|
|
269
|
+
}
|
|
270
|
+
return Date.now();
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// src/release.ts
|
|
274
|
+
var import_meta = {};
|
|
275
|
+
function fromImportMeta() {
|
|
276
|
+
try {
|
|
277
|
+
const meta = import_meta.env;
|
|
278
|
+
if (!meta) return null;
|
|
279
|
+
return meta.NEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA || meta.VERCEL_GIT_COMMIT_SHA || meta.NEXT_PUBLIC_COMMIT_SHA || null;
|
|
280
|
+
} catch {
|
|
281
|
+
return null;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
function fromProcessEnv() {
|
|
285
|
+
try {
|
|
286
|
+
if (typeof process === "undefined" || !process || !process.env) return null;
|
|
287
|
+
return process.env.GITHUB_SHA || process.env.RELEASE || null;
|
|
288
|
+
} catch {
|
|
289
|
+
return null;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
function fromGlobal() {
|
|
293
|
+
try {
|
|
294
|
+
const g = globalThis;
|
|
295
|
+
return typeof g.__FIXPROMPT_RELEASE__ === "string" ? g.__FIXPROMPT_RELEASE__ : null;
|
|
296
|
+
} catch {
|
|
297
|
+
return null;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
function fromMetaTag() {
|
|
301
|
+
try {
|
|
302
|
+
if (typeof document === "undefined") return null;
|
|
303
|
+
const el = document.querySelector('meta[name="fixprompt-release"]');
|
|
304
|
+
const content = el?.getAttribute("content");
|
|
305
|
+
return content && content.length > 0 ? content : null;
|
|
306
|
+
} catch {
|
|
307
|
+
return null;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
function detectRelease(explicit) {
|
|
311
|
+
if (typeof explicit === "string" && explicit.length > 0) return explicit;
|
|
312
|
+
return fromImportMeta() || fromProcessEnv() || fromGlobal() || fromMetaTag() || null;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// src/state.ts
|
|
316
|
+
var STATE_KEY = "__fixprompt_browser_state__";
|
|
317
|
+
function globalScope() {
|
|
318
|
+
if (typeof globalThis !== "undefined") return globalThis;
|
|
319
|
+
if (typeof window !== "undefined") return window;
|
|
320
|
+
return {};
|
|
321
|
+
}
|
|
322
|
+
function getState() {
|
|
323
|
+
const g = globalScope();
|
|
324
|
+
if (!g[STATE_KEY]) {
|
|
325
|
+
g[STATE_KEY] = {
|
|
326
|
+
initialized: false,
|
|
327
|
+
config: null,
|
|
328
|
+
sessionId: null,
|
|
329
|
+
cleanup: {}
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
return g[STATE_KEY];
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
// src/init.ts
|
|
336
|
+
var DEFAULT_ENDPOINT = "https://geosloghub-production.up.railway.app";
|
|
337
|
+
function resolveConfig(opts) {
|
|
338
|
+
if (!opts || typeof opts.projectKey !== "string" || opts.projectKey.length === 0) {
|
|
339
|
+
throw new Error("initFixPrompt: projectKey is required");
|
|
340
|
+
}
|
|
341
|
+
return {
|
|
342
|
+
projectKey: opts.projectKey,
|
|
343
|
+
endpoint: (opts.endpoint ?? DEFAULT_ENDPOINT).replace(/\/$/, ""),
|
|
344
|
+
source: opts.source ?? "browser",
|
|
345
|
+
release: detectRelease(opts.release),
|
|
346
|
+
service: opts.service ?? "web",
|
|
347
|
+
app: opts.app ?? "browser",
|
|
348
|
+
env: opts.env ?? "prod",
|
|
349
|
+
wrapFetch: opts.wrapFetch ?? false,
|
|
350
|
+
patchConsoleError: opts.patchConsoleError ?? true,
|
|
351
|
+
debug: opts.debug ?? false
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
function initFixPrompt(opts) {
|
|
355
|
+
const state = getState();
|
|
356
|
+
if (state.initialized) {
|
|
357
|
+
if (opts.debug) {
|
|
358
|
+
console.warn("[fixprompt] already initialized \u2014 call ignored");
|
|
359
|
+
}
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
if (typeof window === "undefined") {
|
|
363
|
+
return;
|
|
364
|
+
}
|
|
365
|
+
const config = resolveConfig(opts);
|
|
366
|
+
state.config = config;
|
|
367
|
+
state.sessionId = getSessionId();
|
|
368
|
+
const { removeErrorListener, removeRejectionListener } = installGlobalHandlers(config);
|
|
369
|
+
state.cleanup.removeErrorListener = removeErrorListener;
|
|
370
|
+
state.cleanup.removeRejectionListener = removeRejectionListener;
|
|
371
|
+
if (config.patchConsoleError) {
|
|
372
|
+
state.cleanup.restoreConsoleError = patchConsoleError(config);
|
|
373
|
+
}
|
|
374
|
+
if (config.wrapFetch) {
|
|
375
|
+
state.cleanup.restoreFetch = wrapFetch(config);
|
|
376
|
+
}
|
|
377
|
+
state.initialized = true;
|
|
378
|
+
if (config.debug) {
|
|
379
|
+
console.log("[fixprompt] initialized", {
|
|
380
|
+
endpoint: config.endpoint,
|
|
381
|
+
release: config.release,
|
|
382
|
+
session_id: state.sessionId
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
function captureException(err, options = {}) {
|
|
387
|
+
const state = getState();
|
|
388
|
+
if (!state.initialized || !state.config) return;
|
|
389
|
+
const isErr = err instanceof Error;
|
|
390
|
+
sendEvent(state.config, {
|
|
391
|
+
level: "error",
|
|
392
|
+
message: isErr ? err.message : String(err),
|
|
393
|
+
stack: isErr && typeof err.stack === "string" ? err.stack : void 0,
|
|
394
|
+
attrs: {
|
|
395
|
+
kind: "captureException",
|
|
396
|
+
severity: "error",
|
|
397
|
+
error_name: isErr ? err.name : typeof err,
|
|
398
|
+
...options.attrs ?? {}
|
|
399
|
+
},
|
|
400
|
+
synthetic: options.synthetic === true
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
function _resetForTests() {
|
|
404
|
+
const state = getState();
|
|
405
|
+
state.cleanup.removeErrorListener?.();
|
|
406
|
+
state.cleanup.removeRejectionListener?.();
|
|
407
|
+
state.cleanup.restoreConsoleError?.();
|
|
408
|
+
state.cleanup.restoreFetch?.();
|
|
409
|
+
state.initialized = false;
|
|
410
|
+
state.config = null;
|
|
411
|
+
state.sessionId = null;
|
|
412
|
+
state.cleanup = {};
|
|
413
|
+
}
|
|
414
|
+
return __toCommonJS(src_exports);
|
|
415
|
+
})();
|
|
416
|
+
//# sourceMappingURL=index.global.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/version.ts","../src/session.ts","../src/transport.ts","../src/handlers.ts","../src/console.ts","../src/fetch.ts","../src/release.ts","../src/state.ts","../src/init.ts"],"sourcesContent":["export { initFixPrompt, captureException, _resetForTests } from './init';\nexport type {\n InitOptions,\n ResolvedConfig,\n EventPayload,\n Severity,\n} from './types';\nexport { SDK_NAME, SDK_VERSION } from './version';\n","export const SDK_NAME = '@fixprompt/browser';\nexport const SDK_VERSION = '0.0.1';\n","const STORAGE_KEY = 'fixprompt_sid';\n\nfunction uuid(): string {\n if (\n typeof crypto !== 'undefined' &&\n typeof crypto.randomUUID === 'function'\n ) {\n return crypto.randomUUID();\n }\n // RFC 4122 v4-ish fallback for older browsers\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const r = (Math.random() * 16) | 0;\n const v = c === 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n}\n\nexport function getSessionId(): string {\n try {\n if (typeof sessionStorage !== 'undefined') {\n const existing = sessionStorage.getItem(STORAGE_KEY);\n if (existing) return existing;\n const sid = uuid();\n sessionStorage.setItem(STORAGE_KEY, sid);\n return sid;\n }\n } catch {\n // sessionStorage may throw under quota / privacy modes\n }\n return uuid();\n}\n","import { SDK_NAME, SDK_VERSION } from './version';\nimport { getSessionId } from './session';\nimport type { EventPayload, ResolvedConfig } from './types';\n\n/**\n * Sends one event to the broker. Fire-and-forget — never throws.\n *\n * Uses navigator.sendBeacon when available for pagehide reliability;\n * falls back to fetch with keepalive.\n */\nexport function sendEvent(\n config: ResolvedConfig,\n payload: Omit<EventPayload, 'service' | 'app' | 'env'> & {\n service?: string;\n app?: string;\n env?: string;\n },\n): void {\n try {\n const body: EventPayload = {\n service: payload.service ?? config.service,\n app: payload.app ?? config.app,\n env: payload.env ?? config.env,\n level: payload.level,\n message: payload.message,\n stack: payload.stack,\n attrs: {\n ...payload.attrs,\n sdk: SDK_NAME,\n sdk_version: SDK_VERSION,\n session_id: getSessionId(),\n release: config.release,\n page_url: typeof location !== 'undefined' ? location.href : undefined,\n user_agent:\n typeof navigator !== 'undefined' ? navigator.userAgent : undefined,\n },\n synthetic: payload.synthetic,\n };\n\n const url = `${config.endpoint.replace(/\\/$/, '')}/ingest/log`;\n const json = JSON.stringify(body);\n\n const headers = {\n 'Content-Type': 'application/json',\n 'x-loghub-source': config.source,\n 'x-loghub-key': config.projectKey,\n } as Record<string, string>;\n\n if (\n typeof navigator !== 'undefined' &&\n typeof navigator.sendBeacon === 'function' &&\n // sendBeacon does not allow custom headers, so we use it only as\n // a last-resort fallback once we add a URL-token path. Until then,\n // prefer fetch+keepalive so auth headers are honored.\n false\n ) {\n const blob = new Blob([json], { type: 'application/json' });\n navigator.sendBeacon(url, blob);\n return;\n }\n\n if (typeof fetch === 'function') {\n void fetch(url, {\n method: 'POST',\n headers,\n body: json,\n keepalive: true,\n mode: 'cors',\n credentials: 'omit',\n }).catch(() => undefined);\n }\n } catch (err) {\n if (config.debug) {\n // eslint-disable-next-line no-console\n console.warn('[fixprompt] transport error', err);\n }\n }\n}\n","import { sendEvent } from './transport';\nimport type { ResolvedConfig } from './types';\n\nexport function installGlobalHandlers(config: ResolvedConfig): {\n removeErrorListener: () => void;\n removeRejectionListener: () => void;\n} {\n const onError = (ev: ErrorEvent) => {\n const err = ev.error;\n sendEvent(config, {\n level: 'error',\n message: ev.message ?? (err && err.message) ?? 'Unknown error',\n stack: err && typeof err.stack === 'string' ? err.stack : undefined,\n attrs: {\n kind: 'window.error',\n severity: 'error',\n filename: ev.filename,\n line: ev.lineno,\n column: ev.colno,\n error_name: err && err.name,\n },\n });\n };\n\n const onRejection = (ev: PromiseRejectionEvent) => {\n const reason = ev.reason;\n const isErr = reason instanceof Error;\n sendEvent(config, {\n level: 'error',\n message: isErr\n ? reason.message\n : typeof reason === 'string'\n ? reason\n : safeJson(reason),\n stack: isErr && typeof reason.stack === 'string' ? reason.stack : undefined,\n attrs: {\n kind: 'unhandledrejection',\n severity: 'error',\n error_name: isErr ? reason.name : typeof reason,\n },\n });\n };\n\n window.addEventListener('error', onError);\n window.addEventListener('unhandledrejection', onRejection);\n\n return {\n removeErrorListener: () => window.removeEventListener('error', onError),\n removeRejectionListener: () =>\n window.removeEventListener('unhandledrejection', onRejection),\n };\n}\n\nfunction safeJson(v: unknown): string {\n try {\n return JSON.stringify(v);\n } catch {\n return String(v);\n }\n}\n","import { sendEvent } from './transport';\nimport type { ResolvedConfig } from './types';\n\nexport function patchConsoleError(config: ResolvedConfig): () => void {\n const original = console.error;\n\n console.error = function patchedError(...args: any[]) {\n try {\n const stackFrom = args.find((a) => a instanceof Error) as\n | Error\n | undefined;\n sendEvent(config, {\n level: 'warn',\n message: args\n .map((a) =>\n a instanceof Error\n ? a.message\n : typeof a === 'string'\n ? a\n : safeJson(a),\n )\n .join(' '),\n stack: stackFrom && typeof stackFrom.stack === 'string' ? stackFrom.stack : undefined,\n attrs: {\n kind: 'console.error',\n severity: 'warning',\n },\n });\n } catch {\n // never block user code\n }\n return original.apply(console, args as any);\n };\n\n return () => {\n console.error = original;\n };\n}\n\nfunction safeJson(v: unknown): string {\n try {\n return JSON.stringify(v);\n } catch {\n return String(v);\n }\n}\n","import { sendEvent } from './transport';\nimport type { ResolvedConfig } from './types';\n\n/**\n * Wraps `window.fetch` so failed requests (4xx → warning, 5xx → critical)\n * forward to the broker. Network failures (thrown errors) also forward.\n *\n * URL query string is stripped before logging to reduce PII leak risk.\n */\nexport function wrapFetch(config: ResolvedConfig): () => void {\n if (typeof fetch !== 'function') return () => undefined;\n const original = fetch.bind(globalThis);\n const brokerHost = safeHost(config.endpoint);\n\n const patched: typeof fetch = async (...args) => {\n const t0 = nowMs();\n const [input, init] = args;\n const method =\n (init && (init as RequestInit).method) ||\n (input instanceof Request ? input.method : 'GET');\n const url = urlString(input);\n\n // Never trip on requests to our own broker — would infinite-loop on outage.\n if (url.startsWith(config.endpoint) || safeHost(url) === brokerHost) {\n return original(...args);\n }\n\n try {\n const response = await original(...args);\n const status = response.status;\n const latency = Math.round(nowMs() - t0);\n\n if (status >= 400) {\n sendEvent(config, {\n level: status >= 500 ? 'error' : 'warn',\n message: `fetch ${method} ${stripQuery(url)} → ${status}`,\n attrs: {\n kind: 'fetch',\n severity: status >= 500 ? 'critical' : 'warning',\n method,\n url: stripQuery(url),\n status,\n latency_ms: latency,\n },\n });\n }\n\n return response;\n } catch (err: any) {\n const latency = Math.round(nowMs() - t0);\n sendEvent(config, {\n level: 'error',\n message: `fetch ${method} ${stripQuery(url)} failed: ${err?.message ?? String(err)}`,\n stack: err?.stack,\n attrs: {\n kind: 'fetch',\n severity: 'critical',\n method,\n url: stripQuery(url),\n latency_ms: latency,\n error_name: err?.name,\n },\n });\n throw err;\n }\n };\n\n (globalThis as any).fetch = patched;\n\n return () => {\n (globalThis as any).fetch = original;\n };\n}\n\nfunction urlString(input: RequestInfo | URL): string {\n if (typeof input === 'string') return input;\n if (input instanceof URL) return input.toString();\n if (input instanceof Request) return input.url;\n return String(input);\n}\n\nfunction stripQuery(url: string): string {\n const q = url.indexOf('?');\n return q === -1 ? url : url.slice(0, q);\n}\n\nfunction safeHost(url: string): string {\n try {\n return new URL(url).host;\n } catch {\n return '';\n }\n}\n\nfunction nowMs(): number {\n if (typeof performance !== 'undefined' && typeof performance.now === 'function') {\n return performance.now();\n }\n return Date.now();\n}\n","/**\n * Release auto-detect cascade — see WEEK1_TICKETS.md W1-12.\n *\n * Priority:\n * 1. opts.release (handled in init.ts)\n * 2. import.meta.env.NEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA\n * 3. import.meta.env.VERCEL_GIT_COMMIT_SHA\n * 4. import.meta.env.NEXT_PUBLIC_COMMIT_SHA\n * 5. process.env.GITHUB_SHA\n * 6. process.env.RELEASE / globalThis.__FIXPROMPT_RELEASE__\n * 7. <meta name=\"fixprompt-release\" content=\"...\">\n * 8. null\n */\n\nfunction fromImportMeta(): string | null {\n try {\n // Vite/Next/etc. — import.meta.env may exist at build time\n const meta = (import.meta as any).env;\n if (!meta) return null;\n return (\n meta.NEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA ||\n meta.VERCEL_GIT_COMMIT_SHA ||\n meta.NEXT_PUBLIC_COMMIT_SHA ||\n null\n );\n } catch {\n return null;\n }\n}\n\nfunction fromProcessEnv(): string | null {\n try {\n if (typeof process === 'undefined' || !process || !process.env) return null;\n return process.env.GITHUB_SHA || process.env.RELEASE || null;\n } catch {\n return null;\n }\n}\n\nfunction fromGlobal(): string | null {\n try {\n const g = globalThis as any;\n return typeof g.__FIXPROMPT_RELEASE__ === 'string'\n ? g.__FIXPROMPT_RELEASE__\n : null;\n } catch {\n return null;\n }\n}\n\nfunction fromMetaTag(): string | null {\n try {\n if (typeof document === 'undefined') return null;\n const el = document.querySelector('meta[name=\"fixprompt-release\"]');\n const content = el?.getAttribute('content');\n return content && content.length > 0 ? content : null;\n } catch {\n return null;\n }\n}\n\nexport function detectRelease(explicit?: string): string | null {\n if (typeof explicit === 'string' && explicit.length > 0) return explicit;\n return (\n fromImportMeta() ||\n fromProcessEnv() ||\n fromGlobal() ||\n fromMetaTag() ||\n null\n );\n}\n","import type { ResolvedConfig } from './types';\n\nexport interface CleanupHooks {\n removeErrorListener?: () => void;\n removeRejectionListener?: () => void;\n restoreConsoleError?: () => void;\n restoreFetch?: () => void;\n}\n\ninterface SdkState {\n initialized: boolean;\n config: ResolvedConfig | null;\n sessionId: string | null;\n cleanup: CleanupHooks;\n}\n\nconst STATE_KEY = '__fixprompt_browser_state__';\n\nfunction globalScope(): any {\n if (typeof globalThis !== 'undefined') return globalThis;\n if (typeof window !== 'undefined') return window;\n return {};\n}\n\nexport function getState(): SdkState {\n const g = globalScope();\n if (!g[STATE_KEY]) {\n g[STATE_KEY] = {\n initialized: false,\n config: null,\n sessionId: null,\n cleanup: {},\n } satisfies SdkState;\n }\n return g[STATE_KEY] as SdkState;\n}\n\nexport function resetStateForTests(): void {\n const g = globalScope();\n delete g[STATE_KEY];\n}\n","import { installGlobalHandlers } from './handlers';\nimport { patchConsoleError } from './console';\nimport { wrapFetch as installFetchWrapper } from './fetch';\nimport { detectRelease } from './release';\nimport { getSessionId } from './session';\nimport { sendEvent } from './transport';\nimport { getState } from './state';\nimport type { InitOptions, ResolvedConfig } from './types';\n\nconst DEFAULT_ENDPOINT = 'https://geosloghub-production.up.railway.app';\n\nfunction resolveConfig(opts: InitOptions): ResolvedConfig {\n if (!opts || typeof opts.projectKey !== 'string' || opts.projectKey.length === 0) {\n throw new Error('initFixPrompt: projectKey is required');\n }\n return {\n projectKey: opts.projectKey,\n endpoint: (opts.endpoint ?? DEFAULT_ENDPOINT).replace(/\\/$/, ''),\n source: opts.source ?? 'browser',\n release: detectRelease(opts.release),\n service: opts.service ?? 'web',\n app: opts.app ?? 'browser',\n env: opts.env ?? 'prod',\n wrapFetch: opts.wrapFetch ?? false,\n patchConsoleError: opts.patchConsoleError ?? true,\n debug: opts.debug ?? false,\n };\n}\n\nexport function initFixPrompt(opts: InitOptions): void {\n const state = getState();\n if (state.initialized) {\n if (opts.debug) {\n // eslint-disable-next-line no-console\n console.warn('[fixprompt] already initialized — call ignored');\n }\n return;\n }\n\n if (typeof window === 'undefined') {\n // Not in a browser environment — degrade gracefully (e.g. SSR import).\n return;\n }\n\n const config = resolveConfig(opts);\n state.config = config;\n state.sessionId = getSessionId();\n\n const { removeErrorListener, removeRejectionListener } =\n installGlobalHandlers(config);\n state.cleanup.removeErrorListener = removeErrorListener;\n state.cleanup.removeRejectionListener = removeRejectionListener;\n\n if (config.patchConsoleError) {\n state.cleanup.restoreConsoleError = patchConsoleError(config);\n }\n if (config.wrapFetch) {\n state.cleanup.restoreFetch = installFetchWrapper(config);\n }\n\n state.initialized = true;\n\n if (config.debug) {\n // eslint-disable-next-line no-console\n console.log('[fixprompt] initialized', {\n endpoint: config.endpoint,\n release: config.release,\n session_id: state.sessionId,\n });\n }\n}\n\n/**\n * Manually report an error or message. Useful for synthetic events\n * (\"Send Test Exception\") or domain-specific catch blocks.\n */\nexport function captureException(\n err: unknown,\n options: { synthetic?: boolean; attrs?: Record<string, any> } = {},\n): void {\n const state = getState();\n if (!state.initialized || !state.config) return;\n\n const isErr = err instanceof Error;\n sendEvent(state.config, {\n level: 'error',\n message: isErr ? err.message : String(err),\n stack: isErr && typeof err.stack === 'string' ? err.stack : undefined,\n attrs: {\n kind: 'captureException',\n severity: 'error',\n error_name: isErr ? err.name : typeof err,\n ...(options.attrs ?? {}),\n },\n synthetic: options.synthetic === true,\n });\n}\n\n/**\n * Internal use only. Reverses every patch installed by initFixPrompt —\n * intended for tests and React HMR. Not part of the supported API.\n * @internal\n */\nexport function _resetForTests(): void {\n const state = getState();\n state.cleanup.removeErrorListener?.();\n state.cleanup.removeRejectionListener?.();\n state.cleanup.restoreConsoleError?.();\n state.cleanup.restoreFetch?.();\n state.initialized = false;\n state.config = null;\n state.sessionId = null;\n state.cleanup = {};\n}\n"],"mappings":"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","names":["safeJson"]}
|