@juo/blocks 1.20.1 → 1.21.0
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/core.js +39 -6
- package/dist/services/login/adapter.d.ts +8 -1
- package/dist/services/login/adapter.d.ts.map +1 -1
- package/dist/services/login/errors.d.ts +6 -0
- package/dist/services/login/errors.d.ts.map +1 -1
- package/dist/services/login/index.d.ts +2 -2
- package/dist/services/login/index.d.ts.map +1 -1
- package/dist/services/login/loginService.d.ts.map +1 -1
- package/dist/utils/index.d.ts +5 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/vue/main.d.ts +1 -0
- package/dist/vue/main.d.ts.map +1 -1
- package/dist/vue/useLoginCooldown.d.ts +7 -0
- package/dist/vue/useLoginCooldown.d.ts.map +1 -0
- package/dist/vue/useLoginCooldown.test.d.ts +2 -0
- package/dist/vue/useLoginCooldown.test.d.ts.map +1 -0
- package/dist/vue.js +34 -0
- package/package.json +1 -1
package/dist/core.js
CHANGED
|
@@ -234,6 +234,7 @@ function uuid() {
|
|
|
234
234
|
);
|
|
235
235
|
}
|
|
236
236
|
var AuthenticationErrorReason = /* @__PURE__ */ ((AuthenticationErrorReason2) => {
|
|
237
|
+
AuthenticationErrorReason2["RateLimited"] = "rate-limited";
|
|
237
238
|
AuthenticationErrorReason2["Expired"] = "expired";
|
|
238
239
|
AuthenticationErrorReason2["IncorrectCode"] = "wrong-code";
|
|
239
240
|
AuthenticationErrorReason2["TooManyTries"] = "too-many-tries";
|
|
@@ -251,6 +252,17 @@ class AuthenticationError extends Error {
|
|
|
251
252
|
this.data = data ?? {};
|
|
252
253
|
}
|
|
253
254
|
}
|
|
255
|
+
class RateLimitedError extends AuthenticationError {
|
|
256
|
+
constructor(retryAt) {
|
|
257
|
+
super(
|
|
258
|
+
"rate-limited"
|
|
259
|
+
/* RateLimited */
|
|
260
|
+
);
|
|
261
|
+
/** Epoch milliseconds before which the backend will refuse another login request. */
|
|
262
|
+
__publicField(this, "retryAt");
|
|
263
|
+
this.retryAt = retryAt;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
254
266
|
const OTP_ERROR_REASONS = {
|
|
255
267
|
INCORRECT_CODE: AuthenticationErrorReason.IncorrectCode,
|
|
256
268
|
TOO_MANY_TRIES: AuthenticationErrorReason.TooManyTries,
|
|
@@ -272,6 +284,15 @@ function authenticationErrorFromBody(data) {
|
|
|
272
284
|
const reason = OTP_ERROR_REASONS[code];
|
|
273
285
|
return reason == null ? void 0 : new AuthenticationError(reason);
|
|
274
286
|
}
|
|
287
|
+
function rateLimitErrorFromResponse(res) {
|
|
288
|
+
var _a;
|
|
289
|
+
if (res.status !== 429) {
|
|
290
|
+
return void 0;
|
|
291
|
+
}
|
|
292
|
+
const seconds = (_a = res.headers.get("Retry-After")) == null ? void 0 : _a.trim();
|
|
293
|
+
const delay2 = seconds && /^\d+$/.test(seconds) ? Number(seconds) * 1e3 : 6e4;
|
|
294
|
+
return new RateLimitedError(Date.now() + delay2);
|
|
295
|
+
}
|
|
275
296
|
function createMockLoginAdapter(opts = {}) {
|
|
276
297
|
const appUrl = opts.appUrl ?? "https://admin.juo.io";
|
|
277
298
|
return {
|
|
@@ -310,6 +331,8 @@ function createApiLoginAdapter(fetcher, opts) {
|
|
|
310
331
|
},
|
|
311
332
|
body: JSON.stringify(body)
|
|
312
333
|
});
|
|
334
|
+
const limited = rateLimitErrorFromResponse(res);
|
|
335
|
+
if (limited) throw limited;
|
|
313
336
|
if (res.status === 403) {
|
|
314
337
|
const error = authenticationErrorFromBody(await res.json());
|
|
315
338
|
if (error != null) {
|
|
@@ -345,6 +368,8 @@ function createApiLoginAdapter(fetcher, opts) {
|
|
|
345
368
|
},
|
|
346
369
|
body: JSON.stringify(params)
|
|
347
370
|
});
|
|
371
|
+
const limited = rateLimitErrorFromResponse(res);
|
|
372
|
+
if (limited) throw limited;
|
|
348
373
|
if (res.status === 403) {
|
|
349
374
|
const error = authenticationErrorFromBody(await res.json());
|
|
350
375
|
if (error != null) {
|
|
@@ -417,6 +442,12 @@ function loginService(deps) {
|
|
|
417
442
|
}
|
|
418
443
|
function createLoginService(init) {
|
|
419
444
|
const { adapter, formatError, router, shop, onLoginSuccess } = init;
|
|
445
|
+
function failure(error) {
|
|
446
|
+
return {
|
|
447
|
+
_tag: "Failure",
|
|
448
|
+
error: error instanceof RateLimitedError ? { ...formatError(error), retryAt: error.retryAt } : formatError(error)
|
|
449
|
+
};
|
|
450
|
+
}
|
|
420
451
|
const accessToken = d(null);
|
|
421
452
|
const delegatedToken = d(storage(STORAGE_DELEGATED_TOKEN));
|
|
422
453
|
const refreshToken = d(storage(STORAGE_REFRESH_TOKEN_KEY));
|
|
@@ -489,11 +520,11 @@ function createLoginService(init) {
|
|
|
489
520
|
lang
|
|
490
521
|
});
|
|
491
522
|
if (result._tag === "Failure") {
|
|
492
|
-
return
|
|
523
|
+
return failure(result.error);
|
|
493
524
|
}
|
|
494
525
|
return { _tag: "Success", data: void 0 };
|
|
495
526
|
} catch (error) {
|
|
496
|
-
return
|
|
527
|
+
return failure(error);
|
|
497
528
|
}
|
|
498
529
|
},
|
|
499
530
|
async verify(email, code) {
|
|
@@ -509,13 +540,13 @@ function createLoginService(init) {
|
|
|
509
540
|
code
|
|
510
541
|
});
|
|
511
542
|
if (result._tag === "Failure") {
|
|
512
|
-
return
|
|
543
|
+
return failure(result.error);
|
|
513
544
|
}
|
|
514
545
|
storeTokens(result.data);
|
|
515
546
|
await onSuccess();
|
|
516
547
|
return { _tag: "Success", data: void 0 };
|
|
517
548
|
} catch (error) {
|
|
518
|
-
return
|
|
549
|
+
return failure(error);
|
|
519
550
|
}
|
|
520
551
|
}
|
|
521
552
|
}
|
|
@@ -535,13 +566,13 @@ function createLoginService(init) {
|
|
|
535
566
|
try {
|
|
536
567
|
const result = await adapter.authenticate({ code });
|
|
537
568
|
if (result._tag === "Failure") {
|
|
538
|
-
return
|
|
569
|
+
return failure(result.error);
|
|
539
570
|
}
|
|
540
571
|
storeTokens(result.data);
|
|
541
572
|
await onSuccess();
|
|
542
573
|
return { _tag: "Success", data: void 0 };
|
|
543
574
|
} catch (error) {
|
|
544
|
-
return
|
|
575
|
+
return failure(error);
|
|
545
576
|
}
|
|
546
577
|
}
|
|
547
578
|
},
|
|
@@ -4156,6 +4187,7 @@ export {
|
|
|
4156
4187
|
OrdersServiceContext,
|
|
4157
4188
|
P as PAGE_ROOT_SLOT,
|
|
4158
4189
|
ProductServiceContext,
|
|
4190
|
+
RateLimitedError,
|
|
4159
4191
|
RouterServiceContext,
|
|
4160
4192
|
SUPPORTED_UI_LANGUAGES,
|
|
4161
4193
|
SUPPORTED_UI_LANGUAGE_OPTIONS,
|
|
@@ -4245,6 +4277,7 @@ export {
|
|
|
4245
4277
|
a1 as projectToCss,
|
|
4246
4278
|
p as projectToGridStack,
|
|
4247
4279
|
a2 as provideContext,
|
|
4280
|
+
rateLimitErrorFromResponse,
|
|
4248
4281
|
a3 as readingOrder,
|
|
4249
4282
|
e as reconcileLayout,
|
|
4250
4283
|
a4 as rectsOverlap,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ApiFetcher, Result } from '../../utils';
|
|
2
|
-
import { AuthenticationError } from './errors';
|
|
2
|
+
import { AuthenticationError, RateLimitedError } from './errors';
|
|
3
3
|
export type AuthTokens = {
|
|
4
4
|
access_token: string;
|
|
5
5
|
refresh_token: string;
|
|
@@ -33,6 +33,13 @@ export interface LoginAdapter {
|
|
|
33
33
|
* and translating it to a code is the backend's job.
|
|
34
34
|
*/
|
|
35
35
|
export declare function authenticationErrorFromBody(data: unknown): AuthenticationError | undefined;
|
|
36
|
+
/**
|
|
37
|
+
* Turn a `429` from the auth endpoints into a `RateLimitedError`, or
|
|
38
|
+
* `undefined` for any other status. `Retry-After` is read as delay-seconds; a
|
|
39
|
+
* missing or unparseable header falls back to a minute so the form can't stay
|
|
40
|
+
* blocked forever.
|
|
41
|
+
*/
|
|
42
|
+
export declare function rateLimitErrorFromResponse(res: Pick<Response, "status" | "headers">): RateLimitedError | undefined;
|
|
36
43
|
export declare function createMockLoginAdapter(opts?: {
|
|
37
44
|
appUrl?: string;
|
|
38
45
|
}): LoginAdapter;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/services/login/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/services/login/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EACL,mBAAmB,EAEnB,gBAAgB,EACjB,MAAM,UAAU,CAAC;AAElB,MAAM,MAAM,UAAU,GAAG;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,WAAW,YAAY;IAC3B,iBAAiB,CAAC,MAAM,EAAE;QACxB,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;KACd,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;IAE1B,YAAY,CACV,MAAM,EACF;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAC/B;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAChB;QAAE,YAAY,EAAE,MAAM,CAAA;KAAE,GAC3B,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;IAE/B,eAAe,CAAC,MAAM,EAAE;QACtB,UAAU,EAAE,UAAU,GAAG,eAAe,CAAC;QACzC,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;KACd,GAAG,MAAM,CAAC;CACZ;AAQD;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,CACzC,IAAI,EAAE,OAAO,GACZ,mBAAmB,GAAG,SAAS,CAoBjC;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CACxC,GAAG,EAAE,IAAI,CAAC,QAAQ,EAAE,QAAQ,GAAG,SAAS,CAAC,GACxC,gBAAgB,GAAG,SAAS,CAU9B;AAED,wBAAgB,sBAAsB,CACpC,IAAI,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAO,GAC7B,YAAY,CAwBd;AAED,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,UAAU,EACnB,IAAI,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC3C,YAAY,CA0Gd"}
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* which is what lets the adapter's code lookup be a plain table.
|
|
7
7
|
*/
|
|
8
8
|
export declare enum AuthenticationErrorReason {
|
|
9
|
+
RateLimited = "rate-limited",
|
|
9
10
|
Expired = "expired",
|
|
10
11
|
IncorrectCode = "wrong-code",
|
|
11
12
|
TooManyTries = "too-many-tries",
|
|
@@ -18,4 +19,9 @@ export declare class AuthenticationError extends Error {
|
|
|
18
19
|
data: Record<string, unknown>;
|
|
19
20
|
constructor(reason: AuthenticationErrorReason, data?: Record<string, unknown>);
|
|
20
21
|
}
|
|
22
|
+
export declare class RateLimitedError extends AuthenticationError {
|
|
23
|
+
/** Epoch milliseconds before which the backend will refuse another login request. */
|
|
24
|
+
readonly retryAt: number;
|
|
25
|
+
constructor(retryAt: number);
|
|
26
|
+
}
|
|
21
27
|
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/services/login/errors.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,oBAAY,yBAAyB;IACnC,OAAO,YAAY;IACnB,aAAa,eAAe;IAC5B,YAAY,mBAAmB;IAC/B,OAAO,aAAa;IACpB,OAAO,YAAY;IACnB,OAAO,YAAY;CACpB;AAED,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,MAAM,EAAE,yBAAyB,CAAC;IAClC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAG5B,MAAM,EAAE,yBAAyB,EACjC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAMjC"}
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/services/login/errors.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,oBAAY,yBAAyB;IACnC,WAAW,iBAAiB;IAC5B,OAAO,YAAY;IACnB,aAAa,eAAe;IAC5B,YAAY,mBAAmB;IAC/B,OAAO,aAAa;IACpB,OAAO,YAAY;IACnB,OAAO,YAAY;CACpB;AAED,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,MAAM,EAAE,yBAAyB,CAAC;IAClC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAG5B,MAAM,EAAE,yBAAyB,EACjC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAMjC;AAED,qBAAa,gBAAiB,SAAQ,mBAAmB;IACvD,qFAAqF;IACrF,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;gBAEb,OAAO,EAAE,MAAM;CAI5B"}
|
|
@@ -21,6 +21,6 @@ export declare const LoginServiceContext: {
|
|
|
21
21
|
__context__: LoginService;
|
|
22
22
|
};
|
|
23
23
|
export { loginService, createLoginService, type LoginServiceDependencies, type ErrorFormatter, } from './loginService';
|
|
24
|
-
export { AuthenticationError, AuthenticationErrorReason } from './errors';
|
|
25
|
-
export { type LoginAdapter, type AuthTokens, authenticationErrorFromBody, createApiLoginAdapter, createMockLoginAdapter, } from './adapter';
|
|
24
|
+
export { AuthenticationError, AuthenticationErrorReason, RateLimitedError, } from './errors';
|
|
25
|
+
export { type LoginAdapter, type AuthTokens, authenticationErrorFromBody, rateLimitErrorFromResponse, createApiLoginAdapter, createMockLoginAdapter, } from './adapter';
|
|
26
26
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/login/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAE9C,OAAO,EAAE,MAAM,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAExD,KAAK,YAAY,GAAG;IAClB,YAAY,EAAE;QACZ,KAAK,EAAE;YACL,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC;YAC1D,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC;SAC1E,CAAC;KACH,CAAC;IAEF,MAAM,EAAE;QACN,KAAK,CAAC,QAAQ,EAAE,QAAQ,GAAG,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC;QAC5E,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC;KAC3D,CAAC;IAEF,eAAe,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAEjC,QAAQ,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAEnC,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAElD,iBAAiB,CACf,KAAK,EAAE,eAAe,GACrB,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC;IAEvC,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;CAC3B,CAAC;AAEF,eAAO,MAAM,mBAAmB;;CACe,CAAC;AAEhD,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,KAAK,wBAAwB,EAC7B,KAAK,cAAc,GACpB,MAAM,gBAAgB,CAAC;AAExB,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/login/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAE9C,OAAO,EAAE,MAAM,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAExD,KAAK,YAAY,GAAG;IAClB,YAAY,EAAE;QACZ,KAAK,EAAE;YACL,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC;YAC1D,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC;SAC1E,CAAC;KACH,CAAC;IAEF,MAAM,EAAE;QACN,KAAK,CAAC,QAAQ,EAAE,QAAQ,GAAG,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC;QAC5E,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC;KAC3D,CAAC;IAEF,eAAe,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IAEjC,QAAQ,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAEnC,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAElD,iBAAiB,CACf,KAAK,EAAE,eAAe,GACrB,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC;IAEvC,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;CAC3B,CAAC;AAEF,eAAO,MAAM,mBAAmB;;CACe,CAAC;AAEhD,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,KAAK,wBAAwB,EAC7B,KAAK,cAAc,GACpB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,mBAAmB,EACnB,yBAAyB,EACzB,gBAAgB,GACjB,MAAM,UAAU,CAAC;AAElB,OAAO,EACL,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,2BAA2B,EAC3B,0BAA0B,EAC1B,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,WAAW,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loginService.d.ts","sourceRoot":"","sources":["../../../src/services/login/loginService.ts"],"names":[],"mappings":"AAEA,OAAO,EAA4B,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAKxE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAE9C,OAAO,
|
|
1
|
+
{"version":3,"file":"loginService.d.ts","sourceRoot":"","sources":["../../../src/services/login/loginService.ts"],"names":[],"mappings":"AAEA,OAAO,EAA4B,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAKxE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAE9C,OAAO,EACL,mBAAmB,EACnB,yBAAyB,EAE1B,MAAM,UAAU,CAAC;AAElB,UAAU,aAAa;IACrB,IAAI,CAAC,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,GAAG,IAAI,CAAC;IACtE,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,UAAU,WAAW;IACnB,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;CAChB;AA0BD,MAAM,MAAM,cAAc,GAAG,CAAC,KAAK,EAAE,OAAO,GAAG,mBAAmB,KAAK;IACrE,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,yBAAyB,CAAC;CACpC,CAAC;AAEF,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,YAAY,CAAC;IACtB,WAAW,EAAE,cAAc,CAAC;IAC5B,MAAM,EAAE,aAAa,CAAC;IACtB,IAAI,EAAE,WAAW,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACtC;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE;IACjC,WAAW,EAAE,cAAc,CAAC;IAC5B,SAAS,EAAE,MAAM,MAAM,CAAC;IACxB,MAAM,EAAE,aAAa,CAAC;IACtB,IAAI,EAAE;QACJ,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,cAAc,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACtC;;;;;;;;;;;;;;;;EAmBA;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,wBAAwB;;;;;;;;;;;;;;;;EAkOhE"}
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -27,6 +27,11 @@ export type ErrorDetails = {
|
|
|
27
27
|
* Values are `AuthenticationErrorReason` members.
|
|
28
28
|
*/
|
|
29
29
|
reason?: string;
|
|
30
|
+
/**
|
|
31
|
+
* Epoch milliseconds before which the backend will refuse another login
|
|
32
|
+
* request. Present when `reason` is rate-limited.
|
|
33
|
+
*/
|
|
34
|
+
retryAt?: number;
|
|
30
35
|
};
|
|
31
36
|
export type Image = {
|
|
32
37
|
url: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,OAAO,CAAC,CAAC,GAAG,OAAO,IAAI;IACjC,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,CAAC,CAAC;CACV,CAAC;AAEF,MAAM,MAAM,OAAO,CAAC,CAAC,GAAG,IAAI,IAAI;IAC9B,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,CAAC,CAAC;CACT,CAAC;AAEF,MAAM,MAAM,MAAM,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,OAAO,IAAI,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;AAEpE,MAAM,WAAW,QAAQ;IACvB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa,CAAC,CAAC;IAC9B,KAAK,EAAE,CAAC,EAAE,CAAC;IACX,QAAQ,EAAE,QAAQ,CAAC;CACpB;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,OAAO,CAAC,CAAC,GAAG,OAAO,IAAI;IACjC,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,CAAC,CAAC;CACV,CAAC;AAEF,MAAM,MAAM,OAAO,CAAC,CAAC,GAAG,IAAI,IAAI;IAC9B,IAAI,EAAE,SAAS,CAAC;IAChB,IAAI,EAAE,CAAC,CAAC;CACT,CAAC;AAEF,MAAM,MAAM,MAAM,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,OAAO,IAAI,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;AAEpE,MAAM,WAAW,QAAQ;IACvB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa,CAAC,CAAC;IAC9B,KAAK,EAAE,CAAC,EAAE,CAAC;IACX,QAAQ,EAAE,QAAQ,CAAC;CACpB;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,KAAK,GAAG;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;AACjF,cAAc,UAAU,CAAC"}
|
package/dist/vue/main.d.ts
CHANGED
package/dist/vue/main.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/vue/main.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC"}
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/vue/main.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,cAAc,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { MaybeRefOrGetter } from 'vue';
|
|
2
|
+
export declare function useLoginCooldown(deadline: MaybeRefOrGetter<number | null>): {
|
|
3
|
+
remainingSeconds: import('vue').ComputedRef<number>;
|
|
4
|
+
remainingTime: import('vue').ComputedRef<string>;
|
|
5
|
+
isBlocked: import('vue').ComputedRef<boolean>;
|
|
6
|
+
};
|
|
7
|
+
//# sourceMappingURL=useLoginCooldown.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useLoginCooldown.d.ts","sourceRoot":"","sources":["../../src/vue/useLoginCooldown.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,gBAAgB,EACtB,MAAM,KAAK,CAAC;AAEb,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,gBAAgB,CAAC,MAAM,GAAG,IAAI,CAAC;;;;EAsCzE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useLoginCooldown.test.d.ts","sourceRoot":"","sources":["../../src/vue/useLoginCooldown.test.ts"],"names":[],"mappings":""}
|
package/dist/vue.js
CHANGED
|
@@ -346,6 +346,39 @@ function useBridge(options) {
|
|
|
346
346
|
});
|
|
347
347
|
return { isEditorMode: isEditorMode.value };
|
|
348
348
|
}
|
|
349
|
+
function useLoginCooldown(deadline) {
|
|
350
|
+
const retryAt = computed(() => toValue(deadline) ?? 0);
|
|
351
|
+
const now = ref(Date.now());
|
|
352
|
+
const remainingSeconds = computed(
|
|
353
|
+
() => Math.max(0, Math.ceil((retryAt.value - now.value) / 1e3))
|
|
354
|
+
);
|
|
355
|
+
const remainingTime = computed(() => {
|
|
356
|
+
const minutes = Math.floor(remainingSeconds.value / 60);
|
|
357
|
+
const seconds = remainingSeconds.value % 60;
|
|
358
|
+
return `${String(minutes).padStart(2, "0")}:${String(seconds).padStart(2, "0")}`;
|
|
359
|
+
});
|
|
360
|
+
const isBlocked = computed(() => remainingSeconds.value > 0);
|
|
361
|
+
let timer;
|
|
362
|
+
function stop() {
|
|
363
|
+
clearInterval(timer);
|
|
364
|
+
timer = void 0;
|
|
365
|
+
}
|
|
366
|
+
watch(
|
|
367
|
+
retryAt,
|
|
368
|
+
(value) => {
|
|
369
|
+
stop();
|
|
370
|
+
now.value = Date.now();
|
|
371
|
+
if (value <= now.value) return;
|
|
372
|
+
timer = setInterval(() => {
|
|
373
|
+
now.value = Date.now();
|
|
374
|
+
if (!isBlocked.value) stop();
|
|
375
|
+
}, 250);
|
|
376
|
+
},
|
|
377
|
+
{ immediate: true, flush: "sync" }
|
|
378
|
+
);
|
|
379
|
+
onScopeDispose(stop);
|
|
380
|
+
return { remainingSeconds, remainingTime, isBlocked };
|
|
381
|
+
}
|
|
349
382
|
export {
|
|
350
383
|
ContextProvider,
|
|
351
384
|
createVueCeRenderer,
|
|
@@ -357,6 +390,7 @@ export {
|
|
|
357
390
|
useBlockType,
|
|
358
391
|
useBridge,
|
|
359
392
|
useContext,
|
|
393
|
+
useLoginCooldown,
|
|
360
394
|
useProvideContext,
|
|
361
395
|
useProvideContextProvider,
|
|
362
396
|
useRegisterTranslationKeys,
|