@deflectbot/deflect-sdk 1.3.0 → 1.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,226 +1,194 @@
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
- };
10
- class Deflect {
1
+ "use strict";
2
+ (() => {
3
+ var __defProp = Object.defineProperty;
4
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
5
+
6
+ // src/index.ts
7
+ var Deflect = class {
11
8
  constructor() {
12
- this.config = null;
13
- this.scriptCache = null;
14
- this.isWarmupInProgress = false;
15
- this.initializeGlobalState();
16
- this.setupAutomaticWarmup();
9
+ this.config = null;
10
+ this.scriptCache = null;
11
+ this.isWarmupInProgress = false;
12
+ this.initializeGlobalState();
13
+ this.setupAutomaticWarmup();
14
+ }
15
+ static {
16
+ __name(this, "Deflect");
17
17
  }
18
18
  initializeGlobalState() {
19
- if (typeof window === "undefined")
20
- return;
21
- window.Deflect = window.Deflect || {};
19
+ if (typeof window === "undefined") return;
20
+ window.Deflect = window.Deflect || {};
22
21
  }
23
22
  setupAutomaticWarmup() {
24
- if (typeof window === "undefined")
25
- return;
26
- if (document.readyState === "loading") {
27
- document.addEventListener("DOMContentLoaded", () => this.tryWarmup());
28
- }
29
- else {
30
- setTimeout(() => this.tryWarmup(), 100);
31
- }
32
- }
33
- tryWarmup() {
34
- return __awaiter(this, void 0, void 0, function* () {
35
- var _a;
36
- if (!((_a = this.config) === null || _a === void 0 ? void 0 : _a.actionId) || this.isWarmupInProgress || this.scriptCache) {
37
- return;
38
- }
39
- this.isWarmupInProgress = true;
40
- try {
41
- this.scriptCache = yield this.fetchScript();
42
- }
43
- catch (_b) {
44
- /* empty */
45
- }
46
- finally {
47
- this.isWarmupInProgress = false;
48
- }
49
- });
23
+ if (typeof window === "undefined") return;
24
+ if (document.readyState === "loading") {
25
+ document.addEventListener("DOMContentLoaded", () => this.tryWarmup());
26
+ } else {
27
+ setTimeout(() => this.tryWarmup(), 100);
28
+ }
29
+ }
30
+ async tryWarmup() {
31
+ if (!this.config?.actionId || this.isWarmupInProgress || this.scriptCache) {
32
+ return;
33
+ }
34
+ this.isWarmupInProgress = true;
35
+ try {
36
+ this.scriptCache = await this.fetchScript();
37
+ } catch {
38
+ } finally {
39
+ this.isWarmupInProgress = false;
40
+ }
50
41
  }
51
42
  buildScriptUrl(actionId) {
52
- var _a, _b;
53
- const baseUrl = ((_a = this.config) === null || _a === void 0 ? void 0 : _a.scriptUrl) || "https://js.deflect.bot/main.js";
54
- if ((_b = this.config) === null || _b === void 0 ? void 0 : _b.scriptUrl) {
55
- return baseUrl;
56
- }
57
- const nonce = Date.now().toString();
58
- return `${baseUrl}?action_id=${actionId}&_=${nonce}`;
59
- }
60
- fetchScript() {
61
- return __awaiter(this, void 0, void 0, function* () {
62
- var _a;
63
- if (!((_a = this.config) === null || _a === void 0 ? void 0 : _a.actionId)) {
64
- throw new Error("actionId is required");
65
- }
66
- const url = this.buildScriptUrl(this.config.actionId);
67
- const response = yield fetch(url, { cache: "no-store" });
68
- if (!response.ok) {
69
- throw new Error(`Failed to fetch script: ${response.status}`);
70
- }
71
- return {
72
- content: yield response.text(),
73
- sessionId: response.headers.get("session_id") || undefined,
74
- };
75
- });
76
- }
77
- executeScript(script) {
78
- return __awaiter(this, void 0, void 0, function* () {
79
- if (script.sessionId && typeof window !== "undefined") {
80
- window.Deflect.sessionId = script.sessionId;
81
- }
82
- const readyPromise = this.createReadyPromise();
83
- const blobUrl = this.createScriptBlob(script.content);
84
- const scriptElement = yield this.loadScriptElement(blobUrl);
85
- try {
86
- yield readyPromise;
87
- const token = yield this.getTokenFromScript();
88
- this.prefetchNextScript();
89
- return token;
90
- }
91
- finally {
92
- this.cleanup(blobUrl, scriptElement);
93
- }
94
- });
43
+ const baseUrl = this.config?.scriptUrl || "https://js.deflect.bot/main.js";
44
+ const nonce = Date.now().toString();
45
+ return `${baseUrl}?action_id=${actionId}&_=${nonce}`;
46
+ }
47
+ async fetchScript() {
48
+ if (!this.config?.actionId) {
49
+ throw new Error("actionId is required");
50
+ }
51
+ const url = this.buildScriptUrl(this.config.actionId);
52
+ const response = await fetch(url, { cache: "no-store" });
53
+ if (!response.ok) {
54
+ throw new Error(`Failed to fetch script: ${response.status}`);
55
+ }
56
+ return {
57
+ content: await response.text(),
58
+ sessionId: response.headers.get("session_id") || void 0
59
+ };
60
+ }
61
+ async executeScript(script) {
62
+ if (script.sessionId && typeof window !== "undefined") {
63
+ window.Deflect.sessionId = script.sessionId;
64
+ }
65
+ const readyPromise = this.createReadyPromise();
66
+ const blobUrl = this.createScriptBlob(script.content);
67
+ const scriptElement = await this.loadScriptElement(blobUrl);
68
+ try {
69
+ await readyPromise;
70
+ const token = await this.getTokenFromScript();
71
+ this.prefetchNextScript();
72
+ return token;
73
+ } finally {
74
+ this.cleanup(blobUrl, scriptElement);
75
+ }
95
76
  }
96
77
  prefetchNextScript() {
97
- this.tryWarmup().catch(() => { });
78
+ this.tryWarmup().catch(() => {
79
+ });
98
80
  }
99
81
  createReadyPromise() {
100
- return new Promise((resolve) => {
101
- if (typeof window !== "undefined") {
102
- window.Deflect.ready = {
103
- promise: new Promise((innerResolve) => {
104
- window.Deflect.ready.resolve = innerResolve;
105
- }),
106
- resolve: () => resolve(),
107
- };
108
- }
109
- });
82
+ return new Promise((resolve) => {
83
+ if (typeof window !== "undefined") {
84
+ window.Deflect.ready = {
85
+ promise: new Promise((innerResolve) => {
86
+ window.Deflect.ready.resolve = innerResolve;
87
+ }),
88
+ resolve: /* @__PURE__ */ __name(() => resolve(), "resolve")
89
+ };
90
+ }
91
+ });
110
92
  }
111
93
  createScriptBlob(content) {
112
- const blob = new Blob([content], { type: "text/javascript" });
113
- return URL.createObjectURL(blob);
114
- }
115
- loadScriptElement(blobUrl) {
116
- return __awaiter(this, void 0, void 0, function* () {
117
- return new Promise((resolve, reject) => {
118
- const script = document.createElement("script");
119
- script.type = "module";
120
- script.src = blobUrl;
121
- script.onload = () => resolve(script);
122
- script.onerror = () => reject(new Error("Script failed to load"));
123
- document.head.appendChild(script);
124
- });
125
- });
126
- }
127
- getTokenFromScript() {
128
- return __awaiter(this, void 0, void 0, function* () {
129
- var _a;
130
- if (typeof window === "undefined" ||
131
- typeof ((_a = window.Deflect) === null || _a === void 0 ? void 0 : _a.getToken) !== "function") {
132
- throw new Error("Script did not load properly - getToken not available");
133
- }
134
- try {
135
- return yield window.Deflect.getToken();
136
- }
137
- catch (error) {
138
- throw new Error(`Script execution failed: ${error}`);
139
- }
140
- });
94
+ const blob = new Blob([content], { type: "text/javascript" });
95
+ return URL.createObjectURL(blob);
96
+ }
97
+ async loadScriptElement(blobUrl) {
98
+ return new Promise((resolve, reject) => {
99
+ const script = document.createElement("script");
100
+ script.type = "module";
101
+ script.src = blobUrl;
102
+ script.onload = () => resolve(script);
103
+ script.onerror = () => reject(new Error("Script failed to load"));
104
+ document.head.appendChild(script);
105
+ });
106
+ }
107
+ async getTokenFromScript() {
108
+ if (typeof window === "undefined" || typeof window.Deflect?.getToken !== "function") {
109
+ throw new Error("Script did not load properly - getToken not available");
110
+ }
111
+ try {
112
+ return await window.Deflect.getToken();
113
+ } catch (error) {
114
+ throw new Error(`Script execution failed: ${error}`);
115
+ }
141
116
  }
142
117
  cleanup(blobUrl, scriptElement) {
143
- var _a;
144
- URL.revokeObjectURL(blobUrl);
145
- scriptElement.remove();
146
- if (typeof window !== "undefined" && ((_a = window.Deflect) === null || _a === void 0 ? void 0 : _a.getToken)) {
147
- delete window.Deflect.getToken;
148
- }
118
+ URL.revokeObjectURL(blobUrl);
119
+ scriptElement.remove();
120
+ if (typeof window !== "undefined" && window.Deflect?.getToken) {
121
+ delete window.Deflect.getToken;
122
+ }
149
123
  }
150
124
  configure(params) {
151
- var _a;
152
- if (!((_a = params.actionId) === null || _a === void 0 ? void 0 : _a.trim())) {
153
- throw new Error("actionId is required and cannot be empty");
154
- }
155
- this.config = Object.assign({}, params);
156
- if (typeof window !== "undefined") {
157
- window.Deflect.actionId = params.actionId;
158
- }
159
- this.tryWarmup();
125
+ if (!params.actionId?.trim()) {
126
+ throw new Error("actionId is required and cannot be empty");
127
+ }
128
+ this.config = { ...params };
129
+ if (typeof window !== "undefined") {
130
+ window.Deflect.actionId = params.actionId;
131
+ }
132
+ this.tryWarmup();
160
133
  }
161
134
  // Deprecated name kept for backward compatibility
162
- solveChallenge() {
163
- return __awaiter(this, void 0, void 0, function* () {
164
- return this.getToken();
165
- });
166
- }
167
- getToken() {
168
- return __awaiter(this, void 0, void 0, function* () {
169
- var _a;
170
- if (!((_a = this.config) === null || _a === void 0 ? void 0 : _a.actionId)) {
171
- throw new Error("Must call configure() before solveChallenge()");
172
- }
173
- let script;
174
- if (this.scriptCache && !this.isWarmupInProgress) {
175
- script = this.scriptCache;
176
- this.scriptCache = null;
177
- }
178
- else {
179
- script = yield this.fetchScript();
180
- }
181
- return this.executeScript(script);
182
- });
183
- }
184
- warmup() {
185
- return __awaiter(this, void 0, void 0, function* () {
186
- var _a;
187
- if (!((_a = this.config) === null || _a === void 0 ? void 0 : _a.actionId)) {
188
- return false;
189
- }
190
- try {
191
- yield this.tryWarmup();
192
- return this.scriptCache !== null;
193
- }
194
- catch (_b) {
195
- return false;
196
- }
197
- });
135
+ async solveChallenge() {
136
+ return this.getToken();
137
+ }
138
+ async getToken() {
139
+ if (!this.config?.actionId) {
140
+ throw new Error("Must call configure() before solveChallenge()");
141
+ }
142
+ let script;
143
+ if (this.scriptCache && !this.isWarmupInProgress) {
144
+ script = this.scriptCache;
145
+ this.scriptCache = null;
146
+ } else {
147
+ script = await this.fetchScript();
148
+ }
149
+ return this.executeScript(script);
150
+ }
151
+ async warmup() {
152
+ if (!this.config?.actionId) {
153
+ return false;
154
+ }
155
+ try {
156
+ await this.tryWarmup();
157
+ return this.scriptCache !== null;
158
+ } catch {
159
+ return false;
160
+ }
198
161
  }
199
162
  clearCache() {
200
- this.scriptCache = null;
163
+ this.scriptCache = null;
201
164
  }
202
165
  /**
203
166
  * Inject a fresh token as a hidden input into a form. Only accepts a submit event from onsubmit.
204
167
  * Usage: <form ... onsubmit="return Deflect.injectToken(event)">
205
168
  * Returns false to prevent double submit.
206
169
  */
207
- injectToken(event) {
208
- return __awaiter(this, void 0, void 0, function* () {
209
- if (!event || !event.target || !(event.target instanceof HTMLFormElement)) {
210
- throw new Error("injectToken: must be called from a form submit event");
211
- }
212
- event.preventDefault();
213
- const form = event.target;
214
- const token = yield this.getToken();
215
- Array.from(form.querySelectorAll('input[name="deflect_token"]')).forEach((el) => el.remove());
216
- const hidden = document.createElement("input");
217
- hidden.type = "hidden";
218
- hidden.name = "deflect_token";
219
- hidden.value = token;
220
- form.appendChild(hidden);
221
- form.submit();
222
- return false;
223
- });
224
- }
225
- }
226
- export default new Deflect();
170
+ async injectToken(event) {
171
+ if (!event || !event.target || !(event.target instanceof HTMLFormElement)) {
172
+ throw new Error("injectToken: must be called from a form submit event");
173
+ }
174
+ event.preventDefault();
175
+ const form = event.target;
176
+ const token = await this.getToken();
177
+ Array.from(form.querySelectorAll('input[name="deflect_token"]')).forEach(
178
+ (el) => el.remove()
179
+ );
180
+ const hidden = document.createElement("input");
181
+ hidden.type = "hidden";
182
+ hidden.name = "deflect_token";
183
+ hidden.value = token;
184
+ form.appendChild(hidden);
185
+ form.submit();
186
+ return false;
187
+ }
188
+ };
189
+ var DeflectInstance = new Deflect();
190
+ if (typeof window !== "undefined") {
191
+ window.Deflect = DeflectInstance;
192
+ }
193
+ var src_default = DeflectInstance;
194
+ })();
@@ -0,0 +1 @@
1
+ "use strict";(()=>{var o=class{constructor(){this.config=null;this.scriptCache=null;this.isWarmupInProgress=!1;this.initializeGlobalState(),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))}async tryWarmup(){if(!(!this.config?.actionId||this.isWarmupInProgress||this.scriptCache)){this.isWarmupInProgress=!0;try{this.scriptCache=await this.fetchScript()}catch{}finally{this.isWarmupInProgress=!1}}}buildScriptUrl(e){let t=this.config?.scriptUrl||"https://js.deflect.bot/main.js",r=Date.now().toString();return`${t}?action_id=${e}&_=${r}`}async fetchScript(){if(!this.config?.actionId)throw new Error("actionId is required");let e=this.buildScriptUrl(this.config.actionId),t=await fetch(e,{cache:"no-store"});if(!t.ok)throw new Error(`Failed to fetch script: ${t.status}`);return{content:await t.text(),sessionId:t.headers.get("session_id")||void 0}}async executeScript(e){e.sessionId&&typeof window<"u"&&(window.Deflect.sessionId=e.sessionId);let t=this.createReadyPromise(),r=this.createScriptBlob(e.content),i=await this.loadScriptElement(r);try{await t;let n=await this.getTokenFromScript();return this.prefetchNextScript(),n}finally{this.cleanup(r,i)}}prefetchNextScript(){this.tryWarmup().catch(()=>{})}createReadyPromise(){return new Promise(e=>{typeof window<"u"&&(window.Deflect.ready={promise:new Promise(t=>{window.Deflect.ready.resolve=t}),resolve:()=>e()})})}createScriptBlob(e){let t=new Blob([e],{type:"text/javascript"});return URL.createObjectURL(t)}async loadScriptElement(e){return new Promise((t,r)=>{let i=document.createElement("script");i.type="module",i.src=e,i.onload=()=>t(i),i.onerror=()=>r(new Error("Script failed to load")),document.head.appendChild(i)})}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){if(!e.actionId?.trim())throw new Error("actionId is required and cannot be empty");this.config={...e},typeof window<"u"&&(window.Deflect.actionId=e.actionId),this.tryWarmup()}async solveChallenge(){return this.getToken()}async getToken(){if(!this.config?.actionId)throw new Error("Must call configure() before solveChallenge()");let e;return this.scriptCache&&!this.isWarmupInProgress?(e=this.scriptCache,this.scriptCache=null):e=await this.fetchScript(),this.executeScript(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,r=await this.getToken();Array.from(t.querySelectorAll('input[name="deflect_token"]')).forEach(n=>n.remove());let i=document.createElement("input");return i.type="hidden",i.name="deflect_token",i.value=r,t.appendChild(i),t.submit(),!1}},c=new o;typeof window<"u"&&(window.Deflect=c);var a=c;})();
package/package.json CHANGED
@@ -1,12 +1,15 @@
1
1
  {
2
2
  "name": "@deflectbot/deflect-sdk",
3
- "version": "1.3.0",
3
+ "version": "1.3.2",
4
4
  "description": "SDK for deflect.bot - Use it for seamless captcha integration on any website.",
5
- "main": "dist/index.js",
6
- "types": "dist/types/index.d.ts",
5
+ "main": "dist/index.min.js",
6
+ "unpkg": "dist/index.min.js",
7
+ "jsdelivr": "dist/index.min.js",
8
+ "files": [
9
+ "dist/**/*"
10
+ ],
7
11
  "scripts": {
8
- "build": "tsc && npm run build:global",
9
- "build:global": "esbuild src/global.ts --bundle --format=iife --global-name=Deflect --minify --outfile=dist/deflect.global.min.js"
12
+ "build": "esbuild src/index.ts --bundle --format=iife --outfile=dist/index.js --keep-names && esbuild src/index.ts --bundle --format=iife --minify --outfile=dist/index.min.js"
10
13
  },
11
14
  "author": "Deflect",
12
15
  "license": "MIT",
@@ -20,6 +23,5 @@
20
23
  },
