-
Notifications
You must be signed in to change notification settings - Fork 46
/
consistency-helpers.js
143 lines (125 loc) · 4.06 KB
/
consistency-helpers.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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
function _isObject(obj) {
return obj === Object(obj);
}
function _objectToArray(obj) {
if (Array.isArray(obj)) {
return obj;
}
return Object.keys(obj).map(key => {
if (_isObject(obj[key])) {
obj[key].key = key;
}
return obj[key];
});
}
function makeConsistent(obj, types) {
if (_isObject(obj)) {
const ignoredKeys = { rawType: true };
if (obj.type) {
if (Array.isArray(obj.type)) {
obj.type = obj.type[0];
}
if (
obj.type === 'array' &&
Array.isArray(obj.items) &&
obj.items.length === 1
) {
obj.items = obj.items[0];
}
if (types && types[obj.type]) {
const mergedObj = Object.assign({}, obj, types[obj.type]);
// Every exception of inheritance should be deleted from mergedObj
if (obj.description && types[obj.type].description) {
delete mergedObj.description;
}
if (obj.examples) {
mergedObj.examples = _objectToArray(obj.examples);
} else if (obj.example) {
mergedObj.examples = [];
} else if (Array.isArray(types[obj.type].examples)) {
mergedObj.examples = [...types[obj.type].examples];
} else if (_isObject(types[obj.type].examples)) {
mergedObj.examples = _objectToArray(types[obj.type].examples);
}
Object.assign(obj, mergedObj);
ignoredKeys.type = true;
}
}
if (obj.items && types && types[obj.items]) {
obj.items = types[obj.items];
ignoredKeys.items = true;
}
if (obj.structuredExample) {
if (typeof obj.examples === 'undefined') {
obj.examples = [];
}
obj.examples.push(obj.structuredExample);
delete obj.example;
delete obj.structuredExample;
}
if (obj.examples && obj.examples.length) {
obj.examples = obj.examples.map(example => {
if (!example.value) {
return { value: example };
}
if (!example.displayName && example.name) {
example.displayName = example.name;
}
return example;
});
}
// Give each security scheme a displayName if it isn't already set
if (obj.securitySchemes) {
Object.keys(obj.securitySchemes).forEach(schemeName => {
const scheme = obj.securitySchemes[schemeName];
scheme.displayName = scheme.displayName || scheme.name;
});
}
if (Array.isArray(obj.securedBy)) {
if (
obj.securedBy.length === 0 ||
obj.securedBy.every(scheme => scheme === null)
) {
// The RAML 1.0 spec allows that:
// "A securedBy node containing null as the array component indicates
// the method can be called without applying any security scheme."
delete obj.securedBy;
} else {
// Guarantee that all elements of the securedBy array are either null or
// objects containing a schemeName property (and an optional scopes property)
obj.securedBy = obj.securedBy.map(scheme => {
if (scheme === null) {
return null;
}
if (typeof scheme === 'string') {
return { schemeName: scheme };
}
const schemeName = Object.keys(scheme)[0];
return Object.assign({ schemeName }, scheme[schemeName] || {});
});
}
}
// Fix inconsistency between request headers and response headers from raml-1-parser.
// https://github.com/raml-org/raml-js-parser-2/issues/582
// TODO this issue is fixed since 26 Sep 2017, i.e. v1.1.32, could be removed
if (Array.isArray(obj.headers)) {
obj.headers.forEach(hdr => {
if (typeof hdr.key === 'undefined' && hdr.name) {
hdr.key = hdr.name;
}
});
}
Object.keys(obj).forEach(key => {
// Don't recurse into types, which have already been canonicalized.
if (!(key in ignoredKeys)) {
makeConsistent(obj[key], types);
}
});
} else if (Array.isArray(obj)) {
obj.forEach(value => {
makeConsistent(value, types);
});
}
return obj;
}
module.exports = makeConsistent;