@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/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
- const resolvedPathname = fs.realpathSync(pathname);
260
- const baseCwd = options?.cwd ? fs.realpathSync(options["cwd"]) : getCwd();
261
- const relativePath = (0, import_normalize.normalizePath)(path.relative(baseCwd, resolvedPathname));
262
- return files.includes(relativePath);
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 (!process.env["DISABLE_GITHUB_CACHE"]) {
193
- const cached = await cache.get(key);
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 data = await fetchGhsaDetails(ghsaId, options);
199
- await cache.set(key, JSON.stringify(data));
200
- return data;
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 key = JSON.stringify({ patterns, options });
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__
@@ -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)`
@@ -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
- try {
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 a = a_[0].slice(0, a_[0].lastIndexOf("@"));
68
- const b = b_[0].slice(0, b_[0].lastIndexOf("@"));
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:
@@ -204,7 +204,8 @@ class ProcessLockManager {
204
204
  );
205
205
  }
206
206
  if (code === "ENOTDIR") {
207
- const parentDir = lockPath.slice(0, lockPath.lastIndexOf("/"));
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 parentDir = lockPath.slice(0, lockPath.lastIndexOf("/"));
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>;
@@ -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
- const releases = JSON.parse(response.body.toString("utf8"));
211
- const matchingReleases = releases.filter(
212
- (release) => {
213
- const { assets, tag_name: tag2 } = release;
214
- if (!tag2.startsWith(toolPrefix)) {
215
- return false;
216
- }
217
- if (!assets || assets.length === 0) {
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
- const release = JSON.parse(response.body.toString("utf8"));
279
- const asset = release.assets.find(
280
- (a) => isMatch(a.name)
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})`;
@@ -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.7.0",
4
- "packageManager": "pnpm@10.29.1",
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.5.3",
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": "^10.2.0",
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
- "node-gyp@11.5.0": "patches/node-gyp@11.5.0.patch"
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
  }