@fuzdev/fuz_util 0.53.2 → 0.53.4
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/hash_blake3.d.ts +4 -0
- package/dist/hash_blake3.d.ts.map +1 -1
- package/dist/hash_blake3.js +5 -0
- package/dist/zod.d.ts +63 -2
- package/dist/zod.d.ts.map +1 -1
- package/dist/zod.js +114 -2
- package/package.json +2 -2
- package/src/lib/hash_blake3.ts +7 -0
- package/src/lib/zod.ts +127 -2
package/dist/hash_blake3.d.ts
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
*
|
|
8
8
|
* @module
|
|
9
9
|
*/
|
|
10
|
+
import { z } from 'zod';
|
|
10
11
|
/**
|
|
11
12
|
* Resolves when the BLAKE3 WASM module is initialized and ready.
|
|
12
13
|
* Initialization starts eagerly on import. Idempotent — safe to await multiple times.
|
|
@@ -20,4 +21,7 @@ export declare const blake3_ready: Promise<void>;
|
|
|
20
21
|
* @returns 64-character hexadecimal hash string (32 bytes).
|
|
21
22
|
*/
|
|
22
23
|
export declare const hash_blake3: (data: BufferSource | string) => string;
|
|
24
|
+
/** Zod schema for a BLAKE3 hex hash — 64 lowercase hex characters (256-bit output). */
|
|
25
|
+
export declare const Blake3Hash: z.ZodString;
|
|
26
|
+
export type Blake3Hash = z.infer<typeof Blake3Hash>;
|
|
23
27
|
//# sourceMappingURL=hash_blake3.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hash_blake3.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/hash_blake3.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;
|
|
1
|
+
{"version":3,"file":"hash_blake3.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/hash_blake3.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAMtB;;;;GAIG;AACH,eAAO,MAAM,YAAY,eAAS,CAAC;AAEnC;;;;;GAKG;AACH,eAAO,MAAM,WAAW,GAAI,MAAM,YAAY,GAAG,MAAM,KAAG,MAAsC,CAAC;AAEjG,uFAAuF;AACvF,eAAO,MAAM,UAAU,aAEuD,CAAC;AAC/E,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC"}
|
package/dist/hash_blake3.js
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
*
|
|
8
8
|
* @module
|
|
9
9
|
*/
|
|
10
|
+
import { z } from 'zod';
|
|
10
11
|
import { hash, init } from '@fuzdev/blake3_wasm';
|
|
11
12
|
import { to_hex } from './hex.js';
|
|
12
13
|
import { to_bytes } from './bytes.js';
|
|
@@ -23,3 +24,7 @@ export const blake3_ready = init();
|
|
|
23
24
|
* @returns 64-character hexadecimal hash string (32 bytes).
|
|
24
25
|
*/
|
|
25
26
|
export const hash_blake3 = (data) => to_hex(hash(to_bytes(data)));
|
|
27
|
+
/** Zod schema for a BLAKE3 hex hash — 64 lowercase hex characters (256-bit output). */
|
|
28
|
+
export const Blake3Hash = z
|
|
29
|
+
.string()
|
|
30
|
+
.regex(/^[0-9a-f]{64}$/, 'Expected a 64-character lowercase hex blake3 hash');
|
package/dist/zod.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Zod schema introspection utilities.
|
|
3
3
|
*
|
|
4
|
-
* Generic helpers for extracting metadata from Zod schemas.
|
|
5
|
-
*
|
|
4
|
+
* Generic helpers for walking, unwrapping, and extracting metadata from Zod schemas.
|
|
5
|
+
* Used by CLI argument parsing, adversarial input testing, and surface generation.
|
|
6
6
|
*
|
|
7
7
|
* @module
|
|
8
8
|
*/
|
|
@@ -14,6 +14,67 @@ import type { z } from 'zod';
|
|
|
14
14
|
* @returns Inner schema if wrapped, undefined otherwise.
|
|
15
15
|
*/
|
|
16
16
|
export declare const zod_to_subschema: (def: z.core.$ZodTypeDef) => z.ZodType | undefined;
|
|
17
|
+
/** Zod wrapper type names that `zod_unwrap_def` traverses through. */
|
|
18
|
+
export declare const ZOD_WRAPPER_TYPES: Set<string>;
|
|
19
|
+
/**
|
|
20
|
+
* Unwrap Zod wrappers (optional, default, nullable, pipe, transform)
|
|
21
|
+
* to get the base type definition.
|
|
22
|
+
*
|
|
23
|
+
* @param schema - Zod schema to unwrap
|
|
24
|
+
* @returns the innermost non-wrapper type definition
|
|
25
|
+
*/
|
|
26
|
+
export declare const zod_unwrap_def: (schema: z.ZodType) => z.core.$ZodTypeDef;
|
|
27
|
+
/**
|
|
28
|
+
* Get the base type name for a Zod schema, unwrapping all wrappers.
|
|
29
|
+
*
|
|
30
|
+
* @param schema - Zod schema to inspect
|
|
31
|
+
* @returns base type name (e.g. `'string'`, `'object'`, `'uuid'`)
|
|
32
|
+
*/
|
|
33
|
+
export declare const zod_get_base_type: (schema: z.ZodType) => string;
|
|
34
|
+
/**
|
|
35
|
+
* Check if a schema is optional at the outermost level.
|
|
36
|
+
*
|
|
37
|
+
* @param schema - Zod schema to check
|
|
38
|
+
*/
|
|
39
|
+
export declare const zod_is_optional: (schema: z.ZodType) => boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Check if a schema accepts null at any wrapping level.
|
|
42
|
+
*
|
|
43
|
+
* @param schema - Zod schema to check
|
|
44
|
+
*/
|
|
45
|
+
export declare const zod_is_nullable: (schema: z.ZodType) => boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Check if a schema has a default value at any wrapping level.
|
|
48
|
+
*
|
|
49
|
+
* Unlike `zod_to_schema_default` (which returns the value), this returns a boolean.
|
|
50
|
+
* Distinguishes "no default" from "default is undefined".
|
|
51
|
+
*
|
|
52
|
+
* @param schema - Zod schema to check
|
|
53
|
+
*/
|
|
54
|
+
export declare const zod_has_default: (schema: z.ZodType) => boolean;
|
|
55
|
+
/**
|
|
56
|
+
* Unwrap a schema to find the inner `ZodObject`, or `null` if not an object schema.
|
|
57
|
+
* Handles wrappers like `z.strictObject({...}).default({...})`.
|
|
58
|
+
*
|
|
59
|
+
* @param schema - Zod schema to unwrap
|
|
60
|
+
* @returns the inner ZodObject or null
|
|
61
|
+
*/
|
|
62
|
+
export declare const zod_unwrap_to_object: (schema: z.ZodType) => z.ZodObject | null;
|
|
63
|
+
/** Metadata extracted from a single field of a Zod object schema. */
|
|
64
|
+
export interface ZodFieldInfo {
|
|
65
|
+
name: string;
|
|
66
|
+
base_type: string;
|
|
67
|
+
required: boolean;
|
|
68
|
+
has_default: boolean;
|
|
69
|
+
nullable: boolean;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Extract field metadata from a Zod object schema.
|
|
73
|
+
*
|
|
74
|
+
* @param schema - Zod object schema to extract from
|
|
75
|
+
* @returns array of field info for each property
|
|
76
|
+
*/
|
|
77
|
+
export declare const zod_extract_fields: (schema: z.ZodObject) => Array<ZodFieldInfo>;
|
|
17
78
|
/**
|
|
18
79
|
* Get the description from a schema's metadata, unwrapping if needed.
|
|
19
80
|
*
|
package/dist/zod.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zod.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/zod.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAM3B;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,GAAI,KAAK,CAAC,CAAC,IAAI,CAAC,WAAW,KAAG,CAAC,CAAC,OAAO,GAAG,SAStE,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,MAAM,GAAG,IAUtE,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,OAUzD,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,KAAK,CAAC,MAAM,CAUrE,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,MA4C7D,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,GAAI,OAAO,OAAO,KAAG,MAQjD,CAAC;AAMF;;GAEG;AACH,MAAM,WAAW,iBAAiB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;CACvB;AAED;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,KAAK,CAAC,iBAAiB,CAuBnF,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,gCAAgC,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,GAAG,CAAC,MAAM,CAW9E,CAAC"}
|
|
1
|
+
{"version":3,"file":"zod.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/zod.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAM3B;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,GAAI,KAAK,CAAC,CAAC,IAAI,CAAC,WAAW,KAAG,CAAC,CAAC,OAAO,GAAG,SAStE,CAAC;AAEF,sEAAsE;AACtE,eAAO,MAAM,iBAAiB,aAO5B,CAAC;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,CAAC,CAAC,IAAI,CAAC,WAOzD,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,MAAqC,CAAC;AAE5F;;;;GAIG;AACH,eAAO,MAAM,eAAe,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,OAA8C,CAAC;AAEnG;;;;GAIG;AACH,eAAO,MAAM,eAAe,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,OAQnD,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,OAMnD,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,CAAC,CAAC,SAAS,GAAG,IAUtE,CAAC;AAIF,qEAAqE;AACrE,MAAM,WAAW,YAAY;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC;CAClB;AAED;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,GAAI,QAAQ,CAAC,CAAC,SAAS,KAAG,KAAK,CAAC,YAAY,CAa1E,CAAC;AAIF;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,MAAM,GAAG,IAUtE,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,OAUzD,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,KAAK,CAAC,MAAM,CAUrE,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,MA4C7D,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,GAAI,OAAO,OAAO,KAAG,MAQjD,CAAC;AAMF;;GAEG;AACH,MAAM,WAAW,iBAAiB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;CACvB;AAED;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,KAAK,CAAC,iBAAiB,CAuBnF,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,gCAAgC,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,GAAG,CAAC,MAAM,CAW9E,CAAC"}
|
package/dist/zod.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Zod schema introspection utilities.
|
|
3
3
|
*
|
|
4
|
-
* Generic helpers for extracting metadata from Zod schemas.
|
|
5
|
-
*
|
|
4
|
+
* Generic helpers for walking, unwrapping, and extracting metadata from Zod schemas.
|
|
5
|
+
* Used by CLI argument parsing, adversarial input testing, and surface generation.
|
|
6
6
|
*
|
|
7
7
|
* @module
|
|
8
8
|
*/
|
|
@@ -27,6 +27,118 @@ export const zod_to_subschema = (def) => {
|
|
|
27
27
|
}
|
|
28
28
|
return undefined;
|
|
29
29
|
};
|
|
30
|
+
/** Zod wrapper type names that `zod_unwrap_def` traverses through. */
|
|
31
|
+
export const ZOD_WRAPPER_TYPES = new Set([
|
|
32
|
+
'optional',
|
|
33
|
+
'nullable',
|
|
34
|
+
'default',
|
|
35
|
+
'transform',
|
|
36
|
+
'pipe',
|
|
37
|
+
'prefault',
|
|
38
|
+
]);
|
|
39
|
+
/**
|
|
40
|
+
* Unwrap Zod wrappers (optional, default, nullable, pipe, transform)
|
|
41
|
+
* to get the base type definition.
|
|
42
|
+
*
|
|
43
|
+
* @param schema - Zod schema to unwrap
|
|
44
|
+
* @returns the innermost non-wrapper type definition
|
|
45
|
+
*/
|
|
46
|
+
export const zod_unwrap_def = (schema) => {
|
|
47
|
+
const def = schema._zod.def;
|
|
48
|
+
if (ZOD_WRAPPER_TYPES.has(def.type)) {
|
|
49
|
+
const sub = zod_to_subschema(def);
|
|
50
|
+
if (sub)
|
|
51
|
+
return zod_unwrap_def(sub);
|
|
52
|
+
}
|
|
53
|
+
return def;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Get the base type name for a Zod schema, unwrapping all wrappers.
|
|
57
|
+
*
|
|
58
|
+
* @param schema - Zod schema to inspect
|
|
59
|
+
* @returns base type name (e.g. `'string'`, `'object'`, `'uuid'`)
|
|
60
|
+
*/
|
|
61
|
+
export const zod_get_base_type = (schema) => zod_unwrap_def(schema).type;
|
|
62
|
+
/**
|
|
63
|
+
* Check if a schema is optional at the outermost level.
|
|
64
|
+
*
|
|
65
|
+
* @param schema - Zod schema to check
|
|
66
|
+
*/
|
|
67
|
+
export const zod_is_optional = (schema) => schema._zod.def.type === 'optional';
|
|
68
|
+
/**
|
|
69
|
+
* Check if a schema accepts null at any wrapping level.
|
|
70
|
+
*
|
|
71
|
+
* @param schema - Zod schema to check
|
|
72
|
+
*/
|
|
73
|
+
export const zod_is_nullable = (schema) => {
|
|
74
|
+
const def = schema._zod.def;
|
|
75
|
+
if (def.type === 'nullable')
|
|
76
|
+
return true;
|
|
77
|
+
if (ZOD_WRAPPER_TYPES.has(def.type)) {
|
|
78
|
+
const sub = zod_to_subschema(def);
|
|
79
|
+
if (sub)
|
|
80
|
+
return zod_is_nullable(sub);
|
|
81
|
+
}
|
|
82
|
+
return false;
|
|
83
|
+
};
|
|
84
|
+
/**
|
|
85
|
+
* Check if a schema has a default value at any wrapping level.
|
|
86
|
+
*
|
|
87
|
+
* Unlike `zod_to_schema_default` (which returns the value), this returns a boolean.
|
|
88
|
+
* Distinguishes "no default" from "default is undefined".
|
|
89
|
+
*
|
|
90
|
+
* @param schema - Zod schema to check
|
|
91
|
+
*/
|
|
92
|
+
export const zod_has_default = (schema) => {
|
|
93
|
+
const def = schema._zod.def;
|
|
94
|
+
if ('defaultValue' in def)
|
|
95
|
+
return true;
|
|
96
|
+
const sub = zod_to_subschema(def);
|
|
97
|
+
if (sub)
|
|
98
|
+
return zod_has_default(sub);
|
|
99
|
+
return false;
|
|
100
|
+
};
|
|
101
|
+
/**
|
|
102
|
+
* Unwrap a schema to find the inner `ZodObject`, or `null` if not an object schema.
|
|
103
|
+
* Handles wrappers like `z.strictObject({...}).default({...})`.
|
|
104
|
+
*
|
|
105
|
+
* @param schema - Zod schema to unwrap
|
|
106
|
+
* @returns the inner ZodObject or null
|
|
107
|
+
*/
|
|
108
|
+
export const zod_unwrap_to_object = (schema) => {
|
|
109
|
+
const def = zod_unwrap_def(schema);
|
|
110
|
+
if (def.type !== 'object')
|
|
111
|
+
return null;
|
|
112
|
+
let s = schema;
|
|
113
|
+
while (s._zod.def.type !== 'object') {
|
|
114
|
+
const sub = zod_to_subschema(s._zod.def);
|
|
115
|
+
if (!sub)
|
|
116
|
+
return null;
|
|
117
|
+
s = sub;
|
|
118
|
+
}
|
|
119
|
+
return s;
|
|
120
|
+
};
|
|
121
|
+
/**
|
|
122
|
+
* Extract field metadata from a Zod object schema.
|
|
123
|
+
*
|
|
124
|
+
* @param schema - Zod object schema to extract from
|
|
125
|
+
* @returns array of field info for each property
|
|
126
|
+
*/
|
|
127
|
+
export const zod_extract_fields = (schema) => {
|
|
128
|
+
const fields = [];
|
|
129
|
+
for (const [name, field_schema] of Object.entries(schema.shape)) {
|
|
130
|
+
const field = field_schema;
|
|
131
|
+
fields.push({
|
|
132
|
+
name,
|
|
133
|
+
base_type: zod_get_base_type(field),
|
|
134
|
+
required: !zod_is_optional(field),
|
|
135
|
+
has_default: zod_has_default(field),
|
|
136
|
+
nullable: zod_is_nullable(field),
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
return fields;
|
|
140
|
+
};
|
|
141
|
+
// --- Metadata extraction ---
|
|
30
142
|
/**
|
|
31
143
|
* Get the description from a schema's metadata, unwrapping if needed.
|
|
32
144
|
*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fuzdev/fuz_util",
|
|
3
|
-
"version": "0.53.
|
|
3
|
+
"version": "0.53.4",
|
|
4
4
|
"description": "utility belt for JS",
|
|
5
5
|
"glyph": "🦕",
|
|
6
6
|
"logo": "logo.svg",
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
"@fuzdev/fuz_ui": "^0.185.2",
|
|
82
82
|
"@fuzdev/gro": "^0.197.0",
|
|
83
83
|
"@jridgewell/trace-mapping": "^0.3.31",
|
|
84
|
-
"@ryanatkn/eslint-config": "^0.10.
|
|
84
|
+
"@ryanatkn/eslint-config": "^0.10.1",
|
|
85
85
|
"@sveltejs/adapter-static": "^3.0.10",
|
|
86
86
|
"@sveltejs/kit": "^2.50.1",
|
|
87
87
|
"@sveltejs/package": "^2.5.7",
|
package/src/lib/hash_blake3.ts
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
* @module
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
+
import {z} from 'zod';
|
|
11
12
|
import {hash, init} from '@fuzdev/blake3_wasm';
|
|
12
13
|
|
|
13
14
|
import {to_hex} from './hex.js';
|
|
@@ -27,3 +28,9 @@ export const blake3_ready = init();
|
|
|
27
28
|
* @returns 64-character hexadecimal hash string (32 bytes).
|
|
28
29
|
*/
|
|
29
30
|
export const hash_blake3 = (data: BufferSource | string): string => to_hex(hash(to_bytes(data)));
|
|
31
|
+
|
|
32
|
+
/** Zod schema for a BLAKE3 hex hash — 64 lowercase hex characters (256-bit output). */
|
|
33
|
+
export const Blake3Hash = z
|
|
34
|
+
.string()
|
|
35
|
+
.regex(/^[0-9a-f]{64}$/, 'Expected a 64-character lowercase hex blake3 hash');
|
|
36
|
+
export type Blake3Hash = z.infer<typeof Blake3Hash>;
|
package/src/lib/zod.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Zod schema introspection utilities.
|
|
3
3
|
*
|
|
4
|
-
* Generic helpers for extracting metadata from Zod schemas.
|
|
5
|
-
*
|
|
4
|
+
* Generic helpers for walking, unwrapping, and extracting metadata from Zod schemas.
|
|
5
|
+
* Used by CLI argument parsing, adversarial input testing, and surface generation.
|
|
6
6
|
*
|
|
7
7
|
* @module
|
|
8
8
|
*/
|
|
@@ -30,6 +30,131 @@ export const zod_to_subschema = (def: z.core.$ZodTypeDef): z.ZodType | undefined
|
|
|
30
30
|
return undefined;
|
|
31
31
|
};
|
|
32
32
|
|
|
33
|
+
/** Zod wrapper type names that `zod_unwrap_def` traverses through. */
|
|
34
|
+
export const ZOD_WRAPPER_TYPES = new Set([
|
|
35
|
+
'optional',
|
|
36
|
+
'nullable',
|
|
37
|
+
'default',
|
|
38
|
+
'transform',
|
|
39
|
+
'pipe',
|
|
40
|
+
'prefault',
|
|
41
|
+
]);
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Unwrap Zod wrappers (optional, default, nullable, pipe, transform)
|
|
45
|
+
* to get the base type definition.
|
|
46
|
+
*
|
|
47
|
+
* @param schema - Zod schema to unwrap
|
|
48
|
+
* @returns the innermost non-wrapper type definition
|
|
49
|
+
*/
|
|
50
|
+
export const zod_unwrap_def = (schema: z.ZodType): z.core.$ZodTypeDef => {
|
|
51
|
+
const def = schema._zod.def;
|
|
52
|
+
if (ZOD_WRAPPER_TYPES.has(def.type)) {
|
|
53
|
+
const sub = zod_to_subschema(def);
|
|
54
|
+
if (sub) return zod_unwrap_def(sub);
|
|
55
|
+
}
|
|
56
|
+
return def;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Get the base type name for a Zod schema, unwrapping all wrappers.
|
|
61
|
+
*
|
|
62
|
+
* @param schema - Zod schema to inspect
|
|
63
|
+
* @returns base type name (e.g. `'string'`, `'object'`, `'uuid'`)
|
|
64
|
+
*/
|
|
65
|
+
export const zod_get_base_type = (schema: z.ZodType): string => zod_unwrap_def(schema).type;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Check if a schema is optional at the outermost level.
|
|
69
|
+
*
|
|
70
|
+
* @param schema - Zod schema to check
|
|
71
|
+
*/
|
|
72
|
+
export const zod_is_optional = (schema: z.ZodType): boolean => schema._zod.def.type === 'optional';
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Check if a schema accepts null at any wrapping level.
|
|
76
|
+
*
|
|
77
|
+
* @param schema - Zod schema to check
|
|
78
|
+
*/
|
|
79
|
+
export const zod_is_nullable = (schema: z.ZodType): boolean => {
|
|
80
|
+
const def = schema._zod.def;
|
|
81
|
+
if (def.type === 'nullable') return true;
|
|
82
|
+
if (ZOD_WRAPPER_TYPES.has(def.type)) {
|
|
83
|
+
const sub = zod_to_subschema(def);
|
|
84
|
+
if (sub) return zod_is_nullable(sub);
|
|
85
|
+
}
|
|
86
|
+
return false;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Check if a schema has a default value at any wrapping level.
|
|
91
|
+
*
|
|
92
|
+
* Unlike `zod_to_schema_default` (which returns the value), this returns a boolean.
|
|
93
|
+
* Distinguishes "no default" from "default is undefined".
|
|
94
|
+
*
|
|
95
|
+
* @param schema - Zod schema to check
|
|
96
|
+
*/
|
|
97
|
+
export const zod_has_default = (schema: z.ZodType): boolean => {
|
|
98
|
+
const def = schema._zod.def;
|
|
99
|
+
if ('defaultValue' in def) return true;
|
|
100
|
+
const sub = zod_to_subschema(def);
|
|
101
|
+
if (sub) return zod_has_default(sub);
|
|
102
|
+
return false;
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Unwrap a schema to find the inner `ZodObject`, or `null` if not an object schema.
|
|
107
|
+
* Handles wrappers like `z.strictObject({...}).default({...})`.
|
|
108
|
+
*
|
|
109
|
+
* @param schema - Zod schema to unwrap
|
|
110
|
+
* @returns the inner ZodObject or null
|
|
111
|
+
*/
|
|
112
|
+
export const zod_unwrap_to_object = (schema: z.ZodType): z.ZodObject | null => {
|
|
113
|
+
const def = zod_unwrap_def(schema);
|
|
114
|
+
if (def.type !== 'object') return null;
|
|
115
|
+
let s: z.ZodType = schema;
|
|
116
|
+
while (s._zod.def.type !== 'object') {
|
|
117
|
+
const sub = zod_to_subschema(s._zod.def);
|
|
118
|
+
if (!sub) return null;
|
|
119
|
+
s = sub;
|
|
120
|
+
}
|
|
121
|
+
return s as z.ZodObject;
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
// --- Field extraction ---
|
|
125
|
+
|
|
126
|
+
/** Metadata extracted from a single field of a Zod object schema. */
|
|
127
|
+
export interface ZodFieldInfo {
|
|
128
|
+
name: string;
|
|
129
|
+
base_type: string;
|
|
130
|
+
required: boolean;
|
|
131
|
+
has_default: boolean;
|
|
132
|
+
nullable: boolean;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Extract field metadata from a Zod object schema.
|
|
137
|
+
*
|
|
138
|
+
* @param schema - Zod object schema to extract from
|
|
139
|
+
* @returns array of field info for each property
|
|
140
|
+
*/
|
|
141
|
+
export const zod_extract_fields = (schema: z.ZodObject): Array<ZodFieldInfo> => {
|
|
142
|
+
const fields: Array<ZodFieldInfo> = [];
|
|
143
|
+
for (const [name, field_schema] of Object.entries(schema.shape)) {
|
|
144
|
+
const field = field_schema as z.ZodType;
|
|
145
|
+
fields.push({
|
|
146
|
+
name,
|
|
147
|
+
base_type: zod_get_base_type(field),
|
|
148
|
+
required: !zod_is_optional(field),
|
|
149
|
+
has_default: zod_has_default(field),
|
|
150
|
+
nullable: zod_is_nullable(field),
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
return fields;
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
// --- Metadata extraction ---
|
|
157
|
+
|
|
33
158
|
/**
|
|
34
159
|
* Get the description from a schema's metadata, unwrapping if needed.
|
|
35
160
|
*
|