import {z} from 'zod' export type GetApiAccountsAccountIdArgs = {accountId: number, include?: string | undefined}; export type GetApiAccountsAccountIdOptions = {baseUrl: string, fetch?: typeof fetch | undefined}; export const money = z.object({amount: z.number(), currency: z.enum(["AUD", "BRL", "CAD", "EUR", "GBP", "HKD", "IDR", "INR", "JPY", "NZD", "SGD", "USD", "ZAR", "CNY", "VND", "MYR", "CHF"])}); export const identifier = z.object({type: z.enum(["NIE", "DNI", "EIN", "BN", "AADHAR", "NIN", "NRIC"]).optional(), value: z.string().optional()}); export const accountAddress = z.object({zip: z.string().optional(), country: z.string().optional(), address3: z.string().optional(), address2: z.string().optional(), city: z.string().optional(), sourceType: z.string().optional(), address1: z.string().optional(), street: z.string().optional(), state: z.string().optional(), type: z.enum(["HOME", "BUSINESS", "POBOX", "RETAIL", "OFFICE", "SMALL_BUSINESS", "COMMUNICATION", "PERMANENT", "STATEMENT_ADDRESS", "PAYMENT", "PAYOFF", "UNKNOWN"]).optional()}); export const phoneNumber = z.object({type: z.enum(["HOME", "WORK", "LANDLINE", "MOBILE"]).optional(), value: z.string().optional()}); export const email = z.object({type: z.enum(["PRIMARY", "SECONDARY", "PERSONAL", "WORK", "OTHERS"]).optional(), value: z.string().optional()}); export const accountProfile = z.object({identifier: z.array(identifier).optional(), address: z.array(accountAddress).optional(), phoneNumber: z.array(phoneNumber).optional(), email: z.array(email).optional()}); export const name = z.object({middle: z.string().optional(), last: z.string().optional(), fullName: z.string().optional(), first: z.string().optional()}); export const accountHolder = z.object({identifier: z.array(identifier).optional(), gender: z.string().optional(), ownership: z.enum(["PRIMARY", "SECONDARY", "CUSTODIAN", "OTHERS", "POWER_OF_ATTORNEY", "TRUSTEE", "JOINT_OWNER", "BENEFICIARY", "AAS", "BUSINESS", "DBA", "TRUST"]).optional(), name: name.optional()}); export const accountDataset = z.object({lastUpdated: z.string().optional(), updateEligibility: z.enum(["ALLOW_UPDATE", "ALLOW_UPDATE_WITH_CREDENTIALS", "DISALLOW_UPDATE"]).optional(), additionalStatus: z.enum(["LOGIN_IN_PROGRESS", "DATA_RETRIEVAL_IN_PROGRESS", "ACCT_SUMMARY_RECEIVED", "AVAILABLE_DATA_RETRIEVED", "PARTIAL_DATA_RETRIEVED", "DATA_RETRIEVAL_FAILED", "DATA_NOT_AVAILABLE", "ACCOUNT_LOCKED", "ADDL_AUTHENTICATION_REQUIRED", "BETA_SITE_DEV_IN_PROGRESS", "CREDENTIALS_UPDATE_NEEDED", "INCORRECT_CREDENTIALS", "PROPERTY_VALUE_NOT_AVAILABLE", "INVALID_ADDL_INFO_PROVIDED", "REQUEST_TIME_OUT", "SITE_BLOCKING_ERROR", "UNEXPECTED_SITE_ERROR", "SITE_NOT_SUPPORTED", "SITE_UNAVAILABLE", "TECH_ERROR", "USER_ACTION_NEEDED_AT_SITE", "SITE_SESSION_INVALIDATED", "NEW_AUTHENTICATION_REQUIRED", "DATASET_NOT_SUPPORTED", "ENROLLMENT_REQUIRED_FOR_DATASET", "CONSENT_REQUIRED", "CONSENT_EXPIRED", "CONSENT_REVOKED", "INCORRECT_OAUTH_TOKEN", "MIGRATION_IN_PROGRESS"]).optional(), nextUpdateScheduled: z.string().optional(), name: z.enum(["BASIC_AGG_DATA", "ADVANCE_AGG_DATA", "ACCT_PROFILE", "DOCUMENT"]).optional(), lastUpdateAttempt: z.string().optional()}); export const rewardBalance = z.object({expiryDate: z.string().optional(), balanceToReward: z.string().optional(), balanceType: z.enum(["EXPIRING_BALANCE", "BALANCE_TO_LEVEL", "BALANCE_TO_REWARD", "BALANCE", "TOTAL_BALANCE"]).optional(), balance: z.number().optional(), description: z.string().optional(), balanceToLevel: z.string().optional(), units: z.string().optional()}); export const bankTransferCode = z.object({id: z.string().optional(), type: z.enum(["BSB", "IFSC", "ROUTING_NUMBER", "SORT_CODE"]).optional()}); export const coverageAmount = z.object({cover: money.optional(), unitType: z.enum(["PER_FAMILY", "PER_MEMBER"]).optional(), type: z.enum(["DEDUCTIBLE", "OUT_OF_POCKET", "ANNUAL_BENEFIT", "MAX_BENEFIT", "COVERAGE_AMOUNT", "MONTHLY_BENEFIT", "OTHER"]).optional(), limitType: z.enum(["IN_NETWORK", "OUT_NETWORK"]).optional(), met: money.optional()}); export const coverage = z.object({amount: z.array(coverageAmount).optional(), planType: z.enum(["PPO", "HMO", "UNKNOWN"]).optional(), endDate: z.string().optional(), type: z.enum(["VISION", "DENTAL", "MEDICAL", "HEALTH", "DEATH_COVER", "TOTAL_PERMANENT_DISABILITY", "ACCIDENTAL_DEATH_COVER", "INCOME_PROTECTION", "DEATH_TOTAL_PERMANENT_DISABILITY", "OTHER"]).optional(), startDate: z.string().optional()}); export const autoRefresh = z.object({additionalStatus: z.enum(["SCHEDULED", "TEMP_ERROR", "SITE_BLOCKING", "SITE_NOT_SUPPORTED", "REAL_TIME_MFA_REQUIRED", "USER_ACTION_REQUIRED", "UNSUBSCRIBED", "MANUAL_ACCOUNT"]).optional(), asOfDate: z.string().optional(), status: z.enum(["ENABLED", "DISABLED"]).optional()}); export const fullAccountNumberList = z.object({paymentAccountNumber: z.string().optional(), unmaskedAccountNumber: z.string().optional()}); export const loanPayoffDetails = z.object({payByDate: z.string().optional(), payoffAmount: money.optional(), outstandingBalance: money.optional()}); export const paymentIdentifier = z.object({type: z.enum(["REFERENCE_NUMBER", "PLATFORM_CODE"]).optional(), value: z.string().optional()}); export const paymentBankTransferCode = z.object({id: z.string().optional(), type: z.enum(["ROUTING_NUMBER", "BSB", "IFSC", "SORT_CODE"]).optional()}); export const paymentProfile = z.object({identifier: paymentIdentifier.optional(), address: z.array(accountAddress).optional(), paymentBankTransferCode: paymentBankTransferCode.optional()}); export const account = z.object({availableCash: money.optional(), includeInNetWorth: z.boolean().optional(), moneyMarketBalance: money.optional(), enrollmentDate: z.string().optional(), estimatedDate: z.string().optional(), memo: z.string().optional(), guarantor: z.string().optional(), interestPaidLastYear: money.optional(), lastUpdated: z.string().optional(), balance: money.optional(), homeInsuranceType: z.enum(["HOME_OWNER", "RENTAL", "RENTER", "UNKNOWN", "OTHER"]).optional(), id: z.number().int().optional(), cash: money.optional(), totalCreditLine: money.optional(), providerName: z.string().optional(), valuationType: z.enum(["SYSTEM", "MANUAL"]).optional(), marginBalance: money.optional(), apr: z.number().optional(), availableCredit: money.optional(), currentBalance: money.optional(), isManual: z.boolean().optional(), profile: accountProfile.optional(), escrowBalance: money.optional(), nextLevel: z.string().optional(), classification: z.enum(["OTHER", "PERSONAL", "CORPORATE", "SMALL_BUSINESS", "TRUST", "ADD_ON_CARD", "VIRTUAL_CARD"]).optional(), loanPayoffAmount: money.optional(), interestRateType: z.enum(["FIXED", "VARIABLE", "UNKNOWN", "OTHER"]).optional(), loanPayByDate: z.string().optional(), faceAmount: money.optional(), policyFromDate: z.string().optional(), premiumPaymentTerm: z.string().optional(), policyTerm: z.string().optional(), repaymentPlanType: z.enum(["STANDARD", "GRADUATED", "EXTENDED", "INCOME_BASED", "INCOME_CONTINGENT", "INCOME_SENSITIVE", "PAY_AS_YOU_EARN", "REVISED_PAY_AS_YOU_EARN"]).optional(), availableBalance: money.optional(), accountStatus: z.enum(["ACTIVE", "INACTIVE", "TO_BE_CLOSED", "CLOSED", "DELETED"]).optional(), lifeInsuranceType: z.enum(["OTHER", "TERM_LIFE_INSURANCE", "UNIVERSAL_LIFE_INSURANCE", "WHOLE_LIFE_INSURANCE", "VARIABLE_LIFE_INSURANCE", "ULIP", "ENDOWMENT"]).optional(), fullAccountNumber: z.string().optional(), premium: money.optional(), aggregationSource: z.enum(["SYSTEM", "USER"]).optional(), overDraftLimit: money.optional(), nickname: z.string().optional(), term: z.string().optional(), interestRate: z.number().optional(), deathBenefit: money.optional(), address: accountAddress.optional(), cashValue: money.optional(), holder: z.array(accountHolder).optional(), "401kLoan": money.optional(), homeValue: money.optional(), accountNumber: z.string().optional(), createdDate: z.string().optional(), interestPaidYTD: money.optional(), providerAccountId: z.number().int().optional(), collateral: z.string().optional(), dataset: z.array(accountDataset).optional(), runningBalance: money.optional(), sourceId: z.string().optional(), dueDate: z.string().optional(), frequency: z.enum(["DAILY", "ONE_TIME", "WEEKLY", "EVERY_2_WEEKS", "SEMI_MONTHLY", "MONTHLY", "QUARTERLY", "SEMI_ANNUALLY", "ANNUALLY", "EVERY_2_MONTHS", "EBILL", "FIRST_DAY_MONTHLY", "LAST_DAY_MONTHLY", "EVERY_4_WEEKS", "UNKNOWN", "OTHER"]).optional(), maturityAmount: money.optional(), associatedProviderAccountId: z.array(z.number().int()).optional(), isAsset: z.boolean().optional(), principalBalance: money.optional(), totalCashLimit: money.optional(), maturityDate: z.string().optional(), minimumAmountDue: money.optional(), annualPercentageYield: z.number().optional(), accountType: z.string().optional(), originationDate: z.string().optional(), totalVestedBalance: money.optional(), rewardBalance: z.array(rewardBalance).optional(), sourceAccountStatus: z.enum(["IN_REPAYMENT", "DEFAULTED", "IN_SCHOOL", "IN_GRACE_PERIOD", "DELINQUENCY", "DEFERMENT", "FORBEARANCE"]).optional(), derivedApr: z.number().optional(), policyEffectiveDate: z.string().optional(), totalUnvestedBalance: money.optional(), annuityBalance: money.optional(), accountName: z.string().optional(), totalCreditLimit: money.optional(), policyStatus: z.enum(["ACTIVE", "INACTIVE", "OTHER"]).optional(), shortBalance: money.optional(), lender: z.string().optional(), lastEmployeeContributionAmount: money.optional(), providerId: z.string().optional(), lastPaymentDate: z.string().optional(), primaryRewardUnit: z.string().optional(), lastPaymentAmount: money.optional(), remainingBalance: money.optional(), userClassification: z.enum(["BUSINESS", "PERSONAL"]).optional(), bankTransferCode: z.array(bankTransferCode).optional(), expirationDate: z.string().optional(), coverage: z.array(coverage).optional(), cashApr: z.number().optional(), autoRefresh: autoRefresh.optional(), oauthMigrationStatus: z.enum(["IN_PROGRESS", "TO_BE_MIGRATED", "COMPLETED"]).optional(), displayedName: z.string().optional(), fullAccountNumberList: fullAccountNumberList.optional(), amountDue: money.optional(), currentLevel: z.string().optional(), originalLoanAmount: money.optional(), policyToDate: z.string().optional(), loanPayoffDetails: loanPayoffDetails.optional(), paymentProfile: paymentProfile.optional(), CONTAINER: z.enum(["bank", "creditCard", "investment", "insurance", "loan", "reward", "realEstate", "otherAssets", "otherLiabilities"]).optional(), lastEmployeeContributionDate: z.string().optional(), lastPayment: money.optional(), recurringPayment: money.optional()}); export const accountResponse = z.object({account: z.array(account).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 Account Details * * GET /accounts/{accountId} */ export const getApiAccountsAccountId = async (args: GetApiAccountsAccountIdArgs, options: GetApiAccountsAccountIdOptions) => { const {baseUrl, fetch: fetchFn = fetch} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json;charset=UTF-8") if (args.include != null) query.append("include", String(args.include)) const url = `${baseUrl.replace(/\/+$/, '')}/accounts/${encodeURIComponent(String(args.accountId))}${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(accountResponse, await res.json()) };