@apidevtools/json-schema-ref-parser 7.1.4 → 8.0.0
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/CHANGELOG.md +1 -1
- package/lib/dereference.js +149 -149
- package/lib/refs.js +196 -196
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -8,7 +8,7 @@ JSON Schema $Ref Parser adheres to [Semantic Versioning](http://semver.org/).
|
|
|
8
8
|
[v8.0.0](https://github.com/APIDevTools/json-schema-ref-parser/tree/v8.0.0) (2020-03-13)
|
|
9
9
|
----------------------------------------------------------------------------------------------------
|
|
10
10
|
|
|
11
|
-
- Moved JSON Schema $Ref Parser to the @APIDevTools scope](https://www.npmjs.com/org/apidevtools) on NPM
|
|
11
|
+
- Moved JSON Schema $Ref Parser to the [@APIDevTools scope](https://www.npmjs.com/org/apidevtools) on NPM
|
|
12
12
|
|
|
13
13
|
- The "json-schema-ref-parser" NPM package is now just a wrapper around the scoped "@apidevtools/json-schema-ref-parser" package
|
|
14
14
|
|
package/lib/dereference.js
CHANGED
|
@@ -1,149 +1,149 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
const $Ref = require("./ref");
|
|
4
|
-
const Pointer = require("./pointer");
|
|
5
|
-
const { ono } = require("@jsdevtools/ono");
|
|
6
|
-
const url = require("./util/url");
|
|
7
|
-
|
|
8
|
-
module.exports = dereference;
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Crawls the JSON schema, finds all JSON references, and dereferences them.
|
|
12
|
-
* This method mutates the JSON schema object, replacing JSON references with their resolved value.
|
|
13
|
-
*
|
|
14
|
-
* @param {$RefParser} parser
|
|
15
|
-
* @param {$RefParserOptions} options
|
|
16
|
-
*/
|
|
17
|
-
function dereference (parser, options) {
|
|
18
|
-
// console.log('Dereferencing $ref pointers in %s', parser.$refs._root$Ref.path);
|
|
19
|
-
let dereferenced = crawl(parser.schema, parser.$refs._root$Ref.path, "#", [], parser.$refs, options);
|
|
20
|
-
parser.$refs.circular = dereferenced.circular;
|
|
21
|
-
parser.schema = dereferenced.value;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Recursively crawls the given value, and dereferences any JSON references.
|
|
26
|
-
*
|
|
27
|
-
* @param {*} obj - The value to crawl. If it's not an object or array, it will be ignored.
|
|
28
|
-
* @param {string} path - The full path of `obj`, possibly with a JSON Pointer in the hash
|
|
29
|
-
* @param {string} pathFromRoot - The path of `obj` from the schema root
|
|
30
|
-
* @param {object[]} parents - An array of the parent objects that have already been dereferenced
|
|
31
|
-
* @param {$Refs} $refs
|
|
32
|
-
* @param {$RefParserOptions} options
|
|
33
|
-
* @returns {{value: object, circular: boolean}}
|
|
34
|
-
*/
|
|
35
|
-
function crawl (obj, path, pathFromRoot, parents, $refs, options) {
|
|
36
|
-
let dereferenced;
|
|
37
|
-
let result = {
|
|
38
|
-
value: obj,
|
|
39
|
-
circular: false
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
if (obj && typeof obj === "object") {
|
|
43
|
-
parents.push(obj);
|
|
44
|
-
|
|
45
|
-
if ($Ref.isAllowed$Ref(obj, options)) {
|
|
46
|
-
dereferenced = dereference$Ref(obj, path, pathFromRoot, parents, $refs, options);
|
|
47
|
-
result.circular = dereferenced.circular;
|
|
48
|
-
result.value = dereferenced.value;
|
|
49
|
-
}
|
|
50
|
-
else {
|
|
51
|
-
for (let key of Object.keys(obj)) {
|
|
52
|
-
let keyPath = Pointer.join(path, key);
|
|
53
|
-
let keyPathFromRoot = Pointer.join(pathFromRoot, key);
|
|
54
|
-
let value = obj[key];
|
|
55
|
-
let circular = false;
|
|
56
|
-
|
|
57
|
-
if ($Ref.isAllowed$Ref(value, options)) {
|
|
58
|
-
dereferenced = dereference$Ref(value, keyPath, keyPathFromRoot, parents, $refs, options);
|
|
59
|
-
circular = dereferenced.circular;
|
|
60
|
-
obj[key] = dereferenced.value;
|
|
61
|
-
}
|
|
62
|
-
else {
|
|
63
|
-
if (parents.indexOf(value) === -1) {
|
|
64
|
-
dereferenced = crawl(value, keyPath, keyPathFromRoot, parents, $refs, options);
|
|
65
|
-
circular = dereferenced.circular;
|
|
66
|
-
obj[key] = dereferenced.value;
|
|
67
|
-
}
|
|
68
|
-
else {
|
|
69
|
-
circular = foundCircularReference(keyPath, $refs, options);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// Set the "isCircular" flag if this or any other property is circular
|
|
74
|
-
result.circular = result.circular || circular;
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
parents.pop();
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
return result;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Dereferences the given JSON Reference, and then crawls the resulting value.
|
|
86
|
-
*
|
|
87
|
-
* @param {{$ref: string}} $ref - The JSON Reference to resolve
|
|
88
|
-
* @param {string} path - The full path of `$ref`, possibly with a JSON Pointer in the hash
|
|
89
|
-
* @param {string} pathFromRoot - The path of `$ref` from the schema root
|
|
90
|
-
* @param {object[]} parents - An array of the parent objects that have already been dereferenced
|
|
91
|
-
* @param {$Refs} $refs
|
|
92
|
-
* @param {$RefParserOptions} options
|
|
93
|
-
* @returns {{value: object, circular: boolean}}
|
|
94
|
-
*/
|
|
95
|
-
function dereference$Ref ($ref, path, pathFromRoot, parents, $refs, options) {
|
|
96
|
-
// console.log('Dereferencing $ref pointer "%s" at %s', $ref.$ref, path);
|
|
97
|
-
|
|
98
|
-
let $refPath = url.resolve(path, $ref.$ref);
|
|
99
|
-
let pointer = $refs._resolve($refPath, options);
|
|
100
|
-
|
|
101
|
-
// Check for circular references
|
|
102
|
-
let directCircular = pointer.circular;
|
|
103
|
-
let circular = directCircular || parents.indexOf(pointer.value) !== -1;
|
|
104
|
-
circular && foundCircularReference(path, $refs, options);
|
|
105
|
-
|
|
106
|
-
// Dereference the JSON reference
|
|
107
|
-
let dereferencedValue = $Ref.dereference($ref, pointer.value);
|
|
108
|
-
|
|
109
|
-
// Crawl the dereferenced value (unless it's circular)
|
|
110
|
-
if (!circular) {
|
|
111
|
-
// Determine if the dereferenced value is circular
|
|
112
|
-
let dereferenced = crawl(dereferencedValue, pointer.path, pathFromRoot, parents, $refs, options);
|
|
113
|
-
circular = dereferenced.circular;
|
|
114
|
-
dereferencedValue = dereferenced.value;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
if (circular && !directCircular && options.dereference.circular === "ignore") {
|
|
118
|
-
// The user has chosen to "ignore" circular references, so don't change the value
|
|
119
|
-
dereferencedValue = $ref;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
if (directCircular) {
|
|
123
|
-
// The pointer is a DIRECT circular reference (i.e. it references itself).
|
|
124
|
-
// So replace the $ref path with the absolute path from the JSON Schema root
|
|
125
|
-
dereferencedValue.$ref = pathFromRoot;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
return {
|
|
129
|
-
circular,
|
|
130
|
-
value: dereferencedValue
|
|
131
|
-
};
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
* Called when a circular reference is found.
|
|
136
|
-
* It sets the {@link $Refs#circular} flag, and throws an error if options.dereference.circular is false.
|
|
137
|
-
*
|
|
138
|
-
* @param {string} keyPath - The JSON Reference path of the circular reference
|
|
139
|
-
* @param {$Refs} $refs
|
|
140
|
-
* @param {$RefParserOptions} options
|
|
141
|
-
* @returns {boolean} - always returns true, to indicate that a circular reference was found
|
|
142
|
-
*/
|
|
143
|
-
function foundCircularReference (keyPath, $refs, options) {
|
|
144
|
-
$refs.circular = true;
|
|
145
|
-
if (!options.dereference.circular) {
|
|
146
|
-
throw ono.reference(`Circular $ref pointer found at ${keyPath}`);
|
|
147
|
-
}
|
|
148
|
-
return true;
|
|
149
|
-
}
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const $Ref = require("./ref");
|
|
4
|
+
const Pointer = require("./pointer");
|
|
5
|
+
const { ono } = require("@jsdevtools/ono");
|
|
6
|
+
const url = require("./util/url");
|
|
7
|
+
|
|
8
|
+
module.exports = dereference;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Crawls the JSON schema, finds all JSON references, and dereferences them.
|
|
12
|
+
* This method mutates the JSON schema object, replacing JSON references with their resolved value.
|
|
13
|
+
*
|
|
14
|
+
* @param {$RefParser} parser
|
|
15
|
+
* @param {$RefParserOptions} options
|
|
16
|
+
*/
|
|
17
|
+
function dereference (parser, options) {
|
|
18
|
+
// console.log('Dereferencing $ref pointers in %s', parser.$refs._root$Ref.path);
|
|
19
|
+
let dereferenced = crawl(parser.schema, parser.$refs._root$Ref.path, "#", [], parser.$refs, options);
|
|
20
|
+
parser.$refs.circular = dereferenced.circular;
|
|
21
|
+
parser.schema = dereferenced.value;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Recursively crawls the given value, and dereferences any JSON references.
|
|
26
|
+
*
|
|
27
|
+
* @param {*} obj - The value to crawl. If it's not an object or array, it will be ignored.
|
|
28
|
+
* @param {string} path - The full path of `obj`, possibly with a JSON Pointer in the hash
|
|
29
|
+
* @param {string} pathFromRoot - The path of `obj` from the schema root
|
|
30
|
+
* @param {object[]} parents - An array of the parent objects that have already been dereferenced
|
|
31
|
+
* @param {$Refs} $refs
|
|
32
|
+
* @param {$RefParserOptions} options
|
|
33
|
+
* @returns {{value: object, circular: boolean}}
|
|
34
|
+
*/
|
|
35
|
+
function crawl (obj, path, pathFromRoot, parents, $refs, options) {
|
|
36
|
+
let dereferenced;
|
|
37
|
+
let result = {
|
|
38
|
+
value: obj,
|
|
39
|
+
circular: false
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
if (obj && typeof obj === "object") {
|
|
43
|
+
parents.push(obj);
|
|
44
|
+
|
|
45
|
+
if ($Ref.isAllowed$Ref(obj, options)) {
|
|
46
|
+
dereferenced = dereference$Ref(obj, path, pathFromRoot, parents, $refs, options);
|
|
47
|
+
result.circular = dereferenced.circular;
|
|
48
|
+
result.value = dereferenced.value;
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
for (let key of Object.keys(obj)) {
|
|
52
|
+
let keyPath = Pointer.join(path, key);
|
|
53
|
+
let keyPathFromRoot = Pointer.join(pathFromRoot, key);
|
|
54
|
+
let value = obj[key];
|
|
55
|
+
let circular = false;
|
|
56
|
+
|
|
57
|
+
if ($Ref.isAllowed$Ref(value, options)) {
|
|
58
|
+
dereferenced = dereference$Ref(value, keyPath, keyPathFromRoot, parents, $refs, options);
|
|
59
|
+
circular = dereferenced.circular;
|
|
60
|
+
obj[key] = dereferenced.value;
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
if (parents.indexOf(value) === -1) {
|
|
64
|
+
dereferenced = crawl(value, keyPath, keyPathFromRoot, parents, $refs, options);
|
|
65
|
+
circular = dereferenced.circular;
|
|
66
|
+
obj[key] = dereferenced.value;
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
circular = foundCircularReference(keyPath, $refs, options);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Set the "isCircular" flag if this or any other property is circular
|
|
74
|
+
result.circular = result.circular || circular;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
parents.pop();
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return result;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Dereferences the given JSON Reference, and then crawls the resulting value.
|
|
86
|
+
*
|
|
87
|
+
* @param {{$ref: string}} $ref - The JSON Reference to resolve
|
|
88
|
+
* @param {string} path - The full path of `$ref`, possibly with a JSON Pointer in the hash
|
|
89
|
+
* @param {string} pathFromRoot - The path of `$ref` from the schema root
|
|
90
|
+
* @param {object[]} parents - An array of the parent objects that have already been dereferenced
|
|
91
|
+
* @param {$Refs} $refs
|
|
92
|
+
* @param {$RefParserOptions} options
|
|
93
|
+
* @returns {{value: object, circular: boolean}}
|
|
94
|
+
*/
|
|
95
|
+
function dereference$Ref ($ref, path, pathFromRoot, parents, $refs, options) {
|
|
96
|
+
// console.log('Dereferencing $ref pointer "%s" at %s', $ref.$ref, path);
|
|
97
|
+
|
|
98
|
+
let $refPath = url.resolve(path, $ref.$ref);
|
|
99
|
+
let pointer = $refs._resolve($refPath, options);
|
|
100
|
+
|
|
101
|
+
// Check for circular references
|
|
102
|
+
let directCircular = pointer.circular;
|
|
103
|
+
let circular = directCircular || parents.indexOf(pointer.value) !== -1;
|
|
104
|
+
circular && foundCircularReference(path, $refs, options);
|
|
105
|
+
|
|
106
|
+
// Dereference the JSON reference
|
|
107
|
+
let dereferencedValue = $Ref.dereference($ref, pointer.value);
|
|
108
|
+
|
|
109
|
+
// Crawl the dereferenced value (unless it's circular)
|
|
110
|
+
if (!circular) {
|
|
111
|
+
// Determine if the dereferenced value is circular
|
|
112
|
+
let dereferenced = crawl(dereferencedValue, pointer.path, pathFromRoot, parents, $refs, options);
|
|
113
|
+
circular = dereferenced.circular;
|
|
114
|
+
dereferencedValue = dereferenced.value;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (circular && !directCircular && options.dereference.circular === "ignore") {
|
|
118
|
+
// The user has chosen to "ignore" circular references, so don't change the value
|
|
119
|
+
dereferencedValue = $ref;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (directCircular) {
|
|
123
|
+
// The pointer is a DIRECT circular reference (i.e. it references itself).
|
|
124
|
+
// So replace the $ref path with the absolute path from the JSON Schema root
|
|
125
|
+
dereferencedValue.$ref = pathFromRoot;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return {
|
|
129
|
+
circular,
|
|
130
|
+
value: dereferencedValue
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Called when a circular reference is found.
|
|
136
|
+
* It sets the {@link $Refs#circular} flag, and throws an error if options.dereference.circular is false.
|
|
137
|
+
*
|
|
138
|
+
* @param {string} keyPath - The JSON Reference path of the circular reference
|
|
139
|
+
* @param {$Refs} $refs
|
|
140
|
+
* @param {$RefParserOptions} options
|
|
141
|
+
* @returns {boolean} - always returns true, to indicate that a circular reference was found
|
|
142
|
+
*/
|
|
143
|
+
function foundCircularReference (keyPath, $refs, options) {
|
|
144
|
+
$refs.circular = true;
|
|
145
|
+
if (!options.dereference.circular) {
|
|
146
|
+
throw ono.reference(`Circular $ref pointer found at ${keyPath}`);
|
|
147
|
+
}
|
|
148
|
+
return true;
|
|
149
|
+
}
|
package/lib/refs.js
CHANGED
|
@@ -1,196 +1,196 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
const { ono } = require("@jsdevtools/ono");
|
|
4
|
-
const $Ref = require("./ref");
|
|
5
|
-
const url = require("./util/url");
|
|
6
|
-
|
|
7
|
-
module.exports = $Refs;
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* This class is a map of JSON references and their resolved values.
|
|
11
|
-
*/
|
|
12
|
-
function $Refs () {
|
|
13
|
-
/**
|
|
14
|
-
* Indicates whether the schema contains any circular references.
|
|
15
|
-
*
|
|
16
|
-
* @type {boolean}
|
|
17
|
-
*/
|
|
18
|
-
this.circular = false;
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* A map of paths/urls to {@link $Ref} objects
|
|
22
|
-
*
|
|
23
|
-
* @type {object}
|
|
24
|
-
* @protected
|
|
25
|
-
*/
|
|
26
|
-
this._$refs = {};
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* The {@link $Ref} object that is the root of the JSON schema.
|
|
30
|
-
*
|
|
31
|
-
* @type {$Ref}
|
|
32
|
-
* @protected
|
|
33
|
-
*/
|
|
34
|
-
this._root$Ref = null;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Returns the paths of all the files/URLs that are referenced by the JSON schema,
|
|
39
|
-
* including the schema itself.
|
|
40
|
-
*
|
|
41
|
-
* @param {...string|string[]} [types] - Only return paths of the given types ("file", "http", etc.)
|
|
42
|
-
* @returns {string[]}
|
|
43
|
-
*/
|
|
44
|
-
$Refs.prototype.paths = function (types) {
|
|
45
|
-
let paths = getPaths(this._$refs, arguments);
|
|
46
|
-
return paths.map((path) => {
|
|
47
|
-
return path.decoded;
|
|
48
|
-
});
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Returns the map of JSON references and their resolved values.
|
|
53
|
-
*
|
|
54
|
-
* @param {...string|string[]} [types] - Only return references of the given types ("file", "http", etc.)
|
|
55
|
-
* @returns {object}
|
|
56
|
-
*/
|
|
57
|
-
$Refs.prototype.values = function (types) {
|
|
58
|
-
let $refs = this._$refs;
|
|
59
|
-
let paths = getPaths($refs, arguments);
|
|
60
|
-
return paths.reduce((obj, path) => {
|
|
61
|
-
obj[path.decoded] = $refs[path.encoded].value;
|
|
62
|
-
return obj;
|
|
63
|
-
}, {});
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Returns a POJO (plain old JavaScript object) for serialization as JSON.
|
|
68
|
-
*
|
|
69
|
-
* @returns {object}
|
|
70
|
-
*/
|
|
71
|
-
$Refs.prototype.toJSON = $Refs.prototype.values;
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Determines whether the given JSON reference exists.
|
|
75
|
-
*
|
|
76
|
-
* @param {string} path - The path being resolved, optionally with a JSON pointer in the hash
|
|
77
|
-
* @param {$RefParserOptions} [options]
|
|
78
|
-
* @returns {boolean}
|
|
79
|
-
*/
|
|
80
|
-
$Refs.prototype.exists = function (path, options) {
|
|
81
|
-
try {
|
|
82
|
-
this._resolve(path, options);
|
|
83
|
-
return true;
|
|
84
|
-
}
|
|
85
|
-
catch (e) {
|
|
86
|
-
return false;
|
|
87
|
-
}
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Resolves the given JSON reference and returns the resolved value.
|
|
92
|
-
*
|
|
93
|
-
* @param {string} path - The path being resolved, with a JSON pointer in the hash
|
|
94
|
-
* @param {$RefParserOptions} [options]
|
|
95
|
-
* @returns {*} - Returns the resolved value
|
|
96
|
-
*/
|
|
97
|
-
$Refs.prototype.get = function (path, options) {
|
|
98
|
-
return this._resolve(path, options).value;
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* Sets the value of a nested property within this {@link $Ref#value}.
|
|
103
|
-
* If the property, or any of its parents don't exist, they will be created.
|
|
104
|
-
*
|
|
105
|
-
* @param {string} path - The path of the property to set, optionally with a JSON pointer in the hash
|
|
106
|
-
* @param {*} value - The value to assign
|
|
107
|
-
*/
|
|
108
|
-
$Refs.prototype.set = function (path, value) {
|
|
109
|
-
let absPath = url.resolve(this._root$Ref.path, path);
|
|
110
|
-
let withoutHash = url.stripHash(absPath);
|
|
111
|
-
let $ref = this._$refs[withoutHash];
|
|
112
|
-
|
|
113
|
-
if (!$ref) {
|
|
114
|
-
throw ono(`Error resolving $ref pointer "${path}". \n"${withoutHash}" not found.`);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
$ref.set(absPath, value);
|
|
118
|
-
};
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* Creates a new {@link $Ref} object and adds it to this {@link $Refs} object.
|
|
122
|
-
*
|
|
123
|
-
* @param {string} path - The file path or URL of the referenced file
|
|
124
|
-
*/
|
|
125
|
-
$Refs.prototype._add = function (path) {
|
|
126
|
-
let withoutHash = url.stripHash(path);
|
|
127
|
-
|
|
128
|
-
let $ref = new $Ref();
|
|
129
|
-
$ref.path = withoutHash;
|
|
130
|
-
$ref.$refs = this;
|
|
131
|
-
|
|
132
|
-
this._$refs[withoutHash] = $ref;
|
|
133
|
-
this._root$Ref = this._root$Ref || $ref;
|
|
134
|
-
|
|
135
|
-
return $ref;
|
|
136
|
-
};
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* Resolves the given JSON reference.
|
|
140
|
-
*
|
|
141
|
-
* @param {string} path - The path being resolved, optionally with a JSON pointer in the hash
|
|
142
|
-
* @param {$RefParserOptions} [options]
|
|
143
|
-
* @returns {Pointer}
|
|
144
|
-
* @protected
|
|
145
|
-
*/
|
|
146
|
-
$Refs.prototype._resolve = function (path, options) {
|
|
147
|
-
let absPath = url.resolve(this._root$Ref.path, path);
|
|
148
|
-
let withoutHash = url.stripHash(absPath);
|
|
149
|
-
let $ref = this._$refs[withoutHash];
|
|
150
|
-
|
|
151
|
-
if (!$ref) {
|
|
152
|
-
throw ono(`Error resolving $ref pointer "${path}". \n"${withoutHash}" not found.`);
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
return $ref.resolve(absPath, options, path);
|
|
156
|
-
};
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
* Returns the specified {@link $Ref} object, or undefined.
|
|
160
|
-
*
|
|
161
|
-
* @param {string} path - The path being resolved, optionally with a JSON pointer in the hash
|
|
162
|
-
* @returns {$Ref|undefined}
|
|
163
|
-
* @protected
|
|
164
|
-
*/
|
|
165
|
-
$Refs.prototype._get$Ref = function (path) {
|
|
166
|
-
path = url.resolve(this._root$Ref.path, path);
|
|
167
|
-
let withoutHash = url.stripHash(path);
|
|
168
|
-
return this._$refs[withoutHash];
|
|
169
|
-
};
|
|
170
|
-
|
|
171
|
-
/**
|
|
172
|
-
* Returns the encoded and decoded paths keys of the given object.
|
|
173
|
-
*
|
|
174
|
-
* @param {object} $refs - The object whose keys are URL-encoded paths
|
|
175
|
-
* @param {...string|string[]} [types] - Only return paths of the given types ("file", "http", etc.)
|
|
176
|
-
* @returns {object[]}
|
|
177
|
-
*/
|
|
178
|
-
function getPaths ($refs, types) {
|
|
179
|
-
let paths = Object.keys($refs);
|
|
180
|
-
|
|
181
|
-
// Filter the paths by type
|
|
182
|
-
types = Array.isArray(types[0]) ? types[0] : Array.prototype.slice.call(types);
|
|
183
|
-
if (types.length > 0 && types[0]) {
|
|
184
|
-
paths = paths.filter((key) => {
|
|
185
|
-
return types.indexOf($refs[key].pathType) !== -1;
|
|
186
|
-
});
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
// Decode local filesystem paths
|
|
190
|
-
return paths.map((path) => {
|
|
191
|
-
return {
|
|
192
|
-
encoded: path,
|
|
193
|
-
decoded: $refs[path].pathType === "file" ? url.toFileSystemPath(path, true) : path
|
|
194
|
-
};
|
|
195
|
-
});
|
|
196
|
-
}
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const { ono } = require("@jsdevtools/ono");
|
|
4
|
+
const $Ref = require("./ref");
|
|
5
|
+
const url = require("./util/url");
|
|
6
|
+
|
|
7
|
+
module.exports = $Refs;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* This class is a map of JSON references and their resolved values.
|
|
11
|
+
*/
|
|
12
|
+
function $Refs () {
|
|
13
|
+
/**
|
|
14
|
+
* Indicates whether the schema contains any circular references.
|
|
15
|
+
*
|
|
16
|
+
* @type {boolean}
|
|
17
|
+
*/
|
|
18
|
+
this.circular = false;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* A map of paths/urls to {@link $Ref} objects
|
|
22
|
+
*
|
|
23
|
+
* @type {object}
|
|
24
|
+
* @protected
|
|
25
|
+
*/
|
|
26
|
+
this._$refs = {};
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* The {@link $Ref} object that is the root of the JSON schema.
|
|
30
|
+
*
|
|
31
|
+
* @type {$Ref}
|
|
32
|
+
* @protected
|
|
33
|
+
*/
|
|
34
|
+
this._root$Ref = null;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Returns the paths of all the files/URLs that are referenced by the JSON schema,
|
|
39
|
+
* including the schema itself.
|
|
40
|
+
*
|
|
41
|
+
* @param {...string|string[]} [types] - Only return paths of the given types ("file", "http", etc.)
|
|
42
|
+
* @returns {string[]}
|
|
43
|
+
*/
|
|
44
|
+
$Refs.prototype.paths = function (types) {
|
|
45
|
+
let paths = getPaths(this._$refs, arguments);
|
|
46
|
+
return paths.map((path) => {
|
|
47
|
+
return path.decoded;
|
|
48
|
+
});
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Returns the map of JSON references and their resolved values.
|
|
53
|
+
*
|
|
54
|
+
* @param {...string|string[]} [types] - Only return references of the given types ("file", "http", etc.)
|
|
55
|
+
* @returns {object}
|
|
56
|
+
*/
|
|
57
|
+
$Refs.prototype.values = function (types) {
|
|
58
|
+
let $refs = this._$refs;
|
|
59
|
+
let paths = getPaths($refs, arguments);
|
|
60
|
+
return paths.reduce((obj, path) => {
|
|
61
|
+
obj[path.decoded] = $refs[path.encoded].value;
|
|
62
|
+
return obj;
|
|
63
|
+
}, {});
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Returns a POJO (plain old JavaScript object) for serialization as JSON.
|
|
68
|
+
*
|
|
69
|
+
* @returns {object}
|
|
70
|
+
*/
|
|
71
|
+
$Refs.prototype.toJSON = $Refs.prototype.values;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Determines whether the given JSON reference exists.
|
|
75
|
+
*
|
|
76
|
+
* @param {string} path - The path being resolved, optionally with a JSON pointer in the hash
|
|
77
|
+
* @param {$RefParserOptions} [options]
|
|
78
|
+
* @returns {boolean}
|
|
79
|
+
*/
|
|
80
|
+
$Refs.prototype.exists = function (path, options) {
|
|
81
|
+
try {
|
|
82
|
+
this._resolve(path, options);
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
catch (e) {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Resolves the given JSON reference and returns the resolved value.
|
|
92
|
+
*
|
|
93
|
+
* @param {string} path - The path being resolved, with a JSON pointer in the hash
|
|
94
|
+
* @param {$RefParserOptions} [options]
|
|
95
|
+
* @returns {*} - Returns the resolved value
|
|
96
|
+
*/
|
|
97
|
+
$Refs.prototype.get = function (path, options) {
|
|
98
|
+
return this._resolve(path, options).value;
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Sets the value of a nested property within this {@link $Ref#value}.
|
|
103
|
+
* If the property, or any of its parents don't exist, they will be created.
|
|
104
|
+
*
|
|
105
|
+
* @param {string} path - The path of the property to set, optionally with a JSON pointer in the hash
|
|
106
|
+
* @param {*} value - The value to assign
|
|
107
|
+
*/
|
|
108
|
+
$Refs.prototype.set = function (path, value) {
|
|
109
|
+
let absPath = url.resolve(this._root$Ref.path, path);
|
|
110
|
+
let withoutHash = url.stripHash(absPath);
|
|
111
|
+
let $ref = this._$refs[withoutHash];
|
|
112
|
+
|
|
113
|
+
if (!$ref) {
|
|
114
|
+
throw ono(`Error resolving $ref pointer "${path}". \n"${withoutHash}" not found.`);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
$ref.set(absPath, value);
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Creates a new {@link $Ref} object and adds it to this {@link $Refs} object.
|
|
122
|
+
*
|
|
123
|
+
* @param {string} path - The file path or URL of the referenced file
|
|
124
|
+
*/
|
|
125
|
+
$Refs.prototype._add = function (path) {
|
|
126
|
+
let withoutHash = url.stripHash(path);
|
|
127
|
+
|
|
128
|
+
let $ref = new $Ref();
|
|
129
|
+
$ref.path = withoutHash;
|
|
130
|
+
$ref.$refs = this;
|
|
131
|
+
|
|
132
|
+
this._$refs[withoutHash] = $ref;
|
|
133
|
+
this._root$Ref = this._root$Ref || $ref;
|
|
134
|
+
|
|
135
|
+
return $ref;
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Resolves the given JSON reference.
|
|
140
|
+
*
|
|
141
|
+
* @param {string} path - The path being resolved, optionally with a JSON pointer in the hash
|
|
142
|
+
* @param {$RefParserOptions} [options]
|
|
143
|
+
* @returns {Pointer}
|
|
144
|
+
* @protected
|
|
145
|
+
*/
|
|
146
|
+
$Refs.prototype._resolve = function (path, options) {
|
|
147
|
+
let absPath = url.resolve(this._root$Ref.path, path);
|
|
148
|
+
let withoutHash = url.stripHash(absPath);
|
|
149
|
+
let $ref = this._$refs[withoutHash];
|
|
150
|
+
|
|
151
|
+
if (!$ref) {
|
|
152
|
+
throw ono(`Error resolving $ref pointer "${path}". \n"${withoutHash}" not found.`);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
return $ref.resolve(absPath, options, path);
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Returns the specified {@link $Ref} object, or undefined.
|
|
160
|
+
*
|
|
161
|
+
* @param {string} path - The path being resolved, optionally with a JSON pointer in the hash
|
|
162
|
+
* @returns {$Ref|undefined}
|
|
163
|
+
* @protected
|
|
164
|
+
*/
|
|
165
|
+
$Refs.prototype._get$Ref = function (path) {
|
|
166
|
+
path = url.resolve(this._root$Ref.path, path);
|
|
167
|
+
let withoutHash = url.stripHash(path);
|
|
168
|
+
return this._$refs[withoutHash];
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Returns the encoded and decoded paths keys of the given object.
|
|
173
|
+
*
|
|
174
|
+
* @param {object} $refs - The object whose keys are URL-encoded paths
|
|
175
|
+
* @param {...string|string[]} [types] - Only return paths of the given types ("file", "http", etc.)
|
|
176
|
+
* @returns {object[]}
|
|
177
|
+
*/
|
|
178
|
+
function getPaths ($refs, types) {
|
|
179
|
+
let paths = Object.keys($refs);
|
|
180
|
+
|
|
181
|
+
// Filter the paths by type
|
|
182
|
+
types = Array.isArray(types[0]) ? types[0] : Array.prototype.slice.call(types);
|
|
183
|
+
if (types.length > 0 && types[0]) {
|
|
184
|
+
paths = paths.filter((key) => {
|
|
185
|
+
return types.indexOf($refs[key].pathType) !== -1;
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Decode local filesystem paths
|
|
190
|
+
return paths.map((path) => {
|
|
191
|
+
return {
|
|
192
|
+
encoded: path,
|
|
193
|
+
decoded: $refs[path].pathType === "file" ? url.toFileSystemPath(path, true) : path
|
|
194
|
+
};
|
|
195
|
+
});
|
|
196
|
+
}
|