Files
cfw-autumn/server/src/utils/scriptUtils/createTestProducts.ts
2025-10-24 10:11:16 +01:00

207 lines
3.9 KiB
TypeScript

import {
AppEnv,
BillingInterval,
CouponDurationType,
type CreateFreeTrial,
CreateFreeTrialSchema,
type CreateReward,
FeatureUsageType,
type FreeTrial,
FreeTrialDuration,
type ProductItem,
type ProductV2,
RewardType,
} from "@autumn/shared";
import {
constructBooleanFeature,
constructMeteredFeature,
} from "@/internal/features/utils/constructFeatureUtils.js";
import { constructPriceItem } from "@/internal/products/product-items/productItemUtils.js";
import { keyToTitle } from "../genUtils.js";
export enum TestFeatureType {
Boolean = "boolean",
SingleUse = "single_use",
ContinuousUse = "continuous_use",
}
export const initFeature = ({
id,
orgId,
type,
}: {
id: string;
orgId: string;
type: TestFeatureType;
}) => {
if (type === TestFeatureType.Boolean) {
return constructBooleanFeature({
featureId: id,
orgId,
env: AppEnv.Sandbox,
});
} else if (type === TestFeatureType.SingleUse) {
return constructMeteredFeature({
featureId: id,
orgId,
env: AppEnv.Sandbox,
usageType: FeatureUsageType.Single,
});
} else {
return constructMeteredFeature({
featureId: id,
orgId,
env: AppEnv.Sandbox,
usageType: FeatureUsageType.Continuous,
});
}
};
export const constructRawProduct = ({
id,
isAddOn = false,
items,
}: {
id: string;
isAddOn?: boolean;
items: ProductItem[];
}) => {
return {
id,
name: keyToTitle(id),
items,
is_add_on: isAddOn,
is_default: false,
version: 1,
group: "",
created_at: Date.now(),
env: AppEnv.Sandbox,
};
};
export const constructProduct = ({
id,
items,
type,
interval,
group,
intervalCount,
isAnnual = false,
trial = false,
excludeBase = false,
isDefault = true,
isAddOn = false,
freeTrial,
forcePaidDefault = false,
}: {
id?: string;
items: ProductItem[];
type: "free" | "pro" | "premium" | "growth" | "one_off";
interval?: BillingInterval;
group?: string;
intervalCount?: number;
isAnnual?: boolean;
trial?: boolean;
excludeBase?: boolean;
isDefault?: boolean;
isAddOn?: boolean;
freeTrial?: CreateFreeTrial;
forcePaidDefault?: boolean;
}) => {
let price = 0;
if (type === "pro") {
price = 20;
} else if (type === "premium") {
price = 50;
} else if (type === "growth") {
price = 100;
}
if (price && !excludeBase) {
items.push(
constructPriceItem({
price: isAnnual ? price * 10 : price,
interval: isAnnual
? BillingInterval.Year
: interval
? interval
: BillingInterval.Month,
intervalCount: intervalCount || 1,
}),
);
}
if (type === "one_off") {
items.push(
constructPriceItem({
price: 10,
interval: null,
}),
);
}
const id_ =
id ||
(isAnnual ? `${type}-annual` : interval ? `${type}-${interval}` : type);
let free_trial: CreateFreeTrial | null = null;
if (freeTrial) {
free_trial = freeTrial as FreeTrial;
} else if (trial) {
free_trial = CreateFreeTrialSchema.parse({
length: 7,
duration: FreeTrialDuration.Day,
});
}
const product: ProductV2 = {
id: id_,
name: id
? keyToTitle(id)
: isAnnual
? `${keyToTitle(type)} (Annual)`
: interval
? `${keyToTitle(type)} (${interval})`
: keyToTitle(type),
items,
env: AppEnv.Sandbox,
is_add_on: isAddOn,
is_default: (type === "free" && isDefault) || forcePaidDefault,
version: 1,
group: group || "",
free_trial: free_trial as FreeTrial,
created_at: Date.now(),
};
return product;
};
export const constructCoupon = ({
id,
promoCode,
discountType = RewardType.FixedDiscount,
discountValue = 10,
}: {
id: string;
promoCode: string;
discountType?: RewardType;
discountValue?: number;
}) => {
const reward: CreateReward = {
id,
name: keyToTitle(id),
promo_codes: [{ code: promoCode }],
type: discountType,
discount_config: {
discount_value: discountValue,
duration_type: CouponDurationType.Forever,
duration_value: 1,
should_rollover: true,
apply_to_all: true,
price_ids: [],
},
};
return reward;
};