@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.
@@ -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;AAOH;;;;GAIG;AACH,eAAO,MAAM,YAAY,eAAS,CAAC;AAEnC;;;;;GAKG;AACH,eAAO,MAAM,WAAW,GAAI,MAAM,YAAY,GAAG,MAAM,KAAG,MAAsC,CAAC"}
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"}
@@ -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
- * Designed for CLI argument parsing but applicable elsewhere.
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
- * Designed for CLI argument parsing but applicable elsewhere.
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.2",
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.0",
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",
@@ -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
- * Designed for CLI argument parsing but applicable elsewhere.
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
  *