import { z } from "zod" import { focalPointSchema } from "./focalPoint" 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, } }