@vsaas/loopback 12.1.1 → 12.2.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.
Files changed (117) hide show
  1. package/README.md +6 -0
  2. package/common/models/rate-limit-state.json +121 -0
  3. package/common/models/two-factor-challenge.json +112 -0
  4. package/common/models/two-factor-credential.json +117 -0
  5. package/common/models/two-factor-recovery-code.json +63 -0
  6. package/common/models/user.json +30 -0
  7. package/dist/_virtual/_rolldown/runtime.cjs +9 -2
  8. package/dist/common/models/access-token.d.cts +3 -0
  9. package/dist/common/models/acl.cjs +1 -3
  10. package/dist/common/models/acl.d.cts +1 -0
  11. package/dist/common/models/application.d.cts +3 -0
  12. package/dist/common/models/change.cjs +21 -18
  13. package/dist/common/models/change.d.cts +1 -0
  14. package/dist/common/models/checkpoint.d.cts +3 -0
  15. package/dist/common/models/email.d.cts +3 -0
  16. package/dist/common/models/key-value-model.d.cts +3 -0
  17. package/dist/common/models/rate-limit-state.cjs +7 -0
  18. package/dist/common/models/rate-limit-state.d.cts +3 -0
  19. package/dist/common/models/rate-limit-state2.cjs +109 -0
  20. package/dist/common/models/role-mapping.d.cts +3 -0
  21. package/dist/common/models/role.cjs +12 -8
  22. package/dist/common/models/role.d.cts +1 -0
  23. package/dist/common/models/scope.d.cts +3 -0
  24. package/dist/common/models/two-factor-challenge.cjs +7 -0
  25. package/dist/common/models/two-factor-challenge.d.cts +3 -0
  26. package/dist/common/models/two-factor-challenge2.cjs +108 -0
  27. package/dist/common/models/two-factor-credential.cjs +7 -0
  28. package/dist/common/models/two-factor-credential.d.cts +3 -0
  29. package/dist/common/models/two-factor-credential2.cjs +103 -0
  30. package/dist/common/models/two-factor-recovery-code.cjs +7 -0
  31. package/dist/common/models/two-factor-recovery-code.d.cts +3 -0
  32. package/dist/common/models/two-factor-recovery-code2.cjs +57 -0
  33. package/dist/common/models/user.cjs +261 -21
  34. package/dist/common/models/user.d.cts +3 -0
  35. package/dist/common/models/user2.cjs +30 -0
  36. package/dist/index.cjs +2 -0
  37. package/dist/index.d.cts +3 -0
  38. package/dist/lib/access-context.d.cts +33 -0
  39. package/dist/lib/application.d.cts +1 -0
  40. package/dist/lib/authentication-security-initializer.cjs +351 -0
  41. package/dist/lib/authentication-security-initializer.d.cts +4 -0
  42. package/dist/lib/builtin-models.cjs +12 -0
  43. package/dist/lib/builtin-models.d.cts +3 -0
  44. package/dist/lib/configure-shared-methods.cjs +7 -4
  45. package/dist/lib/configure-shared-methods.d.cts +3 -0
  46. package/dist/lib/connectors/base-connector.d.cts +6 -0
  47. package/dist/lib/connectors/mail-direct-transport.cjs +26 -23
  48. package/dist/lib/connectors/mail-direct-transport.d.cts +22 -0
  49. package/dist/lib/connectors/mail-stub-transport.d.cts +14 -0
  50. package/dist/lib/connectors/mail.d.cts +7 -0
  51. package/dist/lib/connectors/memory.d.cts +6 -0
  52. package/dist/lib/current-context.d.cts +3 -0
  53. package/dist/lib/globalize.d.cts +10 -0
  54. package/dist/lib/loopback.cjs +6 -0
  55. package/dist/lib/loopback.d.cts +1 -0
  56. package/dist/lib/model.d.cts +1 -0
  57. package/dist/lib/persisted-model.cjs +7 -12
  58. package/dist/lib/persisted-model.d.cts +1 -0
  59. package/dist/lib/rate-limit/algorithms/common.cjs +37 -0
  60. package/dist/lib/rate-limit/algorithms/failure-lockout.cjs +70 -0
  61. package/dist/lib/rate-limit/algorithms/fixed-window.cjs +61 -0
  62. package/dist/lib/rate-limit/algorithms/index.cjs +55 -0
  63. package/dist/lib/rate-limit/config.cjs +107 -0
  64. package/dist/lib/rate-limit/errors.cjs +58 -0
  65. package/dist/lib/rate-limit/index.cjs +15 -0
  66. package/dist/lib/rate-limit/index.d.cts +1 -0
  67. package/dist/lib/rate-limit/initializer.cjs +92 -0
  68. package/dist/lib/rate-limit/initializer.d.cts +4 -0
  69. package/dist/lib/rate-limit/limiter.cjs +368 -0
  70. package/dist/lib/rate-limit/registry.cjs +92 -0
  71. package/dist/lib/rate-limit/remote.cjs +180 -0
  72. package/dist/lib/rate-limit/remote.d.cts +6 -0
  73. package/dist/lib/rate-limit/stores/persisted-model.cjs +353 -0
  74. package/dist/lib/rate-limit/subject.cjs +127 -0
  75. package/dist/lib/rate-limit/types.cjs +1 -0
  76. package/dist/lib/rate-limit/types.d.cts +167 -0
  77. package/dist/lib/registry.d.cts +1 -0
  78. package/dist/lib/runtime.d.cts +10 -0
  79. package/dist/lib/server-app.d.cts +3 -0
  80. package/dist/lib/two-factor/config.cjs +199 -0
  81. package/dist/lib/two-factor/config.d.cts +55 -0
  82. package/dist/lib/two-factor/crypto.cjs +68 -0
  83. package/dist/lib/two-factor/crypto.d.cts +16 -0
  84. package/dist/lib/two-factor/errors.cjs +58 -0
  85. package/dist/lib/two-factor/errors.d.cts +18 -0
  86. package/dist/lib/two-factor/rate-limit.cjs +153 -0
  87. package/dist/lib/two-factor/rate-limit.d.cts +22 -0
  88. package/dist/lib/two-factor/recovery-codes.cjs +49 -0
  89. package/dist/lib/two-factor/recovery-codes.d.cts +16 -0
  90. package/dist/lib/two-factor/service.cjs +1108 -0
  91. package/dist/lib/two-factor/service.d.cts +78 -0
  92. package/dist/lib/two-factor/totp.cjs +50 -0
  93. package/dist/lib/two-factor/totp.d.cts +14 -0
  94. package/dist/lib/utils.d.cts +36 -0
  95. package/dist/package.cjs +46 -10
  96. package/dist/server/middleware/context.d.cts +3 -0
  97. package/dist/server/middleware/error-handler.d.cts +3 -0
  98. package/dist/server/middleware/favicon.d.cts +7 -0
  99. package/dist/server/middleware/rest.d.cts +6 -0
  100. package/dist/server/middleware/static.d.cts +3 -0
  101. package/dist/server/middleware/status.d.cts +19 -0
  102. package/dist/server/middleware/token.d.cts +3 -0
  103. package/dist/server/middleware/url-not-found.d.cts +13 -0
  104. package/docs/api-explorer-details.md +110 -0
  105. package/docs/application-guide.md +1110 -0
  106. package/docs/assets/explorer-api.png +0 -0
  107. package/docs/assets/explorer-endpoint.png +0 -0
  108. package/docs/assets/explorer-listing.png +0 -0
  109. package/docs/assets/explorer-req-res.png +0 -0
  110. package/docs/assets/lb-modules.png +0 -0
  111. package/docs/assets/loopback-architecture.png +0 -0
  112. package/docs/assets/loopback-concepts.png +0 -0
  113. package/docs/assets/loopback_ov.png +0 -0
  114. package/docs/rate-limiting.md +879 -0
  115. package/docs/two-factor-authentication.md +611 -0
  116. package/docs/two-factor-authenticator-loss-runbook.md +117 -0
  117. package/package.json +56 -20
