import {z} from 'zod' export type GetApiAtsConnectionIdJobIdArgs = {fields?: (Array<'id' | 'created_at' | 'updated_at' | 'name' | 'description' | 'recruiter_ids' | 'hiring_manager_ids' | 'hiring_managers' | 'status' | 'closed_at' | 'addresses' | 'compensation' | 'employment_type' | 'remote' | 'language_locale' | 'public_job_urls' | 'number_of_openings' | 'company_id' | 'questions' | 'postings' | 'groups' | 'openings' | 'minimum_experience_years' | 'minimum_degree' | 'skills' | 'metadata' | 'user_id' | 'industry' | 'summary' | 'raw'>) | undefined, raw?: string | undefined, connection_id: string, id: string}; export type GetApiAtsConnectionIdJobIdOptions = {baseUrl?: string | undefined, jwt?: string | undefined, fetch?: typeof fetch | undefined}; export const propertyAtsJobRecruiterIds = z.array(z.string()); export const propertyAtsJobHiringManagerIds = z.array(z.string()); export const atsReference = z.object({id: z.string().optional(), name: z.string().optional()}); export const propertyAtsJobHiringManagers = z.array(atsReference); export const atsAddress = z.object({address1: z.string().optional(), address2: z.string().optional(), city: z.string().optional(), region: z.string().optional(), region_code: z.string().optional(), postal_code: z.string().optional(), country: z.string().optional(), country_code: z.string().optional()}); export const propertyAtsJobAddresses = z.array(atsAddress); export const atsCompensation = z.object({type: z.enum(["SALARY", "BONUS", "STOCK_OPTIONS", "EQUITY", "OTHER"]).optional(), min: z.number().optional(), max: z.number().optional(), currency: z.string().optional(), frequency: z.enum(["ONE_TIME", "DAY", "QUARTER", "YEAR", "HOUR", "MONTH", "WEEK"]).optional()}); export const propertyAtsJobCompensation = z.array(atsCompensation); export const propertyAtsJobPublicJobUrls = z.array(z.string()); export const propertyAtsJobQuestionOptions = z.array(z.string()); export const propertyAtsJobQuestionParentAnswerValues = z.array(z.string()); export const atsJobQuestion = z.object({id: z.string().optional(), question: z.string(), required: z.boolean().optional(), description: z.string().optional(), prompt: z.string().optional(), type: z.enum(["TEXT", "NUMBER", "DATE", "BOOLEAN", "MULTIPLE_CHOICE", "FILE", "TEXTAREA", "MULTIPLE_SELECT", "UNIVERSITY", "YES_NO", "CURRENCY", "URL"]), options: propertyAtsJobQuestionOptions.optional(), min_length: z.number().optional(), max_length: z.number().optional(), min_value: z.number().optional(), max_value: z.number().optional(), min_at: z.string().optional(), max_at: z.string().optional(), parent_id: z.string().optional(), parent_answer_values: propertyAtsJobQuestionParentAnswerValues.optional()}); export const propertyAtsJobQuestions = z.array(atsJobQuestion); export const propertyAtsJobPostingAddress = z.object({address1: z.string().optional(), address2: z.string().optional(), city: z.string().optional(), region: z.string().optional(), region_code: z.string().optional(), postal_code: z.string().optional(), country: z.string().optional(), country_code: z.string().optional()}); export const atsJobPosting = z.object({id: z.string().optional(), created_at: z.string().optional(), updated_at: z.string().optional(), posting_url: z.string().optional(), name: z.string().optional(), description: z.string().optional(), address: propertyAtsJobPostingAddress.optional(), location: z.string().optional(), is_active: z.boolean().optional()}); export const propertyAtsJobPostings = z.array(atsJobPosting); export const atsGroup = z.object({id: z.string().optional(), name: z.string().optional(), type: z.enum(["TEAM", "GROUP", "DEPARTMENT", "DIVISION", "BUSINESS_UNIT", "BRANCH", "SUB_DEPARTMENT"]).optional()}); export const propertyAtsJobGroups = z.array(atsGroup); export const atsJobOpening = z.object({status: z.enum(["OPEN", "CLOSED"]).optional(), opened_at: z.string().optional(), closed_at: z.string().optional(), application_id: z.string().optional(), close_reason: z.string().optional()}); export const propertyAtsJobOpenings = z.array(atsJobOpening); export const propertyAtsJobSkills = z.array(z.string()); export const atsMetadata = z.object({id: z.string().optional(), slug: z.string().optional(), value: z.union([z.record(z.string(), z.unknown()), z.string(), z.number(), z.boolean(), z.array(z.union([z.object({}), z.string(), z.number(), z.boolean()]))]).optional(), namespace: z.string().optional(), format: z.enum(["TEXT", "NUMBER", "DATE", "BOOLEAN", "FILE", "TEXTAREA", "SINGLE_SELECT", "MULTIPLE_SELECT", "MEASUREMENT", "PRICE", "YES_NO", "CURRENCY", "URL"]).optional(), extra_data: z.union([z.record(z.string(), z.unknown()), z.string(), z.number(), z.boolean(), z.array(z.union([z.object({}), z.string(), z.number(), z.boolean()]))]).optional()}); export const propertyAtsJobMetadata = z.array(atsMetadata); export const atsJob = z.object({id: z.string().optional(), created_at: z.string().optional(), updated_at: z.string().optional(), name: z.string().optional(), description: z.string().optional(), recruiter_ids: propertyAtsJobRecruiterIds.optional(), hiring_manager_ids: propertyAtsJobHiringManagerIds.optional(), hiring_managers: propertyAtsJobHiringManagers.optional(), status: z.enum(["ARCHIVED", "PENDING", "DRAFT", "OPEN", "CLOSED"]).optional(), closed_at: z.string().optional(), addresses: propertyAtsJobAddresses.optional(), compensation: propertyAtsJobCompensation.optional(), employment_type: z.enum(["FULL_TIME", "PART_TIME", "CONTRACTOR", "INTERN", "CONSULTANT", "VOLUNTEER", "CASUAL", "SEASONAL", "FREELANCE", "OTHER"]).optional(), remote: z.boolean().optional(), language_locale: z.string().optional(), public_job_urls: propertyAtsJobPublicJobUrls.optional(), number_of_openings: z.number().optional(), company_id: z.string().optional(), questions: propertyAtsJobQuestions.optional(), postings: propertyAtsJobPostings.optional(), groups: propertyAtsJobGroups.optional(), openings: propertyAtsJobOpenings.optional(), minimum_experience_years: z.number().optional(), minimum_degree: z.string().optional(), skills: propertyAtsJobSkills.optional(), metadata: propertyAtsJobMetadata.optional(), user_id: z.string().optional(), industry: z.string().optional(), summary: z.string().optional(), raw: z.record(z.string(), z.unknown()).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 }; /** * Retrieve a job * * GET /ats/{connection_id}/job/{id} */ export const getApiAtsConnectionIdJobId = async (args: GetApiAtsConnectionIdJobIdArgs, options?: GetApiAtsConnectionIdJobIdOptions) => { const {baseUrl = "https://api.unified.to", fetch: fetchFn = fetch, jwt} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") for (const item of args.fields ?? []) query.append("fields", String(item)) if (args.raw != null) query.append("raw", String(args.raw)) if (jwt !== undefined) headers.set("authorization", jwt) const url = `${baseUrl.replace(/\/+$/, '')}/ats/${encodeURIComponent(String(args.connection_id))}/job/${encodeURIComponent(String(args.id))}${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "GET", headers}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(atsJob, await res.json()) };