@databehave/server 0.1.4 → 0.2.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.
Files changed (156) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.md +85 -83
  3. package/dist/cors.d.ts +1 -1
  4. package/dist/cors.js +1 -1
  5. package/dist/cors.js.map +1 -1
  6. package/dist/http.d.ts +94 -0
  7. package/dist/http.d.ts.map +1 -0
  8. package/dist/http.js +23 -0
  9. package/dist/http.js.map +1 -0
  10. package/dist/index.d.ts +10 -20
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +8 -18
  13. package/dist/index.js.map +1 -1
  14. package/dist/log.d.ts +9 -49
  15. package/dist/log.d.ts.map +1 -1
  16. package/dist/log.js +16 -92
  17. package/dist/log.js.map +1 -1
  18. package/dist/node-authority.d.ts +12 -0
  19. package/dist/node-authority.d.ts.map +1 -0
  20. package/dist/node-authority.js +72 -0
  21. package/dist/node-authority.js.map +1 -0
  22. package/dist/node-body.d.ts +11 -0
  23. package/dist/node-body.d.ts.map +1 -0
  24. package/dist/node-body.js +61 -0
  25. package/dist/node-body.js.map +1 -0
  26. package/dist/node-http.d.ts +19 -0
  27. package/dist/node-http.d.ts.map +1 -0
  28. package/dist/node-http.js +210 -0
  29. package/dist/node-http.js.map +1 -0
  30. package/dist/plugins/access-log.d.ts +11 -0
  31. package/dist/plugins/access-log.d.ts.map +1 -0
  32. package/dist/plugins/access-log.js +27 -0
  33. package/dist/plugins/access-log.js.map +1 -0
  34. package/dist/plugins/cors.d.ts +5 -0
  35. package/dist/plugins/cors.d.ts.map +1 -0
  36. package/dist/plugins/cors.js +35 -0
  37. package/dist/plugins/cors.js.map +1 -0
  38. package/dist/plugins/routes.d.ts +5 -0
  39. package/dist/plugins/routes.d.ts.map +1 -0
  40. package/dist/plugins/routes.js +10 -0
  41. package/dist/plugins/routes.js.map +1 -0
  42. package/dist/request.d.ts +2 -2
  43. package/dist/request.d.ts.map +1 -1
  44. package/dist/request.js +6 -4
  45. package/dist/request.js.map +1 -1
  46. package/dist/route-key.d.ts +2 -0
  47. package/dist/route-key.d.ts.map +1 -1
  48. package/dist/route-key.js +5 -1
  49. package/dist/route-key.js.map +1 -1
  50. package/dist/server.d.ts +7 -59
  51. package/dist/server.d.ts.map +1 -1
  52. package/dist/server.js +289 -466
  53. package/dist/server.js.map +1 -1
  54. package/dist/types.d.ts +10 -156
  55. package/dist/types.d.ts.map +1 -1
  56. package/dist/types.js +1 -1
  57. package/package.json +9 -22
  58. package/dist/admin/admin-routes.d.ts +0 -42
  59. package/dist/admin/admin-routes.d.ts.map +0 -1
  60. package/dist/admin/admin-routes.js +0 -472
  61. package/dist/admin/admin-routes.js.map +0 -1
  62. package/dist/admin/admin-types.d.ts +0 -170
  63. package/dist/admin/admin-types.d.ts.map +0 -1
  64. package/dist/admin/admin-types.js +0 -30
  65. package/dist/admin/admin-types.js.map +0 -1
  66. package/dist/admin/banner.d.ts +0 -11
  67. package/dist/admin/banner.d.ts.map +0 -1
  68. package/dist/admin/banner.js +0 -5
  69. package/dist/admin/banner.js.map +0 -1
  70. package/dist/admin/header-parser.d.ts +0 -14
  71. package/dist/admin/header-parser.d.ts.map +0 -1
  72. package/dist/admin/header-parser.js +0 -171
  73. package/dist/admin/header-parser.js.map +0 -1
  74. package/dist/admin/inject.d.ts +0 -48
  75. package/dist/admin/inject.d.ts.map +0 -1
  76. package/dist/admin/inject.js +0 -167
  77. package/dist/admin/inject.js.map +0 -1
  78. package/dist/admin/overrides-store.d.ts +0 -18
  79. package/dist/admin/overrides-store.d.ts.map +0 -1
  80. package/dist/admin/overrides-store.js +0 -100
  81. package/dist/admin/overrides-store.js.map +0 -1
  82. package/dist/admin/resolve-cors.d.ts +0 -22
  83. package/dist/admin/resolve-cors.d.ts.map +0 -1
  84. package/dist/admin/resolve-cors.js +0 -28
  85. package/dist/admin/resolve-cors.js.map +0 -1
  86. package/dist/admin/scenarios-store.d.ts +0 -15
  87. package/dist/admin/scenarios-store.d.ts.map +0 -1
  88. package/dist/admin/scenarios-store.js +0 -109
  89. package/dist/admin/scenarios-store.js.map +0 -1
  90. package/dist/admin/ui.css +0 -1
  91. package/dist/admin/ui.html +0 -13
  92. package/dist/admin/ui.js +0 -240
  93. package/dist/bin-helpers.d.ts +0 -46
  94. package/dist/bin-helpers.d.ts.map +0 -1
  95. package/dist/bin-helpers.js +0 -61
  96. package/dist/bin-helpers.js.map +0 -1
  97. package/dist/bin.d.ts +0 -3
  98. package/dist/bin.d.ts.map +0 -1
  99. package/dist/bin.js +0 -86
  100. package/dist/bin.js.map +0 -1
  101. package/dist/define.d.ts +0 -26
  102. package/dist/define.d.ts.map +0 -1
  103. package/dist/define.js +0 -55
  104. package/dist/define.js.map +0 -1
  105. package/dist/json-config.d.ts +0 -170
  106. package/dist/json-config.d.ts.map +0 -1
  107. package/dist/json-config.js +0 -684
  108. package/dist/json-config.js.map +0 -1
  109. package/dist/jsonc.d.ts +0 -24
  110. package/dist/jsonc.d.ts.map +0 -1
  111. package/dist/jsonc.js +0 -125
  112. package/dist/jsonc.js.map +0 -1
  113. package/dist/middleware/request-validation.d.ts +0 -58
  114. package/dist/middleware/request-validation.d.ts.map +0 -1
  115. package/dist/middleware/request-validation.js +0 -328
  116. package/dist/middleware/request-validation.js.map +0 -1
  117. package/dist/mock-mode.d.ts +0 -95
  118. package/dist/mock-mode.d.ts.map +0 -1
  119. package/dist/mock-mode.js +0 -95
  120. package/dist/mock-mode.js.map +0 -1
  121. package/dist/openapi/auto-schema.d.ts +0 -83
  122. package/dist/openapi/auto-schema.d.ts.map +0 -1
  123. package/dist/openapi/auto-schema.js +0 -232
  124. package/dist/openapi/auto-schema.js.map +0 -1
  125. package/dist/openapi/generate.d.ts +0 -20
  126. package/dist/openapi/generate.d.ts.map +0 -1
  127. package/dist/openapi/generate.js +0 -121
  128. package/dist/openapi/generate.js.map +0 -1
  129. package/dist/openapi/loader.d.ts +0 -18
  130. package/dist/openapi/loader.d.ts.map +0 -1
  131. package/dist/openapi/loader.js +0 -25
  132. package/dist/openapi/loader.js.map +0 -1
  133. package/dist/openapi/register.d.ts +0 -58
  134. package/dist/openapi/register.d.ts.map +0 -1
  135. package/dist/openapi/register.js +0 -166
  136. package/dist/openapi/register.js.map +0 -1
  137. package/dist/openapi/seed.d.ts +0 -16
  138. package/dist/openapi/seed.d.ts.map +0 -1
  139. package/dist/openapi/seed.js +0 -58
  140. package/dist/openapi/seed.js.map +0 -1
  141. package/dist/openapi/translate.d.ts +0 -55
  142. package/dist/openapi/translate.d.ts.map +0 -1
  143. package/dist/openapi/translate.js +0 -319
  144. package/dist/openapi/translate.js.map +0 -1
  145. package/dist/openapi/walker.d.ts +0 -44
  146. package/dist/openapi/walker.d.ts.map +0 -1
  147. package/dist/openapi/walker.js +0 -15
  148. package/dist/openapi/walker.js.map +0 -1
  149. package/dist/run.d.ts +0 -27
  150. package/dist/run.d.ts.map +0 -1
  151. package/dist/run.js +0 -87
  152. package/dist/run.js.map +0 -1
  153. package/dist/validation/validate.d.ts +0 -38
  154. package/dist/validation/validate.d.ts.map +0 -1
  155. package/dist/validation/validate.js +0 -372
  156. package/dist/validation/validate.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -7,6 +7,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ Upcoming package version: **0.2.0**. This section describes planned release contents, not a published release.
