Files
cfw-autumn/shared/api/billing/common/customizePlan/customizePlanV1.ts
John Yeo 972b5f6019 latest
2026-05-08 01:25:53 +08:00

79 lines
2.7 KiB
TypeScript

import { FreeTrialParamsV1Schema } from "@api/common/freeTrial/freeTrialParamsV1";
import { BasePriceParamsSchema } from "@api/products/components/basePrice/basePrice";
import { CreatePlanItemParamsV1Schema } from "@api/products/items/crud/createPlanItemParamsV1";
import { PlanItemFilterSchema } from "@api/products/items/filter/planItemFilter";
import { z } from "zod/v4";
export const CustomizePlanV1Schema = z
.object({
price: BasePriceParamsSchema.nullable().optional().meta({
description:
"Override the base price of the plan. Pass null to remove the base price.",
}),
items: z.array(CreatePlanItemParamsV1Schema).optional().meta({
description:
"Override the items in the plan (PUT-style — replaces all existing items). Mutually exclusive with add_items / remove_items.",
}),
add_items: z.array(CreatePlanItemParamsV1Schema).optional().meta({
description: "Items to add to the plan.",
}),
remove_items: z.array(PlanItemFilterSchema).optional().meta({
description: "Filters selecting items to remove from the plan.",
}),
free_trial: FreeTrialParamsV1Schema.nullable().optional().meta({
description:
"Override the plan's default free trial. Pass an object to set a custom trial, or null to remove the trial entirely.",
}),
})
.refine(
(data) =>
data.items !== undefined ||
data.price !== undefined ||
data.free_trial !== undefined ||
data.add_items !== undefined ||
data.remove_items !== undefined,
{
message:
"When using customize, at least one of price, items, add_items, remove_items, or free_trial must be provided",
},
)
.refine(
(data) =>
!(
data.items !== undefined &&
(data.add_items !== undefined || data.remove_items !== undefined)
),
{
message:
"customize.items (PUT-style) cannot be combined with add_items/remove_items (PATCH-style); pick one approach",
},
)
.meta({
title: "CustomizePlan",
description:
"Customize a plan by overriding its price, items, free trial, or a combination.",
});
export type CustomizePlanV1 = z.infer<typeof CustomizePlanV1Schema>;
/** Returns true if customize has custom items or price (not just free_trial) */
export const hasCustomItems = (
customize?: CustomizePlanV1,
): customize is CustomizePlanV1 => {
if (!customize) return false;
return (
customize.price !== undefined ||
customize.items !== undefined ||
customize.add_items !== undefined ||
customize.remove_items !== undefined
);
};
export const isCustomizePlanPatchStyle = (
customize?: CustomizePlanV1,
): customize is CustomizePlanV1 =>
customize?.items === undefined &&
(customize?.price !== undefined ||
customize?.add_items !== undefined ||
customize?.remove_items !== undefined);