import {z} from 'zod' export type BalanceChangeType = 'ORDER' | 'ORDER_ADJUSTMENT' | 'REFUND' | 'SETTLEMENT' | 'GRANT' | 'DEBIT' | 'REV_SHARE' | 'REV_SHARE_REVOKE'; export type GetApiAccountBillingTransactionsArgs = {$cursor?: string | undefined, type?: Array | undefined, groupBy?: 'operationId' | undefined}; export type GetApiAccountBillingTransactionsOptions = {baseUrl?: string | undefined, bearer?: string | undefined, fetch?: typeof fetch | undefined}; export const balanceChangeType = z.enum(["ORDER", "ORDER_ADJUSTMENT", "REFUND", "SETTLEMENT", "GRANT", "DEBIT", "REV_SHARE", "REV_SHARE_REVOKE"]); export const billingTransactionResponse = z.object({"@type": z.literal("unstoppabledomains.com/partner.v3.BillingTransaction"), id: z.string(), type: balanceChangeType, amountUsdCents: z.number().int(), operationId: z.string(), createdAtTimestamp: z.number().int(), notes: z.string().nullable()}); export const cursorListResponseNext = z.object({$cursor: z.string().optional()}); export const billingTransactionListResponse = z.object({"@type": z.literal("unstoppabledomains.com/partner.v3.CursorList"), items: z.array(billingTransactionResponse), next: cursorListResponseNext.nullable()}); export const billingTransactionGroupResponse = z.object({"@type": z.literal("unstoppabledomains.com/partner.v3.BillingTransactionGroup"), operationId: z.string(), operationType: z.enum(["ADMIN_GENERIC", "DOMAIN_ADMIN_UPDATE", "DOMAIN_RENEW", "DOMAIN_RESTORE", "ACCOUNT_UPDATE", "DOMAIN_DNS_RECORD_CREATE", "DOMAIN_DNS_RECORD_UPDATE", "DOMAIN_DNS_RECORD_DELETE", "DOMAIN_DNS_RECORD_BATCH", "DOMAIN_DNS_SECURITY_ENABLE", "DOMAIN_DNS_SECURITY_DELETE", "DOMAIN_DNS_NAME_SERVER_UPDATE", "DOMAIN_HOSTING_UPDATE", "DOMAIN_HOSTING_DISABLE", "DOMAIN_TRANSFER_OUT", "DOMAIN_TRANSFER_OUT_TOGGLE", "DOMAIN_FLAGS_UPDATE", "DOMAIN_CONTACTS_UPDATE", "CONTACT_CREATE", "DOMAIN_SUGGESTION_CREATE", "DOMAIN_SUGGESTION_REFRESH", "DOMAIN_ADMIN_DNS_ZONE_MIGRATE", "LTO_INITIATE", "LTO_COMPLETE", "LTO_CANCEL", "DOMAIN_AUCTION_INTERNAL_PUSH"]), domain: z.string().nullable(), createdAtTimestamp: z.number().int(), totalAmountUsdCents: z.number().int(), transactions: z.array(billingTransactionResponse)}); export const billingTransactionGroupListResponse = z.object({"@type": z.literal("unstoppabledomains.com/partner.v3.CursorList"), items: z.array(billingTransactionGroupResponse), next: cursorListResponseNext.nullable()}); export const getApiAccountBillingTransactionsResponse = z.union([billingTransactionListResponse, billingTransactionGroupListResponse]); 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 billing transactions * * GET /account/billing/transactions */ export const getApiAccountBillingTransactions = async (args: GetApiAccountBillingTransactionsArgs, options?: GetApiAccountBillingTransactionsOptions) => { const {baseUrl = "https://api.unstoppabledomains.com/partner/v3", fetch: fetchFn = fetch, bearer} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") if (args.$cursor != null) query.append("$cursor", String(args.$cursor)) for (const item of args.type ?? []) query.append("type", String(item)) if (args.groupBy != null) query.append("groupBy", String(args.groupBy)) if (bearer !== undefined) headers.set('authorization', `Bearer ${bearer}`) const url = `${baseUrl.replace(/\/+$/, '')}/account/billing/transactions${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(getApiAccountBillingTransactionsResponse, await res.json()) };