isomorphic-git 1.40.8 → 1.41.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.
- package/http/node/index.cjs +5 -0
- package/http/node/index.d.cts +5 -1
- package/http/node/index.d.ts +5 -1
- package/http/node/index.js +5 -0
- package/http/web/index.cjs +7 -1
- package/http/web/index.d.cts +5 -1
- package/http/web/index.d.ts +5 -1
- package/http/web/index.js +7 -1
- package/http/web/index.umd.js +7 -1
- package/index.cjs +67 -11
- package/index.d.cts +5 -0
- package/index.d.ts +5 -0
- package/index.js +67 -11
- package/index.umd.min.d.ts +5 -0
- package/index.umd.min.js +1 -1
- package/index.umd.min.js.map +1 -1
- package/managers/index.cjs +65 -9
- package/managers/index.d.cts +4 -0
- package/managers/index.d.ts +4 -0
- package/managers/index.js +65 -9
- package/managers/index.umd.min.js +1 -1
- package/managers/index.umd.min.js.map +1 -1
- package/package.json +1 -1
package/managers/index.cjs
CHANGED
|
@@ -33,6 +33,7 @@ var crypto$1 = require('crypto');
|
|
|
33
33
|
* @property {AsyncIterableIterator<Uint8Array>} [body] - An async iterator of Uint8Arrays that make up the body of POST requests
|
|
34
34
|
* @property {ProgressCallback} [onProgress] - Reserved for future use (emitting `GitProgressEvent`s)
|
|
35
35
|
* @property {object} [signal] - Reserved for future use (canceling a request)
|
|
36
|
+
* @property {Object} [fetchOptions={}] - Additional options to pass to fetch (Web) or simple-get (Node)
|
|
36
37
|
*/
|
|
37
38
|
|
|
38
39
|
/**
|
|
@@ -2484,21 +2485,76 @@ async function collect(iterable) {
|
|
|
2484
2485
|
return result
|
|
2485
2486
|
}
|
|
2486
2487
|
|
|
2488
|
+
// The `@` that ends the credentials is the last one in the authority, and the
|
|
2489
|
+
// scheme is matched case-insensitively: `HTTPS://user:pass@host/x` is a URL
|
|
2490
|
+
// like any other, and leaving the credentials in it is what `fetch` rejects.
|
|
2491
|
+
// The authority ends at the first `/`, `?` or `#`, so an `@` that lives in a
|
|
2492
|
+
// query or a fragment is left where it is.
|
|
2493
|
+
const CREDENTIALS = /^(https?:\/\/)([^/?#]+)@/i;
|
|
2494
|
+
|
|
2487
2495
|
function extractAuthFromUrl(url) {
|
|
2488
2496
|
// For whatever reason, the `fetch` API does not convert credentials embedded in the URL
|
|
2489
2497
|
// into Basic Authentication headers automatically. Instead it throws an error!
|
|
2490
2498
|
// So we must manually parse the URL, rip out the user:password portion if it is present
|
|
2491
2499
|
// and compute the Authorization header.
|
|
2492
|
-
|
|
2493
|
-
let userpass = url.match(/^https?:\/\/([^/]+)@/);
|
|
2500
|
+
const credentials = url.match(CREDENTIALS);
|
|
2494
2501
|
// No credentials, return the url unmodified and an empty auth object
|
|
2495
|
-
if (
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
//
|
|
2499
|
-
|
|
2500
|
-
//
|
|
2501
|
-
return {
|
|
2502
|
+
if (credentials == null) return { url, auth: {} }
|
|
2503
|
+
// Has credentials, return the fetch-safe URL and the parsed credentials.
|
|
2504
|
+
// The credentials are cut out of the original string rather than read back
|
|
2505
|
+
// off the parsed URL: serializing that one would also drop an explicit
|
|
2506
|
+
// `:443` and append a slash to a URL that has no path, and this return value
|
|
2507
|
+
// is what the request goes out against.
|
|
2508
|
+
return {
|
|
2509
|
+
url: url.replace(CREDENTIALS, '$1'),
|
|
2510
|
+
auth: parseUserinfo(url, credentials[2]),
|
|
2511
|
+
}
|
|
2512
|
+
}
|
|
2513
|
+
|
|
2514
|
+
function parseUserinfo(url, userpass) {
|
|
2515
|
+
// `URL` splits the two halves the way the platform does, so the first colon
|
|
2516
|
+
// separates them and any later one stays in the password. Only the split is
|
|
2517
|
+
// taken from it, for the reason above.
|
|
2518
|
+
const parsed = parseUrl(url);
|
|
2519
|
+
// A password is absent, not empty, when no colon was written at all. `URL`
|
|
2520
|
+
// reports `''` for both, and the difference is worth keeping.
|
|
2521
|
+
const hasPassword = userpass.indexOf(':') !== -1;
|
|
2522
|
+
|
|
2523
|
+
if (parsed !== null) {
|
|
2524
|
+
return {
|
|
2525
|
+
username: decodeUserinfo(parsed.username),
|
|
2526
|
+
password: hasPassword ? decodeUserinfo(parsed.password) : undefined,
|
|
2527
|
+
}
|
|
2528
|
+
}
|
|
2529
|
+
|
|
2530
|
+
// No `URL` to parse with, or it rejected a string the expression above
|
|
2531
|
+
// accepted. Split on the first colon by hand, without the percent-decoding.
|
|
2532
|
+
const separatorIndex = userpass.indexOf(':');
|
|
2533
|
+
return {
|
|
2534
|
+
username: hasPassword ? userpass.slice(0, separatorIndex) : userpass,
|
|
2535
|
+
password: hasPassword ? userpass.slice(separatorIndex + 1) : undefined,
|
|
2536
|
+
}
|
|
2537
|
+
}
|
|
2538
|
+
|
|
2539
|
+
function parseUrl(url) {
|
|
2540
|
+
if (typeof URL !== 'function') return null
|
|
2541
|
+
try {
|
|
2542
|
+
return new URL(url)
|
|
2543
|
+
} catch (_) {
|
|
2544
|
+
return null
|
|
2545
|
+
}
|
|
2546
|
+
}
|
|
2547
|
+
|
|
2548
|
+
// `URL` hands back the userinfo still percent-encoded, so `p:ss` arrives as
|
|
2549
|
+
// `p%3Ass` and has to be decoded before it reaches the Authorization header. A
|
|
2550
|
+
// lone `%` is not something the parser encodes, and it makes the decode throw,
|
|
2551
|
+
// so the raw value stands in whenever the decode fails.
|
|
2552
|
+
function decodeUserinfo(value) {
|
|
2553
|
+
try {
|
|
2554
|
+
return decodeURIComponent(value)
|
|
2555
|
+
} catch (_) {
|
|
2556
|
+
return value
|
|
2557
|
+
}
|
|
2502
2558
|
}
|
|
2503
2559
|
|
|
2504
2560
|
class EmptyServerResponseError extends BaseError {
|
package/managers/index.d.cts
CHANGED
|
@@ -54,6 +54,10 @@ export type GitHttpRequest = {
|
|
|
54
54
|
* - Reserved for future use (canceling a request)
|
|
55
55
|
*/
|
|
56
56
|
signal?: object;
|
|
57
|
+
/**
|
|
58
|
+
* - Additional options to pass to fetch (Web) or simple-get (Node)
|
|
59
|
+
*/
|
|
60
|
+
fetchOptions?: any;
|
|
57
61
|
};
|
|
58
62
|
export type GitHttpResponse = {
|
|
59
63
|
/**
|
package/managers/index.d.ts
CHANGED
|
@@ -53,6 +53,10 @@ export type GitHttpRequest = {
|
|
|
53
53
|
* - Reserved for future use (canceling a request)
|
|
54
54
|
*/
|
|
55
55
|
signal?: object;
|
|
56
|
+
/**
|
|
57
|
+
* - Additional options to pass to fetch (Web) or simple-get (Node)
|
|
58
|
+
*/
|
|
59
|
+
fetchOptions?: any;
|
|
56
60
|
};
|
|
57
61
|
export type GitHttpResponse = {
|
|
58
62
|
/**
|
package/managers/index.js
CHANGED
|
@@ -26,6 +26,7 @@ import pako from 'pako';
|
|
|
26
26
|
* @property {AsyncIterableIterator<Uint8Array>} [body] - An async iterator of Uint8Arrays that make up the body of POST requests
|
|
27
27
|
* @property {ProgressCallback} [onProgress] - Reserved for future use (emitting `GitProgressEvent`s)
|
|
28
28
|
* @property {object} [signal] - Reserved for future use (canceling a request)
|
|
29
|
+
* @property {Object} [fetchOptions={}] - Additional options to pass to fetch (Web) or simple-get (Node)
|
|
29
30
|
*/
|
|
30
31
|
|
|
31
32
|
/**
|
|
@@ -2477,21 +2478,76 @@ async function collect(iterable) {
|
|
|
2477
2478
|
return result
|
|
2478
2479
|
}
|
|
2479
2480
|
|
|
2481
|
+
// The `@` that ends the credentials is the last one in the authority, and the
|
|
2482
|
+
// scheme is matched case-insensitively: `HTTPS://user:pass@host/x` is a URL
|
|
2483
|
+
// like any other, and leaving the credentials in it is what `fetch` rejects.
|
|
2484
|
+
// The authority ends at the first `/`, `?` or `#`, so an `@` that lives in a
|
|
2485
|
+
// query or a fragment is left where it is.
|
|
2486
|
+
const CREDENTIALS = /^(https?:\/\/)([^/?#]+)@/i;
|
|
2487
|
+
|
|
2480
2488
|
function extractAuthFromUrl(url) {
|
|
2481
2489
|
// For whatever reason, the `fetch` API does not convert credentials embedded in the URL
|
|
2482
2490
|
// into Basic Authentication headers automatically. Instead it throws an error!
|
|
2483
2491
|
// So we must manually parse the URL, rip out the user:password portion if it is present
|
|
2484
2492
|
// and compute the Authorization header.
|
|
2485
|
-
|
|
2486
|
-
let userpass = url.match(/^https?:\/\/([^/]+)@/);
|
|
2493
|
+
const credentials = url.match(CREDENTIALS);
|
|
2487
2494
|
// No credentials, return the url unmodified and an empty auth object
|
|
2488
|
-
if (
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
//
|
|
2492
|
-
|
|
2493
|
-
//
|
|
2494
|
-
return {
|
|
2495
|
+
if (credentials == null) return { url, auth: {} }
|
|
2496
|
+
// Has credentials, return the fetch-safe URL and the parsed credentials.
|
|
2497
|
+
// The credentials are cut out of the original string rather than read back
|
|
2498
|
+
// off the parsed URL: serializing that one would also drop an explicit
|
|
2499
|
+
// `:443` and append a slash to a URL that has no path, and this return value
|
|
2500
|
+
// is what the request goes out against.
|
|
2501
|
+
return {
|
|
2502
|
+
url: url.replace(CREDENTIALS, '$1'),
|
|
2503
|
+
auth: parseUserinfo(url, credentials[2]),
|
|
2504
|
+
}
|
|
2505
|
+
}
|
|
2506
|
+
|
|
2507
|
+
function parseUserinfo(url, userpass) {
|
|
2508
|
+
// `URL` splits the two halves the way the platform does, so the first colon
|
|
2509
|
+
// separates them and any later one stays in the password. Only the split is
|
|
2510
|
+
// taken from it, for the reason above.
|
|
2511
|
+
const parsed = parseUrl(url);
|
|
2512
|
+
// A password is absent, not empty, when no colon was written at all. `URL`
|
|
2513
|
+
// reports `''` for both, and the difference is worth keeping.
|
|
2514
|
+
const hasPassword = userpass.indexOf(':') !== -1;
|
|
2515
|
+
|
|
2516
|
+
if (parsed !== null) {
|
|
2517
|
+
return {
|
|
2518
|
+
username: decodeUserinfo(parsed.username),
|
|
2519
|
+
password: hasPassword ? decodeUserinfo(parsed.password) : undefined,
|
|
2520
|
+
}
|
|
2521
|
+
}
|
|
2522
|
+
|
|
2523
|
+
// No `URL` to parse with, or it rejected a string the expression above
|
|
2524
|
+
// accepted. Split on the first colon by hand, without the percent-decoding.
|
|
2525
|
+
const separatorIndex = userpass.indexOf(':');
|
|
2526
|
+
return {
|
|
2527
|
+
username: hasPassword ? userpass.slice(0, separatorIndex) : userpass,
|
|
2528
|
+
password: hasPassword ? userpass.slice(separatorIndex + 1) : undefined,
|
|
2529
|
+
}
|
|
2530
|
+
}
|
|
2531
|
+
|
|
2532
|
+
function parseUrl(url) {
|
|
2533
|
+
if (typeof URL !== 'function') return null
|
|
2534
|
+
try {
|
|
2535
|
+
return new URL(url)
|
|
2536
|
+
} catch (_) {
|
|
2537
|
+
return null
|
|
2538
|
+
}
|
|
2539
|
+
}
|
|
2540
|
+
|
|
2541
|
+
// `URL` hands back the userinfo still percent-encoded, so `p:ss` arrives as
|
|
2542
|
+
// `p%3Ass` and has to be decoded before it reaches the Authorization header. A
|
|
2543
|
+
// lone `%` is not something the parser encodes, and it makes the decode throw,
|
|
2544
|
+
// so the raw value stands in whenever the decode fails.
|
|
2545
|
+
function decodeUserinfo(value) {
|
|
2546
|
+
try {
|
|
2547
|
+
return decodeURIComponent(value)
|
|
2548
|
+
} catch (_) {
|
|
2549
|
+
return value
|
|
2550
|
+
}
|
|
2495
2551
|
}
|
|
2496
2552
|
|
|
2497
2553
|
class EmptyServerResponseError extends BaseError {
|