@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.
Files changed (52) hide show
  1. package/CHANGELOG.md +116 -95
  2. package/README.md +24 -181
  3. package/dist/archives.js +13 -0
  4. package/dist/cacache.js +6 -8
  5. package/dist/cache-with-ttl.js +1 -1
  6. package/dist/constants/socket.js +1 -1
  7. package/dist/dlx/detect.js +25 -8
  8. package/dist/dlx/manifest.js +8 -19
  9. package/dist/dlx/package.js +16 -2
  10. package/dist/env/socket-cli.d.ts +4 -3
  11. package/dist/env/socket-cli.js +1 -1
  12. package/dist/errors.d.ts +96 -2
  13. package/dist/errors.js +55 -0
  14. package/dist/external/pony-cause.js +12 -11
  15. package/dist/fs.js +8 -2
  16. package/dist/github.js +3 -2
  17. package/dist/globs.js +5 -1
  18. package/dist/ipc.js +2 -2
  19. package/dist/json/edit.js +3 -2
  20. package/dist/json/parse.d.ts +47 -2
  21. package/dist/json/parse.js +40 -2
  22. package/dist/json/types.d.ts +49 -0
  23. package/dist/memoization.d.ts +4 -23
  24. package/dist/memoization.js +14 -54
  25. package/dist/packages/isolation.js +4 -4
  26. package/dist/packages/specs.js +9 -2
  27. package/dist/performance.js +3 -2
  28. package/dist/process-lock.js +4 -12
  29. package/dist/promise-queue.d.ts +9 -4
  30. package/dist/promise-queue.js +9 -7
  31. package/dist/promises.d.ts +41 -0
  32. package/dist/promises.js +19 -2
  33. package/dist/regexps.d.ts +4 -13
  34. package/dist/regexps.js +60 -3
  35. package/dist/releases/github.js +3 -2
  36. package/dist/releases/socket-btm.d.ts +61 -5
  37. package/dist/releases/socket-btm.js +2 -2
  38. package/dist/schema/parse.d.ts +26 -0
  39. package/dist/schema/parse.js +38 -0
  40. package/dist/schema/types.d.ts +121 -0
  41. package/dist/schema/validate.d.ts +35 -0
  42. package/dist/{validation/validate-schema.js → schema/validate.js} +4 -14
  43. package/dist/suppress-warnings.js +0 -2
  44. package/dist/url.js +5 -1
  45. package/dist/versions.js +2 -2
  46. package/dist/words.js +4 -7
  47. package/package.json +15 -15
  48. package/dist/validation/json-parser.d.ts +0 -58
  49. package/dist/validation/json-parser.js +0 -63
  50. package/dist/validation/types.d.ts +0 -118
  51. package/dist/validation/validate-schema.d.ts +0 -124
  52. /package/dist/{validation → schema}/types.js +0 -0
package/dist/regexps.js CHANGED
@@ -23,10 +23,67 @@ __export(regexps_exports, {
23
23
  escapeRegExp: () => escapeRegExp
24
24
  });
25
25
  module.exports = __toCommonJS(regexps_exports);
