import {z} from 'zod' export type InstrumentType = 'mx_direct_debit_card' | 'mx_clabe'; export type Bank = 'mx_santander' | 'mx_banorte' | 'mx_bbva' | 'mx_banamex' | 'mx_hsbc' | 'mx_citi' | 'mx_banjercito' | 'mx_bajio' | 'mx_inbursa' | 'mx_invex' | 'mx_america' | 'mx_vepormas' | 'mx_azteca' | 'mx_multiva' | 'mx_actinver' | 'mx_bancoppel' | 'mx_fundaciondonde' | 'mx_bancrea' | 'mx_bankaaol' | 'mx_scotiabank' | 'mx_banregio' | 'mx_afirme' | 'mx_compartamos' | 'mx_base' | 'mx_ci' | 'mx_mifel' | 'mx_interbanco' | 'mx_sabadell'; export type MXDirectDebitCardInstrument = {card_number: string, bank: Bank}; export type MXClabeInstrument = {clabe: string, can_credit?: (boolean | null) | undefined, can_debit?: (boolean | null) | undefined}; export type InstrumentCreate = {type: InstrumentType, customer_id: string, description?: (string | null) | undefined, mx_direct_debit_card?: (MXDirectDebitCardInstrument | null) | undefined, mx_clabe?: (MXClabeInstrument | null) | undefined}; export type CreateApiInstrumentsArgs = {'X-API-Key'?: (string | null) | undefined, body: InstrumentCreate}; export type CreateApiInstrumentsOptions = {baseUrl: string, fetch?: typeof fetch | undefined}; export const instrumentType = z.enum(["mx_direct_debit_card", "mx_clabe"]); export const instrumentStatus = z.enum(["active", "inactive", "verification_in_progress", "errored"]); export const bank = z.enum(["mx_santander", "mx_banorte", "mx_bbva", "mx_banamex", "mx_hsbc", "mx_citi", "mx_banjercito", "mx_bajio", "mx_inbursa", "mx_invex", "mx_america", "mx_vepormas", "mx_azteca", "mx_multiva", "mx_actinver", "mx_bancoppel", "mx_fundaciondonde", "mx_bancrea", "mx_bankaaol", "mx_scotiabank", "mx_banregio", "mx_afirme", "mx_compartamos", "mx_base", "mx_ci", "mx_mifel", "mx_interbanco", "mx_sabadell"]); export const mXDirectDebitCardInstrument = z.object({card_number: z.string().min(1).max(255), bank: bank}); export const mXClabeInstrument = z.object({clabe: z.string().min(1).max(18), can_credit: z.boolean().nullable().optional(), can_debit: z.boolean().nullable().optional()}); export const verificationResult = z.enum(["no_match", "matched", "errored"]); export const instrumentResponse = z.object({org_id: z.string(), customer_id: z.string(), type: instrumentType, description: z.string().nullable().optional(), status: instrumentStatus.optional(), mx_direct_debit_card: mXDirectDebitCardInstrument.nullable().optional(), mx_clabe: mXClabeInstrument.nullable().optional(), currency: z.string().min(3).max(3).nullable().optional(), ownership_verification_result: verificationResult.nullable().optional(), ownership_verification_result_at: z.string().nullable().optional(), id: z.string(), created_at: z.string(), updated_at: z.string().nullable().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 }; /** * Create Instrument * * POST /instruments */ export const createApiInstruments = async (args: CreateApiInstrumentsArgs, options: CreateApiInstrumentsOptions) => { const {baseUrl, fetch: fetchFn = fetch} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('content-type', "application/json") headers.set('accept', "application/json") if (args['X-API-Key'] != null) headers.set("X-API-Key", String(args['X-API-Key'])) const url = `${baseUrl.replace(/\/+$/, '')}/instruments${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(instrumentResponse, await res.json()) };