11import type { AxiosInstance } from "axios" ;
2+ import type { ZodType } from "zod" ;
23
34/**
45 * The type of data source to extract from.
@@ -9,20 +10,18 @@ export type ExtractType = "url" | "text";
910
1011/**
1112 * JSON Schema definition for structured extraction output.
12- * Must conform to JSON Schema specification.
13+ */
14+ export interface JsonSchema {
15+ [ key : string ] : unknown ;
16+ }
17+
18+ /**
19+ * Schema for structured extraction output.
20+ * Can be either a JSON Schema object or a Zod schema.
1321 *
1422 * @example
1523 * ```typescript
16- * // Schema for extracting a table as 2D array
17- * const schema: ExtractSchema = {
18- * type: "array",
19- * items: {
20- * type: "array",
21- * items: { type: "string" }
22- * }
23- * };
24- *
25- * // Schema for extracting product objects
24+ * // Using JSON Schema
2625 * const schema: ExtractSchema = {
2726 * type: "array",
2827 * items: {
@@ -33,10 +32,62 @@ export type ExtractType = "url" | "text";
3332 * }
3433 * }
3534 * };
35+ *
36+ * // Using Zod schema (requires Zod 3.24+)
37+ * import { z } from "zod/v4";
38+ *
39+ * const schema = z.array(z.object({
40+ * name: z.string(),
41+ * price: z.number()
42+ * }));
3643 * ```
3744 */
38- export interface ExtractSchema {
39- [ key : string ] : unknown ;
45+ export type ExtractSchema = JsonSchema | ZodType ;
46+
47+ /**
48+ * Check if a value is a Zod schema.
49+ */
50+ function isZodSchema ( schema : ExtractSchema ) : schema is ZodType {
51+ return (
52+ schema !== null &&
53+ typeof schema === "object" &&
54+ "_def" in schema &&
55+ "safeParse" in schema &&
56+ typeof ( schema as ZodType ) . safeParse === "function"
57+ ) ;
58+ }
59+
60+ // Cache the zod module to avoid repeated dynamic imports
61+ let zodModule : { toJSONSchema ?: ( schema : ZodType ) => JsonSchema } | null = null ;
62+
63+ /**
64+ * Convert a schema to JSON Schema format.
65+ * If the schema is a Zod schema, it will be converted using Zod's toJSONSchema().
66+ */
67+ async function convertToJsonSchema ( schema : ExtractSchema ) : Promise < JsonSchema > {
68+ if ( isZodSchema ( schema ) ) {
69+ // Try to use cached zod module first
70+ if ( zodModule ?. toJSONSchema ) {
71+ return zodModule . toJSONSchema ( schema ) ;
72+ }
73+
74+ // Dynamically import zod/v4 (works in both ESM and CJS environments)
75+ try {
76+ const z = await import ( "zod/v4" ) ;
77+ if ( z && typeof z . toJSONSchema === "function" ) {
78+ zodModule = z ;
79+ return z . toJSONSchema ( schema ) as JsonSchema ;
80+ }
81+ } catch {
82+ // import failed, zod/v4 not available
83+ }
84+
85+ throw new Error (
86+ "Zod schema conversion requires Zod 3.24+ with zod/v4 subpath. " +
87+ "Please install Zod 3.24+ or use a JSON Schema object directly." ,
88+ ) ;
89+ }
90+ return schema ;
4091}
4192
4293/**
@@ -69,21 +120,30 @@ export interface ExtractRequest {
69120 prompt ?: string ;
70121
71122 /**
72- * Optional JSON Schema for consistent and predictable extraction results.
123+ * Optional schema for consistent and predictable extraction results.
124+ * Can be a JSON Schema object or a Zod schema (requires Zod 3.24+).
73125 * If not provided, the system will auto-generate the structure based on the data.
74126 *
75127 * @example
76- * ```json
77- * {
78- * "type": "array",
79- * "items": {
80- * "type": "object",
81- * "properties": {
82- * "name": { "type": "string" },
83- * "price": { "type": "number" }
128+ * ```typescript
129+ * // Using JSON Schema
130+ * schema: {
131+ * type: "array",
132+ * items: {
133+ * type: "object",
134+ * properties: {
135+ * name: { type: "string" },
136+ * price: { type: "number" }
84137 * }
85138 * }
86139 * }
140+ *
141+ * // Using Zod schema (requires Zod 3.24+)
142+ * import { z } from "zod/v4";
143+ * schema: z.array(z.object({
144+ * name: z.string(),
145+ * price: z.number()
146+ * }))
87147 * ```
88148 */
89149 schema ?: ExtractSchema ;
@@ -151,6 +211,11 @@ export async function extract(
151211 client : AxiosInstance ,
152212 request : ExtractRequest ,
153213) : Promise < ExtractResponse > {
154- const response = await client . post < ExtractResponse > ( "/v1/extract" , request ) ;
214+ // Convert Zod schema to JSON Schema if needed
215+ const payload = request . schema
216+ ? { ...request , schema : await convertToJsonSchema ( request . schema ) }
217+ : request ;
218+
219+ const response = await client . post < ExtractResponse > ( "/v1/extract" , payload ) ;
155220 return response . data ;
156221}
0 commit comments