From 1f87c6338c32dac010561cf554f8ba39fe8faa3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benedikt=20R=C3=B6tsch?= Date: Wed, 5 May 2021 18:57:16 +0200 Subject: [PATCH] refactor: flatten Contentful asset data structure to match GraphQL API schema (#31115) --- .../src/pages/gatsby-plugin-image.js | 54 +++++------ .../contentful/src/pages/media-reference.js | 90 +++++-------------- .../src/__tests__/gatsby-node.js | 9 +- .../src/extend-node-type.js | 15 +--- .../src/gatsby-plugin-image.js | 25 +++--- .../src/generate-schema.js | 57 ++++-------- .../src/image-helpers.js | 2 +- .../gatsby-source-contentful/src/normalize.js | 17 ++-- 8 files changed, 95 insertions(+), 174 deletions(-) diff --git a/e2e-tests/contentful/src/pages/gatsby-plugin-image.js b/e2e-tests/contentful/src/pages/gatsby-plugin-image.js index e5ef0b60f9e41..deb54a7640138 100644 --- a/e2e-tests/contentful/src/pages/gatsby-plugin-image.js +++ b/e2e-tests/contentful/src/pages/gatsby-plugin-image.js @@ -16,14 +16,14 @@ const GatsbyPluginImagePage = ({ data }) => {

- {node.title} ({node.file.fileName.split(".").pop()}) + {node.title} ({node.fileName.split(".").pop()})

{node.description &&

{node.description}

} {node.constrained ? ( ) : ( - + )}
))} @@ -34,14 +34,14 @@ const GatsbyPluginImagePage = ({ data }) => {

- {node.title} ({node.file.fileName.split(".").pop()}) + {node.title} ({node.fileName.split(".").pop()})

{node.description &&

{node.description}

} {node.fullWidth ? ( ) : ( - + )}
))} @@ -53,14 +53,14 @@ const GatsbyPluginImagePage = ({ data }) => {

- {node.title} ({node.file.fileName.split(".").pop()}) + {node.title} ({node.fileName.split(".").pop()})

{node.description &&

{node.description}

} {node.fixed ? ( ) : ( - + )}
))} @@ -72,14 +72,14 @@ const GatsbyPluginImagePage = ({ data }) => {

- {node.title} ({node.file.fileName.split(".").pop()}) + {node.title} ({node.fileName.split(".").pop()})

{node.description &&

{node.description}

} {node.dominantColor ? ( ) : ( - + )}
))} @@ -91,14 +91,14 @@ const GatsbyPluginImagePage = ({ data }) => {

- {node.title} ({node.file.fileName.split(".").pop()}) + {node.title} ({node.fileName.split(".").pop()})

{node.description &&

{node.description}

} {node.traced ? ( ) : ( - + )}
))} @@ -110,14 +110,14 @@ const GatsbyPluginImagePage = ({ data }) => {

- {node.title} ({node.file.fileName.split(".").pop()}) + {node.title} ({node.fileName.split(".").pop()})

{node.description &&

{node.description}

} {node.blurred ? ( ) : ( - + )}
))} @@ -148,7 +148,7 @@ const GatsbyPluginImagePage = ({ data }) => {

- {node.title} ({node.file.fileName.split(".").pop()}) + {node.title} ({node.fileName.split(".").pop()})

{node.description &&

{node.description}

} @@ -162,7 +162,7 @@ const GatsbyPluginImagePage = ({ data }) => { }} /> ) : ( - + )}
))} @@ -174,14 +174,14 @@ const GatsbyPluginImagePage = ({ data }) => {

- {node.title} ({node.file.fileName.split(".").pop()}) + {node.title} ({node.fileName.split(".").pop()})

{node.description &&

{node.description}

} {node.constrained ? ( ) : ( - + )}
))} @@ -193,14 +193,14 @@ const GatsbyPluginImagePage = ({ data }) => {

- {node.title} ({node.file.fileName.split(".").pop()}) + {node.title} ({node.fileName.split(".").pop()})

{node.description &&

{node.description}

} {node.constrained ? ( ) : ( - + )}
))} @@ -231,10 +231,8 @@ export const pageQuery = graphql` nodes { title description - file { - fileName - url - } + fileName + url constrained: gatsbyImageData(width: 420) fullWidth: gatsbyImageData(width: 200, layout: FIXED) fixed: gatsbyImageData(width: 200, layout: FIXED) @@ -268,10 +266,8 @@ export const pageQuery = graphql` nodes { title description - file { - fileName - url - } + fileName + url constrained: gatsbyImageData(width: 420) } } @@ -284,10 +280,8 @@ export const pageQuery = graphql` nodes { title description - file { - fileName - url - } + fileName + url constrained: gatsbyImageData(width: 420) } } diff --git a/e2e-tests/contentful/src/pages/media-reference.js b/e2e-tests/contentful/src/pages/media-reference.js index 9361b6b641bc0..dfd9402cfeb8a 100644 --- a/e2e-tests/contentful/src/pages/media-reference.js +++ b/e2e-tests/contentful/src/pages/media-reference.js @@ -16,14 +16,12 @@ const MediaReferencePage = ({ data }) => { let content = null if (many) { content = many.map(imageData => ( - {title} + {title} )) } if (one) { - content = ( - {title} - ) + content = {title} } return ( @@ -41,38 +39,24 @@ const MediaReferencePage = ({ data }) => { let content = null if (manyLocalized) { content = manyLocalized.map(imageData => ( - {title} + {title} )) } if (oneLocalized) { content = ( - {title} + {title} ) } if (many) { content = many.map(imageData => ( - {title} + {title} )) } if (one) { - content = ( - {title} - ) + content = {title} } return ( @@ -92,38 +76,24 @@ const MediaReferencePage = ({ data }) => { let content = null if (manyLocalized) { content = manyLocalized.map(imageData => ( - {title} + {title} )) } if (oneLocalized) { content = ( - {title} + {title} ) } if (many) { content = many.map(imageData => ( - {title} + {title} )) } if (one) { - content = ( - {title} - ) + content = {title} } return ( @@ -155,14 +125,10 @@ export const pageQuery = graphql` id } one { - file { - url - } + url } many { - file { - url - } + url } } } @@ -179,24 +145,16 @@ export const pageQuery = graphql` id } one { - file { - url - } + url } many { - file { - url - } + url } oneLocalized { - file { - url - } + url } manyLocalized { - file { - url - } + url } } } @@ -213,24 +171,16 @@ export const pageQuery = graphql` id } one { - file { - url - } + url } many { - file { - url - } + url } oneLocalized { - file { - url - } + url } manyLocalized { - file { - url - } + url } } } diff --git a/packages/gatsby-source-contentful/src/__tests__/gatsby-node.js b/packages/gatsby-source-contentful/src/__tests__/gatsby-node.js index ac4082c9385b5..dd7329213cf3c 100644 --- a/packages/gatsby-source-contentful/src/__tests__/gatsby-node.js +++ b/packages/gatsby-source-contentful/src/__tests__/gatsby-node.js @@ -260,6 +260,8 @@ describe(`gatsby-node`, () => { }) ) + const file = getFieldValue(asset.fields.file, locale, defaultLocale) + // check if asset exists expect(getNode(assetId)).toMatchObject({ title: getFieldValue(asset.fields.title, locale, defaultLocale), @@ -268,7 +270,12 @@ describe(`gatsby-node`, () => { locale, defaultLocale ), - file: getFieldValue(asset.fields.file, locale, defaultLocale), + contentType: file.contentType, + fileName: file.fileName, + url: file.url, + size: file.details.size, + width: file.details?.image?.width || null, + height: file.details?.image?.height || null, }) }) }) diff --git a/packages/gatsby-source-contentful/src/extend-node-type.js b/packages/gatsby-source-contentful/src/extend-node-type.js index b25ceb2bfda8a..2e047524500b7 100644 --- a/packages/gatsby-source-contentful/src/extend-node-type.js +++ b/packages/gatsby-source-contentful/src/extend-node-type.js @@ -1,20 +1,9 @@ // @ts-check import { stripIndent } from "common-tags" -import { - GraphQLBoolean, - GraphQLInt, - GraphQLJSON, - GraphQLList, -} from "gatsby/graphql" +import { GraphQLBoolean, GraphQLInt, GraphQLJSON } from "gatsby/graphql" import { resolveGatsbyImageData } from "./gatsby-plugin-image" -import { - ImageCropFocusType, - ImageFormatType, - ImageLayoutType, - ImagePlaceholderType, - ImageResizingBehavior, -} from "./schemes" +import { ImageCropFocusType, ImageResizingBehavior } from "./schemes" export async function setFieldsOnGraphQLNodeType({ type, cache }) { if (type.name !== `ContentfulAsset`) { diff --git a/packages/gatsby-source-contentful/src/gatsby-plugin-image.js b/packages/gatsby-source-contentful/src/gatsby-plugin-image.js index 959b3a1fd9a77..9b57ebd001ef2 100644 --- a/packages/gatsby-source-contentful/src/gatsby-plugin-image.js +++ b/packages/gatsby-source-contentful/src/gatsby-plugin-image.js @@ -81,10 +81,7 @@ export const getBase64Image = (imageProps, cache) => { const getTracedSVG = async ({ image, options, cache }) => { const { traceSVG } = await import(`gatsby-plugin-sharp`) - - const { - file: { contentType, url: imgUrl, fileName }, - } = image + const { url: imgUrl, fileName, contentType } = image if (contentType.indexOf(`image/`) !== 0) { return null @@ -104,7 +101,7 @@ const getTracedSVG = async ({ image, options, cache }) => { return traceSVG({ file: { internal: image.internal, - name: image.file.fileName, + name: fileName, extension, absolutePath, }, @@ -170,20 +167,18 @@ const getDominantColor = async ({ image, options, cache }) => { } function getBasicImageProps(image, args) { - let aspectRatio + let { width, height } = image if (args.width && args.height) { - aspectRatio = args.width / args.height - } else { - aspectRatio = - image.file.details.image.width / image.file.details.image.height + width = args.width + height = args.height } return { - baseUrl: image.file.url, - contentType: image.file.contentType, - aspectRatio, - width: image.file.details.image.width, - height: image.file.details.image.height, + baseUrl: image.url, + contentType: image.contentType, + aspectRatio: width / height, + width, + height, } } diff --git a/packages/gatsby-source-contentful/src/generate-schema.js b/packages/gatsby-source-contentful/src/generate-schema.js index b55d701cf99e3..27cef28b4c103 100644 --- a/packages/gatsby-source-contentful/src/generate-schema.js +++ b/packages/gatsby-source-contentful/src/generate-schema.js @@ -107,32 +107,14 @@ const translateFieldType = field => { function generateAssetTypes({ createTypes }) { createTypes(` type ContentfulAsset implements ContentfulInternalReference & Node { - file: ContentfulAssetFile - title: String - description: String sys: ContentfulInternalSys id: ID! - } - `) - - createTypes(` - type ContentfulAssetFile @derivedTypes { - url: String - details: ContentfulAssetFileDetails - fileName: String + title: String + description: String contentType: String - } - `) - - createTypes(` - type ContentfulAssetFileDetails @derivedTypes { + fileName: String + url: String size: Int - image: ContentfulAssetFileDetailsImage - } - `) - - createTypes(` - type ContentfulAssetFileDetailsImage { width: Int height: Int } @@ -187,24 +169,21 @@ export function generateSchema({ generateAssetTypes({ createTypes }) // Rich Text - const makeRichTextLinksResolver = (nodeType, entityType) => ( - source, - args, - context - ) => { - const links = getRichTextEntityLinks(source, nodeType)[entityType].map( - ({ id }) => id - ) + const makeRichTextLinksResolver = + (nodeType, entityType) => (source, args, context) => { + const links = getRichTextEntityLinks(source, nodeType)[entityType].map( + ({ id }) => id + ) - return context.nodeModel.getAllNodes().filter( - node => - node.internal.owner === `gatsby-source-contentful` && - node?.sys?.id && - node?.sys?.type === entityType && - links.includes(node.sys.id) - // @todo how can we check for correct space and environment? We need to access the sys field of the fields parent entry. - ) - } + return context.nodeModel.getAllNodes().filter( + node => + node.internal.owner === `gatsby-source-contentful` && + node?.sys?.id && + node?.sys?.type === entityType && + links.includes(node.sys.id) + // @todo how can we check for correct space and environment? We need to access the sys field of the fields parent entry. + ) + } // Contentful specific types if (pluginConfig.get(`enableTags`)) { diff --git a/packages/gatsby-source-contentful/src/image-helpers.js b/packages/gatsby-source-contentful/src/image-helpers.js index 7bfe412e93f69..dcfc5ecde2836 100644 --- a/packages/gatsby-source-contentful/src/image-helpers.js +++ b/packages/gatsby-source-contentful/src/image-helpers.js @@ -20,7 +20,7 @@ export const mimeTypeExtensions = new Map([ // Check if Contentful asset is actually an image export function isImage(image) { - return mimeTypeExtensions.has(image?.file?.contentType) + return mimeTypeExtensions.has(image?.contentType) } // Create a Contentful Image API url diff --git a/packages/gatsby-source-contentful/src/normalize.js b/packages/gatsby-source-contentful/src/normalize.js index 753bd0fe83449..cbe14764d5509 100644 --- a/packages/gatsby-source-contentful/src/normalize.js +++ b/packages/gatsby-source-contentful/src/normalize.js @@ -585,15 +585,12 @@ export const createAssetNodes = ({ localesFallback, }) + const file = getField(assetItem.fields.file) + const assetNode = { id: mId(space.sys.id, assetItem.sys.id, assetItem.sys.type), parent: null, children: [], - file: assetItem.fields.file ? getField(assetItem.fields.file) : null, - title: assetItem.fields.title ? getField(assetItem.fields.title) : ``, - description: assetItem.fields.description - ? getField(assetItem.fields.description) - : ``, internal: { type: `${makeTypeName(`Asset`)}`, // The content of an asset is guaranteed to be updated if and only if the .sys.updatedAt field changed @@ -611,6 +608,16 @@ export const createAssetNodes = ({ publishedAt: assetItem.sys.updatedAt, publishedVersion: assetItem.sys.revision, }, + title: assetItem.fields.title ? getField(assetItem.fields.title) : ``, + description: assetItem.fields.description + ? getField(assetItem.fields.description) + : ``, + contentType: file.contentType, + fileName: file.fileName, + url: file.url, + size: file.details.size, + width: file.details?.image?.width || null, + height: file.details?.image?.height || null, } // Link tags