@socketsecurity/lib 5.20.1 → 5.21.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 +96 -95
- 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/package.js +14 -1
- package/dist/fs.js +8 -2
- package/dist/globs.js +5 -1
- package/dist/ipc.js +2 -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/specs.js +9 -2
- package/dist/process-lock.js +1 -6
- 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/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 +14 -14
- 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
|
@@ -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
|
|
22
|
-
__export(
|
|
23
|
-
parseSchema: () => parseSchema,
|
|
21
|
+
var validate_exports = {};
|
|
22
|
+
__export(validate_exports, {
|
|
24
23
|
validateSchema: () => validateSchema
|
|
25
24
|
});
|
|
26
|
-
module.exports = __toCommonJS(
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
31
|
-
if (length === 0) {
|
|
30
|
+
if (word.length === 0) {
|
|
32
31
|
return word;
|
|
33
32
|
}
|
|
34
|
-
|
|
35
|
-
|
|
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]
|
|
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,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@socketsecurity/lib",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.21.0",
|
|
4
4
|
"packageManager": "pnpm@11.0.0-rc.2",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "Core utilities and infrastructure for Socket.dev security tools",
|
|
@@ -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.
|
|
727
|
+
"@socketsecurity/lib-stable": "npm:@socketsecurity/lib@5.20.1",
|
|
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;
|
|
@@ -1,63 +0,0 @@
|
|
|
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 json_parser_exports = {};
|
|
22
|
-
__export(json_parser_exports, {
|
|
23
|
-
safeJsonParse: () => safeJsonParse
|
|
24
|
-
});
|
|
25
|
-
module.exports = __toCommonJS(json_parser_exports);
|
|
26
|
-
const DANGEROUS_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
|
|
27
|
-
function prototypePollutionReviver(key, value) {
|
|
28
|
-
if (DANGEROUS_KEYS.has(key)) {
|
|
29
|
-
throw new Error(
|
|
30
|
-
"JSON contains potentially malicious prototype pollution keys"
|
|
31
|
-
);
|
|
32
|
-
}
|
|
33
|
-
return value;
|
|
34
|
-
}
|
|
35
|
-
function safeJsonParse(jsonString, schema, options = {}) {
|
|
36
|
-
const { allowPrototype = false, maxSize = 10 * 1024 * 1024 } = options;
|
|
37
|
-
const byteLength = Buffer.byteLength(jsonString, "utf8");
|
|
38
|
-
if (byteLength > maxSize) {
|
|
39
|
-
throw new Error(
|
|
40
|
-
`JSON string exceeds maximum size limit${maxSize !== 10 * 1024 * 1024 ? ` of ${maxSize} bytes` : ""}`
|
|
41
|
-
);
|
|
42
|
-
}
|
|
43
|
-
let parsed;
|
|
44
|
-
try {
|
|
45
|
-
parsed = allowPrototype ? JSON.parse(jsonString) : JSON.parse(jsonString, prototypePollutionReviver);
|
|
46
|
-
} catch (error) {
|
|
47
|
-
throw new Error(`Failed to parse JSON: ${error}`);
|
|
48
|
-
}
|
|
49
|
-
if (schema) {
|
|
50
|
-
const result = schema.safeParse(parsed);
|
|
51
|
-
if (!result.success) {
|
|
52
|
-
const error = result.error;
|
|
53
|
-
const errors = error.issues.map((issue) => `${issue.path.join(".")}: ${issue.message}`).join(", ");
|
|
54
|
-
throw new Error(`Validation failed: ${errors}`);
|
|
55
|
-
}
|
|
56
|
-
return result.data;
|
|
57
|
-
}
|
|
58
|
-
return parsed;
|
|
59
|
-
}
|
|
60
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
61
|
-
0 && (module.exports = {
|
|
62
|
-
safeJsonParse
|
|
63
|
-
});
|
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Validation type definitions.
|
|
3
|
-
* Provides core types for schema validation and JSON parsing with security features.
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* Result of a schema validation operation.
|
|
7
|
-
* Contains either successful parsed data or error information.
|
|
8
|
-
*
|
|
9
|
-
* @template T - The expected type of the parsed data
|
|
10
|
-
*
|
|
11
|
-
* @example
|
|
12
|
-
* ```ts
|
|
13
|
-
* const result: ParseResult<User> = schema.safeParse(data)
|
|
14
|
-
* if (result.success) {
|
|
15
|
-
* console.log(result.data) // User object
|
|
16
|
-
* } else {
|
|
17
|
-
* console.error(result.error) // Error details
|
|
18
|
-
* }
|
|
19
|
-
* ```
|
|
20
|
-
*/
|
|
21
|
-
export interface ParseResult<T> {
|
|
22
|
-
/** Indicates whether parsing was successful */
|
|
23
|
-
success: boolean;
|
|
24
|
-
/** Parsed and validated data (only present when `success` is `true`) */
|
|
25
|
-
data?: T | undefined;
|
|
26
|
-
/** Error information (only present when `success` is `false`) */
|
|
27
|
-
error?: unknown;
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* Base schema interface compatible with Zod and similar validation libraries.
|
|
31
|
-
* Provides both safe and throwing parsing methods.
|
|
32
|
-
*
|
|
33
|
-
* @template T - The expected output type after validation
|
|
34
|
-
*
|
|
35
|
-
* @example
|
|
36
|
-
* ```ts
|
|
37
|
-
* import { z } from 'zod'
|
|
38
|
-
*
|
|
39
|
-
* const userSchema = z.object({
|
|
40
|
-
* name: z.string(),
|
|
41
|
-
* age: z.number()
|
|
42
|
-
* })
|
|
43
|
-
*
|
|
44
|
-
* // Schema satisfies this interface
|
|
45
|
-
* const schema: Schema<User> = userSchema
|
|
46
|
-
* const result = schema.safeParse({ name: 'Alice', age: 30 })
|
|
47
|
-
* ```
|
|
48
|
-
*/
|
|
49
|
-
export interface Schema<T = unknown> {
|
|
50
|
-
/**
|
|
51
|
-
* Safely parse data without throwing errors.
|
|
52
|
-
* Returns a result object indicating success or failure.
|
|
53
|
-
*
|
|
54
|
-
* @param data - The data to validate
|
|
55
|
-
* @returns Parse result with success flag and data or error
|
|
56
|
-
*/
|
|
57
|
-
safeParse(data: unknown): ParseResult<T>;
|
|
58
|
-
/**
|
|
59
|
-
* Parse data and throw an error if validation fails.
|
|
60
|
-
* Use this when you want to fail fast on invalid data.
|
|
61
|
-
*
|
|
62
|
-
* @param data - The data to validate
|
|
63
|
-
* @returns The validated and parsed data
|
|
64
|
-
* @throws {Error} When validation fails
|
|
65
|
-
*/
|
|
66
|
-
parse(data: unknown): T;
|
|
67
|
-
/**
|
|
68
|
-
* Optional schema name for debugging and error messages.
|
|
69
|
-
* Useful for identifying which schema failed in complex validation chains.
|
|
70
|
-
*/
|
|
71
|
-
_name?: string | undefined;
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Options for configuring safe JSON parsing with security controls.
|
|
75
|
-
* Distinct from `JsonParseOptions` in `@socketsecurity/lib/json/types`
|
|
76
|
-
* which is scoped to reviver/error-handling for fs-oriented JSON reads.
|
|
77
|
-
*
|
|
78
|
-
* @example
|
|
79
|
-
* ```ts
|
|
80
|
-
* const options: SafeJsonParseOptions = {
|
|
81
|
-
* maxSize: 1024 * 1024, // 1MB limit
|
|
82
|
-
* allowPrototype: false // Block prototype pollution
|
|
83
|
-
* }
|
|
84
|
-
* ```
|
|
85
|
-
*/
|
|
86
|
-
export interface SafeJsonParseOptions {
|
|
87
|
-
/**
|
|
88
|
-
* Allow dangerous prototype pollution keys (`__proto__`, `constructor`, `prototype`).
|
|
89
|
-
* Set to `true` only if you trust the JSON source completely.
|
|
90
|
-
*
|
|
91
|
-
* @default false
|
|
92
|
-
*
|
|
93
|
-
* @example
|
|
94
|
-
* ```ts
|
|
95
|
-
* // Will throw error by default
|
|
96
|
-
* safeJsonParse('{"__proto__": {"polluted": true}}')
|
|
97
|
-
*
|
|
98
|
-
* // Allows the parse (dangerous!)
|
|
99
|
-
* safeJsonParse('{"__proto__": {"polluted": true}}', undefined, {
|
|
100
|
-
* allowPrototype: true
|
|
101
|
-
* })
|
|
102
|
-
* ```
|
|
103
|
-
*/
|
|
104
|
-
allowPrototype?: boolean | undefined;
|
|
105
|
-
/**
|
|
106
|
-
* Maximum allowed size of JSON string in bytes.
|
|
107
|
-
* Prevents memory exhaustion from extremely large payloads.
|
|
108
|
-
*
|
|
109
|
-
* @default 10_485_760 (10 MB)
|
|
110
|
-
*
|
|
111
|
-
* @example
|
|
112
|
-
* ```ts
|
|
113
|
-
* // Limit to 1KB
|
|
114
|
-
* safeJsonParse(jsonString, undefined, { maxSize: 1024 })
|
|
115
|
-
* ```
|
|
116
|
-
*/
|
|
117
|
-
maxSize?: number | undefined;
|
|
118
|
-
}
|