@zintrust/core 0.1.41 → 0.1.42

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 (193) hide show
  1. package/package.json +17 -1
  2. package/src/boot/bootstrap.js +27 -11
  3. package/src/boot/registry/runtime.d.ts.map +1 -1
  4. package/src/boot/registry/runtime.js +11 -0
  5. package/src/cli/CLI.d.ts.map +1 -1
  6. package/src/cli/CLI.js +12 -0
  7. package/src/cli/commands/ConfigCommand.d.ts.map +1 -1
  8. package/src/cli/commands/ConfigCommand.js +3 -5
  9. package/src/cli/commands/D1LearnCommand.d.ts +9 -0
  10. package/src/cli/commands/D1LearnCommand.d.ts.map +1 -0
  11. package/src/cli/commands/D1LearnCommand.js +143 -0
  12. package/src/cli/commands/D1MigrateCommand.d.ts.map +1 -1
  13. package/src/cli/commands/D1MigrateCommand.js +55 -16
  14. package/src/cli/commands/InitContainerCommand.d.ts.map +1 -1
  15. package/src/cli/commands/InitContainerCommand.js +21 -6
  16. package/src/cli/commands/InitEcosystemCommand.d.ts +6 -0
  17. package/src/cli/commands/InitEcosystemCommand.d.ts.map +1 -0
  18. package/src/cli/commands/InitEcosystemCommand.js +51 -0
  19. package/src/cli/commands/MigrateCommand.d.ts.map +1 -1
  20. package/src/cli/commands/MigrateCommand.js +78 -36
  21. package/src/cli/commands/MigrateWorkerCommand.d.ts.map +1 -1
  22. package/src/cli/commands/MigrateWorkerCommand.js +36 -2
  23. package/src/cli/commands/PutCommand.d.ts +6 -0
  24. package/src/cli/commands/PutCommand.d.ts.map +1 -0
  25. package/src/cli/commands/PutCommand.js +173 -0
  26. package/src/cli/commands/QueueRecoveryCommand.d.ts.map +1 -1
  27. package/src/cli/commands/QueueRecoveryCommand.js +113 -14
  28. package/src/cli/commands/ScheduleListCommand.d.ts +6 -0
  29. package/src/cli/commands/ScheduleListCommand.d.ts.map +1 -0
  30. package/src/cli/commands/ScheduleListCommand.js +62 -0
  31. package/src/cli/commands/ScheduleRunCommand.d.ts +6 -0
  32. package/src/cli/commands/ScheduleRunCommand.d.ts.map +1 -0
  33. package/src/cli/commands/ScheduleRunCommand.js +32 -0
  34. package/src/cli/commands/ScheduleStartCommand.d.ts +6 -0
  35. package/src/cli/commands/ScheduleStartCommand.d.ts.map +1 -0
  36. package/src/cli/commands/ScheduleStartCommand.js +40 -0
  37. package/src/cli/commands/SecretsCommand.d.ts.map +1 -1
  38. package/src/cli/commands/SecretsCommand.js +2 -2
  39. package/src/cli/commands/schedule/ScheduleCliSupport.d.ts +6 -0
  40. package/src/cli/commands/schedule/ScheduleCliSupport.d.ts.map +1 -0
  41. package/src/cli/commands/schedule/ScheduleCliSupport.js +55 -0
  42. package/src/cli/config/ConfigManager.d.ts.map +1 -1
  43. package/src/cli/config/ConfigManager.js +8 -1
  44. package/src/cli/d1/D1SqlMigrations.d.ts.map +1 -1
  45. package/src/cli/d1/D1SqlMigrations.js +11 -1
  46. package/src/cli/d1/WranglerConfig.d.ts.map +1 -1
  47. package/src/cli/d1/WranglerConfig.js +34 -2
  48. package/src/cli/services/VersionChecker.d.ts.map +1 -1
  49. package/src/cli/services/VersionChecker.js +5 -1
  50. package/src/cli/utils/DatabaseCliUtils.d.ts.map +1 -1
  51. package/src/cli/utils/DatabaseCliUtils.js +6 -1
  52. package/src/cli/utils/EnvFileLoader.d.ts.map +1 -1
  53. package/src/cli/utils/EnvFileLoader.js +33 -14
  54. package/src/cli.d.ts +5 -0
  55. package/src/cli.d.ts.map +1 -0
  56. package/src/cli.js +4 -0
  57. package/src/collections/index.d.ts +2 -2
  58. package/src/collections/index.d.ts.map +1 -1
  59. package/src/collections/index.js +1 -1
  60. package/src/common/RemoteSignedJson.d.ts.map +1 -1
  61. package/src/common/RemoteSignedJson.js +49 -23
  62. package/src/common/utility.d.ts.map +1 -1
  63. package/src/common/utility.js +2 -6
  64. package/src/config/cloudflare.d.ts.map +1 -1
  65. package/src/config/cloudflare.js +19 -8
  66. package/src/config/env.js +2 -2
  67. package/src/helper/index.d.ts +225 -0
  68. package/src/helper/index.d.ts.map +1 -0
  69. package/src/helper/index.js +347 -0
  70. package/src/index.d.ts +3 -6
  71. package/src/index.d.ts.map +1 -1
  72. package/src/index.js +7 -9
  73. package/src/migrations/MigrationDiscovery.d.ts.map +1 -1
  74. package/src/migrations/MigrationDiscovery.js +2 -1
  75. package/src/orm/DatabaseAdapter.d.ts +1 -0
  76. package/src/orm/DatabaseAdapter.d.ts.map +1 -1
  77. package/src/orm/SchemaStatemenWriter.d.ts +15 -0
  78. package/src/orm/SchemaStatemenWriter.d.ts.map +1 -0
  79. package/src/orm/SchemaStatemenWriter.js +78 -0
  80. package/src/orm/adapters/D1Adapter.d.ts.map +1 -1
  81. package/src/orm/adapters/D1Adapter.js +52 -2
  82. package/src/orm/adapters/D1RemoteAdapter.d.ts.map +1 -1
  83. package/src/orm/adapters/D1RemoteAdapter.js +137 -89
  84. package/src/orm/adapters/MySQLProxyAdapter.d.ts.map +1 -1
  85. package/src/orm/adapters/MySQLProxyAdapter.js +100 -81
  86. package/src/orm/adapters/PostgreSQLProxyAdapter.d.ts.map +1 -1
  87. package/src/orm/adapters/PostgreSQLProxyAdapter.js +26 -10
  88. package/src/orm/adapters/SqlProxyAdapterUtils.d.ts.map +1 -1
  89. package/src/orm/adapters/SqlProxyAdapterUtils.js +2 -1
  90. package/src/orm/adapters/SqlProxyRegistryMode.d.ts +12 -0
  91. package/src/orm/adapters/SqlProxyRegistryMode.d.ts.map +1 -0
  92. package/src/orm/adapters/SqlProxyRegistryMode.js +24 -0
  93. package/src/orm/adapters/SqlServerProxyAdapter.d.ts +3 -0
  94. package/src/orm/adapters/SqlServerProxyAdapter.d.ts.map +1 -1
  95. package/src/orm/adapters/SqlServerProxyAdapter.js +125 -117
  96. package/src/orm/migrations/MigrationStore.js +1 -1
  97. package/src/proxy/ProxyRequestParsing.d.ts +9 -0
  98. package/src/proxy/ProxyRequestParsing.d.ts.map +1 -0
  99. package/src/proxy/ProxyRequestParsing.js +16 -0
  100. package/src/proxy/RequestValidator.d.ts.map +1 -1
  101. package/src/proxy/RequestValidator.js +2 -1
  102. package/src/proxy/SigningService.js +2 -2
  103. package/src/proxy/SqlProxyDbOverrides.d.ts +17 -0
  104. package/src/proxy/SqlProxyDbOverrides.d.ts.map +1 -0
  105. package/src/proxy/SqlProxyDbOverrides.js +1 -0
  106. package/src/proxy/SqlProxyServerDeps.d.ts +12 -0
  107. package/src/proxy/SqlProxyServerDeps.d.ts.map +1 -0
  108. package/src/proxy/SqlProxyServerDeps.js +9 -0
  109. package/src/proxy/StatementPayloadValidator.d.ts +13 -0
  110. package/src/proxy/StatementPayloadValidator.d.ts.map +1 -0
  111. package/src/proxy/StatementPayloadValidator.js +18 -0
  112. package/src/proxy/StatementRegistryLoader.d.ts +2 -0
  113. package/src/proxy/StatementRegistryLoader.d.ts.map +1 -0
  114. package/src/proxy/StatementRegistryLoader.js +36 -0
  115. package/src/proxy/StatementRegistryResolver.d.ts +15 -0
  116. package/src/proxy/StatementRegistryResolver.d.ts.map +1 -0
  117. package/src/proxy/StatementRegistryResolver.js +34 -0
  118. package/src/proxy/d1/ZintrustD1Proxy.d.ts +2 -1
  119. package/src/proxy/d1/ZintrustD1Proxy.d.ts.map +1 -1
  120. package/src/proxy/d1/ZintrustD1Proxy.js +2 -1
  121. package/src/proxy/isMutatingSql.d.ts +2 -0
  122. package/src/proxy/isMutatingSql.d.ts.map +1 -0
  123. package/src/proxy/isMutatingSql.js +12 -0
  124. package/src/proxy/kv/ZintrustKvProxy.d.ts +2 -1
  125. package/src/proxy/kv/ZintrustKvProxy.d.ts.map +1 -1
  126. package/src/proxy/kv/ZintrustKvProxy.js +2 -1
  127. package/src/proxy/mysql/MySqlProxyServer.d.ts +2 -8
  128. package/src/proxy/mysql/MySqlProxyServer.d.ts.map +1 -1
  129. package/src/proxy/mysql/MySqlProxyServer.js +84 -51
  130. package/src/proxy/postgres/PostgresProxyServer.d.ts +2 -8
  131. package/src/proxy/postgres/PostgresProxyServer.d.ts.map +1 -1
  132. package/src/proxy/postgres/PostgresProxyServer.js +86 -48
  133. package/src/proxy/smtp/SmtpProxyServer.d.ts.map +1 -1
  134. package/src/proxy/smtp/SmtpProxyServer.js +6 -5
  135. package/src/proxy/sqlserver/SqlServerProxyServer.d.ts +2 -8
  136. package/src/proxy/sqlserver/SqlServerProxyServer.d.ts.map +1 -1
  137. package/src/proxy/sqlserver/SqlServerProxyServer.js +84 -49
  138. package/src/proxy.d.ts +4 -0
  139. package/src/proxy.d.ts.map +1 -0
  140. package/src/proxy.js +3 -0
  141. package/src/scheduler/Schedule.d.ts +36 -0
  142. package/src/scheduler/Schedule.d.ts.map +1 -0
  143. package/src/scheduler/Schedule.js +197 -0
  144. package/src/scheduler/ScheduleHttpGateway.d.ts +8 -0
  145. package/src/scheduler/ScheduleHttpGateway.d.ts.map +1 -0
  146. package/src/scheduler/ScheduleHttpGateway.js +196 -0
  147. package/src/scheduler/ScheduleRunner.d.ts +6 -0
  148. package/src/scheduler/ScheduleRunner.d.ts.map +1 -1
  149. package/src/scheduler/ScheduleRunner.js +166 -29
  150. package/src/scheduler/SchedulerRuntime.d.ts +15 -0
  151. package/src/scheduler/SchedulerRuntime.d.ts.map +1 -0
  152. package/src/scheduler/SchedulerRuntime.js +79 -0
  153. package/src/scheduler/cron/Cron.d.ts +19 -0
  154. package/src/scheduler/cron/Cron.d.ts.map +1 -0
  155. package/src/scheduler/cron/Cron.js +200 -0
  156. package/src/scheduler/leader/SchedulerLeader.d.ts +14 -0
  157. package/src/scheduler/leader/SchedulerLeader.d.ts.map +1 -0
  158. package/src/scheduler/leader/SchedulerLeader.js +187 -0
  159. package/src/scheduler/state/ScheduleStateStore.d.ts +27 -0
  160. package/src/scheduler/state/ScheduleStateStore.d.ts.map +1 -0
  161. package/src/scheduler/state/ScheduleStateStore.js +27 -0
  162. package/src/scheduler/types.d.ts +10 -0
  163. package/src/scheduler/types.d.ts.map +1 -1
  164. package/src/schedules/index.d.ts +1 -0
  165. package/src/schedules/index.d.ts.map +1 -1
  166. package/src/schedules/index.js +1 -0
  167. package/src/schedules/job-tracking-cleanup.d.ts +4 -0
  168. package/src/schedules/job-tracking-cleanup.d.ts.map +1 -0
  169. package/src/schedules/job-tracking-cleanup.js +116 -0
  170. package/src/schedules/log-cleanup.d.ts +1 -2
  171. package/src/schedules/log-cleanup.d.ts.map +1 -1
  172. package/src/schedules/log-cleanup.js +12 -15
  173. package/src/security/Sanitizer.d.ts.map +1 -1
  174. package/src/security/Sanitizer.js +1 -9
  175. package/src/security/SignedRequest.d.ts.map +1 -1
  176. package/src/security/SignedRequest.js +2 -2
  177. package/src/templates/docker/docker-compose.ecosystem.yml.tpl +301 -0
  178. package/src/templates/docker/docker-compose.schedules.yml.tpl +84 -0
  179. package/src/templates/project/basic/app/Schedules/index.ts.tpl +0 -0
  180. package/src/templates/project/basic/config/database.ts.tpl +1 -1
  181. package/src/toolkit/Secrets/Manifest.d.ts.map +1 -1
  182. package/src/toolkit/Secrets/Manifest.js +5 -7
  183. package/src/tools/mail/drivers/Smtp.d.ts.map +1 -1
  184. package/src/tools/mail/drivers/Smtp.js +7 -1
  185. package/src/tools/queue/JobReconciliationRunner.d.ts.map +1 -1
  186. package/src/tools/queue/JobReconciliationRunner.js +7 -39
  187. package/src/tools/queue/JobRecoveryDaemon.d.ts.map +1 -1
  188. package/src/tools/queue/JobRecoveryDaemon.js +116 -18
  189. package/src/tools/queue/JobStateTracker.d.ts +10 -1
  190. package/src/tools/queue/JobStateTracker.d.ts.map +1 -1
  191. package/src/tools/queue/JobStateTracker.js +24 -2
  192. package/src/tools/queue/JobStateTrackerDbPersistence.d.ts.map +1 -1
  193. package/src/tools/queue/JobStateTrackerDbPersistence.js +93 -2
