@pnpm/error 1100.2.0 → 1100.2.2
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/CHANGELOG.md +13 -0
- package/lib/index.d.ts +23 -0
- package/lib/index.js +40 -25
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# @pnpm/error
|
|
2
2
|
|
|
3
|
+
## 1100.2.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies:
|
|
8
|
+
- @pnpm/constants@1102.0.1
|
|
9
|
+
|
|
10
|
+
## 1100.2.1
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- `pnpm install` now works in StackBlitz WebContainers on projects without a lockfile. It used to fail there with `ENOENT ... pnpm-lock.yaml`, because pnpm did not recognize the errors that WebContainers return from asynchronous file system calls [#15649](https://github.com/pnpm/pnpm/issues/15649).
|
|
15
|
+
|
|
3
16
|
## 1100.2.0
|
|
4
17
|
|
|
5
18
|
### Minor Changes
|
package/lib/index.d.ts
CHANGED
|
@@ -38,6 +38,19 @@ export declare class FetchTimeoutError extends PnpmError {
|
|
|
38
38
|
cause: unknown;
|
|
39
39
|
});
|
|
40
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* Strip `user:pass@` (or `user@`) userinfo that follows a URL scheme in any
|
|
43
|
+
* text, e.g. `GET https://user:pass@host/pkg: ...` → `GET https://host/pkg: ...`.
|
|
44
|
+
* A registry configured as `https://user:pass@host/` would otherwise leak its
|
|
45
|
+
* embedded basic-auth credentials into every error message that interpolates
|
|
46
|
+
* the request URL (terminal output, CI logs). `FetchError` already hides the
|
|
47
|
+
* auth *header*; this covers credentials carried in the URL itself.
|
|
48
|
+
*
|
|
49
|
+
* Implemented as a single forward scan rather than a regex: `text` is
|
|
50
|
+
* uncontrolled (it interpolates the request URL), so a backtracking pattern is
|
|
51
|
+
* a ReDoS vector, and the scan strips up to the **last** `@` in the authority
|
|
52
|
+
* so a raw `@` inside the password (`user:p@ss@host`) doesn't leak its tail.
|
|
53
|
+
*/
|
|
41
54
|
export declare function redactUrlCredentials(text: string): string;
|
|
42
55
|
/**
|
|
43
56
|
* Make untrusted, URL-bearing text safe to print or log: redact inline
|
|
@@ -68,3 +81,13 @@ export declare function redactAndSanitizeMultiline(text: string): string;
|
|
|
68
81
|
export declare class LockfileMissingDependencyError extends PnpmError {
|
|
69
82
|
constructor(depPath: string);
|
|
70
83
|
}
|
|
84
|
+
/**
|
|
85
|
+
* Whether `value` is an `Error`, whichever way the runtime created it.
|
|
86
|
+
*
|
|
87
|
+
* `util.types.isNativeError` misses the errors that StackBlitz WebContainers
|
|
88
|
+
* reject asynchronous `fs` calls with: they inherit from `Error`, but the
|
|
89
|
+
* native constructor did not create them. `instanceof Error` misses errors
|
|
90
|
+
* from another realm, such as the ones code under Jest's VM contexts catches.
|
|
91
|
+
* Either check passing is enough.
|
|
92
|
+
*/
|
|
93
|
+
export declare function isError(value: unknown): value is Error;
|
package/lib/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import util from 'node:util';
|
|
1
2
|
import { WANTED_LOCKFILE } from '@pnpm/constants';
|
|
2
3
|
export class PnpmError extends Error {
|
|
3
4
|
code;
|
|
@@ -67,19 +68,6 @@ export class FetchTimeoutError extends PnpmError {
|
|
|
67
68
|
});
|
|
68
69
|
}
|
|
69
70
|
}
|
|
70
|
-
/**
|
|
71
|
-
* Strip `user:pass@` (or `user@`) userinfo that follows a URL scheme in any
|
|
72
|
-
* text, e.g. `GET https://user:pass@host/pkg: …` → `GET https://host/pkg: …`.
|
|
73
|
-
* A registry configured as `https://user:pass@host/` would otherwise leak its
|
|
74
|
-
* embedded basic-auth credentials into every error message that interpolates
|
|
75
|
-
* the request URL (terminal output, CI logs). `FetchError` already hides the
|
|
76
|
-
* auth *header*; this covers credentials carried in the URL itself.
|
|
77
|
-
*
|
|
78
|
-
* Implemented as a single forward scan rather than a regex: `text` is
|
|
79
|
-
* uncontrolled (it interpolates the request URL), so a backtracking pattern is
|
|
80
|
-
* a ReDoS vector, and the scan strips up to the **last** `@` in the authority
|
|
81
|
-
* so a raw `@` inside the password (`user:p@ss@host`) doesn't leak its tail.
|
|
82
|
-
*/
|
|
83
71
|
/**
|
|
84
72
|
* A request URL made safe to print: its `user:pass@` userinfo and control
|
|
85
73
|
* characters redacted ({@link redactAndSanitize}), then everything from the
|
|
@@ -106,6 +94,19 @@ function redactUrlSecrets(url) {
|
|
|
106
94
|
return '[hidden]';
|
|
107
95
|
return sanitized.split(/[?#]/)[0];
|
|
108
96
|
}
|
|
97
|
+
/**
|
|
98
|
+
* Strip `user:pass@` (or `user@`) userinfo that follows a URL scheme in any
|
|
99
|
+
* text, e.g. `GET https://user:pass@host/pkg: ...` → `GET https://host/pkg: ...`.
|
|
100
|
+
* A registry configured as `https://user:pass@host/` would otherwise leak its
|
|
101
|
+
* embedded basic-auth credentials into every error message that interpolates
|
|
102
|
+
* the request URL (terminal output, CI logs). `FetchError` already hides the
|
|
103
|
+
* auth *header*; this covers credentials carried in the URL itself.
|
|
104
|
+
*
|
|
105
|
+
* Implemented as a single forward scan rather than a regex: `text` is
|
|
106
|
+
* uncontrolled (it interpolates the request URL), so a backtracking pattern is
|
|
107
|
+
* a ReDoS vector, and the scan strips up to the **last** `@` in the authority
|
|
108
|
+
* so a raw `@` inside the password (`user:p@ss@host`) doesn't leak its tail.
|
|
109
|
+
*/
|
|
109
110
|
export function redactUrlCredentials(text) {
|
|
110
111
|
let result = '';
|
|
111
112
|
let cursor = 0;
|
|
@@ -121,21 +122,23 @@ export function redactUrlCredentials(text) {
|
|
|
121
122
|
// bare `://` in the text is left untouched.
|
|
122
123
|
if (schemeSep === 0 || !isSchemeTailChar(text.charCodeAt(schemeSep - 1)))
|
|
123
124
|
continue;
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
for (let i = authorityStart; i < text.length; i++) {
|
|
128
|
-
const code = text.charCodeAt(i);
|
|
129
|
-
if (code === 0x2f || code === 0x3f || code === 0x23 || isAsciiWhitespace(code))
|
|
130
|
-
break;
|
|
131
|
-
if (code === 0x40)
|
|
132
|
-
lastAt = i;
|
|
133
|
-
}
|
|
134
|
-
if (lastAt !== -1)
|
|
135
|
-
cursor = lastAt + 1;
|
|
125
|
+
const userinfoEnd = findAuthorityUserinfoEnd(text, authorityStart);
|
|
126
|
+
if (userinfoEnd !== -1)
|
|
127
|
+
cursor = userinfoEnd;
|
|
136
128
|
}
|
|
137
129
|
return result;
|
|
138
130
|
}
|
|
131
|
+
function findAuthorityUserinfoEnd(text, authorityStart) {
|
|
132
|
+
let lastAt = -1;
|
|
133
|
+
for (let index = authorityStart; index < text.length; index++) {
|
|
134
|
+
const code = text.charCodeAt(index);
|
|
135
|
+
if (code === 0x2f || code === 0x3f || code === 0x23 || isAsciiWhitespace(code))
|
|
136
|
+
break;
|
|
137
|
+
if (code === 0x40)
|
|
138
|
+
lastAt = index;
|
|
139
|
+
}
|
|
140
|
+
return lastAt === -1 ? -1 : lastAt + 1;
|
|
141
|
+
}
|
|
139
142
|
/**
|
|
140
143
|
* Make untrusted, URL-bearing text safe to print or log: redact inline
|
|
141
144
|
* `user:pass@` credentials ({@link redactUrlCredentials}) and strip every
|
|
@@ -219,4 +222,16 @@ export class LockfileMissingDependencyError extends PnpmError {
|
|
|
219
222
|
});
|
|
220
223
|
}
|
|
221
224
|
}
|
|
225
|
+
/**
|
|
226
|
+
* Whether `value` is an `Error`, whichever way the runtime created it.
|
|
227
|
+
*
|
|
228
|
+
* `util.types.isNativeError` misses the errors that StackBlitz WebContainers
|
|
229
|
+
* reject asynchronous `fs` calls with: they inherit from `Error`, but the
|
|
230
|
+
* native constructor did not create them. `instanceof Error` misses errors
|
|
231
|
+
* from another realm, such as the ones code under Jest's VM contexts catches.
|
|
232
|
+
* Either check passing is enough.
|
|
233
|
+
*/
|
|
234
|
+
export function isError(value) {
|
|
235
|
+
return util.types.isNativeError(value) || value instanceof Error;
|
|
236
|
+
}
|
|
222
237
|
//# sourceMappingURL=index.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pnpm/error",
|
|
3
|
-
"version": "1100.2.
|
|
3
|
+
"version": "1100.2.2",
|
|
4
4
|
"description": "An error class for pnpm errors",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pnpm",
|
|
@@ -28,11 +28,11 @@
|
|
|
28
28
|
"!*.map"
|
|
29
29
|
],
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@pnpm/constants": "1102.0.
|
|
31
|
+
"@pnpm/constants": "1102.0.1"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"@jest/globals": "30.4.1",
|
|
35
|
-
"@pnpm/error": "1100.2.
|
|
35
|
+
"@pnpm/error": "1100.2.2"
|
|
36
36
|
},
|
|
37
37
|
"engines": {
|
|
38
38
|
"node": ">=22.13"
|