@databehave/server 0.1.1 → 0.1.2

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/docs/errors.md DELETED
@@ -1,192 +0,0 @@
1
- # Error catalogue
2
-
3
- Every user-visible error `@databehave/server` raises, grouped by
4
- phase and module. Source citations are `file:line` relative to
5
- `packages/server/`. The kit follows a **fail-loud** policy: shape
6
- violations are caught at boot, not first request.
7
-
8
- For symptom-driven guidance see [troubleshooting.md](./troubleshooting.md).
9
- For the auto-schema install-hint walkthrough see
10
- [openapi/auto-schema.md#missing-install-error](./openapi/auto-schema.md#missing-install-error).
11
-
12
- ## 1. JSONC config errors (`src/json-config.ts`)
13
-
14
- Every entry below throws synchronously from
15
- `loadConfig` and surfaces as a boot-time error.
16
-
17
- | Message (verbatim, prefixed `@databehave/server/config:`) | When | Source |
18
- | --- | --- | --- |
19
- | `JSON root must be an object` | Top-level value of the file is not a JSON object. | `src/json-config.ts:441` |
20
- | `"openapi" must be a string path` | `openapi:` not a string. | `src/json-config.ts:447` |
21
- | `"server" must be an object` | `server:` not a plain object. | `src/json-config.ts:453` |
22
- | `"basePath" must be a string` | `basePath:` not a string. | `src/json-config.ts:459` |
23
- | `"basePath" must start with "/"` | First char of `basePath` is not `/`. | `src/json-config.ts:462` |
24
- | `"basePath" must not end with "/"` | Trailing `/` on `basePath`. | `src/json-config.ts:465` |
25
- | `"cors" must be an object` | `cors:` not a plain object. | `src/json-config.ts:471` |
26
- | `"mockMode" must be an object` | `mockMode:` not a plain object. | `src/json-config.ts:477` |
27
- | `"endpoints" must be an object` | `endpoints:` not a plain object. | `src/json-config.ts:531` |
28
- | `"admin" must be an object` | `admin:` not a plain object. | `src/json-config.ts:541` |
29
- | `"log" must be a boolean or an object` | Wrong type for `log:`. | `src/json-config.ts:552` |
30
- | `"validation" must be an object` | `validation:` not a plain object. | `src/json-config.ts:560` |
31
- | `endpoints["KEY"] must be a string or object` | Endpoint value is neither shorthand path nor `{ handler / response }`. | `src/json-config.ts:314` |
32
- | `endpoints["KEY"] cannot have both "handler" and "response"` | Mutually exclusive shapes. | `src/json-config.ts:398` |
33
- | `endpoints["KEY"] must have either "handler" or "response"` | Empty object value. | `src/json-config.ts:405` |
34
- | `endpoints["KEY"].handler must be a string` | `handler` not a module path. | `src/json-config.ts:410` |
35
- | `endpoints["KEY"].status must be a number` | Bad per-endpoint status. | `src/json-config.ts:416` |
36
- | `endpoints["KEY"].status cannot be combined with "response" (put status inside response)` | `status` next to `response` instead of inside it. | `src/json-config.ts:422` |
37
- | `endpoints["KEY"].response must be an object` | `response` not an object. | `src/json-config.ts:353` |
38
- | `endpoints["KEY"].response.status must be a number` | `response.status` missing or not numeric. | `src/json-config.ts:358` |
39
- | `endpoints["KEY"].response.empty must be a boolean` | `response.empty` not boolean. | `src/json-config.ts:366` |
40
- | `endpoints["KEY"].response.headers must be an object` | `response.headers` not a plain object. | `src/json-config.ts:374` |
41
- | `endpoints["KEY"].response.headers["H"] must be a string` | Non-string header value. | `src/json-config.ts:381` |
42
- | `endpoints keys "A" and "B" both resolve to "C" after applying basePath` | Two endpoint keys collapse to the same `METHOD path` once `basePath` is prefixed. | `src/json-config.ts:683` |
43
- | `MODULE (mapped to KEY) has no default-exported handler function` | Handler module did not `export default` a function. | `src/json-config.ts:314` |
44
- | `handlers override for "MODULE" (mapped to KEY) is not a function (got TYPE)` | `LoadConfigOptions.handlers` value not callable. | `src/json-config.ts:297` |
45
- | `endpoints["KEY"]` validation chain (32 sub-errors) | Aggregated via `AggregateError` so a multi-broken config surfaces every gap at once. | `src/json-config.ts:432`, `src/json-config.ts:715-735` |
46
-
47
- ## 2. OpenAPI loader / walker errors
48
-
49
- | Message (verbatim) | When | Source |
50
- | --- | --- | --- |
51
- | `JSON-only spec loader. Convert YAML first: yq -o=json <file>.yaml > <file>.json` | `openapi:` points at `*.yaml` / `*.yml`. | `src/openapi/loader.ts:25` |
52
- | `@databehave/server/openapi: failed to parse JSON OpenAPI document at PATH: <native message>` | `JSON.parse` failed on the OAS bytes (after BOM strip). | `src/openapi/loader.ts:34` |
53
- | `@databehave/server/openapi: unsupported $ref: <ref>` | Remote `$ref` (`http://…` / `https://…`) or a `$ref` not pointing under `#/components/schemas/`. | `src/openapi/generate.ts:50` |
54
- | `@databehave/server/openapi: $ref not found: <ref>` | Intra-document `$ref` whose target does not exist. | `src/openapi/generate.ts:55` |
55
- | Generator: walker reached unsupported node type | Walker encountered a JSON-Schema construct without a fallback. | `src/openapi/generate.ts:44`, `:116` |
56
-
57
- Walker errors do not always abort boot — when `onOpenApiWalkError` /
58
- `onOpenApiEmptySchema` is configured the walker substitutes a stub
59
- body (`{}` for GET, `{ "success": true, "message": null }` for
60
- mutations) and emits a logged warning instead. See
61
- [openapi/fallback.md#walker-failures](./openapi/fallback.md).
62
-
63
- ## 3. Auto-schema errors (`src/openapi/auto-schema.ts`)
64
-
65
- | Message (verbatim, prefixed `@databehave/server/config:`) | When | Source |
66
- | --- | --- | --- |
67
- | `"schema" must be an object like \{ "enabled": true \}; the boolean shorthand was removed (got VALUE)` | `schema:` set to the removed boolean form (`true` / `false`). | `src/openapi/auto-schema.ts` |
68
- | `"schema" must be an object like \{ "enabled": true \} (got TYPE)` | `schema:` set to a non-object value (and not the removed boolean shorthand). | `src/openapi/auto-schema.ts` |
69
- | `"schema.enabled" must be a boolean (got VALUE)` | `schema:` is an object but `enabled` is missing or not boolean. | `src/openapi/auto-schema.ts` |
70
- | `unknown key in "schema": "K" (valid keys: enabled, seed, locale, arrayCount)` | Unknown sub-key. | `src/openapi/auto-schema.ts` |
71
- | `"schema.seed" must be a number, "stable", or "random" (got VALUE)` | Bad `seed` value. | `src/openapi/auto-schema.ts` |
72
- | `"schema.locale" must be a string` | Non-string `locale`. | `src/openapi/auto-schema.ts` |
73
- | `"schema.arrayCount" must be a non-negative number` | Negative or non-finite `arrayCount`. | `src/openapi/auto-schema.ts` |
74
-
75
- ### Missing install error (`INSTALL_HINT`)
76
-
77
- When `schema.enabled === true` but `@databehave/schema` cannot be
78
- resolved the server suppresses the native `Cannot find module`
79
- text and throws this verbatim template (no `cause` chain — by
80
- design):
81
-
82
- ```text
83
- [@databehave/server] Auto-schema mode is enabled in databehave.jsonc
84
- ("schema": { "enabled": true } is set), but the data-generation engine is not installed.
85
-
86
- npm i @databehave/schema
87
- # or: pnpm add @databehave/schema
88
- # or: yarn add @databehave/schema
89
-
90
- This enables realistic, seeded mock data derived from your OpenAPI
91
- document. See: https://github.com/ochairo/databehave/blob/main/packages/server/docs/openapi/auto-schema.md#missing-install-error
92
-
93
- To keep the default zero-dep placeholder mode instead, set
94
- "schema": { "enabled": false } or remove the "schema" field from databehave.jsonc.
95
- ```
96
-
97
- Source: `src/openapi/auto-schema.ts` (`INSTALL_HINT` constant) and
98
- `loadSchemaModule` (throw site).
99
-
100
- ## 4. Validator build-time errors (`src/validation/validate.ts`)
101
-
102
- The validator FAILS LOUD at server-start on any unsupported
103
- JSON-Schema keyword — there is no silent passthrough. The same
104
- keyword set is rejected by the auto-schema translator
105
- (`src/openapi/translate.ts`).
106
-
107
- Rejected keywords: `if`, `then`, `else`, `dependentSchemas`,
108
- `dependentRequired`, `unevaluatedProperties`, `unevaluatedItems`,
109
- `contentEncoding`, `contentMediaType`, `propertyNames`,
110
- `patternProperties`. Remote `$ref` is also rejected.
111
-
112
- Pattern length is capped at **1024 characters** (ReDoS guard);
113
- recursion depth at **64 levels** (`$ref` cycles, deeply-nested
114
- schemas). Both caps surface as build-time errors prefixed
115
- `@databehave/server/validation:` and pointing at the offending
116
- JSON-Pointer.
117
-
118
- ## 5. Runtime errors
119
-
120
- | Message (verbatim) | When | Source |
121
- | --- | --- | --- |
122
- | `@databehave/server: invalid route key (missing space): "KEY"` | Route key without the `METHOD path` space separator. | `src/route-key.ts:52` |
123
- | `@databehave/server: invalid route key …` (unsupported method, bad path, etc.) | Five further per-shape rejections. | `src/route-key.ts:56,64,71,97,100` |
124
- | `@databehave/server: empty param name in path "PATH"` | `:` followed by no name. | `src/route-key.ts:97` |
125
- | `@databehave/server: duplicate route declared: KEY` | Two route entries collide post-`basePath`. | `src/server.ts:136` |
126
- | `@databehave/server: admin is enabled and server.host=… — set admin.bind: "any" to confirm this is intentional, or bind to loopback (127.0.0.1, ::1, localhost). See README "Admin mode".` | Admin mode + non-loopback `host`. | `src/server.ts:511` |
127
- | `@databehave/server: invalid scenario name: "NAME"` | Scenario name fails `^[A-Za-z0-9_-]{1,64}$`. | `src/admin/scenarios-store.ts:97` |
128
- | `admin.path` must start with `/` | Bad admin path. | `src/admin/admin-routes.ts:318` |
129
- | MockResponse shape violation | Handler returned a body that violates the discriminated-union (`json` / `text` / `html` / `raw` / `empty` — exactly one). | `src/response.ts:33` |
130
- | Admin route collision with user route | A hand-written `endpoints` key collides with the admin sub-tree at `${admin.path}`. | `src/server.ts:289` |
131
- | Validation rejection (`application/problem+json`) | See section 6. | `src/middleware/request-validation.ts` |
132
-
133
- ### `x-mock-*` header parser errors
134
-
135
- All raise `400 Bad Request` with a JSON envelope of shape
136
- `{ "error": "...", "detail": "..." }`. Verbatim error wording
137
- ships from `src/admin/header-parser.ts:44,53,64,77,97,110`.
138
-
139
- | Trigger | Resulting shape |
140
- | --- | --- |
141
- | Invalid base64 in `x-mock-business-failure-b64` / `x-mock-business-failure-extra` | `400 { error, detail }` |
142
- | Invalid JSON in `x-mock-business-failure-extra` | `400 { error, detail }` |
143
- | `x-mock-status` not a 200–600 integer | `400 { error, detail }` |
144
- | Conflicting terminal headers (e.g. `x-mock-status` + `x-mock-empty`) | `400 { error, detail }` |
145
- | `x-mock-delay-then` set to `delay` / `hang` / `destroy` | `400 { error, detail }` |
146
- | `x-mock-business-failure-extra` decoded to a non-object | `400 { error, detail }` |
147
-
148
- Reference: [admin/headers.md](./admin/headers.md),
149
- [admin/error-mode.md](./admin/error-mode.md).
150
-
151
- ## 6. Validation runtime rejections (RFC 7807)
152
-
153
- When `validation.request: true` is set, off-contract requests are
154
- rejected with `application/problem+json`. Status mapping:
155
-
156
- | Status | Cause |
157
- | --- | --- |
158
- | `400` | Malformed JSON body (parse failure). |
159
- | `401` | Required security scheme not satisfied (`http`, `apiKey`, `oauth2`, `openIdConnect`). Includes a `WWW-Authenticate` challenge header. |
160
- | `413` | Request body exceeds `validation.maxBodyBytes` (default `102400`). |
161
- | `415` | Request body content-type is not declared by the spec for this route (when the route is JSON-only). |
162
- | `422` | Schema violation. Body includes a `violations: Violation[]` array, each entry `{ path, keyword, message }` keyed by JSON-Pointer. |
163
-
164
- Source: `src/middleware/request-validation.ts:24-50` (status
165
- mapping), `:42-46` (default `maxBodyBytes`), `:300-450` (dispatch).
166
- Full surface: [config/validation.md](./config/validation.md).
167
-
168
- ## 7. CLI errors (`src/bin.ts`, `src/bin-helpers.ts`)
169
-
170
- | Output | Exit | When |
171
- | --- | --- | --- |
172
- | `[@databehave/server] unknown option(s): <flag>` (then `HELP_TEXT` to stderr) | `2` | Any flag other than `--open` / `-h` / `--help`. |
173
- | `HELP_TEXT` to stderr (no error line) | `2` | Missing positional `<config>`. |
174
- | `[@databehave/server] failed to start <error>` | `1` | Bootstrap exception (config load, listen failure, etc.). |
175
- | `[@databehave/server] failed to close <error>` | `1` | `RunHandle.close()` rejected during shutdown. |
176
- | `[@databehave/server] shutting down (SIGINT|SIGTERM)` (info) | `0` | Graceful shutdown. |
177
-
178
- `HELP_TEXT` source: `src/bin-helpers.ts:18-23`. Reference:
179
- [cli.md](./cli.md).
180
-
181
- ## 8. Admin destroy signal (internal)
182
-
183
- `AdminDestroySocketSignal` is thrown when a request bearing the
184
- `x-mock-destroy` header — and `admin.allowDestroy === true` —
185
- reaches `fetch()` outside `listen()`. Inside `listen()` the signal
186
- is caught by the Node http adapter, which destroys the underlying
187
- socket without writing a response. Outside `listen()` (i.e. tests
188
- calling `server.fetch(req)` directly) the signal escapes by design
189
- so the test can assert on it.
190
-
191
- Source: `src/admin/admin-types.ts:23-28`,
192
- `src/server.ts:565-572`.
@@ -1,146 +0,0 @@
1
- # Getting started
2
-
3
- > If you have an OpenAPI document and want a mock server in 5
4
- > minutes, you're in the right place.
5
-
6
- This is the tutorial. For exhaustive option tables see
7
- [config/](./config/index.md); for the CLI reference see
8
- [cli.md](./cli.md); for the admin UI see
9
- [admin/](./admin/index.md).
10
-
11
- ## Install
12
-
13
- ```sh
14
- npm install @databehave/schema @databehave/server
15
- # or: pnpm add @databehave/schema @databehave/server
16
- # or: yarn add @databehave/schema @databehave/server
17
- ```
18
-
19
- `@databehave/schema` is an optional peer — only required if you want
20
- [auto-schema mode](./openapi/auto-schema.md). The server itself
21
- keeps `dependencies: {}` and `peerDependencies: {}` (zero-dep
22
- invariant).
23
-
24
- ## Step 1 — Write a minimal `databehave.jsonc`
25
-
26
- Drop this next to your OpenAPI document. Both paths are resolved
27
- relative to the directory of the config file.
28
-
29
- ```jsonc
30
- {
31
- // Optional — but required if you want OAS-fallback responses or
32
- // auto-schema mode. JSON only; convert YAML up-front
33
- // (e.g. `yq -o=json openapi.yaml > openapi.json`).
34
- "openapi": "./openapi.json",
35
-
36
- // Optional — defaults to `127.0.0.1:3000`.
37
- "server": { "host": "127.0.0.1", "port": 8000 },
38
-
39
- // Required (may be empty). Routes you declare here always win
40
- // over any OAS fallback.
41
- "endpoints": {}
42
- }
43
- ```
44
-
45
- JSONC features supported: `// line` comments, `/* block */`
46
- comments, trailing commas, and `${VAR}` / `${VAR:default}` env
47
- interpolation in any string value. Full grammar:
48
- [config/index.md#file-format](./config/index.md#file-format).
49
-
50
- ## Step 2 — Run
51
-
52
- ```sh
53
- npx @databehave/server databehave.jsonc
54
- ```
55
-
56
- The positional `<config>` is required — there is no implicit default
57
- path. On boot the CLI prints:
58
-
59
- ```txt
60
- [@databehave/server] listening on http://127.0.0.1:8000
61
- ```
62
-
63
- `SIGINT` / `SIGTERM` shut down cleanly with exit code `0`. Boot
64
- errors exit `1`; bad usage exits `2`. See [cli.md](./cli.md) for
65
- all flags and exit codes.
66
-
67
- ## Step 3 — Hit an endpoint
68
-
69
- For any path declared in your OAS document the server returns a
70
- deterministic stub body derived from the response schema. Stubs are
71
- `{}` for `GET` and `{ "success": true, "message": null }` for
72
- mutations when no schema is available; otherwise the body comes
73
- from the OAS-only generator (or the auto-schema engine, if enabled).
74
-
75
- ```sh
76
- curl -i http://127.0.0.1:8000/anything-in-your-spec
77
- ```
78
-
79
- Behaviour, status-pick rules, and the walker stub policy are
80
- documented in [openapi/fallback.md](./openapi/fallback.md).
81
-
82
- ## Step 4 — Declare a custom route
83
-
84
- When you need exact control of a response, list it under
85
- `endpoints`. The shorthand `{ status, json }` form is enough for
86
- static bodies — no handler module required:
87
-
88
- ```jsonc
89
- {
90
- "openapi": "./openapi.json",
91
- "endpoints": {
92
- "GET /health": { "response": { "status": 200, "json": { "ok": true } } },
93
- "POST /widgets": "./src/routes/widgets/create.js"
94
- }
95
- }
96
- ```
97
-
98
- Hand-written `endpoints` always win over any OAS fallback or
99
- auto-schema route at the same key. Full set of forms (string
100
- handler, `{ handler, status }`, `{ response }`):
101
- [config/endpoints.md](./config/endpoints.md).
102
-
103
- ## Step 5 — Enable auto-schema mode
104
-
105
- If you want realistic, seeded mock data instead of the structurally
106
- deterministic OAS-only stubs, opt in by adding a top-level `schema`
107
- field. This requires `@databehave/schema` (already installed in
108
- Step 1):
109
-
110
- ```jsonc
111
- {
112
- "openapi": "./openapi.json",
113
- "schema": { "enabled": true }, // "enabled" gates auto-mode; defaults equivalent to { "seed": "stable" }
114
- "endpoints": {}
115
- }
116
- ```
117
-
118
- Long form, with knobs:
119
-
120
- ```jsonc
121
- "schema": {
122
- "enabled": true,
123
- "seed": 42, // number | "stable" | "random" — default "stable"
124
- "locale": "ja", // forwarded to the engine as a future hint
125
- "arrayCount": 20 // default array length when OAS lacks minItems
126
- }
127
- ```
128
-
129
- If the peer is missing the server fails fast at startup with a
130
- friendly install hint — never lazily on first request. Full
131
- walkthrough: [openapi/auto-schema.md](./openapi/auto-schema.md).
132
- The exact install-hint text and every other user-visible error
133
- live in [errors.md](./errors.md).
134
-
135
- ## Where to next
136
-
137
- | You want to … | Read |
138
- | --- | --- |
139
- | Override responses without code (UI + REST) | [admin/](./admin/index.md) |
140
- | Inject errors via `x-mock-*` request headers | [admin/headers.md](./admin/headers.md) |
141
- | Save and reload override sets | [admin/scenarios.md](./admin/scenarios.md) |
142
- | Validate inbound requests against the OAS | [config/validation.md](./config/validation.md) |
143
- | See every JSONC field | [config/](./config/index.md) |
144
- | Diagnose an unexpected error | [errors.md](./errors.md) + [troubleshooting.md](./troubleshooting.md) |
145
- | Use the kit programmatically (`createServer`, `run`) | [recipes.md](./recipes.md) |
146
- | Understand the dispatch pipeline | [design.md](./design.md) |
package/docs/index.md DELETED
@@ -1,23 +0,0 @@
1
- # `@databehave/server` documentation
2
-
3
- Reading order by audience:
4
-
5
- **Start here**
6
-
7
- - [getting-started.md](./getting-started.md) — 5-step tutorial from `npm install` to a custom route.
8
- - [troubleshooting.md](./troubleshooting.md) — symptom → cause → fix.
9
-
10
- **Reference**
11
-
12
- - [config/](./config/index.md) — every JSONC field.
13
- - [config/validation.md](./config/validation.md) — opt-in inbound request validation (RFC 7807).
14
- - [admin/](./admin/index.md) — admin panel, REST API, `x-mock-*` headers.
15
- - [openapi/](./openapi/fallback.md) — OAS fallback, auto-schema mode, keyword parity.
16
- - [cli.md](./cli.md) — `@databehave/server` CLI.
17
- - [errors.md](./errors.md) — every user-visible error message, source-cited.
18
-
19
- **Deeper**
20
-
21
- - [design.md](./design.md) — architecture, dispatch pipeline, why the HTTP framework is hidden.
22
- - [stability.md](./stability.md) — public-surface lock, SemVer triggers, contract surfaces.
23
- - [recipes.md](./recipes.md) — error injection, static responses, programmatic hooks, in-process tests.
@@ -1,146 +0,0 @@
1
- # Auto-schema mode
2
-
3
- > "I have an OpenAPI document. I want realistic, deterministic
4
- > mock data. I don't want to write any TS schemas or handlers."
5
-
6
- Set the top-level `schema:` field in `databehave.jsonc` and every
7
- endpoint absent from `endpoints` is served from data generated by
8
- `@databehave/schema`'s `mock()` engine — derived directly from your
9
- OpenAPI document.
10
-
11
- **Minimal:**
12
-
13
- ```jsonc
14
- {
15
- "openapi": "./openapi.json",
16
- "schema": { "enabled": true }, // "enabled" gates auto-mode; defaults equivalent to { "seed": "stable" }
17
- "endpoints": {}
18
- }
19
- ```
20
-
21
- **With knobs:**
22
-
23
- ```jsonc
24
- {
25
- "openapi": "./openapi.json",
26
- "schema": {
27
- "enabled": true,
28
- "seed": 42, // number = fixed; "stable" = derive from endpoint|query|params; "random" = fresh per request; default "stable"
29
- "locale": "ja",
30
- "arrayCount": 20 // default array length when the OAS lacks minItems
31
- }
32
- }
33
- ```
34
-
35
- ## Architecture
36
-
37
- The server walks your OAS, translates each response schema to a
38
- `@databehave/schema` IR via `translateOasToIR` (in-server, ~150 LoC,
39
- zero-dep), then calls `mock(ir, { seed })` per request. The
40
- `@databehave/schema` package is loaded **only** via
41
- `await import('@databehave/schema')` when `schema:` is set — the
42
- server itself keeps `dependencies: {}` and `peerDependencies: {}`.
43
-
44
- The IR is **pre-translated** at server-creation time. Every
45
- response schema in the OAS doc is walked once during boot; per-
46
- request work is just `mock(ir, { seed })`. This catches translator
47
- errors loudly at startup (`@databehave/server: translateOasToIR
48
- failed for GET /widgets responses[200]: <reason>`) instead of
49
- serving 500s on the first hit.
50
-
51
- Translator scope:
52
-
53
- - Only the `200` (or smallest declared `2xx`) JSON response is
54
- translated for each endpoint. Other statuses fall back to the
55
- zero-dep generator and the per-status body table from
56
- [fallback.md](./fallback.md#per-status-body-generators).
57
- - `204` responses are skipped entirely — no body, no IR.
58
-
59
- ## Stable seed derivation
60
-
61
- `seed: "stable"` (the default) computes a per-request 32-bit FNV-1a
62
- hash so identical requests produce byte-identical responses across
63
- restarts and across machines:
64
-
65
- ```text
66
- input = `${METHOD} ${endpointPath}|${sortedQuery}|${sortedPathParams}`
67
- seed = fnv1a32(input)
68
- ```
69
-
70
- - `endpointPath` is the OAS pattern (e.g. `/users/:id`), not the
71
- resolved live URL — `/users/1` and `/users/2` therefore generate
72
- different bodies, while `/users/1` always generates the same one.
73
- - `sortedQuery` is the query string with keys sorted lexically, so
74
- `?a=1&b=2` and `?b=2&a=1` collide on purpose.
75
- - `sortedPathParams` is the matched path-param map serialised the
76
- same way.
77
-
78
- Snapshot tests built on top of auto-schema mode rely on this exact
79
- input — change the URL or the param shape and the body changes.
80
-
81
- `seed: <number>` skips the derivation and feeds the literal value to
82
- `mock()`; every request to the same endpoint returns the same body.
83
- `seed: "random"` calls `Math.random()` per request so bodies vary —
84
- useful for load tests, useless for snapshots.
85
-
86
- ## Locale (forwarded, currently no-op)
87
-
88
- The `locale` field is parsed and forwarded into the per-request call
89
- to `mock()`, but `@databehave/schema`'s zero-dep mock engine does
90
- not currently consume it — output is locale-agnostic regardless of
91
- the value. The field is kept so a future `@databehave/schema`
92
- release can pick it up without changing this server's API surface.
93
- For locale-tied corpora today, generate fixtures up-front via
94
- `@databehave/schema` and serve them from `endpoints` with
95
- `response.json`.
96
-
97
- ## Install path
98
-
99
- Auto-schema mode requires the optional peer:
100
-
101
- ```sh
102
- npm i @databehave/server @databehave/schema
103
- # or: pnpm add @databehave/server @databehave/schema
104
- # or: yarn add @databehave/server @databehave/schema
105
- ```
106
-
107
- ## Missing-install error
108
-
109
- If `schema:` is set but `@databehave/schema` is not installed,
110
- server-creation fails fast at startup with a friendly multi-line
111
- install hint. The native `Cannot find module` error from the
112
- underlying `await import(...)` is suppressed (no `cause` chain) and
113
- replaced verbatim with:
114
-
115
- ```text
116
- [@databehave/server] Auto-schema mode is enabled in databehave.jsonc
117
- ("schema": { "enabled": true } is set), but the data-generation engine is not installed.
118
-
119
- npm i @databehave/schema
120
- # or: pnpm add @databehave/schema
121
- # or: yarn add @databehave/schema
122
-
123
- This enables realistic, seeded mock data derived from your OpenAPI
124
- document. See: https://github.com/ochairo/databehave/blob/main/packages/server/docs/openapi/auto-schema.md#missing-install-error
125
-
126
- To keep the default zero-dep placeholder mode instead, set
127
- "schema": { "enabled": false } or remove the "schema" field from databehave.jsonc.
128
- ```
129
-
130
- ## Precedence
131
-
132
- Hand-written `endpoints` always override auto-mode for the same
133
- route — auto-mode only fills paths absent from your `endpoints` map.
134
-
135
- ## Default behaviour
136
-
137
- Omit the `schema:` field and the server keeps its existing zero-dep
138
- placeholder generator (deterministic structural values like
139
- `"string"`, `0`, `false`). Activating auto-mode is opt-in.
140
-
141
- ## Richer fixtures
142
-
143
- For richer DSL features (custom distributions, FK-aware datasets,
144
- locale-tied corpora) see the
145
- [`@databehave/schema`](https://github.com/ochairo/databehave/tree/main/packages/schema)
146
- README.