@databehave/server 0.1.4 → 0.3.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/CHANGELOG.md +30 -0
- package/README.md +85 -83
- package/dist/cors.d.ts +1 -1
- package/dist/cors.js +1 -1
- package/dist/cors.js.map +1 -1
- package/dist/http.d.ts +94 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/http.js +23 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +10 -20
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -18
- package/dist/index.js.map +1 -1
- package/dist/log.d.ts +9 -49
- package/dist/log.d.ts.map +1 -1
- package/dist/log.js +16 -92
- package/dist/log.js.map +1 -1
- package/dist/node-authority.d.ts +12 -0
- package/dist/node-authority.d.ts.map +1 -0
- package/dist/node-authority.js +72 -0
- package/dist/node-authority.js.map +1 -0
- package/dist/node-body.d.ts +11 -0
- package/dist/node-body.d.ts.map +1 -0
- package/dist/node-body.js +61 -0
- package/dist/node-body.js.map +1 -0
- package/dist/node-http.d.ts +19 -0
- package/dist/node-http.d.ts.map +1 -0
- package/dist/node-http.js +210 -0
- package/dist/node-http.js.map +1 -0
- package/dist/plugins/access-log.d.ts +11 -0
- package/dist/plugins/access-log.d.ts.map +1 -0
- package/dist/plugins/access-log.js +27 -0
- package/dist/plugins/access-log.js.map +1 -0
- package/dist/plugins/cors.d.ts +5 -0
- package/dist/plugins/cors.d.ts.map +1 -0
- package/dist/plugins/cors.js +35 -0
- package/dist/plugins/cors.js.map +1 -0
- package/dist/plugins/routes.d.ts +5 -0
- package/dist/plugins/routes.d.ts.map +1 -0
- package/dist/plugins/routes.js +10 -0
- package/dist/plugins/routes.js.map +1 -0
- package/dist/request.d.ts +2 -2
- package/dist/request.d.ts.map +1 -1
- package/dist/request.js +6 -4
- package/dist/request.js.map +1 -1
- package/dist/route-key.d.ts +2 -0
- package/dist/route-key.d.ts.map +1 -1
- package/dist/route-key.js +5 -1
- package/dist/route-key.js.map +1 -1
- package/dist/server.d.ts +7 -59
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +289 -466
- package/dist/server.js.map +1 -1
- package/dist/types.d.ts +10 -156
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -1
- package/package.json +11 -24
- package/dist/admin/admin-routes.d.ts +0 -42
- package/dist/admin/admin-routes.d.ts.map +0 -1
- package/dist/admin/admin-routes.js +0 -472
- package/dist/admin/admin-routes.js.map +0 -1
- package/dist/admin/admin-types.d.ts +0 -170
- package/dist/admin/admin-types.d.ts.map +0 -1
- package/dist/admin/admin-types.js +0 -30
- package/dist/admin/admin-types.js.map +0 -1
- package/dist/admin/banner.d.ts +0 -11
- package/dist/admin/banner.d.ts.map +0 -1
- package/dist/admin/banner.js +0 -5
- package/dist/admin/banner.js.map +0 -1
- package/dist/admin/header-parser.d.ts +0 -14
- package/dist/admin/header-parser.d.ts.map +0 -1
- package/dist/admin/header-parser.js +0 -171
- package/dist/admin/header-parser.js.map +0 -1
- package/dist/admin/inject.d.ts +0 -48
- package/dist/admin/inject.d.ts.map +0 -1
- package/dist/admin/inject.js +0 -167
- package/dist/admin/inject.js.map +0 -1
- package/dist/admin/overrides-store.d.ts +0 -18
- package/dist/admin/overrides-store.d.ts.map +0 -1
- package/dist/admin/overrides-store.js +0 -100
- package/dist/admin/overrides-store.js.map +0 -1
- package/dist/admin/resolve-cors.d.ts +0 -22
- package/dist/admin/resolve-cors.d.ts.map +0 -1
- package/dist/admin/resolve-cors.js +0 -28
- package/dist/admin/resolve-cors.js.map +0 -1
- package/dist/admin/scenarios-store.d.ts +0 -15
- package/dist/admin/scenarios-store.d.ts.map +0 -1
- package/dist/admin/scenarios-store.js +0 -109
- package/dist/admin/scenarios-store.js.map +0 -1
- package/dist/admin/ui.css +0 -1
- package/dist/admin/ui.html +0 -13
- package/dist/admin/ui.js +0 -240
- package/dist/bin-helpers.d.ts +0 -46
- package/dist/bin-helpers.d.ts.map +0 -1
- package/dist/bin-helpers.js +0 -61
- package/dist/bin-helpers.js.map +0 -1
- package/dist/bin.d.ts +0 -3
- package/dist/bin.d.ts.map +0 -1
- package/dist/bin.js +0 -86
- package/dist/bin.js.map +0 -1
- package/dist/define.d.ts +0 -26
- package/dist/define.d.ts.map +0 -1
- package/dist/define.js +0 -55
- package/dist/define.js.map +0 -1
- package/dist/json-config.d.ts +0 -170
- package/dist/json-config.d.ts.map +0 -1
- package/dist/json-config.js +0 -684
- package/dist/json-config.js.map +0 -1
- package/dist/jsonc.d.ts +0 -24
- package/dist/jsonc.d.ts.map +0 -1
- package/dist/jsonc.js +0 -125
- package/dist/jsonc.js.map +0 -1
- package/dist/middleware/request-validation.d.ts +0 -58
- package/dist/middleware/request-validation.d.ts.map +0 -1
- package/dist/middleware/request-validation.js +0 -328
- package/dist/middleware/request-validation.js.map +0 -1
- package/dist/mock-mode.d.ts +0 -95
- package/dist/mock-mode.d.ts.map +0 -1
- package/dist/mock-mode.js +0 -95
- package/dist/mock-mode.js.map +0 -1
- package/dist/openapi/auto-schema.d.ts +0 -83
- package/dist/openapi/auto-schema.d.ts.map +0 -1
- package/dist/openapi/auto-schema.js +0 -232
- package/dist/openapi/auto-schema.js.map +0 -1
- package/dist/openapi/generate.d.ts +0 -20
- package/dist/openapi/generate.d.ts.map +0 -1
- package/dist/openapi/generate.js +0 -121
- package/dist/openapi/generate.js.map +0 -1
- package/dist/openapi/loader.d.ts +0 -18
- package/dist/openapi/loader.d.ts.map +0 -1
- package/dist/openapi/loader.js +0 -25
- package/dist/openapi/loader.js.map +0 -1
- package/dist/openapi/register.d.ts +0 -58
- package/dist/openapi/register.d.ts.map +0 -1
- package/dist/openapi/register.js +0 -166
- package/dist/openapi/register.js.map +0 -1
- package/dist/openapi/seed.d.ts +0 -16
- package/dist/openapi/seed.d.ts.map +0 -1
- package/dist/openapi/seed.js +0 -58
- package/dist/openapi/seed.js.map +0 -1
- package/dist/openapi/translate.d.ts +0 -55
- package/dist/openapi/translate.d.ts.map +0 -1
- package/dist/openapi/translate.js +0 -319
- package/dist/openapi/translate.js.map +0 -1
- package/dist/openapi/walker.d.ts +0 -44
- package/dist/openapi/walker.d.ts.map +0 -1
- package/dist/openapi/walker.js +0 -15
- package/dist/openapi/walker.js.map +0 -1
- package/dist/run.d.ts +0 -27
- package/dist/run.d.ts.map +0 -1
- package/dist/run.js +0 -87
- package/dist/run.js.map +0 -1
- package/dist/validation/validate.d.ts +0 -38
- package/dist/validation/validate.d.ts.map +0 -1
- package/dist/validation/validate.js +0 -372
- package/dist/validation/validate.js.map +0 -1
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { buildCorsResponseHeaders, buildPreflightResponse, mergeVary } from '../cors.js';
|
|
2
|
+
import { httpCapability } from '../http.js';
|
|
3
|
+
/** Apply application CORS only to resolved routes, honoring each route owner's policy. */
|
|
4
|
+
export const corsPlugin = (options = {}) => ({
|
|
5
|
+
id: 'databehave.http.cors', apiVersion: 1, requires: [httpCapability],
|
|
6
|
+
setup(ctx) {
|
|
7
|
+
const http = ctx.use(httpCapability);
|
|
8
|
+
const policy = (request) => {
|
|
9
|
+
const method = request.method === 'options'
|
|
10
|
+
? request.headers['access-control-request-method'] ?? 'options'
|
|
11
|
+
: request.method;
|
|
12
|
+
const route = http.resolveRoute(method, request.path);
|
|
13
|
+
return route ? route.cors ?? options : false;
|
|
14
|
+
};
|
|
15
|
+
http.registerMiddleware({ owner: 'databehave.http.cors', order: ctx.order, stage: 'preflight', handle: (request) => {
|
|
16
|
+
const selected = policy(request);
|
|
17
|
+
if (request.method === 'options' && selected !== false)
|
|
18
|
+
return buildPreflightResponse(selected, request);
|
|
19
|
+
} });
|
|
20
|
+
http.registerMiddleware({ owner: 'databehave.http.cors', order: ctx.order, stage: 'decoration', handle: (request, response) => {
|
|
21
|
+
const selected = policy(request);
|
|
22
|
+
if (selected === false)
|
|
23
|
+
return;
|
|
24
|
+
const headers = new Headers(response.headers);
|
|
25
|
+
for (const [name, value] of Object.entries(buildCorsResponseHeaders(selected, request))) {
|
|
26
|
+
if (name === 'vary')
|
|
27
|
+
headers.set(name, mergeVary(headers.get(name) ?? undefined, value));
|
|
28
|
+
else if (!headers.has(name))
|
|
29
|
+
headers.set(name, value);
|
|
30
|
+
}
|
|
31
|
+
return { ...response, headers: Object.fromEntries(headers.entries()) };
|
|
32
|
+
} });
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
//# sourceMappingURL=cors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cors.js","sourceRoot":"","sources":["../../src/plugins/cors.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,wBAAwB,EAAE,sBAAsB,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AACxF,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAG3C,0FAA0F;AAC1F,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,UAAsB,EAAE,EAAU,EAAE,CAAC,CAAC;IAC/D,EAAE,EAAE,sBAAsB,EAAE,UAAU,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,cAAc,CAAC;IACrE,KAAK,CAAC,GAAG;QACP,MAAM,IAAI,GAAG,GAAG,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;QACpC,MAAM,MAAM,GAAG,CAAC,OAAoB,EAAsB,EAAE;YAC1D,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,KAAK,SAAS;gBACzC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,+BAA+B,CAAC,IAAI,SAAS;gBAC/D,CAAC,CAAC,OAAO,CAAC,MAAM,CAAA;YAClB,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;YACrD,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,CAAA;QAC9C,CAAC,CAAA;QACD,IAAI,CAAC,kBAAkB,CAAC,EAAE,KAAK,EAAE,sBAAsB,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE;gBACjH,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,CAAA;gBAChC,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,IAAI,QAAQ,KAAK,KAAK;oBAAE,OAAO,sBAAsB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;YAC1G,CAAC,EAAE,CAAC,CAAA;QACJ,IAAI,CAAC,kBAAkB,CAAC,EAAE,KAAK,EAAE,sBAAsB,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE;gBAC5H,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,CAAA;gBAChC,IAAI,QAAQ,KAAK,KAAK;oBAAE,OAAM;gBAC9B,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;gBAC7C,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,wBAAwB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC;oBACxF,IAAI,IAAI,KAAK,MAAM;wBAAE,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,SAAS,EAAE,KAAK,CAAC,CAAC,CAAA;yBACnF,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;wBAAE,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;gBACvD,CAAC;gBACD,OAAO,EAAE,GAAG,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,EAAE,CAAA;YACxE,CAAC,EAAE,CAAC,CAAA;IACN,CAAC;CACF,CAAC,CAAA"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Plugin } from '@databehave/core';
|
|
2
|
+
import type { Handler, RouteKey } from '../types.js';
|
|
3
|
+
/** Register explicit handlers through the same contribution contract as external plugins. */
|
|
4
|
+
export declare const routesPlugin: (routes: Readonly<Partial<Record<RouteKey, Handler>>>, id?: string) => Plugin;
|
|
5
|
+
//# sourceMappingURL=routes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/plugins/routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAE9C,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAEpD,6FAA6F;AAC7F,eAAO,MAAM,YAAY,GAAI,QAAQ,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,WAA6B,KAAG,MAMjH,CAAA"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { httpCapability } from '../http.js';
|
|
2
|
+
/** Register explicit handlers through the same contribution contract as external plugins. */
|
|
3
|
+
export const routesPlugin = (routes, id = 'databehave.http.routes') => ({
|
|
4
|
+
id, apiVersion: 1, requires: [httpCapability],
|
|
5
|
+
setup(ctx) {
|
|
6
|
+
const entries = Object.entries(routes);
|
|
7
|
+
ctx.use(httpCapability).registerRoutes({ owner: id, order: ctx.order, materialize: () => entries.flatMap(([key, handler]) => handler ? [{ key: key, handler, priority: 'explicit' }] : []) });
|
|
8
|
+
},
|
|
9
|
+
});
|
|
10
|
+
//# sourceMappingURL=routes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routes.js","sourceRoot":"","sources":["../../src/plugins/routes.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAG3C,6FAA6F;AAC7F,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,MAAoD,EAAE,EAAE,GAAG,wBAAwB,EAAU,EAAE,CAAC,CAAC;IAC5H,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,cAAc,CAAC;IAC7C,KAAK,CAAC,GAAG;QACP,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;QACtC,GAAG,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,cAAc,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,GAAe,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAmB,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAA;IACpN,CAAC;CACF,CAAC,CAAA"}
|
package/dist/request.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { MockRequest } from './types.js';
|
|
1
|
+
import type { ObservedMethod, MockRequest } from './types.js';
|
|
2
2
|
/**
|
|
3
3
|
* Build a `MockRequest` from a web standard `Request`.
|
|
4
4
|
*
|
|
@@ -15,5 +15,5 @@ import type { MockRequest } from './types.js';
|
|
|
15
15
|
* directly and then calling `json()` / `text()` will throw, matching
|
|
16
16
|
* the web standard.
|
|
17
17
|
*/
|
|
18
|
-
export declare const buildRequest: (req: globalThis.Request, params?: Readonly<Record<string, string
|
|
18
|
+
export declare const buildRequest: (req: globalThis.Request, params?: Readonly<Record<string, string>>, effectiveMethod?: ObservedMethod) => MockRequest;
|
|
19
19
|
//# sourceMappingURL=request.d.ts.map
|
package/dist/request.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../src/request.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../src/request.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAa7D;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,YAAY,GACvB,KAAK,UAAU,CAAC,OAAO,EACvB,SAAQ,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAM,EAC7C,kBAAkB,cAAc,KAC/B,WAyCF,CAAA"}
|
package/dist/request.js
CHANGED
|
@@ -24,21 +24,21 @@ const bodyCache = new WeakMap();
|
|
|
24
24
|
* directly and then calling `json()` / `text()` will throw, matching
|
|
25
25
|
* the web standard.
|
|
26
26
|
*/
|
|
27
|
-
export const buildRequest = (req, params = {}) => {
|
|
27
|
+
export const buildRequest = (req, params = {}, effectiveMethod) => {
|
|
28
28
|
const url = new URL(req.url);
|
|
29
29
|
const method = req.method.toLowerCase();
|
|
30
|
-
const queryAll =
|
|
30
|
+
const queryAll = Object.create(null);
|
|
31
31
|
for (const [k, v] of url.searchParams.entries()) {
|
|
32
32
|
;
|
|
33
33
|
(queryAll[k] ??= []).push(v);
|
|
34
34
|
}
|
|
35
|
-
const query =
|
|
35
|
+
const query = Object.create(null);
|
|
36
36
|
for (const [k, vs] of Object.entries(queryAll)) {
|
|
37
37
|
const last = vs[vs.length - 1];
|
|
38
38
|
if (last !== undefined)
|
|
39
39
|
query[k] = last;
|
|
40
40
|
}
|
|
41
|
-
const headers =
|
|
41
|
+
const headers = Object.create(null);
|
|
42
42
|
req.headers.forEach((value, key) => {
|
|
43
43
|
headers[key.toLowerCase()] = value;
|
|
44
44
|
});
|
|
@@ -52,6 +52,8 @@ export const buildRequest = (req, params = {}) => {
|
|
|
52
52
|
};
|
|
53
53
|
return {
|
|
54
54
|
method,
|
|
55
|
+
effectiveMethod: effectiveMethod ?? method,
|
|
56
|
+
signal: req.signal,
|
|
55
57
|
url: req.url,
|
|
56
58
|
path: url.pathname,
|
|
57
59
|
query,
|
package/dist/request.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request.js","sourceRoot":"","sources":["../src/request.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,MAAM,SAAS,GAAG,IAAI,OAAO,EAAuC,CAAA;AAEpE;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAC1B,GAAuB,EACvB,SAA2C,EAAE,
|
|
1
|
+
{"version":3,"file":"request.js","sourceRoot":"","sources":["../src/request.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,MAAM,SAAS,GAAG,IAAI,OAAO,EAAuC,CAAA;AAEpE;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAC1B,GAAuB,EACvB,SAA2C,EAAE,EAC7C,eAAgC,EACnB,EAAE;IACf,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IAC5B,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,WAAW,EAAoB,CAAA;IAEzD,MAAM,QAAQ,GAA6B,MAAM,CAAC,MAAM,CAAC,IAAI,CAA6B,CAAA;IAC1F,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,YAAY,CAAC,OAAO,EAAE,EAAE,CAAC;QAChD,CAAC;QAAA,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAC/B,CAAC;IACD,MAAM,KAAK,GAA2B,MAAM,CAAC,MAAM,CAAC,IAAI,CAA2B,CAAA;IACnF,KAAK,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC/C,MAAM,IAAI,GAAG,EAAE,CAAC,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;QAC9B,IAAI,IAAI,KAAK,SAAS;YAAE,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAA;IACzC,CAAC;IAED,MAAM,OAAO,GAA2B,MAAM,CAAC,MAAM,CAAC,IAAI,CAA2B,CAAA;IACrF,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACjC,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,GAAG,KAAK,CAAA;IACpC,CAAC,CAAC,CAAA;IAEF,MAAM,IAAI,GAAG,GAAoB,EAAE;QACjC,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QACjC,IAAI,MAAM;YAAE,OAAO,MAAM,CAAA;QACzB,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,CAAA;QAChC,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;QACzB,OAAO,KAAK,CAAA;IACd,CAAC,CAAA;IAED,OAAO;QACL,MAAM;QACN,eAAe,EAAE,eAAe,IAAI,MAAM;QAC1C,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,GAAG,EAAE,GAAG,CAAC,GAAG;QACZ,IAAI,EAAE,GAAG,CAAC,QAAQ;QAClB,KAAK;QACL,QAAQ;QACR,MAAM;QACN,OAAO;QACP,IAAI,EAAE,GAAgB,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAM,CAAC;QAC/D,IAAI;QACJ,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG;KACf,CAAA;AACH,CAAC,CAAA"}
|
package/dist/route-key.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Method, RouteKey } from './types.js';
|
|
2
|
+
/** Parsed method and absolute path. */
|
|
2
3
|
export interface ParsedRouteKey {
|
|
3
4
|
readonly method: Method;
|
|
4
5
|
readonly path: string;
|
|
@@ -16,6 +17,7 @@ export type PatternSegment = {
|
|
|
16
17
|
readonly kind: 'param';
|
|
17
18
|
readonly name: string;
|
|
18
19
|
};
|
|
20
|
+
/** Compiled path segments used by the route matcher. */
|
|
19
21
|
export interface RoutePattern {
|
|
20
22
|
/** Original path string as declared (post-trim). */
|
|
21
23
|
readonly path: string;
|
package/dist/route-key.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route-key.d.ts","sourceRoot":"","sources":["../src/route-key.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"route-key.d.ts","sourceRoot":"","sources":["../src/route-key.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAYlD,uCAAuC;AACvC,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;AAED;;;;;GAKG;AACH,MAAM,MAAM,cAAc,GACtB;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACnD;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAA;AAErD,wDAAwD;AACxD,MAAM,WAAW,YAAY;IAC3B,oDAAoD;IACpD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,oEAAoE;IACpE,QAAQ,CAAC,QAAQ,EAAE,SAAS,cAAc,EAAE,CAAA;IAC5C,qEAAqE;IACrE,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;CAC3B;AAED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,aAAa,GAAI,KAAK,QAAQ,KAAG,cA6B7C,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,GAAI,MAAM,MAAM,KAAG,YAwBhD,CAAA;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY,GACvB,SAAS,YAAY,EACrB,aAAa,MAAM,KAClB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAoB3B,CAAA"}
|
package/dist/route-key.js
CHANGED
|
@@ -4,6 +4,8 @@ const SUPPORTED_METHODS = new Set([
|
|
|
4
4
|
'put',
|
|
5
5
|
'delete',
|
|
6
6
|
'patch',
|
|
7
|
+
'head',
|
|
8
|
+
'options',
|
|
7
9
|
]);
|
|
8
10
|
/**
|
|
9
11
|
* Parse a `'METHOD /path'` key.
|
|
@@ -82,10 +84,12 @@ export const matchPattern = (pattern, requestPath) => {
|
|
|
82
84
|
const reqSegments = requestPath.slice(1).split('/');
|
|
83
85
|
if (reqSegments.length !== pattern.segments.length)
|
|
84
86
|
return null;
|
|
85
|
-
const params =
|
|
87
|
+
const params = Object.create(null);
|
|
86
88
|
for (let i = 0; i < pattern.segments.length; i++) {
|
|
87
89
|
const seg = pattern.segments[i];
|
|
88
90
|
const part = reqSegments[i];
|
|
91
|
+
if (seg === undefined || part === undefined)
|
|
92
|
+
return null;
|
|
89
93
|
if (seg.kind === 'static') {
|
|
90
94
|
if (seg.value !== part)
|
|
91
95
|
return null;
|
package/dist/route-key.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route-key.js","sourceRoot":"","sources":["../src/route-key.ts"],"names":[],"mappings":"AAEA,MAAM,iBAAiB,GAAwB,IAAI,GAAG,CAAS;IAC7D,KAAK;IACL,MAAM;IACN,KAAK;IACL,QAAQ;IACR,OAAO;
|
|
1
|
+
{"version":3,"file":"route-key.js","sourceRoot":"","sources":["../src/route-key.ts"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts
CHANGED
|
@@ -1,60 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
export declare const resolveAdminMode: (cfg: AdminModeConfig | undefined) => {
|
|
9
|
-
path: string;
|
|
10
|
-
ui: boolean;
|
|
11
|
-
headers: boolean;
|
|
12
|
-
bind: "loopback-only" | "any";
|
|
13
|
-
cors: NonNullable<AdminModeConfig["cors"]>;
|
|
14
|
-
allowDestroy: boolean;
|
|
15
|
-
openapiBody: string | undefined;
|
|
16
|
-
scenariosDir: string;
|
|
17
|
-
} | null;
|
|
18
|
-
/**
|
|
19
|
-
* Compose two onRequest hooks (user-first per spec H13): if the user
|
|
20
|
-
* hook returned a response, skip the admin inject hook; else call
|
|
21
|
-
* inject. Exported for unit testability.
|
|
22
|
-
*/
|
|
23
|
-
export declare const composeAdminOnRequest: (userHook: ((req: MockRequest) => MockResponse | void | Promise<MockResponse | void>) | undefined, adminHook: (req: MockRequest) => Promise<MockResponse | void>) => ((req: MockRequest) => Promise<MockResponse | void>);
|
|
24
|
-
/**
|
|
25
|
-
* Build a @databehave/server server.
|
|
26
|
-
*
|
|
27
|
-
* Construction validates every route key and pre-computes a dispatch
|
|
28
|
-
* index (static lookups are O(1), `:param` patterns are linear). The
|
|
29
|
-
* returned object exposes:
|
|
30
|
-
*
|
|
31
|
-
* - `fetch(Request)` for in-process testing — no socket is opened.
|
|
32
|
-
* - `listen({port, host})` to bind a Node HTTP server. Port `0`
|
|
33
|
-
* asks the OS for a free port; the resolved port/host come back in
|
|
34
|
-
* the handle.
|
|
35
|
-
*
|
|
36
|
-
* Request flow per call:
|
|
37
|
-
* 1. CORS preflight (OPTIONS) → short-circuit when `cors` is set
|
|
38
|
-
* 2. `hooks.onRequest` → may short-circuit
|
|
39
|
-
* 3. Route dispatch → handler / OAS walker / 404
|
|
40
|
-
* 4. `hooks.onResponse` → may replace the result
|
|
41
|
-
* 5. CORS response headers merged on top (don't override the user)
|
|
42
|
-
* 6. Handler errors funnel through `hooks.onError` or fall back
|
|
43
|
-
* to a 500 JSON envelope.
|
|
44
|
-
*/
|
|
45
|
-
/**
|
|
46
|
-
* Route a runtime `'error'` event from a bound Node `http.Server` to
|
|
47
|
-
* the user-supplied `onServerError` hook (when present), with a
|
|
48
|
-
* `console.error` fallback. Exported so the branching is unit-testable
|
|
49
|
-
* without standing up a real socket and provoking EMFILE/EACCES.
|
|
50
|
-
*
|
|
51
|
-
* Branch contract:
|
|
52
|
-
* - no hook → log via `console.error`
|
|
53
|
-
* - hook returns → silent (hook owns reporting)
|
|
54
|
-
* - hook itself throws → log the *hook* failure AND the original
|
|
55
|
-
* error, so a misbehaving logger never
|
|
56
|
-
* silently swallows a real server fault.
|
|
57
|
-
*/
|
|
58
|
-
export declare const handleRuntimeServerError: (err: Error, onServerError: ((err: Error) => void) | undefined) => void;
|
|
59
|
-
export declare const createServer: (config: Config) => Server;
|
|
1
|
+
import type { Plugin } from '@databehave/core';
|
|
2
|
+
/** Shutdown budget shared by logical requests and optional transports. */
|
|
3
|
+
export interface HttpOptions {
|
|
4
|
+
readonly drainTimeoutMs?: number;
|
|
5
|
+
}
|
|
6
|
+
/** Provide an instance-local HTTP pipeline; no listener or feature is installed implicitly. */
|
|
7
|
+
export declare const httpPlugin: (options?: HttpOptions) => Plugin;
|
|
60
8
|
//# sourceMappingURL=server.d.ts.map
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAyB9C,0EAA0E;AAC1E,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAA;CACjC;AAED,+FAA+F;AAC/F,eAAO,MAAM,UAAU,GAAI,UAAS,WAAgB,KAAG,MA2PtD,CAAA"}
|