import {z} from 'zod' export type GetApiV1InsightsRequestIdArgs = {requestId: string}; export type GetApiV1InsightsRequestIdOptions = {baseUrl: string, Bearer?: string | undefined, fetch?: typeof fetch | undefined}; export const requestStatus = z.enum(["PENDING", "PROCESSING", "PROCESSED", "REJECTED"]); export const transaction = z.object({amount: z.number().nullable().optional(), categoryId: z.number().int().optional(), title: z.string().nullable().optional(), date: z.string().nullable().optional(), info: z.string().nullable().optional(), transactionId: z.string().nullable().optional(), partner: z.string().nullable().optional()}); export const currency = z.object({code: z.string().nullable().optional(), creditTurnover: z.number().nullable().optional(), debitTurnover: z.number().nullable().optional(), endBalance: z.number().nullable().optional(), startBalance: z.number().nullable().optional(), transactions: z.array(transaction).nullable().optional()}); export const accountHolder = z.object({name: z.string().nullable().optional()}); export const account = z.object({accountNumber: z.string().nullable().optional(), bank: z.string().nullable().optional(), country: z.string().nullable().optional(), currencies: z.array(currency).nullable().optional(), holders: z.array(accountHolder).nullable().optional(), iban: z.string().nullable().optional(), isJointOwnership: z.boolean().nullable().optional(), isSharedOwnership: z.boolean().nullable().optional(), periodEnd: z.string().nullable().optional(), periodStart: z.string().nullable().optional()}); export const categorisation = z.object({accounts: z.array(account).nullable().optional(), categoryTreeVersion: z.string().nullable().optional()}); export const insightsCurrencyDetails = z.object({currency: z.string().nullable().optional(), rate: z.number().nullable().optional()}); export const insightsCurrency = z.object({displayCurrency: z.string().nullable().optional(), appliedCurrencyConversions: z.array(insightsCurrencyDetails).nullable().optional()}); export const insightsDetails = z.object({currency: insightsCurrency.optional()}); export const definitionDetails = z.object({categoryId: z.string().nullable().optional(), title: z.string().nullable().optional()}); export const definition = z.object({expenses: z.array(definitionDetails).nullable().optional(), income: z.array(definitionDetails).nullable().optional()}); export const incomeDetails = z.object({averageIncomePayment: z.number().nullable().optional(), averageMonthlyIncome: z.number().nullable().optional(), daysSinceLastIncomePayment: z.number().int().nullable().optional(), medianIncomePayment: z.number().nullable().optional(), numberOfIncomePayments: z.number().int().nullable().optional()}); export const monthlyIncome = z.object({expectedRemainingIncome: z.number().nullable().optional(), month: z.string().nullable().optional(), receivedIncome: z.number().nullable().optional(), remainingMonthlyDiscretionaryIncome: z.number().nullable().optional()}); export const income = z.object({averageDaysBetweenIncomePayments: z.number().int().nullable().optional(), averageMonthlyDiscretionaryIncome: z.number().nullable().optional(), averageMonthlyIncome: z.number().nullable().optional(), calendarMonths: z.number().int().nullable().optional(), calendarMonthsWithIncome: z.number().int().nullable().optional(), daysSinceLastIncomePayment: z.number().int().nullable().optional(), debtToIncomeRatio: z.number().nullable().optional(), definitions: definition.optional(), incomeByCategory: z.record(z.string(), incomeDetails).nullable().optional(), lastIncompleteMonth: monthlyIncome.optional(), monthlyRegularity: z.number().nullable().optional(), monthlyStability: z.number().nullable().optional(), monthlyTrend: z.number().nullable().optional()}); export const categoryId = z.object({expense: z.string().nullable().optional(), income: z.string().nullable().optional()}); export const loanDetails = z.object({averageMonthlyOutgoingLoanPayment: z.number().nullable().optional(), categoryId: categoryId.optional(), categoryTitle: z.string().nullable().optional(), daysSinceLastIncomingLoan: z.number().int().nullable().optional(), monthlyIncomingLoanTrend: z.number().nullable().optional(), monthlyOutgoingLoanTrend: z.number().nullable().optional(), numberOfIncomingLoanSources: z.number().int().nullable().optional(), numberOfOutgoingLoanSources: z.number().int().nullable().optional(), ratioOfOutgoingLoanCategoryToLoans: z.number().nullable().optional()}); export const loan = z.object({averageMonthlyOutgoingLoanPayment: z.number().nullable().optional(), calendarMonths: z.number().int().nullable().optional(), calendarMonthsWithIncomingLoans: z.number().int().nullable().optional(), calendarMonthsWithOutgoingLoans: z.number().int().nullable().optional(), daysSinceLastIncomingLoan: z.number().int().nullable().optional(), loansByCategory: z.array(loanDetails).nullable().optional(), monthlyIncomingLoanTrend: z.number().nullable().optional(), monthlyOutgoingLoanTrend: z.number().nullable().optional(), ratioOfIncomingLoansToAllIncome: z.number().nullable().optional(), ratioOfOutgoingLoansToAllExpenses: z.number().nullable().optional()}); export const paymentDetails = z.object({averageCountAMonth: z.number().nullable().optional(), averageSumAMonth: z.number().nullable().optional()}); export const balanceDetails = z.object({calendarMonthEndBalance: z.number().nullable().optional(), calendarMonthStartBalance: z.number().nullable().optional(), netCashFlow: z.number().nullable().optional(), statementEndBalance: z.number().nullable().optional(), statementStartBalance: z.number().nullable().optional()}); export const cashDetails = z.object({averageCountOfCashDepositAMonth: z.number().nullable().optional(), averageCountOfCashWithdrawalAMonth: z.number().nullable().optional(), averageSumOfCashDepositAMonth: z.number().nullable().optional(), averageSumOfCashWithdrawalAMonth: z.number().nullable().optional(), cashDepositMonthlyTrend: z.number().nullable().optional(), cashDepositToIncome: z.number().nullable().optional(), cashWithdrawalMonthlyTrend: z.number().nullable().optional(), cashWithdrawalToExpenses: z.number().nullable().optional(), cashWithdrawalToIncome: z.number().nullable().optional(), stableMonthlyCashDeposits: z.boolean().nullable().optional()}); export const gamblingDetails = z.object({averageCountAMonth: z.number().nullable().optional(), averageSumAMonth: z.number().nullable().optional(), daysSinceLastTransaction: z.number().int().nullable().optional(), gamblingToAllExpenses: z.number().nullable().optional(), monthlyRegularityOfGambling: z.number().nullable().optional(), ratioOfCasino: z.number().nullable().optional(), ratioOfLottery: z.number().nullable().optional(), ratioOfSportsBetting: z.number().nullable().optional()}); export const risk = z.object({alimonyPayments: paymentDetails.optional(), bailiffs: paymentDetails.optional(), balance: balanceDetails.optional(), cash: cashDetails.optional(), debtCollection: paymentDetails.optional(), dishonours: paymentDetails.optional(), gambling: gamblingDetails.optional(), loanFines: paymentDetails.optional()}); export const personIdentification = z.object({_type: z.string().nullable().optional(), id: z.string().nullable().optional()}); export const kycDetails = z.object({address: z.string().nullable().optional(), bank: z.string().nullable().optional(), dateOfBirth: z.string().nullable().optional(), emailAddress: z.string().nullable().optional(), firstName: z.string().nullable().optional(), lastName: z.string().nullable().optional(), fullName: z.string().nullable().optional(), iban: z.string().nullable().optional(), personIdentification: z.array(personIdentification).nullable().optional(), phoneNumber: z.string().nullable().optional()}); export const observation = z.object({description: z.string().nullable().optional(), severity: z.string().nullable().optional()}); export const segment = z.object({triggered: z.boolean().nullable().optional(), details: z.string().nullable().optional()}); export const segments = z.object({hasChildren: segment.optional(), hasCar: segment.optional(), hasHouse: segment.optional(), hasPets: segment.optional(), hasLifeInsurance: segment.optional(), isDigital: segment.optional(), interestedInClothing: segment.optional(), interestedInSports: segment.optional(), interestedInTraveling: segment.optional(), interestedInBeauty: segment.optional(), interestedInCulture: segment.optional(), interestedInGambling: segment.optional()}); export const marketing = z.object({segments: segments.optional()}); export const statementDetails = z.object({countOfAnalysedAccounts: z.number().int().nullable().optional(), countOfUploadedAccounts: z.number().int().nullable().optional(), dropJointAccounts: z.boolean().nullable().optional(), dropSharedAccounts: z.boolean().nullable().optional()}); export const metadata = z.object({statementDetails: statementDetails.optional(), insightsDetails: insightsDetails.optional()}); export const insightsResponseDetails = z.object({categorisation: categorisation.optional(), creditScores: z.record(z.string(), z.number()).nullable().optional(), features: z.record(z.string(), z.record(z.string(), z.number())).nullable().optional(), insightsDetails: insightsDetails.optional(), insightsIncome: income.optional(), insightsLoans: loan.optional(), insightsRisk: risk.optional(), kyc: z.array(kycDetails).nullable().optional(), observations: z.record(z.string(), observation).nullable().optional(), marketing: marketing.optional(), simpleScore: z.number().int().nullable().optional(), metadata: metadata.optional()}); export const insightsResponse = z.object({id: z.string(), requestStatus: requestStatus, rejectReason: z.string().nullable().optional(), report: insightsResponseDetails.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 }; /** * Get an insights report. * * GET /v1/insights/{requestId} */ export const getApiV1InsightsRequestId = async (args: GetApiV1InsightsRequestIdArgs, options: GetApiV1InsightsRequestIdOptions) => { const {baseUrl, fetch: fetchFn = fetch, Bearer} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") if (Bearer !== undefined) headers.set("Authorization", Bearer) const url = `${baseUrl.replace(/\/+$/, '')}/v1/insights/${encodeURIComponent(String(args.requestId))}${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(insightsResponse, await res.json()) };