@socketsecurity/lib 5.16.0 → 5.18.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.
- package/CHANGELOG.md +21 -0
- package/dist/constants/socket.d.ts +5 -0
- package/dist/constants/socket.js +12 -0
- package/dist/dlx/package.d.ts +8 -0
- package/dist/dlx/package.js +83 -4
- package/dist/http-request.js +2 -1
- package/dist/paths/normalize.d.ts +58 -26
- package/dist/paths/normalize.js +20 -6
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,27 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [5.18.0](https://github.com/SocketDev/socket-lib/releases/tag/v5.18.0) - 2026-04-14
|
|
9
|
+
|
|
10
|
+
### Added — dlx
|
|
11
|
+
|
|
12
|
+
- Socket Firewall API check before package downloads — resolves dependency tree via `buildIdealTree`, checks all packages against `firewall-api.socket.dev/purl` in parallel, blocks on critical/high severity alerts
|
|
13
|
+
|
|
14
|
+
### Changed — http-request
|
|
15
|
+
|
|
16
|
+
- Default `User-Agent` header updated from `socket-registry/1.0` to `socketsecurity-lib/{version}`
|
|
17
|
+
|
|
18
|
+
## [5.17.0](https://github.com/SocketDev/socket-lib/releases/tag/v5.17.0) - 2026-04-14
|
|
19
|
+
|
|
20
|
+
### Added — paths
|
|
21
|
+
|
|
22
|
+
- `isUnixPath()` — detect MSYS/Git Bash drive letter notation (`/c/...`)
|
|
23
|
+
|
|
24
|
+
### Changed — paths
|
|
25
|
+
|
|
26
|
+
- `normalizePath()` now converts MSYS drive letters on Windows (`/c/path` → `C:/path`)
|
|
27
|
+
- `fromUnixPath()` now produces native Windows paths with backslashes (`/c/path` → `C:\path`), making it the true inverse of `toUnixPath()`
|
|
28
|
+
|
|
8
29
|
## [5.16.0](https://github.com/SocketDev/socket-lib/releases/tag/v5.16.0) - 2026-04-14
|
|
9
30
|
|
|
10
31
|
### Added — paths
|
|
@@ -30,6 +30,11 @@ export declare const SOCKET_DLX_APP_NAME = "dlx";
|
|
|
30
30
|
export declare const SOCKET_FIREWALL_APP_NAME = "sfw";
|
|
31
31
|
export declare const SOCKET_REGISTRY_APP_NAME = "registry";
|
|
32
32
|
export declare const SOCKET_APP_PREFIX = "_";
|
|
33
|
+
// Socket.dev lib.
|
|
34
|
+
export declare const SOCKET_LIB_NAME = "@socketsecurity/lib";
|
|
35
|
+
export declare const SOCKET_LIB_VERSION: string;
|
|
36
|
+
export declare const SOCKET_LIB_URL = "https://github.com/SocketDev/socket-lib";
|
|
37
|
+
export declare const SOCKET_LIB_USER_AGENT: string;
|
|
33
38
|
// Socket.dev IPC.
|
|
34
39
|
export declare const SOCKET_IPC_HANDSHAKE = "SOCKET_IPC_HANDSHAKE";
|
|
35
40
|
// Socket.dev cache and registry.
|
package/dist/constants/socket.js
CHANGED
|
@@ -34,6 +34,10 @@ __export(socket_exports, {
|
|
|
34
34
|
SOCKET_FIREWALL_APP_NAME: () => SOCKET_FIREWALL_APP_NAME,
|
|
35
35
|
SOCKET_GITHUB_ORG: () => SOCKET_GITHUB_ORG,
|
|
36
36
|
SOCKET_IPC_HANDSHAKE: () => SOCKET_IPC_HANDSHAKE,
|
|
37
|
+
SOCKET_LIB_NAME: () => SOCKET_LIB_NAME,
|
|
38
|
+
SOCKET_LIB_URL: () => SOCKET_LIB_URL,
|
|
39
|
+
SOCKET_LIB_USER_AGENT: () => SOCKET_LIB_USER_AGENT,
|
|
40
|
+
SOCKET_LIB_VERSION: () => SOCKET_LIB_VERSION,
|
|
37
41
|
SOCKET_OVERRIDE_SCOPE: () => SOCKET_OVERRIDE_SCOPE,
|
|
38
42
|
SOCKET_PRICING_URL: () => SOCKET_PRICING_URL,
|
|
39
43
|
SOCKET_PUBLIC_API_KEY: () => SOCKET_PUBLIC_API_KEY,
|
|
@@ -71,6 +75,10 @@ const SOCKET_DLX_APP_NAME = "dlx";
|
|
|
71
75
|
const SOCKET_FIREWALL_APP_NAME = "sfw";
|
|
72
76
|
const SOCKET_REGISTRY_APP_NAME = "registry";
|
|
73
77
|
const SOCKET_APP_PREFIX = "_";
|
|
78
|
+
const SOCKET_LIB_NAME = "@socketsecurity/lib";
|
|
79
|
+
const SOCKET_LIB_VERSION = "5.18.0";
|
|
80
|
+
const SOCKET_LIB_URL = "https://github.com/SocketDev/socket-lib";
|
|
81
|
+
const SOCKET_LIB_USER_AGENT = `socketsecurity-lib/${SOCKET_LIB_VERSION} (${SOCKET_LIB_URL})`;
|
|
74
82
|
const SOCKET_IPC_HANDSHAKE = "SOCKET_IPC_HANDSHAKE";
|
|
75
83
|
const CACHE_SOCKET_API_DIR = "socket-api";
|
|
76
84
|
const REGISTRY = "registry";
|
|
@@ -92,6 +100,10 @@ const REGISTRY_SCOPE_DELIMITER = "__";
|
|
|
92
100
|
SOCKET_FIREWALL_APP_NAME,
|
|
93
101
|
SOCKET_GITHUB_ORG,
|
|
94
102
|
SOCKET_IPC_HANDSHAKE,
|
|
103
|
+
SOCKET_LIB_NAME,
|
|
104
|
+
SOCKET_LIB_URL,
|
|
105
|
+
SOCKET_LIB_USER_AGENT,
|
|
106
|
+
SOCKET_LIB_VERSION,
|
|
95
107
|
SOCKET_OVERRIDE_SCOPE,
|
|
96
108
|
SOCKET_PRICING_URL,
|
|
97
109
|
SOCKET_PUBLIC_API_KEY,
|
package/dist/dlx/package.d.ts
CHANGED
|
@@ -181,6 +181,14 @@ export declare function findBinaryPath(packageDir: string, packageName: string,
|
|
|
181
181
|
* ```
|
|
182
182
|
*/
|
|
183
183
|
export declare function makePackageBinsExecutable(packageDir: string, packageName: string): void;
|
|
184
|
+
/**
|
|
185
|
+
* Build a PURL string for an npm package.
|
|
186
|
+
* Follows the PURL spec for the npm type:
|
|
187
|
+
* - Scoped: `@scope/pkg` → `pkg:npm/%40scope/pkg@version`
|
|
188
|
+
* - Unscoped: `pkg` → `pkg:npm/pkg@version`
|
|
189
|
+
*
|
|
190
|
+
*/
|
|
191
|
+
export declare function npmPurl(name: string, version: string): string;
|
|
184
192
|
/**
|
|
185
193
|
* Parse package spec into name and version using npm-package-arg.
|
|
186
194
|
* Examples:
|
package/dist/dlx/package.js
CHANGED
|
@@ -35,18 +35,21 @@ __export(package_exports, {
|
|
|
35
35
|
executePackage: () => executePackage,
|
|
36
36
|
findBinaryPath: () => findBinaryPath,
|
|
37
37
|
makePackageBinsExecutable: () => makePackageBinsExecutable,
|
|
38
|
+
npmPurl: () => npmPurl,
|
|
38
39
|
parsePackageSpec: () => parsePackageSpec,
|
|
39
40
|
resolveBinaryPath: () => resolveBinaryPath
|
|
40
41
|
});
|
|
41
42
|
module.exports = __toCommonJS(package_exports);
|
|
42
43
|
var import_platform = require("../constants/platform");
|
|
44
|
+
var import_socket = require("../constants/socket");
|
|
43
45
|
var import_cache = require("./cache");
|
|
44
46
|
var import_arborist = __toESM(require("../external/@npmcli/arborist"));
|
|
45
47
|
var import_libnpmexec = __toESM(require("../external/libnpmexec"));
|
|
46
48
|
var import_npm_package_arg = __toESM(require("../external/npm-package-arg"));
|
|
47
49
|
var import_fs = require("../fs");
|
|
50
|
+
var import_http_request = require("../http-request");
|
|
48
51
|
var import_normalize = require("../paths/normalize");
|
|
49
|
-
var
|
|
52
|
+
var import_socket2 = require("../paths/socket");
|
|
50
53
|
var import_process_lock = require("../process-lock");
|
|
51
54
|
var import_spawn = require("../spawn");
|
|
52
55
|
let _fs;
|
|
@@ -110,7 +113,7 @@ async function ensurePackageInstalled(packageName, packageSpec, force) {
|
|
|
110
113
|
const fs = /* @__PURE__ */ getFs();
|
|
111
114
|
const path = /* @__PURE__ */ getPath();
|
|
112
115
|
const cacheKey = (0, import_cache.generateCacheKey)(packageSpec);
|
|
113
|
-
const packageDir = (0, import_normalize.normalizePath)(path.join((0,
|
|
116
|
+
const packageDir = (0, import_normalize.normalizePath)(path.join((0, import_socket2.getSocketDlxDir)(), cacheKey));
|
|
114
117
|
const installedDir = (0, import_normalize.normalizePath)(
|
|
115
118
|
path.join(packageDir, "node_modules", packageName)
|
|
116
119
|
);
|
|
@@ -150,7 +153,7 @@ Ensure the filesystem is writable or set SOCKET_DLX_DIR to a writable location.`
|
|
|
150
153
|
const arb = new import_arborist.default({
|
|
151
154
|
path: packageDir,
|
|
152
155
|
// Use Socket's shared cacache directory (~/.socket/_cacache).
|
|
153
|
-
cache: (0,
|
|
156
|
+
cache: (0, import_socket2.getSocketCacacheDir)(),
|
|
154
157
|
// Skip devDependencies (production-only like npx).
|
|
155
158
|
omit: ["dev"],
|
|
156
159
|
// Security: Skip install/preinstall/postinstall scripts to prevent arbitrary code execution.
|
|
@@ -164,8 +167,13 @@ Ensure the filesystem is writable or set SOCKET_DLX_DIR to a writable location.`
|
|
|
164
167
|
// Suppress output (unneeded for ephemeral dlx installs).
|
|
165
168
|
silent: true
|
|
166
169
|
});
|
|
167
|
-
await arb.
|
|
170
|
+
await arb.buildIdealTree({ add: [packageSpec] });
|
|
171
|
+
await checkFirewallPurls(arb, packageName);
|
|
172
|
+
await arb.reify({ save: true });
|
|
168
173
|
} catch (e) {
|
|
174
|
+
if (e instanceof Error && e.message.startsWith("Socket Firewall blocked")) {
|
|
175
|
+
throw e;
|
|
176
|
+
}
|
|
169
177
|
const code = e.code;
|
|
170
178
|
if (code === "E404" || code === "ETARGET") {
|
|
171
179
|
throw new Error(
|
|
@@ -295,6 +303,76 @@ function makePackageBinsExecutable(packageDir, packageName) {
|
|
|
295
303
|
} catch {
|
|
296
304
|
}
|
|
297
305
|
}
|
|
306
|
+
const FIREWALL_API_URL = "https://firewall-api.socket.dev/purl";
|
|
307
|
+
const FIREWALL_TIMEOUT = 1e4;
|
|
308
|
+
const FIREWALL_BLOCK_SEVERITIES = /* @__PURE__ */ new Set([
|
|
309
|
+
"critical",
|
|
310
|
+
"high"
|
|
311
|
+
]);
|
|
312
|
+
function npmPurl(name, version) {
|
|
313
|
+
const encoded = name.startsWith("@") ? `%40${name.slice(1)}` : name;
|
|
314
|
+
const encodedVersion = version.replace(/\+/g, "%2B");
|
|
315
|
+
return `pkg:npm/${encoded}@${encodedVersion}`;
|
|
316
|
+
}
|
|
317
|
+
async function checkFirewallPurls(arb, requestedPackage) {
|
|
318
|
+
const idealTree = arb.idealTree;
|
|
319
|
+
if (!idealTree) {
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
const purls = [];
|
|
323
|
+
for (const node of idealTree.inventory.values()) {
|
|
324
|
+
if (node.isProjectRoot) {
|
|
325
|
+
continue;
|
|
326
|
+
}
|
|
327
|
+
const { name, version } = node.package;
|
|
328
|
+
if (!name || !version) {
|
|
329
|
+
continue;
|
|
330
|
+
}
|
|
331
|
+
purls.push({ purl: npmPurl(name, version), name, version });
|
|
332
|
+
}
|
|
333
|
+
if (purls.length === 0) {
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
const blocked = [];
|
|
337
|
+
await Promise.allSettled(
|
|
338
|
+
purls.map(async ({ name, purl, version }) => {
|
|
339
|
+
try {
|
|
340
|
+
const data = await (0, import_http_request.httpJson)(
|
|
341
|
+
`${FIREWALL_API_URL}/${encodeURIComponent(purl)}`,
|
|
342
|
+
{
|
|
343
|
+
headers: { "User-Agent": import_socket.SOCKET_LIB_USER_AGENT },
|
|
344
|
+
timeout: FIREWALL_TIMEOUT,
|
|
345
|
+
retries: 1,
|
|
346
|
+
retryDelay: 500
|
|
347
|
+
}
|
|
348
|
+
);
|
|
349
|
+
const blocking = (data.alerts ?? []).filter(
|
|
350
|
+
(a) => a.severity && FIREWALL_BLOCK_SEVERITIES.has(a.severity)
|
|
351
|
+
);
|
|
352
|
+
if (blocking.length > 0) {
|
|
353
|
+
blocked.push({
|
|
354
|
+
name,
|
|
355
|
+
version,
|
|
356
|
+
alerts: blocking.map(
|
|
357
|
+
(a) => `${a.severity}: ${a.type ?? a.key ?? "unknown"}`
|
|
358
|
+
)
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
} catch {
|
|
362
|
+
}
|
|
363
|
+
})
|
|
364
|
+
);
|
|
365
|
+
if (blocked.length > 0) {
|
|
366
|
+
const details = blocked.map((b) => ` ${b.name}@${b.version}: ${b.alerts.join(", ")}`).join("\n");
|
|
367
|
+
throw new Error(
|
|
368
|
+
`Socket Firewall blocked installation of "${requestedPackage}".
|
|
369
|
+
The following dependencies have security alerts:
|
|
370
|
+
${details}
|
|
371
|
+
|
|
372
|
+
Visit https://socket.dev for more information.`
|
|
373
|
+
);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
298
376
|
function parsePackageSpec(spec) {
|
|
299
377
|
try {
|
|
300
378
|
const parsed = (0, import_npm_package_arg.default)(spec);
|
|
@@ -345,6 +423,7 @@ function resolveBinaryPath(basePath) {
|
|
|
345
423
|
executePackage,
|
|
346
424
|
findBinaryPath,
|
|
347
425
|
makePackageBinsExecutable,
|
|
426
|
+
npmPurl,
|
|
348
427
|
parsePackageSpec,
|
|
349
428
|
resolveBinaryPath
|
|
350
429
|
});
|
package/dist/http-request.js
CHANGED
|
@@ -32,6 +32,7 @@ __export(http_request_exports, {
|
|
|
32
32
|
sanitizeHeaders: () => sanitizeHeaders
|
|
33
33
|
});
|
|
34
34
|
module.exports = __toCommonJS(http_request_exports);
|
|
35
|
+
var import_socket = require("./constants/socket");
|
|
35
36
|
var import_fs = require("./fs.js");
|
|
36
37
|
let _fs;
|
|
37
38
|
// @__NO_SIDE_EFFECTS__
|
|
@@ -287,7 +288,7 @@ async function httpRequestAttempt(url, options) {
|
|
|
287
288
|
const startTime = Date.now();
|
|
288
289
|
const streamHeaders = body && typeof body === "object" && "getHeaders" in body && typeof body.getHeaders === "function" ? body.getHeaders() : void 0;
|
|
289
290
|
const mergedHeaders = {
|
|
290
|
-
"User-Agent":
|
|
291
|
+
"User-Agent": import_socket.SOCKET_LIB_USER_AGENT,
|
|
291
292
|
...streamHeaders,
|
|
292
293
|
...headers
|
|
293
294
|
};
|
|
@@ -142,43 +142,70 @@ export declare function isPath(pathLike: string | Buffer | URL): boolean;
|
|
|
142
142
|
/*@__NO_SIDE_EFFECTS__*/
|
|
143
143
|
export declare function isRelative(pathLike: string | Buffer | URL): boolean;
|
|
144
144
|
/**
|
|
145
|
-
*
|
|
145
|
+
* Check if a path uses MSYS/Git Bash Unix-style drive letter notation.
|
|
146
146
|
*
|
|
147
|
-
*
|
|
148
|
-
*
|
|
149
|
-
*
|
|
147
|
+
* Detects paths in the format `/c/...` where a single letter after the leading
|
|
148
|
+
* slash represents a Windows drive letter. These paths are produced by MSYS2,
|
|
149
|
+
* Git Bash, and `command -v` on Windows.
|
|
150
|
+
*
|
|
151
|
+
* Detection rules:
|
|
152
|
+
* - Must start with `/` followed by a single ASCII letter (a-z, A-Z)
|
|
153
|
+
* - The letter must be followed by `/` or be at the end of the string
|
|
154
|
+
* - Examples: `/c/tools/bin`, `/d/projects`, `/c`
|
|
155
|
+
* - Non-matches: `/tmp`, `/usr/local`, `C:/Windows`
|
|
156
|
+
*
|
|
157
|
+
* @param {string | Buffer | URL} pathLike - The path to check
|
|
158
|
+
* @returns {boolean} `true` if the path uses MSYS drive letter notation
|
|
159
|
+
*
|
|
160
|
+
* @example
|
|
161
|
+
* ```typescript
|
|
162
|
+
* // MSYS drive letter paths
|
|
163
|
+
* isUnixPath('/c/tools/bin') // true
|
|
164
|
+
* isUnixPath('/d/projects/app') // true
|
|
165
|
+
* isUnixPath('/c') // true
|
|
166
|
+
* isUnixPath('/C/Windows') // true
|
|
167
|
+
*
|
|
168
|
+
* // Not MSYS drive paths
|
|
169
|
+
* isUnixPath('/tmp/build') // false
|
|
170
|
+
* isUnixPath('/usr/local/bin') // false
|
|
171
|
+
* isUnixPath('C:/Windows') // false
|
|
172
|
+
* isUnixPath('./relative') // false
|
|
173
|
+
* isUnixPath('') // false
|
|
174
|
+
* ```
|
|
175
|
+
*/
|
|
176
|
+
/*@__NO_SIDE_EFFECTS__*/
|
|
177
|
+
export declare function isUnixPath(pathLike: string | Buffer | URL): boolean;
|
|
178
|
+
/**
|
|
179
|
+
* Convert Unix-style POSIX paths to native Windows paths.
|
|
180
|
+
*
|
|
181
|
+
* This is the inverse of {@link toUnixPath}. On Windows, MSYS-style paths use
|
|
182
|
+
* `/c/` notation for drive letters and forward slashes, which PowerShell and
|
|
183
|
+
* cmd.exe cannot resolve. This function converts them to native Windows format
|
|
184
|
+
* with backslashes and proper drive letters.
|
|
150
185
|
*
|
|
151
186
|
* Conversion rules:
|
|
152
|
-
* - On Windows: Converts
|
|
153
|
-
* - `/c/path/to/file` becomes `C
|
|
154
|
-
* - `/d/projects/app` becomes `D
|
|
187
|
+
* - On Windows: Converts drive notation and separators to native format
|
|
188
|
+
* - `/c/path/to/file` becomes `C:\path\to\file`
|
|
189
|
+
* - `/d/projects/app` becomes `D:\projects\app`
|
|
190
|
+
* - Forward slashes become backslashes
|
|
155
191
|
* - Drive letters are always uppercase in the output
|
|
156
|
-
* - On Unix: Returns the path unchanged (
|
|
157
|
-
*
|
|
158
|
-
* This is particularly important for:
|
|
159
|
-
* - GitHub Actions runners where `command -v` returns MSYS paths
|
|
160
|
-
* - Tools like sfw that need to resolve real binary paths on Windows
|
|
161
|
-
* - Scripts that receive paths from Git Bash but need to pass them to native Windows tools
|
|
192
|
+
* - On Unix: Returns the normalized path unchanged (forward slashes preserved)
|
|
162
193
|
*
|
|
163
194
|
* @param {string | Buffer | URL} pathLike - The MSYS/Unix-style path to convert
|
|
164
|
-
* @returns {string} Native Windows path (e.g., `C
|
|
195
|
+
* @returns {string} Native Windows path (e.g., `C:\path\to\file`) or normalized Unix path
|
|
165
196
|
*
|
|
166
197
|
* @example
|
|
167
198
|
* ```typescript
|
|
168
|
-
* // MSYS drive letter paths
|
|
169
|
-
* fromUnixPath('/c/projects/app/file.txt') // 'C
|
|
170
|
-
* fromUnixPath('/d/projects/foo/bar') // 'D
|
|
199
|
+
* // MSYS drive letter paths (Windows)
|
|
200
|
+
* fromUnixPath('/c/projects/app/file.txt') // 'C:\\projects\\app\\file.txt'
|
|
201
|
+
* fromUnixPath('/d/projects/foo/bar') // 'D:\\projects\\foo\\bar'
|
|
202
|
+
* fromUnixPath('/c') // 'C:\\'
|
|
171
203
|
*
|
|
172
|
-
* //
|
|
173
|
-
* fromUnixPath('/
|
|
174
|
-
* fromUnixPath('/usr/local/bin') // '/usr/local/bin'
|
|
175
|
-
*
|
|
176
|
-
* // Already Windows paths (unchanged)
|
|
177
|
-
* fromUnixPath('C:/Windows/System32') // 'C:/Windows/System32'
|
|
204
|
+
* // Forward-slash paths (Windows)
|
|
205
|
+
* fromUnixPath('C:/Windows/System32') // 'C:\\Windows\\System32'
|
|
178
206
|
*
|
|
179
|
-
* //
|
|
180
|
-
* fromUnixPath('/
|
|
181
|
-
* fromUnixPath('') // '.'
|
|
207
|
+
* // Unix (unchanged, forward slashes preserved)
|
|
208
|
+
* fromUnixPath('/tmp/build/output') // '/tmp/build/output'
|
|
182
209
|
* ```
|
|
183
210
|
*/
|
|
184
211
|
/*@__NO_SIDE_EFFECTS__*/
|
|
@@ -196,6 +223,7 @@ export declare function fromUnixPath(pathLike: string | Buffer | URL): string;
|
|
|
196
223
|
* - Returns `.` for empty or collapsed paths
|
|
197
224
|
*
|
|
198
225
|
* Special handling:
|
|
226
|
+
* - MSYS drive letters (Windows only): `/c/path` becomes `C:/path`
|
|
199
227
|
* - UNC paths: Maintains double leading slashes for `//server/share` format
|
|
200
228
|
* - Windows namespaces: Preserves `//./` and `//?/` prefixes
|
|
201
229
|
* - Leading `..` segments: Preserved in relative paths without prefix
|
|
@@ -222,6 +250,10 @@ export declare function fromUnixPath(pathLike: string | Buffer | URL): string;
|
|
|
222
250
|
* normalizePath('C:\\Users\\username\\file.txt') // 'C:/Users/username/file.txt'
|
|
223
251
|
* normalizePath('foo\\bar\\baz') // 'foo/bar/baz'
|
|
224
252
|
*
|
|
253
|
+
* // MSYS drive letters (Windows only)
|
|
254
|
+
* normalizePath('/c/projects/app') // 'C:/projects/app' (on Windows)
|
|
255
|
+
* normalizePath('/d/tools/bin') // 'D:/tools/bin' (on Windows)
|
|
256
|
+
*
|
|
225
257
|
* // UNC paths
|
|
226
258
|
* normalizePath('\\\\server\\share\\file') // '//server/share/file'
|
|
227
259
|
*
|
package/dist/paths/normalize.js
CHANGED
|
@@ -24,6 +24,7 @@ __export(normalize_exports, {
|
|
|
24
24
|
isNodeModules: () => isNodeModules,
|
|
25
25
|
isPath: () => isPath,
|
|
26
26
|
isRelative: () => isRelative,
|
|
27
|
+
isUnixPath: () => isUnixPath,
|
|
27
28
|
normalizePath: () => normalizePath,
|
|
28
29
|
pathLikeToString: () => pathLikeToString,
|
|
29
30
|
relativeResolve: () => relativeResolve,
|
|
@@ -41,6 +42,7 @@ const CHAR_LOWERCASE_A = 97;
|
|
|
41
42
|
const CHAR_LOWERCASE_Z = 122;
|
|
42
43
|
const CHAR_UPPERCASE_A = 65;
|
|
43
44
|
const CHAR_UPPERCASE_Z = 90;
|
|
45
|
+
const msysDriveRegExp = /^\/([a-zA-Z])(\/|$)/;
|
|
44
46
|
const slashRegExp = /[/\\]/;
|
|
45
47
|
const nodeModulesPathRegExp = /(?:^|[/\\])node_modules(?:[/\\]|$)/;
|
|
46
48
|
// @__NO_SIDE_EFFECTS__
|
|
@@ -67,6 +69,15 @@ function getUrl() {
|
|
|
67
69
|
}
|
|
68
70
|
return _url;
|
|
69
71
|
}
|
|
72
|
+
function msysDriveToNative(normalized) {
|
|
73
|
+
if (import_platform.WIN32) {
|
|
74
|
+
return normalized.replace(
|
|
75
|
+
msysDriveRegExp,
|
|
76
|
+
(_, letter, sep) => `${letter.toUpperCase()}:${sep || "/"}`
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
return normalized;
|
|
80
|
+
}
|
|
70
81
|
// @__NO_SIDE_EFFECTS__
|
|
71
82
|
function isNodeModules(pathLike) {
|
|
72
83
|
const filepath = /* @__PURE__ */ pathLikeToString(pathLike);
|
|
@@ -131,13 +142,15 @@ function isRelative(pathLike) {
|
|
|
131
142
|
return !/* @__PURE__ */ isAbsolute(filepath);
|
|
132
143
|
}
|
|
133
144
|
// @__NO_SIDE_EFFECTS__
|
|
145
|
+
function isUnixPath(pathLike) {
|
|
146
|
+
const filepath = /* @__PURE__ */ pathLikeToString(pathLike);
|
|
147
|
+
return typeof filepath === "string" && msysDriveRegExp.test(filepath);
|
|
148
|
+
}
|
|
149
|
+
// @__NO_SIDE_EFFECTS__
|
|
134
150
|
function fromUnixPath(pathLike) {
|
|
135
151
|
const normalized = /* @__PURE__ */ normalizePath(pathLike);
|
|
136
152
|
if (import_platform.WIN32) {
|
|
137
|
-
return normalized.replace(
|
|
138
|
-
/^\/([a-zA-Z])(\/|$)/,
|
|
139
|
-
(_, letter, sep) => `${letter.toUpperCase()}:${sep || "/"}`
|
|
140
|
-
);
|
|
153
|
+
return normalized.replace(/\//g, "\\");
|
|
141
154
|
}
|
|
142
155
|
return normalized;
|
|
143
156
|
}
|
|
@@ -219,7 +232,7 @@ function normalizePath(pathLike) {
|
|
|
219
232
|
if (segment === "..") {
|
|
220
233
|
return prefix ? prefix.slice(0, -1) || "/" : "..";
|
|
221
234
|
}
|
|
222
|
-
return prefix + segment;
|
|
235
|
+
return msysDriveToNative(prefix + segment);
|
|
223
236
|
}
|
|
224
237
|
let collapsed = "";
|
|
225
238
|
let segmentCount = 0;
|
|
@@ -300,7 +313,7 @@ function normalizePath(pathLike) {
|
|
|
300
313
|
if (collapsed.length === 0) {
|
|
301
314
|
return prefix || ".";
|
|
302
315
|
}
|
|
303
|
-
return prefix + collapsed;
|
|
316
|
+
return msysDriveToNative(prefix + collapsed);
|
|
304
317
|
}
|
|
305
318
|
// @__NO_SIDE_EFFECTS__
|
|
306
319
|
function pathLikeToString(pathLike) {
|
|
@@ -465,6 +478,7 @@ function toUnixPath(pathLike) {
|
|
|
465
478
|
isNodeModules,
|
|
466
479
|
isPath,
|
|
467
480
|
isRelative,
|
|
481
|
+
isUnixPath,
|
|
468
482
|
normalizePath,
|
|
469
483
|
pathLikeToString,
|
|
470
484
|
relativeResolve,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@socketsecurity/lib",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.18.0",
|
|
4
4
|
"packageManager": "pnpm@11.0.0-rc.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "Core utilities and infrastructure for Socket.dev security tools",
|
|
@@ -737,7 +737,7 @@
|
|
|
737
737
|
"@socketregistry/is-unicode-supported": "1.0.5",
|
|
738
738
|
"@socketregistry/packageurl-js": "1.4.1",
|
|
739
739
|
"@socketregistry/yocto-spinner": "1.0.25",
|
|
740
|
-
"@socketsecurity/lib-stable": "npm:@socketsecurity/lib@5.
|
|
740
|
+
"@socketsecurity/lib-stable": "npm:@socketsecurity/lib@5.17.0",
|
|
741
741
|
"@types/node": "24.9.2",
|
|
742
742
|
"@typescript/native-preview": "7.0.0-dev.20250920.1",
|
|
743
743
|
"@vitest/coverage-v8": "4.0.3",
|