@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,11 @@
|
|
|
1
|
+
import {OAReferenceObject} from '../oa-specification.js';
|
|
2
|
+
|
|
3
|
+
export declare const oaSchemaRef: (name: string) => OAReferenceObject;
|
|
4
|
+
export declare const oaResponseRef: (name: string) => OAReferenceObject;
|
|
5
|
+
export declare const oaParameterRef: (name: string) => OAReferenceObject;
|
|
6
|
+
export declare const oaExampleRef: (name: string) => OAReferenceObject;
|
|
7
|
+
export declare const oaRequestBodyRef: (name: string) => OAReferenceObject;
|
|
8
|
+
export declare const oaSecuritySchemeRef: (name: string) => OAReferenceObject;
|
|
9
|
+
export declare const oaLinkRef: (name: string) => OAReferenceObject;
|
|
10
|
+
export declare const oaCallbackRef: (name: string) => OAReferenceObject;
|
|
11
|
+
export declare const oaPathItemRef: (name: string) => OAReferenceObject;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import {InvalidArgumentError} from '@e22m4u/js-format';
|
|
2
|
+
import {escapeJsonPointer} from '../json-pointer/index.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Create the Reference Object.
|
|
6
|
+
*
|
|
7
|
+
* @param {string} name
|
|
8
|
+
* @param {string} segment
|
|
9
|
+
* @returns {object}
|
|
10
|
+
*/
|
|
11
|
+
function oaRef(name, segment) {
|
|
12
|
+
if (!name || typeof name !== 'string') {
|
|
13
|
+
throw new InvalidArgumentError(
|
|
14
|
+
'Parameter "name" must be a non-empty String, but %v was given.',
|
|
15
|
+
name,
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
const escapedName = escapeJsonPointer(name);
|
|
19
|
+
return {$ref: `#/components/${segment}/${escapedName}`};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/* aliases */
|
|
23
|
+
export const oaSchemaRef = name => oaRef(name, 'schemas');
|
|
24
|
+
export const oaResponseRef = name => oaRef(name, 'responses');
|
|
25
|
+
export const oaParameterRef = name => oaRef(name, 'parameters');
|
|
26
|
+
export const oaExampleRef = name => oaRef(name, 'examples');
|
|
27
|
+
export const oaRequestBodyRef = name => oaRef(name, 'requestBodies');
|
|
28
|
+
export const oaSecuritySchemeRef = name => oaRef(name, 'securitySchemes');
|
|
29
|
+
export const oaLinkRef = name => oaRef(name, 'links');
|
|
30
|
+
export const oaCallbackRef = name => oaRef(name, 'callbacks');
|
|
31
|
+
export const oaPathItemRef = name => oaRef(name, 'pathItems');
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import {expect} from 'chai';
|
|
2
|
+
import {format} from '@e22m4u/js-format';
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
oaLinkRef,
|
|
6
|
+
oaSchemaRef,
|
|
7
|
+
oaExampleRef,
|
|
8
|
+
oaResponseRef,
|
|
9
|
+
oaPathItemRef,
|
|
10
|
+
oaCallbackRef,
|
|
11
|
+
oaParameterRef,
|
|
12
|
+
oaRequestBodyRef,
|
|
13
|
+
oaSecuritySchemeRef,
|
|
14
|
+
} from './oa-ref.js';
|
|
15
|
+
|
|
16
|
+
const ALIASES_MAP = [
|
|
17
|
+
[oaSchemaRef, 'schemas'],
|
|
18
|
+
[oaResponseRef, 'responses'],
|
|
19
|
+
[oaParameterRef, 'parameters'],
|
|
20
|
+
[oaExampleRef, 'examples'],
|
|
21
|
+
[oaRequestBodyRef, 'requestBodies'],
|
|
22
|
+
[oaSecuritySchemeRef, 'securitySchemes'],
|
|
23
|
+
[oaLinkRef, 'links'],
|
|
24
|
+
[oaCallbackRef, 'callbacks'],
|
|
25
|
+
[oaPathItemRef, 'pathItems'],
|
|
26
|
+
];
|
|
27
|
+
|
|
28
|
+
describe('oaRef aliases', function () {
|
|
29
|
+
// eslint-disable-next-line mocha/no-setup-in-describe
|
|
30
|
+
ALIASES_MAP.forEach(([fn, segment]) => {
|
|
31
|
+
describe(fn.name, function () {
|
|
32
|
+
it('should require the "name" parameter to be a none-empty String', function () {
|
|
33
|
+
const throwable = v => () => fn(v);
|
|
34
|
+
const error = s =>
|
|
35
|
+
format(
|
|
36
|
+
'Parameter "name" 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('name')();
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('should return the correct reference', function () {
|
|
52
|
+
expect(fn('name')).to.be.eql({$ref: `#/components/${segment}/name`});
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import {OAReferenceObject} from '../oa-specification.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Разрешает объект ссылки (Reference Object) и возвращает целевое значение.
|
|
5
|
+
* Функция реализует навигацию по JSON Pointer (RFC 6901) внутри корневого
|
|
6
|
+
* документа `options.rootDocument`. Утилита находит и возвращает узел, на который
|
|
7
|
+
* указывает `$ref`.
|
|
8
|
+
*
|
|
9
|
+
* - Поддерживает только локальные ссылки, начинающиеся с `#`.
|
|
10
|
+
* - Нет поддержки $dynamicRef, $anchor и $id.
|
|
11
|
+
*
|
|
12
|
+
* @param referenceObj
|
|
13
|
+
* @param options
|
|
14
|
+
*/
|
|
15
|
+
export function resolveOAReferenceObject<T = any>(
|
|
16
|
+
referenceObj: OAReferenceObject,
|
|
17
|
+
options?: {rootDocument?: object | unknown[]},
|
|
18
|
+
): T;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import {InvalidArgumentError} from '@e22m4u/js-format';
|
|
2
|
+
import {resolveJsonPointer} from '../json-pointer/index.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Разрешает объект ссылки (Reference Object) и возвращает целевое значение.
|
|
6
|
+
* Функция реализует навигацию по JSON Pointer (RFC 6901) внутри корневого
|
|
7
|
+
* документа `options.rootDocument`. Утилита находит и возвращает узел, на который
|
|
8
|
+
* указывает `$ref`.
|
|
9
|
+
*
|
|
10
|
+
* - Поддерживает только локальные ссылки, начинающиеся с `#`.
|
|
11
|
+
* - Нет поддержки $dynamicRef, $anchor и $id.
|
|
12
|
+
*
|
|
13
|
+
* @param {object} referenceObj
|
|
14
|
+
* @param {object} [options]
|
|
15
|
+
* @returns {*}
|
|
16
|
+
*/
|
|
17
|
+
export function resolveOAReferenceObject(referenceObj, options = {}) {
|
|
18
|
+
if (
|
|
19
|
+
!referenceObj ||
|
|
20
|
+
typeof referenceObj !== 'object' ||
|
|
21
|
+
Array.isArray(referenceObj)
|
|
22
|
+
) {
|
|
23
|
+
throw new InvalidArgumentError(
|
|
24
|
+
'Parameter "referenceObj" must be an Object, but %v was given.',
|
|
25
|
+
referenceObj,
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
// options
|
|
29
|
+
if (!options || typeof options !== 'object' || Array.isArray(options)) {
|
|
30
|
+
throw new InvalidArgumentError(
|
|
31
|
+
'Parameter "options" must be an Object, but %v was given.',
|
|
32
|
+
options,
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
// options.rootDocument
|
|
36
|
+
if (options.rootDocument !== undefined) {
|
|
37
|
+
if (!options.rootDocument || typeof options.rootDocument !== 'object') {
|
|
38
|
+
throw new InvalidArgumentError(
|
|
39
|
+
'Option "rootDocument" must be an Object or an Array, but %v was given.',
|
|
40
|
+
options.rootDocument,
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// $ref
|
|
45
|
+
if (referenceObj.$ref !== undefined) {
|
|
46
|
+
if (!referenceObj.$ref || typeof referenceObj.$ref !== 'string') {
|
|
47
|
+
throw new InvalidArgumentError(
|
|
48
|
+
'Schema keyword "$ref" must be a non-empty String, ' +
|
|
49
|
+
'but %v was given.',
|
|
50
|
+
referenceObj.$ref,
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
const refUri = referenceObj.$ref;
|
|
54
|
+
// если ссылка начинается с корня документа,
|
|
55
|
+
// то выполняется поиск указанного узла
|
|
56
|
+
if (refUri.startsWith('#')) {
|
|
57
|
+
if (!options.rootDocument) {
|
|
58
|
+
throw new InvalidArgumentError(
|
|
59
|
+
'Option "rootDocument" is required to resolve the same-document ' +
|
|
60
|
+
'reference (URI starts with "#").',
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
// если URI ссылается на корень документа (символ "#"),
|
|
64
|
+
// то возвращается корневой узел без поиска сегмента
|
|
65
|
+
if (refUri === '#') {
|
|
66
|
+
return options.rootDocument;
|
|
67
|
+
}
|
|
68
|
+
// если URI является JSON Pointer (прим. "#/path/to/element")
|
|
69
|
+
// то выполняется поиск узла согласно сегментам указателя
|
|
70
|
+
else if (refUri.startsWith('#/')) {
|
|
71
|
+
return resolveJsonPointer(options.rootDocument, refUri.substring(1));
|
|
72
|
+
}
|
|
73
|
+
// так как якорь (прим. "#SomeAnchor") требует обхода всего
|
|
74
|
+
// документа, в целях улучшения производительности данный
|
|
75
|
+
// функционал не будет реализован в утилитарной функции
|
|
76
|
+
throw new InvalidArgumentError(
|
|
77
|
+
'Anchor reference is not supported, but %v was given.',
|
|
78
|
+
refUri,
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
// удаленный ресурс (прим. "http://example.com/schema")
|
|
82
|
+
if (refUri.startsWith('http://') || refUri.startsWith('https://')) {
|
|
83
|
+
// так как разрешение внешних ссылок требует накладных расходов
|
|
84
|
+
// на производительность и кэширование, данный функционал
|
|
85
|
+
// не будет реализован в утилитарной функции
|
|
86
|
+
throw new InvalidArgumentError(
|
|
87
|
+
'External resource is not supported, but %v was given.',
|
|
88
|
+
refUri,
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
// так как для создания карты идентификаторов требуется обход
|
|
92
|
+
// всего документа, в целях повышения производительности данный
|
|
93
|
+
// функционал не будет реализован в утилитарной функции
|
|
94
|
+
throw new InvalidArgumentError(
|
|
95
|
+
'Relative reference is not supported, but %v was given.',
|
|
96
|
+
refUri,
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
// $dynamicRef
|
|
100
|
+
if (referenceObj.$dynamicRef) {
|
|
101
|
+
// поддержка $dynamicRef требует реализации динамической области
|
|
102
|
+
// видимости с отслеживанием стека вызовов при обходе схемы,
|
|
103
|
+
// но данная утилитарная функция выполняется без контекста
|
|
104
|
+
throw new InvalidArgumentError(
|
|
105
|
+
'Schema keyword "$dynamicRef" is not supported.',
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
// если объект ссылки не имеет свойств
|
|
109
|
+
// указателей, то выбрасывается ошибка
|
|
110
|
+
throw new InvalidArgumentError(
|
|
111
|
+
'Reference object does not have reference properties.',
|
|
112
|
+
);
|
|
113
|
+
}
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import {expect} from 'chai';
|
|
2
|
+
import {format} from '@e22m4u/js-format';
|
|
3
|
+
import {resolveOAReferenceObject} from './resolve-oa-reference-object.js';
|
|
4
|
+
|
|
5
|
+
describe('resolveOAReferenceObject', function () {
|
|
6
|
+
it('should require the parameter "referenceObj" to be an Object', function () {
|
|
7
|
+
const throwable = v => () =>
|
|
8
|
+
resolveOAReferenceObject(v, {rootDocument: {}});
|
|
9
|
+
const error = s =>
|
|
10
|
+
format(
|
|
11
|
+
'Parameter "referenceObj" must be an Object, but %s was given.',
|
|
12
|
+
s,
|
|
13
|
+
);
|
|
14
|
+
expect(throwable('str')).to.throw(error('"str"'));
|
|
15
|
+
expect(throwable('')).to.throw(error('""'));
|
|
16
|
+
expect(throwable(10)).to.throw(error('10'));
|
|
17
|
+
expect(throwable(0)).to.throw(error('0'));
|
|
18
|
+
expect(throwable(true)).to.throw(error('true'));
|
|
19
|
+
expect(throwable(false)).to.throw(error('false'));
|
|
20
|
+
expect(throwable([])).to.throw(error('Array'));
|
|
21
|
+
expect(throwable(undefined)).to.throw(error('undefined'));
|
|
22
|
+
expect(throwable(null)).to.throw(error('null'));
|
|
23
|
+
throwable({$ref: '#'})();
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('should require the parameter "options" to be an Object', function () {
|
|
27
|
+
const throwable = v => () => resolveOAReferenceObject({$ref: '#'}, v);
|
|
28
|
+
const error = s =>
|
|
29
|
+
format('Parameter "options" must be an Object, but %s was given.', s);
|
|
30
|
+
expect(throwable('str')).to.throw(error('"str"'));
|
|
31
|
+
expect(throwable('')).to.throw(error('""'));
|
|
32
|
+
expect(throwable(10)).to.throw(error('10'));
|
|
33
|
+
expect(throwable(0)).to.throw(error('0'));
|
|
34
|
+
expect(throwable(true)).to.throw(error('true'));
|
|
35
|
+
expect(throwable(false)).to.throw(error('false'));
|
|
36
|
+
expect(throwable([])).to.throw(error('Array'));
|
|
37
|
+
expect(throwable(null)).to.throw(error('null'));
|
|
38
|
+
throwable({rootDocument: {}})();
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('should require the option "rootDocument" to be an Object or an Array', function () {
|
|
42
|
+
const throwable = v => () =>
|
|
43
|
+
resolveOAReferenceObject({$ref: '#'}, {rootDocument: v});
|
|
44
|
+
const error = s =>
|
|
45
|
+
format(
|
|
46
|
+
'Option "rootDocument" must be an Object or an Array, but %s was given.',
|
|
47
|
+
s,
|
|
48
|
+
);
|
|
49
|
+
expect(throwable('str')).to.throw(error('"str"'));
|
|
50
|
+
expect(throwable('')).to.throw(error('""'));
|
|
51
|
+
expect(throwable(10)).to.throw(error('10'));
|
|
52
|
+
expect(throwable(0)).to.throw(error('0'));
|
|
53
|
+
expect(throwable(true)).to.throw(error('true'));
|
|
54
|
+
expect(throwable(false)).to.throw(error('false'));
|
|
55
|
+
expect(throwable(null)).to.throw(error('null'));
|
|
56
|
+
throwable([])();
|
|
57
|
+
throwable({})();
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it('should require at least one reference property', function () {
|
|
61
|
+
const throwable = () => resolveOAReferenceObject({});
|
|
62
|
+
expect(throwable).to.throw(
|
|
63
|
+
'Reference object does not have reference properties.',
|
|
64
|
+
);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
describe('$ref', function () {
|
|
68
|
+
it('should require the property "$ref" to be a non-empty String', function () {
|
|
69
|
+
const throwable = v => () =>
|
|
70
|
+
resolveOAReferenceObject({$ref: v}, {rootDocument: {}});
|
|
71
|
+
const error = s =>
|
|
72
|
+
format(
|
|
73
|
+
'Schema keyword "$ref" must be a non-empty String, ' +
|
|
74
|
+
'but %s was given.',
|
|
75
|
+
s,
|
|
76
|
+
);
|
|
77
|
+
expect(throwable('')).to.throw(error('""'));
|
|
78
|
+
expect(throwable(10)).to.throw(error('10'));
|
|
79
|
+
expect(throwable(0)).to.throw(error('0'));
|
|
80
|
+
expect(throwable(true)).to.throw(error('true'));
|
|
81
|
+
expect(throwable(false)).to.throw(error('false'));
|
|
82
|
+
expect(throwable([])).to.throw(error('Array'));
|
|
83
|
+
expect(throwable({})).to.throw(error('Object'));
|
|
84
|
+
expect(throwable(null)).to.throw(error('null'));
|
|
85
|
+
throwable('#')();
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
describe('a document reference (URI starts with "#")', function () {
|
|
89
|
+
it('should require the option "rootDocument" when resolving the same-document', function () {
|
|
90
|
+
const throwable = v => () => resolveOAReferenceObject({$ref: v});
|
|
91
|
+
['#', '#/', '#/path'].forEach(uri => {
|
|
92
|
+
expect(throwable(uri)).to.throw(
|
|
93
|
+
'Option "rootDocument" is required to resolve the same-document ' +
|
|
94
|
+
'reference (URI starts with "#").',
|
|
95
|
+
);
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it('should return the root document when resolving the root reference', function () {
|
|
100
|
+
const rootDocument = {};
|
|
101
|
+
const res = resolveOAReferenceObject({$ref: '#'}, {rootDocument});
|
|
102
|
+
expect(res).to.be.eq(rootDocument);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it('should return a node with an empty string key', function () {
|
|
106
|
+
const node = {foo: 'bar'};
|
|
107
|
+
const res1 = resolveOAReferenceObject(
|
|
108
|
+
{$ref: '#/'},
|
|
109
|
+
{rootDocument: {'': node}},
|
|
110
|
+
);
|
|
111
|
+
expect(res1).to.be.eq(node);
|
|
112
|
+
const res2 = resolveOAReferenceObject(
|
|
113
|
+
{$ref: '#/path/'},
|
|
114
|
+
{rootDocument: {path: {'': node}}},
|
|
115
|
+
);
|
|
116
|
+
expect(res2).to.be.eq(node);
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
it('should unescape segments of the json pointer', function () {
|
|
120
|
+
const node = {foo: 'bar'};
|
|
121
|
+
const res = resolveOAReferenceObject(
|
|
122
|
+
{$ref: '#/~1path'},
|
|
123
|
+
{rootDocument: {'/path': node}},
|
|
124
|
+
);
|
|
125
|
+
expect(res).to.be.eq(node);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it('should resolve a document node by the json pointer with multiple segments', function () {
|
|
129
|
+
const node = {foo: 'bar'};
|
|
130
|
+
const res = resolveOAReferenceObject(
|
|
131
|
+
{$ref: '#/a/b/c'},
|
|
132
|
+
{rootDocument: {a: {b: {c: node}}}},
|
|
133
|
+
);
|
|
134
|
+
expect(res).to.be.eq(node);
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
it('should resolve an array element when the root document is an array', function () {
|
|
138
|
+
const res = resolveOAReferenceObject(
|
|
139
|
+
{$ref: '#/1'},
|
|
140
|
+
{rootDocument: ['foo', 'bar', 'baz']},
|
|
141
|
+
);
|
|
142
|
+
expect(res).to.be.eq('bar');
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it('should be able to walk through an array element', function () {
|
|
146
|
+
const res = resolveOAReferenceObject(
|
|
147
|
+
{$ref: '#/1/prop'},
|
|
148
|
+
{rootDocument: [{prop: 'foo'}, {prop: 'bar'}, {prop: 'baz'}]},
|
|
149
|
+
);
|
|
150
|
+
expect(res).to.be.eq('bar');
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
it('should ignore an array index with zero prefix', function () {
|
|
154
|
+
const throwable = () =>
|
|
155
|
+
resolveOAReferenceObject(
|
|
156
|
+
{$ref: '#/01'},
|
|
157
|
+
{rootDocument: ['foo', 'bar', 'baz']},
|
|
158
|
+
);
|
|
159
|
+
expect(throwable).to.throw(
|
|
160
|
+
'Unable to resolve "/01" in the given document.',
|
|
161
|
+
);
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
it('should throw an error if a value of the target property is undefined', function () {
|
|
165
|
+
const node = {foo: undefined};
|
|
166
|
+
const throwable = () =>
|
|
167
|
+
resolveOAReferenceObject({$ref: '#/foo'}, {rootDocument: node});
|
|
168
|
+
expect(throwable).to.throw(
|
|
169
|
+
'Unable to resolve "/foo" in the given document.',
|
|
170
|
+
);
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
it('should not throw an error when a value of the target property is defined', function () {
|
|
174
|
+
const values = ['str', '', 10, 0, true, false, {}, [], null];
|
|
175
|
+
values.forEach(value => {
|
|
176
|
+
const rootDocument = {foo: value};
|
|
177
|
+
const res = resolveOAReferenceObject({$ref: '#/foo'}, {rootDocument});
|
|
178
|
+
expect(res).to.be.eq(value);
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
describe('an anchor reference (example "#SomeAnchor")', function () {
|
|
184
|
+
it('should throw an error when the URI has an anchor name', function () {
|
|
185
|
+
const throwable = () =>
|
|
186
|
+
resolveOAReferenceObject({$ref: '#SomeAnchor'}, {rootDocument: {}});
|
|
187
|
+
expect(throwable).to.throw(
|
|
188
|
+
'Anchor reference is not supported, but "#SomeAnchor" was given.',
|
|
189
|
+
);
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
describe('an external resource (example "http://example.com")', function () {
|
|
194
|
+
it('should throw an error when the URI starts with http(s) protocol', function () {
|
|
195
|
+
const throwable = v => () =>
|
|
196
|
+
resolveOAReferenceObject({$ref: v}, {rootDocument: {}});
|
|
197
|
+
['http://example', 'https://example'].forEach(uri => {
|
|
198
|
+
expect(throwable(uri)).to.throw(
|
|
199
|
+
format(
|
|
200
|
+
'External resource is not supported, but %v was given.',
|
|
201
|
+
uri,
|
|
202
|
+
),
|
|
203
|
+
);
|
|
204
|
+
});
|
|
205
|
+
});
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
describe('a relative reference (example "/path")', function () {
|
|
209
|
+
it('should throw an error when the URI has a relative reference', function () {
|
|
210
|
+
const throwable = v => () =>
|
|
211
|
+
resolveOAReferenceObject({$ref: v}, {rootDocument: {}});
|
|
212
|
+
['/path', 'path', './path', '../path'].forEach(uri => {
|
|
213
|
+
expect(throwable(uri)).to.throw(
|
|
214
|
+
format(
|
|
215
|
+
'Relative reference is not supported, but %v was given.',
|
|
216
|
+
uri,
|
|
217
|
+
),
|
|
218
|
+
);
|
|
219
|
+
});
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
describe('$dynamicRef', function () {
|
|
225
|
+
it('should throw an error when a dynamic reference is provided', function () {
|
|
226
|
+
const throwable = () =>
|
|
227
|
+
resolveOAReferenceObject({$dynamicRef: '#meta'}, {rootDocument: {}});
|
|
228
|
+
expect(throwable).to.throw(
|
|
229
|
+
'Schema keyword "$dynamicRef" is not supported.',
|
|
230
|
+
);
|
|
231
|
+
});
|
|
232
|
+
});
|
|
233
|
+
});
|