feat(SW-2863): Move contentstack router to trpc package * Add exports to packages and lint rule to prevent relative imports * Add env to trpc package * Add eslint to trpc package * Apply lint rules * Use direct imports from trpc package * Add lint-staged config to trpc * Move lang enum to common * Restructure trpc package folder structure * WIP first step * update internal imports in trpc * Fix most errors in scandic-web Just 100 left... * Move Props type out of trpc * Fix CategorizedFilters types * Move more schemas in hotel router * Fix deps * fix getNonContentstackUrls * Fix import error * Fix entry error handling * Fix generateMetadata metrics * Fix alertType enum * Fix duplicated types * lint:fix * Merge branch 'master' into feat/sw-2863-move-contentstack-router-to-trpc-package * Fix broken imports * Merge branch 'master' into feat/sw-2863-move-contentstack-router-to-trpc-package Approved-by: Linus Flood
176 lines
4.5 KiB
TypeScript
176 lines
4.5 KiB
TypeScript
import { z } from "zod"
|
|
|
|
import { MembershipLevelEnum } from "@scandic-hotels/common/constants/membershipLevels"
|
|
|
|
import {
|
|
linkRefsUnionSchema,
|
|
linkUnionSchema,
|
|
transformPageLink,
|
|
} from "../schemas/pageLinks"
|
|
import { systemSchema } from "../schemas/system"
|
|
|
|
export {
|
|
BenefitReward,
|
|
CouponData,
|
|
CouponReward,
|
|
REDEEM_LOCATIONS,
|
|
REWARD_TYPES,
|
|
rewardRefsSchema,
|
|
validateApiAllTiersSchema,
|
|
validateCategorizedRewardsSchema,
|
|
validateCmsRewardsSchema,
|
|
}
|
|
|
|
const validateCmsRewardsSchema = z
|
|
.object({
|
|
data: z.object({
|
|
all_reward: z.object({
|
|
items: z.array(
|
|
z.object({
|
|
taxonomies: z.array(
|
|
z.object({
|
|
term_uid: z.string().optional().default(""),
|
|
})
|
|
),
|
|
label: z.string().optional(),
|
|
reward_id: z.string(),
|
|
grouped_label: z.string().optional(),
|
|
description: z.string().optional(),
|
|
redeem_description: z
|
|
.object({
|
|
json: z.any(), // JSON
|
|
embedded_itemsConnection: z.object({
|
|
edges: z.array(
|
|
z.object({
|
|
node: linkUnionSchema.transform((data) => {
|
|
const link = transformPageLink(data)
|
|
if (link) {
|
|
return link
|
|
}
|
|
return data
|
|
}),
|
|
})
|
|
),
|
|
}),
|
|
})
|
|
// This is primarily added in order to handle a transition
|
|
// switching from string to RTE
|
|
.nullable(),
|
|
grouped_description: z.string().optional(),
|
|
value: z.string().optional(),
|
|
})
|
|
),
|
|
}),
|
|
}),
|
|
})
|
|
.transform((data) => data.data.all_reward.items)
|
|
|
|
const rewardRefsSchema = z.object({
|
|
data: z.object({
|
|
all_reward: z.object({
|
|
items: z.array(
|
|
z.object({
|
|
redeem_description: z
|
|
.object({
|
|
embedded_itemsConnection: z.object({
|
|
edges: z.array(
|
|
z.object({
|
|
node: linkRefsUnionSchema,
|
|
})
|
|
),
|
|
}),
|
|
})
|
|
// This is primarily added in order to handle a transition
|
|
// switching from string to RTE
|
|
.nullable(),
|
|
system: systemSchema,
|
|
})
|
|
),
|
|
}),
|
|
}),
|
|
})
|
|
|
|
const REDEEM_LOCATIONS = ["Non-redeemable", "On-site", "Online"] as const
|
|
const REWARD_CATEGORIES = [
|
|
"Restaurants",
|
|
"Bar",
|
|
"Voucher",
|
|
"Services and rooms",
|
|
"Spa and gym",
|
|
] as const
|
|
|
|
const BaseReward = z.object({
|
|
title: z.string().optional(),
|
|
id: z.string(),
|
|
categories: z
|
|
.array(z.enum(REWARD_CATEGORIES).or(z.literal("")))
|
|
.optional()
|
|
// we sometimes receive empty categories, this filters them out
|
|
.transform((categories = []) =>
|
|
categories.filter(
|
|
(c): c is (typeof REWARD_CATEGORIES)[number] => c !== ""
|
|
)
|
|
),
|
|
rewardId: z.string(),
|
|
redeemLocation: z.enum(REDEEM_LOCATIONS),
|
|
status: z.enum(["active", "expired"]),
|
|
})
|
|
|
|
const REWARD_TYPES = {
|
|
Surprise: "Surprise",
|
|
Campaign: "Campaign",
|
|
MemberVoucher: "Member-voucher",
|
|
Tier: "Tier",
|
|
} as const
|
|
|
|
const BenefitReward = BaseReward.merge(
|
|
z.object({
|
|
rewardType: z.enum([REWARD_TYPES.Tier]),
|
|
rewardTierLevel: z.string().optional(),
|
|
})
|
|
)
|
|
|
|
const CouponData = z.object({
|
|
couponCode: z.string(),
|
|
unwrapped: z.boolean().default(false),
|
|
state: z.enum(["claimed", "redeemed", "viewed"]),
|
|
expiresAt: z.string().datetime({ offset: true }).optional(),
|
|
})
|
|
|
|
const CouponReward = BaseReward.merge(
|
|
z.object({
|
|
rewardType: z.enum([
|
|
REWARD_TYPES.Surprise,
|
|
REWARD_TYPES.Campaign,
|
|
REWARD_TYPES.MemberVoucher,
|
|
]),
|
|
operaRewardId: z.string().default(""),
|
|
coupon: z
|
|
.array(CouponData)
|
|
.optional()
|
|
.transform((val) => val || []),
|
|
})
|
|
)
|
|
|
|
const validateCategorizedRewardsSchema = z.object({
|
|
benefits: z.array(BenefitReward),
|
|
coupons: z.array(CouponReward),
|
|
})
|
|
|
|
const TierKeyMapping = {
|
|
tier1: MembershipLevelEnum.L1,
|
|
tier2: MembershipLevelEnum.L2,
|
|
tier3: MembershipLevelEnum.L3,
|
|
tier4: MembershipLevelEnum.L4,
|
|
tier5: MembershipLevelEnum.L5,
|
|
tier6: MembershipLevelEnum.L6,
|
|
tier7: MembershipLevelEnum.L7,
|
|
} as const
|
|
|
|
const TierKeys = Object.keys(TierKeyMapping) as [keyof typeof TierKeyMapping]
|
|
|
|
const validateApiAllTiersSchema = z.record(
|
|
z.enum(TierKeys).transform((data) => TierKeyMapping[data]),
|
|
z.array(BenefitReward)
|
|
)
|