import {z} from 'zod' export type GetApiPricePlansArgs = {nextToken?: string | undefined, pageSize?: number | undefined}; export type GetApiPricePlansOptions = {baseUrl?: string | undefined, bearerAuth?: string | undefined, fetch?: typeof fetch | undefined}; export const pricingCycleInterval = z.enum(["WEEKLY", "MONTHLY", "QUARTERLY", "HALF_YEARLY", "ANNUALLY"]); export const pricingCycleConfig = z.object({interval: pricingCycleInterval, startOffset: z.object({dayOffset: z.string(), monthOffset: z.string()}).optional(), gracePeriod: z.number().int(), anniversaryCycle: z.boolean().optional()}); export const pricingModel = z.enum(["TIERED", "VOLUME"]); export const priceType = z.enum(["FLAT", "PER_UNIT", "PACKAGE"]); export const slab = z.object({order: z.number().int().gte(1).lte(10), startAfter: z.number(), priceType: priceType, slabConfig: z.record(z.string(), z.string()).optional()}); export const ratePlan = z.object({pricingModel: pricingModel, slabs: z.array(slab)}); export const slabRate = z.object({order: z.number().int(), rate: z.number(), slabRateConfig: z.record(z.string(), z.string()).optional()}); export const rateValue = z.object({currency: z.string(), slabRates: z.array(slabRate), rateConfig: z.record(z.string(), z.string()).optional()}); export const usageRateCard = z.object({displayName: z.string().optional(), tag: z.string().optional(), usageMeterId: z.string(), ratePlan: ratePlan, rateValues: z.array(rateValue)}); export const invoiceTiming = z.enum(["IN_ADVANCE", "IN_ARREARS", "PREPAID"]); export const fixedFeeType = z.enum(["ONE_TIME", "RECURRING"]); export const currencyRateValue = z.object({currency: z.string(), rate: z.number()}); export const recurrenceConfig = z.object({interval: z.number().int().optional(), offset: z.number().int().optional()}); export const fixedFeeRateCard = z.object({id: z.string().max(50), displayName: z.string().optional(), tag: z.string().optional(), invoiceTiming: invoiceTiming.optional(), type: fixedFeeType.optional(), rateValues: z.array(currencyRateValue), enableProration: z.boolean(), recurrenceConfig: recurrenceConfig.optional()}); export const addOnType = z.enum(["LICENSE", "FIXED_FEE", "CREDIT_GRANT", "NAMED_LICENSE"]); export const usageCycleInterval = z.enum(["WEEKLY", "MONTHLY", "QUARTERLY", "HALF_YEARLY", "ANNUALLY"]); export const maxQuantityBreachAction = z.literal("DO_NOTHING"); export const licenseRateCardConfig = z.object({maxQuantity: z.number().int().optional(), maxQuantityBreachAction: maxQuantityBreachAction.optional()}); export const proratedRefundMode = z.enum(["NONE", "CREDITS", "PAYMENT", "WALLET"]); export const licenseRateCard = z.object({id: z.string().max(50), type: addOnType.optional(), displayName: z.string().optional(), tag: z.string().optional(), invoiceTiming: invoiceTiming.optional(), usageCycle: usageCycleInterval.optional(), enableProration: z.boolean(), config: licenseRateCardConfig.optional(), ratePlan: ratePlan, rateValues: z.array(rateValue), proratedRefundMode: proratedRefundMode.optional()}); export const featureConfig = z.object({effectiveFrom: z.string().optional(), effectiveUntil: z.string(), featureCreditLimit: z.number().gte(0)}); export const billingEntitlementRateCard = z.object({featureId: z.string(), featureConfigs: z.array(featureConfig), tag: z.string().optional(), invoiceTiming: invoiceTiming, displayName: z.string().optional(), ratePlan: ratePlan, rateValues: z.array(rateValue), recurrenceConfig: recurrenceConfig.optional()}); export const billingConfig = z.object({interval: z.number().int().optional(), startOffset: z.number().int().optional()}); export const entitlementOverageRateCard = z.object({featureId: z.string().max(50), displayName: z.string().optional(), tag: z.string().optional(), maxQuantity: z.number().optional(), ratePlan: ratePlan, rateValues: z.array(rateValue), billingConfig: billingConfig.optional()}); export const minimumCommitment = z.object({displayName: z.string(), rateValues: z.array(currencyRateValue)}); export const expiryType = z.enum(["PRICING_CYCLE", "NO_EXPIRY", "CUSTOM"]); export const grantDetails = z.object({priority: z.number().int().gte(0), expiryType: expiryType, expiryDuration: z.string().optional(), applicableEntityIds: z.array(z.string()).optional()}); export const slabDetail = z.object({startAfter: z.number(), priceType: priceType, slabConfig: z.record(z.string(), z.string()).optional(), rate: z.number(), slabRateConfig: z.record(z.string(), z.string()).optional()}); export const currencySlabRateDetail = z.object({currency: z.string(), creditAmount: z.number().gte(0), slabDetails: z.array(slabDetail), rateConfig: z.record(z.string(), z.string()).optional()}); export const creditRateDetails = z.object({pricingModel: pricingModel, currencySlabRateDetails: z.array(currencySlabRateDetail)}); export const creditGrantType = z.enum(["ONE_TIME", "RECURRING"]); export const creditGrantRateCard = z.object({id: z.string(), displayName: z.string().optional(), tag: z.string().optional(), grantDetails: grantDetails, rateDetails: creditRateDetails, invoiceTiming: invoiceTiming.optional(), type: creditGrantType.optional(), recurrenceConfig: recurrenceConfig.optional()}); export const pricePlanType = z.enum(["BILLING", "PURCHASE"]); export const pricePlanDetails = z.object({supportedCurrencies: z.array(z.string()), activeCurrencies: z.array(z.string()), pricingCycleConfig: pricingCycleConfig.optional(), usageRateCards: z.array(usageRateCard).optional(), fixedFeeRateCards: z.array(fixedFeeRateCard).optional(), licenseRateCards: z.array(licenseRateCard).optional(), billingEntitlementRateCards: z.array(billingEntitlementRateCard).optional(), entitlementOverageRateCards: z.array(entitlementOverageRateCard).optional(), minimumCommitment: minimumCommitment.optional(), creditGrantRateCards: z.array(creditGrantRateCard).optional(), type: pricePlanType.optional(), deferredRevenue: z.boolean().optional()}); export const pricingRuleTiming = z.enum(["IN_ADVANCE", "IN_ARREARS"]); export const pricingRuleAction = z.object({type: z.enum(["ADD", "UPDATE"]), target: z.string().optional(), id: z.string().optional(), description: z.string().optional(), metadata: z.record(z.string(), z.string()).optional()}); export const pricingRule = z.object({id: z.string(), name: z.string(), version: z.number().int().gte(1), invoiceTiming: pricingRuleTiming.optional(), order: z.number().int().gte(1), condition: z.string().optional(), computation: z.string(), action: pricingRuleAction}); export const pricePlanListData = z.object({id: z.string().max(50), name: z.string().max(50), version: z.number().int(), description: z.string().max(255).optional(), status: z.enum(["DRAFT", "ACTIVE", "ARCHIVED"]), usageMeters: z.array(z.string()), pricePlanDetails: pricePlanDetails, pricingRules: z.array(pricingRule).optional(), createdAt: z.string(), updatedAt: z.string(), type: pricePlanType}); export const paginationOptions = z.object({pageSize: z.number().int().optional(), sortOrder: z.enum(["ASC", "DESC"]).optional()}); export const pricePlanPaginatedResponse = z.object({data: z.array(pricePlanListData), nextToken: z.string().optional(), context: paginationOptions.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 }; /** * List price plans * * GET /price_plans */ export const getApiPricePlans = async (args: GetApiPricePlansArgs, options?: GetApiPricePlansOptions) => { const {baseUrl = "https://api.togai.com", fetch: fetchFn = fetch, bearerAuth} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") if (args.nextToken != null) query.append("nextToken", String(args.nextToken)) if (args.pageSize != null) query.append("pageSize", String(args.pageSize)) if (bearerAuth !== undefined) headers.set('authorization', `Bearer ${bearerAuth}`) const url = `${baseUrl.replace(/\/+$/, '')}/price_plans${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(pricePlanPaginatedResponse, await res.json()) };