import {z} from 'zod' export type ProductCurrency = 'EUR' | 'USD'; export type ProductRequestBillingType = 'recurring' | 'onetime'; export type ProductRequestBillingPeriod = 'once' | 'every-day' | 'every-month' | 'every-three-months' | 'every-six-months' | 'every-year' | 'custom'; export type ProductRequestRecurringInterval = 'day' | 'week' | 'month' | 'year'; export type TaxMode = 'inclusive' | 'exclusive'; export type TaxCategory = 'saas' | 'digital-goods-service' | 'ebooks'; export type CustomFieldRequestType = 'text' | 'checkbox'; export type TextFieldConfig = {max_length?: number | undefined, min_length?: number | undefined}; export type CheckboxFieldConfig = {label?: string | undefined}; export type CustomFieldRequestEntity = {type: CustomFieldRequestType, key: string, label: string, optional?: boolean | undefined, text?: TextFieldConfig | undefined, checkbox?: CheckboxFieldConfig | undefined}; export type UsagePriceSettlementMode = 'prepaid' | 'postpaid'; export type UsagePriceTargetAccount = 'shared' | 'per_unit'; export type UsagePriceTrialUsageMode = 'free' | 'accrue'; export type UsagePriceRequestEntity = {id?: string | undefined, meter_id: string, unit_price: number, free_allowance?: number | undefined, cap?: (number | null) | undefined, settlement_mode: UsagePriceSettlementMode, target_account?: UsagePriceTargetAccount | undefined, target_account_name?: (string | null) | undefined, trial_usage_mode?: UsagePriceTrialUsageMode | undefined}; export type ProductFeatureRequestType = 'customerCredits'; export type CustomerCreditsFeatureEntity = {amount: string, unit_label?: (string | null) | undefined, bucket_name?: (string | null) | undefined}; export type ProductFeatureRequestEntity = {id?: string | undefined, type: ProductFeatureRequestType, description: string, customer_credits: CustomerCreditsFeatureEntity}; export type CreateProductRequestEntity = {name: string, description: string, image_url?: string | undefined, image_urls?: Array | undefined, price: number, currency: ProductCurrency, billing_type: ProductRequestBillingType, billing_period?: ProductRequestBillingPeriod | undefined, recurring_interval?: ProductRequestRecurringInterval | undefined, recurring_interval_count?: number | undefined, tax_mode?: TaxMode | undefined, business_net_pricing?: boolean | undefined, tax_category?: TaxCategory | undefined, pay_what_you_want?: boolean | undefined, suggested_price?: number | undefined, trial_period_days?: number | undefined, trial_price?: number | undefined, default_success_url?: string | undefined, custom_fields?: Array | undefined, custom_field?: Array | undefined, abandoned_cart_recovery_enabled?: boolean | undefined, usage_prices?: Array | undefined, features?: Array | undefined}; export type CreateApiV1ProductsArgs = {'Idempotency-Key'?: string | undefined, body: CreateProductRequestEntity}; export type CreateApiV1ProductsOptions = {baseUrl?: string | undefined, ApiKey?: string | undefined, fetch?: typeof fetch | undefined}; export const environmentMode = z.enum(["test", "prod", "sandbox"]); export const productFeatureType = z.enum(["custom", "file", "licenseKey", "customerCredits"]); export const customerCreditsFeatureEntity = z.object({amount: z.string(), unit_label: z.string().nullable().optional(), bucket_name: z.string().nullable().optional()}); export const featureEntity = z.object({id: z.string(), type: productFeatureType, description: z.string(), customer_credits: customerCreditsFeatureEntity.nullable().optional()}); export const usagePriceSettlementMode = z.enum(["prepaid", "postpaid"]); export const usagePriceTargetAccount = z.enum(["shared", "per_unit"]); export const usagePriceTrialUsageMode = z.enum(["free", "accrue"]); export const usagePriceEntity = z.object({id: z.string(), meter_id: z.string(), unit_price: z.number(), free_allowance: z.number().int(), cap: z.number().int().nullable().optional(), settlement_mode: usagePriceSettlementMode, target_account: usagePriceTargetAccount, target_account_name: z.string().nullable().optional(), trial_usage_mode: usagePriceTrialUsageMode}); export const productBillingType = z.enum(["recurring", "onetime"]); export const productBillingPeriod = z.enum(["every-month", "every-three-months", "every-six-months", "every-year", "every-day", "once", "custom"]); export const productStatus = z.enum(["active", "archived"]); export const taxMode = z.enum(["inclusive", "exclusive"]); export const taxCategory = z.enum(["saas", "digital-goods-service", "ebooks"]); export const customFieldType = z.enum(["text", "checkbox"]); export const text = z.object({max_length: z.number().nullable().optional(), minimum_length: z.number().nullable().optional(), value: z.string().nullable().optional()}); export const checkbox = z.object({label: z.string().nullable().optional(), value: z.boolean().nullable().optional()}); export const customField = z.object({type: customFieldType, key: z.string().max(200), label: z.string().max(200), optional: z.boolean().nullable().optional(), text: text.nullable().optional(), checkbox: checkbox.nullable().optional()}); export const productEntity = z.object({id: z.string(), mode: environmentMode, object: z.string(), name: z.string(), description: z.string(), image_url: z.string().optional(), image_urls: z.array(z.string()).optional(), features: z.array(featureEntity).optional(), usage_prices: z.array(usagePriceEntity).optional(), price: z.number(), currency: z.string(), billing_type: productBillingType, billing_period: productBillingPeriod, recurring_interval: z.string().nullable().optional(), recurring_interval_count: z.number().int().nullable().optional(), trial_period_days: z.number().int().nullable().optional(), trial_price: z.number().int().nullable().optional(), status: productStatus, tax_mode: taxMode, business_net_pricing: z.boolean().optional(), tax_category: taxCategory, product_url: z.string().optional(), default_success_url: z.string().nullable().optional(), custom_fields: z.array(customField).nullable().optional(), created_at: z.string(), updated_at: 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 }; /** * Creates a new product. * * POST /v1/products */ export const createApiV1Products = async (args: CreateApiV1ProductsArgs, options?: CreateApiV1ProductsOptions) => { const {baseUrl = "https://api.creem.io", fetch: fetchFn = fetch, ApiKey} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('content-type', "application/json") headers.set('accept', "application/json") if (args['Idempotency-Key'] != null) headers.set("Idempotency-Key", String(args['Idempotency-Key'])) if (ApiKey !== undefined) headers.set("x-api-key", ApiKey) const url = `${baseUrl.replace(/\/+$/, '')}/v1/products${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "POST", headers, body: JSON.stringify(args.body)}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(productEntity, await res.json()) };