@socketsecurity/lib 5.20.1 → 5.23.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 +116 -95
- package/README.md +24 -181
- package/dist/archives.js +13 -0
- package/dist/cacache.js +6 -8
- package/dist/cache-with-ttl.js +1 -1
- package/dist/constants/socket.js +1 -1
- package/dist/dlx/detect.js +25 -8
- package/dist/dlx/manifest.js +8 -19
- package/dist/dlx/package.js +16 -2
- package/dist/env/socket-cli.d.ts +4 -3
- package/dist/env/socket-cli.js +1 -1
- package/dist/errors.d.ts +96 -2
- package/dist/errors.js +55 -0
- package/dist/external/pony-cause.js +12 -11
- package/dist/fs.js +8 -2
- package/dist/github.js +3 -2
- package/dist/globs.js +5 -1
- package/dist/ipc.js +2 -2
- package/dist/json/edit.js +3 -2
- package/dist/json/parse.d.ts +47 -2
- package/dist/json/parse.js +40 -2
- package/dist/json/types.d.ts +49 -0
- package/dist/memoization.d.ts +4 -23
- package/dist/memoization.js +14 -54
- package/dist/packages/isolation.js +4 -4
- package/dist/packages/specs.js +9 -2
- package/dist/performance.js +3 -2
- package/dist/process-lock.js +4 -12
- package/dist/promise-queue.d.ts +9 -4
- package/dist/promise-queue.js +9 -7
- package/dist/promises.d.ts +41 -0
- package/dist/promises.js +19 -2
- package/dist/regexps.d.ts +4 -13
- package/dist/regexps.js +60 -3
- package/dist/releases/github.js +3 -2
- package/dist/releases/socket-btm.d.ts +61 -5
- package/dist/releases/socket-btm.js +2 -2
- package/dist/schema/parse.d.ts +26 -0
- package/dist/schema/parse.js +38 -0
- package/dist/schema/types.d.ts +121 -0
- package/dist/schema/validate.d.ts +35 -0
- package/dist/{validation/validate-schema.js → schema/validate.js} +4 -14
- package/dist/suppress-warnings.js +0 -2
- package/dist/url.js +5 -1
- package/dist/versions.js +2 -2
- package/dist/words.js +4 -7
- package/package.json +15 -15
- package/dist/validation/json-parser.d.ts +0 -58
- package/dist/validation/json-parser.js +0 -63
- package/dist/validation/types.d.ts +0 -118
- package/dist/validation/validate-schema.d.ts +0 -124
- /package/dist/{validation → schema}/types.js +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,92 +5,120 @@ 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.
|
|
8
|
+
## [5.23.0](https://github.com/SocketDev/socket-lib/releases/tag/v5.23.0) - 2026-04-22
|
|
9
9
|
|
|
10
|
-
###
|
|
10
|
+
### Added
|
|
11
11
|
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
- `src/paths/packages.ts` — `resolvePackageJsonDirname` / `resolvePackageJsonPath` gated on `filepath.endsWith('package.json')`, which misidentified any file whose name ended in that suffix (e.g. `/foo/my-package.json`) as a manifest. Now checks for the literal final segment
|
|
18
|
-
- `src/json/edit.ts` — `@example` for `getEditableJsonClass` imported from `@socketsecurity/lib/json`, which is not a package export; fixed to `@socketsecurity/lib/json/edit`
|
|
12
|
+
- `@socketsecurity/lib/errors` `isError(value)` — spec-compliant ES2025 [`Error.isError`](https://tc39.es/ecma262/#sec-error.iserror) with an `@@toStringTag`-based shim for older engines. Recognizes cross-realm Errors (worker threads, vm contexts, iframes) that same-realm `instanceof Error` misses
|
|
13
|
+
- `@socketsecurity/lib/errors` `errorMessage(value)` — extracts a readable message from any caught value (Error with cause chain via `messageWithCauses`, primitive, plain object, or nullish) with the shared `UNKNOWN_ERROR` (`'Unknown error'`) fallback. Replaces the `e instanceof Error ? e.message : String(e)` pattern
|
|
14
|
+
- `@socketsecurity/lib/errors` `errorStack(value)` — companion helper returning the cause-aware stack for Error instances (via `stackWithCauses`) and `undefined` otherwise
|
|
15
|
+
- `@socketsecurity/lib/errors` `isErrnoException(value)` — narrows to `NodeJS.ErrnoException` (an Error with a non-empty uppercase-prefixed `.code`, matching the libuv `UV_E*` / Node `ERR_*` conventions), cross-realm safe
|
|
16
|
+
- `@socketsecurity/lib/errors` re-exports `UNKNOWN_ERROR` from `constants/core` so callers don't need a separate import
|
|
19
17
|
|
|
20
|
-
|
|
18
|
+
### Changed
|
|
19
|
+
|
|
20
|
+
- `@socketsecurity/lib/errors` pony-cause `messageWithCauses` / `stackWithCauses` / `findCauseByReference` / `getErrorCause` — patched to use `isError` internally so cross-realm Errors are recognized (previously returned `''` for any Error thrown in a different realm)
|
|
21
|
+
|
|
22
|
+
## [5.22.0](https://github.com/SocketDev/socket-lib/releases/tag/v5.22.0) - 2026-04-21
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
|
|
26
|
+
- `@socketsecurity/lib/releases/socket-btm` `getPlatformArch()` / `getBinaryAssetName()` — aligned with pnpm pack-app's `<os>-<arch>[-<libc>]` target format. The Windows OS segment is now `win32` (was `win`); `getPlatformArch('win32', 'x64')` returns `'win32-x64'` and `getBinaryAssetName('node', 'win32', 'x64')` returns `'node-win32-x64.exe'`. Callers that string-match on the output need updates
|
|
27
|
+
|
|
28
|
+
## [5.21.0](https://github.com/SocketDev/socket-lib/releases/tag/v5.21.0) - 2026-04-20
|
|
29
|
+
|
|
30
|
+
### Added
|
|
21
31
|
|
|
22
|
-
|
|
32
|
+
- `@socketsecurity/lib/schema/validate` — non-throwing Zod/TypeBox validator returning `{ ok, value } | { ok, errors }` with normalized paths
|
|
33
|
+
- `@socketsecurity/lib/schema/parse` — throwing variant for fail-fast trust boundaries
|
|
34
|
+
- `@socketsecurity/lib/schema/types` — `Schema<T>`, `ValidateResult<T>`, `ValidationIssue`, `AnySchema`, `Infer<S>`
|
|
35
|
+
- `@socketsecurity/lib/promises` `withResolvers()` — spec-compliant [`Promise.withResolvers`](https://tc39.es/ecma262/#sec-promise.withResolvers) helper with `PromiseWithResolvers<T>` type. Uses the native implementation when available
|
|
23
36
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
- `
|
|
37
|
+
### Changed
|
|
38
|
+
|
|
39
|
+
- `@socketsecurity/lib/regexps` `escapeRegExp()` — now spec-compliant with TC39 [`RegExp.escape`](https://tc39.es/ecma262/#sec-regexp.escape); uses the native implementation when available. **Caller-visible shape change**: escaped output now uses `\xHH` for many characters that previously passed through literally (e.g. `escapeRegExp('a')` is now `'\x61'`). Functional equivalence (the compiled regex matches the original input) is preserved; only callers that string-match on escape output need updates
|
|
40
|
+
- `@socketsecurity/lib/memoization` `MemoizeOptions<Args>` — dropped the unused second type parameter. Consumers who wrote `MemoizeOptions<Args, Result>` must drop the second argument
|
|
41
|
+
- `@socketsecurity/lib/packages/specs` `getRepoUrlDetails()` — now accepts `git+https://` / `git+ssh://` GitHub URLs and rejects lookalike hosts (`githubXcom`, `fake-github.com.attacker.tld`). scp-style `git@github.com:…` URLs (no `://`) now return `{ user: '', project: '' }` — callers must normalize to https/ssh upstream
|
|
42
|
+
- `@socketsecurity/lib/url` `urlSearchParamAsBoolean()` — accepts the same truthy vocabulary as `envAsBoolean` (`1` / `true` / `yes` / `on`, case-insensitive). Empty-string input now falls through to `defaultValue` instead of returning `false`
|
|
43
|
+
|
|
44
|
+
### Removed
|
|
45
|
+
|
|
46
|
+
- `@socketsecurity/lib/validation/*` subpath retired — exports re-homed:
|
|
47
|
+
- `validateSchema` / `parseSchema` → `@socketsecurity/lib/schema/validate` / `@socketsecurity/lib/schema/parse`
|
|
48
|
+
- `safeJsonParse` → `@socketsecurity/lib/json/parse`
|
|
49
|
+
- Types → `@socketsecurity/lib/schema/types` and `@socketsecurity/lib/json/types`
|
|
50
|
+
- `memoizeDebounced` from `@socketsecurity/lib/memoization` — was misnamed and had no consumers. Use `memoize` / `memoizeAsync` with a `ttl` instead
|
|
27
51
|
|
|
28
52
|
### Fixed
|
|
29
53
|
|
|
30
|
-
- `
|
|
31
|
-
-
|
|
32
|
-
-
|
|
33
|
-
-
|
|
34
|
-
-
|
|
35
|
-
-
|
|
36
|
-
-
|
|
54
|
+
- `@socketsecurity/lib/versions` `maxVersion()` / `minVersion()` — return the latest/earliest prerelease for all-prerelease inputs (previously returned `undefined`)
|
|
55
|
+
- `@socketsecurity/lib/fs` `findUp()` / `findUpSync()` — traverse up to and **including** the filesystem root (previously missed matches at `/.foo`)
|
|
56
|
+
- `@socketsecurity/lib/words` `capitalize()` — safe for non-BMP characters (emoji, astral-plane scripts); previously produced broken surrogate pairs
|
|
57
|
+
- `@socketsecurity/lib/words` `determineArticle()` — case-insensitive vowel match (`Apple` → `an Apple`)
|
|
58
|
+
- `@socketsecurity/lib/archives` `extractZip()` / `extractTar()` / `extractTarGz()` — missing-archive errors now uniformly surface as `ENOENT` with `code` / `path` / message (previously `extractZip` surfaced adm-zip's generic `"Invalid filename"`)
|
|
59
|
+
- `@socketsecurity/lib/promise-queue` — bounded queue now rejects the newest submission when full, preserving in-flight work
|
|
60
|
+
- `@socketsecurity/lib/cacache` / `@socketsecurity/lib/cache-with-ttl` — wildcard key deletion anchors both ends of the pattern (`deleteAll('foo*bar')` no longer sweeps `foo123bar-extra`)
|
|
61
|
+
- `@socketsecurity/lib/process-lock` — sub-second `staleMs` values now honored at full precision; TOCTOU window on lock acquisition closed
|
|
62
|
+
- `@socketsecurity/lib/suppress-warnings` `withSuppressedWarnings()` — no longer wipes concurrent suppressions on exit
|
|
63
|
+
- Unbounded LRU caches in `@socketsecurity/lib/dlx` capped (binary path, package.json path); negative package.json lookups now expire after 10s
|
|
64
|
+
- Glob cache keys for array-valued options (e.g. `ignore`) are order-insensitive
|
|
37
65
|
|
|
38
|
-
|
|
66
|
+
### Performance
|
|
39
67
|
|
|
40
|
-
|
|
68
|
+
- `@socketsecurity/lib/memoization` — `memoize()` / `memoizeAsync()` cache-hit bookkeeping dropped from O(n) to O(1). Noticeable on caches with many entries
|
|
69
|
+
- `@socketsecurity/lib/cacache` — wildcard `clear()` no longer recompiles the match regex per streamed entry
|
|
41
70
|
|
|
42
|
-
5.
|
|
71
|
+
## [5.20.1](https://github.com/SocketDev/socket-lib/releases/tag/v5.20.1) - 2026-04-19
|
|
43
72
|
|
|
44
|
-
|
|
73
|
+
### Fixed
|
|
45
74
|
|
|
46
|
-
- `@socketsecurity/lib/
|
|
47
|
-
- `@socketsecurity/lib/
|
|
48
|
-
- `@socketsecurity/lib/
|
|
49
|
-
-
|
|
50
|
-
-
|
|
75
|
+
- `@socketsecurity/lib/ipc` — harden stub-file writes against symlink/TOCTOU attacks on shared-tmp filesystems (POSIX ownership + mode validation, `O_EXCL | O_NOFOLLOW` open)
|
|
76
|
+
- `@socketsecurity/lib/cache-with-ttl` `getOrFetch()` — close concurrent-caller race that let two cold-cache awaits both skip the inflight-dedupe check and fire the fetcher twice
|
|
77
|
+
- `@socketsecurity/lib/cache-with-ttl` — cap the in-memory memo layer with LRU eviction (`memoMaxSize`, default 1000); long-running processes no longer grow unbounded
|
|
78
|
+
- `@socketsecurity/lib/memoization` `memoizeAsync()` — refresh cache entry timestamp on resolve so slow fetches (longer than `ttl`) aren't classified as expired the moment they land
|
|
79
|
+
- `@socketsecurity/lib/tables` — `displayWidth` now measures rendered terminal cells (via `stringWidth`) instead of UTF-16 code units; CJK / emoji / combining marks align correctly
|
|
80
|
+
- `@socketsecurity/lib/paths/packages` — `resolvePackageJsonDirname` / `resolvePackageJsonPath` no longer mis-identify files like `/foo/my-package.json` as package manifests
|
|
81
|
+
- `@socketsecurity/lib/json/edit` — `@example` import path corrected
|
|
51
82
|
|
|
52
|
-
## [5.
|
|
83
|
+
## [5.20.0](https://github.com/SocketDev/socket-lib/releases/tag/v5.20.0) - 2026-04-19
|
|
84
|
+
|
|
85
|
+
### Added
|
|
53
86
|
|
|
54
|
-
|
|
87
|
+
- `@socketsecurity/lib/validation/validate-schema` — universal Zod-style schema validator with `validateSchema` (tagged result) and `parseSchema` (throwing); `Infer<S>`, `ValidateResult<T>`, `ValidationIssue`, `AnySchema` types. No runtime `zod` dependency
|
|
55
88
|
|
|
56
|
-
|
|
57
|
-
- `normalizeHash()`, `computeHashes()`, `verifyHash()` — `verifyHash` uses `crypto.timingSafeEqual` for constant-time comparison
|
|
58
|
-
- `DlxHashMismatchError` — carries `expected` + `actual` for diagnostics
|
|
89
|
+
> **Deprecated in 5.21.0**: moved to `@socketsecurity/lib/schema/*`.
|
|
59
90
|
|
|
60
|
-
###
|
|
91
|
+
### Fixed
|
|
61
92
|
|
|
62
|
-
-
|
|
63
|
-
- `
|
|
64
|
-
-
|
|
93
|
+
- `@socketsecurity/lib/promise-queue` — synchronous throws inside a queued task now convert to proper rejections instead of escaping as uncaught exceptions
|
|
94
|
+
- `@socketsecurity/lib/stdio/progress` `formatTime()` — clamp negative milliseconds so over-ticking / clock-skewed bars don't render negative ETAs
|
|
95
|
+
- `@socketsecurity/lib/dlx/lockfile` — scratch-directory cleanup can no longer clobber the real exception from the main block
|
|
96
|
+
- `@socketsecurity/lib/dlx/package` `parsePackageSpec` — normalize a bare trailing `@` (e.g. `"pkg@"`) to `version: undefined`
|
|
97
|
+
- `@socketsecurity/lib/stdio/prompts` — tighten an internal destructure type away from `as any`
|
|
98
|
+
- `@socketsecurity/lib/http-request` — hoist checksum regex literals out of a per-line loop
|
|
65
99
|
|
|
66
|
-
|
|
100
|
+
## [5.19.1](https://github.com/SocketDev/socket-lib/releases/tag/v5.19.1) - 2026-04-19
|
|
67
101
|
|
|
68
|
-
|
|
69
|
-
- **Default `minReleaseDays: 7`** — resolution refuses to select versions published in the last week. Pass `0` to disable. `minReleaseMins` is a pnpm-style alias (mutually exclusive with `minReleaseDays`)
|
|
70
|
-
- `LockfileSpec` type — export for use as the new `lockfile` option on `downloadPackage`
|
|
102
|
+
### Fixed
|
|
71
103
|
|
|
72
|
-
|
|
104
|
+
Restore `@socketsecurity/lib/stdio/prompts`, `@socketsecurity/lib/stdio/progress`, and `@socketsecurity/lib/stdio/clear` — accidentally removed in 5.19.0 without a major-bump callout. Downstream consumers that import `stdio/prompts` directly are unbroken.
|
|
73
105
|
|
|
74
|
-
|
|
75
|
-
- `DlxBinaryOptions.hash?: HashSpec` — ergonomic alternative to the lower-level `integrity` and `sha256` fields (both still accepted)
|
|
106
|
+
## [5.19.0](https://github.com/SocketDev/socket-lib/releases/tag/v5.19.0) - 2026-04-19
|
|
76
107
|
|
|
77
|
-
###
|
|
108
|
+
### Added
|
|
78
109
|
|
|
79
|
-
- `
|
|
110
|
+
- `@socketsecurity/lib/dlx/integrity` — hash verification utilities: `HashSpec`, `NormalizedHash`, `ComputedHashes`, `normalizeHash()`, `computeHashes()`, `verifyHash()` (constant-time via `crypto.timingSafeEqual`), `DlxHashMismatchError`
|
|
111
|
+
- `@socketsecurity/lib/dlx/arborist` — hardened `@npmcli/arborist` wrappers: `safeIdealTree()`, `safeReify()`, `writeSafeNpmrc()`. Locks down `audit`, `fund`, `ignoreScripts`, `saveBundle`, etc. Supports `before?: Date` for release-age enforcement
|
|
112
|
+
- `@socketsecurity/lib/dlx/lockfile` — `generatePackagePin()` returns `{ name, version, hash, packageJson, lockfile }` for a resolved package. Default `minReleaseDays: 7` refuses versions published in the last week (`0` to disable); `minReleaseMins` accepted as pnpm-style alias
|
|
113
|
+
- `DlxPackageOptions.hash`, `DlxPackageOptions.lockfile`, `DlxBinaryOptions.hash` — first-class integrity + lockfile options on the dlx entry points
|
|
80
114
|
|
|
81
|
-
###
|
|
115
|
+
### Fixed
|
|
82
116
|
|
|
83
|
-
- `
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
- `@npmcli/git`, `pacote/lib/{git,file,dir,remote}.js` — registry specs only
|
|
89
|
-
- arborist `audit-report.js`, `yarn-lock.js`, `isolated-reifier.js`, `query-selector-all.js`, `printable.js` — each gated or unused
|
|
90
|
-
- `cacache/lib/verify.js` — `cacache.verify` (npm cache verify) unused
|
|
91
|
-
- `proggy` — progress tracker, gated by `progress: false`
|
|
92
|
-
- `debug/src/browser.js` — Node-only bundle
|
|
93
|
-
- `dist/external/zod.js`: 597,238 → 291,430 bytes (−306 KB, −51.2%). Stubbed `zod/v4/{core,classic,mini}`'s eager `locales/index.cjs` barrel (40+ translation modules). Opt-in via `z.config(z.locales.xx())` is never called by us
|
|
117
|
+
- `pacote` shim — exposes `tarball`, `manifest`, `packument` alongside `extract`. Fixes a latent runtime crash in `fetchPackageManifest` / `fetchPackagePackument` callers
|
|
118
|
+
|
|
119
|
+
### Changed
|
|
120
|
+
|
|
121
|
+
Reduced bundle size of `dist/external/npm-pack.js` (−771 KB, −30.5%) and `dist/external/zod.js` (−306 KB, −51.2%) by stubbing code paths our callers never reach (Sigstore attestation, arborist audit/query, zod locale translations, etc.)
|
|
94
122
|
|
|
95
123
|
## [5.18.2](https://github.com/SocketDev/socket-lib/releases/tag/v5.18.2) - 2026-04-14
|
|
96
124
|
|
|
@@ -100,70 +128,63 @@ Restored:
|
|
|
100
128
|
|
|
101
129
|
## [5.18.1](https://github.com/SocketDev/socket-lib/releases/tag/v5.18.1) - 2026-04-14
|
|
102
130
|
|
|
103
|
-
### Changed
|
|
131
|
+
### Changed
|
|
104
132
|
|
|
105
|
-
-
|
|
106
|
-
- npm-pack.js: 69,738 → 66,443 lines (2.59MB → 2.46MB), 22 duplicate packages removed
|
|
133
|
+
- Deduplicated the `dist/external/npm-pack` bundle via `pnpm overrides` (pacote 21.5.0, make-fetch-happen 15.0.5, and 7 transitive `@npmcli/*` packages) — 22 duplicate packages removed, ~130 KB smaller
|
|
107
134
|
|
|
108
135
|
## [5.18.0](https://github.com/SocketDev/socket-lib/releases/tag/v5.18.0) - 2026-04-14
|
|
109
136
|
|
|
110
|
-
### Added
|
|
137
|
+
### Added
|
|
111
138
|
|
|
112
|
-
- Socket Firewall API check before package downloads
|
|
139
|
+
- `@socketsecurity/lib/dlx` — Socket Firewall API check before package downloads. Resolves the dependency tree and blocks on critical/high severity alerts
|
|
113
140
|
|
|
114
|
-
### Changed
|
|
141
|
+
### Changed
|
|
115
142
|
|
|
116
|
-
-
|
|
143
|
+
- `@socketsecurity/lib/http-request` — default `User-Agent` updated from `socket-registry/1.0` to `socketsecurity-lib/{version}`
|
|
117
144
|
|
|
118
145
|
## [5.17.0](https://github.com/SocketDev/socket-lib/releases/tag/v5.17.0) - 2026-04-14
|
|
119
146
|
|
|
120
|
-
### Added
|
|
147
|
+
### Added
|
|
121
148
|
|
|
122
|
-
- `isUnixPath()` — detect MSYS/Git Bash drive
|
|
149
|
+
- `@socketsecurity/lib/paths` `isUnixPath()` — detect MSYS/Git Bash drive-letter notation (`/c/...`)
|
|
123
150
|
|
|
124
|
-
### Changed
|
|
151
|
+
### Changed
|
|
125
152
|
|
|
126
|
-
- `normalizePath()`
|
|
127
|
-
- `fromUnixPath()`
|
|
153
|
+
- `@socketsecurity/lib/paths` `normalizePath()` — converts MSYS drive letters on Windows (`/c/path` → `C:/path`)
|
|
154
|
+
- `@socketsecurity/lib/paths` `fromUnixPath()` — produces native Windows paths with backslashes (`/c/path` → `C:\path`), making it the true inverse of `toUnixPath()`
|
|
128
155
|
|
|
129
156
|
## [5.16.0](https://github.com/SocketDev/socket-lib/releases/tag/v5.16.0) - 2026-04-14
|
|
130
157
|
|
|
131
|
-
### Added
|
|
158
|
+
### Added
|
|
132
159
|
|
|
133
|
-
- `fromUnixPath()` — convert MSYS/Git Bash Unix-style paths (`/c/path`) back to native Windows format (`C:/path`), inverse of `toUnixPath` (#168)
|
|
160
|
+
- `@socketsecurity/lib/paths` `fromUnixPath()` — convert MSYS/Git Bash Unix-style paths (`/c/path`) back to native Windows format (`C:/path`), inverse of `toUnixPath` (#168)
|
|
134
161
|
|
|
135
|
-
### Fixed
|
|
162
|
+
### Fixed
|
|
136
163
|
|
|
137
|
-
-
|
|
164
|
+
- `@socketsecurity/lib/dlx` `isInSocketDlx` — normalize the dlx directory path for Windows compatibility
|
|
138
165
|
|
|
139
166
|
## [5.15.0](https://github.com/SocketDev/socket-lib/releases/tag/v5.15.0) - 2026-04-06
|
|
140
167
|
|
|
141
|
-
### Added
|
|
142
|
-
|
|
143
|
-
- `stream` option on `HttpRequestOptions` — resolves with `HttpResponse` immediately after headers arrive, leaving `rawResponse` unconsumed for piping to files
|
|
144
|
-
- `headers`, `ok`, `status`, `statusText` fields on `HttpDownloadResult`
|
|
145
|
-
|
|
146
|
-
### Changed — http-request
|
|
168
|
+
### Added
|
|
147
169
|
|
|
148
|
-
- `
|
|
170
|
+
- `@socketsecurity/lib/http-request` — `stream` option on `HttpRequestOptions` resolves with `HttpResponse` immediately after headers arrive, leaving `rawResponse` unconsumed for piping to files
|
|
171
|
+
- `@socketsecurity/lib/http-request` — `headers`, `ok`, `status`, `statusText` fields on `HttpDownloadResult`
|
|
149
172
|
|
|
150
173
|
## [5.14.0](https://github.com/SocketDev/socket-lib/releases/tag/v5.14.0) - 2026-04-06
|
|
151
174
|
|
|
152
|
-
### Added
|
|
175
|
+
### Added
|
|
153
176
|
|
|
154
|
-
-
|
|
155
|
-
- `
|
|
156
|
-
- `
|
|
157
|
-
-
|
|
158
|
-
- `
|
|
159
|
-
- `
|
|
177
|
+
- `@socketsecurity/lib/http-request`:
|
|
178
|
+
- `HttpResponseError` class — thrown on non-2xx when `throwOnError` is enabled; carries the full `HttpResponse`
|
|
179
|
+
- `throwOnError` option — non-2xx responses throw instead of resolving with `ok: false`
|
|
180
|
+
- `onRetry` callback — customize retry behavior per-attempt (`false` to stop, a `number` to override delay, `undefined` for default backoff)
|
|
181
|
+
- Streaming body support — `body` accepts `Readable` streams (incl. `form-data`), auto-merges `getHeaders()` when present
|
|
182
|
+
- `parseRetryAfterHeader()` — standalone RFC 7231 §7.1.3 parser
|
|
183
|
+
- `sanitizeHeaders()` — redact sensitive headers for safe logging
|
|
160
184
|
|
|
161
|
-
### Changed
|
|
185
|
+
### Changed
|
|
162
186
|
|
|
163
|
-
- `HttpRequestOptions.body`
|
|
164
|
-
- Redirect responses now drained via `res.resume()` to free sockets
|
|
165
|
-
- `maxResponseSize` exceeded now cleans up both response and request
|
|
166
|
-
- `onResponse` hooks wrapped in try/catch — user hook errors can no longer leave promises pending
|
|
187
|
+
- `@socketsecurity/lib/http-request` — `HttpRequestOptions.body` widened to `Buffer | Readable | string`; `onResponse` hook errors no longer leave promises pending
|
|
167
188
|
|
|
168
189
|
## [5.13.0](https://github.com/SocketDev/socket-lib/releases/tag/v5.13.0) - 2026-04-05
|
|
169
190
|
|
package/README.md
CHANGED
|
@@ -7,219 +7,62 @@
|
|
|
7
7
|
[](https://twitter.com/SocketSecurity)
|
|
8
8
|
[](https://bsky.app/profile/socket.dev)
|
|
9
9
|
|
|
10
|
-
Core
|
|
11
|
-
|
|
12
|
-
## Prerequisites
|
|
13
|
-
|
|
14
|
-
**Node.js 22 or higher** is required.
|
|
10
|
+
Core utilities for [Socket.dev](https://socket.dev/) tools: file system, processes, HTTP, env detection, logging, spinners, and more. Tree-shakeable, TypeScript-first, cross-platform.
|
|
15
11
|
|
|
16
12
|
## Install
|
|
17
13
|
|
|
18
14
|
```bash
|
|
19
|
-
# Using pnpm (recommended)
|
|
20
15
|
pnpm add @socketsecurity/lib
|
|
21
|
-
|
|
22
|
-
# Using npm
|
|
23
|
-
npm install @socketsecurity/lib
|
|
24
|
-
|
|
25
|
-
# Using yarn
|
|
26
|
-
yarn add @socketsecurity/lib
|
|
27
16
|
```
|
|
28
17
|
|
|
29
18
|
## Quick Start
|
|
30
19
|
|
|
31
20
|
```typescript
|
|
32
21
|
import { Spinner } from '@socketsecurity/lib/spinner'
|
|
33
|
-
import { getDefaultLogger } from '@socketsecurity/lib/logger'
|
|
34
22
|
import { readJson } from '@socketsecurity/lib/fs'
|
|
35
23
|
|
|
36
|
-
const
|
|
37
|
-
const spinner = Spinner({ text: 'Loading package.json...' })
|
|
38
|
-
|
|
24
|
+
const spinner = Spinner({ text: 'Loading…' })
|
|
39
25
|
spinner.start()
|
|
40
26
|
const pkg = await readJson('./package.json')
|
|
41
|
-
spinner.successAndStop(
|
|
42
|
-
|
|
43
|
-
logger.success(`Package: ${pkg.name}@${pkg.version}`)
|
|
27
|
+
spinner.successAndStop(`Loaded ${pkg.name}@${pkg.version}`)
|
|
44
28
|
```
|
|
45
29
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
- [API Index](./docs/api-index.md) - Every subpath export with a one-line description (start here)
|
|
49
|
-
- [Getting Started](./docs/getting-started.md) - Prerequisites, installation, and first examples
|
|
50
|
-
- [Visual Effects](./docs/visual-effects.md) - Spinners, loggers, themes, and progress indicators
|
|
51
|
-
- [File System](./docs/file-system.md) - File operations, globs, paths, and safe deletion
|
|
52
|
-
- [HTTP Utilities](./docs/http-utilities.md) - Making requests, downloading files, and retry logic
|
|
53
|
-
- [Process Utilities](./docs/process-utilities.md) - Spawning processes, IPC, and locks
|
|
54
|
-
- [Package Management](./docs/package-management.md) - npm/pnpm/yarn detection and operations
|
|
55
|
-
- [Environment](./docs/environment.md) - CI detection, env getters, and platform checks
|
|
56
|
-
- [Constants](./docs/constants.md) - Node versions, npm URLs, and platform values
|
|
57
|
-
- [Examples](./docs/examples.md) - Real-world usage patterns
|
|
58
|
-
- [Troubleshooting](./docs/troubleshooting.md) - Common issues and solutions
|
|
59
|
-
|
|
60
|
-
## What's Inside
|
|
61
|
-
|
|
62
|
-
### Visual Effects
|
|
63
|
-
|
|
64
|
-
Spinners, colored loggers, themes, progress bars, and terminal output formatting.
|
|
65
|
-
|
|
66
|
-
- `Spinner` - Animated CLI spinners with progress tracking
|
|
67
|
-
- `getDefaultLogger()` - Colored console logger with symbols
|
|
68
|
-
- `LOG_SYMBOLS` - Colored terminal symbols (✓, ✗, ⚠, ℹ, →)
|
|
69
|
-
- `setTheme()` - Customize colors across the library
|
|
70
|
-
|
|
71
|
-
### File System
|
|
72
|
-
|
|
73
|
-
Cross-platform file operations with safe deletion and convenient wrappers.
|
|
74
|
-
|
|
75
|
-
- `readFileUtf8()`, `readFileBinary()` - Read files as text or binary
|
|
76
|
-
- `readJson()`, `writeJson()` - Parse and format JSON files
|
|
77
|
-
- `safeDelete()` - Protected deletion with safety checks
|
|
78
|
-
- `findUp()`, `findUpSync()` - Traverse up to find files
|
|
79
|
-
- `safeMkdir()` - Create directories without EEXIST errors
|
|
80
|
-
- `validateFiles()` - Check file readability (useful for Yarn PnP, pnpm)
|
|
81
|
-
|
|
82
|
-
### HTTP Utilities
|
|
83
|
-
|
|
84
|
-
Native Node.js HTTP/HTTPS requests with retry logic and redirects.
|
|
85
|
-
|
|
86
|
-
- `httpJson()` - Fetch and parse JSON from APIs
|
|
87
|
-
- `httpText()` - Fetch text/HTML content
|
|
88
|
-
- `httpDownload()` - Download files with progress callbacks
|
|
89
|
-
- `httpRequest()` - Full control over requests and responses
|
|
90
|
-
- Automatic redirects, exponential backoff retries, timeout support
|
|
91
|
-
|
|
92
|
-
### Process Management
|
|
93
|
-
|
|
94
|
-
Spawn child processes safely with cross-platform support.
|
|
95
|
-
|
|
96
|
-
- `spawn()` - Promise-based process spawning with output capture
|
|
97
|
-
- `spawnSync()` - Synchronous version for blocking operations
|
|
98
|
-
- Array-based arguments prevent command injection
|
|
99
|
-
- Automatic Windows `.cmd`/`.bat` handling
|
|
100
|
-
- `processLock.withLock()` / `processLock.acquire()` / `processLock.release()` - Ensure only one instance runs at a time
|
|
101
|
-
- `writeIpcStub()` / `getIpcStubPath()` - Filesystem-based inter-process data handoff
|
|
102
|
-
|
|
103
|
-
### Environment Detection
|
|
104
|
-
|
|
105
|
-
Type-safe environment variable access and platform detection.
|
|
106
|
-
|
|
107
|
-
- `getCI()` - Detect CI environment
|
|
108
|
-
- `getNodeEnv()` - Get NODE_ENV value
|
|
109
|
-
- `isTest()` - Check if running tests
|
|
110
|
-
- `getHome()` - Home directory (cross-platform, with Windows `USERPROFILE` fallback)
|
|
111
|
-
- Test rewiring with `setEnv()`, `resetEnv()`
|
|
112
|
-
|
|
113
|
-
### Package Management
|
|
114
|
-
|
|
115
|
-
Detect and work with npm, pnpm, and yarn.
|
|
116
|
-
|
|
117
|
-
- `detectPackageManager()` - Identify running package manager from `npm_config_user_agent` / binary path
|
|
118
|
-
- Package manifest operations
|
|
119
|
-
- Lock file management
|
|
120
|
-
|
|
121
|
-
### Constants
|
|
122
|
-
|
|
123
|
-
Pre-defined values for Node.js, npm, and platform detection.
|
|
124
|
-
|
|
125
|
-
- `getNodeMajorVersion()` - Get current Node.js major version
|
|
126
|
-
- `WIN32`, `DARWIN` - Platform booleans (use `!WIN32 && !DARWIN` for Linux)
|
|
127
|
-
- `getAbortSignal()` - Global abort signal
|
|
128
|
-
|
|
129
|
-
### Utilities
|
|
130
|
-
|
|
131
|
-
Helpers for arrays, objects, strings, promises, sorting, and more.
|
|
132
|
-
|
|
133
|
-
- Arrays, objects, strings manipulation
|
|
134
|
-
- Promise utilities and queues
|
|
135
|
-
- Natural sorting
|
|
136
|
-
- Version comparison
|
|
137
|
-
- Error handling with causes
|
|
138
|
-
|
|
139
|
-
## Features
|
|
140
|
-
|
|
141
|
-
- **Tree-shakeable exports** - Import only what you need
|
|
142
|
-
- **Cross-platform** - Works on Windows, macOS, and Linux
|
|
143
|
-
- **TypeScript-first** - Full type safety with .d.ts files
|
|
144
|
-
- **Zero dependencies** (for core HTTP - uses Node.js native modules)
|
|
145
|
-
- **Well-tested** - 6000+ tests across 139+ test files
|
|
146
|
-
- **Security-focused** - Safe defaults, command injection protection
|
|
147
|
-
- **CommonJS output** - Compatible with Node.js tooling
|
|
148
|
-
|
|
149
|
-
## Common Use Cases
|
|
150
|
-
|
|
151
|
-
### Running Shell Commands
|
|
30
|
+
Every export lives under a subpath — pick what you need:
|
|
152
31
|
|
|
153
32
|
```typescript
|
|
154
33
|
import { spawn } from '@socketsecurity/lib/spawn'
|
|
155
|
-
|
|
156
|
-
const result = await spawn('git', ['status'])
|
|
157
|
-
console.log(result.stdout)
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
### Making API Requests
|
|
161
|
-
|
|
162
|
-
```typescript
|
|
163
34
|
import { httpJson } from '@socketsecurity/lib/http-request'
|
|
164
|
-
|
|
165
|
-
const data = await httpJson('https://api.example.com/data')
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
### Visual Feedback
|
|
169
|
-
|
|
170
|
-
```typescript
|
|
171
|
-
import { Spinner } from '@socketsecurity/lib/spinner'
|
|
172
|
-
|
|
173
|
-
const spinner = Spinner({ text: 'Processing...' })
|
|
174
|
-
spinner.start()
|
|
175
|
-
// ... do work ...
|
|
176
|
-
spinner.successAndStop('Complete!')
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
### Safe File Deletion
|
|
180
|
-
|
|
181
|
-
```typescript
|
|
182
35
|
import { safeDelete } from '@socketsecurity/lib/fs'
|
|
183
|
-
|
|
184
|
-
// Protected against deleting parent directories
|
|
185
|
-
await safeDelete('./build')
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
## Troubleshooting
|
|
189
|
-
|
|
190
|
-
**Module not found**: Verify you're importing from the correct path:
|
|
191
|
-
|
|
192
|
-
```typescript
|
|
193
|
-
// Correct
|
|
194
|
-
import { Spinner } from '@socketsecurity/lib/spinner'
|
|
195
|
-
|
|
196
|
-
// Wrong
|
|
197
|
-
import { Spinner } from '@socketsecurity/lib'
|
|
198
36
|
```
|
|
199
37
|
|
|
200
|
-
|
|
38
|
+
## Documentation
|
|
201
39
|
|
|
202
|
-
|
|
203
|
-
node --version
|
|
204
|
-
```
|
|
40
|
+
Start with the [API Index](./docs/api-index.md) — every subpath export with a one-line description.
|
|
205
41
|
|
|
206
|
-
|
|
42
|
+
- [Getting Started](./docs/getting-started.md) – install + first examples
|
|
43
|
+
- [Visual Effects](./docs/visual-effects.md) – spinners, loggers, themes
|
|
44
|
+
- [File System](./docs/file-system.md) – files, globs, paths, safe deletion
|
|
45
|
+
- [HTTP Utilities](./docs/http-utilities.md) – requests, downloads, retries
|
|
46
|
+
- [Process Utilities](./docs/process-utilities.md) – spawn, IPC, locks
|
|
47
|
+
- [Package Management](./docs/package-management.md) – npm/pnpm/yarn detection
|
|
48
|
+
- [Environment](./docs/environment.md) – CI/platform detection, env getters
|
|
49
|
+
- [Constants](./docs/constants.md) – Node versions, npm URLs, platform values
|
|
50
|
+
- [Examples](./docs/examples.md) – real-world patterns
|
|
51
|
+
- [Troubleshooting](./docs/troubleshooting.md) – common issues
|
|
207
52
|
|
|
208
53
|
## Development
|
|
209
54
|
|
|
210
55
|
```bash
|
|
211
|
-
pnpm install
|
|
212
|
-
pnpm build
|
|
213
|
-
pnpm test
|
|
214
|
-
pnpm run cover
|
|
215
|
-
pnpm dev
|
|
216
|
-
pnpm run lint
|
|
217
|
-
pnpm run fix
|
|
56
|
+
pnpm install # install
|
|
57
|
+
pnpm build # build
|
|
58
|
+
pnpm test # run tests
|
|
59
|
+
pnpm run cover # tests with coverage
|
|
60
|
+
pnpm dev # watch mode
|
|
61
|
+
pnpm run lint # check style
|
|
62
|
+
pnpm run fix # auto-fix formatting
|
|
218
63
|
```
|
|
219
64
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
Contributions are welcome! Please read the [CLAUDE.md](./CLAUDE.md) file for development guidelines and coding standards.
|
|
65
|
+
See [CLAUDE.md](./CLAUDE.md) for contributor guidelines.
|
|
223
66
|
|
|
224
67
|
## License
|
|
225
68
|
|
package/dist/archives.js
CHANGED
|
@@ -80,6 +80,16 @@ function validatePathWithinBase(targetPath, baseDir, entryName) {
|
|
|
80
80
|
);
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
|
+
function assertArchiveExists(archivePath) {
|
|
84
|
+
if (!(0, import_node_fs.existsSync)(archivePath)) {
|
|
85
|
+
const err = new Error(
|
|
86
|
+
`ENOENT: no such file or directory, open '${archivePath}'`
|
|
87
|
+
);
|
|
88
|
+
err.code = "ENOENT";
|
|
89
|
+
err.path = archivePath;
|
|
90
|
+
throw err;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
83
93
|
function detectArchiveFormat(filePath) {
|
|
84
94
|
const lower = filePath.toLowerCase();
|
|
85
95
|
if (lower.endsWith(".tar.gz")) {
|
|
@@ -116,6 +126,7 @@ async function extractArchive(archivePath, outputDir, options = {}) {
|
|
|
116
126
|
}
|
|
117
127
|
}
|
|
118
128
|
async function extractTar(archivePath, outputDir, options = {}) {
|
|
129
|
+
assertArchiveExists(archivePath);
|
|
119
130
|
const {
|
|
120
131
|
maxEntries = DEFAULT_MAX_ENTRIES,
|
|
121
132
|
maxFileSize = DEFAULT_MAX_FILE_SIZE,
|
|
@@ -207,6 +218,7 @@ async function extractTar(archivePath, outputDir, options = {}) {
|
|
|
207
218
|
}
|
|
208
219
|
}
|
|
209
220
|
async function extractTarGz(archivePath, outputDir, options = {}) {
|
|
221
|
+
assertArchiveExists(archivePath);
|
|
210
222
|
const {
|
|
211
223
|
maxEntries = DEFAULT_MAX_ENTRIES,
|
|
212
224
|
maxFileSize = DEFAULT_MAX_FILE_SIZE,
|
|
@@ -298,6 +310,7 @@ async function extractTarGz(archivePath, outputDir, options = {}) {
|
|
|
298
310
|
}
|
|
299
311
|
}
|
|
300
312
|
async function extractZip(archivePath, outputDir, options = {}) {
|
|
313
|
+
assertArchiveExists(archivePath);
|
|
301
314
|
const {
|
|
302
315
|
maxEntries = DEFAULT_MAX_ENTRIES,
|
|
303
316
|
maxFileSize = DEFAULT_MAX_FILE_SIZE,
|
package/dist/cacache.js
CHANGED
|
@@ -41,17 +41,14 @@ __export(cacache_exports, {
|
|
|
41
41
|
module.exports = __toCommonJS(cacache_exports);
|
|
42
42
|
var import_cacache = __toESM(require("./external/cacache"));
|
|
43
43
|
var import_socket = require("./paths/socket");
|
|
44
|
-
function
|
|
44
|
+
function createPatternMatcher(pattern) {
|
|
45
45
|
if (!pattern.includes("*")) {
|
|
46
|
-
return key.startsWith(pattern);
|
|
46
|
+
return (key) => key.startsWith(pattern);
|
|
47
47
|
}
|
|
48
|
-
const regex = patternToRegex(pattern);
|
|
49
|
-
return regex.test(key);
|
|
50
|
-
}
|
|
51
|
-
function patternToRegex(pattern) {
|
|
52
48
|
const escaped = pattern.replaceAll(/[.+?^${}()|[\]\\]/g, "\\$&");
|
|
53
49
|
const regexPattern = escaped.replaceAll("*", ".*");
|
|
54
|
-
|
|
50
|
+
const regex = new RegExp(`^${regexPattern}$`);
|
|
51
|
+
return (key) => regex.test(key);
|
|
55
52
|
}
|
|
56
53
|
async function clear(options) {
|
|
57
54
|
const opts = { __proto__: null, ...options };
|
|
@@ -84,9 +81,10 @@ async function clear(options) {
|
|
|
84
81
|
return removed2;
|
|
85
82
|
}
|
|
86
83
|
let removed = 0;
|
|
84
|
+
const matches = createPatternMatcher(opts.prefix);
|
|
87
85
|
const stream = cacache2.ls.stream(cacheDir);
|
|
88
86
|
for await (const entry of stream) {
|
|
89
|
-
if (
|
|
87
|
+
if (matches(entry.key)) {
|
|
90
88
|
try {
|
|
91
89
|
await cacache2.rm.entry(cacheDir, entry.key);
|
|
92
90
|
removed++;
|