@databehave/server 0.1.3 → 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
@@ -1,472 +0,0 @@
1
- /**
2
- * Admin REST + UI routes. Mounted under a configurable `basePath`
3
- * (default `/databehave`).
4
- *
5
- * GET {basePath} — admin HTML page (UI shell)
6
- * GET {basePath}/ — same (trailing-slash equivalent)
7
- * GET {basePath}/ui.js — admin UI script bundle
8
- * GET {basePath}/ui.css — admin UI stylesheet
9
- * GET {basePath}/openapi-routes — `{method, path, summary}[]`
10
- * GET {basePath}/openapi.json — raw OpenAPI document (404 when not configured)
11
- * GET {basePath}/overrides — list active sticky overrides
12
- * POST {basePath}/overrides — add a sticky override (201)
13
- * DELETE {basePath}/overrides — clear all
14
- * DELETE {basePath}/overrides/:id — remove by id (404 if missing)
15
- * GET {basePath}/scenarios — list saved scenarios
16
- * POST {basePath}/scenarios — save current overrides as a scenario
17
- * GET {basePath}/scenarios/:name — fetch a saved scenario
18
- * DELETE {basePath}/scenarios/:name — delete a saved scenario
19
- * POST {basePath}/scenarios/:name/load — replace active overrides with the scenario
20
- *
21
- * CORS for these routes is controlled by `admin.cors`; the kit's
22
- * server integration injects the resolved header bag here via
23
- * {@link AdminRoutesOptions.corsHeaders}.
24
- */
25
- import { readFile } from 'node:fs/promises';
26
- import { dirname, resolve } from 'node:path';
27
- import { fileURLToPath } from 'node:url';
28
- import { isValidScenarioName } from './scenarios-store.js';
29
- const HERE = dirname(fileURLToPath(import.meta.url));
30
- const UI_HTML_PATH = resolve(HERE, 'ui.html');
31
- const UI_JS_PATH = resolve(HERE, 'ui.js');
32
- const UI_CSS_PATH = resolve(HERE, 'ui.css');
33
- // Cached on first read — the admin bundle is static for the process lifetime.
34
- // HTML is cached per basePath because the served body is templated with the
35
- // base so the UI bundle and the asset <script>/<link> tags know where to
36
- // fetch from when the UI is mounted at a non-default path.
37
- const uiHtmlCacheByBase = new Map();
38
- let uiJsCache;
39
- let uiCssCache;
40
- /**
41
- * Inject the resolved `basePath` into the prebuilt UI shell HTML so
42
- * the `<script>` / `<link>` tags resolve correctly when the UI is
43
- * mounted at the bare base path (browsers resolve `./ui.js` against
44
- * the parent of the current URL, which is wrong when the URL has no
45
- * trailing slash) and so the UI bundle can read
46
- * `window.__DATABEHAVE_BASE__` to build its fetch URLs.
47
- */
48
- const templateHtml = (raw, basePath) => {
49
- const baseJson = JSON.stringify(basePath);
50
- return raw
51
- .replace(/src="\.\/ui\.js"/g, `src="${basePath}/ui.js"`)
52
- .replace(/href="\.\/ui\.css"/g, `href="${basePath}/ui.css"`)
53
- .replace(/<script type="module"/, `<script>window.__DATABEHAVE_BASE__=${baseJson};</script>\n <script type="module"`);
54
- };
55
- const isPlainObject = (v) => v !== null && typeof v === 'object' && !Array.isArray(v);
56
- const validateMode = (raw) => {
57
- if (!isPlainObject(raw) || typeof raw.kind !== 'string') {
58
- return [null, 'mode.kind must be a string'];
59
- }
60
- switch (raw.kind) {
61
- case 'http-status':
62
- if (typeof raw.status !== 'number')
63
- return [null, 'http-status.status must be number'];
64
- return [{ kind: 'http-status', status: raw.status }, null];
65
- case 'business-failure': {
66
- if (typeof raw.message !== 'string')
67
- return [null, 'business-failure.message must be string'];
68
- const mode = { kind: 'business-failure', message: raw.message };
69
- if (raw.extra !== undefined) {
70
- if (!isPlainObject(raw.extra))
71
- return [null, 'business-failure.extra must be a plain object'];
72
- mode.extra = raw.extra;
73
- }
74
- return [mode, null];
75
- }
76
- case 'custom-body': {
77
- if (!('body' in raw))
78
- return [null, 'custom-body.body is required'];
79
- const mode = { kind: 'custom-body', body: raw.body };
80
- if (raw.status !== undefined) {
81
- if (typeof raw.status !== 'number')
82
- return [null, 'custom-body.status must be number'];
83
- mode.status = raw.status;
84
- }
85
- if (raw.contentType !== undefined) {
86
- if (typeof raw.contentType !== 'string')
87
- return [null, 'custom-body.contentType must be string'];
88
- mode.contentType = raw.contentType;
89
- }
90
- return [mode, null];
91
- }
92
- case 'empty-body': {
93
- const mode = { kind: 'empty-body' };
94
- if (raw.status !== undefined) {
95
- if (typeof raw.status !== 'number')
96
- return [null, 'empty-body.status must be number'];
97
- mode.status = raw.status;
98
- }
99
- return [mode, null];
100
- }
101
- case 'malformed-json': {
102
- const mode = { kind: 'malformed-json' };
103
- if (raw.status !== undefined) {
104
- if (typeof raw.status !== 'number')
105
- return [null, 'malformed-json.status must be number'];
106
- mode.status = raw.status;
107
- }
108
- return [mode, null];
109
- }
110
- case 'delay': {
111
- if (typeof raw.ms !== 'number' || raw.ms < 0)
112
- return [null, 'delay.ms must be a non-negative number'];
113
- if (raw.then === undefined)
114
- return [{ kind: 'delay', ms: raw.ms }, null];
115
- const [inner, err] = validateMode(raw.then);
116
- if (err)
117
- return [null, `delay.then: ${err}`];
118
- if (inner.kind === 'delay' ||
119
- inner.kind === 'hang' ||
120
- inner.kind === 'destroy') {
121
- return [null, `delay.then cannot be ${inner.kind}`];
122
- }
123
- return [
124
- {
125
- kind: 'delay',
126
- ms: raw.ms,
127
- then: inner,
128
- },
129
- null,
130
- ];
131
- }
132
- case 'hang':
133
- return [{ kind: 'hang' }, null];
134
- case 'destroy':
135
- return [{ kind: 'destroy' }, null];
136
- default:
137
- return [null, `unknown mode.kind: ${String(raw.kind)}`];
138
- }
139
- };
140
- const validateMatcher = (raw) => {
141
- if (!isPlainObject(raw) || typeof raw.kind !== 'string') {
142
- return [null, 'matcher.kind must be a string'];
143
- }
144
- switch (raw.kind) {
145
- case 'exact':
146
- if (typeof raw.method !== 'string')
147
- return [null, 'matcher.method must be string'];
148
- if (typeof raw.path !== 'string' || !raw.path.startsWith('/'))
149
- return [null, 'matcher.path must start with "/"'];
150
- return [{ kind: 'exact', method: raw.method, path: raw.path }, null];
151
- case 'path':
152
- if (typeof raw.path !== 'string' || !raw.path.startsWith('/'))
153
- return [null, 'matcher.path must start with "/"'];
154
- return [{ kind: 'path', path: raw.path }, null];
155
- case 'global': {
156
- if (raw.methods === undefined)
157
- return [{ kind: 'global' }, null];
158
- if (!Array.isArray(raw.methods))
159
- return [null, 'matcher.methods must be an array of strings'];
160
- const methods = [];
161
- for (const m of raw.methods) {
162
- if (typeof m !== 'string')
163
- return [null, 'matcher.methods must be an array of strings'];
164
- const trimmed = m.trim();
165
- if (trimmed.length === 0)
166
- return [null, 'matcher.methods entries must be non-empty'];
167
- methods.push(trimmed.toUpperCase());
168
- }
169
- if (methods.length === 0)
170
- return [{ kind: 'global' }, null];
171
- return [{ kind: 'global', methods }, null];
172
- }
173
- default:
174
- return [null, `unknown matcher.kind: ${String(raw.kind)}`];
175
- }
176
- };
177
- const buildAdminRoutesList = (openapiBody, handlerRoutes, basePath) => {
178
- const out = [];
179
- const seen = new Set();
180
- if (openapiBody !== undefined) {
181
- try {
182
- const doc = JSON.parse(openapiBody);
183
- const paths = doc.paths ?? {};
184
- for (const [p, ops] of Object.entries(paths)) {
185
- for (const method of [
186
- 'get',
187
- 'post',
188
- 'put',
189
- 'delete',
190
- 'patch',
191
- ]) {
192
- const op = ops[method];
193
- if (op !== undefined) {
194
- const upper = method.toUpperCase();
195
- seen.add(`${upper} ${p}`);
196
- out.push({
197
- method: upper,
198
- path: p,
199
- ...(typeof op.summary === 'string'
200
- ? { summary: op.summary }
201
- : {}),
202
- source: 'openapi',
203
- });
204
- }
205
- }
206
- }
207
- }
208
- catch {
209
- // ignore parse errors — UI will simply show an empty list.
210
- }
211
- }
212
- if (handlerRoutes) {
213
- for (const r of handlerRoutes) {
214
- const upper = r.method.toUpperCase();
215
- // Hide admin routes from the UI list — they would self-list otherwise.
216
- if (r.path === basePath || r.path.startsWith(`${basePath}/`))
217
- continue;
218
- const key = `${upper} ${r.path}`;
219
- if (seen.has(key))
220
- continue;
221
- seen.add(key);
222
- out.push({ method: upper, path: r.path, source: 'handler' });
223
- }
224
- }
225
- out.sort((a, b) => a.path === b.path
226
- ? a.method.localeCompare(b.method)
227
- : a.path.localeCompare(b.path));
228
- return { routes: out, discoveredAt: new Date().toISOString() };
229
- };
230
- export const createAdminRoutes = (opts) => {
231
- const { store, openapiBody } = opts;
232
- const basePath = opts.basePath ?? '/databehave';
233
- const ui = opts.ui !== false;
234
- const corsHeaders = opts.corsHeaders ?? {};
235
- const routesCache = buildAdminRoutesList(openapiBody, opts.handlerRoutes, basePath);
236
- if (!basePath.startsWith('/')) {
237
- throw new Error(`@databehave/server: admin.path must start with "/" (got ${JSON.stringify(basePath)})`);
238
- }
239
- const json = (status, body) => ({
240
- status,
241
- json: body,
242
- headers: { ...corsHeaders },
243
- });
244
- const uiHandler = async () => {
245
- try {
246
- let html = uiHtmlCacheByBase.get(basePath);
247
- if (html === undefined) {
248
- const raw = await readFile(UI_HTML_PATH, 'utf8');
249
- html = templateHtml(raw, basePath);
250
- uiHtmlCacheByBase.set(basePath, html);
251
- }
252
- return { status: 200, html, headers: { ...corsHeaders } };
253
- /* v8 ignore start -- ui.html ships with the package; missing only on a broken install */
254
- }
255
- catch (err) {
256
- return json(500, {
257
- error: 'failed to read ui.html',
258
- detail: err instanceof Error ? err.message : String(err),
259
- });
260
- }
261
- /* v8 ignore stop */
262
- };
263
- const uiJsHandler = async () => {
264
- try {
265
- if (uiJsCache === undefined) {
266
- uiJsCache = await readFile(UI_JS_PATH, 'utf8');
267
- }
268
- return {
269
- status: 200,
270
- text: uiJsCache,
271
- headers: {
272
- ...corsHeaders,
273
- 'Content-Type': 'application/javascript; charset=utf-8',
274
- },
275
- };
276
- /* v8 ignore start -- ui.js ships with the package; missing only on a broken install */
277
- }
278
- catch (err) {
279
- return json(500, {
280
- error: 'failed to read ui.js',
281
- detail: err instanceof Error ? err.message : String(err),
282
- });
283
- }
284
- /* v8 ignore stop */
285
- };
286
- const uiCssHandler = async () => {
287
- try {
288
- if (uiCssCache === undefined) {
289
- uiCssCache = await readFile(UI_CSS_PATH, 'utf8');
290
- }
291
- return {
292
- status: 200,
293
- text: uiCssCache,
294
- headers: {
295
- ...corsHeaders,
296
- 'Content-Type': 'text/css; charset=utf-8',
297
- },
298
- };
299
- /* v8 ignore start -- ui.css ships with the package; missing only on a broken install */
300
- }
301
- catch (err) {
302
- return json(500, {
303
- error: 'failed to read ui.css',
304
- detail: err instanceof Error ? err.message : String(err),
305
- });
306
- }
307
- /* v8 ignore stop */
308
- };
309
- const listRoutesHandler = () => json(200, routesCache);
310
- const openApiDocHandler = () => {
311
- if (openapiBody === undefined) {
312
- return json(404, { error: 'no openapi document configured' });
313
- }
314
- return {
315
- status: 200,
316
- text: openapiBody,
317
- headers: {
318
- ...corsHeaders,
319
- 'Content-Type': 'application/json',
320
- 'Cache-Control': 'no-store',
321
- },
322
- };
323
- };
324
- const listOverridesHandler = () => json(200, { overrides: store.list() });
325
- const addOverrideHandler = async (req) => {
326
- let body;
327
- try {
328
- body = await req.json();
329
- }
330
- catch (err) {
331
- return json(400, {
332
- error: 'invalid JSON body',
333
- detail: err instanceof Error ? err.message : String(err),
334
- });
335
- }
336
- if (!isPlainObject(body))
337
- return json(400, { error: 'body must be a JSON object' });
338
- const [matcher, mErr] = validateMatcher(body.matcher);
339
- if (mErr)
340
- return json(400, { error: `matcher invalid: ${mErr}` });
341
- const [mode, modeErr] = validateMode(body.mode);
342
- if (modeErr)
343
- return json(400, { error: `mode invalid: ${modeErr}` });
344
- const description = typeof body.description === 'string' ? body.description : undefined;
345
- const override = store.add({
346
- matcher: matcher,
347
- mode: mode,
348
- ...(description !== undefined ? { description } : {}),
349
- });
350
- return {
351
- status: 201,
352
- json: { id: override.id, override },
353
- headers: { ...corsHeaders },
354
- };
355
- };
356
- const removeByIdHandler = (req) => {
357
- const id = req.params.id;
358
- if (!id)
359
- return json(400, { error: 'missing :id' });
360
- const ok = store.remove(id);
361
- if (!ok)
362
- return json(404, { error: 'override not found', id });
363
- return json(200, { deleted: true, id });
364
- };
365
- const clearAllHandler = () => {
366
- const n = store.clear();
367
- return json(200, { cleared: n });
368
- };
369
- const routes = {
370
- [`GET ${basePath}/openapi-routes`]: listRoutesHandler,
371
- [`GET ${basePath}/openapi.json`]: openApiDocHandler,
372
- [`GET ${basePath}/overrides`]: listOverridesHandler,
373
- [`POST ${basePath}/overrides`]: addOverrideHandler,
374
- [`DELETE ${basePath}/overrides`]: clearAllHandler,
375
- [`DELETE ${basePath}/overrides/:id`]: removeByIdHandler,
376
- };
377
- if (ui) {
378
- // Serve the HTML shell at the bare base path AND its trailing-slash
379
- // variant so both `/databehave` and `/databehave/` work in a browser.
380
- routes[`GET ${basePath}`] = uiHandler;
381
- if (!basePath.endsWith('/')) {
382
- routes[`GET ${basePath}/`] = uiHandler;
383
- }
384
- routes[`GET ${basePath}/ui.js`] = uiJsHandler;
385
- routes[`GET ${basePath}/ui.css`] = uiCssHandler;
386
- }
387
- // Scenarios (file-backed snapshots of override sets). Mounted only
388
- // when a scenarios store is provided — pure REST CRUD plus a
389
- // `:name/load` action that atomically replaces the active overrides.
390
- const scenarios = opts.scenarios;
391
- if (scenarios) {
392
- const listScenariosHandler = async () => json(200, { scenarios: await scenarios.list() });
393
- const getScenarioHandler = async (req) => {
394
- const name = req.params.name ?? '';
395
- if (!isValidScenarioName(name))
396
- return json(400, { error: 'invalid scenario name' });
397
- const s = await scenarios.get(name);
398
- if (!s)
399
- return json(404, { error: 'scenario not found', name });
400
- return json(200, s);
401
- };
402
- const createScenarioHandler = async (req) => {
403
- let body;
404
- try {
405
- body = await req.json();
406
- }
407
- catch (err) {
408
- return json(400, {
409
- error: 'invalid JSON body',
410
- detail: err instanceof Error ? err.message : String(err),
411
- });
412
- }
413
- if (!isPlainObject(body))
414
- return json(400, { error: 'body must be a JSON object' });
415
- const name = typeof body.name === 'string' ? body.name : '';
416
- if (!isValidScenarioName(name))
417
- return json(400, {
418
- error: 'invalid scenario name (only [A-Za-z0-9_-], max 64 chars)',
419
- });
420
- const explicit = body.overrides;
421
- const overrides = Array.isArray(explicit)
422
- ? explicit
423
- : store.list();
424
- const saved = await scenarios.save(name, overrides);
425
- return {
426
- status: 201,
427
- json: saved,
428
- headers: { ...corsHeaders },
429
- };
430
- };
431
- const deleteScenarioHandler = async (req) => {
432
- const name = req.params.name ?? '';
433
- if (!isValidScenarioName(name))
434
- return json(400, { error: 'invalid scenario name' });
435
- const ok = await scenarios.remove(name);
436
- if (!ok)
437
- return json(404, { error: 'scenario not found', name });
438
- return json(200, { deleted: true, name });
439
- };
440
- const loadScenarioHandler = async (req) => {
441
- const name = req.params.name ?? '';
442
- if (!isValidScenarioName(name))
443
- return json(400, { error: 'invalid scenario name' });
444
- const s = await scenarios.get(name);
445
- if (!s)
446
- return json(404, { error: 'scenario not found', name });
447
- store.clear();
448
- const loaded = [];
449
- for (const o of s.overrides) {
450
- const added = store.add({
451
- matcher: o.matcher,
452
- mode: o.mode,
453
- ...(o.description !== undefined
454
- ? { description: o.description }
455
- : {}),
456
- });
457
- loaded.push(added.id);
458
- }
459
- return json(200, { loaded: loaded.length, name });
460
- };
461
- routes[`GET ${basePath}/scenarios`] =
462
- listScenariosHandler;
463
- routes[`GET ${basePath}/scenarios/:name`] =
464
- getScenarioHandler;
465
- routes[`POST ${basePath}/scenarios`] =
466
- createScenarioHandler;
467
- routes[`DELETE ${basePath}/scenarios/:name`] = deleteScenarioHandler;
468
- routes[`POST ${basePath}/scenarios/:name/load`] = loadScenarioHandler;
469
- }
470
- return routes;
471
- };
472
- //# sourceMappingURL=admin-routes.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"admin-routes.js","sourceRoot":"","sources":["../../src/admin/admin-routes.ts"],"names":[],"mappings":"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"}
@@ -1,170 +0,0 @@
1
- /**
2
- * Admin-mode types & internal sentinel.
3
- *
4
- * `admin` is an opt-in extension of `Config` that
5
- * mounts an in-memory error-injection panel + `x-mock-*` headers
6
- * under a configurable mount path (default `/databehave`). See
7
- * {@link AdminModeConfig} on `Config.admin`.
8
- */
9
- /**
10
- * Internal symbol attached to the response object returned by
11
- * {@link createInjectHook} when an `x-mock-destroy` is honored. The
12
- * kit's `server.listen()` http adapter recognizes this property and
13
- * drops the underlying socket without writing a response. Hidden
14
- * from {@link MockResponse} on purpose — destroy is not a
15
- * normal HTTP response shape.
16
- */
17
- export declare const DESTROY_SOCKET_SENTINEL: unique symbol;
18
- export type DestroySocketSentinel = typeof DESTROY_SOCKET_SENTINEL;
19
- /**
20
- * Thrown internally by `server.fetch` when the admin inject hook
21
- * surfaced a {@link DESTROY_SOCKET_SENTINEL} response. `server.listen()`
22
- * catches it and destroys the socket; callers of `server.fetch()`
23
- * outside a listening server will observe the throw.
24
- */
25
- export declare class AdminDestroySocketSignal extends Error {
26
- readonly name = "AdminDestroySocketSignal";
27
- constructor();
28
- }
29
- /**
30
- * Discriminated union of every error mode the admin layer can inject.
31
- * 1. `http-status` — non-2xx → typical HTTP error
32
- * 2. `business-failure` — 2xx + `{success:false, message}`
33
- * 3. `custom-body` — arbitrary status + arbitrary JSON / text
34
- * 4. `empty-body` — empty body
35
- * 5. `malformed-json` — body is literally `{` so JSON.parse blows up
36
- * 6. `delay` — sleep `ms` then either run `then` or pass through
37
- * 7. `hang` — never resolve (FE timeout / hang detection)
38
- * 8. `destroy` — drop the socket without a response
39
- */
40
- export type ErrorMode = {
41
- kind: 'http-status';
42
- status: number;
43
- } | {
44
- kind: 'business-failure';
45
- message: string;
46
- extra?: Record<string, unknown>;
47
- } | {
48
- kind: 'custom-body';
49
- status?: number;
50
- body: unknown;
51
- contentType?: string;
52
- } | {
53
- kind: 'empty-body';
54
- status?: number;
55
- } | {
56
- kind: 'malformed-json';
57
- status?: number;
58
- } | {
59
- kind: 'delay';
60
- ms: number;
61
- then?: Exclude<ErrorMode, {
62
- kind: 'delay';
63
- } | {
64
- kind: 'hang';
65
- } | {
66
- kind: 'destroy';
67
- }>;
68
- } | {
69
- kind: 'hang';
70
- } | {
71
- kind: 'destroy';
72
- };
73
- /**
74
- * Resolution priority (handled by `OverridesStore.resolve`):
75
- * 1. `exact` (METHOD + path)
76
- * 2. `path` (path only, any method)
77
- * 3. `global` (every route)
78
- */
79
- export type OverrideMatcher = {
80
- kind: 'exact';
81
- method: string;
82
- path: string;
83
- } | {
84
- kind: 'path';
85
- path: string;
86
- } | {
87
- kind: 'global';
88
- methods?: readonly string[];
89
- };
90
- /** Alias kept for parity with the legacy reference; prefer {@link OverrideMatcher}. */
91
- export type StickyMatcher = OverrideMatcher;
92
- export interface StickyOverride {
93
- readonly id: string;
94
- readonly matcher: OverrideMatcher;
95
- readonly mode: ErrorMode;
96
- readonly createdAt: string;
97
- readonly description?: string;
98
- }
99
- /**
100
- * Admin-mode CORS policy.
101
- *
102
- * - `'auto'` — `'*'` when bind is loopback-only, `'same-origin'`
103
- * when `bind === 'any'` (defensive default for
104
- * LAN-exposed servers).
105
- * - `'any'` — `Access-Control-Allow-Origin: *`.
106
- * - `'same-origin'` — no CORS headers added; browser enforces same-origin.
107
- * - `{ origin }` — explicit allowlist (string | string[]).
108
- */
109
- export type AdminModeCors = 'auto' | 'any' | 'same-origin' | {
110
- origin: string | readonly string[];
111
- };
112
- /** Opt-in admin-mode configuration. All fields optional. */
113
- export interface AdminModeConfig {
114
- /** Opt-in. Default: false. */
115
- enabled?: boolean;
116
- /** Mount point for admin routes. Default: '/databehave'. Must start with '/'. */
117
- path?: string;
118
- /** Serve the admin HTML page at `${path}` itself. Default: true when enabled. */
119
- ui?: boolean;
120
- /** Honor `x-mock-*` request headers. Default: true when enabled. */
121
- headers?: boolean;
122
- /**
123
- * Bind policy. 'loopback-only' (default) refuses to enable admin when
124
- * server.host resolves to a non-loopback address. 'any' allows it.
125
- */
126
- bind?: 'loopback-only' | 'any';
127
- /** Admin-route CORS — see {@link AdminModeCors}. Default: 'auto'. */
128
- cors?: AdminModeCors;
129
- /** Allow `x-mock-destroy: 1` and the equivalent sticky. Default: true. */
130
- allowDestroy?: boolean;
131
- /**
132
- * When `true`, the kit spawns the platform browser opener on the
133
- * resolved admin URL after `server.listen()` emits `listening`.
134
- * Default: `false` — the URL is logged to stdout (see the
135
- * `admin panel ready at …` banner) but no browser is launched.
136
- * Opt-in only; consumers who prefer to click the logged link, or
137
- * who run the kit in headless / CI environments, should leave this
138
- * unset. The CLI's `--open` flag is ORed with this field, so either
139
- * trigger launches the browser exactly once.
140
- */
141
- openBrowserOnStart?: boolean;
142
- /**
143
- * Optional raw OpenAPI document body (JSON text) used to populate
144
- * the route picker in the UI. The CLI fills this in from the
145
- * config's `openapi` field; programmatic consumers can pass it
146
- * directly.
147
- */
148
- openapiBody?: string;
149
- /**
150
- * Directory used to persist named scenarios (snapshots of the
151
- * current sticky overrides set). Default:
152
- * `<process.cwd()>/mock-scenarios`. The directory is created on
153
- * first write; a missing directory is treated as "no scenarios"
154
- * rather than an error.
155
- */
156
- scenariosDir?: string;
157
- }
158
- /** A persisted scenario — a named bundle of sticky overrides. */
159
- export interface Scenario {
160
- readonly name: string;
161
- readonly overrides: readonly StickyOverride[];
162
- readonly created?: string;
163
- }
164
- /** Lightweight scenario summary returned by the list endpoint. */
165
- export interface ScenarioSummary {
166
- readonly name: string;
167
- readonly count: number;
168
- readonly created: string;
169
- }
170
- //# sourceMappingURL=admin-types.d.ts.map