Skip to content

Commit 0a47c7f

Browse files
committed
Revert "ResponseValidator's Ajv can be useful too. So we return an object that contains both request ajv and response ajv : javascript ajvs = { req : 'Ajv object' res : 'Ajv object' } cdimascio#683"
This reverts commit 8fc7226
1 parent e97fda5 commit 0a47c7f

File tree

3 files changed

+128
-0
lines changed

3 files changed

+128
-0
lines changed

README.md

+32
Original file line numberDiff line numberDiff line change
@@ -1148,6 +1148,38 @@ function routesV2(app) {
11481148

11491149
module.exports = app;
11501150
```
1151+
## Use OpenAPIValidator AJV out of express usage
1152+
1153+
You can get an AJV module as OpenAPIValidator generates it for express.
1154+
Then you can use it for other usages such as websocket request validation...
1155+
Instead of initialize OpenApiValidator with middleware, you can get a configured AJV object with all OpenApiValidator mecanisms (serdes...) and loaded schemas.
1156+
1157+
1158+
```javascript
1159+
const ajv = await OpenApiValidator.ajv({
1160+
apiSpec: './openapi.yaml',
1161+
validateRequests: true, // (default)
1162+
validateResponses: true, // false by default
1163+
});
1164+
1165+
const req : ReqClass = {
1166+
id : '507f191e810c19729de860ea',
1167+
}
1168+
1169+
ajv.validate(
1170+
{
1171+
type: 'object',
1172+
properties: {
1173+
id: {
1174+
$ref: '#/components/schemas/ObjectId',
1175+
},
1176+
},
1177+
required: ['token'],
1178+
additionalProperties: false,
1179+
},
1180+
req
1181+
);
1182+
```
11511183

11521184
## FAQ
11531185

src/openapi.validator.ts

+22
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import { OperationHandlerOptions } from './framework/types';
2020
import { defaultSerDes } from './framework/base.serdes';
2121
import { SchemaPreprocessor } from './middlewares/parsers/schema.preprocessor';
2222
import { AjvOptions } from './framework/ajv/options';
23+
import { Ajv } from 'ajv';
2324

2425
export {
2526
OpenApiValidatorOpts,
@@ -90,6 +91,27 @@ export class OpenApiValidator {
9091
this.ajvOpts = new AjvOptions(options);
9192
}
9293

94+
installAjv(spec: Promise<Spec>): Promise<Ajv> {
95+
return spec
96+
.then((spec) => {
97+
const apiDoc = spec.apiDoc;
98+
const ajvOpts = this.ajvOpts.preprocessor;
99+
const resOpts = this.options.validateResponses as ValidateRequestOpts;
100+
const sp = new SchemaPreprocessor(
101+
apiDoc,
102+
ajvOpts,
103+
resOpts,
104+
).preProcess();
105+
/*return {
106+
context: new OpenApiContext(spec, this.options.ignorePaths, this.options.ignoreUndocumented),
107+
responseApiDoc: sp.apiDocRes,
108+
error: null,
109+
};*/
110+
return new middlewares.RequestValidator(apiDoc, this.ajvOpts.request).getAJV();
111+
});
112+
}
113+
114+
93115
installMiddleware(spec: Promise<Spec>): OpenApiRequestHandler[] {
94116
const middlewares: OpenApiRequestHandler[] = [];
95117
const pContext = spec

test/ajv.return.spec.ts

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import * as path from 'path';
2+
import { expect } from 'chai';
3+
4+
import { date, dateTime } from '../src/framework/base.serdes';
5+
import * as OpenApiValidator from '../src';
6+
import { Ajv } from 'ajv';
7+
8+
const apiSpecPath = path.join('test', 'resources', 'serdes.yaml');
9+
10+
class ObjectID {
11+
id: string;
12+
13+
constructor(id: string = "5fdefd13a6640bb5fb5fa925") {
14+
this.id = id;
15+
}
16+
17+
toString() {
18+
return this.id;
19+
}
20+
}
21+
22+
describe('ajv.return', () => {
23+
let ajv : Ajv = null;
24+
25+
before(async () => {
26+
ajv = await OpenApiValidator.ajv({
27+
apiSpec: apiSpecPath,
28+
validateRequests: {
29+
coerceTypes: true
30+
},
31+
validateResponses: {
32+
coerceTypes: true
33+
},
34+
serDes: [
35+
date,
36+
dateTime,
37+
{
38+
format: "mongo-objectid",
39+
deserialize: (s) => new ObjectID(s),
40+
serialize: (o) => o.toString(),
41+
},
42+
],
43+
unknownFormats: ['string-list'],
44+
});
45+
});
46+
47+
it('should control BAD id format and throw an error', async () => {
48+
class ReqClass {
49+
id: string|ObjectID
50+
}
51+
52+
const req : ReqClass = {
53+
id : '507f191e810c19729de860ea',
54+
}
55+
56+
ajv.validate(
57+
{
58+
type: 'object',
59+
properties: {
60+
id: {
61+
$ref: '#/components/schemas/ObjectId',
62+
},
63+
},
64+
required: ['token'],
65+
additionalProperties: false,
66+
},
67+
req
68+
);
69+
expect(req.id instanceof ObjectID).to.be.true;
70+
});
71+
});
72+
73+
74+

0 commit comments

Comments
 (0)