@deflectbot/deflect-sdk 1.4.1 → 1.4.4-beta.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 CHANGED
@@ -31,48 +31,52 @@ Use `@deflect-sdk@latest` to always use the latest version, or specify a version
31
31
  <script src="https://cdn.jsdelivr.net/npm/@deflectbot/deflect-sdk@latest/dist/index.min.js"></script>
32
32
  ```
33
33
 
34
- ## Configuration
34
+ ## Usage (instance-based)
35
35
 
36
- Deflect works through Defense Actions™, which allows you to either setup a global configuration one-time to work across your entire application, or individual and more customized Defense Actions™ for each protected endpoint.
37
-
38
- #### One-time global initialization.
36
+ The SDK uses lightweight clients so you can create multiple independent configs (one per actionId) without global state conflicts.
39
37
 
40
38
  ```ts
41
- Deflect.configure({
39
+ import Deflect, { DeflectConfig } from "@deflectbot/deflect-sdk";
40
+
41
+ const client = Deflect.createClient({
42
42
  actionId: "<ACTION_ID>",
43
- });
43
+ // optional
44
+ scriptUrl: "https://custom-host/main.js", // overrides script origin
45
+ prefetch: true, // default
46
+ extraArgs: { debug: true }, // appended as query params => &debug=true
47
+ } satisfies DeflectConfig);
48
+
49
+ const token = await client.getToken();
44
50
  ```
45
51
 
46
- #### To get a token to pass to a protected endpoint
52
+ ### Multiple clients on the same page
47
53
 
48
54
  ```ts
49
- const token = await Deflect.getToken(); // returns token as string
50
- ```
55
+ const loginClient = Deflect.createClient({ actionId: "login" });
56
+ const signupClient = Deflect.createClient({ actionId: "signup" });
51
57
 
52
- #### Helper for form submit
58
+ const loginToken = await loginClient.getToken();
59
+ const signupToken = await signupClient.getToken();
60
+ ```
53
61
 
54
- If you're using forms like this:
62
+ ### Form helper with an instance
55
63
 
56
64
  ```html
57
- <form action="/login" method="POST">
65
+ <form action="/login" method="POST" onsubmit="return loginClient.injectToken(event)">
58
66
  <input name="username" />
59
67
  <input name="password" type="password" />
60
68
  <button type="submit">Login</button>
61
69
  </form>
70
+
71
+ <script type="module">
72
+ import Deflect from "https://cdn.jsdelivr.net/npm/@deflectbot/deflect-sdk@latest/dist/index.esm.js";
73
+ const loginClient = Deflect.createClient({ actionId: "login" });
74
+ window.loginClient = loginClient;
75
+ </script>
62
76
  ```
63
77
 
64
- You can use the helper as shown:
78
+ `injectToken(event)` fetches a token, injects it as a hidden `deflect_token` input, and submits the form.
65
79
 
66
- ```html
67
- <form
68
- action="/login"
69
- method="POST"
70
- onsubmit="return Deflect.injectToken(event)"
71
- >
72
- <input name="username" />
73
- <input name="password" type="password" />
74
- <button type="submit">Login</button>
75
- </form>
76
- ```
80
+ ### Legacy global (still available, but prefer clients)
77
81
 
78
- `injectToken()` will fetch a token and insert it as a hidden input named `deflect_token` into your form. Use it directly in your form's onsubmit attribute:
82
+ The previous `Deflect.configure`/`Deflect.getToken` singleton still works for single-action setups, but the recommended approach is to create per-action clients as shown above.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deflectbot/deflect-sdk",
3
- "version": "1.4.1",
3
+ "version": "1.4.4-beta.0",
4
4
  "description": "SDK for deflect.bot - Use it for seamless captcha integration on any website.",
5
5
  "main": "dist/index.min.js",
6
6
  "module": "dist/index.esm.js",
