import {z} from 'zod' export type GetApiSavedSearchesOptions = {baseUrl: string, fetch?: typeof fetch | undefined}; export const searchType = z.enum(["EVENT_FEED", "COMPANIES_LIST", "PERSONS", "TYPEAHEAD", "INVESTORS"]); export const filter = z.object({field: z.string(), field_urn: z.string().nullable().optional(), comparator: z.string(), filter_value: z.unknown()}); export const filterGroupGeneratorId = z.enum(["company_headcount", "search_v2_accelerator", "search_v2_company_funding_stage", "search_v2_company_funding_stage_simple", "search_v2_company_funding_total_range", "search_v2_company_funding_last_round_total_range", "search_v2_company_funding_undisclosed", "search_v2_company_currently_raising", "search_v2_company_funding_include_investors", "search_v2_company_funding_exclude_investors", "search_v2_company_funding_last_round_date", "search_v2_company_funding_foundation_date", "search_v2_company_funding_investors_deal_search", "search_v2_company_team_headcount_range", "search_v2_company_team_headcount_percent_growth_range", "search_v2_company_latest_web_traffic_range", "search_v2_company_web_traffic_percent_growth_range", "search_v2_company_headcount_department_percent_growth_range", "search_v2_company_socials_growth_range", "search_v2_company_team_highlights", "search_v2_company_sector_include_keywords", "search_v2_company_sector_exclude_keywords", "search_v2_company_sector_match_keywords", "search_v2_company_sector_include_industry_tags", "search_v2_company_sector_exclude_industry_tags", "search_v2_company_sector_include_business_tags", "search_v2_company_sector_exclude_business_tags", "search_v2_company_sector_include_technology_tags", "search_v2_company_sector_exclude_technology_tags", "search_v2_company_sector_preset", "search_v2_company_sector_include_tags", "search_v2_company_sector_exclude_tags", "search_v2_company_sector_product_categories", "search_v2_company_team_founding_experience", "search_v2_company_team_member_experience", "search_v2_company_team_notable_followers", "search_v2_company_team_notable_followers_count", "search_v2_company_list_and_more_initialized_date", "search_v2_company_list_and_more_updated_date", "search_v2_company_list_and_more_include_from_watchlist", "search_v2_company_list_and_more_exclude_from_watchlist", "search_v2_company_list_and_more_accelerators", "search_v2_company_list_and_more_location", "search_v2_company_list_and_more_continents", "search_v2_company_list_and_more_include_from_people_list", "search_v2_company_list_and_more_exclude_from_people_list", "search_v2_company_is_not_investor", "search_people_employees", "search_v2_people_education_experience", "search_v2_people_general_highlights", "search_v2_people_general_location", "search_v2_people_general_connections", "search_v2_person_network_membership", "search_v2_company_network_membership", "search_v2_investor_network_membership", "search_v2_people_general_linkedin_headlines", "search_v2_people_general_people_lists", "search_v2_people_current_experience", "search_v2_people_past_experience", "search_v2_people_general_correspondences", "search_v2_person_notable_followers", "search_v2_person_notable_followers_count", "search_v2_company_team_correspondences", "search_v2_semantic_search_filter", "search_v2_similar_company_search_filter", "search_v2_investor_aum_range", "search_v2_investor_check_size_range", "search_v2_investor_funded_company_location", "search_v2_investor_invested_stage", "search_v2_investor_latest_investment_date", "search_v2_investor_location", "search_v2_investor_num_deals_range", "search_v2_investor_team_size_range", "search_v2_investor_co_investors", "search_v2_investor_average_investment_size_range", "search_v2_investor_entry_stage_focus", "search_v2_investor_country_focus", "search_v2_investor_sector_focus", "search_v2_investor_funded_company", "search_v2_investor_website_keywords", "search_v2_investor_funded_company_sector_tags", "search_v2_investor_portfolio_details", "search_v2_investor_team_correspondences", "search_v2_investor_lists", "search_v2_investor_type", "search_v2_investor_primary_type", "search_v2_investor_secondary_types"]); export const filterGroupGenerator = z.object({generator_id: filterGroupGeneratorId, arguments: z.object({})}); export const filterGroupOutput: z.ZodType = z.object({join_operator: z.enum(["and", "or"]), filters: z.array(filter).nullable().optional(), filter_groups: z.array(z.lazy(() => filterGroupOutput)).nullable().optional(), filter_group_generators: z.array(filterGroupGenerator).nullable().optional()}); export const pagination = z.object({start: z.number().int().nullable().optional(), page_size: z.number().int()}); export const sortContextArguments = z.object({saved_search_id: z.number().int().nullable().optional(), date_added_after: z.string().nullable().optional(), list_urn: z.union([z.string(), z.string()]).nullable().optional(), custom_field_urn: z.union([z.string(), z.string()]).nullable().optional(), company_id: z.number().int().nullable().optional()}); export const sortOutput = z.object({sort_field: z.string(), descending: z.boolean(), sort_context_values: sortContextArguments.nullable().optional()}); export const apiSearchQueryOutput = z.object({filter_group: filterGroupOutput, pagination: pagination, sort: z.array(sortOutput).optional(), controlled_filter_group: filterGroupOutput.nullable().optional(), merge_query_for_nested_fields: z.boolean().optional()}); export const userSavedSearchType = z.enum(["USER_CREATED", "GENERATED_FROM_PREFERENCES", "TEMPLATE_FROM_PREFERENCES"]); export const savedSearchColumnViewSettings = z.object({entity_urn: z.union([z.string(), z.string(), z.string(), z.string(), z.string(), z.string(), z.string()]), column_width: z.number().int().nullable().optional()}); export const savedSearchOutput = z.object({name: z.string(), is_private: z.boolean().optional(), type: searchType.optional(), query: apiSearchQueryOutput, id: z.number().int(), entity_urn: z.string(), creator: z.string(), user_saved_search_type: userSavedSearchType, updated_at: z.string(), created_at: z.string(), column_view_settings: z.array(savedSearchColumnViewSettings).nullable().optional(), sort_field_v2: z.string().nullable().optional()}); export const getApiSavedSearchesResponse = z.array(savedSearchOutput); 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 Saved Search By Owner * * GET /savedSearches */ export const getApiSavedSearches = async (options: GetApiSavedSearchesOptions) => { const {baseUrl, fetch: fetchFn = fetch} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") const url = `${baseUrl.replace(/\/+$/, '')}/savedSearches${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(getApiSavedSearchesResponse, await res.json()) };