@apidevtools/json-schema-ref-parser 11.0.0 → 11.1.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.
@@ -130,7 +130,9 @@ function crawl(obj, path, pathFromRoot, parents, processedObjects, dereferencedC
130
130
  */
131
131
  function dereference$Ref($ref, path, pathFromRoot, parents, processedObjects, dereferencedCache, $refs, options) {
132
132
  // console.log('Dereferencing $ref pointer "%s" at %s', $ref.$ref, path);
133
- const $refPath = url.resolve(path, $ref.$ref);
133
+ const isExternalRef = ref_js_1.default.isExternal$Ref($ref);
134
+ const shouldResolveOnCwd = isExternalRef && options?.dereference.externalReferenceResolution === "root";
135
+ const $refPath = url.resolve(shouldResolveOnCwd ? url.cwd() : path, $ref.$ref);
134
136
  const cache = dereferencedCache.get($refPath);
135
137
  if (cache) {
136
138
  const refKeys = Object.keys($ref);
package/dist/lib/index.js CHANGED
@@ -88,6 +88,13 @@ class $RefParser {
88
88
  args.path = url.fromFileSystemPath(args.path);
89
89
  pathType = "file";
90
90
  }
91
+ else if (!args.path && args.schema && args.schema.$id) {
92
+ // when schema id has defined an URL should use that hostname to request the references,
93
+ // instead of using the current page URL
94
+ const params = url.parse(args.schema.$id);
95
+ const port = params.protocol === "https:" ? 443 : 80;
96
+ args.path = `${params.protocol}//${params.hostname}:${port}`;
97
+ }
91
98
  // Resolve the absolute path of the schema
92
99
  args.path = url.resolve(url.cwd(), args.path);
93
100
  if (args.schema && typeof args.schema === "object") {
@@ -69,6 +69,12 @@ interface $RefParserOptions {
69
69
  * @argument {JSONSchemaObject} object The JSON-Schema that the `$ref` resolved to.
70
70
  */
71
71
  onDereference?(path: string, value: JSONSchemaObject): void;
72
+ /**
73
+ * Whether a reference should resolve relative to its directory/path, or from the cwd
74
+ *
75
+ * Default: `relative`
76
+ */
77
+ externalReferenceResolution?: "relative" | "root";
72
78
  };
73
79
  }
74
80
  export declare const getNewOptions: (options: DeepPartial<$RefParserOptions>) => $RefParserOptions;
@@ -69,6 +69,7 @@ const getDefaults = () => {
69
69
  * @type {function}
70
70
  */
71
71
  excludedPathMatcher: () => false,
72
+ referenceResolution: "relative",
72
73
  },
73
74
  };
74
75
  return (0, lodash_clonedeep_1.default)(defaults);
@@ -102,8 +102,8 @@ function crawl(obj, path, $refs, options, seen, external) {
102
102
  * including nested references that are contained in externally-referenced files.
103
103
  */
104
104
  async function resolve$Ref($ref, path, $refs, options) {
105
- // console.log('Resolving $ref pointer "%s" at %s', $ref.$ref, path);
106
- const resolvedPath = url.resolve(path, $ref.$ref);
105
+ const shouldResolveOnCwd = options.dereference.externalReferenceResolution === "root";
106
+ const resolvedPath = url.resolve(shouldResolveOnCwd ? url.cwd() : path, $ref.$ref);
107
107
  const withoutHash = url.stripHash(resolvedPath);
108
108
  // $ref.$ref = url.relative($refs._root$Ref.path, resolvedPath);
109
109
  // Do we already have this $ref?
@@ -97,7 +97,7 @@ async function download(u, httpOptions, _redirects) {
97
97
  throw (0, ono_1.ono)({ status: res.status }, `HTTP ${res.status} redirect with no location header`);
98
98
  }
99
99
  else {
100
- const redirectTo = url.resolve(u, res.headers.location);
100
+ const redirectTo = url.resolve(u.href, res.headers.location);
101
101
  return download(redirectTo, httpOptions, redirects);
102
102
  }
103
103
  }
@@ -1,10 +1,10 @@
1
- export declare const parse: (u: any) => URL;
1
+ export declare const parse: (u: string | URL) => URL;
2
2
  /**
3
3
  * Returns resolved target URL relative to a base URL in a manner similar to that of a Web browser resolving an anchor tag HREF.
4
4
  *
5
5
  * @returns
6
6
  */
7
- export declare function resolve(from: any, to: any): string;
7
+ export declare function resolve(from: string, to: string): string;
8
8
  /**
9
9
  * Returns the current working directory (in Node) or the current page URL (in browsers).
10
10
  *
@@ -91,4 +91,4 @@ export declare function toFileSystemPath(path: string | undefined, keepFileProto
91
91
  * @returns
92
92
  */
93
93
  export declare function safePointerToPath(pointer: any): any;
94
- export declare function relative(from: string | undefined, to: string | undefined): string;
94
+ export declare function relative(from: string, to: string): string;
@@ -48,7 +48,8 @@ exports.parse = parse;
48
48
  * @returns
49
49
  */
50
50
  function resolve(from, to) {
51
- const resolvedUrl = new URL(to, new URL(from, "resolve://"));
51
+ const fromUrl = new URL((0, convert_path_to_posix_1.default)(from), "resolve://");
52
+ const resolvedUrl = new URL((0, convert_path_to_posix_1.default)(to), fromUrl);
52
53
  if (resolvedUrl.protocol === "resolve:") {
53
54
  // `from` is a relative URL.
54
55
  const { pathname, search, hash } = resolvedUrl;
@@ -169,7 +169,9 @@ function dereference$Ref(
169
169
  ) {
170
170
  // console.log('Dereferencing $ref pointer "%s" at %s', $ref.$ref, path);
171
171
 
172
- const $refPath = url.resolve(path, $ref.$ref);
172
+ const isExternalRef = $Ref.isExternal$Ref($ref);
173
+ const shouldResolveOnCwd = isExternalRef && options?.dereference.externalReferenceResolution === "root";
174
+ const $refPath = url.resolve(shouldResolveOnCwd ? url.cwd() : path, $ref.$ref);
173
175
 
174
176
  const cache = dereferencedCache.get($refPath);
175
177
  if (cache) {
package/lib/index.ts CHANGED
@@ -100,6 +100,13 @@ export class $RefParser {
100
100
  if (url.isFileSystemPath(args.path)) {
101
101
  args.path = url.fromFileSystemPath(args.path);
102
102
  pathType = "file";
103
+ } else if (!args.path && args.schema && args.schema.$id) {
104
+ // when schema id has defined an URL should use that hostname to request the references,
105
+ // instead of using the current page URL
106
+ const params = url.parse(args.schema.$id);
107
+ const port = params.protocol === "https:" ? 443 : 80;
108
+
109
+ args.path = `${params.protocol}//${params.hostname}:${port}`;
103
110
  }
104
111
 
105
112
  // Resolve the absolute path of the schema
package/lib/options.ts CHANGED
@@ -83,6 +83,13 @@ interface $RefParserOptions {
83
83
  * @argument {JSONSchemaObject} object The JSON-Schema that the `$ref` resolved to.
84
84
  */
85
85
  onDereference?(path: string, value: JSONSchemaObject): void;
86
+
87
+ /**
88
+ * Whether a reference should resolve relative to its directory/path, or from the cwd
89
+ *
90
+ * Default: `relative`
91
+ */
92
+ externalReferenceResolution?: "relative" | "root";
86
93
  };
87
94
  }
88
95
 
@@ -149,8 +156,9 @@ const getDefaults = () => {
149
156
  * @type {function}
150
157
  */
151
158
  excludedPathMatcher: () => false,
159
+ referenceResolution: "relative",
152
160
  },
153
- };
161
+ } as $RefParserOptions;
154
162
  return cloneDeep(defaults);
155
163
  };
156
164
 
package/lib/refs.ts CHANGED
@@ -95,7 +95,7 @@ export default class $Refs {
95
95
  * @param value The value to assign. Can be anything (object, string, number, etc.)
96
96
  */
97
97
  set(path: any, value: JSONSchema4Type | JSONSchema6Type | JSONSchema7Type) {
98
- const absPath = url.resolve(this._root$Ref.path, path);
98
+ const absPath = url.resolve(this._root$Ref.path!, path);
99
99
  const withoutHash = url.stripHash(absPath);
100
100
  const $ref = this._$refs[withoutHash];
101
101
 
@@ -113,7 +113,7 @@ export default class $Refs {
113
113
  * @protected
114
114
  */
115
115
  _get$Ref(path: any) {
116
- path = url.resolve(this._root$Ref.path, path);
116
+ path = url.resolve(this._root$Ref.path!, path);
117
117
  const withoutHash = url.stripHash(path);
118
118
  return this._$refs[withoutHash];
119
119
  }
@@ -145,7 +145,7 @@ export default class $Refs {
145
145
  * @protected
146
146
  */
147
147
  _resolve(path: string, pathFromRoot: string, options?: any) {
148
- const absPath = url.resolve(this._root$Ref.path, path);
148
+ const absPath = url.resolve(this._root$Ref.path!, path);
149
149
  const withoutHash = url.stripHash(absPath);
150
150
  const $ref = this._$refs[withoutHash];
151
151
 
@@ -92,9 +92,8 @@ function crawl(
92
92
  * including nested references that are contained in externally-referenced files.
93
93
  */
94
94
  async function resolve$Ref($ref: JSONSchema, path: string, $refs: $Refs, options: Options) {
95
- // console.log('Resolving $ref pointer "%s" at %s', $ref.$ref, path);
96
-
97
- const resolvedPath = url.resolve(path, $ref.$ref);
95
+ const shouldResolveOnCwd = options.dereference.externalReferenceResolution === "root";
96
+ const resolvedPath = url.resolve(shouldResolveOnCwd ? url.cwd() : path, $ref.$ref!);
98
97
  const withoutHash = url.stripHash(resolvedPath);
99
98
 
100
99
  // $ref.$ref = url.relative($refs._root$Ref.path, resolvedPath);
@@ -86,7 +86,7 @@ async function download(u: URL | string, httpOptions: HTTPResolverOptions, _redi
86
86
  } else if (!("location" in res.headers) || !res.headers.location) {
87
87
  throw ono({ status: res.status }, `HTTP ${res.status} redirect with no location header`);
88
88
  } else {
89
- const redirectTo = url.resolve(u, res.headers.location);
89
+ const redirectTo = url.resolve(u.href, res.headers.location as string);
90
90
  return download(redirectTo, httpOptions, redirects);
91
91
  }
92
92
  } else {
package/lib/util/url.ts CHANGED
@@ -16,15 +16,16 @@ const urlEncodePatterns = [/\?/g, "%3F", /#/g, "%23"];
16
16
  // RegExp patterns to URL-decode special characters for local filesystem paths
17
17
  const urlDecodePatterns = [/%23/g, "#", /%24/g, "$", /%26/g, "&", /%2C/g, ",", /%40/g, "@"];
18
18
 
19
- export const parse = (u: any) => new URL(u);
19
+ export const parse = (u: string | URL) => new URL(u);
20
20
 
21
21
  /**
22
22
  * Returns resolved target URL relative to a base URL in a manner similar to that of a Web browser resolving an anchor tag HREF.
23
23
  *
24
24
  * @returns
25
25
  */
26
- export function resolve(from: any, to: any) {
27
- const resolvedUrl = new URL(to, new URL(from, "resolve://"));
26
+ export function resolve(from: string, to: string) {
27
+ const fromUrl = new URL(convertPathToPosix(from), "resolve://");
28
+ const resolvedUrl = new URL(convertPathToPosix(to), fromUrl);
28
29
  if (resolvedUrl.protocol === "resolve:") {
29
30
  // `from` is a relative URL.
30
31
  const { pathname, search, hash } = resolvedUrl;
@@ -279,7 +280,7 @@ export function safePointerToPath(pointer: any) {
279
280
  });
280
281
  }
281
282
 
282
- export function relative(from: string | undefined, to: string | undefined) {
283
+ export function relative(from: string, to: string) {
283
284
  if (!isFileSystemPath(from) || !isFileSystemPath(to)) {
284
285
  return resolve(from, to);
285
286
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@apidevtools/json-schema-ref-parser",
3
- "version": "11.0.0",
3
+ "version": "11.1.0",
4
4
  "description": "Parse, Resolve, and Dereference JSON Schema $ref pointers",
5
5
  "keywords": [
6
6
  "json",