@databehave/openapi 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/LICENSE +21 -0
  3. package/README.md +93 -2
  4. package/dist/catalog.d.ts +51 -0
  5. package/dist/catalog.d.ts.map +1 -0
  6. package/dist/catalog.js +90 -0
  7. package/dist/catalog.js.map +1 -0
  8. package/dist/index.d.ts +11 -0
  9. package/dist/index.d.ts.map +1 -0
  10. package/dist/index.js +9 -0
  11. package/dist/index.js.map +1 -0
  12. package/dist/middleware/request-validation.d.ts +65 -0
  13. package/dist/middleware/request-validation.d.ts.map +1 -0
  14. package/dist/middleware/request-validation.js +353 -0
  15. package/dist/middleware/request-validation.js.map +1 -0
  16. package/dist/mock-mode-plugin.d.ts +5 -0
  17. package/dist/mock-mode-plugin.d.ts.map +1 -0
  18. package/dist/mock-mode-plugin.js +20 -0
  19. package/dist/mock-mode-plugin.js.map +1 -0
  20. package/dist/mock-mode.d.ts +76 -0
  21. package/dist/mock-mode.d.ts.map +1 -0
  22. package/dist/mock-mode.js +93 -0
  23. package/dist/mock-mode.js.map +1 -0
  24. package/dist/openapi/auto-schema.d.ts +3 -0
  25. package/dist/openapi/auto-schema.d.ts.map +1 -0
  26. package/dist/openapi/auto-schema.js +10 -0
  27. package/dist/openapi/auto-schema.js.map +1 -0
  28. package/dist/openapi/generate.d.ts +8 -0
  29. package/dist/openapi/generate.d.ts.map +1 -0
  30. package/dist/openapi/generate.js +121 -0
  31. package/dist/openapi/generate.js.map +1 -0
  32. package/dist/openapi/loader.d.ts +18 -0
  33. package/dist/openapi/loader.d.ts.map +1 -0
  34. package/dist/openapi/loader.js +32 -0
  35. package/dist/openapi/loader.js.map +1 -0
  36. package/dist/openapi/seed.d.ts +17 -0
  37. package/dist/openapi/seed.d.ts.map +1 -0
  38. package/dist/openapi/seed.js +58 -0
  39. package/dist/openapi/seed.js.map +1 -0
  40. package/dist/openapi/translate.d.ts +14 -0
  41. package/dist/openapi/translate.d.ts.map +1 -0
  42. package/dist/openapi/translate.js +312 -0
  43. package/dist/openapi/translate.js.map +1 -0
  44. package/dist/openapi/walker.d.ts +37 -0
  45. package/dist/openapi/walker.d.ts.map +1 -0
  46. package/dist/openapi/walker.js +2 -0
  47. package/dist/openapi/walker.js.map +1 -0
  48. package/dist/placeholder.d.ts +7 -0
  49. package/dist/placeholder.d.ts.map +1 -0
  50. package/dist/placeholder.js +17 -0
  51. package/dist/placeholder.js.map +1 -0
  52. package/dist/plugin.d.ts +10 -0
  53. package/dist/plugin.d.ts.map +1 -0
  54. package/dist/plugin.js +43 -0
  55. package/dist/plugin.js.map +1 -0
  56. package/dist/request-validation-plugin.d.ts +8 -0
  57. package/dist/request-validation-plugin.d.ts.map +1 -0
  58. package/dist/request-validation-plugin.js +24 -0
  59. package/dist/request-validation-plugin.js.map +1 -0
  60. package/dist/schema.d.ts +18 -0
  61. package/dist/schema.d.ts.map +1 -0
  62. package/dist/schema.js +26 -0
  63. package/dist/schema.js.map +1 -0
  64. package/dist/validation/validate.d.ts +40 -0
  65. package/dist/validation/validate.d.ts.map +1 -0
  66. package/dist/validation/validate.js +378 -0
  67. package/dist/validation/validate.js.map +1 -0
  68. package/package.json +55 -3
