import {z} from 'zod' export type LinkedInCompanySize = '1-10' | '11-50' | '51-200' | '201-500' | '501-1000' | '1001-5000' | '5001-10000' | '10001+'; export type LinkedInCompanyIndustry = 'accounting' | 'agriculture' | 'airlines/aviation' | 'alternative dispute resolution' | 'alternative medicine' | 'animation' | 'apparel & fashion' | 'architecture & planning' | 'arts & crafts' | 'automotive' | 'aviation & aerospace' | 'banking' | 'biotechnology' | 'broadcast media' | 'building materials' | 'business supplies & equipment' | 'capital markets' | 'chemicals' | 'civic & social organization' | 'civil engineering' | 'commercial real estate' | 'computer & network security' | 'computer games' | 'computer hardware' | 'computer networking' | 'computer software' | 'construction' | 'consumer electronics' | 'consumer goods' | 'consumer services' | 'cosmetics' | 'dairy' | 'defense & space' | 'design' | 'e-learning' | 'education management' | 'electrical/electronic manufacturing' | 'entertainment' | 'environmental services' | 'events services' | 'executive office' | 'facilities services' | 'farming' | 'financial services' | 'fine art' | 'fishery' | 'food & beverages' | 'food production' | 'fund-raising' | 'furniture' | 'gambling & casinos' | 'glass, ceramics & concrete' | 'government administration' | 'government relations' | 'graphic design' | 'health, wellness & fitness' | 'higher education' | 'hospital & health care' | 'hospitality' | 'human resources' | 'import & export' | 'individual & family services' | 'industrial automation' | 'information services' | 'information technology & services' | 'insurance' | 'international affairs' | 'international trade & development' | 'internet' | 'investment banking' | 'investment management' | 'judiciary' | 'law enforcement' | 'law practice' | 'legal services' | 'legislative office' | 'leisure, travel & tourism' | 'libraries' | 'logistics & supply chain' | 'luxury goods & jewelry' | 'machinery' | 'management consulting' | 'maritime' | 'market research' | 'marketing & advertising' | 'mechanical or industrial engineering' | 'media production' | 'medical devices' | 'medical practice' | 'mental health care' | 'military' | 'mining & metals' | 'motion pictures & film' | 'museums & institutions' | 'music' | 'nanotechnology' | 'newspapers' | 'nonprofit organization management' | 'oil & energy' | 'online media' | 'outsourcing/offshoring' | 'package/freight delivery' | 'packaging & containers' | 'paper & forest products' | 'performing arts' | 'pharmaceuticals' | 'philanthropy' | 'photography' | 'plastics' | 'political organization' | 'primary/secondary education' | 'printing' | 'professional training & coaching' | 'program development' | 'public policy' | 'public relations & communications' | 'public safety' | 'publishing' | 'railroad manufacture' | 'ranching' | 'real estate' | 'recreational facilities & services' | 'religious institutions' | 'renewables & environment' | 'research' | 'restaurants' | 'retail' | 'security & investigations' | 'semiconductors' | 'shipbuilding' | 'sporting goods' | 'sports' | 'staffing & recruiting' | 'supermarkets' | 'telecommunications' | 'textiles' | 'think tanks' | 'tobacco' | 'translation & localization' | 'transportation/trucking/railroad' | 'utilities' | 'venture capital & private equity' | 'veterinary' | 'warehousing' | 'wholesale' | 'wine & spirits' | 'wireless' | 'writing & editing'; export type CreateApiLinkedinSearchPeopleArgs = {body: {keywords?: string | undefined, locations?: Array | undefined, titles?: Array | undefined, seniorities?: (Array<'owner' | 'founder' | 'c_suite' | 'partner' | 'vp' | 'head' | 'director' | 'manager' | 'senior' | 'entry' | 'intern'>) | undefined, company_sizes?: Array | undefined, company_industries?: Array | undefined, company_domains?: Array | undefined, page?: number | undefined}}; export type CreateApiLinkedinSearchPeopleOptions = {baseUrl?: string | undefined, apiKey?: string | undefined, fetch?: typeof fetch | undefined}; export const linkedInPerson = z.object({url: z.string().optional(), name: z.string().optional(), location: z.string().optional(), title: z.string().nullable().optional(), company_name: z.string().optional(), company_url: z.string().optional(), experiences: z.array(z.object({title: z.string().nullable().optional(), company_name: z.string().optional(), start_date: z.string().nullable().optional(), end_date: z.string().nullable().optional()})).optional()}); export const createApiLinkedinSearchPeopleResponse = z.object({people: z.array(linkedInPerson).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 }; /** * Search for LinkedIn people * * POST /linkedin/search-people */ export const createApiLinkedinSearchPeople = async (args: CreateApiLinkedinSearchPeopleArgs, options?: CreateApiLinkedinSearchPeopleOptions) => { const {baseUrl = "https://api.exfunc.dev", fetch: fetchFn = fetch, apiKey} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('content-type', "application/json") headers.set('accept', "application/json") if (apiKey !== undefined) headers.set("x-api-key", apiKey) const url = `${baseUrl.replace(/\/+$/, '')}/linkedin/search-people${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(createApiLinkedinSearchPeopleResponse, await res.json()) };