@cequrebackends/cequre-ts 0.11.4

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 (60) hide show
  1. package/dist/adapters/bun/bun-cron.d.ts +20 -0
  2. package/dist/adapters/bun/bun-media.d.ts +9 -0
  3. package/dist/adapters/bun/bun-redis-cache.d.ts +33 -0
  4. package/dist/adapters/bun/bun-response.d.ts +13 -0
  5. package/dist/adapters/bun/bun-server.d.ts +6 -0
  6. package/dist/adapters/bun/bun-storage.d.ts +10 -0
  7. package/dist/adapters/bun/bun-websocket.d.ts +104 -0
  8. package/dist/adapters/bun/index.d.ts +9 -0
  9. package/dist/adapters/bun/index.js +547 -0
  10. package/dist/adapters/node/index.d.ts +9 -0
  11. package/dist/adapters/node/index.js +902 -0
  12. package/dist/adapters/node/node-cron.d.ts +20 -0
  13. package/dist/adapters/node/node-media.d.ts +9 -0
  14. package/dist/adapters/node/node-redis-cache.d.ts +32 -0
  15. package/dist/adapters/node/node-response.d.ts +13 -0
  16. package/dist/adapters/node/node-server.d.ts +6 -0
  17. package/dist/adapters/node/node-storage.d.ts +10 -0
  18. package/dist/adapters/node/node-websocket.d.ts +102 -0
  19. package/dist/index-17yswtmg.js +175 -0
  20. package/dist/index-kyvy0s1x.js +2662 -0
  21. package/dist/index-mfqj7cwr.js +165 -0
  22. package/dist/index-rf1kdn5b.js +732 -0
  23. package/dist/index.d.ts +18 -0
  24. package/dist/index.js +3152 -0
  25. package/dist/interface-map.d.ts +175 -0
  26. package/dist/shared/core/adapter.d.ts +84 -0
  27. package/dist/shared/core/base-sql-adapter.d.ts +34 -0
  28. package/dist/shared/core/cache.d.ts +8 -0
  29. package/dist/shared/core/email.d.ts +53 -0
  30. package/dist/shared/core/index.d.ts +12 -0
  31. package/dist/shared/core/index.js +47 -0
  32. package/dist/shared/core/openapi.d.ts +24 -0
  33. package/dist/shared/core/plugins.d.ts +2 -0
  34. package/dist/shared/core/request.d.ts +32 -0
  35. package/dist/shared/core/sdk.d.ts +3 -0
  36. package/dist/shared/core/stream.d.ts +24 -0
  37. package/dist/shared/core/types-generator.d.ts +0 -0
  38. package/dist/shared/core/types.d.ts +304 -0
  39. package/dist/shared/core/ulid.d.ts +5 -0
  40. package/dist/shared/core/validator.d.ts +32 -0
  41. package/dist/shared/main/access-evaluator.d.ts +13 -0
  42. package/dist/shared/main/access.d.ts +34 -0
  43. package/dist/shared/main/aot.d.ts +3 -0
  44. package/dist/shared/main/hooks.d.ts +76 -0
  45. package/dist/shared/main/population.d.ts +13 -0
  46. package/dist/shared/main/router.d.ts +112 -0
  47. package/dist/shared/main/runtime.d.ts +195 -0
  48. package/dist/shared/main/sse.d.ts +87 -0
  49. package/dist/shared/utils/crypto.d.ts +23 -0
  50. package/dist/shared/utils/durable-queue.d.ts +20 -0
  51. package/dist/shared/utils/duration.d.ts +15 -0
  52. package/dist/shared/utils/error.d.ts +52 -0
  53. package/dist/shared/utils/kv/adapters/memory.d.ts +20 -0
  54. package/dist/shared/utils/kv/adapters/sqlite.d.ts +32 -0
  55. package/dist/shared/utils/kv/index.d.ts +37 -0
  56. package/dist/shared/utils/kv/types.d.ts +38 -0
  57. package/dist/shared/utils/logger.d.ts +42 -0
  58. package/dist/shared/utils/queue-manager.d.ts +64 -0
  59. package/dist/shared/utils/url.d.ts +13 -0
  60. package/package.json +63 -0
