ont-run 0.0.6 → 0.0.8

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/index.js CHANGED
@@ -13892,57 +13892,19 @@ var init_zod = __esm(() => {
13892
13892
  init_external();
13893
13893
  });
13894
13894
 
13895
- // src/config/categorical.ts
13896
- function fieldFrom(functionName) {
13897
- const schema = exports_external.string();
13898
- schema[FIELD_FROM_METADATA] = { functionName };
13899
- return schema;
13900
- }
13901
- function hasFieldFromMetadata(schema) {
13902
- return schema !== null && typeof schema === "object" && FIELD_FROM_METADATA in schema;
13903
- }
13904
- function getFieldFromMetadata(schema) {
13905
- if (hasFieldFromMetadata(schema)) {
13906
- return schema[FIELD_FROM_METADATA];
13907
- }
13908
- return null;
13909
- }
13910
- function userContext(schema) {
13911
- const marked = schema;
13912
- marked[USER_CONTEXT_METADATA] = true;
13913
- return marked;
13914
- }
13915
- function hasUserContextMetadata(schema) {
13916
- return schema !== null && typeof schema === "object" && USER_CONTEXT_METADATA in schema && schema[USER_CONTEXT_METADATA] === true;
13917
- }
13918
- function getUserContextFields(schema) {
13919
- const fields = [];
13920
- const def = schema._def;
13921
- if (def?.typeName === "ZodObject" && typeof def.shape === "function") {
13922
- const shape = def.shape();
13923
- for (const [key, value] of Object.entries(shape)) {
13924
- if (hasUserContextMetadata(value)) {
13925
- fields.push(key);
13926
- }
13927
- }
13928
- }
13929
- return fields;
13930
- }
13931
- var FIELD_FROM_METADATA, USER_CONTEXT_METADATA;
13932
- var init_categorical = __esm(() => {
13933
- init_zod();
13934
- FIELD_FROM_METADATA = Symbol.for("ont:fieldFrom");
13935
- USER_CONTEXT_METADATA = Symbol.for("ont:userContext");
13936
- });
13937
-
13938
13895
  // src/config/zod-utils.ts
13896
+ function isZod3Schema(val) {
13897
+ if (val === null || typeof val !== "object")
13898
+ return false;
13899
+ if ("_def" in val && "safeParse" in val && !("_zod" in val))
13900
+ return true;
13901
+ return false;
13902
+ }
13939
13903
  function isZodSchema(val) {
13940
13904
  if (val === null || typeof val !== "object")
13941
13905
  return false;
13942
13906
  if ("_zod" in val && "safeParse" in val)
13943
13907
  return true;
13944
- if ("_def" in val && "safeParse" in val)
13945
- return true;
13946
13908
  return false;
13947
13909
  }
