@socketsecurity/lib 5.7.0 → 5.8.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 +29 -2
- package/README.md +190 -18
- package/dist/archives.d.ts +58 -0
- package/dist/archives.js +313 -0
- package/dist/arrays.js +2 -3
- package/dist/cache-with-ttl.js +21 -6
- package/dist/constants/node.js +2 -1
- package/dist/cover/formatters.js +5 -3
- package/dist/dlx/package.js +1 -1
- package/dist/external/@npmcli/package-json.js +352 -824
- package/dist/external/adm-zip.js +2695 -0
- package/dist/external/debug.js +183 -7
- package/dist/external/external-pack.js +19 -1409
- package/dist/external/libnpmexec.js +2 -2
- package/dist/external/npm-pack.js +18777 -19997
- package/dist/external/pico-pack.js +29 -5
- package/dist/external/spdx-pack.js +41 -263
- package/dist/external/tar-fs.js +3053 -0
- package/dist/git.js +22 -4
- package/dist/github.js +7 -8
- package/dist/globs.js +20 -1
- package/dist/http-request.js +1 -1
- package/dist/memoization.js +22 -13
- package/dist/package-extensions.js +4 -2
- package/dist/packages/normalize.js +3 -0
- package/dist/process-lock.js +4 -2
- package/dist/releases/github.d.ts +40 -0
- package/dist/releases/github.js +122 -22
- package/dist/spawn.js +1 -1
- package/dist/spinner.js +1 -1
- package/dist/stdio/progress.js +2 -2
- package/package.json +38 -15
package/dist/git.js
CHANGED
|
@@ -56,6 +56,16 @@ function getPath() {
|
|
|
56
56
|
return _path;
|
|
57
57
|
}
|
|
58
58
|
const gitDiffCache = /* @__PURE__ */ new Map();
|
|
59
|
+
const gitDiffAccessOrder = [];
|
|
60
|
+
const GIT_CACHE_MAX_SIZE = 100;
|
|
61
|
+
function evictLRUGitCache() {
|
|
62
|
+
if (gitDiffCache.size >= GIT_CACHE_MAX_SIZE && gitDiffAccessOrder.length > 0) {
|
|
63
|
+
const oldest = gitDiffAccessOrder.shift();
|
|
64
|
+
if (oldest) {
|
|
65
|
+
gitDiffCache.delete(oldest);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
59
69
|
function getGitPath() {
|
|
60
70
|
return "git";
|
|
61
71
|
}
|
|
@@ -114,7 +124,9 @@ async function innerDiff(args, options) {
|
|
|
114
124
|
return [];
|
|
115
125
|
}
|
|
116
126
|
if (cache && cacheKey) {
|
|
127
|
+
evictLRUGitCache();
|
|
117
128
|
gitDiffCache.set(cacheKey, result);
|
|
129
|
+
gitDiffAccessOrder.push(cacheKey);
|
|
118
130
|
}
|
|
119
131
|
return result;
|
|
120
132
|
}
|
|
@@ -144,7 +156,9 @@ function innerDiffSync(args, options) {
|
|
|
144
156
|
return [];
|
|
145
157
|
}
|
|
146
158
|
if (cache && cacheKey) {
|
|
159
|
+
evictLRUGitCache();
|
|
147
160
|
gitDiffCache.set(cacheKey, result);
|
|
161
|
+
gitDiffAccessOrder.push(cacheKey);
|
|
148
162
|
}
|
|
149
163
|
return result;
|
|
150
164
|
}
|
|
@@ -256,10 +270,14 @@ function isChangedSync(pathname, options) {
|
|
|
256
270
|
});
|
|
257
271
|
const fs = /* @__PURE__ */ getFs();
|
|
258
272
|
const path = /* @__PURE__ */ getPath();
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
273
|
+
try {
|
|
274
|
+
const resolvedPathname = fs.realpathSync(pathname);
|
|
275
|
+
const baseCwd = options?.cwd ? fs.realpathSync(options["cwd"]) : getCwd();
|
|
276
|
+
const relativePath = (0, import_normalize.normalizePath)(path.relative(baseCwd, resolvedPathname));
|
|
277
|
+
return files.includes(relativePath);
|
|
278
|
+
} catch {
|
|
279
|
+
return false;
|
|
280
|
+
}
|
|
263
281
|
}
|
|
264
282
|
async function isUnstaged(pathname, options) {
|
|
265
283
|
const files = await getUnstagedFiles({
|
package/dist/github.js
CHANGED
|
@@ -189,15 +189,14 @@ async function fetchGhsaDetails(ghsaId, options) {
|
|
|
189
189
|
async function cacheFetchGhsa(ghsaId, options) {
|
|
190
190
|
const cache = getGithubCache();
|
|
191
191
|
const key = `ghsa:${ghsaId}`;
|
|
192
|
-
if (
|
|
193
|
-
|
|
194
|
-
if (cached) {
|
|
195
|
-
return JSON.parse(cached);
|
|
196
|
-
}
|
|
192
|
+
if (process.env["DISABLE_GITHUB_CACHE"]) {
|
|
193
|
+
return await fetchGhsaDetails(ghsaId, options);
|
|
197
194
|
}
|
|
198
|
-
const
|
|
199
|
-
|
|
200
|
-
|
|
195
|
+
const cached = await cache.getOrFetch(key, async () => {
|
|
196
|
+
const data = await fetchGhsaDetails(ghsaId, options);
|
|
197
|
+
return JSON.stringify(data);
|
|
198
|
+
});
|
|
199
|
+
return JSON.parse(cached);
|
|
201
200
|
}
|
|
202
201
|
// Annotate the CommonJS export names for ESM import in node:
|
|
203
202
|
0 && (module.exports = {
|
package/dist/globs.js
CHANGED
|
@@ -107,15 +107,33 @@ function globStreamLicenses(dirname, options) {
|
|
|
107
107
|
}
|
|
108
108
|
);
|
|
109
109
|
}
|
|
110
|
+
const MATCHER_CACHE_MAX_SIZE = 100;
|
|
110
111
|
const matcherCache = /* @__PURE__ */ new Map();
|
|
112
|
+
const matcherAccessOrder = [];
|
|
113
|
+
function evictLRUMatcher() {
|
|
114
|
+
if (matcherCache.size >= MATCHER_CACHE_MAX_SIZE && matcherAccessOrder.length > 0) {
|
|
115
|
+
const oldest = matcherAccessOrder.shift();
|
|
116
|
+
if (oldest) {
|
|
117
|
+
matcherCache.delete(oldest);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
111
121
|
// @__NO_SIDE_EFFECTS__
|
|
112
122
|
function getGlobMatcher(glob2, options) {
|
|
113
123
|
const patterns = Array.isArray(glob2) ? glob2 : [glob2];
|
|
114
|
-
const
|
|
124
|
+
const sortedPatterns = [...patterns].sort();
|
|
125
|
+
const sortedOptions = options ? Object.keys(options).sort().map((k) => `${k}:${JSON.stringify(options[k])}`).join(",") : "";
|
|
126
|
+
const key = `${sortedPatterns.join("|")}:${sortedOptions}`;
|
|
115
127
|
let matcher = matcherCache.get(key);
|
|
116
128
|
if (matcher) {
|
|
129
|
+
const index = matcherAccessOrder.indexOf(key);
|
|
130
|
+
if (index !== -1) {
|
|
131
|
+
matcherAccessOrder.splice(index, 1);
|
|
132
|
+
matcherAccessOrder.push(key);
|
|
133
|
+
}
|
|
117
134
|
return matcher;
|
|
118
135
|
}
|
|
136
|
+
evictLRUMatcher();
|
|
119
137
|
const positivePatterns = patterns.filter((p) => !p.startsWith("!"));
|
|
120
138
|
const negativePatterns = patterns.filter((p) => p.startsWith("!")).map((p) => p.slice(1));
|
|
121
139
|
const matchOptions = {
|
|
@@ -129,6 +147,7 @@ function getGlobMatcher(glob2, options) {
|
|
|
129
147
|
matchOptions
|
|
130
148
|
);
|
|
131
149
|
matcherCache.set(key, matcher);
|
|
150
|
+
matcherAccessOrder.push(key);
|
|
132
151
|
return matcher;
|
|
133
152
|
}
|
|
134
153
|
// @__NO_SIDE_EFFECTS__
|
package/dist/http-request.js
CHANGED
|
@@ -299,7 +299,7 @@ async function httpDownload(url, destPath, options) {
|
|
|
299
299
|
} else if (logger) {
|
|
300
300
|
let lastPercent = 0;
|
|
301
301
|
progressCallback = (downloaded, total) => {
|
|
302
|
-
const percent = Math.floor(downloaded / total * 100);
|
|
302
|
+
const percent = total === 0 ? 0 : Math.floor(downloaded / total * 100);
|
|
303
303
|
if (percent >= lastPercent + progressInterval) {
|
|
304
304
|
logger.log(
|
|
305
305
|
` Progress: ${percent}% (${(downloaded / 1024 / 1024).toFixed(1)} MB / ${(total / 1024 / 1024).toFixed(1)} MB)`
|
package/dist/memoization.js
CHANGED
|
@@ -36,6 +36,9 @@ function memoize(fn, options = {}) {
|
|
|
36
36
|
name = fn.name || "anonymous",
|
|
37
37
|
ttl = Number.POSITIVE_INFINITY
|
|
38
38
|
} = options;
|
|
39
|
+
if (ttl < 0) {
|
|
40
|
+
throw new TypeError("TTL must be non-negative");
|
|
41
|
+
}
|
|
39
42
|
const cache = /* @__PURE__ */ new Map();
|
|
40
43
|
const accessOrder = [];
|
|
41
44
|
function evictLRU() {
|
|
@@ -123,7 +126,24 @@ function memoizeAsync(fn, options = {}) {
|
|
|
123
126
|
return await cached.value;
|
|
124
127
|
}
|
|
125
128
|
(0, import_debug.debugLog)(`[memoizeAsync:${name}] miss`, { key });
|
|
126
|
-
const promise = fn(...args)
|
|
129
|
+
const promise = fn(...args).then(
|
|
130
|
+
(result) => {
|
|
131
|
+
const entry = cache.get(key);
|
|
132
|
+
if (entry) {
|
|
133
|
+
entry.value = Promise.resolve(result);
|
|
134
|
+
}
|
|
135
|
+
return result;
|
|
136
|
+
},
|
|
137
|
+
(error) => {
|
|
138
|
+
cache.delete(key);
|
|
139
|
+
const index = accessOrder.indexOf(key);
|
|
140
|
+
if (index !== -1) {
|
|
141
|
+
accessOrder.splice(index, 1);
|
|
142
|
+
}
|
|
143
|
+
(0, import_debug.debugLog)(`[memoizeAsync:${name}] error`, { key, error });
|
|
144
|
+
throw error;
|
|
145
|
+
}
|
|
146
|
+
);
|
|
127
147
|
evictLRU();
|
|
128
148
|
cache.set(key, {
|
|
129
149
|
value: promise,
|
|
@@ -132,18 +152,7 @@ function memoizeAsync(fn, options = {}) {
|
|
|
132
152
|
});
|
|
133
153
|
accessOrder.push(key);
|
|
134
154
|
(0, import_debug.debugLog)(`[memoizeAsync:${name}] set`, { key, cacheSize: cache.size });
|
|
135
|
-
|
|
136
|
-
const result = await promise;
|
|
137
|
-
return result;
|
|
138
|
-
} catch (e) {
|
|
139
|
-
cache.delete(key);
|
|
140
|
-
const orderIndex = accessOrder.indexOf(key);
|
|
141
|
-
if (orderIndex !== -1) {
|
|
142
|
-
accessOrder.splice(orderIndex, 1);
|
|
143
|
-
}
|
|
144
|
-
(0, import_debug.debugLog)(`[memoizeAsync:${name}] clear`, { key, reason: "error" });
|
|
145
|
-
throw e;
|
|
146
|
-
}
|
|
155
|
+
return await promise;
|
|
147
156
|
};
|
|
148
157
|
}
|
|
149
158
|
function Memoize(options = {}) {
|
|
@@ -64,8 +64,10 @@ const packageExtensions = ObjectFreeze(
|
|
|
64
64
|
}
|
|
65
65
|
]
|
|
66
66
|
].sort((a_, b_) => {
|
|
67
|
-
const
|
|
68
|
-
const
|
|
67
|
+
const aIndex = a_[0].lastIndexOf("@");
|
|
68
|
+
const bIndex = b_[0].lastIndexOf("@");
|
|
69
|
+
const a = aIndex === -1 ? a_[0] : a_[0].slice(0, aIndex);
|
|
70
|
+
const b = bIndex === -1 ? b_[0] : b_[0].slice(0, bIndex);
|
|
69
71
|
if (a < b) {
|
|
70
72
|
return -1;
|
|
71
73
|
}
|
|
@@ -91,6 +91,9 @@ function resolveOriginalPackageName(sockRegPkgName) {
|
|
|
91
91
|
}
|
|
92
92
|
// @__NO_SIDE_EFFECTS__
|
|
93
93
|
function unescapeScope(escapedScope) {
|
|
94
|
+
if (escapedScope.length < import_socket.REGISTRY_SCOPE_DELIMITER.length) {
|
|
95
|
+
return `@${escapedScope}`;
|
|
96
|
+
}
|
|
94
97
|
return `@${escapedScope.slice(0, -import_socket.REGISTRY_SCOPE_DELIMITER.length)}`;
|
|
95
98
|
}
|
|
96
99
|
// Annotate the CommonJS export names for ESM import in node:
|
package/dist/process-lock.js
CHANGED
|
@@ -204,7 +204,8 @@ class ProcessLockManager {
|
|
|
204
204
|
);
|
|
205
205
|
}
|
|
206
206
|
if (code === "ENOTDIR") {
|
|
207
|
-
const
|
|
207
|
+
const lastSlashIndex = lockPath.lastIndexOf("/");
|
|
208
|
+
const parentDir = lastSlashIndex === -1 ? "." : lockPath.slice(0, lastSlashIndex);
|
|
208
209
|
throw new Error(
|
|
209
210
|
`Cannot create lock directory: ${lockPath}
|
|
210
211
|
A path component is a file when it should be a directory.
|
|
@@ -217,7 +218,8 @@ To resolve:
|
|
|
217
218
|
);
|
|
218
219
|
}
|
|
219
220
|
if (code === "ENOENT") {
|
|
220
|
-
const
|
|
221
|
+
const lastSlashIndex = lockPath.lastIndexOf("/");
|
|
222
|
+
const parentDir = lastSlashIndex === -1 ? "." : lockPath.slice(0, lastSlashIndex);
|
|
221
223
|
throw new Error(
|
|
222
224
|
`Cannot create lock directory: ${lockPath}
|
|
223
225
|
Parent directory does not exist: ${parentDir}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type ArchiveFormat } from '../archives.js';
|
|
1
2
|
/**
|
|
2
3
|
* Pattern for matching release assets.
|
|
3
4
|
* Can be either:
|
|
@@ -133,3 +134,42 @@ export declare function getLatestRelease(toolPrefix: string, repoConfig: RepoCon
|
|
|
133
134
|
export declare function getReleaseAssetUrl(tag: string, assetPattern: string | AssetPattern, repoConfig: RepoConfig, options?: {
|
|
134
135
|
quiet?: boolean;
|
|
135
136
|
}): Promise<string | null>;
|
|
137
|
+
/**
|
|
138
|
+
* Download and extract a zip file from a GitHub release.
|
|
139
|
+
* Automatically handles downloading, extracting, and cleanup.
|
|
140
|
+
*
|
|
141
|
+
* @param tag - Release tag name
|
|
142
|
+
* @param assetPattern - Asset name or pattern (glob string, prefix/suffix object, or RegExp)
|
|
143
|
+
* @param outputDir - Directory to extract the zip contents to
|
|
144
|
+
* @param repoConfig - Repository configuration (owner/repo)
|
|
145
|
+
* @param options - Additional options
|
|
146
|
+
* @param options.quiet - Suppress log messages
|
|
147
|
+
* @param options.cleanup - Remove downloaded zip file after extraction (default: true)
|
|
148
|
+
* @returns Path to the extraction directory
|
|
149
|
+
*/
|
|
150
|
+
export declare function downloadAndExtractZip(tag: string, assetPattern: string | AssetPattern, outputDir: string, repoConfig: RepoConfig, options?: {
|
|
151
|
+
cleanup?: boolean;
|
|
152
|
+
quiet?: boolean;
|
|
153
|
+
}): Promise<string>;
|
|
154
|
+
/**
|
|
155
|
+
* Download and extract an archive from a GitHub release.
|
|
156
|
+
* Supports zip, tar, tar.gz, and tgz formats.
|
|
157
|
+
* Automatically handles downloading, extracting, and cleanup.
|
|
158
|
+
*
|
|
159
|
+
* @param tag - Release tag name
|
|
160
|
+
* @param assetPattern - Asset name or pattern (glob string, prefix/suffix object, or RegExp)
|
|
161
|
+
* @param outputDir - Directory to extract the archive contents to
|
|
162
|
+
* @param repoConfig - Repository configuration (owner/repo)
|
|
163
|
+
* @param options - Additional options
|
|
164
|
+
* @param options.quiet - Suppress log messages
|
|
165
|
+
* @param options.cleanup - Remove downloaded archive after extraction (default: true)
|
|
166
|
+
* @param options.strip - Strip leading path components (like tar --strip-components)
|
|
167
|
+
* @param options.format - Archive format (auto-detected if not specified)
|
|
168
|
+
* @returns Path to the extraction directory
|
|
169
|
+
*/
|
|
170
|
+
export declare function downloadAndExtractArchive(tag: string, assetPattern: string | AssetPattern, outputDir: string, repoConfig: RepoConfig, options?: {
|
|
171
|
+
cleanup?: boolean;
|
|
172
|
+
format?: ArchiveFormat;
|
|
173
|
+
quiet?: boolean;
|
|
174
|
+
strip?: number;
|
|
175
|
+
}): Promise<string>;
|
package/dist/releases/github.js
CHANGED
|
@@ -31,6 +31,8 @@ var github_exports = {};
|
|
|
31
31
|
__export(github_exports, {
|
|
32
32
|
SOCKET_BTM_REPO: () => SOCKET_BTM_REPO,
|
|
33
33
|
createAssetMatcher: () => createAssetMatcher,
|
|
34
|
+
downloadAndExtractArchive: () => downloadAndExtractArchive,
|
|
35
|
+
downloadAndExtractZip: () => downloadAndExtractZip,
|
|
34
36
|
downloadGitHubRelease: () => downloadGitHubRelease,
|
|
35
37
|
downloadReleaseAsset: () => downloadReleaseAsset,
|
|
36
38
|
getAuthHeaders: () => getAuthHeaders,
|
|
@@ -39,6 +41,7 @@ __export(github_exports, {
|
|
|
39
41
|
});
|
|
40
42
|
module.exports = __toCommonJS(github_exports);
|
|
41
43
|
var import_picomatch = __toESM(require("../external/picomatch.js"));
|
|
44
|
+
var import_archives = require("../archives.js");
|
|
42
45
|
var import_fs = require("../fs.js");
|
|
43
46
|
var import_http_request = require("../http-request.js");
|
|
44
47
|
var import_logger = require("../logger.js");
|
|
@@ -207,27 +210,33 @@ async function getLatestRelease(toolPrefix, repoConfig, options = {}) {
|
|
|
207
210
|
if (!response.ok) {
|
|
208
211
|
throw new Error(`Failed to fetch releases: ${response.status}`);
|
|
209
212
|
}
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
(
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
}
|
|
217
|
-
|
|
213
|
+
let releases;
|
|
214
|
+
try {
|
|
215
|
+
releases = JSON.parse(response.body.toString("utf8"));
|
|
216
|
+
} catch (cause) {
|
|
217
|
+
throw new Error(
|
|
218
|
+
`Failed to parse GitHub releases response from https://api.github.com/repos/${owner}/${repo}/releases`,
|
|
219
|
+
{ cause }
|
|
220
|
+
);
|
|
221
|
+
}
|
|
222
|
+
const matchingReleases = releases.filter((release) => {
|
|
223
|
+
const { assets, tag_name: tag2 } = release;
|
|
224
|
+
if (!tag2.startsWith(toolPrefix)) {
|
|
225
|
+
return false;
|
|
226
|
+
}
|
|
227
|
+
if (!assets || assets.length === 0) {
|
|
228
|
+
return false;
|
|
229
|
+
}
|
|
230
|
+
if (isMatch) {
|
|
231
|
+
const hasMatchingAsset = assets.some(
|
|
232
|
+
(a) => isMatch(a.name)
|
|
233
|
+
);
|
|
234
|
+
if (!hasMatchingAsset) {
|
|
218
235
|
return false;
|
|
219
236
|
}
|
|
220
|
-
if (isMatch) {
|
|
221
|
-
const hasMatchingAsset = assets.some(
|
|
222
|
-
(a) => isMatch(a.name)
|
|
223
|
-
);
|
|
224
|
-
if (!hasMatchingAsset) {
|
|
225
|
-
return false;
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
return true;
|
|
229
237
|
}
|
|
230
|
-
|
|
238
|
+
return true;
|
|
239
|
+
});
|
|
231
240
|
if (matchingReleases.length === 0) {
|
|
232
241
|
if (!quiet) {
|
|
233
242
|
logger.info(`No ${toolPrefix} release found in latest 100 releases`);
|
|
@@ -275,10 +284,16 @@ async function getReleaseAssetUrl(tag, assetPattern, repoConfig, options = {}) {
|
|
|
275
284
|
if (!response.ok) {
|
|
276
285
|
throw new Error(`Failed to fetch release ${tag}: ${response.status}`);
|
|
277
286
|
}
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
)
|
|
287
|
+
let release;
|
|
288
|
+
try {
|
|
289
|
+
release = JSON.parse(response.body.toString("utf8"));
|
|
290
|
+
} catch (cause) {
|
|
291
|
+
throw new Error(
|
|
292
|
+
`Failed to parse GitHub release response for tag ${tag}`,
|
|
293
|
+
{ cause }
|
|
294
|
+
);
|
|
295
|
+
}
|
|
296
|
+
const asset = release.assets.find((a) => isMatch(a.name));
|
|
282
297
|
if (!asset) {
|
|
283
298
|
const patternDesc = typeof assetPattern === "string" ? assetPattern : "matching pattern";
|
|
284
299
|
throw new Error(`Asset ${patternDesc} not found in release ${tag}`);
|
|
@@ -304,10 +319,95 @@ async function getReleaseAssetUrl(tag, assetPattern, repoConfig, options = {}) {
|
|
|
304
319
|
}
|
|
305
320
|
);
|
|
306
321
|
}
|
|
322
|
+
async function downloadAndExtractZip(tag, assetPattern, outputDir, repoConfig, options = {}) {
|
|
323
|
+
const { cleanup = true, quiet = false } = options;
|
|
324
|
+
const path = /* @__PURE__ */ getPath();
|
|
325
|
+
const fs = /* @__PURE__ */ getFs();
|
|
326
|
+
await (0, import_fs.safeMkdir)(outputDir);
|
|
327
|
+
const zipPath = path.join(outputDir, "__temp_download__.zip");
|
|
328
|
+
if (!quiet) {
|
|
329
|
+
logger.info(`Downloading zip asset from release ${tag}...`);
|
|
330
|
+
}
|
|
331
|
+
await downloadReleaseAsset(tag, assetPattern, zipPath, repoConfig, { quiet });
|
|
332
|
+
if (!quiet) {
|
|
333
|
+
logger.info(`Extracting zip to ${outputDir}...`);
|
|
334
|
+
}
|
|
335
|
+
try {
|
|
336
|
+
await (0, import_archives.extractArchive)(zipPath, outputDir, { quiet });
|
|
337
|
+
if (!quiet) {
|
|
338
|
+
logger.info(`Extracted zip contents to ${outputDir}`);
|
|
339
|
+
}
|
|
340
|
+
} catch (cause) {
|
|
341
|
+
throw new Error(`Failed to extract zip file: ${zipPath}`, { cause });
|
|
342
|
+
} finally {
|
|
343
|
+
if (cleanup) {
|
|
344
|
+
try {
|
|
345
|
+
await fs.promises.unlink(zipPath);
|
|
346
|
+
if (!quiet) {
|
|
347
|
+
logger.info("Cleaned up temporary zip file");
|
|
348
|
+
}
|
|
349
|
+
} catch (error) {
|
|
350
|
+
if (!quiet) {
|
|
351
|
+
logger.warn(`Failed to cleanup zip file: ${error}`);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
return outputDir;
|
|
357
|
+
}
|
|
358
|
+
async function downloadAndExtractArchive(tag, assetPattern, outputDir, repoConfig, options = {}) {
|
|
359
|
+
const { cleanup = true, format, quiet = false, strip } = options;
|
|
360
|
+
const path = /* @__PURE__ */ getPath();
|
|
361
|
+
const fs = /* @__PURE__ */ getFs();
|
|
362
|
+
await (0, import_fs.safeMkdir)(outputDir);
|
|
363
|
+
let ext = ".archive";
|
|
364
|
+
if (format) {
|
|
365
|
+
ext = format === "tar.gz" ? ".tar.gz" : `.${format}`;
|
|
366
|
+
} else if (typeof assetPattern === "string") {
|
|
367
|
+
const detectedFormat = (0, import_archives.detectArchiveFormat)(assetPattern);
|
|
368
|
+
if (detectedFormat) {
|
|
369
|
+
ext = detectedFormat === "tar.gz" ? ".tar.gz" : `.${detectedFormat}`;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
const archivePath = path.join(outputDir, `__temp_download__${ext}`);
|
|
373
|
+
if (!quiet) {
|
|
374
|
+
logger.info(`Downloading archive from release ${tag}...`);
|
|
375
|
+
}
|
|
376
|
+
await downloadReleaseAsset(tag, assetPattern, archivePath, repoConfig, {
|
|
377
|
+
quiet
|
|
378
|
+
});
|
|
379
|
+
if (!quiet) {
|
|
380
|
+
logger.info(`Extracting archive to ${outputDir}...`);
|
|
381
|
+
}
|
|
382
|
+
try {
|
|
383
|
+
await (0, import_archives.extractArchive)(archivePath, outputDir, { quiet, strip });
|
|
384
|
+
if (!quiet) {
|
|
385
|
+
logger.info(`Extracted archive contents to ${outputDir}`);
|
|
386
|
+
}
|
|
387
|
+
} catch (cause) {
|
|
388
|
+
throw new Error(`Failed to extract archive: ${archivePath}`, { cause });
|
|
389
|
+
} finally {
|
|
390
|
+
if (cleanup) {
|
|
391
|
+
try {
|
|
392
|
+
await fs.promises.unlink(archivePath);
|
|
393
|
+
if (!quiet) {
|
|
394
|
+
logger.info("Cleaned up temporary archive file");
|
|
395
|
+
}
|
|
396
|
+
} catch (error) {
|
|
397
|
+
if (!quiet) {
|
|
398
|
+
logger.warn(`Failed to cleanup archive file: ${error}`);
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
return outputDir;
|
|
404
|
+
}
|
|
307
405
|
// Annotate the CommonJS export names for ESM import in node:
|
|
308
406
|
0 && (module.exports = {
|
|
309
407
|
SOCKET_BTM_REPO,
|
|
310
408
|
createAssetMatcher,
|
|
409
|
+
downloadAndExtractArchive,
|
|
410
|
+
downloadAndExtractZip,
|
|
311
411
|
downloadGitHubRelease,
|
|
312
412
|
downloadReleaseAsset,
|
|
313
413
|
getAuthHeaders,
|
package/dist/spawn.js
CHANGED
|
@@ -92,7 +92,7 @@ function enhanceSpawnError(error) {
|
|
|
92
92
|
}
|
|
93
93
|
const trimmedStderr = stderrText.trim();
|
|
94
94
|
if (trimmedStderr) {
|
|
95
|
-
const firstLine = trimmedStderr.split("\n")[0];
|
|
95
|
+
const firstLine = trimmedStderr.split("\n")[0] ?? "";
|
|
96
96
|
if (firstLine.length < 200) {
|
|
97
97
|
enhancedMessage += `
|
|
98
98
|
${firstLine}`;
|
package/dist/spinner.js
CHANGED
|
@@ -66,7 +66,7 @@ function desc(value) {
|
|
|
66
66
|
}
|
|
67
67
|
function formatProgress(progress) {
|
|
68
68
|
const { current, total, unit } = progress;
|
|
69
|
-
const percentage = Math.round(current / total * 100);
|
|
69
|
+
const percentage = total === 0 ? 0 : Math.round(current / total * 100);
|
|
70
70
|
const bar = renderProgressBar(percentage);
|
|
71
71
|
const count = unit ? `${current}/${total} ${unit}` : `${current}/${total}`;
|
|
72
72
|
return `${bar} ${percentage}% (${count})`;
|
package/dist/stdio/progress.js
CHANGED
|
@@ -128,11 +128,11 @@ class ProgressBar {
|
|
|
128
128
|
*/
|
|
129
129
|
render(tokens) {
|
|
130
130
|
const colorFn = import_yoctocolors_cjs.default[this.options.color] || ((s) => s);
|
|
131
|
-
const percent = Math.floor(this.current / this.total * 100);
|
|
131
|
+
const percent = this.total === 0 ? 0 : Math.floor(this.current / this.total * 100);
|
|
132
132
|
const elapsed = Date.now() - this.startTime;
|
|
133
133
|
const eta = this.current === 0 ? 0 : elapsed / this.current * (this.total - this.current);
|
|
134
134
|
const availableWidth = this.options.width;
|
|
135
|
-
const filledWidth = Math.floor(this.current / this.total * availableWidth);
|
|
135
|
+
const filledWidth = this.total === 0 ? 0 : Math.floor(this.current / this.total * availableWidth);
|
|
136
136
|
const emptyWidth = availableWidth - filledWidth;
|
|
137
137
|
const filled = (0, import_strings.repeatString)(this.options.complete, filledWidth);
|
|
138
138
|
const empty = (0, import_strings.repeatString)(this.options.incomplete, emptyWidth);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@socketsecurity/lib",
|
|
3
|
-
"version": "5.
|
|
4
|
-
"packageManager": "pnpm@10.
|
|
3
|
+
"version": "5.8.0",
|
|
4
|
+
"packageManager": "pnpm@10.32.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "Core utilities and infrastructure for Socket.dev security tools",
|
|
7
7
|
"keywords": [
|
|
@@ -103,6 +103,10 @@
|
|
|
103
103
|
"types": "./dist/ansi.d.ts",
|
|
104
104
|
"default": "./dist/ansi.js"
|
|
105
105
|
},
|
|
106
|
+
"./archives": {
|
|
107
|
+
"types": "./dist/archives.d.ts",
|
|
108
|
+
"default": "./dist/archives.js"
|
|
109
|
+
},
|
|
106
110
|
"./argv/flags": {
|
|
107
111
|
"types": "./dist/argv/flags.d.ts",
|
|
108
112
|
"default": "./dist/argv/flags.js"
|
|
@@ -679,7 +683,6 @@
|
|
|
679
683
|
"types": "./dist/zod.d.ts",
|
|
680
684
|
"default": "./dist/zod.js"
|
|
681
685
|
},
|
|
682
|
-
"./biome.json": "./biome.json",
|
|
683
686
|
"./data/extensions.json": "./data/extensions.json",
|
|
684
687
|
"./package.json": "./package.json",
|
|
685
688
|
"./tsconfig.dts.json": "./tsconfig.dts.json",
|
|
@@ -703,7 +706,11 @@
|
|
|
703
706
|
"cover": "node scripts/test/cover.mjs",
|
|
704
707
|
"dev": "node scripts/build/main.mjs --watch",
|
|
705
708
|
"fix": "node scripts/lint.mjs --fix",
|
|
709
|
+
"format": "oxfmt",
|
|
710
|
+
"format:check": "oxfmt --check",
|
|
706
711
|
"lint": "node scripts/lint.mjs",
|
|
712
|
+
"lint:oxlint": "oxlint .",
|
|
713
|
+
"lint:oxfmt": "oxfmt --check .",
|
|
707
714
|
"prepare": "husky",
|
|
708
715
|
"prepublishOnly": "pnpm run build",
|
|
709
716
|
"test": "node scripts/test/main.mjs",
|
|
@@ -714,10 +721,7 @@
|
|
|
714
721
|
"@babel/parser": "7.28.4",
|
|
715
722
|
"@babel/traverse": "7.28.4",
|
|
716
723
|
"@babel/types": "7.28.4",
|
|
717
|
-
"@biomejs/biome": "2.2.4",
|
|
718
724
|
"@dotenvx/dotenvx": "1.49.0",
|
|
719
|
-
"@eslint/compat": "1.4.0",
|
|
720
|
-
"@eslint/js": "9.38.0",
|
|
721
725
|
"@inquirer/checkbox": "4.3.1",
|
|
722
726
|
"@inquirer/confirm": "5.1.16",
|
|
723
727
|
"@inquirer/input": "4.2.2",
|
|
@@ -730,31 +734,27 @@
|
|
|
730
734
|
"@socketregistry/is-unicode-supported": "1.0.5",
|
|
731
735
|
"@socketregistry/packageurl-js": "1.3.5",
|
|
732
736
|
"@socketregistry/yocto-spinner": "1.0.25",
|
|
733
|
-
"@socketsecurity/lib-stable": "npm:@socketsecurity/lib@5.
|
|
737
|
+
"@socketsecurity/lib-stable": "npm:@socketsecurity/lib@5.7.0",
|
|
734
738
|
"@types/node": "24.9.2",
|
|
735
739
|
"@typescript/native-preview": "7.0.0-dev.20250920.1",
|
|
736
740
|
"@vitest/coverage-v8": "4.0.3",
|
|
737
741
|
"@vitest/ui": "4.0.3",
|
|
738
742
|
"@yarnpkg/core": "4.5.0",
|
|
739
743
|
"@yarnpkg/extensions": "2.0.6",
|
|
744
|
+
"adm-zip": "0.5.16",
|
|
740
745
|
"cacache": "20.0.1",
|
|
741
746
|
"debug": "4.4.3",
|
|
742
747
|
"del": "8.0.1",
|
|
743
748
|
"del-cli": "6.0.0",
|
|
744
749
|
"esbuild": "0.25.11",
|
|
745
|
-
"eslint": "9.35.0",
|
|
746
|
-
"eslint-import-resolver-typescript": "4.4.4",
|
|
747
|
-
"eslint-plugin-import-x": "4.16.1",
|
|
748
|
-
"eslint-plugin-n": "17.23.1",
|
|
749
750
|
"eslint-plugin-sort-destructure-keys": "2.0.0",
|
|
750
|
-
"eslint-plugin-unicorn": "61.0.2",
|
|
751
751
|
"fast-glob": "3.3.3",
|
|
752
752
|
"fast-sort": "3.4.1",
|
|
753
753
|
"get-east-asian-width": "1.3.0",
|
|
754
754
|
"globals": "16.4.0",
|
|
755
755
|
"has-flag": "5.0.1",
|
|
756
756
|
"husky": "9.1.7",
|
|
757
|
-
"libnpmexec": "
|
|
757
|
+
"libnpmexec": "10.2.3",
|
|
758
758
|
"libnpmpack": "9.0.9",
|
|
759
759
|
"lint-staged": "15.2.11",
|
|
760
760
|
"magic-string": "0.30.17",
|
|
@@ -762,6 +762,8 @@
|
|
|
762
762
|
"nock": "14.0.10",
|
|
763
763
|
"normalize-package-data": "8.0.0",
|
|
764
764
|
"npm-package-arg": "13.0.0",
|
|
765
|
+
"oxfmt": "^0.37.0",
|
|
766
|
+
"oxlint": "^1.52.0",
|
|
765
767
|
"pacote": "21.0.1",
|
|
766
768
|
"picomatch": "2.3.1",
|
|
767
769
|
"pony-cause": "2.1.11",
|
|
@@ -771,11 +773,12 @@
|
|
|
771
773
|
"spdx-expression-parse": "4.0.0",
|
|
772
774
|
"streaming-iterables": "8.0.1",
|
|
773
775
|
"supports-color": "10.0.0",
|
|
776
|
+
"tar-fs": "3.1.2",
|
|
777
|
+
"tar-stream": "3.1.8",
|
|
774
778
|
"taze": "19.9.2",
|
|
775
779
|
"trash": "10.0.0",
|
|
776
780
|
"type-coverage": "2.29.7",
|
|
777
781
|
"typescript": "5.9.2",
|
|
778
|
-
"typescript-eslint": "8.44.1",
|
|
779
782
|
"validate-npm-package-name": "6.0.2",
|
|
780
783
|
"vite-tsconfig-paths": "5.1.4",
|
|
781
784
|
"vitest": "4.0.3",
|
|
@@ -794,23 +797,40 @@
|
|
|
794
797
|
},
|
|
795
798
|
"pnpm": {
|
|
796
799
|
"overrides": {
|
|
800
|
+
"@inquirer/ansi": "1.0.2",
|
|
801
|
+
"@inquirer/core": "10.3.1",
|
|
802
|
+
"@inquirer/figures": "1.0.15",
|
|
797
803
|
"@npmcli/arborist": "9.1.6",
|
|
804
|
+
"@npmcli/git": "6.0.3",
|
|
798
805
|
"@npmcli/run-script": "10.0.0",
|
|
799
806
|
"@sigstore/core": "3.1.0",
|
|
800
807
|
"@sigstore/sign": "4.1.0",
|
|
801
808
|
"ansi-regex": "6.2.2",
|
|
809
|
+
"chownr": "3.0.0",
|
|
802
810
|
"debug": "4.4.3",
|
|
803
811
|
"execa": "5.1.1",
|
|
804
812
|
"has-flag": "5.0.1",
|
|
813
|
+
"hosted-git-info": "8.1.0",
|
|
805
814
|
"isexe": "3.1.1",
|
|
806
815
|
"lru-cache": "11.2.2",
|
|
816
|
+
"minimatch": "9.0.5",
|
|
817
|
+
"minipass": "7.1.3",
|
|
818
|
+
"minipass@7": "7.1.3",
|
|
819
|
+
"minipass-fetch": "4.0.1",
|
|
820
|
+
"minipass-sized": "1.0.3",
|
|
821
|
+
"minizlib": "3.1.0",
|
|
822
|
+
"npm-package-arg": "12.0.2",
|
|
823
|
+
"npm-pick-manifest": "10.0.0",
|
|
807
824
|
"picomatch": "4.0.3",
|
|
808
825
|
"proc-log": "6.1.0",
|
|
809
826
|
"semver": "7.7.2",
|
|
810
827
|
"signal-exit": "4.1.0",
|
|
828
|
+
"spdx-expression-parse": "4.0.0",
|
|
829
|
+
"ssri": "12.0.0",
|
|
811
830
|
"string-width": "8.1.0",
|
|
812
831
|
"strip-ansi": "7.1.2",
|
|
813
832
|
"supports-color": "10.0.0",
|
|
833
|
+
"tar": "7.5.11",
|
|
814
834
|
"which": "5.0.0",
|
|
815
835
|
"wrap-ansi": "9.0.2",
|
|
816
836
|
"yoctocolors-cjs": "2.1.3"
|
|
@@ -819,7 +839,10 @@
|
|
|
819
839
|
"@npmcli/run-script@10.0.0": "patches/@npmcli__run-script@10.0.0.patch",
|
|
820
840
|
"@sigstore/sign@4.1.0": "patches/@sigstore__sign@4.1.0.patch",
|
|
821
841
|
"execa@5.1.1": "patches/execa@5.1.1.patch",
|
|
822
|
-
"
|
|
842
|
+
"minipass-flush@1.0.5": "patches/minipass-flush@1.0.5.patch",
|
|
843
|
+
"minipass-pipeline@1.2.4": "patches/minipass-pipeline@1.2.4.patch",
|
|
844
|
+
"node-gyp@11.5.0": "patches/node-gyp@11.5.0.patch",
|
|
845
|
+
"minipass-sized@1.0.3": "patches/minipass-sized@1.0.3.patch"
|
|
823
846
|
}
|
|
824
847
|
}
|
|
825
848
|
}
|