95 lines
2.8 KiB
TypeScript
95 lines
2.8 KiB
TypeScript
import { ApiVersion } from "@api/versionUtils/ApiVersion.js";
|
|
import {
|
|
AffectedResource,
|
|
defineVersionChange,
|
|
} from "@api/versionUtils/versionChangeUtils/VersionChange.js";
|
|
import { FeatureType } from "@models/featureModels/featureEnums.js";
|
|
import { isAiCreditSystem } from "@utils/featureUtils/classifyFeature/isAiCreditSystem";
|
|
import type { z } from "zod/v4";
|
|
import { ApiFeatureV1Schema } from "../apiFeatureV1.js";
|
|
import {
|
|
ApiFeatureType,
|
|
ApiFeatureV0Schema,
|
|
} from "../prevVersions/apiFeatureV0.js";
|
|
|
|
/**
|
|
* V1_2_FeatureChange: Transforms feature response between V1 and V0
|
|
*
|
|
* Applied when: targetVersion <= V1_Beta
|
|
*
|
|
* Breaking changes introduced in V2.0:
|
|
*
|
|
* 1. Type enum changes:
|
|
* - V1: Uses FeatureType (boolean, metered, credit_system)
|
|
* - V0: Uses ApiFeatureType (static, boolean, single_use, continuous_use, credit_system)
|
|
*
|
|
* 2. Fields in V1 not in V0:
|
|
* - `consumable`: Boolean flag for metered features
|
|
* - `event_names`: Optional array of event names
|
|
*
|
|
* 3. Type mapping (V1 → V0):
|
|
* - boolean → boolean
|
|
* - credit_system → credit_system
|
|
* - metered (consumable: true) → single_use
|
|
* - metered (consumable: false) → continuous_use
|
|
*
|
|
* Input: ApiFeatureV1 (V2.0+ format)
|
|
* Output: ApiFeatureV0 (V1.2 format)
|
|
*/
|
|
|
|
export const V1_2_FeatureChange = defineVersionChange({
|
|
name: "V1_2 Feature Change",
|
|
newVersion: ApiVersion.V2_0,
|
|
oldVersion: ApiVersion.V1_Beta,
|
|
description: [
|
|
"Feature type enum changed from FeatureType to ApiFeatureType",
|
|
"Removed consumable and event_names fields",
|
|
],
|
|
affectedResources: [AffectedResource.Feature],
|
|
newSchema: ApiFeatureV1Schema,
|
|
oldSchema: ApiFeatureV0Schema,
|
|
affectsResponse: true,
|
|
affectsRequest: false,
|
|
|
|
// Response: V1 → V0 (new format to old)
|
|
transformResponse: ({
|
|
input,
|
|
}: {
|
|
input: z.infer<typeof ApiFeatureV1Schema>;
|
|
}): z.infer<typeof ApiFeatureV0Schema> => {
|
|
// Map V1 type to V0 type
|
|
let v0Type: ApiFeatureType;
|
|
|
|
if (input.type === FeatureType.Boolean) {
|
|
v0Type = ApiFeatureType.Boolean;
|
|
} else if (input.type === FeatureType.CreditSystem) {
|
|
v0Type = ApiFeatureType.CreditSystem;
|
|
} else if (isAiCreditSystem(input.type)) {
|
|
v0Type = ApiFeatureType.AiCreditSystem;
|
|
} else if (input.type === FeatureType.Metered) {
|
|
v0Type = input.consumable
|
|
? ApiFeatureType.SingleUsage
|
|
: ApiFeatureType.ContinuousUse;
|
|
} else {
|
|
v0Type = ApiFeatureType.Boolean;
|
|
}
|
|
|
|
return {
|
|
id: input.id,
|
|
name: input.name,
|
|
type: v0Type,
|
|
display: input.display
|
|
? {
|
|
singular: input.display.singular || "",
|
|
plural: input.display.plural || "",
|
|
}
|
|
: null,
|
|
credit_schema: input.credit_schema?.map((item) => ({
|
|
metered_feature_id: item.metered_feature_id,
|
|
credit_cost: item.credit_cost,
|
|
})) || null,
|
|
archived: input.archived,
|
|
} satisfies z.infer<typeof ApiFeatureV0Schema>;
|
|
},
|
|
});
|