@financial-times/cp-content-pipeline-schema 3.16.0 → 3.17.0

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.
Files changed (31) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/lib/generated/index.d.ts +19 -2
  3. package/lib/resolvers/content-tree/Workarounds.d.ts +2 -2
  4. package/lib/resolvers/content-tree/nodePredicates.d.ts +1 -1
  5. package/lib/resolvers/content-tree/nodePredicates.js +1 -0
  6. package/lib/resolvers/content-tree/nodePredicates.js.map +1 -1
  7. package/lib/resolvers/content-tree/references/RecommendedList.d.ts +5 -0
  8. package/lib/resolvers/content-tree/references/RecommendedList.js +41 -0
  9. package/lib/resolvers/content-tree/references/RecommendedList.js.map +1 -0
  10. package/lib/resolvers/content-tree/references/Reference.d.ts +1 -1
  11. package/lib/resolvers/content-tree/references/index.d.ts +3 -1
  12. package/lib/resolvers/content-tree/references/index.js +3 -0
  13. package/lib/resolvers/content-tree/references/index.js.map +1 -1
  14. package/lib/resolvers/content-tree/tagMappings.js +19 -0
  15. package/lib/resolvers/content-tree/tagMappings.js.map +1 -1
  16. package/lib/resolvers/index.d.ts +2 -0
  17. package/lib/resolvers/teaser.d.ts +1 -0
  18. package/lib/resolvers/teaser.js +1 -0
  19. package/lib/resolvers/teaser.js.map +1 -1
  20. package/package.json +2 -2
  21. package/queries/article.graphql +9 -0
  22. package/src/generated/index.ts +21 -2
  23. package/src/resolvers/content-tree/Workarounds.ts +2 -0
  24. package/src/resolvers/content-tree/nodePredicates.ts +1 -0
  25. package/src/resolvers/content-tree/references/RecommendedList.ts +52 -0
  26. package/src/resolvers/content-tree/references/index.ts +5 -0
  27. package/src/resolvers/content-tree/tagMappings.ts +22 -0
  28. package/src/resolvers/teaser.ts +1 -0
  29. package/tsconfig.tsbuildinfo +1 -1
  30. package/typedefs/references/recommendedList.graphql +7 -0
  31. package/typedefs/teaser.graphql +3 -0
@@ -0,0 +1,52 @@
1
+ import { uuidFromUrl } from '../../../helpers/metadata'
2
+ import { RecommendedListResolvers } from '../../../generated'
3
+ import { OperationalError } from '@dotcom-reliability-kit/errors'
4
+ import { ContentTree } from '@financial-times/content-tree'
5
+ import { Logger } from '@dotcom-reliability-kit/logger'
6
+ import { CapiDataSource } from '../../../datasources/capi'
7
+
8
+ function getTeaser(context: {
9
+ logger: Logger
10
+ dataSources: { capi: CapiDataSource }
11
+ }) {
12
+ return async function (child: ContentTree.Recommended) {
13
+ try {
14
+ let content = await context.dataSources.capi.getContent(
15
+ uuidFromUrl(child.id)
16
+ )
17
+
18
+ if (!content) {
19
+ throw new Error('Invalid content from recommended article teaser')
20
+ }
21
+
22
+ if (child.teaserTitleOverride) {
23
+ content = content.overrideTitle(child.teaserTitleOverride)
24
+ }
25
+ return content
26
+ } catch (error) {
27
+ if (error instanceof Error) {
28
+ context.logger.warn({
29
+ event: 'RECOVERABLE_ERROR',
30
+ error: new OperationalError({
31
+ code: 'RECOMMENDED_TEASER_ERROR',
32
+ message: `Couldn't load teaser for recommended article ${child.id}`,
33
+ cause: error,
34
+ }),
35
+ })
36
+ }
37
+ }
38
+ }
39
+ }
40
+
41
+ export const RecommendedList = {
42
+ async teasers(parent, _args, context) {
43
+ const responses = await Promise.all(
44
+ parent.reference.children.map(getTeaser(context))
45
+ )
46
+
47
+ return responses.filter((response) => response !== undefined)
48
+ },
49
+ type(parent) {
50
+ return parent.reference.type
51
+ },
52
+ } satisfies RecommendedListResolvers
@@ -10,6 +10,7 @@ import { CustomCodeComponent } from './CustomCodeComponent'
10
10
  import { Video } from './Video'