26
- // @__NO_SIDE_EFFECTS__
27
- function escapeRegExp(str) {
28
- return str.replace(/[\\|{}()[\]^$+*?.]/g, "\\$&");
26
+ const SYNTAX_CHARACTERS = new Set("^$\\.*+?()[]{}|/");
27
+ const CONTROL_ESCAPES = /* @__PURE__ */ new Map([
28
+ [9, "\\t"],
29
+ [10, "\\n"],
30
+ [11, "\\v"],
31
+ [12, "\\f"],
32
+ [13, "\\r"]
33
+ ]);
34
+ const OTHER_PUNCTUATORS = new Set(",-=<>#&!%:;@~'`\"");
35
+ function isSpecHexEscapeCp(cp) {
36
+ if (OTHER_PUNCTUATORS.has(String.fromCodePoint(cp))) {
37
+ return true;
38
+ }
39
+ if (cp === 10 || cp === 13 || cp === 8232 || cp === 8233) {
40
+ return true;
41
+ }
42
+ if (cp === 9 || cp === 11 || cp === 12 || cp === 32 || cp === 160 || cp === 65279) {
43
+ return true;
44
+ }
45
+ if (cp >= 55296 && cp <= 57343) {
46
+ return true;
47
+ }
48
+ return false;
49
+ }
50
+ function hex2(n) {
51
+ return n.toString(16).padStart(2, "0");
52
+ }
53
+ function hex4(n) {
54
+ return n.toString(16).padStart(4, "0");
55
+ }
56
+ function escapeRegExpFallback(str) {
57
+ let out = "";
58
+ let isFirst = true;
59
+ for (const char of str) {
60
+ const cp = char.codePointAt(0);
61
+ if (isFirst && (cp >= 48 && cp <= 57 || cp >= 65 && cp <= 90 || cp >= 97 && cp <= 122)) {
62
+ out += "\\x" + hex2(cp);
63
+ } else if (SYNTAX_CHARACTERS.has(char)) {
64
+ out += "\\" + char;
65
+ } else {
66
+ const ctrl = CONTROL_ESCAPES.get(cp);
67
+ if (ctrl !== void 0) {
68
+ out += ctrl;
69
+ } else if (isSpecHexEscapeCp(cp)) {
70
+ if (cp <= 255) {
71
+ out += "\\x" + hex2(cp);
72
+ } else {
73
+ for (let i = 0; i < char.length; i++) {
74
+ out += "\\u" + hex4(char.charCodeAt(i));
75
+ }
76
+ }
77
+ } else {
78
+ out += char;
79
+ }
80
+ }
81
+ isFirst = false;
82
+ }
83
+ return out;
29
84
  }
85
+ const maybeNativeEscape = RegExp.escape;
86
+ const escapeRegExp = typeof maybeNativeEscape === "function" ? maybeNativeEscape : escapeRegExpFallback;
30
87
  // Annotate the CommonJS export names for ESM import in node:
31
88
  0 && (module.exports = {
32
89
  escapeRegExp
@@ -43,6 +43,7 @@ module.exports = __toCommonJS(github_exports);
43
43
  var import_node_process = __toESM(require("node:process"));
44
44
  var import_picomatch = __toESM(require("../external/picomatch"));
45
45
  var import_archives = require("../archives");
46
+ var import_errors = require("../errors");
46
47
  var import_fs = require("../fs");
47
48
  var import_http_request = require("../http-request");
48
49
  var import_logger = require("../logger");
@@ -341,7 +342,7 @@ async function getLatestRelease(toolPrefix, repoConfig, options = {}) {
341
342
  `Retry attempt ${attempt + 1}/${RETRY_CONFIG.retries + 1} for ${toolPrefix} release...`
342
343
  );
343
344
  logger.warn(
344
- `Attempt ${attempt + 1}/${RETRY_CONFIG.retries + 1} failed: ${error instanceof Error ? error.message : String(error)}`
345
+ `Attempt ${attempt + 1}/${RETRY_CONFIG.retries + 1} failed: ${(0, import_errors.errorMessage)(error)}`
345
346
  );
346
347
  }
347
348
  return void 0;
@@ -395,7 +396,7 @@ async function getReleaseAssetUrl(tag, assetPattern, repoConfig, options = {}) {
395
396
  `Retry attempt ${attempt + 1}/${RETRY_CONFIG.retries + 1} for asset URL...`
396
397
  );
397
398
  logger.warn(
398
- `Attempt ${attempt + 1}/${RETRY_CONFIG.retries + 1} failed: ${error instanceof Error ? error.message : String(error)}`
399
+ `Attempt ${attempt + 1}/${RETRY_CONFIG.retries + 1} failed: ${(0, import_errors.errorMessage)(error)}`
399
400
  );
400
401
  }
401
402
  return void 0;
@@ -126,18 +126,74 @@ export declare function getBinaryAssetName(binaryBaseName: string, platform: Pla
126
126
  */
127
127
  export declare function getBinaryName(binaryBaseName: string, platform: Platform): string;
128
128
  /**
129
- * Get platform-arch identifier for directory structure.
130
- * Uses 'win' instead of 'win32' for file/folder names.
129
+ * Get platform-arch identifier for directory structure and asset names.
130
+ *
131
+ * # Format: `<os>-<arch>[-<libc>]`
132
+ *
133
+ * The OS segment is `process.platform` verbatim: `darwin` / `linux` /
134
+ * `win32`. The arch segment is `process.arch` verbatim: `x64` / `arm64`.
135
+ * The optional libc suffix is `-musl` (Linux only; the glibc default is
136
+ * unsuffixed to match Node.js's own linuxstatic convention).
137
+ *
138
+ * # Why these specific conventions
139
+ *
140
+ * ## Why `win32`, not `win`
141
+ *
142
+ * `win32` is what `process.platform` returns on every Windows host. Every
143
+ * npm package whose install-time platform filter uses the standard
144
+ * `os` / `cpu` / `libc` manifest fields must match `process.platform`
145
+ * strings exactly (npm compares them verbatim — there's no shorthand
146
+ * layer). Using `win` internally here would have forced a translation
147
+ * every time we constructed an install filter or a target triple, and
148
+ * reviewers would have to remember "we abbreviate on disk but not in
149
+ * package filters." Since the two now match, there's no translation
150
+ * step to get wrong.
151
+ *
152
+ * pnpm's pack-app (v11+) accepts `<os>-<arch>[-<libc>]` target strings
153
+ * and its shards are `@pnpm/exe.<os>-<arch>` (with `win32`, not `win` —
154
+ * see pnpm#11314). Our naming matches so asset names we emit can flow
155
+ * directly into pack-app's `--target` arg, `pnpm.app.targets` config,
156
+ * and sibling-package-name construction without a translation map.
157
+ *
158
+ * ## Why `-musl` is the suffix (and glibc is unsuffixed)
159
+ *
160
+ * Node.js's own linuxstatic tarballs historically used the unqualified
161
+ * `linux` for glibc and a separate download channel for musl. The pnpm
162
+ * ecosystem codified that as `linux-<arch>` (glibc, default) and
163
+ * `linux-<arch>-musl` (the libc outlier), matching the asymmetric
164
+ * reality of Linux distros — glibc is the majority case, musl is
165
+ * Alpine-and-similar. Adding `-glibc` for the default would be
166
+ * redundant noise in the name.
167
+ *
168
+ * ## Why libc is only appended for Linux
169
+ *
170
+ * macOS and Windows have exactly one system libc each (Apple libSystem,
171
+ * Microsoft UCRT). A hypothetical `darwin-arm64-libsystem` conveys no
172
+ * information. Node.js, npm, and pnpm all treat libc as a Linux-only
173
+ * axis; we follow the same convention so callers don't have to special-
174
+ * case `'darwin-arm64'.startsWith('darwin-arm64')` style matches.
175
+ *
176
+ * ## Why this function exists at all (vs. inlining)
177
+ *
178
+ * Two upstream APIs that socket-btm consumers end up calling — the
179
+ * npm manifest filter (`os`/`cpu`/`libc`) and pnpm's pack-app
180
+ * `--target` — both need the exact same triple format. Centralizing
181
+ * the construction here means a future schema change (e.g. Node
182
+ * introducing `riscv64`) gets one edit, and the error message for an
183
+ * unsupported platform is uniform across downloaders, pack-app
184
+ * invocations, and the `@socketbin/*` resolver logic.
131
185
  *
132
186
  * @param platform - Target platform
133
187
  * @param arch - Target architecture
134
- * @param libc - Linux libc variant (optional)
135
- * @returns Platform-arch identifier (e.g., 'darwin-arm64', 'linux-x64-musl', 'win-x64')
188
+ * @param libc - Linux libc variant (optional; non-linux platforms ignore)
189
+ * @returns Platform-arch identifier (e.g., 'darwin-arm64', 'linux-x64-musl', 'win32-x64')
136
190
  *
137
191
  * @example
138
192
  * ```typescript
139
193
  * getPlatformArch('linux', 'x64', 'musl') // 'linux-x64-musl'
140
- * getPlatformArch('darwin', 'arm64') // 'darwin-arm64'
194
+ * getPlatformArch('darwin', 'arm64') // 'darwin-arm64'
195
+ * getPlatformArch('win32', 'x64') // 'win32-x64'
196
+ * getPlatformArch('darwin', 'x64', 'musl') // 'darwin-x64' — libc ignored
141
197
  * ```
142
198
  */
143
199
  export declare function getPlatformArch(platform: Platform, arch: Arch, libc?: Libc | undefined): string;
@@ -38,7 +38,7 @@ const PLATFORM_MAP = {
38
38
  __proto__: null,
39
39
  darwin: "darwin",
40
40
  linux: "linux",
41
- win32: "win"
41
+ win32: "win32"
42
42
  };
43
43
  const ARCH_MAP = {
44
44
  __proto__: null,
@@ -185,7 +185,7 @@ function getBinaryAssetName(binaryBaseName, platform, arch, libc) {
185
185
  return `${binaryBaseName}-linux-${mappedArch}${muslSuffix}${ext}`;
186
186
  }
187
187
  if (platform === "win32") {
188
- return `${binaryBaseName}-win-${mappedArch}${ext}`;
188
+ return `${binaryBaseName}-win32-${mappedArch}${ext}`;
189
189
  }
190
190
  throw new Error(`Unsupported platform: ${platform}`);
191
191
  }
@@ -0,0 +1,26 @@
1
+ /**
2
+ * @fileoverview Throwing twin of `validateSchema`.
3
+ *
4
+ * Use `parseSchema(schema, data)` for fail-fast trust boundaries (app
5
+ * startup, config files, internal assertions). Use the non-throwing
6
+ * `validateSchema` for recoverable input (form fields, API request bodies,
7
+ * anywhere errors need to surface to a user).
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * import { z } from 'zod'
12
+ * import { parseSchema } from '@socketsecurity/lib/schema/parse'
13
+ *
14
+ * const Config = z.object({ host: z.string(), port: z.number() })
15
+ * const config = parseSchema(Config, json) // throws on invalid
16
+ * ```
17
+ */
18
+ import type { Infer } from './types';
19
+ /**
20
+ * Parse `data` against `schema` and return the validated value.
21
+ *
22
+ * @throws {Error} When validation fails. The message lists all issues as
23
+ * `path: message, path: message, ...`. Use `validateSchema` if you need
24
+ * structured access to the error list.
25
+ */
26
+ export declare function parseSchema<S>(schema: S, data: unknown): Infer<S>;
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ /* Socket Lib - Built with esbuild */
3
+ "use strict";
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
21
+ var parse_exports = {};
22
+ __export(parse_exports, {
23
+ parseSchema: () => parseSchema
24
+ });
25
+ module.exports = __toCommonJS(parse_exports);
26
+ var import_validate = require("./validate");
27
+ function parseSchema(schema, data) {
28
+ const result = (0, import_validate.validateSchema)(schema, data);
29
+ if (result.ok) {
30
+ return result.value;
31
+ }
32
+ const summary = result.errors.map((e) => `${e.path.join(".") || "(root)"}: ${e.message}`).join(", ");
33
+ throw new Error(`Validation failed: ${summary}`);
34
+ }
35
+ // Annotate the CommonJS export names for ESM import in node:
36
+ 0 && (module.exports = {
37
+ parseSchema
38
+ });
@@ -0,0 +1,121 @@
1
+ /**
2
+ * @fileoverview Shared types for schema validation.
3
+ *
4
+ * `Schema<T>` is the Zod-shaped duck-type contract — any validator with
5
+ * a `.safeParse(data)` method returning `{ success, data?, error? }`
6
+ * satisfies it. socket-lib detects Zod (v3 and v4) structurally via this
7
+ * interface; consumers bring their own Zod.
8
+ *
9
+ * `ValidateResult<T>` / `ValidationIssue` / `Infer<S>` / `AnySchema` are
10
+ * the normalized shapes produced by `@socketsecurity/lib/schema/validate`
11
+ * and `@socketsecurity/lib/schema/parse`.
12
+ */
13
+ /**
14
+ * Result of a Zod-shaped schema's `.safeParse()` call.
15
+ *
16
+ * @template T - The expected type of the parsed data
17
+ */
18
+ export interface ParseResult<T> {
19
+ /** Indicates whether parsing was successful */
20
+ success: boolean;
21
+ /** Parsed and validated data (only present when `success` is `true`) */
22
+ data?: T | undefined;
23
+ /** Error information (only present when `success` is `false`) */
24
+ error?: unknown;
25
+ }
26
+ /**
27
+ * Zod-shaped duck-type for any validator exposing `safeParse` / `parse`.
28
+ *
29
+ * @template T - The expected output type after validation
30
+ *
31
+ * @example
32
+ * ```ts
33
+ * import { z } from 'zod'
34
+ *
35
+ * const userSchema = z.object({ name: z.string(), age: z.number() })
36
+ *
37
+ * // Schema satisfies this interface
38
+ * const schema: Schema<User> = userSchema
39
+ * const result = schema.safeParse({ name: 'Alice', age: 30 })
40
+ * ```
41
+ */
42
+ export interface Schema<T = unknown> {
43
+ /** Non-throwing parse. */
44
+ safeParse(data: unknown): ParseResult<T>;
45
+ /** Throwing parse. */
46
+ parse(data: unknown): T;
47
+ /** Optional schema name for debugging. */
48
+ _name?: string | undefined;
49
+ }
50
+ /**
51
+ * Internal structural shape of a Zod v4 schema — carries the inferred
52
+ * output type on `_zod.output`. Used for type-only detection in `Infer<S>`.
53
+ *
54
+ * @internal
55
+ */
56
+ interface ZodV4LikeSchema<O = unknown> {
57
+ _zod: {
58
+ output: O;
59
+ };
60
+ safeParse(data: unknown): unknown;
61
+ }
62
+ /**
63
+ * Internal structural shape of a Zod v3 schema — carries the inferred
64
+ * output type on `_output`. Used for type-only detection in `Infer<S>`.
65
+ *
66
+ * @internal
67
+ */
68
+ interface ZodV3LikeSchema<O = unknown> {
69
+ _output: O;
70
+ safeParse(data: unknown): unknown;
71
+ }
72
+ /**
73
+ * Internal structural shape of a TypeBox `TSchema` — carries the inferred
74
+ * output type on the phantom `static` field. Only used inside socket-lib
75
+ * for type-only detection in `Infer<S>`; external callers should pass
76
+ * Zod schemas.
77
+ *
78
+ * @internal
79
+ */
80
+ interface TypeBoxLikeSchema {
81
+ static: unknown;
82
+ }
83
+ /**
84
+ * Any schema kind the validators accept.
85
+ */
86
+ export type AnySchema = ZodV4LikeSchema<unknown> | ZodV3LikeSchema<unknown> | TypeBoxLikeSchema | Schema<unknown>;
87
+ /**
88
+ * Infer the validated output type from any supported schema kind.
89
+ *
90
+ * Order matters: TypeBox schemas carry a phantom `static` field, so we
91
+ * check for TypeBox before falling through to Zod and the duck-type.
92
+ */
93
+ export type Infer<S> = S extends {
94
+ static: infer Static;
95
+ } ? Static : S extends {
96
+ _zod: {
97
+ output: infer O;
98
+ };
99
+ } ? O : S extends {
100
+ _output: infer O;
101
+ } ? O : S extends Schema<infer T> ? T : unknown;
102
+ /**
103
+ * A single normalized validation error.
104
+ */
105
+ export interface ValidationIssue {
106
+ /** Array path into the value (e.g. `['user', 'age']`). */
107
+ path: Array<string | number>;
108
+ /** Human-readable description of the failure. */
109
+ message: string;
110
+ }
111
+ /**
112
+ * Tagged-union result of `validateSchema`. Callers narrow on `ok`.
113
+ */
114
+ export type ValidateResult<T> = {
115
+ ok: true;
116
+ value: T;
117
+ } | {
118
+ ok: false;
119
+ errors: ValidationIssue[];
120
+ };
121
+ export {};
@@ -0,0 +1,35 @@
1
+ /**
2
+ * @fileoverview Universal schema validator — non-throwing.
3
+ *
4
+ * Accepts any Zod-shaped schema (`.safeParse`-exposing) and returns a tagged
5
+ * result `{ ok: true, value } | { ok: false, errors }` with normalized
6
+ * `{ path, message }` issues. No runtime dependency on `zod` — detection
7
+ * is purely structural.
8
+ *
9
+ * @internal
10
+ * socket-lib additionally recognizes TypeBox schemas for its own internal
11
+ * use (e.g. `src/ipc.ts`'s stub-file validation). That path is not a
12
+ * supported consumer API.
13
+ *
14
+ * @example
15
+ * ```ts
16
+ * import { z } from 'zod'
17
+ * import { validateSchema } from '@socketsecurity/lib/schema/validate'
18
+ *
19
+ * const User = z.object({ name: z.string() })
20
+ * const r = validateSchema(User, data)
21
+ * if (r.ok) r.value.name // string
22
+ * else r.errors // ValidationIssue[]
23
+ * ```
24
+ */
25
+ import type { Infer, ValidateResult } from './types';
26
+ /**
27
+ * Validate `data` against a Zod-style `schema`. Non-throwing.
28
+ *
29
+ * The return type narrows `value` to `Infer<S>`, so callers get
30
+ * `z.infer<typeof S>` with no casts. Errors are normalized to
31
+ * `{ path, message }` regardless of the underlying validator.
32
+ *
33
+ * @throws {TypeError} When `schema` is not a recognized validator kind.
34
+ */
35
+ export declare function validateSchema<S>(schema: S, data: unknown): ValidateResult<Infer<S>>;
@@ -18,12 +18,11 @@ var __copyProps = (to, from, except, desc) => {
18
18
  return to;
19
19
  };
20
20
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
21
- var validate_schema_exports = {};
22
- __export(validate_schema_exports, {
23
- parseSchema: () => parseSchema,
21
+ var validate_exports = {};
22
+ __export(validate_exports, {
24
23
  validateSchema: () => validateSchema
25
24
  });
26
- module.exports = __toCommonJS(validate_schema_exports);
25
+ module.exports = __toCommonJS(validate_exports);
27
26
  function isTypeBoxSchema(schema) {
28
27
  if (schema === null || typeof schema !== "object") {
29
28
  return false;
@@ -90,19 +89,10 @@ function validateSchema(schema, data) {
90
89
  };
91
90
  }
92
91
  throw new TypeError(
93
- "validateSchema: unsupported schema kind. Expected a TypeBox schema, a Zod schema, or an object with a safeParse method."
92
+ "validateSchema: unsupported schema kind. Expected a Zod schema or an object with a safeParse method."
94
93
  );
95
94
  }
96
- function parseSchema(schema, data) {
97
- const result = validateSchema(schema, data);
98
- if (result.ok) {
99
- return result.value;
100
- }
101
- const summary = result.errors.map((e) => `${e.path.join(".") || "(root)"}: ${e.message}`).join(", ");
102
- throw new Error(`Validation failed: ${summary}`);
103
- }
104
95
  // Annotate the CommonJS export names for ESM import in node:
105
96
  0 && (module.exports = {
106
- parseSchema,
107
97
  validateSchema
108
98
  });
@@ -95,7 +95,6 @@ function suppressWarningType(warningType) {
95
95
  }
96
96
  async function withSuppressedWarnings(warningType, callback) {
97
97
  const wasAlreadySuppressed = suppressedWarnings.has(warningType);
98
- const original = import_node_process.default.emitWarning;
99
98
  suppressWarningType(warningType);
100
99
  try {
101
100
  return await callback();
@@ -103,7 +102,6 @@ async function withSuppressedWarnings(warningType, callback) {
103
102
  if (!wasAlreadySuppressed) {
104
103
  suppressedWarnings.delete(warningType);
105
104
  }
106
- import_node_process.default.emitWarning = original;
107
105
  }
108
106
  }
109
107
  // Annotate the CommonJS export names for ESM import in node:
package/dist/url.js CHANGED
@@ -73,7 +73,11 @@ function urlSearchParamAsBoolean(value, options) {
73
73
  };
74
74
  if (typeof value === "string") {
75
75
  const trimmed = value.trim();
76
- return trimmed === "1" || trimmed.toLowerCase() === "true";
76
+ if (trimmed === "") {
77
+ return !!defaultValue;
78
+ }
79
+ const lowered = trimmed.toLowerCase();
80
+ return lowered === "1" || lowered === "true" || lowered === "yes" || lowered === "on";
77
81
  }
78
82
  if (value === null || value === void 0) {
79
83
  return !!defaultValue;
package/dist/versions.js CHANGED
@@ -111,11 +111,11 @@ function isValidVersion(version) {
111
111
  }
112
112
  function maxVersion(versions) {
113
113
  const semver = getSemver();
114
- return semver.maxSatisfying(versions, "*") || void 0;
114
+ return semver.maxSatisfying(versions, "*", { includePrerelease: true }) || void 0;
115
115
  }
116
116
  function minVersion(versions) {
117
117
  const semver = getSemver();
118
- return semver.minSatisfying(versions, "*") || void 0;
118
+ return semver.minSatisfying(versions, "*", { includePrerelease: true }) || void 0;
119
119
  }
120
120
  function parseVersion(version) {
121
121
  const semver = getSemver();
package/dist/words.js CHANGED
@@ -27,18 +27,15 @@ __export(words_exports, {
27
27
  module.exports = __toCommonJS(words_exports);
28
28
  // @__NO_SIDE_EFFECTS__
29
29
  function capitalize(word) {
30
- const { length } = word;
31
- if (length === 0) {
30
+ if (word.length === 0) {
32
31
  return word;
33
32
  }
34
- if (length === 1) {
35
- return word.toUpperCase();
36
- }
37
- return `${word.charAt(0).toUpperCase()}${word.slice(1).toLowerCase()}`;
33
+ const [first, ...rest] = [...word];
34
+ return (first ?? "").toUpperCase() + rest.join("").toLowerCase();
38
35
  }
39
36
  // @__NO_SIDE_EFFECTS__
40
37
  function determineArticle(word) {
41
- return /^[aeiou]/.test(word) ? "an" : "a";
38
+ return /^[aeiou]/i.test(word) ? "an" : "a";
42
39
  }
43
40
  // @__NO_SIDE_EFFECTS__
44
41
  function pluralize(word, options) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@socketsecurity/lib",
3
- "version": "5.20.1",
4
- "packageManager": "pnpm@11.0.0-rc.2",
3
+ "version": "5.23.0",
4
+ "packageManager": "pnpm@11.0.0-rc.5",
5
5
  "license": "MIT",
6
6
  "description": "Core utilities and infrastructure for Socket.dev security tools",
7
7
  "keywords": [
@@ -547,6 +547,18 @@
547
547
  "types": "./dist/releases/socket-btm.d.ts",
548
548
  "default": "./dist/releases/socket-btm.js"
549
549
  },
550
+ "./schema/parse": {
551
+ "types": "./dist/schema/parse.d.ts",
552
+ "default": "./dist/schema/parse.js"
553
+ },
554
+ "./schema/types": {
555
+ "types": "./dist/schema/types.d.ts",
556
+ "default": "./dist/schema/types.js"
557
+ },
558
+ "./schema/validate": {
559
+ "types": "./dist/schema/validate.d.ts",
560
+ "default": "./dist/schema/validate.js"
561
+ },
550
562
  "./sea": {
551
563
  "types": "./dist/sea.d.ts",
552
564
  "default": "./dist/sea.js"
@@ -655,18 +667,6 @@
655
667
  "types": "./dist/url.d.ts",
656
668
  "default": "./dist/url.js"
657
669
  },
658
- "./validation/json-parser": {
659
- "types": "./dist/validation/json-parser.d.ts",
660
- "default": "./dist/validation/json-parser.js"
661
- },
662
- "./validation/types": {
663
- "types": "./dist/validation/types.d.ts",
664
- "default": "./dist/validation/types.js"
665
- },
666
- "./validation/validate-schema": {
667
- "types": "./dist/validation/validate-schema.d.ts",
668
- "default": "./dist/validation/validate-schema.js"
669
- },
670
670
  "./versions": {
671
671
  "types": "./dist/versions.d.ts",
672
672
  "default": "./dist/versions.js"
@@ -724,7 +724,7 @@
724
724
  "@socketregistry/is-unicode-supported": "1.0.5",
725
725
  "@socketregistry/packageurl-js": "1.4.2",
726
726
  "@socketregistry/yocto-spinner": "1.0.25",
727
- "@socketsecurity/lib-stable": "npm:@socketsecurity/lib@5.19.1",
727
+ "@socketsecurity/lib-stable": "npm:@socketsecurity/lib@5.21.0",
728
728
  "@types/node": "24.9.2",
729
729
  "@typescript/native-preview": "7.0.0-dev.20260415.1",
730
730
  "@vitest/coverage-v8": "4.0.3",
@@ -1,58 +0,0 @@
1
- /**
2
- * @fileoverview Safe JSON parsing with validation and security controls.
3
- * Provides protection against prototype pollution, size limits, and schema
4
- * validation.
5
- *
6
- * Key Features:
7
- * - Prototype pollution protection: Blocks `__proto__`, `constructor`, and
8
- * `prototype` keys via JSON.parse reviver at any depth.
9
- * - Size limits: Configurable maximum JSON string size (default 10MB).
10
- * - Schema validation: Optional Zod-compatible schema validation.
11
- * - Memory safety: Prevents memory exhaustion attacks.
12
- */
13
- import type { SafeJsonParseOptions, Schema } from './types';
14
- /**
15
- * Safely parse JSON with optional schema validation and security controls.
16
- * Throws errors on parse failures, validation failures, or security violations.
17
- *
18
- * This is the recommended method for parsing untrusted JSON input as it
19
- * provides multiple layers of security including prototype pollution
20
- * protection and size limits.
21
- *
22
- * @template T - The expected type of the parsed data
23
- * @param jsonString - The JSON string to parse
24
- * @param schema - Optional Zod-compatible schema for validation
25
- * @param options - Parsing options for security and behavior control
26
- * @returns The parsed and validated data
27
- *
28
- * @throws {Error} When JSON string exceeds `maxSize`.
29
- * @throws {Error} When JSON parsing fails.
30
- * @throws {Error} When prototype pollution keys are detected (unless
31
- * `allowPrototype` is `true`).
32
- * @throws {Error} When schema validation fails.
33
- *
34
- * @example
35
- * ```ts
36
- * // Basic parsing with type inference
37
- * const data = safeJsonParse<User>('{"name":"Alice","age":30}')
38
- *
39
- * // With schema validation
40
- * import { z } from 'zod'
41
- * const userSchema = z.object({
42
- * name: z.string(),
43
- * age: z.number()
44
- * })
45
- * const user = safeJsonParse('{"name":"Alice","age":30}', userSchema)
46
- *
47
- * // With size limit
48
- * const data = safeJsonParse(jsonString, undefined, {
49
- * maxSize: 1024 * 1024 // 1MB
50
- * })
51
- *
52
- * // Allow prototype keys (DANGEROUS — only for trusted sources)
53
- * const data = safeJsonParse('{"__proto__": {}}', undefined, {
54
- * allowPrototype: true
55
- * })
56
- * ```
57
- */
58
- export declare function safeJsonParse<T = unknown>(jsonString: string, schema?: Schema<T> | undefined, options?: SafeJsonParseOptions): T;