@deflectbot/deflect-sdk 1.2.0 → 1.2.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,196 +1,108 @@
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 {
11
- constructor() {
12
- this.config = null;
13
- this.scriptCache = null;
14
- this.isWarmupInProgress = false;
15
- this.initializeGlobalState();
16
- this.setupAutomaticWarmup();
17
- }
18
- initializeGlobalState() {
19
- if (typeof window === "undefined")
20
- return;
21
- window.Deflect = window.Deflect || {};
22
- window.Deflect.extraArgs = window.Deflect.extraArgs || {};
23
- }
24
- setupAutomaticWarmup() {
25
- if (typeof window === "undefined")
26
- return;
27
- if (document.readyState === "loading") {
28
- document.addEventListener("DOMContentLoaded", () => this.tryWarmup());
29
- }
30
- else {
31
- setTimeout(() => this.tryWarmup(), 100);
32
- }
33
- }
34
- tryWarmup() {
35
- return __awaiter(this, void 0, void 0, function* () {
36
- var _a;
37
- if (!((_a = this.config) === null || _a === void 0 ? void 0 : _a.actionId) || this.isWarmupInProgress || this.scriptCache) {
38
- return;
39
- }
40
- this.isWarmupInProgress = true;
41
- try {
42
- this.scriptCache = yield this.fetchScript();
43
- }
44
- catch (_b) {
45
- }
46
- finally {
47
- this.isWarmupInProgress = false;
48
- }
49
- });
50
- }
51
- 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
- return token;
89
- }
90
- finally {
91
- this.cleanup(blobUrl, scriptElement);
92
- }
93
- });
94
- }
95
- createReadyPromise() {
96
- return new Promise((resolve) => {
97
- if (typeof window !== "undefined") {
98
- window.Deflect.ready = {
99
- promise: new Promise((innerResolve) => {
100
- window.Deflect.ready.resolve = innerResolve;
101
- }),
102
- resolve: () => resolve(),
103
- };
104
- }
105
- });
106
- }
107
- createScriptBlob(content) {
108
- const blob = new Blob([content], { type: "text/javascript" });
109
- return URL.createObjectURL(blob);
110
- }
111
- loadScriptElement(blobUrl) {
112
- return __awaiter(this, void 0, void 0, function* () {
113
- return new Promise((resolve, reject) => {
114
- const script = document.createElement("script");
115
- script.type = "module";
116
- script.src = blobUrl;
117
- script.onload = () => resolve(script);
118
- script.onerror = () => reject(new Error("Script failed to load"));
119
- document.head.appendChild(script);
120
- });
121
- });
122
- }
123
- getTokenFromScript() {
124
- return __awaiter(this, void 0, void 0, function* () {
125
- var _a;
126
- if (typeof window === "undefined" ||
127
- typeof ((_a = window.Deflect) === null || _a === void 0 ? void 0 : _a.getToken) !== "function") {
128
- throw new Error("Script did not load properly - getToken not available");
129
- }
130
- try {
131
- return yield window.Deflect.getToken();
132
- }
133
- catch (error) {
134
- throw new Error(`Script execution failed: ${error}`);
135
- }
136
- });
137
- }
138
- cleanup(blobUrl, scriptElement) {
139
- var _a;
140
- URL.revokeObjectURL(blobUrl);
141
- scriptElement.remove();
142
- if (typeof window !== "undefined" && ((_a = window.Deflect) === null || _a === void 0 ? void 0 : _a.getToken)) {
143
- delete window.Deflect.getToken;
144
- }
145
- }
146
- configure(params) {
147
- var _a;
148
- if (!((_a = params.actionId) === null || _a === void 0 ? void 0 : _a.trim())) {
149
- throw new Error("actionId is required and cannot be empty");
150
- }
151
- this.config = Object.assign({}, params);
152
- if (typeof window !== "undefined") {
153
- window.Deflect.actionId = params.actionId;
154
- if (params.extraArgs) {
155
- window.Deflect.extraArgs = Object.assign({}, params.extraArgs);
156
- }
157
- }
158
- this.tryWarmup();
159
- }
160
- solveChallenge() {
161
- return __awaiter(this, void 0, void 0, function* () {
162
- var _a;
163
- if (!((_a = this.config) === null || _a === void 0 ? void 0 : _a.actionId)) {
164
- throw new Error("Must call configure() before solveChallenge()");
165
- }
166
- let script;
167
- if (this.scriptCache && !this.isWarmupInProgress) {
168
- script = this.scriptCache;
169
- this.scriptCache = null;
170
- }
171
- else {
172
- script = yield this.fetchScript();
173
- }
174
- return this.executeScript(script);
175
- });
176
- }
177
- warmup() {
178
- return __awaiter(this, void 0, void 0, function* () {
179
- var _a;
180
- if (!((_a = this.config) === null || _a === void 0 ? void 0 : _a.actionId)) {
181
- return false;
182
- }
183
- try {
184
- yield this.tryWarmup();
185
- return this.scriptCache !== null;
186
- }
187
- catch (_b) {
188
- return false;
189
- }
190
- });
191
- }
192
- clearCache() {
193
- this.scriptCache = null;
194
- }
195
- }
196
- export default new Deflect();
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 {
11
+ constructor() {
12
+ this._prefetchedScriptText = null;
13
+ this._hasUsedPrefetch = false;
14
+ window.Deflect = window.Deflect || {};
15
+ window.Deflect.extraArgs = window.Deflect.extraArgs || {};
16
+ if (typeof window !== "undefined") {
17
+ window.addEventListener("load", () => {
18
+ setTimeout(() => {
19
+ this._warmupScript();
20
+ }, 500);
21
+ });
22
+ }
23
+ }
24
+ _warmupScript() {
25
+ if (!window.Deflect.actionId)
26
+ return;
27
+ const nonce = Date.now().toString();
28
+ const scriptUrl = `https://js.deflect.bot/main.js?action_id=${window.Deflect.actionId}&_=${nonce}`;
29
+ fetch(scriptUrl, { cache: "no-store" })
30
+ .then((res) => __awaiter(this, void 0, void 0, function* () {
31
+ if (!res.ok)
32
+ return;
33
+ this._prefetchedScriptText = yield res.text();
34
+ }))
35
+ .catch(() => { });
36
+ }
37
+ setupReady() {
38
+ let resolveFn;
39
+ const promise = new Promise((resolve) => {
40
+ resolveFn = resolve;
41
+ });
42
+ window.Deflect.ready = {
43
+ promise,
44
+ resolve: () => resolveFn(),
45
+ };
46
+ }
47
+ configure(params) {
48
+ if (!params.actionId) {
49
+ throw new Error("actionId is required in configuration");
50
+ }
51
+ window.Deflect.actionId = params.actionId;
52
+ }
53
+ solveChallenge() {
54
+ return __awaiter(this, void 0, void 0, function* () {
55
+ var _a;
56
+ if (!window.Deflect.actionId) {
57
+ throw new Error("actionId is missing in configuration");
58
+ }
59
+ this.setupReady();
60
+ let scriptText;
61
+ let sessionId = null;
62
+ if (this._prefetchedScriptText && !this._hasUsedPrefetch) {
63
+ scriptText = this._prefetchedScriptText;
64
+ this._hasUsedPrefetch = true;
65
+ }
66
+ else {
67
+ const nonce = Date.now().toString();
68
+ const scriptUrl = `https://js.deflect.bot/main.js?action_id=${window.Deflect.actionId}&_=${nonce}`;
69
+ const response = yield fetch(scriptUrl, { cache: "no-store" });
70
+ if (!response.ok) {
71
+ throw new Error("Failed to fetch the Deflect script");
72
+ }
73
+ sessionId = response.headers.get("session_id");
74
+ scriptText = yield response.text();
75
+ }
76
+ if (sessionId) {
77
+ window.Deflect.sessionId = sessionId;
78
+ }
79
+ const blob = new Blob([scriptText], { type: "text/javascript" });
80
+ const blobUrl = URL.createObjectURL(blob);
81
+ const scriptEl = document.createElement("script");
82
+ scriptEl.type = "module";
83
+ scriptEl.src = blobUrl;
84
+ document.head.appendChild(scriptEl);
85
+ yield new Promise((resolve, reject) => {
86
+ scriptEl.onload = () => resolve();
87
+ scriptEl.onerror = () => reject("Failed to load the Deflect script");
88
+ });
89
+ yield ((_a = window.Deflect.ready) === null || _a === void 0 ? void 0 : _a.promise);
90
+ if (typeof window.Deflect === "undefined" ||
91
+ typeof window.Deflect.getToken !== "function") {
92
+ throw new Error("Deflect script did not load properly");
93
+ }
94
+ let token;
95
+ try {
96
+ token = yield window.Deflect.getToken();
97
+ }
98
+ catch (error) {
99
+ throw new Error(`Deflect script execution failed: ${error}`);
100
+ }
101
+ URL.revokeObjectURL(blobUrl);
102
+ scriptEl.remove();
103
+ delete window.Deflect.getToken;
104
+ return token;
105
+ });
106
+ }
107
+ }
108
+ export default new Deflect();
@@ -1,28 +1,17 @@
1
- interface DeflectConfig {
2
- actionId: string;
3
- scriptUrl?: string;
4
- extraArgs?: Record<string, string>;
5
- }
6
- declare class Deflect {
7
- private config;
8
- private scriptCache;
9
- private isWarmupInProgress;
10
- constructor();
11
- private initializeGlobalState;
12
- private setupAutomaticWarmup;
13
- private tryWarmup;
14
- private buildScriptUrl;
15
- private fetchScript;
16
- private executeScript;
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
- warmup(): Promise<boolean>;
25
- clearCache(): void;
26
- }
27
- declare const _default: Deflect;
28
- export default _default;
1
+ interface DeflectConfig {
2
+ actionId: string;
3
+ extraArgs?: {
4
+ [key: string]: string;
5
+ };
6
+ }
7
+ declare class Deflect {
8
+ private _prefetchedScriptText;
9
+ private _hasUsedPrefetch;
10
+ constructor();
11
+ private _warmupScript;
12
+ private setupReady;
13
+ configure(params: DeflectConfig): void;
14
+ solveChallenge(): Promise<string>;
15
+ }
16
+ declare const _default: Deflect;
17
+ export default _default;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deflectbot/deflect-sdk",
3
- "version": "1.2.0",
3
+ "version": "1.2.2",
4
4
  "description": "SDK for deflect.bot - Use it for seamless captcha integration on any website.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/types/index.d.ts",
