isomorphic-git 1.41.0 → 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/index.cjs +66 -11
- package/index.js +66 -11
- package/index.umd.min.js +1 -1
- package/index.umd.min.js.map +1 -1
- package/managers/index.cjs +64 -9
- package/managers/index.js +64 -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
|
@@ -2485,21 +2485,76 @@ async function collect(iterable) {
|
|
|
2485
2485
|
return result
|
|
2486
2486
|
}
|
|
2487
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
|
+
|
|
2488
2495
|
function extractAuthFromUrl(url) {
|
|
2489
2496
|
// For whatever reason, the `fetch` API does not convert credentials embedded in the URL
|
|
2490
2497
|
// into Basic Authentication headers automatically. Instead it throws an error!
|
|
2491
2498
|
// So we must manually parse the URL, rip out the user:password portion if it is present
|
|
2492
2499
|
// and compute the Authorization header.
|
|
2493
|
-
|
|
2494
|
-
let userpass = url.match(/^https?:\/\/([^/]+)@/);
|
|
2500
|
+
const credentials = url.match(CREDENTIALS);
|
|
2495
2501
|
// No credentials, return the url unmodified and an empty auth object
|
|
2496
|
-
if (
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
//
|
|
2500
|
-
|
|
2501
|
-
//
|
|
2502
|
-
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
|
+
}
|
|
2503
2558
|
}
|
|
2504
2559
|
|
|
2505
2560
|
class EmptyServerResponseError extends BaseError {
|
package/managers/index.js
CHANGED
|
@@ -2478,21 +2478,76 @@ async function collect(iterable) {
|
|
|
2478
2478
|
return result
|
|
2479
2479
|
}
|
|
2480
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
|
+
|
|
2481
2488
|
function extractAuthFromUrl(url) {
|
|
2482
2489
|
// For whatever reason, the `fetch` API does not convert credentials embedded in the URL
|
|
2483
2490
|
// into Basic Authentication headers automatically. Instead it throws an error!
|
|
2484
2491
|
// So we must manually parse the URL, rip out the user:password portion if it is present
|
|
2485
2492
|
// and compute the Authorization header.
|
|
2486
|
-
|
|
2487
|
-
let userpass = url.match(/^https?:\/\/([^/]+)@/);
|
|
2493
|
+
const credentials = url.match(CREDENTIALS);
|
|
2488
2494
|
// No credentials, return the url unmodified and an empty auth object
|
|
2489
|
-
if (
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
//
|
|
2493
|
-
|
|
2494
|
-
//
|
|
2495
|
-
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
|
+
}
|
|
2496
2551
|
}
|
|
2497
2552
|
|
|
2498
2553
|
class EmptyServerResponseError extends BaseError {
|