/
schema.parse.ts
82 lines (68 loc) 路 2.5 KB
/
schema.parse.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import { OpenAPIV3, ParametersSchema } from '../../framework/types';
import { validationError } from '../util';
import { dereferenceParameter, normalizeParameter } from './util';
const PARAM_TYPE = {
query: 'query',
header: 'headers',
path: 'params',
cookie: 'cookies',
};
type Parameter = OpenAPIV3.ReferenceObject | OpenAPIV3.ParameterObject;
/**
* A class top arse incoing parameters and populate a list of request fields e.g. id and field types e.g. query
* whose value must later be parsed as a JSON object, JSON Exploded Object, JSON Array, or JSON Exploded Array
*/
export class ParametersSchemaParser {
private _apiDocs: OpenAPIV3.Document;
constructor(apiDocs: OpenAPIV3.Document) {
this._apiDocs = apiDocs;
}
/**
* Parse incoing parameters and populate a list of request fields e.g. id and field types e.g. query
* whose value must later be parsed as a JSON object, JSON Exploded Object, JSON Array, or JSON Exploded Array
* @param path
* @param parameters
*/
public parse(path: string, parameters: Parameter[] = []): ParametersSchema {
const schemas = { query: {}, headers: {}, params: {}, cookies: {} };
parameters.forEach(p => {
const parameter = dereferenceParameter(this._apiDocs, p);
this.validateParameterType(path, parameter);
const reqField = PARAM_TYPE[parameter.in];
const { name, schema } = normalizeParameter(parameter);
if (!schemas[reqField].properties) {
schemas[reqField] = {
type: 'object',
properties: {},
};
}
schemas[reqField].properties[name] = schema;
if (parameter.required) {
if (!schemas[reqField].required) {
schemas[reqField].required = [];
}
schemas[reqField].required.push(name);
}
});
return schemas;
}
private validateParameterType(
path: string,
parameter: OpenAPIV3.ParameterObject,
): void {
const isKnownType = PARAM_TYPE[parameter.in];
if (!isKnownType) {
const message = `Parameter 'in' has incorrect value '${parameter.in}' for [${parameter.name}]`;
throw validationError(400, path, message);
}
const hasSchema = () => {
const contentType =
parameter.content && Object.keys(parameter.content)[0];
return !parameter.schema || !parameter.content?.[contentType]?.schema;
};
if (!hasSchema()) {
const message = `No available parameter in 'schema' or 'content' for [${parameter.name}]`;
throw validationError(400, path, message);
}
}
}