@financial-times/cp-content-pipeline-schema 0.2.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.
Files changed (100) hide show
  1. package/.toolkitrc.yml +12 -0
  2. package/CHANGELOG.md +72 -0
  3. package/jest.config.js +3 -0
  4. package/lib/concept.d.ts +7 -0
  5. package/lib/concept.js +39 -0
  6. package/lib/concept.js.map +1 -0
  7. package/lib/constants/contentTypes.d.ts +2 -0
  8. package/lib/constants/contentTypes.js +3 -0
  9. package/lib/constants/contentTypes.js.map +1 -0
  10. package/lib/content.d.ts +55 -0
  11. package/lib/content.js +133 -0
  12. package/lib/content.js.map +1 -0
  13. package/lib/content.test.d.ts +1 -0
  14. package/lib/content.test.js +149 -0
  15. package/lib/content.test.js.map +1 -0
  16. package/lib/datasources/capi.d.ts +10 -0
  17. package/lib/datasources/capi.js +28 -0
  18. package/lib/datasources/capi.js.map +1 -0
  19. package/lib/datasources/index.d.ts +9 -0
  20. package/lib/datasources/index.js +9 -0
  21. package/lib/datasources/index.js.map +1 -0
  22. package/lib/datasources/origami-image.d.ts +8 -0
  23. package/lib/datasources/origami-image.js +11 -0
  24. package/lib/datasources/origami-image.js.map +1 -0
  25. package/lib/datasources/url-management.d.ts +11 -0
  26. package/lib/datasources/url-management.js +40 -0
  27. package/lib/datasources/url-management.js.map +1 -0
  28. package/lib/datasources/url-management.test.d.ts +1 -0
  29. package/lib/datasources/url-management.test.js +69 -0
  30. package/lib/datasources/url-management.test.js.map +1 -0
  31. package/lib/helpers/byline.d.ts +1 -0
  32. package/lib/helpers/byline.js +5 -0
  33. package/lib/helpers/byline.js.map +1 -0
  34. package/lib/helpers/imageService.d.ts +8 -0
  35. package/lib/helpers/imageService.js +13 -0
  36. package/lib/helpers/imageService.js.map +1 -0
  37. package/lib/helpers/metadata.d.ts +12 -0
  38. package/lib/helpers/metadata.js +60 -0
  39. package/lib/helpers/metadata.js.map +1 -0
  40. package/lib/helpers/syntaxTree.d.ts +23 -0
  41. package/lib/helpers/syntaxTree.js +23 -0
  42. package/lib/helpers/syntaxTree.js.map +1 -0
  43. package/lib/image.d.ts +25 -0
  44. package/lib/image.js +123 -0
  45. package/lib/image.js.map +1 -0
  46. package/lib/image.test.d.ts +1 -0
  47. package/lib/image.test.js +235 -0
  48. package/lib/image.test.js.map +1 -0
  49. package/lib/index.d.ts +8 -0
  50. package/lib/index.js +69 -0
  51. package/lib/index.js.map +1 -0
  52. package/lib/picture.d.ts +22 -0
  53. package/lib/picture.js +80 -0
  54. package/lib/picture.js.map +1 -0
  55. package/lib/richText.d.ts +14 -0
  56. package/lib/richText.js +48 -0
  57. package/lib/richText.js.map +1 -0
  58. package/lib/tags.d.ts +13 -0
  59. package/lib/tags.js +178 -0
  60. package/lib/tags.js.map +1 -0
  61. package/lib/topper.d.ts +7 -0
  62. package/lib/topper.js +196 -0
  63. package/lib/topper.js.map +1 -0
  64. package/lib/unified-plugins/extract-references.d.ts +7 -0
  65. package/lib/unified-plugins/extract-references.js +36 -0
  66. package/lib/unified-plugins/extract-references.js.map +1 -0
  67. package/lib/unified-plugins/map-to-abstract-types.d.ts +4 -0
  68. package/lib/unified-plugins/map-to-abstract-types.js +17 -0
  69. package/lib/unified-plugins/map-to-abstract-types.js.map +1 -0
  70. package/package.json +43 -0
  71. package/src/__snapshots__/content.test.ts.snap +118 -0
  72. package/src/concept.ts +58 -0
  73. package/src/constants/contentTypes.ts +4 -0
  74. package/src/content.test.ts +163 -0
  75. package/src/content.ts +146 -0
  76. package/src/datasources/capi.ts +28 -0
  77. package/src/datasources/index.ts +11 -0
  78. package/src/datasources/origami-image.ts +10 -0
  79. package/src/datasources/url-management.test.ts +92 -0
  80. package/src/datasources/url-management.ts +65 -0
  81. package/src/helpers/byline.ts +4 -0
  82. package/src/helpers/imageService.ts +31 -0
  83. package/src/helpers/metadata.ts +88 -0
  84. package/src/helpers/syntaxTree.ts +26 -0
  85. package/src/image.test.ts +339 -0
  86. package/src/image.ts +154 -0
  87. package/src/index.ts +87 -0
  88. package/src/picture.ts +98 -0
  89. package/src/richText.ts +62 -0
  90. package/src/tags.ts +237 -0
  91. package/src/topper.ts +228 -0
  92. package/src/types/internal-content.d.ts +78 -0
  93. package/src/types/n-concept-ids.d.ts +16 -0
  94. package/src/types/n-display-metadata.d.ts +1 -0
  95. package/src/types/n-url-management-api-read-client.d.ts +11 -0
  96. package/src/types/next-metrics.d.ts +1 -0
  97. package/src/unified-plugins/extract-references.ts +50 -0
  98. package/src/unified-plugins/map-to-abstract-types.ts +21 -0
  99. package/tsconfig.json +10 -0
  100. package/tsconfig.tsbuildinfo +1 -0
