@cequrebackends/cequre-ts 0.12.1 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/bun/bun-websocket.d.ts +2 -2
- package/dist/adapters/bun/index.js +2 -2
- package/dist/adapters/node/index.js +1 -1
- package/dist/{index-rf1kdn5b.js → index-c3vh32en.js} +33 -15
- package/dist/index.js +21 -10
- package/dist/shared/core/stream.d.ts +1 -1
- package/dist/shared/main/router.d.ts +1 -1
- package/dist/shared/main/runtime.d.ts +4 -4
- package/package.json +1 -1
|
@@ -65,11 +65,11 @@ export declare function createBunWebSocketRoute({ path, heartbeat, onJoinRoom, }
|
|
|
65
65
|
timeout?: number;
|
|
66
66
|
} | false;
|
|
67
67
|
onJoinRoom?: (room: string, ws: CequreServerWebSocket) => MaybePromise<boolean>;
|
|
68
|
-
}): (request: Request, server
|
|
68
|
+
}): (request: Request, server?: any) => Promise<any>;
|
|
69
69
|
export declare function createBunWebSocketHandlers(): Bun.WebSocketHandler<CequreWebSocketData>;
|
|
70
70
|
export declare class CequreWebsocket {
|
|
71
71
|
static get manager(): WebSocketManager;
|
|
72
|
-
static route(options?: Parameters<typeof createBunWebSocketRoute>[0]): (request: Request, server
|
|
72
|
+
static route(options?: Parameters<typeof createBunWebSocketRoute>[0]): (request: Request, server?: any) => Promise<any>;
|
|
73
73
|
static handler(options?: Parameters<typeof createWebSocketHandler>[0]): CequreWebSocketHandler;
|
|
74
74
|
static handlers(): Bun.WebSocketHandler<CequreWebSocketData>;
|
|
75
75
|
static register(ws: CequreServerWebSocket): void;
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
init_bun_redis_cache,
|
|
20
20
|
init_logger,
|
|
21
21
|
logger
|
|
22
|
-
} from "../../index-
|
|
22
|
+
} from "../../index-c3vh32en.js";
|
|
23
23
|
import {
|
|
24
24
|
CequreError,
|
|
25
25
|
ulid
|
|
@@ -382,7 +382,7 @@ function createBunWebSocketRoute({
|
|
|
382
382
|
}
|
|
383
383
|
});
|
|
384
384
|
if (didUpgrade) {
|
|
385
|
-
return;
|
|
385
|
+
return UPGRADED;
|
|
386
386
|
}
|
|
387
387
|
return new Response(JSON.stringify({ message: "WebSocket upgrade failed" }), { status: 400 });
|
|
388
388
|
};
|
|
@@ -556,6 +556,7 @@ var init_logger = __esm(() => {
|
|
|
556
556
|
|
|
557
557
|
// shared/utils/queue-manager.ts
|
|
558
558
|
import { Queue as BullQueue, Worker as BullWorker, QueueEvents as BullQueueEvents } from "bullmq";
|
|
559
|
+
import { Effect } from "effect";
|
|
559
560
|
init_logger();
|
|
560
561
|
|
|
561
562
|
class BullMQQueueAdapter {
|
|
@@ -627,6 +628,11 @@ class CequreQueueManager {
|
|
|
627
628
|
...this.config.defaultQueueOptions ?? {},
|
|
628
629
|
...this.getBullMQBaseOptions()
|
|
629
630
|
});
|
|
631
|
+
queue.on("error", (err) => {
|
|
632
|
+
if (err?.message?.includes("Connection is closed"))
|
|
633
|
+
return;
|
|
634
|
+
logger.error(err, `[ ${name.toUpperCase()} QUEUE ] Error`);
|
|
635
|
+
});
|
|
630
636
|
const wrapped = new BullMQQueueAdapter(queue);
|
|
631
637
|
this.queues.set(name, wrapped);
|
|
632
638
|
return wrapped;
|
|
@@ -663,6 +669,8 @@ class CequreQueueManager {
|
|
|
663
669
|
logger.error(err, `${queueNameForLogs} Job ${job?.id ?? "unknown"} failed`);
|
|
664
670
|
});
|
|
665
671
|
worker.on("error", (err) => {
|
|
672
|
+
if (err?.message?.includes("Connection is closed"))
|
|
673
|
+
return;
|
|
666
674
|
logger.error(err, `${queueNameForLogs} Worker error`);
|
|
667
675
|
});
|
|
668
676
|
await worker.waitUntilReady();
|
|
@@ -685,6 +693,11 @@ class CequreQueueManager {
|
|
|
685
693
|
const events = new BullQueueEvents(name, {
|
|
686
694
|
...this.getBullMQBaseOptions()
|
|
687
695
|
});
|
|
696
|
+
events.on("error", (err) => {
|
|
697
|
+
if (err?.message?.includes("Connection is closed"))
|
|
698
|
+
return;
|
|
699
|
+
logger.error(err, `[ ${name.toUpperCase()} QUEUE EVENTS ] Error`);
|
|
700
|
+
});
|
|
688
701
|
const wrapped = {
|
|
689
702
|
disconnect: async () => {
|
|
690
703
|
await events.close();
|
|
@@ -707,21 +720,26 @@ class CequreQueueManager {
|
|
|
707
720
|
if (this.closing)
|
|
708
721
|
return;
|
|
709
722
|
this.closing = true;
|
|
710
|
-
const
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
};
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
723
|
+
const closeItemEffect = (item, label) => Effect.tryPromise({
|
|
724
|
+
try: async () => {
|
|
725
|
+
if (item.close)
|
|
726
|
+
await item.close();
|
|
727
|
+
else if (item.disconnect)
|
|
728
|
+
await item.disconnect();
|
|
729
|
+
},
|
|
730
|
+
catch: (err) => err
|
|
731
|
+
}).pipe(Effect.catchAll((err) => Effect.sync(() => {
|
|
732
|
+
logger.error(err, `[QueueManager] Error closing ${label}`);
|
|
733
|
+
})));
|
|
734
|
+
const closeGroupEffect = (items, label) => Effect.all(items.map((item) => closeItemEffect(item, label)), { concurrency: "unbounded" });
|
|
735
|
+
const workers = Array.from(this.workers.values());
|
|
736
|
+
const queueEvents = Array.from(this.queueEvents.values());
|
|
737
|
+
const queues = Array.from(this.queues.values());
|
|
738
|
+
await Effect.runPromise(Effect.gen(function* () {
|
|
739
|
+
yield* closeGroupEffect(workers, "worker");
|
|
740
|
+
yield* closeGroupEffect(queueEvents, "queue events");
|
|
741
|
+
yield* closeGroupEffect(queues, "queue");
|
|
742
|
+
}));
|
|
725
743
|
this.workers.clear();
|
|
726
744
|
this.queueEvents.clear();
|
|
727
745
|
this.queues.clear();
|
package/dist/index.js
CHANGED
|
@@ -37,7 +37,7 @@ import {
|
|
|
37
37
|
init_kv,
|
|
38
38
|
init_logger,
|
|
39
39
|
logger
|
|
40
|
-
} from "./index-
|
|
40
|
+
} from "./index-c3vh32en.js";
|
|
41
41
|
import {
|
|
42
42
|
CequreError,
|
|
43
43
|
__require,
|
|
@@ -1449,12 +1449,12 @@ async function populateDocuments(schema, collectionSlug, docs, adapter, depth) {
|
|
|
1449
1449
|
// shared/main/runtime.ts
|
|
1450
1450
|
init_openapi();
|
|
1451
1451
|
init_kv();
|
|
1452
|
-
import { RateLimiter } from "@cequrebackends/
|
|
1452
|
+
import { RateLimiter } from "@cequrebackends/plugin-security";
|
|
1453
1453
|
init_logger();
|
|
1454
1454
|
import path from "path";
|
|
1455
1455
|
import { AsyncLocalStorage } from "async_hooks";
|
|
1456
|
-
import { computeAuditHmac, verifyAuditChain } from "@cequrebackends/
|
|
1457
|
-
import { encryptField, decryptField, isEncrypted } from "@cequrebackends/
|
|
1456
|
+
import { computeAuditHmac, verifyAuditChain } from "@cequrebackends/plugin-security";
|
|
1457
|
+
import { encryptField, decryptField, isEncrypted } from "@cequrebackends/plugin-security";
|
|
1458
1458
|
|
|
1459
1459
|
// shared/utils/crypto.ts
|
|
1460
1460
|
async function sha256Hex(input) {
|
|
@@ -2532,8 +2532,13 @@ class CequreRuntime {
|
|
|
2532
2532
|
result[f.name] = f.default;
|
|
2533
2533
|
}
|
|
2534
2534
|
const v = result[f.name];
|
|
2535
|
-
if (v !== undefined &&
|
|
2536
|
-
|
|
2535
|
+
if (v !== undefined && v !== null) {
|
|
2536
|
+
if (typeof v === "string" && !isEncrypted(v)) {
|
|
2537
|
+
result[f.name] = await encryptField(key, v);
|
|
2538
|
+
} else if (typeof v !== "string") {
|
|
2539
|
+
const jsonStr = JSON.stringify(v);
|
|
2540
|
+
result[f.name] = await encryptField(key, jsonStr);
|
|
2541
|
+
}
|
|
2537
2542
|
}
|
|
2538
2543
|
}
|
|
2539
2544
|
}
|
|
@@ -2553,8 +2558,13 @@ class CequreRuntime {
|
|
|
2553
2558
|
for (const [k, v] of Object.entries(result)) {
|
|
2554
2559
|
if (encFields.has(k) && typeof v === "string" && isEncrypted(v)) {
|
|
2555
2560
|
const decrypted = await decryptField(key, v);
|
|
2556
|
-
if (decrypted !== null)
|
|
2557
|
-
|
|
2561
|
+
if (decrypted !== null) {
|
|
2562
|
+
try {
|
|
2563
|
+
result[k] = JSON.parse(decrypted);
|
|
2564
|
+
} catch {
|
|
2565
|
+
result[k] = decrypted;
|
|
2566
|
+
}
|
|
2567
|
+
}
|
|
2558
2568
|
}
|
|
2559
2569
|
}
|
|
2560
2570
|
return result;
|
|
@@ -2881,6 +2891,7 @@ class CequreRuntime {
|
|
|
2881
2891
|
},
|
|
2882
2892
|
maxBodyBytes: this.schema.core?.api?.maxBodyBytes,
|
|
2883
2893
|
idempotencyKV: this.idempotencyKV,
|
|
2894
|
+
state: (server2) => server2,
|
|
2884
2895
|
headers: {
|
|
2885
2896
|
...this.schema.security?.headers?.enabled ? {
|
|
2886
2897
|
"X-Content-Type-Options": "nosniff",
|
|
@@ -2969,7 +2980,7 @@ class CequreRuntime {
|
|
|
2969
2980
|
}
|
|
2970
2981
|
let executionPromise = (async () => {
|
|
2971
2982
|
let r2 = await this.router.handle(req, srv, ctx.user, this);
|
|
2972
|
-
return r2
|
|
2983
|
+
return r2;
|
|
2973
2984
|
})();
|
|
2974
2985
|
const timeoutMs = this.schema.core?.api?.requestTimeoutMs;
|
|
2975
2986
|
let timeoutHandle;
|
|
@@ -2984,7 +2995,7 @@ class CequreRuntime {
|
|
|
2984
2995
|
}
|
|
2985
2996
|
let res = await executionPromise;
|
|
2986
2997
|
for (const plugin of this.plugins) {
|
|
2987
|
-
if (plugin.afterRequest)
|
|
2998
|
+
if (plugin.afterRequest && res)
|
|
2988
2999
|
await plugin.afterRequest(ctx, res);
|
|
2989
3000
|
}
|
|
2990
3001
|
return res;
|
|
@@ -13,7 +13,7 @@ export interface DurableStreamStore {
|
|
|
13
13
|
* In-memory implementation of DurableStreamStore.
|
|
14
14
|
* [Development Only] This uses a local array ring buffer.
|
|
15
15
|
* It does not scale across multiple servers and loses data on restart.
|
|
16
|
-
* Use @cequrebackends/
|
|
16
|
+
* Use @cequrebackends/plugin-durable-streams for production.
|
|
17
17
|
*/
|
|
18
18
|
export declare class MemoryStreamStore implements DurableStreamStore {
|
|
19
19
|
private streams;
|
|
@@ -2,7 +2,7 @@ import type { TSchema, Static } from "@sinclair/typebox";
|
|
|
2
2
|
import type { CequreRuntime } from "./runtime";
|
|
3
3
|
import type { CequreRouteContext, CequreParams, CequreQuery } from "../core/request";
|
|
4
4
|
import { type BunRouteResult } from "../../adapters/bun/bun-response";
|
|
5
|
-
import type { CequreMonitoringAPI } from "@cequrebackends/
|
|
5
|
+
import type { CequreMonitoringAPI } from "@cequrebackends/plugin-monitoring";
|
|
6
6
|
export type CequreRouteHandler<TCollections extends Record<string, any> = any, TState = unknown, TParams extends TSchema | undefined = undefined, TQuery extends TSchema | undefined = undefined, TBody extends TSchema | undefined = undefined, TResponse extends TSchema | undefined = undefined> = (context: CequreRouteContext<TCollections, TState, TParams extends TSchema ? Static<TParams> : CequreParams, TQuery extends TSchema ? Static<TQuery> : CequreQuery, TBody extends TSchema ? Static<TBody> : unknown>) => TResponse extends TSchema ? BunRouteResult<Static<TResponse>> | Promise<BunRouteResult<Static<TResponse>>> : BunRouteResult | Promise<BunRouteResult>;
|
|
7
7
|
export interface CequreRouteOptions<TParams extends TSchema | undefined = undefined, TQuery extends TSchema | undefined = undefined, TBody extends TSchema | undefined = undefined, TResponse extends TSchema | undefined = undefined> {
|
|
8
8
|
body?: TBody;
|
|
@@ -4,12 +4,12 @@ import { type DurableStreamStore } from "../core/stream";
|
|
|
4
4
|
import type { AccessRules, AuthUser, CequreRequestContext } from "./access";
|
|
5
5
|
import type { Hooks } from "./hooks";
|
|
6
6
|
import { CequreRouter } from "./router";
|
|
7
|
-
import { type CequreMonitoringAPI } from "@cequrebackends/
|
|
8
|
-
import { RateLimiter } from "@cequrebackends/
|
|
7
|
+
import { type CequreMonitoringAPI } from "@cequrebackends/plugin-monitoring";
|
|
8
|
+
import { RateLimiter } from "@cequrebackends/plugin-security";
|
|
9
9
|
import { type CequreMailer } from "../core/email";
|
|
10
10
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
11
|
-
import { JWTAuthenticator } from "@cequrebackends/
|
|
12
|
-
import { type CequreAuditEvent } from "@cequrebackends/
|
|
11
|
+
import { JWTAuthenticator } from "@cequrebackends/plugin-security";
|
|
12
|
+
import { type CequreAuditEvent } from "@cequrebackends/plugin-security";
|
|
13
13
|
/**
|
|
14
14
|
* AsyncLocalStorage for propagating the request ID from the router
|
|
15
15
|
* to the runtime's audit calls without threading it through every
|