11
+
12
+ ### Breaking changes
13
+
14
+ - Require Node.js 24 or 26; support and test majors 24 and 26. Drop Node.js 18, 20 and 22.
15
+ - Replace `createServer` and server-owned JSONC/CLI assembly with core host composition and explicit HTTP plugins.
16
+ - Move OpenAPI, request validation, admin UI, fault controls and CLI ownership to their separate packages.
17
+ - Move the shared drain timeout to `httpPlugin`; HTTP owns both in-process requests and response stream lifetimes.
18
+
19
+ ### Added
20
+
21
+ - Public route, middleware, bind-guard and route-source contracts with registration sealing and staged startup.
22
+ - Explicit Node transport, CORS and access logging plugins, authority validation, bounded shutdown and cancellation.
23
+ - Consistent HEAD fallback, response decoration, route precedence and single-outcome observation.
24
+
25
+ See [migration](../../MIGRATION.md) and [release procedures](../../docs/releasing.md).
26
+
10
27
  ## [0.1.0] - 2026-06-03
11
28
 
12
29
  Initial public release of `@databehave/server`.
package/README.md CHANGED
@@ -1,87 +1,89 @@
1
- <!-- markdownlint-disable MD033 MD041 -->
2
-
3
- <div align="center">
4
-
5
1
  # @databehave/server
