import {z} from 'zod' export type CompletesGoal = number; export type QuestionID = number; export type ProfileTargetsSelectionConditionsV3 = {object: 'selection', question_id: QuestionID, option: string}; export type ProfileTargetsRangeConditionsV3 = {object: 'range', question_id: QuestionID, min: number, max: number}; export type ProfileTargetsOpenEndedConditionsV3 = {object: 'open_ended', question_id: QuestionID, allow_all_values: true, open_ended_values: Array | null} | {object: 'open_ended', question_id: QuestionID, allow_all_values: false, open_ended_values: Array}; export type InterlockProfileConditionsV3 = ProfileTargetsSelectionConditionsV3 | ProfileTargetsRangeConditionsV3 | ProfileTargetsOpenEndedConditionsV3; export type RequestDraftQuotaNominalV3 = {conditions: Array, quota: {name?: string | undefined, completes_goal: number}}; export type RequestDraftQuotaPercentageV3 = {conditions: Array, quota: {name?: string | undefined, completes_goal_percentage: number}}; export type RequestDraftNoQuotaV3 = {object?: 'nominal' | undefined, conditions: Array, quota?: (Record | null) | undefined}; export type RequestDraftQuotaV3 = Array | Array | Array; export type RequestDraftRegularProfileV3 = {object: 'regular', name?: string | undefined, quotas_enabled: boolean, targets: RequestDraftQuotaV3} | {object: 'blended', blended_type?: ('interlock' | 'control') | undefined, name: string, quotas_enabled: boolean, targets: RequestDraftQuotaV3}; export type GenerateDraftInterlockedProfileRequestV3 = {locale: string, completes_goal: CompletesGoal, start_at: string, end_at: string, collects_pii: boolean, profiling: {profile_adjustment_type: 'percentage' | 'nominal', profiles: Array}}; export type CreateApiDemandAccountsAccountIdDraftsGenerateBlendedProfileArgs = {body: GenerateDraftInterlockedProfileRequestV3}; export type CreateApiDemandAccountsAccountIdDraftsGenerateBlendedProfileOptions = {baseUrl?: string | undefined, BearerAuth?: string | undefined, fetch?: typeof fetch | undefined}; export const questionID = z.number().int(); export const profileTargetsSelectionConditionsV3 = z.object({object: z.literal("selection"), question_id: questionID, option: z.string()}); export const profileTargetsRangeConditionsV3 = z.object({object: z.literal("range"), question_id: questionID, min: z.number().int().gte(1).lte(99), max: z.number().int().gte(1).lte(99)}); export const profileTargetsOpenEndedConditionsV3 = z.union([z.object({object: z.literal("open_ended"), question_id: questionID, allow_all_values: z.literal(true), open_ended_values: z.array(z.string()).nullable()}), z.object({object: z.literal("open_ended"), question_id: questionID, allow_all_values: z.literal(false), open_ended_values: z.array(z.string())})]); export const interlockProfileConditionsV3 = z.union([profileTargetsSelectionConditionsV3, profileTargetsRangeConditionsV3, profileTargetsOpenEndedConditionsV3]); export const draftQuotaDetailsV3 = z.union([z.object({id: z.string(), name: z.string().optional(), text: z.string().optional(), text_translated: z.string().optional(), conditions: z.array(interlockProfileConditionsV3), quota: z.object({name: z.string().optional(), completes_goal_percentage: z.number().gte(0).lte(100).multipleOf(0.01), quota_nominal: z.number().int().gte(0), completes_goal: z.number().int().gte(0)})}), z.object({id: z.string(), name: z.string().optional(), text: z.string().optional(), text_translated: z.string().optional(), conditions: z.array(interlockProfileConditionsV3)})]); export const draftQuotaV3 = z.array(draftQuotaDetailsV3); export const compositeDraftRegularProfileV3 = z.object({object: z.literal("blended"), quotas_enabled: z.boolean(), name: z.string(), description: z.string(), description_translated: z.string().optional(), targets: draftQuotaV3}); 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 }; /** * Generates a blended profile from regular profiles * * POST /demand/accounts/{account_id}/drafts/generate-blended-profile */ export const createApiDemandAccountsAccountIdDraftsGenerateBlendedProfile = async (args: CreateApiDemandAccountsAccountIdDraftsGenerateBlendedProfileArgs, options?: CreateApiDemandAccountsAccountIdDraftsGenerateBlendedProfileOptions) => { const {baseUrl = "https://api.cint.com/v1", fetch: fetchFn = fetch, BearerAuth} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('content-type', "application/json") headers.set('accept', "application/json") if (BearerAuth !== undefined) headers.set('authorization', `Bearer ${BearerAuth}`) const url = `${baseUrl.replace(/\/+$/, '')}/demand/accounts/${encodeURIComponent(String(args.account_id))}/drafts/generate-blended-profile${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(compositeDraftRegularProfileV3, await res.json()) };