{"version":3,"file":"schema-to-code.mjs","names":[],"sources":["../../src/codegen/schema-to-code.ts"],"sourcesContent":["import type { StandardSchemaV1 } from '@standard-schema/spec';\nimport { getJsonSchema } from '../core/args.ts';\nimport type { FieldMeta } from './types.ts';\n\ninterface SchemaToCodeResult {\n  /** The generated Zod source code */\n  code: string;\n  /** Imports needed (e.g. ['z']) */\n  imports: string[];\n}\n\n/**\n * Convert a JSON Schema property to Zod code.\n */\nfunction jsonSchemaPropertyToZod(prop: Record<string, any>, required: boolean, ambiguous?: boolean): string {\n  let code: string;\n\n  const type = prop.type as string | undefined;\n  const enumValues = prop.enum as unknown[] | undefined;\n\n  if (enumValues && enumValues.length > 0) {\n    const values = enumValues.map((v) => JSON.stringify(v)).join(', ');\n    code = `z.enum([${values}])`;\n  } else if (type === 'string') {\n    code = 'z.string()';\n  } else if (type === 'number' || type === 'integer') {\n    code = 'z.number()';\n  } else if (type === 'boolean') {\n    code = 'z.boolean()';\n  } else if (type === 'array') {\n    const items = prop.items as Record<string, any> | undefined;\n    const itemCode = items ? jsonSchemaPropertyToZod(items, true) : 'z.unknown()';\n    code = `${itemCode}.array()`;\n  } else {\n    code = 'z.unknown()';\n  }\n\n  if (prop.default !== undefined) {\n    code += `.default(${JSON.stringify(prop.default)})`;\n  } else if (!required) {\n    code += '.optional()';\n  }\n\n  if (prop.description) {\n    code += `.describe(${JSON.stringify(prop.description)})`;\n  }\n\n  if (ambiguous) {\n    code += ' /* TODO: verify type */';\n  }\n\n  return code;\n}\n\n/**\n * Generate Zod source code from a Standard Schema instance by introspecting\n * its `~standard.jsonSchema` interface.\n */\nexport function schemaToCode(schema: StandardSchemaV1): SchemaToCodeResult {\n  try {\n    const jsonSchema = getJsonSchema(schema as any) as Record<string, any>;\n    return jsonSchemaToCode(jsonSchema);\n  } catch {\n    return { code: 'z.unknown()', imports: ['z'] };\n  }\n}\n\nfunction jsonSchemaToCode(jsonSchema: Record<string, any>): SchemaToCodeResult {\n  if (jsonSchema.type === 'object' && jsonSchema.properties) {\n    const properties = jsonSchema.properties as Record<string, any>;\n    const required = new Set((jsonSchema.required as string[]) || []);\n\n    const entries = Object.entries(properties).map(([key, prop]) => {\n      const isRequired = required.has(key);\n      const zodCode = jsonSchemaPropertyToZod(prop as Record<string, any>, isRequired);\n      return `  ${key}: ${zodCode},`;\n    });\n\n    const code = `z.object({\\n${entries.join('\\n')}\\n})`;\n    return { code, imports: ['z'] };\n  }\n\n  // Fallback for non-object schemas\n  const code = jsonSchemaPropertyToZod(jsonSchema, true);\n  return { code, imports: ['z'] };\n}\n\n/**\n * Build a real Zod schema from FieldMeta objects.\n * Returns the schema as Zod source code, since we can't dynamically import Zod here\n * (codegen has no runtime dependency on padrone's main entry point).\n */\nexport function fieldMetaToCode(fields: FieldMeta[]): SchemaToCodeResult {\n  const entries = fields.map((field) => {\n    let code: string;\n\n    switch (field.type) {\n      case 'string':\n        code = 'z.string()';\n        break;\n      case 'number':\n        code = 'z.number()';\n        break;\n      case 'boolean':\n        code = 'z.boolean()';\n        break;\n      case 'array': {\n        const itemType = field.items || 'string';\n        const itemCode = itemType === 'number' ? 'z.number()' : 'z.string()';\n        code = `${itemCode}.array()`;\n        break;\n      }\n      case 'enum':\n        if (field.enumValues && field.enumValues.length > 0) {\n          const values = field.enumValues.map((v) => JSON.stringify(v)).join(', ');\n          code = `z.enum([${values}])`;\n        } else {\n          code = 'z.string()';\n        }\n        break;\n      default:\n        code = 'z.unknown()';\n        break;\n    }\n\n    if (field.default !== undefined) {\n      code += `.default(${JSON.stringify(field.default)})`;\n    } else if (!field.required) {\n      code += '.optional()';\n    }\n\n    if (field.description) {\n      code += `.describe(${JSON.stringify(field.description)})`;\n    }\n\n    if (field.ambiguous) {\n      code += ' /* TODO: verify type */';\n    }\n\n    const key = needsQuoting(field.name) ? JSON.stringify(field.name) : field.name;\n    return `  ${key}: ${code},`;\n  });\n\n  const code = `z.object({\\n${entries.join('\\n')}\\n})`;\n  return { code, imports: ['z'] };\n}\n\nconst JS_RESERVED = new Set([\n  'break',\n  'case',\n  'catch',\n  'continue',\n  'debugger',\n  'default',\n  'delete',\n  'do',\n  'else',\n  'export',\n  'extends',\n  'finally',\n  'for',\n  'function',\n  'if',\n  'import',\n  'in',\n  'instanceof',\n  'new',\n  'return',\n  'super',\n  'switch',\n  'this',\n  'throw',\n  'try',\n  'typeof',\n  'var',\n  'void',\n  'while',\n  'with',\n  'yield',\n  'class',\n  'const',\n  'enum',\n  'let',\n  'static',\n  'implements',\n  'interface',\n  'package',\n  'private',\n  'protected',\n  'public',\n  'await',\n  'async',\n]);\n\n/** Returns true if the name needs quoting to be a valid JS object key. */\nfunction needsQuoting(name: string): boolean {\n  if (JS_RESERVED.has(name)) return true;\n  // Must be a valid identifier: starts with letter/$/_, contains only word chars\n  return !/^[a-zA-Z_$][\\w$]*$/.test(name);\n}\n"],"mappings":"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"}