21
24
  "publishConfig": {
22
25
  "access": "public"
23
- },
24
- "dependencies": {}
26
+ }
25
27
  }
package/.gitattributes DELETED
@@ -1,2 +0,0 @@
1
- # Auto detect text files and perform LF normalization
2
- * text=auto
@@ -1 +0,0 @@
1
- "use strict";var Deflect=(()=>{var c=Object.defineProperty;var l=Object.getOwnPropertyDescriptor;var d=Object.getOwnPropertyNames;var p=Object.prototype.hasOwnProperty;var f=(n,e)=>{for(var t in e)c(n,t,{get:e[t],enumerable:!0})},u=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of d(e))!p.call(n,i)&&i!==t&&c(n,i,{get:()=>e[i],enumerable:!(r=l(e,i))||r.enumerable});return n};var h=n=>u(c({},"__esModule",{value:!0}),n);var m={};f(m,{default:()=>w});var s=class{constructor(){this.config=null;this.scriptCache=null;this.isWarmupInProgress=!1;this.initializeGlobalState(),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))}async tryWarmup(){if(!(!this.config?.actionId||this.isWarmupInProgress||this.scriptCache)){this.isWarmupInProgress=!0;try{this.scriptCache=await this.fetchScript()}catch{}finally{this.isWarmupInProgress=!1}}}buildScriptUrl(e){let t=this.config?.scriptUrl||"https://js.deflect.bot/main.js";if(this.config?.scriptUrl)return t;let r=Date.now().toString();return`${t}?action_id=${e}&_=${r}`}async fetchScript(){if(!this.config?.actionId)throw new Error("actionId is required");let e=this.buildScriptUrl(this.config.actionId),t=await fetch(e,{cache:"no-store"});if(!t.ok)throw new Error(`Failed to fetch script: ${t.status}`);return{content:await t.text(),sessionId:t.headers.get("session_id")||void 0}}async executeScript(e){e.sessionId&&typeof window<"u"&&(window.Deflect.sessionId=e.sessionId);let t=this.createReadyPromise(),r=this.createScriptBlob(e.content),i=await this.loadScriptElement(r);try{await t;let o=await this.getTokenFromScript();return this.prefetchNextScript(),o}finally{this.cleanup(r,i)}}prefetchNextScript(){this.tryWarmup().catch(()=>{})}createReadyPromise(){return new Promise(e=>{typeof window<"u"&&(window.Deflect.ready={promise:new Promise(t=>{window.Deflect.ready.resolve=t}),resolve:()=>e()})})}createScriptBlob(e){let t=new Blob([e],{type:"text/javascript"});return URL.createObjectURL(t)}async loadScriptElement(e){return new Promise((t,r)=>{let i=document.createElement("script");i.type="module",i.src=e,i.onload=()=>t(i),i.onerror=()=>r(new Error("Script failed to load")),document.head.appendChild(i)})}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){if(!e.actionId?.trim())throw new Error("actionId is required and cannot be empty");this.config={...e},typeof window<"u"&&(window.Deflect.actionId=e.actionId),this.tryWarmup()}async solveChallenge(){return this.getToken()}async getToken(){if(!this.config?.actionId)throw new Error("Must call configure() before solveChallenge()");let e;return this.scriptCache&&!this.isWarmupInProgress?(e=this.scriptCache,this.scriptCache=null):e=await this.fetchScript(),this.executeScript(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,r=await this.getToken();Array.from(t.querySelectorAll('input[name="deflect_token"]')).forEach(o=>o.remove());let i=document.createElement("input");return i.type="hidden",i.name="deflect_token",i.value=r,t.appendChild(i),t.submit(),!1}},a=new s;typeof window<"u"&&(window.Deflect=a);var w=a;return h(m);})();
package/dist/global.js DELETED
@@ -1,7 +0,0 @@
1
- // Re-export the default instance while also assigning it to window.Deflect for non-module usage.
2
- import DeflectInstance from "./index";
3
- if (typeof window !== "undefined") {
4
- // Avoid overwriting if a user already attached something custom.
5
- window.Deflect = DeflectInstance;
6
- }
7
- export default DeflectInstance;
@@ -1,7 +0,0 @@
1
- import DeflectInstance from "./index";
2
- declare global {
3
- interface Window {
4
- Deflect: any;
5
- }
6
- }
7
- export default DeflectInstance;
@@ -1,35 +0,0 @@
1
- interface DeflectConfig {
2
- actionId: string;
3
- scriptUrl?: string;
4
- }
5
- declare class Deflect {
6
- private config;
7
- private scriptCache;
8
- private isWarmupInProgress;
9
- constructor();
10
- private initializeGlobalState;
11
- private setupAutomaticWarmup;
12
- private tryWarmup;
13
- private buildScriptUrl;
14
- private fetchScript;
15
- private executeScript;
16
- private prefetchNextScript;
17
- private createReadyPromise;
18
- private createScriptBlob;
19
- private loadScriptElement;
20
- private getTokenFromScript;
21
- private cleanup;
22
- configure(params: DeflectConfig): void;
23
- solveChallenge(): Promise<string>;
24
- getToken(): Promise<string>;
25
- warmup(): Promise<boolean>;
26
- clearCache(): void;
27
- /**
28
- * Inject a fresh token as a hidden input into a form. Only accepts a submit event from onsubmit.
29
- * Usage: <form ... onsubmit="return Deflect.injectToken(event)">
30
- * Returns false to prevent double submit.
31
- */
32
- injectToken(event: SubmitEvent): Promise<false>;
33
- }
34
- declare const _default: Deflect;
35
- export default _default;
package/eslint.config.mjs DELETED
@@ -1,12 +0,0 @@
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/src/global.ts DELETED
@@ -1,18 +0,0 @@
1
- // Re-export the default instance while also assigning it to window.Deflect for non-module usage.
2
- import DeflectInstance from "./index";
3
-
4
- // Ensure side effects (constructor) already ran on import.
5
- // Attach to window for classic script tag usage.
6
- declare global {
7
- interface Window {
8
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- SDK attaches dynamic shape at runtime
9
- Deflect: any;
10
- }
11
- }
12
-
13
- if (typeof window !== "undefined") {
14
- // Avoid overwriting if a user already attached something custom.
15
- window.Deflect = DeflectInstance;
16
- }
17
-
18
- export default DeflectInstance;
package/src/index.ts DELETED
@@ -1,238 +0,0 @@
1
- interface DeflectConfig {
2
- actionId: string;
3
- scriptUrl?: string;
4
- }
5
-
6
- interface DeflectScript {
7
- sessionId?: string;
8
- content: string;
9
- }
10
-
11
- class Deflect {
12
- private config: DeflectConfig | null = null;
13
- private scriptCache: DeflectScript | null = null;
14
- private isWarmupInProgress = false;
15
-
16
- constructor() {
17
- this.initializeGlobalState();
18
- this.setupAutomaticWarmup();
19
- }
20
-
21
- private initializeGlobalState(): void {
22
- if (typeof window === "undefined") return;
23
- window.Deflect = window.Deflect || {};
24
- }
25
-
26
- private setupAutomaticWarmup(): void {
27
- if (typeof window === "undefined") return;
28
-
29
- if (document.readyState === "loading") {
30
- document.addEventListener("DOMContentLoaded", () => this.tryWarmup());
31
- } else {
32
- setTimeout(() => this.tryWarmup(), 100);
33
- }
34
- }
35
-
36
- private async tryWarmup(): Promise<void> {
37
- if (!this.config?.actionId || this.isWarmupInProgress || this.scriptCache) {
38
- return;
39
- }
40
-
41
- this.isWarmupInProgress = true;
42
-
43
- try {
44
- this.scriptCache = await this.fetchScript();
45
- } catch {
46
- /* empty */
47
- } finally {
48
- this.isWarmupInProgress = false;
49
- }
50
- }
51
-
52
- private buildScriptUrl(actionId: string): string {
53
- const baseUrl = this.config?.scriptUrl || "https://js.deflect.bot/main.js";
54
-
55
- if (this.config?.scriptUrl) {
56
- return baseUrl;
57
- }
58
-
59
- const nonce = Date.now().toString();
60
- return `${baseUrl}?action_id=${actionId}&_=${nonce}`;
61
- }
62
-
63
- private async fetchScript(): Promise<DeflectScript> {
64
- if (!this.config?.actionId) {
65
- throw new Error("actionId is required");
66
- }
67
-
68
- const url = this.buildScriptUrl(this.config.actionId);
69
- const response = await fetch(url, { cache: "no-store" });
70
-
71
- if (!response.ok) {
72
- throw new Error(`Failed to fetch script: ${response.status}`);
73
- }
74
-
75
- return {
76
- content: await response.text(),
77
- sessionId: response.headers.get("session_id") || undefined,
78
- };
79
- }
80
-
81
- private async executeScript(script: DeflectScript): Promise<string> {
82
- if (script.sessionId && typeof window !== "undefined") {
83
- window.Deflect.sessionId = script.sessionId;
84
- }
85
-
86
- const readyPromise = this.createReadyPromise();
87
-
88
- const blobUrl = this.createScriptBlob(script.content);
89
- const scriptElement = await this.loadScriptElement(blobUrl);
90
-
91
- try {
92
- await readyPromise;
93
-
94
- const token = await this.getTokenFromScript();
95
-
96
- this.prefetchNextScript();
97
-
98
- return token;
99
- } finally {
100
- this.cleanup(blobUrl, scriptElement);
101
- }
102
- }
103
-
104
- private prefetchNextScript(): void {
105
- this.tryWarmup().catch(() => {});
106
- }
107
-
108
- private createReadyPromise(): Promise<void> {
109
- return new Promise<void>((resolve) => {
110
- if (typeof window !== "undefined") {
111
- window.Deflect.ready = {
112
- promise: new Promise<void>((innerResolve) => {
113
- window.Deflect.ready.resolve = innerResolve;
114
- }),
115
- resolve: () => resolve(),
116
- };
117
- }
118
- });
119
- }
120
-
121
- private createScriptBlob(content: string): string {
122
- const blob = new Blob([content], { type: "text/javascript" });
123
- return URL.createObjectURL(blob);
124
- }
125
-
126
- private async loadScriptElement(blobUrl: string): Promise<HTMLScriptElement> {
127
- return new Promise((resolve, reject) => {
128
- const script = document.createElement("script");
129
- script.type = "module";
130
- script.src = blobUrl;
131
-
132
- script.onload = () => resolve(script);
133
- script.onerror = () => reject(new Error("Script failed to load"));
134
-
135
- document.head.appendChild(script);
136
- });
137
- }
138
-
139
- private async getTokenFromScript(): Promise<string> {
140
- if (
141
- typeof window === "undefined" ||
142
- typeof window.Deflect?.getToken !== "function"
143
- ) {
144
- throw new Error("Script did not load properly - getToken not available");
145
- }
146
-
147
- try {
148
- return await window.Deflect.getToken();
149
- } catch (error) {
150
- throw new Error(`Script execution failed: ${error}`);
151
- }
152
- }
153
-
154
- private cleanup(blobUrl: string, scriptElement: HTMLScriptElement): void {
155
- URL.revokeObjectURL(blobUrl);
156
- scriptElement.remove();
157
-
158
- if (typeof window !== "undefined" && window.Deflect?.getToken) {
159
- delete window.Deflect.getToken;
160
- }
161
- }
162
-
163
- public configure(params: DeflectConfig): void {
164
- if (!params.actionId?.trim()) {
165
- throw new Error("actionId is required and cannot be empty");
166
- }
167
- this.config = { ...params };
168
- if (typeof window !== "undefined") {
169
- window.Deflect.actionId = params.actionId;
170
- }
171
- this.tryWarmup();
172
- }
173
-
174
- // Deprecated name kept for backward compatibility
175
- public async solveChallenge(): Promise<string> {
176
- return this.getToken();
177
- }
178
-
179
- public async getToken(): Promise<string> {
180
- if (!this.config?.actionId) {
181
- throw new Error("Must call configure() before solveChallenge()");
182
- }
183
-
184
- let script: DeflectScript;
185
-
186
- if (this.scriptCache && !this.isWarmupInProgress) {
187
- script = this.scriptCache;
188
- this.scriptCache = null;
189
- } else {
190
- script = await this.fetchScript();
191
- }
192
-
193
- return this.executeScript(script);
194
- }
195
-
196
- public async warmup(): Promise<boolean> {
197
- if (!this.config?.actionId) {
198
- return false;
199
- }
200
-
201
- try {
202
- await this.tryWarmup();
203
- return this.scriptCache !== null;
204
- } catch {
205
- return false;
206
- }
207
- }
208
-
209
- public clearCache(): void {
210
- this.scriptCache = null;
211
- }
212
-
213
- /**
214
- * Inject a fresh token as a hidden input into a form. Only accepts a submit event from onsubmit.
215
- * Usage: <form ... onsubmit="return Deflect.injectToken(event)">
216
- * Returns false to prevent double submit.
217
- */
218
- public async injectToken(event: SubmitEvent): Promise<false> {
219
- if (!event || !event.target || !(event.target instanceof HTMLFormElement)) {
220
- throw new Error("injectToken: must be called from a form submit event");
221
- }
222
- event.preventDefault();
223
- const form = event.target;
224
- const token = await this.getToken();
225
- Array.from(form.querySelectorAll('input[name="deflect_token"]')).forEach(
226
- (el) => el.remove()
227
- );
228
- const hidden = document.createElement("input");
229
- hidden.type = "hidden";
230
- hidden.name = "deflect_token";
231
- hidden.value = token;
232
- form.appendChild(hidden);
233
- form.submit();
234
- return false;
235
- }
236
- }
237
-
238
- export default new Deflect();
@@ -1,6 +0,0 @@
1
- // Global window augmentation for Deflect SDK.
2
- // Using 'any' here keeps backward compatibility and avoids circular type issues.
3
- interface Window {
4
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- SDK attaches dynamic shape at runtime
5
- Deflect: any;
6
- }
package/tsconfig.json DELETED
@@ -1,22 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2015", // Set target to ES2015 or later
4
- "module": "ESNext", // Use ES module syntax
5
- "moduleResolution": "node", // Resolve modules like Node.js
6
- "strict": true, // Enable strict type-checking
7
- "declaration": true, // Enable generation of .d.ts files
8
- "declarationDir": "./dist/types", // Directory for .d.ts files
9
- "esModuleInterop": true, // Allow importing non-ESM modules
10
- "skipLibCheck": true, // Skip type checking of declaration files
11
- "outDir": "./dist", // Output directory for JavaScript files
12
- "lib": ["ES2015", "DOM"], // Add ES2015 and DOM libraries
13
- "jsx": "preserve" // For JSX compatibility in Vue
14
- },
15
- "include": [
16
- "src/**/*"
17
- ],
18
- "exclude": [
19
- "node_modules",
20
- "dist"
21
- ]
22
- }