6
2
 
7
- <b>A JSON file config-driven mock server</b>
8
-
9
- [![npm version](https://img.shields.io/npm/v/@databehave/server.svg)](https://www.npmjs.com/package/@databehave/server)
10
- [![CI](https://github.com/ochairo/databehave/actions/workflows/ci.yml/badge.svg)](https://github.com/ochairo/databehave/actions/workflows/ci.yml)
11
- [![Node.js](https://img.shields.io/badge/node-%E2%89%A518.17-brightgreen)](https://nodejs.org/)
12
- [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
13
-
14
- </div>
15
-
16
- ## Install
17
-
18
- You can install `@databehave/server` alone but to get full functionality, the recommended companion is `@databehave/schema`.
19
-
20
- ```bash
21
- npm install @databehave/schema @databehave/server
22
- # or: pnpm add @databehave/schema @databehave/server
23
- # or: yarn add @databehave/schema @databehave/server
24
- ```
25
-
26
- > `@databehave/schema` is declared as an optional peer dependency. Install it alongside `@databehave/server` whenever you enable auto-schema mode.
27
-
28
- ## A 60-second tour
29
-
30
- **1. OpenAPI specs driven data** — realistic mock data derived from your OpenAPI document, with zero config. See [docs/openapi.md](docs/openapi.md) for the `openapi` field reference.
31
-
32
- **2. Auto-schema mode (`@databehave/schema`)** — realistic distributions, referential integrity, and deterministic seeding. See [docs/openapi/auto-schema.md](docs/openapi/auto-schema.md) for the `schema` field reference (knobs, defaults, install hint).
33
-
34
- **3. Full custom data** — hand-write response generators as modules, and point routes to them. The module exports a function that receives the request and returns a response shape. You can use `@databehave/schema` or any other data source.
35
-
36
- **4. Admin UI** You have a UI to override any route's response, with the override "sticking" until you remove it. No code change required for error injection.
37
-
38
- ```jsonc
39
- {
40
- "server": {
41
- "host": "127.0.0.1",
42
- "port": "8000"
43
- },
44
- // 1. OpenAPI specs driven data
45
- "openapi": "./openapi.json",
46
- // 2. Auto-schema mode (Adds @databehave/schema data generation engine to OpenAPI specs)
47
- "schema": { "enabled": true },
48
- // 3. Full custom data
49
- "endpoints": {
50
- "GET /health": { "response": { "status": 200, "json": { "ok": true } } },
51
- "GET /products/list": "./src/routes/products/list.js",
52
- "POST /products/bulk-update": "./src/routes/products/bulk-update.js"
53
- },
54
- // 4. Admin UI: http://[server.host]:[server.port]/[admin.path]
55
- "admin": { "enabled": true, "path": "/databehave" },
56
- }
3
+ HTTP contracts and explicit HTTP plugins for Databehave. The package has no schema,
4
+ OpenAPI, admin, UI-build or CLI dependency.
5
+
6
+ ```ts
7
+ import { createHost } from '@databehave/core'
8
+ import {
9
+ httpPlugin, routesPlugin, corsPlugin, accessLogPlugin, nodeHttpPlugin,
10
+ } from '@databehave/server'
11
+
12
+ const host = createHost({ plugins: [
13
+ httpPlugin(),
14
+ routesPlugin({ 'GET /hello': () => ({ status: 200, json: { hello: 'world' } }) }),
15
+ corsPlugin({ origin: () => '*' }),
16
+ accessLogPlugin(),
17
+ nodeHttpPlugin({ host: '127.0.0.1', port: 3000 }),
18
+ ] })
19
+ await host.start()
20
+ // await host.close() when the application shuts down.
57
21
  ```
58
22
 
59
- ## Documentation
60
-
61
- ### Start here
62
-
63
- - [Index](docs/index.md) — package TOC and reading order.
64
- - [Getting Started](docs/getting-started.md) — 5-step tutorial from install to a custom route.
65
- - [Troubleshooting](docs/troubleshooting.md) — symptom → cause → fix.
66
-
67
- ### Reference
68
-
69
- - [Config](docs/config/index.md) — every `databehave.json` field.
70
- - [Config Validation](docs/config/validation.md) — opt-in inbound request validation (RFC 7807).
71
- - [Admin](docs/admin/index.md) — admin UI, REST endpoints, matchers, ErrorMode, `x-mock-*` headers, scenarios, security notes.
72
- - [OpenAPI](docs/openapi/fallback.md) — OAS fallback walker, [Auto-schema](docs/openapi/auto-schema.md), keyword parity.
73
- - [CLI](docs/cli.md) — `@databehave/server` CLI reference.
74
- - [Errors](docs/errors.md) — every user-visible error message, source-cited.
75
-
76
- ### Deeper
77
-
78
- - [Design](docs/design.md) — architecture, dispatch pipeline, why the HTTP framework is hidden.
79
- - [Stability](docs/stability.md) — public-surface lock, SemVer triggers, contract surfaces.
80
- - [Recipes](docs/recipes.md) — error injection, static responses, programmatic hooks, in-process tests with `fetch()`.
81
-
82
- <br /><br />
83
- <div align="center">
84
-
85
- © 2026-present ochairo. See [LICENSE](LICENSE)
86
-
87
- </div>
23
+ For in-process requests, omit the listener and call
24
+ `host.get(httpCapability).fetch(new Request('http://localhost/hello'))` after startup.
25
+
26
+ External plugins declare `requires: [httpCapability]` and register route sources,
27
+ middleware or bind guards during `setup`. Pass `ctx.order` as the contribution order;
28
+ this preserves explicit composition order independently of capability dependency order.
29
+ Route sources materialize once after every plugin has prepared. Explicit routes replace
30
+ generated routes with the same key; equal-priority duplicates fail with both owners.
31
+ Exact paths precede parameterized paths. Parameterized ties use composition order and
32
+ then declaration order.
33
+
34
+ `http.resolveRoute(method, path)` uses the same precedence and HEAD fallback as dispatch. A route contribution's
35
+ `cors` field can override application CORS, or be `false` when its owner supplies the policy. General CORS only
36
+ handles resolved routes; preflights resolve the `Access-Control-Request-Method` target. Unknown paths receive no
37
+ implicit CORS authorization. This keeps feature-owned admin restrictions effective in either composition order.
38
+
39
+ The middleware pipeline runs preflight, validation, interception, the selected handler,
40
+ response decoration, and final observation. Short circuits and error responses receive
41
+ decoration once. Error handlers are bounded; an error-handler failure yields a generic
42
+ 500. Observation cannot replace a response. HEAD calls an explicit HEAD handler or GET
43
+ fallback once, retains `request.method === 'HEAD'`, exposes `effectiveMethod`, and strips
44
+ the body after decoration. One request produces one observation.
45
+
46
+ `terminateTransport()` produces a terminal transport outcome for Node listeners.
47
+ Fetch cannot destroy a connection and reports `UnsupportedTransportError`. Request
48
+ signals cancel on disconnect or host shutdown. Dispatch is admitted only after HTTP's open
49
+ phase and rejects already-aborted callers before executing middleware or handlers. The HTTP
50
+ runtime stops admission synchronously, cancels work, then waits for handlers and returned
51
+ response bodies (EOF, error, or completed cancellation) before dependent resources are disposed.
52
+ HEAD-suppressed bodies are cancelled. Callers must consume or cancel returned bodies.
53
+
54
+ Configure the shared shutdown budget with `httpPlugin({ drainTimeoutMs: 1000 })` (1000 ms
55
+ by default). The deadline begins when admission stops and covers both logical requests and
56
+ Node connections; it is not restarted for each drain. The listener force-closes remaining
57
+ connections at that deadline. Uncooperative handlers or body cancellation report a failed
58
+ close instead of claiming a clean drain; callbacks cannot be forcibly stopped by JavaScript.
59
+ The former `nodeHttpPlugin({ drainTimeoutMs })` option moves to `httpPlugin`.
60
+
61
+ Node validates exactly one Host header and the origin-form request target before dispatch.
62
+ Host must use the actual listener port and match its binding, local socket address, or a
63
+ loopback alias for a loopback endpoint. For custom DNS use
64
+ `nodeHttpPlugin({ allowedHosts: ['app.example.test'] })`; entries are explicit hostnames or
65
+ IP literals, without ports, schemes, credentials, paths, or wildcards. Forwarded headers do
66
+ not grant authority. Malformed requests receive 400; unapproved authorities receive 421.
67
+ In-process Fetch requests remain trusted caller-supplied requests.
68
+
69
+ Incoming Node bodies are pulled in bounded chunks. Cancelling a body stops intake without
70
+ destroying the response socket, allowing early validation errors to reach uploading clients.
71
+ Incomplete uploads receive `Connection: close`, but remain readable while a response stream
72
+ consumes them. Explicit cancellation arms the rejection cleanup deadline immediately. Otherwise,
73
+ response-source completion stops remaining input and arms cleanup before waiting for the response
74
+ to flush. There is no ordinary response-write timeout; an uncancelled stalled duplex exchange
75
+ remains backpressured until completion, disconnection or bounded host shutdown. Fully read bodies
76
+ retain normal keep-alive behavior.
77
+
78
+ Feature packages use this same public boundary:
79
+
80
+ - [OpenAPI](../openapi/README.md): catalogs, selectable generators, validation and mock status policy.
81
+ - [Admin](../admin/README.md): opt-in fault injection, UI/API and scenarios.
82
+ - [CLI](../cli/README.md): explicit ESM composition and process lifecycle.
83
+ - [Core](../core/README.md): capability dependencies and lifecycle.
84
+
85
+ The upcoming 0.2 release removes the former JSONC configuration and monolithic `createServer` API.
86
+ See the [migration guide](../../MIGRATION.md) for the replacement of each option.
87
+
88
+ Requires Node.js 24 or 26; supported majors are 24 and 26. Start with the
89
+ [runnable HTTP example](../../examples/http.mjs) and [plugin author guide](../../docs/plugins.md).
package/dist/cors.d.ts CHANGED
@@ -12,7 +12,7 @@
12
12
  * migration stays backwards-compatible:
13
13
  * - origin: mirror request `Origin`, or `*` when absent
14
14
  * - credentials: header omitted by default; set `credentials: true` in
15
- * `Config.cors` to send `Access-Control-Allow-Credentials: true`
15
+ * `corsPlugin` to send `Access-Control-Allow-Credentials: true`
16
16
  */
17
17
  import type { CorsConfig, MockRequest, MockResponse } from './types.js';
18
18
  /**
package/dist/cors.js CHANGED
@@ -1,4 +1,4 @@
1
- const DEFAULT_METHODS = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'];
1
+ const DEFAULT_METHODS = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD', 'OPTIONS'];
2
2
  const DEFAULT_HEADERS = ['content-type', 'authorization'];
3
3
  const resolveOrigin = (cfg, reqOrigin) => {
4
4
  if (cfg.origin)
package/dist/cors.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cors.js","sourceRoot":"","sources":["../src/cors.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cors.js","sourceRoot":"","sources":["../src/cors.ts"],"names":[],"mappings":"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"}
package/dist/http.d.ts ADDED
@@ -0,0 +1,94 @@
1
+ import type { CorsConfig, Handler, Method, MockRequest, MockResponse, RouteKey } from './types.js';
2
+ /** A contributed route; explicit routes replace generated defaults with the same key. */
3
+ export interface RouteDefinition {
4
+ readonly key: RouteKey;
5
+ readonly handler: Handler;
6
+ readonly priority: 'explicit' | 'generated';
7
+ readonly source?: string;
8
+ readonly metadata?: Readonly<Record<string, unknown>>;
9
+ /** Override application CORS, or false when the route owner supplies its own policy. */
10
+ readonly cors?: CorsConfig | false;
11
+ }
12
+ /** Registered in setup, materialized exactly once after every plugin has prepared. */
13
+ export interface RouteSource {
14
+ readonly owner: string;
15
+ readonly order: number;
16
+ materialize(): readonly RouteDefinition[];
17
+ }
18
+ /** Frozen resolved route metadata exposed after HTTP activation. Exact paths match first;
19
+ * parameterized ties follow source composition order, then source declaration order. */
20
+ export interface ResolvedRoute extends RouteDefinition {
21
+ readonly owner: string;
22
+ readonly method: Method;
23
+ readonly path: string;
24
+ }
25
+ /** Final outcome, including transport effects which cannot be represented by Fetch responses. */
26
+ export type HttpOutcome = {
27
+ readonly kind: 'response';
28
+ readonly response: Response;
29
+ } | {
30
+ readonly kind: 'terminate';
31
+ readonly reason: string;
32
+ };
33
+ /** One final observation per request, after decoration and HEAD body suppression. */
34
+ export interface HttpObservation {
35
+ readonly request: MockRequest;
36
+ readonly outcome: HttpOutcome;
37
+ readonly durationMs: number;
38
+ readonly error?: unknown;
39
+ }
40
+ /** Fixed pipeline phase with explicit composition order, independent of dependency sorting. */
41
+ export type HttpMiddleware = {
42
+ readonly owner: string;
43
+ readonly order: number;
44
+ } & ({
45
+ readonly stage: 'preflight' | 'validation' | 'interception';
46
+ readonly handle: (request: MockRequest) => MockResponse | void | Promise<MockResponse | void>;
47
+ } | {
48
+ readonly stage: 'decoration';
49
+ readonly handle: (request: MockRequest, response: MockResponse) => MockResponse | void | Promise<MockResponse | void>;
50
+ } | {
51
+ readonly stage: 'error';
52
+ readonly handle: (request: MockRequest, error: unknown) => MockResponse | void | Promise<MockResponse | void>;
53
+ } | {
54
+ readonly stage: 'observation';
55
+ readonly handle: (observation: HttpObservation) => void | Promise<void>;
56
+ });
57
+ /** Listener bind intent passed to every guard before any socket opens. */
58
+ export interface HttpBind {
59
+ readonly host: string;
60
+ readonly port: number;
61
+ }
62
+ /** Feature-owned policy registered before HTTP registration is sealed. */
63
+ export interface BindGuard {
64
+ readonly owner: string;
65
+ check(bind: HttpBind): void | Promise<void>;
66
+ }
67
+ /** HTTP registration, resolved catalog, request dispatch, and pre-bind policy contract. */
68
+ export interface HttpRuntime {
69
+ /** Shared logical/transport shutdown policy; deadline uses performance.now(). */
70
+ readonly drainTimeoutMs: number;
71
+ readonly drainDeadline: number | undefined;
72
+ registerRoutes(source: RouteSource): void;
73
+ registerMiddleware(middleware: HttpMiddleware): void;
74
+ registerBindGuard(guard: BindGuard): void;
75
+ readonly routes: readonly ResolvedRoute[];
76
+ /** Resolve with dispatch precedence, including HEAD fallback; available after activation. */
77
+ resolveRoute(method: string, path: string): ResolvedRoute | undefined;
78
+ checkBind(bind: HttpBind): Promise<void>;
79
+ dispatch(request: Request): Promise<HttpOutcome>;
80
+ fetch(request: Request): Promise<Response>;
81
+ }
82
+ export declare const httpCapability: import("@databehave/core").Capability<HttpRuntime>;
83
+ /** A terminal transport effect; the pipeline observes it without running response decorators. */
84
+ export declare class HttpTransportTermination extends Error {
85
+ constructor(message?: string);
86
+ }
87
+ /** Fetch has no socket to terminate; callers receive this explicit unsupported-effect error. */
88
+ export declare class UnsupportedTransportError extends Error {
89
+ readonly reason: string;
90
+ constructor(reason: string);
91
+ }
92
+ /** Terminate the actual HTTP connection when invoked by a handler or middleware. */
93
+ export declare const terminateTransport: (reason?: string) => never;
94
+ //# sourceMappingURL=http.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"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"}
package/dist/http.js ADDED
@@ -0,0 +1,23 @@
1
+ import { capability } from '@databehave/core';
2
+ export const httpCapability = capability('databehave.http', 1);
3
+ /** A terminal transport effect; the pipeline observes it without running response decorators. */
4
+ export class HttpTransportTermination extends Error {
5
+ constructor(message = 'Connection terminated by HTTP policy') {
6
+ super(message);
7
+ this.name = 'HttpTransportTermination';
8
+ }
9
+ }
10
+ /** Fetch has no socket to terminate; callers receive this explicit unsupported-effect error. */
11
+ export class UnsupportedTransportError extends Error {
12
+ reason;
13
+ constructor(reason) {
14
+ super(`Transport termination is unsupported by fetch: ${reason}`);
15
+ this.reason = reason;
16
+ this.name = 'UnsupportedTransportError';
17
+ }
18
+ }
19
+ /** Terminate the actual HTTP connection when invoked by a handler or middleware. */
20
+ export const terminateTransport = (reason) => {
21
+ throw new HttpTransportTermination(reason);
22
+ };
23
+ //# sourceMappingURL=http.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAiF7C,MAAM,CAAC,MAAM,cAAc,GAAG,UAAU,CAAc,iBAAiB,EAAE,CAAC,CAAC,CAAA;AAE3E,iGAAiG;AACjG,MAAM,OAAO,wBAAyB,SAAQ,KAAK;IACjD,YAAY,OAAO,GAAG,sCAAsC;QAC1D,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,0BAA0B,CAAA;IACxC,CAAC;CACF;AAED,gGAAgG;AAChG,MAAM,OAAO,yBAA0B,SAAQ,KAAK;IAC7B;IAArB,YAAqB,MAAc;QACjC,KAAK,CAAC,kDAAkD,MAAM,EAAE,CAAC,CAAA;QAD9C,WAAM,GAAN,MAAM,CAAQ;QAEjC,IAAI,CAAC,IAAI,GAAG,2BAA2B,CAAA;IACzC,CAAC;CACF;AAED,oFAAoF;AACpF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,MAAe,EAAS,EAAE;IAC3D,MAAM,IAAI,wBAAwB,CAAC,MAAM,CAAC,CAAA;AAC5C,CAAC,CAAA"}
package/dist/index.d.ts CHANGED
@@ -1,21 +1,11 @@
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';
1
+ /** Public HTTP contracts and optional HTTP plugins. Feature packages depend on this boundary. */
2
+ export { httpPlugin, type HttpOptions } from './server.js';
3
+ export { httpCapability, terminateTransport, HttpTransportTermination, UnsupportedTransportError, type HttpRuntime, type HttpMiddleware, type HttpOutcome, type HttpObservation, type HttpBind, type BindGuard, type RouteDefinition, type RouteSource, type ResolvedRoute, } from './http.js';
4
+ export { nodeHttpPlugin, listenerCapability, type HttpListener, type NodeHttpOptions } from './node-http.js';
5
+ export { routesPlugin } from './plugins/routes.js';
6
+ export { corsPlugin } from './plugins/cors.js';
7
+ export { accessLogPlugin, type AccessLogOptions } from './plugins/access-log.js';
8
+ export { parseRouteKey, parseRoutePattern, matchPattern, type RoutePattern, type PatternSegment, type ParsedRouteKey } from './route-key.js';
9
+ export type { LogFormatOptions } from './log.js';
10
+ export type { Handler, Method, MockRequest, MockResponse, MockResponseBody, ObservedMethod, RouteKey, CorsConfig } from './types.js';
21
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iGAAiG;AACjG,OAAO,EAAE,UAAU,EAAE,KAAK,WAAW,EAAE,MAAM,aAAa,CAAA;AAC1D,OAAO,EACL,cAAc,EAAE,kBAAkB,EAAE,wBAAwB,EAAE,yBAAyB,EACvF,KAAK,WAAW,EAAE,KAAK,cAAc,EAAE,KAAK,WAAW,EAAE,KAAK,eAAe,EAC7E,KAAK,QAAQ,EAAE,KAAK,SAAS,EAAE,KAAK,eAAe,EAAE,KAAK,WAAW,EAAE,KAAK,aAAa,GAC1F,MAAM,WAAW,CAAA;AAClB,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,KAAK,YAAY,EAAE,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAC5G,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAC9C,OAAO,EAAE,eAAe,EAAE,KAAK,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAChF,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,YAAY,EAAE,KAAK,YAAY,EAAE,KAAK,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAC5I,YAAY,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AAChD,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA"}
package/dist/index.js CHANGED
@@ -1,19 +1,9 @@
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';
1
+ /** Public HTTP contracts and optional HTTP plugins. Feature packages depend on this boundary. */
2
+ export { httpPlugin } from './server.js';
3
+ export { httpCapability, terminateTransport, HttpTransportTermination, UnsupportedTransportError, } from './http.js';
4
+ export { nodeHttpPlugin, listenerCapability } from './node-http.js';
5
+ export { routesPlugin } from './plugins/routes.js';
6
+ export { corsPlugin } from './plugins/cors.js';
7
+ export { accessLogPlugin } from './plugins/access-log.js';
8
+ export { parseRouteKey, parseRoutePattern, matchPattern } from './route-key.js';
19
9
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iGAAiG;AACjG,OAAO,EAAE,UAAU,EAAoB,MAAM,aAAa,CAAA;AAC1D,OAAO,EACL,cAAc,EAAE,kBAAkB,EAAE,wBAAwB,EAAE,yBAAyB,GAGxF,MAAM,WAAW,CAAA;AAClB,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAA2C,MAAM,gBAAgB,CAAA;AAC5G,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAC9C,OAAO,EAAE,eAAe,EAAyB,MAAM,yBAAyB,CAAA;AAChF,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,YAAY,EAA+D,MAAM,gBAAgB,CAAA"}
package/dist/log.d.ts CHANGED
@@ -1,57 +1,17 @@
1
- /**
2
- * Opt-in per-request access logger.
3
- *
4
- * One line per request, written to **stdout**. Default off — when the
5
- * top-level `log` config is absent or `false`, no logger is built and
6
- * the request hot path is untouched.
7
- *
8
- * Format `pretty` (default) — ANSI-coloured one-liner like:
9
- *
10
- * GET /api/v1/health → 200 4 ms · 56
11
- *
12
- * Format `json` — newline-terminated JSON object suitable for piping
13
- * into structured log collectors:
14
- *
15
- * {"t":"2026-05-28T…","method":"GET","path":"/api/v1/health","status":200,"ms":4,"bytes":56}
16
- *
17
- * Sticky / header overrides synthesised by the admin inject hook are
18
- * marked with ` [override:<mode.kind>]` (pretty) or `"override":"<kind>"` (json).
19
- *
20
- * Admin-panel traffic is suppressed by default — set `includeAdmin: true`
21
- * to log it too. The hot-path check is a single `startsWith` against the
22
- * resolved admin base path.
23
- */
24
- import type { LogConfig } from './types.js';
25
- export interface ResolvedLogConfig {
26
- readonly access: boolean;
27
- readonly includeAdmin: boolean;
28
- readonly colors: boolean;
29
- readonly format: 'pretty' | 'json';
30
- }
1
+ /** One access event, already reduced to fields intended for logging. */
31
2
  export interface LogEvent {
32
3
  readonly method: string;
33
4
  readonly path: string;
34
- readonly status: number;
5
+ readonly status: number | 'terminated';
35
6
  readonly ms: number;
36
7
  readonly bytes: string;
37
- readonly override: string | undefined;
38
- readonly error: string | undefined;
8
+ readonly error?: string;
39
9
  }
40
- export interface AccessLogger {
41
- readonly emit: (ev: LogEvent) => void;
42
- readonly isAdminPath: (path: string) => boolean;
10
+ /** Access formatter configuration, independent of request filtering and output. */
11
+ export interface LogFormatOptions {
12
+ readonly format?: 'pretty' | 'json';
13
+ readonly colors?: 'auto' | 'always' | 'never';
43
14
  }
44
- /**
45
- * Resolve a user-supplied `log` config into a normalised shape, or
46
- * `null` when logging is disabled. Pure — safe to call at construction.
47
- */
48
- export declare const resolveLogConfig: (cfg: LogConfig | undefined) => ResolvedLogConfig | null;
49
- /**
50
- * Build an access logger bound to the resolved config + admin path.
51
- * `adminPath` is the resolved `admin.path` (e.g. `/mock`), or
52
- * `undefined` when admin mode is off. Returns `null` when logging is
53
- * disabled — callers should short-circuit on `null` to avoid any
54
- * per-request allocation.
55
- */
56
- export declare const createAccessLogger: (cfg: LogConfig | undefined, adminPath: string | undefined) => AccessLogger | null;
15
+ /** Format one newline-terminated event without reading or consuming a response body. */
16
+ export declare const formatAccessLog: (event: LogEvent, options: LogFormatOptions) => string;
57
17
  //# sourceMappingURL=log.d.ts.map
package/dist/log.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../src/log.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAE3C,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;IACxB,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAA;IAC9B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;IACxB,QAAQ,CAAC,MAAM,EAAE,QAAQ,GAAG,MAAM,CAAA;CACnC;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAA;IACrC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAA;CACnC;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,QAAQ,KAAK,IAAI,CAAA;IACrC,QAAQ,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAA;CAChD;AAgCD;;;GAGG;AACH,eAAO,MAAM,gBAAgB,GAC3B,KAAK,SAAS,GAAG,SAAS,KACzB,iBAAiB,GAAG,IAkBtB,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,GAC7B,KAAK,SAAS,GAAG,SAAS,EAC1B,WAAW,MAAM,GAAG,SAAS,KAC5B,YAAY,GAAG,IA0CjB,CAAA"}
1
+ {"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../src/log.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,CAAA;IACtC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CACxB;AAED,mFAAmF;AACnF,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAA;IACnC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAA;CAC9C;AAcD,wFAAwF;AACxF,eAAO,MAAM,eAAe,GAAI,OAAO,QAAQ,EAAE,SAAS,gBAAgB,KAAG,MAQ5E,CAAA"}