@hey-api/json-schema-ref-parser 0.0.1

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.
Files changed (68) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +138 -0
  3. package/dist/lib/bundle.d.ts +26 -0
  4. package/dist/lib/bundle.js +293 -0
  5. package/dist/lib/dereference.d.ts +11 -0
  6. package/dist/lib/dereference.js +224 -0
  7. package/dist/lib/index.d.ts +74 -0
  8. package/dist/lib/index.js +208 -0
  9. package/dist/lib/options.d.ts +61 -0
  10. package/dist/lib/options.js +45 -0
  11. package/dist/lib/parse.d.ts +13 -0
  12. package/dist/lib/parse.js +87 -0
  13. package/dist/lib/parsers/binary.d.ts +2 -0
  14. package/dist/lib/parsers/binary.js +12 -0
  15. package/dist/lib/parsers/json.d.ts +2 -0
  16. package/dist/lib/parsers/json.js +38 -0
  17. package/dist/lib/parsers/text.d.ts +2 -0
  18. package/dist/lib/parsers/text.js +18 -0
  19. package/dist/lib/parsers/yaml.d.ts +2 -0
  20. package/dist/lib/parsers/yaml.js +28 -0
  21. package/dist/lib/pointer.d.ts +88 -0
  22. package/dist/lib/pointer.js +293 -0
  23. package/dist/lib/ref.d.ts +180 -0
  24. package/dist/lib/ref.js +226 -0
  25. package/dist/lib/refs.d.ts +127 -0
  26. package/dist/lib/refs.js +232 -0
  27. package/dist/lib/resolve-external.d.ts +13 -0
  28. package/dist/lib/resolve-external.js +147 -0
  29. package/dist/lib/resolvers/file.d.ts +4 -0
  30. package/dist/lib/resolvers/file.js +61 -0
  31. package/dist/lib/resolvers/url.d.ts +11 -0
  32. package/dist/lib/resolvers/url.js +57 -0
  33. package/dist/lib/types/index.d.ts +43 -0
  34. package/dist/lib/types/index.js +2 -0
  35. package/dist/lib/util/convert-path-to-posix.d.ts +1 -0
  36. package/dist/lib/util/convert-path-to-posix.js +14 -0
  37. package/dist/lib/util/errors.d.ts +56 -0
  38. package/dist/lib/util/errors.js +112 -0
  39. package/dist/lib/util/is-windows.d.ts +1 -0
  40. package/dist/lib/util/is-windows.js +6 -0
  41. package/dist/lib/util/plugins.d.ts +16 -0
  42. package/dist/lib/util/plugins.js +45 -0
  43. package/dist/lib/util/url.d.ts +79 -0
  44. package/dist/lib/util/url.js +285 -0
  45. package/dist/vite.config.d.ts +2 -0
  46. package/dist/vite.config.js +18 -0
  47. package/lib/bundle.ts +299 -0
  48. package/lib/dereference.ts +286 -0
  49. package/lib/index.ts +209 -0
  50. package/lib/options.ts +108 -0
  51. package/lib/parse.ts +56 -0
  52. package/lib/parsers/binary.ts +13 -0
  53. package/lib/parsers/json.ts +39 -0
  54. package/lib/parsers/text.ts +21 -0
  55. package/lib/parsers/yaml.ts +26 -0
  56. package/lib/pointer.ts +327 -0
  57. package/lib/ref.ts +279 -0
  58. package/lib/refs.ts +239 -0
  59. package/lib/resolve-external.ts +141 -0
  60. package/lib/resolvers/file.ts +24 -0
  61. package/lib/resolvers/url.ts +78 -0
  62. package/lib/types/index.ts +51 -0
  63. package/lib/util/convert-path-to-posix.ts +11 -0
  64. package/lib/util/errors.ts +153 -0
  65. package/lib/util/is-windows.ts +2 -0
  66. package/lib/util/plugins.ts +56 -0
  67. package/lib/util/url.ts +266 -0
  68. package/package.json +96 -0
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.parseFile = void 0;
37
+ exports.newFile = newFile;
38
+ const ono_1 = require("@jsdevtools/ono");
39
+ const url_js_1 = require("./util/url.js");
40
+ const plugins = __importStar(require("./util/plugins.js"));
41
+ const errors_js_1 = require("./util/errors.js");
42
+ /**
43
+ * Prepares the file object so we can populate it with data and other values
44
+ * when it's read and parsed. This "file object" will be passed to all
45
+ * resolvers and parsers.
46
+ */
47
+ function newFile(path) {
48
+ let url = path;
49
+ // Remove the URL fragment, if any
50
+ const hashIndex = url.indexOf("#");
51
+ let hash = "";
52
+ if (hashIndex > -1) {
53
+ hash = url.substring(hashIndex);
54
+ url = url.substring(0, hashIndex);
55
+ }
56
+ return {
57
+ extension: (0, url_js_1.getExtension)(url),
58
+ hash,
59
+ url,
60
+ };
61
+ }
62
+ /**
63
+ * Parses the given file's contents, using the configured parser plugins.
64
+ */
65
+ const parseFile = async (file, options) => {
66
+ try {
67
+ // If none of the parsers are a match for this file, try all of them. This
68
+ // handles situations where the file is a supported type, just with an
69
+ // unknown extension.
70
+ const parsers = [options.parse.json, options.parse.yaml, options.parse.text, options.parse.binary];
71
+ const filtered = parsers.filter((plugin) => plugin.canHandle(file));
72
+ return await plugins.run(filtered.length ? filtered : parsers, file);
73
+ }
74
+ catch (error) {
75
+ if (error && error.message && error.message.startsWith("Error parsing")) {
76
+ throw error;
77
+ }
78
+ if (!error || !("error" in error)) {
79
+ throw ono_1.ono.syntax(`Unable to parse ${file.url}`);
80
+ }
81
+ if (error.error instanceof errors_js_1.ParserError) {
82
+ throw error.error;
83
+ }
84
+ throw new errors_js_1.ParserError(error.error.message, file.url);
85
+ }
86
+ };
87
+ exports.parseFile = parseFile;
@@ -0,0 +1,2 @@
1
+ import type { Plugin } from "../types/index.js";
2
+ export declare const binaryParser: Plugin;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.binaryParser = void 0;
4
+ const BINARY_REGEXP = /\.(jpeg|jpg|gif|png|bmp|ico)$/i;
5
+ exports.binaryParser = {
6
+ canHandle: (file) => Buffer.isBuffer(file.data) && BINARY_REGEXP.test(file.url),
7
+ handler: (file) => Buffer.isBuffer(file.data)
8
+ ? file.data
9
+ // This will reject if data is anything other than a string or typed array
10
+ : Buffer.from(file.data),
11
+ name: 'binary',
12
+ };
@@ -0,0 +1,2 @@
1
+ import type { Plugin } from "../types/index.js";
2
+ export declare const jsonParser: Plugin;
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.jsonParser = void 0;
4
+ const errors_js_1 = require("../util/errors.js");
5
+ exports.jsonParser = {
6
+ canHandle: (file) => file.extension === '.json',
7
+ async handler(file) {
8
+ let data = file.data;
9
+ if (Buffer.isBuffer(data)) {
10
+ data = data.toString();
11
+ }
12
+ if (typeof data !== "string") {
13
+ // data is already a JavaScript value (object, array, number, null, NaN, etc.)
14
+ return data;
15
+ }
16
+ if (!data.trim().length) {
17
+ // this mirrors the YAML behavior
18
+ return;
19
+ }
20
+ try {
21
+ return JSON.parse(data);
22
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
23
+ }
24
+ catch (error) {
25
+ try {
26
+ // find the first curly brace
27
+ const firstCurlyBrace = data.indexOf("{");
28
+ // remove any characters before the first curly brace
29
+ data = data.slice(firstCurlyBrace);
30
+ return JSON.parse(data);
31
+ }
32
+ catch (error) {
33
+ throw new errors_js_1.ParserError(error.message, file.url);
34
+ }
35
+ }
36
+ },
37
+ name: 'json',
38
+ };
@@ -0,0 +1,2 @@
1
+ import type { Plugin } from "../types/index.js";
2
+ export declare const textParser: Plugin;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.textParser = void 0;
4
+ const errors_js_1 = require("../util/errors.js");
5
+ const TEXT_REGEXP = /\.(txt|htm|html|md|xml|js|min|map|css|scss|less|svg)$/i;
6
+ exports.textParser = {
7
+ canHandle: (file) => (typeof file.data === "string" || Buffer.isBuffer(file.data)) && TEXT_REGEXP.test(file.url),
8
+ handler(file) {
9
+ if (typeof file.data === "string") {
10
+ return file.data;
11
+ }
12
+ if (!Buffer.isBuffer(file.data)) {
13
+ throw new errors_js_1.ParserError("data is not text", file.url);
14
+ }
15
+ return file.data.toString('utf-8');
16
+ },
17
+ name: 'text',
18
+ };
@@ -0,0 +1,2 @@
1
+ import type { Plugin } from "../types/index.js";
2
+ export declare const yamlParser: Plugin;
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.yamlParser = void 0;
7
+ const errors_js_1 = require("../util/errors.js");
8
+ const js_yaml_1 = __importDefault(require("js-yaml"));
9
+ const js_yaml_2 = require("js-yaml");
10
+ exports.yamlParser = {
11
+ // JSON is valid YAML
12
+ canHandle: (file) => [".yaml", ".yml", ".json"].includes(file.extension),
13
+ handler: async (file) => {
14
+ const data = Buffer.isBuffer(file.data) ? file.data.toString() : file.data;
15
+ if (typeof data !== "string") {
16
+ // data is already a JavaScript value (object, array, number, null, NaN, etc.)
17
+ return data;
18
+ }
19
+ try {
20
+ const yamlSchema = js_yaml_1.default.load(data, { schema: js_yaml_2.JSON_SCHEMA });
21
+ return yamlSchema;
22
+ }
23
+ catch (error) {
24
+ throw new errors_js_1.ParserError(error?.message || "Parser Error", file.url);
25
+ }
26
+ },
27
+ name: 'yaml',
28
+ };
@@ -0,0 +1,88 @@
1
+ import type { ParserOptions } from "./options.js";
2
+ import $Ref from "./ref.js";
3
+ import type { JSONSchema } from "./types";
4
+ /**
5
+ * This class represents a single JSON pointer and its resolved value.
6
+ *
7
+ * @param $ref
8
+ * @param path
9
+ * @param [friendlyPath] - The original user-specified path (used for error messages)
10
+ * @class
11
+ */
12
+ declare class Pointer<S extends object = JSONSchema> {
13
+ /**
14
+ * The {@link $Ref} object that contains this {@link Pointer} object.
15
+ */
16
+ $ref: $Ref<S>;
17
+ /**
18
+ * The file path or URL, containing the JSON pointer in the hash.
19
+ * This path is relative to the path of the main JSON schema file.
20
+ */
21
+ path: string;
22
+ /**
23
+ * The original path or URL, used for error messages.
24
+ */
25
+ originalPath: string;
26
+ /**
27
+ * The value of the JSON pointer.
28
+ * Can be any JSON type, not just objects. Unknown file types are represented as Buffers (byte arrays).
29
+ */
30
+ value: any;
31
+ /**
32
+ * Indicates whether the pointer references itself.
33
+ */
34
+ circular: boolean;
35
+ /**
36
+ * The number of indirect references that were traversed to resolve the value.
37
+ * Resolving a single pointer may require resolving multiple $Refs.
38
+ */
39
+ indirections: number;
40
+ constructor($ref: $Ref<S>, path: string, friendlyPath?: string);
41
+ /**
42
+ * Resolves the value of a nested property within the given object.
43
+ *
44
+ * @param obj - The object that will be crawled
45
+ * @param options
46
+ * @param pathFromRoot - the path of place that initiated resolving
47
+ *
48
+ * @returns
49
+ * Returns a JSON pointer whose {@link Pointer#value} is the resolved value.
50
+ * If resolving this value required resolving other JSON references, then
51
+ * the {@link Pointer#$ref} and {@link Pointer#path} will reflect the resolution path
52
+ * of the resolved value.
53
+ */
54
+ resolve(obj: S, options?: ParserOptions, pathFromRoot?: string): this;
55
+ /**
56
+ * Sets the value of a nested property within the given object.
57
+ *
58
+ * @param obj - The object that will be crawled
59
+ * @param value - the value to assign
60
+ * @param options
61
+ *
62
+ * @returns
63
+ * Returns the modified object, or an entirely new object if the entire object is overwritten.
64
+ */
65
+ set(obj: S, value: any, options?: ParserOptions): any;
66
+ /**
67
+ * Parses a JSON pointer (or a path containing a JSON pointer in the hash)
68
+ * and returns an array of the pointer's tokens.
69
+ * (e.g. "schema.json#/definitions/person/name" => ["definitions", "person", "name"])
70
+ *
71
+ * The pointer is parsed according to RFC 6901
72
+ * {@link https://tools.ietf.org/html/rfc6901#section-3}
73
+ *
74
+ * @param path
75
+ * @param [originalPath]
76
+ * @returns
77
+ */
78
+ static parse(path: string, originalPath?: string): string[];
79
+ /**
80
+ * Creates a JSON pointer path, by joining one or more tokens to a base path.
81
+ *
82
+ * @param base - The base path (e.g. "schema.json#/definitions/person")
83
+ * @param tokens - The token(s) to append (e.g. ["name", "first"])
84
+ * @returns
85
+ */
86
+ static join(base: string, tokens: string | string[]): string;
87
+ }
88
+ export default Pointer;
@@ -0,0 +1,293 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ const ref_js_1 = __importDefault(require("./ref.js"));
40
+ const url = __importStar(require("./util/url.js"));
41
+ const errors_js_1 = require("./util/errors.js");
42
+ const slashes = /\//g;
43
+ const tildes = /~/g;
44
+ const escapedSlash = /~1/g;
45
+ const escapedTilde = /~0/g;
46
+ const safeDecodeURIComponent = (encodedURIComponent) => {
47
+ try {
48
+ return decodeURIComponent(encodedURIComponent);
49
+ }
50
+ catch {
51
+ return encodedURIComponent;
52
+ }
53
+ };
54
+ /**
55
+ * This class represents a single JSON pointer and its resolved value.
56
+ *
57
+ * @param $ref
58
+ * @param path
59
+ * @param [friendlyPath] - The original user-specified path (used for error messages)
60
+ * @class
61
+ */
62
+ class Pointer {
63
+ constructor($ref, path, friendlyPath) {
64
+ this.$ref = $ref;
65
+ this.path = path;
66
+ this.originalPath = friendlyPath || path;
67
+ this.value = undefined;
68
+ this.circular = false;
69
+ this.indirections = 0;
70
+ }
71
+ /**
72
+ * Resolves the value of a nested property within the given object.
73
+ *
74
+ * @param obj - The object that will be crawled
75
+ * @param options
76
+ * @param pathFromRoot - the path of place that initiated resolving
77
+ *
78
+ * @returns
79
+ * Returns a JSON pointer whose {@link Pointer#value} is the resolved value.
80
+ * If resolving this value required resolving other JSON references, then
81
+ * the {@link Pointer#$ref} and {@link Pointer#path} will reflect the resolution path
82
+ * of the resolved value.
83
+ */
84
+ resolve(obj, options, pathFromRoot) {
85
+ const tokens = Pointer.parse(this.path, this.originalPath);
86
+ // Crawl the object, one token at a time
87
+ this.value = unwrapOrThrow(obj);
88
+ for (let i = 0; i < tokens.length; i++) {
89
+ if (resolveIf$Ref(this, options, pathFromRoot)) {
90
+ // The $ref path has changed, so append the remaining tokens to the path
91
+ this.path = Pointer.join(this.path, tokens.slice(i));
92
+ }
93
+ if (typeof this.value === "object" && this.value !== null && !isRootPath(pathFromRoot) && "$ref" in this.value) {
94
+ return this;
95
+ }
96
+ const token = tokens[i];
97
+ if (this.value[token] === undefined || (this.value[token] === null && i === tokens.length - 1)) {
98
+ // one final case is if the entry itself includes slashes, and was parsed out as a token - we can join the remaining tokens and try again
99
+ let didFindSubstringSlashMatch = false;
100
+ for (let j = tokens.length - 1; j > i; j--) {
101
+ const joinedToken = tokens.slice(i, j + 1).join("/");
102
+ if (this.value[joinedToken] !== undefined) {
103
+ this.value = this.value[joinedToken];
104
+ i = j;
105
+ didFindSubstringSlashMatch = true;
106
+ break;
107
+ }
108
+ }
109
+ if (didFindSubstringSlashMatch) {
110
+ continue;
111
+ }
112
+ this.value = null;
113
+ throw new errors_js_1.MissingPointerError(token, decodeURI(this.originalPath));
114
+ }
115
+ else {
116
+ this.value = this.value[token];
117
+ }
118
+ }
119
+ // Resolve the final value
120
+ if (!this.value || (this.value.$ref && url.resolve(this.path, this.value.$ref) !== pathFromRoot)) {
121
+ resolveIf$Ref(this, options, pathFromRoot);
122
+ }
123
+ return this;
124
+ }
125
+ /**
126
+ * Sets the value of a nested property within the given object.
127
+ *
128
+ * @param obj - The object that will be crawled
129
+ * @param value - the value to assign
130
+ * @param options
131
+ *
132
+ * @returns
133
+ * Returns the modified object, or an entirely new object if the entire object is overwritten.
134
+ */
135
+ set(obj, value, options) {
136
+ const tokens = Pointer.parse(this.path);
137
+ let token;
138
+ if (tokens.length === 0) {
139
+ // There are no tokens, replace the entire object with the new value
140
+ this.value = value;
141
+ return value;
142
+ }
143
+ // Crawl the object, one token at a time
144
+ this.value = unwrapOrThrow(obj);
145
+ for (let i = 0; i < tokens.length - 1; i++) {
146
+ resolveIf$Ref(this, options);
147
+ token = tokens[i];
148
+ if (this.value && this.value[token] !== undefined) {
149
+ // The token exists
150
+ this.value = this.value[token];
151
+ }
152
+ else {
153
+ // The token doesn't exist, so create it
154
+ this.value = setValue(this, token, {});
155
+ }
156
+ }
157
+ // Set the value of the final token
158
+ resolveIf$Ref(this, options);
159
+ token = tokens[tokens.length - 1];
160
+ setValue(this, token, value);
161
+ // Return the updated object
162
+ return obj;
163
+ }
164
+ /**
165
+ * Parses a JSON pointer (or a path containing a JSON pointer in the hash)
166
+ * and returns an array of the pointer's tokens.
167
+ * (e.g. "schema.json#/definitions/person/name" => ["definitions", "person", "name"])
168
+ *
169
+ * The pointer is parsed according to RFC 6901
170
+ * {@link https://tools.ietf.org/html/rfc6901#section-3}
171
+ *
172
+ * @param path
173
+ * @param [originalPath]
174
+ * @returns
175
+ */
176
+ static parse(path, originalPath) {
177
+ // Get the JSON pointer from the path's hash
178
+ const pointer = url.getHash(path).substring(1);
179
+ // If there's no pointer, then there are no tokens,
180
+ // so return an empty array
181
+ if (!pointer) {
182
+ return [];
183
+ }
184
+ // Split into an array
185
+ const split = pointer.split("/");
186
+ // Decode each part, according to RFC 6901
187
+ for (let i = 0; i < split.length; i++) {
188
+ split[i] = safeDecodeURIComponent(split[i].replace(escapedSlash, "/").replace(escapedTilde, "~"));
189
+ }
190
+ if (split[0] !== "") {
191
+ throw new errors_js_1.InvalidPointerError(pointer, originalPath === undefined ? path : originalPath);
192
+ }
193
+ return split.slice(1);
194
+ }
195
+ /**
196
+ * Creates a JSON pointer path, by joining one or more tokens to a base path.
197
+ *
198
+ * @param base - The base path (e.g. "schema.json#/definitions/person")
199
+ * @param tokens - The token(s) to append (e.g. ["name", "first"])
200
+ * @returns
201
+ */
202
+ static join(base, tokens) {
203
+ // Ensure that the base path contains a hash
204
+ if (base.indexOf("#") === -1) {
205
+ base += "#";
206
+ }
207
+ // Append each token to the base path
208
+ tokens = Array.isArray(tokens) ? tokens : [tokens];
209
+ for (let i = 0; i < tokens.length; i++) {
210
+ const token = tokens[i];
211
+ // Encode the token, according to RFC 6901
212
+ base += "/" + encodeURIComponent(token.replace(tildes, "~0").replace(slashes, "~1"));
213
+ }
214
+ return base;
215
+ }
216
+ }
217
+ /**
218
+ * If the given pointer's {@link Pointer#value} is a JSON reference,
219
+ * then the reference is resolved and {@link Pointer#value} is replaced with the resolved value.
220
+ * In addition, {@link Pointer#path} and {@link Pointer#$ref} are updated to reflect the
221
+ * resolution path of the new value.
222
+ *
223
+ * @param pointer
224
+ * @param options
225
+ * @param [pathFromRoot] - the path of place that initiated resolving
226
+ * @returns - Returns `true` if the resolution path changed
227
+ */
228
+ function resolveIf$Ref(pointer, options, pathFromRoot) {
229
+ // Is the value a JSON reference? (and allowed?)
230
+ if (ref_js_1.default.isAllowed$Ref(pointer.value)) {
231
+ const $refPath = url.resolve(pointer.path, pointer.value.$ref);
232
+ if ($refPath === pointer.path && !isRootPath(pathFromRoot)) {
233
+ // The value is a reference to itself, so there's nothing to do.
234
+ pointer.circular = true;
235
+ }
236
+ else {
237
+ const resolved = pointer.$ref.$refs._resolve($refPath, pointer.path, options);
238
+ if (resolved === null) {
239
+ return false;
240
+ }
241
+ pointer.indirections += resolved.indirections + 1;
242
+ if (ref_js_1.default.isExtended$Ref(pointer.value)) {
243
+ // This JSON reference "extends" the resolved value, rather than simply pointing to it.
244
+ // So the resolved path does NOT change. Just the value does.
245
+ pointer.value = ref_js_1.default.dereference(pointer.value, resolved.value);
246
+ return false;
247
+ }
248
+ else {
249
+ // Resolve the reference
250
+ pointer.$ref = resolved.$ref;
251
+ pointer.path = resolved.path;
252
+ pointer.value = resolved.value;
253
+ }
254
+ return true;
255
+ }
256
+ }
257
+ return undefined;
258
+ }
259
+ exports.default = Pointer;
260
+ /**
261
+ * Sets the specified token value of the {@link Pointer#value}.
262
+ *
263
+ * The token is evaluated according to RFC 6901.
264
+ * {@link https://tools.ietf.org/html/rfc6901#section-4}
265
+ *
266
+ * @param pointer - The JSON Pointer whose value will be modified
267
+ * @param token - A JSON Pointer token that indicates how to modify `obj`
268
+ * @param value - The value to assign
269
+ * @returns - Returns the assigned value
270
+ */
271
+ function setValue(pointer, token, value) {
272
+ if (pointer.value && typeof pointer.value === "object") {
273
+ if (token === "-" && Array.isArray(pointer.value)) {
274
+ pointer.value.push(value);
275
+ }
276
+ else {
277
+ pointer.value[token] = value;
278
+ }
279
+ }
280
+ else {
281
+ throw new errors_js_1.JSONParserError(`Error assigning $ref pointer "${pointer.path}". \nCannot set "${token}" of a non-object.`);
282
+ }
283
+ return value;
284
+ }
285
+ function unwrapOrThrow(value) {
286
+ if ((0, errors_js_1.isHandledError)(value)) {
287
+ throw value;
288
+ }
289
+ return value;
290
+ }
291
+ function isRootPath(pathFromRoot) {
292
+ return typeof pathFromRoot == "string" && Pointer.parse(pathFromRoot).length == 0;
293
+ }