Merged in feat/sw-2863-move-contentstack-router-to-trpc-package (pull request #2389)
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
This commit is contained in:
201
packages/trpc/lib/routers/contentstack/metadata/output.ts
Normal file
201
packages/trpc/lib/routers/contentstack/metadata/output.ts
Normal file
@@ -0,0 +1,201 @@
|
||||
import { z } from "zod"
|
||||
|
||||
import { findMyBooking } from "@scandic-hotels/common/constants/routes/findMyBooking"
|
||||
import { myStay } from "@scandic-hotels/common/constants/routes/myStay"
|
||||
|
||||
import { attributesSchema as hotelAttributesSchema } from "../../../routers/hotels/schemas/hotel"
|
||||
import { Country } from "../../../types/country"
|
||||
import { RTETypeEnum } from "../../../types/RTEenums"
|
||||
import { additionalDataAttributesSchema } from "../../hotels/schemas/hotel/include/additionalData"
|
||||
import { imageSchema } from "../../hotels/schemas/image"
|
||||
import { tempImageVaultAssetSchema } from "../schemas/imageVault"
|
||||
import { systemSchema } from "../schemas/system"
|
||||
|
||||
import type { Lang } from "@scandic-hotels/common/constants/language"
|
||||
|
||||
import type { ImageVaultAsset } from "../../../types/imageVault"
|
||||
import type { LanguageSwitcherData } from "../../../types/languageSwitcher"
|
||||
|
||||
const metaDataJsonSchema = z.object({
|
||||
children: z.array(
|
||||
z.object({
|
||||
type: z.nativeEnum(RTETypeEnum),
|
||||
children: z.array(
|
||||
z.object({
|
||||
text: z.string().optional(),
|
||||
})
|
||||
),
|
||||
})
|
||||
),
|
||||
})
|
||||
|
||||
const metaDataBlocksSchema = z
|
||||
.array(
|
||||
z.object({
|
||||
content: z
|
||||
.object({
|
||||
content: z
|
||||
.object({
|
||||
json: metaDataJsonSchema,
|
||||
})
|
||||
.optional()
|
||||
.nullable(),
|
||||
})
|
||||
.optional()
|
||||
.nullable(),
|
||||
})
|
||||
)
|
||||
.optional()
|
||||
.nullable()
|
||||
|
||||
export const rawMetadataSchema = z.object({
|
||||
web: z
|
||||
.object({
|
||||
seo_metadata: z
|
||||
.object({
|
||||
title: z.string().nullish(),
|
||||
description: z.string().nullish(),
|
||||
noindex: z.boolean().nullish(),
|
||||
seo_image: tempImageVaultAssetSchema.nullable(),
|
||||
})
|
||||
.nullish(),
|
||||
breadcrumbs: z
|
||||
.object({
|
||||
title: z.string().nullish(),
|
||||
})
|
||||
.nullish(),
|
||||
})
|
||||
.nullish(),
|
||||
destination_settings: z
|
||||
.object({
|
||||
city_denmark: z.string().nullish(),
|
||||
city_finland: z.string().nullish(),
|
||||
city_germany: z.string().nullish(),
|
||||
city_poland: z.string().nullish(),
|
||||
city_norway: z.string().nullish(),
|
||||
city_sweden: z.string().nullish(),
|
||||
country: z.nativeEnum(Country).nullish(),
|
||||
})
|
||||
.nullish(),
|
||||
heading: z.string().nullish(),
|
||||
preamble: z
|
||||
.union([
|
||||
z.string(),
|
||||
z.object({
|
||||
first_column: z.string(),
|
||||
}),
|
||||
])
|
||||
.transform((preamble) => {
|
||||
if (typeof preamble === "string") {
|
||||
return preamble
|
||||
}
|
||||
|
||||
return preamble?.first_column || null
|
||||
})
|
||||
.nullish(),
|
||||
header: z
|
||||
.object({
|
||||
heading: z.string().nullish(),
|
||||
preamble: z.string().nullish(),
|
||||
hero_image: tempImageVaultAssetSchema.nullable(),
|
||||
})
|
||||
.nullish(),
|
||||
hero_image: tempImageVaultAssetSchema.nullable(),
|
||||
images: z
|
||||
.array(z.object({ image: tempImageVaultAssetSchema }).nullish())
|
||||
.transform((images) =>
|
||||
images
|
||||
.map((image) => image?.image)
|
||||
.filter((image): image is ImageVaultAsset => !!image)
|
||||
)
|
||||
.nullish(),
|
||||
blocks: metaDataBlocksSchema,
|
||||
hotel_page_id: z.string().nullish(),
|
||||
hotelData: hotelAttributesSchema
|
||||
.pick({
|
||||
name: true,
|
||||
address: true,
|
||||
detailedFacilities: true,
|
||||
hotelContent: true,
|
||||
healthFacilities: true,
|
||||
})
|
||||
.nullish(),
|
||||
additionalHotelData: additionalDataAttributesSchema
|
||||
.pick({
|
||||
gallery: true,
|
||||
hotelParking: true,
|
||||
healthAndFitness: true,
|
||||
hotelSpecialNeeds: true,
|
||||
meetingRooms: true,
|
||||
parkingImages: true,
|
||||
accessibility: true,
|
||||
conferencesAndMeetings: true,
|
||||
})
|
||||
.nullish(),
|
||||
hotelRestaurants: z
|
||||
.array(
|
||||
z.object({
|
||||
nameInUrl: z.string().nullish(),
|
||||
elevatorPitch: z.string().nullish(),
|
||||
name: z.string().nullish(),
|
||||
content: z
|
||||
.object({
|
||||
images: z.array(imageSchema).nullish(),
|
||||
})
|
||||
.nullish(),
|
||||
})
|
||||
)
|
||||
.nullish(),
|
||||
subpageUrl: z.string().nullish(),
|
||||
destinationData: z
|
||||
.object({
|
||||
location: z.string().nullish(),
|
||||
filter: z.string().nullish(),
|
||||
filterType: z.enum(["facility", "surroundings"]).nullish(),
|
||||
hotelCount: z.number().nullish(),
|
||||
cities: z.array(z.string()).nullish(),
|
||||
})
|
||||
.nullish(),
|
||||
system: systemSchema,
|
||||
})
|
||||
|
||||
export interface RawMetadataSchema extends z.output<typeof rawMetadataSchema> {}
|
||||
|
||||
// Several pages are not currently routed within contentstack context.
|
||||
// This function is used to generate the urls for these pages.
|
||||
export function getNonContentstackUrls(lang: Lang, pathName: string) {
|
||||
if (Object.values(findMyBooking).includes(pathName)) {
|
||||
const urls: LanguageSwitcherData = {}
|
||||
return Object.entries(findMyBooking).reduce((acc, [lang, url]) => {
|
||||
acc[lang as Lang] = { url }
|
||||
return urls
|
||||
}, urls)
|
||||
}
|
||||
|
||||
if (Object.values(myStay).includes(pathName)) {
|
||||
const urls: LanguageSwitcherData = {}
|
||||
return Object.entries(myStay).reduce((acc, [lang, url]) => {
|
||||
acc[lang as Lang] = { url }
|
||||
return urls
|
||||
}, urls)
|
||||
}
|
||||
|
||||
if (pathName.startsWith(hotelreservation(lang))) {
|
||||
return baseUrls
|
||||
}
|
||||
|
||||
return { [lang]: { url: pathName } }
|
||||
}
|
||||
|
||||
const baseUrls: LanguageSwitcherData = {
|
||||
da: { url: "/da/" },
|
||||
de: { url: "/de/" },
|
||||
en: { url: "/en/" },
|
||||
fi: { url: "/fi/" },
|
||||
no: { url: "/no/" },
|
||||
sv: { url: "/sv/" },
|
||||
}
|
||||
|
||||
function hotelreservation(lang: Lang) {
|
||||
return `/${lang}/hotelreservation`
|
||||
}
|
||||
Reference in New Issue
Block a user