11
11
  import { Flourish, FlourishSource } from './Flourish'
12
12
  import { Recommended } from './Recommended'
13
+ import { RecommendedList } from './RecommendedList'
13
14
  import { LayoutImage } from './LayoutImage'
14
15
  import { RawImage } from './RawImage'
15
16
  import { ScrollyImage } from './ScrollyImage'
@@ -21,6 +22,7 @@ import {
21
22
  LayoutImageResolvers,
22
23
  RawImageResolvers,
23
24
  RecommendedResolvers,
25
+ RecommendedListResolvers,
24
26
  ReferenceResolvers,
25
27
  ScrollyImageResolvers,
26
28
  TweetResolvers,
@@ -48,6 +50,7 @@ export const resolvers: {
48
50
  Flourish: FlourishResolvers
49
51
  FlourishSource: FlourishSourceResolvers
50
52
  Recommended: RecommendedResolvers
53
+ RecommendedList: RecommendedListResolvers
51
54
  LayoutImage: LayoutImageResolvers
52
55
  RawImage: RawImageResolvers
53
56
  ScrollyImage: ScrollyImageResolvers
@@ -65,6 +68,7 @@ export const resolvers: {
65
68
  Flourish,
66
69
  FlourishSource,
67
70
  Recommended,
71
+ RecommendedList,
68
72
  LayoutImage,
69
73
  RawImage,
70
74
  ScrollyImage,
@@ -83,6 +87,7 @@ export const mapNodeToReference = {
83
87
  'custom-code-component': 'CustomCodeComponent',
84
88
  video: 'VideoReference',
85
89
  recommended: 'Recommended',
90
+ 'recommended-list': 'RecommendedList',
86
91
  'layout-image': 'LayoutImage',
87
92
  'scrolly-image': 'ScrollyImage',
88
93
  'raw-image': 'RawImage',
@@ -9,6 +9,7 @@ import {
9
9
  TableChildren,
10
10
  TableColumnSettings,
11
11
  TableFooter,
12
+ Recommended,
12
13
  } from './Workarounds'
13
14
 
14
15
  import {
@@ -303,6 +304,27 @@ const commonTagMappings: TagMappings = {
303
304
  teaserTitleOverride: $firstLink.text(),
304
305
  }
305
306
  },
307
+ 'recommended-list': ($el) => {
308
+ const title = $el.find('recommended-title').first().text()
309
+ const items = $el
310
+ .find('ft-content')
311
+ .toArray()
312
+ .map((item) => {
313
+ const $item = $el.find(item)
314
+
315
+ return {
316
+ id: $item.attr('url') || '',
317
+ type: 'recommended',
318
+ teaserTitleOverride: $item.text(),
319
+ }
320
+ }) as Recommended[]
321
+
322
+ return {
323
+ type: 'recommended-list',
324
+ heading: title || 'Related content',
325
+ children: items,
326
+ }
327
+ },
306
328
  'big-number': ($el) => {
307
329
  const $number = $el.find('big-number-headline').first()
308
330
  const $description = $el.find('big-number-intro').first()
@@ -33,6 +33,7 @@ const resolvers = {
33
33
  publishedDate: (parent) => parent.publishedDate(),
34
34
  theme: (parent) => parent.design().theme,
35
35
  title: (parent) => parent.title(),
36
+ clientName: (parent) => parent.clientName?.(),
36
37
  },
37
38
  TeaserIndicators: {
38
39
  accessLevel: (parent) => parent.accessLevel,