13948
13910
  function getZodTypeName(schema) {
@@ -13951,38 +13913,39 @@ function getZodTypeName(schema) {
13951
13913
  const s = schema;
13952
13914
  if (s._zod && typeof s._zod === "object") {
13953
13915
  const zod = s._zod;
13916
+ if (zod.traits && zod.traits instanceof Set) {
13917
+ const traits = Array.from(zod.traits);
13918
+ const zodType = traits.find((t) => t.startsWith("Zod") && !t.startsWith("$") && !t.startsWith("_"));
13919
+ if (zodType)
13920
+ return zodType;
13921
+ }
13954
13922
  if (zod.def && typeof zod.def === "object") {
13955
13923
  const def = zod.def;
13956
13924
  if (typeof def.typeName === "string")
13957
13925
  return def.typeName;
13958
13926
  }
13959
13927
  }
13960
- if (s._def && typeof s._def === "object") {
13961
- const def = s._def;
13962
- if (typeof def.typeName === "string")
13963
- return def.typeName;
13964
- }
13965
13928
  return;
13966
13929
  }
13967
13930
  function isZodObject(schema) {
13968
13931
  const typeName = getZodTypeName(schema);
13969
- return typeName === "ZodObject" || typeName === "object";
13932
+ return typeName === "ZodObject";
13970
13933
  }
13971
13934
  function isZodOptional(schema) {
13972
13935
  const typeName = getZodTypeName(schema);
13973
- return typeName === "ZodOptional" || typeName === "optional";
13936
+ return typeName === "ZodOptional";
13974
13937
  }
13975
13938
  function isZodNullable(schema) {
13976
13939
  const typeName = getZodTypeName(schema);
13977
- return typeName === "ZodNullable" || typeName === "nullable";
13940
+ return typeName === "ZodNullable";
13978
13941
  }
13979
13942
  function isZodArray(schema) {
13980
13943
  const typeName = getZodTypeName(schema);
13981
- return typeName === "ZodArray" || typeName === "array";
13944
+ return typeName === "ZodArray";
13982
13945
  }
13983
13946
  function isZodDefault(schema) {
13984
13947
  const typeName = getZodTypeName(schema);
13985
- return typeName === "ZodDefault" || typeName === "default";
13948
+ return typeName === "ZodDefault";
13986
13949
  }
13987
13950
  function getObjectShape(schema) {
13988
13951
  if (!isZodObject(schema))
@@ -13992,12 +13955,15 @@ function getObjectShape(schema) {
13992
13955
  const zod = s._zod;
13993
13956
  if (zod.def && typeof zod.def === "object") {
13994
13957
  const def = zod.def;
13995
- if (def.shape && typeof def.shape === "object") {
13996
- return def.shape;
13958
+ if (def.shape) {
13959
+ const shape = def.shape;
13960
+ if (typeof shape === "object" && shape !== null) {
13961
+ return shape;
13962
+ }
13997
13963
  }
13998
13964
  }
13999
13965
  }
14000
- if (typeof s.shape === "object" && s.shape !== null) {
13966
+ if ("shape" in s && s.shape && typeof s.shape === "object") {
14001
13967
  return s.shape;
14002
13968
  }
14003
13969
  return;
@@ -14012,14 +13978,6 @@ function getInnerSchema(schema) {
14012
13978
  return def.innerType;
14013
13979
  }
14014
13980
  }
14015
- if (typeof s.unwrap === "function") {
14016
- return s.unwrap();
14017
- }
14018
- if (s._def && typeof s._def === "object") {
14019
- const def = s._def;
14020
- if (def.innerType)
14021
- return def.innerType;
14022
- }
14023
13981
  return;
14024
13982
  }
14025
13983
  function getArrayElement(schema) {
@@ -14034,11 +13992,53 @@ function getArrayElement(schema) {
14034
13992
  return def.element;
14035
13993
  }
14036
13994
  }
14037
- if (s.element)
14038
- return s.element;
14039
13995
  return;
14040
13996
  }
14041
13997
 
13998
+ // src/config/categorical.ts
13999
+ function fieldFrom(functionName) {
14000
+ const schema = exports_external.string();
14001
+ schema[FIELD_FROM_METADATA] = { functionName };
14002
+ return schema;
14003
+ }
14004
+ function hasFieldFromMetadata(schema) {
14005
+ return schema !== null && typeof schema === "object" && FIELD_FROM_METADATA in schema;
14006
+ }
14007
+ function getFieldFromMetadata(schema) {
14008
+ if (hasFieldFromMetadata(schema)) {
14009
+ return schema[FIELD_FROM_METADATA];
14010
+ }
14011
+ return null;
14012
+ }
14013
+ function userContext(schema) {
14014
+ const marked = schema;
14015
+ marked[USER_CONTEXT_METADATA] = true;
14016
+ return marked;
14017
+ }
14018
+ function hasUserContextMetadata(schema) {
14019
+ return schema !== null && typeof schema === "object" && USER_CONTEXT_METADATA in schema && schema[USER_CONTEXT_METADATA] === true;
14020
+ }
14021
+ function getUserContextFields(schema) {
14022
+ const fields = [];
14023
+ if (isZodObject(schema)) {
14024
+ const shape = getObjectShape(schema);
14025
+ if (shape) {
14026
+ for (const [key, value] of Object.entries(shape)) {
14027
+ if (hasUserContextMetadata(value)) {
14028
+ fields.push(key);
14029
+ }
14030
+ }
14031
+ }
14032
+ }
14033
+ return fields;
14034
+ }
14035
+ var FIELD_FROM_METADATA, USER_CONTEXT_METADATA;
14036
+ var init_categorical = __esm(() => {
14037
+ init_zod();
14038
+ FIELD_FROM_METADATA = Symbol.for("ont:fieldFrom");
14039
+ USER_CONTEXT_METADATA = Symbol.for("ont:userContext");
14040
+ });
14041
+
14042
14042
  // node_modules/consola/dist/chunks/prompt.mjs
14043
14043
  var exports_prompt = {};
14044
14044
  __export(exports_prompt, {
@@ -22094,15 +22094,24 @@ var EntityDefinitionSchema = exports_external.object({
22094
22094
  function isFunction(val) {
22095
22095
  return typeof val === "function";
22096
22096
  }
22097
+ function validateZodSchema(val, fieldName) {
22098
+ if (isZodSchema(val))
22099
+ return true;
22100
+ if (isZod3Schema(val)) {
22101
+ throw new Error(`${fieldName} appears to be a Zod 3 schema. ont-run requires Zod 4.
22102
+ ` + `Please upgrade: bun add zod@4`);
22103
+ }
22104
+ return false;
22105
+ }
22097
22106
  var FunctionDefinitionSchema = exports_external.object({
22098
22107
  description: exports_external.string(),
22099
22108
  access: exports_external.array(exports_external.string()).min(1),
22100
22109
  entities: exports_external.array(exports_external.string()),
22101
- inputs: exports_external.custom(isZodSchema, {
22102
- message: "inputs must be a Zod schema"
22110
+ inputs: exports_external.custom((val) => validateZodSchema(val, "inputs"), {
22111
+ message: "inputs must be a Zod 4 schema"
22103
22112
  }),
22104
- outputs: exports_external.custom(isZodSchema, {
22105
- message: "outputs must be a Zod schema"
22113
+ outputs: exports_external.custom((val) => validateZodSchema(val, "outputs"), {
22114
+ message: "outputs must be a Zod 4 schema"
22106
22115
  }).optional(),
22107
22116
  resolver: exports_external.custom(isFunction, {
22108
22117
  message: "resolver must be a function"
@@ -132,7 +132,6 @@ export declare function hasUserContextMetadata(schema: unknown): schema is UserC
132
132
  /**
133
133
  * Get all userContext field names from a Zod object schema
134
134
  *
135
- * Note: Uses _def.typeName check instead of instanceof to work across
136
- * module boundaries in bundled CLI.
135
+ * Note: Uses zod-utils for bundler compatibility (instanceof fails across module boundaries)
137
136
  */
138
137
  export declare function getUserContextFields(schema: z.ZodType): string[];
@@ -1,44 +1,48 @@
1
1
  /**
2
- * Utility functions for inspecting Zod schemas.
3
- * These use duck typing to work across Zod 3 and Zod 4.
2
+ * Utility functions for inspecting Zod 4 schemas.
3
+ * These use duck typing to work across bundle boundaries.
4
4
  */
5
5
  /**
6
- * Check if a value is a Zod schema (duck typing to work across bundle boundaries and Zod versions)
6
+ * Check if a value is a Zod 3 schema (has _def but not _zod)
7
+ */
8
+ export declare function isZod3Schema(val: unknown): boolean;
9
+ /**
10
+ * Check if a value is a Zod schema (duck typing to work across bundle boundaries)
7
11
  */
8
12
  export declare function isZodSchema(val: unknown): boolean;
9
13
  /**
10
- * Get the Zod type name from a schema (works with both Zod 3 and 4)
14
+ * Get the Zod type name from a schema
11
15
  */
12
16
  export declare function getZodTypeName(schema: unknown): string | undefined;
13
17
  /**
14
- * Check if schema is a ZodObject (works with both Zod 3 and 4)
18
+ * Check if schema is a ZodObject
15
19
  */
16
20
  export declare function isZodObject(schema: unknown): boolean;
17
21
  /**
18
- * Check if schema is a ZodOptional (works with both Zod 3 and 4)
22
+ * Check if schema is a ZodOptional
19
23
  */
20
24
  export declare function isZodOptional(schema: unknown): boolean;
21
25
  /**
22
- * Check if schema is a ZodNullable (works with both Zod 3 and 4)
26
+ * Check if schema is a ZodNullable
23
27
  */
24
28
  export declare function isZodNullable(schema: unknown): boolean;
25
29
  /**
26
- * Check if schema is a ZodArray (works with both Zod 3 and 4)
30
+ * Check if schema is a ZodArray
27
31
  */
28
32
  export declare function isZodArray(schema: unknown): boolean;
29
33
  /**
30
- * Check if schema is a ZodDefault (works with both Zod 3 and 4)
34
+ * Check if schema is a ZodDefault
31
35
  */
32
36
  export declare function isZodDefault(schema: unknown): boolean;
33
37
  /**
34
- * Get the shape of a ZodObject schema (works with both Zod 3 and 4)
38
+ * Get the shape of a ZodObject schema
35
39
  */
36
40
  export declare function getObjectShape(schema: unknown): Record<string, unknown> | undefined;
37
41
  /**
38
- * Get the inner schema from Optional/Nullable/Default (works with both Zod 3 and 4)
42
+ * Get the inner schema from Optional/Nullable/Default
39
43
  */
40
44
  export declare function getInnerSchema(schema: unknown): unknown;
41
45
  /**
42
- * Get the element schema from a ZodArray (works with both Zod 3 and 4)
46
+ * Get the element schema from a ZodArray
43
47
  */
44
48
  export declare function getArrayElement(schema: unknown): unknown;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ont-run",
3
- "version": "0.0.6",
3
+ "version": "0.0.8",
4
4
  "description": "Ontology-enforced API framework for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {
@@ -21,7 +21,7 @@
21
21
  "scripts": {
22
22
  "dev": "bun run bin/ont.ts",
23
23
  "build": "bun build ./src/index.ts --outdir ./dist --target node",
24
- "build:cli": "bun build ./bin/ont.ts --outfile ./dist/bin/ont.js --target node --external @modelcontextprotocol/sdk",
24
+ "build:cli": "bun build ./bin/ont.ts --outfile ./dist/bin/ont.js --target node --external @modelcontextprotocol/sdk --external zod",
25
25
  "build:types": "tsc --declaration --emitDeclarationOnly",
26
26
  "prepublishOnly": "bun run build && bun run build:cli && bun run build:types",
27
27
  "docs": "cd docs && bun run dev",
@@ -34,15 +34,16 @@
34
34
  "citty": "^0.1.6",
35
35
  "consola": "^3.2.0",
36
36
  "hono": "^4.6.0",
37
- "open": "^10.0.0",
38
- "zod": "4"
37
+ "open": "^10.0.0"
39
38
  },
40
39
  "devDependencies": {
41
40
  "@types/bun": "latest",
42
- "typescript": "^5.5.0"
41
+ "typescript": "^5.5.0",
42
+ "zod": "^4.0.0"
43
43
  },
44
44
  "peerDependencies": {
45
- "bun": ">=1.0.0"
45
+ "bun": ">=1.0.0",
46
+ "zod": ">=4"
46
47
  },
47
48
  "peerDependenciesMeta": {
48
49
  "bun": {
@@ -1,4 +1,5 @@
1
1
  import { z } from "zod";
2
+ import { isZodObject, getObjectShape } from "./zod-utils";
2
3
 
3
4
  /**
4
5
  * Symbol for storing fieldFrom metadata on Zod schemas
@@ -175,19 +176,18 @@ export function hasUserContextMetadata(
175
176
  /**
176
177
  * Get all userContext field names from a Zod object schema
177
178
  *
178
- * Note: Uses _def.typeName check instead of instanceof to work across
179
- * module boundaries in bundled CLI.
179
+ * Note: Uses zod-utils for bundler compatibility (instanceof fails across module boundaries)
180
180
  */
181
181
  export function getUserContextFields(schema: z.ZodType): string[] {
182
182
  const fields: string[] = [];
183
183
 
184
- // Use _def.typeName check for bundler compatibility (instanceof fails across module boundaries)
185
- const def = (schema as unknown as { _def?: { typeName?: string; shape?: () => Record<string, unknown> } })._def;
186
- if (def?.typeName === "ZodObject" && typeof def.shape === "function") {
187
- const shape = def.shape();
188
- for (const [key, value] of Object.entries(shape)) {
189
- if (hasUserContextMetadata(value)) {
190
- fields.push(key);
184
+ if (isZodObject(schema)) {
185
+ const shape = getObjectShape(schema);
186
+ if (shape) {
187
+ for (const [key, value] of Object.entries(shape)) {
188
+ if (hasUserContextMetadata(value)) {
189
+ fields.push(key);
190
+ }
191
191
  }
192
192
  }
193
193
  }
@@ -2,6 +2,7 @@ import { z } from "zod";
2
2
  import { getFieldFromMetadata, getUserContextFields } from "./categorical.js";
3
3
  import {
4
4
  isZodSchema,
5
+ isZod3Schema,
5
6
  isZodObject,
6
7
  isZodOptional,
7
8
  isZodNullable,
@@ -43,6 +44,20 @@ function isFunction(val: unknown): val is (...args: unknown[]) => unknown {
43
44
  return typeof val === "function";
44
45
  }
45
46
 
47
+ /**
48
+ * Validate that a value is a Zod 4 schema, with helpful error for Zod 3
49
+ */
50
+ function validateZodSchema(val: unknown, fieldName: string): boolean {
51
+ if (isZodSchema(val)) return true;
52
+ if (isZod3Schema(val)) {
53
+ throw new Error(
54
+ `${fieldName} appears to be a Zod 3 schema. ont-run requires Zod 4.\n` +
55
+ `Please upgrade: bun add zod@4`
56
+ );
57
+ }
58
+ return false;
59
+ }
60
+
46
61
  /**
47
62
  * Schema for function definition
48
63
  */
@@ -50,12 +65,12 @@ export const FunctionDefinitionSchema = z.object({
50
65
  description: z.string(),
51
66
  access: z.array(z.string()).min(1),
52
67
  entities: z.array(z.string()),
53
- inputs: z.custom<z.ZodType>(isZodSchema, {
54
- message: "inputs must be a Zod schema",
68
+ inputs: z.custom<z.ZodType>((val) => validateZodSchema(val, "inputs"), {
69
+ message: "inputs must be a Zod 4 schema",
55
70
  }),
56
71
  outputs: z
57
- .custom<z.ZodType>(isZodSchema, {
58
- message: "outputs must be a Zod schema",
72
+ .custom<z.ZodType>((val) => validateZodSchema(val, "outputs"), {
73
+ message: "outputs must be a Zod 4 schema",
59
74
  })
60
75
  .optional(),
61
76
  resolver: z.custom<(...args: unknown[]) => unknown>(isFunction, {
@@ -1,107 +1,122 @@
1
1
  /**
2
- * Utility functions for inspecting Zod schemas.
3
- * These use duck typing to work across Zod 3 and Zod 4.
2
+ * Utility functions for inspecting Zod 4 schemas.
3
+ * These use duck typing to work across bundle boundaries.
4
4
  */
5
5
 
6
6
  /**
7
- * Check if a value is a Zod schema (duck typing to work across bundle boundaries and Zod versions)
7
+ * Check if a value is a Zod 3 schema (has _def but not _zod)
8
+ */
9
+ export function isZod3Schema(val: unknown): boolean {
10
+ if (val === null || typeof val !== "object") return false;
11
+ // Zod 3 uses _def property without _zod
12
+ if ("_def" in val && "safeParse" in val && !("_zod" in val)) return true;
13
+ return false;
14
+ }
15
+
16
+ /**
17
+ * Check if a value is a Zod schema (duck typing to work across bundle boundaries)
8
18
  */
9
19
  export function isZodSchema(val: unknown): boolean {
10
20
  if (val === null || typeof val !== "object") return false;
11
21
  // Zod 4 uses _zod property
12
22
  if ("_zod" in val && "safeParse" in val) return true;
13
- // Zod 3 uses _def property
14
- if ("_def" in val && "safeParse" in val) return true;
15
23
  return false;
16
24
  }
17
25
 
18
26
  /**
19
- * Get the Zod type name from a schema (works with both Zod 3 and 4)
27
+ * Get the Zod type name from a schema
20
28
  */
21
29
  export function getZodTypeName(schema: unknown): string | undefined {
22
30
  if (!isZodSchema(schema)) return undefined;
23
31
  const s = schema as Record<string, unknown>;
24
- // Zod 4: check _zod.def.typeName
32
+ // Zod 4: check _zod.traits for type name
25
33
  if (s._zod && typeof s._zod === "object") {
26
34
  const zod = s._zod as Record<string, unknown>;
35
+ // Check traits Set for the Zod type name
36
+ if (zod.traits && zod.traits instanceof Set) {
37
+ const traits = Array.from(zod.traits as Set<string>);
38
+ // Find the main type name (e.g., "ZodObject", "ZodString", etc.)
39
+ const zodType = traits.find(t => t.startsWith('Zod') && !t.startsWith('$') && !t.startsWith('_'));
40
+ if (zodType) return zodType;
41
+ }
42
+ // Fallback: check _zod.def.typeName for older versions
27
43
  if (zod.def && typeof zod.def === "object") {
28
44
  const def = zod.def as Record<string, unknown>;
29
45
  if (typeof def.typeName === "string") return def.typeName;
30
46
  }
31
47
  }
32
- // Zod 3: check _def.typeName
33
- if (s._def && typeof s._def === "object") {
34
- const def = s._def as Record<string, unknown>;
35
- if (typeof def.typeName === "string") return def.typeName;
36
- }
37
48
  return undefined;
38
49
  }
39
50
 
40
51
  /**
41
- * Check if schema is a ZodObject (works with both Zod 3 and 4)
52
+ * Check if schema is a ZodObject
42
53
  */
43
54
  export function isZodObject(schema: unknown): boolean {
44
55
  const typeName = getZodTypeName(schema);
45
- return typeName === "ZodObject" || typeName === "object";
56
+ return typeName === "ZodObject";
46
57
  }
47
58
 
48
59
  /**
49
- * Check if schema is a ZodOptional (works with both Zod 3 and 4)
60
+ * Check if schema is a ZodOptional
50
61
  */
51
62
  export function isZodOptional(schema: unknown): boolean {
52
63
  const typeName = getZodTypeName(schema);
53
- return typeName === "ZodOptional" || typeName === "optional";
64
+ return typeName === "ZodOptional";
54
65
  }
55
66
 
56
67
  /**
57
- * Check if schema is a ZodNullable (works with both Zod 3 and 4)
68
+ * Check if schema is a ZodNullable
58
69
  */
59
70
  export function isZodNullable(schema: unknown): boolean {
60
71
  const typeName = getZodTypeName(schema);
61
- return typeName === "ZodNullable" || typeName === "nullable";
72
+ return typeName === "ZodNullable";
62
73
  }
63
74
 
64
75
  /**
65
- * Check if schema is a ZodArray (works with both Zod 3 and 4)
76
+ * Check if schema is a ZodArray
66
77
  */
67
78
  export function isZodArray(schema: unknown): boolean {
68
79
  const typeName = getZodTypeName(schema);
69
- return typeName === "ZodArray" || typeName === "array";
80
+ return typeName === "ZodArray";
70
81
  }
71
82
 
72
83
  /**
73
- * Check if schema is a ZodDefault (works with both Zod 3 and 4)
84
+ * Check if schema is a ZodDefault
74
85
  */
75
86
  export function isZodDefault(schema: unknown): boolean {
76
87
  const typeName = getZodTypeName(schema);
77
- return typeName === "ZodDefault" || typeName === "default";
88
+ return typeName === "ZodDefault";
78
89
  }
79
90
 
80
91
  /**
81
- * Get the shape of a ZodObject schema (works with both Zod 3 and 4)
92
+ * Get the shape of a ZodObject schema
82
93
  */
83
94
  export function getObjectShape(schema: unknown): Record<string, unknown> | undefined {
84
95
  if (!isZodObject(schema)) return undefined;
85
96
  const s = schema as Record<string, unknown>;
86
- // Zod 4: shape is in _zod.def.shape
97
+ // Zod 4: shape is in _zod.def.shape (may be a getter)
87
98
  if (s._zod && typeof s._zod === "object") {
88
99
  const zod = s._zod as Record<string, unknown>;
89
100
  if (zod.def && typeof zod.def === "object") {
90
101
  const def = zod.def as Record<string, unknown>;
91
- if (def.shape && typeof def.shape === "object") {
92
- return def.shape as Record<string, unknown>;
102
+ if (def.shape) {
103
+ // In Zod 4, shape might be a getter, so access it
104
+ const shape = def.shape;
105
+ if (typeof shape === "object" && shape !== null) {
106
+ return shape as Record<string, unknown>;
107
+ }
93
108
  }
94
109
  }
95
110
  }
96
- // Zod 3: shape property directly on schema
97
- if (typeof s.shape === "object" && s.shape !== null) {
111
+ // Fallback: try accessing .shape directly on the schema
112
+ if ('shape' in s && s.shape && typeof s.shape === "object") {
98
113
  return s.shape as Record<string, unknown>;
99
114
  }
100
115
  return undefined;
101
116
  }
102
117
 
103
118
  /**
104
- * Get the inner schema from Optional/Nullable/Default (works with both Zod 3 and 4)
119
+ * Get the inner schema from Optional/Nullable/Default
105
120
  */
106
121
  export function getInnerSchema(schema: unknown): unknown {
107
122
  const s = schema as Record<string, unknown>;
@@ -113,19 +128,11 @@ export function getInnerSchema(schema: unknown): unknown {
113
128
  if (def.innerType) return def.innerType;
114
129
  }
115
130
  }
116
- // Zod 3: unwrap method or _def.innerType
117
- if (typeof s.unwrap === "function") {
118
- return (s.unwrap as () => unknown)();
119
- }
120
- if (s._def && typeof s._def === "object") {
121
- const def = s._def as Record<string, unknown>;
122
- if (def.innerType) return def.innerType;
123
- }
124
131
  return undefined;
125
132
  }
126
133
 
127
134
  /**
128
- * Get the element schema from a ZodArray (works with both Zod 3 and 4)
135
+ * Get the element schema from a ZodArray
129
136
  */
130
137
  export function getArrayElement(schema: unknown): unknown {
131
138
  if (!isZodArray(schema)) return undefined;
@@ -138,7 +145,5 @@ export function getArrayElement(schema: unknown): unknown {
138
145
  if (def.element) return def.element;
139
146
  }
140
147
  }
141
- // Zod 3: element property directly on schema
142
- if (s.element) return s.element;
143
148
  return undefined;
144
149
  }