diff --git a/.vscode/settings.json b/.vscode/settings.json index bb1ea9114..7b762d2d8 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,4 +1,4 @@ { - "typescript.tsdk": "node_modules/typescript/lib", - "typescript.experimental.useTsgo": false + "typescript.tsdk": "node_modules/typescript/lib", + "typescript.experimental.useTsgo": false } diff --git a/apps/scandic-web/components/Blocks/AllCampaigns/index.tsx b/apps/scandic-web/components/Blocks/AllCampaigns/index.tsx index ca2d4df8d..c84a87f33 100644 --- a/apps/scandic-web/components/Blocks/AllCampaigns/index.tsx +++ b/apps/scandic-web/components/Blocks/AllCampaigns/index.tsx @@ -12,7 +12,7 @@ import ContentCard from "@/components/ContentCard" import styles from "./allCampaigns.module.css" -import type { ImageVaultAsset } from "@scandic-hotels/trpc/types/imageVault" +import type { ImageVaultAsset } from "@scandic-hotels/common/utils/imageVault" interface AllCampaignsProps { heading: string diff --git a/apps/scandic-web/components/ContentCard/index.tsx b/apps/scandic-web/components/ContentCard/index.tsx index 587864591..8c164f879 100644 --- a/apps/scandic-web/components/ContentCard/index.tsx +++ b/apps/scandic-web/components/ContentCard/index.tsx @@ -6,7 +6,7 @@ import Subtitle from "@scandic-hotels/design-system/Subtitle" import styles from "./contentCard.module.css" -import type { ImageVaultAsset } from "@scandic-hotels/trpc/types/imageVault" +import type { ImageVaultAsset } from "@scandic-hotels/common/utils/imageVault" interface ContentCardProps { link?: { diff --git a/apps/scandic-web/components/ContentType/DestinationPage/TopImages/index.tsx b/apps/scandic-web/components/ContentType/DestinationPage/TopImages/index.tsx index aa071d5f6..369d3fd2c 100644 --- a/apps/scandic-web/components/ContentType/DestinationPage/TopImages/index.tsx +++ b/apps/scandic-web/components/ContentType/DestinationPage/TopImages/index.tsx @@ -11,7 +11,7 @@ import { mapImageVaultImagesToGalleryImages } from "@/utils/imageGallery" import styles from "./topImages.module.css" -import type { ImageVaultAsset } from "@scandic-hotels/trpc/types/imageVault" +import type { ImageVaultAsset } from "@scandic-hotels/common/utils/imageVault" interface TopImageProps { images: ImageVaultAsset[] diff --git a/apps/scandic-web/components/DeprecatedJsonToHtml/renderOptions.tsx b/apps/scandic-web/components/DeprecatedJsonToHtml/renderOptions.tsx index d4ca74731..036d7e4a2 100644 --- a/apps/scandic-web/components/DeprecatedJsonToHtml/renderOptions.tsx +++ b/apps/scandic-web/components/DeprecatedJsonToHtml/renderOptions.tsx @@ -1,3 +1,9 @@ +import { + type DeprecatedImageVaultAssetResponse, + type ImageVaultAssetResponse, + mapImageVaultAssetResponseToImageVaultAsset, + mapInsertResponseToImageVaultAsset, +} from "@scandic-hotels/common/utils/imageVault" import { removeMultipleSlashes } from "@scandic-hotels/common/utils/url" import Body from "@scandic-hotels/design-system/Body" import Caption from "@scandic-hotels/design-system/Caption" @@ -14,18 +20,15 @@ import { RTEItemTypeEnum, RTETypeEnum, } from "@scandic-hotels/trpc/types/RTEenums" -import { insertResponseToImageVaultAsset } from "@scandic-hotels/trpc/utils/imageVault" import BiroScript from "../TempDesignSystem/Text/BiroScript" import { hasAvailableParagraphFormat, hasAvailableULFormat } from "./utils" import styles from "./jsontohtml.module.css" -import type { ImageVaultAsset } from "@scandic-hotels/trpc/types/imageVault" - import type { EmbedByUid } from "@/types/components/deprecatedjsontohtml" import { EmbedEnum } from "@/types/requests/utils/embeds" -import type { Attributes, RTEImageVaultAttrs } from "@/types/rte/attrs" +import type { Attributes } from "@/types/rte/attrs" import { type RTEDefaultNode, type RTEImageNode, @@ -309,28 +312,11 @@ export const renderOptions: RenderOptions = { if (entry?.node.__typename === EmbedEnum.ImageContainer) { if (entry.node.image_left && entry.node.image_right) { - if ("dimensions" in entry.node.image_left) { - // Only temp until all ImageVaultAssets are - // handled in schema.transform() - return ( - - ) - } - const leftImage = insertResponseToImageVaultAsset( - entry.node.image_left - ) - const rightImage = insertResponseToImageVaultAsset( - entry.node.image_right - ) return ( - + ) } return null @@ -372,40 +358,46 @@ export const renderOptions: RenderOptions = { }, [RTETypeEnum.ImageVault]: (node: RTEImageNode) => { - if ("attrs" in node) { - const type = node.type - if (type === RTETypeEnum.ImageVault) { - const attrs = node.attrs as RTEImageVaultAttrs - let image = undefined - if ("dimensions" in attrs) { - image = attrs - } else { - image = insertResponseToImageVaultAsset(attrs) - } - const alt = image.meta.alt ?? image.title - - const width = attrs.width - ? parseInt(attrs.width.replaceAll("px", "")) - : image.dimensions.width - const props = extractPossibleAttributes(attrs) - return ( -
- {alt} - {image.meta.caption} -
- ) - } + const type = node.type + if (!("attrs" in node) || type !== RTETypeEnum.ImageVault) { + return null } + let image = undefined + if ("imageVaultId" in node.attrs && "fileName" in node.attrs) { + image = mapImageVaultAssetResponseToImageVaultAsset( + node.attrs as unknown as ImageVaultAssetResponse + ) + } + + if ("Name" in node.attrs && "Id" in node.attrs) { + image = mapInsertResponseToImageVaultAsset( + node.attrs as unknown as DeprecatedImageVaultAssetResponse + ) + } + + if (!image) { + return null + } + const alt = image.meta.alt ?? image.title + const props = extractPossibleAttributes(node.attrs) + + return ( +
+ {alt} + {image.meta.caption} +
+ ) + return null }, diff --git a/apps/scandic-web/components/Hero/hero.ts b/apps/scandic-web/components/Hero/hero.ts index 73f1b0aba..4dc1b1dfb 100644 --- a/apps/scandic-web/components/Hero/hero.ts +++ b/apps/scandic-web/components/Hero/hero.ts @@ -1,4 +1,5 @@ -import type { FocalPoint, Image } from "@scandic-hotels/trpc/types/image" +import type { FocalPoint } from "@scandic-hotels/common/utils/imageVault" +import type { Image } from "@scandic-hotels/trpc/types/image" export interface HeroProps { alt: string diff --git a/apps/scandic-web/components/TempDesignSystem/Card/card.ts b/apps/scandic-web/components/TempDesignSystem/Card/card.ts index 80fac2178..0a1bcd0de 100644 --- a/apps/scandic-web/components/TempDesignSystem/Card/card.ts +++ b/apps/scandic-web/components/TempDesignSystem/Card/card.ts @@ -1,4 +1,4 @@ -import type { ImageVaultAsset } from "@scandic-hotels/trpc/types/imageVault" +import type { ImageVaultAsset } from "@scandic-hotels/common/utils/imageVault" import type { VariantProps } from "class-variance-authority" import type { ApiImage } from "@/types/components/image" diff --git a/apps/scandic-web/components/TempDesignSystem/LoyaltyCard/loyaltyCard.ts b/apps/scandic-web/components/TempDesignSystem/LoyaltyCard/loyaltyCard.ts index 0bf119438..3eb94eb06 100644 --- a/apps/scandic-web/components/TempDesignSystem/LoyaltyCard/loyaltyCard.ts +++ b/apps/scandic-web/components/TempDesignSystem/LoyaltyCard/loyaltyCard.ts @@ -1,4 +1,4 @@ -import type { ImageVaultAsset } from "@scandic-hotels/trpc/types/imageVault" +import type { ImageVaultAsset } from "@scandic-hotels/common/utils/imageVault" import type { VariantProps } from "class-variance-authority" import type { loyaltyCardVariants } from "./variants" diff --git a/apps/scandic-web/types/components/blocks/infoCard.ts b/apps/scandic-web/types/components/blocks/infoCard.ts index 20318767b..e001e5ff9 100644 --- a/apps/scandic-web/types/components/blocks/infoCard.ts +++ b/apps/scandic-web/types/components/blocks/infoCard.ts @@ -1,4 +1,4 @@ -import type { ImageVaultAsset } from "@scandic-hotels/trpc/types/imageVault" +import type { ImageVaultAsset } from "@scandic-hotels/common/utils/imageVault" import type { VariantProps } from "class-variance-authority" import type { CardProps } from "@/components/TempDesignSystem/Card/card" diff --git a/apps/scandic-web/types/components/image.ts b/apps/scandic-web/types/components/image.ts index 88444e637..967067f6f 100644 --- a/apps/scandic-web/types/components/image.ts +++ b/apps/scandic-web/types/components/image.ts @@ -1,4 +1,4 @@ -import type { FocalPoint } from "@scandic-hotels/trpc/types/image" +import type { FocalPoint } from "@scandic-hotels/common/utils/imageVault" interface Dimensions { width: number diff --git a/apps/scandic-web/types/components/teaserCard.ts b/apps/scandic-web/types/components/teaserCard.ts index eba3ae7b5..76807ddbf 100644 --- a/apps/scandic-web/types/components/teaserCard.ts +++ b/apps/scandic-web/types/components/teaserCard.ts @@ -1,5 +1,5 @@ +import type { ImageVaultAsset } from "@scandic-hotels/common/utils/imageVault" import type { TeaserCard } from "@scandic-hotels/trpc/types/blocks" -import type { ImageVaultAsset } from "@scandic-hotels/trpc/types/imageVault" import type { VariantProps } from "class-variance-authority" import type { CardProps } from "@/components/TempDesignSystem/Card/card" diff --git a/apps/scandic-web/types/requests/embeds.ts b/apps/scandic-web/types/requests/embeds.ts index 092b05914..e4f82d9a7 100644 --- a/apps/scandic-web/types/requests/embeds.ts +++ b/apps/scandic-web/types/requests/embeds.ts @@ -1,9 +1,8 @@ -import { EmbedEnum } from "./utils/embeds" -import { PageLink, PageLinkWithOriginalUrl } from "./utils/pageLink" -import { TypenameInterface } from "./utils/typename" - import type { ImageContainer } from "./imageContainer" import type { SysAsset } from "./utils/asset" +import type { EmbedEnum } from "./utils/embeds" +import type { PageLink, PageLinkWithOriginalUrl } from "./utils/pageLink" +import type { TypenameInterface } from "./utils/typename" interface AccountPage extends TypenameInterface, diff --git a/apps/scandic-web/types/requests/imageContainer.ts b/apps/scandic-web/types/requests/imageContainer.ts index 595eccccc..68ac08b30 100644 --- a/apps/scandic-web/types/requests/imageContainer.ts +++ b/apps/scandic-web/types/requests/imageContainer.ts @@ -1,5 +1,5 @@ +import type { ImageVaultAsset } from "@scandic-hotels/common/utils/imageVault" import type { System } from "@scandic-hotels/trpc/routers/contentstack/schemas/system" -import type { ImageVaultAssetResponse } from "@scandic-hotels/trpc/types/imageVault" import type { EmbedEnum } from "./utils/embeds" import type { TypenameInterface } from "./utils/typename" @@ -7,6 +7,6 @@ import type { TypenameInterface } from "./utils/typename" export interface ImageContainer extends TypenameInterface, System { - image_left?: ImageVaultAssetResponse - image_right?: ImageVaultAssetResponse + image_left?: ImageVaultAsset + image_right?: ImageVaultAsset } diff --git a/apps/scandic-web/types/rte/attrs.ts b/apps/scandic-web/types/rte/attrs.ts index e8767301a..4f7253d39 100644 --- a/apps/scandic-web/types/rte/attrs.ts +++ b/apps/scandic-web/types/rte/attrs.ts @@ -2,7 +2,7 @@ import type { Lang } from "@scandic-hotels/common/constants/language" import type { ImageVaultAsset, ImageVaultAssetResponse, -} from "@scandic-hotels/trpc/types/imageVault" +} from "@scandic-hotels/common/utils/imageVault" import type { EmbedTypesEnum, RTEItemType, diff --git a/apps/scandic-web/types/transitionTypes/rte/attrs.ts b/apps/scandic-web/types/transitionTypes/rte/attrs.ts index e7ab49e6d..5791d9907 100644 --- a/apps/scandic-web/types/transitionTypes/rte/attrs.ts +++ b/apps/scandic-web/types/transitionTypes/rte/attrs.ts @@ -1,5 +1,5 @@ import type { Lang } from "@scandic-hotels/common/constants/language" -import type { ImageVaultAsset } from "@scandic-hotels/trpc/types/imageVault" +import type { ImageVaultAsset } from "@scandic-hotels/common/utils/imageVault" import type { EmbedTypesEnum, RTEItemType, RTEItemTypeEnum } from "./enums" diff --git a/apps/scandic-web/utils/imageGallery.ts b/apps/scandic-web/utils/imageGallery.ts index 7bbb11a66..d1aa65b13 100644 --- a/apps/scandic-web/utils/imageGallery.ts +++ b/apps/scandic-web/utils/imageGallery.ts @@ -1,5 +1,5 @@ +import type { ImageVaultAsset } from "@scandic-hotels/common/utils/imageVault" import type { ApiImage } from "@scandic-hotels/trpc/types/hotel" -import type { ImageVaultAsset } from "@scandic-hotels/trpc/types/imageVault" import type { GalleryImage } from "@/types/components/imageGallery" diff --git a/packages/common/package.json b/packages/common/package.json index 85ecde635..8925db621 100644 --- a/packages/common/package.json +++ b/packages/common/package.json @@ -45,6 +45,7 @@ "./utils/chunk": "./utils/chunk.ts", "./utils/dateFormatting": "./utils/dateFormatting.ts", "./utils/debounce": "./utils/debounce.ts", + "./utils/imageVault": "./utils/imageVault.ts", "./utils/isDefined": "./utils/isDefined.ts", "./utils/isEdge": "./utils/isEdge.ts", "./utils/isValidJson": "./utils/isValidJson.ts", diff --git a/packages/common/utils/imageVault.ts b/packages/common/utils/imageVault.ts new file mode 100644 index 000000000..03765d52f --- /dev/null +++ b/packages/common/utils/imageVault.ts @@ -0,0 +1,212 @@ +import { z } from "zod" + +const focalPointSchema = z.object({ + x: z.number(), + y: z.number(), +}) + +const deprecatedMetaDataSchema = z.object({ + DefinitionType: z.number().nullish(), + Description: z.string().nullable(), + LanguageId: z.number().nullable(), + MetadataDefinitionId: z.number(), + Name: z.string(), + Value: z.string().nullable(), +}) + +/** + * Defines a media asset, original or conversion + */ +const deprecatedMediaConversionSchema = z.object({ + /** + * Aspect ratio of the conversion + */ + AspectRatio: z.number(), + /** + * Content type of the conversion + */ + ContentType: z.string(), + /** + * Aspect ratio of the selected/requested format + */ + FormatAspectRatio: z.number(), + /** + * Height of the selected/requested format + */ + FormatHeight: z.number(), + /** + * Width of the selected/requested format + */ + FormatWidth: z.number(), + /** + * Height, in pixels, of the conversion + */ + Height: z.number(), + /** + * Html representing the conversion + */ + Html: z.string(), + /** + * Id of the selected media format + */ + MediaFormatId: z.number(), + /** + * Name of the media format + */ + MediaFormatName: z.string(), + /** + * Name of the conversion + */ + Name: z.string(), + /** + * The url to the conversion + */ + Url: z.string(), + /** + * Width, in pixels, of the conversion + */ + Width: z.number(), +}) + +/** + * The response from ImageVault when inserting an asset + */ +export const deprecatedImageVaultAssetSchema = z.object({ + /** + * The media item id of the asset + */ + Id: z.number(), + /** + * The id of the vault where the asset resides + */ + VaultId: z.number(), + /** + * The name of the asset + */ + Name: z.string(), + /** + * The conversion selected by the user. Is an array but will only contain one object + */ + MediaConversions: z.array(deprecatedMediaConversionSchema), + Metadata: z.array(deprecatedMetaDataSchema), + /** + * Date when the asset was added to ImageVault + */ + DateAdded: z.string(), + /** + * Name of the user that added the asset to ImageVault + */ + AddedBy: z.string(), + FocalPoint: focalPointSchema.optional(), +}) + +export const imageVaultAssetSchema = z.object({ + imageVaultId: z.number(), + fileName: z.string(), + url: z.string(), + dimensions: z.object({ + width: z.number(), + height: z.number(), + aspectRatio: z.number(), + }), + focalPoint: focalPointSchema, + meta: z.object({ alt: z.string(), caption: z.string() }), +}) + +export const transformedImageVaultAssetSchema = imageVaultAssetSchema + .or(deprecatedImageVaultAssetSchema) + .nullish() + .or( + // Temp since there is a bug in Contentstack + // sending empty objects when there has been an + // image selected previously but has since been + // deleted + z.object({}) + ) + .transform((data) => { + if (!data || Object.keys(data).length === 0) { + return undefined + } + + if ("imageVaultId" in data && "fileName" in data) { + return mapImageVaultAssetResponseToImageVaultAsset(data) + } + + if ("Name" in data && "Id" in data) { + return mapInsertResponseToImageVaultAsset(data) + } + }) + +export type FocalPoint = z.infer + +export type DeprecatedImageVaultAssetResponse = z.infer< + typeof deprecatedImageVaultAssetSchema +> +export type ImageVaultAssetResponse = z.infer + +export type ImageVaultAsset = { + id: number + title: string + url: string + dimensions: { + width: number + height: number + aspectRatio: number + } + meta: { alt: string | undefined | null; caption: string | undefined | null } + focalPoint: FocalPoint +} + +export function mapInsertResponseToImageVaultAsset( + response: DeprecatedImageVaultAssetResponse +): ImageVaultAsset { + const alt = response.Metadata?.find((meta) => + meta.Name.includes("AltText_") + )?.Value + + const caption = response.Metadata?.find((meta) => + meta.Name.includes("Title_") + )?.Value + + const mediaConversion = response.MediaConversions[0] + const aspectRatio = + mediaConversion.FormatAspectRatio || + mediaConversion.AspectRatio || + mediaConversion.Width / mediaConversion.Height + + return { + id: response.Id, + title: response.Name, + url: mediaConversion.Url, + dimensions: { + width: mediaConversion.Width, + height: mediaConversion.Height, + aspectRatio, + }, + meta: { + alt, + caption, + }, + focalPoint: response.FocalPoint || { x: 50, y: 50 }, + } +} + +export function mapImageVaultAssetResponseToImageVaultAsset( + response: ImageVaultAssetResponse +): ImageVaultAsset { + return { + id: response.imageVaultId, + title: response.fileName, + url: response.url, + dimensions: { + width: response.dimensions.width, + height: response.dimensions.height, + aspectRatio: response.dimensions.aspectRatio, + }, + meta: { + alt: response.meta.alt, + caption: response.meta.caption, + }, + focalPoint: response.focalPoint, + } +} diff --git a/packages/design-system/lib/components/JsonToHtml/JsonToHtml.stories.tsx b/packages/design-system/lib/components/JsonToHtml/JsonToHtml.stories.tsx index 5a110fa21..b30b67aba 100644 --- a/packages/design-system/lib/components/JsonToHtml/JsonToHtml.stories.tsx +++ b/packages/design-system/lib/components/JsonToHtml/JsonToHtml.stories.tsx @@ -1,8 +1,8 @@ import type { Meta, StoryObj } from '@storybook/nextjs-vite' -import { JsonToHtml } from './JsonToHtml' -import { RTEImageVaultNode, RTENode } from './types/rte/node' -import { RTETypeEnum } from './types/rte/enums' import { expect } from 'storybook/test' +import { JsonToHtml } from './JsonToHtml' +import { RTETypeEnum } from './types/rte/enums' +import { RTEImageVaultNode, RTENode } from './types/rte/node' const meta: Meta = { title: 'Components/JsonToHtml', @@ -192,7 +192,8 @@ const image: RTEImageVaultNode = { url: 'https://imagevault.scandichotels.com/publishedmedia/77obkq3g4harjm8wyua9/Scandic_Family_Breakfast_2.jpg', height: '200px', width: '200px', - id: 1, + fileName: 'Scandic_Family_Breakfast_2.jpg', + imageVaultId: 1, title: 'Image Title', dimensions: { width: 200, height: 200, aspectRatio: 1.5 }, meta: { alt: 'Image Alt', caption: 'Image Caption' }, diff --git a/packages/design-system/lib/components/JsonToHtml/JsonToHtml.tsx b/packages/design-system/lib/components/JsonToHtml/JsonToHtml.tsx index 8a0ce3ff8..5bd5575e5 100644 --- a/packages/design-system/lib/components/JsonToHtml/JsonToHtml.tsx +++ b/packages/design-system/lib/components/JsonToHtml/JsonToHtml.tsx @@ -4,31 +4,15 @@ import { nodesToHtml } from './utils' import styles from './jsontohtml.module.css' +import { ImageVaultAsset } from '@scandic-hotels/common/utils/imageVault' +import { ContentBlockType } from './types/rte/enums' import type { RTENode } from './types/rte/node' import type { RenderOptions } from './types/rte/option' -import { ContentBlockType } from './types/rte/enums' export type Node = { node: T } -type Image = { - id: number - title: string - url: string - focalPoint: { - x: number - y: number - } - dimensions?: { - width: number - height: number - } - meta: { - alt?: string | null - caption?: string | null - } -} export type Embeds = | { __typename: Exclude @@ -38,11 +22,11 @@ export type Embeds = } | { __typename: 'ImageContainer' - system?: { uid: string } | undefined | null - url?: string | undefined | null - title?: string | undefined | null - image_left?: Image | undefined - image_right?: Image | undefined + system?: { uid: string } | null + url?: string | null + title?: string | null + image_left?: ImageVaultAsset + image_right?: ImageVaultAsset } export type EmbedByUid = Record> diff --git a/packages/design-system/lib/components/JsonToHtml/insertResponseToImageVaultAsset.ts b/packages/design-system/lib/components/JsonToHtml/insertResponseToImageVaultAsset.ts deleted file mode 100644 index a61d57a8d..000000000 --- a/packages/design-system/lib/components/JsonToHtml/insertResponseToImageVaultAsset.ts +++ /dev/null @@ -1,60 +0,0 @@ -export type ImageVaultAsset = { - id: number - title: string - url: string - dimensions: { - width: number - height: number - aspectRatio: number - } - meta: { alt: string | undefined | null; caption: string | undefined | null } - focalPoint: { x: number; y: number } -} - -type ImageVaultAssetResponse = { - Id: number - Name: string - FocalPoint: { x: number; y: number } - Metadata: Array<{ Name: string; Value: string }> - MediaConversions: Array<{ - Url: string - Width: number - Height: number - AspectRatio: number - FormatAspectRatio: number - }> -} - -export function insertResponseToImageVaultAsset( - response: ImageVaultAssetResponse -): ImageVaultAsset { - const alt = response.Metadata?.find((meta) => - meta.Name.includes('AltText_') - )?.Value - - const caption = response.Metadata?.find((meta) => - meta.Name.includes('Title_') - )?.Value - - const mediaConversion = response.MediaConversions[0] - const aspectRatio = - mediaConversion.FormatAspectRatio || - mediaConversion.AspectRatio || - mediaConversion.Width / mediaConversion.Height - - return { - url: mediaConversion.Url, - id: response.Id, - meta: { - alt, - caption, - }, - title: response.Name, - dimensions: { - width: mediaConversion.Width, - height: mediaConversion.Height, - aspectRatio, - }, - focalPoint: response.FocalPoint || { x: 50, y: 50 }, - } -} diff --git a/packages/design-system/lib/components/JsonToHtml/renderOptions.tsx b/packages/design-system/lib/components/JsonToHtml/renderOptions.tsx index 094b73b99..3534bb99e 100644 --- a/packages/design-system/lib/components/JsonToHtml/renderOptions.tsx +++ b/packages/design-system/lib/components/JsonToHtml/renderOptions.tsx @@ -15,9 +15,14 @@ import { import styles from './jsontohtml.module.css' -import { insertResponseToImageVaultAsset } from './insertResponseToImageVaultAsset' +import { + DeprecatedImageVaultAssetResponse, + ImageVaultAssetResponse, + mapImageVaultAssetResponseToImageVaultAsset, + mapInsertResponseToImageVaultAsset, +} from '@scandic-hotels/common/utils/imageVault' import type { EmbedByUid } from './JsonToHtml' -import type { Attributes, RTEImageVaultAttrs } from './types/rte/attrs' +import type { Attributes } from './types/rte/attrs' import { AvailableParagraphFormatEnum, RTEItemTypeEnum, @@ -478,13 +483,26 @@ export const renderOptions: RenderOptions = { return null } - const attrs = node.attrs as RTEImageVaultAttrs - const image = - 'dimensions' in attrs ? attrs : insertResponseToImageVaultAsset(attrs) + let image = undefined + if ('imageVaultId' in node.attrs && 'fileName' in node.attrs) { + image = mapImageVaultAssetResponseToImageVaultAsset( + node.attrs as unknown as ImageVaultAssetResponse + ) + } + + if ('Name' in node.attrs && 'Id' in node.attrs) { + image = mapInsertResponseToImageVaultAsset( + node.attrs as unknown as DeprecatedImageVaultAssetResponse + ) + } + + if (!image) { + return null + } const alt = image.meta.alt ?? image.title const caption = image.meta.caption - const { className, ...props } = extractPossibleAttributes(attrs) + const { className, ...props } = extractPossibleAttributes(node.attrs) return (
diff --git a/packages/design-system/lib/components/JsonToHtml/types/rte/node.ts b/packages/design-system/lib/components/JsonToHtml/types/rte/node.ts index d79df13dd..6b43fddd2 100644 --- a/packages/design-system/lib/components/JsonToHtml/types/rte/node.ts +++ b/packages/design-system/lib/components/JsonToHtml/types/rte/node.ts @@ -1,11 +1,14 @@ import type { JSX } from 'react' +import { + DeprecatedImageVaultAssetResponse, + ImageVaultAssetResponse, +} from '@scandic-hotels/common/utils/imageVault' import type { EmbedByUid } from '../../JsonToHtml' import type { Attributes, RTEAnchorAttrs, RTEAssetAttrs, - RTEImageVaultAttrs, RTELinkAttrs, } from './attrs' import type { RTETypeEnum } from './enums' @@ -39,7 +42,8 @@ export interface RTEReferenceLinkNode extends RTEDefaultNode { } export interface RTEImageVaultNode extends RTEDefaultNode { - attrs: RTEImageVaultAttrs + attrs: Attributes & + (DeprecatedImageVaultAssetResponse | ImageVaultAssetResponse) type: RTETypeEnum.ImageVault } diff --git a/packages/trpc/lib/graphql/Fragments/Blocks/Content.graphql b/packages/trpc/lib/graphql/Fragments/Blocks/Content.graphql index 1d7471226..89dd9d8a8 100644 --- a/packages/trpc/lib/graphql/Fragments/Blocks/Content.graphql +++ b/packages/trpc/lib/graphql/Fragments/Blocks/Content.graphql @@ -60,6 +60,7 @@ fragment Content_ContentPageRefs on ContentPageBlocksContent { edges { node { __typename + ...ImageContainerRef ...AccountPageRef ...CampaignOverviewPageRef ...CampaignPageRef diff --git a/packages/trpc/lib/routers/contentstack/accountPage/output.ts b/packages/trpc/lib/routers/contentstack/accountPage/output.ts index 3b26f7844..537ae82fe 100644 --- a/packages/trpc/lib/routers/contentstack/accountPage/output.ts +++ b/packages/trpc/lib/routers/contentstack/accountPage/output.ts @@ -1,5 +1,7 @@ import { z } from "zod" +import { transformedImageVaultAssetSchema } from "@scandic-hotels/common/utils/imageVault" + import { AccountPageEnum } from "../../../types/accountPageEnum" import { discriminatedUnionArray } from "../../../utils/discriminatedUnion" import { @@ -15,7 +17,6 @@ import { shortcutsSchema, } from "../schemas/blocks/shortcuts" import { textContentSchema } from "../schemas/blocks/textContent" -import { tempImageVaultAssetSchema } from "../schemas/imageVault" import { systemSchema } from "../schemas/system" const accountPageAccordions = z @@ -54,7 +55,7 @@ export const accountPageSchema = z.object({ content: discriminatedUnionArray(blocksSchema.options), heading: z.string().nullable(), preamble: z.string().nullable(), - hero_image: tempImageVaultAssetSchema, + hero_image: transformedImageVaultAssetSchema, hero_image_active: z .boolean() .nullable() diff --git a/packages/trpc/lib/routers/contentstack/campaignPage/output.ts b/packages/trpc/lib/routers/contentstack/campaignPage/output.ts index 244de145a..81d370ca6 100644 --- a/packages/trpc/lib/routers/contentstack/campaignPage/output.ts +++ b/packages/trpc/lib/routers/contentstack/campaignPage/output.ts @@ -1,5 +1,6 @@ import { z } from "zod" +import { transformedImageVaultAssetSchema } from "@scandic-hotels/common/utils/imageVault" import { removeMultipleSlashes } from "@scandic-hotels/common/utils/url" import { CampaignPageEnum } from "../../../types/campaignPage" @@ -14,7 +15,6 @@ import { } from "../schemas/blocks/carouselCards" import { essentialsBlockSchema } from "../schemas/blocks/essentials" import { campaignPageHotelListingSchema } from "../schemas/blocks/hotelListing" -import { tempImageVaultAssetSchema } from "../schemas/imageVault" import { linkConnectionRefs, linkConnectionSchema, @@ -22,7 +22,7 @@ import { import { systemSchema } from "../schemas/system" import { getCarouselCardsBlockWithBookingCodeLinks } from "./utils" -import type { ImageVaultAsset } from "../../../types/imageVault" +import type { ImageVaultAsset } from "@scandic-hotels/common/utils/imageVault" const campaignPageEssentials = z .object({ @@ -56,7 +56,7 @@ export const blocksSchema = z.discriminatedUnion("__typename", [ ]) export const heroSchema = z.object({ - image: tempImageVaultAssetSchema, + image: transformedImageVaultAssetSchema, heading: z.string(), theme: z.enum(["Peach", "Burgundy"]).default("Peach"), benefits: z @@ -206,7 +206,7 @@ export const campaignPagesByHotelUidSchema = z sort_order: z.number().nullish(), card_content: z .object({ - image: tempImageVaultAssetSchema, + image: transformedImageVaultAssetSchema, heading: z.string().nullish(), text: z.string().nullish(), }) diff --git a/packages/trpc/lib/routers/contentstack/collectionPage/output.ts b/packages/trpc/lib/routers/contentstack/collectionPage/output.ts index 19de82044..fff4cc37c 100644 --- a/packages/trpc/lib/routers/contentstack/collectionPage/output.ts +++ b/packages/trpc/lib/routers/contentstack/collectionPage/output.ts @@ -1,5 +1,7 @@ import { z } from "zod" +import { transformedImageVaultAssetSchema } from "@scandic-hotels/common/utils/imageVault" + import { CollectionPageEnum } from "../../../types/collectionPage" import { discriminatedUnionArray } from "../../../utils/discriminatedUnion" import { @@ -15,7 +17,6 @@ import { shortcutsSchema, } from "../schemas/blocks/shortcuts" import { uspGridRefsSchema, uspGridSchema } from "../schemas/blocks/uspGrid" -import { tempImageVaultAssetSchema } from "../schemas/imageVault" import { linkAndTitleSchema, linkConnectionRefs, @@ -87,7 +88,7 @@ const topPrimaryButtonSchema = linkAndTitleSchema // Content Page Schema and types export const collectionPageSchema = z.object({ collection_page: z.object({ - hero_image: tempImageVaultAssetSchema, + hero_image: transformedImageVaultAssetSchema, blocks: discriminatedUnionArray(blocksSchema.options).nullable(), title: z.string(), header: z.object({ diff --git a/packages/trpc/lib/routers/contentstack/contentPage/output.ts b/packages/trpc/lib/routers/contentstack/contentPage/output.ts index 76ad5edb5..558fd110e 100644 --- a/packages/trpc/lib/routers/contentstack/contentPage/output.ts +++ b/packages/trpc/lib/routers/contentstack/contentPage/output.ts @@ -1,5 +1,7 @@ import { z } from "zod" +import { transformedImageVaultAssetSchema } from "@scandic-hotels/common/utils/imageVault" + import { ContentPageEnum } from "../../../types/contentPage" import { discriminatedUnionArray } from "../../../utils/discriminatedUnion" import { @@ -30,7 +32,6 @@ import { dynamicContentRefsSchema as headerDynamicContentRefsSchema, dynamicContentSchema as headerDynamicContentSchema, } from "../schemas/headers/dynamicContent" -import { tempImageVaultAssetSchema } from "../schemas/imageVault" import { linkAndTitleSchema, linkConnectionRefs, @@ -203,7 +204,7 @@ const topPrimaryButtonSchema = linkAndTitleSchema // Content Page Schema and types export const contentPageSchema = z.object({ content_page: z.object({ - hero_image: tempImageVaultAssetSchema, + hero_image: transformedImageVaultAssetSchema, blocks: discriminatedUnionArray(blocksSchema.options).nullable(), sidebar: discriminatedUnionArray(sidebarSchema.options).nullable(), title: z.string(), diff --git a/packages/trpc/lib/routers/contentstack/destinationCityPage/output.ts b/packages/trpc/lib/routers/contentstack/destinationCityPage/output.ts index 29d9d7bea..2945f047a 100644 --- a/packages/trpc/lib/routers/contentstack/destinationCityPage/output.ts +++ b/packages/trpc/lib/routers/contentstack/destinationCityPage/output.ts @@ -1,5 +1,6 @@ import { z } from "zod" +import { transformedImageVaultAssetSchema } from "@scandic-hotels/common/utils/imageVault" import { removeMultipleSlashes } from "@scandic-hotels/common/utils/url" import { DestinationCityPageEnum } from "../../../types/destinationCityPage" @@ -10,7 +11,6 @@ import { accordionSchema, } from "../schemas/blocks/accordion" import { contentRefsSchema, contentSchema } from "../schemas/blocks/content" -import { tempImageVaultAssetSchema } from "../schemas/imageVault" import { mapLocationSchema } from "../schemas/mapLocation" import { linkRefsUnionSchema, @@ -19,7 +19,7 @@ import { } from "../schemas/pageLinks" import { systemSchema } from "../schemas/system" -import type { ImageVaultAsset } from "../../../types/imageVault" +import type { ImageVaultAsset } from "@scandic-hotels/common/utils/imageVault" export const destinationCityPageDestinationSettingsSchema = z .object({ @@ -73,7 +73,7 @@ export const destinationCityListDataSchema = z ) .nullish(), images: z - .array(z.object({ image: tempImageVaultAssetSchema })) + .array(z.object({ image: transformedImageVaultAssetSchema })) .transform((images) => images .map((image) => image.image) @@ -128,7 +128,7 @@ export const destinationCityPageSchema = z.object({ .nullish() .transform((experiences) => experiences?.destination_experiences ?? []), images: z - .array(z.object({ image: tempImageVaultAssetSchema })) + .array(z.object({ image: transformedImageVaultAssetSchema })) .transform((images) => images .map((image) => image.image) diff --git a/packages/trpc/lib/routers/contentstack/destinationCountryPage/output.ts b/packages/trpc/lib/routers/contentstack/destinationCountryPage/output.ts index fd4ab6415..80cd79981 100644 --- a/packages/trpc/lib/routers/contentstack/destinationCountryPage/output.ts +++ b/packages/trpc/lib/routers/contentstack/destinationCountryPage/output.ts @@ -1,5 +1,6 @@ import { z } from "zod" +import { transformedImageVaultAssetSchema } from "@scandic-hotels/common/utils/imageVault" import { removeMultipleSlashes } from "@scandic-hotels/common/utils/url" import { Country } from "../../../types/country" @@ -10,7 +11,6 @@ import { accordionSchema, } from "../schemas/blocks/accordion" import { contentRefsSchema, contentSchema } from "../schemas/blocks/content" -import { tempImageVaultAssetSchema } from "../schemas/imageVault" import { mapLocationSchema } from "../schemas/mapLocation" import { linkRefsUnionSchema, @@ -19,7 +19,7 @@ import { } from "../schemas/pageLinks" import { systemSchema } from "../schemas/system" -import type { ImageVaultAsset } from "../../../types/imageVault" +import type { ImageVaultAsset } from "@scandic-hotels/common/utils/imageVault" export const destinationCountryPageContent = z .object({ @@ -57,7 +57,7 @@ export const destinationCountryPageSchema = z.object({ }) .transform(({ destination_experiences }) => destination_experiences), images: z - .array(z.object({ image: tempImageVaultAssetSchema })) + .array(z.object({ image: transformedImageVaultAssetSchema })) .transform((images) => images .map((image) => image.image) diff --git a/packages/trpc/lib/routers/contentstack/loyaltyPage/output.ts b/packages/trpc/lib/routers/contentstack/loyaltyPage/output.ts index 820be2319..feadcc938 100644 --- a/packages/trpc/lib/routers/contentstack/loyaltyPage/output.ts +++ b/packages/trpc/lib/routers/contentstack/loyaltyPage/output.ts @@ -1,5 +1,7 @@ import { z } from "zod" +import { transformedImageVaultAssetSchema } from "@scandic-hotels/common/utils/imageVault" + import { LoyaltyPageEnum } from "../../../enums/loyaltyPage" import { discriminatedUnionArray } from "../../../utils/discriminatedUnion" import { @@ -18,7 +20,6 @@ import { shortcutsRefsSchema, shortcutsSchema, } from "../schemas/blocks/shortcuts" -import { tempImageVaultAssetSchema } from "../schemas/imageVault" import { contentRefsSchema as sidebarContentRefsSchema, contentSchema as sidebarContentSchema, @@ -166,7 +167,7 @@ export const loyaltyPageSchema = z.object({ .object({ blocks: discriminatedUnionArray(blocksSchema.options).nullable(), heading: z.string().optional(), - hero_image: tempImageVaultAssetSchema, + hero_image: transformedImageVaultAssetSchema, preamble: z.string().optional(), sidebar: discriminatedUnionArray(sidebarSchema.options).nullable(), title: z.string().optional(), diff --git a/packages/trpc/lib/routers/contentstack/metadata/output.ts b/packages/trpc/lib/routers/contentstack/metadata/output.ts index 4b07e7ed6..8422e2078 100644 --- a/packages/trpc/lib/routers/contentstack/metadata/output.ts +++ b/packages/trpc/lib/routers/contentstack/metadata/output.ts @@ -2,18 +2,18 @@ import { z } from "zod" import { findMyBooking } from "@scandic-hotels/common/constants/routes/findMyBooking" import { myStay } from "@scandic-hotels/common/constants/routes/myStay" +import { transformedImageVaultAssetSchema } from "@scandic-hotels/common/utils/imageVault" 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 "@scandic-hotels/common/utils/imageVault" -import type { ImageVaultAsset } from "../../../types/imageVault" import type { LanguageSwitcherData } from "../../../types/languageSwitcher" const metaDataJsonSchema = z.object({ @@ -56,7 +56,7 @@ export const rawMetadataSchema = z.object({ title: z.string().nullish(), description: z.string().nullish(), noindex: z.boolean().nullish(), - seo_image: tempImageVaultAssetSchema.nullable(), + seo_image: transformedImageVaultAssetSchema, }) .nullish(), breadcrumbs: z @@ -97,12 +97,12 @@ export const rawMetadataSchema = z.object({ .object({ heading: z.string().nullish(), preamble: z.string().nullish(), - hero_image: tempImageVaultAssetSchema.nullable(), + hero_image: transformedImageVaultAssetSchema, }) .nullish(), - hero_image: tempImageVaultAssetSchema.nullable(), + hero_image: transformedImageVaultAssetSchema, images: z - .array(z.object({ image: tempImageVaultAssetSchema }).nullish()) + .array(z.object({ image: transformedImageVaultAssetSchema }).nullish()) .transform((images) => images .map((image) => image?.image) diff --git a/packages/trpc/lib/routers/contentstack/schemas/blocks/activitiesCard.ts b/packages/trpc/lib/routers/contentstack/schemas/blocks/activitiesCard.ts index 312abbe3f..f2ad59866 100644 --- a/packages/trpc/lib/routers/contentstack/schemas/blocks/activitiesCard.ts +++ b/packages/trpc/lib/routers/contentstack/schemas/blocks/activitiesCard.ts @@ -1,9 +1,9 @@ import { z } from "zod" +import { transformedImageVaultAssetSchema } from "@scandic-hotels/common/utils/imageVault" import { removeMultipleSlashes } from "@scandic-hotels/common/utils/url" import { HotelPageEnum } from "../../../../types/hotelPageEnum" -import { tempImageVaultAssetSchema } from "../imageVault" import { collectionPageRefSchema, collectionPageSchema, @@ -18,7 +18,7 @@ export const activitiesCardSchema = z.object({ .default(HotelPageEnum.ContentStack.blocks.ActivitiesCard), upcoming_activities_card: z .object({ - background_image: tempImageVaultAssetSchema, + background_image: transformedImageVaultAssetSchema, body_text: z.string(), cta_text: z.string(), sidepeek_cta_text: z.string(), diff --git a/packages/trpc/lib/routers/contentstack/schemas/blocks/allCampaigns.ts b/packages/trpc/lib/routers/contentstack/schemas/blocks/allCampaigns.ts index c756e8081..74bea9764 100644 --- a/packages/trpc/lib/routers/contentstack/schemas/blocks/allCampaigns.ts +++ b/packages/trpc/lib/routers/contentstack/schemas/blocks/allCampaigns.ts @@ -1,13 +1,13 @@ import { z } from "zod" +import { transformedImageVaultAssetSchema } from "@scandic-hotels/common/utils/imageVault" import { removeMultipleSlashes } from "@scandic-hotels/common/utils/url" import { BlocksEnums } from "../../../../types/blocksEnum" -import { tempImageVaultAssetSchema } from "../imageVault" import { campaignPageRefSchema } from "../pageLinks" export const campaignPageCardSchema = z.object({ - image: tempImageVaultAssetSchema, + image: transformedImageVaultAssetSchema, heading: z.string(), text: z.string(), }) @@ -29,7 +29,7 @@ export const allCampaignsSchema = z.object({ url: z.string(), card_content: z .object({ - image: tempImageVaultAssetSchema, + image: transformedImageVaultAssetSchema, heading: z.string().nullish(), text: z.string().nullish(), }) diff --git a/packages/trpc/lib/routers/contentstack/schemas/blocks/cards/contentCard.ts b/packages/trpc/lib/routers/contentstack/schemas/blocks/cards/contentCard.ts index 89f018e52..a77b3b11d 100644 --- a/packages/trpc/lib/routers/contentstack/schemas/blocks/cards/contentCard.ts +++ b/packages/trpc/lib/routers/contentstack/schemas/blocks/cards/contentCard.ts @@ -1,7 +1,8 @@ import { z } from "zod" +import { transformedImageVaultAssetSchema } from "@scandic-hotels/common/utils/imageVault" + import { CardsEnum } from "../../../../../types/cardsEnum" -import { tempImageVaultAssetSchema } from "../../imageVault" import { systemSchema } from "../../system" import { buttonSchema } from "../utils/buttonLinkSchema" import { linkConnectionRefsSchema } from "../utils/linkConnection" @@ -10,7 +11,7 @@ export const contentCardSchema = z.object({ __typename: z.literal(CardsEnum.ContentCard), title: z.string(), heading: z.string(), - image: tempImageVaultAssetSchema, + image: transformedImageVaultAssetSchema, body_text: z.string(), promo_text: z.string().optional(), has_card_link: z.boolean(), diff --git a/packages/trpc/lib/routers/contentstack/schemas/blocks/cards/infoCard.ts b/packages/trpc/lib/routers/contentstack/schemas/blocks/cards/infoCard.ts index d21f7703c..aa8314010 100644 --- a/packages/trpc/lib/routers/contentstack/schemas/blocks/cards/infoCard.ts +++ b/packages/trpc/lib/routers/contentstack/schemas/blocks/cards/infoCard.ts @@ -1,7 +1,8 @@ import { z } from "zod" +import { transformedImageVaultAssetSchema } from "@scandic-hotels/common/utils/imageVault" + import { CardsEnum } from "../../../../../types/cardsEnum" -import { tempImageVaultAssetSchema } from "../../imageVault" import { systemSchema } from "../../system" import { buttonSchema } from "../utils/buttonLinkSchema" import { linkConnectionRefsSchema } from "../utils/linkConnection" @@ -19,7 +20,7 @@ export const infoCardBlockSchema = z.object({ scripted_top_title: z.string().optional(), heading: z.string().optional().default(""), body_text: z.string().optional().default(""), - image: tempImageVaultAssetSchema, + image: transformedImageVaultAssetSchema, theme: z.enum(INFO_CARD_THEMES).nullable(), title: z.string().optional(), primary_button: buttonSchema.optional().nullable(), diff --git a/packages/trpc/lib/routers/contentstack/schemas/blocks/cards/loyaltyCard.ts b/packages/trpc/lib/routers/contentstack/schemas/blocks/cards/loyaltyCard.ts index 3459beae6..ca3fb3b37 100644 --- a/packages/trpc/lib/routers/contentstack/schemas/blocks/cards/loyaltyCard.ts +++ b/packages/trpc/lib/routers/contentstack/schemas/blocks/cards/loyaltyCard.ts @@ -1,7 +1,8 @@ import { z } from "zod" +import { transformedImageVaultAssetSchema } from "@scandic-hotels/common/utils/imageVault" + import { CardsEnum } from "../../../../../types/cardsEnum" -import { tempImageVaultAssetSchema } from "../../imageVault" import { systemSchema } from "../../system" import { buttonSchema } from "../utils/buttonLinkSchema" import { linkConnectionRefsSchema } from "../utils/linkConnection" @@ -11,7 +12,7 @@ export const loyaltyCardBlockSchema = z.object({ body_text: z.string().optional(), heading: z.string().optional().default(""), // JSON - ImageVault Image - image: tempImageVaultAssetSchema, + image: transformedImageVaultAssetSchema, link: buttonSchema, system: systemSchema, title: z.string().optional(), diff --git a/packages/trpc/lib/routers/contentstack/schemas/blocks/cards/teaserCard.ts b/packages/trpc/lib/routers/contentstack/schemas/blocks/cards/teaserCard.ts index dfc2c9ab9..0027952e1 100644 --- a/packages/trpc/lib/routers/contentstack/schemas/blocks/cards/teaserCard.ts +++ b/packages/trpc/lib/routers/contentstack/schemas/blocks/cards/teaserCard.ts @@ -1,7 +1,8 @@ import { z } from "zod" +import { transformedImageVaultAssetSchema } from "@scandic-hotels/common/utils/imageVault" + import { CardsEnum } from "../../../../../types/cardsEnum" -import { tempImageVaultAssetSchema } from "../../imageVault" import { accountPageSchema, campaignOverviewPageSchema, @@ -26,7 +27,7 @@ export const teaserCardBlockSchema = z.object({ __typename: z.literal(CardsEnum.TeaserCard), heading: z.string().default(""), body_text: z.string().default(""), - image: tempImageVaultAssetSchema, + image: transformedImageVaultAssetSchema, primary_button: buttonSchema, secondary_button: buttonSchema, has_primary_button: z.boolean().default(false), diff --git a/packages/trpc/lib/routers/contentstack/schemas/blocks/cardsGrid.ts b/packages/trpc/lib/routers/contentstack/schemas/blocks/cardsGrid.ts index 9279f531b..8543fd48d 100644 --- a/packages/trpc/lib/routers/contentstack/schemas/blocks/cardsGrid.ts +++ b/packages/trpc/lib/routers/contentstack/schemas/blocks/cardsGrid.ts @@ -1,12 +1,13 @@ import { z } from "zod" +import { transformedImageVaultAssetSchema } from "@scandic-hotels/common/utils/imageVault" + import { scriptedCardThemeEnum } from "../../../../enums/scriptedCard" import { BlocksEnums } from "../../../../types/blocksEnum" import { CardsGridEnum, CardsGridLayoutEnum, } from "../../../../types/cardsGridEnum" -import { tempImageVaultAssetSchema } from "../imageVault" import { systemSchema } from "../system" import { infoCardBlockRefsSchema, @@ -28,7 +29,7 @@ import { linkConnectionRefsSchema } from "./utils/linkConnection" export const cardBlockSchema = z.object({ __typename: z.literal(CardsGridEnum.cards.Card), // JSON - ImageVault Image - background_image: tempImageVaultAssetSchema, + background_image: transformedImageVaultAssetSchema, body_text: z.string().optional().default(""), has_primary_button: z.boolean().default(false), has_secondary_button: z.boolean().default(false), diff --git a/packages/trpc/lib/routers/contentstack/schemas/blocks/fullWidthCampaign.ts b/packages/trpc/lib/routers/contentstack/schemas/blocks/fullWidthCampaign.ts index c1c8f8660..3da1ef7c3 100644 --- a/packages/trpc/lib/routers/contentstack/schemas/blocks/fullWidthCampaign.ts +++ b/packages/trpc/lib/routers/contentstack/schemas/blocks/fullWidthCampaign.ts @@ -1,8 +1,9 @@ import { z } from "zod" +import { transformedImageVaultAssetSchema } from "@scandic-hotels/common/utils/imageVault" + import * as pageLinks from "../../../../routers/contentstack/schemas/pageLinks" import { BlocksEnums } from "../../../../types/blocksEnum" -import { tempImageVaultAssetSchema } from "../imageVault" import { systemSchema } from "../system" import { buttonSchema } from "./utils/buttonLinkSchema" @@ -13,7 +14,7 @@ export const fullWidthCampaignSchema = z.object({ edges: z.array( z.object({ node: z.object({ - background_image: tempImageVaultAssetSchema, + background_image: transformedImageVaultAssetSchema, heading: z.string().optional(), body_text: z.string().optional(), scripted_top_title: z.string().optional(), diff --git a/packages/trpc/lib/routers/contentstack/schemas/blocks/imageContainer.ts b/packages/trpc/lib/routers/contentstack/schemas/blocks/imageContainer.ts index de25ee3fb..ad51a9b1e 100644 --- a/packages/trpc/lib/routers/contentstack/schemas/blocks/imageContainer.ts +++ b/packages/trpc/lib/routers/contentstack/schemas/blocks/imageContainer.ts @@ -1,15 +1,14 @@ import { z } from "zod" +import { transformedImageVaultAssetSchema } from "@scandic-hotels/common/utils/imageVault" + import { ContentEnum } from "../../../../types/content" -import { tempImageVaultAssetSchema } from "../imageVault" import { systemSchema } from "../system" export const imageContainerSchema = z.object({ __typename: z.literal(ContentEnum.blocks.ImageContainer), - // JSON - ImageVault Image - image_left: tempImageVaultAssetSchema, - // JSON - ImageVault Image - image_right: tempImageVaultAssetSchema, + image_left: transformedImageVaultAssetSchema, + image_right: transformedImageVaultAssetSchema, system: systemSchema, title: z.string().optional(), }) diff --git a/packages/trpc/lib/routers/contentstack/schemas/blocks/joinScandicFriends.ts b/packages/trpc/lib/routers/contentstack/schemas/blocks/joinScandicFriends.ts index ef73310e8..cc5bf3796 100644 --- a/packages/trpc/lib/routers/contentstack/schemas/blocks/joinScandicFriends.ts +++ b/packages/trpc/lib/routers/contentstack/schemas/blocks/joinScandicFriends.ts @@ -1,7 +1,8 @@ import { z } from "zod" +import { transformedImageVaultAssetSchema } from "@scandic-hotels/common/utils/imageVault" + import { BlocksEnums } from "../../../../types/blocksEnum" -import { tempImageVaultAssetSchema } from "../imageVault" import { buttonSchema } from "./utils/buttonLinkSchema" import { linkConnectionRefsSchema } from "./utils/linkConnection" @@ -11,7 +12,7 @@ export const joinScandicFriendsSchema = z.object({ scripted_top_title: z.string(), title: z.string(), preamble: z.string(), - image: tempImageVaultAssetSchema, + image: transformedImageVaultAssetSchema, show_usp: z.boolean().default(false), usp: z.array(z.string()), has_primary_button: z.boolean().default(false), diff --git a/packages/trpc/lib/routers/contentstack/schemas/imageVault.ts b/packages/trpc/lib/routers/contentstack/schemas/imageVault.ts deleted file mode 100644 index a824858c7..000000000 --- a/packages/trpc/lib/routers/contentstack/schemas/imageVault.ts +++ /dev/null @@ -1,163 +0,0 @@ -import { z } from "zod" - -import { insertResponseToImageVaultAsset } from "../../../utils/imageVault" - -import type { ImageVaultAssetResponse } from "../../../types/imageVault" - -const metaData = z.object({ - DefinitionType: z.number().nullable().optional(), - Description: z.string().nullable(), - LanguageId: z.number().nullable(), - MetadataDefinitionId: z.number(), - Name: z.string(), - Value: z.string().nullable(), -}) - -export const focalPointSchema = z.object({ - x: z.number(), - y: z.number(), -}) - -/** - * Defines a media asset, original or conversion - */ -const mediaConversion = z.object({ - /** - * Aspect ratio of the conversion - */ - AspectRatio: z.number(), - /** - * Content type of the conversion - */ - ContentType: z.string(), - /** - * Aspect ratio of the selected/requested format - */ - FormatAspectRatio: z.number(), - /** - * Height of the selected/requested format - */ - FormatHeight: z.number(), - /** - * Width of the selected/requested format - */ - FormatWidth: z.number(), - /** - * Height, in pixels, of the conversion - */ - Height: z.number(), - /** - * Html representing the conversion - */ - Html: z.string(), - /** - * Id of the selected media format - */ - MediaFormatId: z.number(), - /** - * Name of the media format - */ - MediaFormatName: z.string(), - /** - * Name of the conversion - */ - Name: z.string(), - /** - * The url to the conversion - */ - Url: z.string(), - /** - * Width, in pixels, of the conversion - */ - Width: z.number(), -}) - -/** - * The response from ImageVault when inserting an asset - */ -export const imageVaultAssetSchema = z.object({ - /** - * The media item id of the asset - */ - Id: z.number(), - /** - * The id of the vault where the asset resides - */ - VaultId: z.number(), - /** - * The name of the asset - */ - Name: z.string(), - /** - * The conversion selected by the user. Is an array but will only contain one object - */ - MediaConversions: z.array(mediaConversion), - Metadata: z.array(metaData), - /** - * Date when the asset was added to ImageVault - */ - DateAdded: z.string(), - /** - * Name of the user that added the asset to ImageVault - */ - AddedBy: z.string(), - FocalPoint: focalPointSchema.optional(), -}) - -export const imageVaultAssetTransformedSchema = imageVaultAssetSchema.transform( - (rawData) => { - const alt = rawData.Metadata?.find((meta) => - meta.Name.includes("AltText_") - )?.Value - - const caption = rawData.Metadata?.find((meta) => - meta.Name.includes("Title_") - )?.Value - const mediaConversion = rawData.MediaConversions[0] - const aspectRatio = - mediaConversion.FormatAspectRatio || - mediaConversion.AspectRatio || - mediaConversion.Width / mediaConversion.Height - - return { - url: mediaConversion.Url, - id: rawData.Id, - meta: { - alt, - caption, - }, - title: rawData.Name, - dimensions: { - width: mediaConversion.Width, - height: mediaConversion.Height, - aspectRatio, - }, - focalPoint: rawData.FocalPoint || { x: 50, y: 50 }, - } - } -) - -export const tempImageVaultAssetSchema = imageVaultAssetSchema - .nullable() - .optional() - .or( - // Temp since there is a bug in Contentstack - // sending empty objects when there has been an - // image selected previously but has since been - // deleted - z.object({}) - ) - .transform((data) => { - if (data) { - if ("Name" in data) { - return makeImageVaultImage(data) - } - } - return undefined - }) - -function makeImageVaultImage(image: any) { - return image && !!Object.keys(image).length - ? insertResponseToImageVaultAsset(image as ImageVaultAssetResponse) - : undefined -} diff --git a/packages/trpc/lib/routers/contentstack/startPage/output.ts b/packages/trpc/lib/routers/contentstack/startPage/output.ts index 81c4d9888..10980da55 100644 --- a/packages/trpc/lib/routers/contentstack/startPage/output.ts +++ b/packages/trpc/lib/routers/contentstack/startPage/output.ts @@ -1,5 +1,7 @@ import { z } from "zod" +import { transformedImageVaultAssetSchema } from "@scandic-hotels/common/utils/imageVault" + import { discriminatedUnionArray } from "../../../utils/discriminatedUnion" import { cardGridRefsSchema, @@ -17,7 +19,6 @@ import { joinScandicFriendsBlockRefsSchema, joinScandicFriendsBlockSchema, } from "../schemas/blocks/joinScandicFriends" -import { tempImageVaultAssetSchema } from "../schemas/imageVault" import { systemSchema } from "../schemas/system" import { StartPageEnum } from "./utils" @@ -57,7 +58,7 @@ export const startPageSchema = z.object({ title: z.string(), header: z.object({ heading: z.string(), - hero_image: tempImageVaultAssetSchema, + hero_image: transformedImageVaultAssetSchema, }), blocks: discriminatedUnionArray(blocksSchema.options) .nullable() diff --git a/packages/trpc/lib/types/image.ts b/packages/trpc/lib/types/image.ts index 797694767..f5efeae00 100644 --- a/packages/trpc/lib/types/image.ts +++ b/packages/trpc/lib/types/image.ts @@ -1,8 +1,3 @@ -export interface FocalPoint { - x: number - y: number -} - export interface Image { description?: string | null dimension: { diff --git a/packages/trpc/lib/types/imageVault.ts b/packages/trpc/lib/types/imageVault.ts deleted file mode 100644 index 2fead48ec..000000000 --- a/packages/trpc/lib/types/imageVault.ts +++ /dev/null @@ -1,28 +0,0 @@ -/** - * @file TypeScript typings for ImageVault - * - * The types in this file are based on the source maps of the downloaded - * distribution at https://clientscript.imagevault.se/Installation/ImageVaultInsertMedia - * - * They have been clean up and amended to. - */ - -import type { z } from "zod" - -import type { imageVaultAssetSchema } from "../routers/contentstack/schemas/imageVault" -import type { FocalPoint } from "./image" - -export type ImageVaultAssetResponse = z.infer - -export type ImageVaultAsset = { - id: number - title: string - url: string - dimensions: { - width: number - height: number - aspectRatio: number - } - meta: { alt: string | undefined | null; caption: string | undefined | null } - focalPoint: FocalPoint -} diff --git a/packages/trpc/lib/utils/imageVault.ts b/packages/trpc/lib/utils/imageVault.ts deleted file mode 100644 index dcdbd0c91..000000000 --- a/packages/trpc/lib/utils/imageVault.ts +++ /dev/null @@ -1,38 +0,0 @@ -import type { - ImageVaultAsset, - ImageVaultAssetResponse, -} from "../types/imageVault" - -export function insertResponseToImageVaultAsset( - response: ImageVaultAssetResponse -): ImageVaultAsset { - const alt = response.Metadata?.find((meta) => - meta.Name.includes("AltText_") - )?.Value - - const caption = response.Metadata?.find((meta) => - meta.Name.includes("Title_") - )?.Value - - const mediaConversion = response.MediaConversions[0] - const aspectRatio = - mediaConversion.FormatAspectRatio || - mediaConversion.AspectRatio || - mediaConversion.Width / mediaConversion.Height - - return { - url: mediaConversion.Url, - id: response.Id, - meta: { - alt, - caption, - }, - title: response.Name, - dimensions: { - width: mediaConversion.Width, - height: mediaConversion.Height, - aspectRatio, - }, - focalPoint: response.FocalPoint || { x: 50, y: 50 }, - } -}