@@ -0,0 +1,187 @@
1
+ import { Env } from '../../config/env.js';
2
+ import { Logger } from '../../config/logger.js';
3
+ import { ErrorFactory } from '../../exceptions/ZintrustError.js';
4
+ import { ZintrustLang } from '../../lang/lang.js';
5
+ import { createAdvancedQueue } from '../../tools/queue/AdvancedQueue.js';
6
+ import { getLockProvider } from '../../tools/queue/LockProvider.js';
7
+ const readSettings = () => {
8
+ const enabled = Env.getBool('SCHEDULE_LEADER_ENABLED', false);
9
+ const provider = Env.get('SCHEDULE_LEADER_LOCK_PROVIDER', 'redis').trim() || 'redis';
10
+ const key = Env.get('SCHEDULE_LEADER_LOCK_KEY', 'scheduler:leader').trim() || 'scheduler:leader';
11
+ const ttlMs = Env.getInt('SCHEDULE_LEADER_LOCK_TTL_MS', 30000);
12
+ const renewEveryMs = Env.getInt('SCHEDULE_LEADER_LOCK_RENEW_MS', Math.floor(ttlMs / 2));
13
+ const retryEveryMs = Env.getInt('SCHEDULE_LEADER_LOCK_RETRY_MS', 5000);
14
+ const acquireTimeoutMs = Env.getInt('SCHEDULE_LEADER_LOCK_ACQUIRE_TIMEOUT_MS', 2000);
15
+ return Object.freeze({
16
+ enabled,
17
+ provider,
18
+ key,
19
+ ttlMs: Math.max(1000, ttlMs),
20
+ renewEveryMs: Math.max(250, renewEveryMs),
21
+ retryEveryMs: Math.max(250, retryEveryMs),
22
+ acquireTimeoutMs: Math.max(250, acquireTimeoutMs),
23
+ });
24
+ };
25
+ const isUnrefableTimer = (timer) => {
26
+ return (typeof timer === 'object' &&
27
+ timer !== null &&
28
+ 'unref' in timer &&
29
+ typeof timer.unref === 'function');
30
+ };
31
+ const withTimeout = async (promise, timeoutMs) => {
32
+ if (!Number.isFinite(timeoutMs) || timeoutMs <= 0)
33
+ return promise;
34
+ let timeoutId;
35
+ try {
36
+ return await Promise.race([
37
+ promise,
38
+ new Promise((_, reject) => {
39
+ timeoutId = globalThis.setTimeout(() => {
40
+ reject(ErrorFactory.createConnectionError('Leader lock acquire timed out', { timeoutMs }));
41
+ }, timeoutMs);
42
+ }),
43
+ ]);
44
+ }
45
+ finally {
46
+ if (timeoutId !== undefined)
47
+ globalThis.clearTimeout(timeoutId);
48
+ }
49
+ };
50
+ const resolveProvider = (providerName, ttlMs) => {
51
+ const name = providerName.trim().toLowerCase();
52
+ if (name.length === 0)
53
+ return null;
54
+ // Ensure provider is registered; AdvancedQueue wiring bootstraps lock providers.
55
+ createAdvancedQueue({
56
+ name: ZintrustLang.CLI_LOCKS,
57
+ connection: undefined,
58
+ defaultDedupTtl: ttlMs,
59
+ lockProvider: name,
60
+ });
61
+ return getLockProvider(name) ?? null;
62
+ };
63
+ const clearTimers = (state) => {
64
+ if (state.renewTimer !== undefined) {
65
+ globalThis.clearInterval(state.renewTimer);
66
+ state.renewTimer = undefined;
67
+ }
68
+ if (state.retryTimer !== undefined) {
69
+ globalThis.clearInterval(state.retryTimer);
70
+ state.retryTimer = undefined;
71
+ }
72
+ };
73
+ const loseLeadership = (state) => {
74
+ if (state.leaderLock !== null) {
75
+ Logger.warn('Scheduler leadership lost; stopping schedules');
76
+ }
77
+ state.leaderLock = null;
78
+ state.hooks?.onLostLeadership();
79
+ };
80
+ const ensureProvider = (state, settings) => {
81
+ if (state.provider !== null)
82
+ return state.provider;
83
+ state.provider = resolveProvider(settings.provider, settings.ttlMs);
84
+ if (state.provider === null) {
85
+ Logger.warn('Leader lock provider not available; scheduling disabled', {
86
+ provider: settings.provider,
87
+ });
88
+ }
89
+ return state.provider;
90
+ };
91
+ const tryAcquire = async (state, settings) => {
92
+ if (!state.started)
93
+ return;
94
+ if (state.leaderLock !== null)
95
+ return;
96
+ const provider = ensureProvider(state, settings);
97
+ if (provider === null)
98
+ return;
99
+ try {
100
+ const lock = await withTimeout(provider.acquire(settings.key, { ttl: settings.ttlMs }), settings.acquireTimeoutMs);
101
+ if (!lock.acquired)
102
+ return;
103
+ state.leaderLock = lock;
104
+ Logger.info('Scheduler leadership acquired', { key: settings.key, ttlMs: settings.ttlMs });
105
+ state.hooks?.onBecameLeader();
106
+ }
107
+ catch (error) {
108
+ Logger.warn('Failed to acquire scheduler leader lock', {
109
+ key: settings.key,
110
+ provider: settings.provider,
111
+ message: error instanceof Error ? error.message : String(error),
112
+ });
113
+ }
114
+ };
115
+ const startRenewLoop = (state, settings) => {
116
+ if (state.renewTimer !== undefined)
117
+ return;
118
+ state.renewTimer = globalThis.setInterval(async () => {
119
+ if (!state.started)
120
+ return;
121
+ if (state.leaderLock === null || state.provider === null)
122
+ return;
123
+ const ok = await state.provider.extend(state.leaderLock, settings.ttlMs);
124
+ if (!ok)
125
+ loseLeadership(state);
126
+ }, settings.renewEveryMs);
127
+ if (isUnrefableTimer(state.renewTimer))
128
+ state.renewTimer.unref();
129
+ };
130
+ const startRetryLoop = (state, settings) => {
131
+ if (state.retryTimer !== undefined)
132
+ return;
133
+ state.retryTimer = globalThis.setInterval(() => {
134
+ void tryAcquire(state, settings);
135
+ }, settings.retryEveryMs);
136
+ if (isUnrefableTimer(state.retryTimer))
137
+ state.retryTimer.unref();
138
+ };
139
+ export const SchedulerLeader = Object.freeze({
140
+ create() {
141
+ const state = {
142
+ started: false,
143
+ leaderLock: null,
144
+ provider: null,
145
+ renewTimer: undefined,
146
+ retryTimer: undefined,
147
+ hooks: null,
148
+ };
149
+ return Object.freeze({
150
+ isEnabled() {
151
+ return readSettings().enabled;
152
+ },
153
+ start(newHooks) {
154
+ const settings = readSettings();
155
+ if (!settings.enabled)
156
+ return;
157
+ if (state.started)
158
+ return;
159
+ state.started = true;
160
+ state.hooks = newHooks;
161
+ state.provider = null;
162
+ // Attempt immediately; keep retrying until acquired.
163
+ void tryAcquire(state, settings);
164
+ startRetryLoop(state, settings);
165
+ startRenewLoop(state, settings);
166
+ },
167
+ async stop() {
168
+ if (!state.started)
169
+ return;
170
+ state.started = false;
171
+ clearTimers(state);
172
+ if (state.leaderLock !== null && state.provider !== null) {
173
+ try {
174
+ await state.provider.release(state.leaderLock);
175
+ }
176
+ catch {
177
+ // best-effort
178
+ }
179
+ }
180
+ state.leaderLock = null;
181
+ state.provider = null;
182
+ state.hooks = null;
183
+ },
184
+ });
185
+ },
186
+ });
187
+ export default SchedulerLeader;
@@ -0,0 +1,27 @@
1
+ export type ScheduleRunState = Readonly<{
2
+ lastRunAt?: number;
3
+ lastSuccessAt?: number;
4
+ lastErrorAt?: number;
5
+ lastErrorMessage?: string;
6
+ nextRunAt?: number;
7
+ consecutiveFailures?: number;
8
+ }>;
9
+ export type ScheduleRunStatePatch = Partial<ScheduleRunState>;
10
+ export type IScheduleStateStore = Readonly<{
11
+ get: (name: string) => Promise<ScheduleRunState | null>;
12
+ set: (name: string, patch: ScheduleRunStatePatch) => Promise<void>;
13
+ list: () => Promise<Array<{
14
+ name: string;
15
+ state: ScheduleRunState;
16
+ }>>;
17
+ }>;
18
+ export declare const InMemoryScheduleStateStore: Readonly<{
19
+ create(): IScheduleStateStore;
20
+ }>;
21
+ declare const _default: {
22
+ InMemoryScheduleStateStore: Readonly<{
23
+ create(): IScheduleStateStore;
24
+ }>;
25
+ };
26
+ export default _default;
27
+ //# sourceMappingURL=ScheduleStateStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ScheduleStateStore.d.ts","sourceRoot":"","sources":["../../../../src/scheduler/state/ScheduleStateStore.ts"],"names":[],"mappings":"AACA,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B,CAAC,CAAC;AAEH,MAAM,MAAM,qBAAqB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;AAE9D,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC;IACzC,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IACxD,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,qBAAqB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACnE,IAAI,EAAE,MAAM,OAAO,CAAC,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,gBAAgB,CAAA;KAAE,CAAC,CAAC,CAAC;CACvE,CAAC,CAAC;AAIH,eAAO,MAAM,0BAA0B;cAC3B,mBAAmB;EAuB7B,CAAC;;;kBAvBS,mBAAmB;;;AAyB/B,wBAEE"}
@@ -0,0 +1,27 @@
1
+ const normalizeName = (name) => String(name ?? '').trim();
2
+ export const InMemoryScheduleStateStore = Object.freeze({
3
+ create() {
4
+ const states = new Map();
5
+ return Object.freeze({
6
+ async get(name) {
7
+ const key = normalizeName(name);
8
+ if (key.length === 0)
9
+ return null;
10
+ return states.get(key) ?? null;
11
+ },
12
+ async set(name, patch) {
13
+ const key = normalizeName(name);
14
+ if (key.length === 0)
15
+ return;
16
+ const current = states.get(key) ?? {};
17
+ states.set(key, { ...current, ...patch });
18
+ },
19
+ async list() {
20
+ return Array.from(states.entries()).map(([name, state]) => ({ name, state }));
21
+ },
22
+ });
23
+ },
24
+ });
25
+ export default {
26
+ InMemoryScheduleStateStore,
27
+ };
@@ -6,9 +6,19 @@ export type IScheduleKernel = Readonly<{
6
6
  getRouter?: () => unknown;
7
7
  }>;
