@e22m4u/js-openapi 0.0.5
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/.c8rc +9 -0
- package/.commitlintrc +5 -0
- package/.editorconfig +13 -0
- package/.husky/commit-msg +1 -0
- package/.husky/pre-commit +6 -0
- package/.mocharc.json +4 -0
- package/.prettierrc +7 -0
- package/LICENSE +21 -0
- package/README.md +510 -0
- package/build-cjs.js +16 -0
- package/dist/cjs/index.cjs +2695 -0
- package/eslint.config.js +41 -0
- package/package.json +64 -0
- package/src/data-type/index.d.ts +1 -0
- package/src/data-type/index.js +1 -0
- package/src/data-type/infer-openapi-data-type.d.ts +30 -0
- package/src/data-type/infer-openapi-data-type.js +38 -0
- package/src/data-validation/data-format-validator-map.d.ts +13 -0
- package/src/data-validation/data-format-validator-map.js +36 -0
- package/src/data-validation/data-format-validator-map.spec.js +39 -0
- package/src/data-validation/data-format-validators.d.ts +84 -0
- package/src/data-validation/data-format-validators.js +217 -0
- package/src/data-validation/index.d.ts +3 -0
- package/src/data-validation/index.js +3 -0
- package/src/data-validation/validate-data-with-openapi-schema.d.ts +46 -0
- package/src/data-validation/validate-data-with-openapi-schema.js +1913 -0
- package/src/data-validation/validate-data-with-openapi-schema.spec.js +6953 -0
- package/src/errors/index.d.ts +1 -0
- package/src/errors/index.js +1 -0
- package/src/errors/oa-data-validation-error.d.ts +6 -0
- package/src/errors/oa-data-validation-error.js +6 -0
- package/src/errors/oa-data-validation-error.spec.js +17 -0
- package/src/index.d.ts +9 -0
- package/src/index.js +9 -0
- package/src/json-pointer/escape-json-pointer.d.ts +7 -0
- package/src/json-pointer/escape-json-pointer.js +18 -0
- package/src/json-pointer/escape-json-pointer.spec.js +36 -0
- package/src/json-pointer/index.d.ts +3 -0
- package/src/json-pointer/index.js +3 -0
- package/src/json-pointer/resolve-json-pointer.d.ts +10 -0
- package/src/json-pointer/resolve-json-pointer.js +83 -0
- package/src/json-pointer/resolve-json-pointer.spec.js +103 -0
- package/src/json-pointer/unescape-json-pointer.d.ts +8 -0
- package/src/json-pointer/unescape-json-pointer.js +18 -0
- package/src/json-pointer/unescape-json-pointer.spec.js +32 -0
- package/src/oa-document-builder.d.ts +312 -0
- package/src/oa-document-builder.js +450 -0
- package/src/oa-document-object/index.d.ts +1 -0
- package/src/oa-document-object/index.js +1 -0
- package/src/oa-document-object/validate-shallow-oa-document.d.ts +10 -0
- package/src/oa-document-object/validate-shallow-oa-document.js +209 -0
- package/src/oa-document-object/validate-shallow-oa-document.spec.js +362 -0
- package/src/oa-document-scope.d.ts +52 -0
- package/src/oa-document-scope.js +228 -0
- package/src/oa-reference-object/index.d.ts +3 -0
- package/src/oa-reference-object/index.js +3 -0
- package/src/oa-reference-object/is-oa-reference-object.d.ts +9 -0
- package/src/oa-reference-object/is-oa-reference-object.js +14 -0
- package/src/oa-reference-object/is-oa-reference-object.spec.js +19 -0
- package/src/oa-reference-object/oa-ref.d.ts +11 -0
- package/src/oa-reference-object/oa-ref.js +31 -0
- package/src/oa-reference-object/oa-ref.spec.js +56 -0
- package/src/oa-reference-object/resolve-oa-reference-object.d.ts +18 -0
- package/src/oa-reference-object/resolve-oa-reference-object.js +113 -0
- package/src/oa-reference-object/resolve-oa-reference-object.spec.js +233 -0
- package/src/oa-specification.d.ts +767 -0
- package/src/oa-specification.js +153 -0
- package/src/types.d.ts +4 -0
- package/src/utils/count-unicode.d.ts +11 -0
- package/src/utils/count-unicode.js +15 -0
- package/src/utils/index.d.ts +5 -0
- package/src/utils/index.js +5 -0
- package/src/utils/join-path.d.ts +6 -0
- package/src/utils/join-path.js +36 -0
- package/src/utils/join-path.spec.js +104 -0
- package/src/utils/normalize-path.d.ts +12 -0
- package/src/utils/normalize-path.js +22 -0
- package/src/utils/normalize-path.spec.js +56 -0
- package/src/utils/to-pascal-case.d.ts +6 -0
- package/src/utils/to-pascal-case.js +26 -0
- package/src/utils/to-pascal-case.spec.js +15 -0
- package/src/utils/to-spaced-json.d.ts +17 -0
- package/src/utils/to-spaced-json.js +27 -0
- package/tsconfig.json +14 -0
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
import {expect} from 'chai';
|
|
2
|
+
import {format} from '@e22m4u/js-format';
|
|
3
|
+
import {OPENAPI_VERSION} from '../oa-specification.js';
|
|
4
|
+
import {validateShallowOADocument} from './validate-shallow-oa-document.js';
|
|
5
|
+
|
|
6
|
+
const MINIMAL_DOCUMENT = {
|
|
7
|
+
openapi: OPENAPI_VERSION,
|
|
8
|
+
info: {title: 'API Documentation', version: '0.0.1'},
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
describe('validateShallowOADocument', function () {
|
|
12
|
+
it('should require the first parameter to be an Object', function () {
|
|
13
|
+
const throwable = v => () => validateShallowOADocument(v);
|
|
14
|
+
const error = s =>
|
|
15
|
+
format('OpenAPI Document Object must be an Object, but %s was given.', s);
|
|
16
|
+
expect(throwable('str')).to.throw(error('"str"'));
|
|
17
|
+
expect(throwable('')).to.throw(error('""'));
|
|
18
|
+
expect(throwable(10)).to.throw(error('10'));
|
|
19
|
+
expect(throwable(0)).to.throw(error('0'));
|
|
20
|
+
expect(throwable(true)).to.throw(error('true'));
|
|
21
|
+
expect(throwable(false)).to.throw(error('false'));
|
|
22
|
+
expect(throwable([])).to.throw(error('Array'));
|
|
23
|
+
expect(throwable(undefined)).to.throw(error('undefined'));
|
|
24
|
+
expect(throwable(null)).to.throw(error('null'));
|
|
25
|
+
throwable(MINIMAL_DOCUMENT)();
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('should require the "openapi" property to be a non-empty String', function () {
|
|
29
|
+
const throwable = v => () =>
|
|
30
|
+
validateShallowOADocument({
|
|
31
|
+
...MINIMAL_DOCUMENT,
|
|
32
|
+
openapi: v,
|
|
33
|
+
});
|
|
34
|
+
const error = s =>
|
|
35
|
+
format(
|
|
36
|
+
'Property "openapi" must be a non-empty String, but %s was given.',
|
|
37
|
+
s,
|
|
38
|
+
);
|
|
39
|
+
expect(throwable('')).to.throw(error('""'));
|
|
40
|
+
expect(throwable(10)).to.throw(error('10'));
|
|
41
|
+
expect(throwable(0)).to.throw(error('0'));
|
|
42
|
+
expect(throwable(true)).to.throw(error('true'));
|
|
43
|
+
expect(throwable(false)).to.throw(error('false'));
|
|
44
|
+
expect(throwable([])).to.throw(error('Array'));
|
|
45
|
+
expect(throwable({})).to.throw(error('Object'));
|
|
46
|
+
expect(throwable(undefined)).to.throw(error('undefined'));
|
|
47
|
+
expect(throwable(null)).to.throw(error('null'));
|
|
48
|
+
throwable('3.1.0')();
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('should require the "info" property to be an Object', function () {
|
|
52
|
+
const throwable = v => () =>
|
|
53
|
+
validateShallowOADocument({
|
|
54
|
+
openapi: OPENAPI_VERSION,
|
|
55
|
+
info: v,
|
|
56
|
+
});
|
|
57
|
+
const error = s =>
|
|
58
|
+
format('Property "info" must be an Object, but %s was given.', s);
|
|
59
|
+
expect(throwable('str')).to.throw(error('"str"'));
|
|
60
|
+
expect(throwable('')).to.throw(error('""'));
|
|
61
|
+
expect(throwable(10)).to.throw(error('10'));
|
|
62
|
+
expect(throwable(0)).to.throw(error('0'));
|
|
63
|
+
expect(throwable(true)).to.throw(error('true'));
|
|
64
|
+
expect(throwable(false)).to.throw(error('false'));
|
|
65
|
+
expect(throwable([])).to.throw(error('Array'));
|
|
66
|
+
expect(throwable(undefined)).to.throw(error('undefined'));
|
|
67
|
+
expect(throwable(null)).to.throw(error('null'));
|
|
68
|
+
throwable({title: 'API Documentation', version: '0.0.1'})();
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it('should require the "info.title" property to be a non-empty String', function () {
|
|
72
|
+
const throwable = v => () =>
|
|
73
|
+
validateShallowOADocument({
|
|
74
|
+
openapi: OPENAPI_VERSION,
|
|
75
|
+
info: {
|
|
76
|
+
title: v,
|
|
77
|
+
version: '0.0.1',
|
|
78
|
+
},
|
|
79
|
+
});
|
|
80
|
+
const error = s =>
|
|
81
|
+
format(
|
|
82
|
+
'Property "info.title" must be a non-empty String, but %s was given.',
|
|
83
|
+
s,
|
|
84
|
+
);
|
|
85
|
+
expect(throwable('')).to.throw(error('""'));
|
|
86
|
+
expect(throwable(10)).to.throw(error('10'));
|
|
87
|
+
expect(throwable(0)).to.throw(error('0'));
|
|
88
|
+
expect(throwable(true)).to.throw(error('true'));
|
|
89
|
+
expect(throwable(false)).to.throw(error('false'));
|
|
90
|
+
expect(throwable([])).to.throw(error('Array'));
|
|
91
|
+
expect(throwable({})).to.throw(error('Object'));
|
|
92
|
+
expect(throwable(undefined)).to.throw(error('undefined'));
|
|
93
|
+
expect(throwable(null)).to.throw(error('null'));
|
|
94
|
+
throwable('API Documentation')();
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it('should require the "jsonSchemaDialect" property to be a non-empty String', function () {
|
|
98
|
+
const throwable = v => () =>
|
|
99
|
+
validateShallowOADocument({
|
|
100
|
+
...MINIMAL_DOCUMENT,
|
|
101
|
+
jsonSchemaDialect: v,
|
|
102
|
+
});
|
|
103
|
+
const error = s =>
|
|
104
|
+
format(
|
|
105
|
+
'Property "jsonSchemaDialect" must be a non-empty String, but %s was given.',
|
|
106
|
+
s,
|
|
107
|
+
);
|
|
108
|
+
expect(throwable('')).to.throw(error('""'));
|
|
109
|
+
expect(throwable(10)).to.throw(error('10'));
|
|
110
|
+
expect(throwable(0)).to.throw(error('0'));
|
|
111
|
+
expect(throwable(true)).to.throw(error('true'));
|
|
112
|
+
expect(throwable(false)).to.throw(error('false'));
|
|
113
|
+
expect(throwable([])).to.throw(error('Array'));
|
|
114
|
+
expect(throwable({})).to.throw(error('Object'));
|
|
115
|
+
expect(throwable(null)).to.throw(error('null'));
|
|
116
|
+
throwable('https://json-schema.org/draft/2020-12/schema')();
|
|
117
|
+
throwable(undefined)();
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it('should require the "servers" property to be an Array', function () {
|
|
121
|
+
const throwable = v => () =>
|
|
122
|
+
validateShallowOADocument({
|
|
123
|
+
...MINIMAL_DOCUMENT,
|
|
124
|
+
servers: v,
|
|
125
|
+
});
|
|
126
|
+
const error = s =>
|
|
127
|
+
format('Property "servers" must be an Array, but %s was given.', s);
|
|
128
|
+
expect(throwable('str')).to.throw(error('"str"'));
|
|
129
|
+
expect(throwable('')).to.throw(error('""'));
|
|
130
|
+
expect(throwable(10)).to.throw(error('10'));
|
|
131
|
+
expect(throwable(0)).to.throw(error('0'));
|
|
132
|
+
expect(throwable(true)).to.throw(error('true'));
|
|
133
|
+
expect(throwable(false)).to.throw(error('false'));
|
|
134
|
+
expect(throwable({})).to.throw(error('Object'));
|
|
135
|
+
expect(throwable(null)).to.throw(error('null'));
|
|
136
|
+
throwable([{url: 'http://localhost'}])();
|
|
137
|
+
throwable([])();
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
it('should require elements of the "servers" property to be an Object', function () {
|
|
141
|
+
const throwable = v => () =>
|
|
142
|
+
validateShallowOADocument({
|
|
143
|
+
...MINIMAL_DOCUMENT,
|
|
144
|
+
servers: [v],
|
|
145
|
+
});
|
|
146
|
+
const error = s =>
|
|
147
|
+
format('Element "servers[0]" must be an Object, but %s was given.', s);
|
|
148
|
+
expect(throwable('str')).to.throw(error('"str"'));
|
|
149
|
+
expect(throwable('')).to.throw(error('""'));
|
|
150
|
+
expect(throwable(10)).to.throw(error('10'));
|
|
151
|
+
expect(throwable(0)).to.throw(error('0'));
|
|
152
|
+
expect(throwable(true)).to.throw(error('true'));
|
|
153
|
+
expect(throwable(false)).to.throw(error('false'));
|
|
154
|
+
expect(throwable([])).to.throw(error('Array'));
|
|
155
|
+
expect(throwable(null)).to.throw(error('null'));
|
|
156
|
+
throwable({url: 'http://localhost'})();
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
it('should require the "servers[n].url" property to be a non-empty String', function () {
|
|
160
|
+
const throwable = v => () =>
|
|
161
|
+
validateShallowOADocument({
|
|
162
|
+
...MINIMAL_DOCUMENT,
|
|
163
|
+
servers: [{url: v}],
|
|
164
|
+
});
|
|
165
|
+
const error = s =>
|
|
166
|
+
format(
|
|
167
|
+
'Property "servers[0].url" must be a non-empty String, ' +
|
|
168
|
+
'but %s was given.',
|
|
169
|
+
s,
|
|
170
|
+
);
|
|
171
|
+
expect(throwable('')).to.throw(error('""'));
|
|
172
|
+
expect(throwable(10)).to.throw(error('10'));
|
|
173
|
+
expect(throwable(0)).to.throw(error('0'));
|
|
174
|
+
expect(throwable(true)).to.throw(error('true'));
|
|
175
|
+
expect(throwable(false)).to.throw(error('false'));
|
|
176
|
+
expect(throwable([])).to.throw(error('Array'));
|
|
177
|
+
expect(throwable({})).to.throw(error('Object'));
|
|
178
|
+
expect(throwable(undefined)).to.throw(error('undefined'));
|
|
179
|
+
expect(throwable(null)).to.throw(error('null'));
|
|
180
|
+
throwable('http://localhost')();
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
it('should require the "paths" property to be an Object', function () {
|
|
184
|
+
const throwable = v => () =>
|
|
185
|
+
validateShallowOADocument({
|
|
186
|
+
...MINIMAL_DOCUMENT,
|
|
187
|
+
paths: v,
|
|
188
|
+
});
|
|
189
|
+
const error = s =>
|
|
190
|
+
format('Property "paths" must be an Object, but %s was given.', s);
|
|
191
|
+
expect(throwable('str')).to.throw(error('"str"'));
|
|
192
|
+
expect(throwable('')).to.throw(error('""'));
|
|
193
|
+
expect(throwable(10)).to.throw(error('10'));
|
|
194
|
+
expect(throwable(0)).to.throw(error('0'));
|
|
195
|
+
expect(throwable(true)).to.throw(error('true'));
|
|
196
|
+
expect(throwable(false)).to.throw(error('false'));
|
|
197
|
+
expect(throwable([])).to.throw(error('Array'));
|
|
198
|
+
expect(throwable(null)).to.throw(error('null'));
|
|
199
|
+
throwable({})();
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
it('should require the "webhooks" property to be an Object', function () {
|
|
203
|
+
const throwable = v => () =>
|
|
204
|
+
validateShallowOADocument({
|
|
205
|
+
...MINIMAL_DOCUMENT,
|
|
206
|
+
webhooks: v,
|
|
207
|
+
});
|
|
208
|
+
const error = s =>
|
|
209
|
+
format('Property "webhooks" must be an Object, but %s was given.', s);
|
|
210
|
+
expect(throwable('str')).to.throw(error('"str"'));
|
|
211
|
+
expect(throwable('')).to.throw(error('""'));
|
|
212
|
+
expect(throwable(10)).to.throw(error('10'));
|
|
213
|
+
expect(throwable(0)).to.throw(error('0'));
|
|
214
|
+
expect(throwable(true)).to.throw(error('true'));
|
|
215
|
+
expect(throwable(false)).to.throw(error('false'));
|
|
216
|
+
expect(throwable([])).to.throw(error('Array'));
|
|
217
|
+
expect(throwable(null)).to.throw(error('null'));
|
|
218
|
+
throwable({})();
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
it('should require the "components" property to be an Object', function () {
|
|
222
|
+
const throwable = v => () =>
|
|
223
|
+
validateShallowOADocument({
|
|
224
|
+
...MINIMAL_DOCUMENT,
|
|
225
|
+
components: v,
|
|
226
|
+
});
|
|
227
|
+
const error = s =>
|
|
228
|
+
format('Property "components" must be an Object, but %s was given.', s);
|
|
229
|
+
expect(throwable('str')).to.throw(error('"str"'));
|
|
230
|
+
expect(throwable('')).to.throw(error('""'));
|
|
231
|
+
expect(throwable(10)).to.throw(error('10'));
|
|
232
|
+
expect(throwable(0)).to.throw(error('0'));
|
|
233
|
+
expect(throwable(true)).to.throw(error('true'));
|
|
234
|
+
expect(throwable(false)).to.throw(error('false'));
|
|
235
|
+
expect(throwable([])).to.throw(error('Array'));
|
|
236
|
+
expect(throwable(null)).to.throw(error('null'));
|
|
237
|
+
throwable({})();
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
it('should require the "security" property to be an Array', function () {
|
|
241
|
+
const throwable = v => () =>
|
|
242
|
+
validateShallowOADocument({
|
|
243
|
+
...MINIMAL_DOCUMENT,
|
|
244
|
+
security: v,
|
|
245
|
+
});
|
|
246
|
+
const error = s =>
|
|
247
|
+
format('Property "security" must be an Array, but %s was given.', s);
|
|
248
|
+
expect(throwable('str')).to.throw(error('"str"'));
|
|
249
|
+
expect(throwable('')).to.throw(error('""'));
|
|
250
|
+
expect(throwable(10)).to.throw(error('10'));
|
|
251
|
+
expect(throwable(0)).to.throw(error('0'));
|
|
252
|
+
expect(throwable(true)).to.throw(error('true'));
|
|
253
|
+
expect(throwable(false)).to.throw(error('false'));
|
|
254
|
+
expect(throwable({})).to.throw(error('Object'));
|
|
255
|
+
expect(throwable(null)).to.throw(error('null'));
|
|
256
|
+
throwable([{}])();
|
|
257
|
+
throwable([])();
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
it('should require elements of the "security" property to be an Object', function () {
|
|
261
|
+
const throwable = v => () =>
|
|
262
|
+
validateShallowOADocument({
|
|
263
|
+
...MINIMAL_DOCUMENT,
|
|
264
|
+
security: [v],
|
|
265
|
+
});
|
|
266
|
+
const error = s =>
|
|
267
|
+
format('Element "security[0]" must be an Object, but %s was given.', s);
|
|
268
|
+
expect(throwable('str')).to.throw(error('"str"'));
|
|
269
|
+
expect(throwable('')).to.throw(error('""'));
|
|
270
|
+
expect(throwable(10)).to.throw(error('10'));
|
|
271
|
+
expect(throwable(0)).to.throw(error('0'));
|
|
272
|
+
expect(throwable(true)).to.throw(error('true'));
|
|
273
|
+
expect(throwable(false)).to.throw(error('false'));
|
|
274
|
+
expect(throwable([])).to.throw(error('Array'));
|
|
275
|
+
expect(throwable(null)).to.throw(error('null'));
|
|
276
|
+
throwable({apiKey: []})();
|
|
277
|
+
throwable({})();
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
it('should require the "tags" property to be an Array', function () {
|
|
281
|
+
const throwable = v => () =>
|
|
282
|
+
validateShallowOADocument({
|
|
283
|
+
...MINIMAL_DOCUMENT,
|
|
284
|
+
tags: v,
|
|
285
|
+
});
|
|
286
|
+
const error = s =>
|
|
287
|
+
format('Property "tags" must be an Array, but %s was given.', s);
|
|
288
|
+
expect(throwable('str')).to.throw(error('"str"'));
|
|
289
|
+
expect(throwable('')).to.throw(error('""'));
|
|
290
|
+
expect(throwable(10)).to.throw(error('10'));
|
|
291
|
+
expect(throwable(0)).to.throw(error('0'));
|
|
292
|
+
expect(throwable(true)).to.throw(error('true'));
|
|
293
|
+
expect(throwable(false)).to.throw(error('false'));
|
|
294
|
+
expect(throwable({})).to.throw(error('Object'));
|
|
295
|
+
expect(throwable(null)).to.throw(error('null'));
|
|
296
|
+
throwable([{name: 'tag'}])();
|
|
297
|
+
throwable([])();
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
it('should require elements of the "tags" property to be an Object', function () {
|
|
301
|
+
const throwable = v => () =>
|
|
302
|
+
validateShallowOADocument({
|
|
303
|
+
...MINIMAL_DOCUMENT,
|
|
304
|
+
tags: [v],
|
|
305
|
+
});
|
|
306
|
+
const error = s =>
|
|
307
|
+
format('Element "tags[0]" must be an Object, but %s was given.', s);
|
|
308
|
+
expect(throwable('str')).to.throw(error('"str"'));
|
|
309
|
+
expect(throwable('')).to.throw(error('""'));
|
|
310
|
+
expect(throwable(10)).to.throw(error('10'));
|
|
311
|
+
expect(throwable(0)).to.throw(error('0'));
|
|
312
|
+
expect(throwable(true)).to.throw(error('true'));
|
|
313
|
+
expect(throwable(false)).to.throw(error('false'));
|
|
314
|
+
expect(throwable([])).to.throw(error('Array'));
|
|
315
|
+
expect(throwable(null)).to.throw(error('null'));
|
|
316
|
+
throwable({name: 'tag'})();
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
it('should require the "tags[n].name" property to be a non-empty String', function () {
|
|
320
|
+
const throwable = v => () =>
|
|
321
|
+
validateShallowOADocument({
|
|
322
|
+
...MINIMAL_DOCUMENT,
|
|
323
|
+
tags: [{name: v}],
|
|
324
|
+
});
|
|
325
|
+
const error = s =>
|
|
326
|
+
format(
|
|
327
|
+
'Property "tags[0].name" must be a non-empty String, ' +
|
|
328
|
+
'but %s was given.',
|
|
329
|
+
s,
|
|
330
|
+
);
|
|
331
|
+
expect(throwable('')).to.throw(error('""'));
|
|
332
|
+
expect(throwable(10)).to.throw(error('10'));
|
|
333
|
+
expect(throwable(0)).to.throw(error('0'));
|
|
334
|
+
expect(throwable(true)).to.throw(error('true'));
|
|
335
|
+
expect(throwable(false)).to.throw(error('false'));
|
|
336
|
+
expect(throwable([])).to.throw(error('Array'));
|
|
337
|
+
expect(throwable({})).to.throw(error('Object'));
|
|
338
|
+
expect(throwable(undefined)).to.throw(error('undefined'));
|
|
339
|
+
expect(throwable(null)).to.throw(error('null'));
|
|
340
|
+
throwable('tag')();
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
it('should require the "externalDocs" property to be an Object', function () {
|
|
344
|
+
const throwable = v => () =>
|
|
345
|
+
validateShallowOADocument({
|
|
346
|
+
...MINIMAL_DOCUMENT,
|
|
347
|
+
externalDocs: v,
|
|
348
|
+
});
|
|
349
|
+
const error = s =>
|
|
350
|
+
format('Property "externalDocs" must be an Object, but %s was given.', s);
|
|
351
|
+
expect(throwable('str')).to.throw(error('"str"'));
|
|
352
|
+
expect(throwable('')).to.throw(error('""'));
|
|
353
|
+
expect(throwable(10)).to.throw(error('10'));
|
|
354
|
+
expect(throwable(0)).to.throw(error('0'));
|
|
355
|
+
expect(throwable(true)).to.throw(error('true'));
|
|
356
|
+
expect(throwable(false)).to.throw(error('false'));
|
|
357
|
+
expect(throwable([])).to.throw(error('Array'));
|
|
358
|
+
expect(throwable(null)).to.throw(error('null'));
|
|
359
|
+
throwable({url: 'https://example.com'})();
|
|
360
|
+
throwable(undefined)();
|
|
361
|
+
});
|
|
362
|
+
});
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import {
|
|
2
|
+
OADocumentBuilder,
|
|
3
|
+
OAOperationDefinition,
|
|
4
|
+
} from './oa-document-builder.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Document scope options.
|
|
8
|
+
*/
|
|
9
|
+
export type OADocumentScopeOptions = {
|
|
10
|
+
pathPrefix?: string;
|
|
11
|
+
tags?: string[];
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Document scope.
|
|
16
|
+
*/
|
|
17
|
+
export declare class OADocumentScope {
|
|
18
|
+
/**
|
|
19
|
+
* @param builder
|
|
20
|
+
* @param options
|
|
21
|
+
*/
|
|
22
|
+
constructor(builder: OADocumentBuilder, options?: OADocumentScopeOptions);
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Get builder.
|
|
26
|
+
*/
|
|
27
|
+
getBuilder(): OADocumentBuilder;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Get path prefix.
|
|
31
|
+
*/
|
|
32
|
+
getPathPrefix(): string;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Get tags.
|
|
36
|
+
*/
|
|
37
|
+
getTags(): string[];
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Define operation.
|
|
41
|
+
*
|
|
42
|
+
* @param operationDef
|
|
43
|
+
*/
|
|
44
|
+
defineOperation(operationDef: OAOperationDefinition): this;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Create scope.
|
|
48
|
+
*
|
|
49
|
+
* @param options
|
|
50
|
+
*/
|
|
51
|
+
createScope(options?: OADocumentScopeOptions): OADocumentScope;
|
|
52
|
+
}
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
import {InvalidArgumentError} from '@e22m4u/js-format';
|
|
2
|
+
import {OAOperationMethod} from './oa-specification.js';
|
|
3
|
+
import {joinPath, normalizePath} from './utils/index.js';
|
|
4
|
+
import {OADocumentBuilder} from './oa-document-builder.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Document scope.
|
|
8
|
+
*/
|
|
9
|
+
export class OADocumentScope {
|
|
10
|
+
/**
|
|
11
|
+
* Builder.
|
|
12
|
+
*
|
|
13
|
+
* @type {OADocumentBuilder}
|
|
14
|
+
*/
|
|
15
|
+
_builder;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Path prefix.
|
|
19
|
+
*
|
|
20
|
+
* @type {string}
|
|
21
|
+
*/
|
|
22
|
+
_pathPrefix;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Tags.
|
|
26
|
+
*
|
|
27
|
+
* @type {string[]}
|
|
28
|
+
*/
|
|
29
|
+
_tags;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* @param {object} builder
|
|
33
|
+
* @param {object} [options]
|
|
34
|
+
*/
|
|
35
|
+
constructor(builder, options = {}) {
|
|
36
|
+
// builder
|
|
37
|
+
if (!(builder instanceof OADocumentBuilder)) {
|
|
38
|
+
throw new InvalidArgumentError(
|
|
39
|
+
'Parameter "builder" must be an instance of OADocumentBuilder, ' +
|
|
40
|
+
'but %v was given.',
|
|
41
|
+
builder,
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
// options
|
|
45
|
+
if (!options || typeof options !== 'object' || Array.isArray(options)) {
|
|
46
|
+
throw new InvalidArgumentError(
|
|
47
|
+
'Parameter "options" must be an Object, but %v was given.',
|
|
48
|
+
options,
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
// options.pathPrefix
|
|
52
|
+
if (options.pathPrefix !== undefined) {
|
|
53
|
+
if (!options.pathPrefix || typeof options.pathPrefix !== 'string') {
|
|
54
|
+
throw new InvalidArgumentError(
|
|
55
|
+
'Property "pathPrefix" must be a non-empty String, ' +
|
|
56
|
+
'but %v was given.',
|
|
57
|
+
options.pathPrefix,
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
// options.tags
|
|
62
|
+
if (options.tags !== undefined) {
|
|
63
|
+
if (!Array.isArray(options.tags)) {
|
|
64
|
+
throw new InvalidArgumentError(
|
|
65
|
+
'Property "tags" must be an Array, but %v was given.',
|
|
66
|
+
options.tags,
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
options.tags.forEach((tag, index) => {
|
|
70
|
+
if (!tag || typeof tag !== 'string') {
|
|
71
|
+
throw new InvalidArgumentError(
|
|
72
|
+
'Element "tags[%d]" must be a non-empty String, but %v was given.',
|
|
73
|
+
index,
|
|
74
|
+
tag,
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
this._builder = builder;
|
|
80
|
+
this._pathPrefix = normalizePath(options.pathPrefix || '/');
|
|
81
|
+
this._tags = options.tags || [];
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Get builder.
|
|
86
|
+
*
|
|
87
|
+
* @returns {OADocumentBuilder}
|
|
88
|
+
*/
|
|
89
|
+
getBuilder() {
|
|
90
|
+
return this._builder;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Get path prefix.
|
|
95
|
+
*
|
|
96
|
+
* @returns {string}
|
|
97
|
+
*/
|
|
98
|
+
getPathPrefix() {
|
|
99
|
+
return this._pathPrefix;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Get tags.
|
|
104
|
+
*
|
|
105
|
+
* @returns {string[]}
|
|
106
|
+
*/
|
|
107
|
+
getTags() {
|
|
108
|
+
return [...this._tags];
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Define operation.
|
|
113
|
+
*
|
|
114
|
+
* @param {object} operationDef
|
|
115
|
+
* @returns {this}
|
|
116
|
+
*/
|
|
117
|
+
defineOperation(operationDef) {
|
|
118
|
+
if (
|
|
119
|
+
!operationDef ||
|
|
120
|
+
typeof operationDef !== 'object' ||
|
|
121
|
+
Array.isArray(operationDef)
|
|
122
|
+
) {
|
|
123
|
+
throw new InvalidArgumentError(
|
|
124
|
+
'Operation Definition must be an Object, but %v was given.',
|
|
125
|
+
operationDef,
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
// path
|
|
129
|
+
if (!operationDef.path || typeof operationDef.path !== 'string') {
|
|
130
|
+
throw new InvalidArgumentError(
|
|
131
|
+
'Property "path" must be a non-empty String, but %v was given.',
|
|
132
|
+
operationDef.path,
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
// method
|
|
136
|
+
if (!operationDef.method || typeof operationDef.method !== 'string') {
|
|
137
|
+
throw new InvalidArgumentError(
|
|
138
|
+
'Property "method" must be a non-empty String, but %v was given.',
|
|
139
|
+
operationDef.method,
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
if (!Object.values(OAOperationMethod).includes(operationDef.method)) {
|
|
143
|
+
throw new InvalidArgumentError(
|
|
144
|
+
'Property "method" must be one of values: %l, but %v was given.',
|
|
145
|
+
Object.values(OAOperationMethod),
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
// operation
|
|
149
|
+
if (
|
|
150
|
+
!operationDef.operation ||
|
|
151
|
+
typeof operationDef.operation !== 'object' ||
|
|
152
|
+
Array.isArray(operationDef.operation)
|
|
153
|
+
) {
|
|
154
|
+
throw new InvalidArgumentError(
|
|
155
|
+
'Property "operation" must be an Object, but %v was given.',
|
|
156
|
+
operationDef.operation,
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
// склеивание пути
|
|
160
|
+
const fullPath = joinPath(this._pathPrefix, operationDef.path);
|
|
161
|
+
// создание копии схемы операции
|
|
162
|
+
// чтобы избежать мутацию аргумента
|
|
163
|
+
const operation = structuredClone(operationDef.operation);
|
|
164
|
+
// объединение тегов текущей области
|
|
165
|
+
// с тегами текущей операции и удаление
|
|
166
|
+
// дубликатов
|
|
167
|
+
if (this._tags.length > 0) {
|
|
168
|
+
operation.tags = [...this._tags, ...(operation.tags || [])];
|
|
169
|
+
operation.tags = [...new Set(operation.tags)];
|
|
170
|
+
}
|
|
171
|
+
// регистрация операции в родительском
|
|
172
|
+
// экземпляре сборщика документа
|
|
173
|
+
this._builder.defineOperation({
|
|
174
|
+
...operationDef,
|
|
175
|
+
path: fullPath,
|
|
176
|
+
operation,
|
|
177
|
+
});
|
|
178
|
+
return this;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Create scope.
|
|
183
|
+
*
|
|
184
|
+
* @param {object} [options]
|
|
185
|
+
* @returns {OADocumentScope}
|
|
186
|
+
*/
|
|
187
|
+
createScope(options = {}) {
|
|
188
|
+
// options
|
|
189
|
+
if (!options || typeof options !== 'object' || Array.isArray(options)) {
|
|
190
|
+
throw new InvalidArgumentError(
|
|
191
|
+
'Parameter "options" must be an Object, but %v was given.',
|
|
192
|
+
options,
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
// options.pathPrefix
|
|
196
|
+
if (options.pathPrefix !== undefined) {
|
|
197
|
+
if (!options.pathPrefix || typeof options.pathPrefix !== 'string') {
|
|
198
|
+
throw new InvalidArgumentError(
|
|
199
|
+
'Property "pathPrefix" must be a non-empty String, ' +
|
|
200
|
+
'but %v was given.',
|
|
201
|
+
options.pathPrefix,
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
// options.tags
|
|
206
|
+
if (options.tags !== undefined) {
|
|
207
|
+
if (!Array.isArray(options.tags)) {
|
|
208
|
+
throw new InvalidArgumentError(
|
|
209
|
+
'Property "tags" must be an Array, but %v was given.',
|
|
210
|
+
options.tags,
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
options.tags.forEach((tag, index) => {
|
|
214
|
+
if (!tag || typeof tag !== 'string') {
|
|
215
|
+
throw new InvalidArgumentError(
|
|
216
|
+
'Element "tags[%d]" must be a non-empty String, but %v was given.',
|
|
217
|
+
index,
|
|
218
|
+
tag,
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
return new OADocumentScope(this._builder, {
|
|
224
|
+
pathPrefix: joinPath(this._pathPrefix, options.pathPrefix),
|
|
225
|
+
tags: [...this._tags, ...(options.tags || [])],
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Is OpenAPI Reference Object.
|
|
3
|
+
*
|
|
4
|
+
* @param {*} value
|
|
5
|
+
* @returns {boolean}
|
|
6
|
+
*/
|
|
7
|
+
export function isOAReferenceObject(value) {
|
|
8
|
+
if (value && typeof value === 'object' && !Array.isArray(value)) {
|
|
9
|
+
if (value.$ref !== undefined || value.$dynamicRef !== undefined) {
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import {expect} from 'chai';
|
|
2
|
+
import {isOAReferenceObject} from './is-oa-reference-object.js';
|
|
3
|
+
|
|
4
|
+
describe('isOAReferenceObject', function () {
|
|
5
|
+
it('should return true when the given value is a reference object', function () {
|
|
6
|
+
expect(isOAReferenceObject('str')).to.be.false;
|
|
7
|
+
expect(isOAReferenceObject('')).to.be.false;
|
|
8
|
+
expect(isOAReferenceObject(10)).to.be.false;
|
|
9
|
+
expect(isOAReferenceObject(0)).to.be.false;
|
|
10
|
+
expect(isOAReferenceObject(true)).to.be.false;
|
|
11
|
+
expect(isOAReferenceObject(false)).to.be.false;
|
|
12
|
+
expect(isOAReferenceObject({})).to.be.false;
|
|
13
|
+
expect(isOAReferenceObject([])).to.be.false;
|
|
14
|
+
expect(isOAReferenceObject(undefined)).to.be.false;
|
|
15
|
+
expect(isOAReferenceObject(null)).to.be.false;
|
|
16
|
+
expect(isOAReferenceObject({$ref: '123'})).to.be.true;
|
|
17
|
+
expect(isOAReferenceObject({$dynamicRef: '123'})).to.be.true;
|
|
18
|
+
});
|
|
19
|
+
});
|