@databehave/server 0.1.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 +28 -0
- package/LICENSE +21 -0
- package/README.md +87 -0
- package/dist/admin/admin-routes.d.ts +42 -0
- package/dist/admin/admin-routes.d.ts.map +1 -0
- package/dist/admin/admin-routes.js +472 -0
- package/dist/admin/admin-routes.js.map +1 -0
- package/dist/admin/admin-types.d.ts +170 -0
- package/dist/admin/admin-types.d.ts.map +1 -0
- package/dist/admin/admin-types.js +30 -0
- package/dist/admin/admin-types.js.map +1 -0
- package/dist/admin/banner.d.ts +11 -0
- package/dist/admin/banner.d.ts.map +1 -0
- package/dist/admin/banner.js +5 -0
- package/dist/admin/banner.js.map +1 -0
- package/dist/admin/header-parser.d.ts +14 -0
- package/dist/admin/header-parser.d.ts.map +1 -0
- package/dist/admin/header-parser.js +171 -0
- package/dist/admin/header-parser.js.map +1 -0
- package/dist/admin/inject.d.ts +48 -0
- package/dist/admin/inject.d.ts.map +1 -0
- package/dist/admin/inject.js +167 -0
- package/dist/admin/inject.js.map +1 -0
- package/dist/admin/overrides-store.d.ts +18 -0
- package/dist/admin/overrides-store.d.ts.map +1 -0
- package/dist/admin/overrides-store.js +100 -0
- package/dist/admin/overrides-store.js.map +1 -0
- package/dist/admin/resolve-cors.d.ts +22 -0
- package/dist/admin/resolve-cors.d.ts.map +1 -0
- package/dist/admin/resolve-cors.js +28 -0
- package/dist/admin/resolve-cors.js.map +1 -0
- package/dist/admin/scenarios-store.d.ts +15 -0
- package/dist/admin/scenarios-store.d.ts.map +1 -0
- package/dist/admin/scenarios-store.js +109 -0
- package/dist/admin/scenarios-store.js.map +1 -0
- package/dist/admin/ui.css +2 -0
- package/dist/admin/ui.html +13 -0
- package/dist/admin/ui.js +240 -0
- package/dist/bin-helpers.d.ts +46 -0
- package/dist/bin-helpers.d.ts.map +1 -0
- package/dist/bin-helpers.js +61 -0
- package/dist/bin-helpers.js.map +1 -0
- package/dist/bin.d.ts +3 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +57 -0
- package/dist/bin.js.map +1 -0
- package/dist/cors.d.ts +57 -0
- package/dist/cors.d.ts.map +1 -0
- package/dist/cors.js +167 -0
- package/dist/cors.js.map +1 -0
- package/dist/define.d.ts +26 -0
- package/dist/define.d.ts.map +1 -0
- package/dist/define.js +55 -0
- package/dist/define.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/json-config.d.ts +170 -0
- package/dist/json-config.d.ts.map +1 -0
- package/dist/json-config.js +684 -0
- package/dist/json-config.js.map +1 -0
- package/dist/jsonc.d.ts +24 -0
- package/dist/jsonc.d.ts.map +1 -0
- package/dist/jsonc.js +125 -0
- package/dist/jsonc.js.map +1 -0
- package/dist/log.d.ts +57 -0
- package/dist/log.d.ts.map +1 -0
- package/dist/log.js +103 -0
- package/dist/log.js.map +1 -0
- package/dist/middleware/request-validation.d.ts +58 -0
- package/dist/middleware/request-validation.d.ts.map +1 -0
- package/dist/middleware/request-validation.js +328 -0
- package/dist/middleware/request-validation.js.map +1 -0
- package/dist/mock-mode.d.ts +95 -0
- package/dist/mock-mode.d.ts.map +1 -0
- package/dist/mock-mode.js +95 -0
- package/dist/mock-mode.js.map +1 -0
- package/dist/openapi/auto-schema.d.ts +83 -0
- package/dist/openapi/auto-schema.d.ts.map +1 -0
- package/dist/openapi/auto-schema.js +232 -0
- package/dist/openapi/auto-schema.js.map +1 -0
- package/dist/openapi/generate.d.ts +20 -0
- package/dist/openapi/generate.d.ts.map +1 -0
- package/dist/openapi/generate.js +121 -0
- package/dist/openapi/generate.js.map +1 -0
- package/dist/openapi/loader.d.ts +18 -0
- package/dist/openapi/loader.d.ts.map +1 -0
- package/dist/openapi/loader.js +25 -0
- package/dist/openapi/loader.js.map +1 -0
- package/dist/openapi/register.d.ts +58 -0
- package/dist/openapi/register.d.ts.map +1 -0
- package/dist/openapi/register.js +166 -0
- package/dist/openapi/register.js.map +1 -0
- package/dist/openapi/seed.d.ts +16 -0
- package/dist/openapi/seed.d.ts.map +1 -0
- package/dist/openapi/seed.js +58 -0
- package/dist/openapi/seed.js.map +1 -0
- package/dist/openapi/translate.d.ts +55 -0
- package/dist/openapi/translate.d.ts.map +1 -0
- package/dist/openapi/translate.js +319 -0
- package/dist/openapi/translate.js.map +1 -0
- package/dist/openapi/walker.d.ts +44 -0
- package/dist/openapi/walker.d.ts.map +1 -0
- package/dist/openapi/walker.js +15 -0
- package/dist/openapi/walker.js.map +1 -0
- package/dist/request.d.ts +19 -0
- package/dist/request.d.ts.map +1 -0
- package/dist/request.js +66 -0
- package/dist/request.js.map +1 -0
- package/dist/response.d.ts +13 -0
- package/dist/response.d.ts.map +1 -0
- package/dist/response.js +43 -0
- package/dist/response.js.map +1 -0
- package/dist/route-key.d.ts +60 -0
- package/dist/route-key.d.ts.map +1 -0
- package/dist/route-key.js +105 -0
- package/dist/route-key.js.map +1 -0
- package/dist/run.d.ts +27 -0
- package/dist/run.d.ts.map +1 -0
- package/dist/run.js +87 -0
- package/dist/run.js.map +1 -0
- package/dist/server.d.ts +60 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +497 -0
- package/dist/server.js.map +1 -0
- package/dist/types.d.ts +274 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +9 -0
- package/dist/types.js.map +1 -0
- package/dist/validation/validate.d.ts +38 -0
- package/dist/validation/validate.d.ts.map +1 -0
- package/dist/validation/validate.js +372 -0
- package/dist/validation/validate.js.map +1 -0
- package/docs/admin/error-mode.md +14 -0
- package/docs/admin/headers.md +63 -0
- package/docs/admin/index.md +111 -0
- package/docs/admin/overrides.md +23 -0
- package/docs/admin/rest-api.md +90 -0
- package/docs/admin/scenarios.md +28 -0
- package/docs/cli.md +76 -0
- package/docs/config/admin.md +62 -0
- package/docs/config/cors.md +72 -0
- package/docs/config/endpoints.md +162 -0
- package/docs/config/index.md +107 -0
- package/docs/config/log.md +43 -0
- package/docs/config/mock-mode.md +84 -0
- package/docs/config/openapi.md +8 -0
- package/docs/config/schema.md +34 -0
- package/docs/config/server.md +32 -0
- package/docs/config/validation.md +161 -0
- package/docs/design.md +517 -0
- package/docs/errors.md +192 -0
- package/docs/getting-started.md +146 -0
- package/docs/index.md +23 -0
- package/docs/openapi/auto-schema.md +146 -0
- package/docs/openapi/fallback.md +242 -0
- package/docs/openapi/keywords.md +78 -0
- package/docs/recipes.md +258 -0
- package/docs/stability.md +118 -0
- package/docs/troubleshooting.md +191 -0
- package/package.json +80 -0
package/dist/cors.js
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
const DEFAULT_METHODS = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'];
|
|
2
|
+
const DEFAULT_HEADERS = ['content-type', 'authorization'];
|
|
3
|
+
const resolveOrigin = (cfg, reqOrigin) => {
|
|
4
|
+
if (cfg.origin)
|
|
5
|
+
return cfg.origin(reqOrigin);
|
|
6
|
+
return reqOrigin === '' ? '*' : reqOrigin;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Merge two `Vary` header values, deduplicating tokens
|
|
10
|
+
* case-insensitively while preserving the first occurrence's casing.
|
|
11
|
+
* `Vary: *` short-circuits to `*` (HTTP semantic: “varies on every
|
|
12
|
+
* possible header”, no further tokens add information).
|
|
13
|
+
*
|
|
14
|
+
* Exported so server-level decorators (and tests) can compose the
|
|
15
|
+
* CORS `Vary` onto whatever the handler already declared.
|
|
16
|
+
*/
|
|
17
|
+
export const mergeVary = (existing, additional) => {
|
|
18
|
+
if (!existing)
|
|
19
|
+
return additional;
|
|
20
|
+
const seen = new Map();
|
|
21
|
+
for (const raw of [existing, additional]) {
|
|
22
|
+
for (const tok of raw.split(',')) {
|
|
23
|
+
const t = tok.trim();
|
|
24
|
+
if (t === '')
|
|
25
|
+
continue;
|
|
26
|
+
if (t === '*')
|
|
27
|
+
return '*';
|
|
28
|
+
const key = t.toLowerCase();
|
|
29
|
+
if (!seen.has(key))
|
|
30
|
+
seen.set(key, t);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return Array.from(seen.values()).join(', ');
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Build the `Access-Control-*` header bag for a non-preflight
|
|
37
|
+
* response.
|
|
38
|
+
*
|
|
39
|
+
* - `Access-Control-Allow-Origin` is omitted when the resolved origin
|
|
40
|
+
* is an empty string (browsers reject empty header values, and an
|
|
41
|
+
* empty header is the de-facto “reject” signal anyway).
|
|
42
|
+
* - `Vary: Origin` is always added when CORS is enabled so reverse
|
|
43
|
+
* proxies and CDNs don't cache one origin's response and serve it
|
|
44
|
+
* to another. The server-level decorator merges this token with
|
|
45
|
+
* any handler-supplied `Vary` (see {@link mergeVary}).
|
|
46
|
+
*/
|
|
47
|
+
export const buildCorsResponseHeaders = (cfg, req) => {
|
|
48
|
+
const headers = {};
|
|
49
|
+
const reqOrigin = req.headers['origin'] ?? '';
|
|
50
|
+
const allowed = resolveOrigin(cfg, reqOrigin);
|
|
51
|
+
if (allowed !== '') {
|
|
52
|
+
headers['access-control-allow-origin'] = allowed;
|
|
53
|
+
}
|
|
54
|
+
headers['vary'] = 'Origin';
|
|
55
|
+
if (cfg.credentials)
|
|
56
|
+
headers['access-control-allow-credentials'] = 'true';
|
|
57
|
+
if (cfg.exposeHeaders && cfg.exposeHeaders.length > 0) {
|
|
58
|
+
headers['access-control-expose-headers'] = cfg.exposeHeaders.join(', ');
|
|
59
|
+
}
|
|
60
|
+
return headers;
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* Intersect the browser's `Access-Control-Request-Headers` with the
|
|
64
|
+
* configured allowlist. Returns a comma-separated header value.
|
|
65
|
+
*
|
|
66
|
+
* Semantics:
|
|
67
|
+
* - `configured === undefined` → echo the request value verbatim
|
|
68
|
+
* (legacy permissive default for backwards compatibility). If the
|
|
69
|
+
* request also omitted the header, fall back to {@link DEFAULT_HEADERS}.
|
|
70
|
+
* - `configured.length === 0` → deny everything; returns `''`. The
|
|
71
|
+
* caller is expected to treat the empty string as "do not emit the
|
|
72
|
+
* header" (see {@link buildPreflightResponse}). This lets operators
|
|
73
|
+
* express a hard lockdown without inventing a separate flag.
|
|
74
|
+
* - `configured` non-empty → keep only requested tokens whose
|
|
75
|
+
* case-insensitive name appears in the allowlist, preserving input
|
|
76
|
+
* order, de-duplicating case-insensitive repeats. If the request
|
|
77
|
+
* omitted the header, the full allowlist is advertised so a browser
|
|
78
|
+
* that probes without `Access-Control-Request-Headers` still knows
|
|
79
|
+
* what is permitted.
|
|
80
|
+
*
|
|
81
|
+
* Token comparison is case-insensitive. The casing of the **request**
|
|
82
|
+
* is preserved (so a request asking for `Content-Type` gets
|
|
83
|
+
* `Content-Type` back), since browsers compare returned tokens
|
|
84
|
+
* case-insensitively anyway and round-tripping the request casing
|
|
85
|
+
* avoids needless diffs in test snapshots.
|
|
86
|
+
*/
|
|
87
|
+
const intersectAllowHeaders = (requested, configured) => {
|
|
88
|
+
if (configured === undefined) {
|
|
89
|
+
return requested ?? DEFAULT_HEADERS.join(', ');
|
|
90
|
+
}
|
|
91
|
+
if (configured.length === 0) {
|
|
92
|
+
// Hard lockdown: empty allowlist means deny all requested headers.
|
|
93
|
+
return '';
|
|
94
|
+
}
|
|
95
|
+
if (requested === undefined || requested === '') {
|
|
96
|
+
// No request header → advertise the full allowlist, deduped by
|
|
97
|
+
// case-insensitive name while preserving the configured casing.
|
|
98
|
+
const seen = new Set();
|
|
99
|
+
const out = [];
|
|
100
|
+
for (const h of configured) {
|
|
101
|
+
const key = h.toLowerCase();
|
|
102
|
+
if (seen.has(key))
|
|
103
|
+
continue;
|
|
104
|
+
seen.add(key);
|
|
105
|
+
out.push(h);
|
|
106
|
+
}
|
|
107
|
+
return out.join(', ');
|
|
108
|
+
}
|
|
109
|
+
const allow = new Set();
|
|
110
|
+
for (const h of configured)
|
|
111
|
+
allow.add(h.toLowerCase());
|
|
112
|
+
const seen = new Set();
|
|
113
|
+
const out = [];
|
|
114
|
+
for (const raw of requested.split(',')) {
|
|
115
|
+
const tok = raw.trim();
|
|
116
|
+
if (tok === '')
|
|
117
|
+
continue;
|
|
118
|
+
const key = tok.toLowerCase();
|
|
119
|
+
if (!allow.has(key))
|
|
120
|
+
continue;
|
|
121
|
+
if (seen.has(key))
|
|
122
|
+
continue;
|
|
123
|
+
seen.add(key);
|
|
124
|
+
out.push(tok);
|
|
125
|
+
}
|
|
126
|
+
return out.join(', ');
|
|
127
|
+
};
|
|
128
|
+
/**
|
|
129
|
+
* Build the preflight (`OPTIONS`) response for a given CORS config.
|
|
130
|
+
* The body is empty (204); headers cover origin, methods, headers,
|
|
131
|
+
* max-age, and `Vary: Origin`.
|
|
132
|
+
*
|
|
133
|
+
* `Access-Control-Allow-Headers` honours `cfg.allowHeaders` as a
|
|
134
|
+
* strict allowlist when it is set — anything off the list is dropped
|
|
135
|
+
* even if the browser requested it. When `cfg.allowHeaders` is unset
|
|
136
|
+
* the request value is echoed verbatim (legacy permissive default).
|
|
137
|
+
*
|
|
138
|
+
* The preflight response body itself does not vary on
|
|
139
|
+
* `Access-Control-Request-Method` / `…-Request-Headers` (we always
|
|
140
|
+
* derive the allow-headers value from the request), so those tokens
|
|
141
|
+
* are intentionally omitted to avoid fragmenting downstream caches.
|
|
142
|
+
*/
|
|
143
|
+
export const buildPreflightResponse = (cfg, req) => {
|
|
144
|
+
const reqOrigin = req.headers['origin'] ?? '';
|
|
145
|
+
const allowMethods = (cfg.allowMethods ?? DEFAULT_METHODS).join(', ');
|
|
146
|
+
const requested = req.headers['access-control-request-headers'];
|
|
147
|
+
const allowHeaders = intersectAllowHeaders(requested, cfg.allowHeaders);
|
|
148
|
+
const allowed = resolveOrigin(cfg, reqOrigin);
|
|
149
|
+
const headers = {
|
|
150
|
+
'access-control-allow-methods': allowMethods,
|
|
151
|
+
'access-control-max-age': String(cfg.maxAge ?? 86_400),
|
|
152
|
+
vary: 'Origin',
|
|
153
|
+
};
|
|
154
|
+
// Empty string == hard lockdown from intersectAllowHeaders.
|
|
155
|
+
// Emitting `access-control-allow-headers: ` would be a syntactically
|
|
156
|
+
// valid but functionally hostile header; omit it instead so the
|
|
157
|
+
// browser falls back to denying the preflight cleanly.
|
|
158
|
+
if (allowHeaders !== '') {
|
|
159
|
+
headers['access-control-allow-headers'] = allowHeaders;
|
|
160
|
+
}
|
|
161
|
+
if (allowed !== '')
|
|
162
|
+
headers['access-control-allow-origin'] = allowed;
|
|
163
|
+
if (cfg.credentials)
|
|
164
|
+
headers['access-control-allow-credentials'] = 'true';
|
|
165
|
+
return { empty: true, status: 204, headers };
|
|
166
|
+
};
|
|
167
|
+
//# sourceMappingURL=cors.js.map
|
package/dist/cors.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cors.js","sourceRoot":"","sources":["../src/cors.ts"],"names":[],"mappings":"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"}
|
package/dist/define.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Config } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Identity helper providing TypeScript intellisense at the config
|
|
4
|
+
* call site. Equivalent to `(config: Config) => config`.
|
|
5
|
+
*
|
|
6
|
+
* In non-production environments the returned config is **deep**-frozen
|
|
7
|
+
* so accidental mutation — including `config.routes['GET /x'] = …`
|
|
8
|
+
* or pushing into `cors.allowMethods` — throws loudly in tests instead
|
|
9
|
+
* of corrupting the server silently. Production skips the freeze to
|
|
10
|
+
* avoid breaking callers that legitimately patch the object after
|
|
11
|
+
* `defineConfig()` for env-specific wiring.
|
|
12
|
+
*
|
|
13
|
+
* Handler functions inside `routes` are intentionally left mutable
|
|
14
|
+
* (they're rebuilt per call anyway) — freeze stops at function
|
|
15
|
+
* boundaries.
|
|
16
|
+
*
|
|
17
|
+
* Usage:
|
|
18
|
+
* ```ts
|
|
19
|
+
* import { defineConfig } from '@databehave/server'
|
|
20
|
+
* export default defineConfig({ routes: { ... } })
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export declare const defineConfig: (config: Config) => Config;
|
|
24
|
+
/** @internal exported for the JSON config loader to apply the same protection. */
|
|
25
|
+
export declare const _deepFreezeForDev: <T>(value: T) => T;
|
|
26
|
+
//# sourceMappingURL=define.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"define.d.ts","sourceRoot":"","sources":["../src/define.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAoBxC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,YAAY,GAAI,QAAQ,MAAM,KAAG,MAK7C,CAAA;AAED,kFAAkF;AAClF,eAAO,MAAM,iBAAiB,GAAI,CAAC,EAAE,OAAO,CAAC,KAAG,CAG/C,CAAA"}
|
package/dist/define.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Recursively freeze a value so mutation throws in strict mode.
|
|
3
|
+
* Skips functions (handlers stay callable, and freezing their
|
|
4
|
+
* own properties is rarely useful) and respects already-frozen
|
|
5
|
+
* branches to avoid revisiting cycles.
|
|
6
|
+
*/
|
|
7
|
+
const deepFreeze = (value, seen = new WeakSet()) => {
|
|
8
|
+
if (value === null || typeof value !== 'object')
|
|
9
|
+
return value;
|
|
10
|
+
if (seen.has(value))
|
|
11
|
+
return value;
|
|
12
|
+
seen.add(value);
|
|
13
|
+
if (Object.isFrozen(value))
|
|
14
|
+
return value;
|
|
15
|
+
for (const v of Object.values(value)) {
|
|
16
|
+
if (v !== null && typeof v === 'object')
|
|
17
|
+
deepFreeze(v, seen);
|
|
18
|
+
}
|
|
19
|
+
Object.freeze(value);
|
|
20
|
+
return value;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Identity helper providing TypeScript intellisense at the config
|
|
24
|
+
* call site. Equivalent to `(config: Config) => config`.
|
|
25
|
+
*
|
|
26
|
+
* In non-production environments the returned config is **deep**-frozen
|
|
27
|
+
* so accidental mutation — including `config.routes['GET /x'] = …`
|
|
28
|
+
* or pushing into `cors.allowMethods` — throws loudly in tests instead
|
|
29
|
+
* of corrupting the server silently. Production skips the freeze to
|
|
30
|
+
* avoid breaking callers that legitimately patch the object after
|
|
31
|
+
* `defineConfig()` for env-specific wiring.
|
|
32
|
+
*
|
|
33
|
+
* Handler functions inside `routes` are intentionally left mutable
|
|
34
|
+
* (they're rebuilt per call anyway) — freeze stops at function
|
|
35
|
+
* boundaries.
|
|
36
|
+
*
|
|
37
|
+
* Usage:
|
|
38
|
+
* ```ts
|
|
39
|
+
* import { defineConfig } from '@databehave/server'
|
|
40
|
+
* export default defineConfig({ routes: { ... } })
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export const defineConfig = (config) => {
|
|
44
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
45
|
+
deepFreeze(config);
|
|
46
|
+
}
|
|
47
|
+
return config;
|
|
48
|
+
};
|
|
49
|
+
/** @internal exported for the JSON config loader to apply the same protection. */
|
|
50
|
+
export const _deepFreezeForDev = (value) => {
|
|
51
|
+
if (process.env.NODE_ENV !== 'production')
|
|
52
|
+
deepFreeze(value);
|
|
53
|
+
return value;
|
|
54
|
+
};
|
|
55
|
+
//# sourceMappingURL=define.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"define.js","sourceRoot":"","sources":["../src/define.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,UAAU,GAAG,CAAI,KAAQ,EAAE,OAAwB,IAAI,OAAO,EAAE,EAAK,EAAE;IAC3E,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAA;IAC7D,IAAI,IAAI,CAAC,GAAG,CAAC,KAAe,CAAC;QAAE,OAAO,KAAK,CAAA;IAC3C,IAAI,CAAC,GAAG,CAAC,KAAe,CAAC,CAAA;IACzB,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAA;IACxC,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,KAAgC,CAAC,EAAE,CAAC;QAChE,IAAI,CAAC,KAAK,IAAI,IAAI,OAAO,CAAC,KAAK,QAAQ;YAAE,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,CAAA;IAC9D,CAAC;IACD,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IACpB,OAAO,KAAK,CAAA;AACd,CAAC,CAAA;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,MAAc,EAAU,EAAE;IACrD,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,EAAE,CAAC;QAC1C,UAAU,CAAC,MAAM,CAAC,CAAA;IACpB,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC,CAAA;AAED,kFAAkF;AAClF,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAI,KAAQ,EAAK,EAAE;IAClD,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY;QAAE,UAAU,CAAC,KAAK,CAAC,CAAA;IAC5D,OAAO,KAAK,CAAA;AACd,CAAC,CAAA"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public entry point for `@databehave/server`.
|
|
3
|
+
*
|
|
4
|
+
* Re-exports the surface that consumers are allowed to use. Internal
|
|
5
|
+
* modules (`request`, `response`, `route-key`) are not re-exported on
|
|
6
|
+
* purpose — they are implementation details.
|
|
7
|
+
*
|
|
8
|
+
* `@databehave/server` is standalone — it ships with an in-server
|
|
9
|
+
* OAS-driven mock generator and pulls no DSL dependency at runtime.
|
|
10
|
+
* For richer mock data (distributions, datasets, FK-aware generation)
|
|
11
|
+
* install the DSL package separately and import it directly.
|
|
12
|
+
*/
|
|
13
|
+
export { defineConfig } from './define.js';
|
|
14
|
+
export { run, type RunHandle, type RunOptions } from './run.js';
|
|
15
|
+
export { createServer } from './server.js';
|
|
16
|
+
export { seedFor, type SeedInput } from './openapi/seed.js';
|
|
17
|
+
export { loadConfig, type EndpointResponse, type EndpointSpec, type LoadedConfig, type LoadConfigOptions, type JsonConfig, } from './json-config.js';
|
|
18
|
+
export { resolveStatus, type MockModeConfig, type MockModeLogger, } from './mock-mode.js';
|
|
19
|
+
export type { Config, CorsConfig, Handler, ListenHandle, ListenOptions, Method, MockRequest, MockResponse, MockResponseBody, ObservedMethod, RouteKey, Server, } from './types.js';
|
|
20
|
+
export type { AdminModeConfig, ErrorMode, StickyOverride, OverrideMatcher, AdminModeCors, } from './admin/admin-types.js';
|
|
21
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,EAAE,GAAG,EAAE,KAAK,SAAS,EAAE,KAAK,UAAU,EAAE,MAAM,UAAU,CAAA;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,EAAE,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAC3D,OAAO,EACL,UAAU,EACV,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,KAAK,UAAU,GAChB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,aAAa,EACb,KAAK,cAAc,EACnB,KAAK,cAAc,GACpB,MAAM,gBAAgB,CAAA;AACvB,YAAY,EACV,MAAM,EACN,UAAU,EACV,OAAO,EACP,YAAY,EACZ,aAAa,EACb,MAAM,EACN,WAAW,EACX,YAAY,EACZ,gBAAgB,EAChB,cAAc,EACd,QAAQ,EACR,MAAM,GACP,MAAM,YAAY,CAAA;AAGnB,YAAY,EACV,eAAe,EACf,SAAS,EACT,cAAc,EACd,eAAe,EACf,aAAa,GACd,MAAM,wBAAwB,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public entry point for `@databehave/server`.
|
|
3
|
+
*
|
|
4
|
+
* Re-exports the surface that consumers are allowed to use. Internal
|
|
5
|
+
* modules (`request`, `response`, `route-key`) are not re-exported on
|
|
6
|
+
* purpose — they are implementation details.
|
|
7
|
+
*
|
|
8
|
+
* `@databehave/server` is standalone — it ships with an in-server
|
|
9
|
+
* OAS-driven mock generator and pulls no DSL dependency at runtime.
|
|
10
|
+
* For richer mock data (distributions, datasets, FK-aware generation)
|
|
11
|
+
* install the DSL package separately and import it directly.
|
|
12
|
+
*/
|
|
13
|
+
export { defineConfig } from './define.js';
|
|
14
|
+
export { run } from './run.js';
|
|
15
|
+
export { createServer } from './server.js';
|
|
16
|
+
export { seedFor } from './openapi/seed.js';
|
|
17
|
+
export { loadConfig, } from './json-config.js';
|
|
18
|
+
export { resolveStatus, } from './mock-mode.js';
|
|
19
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,EAAE,GAAG,EAAmC,MAAM,UAAU,CAAA;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,EAAE,OAAO,EAAkB,MAAM,mBAAmB,CAAA;AAC3D,OAAO,EACL,UAAU,GAMX,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,aAAa,GAGd,MAAM,gBAAgB,CAAA"}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { type MockModeConfig } from './mock-mode.js';
|
|
2
|
+
import type { Config, CorsConfig, Handler } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Static response declarable per endpoint. Returned verbatim when the
|
|
5
|
+
* endpoint uses the `{ response }` form. Mirrors the JSON-safe subset
|
|
6
|
+
* of `MockResponse` (no `text` / `html` / `raw`).
|
|
7
|
+
*/
|
|
8
|
+
export interface EndpointResponse {
|
|
9
|
+
status: number;
|
|
10
|
+
json?: unknown;
|
|
11
|
+
empty?: boolean;
|
|
12
|
+
headers?: Record<string, string>;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Per-endpoint declaration. Three forms:
|
|
16
|
+
*
|
|
17
|
+
* - **string**: module path to a handler (shorthand for `{ handler }`)
|
|
18
|
+
* - **`{ handler, status? }`**: dynamic-import handler. Optional
|
|
19
|
+
* `status` registers an HTTP status override for this route in
|
|
20
|
+
* the mock-mode `pathOverrides` map (e.g. force 500 for that route).
|
|
21
|
+
* - **`{ response }`**: static response only — no handler module.
|
|
22
|
+
* The handler is synthesized to return the literal response.
|
|
23
|
+
*
|
|
24
|
+
* `handler` and `response` are mutually exclusive.
|
|
25
|
+
*/
|
|
26
|
+
export type EndpointSpec = string | {
|
|
27
|
+
handler: string;
|
|
28
|
+
status?: number;
|
|
29
|
+
response?: never;
|
|
30
|
+
} | {
|
|
31
|
+
response: EndpointResponse;
|
|
32
|
+
handler?: never;
|
|
33
|
+
status?: never;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Raw JSON shape declared inside `databehave.json`. Mirrors a
|
|
37
|
+
* narrow subset of `Config` plus the on-disk additions
|
|
38
|
+
* (`endpoints` map of route-key → `EndpointSpec`).
|
|
39
|
+
*/
|
|
40
|
+
export interface JsonConfig {
|
|
41
|
+
/** Path to the JSON OpenAPI document, relative to this file. */
|
|
42
|
+
openapi?: string;
|
|
43
|
+
/** Server listen options used by the CLI. */
|
|
44
|
+
server?: {
|
|
45
|
+
host?: string;
|
|
46
|
+
port?: number;
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Prefix automatically prepended to every `endpoints` key.
|
|
50
|
+
* Lets callers write `"GET products/list"` instead of
|
|
51
|
+
* repeating the API prefix in every entry. Must start with `/` and
|
|
52
|
+
* must not end with `/` (e.g. `"/api/v1"`). OpenAPI paths are
|
|
53
|
+
* left untouched — they already carry their full path in the OAS document.
|
|
54
|
+
*/
|
|
55
|
+
basePath?: string;
|
|
56
|
+
/**
|
|
57
|
+
* CORS knobs. `origin` may be a single allowed origin string or an
|
|
58
|
+
* allowlist of strings (the function form on `CorsConfig`
|
|
59
|
+
* is reserved for the programmatic API). Anything off the allowlist
|
|
60
|
+
* is rejected (empty header) so misconfigured callers fail loudly
|
|
61
|
+
* instead of silently leaking `*`.
|
|
62
|
+
*/
|
|
63
|
+
cors?: Omit<CorsConfig, 'origin'> & {
|
|
64
|
+
origin?: string | readonly string[];
|
|
65
|
+
};
|
|
66
|
+
/** Built-in mock-mode behaviour. Disabled by default. */
|
|
67
|
+
mockMode?: MockModeConfig;
|
|
68
|
+
/**
|
|
69
|
+
* Opt-in admin / error-injection panel. Default: disabled.
|
|
70
|
+
* Pass-through to `Config.admin`. The JSON loader
|
|
71
|
+
* automatically supplements `openapiBody` from the resolved OpenAPI
|
|
72
|
+
* document so the UI route picker works without manual wiring.
|
|
73
|
+
*/
|
|
74
|
+
admin?: Config['admin'];
|
|
75
|
+
/**
|
|
76
|
+
* Opt-in per-request access logs. Pass-through to
|
|
77
|
+
* `Config.log`. Default: disabled. See README
|
|
78
|
+
* "Access logs" for the shape.
|
|
79
|
+
*/
|
|
80
|
+
log?: Config['log'];
|
|
81
|
+
/**
|
|
82
|
+
* Opt-in inbound request validation against the OpenAPI document.
|
|
83
|
+
* Pass-through to `Config.validation`. Default off
|
|
84
|
+
* (`{ request: false }`) — when omitted the runtime behaves
|
|
85
|
+
* byte-identical to a build without the validator.
|
|
86
|
+
*/
|
|
87
|
+
validation?: Config['validation'];
|
|
88
|
+
/**
|
|
89
|
+
* Opt-in auto-schema mode (Phase 2C). When `enabled: true`, every
|
|
90
|
+
* OAS path not covered by `endpoints` is served from data
|
|
91
|
+
* generated by `@databehave/schema`'s `mock()` engine, derived
|
|
92
|
+
* from the OpenAPI document. The peer is loaded via dynamic
|
|
93
|
+
* `import()` at server-creation time; install it separately with
|
|
94
|
+
* `npm i @databehave/schema`. See README "Auto-schema mode".
|
|
95
|
+
*
|
|
96
|
+
* Always an object — the legacy boolean shorthand
|
|
97
|
+
* (`schema: true`) was removed. Unknown keys throw at
|
|
98
|
+
* config-load time. Fields:
|
|
99
|
+
*
|
|
100
|
+
* - `enabled` — required boolean. `false` (or omitting the
|
|
101
|
+
* `schema` field entirely) keeps the default JSONC mock-only
|
|
102
|
+
* flow.
|
|
103
|
+
* - `seed` — `number` (fixed), `"stable"` (per-request hash),
|
|
104
|
+
* or `"random"` (fresh per request). Default `"stable"`.
|
|
105
|
+
* - `locale` — optional locale tag (forwarded as a future hint).
|
|
106
|
+
* - `arrayCount` — default array length when OAS lacks `minItems`.
|
|
107
|
+
*/
|
|
108
|
+
schema?: {
|
|
109
|
+
enabled: boolean;
|
|
110
|
+
seed?: number | 'stable' | 'random';
|
|
111
|
+
locale?: string;
|
|
112
|
+
arrayCount?: number;
|
|
113
|
+
};
|
|
114
|
+
/**
|
|
115
|
+
* Route-key → endpoint declaration map. Keys may be written
|
|
116
|
+
* relative to `basePath` (e.g. `"GET products/list"`); they
|
|
117
|
+
* may also be absolute (`"GET /health"`) — any key starting with
|
|
118
|
+
* `/` after the method is registered verbatim.
|
|
119
|
+
*/
|
|
120
|
+
endpoints?: Partial<Record<string, EndpointSpec>>;
|
|
121
|
+
}
|
|
122
|
+
/** Result of loading a JSON config from disk. */
|
|
123
|
+
export interface LoadedConfig {
|
|
124
|
+
/** Fully-assembled config ready for `createServer`. */
|
|
125
|
+
readonly config: Config;
|
|
126
|
+
/** Server listen options copied verbatim from the JSON. */
|
|
127
|
+
readonly server: {
|
|
128
|
+
host: string;
|
|
129
|
+
port: number;
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Options for `loadConfig`.
|
|
134
|
+
*/
|
|
135
|
+
export interface LoadConfigOptions {
|
|
136
|
+
/**
|
|
137
|
+
* Pre-resolved handler map. Keys may match the JSONC `endpoints`
|
|
138
|
+
* value either exactly (e.g. `./src/routes/health.js`) or in any
|
|
139
|
+
* canonically equivalent form — leading `./` and the file extension
|
|
140
|
+
* (`.js`/`.mjs`/`.cjs`/`.ts`/`.tsx`/`.mts`/`.cts`) are stripped
|
|
141
|
+
* before comparison. When a key matches, the handler is used
|
|
142
|
+
* directly and the dynamic `import()` for that route is skipped.
|
|
143
|
+
*
|
|
144
|
+
* Use case: test environments (vitest under plain Node 18) that cannot
|
|
145
|
+
* load `.ts` source files through native `import()`. Construct the map
|
|
146
|
+
* via static imports or `import.meta.glob('eager')`, then pass it in.
|
|
147
|
+
*
|
|
148
|
+
* Handlers not present in the map fall back to dynamic import. Values
|
|
149
|
+
* that are not functions raise an error at boot time.
|
|
150
|
+
*/
|
|
151
|
+
handlers?: Record<string, Handler>;
|
|
152
|
+
/**
|
|
153
|
+
* Sink for non-fatal warnings emitted while wiring the OpenAPI
|
|
154
|
+
* adapter (walk errors, empty schemas). Defaults to `console.warn`.
|
|
155
|
+
* Inject a no-op logger from tests to silence the output, or a
|
|
156
|
+
* structured logger in production to capture the messages.
|
|
157
|
+
*/
|
|
158
|
+
logger?: {
|
|
159
|
+
warn(message: string): void;
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Load and fully resolve a `databehave.json`.
|
|
164
|
+
*
|
|
165
|
+
* Returns a ready-to-run `Config` plus the listen options the
|
|
166
|
+
* CLI should bind to. Errors are thrown synchronously after parsing
|
|
167
|
+
* to fail fast on bad configs.
|
|
168
|
+
*/
|
|
169
|
+
export declare const loadConfig: (configPath: string, options?: LoadConfigOptions) => Promise<LoadedConfig>;
|
|
170
|
+
//# sourceMappingURL=json-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-config.d.ts","sourceRoot":"","sources":["../src/json-config.ts"],"names":[],"mappings":"AAoBA,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,gBAAgB,CAAA;AAYvB,OAAO,KAAK,EACV,MAAM,EACN,UAAU,EACV,OAAO,EAGR,MAAM,YAAY,CAAA;AAEnB;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACjC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,YAAY,GACpB,MAAM,GACN;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,KAAK,CAAA;CAAE,GACtD;IAAE,QAAQ,EAAE,gBAAgB,CAAC;IAAC,OAAO,CAAC,EAAE,KAAK,CAAC;IAAC,MAAM,CAAC,EAAE,KAAK,CAAA;CAAE,CAAA;AAEnE;;;;GAIG;AACH,MAAM,WAAW,UAAU;IACzB,gEAAgE;IAChE,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,6CAA6C;IAC7C,MAAM,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IACzC;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,GAAG;QAClC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAAA;KACpC,CAAA;IACD,yDAAyD;IACzD,QAAQ,CAAC,EAAE,cAAc,CAAA;IACzB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,CAAA;IACvB;;;;OAIG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,CAAA;IACnB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC,YAAY,CAAC,CAAA;IACjC;;;;;;;;;;;;;;;;;;;OAmBG;IACH,MAAM,CAAC,EAAE;QACP,OAAO,EAAE,OAAO,CAAA;QAChB,IAAI,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,QAAQ,CAAA;QACnC,MAAM,CAAC,EAAE,MAAM,CAAA;QACf,UAAU,CAAC,EAAE,MAAM,CAAA;KACpB,CAAA;IACD;;;;;OAKG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAA;CAClD;AAED,iDAAiD;AACjD,MAAM,WAAW,YAAY;IAC3B,uDAAuD;IACvD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,2DAA2D;IAC3D,QAAQ,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;CAChD;AAybD;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAClC;;;;;OAKG;IACH,MAAM,CAAC,EAAE;QAAE,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAA;CACzC;AAED;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,GACrB,YAAY,MAAM,EAClB,UAAU,iBAAiB,KAC1B,OAAO,CAAC,YAAY,CAgUtB,CAAA"}
|