@@ -0,0 +1,547 @@
1
+ // @bun
2
+ import {
3
+ CequreStreamMedia,
4
+ UPGRADED,
5
+ empty,
6
+ error,
7
+ file,
8
+ json,
9
+ methodNotAllowed,
10
+ notFound,
11
+ redirect,
12
+ routeErrorToResponse,
13
+ stream,
14
+ toResponse
15
+ } from "../../index-mfqj7cwr.js";
16
+ import {
17
+ CequreQueueManager,
18
+ RedisAdapter,
19
+ init_bun_redis_cache,
20
+ init_logger,
21
+ logger
22
+ } from "../../index-rf1kdn5b.js";
23
+ import {
24
+ CequreError,
25
+ ulid
26
+ } from "../../index-17yswtmg.js";
27
+
28
+ // adapters/bun/bun-server.ts
29
+ class BunServerProvider {
30
+ server;
31
+ start(config) {
32
+ const tls = config.tls;
33
+ let finalTls = tls;
34
+ if (tls && tls.cert && tls.key) {
35
+ finalTls = {
36
+ cert: Bun.file(tls.cert),
37
+ key: Bun.file(tls.key),
38
+ passphrase: tls.passphrase,
39
+ serverName: tls.serverName
40
+ };
41
+ }
42
+ this.server = Bun.serve({
43
+ port: config.port ?? (process.env.PORT ? parseInt(process.env.PORT, 10) : 3000),
44
+ hostname: config.hostname,
45
+ tls: finalTls,
46
+ ...config.maxRequestBodySize ? { maxRequestBodySize: config.maxRequestBodySize } : {},
47
+ ...config.routes ? { routes: config.routes } : {},
48
+ fetch: config.fetch
49
+ });
50
+ console.log(`\uD83D\uDE80 Cequre starting on http://${this.server.hostname}:${this.server.port}`);
51
+ return this.server;
52
+ }
53
+ async stop() {
54
+ if (this.server) {
55
+ this.server.stop(true);
56
+ }
57
+ }
58
+ }
59
+ // adapters/bun/bun-cron.ts
60
+ init_logger();
61
+
62
+ class BunCronProvider {
63
+ localJobs = new Map;
64
+ useBullMQ = false;
65
+ constructor() {
66
+ try {
67
+ CequreQueueManager.getInstance();
68
+ this.useBullMQ = true;
69
+ } catch {
70
+ this.useBullMQ = false;
71
+ }
72
+ }
73
+ registerJob(name, schedule, handler) {
74
+ if (this.useBullMQ) {
75
+ const qm = CequreQueueManager.getInstance();
76
+ qm.registerWorker("cequre_cron", async (job) => {
77
+ if (job.name === name) {
78
+ try {
79
+ await Promise.resolve(handler());
80
+ } catch (err) {
81
+ logger.error(err, `[Cequre Cron (BullMQ)] Job "${name}" failed:`);
82
+ throw new Error(String(err instanceof Error ? err.message : err));
83
+ }
84
+ }
85
+ }).catch((err) => {
86
+ logger.error(err, `[Cequre Cron (BullMQ)] Failed to register worker for "${name}":`);
87
+ });
88
+ qm.addJob("cequre_cron", name, {}, {
89
+ repeat: { pattern: schedule },
90
+ jobId: `cron_${name}`,
91
+ removeOnComplete: true,
92
+ removeOnFail: 100
93
+ }).catch((err) => {
94
+ logger.error(err, `[Cequre Cron (BullMQ)] Failed to register job "${name}":`);
95
+ });
96
+ } else {
97
+ if (this.localJobs.has(name)) {
98
+ throw CequreError.Conflict(`[Cequre Cron] A cron job with the name "${name}" is already registered.`);
99
+ }
100
+ const job = Bun.cron(schedule, async () => {
101
+ try {
102
+ await handler();
103
+ } catch (err) {
104
+ logger.error(err, `[Cequre Cron] Job "${name}" failed:`);
105
+ }
106
+ });
107
+ this.localJobs.set(name, job);
108
+ }
109
+ }
110
+ async stop(name) {
111
+ if (this.useBullMQ) {
112
+ const qm = CequreQueueManager.getInstance();
113
+ const queue = qm.getQueue("cequre_cron");
114
+ const repeatableJobs = await queue.getRepeatableJobs();
115
+ const job = repeatableJobs.find((j) => j.name === name);
116
+ if (job) {
117
+ await queue.removeRepeatableByKey(job.key);
118
+ return true;
119
+ }
120
+ return false;
121
+ } else {
122
+ const job = this.localJobs.get(name);
123
+ if (job && typeof job.stop === "function") {
124
+ job.stop();
125
+ this.localJobs.delete(name);
126
+ return true;
127
+ }
128
+ return false;
129
+ }
130
+ }
131
+ async stopAll() {
132
+ if (this.useBullMQ) {
133
+ const qm = CequreQueueManager.getInstance();
134
+ const queue = qm.getQueue("cequre_cron");
135
+ const repeatableJobs = await queue.getRepeatableJobs();
136
+ for (const job of repeatableJobs) {
137
+ await queue.removeRepeatableByKey(job.key);
138
+ }
139
+ } else {
140
+ for (const [name, job] of this.localJobs.entries()) {
141
+ if (typeof job.stop === "function") {
142
+ try {
143
+ job.stop();
144
+ } catch (e) {
145
+ logger.error(e, `[Cequre Cron] Error stopping job "${name}":`);
146
+ }
147
+ }
148
+ }
149
+ this.localJobs.clear();
150
+ }
151
+ }
152
+ async list() {
153
+ if (this.useBullMQ) {
154
+ const qm = CequreQueueManager.getInstance();
155
+ const queue = qm.getQueue("cequre_cron");
156
+ const jobs = await queue.getRepeatableJobs();
157
+ return jobs.map((j) => j.name);
158
+ } else {
159
+ return Array.from(this.localJobs.keys());
160
+ }
161
+ }
162
+ startAll() {}
163
+ }
164
+ // adapters/bun/bun-websocket.ts
165
+ class WebSocketManager {
166
+ connections = new Map;
167
+ rooms = new Map;
168
+ connectionRooms = new Map;
169
+ metadata = new Map;
170
+ lastPong = new Map;
171
+ heartbeatTimer = null;
172
+ register(ws) {
173
+ this.connections.set(ws.id, ws);
174
+ this.connectionRooms.set(ws.id, new Set);
175
+ this.metadata.set(ws.id, {});
176
+ this.lastPong.set(ws.id, Date.now());
177
+ }
178
+ remove(wsOrId) {
179
+ const id = typeof wsOrId === "string" ? wsOrId : wsOrId.id;
180
+ for (const room of this.connectionRooms.get(id) ?? []) {
181
+ this.leaveRoom(id, room);
182
+ }
183
+ this.connections.delete(id);
184
+ this.connectionRooms.delete(id);
185
+ this.metadata.delete(id);
186
+ this.lastPong.delete(id);
187
+ }
188
+ pong(id) {
189
+ if (this.lastPong.has(id))
190
+ this.lastPong.set(id, Date.now());
191
+ }
192
+ startHeartbeat(intervalMs = 30000, timeoutMs = 1e4) {
193
+ if (this.heartbeatTimer !== null)
194
+ return;
195
+ const deadline = intervalMs + timeoutMs;
196
+ this.heartbeatTimer = setInterval(() => {
197
+ const now = Date.now();
198
+ for (const [id, lastSeen] of this.lastPong) {
199
+ if (now - lastSeen > deadline)
200
+ this.remove(id);
201
+ }
202
+ for (const ws of this.connections.values()) {
203
+ ws.send(JSON.stringify({ type: "ping" }));
204
+ }
205
+ }, intervalMs);
206
+ if (this.heartbeatTimer.unref)
207
+ this.heartbeatTimer.unref();
208
+ }
209
+ stopHeartbeat() {
210
+ if (this.heartbeatTimer)
211
+ clearInterval(this.heartbeatTimer);
212
+ this.heartbeatTimer = null;
213
+ }
214
+ joinRoom(id, room) {
215
+ if (!this.rooms.has(room))
216
+ this.rooms.set(room, new Set);
217
+ this.rooms.get(room).add(id);
218
+ this.connectionRooms.get(id)?.add(room);
219
+ }
220
+ leaveRoom(id, room) {
221
+ this.rooms.get(room)?.delete(id);
222
+ if (this.rooms.get(room)?.size === 0)
223
+ this.rooms.delete(room);
224
+ this.connectionRooms.get(id)?.delete(room);
225
+ }
226
+ getRoomMembers(room) {
227
+ return [...this.rooms.get(room) ?? []];
228
+ }
229
+ getConnectionRooms(id) {
230
+ return [...this.connectionRooms.get(id) ?? []];
231
+ }
232
+ listRooms() {
233
+ return [...this.rooms.keys()];
234
+ }
235
+ sendTo(id, payload) {
236
+ const ws = this.connections.get(id);
237
+ if (!ws)
238
+ return false;
239
+ ws.send(JSON.stringify(payload));
240
+ return true;
241
+ }
242
+ broadcastToRoom(room, payload, { exclude = [] } = {}) {
243
+ const ids = this.rooms.get(room);
244
+ if (!ids)
245
+ return 0;
246
+ let sent = 0;
247
+ for (const id of ids) {
248
+ if (exclude.includes(id))
249
+ continue;
250
+ if (this.sendTo(id, payload))
251
+ sent++;
252
+ }
253
+ return sent;
254
+ }
255
+ broadcastAll(payload, { exclude = [] } = {}) {
256
+ let sent = 0;
257
+ for (const id of this.connections.keys()) {
258
+ if (exclude.includes(id))
259
+ continue;
260
+ if (this.sendTo(id, payload))
261
+ sent++;
262
+ }
263
+ return sent;
264
+ }
265
+ setMeta(id, key, value) {
266
+ const meta = this.metadata.get(id);
267
+ if (meta)
268
+ meta[key] = value;
269
+ }
270
+ getMeta(id, key) {
271
+ return this.metadata.get(id)?.[key];
272
+ }
273
+ get connectionCount() {
274
+ return this.connections.size;
275
+ }
276
+ get roomCount() {
277
+ return this.rooms.size;
278
+ }
279
+ getStats() {
280
+ return {
281
+ connections: this.connectionCount,
282
+ rooms: Object.fromEntries([...this.rooms.entries()].map(([room, ids]) => [room, ids.size])),
283
+ heartbeatActive: this.heartbeatTimer !== null
284
+ };
285
+ }
286
+ }
287
+ var wsManager = new WebSocketManager;
288
+ function toServerWebSocket(ws) {
289
+ return {
290
+ id: ws.data.id,
291
+ data: ws.data,
292
+ send: (message, compress) => ws.send(message, compress)
293
+ };
294
+ }
295
+ function parseMessage(message) {
296
+ if (typeof message !== "string") {
297
+ return { type: "binary", payload: message };
298
+ }
299
+ try {
300
+ const parsed = JSON.parse(message);
301
+ return parsed && typeof parsed === "object" ? parsed : { type: "message", payload: parsed };
302
+ } catch {
303
+ return { type: "message", payload: message };
304
+ }
305
+ }
306
+ function createWebSocketHandler({
307
+ heartbeat,
308
+ onJoinRoom
309
+ } = {}) {
310
+ const startHeartbeat = () => {
311
+ if (heartbeat === false)
312
+ return;
313
+ wsManager.startHeartbeat(heartbeat?.interval, heartbeat?.timeout);
314
+ };
315
+ return {
316
+ open(ws) {
317
+ const wrapped = toServerWebSocket(ws);
318
+ wsManager.register(wrapped);
319
+ startHeartbeat();
320
+ ws.send(JSON.stringify({ type: "connected", id: wrapped.id }));
321
+ },
322
+ async message(ws, rawMessage) {
323
+ const message = parseMessage(rawMessage);
324
+ const wrapped = toServerWebSocket(ws);
325
+ const { id } = wrapped;
326
+ switch (message.type) {
327
+ case "join":
328
+ if (!message.room)
329
+ return;
330
+ if (onJoinRoom && !await onJoinRoom(message.room, wrapped)) {
331
+ ws.send(JSON.stringify({ type: "error", message: `Access denied to room '${message.room}'` }));
332
+ return;
333
+ }
334
+ wsManager.joinRoom(id, message.room);
335
+ ws.send(JSON.stringify({ type: "joined", room: message.room }));
336
+ return;
337
+ case "leave":
338
+ if (!message.room)
339
+ return;
340
+ wsManager.leaveRoom(id, message.room);
341
+ ws.send(JSON.stringify({ type: "left", room: message.room }));
342
+ return;
343
+ case "broadcast":
344
+ if (message.room) {
345
+ if (!wsManager.getConnectionRooms(id).includes(message.room)) {
346
+ ws.send(JSON.stringify({ type: "error", message: "Not in room" }));
347
+ return;
348
+ }
349
+ wsManager.broadcastToRoom(message.room, { type: "message", from: id, payload: message.payload }, { exclude: [id] });
350
+ }
351
+ return;
352
+ case "ping":
353
+ ws.send(JSON.stringify({ type: "pong" }));
354
+ return;
355
+ case "pong":
356
+ wsManager.pong(id);
357
+ return;
358
+ default:
359
+ ws.send(JSON.stringify({ type: "error", message: `Unknown type: ${message.type}` }));
360
+ }
361
+ },
362
+ close(ws) {
363
+ wsManager.remove(ws.data.id);
364
+ }
365
+ };
366
+ }
367
+ function createBunWebSocketRoute({
368
+ path = "/ws",
369
+ heartbeat,
370
+ onJoinRoom
371
+ } = {}) {
372
+ const handler = createWebSocketHandler({ heartbeat, onJoinRoom });
373
+ return async (request, server) => {
374
+ if (!server)
375
+ return new Response(JSON.stringify({ message: "WebSocket upgrade requires Bun.serve to pass the server into fetch" }), { status: 500 });
376
+ const didUpgrade = server.upgrade(request, {
377
+ data: {
378
+ id: ulid(),
379
+ path,
380
+ handler
381
+ }
382
+ });
383
+ if (didUpgrade) {
384
+ return;
385
+ }
386
+ return new Response(JSON.stringify({ message: "WebSocket upgrade failed" }), { status: 400 });
387
+ };
388
+ }
389
+ function createBunWebSocketHandlers() {
390
+ return {
391
+ open(ws) {
392
+ return ws.data.handler.open?.(ws);
393
+ },
394
+ message(ws, message) {
395
+ return ws.data.handler.message?.(ws, message);
396
+ },
397
+ close(ws, code, reason) {
398
+ return ws.data.handler.close?.(ws, code, reason);
399
+ },
400
+ drain(ws) {
401
+ return ws.data.handler.drain?.(ws);
402
+ }
403
+ };
404
+ }
405
+
406
+ class CequreWebsocket {
407
+ static get manager() {
408
+ return wsManager;
409
+ }
410
+ static route(options = {}) {
411
+ return createBunWebSocketRoute(options);
412
+ }
413
+ static handler(options = {}) {
414
+ return createWebSocketHandler(options);
415
+ }
416
+ static handlers() {
417
+ return createBunWebSocketHandlers();
418
+ }
419
+ static register(ws) {
420
+ return wsManager.register(ws);
421
+ }
422
+ static remove(wsOrId) {
423
+ return wsManager.remove(wsOrId);
424
+ }
425
+ static pong(id) {
426
+ return wsManager.pong(id);
427
+ }
428
+ static startHeartbeat(intervalMs, timeoutMs) {
429
+ return wsManager.startHeartbeat(intervalMs, timeoutMs);
430
+ }
431
+ static stopHeartbeat() {
432
+ return wsManager.stopHeartbeat();
433
+ }
434
+ static joinRoom(id, room) {
435
+ return wsManager.joinRoom(id, room);
436
+ }
437
+ static leaveRoom(id, room) {
438
+ return wsManager.leaveRoom(id, room);
439
+ }
440
+ static getRoomMembers(room) {
441
+ return wsManager.getRoomMembers(room);
442
+ }
443
+ static getConnectionRooms(id) {
444
+ return wsManager.getConnectionRooms(id);
445
+ }
446
+ static listRooms() {
447
+ return wsManager.listRooms();
448
+ }
449
+ static sendTo(id, payload) {
450
+ return wsManager.sendTo(id, payload);
451
+ }
452
+ static broadcastToRoom(room, payload, opts) {
453
+ return wsManager.broadcastToRoom(room, payload, opts);
454
+ }
455
+ static broadcastAll(payload, opts) {
456
+ return wsManager.broadcastAll(payload, opts);
457
+ }
458
+ static setMeta(id, key, value) {
459
+ return wsManager.setMeta(id, key, value);
460
+ }
461
+ static getMeta(id, key) {
462
+ return wsManager.getMeta(id, key);
463
+ }
464
+ static get connectionCount() {
465
+ return wsManager.connectionCount;
466
+ }
467
+ static get roomCount() {
468
+ return wsManager.roomCount;
469
+ }
470
+ static getStats() {
471
+ return wsManager.getStats();
472
+ }
473
+ }
474
+ // adapters/bun/bun-storage.ts
475
+ import fs from "fs";
476
+ import path from "path";
477
+ class LocalStorageProvider {
478
+ uploadDir;
479
+ apiPrefix;
480
+ constructor(uploadDir = "uploads", apiPrefix = "/api") {
481
+ this.apiPrefix = apiPrefix;
482
+ this.uploadDir = path.resolve(process.cwd(), uploadDir);
483
+ if (!fs.existsSync(this.uploadDir)) {
484
+ fs.mkdirSync(this.uploadDir, { recursive: true });
485
+ }
486
+ }
487
+ async saveFile(file2, options) {
488
+ const ext = file2.name ? path.extname(file2.name) : "";
489
+ const safeName = options?.filename ? options.filename : `${ulid()}${ext}`;
490
+ const filePath = path.join(this.uploadDir, safeName);
491
+ await Bun.write(filePath, file2);
492
+ return {
493
+ filename: safeName,
494
+ originalName: file2.name || "upload",
495
+ mimetype: file2.type || "application/octet-stream",
496
+ size: file2.size,
497
+ url: `${this.apiPrefix}/uploads/${safeName}`
498
+ };
499
+ }
500
+ async deleteFile(filename) {
501
+ const filePath = path.join(this.uploadDir, filename);
502
+ try {
503
+ if (fs.existsSync(filePath)) {
504
+ await fs.promises.unlink(filePath);
505
+ }
506
+ } catch (e) {
507
+ console.error(`Failed to delete file ${filePath}`, e);
508
+ }
509
+ }
510
+ }
511
+
512
+ // adapters/bun/index.ts
513
+ init_bun_redis_cache();
514
+ function withBun(config) {
515
+ return {
516
+ ...config,
517
+ serverProvider: config.serverProvider || new BunServerProvider,
518
+ cronProvider: config.cronProvider || new BunCronProvider,
519
+ realtimeProvider: config.realtimeProvider || { websocket: CequreWebsocket },
520
+ storageProvider: config.storageProvider || new LocalStorageProvider
521
+ };
522
+ }
523
+ export {
524
+ wsManager,
525
+ withBun,
526
+ toResponse,
527
+ stream,
528
+ routeErrorToResponse,
529
+ redirect,
530
+ notFound,
531
+ methodNotAllowed,
532
+ json,
533
+ file,
534
+ error,
535
+ empty,
536
+ createWebSocketHandler,
537
+ createBunWebSocketRoute,
538
+ createBunWebSocketHandlers,
539
+ WebSocketManager,
540
+ UPGRADED,
541
+ RedisAdapter,
542
+ LocalStorageProvider,
543
+ CequreWebsocket,
544
+ CequreStreamMedia,
545
+ BunServerProvider,
546
+ BunCronProvider
547
+ };
@@ -0,0 +1,9 @@
1
+ export * from "./node-server";
2
+ export * from "./node-cron";
3
+ export * from "./node-websocket";
4
+ export * from "./node-storage";
5
+ export * from "./node-redis-cache";
6
+ export * from "./node-response";
7
+ export * from "./node-media";
8
+ import type { CequreConfig } from "../../shared/main/runtime";
9
+ export declare function withNode(config: CequreConfig): CequreConfig;