@rapidrest/service-core 1.0.0-rc.21 → 1.0.0-rc.23
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/lib/ApiErrors.js +2 -0
- package/dist/lib/ApiErrors.js.map +1 -1
- package/dist/lib/OpenApiSpec.js.map +1 -1
- package/dist/lib/Server.js +25 -15
- package/dist/lib/Server.js.map +1 -1
- package/dist/lib/auth/AuthMiddleware.js +2 -1
- package/dist/lib/auth/AuthMiddleware.js.map +1 -1
- package/dist/lib/auth/JWTStrategy.js +21 -1
- package/dist/lib/auth/JWTStrategy.js.map +1 -1
- package/dist/lib/database/ConnectionManager.js +7 -1
- package/dist/lib/database/ConnectionManager.js.map +1 -1
- package/dist/lib/database/MongoSchemaSync.js.map +1 -1
- package/dist/lib/decorators/ModelDecorators.js +17 -0
- package/dist/lib/decorators/ModelDecorators.js.map +1 -1
- package/dist/lib/http/IWebSocketShim.js +2 -0
- package/dist/lib/http/IWebSocketShim.js.map +1 -0
- package/dist/lib/http/MiddlewareChain.js +129 -0
- package/dist/lib/http/MiddlewareChain.js.map +1 -0
- package/dist/lib/http/RuntimeDetect.js +8 -0
- package/dist/lib/http/RuntimeDetect.js.map +1 -0
- package/dist/lib/http/bun/BunAdapters.js +270 -0
- package/dist/lib/http/bun/BunAdapters.js.map +1 -0
- package/dist/lib/http/bun/BunRouter.js +377 -0
- package/dist/lib/http/bun/BunRouter.js.map +1 -0
- package/dist/lib/http/bun/BunWebSocket.js +48 -0
- package/dist/lib/http/bun/BunWebSocket.js.map +1 -0
- package/dist/lib/http/index.js +13 -3
- package/dist/lib/http/index.js.map +1 -1
- package/dist/lib/http/{Adapters.js → uWS/Adapters.js} +65 -27
- package/dist/lib/http/uWS/Adapters.js.map +1 -0
- package/dist/lib/http/{Router.js → uWS/Router.js} +24 -133
- package/dist/lib/http/uWS/Router.js.map +1 -0
- package/dist/lib/http/uWS/WebSocket.js.map +1 -0
- package/dist/lib/models/ModelUtils.js +104 -9
- package/dist/lib/models/ModelUtils.js.map +1 -1
- package/dist/lib/models/RepoUtils.js +89 -6
- package/dist/lib/models/RepoUtils.js.map +1 -1
- package/dist/lib/routes/BaseAdminRoute.js +7 -5
- package/dist/lib/routes/BaseAdminRoute.js.map +1 -1
- package/dist/lib/routes/BaseMetricsRoute.js.map +1 -1
- package/dist/lib/routes/BasePushRoute.js +32 -5
- package/dist/lib/routes/BasePushRoute.js.map +1 -1
- package/dist/lib/routes/CRUDRoute.js.map +1 -1
- package/dist/lib/routes/ModelRoute.js.map +1 -1
- package/dist/lib/routes/RouteUtils.js +6 -2
- package/dist/lib/routes/RouteUtils.js.map +1 -1
- package/dist/lib/security/ACLUtils.js +10 -5
- package/dist/lib/security/ACLUtils.js.map +1 -1
- package/dist/lib/security/AccessControlListMongo.js +29 -29
- package/dist/lib/security/AccessControlListSQL.js +29 -29
- package/dist/lib/security/BaseACLRoute.js.map +1 -1
- package/dist/lib/test/requestws.js +28 -3
- package/dist/lib/test/requestws.js.map +1 -1
- package/dist/types/ApiErrors.d.ts +2 -0
- package/dist/types/OpenApiSpec.d.ts +1 -1
- package/dist/types/Server.d.ts +4 -4
- package/dist/types/auth/AuthMiddleware.d.ts +2 -2
- package/dist/types/auth/AuthStrategy.d.ts +2 -2
- package/dist/types/auth/BasicStrategy.d.ts +3 -3
- package/dist/types/auth/JWTStrategy.d.ts +3 -2
- package/dist/types/decorators/ModelDecorators.d.ts +8 -1
- package/dist/types/decorators/RouteDecorators.d.ts +1 -1
- package/dist/types/http/IWebSocketShim.d.ts +11 -0
- package/dist/types/http/MiddlewareChain.d.ts +40 -0
- package/dist/types/http/RuntimeDetect.d.ts +2 -0
- package/dist/types/http/bun/BunAdapters.d.ts +128 -0
- package/dist/types/http/bun/BunRouter.d.ts +79 -0
- package/dist/types/http/bun/BunWebSocket.d.ts +35 -0
- package/dist/types/http/index.d.ts +12 -6
- package/dist/types/http/types.d.ts +21 -0
- package/dist/types/http/{Adapters.d.ts → uWS/Adapters.d.ts} +24 -2
- package/dist/types/http/{Router.d.ts → uWS/Router.d.ts} +8 -32
- package/dist/types/http/{WebSocket.d.ts → uWS/WebSocket.d.ts} +6 -5
- package/dist/types/models/ModelUtils.d.ts +30 -0
- package/dist/types/models/RepoUtils.d.ts +2 -2
- package/dist/types/routes/BaseAdminRoute.d.ts +3 -3
- package/dist/types/routes/BaseMetricsRoute.d.ts +1 -1
- package/dist/types/routes/BasePushRoute.d.ts +4 -0
- package/dist/types/routes/BaseStaticRoute.d.ts +1 -1
- package/dist/types/routes/CRUDRoute.d.ts +2 -2
- package/dist/types/routes/ModelRoute.d.ts +2 -2
- package/dist/types/security/ACLUtils.d.ts +6 -3
- package/dist/types/security/AccessControlListMongo.d.ts +1 -1
- package/dist/types/security/AccessControlListSQL.d.ts +1 -1
- package/dist/types/security/BaseACLRoute.d.ts +3 -3
- package/package.json +138 -132
- package/dist/lib/http/Adapters.js.map +0 -1
- package/dist/lib/http/Router.js.map +0 -1
- package/dist/lib/http/WebSocket.js.map +0 -1
- /package/dist/lib/http/{WebSocket.js → uWS/WebSocket.js} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MiddlewareChain.js","sourceRoot":"","sources":["../../../src/http/MiddlewareChain.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
2
|
+
// Copyright (C) 2020-2026 Jean-Philippe Steinmetz. All rights reserved.
|
|
3
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
4
|
+
/** Returns `true` when the current process is running under the Bun runtime. */
|
|
5
|
+
export function isBunRuntime() {
|
|
6
|
+
return typeof globalThis.Bun !== "undefined";
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=RuntimeDetect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RuntimeDetect.js","sourceRoot":"","sources":["../../../src/http/RuntimeDetect.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,wEAAwE;AACxE,+EAA+E;AAE/E,gFAAgF;AAChF,MAAM,UAAU,YAAY;IACxB,OAAO,OAAQ,UAAkB,CAAC,GAAG,KAAK,WAAW,CAAC;AAC1D,CAAC"}
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
import { DEFAULT_MAX_BODY_SIZE, parseBodyByContentType, parseCookies, parseQueryString } from "../uWS/Adapters.js";
|
|
2
|
+
import { ApiErrorMessages, ApiErrors } from "../../ApiErrors.js";
|
|
3
|
+
/**
|
|
4
|
+
* Adapts a Bun/Fetch API `Request` to the framework-agnostic `HttpRequest` interface.
|
|
5
|
+
*
|
|
6
|
+
* Unlike uWS's stack-allocated request, a Fetch API `Request` stays valid across `await`, so there
|
|
7
|
+
* is no urgency to capture everything synchronously in the constructor the way `UWSRequest` must —
|
|
8
|
+
* this is done here purely for parity/simplicity, not correctness.
|
|
9
|
+
*/
|
|
10
|
+
export class BunRequest {
|
|
11
|
+
constructor(req, server) {
|
|
12
|
+
this.params = {};
|
|
13
|
+
this.body = undefined;
|
|
14
|
+
this.signedCookies = {};
|
|
15
|
+
this.method = req.method.toUpperCase();
|
|
16
|
+
const u = new URL(req.url);
|
|
17
|
+
this.url = u.pathname + u.search;
|
|
18
|
+
this.path = u.pathname;
|
|
19
|
+
const headers = {};
|
|
20
|
+
req.headers.forEach((value, key) => {
|
|
21
|
+
headers[key.toLowerCase()] = value;
|
|
22
|
+
});
|
|
23
|
+
this.headers = headers;
|
|
24
|
+
this.cookies = parseCookies(headers["cookie"] || "");
|
|
25
|
+
// Reuse the exact same query-string parser the uWS adapter uses (array-collapsing rules,
|
|
26
|
+
// decode-failure fallback) rather than URLSearchParams, to keep parsing behavior identical
|
|
27
|
+
// across both adapters.
|
|
28
|
+
this.query = parseQueryString(u.search.startsWith("?") ? u.search.slice(1) : u.search);
|
|
29
|
+
const ip = server.requestIP(req);
|
|
30
|
+
this.socket = { remoteAddress: ip?.address };
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Adapts a buffered/streamed set of response calls to the framework-agnostic `HttpResponse`
|
|
35
|
+
* interface, bridging them into a Fetch API `Response` that `Bun.serve()`'s `fetch()` handler
|
|
36
|
+
* resolves and returns.
|
|
37
|
+
*
|
|
38
|
+
* Two modes:
|
|
39
|
+
* - Buffered (default): `end()`/`json()`/`send()` finalize the body and resolve `responseReady`
|
|
40
|
+
* with a single complete `Response`.
|
|
41
|
+
* - Streaming: `flushHeaders()`/`write()` construct a `ReadableStream`-backed `Response` and
|
|
42
|
+
* resolve `responseReady` immediately (before the body is fully known) so the client starts
|
|
43
|
+
* receiving bytes right away; further `write()` calls enqueue chunks, `end()` closes the stream.
|
|
44
|
+
*/
|
|
45
|
+
export class BunResponse {
|
|
46
|
+
constructor(rawRequest) {
|
|
47
|
+
this._statusCode = 200;
|
|
48
|
+
this._headers = new Map();
|
|
49
|
+
this._headersSent = false;
|
|
50
|
+
this._writableEnded = false;
|
|
51
|
+
this._streaming = false;
|
|
52
|
+
this._aborted = false;
|
|
53
|
+
this._abortHandlers = [];
|
|
54
|
+
/** Set to true for HEAD requests — body bytes must not be sent. */
|
|
55
|
+
this.isHead = false;
|
|
56
|
+
this._body = null;
|
|
57
|
+
this._controller = null;
|
|
58
|
+
this._stream = null;
|
|
59
|
+
this.responseReady = new Promise((resolve) => {
|
|
60
|
+
this._resolveReady = resolve;
|
|
61
|
+
});
|
|
62
|
+
rawRequest.signal?.addEventListener("abort", () => {
|
|
63
|
+
this._aborted = true;
|
|
64
|
+
for (const handler of this._abortHandlers)
|
|
65
|
+
handler();
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
get statusCode() {
|
|
69
|
+
return this._statusCode;
|
|
70
|
+
}
|
|
71
|
+
get headersSent() {
|
|
72
|
+
return this._headersSent;
|
|
73
|
+
}
|
|
74
|
+
get writableEnded() {
|
|
75
|
+
// Once flushHeaders()/write() has started a streaming response, treat the response as
|
|
76
|
+
// "ended" from the middleware chain's perspective even before end()/close() is called —
|
|
77
|
+
// matches UWSResponse.writableEnded. Without this, runChain's sync-handler branch never
|
|
78
|
+
// sees writableEnded become true for a handler that starts streaming and returns without
|
|
79
|
+
// calling next() (the documented SSE pattern), so the chain hangs forever waiting for next().
|
|
80
|
+
return this._writableEnded || this._streaming;
|
|
81
|
+
}
|
|
82
|
+
status(code) {
|
|
83
|
+
this._statusCode = code;
|
|
84
|
+
return this;
|
|
85
|
+
}
|
|
86
|
+
setHeader(key, value) {
|
|
87
|
+
this._headers.set(key.toLowerCase(), String(value));
|
|
88
|
+
return this;
|
|
89
|
+
}
|
|
90
|
+
getHeader(key) {
|
|
91
|
+
return this._headers.get(key.toLowerCase());
|
|
92
|
+
}
|
|
93
|
+
json(data) {
|
|
94
|
+
this._headers.set("content-type", "application/json");
|
|
95
|
+
this.end(JSON.stringify(data));
|
|
96
|
+
}
|
|
97
|
+
send(data) {
|
|
98
|
+
if (data === undefined || data === null) {
|
|
99
|
+
this.end();
|
|
100
|
+
}
|
|
101
|
+
else if (typeof data === "object" && !Buffer.isBuffer(data)) {
|
|
102
|
+
this.json(data);
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
this.end(data);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
end(data) {
|
|
109
|
+
if (this._aborted || this._writableEnded)
|
|
110
|
+
return;
|
|
111
|
+
this._writableEnded = true;
|
|
112
|
+
if (this._streaming) {
|
|
113
|
+
if (data !== undefined && data !== null)
|
|
114
|
+
this._enqueue(data);
|
|
115
|
+
try {
|
|
116
|
+
this._controller?.close();
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
// already closed/errored
|
|
120
|
+
}
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
this._headersSent = true;
|
|
124
|
+
if (this.isHead) {
|
|
125
|
+
this._body = null;
|
|
126
|
+
}
|
|
127
|
+
else if (data !== undefined && data !== null) {
|
|
128
|
+
this._body = Buffer.isBuffer(data) ? new Uint8Array(data) : data;
|
|
129
|
+
}
|
|
130
|
+
this._resolveReady(this._buildResponse());
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Flushes status and headers to the wire immediately without ending the response, via a
|
|
134
|
+
* `ReadableStream`, and resolves `responseReady` right away so the client starts receiving
|
|
135
|
+
* bytes before the rest of the middleware chain finishes. Required before streaming data
|
|
136
|
+
* (e.g. SSE). Safe to call multiple times — only acts on the first call.
|
|
137
|
+
*/
|
|
138
|
+
flushHeaders() {
|
|
139
|
+
if (this._aborted || this._headersSent)
|
|
140
|
+
return;
|
|
141
|
+
this._streaming = true;
|
|
142
|
+
this._headersSent = true;
|
|
143
|
+
this._stream = new ReadableStream({
|
|
144
|
+
start: (controller) => {
|
|
145
|
+
this._controller = controller;
|
|
146
|
+
},
|
|
147
|
+
cancel: () => {
|
|
148
|
+
this._aborted = true;
|
|
149
|
+
for (const handler of this._abortHandlers)
|
|
150
|
+
handler();
|
|
151
|
+
},
|
|
152
|
+
});
|
|
153
|
+
this._resolveReady(this._buildStreamingResponse());
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Writes a chunk to the response without ending it (streaming / SSE).
|
|
157
|
+
* Flushes headers on the first call if they haven't been sent yet.
|
|
158
|
+
*/
|
|
159
|
+
write(data) {
|
|
160
|
+
if (this._aborted || this._writableEnded)
|
|
161
|
+
return;
|
|
162
|
+
if (!this._headersSent)
|
|
163
|
+
this.flushHeaders();
|
|
164
|
+
this._enqueue(data);
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Registers a callback to run when the client aborts the connection — either before any
|
|
168
|
+
* response was sent (via the request's `AbortSignal`) or mid-stream (via the `ReadableStream`'s
|
|
169
|
+
* `cancel` callback).
|
|
170
|
+
*/
|
|
171
|
+
onAbort(callback) {
|
|
172
|
+
this._abortHandlers.push(callback);
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Errors the underlying stream if it's still open. Used when a middleware chain throws after
|
|
176
|
+
* streaming has already started and the `Response` has already been handed back to the client.
|
|
177
|
+
*/
|
|
178
|
+
abortStream(err) {
|
|
179
|
+
if (this._streaming && !this._writableEnded) {
|
|
180
|
+
try {
|
|
181
|
+
this._controller?.error(err);
|
|
182
|
+
}
|
|
183
|
+
catch {
|
|
184
|
+
// already closed
|
|
185
|
+
}
|
|
186
|
+
this._writableEnded = true;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
_enqueue(data) {
|
|
190
|
+
const chunk = typeof data === "string" ? new TextEncoder().encode(data) : new Uint8Array(data);
|
|
191
|
+
try {
|
|
192
|
+
this._controller?.enqueue(chunk);
|
|
193
|
+
}
|
|
194
|
+
catch {
|
|
195
|
+
// controller may already be closed/errored if the client disconnected
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
_buildHeaders() {
|
|
199
|
+
const headers = new Headers();
|
|
200
|
+
for (const [key, value] of this._headers.entries()) {
|
|
201
|
+
// Let Response compute content-length itself, same rationale as the uWS adapter.
|
|
202
|
+
if (key === "content-length")
|
|
203
|
+
continue;
|
|
204
|
+
headers.set(key, value);
|
|
205
|
+
}
|
|
206
|
+
return headers;
|
|
207
|
+
}
|
|
208
|
+
_buildResponse() {
|
|
209
|
+
return new Response(this._body, { status: this._statusCode, headers: this._buildHeaders() });
|
|
210
|
+
}
|
|
211
|
+
_buildStreamingResponse() {
|
|
212
|
+
return new Response(this._stream, { status: this._statusCode, headers: this._buildHeaders() });
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
/** Builds the 413 JSON response used when a request body exceeds `maxBodySize`. */
|
|
216
|
+
function payloadTooLargeResponse() {
|
|
217
|
+
return new Response(JSON.stringify({
|
|
218
|
+
code: ApiErrors.PAYLOAD_TOO_LARGE,
|
|
219
|
+
status: 413,
|
|
220
|
+
message: ApiErrorMessages.PAYLOAD_TOO_LARGE,
|
|
221
|
+
}), { status: 413, headers: { "content-type": "application/json" } });
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Reads the full request body from a Bun `Request` into a Buffer, mirroring `readBody()`'s uWS
|
|
225
|
+
* behavior exactly: body parsing (JSON / URL-encoded) is applied based on content-type and the
|
|
226
|
+
* result is cached on `req.body` / `req.rawBody`. Rejects with a 413 JSON `Response` if the body
|
|
227
|
+
* exceeds `maxBodySize` — checked both against the declared `Content-Length` up front (fast path)
|
|
228
|
+
* and against the actual accumulated byte count as chunks arrive, so chunked/unknown-length bodies
|
|
229
|
+
* that lie about or omit `Content-Length` are still caught, matching uWS's guarantee.
|
|
230
|
+
*/
|
|
231
|
+
export async function readBunBody(req, rawRequest, maxBodySize = DEFAULT_MAX_BODY_SIZE) {
|
|
232
|
+
if (req.body !== undefined) {
|
|
233
|
+
return { ok: true };
|
|
234
|
+
}
|
|
235
|
+
const declaredLength = rawRequest.headers.get("content-length");
|
|
236
|
+
if (declaredLength && Number(declaredLength) > maxBodySize) {
|
|
237
|
+
return { ok: false, response: payloadTooLargeResponse() };
|
|
238
|
+
}
|
|
239
|
+
if (!rawRequest.body) {
|
|
240
|
+
req.rawBody = undefined;
|
|
241
|
+
req.body = undefined;
|
|
242
|
+
return { ok: true };
|
|
243
|
+
}
|
|
244
|
+
const reader = rawRequest.body.getReader();
|
|
245
|
+
const chunks = [];
|
|
246
|
+
let total = 0;
|
|
247
|
+
for (;;) {
|
|
248
|
+
const { done, value } = await reader.read();
|
|
249
|
+
if (done)
|
|
250
|
+
break;
|
|
251
|
+
if (!value)
|
|
252
|
+
continue;
|
|
253
|
+
total += value.byteLength;
|
|
254
|
+
if (total > maxBodySize) {
|
|
255
|
+
try {
|
|
256
|
+
await reader.cancel();
|
|
257
|
+
}
|
|
258
|
+
catch {
|
|
259
|
+
// ignore — we're rejecting the request regardless
|
|
260
|
+
}
|
|
261
|
+
return { ok: false, response: payloadTooLargeResponse() };
|
|
262
|
+
}
|
|
263
|
+
chunks.push(value);
|
|
264
|
+
}
|
|
265
|
+
const raw = Buffer.concat(chunks.map((c) => Buffer.from(c)));
|
|
266
|
+
req.rawBody = raw;
|
|
267
|
+
req.body = parseBodyByContentType(raw, String(req.headers["content-type"] || ""));
|
|
268
|
+
return { ok: true };
|
|
269
|
+
}
|
|
270
|
+
//# sourceMappingURL=BunAdapters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BunAdapters.js","sourceRoot":"","sources":["../../../../src/http/bun/BunAdapters.ts"],"names":[],"mappings":"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"}
|