@@ -0,0 +1,235 @@
1
+ import { resolvers, ImageType } from './image.js';
2
+ import { jest } from '@jest/globals';
3
+ describe('Image', () => {
4
+ const image = {
5
+ id: 'https://api.ft.com/content/00000000-0000-0000-0000-000000000001',
6
+ type: ImageType.Image,
7
+ title: 'title',
8
+ description: 'description',
9
+ binaryUrl: 'cloudfront.com/image',
10
+ };
11
+ const graphic = {
12
+ ...image,
13
+ type: ImageType.Graphic,
14
+ };
15
+ const getImageMetadata = jest.fn();
16
+ const context = {
17
+ dataSources: {
18
+ origami: {
19
+ getImageMetadata: getImageMetadata,
20
+ },
21
+ capi: {},
22
+ },
23
+ };
24
+ beforeEach(() => {
25
+ getImageMetadata.mockReset();
26
+ });
27
+ describe('sources resolver', () => {
28
+ const sourcesResolver = resolvers.Image
29
+ .sources;
30
+ describe('An image that is provided with a high resolution', () => {
31
+ let sources;
32
+ beforeAll(async () => {
33
+ getImageMetadata.mockReturnValue({ width: 5000, height: 1000 });
34
+ sources = await sourcesResolver(image, {
35
+ width: 1000,
36
+ }, context);
37
+ });
38
+ it('transforms the URL to use the Origami Image Service', () => {
39
+ expect(sources.every((source) => source.url.startsWith('https://www.ft.com/__origami/service/image/v2'))).toBeTruthy();
40
+ });
41
+ it('resizes the image to the requested width', () => {
42
+ expect(sources.every((source) => source.width === 1000 && source.url.includes('width=1000'))).toBeTruthy();
43
+ });
44
+ it('includes sources for all the possible resolutions we can display the image at, given the requested width and the original source width', () => {
45
+ expect(sources.length).toEqual(5);
46
+ expect(sources[0].dpr).toEqual(1);
47
+ expect(sources[0].url).toMatch(/dpr=1/);
48
+ expect(sources[4].dpr).toEqual(5);
49
+ expect(sources[4].url).toMatch(/dpr=5/);
50
+ });
51
+ });
52
+ describe("An image that that isn't wide enough to generate high-resolution sources for", () => {
53
+ it('returns an array with a single resolution iamge service UR', async () => {
54
+ getImageMetadata.mockReturnValue({ width: 1500, height: 500 });
55
+ const sources = await sourcesResolver(image, {
56
+ width: 1000,
57
+ }, context);
58
+ expect(sources.length).toEqual(1);
59
+ expect(sources[0]).toEqual({
60
+ dpr: 1,
61
+ url: 'https://www.ft.com/__origami/service/image/v2/images/raw/ftcms%3A00000000-0000-0000-0000-000000000001?source=undefined&fit=scale-down&quality=highest&width=1000&dpr=1',
62
+ width: 1000,
63
+ });
64
+ });
65
+ });
66
+ describe('An image that that is smaller than the width that was requested', () => {
67
+ it('returns the image at the same width as the original', async () => {
68
+ getImageMetadata.mockReturnValue({ width: 500, height: 500 });
69
+ const sources = await sourcesResolver(image, {
70
+ width: 1000,
71
+ }, context);
72
+ expect(sources.length).toEqual(1);
73
+ expect(sources[0]).toEqual({
74
+ dpr: 1,
75
+ url: 'https://www.ft.com/__origami/service/image/v2/images/raw/ftcms%3A00000000-0000-0000-0000-000000000001?source=undefined&fit=scale-down&quality=highest&width=500&dpr=1',
76
+ width: 500,
77
+ });
78
+ });
79
+ });
80
+ describe('A large image with the maxDpr argumet passed', () => {
81
+ it('only returns sources up to and including the maxDpr', async () => {
82
+ getImageMetadata.mockReturnValue({ width: 5000, height: 500 });
83
+ const sources = await sourcesResolver(image, {
84
+ width: 1000,
85
+ maxDpr: 2,
86
+ }, context);
87
+ expect(sources.length).toEqual(2);
88
+ expect(sources[0].dpr).toEqual(1);
89
+ expect(sources[1].dpr).toEqual(2);
90
+ });
91
+ });
92
+ describe('An invalid image object', () => {
93
+ it('throws an error', async () => {
94
+ const invalidImage = {
95
+ type: ImageType.Image,
96
+ id: 'not-a-uuid',
97
+ title: '',
98
+ description: '',
99
+ binaryUrl: '',
100
+ };
101
+ await expect(sourcesResolver(invalidImage, {
102
+ width: 1000,
103
+ maxDpr: 2,
104
+ }, context)).rejects.toThrow('not-a-uuid is not a valid Content API Image ID');
105
+ expect(getImageMetadata).not.toHaveBeenCalled();
106
+ });
107
+ });
108
+ describe('When the image service fails to return metadata', () => {
109
+ let sources;
110
+ beforeEach(async () => {
111
+ getImageMetadata.mockRejectedValue(null);
112
+ sources = await sourcesResolver(image, {
113
+ width: 3000,
114
+ }, context);
115
+ });
116
+ it('passes the requested width to the image service', async () => {
117
+ expect(sources.length).toEqual(1);
118
+ expect(sources[0].width).toEqual(3000);
119
+ expect(sources[0].url).toMatch(/width=3000/);
120
+ });
121
+ it('falls back to a single DPR source', async () => {
122
+ expect(sources.length).toEqual(1);
123
+ expect(sources[0].dpr).toEqual(1);
124
+ expect(sources[0].url).toMatch(/dpr=1/);
125
+ });
126
+ });
127
+ });
128
+ describe('originalWidth/originalHeight resolvers', () => {
129
+ const originalWidthResolver = resolvers.Image
130
+ .originalWidth;
131
+ const originalHeightResolver = resolvers.Image
132
+ .originalHeight;
133
+ it('returns the original width and height from the image service metadata', async () => {
134
+ getImageMetadata.mockReturnValue({ width: 100, height: 200 });
135
+ const width = await originalWidthResolver(image, undefined, context);
136
+ const height = await originalHeightResolver(image, undefined, context);
137
+ expect(width).toEqual(100);
138
+ expect(height).toEqual(200);
139
+ });
140
+ it('returns null if the image service metadata call fails', async () => {
141
+ getImageMetadata.mockRejectedValue(null);
142
+ const width = await originalWidthResolver(image, undefined, context);
143
+ const height = await originalHeightResolver(image, undefined, context);
144
+ expect(width).toEqual(null);
145
+ expect(height).toEqual(null);
146
+ });
147
+ });
148
+ describe('minDisplayWidth/maxDisplayWidth resolvers', () => {
149
+ const minDisplayWidthResolver = resolvers.Image
150
+ .minDisplayWidth;
151
+ const maxDisplayWidthResolver = resolvers.Image
152
+ .maxDisplayWidth;
153
+ it('uses the argument value if supplied, so consumers can control when an image should be displayed', () => {
154
+ const imageWithDisplayWidth = {
155
+ ...image,
156
+ minDisplayWidth: '980px',
157
+ };
158
+ const minDisplayWidth = minDisplayWidthResolver(imageWithDisplayWidth, {
159
+ width: 500,
160
+ });
161
+ const maxDisplayWidth = maxDisplayWidthResolver(imageWithDisplayWidth, {
162
+ width: 900,
163
+ });
164
+ expect(minDisplayWidth).toEqual('500px');
165
+ expect(maxDisplayWidth).toEqual('900px');
166
+ });
167
+ it('uses the values from the content API if no overrides supplied', () => {
168
+ const imageWithDisplayWidth = {
169
+ ...image,
170
+ minDisplayWidth: '490px',
171
+ maxDisplayWidth: '980px',
172
+ };
173
+ const minDisplayWidth = minDisplayWidthResolver(imageWithDisplayWidth, {});
174
+ const maxDisplayWidth = maxDisplayWidthResolver(imageWithDisplayWidth, {});
175
+ expect(minDisplayWidth).toEqual('490px');
176
+ expect(maxDisplayWidth).toEqual('980px');
177
+ });
178
+ it('returns undefined if no values supplied or in content API response ', () => {
179
+ const minDisplayWidth = minDisplayWidthResolver(image, {});
180
+ const maxDisplayWidth = maxDisplayWidthResolver(image, {});
181
+ expect(minDisplayWidth).toBeUndefined();
182
+ expect(maxDisplayWidth).toBeUndefined();
183
+ });
184
+ });
185
+ describe('caption resolver', () => {
186
+ const captionResolver = resolvers.Image
187
+ .caption;
188
+ it('combines the caption and copyright together', () => {
189
+ const imageWithCopyright = { ...image, copyright: { notice: '© credit' } };
190
+ const caption = captionResolver(imageWithCopyright);
191
+ expect(caption).toBe('title © credit');
192
+ });
193
+ it('returns just the caption if there is no copright', () => {
194
+ const caption = captionResolver(image);
195
+ expect(caption).toBe('title');
196
+ });
197
+ });
198
+ describe('copyright resolver', () => {
199
+ const copyrightResolver = resolvers.Image
200
+ .copyright;
201
+ it('returns the copyright notice if it exists', () => {
202
+ const imageWithCopyright = { ...image, copyright: { notice: '© credit' } };
203
+ const copyright = copyrightResolver(imageWithCopyright);
204
+ expect(copyright).toBe('© credit');
205
+ });
206
+ it('returns undefined if no copyright', () => {
207
+ const copyright = copyrightResolver(image);
208
+ expect(copyright).toBe(undefined);
209
+ });
210
+ });
211
+ describe('alt resolver', () => {
212
+ const altResolver = resolvers.Image
213
+ .alt;
214
+ it('uses the description if it exists', () => {
215
+ const alt = altResolver(image);
216
+ expect(alt).toBe('description');
217
+ });
218
+ it('escapes double quotes', () => {
219
+ const alt = altResolver({
220
+ ...image,
221
+ description: 'This is a "quoted" description',
222
+ });
223
+ expect(alt).toBe('This is a "quoted" description');
224
+ });
225
+ it("returns an empty string for images with no description, so screen readers don't read out the URL", () => {
226
+ const alt = altResolver({ ...image, description: '' });
227
+ expect(alt).toBe('');
228
+ });
229
+ it('returns an default alt text for graphics with no description, as they are not considered presentational', () => {
230
+ const alt = altResolver({ ...graphic, description: '' });
231
+ expect(alt).toBe('A graphic with no description');
232
+ });
233
+ });
234
+ });
235
+ //# sourceMappingURL=image.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image.test.js","sourceRoot":"","sources":["../src/image.test.ts"],"names":[],"mappings":"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"}
package/lib/index.d.ts ADDED
@@ -0,0 +1,8 @@
1
+ import type { IResolvers } from '@graphql-tools/utils';
2
+ import { DocumentNode } from 'graphql';
3
+ import { dataSources, DataSources } from './datasources/index.js';
4
+ export declare const resolvers: IResolvers<unknown, {
5
+ dataSources: DataSources;
6
+ }>;
7
+ export declare const typeDefs: (DocumentNode | DocumentNode[])[];
8
+ export { dataSources, DataSources, typeDefs as schema };
package/lib/index.js ADDED
@@ -0,0 +1,69 @@
1
+ import { gql } from 'graphql-tag';
2
+ import { dataSources } from './datasources/index.js';
3
+ import { typeDef as Content, resolvers as contentResolvers } from './content.js';
4
+ import { typeDef as Concept, resolvers as conceptResolvers } from './concept.js';
5
+ import { typeDef as Picture, resolvers as pictureResolvers } from './picture.js';
6
+ import { typeDef as Image, resolvers as imageResolvers } from './image.js';
7
+ import { typeDef as Topper, resolvers as topperResolvers } from './topper.js';
8
+ import { typeDef as RichText, resolvers as richTextResolvers, } from './richText.js';
9
+ import tags from './tags.js';
10
+ const tagEntries = Object.entries(tags);
11
+ const tagsWithReferences = tagEntries.filter(([_key, tag]) => tag.typeDef);
12
+ const tagTypeDefs = tagsWithReferences.flatMap(([_key, tag]) => tag.typeDef);
13
+ const Reference = gql `union Reference = ${tagsWithReferences
14
+ .flatMap(([key]) => key)
15
+ .join(' | ')}`;
16
+ const tagResolvers = Object.fromEntries(tagEntries.flatMap(([key, tag]) => (tag.resolve ? [[key, tag.resolve]] : [])));
17
+ // A schema is a collection of type definitions (hence "typeDefs")
18
+ // that together define the "shape" of queries that are executed against
19
+ // your data.
20
+ const coreTypeDefs = gql `
21
+ # Comments in GraphQL strings (such as this one) start with the hash (#) symbol.
22
+
23
+ scalar JSON
24
+
25
+ # The "Query" type is special: it lists all of the available queries that
26
+ # clients can execute, along with the return type for each. In this
27
+ # case, the "books" query returns an array of zero or more Books (defined above).
28
+ type Query {
29
+ content(uuid: String!): Content!
30
+ contentFromJSON(content: JSON!): Content!
31
+ }
32
+ `;
33
+ // Resolvers define the technique for fetching the types defined in the
34
+ // schema. This resolver retrieves books from the "books" array above.
35
+ export const resolvers = {
36
+ Query: {
37
+ async content(parent, args, context) {
38
+ return context.dataSources.capi.getContent(args.uuid);
39
+ },
40
+ contentFromJSON(_, { content }) {
41
+ return content;
42
+ },
43
+ },
44
+ Reference: {
45
+ __resolveType(obj) {
46
+ return obj.constructor.name;
47
+ },
48
+ },
49
+ ...conceptResolvers,
50
+ ...contentResolvers,
51
+ ...pictureResolvers,
52
+ ...imageResolvers,
53
+ ...tagResolvers,
54
+ ...topperResolvers,
55
+ ...richTextResolvers,
56
+ };
57
+ export const typeDefs = [
58
+ Content,
59
+ Concept,
60
+ Picture,
61
+ Image,
62
+ Topper,
63
+ RichText,
64
+ Reference,
65
+ tagTypeDefs,
66
+ coreTypeDefs,
67
+ ];
68
+ export { dataSources, typeDefs as schema };
69
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAA;AAEjC,OAAO,EAAE,WAAW,EAAe,MAAM,wBAAwB,CAAA;AAEjE,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,SAAS,IAAI,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAChF,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,SAAS,IAAI,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAChF,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,SAAS,IAAI,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAChF,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,SAAS,IAAI,cAAc,EAAE,MAAM,YAAY,CAAA;AAC1E,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,SAAS,IAAI,eAAe,EAAE,MAAM,aAAa,CAAA;AAC7E,OAAO,EACL,OAAO,IAAI,QAAQ,EACnB,SAAS,IAAI,iBAAiB,GAC/B,MAAM,eAAe,CAAA;AAEtB,OAAO,IAAI,MAAM,WAAW,CAAA;AAE5B,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;AACvC,MAAM,kBAAkB,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;AAC1E,MAAM,WAAW,GAAG,kBAAkB,CAAC,OAAO,CAC5C,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,OAAuB,CAC7C,CAAA;AACD,MAAM,SAAS,GAAG,GAAG,CAAA,qBAAqB,kBAAkB;KACzD,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC;KACvB,IAAI,CAAC,KAAK,CAAC,EAAE,CAAA;AAEhB,MAAM,YAAY,GAAG,MAAM,CAAC,WAAW,CACrC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAC9E,CAAA;AAED,kEAAkE;AAClE,wEAAwE;AACxE,aAAa;AACb,MAAM,YAAY,GAAG,GAAG,CAAA;;;;;;;;;;;;CAYvB,CAAA;AACD,uEAAuE;AACvE,sEAAsE;AACtE,MAAM,CAAC,MAAM,SAAS,GAAsD;IAC1E,KAAK,EAAE;QACL,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO;YACjC,OAAO,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACvD,CAAC;QACD,eAAe,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE;YAC5B,OAAO,OAAO,CAAA;QAChB,CAAC;KACF;IAED,SAAS,EAAE;QACT,aAAa,CAAC,GAAsC;YAClD,OAAO,GAAG,CAAC,WAAW,CAAC,IAAI,CAAA;QAC7B,CAAC;KACF;IAED,GAAG,gBAAgB;IACnB,GAAG,gBAAgB;IACnB,GAAG,gBAAgB;IACnB,GAAG,cAAc;IACjB,GAAG,YAAY;IACf,GAAG,eAAe;IAClB,GAAG,iBAAiB;CACrB,CAAA;AAED,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,OAAO;IACP,OAAO;IACP,OAAO;IACP,KAAK;IACL,MAAM;IACN,QAAQ;IACR,SAAS;IACT,WAAW;IACX,YAAY;CACb,CAAA;AAED,OAAO,EAAE,WAAW,EAAe,QAAQ,IAAI,MAAM,EAAE,CAAA"}
@@ -0,0 +1,22 @@
1
+ import { ImageSet } from './types/internal-content.js';
2
+ import type { DataSources } from './datasources/index.js';
3
+ export declare const ImageType: {
4
+ readonly Image: "http://www.ft.com/ontology/content/Image";
5
+ readonly Graphic: "http://www.ft.com/ontology/content/Graphic";
6
+ };
7
+ export declare const typeDef: import("graphql").DocumentNode;
8
+ export declare const resolvers: {
9
+ Picture: {
10
+ __resolveType(parent: ImageSet, context: {
11
+ dataSources: DataSources;
12
+ }): Promise<"PictureFullBleed" | "PictureInline" | "PictureStandard">;
13
+ images(parent: ImageSet): {
14
+ standard: import("./types/internal-content.js").Image;
15
+ small: import("./types/internal-content.js").Image;
16
+ large: import("./types/internal-content.js").Image;
17
+ };
18
+ caption(parent: ImageSet): string | null;
19
+ alt(parent: ImageSet): string;
20
+ imageType(parent: ImageSet): "http://www.ft.com/ontology/content/Image" | "http://www.ft.com/ontology/content/Graphic";
21
+ };
22
+ };
package/lib/picture.js ADDED
@@ -0,0 +1,80 @@
1
+ import { gql } from 'graphql-tag';
2
+ import { getImageDimensions } from './image.js';
3
+ export const ImageType = {
4
+ Image: 'http://www.ft.com/ontology/content/Image',
5
+ Graphic: 'http://www.ft.com/ontology/content/Graphic',
6
+ };
7
+ const pictureFields = `
8
+ images: PictureImages
9
+ alt: String!
10
+ caption: String
11
+ imageType: ImageType!
12
+ `;
13
+ export const typeDef = gql `
14
+ enum ImageType {
15
+ Image
16
+ Graphic
17
+ }
18
+
19
+ type PictureImages {
20
+ standard: Image!
21
+ small: Image
22
+ large: Image
23
+ }
24
+
25
+ interface Picture {
26
+ ${pictureFields}
27
+ }
28
+
29
+ type PictureStandard implements Picture {
30
+ ${pictureFields}
31
+ }
32
+
33
+ type PictureInline implements Picture {
34
+ ${pictureFields}
35
+ }
36
+
37
+ type PictureFullBleed implements Picture {
38
+ ${pictureFields}
39
+ }
40
+ `;
41
+ export const resolvers = {
42
+ Picture: {
43
+ async __resolveType(parent, context) {
44
+ //TODO: actually work out the types
45
+ if (parent.members.length === 3)
46
+ return 'PictureFullBleed';
47
+ const standard = parent.members[0];
48
+ const { width, height } = await getImageDimensions(standard, context.dataSources);
49
+ if (width < 350 || (width < height && width < 580)) {
50
+ return 'PictureInline';
51
+ }
52
+ return 'PictureStandard';
53
+ },
54
+ images(parent) {
55
+ const standard = parent.members[0];
56
+ const large = parent.members.find((member) => member.minDisplayWidth === '980px') ||
57
+ standard;
58
+ const small = parent.members.find((member) => member.maxDisplayWidth === '490px') ||
59
+ standard;
60
+ return { standard, small, large };
61
+ },
62
+ caption(parent) {
63
+ var _a;
64
+ const standard = parent.members[0];
65
+ const elements = [standard.title, (_a = standard.copyright) === null || _a === void 0 ? void 0 : _a.notice].filter(Boolean);
66
+ return elements.length ? elements.join(' ') : null;
67
+ },
68
+ alt(parent) {
69
+ const standard = parent.members[0];
70
+ const fallback = standard.type === ImageType.Graphic
71
+ ? 'A graphic with no description'
72
+ : '';
73
+ return (standard.description || fallback).replace(/"/g, '&quot;');
74
+ },
75
+ imageType(parent) {
76
+ return parent.members[0].type;
77
+ },
78
+ },
79
+ };
80
+ //# sourceMappingURL=picture.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"picture.js","sourceRoot":"","sources":["../src/picture.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAA;AAEjC,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAI/C,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,KAAK,EAAE,0CAA0C;IACjD,OAAO,EAAE,4CAA4C;CAC7C,CAAA;AAEV,MAAM,aAAa,GAAG;;;;;CAKrB,CAAA;AAED,MAAM,CAAC,MAAM,OAAO,GAAG,GAAG,CAAA;;;;;;;;;;;;;MAapB,aAAa;;;;MAIb,aAAa;;;;MAIb,aAAa;;;;MAIb,aAAa;;CAElB,CAAA;AAED,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,OAAO,EAAE;QACP,KAAK,CAAC,aAAa,CACjB,MAAgB,EAChB,OAAqC;YAErC,mCAAmC;YACnC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,kBAAkB,CAAA;YAC1D,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;YAClC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,kBAAkB,CAChD,QAAQ,EACR,OAAO,CAAC,WAAW,CACpB,CAAA;YACD,IAAI,KAAK,GAAG,GAAG,IAAI,CAAC,KAAK,GAAG,MAAM,IAAI,KAAK,GAAG,GAAG,CAAC,EAAE;gBAClD,OAAO,eAAe,CAAA;aACvB;YACD,OAAO,iBAAiB,CAAA;QAC1B,CAAC;QACD,MAAM,CAAC,MAAgB;YACrB,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;YAClC,MAAM,KAAK,GACT,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,eAAe,KAAK,OAAO,CAAC;gBACnE,QAAQ,CAAA;YACV,MAAM,KAAK,GACT,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,eAAe,KAAK,OAAO,CAAC;gBACnE,QAAQ,CAAA;YAEV,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,CAAA;QACnC,CAAC;QACD,OAAO,CAAC,MAAgB;;YACtB,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;YAClC,MAAM,QAAQ,GAAG,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAA,QAAQ,CAAC,SAAS,0CAAE,MAAM,CAAC,CAAC,MAAM,CAClE,OAAO,CACR,CAAA;YACD,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;QACpD,CAAC;QAED,GAAG,CAAC,MAAgB;YAClB,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;YAClC,MAAM,QAAQ,GACZ,QAAQ,CAAC,IAAI,KAAK,SAAS,CAAC,OAAO;gBACjC,CAAC,CAAC,+BAA+B;gBACjC,CAAC,CAAC,EAAE,CAAA;YACR,OAAO,CAAC,QAAQ,CAAC,WAAW,IAAI,QAAQ,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;QACnE,CAAC;QAED,SAAS,CAAC,MAAgB;YACxB,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;QAC/B,CAAC;KACF;CACF,CAAA"}
@@ -0,0 +1,14 @@
1
+ import type { InternalContent } from './types/internal-content.js';
2
+ declare type RichTextResolverData = {
3
+ source: string;
4
+ value: string;
5
+ contentApiData?: InternalContent;
6
+ };
7
+ export declare const typeDef: import("graphql").DocumentNode;
8
+ export declare const resolvers: {
9
+ RichText: {
10
+ raw(parent: RichTextResolverData): string;
11
+ structured(parent: RichTextResolverData): Promise<unknown>;
12
+ };
13
+ };
14
+ export {};
@@ -0,0 +1,48 @@
1
+ import { unified } from 'unified';
2
+ import { gql } from 'graphql-tag';
3
+ import rehypeParse from 'rehype-parse';
4
+ import extractReferences from './unified-plugins/extract-references.js';
5
+ import mapToAbstractTypes from './unified-plugins/map-to-abstract-types.js';
6
+ export const typeDef = gql `
7
+ type StructuredContent {
8
+ tree: JSON!
9
+ references: [Reference!]!
10
+ }
11
+
12
+ enum Source {
13
+ standfirst
14
+ summary
15
+ }
16
+
17
+ type RichText {
18
+ source: Source!
19
+ raw: String!
20
+ structured: StructuredContent!
21
+ }
22
+ `;
23
+ export const resolvers = {
24
+ RichText: {
25
+ raw(parent) {
26
+ return parent.value;
27
+ },
28
+ async structured(parent) {
29
+ const formatOutput = function formatOutput() {
30
+ this.Compiler = (tree) => {
31
+ const references = this.data('references');
32
+ return { tree, references };
33
+ };
34
+ };
35
+ const pluggableList = [
36
+ mapToAbstractTypes,
37
+ extractReferences({ contentApiData: parent.contentApiData }),
38
+ formatOutput,
39
+ ];
40
+ const body = await unified()
41
+ .use(rehypeParse, { fragment: true })
42
+ .use(pluggableList)
43
+ .process(parent.value);
44
+ return body.result;
45
+ },
46
+ },
47
+ };
48
+ //# sourceMappingURL=richText.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"richText.js","sourceRoot":"","sources":["../src/richText.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAyB,MAAM,SAAS,CAAA;AACxD,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAA;AACjC,OAAO,WAAW,MAAM,cAAc,CAAA;AACtC,OAAO,iBAAiB,MAAM,yCAAyC,CAAA;AACvE,OAAO,kBAAkB,MAAM,4CAA4C,CAAA;AAU3E,MAAM,CAAC,MAAM,OAAO,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;CAgBzB,CAAA;AAED,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,QAAQ,EAAE;QACR,GAAG,CAAC,MAA4B;YAC9B,OAAO,MAAM,CAAC,KAAK,CAAA;QACrB,CAAC;QAED,KAAK,CAAC,UAAU,CAAC,MAA4B;YAC3C,MAAM,YAAY,GAChB,SAAS,YAAY;gBACnB,IAAI,CAAC,QAAQ,GAAG,CAAC,IAAI,EAAE,EAAE;oBACvB,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;oBAC1C,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,CAAA;gBAC7B,CAAC,CAAA;YACH,CAAC,CAAA;YAEH,MAAM,aAAa,GAAkB;gBACnC,kBAAkB;gBAClB,iBAAiB,CAAC,EAAE,cAAc,EAAE,MAAM,CAAC,cAAc,EAAE,CAAC;gBAC5D,YAAY;aACb,CAAA;YAED,MAAM,IAAI,GAAG,MAAM,OAAO,EAAE;iBACzB,GAAG,CAAC,WAAW,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;iBACpC,GAAG,CAAC,aAAa,CAAC;iBAClB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;YAExB,OAAO,IAAI,CAAC,MAAM,CAAA;QACpB,CAAC;KACF;CACF,CAAA"}
package/lib/tags.d.ts ADDED
@@ -0,0 +1,13 @@
1
+ import type * as hast from 'hast';
2
+ import type { IObjectTypeResolver } from '@graphql-tools/utils';
3
+ import type { DocumentNode } from 'graphql';
4
+ import type { InternalContent } from './types/internal-content.js';
5
+ export declare type Tag = object;
6
+ interface TagConstructor {
7
+ new (node: hast.Element, contentApiData?: InternalContent): Tag;
8
+ match(node: hast.Element): boolean;
9
+ typeDef?: DocumentNode;
10
+ resolve?: IObjectTypeResolver<any, any, any>;
11
+ }
12
+ declare const mapping: Record<string, TagConstructor>;
13
+ export default mapping;