package/src/index.ts CHANGED
@@ -1,210 +1,147 @@
1
1
  interface DeflectConfig {
2
2
  actionId: string;
3
3
  scriptUrl?: string;
4
- extraArgs?: Record<string, string>;
5
- }
6
-
7
- interface DeflectScript {
8
- sessionId?: string;
9
- content: string;
4
+ extraArgs?: { [key: string]: string };
10
5
  }
11
6
 
12
7
  class Deflect {
13
- private config: DeflectConfig | null = null;
14
- private scriptCache: DeflectScript | null = null;
15
- private isWarmupInProgress = false;
8
+ private _prefetchedScriptText: string | null = null;
9
+ private _hasUsedPrefetch = false;
10
+ private _customScriptUrl: string | null = null;
16
11
 
17
12
  constructor() {
18
- this.initializeGlobalState();
19
- this.setupAutomaticWarmup();
20
- }
21
-
22
- private initializeGlobalState(): void {
23
- if (typeof window === "undefined") return;
24
-
25
13
  window.Deflect = window.Deflect || {};
26
14
  window.Deflect.extraArgs = window.Deflect.extraArgs || {};
27
- }
28
15
 
29
- private setupAutomaticWarmup(): void {
30
- if (typeof window === "undefined") return;
31
-
32
- if (document.readyState === "loading") {
33
- document.addEventListener("DOMContentLoaded", () => this.tryWarmup());
34
- } else {
35
- setTimeout(() => this.tryWarmup(), 100);
16
+ if (typeof window !== "undefined") {
17
+ window.addEventListener("load", () => {
18
+ setTimeout(() => {
19
+ this._warmupScript();
20
+ }, 500);
21
+ });
36
22
  }
37
23
  }
38
24
 
39
- private async tryWarmup(): Promise<void> {
40
- if (!this.config?.actionId || this.isWarmupInProgress || this.scriptCache) {
41
- return;
25
+ private _getScriptUrl(): string {
26
+ const nonce = Date.now().toString();
27
+ if (this._customScriptUrl) {
28
+ const separator = this._customScriptUrl.includes("?") ? "&" : "?";
29
+ return `${this._customScriptUrl}${separator}action_id=${window.Deflect.actionId}&_=${nonce}`;
42
30
  }
31
+ return `https://js.deflect.bot/main.js?action_id=${window.Deflect.actionId}&_=${nonce}`;
32
+ }
43
33
 
44
- this.isWarmupInProgress = true;
34
+ private _warmupScript(): void {
35
+ if (!window.Deflect.actionId) return;
45
36
 
46
- try {
47
- this.scriptCache = await this.fetchScript();
48
- } catch {
49
- } finally {
50
- this.isWarmupInProgress = false;
51
- }
37
+ const scriptUrl = this._getScriptUrl();
38
+ fetch(scriptUrl, { cache: "no-store" })
39
+ .then(async (res) => {
40
+ if (!res.ok) return;
41
+ this._prefetchedScriptText = await res.text();
42
+ })
43
+ .catch(() => {});
52
44
  }
53
45
 
54
- private buildScriptUrl(actionId: string): string {
55
- const baseUrl = this.config?.scriptUrl || "https://js.deflect.bot/main.js";
46
+ private _refetchScript(): void {
47
+ this._hasUsedPrefetch = false;
48
+ this._prefetchedScriptText = null;
56
49
 
57
- if (this.config?.scriptUrl) {
58
- return baseUrl;
59
- }
50
+ setTimeout(() => {
51
+ this._warmupScript();
52
+ }, 100);
53
+ }
60
54
 
61
- const nonce = Date.now().toString();
62
- return `${baseUrl}?action_id=${actionId}&_=${nonce}`;
55
+ private setupReady(): void {
56
+ let resolveFn: () => void;
57
+ const promise = new Promise<void>((resolve) => {
58
+ resolveFn = resolve;
59
+ });
60
+ window.Deflect.ready = {
61
+ promise,
62
+ resolve: () => resolveFn(),
63
+ };
63
64
  }
64
65
 
65
- private async fetchScript(): Promise<DeflectScript> {
66
- if (!this.config?.actionId) {
67
- throw new Error("actionId is required");
66
+ configure(params: DeflectConfig): void {
67
+ if (!params.actionId) {
68
+ throw new Error("actionId is required in configuration");
68
69
  }
70
+ window.Deflect.actionId = params.actionId;
69
71
 
70
- const url = this.buildScriptUrl(this.config.actionId);
71
- const response = await fetch(url, { cache: "no-store" });
72
-
73
- if (!response.ok) {
74
- throw new Error(`Failed to fetch script: ${response.status}`);
72
+ if (params.scriptUrl) {
73
+ this._customScriptUrl = params.scriptUrl;
75
74
  }
76
-
77
- return {
78
- content: await response.text(),
79
- sessionId: response.headers.get("session_id") || undefined,
80
- };
81
75
  }
82
76
 
83
- private async executeScript(script: DeflectScript): Promise<string> {
84
- if (script.sessionId && typeof window !== "undefined") {
85
- window.Deflect.sessionId = script.sessionId;
77
+ async solveChallenge(): Promise<string> {
78
+ if (!window.Deflect.actionId) {
79
+ throw new Error("actionId is missing in configuration");
86
80
  }
87
81
 
88
- const readyPromise = this.createReadyPromise();
82
+ this.setupReady();
89
83
 
90
- const blobUrl = this.createScriptBlob(script.content);
91
- const scriptElement = await this.loadScriptElement(blobUrl);
84
+ let scriptText: string;
85
+ let sessionId: string | null = null;
92
86
 
93
- try {
94
- await readyPromise;
87
+ if (this._prefetchedScriptText && !this._hasUsedPrefetch) {
88
+ scriptText = this._prefetchedScriptText;
89
+ this._hasUsedPrefetch = true;
90
+ } else {
91
+ const scriptUrl = this._getScriptUrl();
92
+ const response = await fetch(scriptUrl, { cache: "no-store" });
95
93
 
96
- const token = await this.getTokenFromScript();
94
+ if (!response.ok) {
95
+ throw new Error("Failed to fetch the Deflect script");
96
+ }
97
97
 
98
- return token;
99
- } finally {
100
- this.cleanup(blobUrl, scriptElement);
98
+ sessionId = response.headers.get("session_id");
99
+ scriptText = await response.text();
101
100
  }
102
- }
103
101
 
104
- private createReadyPromise(): Promise<void> {
105
- return new Promise<void>((resolve) => {
106
- if (typeof window !== "undefined") {
107
- window.Deflect.ready = {
108
- promise: new Promise<void>((innerResolve) => {
109
- window.Deflect.ready.resolve = innerResolve;
110
- }),
111
- resolve: () => resolve(),
112
- };
113
- }
114
- });
115
- }
102
+ if (sessionId) {
103
+ window.Deflect.sessionId = sessionId;
104
+ }
116
105
 
117
- private createScriptBlob(content: string): string {
118
- const blob = new Blob([content], { type: "text/javascript" });
119
- return URL.createObjectURL(blob);
120
- }
106
+ const blob = new Blob([scriptText], { type: "text/javascript" });
107
+ const blobUrl = URL.createObjectURL(blob);
121
108
 
122
- private async loadScriptElement(blobUrl: string): Promise<HTMLScriptElement> {
123
- return new Promise((resolve, reject) => {
124
- const script = document.createElement("script");
125
- script.type = "module";
126
- script.src = blobUrl;
109
+ const scriptEl = document.createElement("script");
110
+ scriptEl.type = "module";
111
+ scriptEl.src = blobUrl;
127
112
 
128
- script.onload = () => resolve(script);
129
- script.onerror = () => reject(new Error("Script failed to load"));
113
+ document.head.appendChild(scriptEl);
130
114
 
131
- document.head.appendChild(script);
115
+ await new Promise<void>((resolve, reject) => {
116
+ scriptEl.onload = () => resolve();
117
+ scriptEl.onerror = () => reject("Failed to load the Deflect script");
132
118
  });
133
- }
134
119
 
135
- private async getTokenFromScript(): Promise<string> {
120
+ await window.Deflect.ready?.promise;
121
+
136
122
  if (
137
- typeof window === "undefined" ||
138
- typeof window.Deflect?.getToken !== "function"
123
+ typeof window.Deflect === "undefined" ||
124
+ typeof window.Deflect.getToken !== "function"
139
125
  ) {
140
- throw new Error("Script did not load properly - getToken not available");
126
+ throw new Error("Deflect script did not load properly");
141
127
  }
142
128
 
129
+ let token: string;
130
+
143
131
  try {
144
- return await window.Deflect.getToken();
132
+ token = await window.Deflect.getToken();
145
133
  } catch (error) {
146
- throw new Error(`Script execution failed: ${error}`);
147
- }
148
- }
149
-
150
- private cleanup(blobUrl: string, scriptElement: HTMLScriptElement): void {
151
- URL.revokeObjectURL(blobUrl);
152
- scriptElement.remove();
153
-
154
- if (typeof window !== "undefined" && window.Deflect?.getToken) {
155
- delete window.Deflect.getToken;
156
- }
157
- }
158
-
159
- public configure(params: DeflectConfig): void {
160
- if (!params.actionId?.trim()) {
161
- throw new Error("actionId is required and cannot be empty");
162
- }
163
-
164
- this.config = { ...params };
165
-
166
- if (typeof window !== "undefined") {
167
- window.Deflect.actionId = params.actionId;
168
- if (params.extraArgs) {
169
- window.Deflect.extraArgs = { ...params.extraArgs };
170
- }
171
- }
172
-
173
- this.tryWarmup();
174
- }
175
-
176
- public async solveChallenge(): Promise<string> {
177
- if (!this.config?.actionId) {
178
- throw new Error("Must call configure() before solveChallenge()");
134
+ throw new Error(`Deflect script execution failed: ${error}`);
179
135
  }
180
136
 
181
- let script: DeflectScript;
182
-
183
- if (this.scriptCache && !this.isWarmupInProgress) {
184
- script = this.scriptCache;
185
- this.scriptCache = null;
186
- } else {
187
- script = await this.fetchScript();
188
- }
137
+ this._refetchScript();
189
138
 
190
- return this.executeScript(script);
191
- }
192
-
193
- public async warmup(): Promise<boolean> {
194
- if (!this.config?.actionId) {
195
- return false;
196
- }
139
+ URL.revokeObjectURL(blobUrl);
140
+ scriptEl.remove();
197
141
 
198
- try {
199
- await this.tryWarmup();
200
- return this.scriptCache !== null;
201
- } catch {
202
- return false;
203
- }
204
- }
142
+ delete window.Deflect.getToken;
205
143
 
206
- public clearCache(): void {
207
- this.scriptCache = null;
144
+ return token;
208
145
  }
209
146
  }
210
147