@omnizapi/connect 1.0.1 → 1.0.3
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/CHANGELOG.md +43 -0
- package/LICENSE +21 -0
- package/README.md +76 -30
- package/dist/cjs/index.js +324 -120
- package/dist/esm/index.mjs +324 -120
- package/dist/omnizapi.min.js +1 -1
- package/dist/types/src/core/client.d.ts +1 -1
- package/dist/types/src/core/facebook-sdk.d.ts +11 -0
- package/dist/types/src/core/runtime.d.ts +16 -0
- package/dist/types/src/types/index.d.ts +3 -2
- package/examples/angular.ts +5 -3
- package/examples/basic.ts +5 -3
- package/examples/error-handling.ts +29 -11
- package/examples/react.tsx +23 -10
- package/examples/vanilla.html +3 -3
- package/examples/vue.vue +5 -3
- package/examples/with-options.ts +16 -10
- package/package.json +11 -3
package/dist/esm/index.mjs
CHANGED
|
@@ -65,12 +65,22 @@ var getConstants = ({
|
|
|
65
65
|
// src/core/runtime.ts
|
|
66
66
|
var runtimeKey = /* @__PURE__ */ Symbol.for("omnizapi.connect.runtime.v1");
|
|
67
67
|
function getRuntime(host) {
|
|
68
|
+
var _a, _b, _c;
|
|
68
69
|
const target = host;
|
|
69
70
|
let runtime = target[runtimeKey];
|
|
70
71
|
if (!runtime) {
|
|
71
|
-
runtime = {
|
|
72
|
+
runtime = {
|
|
73
|
+
nativeLoginPending: false,
|
|
74
|
+
failedFacebookScripts: /* @__PURE__ */ new WeakSet(),
|
|
75
|
+
erroredFacebookScripts: /* @__PURE__ */ new WeakSet(),
|
|
76
|
+
facebookAppIds: /* @__PURE__ */ new WeakMap(),
|
|
77
|
+
facebookInitObservers: /* @__PURE__ */ new WeakMap()
|
|
78
|
+
};
|
|
72
79
|
Object.defineProperty(target, runtimeKey, { configurable: true, value: runtime });
|
|
73
80
|
}
|
|
81
|
+
(_a = runtime.facebookAppIds) != null ? _a : runtime.facebookAppIds = /* @__PURE__ */ new WeakMap();
|
|
82
|
+
(_b = runtime.facebookInitObservers) != null ? _b : runtime.facebookInitObservers = /* @__PURE__ */ new WeakMap();
|
|
83
|
+
(_c = runtime.erroredFacebookScripts) != null ? _c : runtime.erroredFacebookScripts = /* @__PURE__ */ new WeakSet();
|
|
74
84
|
return runtime;
|
|
75
85
|
}
|
|
76
86
|
|
|
@@ -78,108 +88,238 @@ function getRuntime(host) {
|
|
|
78
88
|
function isReadySdk(sdk) {
|
|
79
89
|
return !!sdk && !("__buffer" in sdk) && typeof sdk.init === "function" && typeof sdk.login === "function";
|
|
80
90
|
}
|
|
91
|
+
function observeFacebookInit(runtime, fb) {
|
|
92
|
+
var _a;
|
|
93
|
+
try {
|
|
94
|
+
const descriptor = Object.getOwnPropertyDescriptor(fb, "init");
|
|
95
|
+
const existing = runtime.facebookInitObservers.get(fb);
|
|
96
|
+
if (existing) {
|
|
97
|
+
if ((descriptor == null ? void 0 : descriptor.value) !== existing.init) throw new Error("FB.init was replaced.");
|
|
98
|
+
return existing;
|
|
99
|
+
}
|
|
100
|
+
if (!descriptor || typeof descriptor.value !== "function" || !descriptor.writable && !descriptor.configurable) {
|
|
101
|
+
throw new Error("FB.init cannot be observed.");
|
|
102
|
+
}
|
|
103
|
+
const original = descriptor.value;
|
|
104
|
+
const observer = {
|
|
105
|
+
calls: 0,
|
|
106
|
+
init: function(...args) {
|
|
107
|
+
observer.calls++;
|
|
108
|
+
runtime.facebookAppIds.delete(fb);
|
|
109
|
+
return Reflect.apply(original, this, args);
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
Object.defineProperty(fb, "init", { ...descriptor, value: observer.init });
|
|
113
|
+
if (((_a = Object.getOwnPropertyDescriptor(fb, "init")) == null ? void 0 : _a.value) !== observer.init) throw new Error("FB.init was not replaced.");
|
|
114
|
+
runtime.facebookInitObservers.set(fb, observer);
|
|
115
|
+
return observer;
|
|
116
|
+
} catch (e) {
|
|
117
|
+
runtime.facebookAppIds.delete(fb);
|
|
118
|
+
throw new OmnizapiError(
|
|
119
|
+
"INVALID_CONFIGURATION",
|
|
120
|
+
"The Meta SDK initialization cannot be observed safely. Use the popup flow or reload a fresh page."
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
function initializeFacebookSdk(host, fb, appId) {
|
|
125
|
+
var _a;
|
|
126
|
+
if (host.FB !== fb || !fb || "__buffer" in fb || typeof fb.login !== "function") {
|
|
127
|
+
throw new OmnizapiError("INVALID_CONFIGURATION", "The Meta SDK is not ready or was replaced before initialization.");
|
|
128
|
+
}
|
|
129
|
+
if (typeof appId !== "string" || !/^[0-9]+$/.test(appId)) {
|
|
130
|
+
throw new OmnizapiError("INVALID_CONFIGURATION", "A numeric Meta appId is required for native login.");
|
|
131
|
+
}
|
|
132
|
+
const runtime = getRuntime(host);
|
|
133
|
+
if (runtime.facebookAppIds.get(fb) === null && (runtime.facebookLoadUncertain || runtime.facebookLoading || typeof host.fbAsyncInit === "function")) {
|
|
134
|
+
runtime.facebookAppIds.delete(fb);
|
|
135
|
+
}
|
|
136
|
+
const initializedAppId = runtime.facebookAppIds.get(fb);
|
|
137
|
+
if (initializedAppId === void 0 || initializedAppId !== null && !runtime.facebookInitObservers.has(fb)) {
|
|
138
|
+
runtime.facebookAppIds.delete(fb);
|
|
139
|
+
throw new OmnizapiError(
|
|
140
|
+
"INVALID_CONFIGURATION",
|
|
141
|
+
"The host Meta SDK configuration is unknown. Use the popup flow or a fresh page without a host-initialized SDK for native login."
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
const observer = observeFacebookInit(runtime, fb);
|
|
145
|
+
if (initializedAppId !== null) {
|
|
146
|
+
if (initializedAppId !== appId) {
|
|
147
|
+
throw new OmnizapiError(
|
|
148
|
+
"INVALID_CONFIGURATION",
|
|
149
|
+
"The Meta SDK is already initialized for another app. Use the popup flow or reload a fresh page before changing apps."
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
const calls = observer.calls;
|
|
155
|
+
runtime.facebookAppIds.delete(fb);
|
|
156
|
+
try {
|
|
157
|
+
fb.init({ appId, version: "v25.0", autoLogAppEvents: true, xfbml: true });
|
|
158
|
+
} catch (e) {
|
|
159
|
+
throw new OmnizapiError("PROVIDER_ERROR", "The Meta SDK could not be initialized.");
|
|
160
|
+
}
|
|
161
|
+
if (observer.calls !== calls + 1 || host.FB !== fb || ((_a = Object.getOwnPropertyDescriptor(fb, "init")) == null ? void 0 : _a.value) !== observer.init) {
|
|
162
|
+
throw new OmnizapiError("INVALID_CONFIGURATION", "The Meta SDK changed during initialization. Use the popup flow or reload a fresh page.");
|
|
163
|
+
}
|
|
164
|
+
runtime.facebookAppIds.set(fb, appId);
|
|
165
|
+
}
|
|
81
166
|
function loadFacebookSdk(host, signal) {
|
|
82
167
|
if (signal.aborted) {
|
|
83
168
|
return Promise.reject(new OmnizapiError("SDK_LOAD_FAILED", "The Meta SDK load was cancelled."));
|
|
84
169
|
}
|
|
85
|
-
if (isReadySdk(host.FB)) {
|
|
86
|
-
return Promise.resolve(host.FB);
|
|
87
|
-
}
|
|
88
170
|
const runtime = getRuntime(host);
|
|
89
|
-
|
|
90
|
-
if (
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
171
|
+
let loading = runtime.facebookLoadObserver;
|
|
172
|
+
if (!loading && isReadySdk(host.FB)) {
|
|
173
|
+
loading = { promise: Promise.resolve(host.FB), consumers: 0 };
|
|
174
|
+
}
|
|
175
|
+
if (!loading) {
|
|
176
|
+
const shared2 = {
|
|
177
|
+
consumers: 0,
|
|
178
|
+
// Register the observer and its consumers before setup can fail synchronously.
|
|
179
|
+
promise: Promise.resolve().then(() => new Promise((resolve, reject) => {
|
|
180
|
+
var _a;
|
|
181
|
+
let settled = false;
|
|
182
|
+
let script;
|
|
183
|
+
let ownedScript = false;
|
|
184
|
+
let freshSdk = false;
|
|
185
|
+
let bootstrap;
|
|
186
|
+
let previous;
|
|
187
|
+
let previousCallback;
|
|
188
|
+
const finish = (sdk, error, definitiveFailure = false) => {
|
|
189
|
+
if (settled) return;
|
|
190
|
+
settled = true;
|
|
191
|
+
clearTimeout(timer);
|
|
192
|
+
script == null ? void 0 : script.removeEventListener("load", onLoad);
|
|
193
|
+
script == null ? void 0 : script.removeEventListener("error", onError);
|
|
194
|
+
try {
|
|
195
|
+
if (host.fbAsyncInit === onReady) {
|
|
196
|
+
if (previous) Object.defineProperty(host, "fbAsyncInit", previous);
|
|
197
|
+
else Reflect.deleteProperty(host, "fbAsyncInit");
|
|
198
|
+
}
|
|
199
|
+
} catch (e) {
|
|
200
|
+
}
|
|
201
|
+
if (error && script) {
|
|
202
|
+
runtime.failedFacebookScripts.add(script);
|
|
203
|
+
if (definitiveFailure) runtime.erroredFacebookScripts.add(script);
|
|
204
|
+
else if (!ownedScript) runtime.facebookLoadUncertain = true;
|
|
205
|
+
if (ownedScript) {
|
|
206
|
+
try {
|
|
207
|
+
script.remove();
|
|
208
|
+
} catch (e) {
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
if (runtime.facebookLoadObserver === shared2) delete runtime.facebookLoadObserver;
|
|
213
|
+
if (sdk) resolve(sdk);
|
|
214
|
+
else reject(error);
|
|
215
|
+
};
|
|
216
|
+
const onLoad = () => {
|
|
217
|
+
var _a2;
|
|
218
|
+
if (settled) return;
|
|
219
|
+
const sdk = host.FB;
|
|
220
|
+
if (!sdk) return;
|
|
221
|
+
if ("__buffer" in sdk) bootstrap = sdk;
|
|
222
|
+
if (((_a2 = bootstrap == null ? void 0 : bootstrap.__buffer) == null ? void 0 : _a2.opts) != null || host.fbAsyncInit !== onReady || (script == null ? void 0 : script.onload) || runtime.facebookLoading || runtime.facebookLoadUncertain) {
|
|
223
|
+
freshSdk = false;
|
|
224
|
+
if (runtime.facebookAppIds.get(sdk) === null) runtime.facebookAppIds.delete(sdk);
|
|
225
|
+
if (bootstrap && runtime.facebookAppIds.get(bootstrap) === null) runtime.facebookAppIds.delete(bootstrap);
|
|
226
|
+
}
|
|
227
|
+
const ready = isReadySdk(sdk);
|
|
228
|
+
if (freshSdk && runtime.facebookAppIds.get(sdk) == null) {
|
|
229
|
+
if (!ready) runtime.facebookAppIds.set(sdk, null);
|
|
230
|
+
else if (!runtime.facebookInitObservers.has(sdk)) {
|
|
231
|
+
try {
|
|
232
|
+
observeFacebookInit(runtime, sdk);
|
|
233
|
+
runtime.facebookAppIds.set(sdk, null);
|
|
234
|
+
} catch (e) {
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
if (ready) finish(sdk);
|
|
239
|
+
};
|
|
240
|
+
const onError = () => finish(void 0, new OmnizapiError("SDK_LOAD_FAILED", "The Meta SDK could not be loaded."), true);
|
|
241
|
+
const onReady = () => {
|
|
242
|
+
if (settled) return;
|
|
114
243
|
try {
|
|
115
|
-
|
|
244
|
+
previousCallback == null ? void 0 : previousCallback.call(host);
|
|
116
245
|
} catch (e) {
|
|
117
246
|
}
|
|
247
|
+
onLoad();
|
|
248
|
+
};
|
|
249
|
+
const timer = setTimeout(() => finish(void 0, new OmnizapiError(
|
|
250
|
+
"SDK_LOAD_FAILED",
|
|
251
|
+
"The Meta SDK load timed out."
|
|
252
|
+
)), 30 * 1e3);
|
|
253
|
+
shared2.cancelIfUnused = () => {
|
|
254
|
+
if (ownedScript && shared2.consumers === 0) {
|
|
255
|
+
finish(void 0, new OmnizapiError("SDK_LOAD_FAILED", "The Meta SDK load was cancelled."));
|
|
256
|
+
}
|
|
257
|
+
};
|
|
258
|
+
try {
|
|
259
|
+
previous = Object.getOwnPropertyDescriptor(host, "fbAsyncInit");
|
|
260
|
+
previousCallback = typeof host.fbAsyncInit === "function" ? host.fbAsyncInit : void 0;
|
|
261
|
+
const document = host.document;
|
|
262
|
+
const byId = document.getElementById("facebook-jssdk");
|
|
263
|
+
script = Array.from(document.scripts).find((candidate) => {
|
|
264
|
+
try {
|
|
265
|
+
const url = new URL(candidate.src);
|
|
266
|
+
if (url.origin !== "https://connect.facebook.net" || !/^\/[^/]+\/sdk\.js$/.test(url.pathname)) return false;
|
|
267
|
+
if (!runtime.failedFacebookScripts.has(candidate)) return true;
|
|
268
|
+
if (!runtime.erroredFacebookScripts.has(candidate)) runtime.facebookLoadUncertain = true;
|
|
269
|
+
return false;
|
|
270
|
+
} catch (e) {
|
|
271
|
+
return false;
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
if (!script) {
|
|
275
|
+
script = document.createElement("script");
|
|
276
|
+
ownedScript = true;
|
|
277
|
+
const initialSdk = host.FB;
|
|
278
|
+
if (initialSdk && "__buffer" in initialSdk) bootstrap = initialSdk;
|
|
279
|
+
freshSdk = !runtime.facebookLoadUncertain && !runtime.facebookLoading && !previousCallback && (!initialSdk || !!bootstrap && runtime.facebookAppIds.get(initialSdk) === null && ((_a = bootstrap.__buffer) == null ? void 0 : _a.opts) == null);
|
|
280
|
+
if (!byId) script.id = "facebook-jssdk";
|
|
281
|
+
script.src = "https://connect.facebook.net/en_US/sdk.js";
|
|
282
|
+
script.crossOrigin = "anonymous";
|
|
283
|
+
script.async = true;
|
|
284
|
+
script.defer = true;
|
|
285
|
+
}
|
|
286
|
+
shared2.cancelIfUnused();
|
|
287
|
+
if (settled) return;
|
|
288
|
+
Object.defineProperty(host, "fbAsyncInit", previous && !previous.configurable ? { value: onReady } : { configurable: true, enumerable: true, writable: true, value: onReady });
|
|
289
|
+
script.addEventListener("load", onLoad);
|
|
290
|
+
script.addEventListener("error", onError);
|
|
291
|
+
onLoad();
|
|
292
|
+
if (!settled && ownedScript) document.head.appendChild(script);
|
|
293
|
+
} catch (e) {
|
|
294
|
+
finish(void 0, new OmnizapiError("SDK_LOAD_FAILED", "The Meta SDK could not be loaded."));
|
|
118
295
|
}
|
|
119
|
-
}
|
|
120
|
-
if (runtime.facebookLoading === loading) delete runtime.facebookLoading;
|
|
121
|
-
if (sdk) resolve(sdk);
|
|
122
|
-
else reject(error);
|
|
123
|
-
};
|
|
124
|
-
const onLoad = () => {
|
|
125
|
-
if (settled) return;
|
|
126
|
-
const sdk = host.FB;
|
|
127
|
-
if (isReadySdk(sdk)) finish(sdk);
|
|
296
|
+
}))
|
|
128
297
|
};
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
298
|
+
runtime.facebookLoadObserver = loading = shared2;
|
|
299
|
+
}
|
|
300
|
+
const shared = loading;
|
|
301
|
+
return new Promise((resolve, reject) => {
|
|
302
|
+
let settled = false;
|
|
303
|
+
shared.consumers++;
|
|
304
|
+
const complete = (sdk, error) => {
|
|
305
|
+
var _a;
|
|
132
306
|
if (settled) return;
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
307
|
+
settled = true;
|
|
308
|
+
signal.removeEventListener("abort", onAbort);
|
|
309
|
+
shared.consumers--;
|
|
310
|
+
if (sdk) resolve(sdk);
|
|
311
|
+
else reject(error);
|
|
312
|
+
(_a = shared.cancelIfUnused) == null ? void 0 : _a.call(shared);
|
|
138
313
|
};
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
}
|
|
149
|
-
previous = Object.getOwnPropertyDescriptor(host, "fbAsyncInit");
|
|
150
|
-
previousCallback = typeof host.fbAsyncInit === "function" ? host.fbAsyncInit : void 0;
|
|
151
|
-
Object.defineProperty(host, "fbAsyncInit", previous && !previous.configurable ? { value: onReady } : { configurable: true, enumerable: true, writable: true, value: onReady });
|
|
152
|
-
const document = host.document;
|
|
153
|
-
const byId = document.getElementById("facebook-jssdk");
|
|
154
|
-
const existingScript = (byId == null ? void 0 : byId.tagName.toLowerCase()) === "script" ? byId : void 0;
|
|
155
|
-
script = (existingScript && !runtime.failedFacebookScripts.has(existingScript) ? existingScript : void 0) || Array.from(document.scripts).find((candidate) => {
|
|
156
|
-
if (runtime.failedFacebookScripts.has(candidate)) return false;
|
|
157
|
-
try {
|
|
158
|
-
const url = new URL(candidate.src);
|
|
159
|
-
return url.origin === "https://connect.facebook.net" && /^\/[^/]+\/sdk\.js$/.test(url.pathname);
|
|
160
|
-
} catch (e) {
|
|
161
|
-
return false;
|
|
162
|
-
}
|
|
163
|
-
});
|
|
164
|
-
if (!script) {
|
|
165
|
-
script = document.createElement("script");
|
|
166
|
-
ownedScript = true;
|
|
167
|
-
if (!byId) script.id = "facebook-jssdk";
|
|
168
|
-
script.src = "https://connect.facebook.net/en_US/sdk.js";
|
|
169
|
-
script.crossOrigin = "anonymous";
|
|
170
|
-
script.async = true;
|
|
171
|
-
script.defer = true;
|
|
172
|
-
}
|
|
173
|
-
script.addEventListener("load", onLoad);
|
|
174
|
-
script.addEventListener("error", onError);
|
|
175
|
-
onLoad();
|
|
176
|
-
if (!settled && ownedScript) document.head.appendChild(script);
|
|
177
|
-
} catch (e) {
|
|
178
|
-
onError();
|
|
179
|
-
}
|
|
180
|
-
}));
|
|
181
|
-
runtime.facebookLoading = loading;
|
|
182
|
-
return loading;
|
|
314
|
+
const onAbort = () => complete(void 0, new OmnizapiError("SDK_LOAD_FAILED", "The Meta SDK load was cancelled."));
|
|
315
|
+
void shared.promise.then(
|
|
316
|
+
(sdk) => signal.aborted ? onAbort() : complete(sdk),
|
|
317
|
+
// A shared observer may belong to another module copy's OmnizapiError class.
|
|
318
|
+
(error) => complete(void 0, new OmnizapiError("SDK_LOAD_FAILED", error.message))
|
|
319
|
+
);
|
|
320
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
321
|
+
if (signal.aborted) onAbort();
|
|
322
|
+
});
|
|
183
323
|
}
|
|
184
324
|
|
|
185
325
|
// src/core/open-popup.ts
|
|
@@ -260,8 +400,8 @@ function requestJson(url, init, signal) {
|
|
|
260
400
|
else resolve(value);
|
|
261
401
|
};
|
|
262
402
|
const onAbort = () => complete(void 0, new OmnizapiError(
|
|
263
|
-
"
|
|
264
|
-
"The API request was
|
|
403
|
+
"ABORTED",
|
|
404
|
+
"The API request was aborted."
|
|
265
405
|
));
|
|
266
406
|
const timer = setTimeout(() => complete(void 0, new OmnizapiError(
|
|
267
407
|
"TIMEOUT",
|
|
@@ -318,10 +458,14 @@ var OmnizapiClientImpl = class {
|
|
|
318
458
|
frontUrl: props.frontUrl
|
|
319
459
|
});
|
|
320
460
|
}
|
|
321
|
-
async getListMessengerPages(channelId, code) {
|
|
461
|
+
async getListMessengerPages(channelId, code, signal) {
|
|
322
462
|
if (!stringOrNull(channelId) || !stringOrNull(code)) {
|
|
323
463
|
throw new OmnizapiError("INVALID_OPTIONS", "A channelId and authorization code are required.");
|
|
324
464
|
}
|
|
465
|
+
if (signal !== void 0 && (!isRecord(signal) || typeof signal.aborted !== "boolean" || typeof signal.addEventListener !== "function" || typeof signal.removeEventListener !== "function")) {
|
|
466
|
+
throw new OmnizapiError("INVALID_OPTIONS", "The abort signal is invalid.");
|
|
467
|
+
}
|
|
468
|
+
if (signal == null ? void 0 : signal.aborted) throw new OmnizapiError("ABORTED", "The API request was aborted.");
|
|
325
469
|
return requestJson(
|
|
326
470
|
new URL(`${this.constants.api}/v1/channels/${encodeChannelId(channelId)}/list-messenger-pages`),
|
|
327
471
|
{
|
|
@@ -331,7 +475,8 @@ var OmnizapiClientImpl = class {
|
|
|
331
475
|
code
|
|
332
476
|
}),
|
|
333
477
|
headers: { "Content-Type": "application/json", Authorization: this.publicKey }
|
|
334
|
-
}
|
|
478
|
+
},
|
|
479
|
+
signal
|
|
335
480
|
);
|
|
336
481
|
}
|
|
337
482
|
async connect(options) {
|
|
@@ -348,10 +493,11 @@ var OmnizapiClientImpl = class {
|
|
|
348
493
|
if (!isRecord(options)) {
|
|
349
494
|
throw new OmnizapiError("INVALID_OPTIONS", "Connection options are required.");
|
|
350
495
|
}
|
|
351
|
-
const { channelId, direct, getQRCode, timeoutMs = TOTAL_TIMEOUT_MS } = options;
|
|
352
|
-
if (typeof channelId !== "string" || direct !== void 0 && typeof direct !== "boolean" || getQRCode !== void 0 && typeof getQRCode !== "function" || typeof timeoutMs !== "number" || !Number.isFinite(timeoutMs) || timeoutMs <= 0 || timeoutMs > 2147483647) {
|
|
353
|
-
throw new OmnizapiError("INVALID_OPTIONS", "Invalid channelId, direct, getQRCode or
|
|
496
|
+
const { channelId, direct, getQRCode, timeoutMs = TOTAL_TIMEOUT_MS, signal } = options;
|
|
497
|
+
if (typeof channelId !== "string" || direct !== void 0 && typeof direct !== "boolean" || getQRCode !== void 0 && typeof getQRCode !== "function" || typeof timeoutMs !== "number" || !Number.isFinite(timeoutMs) || timeoutMs <= 0 || timeoutMs > 2147483647 || signal !== void 0 && (!isRecord(signal) || typeof signal.aborted !== "boolean" || typeof signal.addEventListener !== "function" || typeof signal.removeEventListener !== "function")) {
|
|
498
|
+
throw new OmnizapiError("INVALID_OPTIONS", "Invalid channelId, direct, getQRCode, timeoutMs or signal option.");
|
|
354
499
|
}
|
|
500
|
+
if (signal == null ? void 0 : signal.aborted) throw new OmnizapiError("ABORTED", "The connection was aborted.");
|
|
355
501
|
if (!channelId.trim()) return failure(channelId, null, "invalid_channel");
|
|
356
502
|
const encodedChannelId = encodeChannelId(channelId);
|
|
357
503
|
if (typeof host.open !== "function" || typeof host.addEventListener !== "function" || typeof host.removeEventListener !== "function" || typeof host.location.origin !== "string" || typeof host.location.href !== "string" || typeof ((_a = host.crypto) == null ? void 0 : _a.getRandomValues) !== "function" || typeof AbortController !== "function" || typeof fetch !== "function") {
|
|
@@ -369,6 +515,7 @@ var OmnizapiClientImpl = class {
|
|
|
369
515
|
let channelType = null;
|
|
370
516
|
let redirectUri = null;
|
|
371
517
|
let popup = null;
|
|
518
|
+
let popupError;
|
|
372
519
|
let timeout;
|
|
373
520
|
let popupTimer;
|
|
374
521
|
let messageListener;
|
|
@@ -386,6 +533,10 @@ var OmnizapiClientImpl = class {
|
|
|
386
533
|
settled = true;
|
|
387
534
|
clearTimeout(timeout);
|
|
388
535
|
clearInterval(popupTimer);
|
|
536
|
+
try {
|
|
537
|
+
signal == null ? void 0 : signal.removeEventListener("abort", onAbort);
|
|
538
|
+
} catch (e) {
|
|
539
|
+
}
|
|
389
540
|
if (messageListener) {
|
|
390
541
|
try {
|
|
391
542
|
host.removeEventListener("message", messageListener);
|
|
@@ -418,13 +569,43 @@ var OmnizapiClientImpl = class {
|
|
|
418
569
|
if (outcome instanceof OmnizapiError) reject(outcome);
|
|
419
570
|
else resolve(outcome);
|
|
420
571
|
};
|
|
572
|
+
const onAbort = () => finish(new OmnizapiError("ABORTED", "The connection was aborted."));
|
|
421
573
|
const isLive = () => {
|
|
574
|
+
if (!settled && (signal == null ? void 0 : signal.aborted)) onAbort();
|
|
422
575
|
if (!settled && Date.now() >= deadline) {
|
|
423
576
|
finish(new OmnizapiError("TIMEOUT", "The connection timed out."));
|
|
424
577
|
}
|
|
425
578
|
return !settled;
|
|
426
579
|
};
|
|
427
580
|
const fail = (reason) => finish(failure(channelId, channelType, reason));
|
|
581
|
+
const reservePopup = () => {
|
|
582
|
+
try {
|
|
583
|
+
const opened = openPopup("about:blank", "_blank", 600, 740);
|
|
584
|
+
if (!opened || opened === host) throw new Error("Popup unavailable");
|
|
585
|
+
if (!isLive()) {
|
|
586
|
+
opened.close();
|
|
587
|
+
return;
|
|
588
|
+
}
|
|
589
|
+
popup = opened;
|
|
590
|
+
} catch (e) {
|
|
591
|
+
throw new OmnizapiError("POPUP_BLOCKED", "The connection popup could not be opened.");
|
|
592
|
+
}
|
|
593
|
+
};
|
|
594
|
+
const watchPopup = () => {
|
|
595
|
+
if (popupTimer) return;
|
|
596
|
+
popupTimer = setInterval(() => {
|
|
597
|
+
if (!isLive()) return;
|
|
598
|
+
try {
|
|
599
|
+
if (popup == null ? void 0 : popup.closed) fail("popup_closed");
|
|
600
|
+
} catch (e) {
|
|
601
|
+
finish(new OmnizapiError("PROVIDER_ERROR", "The connection popup could not be monitored."));
|
|
602
|
+
}
|
|
603
|
+
}, 500);
|
|
604
|
+
};
|
|
605
|
+
const unwatchPopup = () => {
|
|
606
|
+
clearInterval(popupTimer);
|
|
607
|
+
popupTimer = void 0;
|
|
608
|
+
};
|
|
428
609
|
const succeed = (data) => {
|
|
429
610
|
if (!isLive() || !channelType) return;
|
|
430
611
|
finish({
|
|
@@ -443,6 +624,8 @@ var OmnizapiClientImpl = class {
|
|
|
443
624
|
};
|
|
444
625
|
try {
|
|
445
626
|
runtime.activeConnection = owner;
|
|
627
|
+
signal == null ? void 0 : signal.addEventListener("abort", onAbort, { once: true });
|
|
628
|
+
if (!isLive()) return;
|
|
446
629
|
const bytes = host.crypto.getRandomValues(new Uint8Array(16));
|
|
447
630
|
const attemptId = Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
448
631
|
for (const [name, value] of [
|
|
@@ -458,6 +641,14 @@ var OmnizapiClientImpl = class {
|
|
|
458
641
|
"TIMEOUT",
|
|
459
642
|
"The connection timed out."
|
|
460
643
|
)), timeoutMs);
|
|
644
|
+
if (!direct) {
|
|
645
|
+
try {
|
|
646
|
+
reservePopup();
|
|
647
|
+
} catch (error) {
|
|
648
|
+
popupError = error instanceof OmnizapiError ? error : new OmnizapiError("POPUP_BLOCKED", "The connection popup could not be opened.");
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
if (!isLive()) return;
|
|
461
652
|
const run = async () => {
|
|
462
653
|
var _a2, _b, _c;
|
|
463
654
|
const info = await requestJson(
|
|
@@ -475,7 +666,13 @@ var OmnizapiClientImpl = class {
|
|
|
475
666
|
}
|
|
476
667
|
const middleware = info.middleware;
|
|
477
668
|
channelType = isChannelType(middleware) ? middleware : null;
|
|
478
|
-
if (currentOrigin !== frontOrigin && !allowOrigins.some((origin) =>
|
|
669
|
+
if (currentOrigin !== frontOrigin && !allowOrigins.some((origin) => {
|
|
670
|
+
try {
|
|
671
|
+
return currentOrigin === new URL(origin).origin;
|
|
672
|
+
} catch (e) {
|
|
673
|
+
return false;
|
|
674
|
+
}
|
|
675
|
+
})) {
|
|
479
676
|
fail("origin_not_allowed");
|
|
480
677
|
return;
|
|
481
678
|
}
|
|
@@ -488,21 +685,30 @@ var OmnizapiClientImpl = class {
|
|
|
488
685
|
if (channelType.startsWith("META_") && !appId || channelType === "META_WHATSAPP" && !configId) {
|
|
489
686
|
throw new OmnizapiError("INVALID_RESPONSE", "The channel provider configuration is invalid.");
|
|
490
687
|
}
|
|
491
|
-
|
|
688
|
+
const nativeWhatsApp = channelType === "META_WHATSAPP" && direct === true;
|
|
689
|
+
let nativeReady = false;
|
|
690
|
+
let fb;
|
|
691
|
+
if (nativeWhatsApp) {
|
|
692
|
+
unwatchPopup();
|
|
492
693
|
if (runtime.nativeLoginPending) {
|
|
493
694
|
throw new OmnizapiError(
|
|
494
695
|
"CONNECTION_IN_PROGRESS",
|
|
495
696
|
"A previous Meta login is incomplete. Reload this window before retrying a native login."
|
|
496
697
|
);
|
|
497
698
|
}
|
|
498
|
-
|
|
699
|
+
fb = await loadFacebookSdk(host, controller.signal);
|
|
499
700
|
if (!isLive()) return;
|
|
500
701
|
try {
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
702
|
+
initializeFacebookSdk(host, fb, appId);
|
|
703
|
+
nativeReady = true;
|
|
704
|
+
} catch (error) {
|
|
705
|
+
if (!(error instanceof OmnizapiError && error.code === "INVALID_CONFIGURATION")) throw error;
|
|
504
706
|
}
|
|
505
707
|
if (!isLive()) return;
|
|
708
|
+
}
|
|
709
|
+
if (nativeReady && fb) {
|
|
710
|
+
popup == null ? void 0 : popup.close();
|
|
711
|
+
popup = null;
|
|
506
712
|
let code = null;
|
|
507
713
|
let wabaId = null;
|
|
508
714
|
let phoneId = null;
|
|
@@ -575,6 +781,8 @@ var OmnizapiClientImpl = class {
|
|
|
575
781
|
}
|
|
576
782
|
});
|
|
577
783
|
} catch (e) {
|
|
784
|
+
releaseNativeLogin();
|
|
785
|
+
nativeLoginStarted = false;
|
|
578
786
|
throw new OmnizapiError("PROVIDER_ERROR", "The Meta login could not be started.");
|
|
579
787
|
}
|
|
580
788
|
return;
|
|
@@ -601,6 +809,7 @@ var OmnizapiClientImpl = class {
|
|
|
601
809
|
} else {
|
|
602
810
|
url = new URL(`${this.constants.front}/connect/${channelType === "BOT_TELEGRAM" ? "telegram" : "whatsapp-web"}`);
|
|
603
811
|
url.searchParams.set("channelId", channelId);
|
|
812
|
+
url.searchParams.set("pk", this.publicKey);
|
|
604
813
|
}
|
|
605
814
|
if (channelType !== "META_MESSENGER" && channelType !== "META_INSTAGRAM") {
|
|
606
815
|
url.searchParams.set("attemptId", attemptId);
|
|
@@ -621,23 +830,18 @@ var OmnizapiClientImpl = class {
|
|
|
621
830
|
};
|
|
622
831
|
host.addEventListener("message", messageListener);
|
|
623
832
|
if (!isLive()) return;
|
|
833
|
+
if (popupError) throw popupError;
|
|
834
|
+
if (!popup) reservePopup();
|
|
835
|
+
if (popup == null ? void 0 : popup.closed) {
|
|
836
|
+
fail("popup_closed");
|
|
837
|
+
return;
|
|
838
|
+
}
|
|
839
|
+
watchPopup();
|
|
624
840
|
try {
|
|
625
|
-
|
|
626
|
-
if (!opened || opened === host) {
|
|
627
|
-
throw new OmnizapiError("POPUP_BLOCKED", "The connection popup was blocked.");
|
|
628
|
-
}
|
|
629
|
-
popup = opened;
|
|
841
|
+
popup == null ? void 0 : popup.location.replace(url.href);
|
|
630
842
|
} catch (e) {
|
|
631
|
-
throw new OmnizapiError("
|
|
843
|
+
throw new OmnizapiError("PROVIDER_ERROR", "The connection popup could not be navigated.");
|
|
632
844
|
}
|
|
633
|
-
popupTimer = setInterval(() => {
|
|
634
|
-
if (!isLive()) return;
|
|
635
|
-
try {
|
|
636
|
-
if (popup == null ? void 0 : popup.closed) fail("popup_closed");
|
|
637
|
-
} catch (e) {
|
|
638
|
-
finish(new OmnizapiError("PROVIDER_ERROR", "The connection popup could not be monitored."));
|
|
639
|
-
}
|
|
640
|
-
}, 500);
|
|
641
845
|
};
|
|
642
846
|
void run().catch((error) => {
|
|
643
847
|
if (!isLive()) return;
|
|
@@ -646,8 +850,8 @@ var OmnizapiClientImpl = class {
|
|
|
646
850
|
"The connection could not be completed."
|
|
647
851
|
));
|
|
648
852
|
});
|
|
649
|
-
} catch (
|
|
650
|
-
finish(new OmnizapiError("INVALID_CONFIGURATION", "The connection could not be initialized."));
|
|
853
|
+
} catch (error) {
|
|
854
|
+
finish(error instanceof OmnizapiError ? error : new OmnizapiError("INVALID_CONFIGURATION", "The connection could not be initialized."));
|
|
651
855
|
}
|
|
652
856
|
});
|
|
653
857
|
} catch (error) {
|