import {z} from 'zod' export type GetAtsJobsParameterCursor = string; export type GetAtsJobsParameterPageSize = number; export type GetAtsJobsParameterUpdatedAfter = string; export type GetAtsJobsParameterIncludeDeleted = 'true' | 'false'; export type GetAtsJobsParameterIgnoreUnsupportedFilters = 'true' | 'false'; export type GetAtsJobsParameterIds = string; export type GetAtsJobsParameterRemoteIds = string; export type GetAtsJobsParameterJobCodes = string; export type GetAtsJobsParameterPostUrl = string; export type GetAtsJobsParameterStatus = 'OPEN' | 'CLOSED' | 'DRAFT' | 'ARCHIVED'; export type GetAtsJobsParameterStatuses = string; export type GetAtsJobsParameterEmploymentTypes = string; export type GetAtsJobsParameterVisibilities = string; export type GetAtsJobsParameterRemoteCreatedAfter = string; export type GetAtsJobsParameterNameContains = string; export type GetApiAtsJobsArgs = {'X-Integration-Id': string, cursor?: GetAtsJobsParameterCursor | undefined, page_size?: GetAtsJobsParameterPageSize | undefined, updated_after?: GetAtsJobsParameterUpdatedAfter | undefined, include_deleted?: GetAtsJobsParameterIncludeDeleted | undefined, ignore_unsupported_filters?: GetAtsJobsParameterIgnoreUnsupportedFilters | undefined, ids?: GetAtsJobsParameterIds | undefined, remote_ids?: GetAtsJobsParameterRemoteIds | undefined, job_codes?: GetAtsJobsParameterJobCodes | undefined, post_url?: GetAtsJobsParameterPostUrl | undefined, status?: GetAtsJobsParameterStatus | undefined, statuses?: GetAtsJobsParameterStatuses | undefined, employment_types?: GetAtsJobsParameterEmploymentTypes | undefined, visibilities?: GetAtsJobsParameterVisibilities | undefined, remote_created_after?: GetAtsJobsParameterRemoteCreatedAfter | undefined, name_contains?: GetAtsJobsParameterNameContains | undefined}; export type GetApiAtsJobsOptions = {baseUrl?: string | undefined, ApiKey?: string | undefined, fetch?: typeof fetch | undefined}; export const getAtsJobsPositiveResponse = z.object({status: z.literal("success"), data: z.object({next: z.string().nullable(), results: z.array(z.object({id: z.string(), remote_id: z.string(), name: z.string().nullable(), job_code: z.string().nullable(), description: z.string().nullable(), confidential: z.boolean().nullable(), weekly_hours: z.number().nullable(), employment_type: z.union([z.enum(["FULL_TIME", "PART_TIME", "CONTRACT", "SEASONAL", "INTERNSHIP"]), z.string()]).nullable().optional(), status: z.union([z.enum(["OPEN", "CLOSED", "DRAFT", "ARCHIVED"]), z.string()]).nullable().optional(), visibility: z.union([z.enum(["PUBLIC", "INTERNAL", "UNLISTED", "CONFIDENTIAL"]), z.string()]).nullable().optional(), category: z.string().nullable(), department: z.string().nullable(), post_url: z.string().nullable(), experience_level: z.string().nullable(), remote_work_status: z.union([z.enum(["REMOTE", "HYBRID", "TEMPORARY", "ON_SITE"]), z.string()]).nullable().optional(), salary_amount: z.number().nullable(), salary_amount_from: z.number().nullable(), salary_amount_to: z.number().nullable(), salary_currency: z.string().nullable(), salary_period: z.union([z.enum(["YEAR", "MONTH", "TWO_WEEKS", "WEEK", "DAY", "HOUR"]), z.string()]).nullable().optional(), location: z.object({city: z.string().nullable().optional(), country: z.string().nullable().optional(), raw: z.string().nullable().optional(), state: z.string().nullable().optional(), street_1: z.string().nullable().optional(), street_2: z.string().nullable().optional(), zip_code: z.string().nullable().optional()}).nullable().optional(), custom_fields: z.record(z.string(), z.unknown()).nullable(), integration_fields: z.array(z.object({id: z.string(), key: z.string(), type: z.enum(["DEFAULT", "CUSTOM"]), value: z.unknown(), label: z.string().nullable()})), remote_url: z.string().nullable(), opened_at: z.string().nullable(), closed_at: z.string().nullable(), remote_created_at: z.string().nullable(), remote_updated_at: z.string().nullable(), contact_id: z.string().nullable(), remote_data: z.record(z.string(), z.unknown()).nullable(), changed_at: z.string(), remote_deleted_at: z.string().nullable(), stages: z.array(z.object({id: z.string(), remote_id: z.string().nullable(), name: z.string().nullable(), status: z.enum(["ACTIVE", "INACTIVE"]).nullable(), custom_fields: z.record(z.string(), z.unknown()).nullable(), integration_fields: z.array(z.object({id: z.string(), key: z.string(), type: z.enum(["DEFAULT", "CUSTOM"]), value: z.unknown(), label: z.string().nullable()})), remote_data: z.record(z.string(), z.unknown()).nullable(), index: z.number().int().nullable().optional()})), screening_questions: z.array(z.object({id: z.string(), remote_id: z.string().nullable(), title: z.string().nullable(), description: z.string().nullable(), format: z.union([z.object({display_type: z.enum(["SINGLE_LINE", "MULTI_LINE", "EMAIL", "URL"]).nullable().optional(), max_length: z.number().int().nullable().optional(), type: z.literal("TEXT")}), z.object({display_type: z.enum(["SLIDER", "FIELD"]).nullable().optional(), max: z.number().nullable().optional(), min: z.number().nullable().optional(), type: z.literal("NUMBER")}), z.object({accepted_mime_types: z.array(z.string()).nullable().optional(), max_file_size_bytes: z.number().int().nullable().optional(), type: z.literal("FILE")}), z.object({display_type: z.enum(["DROPDOWN", "RADIO"]).nullable().optional(), options: z.array(z.object({id: z.string(), remote_id: z.string().nullable().optional(), name: z.string()})), type: z.literal("SINGLE_SELECT")}), z.object({type: z.literal("BOOLEAN")}), z.object({type: z.literal("DATE")}), z.object({options: z.array(z.object({id: z.string(), remote_id: z.string().nullable().optional(), name: z.string()})), type: z.literal("MULTI_SELECT")}), z.object({type: z.literal("INFORMATION")}), z.object({raw_question: z.unknown(), type: z.literal("UNKNOWN")})]).nullable().optional(), category: z.enum(["EEO", "DEMOGRAPHIC"]).nullable(), index: z.number().int().nullable().optional(), required: z.boolean().nullable(), precondition_question_id: z.string().min(24).max(24).nullable().optional(), precondition_options: z.union([z.array(z.string().min(24).max(24)), z.array(z.boolean())]).nullable().optional()})), job_postings: z.array(z.object({id: z.string(), remote_id: z.string().nullable(), title: z.string().nullable(), description_html: z.string().nullable(), status: z.enum(["ACTIVE", "INACTIVE", "DRAFT"]).nullable(), visibility: z.enum(["PUBLIC", "INTERNAL", "UNLISTED"]).nullable(), url: z.string().nullable(), remote_data: z.record(z.string(), z.unknown()).nullable()})), hiring_team: z.array(z.object({id: z.string(), remote_id: z.string().nullable(), first_name: z.string().nullable(), last_name: z.string().nullable(), email: z.string().nullable().optional(), hiring_team_roles: z.array(z.enum(["HIRING_MANAGER", "RECRUITER", "COORDINATOR", "SOURCER", "INTERVIEWER"])), job_roles: z.array(z.object({remote_id: z.string().nullable(), remote_label: z.string().nullable(), unified_type: z.enum(["HIRING_MANAGER", "RECRUITER", "COORDINATOR", "SOURCER", "INTERVIEWER", "ADMIN"]).nullable(), scope: z.literal("JOB")}))}))}))})}); 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 jobs * * GET /ats/jobs */ export const getApiAtsJobs = async (args: GetApiAtsJobsArgs, options?: GetApiAtsJobsOptions) => { const {baseUrl = "https://api.kombo.dev/v1", fetch: fetchFn = fetch, ApiKey} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") if (args['X-Integration-Id'] != null) headers.set("X-Integration-Id", String(args['X-Integration-Id'])) if (args.cursor != null) query.append("cursor", String(args.cursor)) if (args.page_size != null) query.append("page_size", String(args.page_size)) if (args.updated_after != null) query.append("updated_after", String(args.updated_after)) if (args.include_deleted != null) query.append("include_deleted", String(args.include_deleted)) if (args.ignore_unsupported_filters != null) query.append("ignore_unsupported_filters", String(args.ignore_unsupported_filters)) if (args.ids != null) query.append("ids", String(args.ids)) if (args.remote_ids != null) query.append("remote_ids", String(args.remote_ids)) if (args.job_codes != null) query.append("job_codes", String(args.job_codes)) if (args.post_url != null) query.append("post_url", String(args.post_url)) if (args.status != null) query.append("status", String(args.status)) if (args.statuses != null) query.append("statuses", String(args.statuses)) if (args.employment_types != null) query.append("employment_types", String(args.employment_types)) if (args.visibilities != null) query.append("visibilities", String(args.visibilities)) if (args.remote_created_after != null) query.append("remote_created_after", String(args.remote_created_after)) if (args.name_contains != null) query.append("name_contains", String(args.name_contains)) if (ApiKey !== undefined) headers.set('authorization', `Bearer ${ApiKey}`) const url = `${baseUrl.replace(/\/+$/, '')}/ats/jobs${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(getAtsJobsPositiveResponse, await res.json()) };