import {z} from 'zod' export type GetApiBillingEventsOptions = {baseUrl: string, fetch?: typeof fetch | undefined}; export const creditDistributionEventData = z.object({creditLocator: z.string()}); export const creditDistributionEvents = z.object({"billing.creditdistribution.discard": creditDistributionEventData.optional(), "billing.creditdistribution.reverse": creditDistributionEventData.optional(), "billing.creditdistribution.create": creditDistributionEventData.optional(), "billing.creditdistribution.distribute": creditDistributionEventData.optional()}); export const listPageResponseULID = z.object({listCompleted: z.boolean(), items: z.array(z.string())}); export const delinquencyEventEventData = z.object({delinquencyLocator: z.string(), delinquencyEventLocator: z.string(), policyLocators: listPageResponseULID}); export const delinquencyEventEvents = z.object({"billing.delinquency.delinquencyevent.cancel": delinquencyEventEventData.optional(), "billing.delinquency.delinquencyevent.activate": delinquencyEventEventData.optional(), "billing.delinquency.delinquencyevent.create": delinquencyEventEventData.optional(), "billing.delinquency.delinquencyevent.trigger": delinquencyEventEventData.optional()}); export const delinquencyEventData = z.object({delinquencyLocator: z.string(), policyLocators: listPageResponseULID}); export const delinquencyFailureEventData = z.object({delinquencyLocator: z.string(), policyLocators: listPageResponseULID, delinquencyState: z.enum(["preGrace", "inGrace", "lapseTriggered", "settled", "lapseTransactionCreated"])}); export const delinquencyEvents = z.object({"billing.delinquency.create": delinquencyEventData.optional(), "billing.delinquency.settle": delinquencyEventData.optional(), "billing.delinquency.lapse": delinquencyEventData.optional(), "billing.delinquency.fail": delinquencyFailureEventData.optional()}); export const disbursementEventData = z.object({disbursementLocator: z.string()}); export const disbursementEvents = z.object({"billing.disbursement.create": disbursementEventData.optional(), "billing.disbursement.anonymize": disbursementEventData.optional(), "billing.disbursement.reject": disbursementEventData.optional(), "billing.disbursement.discard": disbursementEventData.optional(), "billing.disbursement.validate": disbursementEventData.optional(), "billing.disbursement.execute": disbursementEventData.optional(), "billing.disbursement.reverse": disbursementEventData.optional(), "billing.disbursement.approve": disbursementEventData.optional()}); export const installmentLatticeCreateData = z.object({installmentLatticeLocator: z.string()}); export const installmentEvents = z.object({"billing.installmentlattice.create": installmentLatticeCreateData.optional()}); export const invoiceAutopayData = z.object({invoiceLocator: z.string(), accountLocator: z.string(), invoiceType: z.enum(["normal", "aggregate"]), policyLocators: listPageResponseULID, autopayTime: z.string()}); export const invoiceDiscardData = z.object({invoiceLocator: z.string(), accountLocator: z.string(), invoiceType: z.enum(["normal", "aggregate"])}); export const invoiceGeneratedEventData = z.object({invoiceLocator: z.string(), accountLocator: z.string(), invoiceType: z.enum(["normal", "aggregate"]), policyLocators: listPageResponseULID, generateTime: z.string()}); export const invoiceSettledEventData = z.object({invoiceLocator: z.string(), accountLocator: z.string(), invoiceType: z.enum(["normal", "aggregate"]), policyLocators: listPageResponseULID}); export const invoiceEvents = z.object({"billing.invoice.autopayfailed": invoiceAutopayData.optional(), "billing.invoice.discard": invoiceDiscardData.optional(), "billing.invoice.generate": invoiceGeneratedEventData.optional(), "billing.invoice.settle": invoiceSettledEventData.optional(), "billing.invoice.autopay": invoiceAutopayData.optional(), "billing.invoice.unsettle": invoiceSettledEventData.optional()}); export const numberingEventData = z.object({entityLocator: z.string()}); export const billingNumberingEvents = z.object({"payment.numberAssignmentFailed": numberingEventData.optional(), "disbursement.numberAssignmentFailed": numberingEventData.optional(), "invoice.numberAssignmentFailed": numberingEventData.optional()}); export const paymentEventData = z.object({paymentLocator: z.string(), policyLocators: listPageResponseULID}); export const paymentEvents = z.object({"billing.payment.post": paymentEventData.optional(), "billing.payment.anonymize": paymentEventData.optional(), "billing.payment.cancel": paymentEventData.optional(), "billing.payment.validationfailed": paymentEventData.optional(), "billing.payment.request": paymentEventData.optional(), "billing.payment.reverse": paymentEventData.optional(), "billing.payment.distribute": paymentEventData.optional(), "billing.payment.execute": paymentEventData.optional(), "billing.payment.create": paymentEventData.optional(), "billing.payment.discard": paymentEventData.optional(), "billing.payment.fail": paymentEventData.optional()}); export const shortfallEventData = z.object({shortfallCreditLocator: z.string()}); export const shortfallCreditEvents = z.object({"billing.shortfallcredit.reverse": shortfallEventData.optional(), "billing.shortfallcredit.distribute": shortfallEventData.optional(), "billing.shortfallcredit.create": shortfallEventData.optional()}); export const writeOffEventData = z.object({writeOffLocator: z.string(), policyLocators: listPageResponseULID}); export const writeOffEvents = z.object({"billing.writeoff.reverse": writeOffEventData.optional(), "billing.writeoff.create": writeOffEventData.optional(), "billing.writeoff.distribute": writeOffEventData.optional()}); export const holdEventData = z.object({holdLocator: z.string()}); export const holdEvents = z.object({"billing.hold.create": holdEventData.optional(), "billing.hold.activate": holdEventData.optional(), "billing.hold.reset": holdEventData.optional(), "billing.hold.validate": holdEventData.optional(), "billing.hold.release": holdEventData.optional(), "billing.hold.discard": holdEventData.optional()}); export const billingServiceEventTypeDefinitions = z.object({creditDistributionEvents: creditDistributionEvents, delinquencyEventEvents: delinquencyEventEvents, delinquencyEvents: delinquencyEvents, disbursementEvents: disbursementEvents, installmentEvents: installmentEvents, invoiceEvents: invoiceEvents, numberingEvents: billingNumberingEvents, paymentEvents: paymentEvents, shortfallCreditEvents: shortfallCreditEvents, writeOffEvents: writeOffEvents, holdEvents: holdEvents}); 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 /billing/events */ export const getApiBillingEvents = async (options: GetApiBillingEventsOptions) => { const {baseUrl, fetch: fetchFn = fetch} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") const url = `${baseUrl.replace(/\/+$/, '')}/billing/events${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(billingServiceEventTypeDefinitions, await res.json()) };