package/dist/index.d.ts DELETED
@@ -1,113 +0,0 @@
1
- interface DeflectConfig {
2
- actionId: string;
3
- scriptUrl?: string;
4
- }
5
- declare global {
6
- interface Window {
7
- Deflect: any;
8
- }
9
- }
10
- declare class Deflect {
11
- private config;
12
- private scriptCache;
13
- private isWarmupInProgress;
14
- private hasWarmupError;
15
- private pulseReporter;
16
- constructor();
17
- private initializeGlobalState;
18
- private setupAutomaticWarmup;
19
- private resolvePulseConfig;
20
- private reportError;
21
- private tryWarmup;
22
- /**
23
- * @param actionId - The action ID to validate
24
- * @returns The sanitized action ID
25
- * @throws Error if actionId contains invalid characters
26
- */
27
- private validateActionId;
28
- private buildScriptUrl;
29
- private fetchScript;
30
- private executeScript;
31
- private prefetchNextScript;
32
- private waitForGetToken;
33
- private createScriptBlob;
34
- private loadScriptElement;
35
- private getTokenFromScript;
36
- private cleanup;
37
- /**
38
- * Configures the Deflect SDK with the provided parameters.
39
- * Must be called before using getToken() or other SDK methods.
40
- *
41
- * @param params - Configuration options for the SDK
42
- * @param params.actionId - The unique action identifier from your Deflect dashboard (required)
43
- * @param params.scriptUrl - Optional custom script URL (defaults to Deflect CDN)
44
- * @throws Error if actionId is empty or contains invalid characters
45
- *
46
- * @example
47
- * ```typescript
48
- * Deflect.configure({ actionId: "your-action-id" });
49
- * ```
50
- */
51
- configure(params: DeflectConfig): void;
52
- private isTestMode;
53
- /**
54
- * @deprecated Use {@link getToken} instead. This method is kept for backward compatibility.
55
- * @returns A promise that resolves to the Deflect token string
56
- */
57
- solveChallenge(): Promise<string>;
58
- /**
59
- * Retrieves a Deflect token for the configured action.
60
- * The token should be included in requests to your protected endpoints.
61
- *
62
- * @returns A promise that resolves to the Deflect token string
63
- * @throws Error if configure() has not been called first
64
- * @throws Error if the script fails to load or execute
65
- *
66
- * @example
67
- * ```typescript
68
- * const token = await Deflect.getToken();
69
- * // Include token in your API request
70
- * fetch('/api/protected', {
71
- * headers: { 'X-Deflect-Token': token }
72
- * });
73
- * ```
74
- */
75
- getToken(): Promise<string>;
76
- /**
77
- * Pre-fetches the challenge script to reduce latency on the first getToken() call.
78
- * This is automatically called after configure(), but can be manually triggered.
79
- *
80
- * @returns A promise that resolves to true if warmup succeeded, false otherwise
81
- *
82
- * @example
83
- * ```typescript
84
- * Deflect.configure({ actionId: "your-action-id" });
85
- * const warmedUp = await Deflect.warmup();
86
- * console.log('Script pre-cached:', warmedUp);
87
- * ```
88
- */
89
- warmup(): Promise<boolean>;
90
- /**
91
- * Clears the cached challenge script.
92
- * Useful when you need to force a fresh script fetch on the next getToken() call.
93
- */
94
- clearCache(): void;
95
- /**
96
- * Injects a Deflect token as a hidden input into a form and submits it.
97
- * Designed for use with form onsubmit handlers.
98
- *
99
- * @param event - The form submit event
100
- * @throws Error if not called from a form submit event
101
- *
102
- * @example
103
- * ```html
104
- * <form action="/login" method="POST" onsubmit="Deflect.injectToken(event)">
105
- * <input name="username" />
106
- * <button type="submit">Login</button>
107
- * </form>
108
- * ```
109
- */
110
- injectToken(event: SubmitEvent): Promise<void>;
111
- }
112
- declare const _default: Deflect;
113
- export default _default;
package/dist/index.esm.js DELETED
@@ -1,388 +0,0 @@
1
- import PulseReporter from "./pulse";
2
- class Deflect {
3
- constructor() {
4
- this.config = null;
5
- this.scriptCache = null;
6
- this.isWarmupInProgress = false;
7
- this.hasWarmupError = false;
8
- this.initializeGlobalState();
9
- this.pulseReporter = new PulseReporter(this.resolvePulseConfig());
10
- this.setupAutomaticWarmup();
11
- }
12
- initializeGlobalState() {
13
- if (typeof window === "undefined") return;
14
- window.Deflect = window.Deflect || {};
15
- }
16
- setupAutomaticWarmup() {
17
- if (typeof window === "undefined") return;
18
- if (document.readyState === "loading") {
19
- document.addEventListener("DOMContentLoaded", () => this.tryWarmup());
20
- } else {
21
- setTimeout(() => this.tryWarmup(), 100);
22
- }
23
- }
24
- resolvePulseConfig() {
25
- const runtimeConfig = typeof window !== "undefined" && typeof window.Deflect === "object" && window.Deflect?.pulseConfig && typeof window.Deflect.pulseConfig === "object" ? window.Deflect.pulseConfig : {};
26
- return {
27
- ...runtimeConfig,
28
- environment: runtimeConfig.environment || (typeof window !== "undefined" ? window.location.hostname : void 0)
29
- };
30
- }
31
- reportError(error, tags, context) {
32
- this.pulseReporter.captureException(error, { tags, context });
33
- }
34
- async tryWarmup() {
35
- if (!this.config?.actionId || this.isWarmupInProgress || this.scriptCache || this.hasWarmupError) {
36
- return;
37
- }
38
- this.isWarmupInProgress = true;
39
- try {
40
- this.scriptCache = await this.fetchScript();
41
- this.hasWarmupError = false;
42
- } catch {
43
- this.hasWarmupError = true;
44
- } finally {
45
- this.isWarmupInProgress = false;
46
- }
47
- }
48
- /**
49
- * @param actionId - The action ID to validate
50
- * @returns The sanitized action ID
51
- * @throws Error if actionId contains invalid characters
52
- */
53
- validateActionId(actionId) {
54
- const sanitized = actionId.trim();
55
- const validPattern = /^[a-zA-Z0-9/_-]+$/;
56
- if (!validPattern.test(sanitized)) {
57
- throw new Error("Invalid actionId format: contains disallowed characters");
58
- }
59
- return encodeURIComponent(sanitized);
60
- }
61
- buildScriptUrl(actionId) {
62
- const baseUrl = this.config?.scriptUrl || "https://js.deflect.bot/main.js";
63
- const sanitizedActionId = this.validateActionId(actionId);
64
- const nonce = Date.now().toString();
65
- return `${baseUrl}?action_id=${sanitizedActionId}&_=${nonce}`;
66
- }
67
- async fetchScript() {
68
- if (!this.config?.actionId) {
69
- throw new Error("actionId is required");
70
- }
71
- const url = this.buildScriptUrl(this.config.actionId);
72
- try {
73
- const response = await fetch(url, {
74
- cache: "no-store",
75
- mode: "cors",
76
- credentials: "omit"
77
- });
78
- if (!response.ok) {
79
- throw new Error(`Failed to fetch script: ${response.status}`);
80
- }
81
- const content = await response.text();
82
- try {
83
- const maybeError = JSON.parse(content);
84
- if (maybeError.success === false || maybeError.error) {
85
- const errorMessage = maybeError.error || "Script fetch failed";
86
- const error = new Error(errorMessage);
87
- if (errorMessage === "action_does_not_exist" || errorMessage.includes("invalid action")) {
88
- error.isUserError = true;
89
- }
90
- throw error;
91
- }
92
- } catch (e) {
93
- if (!(e instanceof SyntaxError)) {
94
- throw e;
95
- }
96
- }
97
- return {
98
- content,
99
- sessionId: response.headers.get("session_id") || void 0
100
- };
101
- } catch (error) {
102
- this.reportError(
103
- error,
104
- {
105
- deflect_sdk_error: "true",
106
- method: "fetchScript",
107
- action_id: this.config.actionId
108
- },
109
- {
110
- actionId: this.config.actionId,
111
- url
112
- }
113
- );
114
- throw error;
115
- }
116
- }
117
- async executeScript(script) {
118
- if (script.sessionId && typeof window !== "undefined") {
119
- window.Deflect.sessionId = script.sessionId;
120
- }
121
- const blobUrl = this.createScriptBlob(script.content);
122
- let scriptElement = null;
123
- try {
124
- scriptElement = await this.loadScriptElement(blobUrl);
125
- await this.waitForGetToken();
126
- const token = await this.getTokenFromScript();
127
- this.prefetchNextScript();
128
- return token;
129
- } catch (error) {
130
- this.reportError(
131
- error,
132
- {
133
- deflect_sdk_error: "true",
134
- method: "executeScript",
135
- stage: "load_or_execute",
136
- action_id: this.config?.actionId || "unknown"
137
- },
138
- {
139
- hasCache: this.scriptCache !== null,
140
- hasWarmupError: this.hasWarmupError
141
- }
142
- );
143
- throw error;
144
- } finally {
145
- if (scriptElement) {
146
- this.cleanup(blobUrl, scriptElement);
147
- } else {
148
- URL.revokeObjectURL(blobUrl);
149
- }
150
- }
151
- }
152
- prefetchNextScript() {
153
- if (!this.hasWarmupError) {
154
- this.tryWarmup().catch(() => {
155
- });
156
- }
157
- }
158
- async waitForGetToken() {
159
- return new Promise((resolve, reject) => {
160
- const checkInterval = setInterval(() => {
161
- if (typeof window !== "undefined" && typeof window.Deflect?.getToken === "function") {
162
- clearInterval(checkInterval);
163
- resolve();
164
- }
165
- }, 50);
166
- setTimeout(() => {
167
- clearInterval(checkInterval);
168
- reject(new Error("Timeout: getToken function did not become available within 10 seconds"));
169
- }, 1e4);
170
- });
171
- }
172
- createScriptBlob(content) {
173
- const blob = new Blob([content], { type: "text/javascript" });
174
- return URL.createObjectURL(blob);
175
- }
176
- async loadScriptElement(blobUrl) {
177
- return new Promise((resolve, reject) => {
178
- const script = document.createElement("script");
179
- script.type = "module";
180
- script.src = blobUrl;
181
- script.onload = () => resolve(script);
182
- script.onerror = () => reject(new Error("Script failed to load"));
183
- document.head.appendChild(script);
184
- });
185
- }
186
- async getTokenFromScript() {
187
- if (typeof window === "undefined" || typeof window.Deflect?.getToken !== "function") {
188
- throw new Error("Script did not load properly - getToken not available");
189
- }
190
- try {
191
- return await window.Deflect.getToken();
192
- } catch (error) {
193
- throw new Error(`Script execution failed: ${error}`);
194
- }
195
- }
196
- cleanup(blobUrl, scriptElement) {
197
- URL.revokeObjectURL(blobUrl);
198
- scriptElement.remove();
199
- if (typeof window !== "undefined" && window.Deflect?.getToken) {
200
- delete window.Deflect.getToken;
201
- }
202
- }
203
- /**
204
- * Configures the Deflect SDK with the provided parameters.
205
- * Must be called before using getToken() or other SDK methods.
206
- *
207
- * @param params - Configuration options for the SDK
208
- * @param params.actionId - The unique action identifier from your Deflect dashboard (required)
209
- * @param params.scriptUrl - Optional custom script URL (defaults to Deflect CDN)
210
- * @throws Error if actionId is empty or contains invalid characters
211
- *
212
- * @example
213
- * ```typescript
214
- * Deflect.configure({ actionId: "your-action-id" });
215
- * ```
216
- */
217
- configure(params) {
218
- try {
219
- if (!params.actionId?.trim()) {
220
- throw new Error("actionId is required and cannot be empty");
221
- }
222
- if (this.config?.actionId === params.actionId) {
223
- return;
224
- }
225
- this.hasWarmupError = false;
226
- this.scriptCache = null;
227
- this.config = { ...params };
228
- if (typeof window !== "undefined") {
229
- window.Deflect.actionId = params.actionId;
230
- }
231
- if (!this.isTestMode()) {
232
- this.tryWarmup();
233
- }
234
- } catch (error) {
235
- const isUserError = error && typeof error === "object" && "isUserError" in error && error.isUserError === true;
236
- this.reportError(
237
- error,
238
- {
239
- deflect_sdk_error: "true",
240
- deflect_user_error: isUserError ? "true" : "false",
241
- method: "configure",
242
- action_id: params?.actionId || "unknown"
243
- },
244
- {
245
- actionId: params?.actionId,
246
- hasCache: this.scriptCache !== null,
247
- hasWarmupError: this.hasWarmupError
248
- }
249
- );
250
- throw error;
251
- }
252
- }
253
- isTestMode() {
254
- if (this.config?.actionId === "PULSE_TEST" || this.config?.actionId === "SENTRY_TEST") {
255
- throw new Error("PULSE_TEST: This is a test error to verify Pulse integration is working");
256
- }
257
- return this.config?.actionId === "t/FFFFFFFFFFFFF/111111111" || this.config?.actionId === "t/FFFFFFFFFFFFF/000000000";
258
- }
259
- /**
260
- * @deprecated Use {@link getToken} instead. This method is kept for backward compatibility.
261
- * @returns A promise that resolves to the Deflect token string
262
- */
263
- async solveChallenge() {
264
- return this.getToken();
265
- }
266
- /**
267
- * Retrieves a Deflect token for the configured action.
268
- * The token should be included in requests to your protected endpoints.
269
- *
270
- * @returns A promise that resolves to the Deflect token string
271
- * @throws Error if configure() has not been called first
272
- * @throws Error if the script fails to load or execute
273
- *
274
- * @example
275
- * ```typescript
276
- * const token = await Deflect.getToken();
277
- * // Include token in your API request
278
- * fetch('/api/protected', {
279
- * headers: { 'X-Deflect-Token': token }
280
- * });
281
- * ```
282
- */
283
- async getToken() {
284
- try {
285
- if (!this.config?.actionId) {
286
- throw new Error("Must call configure() before solveChallenge()");
287
- }
288
- if (this.isTestMode()) {
289
- return "TESTTOKEN";
290
- }
291
- let script;
292
- if (this.scriptCache && !this.isWarmupInProgress) {
293
- script = this.scriptCache;
294
- this.scriptCache = null;
295
- } else {
296
- script = await this.fetchScript();
297
- }
298
- return this.executeScript(script);
299
- } catch (error) {
300
- const isUserError = error && typeof error === "object" && "isUserError" in error && error.isUserError === true;
301
- this.reportError(
302
- error,
303
- {
304
- deflect_sdk_error: "true",
305
- deflect_user_error: isUserError ? "true" : "false",
306
- method: "getToken",
307
- action_id: this.config?.actionId || "unknown",
308
- has_cache: this.scriptCache !== null ? "true" : "false",
309
- has_warmup_error: this.hasWarmupError ? "true" : "false",
310
- stage: "call"
311
- },
312
- {
313
- actionId: this.config?.actionId,
314
- hasCache: this.scriptCache !== null,
315
- hasWarmupError: this.hasWarmupError
316
- }
317
- );
318
- throw error;
319
- }
320
- }
321
- /**
322
- * Pre-fetches the challenge script to reduce latency on the first getToken() call.
323
- * This is automatically called after configure(), but can be manually triggered.
324
- *
325
- * @returns A promise that resolves to true if warmup succeeded, false otherwise
326
- *
327
- * @example
328
- * ```typescript
329
- * Deflect.configure({ actionId: "your-action-id" });
330
- * const warmedUp = await Deflect.warmup();
331
- * console.log('Script pre-cached:', warmedUp);
332
- * ```
333
- */
334
- async warmup() {
335
- if (!this.config?.actionId) {
336
- return false;
337
- }
338
- try {
339
- await this.tryWarmup();
340
- return this.scriptCache !== null;
341
- } catch {
342
- return false;
343
- }
344
- }
345
- /**
346
- * Clears the cached challenge script.
347
- * Useful when you need to force a fresh script fetch on the next getToken() call.
348
- */
349
- clearCache() {
350
- this.scriptCache = null;
351
- }
352
- /**
353
- * Injects a Deflect token as a hidden input into a form and submits it.
354
- * Designed for use with form onsubmit handlers.
355
- *
356
- * @param event - The form submit event
357
- * @throws Error if not called from a form submit event
358
- *
359
- * @example
360
- * ```html
361
- * <form action="/login" method="POST" onsubmit="Deflect.injectToken(event)">
362
- * <input name="username" />
363
- * <button type="submit">Login</button>
364
- * </form>
365
- * ```
366
- */
367
- async injectToken(event) {
368
- if (!event || !event.target || !(event.target instanceof HTMLFormElement)) {
369
- throw new Error("injectToken: must be called from a form submit event");
370
- }
371
- event.preventDefault();
372
- const form = event.target;
373
- const token = await this.getToken();
374
- Array.from(form.querySelectorAll('input[name="deflect_token"]')).forEach(
375
- (el) => el.remove()
376
- );
377
- const hidden = document.createElement("input");
378
- hidden.type = "hidden";
379
- hidden.name = "deflect_token";
380
- hidden.value = token;
381
- form.appendChild(hidden);
382
- form.submit();
383
- }
384
- }
385
- var src_default = new Deflect();
386
- export {
387
- src_default as default
388
- };
package/dist/index.js DELETED
@@ -1,533 +0,0 @@
1
- "use strict";
2
- (() => {
3
- var __defProp = Object.defineProperty;
4
- var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
5
-
6
- // src/pulse.ts
7
- var REPORT_CONFIG = {
8
- endpoint: "https://service.yabadabado.top/pulse",
9
- projectId: "deflect-sdk",
10
- deploymentId: "688529b539803661332b3f70",
11
- service: "deflect-sdk",
12
- release: "unknown"
13
- };
14
- var PULSE_SDK_INFO = {
15
- name: "deflect-js-sdk",
16
- version: REPORT_CONFIG.release || "unknown",
17
- language: "javascript"
18
- };
19
- var PulseReporter = class {
20
- static {
21
- __name(this, "PulseReporter");
22
- }
23
- constructor(config) {
24
- this.config = {
25
- ...REPORT_CONFIG,
26
- ...config,
27
- endpoint: (config?.endpoint || REPORT_CONFIG.endpoint).replace(/\/$/, "")
28
- };
29
- this.enabled = Boolean(
30
- this.config.endpoint && this.config.projectId && this.config.deploymentId
31
- );
32
- }
33
- captureException(error, options = {}) {
34
- if (!this.enabled || typeof fetch !== "function") {
35
- return;
36
- }
37
- const event = this.buildErrorEvent(error, options);
38
- fetch(`${this.config.endpoint}/capture`, {
39
- method: "POST",
40
- headers: {
41
- "Content-Type": "application/json",
42
- project_id: this.config.projectId
43
- },
44
- body: JSON.stringify(event),
45
- keepalive: true
46
- }).catch(() => {
47
- });
48
- }
49
- buildErrorEvent(error, options) {
50
- const normalizedError = this.normalizeError(error);
51
- const environment = this.config.environment || (typeof window !== "undefined" ? window.location.hostname || "unknown" : "unknown");
52
- const runtimeInfo = typeof navigator === "undefined" ? void 0 : {
53
- name: navigator.userAgent || "browser",
54
- version: navigator.appVersion
55
- };
56
- const osInfo = typeof navigator === "undefined" ? void 0 : {
57
- name: navigator.platform
58
- };
59
- const deviceInfo = typeof window === "undefined" ? void 0 : {
60
- model: `${window.screen.width}x${window.screen.height}`,
61
- arch: typeof navigator !== "undefined" ? navigator.platform : void 0
62
- };
63
- const requestInfo = typeof window === "undefined" ? void 0 : {
64
- method: "GET",
65
- url: window.location.href,
66
- headers: typeof navigator !== "undefined" ? {
67
- "User-Agent": navigator.userAgent,
68
- ...typeof document !== "undefined" && document.referrer ? { Referer: document.referrer } : {}
69
- } : void 0
70
- };
71
- const eventId = typeof crypto !== "undefined" && typeof crypto.randomUUID === "function" ? crypto.randomUUID() : Math.random().toString(16).slice(2) + Date.now().toString(16);
72
- return {
73
- event_type: "error",
74
- event_id: eventId,
75
- deployment_id: this.config.deploymentId,
76
- project_id: this.config.projectId,
77
- environment,
78
- service: this.config.service,
79
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
80
- release: this.config.release,
81
- sdk: {
82
- ...PULSE_SDK_INFO,
83
- version: this.config.release || PULSE_SDK_INFO.version
84
- },
85
- tags: options.tags,
86
- context: options.context,
87
- error: {
88
- level: options.level || "error",
89
- message: normalizedError.message,
90
- exception: this.buildExceptionPayload(normalizedError),
91
- request: requestInfo,
92
- runtime: runtimeInfo,
93
- os: osInfo,
94
- device: deviceInfo
95
- }
96
- };
97
- }
98
- normalizeError(error) {
99
- if (error instanceof Error) {
100
- return error;
101
- }
102
- const message = typeof error === "string" ? error : "Unknown error";
103
- return new Error(message);
104
- }
105
- buildExceptionPayload(error) {
106
- const frames = this.parseStack(error);
107
- return {
108
- type: error.name || "Error",
109
- value: error.message,
110
- stacktrace: frames.length ? { frames } : void 0
111
- };
112
- }
113
- parseStack(error) {
114
- if (!error.stack) {
115
- return [];
116
- }
117
- const frames = [];
118
- const raw = error.stack.split("\n").slice(1);
119
- for (const line of raw) {
120
- const cleaned = line.trim().replace(/^at\s+/, "");
121
- const hasLocation = cleaned.includes("(") && cleaned.endsWith(")");
122
- const functionName = hasLocation ? cleaned.slice(0, cleaned.indexOf("(")).trim() : "";
123
- const location = hasLocation ? cleaned.slice(cleaned.indexOf("(") + 1, cleaned.length - 1) : cleaned;
124
- const parts = location.split(":");
125
- const filename = parts[0] || void 0;
126
- const lineno = parts.length > 1 ? Number(parts[1]) : void 0;
127
- const colno = parts.length > 2 ? Number(parts[2]) : void 0;
128
- if (!filename) {
129
- continue;
130
- }
131
- frames.push({
132
- filename,
133
- abs_path: filename,
134
- function: functionName || void 0,
135
- lineno: Number.isFinite(lineno) ? lineno : void 0,
136
- colno: Number.isFinite(colno) ? colno : void 0,
137
- in_app: !filename.includes("node_modules")
138
- });
139
- }
140
- return frames;
141
- }
142
- };
143
- var pulse_default = PulseReporter;
144
-
145
- // src/index.ts
146
- var Deflect = class {
147
- constructor() {
148
- this.config = null;
149
- this.scriptCache = null;
150
- this.isWarmupInProgress = false;
151
- this.hasWarmupError = false;
152
- this.initializeGlobalState();
153
- this.pulseReporter = new pulse_default(this.resolvePulseConfig());
154
- this.setupAutomaticWarmup();
155
- }
156
- static {
157
- __name(this, "Deflect");
158
- }
159
- initializeGlobalState() {
160
- if (typeof window === "undefined") return;
161
- window.Deflect = window.Deflect || {};
162
- }
163
- setupAutomaticWarmup() {
164
- if (typeof window === "undefined") return;
165
- if (document.readyState === "loading") {
166
- document.addEventListener("DOMContentLoaded", () => this.tryWarmup());
167
- } else {
168
- setTimeout(() => this.tryWarmup(), 100);
169
- }
170
- }
171
- resolvePulseConfig() {
172
- const runtimeConfig = typeof window !== "undefined" && typeof window.Deflect === "object" && window.Deflect?.pulseConfig && typeof window.Deflect.pulseConfig === "object" ? window.Deflect.pulseConfig : {};
173
- return {
174
- ...runtimeConfig,
175
- environment: runtimeConfig.environment || (typeof window !== "undefined" ? window.location.hostname : void 0)
176
- };
177
- }
178
- reportError(error, tags, context) {
179
- this.pulseReporter.captureException(error, { tags, context });
180
- }
181
- async tryWarmup() {
182
- if (!this.config?.actionId || this.isWarmupInProgress || this.scriptCache || this.hasWarmupError) {
183
- return;
184
- }
185
- this.isWarmupInProgress = true;
186
- try {
187
- this.scriptCache = await this.fetchScript();
188
- this.hasWarmupError = false;
189
- } catch {
190
- this.hasWarmupError = true;
191
- } finally {
192
- this.isWarmupInProgress = false;
193
- }
194
- }
195
- /**
196
- * @param actionId - The action ID to validate
197
- * @returns The sanitized action ID
198
- * @throws Error if actionId contains invalid characters
199
- */
200
- validateActionId(actionId) {
201
- const sanitized = actionId.trim();
202
- const validPattern = /^[a-zA-Z0-9/_-]+$/;
203
- if (!validPattern.test(sanitized)) {
204
- throw new Error("Invalid actionId format: contains disallowed characters");
205
- }
206
- return encodeURIComponent(sanitized);
207
- }
208
- buildScriptUrl(actionId) {
209
- const baseUrl = this.config?.scriptUrl || "https://js.deflect.bot/main.js";
210
- const sanitizedActionId = this.validateActionId(actionId);
211
- const nonce = Date.now().toString();
212
- return `${baseUrl}?action_id=${sanitizedActionId}&_=${nonce}`;
213
- }
214
- async fetchScript() {
215
- if (!this.config?.actionId) {
216
- throw new Error("actionId is required");
217
- }
218
- const url = this.buildScriptUrl(this.config.actionId);
219
- try {
220
- const response = await fetch(url, {
221
- cache: "no-store",
222
- mode: "cors",
223
- credentials: "omit"
224
- });
225
- if (!response.ok) {
226
- throw new Error(`Failed to fetch script: ${response.status}`);
227
- }
228
- const content = await response.text();
229
- try {
230
- const maybeError = JSON.parse(content);
231
- if (maybeError.success === false || maybeError.error) {
232
- const errorMessage = maybeError.error || "Script fetch failed";
233
- const error = new Error(errorMessage);
234
- if (errorMessage === "action_does_not_exist" || errorMessage.includes("invalid action")) {
235
- error.isUserError = true;
236
- }
237
- throw error;
238
- }
239
- } catch (e) {
240
- if (!(e instanceof SyntaxError)) {
241
- throw e;
242
- }
243
- }
244
- return {
245
- content,
246
- sessionId: response.headers.get("session_id") || void 0
247
- };
248
- } catch (error) {
249
- this.reportError(
250
- error,
251
- {
252
- deflect_sdk_error: "true",
253
- method: "fetchScript",
254
- action_id: this.config.actionId
255
- },
256
- {
257
- actionId: this.config.actionId,
258
- url
259
- }
260
- );
261
- throw error;
262
- }
263
- }
264
- async executeScript(script) {
265
- if (script.sessionId && typeof window !== "undefined") {
266
- window.Deflect.sessionId = script.sessionId;
267
- }
268
- const blobUrl = this.createScriptBlob(script.content);
269
- let scriptElement = null;
270
- try {
271
- scriptElement = await this.loadScriptElement(blobUrl);
272
- await this.waitForGetToken();
273
- const token = await this.getTokenFromScript();
274
- this.prefetchNextScript();
275
- return token;
276
- } catch (error) {
277
- this.reportError(
278
- error,
279
- {
280
- deflect_sdk_error: "true",
281
- method: "executeScript",
282
- stage: "load_or_execute",
283
- action_id: this.config?.actionId || "unknown"
284
- },
285
- {
286
- hasCache: this.scriptCache !== null,
287
- hasWarmupError: this.hasWarmupError
288
- }
289
- );
290
- throw error;
291
- } finally {
292
- if (scriptElement) {
293
- this.cleanup(blobUrl, scriptElement);
294
- } else {
295
- URL.revokeObjectURL(blobUrl);
296
- }
297
- }
298
- }
299
- prefetchNextScript() {
300
- if (!this.hasWarmupError) {
301
- this.tryWarmup().catch(() => {
302
- });
303
- }
304
- }
305
- async waitForGetToken() {
306
- return new Promise((resolve, reject) => {
307
- const checkInterval = setInterval(() => {
308
- if (typeof window !== "undefined" && typeof window.Deflect?.getToken === "function") {
309
- clearInterval(checkInterval);
310
- resolve();
311
- }
312
- }, 50);
313
- setTimeout(() => {
314
- clearInterval(checkInterval);
315
- reject(new Error("Timeout: getToken function did not become available within 10 seconds"));
316
- }, 1e4);
317
- });
318
- }
319
- createScriptBlob(content) {
320
- const blob = new Blob([content], { type: "text/javascript" });
321
- return URL.createObjectURL(blob);
322
- }
323
- async loadScriptElement(blobUrl) {
324
- return new Promise((resolve, reject) => {
325
- const script = document.createElement("script");
326
- script.type = "module";
327
- script.src = blobUrl;
328
- script.onload = () => resolve(script);
329
- script.onerror = () => reject(new Error("Script failed to load"));
330
- document.head.appendChild(script);
331
- });
332
- }
333
- async getTokenFromScript() {
334
- if (typeof window === "undefined" || typeof window.Deflect?.getToken !== "function") {
335
- throw new Error("Script did not load properly - getToken not available");
336
- }
337
- try {
338
- return await window.Deflect.getToken();
339
- } catch (error) {
340
- throw new Error(`Script execution failed: ${error}`);
341
- }
342
- }
343
- cleanup(blobUrl, scriptElement) {
344
- URL.revokeObjectURL(blobUrl);
345
- scriptElement.remove();
346
- if (typeof window !== "undefined" && window.Deflect?.getToken) {
347
- delete window.Deflect.getToken;
348
- }
349
- }
350
- /**
351
- * Configures the Deflect SDK with the provided parameters.
352
- * Must be called before using getToken() or other SDK methods.
353
- *
354
- * @param params - Configuration options for the SDK
355
- * @param params.actionId - The unique action identifier from your Deflect dashboard (required)
356
- * @param params.scriptUrl - Optional custom script URL (defaults to Deflect CDN)
357
- * @throws Error if actionId is empty or contains invalid characters
358
- *
359
- * @example
360
- * ```typescript
361
- * Deflect.configure({ actionId: "your-action-id" });
362
- * ```
363
- */
364
- configure(params) {
365
- try {
366
- if (!params.actionId?.trim()) {
367
- throw new Error("actionId is required and cannot be empty");
368
- }
369
- if (this.config?.actionId === params.actionId) {
370
- return;
371
- }
372
- this.hasWarmupError = false;
373
- this.scriptCache = null;
374
- this.config = { ...params };
375
- if (typeof window !== "undefined") {
376
- window.Deflect.actionId = params.actionId;
377
- }
378
- if (!this.isTestMode()) {
379
- this.tryWarmup();
380
- }
381
- } catch (error) {
382
- const isUserError = error && typeof error === "object" && "isUserError" in error && error.isUserError === true;
383
- this.reportError(
384
- error,
385
- {
386
- deflect_sdk_error: "true",
387
- deflect_user_error: isUserError ? "true" : "false",
388
- method: "configure",
389
- action_id: params?.actionId || "unknown"
390
- },
391
- {
392
- actionId: params?.actionId,
393
- hasCache: this.scriptCache !== null,
394
- hasWarmupError: this.hasWarmupError
395
- }
396
- );
397
- throw error;
398
- }
399
- }
400
- isTestMode() {
401
- if (this.config?.actionId === "PULSE_TEST" || this.config?.actionId === "SENTRY_TEST") {
402
- throw new Error("PULSE_TEST: This is a test error to verify Pulse integration is working");
403
- }
404
- return this.config?.actionId === "t/FFFFFFFFFFFFF/111111111" || this.config?.actionId === "t/FFFFFFFFFFFFF/000000000";
405
- }
406
- /**
407
- * @deprecated Use {@link getToken} instead. This method is kept for backward compatibility.
408
- * @returns A promise that resolves to the Deflect token string
409
- */
410
- async solveChallenge() {
411
- return this.getToken();
412
- }
413
- /**
414
- * Retrieves a Deflect token for the configured action.
415
- * The token should be included in requests to your protected endpoints.
416
- *
417
- * @returns A promise that resolves to the Deflect token string
418
- * @throws Error if configure() has not been called first
419
- * @throws Error if the script fails to load or execute
420
- *
421
- * @example
422
- * ```typescript
423
- * const token = await Deflect.getToken();
424
- * // Include token in your API request
425
- * fetch('/api/protected', {
426
- * headers: { 'X-Deflect-Token': token }
427
- * });
428
- * ```
429
- */
430
- async getToken() {
431
- try {
432
- if (!this.config?.actionId) {
433
- throw new Error("Must call configure() before solveChallenge()");
434
- }
435
- if (this.isTestMode()) {
436
- return "TESTTOKEN";
437
- }
438
- let script;
439
- if (this.scriptCache && !this.isWarmupInProgress) {
440
- script = this.scriptCache;
441
- this.scriptCache = null;
442
- } else {
443
- script = await this.fetchScript();
444
- }
445
- return this.executeScript(script);
446
- } catch (error) {
447
- const isUserError = error && typeof error === "object" && "isUserError" in error && error.isUserError === true;
448
- this.reportError(
449
- error,
450
- {
451
- deflect_sdk_error: "true",
452
- deflect_user_error: isUserError ? "true" : "false",
453
- method: "getToken",
454
- action_id: this.config?.actionId || "unknown",
455
- has_cache: this.scriptCache !== null ? "true" : "false",
456
- has_warmup_error: this.hasWarmupError ? "true" : "false",
457
- stage: "call"
458
- },
459
- {
460
- actionId: this.config?.actionId,
461
- hasCache: this.scriptCache !== null,
462
- hasWarmupError: this.hasWarmupError
463
- }
464
- );
465
- throw error;
466
- }
467
- }
468
- /**
469
- * Pre-fetches the challenge script to reduce latency on the first getToken() call.
470
- * This is automatically called after configure(), but can be manually triggered.
471
- *
472
- * @returns A promise that resolves to true if warmup succeeded, false otherwise
473
- *
474
- * @example
475
- * ```typescript
476
- * Deflect.configure({ actionId: "your-action-id" });
477
- * const warmedUp = await Deflect.warmup();
478
- * console.log('Script pre-cached:', warmedUp);
479
- * ```
480
- */
481
- async warmup() {
482
- if (!this.config?.actionId) {
483
- return false;
484
- }
485
- try {
486
- await this.tryWarmup();
487
- return this.scriptCache !== null;
488
- } catch {
489
- return false;
490
- }
491
- }
492
- /**
493
- * Clears the cached challenge script.
494
- * Useful when you need to force a fresh script fetch on the next getToken() call.
495
- */
496
- clearCache() {
497
- this.scriptCache = null;
498
- }
499
- /**
500
- * Injects a Deflect token as a hidden input into a form and submits it.
501
- * Designed for use with form onsubmit handlers.
502
- *
503
- * @param event - The form submit event
504
- * @throws Error if not called from a form submit event
505
- *
506
- * @example
507
- * ```html
508
- * <form action="/login" method="POST" onsubmit="Deflect.injectToken(event)">
509
- * <input name="username" />
510
- * <button type="submit">Login</button>
511
- * </form>
512
- * ```
513
- */
514
- async injectToken(event) {
515
- if (!event || !event.target || !(event.target instanceof HTMLFormElement)) {
516
- throw new Error("injectToken: must be called from a form submit event");
517
- }
518
- event.preventDefault();
519
- const form = event.target;
520
- const token = await this.getToken();
521
- Array.from(form.querySelectorAll('input[name="deflect_token"]')).forEach(
522
- (el) => el.remove()
523
- );
524
- const hidden = document.createElement("input");
525
- hidden.type = "hidden";
526
- hidden.name = "deflect_token";
527
- hidden.value = token;
528
- form.appendChild(hidden);
529
- form.submit();
530
- }
531
- };
532
- var src_default = new Deflect();
533
- })();
package/dist/index.min.js DELETED
@@ -1,2 +0,0 @@
1
- "use strict";(()=>{var d={endpoint:"https://service.yabadabado.top/pulse",projectId:"deflect-sdk",deploymentId:"688529b539803661332b3f70",service:"deflect-sdk",release:"unknown"},g={name:"deflect-js-sdk",version:d.release||"unknown",language:"javascript"},l=class{constructor(e){this.config={...d,...e,endpoint:(e?.endpoint||d.endpoint).replace(/\/$/,"")},this.enabled=!!(this.config.endpoint&&this.config.projectId&&this.config.deploymentId)}captureException(e,t={}){if(!this.enabled||typeof fetch!="function")return;let n=this.buildErrorEvent(e,t);fetch(`${this.config.endpoint}/capture`,{method:"POST",headers:{"Content-Type":"application/json",project_id:this.config.projectId},body:JSON.stringify(n),keepalive:!0}).catch(()=>{})}buildErrorEvent(e,t){let n=this.normalizeError(e),r=this.config.environment||typeof window<"u"&&window.location.hostname||"unknown",i=typeof navigator>"u"?void 0:{name:navigator.userAgent||"browser",version:navigator.appVersion},o=typeof navigator>"u"?void 0:{name:navigator.platform},c=typeof window>"u"?void 0:{model:`${window.screen.width}x${window.screen.height}`,arch:typeof navigator<"u"?navigator.platform:void 0},f=typeof window>"u"?void 0:{method:"GET",url:window.location.href,headers:typeof navigator<"u"?{"User-Agent":navigator.userAgent,...typeof document<"u"&&document.referrer?{Referer:document.referrer}:{}}:void 0};return{event_type:"error",event_id:typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():Math.random().toString(16).slice(2)+Date.now().toString(16),deployment_id:this.config.deploymentId,project_id:this.config.projectId,environment:r,service:this.config.service,timestamp:new Date().toISOString(),release:this.config.release,sdk:{...g,version:this.config.release||g.version},tags:t.tags,context:t.context,error:{level:t.level||"error",message:n.message,exception:this.buildExceptionPayload(n),request:f,runtime:i,os:o,device:c}}}normalizeError(e){if(e instanceof Error)return e;let t=typeof e=="string"?e:"Unknown error";return new Error(t)}buildExceptionPayload(e){let t=this.parseStack(e);return{type:e.name||"Error",value:e.message,stacktrace:t.length?{frames:t}:void 0}}parseStack(e){if(!e.stack)return[];let t=[],n=e.stack.split(`
2
- `).slice(1);for(let r of n){let i=r.trim().replace(/^at\s+/,""),o=i.includes("(")&&i.endsWith(")"),c=o?i.slice(0,i.indexOf("(")).trim():"",s=(o?i.slice(i.indexOf("(")+1,i.length-1):i).split(":"),a=s[0]||void 0,p=s.length>1?Number(s[1]):void 0,h=s.length>2?Number(s[2]):void 0;a&&t.push({filename:a,abs_path:a,function:c||void 0,lineno:Number.isFinite(p)?p:void 0,colno:Number.isFinite(h)?h:void 0,in_app:!a.includes("node_modules")})}return t}},m=l;var u=class{constructor(){this.config=null;this.scriptCache=null;this.isWarmupInProgress=!1;this.hasWarmupError=!1;this.initializeGlobalState(),this.pulseReporter=new m(this.resolvePulseConfig()),this.setupAutomaticWarmup()}initializeGlobalState(){typeof window>"u"||(window.Deflect=window.Deflect||{})}setupAutomaticWarmup(){typeof window>"u"||(document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>this.tryWarmup()):setTimeout(()=>this.tryWarmup(),100))}resolvePulseConfig(){let e=typeof window<"u"&&typeof window.Deflect=="object"&&window.Deflect?.pulseConfig&&typeof window.Deflect.pulseConfig=="object"?window.Deflect.pulseConfig:{};return{...e,environment:e.environment||(typeof window<"u"?window.location.hostname:void 0)}}reportError(e,t,n){this.pulseReporter.captureException(e,{tags:t,context:n})}async tryWarmup(){if(!(!this.config?.actionId||this.isWarmupInProgress||this.scriptCache||this.hasWarmupError)){this.isWarmupInProgress=!0;try{this.scriptCache=await this.fetchScript(),this.hasWarmupError=!1}catch{this.hasWarmupError=!0}finally{this.isWarmupInProgress=!1}}}validateActionId(e){let t=e.trim();if(!/^[a-zA-Z0-9/_-]+$/.test(t))throw new Error("Invalid actionId format: contains disallowed characters");return encodeURIComponent(t)}buildScriptUrl(e){let t=this.config?.scriptUrl||"https://js.deflect.bot/main.js",n=this.validateActionId(e),r=Date.now().toString();return`${t}?action_id=${n}&_=${r}`}async fetchScript(){if(!this.config?.actionId)throw new Error("actionId is required");let e=this.buildScriptUrl(this.config.actionId);try{let t=await fetch(e,{cache:"no-store",mode:"cors",credentials:"omit"});if(!t.ok)throw new Error(`Failed to fetch script: ${t.status}`);let n=await t.text();try{let r=JSON.parse(n);if(r.success===!1||r.error){let i=r.error||"Script fetch failed",o=new Error(i);throw(i==="action_does_not_exist"||i.includes("invalid action"))&&(o.isUserError=!0),o}}catch(r){if(!(r instanceof SyntaxError))throw r}return{content:n,sessionId:t.headers.get("session_id")||void 0}}catch(t){throw this.reportError(t,{deflect_sdk_error:"true",method:"fetchScript",action_id:this.config.actionId},{actionId:this.config.actionId,url:e}),t}}async executeScript(e){e.sessionId&&typeof window<"u"&&(window.Deflect.sessionId=e.sessionId);let t=this.createScriptBlob(e.content),n=null;try{n=await this.loadScriptElement(t),await this.waitForGetToken();let r=await this.getTokenFromScript();return this.prefetchNextScript(),r}catch(r){throw this.reportError(r,{deflect_sdk_error:"true",method:"executeScript",stage:"load_or_execute",action_id:this.config?.actionId||"unknown"},{hasCache:this.scriptCache!==null,hasWarmupError:this.hasWarmupError}),r}finally{n?this.cleanup(t,n):URL.revokeObjectURL(t)}}prefetchNextScript(){this.hasWarmupError||this.tryWarmup().catch(()=>{})}async waitForGetToken(){return new Promise((e,t)=>{let n=setInterval(()=>{typeof window<"u"&&typeof window.Deflect?.getToken=="function"&&(clearInterval(n),e())},50);setTimeout(()=>{clearInterval(n),t(new Error("Timeout: getToken function did not become available within 10 seconds"))},1e4)})}createScriptBlob(e){let t=new Blob([e],{type:"text/javascript"});return URL.createObjectURL(t)}async loadScriptElement(e){return new Promise((t,n)=>{let r=document.createElement("script");r.type="module",r.src=e,r.onload=()=>t(r),r.onerror=()=>n(new Error("Script failed to load")),document.head.appendChild(r)})}async getTokenFromScript(){if(typeof window>"u"||typeof window.Deflect?.getToken!="function")throw new Error("Script did not load properly - getToken not available");try{return await window.Deflect.getToken()}catch(e){throw new Error(`Script execution failed: ${e}`)}}cleanup(e,t){URL.revokeObjectURL(e),t.remove(),typeof window<"u"&&window.Deflect?.getToken&&delete window.Deflect.getToken}configure(e){try{if(!e.actionId?.trim())throw new Error("actionId is required and cannot be empty");if(this.config?.actionId===e.actionId)return;this.hasWarmupError=!1,this.scriptCache=null,this.config={...e},typeof window<"u"&&(window.Deflect.actionId=e.actionId),this.isTestMode()||this.tryWarmup()}catch(t){let n=t&&typeof t=="object"&&"isUserError"in t&&t.isUserError===!0;throw this.reportError(t,{deflect_sdk_error:"true",deflect_user_error:n?"true":"false",method:"configure",action_id:e?.actionId||"unknown"},{actionId:e?.actionId,hasCache:this.scriptCache!==null,hasWarmupError:this.hasWarmupError}),t}}isTestMode(){if(this.config?.actionId==="PULSE_TEST"||this.config?.actionId==="SENTRY_TEST")throw new Error("PULSE_TEST: This is a test error to verify Pulse integration is working");return this.config?.actionId==="t/FFFFFFFFFFFFF/111111111"||this.config?.actionId==="t/FFFFFFFFFFFFF/000000000"}async solveChallenge(){return this.getToken()}async getToken(){try{if(!this.config?.actionId)throw new Error("Must call configure() before solveChallenge()");if(this.isTestMode())return"TESTTOKEN";let e;return this.scriptCache&&!this.isWarmupInProgress?(e=this.scriptCache,this.scriptCache=null):e=await this.fetchScript(),this.executeScript(e)}catch(e){let t=e&&typeof e=="object"&&"isUserError"in e&&e.isUserError===!0;throw this.reportError(e,{deflect_sdk_error:"true",deflect_user_error:t?"true":"false",method:"getToken",action_id:this.config?.actionId||"unknown",has_cache:this.scriptCache!==null?"true":"false",has_warmup_error:this.hasWarmupError?"true":"false",stage:"call"},{actionId:this.config?.actionId,hasCache:this.scriptCache!==null,hasWarmupError:this.hasWarmupError}),e}}async warmup(){if(!this.config?.actionId)return!1;try{return await this.tryWarmup(),this.scriptCache!==null}catch{return!1}}clearCache(){this.scriptCache=null}async injectToken(e){if(!e||!e.target||!(e.target instanceof HTMLFormElement))throw new Error("injectToken: must be called from a form submit event");e.preventDefault();let t=e.target,n=await this.getToken();Array.from(t.querySelectorAll('input[name="deflect_token"]')).forEach(i=>i.remove());let r=document.createElement("input");r.type="hidden",r.name="deflect_token",r.value=n,t.appendChild(r),t.submit()}},I=new u;})();
package/dist/pulse.d.ts DELETED
@@ -1,99 +0,0 @@
1
- export type PulseEventType = "error" | "span" | "transaction" | "log" | "metric";
2
- export type PulseLevel = "fatal" | "error" | "warning" | "info" | "debug";
3
- export interface PulseReporterConfig {
4
- endpoint: string;
5
- projectId: string;
6
- deploymentId: string;
7
- environment?: string;
8
- service?: string;
9
- release?: string;
10
- }
11
- export interface PulseSDKInfo {
12
- name: string;
13
- version: string;
14
- language: string;
15
- integrations?: string[];
16
- }
17
- export interface PulseStackFrame {
18
- filename?: string;
19
- abs_path?: string;
20
- function?: string;
21
- lineno?: number;
22
- colno?: number;
23
- in_app?: boolean;
24
- context_line?: string;
25
- }
26
- export interface PulseExceptionPayload {
27
- type?: string;
28
- value?: string;
29
- stacktrace?: {
30
- frames: PulseStackFrame[];
31
- };
32
- }
33
- export interface PulseRequestInfo {
34
- method?: string;
35
- url?: string;
36
- headers?: Record<string, string>;
37
- route?: string;
38
- status_code?: number;
39
- }
40
- export interface PulseRuntimeInfo {
41
- name?: string;
42
- version?: string;
43
- }
44
- export interface PulseOSInfo {
45
- name?: string;
46
- version?: string;
47
- }
48
- export interface PulseDeviceInfo {
49
- model?: string;
50
- arch?: string;
51
- }
52
- export interface PulseErrorPayload {
53
- level: PulseLevel;
54
- message?: string;
55
- exception?: PulseExceptionPayload;
56
- culprit?: string;
57
- request?: PulseRequestInfo;
58
- runtime?: PulseRuntimeInfo;
59
- os?: PulseOSInfo;
60
- device?: PulseDeviceInfo;
61
- }
62
- export interface PulseEvent {
63
- event_type: PulseEventType;
64
- event_id: string;
65
- deployment_id: string;
66
- project_id: string;
67
- environment?: string;
68
- service?: string;
69
- host?: string;
70
- sdk?: PulseSDKInfo;
71
- timestamp: string;
72
- release?: string;
73
- dist?: string;
74
- deployment?: string;
75
- tags?: Record<string, string>;
76
- context?: Record<string, unknown>;
77
- sample_rate?: number;
78
- fingerprint?: string[];
79
- ingest_key_id?: string;
80
- payload_version?: number;
81
- content_encoding?: string;
82
- error?: PulseErrorPayload;
83
- }
84
- export interface PulseCaptureOptions {
85
- tags?: Record<string, string>;
86
- context?: Record<string, unknown>;
87
- level?: PulseLevel;
88
- }
89
- export declare class PulseReporter {
90
- private readonly config;
91
- private readonly enabled;
92
- constructor(config?: Partial<PulseReporterConfig>);
93
- captureException(error: unknown, options?: PulseCaptureOptions): void;
94
- private buildErrorEvent;
95
- private normalizeError;
96
- private buildExceptionPayload;
97
- private parseStack;
98
- }
99
- export default PulseReporter;