@kedaruma/revlm-client 1.0.50 → 1.0.53
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.d.mts +7 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +57 -22
- package/dist/index.mjs +57 -22
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -204,12 +204,19 @@ declare class Revlm {
|
|
|
204
204
|
private autoRefreshOn401;
|
|
205
205
|
private cookieCheckPromise?;
|
|
206
206
|
private logLevel;
|
|
207
|
+
private refreshPromise;
|
|
207
208
|
constructor(baseUrl: string, opts?: RevlmOptions);
|
|
209
|
+
private canLog;
|
|
210
|
+
logError(...args: any[]): void;
|
|
211
|
+
logWarn(...args: any[]): void;
|
|
212
|
+
logInfo(...args: any[]): void;
|
|
213
|
+
logDebug(...args: any[]): void;
|
|
208
214
|
setToken(token: string): void;
|
|
209
215
|
getToken(): string | undefined;
|
|
210
216
|
clearToken(): void;
|
|
211
217
|
logout(): void;
|
|
212
218
|
refreshToken(): Promise<RevlmResponse>;
|
|
219
|
+
private refreshTokenSingleFlight;
|
|
213
220
|
verifyToken(): Promise<RevlmResponse>;
|
|
214
221
|
private makeHeaders;
|
|
215
222
|
private parseResponse;
|
package/dist/index.d.ts
CHANGED
|
@@ -204,12 +204,19 @@ declare class Revlm {
|
|
|
204
204
|
private autoRefreshOn401;
|
|
205
205
|
private cookieCheckPromise?;
|
|
206
206
|
private logLevel;
|
|
207
|
+
private refreshPromise;
|
|
207
208
|
constructor(baseUrl: string, opts?: RevlmOptions);
|
|
209
|
+
private canLog;
|
|
210
|
+
logError(...args: any[]): void;
|
|
211
|
+
logWarn(...args: any[]): void;
|
|
212
|
+
logInfo(...args: any[]): void;
|
|
213
|
+
logDebug(...args: any[]): void;
|
|
208
214
|
setToken(token: string): void;
|
|
209
215
|
getToken(): string | undefined;
|
|
210
216
|
clearToken(): void;
|
|
211
217
|
logout(): void;
|
|
212
218
|
refreshToken(): Promise<RevlmResponse>;
|
|
219
|
+
private refreshTokenSingleFlight;
|
|
213
220
|
verifyToken(): Promise<RevlmResponse>;
|
|
214
221
|
private makeHeaders;
|
|
215
222
|
private parseResponse;
|
package/dist/index.js
CHANGED
|
@@ -35,7 +35,7 @@ var require_package = __commonJS({
|
|
|
35
35
|
"package.json"(exports2, module2) {
|
|
36
36
|
module2.exports = {
|
|
37
37
|
name: "@kedaruma/revlm-client",
|
|
38
|
-
version: "1.0.
|
|
38
|
+
version: "1.0.53",
|
|
39
39
|
private: false,
|
|
40
40
|
description: "TypeScript client SDK for talking to the Revlm server replacement for MongoDB Realm.",
|
|
41
41
|
keywords: [
|
|
@@ -216,6 +216,12 @@ var RevlmDBDatabase = class {
|
|
|
216
216
|
};
|
|
217
217
|
|
|
218
218
|
// src/Revlm.ts
|
|
219
|
+
var LOG_LEVEL_RANK = {
|
|
220
|
+
error: 0,
|
|
221
|
+
warn: 1,
|
|
222
|
+
info: 2,
|
|
223
|
+
debug: 3
|
|
224
|
+
};
|
|
219
225
|
function normalizeLogLevel(value) {
|
|
220
226
|
if (!value) return "info";
|
|
221
227
|
const lowered = value.toLowerCase();
|
|
@@ -251,6 +257,7 @@ var Revlm = class {
|
|
|
251
257
|
autoRefreshOn401;
|
|
252
258
|
cookieCheckPromise;
|
|
253
259
|
logLevel;
|
|
260
|
+
refreshPromise;
|
|
254
261
|
constructor(baseUrl, opts = {}) {
|
|
255
262
|
if (!baseUrl) throw new Error("baseUrl is required");
|
|
256
263
|
this.baseUrl = baseUrl.replace(/\/$/, "");
|
|
@@ -265,20 +272,33 @@ var Revlm = class {
|
|
|
265
272
|
if (!this.fetchImpl) {
|
|
266
273
|
throw new Error("No fetch implementation available. Provide fetchImpl in options or run in Node 18+ with global fetch.");
|
|
267
274
|
}
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
275
|
+
this.logInfo("\u{1F680} Revlm Client Init", {
|
|
276
|
+
version: getRevlmClientVersion(),
|
|
277
|
+
baseUrl: this.baseUrl,
|
|
278
|
+
autoSetToken: this.autoSetToken,
|
|
279
|
+
autoRefreshOn401: this.autoRefreshOn401,
|
|
280
|
+
provisionalEnabled: this.provisionalEnabled,
|
|
281
|
+
provisionalAuthDomain: this.provisionalAuthDomain || void 0,
|
|
282
|
+
provisionalAuthSecretMaster: maskSecret(this.provisionalAuthSecretMaster),
|
|
283
|
+
defaultHeaders: Object.keys(this.defaultHeaders || {}),
|
|
284
|
+
fetchImplProvided: !!opts.fetchImpl,
|
|
285
|
+
logLevel: this.logLevel
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
canLog(level) {
|
|
289
|
+
return LOG_LEVEL_RANK[this.logLevel] >= LOG_LEVEL_RANK[level];
|
|
290
|
+
}
|
|
291
|
+
logError(...args) {
|
|
292
|
+
if (this.canLog("error")) console.error(...args);
|
|
293
|
+
}
|
|
294
|
+
logWarn(...args) {
|
|
295
|
+
if (this.canLog("warn")) console.warn(...args);
|
|
296
|
+
}
|
|
297
|
+
logInfo(...args) {
|
|
298
|
+
if (this.canLog("info")) console.log(...args);
|
|
299
|
+
}
|
|
300
|
+
logDebug(...args) {
|
|
301
|
+
if (this.canLog("debug")) console.log(...args);
|
|
282
302
|
}
|
|
283
303
|
setToken(token) {
|
|
284
304
|
this._token = token;
|
|
@@ -303,6 +323,18 @@ var Revlm = class {
|
|
|
303
323
|
}
|
|
304
324
|
return res;
|
|
305
325
|
}
|
|
326
|
+
async refreshTokenSingleFlight() {
|
|
327
|
+
if (!this.refreshPromise) {
|
|
328
|
+
this.refreshPromise = (async () => {
|
|
329
|
+
try {
|
|
330
|
+
return await this.refreshToken();
|
|
331
|
+
} finally {
|
|
332
|
+
this.refreshPromise = void 0;
|
|
333
|
+
}
|
|
334
|
+
})();
|
|
335
|
+
}
|
|
336
|
+
return this.refreshPromise;
|
|
337
|
+
}
|
|
306
338
|
// Verify current token with server. If invalid/expired, clear local token.
|
|
307
339
|
async verifyToken() {
|
|
308
340
|
if (!this._token) return { ok: false, error: "No token set" };
|
|
@@ -378,7 +410,7 @@ var Revlm = class {
|
|
|
378
410
|
if (!payload || typeof payload.exp !== "number") return;
|
|
379
411
|
const now = Math.floor(Date.now() / 1e3);
|
|
380
412
|
const ttlSec = payload.exp - now;
|
|
381
|
-
|
|
413
|
+
this.logDebug("### token ttl", {
|
|
382
414
|
event,
|
|
383
415
|
path,
|
|
384
416
|
ttlSec,
|
|
@@ -416,9 +448,12 @@ var Revlm = class {
|
|
|
416
448
|
}
|
|
417
449
|
if (allowAuthRetry && !retrying && res.status === 401 && !this.shouldSkipAuthRetry(path)) {
|
|
418
450
|
const beforePayload = this.decodeJwtPayload(this._token || "");
|
|
419
|
-
const refreshRes = await this.
|
|
451
|
+
const refreshRes = await this.refreshTokenSingleFlight();
|
|
420
452
|
if (!refreshRes.ok) {
|
|
421
|
-
|
|
453
|
+
if (refreshRes.reason === "not_expired") {
|
|
454
|
+
return this.requestWithRetry(path, method, body, { allowAuthRetry: false, retrying: true });
|
|
455
|
+
}
|
|
456
|
+
this.logDebug("### refresh failed:", {
|
|
422
457
|
reason: refreshRes.reason,
|
|
423
458
|
status: refreshRes.status,
|
|
424
459
|
error: refreshRes.error
|
|
@@ -434,7 +469,7 @@ var Revlm = class {
|
|
|
434
469
|
const now = Math.floor(Date.now() / 1e3);
|
|
435
470
|
const oldExp = beforePayload?.exp;
|
|
436
471
|
const newExp = afterPayload?.exp;
|
|
437
|
-
|
|
472
|
+
this.logDebug("### refresh success", {
|
|
438
473
|
path,
|
|
439
474
|
oldExp,
|
|
440
475
|
newExp,
|
|
@@ -498,13 +533,13 @@ var Revlm = class {
|
|
|
498
533
|
if (this.cookieCheckPromise) return this.cookieCheckPromise;
|
|
499
534
|
this.cookieCheckPromise = (async () => {
|
|
500
535
|
const first = await this.requestWithRetry("/cookie-check", "POST", void 0, { allowAuthRetry: false, retrying: false });
|
|
501
|
-
|
|
536
|
+
this.logDebug("### cookie check", { step: "first", ok: first.ok, reason: first.reason, status: first.status });
|
|
502
537
|
if (first.ok) return;
|
|
503
538
|
if (first.reason !== "cookie_missing") {
|
|
504
539
|
throw new Error(`Cookie check failed: ${first.reason || first.error || "unknown_error"}`);
|
|
505
540
|
}
|
|
506
541
|
const second = await this.requestWithRetry("/cookie-check", "POST", void 0, { allowAuthRetry: false, retrying: false });
|
|
507
|
-
|
|
542
|
+
this.logDebug("### cookie check", { step: "second", ok: second.ok, reason: second.reason, status: second.status });
|
|
508
543
|
if (!second.ok) {
|
|
509
544
|
throw new Error("Cookie support missing. Provide a cookie-aware fetch implementation for Node/RN.");
|
|
510
545
|
}
|
|
@@ -588,7 +623,7 @@ var App = class {
|
|
|
588
623
|
throw new Error("Unsupported credentials type");
|
|
589
624
|
}
|
|
590
625
|
const res = await this.revlm.login(cred.email, cred.password);
|
|
591
|
-
|
|
626
|
+
this.revlm.logInfo("### App:login res:", res);
|
|
592
627
|
if (!res || !res.ok || !res.token) {
|
|
593
628
|
const errMsg = res && !res.ok ? res.error : "login failed";
|
|
594
629
|
const err = new Error(errMsg);
|
package/dist/index.mjs
CHANGED
|
@@ -7,7 +7,7 @@ var require_package = __commonJS({
|
|
|
7
7
|
"package.json"(exports, module) {
|
|
8
8
|
module.exports = {
|
|
9
9
|
name: "@kedaruma/revlm-client",
|
|
10
|
-
version: "1.0.
|
|
10
|
+
version: "1.0.53",
|
|
11
11
|
private: false,
|
|
12
12
|
description: "TypeScript client SDK for talking to the Revlm server replacement for MongoDB Realm.",
|
|
13
13
|
keywords: [
|
|
@@ -172,6 +172,12 @@ var RevlmDBDatabase = class {
|
|
|
172
172
|
};
|
|
173
173
|
|
|
174
174
|
// src/Revlm.ts
|
|
175
|
+
var LOG_LEVEL_RANK = {
|
|
176
|
+
error: 0,
|
|
177
|
+
warn: 1,
|
|
178
|
+
info: 2,
|
|
179
|
+
debug: 3
|
|
180
|
+
};
|
|
175
181
|
function normalizeLogLevel(value) {
|
|
176
182
|
if (!value) return "info";
|
|
177
183
|
const lowered = value.toLowerCase();
|
|
@@ -207,6 +213,7 @@ var Revlm = class {
|
|
|
207
213
|
autoRefreshOn401;
|
|
208
214
|
cookieCheckPromise;
|
|
209
215
|
logLevel;
|
|
216
|
+
refreshPromise;
|
|
210
217
|
constructor(baseUrl, opts = {}) {
|
|
211
218
|
if (!baseUrl) throw new Error("baseUrl is required");
|
|
212
219
|
this.baseUrl = baseUrl.replace(/\/$/, "");
|
|
@@ -221,20 +228,33 @@ var Revlm = class {
|
|
|
221
228
|
if (!this.fetchImpl) {
|
|
222
229
|
throw new Error("No fetch implementation available. Provide fetchImpl in options or run in Node 18+ with global fetch.");
|
|
223
230
|
}
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
231
|
+
this.logInfo("\u{1F680} Revlm Client Init", {
|
|
232
|
+
version: getRevlmClientVersion(),
|
|
233
|
+
baseUrl: this.baseUrl,
|
|
234
|
+
autoSetToken: this.autoSetToken,
|
|
235
|
+
autoRefreshOn401: this.autoRefreshOn401,
|
|
236
|
+
provisionalEnabled: this.provisionalEnabled,
|
|
237
|
+
provisionalAuthDomain: this.provisionalAuthDomain || void 0,
|
|
238
|
+
provisionalAuthSecretMaster: maskSecret(this.provisionalAuthSecretMaster),
|
|
239
|
+
defaultHeaders: Object.keys(this.defaultHeaders || {}),
|
|
240
|
+
fetchImplProvided: !!opts.fetchImpl,
|
|
241
|
+
logLevel: this.logLevel
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
canLog(level) {
|
|
245
|
+
return LOG_LEVEL_RANK[this.logLevel] >= LOG_LEVEL_RANK[level];
|
|
246
|
+
}
|
|
247
|
+
logError(...args) {
|
|
248
|
+
if (this.canLog("error")) console.error(...args);
|
|
249
|
+
}
|
|
250
|
+
logWarn(...args) {
|
|
251
|
+
if (this.canLog("warn")) console.warn(...args);
|
|
252
|
+
}
|
|
253
|
+
logInfo(...args) {
|
|
254
|
+
if (this.canLog("info")) console.log(...args);
|
|
255
|
+
}
|
|
256
|
+
logDebug(...args) {
|
|
257
|
+
if (this.canLog("debug")) console.log(...args);
|
|
238
258
|
}
|
|
239
259
|
setToken(token) {
|
|
240
260
|
this._token = token;
|
|
@@ -259,6 +279,18 @@ var Revlm = class {
|
|
|
259
279
|
}
|
|
260
280
|
return res;
|
|
261
281
|
}
|
|
282
|
+
async refreshTokenSingleFlight() {
|
|
283
|
+
if (!this.refreshPromise) {
|
|
284
|
+
this.refreshPromise = (async () => {
|
|
285
|
+
try {
|
|
286
|
+
return await this.refreshToken();
|
|
287
|
+
} finally {
|
|
288
|
+
this.refreshPromise = void 0;
|
|
289
|
+
}
|
|
290
|
+
})();
|
|
291
|
+
}
|
|
292
|
+
return this.refreshPromise;
|
|
293
|
+
}
|
|
262
294
|
// Verify current token with server. If invalid/expired, clear local token.
|
|
263
295
|
async verifyToken() {
|
|
264
296
|
if (!this._token) return { ok: false, error: "No token set" };
|
|
@@ -334,7 +366,7 @@ var Revlm = class {
|
|
|
334
366
|
if (!payload || typeof payload.exp !== "number") return;
|
|
335
367
|
const now = Math.floor(Date.now() / 1e3);
|
|
336
368
|
const ttlSec = payload.exp - now;
|
|
337
|
-
|
|
369
|
+
this.logDebug("### token ttl", {
|
|
338
370
|
event,
|
|
339
371
|
path,
|
|
340
372
|
ttlSec,
|
|
@@ -372,9 +404,12 @@ var Revlm = class {
|
|
|
372
404
|
}
|
|
373
405
|
if (allowAuthRetry && !retrying && res.status === 401 && !this.shouldSkipAuthRetry(path)) {
|
|
374
406
|
const beforePayload = this.decodeJwtPayload(this._token || "");
|
|
375
|
-
const refreshRes = await this.
|
|
407
|
+
const refreshRes = await this.refreshTokenSingleFlight();
|
|
376
408
|
if (!refreshRes.ok) {
|
|
377
|
-
|
|
409
|
+
if (refreshRes.reason === "not_expired") {
|
|
410
|
+
return this.requestWithRetry(path, method, body, { allowAuthRetry: false, retrying: true });
|
|
411
|
+
}
|
|
412
|
+
this.logDebug("### refresh failed:", {
|
|
378
413
|
reason: refreshRes.reason,
|
|
379
414
|
status: refreshRes.status,
|
|
380
415
|
error: refreshRes.error
|
|
@@ -390,7 +425,7 @@ var Revlm = class {
|
|
|
390
425
|
const now = Math.floor(Date.now() / 1e3);
|
|
391
426
|
const oldExp = beforePayload?.exp;
|
|
392
427
|
const newExp = afterPayload?.exp;
|
|
393
|
-
|
|
428
|
+
this.logDebug("### refresh success", {
|
|
394
429
|
path,
|
|
395
430
|
oldExp,
|
|
396
431
|
newExp,
|
|
@@ -454,13 +489,13 @@ var Revlm = class {
|
|
|
454
489
|
if (this.cookieCheckPromise) return this.cookieCheckPromise;
|
|
455
490
|
this.cookieCheckPromise = (async () => {
|
|
456
491
|
const first = await this.requestWithRetry("/cookie-check", "POST", void 0, { allowAuthRetry: false, retrying: false });
|
|
457
|
-
|
|
492
|
+
this.logDebug("### cookie check", { step: "first", ok: first.ok, reason: first.reason, status: first.status });
|
|
458
493
|
if (first.ok) return;
|
|
459
494
|
if (first.reason !== "cookie_missing") {
|
|
460
495
|
throw new Error(`Cookie check failed: ${first.reason || first.error || "unknown_error"}`);
|
|
461
496
|
}
|
|
462
497
|
const second = await this.requestWithRetry("/cookie-check", "POST", void 0, { allowAuthRetry: false, retrying: false });
|
|
463
|
-
|
|
498
|
+
this.logDebug("### cookie check", { step: "second", ok: second.ok, reason: second.reason, status: second.status });
|
|
464
499
|
if (!second.ok) {
|
|
465
500
|
throw new Error("Cookie support missing. Provide a cookie-aware fetch implementation for Node/RN.");
|
|
466
501
|
}
|
|
@@ -544,7 +579,7 @@ var App = class {
|
|
|
544
579
|
throw new Error("Unsupported credentials type");
|
|
545
580
|
}
|
|
546
581
|
const res = await this.revlm.login(cred.email, cred.password);
|
|
547
|
-
|
|
582
|
+
this.revlm.logInfo("### App:login res:", res);
|
|
548
583
|
if (!res || !res.ok || !res.token) {
|
|
549
584
|
const errMsg = res && !res.ok ? res.error : "login failed";
|
|
550
585
|
const err = new Error(errMsg);
|