@financial-times/cp-content-pipeline-schema 2.9.1 → 2.9.2
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 +7 -0
- package/lib/model/CapiResponse.js +4 -3
- package/lib/model/CapiResponse.js.map +1 -1
- package/lib/model/CapiResponse.test.js +3 -3
- package/lib/model/CapiResponse.test.js.map +1 -1
- package/lib/model/Clip.js +1 -1
- package/lib/model/Clip.js.map +1 -1
- package/lib/model/Image.test.js +11 -11
- package/lib/model/Image.test.js.map +1 -1
- package/lib/model/RichText.test.js +4 -4
- package/lib/model/RichText.test.js.map +1 -1
- package/lib/model/Topper.js +2 -2
- package/lib/model/Topper.js.map +1 -1
- package/lib/resolvers/content-tree/bodyXMLToTree.js +8 -2
- package/lib/resolvers/content-tree/bodyXMLToTree.js.map +1 -1
- package/lib/resolvers/content-tree/tagMappings.js +7 -7
- package/lib/resolvers/content-tree/tagMappings.js.map +1 -1
- package/lib/resolvers/content-tree/tagMappings.test.js.map +1 -1
- package/package.json +1 -1
- package/src/model/CapiResponse.test.ts +3 -3
- package/src/model/CapiResponse.ts +6 -3
- package/src/model/Clip.ts +1 -1
- package/src/model/Image.test.ts +11 -11
- package/src/model/RichText.test.ts +4 -4
- package/src/model/Topper.ts +2 -2
- package/src/resolvers/content-tree/bodyXMLToTree.ts +13 -6
- package/src/resolvers/content-tree/tagMappings.test.ts +1 -1
- package/src/resolvers/content-tree/tagMappings.ts +7 -7
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -141,7 +141,7 @@ function getContentType(
|
|
|
141
141
|
const TYPE_REGEX = /https?:\/\/www.ft.com\/ontology\/content\//
|
|
142
142
|
const useType =
|
|
143
143
|
'type' in content && content.type ? content.type : content.types[0]
|
|
144
|
-
const type = useType
|
|
144
|
+
const type = useType?.replace(TYPE_REGEX, '')
|
|
145
145
|
|
|
146
146
|
if (validate && !validLiteralUnionValue(type, ContentType.values)) {
|
|
147
147
|
throw new Error('Content type is invalid: ' + useType)
|
|
@@ -535,7 +535,10 @@ export class CapiResponse {
|
|
|
535
535
|
#createCAPIImage(image: MainImage | undefined) {
|
|
536
536
|
if (image?.type === 'http://www.ft.com/ontology/content/Image') {
|
|
537
537
|
return new CAPIImage(image, this.context)
|
|
538
|
-
} else if (
|
|
538
|
+
} else if (
|
|
539
|
+
image?.type === 'http://www.ft.com/ontology/content/ImageSet' &&
|
|
540
|
+
image.members[0]
|
|
541
|
+
) {
|
|
539
542
|
return new CAPIImage(image.members[0], this.context)
|
|
540
543
|
}
|
|
541
544
|
|
|
@@ -753,7 +756,7 @@ export class CapiResponse {
|
|
|
753
756
|
)
|
|
754
757
|
|
|
755
758
|
if (pinnedPostIndex !== -1) {
|
|
756
|
-
return liveBlogPosts.splice(pinnedPostIndex, 1)[0]
|
|
759
|
+
return liveBlogPosts.splice(pinnedPostIndex, 1)[0] ?? null
|
|
757
760
|
}
|
|
758
761
|
}
|
|
759
762
|
return null
|
package/src/model/Clip.ts
CHANGED
package/src/model/Image.test.ts
CHANGED
|
@@ -68,10 +68,10 @@ describe('Image', () => {
|
|
|
68
68
|
|
|
69
69
|
it('includes sourceSet for all the possible resolutions we can display the image at, given the requested width and the original source width', () => {
|
|
70
70
|
expect(sourceSet.length).toEqual(5)
|
|
71
|
-
expect(sourceSet[0]
|
|
72
|
-
expect(sourceSet[0]
|
|
73
|
-
expect(sourceSet[4]
|
|
74
|
-
expect(sourceSet[4]
|
|
71
|
+
expect(sourceSet[0]?.dpr).toEqual(1)
|
|
72
|
+
expect(sourceSet[0]?.url).toMatch(/dpr=1/)
|
|
73
|
+
expect(sourceSet[4]?.dpr).toEqual(5)
|
|
74
|
+
expect(sourceSet[4]?.url).toMatch(/dpr=5/)
|
|
75
75
|
})
|
|
76
76
|
})
|
|
77
77
|
|
|
@@ -109,7 +109,7 @@ describe('Image', () => {
|
|
|
109
109
|
const model = new CAPIImage(mockImage, context)
|
|
110
110
|
const sourceSet = await model.sourceSet({ width: MAX_IMAGE_WIDTH })
|
|
111
111
|
expect(sourceSet.length).toEqual(1)
|
|
112
|
-
expect(sourceSet[0]
|
|
112
|
+
expect(sourceSet[0]?.width).toEqual(MAX_IMAGE_WIDTH)
|
|
113
113
|
})
|
|
114
114
|
})
|
|
115
115
|
|
|
@@ -119,8 +119,8 @@ describe('Image', () => {
|
|
|
119
119
|
const model = new CAPIImage(mockImage, context)
|
|
120
120
|
const sourceSet = await model.sourceSet({ width: 1000, maxDpr: 2 })
|
|
121
121
|
expect(sourceSet.length).toEqual(2)
|
|
122
|
-
expect(sourceSet[0]
|
|
123
|
-
expect(sourceSet[1]
|
|
122
|
+
expect(sourceSet[0]?.dpr).toEqual(1)
|
|
123
|
+
expect(sourceSet[1]?.dpr).toEqual(2)
|
|
124
124
|
})
|
|
125
125
|
})
|
|
126
126
|
|
|
@@ -150,13 +150,13 @@ describe('Image', () => {
|
|
|
150
150
|
})
|
|
151
151
|
it('passes the requested width to the image service', async () => {
|
|
152
152
|
expect(sourceSet.length).toEqual(1)
|
|
153
|
-
expect(sourceSet[0]
|
|
154
|
-
expect(sourceSet[0]
|
|
153
|
+
expect(sourceSet[0]?.width).toEqual(3000)
|
|
154
|
+
expect(sourceSet[0]?.url).toMatch(/width=3000/)
|
|
155
155
|
})
|
|
156
156
|
it('falls back to a single DPR source', async () => {
|
|
157
157
|
expect(sourceSet.length).toEqual(1)
|
|
158
|
-
expect(sourceSet[0]
|
|
159
|
-
expect(sourceSet[0]
|
|
158
|
+
expect(sourceSet[0]?.dpr).toEqual(1)
|
|
159
|
+
expect(sourceSet[0]?.url).toMatch(/dpr=1/)
|
|
160
160
|
})
|
|
161
161
|
})
|
|
162
162
|
})
|
|
@@ -59,8 +59,8 @@ describe('RichText resolver', () => {
|
|
|
59
59
|
const model = new RichText('bodyXML', bodyXML)
|
|
60
60
|
const result = await model.structured()
|
|
61
61
|
|
|
62
|
-
expect(result.references[0]
|
|
63
|
-
expect(result.references[1]
|
|
62
|
+
expect(result.references[0]?.reference.type).toEqual('main-image')
|
|
63
|
+
expect(result.references[1]?.reference.type).toEqual('image-set')
|
|
64
64
|
})
|
|
65
65
|
|
|
66
66
|
it('should not match the first imageset inside other components', async () => {
|
|
@@ -76,8 +76,8 @@ describe('RichText resolver', () => {
|
|
|
76
76
|
const model = new RichText('bodyXML', bodyXML)
|
|
77
77
|
const result = await model.structured()
|
|
78
78
|
|
|
79
|
-
expect(result.references[0]
|
|
80
|
-
expect(result.references[1]
|
|
79
|
+
expect(result.references[0]?.reference.type).toEqual('main-image')
|
|
80
|
+
expect(result.references[1]?.reference.type).toEqual('image-set')
|
|
81
81
|
})
|
|
82
82
|
})
|
|
83
83
|
})
|
package/src/model/Topper.ts
CHANGED
|
@@ -275,7 +275,7 @@ export class Topper {
|
|
|
275
275
|
const isOpinionOrColumn =
|
|
276
276
|
this.type() === 'OpinionTopper' || this.capiResponse.isColumn()
|
|
277
277
|
|
|
278
|
-
return isOpinionOrColumn && authors
|
|
278
|
+
return isOpinionOrColumn && authors[0] ? authors[0] : null
|
|
279
279
|
}
|
|
280
280
|
|
|
281
281
|
brandConcept() {
|
|
@@ -319,7 +319,7 @@ export class Topper {
|
|
|
319
319
|
if (this.capiResponse.isOpinion()) {
|
|
320
320
|
const authors = this.capiResponse.authors()
|
|
321
321
|
|
|
322
|
-
if (authors && authors
|
|
322
|
+
if (authors && authors[0]) {
|
|
323
323
|
return authors[0].headshot(args)
|
|
324
324
|
}
|
|
325
325
|
}
|
|
@@ -45,11 +45,13 @@ export default function bodyXMLToTree(
|
|
|
45
45
|
|
|
46
46
|
if (matchedSelector) {
|
|
47
47
|
const contentTreeTransform = tagMappings[matchedSelector]
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
48
|
+
if (contentTreeTransform) {
|
|
49
|
+
return contentTreeTransform(
|
|
50
|
+
$(node),
|
|
51
|
+
() => flattenAndTraverseChildren(node.children),
|
|
52
|
+
context
|
|
53
|
+
)
|
|
54
|
+
}
|
|
53
55
|
}
|
|
54
56
|
|
|
55
57
|
return flattenAndTraverseChildren(node.children)
|
|
@@ -58,7 +60,12 @@ export default function bodyXMLToTree(
|
|
|
58
60
|
return []
|
|
59
61
|
}
|
|
60
62
|
|
|
61
|
-
const
|
|
63
|
+
const cheerioBody = $('body')
|
|
64
|
+
if (!cheerioBody[0]) {
|
|
65
|
+
throw new Error('No body tag found in bodyXML')
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const body = traverse(cheerioBody[0])
|
|
62
69
|
|
|
63
70
|
logErrors(context)
|
|
64
71
|
|
|
@@ -40,7 +40,7 @@ describe('tagMappings test', () => {
|
|
|
40
40
|
const selector =
|
|
41
41
|
'ft-content[type="http://www.ft.com/ontology/content/clip"]'
|
|
42
42
|
const $el = load(bodyXML)(selector)
|
|
43
|
-
const mapping = tagMappings[selector]($el, () => [])
|
|
43
|
+
const mapping = tagMappings[selector]!($el, () => [])
|
|
44
44
|
|
|
45
45
|
expectNodeType<OldClip>(mapping, 'clip')
|
|
46
46
|
expect(mapping.url).toBe(
|
|
@@ -265,7 +265,7 @@ const commonTagMappings: TagMappings = {
|
|
|
265
265
|
): ContentTree.Layout['children'] => {
|
|
266
266
|
const [firstChild, ...otherChildren] = children
|
|
267
267
|
|
|
268
|
-
if (firstChild.type === 'heading') {
|
|
268
|
+
if (firstChild && firstChild.type === 'heading') {
|
|
269
269
|
return [
|
|
270
270
|
firstChild,
|
|
271
271
|
...everyChildIsType<ContentTree.LayoutSlot>(
|
|
@@ -317,9 +317,9 @@ const commonTagMappings: TagMappings = {
|
|
|
317
317
|
table: ($el, traverse, context): Table | ContentTree.Layout => {
|
|
318
318
|
const layoutSmallscreen = $el.attr('data-table-layout-smallscreen')
|
|
319
319
|
const responsiveStyle: Table['responsiveStyle'] =
|
|
320
|
-
layoutSmallscreen
|
|
320
|
+
(layoutSmallscreen
|
|
321
321
|
? tableResponsiveStyleMap[layoutSmallscreen]
|
|
322
|
-
: 'overflow'
|
|
322
|
+
: undefined) ?? 'overflow'
|
|
323
323
|
|
|
324
324
|
const children = traverse()
|
|
325
325
|
const bodies = children.filter(
|
|
@@ -342,14 +342,14 @@ const commonTagMappings: TagMappings = {
|
|
|
342
342
|
// HACK:KB:20230523 transform single-cell tables into infoboxes, for legacy articles
|
|
343
343
|
if (
|
|
344
344
|
bodies.length === 1 &&
|
|
345
|
-
bodies[0]
|
|
346
|
-
bodies[0]
|
|
345
|
+
bodies[0]?.children.length === 1 &&
|
|
346
|
+
bodies[0]?.children[0]?.children.length === 1
|
|
347
347
|
) {
|
|
348
348
|
const slot: ContentTree.LayoutSlot = {
|
|
349
349
|
type: 'layout-slot',
|
|
350
350
|
children: childrenOfTypes(
|
|
351
351
|
['paragraph', 'heading'],
|
|
352
|
-
bodies[0]
|
|
352
|
+
bodies[0]?.children[0]?.children[0]?.children ?? [],
|
|
353
353
|
'layout-slot',
|
|
354
354
|
context
|
|
355
355
|
),
|
|
@@ -548,7 +548,7 @@ const commonTagMappings: TagMappings = {
|
|
|
548
548
|
children: [
|
|
549
549
|
...everyChildIsType<ContentTree.ScrollyImage>(
|
|
550
550
|
'scrolly-image',
|
|
551
|
-
[firstChild],
|
|
551
|
+
firstChild ? [firstChild] : [],
|
|
552
552
|
'scrolly-section',
|
|
553
553
|
context
|
|
554
554
|
),
|