import {z} from 'zod' export type PlanType = 'cloud' | 'rhino-plugin' | 'revit-plugin' | 'bundled-plugin' | 'application' | 'seat' | 'cloud-compute'; export type GetApiSubscriptionPlansArgs = {'plan-type'?: PlanType | undefined}; export type GetApiSubscriptionPlansOptions = {baseUrl: string, fetch?: typeof fetch | undefined}; export const planType = z.enum(["cloud", "rhino-plugin", "revit-plugin", "bundled-plugin", "application", "seat", "cloud-compute"]); export const quotaType = z.enum(["storage", "compute_hours", "parallel_workflow_containers", "runs_per_study", "private_repositories", "private_projects", "teams", "members", "cpu_limit", "memory_limit", "rhino_plugin_license", "revit_plugin_license", "application_cpu", "application_memory"]); export const quotaPlan = z.object({type: quotaType, resets: z.boolean().optional(), limit: z.number().optional(), enforced: z.boolean().optional(), max_limit: z.number().optional(), display_name: z.string().optional(), description: z.string().optional(), unit: z.string().optional()}); export const accountType = z.enum(["org", "user"]); export const billingOption = z.object({id: z.number().int(), name: z.string(), billing_type: z.string(), billing_period: z.number().int(), recurring_price: z.record(z.string(), z.number())}); export const subscriptionPlan = z.object({type: planType, slug: z.string(), name: z.string(), quotas: z.array(quotaPlan).optional(), account_types: z.array(accountType), billing_options: z.array(billingOption).optional()}); export const getApiSubscriptionPlansResponse = z.array(subscriptionPlan); 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 Subscription Plans * * GET /subscription-plans/ */ export const getApiSubscriptionPlans = async (args: GetApiSubscriptionPlansArgs, options: GetApiSubscriptionPlansOptions) => { const {baseUrl, fetch: fetchFn = fetch} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") if (args['plan-type'] != null) query.append("plan-type", String(args['plan-type'])) const url = `${baseUrl.replace(/\/+$/, '')}/subscription-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(getApiSubscriptionPlansResponse, await res.json()) };