5xx-sdk 1.0.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 ADDED
@@ -0,0 +1,139 @@
1
+ # @5xx/sdk
2
+
3
+ Lightweight error tracking SDK for JavaScript/TypeScript applications.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @5xx/sdk
9
+ ```
10
+
11
+ Or copy the SDK files directly into your project.
12
+
13
+ ## Quick Start
14
+
15
+ ### Browser
16
+
17
+ ```typescript
18
+ import { FiveXXBrowser } from '@5xx/sdk/browser';
19
+
20
+ const fivexx = new FiveXXBrowser({
21
+ apiKey: 'your-api-key',
22
+ endpoint: 'https://your-5xx-instance.com',
23
+ });
24
+
25
+ // Enable automatic capture of unhandled errors
26
+ fivexx.enableAutoCapture();
27
+
28
+ // Set user context (optional)
29
+ fivexx.setUser({
30
+ id: 'user-123',
31
+ email: 'user@example.com',
32
+ });
33
+
34
+ // Manual error capture
35
+ try {
36
+ riskyOperation();
37
+ } catch (error) {
38
+ fivexx.captureError(error, { context: 'checkout' });
39
+ }
40
+ ```
41
+
42
+ ### Node.js
43
+
44
+ ```typescript
45
+ import { FiveXXNode } from '@5xx/sdk/node';
46
+
47
+ const fivexx = new FiveXXNode({
48
+ apiKey: 'your-api-key',
49
+ endpoint: 'https://your-5xx-instance.com',
50
+ exitOnFatalError: true, // Exit process after capturing fatal errors
51
+ });
52
+
53
+ // Enable automatic capture of uncaught exceptions
54
+ fivexx.enableAutoCapture();
55
+
56
+ // Wrap async functions
57
+ const wrappedFn = fivexx.wrapAsync(async () => {
58
+ await someAsyncOperation();
59
+ });
60
+
61
+ // Manual capture
62
+ fivexx.captureError(new Error('Something went wrong'), {
63
+ userId: '123',
64
+ requestId: 'abc',
65
+ });
66
+ ```
67
+
68
+ ### Universal (works in both environments)
69
+
70
+ ```typescript
71
+ import { FiveXX } from '@5xx/sdk';
72
+
73
+ const fivexx = new FiveXX({
74
+ apiKey: 'your-api-key',
75
+ endpoint: 'https://your-5xx-instance.com',
76
+ environment: 'production',
77
+ });
78
+
79
+ // Manual capture only
80
+ fivexx.captureError(new Error('Something went wrong'));
81
+ fivexx.captureMessage('User performed invalid action');
82
+ ```
83
+
84
+ ## API
85
+
86
+ ### FiveXX (Base Client)
87
+
88
+ ```typescript
89
+ new FiveXX(options: FiveXXOptions)
90
+
91
+ interface FiveXXOptions {
92
+ apiKey: string; // Your project's API key
93
+ endpoint: string; // Your 5xx instance URL
94
+ environment?: string; // e.g., "production", "staging"
95
+ }
96
+ ```
97
+
98
+ **Methods:**
99
+ - `setEnvironment(env: string)` - Set the environment
100
+ - `setUser(user: User | null)` - Set user context for errors
101
+ - `captureError(error: Error, metadata?: object)` - Capture an error
102
+ - `captureMessage(message: string, metadata?: object)` - Capture a message
103
+
104
+ ### FiveXXBrowser
105
+
106
+ Extends FiveXX with browser-specific features.
107
+
108
+ **Additional Methods:**
109
+ - `enableAutoCapture()` - Auto-capture window.onerror and unhandledrejection
110
+ - `disableAutoCapture()` - Disable auto-capture
111
+
112
+ ### FiveXXNode
113
+
114
+ Extends FiveXX with Node.js-specific features.
115
+
116
+ **Constructor Options:**
117
+ - `exitOnFatalError?: boolean` - Exit process after fatal errors (default: true)
118
+
119
+ **Additional Methods:**
120
+ - `enableAutoCapture()` - Auto-capture uncaughtException and unhandledRejection
121
+ - `wrapAsync(fn, metadata?)` - Wrap async function to capture errors
122
+
123
+ ## Metadata
124
+
125
+ You can attach any metadata to errors:
126
+
127
+ ```typescript
128
+ fivexx.captureError(error, {
129
+ userId: 'user-123',
130
+ requestId: 'req-456',
131
+ action: 'checkout',
132
+ cart: { items: 3, total: 99.99 },
133
+ });
134
+ ```
135
+
136
+ The SDK automatically includes:
137
+ - User context (if set via `setUser()`)
138
+ - Browser: URL, user agent
139
+ - Node.js: Node version, platform, PID
@@ -0,0 +1,21 @@
1
+ import { F as FiveXX, a as FiveXXOptions } from './client-BhKj28Zi.mjs';
2
+
3
+ /**
4
+ * Browser-specific FiveXX client with automatic error capture
5
+ */
6
+ declare class FiveXXBrowser extends FiveXX {
7
+ private autoCapture;
8
+ private originalOnError;
9
+ private originalOnUnhandledRejection;
10
+ constructor(options: FiveXXOptions);
11
+ /**
12
+ * Enable automatic capture of unhandled errors and promise rejections
13
+ */
14
+ enableAutoCapture(): void;
15
+ /**
16
+ * Disable automatic capture
17
+ */
18
+ disableAutoCapture(): void;
19
+ }
20
+
21
+ export { FiveXXBrowser };
@@ -0,0 +1,21 @@
1
+ import { F as FiveXX, a as FiveXXOptions } from './client-BhKj28Zi.js';
2
+
3
+ /**
4
+ * Browser-specific FiveXX client with automatic error capture
5
+ */
6
+ declare class FiveXXBrowser extends FiveXX {
7
+ private autoCapture;
8
+ private originalOnError;
9
+ private originalOnUnhandledRejection;
10
+ constructor(options: FiveXXOptions);
11
+ /**
12
+ * Enable automatic capture of unhandled errors and promise rejections
13
+ */
14
+ enableAutoCapture(): void;
15
+ /**
16
+ * Disable automatic capture
17
+ */
18
+ disableAutoCapture(): void;
19
+ }
20
+
21
+ export { FiveXXBrowser };
@@ -0,0 +1,181 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/browser.ts
21
+ var browser_exports = {};
22
+ __export(browser_exports, {
23
+ FiveXXBrowser: () => FiveXXBrowser
24
+ });
25
+ module.exports = __toCommonJS(browser_exports);
26
+
27
+ // src/client.ts
28
+ var FiveXX = class {
29
+ constructor(options) {
30
+ this.user = null;
31
+ this.apiKey = options.apiKey;
32
+ this.endpoint = options.endpoint.replace(/\/$/, "");
33
+ this.environment = options.environment || "production";
34
+ }
35
+ /**
36
+ * Set the environment (e.g., "production", "development", "staging")
37
+ */
38
+ setEnvironment(env) {
39
+ this.environment = env;
40
+ }
41
+ /**
42
+ * Set user context for errors
43
+ */
44
+ setUser(user) {
45
+ this.user = user;
46
+ }
47
+ /**
48
+ * Capture an error and send it to the 5xx server
49
+ */
50
+ async captureError(error, metadata) {
51
+ const payload = {
52
+ message: error.message || String(error),
53
+ stack: error.stack,
54
+ environment: this.environment,
55
+ metadata: {
56
+ ...metadata,
57
+ ...this.user && { user: this.user }
58
+ }
59
+ };
60
+ return this.send(payload);
61
+ }
62
+ /**
63
+ * Capture a message as an error
64
+ */
65
+ async captureMessage(message, metadata) {
66
+ const payload = {
67
+ message,
68
+ environment: this.environment,
69
+ metadata: {
70
+ ...metadata,
71
+ ...this.user && { user: this.user }
72
+ }
73
+ };
74
+ return this.send(payload);
75
+ }
76
+ /**
77
+ * Send error payload to the server
78
+ */
79
+ async send(payload) {
80
+ try {
81
+ const response = await fetch(`${this.endpoint}/api/errors`, {
82
+ method: "POST",
83
+ headers: {
84
+ "Content-Type": "application/json",
85
+ "X-API-Key": this.apiKey
86
+ },
87
+ body: JSON.stringify(payload)
88
+ });
89
+ if (!response.ok) {
90
+ console.error(`5xx: Failed to send error (${response.status})`);
91
+ return null;
92
+ }
93
+ const data = await response.json();
94
+ return data.id;
95
+ } catch (err) {
96
+ console.error("5xx: Failed to send error", err);
97
+ return null;
98
+ }
99
+ }
100
+ };
101
+
102
+ // src/browser.ts
103
+ var FiveXXBrowser = class extends FiveXX {
104
+ constructor(options) {
105
+ super(options);
106
+ this.autoCapture = false;
107
+ this.originalOnError = null;
108
+ this.originalOnUnhandledRejection = null;
109
+ if (typeof window !== "undefined" && !options.environment) {
110
+ const hostname = window.location.hostname;
111
+ if (hostname === "localhost" || hostname === "127.0.0.1") {
112
+ this.setEnvironment("development");
113
+ }
114
+ }
115
+ }
116
+ /**
117
+ * Enable automatic capture of unhandled errors and promise rejections
118
+ */
119
+ enableAutoCapture() {
120
+ if (this.autoCapture || typeof window === "undefined") return;
121
+ this.autoCapture = true;
122
+ this.originalOnError = window.onerror;
123
+ window.onerror = (message, source, lineno, colno, error) => {
124
+ if (error) {
125
+ this.captureError(error, {
126
+ source,
127
+ lineno,
128
+ colno,
129
+ url: window.location.href,
130
+ userAgent: navigator.userAgent
131
+ });
132
+ } else {
133
+ this.captureMessage(String(message), {
134
+ source,
135
+ lineno,
136
+ colno,
137
+ url: window.location.href,
138
+ userAgent: navigator.userAgent
139
+ });
140
+ }
141
+ if (this.originalOnError) {
142
+ return this.originalOnError(message, source, lineno, colno, error);
143
+ }
144
+ return false;
145
+ };
146
+ this.originalOnUnhandledRejection = window.onunhandledrejection;
147
+ window.onunhandledrejection = (event) => {
148
+ const error = event.reason;
149
+ if (error instanceof Error) {
150
+ this.captureError(error, {
151
+ type: "unhandledRejection",
152
+ url: window.location.href,
153
+ userAgent: navigator.userAgent
154
+ });
155
+ } else {
156
+ this.captureMessage(String(error), {
157
+ type: "unhandledRejection",
158
+ url: window.location.href,
159
+ userAgent: navigator.userAgent
160
+ });
161
+ }
162
+ if (this.originalOnUnhandledRejection) {
163
+ this.originalOnUnhandledRejection(event);
164
+ }
165
+ };
166
+ }
167
+ /**
168
+ * Disable automatic capture
169
+ */
170
+ disableAutoCapture() {
171
+ if (!this.autoCapture || typeof window === "undefined") return;
172
+ this.autoCapture = false;
173
+ window.onerror = this.originalOnError;
174
+ window.onunhandledrejection = this.originalOnUnhandledRejection;
175
+ }
176
+ };
177
+ // Annotate the CommonJS export names for ESM import in node:
178
+ 0 && (module.exports = {
179
+ FiveXXBrowser
180
+ });
181
+ //# sourceMappingURL=browser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/browser.ts","../src/client.ts"],"sourcesContent":["import { FiveXX } from \"./client\";\nimport type { FiveXXOptions } from \"./types\";\n\n/**\n * Browser-specific FiveXX client with automatic error capture\n */\nexport class FiveXXBrowser extends FiveXX {\n private autoCapture = false;\n private originalOnError: OnErrorEventHandler | null = null;\n private originalOnUnhandledRejection: ((event: PromiseRejectionEvent) => void) | null = null;\n\n constructor(options: FiveXXOptions) {\n super(options);\n\n // Auto-detect environment from URL\n if (typeof window !== \"undefined\" && !options.environment) {\n const hostname = window.location.hostname;\n if (hostname === \"localhost\" || hostname === \"127.0.0.1\") {\n this.setEnvironment(\"development\");\n }\n }\n }\n\n /**\n * Enable automatic capture of unhandled errors and promise rejections\n */\n enableAutoCapture(): void {\n if (this.autoCapture || typeof window === \"undefined\") return;\n\n this.autoCapture = true;\n\n // Capture unhandled errors\n this.originalOnError = window.onerror;\n window.onerror = (message, source, lineno, colno, error) => {\n if (error) {\n this.captureError(error, {\n source,\n lineno,\n colno,\n url: window.location.href,\n userAgent: navigator.userAgent,\n });\n } else {\n this.captureMessage(String(message), {\n source,\n lineno,\n colno,\n url: window.location.href,\n userAgent: navigator.userAgent,\n });\n }\n\n // Call original handler if it exists\n if (this.originalOnError) {\n return this.originalOnError(message, source, lineno, colno, error);\n }\n return false;\n };\n\n // Capture unhandled promise rejections\n this.originalOnUnhandledRejection = window.onunhandledrejection;\n window.onunhandledrejection = (event) => {\n const error = event.reason;\n if (error instanceof Error) {\n this.captureError(error, {\n type: \"unhandledRejection\",\n url: window.location.href,\n userAgent: navigator.userAgent,\n });\n } else {\n this.captureMessage(String(error), {\n type: \"unhandledRejection\",\n url: window.location.href,\n userAgent: navigator.userAgent,\n });\n }\n\n if (this.originalOnUnhandledRejection) {\n this.originalOnUnhandledRejection(event);\n }\n };\n }\n\n /**\n * Disable automatic capture\n */\n disableAutoCapture(): void {\n if (!this.autoCapture || typeof window === \"undefined\") return;\n\n this.autoCapture = false;\n window.onerror = this.originalOnError;\n window.onunhandledrejection = this.originalOnUnhandledRejection;\n }\n}\n","import type { FiveXXOptions, ErrorPayload, User } from \"./types\";\n\nexport class FiveXX {\n private apiKey: string;\n private endpoint: string;\n private environment: string;\n private user: User | null = null;\n\n constructor(options: FiveXXOptions) {\n this.apiKey = options.apiKey;\n this.endpoint = options.endpoint.replace(/\\/$/, \"\"); // Remove trailing slash\n this.environment = options.environment || \"production\";\n }\n\n /**\n * Set the environment (e.g., \"production\", \"development\", \"staging\")\n */\n setEnvironment(env: string): void {\n this.environment = env;\n }\n\n /**\n * Set user context for errors\n */\n setUser(user: User | null): void {\n this.user = user;\n }\n\n /**\n * Capture an error and send it to the 5xx server\n */\n async captureError(\n error: Error,\n metadata?: Record<string, unknown>\n ): Promise<string | null> {\n const payload: ErrorPayload = {\n message: error.message || String(error),\n stack: error.stack,\n environment: this.environment,\n metadata: {\n ...metadata,\n ...(this.user && { user: this.user }),\n },\n };\n\n return this.send(payload);\n }\n\n /**\n * Capture a message as an error\n */\n async captureMessage(\n message: string,\n metadata?: Record<string, unknown>\n ): Promise<string | null> {\n const payload: ErrorPayload = {\n message,\n environment: this.environment,\n metadata: {\n ...metadata,\n ...(this.user && { user: this.user }),\n },\n };\n\n return this.send(payload);\n }\n\n /**\n * Send error payload to the server\n */\n private async send(payload: ErrorPayload): Promise<string | null> {\n try {\n const response = await fetch(`${this.endpoint}/api/errors`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"X-API-Key\": this.apiKey,\n },\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n console.error(`5xx: Failed to send error (${response.status})`);\n return null;\n }\n\n const data = await response.json();\n return data.id;\n } catch (err) {\n console.error(\"5xx: Failed to send error\", err);\n return null;\n }\n }\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,8 @@
1
+ import {
2
+ FiveXXBrowser
3
+ } from "./chunk-LD3XNYST.mjs";
4
+ import "./chunk-5YY5E33R.mjs";
5
+ export {
6
+ FiveXXBrowser
7
+ };
8
+ //# sourceMappingURL=browser.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,79 @@
1
+ // src/client.ts
2
+ var FiveXX = class {
3
+ constructor(options) {
4
+ this.user = null;
5
+ this.apiKey = options.apiKey;
6
+ this.endpoint = options.endpoint.replace(/\/$/, "");
7
+ this.environment = options.environment || "production";
8
+ }
9
+ /**
10
+ * Set the environment (e.g., "production", "development", "staging")
11
+ */
12
+ setEnvironment(env) {
13
+ this.environment = env;
14
+ }
15
+ /**
16
+ * Set user context for errors
17
+ */
18
+ setUser(user) {
19
+ this.user = user;
20
+ }
21
+ /**
22
+ * Capture an error and send it to the 5xx server
23
+ */
24
+ async captureError(error, metadata) {
25
+ const payload = {
26
+ message: error.message || String(error),
27
+ stack: error.stack,
28
+ environment: this.environment,
29
+ metadata: {
30
+ ...metadata,
31
+ ...this.user && { user: this.user }
32
+ }
33
+ };
34
+ return this.send(payload);
35
+ }
36
+ /**
37
+ * Capture a message as an error
38
+ */
39
+ async captureMessage(message, metadata) {
40
+ const payload = {
41
+ message,
42
+ environment: this.environment,
43
+ metadata: {
44
+ ...metadata,
45
+ ...this.user && { user: this.user }
46
+ }
47
+ };
48
+ return this.send(payload);
49
+ }
50
+ /**
51
+ * Send error payload to the server
52
+ */
53
+ async send(payload) {
54
+ try {
55
+ const response = await fetch(`${this.endpoint}/api/errors`, {
56
+ method: "POST",
57
+ headers: {
58
+ "Content-Type": "application/json",
59
+ "X-API-Key": this.apiKey
60
+ },
61
+ body: JSON.stringify(payload)
62
+ });
63
+ if (!response.ok) {
64
+ console.error(`5xx: Failed to send error (${response.status})`);
65
+ return null;
66
+ }
67
+ const data = await response.json();
68
+ return data.id;
69
+ } catch (err) {
70
+ console.error("5xx: Failed to send error", err);
71
+ return null;
72
+ }
73
+ }
74
+ };
75
+
76
+ export {
77
+ FiveXX
78
+ };
79
+ //# sourceMappingURL=chunk-5YY5E33R.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/client.ts"],"sourcesContent":["import type { FiveXXOptions, ErrorPayload, User } from \"./types\";\n\nexport class FiveXX {\n private apiKey: string;\n private endpoint: string;\n private environment: string;\n private user: User | null = null;\n\n constructor(options: FiveXXOptions) {\n this.apiKey = options.apiKey;\n this.endpoint = options.endpoint.replace(/\\/$/, \"\"); // Remove trailing slash\n this.environment = options.environment || \"production\";\n }\n\n /**\n * Set the environment (e.g., \"production\", \"development\", \"staging\")\n */\n setEnvironment(env: string): void {\n this.environment = env;\n }\n\n /**\n * Set user context for errors\n */\n setUser(user: User | null): void {\n this.user = user;\n }\n\n /**\n * Capture an error and send it to the 5xx server\n */\n async captureError(\n error: Error,\n metadata?: Record<string, unknown>\n ): Promise<string | null> {\n const payload: ErrorPayload = {\n message: error.message || String(error),\n stack: error.stack,\n environment: this.environment,\n metadata: {\n ...metadata,\n ...(this.user && { user: this.user }),\n },\n };\n\n return this.send(payload);\n }\n\n /**\n * Capture a message as an error\n */\n async captureMessage(\n message: string,\n metadata?: Record<string, unknown>\n ): Promise<string | null> {\n const payload: ErrorPayload = {\n message,\n environment: this.environment,\n metadata: {\n ...metadata,\n ...(this.user && { user: this.user }),\n },\n };\n\n return this.send(payload);\n }\n\n /**\n * Send error payload to the server\n */\n private async send(payload: ErrorPayload): Promise<string | null> {\n try {\n const response = await fetch(`${this.endpoint}/api/errors`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"X-API-Key\": this.apiKey,\n },\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n console.error(`5xx: Failed to send error (${response.status})`);\n return null;\n }\n\n const data = await response.json();\n return data.id;\n } catch (err) {\n console.error(\"5xx: Failed to send error\", err);\n return null;\n }\n }\n}\n"],"mappings":";AAEO,IAAM,SAAN,MAAa;AAAA,EAMlB,YAAY,SAAwB;AAFpC,SAAQ,OAAoB;AAG1B,SAAK,SAAS,QAAQ;AACtB,SAAK,WAAW,QAAQ,SAAS,QAAQ,OAAO,EAAE;AAClD,SAAK,cAAc,QAAQ,eAAe;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA,EAKA,eAAe,KAAmB;AAChC,SAAK,cAAc;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA,EAKA,QAAQ,MAAyB;AAC/B,SAAK,OAAO;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,aACJ,OACA,UACwB;AACxB,UAAM,UAAwB;AAAA,MAC5B,SAAS,MAAM,WAAW,OAAO,KAAK;AAAA,MACtC,OAAO,MAAM;AAAA,MACb,aAAa,KAAK;AAAA,MAClB,UAAU;AAAA,QACR,GAAG;AAAA,QACH,GAAI,KAAK,QAAQ,EAAE,MAAM,KAAK,KAAK;AAAA,MACrC;AAAA,IACF;AAEA,WAAO,KAAK,KAAK,OAAO;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,eACJ,SACA,UACwB;AACxB,UAAM,UAAwB;AAAA,MAC5B;AAAA,MACA,aAAa,KAAK;AAAA,MAClB,UAAU;AAAA,QACR,GAAG;AAAA,QACH,GAAI,KAAK,QAAQ,EAAE,MAAM,KAAK,KAAK;AAAA,MACrC;AAAA,IACF;AAEA,WAAO,KAAK,KAAK,OAAO;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,KAAK,SAA+C;AAChE,QAAI;AACF,YAAM,WAAW,MAAM,MAAM,GAAG,KAAK,QAAQ,eAAe;AAAA,QAC1D,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,UAChB,aAAa,KAAK;AAAA,QACpB;AAAA,QACA,MAAM,KAAK,UAAU,OAAO;AAAA,MAC9B,CAAC;AAED,UAAI,CAAC,SAAS,IAAI;AAChB,gBAAQ,MAAM,8BAA8B,SAAS,MAAM,GAAG;AAC9D,eAAO;AAAA,MACT;AAEA,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,aAAO,KAAK;AAAA,IACd,SAAS,KAAK;AACZ,cAAQ,MAAM,6BAA6B,GAAG;AAC9C,aAAO;AAAA,IACT;AAAA,EACF;AACF;","names":[]}
@@ -0,0 +1,84 @@
1
+ import {
2
+ FiveXX
3
+ } from "./chunk-5YY5E33R.mjs";
4
+
5
+ // src/browser.ts
6
+ var FiveXXBrowser = class extends FiveXX {
7
+ constructor(options) {
8
+ super(options);
9
+ this.autoCapture = false;
10
+ this.originalOnError = null;
11
+ this.originalOnUnhandledRejection = null;
12
+ if (typeof window !== "undefined" && !options.environment) {
13
+ const hostname = window.location.hostname;
14
+ if (hostname === "localhost" || hostname === "127.0.0.1") {
15
+ this.setEnvironment("development");
16
+ }
17
+ }
18
+ }
19
+ /**
20
+ * Enable automatic capture of unhandled errors and promise rejections
21
+ */
22
+ enableAutoCapture() {
23
+ if (this.autoCapture || typeof window === "undefined") return;
24
+ this.autoCapture = true;
25
+ this.originalOnError = window.onerror;
26
+ window.onerror = (message, source, lineno, colno, error) => {
27
+ if (error) {
28
+ this.captureError(error, {
29
+ source,
30
+ lineno,
31
+ colno,
32
+ url: window.location.href,
33
+ userAgent: navigator.userAgent
34
+ });
35
+ } else {
36
+ this.captureMessage(String(message), {
37
+ source,
38
+ lineno,
39
+ colno,
40
+ url: window.location.href,
41
+ userAgent: navigator.userAgent
42
+ });
43
+ }
44
+ if (this.originalOnError) {
45
+ return this.originalOnError(message, source, lineno, colno, error);
46
+ }
47
+ return false;
48
+ };
49
+ this.originalOnUnhandledRejection = window.onunhandledrejection;
50
+ window.onunhandledrejection = (event) => {
51
+ const error = event.reason;
52
+ if (error instanceof Error) {
53
+ this.captureError(error, {
54
+ type: "unhandledRejection",
55
+ url: window.location.href,
56
+ userAgent: navigator.userAgent
57
+ });
58
+ } else {
59
+ this.captureMessage(String(error), {
60
+ type: "unhandledRejection",
61
+ url: window.location.href,
62
+ userAgent: navigator.userAgent
63
+ });
64
+ }
65
+ if (this.originalOnUnhandledRejection) {
66
+ this.originalOnUnhandledRejection(event);
67
+ }
68
+ };
69
+ }
70
+ /**
71
+ * Disable automatic capture
72
+ */
73
+ disableAutoCapture() {
74
+ if (!this.autoCapture || typeof window === "undefined") return;
75
+ this.autoCapture = false;
76
+ window.onerror = this.originalOnError;
77
+ window.onunhandledrejection = this.originalOnUnhandledRejection;
78
+ }
79
+ };
80
+
81
+ export {
82
+ FiveXXBrowser
83
+ };
84
+ //# sourceMappingURL=chunk-LD3XNYST.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/browser.ts"],"sourcesContent":["import { FiveXX } from \"./client\";\nimport type { FiveXXOptions } from \"./types\";\n\n/**\n * Browser-specific FiveXX client with automatic error capture\n */\nexport class FiveXXBrowser extends FiveXX {\n private autoCapture = false;\n private originalOnError: OnErrorEventHandler | null = null;\n private originalOnUnhandledRejection: ((event: PromiseRejectionEvent) => void) | null = null;\n\n constructor(options: FiveXXOptions) {\n super(options);\n\n // Auto-detect environment from URL\n if (typeof window !== \"undefined\" && !options.environment) {\n const hostname = window.location.hostname;\n if (hostname === \"localhost\" || hostname === \"127.0.0.1\") {\n this.setEnvironment(\"development\");\n }\n }\n }\n\n /**\n * Enable automatic capture of unhandled errors and promise rejections\n */\n enableAutoCapture(): void {\n if (this.autoCapture || typeof window === \"undefined\") return;\n\n this.autoCapture = true;\n\n // Capture unhandled errors\n this.originalOnError = window.onerror;\n window.onerror = (message, source, lineno, colno, error) => {\n if (error) {\n this.captureError(error, {\n source,\n lineno,\n colno,\n url: window.location.href,\n userAgent: navigator.userAgent,\n });\n } else {\n this.captureMessage(String(message), {\n source,\n lineno,\n colno,\n url: window.location.href,\n userAgent: navigator.userAgent,\n });\n }\n\n // Call original handler if it exists\n if (this.originalOnError) {\n return this.originalOnError(message, source, lineno, colno, error);\n }\n return false;\n };\n\n // Capture unhandled promise rejections\n this.originalOnUnhandledRejection = window.onunhandledrejection;\n window.onunhandledrejection = (event) => {\n const error = event.reason;\n if (error instanceof Error) {\n this.captureError(error, {\n type: \"unhandledRejection\",\n url: window.location.href,\n userAgent: navigator.userAgent,\n });\n } else {\n this.captureMessage(String(error), {\n type: \"unhandledRejection\",\n url: window.location.href,\n userAgent: navigator.userAgent,\n });\n }\n\n if (this.originalOnUnhandledRejection) {\n this.originalOnUnhandledRejection(event);\n }\n };\n }\n\n /**\n * Disable automatic capture\n */\n disableAutoCapture(): void {\n if (!this.autoCapture || typeof window === \"undefined\") return;\n\n this.autoCapture = false;\n window.onerror = this.originalOnError;\n window.onunhandledrejection = this.originalOnUnhandledRejection;\n }\n}\n"],"mappings":";;;;;AAMO,IAAM,gBAAN,cAA4B,OAAO;AAAA,EAKxC,YAAY,SAAwB;AAClC,UAAM,OAAO;AALf,SAAQ,cAAc;AACtB,SAAQ,kBAA8C;AACtD,SAAQ,+BAAgF;AAMtF,QAAI,OAAO,WAAW,eAAe,CAAC,QAAQ,aAAa;AACzD,YAAM,WAAW,OAAO,SAAS;AACjC,UAAI,aAAa,eAAe,aAAa,aAAa;AACxD,aAAK,eAAe,aAAa;AAAA,MACnC;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,oBAA0B;AACxB,QAAI,KAAK,eAAe,OAAO,WAAW,YAAa;AAEvD,SAAK,cAAc;AAGnB,SAAK,kBAAkB,OAAO;AAC9B,WAAO,UAAU,CAAC,SAAS,QAAQ,QAAQ,OAAO,UAAU;AAC1D,UAAI,OAAO;AACT,aAAK,aAAa,OAAO;AAAA,UACvB;AAAA,UACA;AAAA,UACA;AAAA,UACA,KAAK,OAAO,SAAS;AAAA,UACrB,WAAW,UAAU;AAAA,QACvB,CAAC;AAAA,MACH,OAAO;AACL,aAAK,eAAe,OAAO,OAAO,GAAG;AAAA,UACnC;AAAA,UACA;AAAA,UACA;AAAA,UACA,KAAK,OAAO,SAAS;AAAA,UACrB,WAAW,UAAU;AAAA,QACvB,CAAC;AAAA,MACH;AAGA,UAAI,KAAK,iBAAiB;AACxB,eAAO,KAAK,gBAAgB,SAAS,QAAQ,QAAQ,OAAO,KAAK;AAAA,MACnE;AACA,aAAO;AAAA,IACT;AAGA,SAAK,+BAA+B,OAAO;AAC3C,WAAO,uBAAuB,CAAC,UAAU;AACvC,YAAM,QAAQ,MAAM;AACpB,UAAI,iBAAiB,OAAO;AAC1B,aAAK,aAAa,OAAO;AAAA,UACvB,MAAM;AAAA,UACN,KAAK,OAAO,SAAS;AAAA,UACrB,WAAW,UAAU;AAAA,QACvB,CAAC;AAAA,MACH,OAAO;AACL,aAAK,eAAe,OAAO,KAAK,GAAG;AAAA,UACjC,MAAM;AAAA,UACN,KAAK,OAAO,SAAS;AAAA,UACrB,WAAW,UAAU;AAAA,QACvB,CAAC;AAAA,MACH;AAEA,UAAI,KAAK,8BAA8B;AACrC,aAAK,6BAA6B,KAAK;AAAA,MACzC;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,qBAA2B;AACzB,QAAI,CAAC,KAAK,eAAe,OAAO,WAAW,YAAa;AAExD,SAAK,cAAc;AACnB,WAAO,UAAU,KAAK;AACtB,WAAO,uBAAuB,KAAK;AAAA,EACrC;AACF;","names":[]}
@@ -0,0 +1,72 @@
1
+ import {
2
+ FiveXX
3
+ } from "./chunk-5YY5E33R.mjs";
4
+
5
+ // src/node.ts
6
+ var FiveXXNode = class extends FiveXX {
7
+ constructor(options) {
8
+ super(options);
9
+ this.autoCapture = false;
10
+ this.exitOnFatalError = options.exitOnFatalError ?? true;
11
+ if (!options.environment && process.env.NODE_ENV) {
12
+ this.setEnvironment(process.env.NODE_ENV);
13
+ }
14
+ }
15
+ /**
16
+ * Enable automatic capture of uncaught exceptions and unhandled rejections
17
+ */
18
+ enableAutoCapture() {
19
+ if (this.autoCapture) return;
20
+ this.autoCapture = true;
21
+ process.on("uncaughtException", async (error) => {
22
+ console.error("5xx: Uncaught exception:", error);
23
+ await this.captureError(error, {
24
+ type: "uncaughtException",
25
+ nodeVersion: process.version,
26
+ platform: process.platform,
27
+ pid: process.pid
28
+ });
29
+ if (this.exitOnFatalError) {
30
+ process.exit(1);
31
+ }
32
+ });
33
+ process.on("unhandledRejection", async (reason) => {
34
+ console.error("5xx: Unhandled rejection:", reason);
35
+ if (reason instanceof Error) {
36
+ await this.captureError(reason, {
37
+ type: "unhandledRejection",
38
+ nodeVersion: process.version,
39
+ platform: process.platform,
40
+ pid: process.pid
41
+ });
42
+ } else {
43
+ await this.captureMessage(String(reason), {
44
+ type: "unhandledRejection",
45
+ nodeVersion: process.version,
46
+ platform: process.platform,
47
+ pid: process.pid
48
+ });
49
+ }
50
+ });
51
+ }
52
+ /**
53
+ * Wrap an async function to capture errors
54
+ */
55
+ wrapAsync(fn, metadata) {
56
+ return (async (...args) => {
57
+ try {
58
+ return await fn(...args);
59
+ } catch (error) {
60
+ if (error instanceof Error) {
61
+ await this.captureError(error, metadata);
62
+ }
63
+ throw error;
64
+ }
65
+ });
66
+ }
67
+ };
68
+
69
+ export {
70
+ FiveXXNode
71
+ };
72
+ //# sourceMappingURL=chunk-MOWJJPVU.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/node.ts"],"sourcesContent":["import { FiveXX } from \"./client\";\nimport type { FiveXXOptions } from \"./types\";\n\ninterface NodeOptions extends FiveXXOptions {\n exitOnFatalError?: boolean;\n}\n\n/**\n * Node.js-specific FiveXX client with automatic error capture\n */\nexport class FiveXXNode extends FiveXX {\n private autoCapture = false;\n private exitOnFatalError: boolean;\n\n constructor(options: NodeOptions) {\n super(options);\n this.exitOnFatalError = options.exitOnFatalError ?? true;\n\n // Auto-detect environment from NODE_ENV\n if (!options.environment && process.env.NODE_ENV) {\n this.setEnvironment(process.env.NODE_ENV);\n }\n }\n\n /**\n * Enable automatic capture of uncaught exceptions and unhandled rejections\n */\n enableAutoCapture(): void {\n if (this.autoCapture) return;\n\n this.autoCapture = true;\n\n // Capture uncaught exceptions\n process.on(\"uncaughtException\", async (error) => {\n console.error(\"5xx: Uncaught exception:\", error);\n await this.captureError(error, {\n type: \"uncaughtException\",\n nodeVersion: process.version,\n platform: process.platform,\n pid: process.pid,\n });\n\n if (this.exitOnFatalError) {\n process.exit(1);\n }\n });\n\n // Capture unhandled promise rejections\n process.on(\"unhandledRejection\", async (reason) => {\n console.error(\"5xx: Unhandled rejection:\", reason);\n if (reason instanceof Error) {\n await this.captureError(reason, {\n type: \"unhandledRejection\",\n nodeVersion: process.version,\n platform: process.platform,\n pid: process.pid,\n });\n } else {\n await this.captureMessage(String(reason), {\n type: \"unhandledRejection\",\n nodeVersion: process.version,\n platform: process.platform,\n pid: process.pid,\n });\n }\n });\n }\n\n /**\n * Wrap an async function to capture errors\n */\n wrapAsync<T extends (...args: unknown[]) => Promise<unknown>>(\n fn: T,\n metadata?: Record<string, unknown>\n ): T {\n return (async (...args: Parameters<T>) => {\n try {\n return await fn(...args);\n } catch (error) {\n if (error instanceof Error) {\n await this.captureError(error, metadata);\n }\n throw error;\n }\n }) as T;\n }\n}\n"],"mappings":";;;;;AAUO,IAAM,aAAN,cAAyB,OAAO;AAAA,EAIrC,YAAY,SAAsB;AAChC,UAAM,OAAO;AAJf,SAAQ,cAAc;AAKpB,SAAK,mBAAmB,QAAQ,oBAAoB;AAGpD,QAAI,CAAC,QAAQ,eAAe,QAAQ,IAAI,UAAU;AAChD,WAAK,eAAe,QAAQ,IAAI,QAAQ;AAAA,IAC1C;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,oBAA0B;AACxB,QAAI,KAAK,YAAa;AAEtB,SAAK,cAAc;AAGnB,YAAQ,GAAG,qBAAqB,OAAO,UAAU;AAC/C,cAAQ,MAAM,4BAA4B,KAAK;AAC/C,YAAM,KAAK,aAAa,OAAO;AAAA,QAC7B,MAAM;AAAA,QACN,aAAa,QAAQ;AAAA,QACrB,UAAU,QAAQ;AAAA,QAClB,KAAK,QAAQ;AAAA,MACf,CAAC;AAED,UAAI,KAAK,kBAAkB;AACzB,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF,CAAC;AAGD,YAAQ,GAAG,sBAAsB,OAAO,WAAW;AACjD,cAAQ,MAAM,6BAA6B,MAAM;AACjD,UAAI,kBAAkB,OAAO;AAC3B,cAAM,KAAK,aAAa,QAAQ;AAAA,UAC9B,MAAM;AAAA,UACN,aAAa,QAAQ;AAAA,UACrB,UAAU,QAAQ;AAAA,UAClB,KAAK,QAAQ;AAAA,QACf,CAAC;AAAA,MACH,OAAO;AACL,cAAM,KAAK,eAAe,OAAO,MAAM,GAAG;AAAA,UACxC,MAAM;AAAA,UACN,aAAa,QAAQ;AAAA,UACrB,UAAU,QAAQ;AAAA,UAClB,KAAK,QAAQ;AAAA,QACf,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,UACE,IACA,UACG;AACH,YAAQ,UAAU,SAAwB;AACxC,UAAI;AACF,eAAO,MAAM,GAAG,GAAG,IAAI;AAAA,MACzB,SAAS,OAAO;AACd,YAAI,iBAAiB,OAAO;AAC1B,gBAAM,KAAK,aAAa,OAAO,QAAQ;AAAA,QACzC;AACA,cAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACF;","names":[]}