@neetru/sdk 3.1.0 → 3.1.1
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/auth.cjs +159 -15
- package/dist/auth.cjs.map +1 -1
- package/dist/auth.d.cts +1 -1
- package/dist/auth.d.ts +1 -1
- package/dist/auth.mjs +159 -15
- package/dist/auth.mjs.map +1 -1
- package/dist/catalog.cjs +50 -2
- package/dist/catalog.cjs.map +1 -1
- package/dist/catalog.d.cts +1 -1
- package/dist/catalog.d.ts +1 -1
- package/dist/catalog.mjs +50 -2
- package/dist/catalog.mjs.map +1 -1
- package/dist/checkout.cjs +52 -3
- package/dist/checkout.cjs.map +1 -1
- package/dist/checkout.d.cts +1 -1
- package/dist/checkout.d.ts +1 -1
- package/dist/checkout.mjs +52 -3
- package/dist/checkout.mjs.map +1 -1
- package/dist/db-react.cjs +3 -1
- package/dist/db-react.cjs.map +1 -1
- package/dist/db-react.d.cts +1 -1
- package/dist/db-react.d.ts +1 -1
- package/dist/db-react.mjs +3 -1
- package/dist/db-react.mjs.map +1 -1
- package/dist/db.cjs +93 -6
- package/dist/db.cjs.map +1 -1
- package/dist/db.d.cts +1 -1
- package/dist/db.d.ts +1 -1
- package/dist/db.mjs +93 -6
- package/dist/db.mjs.map +1 -1
- package/dist/entitlements.cjs +50 -2
- package/dist/entitlements.cjs.map +1 -1
- package/dist/entitlements.d.cts +1 -1
- package/dist/entitlements.d.ts +1 -1
- package/dist/entitlements.mjs +50 -2
- package/dist/entitlements.mjs.map +1 -1
- package/dist/errors.cjs.map +1 -1
- package/dist/errors.d.cts +3 -1
- package/dist/errors.d.ts +3 -1
- package/dist/errors.mjs.map +1 -1
- package/dist/firestore-compat.cjs +14 -2
- package/dist/firestore-compat.cjs.map +1 -1
- package/dist/firestore-compat.d.cts +28 -3
- package/dist/firestore-compat.d.ts +28 -3
- package/dist/firestore-compat.mjs +14 -2
- package/dist/firestore-compat.mjs.map +1 -1
- package/dist/index.cjs +195 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -3
- package/dist/index.d.ts +9 -3
- package/dist/index.mjs +194 -17
- package/dist/index.mjs.map +1 -1
- package/dist/mocks.cjs.map +1 -1
- package/dist/mocks.d.cts +1 -1
- package/dist/mocks.d.ts +1 -1
- package/dist/mocks.mjs.map +1 -1
- package/dist/notifications.cjs +50 -2
- package/dist/notifications.cjs.map +1 -1
- package/dist/notifications.d.cts +1 -1
- package/dist/notifications.d.ts +1 -1
- package/dist/notifications.mjs +50 -2
- package/dist/notifications.mjs.map +1 -1
- package/dist/react.cjs +2 -3
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +22 -4
- package/dist/react.d.ts +22 -4
- package/dist/react.mjs +2 -3
- package/dist/react.mjs.map +1 -1
- package/dist/support.cjs +50 -2
- package/dist/support.cjs.map +1 -1
- package/dist/support.d.cts +1 -1
- package/dist/support.d.ts +1 -1
- package/dist/support.mjs +50 -2
- package/dist/support.mjs.map +1 -1
- package/dist/telemetry.cjs +65 -4
- package/dist/telemetry.cjs.map +1 -1
- package/dist/telemetry.d.cts +1 -1
- package/dist/telemetry.d.ts +1 -1
- package/dist/telemetry.mjs +65 -4
- package/dist/telemetry.mjs.map +1 -1
- package/dist/{types-BRv8wBxX.d.ts → types-B3XFHD4A.d.ts} +60 -1
- package/dist/{types-nwErcRX8.d.cts → types-DePdSU3P.d.cts} +60 -1
- package/dist/usage.cjs +50 -2
- package/dist/usage.cjs.map +1 -1
- package/dist/usage.d.cts +1 -1
- package/dist/usage.d.ts +1 -1
- package/dist/usage.mjs +50 -2
- package/dist/usage.mjs.map +1 -1
- package/dist/webhooks.cjs +83 -2
- package/dist/webhooks.cjs.map +1 -1
- package/dist/webhooks.d.cts +1 -1
- package/dist/webhooks.d.ts +1 -1
- package/dist/webhooks.mjs +83 -3
- package/dist/webhooks.mjs.map +1 -1
- package/package.json +1 -1
package/dist/auth.cjs
CHANGED
|
@@ -53,8 +53,47 @@ var init_idempotency = __esm({
|
|
|
53
53
|
// src/http.ts
|
|
54
54
|
var http_exports = {};
|
|
55
55
|
__export(http_exports, {
|
|
56
|
+
checkCoreVersionCompat: () => checkCoreVersionCompat,
|
|
56
57
|
httpRequest: () => httpRequest
|
|
57
58
|
});
|
|
59
|
+
function stripRevision(v) {
|
|
60
|
+
return v.split("+")[0] ?? v;
|
|
61
|
+
}
|
|
62
|
+
function compareCalVer(a, b) {
|
|
63
|
+
const partsA = stripRevision(a).split(".").map(Number);
|
|
64
|
+
const partsB = stripRevision(b).split(".").map(Number);
|
|
65
|
+
const len = Math.max(partsA.length, partsB.length);
|
|
66
|
+
for (let i = 0; i < len; i++) {
|
|
67
|
+
const pa = partsA[i] ?? 0;
|
|
68
|
+
const pb = partsB[i] ?? 0;
|
|
69
|
+
if (pa !== pb) return pa - pb;
|
|
70
|
+
}
|
|
71
|
+
return 0;
|
|
72
|
+
}
|
|
73
|
+
function getSdkMajor() {
|
|
74
|
+
try {
|
|
75
|
+
const ver = globalThis.__NEETRU_SDK_VERSION__;
|
|
76
|
+
if (ver) return parseInt(ver.split(".")[0] ?? "3", 10);
|
|
77
|
+
} catch {
|
|
78
|
+
}
|
|
79
|
+
return 3;
|
|
80
|
+
}
|
|
81
|
+
function checkCoreVersionCompat(coreVersion) {
|
|
82
|
+
if (!coreVersion) return;
|
|
83
|
+
const sdkMajor = getSdkMajor();
|
|
84
|
+
const minCore = COMPAT_MATRIX[sdkMajor];
|
|
85
|
+
if (!minCore) return;
|
|
86
|
+
const stripped = stripRevision(coreVersion);
|
|
87
|
+
if (compareCalVer(stripped, minCore) < 0) {
|
|
88
|
+
const key = `${sdkMajor}:${stripped}`;
|
|
89
|
+
if (!_warnedCoreTooOld.has(key)) {
|
|
90
|
+
_warnedCoreTooOld.add(key);
|
|
91
|
+
console.warn(
|
|
92
|
+
`[Neetru SDK] Aten\xE7\xE3o: Core vers\xE3o "${coreVersion}" \xE9 anterior ao m\xEDnimo recomendado "${minCore}" para SDK major ${sdkMajor}. Alguns recursos podem n\xE3o funcionar corretamente. Atualize o Core para a vers\xE3o mais recente.`
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
58
97
|
function backoffMs(attempt) {
|
|
59
98
|
const base = 200 * Math.pow(4, attempt);
|
|
60
99
|
const jitter = base * 0.2 * (Math.random() * 2 - 1);
|
|
@@ -63,11 +102,11 @@ function backoffMs(attempt) {
|
|
|
63
102
|
function parseRetryAfter(value) {
|
|
64
103
|
if (!value) return null;
|
|
65
104
|
const secs = Number(value);
|
|
66
|
-
if (Number.isFinite(secs) && secs >= 0) return Math.round(secs * 1e3);
|
|
105
|
+
if (Number.isFinite(secs) && secs >= 0) return Math.min(Math.round(secs * 1e3), MAX_RETRY_AFTER_MS);
|
|
67
106
|
const dateMs = Date.parse(value);
|
|
68
107
|
if (Number.isFinite(dateMs)) {
|
|
69
108
|
const delta = dateMs - Date.now();
|
|
70
|
-
if (delta > 0) return delta;
|
|
109
|
+
if (delta > 0) return Math.min(delta, MAX_RETRY_AFTER_MS);
|
|
71
110
|
}
|
|
72
111
|
return null;
|
|
73
112
|
}
|
|
@@ -78,6 +117,7 @@ function statusToCode(status) {
|
|
|
78
117
|
if (status === 401) return "unauthorized";
|
|
79
118
|
if (status === 403) return "forbidden";
|
|
80
119
|
if (status === 404) return "not_found";
|
|
120
|
+
if (status === 409) return "conflict";
|
|
81
121
|
if (status === 422 || status === 400) return "validation_failed";
|
|
82
122
|
if (status === 429) return "rate_limited";
|
|
83
123
|
if (status >= 500) return "server_error";
|
|
@@ -149,6 +189,8 @@ async function httpRequest(config, opts) {
|
|
|
149
189
|
}
|
|
150
190
|
const requestId = res.headers.get("x-request-id") ?? res.headers.get("x-correlation-id") ?? void 0;
|
|
151
191
|
if (res.ok) {
|
|
192
|
+
const coreVersion = res.headers.get("x-neetru-version");
|
|
193
|
+
if (coreVersion) checkCoreVersionCompat(coreVersion);
|
|
152
194
|
const parsed = await safeJson(res);
|
|
153
195
|
return parsed;
|
|
154
196
|
}
|
|
@@ -177,11 +219,17 @@ async function httpRequest(config, opts) {
|
|
|
177
219
|
}
|
|
178
220
|
throw lastError ?? new NeetruError("unknown", "unexpected httpRequest exit");
|
|
179
221
|
}
|
|
180
|
-
var DEFAULT_RETRIES_READ, DEFAULT_RETRIES_WRITE, READ_METHODS, RETRYABLE_CODES;
|
|
222
|
+
var COMPAT_MATRIX, _warnedCoreTooOld, DEFAULT_RETRIES_READ, DEFAULT_RETRIES_WRITE, READ_METHODS, RETRYABLE_CODES, MAX_RETRY_AFTER_MS;
|
|
181
223
|
var init_http = __esm({
|
|
182
224
|
"src/http.ts"() {
|
|
183
225
|
init_errors();
|
|
184
226
|
init_idempotency();
|
|
227
|
+
COMPAT_MATRIX = {
|
|
228
|
+
// SDK major 3.x requer Core ≥ 2026.05.1 (suporte a X-Neetru-Version header,
|
|
229
|
+
// runTransaction write-after-read, verifyWebhookRequest, webhooks 3.0+)
|
|
230
|
+
3: "2026.05.1"
|
|
231
|
+
};
|
|
232
|
+
_warnedCoreTooOld = /* @__PURE__ */ new Set();
|
|
185
233
|
DEFAULT_RETRIES_READ = 2;
|
|
186
234
|
DEFAULT_RETRIES_WRITE = 0;
|
|
187
235
|
READ_METHODS = /* @__PURE__ */ new Set(["GET", "HEAD"]);
|
|
@@ -190,6 +238,7 @@ var init_http = __esm({
|
|
|
190
238
|
"server_error",
|
|
191
239
|
"network_error"
|
|
192
240
|
]);
|
|
241
|
+
MAX_RETRY_AFTER_MS = 6e4;
|
|
193
242
|
}
|
|
194
243
|
});
|
|
195
244
|
|
|
@@ -891,11 +940,11 @@ var TRACK_MAX_QUEUE = 50;
|
|
|
891
940
|
function createTelemetryNamespace(config) {
|
|
892
941
|
const queue = [];
|
|
893
942
|
let flushTimer = null;
|
|
943
|
+
let _inflightDrain = null;
|
|
894
944
|
async function drainQueue() {
|
|
895
945
|
if (queue.length === 0) return;
|
|
896
946
|
const batch = queue.splice(0, queue.length);
|
|
897
|
-
|
|
898
|
-
await Promise.allSettled(
|
|
947
|
+
const work = Promise.allSettled(
|
|
899
948
|
batch.map(async (ev) => {
|
|
900
949
|
try {
|
|
901
950
|
const body = { name: ev.name };
|
|
@@ -917,6 +966,14 @@ function createTelemetryNamespace(config) {
|
|
|
917
966
|
}
|
|
918
967
|
})
|
|
919
968
|
);
|
|
969
|
+
_inflightDrain = work.then(() => {
|
|
970
|
+
_inflightDrain = null;
|
|
971
|
+
});
|
|
972
|
+
await work;
|
|
973
|
+
flushTimer = null;
|
|
974
|
+
if (queue.length > 0) {
|
|
975
|
+
scheduleFlush();
|
|
976
|
+
}
|
|
920
977
|
}
|
|
921
978
|
function scheduleFlush() {
|
|
922
979
|
if (flushTimer) return;
|
|
@@ -979,6 +1036,10 @@ function createTelemetryNamespace(config) {
|
|
|
979
1036
|
if (input.name.length > 128) return;
|
|
980
1037
|
queue.push(input);
|
|
981
1038
|
if (queue.length >= TRACK_MAX_QUEUE) {
|
|
1039
|
+
if (flushTimer) {
|
|
1040
|
+
clearTimeout(flushTimer);
|
|
1041
|
+
flushTimer = null;
|
|
1042
|
+
}
|
|
982
1043
|
void drainQueue();
|
|
983
1044
|
} else {
|
|
984
1045
|
scheduleFlush();
|
|
@@ -993,6 +1054,7 @@ function createTelemetryNamespace(config) {
|
|
|
993
1054
|
clearTimeout(flushTimer);
|
|
994
1055
|
flushTimer = null;
|
|
995
1056
|
}
|
|
1057
|
+
if (_inflightDrain) await _inflightDrain;
|
|
996
1058
|
await drainQueue();
|
|
997
1059
|
},
|
|
998
1060
|
/**
|
|
@@ -1481,6 +1543,31 @@ var LocalStore = class {
|
|
|
1481
1543
|
this.db?.close();
|
|
1482
1544
|
this.db = null;
|
|
1483
1545
|
}
|
|
1546
|
+
/**
|
|
1547
|
+
* Apaga completamente o banco IndexedDB e o recria do zero.
|
|
1548
|
+
*
|
|
1549
|
+
* Ao contrário de `close()` + `open()` (que reabre o banco existente sem
|
|
1550
|
+
* apagar dados), `clearAll()` chama `indexedDB.deleteDatabase(dbName)` e
|
|
1551
|
+
* só então chama `open()` — garantindo que nenhum documento, mutação ou
|
|
1552
|
+
* metadado sobrevive.
|
|
1553
|
+
*
|
|
1554
|
+
* BUG fix: `clearCache()` em `NeetruDbDocumentsImpl` chamava close+open,
|
|
1555
|
+
* que reabre o mesmo banco. `clearAll()` é o método correto.
|
|
1556
|
+
*/
|
|
1557
|
+
async clearAll() {
|
|
1558
|
+
if (this.db !== null) {
|
|
1559
|
+
this.db.close();
|
|
1560
|
+
this.db = null;
|
|
1561
|
+
}
|
|
1562
|
+
await new Promise((resolve, reject) => {
|
|
1563
|
+
const req = indexedDB.deleteDatabase(this.dbName);
|
|
1564
|
+
req.onsuccess = () => resolve();
|
|
1565
|
+
req.onerror = () => reject(req.error);
|
|
1566
|
+
req.onblocked = () => {
|
|
1567
|
+
};
|
|
1568
|
+
});
|
|
1569
|
+
await this.open();
|
|
1570
|
+
}
|
|
1484
1571
|
assertOpen() {
|
|
1485
1572
|
if (this.db === null) {
|
|
1486
1573
|
throw new Error("LocalStore: banco n\xE3o est\xE1 aberto. Chame open() primeiro.");
|
|
@@ -1688,6 +1775,12 @@ var MemoryStore = class {
|
|
|
1688
1775
|
async open() {
|
|
1689
1776
|
}
|
|
1690
1777
|
async close() {
|
|
1778
|
+
}
|
|
1779
|
+
/**
|
|
1780
|
+
* Apaga todos os dados em memória — equivalente ao `indexedDB.deleteDatabase`
|
|
1781
|
+
* que `LocalStore.clearAll()` executa em ambientes com IndexedDB.
|
|
1782
|
+
*/
|
|
1783
|
+
async clearAll() {
|
|
1691
1784
|
this._docs.clear();
|
|
1692
1785
|
this._mutations.clear();
|
|
1693
1786
|
this._meta.clear();
|
|
@@ -2202,6 +2295,8 @@ var SyncEngine = class {
|
|
|
2202
2295
|
const phase1Ok = await this._phase1Push();
|
|
2203
2296
|
if (!phase1Ok) {
|
|
2204
2297
|
this._updateState({ status: "idle" });
|
|
2298
|
+
this._refreshPendingWrites().catch(() => {
|
|
2299
|
+
});
|
|
2205
2300
|
this._syncing = false;
|
|
2206
2301
|
return;
|
|
2207
2302
|
}
|
|
@@ -2588,7 +2683,7 @@ var SyncEngine = class {
|
|
|
2588
2683
|
ownerId: localDoc.meta.ownerId
|
|
2589
2684
|
}
|
|
2590
2685
|
};
|
|
2591
|
-
const pendingMuts = await this._queue.
|
|
2686
|
+
const pendingMuts = await this._queue.listAll();
|
|
2592
2687
|
const docMut = pendingMuts.find(
|
|
2593
2688
|
(m) => m.collection === serverDoc.collection && m.docId === serverDoc.id
|
|
2594
2689
|
);
|
|
@@ -3942,8 +4037,13 @@ var NeetruDbDocumentsImpl = class {
|
|
|
3942
4037
|
return this._engine.flush();
|
|
3943
4038
|
}
|
|
3944
4039
|
async clearCache() {
|
|
3945
|
-
|
|
3946
|
-
|
|
4040
|
+
const storeWithClear = this._store;
|
|
4041
|
+
if (typeof storeWithClear.clearAll === "function") {
|
|
4042
|
+
await storeWithClear.clearAll();
|
|
4043
|
+
} else {
|
|
4044
|
+
await this._store.close();
|
|
4045
|
+
await this._store.open();
|
|
4046
|
+
}
|
|
3947
4047
|
}
|
|
3948
4048
|
async getConflicts() {
|
|
3949
4049
|
return this._store.listConflicts();
|
|
@@ -4830,7 +4930,8 @@ function createHttpCheckoutNamespace(config) {
|
|
|
4830
4930
|
method: "POST",
|
|
4831
4931
|
path: "/api/v1/checkout/intents",
|
|
4832
4932
|
body,
|
|
4833
|
-
requireAuth: true
|
|
4933
|
+
requireAuth: true,
|
|
4934
|
+
idempotencyKey: true
|
|
4834
4935
|
});
|
|
4835
4936
|
const result = parseStartResponse(raw);
|
|
4836
4937
|
const shouldRedirect = input.autoRedirect !== false;
|
|
@@ -5585,6 +5686,7 @@ function createOidcAuthNamespace(config) {
|
|
|
5585
5686
|
const STORAGE_KEY = "neetru_id_token";
|
|
5586
5687
|
const listeners = /* @__PURE__ */ new Set();
|
|
5587
5688
|
let cachedUser = null;
|
|
5689
|
+
let _expiryTimerId = null;
|
|
5588
5690
|
function getStorage() {
|
|
5589
5691
|
try {
|
|
5590
5692
|
return typeof globalThis.localStorage !== "undefined" ? globalThis.localStorage : null;
|
|
@@ -5607,6 +5709,9 @@ function createOidcAuthNamespace(config) {
|
|
|
5607
5709
|
function tokenToUser(token) {
|
|
5608
5710
|
const payload = decodeJwtPayload(token);
|
|
5609
5711
|
if (!payload || typeof payload.sub !== "string") return null;
|
|
5712
|
+
if (typeof payload.exp === "number" && payload.exp * 1e3 < Date.now()) {
|
|
5713
|
+
return null;
|
|
5714
|
+
}
|
|
5610
5715
|
return {
|
|
5611
5716
|
uid: payload.sub,
|
|
5612
5717
|
email: typeof payload.email === "string" ? payload.email : "",
|
|
@@ -5620,12 +5725,28 @@ function createOidcAuthNamespace(config) {
|
|
|
5620
5725
|
};
|
|
5621
5726
|
}
|
|
5622
5727
|
function loadCachedUser() {
|
|
5623
|
-
if (cachedUser)
|
|
5728
|
+
if (cachedUser) {
|
|
5729
|
+
const exp = cachedUser.exp;
|
|
5730
|
+
if (typeof exp === "number" && exp * 1e3 < Date.now()) {
|
|
5731
|
+
cachedUser = null;
|
|
5732
|
+
const storage2 = getStorage();
|
|
5733
|
+
storage2?.removeItem(STORAGE_KEY);
|
|
5734
|
+
notify();
|
|
5735
|
+
return null;
|
|
5736
|
+
}
|
|
5737
|
+
return cachedUser;
|
|
5738
|
+
}
|
|
5624
5739
|
const storage = getStorage();
|
|
5625
5740
|
if (!storage) return null;
|
|
5626
5741
|
const token = storage.getItem(STORAGE_KEY);
|
|
5627
5742
|
if (!token) return null;
|
|
5628
|
-
|
|
5743
|
+
const user = tokenToUser(token);
|
|
5744
|
+
if (!user) {
|
|
5745
|
+
storage.removeItem(STORAGE_KEY);
|
|
5746
|
+
return null;
|
|
5747
|
+
}
|
|
5748
|
+
cachedUser = user;
|
|
5749
|
+
scheduleExpiryTimer(user);
|
|
5629
5750
|
return cachedUser;
|
|
5630
5751
|
}
|
|
5631
5752
|
function notify() {
|
|
@@ -5636,6 +5757,23 @@ function createOidcAuthNamespace(config) {
|
|
|
5636
5757
|
}
|
|
5637
5758
|
}
|
|
5638
5759
|
}
|
|
5760
|
+
function cancelExpiryTimer() {
|
|
5761
|
+
if (_expiryTimerId !== null) {
|
|
5762
|
+
clearTimeout(_expiryTimerId);
|
|
5763
|
+
_expiryTimerId = null;
|
|
5764
|
+
}
|
|
5765
|
+
}
|
|
5766
|
+
function scheduleExpiryTimer(user) {
|
|
5767
|
+
cancelExpiryTimer();
|
|
5768
|
+
const exp = user.exp;
|
|
5769
|
+
if (typeof exp !== "number") return;
|
|
5770
|
+
const msUntilExpiry = exp * 1e3 - Date.now();
|
|
5771
|
+
if (msUntilExpiry <= 0) return;
|
|
5772
|
+
_expiryTimerId = setTimeout(() => {
|
|
5773
|
+
_expiryTimerId = null;
|
|
5774
|
+
loadCachedUser();
|
|
5775
|
+
}, msUntilExpiry + 1);
|
|
5776
|
+
}
|
|
5639
5777
|
return {
|
|
5640
5778
|
async signIn(options) {
|
|
5641
5779
|
if (typeof globalThis.location !== "undefined" && typeof globalThis.location.assign === "function") {
|
|
@@ -5663,18 +5801,24 @@ function createOidcAuthNamespace(config) {
|
|
|
5663
5801
|
},
|
|
5664
5802
|
async signOut() {
|
|
5665
5803
|
const storage = getStorage();
|
|
5804
|
+
const storedToken = storage?.getItem(STORAGE_KEY) ?? null;
|
|
5666
5805
|
if (storage) storage.removeItem(STORAGE_KEY);
|
|
5806
|
+
cancelExpiryTimer();
|
|
5667
5807
|
cachedUser = null;
|
|
5668
5808
|
const overrideAuthUrl = typeof globalThis.NEETRU_AUTH_URL === "string" ? globalThis.NEETRU_AUTH_URL : null;
|
|
5669
5809
|
const idpOrigin = overrideAuthUrl ?? config.baseUrl.replace(/^https?:\/\/api\./, "https://auth.");
|
|
5670
5810
|
const revokeUrl = `${idpOrigin}/api/v1/oauth/revoke`;
|
|
5811
|
+
const revokeBody = storedToken ? JSON.stringify({ token: storedToken }) : null;
|
|
5671
5812
|
let revokeError = null;
|
|
5672
5813
|
for (let attempt = 0; attempt < 2; attempt++) {
|
|
5673
5814
|
try {
|
|
5674
|
-
|
|
5675
|
-
|
|
5676
|
-
|
|
5677
|
-
|
|
5815
|
+
if (revokeBody) {
|
|
5816
|
+
await config.fetch(revokeUrl, {
|
|
5817
|
+
method: "POST",
|
|
5818
|
+
headers: { "content-type": "application/json" },
|
|
5819
|
+
body: revokeBody
|
|
5820
|
+
});
|
|
5821
|
+
}
|
|
5678
5822
|
revokeError = null;
|
|
5679
5823
|
break;
|
|
5680
5824
|
} catch (err) {
|