1import {z} from 'npm:@hono/zod-openapi'
2import {ZodObject, ZodType, ZodTypeAny} from "npm:zod"
3
31
32 // Create new object schema with additionalProperties: false and all fields required
33 return z.object(newShape).openapi({
34 // Preserve description and example if they exist
35 ...(schema._def.openapi ? {
36 description: schema._def.openapi.description,
37 example: schema._def.openapi.example
38 } : {}),
39 // Always add additionalProperties: false
44 // Process array items, removing all array constraints
45 // This removes: minItems, maxItems, uniqueItems validation
46 return z.array(processSchema(schema._def.type)).openapi({
47 // Preserve description and example if they exist
48 ...(schema._def.openapi ? {
49 description: schema._def.openapi.description,
50 example: schema._def.openapi.example
51 } : {})
52 })
54 else if (schema instanceof z.ZodString) {
55 // Remove ALL string validations (min, max, regex, email, url, etc.)
56 return z.string().openapi({
57 // Preserve description and example if they exist
58 ...(schema._def.openapi ? {
59 description: schema._def.openapi.description,
60 example: schema._def.openapi.example
61 } : {})
62 })
64 else if (schema instanceof z.ZodNumber) {
65 // Remove ALL number validations (min, max, multipleOf, int, etc.)
66 return z.number().openapi({
67 // Preserve description and example if they exist
68 ...(schema._def.openapi ? {
69 description: schema._def.openapi.description,
70 example: schema._def.openapi.example
71 } : {})
72 })
74 else if (schema instanceof z.ZodBoolean) {
75 // Preserve boolean as is
76 return z.boolean().openapi({
77 // Preserve description and example if they exist
78 ...(schema._def.openapi ? {
79 description: schema._def.openapi.description,
80 example: schema._def.openapi.example
81 } : {})
82 })
93 // Preserve enums and literals but without additional constraints
94 // Convert them to strings for maximum compatibility
95 return z.string().openapi({
96 // Preserve description and example if they exist
97 ...(schema._def.openapi ? {
98 description: schema._def.openapi.description,
99 example: schema._def.openapi.example
100 } : {})
101 })
119 z.object({
120 value: valueSchema,
121 confidence: z.number().min(0).max(1).openapi({
122 description: 'Confidence score between 0 and 1',
123 example: 0.95
124 }),
125 standardization: z.string().nullable().openapi({
126 description: 'Notes about any standardization applied',
127 example: 'Standardized from "JS" to "JavaScript"'
135 durationInMonths: ConfidenceFieldSchema(z.number().nullable()),
136 current: ConfidenceFieldSchema(z.boolean())
137}).openapi('DateRange')
138
139// Request schema
140export const ResumeParserRequestSchema = z.object({
141 resumeText: z.string().min(1).openapi({
142 description: 'The raw text of the resume to parse',
143 example: 'John Doe\nSoftware Engineer\n...'
144 }),
145 options: z.object({
146 confidenceThreshold: z.number().min(0).max(1).optional().openapi({
147 description: 'Minimum confidence score threshold (0-1)',
148 example: 0.5
149 }),
150 standardizationEnabled: z.boolean().optional().openapi({
151 description: 'Whether to standardize terminology',
152 example: true
153 }),
154 extractSummary: z.boolean().optional().openapi({
155 description: 'Whether to extract and analyze the resume summary',
156 example: true
157 }),
158 sectionPriorities: z.array(z.string()).optional().openapi({
159 description: 'Sections to prioritize in extraction',
160 example: ['skills', 'workExperience']
161 }),
162 extractLanguages: z.boolean().optional().openapi({
163 description: 'Whether to extract language proficiencies',
164 example: true
165 })
166 }).optional().openapi({
167 description: 'Parser configuration options'
168 })
169}).openapi('ResumeParserRequest')
170
171// Personal info schema
179 website: ConfidenceFieldSchema(z.string().nullable()),
180 summary: ConfidenceFieldSchema(z.string().nullable())
181}).openapi('PersonalInfo')
182
183// Skill schema
187 proficiency: ConfidenceFieldSchema(z.string().nullable()),
188 yearsOfExperience: ConfidenceFieldSchema(z.number().nullable())
189}).openapi('Skill')
190
191// Work experience schema
198 technologies: ConfidenceFieldSchema(z.array(z.string())),
199 achievements: ConfidenceFieldSchema(z.array(z.string()))
200}).openapi('WorkExperience')
201
202// Education schema
209 coursework: ConfidenceFieldSchema(z.array(z.string()).nullable()),
210 achievements: ConfidenceFieldSchema(z.array(z.string()).nullable())
211}).openapi('Education')
212
213// Project schema
219 dates: ConfidenceFieldSchema(DateRangeSchema.nullable()),
220 role: ConfidenceFieldSchema(z.string().nullable())
221}).openapi('Project')
222
223// Certification schema
228 expiryDate: ConfidenceFieldSchema(z.string().nullable()),
229 id: ConfidenceFieldSchema(z.string().nullable())
230}).openapi('Certification')
231
232// Language schema
234 name: ConfidenceFieldSchema(z.string()),
235 proficiency: ConfidenceFieldSchema(z.string().nullable())
236}).openapi('Language')
237
238// Parsed resume schema
248 missingFields: z.array(z.string()),
249 detectedSections: z.array(z.string())
250}).openapi('ParsedResume')
251
252// Response schema
259 details: z.unknown().optional()
260 }).optional()
261}).openapi('ParseResumeResponse')
262
263// Error response schema
269 details: z.unknown().optional()
270 })
271}).openapi('ErrorResponse')
272//Simplified ConfidenceFieldSchema
273export const SimplifiedConfidenceFieldSchema = <T extends z.ZodTypeAny>(valueSchema: T) =>