@deflectbot/deflect-sdk 1.0.7 → 1.0.9

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
@@ -5,8 +5,46 @@
5
5
 
6
6
  Deflect is an antibot solution that works with Vue, React, NextJS, and other JavaScript frameworks.
7
7
 
8
- ## Installation
8
+ ---
9
+
10
+ ## CDN Install (Auto-Updates)
11
+
12
+ ```bash
13
+ Include in your project:
14
+ <script src="https://cdn.jsdelivr.net/npm/@deflectbot/deflect-sdk/dist/index.min.js"></script>
15
+ ```
16
+
17
+ ---
18
+
19
+ ## NPM Install (Requires Manual Updates)
9
20
 
10
21
  ```bash
11
22
  npm install deflect
12
23
  ```
24
+
25
+ ---
26
+
27
+ ## Setup
28
+
29
+ ```ts
30
+ import Deflect from "@deflectbot/deflect-sdk";
31
+
32
+ Deflect.configure({
33
+ siteKey: "YOUR_SITE_KEY",
34
+ extraArgs: { mode: "strict" }, // Optional
35
+ forceRefresh: true, // Optional
36
+ });
37
+ ```
38
+
39
+ ---
40
+
41
+ ## Solve Challenge
42
+
43
+ ```ts
44
+ try {
45
+ const token = await Deflect.solveChallenge();
46
+ console.log("✅ Token received:", token);
47
+ } catch (error) {
48
+ console.error("❌ Failed to solve challenge:", error);
49
+ }
50
+ ```
package/dist/index.js CHANGED
@@ -1,41 +1,132 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
1
10
  class Deflect {
2
11
  constructor() {
3
- if (typeof window.Deflect === "undefined") {
4
- window.Deflect = {};
5
- }
6
- window.Deflect.siteKey = "";
12
+ this.scriptLoadPromise = null;
13
+ this.cacheTTL = 10 * 60 * 1000;
14
+ window.Deflect = window.Deflect || {};
15
+ window.Deflect.siteKey = window.Deflect.siteKey || "";
16
+ window.Deflect.sessionId = window.Deflect.sessionId || "";
17
+ window.Deflect.extraArgs = window.Deflect.extraArgs || {};
7
18
  }
8
- configure(params) {
19
+ configure(params, forceRefresh = false) {
9
20
  if (!params.siteKey) {
10
21
  throw new Error("siteKey is required in configuration");
11
22
  }
12
23
  window.Deflect.siteKey = params.siteKey;
24
+ window.Deflect.extraArgs = params.extraArgs || {};
25
+ if (forceRefresh) {
26
+ console.log("Main.js force refreshed");
27
+ sessionStorage.removeItem("deflect_script");
28
+ localStorage.removeItem("deflect_script_timestamp");
29
+ this.scriptLoadPromise = null;
30
+ }
31
+ if (!this.scriptLoadPromise) {
32
+ this.scriptLoadPromise = this.loadDeflectScript();
33
+ }
13
34
  }
14
- solveChallenge() {
35
+ loadDeflectScript() {
36
+ const extraArgs = Object.keys(window.Deflect.extraArgs || {})
37
+ .map((key) => `${encodeURIComponent(key)}=${encodeURIComponent(window.Deflect.extraArgs[key])}`)
38
+ .join("&");
39
+ const scriptUrl = `https://js.deflect.bot/main.js?site=${encodeURIComponent(window.Deflect.siteKey)}${extraArgs ? `&${extraArgs}` : ""}`;
15
40
  return new Promise((resolve, reject) => {
16
- if (!window.Deflect.siteKey) {
17
- return reject("API key (siteKey) is missing in configuration");
18
- }
19
- const scriptUrl = `https://js.deflect.bot/main.js?site=${window.Deflect.siteKey}`;
20
- const script = document.createElement("script");
21
- script.src = scriptUrl;
22
- script.onload = () => {
23
- if (typeof window.Deflect === "undefined" ||
24
- typeof window.Deflect.getToken !== "function") {
25
- return reject("Deflect script did not load properly");
41
+ const cachedScript = sessionStorage.getItem("deflect_script");
42
+ const lastFetchTime = localStorage.getItem("deflect_script_timestamp");
43
+ // Check if we have a valid cache (within 10 minutes)
44
+ if (cachedScript &&
45
+ lastFetchTime &&
46
+ Date.now() - parseInt(lastFetchTime) < this.cacheTTL) {
47
+ console.log("✅ Using cached Deflect script");
48
+ this.injectScript(cachedScript, resolve, reject);
49
+ return;
50
+ }
51
+ console.log("⏳ Fetching new Deflect script...");
52
+ const workerCode = `
53
+ self.onmessage = async function(event) {
54
+ try {
55
+ const response = await fetch(event.data.url, { cache: "no-store" });
56
+ if (!response.ok) {
57
+ const errorText = await response.text();
58
+ self.postMessage({ error: 'Failed to fetch script. Status: ' + response.status + ' - ' + errorText });
59
+ return;
60
+ }
61
+ const sessionId = response.headers.get("session_id") || "";
62
+ const scriptText = await response.text();
63
+ self.postMessage({ scriptText: scriptText, sessionId: sessionId });
64
+ } catch (err) {
65
+ self.postMessage({ error: 'Error in worker: ' + (err instanceof Error ? err.message : String(err)) });
66
+ }
67
+ };
68
+ `;
69
+ const blob = new Blob([workerCode], { type: "application/javascript" });
70
+ const worker = new Worker(URL.createObjectURL(blob));
71
+ worker.onmessage = (event) => {
72
+ if (event.data.error) {
73
+ reject(new Error(event.data.error));
74
+ worker.terminate();
75
+ return;
26
76
  }
27
- window.Deflect.getToken()
28
- .then((token) => {
29
- resolve(token);
30
- })
31
- .catch((err) => {
32
- reject(`Failed to get token: ${err.message}`);
33
- });
77
+ const scriptText = event.data.scriptText || "";
78
+ window.Deflect.sessionId = event.data.sessionId || "";
79
+ // Cache script info
80
+ sessionStorage.setItem("deflect_script", scriptText);
81
+ localStorage.setItem("deflect_script_timestamp", Date.now().toString());
82
+ this.injectScript(scriptText, resolve, reject);
83
+ worker.terminate();
34
84
  };
35
- script.onerror = () => {
36
- reject("Failed to load the Deflect script");
85
+ worker.onerror = function (event) {
86
+ reject(new Error("Worker encountered an error: " + event.message));
87
+ worker.terminate();
37
88
  };
38
- document.head.appendChild(script);
89
+ worker.postMessage({ url: scriptUrl });
90
+ });
91
+ }
92
+ injectScript(scriptText, resolve, reject) {
93
+ const scriptEl = document.createElement("script");
94
+ scriptEl.textContent = scriptText;
95
+ scriptEl.onload = () => {
96
+ console.log("✅ Deflect script loaded successfully.");
97
+ resolve();
98
+ };
99
+ scriptEl.onerror = () => {
100
+ reject(new Error("Failed to load Deflect script"));
101
+ };
102
+ document.head.appendChild(scriptEl);
103
+ }
104
+ solveChallenge() {
105
+ return __awaiter(this, void 0, void 0, function* () {
106
+ if (!window.Deflect.siteKey) {
107
+ throw new Error("API key (siteKey) is missing in configuration");
108
+ }
109
+ try {
110
+ yield this.scriptLoadPromise;
111
+ }
112
+ catch (error) {
113
+ if (error instanceof Error) {
114
+ throw new Error("Deflect script failed to load: " + error.message);
115
+ }
116
+ throw new Error("Deflect script failed to load: " + String(error));
117
+ }
118
+ if (typeof window.Deflect.getToken !== "function") {
119
+ throw new Error("Deflect script did not load properly or is not exposing getToken.");
120
+ }
121
+ try {
122
+ return yield window.Deflect.getToken(window.Deflect.siteKey, window.Deflect.sessionId);
123
+ }
124
+ catch (error) {
125
+ if (error instanceof Error) {
126
+ throw new Error("Error getting Deflect token: " + error.message);
127
+ }
128
+ throw new Error("Error getting Deflect token: " + String(error));
129
+ }
39
130
  });
40
131
  }
41
132
  }
@@ -1,10 +1,17 @@
1
1
  interface DeflectConfig {
2
- siteKey: string;
2
+ siteKey: string;
3
+ extraArgs?: {
4
+ [key: string]: string;
5
+ };
3
6
  }
4
7
  declare class Deflect {
5
- constructor();
6
- configure(params: DeflectConfig): void;
7
- solveChallenge(): Promise<string>;
8
+ private scriptLoadPromise;
9
+ private cacheTTL;
10
+ constructor();
11
+ configure(params: DeflectConfig, forceRefresh?: boolean): void;
12
+ private loadDeflectScript;
13
+ private injectScript;
14
+ solveChallenge(): Promise<string>;
8
15
  }
9
16
  declare const _default: Deflect;
10
17
  export default _default;
@@ -0,0 +1,12 @@
1
+ import globals from "globals";
2
+ import pluginJs from "@eslint/js";
3
+ import tseslint from "typescript-eslint";
4
+
5
+
6
+ /** @type {import('eslint').Linter.Config[]} */
7
+ export default [
8
+ {files: ["**/*.{js,mjs,cjs,ts}"]},
9
+ {languageOptions: { globals: globals.browser }},
10
+ pluginJs.configs.recommended,
11
+ ...tseslint.configs.recommended,
12
+ ];
package/package.json CHANGED
@@ -1,18 +1,25 @@
1
- {
2
- "name": "@deflectbot/deflect-sdk",
3
- "version": "1.0.7",
4
- "description": "",
5
- "main": "dist/index.js",
6
- "types": "dist/types/index.d.ts",
7
- "scripts": {
8
- "build": "tsc"
9
- },
10
- "author": "Fredrik Rafn",
11
- "license": "MIT",
12
- "devDependencies": {
13
- "typescript": "^5.7.3"
14
- },
15
- "publishConfig": {
16
- "access": "public"
17
- }
18
- }
1
+ {
2
+ "name": "@deflectbot/deflect-sdk",
3
+ "version": "1.0.9",
4
+ "description": "",
5
+ "main": "dist/index.js",
6
+ "types": "dist/types/index.d.ts",
7
+ "scripts": {
8
+ "build": "tsc"
9
+ },
10
+ "author": "Fredrik Rafn",
11
+ "license": "MIT",
12
+ "devDependencies": {
13
+ "@eslint/js": "^9.22.0",
14
+ "eslint": "^9.22.0",
15
+ "globals": "^16.0.0",
16
+ "typescript": "^5.7.3",
17
+ "typescript-eslint": "^8.27.0"
18
+ },
19
+ "publishConfig": {
20
+ "access": "public"
21
+ },
22
+ "dependencies": {
23
+ "@deflectbot/deflect-sdk": "file:"
24
+ }
25
+ }
package/src/index.ts CHANGED
@@ -1,55 +1,173 @@
1
1
  interface DeflectConfig {
2
2
  siteKey: string;
3
+ extraArgs?: { [key: string]: string };
3
4
  }
4
5
 
5
6
  class Deflect {
7
+ private scriptLoadPromise: Promise<void> | null = null;
8
+ private cacheTTL: number = 10 * 60 * 1000;
9
+
6
10
  constructor() {
7
- if (typeof window.Deflect === "undefined") {
8
- window.Deflect = {};
9
- }
10
- window.Deflect.siteKey = "";
11
- window.Deflect.sessionId = "";
11
+ window.Deflect = window.Deflect || {};
12
+ window.Deflect.siteKey = window.Deflect.siteKey || "";
13
+ window.Deflect.sessionId = window.Deflect.sessionId || "";
14
+ window.Deflect.extraArgs = window.Deflect.extraArgs || {};
12
15
  }
13
16
 
14
- configure(params: DeflectConfig): void {
17
+ configure(params: DeflectConfig, forceRefresh = false): void {
15
18
  if (!params.siteKey) {
16
19
  throw new Error("siteKey is required in configuration");
17
20
  }
18
- window.Deflect.siteKey = params.siteKey;
19
- }
20
21
 
21
- async solveChallenge(): Promise<string> {
22
- if (!window.Deflect.siteKey) {
23
- throw new Error("API key (siteKey) is missing in configuration");
24
- }
22
+ window.Deflect.siteKey = params.siteKey;
23
+ window.Deflect.extraArgs = params.extraArgs || {};
25
24
 
26
- const scriptUrl = `https://js.deflect.bot/main.js?site=${window.Deflect.siteKey}`;
25
+ if (forceRefresh) {
26
+ console.log("Main.js force refreshed");
27
+ sessionStorage.removeItem("deflect_script");
28
+ localStorage.removeItem("deflect_script_timestamp");
27
29
 
28
- const response = await fetch(scriptUrl);
29
- if (!response.ok) {
30
- throw new Error("Failed to fetch the Deflect script");
30
+ this.scriptLoadPromise = null;
31
31
  }
32
32
 
33
- const sessionId = response.headers.get("session_id");
34
- if (sessionId) {
35
- window.Deflect.sessionId = sessionId;
33
+ if (!this.scriptLoadPromise) {
34
+ this.scriptLoadPromise = this.loadDeflectScript();
36
35
  }
36
+ }
37
+
38
+ private loadDeflectScript(): Promise<void> {
39
+ const extraArgs = Object.keys(window.Deflect.extraArgs || {})
40
+ .map(
41
+ (key) =>
42
+ `${encodeURIComponent(key)}=${encodeURIComponent(
43
+ window.Deflect.extraArgs[key]
44
+ )}`
45
+ )
46
+ .join("&");
47
+
48
+ const scriptUrl = `https://js.deflect.bot/main.js?site=${encodeURIComponent(
49
+ window.Deflect.siteKey
50
+ )}${extraArgs ? `&${extraArgs}` : ""}`;
51
+
52
+ return new Promise((resolve, reject) => {
53
+ const cachedScript = sessionStorage.getItem("deflect_script");
54
+ const lastFetchTime = localStorage.getItem("deflect_script_timestamp");
55
+
56
+ // Check if we have a valid cache (within 10 minutes)
57
+ if (
58
+ cachedScript &&
59
+ lastFetchTime &&
60
+ Date.now() - parseInt(lastFetchTime) < this.cacheTTL
61
+ ) {
62
+ console.log("✅ Using cached Deflect script");
63
+ this.injectScript(cachedScript, resolve, reject);
64
+ return;
65
+ }
66
+
67
+ console.log("⏳ Fetching new Deflect script...");
68
+
69
+ const workerCode = `
70
+ self.onmessage = async function(event) {
71
+ try {
72
+ const response = await fetch(event.data.url, { cache: "no-store" });
73
+ if (!response.ok) {
74
+ const errorText = await response.text();
75
+ self.postMessage({ error: 'Failed to fetch script. Status: ' + response.status + ' - ' + errorText });
76
+ return;
77
+ }
78
+ const sessionId = response.headers.get("session_id") || "";
79
+ const scriptText = await response.text();
80
+ self.postMessage({ scriptText: scriptText, sessionId: sessionId });
81
+ } catch (err) {
82
+ self.postMessage({ error: 'Error in worker: ' + (err instanceof Error ? err.message : String(err)) });
83
+ }
84
+ };
85
+ `;
37
86
 
38
- const scriptText = await response.text();
87
+ const blob = new Blob([workerCode], { type: "application/javascript" });
88
+ const worker = new Worker(URL.createObjectURL(blob));
39
89
 
90
+ worker.onmessage = (
91
+ event: MessageEvent<{
92
+ scriptText?: string;
93
+ sessionId?: string;
94
+ error?: string;
95
+ }>
96
+ ) => {
97
+ if (event.data.error) {
98
+ reject(new Error(event.data.error));
99
+ worker.terminate();
100
+ return;
101
+ }
102
+
103
+ const scriptText = event.data.scriptText || "";
104
+ window.Deflect.sessionId = event.data.sessionId || "";
105
+
106
+ // Cache script info
107
+ sessionStorage.setItem("deflect_script", scriptText);
108
+ localStorage.setItem("deflect_script_timestamp", Date.now().toString());
109
+
110
+ this.injectScript(scriptText, resolve, reject);
111
+ worker.terminate();
112
+ };
113
+
114
+ worker.onerror = function (event: ErrorEvent) {
115
+ reject(new Error("Worker encountered an error: " + event.message));
116
+ worker.terminate();
117
+ };
118
+
119
+ worker.postMessage({ url: scriptUrl });
120
+ });
121
+ }
122
+
123
+ private injectScript(
124
+ scriptText: string,
125
+ resolve: () => void,
126
+ reject: (error: Error) => void
127
+ ) {
40
128
  const scriptEl = document.createElement("script");
41
129
  scriptEl.textContent = scriptText;
130
+ scriptEl.onload = () => {
131
+ console.log("✅ Deflect script loaded successfully.");
132
+ resolve();
133
+ };
134
+ scriptEl.onerror = () => {
135
+ reject(new Error("Failed to load Deflect script"));
136
+ };
42
137
  document.head.appendChild(scriptEl);
138
+ }
43
139
 
44
- if (
45
- typeof window.Deflect === "undefined" ||
46
- typeof window.Deflect.getToken !== "function"
47
- ) {
48
- throw new Error("Deflect script did not load properly");
140
+ async solveChallenge(): Promise<string> {
141
+ if (!window.Deflect.siteKey) {
142
+ throw new Error("API key (siteKey) is missing in configuration");
143
+ }
144
+
145
+ try {
146
+ await this.scriptLoadPromise;
147
+ } catch (error: unknown) {
148
+ if (error instanceof Error) {
149
+ throw new Error("Deflect script failed to load: " + error.message);
150
+ }
151
+ throw new Error("Deflect script failed to load: " + String(error));
152
+ }
153
+
154
+ if (typeof window.Deflect.getToken !== "function") {
155
+ throw new Error(
156
+ "Deflect script did not load properly or is not exposing getToken."
157
+ );
49
158
  }
50
159
 
51
- const token = await window.Deflect.getToken();
52
- return token;
160
+ try {
161
+ return await window.Deflect.getToken(
162
+ window.Deflect.siteKey,
163
+ window.Deflect.sessionId
164
+ );
165
+ } catch (error: unknown) {
166
+ if (error instanceof Error) {
167
+ throw new Error("Error getting Deflect token: " + error.message);
168
+ }
169
+ throw new Error("Error getting Deflect token: " + String(error));
170
+ }
53
171
  }
54
172
  }
55
173