8
8
  export type IScheduleHandler = (kernel?: IScheduleKernel) => Promise<void> | void;
9
+ export type IScheduleBackoffPolicy = Readonly<{
10
+ initialMs: number;
11
+ maxMs: number;
12
+ factor?: number;
13
+ }>;
9
14
  export type ISchedule = {
10
15
  name: string;
11
16
  intervalMs?: number;
17
+ cron?: string;
18
+ timezone?: string;
19
+ jitterMs?: number;
20
+ backoff?: IScheduleBackoffPolicy;
21
+ leaderOnly?: boolean;
12
22
  handler: IScheduleHandler;
13
23
  enabled?: boolean;
14
24
  runOnStart?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/scheduler/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC;IACrC,YAAY,CAAC,EAAE,MAAM,OAAO,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC;CAC3B,CAAC,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,CAAC,MAAM,CAAC,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAElF,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,gBAAgB,CAAC;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/scheduler/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC;IACrC,YAAY,CAAC,EAAE,MAAM,OAAO,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC;CAC3B,CAAC,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,CAAC,MAAM,CAAC,EAAE,eAAe,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAElF,MAAM,MAAM,sBAAsB,GAAG,QAAQ,CAAC;IAC5C,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC,CAAC;AAEH,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,sBAAsB,CAAC;IACjC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE,gBAAgB,CAAC;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,CAAC"}
@@ -1,2 +1,3 @@
1
+ export { default as jobTrackingCleanup } from './job-tracking-cleanup';
1
2
  export { default as logCleanup } from './log-cleanup';
2
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/schedules/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/schedules/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAChF,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,wBAAwB,CAAC"}
@@ -1 +1,2 @@
1
+ export { default as jobTrackingCleanup } from './job-tracking-cleanup.js';
1
2
  export { default as logCleanup } from './log-cleanup.js';
@@ -0,0 +1,4 @@
1
+ export declare const cleanupJobTrackingOnce: () => Promise<void>;
2
+ declare const JobTrackingCleanupSchedule: import("../scheduler").ISchedule;
3
+ export default JobTrackingCleanupSchedule;
4
+ //# sourceMappingURL=job-tracking-cleanup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"job-tracking-cleanup.d.ts","sourceRoot":"","sources":["../../../src/schedules/job-tracking-cleanup.ts"],"names":[],"mappings":"AA4FA,eAAO,MAAM,sBAAsB,QAAa,OAAO,CAAC,IAAI,CAS3D,CAAC;AAKF,QAAA,MAAM,0BAA0B,kCAsCtB,CAAC;AAEX,eAAe,0BAA0B,CAAC"}
@@ -0,0 +1,116 @@
1
+ import { Env } from '../config/env.js';
2
+ import { Logger } from '../config/logger.js';
3
+ import { ErrorFactory } from '../exceptions/ZintrustError.js';
4
+ import { useDatabase } from '../orm/Database.js';
5
+ import { Schedule } from '../scheduler/Schedule.js';
6
+ const toSqlDateTime = (value) => value.toISOString().slice(0, 19).replace('T', ' ');
7
+ const assertSafeTableName = (raw, label) => {
8
+ const value = raw.trim();
9
+ if (value.length === 0)
10
+ throw ErrorFactory.createGeneralError(`${label} table is empty`);
11
+ // allow db.schema.table and underscores
12
+ if (!/^[A-Za-z0-9_.]+$/u.test(value)) {
13
+ throw ErrorFactory.createGeneralError(`${label} table contains invalid characters: ${value}`);
14
+ }
15
+ return value;
16
+ };
17
+ const cleanupJobTrackingBatch = async () => {
18
+ const connection = Env.get('JOB_TRACKING_DB_CONNECTION', 'default');
19
+ const jobsTable = assertSafeTableName(Env.get('JOB_TRACKING_DB_TABLE', 'zintrust_jobs'), 'Jobs');
20
+ const transitionsTable = assertSafeTableName(Env.get('JOB_TRACKING_DB_TRANSITIONS_TABLE', 'zintrust_job_transitions'), 'Transitions');
21
+ const retentionHoursRaw = Env.get('JOB_TRACKING_CLEANUP_RETENTION_HOURS', '').trim();
22
+ const retentionHours = retentionHoursRaw.length > 0 ? Number.parseFloat(retentionHoursRaw) : Number.NaN;
23
+ const retentionDays = Math.max(1, Env.getInt('JOB_TRACKING_CLEANUP_RETENTION_DAYS', 30));
24
+ const batchSize = Math.max(100, Env.getInt('JOB_TRACKING_CLEANUP_BATCH_SIZE', 5000));
25
+ const retentionMs = Number.isFinite(retentionHours) && retentionHours > 0
26
+ ? retentionHours * 60 * 60 * 1000
27
+ : retentionDays * 24 * 60 * 60 * 1000;
28
+ const cutoff = new Date(Date.now() - retentionMs);
29
+ const cutoffSql = toSqlDateTime(cutoff);
30
+ const db = useDatabase(undefined, connection);
31
+ const transitionRows = await db
32
+ .table(transitionsTable)
33
+ .select('id')
34
+ .where('transitioned_at', '<=', cutoffSql)
35
+ .orderBy('id', 'ASC')
36
+ .limit(batchSize)
37
+ .get();
38
+ const transitionIds = (transitionRows ?? [])
39
+ .map((row) => Number(row.id))
40
+ .filter((id) => Number.isFinite(id))
41
+ .map((id) => Math.floor(id));
42
+ if (transitionIds.length > 0) {
43
+ await db.table(transitionsTable).whereIn('id', transitionIds).delete();
44
+ }
45
+ const jobRows = await db
46
+ .table(jobsTable)
47
+ .select('id')
48
+ .where('status', '=', 'enqueued')
49
+ .where('updated_at', '<=', cutoffSql)
50
+ .orderBy('id', 'ASC')
51
+ .limit(batchSize)
52
+ .get();
53
+ const jobIds = (jobRows ?? [])
54
+ .map((row) => Number(row.id))
55
+ .filter((id) => Number.isFinite(id))
56
+ .map((id) => Math.floor(id));
57
+ if (jobIds.length > 0) {
58
+ await db.table(jobsTable).whereIn('id', jobIds).delete();
59
+ }
60
+ return {
61
+ retentionDays,
62
+ cutoffIso: cutoff.toISOString(),
63
+ batchSize,
64
+ deletedTransitions: transitionIds.length,
65
+ deletedJobs: jobIds.length,
66
+ };
67
+ };
68
+ export const cleanupJobTrackingOnce = async () => {
69
+ const result = await cleanupJobTrackingBatch();
70
+ Logger.info('Job tracking cleanup batch completed', {
71
+ retentionDays: result.retentionDays,
72
+ cutoff: result.cutoffIso,
73
+ deletedTransitions: result.deletedTransitions,
74
+ deletedJobs: result.deletedJobs,
75
+ batchSize: result.batchSize,
76
+ });
77
+ };
78
+ const enabled = Env.getBool('JOB_TRACKING_CLEANUP_ENABLED', false);
79
+ const intervalMs = Env.getInt('JOB_TRACKING_CLEANUP_INTERVAL_MS', 6 * 60 * 60 * 1000);
80
+ const JobTrackingCleanupSchedule = Schedule.define('jobTracking.cleanup', async () => {
81
+ const maxBatches = Math.max(1, Env.getInt('JOB_TRACKING_CLEANUP_MAX_BATCHES', 1));
82
+ let batchesRun = 0;
83
+ let deletedTransitionsTotal = 0;
84
+ let deletedJobsTotal = 0;
85
+ let retentionDays;
86
+ let cutoffIso;
87
+ let batchSize;
88
+ for (let i = 0; i < maxBatches; i += 1) {
89
+ // Bounded sequential batches are intentional; we want predictable DB load.
90
+ // eslint-disable-next-line no-await-in-loop
91
+ const result = await cleanupJobTrackingBatch();
92
+ batchesRun += 1;
93
+ deletedTransitionsTotal += result.deletedTransitions;
94
+ deletedJobsTotal += result.deletedJobs;
95
+ retentionDays = result.retentionDays;
96
+ cutoffIso = result.cutoffIso;
97
+ batchSize = result.batchSize;
98
+ if (result.deletedTransitions + result.deletedJobs === 0) {
99
+ break;
100
+ }
101
+ }
102
+ Logger.info('Job tracking cleanup run completed', {
103
+ retentionDays,
104
+ cutoff: cutoffIso,
105
+ batchSize,
106
+ batchesRun,
107
+ maxBatches,
108
+ deletedTransitionsTotal,
109
+ deletedJobsTotal,
110
+ });
111
+ })
112
+ .intervalMs(intervalMs)
113
+ .withoutOverlapping({ provider: Env.get('JOB_TRACKING_CLEANUP_LOCK_PROVIDER', 'redis') })
114
+ .enabledWhen(enabled)
115
+ .build();
116
+ export default JobTrackingCleanupSchedule;
@@ -1,4 +1,3 @@
1
- import type { ISchedule } from '../scheduler/types';
2
- declare const LogCleanupSchedule: ISchedule;
1
+ declare const LogCleanupSchedule: import("../scheduler").ISchedule;
3
2
  export default LogCleanupSchedule;
4
3
  //# sourceMappingURL=log-cleanup.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"log-cleanup.d.ts","sourceRoot":"","sources":["../../../src/schedules/log-cleanup.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAIlD,QAAA,MAAM,kBAAkB,EAAE,SAYzB,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
1
+ {"version":3,"file":"log-cleanup.d.ts","sourceRoot":"","sources":["../../../src/schedules/log-cleanup.ts"],"names":[],"mappings":"AAIA,QAAA,MAAM,kBAAkB,kCASd,CAAC;AAEX,eAAe,kBAAkB,CAAC"}
@@ -1,18 +1,15 @@
1
1
  import { Env } from '../config/env.js';
2
2
  import { Logger, cleanLogsOnce } from '../config/logger.js';
3
- const intervalMs = Env.getInt('LOG_CLEANUP_INTERVAL_MS', 3600000);
4
- const LogCleanupSchedule = {
5
- name: 'log.cleanup',
6
- intervalMs: intervalMs,
7
- handler: async () => {
8
- try {
9
- await cleanLogsOnce();
10
- }
11
- catch (err) {
12
- Logger.error('Log cleanup schedule failed', err);
13
- }
14
- },
15
- enabled: Env.getBool('LOG_CLEANUP_ENABLED', Env.getBool('LOG_TO_FILE', false)),
16
- runOnStart: false,
17
- };
3
+ import { Schedule } from '../scheduler/Schedule.js';
4
+ const LogCleanupSchedule = Schedule.define('log.cleanup', async () => {
5
+ try {
6
+ await cleanLogsOnce();
7
+ }
8
+ catch (err) {
9
+ Logger.error('Log cleanup schedule failed', err);
10
+ }
11
+ })
12
+ .intervalMs(Env.getInt('LOG_CLEANUP_INTERVAL_MS', 3600000))
13
+ .enabledWhen(Env.getBool('LOG_CLEANUP_ENABLED', Env.getBool('LOG_TO_FILE', false)))
14
+ .build();
18
15
  export default LogCleanupSchedule;
@@ -1 +1 @@
1
- {"version":3,"file":"Sanitizer.d.ts","sourceRoot":"","sources":["../../../src/security/Sanitizer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Sanitizer.d.ts","sourceRoot":"","sources":["../../../src/security/Sanitizer.ts"],"names":[],"mappings":"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"}
@@ -19,6 +19,7 @@
19
19
  * - ~5-15% performance overhead; disable for performance-critical paths
20
20
  */
21
21
  import { ErrorFactory } from '../exceptions/ZintrustError.js';
22
+ import { isEmpty } from '../helper/index.js';
22
23
  const MAX_NUMERIC_INPUT_LEN = 64;
23
24
  const MAX_EMAIL_LEN = 254;
24
25
  const MAX_NAME_LEN = 200;
@@ -28,15 +29,6 @@ const assertMaxLen = (method, label, value, maxLen) => {
28
29
  return;
29
30
  throw ErrorFactory.createSanitizerError(method, `${label} too long`, value);
30
31
  };
31
- const isEmpty = (value) => {
32
- // Preserve legacy semantics: treat 0 and "0" as empty.
33
- return (value === null ||
34
- value === undefined ||
35
- value === false ||
36
- value === 0 ||
37
- value === '' ||
38
- value === '0');
39
- };
40
32
  const toStr = (value) => {
41
33
  return String(value ?? '');
42
34
  };
@@ -1 +1 @@
1
- {"version":3,"file":"SignedRequest.d.ts","sourceRoot":"","sources":["../../../src/security/SignedRequest.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,oBAAoB,GAAG;IACjC,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,gBAAgB,EAAE,MAAM,CAAC;CAC1B,CAAC;AAIF,MAAM,MAAM,gCAAgC,GAAG;IAC7C,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAAC;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAAC;IAClC,OAAO,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACtD,iBAAiB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACvF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CACjF,CAAC;AAEF,MAAM,MAAM,yBAAyB,GACjC;IACE,EAAE,EAAE,IAAI,CAAC;IACT,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;CACf,GACD;IACE,EAAE,EAAE,KAAK,CAAC;IACV,IAAI,EACA,gBAAgB,GAChB,mBAAmB,GACnB,SAAS,GACT,kBAAkB,GAClB,mBAAmB,GACnB,aAAa,GACb,UAAU,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAyFN,eAAO,MAAM,aAAa;sBAzBK,MAAM,GAAG,UAAU,KAAG,OAAO,CAAC,MAAM,CAAC;8BAKnC;QAC/B,MAAM,EAAE,MAAM,CAAC;QACf,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;QAClB,WAAW,EAAE,MAAM,CAAC;QACpB,KAAK,EAAE,MAAM,CAAC;QACd,aAAa,EAAE,MAAM,CAAC;KACvB,KAAG,MAAM;0BAiBoB,gCAAgC,GAAG,OAAO,CAAC,oBAAoB,CAAC;mBAuCvE,yBAAyB,GAAG,OAAO,CAAC,yBAAyB,CAAC;EAuCnF,CAAC"}
1
+ {"version":3,"file":"SignedRequest.d.ts","sourceRoot":"","sources":["../../../src/security/SignedRequest.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,oBAAoB,GAAG;IACjC,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,gBAAgB,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,gCAAgC,GAAG;IAC7C,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAAC;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAAC;IAClC,OAAO,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACtD,iBAAiB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACvF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CACjF,CAAC;AAEF,MAAM,MAAM,yBAAyB,GACjC;IACE,EAAE,EAAE,IAAI,CAAC;IACT,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;CACf,GACD;IACE,EAAE,EAAE,KAAK,CAAC;IACV,IAAI,EACA,gBAAgB,GAChB,mBAAmB,GACnB,SAAS,GACT,kBAAkB,GAClB,mBAAmB,GACnB,aAAa,GACb,UAAU,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AA0FN,eAAO,MAAM,aAAa;sBAzBK,MAAM,GAAG,UAAU,KAAG,OAAO,CAAC,MAAM,CAAC;8BAKnC;QAC/B,MAAM,EAAE,MAAM,CAAC;QACf,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;QAClB,WAAW,EAAE,MAAM,CAAC;QACpB,KAAK,EAAE,MAAM,CAAC;QACd,aAAa,EAAE,MAAM,CAAC;KACvB,KAAG,MAAM;0BAiBoB,gCAAgC,GAAG,OAAO,CAAC,oBAAoB,CAAC;mBAuCvE,yBAAyB,GAAG,OAAO,CAAC,yBAAyB,CAAC;EAuCnF,CAAC"}
@@ -1,4 +1,3 @@
1
- import { ErrorFactory } from '../exceptions/ZintrustError.js';
2
1
  const getHeader = (headers, name) => {
3
2
  if (typeof headers.get === 'function') {
4
3
  const value = headers.get(name);
@@ -19,7 +18,8 @@ const getCrypto = () => {
19
18
  if (typeof crypto === 'undefined' || crypto.subtle === undefined) {
20
19
  // Some runtimes (or test environments) may not expose WebCrypto.
21
20
  // Keep this as a typed ZinTrust error to satisfy lint rules.
22
- throw ErrorFactory.createSecurityError('WebCrypto is not available in this runtime');
21
+ // eslint-disable-next-line no-restricted-syntax
22
+ throw new Error('WebCrypto is not available in this runtime');
23
23
  }
24
24
  return crypto;
25
25
  };