Skip to content

Commit dd778ae

Browse files
authored
Merge pull request #37 from stoplightio/fix/fetch-auth
fix(http): replace url based basic auth with header
2 parents 0a15f2d + 51665de commit dd778ae

File tree

13 files changed

+246
-85
lines changed

13 files changed

+246
-85
lines changed

.circleci/config.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ jobs:
4949
docker:
5050
- image: cimg/node:16.13-browsers
5151
steps:
52-
- browser-tools/install-browser-tools
5352
- checkout
53+
- browser-tools/install-browser-tools
5454
- install
5555
- run:
5656
name: Run browser tests
@@ -65,7 +65,6 @@ workflows:
6565
os:
6666
- linux
6767
node-version:
68-
- "12.22"
6968
- "14.19"
7069
- "16.13"
7170
- test-browser

lib/index.js

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ module.exports.UnmatchedResolverError = UnmatchedResolverError;
2727
* This class parses a JSON schema, builds a map of its JSON references and their resolved values,
2828
* and provides methods for traversing, manipulating, and dereferencing those references.
2929
*
30-
* @constructor
30+
* @class
3131
*/
3232
function $RefParser () {
3333
/**
@@ -55,7 +55,7 @@ function $RefParser () {
5555
* @param {string} [path] - The file path or URL of the JSON schema
5656
* @param {object} [schema] - A JSON schema object. This object will be used instead of reading from `path`.
5757
* @param {$RefParserOptions} [options] - Options that determine how the schema is parsed
58-
* @param {function} [callback] - An error-first callback. The second parameter is the parsed JSON schema object.
58+
* @param {Function} [callback] - An error-first callback. The second parameter is the parsed JSON schema object.
5959
* @returns {Promise} - The returned promise resolves with the parsed JSON schema object.
6060
*/
6161
$RefParser.parse = function parse (path, schema, options, callback) {
@@ -72,7 +72,7 @@ $RefParser.parse = function parse (path, schema, options, callback) {
7272
* @param {string} [path] - The file path or URL of the JSON schema
7373
* @param {object} [schema] - A JSON schema object. This object will be used instead of reading from `path`.
7474
* @param {$RefParserOptions} [options] - Options that determine how the schema is parsed
75-
* @param {function} [callback] - An error-first callback. The second parameter is the parsed JSON schema object.
75+
* @param {Function} [callback] - An error-first callback. The second parameter is the parsed JSON schema object.
7676
* @returns {Promise} - The returned promise resolves with the parsed JSON schema object.
7777
*/
7878
$RefParser.prototype.parse = async function parse (path, schema, options, callback) {
@@ -152,7 +152,7 @@ $RefParser.prototype.parse = async function parse (path, schema, options, callba
152152
* @param {string} [path] - The file path or URL of the JSON schema
153153
* @param {object} [schema] - A JSON schema object. This object will be used instead of reading from `path`.
154154
* @param {$RefParserOptions} [options] - Options that determine how the schema is parsed and resolved
155-
* @param {function} [callback]
155+
* @param {Function} [callback]
156156
* - An error-first callback. The second parameter is a {@link $Refs} object containing the resolved JSON references
157157
*
158158
* @returns {Promise}
@@ -171,7 +171,7 @@ $RefParser.resolve = function resolve (path, schema, options, callback) {
171171
* @param {string} [path] - The file path or URL of the JSON schema
172172
* @param {object} [schema] - A JSON schema object. This object will be used instead of reading from `path`.
173173
* @param {$RefParserOptions} [options] - Options that determine how the schema is parsed and resolved
174-
* @param {function} [callback]
174+
* @param {Function} [callback]
175175
* - An error-first callback. The second parameter is a {@link $Refs} object containing the resolved JSON references
176176
*
177177
* @returns {Promise}
@@ -200,7 +200,7 @@ $RefParser.prototype.resolve = async function resolve (path, schema, options, ca
200200
* @param {string} [path] - The file path or URL of the JSON schema
201201
* @param {object} [schema] - A JSON schema object. This object will be used instead of reading from `path`.
202202
* @param {$RefParserOptions} [options] - Options that determine how the schema is parsed, resolved, and dereferenced
203-
* @param {function} [callback] - An error-first callback. The second parameter is the bundled JSON schema object
203+
* @param {Function} [callback] - An error-first callback. The second parameter is the bundled JSON schema object
204204
* @returns {Promise} - The returned promise resolves with the bundled JSON schema object.
205205
*/
206206
$RefParser.bundle = function bundle (path, schema, options, callback) {
@@ -217,7 +217,7 @@ $RefParser.bundle = function bundle (path, schema, options, callback) {
217217
* @param {string} [path] - The file path or URL of the JSON schema
218218
* @param {object} [schema] - A JSON schema object. This object will be used instead of reading from `path`.
219219
* @param {$RefParserOptions} [options] - Options that determine how the schema is parsed, resolved, and dereferenced
220-
* @param {function} [callback] - An error-first callback. The second parameter is the bundled JSON schema object
220+
* @param {Function} [callback] - An error-first callback. The second parameter is the bundled JSON schema object
221221
* @returns {Promise} - The returned promise resolves with the bundled JSON schema object.
222222
*/
223223
$RefParser.prototype.bundle = async function bundle (path, schema, options, callback) {
@@ -242,7 +242,7 @@ $RefParser.prototype.bundle = async function bundle (path, schema, options, call
242242
* @param {string} [path] - The file path or URL of the JSON schema
243243
* @param {object} [schema] - A JSON schema object. This object will be used instead of reading from `path`.
244244
* @param {$RefParserOptions} [options] - Options that determine how the schema is parsed, resolved, and dereferenced
245-
* @param {function} [callback] - An error-first callback. The second parameter is the dereferenced JSON schema object
245+
* @param {Function} [callback] - An error-first callback. The second parameter is the dereferenced JSON schema object
246246
* @returns {Promise} - The returned promise resolves with the dereferenced JSON schema object.
247247
*/
248248
$RefParser.dereference = function dereference (path, schema, options, callback) {
@@ -258,7 +258,7 @@ $RefParser.dereference = function dereference (path, schema, options, callback)
258258
* @param {string} [path] - The file path or URL of the JSON schema
259259
* @param {object} [schema] - A JSON schema object. This object will be used instead of reading from `path`.
260260
* @param {$RefParserOptions} [options] - Options that determine how the schema is parsed, resolved, and dereferenced
261-
* @param {function} [callback] - An error-first callback. The second parameter is the dereferenced JSON schema object
261+
* @param {Function} [callback] - An error-first callback. The second parameter is the dereferenced JSON schema object
262262
* @returns {Promise} - The returned promise resolves with the dereferenced JSON schema object.
263263
*/
264264
$RefParser.prototype.dereference = async function dereference (path, schema, options, callback) {

lib/options.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ module.exports = $RefParserOptions;
1414
* Options that determine how JSON schemas are parsed, resolved, and dereferenced.
1515
*
1616
* @param {object|$RefParserOptions} [options] - Overridden options
17-
* @constructor
17+
* @class
1818
*/
1919
function $RefParserOptions (options) {
2020
merge(this, $RefParserOptions.defaults);
@@ -59,7 +59,7 @@ $RefParserOptions.defaults = {
5959
* By default, JSON Schema $Ref Parser throws the first error it encounters. Setting `continueOnError` to `true`
6060
* causes it to keep processing as much as possible and then throw a single error that contains all errors
6161
* that were encountered.
62-
*/
62+
*/
6363
continueOnError: false,
6464

6565
/**
@@ -132,7 +132,7 @@ function merge (target, source) {
132132
* or if it is a scalar value that should just override the target value.
133133
*
134134
* @param {*} val
135-
* @returns {Boolean}
135+
* @returns {boolean}
136136
*/
137137
function isMergeable (val) {
138138
return val &&

lib/parsers/json.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ module.exports = {
2626
* Parsers that don't match will be skipped, UNLESS none of the parsers match, in which case
2727
* every parser will be tried.
2828
*
29-
* @type {RegExp|string|string[]|function}
29+
* @type {RegExp | string | string[] | Function}
3030
*/
3131
canParse: ".json",
3232

lib/parsers/yaml.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ module.exports = {
2727
* Parsers that don't match will be skipped, UNLESS none of the parsers match, in which case
2828
* every parser will be tried.
2929
*
30-
* @type {RegExp|string[]|function}
30+
* @type {RegExp | string[] | Function}
3131
*/
3232
canParse: [".yaml", ".yml", ".json"], // JSON is valid YAML
3333

lib/pointer.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,44 +16,50 @@ const escapedTilde = /~0/g;
1616
* @param {$Ref} $ref
1717
* @param {string} path
1818
* @param {string} [friendlyPath] - The original user-specified path (used for error messages)
19-
* @constructor
19+
* @class
2020
*/
2121
function Pointer ($ref, path, friendlyPath) {
2222
/**
2323
* The {@link $Ref} object that contains this {@link Pointer} object.
24+
*
2425
* @type {$Ref}
2526
*/
2627
this.$ref = $ref;
2728

2829
/**
2930
* The file path or URL, containing the JSON pointer in the hash.
3031
* This path is relative to the path of the main JSON schema file.
32+
*
3133
* @type {string}
3234
*/
3335
this.path = path;
3436

3537
/**
3638
* The original path or URL, used for error messages.
39+
*
3740
* @type {string}
3841
*/
3942
this.originalPath = friendlyPath || path;
4043

4144
/**
4245
* The value of the JSON pointer.
4346
* Can be any JSON type, not just objects. Unknown file types are represented as Buffers (byte arrays).
47+
*
4448
* @type {?*}
4549
*/
4650
this.value = undefined;
4751

4852
/**
4953
* Indicates whether the pointer references itself.
54+
*
5055
* @type {boolean}
5156
*/
5257
this.circular = false;
5358

5459
/**
5560
* The number of indirect references that were traversed to resolve the value.
5661
* Resolving a single pointer may require resolving multiple $Refs.
62+
*
5763
* @type {number}
5864
*/
5965
this.indirections = 0;

lib/ref.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const { safePointerToPath, stripHash, getHash } = require("./util/url");
99
/**
1010
* This class represents a single JSON reference and its resolved value.
1111
*
12-
* @constructor
12+
* @class
1313
*/
1414
function $Ref () {
1515
/**
@@ -27,24 +27,28 @@ function $Ref () {
2727
/**
2828
* The resolved value of the JSON reference.
2929
* Can be any JSON type, not just objects. Unknown file types are represented as Buffers (byte arrays).
30+
*
3031
* @type {?*}
3132
*/
3233
this.value = undefined;
3334

3435
/**
3536
* The {@link $Refs} object that contains this {@link $Ref} object.
37+
*
3638
* @type {$Refs}
3739
*/
3840
this.$refs = undefined;
3941

4042
/**
4143
* Indicates the type of {@link $Ref#path} (e.g. "file", "http", etc.)
44+
*
4245
* @type {?string}
4346
*/
4447
this.pathType = undefined;
4548

4649
/**
4750
* List of all errors. Undefined if no errors.
51+
*
4852
* @type {Array<JSONParserError | ResolverError | ParserError | MissingPointerError>}
4953
*/
5054
this.errors = undefined;
@@ -106,7 +110,7 @@ $Ref.prototype.get = function (path, options) {
106110
* @param {string} path - The full path being resolved, optionally with a JSON pointer in the hash
107111
* @param {$RefParserOptions} options
108112
* @param {string} friendlyPath - The original user-specified path (used for error messages)
109-
* @param {string} pathFromRoot - The path of `obj` from the schema root
113+
* @param {string} pathFromRoot - The path of `obj` from the schema root
110114
* @returns {Pointer}
111115
*/
112116
$Ref.prototype.resolve = function (path, options, friendlyPath, pathFromRoot) {

lib/resolvers/http.js

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ module.exports = {
8181
}
8282

8383
return download(u, this, []);
84-
}
84+
},
8585
};
8686

8787
/**
@@ -99,16 +99,29 @@ async function download (u, httpOptions, redirects) {
9999

100100
redirects.push(u.href);
101101

102+
// Certain implementations of `fetch` do not support URL based basic-auth
103+
// Convert to headers
104+
const headers = new Headers(httpOptions.headers);
105+
if (u.auth && !headers.has("Authorization")) {
106+
headers.set("Authorization", "Basic " + btoa(u.auth));
107+
}
108+
109+
u = url.parse(url.format(Object.assign(u, { auth: "" })));
110+
102111
const controller = new AbortController();
103112

104113
/** @type {RequestInit} */
105114
const init = {
106115
method: "GET",
107-
headers: httpOptions.headers || {},
116+
headers: Object.fromEntries(headers.entries()),
108117
credentials: httpOptions.withCredentials ? "include" : "omit",
109118
signal: controller.signal,
110119
// browser fetch API does not support redirects https://fetch.spec.whatwg.org/#atomic-http-redirect-handling
111-
redirect: process.browser ? "follow" : httpOptions.redirects === 0 ? "error" : "manual",
120+
redirect: process.browser
121+
? "follow"
122+
: httpOptions.redirects === 0
123+
? "error"
124+
: "manual",
112125
};
113126

114127
let timeout;
@@ -124,13 +137,24 @@ async function download (u, httpOptions, redirects) {
124137

125138
if (res.status >= 300 && res.status < 400) {
126139
if (redirects.length > httpOptions.redirects) {
127-
throw new ResolverError(ono({ status: res.status },
128-
`Error downloading ${redirects[0]}. \nToo many redirects: \n ${redirects.join(" \n ")}`));
140+
throw new ResolverError(
141+
ono(
142+
{ status: res.status },
143+
`Error downloading ${
144+
redirects[0]
145+
}. \nToo many redirects: \n ${redirects.join(" \n ")}`
146+
)
147+
);
129148
}
130149

131150
let location = res.headers.get("Location");
132151
if (!location) {
133-
throw new ResolverError(ono({ status: res.status }, `HTTP ${res.status} redirect with no location header`));
152+
throw new ResolverError(
153+
ono(
154+
{ status: res.status },
155+
`HTTP ${res.status} redirect with no location header`
156+
)
157+
);
134158
}
135159

136160
let redirectTo = url.resolve(u, location);

lib/util/plugins.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* All other methods in this module expect an array of plugins rather than an object map.
66
*
77
* @param {object} plugins - A map of plugin objects
8-
* @return {object[]}
8+
* @returns {object[]}
99
*/
1010
exports.all = function (plugins) {
1111
return Object.keys(plugins)
@@ -24,7 +24,7 @@ exports.all = function (plugins) {
2424
* @param {object[]} plugins - An array of plugin objects
2525
* @param {string} method - The name of the filter method to invoke for each plugin
2626
* @param {object} file - A file info object, which will be passed to each method
27-
* @return {object[]}
27+
* @returns {object[]}
2828
*/
2929
exports.filter = function (plugins, method, file) {
3030
return plugins
@@ -128,7 +128,7 @@ exports.run = function (plugins, method, file, $refs) {
128128
* @param {object} obj - The object whose property/method is called
129129
* @param {string} prop - The name of the property/method to invoke
130130
* @param {object} file - A file info object, which will be passed to the method
131-
* @param {function} [callback] - A callback function, which will be passed to the method
131+
* @param {Function} [callback] - A callback function, which will be passed to the method
132132
* @returns {*}
133133
*/
134134
function getResult (obj, prop, file, callback, $refs) {

lib/util/url.js

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,23 @@ let isWindows = /^win/.test(process.platform),
1010
jsonPointerTilde = /~0/g;
1111

1212
// RegExp patterns to URL-encode special characters in local filesystem paths
13-
let urlEncodePatterns = [
14-
/\?/g, "%3F",
15-
/\#/g, "%23",
16-
];
13+
let urlEncodePatterns = [/\?/g, "%3F", /\#/g, "%23"];
1714

1815
// RegExp patterns to URL-decode special characters for local filesystem paths
1916
let urlDecodePatterns = [
20-
/\%23/g, "#",
21-
/\%24/g, "$",
22-
/\%26/g, "&",
23-
/\%2C/g, ",",
24-
/\%40/g, "@"
17+
/\%23/g,
18+
"#",
19+
/\%24/g,
20+
"$",
21+
/\%26/g,
22+
"&",
23+
/\%2C/g,
24+
",",
25+
/\%40/g,
26+
"@",
2527
];
2628

29+
exports.format = require("url").format;
2730
exports.parse = require("url").parse;
2831
exports.resolve = require("url").resolve;
2932

@@ -269,7 +272,11 @@ exports.safePathToPointer = function safePointerToPath (path) {
269272
return "#";
270273
}
271274

272-
return `#/${path.map(segment => {
273-
return typeof segment === "number" ? String(segment) : segment.replace(tilde, "~0").replace(slash, "~1");
274-
}).join("/")}`;
275+
return `#/${path
276+
.map((segment) => {
277+
return typeof segment === "number"
278+
? String(segment)
279+
: segment.replace(tilde, "~0").replace(slash, "~1");
280+
})
281+
.join("/")}`;
275282
};

0 commit comments

Comments
 (0)