@financial-times/cp-content-pipeline-schema 1.4.2 → 1.4.4
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 +14 -0
- package/lib/generated/index.d.ts +47 -20
- package/lib/model/CapiResponse.d.ts +5 -5
- package/lib/model/CapiResponse.js +29 -11
- package/lib/model/CapiResponse.js.map +1 -1
- package/lib/model/schemas/capi/article.d.ts +3 -0
- package/lib/model/schemas/capi/article.js +1 -0
- package/lib/model/schemas/capi/article.js.map +1 -1
- package/lib/model/schemas/capi/audio.d.ts +3 -0
- package/lib/model/schemas/capi/audio.js +1 -0
- package/lib/model/schemas/capi/audio.js.map +1 -1
- package/lib/model/schemas/capi/base-schema.d.ts +3 -0
- package/lib/model/schemas/capi/base-schema.js +5 -0
- package/lib/model/schemas/capi/base-schema.js.map +1 -1
- package/lib/model/schemas/capi/content-package.d.ts +3 -0
- package/lib/model/schemas/capi/content-package.js +1 -0
- package/lib/model/schemas/capi/content-package.js.map +1 -1
- package/lib/model/schemas/capi/live-blog-package.d.ts +3 -0
- package/lib/model/schemas/capi/live-blog-package.js +1 -0
- package/lib/model/schemas/capi/live-blog-package.js.map +1 -1
- package/lib/model/schemas/capi/placeholder.d.ts +3 -0
- package/lib/model/schemas/capi/placeholder.js +1 -0
- package/lib/model/schemas/capi/placeholder.js.map +1 -1
- package/lib/resolvers/content.d.ts +1 -0
- package/lib/resolvers/content.js +1 -0
- package/lib/resolvers/content.js.map +1 -1
- package/lib/resolvers/index.d.ts +14 -12
- package/lib/resolvers/index.js +3 -1
- package/lib/resolvers/index.js.map +1 -1
- package/lib/resolvers/meta-link.d.ts +5 -0
- package/lib/resolvers/meta-link.js +15 -0
- package/lib/resolvers/meta-link.js.map +1 -0
- package/lib/resolvers/teaser.d.ts +3 -3
- package/lib/resolvers/teaser.js +6 -4
- package/lib/resolvers/teaser.js.map +1 -1
- package/package.json +1 -1
- package/src/generated/index.ts +49 -20
- package/src/model/CapiResponse.ts +35 -17
- package/src/model/schemas/capi/article.ts +1 -0
- package/src/model/schemas/capi/audio.ts +1 -0
- package/src/model/schemas/capi/base-schema.ts +5 -0
- package/src/model/schemas/capi/content-package.ts +1 -0
- package/src/model/schemas/capi/live-blog-package.ts +1 -0
- package/src/model/schemas/capi/placeholder.ts +1 -0
- package/src/resolvers/content.ts +1 -0
- package/src/resolvers/index.ts +3 -1
- package/src/resolvers/meta-link.ts +16 -0
- package/src/resolvers/teaser.ts +6 -4
- package/src/types/n-display-metadata.d.ts +15 -8
- package/tsconfig.tsbuildinfo +1 -1
- package/typedefs/content.graphql +16 -10
- package/typedefs/teaser.graphql +4 -2
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
ImageSet,
|
|
3
|
-
Annotation,
|
|
4
3
|
ContentTypeSchemas,
|
|
5
4
|
MainImage,
|
|
6
5
|
} from '../types/internal-content'
|
|
7
6
|
import conceptIds from '@financial-times/n-concept-ids'
|
|
8
|
-
import metadata
|
|
7
|
+
import metadata from '@financial-times/n-display-metadata'
|
|
9
8
|
import cloneDeep from 'clone-deep'
|
|
10
|
-
import { ConditionalKeys } from 'type-fest'
|
|
11
9
|
import { OperationalError } from '@dotcom-reliability-kit/errors'
|
|
12
10
|
|
|
13
11
|
import type { QueryContext } from '..'
|
|
@@ -241,6 +239,15 @@ export class CapiResponse {
|
|
|
241
239
|
canBeSyndicated(): LiteralUnionScalarValues<typeof CanBeSyndicated> {
|
|
242
240
|
return this.capiData.canBeSyndicated
|
|
243
241
|
}
|
|
242
|
+
originatingParty(): string | null {
|
|
243
|
+
return this.capiData.canBeDistributed === 'no' &&
|
|
244
|
+
this.annotations().some((annotation) => {
|
|
245
|
+
annotation.id() ===
|
|
246
|
+
'http://api.ft.com/things/ed3b6ec5-6466-47ef-b1d8-16952fd522c7'
|
|
247
|
+
})
|
|
248
|
+
? 'Reuters'
|
|
249
|
+
: 'FT'
|
|
250
|
+
}
|
|
244
251
|
summary() {
|
|
245
252
|
if ('summary' in this.capiData) return this.capiData.summary
|
|
246
253
|
return null
|
|
@@ -309,26 +316,37 @@ export class CapiResponse {
|
|
|
309
316
|
})
|
|
310
317
|
}
|
|
311
318
|
|
|
312
|
-
async
|
|
313
|
-
field: ConditionalKeys<TeaserMetadata, Annotation | null>
|
|
314
|
-
) {
|
|
319
|
+
async metaLink() {
|
|
315
320
|
const meta = await this.#teaserMetadata()
|
|
316
|
-
const metaField = meta[field]
|
|
317
321
|
|
|
318
|
-
|
|
322
|
+
if (!meta.link) {
|
|
323
|
+
return meta.link
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// TODO:KB:20231017 rewrite n-display-metadata in typescript using our types (lol. lmao)
|
|
327
|
+
// if meta.link has a predicate field, it's a concept, so wrap it in our concept model
|
|
328
|
+
if ('predicate' in meta.link) {
|
|
329
|
+
return new Concept(meta.link, this.context)
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
// otherwise, it's the package container, so return that directly as we already have it
|
|
333
|
+
return this.containedIn()
|
|
319
334
|
}
|
|
320
335
|
|
|
321
|
-
async
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
if (
|
|
325
|
-
const meta = await this.#teaserMetadata()
|
|
326
|
-
return meta[field]
|
|
327
|
-
} else {
|
|
328
|
-
// HACK 20230629 IM: suffixText doesn't actually exist in the metadata
|
|
329
|
-
// type lol but deleting the field would be a breaking change
|
|
336
|
+
async metaAltLink() {
|
|
337
|
+
const meta = await this.#teaserMetadata()
|
|
338
|
+
|
|
339
|
+
if (!meta.altLink) {
|
|
330
340
|
return null
|
|
331
341
|
}
|
|
342
|
+
|
|
343
|
+
// unlike meta.link, meta.altLink alwyas returns a Concept
|
|
344
|
+
return new Concept(meta.altLink, this.context)
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
async metaPrefixText() {
|
|
348
|
+
const meta = await this.#teaserMetadata()
|
|
349
|
+
return meta.prefixText
|
|
332
350
|
}
|
|
333
351
|
|
|
334
352
|
teaser() {
|
|
@@ -154,6 +154,11 @@ export const baseMetadataSchema = z.object({
|
|
|
154
154
|
z.literal('withContributorPayment'),
|
|
155
155
|
z.literal('unknown'),
|
|
156
156
|
]),
|
|
157
|
+
canBeDistributed: z.union([
|
|
158
|
+
z.literal('yes'),
|
|
159
|
+
z.literal('no'),
|
|
160
|
+
z.literal('verify'),
|
|
161
|
+
]),
|
|
157
162
|
topper: Topper.optional(),
|
|
158
163
|
comments: z
|
|
159
164
|
.object({
|
package/src/resolvers/content.ts
CHANGED
|
@@ -55,6 +55,7 @@ const resolvers = {
|
|
|
55
55
|
annotations: (parent) => parent.annotations(),
|
|
56
56
|
accessLevel: (parent) => parent.accessLevel(),
|
|
57
57
|
canBeSyndicated: (parent) => parent.canBeSyndicated(),
|
|
58
|
+
originatingParty: (parent) => parent.originatingParty(),
|
|
58
59
|
commentsEnabled: (parent) => parent.commentsEnabled(),
|
|
59
60
|
design: (parent) => parent.design(),
|
|
60
61
|
},
|
package/src/resolvers/index.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { default as concept } from './concept'
|
|
|
2
2
|
import { default as content } from './content'
|
|
3
3
|
import { default as core } from './core'
|
|
4
4
|
import { default as image } from './image'
|
|
5
|
+
import { default as metaLink } from './meta-link'
|
|
5
6
|
import { default as picture } from './picture'
|
|
6
7
|
import { default as richText } from './richText'
|
|
7
8
|
import { default as scalars } from './scalars'
|
|
@@ -15,12 +16,13 @@ const resolvers = {
|
|
|
15
16
|
...content,
|
|
16
17
|
...core,
|
|
17
18
|
...image,
|
|
19
|
+
...metaLink,
|
|
18
20
|
...picture,
|
|
21
|
+
...references,
|
|
19
22
|
...richText,
|
|
20
23
|
...scalars,
|
|
21
24
|
...teaser,
|
|
22
25
|
...topper,
|
|
23
|
-
...references,
|
|
24
26
|
} satisfies Resolvers
|
|
25
27
|
|
|
26
28
|
export default resolvers
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { MetaLinkResolvers } from '../generated'
|
|
2
|
+
import { Concept } from '../model/Concept'
|
|
3
|
+
|
|
4
|
+
const resolvers: { MetaLink: MetaLinkResolvers } = {
|
|
5
|
+
MetaLink: {
|
|
6
|
+
__resolveType(parent) {
|
|
7
|
+
if (parent instanceof Concept) {
|
|
8
|
+
return 'Concept'
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
return 'ContentPackage'
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export default resolvers
|
package/src/resolvers/teaser.ts
CHANGED
|
@@ -9,10 +9,12 @@ const resolvers = {
|
|
|
9
9
|
.type()
|
|
10
10
|
.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`)
|
|
11
11
|
.slice(1),
|
|
12
|
-
metaLink: (parent) => parent.
|
|
13
|
-
metaAltLink: (parent) => parent.
|
|
14
|
-
metaPrefixText: (parent) => parent.
|
|
15
|
-
|
|
12
|
+
metaLink: (parent) => parent.metaLink(),
|
|
13
|
+
metaAltLink: (parent) => parent.metaAltLink(),
|
|
14
|
+
metaPrefixText: (parent) => parent.metaPrefixText(),
|
|
15
|
+
// HACK 20230629 IM: suffixText doesn't actually exist in the metadata
|
|
16
|
+
// type lol but deleting the field would be a breaking change
|
|
17
|
+
metaSuffixText: () => null,
|
|
16
18
|
image: (parent) => parent.teaserImage(),
|
|
17
19
|
indicators(parent) {
|
|
18
20
|
return {
|
|
@@ -1,22 +1,29 @@
|
|
|
1
1
|
declare module '@financial-times/n-display-metadata' {
|
|
2
|
-
|
|
2
|
+
export interface MetaLink {
|
|
3
|
+
id?: string
|
|
4
|
+
url?: string
|
|
5
|
+
relativeUrl?: string
|
|
6
|
+
prefLabel?: string
|
|
7
|
+
}
|
|
3
8
|
|
|
4
9
|
export interface FlagsMetadata {
|
|
5
10
|
isOpinion: boolean
|
|
6
11
|
isColumn: boolean
|
|
7
12
|
}
|
|
8
13
|
|
|
9
|
-
export interface TeaserMetadata {
|
|
14
|
+
export interface TeaserMetadata<ConceptType, ContainedInType> {
|
|
10
15
|
flags: FlagsMetadata
|
|
11
16
|
prefixText: string
|
|
12
|
-
link:
|
|
13
|
-
altLink:
|
|
17
|
+
link: ConceptType | ContainedInType | null
|
|
18
|
+
altLink: ConceptType | null
|
|
14
19
|
}
|
|
15
20
|
|
|
16
|
-
export interface Content {
|
|
17
|
-
annotations:
|
|
18
|
-
containedIn:
|
|
21
|
+
export interface Content<ConceptType, ContainedInType> {
|
|
22
|
+
annotations: ConceptType[]
|
|
23
|
+
containedIn: ContainedInType[] | null
|
|
19
24
|
}
|
|
20
25
|
|
|
21
|
-
export function teaser(
|
|
26
|
+
export function teaser<ConceptType, ContainedInType>(
|
|
27
|
+
content: Content<ConceptType, ContainedInType>
|
|
28
|
+
): TeaserMetadata<ConceptType, ContainedInType>
|
|
22
29
|
}
|