@financial-times/cp-content-pipeline-schema 3.4.0 → 3.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +33 -0
- package/lib/datasources/capi.d.ts +0 -2
- package/lib/datasources/capi.js +10 -23
- package/lib/datasources/capi.js.map +1 -1
- package/lib/datasources/instrumented.js +4 -1
- package/lib/datasources/instrumented.js.map +1 -1
- package/lib/datasources/origami-image.d.ts +0 -2
- package/lib/datasources/origami-image.js +5 -19
- package/lib/datasources/origami-image.js.map +1 -1
- package/lib/datasources/twitter.d.ts +0 -2
- package/lib/datasources/twitter.js +2 -16
- package/lib/datasources/twitter.js.map +1 -1
- package/lib/datasources/url-management.js +5 -3
- package/lib/datasources/url-management.js.map +1 -1
- package/lib/fixtures/dummyContext.js +1 -1
- package/lib/generated/index.d.ts +73 -22
- package/lib/index.d.ts +1 -0
- package/lib/index.js.map +1 -1
- package/lib/model/Byline.js +11 -14
- package/lib/model/Byline.js.map +1 -1
- package/lib/model/CapiList.js +2 -0
- package/lib/model/CapiList.js.map +1 -1
- package/lib/model/CapiResponse.d.ts +7 -3
- package/lib/model/CapiResponse.js +125 -57
- package/lib/model/CapiResponse.js.map +1 -1
- package/lib/model/CapiResponse.test.js +92 -7
- package/lib/model/CapiResponse.test.js.map +1 -1
- package/lib/model/Clip.js +2 -0
- package/lib/model/Clip.js.map +1 -1
- package/lib/model/Concept.js +4 -10
- package/lib/model/Concept.js.map +1 -1
- package/lib/model/FlourishSource.d.ts +12 -5
- package/lib/model/FlourishSource.js +37 -38
- package/lib/model/FlourishSource.js.map +1 -1
- package/lib/model/FlourishSource.test.js +5 -5
- package/lib/model/FlourishSource.test.js.map +1 -1
- package/lib/model/Image.js +22 -20
- package/lib/model/Image.js.map +1 -1
- package/lib/model/LeadFlourish.d.ts +1 -1
- package/lib/model/LeadFlourish.js +8 -11
- package/lib/model/LeadFlourish.js.map +1 -1
- package/lib/model/LeadFlourish.test.js +5 -7
- package/lib/model/LeadFlourish.test.js.map +1 -1
- package/lib/model/Person.js +5 -16
- package/lib/model/Person.js.map +1 -1
- package/lib/model/Picture.js +3 -0
- package/lib/model/Picture.js.map +1 -1
- package/lib/model/RichText.js +3 -0
- package/lib/model/RichText.js.map +1 -1
- package/lib/model/Topper.js +5 -16
- package/lib/model/Topper.js.map +1 -1
- package/lib/model/schemas/capi/article.d.ts +3 -3
- package/lib/model/schemas/capi/audio.d.ts +5 -5
- package/lib/model/schemas/capi/base-schema.d.ts +5 -5
- package/lib/model/schemas/capi/base-schema.js +1 -1
- package/lib/model/schemas/capi/base-schema.js.map +1 -1
- package/lib/model/schemas/capi/content-package.d.ts +3 -3
- package/lib/model/schemas/capi/custom-code-component.d.ts +3 -3
- package/lib/model/schemas/capi/index.d.ts +20 -20
- package/lib/model/schemas/capi/internal-content.d.ts +1 -1
- package/lib/model/schemas/capi/live-blog-package.d.ts +3 -3
- package/lib/model/schemas/capi/placeholder.d.ts +3 -3
- package/lib/model/schemas/capi/video.d.ts +3 -3
- package/lib/resolvers/content-tree/references/Flourish.d.ts +9 -19
- package/lib/resolvers/content-tree/references/Flourish.js +10 -32
- package/lib/resolvers/content-tree/references/Flourish.js.map +1 -1
- package/lib/resolvers/content-tree/references/Flourish.test.js +3 -3
- package/lib/resolvers/content-tree/references/Flourish.test.js.map +1 -1
- package/lib/resolvers/content-tree/references/RawImage.js +2 -0
- package/lib/resolvers/content-tree/references/RawImage.js.map +1 -1
- package/lib/resolvers/content-tree/references/index.d.ts +2 -2
- package/lib/resolvers/content-tree/references/index.js +1 -1
- package/lib/resolvers/content-tree/references/index.js.map +1 -1
- package/lib/resolvers/content.d.ts +26 -1
- package/lib/resolvers/content.js +21 -1
- package/lib/resolvers/content.js.map +1 -1
- package/lib/resolvers/index.d.ts +27 -3
- package/lib/resolvers/leadFlourish.d.ts +1 -1
- package/lib/resolvers/literal-union.js +1 -0
- package/lib/resolvers/literal-union.js.map +1 -1
- package/lib/types/connection.d.ts +21 -0
- package/lib/types/connection.js +5 -0
- package/lib/types/connection.js.map +1 -0
- package/package.json +1 -1
- package/queries/article.graphql +8 -2
- package/src/datasources/capi.ts +1 -14
- package/src/datasources/origami-image.ts +1 -13
- package/src/datasources/twitter.ts +1 -14
- package/src/fixtures/dummyContext.ts +1 -1
- package/src/generated/index.ts +75 -24
- package/src/index.ts +1 -0
- package/src/model/CapiResponse.test.ts +137 -7
- package/src/model/CapiResponse.ts +129 -37
- package/src/model/FlourishSource.test.ts +5 -5
- package/src/model/FlourishSource.ts +57 -39
- package/src/model/Image.ts +16 -0
- package/src/model/LeadFlourish.test.ts +6 -9
- package/src/model/LeadFlourish.ts +5 -1
- package/src/model/schemas/capi/base-schema.ts +1 -1
- package/src/model/schemas/capi/internal-content.ts +1 -1
- package/src/resolvers/content-tree/references/Flourish.test.ts +4 -3
- package/src/resolvers/content-tree/references/Flourish.ts +16 -32
- package/src/resolvers/content-tree/references/index.ts +4 -4
- package/src/resolvers/content.ts +31 -1
- package/src/types/connection.ts +28 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/typedefs/content.graphql +40 -2
- package/typedefs/leadFlourish.graphql +1 -1
- package/typedefs/references/flourish.graphql +1 -11
- package/lib/helpers/timeout-error.d.ts +0 -6
- package/lib/helpers/timeout-error.js +0 -15
- package/lib/helpers/timeout-error.js.map +0 -1
- package/src/helpers/timeout-error.ts +0 -13
package/src/generated/index.ts
CHANGED
|
@@ -513,6 +513,20 @@ export type ContentUrlArgs = {
|
|
|
513
513
|
vanity?: InputMaybe<Scalars['Boolean']['input']>;
|
|
514
514
|
};
|
|
515
515
|
|
|
516
|
+
export type ContentConnection = {
|
|
517
|
+
/** A list of edges for the connection. */
|
|
518
|
+
readonly edges: ReadonlyArray<Maybe<ContentEdge>>;
|
|
519
|
+
/** Pagination data for the connection. */
|
|
520
|
+
readonly pageInfo: PageInfo;
|
|
521
|
+
};
|
|
522
|
+
|
|
523
|
+
export type ContentEdge = {
|
|
524
|
+
/** The opaque cursor for this edge that can be used for future requests. */
|
|
525
|
+
readonly cursor: Scalars['String']['output'];
|
|
526
|
+
/** The child article of this edge. */
|
|
527
|
+
readonly node?: Maybe<Content>;
|
|
528
|
+
};
|
|
529
|
+
|
|
516
530
|
export type ContentPackage = Content & {
|
|
517
531
|
/** A scalar representing the access level of the article, eg. 'free'. */
|
|
518
532
|
readonly accessLevel?: Maybe<Scalars['AccessLevel']['output']>;
|
|
@@ -680,20 +694,11 @@ export type Design = {
|
|
|
680
694
|
|
|
681
695
|
export type Flourish = Reference & {
|
|
682
696
|
/** The fallback image to be used if the flourish graphics cannot be loaded. */
|
|
683
|
-
readonly fallbackImage?: Maybe<
|
|
697
|
+
readonly fallbackImage?: Maybe<FlourishSource>;
|
|
684
698
|
/** The type of the reference, eg. 'flourish'. */
|
|
685
699
|
readonly type: Scalars['String']['output'];
|
|
686
700
|
};
|
|
687
701
|
|
|
688
|
-
export type FlourishFallback = {
|
|
689
|
-
/** The height in pixels of the fallback image. */
|
|
690
|
-
readonly height?: Maybe<Scalars['Int']['output']>;
|
|
691
|
-
/** The url of the fallback image. */
|
|
692
|
-
readonly url?: Maybe<Scalars['String']['output']>;
|
|
693
|
-
/** The width in pixels of the fallback image. */
|
|
694
|
-
readonly width?: Maybe<Scalars['Int']['output']>;
|
|
695
|
-
};
|
|
696
|
-
|
|
697
702
|
export type FlourishSource = {
|
|
698
703
|
/** The format of the source, eg. 'standard'. */
|
|
699
704
|
readonly format: Scalars['ImageFormat']['output'];
|
|
@@ -1061,7 +1066,7 @@ export type LayoutImage = Reference & {
|
|
|
1061
1066
|
export type LeadFlourish = {
|
|
1062
1067
|
/** The description of the Flourish chart. */
|
|
1063
1068
|
readonly description?: Maybe<Scalars['String']['output']>;
|
|
1064
|
-
readonly fallbackImage
|
|
1069
|
+
readonly fallbackImage?: Maybe<FlourishSource>;
|
|
1065
1070
|
/** The id of the Flourish chart. */
|
|
1066
1071
|
readonly id?: Maybe<Scalars['String']['output']>;
|
|
1067
1072
|
/** The type of the chart, eg. 'visualisation'. */
|
|
@@ -1120,6 +1125,8 @@ export type LiveBlogPackage = Content & {
|
|
|
1120
1125
|
readonly instantAlertConcept?: Maybe<Concept>;
|
|
1121
1126
|
/** The child articles of this live blog package. */
|
|
1122
1127
|
readonly liveBlogPosts?: Maybe<ReadonlyArray<Maybe<Content>>>;
|
|
1128
|
+
/** The child articles of this live blog package following the [Connections](https://relay.dev/graphql/connections.htm) spec. */
|
|
1129
|
+
readonly liveBlogPostsConnection?: Maybe<ContentConnection>;
|
|
1123
1130
|
/** An image object containing the url and the caption, to be displayed usually before the article content. */
|
|
1124
1131
|
readonly mainImage?: Maybe<Image>;
|
|
1125
1132
|
/** The number of milliseconds since the unix epoch the article was last changed, eg '1712140552443'. */
|
|
@@ -1161,6 +1168,19 @@ export type LiveBlogPackageBylineArgs = {
|
|
|
1161
1168
|
};
|
|
1162
1169
|
|
|
1163
1170
|
|
|
1171
|
+
export type LiveBlogPackageLiveBlogPostsArgs = {
|
|
1172
|
+
count?: InputMaybe<Scalars['Int']['input']>;
|
|
1173
|
+
};
|
|
1174
|
+
|
|
1175
|
+
|
|
1176
|
+
export type LiveBlogPackageLiveBlogPostsConnectionArgs = {
|
|
1177
|
+
after?: InputMaybe<Scalars['String']['input']>;
|
|
1178
|
+
before?: InputMaybe<Scalars['String']['input']>;
|
|
1179
|
+
first?: InputMaybe<Scalars['Int']['input']>;
|
|
1180
|
+
last?: InputMaybe<Scalars['Int']['input']>;
|
|
1181
|
+
};
|
|
1182
|
+
|
|
1183
|
+
|
|
1164
1184
|
export type LiveBlogPackageUrlArgs = {
|
|
1165
1185
|
relative?: InputMaybe<Scalars['Boolean']['input']>;
|
|
1166
1186
|
vanity?: InputMaybe<Scalars['Boolean']['input']>;
|
|
@@ -1312,6 +1332,17 @@ export type OpinionTopperHeadshotArgs = {
|
|
|
1312
1332
|
width?: InputMaybe<Scalars['Int']['input']>;
|
|
1313
1333
|
};
|
|
1314
1334
|
|
|
1335
|
+
export type PageInfo = {
|
|
1336
|
+
/** The cursor for the last edge. */
|
|
1337
|
+
readonly endCursor?: Maybe<Scalars['String']['output']>;
|
|
1338
|
+
/** Whether a subsequent page of edges is available on request. */
|
|
1339
|
+
readonly hasNextPage: Scalars['Boolean']['output'];
|
|
1340
|
+
/** Whether a previous page of edges is available on request. */
|
|
1341
|
+
readonly hasPreviousPage: Scalars['Boolean']['output'];
|
|
1342
|
+
/** The cursor for the first edge. */
|
|
1343
|
+
readonly startCursor?: Maybe<Scalars['String']['output']>;
|
|
1344
|
+
};
|
|
1345
|
+
|
|
1315
1346
|
export type PartnerContentTopper = Topper & TopperWithImages & TopperWithTheme & {
|
|
1316
1347
|
/** Whether the topper should have a background box. */
|
|
1317
1348
|
readonly backgroundBox?: Maybe<Scalars['Boolean']['output']>;
|
|
@@ -1976,6 +2007,8 @@ export type ResolversTypes = ResolversObject<{
|
|
|
1976
2007
|
Concept: ResolverTypeWrapper<ConceptModel>;
|
|
1977
2008
|
ConceptInterface: ResolverTypeWrapper<ConceptModel>;
|
|
1978
2009
|
Content: ResolverTypeWrapper<ResolversInterfaceTypes<ResolversTypes>['Content']>;
|
|
2010
|
+
ContentConnection: ResolverTypeWrapper<Omit<ContentConnection, 'edges'> & { edges: ReadonlyArray<Maybe<ResolversTypes['ContentEdge']>> }>;
|
|
2011
|
+
ContentEdge: ResolverTypeWrapper<Omit<ContentEdge, 'node'> & { node: Maybe<ResolversTypes['Content']> }>;
|
|
1979
2012
|
ContentPackage: ResolverTypeWrapper<CapiResponse>;
|
|
1980
2013
|
ContentType: ResolverTypeWrapper<Scalars['ContentType']['output']>;
|
|
1981
2014
|
CustomCodeComponent: ResolverTypeWrapper<ReferenceWithCAPIData<ContentTree.CustomCodeComponent>>;
|
|
@@ -1984,7 +2017,6 @@ export type ResolversTypes = ResolversObject<{
|
|
|
1984
2017
|
Design: ResolverTypeWrapper<Design>;
|
|
1985
2018
|
Float: ResolverTypeWrapper<Scalars['Float']['output']>;
|
|
1986
2019
|
Flourish: ResolverTypeWrapper<ReferenceWithCAPIData<ContentTree.Flourish>>;
|
|
1987
|
-
FlourishFallback: ResolverTypeWrapper<FlourishFallback>;
|
|
1988
2020
|
FlourishSource: ResolverTypeWrapper<FlourishSourceModel>;
|
|
1989
2021
|
FollowButtonVariant: ResolverTypeWrapper<Scalars['FollowButtonVariant']['output']>;
|
|
1990
2022
|
FullBleedTopper: ResolverTypeWrapper<TopperModel>;
|
|
@@ -2019,6 +2051,7 @@ export type ResolversTypes = ResolversObject<{
|
|
|
2019
2051
|
Mutation: ResolverTypeWrapper<{}>;
|
|
2020
2052
|
OpinionTopper: ResolverTypeWrapper<TopperModel>;
|
|
2021
2053
|
PackageDesign: ResolverTypeWrapper<Scalars['PackageDesign']['output']>;
|
|
2054
|
+
PageInfo: ResolverTypeWrapper<PageInfo>;
|
|
2022
2055
|
PartnerContentTopper: ResolverTypeWrapper<TopperModel>;
|
|
2023
2056
|
Person: ResolverTypeWrapper<PersonModel>;
|
|
2024
2057
|
Picture: ResolverTypeWrapper<PictureModel>;
|
|
@@ -2075,6 +2108,8 @@ export type ResolversParentTypes = ResolversObject<{
|
|
|
2075
2108
|
Concept: ConceptModel;
|
|
2076
2109
|
ConceptInterface: ConceptModel;
|
|
2077
2110
|
Content: ResolversInterfaceTypes<ResolversParentTypes>['Content'];
|
|
2111
|
+
ContentConnection: Omit<ContentConnection, 'edges'> & { edges: ReadonlyArray<Maybe<ResolversParentTypes['ContentEdge']>> };
|
|
2112
|
+
ContentEdge: Omit<ContentEdge, 'node'> & { node: Maybe<ResolversParentTypes['Content']> };
|
|
2078
2113
|
ContentPackage: CapiResponse;
|
|
2079
2114
|
ContentType: Scalars['ContentType']['output'];
|
|
2080
2115
|
CustomCodeComponent: ReferenceWithCAPIData<ContentTree.CustomCodeComponent>;
|
|
@@ -2083,7 +2118,6 @@ export type ResolversParentTypes = ResolversObject<{
|
|
|
2083
2118
|
Design: Design;
|
|
2084
2119
|
Float: Scalars['Float']['output'];
|
|
2085
2120
|
Flourish: ReferenceWithCAPIData<ContentTree.Flourish>;
|
|
2086
|
-
FlourishFallback: FlourishFallback;
|
|
2087
2121
|
FlourishSource: FlourishSourceModel;
|
|
2088
2122
|
FollowButtonVariant: Scalars['FollowButtonVariant']['output'];
|
|
2089
2123
|
FullBleedTopper: TopperModel;
|
|
@@ -2118,6 +2152,7 @@ export type ResolversParentTypes = ResolversObject<{
|
|
|
2118
2152
|
Mutation: {};
|
|
2119
2153
|
OpinionTopper: TopperModel;
|
|
2120
2154
|
PackageDesign: Scalars['PackageDesign']['output'];
|
|
2155
|
+
PageInfo: PageInfo;
|
|
2121
2156
|
PartnerContentTopper: TopperModel;
|
|
2122
2157
|
Person: PersonModel;
|
|
2123
2158
|
Picture: PictureModel;
|
|
@@ -2396,6 +2431,18 @@ export type ContentResolvers<ContextType = QueryContext, ParentType extends Reso
|
|
|
2396
2431
|
url: Resolver<ResolversTypes['String'], ParentType, ContextType, Partial<ContentUrlArgs>>;
|
|
2397
2432
|
}>;
|
|
2398
2433
|
|
|
2434
|
+
export type ContentConnectionResolvers<ContextType = QueryContext, ParentType extends ResolversParentTypes['ContentConnection'] = ResolversParentTypes['ContentConnection']> = ResolversObject<{
|
|
2435
|
+
edges: Resolver<ReadonlyArray<Maybe<ResolversTypes['ContentEdge']>>, ParentType, ContextType>;
|
|
2436
|
+
pageInfo: Resolver<ResolversTypes['PageInfo'], ParentType, ContextType>;
|
|
2437
|
+
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
|
|
2438
|
+
}>;
|
|
2439
|
+
|
|
2440
|
+
export type ContentEdgeResolvers<ContextType = QueryContext, ParentType extends ResolversParentTypes['ContentEdge'] = ResolversParentTypes['ContentEdge']> = ResolversObject<{
|
|
2441
|
+
cursor: Resolver<ResolversTypes['String'], ParentType, ContextType>;
|
|
2442
|
+
node: Resolver<Maybe<ResolversTypes['Content']>, ParentType, ContextType>;
|
|
2443
|
+
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
|
|
2444
|
+
}>;
|
|
2445
|
+
|
|
2399
2446
|
export type ContentPackageResolvers<ContextType = QueryContext, ParentType extends ResolversParentTypes['ContentPackage'] = ResolversParentTypes['ContentPackage']> = ResolversObject<{
|
|
2400
2447
|
accessLevel: Resolver<Maybe<ResolversTypes['AccessLevel']>, ParentType, ContextType>;
|
|
2401
2448
|
altStandfirst: Resolver<Maybe<ResolversTypes['AltStandfirst']>, ParentType, ContextType>;
|
|
@@ -2485,18 +2532,11 @@ export type DesignResolvers<ContextType = QueryContext, ParentType extends Resol
|
|
|
2485
2532
|
}>;
|
|
2486
2533
|
|
|
2487
2534
|
export type FlourishResolvers<ContextType = QueryContext, ParentType extends ResolversParentTypes['Flourish'] = ResolversParentTypes['Flourish']> = ResolversObject<{
|
|
2488
|
-
fallbackImage: Resolver<Maybe<ResolversTypes['
|
|
2535
|
+
fallbackImage: Resolver<Maybe<ResolversTypes['FlourishSource']>, ParentType, ContextType>;
|
|
2489
2536
|
type: Resolver<ResolversTypes['String'], ParentType, ContextType>;
|
|
2490
2537
|
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
|
|
2491
2538
|
}>;
|
|
2492
2539
|
|
|
2493
|
-
export type FlourishFallbackResolvers<ContextType = QueryContext, ParentType extends ResolversParentTypes['FlourishFallback'] = ResolversParentTypes['FlourishFallback']> = ResolversObject<{
|
|
2494
|
-
height: Resolver<Maybe<ResolversTypes['Int']>, ParentType, ContextType>;
|
|
2495
|
-
url: Resolver<Maybe<ResolversTypes['String']>, ParentType, ContextType>;
|
|
2496
|
-
width: Resolver<Maybe<ResolversTypes['Int']>, ParentType, ContextType>;
|
|
2497
|
-
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
|
|
2498
|
-
}>;
|
|
2499
|
-
|
|
2500
2540
|
export type FlourishSourceResolvers<ContextType = QueryContext, ParentType extends ResolversParentTypes['FlourishSource'] = ResolversParentTypes['FlourishSource']> = ResolversObject<{
|
|
2501
2541
|
format: Resolver<ResolversTypes['ImageFormat'], ParentType, ContextType>;
|
|
2502
2542
|
height: Resolver<ResolversTypes['Int'], ParentType, ContextType>;
|
|
@@ -2711,7 +2751,7 @@ export type LayoutImageResolvers<ContextType = QueryContext, ParentType extends
|
|
|
2711
2751
|
|
|
2712
2752
|
export type LeadFlourishResolvers<ContextType = QueryContext, ParentType extends ResolversParentTypes['LeadFlourish'] = ResolversParentTypes['LeadFlourish']> = ResolversObject<{
|
|
2713
2753
|
description: Resolver<Maybe<ResolversTypes['String']>, ParentType, ContextType>;
|
|
2714
|
-
fallbackImage: Resolver<ResolversTypes['FlourishSource']
|
|
2754
|
+
fallbackImage: Resolver<Maybe<ResolversTypes['FlourishSource']>, ParentType, ContextType>;
|
|
2715
2755
|
id: Resolver<Maybe<ResolversTypes['String']>, ParentType, ContextType>;
|
|
2716
2756
|
type: Resolver<Maybe<ResolversTypes['String']>, ParentType, ContextType>;
|
|
2717
2757
|
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
|
|
@@ -2749,7 +2789,8 @@ export type LiveBlogPackageResolvers<ContextType = QueryContext, ParentType exte
|
|
|
2749
2789
|
firstPublishedDate: Resolver<ResolversTypes['String'], ParentType, ContextType>;
|
|
2750
2790
|
id: Resolver<ResolversTypes['ID'], ParentType, ContextType>;
|
|
2751
2791
|
instantAlertConcept: Resolver<Maybe<ResolversTypes['Concept']>, ParentType, ContextType>;
|
|
2752
|
-
liveBlogPosts: Resolver<Maybe<ReadonlyArray<Maybe<ResolversTypes['Content']>>>, ParentType, ContextType
|
|
2792
|
+
liveBlogPosts: Resolver<Maybe<ReadonlyArray<Maybe<ResolversTypes['Content']>>>, ParentType, ContextType, Partial<LiveBlogPackageLiveBlogPostsArgs>>;
|
|
2793
|
+
liveBlogPostsConnection: Resolver<Maybe<ResolversTypes['ContentConnection']>, ParentType, ContextType, Partial<LiveBlogPackageLiveBlogPostsConnectionArgs>>;
|
|
2753
2794
|
mainImage: Resolver<Maybe<ResolversTypes['Image']>, ParentType, ContextType>;
|
|
2754
2795
|
modifiedTimestamp: Resolver<Maybe<ResolversTypes['Float']>, ParentType, ContextType>;
|
|
2755
2796
|
originatingParty: Resolver<Maybe<ResolversTypes['String']>, ParentType, ContextType>;
|
|
@@ -2843,6 +2884,14 @@ export interface PackageDesignScalarConfig extends GraphQLScalarTypeConfig<Resol
|
|
|
2843
2884
|
name: 'PackageDesign';
|
|
2844
2885
|
}
|
|
2845
2886
|
|
|
2887
|
+
export type PageInfoResolvers<ContextType = QueryContext, ParentType extends ResolversParentTypes['PageInfo'] = ResolversParentTypes['PageInfo']> = ResolversObject<{
|
|
2888
|
+
endCursor: Resolver<Maybe<ResolversTypes['String']>, ParentType, ContextType>;
|
|
2889
|
+
hasNextPage: Resolver<ResolversTypes['Boolean'], ParentType, ContextType>;
|
|
2890
|
+
hasPreviousPage: Resolver<ResolversTypes['Boolean'], ParentType, ContextType>;
|
|
2891
|
+
startCursor: Resolver<Maybe<ResolversTypes['String']>, ParentType, ContextType>;
|
|
2892
|
+
__isTypeOf?: IsTypeOfResolverFn<ParentType, ContextType>;
|
|
2893
|
+
}>;
|
|
2894
|
+
|
|
2846
2895
|
export type PartnerContentTopperResolvers<ContextType = QueryContext, ParentType extends ResolversParentTypes['PartnerContentTopper'] = ResolversParentTypes['PartnerContentTopper']> = ResolversObject<{
|
|
2847
2896
|
backgroundBox: Resolver<Maybe<ResolversTypes['Boolean']>, ParentType, ContextType>;
|
|
2848
2897
|
backgroundColour: Resolver<Maybe<ResolversTypes['TopperBackgroundColour']>, ParentType, ContextType>;
|
|
@@ -3183,6 +3232,8 @@ export type Resolvers<ContextType = QueryContext> = ResolversObject<{
|
|
|
3183
3232
|
Concept: ConceptResolvers<ContextType>;
|
|
3184
3233
|
ConceptInterface: ConceptInterfaceResolvers<ContextType>;
|
|
3185
3234
|
Content: ContentResolvers<ContextType>;
|
|
3235
|
+
ContentConnection: ContentConnectionResolvers<ContextType>;
|
|
3236
|
+
ContentEdge: ContentEdgeResolvers<ContextType>;
|
|
3186
3237
|
ContentPackage: ContentPackageResolvers<ContextType>;
|
|
3187
3238
|
ContentType: GraphQLScalarType;
|
|
3188
3239
|
CustomCodeComponent: CustomCodeComponentResolvers<ContextType>;
|
|
@@ -3190,7 +3241,6 @@ export type Resolvers<ContextType = QueryContext> = ResolversObject<{
|
|
|
3190
3241
|
DeepPortraitTopper: DeepPortraitTopperResolvers<ContextType>;
|
|
3191
3242
|
Design: DesignResolvers<ContextType>;
|
|
3192
3243
|
Flourish: FlourishResolvers<ContextType>;
|
|
3193
|
-
FlourishFallback: FlourishFallbackResolvers<ContextType>;
|
|
3194
3244
|
FlourishSource: FlourishSourceResolvers<ContextType>;
|
|
3195
3245
|
FollowButtonVariant: GraphQLScalarType;
|
|
3196
3246
|
FullBleedTopper: FullBleedTopperResolvers<ContextType>;
|
|
@@ -3223,6 +3273,7 @@ export type Resolvers<ContextType = QueryContext> = ResolversObject<{
|
|
|
3223
3273
|
Mutation: MutationResolvers<ContextType>;
|
|
3224
3274
|
OpinionTopper: OpinionTopperResolvers<ContextType>;
|
|
3225
3275
|
PackageDesign: GraphQLScalarType;
|
|
3276
|
+
PageInfo: PageInfoResolvers<ContextType>;
|
|
3226
3277
|
PartnerContentTopper: PartnerContentTopperResolvers<ContextType>;
|
|
3227
3278
|
Person: PersonResolvers<ContextType>;
|
|
3228
3279
|
Picture: PictureResolvers<ContextType>;
|
package/src/index.ts
CHANGED
|
@@ -2,7 +2,6 @@ import { CapiResponse } from './CapiResponse'
|
|
|
2
2
|
import { baseCapiObject } from '../fixtures/capiObject'
|
|
3
3
|
import cloneDeep from 'clone-deep'
|
|
4
4
|
import context from '../fixtures/dummyContext'
|
|
5
|
-
import TimeoutError from '../helpers/timeout-error'
|
|
6
5
|
|
|
7
6
|
describe('CAPI response', () => {
|
|
8
7
|
describe('Content ID', () => {
|
|
@@ -70,7 +69,7 @@ describe('CAPI response', () => {
|
|
|
70
69
|
})
|
|
71
70
|
|
|
72
71
|
describe('liveBlogPosts', () => {
|
|
73
|
-
test('returns a resolved array of the articles contained
|
|
72
|
+
test('returns a resolved array of the articles contained', async () => {
|
|
74
73
|
const liveBlogPackage = cloneDeep({
|
|
75
74
|
...baseCapiObject,
|
|
76
75
|
type: 'http://www.ft.com/ontology/content/LiveBlogPackage',
|
|
@@ -81,14 +80,14 @@ describe('CAPI response', () => {
|
|
|
81
80
|
'http://api.ft.com/content/000000000-0000-0000-0000-000000000000',
|
|
82
81
|
},
|
|
83
82
|
{
|
|
84
|
-
id: 'http://api.ft.com/things/000000000-0000-0000-0000-
|
|
83
|
+
id: 'http://api.ft.com/things/000000000-0000-0000-0000-000000000001',
|
|
85
84
|
apiUrl:
|
|
86
|
-
'http://api.ft.com/content/000000000-0000-0000-0000-
|
|
85
|
+
'http://api.ft.com/content/000000000-0000-0000-0000-000000000001',
|
|
87
86
|
},
|
|
88
87
|
{
|
|
89
|
-
id: 'http://api.ft.com/things/000000000-0000-0000-0000-
|
|
88
|
+
id: 'http://api.ft.com/things/000000000-0000-0000-0000-000000000002',
|
|
90
89
|
apiUrl:
|
|
91
|
-
'http://api.ft.com/content/000000000-0000-0000-0000-
|
|
90
|
+
'http://api.ft.com/content/000000000-0000-0000-0000-000000000002',
|
|
92
91
|
},
|
|
93
92
|
],
|
|
94
93
|
})
|
|
@@ -107,6 +106,137 @@ describe('CAPI response', () => {
|
|
|
107
106
|
})
|
|
108
107
|
})
|
|
109
108
|
|
|
109
|
+
describe('liveBlogPostsConnection', () => {
|
|
110
|
+
const generateId = (i: number) =>
|
|
111
|
+
'00000000-0000-0000-0000-0000000000' + String(i).padStart(2, '0')
|
|
112
|
+
|
|
113
|
+
const postCount = 100
|
|
114
|
+
const liveBlogPackage = cloneDeep({
|
|
115
|
+
...baseCapiObject,
|
|
116
|
+
type: 'http://www.ft.com/ontology/content/LiveBlogPackage',
|
|
117
|
+
contains: [...Array(postCount).keys()].map((i) => {
|
|
118
|
+
const id = generateId(postCount - 1 - i)
|
|
119
|
+
return {
|
|
120
|
+
id: 'http://api.ft.com/things/' + id,
|
|
121
|
+
apiUrl: 'http://api.ft.com/content/' + id,
|
|
122
|
+
}
|
|
123
|
+
}),
|
|
124
|
+
})
|
|
125
|
+
const capiResponse = new CapiResponse(liveBlogPackage, context)
|
|
126
|
+
|
|
127
|
+
test('returns all posts when no argument specified', async () => {
|
|
128
|
+
const liveBlogPostsConnection =
|
|
129
|
+
await capiResponse.liveBlogPostsConnection({})
|
|
130
|
+
expect(liveBlogPostsConnection.edges).toHaveLength(postCount)
|
|
131
|
+
liveBlogPostsConnection.edges.forEach((edge, i) =>
|
|
132
|
+
expect(edge.node.id()).toEqual(generateId(i))
|
|
133
|
+
)
|
|
134
|
+
expect(liveBlogPostsConnection.pageInfo).toEqual(
|
|
135
|
+
expect.objectContaining({
|
|
136
|
+
hasPreviousPage: false,
|
|
137
|
+
hasNextPage: false,
|
|
138
|
+
})
|
|
139
|
+
)
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
test('returns first x edges', async () => {
|
|
143
|
+
const firstCount = 20
|
|
144
|
+
const liveBlogPostsConnection =
|
|
145
|
+
await capiResponse.liveBlogPostsConnection({ first: firstCount })
|
|
146
|
+
expect(liveBlogPostsConnection.edges).toHaveLength(firstCount)
|
|
147
|
+
liveBlogPostsConnection.edges.forEach((edge, i) =>
|
|
148
|
+
expect(edge.node.id()).toEqual(generateId(i))
|
|
149
|
+
)
|
|
150
|
+
expect(liveBlogPostsConnection.pageInfo).toEqual(
|
|
151
|
+
expect.objectContaining({
|
|
152
|
+
hasPreviousPage: false,
|
|
153
|
+
hasNextPage: true,
|
|
154
|
+
})
|
|
155
|
+
)
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
test('returns last x edges', async () => {
|
|
159
|
+
const lastCount = 20
|
|
160
|
+
const liveBlogPostsConnection =
|
|
161
|
+
await capiResponse.liveBlogPostsConnection({ last: lastCount })
|
|
162
|
+
expect(liveBlogPostsConnection.edges).toHaveLength(lastCount)
|
|
163
|
+
liveBlogPostsConnection.edges.forEach((edge, i) =>
|
|
164
|
+
expect(edge.node.id()).toEqual(generateId(i + (postCount - lastCount)))
|
|
165
|
+
)
|
|
166
|
+
expect(liveBlogPostsConnection.pageInfo).toEqual(
|
|
167
|
+
expect.objectContaining({
|
|
168
|
+
hasPreviousPage: true,
|
|
169
|
+
hasNextPage: false,
|
|
170
|
+
})
|
|
171
|
+
)
|
|
172
|
+
})
|
|
173
|
+
|
|
174
|
+
test('returns edges after cursor', async () => {
|
|
175
|
+
const firstCount = 20
|
|
176
|
+
const startingLiveBlogPostsConnection =
|
|
177
|
+
await capiResponse.liveBlogPostsConnection({ first: firstCount })
|
|
178
|
+
const cursor = startingLiveBlogPostsConnection.pageInfo.endCursor
|
|
179
|
+
expect(cursor).toBeDefined()
|
|
180
|
+
|
|
181
|
+
const liveBlogPostsConnection =
|
|
182
|
+
await capiResponse.liveBlogPostsConnection({
|
|
183
|
+
first: firstCount,
|
|
184
|
+
after: cursor,
|
|
185
|
+
})
|
|
186
|
+
expect(liveBlogPostsConnection.edges).toHaveLength(firstCount)
|
|
187
|
+
liveBlogPostsConnection.edges.forEach((edge, i) =>
|
|
188
|
+
expect(edge.node.id()).toEqual(generateId(i + firstCount))
|
|
189
|
+
)
|
|
190
|
+
expect(liveBlogPostsConnection.pageInfo).toEqual(
|
|
191
|
+
expect.objectContaining({
|
|
192
|
+
hasPreviousPage: true,
|
|
193
|
+
hasNextPage: true,
|
|
194
|
+
})
|
|
195
|
+
)
|
|
196
|
+
})
|
|
197
|
+
|
|
198
|
+
test('returns edges before cursor', async () => {
|
|
199
|
+
const lastCount = 20
|
|
200
|
+
const endingLiveBlogPostsConnection =
|
|
201
|
+
await capiResponse.liveBlogPostsConnection({ last: lastCount })
|
|
202
|
+
const cursor = endingLiveBlogPostsConnection.pageInfo.startCursor
|
|
203
|
+
expect(cursor).toBeDefined()
|
|
204
|
+
|
|
205
|
+
const liveBlogPostsConnection =
|
|
206
|
+
await capiResponse.liveBlogPostsConnection({
|
|
207
|
+
last: lastCount,
|
|
208
|
+
before: cursor,
|
|
209
|
+
})
|
|
210
|
+
expect(liveBlogPostsConnection.edges).toHaveLength(lastCount)
|
|
211
|
+
liveBlogPostsConnection.edges.forEach((edge, i) =>
|
|
212
|
+
expect(edge.node.id()).toEqual(
|
|
213
|
+
generateId(i + (postCount - lastCount * 2))
|
|
214
|
+
)
|
|
215
|
+
)
|
|
216
|
+
expect(liveBlogPostsConnection.pageInfo).toEqual(
|
|
217
|
+
expect.objectContaining({
|
|
218
|
+
hasPreviousPage: true,
|
|
219
|
+
hasNextPage: true,
|
|
220
|
+
})
|
|
221
|
+
)
|
|
222
|
+
})
|
|
223
|
+
|
|
224
|
+
test('returns all edges when first is greater than total posts', async () => {
|
|
225
|
+
const liveBlogPostsConnection =
|
|
226
|
+
await capiResponse.liveBlogPostsConnection({ first: postCount + 1 })
|
|
227
|
+
expect(liveBlogPostsConnection.edges).toHaveLength(postCount)
|
|
228
|
+
liveBlogPostsConnection.edges.forEach((edge, i) =>
|
|
229
|
+
expect(edge.node.id()).toEqual(generateId(i))
|
|
230
|
+
)
|
|
231
|
+
expect(liveBlogPostsConnection.pageInfo).toEqual(
|
|
232
|
+
expect.objectContaining({
|
|
233
|
+
hasPreviousPage: false,
|
|
234
|
+
hasNextPage: false,
|
|
235
|
+
})
|
|
236
|
+
)
|
|
237
|
+
})
|
|
238
|
+
})
|
|
239
|
+
|
|
110
240
|
describe('Partner content type articles', () => {
|
|
111
241
|
test('should have `isPartnerContent` set correctly as `true` when correct publication id is set', () => {
|
|
112
242
|
const article = cloneDeep({
|
|
@@ -137,7 +267,7 @@ describe('CAPI response', () => {
|
|
|
137
267
|
|
|
138
268
|
const timingOutContext = cloneDeep(context)
|
|
139
269
|
timingOutContext.dataSources.capi.getPerson = () =>
|
|
140
|
-
Promise.reject(new TimeoutError
|
|
270
|
+
Promise.reject(new DOMException(undefined, 'TimeoutError'))
|
|
141
271
|
const capiResponse = new CapiResponse(article, timingOutContext)
|
|
142
272
|
|
|
143
273
|
const authors = await capiResponse.authors()
|
|
@@ -4,6 +4,7 @@ import type {
|
|
|
4
4
|
MainImage,
|
|
5
5
|
ClipSet,
|
|
6
6
|
CustomCodeComponentReference,
|
|
7
|
+
LiveBlogPackage,
|
|
7
8
|
} from './schemas/capi/internal-content'
|
|
8
9
|
import conceptIds from '@financial-times/n-concept-ids'
|
|
9
10
|
import metadata from '@financial-times/n-display-metadata'
|
|
@@ -34,6 +35,7 @@ import {
|
|
|
34
35
|
ContentAnnotationsArgs,
|
|
35
36
|
ContentPackageContainsArgs,
|
|
36
37
|
ContentUrlArgs,
|
|
38
|
+
LiveBlogPackageLiveBlogPostsArgs,
|
|
37
39
|
Media,
|
|
38
40
|
TableOfContents,
|
|
39
41
|
} from '../generated'
|
|
@@ -42,6 +44,7 @@ import { z } from 'zod'
|
|
|
42
44
|
import { Byline } from './Byline'
|
|
43
45
|
import { RichText } from './RichText'
|
|
44
46
|
import flattenFormattedZodIssues from '../helpers/flatten-formatted-zod-errors'
|
|
47
|
+
import { Connection, ConnectionArguments } from '../types/connection'
|
|
45
48
|
|
|
46
49
|
type Design = {
|
|
47
50
|
theme: LiteralUnionScalarValues<typeof PackageDesign>
|
|
@@ -708,21 +711,54 @@ export class CapiResponse {
|
|
|
708
711
|
surroundingArticles,
|
|
709
712
|
fromId,
|
|
710
713
|
}: Partial<ContentPackageContainsArgs> = {}): Promise<CapiResponse[] | null> {
|
|
714
|
+
let edges
|
|
715
|
+
if (fromId && surroundingArticles) {
|
|
716
|
+
const afterId = await this.containsConnection({
|
|
717
|
+
after: fromId,
|
|
718
|
+
first: surroundingArticles,
|
|
719
|
+
})
|
|
720
|
+
const beforeAndIncludingId = await this.containsConnection({
|
|
721
|
+
before: afterId.pageInfo.startCursor,
|
|
722
|
+
last: surroundingArticles + 1,
|
|
723
|
+
})
|
|
724
|
+
edges = afterId.edges.concat(beforeAndIncludingId.edges)
|
|
725
|
+
} else {
|
|
726
|
+
const connection = await this.containsConnection()
|
|
727
|
+
edges = connection.edges
|
|
728
|
+
}
|
|
729
|
+
return edges.map((edge) => edge.node)
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
async containsConnection(
|
|
733
|
+
{ before, after, first, last }: ConnectionArguments = {},
|
|
734
|
+
transformer?: (
|
|
735
|
+
contains: LiveBlogPackage['contains']
|
|
736
|
+
) => LiveBlogPackage['contains']
|
|
737
|
+
): Promise<Connection<CapiResponse>> {
|
|
711
738
|
if ('contains' in this.capiData) {
|
|
712
|
-
const
|
|
713
|
-
|
|
739
|
+
const { contains: containsUntransformed } = this.capiData
|
|
740
|
+
const contains = transformer
|
|
741
|
+
? transformer(containsUntransformed)
|
|
742
|
+
: containsUntransformed
|
|
743
|
+
|
|
744
|
+
const beforeIndex = before
|
|
745
|
+
? contains.findLastIndex(
|
|
746
|
+
(post) => post.id === `http://api.ft.com/things/${before}`
|
|
747
|
+
)
|
|
748
|
+
: -1
|
|
749
|
+
const afterIndex = after
|
|
750
|
+
? contains.findIndex(
|
|
751
|
+
(post) => post.id === `http://api.ft.com/things/${after}`
|
|
752
|
+
)
|
|
753
|
+
: -1
|
|
754
|
+
const cursoredContains = contains.slice(
|
|
755
|
+
afterIndex >= 0 ? afterIndex + 1 : undefined,
|
|
756
|
+
beforeIndex >= 0 ? beforeIndex : undefined
|
|
714
757
|
)
|
|
715
|
-
|
|
716
|
-
const contains =
|
|
717
|
-
fromId && surroundingArticles
|
|
718
|
-
? this.capiData.contains.slice(
|
|
719
|
-
Math.max(0, fromIndex - surroundingArticles),
|
|
720
|
-
fromIndex + surroundingArticles
|
|
721
|
-
)
|
|
722
|
-
: this.capiData.contains
|
|
758
|
+
const slicedContains = cursoredContains.slice(-(last ?? 0), first)
|
|
723
759
|
|
|
724
760
|
const results = await Promise.allSettled(
|
|
725
|
-
|
|
761
|
+
slicedContains.map(({ id }) =>
|
|
726
762
|
this.context.dataSources.capi.getContent(uuidFromUrl(id), this)
|
|
727
763
|
)
|
|
728
764
|
)
|
|
@@ -741,17 +777,49 @@ export class CapiResponse {
|
|
|
741
777
|
cause: new AggregateError(failed.map((result) => result.reason)),
|
|
742
778
|
}),
|
|
743
779
|
})
|
|
780
|
+
|
|
781
|
+
if (
|
|
782
|
+
failed.some(
|
|
783
|
+
(result) =>
|
|
784
|
+
(result.reason as OperationalError).code === 'FETCH_TIMEOUT_ERROR'
|
|
785
|
+
)
|
|
786
|
+
) {
|
|
787
|
+
this.context.contentTimedOut = true
|
|
788
|
+
}
|
|
744
789
|
}
|
|
745
790
|
|
|
746
|
-
|
|
791
|
+
const edges = results
|
|
747
792
|
.filter(
|
|
748
793
|
(result): result is PromiseFulfilledResult<CapiResponse> =>
|
|
749
794
|
result.status === 'fulfilled'
|
|
750
795
|
)
|
|
751
|
-
.map((result) =>
|
|
796
|
+
.map((result) => {
|
|
797
|
+
const node = result.value
|
|
798
|
+
return { node, cursor: node.id() }
|
|
799
|
+
})
|
|
800
|
+
|
|
801
|
+
return {
|
|
802
|
+
edges,
|
|
803
|
+
pageInfo: {
|
|
804
|
+
hasPreviousPage: last
|
|
805
|
+
? cursoredContains.length > last
|
|
806
|
+
: afterIndex > 0,
|
|
807
|
+
hasNextPage: first
|
|
808
|
+
? cursoredContains.length > first
|
|
809
|
+
: beforeIndex > 0,
|
|
810
|
+
startCursor: edges[0]?.cursor,
|
|
811
|
+
endCursor: edges[edges.length - 1]?.cursor,
|
|
812
|
+
},
|
|
813
|
+
}
|
|
752
814
|
}
|
|
753
815
|
|
|
754
|
-
return
|
|
816
|
+
return {
|
|
817
|
+
edges: [],
|
|
818
|
+
pageInfo: {
|
|
819
|
+
hasPreviousPage: false,
|
|
820
|
+
hasNextPage: false,
|
|
821
|
+
},
|
|
822
|
+
}
|
|
755
823
|
}
|
|
756
824
|
|
|
757
825
|
containsLength() {
|
|
@@ -768,25 +836,37 @@ export class CapiResponse {
|
|
|
768
836
|
: null
|
|
769
837
|
}
|
|
770
838
|
|
|
771
|
-
|
|
772
|
-
|
|
839
|
+
private handleLiveBlogPosts(liveBlogPosts: LiveBlogPackage['contains']) {
|
|
840
|
+
this.context.addSurrogateKeys(
|
|
841
|
+
liveBlogPosts.map((article) => ({
|
|
842
|
+
prefix: 'contentPipelineArticle',
|
|
843
|
+
id: article.id,
|
|
844
|
+
}))
|
|
845
|
+
)
|
|
773
846
|
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
contains.map((article) => ({
|
|
777
|
-
prefix: 'contentPipelineArticle',
|
|
778
|
-
id: article.id(),
|
|
779
|
-
}))
|
|
780
|
-
)
|
|
847
|
+
return [...liveBlogPosts].reverse()
|
|
848
|
+
}
|
|
781
849
|
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
850
|
+
async liveBlogPosts(
|
|
851
|
+
args?: LiveBlogPackageLiveBlogPostsArgs
|
|
852
|
+
): Promise<CapiResponse[] | []> {
|
|
853
|
+
const containsConnections = await this.containsConnection(
|
|
854
|
+
{
|
|
855
|
+
first: args?.count ?? undefined,
|
|
856
|
+
},
|
|
857
|
+
this.handleLiveBlogPosts.bind(this)
|
|
858
|
+
)
|
|
859
|
+
const contains = containsConnections.edges.map((edge) => edge.node)
|
|
785
860
|
|
|
786
|
-
|
|
787
|
-
|
|
861
|
+
return contains.sort(
|
|
862
|
+
(a, b) => b.publishedTimestamp() - a.publishedTimestamp()
|
|
863
|
+
)
|
|
864
|
+
}
|
|
788
865
|
|
|
789
|
-
|
|
866
|
+
async liveBlogPostsConnection(
|
|
867
|
+
args: ConnectionArguments
|
|
868
|
+
): Promise<Connection<CapiResponse>> {
|
|
869
|
+
return this.containsConnection(args, this.handleLiveBlogPosts.bind(this))
|
|
790
870
|
}
|
|
791
871
|
|
|
792
872
|
isPinned() {
|
|
@@ -803,16 +883,28 @@ export class CapiResponse {
|
|
|
803
883
|
|
|
804
884
|
async pinnedPost(): Promise<CapiResponse | null> {
|
|
805
885
|
if ('pinnedPosts' in this.capiData) {
|
|
806
|
-
const pinnedPosts = this.capiData.pinnedPosts
|
|
807
|
-
const liveBlogPosts = await this.liveBlogPosts()
|
|
808
|
-
|
|
886
|
+
const pinnedPosts = this.capiData.pinnedPosts
|
|
809
887
|
const pinnedPostId = pinnedPosts[0]
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
888
|
+
if (!pinnedPostId) {
|
|
889
|
+
return null
|
|
890
|
+
}
|
|
813
891
|
|
|
814
|
-
|
|
815
|
-
return
|
|
892
|
+
try {
|
|
893
|
+
return await this.context.dataSources.capi.getContent(
|
|
894
|
+
uuidFromUrl(pinnedPostId),
|
|
895
|
+
this
|
|
896
|
+
)
|
|
897
|
+
} catch (error) {
|
|
898
|
+
if (isError(error)) {
|
|
899
|
+
this.context.logger.warn({
|
|
900
|
+
event: 'RECOVERABLE_ERROR',
|
|
901
|
+
error: new OperationalError({
|
|
902
|
+
code: 'PACKAGE_PINNED_POST_ERROR',
|
|
903
|
+
message: `Failed to fetch the pinned post ${pinnedPostId} contained in the package ${this.id()}`,
|
|
904
|
+
cause: error,
|
|
905
|
+
}),
|
|
906
|
+
})
|
|
907
|
+
}
|
|
816
908
|
}
|
|
817
909
|
}
|
|
818
910
|
return null
|