diff --git a/src/component/_generated/component.ts b/src/component/_generated/component.ts index de6b464..65b18d2 100644 --- a/src/component/_generated/component.ts +++ b/src/component/_generated/component.ts @@ -29,6 +29,18 @@ export type ComponentApi = "internal", { product: { + benefits: Array<{ + createdAt: string; + deletable: boolean; + description: string; + id: string; + metadata?: Record; + modifiedAt: string | null; + organizationId: string; + properties?: any; + selectable: boolean; + type: string; + }>; createdAt: string; description: string | null; id: string; @@ -59,10 +71,13 @@ export type ComponentApi = organizationId: string; prices: Array<{ amountType?: string; + capAmount?: number | null; createdAt: string; id: string; isArchived: boolean; maximumAmount?: number | null; + meter?: { id: string; name: string }; + meterId?: string; minimumAmount?: number | null; modifiedAt: string | null; presetAmount?: number | null; @@ -70,7 +85,14 @@ export type ComponentApi = priceCurrency?: string; productId: string; recurringInterval?: "day" | "week" | "month" | "year" | null; + seatTiers?: Array<{ + maxSeats: number | null; + minSeats: number; + pricePerSeat: number; + }>; + source?: "catalog" | "ad_hoc"; type?: string; + unitAmount?: string; }>; recurringInterval?: "day" | "week" | "month" | "year" | null; }; @@ -128,6 +150,18 @@ export type ComponentApi = modifiedAt: string | null; priceId?: string; product: { + benefits: Array<{ + createdAt: string; + deletable: boolean; + description: string; + id: string; + metadata?: Record; + modifiedAt: string | null; + organizationId: string; + properties?: any; + selectable: boolean; + type: string; + }>; createdAt: string; description: string | null; id: string; @@ -158,10 +192,13 @@ export type ComponentApi = organizationId: string; prices: Array<{ amountType?: string; + capAmount?: number | null; createdAt: string; id: string; isArchived: boolean; maximumAmount?: number | null; + meter?: { id: string; name: string }; + meterId?: string; minimumAmount?: number | null; modifiedAt: string | null; presetAmount?: number | null; @@ -169,7 +206,14 @@ export type ComponentApi = priceCurrency?: string; productId: string; recurringInterval?: "day" | "week" | "month" | "year" | null; + seatTiers?: Array<{ + maxSeats: number | null; + minSeats: number; + pricePerSeat: number; + }>; + source?: "catalog" | "ad_hoc"; type?: string; + unitAmount?: string; }>; recurringInterval?: "day" | "week" | "month" | "year" | null; }; @@ -192,6 +236,18 @@ export type ComponentApi = "internal", { id: string }, { + benefits: Array<{ + createdAt: string; + deletable: boolean; + description: string; + id: string; + metadata?: Record; + modifiedAt: string | null; + organizationId: string; + properties?: any; + selectable: boolean; + type: string; + }>; createdAt: string; description: string | null; id: string; @@ -222,10 +278,13 @@ export type ComponentApi = organizationId: string; prices: Array<{ amountType?: string; + capAmount?: number | null; createdAt: string; id: string; isArchived: boolean; maximumAmount?: number | null; + meter?: { id: string; name: string }; + meterId?: string; minimumAmount?: number | null; modifiedAt: string | null; presetAmount?: number | null; @@ -233,7 +292,14 @@ export type ComponentApi = priceCurrency?: string; productId: string; recurringInterval?: "day" | "week" | "month" | "year" | null; + seatTiers?: Array<{ + maxSeats: number | null; + minSeats: number; + pricePerSeat: number; + }>; + source?: "catalog" | "ad_hoc"; type?: string; + unitAmount?: string; }>; recurringInterval?: "day" | "week" | "month" | "year" | null; } | null, @@ -305,6 +371,18 @@ export type ComponentApi = "internal", { includeArchived?: boolean }, Array<{ + benefits: Array<{ + createdAt: string; + deletable: boolean; + description: string; + id: string; + metadata?: Record; + modifiedAt: string | null; + organizationId: string; + properties?: any; + selectable: boolean; + type: string; + }>; createdAt: string; description: string | null; id: string; @@ -336,10 +414,13 @@ export type ComponentApi = priceAmount?: number; prices: Array<{ amountType?: string; + capAmount?: number | null; createdAt: string; id: string; isArchived: boolean; maximumAmount?: number | null; + meter?: { id: string; name: string }; + meterId?: string; minimumAmount?: number | null; modifiedAt: string | null; presetAmount?: number | null; @@ -347,7 +428,14 @@ export type ComponentApi = priceCurrency?: string; productId: string; recurringInterval?: "day" | "week" | "month" | "year" | null; + seatTiers?: Array<{ + maxSeats: number | null; + minSeats: number; + pricePerSeat: number; + }>; + source?: "catalog" | "ad_hoc"; type?: string; + unitAmount?: string; }>; recurringInterval?: "day" | "week" | "month" | "year" | null; }>, @@ -374,6 +462,18 @@ export type ComponentApi = modifiedAt: string | null; priceId?: string; product: { + benefits: Array<{ + createdAt: string; + deletable: boolean; + description: string; + id: string; + metadata?: Record; + modifiedAt: string | null; + organizationId: string; + properties?: any; + selectable: boolean; + type: string; + }>; createdAt: string; description: string | null; id: string; @@ -404,10 +504,13 @@ export type ComponentApi = organizationId: string; prices: Array<{ amountType?: string; + capAmount?: number | null; createdAt: string; id: string; isArchived: boolean; maximumAmount?: number | null; + meter?: { id: string; name: string }; + meterId?: string; minimumAmount?: number | null; modifiedAt: string | null; presetAmount?: number | null; @@ -415,7 +518,14 @@ export type ComponentApi = priceCurrency?: string; productId: string; recurringInterval?: "day" | "week" | "month" | "year" | null; + seatTiers?: Array<{ + maxSeats: number | null; + minSeats: number; + pricePerSeat: number; + }>; + source?: "catalog" | "ad_hoc"; type?: string; + unitAmount?: string; }>; recurringInterval?: "day" | "week" | "month" | "year" | null; } | null; @@ -438,6 +548,18 @@ export type ComponentApi = "internal", { product: { + benefits: Array<{ + createdAt: string; + deletable: boolean; + description: string; + id: string; + metadata?: Record; + modifiedAt: string | null; + organizationId: string; + properties?: any; + selectable: boolean; + type: string; + }>; createdAt: string; description: string | null; id: string; @@ -468,10 +590,13 @@ export type ComponentApi = organizationId: string; prices: Array<{ amountType?: string; + capAmount?: number | null; createdAt: string; id: string; isArchived: boolean; maximumAmount?: number | null; + meter?: { id: string; name: string }; + meterId?: string; minimumAmount?: number | null; modifiedAt: string | null; presetAmount?: number | null; @@ -479,7 +604,14 @@ export type ComponentApi = priceCurrency?: string; productId: string; recurringInterval?: "day" | "week" | "month" | "year" | null; + seatTiers?: Array<{ + maxSeats: number | null; + minSeats: number; + pricePerSeat: number; + }>; + source?: "catalog" | "ad_hoc"; type?: string; + unitAmount?: string; }>; recurringInterval?: "day" | "week" | "month" | "year" | null; }; @@ -493,6 +625,18 @@ export type ComponentApi = { polarAccessToken: string; products: Array<{ + benefits: Array<{ + createdAt: string; + deletable: boolean; + description: string; + id: string; + metadata?: Record; + modifiedAt: string | null; + organizationId: string; + properties?: any; + selectable: boolean; + type: string; + }>; createdAt: string; description: string | null; id: string; @@ -523,10 +667,13 @@ export type ComponentApi = organizationId: string; prices: Array<{ amountType?: string; + capAmount?: number | null; createdAt: string; id: string; isArchived: boolean; maximumAmount?: number | null; + meter?: { id: string; name: string }; + meterId?: string; minimumAmount?: number | null; modifiedAt: string | null; presetAmount?: number | null; @@ -534,7 +681,14 @@ export type ComponentApi = priceCurrency?: string; productId: string; recurringInterval?: "day" | "week" | "month" | "year" | null; + seatTiers?: Array<{ + maxSeats: number | null; + minSeats: number; + pricePerSeat: number; + }>; + source?: "catalog" | "ad_hoc"; type?: string; + unitAmount?: string; }>; recurringInterval?: "day" | "week" | "month" | "year" | null; }>; diff --git a/src/component/schema.ts b/src/component/schema.ts index f5027fe..7e8a2f0 100644 --- a/src/component/schema.ts +++ b/src/component/schema.ts @@ -41,9 +41,44 @@ export default defineSchema( priceAmount: v.optional(v.number()), type: v.optional(v.string()), recurringInterval: v.optional(vRecurringInterval), + source: v.optional( + v.union(v.literal("catalog"), v.literal("ad_hoc")), + ), maximumAmount: v.optional(v.union(v.number(), v.null())), minimumAmount: v.optional(v.union(v.number(), v.null())), presetAmount: v.optional(v.union(v.number(), v.null())), + seatTiers: v.optional( + v.array( + v.object({ + minSeats: v.number(), + maxSeats: v.union(v.number(), v.null()), + pricePerSeat: v.number(), + }), + ), + ), + unitAmount: v.optional(v.string()), + capAmount: v.optional(v.union(v.number(), v.null())), + meterId: v.optional(v.string()), + meter: v.optional( + v.object({ + id: v.string(), + name: v.string(), + }), + ), + }), + ), + benefits: v.array( + v.object({ + id: v.string(), + createdAt: v.string(), + modifiedAt: v.union(v.string(), v.null()), + type: v.string(), + description: v.string(), + selectable: v.boolean(), + deletable: v.boolean(), + organizationId: v.string(), + metadata: v.optional(v.record(v.string(), v.any())), + properties: v.optional(v.any()), }), ), medias: v.array( diff --git a/src/component/util.ts b/src/component/util.ts index e64abb3..ead8af1 100644 --- a/src/component/util.ts +++ b/src/component/util.ts @@ -61,29 +61,77 @@ export const convertToDatabaseProduct = ( modifiedAt: product.modifiedAt?.toISOString() ?? null, recurringInterval: product.recurringInterval, metadata: product.metadata, - prices: product.prices.map((price) => ({ - id: price.id, - productId: price.productId, - amountType: price.amountType, - isArchived: price.isArchived, - createdAt: price.createdAt.toISOString(), - modifiedAt: price.modifiedAt?.toISOString() ?? null, - recurringInterval: - price.type === "recurring" - ? price.recurringInterval ?? undefined - : undefined, - priceAmount: price.amountType === "fixed" ? price.priceAmount : undefined, - priceCurrency: - price.amountType === "fixed" || price.amountType === "custom" - ? price.priceCurrency - : undefined, - minimumAmount: - price.amountType === "custom" ? price.minimumAmount : undefined, - maximumAmount: - price.amountType === "custom" ? price.maximumAmount : undefined, - presetAmount: - price.amountType === "custom" ? price.presetAmount : undefined, - type: price.type, + prices: product.prices.map((price) => { + const basePrice = { + id: price.id, + productId: price.productId, + amountType: price.amountType, + isArchived: price.isArchived, + createdAt: price.createdAt.toISOString(), + modifiedAt: price.modifiedAt?.toISOString() ?? null, + recurringInterval: product.recurringInterval, + type: product.isRecurring ? "recurring" : "one_time", + source: price.source, + }; + + if (price.amountType === "fixed") { + return { + ...basePrice, + priceAmount: price.priceAmount, + priceCurrency: price.priceCurrency, + }; + } + + if (price.amountType === "custom") { + return { + ...basePrice, + priceCurrency: price.priceCurrency, + minimumAmount: price.minimumAmount, + maximumAmount: price.maximumAmount, + presetAmount: price.presetAmount, + }; + } + + if (price.amountType === "free") { + return basePrice; + } + + if (price.amountType === "seat_based") { + return { + ...basePrice, + priceCurrency: price.priceCurrency, + seatTiers: price.seatTiers?.tiers.map((tier) => ({ + minSeats: tier.minSeats, + maxSeats: tier.maxSeats ?? null, + pricePerSeat: tier.pricePerSeat, + })), + }; + } + + if (price.amountType === "metered_unit") { + return { + ...basePrice, + priceCurrency: price.priceCurrency, + unitAmount: price.unitAmount, + capAmount: price.capAmount, + meterId: price.meterId, + meter: price.meter, + }; + } + + return basePrice; + }), + benefits: product.benefits.map((benefit) => ({ + id: benefit.id, + createdAt: benefit.createdAt.toISOString(), + modifiedAt: benefit.modifiedAt?.toISOString() ?? null, + type: benefit.type, + description: benefit.description, + selectable: benefit.selectable, + deletable: benefit.deletable, + organizationId: benefit.organizationId, + metadata: benefit.metadata, + properties: benefit.properties, })), medias: product.medias.map((media) => ({ id: media.id,