diff --git a/dotcom-rendering/src/frontend/feArticle.ts b/dotcom-rendering/src/frontend/feArticle.ts index 31737764096..94790182154 100644 --- a/dotcom-rendering/src/frontend/feArticle.ts +++ b/dotcom-rendering/src/frontend/feArticle.ts @@ -1,4 +1,5 @@ import { type CrosswordProps } from '@guardian/react-crossword'; +import { literal, object, type Output, union } from 'valibot'; import type { EditionId } from '../lib/edition'; import type { FEArticleBadgeType } from '../types/badge'; import type { Block } from '../types/blocks'; @@ -135,65 +136,70 @@ type PageType = { isSensitive: boolean; }; -type ThemePillar = - | 'NewsPillar' - | 'OpinionPillar' - | 'SportPillar' - | 'CulturePillar' - | 'LifestylePillar'; - -type ThemeSpecial = 'SpecialReportTheme' | 'Labs' | 'SpecialReportAltTheme'; -type FETheme = ThemePillar | ThemeSpecial; +const FEThemeSchema = union([ + literal('NewsPillar'), + literal('OpinionPillar'), + literal('SportPillar'), + literal('CulturePillar'), + literal('LifestylePillar'), + literal('SpecialReportTheme'), + literal('Labs'), + literal('SpecialReportAltTheme'), +]); /** * FEDesign is what frontend gives (originating in the capi scala client) us on the Format field * https://github.com/guardian/content-api-scala-client/blob/master/client/src/main/scala/com.gu.contentapi.client/utils/format/Design.scala */ -type FEDesign = - | 'ArticleDesign' - | 'PictureDesign' - | 'GalleryDesign' - | 'AudioDesign' - | 'VideoDesign' - | 'CrosswordDesign' - | 'ReviewDesign' - | 'AnalysisDesign' - | 'CommentDesign' - | 'ExplainerDesign' - | 'LetterDesign' - | 'FeatureDesign' - | 'LiveBlogDesign' - | 'DeadBlogDesign' - | 'RecipeDesign' - | 'MatchReportDesign' - | 'InterviewDesign' - | 'EditorialDesign' - | 'QuizDesign' - | 'InteractiveDesign' - | 'PhotoEssayDesign' - | 'ObituaryDesign' - | 'FullPageInteractiveDesign' - | 'NewsletterSignupDesign' - | 'TimelineDesign' - | 'ProfileDesign'; +const FEDesignSchema = union([ + literal('ArticleDesign'), + literal('PictureDesign'), + literal('GalleryDesign'), + literal('AudioDesign'), + literal('VideoDesign'), + literal('CrosswordDesign'), + literal('ReviewDesign'), + literal('AnalysisDesign'), + literal('CommentDesign'), + literal('ExplainerDesign'), + literal('LetterDesign'), + literal('FeatureDesign'), + literal('LiveBlogDesign'), + literal('DeadBlogDesign'), + literal('RecipeDesign'), + literal('MatchReportDesign'), + literal('InterviewDesign'), + literal('EditorialDesign'), + literal('QuizDesign'), + literal('InteractiveDesign'), + literal('PhotoEssayDesign'), + literal('ObituaryDesign'), + literal('FullPageInteractiveDesign'), + literal('NewsletterSignupDesign'), + literal('TimelineDesign'), + literal('ProfileDesign'), +]); /** FEDisplay is the display information passed through from frontend (originating in the capi scala client) and dictates the display style of the content e.g. Immersive https://github.com/guardian/content-api-scala-client/blob/master/client/src/main/scala/com.gu.contentapi.client/utils/format/Display.scala */ -type FEDisplay = - | 'StandardDisplay' - | 'ImmersiveDisplay' - | 'ShowcaseDisplay' - | 'NumberedListDisplay'; +const FEDisplaySchema = union([ + literal('StandardDisplay'), + literal('ImmersiveDisplay'), + literal('ShowcaseDisplay'), + literal('NumberedListDisplay'), +]); /** * FEFormat is the stringified version of Format passed through from Frontend. * It gets converted to the `@guardian/libs` format on platform */ -export type FEFormat = { - design: FEDesign; - theme: FETheme; - display: FEDisplay; -}; +export type FEFormat = Output; + +export const FEFormatSchema = object({ + design: FEDesignSchema, + theme: FEThemeSchema, + display: FEDisplaySchema, +}); export type FEStoryPackage = { heading: string; diff --git a/dotcom-rendering/src/frontend/schemas/feArticle.json b/dotcom-rendering/src/frontend/schemas/feArticle.json index fc5d48ab93a..95979b28ebf 100644 --- a/dotcom-rendering/src/frontend/schemas/feArticle.json +++ b/dotcom-rendering/src/frontend/schemas/feArticle.json @@ -119,24 +119,7 @@ } }, "format": { - "description": "FEFormat is the stringified version of Format passed through from Frontend.\nIt gets converted to the `@guardian/libs` format on platform", - "type": "object", - "properties": { - "design": { - "$ref": "#/definitions/FEDesign" - }, - "theme": { - "$ref": "#/definitions/FETheme" - }, - "display": { - "$ref": "#/definitions/FEDisplay" - } - }, - "required": [ - "design", - "display", - "theme" - ] + "$ref": "#/definitions/{design:\"ArticleDesign\"|\"PictureDesign\"|\"GalleryDesign\"|\"AudioDesign\"|\"VideoDesign\"|\"CrosswordDesign\"|\"ReviewDesign\"|\"AnalysisDesign\"|\"CommentDesign\"|\"ExplainerDesign\"|\"LetterDesign\"|\"FeatureDesign\"|\"LiveBlogDesign\"|\"DeadBlogDesign\"|\"RecipeDesign\"|\"MatchReportDesign\"|\"InterviewDesign\"|\"EditorialDesign\"|\"QuizDesign\"|\"InteractiveDesign\"|\"PhotoEssayDesign\"|\"ObituaryDesign\"|\"FullPageInteractiveDesign\"|\"NewsletterSignupDesign\"|\"TimelineDesign\"|\"ProfileDesign\";theme:\"NewsPillar\"|\"OpinionPillar\"|\"SportPillar\"|\"CulturePillar\"|\"LifestylePillar\"|\"SpecialReportTheme\"|\"Labs\"|\"SpecialReportAltTheme\";display:\"StandardDisplay\"|\"ImmersiveDisplay\"|\"ShowcaseDisplay\"|\"NumberedListDisplay\";}" }, "designType": { "type": "string" @@ -229,7 +212,7 @@ "trails": { "type": "array", "items": { - "$ref": "#/definitions/FETrailType" + "$ref": "#/definitions/{url:string;headline:string;format:{design:\"ArticleDesign\"|\"PictureDesign\"|\"GalleryDesign\"|\"AudioDesign\"|\"VideoDesign\"|\"CrosswordDesign\"|\"ReviewDesign\"|\"AnalysisDesign\"|\"CommentDesign\"|\"ExplainerDesign\"|\"LetterDesign\"|\"FeatureDesign\"|\"LiveBlogDesign\"|\"DeadBlogDesign\"|\"RecipeDesign\"|\"MatchReportDesign\"|\"InterviewDesign\"|\"EditorialDesign\"|\"QuizDesign\"|\"InteractiveDesign\"|\"PhotoEssayDesign\"|\"ObituaryDesign\"|\"FullPageInteractiveDesign\"|\"NewsletterSignupDesign\"|\"TimelineDesign\"|\"ProfileDesign\";theme:\"NewsPillar\"|\"OpinionPillar\"|\"SportPillar\"|\"CulturePillar\"|\"LifestylePillar\"|\"SpecialReportTheme\"|\"Labs\"|\"SpecialReportAltTheme\";display:\"StandardDisplay\"|\"ImmersiveDisplay\"|\"ShowcaseDisplay\"|\"NumberedListDisplay\";};webPublicationDate?:string;avatarUrl?:string;mediaDuration?:number;ageWarning?:string;byline?:string;showByline?:boolean;kickerText?:string;shortUrl?:string;commentCount?:number;starRating?:0|5|4|3|2|1;linkText?:string;branding?:{sponsorName:string;logo:{src:string;link:string;label:string;dimensions:{width:number;height:number;};};aboutThisLink:string;brandingType?:{name:\"paid-content\";}|{name:\"foundation\";}|{name:\"sponsored\";};logoForDarkBackground?:{src:string;link:string;label:string;dimensions:{width:number;height:number;};};};isSnap?:boolean;isCrossword?:boolean;snapData?:{embedHtml?:string;embedCss?:string;embedJs?:string;};showQuotedHeadline?:boolean;discussion?:{isCommentable:boolean;isClosedForComments:boolean;discussionId?:string;};mainMedia?:{width:number;height:number;type:\"Video\";id:string;videoId:string;origin:string;title:string;duration:number;expired:boolean;image?:string;}|{width:number;height:number;type:\"LoopVideo\";videoId:string;duration:number;atomId:string;image?:string;}|{type:\"Audio\";duration:string;podcastImage?:{src?:string;altText?:string;};}|{type:\"Gallery\";count:string;};image?:string;designType?:string;pillar?:string;carouselImages?:{[x:string]:string;};isLiveBlog?:boolean;masterImage?:string;}" } } }, @@ -250,7 +233,7 @@ "trails": { "type": "array", "items": { - "$ref": "#/definitions/FETrailType" + "$ref": "#/definitions/{url:string;headline:string;format:{design:\"ArticleDesign\"|\"PictureDesign\"|\"GalleryDesign\"|\"AudioDesign\"|\"VideoDesign\"|\"CrosswordDesign\"|\"ReviewDesign\"|\"AnalysisDesign\"|\"CommentDesign\"|\"ExplainerDesign\"|\"LetterDesign\"|\"FeatureDesign\"|\"LiveBlogDesign\"|\"DeadBlogDesign\"|\"RecipeDesign\"|\"MatchReportDesign\"|\"InterviewDesign\"|\"EditorialDesign\"|\"QuizDesign\"|\"InteractiveDesign\"|\"PhotoEssayDesign\"|\"ObituaryDesign\"|\"FullPageInteractiveDesign\"|\"NewsletterSignupDesign\"|\"TimelineDesign\"|\"ProfileDesign\";theme:\"NewsPillar\"|\"OpinionPillar\"|\"SportPillar\"|\"CulturePillar\"|\"LifestylePillar\"|\"SpecialReportTheme\"|\"Labs\"|\"SpecialReportAltTheme\";display:\"StandardDisplay\"|\"ImmersiveDisplay\"|\"ShowcaseDisplay\"|\"NumberedListDisplay\";};webPublicationDate?:string;avatarUrl?:string;mediaDuration?:number;ageWarning?:string;byline?:string;showByline?:boolean;kickerText?:string;shortUrl?:string;commentCount?:number;starRating?:0|5|4|3|2|1;linkText?:string;branding?:{sponsorName:string;logo:{src:string;link:string;label:string;dimensions:{width:number;height:number;};};aboutThisLink:string;brandingType?:{name:\"paid-content\";}|{name:\"foundation\";}|{name:\"sponsored\";};logoForDarkBackground?:{src:string;link:string;label:string;dimensions:{width:number;height:number;};};};isSnap?:boolean;isCrossword?:boolean;snapData?:{embedHtml?:string;embedCss?:string;embedJs?:string;};showQuotedHeadline?:boolean;discussion?:{isCommentable:boolean;isClosedForComments:boolean;discussionId?:string;};mainMedia?:{width:number;height:number;type:\"Video\";id:string;videoId:string;origin:string;title:string;duration:number;expired:boolean;image?:string;}|{width:number;height:number;type:\"LoopVideo\";videoId:string;duration:number;atomId:string;image?:string;}|{type:\"Audio\";duration:string;podcastImage?:{src?:string;altText?:string;};}|{type:\"Gallery\";count:string;};image?:string;designType?:string;pillar?:string;carouselImages?:{[x:string]:string;};isLiveBlog?:boolean;masterImage?:string;}" } }, "description": { @@ -263,24 +246,7 @@ "$ref": "#/definitions/OnwardsSource" }, "format": { - "description": "FEFormat is the stringified version of Format passed through from Frontend.\nIt gets converted to the `@guardian/libs` format on platform", - "type": "object", - "properties": { - "design": { - "$ref": "#/definitions/FEDesign" - }, - "theme": { - "$ref": "#/definitions/FETheme" - }, - "display": { - "$ref": "#/definitions/FEDisplay" - } - }, - "required": [ - "design", - "display", - "theme" - ] + "$ref": "#/definitions/{design:\"ArticleDesign\"|\"PictureDesign\"|\"GalleryDesign\"|\"AudioDesign\"|\"VideoDesign\"|\"CrosswordDesign\"|\"ReviewDesign\"|\"AnalysisDesign\"|\"CommentDesign\"|\"ExplainerDesign\"|\"LetterDesign\"|\"FeatureDesign\"|\"LiveBlogDesign\"|\"DeadBlogDesign\"|\"RecipeDesign\"|\"MatchReportDesign\"|\"InterviewDesign\"|\"EditorialDesign\"|\"QuizDesign\"|\"InteractiveDesign\"|\"PhotoEssayDesign\"|\"ObituaryDesign\"|\"FullPageInteractiveDesign\"|\"NewsletterSignupDesign\"|\"TimelineDesign\"|\"ProfileDesign\";theme:\"NewsPillar\"|\"OpinionPillar\"|\"SportPillar\"|\"CulturePillar\"|\"LifestylePillar\"|\"SpecialReportTheme\"|\"Labs\"|\"SpecialReportAltTheme\";display:\"StandardDisplay\"|\"ImmersiveDisplay\"|\"ShowcaseDisplay\"|\"NumberedListDisplay\";}" }, "isCuratedContent": { "type": "boolean" @@ -304,7 +270,15 @@ "$ref": "#/definitions/CommercialProperties" }, "starRating": { - "$ref": "#/definitions/StarRating" + "enum": [ + 0, + 1, + 2, + 3, + 4, + 5 + ], + "type": "number" }, "audioArticleImage": { "$ref": "#/definitions/ImageBlockElement" @@ -2204,7 +2178,15 @@ "type": "string" }, "starRating": { - "$ref": "#/definitions/StarRating" + "enum": [ + 0, + 1, + 2, + 3, + 4, + 5 + ], + "type": "number" }, "isAvatar": { "type": "boolean" @@ -2268,17 +2250,6 @@ "width" ] }, - "StarRating": { - "enum": [ - 0, - 1, - 2, - 3, - 4, - 5 - ], - "type": "number" - }, "InstagramBlockElement": { "type": "object", "properties": { @@ -3332,7 +3303,15 @@ "type": "string" }, "rating": { - "$ref": "#/definitions/StarRating" + "enum": [ + 0, + 1, + 2, + 3, + 4, + 5 + ], + "type": "number" }, "size": { "$ref": "#/definitions/RatingSizeType" @@ -4576,60 +4555,69 @@ ], "type": "string" }, - "FEDesign": { - "description": "FEDesign is what frontend gives (originating in the capi scala client) us on the Format field\nhttps://github.com/guardian/content-api-scala-client/blob/master/client/src/main/scala/com.gu.contentapi.client/utils/format/Design.scala", - "enum": [ - "AnalysisDesign", - "ArticleDesign", - "AudioDesign", - "CommentDesign", - "CrosswordDesign", - "DeadBlogDesign", - "EditorialDesign", - "ExplainerDesign", - "FeatureDesign", - "FullPageInteractiveDesign", - "GalleryDesign", - "InteractiveDesign", - "InterviewDesign", - "LetterDesign", - "LiveBlogDesign", - "MatchReportDesign", - "NewsletterSignupDesign", - "ObituaryDesign", - "PhotoEssayDesign", - "PictureDesign", - "ProfileDesign", - "QuizDesign", - "RecipeDesign", - "ReviewDesign", - "TimelineDesign", - "VideoDesign" - ], - "type": "string" - }, - "FETheme": { - "enum": [ - "CulturePillar", - "Labs", - "LifestylePillar", - "NewsPillar", - "OpinionPillar", - "SpecialReportAltTheme", - "SpecialReportTheme", - "SportPillar" - ], - "type": "string" - }, - "FEDisplay": { - "description": "FEDisplay is the display information passed through from frontend (originating in the capi scala client) and dictates the display style of the content e.g. Immersive\nhttps://github.com/guardian/content-api-scala-client/blob/master/client/src/main/scala/com.gu.contentapi.client/utils/format/Display.scala", - "enum": [ - "ImmersiveDisplay", - "NumberedListDisplay", - "ShowcaseDisplay", - "StandardDisplay" - ], - "type": "string" + "{design:\"ArticleDesign\"|\"PictureDesign\"|\"GalleryDesign\"|\"AudioDesign\"|\"VideoDesign\"|\"CrosswordDesign\"|\"ReviewDesign\"|\"AnalysisDesign\"|\"CommentDesign\"|\"ExplainerDesign\"|\"LetterDesign\"|\"FeatureDesign\"|\"LiveBlogDesign\"|\"DeadBlogDesign\"|\"RecipeDesign\"|\"MatchReportDesign\"|\"InterviewDesign\"|\"EditorialDesign\"|\"QuizDesign\"|\"InteractiveDesign\"|\"PhotoEssayDesign\"|\"ObituaryDesign\"|\"FullPageInteractiveDesign\"|\"NewsletterSignupDesign\"|\"TimelineDesign\"|\"ProfileDesign\";theme:\"NewsPillar\"|\"OpinionPillar\"|\"SportPillar\"|\"CulturePillar\"|\"LifestylePillar\"|\"SpecialReportTheme\"|\"Labs\"|\"SpecialReportAltTheme\";display:\"StandardDisplay\"|\"ImmersiveDisplay\"|\"ShowcaseDisplay\"|\"NumberedListDisplay\";}": { + "description": "FEFormat is the stringified version of Format passed through from Frontend.\nIt gets converted to the `@guardian/libs` format on platform", + "type": "object", + "properties": { + "design": { + "enum": [ + "AnalysisDesign", + "ArticleDesign", + "AudioDesign", + "CommentDesign", + "CrosswordDesign", + "DeadBlogDesign", + "EditorialDesign", + "ExplainerDesign", + "FeatureDesign", + "FullPageInteractiveDesign", + "GalleryDesign", + "InteractiveDesign", + "InterviewDesign", + "LetterDesign", + "LiveBlogDesign", + "MatchReportDesign", + "NewsletterSignupDesign", + "ObituaryDesign", + "PhotoEssayDesign", + "PictureDesign", + "ProfileDesign", + "QuizDesign", + "RecipeDesign", + "ReviewDesign", + "TimelineDesign", + "VideoDesign" + ], + "type": "string" + }, + "theme": { + "enum": [ + "CulturePillar", + "Labs", + "LifestylePillar", + "NewsPillar", + "OpinionPillar", + "SpecialReportAltTheme", + "SpecialReportTheme", + "SportPillar" + ], + "type": "string" + }, + "display": { + "enum": [ + "ImmersiveDisplay", + "NumberedListDisplay", + "ShowcaseDisplay", + "StandardDisplay" + ], + "type": "string" + } + }, + "required": [ + "design", + "display", + "theme" + ] }, "LegacyPillar": { "enum": [ @@ -4907,56 +4895,18 @@ "SharedAdTargeting": { "type": "object" }, - "FETrailType": { + "{url:string;headline:string;format:{design:\"ArticleDesign\"|\"PictureDesign\"|\"GalleryDesign\"|\"AudioDesign\"|\"VideoDesign\"|\"CrosswordDesign\"|\"ReviewDesign\"|\"AnalysisDesign\"|\"CommentDesign\"|\"ExplainerDesign\"|\"LetterDesign\"|\"FeatureDesign\"|\"LiveBlogDesign\"|\"DeadBlogDesign\"|\"RecipeDesign\"|\"MatchReportDesign\"|\"InterviewDesign\"|\"EditorialDesign\"|\"QuizDesign\"|\"InteractiveDesign\"|\"PhotoEssayDesign\"|\"ObituaryDesign\"|\"FullPageInteractiveDesign\"|\"NewsletterSignupDesign\"|\"TimelineDesign\"|\"ProfileDesign\";theme:\"NewsPillar\"|\"OpinionPillar\"|\"SportPillar\"|\"CulturePillar\"|\"LifestylePillar\"|\"SpecialReportTheme\"|\"Labs\"|\"SpecialReportAltTheme\";display:\"StandardDisplay\"|\"ImmersiveDisplay\"|\"ShowcaseDisplay\"|\"NumberedListDisplay\";};webPublicationDate?:string;avatarUrl?:string;mediaDuration?:number;ageWarning?:string;byline?:string;showByline?:boolean;kickerText?:string;shortUrl?:string;commentCount?:number;starRating?:0|5|4|3|2|1;linkText?:string;branding?:{sponsorName:string;logo:{src:string;link:string;label:string;dimensions:{width:number;height:number;};};aboutThisLink:string;brandingType?:{name:\"paid-content\";}|{name:\"foundation\";}|{name:\"sponsored\";};logoForDarkBackground?:{src:string;link:string;label:string;dimensions:{width:number;height:number;};};};isSnap?:boolean;isCrossword?:boolean;snapData?:{embedHtml?:string;embedCss?:string;embedJs?:string;};showQuotedHeadline?:boolean;discussion?:{isCommentable:boolean;isClosedForComments:boolean;discussionId?:string;};mainMedia?:{width:number;height:number;type:\"Video\";id:string;videoId:string;origin:string;title:string;duration:number;expired:boolean;image?:string;}|{width:number;height:number;type:\"LoopVideo\";videoId:string;duration:number;atomId:string;image?:string;}|{type:\"Audio\";duration:string;podcastImage?:{src?:string;altText?:string;};}|{type:\"Gallery\";count:string;};image?:string;designType?:string;pillar?:string;carouselImages?:{[x:string]:string;};isLiveBlog?:boolean;masterImage?:string;}": { "type": "object", "properties": { - "format": { - "description": "FEFormat is the stringified version of Format passed through from Frontend.\nIt gets converted to the `@guardian/libs` format on platform", - "type": "object", - "properties": { - "design": { - "$ref": "#/definitions/FEDesign" - }, - "theme": { - "$ref": "#/definitions/FETheme" - }, - "display": { - "$ref": "#/definitions/FEDisplay" - } - }, - "required": [ - "design", - "display", - "theme" - ] - }, - "designType": { - "type": "string" - }, - "pillar": { - "type": "string" - }, - "carouselImages": { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - "isLiveBlog": { - "type": "boolean" - }, - "masterImage": { - "type": "string" - }, - "image": { - "type": "string" - }, "url": { "type": "string" }, "headline": { "type": "string" }, + "format": { + "$ref": "#/definitions/{design:\"ArticleDesign\"|\"PictureDesign\"|\"GalleryDesign\"|\"AudioDesign\"|\"VideoDesign\"|\"CrosswordDesign\"|\"ReviewDesign\"|\"AnalysisDesign\"|\"CommentDesign\"|\"ExplainerDesign\"|\"LetterDesign\"|\"FeatureDesign\"|\"LiveBlogDesign\"|\"DeadBlogDesign\"|\"RecipeDesign\"|\"MatchReportDesign\"|\"InterviewDesign\"|\"EditorialDesign\"|\"QuizDesign\"|\"InteractiveDesign\"|\"PhotoEssayDesign\"|\"ObituaryDesign\"|\"FullPageInteractiveDesign\"|\"NewsletterSignupDesign\"|\"TimelineDesign\"|\"ProfileDesign\";theme:\"NewsPillar\"|\"OpinionPillar\"|\"SportPillar\"|\"CulturePillar\"|\"LifestylePillar\"|\"SpecialReportTheme\"|\"Labs\"|\"SpecialReportAltTheme\";display:\"StandardDisplay\"|\"ImmersiveDisplay\"|\"ShowcaseDisplay\"|\"NumberedListDisplay\";}" + }, "webPublicationDate": { "type": "string" }, @@ -4985,13 +4935,21 @@ "type": "number" }, "starRating": { - "$ref": "#/definitions/StarRating" + "enum": [ + 0, + 1, + 2, + 3, + 4, + 5 + ], + "type": "number" }, "linkText": { "type": "string" }, "branding": { - "$ref": "#/definitions/Branding" + "$ref": "#/definitions/{sponsorName:string;logo:{src:string;link:string;label:string;dimensions:{width:number;height:number;};};aboutThisLink:string;brandingType?:{name:\"paid-content\";}|{name:\"foundation\";}|{name:\"sponsored\";};logoForDarkBackground?:{src:string;link:string;label:string;dimensions:{width:number;height:number;};};}" }, "isSnap": { "type": "boolean" @@ -5000,42 +4958,47 @@ "type": "boolean" }, "snapData": { - "type": "object", - "properties": { - "embedHtml": { - "type": "string" - }, - "embedCss": { - "type": "string" - }, - "embedJs": { - "type": "string" - } - } + "$ref": "#/definitions/{embedHtml?:string;embedCss?:string;embedJs?:string;}" }, "showQuotedHeadline": { "type": "boolean" }, "discussion": { - "type": "object", - "properties": { - "isCommentable": { - "type": "boolean" + "$ref": "#/definitions/{isCommentable:boolean;isClosedForComments:boolean;discussionId?:string;}" + }, + "mainMedia": { + "anyOf": [ + { + "$ref": "#/definitions/{width:number;height:number;type:\"Video\";id:string;videoId:string;origin:string;title:string;duration:number;expired:boolean;image?:string;}" }, - "isClosedForComments": { - "type": "boolean" + { + "$ref": "#/definitions/{width:number;height:number;type:\"LoopVideo\";videoId:string;duration:number;atomId:string;image?:string;}" }, - "discussionId": { - "type": "string" + { + "$ref": "#/definitions/{type:\"Audio\";duration:string;podcastImage?:{src?:string;altText?:string;};}" + }, + { + "$ref": "#/definitions/{type:\"Gallery\";count:string;}" } - }, - "required": [ - "isClosedForComments", - "isCommentable" ] }, - "mainMedia": { - "$ref": "#/definitions/MainMedia" + "image": { + "type": "string" + }, + "designType": { + "type": "string" + }, + "pillar": { + "type": "string" + }, + "carouselImages": { + "$ref": "#/definitions/{[x:string]:string;}" + }, + "isLiveBlog": { + "type": "boolean" + }, + "masterImage": { + "type": "string" } }, "required": [ @@ -5044,87 +5007,33 @@ "url" ] }, - "Branding": { + "{sponsorName:string;logo:{src:string;link:string;label:string;dimensions:{width:number;height:number;};};aboutThisLink:string;brandingType?:{name:\"paid-content\";}|{name:\"foundation\";}|{name:\"sponsored\";};logoForDarkBackground?:{src:string;link:string;label:string;dimensions:{width:number;height:number;};};}": { "type": "object", "properties": { - "brandingType": { - "$ref": "#/definitions/BrandingType" - }, "sponsorName": { "type": "string" }, "logo": { - "type": "object", - "properties": { - "src": { - "type": "string" - }, - "link": { - "type": "string" - }, - "label": { - "type": "string" - }, - "dimensions": { - "type": "object", - "properties": { - "width": { - "type": "number" - }, - "height": { - "type": "number" - } - }, - "required": [ - "height", - "width" - ] - } - }, - "required": [ - "dimensions", - "label", - "link", - "src" - ] + "$ref": "#/definitions/{src:string;link:string;label:string;dimensions:{width:number;height:number;};}" }, "aboutThisLink": { "type": "string" }, - "logoForDarkBackground": { - "type": "object", - "properties": { - "src": { - "type": "string" - }, - "link": { - "type": "string" + "brandingType": { + "anyOf": [ + { + "$ref": "#/definitions/{name:\"paid-content\";}" }, - "label": { - "type": "string" + { + "$ref": "#/definitions/{name:\"foundation\";}" }, - "dimensions": { - "type": "object", - "properties": { - "width": { - "type": "number" - }, - "height": { - "type": "number" - } - }, - "required": [ - "height", - "width" - ] + { + "$ref": "#/definitions/{name:\"sponsored\";}" } - }, - "required": [ - "dimensions", - "label", - "link", - "src" ] + }, + "logoForDarkBackground": { + "$ref": "#/definitions/{src:string;link:string;label:string;dimensions:{width:number;height:number;};}" } }, "required": [ @@ -5133,273 +5042,243 @@ "sponsorName" ] }, - "BrandingType": { - "anyOf": [ - { - "type": "object", - "properties": { - "name": { - "type": "string", - "const": "paid-content" - } - }, - "required": [ - "name" - ] + "{src:string;link:string;label:string;dimensions:{width:number;height:number;};}": { + "type": "object", + "properties": { + "src": { + "type": "string" }, - { - "type": "object", - "properties": { - "name": { - "type": "string", - "const": "foundation" - } - }, - "required": [ - "name" - ] + "link": { + "type": "string" }, - { - "type": "object", - "properties": { - "name": { - "type": "string", - "const": "sponsored" - } - }, - "required": [ - "name" - ] + "label": { + "type": "string" + }, + "dimensions": { + "$ref": "#/definitions/{width:number;height:number;}" } + }, + "required": [ + "dimensions", + "label", + "link", + "src" ] }, - "MainMedia": { - "anyOf": [ - { - "$ref": "#/definitions/Video", - "description": "For displaying embedded, playable videos directly in cards" + "{width:number;height:number;}": { + "type": "object", + "properties": { + "width": { + "type": "number" }, - { - "$ref": "#/definitions/LoopVideo" + "height": { + "type": "number" + } + }, + "required": [ + "height", + "width" + ] + }, + "{name:\"paid-content\";}": { + "type": "object", + "properties": { + "name": { + "type": "string", + "const": "paid-content" + } + }, + "required": [ + "name" + ] + }, + "{name:\"foundation\";}": { + "type": "object", + "properties": { + "name": { + "type": "string", + "const": "foundation" + } + }, + "required": [ + "name" + ] + }, + "{name:\"sponsored\";}": { + "type": "object", + "properties": { + "name": { + "type": "string", + "const": "sponsored" + } + }, + "required": [ + "name" + ] + }, + "{embedHtml?:string;embedCss?:string;embedJs?:string;}": { + "type": "object", + "properties": { + "embedHtml": { + "type": "string" }, - { - "$ref": "#/definitions/Audio" + "embedCss": { + "type": "string" }, - { - "$ref": "#/definitions/Gallery" + "embedJs": { + "type": "string" + } + } + }, + "{isCommentable:boolean;isClosedForComments:boolean;discussionId?:string;}": { + "type": "object", + "properties": { + "isCommentable": { + "type": "boolean" + }, + "isClosedForComments": { + "type": "boolean" + }, + "discussionId": { + "type": "string" } + }, + "required": [ + "isClosedForComments", + "isCommentable" ] }, - "Video": { - "description": "For displaying embedded, playable videos directly in cards", - "allOf": [ - { - "type": "object", - "properties": { - "type": { - "enum": [ - "Audio", - "Gallery", - "LoopVideo", - "Video" - ], - "type": "string" - } - }, - "required": [ - "type" - ] + "{width:number;height:number;type:\"Video\";id:string;videoId:string;origin:string;title:string;duration:number;expired:boolean;image?:string;}": { + "type": "object", + "properties": { + "width": { + "type": "number" }, - { - "type": "object", - "properties": { - "type": { - "type": "string", - "const": "Video" - }, - "id": { - "type": "string" - }, - "videoId": { - "type": "string" - }, - "height": { - "type": "number" - }, - "width": { - "type": "number" - }, - "origin": { - "type": "string" - }, - "title": { - "type": "string" - }, - "duration": { - "type": "number" - }, - "expired": { - "type": "boolean" - }, - "image": { - "type": "string" - } - }, - "required": [ - "duration", - "expired", - "height", - "id", - "origin", - "title", - "type", - "videoId", - "width" - ] + "height": { + "type": "number" + }, + "type": { + "type": "string", + "const": "Video" + }, + "id": { + "type": "string" + }, + "videoId": { + "type": "string" + }, + "origin": { + "type": "string" + }, + "title": { + "type": "string" + }, + "duration": { + "type": "number" + }, + "expired": { + "type": "boolean" + }, + "image": { + "type": "string" } + }, + "required": [ + "duration", + "expired", + "height", + "id", + "origin", + "title", + "type", + "videoId", + "width" ] }, - "LoopVideo": { - "allOf": [ - { - "type": "object", - "properties": { - "type": { - "enum": [ - "Audio", - "Gallery", - "LoopVideo", - "Video" - ], - "type": "string" - } - }, - "required": [ - "type" - ] + "{width:number;height:number;type:\"LoopVideo\";videoId:string;duration:number;atomId:string;image?:string;}": { + "type": "object", + "properties": { + "width": { + "type": "number" }, - { - "type": "object", - "properties": { - "type": { - "type": "string", - "const": "LoopVideo" - }, - "atomId": { - "type": "string" - }, - "videoId": { - "type": "string" - }, - "height": { - "type": "number" - }, - "width": { - "type": "number" - }, - "duration": { - "type": "number" - }, - "image": { - "type": "string" - } - }, - "required": [ - "atomId", - "duration", - "height", - "type", - "videoId", - "width" - ] + "height": { + "type": "number" + }, + "type": { + "type": "string", + "const": "LoopVideo" + }, + "videoId": { + "type": "string" + }, + "duration": { + "type": "number" + }, + "atomId": { + "type": "string" + }, + "image": { + "type": "string" } + }, + "required": [ + "atomId", + "duration", + "height", + "type", + "videoId", + "width" ] }, - "Audio": { - "allOf": [ - { - "type": "object", - "properties": { - "type": { - "enum": [ - "Audio", - "Gallery", - "LoopVideo", - "Video" - ], - "type": "string" - } - }, - "required": [ - "type" - ] + "{type:\"Audio\";duration:string;podcastImage?:{src?:string;altText?:string;};}": { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "Audio" }, - { - "type": "object", - "properties": { - "type": { - "type": "string", - "const": "Audio" - }, - "duration": { - "type": "string" - }, - "podcastImage": { - "type": "object", - "properties": { - "src": { - "type": "string" - }, - "altText": { - "type": "string" - } - } - } - }, - "required": [ - "duration", - "type" - ] + "duration": { + "type": "string" + }, + "podcastImage": { + "$ref": "#/definitions/{src?:string;altText?:string;}" } + }, + "required": [ + "duration", + "type" ] }, - "Gallery": { - "allOf": [ - { - "type": "object", - "properties": { - "type": { - "enum": [ - "Audio", - "Gallery", - "LoopVideo", - "Video" - ], - "type": "string" - } - }, - "required": [ - "type" - ] + "{src?:string;altText?:string;}": { + "type": "object", + "properties": { + "src": { + "type": "string" }, - { - "type": "object", - "properties": { - "type": { - "type": "string", - "const": "Gallery" - }, - "count": { - "type": "string" - } - }, - "required": [ - "count", - "type" - ] + "altText": { + "type": "string" } + } + }, + "{type:\"Gallery\";count:string;}": { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "Gallery" + }, + "count": { + "type": "string" + } + }, + "required": [ + "count", + "type" ] }, + "{[x:string]:string;}": { + "type": "object" + }, "OnwardsSource": { "enum": [ "curated-content", @@ -5451,7 +5330,7 @@ } }, "branding": { - "$ref": "#/definitions/Branding" + "$ref": "#/definitions/{sponsorName:string;logo:{src:string;link:string;label:string;dimensions:{width:number;height:number;};};aboutThisLink:string;brandingType?:{name:\"paid-content\";}|{name:\"foundation\";}|{name:\"sponsored\";};logoForDarkBackground?:{src:string;link:string;label:string;dimensions:{width:number;height:number;};};}" } }, "required": [ diff --git a/dotcom-rendering/src/frontend/schemas/feCricketMatchPage.json b/dotcom-rendering/src/frontend/schemas/feCricketMatchPage.json index e477fa59159..d4c17807201 100644 --- a/dotcom-rendering/src/frontend/schemas/feCricketMatchPage.json +++ b/dotcom-rendering/src/frontend/schemas/feCricketMatchPage.json @@ -497,6 +497,9 @@ "adUnit": { "type": "string" }, + "pillar": { + "type": "string" + }, "avatarApiUrl": { "type": "string" }, @@ -598,9 +601,6 @@ "assetsPath": { "type": "string" }, - "pillar": { - "type": "string" - }, "commercialBundleUrl": { "type": "string" }, diff --git a/dotcom-rendering/src/frontend/schemas/feFootballMatchListPage.json b/dotcom-rendering/src/frontend/schemas/feFootballMatchListPage.json index 725725e1b0b..0fa9b067bc7 100644 --- a/dotcom-rendering/src/frontend/schemas/feFootballMatchListPage.json +++ b/dotcom-rendering/src/frontend/schemas/feFootballMatchListPage.json @@ -344,6 +344,9 @@ "adUnit": { "type": "string" }, + "pillar": { + "type": "string" + }, "avatarApiUrl": { "type": "string" }, @@ -445,9 +448,6 @@ "assetsPath": { "type": "string" }, - "pillar": { - "type": "string" - }, "commercialBundleUrl": { "type": "string" }, diff --git a/dotcom-rendering/src/frontend/schemas/feFootballMatchPage.json b/dotcom-rendering/src/frontend/schemas/feFootballMatchPage.json index 205fe136e3e..1235c31aecd 100644 --- a/dotcom-rendering/src/frontend/schemas/feFootballMatchPage.json +++ b/dotcom-rendering/src/frontend/schemas/feFootballMatchPage.json @@ -514,6 +514,9 @@ "adUnit": { "type": "string" }, + "pillar": { + "type": "string" + }, "avatarApiUrl": { "type": "string" }, @@ -615,9 +618,6 @@ "assetsPath": { "type": "string" }, - "pillar": { - "type": "string" - }, "commercialBundleUrl": { "type": "string" }, diff --git a/dotcom-rendering/src/frontend/schemas/feFootballTablesPage.json b/dotcom-rendering/src/frontend/schemas/feFootballTablesPage.json index 5c2716d518e..b01ccfcb5ee 100644 --- a/dotcom-rendering/src/frontend/schemas/feFootballTablesPage.json +++ b/dotcom-rendering/src/frontend/schemas/feFootballTablesPage.json @@ -553,6 +553,9 @@ "adUnit": { "type": "string" }, + "pillar": { + "type": "string" + }, "avatarApiUrl": { "type": "string" }, @@ -654,9 +657,6 @@ "assetsPath": { "type": "string" }, - "pillar": { - "type": "string" - }, "commercialBundleUrl": { "type": "string" }, diff --git a/dotcom-rendering/src/frontend/schemas/feFront.json b/dotcom-rendering/src/frontend/schemas/feFront.json index 1c7d182ddf1..1f182e1863a 100644 --- a/dotcom-rendering/src/frontend/schemas/feFront.json +++ b/dotcom-rendering/src/frontend/schemas/feFront.json @@ -361,13 +361,13 @@ "mostViewed": { "type": "array", "items": { - "$ref": "#/definitions/FETrailType" + "$ref": "#/definitions/{url:string;headline:string;format:{design:\"ArticleDesign\"|\"PictureDesign\"|\"GalleryDesign\"|\"AudioDesign\"|\"VideoDesign\"|\"CrosswordDesign\"|\"ReviewDesign\"|\"AnalysisDesign\"|\"CommentDesign\"|\"ExplainerDesign\"|\"LetterDesign\"|\"FeatureDesign\"|\"LiveBlogDesign\"|\"DeadBlogDesign\"|\"RecipeDesign\"|\"MatchReportDesign\"|\"InterviewDesign\"|\"EditorialDesign\"|\"QuizDesign\"|\"InteractiveDesign\"|\"PhotoEssayDesign\"|\"ObituaryDesign\"|\"FullPageInteractiveDesign\"|\"NewsletterSignupDesign\"|\"TimelineDesign\"|\"ProfileDesign\";theme:\"NewsPillar\"|\"OpinionPillar\"|\"SportPillar\"|\"CulturePillar\"|\"LifestylePillar\"|\"SpecialReportTheme\"|\"Labs\"|\"SpecialReportAltTheme\";display:\"StandardDisplay\"|\"ImmersiveDisplay\"|\"ShowcaseDisplay\"|\"NumberedListDisplay\";};webPublicationDate?:string;avatarUrl?:string;mediaDuration?:number;ageWarning?:string;byline?:string;showByline?:boolean;kickerText?:string;shortUrl?:string;commentCount?:number;starRating?:0|5|4|3|2|1;linkText?:string;branding?:{sponsorName:string;logo:{src:string;link:string;label:string;dimensions:{width:number;height:number;};};aboutThisLink:string;brandingType?:{name:\"paid-content\";}|{name:\"foundation\";}|{name:\"sponsored\";};logoForDarkBackground?:{src:string;link:string;label:string;dimensions:{width:number;height:number;};};};isSnap?:boolean;isCrossword?:boolean;snapData?:{embedHtml?:string;embedCss?:string;embedJs?:string;};showQuotedHeadline?:boolean;discussion?:{isCommentable:boolean;isClosedForComments:boolean;discussionId?:string;};mainMedia?:{width:number;height:number;type:\"Video\";id:string;videoId:string;origin:string;title:string;duration:number;expired:boolean;image?:string;}|{width:number;height:number;type:\"LoopVideo\";videoId:string;duration:number;atomId:string;image?:string;}|{type:\"Audio\";duration:string;podcastImage?:{src?:string;altText?:string;};}|{type:\"Gallery\";count:string;};image?:string;designType?:string;pillar?:string;carouselImages?:{[x:string]:string;};isLiveBlog?:boolean;masterImage?:string;}" } }, "deeplyRead": { "type": "array", "items": { - "$ref": "#/definitions/FETrailType" + "$ref": "#/definitions/{url:string;headline:string;format:{design:\"ArticleDesign\"|\"PictureDesign\"|\"GalleryDesign\"|\"AudioDesign\"|\"VideoDesign\"|\"CrosswordDesign\"|\"ReviewDesign\"|\"AnalysisDesign\"|\"CommentDesign\"|\"ExplainerDesign\"|\"LetterDesign\"|\"FeatureDesign\"|\"LiveBlogDesign\"|\"DeadBlogDesign\"|\"RecipeDesign\"|\"MatchReportDesign\"|\"InterviewDesign\"|\"EditorialDesign\"|\"QuizDesign\"|\"InteractiveDesign\"|\"PhotoEssayDesign\"|\"ObituaryDesign\"|\"FullPageInteractiveDesign\"|\"NewsletterSignupDesign\"|\"TimelineDesign\"|\"ProfileDesign\";theme:\"NewsPillar\"|\"OpinionPillar\"|\"SportPillar\"|\"CulturePillar\"|\"LifestylePillar\"|\"SpecialReportTheme\"|\"Labs\"|\"SpecialReportAltTheme\";display:\"StandardDisplay\"|\"ImmersiveDisplay\"|\"ShowcaseDisplay\"|\"NumberedListDisplay\";};webPublicationDate?:string;avatarUrl?:string;mediaDuration?:number;ageWarning?:string;byline?:string;showByline?:boolean;kickerText?:string;shortUrl?:string;commentCount?:number;starRating?:0|5|4|3|2|1;linkText?:string;branding?:{sponsorName:string;logo:{src:string;link:string;label:string;dimensions:{width:number;height:number;};};aboutThisLink:string;brandingType?:{name:\"paid-content\";}|{name:\"foundation\";}|{name:\"sponsored\";};logoForDarkBackground?:{src:string;link:string;label:string;dimensions:{width:number;height:number;};};};isSnap?:boolean;isCrossword?:boolean;snapData?:{embedHtml?:string;embedCss?:string;embedJs?:string;};showQuotedHeadline?:boolean;discussion?:{isCommentable:boolean;isClosedForComments:boolean;discussionId?:string;};mainMedia?:{width:number;height:number;type:\"Video\";id:string;videoId:string;origin:string;title:string;duration:number;expired:boolean;image?:string;}|{width:number;height:number;type:\"LoopVideo\";videoId:string;duration:number;atomId:string;image?:string;}|{type:\"Audio\";duration:string;podcastImage?:{src?:string;altText?:string;};}|{type:\"Gallery\";count:string;};image?:string;designType?:string;pillar?:string;carouselImages?:{[x:string]:string;};isLiveBlog?:boolean;masterImage?:string;}" } }, "contributionsServiceUrl": { @@ -633,24 +633,7 @@ ] }, "format": { - "description": "FEFormat is the stringified version of Format passed through from Frontend.\nIt gets converted to the `@guardian/libs` format on platform", - "type": "object", - "properties": { - "design": { - "$ref": "#/definitions/FEDesign" - }, - "theme": { - "$ref": "#/definitions/FETheme" - }, - "display": { - "$ref": "#/definitions/FEDisplay" - } - }, - "required": [ - "design", - "display", - "theme" - ] + "$ref": "#/definitions/{design:\"ArticleDesign\"|\"PictureDesign\"|\"GalleryDesign\"|\"AudioDesign\"|\"VideoDesign\"|\"CrosswordDesign\"|\"ReviewDesign\"|\"AnalysisDesign\"|\"CommentDesign\"|\"ExplainerDesign\"|\"LetterDesign\"|\"FeatureDesign\"|\"LiveBlogDesign\"|\"DeadBlogDesign\"|\"RecipeDesign\"|\"MatchReportDesign\"|\"InterviewDesign\"|\"EditorialDesign\"|\"QuizDesign\"|\"InteractiveDesign\"|\"PhotoEssayDesign\"|\"ObituaryDesign\"|\"FullPageInteractiveDesign\"|\"NewsletterSignupDesign\"|\"TimelineDesign\"|\"ProfileDesign\";theme:\"NewsPillar\"|\"OpinionPillar\"|\"SportPillar\"|\"CulturePillar\"|\"LifestylePillar\"|\"SpecialReportTheme\"|\"Labs\"|\"SpecialReportAltTheme\";display:\"StandardDisplay\"|\"ImmersiveDisplay\"|\"ShowcaseDisplay\"|\"NumberedListDisplay\";}" } }, "required": [ @@ -1033,7 +1016,15 @@ "type": "string" }, "starRating": { - "$ref": "#/definitions/StarRating" + "enum": [ + 0, + 1, + 2, + 3, + 4, + 5 + ], + "type": "number" }, "shortUrlPath": { "type": "string" @@ -1114,24 +1105,7 @@ ] }, "format": { - "description": "FEFormat is the stringified version of Format passed through from Frontend.\nIt gets converted to the `@guardian/libs` format on platform", - "type": "object", - "properties": { - "design": { - "$ref": "#/definitions/FEDesign" - }, - "theme": { - "$ref": "#/definitions/FETheme" - }, - "display": { - "$ref": "#/definitions/FEDisplay" - } - }, - "required": [ - "design", - "display", - "theme" - ] + "$ref": "#/definitions/{design:\"ArticleDesign\"|\"PictureDesign\"|\"GalleryDesign\"|\"AudioDesign\"|\"VideoDesign\"|\"CrosswordDesign\"|\"ReviewDesign\"|\"AnalysisDesign\"|\"CommentDesign\"|\"ExplainerDesign\"|\"LetterDesign\"|\"FeatureDesign\"|\"LiveBlogDesign\"|\"DeadBlogDesign\"|\"RecipeDesign\"|\"MatchReportDesign\"|\"InterviewDesign\"|\"EditorialDesign\"|\"QuizDesign\"|\"InteractiveDesign\"|\"PhotoEssayDesign\"|\"ObituaryDesign\"|\"FullPageInteractiveDesign\"|\"NewsletterSignupDesign\"|\"TimelineDesign\"|\"ProfileDesign\";theme:\"NewsPillar\"|\"OpinionPillar\"|\"SportPillar\"|\"CulturePillar\"|\"LifestylePillar\"|\"SpecialReportTheme\"|\"Labs\"|\"SpecialReportAltTheme\";display:\"StandardDisplay\"|\"ImmersiveDisplay\"|\"ShowcaseDisplay\"|\"NumberedListDisplay\";}" }, "enriched": { "type": "object", @@ -1206,24 +1180,7 @@ ] }, "format": { - "description": "FEFormat is the stringified version of Format passed through from Frontend.\nIt gets converted to the `@guardian/libs` format on platform", - "type": "object", - "properties": { - "design": { - "$ref": "#/definitions/FEDesign" - }, - "theme": { - "$ref": "#/definitions/FETheme" - }, - "display": { - "$ref": "#/definitions/FEDisplay" - } - }, - "required": [ - "design", - "display", - "theme" - ] + "$ref": "#/definitions/{design:\"ArticleDesign\"|\"PictureDesign\"|\"GalleryDesign\"|\"AudioDesign\"|\"VideoDesign\"|\"CrosswordDesign\"|\"ReviewDesign\"|\"AnalysisDesign\"|\"CommentDesign\"|\"ExplainerDesign\"|\"LetterDesign\"|\"FeatureDesign\"|\"LiveBlogDesign\"|\"DeadBlogDesign\"|\"RecipeDesign\"|\"MatchReportDesign\"|\"InterviewDesign\"|\"EditorialDesign\"|\"QuizDesign\"|\"InteractiveDesign\"|\"PhotoEssayDesign\"|\"ObituaryDesign\"|\"FullPageInteractiveDesign\"|\"NewsletterSignupDesign\"|\"TimelineDesign\"|\"ProfileDesign\";theme:\"NewsPillar\"|\"OpinionPillar\"|\"SportPillar\"|\"CulturePillar\"|\"LifestylePillar\"|\"SpecialReportTheme\"|\"Labs\"|\"SpecialReportAltTheme\";display:\"StandardDisplay\"|\"ImmersiveDisplay\"|\"ShowcaseDisplay\"|\"NumberedListDisplay\";}" } }, "required": [ @@ -1414,24 +1371,7 @@ ] }, "format": { - "description": "FEFormat is the stringified version of Format passed through from Frontend.\nIt gets converted to the `@guardian/libs` format on platform", - "type": "object", - "properties": { - "design": { - "$ref": "#/definitions/FEDesign" - }, - "theme": { - "$ref": "#/definitions/FETheme" - }, - "display": { - "$ref": "#/definitions/FEDisplay" - } - }, - "required": [ - "design", - "display", - "theme" - ] + "$ref": "#/definitions/{design:\"ArticleDesign\"|\"PictureDesign\"|\"GalleryDesign\"|\"AudioDesign\"|\"VideoDesign\"|\"CrosswordDesign\"|\"ReviewDesign\"|\"AnalysisDesign\"|\"CommentDesign\"|\"ExplainerDesign\"|\"LetterDesign\"|\"FeatureDesign\"|\"LiveBlogDesign\"|\"DeadBlogDesign\"|\"RecipeDesign\"|\"MatchReportDesign\"|\"InterviewDesign\"|\"EditorialDesign\"|\"QuizDesign\"|\"InteractiveDesign\"|\"PhotoEssayDesign\"|\"ObituaryDesign\"|\"FullPageInteractiveDesign\"|\"NewsletterSignupDesign\"|\"TimelineDesign\"|\"ProfileDesign\";theme:\"NewsPillar\"|\"OpinionPillar\"|\"SportPillar\"|\"CulturePillar\"|\"LifestylePillar\"|\"SpecialReportTheme\"|\"Labs\"|\"SpecialReportAltTheme\";display:\"StandardDisplay\"|\"ImmersiveDisplay\"|\"ShowcaseDisplay\"|\"NumberedListDisplay\";}" } }, "required": [ @@ -1814,7 +1754,15 @@ "type": "string" }, "starRating": { - "$ref": "#/definitions/StarRating" + "enum": [ + 0, + 1, + 2, + 3, + 4, + 5 + ], + "type": "number" }, "shortUrlPath": { "type": "string" @@ -1895,24 +1843,7 @@ ] }, "format": { - "description": "FEFormat is the stringified version of Format passed through from Frontend.\nIt gets converted to the `@guardian/libs` format on platform", - "type": "object", - "properties": { - "design": { - "$ref": "#/definitions/FEDesign" - }, - "theme": { - "$ref": "#/definitions/FETheme" - }, - "display": { - "$ref": "#/definitions/FEDisplay" - } - }, - "required": [ - "design", - "display", - "theme" - ] + "$ref": "#/definitions/{design:\"ArticleDesign\"|\"PictureDesign\"|\"GalleryDesign\"|\"AudioDesign\"|\"VideoDesign\"|\"CrosswordDesign\"|\"ReviewDesign\"|\"AnalysisDesign\"|\"CommentDesign\"|\"ExplainerDesign\"|\"LetterDesign\"|\"FeatureDesign\"|\"LiveBlogDesign\"|\"DeadBlogDesign\"|\"RecipeDesign\"|\"MatchReportDesign\"|\"InterviewDesign\"|\"EditorialDesign\"|\"QuizDesign\"|\"InteractiveDesign\"|\"PhotoEssayDesign\"|\"ObituaryDesign\"|\"FullPageInteractiveDesign\"|\"NewsletterSignupDesign\"|\"TimelineDesign\"|\"ProfileDesign\";theme:\"NewsPillar\"|\"OpinionPillar\"|\"SportPillar\"|\"CulturePillar\"|\"LifestylePillar\"|\"SpecialReportTheme\"|\"Labs\"|\"SpecialReportAltTheme\";display:\"StandardDisplay\"|\"ImmersiveDisplay\"|\"ShowcaseDisplay\"|\"NumberedListDisplay\";}" }, "enriched": { "type": "object", @@ -1987,24 +1918,7 @@ ] }, "format": { - "description": "FEFormat is the stringified version of Format passed through from Frontend.\nIt gets converted to the `@guardian/libs` format on platform", - "type": "object", - "properties": { - "design": { - "$ref": "#/definitions/FEDesign" - }, - "theme": { - "$ref": "#/definitions/FETheme" - }, - "display": { - "$ref": "#/definitions/FEDisplay" - } - }, - "required": [ - "design", - "display", - "theme" - ] + "$ref": "#/definitions/{design:\"ArticleDesign\"|\"PictureDesign\"|\"GalleryDesign\"|\"AudioDesign\"|\"VideoDesign\"|\"CrosswordDesign\"|\"ReviewDesign\"|\"AnalysisDesign\"|\"CommentDesign\"|\"ExplainerDesign\"|\"LetterDesign\"|\"FeatureDesign\"|\"LiveBlogDesign\"|\"DeadBlogDesign\"|\"RecipeDesign\"|\"MatchReportDesign\"|\"InterviewDesign\"|\"EditorialDesign\"|\"QuizDesign\"|\"InteractiveDesign\"|\"PhotoEssayDesign\"|\"ObituaryDesign\"|\"FullPageInteractiveDesign\"|\"NewsletterSignupDesign\"|\"TimelineDesign\"|\"ProfileDesign\";theme:\"NewsPillar\"|\"OpinionPillar\"|\"SportPillar\"|\"CulturePillar\"|\"LifestylePillar\"|\"SpecialReportTheme\"|\"Labs\"|\"SpecialReportAltTheme\";display:\"StandardDisplay\"|\"ImmersiveDisplay\"|\"ShowcaseDisplay\"|\"NumberedListDisplay\";}" } }, "required": [ @@ -2195,24 +2109,7 @@ ] }, "format": { - "description": "FEFormat is the stringified version of Format passed through from Frontend.\nIt gets converted to the `@guardian/libs` format on platform", - "type": "object", - "properties": { - "design": { - "$ref": "#/definitions/FEDesign" - }, - "theme": { - "$ref": "#/definitions/FETheme" - }, - "display": { - "$ref": "#/definitions/FEDisplay" - } - }, - "required": [ - "design", - "display", - "theme" - ] + "$ref": "#/definitions/{design:\"ArticleDesign\"|\"PictureDesign\"|\"GalleryDesign\"|\"AudioDesign\"|\"VideoDesign\"|\"CrosswordDesign\"|\"ReviewDesign\"|\"AnalysisDesign\"|\"CommentDesign\"|\"ExplainerDesign\"|\"LetterDesign\"|\"FeatureDesign\"|\"LiveBlogDesign\"|\"DeadBlogDesign\"|\"RecipeDesign\"|\"MatchReportDesign\"|\"InterviewDesign\"|\"EditorialDesign\"|\"QuizDesign\"|\"InteractiveDesign\"|\"PhotoEssayDesign\"|\"ObituaryDesign\"|\"FullPageInteractiveDesign\"|\"NewsletterSignupDesign\"|\"TimelineDesign\"|\"ProfileDesign\";theme:\"NewsPillar\"|\"OpinionPillar\"|\"SportPillar\"|\"CulturePillar\"|\"LifestylePillar\"|\"SpecialReportTheme\"|\"Labs\"|\"SpecialReportAltTheme\";display:\"StandardDisplay\"|\"ImmersiveDisplay\"|\"ShowcaseDisplay\"|\"NumberedListDisplay\";}" } }, "required": [ @@ -2595,7 +2492,15 @@ "type": "string" }, "starRating": { - "$ref": "#/definitions/StarRating" + "enum": [ + 0, + 1, + 2, + 3, + 4, + 5 + ], + "type": "number" }, "shortUrlPath": { "type": "string" @@ -2676,24 +2581,7 @@ ] }, "format": { - "description": "FEFormat is the stringified version of Format passed through from Frontend.\nIt gets converted to the `@guardian/libs` format on platform", - "type": "object", - "properties": { - "design": { - "$ref": "#/definitions/FEDesign" - }, - "theme": { - "$ref": "#/definitions/FETheme" - }, - "display": { - "$ref": "#/definitions/FEDisplay" - } - }, - "required": [ - "design", - "display", - "theme" - ] + "$ref": "#/definitions/{design:\"ArticleDesign\"|\"PictureDesign\"|\"GalleryDesign\"|\"AudioDesign\"|\"VideoDesign\"|\"CrosswordDesign\"|\"ReviewDesign\"|\"AnalysisDesign\"|\"CommentDesign\"|\"ExplainerDesign\"|\"LetterDesign\"|\"FeatureDesign\"|\"LiveBlogDesign\"|\"DeadBlogDesign\"|\"RecipeDesign\"|\"MatchReportDesign\"|\"InterviewDesign\"|\"EditorialDesign\"|\"QuizDesign\"|\"InteractiveDesign\"|\"PhotoEssayDesign\"|\"ObituaryDesign\"|\"FullPageInteractiveDesign\"|\"NewsletterSignupDesign\"|\"TimelineDesign\"|\"ProfileDesign\";theme:\"NewsPillar\"|\"OpinionPillar\"|\"SportPillar\"|\"CulturePillar\"|\"LifestylePillar\"|\"SpecialReportTheme\"|\"Labs\"|\"SpecialReportAltTheme\";display:\"StandardDisplay\"|\"ImmersiveDisplay\"|\"ShowcaseDisplay\"|\"NumberedListDisplay\";}" }, "enriched": { "type": "object", @@ -2768,24 +2656,7 @@ ] }, "format": { - "description": "FEFormat is the stringified version of Format passed through from Frontend.\nIt gets converted to the `@guardian/libs` format on platform", - "type": "object", - "properties": { - "design": { - "$ref": "#/definitions/FEDesign" - }, - "theme": { - "$ref": "#/definitions/FETheme" - }, - "display": { - "$ref": "#/definitions/FEDisplay" - } - }, - "required": [ - "design", - "display", - "theme" - ] + "$ref": "#/definitions/{design:\"ArticleDesign\"|\"PictureDesign\"|\"GalleryDesign\"|\"AudioDesign\"|\"VideoDesign\"|\"CrosswordDesign\"|\"ReviewDesign\"|\"AnalysisDesign\"|\"CommentDesign\"|\"ExplainerDesign\"|\"LetterDesign\"|\"FeatureDesign\"|\"LiveBlogDesign\"|\"DeadBlogDesign\"|\"RecipeDesign\"|\"MatchReportDesign\"|\"InterviewDesign\"|\"EditorialDesign\"|\"QuizDesign\"|\"InteractiveDesign\"|\"PhotoEssayDesign\"|\"ObituaryDesign\"|\"FullPageInteractiveDesign\"|\"NewsletterSignupDesign\"|\"TimelineDesign\"|\"ProfileDesign\";theme:\"NewsPillar\"|\"OpinionPillar\"|\"SportPillar\"|\"CulturePillar\"|\"LifestylePillar\"|\"SpecialReportTheme\"|\"Labs\"|\"SpecialReportAltTheme\";display:\"StandardDisplay\"|\"ImmersiveDisplay\"|\"ShowcaseDisplay\"|\"NumberedListDisplay\";}" } }, "required": [ @@ -2984,7 +2855,7 @@ ] }, "branding": { - "$ref": "#/definitions/Branding" + "$ref": "#/definitions/{sponsorName:string;logo:{src:string;link:string;label:string;dimensions:{width:number;height:number;};};aboutThisLink:string;brandingType?:{name:\"paid-content\";}|{name:\"foundation\";}|{name:\"sponsored\";};logoForDarkBackground?:{src:string;link:string;label:string;dimensions:{width:number;height:number;};};}" } }, "required": [ @@ -3001,87 +2872,33 @@ ], "type": "string" }, - "Branding": { + "{sponsorName:string;logo:{src:string;link:string;label:string;dimensions:{width:number;height:number;};};aboutThisLink:string;brandingType?:{name:\"paid-content\";}|{name:\"foundation\";}|{name:\"sponsored\";};logoForDarkBackground?:{src:string;link:string;label:string;dimensions:{width:number;height:number;};};}": { "type": "object", "properties": { - "brandingType": { - "$ref": "#/definitions/BrandingType" - }, "sponsorName": { "type": "string" }, "logo": { - "type": "object", - "properties": { - "src": { - "type": "string" - }, - "link": { - "type": "string" - }, - "label": { - "type": "string" - }, - "dimensions": { - "type": "object", - "properties": { - "width": { - "type": "number" - }, - "height": { - "type": "number" - } - }, - "required": [ - "height", - "width" - ] - } - }, - "required": [ - "dimensions", - "label", - "link", - "src" - ] + "$ref": "#/definitions/{src:string;link:string;label:string;dimensions:{width:number;height:number;};}" }, "aboutThisLink": { "type": "string" }, - "logoForDarkBackground": { - "type": "object", - "properties": { - "src": { - "type": "string" - }, - "link": { - "type": "string" + "brandingType": { + "anyOf": [ + { + "$ref": "#/definitions/{name:\"paid-content\";}" }, - "label": { - "type": "string" + { + "$ref": "#/definitions/{name:\"foundation\";}" }, - "dimensions": { - "type": "object", - "properties": { - "width": { - "type": "number" - }, - "height": { - "type": "number" - } - }, - "required": [ - "height", - "width" - ] + { + "$ref": "#/definitions/{name:\"sponsored\";}" } - }, - "required": [ - "dimensions", - "label", - "link", - "src" ] + }, + "logoForDarkBackground": { + "$ref": "#/definitions/{src:string;link:string;label:string;dimensions:{width:number;height:number;};}" } }, "required": [ @@ -3090,100 +2907,143 @@ "sponsorName" ] }, - "BrandingType": { - "anyOf": [ - { - "type": "object", - "properties": { - "name": { - "type": "string", - "const": "paid-content" - } - }, - "required": [ - "name" - ] + "{src:string;link:string;label:string;dimensions:{width:number;height:number;};}": { + "type": "object", + "properties": { + "src": { + "type": "string" }, - { - "type": "object", - "properties": { - "name": { - "type": "string", - "const": "foundation" - } - }, - "required": [ - "name" - ] + "link": { + "type": "string" }, - { - "type": "object", - "properties": { - "name": { - "type": "string", - "const": "sponsored" - } - }, - "required": [ - "name" - ] + "label": { + "type": "string" + }, + "dimensions": { + "$ref": "#/definitions/{width:number;height:number;}" } + }, + "required": [ + "dimensions", + "label", + "link", + "src" ] }, - "FEDesign": { - "description": "FEDesign is what frontend gives (originating in the capi scala client) us on the Format field\nhttps://github.com/guardian/content-api-scala-client/blob/master/client/src/main/scala/com.gu.contentapi.client/utils/format/Design.scala", - "enum": [ - "AnalysisDesign", - "ArticleDesign", - "AudioDesign", - "CommentDesign", - "CrosswordDesign", - "DeadBlogDesign", - "EditorialDesign", - "ExplainerDesign", - "FeatureDesign", - "FullPageInteractiveDesign", - "GalleryDesign", - "InteractiveDesign", - "InterviewDesign", - "LetterDesign", - "LiveBlogDesign", - "MatchReportDesign", - "NewsletterSignupDesign", - "ObituaryDesign", - "PhotoEssayDesign", - "PictureDesign", - "ProfileDesign", - "QuizDesign", - "RecipeDesign", - "ReviewDesign", - "TimelineDesign", - "VideoDesign" - ], - "type": "string" + "{width:number;height:number;}": { + "type": "object", + "properties": { + "width": { + "type": "number" + }, + "height": { + "type": "number" + } + }, + "required": [ + "height", + "width" + ] }, - "FETheme": { - "enum": [ - "CulturePillar", - "Labs", - "LifestylePillar", - "NewsPillar", - "OpinionPillar", - "SpecialReportAltTheme", - "SpecialReportTheme", - "SportPillar" - ], - "type": "string" + "{name:\"paid-content\";}": { + "type": "object", + "properties": { + "name": { + "type": "string", + "const": "paid-content" + } + }, + "required": [ + "name" + ] }, - "FEDisplay": { - "description": "FEDisplay is the display information passed through from frontend (originating in the capi scala client) and dictates the display style of the content e.g. Immersive\nhttps://github.com/guardian/content-api-scala-client/blob/master/client/src/main/scala/com.gu.contentapi.client/utils/format/Display.scala", - "enum": [ - "ImmersiveDisplay", - "NumberedListDisplay", - "ShowcaseDisplay", - "StandardDisplay" - ], - "type": "string" + "{name:\"foundation\";}": { + "type": "object", + "properties": { + "name": { + "type": "string", + "const": "foundation" + } + }, + "required": [ + "name" + ] + }, + "{name:\"sponsored\";}": { + "type": "object", + "properties": { + "name": { + "type": "string", + "const": "sponsored" + } + }, + "required": [ + "name" + ] + }, + "{design:\"ArticleDesign\"|\"PictureDesign\"|\"GalleryDesign\"|\"AudioDesign\"|\"VideoDesign\"|\"CrosswordDesign\"|\"ReviewDesign\"|\"AnalysisDesign\"|\"CommentDesign\"|\"ExplainerDesign\"|\"LetterDesign\"|\"FeatureDesign\"|\"LiveBlogDesign\"|\"DeadBlogDesign\"|\"RecipeDesign\"|\"MatchReportDesign\"|\"InterviewDesign\"|\"EditorialDesign\"|\"QuizDesign\"|\"InteractiveDesign\"|\"PhotoEssayDesign\"|\"ObituaryDesign\"|\"FullPageInteractiveDesign\"|\"NewsletterSignupDesign\"|\"TimelineDesign\"|\"ProfileDesign\";theme:\"NewsPillar\"|\"OpinionPillar\"|\"SportPillar\"|\"CulturePillar\"|\"LifestylePillar\"|\"SpecialReportTheme\"|\"Labs\"|\"SpecialReportAltTheme\";display:\"StandardDisplay\"|\"ImmersiveDisplay\"|\"ShowcaseDisplay\"|\"NumberedListDisplay\";}": { + "description": "FEFormat is the stringified version of Format passed through from Frontend.\nIt gets converted to the `@guardian/libs` format on platform", + "type": "object", + "properties": { + "design": { + "enum": [ + "AnalysisDesign", + "ArticleDesign", + "AudioDesign", + "CommentDesign", + "CrosswordDesign", + "DeadBlogDesign", + "EditorialDesign", + "ExplainerDesign", + "FeatureDesign", + "FullPageInteractiveDesign", + "GalleryDesign", + "InteractiveDesign", + "InterviewDesign", + "LetterDesign", + "LiveBlogDesign", + "MatchReportDesign", + "NewsletterSignupDesign", + "ObituaryDesign", + "PhotoEssayDesign", + "PictureDesign", + "ProfileDesign", + "QuizDesign", + "RecipeDesign", + "ReviewDesign", + "TimelineDesign", + "VideoDesign" + ], + "type": "string" + }, + "theme": { + "enum": [ + "CulturePillar", + "Labs", + "LifestylePillar", + "NewsPillar", + "OpinionPillar", + "SpecialReportAltTheme", + "SpecialReportTheme", + "SportPillar" + ], + "type": "string" + }, + "display": { + "enum": [ + "ImmersiveDisplay", + "NumberedListDisplay", + "ShowcaseDisplay", + "StandardDisplay" + ], + "type": "string" + } + }, + "required": [ + "design", + "display", + "theme" + ] }, "FEMediaAtom": { "type": "object", @@ -3337,17 +3197,6 @@ ], "type": "string" }, - "StarRating": { - "enum": [ - 0, - 1, - 2, - 3, - 4, - 5 - ], - "type": "number" - }, "BoostLevel": { "enum": [ "boost", @@ -3670,56 +3519,18 @@ "url" ] }, - "FETrailType": { + "{url:string;headline:string;format:{design:\"ArticleDesign\"|\"PictureDesign\"|\"GalleryDesign\"|\"AudioDesign\"|\"VideoDesign\"|\"CrosswordDesign\"|\"ReviewDesign\"|\"AnalysisDesign\"|\"CommentDesign\"|\"ExplainerDesign\"|\"LetterDesign\"|\"FeatureDesign\"|\"LiveBlogDesign\"|\"DeadBlogDesign\"|\"RecipeDesign\"|\"MatchReportDesign\"|\"InterviewDesign\"|\"EditorialDesign\"|\"QuizDesign\"|\"InteractiveDesign\"|\"PhotoEssayDesign\"|\"ObituaryDesign\"|\"FullPageInteractiveDesign\"|\"NewsletterSignupDesign\"|\"TimelineDesign\"|\"ProfileDesign\";theme:\"NewsPillar\"|\"OpinionPillar\"|\"SportPillar\"|\"CulturePillar\"|\"LifestylePillar\"|\"SpecialReportTheme\"|\"Labs\"|\"SpecialReportAltTheme\";display:\"StandardDisplay\"|\"ImmersiveDisplay\"|\"ShowcaseDisplay\"|\"NumberedListDisplay\";};webPublicationDate?:string;avatarUrl?:string;mediaDuration?:number;ageWarning?:string;byline?:string;showByline?:boolean;kickerText?:string;shortUrl?:string;commentCount?:number;starRating?:0|5|4|3|2|1;linkText?:string;branding?:{sponsorName:string;logo:{src:string;link:string;label:string;dimensions:{width:number;height:number;};};aboutThisLink:string;brandingType?:{name:\"paid-content\";}|{name:\"foundation\";}|{name:\"sponsored\";};logoForDarkBackground?:{src:string;link:string;label:string;dimensions:{width:number;height:number;};};};isSnap?:boolean;isCrossword?:boolean;snapData?:{embedHtml?:string;embedCss?:string;embedJs?:string;};showQuotedHeadline?:boolean;discussion?:{isCommentable:boolean;isClosedForComments:boolean;discussionId?:string;};mainMedia?:{width:number;height:number;type:\"Video\";id:string;videoId:string;origin:string;title:string;duration:number;expired:boolean;image?:string;}|{width:number;height:number;type:\"LoopVideo\";videoId:string;duration:number;atomId:string;image?:string;}|{type:\"Audio\";duration:string;podcastImage?:{src?:string;altText?:string;};}|{type:\"Gallery\";count:string;};image?:string;designType?:string;pillar?:string;carouselImages?:{[x:string]:string;};isLiveBlog?:boolean;masterImage?:string;}": { "type": "object", "properties": { - "format": { - "description": "FEFormat is the stringified version of Format passed through from Frontend.\nIt gets converted to the `@guardian/libs` format on platform", - "type": "object", - "properties": { - "design": { - "$ref": "#/definitions/FEDesign" - }, - "theme": { - "$ref": "#/definitions/FETheme" - }, - "display": { - "$ref": "#/definitions/FEDisplay" - } - }, - "required": [ - "design", - "display", - "theme" - ] - }, - "designType": { - "type": "string" - }, - "pillar": { - "type": "string" - }, - "carouselImages": { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - "isLiveBlog": { - "type": "boolean" - }, - "masterImage": { - "type": "string" - }, - "image": { - "type": "string" - }, "url": { "type": "string" }, "headline": { "type": "string" }, + "format": { + "$ref": "#/definitions/{design:\"ArticleDesign\"|\"PictureDesign\"|\"GalleryDesign\"|\"AudioDesign\"|\"VideoDesign\"|\"CrosswordDesign\"|\"ReviewDesign\"|\"AnalysisDesign\"|\"CommentDesign\"|\"ExplainerDesign\"|\"LetterDesign\"|\"FeatureDesign\"|\"LiveBlogDesign\"|\"DeadBlogDesign\"|\"RecipeDesign\"|\"MatchReportDesign\"|\"InterviewDesign\"|\"EditorialDesign\"|\"QuizDesign\"|\"InteractiveDesign\"|\"PhotoEssayDesign\"|\"ObituaryDesign\"|\"FullPageInteractiveDesign\"|\"NewsletterSignupDesign\"|\"TimelineDesign\"|\"ProfileDesign\";theme:\"NewsPillar\"|\"OpinionPillar\"|\"SportPillar\"|\"CulturePillar\"|\"LifestylePillar\"|\"SpecialReportTheme\"|\"Labs\"|\"SpecialReportAltTheme\";display:\"StandardDisplay\"|\"ImmersiveDisplay\"|\"ShowcaseDisplay\"|\"NumberedListDisplay\";}" + }, "webPublicationDate": { "type": "string" }, @@ -3748,13 +3559,21 @@ "type": "number" }, "starRating": { - "$ref": "#/definitions/StarRating" + "enum": [ + 0, + 1, + 2, + 3, + 4, + 5 + ], + "type": "number" }, "linkText": { "type": "string" }, "branding": { - "$ref": "#/definitions/Branding" + "$ref": "#/definitions/{sponsorName:string;logo:{src:string;link:string;label:string;dimensions:{width:number;height:number;};};aboutThisLink:string;brandingType?:{name:\"paid-content\";}|{name:\"foundation\";}|{name:\"sponsored\";};logoForDarkBackground?:{src:string;link:string;label:string;dimensions:{width:number;height:number;};};}" }, "isSnap": { "type": "boolean" @@ -3763,42 +3582,47 @@ "type": "boolean" }, "snapData": { - "type": "object", - "properties": { - "embedHtml": { - "type": "string" - }, - "embedCss": { - "type": "string" - }, - "embedJs": { - "type": "string" - } - } + "$ref": "#/definitions/{embedHtml?:string;embedCss?:string;embedJs?:string;}" }, "showQuotedHeadline": { "type": "boolean" }, "discussion": { - "type": "object", - "properties": { - "isCommentable": { - "type": "boolean" + "$ref": "#/definitions/{isCommentable:boolean;isClosedForComments:boolean;discussionId?:string;}_1" + }, + "mainMedia": { + "anyOf": [ + { + "$ref": "#/definitions/{width:number;height:number;type:\"Video\";id:string;videoId:string;origin:string;title:string;duration:number;expired:boolean;image?:string;}" }, - "isClosedForComments": { - "type": "boolean" + { + "$ref": "#/definitions/{width:number;height:number;type:\"LoopVideo\";videoId:string;duration:number;atomId:string;image?:string;}" }, - "discussionId": { - "type": "string" + { + "$ref": "#/definitions/{type:\"Audio\";duration:string;podcastImage?:{src?:string;altText?:string;};}" + }, + { + "$ref": "#/definitions/{type:\"Gallery\";count:string;}" } - }, - "required": [ - "isClosedForComments", - "isCommentable" ] }, - "mainMedia": { - "$ref": "#/definitions/MainMedia" + "image": { + "type": "string" + }, + "designType": { + "type": "string" + }, + "pillar": { + "type": "string" + }, + "carouselImages": { + "$ref": "#/definitions/{[x:string]:string;}" + }, + "isLiveBlog": { + "type": "boolean" + }, + "masterImage": { + "type": "string" } }, "required": [ @@ -3807,232 +3631,168 @@ "url" ] }, - "MainMedia": { - "anyOf": [ - { - "$ref": "#/definitions/Video", - "description": "For displaying embedded, playable videos directly in cards" + "{embedHtml?:string;embedCss?:string;embedJs?:string;}": { + "type": "object", + "properties": { + "embedHtml": { + "type": "string" }, - { - "$ref": "#/definitions/LoopVideo" + "embedCss": { + "type": "string" }, - { - "$ref": "#/definitions/Audio" + "embedJs": { + "type": "string" + } + } + }, + "{isCommentable:boolean;isClosedForComments:boolean;discussionId?:string;}_1": { + "type": "object", + "properties": { + "isCommentable": { + "type": "boolean" }, - { - "$ref": "#/definitions/Gallery" + "isClosedForComments": { + "type": "boolean" + }, + "discussionId": { + "type": "string" } + }, + "required": [ + "isClosedForComments", + "isCommentable" ] }, - "Video": { - "description": "For displaying embedded, playable videos directly in cards", - "allOf": [ - { - "type": "object", - "properties": { - "type": { - "enum": [ - "Audio", - "Gallery", - "LoopVideo", - "Video" - ], - "type": "string" - } - }, - "required": [ - "type" - ] + "{width:number;height:number;type:\"Video\";id:string;videoId:string;origin:string;title:string;duration:number;expired:boolean;image?:string;}": { + "type": "object", + "properties": { + "width": { + "type": "number" }, - { - "type": "object", - "properties": { - "type": { - "type": "string", - "const": "Video" - }, - "id": { - "type": "string" - }, - "videoId": { - "type": "string" - }, - "height": { - "type": "number" - }, - "width": { - "type": "number" - }, - "origin": { - "type": "string" - }, - "title": { - "type": "string" - }, - "duration": { - "type": "number" - }, - "expired": { - "type": "boolean" - }, - "image": { - "type": "string" - } - }, - "required": [ - "duration", - "expired", - "height", - "id", - "origin", - "title", - "type", - "videoId", - "width" - ] + "height": { + "type": "number" + }, + "type": { + "type": "string", + "const": "Video" + }, + "id": { + "type": "string" + }, + "videoId": { + "type": "string" + }, + "origin": { + "type": "string" + }, + "title": { + "type": "string" + }, + "duration": { + "type": "number" + }, + "expired": { + "type": "boolean" + }, + "image": { + "type": "string" } + }, + "required": [ + "duration", + "expired", + "height", + "id", + "origin", + "title", + "type", + "videoId", + "width" ] }, - "LoopVideo": { - "allOf": [ - { - "type": "object", - "properties": { - "type": { - "enum": [ - "Audio", - "Gallery", - "LoopVideo", - "Video" - ], - "type": "string" - } - }, - "required": [ - "type" - ] + "{width:number;height:number;type:\"LoopVideo\";videoId:string;duration:number;atomId:string;image?:string;}": { + "type": "object", + "properties": { + "width": { + "type": "number" }, - { - "type": "object", - "properties": { - "type": { - "type": "string", - "const": "LoopVideo" - }, - "atomId": { - "type": "string" - }, - "videoId": { - "type": "string" - }, - "height": { - "type": "number" - }, - "width": { - "type": "number" - }, - "duration": { - "type": "number" - }, - "image": { - "type": "string" - } - }, - "required": [ - "atomId", - "duration", - "height", - "type", - "videoId", - "width" - ] + "height": { + "type": "number" + }, + "type": { + "type": "string", + "const": "LoopVideo" + }, + "videoId": { + "type": "string" + }, + "duration": { + "type": "number" + }, + "atomId": { + "type": "string" + }, + "image": { + "type": "string" } + }, + "required": [ + "atomId", + "duration", + "height", + "type", + "videoId", + "width" ] }, - "Audio": { - "allOf": [ - { - "type": "object", - "properties": { - "type": { - "enum": [ - "Audio", - "Gallery", - "LoopVideo", - "Video" - ], - "type": "string" - } - }, - "required": [ - "type" - ] + "{type:\"Audio\";duration:string;podcastImage?:{src?:string;altText?:string;};}": { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "Audio" }, - { - "type": "object", - "properties": { - "type": { - "type": "string", - "const": "Audio" - }, - "duration": { - "type": "string" - }, - "podcastImage": { - "type": "object", - "properties": { - "src": { - "type": "string" - }, - "altText": { - "type": "string" - } - } - } - }, - "required": [ - "duration", - "type" - ] + "duration": { + "type": "string" + }, + "podcastImage": { + "$ref": "#/definitions/{src?:string;altText?:string;}" } + }, + "required": [ + "duration", + "type" ] }, - "Gallery": { - "allOf": [ - { - "type": "object", - "properties": { - "type": { - "enum": [ - "Audio", - "Gallery", - "LoopVideo", - "Video" - ], - "type": "string" - } - }, - "required": [ - "type" - ] + "{src?:string;altText?:string;}": { + "type": "object", + "properties": { + "src": { + "type": "string" }, - { - "type": "object", - "properties": { - "type": { - "type": "string", - "const": "Gallery" - }, - "count": { - "type": "string" - } - }, - "required": [ - "count", - "type" - ] + "altText": { + "type": "string" } + } + }, + "{type:\"Gallery\";count:string;}": { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "Gallery" + }, + "count": { + "type": "string" + } + }, + "required": [ + "count", + "type" ] + }, + "{[x:string]:string;}": { + "type": "object" } }, "$schema": "http://json-schema.org/draft-07/schema#" diff --git a/dotcom-rendering/src/frontend/schemas/feTagPage.json b/dotcom-rendering/src/frontend/schemas/feTagPage.json index ea3f0a9af7a..d27679972d6 100644 --- a/dotcom-rendering/src/frontend/schemas/feTagPage.json +++ b/dotcom-rendering/src/frontend/schemas/feTagPage.json @@ -158,24 +158,7 @@ ] }, "format": { - "description": "FEFormat is the stringified version of Format passed through from Frontend.\nIt gets converted to the `@guardian/libs` format on platform", - "type": "object", - "properties": { - "design": { - "$ref": "#/definitions/FEDesign" - }, - "theme": { - "$ref": "#/definitions/FETheme" - }, - "display": { - "$ref": "#/definitions/FEDisplay" - } - }, - "required": [ - "design", - "display", - "theme" - ] + "$ref": "#/definitions/{design:\"ArticleDesign\"|\"PictureDesign\"|\"GalleryDesign\"|\"AudioDesign\"|\"VideoDesign\"|\"CrosswordDesign\"|\"ReviewDesign\"|\"AnalysisDesign\"|\"CommentDesign\"|\"ExplainerDesign\"|\"LetterDesign\"|\"FeatureDesign\"|\"LiveBlogDesign\"|\"DeadBlogDesign\"|\"RecipeDesign\"|\"MatchReportDesign\"|\"InterviewDesign\"|\"EditorialDesign\"|\"QuizDesign\"|\"InteractiveDesign\"|\"PhotoEssayDesign\"|\"ObituaryDesign\"|\"FullPageInteractiveDesign\"|\"NewsletterSignupDesign\"|\"TimelineDesign\"|\"ProfileDesign\";theme:\"NewsPillar\"|\"OpinionPillar\"|\"SportPillar\"|\"CulturePillar\"|\"LifestylePillar\"|\"SpecialReportTheme\"|\"Labs\"|\"SpecialReportAltTheme\";display:\"StandardDisplay\"|\"ImmersiveDisplay\"|\"ShowcaseDisplay\"|\"NumberedListDisplay\";}" } }, "required": [ @@ -558,7 +541,15 @@ "type": "string" }, "starRating": { - "$ref": "#/definitions/StarRating" + "enum": [ + 0, + 1, + 2, + 3, + 4, + 5 + ], + "type": "number" }, "shortUrlPath": { "type": "string" @@ -639,24 +630,7 @@ ] }, "format": { - "description": "FEFormat is the stringified version of Format passed through from Frontend.\nIt gets converted to the `@guardian/libs` format on platform", - "type": "object", - "properties": { - "design": { - "$ref": "#/definitions/FEDesign" - }, - "theme": { - "$ref": "#/definitions/FETheme" - }, - "display": { - "$ref": "#/definitions/FEDisplay" - } - }, - "required": [ - "design", - "display", - "theme" - ] + "$ref": "#/definitions/{design:\"ArticleDesign\"|\"PictureDesign\"|\"GalleryDesign\"|\"AudioDesign\"|\"VideoDesign\"|\"CrosswordDesign\"|\"ReviewDesign\"|\"AnalysisDesign\"|\"CommentDesign\"|\"ExplainerDesign\"|\"LetterDesign\"|\"FeatureDesign\"|\"LiveBlogDesign\"|\"DeadBlogDesign\"|\"RecipeDesign\"|\"MatchReportDesign\"|\"InterviewDesign\"|\"EditorialDesign\"|\"QuizDesign\"|\"InteractiveDesign\"|\"PhotoEssayDesign\"|\"ObituaryDesign\"|\"FullPageInteractiveDesign\"|\"NewsletterSignupDesign\"|\"TimelineDesign\"|\"ProfileDesign\";theme:\"NewsPillar\"|\"OpinionPillar\"|\"SportPillar\"|\"CulturePillar\"|\"LifestylePillar\"|\"SpecialReportTheme\"|\"Labs\"|\"SpecialReportAltTheme\";display:\"StandardDisplay\"|\"ImmersiveDisplay\"|\"ShowcaseDisplay\"|\"NumberedListDisplay\";}" }, "enriched": { "type": "object", @@ -731,24 +705,7 @@ ] }, "format": { - "description": "FEFormat is the stringified version of Format passed through from Frontend.\nIt gets converted to the `@guardian/libs` format on platform", - "type": "object", - "properties": { - "design": { - "$ref": "#/definitions/FEDesign" - }, - "theme": { - "$ref": "#/definitions/FETheme" - }, - "display": { - "$ref": "#/definitions/FEDisplay" - } - }, - "required": [ - "design", - "display", - "theme" - ] + "$ref": "#/definitions/{design:\"ArticleDesign\"|\"PictureDesign\"|\"GalleryDesign\"|\"AudioDesign\"|\"VideoDesign\"|\"CrosswordDesign\"|\"ReviewDesign\"|\"AnalysisDesign\"|\"CommentDesign\"|\"ExplainerDesign\"|\"LetterDesign\"|\"FeatureDesign\"|\"LiveBlogDesign\"|\"DeadBlogDesign\"|\"RecipeDesign\"|\"MatchReportDesign\"|\"InterviewDesign\"|\"EditorialDesign\"|\"QuizDesign\"|\"InteractiveDesign\"|\"PhotoEssayDesign\"|\"ObituaryDesign\"|\"FullPageInteractiveDesign\"|\"NewsletterSignupDesign\"|\"TimelineDesign\"|\"ProfileDesign\";theme:\"NewsPillar\"|\"OpinionPillar\"|\"SportPillar\"|\"CulturePillar\"|\"LifestylePillar\"|\"SpecialReportTheme\"|\"Labs\"|\"SpecialReportAltTheme\";display:\"StandardDisplay\"|\"ImmersiveDisplay\"|\"ShowcaseDisplay\"|\"NumberedListDisplay\";}" } }, "required": [ @@ -1303,60 +1260,69 @@ "webURL" ], "definitions": { - "FEDesign": { - "description": "FEDesign is what frontend gives (originating in the capi scala client) us on the Format field\nhttps://github.com/guardian/content-api-scala-client/blob/master/client/src/main/scala/com.gu.contentapi.client/utils/format/Design.scala", - "enum": [ - "AnalysisDesign", - "ArticleDesign", - "AudioDesign", - "CommentDesign", - "CrosswordDesign", - "DeadBlogDesign", - "EditorialDesign", - "ExplainerDesign", - "FeatureDesign", - "FullPageInteractiveDesign", - "GalleryDesign", - "InteractiveDesign", - "InterviewDesign", - "LetterDesign", - "LiveBlogDesign", - "MatchReportDesign", - "NewsletterSignupDesign", - "ObituaryDesign", - "PhotoEssayDesign", - "PictureDesign", - "ProfileDesign", - "QuizDesign", - "RecipeDesign", - "ReviewDesign", - "TimelineDesign", - "VideoDesign" - ], - "type": "string" - }, - "FETheme": { - "enum": [ - "CulturePillar", - "Labs", - "LifestylePillar", - "NewsPillar", - "OpinionPillar", - "SpecialReportAltTheme", - "SpecialReportTheme", - "SportPillar" - ], - "type": "string" - }, - "FEDisplay": { - "description": "FEDisplay is the display information passed through from frontend (originating in the capi scala client) and dictates the display style of the content e.g. Immersive\nhttps://github.com/guardian/content-api-scala-client/blob/master/client/src/main/scala/com.gu.contentapi.client/utils/format/Display.scala", - "enum": [ - "ImmersiveDisplay", - "NumberedListDisplay", - "ShowcaseDisplay", - "StandardDisplay" - ], - "type": "string" + "{design:\"ArticleDesign\"|\"PictureDesign\"|\"GalleryDesign\"|\"AudioDesign\"|\"VideoDesign\"|\"CrosswordDesign\"|\"ReviewDesign\"|\"AnalysisDesign\"|\"CommentDesign\"|\"ExplainerDesign\"|\"LetterDesign\"|\"FeatureDesign\"|\"LiveBlogDesign\"|\"DeadBlogDesign\"|\"RecipeDesign\"|\"MatchReportDesign\"|\"InterviewDesign\"|\"EditorialDesign\"|\"QuizDesign\"|\"InteractiveDesign\"|\"PhotoEssayDesign\"|\"ObituaryDesign\"|\"FullPageInteractiveDesign\"|\"NewsletterSignupDesign\"|\"TimelineDesign\"|\"ProfileDesign\";theme:\"NewsPillar\"|\"OpinionPillar\"|\"SportPillar\"|\"CulturePillar\"|\"LifestylePillar\"|\"SpecialReportTheme\"|\"Labs\"|\"SpecialReportAltTheme\";display:\"StandardDisplay\"|\"ImmersiveDisplay\"|\"ShowcaseDisplay\"|\"NumberedListDisplay\";}": { + "description": "FEFormat is the stringified version of Format passed through from Frontend.\nIt gets converted to the `@guardian/libs` format on platform", + "type": "object", + "properties": { + "design": { + "enum": [ + "AnalysisDesign", + "ArticleDesign", + "AudioDesign", + "CommentDesign", + "CrosswordDesign", + "DeadBlogDesign", + "EditorialDesign", + "ExplainerDesign", + "FeatureDesign", + "FullPageInteractiveDesign", + "GalleryDesign", + "InteractiveDesign", + "InterviewDesign", + "LetterDesign", + "LiveBlogDesign", + "MatchReportDesign", + "NewsletterSignupDesign", + "ObituaryDesign", + "PhotoEssayDesign", + "PictureDesign", + "ProfileDesign", + "QuizDesign", + "RecipeDesign", + "ReviewDesign", + "TimelineDesign", + "VideoDesign" + ], + "type": "string" + }, + "theme": { + "enum": [ + "CulturePillar", + "Labs", + "LifestylePillar", + "NewsPillar", + "OpinionPillar", + "SpecialReportAltTheme", + "SpecialReportTheme", + "SportPillar" + ], + "type": "string" + }, + "display": { + "enum": [ + "ImmersiveDisplay", + "NumberedListDisplay", + "ShowcaseDisplay", + "StandardDisplay" + ], + "type": "string" + } + }, + "required": [ + "design", + "display", + "theme" + ] }, "FEMediaAtom": { "type": "object", @@ -1507,7 +1473,7 @@ ] }, "branding": { - "$ref": "#/definitions/Branding" + "$ref": "#/definitions/{sponsorName:string;logo:{src:string;link:string;label:string;dimensions:{width:number;height:number;};};aboutThisLink:string;brandingType?:{name:\"paid-content\";}|{name:\"foundation\";}|{name:\"sponsored\";};logoForDarkBackground?:{src:string;link:string;label:string;dimensions:{width:number;height:number;};};}" } }, "required": [ @@ -1524,87 +1490,33 @@ ], "type": "string" }, - "Branding": { + "{sponsorName:string;logo:{src:string;link:string;label:string;dimensions:{width:number;height:number;};};aboutThisLink:string;brandingType?:{name:\"paid-content\";}|{name:\"foundation\";}|{name:\"sponsored\";};logoForDarkBackground?:{src:string;link:string;label:string;dimensions:{width:number;height:number;};};}": { "type": "object", "properties": { - "brandingType": { - "$ref": "#/definitions/BrandingType" - }, "sponsorName": { "type": "string" }, "logo": { - "type": "object", - "properties": { - "src": { - "type": "string" - }, - "link": { - "type": "string" - }, - "label": { - "type": "string" - }, - "dimensions": { - "type": "object", - "properties": { - "width": { - "type": "number" - }, - "height": { - "type": "number" - } - }, - "required": [ - "height", - "width" - ] - } - }, - "required": [ - "dimensions", - "label", - "link", - "src" - ] + "$ref": "#/definitions/{src:string;link:string;label:string;dimensions:{width:number;height:number;};}" }, "aboutThisLink": { "type": "string" }, - "logoForDarkBackground": { - "type": "object", - "properties": { - "src": { - "type": "string" - }, - "link": { - "type": "string" + "brandingType": { + "anyOf": [ + { + "$ref": "#/definitions/{name:\"paid-content\";}" }, - "label": { - "type": "string" + { + "$ref": "#/definitions/{name:\"foundation\";}" }, - "dimensions": { - "type": "object", - "properties": { - "width": { - "type": "number" - }, - "height": { - "type": "number" - } - }, - "required": [ - "height", - "width" - ] + { + "$ref": "#/definitions/{name:\"sponsored\";}" } - }, - "required": [ - "dimensions", - "label", - "link", - "src" ] + }, + "logoForDarkBackground": { + "$ref": "#/definitions/{src:string;link:string;label:string;dimensions:{width:number;height:number;};}" } }, "required": [ @@ -1613,44 +1525,78 @@ "sponsorName" ] }, - "BrandingType": { - "anyOf": [ - { - "type": "object", - "properties": { - "name": { - "type": "string", - "const": "paid-content" - } - }, - "required": [ - "name" - ] + "{src:string;link:string;label:string;dimensions:{width:number;height:number;};}": { + "type": "object", + "properties": { + "src": { + "type": "string" }, - { - "type": "object", - "properties": { - "name": { - "type": "string", - "const": "foundation" - } - }, - "required": [ - "name" - ] + "link": { + "type": "string" }, - { - "type": "object", - "properties": { - "name": { - "type": "string", - "const": "sponsored" - } - }, - "required": [ - "name" - ] + "label": { + "type": "string" + }, + "dimensions": { + "$ref": "#/definitions/{width:number;height:number;}" } + }, + "required": [ + "dimensions", + "label", + "link", + "src" + ] + }, + "{width:number;height:number;}": { + "type": "object", + "properties": { + "width": { + "type": "number" + }, + "height": { + "type": "number" + } + }, + "required": [ + "height", + "width" + ] + }, + "{name:\"paid-content\";}": { + "type": "object", + "properties": { + "name": { + "type": "string", + "const": "paid-content" + } + }, + "required": [ + "name" + ] + }, + "{name:\"foundation\";}": { + "type": "object", + "properties": { + "name": { + "type": "string", + "const": "foundation" + } + }, + "required": [ + "name" + ] + }, + "{name:\"sponsored\";}": { + "type": "object", + "properties": { + "name": { + "type": "string", + "const": "sponsored" + } + }, + "required": [ + "name" ] }, "FEFrontCardStyle": { @@ -1671,17 +1617,6 @@ ], "type": "string" }, - "StarRating": { - "enum": [ - 0, - 1, - 2, - 3, - 4, - 5 - ], - "type": "number" - }, "BoostLevel": { "enum": [ "boost", @@ -1914,7 +1849,7 @@ } }, "branding": { - "$ref": "#/definitions/Branding" + "$ref": "#/definitions/{sponsorName:string;logo:{src:string;link:string;label:string;dimensions:{width:number;height:number;};};aboutThisLink:string;brandingType?:{name:\"paid-content\";}|{name:\"foundation\";}|{name:\"sponsored\";};logoForDarkBackground?:{src:string;link:string;label:string;dimensions:{width:number;height:number;};};}" } }, "required": [ diff --git a/dotcom-rendering/src/model/block-schema.json b/dotcom-rendering/src/model/block-schema.json index 2d8940e6521..ba0ce30bd73 100644 --- a/dotcom-rendering/src/model/block-schema.json +++ b/dotcom-rendering/src/model/block-schema.json @@ -1693,7 +1693,15 @@ "type": "string" }, "starRating": { - "$ref": "#/definitions/StarRating" + "enum": [ + 0, + 1, + 2, + 3, + 4, + 5 + ], + "type": "number" }, "isAvatar": { "type": "boolean" @@ -1757,17 +1765,6 @@ "width" ] }, - "StarRating": { - "enum": [ - 0, - 1, - 2, - 3, - 4, - 5 - ], - "type": "number" - }, "InstagramBlockElement": { "type": "object", "properties": { @@ -2821,7 +2818,15 @@ "type": "string" }, "rating": { - "$ref": "#/definitions/StarRating" + "enum": [ + 0, + 1, + 2, + 3, + 4, + 5 + ], + "type": "number" }, "size": { "$ref": "#/definitions/RatingSizeType" diff --git a/dotcom-rendering/src/types/branding.ts b/dotcom-rendering/src/types/branding.ts index 545d84a77fc..c0d45fba724 100644 --- a/dotcom-rendering/src/types/branding.ts +++ b/dotcom-rendering/src/types/branding.ts @@ -1,27 +1,46 @@ +import { + literal, + number, + object, + optional, + type Output, + string, + union, +} from 'valibot'; import type { EditionId } from '../lib/edition'; -type BrandingLogo = { - src: string; - link: string; - label: string; - dimensions: { width: number; height: number }; -}; +export type BrandingLogo = Output; + +export const BrandingLogoSchema = object({ + src: string(), + link: string(), + label: string(), + dimensions: object({ + width: number(), + height: number(), + }), +}); /** * @see https://github.com/guardian/commercial-shared/blob/35cdf4e1/src/main/scala/com/gu/commercial/branding/BrandingType.scala */ -export type BrandingType = - | { name: 'paid-content' } - | { name: 'foundation' } - | { name: 'sponsored' }; - -export interface Branding { - brandingType?: BrandingType; - sponsorName: string; - logo: BrandingLogo; - aboutThisLink: string; - logoForDarkBackground?: BrandingLogo; -} +export type BrandingType = Output; + +export const BrandingTypeSchema = union([ + object({ name: literal('paid-content') }), + object({ name: literal('foundation') }), + object({ name: literal('sponsored') }), +]); + +export type Branding = Output; + +export const BrandingSchema = object({ + brandingType: optional(BrandingTypeSchema), + sponsorName: string(), + logo: BrandingLogoSchema, + aboutThisLink: string(), + logoForDarkBackground: optional(BrandingLogoSchema), +}); export interface EditionBranding { edition: { diff --git a/dotcom-rendering/src/types/content.ts b/dotcom-rendering/src/types/content.ts index 9e5d2390e42..9144058d096 100644 --- a/dotcom-rendering/src/types/content.ts +++ b/dotcom-rendering/src/types/content.ts @@ -1,7 +1,17 @@ import { type CrosswordProps } from '@guardian/react-crossword'; +import { literal, type Output, union } from 'valibot'; import type { ArticleFormat } from '../lib/articleFormat'; -export type StarRating = 0 | 1 | 2 | 3 | 4 | 5; +export const StarRatingSchema = union([ + literal(0), + literal(1), + literal(2), + literal(3), + literal(4), + literal(5), +]); + +export type StarRating = Output; export type BoostLevel = 'default' | 'boost' | 'megaboost' | 'gigaboost'; diff --git a/dotcom-rendering/src/types/front.ts b/dotcom-rendering/src/types/front.ts index 6fb1bd8f4b1..cc38a6f5431 100644 --- a/dotcom-rendering/src/types/front.ts +++ b/dotcom-rendering/src/types/front.ts @@ -1,3 +1,4 @@ +import { object, optional, type Output, string } from 'valibot'; import type { FEAspectRatio, FEContainer, @@ -109,11 +110,13 @@ export type DCRSlideshowImage = { imageCaption?: string; }; -export type DCRSnapType = { - embedHtml?: string; - embedCss?: string; - embedJs?: string; -}; +export type DCRSnapType = Output; + +export const DCRSnapTypeSchema = object({ + embedHtml: optional(string()), + embedCss: optional(string()), + embedJs: optional(string()), +}); export type AspectRatio = FEAspectRatio; diff --git a/dotcom-rendering/src/types/mainMedia.ts b/dotcom-rendering/src/types/mainMedia.ts index a13d7d48936..ad854fdac41 100644 --- a/dotcom-rendering/src/types/mainMedia.ts +++ b/dotcom-rendering/src/types/mainMedia.ts @@ -1,43 +1,55 @@ -import type { PodcastSeriesImage } from './tag'; - -type Media = { - type: 'Video' | 'LoopVideo' | 'Audio' | 'Gallery'; -}; - +import { + boolean, + literal, + number, + object, + optional, + type Output, + string, + union, +} from 'valibot'; +import { PodcastSeriesImageSchema } from './tag'; /** For displaying embedded, playable videos directly in cards */ -type Video = Media & { - type: 'Video'; +const VideoSchema = object({ + type: literal('Video'), /** @see https://github.com/guardian/frontend/blob/8e7e4d0e/common/app/model/content/Atom.scala#L159 */ - id: string; - videoId: string; - height: number; - width: number; - origin: string; - title: string; - duration: number; - expired: boolean; - image?: string; -}; + id: string(), + videoId: string(), + height: number(), + width: number(), + origin: string(), + title: string(), + duration: number(), + expired: boolean(), + image: optional(string()), +}); + +const LoopVideoSchema = object({ + type: literal('LoopVideo'), + atomId: string(), + videoId: string(), + height: number(), + width: number(), + duration: number(), + image: optional(string()), +}); -type LoopVideo = Media & { - type: 'LoopVideo'; - atomId: string; - videoId: string; - height: number; - width: number; - duration: number; - image?: string; -}; +const AudioSchema = object({ + type: literal('Audio'), + duration: string(), + podcastImage: optional(PodcastSeriesImageSchema), +}); -type Audio = Media & { - type: 'Audio'; - duration: string; - podcastImage?: PodcastSeriesImage; -}; +const GallerySchema = object({ + type: literal('Gallery'), + count: string(), +}); -type Gallery = Media & { - type: 'Gallery'; - count: string; -}; +export type MainMedia = Output; -export type MainMedia = Video | LoopVideo | Audio | Gallery; +export const MainMediaSchema = union([ + VideoSchema, + LoopVideoSchema, + AudioSchema, + GallerySchema, +]); diff --git a/dotcom-rendering/src/types/tag.ts b/dotcom-rendering/src/types/tag.ts index aca68f30f28..52ebaf54b30 100644 --- a/dotcom-rendering/src/types/tag.ts +++ b/dotcom-rendering/src/types/tag.ts @@ -1,3 +1,4 @@ +import { object, optional, type Output, string } from 'valibot'; /** * This type comes from `frontend`, hence the FE prefix. * @@ -43,10 +44,12 @@ export type Podcast = { image?: string; }; -export type PodcastSeriesImage = { - src?: string; - altText?: string; -}; +export type PodcastSeriesImage = Output; + +export const PodcastSeriesImageSchema = object({ + src: optional(string()), + altText: optional(string()), +}); export type TagType = { id: string; diff --git a/dotcom-rendering/src/types/trails.ts b/dotcom-rendering/src/types/trails.ts index 396a31072c7..6c805021e19 100644 --- a/dotcom-rendering/src/types/trails.ts +++ b/dotcom-rendering/src/types/trails.ts @@ -1,36 +1,53 @@ -import type { FEFormat } from '../frontend/feArticle'; +import { + boolean, + number, + object, + optional, + type Output, + record, + string, +} from 'valibot'; +import { FEFormatSchema } from '../frontend/feArticle'; import type { ArticleFormat } from '../lib/articleFormat'; -import type { Branding } from './branding'; -import type { BoostLevel, StarRating } from './content'; -import type { DCRFrontImage, DCRSnapType, DCRSupportingContent } from './front'; -import type { MainMedia } from './mainMedia'; +import { BrandingSchema } from './branding'; +import { type BoostLevel, StarRatingSchema } from './content'; +import { + type DCRFrontImage, + DCRSnapTypeSchema, + type DCRSupportingContent, +} from './front'; +import { MainMediaSchema } from './mainMedia'; -interface BaseTrailType { - url: string; - headline: string; - webPublicationDate?: string; - avatarUrl?: string; - mediaDuration?: number; - ageWarning?: string; - byline?: string; - showByline?: boolean; - kickerText?: string; - shortUrl?: string; - commentCount?: number; - starRating?: StarRating; - linkText?: string; - branding?: Branding; - isSnap?: boolean; - isCrossword?: boolean; - snapData?: DCRSnapType; - showQuotedHeadline?: boolean; - discussion?: { - isCommentable: boolean; - isClosedForComments: boolean; - discussionId?: string; - }; - mainMedia?: MainMedia; -} +export const DiscussionSchema = object({ + isCommentable: boolean(), + isClosedForComments: boolean(), + discussionId: optional(string()), +}); + +export type BaseTrailType = Output; + +export const BaseTrailTypeSchema = object({ + url: string(), + headline: string(), + webPublicationDate: optional(string()), + avatarUrl: optional(string()), + mediaDuration: optional(number()), + ageWarning: optional(string()), + byline: optional(string()), + showByline: optional(boolean()), + kickerText: optional(string()), + shortUrl: optional(string()), + commentCount: optional(number()), + starRating: optional(StarRatingSchema), + linkText: optional(string()), + branding: optional(BrandingSchema), + isSnap: optional(boolean()), + isCrossword: optional(boolean()), + snapData: optional(DCRSnapTypeSchema), + showQuotedHeadline: optional(boolean()), + discussion: optional(DiscussionSchema), + mainMedia: optional(MainMediaSchema), +}); export interface TrailType extends BaseTrailType { palette?: never; @@ -45,23 +62,28 @@ export interface TrailType extends BaseTrailType { image?: DCRFrontImage; } -export interface FETrailType extends BaseTrailType { - format: FEFormat; +export type FETrailType = Output; + +export const FETrailTypeSchema = object({ + ...BaseTrailTypeSchema.entries, + format: FEFormatSchema, /** * @deprecated This type must exist as it's passed by frontend, but we shouldn't use it. * We should remove this property upstream in the future */ - designType?: string; + designType: optional(string()), /** * @deprecated This type must exist as it's passed by frontend, but we shouldn't use it. * We should remove this property upstream in the future */ - pillar?: string; - carouselImages?: { [key: string]: string }; - isLiveBlog?: boolean; - masterImage?: string; - image?: string; -} + pillar: optional(string()), + carouselImages: optional(record(string(), string())), + isLiveBlog: optional(boolean()), + masterImage: optional(string()), + image: optional(string()), +}); + +// export type FETrailType = Output; // TODO export interface TrailTabType { heading: string;