import {z} from 'zod' export type CreateApiPublicV1DoNotContactSyncArgs = {body: {workspaceId?: string | undefined, externalId: string, source?: string | undefined, action?: ('add' | 'remove') | undefined, emails?: Array | undefined, domains?: Array | undefined, linkedinUrls?: Array | undefined}}; export type CreateApiPublicV1DoNotContactSyncOptions = {baseUrl?: string | undefined, ApiKeyAuth?: string | undefined, fetch?: typeof fetch | undefined}; export const createApiPublicV1DoNotContactSyncResponse = z.object({statusCode: z.number().optional(), status: z.boolean().optional(), message: z.string().optional(), data: z.object({externalRef: z.string().optional(), status: z.string().optional(), prospectsMatched: z.number().optional(), emails: z.array(z.string()).optional(), domains: z.array(z.string()).optional(), removed: z.number().optional(), rejected: z.array(z.object({value: z.string().optional(), reason: z.string().optional()})).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 }; /** * Sync one outside record (for example a Salesforce Lead, Contact or Account) into the workspace Do Not Contact list. action "add" blocks the record's emails, company domains (everyone at that company) and any Valley person matching them or its LinkedIn URLs, and stops their in-flight campaigns at the next send, LinkedIn and email alike. Calling add again for the same externalId with the same contents changes nothing; with new contents it replaces what that record blocked. action "remove" lifts exactly what that record blocked; someone also blocked for another reason (an opt-out reply, a manual block) stays blocked. Workspace owners, admins and managers only. * * POST /public/v1/do-not-contact/sync */ export const createApiPublicV1DoNotContactSync = async (args: CreateApiPublicV1DoNotContactSyncArgs, options?: CreateApiPublicV1DoNotContactSyncOptions) => { const {baseUrl = "https://api.joinvalley.co", 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("x-api-key", ApiKeyAuth) const url = `${baseUrl.replace(/\/+$/, '')}/public/v1/do-not-contact/sync${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(createApiPublicV1DoNotContactSyncResponse, await res.json()) };