@apidevtools/json-schema-ref-parser 11.7.2 → 11.8.2
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/README.md +4 -8
- package/cjs/bundle.js +304 -0
- package/cjs/dereference.js +258 -0
- package/cjs/index.js +603 -0
- package/cjs/normalize-args.js +64 -0
- package/cjs/options.js +125 -0
- package/cjs/package.json +3 -0
- package/cjs/parse.js +338 -0
- package/cjs/parsers/binary.js +54 -0
- package/cjs/parsers/json.js +199 -0
- package/cjs/parsers/text.js +61 -0
- package/cjs/parsers/yaml.js +239 -0
- package/cjs/pointer.js +290 -0
- package/cjs/ref.js +333 -0
- package/cjs/refs.js +214 -0
- package/cjs/resolve-external.js +333 -0
- package/cjs/resolvers/file.js +106 -0
- package/cjs/resolvers/http.js +184 -0
- package/cjs/util/errors.js +401 -0
- package/cjs/util/plugins.js +159 -0
- package/cjs/util/projectDir.cjs +6 -0
- package/cjs/util/url.js +228 -0
- package/dist/lib/bundle.js +17 -7
- package/dist/lib/dereference.js +20 -8
- package/dist/lib/index.d.ts +6 -6
- package/dist/lib/index.js +17 -7
- package/dist/lib/options.d.ts +9 -2
- package/dist/lib/parse.d.ts +1 -1
- package/dist/lib/parse.js +17 -7
- package/dist/lib/pointer.js +25 -9
- package/dist/lib/refs.js +17 -7
- package/dist/lib/resolve-external.js +17 -7
- package/dist/lib/resolvers/file.js +17 -7
- package/dist/lib/resolvers/http.js +17 -7
- package/dist/lib/util/errors.d.ts +6 -2
- package/dist/lib/util/errors.js +7 -3
- package/dist/lib/util/plugins.d.ts +2 -2
- package/dist/lib/util/url.js +20 -9
- package/lib/dereference.ts +4 -1
- package/lib/index.ts +6 -12
- package/lib/options.ts +7 -0
- package/lib/pointer.ts +13 -2
- package/lib/util/errors.ts +14 -5
- package/lib/util/plugins.ts +6 -7
- package/lib/util/url.ts +3 -2
- package/package.json +31 -31
package/cjs/pointer.js
ADDED
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "default", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return _default;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
var _refJs = /*#__PURE__*/ _interopRequireDefault(require("./ref.js"));
|
|
12
|
+
var _urlJs = /*#__PURE__*/ _interopRequireWildcard(require("./util/url.js"));
|
|
13
|
+
var _errorsJs = require("./util/errors.js");
|
|
14
|
+
function _interopRequireDefault(obj) {
|
|
15
|
+
return obj && obj.__esModule ? obj : {
|
|
16
|
+
default: obj
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
function _getRequireWildcardCache(nodeInterop) {
|
|
20
|
+
if (typeof WeakMap !== "function") return null;
|
|
21
|
+
var cacheBabelInterop = new WeakMap();
|
|
22
|
+
var cacheNodeInterop = new WeakMap();
|
|
23
|
+
return (_getRequireWildcardCache = function(nodeInterop) {
|
|
24
|
+
return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
|
|
25
|
+
})(nodeInterop);
|
|
26
|
+
}
|
|
27
|
+
function _interopRequireWildcard(obj, nodeInterop) {
|
|
28
|
+
if (!nodeInterop && obj && obj.__esModule) {
|
|
29
|
+
return obj;
|
|
30
|
+
}
|
|
31
|
+
if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
|
|
32
|
+
return {
|
|
33
|
+
default: obj
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
var cache = _getRequireWildcardCache(nodeInterop);
|
|
37
|
+
if (cache && cache.has(obj)) {
|
|
38
|
+
return cache.get(obj);
|
|
39
|
+
}
|
|
40
|
+
var newObj = {};
|
|
41
|
+
var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
|
|
42
|
+
for(var key in obj){
|
|
43
|
+
if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
44
|
+
var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
|
|
45
|
+
if (desc && (desc.get || desc.set)) {
|
|
46
|
+
Object.defineProperty(newObj, key, desc);
|
|
47
|
+
} else {
|
|
48
|
+
newObj[key] = obj[key];
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
newObj.default = obj;
|
|
53
|
+
if (cache) {
|
|
54
|
+
cache.set(obj, newObj);
|
|
55
|
+
}
|
|
56
|
+
return newObj;
|
|
57
|
+
}
|
|
58
|
+
var _default = Pointer;
|
|
59
|
+
var slashes = /\//g;
|
|
60
|
+
var tildes = /~/g;
|
|
61
|
+
var escapedSlash = /~1/g;
|
|
62
|
+
var escapedTilde = /~0/g;
|
|
63
|
+
/**
|
|
64
|
+
* This class represents a single JSON pointer and its resolved value.
|
|
65
|
+
*
|
|
66
|
+
* @param {$Ref} $ref
|
|
67
|
+
* @param {string} path
|
|
68
|
+
* @param {string} [friendlyPath] - The original user-specified path (used for error messages)
|
|
69
|
+
* @constructor
|
|
70
|
+
*/ function Pointer($ref, path, friendlyPath) {
|
|
71
|
+
/**
|
|
72
|
+
* The {@link $Ref} object that contains this {@link Pointer} object.
|
|
73
|
+
* @type {$Ref}
|
|
74
|
+
*/ this.$ref = $ref;
|
|
75
|
+
/**
|
|
76
|
+
* The file path or URL, containing the JSON pointer in the hash.
|
|
77
|
+
* This path is relative to the path of the main JSON schema file.
|
|
78
|
+
* @type {string}
|
|
79
|
+
*/ this.path = path;
|
|
80
|
+
/**
|
|
81
|
+
* The original path or URL, used for error messages.
|
|
82
|
+
* @type {string}
|
|
83
|
+
*/ this.originalPath = friendlyPath || path;
|
|
84
|
+
/**
|
|
85
|
+
* The value of the JSON pointer.
|
|
86
|
+
* Can be any JSON type, not just objects. Unknown file types are represented as Buffers (byte arrays).
|
|
87
|
+
* @type {?*}
|
|
88
|
+
*/ this.value = undefined;
|
|
89
|
+
/**
|
|
90
|
+
* Indicates whether the pointer references itself.
|
|
91
|
+
* @type {boolean}
|
|
92
|
+
*/ this.circular = false;
|
|
93
|
+
/**
|
|
94
|
+
* The number of indirect references that were traversed to resolve the value.
|
|
95
|
+
* Resolving a single pointer may require resolving multiple $Refs.
|
|
96
|
+
* @type {number}
|
|
97
|
+
*/ this.indirections = 0;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Resolves the value of a nested property within the given object.
|
|
101
|
+
*
|
|
102
|
+
* @param {*} obj - The object that will be crawled
|
|
103
|
+
* @param {$RefParserOptions} options
|
|
104
|
+
* @param {string} pathFromRoot - the path of place that initiated resolving
|
|
105
|
+
*
|
|
106
|
+
* @returns {Pointer}
|
|
107
|
+
* Returns a JSON pointer whose {@link Pointer#value} is the resolved value.
|
|
108
|
+
* If resolving this value required resolving other JSON references, then
|
|
109
|
+
* the {@link Pointer#$ref} and {@link Pointer#path} will reflect the resolution path
|
|
110
|
+
* of the resolved value.
|
|
111
|
+
*/ Pointer.prototype.resolve = function(obj, options, pathFromRoot) {
|
|
112
|
+
var tokens = Pointer.parse(this.path, this.originalPath);
|
|
113
|
+
// Crawl the object, one token at a time
|
|
114
|
+
this.value = unwrapOrThrow(obj);
|
|
115
|
+
for(var i = 0; i < tokens.length; i++){
|
|
116
|
+
if (resolveIf$Ref(this, options)) {
|
|
117
|
+
// The $ref path has changed, so append the remaining tokens to the path
|
|
118
|
+
this.path = Pointer.join(this.path, tokens.slice(i));
|
|
119
|
+
}
|
|
120
|
+
if (typeof this.value === "object" && this.value !== null && "$ref" in this.value) {
|
|
121
|
+
return this;
|
|
122
|
+
}
|
|
123
|
+
var token = tokens[i];
|
|
124
|
+
if (this.value[token] === undefined || this.value[token] === null) {
|
|
125
|
+
this.value = null;
|
|
126
|
+
throw new _errorsJs.MissingPointerError(token, decodeURI(this.originalPath));
|
|
127
|
+
} else {
|
|
128
|
+
this.value = this.value[token];
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
// Resolve the final value
|
|
132
|
+
if (!this.value || this.value.$ref && _urlJs.resolve(this.path, this.value.$ref) !== pathFromRoot) {
|
|
133
|
+
resolveIf$Ref(this, options);
|
|
134
|
+
}
|
|
135
|
+
return this;
|
|
136
|
+
};
|
|
137
|
+
/**
|
|
138
|
+
* Sets the value of a nested property within the given object.
|
|
139
|
+
*
|
|
140
|
+
* @param {*} obj - The object that will be crawled
|
|
141
|
+
* @param {*} value - the value to assign
|
|
142
|
+
* @param {$RefParserOptions} options
|
|
143
|
+
*
|
|
144
|
+
* @returns {*}
|
|
145
|
+
* Returns the modified object, or an entirely new object if the entire object is overwritten.
|
|
146
|
+
*/ Pointer.prototype.set = function(obj, value, options) {
|
|
147
|
+
var tokens = Pointer.parse(this.path);
|
|
148
|
+
var token;
|
|
149
|
+
if (tokens.length === 0) {
|
|
150
|
+
// There are no tokens, replace the entire object with the new value
|
|
151
|
+
this.value = value;
|
|
152
|
+
return value;
|
|
153
|
+
}
|
|
154
|
+
// Crawl the object, one token at a time
|
|
155
|
+
this.value = unwrapOrThrow(obj);
|
|
156
|
+
for(var i = 0; i < tokens.length - 1; i++){
|
|
157
|
+
resolveIf$Ref(this, options);
|
|
158
|
+
token = tokens[i];
|
|
159
|
+
if (this.value && this.value[token] !== undefined) {
|
|
160
|
+
// The token exists
|
|
161
|
+
this.value = this.value[token];
|
|
162
|
+
} else {
|
|
163
|
+
// The token doesn't exist, so create it
|
|
164
|
+
this.value = setValue(this, token, {});
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
// Set the value of the final token
|
|
168
|
+
resolveIf$Ref(this, options);
|
|
169
|
+
token = tokens[tokens.length - 1];
|
|
170
|
+
setValue(this, token, value);
|
|
171
|
+
// Return the updated object
|
|
172
|
+
return obj;
|
|
173
|
+
};
|
|
174
|
+
/**
|
|
175
|
+
* Parses a JSON pointer (or a path containing a JSON pointer in the hash)
|
|
176
|
+
* and returns an array of the pointer's tokens.
|
|
177
|
+
* (e.g. "schema.json#/definitions/person/name" => ["definitions", "person", "name"])
|
|
178
|
+
*
|
|
179
|
+
* The pointer is parsed according to RFC 6901
|
|
180
|
+
* {@link https://tools.ietf.org/html/rfc6901#section-3}
|
|
181
|
+
*
|
|
182
|
+
* @param {string} path
|
|
183
|
+
* @param {string} [originalPath]
|
|
184
|
+
* @returns {string[]}
|
|
185
|
+
*/ Pointer.parse = function(path, originalPath) {
|
|
186
|
+
// Get the JSON pointer from the path's hash
|
|
187
|
+
var pointer = _urlJs.getHash(path).substr(1);
|
|
188
|
+
// If there's no pointer, then there are no tokens,
|
|
189
|
+
// so return an empty array
|
|
190
|
+
if (!pointer) {
|
|
191
|
+
return [];
|
|
192
|
+
}
|
|
193
|
+
// Split into an array
|
|
194
|
+
pointer = pointer.split("/");
|
|
195
|
+
// Decode each part, according to RFC 6901
|
|
196
|
+
for(var i = 0; i < pointer.length; i++){
|
|
197
|
+
pointer[i] = decodeURIComponent(pointer[i].replace(escapedSlash, "/").replace(escapedTilde, "~"));
|
|
198
|
+
}
|
|
199
|
+
if (pointer[0] !== "") {
|
|
200
|
+
throw new _errorsJs.InvalidPointerError(pointer, originalPath === undefined ? path : originalPath);
|
|
201
|
+
}
|
|
202
|
+
return pointer.slice(1);
|
|
203
|
+
};
|
|
204
|
+
/**
|
|
205
|
+
* Creates a JSON pointer path, by joining one or more tokens to a base path.
|
|
206
|
+
*
|
|
207
|
+
* @param {string} base - The base path (e.g. "schema.json#/definitions/person")
|
|
208
|
+
* @param {string|string[]} tokens - The token(s) to append (e.g. ["name", "first"])
|
|
209
|
+
* @returns {string}
|
|
210
|
+
*/ Pointer.join = function(base, tokens) {
|
|
211
|
+
// Ensure that the base path contains a hash
|
|
212
|
+
if (base.indexOf("#") === -1) {
|
|
213
|
+
base += "#";
|
|
214
|
+
}
|
|
215
|
+
// Append each token to the base path
|
|
216
|
+
tokens = Array.isArray(tokens) ? tokens : [
|
|
217
|
+
tokens
|
|
218
|
+
];
|
|
219
|
+
for(var i = 0; i < tokens.length; i++){
|
|
220
|
+
var token = tokens[i];
|
|
221
|
+
// Encode the token, according to RFC 6901
|
|
222
|
+
base += "/" + encodeURIComponent(token.replace(tildes, "~0").replace(slashes, "~1"));
|
|
223
|
+
}
|
|
224
|
+
return base;
|
|
225
|
+
};
|
|
226
|
+
/**
|
|
227
|
+
* If the given pointer's {@link Pointer#value} is a JSON reference,
|
|
228
|
+
* then the reference is resolved and {@link Pointer#value} is replaced with the resolved value.
|
|
229
|
+
* In addition, {@link Pointer#path} and {@link Pointer#$ref} are updated to reflect the
|
|
230
|
+
* resolution path of the new value.
|
|
231
|
+
*
|
|
232
|
+
* @param {Pointer} pointer
|
|
233
|
+
* @param {$RefParserOptions} options
|
|
234
|
+
* @returns {boolean} - Returns `true` if the resolution path changed
|
|
235
|
+
*/ function resolveIf$Ref(pointer, options) {
|
|
236
|
+
// Is the value a JSON reference? (and allowed?)
|
|
237
|
+
if (_refJs.default.isAllowed$Ref(pointer.value, options)) {
|
|
238
|
+
var $refPath = _urlJs.resolve(pointer.path, pointer.value.$ref);
|
|
239
|
+
if ($refPath === pointer.path) {
|
|
240
|
+
// The value is a reference to itself, so there's nothing to do.
|
|
241
|
+
pointer.circular = true;
|
|
242
|
+
} else {
|
|
243
|
+
var resolved = pointer.$ref.$refs._resolve($refPath, pointer.path, options);
|
|
244
|
+
if (resolved === null) {
|
|
245
|
+
return false;
|
|
246
|
+
}
|
|
247
|
+
pointer.indirections += resolved.indirections + 1;
|
|
248
|
+
if (_refJs.default.isExtended$Ref(pointer.value)) {
|
|
249
|
+
// This JSON reference "extends" the resolved value, rather than simply pointing to it.
|
|
250
|
+
// So the resolved path does NOT change. Just the value does.
|
|
251
|
+
pointer.value = _refJs.default.dereference(pointer.value, resolved.value);
|
|
252
|
+
return false;
|
|
253
|
+
} else {
|
|
254
|
+
// Resolve the reference
|
|
255
|
+
pointer.$ref = resolved.$ref;
|
|
256
|
+
pointer.path = resolved.path;
|
|
257
|
+
pointer.value = resolved.value;
|
|
258
|
+
}
|
|
259
|
+
return true;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Sets the specified token value of the {@link Pointer#value}.
|
|
265
|
+
*
|
|
266
|
+
* The token is evaluated according to RFC 6901.
|
|
267
|
+
* {@link https://tools.ietf.org/html/rfc6901#section-4}
|
|
268
|
+
*
|
|
269
|
+
* @param {Pointer} pointer - The JSON Pointer whose value will be modified
|
|
270
|
+
* @param {string} token - A JSON Pointer token that indicates how to modify `obj`
|
|
271
|
+
* @param {*} value - The value to assign
|
|
272
|
+
* @returns {*} - Returns the assigned value
|
|
273
|
+
*/ function setValue(pointer, token, value) {
|
|
274
|
+
if (pointer.value && typeof pointer.value === "object") {
|
|
275
|
+
if (token === "-" && Array.isArray(pointer.value)) {
|
|
276
|
+
pointer.value.push(value);
|
|
277
|
+
} else {
|
|
278
|
+
pointer.value[token] = value;
|
|
279
|
+
}
|
|
280
|
+
} else {
|
|
281
|
+
throw new _errorsJs.JSONParserError('Error assigning $ref pointer "'.concat(pointer.path, '". \nCannot set "').concat(token, '" of a non-object.'));
|
|
282
|
+
}
|
|
283
|
+
return value;
|
|
284
|
+
}
|
|
285
|
+
function unwrapOrThrow(value) {
|
|
286
|
+
if ((0, _errorsJs.isHandledError)(value)) {
|
|
287
|
+
throw value;
|
|
288
|
+
}
|
|
289
|
+
return value;
|
|
290
|
+
}
|
package/cjs/ref.js
ADDED
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "default", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return _default;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
var _pointerJs = /*#__PURE__*/ _interopRequireDefault(require("./pointer.js"));
|
|
12
|
+
var _errorsJs = require("./util/errors.js");
|
|
13
|
+
var _urlJs = require("./util/url.js");
|
|
14
|
+
function _arrayLikeToArray(arr, len) {
|
|
15
|
+
if (len == null || len > arr.length) len = arr.length;
|
|
16
|
+
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
17
|
+
return arr2;
|
|
18
|
+
}
|
|
19
|
+
function _arrayWithoutHoles(arr) {
|
|
20
|
+
if (Array.isArray(arr)) return _arrayLikeToArray(arr);
|
|
21
|
+
}
|
|
22
|
+
function _instanceof(left, right) {
|
|
23
|
+
if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
|
|
24
|
+
return !!right[Symbol.hasInstance](left);
|
|
25
|
+
} else {
|
|
26
|
+
return left instanceof right;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function _interopRequireDefault(obj) {
|
|
30
|
+
return obj && obj.__esModule ? obj : {
|
|
31
|
+
default: obj
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function _iterableToArray(iter) {
|
|
35
|
+
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
|
|
36
|
+
}
|
|
37
|
+
function _nonIterableSpread() {
|
|
38
|
+
throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
39
|
+
}
|
|
40
|
+
function _toConsumableArray(arr) {
|
|
41
|
+
return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
|
|
42
|
+
}
|
|
43
|
+
function _unsupportedIterableToArray(o, minLen) {
|
|
44
|
+
if (!o) return;
|
|
45
|
+
if (typeof o === "string") return _arrayLikeToArray(o, minLen);
|
|
46
|
+
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
47
|
+
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
48
|
+
if (n === "Map" || n === "Set") return Array.from(n);
|
|
49
|
+
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
|
|
50
|
+
}
|
|
51
|
+
var _default = $Ref;
|
|
52
|
+
/**
|
|
53
|
+
* This class represents a single JSON reference and its resolved value.
|
|
54
|
+
*
|
|
55
|
+
* @class
|
|
56
|
+
*/ function $Ref() {
|
|
57
|
+
/**
|
|
58
|
+
* The file path or URL of the referenced file.
|
|
59
|
+
* This path is relative to the path of the main JSON schema file.
|
|
60
|
+
*
|
|
61
|
+
* This path does NOT contain document fragments (JSON pointers). It always references an ENTIRE file.
|
|
62
|
+
* Use methods such as {@link $Ref#get}, {@link $Ref#resolve}, and {@link $Ref#exists} to get
|
|
63
|
+
* specific JSON pointers within the file.
|
|
64
|
+
*
|
|
65
|
+
* @type {string}
|
|
66
|
+
*/ this.path = undefined;
|
|
67
|
+
/**
|
|
68
|
+
* The resolved value of the JSON reference.
|
|
69
|
+
* Can be any JSON type, not just objects. Unknown file types are represented as Buffers (byte arrays).
|
|
70
|
+
*
|
|
71
|
+
* @type {?*}
|
|
72
|
+
*/ this.value = undefined;
|
|
73
|
+
/**
|
|
74
|
+
* The {@link $Refs} object that contains this {@link $Ref} object.
|
|
75
|
+
*
|
|
76
|
+
* @type {$Refs}
|
|
77
|
+
*/ this.$refs = undefined;
|
|
78
|
+
/**
|
|
79
|
+
* Indicates the type of {@link $Ref#path} (e.g. "file", "http", etc.)
|
|
80
|
+
*
|
|
81
|
+
* @type {?string}
|
|
82
|
+
*/ this.pathType = undefined;
|
|
83
|
+
/**
|
|
84
|
+
* List of all errors. Undefined if no errors.
|
|
85
|
+
*
|
|
86
|
+
* @type {Array<JSONParserError | ResolverError | ParserError | MissingPointerError>}
|
|
87
|
+
*/ this.errors = undefined;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Pushes an error to errors array.
|
|
91
|
+
*
|
|
92
|
+
* @param {Array<JSONParserError | JSONParserErrorGroup>} err - The error to be pushed
|
|
93
|
+
* @returns {void}
|
|
94
|
+
*/ $Ref.prototype.addError = function(err) {
|
|
95
|
+
if (this.errors === undefined) {
|
|
96
|
+
this.errors = [];
|
|
97
|
+
}
|
|
98
|
+
var existingErrors = this.errors.map(function(param) {
|
|
99
|
+
var footprint = param.footprint;
|
|
100
|
+
return footprint;
|
|
101
|
+
});
|
|
102
|
+
// the path has been almost certainly set at this point,
|
|
103
|
+
// but just in case something went wrong, normalizeError injects path if necessary
|
|
104
|
+
// moreover, certain errors might point at the same spot, so filter them out to reduce noise
|
|
105
|
+
if (Array.isArray(err.errors)) {
|
|
106
|
+
var _this_errors;
|
|
107
|
+
(_this_errors = this.errors).push.apply(_this_errors, _toConsumableArray(err.errors.map(_errorsJs.normalizeError).filter(function(param) {
|
|
108
|
+
var footprint = param.footprint;
|
|
109
|
+
return !existingErrors.includes(footprint);
|
|
110
|
+
})));
|
|
111
|
+
} else if (!existingErrors.includes(err.footprint)) {
|
|
112
|
+
this.errors.push((0, _errorsJs.normalizeError)(err));
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
/**
|
|
116
|
+
* Determines whether the given JSON reference exists within this {@link $Ref#value}.
|
|
117
|
+
*
|
|
118
|
+
* @param {string} path - The full path being resolved, optionally with a JSON pointer in the hash
|
|
119
|
+
* @param {$RefParserOptions} options
|
|
120
|
+
* @returns {boolean}
|
|
121
|
+
*/ $Ref.prototype.exists = function(path, options) {
|
|
122
|
+
try {
|
|
123
|
+
this.resolve(path, options);
|
|
124
|
+
return true;
|
|
125
|
+
} catch (e) {
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
/**
|
|
130
|
+
* Resolves the given JSON reference within this {@link $Ref#value} and returns the resolved value.
|
|
131
|
+
*
|
|
132
|
+
* @param {string} path - The full path being resolved, optionally with a JSON pointer in the hash
|
|
133
|
+
* @param {$RefParserOptions} options
|
|
134
|
+
* @returns {*} - Returns the resolved value
|
|
135
|
+
*/ $Ref.prototype.get = function(path, options) {
|
|
136
|
+
return this.resolve(path, options).value;
|
|
137
|
+
};
|
|
138
|
+
/**
|
|
139
|
+
* Resolves the given JSON reference within this {@link $Ref#value}.
|
|
140
|
+
*
|
|
141
|
+
* @param {string} path - The full path being resolved, optionally with a JSON pointer in the hash
|
|
142
|
+
* @param {$RefParserOptions} options
|
|
143
|
+
* @param {string} friendlyPath - The original user-specified path (used for error messages)
|
|
144
|
+
* @param {string} pathFromRoot - The path of `obj` from the schema root
|
|
145
|
+
* @returns {Pointer | null}
|
|
146
|
+
*/ $Ref.prototype.resolve = function(path, options, friendlyPath, pathFromRoot) {
|
|
147
|
+
var pointer = new _pointerJs.default(this, path, friendlyPath);
|
|
148
|
+
try {
|
|
149
|
+
return pointer.resolve(this.value, options, pathFromRoot);
|
|
150
|
+
} catch (err) {
|
|
151
|
+
if (!options || !options.continueOnError || !(0, _errorsJs.isHandledError)(err)) {
|
|
152
|
+
throw err;
|
|
153
|
+
}
|
|
154
|
+
if (err.path === null) {
|
|
155
|
+
err.path = (0, _urlJs.safePointerToPath)((0, _urlJs.getHash)(pathFromRoot));
|
|
156
|
+
}
|
|
157
|
+
if (_instanceof(err, _errorsJs.InvalidPointerError)) {
|
|
158
|
+
// this is a special case - InvalidPointerError is thrown when dereferencing external file,
|
|
159
|
+
// but the issue is caused by the source file that referenced the file that undergoes dereferencing
|
|
160
|
+
err.source = decodeURI((0, _urlJs.stripHash)(pathFromRoot));
|
|
161
|
+
}
|
|
162
|
+
this.addError(err);
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
/**
|
|
167
|
+
* Sets the value of a nested property within this {@link $Ref#value}.
|
|
168
|
+
* If the property, or any of its parents don't exist, they will be created.
|
|
169
|
+
*
|
|
170
|
+
* @param {string} path - The full path of the property to set, optionally with a JSON pointer in the hash
|
|
171
|
+
* @param {*} value - The value to assign
|
|
172
|
+
*/ $Ref.prototype.set = function(path, value) {
|
|
173
|
+
var pointer = new _pointerJs.default(this, path);
|
|
174
|
+
this.value = pointer.set(this.value, value);
|
|
175
|
+
};
|
|
176
|
+
/**
|
|
177
|
+
* Determines whether the given value is a JSON reference.
|
|
178
|
+
*
|
|
179
|
+
* @param {*} value - The value to inspect
|
|
180
|
+
* @returns {boolean}
|
|
181
|
+
*/ $Ref.is$Ref = function(value) {
|
|
182
|
+
return value && typeof value === "object" && typeof value.$ref === "string" && value.$ref.length > 0;
|
|
183
|
+
};
|
|
184
|
+
/**
|
|
185
|
+
* Determines whether the given value is an external JSON reference.
|
|
186
|
+
*
|
|
187
|
+
* @param {*} value - The value to inspect
|
|
188
|
+
* @returns {boolean}
|
|
189
|
+
*/ $Ref.isExternal$Ref = function(value) {
|
|
190
|
+
return $Ref.is$Ref(value) && value.$ref[0] !== "#";
|
|
191
|
+
};
|
|
192
|
+
/**
|
|
193
|
+
* Determines whether the given value is a JSON reference, and whether it is allowed by the options.
|
|
194
|
+
* For example, if it references an external file, then options.resolve.external must be true.
|
|
195
|
+
*
|
|
196
|
+
* @param {*} value - The value to inspect
|
|
197
|
+
* @param {$RefParserOptions} options
|
|
198
|
+
* @returns {boolean}
|
|
199
|
+
*/ $Ref.isAllowed$Ref = function(value, options) {
|
|
200
|
+
if ($Ref.is$Ref(value)) {
|
|
201
|
+
if (value.$ref.substr(0, 2) === "#/" || value.$ref === "#") {
|
|
202
|
+
// It's a JSON Pointer reference, which is always allowed
|
|
203
|
+
return true;
|
|
204
|
+
} else if (value.$ref[0] !== "#" && (!options || options.resolve.external)) {
|
|
205
|
+
// It's an external reference, which is allowed by the options
|
|
206
|
+
return true;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
/**
|
|
211
|
+
* Determines whether the given value is a JSON reference that "extends" its resolved value.
|
|
212
|
+
* That is, it has extra properties (in addition to "$ref"), so rather than simply pointing to
|
|
213
|
+
* an existing value, this $ref actually creates a NEW value that is a shallow copy of the resolved
|
|
214
|
+
* value, plus the extra properties.
|
|
215
|
+
*
|
|
216
|
+
* @example:
|
|
217
|
+
* {
|
|
218
|
+
* person: {
|
|
219
|
+
* properties: {
|
|
220
|
+
* firstName: { type: string }
|
|
221
|
+
* lastName: { type: string }
|
|
222
|
+
* }
|
|
223
|
+
* }
|
|
224
|
+
* employee: {
|
|
225
|
+
* properties: {
|
|
226
|
+
* $ref: #/person/properties
|
|
227
|
+
* salary: { type: number }
|
|
228
|
+
* }
|
|
229
|
+
* }
|
|
230
|
+
* }
|
|
231
|
+
*
|
|
232
|
+
* In this example, "employee" is an extended $ref, since it extends "person" with an additional
|
|
233
|
+
* property (salary). The result is a NEW value that looks like this:
|
|
234
|
+
*
|
|
235
|
+
* {
|
|
236
|
+
* properties: {
|
|
237
|
+
* firstName: { type: string }
|
|
238
|
+
* lastName: { type: string }
|
|
239
|
+
* salary: { type: number }
|
|
240
|
+
* }
|
|
241
|
+
* }
|
|
242
|
+
*
|
|
243
|
+
* @param {*} value - The value to inspect
|
|
244
|
+
* @returns {boolean}
|
|
245
|
+
*/ $Ref.isExtended$Ref = function(value) {
|
|
246
|
+
return $Ref.is$Ref(value) && Object.keys(value).length > 1;
|
|
247
|
+
};
|
|
248
|
+
/**
|
|
249
|
+
* Returns the resolved value of a JSON Reference.
|
|
250
|
+
* If necessary, the resolved value is merged with the JSON Reference to create a new object
|
|
251
|
+
*
|
|
252
|
+
* @example:
|
|
253
|
+
* {
|
|
254
|
+
* person: {
|
|
255
|
+
* properties: {
|
|
256
|
+
* firstName: { type: string }
|
|
257
|
+
* lastName: { type: string }
|
|
258
|
+
* }
|
|
259
|
+
* }
|
|
260
|
+
* employee: {
|
|
261
|
+
* properties: {
|
|
262
|
+
* $ref: #/person/properties
|
|
263
|
+
* salary: { type: number }
|
|
264
|
+
* }
|
|
265
|
+
* }
|
|
266
|
+
* }
|
|
267
|
+
*
|
|
268
|
+
* When "person" and "employee" are merged, you end up with the following object:
|
|
269
|
+
*
|
|
270
|
+
* {
|
|
271
|
+
* properties: {
|
|
272
|
+
* firstName: { type: string }
|
|
273
|
+
* lastName: { type: string }
|
|
274
|
+
* salary: { type: number }
|
|
275
|
+
* }
|
|
276
|
+
* }
|
|
277
|
+
*
|
|
278
|
+
* @param {object} $ref - The JSON reference object (the one with the "$ref" property)
|
|
279
|
+
* @param {*} resolvedValue - The resolved value, which can be any type
|
|
280
|
+
* @returns {*} - Returns the dereferenced value
|
|
281
|
+
*/ $Ref.dereference = function($ref, resolvedValue) {
|
|
282
|
+
if (resolvedValue && typeof resolvedValue === "object" && $Ref.isExtended$Ref($ref)) {
|
|
283
|
+
var merged = {};
|
|
284
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
285
|
+
try {
|
|
286
|
+
for(var _iterator = Object.keys($ref)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
287
|
+
var key = _step.value;
|
|
288
|
+
if (key !== "$ref") {
|
|
289
|
+
merged[key] = $ref[key];
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
} catch (err) {
|
|
293
|
+
_didIteratorError = true;
|
|
294
|
+
_iteratorError = err;
|
|
295
|
+
} finally{
|
|
296
|
+
try {
|
|
297
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
298
|
+
_iterator.return();
|
|
299
|
+
}
|
|
300
|
+
} finally{
|
|
301
|
+
if (_didIteratorError) {
|
|
302
|
+
throw _iteratorError;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
|
|
307
|
+
try {
|
|
308
|
+
for(var _iterator1 = Object.keys(resolvedValue)[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
|
|
309
|
+
var key1 = _step1.value;
|
|
310
|
+
if (!(key1 in merged)) {
|
|
311
|
+
merged[key1] = resolvedValue[key1];
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
} catch (err) {
|
|
315
|
+
_didIteratorError1 = true;
|
|
316
|
+
_iteratorError1 = err;
|
|
317
|
+
} finally{
|
|
318
|
+
try {
|
|
319
|
+
if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
|
|
320
|
+
_iterator1.return();
|
|
321
|
+
}
|
|
322
|
+
} finally{
|
|
323
|
+
if (_didIteratorError1) {
|
|
324
|
+
throw _iteratorError1;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
return merged;
|
|
329
|
+
} else {
|
|
330
|
+
// Completely replace the original reference with the resolved value
|
|
331
|
+
return resolvedValue;
|
|
332
|
+
}
|
|
333
|
+
};
|