@@ -0,0 +1,37 @@
1
+ const require_runtime = require("../../../_virtual/_rolldown/runtime.cjs");
2
+ //#region src/lib/rate-limit/algorithms/common.ts
3
+ function emptyRateLimitState() {
4
+ return {
5
+ failureCount: 0,
6
+ attemptCount: 0,
7
+ lockoutLevel: 0,
8
+ windowStartedAtMs: null,
9
+ lastAttemptAtMs: null,
10
+ lastFailureAtMs: null,
11
+ blockedUntilMs: null
12
+ };
13
+ }
14
+ function cloneRateLimitState(state) {
15
+ const empty = emptyRateLimitState();
16
+ if (!state) return empty;
17
+ for (const key of Object.keys(empty)) {
18
+ const value = state[key];
19
+ if (value !== void 0) empty[key] = value;
20
+ }
21
+ return empty;
22
+ }
23
+ function isBlocked(state, nowMs) {
24
+ return state.blockedUntilMs != null && state.blockedUntilMs > nowMs;
25
+ }
26
+ var init_common = require_runtime.__esmMin((() => {}));
27
+ //#endregion
28
+ init_common();
29
+ exports.cloneRateLimitState = cloneRateLimitState;
30
+ exports.emptyRateLimitState = emptyRateLimitState;
31
+ Object.defineProperty(exports, "init_common", {
32
+ enumerable: true,
33
+ get: function() {
34
+ return init_common;
35
+ }
36
+ });
37
+ exports.isBlocked = isBlocked;
@@ -0,0 +1,70 @@
1
+ const require_runtime = require("../../../_virtual/_rolldown/runtime.cjs");
2
+ const require_common = require("./common.cjs");
3
+ //#region src/lib/rate-limit/algorithms/failure-lockout.ts
4
+ function normalizeFailureWindow(current, policy, nowMs) {
5
+ const state = require_common.cloneRateLimitState(current);
6
+ if (state.blockedUntilMs != null && state.blockedUntilMs <= nowMs) {
7
+ state.blockedUntilMs = null;
8
+ state.failureCount = 0;
9
+ state.windowStartedAtMs = null;
10
+ }
11
+ if (state.windowStartedAtMs != null && state.windowStartedAtMs + policy.observationWindowMs <= nowMs) {
12
+ state.failureCount = 0;
13
+ state.windowStartedAtMs = null;
14
+ }
15
+ if (state.lastFailureAtMs != null && state.lastFailureAtMs + policy.backoffResetAfterMs <= nowMs) state.lockoutLevel = 0;
16
+ return state;
17
+ }
18
+ function inspectFailureLockout(current, policy, nowMs) {
19
+ const state = normalizeFailureWindow(current, policy, nowMs);
20
+ return {
21
+ state,
22
+ allowed: !require_common.isBlocked(state, nowMs),
23
+ blockedUntilMs: require_common.isBlocked(state, nowMs) ? state.blockedUntilMs : null
24
+ };
25
+ }
26
+ function blockDuration(policy, lockoutLevel) {
27
+ if (policy.strategy === "fixed") return policy.blockDurationMs;
28
+ const exponent = Math.min(30, Math.max(0, lockoutLevel - 1));
29
+ return Math.min(policy.maxBlockDurationMs, policy.blockDurationMs * Math.pow(policy.multiplier, exponent));
30
+ }
31
+ function consumeFailureLockout(current, policy, cost, nowMs) {
32
+ const state = normalizeFailureWindow(current, policy, nowMs);
33
+ if (require_common.isBlocked(state, nowMs)) return {
34
+ state,
35
+ allowed: false,
36
+ blockedUntilMs: state.blockedUntilMs
37
+ };
38
+ if (state.windowStartedAtMs == null) state.windowStartedAtMs = nowMs;
39
+ state.lastFailureAtMs = nowMs;
40
+ state.failureCount = Math.min(policy.maxFailedAttempts, state.failureCount + cost);
41
+ if (state.failureCount >= policy.maxFailedAttempts) {
42
+ state.failureCount = 0;
43
+ state.windowStartedAtMs = null;
44
+ state.lockoutLevel += 1;
45
+ state.blockedUntilMs = nowMs + blockDuration(policy, state.lockoutLevel);
46
+ return {
47
+ state,
48
+ allowed: false,
49
+ blockedUntilMs: state.blockedUntilMs
50
+ };
51
+ }
52
+ return {
53
+ state,
54
+ allowed: true,
55
+ blockedUntilMs: null
56
+ };
57
+ }
58
+ var init_failure_lockout = require_runtime.__esmMin((() => {
59
+ require_common.init_common();
60
+ }));
61
+ //#endregion
62
+ init_failure_lockout();
63
+ exports.consumeFailureLockout = consumeFailureLockout;
64
+ Object.defineProperty(exports, "init_failure_lockout", {
65
+ enumerable: true,
66
+ get: function() {
67
+ return init_failure_lockout;
68
+ }
69
+ });
70
+ exports.inspectFailureLockout = inspectFailureLockout;
@@ -0,0 +1,61 @@
1
+ const require_runtime = require("../../../_virtual/_rolldown/runtime.cjs");
2
+ const require_common = require("./common.cjs");
3
+ //#region src/lib/rate-limit/algorithms/fixed-window.ts
4
+ function normalizeWindow(current, policy, nowMs) {
5
+ const state = require_common.cloneRateLimitState(current);
6
+ const blockExpired = state.blockedUntilMs != null && state.blockedUntilMs <= nowMs;
7
+ const windowExpired = state.windowStartedAtMs != null && state.windowStartedAtMs + policy.observationWindowMs <= nowMs;
8
+ if (blockExpired || windowExpired) {
9
+ state.attemptCount = 0;
10
+ state.windowStartedAtMs = null;
11
+ state.blockedUntilMs = null;
12
+ }
13
+ return state;
14
+ }
15
+ function inspectFixedWindow(current, policy, nowMs) {
16
+ const state = normalizeWindow(current, policy, nowMs);
17
+ return {
18
+ state,
19
+ allowed: !require_common.isBlocked(state, nowMs),
20
+ blockedUntilMs: require_common.isBlocked(state, nowMs) ? state.blockedUntilMs : null
21
+ };
22
+ }
23
+ function consumeFixedWindow(current, policy, cost, nowMs) {
24
+ const state = normalizeWindow(current, policy, nowMs);
25
+ if (require_common.isBlocked(state, nowMs)) return {
26
+ state,
27
+ allowed: false,
28
+ blockedUntilMs: state.blockedUntilMs
29
+ };
30
+ if (state.windowStartedAtMs == null) state.windowStartedAtMs = nowMs;
31
+ state.lastAttemptAtMs = nowMs;
32
+ if (cost > Math.max(0, policy.maxAttempts - state.attemptCount)) {
33
+ state.attemptCount = policy.maxAttempts;
34
+ state.blockedUntilMs = nowMs + policy.blockDurationMs;
35
+ return {
36
+ state,
37
+ allowed: false,
38
+ blockedUntilMs: state.blockedUntilMs
39
+ };
40
+ }
41
+ state.attemptCount += cost;
42
+ if (state.attemptCount === policy.maxAttempts) state.blockedUntilMs = nowMs + policy.blockDurationMs;
43
+ return {
44
+ state,
45
+ allowed: true,
46
+ blockedUntilMs: state.blockedUntilMs
47
+ };
48
+ }
49
+ var init_fixed_window = require_runtime.__esmMin((() => {
50
+ require_common.init_common();
51
+ }));
52
+ //#endregion
53
+ init_fixed_window();
54
+ exports.consumeFixedWindow = consumeFixedWindow;
55
+ Object.defineProperty(exports, "init_fixed_window", {
56
+ enumerable: true,
57
+ get: function() {
58
+ return init_fixed_window;
59
+ }
60
+ });
61
+ exports.inspectFixedWindow = inspectFixedWindow;
@@ -0,0 +1,55 @@
1
+ const require_runtime = require("../../../_virtual/_rolldown/runtime.cjs");
2
+ const require_common = require("./common.cjs");
3
+ const require_failure_lockout = require("./failure-lockout.cjs");
4
+ const require_fixed_window = require("./fixed-window.cjs");
5
+ //#region src/lib/rate-limit/algorithms/index.ts
6
+ var algorithms_exports = /* @__PURE__ */ require_runtime.__exportAll({
7
+ cloneRateLimitState: () => require_common.cloneRateLimitState,
8
+ consumeFailureLockout: () => require_failure_lockout.consumeFailureLockout,
9
+ consumeFixedWindow: () => require_fixed_window.consumeFixedWindow,
10
+ consumeState: () => consumeState,
11
+ emptyRateLimitState: () => require_common.emptyRateLimitState,
12
+ inspectFailureLockout: () => require_failure_lockout.inspectFailureLockout,
13
+ inspectFixedWindow: () => require_fixed_window.inspectFixedWindow,
14
+ inspectState: () => inspectState,
15
+ isBlocked: () => require_common.isBlocked
16
+ });
17
+ function inspectState(state, policy, nowMs) {
18
+ if (policy.algorithm === "fixed-window") return require_fixed_window.inspectFixedWindow(state, policy, nowMs);
19
+ return require_failure_lockout.inspectFailureLockout(state, policy, nowMs);
20
+ }
21
+ function consumeState(state, policy, cost, nowMs) {
22
+ if (policy.algorithm === "fixed-window") return require_fixed_window.consumeFixedWindow(state, policy, cost, nowMs);
23
+ return require_failure_lockout.consumeFailureLockout(state, policy, cost, nowMs);
24
+ }
25
+ var init_algorithms = require_runtime.__esmMin((() => {
26
+ require_failure_lockout.init_failure_lockout();
27
+ require_fixed_window.init_fixed_window();
28
+ require_common.init_common();
29
+ }));
30
+ //#endregion
31
+ require_common.init_common();
32
+ require_failure_lockout.init_failure_lockout();
33
+ require_fixed_window.init_fixed_window();
34
+ init_algorithms();
35
+ Object.defineProperty(exports, "algorithms_exports", {
36
+ enumerable: true,
37
+ get: function() {
38
+ return algorithms_exports;
39
+ }
40
+ });
41
+ exports.cloneRateLimitState = require_common.cloneRateLimitState;
42
+ exports.consumeFailureLockout = require_failure_lockout.consumeFailureLockout;
43
+ exports.consumeFixedWindow = require_fixed_window.consumeFixedWindow;
44
+ exports.consumeState = consumeState;
45
+ exports.emptyRateLimitState = require_common.emptyRateLimitState;
46
+ Object.defineProperty(exports, "init_algorithms", {
47
+ enumerable: true,
48
+ get: function() {
49
+ return init_algorithms;
50
+ }
51
+ });
52
+ exports.inspectFailureLockout = require_failure_lockout.inspectFailureLockout;
53
+ exports.inspectFixedWindow = require_fixed_window.inspectFixedWindow;
54
+ exports.inspectState = inspectState;
55
+ exports.isBlocked = require_common.isBlocked;
@@ -0,0 +1,107 @@
1
+ const require_runtime = require("../../_virtual/_rolldown/runtime.cjs");
2
+ const require_errors = require("./errors.cjs");
3
+ const require_subject = require("./subject.cjs");
4
+ //#region src/lib/rate-limit/config.ts
5
+ var config_exports = /* @__PURE__ */ require_runtime.__exportAll({
6
+ canonicalJson: () => canonicalJson,
7
+ fingerprintPolicy: () => fingerprintPolicy,
8
+ normalizeFailureLockoutPolicy: () => normalizeFailureLockoutPolicy,
9
+ normalizeFixedWindowPolicy: () => normalizeFixedWindowPolicy,
10
+ validateRateLimitCost: () => validateRateLimitCost
11
+ });
12
+ function assertInteger(value, name, minimum = 1, maximum = MAX_INTEGER) {
13
+ if (!Number.isSafeInteger(value) || value < minimum || value > maximum) throw require_errors.rateLimitConfigurationError(`${name} must be an integer between ${minimum} and ${maximum}`);
14
+ return value;
15
+ }
16
+ function canonicalize(value) {
17
+ if (Array.isArray(value)) return value.map(canonicalize);
18
+ if (value && typeof value === "object") {
19
+ const output = {};
20
+ for (const key of Object.keys(value).sort()) {
21
+ const current = value[key];
22
+ if (current !== void 0) output[key] = canonicalize(current);
23
+ }
24
+ return output;
25
+ }
26
+ return value;
27
+ }
28
+ function canonicalJson(value) {
29
+ return JSON.stringify(canonicalize(value));
30
+ }
31
+ function fingerprintPolicy(policy) {
32
+ return crypto.createHash("sha256").update(canonicalJson(policy)).digest("hex");
33
+ }
34
+ function normalizeFixedWindowPolicy(input) {
35
+ require_subject.validateSafeIdentifier(input.policyId, "policyId");
36
+ require_subject.validateSafeIdentifier(input.policyVersion, "policyVersion");
37
+ const normalized = {
38
+ policyId: input.policyId,
39
+ policyVersion: input.policyVersion,
40
+ algorithm: "fixed-window",
41
+ maxAttempts: assertInteger(input.maxAttempts, "maxAttempts"),
42
+ observationWindowMs: assertInteger(input.observationWindowMs, "observationWindowMs", 1, MAX_DURATION_MS),
43
+ blockDurationMs: assertInteger(input.blockDurationMs, "blockDurationMs", 1, MAX_DURATION_MS),
44
+ stateTtlMs: assertInteger(input.stateTtlMs, "stateTtlMs", 1, MAX_DURATION_MS)
45
+ };
46
+ if (normalized.stateTtlMs < Math.max(normalized.observationWindowMs, normalized.blockDurationMs)) throw require_errors.rateLimitConfigurationError("stateTtlMs must cover observationWindowMs and blockDurationMs");
47
+ return {
48
+ ...normalized,
49
+ policyFingerprint: fingerprintPolicy(normalized)
50
+ };
51
+ }
52
+ function normalizeFailureLockoutPolicy(input) {
53
+ require_subject.validateSafeIdentifier(input.policyId, "policyId");
54
+ require_subject.validateSafeIdentifier(input.policyVersion, "policyVersion");
55
+ const strategy = input.strategy || "fixed";
56
+ if (strategy !== "fixed" && strategy !== "exponential") throw require_errors.rateLimitConfigurationError("strategy must be fixed or exponential");
57
+ const blockDurationMs = assertInteger(input.blockDurationMs, "blockDurationMs", 1, MAX_DURATION_MS);
58
+ const maxBlockDurationMs = assertInteger(input.maxBlockDurationMs || blockDurationMs, "maxBlockDurationMs", blockDurationMs, MAX_DURATION_MS);
59
+ const normalized = {
60
+ policyId: input.policyId,
61
+ policyVersion: input.policyVersion,
62
+ algorithm: "failure-lockout",
63
+ maxFailedAttempts: assertInteger(input.maxFailedAttempts, "maxFailedAttempts"),
64
+ observationWindowMs: assertInteger(input.observationWindowMs, "observationWindowMs", 1, MAX_DURATION_MS),
65
+ blockDurationMs,
66
+ strategy,
67
+ multiplier: assertInteger(input.multiplier || 2, "multiplier", 1, 100),
68
+ maxBlockDurationMs,
69
+ backoffResetAfterMs: assertInteger(input.backoffResetAfterMs, "backoffResetAfterMs", 1, MAX_DURATION_MS),
70
+ stateTtlMs: assertInteger(input.stateTtlMs, "stateTtlMs", 1, MAX_DURATION_MS)
71
+ };
72
+ if (normalized.stateTtlMs < Math.max(normalized.observationWindowMs, normalized.maxBlockDurationMs, normalized.backoffResetAfterMs)) throw require_errors.rateLimitConfigurationError("stateTtlMs must cover window, maximum block and backoff reset");
73
+ return {
74
+ ...normalized,
75
+ policyFingerprint: fingerprintPolicy(normalized)
76
+ };
77
+ }
78
+ function validateRateLimitCost(cost, maximum = 1e5) {
79
+ return assertInteger(cost, "cost", 1, maximum);
80
+ }
81
+ var crypto, MAX_INTEGER, MAX_DURATION_MS;
82
+ var init_config = require_runtime.__esmMin((() => {
83
+ require_errors.init_errors();
84
+ require_subject.init_subject();
85
+ crypto = require("crypto");
86
+ MAX_INTEGER = 2147483647;
87
+ MAX_DURATION_MS = 31536e6;
88
+ }));
89
+ //#endregion
90
+ init_config();
91
+ exports.canonicalJson = canonicalJson;
92
+ Object.defineProperty(exports, "config_exports", {
93
+ enumerable: true,
94
+ get: function() {
95
+ return config_exports;
96
+ }
97
+ });
98
+ exports.fingerprintPolicy = fingerprintPolicy;
99
+ Object.defineProperty(exports, "init_config", {
100
+ enumerable: true,
101
+ get: function() {
102
+ return init_config;
103
+ }
104
+ });
105
+ exports.normalizeFailureLockoutPolicy = normalizeFailureLockoutPolicy;
106
+ exports.normalizeFixedWindowPolicy = normalizeFixedWindowPolicy;
107
+ exports.validateRateLimitCost = validateRateLimitCost;
@@ -0,0 +1,58 @@
1
+ const require_runtime = require("../../_virtual/_rolldown/runtime.cjs");
2
+ //#region src/lib/rate-limit/errors.ts
3
+ var errors_exports = /* @__PURE__ */ require_runtime.__exportAll({
4
+ RateLimitError: () => RateLimitError,
5
+ rateLimitConfigurationError: () => rateLimitConfigurationError,
6
+ rateLimitUnavailableError: () => rateLimitUnavailableError,
7
+ rateLimitedError: () => rateLimitedError
8
+ });
9
+ function rateLimitedError(blockedUntilMs, nowMs = Date.now(), code = "RATE_LIMITED") {
10
+ const retryAfter = blockedUntilMs == null ? 1 : Math.max(1, Math.ceil((blockedUntilMs - nowMs) / 1e3));
11
+ return new RateLimitError(code, "Too many requests", 429, {
12
+ retryAfter,
13
+ details: { retryAfter }
14
+ });
15
+ }
16
+ function rateLimitUnavailableError(cause, code = "RATE_LIMIT_UNAVAILABLE") {
17
+ return new RateLimitError(code, "Rate limit service unavailable", 503, { cause });
18
+ }
19
+ function rateLimitConfigurationError(message) {
20
+ return new RateLimitError("RATE_LIMIT_CONFIGURATION_INVALID", message, 500);
21
+ }
22
+ var RateLimitError;
23
+ var init_errors = require_runtime.__esmMin((() => {
24
+ RateLimitError = class extends Error {
25
+ code;
26
+ statusCode;
27
+ details;
28
+ retryAfter;
29
+ cause;
30
+ constructor(code, message, statusCode, options = {}) {
31
+ super(message);
32
+ this.name = "RateLimitError";
33
+ this.code = code;
34
+ this.statusCode = statusCode;
35
+ this.cause = options.cause;
36
+ this.details = options.details;
37
+ this.retryAfter = options.retryAfter;
38
+ }
39
+ };
40
+ }));
41
+ //#endregion
42
+ init_errors();
43
+ exports.RateLimitError = RateLimitError;
44
+ Object.defineProperty(exports, "errors_exports", {
45
+ enumerable: true,
46
+ get: function() {
47
+ return errors_exports;
48
+ }
49
+ });
50
+ Object.defineProperty(exports, "init_errors", {
51
+ enumerable: true,
52
+ get: function() {
53
+ return init_errors;
54
+ }
55
+ });
56
+ exports.rateLimitConfigurationError = rateLimitConfigurationError;
57
+ exports.rateLimitUnavailableError = rateLimitUnavailableError;
58
+ exports.rateLimitedError = rateLimitedError;
@@ -0,0 +1,15 @@
1
+ const require_runtime = require("../../_virtual/_rolldown/runtime.cjs");
2
+ const require_errors = require("./errors.cjs");
3
+ const require_subject = require("./subject.cjs");
4
+ const require_config = require("./config.cjs");
5
+ const require_limiter = require("./limiter.cjs");
6
+ const require_index = require("./algorithms/index.cjs");
7
+ const require_persisted_model = require("./stores/persisted-model.cjs");
8
+ const require_registry = require("./registry.cjs");
9
+ const require_lib_rate_limit_remote = require("./remote.cjs");
10
+ //#region src/lib/rate-limit/index.ts
11
+ var require_rate_limit = /* @__PURE__ */ require_runtime.__commonJSMin(((exports, module) => {
12
+ module.exports = Object.assign({}, (require_errors.init_errors(), require_runtime.__toCommonJS(require_errors.errors_exports)), (require_config.init_config(), require_runtime.__toCommonJS(require_config.config_exports)), (require_subject.init_subject(), require_runtime.__toCommonJS(require_subject.subject_exports)), (require_index.init_algorithms(), require_runtime.__toCommonJS(require_index.algorithms_exports)), (require_limiter.init_limiter(), require_runtime.__toCommonJS(require_limiter.limiter_exports)), (require_registry.init_registry(), require_runtime.__toCommonJS(require_registry.registry_exports)), (require_lib_rate_limit_remote.init_remote(), require_runtime.__toCommonJS(require_lib_rate_limit_remote.remote_exports)), (require_persisted_model.init_persisted_model(), require_runtime.__toCommonJS(require_persisted_model.persisted_model_exports)));
13
+ }));
14
+ //#endregion
15
+ module.exports = require_rate_limit();
@@ -0,0 +1 @@
1
+ export {}
@@ -0,0 +1,92 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_runtime = require("../../_virtual/_rolldown/runtime.cjs");
3
+ const require_limiter = require("./limiter.cjs");
4
+ const require_registry = require("./registry.cjs");
5
+ const require_lib_rate_limit_remote = require("./remote.cjs");
6
+ //#region src/lib/rate-limit/initializer.ts
7
+ var initializer_exports = /* @__PURE__ */ require_runtime.__exportAll({ installRateLimiting: () => installRateLimiting });
8
+ function installRateLimiting(app) {
9
+ const registry = new require_registry.RateLimitRegistry(app);
10
+ const limiter = new require_limiter.RateLimiter(registry);
11
+ const registered = new require_limiter.RegisteredRateLimiter(limiter, registry);
12
+ let initialization = null;
13
+ require_lib_rate_limit_remote.installRemoteRateLimiting(app);
14
+ app.rateLimitRegistry = registry;
15
+ app.rateLimiter = registered;
16
+ app.rateLimit = {
17
+ limiter,
18
+ registry,
19
+ get ready() {
20
+ return app.rateLimitReadiness.ready;
21
+ }
22
+ };
23
+ app.rateLimitReadiness = {
24
+ ready: false,
25
+ error: null
26
+ };
27
+ app.registerRateLimitProvider = function(name, factory) {
28
+ registry.registerProvider(name, factory);
29
+ return app;
30
+ };
31
+ app.registerRateLimitStore = function(name, store) {
32
+ registry.registerStore(name, store);
33
+ return app;
34
+ };
35
+ app.registerRateLimitSubjectKeyring = function(name, keyring) {
36
+ registry.registerKeyring(name, keyring);
37
+ return app;
38
+ };
39
+ app.cleanupRateLimitStates = function(options = {}, callback) {
40
+ const promise = Promise.resolve().then(async () => {
41
+ const modelName = options.model || "RateLimitState";
42
+ const model = app.models && app.models[modelName];
43
+ if (!model) throw new Error(`Rate limit state model ${modelName} was not found`);
44
+ return model.destroyAll({ expiresAt: { lt: options.now || /* @__PURE__ */ new Date() } });
45
+ });
46
+ if (typeof callback === "function") {
47
+ promise.then((result) => callback(null, result), callback);
48
+ return;
49
+ }
50
+ return promise;
51
+ };
52
+ app.initializeRateLimiting = function(callback) {
53
+ if (!initialization) initialization = Promise.resolve().then(async () => {
54
+ const config = app.get("rateLimit") || {};
55
+ registered.configureLimits(config.limits || {});
56
+ registry.configure(config);
57
+ await Promise.all(Object.keys(config.stores || {}).map((name) => registry.resolveStore(name)));
58
+ await app.validateRemoteRateLimits();
59
+ registry.freeze();
60
+ app.installRemoteRateLimits();
61
+ app.rateLimitReadiness.ready = true;
62
+ }).catch((error) => {
63
+ app.rateLimitReadiness.error = error;
64
+ throw error;
65
+ });
66
+ if (typeof callback === "function") {
67
+ initialization.then(() => callback(null), callback);
68
+ return;
69
+ }
70
+ return initialization;
71
+ };
72
+ }
73
+ var init_initializer = require_runtime.__esmMin((() => {
74
+ require_limiter.init_limiter();
75
+ require_registry.init_registry();
76
+ require_lib_rate_limit_remote.init_remote();
77
+ }));
78
+ //#endregion
79
+ init_initializer();
80
+ Object.defineProperty(exports, "init_initializer", {
81
+ enumerable: true,
82
+ get: function() {
83
+ return init_initializer;
84
+ }
85
+ });
86
+ Object.defineProperty(exports, "initializer_exports", {
87
+ enumerable: true,
88
+ get: function() {
89
+ return initializer_exports;
90
+ }
91
+ });
92
+ exports.installRateLimiting = installRateLimiting;
@@ -0,0 +1,4 @@
1
+ //#region src/lib/rate-limit/initializer.d.ts
2
+ declare function installRateLimiting(app: any): void;
3
+ //#endregion
4
+ export { installRateLimiting };