@kyro-cms/core 0.1.5 → 0.1.7

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 (170) hide show
  1. package/dist/WebhookService-BCgL1bLF.d.cts +112 -0
  2. package/dist/WebhookService-BPVJUgTl.d.ts +112 -0
  3. package/dist/{base-DlhVlwnN.d.cts → base-B0Y6isUJ.d.cts} +1 -1
  4. package/dist/{base-CQkFzqQl.d.ts → base-DaP-5PPG.d.ts} +1 -1
  5. package/dist/bootstrap-BMWVB2T6.cjs +31 -0
  6. package/dist/{bootstrap-X6TP3NKX.cjs.map → bootstrap-BMWVB2T6.cjs.map} +1 -1
  7. package/dist/bootstrap-LL6O7PWO.js +6 -0
  8. package/dist/{bootstrap-BDTTUGY2.js.map → bootstrap-LL6O7PWO.js.map} +1 -1
  9. package/dist/{chunk-3VZCX4DF.cjs → chunk-42JPONZU.cjs} +77 -14
  10. package/dist/chunk-42JPONZU.cjs.map +1 -0
  11. package/dist/{chunk-MHS6CPO5.cjs → chunk-4M5PHMUE.cjs} +66 -346
  12. package/dist/chunk-4M5PHMUE.cjs.map +1 -0
  13. package/dist/chunk-4PWRCMTQ.cjs +15 -0
  14. package/dist/chunk-4PWRCMTQ.cjs.map +1 -0
  15. package/dist/chunk-6COM32WF.js +47 -0
  16. package/dist/chunk-6COM32WF.js.map +1 -0
  17. package/dist/chunk-6MSSF46R.js +941 -0
  18. package/dist/chunk-6MSSF46R.js.map +1 -0
  19. package/dist/{chunk-TZFJMPCH.cjs → chunk-7YITG2US.cjs} +9 -18
  20. package/dist/chunk-7YITG2US.cjs.map +1 -0
  21. package/dist/{chunk-A3RQWHKD.cjs → chunk-BLMFBDBG.cjs} +56 -6
  22. package/dist/chunk-BLMFBDBG.cjs.map +1 -0
  23. package/dist/{chunk-EINVJPFM.js → chunk-BTOE3VUK.js} +65 -3
  24. package/dist/chunk-BTOE3VUK.js.map +1 -0
  25. package/dist/chunk-E5X75WNB.js +497 -0
  26. package/dist/chunk-E5X75WNB.js.map +1 -0
  27. package/dist/chunk-E63IF3MD.cjs +951 -0
  28. package/dist/chunk-E63IF3MD.cjs.map +1 -0
  29. package/dist/{chunk-K7QF2QCM.cjs → chunk-FTSSDDZQ.cjs} +7 -3
  30. package/dist/chunk-FTSSDDZQ.cjs.map +1 -0
  31. package/dist/chunk-G7VZBCD6.cjs +35 -0
  32. package/dist/{chunk-5BLDMQED.cjs.map → chunk-G7VZBCD6.cjs.map} +1 -1
  33. package/dist/{chunk-VMSRTAH7.js → chunk-GLCPGZPM.js} +56 -6
  34. package/dist/chunk-GLCPGZPM.js.map +1 -0
  35. package/dist/{chunk-V3B25QOK.cjs → chunk-GVFB5C6O.cjs} +74 -2
  36. package/dist/chunk-GVFB5C6O.cjs.map +1 -0
  37. package/dist/chunk-HVSQDZZJ.cjs +765 -0
  38. package/dist/chunk-HVSQDZZJ.cjs.map +1 -0
  39. package/dist/chunk-HYC4GNHX.js +758 -0
  40. package/dist/chunk-HYC4GNHX.js.map +1 -0
  41. package/dist/chunk-KDVDIZ4Y.cjs +3479 -0
  42. package/dist/chunk-KDVDIZ4Y.cjs.map +1 -0
  43. package/dist/{chunk-OG3KX56O.js → chunk-KWGNR4HM.js} +7 -3
  44. package/dist/chunk-KWGNR4HM.js.map +1 -0
  45. package/dist/chunk-LIJVWQKU.cjs +256 -0
  46. package/dist/chunk-LIJVWQKU.cjs.map +1 -0
  47. package/dist/{chunk-XTZSUDSI.js → chunk-LTRCYJAG.js} +3 -18
  48. package/dist/chunk-LTRCYJAG.js.map +1 -0
  49. package/dist/{chunk-UEYC46RL.js → chunk-OUGKLCYF.js} +71 -8
  50. package/dist/chunk-OUGKLCYF.js.map +1 -0
  51. package/dist/chunk-RONAX6UU.js +3456 -0
  52. package/dist/chunk-RONAX6UU.js.map +1 -0
  53. package/dist/{chunk-C74MQIRL.js → chunk-RRYXQMZG.js} +66 -344
  54. package/dist/chunk-RRYXQMZG.js.map +1 -0
  55. package/dist/{chunk-QUJ4OLSC.js → chunk-U74F3YZU.js} +87 -7
  56. package/dist/chunk-U74F3YZU.js.map +1 -0
  57. package/dist/chunk-VIONYQ2K.cjs +517 -0
  58. package/dist/chunk-VIONYQ2K.cjs.map +1 -0
  59. package/dist/chunk-VSTRLXMQ.cjs +50 -0
  60. package/dist/chunk-VSTRLXMQ.cjs.map +1 -0
  61. package/dist/chunk-YT7HXXVN.js +13 -0
  62. package/dist/chunk-YT7HXXVN.js.map +1 -0
  63. package/dist/chunk-Z6ZWNWWR.js +30 -0
  64. package/dist/{chunk-NSBPE2FW.js.map → chunk-Z6ZWNWWR.js.map} +1 -1
  65. package/dist/cli/index.cjs +11 -7
  66. package/dist/cli/index.cjs.map +1 -1
  67. package/dist/cli/index.js +11 -7
  68. package/dist/cli/index.js.map +1 -1
  69. package/dist/drizzle/index.cjs +20 -17
  70. package/dist/drizzle/index.d.cts +4 -4
  71. package/dist/drizzle/index.d.ts +4 -4
  72. package/dist/drizzle/index.js +4 -5
  73. package/dist/graphql/index.cjs +4 -4
  74. package/dist/graphql/index.d.cts +3 -2
  75. package/dist/graphql/index.d.ts +3 -2
  76. package/dist/graphql/index.js +2 -2
  77. package/dist/{index-DI0DRPNv.d.cts → index-BwE4NueJ.d.cts} +1 -1
  78. package/dist/{index-CMUNCIWQ.d.ts → index-DUKmDSeC.d.cts} +96 -24
  79. package/dist/{index-BMySjW6o.d.cts → index-DtBi3zP0.d.ts} +96 -24
  80. package/dist/{index-4fJKLFK2.d.ts → index-DupWTmW6.d.ts} +1 -1
  81. package/dist/index.cjs +3317 -352
  82. package/dist/index.cjs.map +1 -1
  83. package/dist/index.d.cts +379 -105
  84. package/dist/index.d.ts +379 -105
  85. package/dist/index.js +3211 -310
  86. package/dist/index.js.map +1 -1
  87. package/dist/media-HOT3O7RW.js +4 -0
  88. package/dist/media-HOT3O7RW.js.map +1 -0
  89. package/dist/media-WKP5AOX2.cjs +17 -0
  90. package/dist/media-WKP5AOX2.cjs.map +1 -0
  91. package/dist/mongodb/index.cjs +1 -1
  92. package/dist/mongodb/index.d.cts +2 -2
  93. package/dist/mongodb/index.d.ts +2 -2
  94. package/dist/mongodb/index.js +1 -1
  95. package/dist/mysql-media-AI6YK767.cjs +48 -0
  96. package/dist/mysql-media-AI6YK767.cjs.map +1 -0
  97. package/dist/mysql-media-CDZUS7YX.js +45 -0
  98. package/dist/mysql-media-CDZUS7YX.js.map +1 -0
  99. package/dist/postgres-auth-adapter-EVRPO7BQ.cjs +14 -0
  100. package/dist/{postgres-auth-adapter-VK6GY7LX.cjs.map → postgres-auth-adapter-EVRPO7BQ.cjs.map} +1 -1
  101. package/dist/postgres-auth-adapter-OTRWSTT5.js +5 -0
  102. package/dist/{postgres-auth-adapter-REJFUMP7.js.map → postgres-auth-adapter-OTRWSTT5.js.map} +1 -1
  103. package/dist/redis-adapter-2N6VA7BI.cjs +13 -0
  104. package/dist/{redis-adapter-LBLNKGNS.cjs.map → redis-adapter-2N6VA7BI.cjs.map} +1 -1
  105. package/dist/redis-adapter-RA24FNCX.js +4 -0
  106. package/dist/{redis-adapter-4YDY4LWE.js.map → redis-adapter-RA24FNCX.js.map} +1 -1
  107. package/dist/rest/index.cjs +7 -5
  108. package/dist/rest/index.d.cts +29 -3
  109. package/dist/rest/index.d.ts +29 -3
  110. package/dist/rest/index.js +5 -3
  111. package/dist/schema-CNB2DDTX.js +6 -0
  112. package/dist/schema-CNB2DDTX.js.map +1 -0
  113. package/dist/schema-Y777CQQS.cjs +67 -0
  114. package/dist/schema-Y777CQQS.cjs.map +1 -0
  115. package/dist/templates/index.cjs +24 -28
  116. package/dist/templates/index.d.cts +2 -4
  117. package/dist/templates/index.d.ts +2 -4
  118. package/dist/templates/index.js +2 -2
  119. package/dist/trpc/index.cjs +12 -12
  120. package/dist/trpc/index.d.cts +19 -14
  121. package/dist/trpc/index.d.ts +19 -14
  122. package/dist/trpc/index.js +3 -3
  123. package/dist/{types-BGM5MV_K.d.cts → types-BM0s_YOy.d.cts} +67 -35
  124. package/dist/{types-BGM5MV_K.d.ts → types-BM0s_YOy.d.ts} +67 -35
  125. package/dist/ws/index.cjs +1 -1
  126. package/dist/ws/index.js +1 -1
  127. package/package.json +11 -1
  128. package/dist/bootstrap-BDTTUGY2.js +0 -4
  129. package/dist/bootstrap-X6TP3NKX.cjs +0 -29
  130. package/dist/chunk-3QX6KG2S.js +0 -2125
  131. package/dist/chunk-3QX6KG2S.js.map +0 -1
  132. package/dist/chunk-3VZCX4DF.cjs.map +0 -1
  133. package/dist/chunk-5BLDMQED.cjs +0 -18
  134. package/dist/chunk-7G6EVYCU.cjs +0 -94
  135. package/dist/chunk-7G6EVYCU.cjs.map +0 -1
  136. package/dist/chunk-A3RQWHKD.cjs.map +0 -1
  137. package/dist/chunk-C74MQIRL.js.map +0 -1
  138. package/dist/chunk-EINVJPFM.js.map +0 -1
  139. package/dist/chunk-F5B64H5S.cjs +0 -2149
  140. package/dist/chunk-F5B64H5S.cjs.map +0 -1
  141. package/dist/chunk-K7QF2QCM.cjs.map +0 -1
  142. package/dist/chunk-LRTZJJPD.js +0 -86
  143. package/dist/chunk-LRTZJJPD.js.map +0 -1
  144. package/dist/chunk-MHS6CPO5.cjs.map +0 -1
  145. package/dist/chunk-NSBPE2FW.js +0 -15
  146. package/dist/chunk-OG3KX56O.js.map +0 -1
  147. package/dist/chunk-QUJ4OLSC.js.map +0 -1
  148. package/dist/chunk-R3XIBBAW.cjs +0 -34
  149. package/dist/chunk-R3XIBBAW.cjs.map +0 -1
  150. package/dist/chunk-SDMNUYVU.js +0 -30
  151. package/dist/chunk-SDMNUYVU.js.map +0 -1
  152. package/dist/chunk-TZFJMPCH.cjs.map +0 -1
  153. package/dist/chunk-UEG7KMKC.cjs +0 -228
  154. package/dist/chunk-UEG7KMKC.cjs.map +0 -1
  155. package/dist/chunk-UEYC46RL.js.map +0 -1
  156. package/dist/chunk-V3B25QOK.cjs.map +0 -1
  157. package/dist/chunk-VMSRTAH7.js.map +0 -1
  158. package/dist/chunk-XTZSUDSI.js.map +0 -1
  159. package/dist/chunk-YD7Y25W7.cjs +0 -176
  160. package/dist/chunk-YD7Y25W7.cjs.map +0 -1
  161. package/dist/chunk-YPAFJ7EV.js +0 -225
  162. package/dist/chunk-YPAFJ7EV.js.map +0 -1
  163. package/dist/database-7CJOXEZR.js +0 -5
  164. package/dist/database-7CJOXEZR.js.map +0 -1
  165. package/dist/database-QOIV44GT.cjs +0 -22
  166. package/dist/database-QOIV44GT.cjs.map +0 -1
  167. package/dist/postgres-auth-adapter-REJFUMP7.js +0 -5
  168. package/dist/postgres-auth-adapter-VK6GY7LX.cjs +0 -14
  169. package/dist/redis-adapter-4YDY4LWE.js +0 -4
  170. package/dist/redis-adapter-LBLNKGNS.cjs +0 -13
