import {z} from 'zod' export type GetApiAccountsArgs = {limit?: number | undefined, offset?: number | undefined, primaryEmailAddress?: string | undefined, search?: string | undefined, include?: ('market' | Array<'market'>) | undefined}; export type GetApiAccountsOptions = {baseUrl?: string | undefined, CommonAuth?: string | undefined, fetch?: typeof fetch | undefined}; export const getApiAccountsResponse = z.object({limit: z.number().int().gte(1).lte(1000).optional(), offset: z.number().int().optional(), count: z.number().int(), rows: z.array(z.object({id: z.string(), type: z.enum(["Business", "Personal"]), status: z.enum(["applicationPending", "active", "inactive", "suspended", "customerClosed", "equalsFullClosed", "equalsReadonlyClosed", "identityVerificationRequired"]), termsAccepted: z.boolean(), correlationId: z.string().optional(), privacyAccepted: z.boolean(), salesperson: z.string().max(256).nullable(), accountManager: z.string().max(256).nullable(), bankEntity: z.string().max(256).nullable().optional(), configurationId: z.string().max(36).nullable().optional(), currentRiskLevel: z.enum(["Low", "Medium", "MediumHigh", "High", "Dormant", "Extreme", "redacted"]).optional(), tier: z.enum(["BRONZE", "SILVER", "GOLD", "NotTraded"]).optional(), features: z.object({id: z.string().max(36).optional(), accountId: z.string().optional(), payments: z.boolean().optional(), batchPayments: z.boolean().optional(), cards: z.boolean().optional(), virtualCards: z.enum(["active", "inactive", "restricted"]).optional(), physicalCards: z.enum(["active", "inactive", "restricted"]).optional(), microCorp: z.boolean().nullable().optional(), sharedCardProductId: z.string().nullable().optional(), individualVirtualCardProductId: z.string().nullable().optional(), individualPhysicalCardProductId: z.string().nullable().optional(), useBalanceName: z.boolean().optional(), forwardContracts: z.boolean().optional(), sourceOfBalance: z.enum(["boxes", "mts"]).optional(), cardsSharedType: z.enum(["prepaid", "debit"]).nullable().optional(), cardsIndividualType: z.enum(["prepaid", "debit"]).nullable().optional(), selfApprove: z.boolean().optional(), apiIgnorePaymentApproval: z.boolean().optional(), moveMoneyRequests: z.boolean().optional(), subBalances: z.boolean().optional(), autoCreditToFundsHeld: z.boolean().optional(), dualAuthorise: z.boolean().optional(), freeInternalTransfers: z.boolean().optional(), expediteCardProcessingEnabled: z.boolean().optional(), enforceMFAVerification: z.boolean().optional(), pinForVirtualCardsEnabled: z.boolean().optional(), sharedCardsEnabled: z.boolean().optional(), individualCardsEnabled: z.boolean().optional(), lowBalanceAlertsEnabled: z.boolean().optional(), minimumCardOrderTopUpAmount: z.number().nullable().optional(), minimumCardOrderTopUpAmountReached: z.boolean().optional(), statementsFrom: z.string().nullable().optional(), createdAt: z.string().optional(), updatedAt: z.string().optional()}).optional(), productId: z.string().max(36).optional(), primaryOwner: z.object({id: z.string(), firstName: z.string().max(256), lastName: z.string().max(256), title: z.enum(["Master", "Mr", "Miss", "Mrs", "Ms", "Mx"]).nullable().optional(), middleInitials: z.string().max(10).nullable(), dob: z.string().nullable(), gender: z.string().max(20).nullable(), nationality: z.string().max(256).nullable(), nationalities: z.array(z.enum(["AD", "AE", "AF", "AG", "AI", "AL", "AM", "AO", "AQ", "AR", "AS", "AT", "AU", "AW", "AX", "AZ", "BA", "BB", "BD", "BE", "BF", "BG", "BH", "BI", "BJ", "BL", "BM", "BN", "BO", "BQ", "BR", "BS", "BT", "BV", "BW", "BY", "BZ", "CA", "CC", "CD", "CF", "CG", "CH", "CI", "CK", "CL", "CM", "CN", "CO", "CR", "CU", "CV", "CW", "CX", "CY", "CZ", "DE", "DJ", "DK", "DM", "DO", "DZ", "EC", "EE", "EG", "EH", "ER", "ES", "ET", "FI", "FJ", "FK", "FM", "FO", "FR", "GA", "GB", "GD", "GE", "GF", "GG", "GH", "GI", "GL", "GM", "GN", "GP", "GQ", "GR", "GS", "GT", "GU", "GW", "GY", "HK", "HM", "HN", "HR", "HT", "HU", "ID", "IE", "IL", "IM", "IN", "IO", "IQ", "IR", "IS", "IT", "JE", "JM", "JO", "JP", "KE", "KG", "KH", "KI", "KM", "KN", "KP", "KR", "KW", "KY", "KZ", "LA", "LB", "LC", "LI", "LK", "LR", "LS", "LT", "LU", "LV", "LY", "MA", "MC", "MD", "ME", "MF", "MG", "MH", "MK", "ML", "MM", "MN", "MO", "MP", "MQ", "MR", "MS", "MT", "MU", "MV", "MW", "MX", "MY", "MZ", "NA", "NC", "NE", "NF", "NG", "NI", "NL", "NO", "NP", "NR", "NU", "NZ", "OM", "PA", "PE", "PF", "PG", "PH", "PK", "PL", "PM", "PN", "PR", "PS", "PT", "PW", "PY", "QA", "RE", "RO", "RS", "RU", "RW", "SA", "SB", "SC", "SD", "SE", "SG", "SH", "SI", "SJ", "SK", "SL", "SM", "SN", "SO", "SR", "SS", "ST", "SV", "SX", "SY", "SZ", "TC", "TD", "TF", "TG", "TH", "TJ", "TK", "TL", "TM", "TN", "TO", "TR", "TT", "TV", "TW", "TZ", "UA", "UG", "UM", "US", "UY", "UZ", "VA", "VC", "VE", "VG", "VI", "VN", "VU", "WF", "WS", "XK", "YE", "YT", "ZA", "ZM", "ZW"])).nullable().optional(), countryOfResidence: z.string().max(256).nullable(), primaryMobileNumber: z.string().max(50).nullable().optional(), primaryEmailAddress: z.string().max(256), avatar: z.object({url: z.string().optional(), fileName: z.string().optional()}).optional(), sendInvite: z.boolean().optional(), roleId: z.string().optional(), verifyEmailAddress: z.boolean().optional(), verifyMobileNumber: z.boolean().optional(), sub: z.string().max(256).nullable().optional(), hasPeopleCard: z.boolean().optional(), card: z.object({id: z.string()}).nullable().optional(), status: z.enum(["active", "deactivated", "kycReferred", "rejected"]), locale: z.literal("en-GB").nullable(), productId: z.string().max(36), avatarId: z.string().nullable(), avatarCdnUrl: z.string().nullable(), emailTheme: z.string().max(32).nullable().optional(), preferred2FAMethod: z.enum(["whatsapp", "sms"]).nullable(), persona: z.record(z.string(), z.unknown()).optional(), createdAt: z.string(), updatedAt: z.string()}).optional(), primaryOwnerPersonaId: z.string().max(36).nullable().optional(), business: z.object({accountId: z.string().optional(), name: z.string().max(256).optional(), countryOfRegistration: z.string().max(256).nullable().optional(), companyType: z.string().max(50).nullable().optional(), companiesHouseId: z.string().max(50).nullable().optional(), telephoneNumber: z.string().max(50).nullable().optional(), timezone: z.string().max(256).nullable().optional(), registeredName: z.string().max(256).nullable().optional(), tradingName: z.string().max(256).nullable().optional(), website: z.string().max(256).nullable().optional(), industry: z.string().max(256).nullable().optional(), fourthLine: z.string().max(21).nullable().optional(), logo: z.object({url: z.string(), fileName: z.string()}).nullable().optional(), createdAt: z.string().optional(), updatedAt: z.string().optional()}).nullable().optional(), personal: z.object({accountId: z.string().optional(), name: z.string().max(256).optional(), countryOfRegistration: z.string().max(256).nullable().optional(), companyType: z.string().max(50).nullable().optional(), companiesHouseId: z.string().max(50).nullable().optional(), telephoneNumber: z.string().max(50).nullable().optional(), timezone: z.string().max(256).nullable().optional(), registeredName: z.string().max(256).nullable().optional(), tradingName: z.string().max(256).nullable().optional(), website: z.string().max(256).nullable().optional(), industry: z.string().max(256).nullable().optional(), logo: z.object({url: z.string(), fileName: z.string()}).nullable().optional(), createdAt: z.string().optional(), updatedAt: z.string().optional()}).nullable().optional(), addresses: z.array(z.object({id: z.string(), type: z.string(), nickName: z.string().max(256).nullable().optional(), addressLine1: z.string().min(1).max(256), addressLine2: z.string().max(256).nullable().optional(), addressLine3: z.string().max(256).nullable().optional(), addressContact: z.string().max(256).nullable().optional(), city: z.string().max(256), postcode: z.string().max(50), country: z.string().max(256), countryCode: z.string().max(2).nullable().optional(), createdAt: z.string().optional(), updatedAt: z.string().optional()})).optional(), currencies: z.array(z.object({id: z.string(), code: z.string(), name: z.string().optional(), status: z.object({enabled: z.boolean().optional()}).optional()})).optional(), payments: z.object({id: z.string().optional(), active: z.boolean().optional(), maxLength: z.number().optional(), depositRequired: z.number().optional(), maxAmount: z.number().optional(), accountId: z.string().optional()}).optional(), solutions: z.boolean().optional(), maxCardsAndBudgets: z.object({maxIndividualCards: z.number().optional(), maxSharedCards: z.number().optional(), maxBudgets: z.number().optional(), maxIndividualCardsPerPerson: z.number().optional()}).nullable().optional(), locale: z.literal("en-GB"), preferredLanguage: z.enum(["EN", "FR", "DE", "ES", "IT", "NL", "PT"]).nullable(), marketId: z.string().max(36).nullable().optional(), market: z.object({id: z.string(), name: z.string().optional(), bank: z.string().nullable().optional(), baseCurrencyId: z.string().nullable().optional(), atmWithdrawalFee: z.number().gte(0).nullable().optional(), createdAt: z.string().optional(), updatedAt: z.string().optional()}).optional(), createdAt: z.string(), updatedAt: z.string()}))}); 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 }; /** * List all accounts * * GET /accounts */ export const getApiAccounts = async (args: GetApiAccountsArgs, options?: GetApiAccountsOptions) => { const {baseUrl = "https://api.equalsmoney.com/v2", fetch: fetchFn = fetch, CommonAuth} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") if (args.limit != null) query.append("limit", String(args.limit)) if (args.offset != null) query.append("offset", String(args.offset)) if (args.primaryEmailAddress != null) query.append("primaryEmailAddress", String(args.primaryEmailAddress)) if (args.search != null) query.append("search", String(args.search)) if (args.include != null) query.append("include", String(args.include)) if (CommonAuth !== undefined) headers.set("Authorization", CommonAuth) const url = `${baseUrl.replace(/\/+$/, '')}/accounts${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(getApiAccountsResponse, await res.json()) };