import {z} from 'zod' export type Identifier = string; export type ResumeSearchParametersLocation = {name?: string | undefined, coordinates?: ({latitude?: (number | null) | undefined, longitude?: (number | null) | undefined} | null) | undefined, distance?: number | undefined, unit?: ('km' | 'mi') | undefined}; export type ResumeSearchParametersSkill = {name?: string | undefined, required?: boolean | undefined}; export type EducationLevel = 'school' | 'certificate' | 'bachelors' | 'masters' | 'doctoral' | null; export type ManagementLevel = 'None' | 'Low' | 'Mid' | 'Upper' | null; export type ResumeSearchParametersCustomData = {filterType: 'equals' | 'range', dataPoint?: (string | null) | undefined, field?: (string | null) | undefined, query: Record, required?: boolean | undefined, weight?: number | undefined}; export type ResumeSearchParameters = {indices: Array, jobDescription?: Identifier | undefined, resume?: Identifier | undefined, jobTitles?: Array | undefined, jobTitlesCurrentOnly?: boolean | undefined, jobTitlesRequired?: boolean | undefined, jobTitlesWeight?: number | undefined, yearsExperienceMin?: (number | null) | undefined, yearsExperienceMax?: (number | null) | undefined, yearsExperienceRequired?: boolean | undefined, yearsExperienceWeight?: number | undefined, locations?: Array | undefined, locationsWeight?: number | undefined, locationsRequired?: boolean | undefined, skills?: Array | undefined, skillsWeight?: number | undefined, languages?: Array | undefined, languagesWeight?: number | undefined, institutions?: Array | undefined, institutionsRequired?: boolean | undefined, degrees?: Array | undefined, degreesRequired?: boolean | undefined, highestDegreeTypes?: Array | undefined, highestDegreeTypesRequired?: boolean | undefined, isCurrentStudent?: boolean | undefined, isCurrentStudentRequired?: boolean | undefined, isRecentGraduate?: boolean | undefined, isRecentGraduateRequired?: boolean | undefined, educationWeight?: number | undefined, searchExpression?: (string | null) | undefined, searchExpressionRequired?: boolean | undefined, searchExpressionWeight?: number | undefined, socCodes?: Array | undefined, socCodesWeight?: number | undefined, socCodesRequired?: boolean | undefined, managementLevel?: ManagementLevel | undefined, managementLevelRequired?: boolean | undefined, managementLevelWeight?: number | undefined, customData?: Array | undefined}; export type CreateApiV2ResumeSearchDetailsIdentifierArgs = {identifier: string, body: ResumeSearchParameters}; export type CreateApiV2ResumeSearchDetailsIdentifierOptions = {baseUrl?: string | undefined, ApiKeyAuth?: string | undefined, fetch?: typeof fetch | undefined}; export const resumeSearchParametersLocation = z.object({name: z.string().optional(), coordinates: z.object({latitude: z.number().nullable().optional(), longitude: z.number().nullable().optional()}).nullable().optional(), distance: z.number().int().gte(1).optional(), unit: z.enum(["km", "mi"]).optional()}); export const accreditation = z.object({education: z.string().optional(), inputStr: z.string().optional(), matchStr: z.string().nullable().optional(), educationLevel: z.string().nullable().optional()}).nullable(); export const location = z.object({formatted: z.string().nullable().optional(), postalCode: z.string().nullable().optional(), state: z.string().nullable().optional(), stateCode: z.string().nullable().optional(), country: z.string().nullable().optional(), countryCode: z.string().nullable().optional(), rawInput: z.string(), streetNumber: z.string().nullable().optional(), street: z.string().nullable().optional(), apartmentNumber: z.string().nullable().optional(), city: z.string().nullable().optional(), latitude: z.number().nullable().optional(), longitude: z.number().nullable().optional(), poBox: z.string().nullable().optional()}).nullable(); export const resumeSearchParametersSkill = z.object({name: z.string().optional(), required: z.boolean().optional()}); export const occupationGroup: z.ZodType = z.object({code: z.number().int(), name: z.string(), children: z.array(z.lazy(() => occupationGroup))}); export const occupationGroupSearchResult = z.object({match: z.boolean().optional(), code: z.number().int(), name: z.string(), children: z.array(occupationGroup).optional(), parents: z.array(occupationGroup).optional()}); export const managementLevel = z.enum(["None", "Low", "Mid", "Upper"]).nullable(); export const resumeSearchDetail = z.object({jobTitle: z.object({missing: z.array(z.string()).optional(), value: z.array(z.object({name: z.string().nullable().optional(), startDate: z.string().nullable().optional(), endDate: z.string().nullable().optional(), companyName: z.string().nullable().optional(), match: z.boolean().optional()})).optional()}).optional(), location: z.object({missing: z.array(resumeSearchParametersLocation).optional(), value: z.object({formatted: z.string().nullable().optional(), postalCode: z.string().nullable().optional(), state: z.string().nullable().optional(), stateCode: z.string().nullable().optional(), country: z.string().nullable().optional(), countryCode: z.string().nullable().optional(), rawInput: z.string(), streetNumber: z.string().nullable().optional(), street: z.string().nullable().optional(), apartmentNumber: z.string().nullable().optional(), city: z.string().nullable().optional(), latitude: z.number().nullable().optional(), longitude: z.number().nullable().optional(), poBox: z.string().nullable().optional(), match: z.boolean().optional()}).nullable().optional()}).optional(), education: z.object({missing: z.object({degrees: z.array(z.string()).optional(), highestDegreeTypes: z.array(z.string()).optional(), institutions: z.array(z.string()).optional(), currentStudent: z.boolean().optional(), recentGraduate: z.boolean().optional()}).optional(), value: z.array(z.object({id: z.number().int().gte(1).optional(), organization: z.string().nullable().optional(), accreditation: accreditation.optional(), grade: z.object({raw: z.string().optional(), metric: z.string().nullable().optional(), value: z.string().optional()}).and(z.record(z.string(), z.unknown())).nullable().optional(), location: location.optional(), dates: z.object({completionDate: z.string().optional(), isCurrent: z.boolean().optional(), startDate: z.string().nullable().optional(), rawText: z.string().optional()}).nullable().optional(), match: z.boolean().optional()})).optional()}).optional(), skills: z.object({missing: z.array(resumeSearchParametersSkill).optional(), value: z.array(z.object({name: z.string().nullable().optional(), lastUsed: z.string().nullable().optional(), numberOfMonths: z.number().int().gte(0).nullable().optional(), type: z.string().nullable().optional(), sources: z.array(z.object({section: z.enum(["Achievements", "AdditionalInformation", "Education", "Extracurriculars", "Organisations", "Other", "PersonalDetails", "Projects", "Publications", "Referees", "Skills", "Summary", "Training", "WorkExperience", "NotPopulated", "Header", "Footer", "Skills/Interests/Languages", "Training/Certifications", "Extracurriculars/Leadership"]).optional(), position: z.number().int().gte(0).nullable().optional()})).optional(), match: z.boolean().optional()})).optional()}).optional(), experience: z.object({years: z.number().int().gte(0).nullable().optional(), match: z.boolean().optional()}).optional(), occupationGroup: z.object({missing: z.array(z.number().int()).optional(), value: z.array(occupationGroupSearchResult).optional()}).optional(), languages: z.object({missing: z.array(resumeSearchParametersSkill).optional(), value: z.array(z.object({name: z.string().nullable().optional(), lastUsed: z.string().nullable().optional(), numberOfMonths: z.number().int().gte(0).nullable().optional(), type: z.string().nullable().optional(), sources: z.array(z.object({section: z.enum(["Achievements", "AdditionalInformation", "Education", "Extracurriculars", "Organisations", "Other", "PersonalDetails", "Projects", "Publications", "Referees", "Skills", "Summary", "Training", "WorkExperience", "NotPopulated", "Header", "Footer", "Skills/Interests/Languages", "Training/Certifications", "Extracurriculars/Leadership"]).optional(), position: z.number().int().gte(0).nullable().optional()})).optional(), match: z.boolean().optional()})).optional()}).optional(), managementLevel: z.object({level: managementLevel.optional(), match: z.boolean().optional()}).nullable().optional(), searchExpression: z.object({missing: z.array(z.string()).optional(), value: z.array(z.string()).optional()}).optional()}); export const validateResponse = async ( schema: { readonly '~standard': { readonly validate: (value: unknown) => ({ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }) | Promise<{ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }> } }, value: unknown ): Promise => { const result = await schema['~standard'].validate(value) if (result.issues !== undefined) { const detail = result.issues .map(({ message, path }) => path?.length ? `${path.map((segment) => String(typeof segment === 'object' ? segment.key : segment)).join('.')}: ${message}` : message ) .join('; ') throw new Error(`Response does not match the schema: ${detail}`, { cause: { issues: result.issues } }) } return result.value }; /** * Get search result of specific resume * * POST /v2/resume_search/details/{identifier} */ export const createApiV2ResumeSearchDetailsIdentifier = async (args: CreateApiV2ResumeSearchDetailsIdentifierArgs, options?: CreateApiV2ResumeSearchDetailsIdentifierOptions) => { const {baseUrl = "https://api.affinda.com", fetch: fetchFn = fetch, ApiKeyAuth} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('content-type', "application/json") headers.set('accept', "application/json") if (ApiKeyAuth !== undefined) headers.set('authorization', `Bearer ${ApiKeyAuth}`) const url = `${baseUrl.replace(/\/+$/, '')}/v2/resume_search/details/${encodeURIComponent(String(args.identifier))}${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "POST", headers, body: JSON.stringify(args.body)}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(resumeSearchDetail, await res.json()) };