@@ -0,0 +1,951 @@
1
+ 'use strict';
2
+
3
+ var chunkHVSQDZZJ_cjs = require('./chunk-HVSQDZZJ.cjs');
4
+ var chunkVIONYQ2K_cjs = require('./chunk-VIONYQ2K.cjs');
5
+ var hono = require('hono');
6
+ var jwt = require('jsonwebtoken');
7
+
8
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
9
+
10
+ var jwt__default = /*#__PURE__*/_interopDefault(jwt);
11
+
12
+ function createAuthMiddleware(config) {
13
+ const {
14
+ secret,
15
+ issuer,
16
+ audience,
17
+ db,
18
+ userLookup,
19
+ extractToken = defaultExtractToken
20
+ } = config;
21
+ return async function authMiddleware(req) {
22
+ const apiKeyRaw = chunkVIONYQ2K_cjs.extractApiKeyFromRequest(req);
23
+ if (apiKeyRaw && db) {
24
+ const result = await chunkVIONYQ2K_cjs.validateApiKey(apiKeyRaw, db, userLookup);
25
+ if (result.valid && result.user) {
26
+ return {
27
+ user: result.user,
28
+ tenantContext: createTenantContextFromUser(result.user),
29
+ apiKeyContext: chunkVIONYQ2K_cjs.createApiKeyContext(result),
30
+ status: 200,
31
+ authType: "apikey"
32
+ };
33
+ }
34
+ if (result.error) {
35
+ return {
36
+ status: 401,
37
+ error: result.error
38
+ };
39
+ }
40
+ }
41
+ const token = extractToken(req);
42
+ if (!token) {
43
+ return {
44
+ status: 401,
45
+ error: "No authentication token provided"
46
+ };
47
+ }
48
+ try {
49
+ const payload = jwt__default.default.verify(token, secret, {
50
+ issuer,
51
+ audience
52
+ });
53
+ const user = {
54
+ id: payload.sub,
55
+ email: payload.email,
56
+ role: payload.role,
57
+ tenantId: payload.tenantId
58
+ };
59
+ return {
60
+ user,
61
+ token,
62
+ tenantContext: createTenantContextFromUser(user),
63
+ status: 200,
64
+ authType: "jwt"
65
+ };
66
+ } catch (error) {
67
+ if (error instanceof jwt__default.default.TokenExpiredError) {
68
+ return {
69
+ status: 401,
70
+ error: "Token has expired"
71
+ };
72
+ }
73
+ if (error instanceof jwt__default.default.JsonWebTokenError) {
74
+ return {
75
+ status: 401,
76
+ error: "Invalid token"
77
+ };
78
+ }
79
+ return {
80
+ status: 401,
81
+ error: "Authentication failed"
82
+ };
83
+ }
84
+ };
85
+ }
86
+ function defaultExtractToken(req) {
87
+ const authHeader = req.headers.get("Authorization");
88
+ if (authHeader?.startsWith("Bearer ")) {
89
+ return authHeader.slice(7);
90
+ }
91
+ const cookieHeader = req.headers.get("Cookie");
92
+ if (cookieHeader) {
93
+ const cookies = Object.fromEntries(
94
+ cookieHeader.split("; ").map((c) => {
95
+ const [key, ...val] = c.split("=");
96
+ return [key.trim(), val.join("=")];
97
+ })
98
+ );
99
+ return cookies["auth_token"] || null;
100
+ }
101
+ return null;
102
+ }
103
+ function createTenantContextFromUser(user) {
104
+ return {
105
+ tenantId: user.tenantId || "default",
106
+ userId: user.id || "anonymous",
107
+ role: user.role || "guest",
108
+ roles: [user.role || "guest"],
109
+ permissions: [],
110
+ isSuperAdmin: user.role === "super_admin"
111
+ };
112
+ }
113
+ function generateToken(payload, secret, options = {}) {
114
+ return jwt__default.default.sign(payload, secret, {
115
+ expiresIn: options.expiresIn || "24h",
116
+ issuer: options.issuer,
117
+ audience: options.audience
118
+ });
119
+ }
120
+
121
+ // src/auth/security/in-memory-rate-limit.ts
122
+ var InMemoryRateLimiter = class {
123
+ storage = /* @__PURE__ */ new Map();
124
+ userStorage = /* @__PURE__ */ new Map();
125
+ limits;
126
+ userLimits;
127
+ constructor(limits, userLimits) {
128
+ this.limits = { ...DEFAULT_RATE_LIMITS, ...limits };
129
+ this.userLimits = userLimits || {
130
+ "user:api": { window: 6e4, max: 500 },
131
+ "user:write": { window: 36e5, max: 100 }
132
+ };
133
+ }
134
+ getKey(type, identifier) {
135
+ return `${type}:${identifier}`;
136
+ }
137
+ getUserKey(type, userId, identifier) {
138
+ return `user:${type}:${userId}:${identifier}`;
139
+ }
140
+ cleanupOldEntries(entries, window) {
141
+ const now = Date.now();
142
+ const windowStart = now - window;
143
+ while (entries.length > 0 && entries[0].timestamp < windowStart) {
144
+ entries.shift();
145
+ }
146
+ }
147
+ async check(type, identifier) {
148
+ const config = this.limits[type] || this.limits["api:general"];
149
+ const key = this.getKey(type, identifier);
150
+ let entries = this.storage.get(key);
151
+ if (!entries) {
152
+ entries = [];
153
+ this.storage.set(key, entries);
154
+ }
155
+ this.cleanupOldEntries(entries, config.window);
156
+ const now = Date.now();
157
+ const count = entries.reduce((sum, entry) => sum + entry.count, 0);
158
+ entries.push({ timestamp: now, count: 1 });
159
+ if (count >= config.max) {
160
+ const oldestEntry = entries.reduce(
161
+ (oldest, current) => oldest.timestamp < current.timestamp ? oldest : current,
162
+ entries[0]
163
+ );
164
+ const resetAt = oldestEntry.timestamp + config.window;
165
+ return {
166
+ allowed: false,
167
+ remaining: 0,
168
+ resetAt,
169
+ retryAfter: Math.ceil((resetAt - now) / 1e3)
170
+ };
171
+ }
172
+ return {
173
+ allowed: true,
174
+ remaining: config.max - count - 1,
175
+ resetAt: now + config.window
176
+ };
177
+ }
178
+ async checkUser(type, userId, identifier) {
179
+ const config = this.userLimits[type] || this.userLimits["user:api"];
180
+ const userMap = this.userStorage.get(userId);
181
+ let entries = [];
182
+ if (userMap) {
183
+ entries = userMap.get(this.getKey(type, identifier)) || [];
184
+ } else {
185
+ if (!this.userStorage.has(userId)) {
186
+ this.userStorage.set(userId, /* @__PURE__ */ new Map());
187
+ }
188
+ this.userStorage.get(userId).set(this.getKey(type, identifier), entries);
189
+ }
190
+ this.cleanupOldEntries(entries, config.window);
191
+ const now = Date.now();
192
+ const count = entries.reduce((sum, entry) => sum + entry.count, 0);
193
+ entries.push({ timestamp: now, count: 1 });
194
+ if (count >= config.max) {
195
+ const oldestEntry = entries.reduce(
196
+ (oldest, current) => oldest.timestamp < current.timestamp ? oldest : current,
197
+ entries[0]
198
+ );
199
+ const resetAt = oldestEntry.timestamp + config.window;
200
+ return {
201
+ allowed: false,
202
+ remaining: 0,
203
+ resetAt,
204
+ retryAfter: Math.ceil((resetAt - now) / 1e3)
205
+ };
206
+ }
207
+ return {
208
+ allowed: true,
209
+ remaining: config.max - count - 1,
210
+ resetAt: now + config.window
211
+ };
212
+ }
213
+ async reset(type, identifier) {
214
+ const key = this.getKey(type, identifier);
215
+ this.storage.delete(key);
216
+ }
217
+ async resetUser(type, userId, identifier) {
218
+ const userMap = this.userStorage.get(userId);
219
+ if (userMap) {
220
+ const key = this.getKey(type, identifier);
221
+ userMap.delete(key);
222
+ }
223
+ }
224
+ async getStatus(type, identifier) {
225
+ const config = this.limits[type] || this.limits["api:general"];
226
+ const key = this.getKey(type, identifier);
227
+ let entries = this.storage.get(key);
228
+ if (!entries) {
229
+ entries = [];
230
+ this.storage.set(key, entries);
231
+ }
232
+ this.cleanupOldEntries(entries, config.window);
233
+ const now = Date.now();
234
+ const count = entries.reduce((sum, entry) => sum + entry.count, 0);
235
+ return {
236
+ count,
237
+ limit: config.max,
238
+ remaining: Math.max(0, config.max - count),
239
+ resetAt: now + config.window
240
+ };
241
+ }
242
+ setLimit(type, config) {
243
+ this.limits[type] = config;
244
+ }
245
+ setUserLimit(type, config) {
246
+ this.userLimits[type] = config;
247
+ }
248
+ };
249
+ var DEFAULT_RATE_LIMITS = {
250
+ "auth:login": { window: 9e5, max: 5 },
251
+ "auth:register": { window: 36e5, max: 3 },
252
+ "auth:forgot": { window: 36e5, max: 3 },
253
+ "auth:reset": { window: 36e5, max: 5 },
254
+ "auth:verify": { window: 36e5, max: 5 },
255
+ "api:general": { window: 6e4, max: 100 },
256
+ "api:authenticated": { window: 6e4, max: 200 }
257
+ };
258
+
259
+ // src/api/rest/hono-app.ts
260
+ var COLLECTION_EVENT_MAP = {
261
+ _media: {
262
+ create: chunkVIONYQ2K_cjs.WEBHOOK_EVENTS.MEDIA_UPLOAD,
263
+ update: chunkVIONYQ2K_cjs.WEBHOOK_EVENTS.MEDIA_UPLOAD,
264
+ delete: chunkVIONYQ2K_cjs.WEBHOOK_EVENTS.MEDIA_DELETE
265
+ }
266
+ };
267
+ function getWebhookEvent(collection, operation) {
268
+ const mapped = COLLECTION_EVENT_MAP[collection];
269
+ if (mapped) return mapped[operation];
270
+ return `collection.${operation}`;
271
+ }
272
+ async function checkCollectionAccess(collection, operation, req, ctxUser, ctxTenantID, apiKeyContext, enablePublicAccess = true, defaultCollectionAccess = "read") {
273
+ const accessRule = collection.access?.[operation];
274
+ if (accessRule) {
275
+ const allowed = await chunkVIONYQ2K_cjs.evaluateAccess(accessRule, {
276
+ req,
277
+ user: ctxUser,
278
+ tenantID: ctxTenantID
279
+ });
280
+ if (allowed === false) {
281
+ return { allowed: false, error: "Access denied", status: 403 };
282
+ }
283
+ } else if (!ctxUser) {
284
+ const accessLevels = {
285
+ none: false,
286
+ read: operation === "read",
287
+ create: operation === "read" || operation === "create",
288
+ update: operation === "read" || operation === "create" || operation === "update",
289
+ admin: true
290
+ };
291
+ const allowed = enablePublicAccess && accessLevels[defaultCollectionAccess];
292
+ if (!allowed) {
293
+ return {
294
+ allowed: false,
295
+ error: "Authentication required",
296
+ status: 401
297
+ };
298
+ }
299
+ }
300
+ if (apiKeyContext?.permissions?.length > 0) {
301
+ const resource = collection.slug;
302
+ const action = operation === "read" ? "read" : operation === "create" ? "create" : "update";
303
+ const permission = `${resource}:${action}`;
304
+ if (!chunkVIONYQ2K_cjs.hasApiKeyPermission(apiKeyContext.permissions, permission) && !chunkVIONYQ2K_cjs.hasApiKeyPermission(apiKeyContext.permissions, `${resource}:admin`)) {
305
+ return {
306
+ allowed: false,
307
+ error: `Missing permission: ${permission}`,
308
+ status: 403
309
+ };
310
+ }
311
+ }
312
+ return { allowed: true };
313
+ }
314
+ async function checkGlobalAccess(global, operation, req, ctxUser, ctxTenantID, enablePublicAccess = true) {
315
+ const accessRule = global.access?.[operation];
316
+ if (accessRule) {
317
+ const allowed = await chunkVIONYQ2K_cjs.evaluateAccess(accessRule, {
318
+ req,
319
+ user: ctxUser,
320
+ tenantID: ctxTenantID
321
+ });
322
+ if (allowed === false) {
323
+ return { allowed: false, error: "Access denied", status: 403 };
324
+ }
325
+ } else if (!ctxUser) {
326
+ const accessLevels = {
327
+ none: false,
328
+ read: operation === "read",
329
+ update: operation === "read" || operation === "update"
330
+ };
331
+ const allowed = enablePublicAccess && accessLevels[operation === "read" ? "read" : "admin"];
332
+ if (!allowed) {
333
+ return {
334
+ allowed: false,
335
+ error: "Authentication required",
336
+ status: 401
337
+ };
338
+ }
339
+ }
340
+ return { allowed: true };
341
+ }
342
+ async function resolveAuthContext(req, authMw, staticUser, staticTenantID) {
343
+ if (!authMw) {
344
+ return {
345
+ user: staticUser,
346
+ tenantID: staticTenantID,
347
+ apiKeyContext: void 0
348
+ };
349
+ }
350
+ const result = await authMw(req);
351
+ if (result.status === 401) {
352
+ return { user: void 0, tenantID: void 0, apiKeyContext: void 0 };
353
+ }
354
+ return {
355
+ user: result.user || staticUser,
356
+ tenantID: result.tenantContext?.tenantId || staticTenantID,
357
+ apiKeyContext: result.apiKeyContext
358
+ };
359
+ }
360
+ function createHonoApp(options) {
361
+ const {
362
+ registry,
363
+ db,
364
+ authSecret,
365
+ user,
366
+ tenantID,
367
+ cors,
368
+ webhookService,
369
+ settings
370
+ } = options;
371
+ const app = new hono.Hono();
372
+ const apiAccess = settings?.access?.apiAccess;
373
+ if (apiAccess?.restEnabled === false) {
374
+ app.all("/api/*", (c) => {
375
+ return c.json({ error: "REST API is disabled" }, 503);
376
+ });
377
+ return app;
378
+ }
379
+ const enablePublicAccess = settings?.access?.enablePublicAccess ?? true;
380
+ const defaultCollectionAccess = settings?.access?.defaultCollectionAccess ?? "read";
381
+ const requireAuth = apiAccess?.requireAuth;
382
+ if (requireAuth && !authSecret) {
383
+ throw new Error(
384
+ "authSecret is required when requireAuth is enabled in access settings"
385
+ );
386
+ }
387
+ const authMw = authSecret ? createAuthMiddleware({ secret: authSecret, db }) : null;
388
+ const settingsCorsRaw = apiAccess?.cors?.allowedOrigins;
389
+ const optionsCors = cors?.origins;
390
+ const settingsCors = Array.isArray(settingsCorsRaw) ? settingsCorsRaw : typeof settingsCorsRaw === "string" && settingsCorsRaw ? settingsCorsRaw.split("\n").map((s) => s.trim()).filter(Boolean) : [];
391
+ const allowedOrigins = settingsCors.length > 0 ? settingsCors : optionsCors || [];
392
+ const corsEnabled = allowedOrigins.length > 0 || !!cors;
393
+ if (corsEnabled) {
394
+ app.use("*", async (c, next) => {
395
+ const origin = c.req.header("Origin") || "*";
396
+ if (allowedOrigins.length > 0 && !allowedOrigins.includes(origin)) {
397
+ return c.json({ error: "Origin not allowed" }, 403);
398
+ }
399
+ const allowOrigin = allowedOrigins.length > 0 ? origin : "*";
400
+ c.header("Access-Control-Allow-Origin", allowOrigin);
401
+ c.header(
402
+ "Access-Control-Allow-Methods",
403
+ "GET, POST, PATCH, DELETE, OPTIONS"
404
+ );
405
+ c.header(
406
+ "Access-Control-Allow-Headers",
407
+ "Content-Type, Authorization, X-API-Key"
408
+ );
409
+ if (cors?.credentials) {
410
+ c.header("Access-Control-Allow-Credentials", "true");
411
+ }
412
+ if (c.req.method === "OPTIONS") {
413
+ return c.text("");
414
+ }
415
+ await next();
416
+ });
417
+ }
418
+ const rateLimiting = settings?.access?.rateLimiting;
419
+ let rateLimiter;
420
+ if (rateLimiting?.enabled) {
421
+ const maxRequests = rateLimiting.maxRequests || 100;
422
+ const windowMs = rateLimiting.windowMs || 6e4;
423
+ rateLimiter = new InMemoryRateLimiter({
424
+ "api:general": { window: windowMs, max: maxRequests }
425
+ });
426
+ app.use("/api/*", async (c, next) => {
427
+ if (!rateLimiter) {
428
+ return next();
429
+ }
430
+ const ip = c.req.header("CF-Connecting-IP") || c.req.header("X-Forwarded-For")?.split(",")[0]?.trim() || c.req.header("X-Real-IP") || "unknown";
431
+ const result = await rateLimiter.check("api:general", ip);
432
+ c.header("X-RateLimit-Limit", String(maxRequests));
433
+ c.header("X-RateLimit-Remaining", String(result.remaining));
434
+ c.header("X-RateLimit-Reset", String(result.resetAt));
435
+ if (!result.allowed) {
436
+ return c.json(
437
+ {
438
+ error: "Too many requests",
439
+ retryAfter: result.retryAfter
440
+ },
441
+ 429
442
+ );
443
+ }
444
+ await next();
445
+ });
446
+ }
447
+ app.get("/api/health", (c) => {
448
+ return c.json({
449
+ status: "ok",
450
+ version: "0.1.0",
451
+ collections: registry.getCollectionSlugs(),
452
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
453
+ });
454
+ });
455
+ app.get("/api/collections", (c) => {
456
+ const collections2 = registry.getCollections().map((col) => ({
457
+ slug: col.slug,
458
+ label: col.label || col.slug,
459
+ fields: col.fields.filter((f) => f.name).map((f) => ({
460
+ name: f.name,
461
+ type: f.type,
462
+ required: f.required,
463
+ label: f.label
464
+ }))
465
+ }));
466
+ return c.json(collections2);
467
+ });
468
+ app.get("/api/search", async (c) => {
469
+ try {
470
+ const query = c.req.query("q") || "";
471
+ const collectionsParam = c.req.query("collections") || "";
472
+ const limit = Math.min(parseInt(c.req.query("limit") || "10"), 50);
473
+ if (!query || query.length < 2) {
474
+ return c.json({ results: [], message: "Query too short" });
475
+ }
476
+ console.log("[API /api/search] Query:", query);
477
+ const { user: ctxUser, tenantID: ctxTenantID } = await resolveAuthContext(
478
+ c.req.raw,
479
+ authMw,
480
+ user,
481
+ tenantID
482
+ );
483
+ const targetCollections = collectionsParam ? collectionsParam.split(",").filter(Boolean) : registry.getCollectionSlugs();
484
+ const results = [];
485
+ const regex = new RegExp(
486
+ query.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"),
487
+ "i"
488
+ );
489
+ for (const collection of registry.getCollections()) {
490
+ if (!targetCollections.includes(collection.slug)) continue;
491
+ if (collection.slug === "users") continue;
492
+ const access = await checkCollectionAccess(
493
+ collection,
494
+ "read",
495
+ c.req.raw,
496
+ ctxUser,
497
+ ctxTenantID,
498
+ void 0,
499
+ enablePublicAccess,
500
+ defaultCollectionAccess
501
+ );
502
+ if (!access.allowed) continue;
503
+ const searchableFields = collection.fields.filter(
504
+ (f) => f.name && f.name !== "id" && (f.type === "text" || f.type === "email" || f.type === "textarea" || f.type === "richtext" || f.indexed) && !f.admin?.hidden
505
+ ).map((f) => f.name);
506
+ if (searchableFields.length === 0) continue;
507
+ try {
508
+ const orConditions = searchableFields.map(
509
+ (field) => {
510
+ const condition = {};
511
+ condition[field] = { like: `%${query}%` };
512
+ return condition;
513
+ }
514
+ );
515
+ const searchResult = await db.find({
516
+ collection: collection.slug,
517
+ where: { OR: orConditions },
518
+ limit,
519
+ tenantID: ctxTenantID
520
+ });
521
+ for (const doc of searchResult.docs) {
522
+ const titleField = collection.admin?.useAsTitle || searchableFields.find(
523
+ (f) => f === "title" || f === "name" || f === "heading" || f === "slug"
524
+ );
525
+ const title = titleField ? doc[titleField] : doc.id;
526
+ results.push({
527
+ collection: collection.slug,
528
+ label: collection.label || collection.slug,
529
+ id: doc.id,
530
+ title: String(title || "Untitled"),
531
+ doc
532
+ });
533
+ }
534
+ } catch (err) {
535
+ console.error(`Search error for ${collection.slug}:`, err);
536
+ }
537
+ }
538
+ results.sort((a, b) => a.label.localeCompare(b.label));
539
+ return c.json({ results });
540
+ } catch (error) {
541
+ return c.json({ error: error.message, results: [] }, 500);
542
+ }
543
+ });
544
+ const collections = registry.getCollections();
545
+ for (const collection of collections) {
546
+ const slug = collection.slug;
547
+ const basePath = `/api/${slug}`;
548
+ app.get(basePath, async (c) => {
549
+ try {
550
+ const {
551
+ user: ctxUser,
552
+ tenantID: ctxTenantID,
553
+ apiKeyContext
554
+ } = await resolveAuthContext(c.req.raw, authMw, user, tenantID);
555
+ const access = await checkCollectionAccess(
556
+ collection,
557
+ "read",
558
+ c.req.raw,
559
+ ctxUser,
560
+ ctxTenantID,
561
+ apiKeyContext
562
+ );
563
+ if (!access.allowed) {
564
+ return c.json({ error: access.error }, access.status || 403);
565
+ }
566
+ const url = new URL(c.req.url);
567
+ const page = parseInt(url.searchParams.get("page") || "1");
568
+ const limit = Math.min(
569
+ parseInt(url.searchParams.get("limit") || "10"),
570
+ 100
571
+ );
572
+ const sort = url.searchParams.get("sort") || void 0;
573
+ const depth = parseInt(url.searchParams.get("depth") || "0");
574
+ const select = url.searchParams.get("select")?.split(",") || void 0;
575
+ let where = {};
576
+ const whereParam = url.searchParams.get("where");
577
+ if (whereParam) {
578
+ try {
579
+ where = JSON.parse(whereParam);
580
+ } catch {
581
+ }
582
+ }
583
+ const result = await db.find({
584
+ collection: slug,
585
+ where,
586
+ sort,
587
+ limit,
588
+ page,
589
+ depth,
590
+ tenantID: ctxTenantID,
591
+ select
592
+ });
593
+ return c.json(result);
594
+ } catch (error) {
595
+ return c.json({ error: error.message }, 500);
596
+ }
597
+ });
598
+ app.get(`${basePath}/:id`, async (c) => {
599
+ try {
600
+ const {
601
+ user: ctxUser,
602
+ tenantID: ctxTenantID,
603
+ apiKeyContext
604
+ } = await resolveAuthContext(c.req.raw, authMw, user, tenantID);
605
+ const access = await checkCollectionAccess(
606
+ collection,
607
+ "read",
608
+ c.req.raw,
609
+ ctxUser,
610
+ ctxTenantID,
611
+ apiKeyContext
612
+ );
613
+ if (!access.allowed) {
614
+ return c.json({ error: access.error }, access.status || 403);
615
+ }
616
+ const id = c.req.param("id");
617
+ const url = new URL(c.req.url);
618
+ const depth = parseInt(url.searchParams.get("depth") || "0");
619
+ const select = url.searchParams.get("select")?.split(",") || void 0;
620
+ const doc = await db.findByID({
621
+ collection: slug,
622
+ id,
623
+ depth,
624
+ tenantID: ctxTenantID,
625
+ select
626
+ });
627
+ if (!doc) {
628
+ return c.json({ error: "Document not found" }, 404);
629
+ }
630
+ return c.json(doc);
631
+ } catch (error) {
632
+ return c.json({ error: error.message }, 500);
633
+ }
634
+ });
635
+ app.post(basePath, async (c) => {
636
+ try {
637
+ const {
638
+ user: ctxUser,
639
+ tenantID: ctxTenantID,
640
+ apiKeyContext
641
+ } = await resolveAuthContext(c.req.raw, authMw, user, tenantID);
642
+ const access = await checkCollectionAccess(
643
+ collection,
644
+ "read",
645
+ c.req.raw,
646
+ ctxUser,
647
+ ctxTenantID,
648
+ apiKeyContext,
649
+ enablePublicAccess,
650
+ defaultCollectionAccess
651
+ );
652
+ if (!access.allowed) {
653
+ return c.json({ error: access.error }, access.status || 403);
654
+ }
655
+ const body = await c.req.json();
656
+ const schema = registry.getCreateZodSchema(slug);
657
+ const validated = schema.parse(body);
658
+ if (collection.tenantScoped && ctxTenantID) {
659
+ validated.tenantID = ctxTenantID;
660
+ }
661
+ const doc = await db.create({
662
+ collection: slug,
663
+ data: validated,
664
+ tenantID: ctxTenantID
665
+ });
666
+ if (webhookService) {
667
+ webhookService.trigger(getWebhookEvent(slug, "create"), {
668
+ collection: slug,
669
+ operation: "create",
670
+ data: doc,
671
+ user: ctxUser ? { id: ctxUser.id, email: ctxUser.email, role: ctxUser.role } : void 0,
672
+ tenantId: ctxTenantID
673
+ }).catch((err) => console.error(`[Webhook] Failed to trigger:`, err));
674
+ }
675
+ return c.json({ doc, message: "Created successfully" }, 201);
676
+ } catch (error) {
677
+ if (error.name === "ZodError") {
678
+ return c.json(
679
+ { error: "Validation failed", details: error.errors },
680
+ 400
681
+ );
682
+ }
683
+ return c.json({ error: error.message }, 500);
684
+ }
685
+ });
686
+ app.patch(`${basePath}/:id`, async (c) => {
687
+ try {
688
+ const {
689
+ user: ctxUser,
690
+ tenantID: ctxTenantID,
691
+ apiKeyContext
692
+ } = await resolveAuthContext(c.req.raw, authMw, user, tenantID);
693
+ const access = await checkCollectionAccess(
694
+ collection,
695
+ "update",
696
+ c.req.raw,
697
+ ctxUser,
698
+ ctxTenantID,
699
+ apiKeyContext,
700
+ enablePublicAccess,
701
+ defaultCollectionAccess
702
+ );
703
+ if (!access.allowed) {
704
+ return c.json({ error: access.error }, access.status || 403);
705
+ }
706
+ const id = c.req.param("id");
707
+ const body = await c.req.json();
708
+ const schema = registry.getUpdateZodSchema(slug);
709
+ const validated = schema.parse(body);
710
+ const originalDoc = await db.findByID({
711
+ collection: slug,
712
+ id,
713
+ tenantID: ctxTenantID
714
+ });
715
+ const doc = await db.update({
716
+ collection: slug,
717
+ id,
718
+ data: validated,
719
+ tenantID: ctxTenantID
720
+ });
721
+ if (webhookService) {
722
+ webhookService.trigger(getWebhookEvent(slug, "update"), {
723
+ collection: slug,
724
+ operation: "update",
725
+ data: doc,
726
+ previousData: originalDoc,
727
+ user: ctxUser ? { id: ctxUser.id, email: ctxUser.email, role: ctxUser.role } : void 0,
728
+ tenantId: ctxTenantID
729
+ }).catch((err) => console.error(`[Webhook] Failed to trigger:`, err));
730
+ }
731
+ return c.json({ doc, message: "Updated successfully" });
732
+ } catch (error) {
733
+ if (error.name === "ZodError") {
734
+ return c.json(
735
+ { error: "Validation failed", details: error.errors },
736
+ 400
737
+ );
738
+ }
739
+ return c.json({ error: error.message }, 500);
740
+ }
741
+ });
742
+ app.delete(`${basePath}/:id`, async (c) => {
743
+ try {
744
+ const {
745
+ user: ctxUser,
746
+ tenantID: ctxTenantID,
747
+ apiKeyContext
748
+ } = await resolveAuthContext(c.req.raw, authMw, user, tenantID);
749
+ const access = await checkCollectionAccess(
750
+ collection,
751
+ "delete",
752
+ c.req.raw,
753
+ ctxUser,
754
+ ctxTenantID,
755
+ apiKeyContext,
756
+ enablePublicAccess,
757
+ defaultCollectionAccess
758
+ );
759
+ if (!access.allowed) {
760
+ return c.json({ error: access.error }, access.status || 403);
761
+ }
762
+ const id = c.req.param("id");
763
+ const originalDoc = await db.findByID({
764
+ collection: slug,
765
+ id,
766
+ tenantID: ctxTenantID
767
+ });
768
+ const doc = await db.delete({
769
+ collection: slug,
770
+ id,
771
+ tenantID: ctxTenantID
772
+ });
773
+ if (webhookService) {
774
+ webhookService.trigger(getWebhookEvent(slug, "delete"), {
775
+ collection: slug,
776
+ operation: "delete",
777
+ data: doc,
778
+ previousData: originalDoc,
779
+ user: ctxUser ? { id: ctxUser.id, email: ctxUser.email, role: ctxUser.role } : void 0,
780
+ tenantId: ctxTenantID
781
+ }).catch((err) => console.error(`[Webhook] Failed to trigger:`, err));
782
+ }
783
+ return c.json({ doc, message: "Deleted successfully" });
784
+ } catch (error) {
785
+ return c.json({ error: error.message }, 500);
786
+ }
787
+ });
788
+ }
789
+ for (const globalConfig of registry.getGlobals()) {
790
+ const slug = globalConfig.slug;
791
+ const basePath = `/api/globals/${slug}`;
792
+ app.get(basePath, async (c) => {
793
+ try {
794
+ const { user: ctxUser, tenantID: ctxTenantID } = await resolveAuthContext(c.req.raw, authMw, user, tenantID);
795
+ const access = await checkGlobalAccess(
796
+ globalConfig,
797
+ "read",
798
+ c.req.raw,
799
+ ctxUser,
800
+ ctxTenantID,
801
+ enablePublicAccess
802
+ );
803
+ if (!access.allowed) {
804
+ return c.json({ error: access.error }, access.status || 403);
805
+ }
806
+ const doc = await db.findOne({
807
+ collection: `_globals_${slug}`,
808
+ where: {},
809
+ tenantID: ctxTenantID
810
+ });
811
+ return c.json(doc || {});
812
+ } catch (error) {
813
+ return c.json({ error: error.message }, 500);
814
+ }
815
+ });
816
+ app.post(basePath, async (c) => {
817
+ try {
818
+ const { user: ctxUser, tenantID: ctxTenantID } = await resolveAuthContext(c.req.raw, authMw, user, tenantID);
819
+ const access = await checkGlobalAccess(
820
+ globalConfig,
821
+ "update",
822
+ c.req.raw,
823
+ ctxUser,
824
+ ctxTenantID,
825
+ enablePublicAccess
826
+ );
827
+ if (!access.allowed) {
828
+ return c.json({ error: access.error }, access.status || 403);
829
+ }
830
+ const body = await c.req.json();
831
+ const schema = registry.getZodSchema(slug);
832
+ const validated = schema.parse(body);
833
+ const doc = await db.create({
834
+ collection: `_globals_${slug}`,
835
+ data: { ...validated, id: slug },
836
+ tenantID: ctxTenantID
837
+ });
838
+ return c.json({ doc, message: "Updated successfully" });
839
+ } catch (error) {
840
+ if (error.name === "ZodError") {
841
+ return c.json(
842
+ { error: "Validation failed", details: error.errors },
843
+ 400
844
+ );
845
+ }
846
+ return c.json({ error: error.message }, 500);
847
+ }
848
+ });
849
+ if (slug === "email-settings") {
850
+ app.post(`${basePath}/test`, async (c) => {
851
+ try {
852
+ const { user: ctxUser, tenantID: ctxTenantID } = await resolveAuthContext(c.req.raw, authMw, user, tenantID);
853
+ const access = await checkGlobalAccess(
854
+ globalConfig,
855
+ "update",
856
+ c.req.raw,
857
+ ctxUser,
858
+ ctxTenantID,
859
+ enablePublicAccess
860
+ );
861
+ if (!access.allowed) {
862
+ return c.json(
863
+ { error: access.error },
864
+ access.status || 403
865
+ );
866
+ }
867
+ const body = await c.req.json();
868
+ const transportConfig = {
869
+ provider: body.provider,
870
+ from: body.fromEmail || body.from,
871
+ fromName: body.fromName,
872
+ replyTo: body.replyTo,
873
+ smtp: body.smtp ? {
874
+ host: body.smtp.host,
875
+ port: body.smtp.port,
876
+ secure: body.smtp.secure,
877
+ auth: {
878
+ user: body.smtp.username || body.smtp.user,
879
+ pass: body.smtp.password || body.smtp.pass
880
+ }
881
+ } : void 0,
882
+ resend: body.resend,
883
+ sendgrid: body.sendgrid,
884
+ mailgun: body.mailgun,
885
+ ses: body.ses
886
+ };
887
+ const transport = new chunkHVSQDZZJ_cjs.EmailTransport(transportConfig);
888
+ const recipient = body.testEmail || body.testEmailSection && body.testEmailSection.testEmail;
889
+ if (!recipient) {
890
+ return c.json({ error: "No test recipient email provided" }, 400);
891
+ }
892
+ await transport.send({
893
+ to: recipient,
894
+ subject: "Kyro CMS - Test Email",
895
+ html: `
896
+ <div style="font-family: sans-serif; max-width: 600px; margin: 0 auto; padding: 20px; border: 1px solid #e2e8f0; border-radius: 8px;">
897
+ <h1 style="color: #0b1222; margin-bottom: 16px;">Success! \u{1F680}</h1>
898
+ <p style="font-size: 16px; color: #334155; line-height: 1.6;">
899
+ Your email settings in <b>Kyro CMS</b> are working correctly.
900
+ </p>
901
+ <div style="background: #f8fafc; padding: 16px; border-radius: 6px; margin: 24px 0;">
902
+ <p style="margin: 0; font-size: 14px; color: #64748b;">
903
+ <b>Provider:</b> ${body.provider.toUpperCase()}
904
+ </p>
905
+ <p style="margin: 8px 0 0; font-size: 14px; color: #64748b;">
906
+ <b>Sent at:</b> ${(/* @__PURE__ */ new Date()).toLocaleString()}
907
+ </p>
908
+ </div>
909
+ <p style="font-size: 12px; color: #94a3b8; margin-top: 32px; border-top: 1px solid #f1f5f9; padding-top: 16px;">
910
+ This is a test email sent from the Kyro CMS Admin Panel.
911
+ </p>
912
+ </div>
913
+ `,
914
+ text: `Success! Your email settings in Kyro CMS are working correctly.
915
+
916
+ Provider: ${body.provider}
917
+ Sent at: ${(/* @__PURE__ */ new Date()).toLocaleString()}`
918
+ });
919
+ return c.json({ message: "Test email sent successfully!" });
920
+ } catch (error) {
921
+ console.error("[Email Test] Failed:", error);
922
+ return c.json(
923
+ { error: error.message || "Failed to send test email" },
924
+ 500
925
+ );
926
+ }
927
+ });
928
+ }
929
+ }
930
+ return app;
931
+ }
932
+ function createRESTAPI(registry, db, options) {
933
+ return createHonoApp({
934
+ registry,
935
+ db,
936
+ authSecret: options?.authSecret,
937
+ user: options?.user,
938
+ req: options?.req,
939
+ tenantID: options?.tenantID,
940
+ cors: options?.cors,
941
+ webhookService: options?.webhookService
942
+ });
943
+ }
944
+
945
+ exports.InMemoryRateLimiter = InMemoryRateLimiter;
946
+ exports.createHonoApp = createHonoApp;
947
+ exports.createRESTAPI = createRESTAPI;
948
+ exports.defaultExtractToken = defaultExtractToken;
949
+ exports.generateToken = generateToken;
950
+ //# sourceMappingURL=chunk-E63IF3MD.cjs.map
951
+ //# sourceMappingURL=chunk-E63IF3MD.cjs.map