@@ -0,0 +1,353 @@
1
+ import { matchPattern, parseRoutePattern } from '@databehave/server';
2
+ import { compileValidator } from '../validation/validate.js';
3
+ const PROBLEM_TYPE_BASE = 'https://github.com/ochairo/databehave/blob/main/docs/errors';
4
+ const PROBLEM_TYPE_SLUG = {
5
+ 400: 'malformed-body',
6
+ 401: 'unauthorized',
7
+ 413: 'payload-too-large',
8
+ 415: 'unsupported-media-type',
9
+ 422: 'request-validation',
10
+ };
11
+ const problemType = (status) => `${PROBLEM_TYPE_BASE}/${PROBLEM_TYPE_SLUG[status] ?? 'request-validation'}.md`;
12
+ // Default cap on request-body size (bytes). Matches the express
13
+ // `body-parser` default; raise via `validation.maxBodyBytes` only if
14
+ // the spec genuinely demands large bodies.
15
+ const DEFAULT_MAX_BODY_BYTES = 102400;
16
+ const STATUS_TITLES = {
17
+ 400: 'Malformed request',
18
+ 401: 'Unauthorized',
19
+ 413: 'Payload too large',
20
+ 415: 'Unsupported media type',
21
+ 422: 'Request validation failed',
22
+ };
23
+ const isObj = (v) => typeof v === 'object' && v !== null && !Array.isArray(v);
24
+ const resolveParam = (raw, doc) => {
25
+ if (!isObj(raw))
26
+ return null;
27
+ let node = raw;
28
+ if (typeof node.$ref === 'string') {
29
+ const m = /^#\/components\/parameters\/(.+)$/.exec(node.$ref);
30
+ if (!m)
31
+ return null;
32
+ const docAny = doc;
33
+ const target = docAny.components?.parameters?.[decodeURIComponent(m[1])];
34
+ if (!isObj(target))
35
+ return null;
36
+ node = target;
37
+ }
38
+ const location = node.in;
39
+ if ((location !== 'query' && location !== 'path' && location !== 'header' && location !== 'cookie') || typeof node.name !== 'string')
40
+ return null;
41
+ return {
42
+ in: location, name: node.name,
43
+ ...(typeof node.required === 'boolean' ? { required: node.required } : {}),
44
+ ...(isObj(node.schema) ? { schema: node.schema } : {}),
45
+ };
46
+ };
47
+ export const createRequestValidationContext = (catalog, options = {}) => {
48
+ const maxBodyBytes = options.maxBodyBytes ?? DEFAULT_MAX_BODY_BYTES;
49
+ if (!Number.isSafeInteger(maxBodyBytes) || maxBodyBytes < 0) {
50
+ throw new Error('maxBodyBytes must be a nonnegative safe integer');
51
+ }
52
+ const doc = catalog.document;
53
+ const schemes = new Map();
54
+ for (const [name, scheme] of Object.entries(doc.components?.securitySchemes ?? {})) {
55
+ if (isObj(scheme) && typeof scheme.type === 'string') {
56
+ schemes.set(name, scheme);
57
+ }
58
+ }
59
+ const globalSecurity = doc.security ?? [];
60
+ const routes = [];
61
+ for (const operation of catalog.operations) {
62
+ const oasPath = operation.sourcePath;
63
+ const methodName = operation.method;
64
+ const pattern = parseRoutePattern(operation.path);
65
+ const pathLevelParams = operation.pathParameters;
66
+ const op = operation.definition;
67
+ const opNode = op;
68
+ const params = [];
69
+ const rawParams = [...pathLevelParams, ...(opNode.parameters ?? [])];
70
+ for (const raw of rawParams) {
71
+ const p = resolveParam(raw, doc);
72
+ if (!p || p.in === 'cookie')
73
+ continue;
74
+ const schema = (p.schema ?? {});
75
+ const validator = compileValidator(schema, doc, `#/paths/${oasPath}/${methodName}/parameters/${p.name}`);
76
+ params.push({
77
+ name: p.name,
78
+ in: p.in,
79
+ required: p.required === true || p.in === 'path',
80
+ type: typeof schema.type === 'string' ? schema.type : null,
81
+ validator,
82
+ });
83
+ }
84
+ const requestBody = opNode.requestBody;
85
+ const content = requestBody?.content;
86
+ const declaredTypes = content ? Object.keys(content) : [];
87
+ const hasJsonBody = declaredTypes.some((c) => /^application\/json(\b|;)/i.test(c));
88
+ const bodyOnlyJson = hasJsonBody &&
89
+ declaredTypes.every((c) => /^application\/json(\b|;)/i.test(c));
90
+ const jsonSchema = content?.['application/json']?.schema;
91
+ const bodyValidator = jsonSchema
92
+ ? compileValidator(jsonSchema, doc, `#/paths/${oasPath}/${methodName}/requestBody`)
93
+ : null;
94
+ routes.push({
95
+ key: operation.key,
96
+ pattern,
97
+ hasBody: requestBody !== undefined,
98
+ hasJsonBody,
99
+ bodyOnlyJson,
100
+ bodyRequired: requestBody?.required === true,
101
+ bodyValidator,
102
+ params,
103
+ security: opNode.security ?? globalSecurity,
104
+ });
105
+ }
106
+ return {
107
+ catalog,
108
+ routes,
109
+ schemes,
110
+ maxBodyBytes,
111
+ };
112
+ };
113
+ const coerce = (raw, type) => {
114
+ if (type === 'integer') {
115
+ if (!/^-?\d+$/.test(raw))
116
+ return raw;
117
+ const n = Number(raw);
118
+ return Number.isFinite(n) ? n : raw;
119
+ }
120
+ if (type === 'number') {
121
+ if (!/^-?\d+(?:\.\d+)?$/.test(raw))
122
+ return raw;
123
+ const n = Number(raw);
124
+ return Number.isFinite(n) ? n : raw;
125
+ }
126
+ if (type === 'boolean') {
127
+ if (raw === 'true')
128
+ return true;
129
+ if (raw === 'false')
130
+ return false;
131
+ return raw;
132
+ }
133
+ return raw;
134
+ };
135
+ const isSecuritySatisfied = (req, ctx, headers, url) => {
136
+ const names = Object.keys(req);
137
+ if (names.length === 0)
138
+ return true;
139
+ return names.every((name) => {
140
+ const scheme = ctx.schemes.get(name);
141
+ if (!scheme)
142
+ return false;
143
+ if (scheme.type === 'http') {
144
+ const auth = headers.get('authorization') ?? '';
145
+ const want = (scheme.scheme ?? 'bearer').toLowerCase();
146
+ return new RegExp(`^${want}\\s+`, 'i').test(auth);
147
+ }
148
+ if (scheme.type === 'apiKey') {
149
+ if (scheme.in === 'header' && scheme.name) {
150
+ return headers.has(scheme.name.toLowerCase());
151
+ }
152
+ if (scheme.in === 'query' && scheme.name) {
153
+ return url.searchParams.has(scheme.name);
154
+ }
155
+ return false;
156
+ }
157
+ // oauth2 / openIdConnect: presence-only check; full token validation
158
+ // (introspection, signature verification) is out of scope for a
159
+ // zero-dep walker. Consumers needing it should layer it via
160
+ // a separate HTTP preflight or validation plugin.
161
+ return headers.has('authorization');
162
+ });
163
+ };
164
+ const buildAuthChallenge = (reqs, ctx) => {
165
+ for (const r of reqs) {
166
+ for (const name of Object.keys(r)) {
167
+ const scheme = ctx.schemes.get(name);
168
+ if (scheme?.type === 'http') {
169
+ const s = (scheme.scheme ?? 'bearer').replace(/^./, (c) => c.toUpperCase());
170
+ return { 'www-authenticate': `${s} realm="api"` };
171
+ }
172
+ }
173
+ }
174
+ return { 'www-authenticate': 'Bearer realm="api"' };
175
+ };
176
+ const problem = (status, detail, violations = [], extraHeaders = {}) => {
177
+ const body = {
178
+ type: problemType(status),
179
+ title: STATUS_TITLES[status] ?? 'Request validation failed',
180
+ status,
181
+ detail,
182
+ };
183
+ if (violations.length > 0)
184
+ body.violations = violations;
185
+ return new Response(JSON.stringify(body), {
186
+ status,
187
+ headers: {
188
+ 'content-type': 'application/problem+json',
189
+ ...extraHeaders,
190
+ },
191
+ });
192
+ };
193
+ const readBody = async (req, maxBodyBytes) => {
194
+ let reader;
195
+ // Tee cancellation only reaches the source after both branches cancel. Neither
196
+ // promise can be awaited here: a user source may never settle its cancel hook.
197
+ const cancel = () => {
198
+ void reader?.cancel().catch(() => { });
199
+ void req.body?.cancel().catch(() => { });
200
+ };
201
+ let onAbort = () => { };
202
+ try {
203
+ if (req.signal.aborted)
204
+ throw new Error('request aborted');
205
+ reader = req.clone().body?.getReader();
206
+ if (!reader)
207
+ return { raw: '', bytes: 0 };
208
+ const aborted = new Promise((_, reject) => {
209
+ onAbort = () => reject(new Error('request aborted'));
210
+ req.signal.addEventListener('abort', onAbort, { once: true });
211
+ });
212
+ const decoder = new TextDecoder();
213
+ let bytes = 0;
214
+ let raw = '';
215
+ while (true) {
216
+ const chunk = await Promise.race([reader.read(), aborted]);
217
+ if (req.signal.aborted)
218
+ throw new Error('request aborted');
219
+ if (chunk.done)
220
+ return { raw: raw + decoder.decode(), bytes };
221
+ bytes += chunk.value.byteLength;
222
+ if (bytes > maxBodyBytes) {
223
+ cancel();
224
+ return { response: problem(413, `request body exceeds maxBodyBytes (${maxBodyBytes})`) };
225
+ }
226
+ raw += decoder.decode(chunk.value, { stream: true });
227
+ }
228
+ }
229
+ catch {
230
+ cancel();
231
+ return { response: problem(400, 'request body could not be read') };
232
+ }
233
+ finally {
234
+ req.signal.removeEventListener('abort', onAbort);
235
+ reader?.releaseLock();
236
+ }
237
+ };
238
+ export const validateRequest = async (req, ctx, effectiveMethod = req.method) => {
239
+ const url = new URL(req.url);
240
+ const method = effectiveMethod.toUpperCase();
241
+ const operation = ctx.catalog.find(method, url.pathname);
242
+ let matched = null;
243
+ for (const r of ctx.routes) {
244
+ if (r.key !== operation?.key)
245
+ continue;
246
+ const params = matchPattern(r.pattern, url.pathname);
247
+ if (params) {
248
+ matched = { route: r, params };
249
+ break;
250
+ }
251
+ }
252
+ // Unmatched paths fall through — they are either hand-written routes
253
+ // outside the OAS document or genuine 404s. Either way the validator
254
+ // has no contract to enforce.
255
+ if (!matched)
256
+ return null;
257
+ const { route, params } = matched;
258
+ const headers = new Map();
259
+ req.headers.forEach((v, k) => headers.set(k.toLowerCase(), v));
260
+ // 1) Security gate.
261
+ if (route.security.length > 0) {
262
+ const ok = route.security.some((sr) => isSecuritySatisfied(sr, ctx, headers, url));
263
+ if (!ok) {
264
+ return problem(401, 'missing or invalid credentials', [], buildAuthChallenge(route.security, ctx));
265
+ }
266
+ }
267
+ const hasBodyMethod = method !== 'GET' && method !== 'HEAD';
268
+ const contentType = (headers.get('content-type') ?? '').split(';')[0]?.trim().toLowerCase() ?? '';
269
+ // 2) Content-Type guard for routes that declare a JSON-only requestBody.
270
+ if (hasBodyMethod && route.bodyOnlyJson && contentType && contentType !== 'application/json') {
271
+ return problem(415, `unsupported media type '${contentType}' (expected application/json)`);
272
+ }
273
+ const violations = [];
274
+ // 3) Body parse + validate.
275
+ if (hasBodyMethod && route.hasBody) {
276
+ const body = await readBody(req, ctx.maxBodyBytes);
277
+ if ('response' in body)
278
+ return body.response;
279
+ const { raw } = body;
280
+ if (body.bytes === 0) {
281
+ if (route.bodyRequired) {
282
+ return problem(422, 'request body is required', [
283
+ { path: '/body', keyword: 'required', message: 'missing required body' },
284
+ ]);
285
+ }
286
+ }
287
+ else if (route.hasJsonBody && (!contentType || contentType === 'application/json')) {
288
+ let parsed;
289
+ try {
290
+ parsed = JSON.parse(raw);
291
+ }
292
+ catch {
293
+ return problem(400, 'malformed JSON body');
294
+ }
295
+ if (route.bodyValidator)
296
+ violations.push(...route.bodyValidator(parsed, '/body'));
297
+ }
298
+ }
299
+ // 4) Param validation (with type coercion for query/path/header).
300
+ for (const p of route.params) {
301
+ if (p.in === 'query') {
302
+ const raw = url.searchParams.get(p.name);
303
+ if (raw === null) {
304
+ if (p.required) {
305
+ violations.push({
306
+ path: `/query/${p.name}`,
307
+ keyword: 'required',
308
+ message: 'missing required query parameter',
309
+ });
310
+ }
311
+ continue;
312
+ }
313
+ violations.push(...p.validator(coerce(raw, p.type), `/query/${p.name}`));
314
+ }
315
+ else if (p.in === 'path') {
316
+ const raw = params[p.name];
317
+ // Defensive: `matchPattern` always populates every named path
318
+ // segment when the route matches, so a missing path param is
319
+ // unreachable in practice. Kept as a guard against future
320
+ // refactors that loosen the matcher contract.
321
+ /* c8 ignore start */
322
+ if (raw === undefined) {
323
+ violations.push({
324
+ path: `/path/${p.name}`,
325
+ keyword: 'required',
326
+ message: 'missing required path parameter',
327
+ });
328
+ continue;
329
+ }
330
+ /* c8 ignore stop */
331
+ violations.push(...p.validator(coerce(raw, p.type), `/path/${p.name}`));
332
+ }
333
+ else {
334
+ const raw = headers.get(p.name.toLowerCase());
335
+ if (raw === undefined) {
336
+ if (p.required) {
337
+ violations.push({
338
+ path: `/header/${p.name}`,
339
+ keyword: 'required',
340
+ message: 'missing required header',
341
+ });
342
+ }
343
+ continue;
344
+ }
345
+ violations.push(...p.validator(coerce(raw, p.type), `/header/${p.name}`));
346
+ }
347
+ }
348
+ if (violations.length > 0) {
349
+ return problem(422, `request validation failed (${violations.length} violation${violations.length === 1 ? '' : 's'})`, violations);
350
+ }
351
+ return null;
352
+ };
353
+ //# sourceMappingURL=request-validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-validation.js","sourceRoot":"","sources":["../../src/middleware/request-validation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { Plugin } from '@databehave/core';
2
+ import type { MockModeOptions } from './mock-mode.js';
3
+ export type { MockModeOptions } from './mock-mode.js';
4
+ export declare const mockModePlugin: (options?: MockModeOptions) => Plugin;
5
+ //# sourceMappingURL=mock-mode-plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mock-mode-plugin.d.ts","sourceRoot":"","sources":["../src/mock-mode-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAI9C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AACrD,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAErD,eAAO,MAAM,cAAc,GAAI,UAAS,eAAoB,KAAG,MAc7D,CAAA"}
@@ -0,0 +1,20 @@
1
+ import { httpCapability } from '@databehave/server';
2
+ import { openapiCapability } from './catalog.js';
3
+ import { buildMockModeHooks } from './mock-mode.js';
4
+ export const mockModePlugin = (options = {}) => ({
5
+ id: 'databehave.openapi.mock-mode', apiVersion: 1,
6
+ requires: [httpCapability, openapiCapability],
7
+ setup(ctx) {
8
+ const catalog = ctx.use(openapiCapability);
9
+ const runtime = ctx.use(httpCapability);
10
+ const hooks = buildMockModeHooks({ ...options, enabled: true }, (request, status) => {
11
+ const operation = catalog.find(request.effectiveMethod, request.path);
12
+ return operation ? catalog.body(operation, status, request) : undefined;
13
+ });
14
+ if (!hooks)
15
+ throw new Error('Mock mode configuration failed');
16
+ runtime.registerMiddleware({ owner: 'databehave.openapi.mock-mode', order: ctx.order, stage: 'interception', handle: hooks.onRequest });
17
+ runtime.registerMiddleware({ owner: 'databehave.openapi.mock-mode', order: ctx.order, stage: 'decoration', handle: hooks.onResponse });
18
+ },
19
+ });
20
+ //# sourceMappingURL=mock-mode-plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mock-mode-plugin.js","sourceRoot":"","sources":["../src/mock-mode-plugin.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAChD,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AAInD,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,UAA2B,EAAE,EAAU,EAAE,CAAC,CAAC;IACxE,EAAE,EAAE,8BAA8B,EAAE,UAAU,EAAE,CAAC;IACjD,QAAQ,EAAE,CAAC,cAAc,EAAE,iBAAiB,CAAC;IAC7C,KAAK,CAAC,GAAG;QACP,MAAM,OAAO,GAAG,GAAG,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAA;QAC1C,MAAM,OAAO,GAAG,GAAG,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;QACvC,MAAM,KAAK,GAAG,kBAAkB,CAAC,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAClF,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;YACrE,OAAO,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;QACzE,CAAC,CAAC,CAAA;QACF,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAA;QAC7D,OAAO,CAAC,kBAAkB,CAAC,EAAE,KAAK,EAAE,8BAA8B,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC,CAAA;QACvI,OAAO,CAAC,kBAAkB,CAAC,EAAE,KAAK,EAAE,8BAA8B,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC,CAAA;IACxI,CAAC;CACF,CAAC,CAAA"}
@@ -0,0 +1,76 @@
1
+ /** Explicit status selection and response tagging policy. */
2
+ import type { MockRequest, MockResponse } from '@databehave/server';
3
+ /** Optional generated body lookup for a selected route and status. */
4
+ export type BodyResolver = (request: MockRequest, status: number) => unknown | undefined;
5
+ /**
6
+ * Minimal logger interface (compatible with the host server's logger
7
+ * and with `console`). Only `warn` is required by mock-mode today; the
8
+ * shape is kept narrow so callers can pass an existing logger without
9
+ * adapter glue.
10
+ */
11
+ export interface MockModeLogger {
12
+ warn(message: string): void;
13
+ }
14
+ /** Status policy enabled by including the mock-mode plugin. */
15
+ export interface MockModeOptions {
16
+ /** MockResponse header that tags every response with the resolved status. */
17
+ header?: string;
18
+ /**
19
+ * When `true`, an incoming request may force the mocked status by
20
+ * sending the same header (default `x-mock-status: 500`). Disabled
21
+ * by default so production-style mock servers don't expose status
22
+ * injection to arbitrary clients. Resolution becomes:
23
+ * 1. request `header` value (when `allowHeaderOverride === true`)
24
+ * 2. `pathOverrides["<METHOD> <path>"]`
25
+ * 3. `pathOverrides["<path>"]`
26
+ * 4. `defaultStatus`
27
+ * 5. passthrough
28
+ */
29
+ allowHeaderOverride?: boolean;
30
+ /** Paths exempt from status injection (typically health probes). */
31
+ healthPaths?: readonly string[];
32
+ /**
33
+ * Status applied when no `pathOverrides` entry matches. Omit (or set
34
+ * `undefined`) for passthrough (real handler runs). Set to an error
35
+ * code (e.g. `500`) to force every route to that status by default.
36
+ */
37
+ defaultStatus?: number;
38
+ /**
39
+ * Per-route status overrides. Keys use one of:
40
+ * - `"<METHOD> <path>"` (e.g. `"GET /api/v1/x"`) — method-scoped
41
+ * - `"<path>"` (e.g. `"/api/v1/x"`) — any method
42
+ * Paths must be absolute (start with `/`). Values are HTTP status codes.
43
+ */
44
+ pathOverrides?: Record<string, number>;
45
+ /**
46
+ * Logger used for non-fatal diagnostics (e.g. out-of-range header
47
+ * overrides). Defaults to the global `console`. Pass the host
48
+ * application's logger to keep mock-server output in one place
49
+ * instead of leaking to stdout/stderr.
50
+ */
51
+ logger?: MockModeLogger;
52
+ }
53
+ /** Interception and decoration callbacks for the HTTP middleware stages. */
54
+ export interface MockModeHooks {
55
+ onRequest: (req: MockRequest) => MockResponse | undefined;
56
+ onResponse: (req: MockRequest, res: MockResponse) => MockResponse;
57
+ }
58
+ /**
59
+ * Resolve the status code for a request using only the supplied config.
60
+ * Returns `undefined` when the request should pass through.
61
+ * Exported for unit-testing; callers normally use `buildMockModeHooks`.
62
+ */
63
+ export declare const resolveStatus: (method: string, path: string, config: MockModeOptions) => number | undefined;
64
+ /**
65
+ * Build the onRequest / onResponse hook pair. Returns `undefined`
66
+ * when the feature is disabled (caller may skip wiring entirely).
67
+ *
68
+ * `bodyResolver` is optional. When provided, @databehave/server asks it for a
69
+ * body for the configured status (typically a generator backed by
70
+ * the OpenAPI `responses[N]` schema). When it returns `undefined`,
71
+ * the minimal envelope `{ error: true, status: N }` is used instead.
72
+ */
73
+ export declare const buildMockModeHooks: (config: MockModeOptions & {
74
+ readonly enabled?: boolean;
75
+ }, bodyResolver?: BodyResolver) => MockModeHooks | undefined;
76
+ //# sourceMappingURL=mock-mode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mock-mode.d.ts","sourceRoot":"","sources":["../src/mock-mode.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAC7D,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAEnE,sEAAsE;AACtE,MAAM,MAAM,YAAY,GAAG,CACzB,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,MAAM,KACX,OAAO,GAAG,SAAS,CAAA;AAExB;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CAC5B;AAED,+DAA+D;AAC/D,MAAM,WAAW,eAAe;IAC9B,6EAA6E;IAC7E,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;;;;;;;;;;OAUG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAA;IAC7B,oEAAoE;IACpE,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAC/B;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACtC;;;;;OAKG;IACH,MAAM,CAAC,EAAE,cAAc,CAAA;CACxB;AAED,4EAA4E;AAC5E,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,YAAY,GAAG,SAAS,CAAA;IACzD,UAAU,EAAE,CAAC,GAAG,EAAE,WAAW,EAAE,GAAG,EAAE,YAAY,KAAK,YAAY,CAAA;CAClE;AAED;;;;GAIG;AACH,eAAO,MAAM,aAAa,GACxB,QAAQ,MAAM,EACd,MAAM,MAAM,EACZ,QAAQ,eAAe,KACtB,MAAM,GAAG,SAQX,CAAA;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB,GAC7B,QAAQ,eAAe,GAAG;IAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,EACxD,eAAe,YAAY,KAC1B,aAAa,GAAG,SAyElB,CAAA"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Resolve the status code for a request using only the supplied config.
3
+ * Returns `undefined` when the request should pass through.
4
+ * Exported for unit-testing; callers normally use `buildMockModeHooks`.
5
+ */
6
+ export const resolveStatus = (method, path, config) => {
7
+ const overrides = config.pathOverrides ?? {};
8
+ const m = method.toUpperCase();
9
+ const byMethodPath = overrides[`${m} ${path}`];
10
+ if (byMethodPath !== undefined)
11
+ return byMethodPath;
12
+ const byPath = overrides[path];
13
+ if (byPath !== undefined)
14
+ return byPath;
15
+ return config.defaultStatus;
16
+ };
17
+ /**
18
+ * Build the onRequest / onResponse hook pair. Returns `undefined`
19
+ * when the feature is disabled (caller may skip wiring entirely).
20
+ *
21
+ * `bodyResolver` is optional. When provided, @databehave/server asks it for a
22
+ * body for the configured status (typically a generator backed by
23
+ * the OpenAPI `responses[N]` schema). When it returns `undefined`,
24
+ * the minimal envelope `{ error: true, status: N }` is used instead.
25
+ */
26
+ export const buildMockModeHooks = (config, bodyResolver) => {
27
+ if (config.enabled !== true)
28
+ return undefined;
29
+ const header = config.header ?? 'x-mock-status';
30
+ const healthPaths = new Set(config.healthPaths ?? []);
31
+ const isHealthPath = (p) => healthPaths.has(p);
32
+ const logger = config.logger ?? console;
33
+ const synthesize = (request, status) => {
34
+ const headers = { [header]: String(status) };
35
+ if (status === 204 || status === 205 || status === 304) {
36
+ return { status, empty: true, headers };
37
+ }
38
+ const resolved = bodyResolver?.(request, status);
39
+ const body = resolved === undefined ? { error: true, status } : resolved;
40
+ return { status, json: body, headers };
41
+ };
42
+ const onRequest = (req) => {
43
+ if (isHealthPath(req.path))
44
+ return undefined;
45
+ // Header override (opt-in). The header name is the same one used
46
+ // to tag responses so a single curl flag flips both directions.
47
+ // 1xx (informational) responses are rejected: Node's HTTP layer
48
+ // treats them specially and a mock server has no use for them.
49
+ if (config.allowHeaderOverride === true) {
50
+ const raw = req.headers[header.toLowerCase()];
51
+ if (raw !== undefined) {
52
+ const n = Number.parseInt(raw, 10);
53
+ if (Number.isFinite(n) && n >= 200 && n < 600) {
54
+ return synthesize(req, n);
55
+ }
56
+ // Out-of-range or non-numeric values were previously dropped on
57
+ // the floor, which made debugging "why doesn't my override
58
+ // work?" needlessly hard. Emit a single warn line so the typo
59
+ // is visible without escalating to a hard failure (which would
60
+ // break legitimate clients that ship the header for other
61
+ // reasons).
62
+ logger.warn(`@databehave/openapi/mock-mode: ignored ${header}=${JSON.stringify(raw)} ` +
63
+ `(must be an integer in [200, 600))`);
64
+ }
65
+ }
66
+ const status = resolveStatus(req.method, req.path, config);
67
+ if (status === undefined)
68
+ return undefined;
69
+ return synthesize(req, status);
70
+ };
71
+ const onResponse = (req, res) => {
72
+ if (isHealthPath(req.path))
73
+ return res;
74
+ // Skip when the response (synthesised or handler-supplied) already
75
+ // carries the tag header. Header lookup is case-insensitive so
76
+ // `'X-Mock-Status'` from a handler is recognised against the
77
+ // configured (typically lowercase) `header` name.
78
+ if (res.headers) {
79
+ const wanted = header.toLowerCase();
80
+ for (const k of Object.keys(res.headers)) {
81
+ if (k.toLowerCase() === wanted)
82
+ return res;
83
+ }
84
+ }
85
+ const tag = String(res.status ?? 200);
86
+ return {
87
+ ...res,
88
+ headers: { ...(res.headers ?? {}), [header]: tag },
89
+ };
90
+ };
91
+ return { onRequest, onResponse };
92
+ };
93
+ //# sourceMappingURL=mock-mode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mock-mode.js","sourceRoot":"","sources":["../src/mock-mode.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ /** FNV-1a request seed derivation retained across generation strategies. */
2
+ export declare const hashSeed: (input: string) => number;
3
+ //# sourceMappingURL=auto-schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto-schema.d.ts","sourceRoot":"","sources":["../../src/openapi/auto-schema.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,eAAO,MAAM,QAAQ,GAAI,OAAO,MAAM,KAAG,MAOxC,CAAA"}
@@ -0,0 +1,10 @@
1
+ /** FNV-1a request seed derivation retained across generation strategies. */
2
+ export const hashSeed = (input) => {
3
+ let h = 0x811c9dc5;
4
+ for (let i = 0; i < input.length; i++) {
5
+ h ^= input.charCodeAt(i);
6
+ h = (h + ((h << 1) + (h << 4) + (h << 7) + (h << 8) + (h << 24))) >>> 0;
7
+ }
8
+ return h >>> 0;
9
+ };
10
+ //# sourceMappingURL=auto-schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto-schema.js","sourceRoot":"","sources":["../../src/openapi/auto-schema.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,KAAa,EAAU,EAAE;IAChD,IAAI,CAAC,GAAG,UAAU,CAAA;IAClB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAA;QACxB,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;IACzE,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,CAAA;AAChB,CAAC,CAAA"}
@@ -0,0 +1,8 @@
1
+ /** Deterministic structural placeholder generation; no schema runtime dependency. */
2
+ import type { OasDoc, OasNode } from './walker.js';
3
+ /** Reserved for a future seeded mode (brief item #11). Currently ignored. */
4
+ export interface GenerateOptions {
5
+ readonly seed?: number;
6
+ }
7
+ export declare const generateFromOasSchema: (node: OasNode, doc?: OasDoc, _opts?: GenerateOptions, seen?: Set<string>) => unknown;
8
+ //# sourceMappingURL=generate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/openapi/generate.ts"],"names":[],"mappings":"AAAA,qFAAqF;AACrF,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAElD,6EAA6E;AAC7E,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CACvB;AAsDD,eAAO,MAAM,qBAAqB,GAChC,MAAM,OAAO,EACb,MAAK,MAAW,EAEhB,QAAO,eAAoB,EAC3B,OAAM,GAAG,CAAC,MAAM,CAAqB,KACpC,OAqEF,CAAA"}