@openaddresses/batch-schema 10.25.0 → 10.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -0
- package/README.md +78 -0
- package/dist/lib/openapi.js +16 -6
- package/dist/lib/openapi.js.map +1 -1
- package/dist/lib/schema.d.ts +20 -0
- package/dist/lib/schema.js +78 -10
- package/dist/lib/schema.js.map +1 -1
- package/dist/lib/types.d.ts +48 -1
- package/dist/lib/types.js +48 -1
- package/dist/lib/types.js.map +1 -1
- package/dist/test/schema.srv.test.js +216 -0
- package/dist/test/schema.srv.test.js.map +1 -1
- package/lib/openapi.ts +14 -6
- package/lib/schema.ts +86 -7
- package/lib/types.ts +86 -1
- package/package.json +1 -1
- package/test/schema.srv.test.ts +244 -0
|
@@ -19,6 +19,71 @@ describe('Schema Server', () => {
|
|
|
19
19
|
}, async (_, res) => {
|
|
20
20
|
res.json({ ok: true });
|
|
21
21
|
});
|
|
22
|
+
await schema.post('/json-only', {
|
|
23
|
+
description: 'Backwards compatible JSON body',
|
|
24
|
+
body: Type.Object({
|
|
25
|
+
name: Type.String()
|
|
26
|
+
}),
|
|
27
|
+
res: Type.Object({ ok: Type.Boolean() })
|
|
28
|
+
}, async (req, res) => {
|
|
29
|
+
res.json({ ok: typeof req.body.name === 'string' });
|
|
30
|
+
});
|
|
31
|
+
await schema.post('/multi-body', {
|
|
32
|
+
description: 'Multi content-type body',
|
|
33
|
+
body: {
|
|
34
|
+
'application/json': Type.Object({ name: Type.String() }),
|
|
35
|
+
'text/xml': true
|
|
36
|
+
},
|
|
37
|
+
res: Type.Object({
|
|
38
|
+
contentType: Type.String(),
|
|
39
|
+
body: Type.Any()
|
|
40
|
+
})
|
|
41
|
+
}, async (req, res) => {
|
|
42
|
+
res.json({
|
|
43
|
+
contentType: (req.headers['content-type'] || '').split(';')[0],
|
|
44
|
+
body: req.body
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
await schema.post('/wildcard-body', {
|
|
48
|
+
description: 'Wildcard content-type body',
|
|
49
|
+
body: {
|
|
50
|
+
'application/json': Type.Object({ name: Type.String() }),
|
|
51
|
+
'text/*': true
|
|
52
|
+
},
|
|
53
|
+
res: Type.Object({
|
|
54
|
+
contentType: Type.String(),
|
|
55
|
+
body: Type.Any()
|
|
56
|
+
})
|
|
57
|
+
}, async (req, res) => {
|
|
58
|
+
res.json({
|
|
59
|
+
contentType: (req.headers['content-type'] || '').split(';')[0],
|
|
60
|
+
body: req.body
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
await schema.post('/optional-body', {
|
|
64
|
+
description: 'Optional body',
|
|
65
|
+
body: Type.Object({ name: Type.String() }),
|
|
66
|
+
bodyRequired: false,
|
|
67
|
+
res: Type.Object({ ok: Type.Boolean() })
|
|
68
|
+
}, async (_req, res) => {
|
|
69
|
+
res.json({ ok: true });
|
|
70
|
+
});
|
|
71
|
+
await schema.post('/with-examples', {
|
|
72
|
+
description: 'Body with examples in OpenAPI',
|
|
73
|
+
body: {
|
|
74
|
+
'application/json': {
|
|
75
|
+
schema: Type.Object({ name: Type.String() }),
|
|
76
|
+
example: { name: 'sample' },
|
|
77
|
+
examples: {
|
|
78
|
+
primary: { summary: 'Primary', value: { name: 'alice' } },
|
|
79
|
+
secondary: { summary: 'Secondary', value: { name: 'bob' } }
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
res: Type.Object({ ok: Type.Boolean() })
|
|
84
|
+
}, async (_req, res) => {
|
|
85
|
+
res.json({ ok: true });
|
|
86
|
+
});
|
|
22
87
|
await schema.api();
|
|
23
88
|
done();
|
|
24
89
|
});
|
|
@@ -35,6 +100,31 @@ describe('Schema Server', () => {
|
|
|
35
100
|
query: false,
|
|
36
101
|
res: true
|
|
37
102
|
},
|
|
103
|
+
'POST /json-only': {
|
|
104
|
+
body: true,
|
|
105
|
+
query: false,
|
|
106
|
+
res: true
|
|
107
|
+
},
|
|
108
|
+
'POST /multi-body': {
|
|
109
|
+
body: true,
|
|
110
|
+
query: false,
|
|
111
|
+
res: true
|
|
112
|
+
},
|
|
113
|
+
'POST /wildcard-body': {
|
|
114
|
+
body: true,
|
|
115
|
+
query: false,
|
|
116
|
+
res: true
|
|
117
|
+
},
|
|
118
|
+
'POST /optional-body': {
|
|
119
|
+
body: true,
|
|
120
|
+
query: false,
|
|
121
|
+
res: true
|
|
122
|
+
},
|
|
123
|
+
'POST /with-examples': {
|
|
124
|
+
body: true,
|
|
125
|
+
query: false,
|
|
126
|
+
res: true
|
|
127
|
+
},
|
|
38
128
|
'GET /schema': {
|
|
39
129
|
body: false,
|
|
40
130
|
query: true,
|
|
@@ -104,5 +194,131 @@ describe('Schema Server', () => {
|
|
|
104
194
|
assert.strictEqual(body.paths['/legacy'].get.deprecated, true);
|
|
105
195
|
assert.strictEqual(body.paths['/schema'].get.deprecated, false);
|
|
106
196
|
});
|
|
197
|
+
it('POST: /json-only with valid JSON body (backwards compat)', async () => {
|
|
198
|
+
const res = await fetch('http://localhost:2000/api/json-only', {
|
|
199
|
+
method: 'POST',
|
|
200
|
+
headers: { 'Content-Type': 'application/json' },
|
|
201
|
+
body: JSON.stringify({ name: 'foo' })
|
|
202
|
+
});
|
|
203
|
+
assert.strictEqual(res.status, 200);
|
|
204
|
+
assert.deepStrictEqual(await res.json(), { ok: true });
|
|
205
|
+
});
|
|
206
|
+
it('POST: /multi-body with application/json', async () => {
|
|
207
|
+
const res = await fetch('http://localhost:2000/api/multi-body', {
|
|
208
|
+
method: 'POST',
|
|
209
|
+
headers: { 'Content-Type': 'application/json' },
|
|
210
|
+
body: JSON.stringify({ name: 'foo' })
|
|
211
|
+
});
|
|
212
|
+
assert.strictEqual(res.status, 200);
|
|
213
|
+
assert.deepStrictEqual(await res.json(), {
|
|
214
|
+
contentType: 'application/json',
|
|
215
|
+
body: { name: 'foo' }
|
|
216
|
+
});
|
|
217
|
+
});
|
|
218
|
+
it('POST: /multi-body with text/xml (true => no validation)', async () => {
|
|
219
|
+
const res = await fetch('http://localhost:2000/api/multi-body', {
|
|
220
|
+
method: 'POST',
|
|
221
|
+
headers: { 'Content-Type': 'text/xml' },
|
|
222
|
+
body: '<root><a>1</a></root>'
|
|
223
|
+
});
|
|
224
|
+
assert.strictEqual(res.status, 200);
|
|
225
|
+
assert.deepStrictEqual(await res.json(), {
|
|
226
|
+
contentType: 'text/xml',
|
|
227
|
+
body: '<root><a>1</a></root>'
|
|
228
|
+
});
|
|
229
|
+
});
|
|
230
|
+
it('POST: /multi-body with unsupported content-type returns 400', async () => {
|
|
231
|
+
const res = await fetch('http://localhost:2000/api/multi-body', {
|
|
232
|
+
method: 'POST',
|
|
233
|
+
headers: { 'Content-Type': 'text/plain' },
|
|
234
|
+
body: 'hello'
|
|
235
|
+
});
|
|
236
|
+
assert.strictEqual(res.status, 400);
|
|
237
|
+
const body = await res.json();
|
|
238
|
+
assert.strictEqual(body.status, 400);
|
|
239
|
+
assert.match(body.message, /Content-Type text\/plain not supported/);
|
|
240
|
+
});
|
|
241
|
+
it('POST: /multi-body with invalid JSON body fails validation', async () => {
|
|
242
|
+
const res = await fetch('http://localhost:2000/api/multi-body', {
|
|
243
|
+
method: 'POST',
|
|
244
|
+
headers: { 'Content-Type': 'application/json' },
|
|
245
|
+
body: JSON.stringify({})
|
|
246
|
+
});
|
|
247
|
+
assert.strictEqual(res.status, 400);
|
|
248
|
+
const body = await res.json();
|
|
249
|
+
assert.strictEqual(body.message, 'Validation Error POST /multi-body');
|
|
250
|
+
});
|
|
251
|
+
it('GET: api/openapi documents multiple content types', async () => {
|
|
252
|
+
const res = await fetch('http://localhost:2000/api/openapi');
|
|
253
|
+
const body = await res.json();
|
|
254
|
+
assert.deepStrictEqual(Object.keys(body.paths['/multi-body'].post.requestBody.content).sort(), ['application/json', 'text/xml']);
|
|
255
|
+
assert.deepStrictEqual(body.paths['/multi-body'].post.requestBody.content['text/xml'], { schema: {} });
|
|
256
|
+
assert.strictEqual(body.paths['/json-only'].post.requestBody.content['application/json'].schema.type, 'object');
|
|
257
|
+
});
|
|
258
|
+
it('POST: /wildcard-body matches text/* with text/csv', async () => {
|
|
259
|
+
const res = await fetch('http://localhost:2000/api/wildcard-body', {
|
|
260
|
+
method: 'POST',
|
|
261
|
+
headers: { 'Content-Type': 'text/csv' },
|
|
262
|
+
body: 'a,b,c\n1,2,3'
|
|
263
|
+
});
|
|
264
|
+
assert.strictEqual(res.status, 200);
|
|
265
|
+
assert.deepStrictEqual(await res.json(), {
|
|
266
|
+
contentType: 'text/csv',
|
|
267
|
+
body: 'a,b,c\n1,2,3'
|
|
268
|
+
});
|
|
269
|
+
});
|
|
270
|
+
it('POST: /wildcard-body still validates application/json strictly', async () => {
|
|
271
|
+
const res = await fetch('http://localhost:2000/api/wildcard-body', {
|
|
272
|
+
method: 'POST',
|
|
273
|
+
headers: { 'Content-Type': 'application/json' },
|
|
274
|
+
body: JSON.stringify({ name: 'foo' })
|
|
275
|
+
});
|
|
276
|
+
assert.strictEqual(res.status, 200);
|
|
277
|
+
});
|
|
278
|
+
it('POST: /wildcard-body rejects unsupported family', async () => {
|
|
279
|
+
const res = await fetch('http://localhost:2000/api/wildcard-body', {
|
|
280
|
+
method: 'POST',
|
|
281
|
+
headers: { 'Content-Type': 'image/png' },
|
|
282
|
+
body: 'binary'
|
|
283
|
+
});
|
|
284
|
+
assert.strictEqual(res.status, 400);
|
|
285
|
+
const body = await res.json();
|
|
286
|
+
assert.match(body.message, /Content-Type image\/png not supported/);
|
|
287
|
+
});
|
|
288
|
+
it('POST: /optional-body accepts no body when bodyRequired=false', async () => {
|
|
289
|
+
const res = await fetch('http://localhost:2000/api/optional-body', {
|
|
290
|
+
method: 'POST'
|
|
291
|
+
});
|
|
292
|
+
assert.strictEqual(res.status, 200);
|
|
293
|
+
assert.deepStrictEqual(await res.json(), { ok: true });
|
|
294
|
+
});
|
|
295
|
+
it('POST: /optional-body still validates when a body is sent', async () => {
|
|
296
|
+
const res = await fetch('http://localhost:2000/api/optional-body', {
|
|
297
|
+
method: 'POST',
|
|
298
|
+
headers: { 'Content-Type': 'application/json' },
|
|
299
|
+
body: JSON.stringify({})
|
|
300
|
+
});
|
|
301
|
+
assert.strictEqual(res.status, 400);
|
|
302
|
+
});
|
|
303
|
+
it('GET: api/openapi marks optional body required=false', async () => {
|
|
304
|
+
const res = await fetch('http://localhost:2000/api/openapi');
|
|
305
|
+
const body = await res.json();
|
|
306
|
+
assert.strictEqual(body.paths['/optional-body'].post.requestBody.required, false);
|
|
307
|
+
assert.strictEqual(body.paths['/json-only'].post.requestBody.required, true);
|
|
308
|
+
});
|
|
309
|
+
it('GET: api/openapi includes example and examples on media type', async () => {
|
|
310
|
+
const res = await fetch('http://localhost:2000/api/openapi');
|
|
311
|
+
const body = await res.json();
|
|
312
|
+
const media = body.paths['/with-examples'].post.requestBody.content['application/json'];
|
|
313
|
+
assert.deepStrictEqual(media.example, { name: 'sample' });
|
|
314
|
+
assert.deepStrictEqual(media.examples.primary, {
|
|
315
|
+
summary: 'Primary',
|
|
316
|
+
value: { name: 'alice' }
|
|
317
|
+
});
|
|
318
|
+
assert.deepStrictEqual(media.examples.secondary, {
|
|
319
|
+
summary: 'Secondary',
|
|
320
|
+
value: { name: 'bob' }
|
|
321
|
+
});
|
|
322
|
+
});
|
|
107
323
|
});
|
|
108
324
|
//# sourceMappingURL=schema.srv.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.srv.test.js","sourceRoot":"","sources":["../../test/schema.srv.test.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"schema.srv.test.js","sourceRoot":"","sources":["../../test/schema.srv.test.ts"],"names":[],"mappings":"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"}
|
package/lib/openapi.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { OpenAPIV3 as Doc } from 'openapi-types'
|
|
2
2
|
import type { RequestValidation } from './types.js';
|
|
3
|
+
import { normalizeBody } from './types.js';
|
|
3
4
|
import type { TSchema } from '@sinclair/typebox';
|
|
4
5
|
|
|
5
6
|
export type OpenAPIDocumentInput = {
|
|
@@ -165,13 +166,20 @@ export default class Docs {
|
|
|
165
166
|
}
|
|
166
167
|
|
|
167
168
|
if (schemas.body) {
|
|
169
|
+
const normalized = normalizeBody(schemas.body) || {};
|
|
170
|
+
const content: Record<string, Doc.MediaTypeObject> = {};
|
|
171
|
+
for (const ct of Object.keys(normalized)) {
|
|
172
|
+
const entry = normalized[ct];
|
|
173
|
+
const media: Doc.MediaTypeObject = {
|
|
174
|
+
schema: entry.schema === true ? {} : entry.schema as Doc.SchemaObject
|
|
175
|
+
};
|
|
176
|
+
if (entry.example !== undefined) media.example = entry.example;
|
|
177
|
+
if (entry.examples !== undefined) media.examples = entry.examples as Record<string, Doc.ExampleObject>;
|
|
178
|
+
content[ct] = media;
|
|
179
|
+
}
|
|
168
180
|
document.requestBody = {
|
|
169
|
-
required:
|
|
170
|
-
content
|
|
171
|
-
'application/json': {
|
|
172
|
-
schema: schemas.body
|
|
173
|
-
}
|
|
174
|
-
}
|
|
181
|
+
required: schemas.bodyRequired !== false,
|
|
182
|
+
content
|
|
175
183
|
};
|
|
176
184
|
}
|
|
177
185
|
|
package/lib/schema.ts
CHANGED
|
@@ -13,6 +13,7 @@ import { Ajv } from 'ajv'
|
|
|
13
13
|
import type { ErrorObject } from 'ajv'
|
|
14
14
|
import addFormatsModule from 'ajv-formats'
|
|
15
15
|
import type { RequestValidation } from './types.js';
|
|
16
|
+
import { normalizeBody, matchContentType } from './types.js';
|
|
16
17
|
import type { OpenAPIDocumentInput } from './openapi.js'
|
|
17
18
|
import SchemaAPI from './api.js';
|
|
18
19
|
import Docs from './openapi.js';
|
|
@@ -53,6 +54,67 @@ export default class Schemas {
|
|
|
53
54
|
return new Err(400, null, `Validation Error ${String(method).toUpperCase()} ${path}`);
|
|
54
55
|
}
|
|
55
56
|
|
|
57
|
+
/**
|
|
58
|
+
* Compile body validators keyed by content-type. Returns null when no
|
|
59
|
+
* body validation is configured. Each entry is either `true` (any body
|
|
60
|
+
* accepted for this content-type) or a compiled ajv validator function.
|
|
61
|
+
*/
|
|
62
|
+
compileBodyValidators(
|
|
63
|
+
body: RequestValidation<TSchema, TSchema, TSchema, TSchema>['body']
|
|
64
|
+
): Map<string, true | ReturnType<typeof ajv.compile>> | null {
|
|
65
|
+
const normalized = normalizeBody(body);
|
|
66
|
+
if (!normalized) return null;
|
|
67
|
+
|
|
68
|
+
const map = new Map<string, true | ReturnType<typeof ajv.compile>>();
|
|
69
|
+
for (const ct of Object.keys(normalized)) {
|
|
70
|
+
const schema = normalized[ct].schema;
|
|
71
|
+
if (schema === true || schema === undefined) {
|
|
72
|
+
map.set(ct, true);
|
|
73
|
+
} else {
|
|
74
|
+
map.set(ct, ajv.compile(schema));
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return map;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Validate the incoming request body against the compiled validator
|
|
82
|
+
* map for the route. Pushes a Body error onto `errors` if validation
|
|
83
|
+
* fails; returns an Err to respond with for an unsupported content-type.
|
|
84
|
+
*
|
|
85
|
+
* If `bodyRequired` is false and the request has no body / no
|
|
86
|
+
* content-type, validation is skipped.
|
|
87
|
+
*/
|
|
88
|
+
validateBody(
|
|
89
|
+
req: Request,
|
|
90
|
+
validators: Map<string, true | ReturnType<typeof ajv.compile>>,
|
|
91
|
+
errors: Array<ErrorListItem>,
|
|
92
|
+
opts: { required?: boolean } = {}
|
|
93
|
+
): Err | null {
|
|
94
|
+
const raw = (req.headers['content-type'] || '').split(';')[0].trim().toLowerCase();
|
|
95
|
+
const required = opts.required !== false;
|
|
96
|
+
|
|
97
|
+
if (!raw && !required) return null;
|
|
98
|
+
|
|
99
|
+
const normalizedMap: Record<string, { schema: true }> = {};
|
|
100
|
+
for (const key of validators.keys()) normalizedMap[key] = { schema: true };
|
|
101
|
+
const matched = matchContentType(raw, normalizedMap);
|
|
102
|
+
const validator = matched ? validators.get(matched) : undefined;
|
|
103
|
+
|
|
104
|
+
if (!validator) {
|
|
105
|
+
const supported = Array.from(validators.keys()).join(', ');
|
|
106
|
+
return new Err(400, null, `Content-Type ${raw || '(none)'} not supported. Supported: ${supported}`);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (validator !== true) {
|
|
110
|
+
if (!validator(req.body)) {
|
|
111
|
+
errors.push({ type: 'Body', errors: validator.errors as ErrorObject[] });
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
|
|
56
118
|
constructor(
|
|
57
119
|
router: Router,
|
|
58
120
|
opts: {
|
|
@@ -74,8 +136,16 @@ export default class Schemas {
|
|
|
74
136
|
this.router.use(morgan('combined', morganOptions));
|
|
75
137
|
}
|
|
76
138
|
|
|
77
|
-
this.router.use(bodyparser.urlencoded({ extended: true }));
|
|
139
|
+
this.router.use(bodyparser.urlencoded({ extended: true, limit: `${opts.limit || 50}mb` }));
|
|
78
140
|
this.router.use(bodyparser.json({ limit: `${opts.limit || 50}mb` }));
|
|
141
|
+
this.router.use(bodyparser.text({
|
|
142
|
+
limit: `${opts.limit || 50}mb`,
|
|
143
|
+
type: ['text/*', 'application/xml', 'application/*+xml']
|
|
144
|
+
}));
|
|
145
|
+
this.router.use(bodyparser.raw({
|
|
146
|
+
limit: `${opts.limit || 50}mb`,
|
|
147
|
+
type: ['application/octet-stream']
|
|
148
|
+
}));
|
|
79
149
|
|
|
80
150
|
if (opts.error) {
|
|
81
151
|
this.error = opts.error;
|
|
@@ -264,7 +334,7 @@ export default class Schemas {
|
|
|
264
334
|
const resValidation = validation.res && !(validation.res instanceof Type.Any) && !(validation.res instanceof Type.Unknown) && ajv.compile(validation.res);
|
|
265
335
|
const paramsValidation = validation.params && ajv.compile(validation.params);
|
|
266
336
|
const queryValidation = validation.query && ajv.compile(validation.query);
|
|
267
|
-
const
|
|
337
|
+
const bodyValidators = this.compileBodyValidators(validation.body);
|
|
268
338
|
|
|
269
339
|
const _handler: RequestHandler = (req, res, next) => {
|
|
270
340
|
if (req.query) { // Ref: https://github.com/cdimascio/express-openapi-validator/issues/969
|
|
@@ -277,7 +347,10 @@ export default class Schemas {
|
|
|
277
347
|
const errors: Array<ErrorListItem> = [];
|
|
278
348
|
if (paramsValidation && !paramsValidation(req.params)) errors.push({ type: 'Params', errors: paramsValidation.errors as ErrorObject[] });
|
|
279
349
|
if (queryValidation && !queryValidation(req.query)) errors.push({ type: 'Query', errors: queryValidation.errors as ErrorObject[] });
|
|
280
|
-
if (
|
|
350
|
+
if (bodyValidators) {
|
|
351
|
+
const ctErr = this.validateBody(req, bodyValidators, errors, { required: validation.bodyRequired });
|
|
352
|
+
if (ctErr) return Err.respond(ctErr, res);
|
|
353
|
+
}
|
|
281
354
|
if (errors.length) return Err.respond(this.validationError(Doc.HttpMethods.POST, path), res, errors);
|
|
282
355
|
|
|
283
356
|
const json = res.json;
|
|
@@ -315,7 +388,7 @@ export default class Schemas {
|
|
|
315
388
|
const resValidation = validation.res && !(validation.res instanceof Type.Any) && !(validation.res instanceof Type.Unknown) && ajv.compile(validation.res);
|
|
316
389
|
const paramsValidation = validation.params && ajv.compile(validation.params);
|
|
317
390
|
const queryValidation = validation.query && ajv.compile(validation.query);
|
|
318
|
-
const
|
|
391
|
+
const bodyValidators = this.compileBodyValidators(validation.body);
|
|
319
392
|
|
|
320
393
|
const _handler: RequestHandler = (req, res, next) => {
|
|
321
394
|
if (req.query) { // Ref: https://github.com/cdimascio/express-openapi-validator/issues/969
|
|
@@ -328,7 +401,10 @@ export default class Schemas {
|
|
|
328
401
|
const errors: Array<ErrorListItem> = [];
|
|
329
402
|
if (paramsValidation && !paramsValidation(req.params)) errors.push({ type: 'Params', errors: paramsValidation.errors as ErrorObject[] });
|
|
330
403
|
if (queryValidation && !queryValidation(req.query)) errors.push({ type: 'Query', errors: queryValidation.errors as ErrorObject[] });
|
|
331
|
-
if (
|
|
404
|
+
if (bodyValidators) {
|
|
405
|
+
const ctErr = this.validateBody(req, bodyValidators, errors, { required: validation.bodyRequired });
|
|
406
|
+
if (ctErr) return Err.respond(ctErr, res);
|
|
407
|
+
}
|
|
332
408
|
if (errors.length) return Err.respond(this.validationError(Doc.HttpMethods.PATCH, path), res, errors);
|
|
333
409
|
|
|
334
410
|
const json = res.json;
|
|
@@ -366,7 +442,7 @@ export default class Schemas {
|
|
|
366
442
|
const resValidation = validation.res && !(validation.res instanceof Type.Any) && !(validation.res instanceof Type.Unknown) && ajv.compile(validation.res);
|
|
367
443
|
const paramsValidation = validation.params && ajv.compile(validation.params);
|
|
368
444
|
const queryValidation = validation.query && ajv.compile(validation.query);
|
|
369
|
-
const
|
|
445
|
+
const bodyValidators = this.compileBodyValidators(validation.body);
|
|
370
446
|
|
|
371
447
|
const _handler: RequestHandler = (req, res, next) => {
|
|
372
448
|
if (req.query) { // Ref: https://github.com/cdimascio/express-openapi-validator/issues/969
|
|
@@ -379,7 +455,10 @@ export default class Schemas {
|
|
|
379
455
|
const errors: Array<ErrorListItem> = [];
|
|
380
456
|
if (paramsValidation && !paramsValidation(req.params)) errors.push({ type: 'Params', errors: paramsValidation.errors as ErrorObject[] });
|
|
381
457
|
if (queryValidation && !queryValidation(req.query)) errors.push({ type: 'Query', errors: queryValidation.errors as ErrorObject[] });
|
|
382
|
-
if (
|
|
458
|
+
if (bodyValidators) {
|
|
459
|
+
const ctErr = this.validateBody(req, bodyValidators, errors, { required: validation.bodyRequired });
|
|
460
|
+
if (ctErr) return Err.respond(ctErr, res);
|
|
461
|
+
}
|
|
383
462
|
if (errors.length) return Err.respond(this.validationError(Doc.HttpMethods.PUT, path), res, errors);
|
|
384
463
|
|
|
385
464
|
const json = res.json;
|
package/lib/types.ts
CHANGED
|
@@ -1,5 +1,88 @@
|
|
|
1
|
+
import { Kind } from '@sinclair/typebox';
|
|
1
2
|
import type { TSchema } from '@sinclair/typebox';
|
|
2
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Per-content-type body entry. May be:
|
|
6
|
+
* - a TypeBox schema (validated, no example)
|
|
7
|
+
* - `true` (any body accepted, no validation)
|
|
8
|
+
* - an object with optional `schema` (TSchema | true), `example`, `examples`
|
|
9
|
+
* (forwarded to the OpenAPI media type object)
|
|
10
|
+
*/
|
|
11
|
+
export type BodyEntryConfig = {
|
|
12
|
+
schema?: TSchema | true;
|
|
13
|
+
example?: unknown;
|
|
14
|
+
examples?: Record<string, { summary?: string; description?: string; value: unknown }>;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export type BodyEntry = TSchema | true | BodyEntryConfig;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Body validation can either be:
|
|
21
|
+
* - a TypeBox schema (treated as `application/json` for backwards compatibility)
|
|
22
|
+
* - a record mapping content-type strings to a `BodyEntry`. Content-type
|
|
23
|
+
* keys may include wildcards: `text/*`, `application/*`, or `* / *`.
|
|
24
|
+
*/
|
|
25
|
+
export type BodyValidation<TBody extends TSchema> =
|
|
26
|
+
| TBody
|
|
27
|
+
| Record<string, BodyEntry>;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Normalized internal representation: every entry has the expanded
|
|
31
|
+
* `BodyEntryConfig` shape with `schema` always set (defaulting to `true`).
|
|
32
|
+
*/
|
|
33
|
+
export type NormalizedBody = Record<string, Required<Pick<BodyEntryConfig, 'schema'>> & BodyEntryConfig>;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Detect whether a given value is a TypeBox schema. TypeBox attaches a
|
|
37
|
+
* `[Kind]` symbol to every schema instance which is what we use to
|
|
38
|
+
* distinguish a schema from a content-type-keyed body record.
|
|
39
|
+
*/
|
|
40
|
+
export function isTSchema(value: unknown): value is TSchema {
|
|
41
|
+
return !!value && typeof value === 'object' && Kind in (value as object);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function normalizeEntry(entry: BodyEntry): NormalizedBody[string] {
|
|
45
|
+
if (entry === true) return { schema: true };
|
|
46
|
+
if (isTSchema(entry)) return { schema: entry };
|
|
47
|
+
return { schema: true, ...entry };
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Normalize the body option into a `NormalizedBody` map. A bare TypeBox
|
|
52
|
+
* schema is mapped to `application/json` for backwards compatibility.
|
|
53
|
+
*/
|
|
54
|
+
export function normalizeBody(
|
|
55
|
+
body: TSchema | Record<string, BodyEntry> | undefined
|
|
56
|
+
): NormalizedBody | undefined {
|
|
57
|
+
if (!body) return undefined;
|
|
58
|
+
if (isTSchema(body)) return { 'application/json': { schema: body } };
|
|
59
|
+
|
|
60
|
+
const out: NormalizedBody = {};
|
|
61
|
+
for (const ct of Object.keys(body)) {
|
|
62
|
+
out[ct.toLowerCase()] = normalizeEntry(body[ct]);
|
|
63
|
+
}
|
|
64
|
+
return out;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Match an incoming content-type against a normalized body map, honoring
|
|
69
|
+
* wildcard entries like `text/*` or `*\/*`. Exact matches always win.
|
|
70
|
+
*/
|
|
71
|
+
export function matchContentType(
|
|
72
|
+
incoming: string,
|
|
73
|
+
normalized: NormalizedBody
|
|
74
|
+
): string | undefined {
|
|
75
|
+
if (!incoming) {
|
|
76
|
+
return normalized['*/*'] ? '*/*' : undefined;
|
|
77
|
+
}
|
|
78
|
+
if (normalized[incoming]) return incoming;
|
|
79
|
+
|
|
80
|
+
const [type] = incoming.split('/');
|
|
81
|
+
if (type && normalized[`${type}/*`]) return `${type}/*`;
|
|
82
|
+
if (normalized['*/*']) return '*/*';
|
|
83
|
+
return undefined;
|
|
84
|
+
}
|
|
85
|
+
|
|
3
86
|
export type RequestValidation<
|
|
4
87
|
TParams extends TSchema,
|
|
5
88
|
TQuery extends TSchema,
|
|
@@ -13,6 +96,8 @@ export type RequestValidation<
|
|
|
13
96
|
description?: string;
|
|
14
97
|
params?: TParams;
|
|
15
98
|
query?: TQuery;
|
|
16
|
-
body?: TBody
|
|
99
|
+
body?: BodyValidation<TBody>;
|
|
100
|
+
/** Whether the request body is required. Defaults to true when `body` is set. */
|
|
101
|
+
bodyRequired?: boolean;
|
|
17
102
|
res?: TResponse
|
|
18
103
|
};
|