This repository was archived by the owner on Nov 8, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy pathparseOpenAPIObject.js
127 lines (105 loc) · 4.35 KB
/
parseOpenAPIObject.js
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
const R = require('ramda');
const {
isAnnotation, isExtension, hasKey, getValue,
} = require('../../predicates');
const {
createUnsupportedMemberWarning,
createInvalidMemberWarning,
} = require('../annotations');
const pipeParseResult = require('../../pipeParseResult');
const parseObject = require('../parseObject');
const parseOpenAPI = require('../openapi');
const parseServersArray = require('./parseServersArray');
const parseInfoObject = require('./parseInfoObject');
const parsePathsObject = require('./parsePathsObject');
const parseComponentsObject = require('./parseComponentsObject');
const parseSecurityRequirementsArray = require('./parseSecurityRequirementsArray');
const name = 'OpenAPI Object';
const requiredKeys = ['openapi', 'info', 'paths'];
const unsupportedKeys = ['tags', 'externalDocs'];
const unsupportedOpenAPI31Keys = ['webhooks', 'jsonSchemaDialect'];
/**
* Returns whether the given member element is unsupported
* @param member {MemberElement}
* @returns {boolean}
* @see unsupportedKeys
* @private
*/
const isUnsupportedKey = R.anyPass(R.map(hasKey, unsupportedKeys));
const isUnsupportedOpenAPI31Key = R.anyPass(R.map(hasKey, unsupportedOpenAPI31Keys));
function parseOASObject(context, object) {
const { namespace } = context;
// Takes a parse result, and wraps all of the non annotations inside an array
const asArray = (parseResult) => {
const array = new namespace.elements.Array(R.reject(isAnnotation, parseResult));
return new namespace.elements.ParseResult([array].concat(parseResult.annotations.elements));
};
const isOpenAPI31OrHigher = () => context.isOpenAPIVersionMoreThanOrEqual(3, 1);
const parseMember = R.cond([
[hasKey('openapi'), parseOpenAPI(context)],
[hasKey('servers'), R.compose(parseServersArray(context, name), getValue)],
[hasKey('info'), R.compose(parseInfoObject(context), getValue)],
[hasKey('components'), R.compose(parseComponentsObject(context), getValue)],
[hasKey('paths'), R.compose(asArray, parsePathsObject(context), getValue)],
[hasKey('security'), R.compose(parseSecurityRequirementsArray(context), getValue)],
// FIXME Support exposing extensions into parse result
[isExtension, () => new namespace.elements.ParseResult()],
[
R.both(isUnsupportedOpenAPI31Key, isOpenAPI31OrHigher),
createUnsupportedMemberWarning(namespace, name),
],
[isUnsupportedKey, createUnsupportedMemberWarning(namespace, name)],
// Return a warning for additional properties
[R.T, createInvalidMemberWarning(namespace, name)],
]);
const parseOASObject = pipeParseResult(namespace,
parseObject(context, name, parseMember, requiredKeys, ['openapi', 'components']),
(object) => {
const api = object.get('info');
const hosts = object.get('servers');
const components = object.get('components');
const security = object.get('security');
if (components) {
const schemes = R.or(components.get('securitySchemes'), new namespace.elements.Array());
if (!schemes.isEmpty) {
api.push(new namespace.elements.Category(
schemes.content, { classes: ['authSchemes'] }
));
}
}
if (hosts) {
api.push(hosts);
}
const resources = object.get('paths');
if (resources) {
api.content = api.content.concat(resources.content);
}
api.resources.forEach((resource) => {
resource.transitions.forEach((transition) => {
transition.transactions.forEach((transaction) => {
if (!transaction.authSchemes && security && !security.isEmpty) {
transaction.attributes.set('authSchemes', security.clone());
}
if (transaction.authSchemes && transaction.authSchemes.isEmpty) {
transaction.attributes.remove('authSchemes');
}
});
});
});
if (components) {
const schemas = R.or(components.get('schemas'), new namespace.elements.Array())
.content
.filter(member => member.value)
.map(getValue);
if (schemas.length > 0) {
const dataStructures = new namespace.elements.Category(
schemas, { classes: ['dataStructures'] }
);
api.push(dataStructures);
}
}
return api;
});
return parseOASObject(object);
}
module.exports = R.curry(parseOASObject);