From 841d8191e5158a47a15be95465c4ec0b2643c456 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benedikt=20R=C3=B6tsch?= Date: Mon, 12 Apr 2021 10:55:53 +0200 Subject: [PATCH 01/34] WIP - initial schema generation --- .../src/gatsby-node.js | 2 +- .../src/generate-schema.js | 211 ++++++++++++++++++ .../gatsby-source-contentful/src/normalize.js | 7 +- .../src/source-nodes.js | 19 +- 4 files changed, 232 insertions(+), 7 deletions(-) create mode 100644 packages/gatsby-source-contentful/src/generate-schema.js diff --git a/packages/gatsby-source-contentful/src/gatsby-node.js b/packages/gatsby-source-contentful/src/gatsby-node.js index 7e7981df2c86d..b9d0ec13607b7 100644 --- a/packages/gatsby-source-contentful/src/gatsby-node.js +++ b/packages/gatsby-source-contentful/src/gatsby-node.js @@ -6,8 +6,8 @@ import fetchRetry from "@vercel/fetch-retry" import { maskText } from "./plugin-options" export { createSchemaCustomization } from "./create-schema-customization" -export { sourceNodes } from "./source-nodes" export { setFieldsOnGraphQLNodeType } from "./extend-node-type" +export { sourceNodes } from "./source-nodes" const fetch = fetchRetry(origFetch) diff --git a/packages/gatsby-source-contentful/src/generate-schema.js b/packages/gatsby-source-contentful/src/generate-schema.js new file mode 100644 index 0000000000000..5abc7241baab4 --- /dev/null +++ b/packages/gatsby-source-contentful/src/generate-schema.js @@ -0,0 +1,211 @@ +const fs = require(`fs`) + +import { makeTypeName } from "./normalize" + +const types = [] + +function generateAssetSchemas({ createTypes }) { + createTypes(` + type ContentfulAsset implements ContentfulReference & Node @derivedTypes @dontInfer { + contentful_id: String! + spaceId: String + createdAt: Date @dateformat + updatedAt: Date @dateformat + file: ContentfulAssetFile + title: String + description: String + node_locale: String + sys: ContentfulAssetSys + } + `) + + createTypes(` + type ContentfulAssetFile @derivedTypes { + url: String + details: ContentfulAssetFileDetails + fileName: String + contentType: String + } + `) + + createTypes(` + type ContentfulAssetFileDetails @derivedTypes { + size: Int + image: ContentfulAssetFileDetailsImage + } + `) + + createTypes(` + type ContentfulAssetFileDetailsImage { + width: Int + height: Int + } + `) + + createTypes(` + type ContentfulAssetSys { + type: String + revision: Int + } + `) +} + +export function generateSchemas({ + createTypes, + schema, + pluginConfig, + contentTypeItems, +}) { + // logger @todo remove it + const origTypes = createTypes + createTypes = (...all) => { + types.push(all) + origTypes(...all) + } + + createTypes(` + interface ContentfulEntry implements Node { + contentful_id: String! + id: ID! + node_locale: String! + } + `) + + createTypes(` + interface ContentfulReference { + contentful_id: String! + id: ID! + } + `) + + generateAssetSchemas({ createTypes }) + + // Contentful specific types + + if (pluginConfig.get(`enableTags`)) { + createTypes( + schema.buildObjectType({ + name: `ContentfulTag`, + fields: { + name: { type: `String!` }, + contentful_id: { type: `String!` }, + id: { type: `ID!` }, + }, + interfaces: [`Node`], + extensions: { dontInfer: {} }, + }) + ) + } + + createTypes( + schema.buildObjectType({ + name: `ContentfulRichTextNode`, + fields: { + raw: { type: `String!` }, + references: { type: `ContentfulReference` }, + }, + interfaces: [`Node`], + }) + ) + + createTypes( + schema.buildObjectType({ + name: `ContentfulLocationNode`, + fields: { + lat: { type: `Float!` }, + lon: { type: `Float!` }, + }, + interfaces: [`Node`], + }) + ) + + createTypes( + schema.buildObjectType({ + name: `ContentfulJSONNode`, + fields: {}, + interfaces: [`Node`], + }) + ) + + createTypes( + schema.buildObjectType({ + name: `ContentfulTextNode`, + fields: {}, + interfaces: [`Node`], + }) + ) + + // Contentful content type schemas + const ContentfulDataTypes = new Map([ + [`Symbol`, `String`], + [`Text`, `String`], + [`Integer`, `Int`], + [`Number`, `Float`], + [`Date`, `Date`], + [`Object`, `JSON`], + [`Boolean`, `Boolean`], + [`Location`, `ContentfulLocationNode`], + [`RichText`, `ContentfulRichTextNode`], + ]) + const getLinkFieldType = linkType => `Contentful${linkType}` + + const translateFieldType = field => { + let id + if (field.type === `Array`) { + id = `[${ + field.items.type === `Link` + ? getLinkFieldType(field.items.linkType) + : translateFieldType(field.items) + }]` + } else if (field.type === `Link`) { + id = getLinkFieldType(field.linkType) + } else { + id = ContentfulDataTypes.get(field.type) + } + + return [id, field.required && `!`].filter(Boolean).join(``) + } + + contentTypeItems.forEach(contentTypeItem => { + try { + const fields = {} + contentTypeItem.fields.forEach(field => { + if (field.disabled || field.omitted) { + return + } + const type = translateFieldType(field) + fields[field.id] = { type } + }) + + // console.log(contentTypeItem.sys.id, { fields }) + + const type = pluginConfig.get(`useNameForId`) + ? contentTypeItem.name + : contentTypeItem.sys.id + + createTypes( + schema.buildObjectType({ + name: makeTypeName(type), + fields: { + contentful_id: { type: `String!` }, + id: { type: `ID!` }, + node_locale: { type: `String!` }, + ...fields, + }, + interfaces: [`ContentfulReference`, `ContentfulEntry`, `Node`], + }) + ) + } catch (err) { + err.message = `Unable to create schema for Contentful Content Type ${ + contentTypeItem.name || contentTypeItem.sys.id + }:\n${err.message}` + throw err + } + }) + + fs.writeFileSync( + process.cwd() + `/generated-types.json`, + JSON.stringify(types, null, 2) + ) + createTypes = origTypes +} diff --git a/packages/gatsby-source-contentful/src/normalize.js b/packages/gatsby-source-contentful/src/normalize.js index adc6e976cd2b2..5ea3a72220989 100644 --- a/packages/gatsby-source-contentful/src/normalize.js +++ b/packages/gatsby-source-contentful/src/normalize.js @@ -5,7 +5,8 @@ import { getGatsbyVersion } from "gatsby-core-utils" import { lt, prerelease } from "semver" const typePrefix = `Contentful` -const makeTypeName = type => _.upperFirst(_.camelCase(`${typePrefix} ${type}`)) +export const makeTypeName = type => + _.upperFirst(_.camelCase(`${typePrefix} ${type}`)) const GATSBY_VERSION_MANIFEST_V2 = `4.3.0` const gatsbyVersion = @@ -189,7 +190,7 @@ function prepareTextNode(id, node, key, text) { children: [], [key]: str, internal: { - type: _.camelCase(`${node.internal.type} ${key} TextNode`), + type: `ContentfulTextNode`, mediaType: `text/markdown`, content: str, // entryItem.sys.updatedAt is source of truth from contentful @@ -213,7 +214,7 @@ function prepareJSONNode(id, node, key, content) { parent: node.id, children: [], internal: { - type: _.camelCase(`${node.internal.type} ${key} JSONNode`), + type: `ContentfulJSONNode`, mediaType: `application/json`, content: str, // entryItem.sys.updatedAt is source of truth from contentful diff --git a/packages/gatsby-source-contentful/src/source-nodes.js b/packages/gatsby-source-contentful/src/source-nodes.js index cd7374c8cd03f..8bd51a0cff385 100644 --- a/packages/gatsby-source-contentful/src/source-nodes.js +++ b/packages/gatsby-source-contentful/src/source-nodes.js @@ -4,6 +4,7 @@ import _ from "lodash" import { downloadContentfulAssets } from "./download-contentful-assets" import { fetchContent } from "./fetch" +import { generateSchemas } from "./generate-schema" import { buildEntryList, buildForeignReferenceMap, @@ -49,11 +50,17 @@ export async function sourceNodes( getCache, reporter, parentSpan, + schema, }, pluginOptions ) { - const { createNode, touchNode, deleteNode, unstable_createNodeManifest } = - actions + const { + createNode, + touchNode, + deleteNode, + unstable_createNodeManifest, + createTypes, + } = actions const online = await isOnline() if ( @@ -180,6 +187,9 @@ export async function sourceNodes( ) processingActivity.start() + // Generate schemas based on Contentful content model + generateSchemas({ createTypes, schema, pluginConfig, contentTypeItems }) + // Array of all existing Contentful nodes const existingNodes = getNodes().filter( n => @@ -220,7 +230,10 @@ export async function sourceNodes( reporter.verbose(`Building Contentful reference map`) - const entryList = buildEntryList({ contentTypeItems, currentSyncData }) + const entryList = buildEntryList({ + currentSyncData, + contentTypeItems, + }) const { assets } = currentSyncData // Create map of resolvable ids so we can check links against them while creating From 3b3fb37fa6356e11f95dca47ff3ad3d8b9a70c57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benedikt=20R=C3=B6tsch?= Date: Mon, 12 Apr 2021 11:11:12 +0200 Subject: [PATCH 02/34] allow complex field types and add date formatter for date fields --- .../src/generate-schema.js | 30 +++++++++++++++---- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/packages/gatsby-source-contentful/src/generate-schema.js b/packages/gatsby-source-contentful/src/generate-schema.js index 5abc7241baab4..94c7f50eea71d 100644 --- a/packages/gatsby-source-contentful/src/generate-schema.js +++ b/packages/gatsby-source-contentful/src/generate-schema.js @@ -141,7 +141,15 @@ export function generateSchemas({ [`Text`, `String`], [`Integer`, `Int`], [`Number`, `Float`], - [`Date`, `Date`], + [ + `Date`, + { + type: `Date`, + extensions: { + dateformat: {}, + }, + }, + ], [`Object`, `JSON`], [`Boolean`, `Boolean`], [`Location`, `ContentfulLocationNode`], @@ -152,18 +160,30 @@ export function generateSchemas({ const translateFieldType = field => { let id if (field.type === `Array`) { - id = `[${ + const fieldData = field.items.type === `Link` ? getLinkFieldType(field.items.linkType) : translateFieldType(field.items) - }]` + + id = + typeof fieldData === `string` + ? `[${fieldData}]` + : { ...fieldData, type: `[${fieldData.type}]` } } else if (field.type === `Link`) { id = getLinkFieldType(field.linkType) } else { id = ContentfulDataTypes.get(field.type) } - return [id, field.required && `!`].filter(Boolean).join(``) + if (typeof id === `string`) { + return [id, field.required && `!`].filter(Boolean).join(``) + } + + if (field.required) { + id.type = `${id.type}!` + } + + return id } contentTypeItems.forEach(contentTypeItem => { @@ -174,7 +194,7 @@ export function generateSchemas({ return } const type = translateFieldType(field) - fields[field.id] = { type } + fields[field.id] = typeof type === `string` ? { type } : type }) // console.log(contentTypeItem.sys.id, { fields }) From ce752bc77f5c75b5bd77409d50e9e7615731090d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benedikt=20R=C3=B6tsch?= Date: Mon, 12 Apr 2021 11:17:34 +0200 Subject: [PATCH 03/34] move generic fields to reference type --- packages/gatsby-source-contentful/src/generate-schema.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/gatsby-source-contentful/src/generate-schema.js b/packages/gatsby-source-contentful/src/generate-schema.js index 94c7f50eea71d..b1c8ba35cc524 100644 --- a/packages/gatsby-source-contentful/src/generate-schema.js +++ b/packages/gatsby-source-contentful/src/generate-schema.js @@ -7,10 +7,6 @@ const types = [] function generateAssetSchemas({ createTypes }) { createTypes(` type ContentfulAsset implements ContentfulReference & Node @derivedTypes @dontInfer { - contentful_id: String! - spaceId: String - createdAt: Date @dateformat - updatedAt: Date @dateformat file: ContentfulAssetFile title: String description: String @@ -75,6 +71,9 @@ export function generateSchemas({ interface ContentfulReference { contentful_id: String! id: ID! + spaceId: String!, + createdAt: Date @dateform, + updatedAt: Date @dateform, } `) From a963c8c7a5e996c5500616f59b3ff8d3714913d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benedikt=20R=C3=B6tsch?= Date: Mon, 12 Apr 2021 13:21:15 +0200 Subject: [PATCH 04/34] use generic types for entry sys and content types --- .../src/generate-schema.js | 41 +++++++++++++++---- .../gatsby-source-contentful/src/normalize.js | 41 ++++++++++++------- 2 files changed, 59 insertions(+), 23 deletions(-) diff --git a/packages/gatsby-source-contentful/src/generate-schema.js b/packages/gatsby-source-contentful/src/generate-schema.js index b1c8ba35cc524..b70c7ee2ad4c0 100644 --- a/packages/gatsby-source-contentful/src/generate-schema.js +++ b/packages/gatsby-source-contentful/src/generate-schema.js @@ -6,12 +6,17 @@ const types = [] function generateAssetSchemas({ createTypes }) { createTypes(` - type ContentfulAsset implements ContentfulReference & Node @derivedTypes @dontInfer { + type ContentfulAsset implements ContentfulReference & Node { file: ContentfulAssetFile title: String description: String node_locale: String sys: ContentfulAssetSys + contentful_id: String! + id: ID! + spaceId: String! + createdAt: String! # Date @dateform, + updatedAt: String! # Date @dateform, } `) @@ -60,20 +65,36 @@ export function generateSchemas({ } createTypes(` - interface ContentfulEntry implements Node { + interface ContentfulReference implements Node { contentful_id: String! id: ID! - node_locale: String! } `) createTypes(` - interface ContentfulReference { + type ContentfulContentType implements Node { + id: ID! + name: String! + displayField: String! + description: String! + } + `) + + createTypes(` + type ContentfulSys implements Node { + id: ID! + type: String + revision: Int + contentType: ContentfulContentType @link(by: "id", from: "contentType___NODE") + } + `) + + createTypes(` + interface ContentfulEntry implements Node { contentful_id: String! id: ID! - spaceId: String!, - createdAt: Date @dateform, - updatedAt: Date @dateform, + spaceId: String! + sys: ContentfulSys @link(by: "id", from: "sys___NODE") } `) @@ -196,8 +217,6 @@ export function generateSchemas({ fields[field.id] = typeof type === `string` ? { type } : type }) - // console.log(contentTypeItem.sys.id, { fields }) - const type = pluginConfig.get(`useNameForId`) ? contentTypeItem.name : contentTypeItem.sys.id @@ -209,6 +228,10 @@ export function generateSchemas({ contentful_id: { type: `String!` }, id: { type: `ID!` }, node_locale: { type: `String!` }, + spaceId: { type: `String!` }, + // @todo these should be real dates and in sys + createdAt: { type: `String!` }, // { type: `Date`, extensions: { dateform: {} } }, + updatedAt: { type: `String!` }, // { type: `Date`, extensions: { dateform: {} } }, ...fields, }, interfaces: [`ContentfulReference`, `ContentfulEntry`, `Node`], diff --git a/packages/gatsby-source-contentful/src/normalize.js b/packages/gatsby-source-contentful/src/normalize.js index 5ea3a72220989..8f243cf678752 100644 --- a/packages/gatsby-source-contentful/src/normalize.js +++ b/packages/gatsby-source-contentful/src/normalize.js @@ -196,9 +196,6 @@ function prepareTextNode(id, node, key, text) { // entryItem.sys.updatedAt is source of truth from contentful contentDigest: node.updatedAt, }, - sys: { - type: node.sys.type, - }, } node.children = node.children.concat([id]) @@ -220,9 +217,6 @@ function prepareJSONNode(id, node, key, content) { // entryItem.sys.updatedAt is source of truth from contentful contentDigest: node.updatedAt, }, - sys: { - type: node.sys.type, - }, } node.children = node.children.concat([id]) @@ -333,8 +327,6 @@ export const createNodesForContentType = ({ // Create a node for the content type const contentTypeNode = { id: createNodeId(contentTypeItemId), - parent: null, - children: [], name: contentTypeItem.name, displayField: contentTypeItem.displayField, description: contentTypeItem.description, @@ -342,9 +334,6 @@ export const createNodesForContentType = ({ type: `${makeTypeName(`ContentType`)}`, contentDigest: contentTypeItem.sys.updatedAt, }, - sys: { - type: contentTypeItem.sys.type, - }, } createNodePromises.push(createNode(contentTypeNode)) @@ -495,6 +484,32 @@ export const createNodesForContentType = ({ }) } + // Create sys node + const sysId = createNodeId(`${entryNodeId}.sys`) + + const sys = { + id: sysId, + // parent___NODE: entryNodeId, + type: entryItem.sys.type, + internal: { + type: `ContentfulSys`, + contentDigest: entryItem.sys.updatedAt, + }, + } + + // Revision applies to entries, assets, and content types + if (entryItem.sys.revision) { + sys.revision = entryItem.sys.revision + } + + // Content type applies to entries only + if (entryItem.sys.contentType) { + sys.contentType___NODE = createNodeId(contentTypeItemId) + } + + childrenNodes.push(sys) + + // Create actual entry node let entryNode = { id: entryNodeId, spaceId: space.sys.id, @@ -506,9 +521,7 @@ export const createNodesForContentType = ({ internal: { type: `${makeTypeName(contentTypeItemId)}`, }, - sys: { - type: entryItem.sys.type, - }, + sys___NODE: sysId, } contentfulCreateNodeManifest({ From 449ffa25b7b51372456a798115b5739c322e2c79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benedikt=20R=C3=B6tsch?= Date: Mon, 12 Apr 2021 13:53:35 +0200 Subject: [PATCH 05/34] use generic types for rich text fields --- .../src/generate-schema.js | 16 ++++++++++++++-- .../gatsby-source-contentful/src/normalize.js | 18 ++++++++++++++++-- .../src/source-nodes.js | 2 ++ 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/packages/gatsby-source-contentful/src/generate-schema.js b/packages/gatsby-source-contentful/src/generate-schema.js index b70c7ee2ad4c0..716fd1f099ebd 100644 --- a/packages/gatsby-source-contentful/src/generate-schema.js +++ b/packages/gatsby-source-contentful/src/generate-schema.js @@ -119,7 +119,7 @@ export function generateSchemas({ createTypes( schema.buildObjectType({ - name: `ContentfulRichTextNode`, + name: `ContentfulNodeTypeRichText`, fields: { raw: { type: `String!` }, references: { type: `ContentfulReference` }, @@ -173,7 +173,15 @@ export function generateSchemas({ [`Object`, `JSON`], [`Boolean`, `Boolean`], [`Location`, `ContentfulLocationNode`], - [`RichText`, `ContentfulRichTextNode`], + [ + `RichText`, + { + type: `ContentfulNodeTypeRichText`, + extensions: { + link: { by: `id` }, + }, + }, + ], ]) const getLinkFieldType = linkType => `Contentful${linkType}` @@ -203,6 +211,10 @@ export function generateSchemas({ id.type = `${id.type}!` } + if (id.extensions.link) { + id.extensions.link.from = `${field.id}___NODE` + } + return id } diff --git a/packages/gatsby-source-contentful/src/normalize.js b/packages/gatsby-source-contentful/src/normalize.js index 8f243cf678752..b8d0cdaa922dd 100644 --- a/packages/gatsby-source-contentful/src/normalize.js +++ b/packages/gatsby-source-contentful/src/normalize.js @@ -303,6 +303,7 @@ export const createNodesForContentType = ({ unstable_createNodeManifest, createNode, createNodeId, + createContentDigest, getNode, resolvable, foreignReferenceMap, @@ -618,10 +619,23 @@ export const createNodesForContentType = ({ ) }) - entryItemFields[entryItemFieldKey] = { - raw: stringify(fieldValue), + const richTextNodeId = createNodeId( + `${entryNodeId}.${entryItemFieldKey}.richText` + ) + + const raw = stringify(fieldValue) + const richTextNode = { + id: richTextNodeId, + raw, references___NODE: [...resolvableReferenceIds], + internal: { + type: `ContentfulNodeTypeRichText`, + contentDigest: createContentDigest(raw), + }, } + childrenNodes.push(richTextNode) + delete entryItemFields[entryItemFieldKey] + entryItemFields[`${entryItemFieldKey}___NODE`] = richTextNodeId } else if ( fieldType === `Object` && _.isPlainObject(entryItemFields[entryItemFieldKey]) diff --git a/packages/gatsby-source-contentful/src/source-nodes.js b/packages/gatsby-source-contentful/src/source-nodes.js index 8bd51a0cff385..ec362163679b2 100644 --- a/packages/gatsby-source-contentful/src/source-nodes.js +++ b/packages/gatsby-source-contentful/src/source-nodes.js @@ -51,6 +51,7 @@ export async function sourceNodes( reporter, parentSpan, schema, + createContentDigest, }, pluginOptions ) { @@ -370,6 +371,7 @@ export async function sourceNodes( useNameForId: pluginConfig.get(`useNameForId`), pluginConfig, unstable_createNodeManifest, + createContentDigest, }) ) } From 147cdec5866d6cde70f68a72504efb918647ea89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benedikt=20R=C3=B6tsch?= Date: Mon, 12 Apr 2021 14:06:57 +0200 Subject: [PATCH 06/34] use generic types for location fields --- .../src/generate-schema.js | 12 +++++- .../gatsby-source-contentful/src/normalize.js | 42 +++++++++++++++++++ 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/packages/gatsby-source-contentful/src/generate-schema.js b/packages/gatsby-source-contentful/src/generate-schema.js index 716fd1f099ebd..f504bde16f0fe 100644 --- a/packages/gatsby-source-contentful/src/generate-schema.js +++ b/packages/gatsby-source-contentful/src/generate-schema.js @@ -130,7 +130,7 @@ export function generateSchemas({ createTypes( schema.buildObjectType({ - name: `ContentfulLocationNode`, + name: `ContentfulNodeTypeLocation`, fields: { lat: { type: `Float!` }, lon: { type: `Float!` }, @@ -172,7 +172,15 @@ export function generateSchemas({ ], [`Object`, `JSON`], [`Boolean`, `Boolean`], - [`Location`, `ContentfulLocationNode`], + [ + `Location`, + { + type: `ContentfulNodeTypeLocation`, + extensions: { + link: { by: `id` }, + }, + }, + ], [ `RichText`, { diff --git a/packages/gatsby-source-contentful/src/normalize.js b/packages/gatsby-source-contentful/src/normalize.js index b8d0cdaa922dd..89dda3ea92475 100644 --- a/packages/gatsby-source-contentful/src/normalize.js +++ b/packages/gatsby-source-contentful/src/normalize.js @@ -203,6 +203,23 @@ function prepareTextNode(id, node, key, text) { return textNode } +function prepareLocationNode(id, node, key, data) { + const { lat, lon } = data + const LocationNode = { + id, + parent: node.id, + lat, + lon, + internal: { + type: `ContentfulNodeTypeLocation`, + // entryItem.sys.updatedAt is source of truth from contentful + contentDigest: node.updatedAt, + }, + } + + return LocationNode +} + function prepareJSONNode(id, node, key, content) { const str = JSON.stringify(content) const JSONNode = { @@ -693,6 +710,31 @@ export const createNodesForContentType = ({ entryItemFields[`${entryItemFieldKey}___NODE`].push(jsonNodeId) }) + delete entryItemFields[entryItemFieldKey] + } else if (fieldType === `Location`) { + const locationNodeId = createNodeId( + `${entryNodeId}${entryItemFieldKey}Location` + ) + + // The Contentful model has `.sys.updatedAt` leading for an entry. If the updatedAt value + // of an entry did not change, then we can trust that none of its children were changed either. + // (That's why child nodes use the updatedAt of the parent node as their digest, too) + const existingNode = getNode(locationNodeId) + if ( + existingNode?.internal?.contentDigest !== entryItem.sys.updatedAt + ) { + const textNode = prepareLocationNode( + locationNodeId, + entryNode, + entryItemFieldKey, + entryItemFields[entryItemFieldKey], + createNodeId + ) + + childrenNodes.push(textNode) + } + + entryItemFields[`${entryItemFieldKey}___NODE`] = locationNodeId delete entryItemFields[entryItemFieldKey] } }) From de774722ac61a07b47152a624d75015622b932a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benedikt=20R=C3=B6tsch?= Date: Mon, 12 Apr 2021 14:17:33 +0200 Subject: [PATCH 07/34] use generic types for JSON fields --- .../gatsby-source-contentful/src/generate-schema.js | 12 ++++++++++-- packages/gatsby-source-contentful/src/normalize.js | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/packages/gatsby-source-contentful/src/generate-schema.js b/packages/gatsby-source-contentful/src/generate-schema.js index f504bde16f0fe..61635fecdf390 100644 --- a/packages/gatsby-source-contentful/src/generate-schema.js +++ b/packages/gatsby-source-contentful/src/generate-schema.js @@ -141,7 +141,7 @@ export function generateSchemas({ createTypes( schema.buildObjectType({ - name: `ContentfulJSONNode`, + name: `ContentfulNodeTypeJSON`, fields: {}, interfaces: [`Node`], }) @@ -170,7 +170,15 @@ export function generateSchemas({ }, }, ], - [`Object`, `JSON`], + [ + `Object`, + { + type: `ContentfulNodeTypeJSON`, + extensions: { + link: { by: `id` }, + }, + }, + ], [`Boolean`, `Boolean`], [ `Location`, diff --git a/packages/gatsby-source-contentful/src/normalize.js b/packages/gatsby-source-contentful/src/normalize.js index 89dda3ea92475..df1a68da20b0c 100644 --- a/packages/gatsby-source-contentful/src/normalize.js +++ b/packages/gatsby-source-contentful/src/normalize.js @@ -228,7 +228,7 @@ function prepareJSONNode(id, node, key, content) { parent: node.id, children: [], internal: { - type: `ContentfulJSONNode`, + type: `ContentfulNodeTypeJSON`, mediaType: `application/json`, content: str, // entryItem.sys.updatedAt is source of truth from contentful From d6e9e31f8c59e845d001cafd4c09c1ee60726761 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benedikt=20R=C3=B6tsch?= Date: Mon, 12 Apr 2021 14:41:13 +0200 Subject: [PATCH 08/34] use generic types for Text fields --- packages/gatsby-source-contentful/README.md | 2 +- .../src/generate-schema.js | 16 +++++++++++++--- .../gatsby-source-contentful/src/normalize.js | 7 ++----- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/packages/gatsby-source-contentful/README.md b/packages/gatsby-source-contentful/README.md index c3512c12700ba..00f4e6a915bcf 100644 --- a/packages/gatsby-source-contentful/README.md +++ b/packages/gatsby-source-contentful/README.md @@ -257,7 +257,7 @@ On Contentful, a "Long text" field uses Markdown by default. The field is expose { contentfulCaseStudy { body { - body + raw } } } diff --git a/packages/gatsby-source-contentful/src/generate-schema.js b/packages/gatsby-source-contentful/src/generate-schema.js index 61635fecdf390..f7b85776ca270 100644 --- a/packages/gatsby-source-contentful/src/generate-schema.js +++ b/packages/gatsby-source-contentful/src/generate-schema.js @@ -149,8 +149,10 @@ export function generateSchemas({ createTypes( schema.buildObjectType({ - name: `ContentfulTextNode`, - fields: {}, + name: `ContentfulNodeTypeText`, + fields: { + raw: `String!`, + }, interfaces: [`Node`], }) ) @@ -158,7 +160,15 @@ export function generateSchemas({ // Contentful content type schemas const ContentfulDataTypes = new Map([ [`Symbol`, `String`], - [`Text`, `String`], + [ + `Text`, + { + type: `ContentfulNodeTypeText`, + extensions: { + link: { by: `id` }, + }, + }, + ], [`Integer`, `Int`], [`Number`, `Float`], [ diff --git a/packages/gatsby-source-contentful/src/normalize.js b/packages/gatsby-source-contentful/src/normalize.js index df1a68da20b0c..7fabb3091aea3 100644 --- a/packages/gatsby-source-contentful/src/normalize.js +++ b/packages/gatsby-source-contentful/src/normalize.js @@ -187,10 +187,9 @@ function prepareTextNode(id, node, key, text) { const textNode = { id, parent: node.id, - children: [], - [key]: str, + raw: str, internal: { - type: `ContentfulTextNode`, + type: `ContentfulNodeTypeText`, mediaType: `text/markdown`, content: str, // entryItem.sys.updatedAt is source of truth from contentful @@ -198,8 +197,6 @@ function prepareTextNode(id, node, key, text) { }, } - node.children = node.children.concat([id]) - return textNode } From 83fec2d54161f3f4026c3562491bf85f5d541be0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benedikt=20R=C3=B6tsch?= Date: Mon, 12 Apr 2021 15:02:53 +0200 Subject: [PATCH 09/34] fix: ensure links from is set properly --- packages/gatsby-source-contentful/src/generate-schema.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/gatsby-source-contentful/src/generate-schema.js b/packages/gatsby-source-contentful/src/generate-schema.js index f7b85776ca270..37ecf956a02e9 100644 --- a/packages/gatsby-source-contentful/src/generate-schema.js +++ b/packages/gatsby-source-contentful/src/generate-schema.js @@ -1,4 +1,5 @@ const fs = require(`fs`) +const { cloneDeep } = require(`lodash`) import { makeTypeName } from "./normalize" @@ -233,6 +234,8 @@ export function generateSchemas({ return [id, field.required && `!`].filter(Boolean).join(``) } + id = cloneDeep(id) + if (field.required) { id.type = `${id.type}!` } From 5a2d8597492aff4e0728ee56400d22eed4f15554 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benedikt=20R=C3=B6tsch?= Date: Mon, 12 Apr 2021 15:12:59 +0200 Subject: [PATCH 10/34] rename internal interfaces to avoid name collisions --- .../src/generate-schema.js | 16 ++++++++++------ .../gatsby-source-contentful/src/normalize.js | 2 +- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/packages/gatsby-source-contentful/src/generate-schema.js b/packages/gatsby-source-contentful/src/generate-schema.js index 37ecf956a02e9..ec1fd673544e3 100644 --- a/packages/gatsby-source-contentful/src/generate-schema.js +++ b/packages/gatsby-source-contentful/src/generate-schema.js @@ -7,7 +7,7 @@ const types = [] function generateAssetSchemas({ createTypes }) { createTypes(` - type ContentfulAsset implements ContentfulReference & Node { + type ContentfulAsset implements ContentfulInternalReference & Node { file: ContentfulAssetFile title: String description: String @@ -66,7 +66,7 @@ export function generateSchemas({ } createTypes(` - interface ContentfulReference implements Node { + interface ContentfulInternalReference implements Node { contentful_id: String! id: ID! } @@ -82,7 +82,7 @@ export function generateSchemas({ `) createTypes(` - type ContentfulSys implements Node { + type ContentfulInternalSys implements Node { id: ID! type: String revision: Int @@ -95,7 +95,7 @@ export function generateSchemas({ contentful_id: String! id: ID! spaceId: String! - sys: ContentfulSys @link(by: "id", from: "sys___NODE") + sys: ContentfulInternalSys @link(by: "id", from: "sys___NODE") } `) @@ -123,7 +123,7 @@ export function generateSchemas({ name: `ContentfulNodeTypeRichText`, fields: { raw: { type: `String!` }, - references: { type: `ContentfulReference` }, + references: { type: `ContentfulInternalReference` }, }, interfaces: [`Node`], }) @@ -275,7 +275,11 @@ export function generateSchemas({ updatedAt: { type: `String!` }, // { type: `Date`, extensions: { dateform: {} } }, ...fields, }, - interfaces: [`ContentfulReference`, `ContentfulEntry`, `Node`], + interfaces: [ + `ContentfulInternalReference`, + `ContentfulEntry`, + `Node`, + ], }) ) } catch (err) { diff --git a/packages/gatsby-source-contentful/src/normalize.js b/packages/gatsby-source-contentful/src/normalize.js index 7fabb3091aea3..97d5293f023b9 100644 --- a/packages/gatsby-source-contentful/src/normalize.js +++ b/packages/gatsby-source-contentful/src/normalize.js @@ -507,7 +507,7 @@ export const createNodesForContentType = ({ // parent___NODE: entryNodeId, type: entryItem.sys.type, internal: { - type: `ContentfulSys`, + type: `ContentfulInternalSys`, contentDigest: entryItem.sys.updatedAt, }, } From 897d287e354005872902847a1c6858390bcedeea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benedikt=20R=C3=B6tsch?= Date: Mon, 12 Apr 2021 15:17:31 +0200 Subject: [PATCH 11/34] properly set links for references to new generic types --- .../gatsby-source-contentful/src/generate-schema.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/gatsby-source-contentful/src/generate-schema.js b/packages/gatsby-source-contentful/src/generate-schema.js index ec1fd673544e3..65cb90c1c9a17 100644 --- a/packages/gatsby-source-contentful/src/generate-schema.js +++ b/packages/gatsby-source-contentful/src/generate-schema.js @@ -210,7 +210,15 @@ export function generateSchemas({ }, ], ]) - const getLinkFieldType = linkType => `Contentful${linkType}` + + const getLinkFieldType = linkType => { + return { + type: `Contentful${linkType}`, + extensions: { + link: { by: `id` }, + }, + } + } const translateFieldType = field => { let id From 61ff2b4f6a68a7f3d9b117db85bd00db3df299e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benedikt=20R=C3=B6tsch?= Date: Tue, 13 Apr 2021 15:35:52 +0200 Subject: [PATCH 12/34] no more create nodes for JSON, RichText and Location --- e2e-tests/contentful/src/pages/json.js | 21 +- e2e-tests/contentful/src/pages/text.js | 4 +- .../src/generate-schema.js | 119 ++++++----- .../gatsby-source-contentful/src/normalize.js | 197 +----------------- .../src/source-nodes.js | 4 +- 5 files changed, 80 insertions(+), 265 deletions(-) diff --git a/e2e-tests/contentful/src/pages/json.js b/e2e-tests/contentful/src/pages/json.js index b41d1bf54501e..45172e184fb0d 100644 --- a/e2e-tests/contentful/src/pages/json.js +++ b/e2e-tests/contentful/src/pages/json.js @@ -62,27 +62,10 @@ export default JSONPage export const pageQuery = graphql` query JSONQuery { simple: contentfulJson(contentful_id: { eq: "2r6tNjP8brkyy5yLR39hhh" }) { - json { - name - city - age - } + json } complex: contentfulJson(contentful_id: { eq: "2y71nV0cpW9vzTmJybq571" }) { - json { - Actors { - name - photo - Birthdate - Born_At - weight - age - wife - children - hasChildren - hasGreyHair - } - } + json } english: contentfulJson( node_locale: { eq: "en-US" } diff --git a/e2e-tests/contentful/src/pages/text.js b/e2e-tests/contentful/src/pages/text.js index bc39dd5ddfa6e..360a154201c5b 100644 --- a/e2e-tests/contentful/src/pages/text.js +++ b/e2e-tests/contentful/src/pages/text.js @@ -33,7 +33,7 @@ const TextPage = ({ data }) => {

Long (Plain):

-

{longPlain.longPlain.longPlain}

+

{longPlain.longPlain.raw}

Markdown (Simple):

{ + // eslint-disable-next-line guard-for-in + for (const k in obj) { + const v = obj[k] + if (v && v.sys && v.sys.type === `Link`) { + if (v.sys.linkType === `Asset`) { + console.log(`adding asset`, v) + referencedAssets.add(v.sys.id) + } + if (v.sys.linkType === `Entry`) { + console.log(`adding entry`, v) + referencedEntries.add(v.sys.id) + } + } else if (v && typeof v === `object`) { + traverse(v) + } + } + } + traverse(source) + + return context.nodeModel + .getAllNodes() + .filter(node => + node.internal.owner === `gatsby-source-contentful` && + node.internal.type === `ContentfulAsset` + ? referencedAssets.has(node.contentful_id) + : referencedEntries.has(node.contentful_id) + ) + }, + }, }, - interfaces: [`Node`], + extensions: { dontInfer: {} }, }) ) @@ -136,18 +176,13 @@ export function generateSchemas({ lat: { type: `Float!` }, lon: { type: `Float!` }, }, - interfaces: [`Node`], - }) - ) - - createTypes( - schema.buildObjectType({ - name: `ContentfulNodeTypeJSON`, - fields: {}, - interfaces: [`Node`], + extensions: { + dontInfer: {}, + }, }) ) + // Is there a way to have this as string and let transformer-remark replace it with an object? createTypes( schema.buildObjectType({ name: `ContentfulNodeTypeText`, @@ -155,6 +190,9 @@ export function generateSchemas({ raw: `String!`, }, interfaces: [`Node`], + extensions: { + dontInfer: {}, + }, }) ) @@ -181,34 +219,10 @@ export function generateSchemas({ }, }, ], - [ - `Object`, - { - type: `ContentfulNodeTypeJSON`, - extensions: { - link: { by: `id` }, - }, - }, - ], + [`Object`, `JSON`], [`Boolean`, `Boolean`], - [ - `Location`, - { - type: `ContentfulNodeTypeLocation`, - extensions: { - link: { by: `id` }, - }, - }, - ], - [ - `RichText`, - { - type: `ContentfulNodeTypeRichText`, - extensions: { - link: { by: `id` }, - }, - }, - ], + [`Location`, `ContentfulNodeTypeLocation`], + [`RichText`, `ContentfulNodeTypeRichText`], ]) const getLinkFieldType = linkType => { @@ -248,14 +262,14 @@ export function generateSchemas({ id.type = `${id.type}!` } - if (id.extensions.link) { + if (id?.extensions?.link) { id.extensions.link.from = `${field.id}___NODE` } return id } - contentTypeItems.forEach(contentTypeItem => { + for (const contentTypeItem of contentTypeItems) { try { const fields = {} contentTypeItem.fields.forEach(field => { @@ -276,11 +290,14 @@ export function generateSchemas({ fields: { contentful_id: { type: `String!` }, id: { type: `ID!` }, + // @todo reconsider the node per locale workflow node_locale: { type: `String!` }, - spaceId: { type: `String!` }, // @todo these should be real dates and in sys + spaceId: { type: `String!` }, createdAt: { type: `String!` }, // { type: `Date`, extensions: { dateform: {} } }, updatedAt: { type: `String!` }, // { type: `Date`, extensions: { dateform: {} } }, + // @todo add metadata + sys: { type: `ContentfulInternalSys` }, ...fields, }, interfaces: [ @@ -296,7 +313,7 @@ export function generateSchemas({ }:\n${err.message}` throw err } - }) + } fs.writeFileSync( process.cwd() + `/generated-types.json`, diff --git a/packages/gatsby-source-contentful/src/normalize.js b/packages/gatsby-source-contentful/src/normalize.js index 97d5293f023b9..06fc95d65751d 100644 --- a/packages/gatsby-source-contentful/src/normalize.js +++ b/packages/gatsby-source-contentful/src/normalize.js @@ -200,44 +200,6 @@ function prepareTextNode(id, node, key, text) { return textNode } -function prepareLocationNode(id, node, key, data) { - const { lat, lon } = data - const LocationNode = { - id, - parent: node.id, - lat, - lon, - internal: { - type: `ContentfulNodeTypeLocation`, - // entryItem.sys.updatedAt is source of truth from contentful - contentDigest: node.updatedAt, - }, - } - - return LocationNode -} - -function prepareJSONNode(id, node, key, content) { - const str = JSON.stringify(content) - const JSONNode = { - ...(_.isPlainObject(content) ? { ...content } : { content: content }), - id, - parent: node.id, - children: [], - internal: { - type: `ContentfulNodeTypeJSON`, - mediaType: `application/json`, - content: str, - // entryItem.sys.updatedAt is source of truth from contentful - contentDigest: node.updatedAt, - }, - } - - node.children = node.children.concat([id]) - - return JSONNode -} - let numberOfContentSyncDebugLogs = 0 const maxContentSyncDebugLogTimes = 50 @@ -317,7 +279,6 @@ export const createNodesForContentType = ({ unstable_createNodeManifest, createNode, createNodeId, - createContentDigest, getNode, resolvable, foreignReferenceMap, @@ -499,17 +460,8 @@ export const createNodesForContentType = ({ }) } - // Create sys node - const sysId = createNodeId(`${entryNodeId}.sys`) - const sys = { - id: sysId, - // parent___NODE: entryNodeId, type: entryItem.sys.type, - internal: { - type: `ContentfulInternalSys`, - contentDigest: entryItem.sys.updatedAt, - }, } // Revision applies to entries, assets, and content types @@ -522,8 +474,6 @@ export const createNodesForContentType = ({ sys.contentType___NODE = createNodeId(contentTypeItemId) } - childrenNodes.push(sys) - // Create actual entry node let entryNode = { id: entryNodeId, @@ -535,8 +485,10 @@ export const createNodesForContentType = ({ children: [], internal: { type: `${makeTypeName(contentTypeItemId)}`, + // The content of an entry is guaranteed to be updated if and only if the .sys.updatedAt field changed + contentDigest: entryItem.sys.updatedAt, }, - sys___NODE: sysId, + sys, } contentfulCreateNodeManifest({ @@ -596,143 +548,6 @@ export const createNodesForContentType = ({ entryItemFields[`${entryItemFieldKey}___NODE`] = textNodeId delete entryItemFields[entryItemFieldKey] - } else if ( - fieldType === `RichText` && - _.isPlainObject(entryItemFields[entryItemFieldKey]) - ) { - const fieldValue = entryItemFields[entryItemFieldKey] - - const rawReferences = [] - - // Locate all Contentful Links within the rich text data - const traverse = obj => { - // eslint-disable-next-line guard-for-in - for (const k in obj) { - const v = obj[k] - if (v && v.sys && v.sys.type === `Link`) { - rawReferences.push(v) - } else if (v && typeof v === `object`) { - traverse(v) - } - } - } - - traverse(fieldValue) - - // Build up resolvable reference list - const resolvableReferenceIds = new Set() - rawReferences - .filter(function (v) { - return resolvable.has( - `${v.sys.id}___${v.sys.linkType || v.sys.type}` - ) - }) - .forEach(function (v) { - resolvableReferenceIds.add( - mId(space.sys.id, v.sys.id, v.sys.linkType || v.sys.type) - ) - }) - - const richTextNodeId = createNodeId( - `${entryNodeId}.${entryItemFieldKey}.richText` - ) - - const raw = stringify(fieldValue) - const richTextNode = { - id: richTextNodeId, - raw, - references___NODE: [...resolvableReferenceIds], - internal: { - type: `ContentfulNodeTypeRichText`, - contentDigest: createContentDigest(raw), - }, - } - childrenNodes.push(richTextNode) - delete entryItemFields[entryItemFieldKey] - entryItemFields[`${entryItemFieldKey}___NODE`] = richTextNodeId - } else if ( - fieldType === `Object` && - _.isPlainObject(entryItemFields[entryItemFieldKey]) - ) { - const jsonNodeId = createNodeId( - `${entryNodeId}${entryItemFieldKey}JSONNode` - ) - - // The Contentful model has `.sys.updatedAt` leading for an entry. If the updatedAt value - // of an entry did not change, then we can trust that none of its children were changed either. - // (That's why child nodes use the updatedAt of the parent node as their digest, too) - const existingNode = getNode(jsonNodeId) - if ( - existingNode?.internal?.contentDigest !== entryItem.sys.updatedAt - ) { - const jsonNode = prepareJSONNode( - jsonNodeId, - entryNode, - entryItemFieldKey, - entryItemFields[entryItemFieldKey] - ) - childrenNodes.push(jsonNode) - } - - entryItemFields[`${entryItemFieldKey}___NODE`] = jsonNodeId - delete entryItemFields[entryItemFieldKey] - } else if ( - fieldType === `Object` && - _.isArray(entryItemFields[entryItemFieldKey]) - ) { - entryItemFields[`${entryItemFieldKey}___NODE`] = [] - - entryItemFields[entryItemFieldKey].forEach((obj, i) => { - const jsonNodeId = createNodeId( - `${entryNodeId}${entryItemFieldKey}${i}JSONNode` - ) - - // The Contentful model has `.sys.updatedAt` leading for an entry. If the updatedAt value - // of an entry did not change, then we can trust that none of its children were changed either. - // (That's why child nodes use the updatedAt of the parent node as their digest, too) - const existingNode = getNode(jsonNodeId) - if ( - existingNode?.internal?.contentDigest !== - entryItem.sys.updatedAt - ) { - const jsonNode = prepareJSONNode( - jsonNodeId, - entryNode, - entryItemFieldKey, - obj - ) - childrenNodes.push(jsonNode) - } - - entryItemFields[`${entryItemFieldKey}___NODE`].push(jsonNodeId) - }) - - delete entryItemFields[entryItemFieldKey] - } else if (fieldType === `Location`) { - const locationNodeId = createNodeId( - `${entryNodeId}${entryItemFieldKey}Location` - ) - - // The Contentful model has `.sys.updatedAt` leading for an entry. If the updatedAt value - // of an entry did not change, then we can trust that none of its children were changed either. - // (That's why child nodes use the updatedAt of the parent node as their digest, too) - const existingNode = getNode(locationNodeId) - if ( - existingNode?.internal?.contentDigest !== entryItem.sys.updatedAt - ) { - const textNode = prepareLocationNode( - locationNodeId, - entryNode, - entryItemFieldKey, - entryItemFields[entryItemFieldKey], - createNodeId - ) - - childrenNodes.push(textNode) - } - - entryItemFields[`${entryItemFieldKey}___NODE`] = locationNodeId - delete entryItemFields[entryItemFieldKey] } }) @@ -742,9 +557,6 @@ export const createNodesForContentType = ({ node_locale: locale.code, } - // The content of an entry is guaranteed to be updated if and only if the .sys.updatedAt field changed - entryNode.internal.contentDigest = entryItem.sys.updatedAt - // Link tags if (pluginConfig.get(`enableTags`)) { entryNode.metadata = { @@ -807,7 +619,10 @@ export const createAssetNodes = ({ node_locale: locale.code, internal: { type: `${makeTypeName(`Asset`)}`, + // The content of an asset is guaranteed to be updated if and only if the .sys.updatedAt field changed + contentDigest: assetItem.sys.updatedAt, }, + // @todo we can probably remove this now sys: { type: assetItem.sys.type, }, diff --git a/packages/gatsby-source-contentful/src/source-nodes.js b/packages/gatsby-source-contentful/src/source-nodes.js index ec362163679b2..4487e3d0c7836 100644 --- a/packages/gatsby-source-contentful/src/source-nodes.js +++ b/packages/gatsby-source-contentful/src/source-nodes.js @@ -4,7 +4,7 @@ import _ from "lodash" import { downloadContentfulAssets } from "./download-contentful-assets" import { fetchContent } from "./fetch" -import { generateSchemas } from "./generate-schema" +import { generateSchema } from "./generate-schema" import { buildEntryList, buildForeignReferenceMap, @@ -189,7 +189,7 @@ export async function sourceNodes( processingActivity.start() // Generate schemas based on Contentful content model - generateSchemas({ createTypes, schema, pluginConfig, contentTypeItems }) + generateSchema({ createTypes, schema, pluginConfig, contentTypeItems }) // Array of all existing Contentful nodes const existingNodes = getNodes().filter( From 3a8df179788ac80a77b4ea35cfc102ff1dc478d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benedikt=20R=C3=B6tsch?= Date: Tue, 13 Apr 2021 17:08:53 +0200 Subject: [PATCH 13/34] refactor: clean up code --- .../references/content-reference.js | 13 +- .../contentful/src/pages/content-reference.js | 7 +- e2e-tests/contentful/src/pages/rich-text.js | 28 ++- .../src/generate-schema.js | 208 +++++++++--------- .../gatsby-source-contentful/src/rich-text.js | 2 +- 5 files changed, 134 insertions(+), 124 deletions(-) diff --git a/e2e-tests/contentful/src/components/references/content-reference.js b/e2e-tests/contentful/src/components/references/content-reference.js index f32ca3a656dde..d3b0e02d24cf3 100644 --- a/e2e-tests/contentful/src/components/references/content-reference.js +++ b/e2e-tests/contentful/src/components/references/content-reference.js @@ -1,16 +1,7 @@ import React from "react" -export const ContentfulContentReference = ({ - one, - many, - content_reference, - title, -}) => { - const references = [ - one, - ...(many || []), - ...(content_reference || []), - ].filter(Boolean) +export const ContentfulContentReference = ({ one, many, title }) => { + const references = [one, ...(many || [])].filter(Boolean) return (

[ContentfulReference] {title}: [ diff --git a/e2e-tests/contentful/src/pages/content-reference.js b/e2e-tests/contentful/src/pages/content-reference.js index 642722e2a92d6..9dfb892765136 100644 --- a/e2e-tests/contentful/src/pages/content-reference.js +++ b/e2e-tests/contentful/src/pages/content-reference.js @@ -104,13 +104,12 @@ export const pageQuery = graphql` contentful_id one { __typename + contentful_id ... on ContentfulText { - contentful_id title short } ... on ContentfulContentReference { - contentful_id title one { ... on ContentfulText { @@ -138,18 +137,16 @@ export const pageQuery = graphql` } many { __typename + contentful_id ... on ContentfulText { - contentful_id title short } ... on ContentfulNumber { - contentful_id title integer } ... on ContentfulContentReference { - contentful_id title one { ... on ContentfulText { diff --git a/e2e-tests/contentful/src/pages/rich-text.js b/e2e-tests/contentful/src/pages/rich-text.js index b064694b7469b..d9d5b34d0586a 100644 --- a/e2e-tests/contentful/src/pages/rich-text.js +++ b/e2e-tests/contentful/src/pages/rich-text.js @@ -148,34 +148,46 @@ export const pageQuery = graphql` contentful_id title one { + __typename + contentful_id + ... on ContentfulText { + title + short + } ... on ContentfulContentReference { - contentful_id title - content_reference { + one { + ... on ContentfulContentReference { + title + } + } + many { ... on ContentfulContentReference { - contentful_id title } } } } many { + __typename + contentful_id ... on ContentfulText { - contentful_id title short } ... on ContentfulNumber { - contentful_id title integer } ... on ContentfulContentReference { - contentful_id title - content_reference { + one { + ... on ContentfulContentReference { + title + } + } + many { ... on ContentfulContentReference { - id title } } diff --git a/packages/gatsby-source-contentful/src/generate-schema.js b/packages/gatsby-source-contentful/src/generate-schema.js index c4544118b4299..141d7fbfeab6f 100644 --- a/packages/gatsby-source-contentful/src/generate-schema.js +++ b/packages/gatsby-source-contentful/src/generate-schema.js @@ -1,9 +1,106 @@ -const fs = require(`fs`) -const { cloneDeep } = require(`lodash`) - import { makeTypeName } from "./normalize" -const types = [] +// Contentful content type schemas +const ContentfulDataTypes = new Map([ + [ + `Symbol`, + () => { + return { type: `String` } + }, + ], + [ + `Text`, + field => { + return { + type: `ContentfulNodeTypeText`, + extensions: { + link: { by: `id`, from: `${field.id}___NODE` }, + }, + } + }, + ], + [ + `Integer`, + () => { + return { type: `Int` } + }, + ], + [ + `Number`, + () => { + return { type: `Float` } + }, + ], + [ + `Date`, + () => { + return { + type: `Date`, + extensions: { + dateformat: {}, + }, + } + }, + ], + [ + `Object`, + () => { + return { type: `JSON` } + }, + ], + [ + `Boolean`, + () => { + return { type: `Boolean` } + }, + ], + [ + `Location`, + () => { + return { type: `ContentfulNodeTypeLocation` } + }, + ], + [ + `RichText`, + () => { + return { type: `ContentfulNodeTypeRichText` } + }, + ], +]) + +const getLinkFieldType = (linkType, field) => { + return { + type: `Contentful${linkType}`, + extensions: { + link: { by: `id`, from: `${field.id}___NODE` }, + }, + } +} + +const translateFieldType = field => { + let fieldType + if (field.type === `Array`) { + // Arrays of Contentful Links or primitive types + const fieldData = + field.items.type === `Link` + ? getLinkFieldType(field.items.linkType, field) + : translateFieldType(field.items) + + fieldType = { ...fieldData, type: `[${fieldData.type}]` } + } else if (field.type === `Link`) { + // Contentful Link (reference) field types + fieldType = getLinkFieldType(field.linkType, field) + } else { + // Primitive field types + fieldType = ContentfulDataTypes.get(field.type)(field) + } + + if (field.required) { + fieldType.type = `${fieldType.type}!` + } + + return fieldType +} function generateAssetTypes({ createTypes }) { createTypes(` @@ -16,8 +113,8 @@ function generateAssetTypes({ createTypes }) { contentful_id: String! id: ID! spaceId: String! - createdAt: String! # Date @dateform, - updatedAt: String! # Date @dateform, + createdAt: Date @dateformat + updatedAt: Date @dateformat } `) @@ -58,13 +155,6 @@ export function generateSchema({ pluginConfig, contentTypeItems, }) { - // logger @todo remove it - const origTypes = createTypes - createTypes = (...all) => { - types.push(all) - origTypes(...all) - } - createTypes(` interface ContentfulInternalReference implements Node { contentful_id: String! @@ -140,11 +230,9 @@ export function generateSchema({ const v = obj[k] if (v && v.sys && v.sys.type === `Link`) { if (v.sys.linkType === `Asset`) { - console.log(`adding asset`, v) referencedAssets.add(v.sys.id) } if (v.sys.linkType === `Entry`) { - console.log(`adding entry`, v) referencedEntries.add(v.sys.id) } } else if (v && typeof v === `object`) { @@ -182,7 +270,7 @@ export function generateSchema({ }) ) - // Is there a way to have this as string and let transformer-remark replace it with an object? + // @todo Is there a way to have this as string and let transformer-remark replace it with an object? createTypes( schema.buildObjectType({ name: `ContentfulNodeTypeText`, @@ -196,79 +284,6 @@ export function generateSchema({ }) ) - // Contentful content type schemas - const ContentfulDataTypes = new Map([ - [`Symbol`, `String`], - [ - `Text`, - { - type: `ContentfulNodeTypeText`, - extensions: { - link: { by: `id` }, - }, - }, - ], - [`Integer`, `Int`], - [`Number`, `Float`], - [ - `Date`, - { - type: `Date`, - extensions: { - dateformat: {}, - }, - }, - ], - [`Object`, `JSON`], - [`Boolean`, `Boolean`], - [`Location`, `ContentfulNodeTypeLocation`], - [`RichText`, `ContentfulNodeTypeRichText`], - ]) - - const getLinkFieldType = linkType => { - return { - type: `Contentful${linkType}`, - extensions: { - link: { by: `id` }, - }, - } - } - - const translateFieldType = field => { - let id - if (field.type === `Array`) { - const fieldData = - field.items.type === `Link` - ? getLinkFieldType(field.items.linkType) - : translateFieldType(field.items) - - id = - typeof fieldData === `string` - ? `[${fieldData}]` - : { ...fieldData, type: `[${fieldData.type}]` } - } else if (field.type === `Link`) { - id = getLinkFieldType(field.linkType) - } else { - id = ContentfulDataTypes.get(field.type) - } - - if (typeof id === `string`) { - return [id, field.required && `!`].filter(Boolean).join(``) - } - - id = cloneDeep(id) - - if (field.required) { - id.type = `${id.type}!` - } - - if (id?.extensions?.link) { - id.extensions.link.from = `${field.id}___NODE` - } - - return id - } - for (const contentTypeItem of contentTypeItems) { try { const fields = {} @@ -276,8 +291,7 @@ export function generateSchema({ if (field.disabled || field.omitted) { return } - const type = translateFieldType(field) - fields[field.id] = typeof type === `string` ? { type } : type + fields[field.id] = translateFieldType(field) }) const type = pluginConfig.get(`useNameForId`) @@ -294,8 +308,8 @@ export function generateSchema({ node_locale: { type: `String!` }, // @todo these should be real dates and in sys spaceId: { type: `String!` }, - createdAt: { type: `String!` }, // { type: `Date`, extensions: { dateform: {} } }, - updatedAt: { type: `String!` }, // { type: `Date`, extensions: { dateform: {} } }, + createdAt: { type: `Date`, extensions: { dateformat: {} } }, + updatedAt: { type: `Date`, extensions: { dateformat: {} } }, // @todo add metadata sys: { type: `ContentfulInternalSys` }, ...fields, @@ -305,19 +319,15 @@ export function generateSchema({ `ContentfulEntry`, `Node`, ], + extensions: { dontInfer: {} }, }) ) } catch (err) { err.message = `Unable to create schema for Contentful Content Type ${ contentTypeItem.name || contentTypeItem.sys.id }:\n${err.message}` + console.log(err.stack) throw err } } - - fs.writeFileSync( - process.cwd() + `/generated-types.json`, - JSON.stringify(types, null, 2) - ) - createTypes = origTypes } diff --git a/packages/gatsby-source-contentful/src/rich-text.js b/packages/gatsby-source-contentful/src/rich-text.js index bed7d4ca7b6fd..662914b6013f3 100644 --- a/packages/gatsby-source-contentful/src/rich-text.js +++ b/packages/gatsby-source-contentful/src/rich-text.js @@ -3,7 +3,7 @@ import { documentToReactComponents } from "@contentful/rich-text-react-renderer" import resolveResponse from "contentful-resolve-response" export function renderRichText({ raw, references }, options = {}) { - const richText = JSON.parse(raw) + const richText = raw // If no references are given, there is no need to resolve them if (!references || !references.length) { From 1ff6e64a9514ccbecbbc7b338e43d290380f6aa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benedikt=20R=C3=B6tsch?= Date: Thu, 29 Apr 2021 12:31:37 +0200 Subject: [PATCH 14/34] refactor: reintroduce contentful sys common resource attribute #31007 --- .../src/components/references/text.js | 2 +- e2e-tests/contentful/src/pages/boolean.js | 21 +- .../contentful/src/pages/content-reference.js | 79 +++- e2e-tests/contentful/src/pages/date.js | 12 +- .../src/pages/gatsby-plugin-image.js | 28 +- e2e-tests/contentful/src/pages/json.js | 24 +- e2e-tests/contentful/src/pages/location.js | 21 +- .../contentful/src/pages/media-reference.js | 39 +- e2e-tests/contentful/src/pages/number.js | 21 +- e2e-tests/contentful/src/pages/rich-text.js | 26 +- e2e-tests/contentful/src/pages/text.js | 35 +- .../gatsby-source-contentful/package.json | 1 + .../__snapshots__/gatsby-node.js.snap | 404 +++++++++++++++++- .../__tests__/download-contentful-assets.js | 40 +- .../src/__tests__/gatsby-node.js | 15 +- .../src/__tests__/normalize.js | 21 +- .../src/__tests__/rich-text.js | 24 +- .../gatsby-source-contentful/src/config.js | 10 + .../src/download-contentful-assets.js | 5 +- .../src/generate-schema.js | 58 ++- .../gatsby-source-contentful/src/normalize.js | 125 +++--- .../gatsby-source-contentful/src/rich-text.js | 4 +- .../src/source-nodes.js | 38 +- 23 files changed, 734 insertions(+), 319 deletions(-) create mode 100644 packages/gatsby-source-contentful/src/config.js diff --git a/e2e-tests/contentful/src/components/references/text.js b/e2e-tests/contentful/src/components/references/text.js index 8bcf361eb99c8..a8647ece05b1d 100644 --- a/e2e-tests/contentful/src/components/references/text.js +++ b/e2e-tests/contentful/src/components/references/text.js @@ -1,5 +1,5 @@ import React from "react" export const ContentfulText = ({ short, longPlain }) => ( -

[ContentfulText] {short || longPlain?.longPlain}

+

[ContentfulText] {short || longPlain?.raw}

) diff --git a/e2e-tests/contentful/src/pages/boolean.js b/e2e-tests/contentful/src/pages/boolean.js index 410065f7074bd..d4bd20c11b096 100644 --- a/e2e-tests/contentful/src/pages/boolean.js +++ b/e2e-tests/contentful/src/pages/boolean.js @@ -50,8 +50,11 @@ export default BooleanPage export const pageQuery = graphql` query BooleanQuery { default: allContentfulBoolean( - sort: { fields: contentful_id } - filter: { node_locale: { eq: "en-US" }, booleanLocalized: { eq: null } } + sort: { fields: sys___id } + filter: { + sys: { locale: { eq: "en-US" } } + booleanLocalized: { eq: null } + } ) { nodes { title @@ -59,8 +62,11 @@ export const pageQuery = graphql` } } english: allContentfulBoolean( - sort: { fields: contentful_id } - filter: { node_locale: { eq: "en-US" }, booleanLocalized: { ne: null } } + sort: { fields: sys___id } + filter: { + sys: { locale: { eq: "en-US" } } + booleanLocalized: { ne: null } + } ) { nodes { title @@ -68,8 +74,11 @@ export const pageQuery = graphql` } } german: allContentfulBoolean( - sort: { fields: contentful_id } - filter: { node_locale: { eq: "de-DE" }, booleanLocalized: { ne: null } } + sort: { fields: sys___id } + filter: { + sys: { locale: { eq: "de-DE" } } + booleanLocalized: { ne: null } + } ) { nodes { title diff --git a/e2e-tests/contentful/src/pages/content-reference.js b/e2e-tests/contentful/src/pages/content-reference.js index 9dfb892765136..cc33294438c0d 100644 --- a/e2e-tests/contentful/src/pages/content-reference.js +++ b/e2e-tests/contentful/src/pages/content-reference.js @@ -24,7 +24,7 @@ const ContentReferencePage = ({ data }) => { return (

Default

- {defaultEntries.map(({ contentful_id, title, one, many }) => { + {defaultEntries.map(({ sys: { id }, title, one, many }) => { const slug = slugify(title, { strict: true, lower: true }) let content = null @@ -37,7 +37,7 @@ const ContentReferencePage = ({ data }) => { } return ( -
+

{title}

{content}
@@ -45,7 +45,7 @@ const ContentReferencePage = ({ data }) => { })}

English Locale

{englishEntries.map( - ({ contentful_id, title, oneLocalized, manyLocalized }) => { + ({ sys: { id }, title, oneLocalized, manyLocalized }) => { const slug = slugify(title, { strict: true, lower: true }) let content = null @@ -58,7 +58,7 @@ const ContentReferencePage = ({ data }) => { } return ( -
+

{title}

{content}
@@ -67,7 +67,7 @@ const ContentReferencePage = ({ data }) => { )}

German Locale

{germanEntries.map( - ({ contentful_id, title, oneLocalized, manyLocalized }) => { + ({ sys: { id }, title, oneLocalized, manyLocalized }) => { const slug = slugify(title, { strict: true, lower: true }) let content = null @@ -80,7 +80,7 @@ const ContentReferencePage = ({ data }) => { } return ( -
+

{title}

{content}
@@ -97,18 +97,29 @@ export const pageQuery = graphql` query ContentReferenceQuery { default: allContentfulContentReference( sort: { fields: title } - filter: { node_locale: { eq: "en-US" }, title: { glob: "!*Localized*" } } + filter: { + sys: { locale: { eq: "en-US" } } + title: { glob: "!*Localized*" } + } ) { nodes { title - contentful_id + sys { + id + } one { __typename - contentful_id + sys { + id + } ... on ContentfulText { title short } + ... on ContentfulNumber { + title + integer + } ... on ContentfulContentReference { title one { @@ -116,6 +127,10 @@ export const pageQuery = graphql` title short } + ... on ContentfulNumber { + title + integer + } ... on ContentfulContentReference { title } @@ -137,7 +152,9 @@ export const pageQuery = graphql` } many { __typename - contentful_id + sys { + id + } ... on ContentfulText { title short @@ -153,6 +170,10 @@ export const pageQuery = graphql` title short } + ... on ContentfulNumber { + title + integer + } ... on ContentfulContentReference { title } @@ -176,16 +197,23 @@ export const pageQuery = graphql` } english: allContentfulContentReference( sort: { fields: title } - filter: { node_locale: { eq: "en-US" }, title: { glob: "*Localized*" } } + filter: { + sys: { locale: { eq: "en-US" } } + title: { glob: "*Localized*" } + } ) { nodes { title - contentful_id + sys { + id + } oneLocalized { __typename - title - decimal - integer + ... on ContentfulNumber { + title + decimal + integer + } } manyLocalized { __typename @@ -198,7 +226,7 @@ export const pageQuery = graphql` title short longPlain { - longPlain + raw } } } @@ -206,16 +234,23 @@ export const pageQuery = graphql` } german: allContentfulContentReference( sort: { fields: title } - filter: { node_locale: { eq: "de-DE" }, title: { glob: "*Localized*" } } + filter: { + sys: { locale: { eq: "de-DE" } } + title: { glob: "*Localized*" } + } ) { nodes { title - contentful_id + sys { + id + } oneLocalized { __typename - title - decimal - integer + ... on ContentfulNumber { + title + decimal + integer + } } manyLocalized { __typename @@ -228,7 +263,7 @@ export const pageQuery = graphql` title short longPlain { - longPlain + raw } } } diff --git a/e2e-tests/contentful/src/pages/date.js b/e2e-tests/contentful/src/pages/date.js index bb3a0ff554a38..ef8cb42c32b86 100644 --- a/e2e-tests/contentful/src/pages/date.js +++ b/e2e-tests/contentful/src/pages/date.js @@ -32,34 +32,32 @@ export default DatePage export const pageQuery = graphql` query DateQuery { - dateTime: contentfulDate(contentful_id: { eq: "38akBjGb3T1t4AjB87wQjo" }) { + dateTime: contentfulDate(sys: { id: { eq: "38akBjGb3T1t4AjB87wQjo" } }) { title date: dateTime formatted: dateTime(formatString: "D.M.YYYY - hh:mm") } dateTimeTimezone: contentfulDate( - contentful_id: { eq: "6dZ8pK4tFWZDZPHgSC0tNS" } + sys: { id: { eq: "6dZ8pK4tFWZDZPHgSC0tNS" } } ) { title date: dateTimeTimezone formatted: dateTimeTimezone(formatString: "D.M.YYYY - hh:mm (z)") } - date: contentfulDate(contentful_id: { eq: "5FuULz0jl0rKoKUKp2rshf" }) { + date: contentfulDate(sys: { id: { eq: "5FuULz0jl0rKoKUKp2rshf" } }) { title date formatted: date(formatString: "D.M.YYYY") } dateEnglish: contentfulDate( - contentful_id: { eq: "1ERWZvDiYELryAZEP1dmKG" } - node_locale: { eq: "en-US" } + sys: { id: { eq: "1ERWZvDiYELryAZEP1dmKG" }, locale: { eq: "en-US" } } ) { title date: dateLocalized formatted: dateLocalized(formatString: "D.M.YYYY - HH:mm:ss") } dateGerman: contentfulDate( - contentful_id: { eq: "1ERWZvDiYELryAZEP1dmKG" } - node_locale: { eq: "de-DE" } + sys: { id: { eq: "1ERWZvDiYELryAZEP1dmKG" }, locale: { eq: "de-DE" } } ) { title date: dateLocalized diff --git a/e2e-tests/contentful/src/pages/gatsby-plugin-image.js b/e2e-tests/contentful/src/pages/gatsby-plugin-image.js index 98d3ea31eb993..e5ef0b60f9e41 100644 --- a/e2e-tests/contentful/src/pages/gatsby-plugin-image.js +++ b/e2e-tests/contentful/src/pages/gatsby-plugin-image.js @@ -215,16 +215,18 @@ export const pageQuery = graphql` query GatsbyPluginImageQuery { default: allContentfulAsset( filter: { - contentful_id: { - in: [ - "3ljGfnpegOnBTFGhV07iC1" - "3BSI9CgDdAn1JchXmY5IJi" - "65syuRuRVeKi03HvRsOkkb" - ] + sys: { + id: { + in: [ + "3ljGfnpegOnBTFGhV07iC1" + "3BSI9CgDdAn1JchXmY5IJi" + "65syuRuRVeKi03HvRsOkkb" + ] + } + locale: { eq: "en-US" } } - node_locale: { eq: "en-US" } } - sort: { fields: contentful_id } + sort: { fields: sys___id } ) { nodes { title @@ -259,10 +261,9 @@ export const pageQuery = graphql` } english: allContentfulAsset( filter: { - contentful_id: { in: ["4FwygYxkL3rAteERtoxxNC"] } - node_locale: { eq: "en-US" } + sys: { id: { in: ["4FwygYxkL3rAteERtoxxNC"] }, locale: { eq: "en-US" } } } - sort: { fields: contentful_id } + sort: { fields: sys___id } ) { nodes { title @@ -276,10 +277,9 @@ export const pageQuery = graphql` } german: allContentfulAsset( filter: { - contentful_id: { in: ["4FwygYxkL3rAteERtoxxNC"] } - node_locale: { eq: "de-DE" } + sys: { id: { in: ["4FwygYxkL3rAteERtoxxNC"] }, locale: { eq: "de-DE" } } } - sort: { fields: contentful_id } + sort: { fields: sys___id } ) { nodes { title diff --git a/e2e-tests/contentful/src/pages/json.js b/e2e-tests/contentful/src/pages/json.js index 45172e184fb0d..bce1cb1edd3a1 100644 --- a/e2e-tests/contentful/src/pages/json.js +++ b/e2e-tests/contentful/src/pages/json.js @@ -31,7 +31,7 @@ const JSONPage = ({ data }) => {

Name: {actor.name}

Photo: {actor.photo}

Birthdate: {actor.Birthdate}

-

Born at: {actor.Born_At}

+

Born at: {actor["Born At"]}

Weight: {actor.weight}

Age: {actor.age}

Wife: {actor.wife}

@@ -61,33 +61,23 @@ export default JSONPage export const pageQuery = graphql` query JSONQuery { - simple: contentfulJson(contentful_id: { eq: "2r6tNjP8brkyy5yLR39hhh" }) { + simple: contentfulJson(sys: { id: { eq: "2r6tNjP8brkyy5yLR39hhh" } }) { json } - complex: contentfulJson(contentful_id: { eq: "2y71nV0cpW9vzTmJybq571" }) { + complex: contentfulJson(sys: { id: { eq: "2y71nV0cpW9vzTmJybq571" } }) { json } english: contentfulJson( - node_locale: { eq: "en-US" } - jsonLocalized: { id: { ne: null } } + sys: { id: { eq: "7DvTBEPg5P6TRC7dI9zXuO" }, locale: { eq: "en-US" } } ) { title - jsonLocalized { - age - city - name - } + jsonLocalized } german: contentfulJson( - node_locale: { eq: "de-DE" } - jsonLocalized: { id: { ne: null } } + sys: { id: { eq: "7DvTBEPg5P6TRC7dI9zXuO" }, locale: { eq: "de-DE" } } ) { title - jsonLocalized { - age - city - name - } + jsonLocalized } } ` diff --git a/e2e-tests/contentful/src/pages/location.js b/e2e-tests/contentful/src/pages/location.js index 813f6cf9ed7dd..f9757a987d661 100644 --- a/e2e-tests/contentful/src/pages/location.js +++ b/e2e-tests/contentful/src/pages/location.js @@ -57,8 +57,11 @@ export default LocationPage export const pageQuery = graphql` query LocationQuery { default: allContentfulLocation( - sort: { fields: contentful_id } - filter: { title: { glob: "!*Localized*" }, node_locale: { eq: "en-US" } } + sort: { fields: sys___id } + filter: { + title: { glob: "!*Localized*" } + sys: { locale: { eq: "en-US" } } + } ) { nodes { title @@ -69,8 +72,11 @@ export const pageQuery = graphql` } } english: allContentfulLocation( - sort: { fields: contentful_id } - filter: { title: { glob: "*Localized*" }, node_locale: { eq: "en-US" } } + sort: { fields: sys___id } + filter: { + title: { glob: "*Localized*" } + sys: { locale: { eq: "en-US" } } + } ) { nodes { title @@ -81,8 +87,11 @@ export const pageQuery = graphql` } } german: allContentfulLocation( - sort: { fields: contentful_id } - filter: { title: { glob: "*Localized*" }, node_locale: { eq: "de-DE" } } + sort: { fields: sys___id } + filter: { + title: { glob: "*Localized*" } + sys: { locale: { eq: "de-DE" } } + } ) { nodes { title diff --git a/e2e-tests/contentful/src/pages/media-reference.js b/e2e-tests/contentful/src/pages/media-reference.js index f6bf077d006e1..9361b6b641bc0 100644 --- a/e2e-tests/contentful/src/pages/media-reference.js +++ b/e2e-tests/contentful/src/pages/media-reference.js @@ -10,7 +10,7 @@ const MediaReferencePage = ({ data }) => { const germanEntries = data.german.nodes return ( - {defaultEntries.map(({ contentful_id, title, one, many }) => { + {defaultEntries.map(({ sys: { id }, title, one, many }) => { const slug = slugify(title, { strict: true, lower: true }) let content = null @@ -27,7 +27,7 @@ const MediaReferencePage = ({ data }) => { } return ( -
+

{title}

{content}
@@ -35,7 +35,7 @@ const MediaReferencePage = ({ data }) => { })}

English Locale

{englishEntries.map( - ({ contentful_id, title, one, oneLocalized, many, manyLocalized }) => { + ({ sys: { id }, title, one, oneLocalized, many, manyLocalized }) => { const slug = slugify(title, { strict: true, lower: true }) let content = null @@ -76,7 +76,7 @@ const MediaReferencePage = ({ data }) => { } return ( -
+

{title}

{content}
@@ -86,7 +86,7 @@ const MediaReferencePage = ({ data }) => {

German Locale

{germanEntries.map( - ({ contentful_id, title, one, oneLocalized, many, manyLocalized }) => { + ({ sys: { id }, title, one, oneLocalized, many, manyLocalized }) => { const slug = slugify(title, { strict: true, lower: true }) let content = null @@ -127,7 +127,7 @@ const MediaReferencePage = ({ data }) => { } return ( -
+

{title}

{content}
@@ -144,11 +144,16 @@ export const pageQuery = graphql` query MediaReferenceQuery { default: allContentfulMediaReference( sort: { fields: title } - filter: { title: { glob: "!*Localized*" }, node_locale: { eq: "en-US" } } + filter: { + title: { glob: "!*Localized*" } + sys: { locale: { eq: "en-US" } } + } ) { nodes { title - contentful_id + sys { + id + } one { file { url @@ -163,11 +168,16 @@ export const pageQuery = graphql` } english: allContentfulMediaReference( sort: { fields: title } - filter: { title: { glob: "*Localized*" }, node_locale: { eq: "en-US" } } + filter: { + title: { glob: "*Localized*" } + sys: { locale: { eq: "en-US" } } + } ) { nodes { title - contentful_id + sys { + id + } one { file { url @@ -192,11 +202,16 @@ export const pageQuery = graphql` } german: allContentfulMediaReference( sort: { fields: title } - filter: { title: { glob: "*Localized*" }, node_locale: { eq: "de-DE" } } + filter: { + title: { glob: "*Localized*" } + sys: { locale: { eq: "de-DE" } } + } ) { nodes { title - contentful_id + sys { + id + } one { file { url diff --git a/e2e-tests/contentful/src/pages/number.js b/e2e-tests/contentful/src/pages/number.js index 5eff2ed704bba..946e9b71d3be1 100644 --- a/e2e-tests/contentful/src/pages/number.js +++ b/e2e-tests/contentful/src/pages/number.js @@ -54,8 +54,11 @@ export default NumberPage export const pageQuery = graphql` query NumberQuery { default: allContentfulNumber( - sort: { fields: contentful_id } - filter: { title: { glob: "!*Localized*" }, node_locale: { eq: "en-US" } } + sort: { fields: sys___id } + filter: { + title: { glob: "!*Localized*" } + sys: { locale: { eq: "en-US" } } + } ) { nodes { title @@ -64,8 +67,11 @@ export const pageQuery = graphql` } } english: allContentfulNumber( - sort: { fields: contentful_id } - filter: { title: { glob: "*Localized*" }, node_locale: { eq: "en-US" } } + sort: { fields: sys___id } + filter: { + title: { glob: "*Localized*" } + sys: { locale: { eq: "en-US" } } + } ) { nodes { title @@ -74,8 +80,11 @@ export const pageQuery = graphql` } } german: allContentfulNumber( - sort: { fields: contentful_id } - filter: { title: { glob: "*Localized*" }, node_locale: { eq: "de-DE" } } + sort: { fields: sys___id } + filter: { + title: { glob: "*Localized*" } + sys: { locale: { eq: "de-DE" } } + } ) { nodes { title diff --git a/e2e-tests/contentful/src/pages/rich-text.js b/e2e-tests/contentful/src/pages/rich-text.js index d9d5b34d0586a..0cd2a3eca6127 100644 --- a/e2e-tests/contentful/src/pages/rich-text.js +++ b/e2e-tests/contentful/src/pages/rich-text.js @@ -118,7 +118,7 @@ export const pageQuery = graphql` sort: { fields: title } filter: { title: { glob: "!*Localized*|*Validated*" } - node_locale: { eq: "en-US" } + sys: { locale: { eq: "en-US" } } } ) { nodes { @@ -128,28 +128,30 @@ export const pageQuery = graphql` raw references { __typename + sys { + id + } ... on ContentfulAsset { contentful_id gatsbyImageData(width: 200) } ... on ContentfulText { - contentful_id title short } ... on ContentfulLocation { - contentful_id location { lat lon } } ... on ContentfulContentReference { - contentful_id title one { __typename - contentful_id + sys { + id + } ... on ContentfulText { title short @@ -170,7 +172,9 @@ export const pageQuery = graphql` } many { __typename - contentful_id + sys { + id + } ... on ContentfulText { title short @@ -200,7 +204,10 @@ export const pageQuery = graphql` } english: allContentfulRichText( sort: { fields: title } - filter: { title: { glob: "*Localized*" }, node_locale: { eq: "en-US" } } + filter: { + title: { glob: "*Localized*" } + sys: { locale: { eq: "en-US" } } + } ) { nodes { id @@ -212,7 +219,10 @@ export const pageQuery = graphql` } german: allContentfulRichText( sort: { fields: title } - filter: { title: { glob: "*Localized*" }, node_locale: { eq: "de-DE" } } + filter: { + title: { glob: "*Localized*" } + sys: { locale: { eq: "de-DE" } } + } ) { nodes { id diff --git a/e2e-tests/contentful/src/pages/text.js b/e2e-tests/contentful/src/pages/text.js index 360a154201c5b..923c86e743da5 100644 --- a/e2e-tests/contentful/src/pages/text.js +++ b/e2e-tests/contentful/src/pages/text.js @@ -57,7 +57,7 @@ const TextPage = ({ data }) => {

Long (Plain):

-

{longEnglish.longLocalized.longLocalized}

+

{longEnglish.longLocalized.raw}

German Locale

@@ -67,7 +67,7 @@ const TextPage = ({ data }) => {

Long (Plain):

-

{longGerman.longLocalized.longLocalized}

+

{longGerman.longLocalized.raw}

) @@ -78,28 +78,24 @@ export default TextPage export const pageQuery = graphql` query TextQuery { short: contentfulText( - node_locale: { eq: "en-US" } - contentful_id: { eq: "5ZtcN1o7KpN7J7xgiTyaXo" } + sys: { id: { eq: "5ZtcN1o7KpN7J7xgiTyaXo" }, locale: { eq: "en-US" } } ) { short } shortList: contentfulText( - node_locale: { eq: "en-US" } - contentful_id: { eq: "7b5U927WTFcQXO2Gewwa2k" } + sys: { id: { eq: "7b5U927WTFcQXO2Gewwa2k" }, locale: { eq: "en-US" } } ) { shortList } longPlain: contentfulText( - node_locale: { eq: "en-US" } - contentful_id: { eq: "6ru8cSC9hZi3Ekvtw7P77S" } + sys: { id: { eq: "6ru8cSC9hZi3Ekvtw7P77S" }, locale: { eq: "en-US" } } ) { longPlain { raw } } longMarkdownSimple: contentfulText( - node_locale: { eq: "en-US" } - contentful_id: { eq: "NyPJw0mcSuCwY2gV0zYny" } + sys: { id: { eq: "NyPJw0mcSuCwY2gV0zYny" }, locale: { eq: "en-US" } } ) { longMarkdown { childMarkdownRemark { @@ -108,8 +104,7 @@ export const pageQuery = graphql` } } longMarkdownComplex: contentfulText( - node_locale: { eq: "en-US" } - contentful_id: { eq: "3pwKS9UWsYmOguo4UdE1EB" } + sys: { id: { eq: "3pwKS9UWsYmOguo4UdE1EB" }, locale: { eq: "en-US" } } ) { longMarkdown { childMarkdownRemark { @@ -118,31 +113,27 @@ export const pageQuery = graphql` } } shortEnglish: contentfulText( - node_locale: { eq: "en-US" } - contentful_id: { eq: "2sQRyOLUexvWZj9nkzS3nN" } + sys: { id: { eq: "2sQRyOLUexvWZj9nkzS3nN" }, locale: { eq: "en-US" } } ) { shortLocalized } shortGerman: contentfulText( - node_locale: { eq: "de-DE" } - contentful_id: { eq: "2sQRyOLUexvWZj9nkzS3nN" } + sys: { id: { eq: "2sQRyOLUexvWZj9nkzS3nN" }, locale: { eq: "de-DE" } } ) { shortLocalized } longEnglish: contentfulText( - node_locale: { eq: "en-US" } - contentful_id: { eq: "5csovkwdDBqTKwSblAOHvd" } + sys: { id: { eq: "5csovkwdDBqTKwSblAOHvd" }, locale: { eq: "en-US" } } ) { longLocalized { - longLocalized + raw } } longGerman: contentfulText( - node_locale: { eq: "de-DE" } - contentful_id: { eq: "5csovkwdDBqTKwSblAOHvd" } + sys: { id: { eq: "5csovkwdDBqTKwSblAOHvd" }, locale: { eq: "de-DE" } } ) { longLocalized { - longLocalized + raw } } } diff --git a/packages/gatsby-source-contentful/package.json b/packages/gatsby-source-contentful/package.json index 5c41c6e917cca..9da53b108859d 100644 --- a/packages/gatsby-source-contentful/package.json +++ b/packages/gatsby-source-contentful/package.json @@ -16,6 +16,7 @@ "chalk": "^4.1.2", "common-tags": "^1.8.2", "contentful": "^8.5.8", + "contentful-resolve-response": "^1.3.0", "fs-extra": "^10.0.0", "gatsby-core-utils": "^3.7.0-next.0", "gatsby-plugin-utils": "^3.1.0-next.0", diff --git a/packages/gatsby-source-contentful/src/__tests__/__snapshots__/gatsby-node.js.snap b/packages/gatsby-source-contentful/src/__tests__/__snapshots__/gatsby-node.js.snap index 4961649230900..4e62cb24f807d 100644 --- a/packages/gatsby-source-contentful/src/__tests__/__snapshots__/gatsby-node.js.snap +++ b/packages/gatsby-source-contentful/src/__tests__/__snapshots__/gatsby-node.js.snap @@ -8,10 +8,402 @@ Array [ ] `; -exports[`gatsby-node stores rich text as raw with references attached 2`] = ` -Array [ - "ahntqop9oi7x___7oHxo6bs0us9wIkq27qdyK___Entry___nl", - "ahntqop9oi7x___6KpLS2NZyB3KAvDzWf4Ukh___Entry___nl", - "ahntqop9oi7x___4ZQrqcrTunWiuNaavhGYNT___Asset___nl", -] +exports[`gatsby-node stores rich text as JSON 2`] = ` +Object { + "content": Array [ + Object { + "content": Array [ + Object { + "data": Object {}, + "marks": Array [], + "nodeType": "text", + "value": "This is the homepage", + }, + ], + "data": Object {}, + "nodeType": "paragraph", + }, + Object { + "content": Array [ + Object { + "data": Object {}, + "marks": Array [], + "nodeType": "text", + "value": "Heading 1", + }, + ], + "data": Object {}, + "nodeType": "heading-1", + }, + Object { + "content": Array [ + Object { + "data": Object {}, + "marks": Array [], + "nodeType": "text", + "value": "Heading 2", + }, + ], + "data": Object {}, + "nodeType": "heading-2", + }, + Object { + "content": Array [ + Object { + "data": Object {}, + "marks": Array [], + "nodeType": "text", + "value": "Heading 3", + }, + ], + "data": Object {}, + "nodeType": "heading-3", + }, + Object { + "content": Array [ + Object { + "data": Object {}, + "marks": Array [], + "nodeType": "text", + "value": "Heading 4", + }, + ], + "data": Object {}, + "nodeType": "heading-4", + }, + Object { + "content": Array [ + Object { + "data": Object {}, + "marks": Array [], + "nodeType": "text", + "value": "Heading 5", + }, + ], + "data": Object {}, + "nodeType": "heading-5", + }, + Object { + "content": Array [ + Object { + "data": Object {}, + "marks": Array [], + "nodeType": "text", + "value": "Heading 6", + }, + ], + "data": Object {}, + "nodeType": "heading-6", + }, + Object { + "content": Array [ + Object { + "data": Object {}, + "marks": Array [], + "nodeType": "text", + "value": "This is ", + }, + Object { + "data": Object {}, + "marks": Array [ + Object { + "type": "bold", + }, + ], + "nodeType": "text", + "value": "bold ", + }, + Object { + "data": Object {}, + "marks": Array [], + "nodeType": "text", + "value": "and ", + }, + Object { + "data": Object {}, + "marks": Array [ + Object { + "type": "italic", + }, + ], + "nodeType": "text", + "value": "italic", + }, + Object { + "data": Object {}, + "marks": Array [], + "nodeType": "text", + "value": " and ", + }, + Object { + "data": Object {}, + "marks": Array [ + Object { + "type": "bold", + }, + Object { + "type": "italic", + }, + ], + "nodeType": "text", + "value": "both", + }, + ], + "data": Object {}, + "nodeType": "paragraph", + }, + Object { + "content": Array [ + Object { + "content": Array [ + Object { + "content": Array [ + Object { + "data": Object {}, + "marks": Array [], + "nodeType": "text", + "value": "Very", + }, + ], + "data": Object {}, + "nodeType": "paragraph", + }, + ], + "data": Object {}, + "nodeType": "list-item", + }, + Object { + "content": Array [ + Object { + "content": Array [ + Object { + "data": Object {}, + "marks": Array [], + "nodeType": "text", + "value": "useful", + }, + ], + "data": Object {}, + "nodeType": "paragraph", + }, + ], + "data": Object {}, + "nodeType": "list-item", + }, + Object { + "content": Array [ + Object { + "content": Array [ + Object { + "data": Object {}, + "marks": Array [], + "nodeType": "text", + "value": "list", + }, + ], + "data": Object {}, + "nodeType": "paragraph", + }, + ], + "data": Object {}, + "nodeType": "list-item", + }, + ], + "data": Object {}, + "nodeType": "unordered-list", + }, + Object { + "content": Array [ + Object { + "content": Array [ + Object { + "data": Object {}, + "marks": Array [], + "nodeType": "text", + "value": "This is a quote", + }, + ], + "data": Object {}, + "nodeType": "paragraph", + }, + ], + "data": Object {}, + "nodeType": "blockquote", + }, + Object { + "content": Array [ + Object { + "data": Object {}, + "marks": Array [], + "nodeType": "text", + "value": "Reference tests:", + }, + ], + "data": Object {}, + "nodeType": "heading-2", + }, + Object { + "content": Array [ + Object { + "data": Object {}, + "marks": Array [], + "nodeType": "text", + "value": "Inline Link: ", + }, + Object { + "content": Array [], + "data": Object { + "target": Object { + "sys": Object { + "id": "7oHxo6bs0us9wIkq27qdyK", + "linkType": "Entry", + "type": "Link", + }, + }, + }, + "nodeType": "embedded-entry-inline", + }, + Object { + "data": Object {}, + "marks": Array [], + "nodeType": "text", + "value": "", + }, + ], + "data": Object {}, + "nodeType": "paragraph", + }, + Object { + "content": Array [ + Object { + "data": Object {}, + "marks": Array [], + "nodeType": "text", + "value": "Link in list:", + }, + ], + "data": Object {}, + "nodeType": "paragraph", + }, + Object { + "content": Array [ + Object { + "content": Array [ + Object { + "content": Array [ + Object { + "data": Object {}, + "marks": Array [], + "nodeType": "text", + "value": "", + }, + Object { + "content": Array [], + "data": Object { + "target": Object { + "sys": Object { + "id": "6KpLS2NZyB3KAvDzWf4Ukh", + "linkType": "Entry", + "type": "Link", + }, + }, + }, + "nodeType": "embedded-entry-inline", + }, + Object { + "data": Object {}, + "marks": Array [], + "nodeType": "text", + "value": "", + }, + ], + "data": Object {}, + "nodeType": "paragraph", + }, + ], + "data": Object {}, + "nodeType": "list-item", + }, + ], + "data": Object {}, + "nodeType": "ordered-list", + }, + Object { + "content": Array [ + Object { + "data": Object {}, + "marks": Array [], + "nodeType": "text", + "value": "Embedded Entity:", + }, + ], + "data": Object {}, + "nodeType": "paragraph", + }, + Object { + "content": Array [], + "data": Object { + "target": Object { + "sys": Object { + "id": "7oHxo6bs0us9wIkq27qdyK", + "linkType": "Entry", + "type": "Link", + }, + }, + }, + "nodeType": "embedded-entry-block", + }, + Object { + "content": Array [ + Object { + "data": Object {}, + "marks": Array [], + "nodeType": "text", + "value": "", + }, + ], + "data": Object {}, + "nodeType": "paragraph", + }, + Object { + "content": Array [ + Object { + "data": Object {}, + "marks": Array [], + "nodeType": "text", + "value": "Embedded Asset:", + }, + ], + "data": Object {}, + "nodeType": "heading-2", + }, + Object { + "content": Array [], + "data": Object { + "target": Object { + "sys": Object { + "id": "4ZQrqcrTunWiuNaavhGYNT", + "linkType": "Asset", + "type": "Link", + }, + }, + }, + "nodeType": "embedded-asset-block", + }, + Object { + "content": Array [ + Object { + "data": Object {}, + "marks": Array [], + "nodeType": "text", + "value": "", + }, + ], + "data": Object {}, + "nodeType": "paragraph", + }, + ], + "data": Object {}, + "nodeType": "document", +} `; diff --git a/packages/gatsby-source-contentful/src/__tests__/download-contentful-assets.js b/packages/gatsby-source-contentful/src/__tests__/download-contentful-assets.js index 72484e5b5a344..f3f6c21fdf6ee 100644 --- a/packages/gatsby-source-contentful/src/__tests__/download-contentful-assets.js +++ b/packages/gatsby-source-contentful/src/__tests__/download-contentful-assets.js @@ -24,24 +24,32 @@ const reporter = { }), } +const mockedContentfulEntity = { + sys: { id: `mocked` }, +} + const fixtures = [ { - sys: { - id: `idJjXOxmNga8CSnQGEwTw`, - type: `Asset`, - createdAt: new Date().toISOString(), - updatedAt: new Date().toISOString(), + id: `aa1beda4-b14a-50f5-89a8-222992a46a41`, + internal: { + owner: `gatsby-source-contentful`, + type: `ContentfulAsset`, }, fields: { + title: { "en-US": `TundraUS`, fr: `TundraFR` }, file: { - "en-US": { - url: `//images.ctfassets.net/testing/us-image.jpeg`, - }, + "en-US": { url: `//images.ctfassets.net/testing/us-image.jpeg` }, + fr: { url: `//images.ctfassets.net/testing/fr-image.jpg` }, }, }, - title: { - "en-US": `TundraUS`, - fr: `TundraFR`, + sys: { + id: `idJjXOxmNga8CSnQGEwTw`, + type: `Asset`, + createdAt: new Date().toISOString(), + updatedAt: new Date().toISOString(), + space: mockedContentfulEntity, + environment: mockedContentfulEntity, + revision: 123, }, }, ] @@ -52,11 +60,7 @@ describe(`downloadContentfulAssets`, () => { const createNodeId = jest.fn(id => id) const defaultLocale = `en-US` const locales = [{ code: `en-US` }, { code: `fr`, fallbackCode: `en-US` }] - const space = { - sys: { - id: `1234`, - }, - } + const space = mockedContentfulEntity const cache = { get: jest.fn(() => Promise.resolve(null)), @@ -90,10 +94,10 @@ describe(`downloadContentfulAssets`, () => { assetNodes.forEach(n => { expect(cache.get).toHaveBeenCalledWith( - `contentful-asset-${n.contentful_id}-${n.node_locale}` + `contentful-asset-${n.sys.id}-${n.sys.locale}` ) expect(cache.set).toHaveBeenCalledWith( - `contentful-asset-${n.contentful_id}-${n.node_locale}`, + `contentful-asset-${n.sys.id}-${n.sys.locale}`, expect.anything() ) }) diff --git a/packages/gatsby-source-contentful/src/__tests__/gatsby-node.js b/packages/gatsby-source-contentful/src/__tests__/gatsby-node.js index 2fce2ea5981ff..ac4082c9385b5 100644 --- a/packages/gatsby-source-contentful/src/__tests__/gatsby-node.js +++ b/packages/gatsby-source-contentful/src/__tests__/gatsby-node.js @@ -10,11 +10,6 @@ import richTextFixture from "../__fixtures__/rich-text-data" import restrictedContentTypeFixture from "../__fixtures__/restricted-content-type" jest.mock(`../fetch`) -jest.mock(`gatsby-core-utils`, () => { - return { - createContentDigest: () => `contentDigest`, - } -}) const defaultPluginOptions = { spaceId: `testSpaceId` } @@ -91,6 +86,7 @@ describe(`gatsby-node`, () => { getCache, reporter, parentSpan, + schema, }, pluginOptions ) @@ -758,7 +754,7 @@ describe(`gatsby-node`, () => { `) }) - it(`stores rich text as raw with references attached`, async () => { + it(`stores rich text as JSON`, async () => { // @ts-ignore fetchContent.mockImplementationOnce(richTextFixture.initialSync) // @ts-ignore @@ -770,14 +766,11 @@ describe(`gatsby-node`, () => { const initNodes = getNodes() const homeNodes = initNodes.filter( - ({ contentful_id: id }) => id === `6KpLS2NZyB3KAvDzWf4Ukh` + ({ sys: { id } }) => id === `6KpLS2NZyB3KAvDzWf4Ukh` ) expect(homeNodes).toHaveLength(2) homeNodes.forEach(homeNode => { - expect(homeNode.content.references___NODE).toStrictEqual([ - ...new Set(homeNode.content.references___NODE), - ]) - expect(homeNode.content.references___NODE).toMatchSnapshot() + expect(homeNode.content).toMatchSnapshot() }) }) diff --git a/packages/gatsby-source-contentful/src/__tests__/normalize.js b/packages/gatsby-source-contentful/src/__tests__/normalize.js index 2709c07332fd7..5e43a7d7d1235 100644 --- a/packages/gatsby-source-contentful/src/__tests__/normalize.js +++ b/packages/gatsby-source-contentful/src/__tests__/normalize.js @@ -1,11 +1,12 @@ // @ts-check +import { restrictedNodeFields } from "../config" import { buildEntryList, - buildResolvableSet, + buildFallbackChain, buildForeignReferenceMap, - createNodesForContentType, + buildResolvableSet, createAssetNodes, - buildFallbackChain, + createNodesForContentType, getLocalizedField, makeId, } from "../normalize" @@ -20,18 +21,8 @@ const { } = require(`./data.json`) const conflictFieldPrefix = `contentful_test` -// restrictedNodeFields from here https://www.gatsbyjs.org/docs/node-interface/ -const restrictedNodeFields = [ - `id`, - `children`, - `contentful_id`, - `parent`, - `fields`, - `internal`, -] const pluginConfig = createPluginConfig({}) - const unstable_createNodeManifest = jest.fn() // Counts the created nodes per node type @@ -304,7 +295,7 @@ describe(`Skip existing nodes in warm build`, () => { // returned is not relevant to test so update if anything breaks. return { id, - internal: { contentDigest: entryList[0][0].sys.updatedAt }, + internal: { contentDigest: entryList[0][0].sys.publishedAt }, } } // All other nodes are new ("unknown") @@ -394,7 +385,7 @@ describe(`Process existing mutated nodes in warm build`, () => { return { id, internal: { - contentDigest: entryList[0][0].sys.updatedAt + `changed`, + contentDigest: entryList[0][0].sys.publishedAt + `changed`, }, } } diff --git a/packages/gatsby-source-contentful/src/__tests__/rich-text.js b/packages/gatsby-source-contentful/src/__tests__/rich-text.js index 46ad833a3bd55..54207938a4543 100644 --- a/packages/gatsby-source-contentful/src/__tests__/rich-text.js +++ b/packages/gatsby-source-contentful/src/__tests__/rich-text.js @@ -10,7 +10,7 @@ import { BLOCKS, INLINES } from "@contentful/rich-text-types" import { initialSync } from "../__fixtures__/rich-text-data" import { cloneDeep } from "lodash" -const raw = JSON.stringify({ +const raw = { nodeType: `document`, data: {}, content: [ @@ -406,7 +406,7 @@ const raw = JSON.stringify({ data: {}, }, ], -}) +} const fixtures = initialSync().currentSyncData @@ -414,7 +414,6 @@ const references = [ ...fixtures.entries.map(entity => { return { sys: entity.sys, - contentful_id: entity.sys.id, __typename: `ContentfulContent`, ...entity.fields, } @@ -422,7 +421,6 @@ const references = [ ...fixtures.assets.map(entity => { return { sys: entity.sys, - contentful_id: entity.sys.id, __typename: `ContentfulAsset`, ...entity.fields, } @@ -453,11 +451,7 @@ describe(`rich text`, () => { ) } - return ( - - Resolved inline Entry ({node.data.target.contentful_id}) - - ) + return Resolved inline Entry ({node.data.target.sys.id}) }, [INLINES.ENTRY_HYPERLINK]: node => { if (!node.data.target) { @@ -468,9 +462,7 @@ describe(`rich text`, () => { ) } return ( - - Resolved entry Hyperlink ({node.data.target.contentful_id}) - + Resolved entry Hyperlink ({node.data.target.sys.id}) ) }, [INLINES.ASSET_HYPERLINK]: node => { @@ -482,9 +474,7 @@ describe(`rich text`, () => { ) } return ( - - Resolved asset Hyperlink ({node.data.target.contentful_id}) - + Resolved asset Hyperlink ({node.data.target.sys.id}) ) }, [BLOCKS.EMBEDDED_ENTRY]: node => { @@ -496,7 +486,7 @@ describe(`rich text`, () => { return (

Resolved embedded Entry: {node.data.target.title[`en-US`]} ( - {node.data.target.contentful_id}) + {node.data.target.sys.id})

) }, @@ -509,7 +499,7 @@ describe(`rich text`, () => { return (

Resolved embedded Asset: {node.data.target.title[`en-US`]} ( - {node.data.target.contentful_id}) + {node.data.target.sys.id})

) }, diff --git a/packages/gatsby-source-contentful/src/config.js b/packages/gatsby-source-contentful/src/config.js new file mode 100644 index 0000000000000..0fd811c357a80 --- /dev/null +++ b/packages/gatsby-source-contentful/src/config.js @@ -0,0 +1,10 @@ +export const restrictedNodeFields = [ + // restrictedNodeFields from here https://www.gatsbyjs.org/docs/node-interface/ + `id`, + `children`, + `parent`, + `fields`, + `internal`, + // Contentful Common resource attributes: https://www.contentful.com/developers/docs/references/content-delivery-api/#/introduction/common-resource-attributes + `sys`, +] diff --git a/packages/gatsby-source-contentful/src/download-contentful-assets.js b/packages/gatsby-source-contentful/src/download-contentful-assets.js index a6c0c28d0e653..f6d7f6f82ca0d 100644 --- a/packages/gatsby-source-contentful/src/download-contentful-assets.js +++ b/packages/gatsby-source-contentful/src/download-contentful-assets.js @@ -50,9 +50,12 @@ export async function downloadContentfulAssets(gatsbyFunctions) { await distributeWorkload( assetNodes.map(node => async () => { let fileNodeID - const { contentful_id: id, node_locale: locale } = node + const { + sys: { id, locale }, + } = node const remoteDataCacheKey = `contentful-asset-${id}-${locale}` const cacheRemoteData = await cache.get(remoteDataCacheKey) + if (!node.file) { reporter.log(id, locale) reporter.warn(`The asset with id: ${id}, contains no file.`) diff --git a/packages/gatsby-source-contentful/src/generate-schema.js b/packages/gatsby-source-contentful/src/generate-schema.js index 141d7fbfeab6f..a10bc19538cae 100644 --- a/packages/gatsby-source-contentful/src/generate-schema.js +++ b/packages/gatsby-source-contentful/src/generate-schema.js @@ -108,13 +108,8 @@ function generateAssetTypes({ createTypes }) { file: ContentfulAssetFile title: String description: String - node_locale: String - sys: ContentfulAssetSys - contentful_id: String! + sys: ContentfulInternalSys id: ID! - spaceId: String! - createdAt: Date @dateformat - updatedAt: Date @dateformat } `) @@ -140,13 +135,6 @@ function generateAssetTypes({ createTypes }) { height: Int } `) - - createTypes(` - type ContentfulAssetSys { - type: String - revision: Int - } - `) } export function generateSchema({ @@ -157,8 +145,8 @@ export function generateSchema({ }) { createTypes(` interface ContentfulInternalReference implements Node { - contentful_id: String! id: ID! + sys: ContentfulInternalSys } `) @@ -173,17 +161,21 @@ export function generateSchema({ createTypes(` type ContentfulInternalSys @dontInfer { - type: String - revision: Int + type: String! + id: String! + spaceId: String! + environmentId: String! contentType: ContentfulContentType @link(by: "id", from: "contentType___NODE") + firstPublishedAt: Date! + publishedAt: Date! + publishedVersion: Int! + locale: String! } `) createTypes(` interface ContentfulEntry implements Node @dontInfer { - contentful_id: String! id: ID! - spaceId: String! sys: ContentfulInternalSys } `) @@ -242,14 +234,20 @@ export function generateSchema({ } traverse(source) - return context.nodeModel - .getAllNodes() - .filter(node => - node.internal.owner === `gatsby-source-contentful` && - node.internal.type === `ContentfulAsset` - ? referencedAssets.has(node.contentful_id) - : referencedEntries.has(node.contentful_id) - ) + // Get all nodes and return all that got referenced in the rich text + return context.nodeModel.getAllNodes().filter(node => { + if ( + !( + node.internal.owner === `gatsby-source-contentful` && + node?.sys?.id + ) + ) { + return false + } + return node.internal.type === `ContentfulAsset` + ? referencedAssets.has(node.sys.id) + : referencedEntries.has(node.sys.id) + }) }, }, }, @@ -302,15 +300,7 @@ export function generateSchema({ schema.buildObjectType({ name: makeTypeName(type), fields: { - contentful_id: { type: `String!` }, id: { type: `ID!` }, - // @todo reconsider the node per locale workflow - node_locale: { type: `String!` }, - // @todo these should be real dates and in sys - spaceId: { type: `String!` }, - createdAt: { type: `Date`, extensions: { dateformat: {} } }, - updatedAt: { type: `Date`, extensions: { dateformat: {} } }, - // @todo add metadata sys: { type: `ContentfulInternalSys` }, ...fields, }, diff --git a/packages/gatsby-source-contentful/src/normalize.js b/packages/gatsby-source-contentful/src/normalize.js index 06fc95d65751d..753bd0fe83449 100644 --- a/packages/gatsby-source-contentful/src/normalize.js +++ b/packages/gatsby-source-contentful/src/normalize.js @@ -1,5 +1,4 @@ // @ts-check -import stringify from "json-stringify-safe" import _ from "lodash" import { getGatsbyVersion } from "gatsby-core-utils" import { lt, prerelease } from "semver" @@ -58,6 +57,10 @@ const makeMakeId = (spaceId, id, type) => createNodeId(makeId({ spaceId, id, currentLocale, defaultLocale, type })) +// Generates an unique id per space for reference resolving +export const generateReferenceId = nodeOrLink => + `${nodeOrLink.sys.id}___${nodeOrLink.sys.linkType || nodeOrLink.sys.type}` + export const buildEntryList = ({ contentTypeItems, currentSyncData }) => { // Create buckets for each type sys.id that we care about (we will always want an array for each, even if its empty) const map = new Map( @@ -81,20 +84,18 @@ export const buildResolvableSet = ({ }) => { const resolvable = new Set() existingNodes.forEach(node => { - // We need to add only root level resolvable (assets and entries) - // Derived nodes (markdown or JSON) will be recreated if needed. - resolvable.add(`${node.contentful_id}___${node.sys.type}`) + if (node.internal.owner === `gatsby-source-contentful` && node?.sys?.id) { + // We need to add only root level resolvable (assets and entries) + // Derived nodes (markdown or JSON) will be recreated if needed. + resolvable.add(generateReferenceId(node)) + } }) entryList.forEach(entries => { - entries.forEach(entry => - resolvable.add(`${entry.sys.id}___${entry.sys.type}`) - ) + entries.forEach(entry => resolvable.add(generateReferenceId(entry))) }) - assets.forEach(assetItem => - resolvable.add(`${assetItem.sys.id}___${assetItem.sys.type}`) - ) + assets.forEach(assetItem => resolvable.add(generateReferenceId(assetItem))) return resolvable } @@ -135,7 +136,7 @@ export const buildForeignReferenceMap = ({ entryItemFieldValue[0].sys.id ) { entryItemFieldValue.forEach(v => { - const key = `${v.sys.id}___${v.sys.linkType || v.sys.type}` + const key = generateReferenceId(v) // Don't create link to an unresolvable field. if (!resolvable.has(key)) { return @@ -156,9 +157,7 @@ export const buildForeignReferenceMap = ({ entryItemFieldValue?.sys?.type && entryItemFieldValue.sys.id ) { - const key = `${entryItemFieldValue.sys.id}___${ - entryItemFieldValue.sys.linkType || entryItemFieldValue.sys.type - }` + const key = generateReferenceId(entryItemFieldValue) // Don't create link to an unresolvable field. if (!resolvable.has(key)) { return @@ -192,8 +191,8 @@ function prepareTextNode(id, node, key, text) { type: `ContentfulNodeTypeText`, mediaType: `text/markdown`, content: str, - // entryItem.sys.updatedAt is source of truth from contentful - contentDigest: node.updatedAt, + // entryItem.sys.publishedAt is source of truth from contentful + contentDigest: node.sys.publishedAt, }, } @@ -310,6 +309,17 @@ export const createNodesForContentType = ({ type: `${makeTypeName(`ContentType`)}`, contentDigest: contentTypeItem.sys.updatedAt, }, + // https://www.contentful.com/developers/docs/references/content-delivery-api/#/introduction/common-resource-attributes + // https://www.contentful.com/developers/docs/references/graphql/#/reference/schema-generation/sys-field + sys: { + type: contentTypeItem.sys.type, + id: contentTypeItem.sys.id, + spaceId: contentTypeItem.sys.space.sys.id, + environmentId: contentTypeItem.sys.environment.sys.id, + firstPublishedAt: contentTypeItem.sys.createdAt, + publishedAt: contentTypeItem.sys.updatedAt, + publishedVersion: contentTypeItem.sys.revision, + }, } createNodePromises.push(createNode(contentTypeNode)) @@ -387,11 +397,7 @@ export const createNodesForContentType = ({ // creating an empty node field in case when original key field value // is empty due to links to missing entities const resolvableEntryItemFieldValue = entryItemFieldValue - .filter(function (v) { - return resolvable.has( - `${v.sys.id}___${v.sys.linkType || v.sys.type}` - ) - }) + .filter(v => resolvable.has(generateReferenceId(v))) .map(function (v) { return mId( space.sys.id, @@ -407,14 +413,7 @@ export const createNodesForContentType = ({ delete entryItemFields[entryItemFieldKey] } } else if (entryItemFieldValue?.sys?.type === `Link`) { - if ( - resolvable.has( - `${entryItemFieldValue.sys.id}___${ - entryItemFieldValue.sys.linkType || - entryItemFieldValue.sys.type - }` - ) - ) { + if (resolvable.has(generateReferenceId(entryItemFieldValue))) { entryItemFields[`${entryItemFieldKey}___NODE`] = mId( space.sys.id, entryItemFieldValue.sys.id, @@ -429,7 +428,7 @@ export const createNodesForContentType = ({ // Add reverse linkages if there are any for this node const foreignReferences = - foreignReferenceMap[`${entryItem.sys.id}___${entryItem.sys.type}`] + foreignReferenceMap[generateReferenceId(entryItem)] if (foreignReferences) { foreignReferences.forEach(foreignReference => { const existingReference = entryItemFields[foreignReference.name] @@ -460,27 +459,9 @@ export const createNodesForContentType = ({ }) } - const sys = { - type: entryItem.sys.type, - } - - // Revision applies to entries, assets, and content types - if (entryItem.sys.revision) { - sys.revision = entryItem.sys.revision - } - - // Content type applies to entries only - if (entryItem.sys.contentType) { - sys.contentType___NODE = createNodeId(contentTypeItemId) - } - // Create actual entry node let entryNode = { id: entryNodeId, - spaceId: space.sys.id, - contentful_id: entryItem.sys.id, - createdAt: entryItem.sys.createdAt, - updatedAt: entryItem.sys.updatedAt, parent: contentTypeItemId, children: [], internal: { @@ -488,7 +469,19 @@ export const createNodesForContentType = ({ // The content of an entry is guaranteed to be updated if and only if the .sys.updatedAt field changed contentDigest: entryItem.sys.updatedAt, }, - sys, + // https://www.contentful.com/developers/docs/references/content-delivery-api/#/introduction/common-resource-attributes + // https://www.contentful.com/developers/docs/references/graphql/#/reference/schema-generation/sys-field + sys: { + type: entryItem.sys.type, + id: entryItem.sys.id, + locale: locale.code, + spaceId: entryItem.sys.space.sys.id, + environmentId: entryItem.sys.environment.sys.id, + contentType___NODE: createNodeId(contentTypeItemId), + firstPublishedAt: entryItem.sys.createdAt, + publishedAt: entryItem.sys.updatedAt, + publishedVersion: entryItem.sys.revision, + }, } contentfulCreateNodeManifest({ @@ -499,16 +492,6 @@ export const createNodesForContentType = ({ unstable_createNodeManifest, }) - // Revision applies to entries, assets, and content types - if (entryItem.sys.revision) { - entryNode.sys.revision = entryItem.sys.revision - } - - // Content type applies to entries only - if (entryItem.sys.contentType) { - entryNode.sys.contentType = entryItem.sys.contentType - } - // Replace text fields with text nodes so we can process their markdown // into HTML. Object.keys(entryItemFields).forEach(entryItemFieldKey => { @@ -554,7 +537,6 @@ export const createNodesForContentType = ({ entryNode = { ...entryItemFields, ...entryNode, - node_locale: locale.code, } // Link tags @@ -604,11 +586,7 @@ export const createAssetNodes = ({ }) const assetNode = { - contentful_id: assetItem.sys.id, - spaceId: space.sys.id, id: mId(space.sys.id, assetItem.sys.id, assetItem.sys.type), - createdAt: assetItem.sys.createdAt, - updatedAt: assetItem.sys.updatedAt, parent: null, children: [], file: assetItem.fields.file ? getField(assetItem.fields.file) : null, @@ -616,15 +594,22 @@ export const createAssetNodes = ({ description: assetItem.fields.description ? getField(assetItem.fields.description) : ``, - node_locale: locale.code, internal: { type: `${makeTypeName(`Asset`)}`, // The content of an asset is guaranteed to be updated if and only if the .sys.updatedAt field changed contentDigest: assetItem.sys.updatedAt, }, - // @todo we can probably remove this now + // https://www.contentful.com/developers/docs/references/content-delivery-api/#/introduction/common-resource-attributes + // https://www.contentful.com/developers/docs/references/graphql/#/reference/schema-generation/sys-field sys: { type: assetItem.sys.type, + id: assetItem.sys.id, + locale: locale.code, + spaceId: assetItem.sys.space.sys.id, + environmentId: assetItem.sys.environment.sys.id, + firstPublishedAt: assetItem.sys.createdAt, + publishedAt: assetItem.sys.updatedAt, + publishedVersion: assetItem.sys.revision, }, } @@ -637,14 +622,6 @@ export const createAssetNodes = ({ } } - // Revision applies to entries, assets, and content types - if (assetItem.sys.revision) { - assetNode.sys.revision = assetItem.sys.revision - } - - // The content of an entry is guaranteed to be updated if and only if the .sys.updatedAt field changed - assetNode.internal.contentDigest = assetItem.sys.updatedAt - // if the node hasn't changed, createNode may return `undefined` instead of a Promise on some versions of Gatsby const maybePromise = createNode(assetNode) diff --git a/packages/gatsby-source-contentful/src/rich-text.js b/packages/gatsby-source-contentful/src/rich-text.js index 662914b6013f3..45e8753193aea 100644 --- a/packages/gatsby-source-contentful/src/rich-text.js +++ b/packages/gatsby-source-contentful/src/rich-text.js @@ -24,7 +24,7 @@ export function renderRichText({ raw, references }, options = {}) { .map(reference => { return { ...reference, - sys: { type: `Entry`, id: reference.contentful_id }, + sys: { type: `Entry`, id: reference.sys.id }, } }), Asset: references @@ -32,7 +32,7 @@ export function renderRichText({ raw, references }, options = {}) { .map(reference => { return { ...reference, - sys: { type: `Asset`, id: reference.contentful_id }, + sys: { type: `Asset`, id: reference.sys.id }, } }), }, diff --git a/packages/gatsby-source-contentful/src/source-nodes.js b/packages/gatsby-source-contentful/src/source-nodes.js index 4487e3d0c7836..be4c23995180d 100644 --- a/packages/gatsby-source-contentful/src/source-nodes.js +++ b/packages/gatsby-source-contentful/src/source-nodes.js @@ -11,6 +11,7 @@ import { buildResolvableSet, createAssetNodes, createNodesForContentType, + generateReferenceId, makeId, } from "./normalize" import { createPluginConfig } from "./plugin-options" @@ -51,7 +52,6 @@ export async function sourceNodes( reporter, parentSpan, schema, - createContentDigest, }, pluginOptions ) { @@ -260,31 +260,30 @@ export async function sourceNodes( const newOrUpdatedEntries = new Set() entryList.forEach(entries => { entries.forEach(entry => { - newOrUpdatedEntries.add(`${entry.sys.id}___${entry.sys.type}`) + newOrUpdatedEntries.add(generateReferenceId(entry)) }) }) // Update existing entry nodes that weren't updated but that need reverse links added. existingNodes - .filter(n => !newOrUpdatedEntries.has(`${n.id}___${n.sys.type}`)) + .filter(n => !newOrUpdatedEntries.has(generateReferenceId(n))) .forEach(n => { - if (foreignReferenceMap[`${n.id}___${n.sys.type}`]) { - foreignReferenceMap[`${n.id}___${n.sys.type}`].forEach( - foreignReference => { - const { name, id } = foreignReference - - // Create new reference field when none exists - if (!n[name]) { - n[name] = [id] - return - } - - // Add non existing references to reference field - if (n[name] && !n[name].includes(id)) { - n[name].push(id) - } + const nodeId = generateReferenceId(n) + if (foreignReferenceMap[nodeId]) { + foreignReferenceMap[nodeId].forEach(foreignReference => { + const { name, id } = foreignReference + + // Create new reference field when none exists + if (!n[name]) { + n[name] = [id] + return } - ) + + // Add non existing references to reference field + if (n[name] && !n[name].includes(id)) { + n[name].push(id) + } + }) } }) @@ -371,7 +370,6 @@ export async function sourceNodes( useNameForId: pluginConfig.get(`useNameForId`), pluginConfig, unstable_createNodeManifest, - createContentDigest, }) ) } From 220624a7df1f8a145b2271051b1264ee0f7f9c16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benedikt=20R=C3=B6tsch?= Date: Wed, 5 May 2021 17:47:27 +0200 Subject: [PATCH 15/34] refactor: align Rich Text field structure to Contentful GraphQL API (#31122) --- e2e-tests/contentful/src/pages/rich-text.js | 122 +- .../gatsby-source-contentful/package.json | 1 + .../src/__tests__/rich-text.js | 191 +-- .../src/generate-schema.js | 129 +- .../gatsby-source-contentful/src/rich-text.js | 78 +- yarn.lock | 1135 ++++++++--------- 6 files changed, 873 insertions(+), 783 deletions(-) diff --git a/e2e-tests/contentful/src/pages/rich-text.js b/e2e-tests/contentful/src/pages/rich-text.js index 0cd2a3eca6127..12c792bc4eea2 100644 --- a/e2e-tests/contentful/src/pages/rich-text.js +++ b/e2e-tests/contentful/src/pages/rich-text.js @@ -20,13 +20,13 @@ function renderReferencedComponent(ref) { return } -const options = { +const makeOptions = ({ assetBlockMap, entryBlockMap, entryInlineMap }) => ({ renderMark: { [MARKS.BOLD]: text => {text}, }, renderNode: { [BLOCKS.EMBEDDED_ASSET]: node => { - const asset = node.data.target + const asset = assetBlockMap.get(node?.data?.target?.sys.id) if (asset.gatsbyImageData) { return } @@ -40,7 +40,7 @@ const options = { ) }, [BLOCKS.EMBEDDED_ENTRY]: node => { - const entry = node?.data?.target + const entry = entryBlockMap.get(node?.data?.target?.sys.id) if (!entry) { throw new Error( `Entity not available for node:\n${JSON.stringify(node, null, 2)}` @@ -49,7 +49,7 @@ const options = { return renderReferencedComponent(entry) }, [INLINES.EMBEDDED_ENTRY]: node => { - const entry = node.data.target + const entry = entryInlineMap.get(node?.data?.target?.sys.id) if (entry.__typename === "ContentfulText") { return ( @@ -64,7 +64,7 @@ const options = { ) }, }, -} +}) const RichTextPage = ({ data }) => { const defaultEntries = data.default.nodes @@ -77,7 +77,7 @@ const RichTextPage = ({ data }) => { return (

{title}

- {renderRichText(richText, options)} + {renderRichText(richText, makeOptions)}
) @@ -89,7 +89,7 @@ const RichTextPage = ({ data }) => { return (

{title}

- {renderRichText(richTextLocalized, options)} + {renderRichText(richTextLocalized, makeOptions)}
) @@ -101,7 +101,7 @@ const RichTextPage = ({ data }) => { return (

{title}

- {renderRichText(richTextLocalized, options)} + {renderRichText(richTextLocalized, makeOptions)}
) @@ -125,76 +125,92 @@ export const pageQuery = graphql` id title richText { - raw - references { - __typename - sys { - id - } - ... on ContentfulAsset { - contentful_id - gatsbyImageData(width: 200) - } - ... on ContentfulText { - title - short - } - ... on ContentfulLocation { - location { - lat - lon + json + links { + assets { + block { + sys { + id + } + gatsbyImageData(width: 200) } } - ... on ContentfulContentReference { - title - one { + entries { + block { __typename sys { id + type } ... on ContentfulText { title short } + ... on ContentfulLocation { + location { + lat + lon + } + } ... on ContentfulContentReference { title one { + __typename + sys { + id + } + ... on ContentfulText { + title + short + } ... on ContentfulContentReference { title + one { + ... on ContentfulContentReference { + title + } + } + many { + ... on ContentfulContentReference { + title + } + } } } many { + __typename + sys { + id + } + ... on ContentfulText { + title + short + } + ... on ContentfulNumber { + title + integer + } ... on ContentfulContentReference { title + one { + ... on ContentfulContentReference { + title + } + } + many { + ... on ContentfulContentReference { + title + } + } } } } } - many { + inline { __typename sys { id - } - ... on ContentfulText { - title - short - } - ... on ContentfulNumber { - title - integer - } - ... on ContentfulContentReference { - title - one { - ... on ContentfulContentReference { - title - } - } - many { - ... on ContentfulContentReference { - title - } - } + type } } } @@ -213,7 +229,7 @@ export const pageQuery = graphql` id title richTextLocalized { - raw + json } } } @@ -228,7 +244,7 @@ export const pageQuery = graphql` id title richTextLocalized { - raw + json } } } diff --git a/packages/gatsby-source-contentful/package.json b/packages/gatsby-source-contentful/package.json index 9da53b108859d..53d2cdea751e0 100644 --- a/packages/gatsby-source-contentful/package.json +++ b/packages/gatsby-source-contentful/package.json @@ -9,6 +9,7 @@ "dependencies": { "@babel/runtime": "^7.15.4", "@contentful/rich-text-react-renderer": "^14.1.3", + "@contentful/rich-text-links": "^14.1.2", "@contentful/rich-text-types": "^14.1.2", "@hapi/joi": "^15.1.1", "@vercel/fetch-retry": "^5.0.3", diff --git a/packages/gatsby-source-contentful/src/__tests__/rich-text.js b/packages/gatsby-source-contentful/src/__tests__/rich-text.js index 54207938a4543..9df80a17a5a7a 100644 --- a/packages/gatsby-source-contentful/src/__tests__/rich-text.js +++ b/packages/gatsby-source-contentful/src/__tests__/rich-text.js @@ -5,12 +5,13 @@ // @ts-check import React from "react" import { render } from "@testing-library/react" -import { renderRichText } from "gatsby-source-contentful/rich-text" +import { renderRichText } from "../rich-text" import { BLOCKS, INLINES } from "@contentful/rich-text-types" +import { getRichTextEntityLinks } from "@contentful/rich-text-links" import { initialSync } from "../__fixtures__/rich-text-data" import { cloneDeep } from "lodash" -const raw = { +const json = { nodeType: `document`, data: {}, content: [ @@ -409,107 +410,129 @@ const raw = { } const fixtures = initialSync().currentSyncData +const fixturesEntriesMap = new Map() +const fixturesAssetsMap = new Map() -const references = [ - ...fixtures.entries.map(entity => { - return { - sys: entity.sys, - __typename: `ContentfulContent`, - ...entity.fields, - } - }), - ...fixtures.assets.map(entity => { - return { - sys: entity.sys, - __typename: `ContentfulAsset`, - ...entity.fields, - } - }), -] +fixtures.entries.forEach(entity => + fixturesEntriesMap.set(entity.sys.id, { sys: entity.sys, ...entity.fields }) +) +fixtures.assets.forEach(entity => + fixturesAssetsMap.set(entity.sys.id, { sys: entity.sys, ...entity.fields }) +) + +const links = { + assets: { + block: getRichTextEntityLinks(json, `embedded-asset-block`)[`Asset`].map( + entity => fixturesAssetsMap.get(entity.id) + ), + hyperlink: getRichTextEntityLinks(json, `asset-hyperlink`)[`Asset`].map( + entity => fixturesAssetsMap.get(entity.id) + ), + }, + entries: { + inline: getRichTextEntityLinks(json, `embedded-entry-inline`)[`Entry`].map( + entity => fixturesEntriesMap.get(entity.id) + ), + block: getRichTextEntityLinks(json, `embedded-entry-block`)[`Entry`].map( + entity => fixturesEntriesMap.get(entity.id) + ), + hyperlink: getRichTextEntityLinks(json, `entry-hyperlink`)[`Entry`].map( + entity => fixturesEntriesMap.get(entity.id) + ), + }, +} describe(`rich text`, () => { test(`renders with default options`, () => { const { container } = render( - <> - {renderRichText({ - raw: cloneDeep(raw), - references: cloneDeep(references), - })} - + <>{renderRichText({ json: cloneDeep(json), links: cloneDeep(links) })} ) expect(container).toMatchSnapshot() }) test(`renders with custom options`, () => { - const options = { - renderNode: { - [INLINES.EMBEDDED_ENTRY]: node => { - if (!node.data.target) { - return ( - - Unresolved INLINE ENTRY: {JSON.stringify(node, null, 2)} - - ) - } - return Resolved inline Entry ({node.data.target.sys.id}) - }, - [INLINES.ENTRY_HYPERLINK]: node => { - if (!node.data.target) { - return ( - - Unresolved ENTRY HYPERLINK: {JSON.stringify(node, null, 2)} - - ) - } - return ( - Resolved entry Hyperlink ({node.data.target.sys.id}) - ) - }, - [INLINES.ASSET_HYPERLINK]: node => { - if (!node.data.target) { - return ( - - Unresolved ASSET HYPERLINK: {JSON.stringify(node, null, 2)} - - ) - } - return ( - Resolved asset Hyperlink ({node.data.target.sys.id}) - ) - }, - [BLOCKS.EMBEDDED_ENTRY]: node => { - if (!node.data.target) { + const makeOptions = ({ + assetBlockMap, + assetHyperlinkMap, + entryBlockMap, + entryInlineMap, + entryHyperlinkMap, + }) => { + return { + renderNode: { + [INLINES.EMBEDDED_ENTRY]: node => { + const entry = entryInlineMap.get(node?.data?.target?.sys.id) + if (!entry) { + return ( + + Unresolved INLINE ENTRY:{` `} + {JSON.stringify({ node, entryInlineMap }, null, 2)} + + ) + } + return Resolved inline Entry ({entry.sys.id}) + }, + [INLINES.ENTRY_HYPERLINK]: node => { + const entry = entryHyperlinkMap.get(node?.data?.target?.sys.id) + if (!entry) { + return ( + + Unresolved ENTRY HYPERLINK: {JSON.stringify(node, null, 2)} + + ) + } + return Resolved entry Hyperlink ({entry.sys.id}) + }, + [INLINES.ASSET_HYPERLINK]: node => { + const entry = assetHyperlinkMap.get(node?.data?.target?.sys.id) + if (!entry) { + return ( + + Unresolved ASSET HYPERLINK: {JSON.stringify(node, null, 2)} + + ) + } + return Resolved asset Hyperlink ({entry.sys.id}) + }, + [BLOCKS.EMBEDDED_ENTRY]: node => { + const entry = entryBlockMap.get(node?.data?.target?.sys.id) + if (!entry) { + return ( +
+ Unresolved ENTRY !!!!": {JSON.stringify(node, null, 2)} +
+ ) + } return ( -
Unresolved ENTRY !!!!": {JSON.stringify(node, null, 2)}
+

+ Resolved embedded Entry: {entry.title[`en-US`]} ({entry.sys.id}) +

) - } - return ( -

- Resolved embedded Entry: {node.data.target.title[`en-US`]} ( - {node.data.target.sys.id}) -

- ) - }, - [BLOCKS.EMBEDDED_ASSET]: node => { - if (!node.data.target) { + }, + [BLOCKS.EMBEDDED_ASSET]: node => { + const entry = assetBlockMap.get(node?.data?.target?.sys.id) + if (!entry) { + return ( +
+ Unresolved ASSET !!!!": {JSON.stringify(node, null, 2)} +
+ ) + } return ( -
Unresolved ASSET !!!!": {JSON.stringify(node, null, 2)}
+

+ Resolved embedded Asset: {entry.title[`en-US`]} ({entry.sys.id}) +

) - } - return ( -

- Resolved embedded Asset: {node.data.target.title[`en-US`]} ( - {node.data.target.sys.id}) -

- ) + }, }, - }, + } } + const { container } = render( <> {renderRichText( - { raw: cloneDeep(raw), references: cloneDeep(references) }, - options + { json: cloneDeep(json), links: cloneDeep(links) }, + makeOptions )} ) diff --git a/packages/gatsby-source-contentful/src/generate-schema.js b/packages/gatsby-source-contentful/src/generate-schema.js index a10bc19538cae..b55d701cf99e3 100644 --- a/packages/gatsby-source-contentful/src/generate-schema.js +++ b/packages/gatsby-source-contentful/src/generate-schema.js @@ -1,3 +1,5 @@ +import { getRichTextEntityLinks } from "@contentful/rich-text-links" + import { makeTypeName } from "./normalize" // Contentful content type schemas @@ -143,6 +145,7 @@ export function generateSchema({ pluginConfig, contentTypeItems, }) { + // Generic Types createTypes(` interface ContentfulInternalReference implements Node { id: ID! @@ -180,8 +183,29 @@ export function generateSchema({ } `) + // Assets generateAssetTypes({ createTypes }) + // Rich Text + 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. + ) + } + // Contentful specific types if (pluginConfig.get(`enableTags`)) { createTypes( @@ -198,56 +222,76 @@ export function generateSchema({ ) } + createTypes( + schema.buildObjectType({ + name: `ContentfulNodeTypeRichTextAssets`, + fields: { + block: { + type: `[ContentfulAsset]!`, + resolve: makeRichTextLinksResolver(`embedded-asset-block`, `Asset`), + }, + hyperlink: { + type: `[ContentfulAsset]!`, + resolve: makeRichTextLinksResolver(`asset-hyperlink`, `Asset`), + }, + }, + }) + ) + + createTypes( + schema.buildObjectType({ + name: `ContentfulNodeTypeRichTextEntries`, + fields: { + inline: { + type: `[ContentfulEntry]!`, + resolve: makeRichTextLinksResolver(`embedded-entry-inline`, `Entry`), + }, + block: { + type: `[ContentfulEntry]!`, + resolve: makeRichTextLinksResolver(`embedded-entry-block`, `Entry`), + }, + hyperlink: { + type: `[ContentfulEntry]!`, + resolve: makeRichTextLinksResolver(`entry-hyperlink`, `Entry`), + }, + }, + }) + ) + + createTypes( + schema.buildObjectType({ + name: `ContentfulNodeTypeRichTextLinks`, + fields: { + assets: { + type: `ContentfulNodeTypeRichTextAssets`, + resolve(source) { + return source + }, + }, + entries: { + type: `ContentfulNodeTypeRichTextEntries`, + resolve(source) { + return source + }, + }, + }, + }) + ) + createTypes( schema.buildObjectType({ name: `ContentfulNodeTypeRichText`, fields: { - raw: { + json: { type: `JSON`, resolve(source) { return source }, }, - references: { - type: `[ContentfulInternalReference]`, - resolve(source, args, context) { - const referencedEntries = new Set() - const referencedAssets = new Set() - - // Locate all Contentful Links within the rich text data - // Traverse logic based on https://github.com/contentful/contentful-resolve-response - const traverse = obj => { - // eslint-disable-next-line guard-for-in - for (const k in obj) { - const v = obj[k] - if (v && v.sys && v.sys.type === `Link`) { - if (v.sys.linkType === `Asset`) { - referencedAssets.add(v.sys.id) - } - if (v.sys.linkType === `Entry`) { - referencedEntries.add(v.sys.id) - } - } else if (v && typeof v === `object`) { - traverse(v) - } - } - } - traverse(source) - - // Get all nodes and return all that got referenced in the rich text - return context.nodeModel.getAllNodes().filter(node => { - if ( - !( - node.internal.owner === `gatsby-source-contentful` && - node?.sys?.id - ) - ) { - return false - } - return node.internal.type === `ContentfulAsset` - ? referencedAssets.has(node.sys.id) - : referencedEntries.has(node.sys.id) - }) + links: { + type: `ContentfulNodeTypeRichTextLinks`, + resolve(source) { + return source }, }, }, @@ -255,6 +299,7 @@ export function generateSchema({ }) ) + // Location createTypes( schema.buildObjectType({ name: `ContentfulNodeTypeLocation`, @@ -268,6 +313,7 @@ export function generateSchema({ }) ) + // Text // @todo Is there a way to have this as string and let transformer-remark replace it with an object? createTypes( schema.buildObjectType({ @@ -282,6 +328,7 @@ export function generateSchema({ }) ) + // Content types for (const contentTypeItem of contentTypeItems) { try { const fields = {} diff --git a/packages/gatsby-source-contentful/src/rich-text.js b/packages/gatsby-source-contentful/src/rich-text.js index 45e8753193aea..0019e715e59fc 100644 --- a/packages/gatsby-source-contentful/src/rich-text.js +++ b/packages/gatsby-source-contentful/src/rich-text.js @@ -1,46 +1,52 @@ // @ts-check import { documentToReactComponents } from "@contentful/rich-text-react-renderer" -import resolveResponse from "contentful-resolve-response" -export function renderRichText({ raw, references }, options = {}) { - const richText = raw +export function renderRichText({ json, links }, makeOptions = {}) { + const options = + typeof makeOptions === `function` + ? makeOptions(generateLinkMaps(links)) + : makeOptions - // If no references are given, there is no need to resolve them - if (!references || !references.length) { - return documentToReactComponents(richText, options) + return documentToReactComponents(json, options) +} + +exports.renderRichText = renderRichText + +/** + * Helper function to simplify Rich Text rendering. Based on: + * https://www.contentful.com/blog/2021/04/14/rendering-linked-assets-entries-in-contentful/ + */ +function generateLinkMaps(links) { + const assetBlockMap = new Map() + for (const asset of links.assets.block || []) { + assetBlockMap.set(asset.sys.id, asset) } - // Create dummy response so we can use official libraries for resolving the entries - const dummyResponse = { - items: [ - { - sys: { type: `Entry` }, - richText, - }, - ], - includes: { - Entry: references - .filter(({ __typename }) => __typename !== `ContentfulAsset`) - .map(reference => { - return { - ...reference, - sys: { type: `Entry`, id: reference.sys.id }, - } - }), - Asset: references - .filter(({ __typename }) => __typename === `ContentfulAsset`) - .map(reference => { - return { - ...reference, - sys: { type: `Asset`, id: reference.sys.id }, - } - }), - }, + const assetHyperlinkMap = new Map() + for (const asset of links.assets.hyperlink || []) { + assetHyperlinkMap.set(asset.sys.id, asset) } - const resolved = resolveResponse(dummyResponse, { - removeUnresolved: true, - }) + const entryBlockMap = new Map() + for (const entry of links.entries.block || []) { + entryBlockMap.set(entry.sys.id, entry) + } - return documentToReactComponents(resolved[0].richText, options) + const entryInlineMap = new Map() + for (const entry of links.entries.inline || []) { + entryInlineMap.set(entry.sys.id, entry) + } + + const entryHyperlinkMap = new Map() + for (const entry of links.entries.hyperlink || []) { + entryHyperlinkMap.set(entry.sys.id, entry) + } + + return { + assetBlockMap, + assetHyperlinkMap, + entryBlockMap, + entryInlineMap, + entryHyperlinkMap, + } } diff --git a/yarn.lock b/yarn.lock index 7ad7ca68a9ac9..68e44d8f8d517 100644 --- a/yarn.lock +++ b/yarn.lock @@ -189,10 +189,10 @@ dependencies: "@babel/highlight" "^7.16.7" -"@babel/compat-data@^7.13.11", "@babel/compat-data@^7.14.7", "@babel/compat-data@^7.15.0": - version "7.15.0" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.15.0.tgz#2dbaf8b85334796cafbb0f5793a90a2fc010b176" - integrity sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA== +"@babel/compat-data@^7.13.11", "@babel/compat-data@^7.14.7", "@babel/compat-data@^7.15.0", "@babel/compat-data@^7.16.4": + version "7.16.4" + resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.16.4.tgz#081d6bbc336ec5c2435c6346b2ae1fb98b5ac68e" + integrity sha512-1o/jo7D+kC9ZjHX5v+EHrdjl3PhxMrLSOTGsOdHJ+KL8HCaEK6ehrVL2RS6oHDZp+L7xLirLrPmQtEng769J/Q== "@babel/core@7.10.5": version "7.10.5" @@ -260,20 +260,20 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/core@^7.1.0", "@babel/core@^7.12.10", "@babel/core@^7.13.16", "@babel/core@^7.14.5", "@babel/core@^7.15.5", "@babel/core@^7.7.2", "@babel/core@^7.7.5": - version "7.15.5" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.15.5.tgz#f8ed9ace730722544609f90c9bb49162dc3bf5b9" - integrity sha512-pYgXxiwAgQpgM1bNkZsDEq85f0ggXMA5L7c+o3tskGMh2BunCI9QUwB9Z4jpvXUOuMdyGKiGKQiRe11VS6Jzvg== +"@babel/core@^7.1.0", "@babel/core@^7.12.10", "@babel/core@^7.12.3", "@babel/core@^7.13.16", "@babel/core@^7.14.5", "@babel/core@^7.15.5", "@babel/core@^7.7.2", "@babel/core@^7.7.5", "@babel/core@^7.8.0": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/core/-/core-7.16.7.tgz#db990f931f6d40cb9b87a0dc7d2adc749f1dcbcf" + integrity sha512-aeLaqcqThRNZYmbMqtulsetOQZ/5gbR/dWruUCJcpas4Qoyy+QeagfDsPdMrqwsPRDNxJvBlRiZxxX7THO7qtA== dependencies: - "@babel/code-frame" "^7.14.5" - "@babel/generator" "^7.15.4" - "@babel/helper-compilation-targets" "^7.15.4" - "@babel/helper-module-transforms" "^7.15.4" - "@babel/helpers" "^7.15.4" - "@babel/parser" "^7.15.5" - "@babel/template" "^7.15.4" - "@babel/traverse" "^7.15.4" - "@babel/types" "^7.15.4" + "@babel/code-frame" "^7.16.7" + "@babel/generator" "^7.16.7" + "@babel/helper-compilation-targets" "^7.16.7" + "@babel/helper-module-transforms" "^7.16.7" + "@babel/helpers" "^7.16.7" + "@babel/parser" "^7.16.7" + "@babel/template" "^7.16.7" + "@babel/traverse" "^7.16.7" + "@babel/types" "^7.16.7" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.2" @@ -306,9 +306,9 @@ jsesc "^2.5.1" source-map "^0.5.0" -"@babel/generator@^7.10.5", "@babel/generator@^7.12.1", "@babel/generator@^7.12.11", "@babel/generator@^7.12.5", "@babel/generator@^7.15.4", "@babel/generator@^7.16.8", "@babel/generator@^7.7.2": +"@babel/generator@^7.10.5", "@babel/generator@^7.12.1", "@babel/generator@^7.12.11", "@babel/generator@^7.12.5", "@babel/generator@^7.15.4", "@babel/generator@^7.16.7", "@babel/generator@^7.16.8", "@babel/generator@^7.7.2": version "7.16.8" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.16.8.tgz#359d44d966b8cd059d543250ce79596f792f2ebe" + resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.16.8.tgz#359d44d966b8cd059d543250ce79596f792f2ebe" integrity sha512-1ojZwE9+lOXzcWdWmO6TbUzDfqLD39CmEhN8+2cX9XkDo5yW1OpgfejfliysR2AWLpMamTiOiAp/mtroaymhpw== dependencies: "@babel/types" "^7.16.8" @@ -330,14 +330,14 @@ "@babel/helper-explode-assignable-expression" "^7.14.5" "@babel/types" "^7.14.5" -"@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.14.5", "@babel/helper-compilation-targets@^7.15.4": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.4.tgz#cf6d94f30fbefc139123e27dd6b02f65aeedb7b9" - integrity sha512-rMWPCirulnPSe4d+gwdWXLfAXTTBj8M3guAf5xFQJ0nvFY7tfNAFnWdqaHegHlgDZOCT4qvhF3BYlSJag8yhqQ== +"@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.14.5", "@babel/helper-compilation-targets@^7.15.4", "@babel/helper-compilation-targets@^7.16.7": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz#06e66c5f299601e6c7da350049315e83209d551b" + integrity sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA== dependencies: - "@babel/compat-data" "^7.15.0" - "@babel/helper-validator-option" "^7.14.5" - browserslist "^4.16.6" + "@babel/compat-data" "^7.16.4" + "@babel/helper-validator-option" "^7.16.7" + browserslist "^4.17.5" semver "^6.3.0" "@babel/helper-create-class-features-plugin@^7.12.1", "@babel/helper-create-class-features-plugin@^7.14.5", "@babel/helper-create-class-features-plugin@^7.15.4": @@ -374,6 +374,13 @@ resolve "^1.14.2" semver "^6.1.2" +"@babel/helper-environment-visitor@^7.16.7": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz#ff484094a839bde9d89cd63cba017d7aae80ecd7" + integrity sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag== + dependencies: + "@babel/types" "^7.16.7" + "@babel/helper-explode-assignable-expression@^7.14.5": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.14.5.tgz#8aa72e708205c7bb643e45c73b4386cdf2a1f645" @@ -388,28 +395,28 @@ dependencies: semver "^6.3.0" -"@babel/helper-function-name@^7.14.5", "@babel/helper-function-name@^7.15.4": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.15.4.tgz#845744dafc4381a4a5fb6afa6c3d36f98a787ebc" - integrity sha512-Z91cOMM4DseLIGOnog+Z8OI6YseR9bua+HpvLAQ2XayUGU+neTtX+97caALaLdyu53I/fjhbeCnWnRH1O3jFOw== +"@babel/helper-function-name@^7.14.5", "@babel/helper-function-name@^7.15.4", "@babel/helper-function-name@^7.16.7": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz#f1ec51551fb1c8956bc8dd95f38523b6cf375f8f" + integrity sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA== dependencies: - "@babel/helper-get-function-arity" "^7.15.4" - "@babel/template" "^7.15.4" - "@babel/types" "^7.15.4" + "@babel/helper-get-function-arity" "^7.16.7" + "@babel/template" "^7.16.7" + "@babel/types" "^7.16.7" -"@babel/helper-get-function-arity@^7.15.4": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.15.4.tgz#098818934a137fce78b536a3e015864be1e2879b" - integrity sha512-1/AlxSF92CmGZzHnC515hm4SirTxtpDnLEJ0UyEMgTMZN+6bxXKg04dKhiRx5Enel+SUA1G1t5Ed/yQia0efrA== +"@babel/helper-get-function-arity@^7.16.7": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz#ea08ac753117a669f1508ba06ebcc49156387419" + integrity sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw== dependencies: - "@babel/types" "^7.15.4" + "@babel/types" "^7.16.7" -"@babel/helper-hoist-variables@^7.15.4": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.15.4.tgz#09993a3259c0e918f99d104261dfdfc033f178df" - integrity sha512-VTy085egb3jUGVK9ycIxQiPbquesq0HUQ+tPO0uv5mPEBZipk+5FkRKiWq5apuyTE9FUrjENB0rCf8y+n+UuhA== +"@babel/helper-hoist-variables@^7.15.4", "@babel/helper-hoist-variables@^7.16.7": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz#86bcb19a77a509c7b77d0e22323ef588fa58c246" + integrity sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg== dependencies: - "@babel/types" "^7.15.4" + "@babel/types" "^7.16.7" "@babel/helper-member-expression-to-functions@^7.15.4": version "7.15.4" @@ -418,26 +425,26 @@ dependencies: "@babel/types" "^7.15.4" -"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.0.0-beta.49", "@babel/helper-module-imports@^7.10.4", "@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.14.5", "@babel/helper-module-imports@^7.15.4": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.15.4.tgz#e18007d230632dea19b47853b984476e7b4e103f" - integrity sha512-jeAHZbzUwdW/xHgHQ3QmWR4Jg6j15q4w/gCfwZvtqOxoo5DKtLHk8Bsf4c5RZRC7NmLEs+ohkdq8jFefuvIxAA== +"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.0.0-beta.49", "@babel/helper-module-imports@^7.10.4", "@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.14.5", "@babel/helper-module-imports@^7.16.7": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz#25612a8091a999704461c8a222d0efec5d091437" + integrity sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg== dependencies: - "@babel/types" "^7.15.4" + "@babel/types" "^7.16.7" -"@babel/helper-module-transforms@^7.10.5", "@babel/helper-module-transforms@^7.12.1", "@babel/helper-module-transforms@^7.14.5", "@babel/helper-module-transforms@^7.15.4": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.15.4.tgz#962cc629a7f7f9a082dd62d0307fa75fe8788d7c" - integrity sha512-9fHHSGE9zTC++KuXLZcB5FKgvlV83Ox+NLUmQTawovwlJ85+QMhk1CnVk406CQVj97LaWod6KVjl2Sfgw9Aktw== +"@babel/helper-module-transforms@^7.10.5", "@babel/helper-module-transforms@^7.12.1", "@babel/helper-module-transforms@^7.14.5", "@babel/helper-module-transforms@^7.15.4", "@babel/helper-module-transforms@^7.16.7": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.7.tgz#7665faeb721a01ca5327ddc6bba15a5cb34b6a41" + integrity sha512-gaqtLDxJEFCeQbYp9aLAefjhkKdjKcdh6DB7jniIGU3Pz52WAmP268zK0VgPz9hUNkMSYeH976K2/Y6yPadpng== dependencies: - "@babel/helper-module-imports" "^7.15.4" - "@babel/helper-replace-supers" "^7.15.4" - "@babel/helper-simple-access" "^7.15.4" - "@babel/helper-split-export-declaration" "^7.15.4" - "@babel/helper-validator-identifier" "^7.14.9" - "@babel/template" "^7.15.4" - "@babel/traverse" "^7.15.4" - "@babel/types" "^7.15.4" + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-module-imports" "^7.16.7" + "@babel/helper-simple-access" "^7.16.7" + "@babel/helper-split-export-declaration" "^7.16.7" + "@babel/helper-validator-identifier" "^7.16.7" + "@babel/template" "^7.16.7" + "@babel/traverse" "^7.16.7" + "@babel/types" "^7.16.7" "@babel/helper-optimise-call-expression@^7.15.4": version "7.15.4" @@ -482,12 +489,12 @@ "@babel/traverse" "^7.15.4" "@babel/types" "^7.15.4" -"@babel/helper-simple-access@^7.15.4": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.15.4.tgz#ac368905abf1de8e9781434b635d8f8674bcc13b" - integrity sha512-UzazrDoIVOZZcTeHHEPYrr1MvTR/K+wgLg6MY6e1CJyaRhbibftF6fR2KU2sFRtI/nERUZR9fBd6aKgBlIBaPg== +"@babel/helper-simple-access@^7.15.4", "@babel/helper-simple-access@^7.16.7": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz#d656654b9ea08dbb9659b69d61063ccd343ff0f7" + integrity sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g== dependencies: - "@babel/types" "^7.15.4" + "@babel/types" "^7.16.7" "@babel/helper-skip-transparent-expression-wrappers@^7.14.5", "@babel/helper-skip-transparent-expression-wrappers@^7.15.4": version "7.15.4" @@ -496,12 +503,12 @@ dependencies: "@babel/types" "^7.15.4" -"@babel/helper-split-export-declaration@^7.15.4": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.15.4.tgz#aecab92dcdbef6a10aa3b62ab204b085f776e257" - integrity sha512-HsFqhLDZ08DxCpBdEVtKmywj6PQbwnF6HHybur0MAnkAKnlS6uHkwnmRIkElB2Owpfb4xL4NwDmDLFubueDXsw== +"@babel/helper-split-export-declaration@^7.15.4", "@babel/helper-split-export-declaration@^7.16.7": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz#0b648c0c42da9d3920d85ad585f2778620b8726b" + integrity sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw== dependencies: - "@babel/types" "^7.15.4" + "@babel/types" "^7.16.7" "@babel/helper-transform-fixture-test-runner@^7.14.5": version "7.14.5" @@ -521,10 +528,10 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad" integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw== -"@babel/helper-validator-option@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz#6e72a1fff18d5dfcb878e1e62f1a021c4b72d5a3" - integrity sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow== +"@babel/helper-validator-option@^7.14.5", "@babel/helper-validator-option@^7.16.7": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz#b203ce62ce5fe153899b617c08957de860de4d23" + integrity sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ== "@babel/helper-wrap-function@^7.10.4", "@babel/helper-wrap-function@^7.15.4": version "7.15.4" @@ -536,14 +543,14 @@ "@babel/traverse" "^7.15.4" "@babel/types" "^7.15.4" -"@babel/helpers@^7.10.4", "@babel/helpers@^7.12.1", "@babel/helpers@^7.12.5", "@babel/helpers@^7.15.4": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.15.4.tgz#5f40f02050a3027121a3cf48d497c05c555eaf43" - integrity sha512-V45u6dqEJ3w2rlryYYXf6i9rQ5YMNu4FLS6ngs8ikblhu2VdR1AqAd6aJjBzmf2Qzh6KOLqKHxEN9+TFbAkAVQ== +"@babel/helpers@^7.10.4", "@babel/helpers@^7.12.1", "@babel/helpers@^7.12.5", "@babel/helpers@^7.16.7": + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.16.7.tgz#7e3504d708d50344112767c3542fc5e357fffefc" + integrity sha512-9ZDoqtfY7AuEOt3cxchfii6C7GDyyMBffktR5B2jvWv8u2+efwvpnVKXMWzNehqy68tKgAfSwfdw/lWpthS2bw== dependencies: - "@babel/template" "^7.15.4" - "@babel/traverse" "^7.15.4" - "@babel/types" "^7.15.4" + "@babel/template" "^7.16.7" + "@babel/traverse" "^7.16.7" + "@babel/types" "^7.16.7" "@babel/highlight@^7.10.4", "@babel/highlight@^7.16.7": version "7.16.7" @@ -571,10 +578,10 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.3.tgz#a305415ebe7a6c7023b40b5122a0662d928334cd" integrity sha512-kFsOS0IbsuhO5ojF8Hc8z/8vEIOkylVBrjiZUbLTE3XFe0Qi+uu6HjzQixkFaqr0ZPAMZcBVxEwmsnsLPZ2Xsw== -"@babel/parser@^7.1.0", "@babel/parser@^7.10.5", "@babel/parser@^7.12.3", "@babel/parser@^7.12.7", "@babel/parser@^7.13.16", "@babel/parser@^7.15.4", "@babel/parser@^7.15.5", "@babel/parser@^7.16.7", "@babel/parser@^7.3.3", "@babel/parser@^7.7.2": - version "7.16.8" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.16.8.tgz#61c243a3875f7d0b0962b0543a33ece6ff2f1f17" - integrity sha512-i7jDUfrVBWc+7OKcBzEe5n7fbv3i2fWtxKzzCvOjnzSxMfWMigAhtfJ7qzZNGFNMsCCd67+uz553dYKWXPvCKw== +"@babel/parser@^7.1.0", "@babel/parser@^7.10.5", "@babel/parser@^7.12.3", "@babel/parser@^7.12.7", "@babel/parser@^7.13.16", "@babel/parser@^7.14.7", "@babel/parser@^7.15.5", "@babel/parser@^7.16.10", "@babel/parser@^7.16.7", "@babel/parser@^7.3.3": + version "7.16.12" + resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.16.12.tgz#9474794f9a650cf5e2f892444227f98e28cdf8b6" + integrity sha512-VfaV15po8RiZssrkPweyvbGVSe4x2y+aciFCgn0n0/SJMR22cwofRV1mtnJQYcSB1wUTaA/X1LnA3es66MCO5A== "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.15.4": version "7.15.4" @@ -987,11 +994,11 @@ "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-typescript@^7.14.0", "@babel/plugin-syntax-typescript@^7.14.5", "@babel/plugin-syntax-typescript@^7.7.2": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.14.5.tgz#b82c6ce471b165b5ce420cf92914d6fb46225716" - integrity sha512-u6OXzDaIXjEstBRRoBCQ/uKQKlbuaeE5in0RvWdA4pN6AhqxTIwUsnHPU1CFZA/amYObMsuWhYfRl3Ch90HD0Q== + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.7.tgz#39c9b55ee153151990fb038651d58d3fd03f98f8" + integrity sha512-YhUIJHHGkqPgEcMYkPCKTyGUdoGKWtopIycQyjJH8OjvRgOYsXsaKehLVPScKJWAULPxMa4N1vCe6szREFlZ7A== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-transform-arrow-functions@^7.14.5": version "7.14.5" @@ -1456,9 +1463,9 @@ regenerator-runtime "^0.13.4" "@babel/runtime@^7.10.0", "@babel/runtime@^7.10.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.15.4", "@babel/runtime@^7.16.3", "@babel/runtime@^7.3.4", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": - version "7.16.3" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.3.tgz#b86f0db02a04187a3c17caa77de69840165d42d5" - integrity sha512-WBwekcqacdY2e9AF/Q7WLFUWmdJGJTkbjqTjoMDgXkVZ3ZRUvOPsLb5KdwISoQVsbP+DQzVZW4Zhci0DvpbNTQ== + version "7.16.7" + resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.16.7.tgz#03ff99f64106588c9c403c6ecb8c3bafbbdff1fa" + integrity sha512-9E9FJowqAsytyOY6LG+1KuueckRL+aQW+mKvXRXnuFGyRAyepJPmEo9vgMfXUA6O9u3IeEdv9MAkppFcaQwogQ== dependencies: regenerator-runtime "^0.13.4" @@ -1471,18 +1478,19 @@ "@babel/parser" "^7.16.7" "@babel/types" "^7.16.7" -"@babel/traverse@^7.1.0", "@babel/traverse@^7.1.6", "@babel/traverse@^7.10.5", "@babel/traverse@^7.12.1", "@babel/traverse@^7.12.9", "@babel/traverse@^7.13.0", "@babel/traverse@^7.15.4", "@babel/traverse@^7.7.2": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.15.4.tgz#ff8510367a144bfbff552d9e18e28f3e2889c22d" - integrity sha512-W6lQD8l4rUbQR/vYgSuCAE75ADyyQvOpFVsvPPdkhf6lATXAsQIG9YdtOcu8BB1dZ0LKu+Zo3c1wEcbKeuhdlA== +"@babel/traverse@^7.1.6", "@babel/traverse@^7.10.5", "@babel/traverse@^7.12.1", "@babel/traverse@^7.12.9", "@babel/traverse@^7.13.0", "@babel/traverse@^7.15.4", "@babel/traverse@^7.16.7", "@babel/traverse@^7.7.2": + version "7.16.10" + resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.16.10.tgz#448f940defbe95b5a8029975b051f75993e8239f" + integrity sha512-yzuaYXoRJBGMlBhsMJoUW7G1UmSb/eXr/JHYM/MsOJgavJibLwASijW7oXBdw3NQ6T0bW7Ty5P/VarOs9cHmqw== dependencies: - "@babel/code-frame" "^7.14.5" - "@babel/generator" "^7.15.4" - "@babel/helper-function-name" "^7.15.4" - "@babel/helper-hoist-variables" "^7.15.4" - "@babel/helper-split-export-declaration" "^7.15.4" - "@babel/parser" "^7.15.4" - "@babel/types" "^7.15.4" + "@babel/code-frame" "^7.16.7" + "@babel/generator" "^7.16.8" + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-function-name" "^7.16.7" + "@babel/helper-hoist-variables" "^7.16.7" + "@babel/helper-split-export-declaration" "^7.16.7" + "@babel/parser" "^7.16.10" + "@babel/types" "^7.16.8" debug "^4.1.0" globals "^11.1.0" @@ -1499,6 +1507,13 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== +"@contentful/rich-text-links@^14.1.2": + version "14.1.2" + resolved "https://registry.npmjs.org/@contentful/rich-text-links/-/rich-text-links-14.1.2.tgz#993cd086d55af11f5d31b76060c02a9866c93a01" + integrity sha512-oK+y/c42fOJOdRM6XDKNLqw7uwVHZUIRGKzk9fJLDaOt5tygDm0pvgJ9bkvadaBwbAioxlQ0hHS0i5JP+UHkvA== + dependencies: + "@contentful/rich-text-types" "^14.1.2" + "@contentful/rich-text-react-renderer@^14.1.3": version "14.1.3" resolved "https://registry.npmjs.org/@contentful/rich-text-react-renderer/-/rich-text-react-renderer-14.1.3.tgz#501136677742d0ad3f4b50fa2c12b17fc1d68cc8" @@ -1998,27 +2013,27 @@ chalk "^2.0.1" slash "^2.0.0" -"@jest/console@^27.4.2": - version "27.4.2" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-27.4.2.tgz#7a95612d38c007ddb528ee446fe5e5e785e685ce" - integrity sha512-xknHThRsPB/To1FUbi6pCe43y58qFC03zfb6R7fDb/FfC7k2R3i1l+izRBJf8DI46KhYGRaF14Eo9A3qbBoixg== +"@jest/console@^27.4.6": + version "27.4.6" + resolved "https://registry.npmjs.org/@jest/console/-/console-27.4.6.tgz#0742e6787f682b22bdad56f9db2a8a77f6a86107" + integrity sha512-jauXyacQD33n47A44KrlOVeiXHEXDqapSdfb9kTekOchH/Pd18kBIO1+xxJQRLuG+LUuljFCwTG92ra4NW7SpA== dependencies: "@jest/types" "^27.4.2" "@types/node" "*" chalk "^4.0.0" - jest-message-util "^27.4.2" + jest-message-util "^27.4.6" jest-util "^27.4.2" slash "^3.0.0" -"@jest/core@^27.4.4": - version "27.4.4" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-27.4.4.tgz#f2ba293235ca23fb48b4b923ccfe67c17e791a92" - integrity sha512-xBNPVqYAdAiAMXnb4ugx9Cdmr0S52lBsLbQMR/sGBRO0810VSPKiuSDtuup6qdkK1e9vxbv3KK3IAP1QFAp8mw== +"@jest/core@^27.4.7": + version "27.4.7" + resolved "https://registry.npmjs.org/@jest/core/-/core-27.4.7.tgz#84eabdf42a25f1fa138272ed229bcf0a1b5e6913" + integrity sha512-n181PurSJkVMS+kClIFSX/LLvw9ExSb+4IMtD6YnfxZVerw9ANYtW0bPrm0MJu2pfe9SY9FJ9FtQ+MdZkrZwjg== dependencies: - "@jest/console" "^27.4.2" - "@jest/reporters" "^27.4.4" - "@jest/test-result" "^27.4.2" - "@jest/transform" "^27.4.4" + "@jest/console" "^27.4.6" + "@jest/reporters" "^27.4.6" + "@jest/test-result" "^27.4.6" + "@jest/transform" "^27.4.6" "@jest/types" "^27.4.2" "@types/node" "*" ansi-escapes "^4.2.1" @@ -2027,63 +2042,63 @@ exit "^0.1.2" graceful-fs "^4.2.4" jest-changed-files "^27.4.2" - jest-config "^27.4.4" - jest-haste-map "^27.4.4" - jest-message-util "^27.4.2" + jest-config "^27.4.7" + jest-haste-map "^27.4.6" + jest-message-util "^27.4.6" jest-regex-util "^27.4.0" - jest-resolve "^27.4.4" - jest-resolve-dependencies "^27.4.4" - jest-runner "^27.4.4" - jest-runtime "^27.4.4" - jest-snapshot "^27.4.4" + jest-resolve "^27.4.6" + jest-resolve-dependencies "^27.4.6" + jest-runner "^27.4.6" + jest-runtime "^27.4.6" + jest-snapshot "^27.4.6" jest-util "^27.4.2" - jest-validate "^27.4.2" - jest-watcher "^27.4.2" + jest-validate "^27.4.6" + jest-watcher "^27.4.6" micromatch "^4.0.4" rimraf "^3.0.0" slash "^3.0.0" strip-ansi "^6.0.0" -"@jest/environment@^27.4.4": - version "27.4.4" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-27.4.4.tgz#66ebebc79673d84aad29d2bb70a8c51e6c29bb4d" - integrity sha512-q+niMx7cJgt/t/b6dzLOh4W8Ef/8VyKG7hxASK39jakijJzbFBGpptx3RXz13FFV7OishQ9lTbv+dQ5K3EhfDQ== +"@jest/environment@^27.4.6": + version "27.4.6" + resolved "https://registry.npmjs.org/@jest/environment/-/environment-27.4.6.tgz#1e92885d64f48c8454df35ed9779fbcf31c56d8b" + integrity sha512-E6t+RXPfATEEGVidr84WngLNWZ8ffCPky8RqqRK6u1Bn0LK92INe0MDttyPl/JOzaq92BmDzOeuqk09TvM22Sg== dependencies: - "@jest/fake-timers" "^27.4.2" + "@jest/fake-timers" "^27.4.6" "@jest/types" "^27.4.2" "@types/node" "*" - jest-mock "^27.4.2" + jest-mock "^27.4.6" -"@jest/fake-timers@^27.4.2": - version "27.4.2" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-27.4.2.tgz#d217f86c3ba2027bf29e0b731fd0cb761a72d093" - integrity sha512-f/Xpzn5YQk5adtqBgvw1V6bF8Nx3hY0OIRRpCvWcfPl0EAjdqWPdhH3t/3XpiWZqtjIEHDyMKP9ajpva1l4Zmg== +"@jest/fake-timers@^27.4.6": + version "27.4.6" + resolved "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.4.6.tgz#e026ae1671316dbd04a56945be2fa251204324e8" + integrity sha512-mfaethuYF8scV8ntPpiVGIHQgS0XIALbpY2jt2l7wb/bvq4Q5pDLk4EP4D7SAvYT1QrPOPVZAtbdGAOOyIgs7A== dependencies: "@jest/types" "^27.4.2" "@sinonjs/fake-timers" "^8.0.1" "@types/node" "*" - jest-message-util "^27.4.2" - jest-mock "^27.4.2" + jest-message-util "^27.4.6" + jest-mock "^27.4.6" jest-util "^27.4.2" -"@jest/globals@^27.4.4": - version "27.4.4" - resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-27.4.4.tgz#fe501a80c23ea2dab585c42be2a519bb5e38530d" - integrity sha512-bqpqQhW30BOreXM8bA8t8JbOQzsq/WnPTnBl+It3UxAD9J8yxEAaBEylHx1dtBapAr/UBk8GidXbzmqnee8tYQ== +"@jest/globals@^27.4.6": + version "27.4.6" + resolved "https://registry.npmjs.org/@jest/globals/-/globals-27.4.6.tgz#3f09bed64b0fd7f5f996920258bd4be8f52f060a" + integrity sha512-kAiwMGZ7UxrgPzu8Yv9uvWmXXxsy0GciNejlHvfPIfWkSxChzv6bgTS3YqBkGuHcis+ouMFI2696n2t+XYIeFw== dependencies: - "@jest/environment" "^27.4.4" + "@jest/environment" "^27.4.6" "@jest/types" "^27.4.2" - expect "^27.4.2" + expect "^27.4.6" -"@jest/reporters@^27.4.4": - version "27.4.4" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-27.4.4.tgz#9e809829f602cd6e68bd058d1ea528f4b7482365" - integrity sha512-ssyJSw9B9Awb1QaxDhIPSs4de1b7SE2kv7tqFehQL13xpn5HUkMYZK/ufTOXiCAnXFOZS+XDl1GaQ/LmJAzI1A== +"@jest/reporters@^27.4.6": + version "27.4.6" + resolved "https://registry.npmjs.org/@jest/reporters/-/reporters-27.4.6.tgz#b53dec3a93baf9b00826abf95b932de919d6d8dd" + integrity sha512-+Zo9gV81R14+PSq4wzee4GC2mhAN9i9a7qgJWL90Gpx7fHYkWpTBvwWNZUXvJByYR9tAVBdc8VxDWqfJyIUrIQ== dependencies: "@bcoe/v8-coverage" "^0.2.3" - "@jest/console" "^27.4.2" - "@jest/test-result" "^27.4.2" - "@jest/transform" "^27.4.4" + "@jest/console" "^27.4.6" + "@jest/test-result" "^27.4.6" + "@jest/transform" "^27.4.6" "@jest/types" "^27.4.2" "@types/node" "*" chalk "^4.0.0" @@ -2092,14 +2107,14 @@ glob "^7.1.2" graceful-fs "^4.2.4" istanbul-lib-coverage "^3.0.0" - istanbul-lib-instrument "^4.0.3" + istanbul-lib-instrument "^5.1.0" istanbul-lib-report "^3.0.0" istanbul-lib-source-maps "^4.0.0" - istanbul-reports "^3.0.2" - jest-haste-map "^27.4.4" - jest-resolve "^27.4.4" + istanbul-reports "^3.1.3" + jest-haste-map "^27.4.6" + jest-resolve "^27.4.6" jest-util "^27.4.2" - jest-worker "^27.4.4" + jest-worker "^27.4.6" slash "^3.0.0" source-map "^0.6.0" string-length "^4.0.1" @@ -2117,7 +2132,7 @@ "@jest/source-map@^27.4.0": version "27.4.0" - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-27.4.0.tgz#2f0385d0d884fb3e2554e8f71f8fa957af9a74b6" + resolved "https://registry.npmjs.org/@jest/source-map/-/source-map-27.4.0.tgz#2f0385d0d884fb3e2554e8f71f8fa957af9a74b6" integrity sha512-Ntjx9jzP26Bvhbm93z/AKcPRj/9wrkI88/gK60glXDx1q+IeI0rf7Lw2c89Ch6ofonB0On/iRDreQuQ6te9pgQ== dependencies: callsites "^3.0.0" @@ -2133,43 +2148,43 @@ "@jest/types" "^24.9.0" "@types/istanbul-lib-coverage" "^2.0.0" -"@jest/test-result@^27.4.2": - version "27.4.2" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-27.4.2.tgz#05fd4a5466ec502f3eae0b39dff2b93ea4d5d9ec" - integrity sha512-kr+bCrra9jfTgxHXHa2UwoQjxvQk3Am6QbpAiJ5x/50LW8llOYrxILkqY0lZRW/hu8FXesnudbql263+EW9iNA== +"@jest/test-result@^27.4.6": + version "27.4.6" + resolved "https://registry.npmjs.org/@jest/test-result/-/test-result-27.4.6.tgz#b3df94c3d899c040f602cea296979844f61bdf69" + integrity sha512-fi9IGj3fkOrlMmhQqa/t9xum8jaJOOAi/lZlm6JXSc55rJMXKHxNDN1oCP39B0/DhNOa2OMupF9BcKZnNtXMOQ== dependencies: - "@jest/console" "^27.4.2" + "@jest/console" "^27.4.6" "@jest/types" "^27.4.2" "@types/istanbul-lib-coverage" "^2.0.0" collect-v8-coverage "^1.0.0" -"@jest/test-sequencer@^27.4.4": - version "27.4.4" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-27.4.4.tgz#60be14369b2702e42d6042e71b8ab3fc69f5ce68" - integrity sha512-mCh+d4JTGTtX7vr13d7q2GHJy33nAobEwtEJ8X3u7R8+0ImVO2eAsQzsLfX8lyvdYHBxYABhqbYuaUNo42/pQw== +"@jest/test-sequencer@^27.4.6": + version "27.4.6" + resolved "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.4.6.tgz#447339b8a3d7b5436f50934df30854e442a9d904" + integrity sha512-3GL+nsf6E1PsyNsJuvPyIz+DwFuCtBdtvPpm/LMXVkBJbdFvQYCDpccYT56qq5BGniXWlE81n2qk1sdXfZebnw== dependencies: - "@jest/test-result" "^27.4.2" + "@jest/test-result" "^27.4.6" graceful-fs "^4.2.4" - jest-haste-map "^27.4.4" - jest-runtime "^27.4.4" + jest-haste-map "^27.4.6" + jest-runtime "^27.4.6" -"@jest/transform@^27.4.4": - version "27.4.4" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-27.4.4.tgz#347e39402730879ba88c6ea6982db0d88640aa78" - integrity sha512-7U/nDSrGsGzL7+X8ScNFV71w8u8knJQWSa9C2xsrrKLMOgb+rWuCG4VAyWke/53BU96GnT+Ka81xCAHA5gk6zA== +"@jest/transform@^27.4.6": + version "27.4.6" + resolved "https://registry.npmjs.org/@jest/transform/-/transform-27.4.6.tgz#153621940b1ed500305eacdb31105d415dc30231" + integrity sha512-9MsufmJC8t5JTpWEQJ0OcOOAXaH5ioaIX6uHVBLBMoCZPfKKQF+EqP8kACAvCZ0Y1h2Zr3uOccg8re+Dr5jxyw== dependencies: "@babel/core" "^7.1.0" "@jest/types" "^27.4.2" - babel-plugin-istanbul "^6.0.0" + babel-plugin-istanbul "^6.1.1" chalk "^4.0.0" convert-source-map "^1.4.0" fast-json-stable-stringify "^2.0.0" graceful-fs "^4.2.4" - jest-haste-map "^27.4.4" + jest-haste-map "^27.4.6" jest-regex-util "^27.4.0" jest-util "^27.4.2" micromatch "^4.0.4" - pirates "^4.0.1" + pirates "^4.0.4" slash "^3.0.0" source-map "^0.6.1" write-file-atomic "^3.0.0" @@ -2196,7 +2211,7 @@ "@jest/types@^27.4.2": version "27.4.2" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-27.4.2.tgz#96536ebd34da6392c2b7c7737d693885b5dd44a5" + resolved "https://registry.npmjs.org/@jest/types/-/types-27.4.2.tgz#96536ebd34da6392c2b7c7737d693885b5dd44a5" integrity sha512-j35yw0PMTPpZsUoOBiuHzr1zTYoad1cVIE0ajEjcrJONxxrko/IRGKkXx3os0Nsi4Hu3+5VmDbVfq5WhG/pWAg== dependencies: "@types/istanbul-lib-coverage" "^2.0.0" @@ -3249,7 +3264,7 @@ "@mswjs/interceptors@^0.12.6", "@mswjs/interceptors@^0.12.7": version "0.12.7" - resolved "https://registry.yarnpkg.com/@mswjs/interceptors/-/interceptors-0.12.7.tgz#0d1cd4cd31a0f663e0455993951201faa09d0909" + resolved "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.12.7.tgz#0d1cd4cd31a0f663e0455993951201faa09d0909" integrity sha512-eGjZ3JRAt0Fzi5FgXiV/P3bJGj0NqsN7vBS0J0FO2AQRQ0jCKQS4lEFm4wvlSgKQNfeuc/Vz6d81VtU3Gkx/zg== dependencies: "@open-draft/until" "^1.0.3" @@ -3595,14 +3610,14 @@ "@sinonjs/fake-timers@^8.0.1": version "8.1.0" - resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz#3fdc2b6cb58935b21bfb8d1625eb1300484316e7" + resolved "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz#3fdc2b6cb58935b21bfb8d1625eb1300484316e7" integrity sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg== dependencies: "@sinonjs/commons" "^1.7.0" "@soda/friendly-errors-webpack-plugin@1.8.1": version "1.8.1" - resolved "https://registry.yarnpkg.com/@soda/friendly-errors-webpack-plugin/-/friendly-errors-webpack-plugin-1.8.1.tgz#4d4fbb1108993aaa362116247c3d18188a2c6c85" + resolved "https://registry.npmjs.org/@soda/friendly-errors-webpack-plugin/-/friendly-errors-webpack-plugin-1.8.1.tgz#4d4fbb1108993aaa362116247c3d18188a2c6c85" integrity sha512-h2ooWqP8XuFqTXT+NyAFbrArzfQA7R6HTezADrvD9Re8fxMLTPPniLdqVTdDaO0eIoLaAwKT+d6w+5GeTk7Vbg== dependencies: chalk "^3.0.0" @@ -3649,7 +3664,7 @@ "@testing-library/dom@^8.11.1": version "8.11.1" - resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-8.11.1.tgz#03fa2684aa09ade589b460db46b4c7be9fc69753" + resolved "https://registry.npmjs.org/@testing-library/dom/-/dom-8.11.1.tgz#03fa2684aa09ade589b460db46b4c7be9fc69753" integrity sha512-3KQDyx9r0RKYailW2MiYrSSKEfH0GTkI51UGEvJenvcoDoeRYs0PZpi2SXqtnMClQvCqdtTTpOfFETDTVADpAg== dependencies: "@babel/code-frame" "^7.10.4" @@ -3663,7 +3678,7 @@ "@testing-library/jest-dom@^5.16.1": version "5.16.1" - resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-5.16.1.tgz#3db7df5ae97596264a7da9696fe14695ba02e51f" + resolved "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.1.tgz#3db7df5ae97596264a7da9696fe14695ba02e51f" integrity sha512-ajUJdfDIuTCadB79ukO+0l8O+QwN0LiSxDaYUTI4LndbbUsGi6rWU1SCexXzBA2NSjlVB9/vbkasQIL3tmPBjw== dependencies: "@babel/runtime" "^7.9.2" @@ -3739,9 +3754,9 @@ integrity sha512-imO+jT/yjOKOAS5GQZ8SDtwiIloAGGr6OaZDKB0V5JVaSfGZLat5K5/ZRtyKW6R60XHV3RHYPTFfhYb+wDKyKg== "@types/babel__core@^7.0.0", "@types/babel__core@^7.1.12", "@types/babel__core@^7.1.14", "@types/babel__core@^7.1.15": - version "7.1.16" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.16.tgz#bc12c74b7d65e82d29876b5d0baf5c625ac58702" - integrity sha512-EAEHtisTMM+KaKwfWdC3oyllIqswlznXCIVCt7/oRNrh+DhgT4UEBNC/jlADNjvw7UnfbcdkGQcPVZ1xYiLcrQ== + version "7.1.18" + resolved "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.18.tgz#1a29abcc411a9c05e2094c98f9a1b7da6cdf49f8" + integrity sha512-S7unDjm/C7z2A2R9NzfKCK1I+BAALDtxEmsJBwlB3EzNfb929ykjL++1CK9LO++EIp2fQrC8O+BwjKvz6UeDyQ== dependencies: "@babel/parser" "^7.1.0" "@babel/types" "^7.0.0" @@ -3765,9 +3780,9 @@ "@babel/types" "^7.0.0" "@types/babel__traverse@*", "@types/babel__traverse@^7.0.4", "@types/babel__traverse@^7.0.6", "@types/babel__traverse@^7.11.1": - version "7.14.2" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.14.2.tgz#ffcd470bbb3f8bf30481678fb5502278ca833a43" - integrity sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA== + version "7.11.1" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.11.1.tgz#654f6c4f67568e24c23b367e947098c6206fa639" + integrity sha512-Vs0hm0vPahPMYi9tDjtP66llufgO3ST16WXaSTtDGEl9cewAl3AibmxWw6TINOqHPT9z0uABKAYjT9jNSg4npw== dependencies: "@babel/types" "^7.3.0" @@ -3872,7 +3887,7 @@ "@types/eslint@*", "@types/eslint@^8.2.1": version "8.2.1" - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.2.1.tgz#13f3d69bac93c2ae008019c28783868d0a1d6605" + resolved "https://registry.npmjs.org/@types/eslint/-/eslint-8.2.1.tgz#13f3d69bac93c2ae008019c28783868d0a1d6605" integrity sha512-UP9rzNn/XyGwb5RQ2fok+DzcIRIYwc16qTXse5+Smsy8MOIccCChT15KAwnsgQx4PzJkaMq4myFyZ4CL5TjhIQ== dependencies: "@types/estree" "*" @@ -3880,7 +3895,7 @@ "@types/eslint@^7.28.2": version "7.29.0" - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-7.29.0.tgz#e56ddc8e542815272720bb0b4ccc2aff9c3e1c78" + resolved "https://registry.npmjs.org/@types/eslint/-/eslint-7.29.0.tgz#e56ddc8e542815272720bb0b4ccc2aff9c3e1c78" integrity sha512-VNcvioYDH8/FxaeTKkM4/TiTwt6pBV9E3OfGmvaw8tPl0rrHCJ4Ll15HRT+pMiFAf/MLQvAzC+6RzUMEL9Ceng== dependencies: "@types/estree" "*" @@ -3999,7 +4014,7 @@ "@types/inquirer@^8.1.3": version "8.1.3" - resolved "https://registry.yarnpkg.com/@types/inquirer/-/inquirer-8.1.3.tgz#dfda4c97cdbe304e4dceb378a80f79448ea5c8fe" + resolved "https://registry.npmjs.org/@types/inquirer/-/inquirer-8.1.3.tgz#dfda4c97cdbe304e4dceb378a80f79448ea5c8fe" integrity sha512-AayK4ZL5ssPzR1OtnOLGAwpT0Dda3Xi/h1G0l1oJDNrowp7T1423q4Zb8/emr7tzRlCy4ssEri0LWVexAqHyKQ== dependencies: "@types/through" "*" @@ -4040,9 +4055,9 @@ prom-client "~11.3.0 || ^12.0.0 || ^13.0.0" "@types/jest@*", "@types/jest@^27.0.2": - version "27.0.2" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-27.0.2.tgz#ac383c4d4aaddd29bbf2b916d8d105c304a5fcd7" - integrity sha512-4dRxkS/AFX0c5XW6IPMNOydLn2tEhNhJV7DnYK+0bjoJZ+QTmfucBlihX7aoEsh/ocYtkLC73UbnBXBXIxsULA== + version "27.4.0" + resolved "https://registry.npmjs.org/@types/jest/-/jest-27.4.0.tgz#037ab8b872067cae842a320841693080f9cb84ed" + integrity sha512-gHl8XuC1RZ8H2j5sHv/JqsaxXkDDM9iDOgu0Wp8sjs4u/snb2PVehyWXJPr+ORA0RPpgw231mnutWI1+0hgjIQ== dependencies: jest-diff "^27.0.0" pretty-format "^27.0.0" @@ -4059,7 +4074,7 @@ "@types/json-schema@*", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.7", "@types/json-schema@^7.0.8": version "7.0.9" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d" + resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d" integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ== "@types/json5@^0.0.29": @@ -4133,9 +4148,9 @@ integrity sha512-sRVq8d+ApGslmkE9e3i+D3gFGk7aZHAT+G4cIpIEdLJYPsWiSPwcAnJEjddLQQDqV3Ra2jOclX/Sv6YrvGYiWA== "@types/node@^14.10.2", "@types/node@^14.17.34": - version "14.17.34" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.17.34.tgz#fe4b38b3f07617c0fa31ae923fca9249641038f0" - integrity sha512-USUftMYpmuMzeWobskoPfzDi+vkpe0dvcOBRNOscFrGxVp4jomnRxWuVohgqBow2xyIPC0S3gjxV/5079jhmDg== + version "14.18.5" + resolved "https://registry.npmjs.org/@types/node/-/node-14.18.5.tgz#0dd636fe7b2c6055cbed0d4ca3b7fb540f130a96" + integrity sha512-LMy+vDDcQR48EZdEx5wRX1q/sEl6NdGuHXPnfeL8ixkwCOSZ2qnIyIZmcCbdX0MeRqHhAcHmX+haCbrS8Run+A== "@types/node@^15.0.1": version "15.0.1" @@ -4167,9 +4182,9 @@ integrity sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw== "@types/prettier@^2.1.5": - version "2.3.2" - resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.3.2.tgz#fc8c2825e4ed2142473b4a81064e6e081463d1b3" - integrity sha512-eI5Yrz3Qv4KPUa/nSIAi0h+qX0XyewOliug5F2QAtuRg6Kjg6jfmxe1GIwoIRhZspD1A0RP8ANrPwvEXXtRFog== + version "2.4.2" + resolved "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.2.tgz#4c62fae93eb479660c3bd93f9d24d561597a8281" + integrity sha512-ekoj4qOQYp7CvjX8ZDBgN86w3MqQhLE1hczEJbEIjgFEumDy+na/4AJAbLXfgEWFNB2pKadM5rPFtuSGMWK7xA== "@types/prop-types@*", "@types/prop-types@^15.7.3": version "15.7.3" @@ -4279,7 +4294,7 @@ "@types/sharp@^0.29.5": version "0.29.5" - resolved "https://registry.yarnpkg.com/@types/sharp/-/sharp-0.29.5.tgz#9c7032d30d138ad16dde6326beaff2af757b91b3" + resolved "https://registry.npmjs.org/@types/sharp/-/sharp-0.29.5.tgz#9c7032d30d138ad16dde6326beaff2af757b91b3" integrity sha512-3TC+S3H5RwnJmLYMHrcdfNjz/CaApKmujjY9b6PU/pE6n0qfooi99YqXGWoW8frU9EWYj/XTI35Pzxa+ThAZ5Q== dependencies: "@types/node" "*" @@ -4304,9 +4319,9 @@ resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e" "@types/stack-utils@^2.0.0": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" - integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== + version "2.0.0" + resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.0.tgz#7036640b4e21cc2f259ae826ce843d277dad8cff" + integrity sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw== "@types/string-similarity@^4.0.0": version "4.0.0" @@ -4455,7 +4470,7 @@ "@typescript-eslint/eslint-plugin@^4.33.0": version "4.33.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz#c24dc7c8069c7706bc40d99f6fa87edcb2005276" + resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz#c24dc7c8069c7706bc40d99f6fa87edcb2005276" integrity sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg== dependencies: "@typescript-eslint/experimental-utils" "4.33.0" @@ -4469,7 +4484,7 @@ "@typescript-eslint/experimental-utils@4.33.0": version "4.33.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz#6f2a786a4209fa2222989e9380b5331b2810f7fd" + resolved "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz#6f2a786a4209fa2222989e9380b5331b2810f7fd" integrity sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q== dependencies: "@types/json-schema" "^7.0.7" @@ -4481,7 +4496,7 @@ "@typescript-eslint/parser@^4.33.0": version "4.33.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.33.0.tgz#dfe797570d9694e560528d18eecad86c8c744899" + resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.33.0.tgz#dfe797570d9694e560528d18eecad86c8c744899" integrity sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA== dependencies: "@typescript-eslint/scope-manager" "4.33.0" @@ -4491,7 +4506,7 @@ "@typescript-eslint/scope-manager@4.33.0": version "4.33.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz#d38e49280d983e8772e29121cf8c6e9221f280a3" + resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz#d38e49280d983e8772e29121cf8c6e9221f280a3" integrity sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ== dependencies: "@typescript-eslint/types" "4.33.0" @@ -4499,12 +4514,12 @@ "@typescript-eslint/types@4.33.0": version "4.33.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.33.0.tgz#a1e59036a3b53ae8430ceebf2a919dc7f9af6d72" + resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz#a1e59036a3b53ae8430ceebf2a919dc7f9af6d72" integrity sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ== "@typescript-eslint/typescript-estree@4.33.0": version "4.33.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz#0dfb51c2908f68c5c08d82aefeaf166a17c24609" + resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz#0dfb51c2908f68c5c08d82aefeaf166a17c24609" integrity sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA== dependencies: "@typescript-eslint/types" "4.33.0" @@ -4517,7 +4532,7 @@ "@typescript-eslint/visitor-keys@4.33.0": version "4.33.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz#2a22f77a41604289b7a186586e9ec48ca92ef1dd" + resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz#2a22f77a41604289b7a186586e9ec48ca92ef1dd" integrity sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg== dependencies: "@typescript-eslint/types" "4.33.0" @@ -4831,7 +4846,7 @@ accepts@^1.3.7, accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: accessible-nprogress@^2.1.2: version "2.1.2" - resolved "https://registry.yarnpkg.com/accessible-nprogress/-/accessible-nprogress-2.1.2.tgz#8e65ebf4936db1752638e1cd2e8730f9bef311e9" + resolved "https://registry.npmjs.org/accessible-nprogress/-/accessible-nprogress-2.1.2.tgz#8e65ebf4936db1752638e1cd2e8730f9bef311e9" integrity sha512-reIwMbbt+ZGOmQLWPXGcPf5X1F4fzsZAekY9alCxpekxizRhQMAd/QInaA8k7WtwTcGMzD9hnYswGLcaJDRY/A== acorn-globals@^4.3.2: @@ -4973,7 +4988,7 @@ agentkeepalive@^3.4.1: agentkeepalive@^4.2.0: version "4.2.0" - resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.2.0.tgz#616ce94ccb41d1a39a45d203d8076fe98713062d" + resolved "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.2.0.tgz#616ce94ccb41d1a39a45d203d8076fe98713062d" integrity sha512-0PhAp58jZNw13UJv7NVdTGb0ZcghHUb3DrZ046JiiJY/BOaTTpbwdHq2VObPCBV8M2GPh7sgrJ3AQ8Ey468LJw== dependencies: debug "^4.1.0" @@ -5098,7 +5113,7 @@ ansi-regex@^4.0.0, ansi-regex@^4.1.0: ansi-regex@^5.0.0, ansi-regex@^5.0.1: version "5.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== ansi-styles@^2.2.1: @@ -5363,7 +5378,7 @@ array.prototype.flat@^1.2.5: array.prototype.flatmap@^1.2.5: version "1.2.5" - resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.2.5.tgz#908dc82d8a406930fdf38598d51e7411d18d4446" + resolved "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.5.tgz#908dc82d8a406930fdf38598d51e7411d18d4446" integrity sha512-08u6rVyi1Lj7oqWbS9nUxliETrtIROT4XGTA4D/LWGten6E3ocm7cy9SIrmNHOL5XVbVuckUp3X6Xyg8/zpvHA== dependencies: call-bind "^1.0.0" @@ -5580,7 +5595,7 @@ autolinker@~0.28.0: autoprefixer@^10.1.0, autoprefixer@^10.4.0, autoprefixer@^10.4.1: version "10.4.1" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.1.tgz#1735959d6462420569bc42408016acbc56861c12" + resolved "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.1.tgz#1735959d6462420569bc42408016acbc56861c12" integrity sha512-B3ZEG7wtzXDRCEFsan7HmR2AeNsxdJB0+sEC0Hc5/c2NbhJqPwuZm+tn233GBVw82L+6CtD6IPSfVruwKjfV3A== dependencies: browserslist "^4.19.1" @@ -5600,7 +5615,7 @@ aws4@^1.8.0: axe-core@^4.3.5: version "4.3.5" - resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.3.5.tgz#78d6911ba317a8262bfee292aeafcc1e04b49cc5" + resolved "https://registry.npmjs.org/axe-core/-/axe-core-4.3.5.tgz#78d6911ba317a8262bfee292aeafcc1e04b49cc5" integrity sha512-WKTW1+xAzhMS5dJsxWkliixlO/PqC4VhmO9T4juNYcaTg9jzWiJsou6m5pxWYGfigWbwzJWeFY6z47a+4neRXA== axios-rate-limit@^1.3.0: @@ -5635,15 +5650,15 @@ babel-extract-comments@^1.0.0: dependencies: babylon "^6.18.0" -babel-jest@^27.2.1, babel-jest@^27.4.4: - version "27.4.4" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-27.4.4.tgz#a012441f8a155df909839543a09510ab3477aa11" - integrity sha512-+6RVutZxOQgJkt4svgTHPFtOQlVe9dUg3wrimIAM38pY6hL/nsL8glfFSUjD9jNVjaVjzkCzj6loFFecrjr9Qw== +babel-jest@^27.2.1, babel-jest@^27.4.6: + version "27.4.6" + resolved "https://registry.npmjs.org/babel-jest/-/babel-jest-27.4.6.tgz#4d024e69e241cdf4f396e453a07100f44f7ce314" + integrity sha512-qZL0JT0HS1L+lOuH+xC2DVASR3nunZi/ozGhpgauJHgmI7f8rudxf6hUjEHympdQ/J64CdKmPkgfJ+A3U6QCrg== dependencies: - "@jest/transform" "^27.4.4" + "@jest/transform" "^27.4.6" "@jest/types" "^27.4.2" "@types/babel__core" "^7.1.14" - babel-plugin-istanbul "^6.0.0" + babel-plugin-istanbul "^6.1.1" babel-preset-jest "^27.4.0" chalk "^4.0.0" graceful-fs "^4.2.4" @@ -5712,20 +5727,20 @@ babel-plugin-import-globals@^2.0.0: dependencies: "@babel/helper-module-imports" "^7.0.0" -babel-plugin-istanbul@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz#e159ccdc9af95e0b570c75b4573b7c34d671d765" - integrity sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ== +babel-plugin-istanbul@^6.1.1: + version "6.1.1" + resolved "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" + integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@istanbuljs/load-nyc-config" "^1.0.0" "@istanbuljs/schema" "^0.1.2" - istanbul-lib-instrument "^4.0.0" + istanbul-lib-instrument "^5.0.4" test-exclude "^6.0.0" babel-plugin-jest-hoist@^27.4.0: version "27.4.0" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.4.0.tgz#d7831fc0f93573788d80dee7e682482da4c730d6" + resolved "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.4.0.tgz#d7831fc0f93573788d80dee7e682482da4c730d6" integrity sha512-Jcu7qS4OX5kTWBc45Hz7BMmgXuJqRnhatqpUhnzGC3OBYpOmf2tv6jFNwZpwM7wU7MUuv2r9IPS/ZlYOuburVw== dependencies: "@babel/template" "^7.3.3" @@ -5881,7 +5896,7 @@ babel-preset-current-node-syntax@^1.0.0: babel-preset-jest@^27.4.0: version "27.4.0" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-27.4.0.tgz#70d0e676a282ccb200fbabd7f415db5fdf393bca" + resolved "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.4.0.tgz#70d0e676a282ccb200fbabd7f415db5fdf393bca" integrity sha512-NK4jGYpnBvNxcGo7/ZpZJr51jCGT+3bwwpVIDY2oNfTxJJldRtB4VAcYdgp1loDE50ODuTu+yBjpMAswv5tlpg== dependencies: babel-plugin-jest-hoist "^27.4.0" @@ -6051,7 +6066,7 @@ body-parser@1.19.0: body-parser@^1.19.0, body-parser@^1.19.1: version "1.19.1" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.1.tgz#1499abbaa9274af3ecc9f6f10396c995943e31d4" + resolved "https://registry.npmjs.org/body-parser/-/body-parser-1.19.1.tgz#1499abbaa9274af3ecc9f6f10396c995943e31d4" integrity sha512-8ljfQi5eBk8EJfECMrgqNGWPEY5jWP+1IzkzkGdFFEwFQZZyaZ21UqdaHktgiMlH0xLHqIFtE/u2OYE5dOtViA== dependencies: bytes "3.1.1" @@ -6200,7 +6215,7 @@ browserslist@4.14.2: browserslist@^4.0.0, browserslist@^4.13.0, browserslist@^4.14.5, browserslist@^4.16.0, browserslist@^4.16.3, browserslist@^4.16.6, browserslist@^4.17.5, browserslist@^4.19.1: version "4.19.1" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.19.1.tgz#4ac0435b35ab655896c31d53018b6dd5e9e4c9a3" + resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.19.1.tgz#4ac0435b35ab655896c31d53018b6dd5e9e4c9a3" integrity sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A== dependencies: caniuse-lite "^1.0.30001286" @@ -6326,7 +6341,7 @@ bytes@3.1.0: bytes@3.1.1: version "3.1.1" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.1.tgz#3f018291cb4cbad9accb6e6970bca9c8889e879a" + resolved "https://registry.npmjs.org/bytes/-/bytes-3.1.1.tgz#3f018291cb4cbad9accb6e6970bca9c8889e879a" integrity sha512-dWe4nWO/ruEOY7HkUJ5gFt1DCFV9zPRoJr8pV0/ASQermOZjtq8jMjOprC0Kd10GLN+l7xaUPvxzJFWtxGu8Fg== c8@^7.6.0: @@ -6400,7 +6415,7 @@ cache-manager@^2.11.1: cache-manager@^3.6.0: version "3.6.0" - resolved "https://registry.yarnpkg.com/cache-manager/-/cache-manager-3.6.0.tgz#696392402bb80447fbab2c9af7a939ce3cd01809" + resolved "https://registry.npmjs.org/cache-manager/-/cache-manager-3.6.0.tgz#696392402bb80447fbab2c9af7a939ce3cd01809" integrity sha512-D4GJZhyYgprYM30ZEPOn9kkdwdPUumX3ujbNbl7FYjcRViRvAgY53k6pO/82wNsm7c4aHVgXfR12/3huA47qnA== dependencies: async "3.2.0" @@ -6427,7 +6442,7 @@ cacheable-request@^6.0.0: cacheable-request@^7.0.2: version "7.0.2" - resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.2.tgz#ea0d0b889364a25854757301ca12b2da77f91d27" + resolved "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz#ea0d0b889364a25854757301ca12b2da77f91d27" integrity sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew== dependencies: clone-response "^1.0.2" @@ -6560,9 +6575,9 @@ caniuse-api@^3.0.0: lodash.uniq "^4.5.0" caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001125, caniuse-lite@^1.0.30001286, caniuse-lite@^1.0.30001294: - version "1.0.30001294" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001294.tgz#4849f27b101fd59ddee3751598c663801032533d" - integrity sha512-LiMlrs1nSKZ8qkNhpUf5KD0Al1KCBE3zaT7OLOwEkagXMEDij98SiOovn9wxVGQpklk9vVC/pUSqgYmkmKOS8g== + version "1.0.30001296" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001296.tgz#d99f0f3bee66544800b93d261c4be55a35f1cec8" + integrity sha512-WfrtPEoNSoeATDlf4y3QvkwiELl9GyPLISV5GejTbbQRtQx4LhsXmc9IQ6XCL2d7UxCyEzToEZNMeqR79OUw8Q== capitalize@^2.0.3: version "2.0.3" @@ -6605,7 +6620,7 @@ chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.0, chalk@^2.3.1, chalk@^2.4. chalk@4.1.1: version "4.1.1" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.1.tgz#c80b3fab28bf6371e6863325eee67e618b77e6ad" + resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz#c80b3fab28bf6371e6863325eee67e618b77e6ad" integrity sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg== dependencies: ansi-styles "^4.1.0" @@ -6783,12 +6798,12 @@ ci-info@^1.5.0: ci-info@^3.2.0: version "3.3.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.3.0.tgz#b4ed1fb6818dea4803a55c623041f9165d2066b2" + resolved "https://registry.npmjs.org/ci-info/-/ci-info-3.3.0.tgz#b4ed1fb6818dea4803a55c623041f9165d2066b2" integrity sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw== cjs-module-lexer@^1.0.0: version "1.2.2" - resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz#9f84ba3244a512f3a54e5277e8eef4c489864e40" + resolved "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz#9f84ba3244a512f3a54e5277e8eef4c489864e40" integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA== clap@^1.0.9: @@ -7166,7 +7181,7 @@ common-path-prefix@^1.0.0: common-tags@^1.8.0, common-tags@^1.8.2: version "1.8.2" - resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.2.tgz#94ebb3c076d26032745fd54face7f688ef5ac9c6" + resolved "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz#94ebb3c076d26032745fd54face7f688ef5ac9c6" integrity sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA== commondir@^1.0.1: @@ -7328,9 +7343,9 @@ contentful-resolve-response@^1.3.0: fast-copy "^2.1.0" contentful-sdk-core@^6.8.5: - version "6.10.3" - resolved "https://registry.yarnpkg.com/contentful-sdk-core/-/contentful-sdk-core-6.10.3.tgz#983fd69257c239881c43cb83e3ce9f501acfbe4a" - integrity sha512-IUBkAU1sJuVaEa2Nv1NKK5ImqpBZ5Q3EmaCFmMZx/UHKa+i98nDCSTUBOL1aJnpZ/s3AaSramsh73VQ4aK2kyA== + version "6.10.4" + resolved "https://registry.npmjs.org/contentful-sdk-core/-/contentful-sdk-core-6.10.4.tgz#3a077bd1017e107224101551d44834e77e62175e" + integrity sha512-vnivU13pKqFzs/eEugqOaDkKce6ZljBkpp6l25MsG8LA1HPCQNBnIkqP5VUbwk/ub7tkHteV9HtoTnmpdvB+Zg== dependencies: fast-copy "^2.1.0" lodash.isplainobject "^4.0.6" @@ -7340,7 +7355,7 @@ contentful-sdk-core@^6.8.5: contentful@^8.5.8: version "8.5.8" - resolved "https://registry.yarnpkg.com/contentful/-/contentful-8.5.8.tgz#ad2f3549d1795310e104a6c33325352524f7bd77" + resolved "https://registry.npmjs.org/contentful/-/contentful-8.5.8.tgz#ad2f3549d1795310e104a6c33325352524f7bd77" integrity sha512-6YyE95uDJYTyGKQYtqYrMzdDZe3sLkrC0UEnpXuIOeciGACRQP9ouTjRJnLMa5ONUPt0+UJh7JH3epNouPZWIw== dependencies: axios "^0.21.1" @@ -7910,7 +7925,7 @@ css-list-helpers@^2.0.0: css-loader@^5.2.7: version "5.2.7" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-5.2.7.tgz#9b9f111edf6fb2be5dc62525644cbc9c232064ae" + resolved "https://registry.npmjs.org/css-loader/-/css-loader-5.2.7.tgz#9b9f111edf6fb2be5dc62525644cbc9c232064ae" integrity sha512-Q7mOvpBNBG7YrVGMxRxcBJZFL75o+cH2abNASdibkj/fffYD8qWbInZrD0S9ccI6vZclF3DsHE7njGlLtaHbhg== dependencies: icss-utils "^5.1.0" @@ -8249,7 +8264,7 @@ cssstyle@^2.0.0, cssstyle@^2.3.0: csstype@^3.0.2: version "3.0.10" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.10.tgz#2ad3a7bed70f35b965707c092e5f30b327c290e5" + resolved "https://registry.npmjs.org/csstype/-/csstype-3.0.10.tgz#2ad3a7bed70f35b965707c092e5f30b327c290e5" integrity sha512-2u44ZG2OcNUO9HDp/Jl8C07x6pU/eTR3ncV91SiK3dhG9TWvRVsCoJw14Ckx5DgWkzGA3waZWO3d7pgqpUI/XA== csvtojson@^2.0.10: @@ -8290,7 +8305,7 @@ d@1, d@^1.0.1: damerau-levenshtein@^1.0.7: version "1.0.7" - resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.7.tgz#64368003512a1a6992593741a09a9d31a836f55d" + resolved "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.7.tgz#64368003512a1a6992593741a09a9d31a836f55d" integrity sha512-VvdQIPGdWP0SqFXghj79Wf/5LArmreyMsGLa6FG6iC4t3j7j5s71TrwWmT/4akbDQIqjfACkLZmjXhA7g2oUZw== danger@^10.6.4: @@ -8386,7 +8401,7 @@ date-fns@^1.30.1: date-fns@^2.25.0, date-fns@^2.28.0: version "2.28.0" - resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.28.0.tgz#9570d656f5fc13143e50c975a3b6bbeb46cd08b2" + resolved "https://registry.npmjs.org/date-fns/-/date-fns-2.28.0.tgz#9570d656f5fc13143e50c975a3b6bbeb46cd08b2" integrity sha512-8d35hViGYx/QH0icHYCeLmsLmMUheMmTyV9Fcm6gvNwdw31yXXH+O85sOBJ+OLnLQMKZowvpKb6FgMIQjcpvQw== dateformat@^3.0.0: @@ -8416,7 +8431,7 @@ debug@3.1.0, debug@~3.1.0: debug@4, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.2.0, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, debug@~4.3.1: version "4.3.3" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" + resolved "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== dependencies: ms "2.1.2" @@ -8444,9 +8459,9 @@ decamelize@^1.1.0, decamelize@^1.1.2, decamelize@^1.2.0: resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" decimal.js@^10.2.1: - version "10.3.1" - resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.3.1.tgz#d8c3a444a9c6774ba60ca6ad7261c3a94fd5e783" - integrity sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ== + version "10.2.1" + resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.2.1.tgz#238ae7b0f0c793d3e3cea410108b35a2c01426a3" + integrity sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw== decode-uri-component@^0.2.0: version "0.2.0" @@ -8777,7 +8792,7 @@ diff-sequences@^24.9.0: diff-sequences@^27.4.0: version "27.4.0" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.4.0.tgz#d783920ad8d06ec718a060d00196dfef25b132a5" + resolved "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.4.0.tgz#d783920ad8d06ec718a060d00196dfef25b132a5" integrity sha512-YqiQzkrsmHMH5uuh8OdQFU9/ZpADnwzml8z0O5HvRNda+5UZsaX/xN+AAxfR2hWq1Y7HZnAzO9J5lJXOuDz2Ww== diff@^4.0.1: @@ -9163,13 +9178,13 @@ ejs@^3.1.6: jake "^10.6.1" electron-to-chromium@^1.3.564, electron-to-chromium@^1.4.17: - version "1.4.31" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.31.tgz#8d5ccc3f8253cd142b07afaa84f200fd33a7f2a6" - integrity sha512-t3XVQtk+Frkv6aTD4RRk0OqosU+VLe1dQFW83MDer78ZD6a52frgXuYOIsLYTQiH2Lm+JB2OKYcn7zrX+YGAiQ== + version "1.4.36" + resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.36.tgz#446c6184dbe5baeb5eae9a875490831e4bc5319a" + integrity sha512-MbLlbF39vKrXWlFEFpCgDHwdlz4O3LmHM5W4tiLRHjSmEUXjJjz8sZkMgWgvYxlZw3N1iDTmCEtOkkESb5TMCg== emittery@^0.8.1: version "0.8.1" - resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.8.1.tgz#bb23cc86d03b30aa75a7f734819dee2e1ba70860" + resolved "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz#bb23cc86d03b30aa75a7f734819dee2e1ba70860" integrity sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg== "emoji-regex@>=6.0.0 <=6.1.1": @@ -9187,7 +9202,7 @@ emoji-regex@^8.0.0: emoji-regex@^9.0.0, emoji-regex@^9.2.2: version "9.2.2" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" + resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== emojis-list@^2.0.0: @@ -9533,7 +9548,7 @@ eslint-import-resolver-node@^0.3.6: eslint-module-utils@^2.7.2: version "2.7.2" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.7.2.tgz#1d0aa455dcf41052339b63cada8ab5fd57577129" + resolved "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.2.tgz#1d0aa455dcf41052339b63cada8ab5fd57577129" integrity sha512-zquepFnWCY2ISMFwD/DqzaM++H+7PDzOpUvotJWm/y1BAFt5R4oeULgdrTejKqLkz7MA/tgstsUMNYc7wNdTrg== dependencies: debug "^3.2.7" @@ -9576,7 +9591,7 @@ eslint-plugin-graphql@^4.0.0: eslint-plugin-import@^2.25.4: version "2.25.4" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.25.4.tgz#322f3f916a4e9e991ac7af32032c25ce313209f1" + resolved "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.25.4.tgz#322f3f916a4e9e991ac7af32032c25ce313209f1" integrity sha512-/KJBASVFxpu0xg1kIBn9AUa8hQVnszpwgE7Ld0lKAlx7Ie87yzEzCgSkekt+le/YVhiaosO4Y14GDAOc41nfxA== dependencies: array-includes "^3.1.4" @@ -9595,7 +9610,7 @@ eslint-plugin-import@^2.25.4: eslint-plugin-jsx-a11y@^6.5.1: version "6.5.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.5.1.tgz#cdbf2df901040ca140b6ec14715c988889c2a6d8" + resolved "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.5.1.tgz#cdbf2df901040ca140b6ec14715c988889c2a6d8" integrity sha512-sVCFKX9fllURnXT2JwLN5Qgo24Ug5NF6dxhkmxsMEUZhXRcGg+X3e1JbJ84YePQKBl5E0ZjAH5Q4rkdcGY99+g== dependencies: "@babel/runtime" "^7.16.3" @@ -9620,12 +9635,12 @@ eslint-plugin-prettier@^4.0.0: eslint-plugin-react-hooks@^4.3.0: version "4.3.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.3.0.tgz#318dbf312e06fab1c835a4abef00121751ac1172" + resolved "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.3.0.tgz#318dbf312e06fab1c835a4abef00121751ac1172" integrity sha512-XslZy0LnMn+84NEG9jSGR6eGqaZB3133L8xewQo3fQagbQuGt7a63gf+P1NGKZavEYEC3UXaWEAA/AqDkuN6xA== eslint-plugin-react@^7.28.0: version "7.28.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.28.0.tgz#8f3ff450677571a659ce76efc6d80b6a525adbdf" + resolved "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.28.0.tgz#8f3ff450677571a659ce76efc6d80b6a525adbdf" integrity sha512-IOlFIRHzWfEQQKcAD4iyYDndHwTQiCMcJVJjxempf203jnNLUnW34AXLrV33+nEXoifJE2ZEGmcjKPL8957eSw== dependencies: array-includes "^3.1.4" @@ -9682,7 +9697,7 @@ eslint-visitor-keys@^2.0.0, eslint-visitor-keys@^2.1.0: eslint-webpack-plugin@^2.6.0: version "2.6.0" - resolved "https://registry.yarnpkg.com/eslint-webpack-plugin/-/eslint-webpack-plugin-2.6.0.tgz#3bd4ada4e539cb1f6687d2f619073dbb509361cd" + resolved "https://registry.npmjs.org/eslint-webpack-plugin/-/eslint-webpack-plugin-2.6.0.tgz#3bd4ada4e539cb1f6687d2f619073dbb509361cd" integrity sha512-V+LPY/T3kur5QO3u+1s34VDTcRxjXWPUGM4hlmTb5DwVD0OQz631yGTxJZf4SpAqAjdbBVe978S8BJeHpAdOhQ== dependencies: "@types/eslint" "^7.28.2" @@ -9793,7 +9808,7 @@ estraverse@^4.1.1, estraverse@^4.2.0: estraverse@^5.1.0, estraverse@^5.2.0, estraverse@^5.3.0: version "5.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== estraverse@~1.5.0: @@ -10021,17 +10036,15 @@ expect@^24.1.0: jest-message-util "^24.9.0" jest-regex-util "^24.9.0" -expect@^27.4.2: - version "27.4.2" - resolved "https://registry.yarnpkg.com/expect/-/expect-27.4.2.tgz#4429b0f7e307771d176de9bdf23229b101db6ef6" - integrity sha512-BjAXIDC6ZOW+WBFNg96J22D27Nq5ohn+oGcuP2rtOtcjuxNoV9McpQ60PcQWhdFOSBIQdR72e+4HdnbZTFSTyg== +expect@^27.4.6: + version "27.4.6" + resolved "https://registry.npmjs.org/expect/-/expect-27.4.6.tgz#f335e128b0335b6ceb4fcab67ece7cbd14c942e6" + integrity sha512-1M/0kAALIaj5LaG66sFJTbRsWTADnylly82cu4bspI0nl+pgP4E6Bh/aqdHlTUjul06K7xQnnrAoqfxVU0+/ag== dependencies: "@jest/types" "^27.4.2" - ansi-styles "^5.0.0" jest-get-type "^27.4.0" - jest-matcher-utils "^27.4.2" - jest-message-util "^27.4.2" - jest-regex-util "^27.4.0" + jest-matcher-utils "^27.4.6" + jest-message-util "^27.4.6" express-graphql@^0.12.0: version "0.12.0" @@ -10195,9 +10208,9 @@ fast-glob@^2.2.6: merge2 "^1.2.3" micromatch "^3.1.10" -fast-glob@^3.0.3, fast-glob@^3.1.1, fast-glob@^3.2.11, fast-glob@^3.2.4: +fast-glob@^3.0.3, fast-glob@^3.1.1, fast-glob@^3.2.11, fast-glob@^3.2.4, fast-glob@^3.2.9: version "3.2.11" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9" + resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9" integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew== dependencies: "@nodelib/fs.stat" "^2.0.2" @@ -10689,7 +10702,7 @@ frac@~1.1.2: fraction.js@^4.1.2: version "4.1.2" - resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.1.2.tgz#13e420a92422b6cf244dff8690ed89401029fbe8" + resolved "https://registry.npmjs.org/fraction.js/-/fraction.js-4.1.2.tgz#13e420a92422b6cf244dff8690ed89401029fbe8" integrity sha512-o2RiJQ6DZaR/5+Si0qJUIy637QMRudSi9kU/FFzx9EZazrIdnBgpU+3sEWCxAVhH2RtxW2Oz+T4p2o8uOPVcgA== fragment-cache@^0.2.1: @@ -10815,7 +10828,7 @@ fs.realpath@^1.0.0: fsevents@^2.3.2, fsevents@~2.3.2: version "2.3.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== function-bind@^1.0.2, function-bind@^1.1.1: @@ -11273,15 +11286,15 @@ globby@^10.0.1: slash "^3.0.0" globby@^11.0.1, globby@^11.0.3, globby@^11.0.4: - version "11.0.4" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.4.tgz#2cbaff77c2f2a62e71e9b2813a67b97a3a3001a5" - integrity sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg== + version "11.1.0" + resolved "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" + integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== dependencies: array-union "^2.1.0" dir-glob "^3.0.1" - fast-glob "^3.1.1" - ignore "^5.1.4" - merge2 "^1.3.0" + fast-glob "^3.2.9" + ignore "^5.2.0" + merge2 "^1.4.1" slash "^3.0.0" globby@^6.1.0: @@ -11321,7 +11334,7 @@ good-listener@^1.2.2: got@^11.8.2, got@^11.8.3: version "11.8.3" - resolved "https://registry.yarnpkg.com/got/-/got-11.8.3.tgz#f496c8fdda5d729a90b4905d2b07dbd148170770" + resolved "https://registry.npmjs.org/got/-/got-11.8.3.tgz#f496c8fdda5d729a90b4905d2b07dbd148170770" integrity sha512-7gtQ5KiPh1RtGS9/Jbv1ofDpBFuq42gyfEib+ejaRBJuj/3tQFeR5+gw57e4ipaU8c/rCjvX6fkQz2lyDlGAOg== dependencies: "@sindresorhus/is" "^4.0.0" @@ -11500,7 +11513,7 @@ graphql-ws@^4.1.0: graphql@^15.5.1, graphql@^15.7.2, graphql@^15.8.0: version "15.8.0" - resolved "https://registry.yarnpkg.com/graphql/-/graphql-15.8.0.tgz#33410e96b012fa3bdb1091cc99a94769db212b38" + resolved "https://registry.npmjs.org/graphql/-/graphql-15.8.0.tgz#33410e96b012fa3bdb1091cc99a94769db212b38" integrity sha512-5gghUc24tP9HRznNpV2+FIoq3xKkj5dTQqf4v0CpdPbFVwFkWoxOM+o+2OC9ZSvjEMTjfmG9QT+gcvggTwW1zw== gray-matter@^2.1.0: @@ -11530,7 +11543,6 @@ gray-percentage@^2.0.0: growly@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" - integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE= gulp-header@^1.7.1: version "1.8.12" @@ -12084,7 +12096,7 @@ http-errors@1.8.0: http-errors@1.8.1: version "1.8.1" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.8.1.tgz#7c3f28577cbc8a207388455dbd62295ed07bd68c" + resolved "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz#7c3f28577cbc8a207388455dbd62295ed07bd68c" integrity sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g== dependencies: depd "~1.1.2" @@ -12161,7 +12173,7 @@ http2-wrapper@^1.0.0-beta.5.2: http2-wrapper@^2.1.10: version "2.1.10" - resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-2.1.10.tgz#307cd0cee2564723692ad34c2d570d12f10e83be" + resolved "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.1.10.tgz#307cd0cee2564723692ad34c2d570d12f10e83be" integrity sha512-QHgsdYkieKp+6JbXP25P+tepqiHYd+FVnDwXpxi/BlUcoIB0nsmTOymTNvETuTO+pDuwcSklPE72VR3DqV+Haw== dependencies: quick-lru "^5.1.1" @@ -12303,10 +12315,10 @@ ignore@^4.0.3, ignore@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" -ignore@^5.0.0, ignore@^5.1.1, ignore@^5.1.4, ignore@^5.1.8: - version "5.1.8" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" - integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== +ignore@^5.0.0, ignore@^5.1.1, ignore@^5.1.4, ignore@^5.1.8, ignore@^5.2.0: + version "5.2.0" + resolved "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" + integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== image-q@^1.1.1: version "1.1.1" @@ -12563,7 +12575,7 @@ inquirer@^7.0.0: inquirer@^8.1.1, inquirer@^8.2.0: version "8.2.0" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-8.2.0.tgz#f44f008dd344bbfc4b30031f45d984e034a3ac3a" + resolved "https://registry.npmjs.org/inquirer/-/inquirer-8.2.0.tgz#f44f008dd344bbfc4b30031f45d984e034a3ac3a" integrity sha512-0crLweprevJ02tTuA6ThpoAERAGyVILC4sS74uib58Xf/zSr1/ZWtmm7D5CI+bSQEaA04f0K7idaHpQbSWgiVQ== dependencies: ansi-escapes "^4.2.1" @@ -12738,9 +12750,9 @@ is-color-stop@^1.0.0, is-color-stop@^1.1.0: rgba-regex "^1.0.0" is-core-module@^2.2.0, is-core-module@^2.5.0, is-core-module@^2.8.0: - version "2.8.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.0.tgz#0321336c3d0925e497fd97f5d95cb114a5ccd548" - integrity sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw== + version "2.8.1" + resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz#f59fdfca701d5879d0a6b100a40aa1560ce27211" + integrity sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA== dependencies: has "^1.0.3" @@ -13255,19 +13267,20 @@ isstream@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" -istanbul-lib-coverage@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz#f5944a37c70b550b02a78a5c3b2055b280cec8ec" - integrity sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg== +istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: + version "3.2.0" + resolved "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" + integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== -istanbul-lib-instrument@^4.0.0, istanbul-lib-instrument@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz#873c6fff897450118222774696a3f28902d77c1d" - integrity sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ== +istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: + version "5.1.0" + resolved "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz#7b49198b657b27a730b8e9cb601f1e1bff24c59a" + integrity sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q== dependencies: - "@babel/core" "^7.7.5" + "@babel/core" "^7.12.3" + "@babel/parser" "^7.14.7" "@istanbuljs/schema" "^0.1.2" - istanbul-lib-coverage "^3.0.0" + istanbul-lib-coverage "^3.2.0" semver "^6.3.0" istanbul-lib-report@^3.0.0: @@ -13288,10 +13301,10 @@ istanbul-lib-source-maps@^4.0.0: istanbul-lib-coverage "^3.0.0" source-map "^0.6.1" -istanbul-reports@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.0.2.tgz#d593210e5000683750cb09fc0644e4b6e27fd53b" - integrity sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw== +istanbul-reports@^3.0.2, istanbul-reports@^3.1.3: + version "3.1.3" + resolved "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.3.tgz#4bcae3103b94518117930d51283690960b50d3c2" + integrity sha512-x9LtDVtfm/t1GFiLl3NffC7hz+I1ragvgX1P/Lg1NlIagifZDKUkuuaAxH/qpwj2IuEfD8G2Bs/UKp+sZ/pKkg== dependencies: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" @@ -13313,82 +13326,82 @@ jake@^10.6.1: jest-changed-files@^27.4.2: version "27.4.2" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-27.4.2.tgz#da2547ea47c6e6a5f6ed336151bd2075736eb4a5" + resolved "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.4.2.tgz#da2547ea47c6e6a5f6ed336151bd2075736eb4a5" integrity sha512-/9x8MjekuzUQoPjDHbBiXbNEBauhrPU2ct7m8TfCg69ywt1y/N+yYwGh3gCpnqUS3klYWDU/lSNgv+JhoD2k1A== dependencies: "@jest/types" "^27.4.2" execa "^5.0.0" throat "^6.0.1" -jest-circus@^27.4.4: - version "27.4.4" - resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-27.4.4.tgz#8bf89aa604b914ecc10e3d895aae283b529f965d" - integrity sha512-4DWhvQerDq5X4GaqhEUoZiBhuNdKDGr0geW0iJwarbDljAmGaGOErKQG+z2PBr0vgN05z7tsGSY51mdWr8E4xg== +jest-circus@^27.4.6: + version "27.4.6" + resolved "https://registry.npmjs.org/jest-circus/-/jest-circus-27.4.6.tgz#d3af34c0eb742a967b1919fbb351430727bcea6c" + integrity sha512-UA7AI5HZrW4wRM72Ro80uRR2Fg+7nR0GESbSI/2M+ambbzVuA63mn5T1p3Z/wlhntzGpIG1xx78GP2YIkf6PhQ== dependencies: - "@jest/environment" "^27.4.4" - "@jest/test-result" "^27.4.2" + "@jest/environment" "^27.4.6" + "@jest/test-result" "^27.4.6" "@jest/types" "^27.4.2" "@types/node" "*" chalk "^4.0.0" co "^4.6.0" dedent "^0.7.0" - expect "^27.4.2" + expect "^27.4.6" is-generator-fn "^2.0.0" - jest-each "^27.4.2" - jest-matcher-utils "^27.4.2" - jest-message-util "^27.4.2" - jest-runtime "^27.4.4" - jest-snapshot "^27.4.4" + jest-each "^27.4.6" + jest-matcher-utils "^27.4.6" + jest-message-util "^27.4.6" + jest-runtime "^27.4.6" + jest-snapshot "^27.4.6" jest-util "^27.4.2" - pretty-format "^27.4.2" + pretty-format "^27.4.6" slash "^3.0.0" stack-utils "^2.0.3" throat "^6.0.1" -jest-cli@^27.4.4: - version "27.4.4" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-27.4.4.tgz#7115ff01f605c2c848314141b1ac144099ddeed5" - integrity sha512-+MfsHnZPUOBigCBURuQFRpgYoPCgmIFkICkqt4SrramZCUp/UAuWcst4pMZb84O3VU8JyKJmnpGG4qH8ClQloA== +jest-cli@^27.4.7: + version "27.4.7" + resolved "https://registry.npmjs.org/jest-cli/-/jest-cli-27.4.7.tgz#d00e759e55d77b3bcfea0715f527c394ca314e5a" + integrity sha512-zREYhvjjqe1KsGV15mdnxjThKNDgza1fhDT+iUsXWLCq3sxe9w5xnvyctcYVT5PcdLSjv7Y5dCwTS3FCF1tiuw== dependencies: - "@jest/core" "^27.4.4" - "@jest/test-result" "^27.4.2" + "@jest/core" "^27.4.7" + "@jest/test-result" "^27.4.6" "@jest/types" "^27.4.2" chalk "^4.0.0" exit "^0.1.2" graceful-fs "^4.2.4" import-local "^3.0.2" - jest-config "^27.4.4" + jest-config "^27.4.7" jest-util "^27.4.2" - jest-validate "^27.4.2" + jest-validate "^27.4.6" prompts "^2.0.1" yargs "^16.2.0" -jest-config@^27.4.4: - version "27.4.4" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-27.4.4.tgz#0e3615392361baae0e29dbf64c296d5563d7e28b" - integrity sha512-6lxg0ugO6KS2zKEbpdDwBzu1IT0Xg4/VhxXMuBu+z/5FvBjLCEMTaWQm3bCaGCZUR9j9FK4DzUIxyhIgn6kVEg== +jest-config@^27.4.7: + version "27.4.7" + resolved "https://registry.npmjs.org/jest-config/-/jest-config-27.4.7.tgz#4f084b2acbd172c8b43aa4cdffe75d89378d3972" + integrity sha512-xz/o/KJJEedHMrIY9v2ParIoYSrSVY6IVeE4z5Z3i101GoA5XgfbJz+1C8EYPsv7u7f39dS8F9v46BHDhn0vlw== dependencies: - "@babel/core" "^7.1.0" - "@jest/test-sequencer" "^27.4.4" + "@babel/core" "^7.8.0" + "@jest/test-sequencer" "^27.4.6" "@jest/types" "^27.4.2" - babel-jest "^27.4.4" + babel-jest "^27.4.6" chalk "^4.0.0" ci-info "^3.2.0" deepmerge "^4.2.2" glob "^7.1.1" graceful-fs "^4.2.4" - jest-circus "^27.4.4" - jest-environment-jsdom "^27.4.4" - jest-environment-node "^27.4.4" + jest-circus "^27.4.6" + jest-environment-jsdom "^27.4.6" + jest-environment-node "^27.4.6" jest-get-type "^27.4.0" - jest-jasmine2 "^27.4.4" + jest-jasmine2 "^27.4.6" jest-regex-util "^27.4.0" - jest-resolve "^27.4.4" - jest-runner "^27.4.4" + jest-resolve "^27.4.6" + jest-runner "^27.4.6" jest-util "^27.4.2" - jest-validate "^27.4.2" + jest-validate "^27.4.6" micromatch "^4.0.4" - pretty-format "^27.4.2" + pretty-format "^27.4.6" slash "^3.0.0" jest-diff@^24.9.0: @@ -13401,57 +13414,57 @@ jest-diff@^24.9.0: jest-get-type "^24.9.0" pretty-format "^24.9.0" -jest-diff@^27.0.0, jest-diff@^27.4.2: - version "27.4.2" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-27.4.2.tgz#786b2a5211d854f848e2dcc1e324448e9481f36f" - integrity sha512-ujc9ToyUZDh9KcqvQDkk/gkbf6zSaeEg9AiBxtttXW59H/AcqEYp1ciXAtJp+jXWva5nAf/ePtSsgWwE5mqp4Q== +jest-diff@^27.0.0, jest-diff@^27.4.6: + version "27.4.6" + resolved "https://registry.npmjs.org/jest-diff/-/jest-diff-27.4.6.tgz#93815774d2012a2cbb6cf23f84d48c7a2618f98d" + integrity sha512-zjaB0sh0Lb13VyPsd92V7HkqF6yKRH9vm33rwBt7rPYrpQvS1nCvlIy2pICbKta+ZjWngYLNn4cCK4nyZkjS/w== dependencies: chalk "^4.0.0" diff-sequences "^27.4.0" jest-get-type "^27.4.0" - pretty-format "^27.4.2" + pretty-format "^27.4.6" jest-docblock@^27.4.0: version "27.4.0" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-27.4.0.tgz#06c78035ca93cbbb84faf8fce64deae79a59f69f" + resolved "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.4.0.tgz#06c78035ca93cbbb84faf8fce64deae79a59f69f" integrity sha512-7TBazUdCKGV7svZ+gh7C8esAnweJoG+SvcF6Cjqj4l17zA2q1cMwx2JObSioubk317H+cjcHgP+7fTs60paulg== dependencies: detect-newline "^3.0.0" -jest-each@^27.4.2: - version "27.4.2" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-27.4.2.tgz#19364c82a692d0d26557642098d1f4619c9ee7d3" - integrity sha512-53V2MNyW28CTruB3lXaHNk6PkiIFuzdOC9gR3C6j8YE/ACfrPnz+slB0s17AgU1TtxNzLuHyvNlLJ+8QYw9nBg== +jest-each@^27.4.6: + version "27.4.6" + resolved "https://registry.npmjs.org/jest-each/-/jest-each-27.4.6.tgz#e7e8561be61d8cc6dbf04296688747ab186c40ff" + integrity sha512-n6QDq8y2Hsmn22tRkgAk+z6MCX7MeVlAzxmZDshfS2jLcaBlyhpF3tZSJLR+kXmh23GEvS0ojMR8i6ZeRvpQcA== dependencies: "@jest/types" "^27.4.2" chalk "^4.0.0" jest-get-type "^27.4.0" jest-util "^27.4.2" - pretty-format "^27.4.2" + pretty-format "^27.4.6" -jest-environment-jsdom@^27.4.4: - version "27.4.4" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-27.4.4.tgz#94f738e99514d7a880e8ed8e03e3a321d43b49db" - integrity sha512-cYR3ndNfHBqQgFvS1RL7dNqSvD//K56j/q1s2ygNHcfTCAp12zfIromO1w3COmXrxS8hWAh7+CmZmGCIoqGcGA== +jest-environment-jsdom@^27.4.6: + version "27.4.6" + resolved "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.4.6.tgz#c23a394eb445b33621dfae9c09e4c8021dea7b36" + integrity sha512-o3dx5p/kHPbUlRvSNjypEcEtgs6LmvESMzgRFQE6c+Prwl2JLA4RZ7qAnxc5VM8kutsGRTB15jXeeSbJsKN9iA== dependencies: - "@jest/environment" "^27.4.4" - "@jest/fake-timers" "^27.4.2" + "@jest/environment" "^27.4.6" + "@jest/fake-timers" "^27.4.6" "@jest/types" "^27.4.2" "@types/node" "*" - jest-mock "^27.4.2" + jest-mock "^27.4.6" jest-util "^27.4.2" jsdom "^16.6.0" -jest-environment-node@^27.4.4: - version "27.4.4" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-27.4.4.tgz#42fe5e3b224cb69b99811ebf6f5eaa5a59618514" - integrity sha512-D+v3lbJ2GjQTQR23TK0kY3vFVmSeea05giInI41HHOaJnAwOnmUHTZgUaZL+VxUB43pIzoa7PMwWtCVlIUoVoA== +jest-environment-node@^27.4.6: + version "27.4.6" + resolved "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.4.6.tgz#ee8cd4ef458a0ef09d087c8cd52ca5856df90242" + integrity sha512-yfHlZ9m+kzTKZV0hVfhVu6GuDxKAYeFHrfulmy7Jxwsq4V7+ZK7f+c0XP/tbVDMQW7E4neG2u147hFkuVz0MlQ== dependencies: - "@jest/environment" "^27.4.4" - "@jest/fake-timers" "^27.4.2" + "@jest/environment" "^27.4.6" + "@jest/fake-timers" "^27.4.6" "@jest/types" "^27.4.2" "@types/node" "*" - jest-mock "^27.4.2" + jest-mock "^27.4.6" jest-util "^27.4.2" jest-extended@^0.11.5: @@ -13474,13 +13487,13 @@ jest-get-type@^24.9.0: jest-get-type@^27.4.0: version "27.4.0" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.4.0.tgz#7503d2663fffa431638337b3998d39c5e928e9b5" + resolved "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.4.0.tgz#7503d2663fffa431638337b3998d39c5e928e9b5" integrity sha512-tk9o+ld5TWq41DkK14L4wox4s2D9MtTpKaAVzXfr5CUKm5ZK2ExcaFE0qls2W71zE/6R2TxxrK9w2r6svAFDBQ== -jest-haste-map@^27.4.4: - version "27.4.4" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-27.4.4.tgz#ec6013845368a155372e25e42e2b77e6ecc5019f" - integrity sha512-kvspmHmgPIZoDaqUsvsJFTaspuxhATvdO6wsFNGNSi8kfdiOCEEvECNbht8xG+eE5Ol88JyJmp2D7RF4dYo85Q== +jest-haste-map@^27.4.6: + version "27.4.6" + resolved "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.4.6.tgz#c60b5233a34ca0520f325b7e2cc0a0140ad0862a" + integrity sha512-0tNpgxg7BKurZeFkIOvGCkbmOHbLFf4LUQOxrQSMjvrQaQe3l6E8x6jYC1NuWkGo5WDdbr8FEzUxV2+LWNawKQ== dependencies: "@jest/types" "^27.4.2" "@types/graceful-fs" "^4.1.2" @@ -13491,53 +13504,52 @@ jest-haste-map@^27.4.4: jest-regex-util "^27.4.0" jest-serializer "^27.4.0" jest-util "^27.4.2" - jest-worker "^27.4.4" + jest-worker "^27.4.6" micromatch "^4.0.4" walker "^1.0.7" optionalDependencies: fsevents "^2.3.2" -jest-jasmine2@^27.4.4: - version "27.4.4" - resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-27.4.4.tgz#1fcdc64de932913366e7d5f2960c375e1145176e" - integrity sha512-ygk2tUgtLeN3ouj4KEYw9p81GLI1EKrnvourPULN5gdgB482PH5op9gqaRG0IenbJhBbbRwiSvh5NoBoQZSqdA== +jest-jasmine2@^27.4.6: + version "27.4.6" + resolved "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.4.6.tgz#109e8bc036cb455950ae28a018f983f2abe50127" + integrity sha512-uAGNXF644I/whzhsf7/qf74gqy9OuhvJ0XYp8SDecX2ooGeaPnmJMjXjKt0mqh1Rl5dtRGxJgNrHlBQIBfS5Nw== dependencies: - "@babel/traverse" "^7.1.0" - "@jest/environment" "^27.4.4" + "@jest/environment" "^27.4.6" "@jest/source-map" "^27.4.0" - "@jest/test-result" "^27.4.2" + "@jest/test-result" "^27.4.6" "@jest/types" "^27.4.2" "@types/node" "*" chalk "^4.0.0" co "^4.6.0" - expect "^27.4.2" + expect "^27.4.6" is-generator-fn "^2.0.0" - jest-each "^27.4.2" - jest-matcher-utils "^27.4.2" - jest-message-util "^27.4.2" - jest-runtime "^27.4.4" - jest-snapshot "^27.4.4" + jest-each "^27.4.6" + jest-matcher-utils "^27.4.6" + jest-message-util "^27.4.6" + jest-runtime "^27.4.6" + jest-snapshot "^27.4.6" jest-util "^27.4.2" - pretty-format "^27.4.2" + pretty-format "^27.4.6" throat "^6.0.1" jest-junit@^12.2.0: - version "12.2.0" - resolved "https://registry.yarnpkg.com/jest-junit/-/jest-junit-12.2.0.tgz#cff7f9516e84f8e30f6bdea04cd84db6b095a376" - integrity sha512-ecGzF3KEQwLbMP5xMO7wqmgmyZlY/5yWDvgE/vFa+/uIT0KsU5nluf0D2fjIlOKB+tb6DiuSSpZuGpsmwbf7Fw== + version "12.3.0" + resolved "https://registry.npmjs.org/jest-junit/-/jest-junit-12.3.0.tgz#ee41a74e439eecdc8965f163f83035cce5998d6d" + integrity sha512-+NmE5ogsEjFppEl90GChrk7xgz8xzvF0f+ZT5AnhW6suJC93gvQtmQjfyjDnE0Z2nXJqEkxF0WXlvjG/J+wn/g== dependencies: mkdirp "^1.0.4" strip-ansi "^5.2.0" uuid "^8.3.2" xml "^1.0.1" -jest-leak-detector@^27.4.2: - version "27.4.2" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-27.4.2.tgz#7fc3120893a7a911c553f3f2bdff9faa4454abbb" - integrity sha512-ml0KvFYZllzPBJWDei3mDzUhyp/M4ubKebX++fPaudpe8OsxUE+m+P6ciVLboQsrzOCWDjE20/eXew9QMx/VGw== +jest-leak-detector@^27.4.6: + version "27.4.6" + resolved "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.4.6.tgz#ed9bc3ce514b4c582637088d9faf58a33bd59bf4" + integrity sha512-kkaGixDf9R7CjHm2pOzfTxZTQQQ2gHTIWKY/JZSiYTc90bZp8kSZnUMS3uLAfwTZwc0tcMRoEX74e14LG1WapA== dependencies: jest-get-type "^27.4.0" - pretty-format "^27.4.2" + pretty-format "^27.4.6" jest-matcher-utils@^22.0.0: version "22.4.3" @@ -13558,15 +13570,15 @@ jest-matcher-utils@^24.9.0: jest-get-type "^24.9.0" pretty-format "^24.9.0" -jest-matcher-utils@^27.4.2: - version "27.4.2" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-27.4.2.tgz#d17c5038607978a255e0a9a5c32c24e984b6c60b" - integrity sha512-jyP28er3RRtMv+fmYC/PKG8wvAmfGcSNproVTW2Y0P/OY7/hWUOmsPfxN1jOhM+0u2xU984u2yEagGivz9OBGQ== +jest-matcher-utils@^27.4.6: + version "27.4.6" + resolved "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.4.6.tgz#53ca7f7b58170638590e946f5363b988775509b8" + integrity sha512-XD4PKT3Wn1LQnRAq7ZsTI0VRuEc9OrCPFiO1XL7bftTGmfNF0DcEwMHRgqiu7NGf8ZoZDREpGrCniDkjt79WbA== dependencies: chalk "^4.0.0" - jest-diff "^27.4.2" + jest-diff "^27.4.6" jest-get-type "^27.4.0" - pretty-format "^27.4.2" + pretty-format "^27.4.6" jest-message-util@^24.9.0: version "24.9.0" @@ -13582,10 +13594,10 @@ jest-message-util@^24.9.0: slash "^2.0.0" stack-utils "^1.0.1" -jest-message-util@^27.4.2: - version "27.4.2" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-27.4.2.tgz#07f3f1bf207d69cf798ce830cc57f1a849f99388" - integrity sha512-OMRqRNd9E0DkBLZpFtZkAGYOXl6ZpoMtQJWTAREJKDOFa0M6ptB7L67tp+cszMBkvSgKOhNtQp2Vbcz3ZZKo/w== +jest-message-util@^27.4.6: + version "27.4.6" + resolved "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.4.6.tgz#9fdde41a33820ded3127465e1a5896061524da31" + integrity sha512-0p5szriFU0U74czRSFjH6RyS7UYIAkn/ntwMuOwTGWrQIOh5NzXXrq72LOqIkJKKvFbPq+byZKuBz78fjBERBA== dependencies: "@babel/code-frame" "^7.12.13" "@jest/types" "^27.4.2" @@ -13593,14 +13605,14 @@ jest-message-util@^27.4.2: chalk "^4.0.0" graceful-fs "^4.2.4" micromatch "^4.0.4" - pretty-format "^27.4.2" + pretty-format "^27.4.6" slash "^3.0.0" stack-utils "^2.0.3" -jest-mock@^27.4.2: - version "27.4.2" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-27.4.2.tgz#184ff197a25491bfe4570c286daa5d62eb760b88" - integrity sha512-PDDPuyhoukk20JrQKeofK12hqtSka7mWH0QQuxSNgrdiPsrnYYLS6wbzu/HDlxZRzji5ylLRULeuI/vmZZDrYA== +jest-mock@^27.4.6: + version "27.4.6" + resolved "https://registry.npmjs.org/jest-mock/-/jest-mock-27.4.6.tgz#77d1ba87fbd33ccb8ef1f061697e7341b7635195" + integrity sha512-kvojdYRkst8iVSZ1EJ+vc1RRD9llueBjKzXzeCytH3dMM7zvPV/ULcfI2nr0v0VUgm3Bjt3hBCQvOeaBz+ZTHw== dependencies: "@jest/types" "^27.4.2" "@types/node" "*" @@ -13617,43 +13629,43 @@ jest-regex-util@^24.9.0: jest-regex-util@^27.4.0: version "27.4.0" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-27.4.0.tgz#e4c45b52653128843d07ad94aec34393ea14fbca" + resolved "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.4.0.tgz#e4c45b52653128843d07ad94aec34393ea14fbca" integrity sha512-WeCpMpNnqJYMQoOjm1nTtsgbR4XHAk1u00qDoNBQoykM280+/TmgA5Qh5giC1ecy6a5d4hbSsHzpBtu5yvlbEg== -jest-resolve-dependencies@^27.4.4: - version "27.4.4" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-27.4.4.tgz#dae11e067a6d6a9553f1386a0ea1efe5be0e2332" - integrity sha512-iAnpCXh81sd9nbyqySvm5/aV9X6JZKE0dQyFXTC8tptXcdrgS0vjPFy+mEgzPHxXw+tq4TQupuTa0n8OXwRIxw== +jest-resolve-dependencies@^27.4.6: + version "27.4.6" + resolved "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.4.6.tgz#fc50ee56a67d2c2183063f6a500cc4042b5e2327" + integrity sha512-W85uJZcFXEVZ7+MZqIPCscdjuctruNGXUZ3OHSXOfXR9ITgbUKeHj+uGcies+0SsvI5GtUfTw4dY7u9qjTvQOw== dependencies: "@jest/types" "^27.4.2" jest-regex-util "^27.4.0" - jest-snapshot "^27.4.4" + jest-snapshot "^27.4.6" -jest-resolve@^27.4.4: - version "27.4.4" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-27.4.4.tgz#5b690662f54f38f7cfaffc0adcdb341ff7724408" - integrity sha512-Yh5jK3PBmDbm01Rc8pT0XqpBlTPEGwWp7cN61ijJuwony/tR2Taof3TLy6yfNiuRS8ucUOPO7NBYm3ei38kkcg== +jest-resolve@^27.4.6: + version "27.4.6" + resolved "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.4.6.tgz#2ec3110655e86d5bfcfa992e404e22f96b0b5977" + integrity sha512-SFfITVApqtirbITKFAO7jOVN45UgFzcRdQanOFzjnbd+CACDoyeX7206JyU92l4cRr73+Qy/TlW51+4vHGt+zw== dependencies: "@jest/types" "^27.4.2" chalk "^4.0.0" graceful-fs "^4.2.4" - jest-haste-map "^27.4.4" + jest-haste-map "^27.4.6" jest-pnp-resolver "^1.2.2" jest-util "^27.4.2" - jest-validate "^27.4.2" + jest-validate "^27.4.6" resolve "^1.20.0" resolve.exports "^1.1.0" slash "^3.0.0" -jest-runner@^27.4.4: - version "27.4.4" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-27.4.4.tgz#0b40cdcbac293ebc4c19c2d7805d17ab1072f1fd" - integrity sha512-AXv/8Q0Xf1puWnDf52m7oLrK7sXcv6re0V/kItwTSVHJbX7Oebm07oGFQqGmq0R0mhO1zpmB3OpqRuaCN2elPA== +jest-runner@^27.4.6: + version "27.4.6" + resolved "https://registry.npmjs.org/jest-runner/-/jest-runner-27.4.6.tgz#1d390d276ec417e9b4d0d081783584cbc3e24773" + integrity sha512-IDeFt2SG4DzqalYBZRgbbPmpwV3X0DcntjezPBERvnhwKGWTW7C5pbbA5lVkmvgteeNfdd/23gwqv3aiilpYPg== dependencies: - "@jest/console" "^27.4.2" - "@jest/environment" "^27.4.4" - "@jest/test-result" "^27.4.2" - "@jest/transform" "^27.4.4" + "@jest/console" "^27.4.6" + "@jest/environment" "^27.4.6" + "@jest/test-result" "^27.4.6" + "@jest/transform" "^27.4.6" "@jest/types" "^27.4.2" "@types/node" "*" chalk "^4.0.0" @@ -13661,49 +13673,45 @@ jest-runner@^27.4.4: exit "^0.1.2" graceful-fs "^4.2.4" jest-docblock "^27.4.0" - jest-environment-jsdom "^27.4.4" - jest-environment-node "^27.4.4" - jest-haste-map "^27.4.4" - jest-leak-detector "^27.4.2" - jest-message-util "^27.4.2" - jest-resolve "^27.4.4" - jest-runtime "^27.4.4" + jest-environment-jsdom "^27.4.6" + jest-environment-node "^27.4.6" + jest-haste-map "^27.4.6" + jest-leak-detector "^27.4.6" + jest-message-util "^27.4.6" + jest-resolve "^27.4.6" + jest-runtime "^27.4.6" jest-util "^27.4.2" - jest-worker "^27.4.4" + jest-worker "^27.4.6" source-map-support "^0.5.6" throat "^6.0.1" -jest-runtime@^27.4.4: - version "27.4.4" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-27.4.4.tgz#0d486735e8a1c8bbcdbb9285b3155ed94c5e3670" - integrity sha512-tZGay6P6vXJq8t4jVFAUzYHx+lzIHXjz+rj1XBk6mAR1Lwtf5kz0Uun7qNuU+oqpZu4+hhuxpUfXb6j30bEPqA== +jest-runtime@^27.4.6: + version "27.4.6" + resolved "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.4.6.tgz#83ae923818e3ea04463b22f3597f017bb5a1cffa" + integrity sha512-eXYeoR/MbIpVDrjqy5d6cGCFOYBFFDeKaNWqTp0h6E74dK0zLHzASQXJpl5a2/40euBmKnprNLJ0Kh0LCndnWQ== dependencies: - "@jest/console" "^27.4.2" - "@jest/environment" "^27.4.4" - "@jest/globals" "^27.4.4" + "@jest/environment" "^27.4.6" + "@jest/fake-timers" "^27.4.6" + "@jest/globals" "^27.4.6" "@jest/source-map" "^27.4.0" - "@jest/test-result" "^27.4.2" - "@jest/transform" "^27.4.4" + "@jest/test-result" "^27.4.6" + "@jest/transform" "^27.4.6" "@jest/types" "^27.4.2" - "@types/yargs" "^16.0.0" chalk "^4.0.0" cjs-module-lexer "^1.0.0" collect-v8-coverage "^1.0.0" execa "^5.0.0" - exit "^0.1.2" glob "^7.1.3" graceful-fs "^4.2.4" - jest-haste-map "^27.4.4" - jest-message-util "^27.4.2" - jest-mock "^27.4.2" + jest-haste-map "^27.4.6" + jest-message-util "^27.4.6" + jest-mock "^27.4.6" jest-regex-util "^27.4.0" - jest-resolve "^27.4.4" - jest-snapshot "^27.4.4" + jest-resolve "^27.4.6" + jest-snapshot "^27.4.6" jest-util "^27.4.2" - jest-validate "^27.4.2" slash "^3.0.0" strip-bom "^4.0.0" - yargs "^16.2.0" jest-serializer-path@^0.1.15: version "0.1.15" @@ -13715,7 +13723,7 @@ jest-serializer-path@^0.1.15: jest-serializer@^27.4.0: version "27.4.0" - resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-27.4.0.tgz#34866586e1cae2388b7d12ffa2c7819edef5958a" + resolved "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.4.0.tgz#34866586e1cae2388b7d12ffa2c7819edef5958a" integrity sha512-RDhpcn5f1JYTX2pvJAGDcnsNTnsV9bjYPU8xcV+xPwOXnUPOQwf4ZEuiU6G9H1UztH+OapMgu/ckEVwO87PwnQ== dependencies: "@types/node" "*" @@ -13729,34 +13737,32 @@ jest-silent-reporter@^0.5.0: chalk "^4.0.0" jest-util "^26.0.0" -jest-snapshot@^27.4.4: - version "27.4.4" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-27.4.4.tgz#fc0a2cd22f742fe66621c5359c9cd64f88260c6b" - integrity sha512-yy+rpCvYMOjTl7IMuaMI9OP9WT229zi8BhdNHm6e6mttAOIzvIiCxFoZ6yRxaV3HDPPgMryi+ReX2b8+IQJdPA== +jest-snapshot@^27.4.6: + version "27.4.6" + resolved "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.4.6.tgz#e2a3b4fff8bdce3033f2373b2e525d8b6871f616" + integrity sha512-fafUCDLQfzuNP9IRcEqaFAMzEe7u5BF7mude51wyWv7VRex60WznZIC7DfKTgSIlJa8aFzYmXclmN328aqSDmQ== dependencies: "@babel/core" "^7.7.2" "@babel/generator" "^7.7.2" - "@babel/parser" "^7.7.2" "@babel/plugin-syntax-typescript" "^7.7.2" "@babel/traverse" "^7.7.2" "@babel/types" "^7.0.0" - "@jest/transform" "^27.4.4" + "@jest/transform" "^27.4.6" "@jest/types" "^27.4.2" "@types/babel__traverse" "^7.0.4" "@types/prettier" "^2.1.5" babel-preset-current-node-syntax "^1.0.0" chalk "^4.0.0" - expect "^27.4.2" + expect "^27.4.6" graceful-fs "^4.2.4" - jest-diff "^27.4.2" + jest-diff "^27.4.6" jest-get-type "^27.4.0" - jest-haste-map "^27.4.4" - jest-matcher-utils "^27.4.2" - jest-message-util "^27.4.2" - jest-resolve "^27.4.4" + jest-haste-map "^27.4.6" + jest-matcher-utils "^27.4.6" + jest-message-util "^27.4.6" jest-util "^27.4.2" natural-compare "^1.4.0" - pretty-format "^27.4.2" + pretty-format "^27.4.6" semver "^7.3.2" jest-util@^26.0.0: @@ -13773,7 +13779,7 @@ jest-util@^26.0.0: jest-util@^27.4.2: version "27.4.2" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-27.4.2.tgz#ed95b05b1adfd761e2cda47e0144c6a58e05a621" + resolved "https://registry.npmjs.org/jest-util/-/jest-util-27.4.2.tgz#ed95b05b1adfd761e2cda47e0144c6a58e05a621" integrity sha512-YuxxpXU6nlMan9qyLuxHaMMOzXAl5aGZWCSzben5DhLHemYQxCc4YK+4L3ZrCutT8GPQ+ui9k5D8rUJoDioMnA== dependencies: "@jest/types" "^27.4.2" @@ -13783,24 +13789,24 @@ jest-util@^27.4.2: graceful-fs "^4.2.4" picomatch "^2.2.3" -jest-validate@^27.4.2: - version "27.4.2" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-27.4.2.tgz#eecfcc1b1c9429aa007da08a2bae4e32a81bbbc3" - integrity sha512-hWYsSUej+Fs8ZhOm5vhWzwSLmVaPAxRy+Mr+z5MzeaHm9AxUpXdoVMEW4R86y5gOobVfBsMFLk4Rb+QkiEpx1A== +jest-validate@^27.4.6: + version "27.4.6" + resolved "https://registry.npmjs.org/jest-validate/-/jest-validate-27.4.6.tgz#efc000acc4697b6cf4fa68c7f3f324c92d0c4f1f" + integrity sha512-872mEmCPVlBqbA5dToC57vA3yJaMRfIdpCoD3cyHWJOMx+SJwLNw0I71EkWs41oza/Er9Zno9XuTkRYCPDUJXQ== dependencies: "@jest/types" "^27.4.2" camelcase "^6.2.0" chalk "^4.0.0" jest-get-type "^27.4.0" leven "^3.1.0" - pretty-format "^27.4.2" + pretty-format "^27.4.6" -jest-watcher@^27.4.2: - version "27.4.2" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-27.4.2.tgz#c9037edfd80354c9fe90de4b6f8b6e2b8e736744" - integrity sha512-NJvMVyyBeXfDezhWzUOCOYZrUmkSCiatpjpm+nFUid74OZEHk6aMLrZAukIiFDwdbqp6mTM6Ui1w4oc+8EobQg== +jest-watcher@^27.4.6: + version "27.4.6" + resolved "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.4.6.tgz#673679ebeffdd3f94338c24f399b85efc932272d" + integrity sha512-yKQ20OMBiCDigbD0quhQKLkBO+ObGN79MO4nT7YaCuQ5SM+dkBNWE8cZX0FjU6czwMvWw6StWbe+Wv4jJPJ+fw== dependencies: - "@jest/test-result" "^27.4.2" + "@jest/test-result" "^27.4.6" "@jest/types" "^27.4.2" "@types/node" "*" ansi-escapes "^4.2.1" @@ -13817,23 +13823,23 @@ jest-worker@^26.2.1, jest-worker@^26.3.0: merge-stream "^2.0.0" supports-color "^7.0.0" -jest-worker@^27.0.6, jest-worker@^27.3.1, jest-worker@^27.4.4: - version "27.4.4" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.4.4.tgz#9390a97c013a54d07f5c2ad2b5f6109f30c4966d" - integrity sha512-jfwxYJvfua1b1XkyuyPh01ATmgg4e5fPM/muLmhy9Qc6dmiwacQB0MLHaU6IjEsv/+nAixHGxTn8WllA27Pn0w== +jest-worker@^27.0.6, jest-worker@^27.3.1, jest-worker@^27.4.6: + version "27.4.6" + resolved "https://registry.npmjs.org/jest-worker/-/jest-worker-27.4.6.tgz#5d2d93db419566cb680752ca0792780e71b3273e" + integrity sha512-gHWJF/6Xi5CTG5QCvROr6GcmpIqNYpDJyc8A1h/DyXqH1tD6SnRCM0d3U5msV31D2LB/U+E0M+W4oyvKV44oNw== dependencies: "@types/node" "*" merge-stream "^2.0.0" supports-color "^8.0.0" jest@^27.4.4: - version "27.4.4" - resolved "https://registry.yarnpkg.com/jest/-/jest-27.4.4.tgz#9b1aa1db25d0b13477a49d18e22ba7cdff97105b" - integrity sha512-AXwEIFa58Uf1Jno3/KSo5HZZ0/2Xwqvfrz0/3bmTwImkFlbOvz5vARAW9nTrxRLkojjkitaZ1KNKAtw3JRFAaA== + version "27.4.7" + resolved "https://registry.npmjs.org/jest/-/jest-27.4.7.tgz#87f74b9026a1592f2da05b4d258e57505f28eca4" + integrity sha512-8heYvsx7nV/m8m24Vk26Y87g73Ba6ueUd0MWed/NXMhSZIm62U/llVbS0PJe1SHunbyXjJ/BqG1z9bFjGUIvTg== dependencies: - "@jest/core" "^27.4.4" + "@jest/core" "^27.4.7" import-local "^3.0.2" - jest-cli "^27.4.4" + jest-cli "^27.4.7" jimp@^0.14.0: version "0.14.0" @@ -13973,7 +13979,7 @@ jsdom@15.2.1, jsdom@^15.0.0: jsdom@^16.6.0: version "16.7.0" - resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.7.0.tgz#918ae71965424b197c819f8183a754e18977b710" + resolved "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz#918ae71965424b197c819f8183a754e18977b710" integrity sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw== dependencies: abab "^2.0.5" @@ -14149,7 +14155,7 @@ jsprim@^1.2.2: "jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.2.1: version "3.2.1" - resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.2.1.tgz#720b97bfe7d901b927d87c3773637ae8ea48781b" + resolved "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.1.tgz#720b97bfe7d901b927d87c3773637ae8ea48781b" integrity sha512-uP5vu8xfy2F9A6LGC22KO7e2/vGTS1MhP+18f++ZNlf0Ohaxbc9nIEwHAsejlJKyzfZzU5UIhe5ItYkitcZnZA== dependencies: array-includes "^3.1.3" @@ -14688,7 +14694,7 @@ locate-path@^6.0.0: lock@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/lock/-/lock-1.1.0.tgz#53157499d1653b136ca66451071fca615703fa55" + resolved "https://registry.npmjs.org/lock/-/lock-1.1.0.tgz#53157499d1653b136ca66451071fca615703fa55" integrity sha1-UxV0mdFlOxNspmRRBx/KYVcD+lU= lockfile@1.0.4, lockfile@^1.0, lockfile@^1.0.4: @@ -15705,10 +15711,10 @@ merge-stream@^2.0.0: resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== -merge2@^1.2.3, merge2@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.3.0.tgz#5b366ee83b2f1582c48f87e47cf1a9352103ca81" - integrity sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw== +merge2@^1.2.3, merge2@^1.3.0, merge2@^1.4.1: + version "1.4.1" + resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== meros@^1.1.2: version "1.1.4" @@ -15767,7 +15773,7 @@ microbundle@^0.13.0: microbundle@^0.14.2: version "0.14.2" - resolved "https://registry.yarnpkg.com/microbundle/-/microbundle-0.14.2.tgz#2db869c8145bd159aa55058ead47223f58f93bf2" + resolved "https://registry.npmjs.org/microbundle/-/microbundle-0.14.2.tgz#2db869c8145bd159aa55058ead47223f58f93bf2" integrity sha512-jODALfU3w7jnJAqw7Tou9uU8e8zH0GRVWzOd/V7eAvD1fsfb9pyMbmzhFZqnX6SCb54eP1EF5oRyNlSxBAxoag== dependencies: "@babel/core" "^7.12.10" @@ -15985,7 +15991,7 @@ min-indent@^1.0.0: mini-css-extract-plugin@1.6.2: version "1.6.2" - resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-1.6.2.tgz#83172b4fd812f8fc4a09d6f6d16f924f53990ca8" + resolved "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-1.6.2.tgz#83172b4fd812f8fc4a09d6f6d16f924f53990ca8" integrity sha512-WhDvO3SjGm40oV5y26GjMJYjd2UMqrLAGKy5YS2/3QKJy2F7jgynuHTir/tgUUOiNQu5saXHdc8reo7YuhhT4Q== dependencies: loader-utils "^2.0.0" @@ -16210,7 +16216,7 @@ msw@^0.35.0: msw@^0.36.3: version "0.36.3" - resolved "https://registry.yarnpkg.com/msw/-/msw-0.36.3.tgz#7feb243a5fcf563806d45edc027bc36144741170" + resolved "https://registry.npmjs.org/msw/-/msw-0.36.3.tgz#7feb243a5fcf563806d45edc027bc36144741170" integrity sha512-Itzp/QhKaleZoslXDrNik3ramW9ynqzOdbwydX2ehBSSaZd5QoiAl/bHYcV33R6CEZcJgIX1N4s+G6XkF/bhkA== dependencies: "@mswjs/cookies" "^0.1.6" @@ -16457,7 +16463,7 @@ nock@^13.2.2: node-abi@^3.3.0: version "3.5.0" - resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.5.0.tgz#26e8b7b251c3260a5ac5ba5aef3b4345a0229248" + resolved "https://registry.npmjs.org/node-abi/-/node-abi-3.5.0.tgz#26e8b7b251c3260a5ac5ba5aef3b4345a0229248" integrity sha512-LtHvNIBgOy5mO8mPEUtkCW/YCRWYEKshIvqhe1GHHyXEHEB5mgICyYnAcl4qan3uFeRROErKGzatFHPf6kDxWw== dependencies: semver "^7.3.5" @@ -16555,13 +16561,9 @@ node-match-path@^0.6.3: resolved "https://registry.yarnpkg.com/node-match-path/-/node-match-path-0.6.3.tgz#55dd8443d547f066937a0752dce462ea7dc27551" integrity sha512-fB1reOHKLRZCJMAka28hIxCwQLxGmd7WewOCBDYKpyA1KXi68A7vaGgdZAPhY2E6SXoYt3KqYCCvXLJ+O0Fu/Q== -node-modules-regexp@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40" - node-notifier@^10.0.0: version "10.0.0" - resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-10.0.0.tgz#93c154055b07b550a33a1966a1b11291c2113e69" + resolved "https://registry.npmjs.org/node-notifier/-/node-notifier-10.0.0.tgz#93c154055b07b550a33a1966a1b11291c2113e69" integrity sha512-ZTqP90y1eyb2xAZTa7j4AlAayTwh6cL8mn0nlJhLDq8itXGnJUmQGYOnpaMUvqZVfGo0vhU7KZ3HtDW6CT2SiQ== dependencies: growly "^1.3.0" @@ -16903,7 +16905,7 @@ object.defaults@^1.1.0: object.entries@^1.1.5: version "1.1.5" - resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.5.tgz#e1acdd17c4de2cd96d5a08487cfb9db84d881861" + resolved "https://registry.npmjs.org/object.entries/-/object.entries-1.1.5.tgz#e1acdd17c4de2cd96d5a08487cfb9db84d881861" integrity sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g== dependencies: call-bind "^1.0.2" @@ -16912,7 +16914,7 @@ object.entries@^1.1.5: object.fromentries@^2.0.5: version "2.0.5" - resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.5.tgz#7b37b205109c21e741e605727fe8b0ad5fa08251" + resolved "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.5.tgz#7b37b205109c21e741e605727fe8b0ad5fa08251" integrity sha512-CAyG5mWQRRiBU57Re4FKoTBjXfDoNwdFVH2Y1tS9PqCsfUTymAohOkEMSG3aRNKmv4lV3O7p1et7c187q6bynw== dependencies: call-bind "^1.0.2" @@ -16929,7 +16931,7 @@ object.getownpropertydescriptors@^2.0.3, object.getownpropertydescriptors@^2.1.0 object.hasown@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/object.hasown/-/object.hasown-1.1.0.tgz#7232ed266f34d197d15cac5880232f7a4790afe5" + resolved "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.0.tgz#7232ed266f34d197d15cac5880232f7a4790afe5" integrity sha512-MhjYRfj3GBlhSkDHo6QmvgjRLXQ2zndabdf3nX0yTyZK9rPfxb6uRpAac8HXNLy1GpqWtZ81Qh4v3uOls2sRAg== dependencies: define-properties "^1.1.3" @@ -17061,7 +17063,7 @@ optionator@^0.9.1: ora@^5.4.1: version "5.4.1" - resolved "https://registry.yarnpkg.com/ora/-/ora-5.4.1.tgz#1b2678426af4ac4a509008e5e4ac9e9959db9e18" + resolved "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz#1b2678426af4ac4a509008e5e4ac9e9959db9e18" integrity sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ== dependencies: bl "^4.1.0" @@ -17285,7 +17287,7 @@ p-some@^4.0.0: p-throttle@^4.1.1: version "4.1.1" - resolved "https://registry.yarnpkg.com/p-throttle/-/p-throttle-4.1.1.tgz#80b1fbd358af40a8bfa1667f9dc8b72b714ad692" + resolved "https://registry.npmjs.org/p-throttle/-/p-throttle-4.1.1.tgz#80b1fbd358af40a8bfa1667f9dc8b72b714ad692" integrity sha512-TuU8Ato+pRTPJoDzYD4s7ocJYcNSEZRvlxoq3hcPI2kZDZ49IQ1Wkj7/gDJc3X7XiEAAvRGtDzdXJI0tC3IL1g== p-timeout@^3.0.0, p-timeout@^3.1.0, p-timeout@^3.2.0: @@ -17660,7 +17662,7 @@ path-to-regexp@^1.0.1: path-to-regexp@^6.2.0: version "6.2.0" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-6.2.0.tgz#f7b3803336104c346889adece614669230645f38" + resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.0.tgz#f7b3803336104c346889adece614669230645f38" integrity sha512-f66KywYG6+43afgE/8j/GoiNyygk/bnoCbps++3ErRKsIYkGGupyv07R2Ok5m9i67Iqc+T2g1eAUGUPzWhYTyg== path-type@^1.0.0: @@ -17781,12 +17783,10 @@ pinpoint@^1.1.0: resolved "https://registry.yarnpkg.com/pinpoint/-/pinpoint-1.1.0.tgz#0cf7757a6977f1bf7f6a32207b709e377388e874" integrity sha1-DPd1eml38b9/ajIge3CeN3OI6HQ= -pirates@^4.0.0, pirates@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.1.tgz#643a92caf894566f91b2b986d2c66950a8e2fb87" - integrity sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA== - dependencies: - node-modules-regexp "^1.0.0" +pirates@^4.0.0, pirates@^4.0.4: + version "4.0.4" + resolved "https://registry.npmjs.org/pirates/-/pirates-4.0.4.tgz#07df81e61028e402735cdd49db701e4885b4e6e6" + integrity sha512-ZIrVPH+A52Dw84R0L3/VS9Op04PuQ2SEoJL6bkshmiTic/HldyW9Tf7oH5mhJZBK7NmDx27vSMrYEXPXclpDKw== pixelmatch@^4.0.2: version "4.0.2" @@ -18483,7 +18483,7 @@ postcss-value-parser@^3.0.0, postcss-value-parser@^3.3.0, postcss-value-parser@^ postcss-value-parser@^4.0.2, postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0: version "4.2.0" - resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" + resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== postcss@6.0.1: @@ -18538,12 +18538,12 @@ potrace@^2.1.8: preact@^10.6.4: version "10.6.4" - resolved "https://registry.yarnpkg.com/preact/-/preact-10.6.4.tgz#ad12c409ff1b4316158486e0a7b8d43636f7ced8" + resolved "https://registry.npmjs.org/preact/-/preact-10.6.4.tgz#ad12c409ff1b4316158486e0a7b8d43636f7ced8" integrity sha512-WyosM7pxGcndU8hY0OQlLd54tOU+qmG45QXj2dAYrL11HoyU/EzOSTlpJsirbBr1QW7lICxSsVJJmcmUglovHQ== prebuild-install@^7.0.0: version "7.0.0" - resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.0.0.tgz#3c5ce3902f1cb9d6de5ae94ca53575e4af0c1574" + resolved "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.0.0.tgz#3c5ce3902f1cb9d6de5ae94ca53575e4af0c1574" integrity sha512-IvSenf33K7JcgddNz2D5w521EgO+4aMMjFt73Uk9FRzQ7P+QZPKrp7qPsDydsSwjGt3T5xRNnM1bj1zMTD5fTA== dependencies: detect-libc "^1.0.3" @@ -18592,7 +18592,7 @@ prettier-linter-helpers@^1.0.0: prettier@2.5.1, prettier@^2.5.1: version "2.5.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.5.1.tgz#fff75fa9d519c54cf0fce328c1017d94546bc56a" + resolved "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz#fff75fa9d519c54cf0fce328c1017d94546bc56a" integrity sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg== pretty-bytes@^3.0.0: @@ -18669,12 +18669,11 @@ pretty-format@^26.6.2: ansi-styles "^4.0.0" react-is "^17.0.1" -pretty-format@^27.0.0, pretty-format@^27.0.2, pretty-format@^27.4.2: - version "27.4.2" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.4.2.tgz#e4ce92ad66c3888423d332b40477c87d1dac1fb8" - integrity sha512-p0wNtJ9oLuvgOQDEIZ9zQjZffK7KtyR6Si0jnXULIDwrlNF8Cuir3AZP0hHv0jmKuNN/edOnbMjnzd4uTcmWiw== +pretty-format@^27.0.0, pretty-format@^27.0.2, pretty-format@^27.4.6: + version "27.4.6" + resolved "https://registry.npmjs.org/pretty-format/-/pretty-format-27.4.6.tgz#1b784d2f53c68db31797b2348fa39b49e31846b7" + integrity sha512-NblstegA1y/RJW2VyML+3LlpFjzx62cUrtBIKIWDXEDkjNeleA7Od7nrzcs/VLQvAeV4CgSYhrN39DRN88Qi/g== dependencies: - "@jest/types" "^27.4.2" ansi-regex "^5.0.1" ansi-styles "^5.0.0" react-is "^17.0.1" @@ -18975,7 +18974,7 @@ qs@6.7.0: qs@6.9.6: version "6.9.6" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.6.tgz#26ed3c8243a431b2924aca84cc90471f35d5a0ee" + resolved "https://registry.npmjs.org/qs/-/qs-6.9.6.tgz#26ed3c8243a431b2924aca84cc90471f35d5a0ee" integrity sha512-TIRk4aqYLNoJUbd+g2lEdz5kLWIuTMRagAXxl78Q0RiVjAOugHmeKNGdd3cwo/ktpf9aL9epCfFqWDEKysUlLQ== qs@^6.1.0, qs@^6.4.0, qs@^6.5.2, qs@^6.9.4: @@ -19067,7 +19066,7 @@ raw-body@2.4.0: raw-body@2.4.2, raw-body@^2.4.1: version "2.4.2" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.2.tgz#baf3e9c21eebced59dd6533ac872b71f7b61cb32" + resolved "https://registry.npmjs.org/raw-body/-/raw-body-2.4.2.tgz#baf3e9c21eebced59dd6533ac872b71f7b61cb32" integrity sha512-RPMAFUJP19WIet/99ngh6Iv8fzAbqum4Li7AD6DtGaW2RpMB/11xDoalPiJMTbu6I3hkbMVkATvZrqb9EEqeeQ== dependencies: bytes "3.1.1" @@ -20716,7 +20715,7 @@ resolve-options@^1.1.0: resolve-url-loader@^3.1.4: version "3.1.4" - resolved "https://registry.yarnpkg.com/resolve-url-loader/-/resolve-url-loader-3.1.4.tgz#3c16caebe0b9faea9c7cc252fa49d2353c412320" + resolved "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-3.1.4.tgz#3c16caebe0b9faea9c7cc252fa49d2353c412320" integrity sha512-D3sQ04o0eeQEySLrcz4DsX3saHfsr8/N6tfhblxgZKXxMT2Louargg12oGNfoTRLV09GXhVUe5/qgA5vdgNigg== dependencies: adjust-sourcemap-loader "3.0.0" @@ -20736,7 +20735,7 @@ resolve-url@^0.2.1: resolve.exports@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.0.tgz#5ce842b94b05146c0e03076985d1d0e7e48c90c9" + resolved "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz#5ce842b94b05146c0e03076985d1d0e7e48c90c9" integrity sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ== resolve@1.1.7: @@ -20955,7 +20954,7 @@ reusify@^1.0.4: rewire@^6.0.0: version "6.0.0" - resolved "https://registry.yarnpkg.com/rewire/-/rewire-6.0.0.tgz#54f4fcda4df9928d28af1eb54a318bc51ca9aa99" + resolved "https://registry.npmjs.org/rewire/-/rewire-6.0.0.tgz#54f4fcda4df9928d28af1eb54a318bc51ca9aa99" integrity sha512-7sZdz5dptqBCapJYocw9EcppLU62KMEqDLIILJnNET2iqzXHaQfaVP5SOJ06XvjX+dNIDJbzjw0ZWzrgDhtjYg== dependencies: eslint "^7.32.0" @@ -21461,7 +21460,7 @@ shallow-copy@~0.0.1: sharp@^0.29.3: version "0.29.3" - resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.29.3.tgz#0da183d626094c974516a48fab9b3e4ba92eb5c2" + resolved "https://registry.npmjs.org/sharp/-/sharp-0.29.3.tgz#0da183d626094c974516a48fab9b3e4ba92eb5c2" integrity sha512-fKWUuOw77E4nhpyzCCJR1ayrttHoFHBT2U/kR/qEMRhvPEcluG4BKj324+SCO1e84+knXHwhJ1HHJGnUt4ElGA== dependencies: color "^4.0.1" @@ -21512,7 +21511,6 @@ shelljs@^0.8.3: shellwords@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" - integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww== shift-left@^0.1.5: version "0.1.5" @@ -21535,7 +21533,7 @@ sift@^7.0.1: signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.5, signal-exit@^3.0.6: version "3.0.6" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.6.tgz#24e630c4b0f03fea446a2bd299e62b4a6ca8d0af" + resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz#24e630c4b0f03fea446a2bd299e62b4a6ca8d0af" integrity sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ== simple-concat@^1.0.0: @@ -21544,7 +21542,7 @@ simple-concat@^1.0.0: simple-get@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-4.0.0.tgz#73fa628278d21de83dadd5512d2cc1f4872bd675" + resolved "https://registry.npmjs.org/simple-get/-/simple-get-4.0.0.tgz#73fa628278d21de83dadd5512d2cc1f4872bd675" integrity sha512-ZalZGexYr3TA0SwySsr5HlgOOinS4Jsa8YB2GJ6lUNAazyAu4KG/VmzMTwAt2YVXzzVj8QmefmAonZIK2BSGcQ== dependencies: decompress-response "^6.0.0" @@ -21733,7 +21731,7 @@ source-list-map@^1.1.1: source-list-map@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" + resolved "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== source-map-js@^0.6.2: @@ -21942,7 +21940,7 @@ stack-utils@^1.0.1: stack-utils@^2.0.2, stack-utils@^2.0.3: version "2.0.5" - resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.5.tgz#d25265fca995154659dbbfba3b49254778d2fdd5" + resolved "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz#d25265fca995154659dbbfba3b49254778d2fdd5" integrity sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA== dependencies: escape-string-regexp "^2.0.0" @@ -22159,7 +22157,7 @@ string-width@^3.0.0, string-width@^3.1.0: string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== dependencies: emoji-regex "^8.0.0" @@ -22168,7 +22166,7 @@ string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2 string.prototype.matchall@^4.0.6: version "4.0.6" - resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.6.tgz#5abb5dabc94c7b0ea2380f65ba610b3a544b15fa" + resolved "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.6.tgz#5abb5dabc94c7b0ea2380f65ba610b3a544b15fa" integrity sha512-6WgDX8HmQqvEd7J+G6VtAahhsQIssiZ8zl7zKh1VDMFyL3hRTJP4FTNA3RbIp2TOQ9AYNDcc7e3fH0Qbup+DBg== dependencies: call-bind "^1.0.2" @@ -22285,7 +22283,7 @@ strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== dependencies: ansi-regex "^5.0.1" @@ -22886,7 +22884,7 @@ thenify-all@^1.0.0: throat@^6.0.1: version "6.0.1" - resolved "https://registry.yarnpkg.com/throat/-/throat-6.0.1.tgz#d514fedad95740c12c2d7fc70ea863eb51ade375" + resolved "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz#d514fedad95740c12c2d7fc70ea863eb51ade375" integrity sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w== through2-filter@^2.0.0: @@ -23085,7 +23083,7 @@ toidentifier@1.0.0: toidentifier@1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + resolved "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== token-types@^2.0.0: @@ -23154,10 +23152,10 @@ tr46@^1.0.1: dependencies: punycode "^2.1.0" -tr46@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.1.0.tgz#fa87aa81ca5d5941da8cbf1f9b749dc969a4e240" - integrity sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw== +tr46@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.0.2.tgz#03273586def1595ae08fedb38d7733cee91d2479" + integrity sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg== dependencies: punycode "^2.1.1" @@ -23242,7 +23240,7 @@ tsc-watch@^4.5.0: tsconfig-paths@^3.12.0: version "3.12.0" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz#19769aca6ee8f6a1a341e38c8fa45dd9fb18899b" + resolved "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz#19769aca6ee8f6a1a341e38c8fa45dd9fb18899b" integrity sha512-e5adrnOYT6zqVnWqZu7i/BQ3BnhzvGbjEjejFXO20lKIKpwTaupkCPgEfv4GZK1IBciJUEhYs3J3p75FdaTFVg== dependencies: "@types/json5" "^0.0.29" @@ -23891,7 +23889,6 @@ universal-user-agent@^6.0.0: universalify@^0.1.0, universalify@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" - integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== universalify@^1.0.0: version "1.0.0" @@ -24120,7 +24117,7 @@ v8-to-istanbul@^7.1.0: v8-to-istanbul@^8.1.0: version "8.1.0" - resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-8.1.0.tgz#0aeb763894f1a0a1676adf8a8b7612a38902446c" + resolved "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.0.tgz#0aeb763894f1a0a1676adf8a8b7612a38902446c" integrity sha512-/PRhfd8aTNp9Ggr62HPzXg2XasNFGy5PBt0Rp04du7/8GNNSgxFL6WBTkgMKSL9bFjH+8kKEG3f37FmxiTqUUA== dependencies: "@types/istanbul-lib-coverage" "^2.0.1" @@ -24536,7 +24533,7 @@ webpack-sources@^0.2.0: webpack-sources@^1.1.0: version "1.4.3" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" + resolved "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== dependencies: source-list-map "^2.0.0" @@ -24650,12 +24647,12 @@ whatwg-url@^7.0.0: webidl-conversions "^4.0.2" whatwg-url@^8.0.0, whatwg-url@^8.5.0: - version "8.7.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.7.0.tgz#656a78e510ff8f3937bc0bcbe9f5c0ac35941b77" - integrity sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg== + version "8.5.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.5.0.tgz#7752b8464fc0903fec89aa9846fc9efe07351fd3" + integrity sha512-fy+R77xWv0AiqfLl4nuGUlQ3/6b5uNfQ4WAbGQVMYshCTCCPK9psC1nWh3XHuxGVCtlcDDQPQW1csmmIQo+fwg== dependencies: lodash "^4.7.0" - tr46 "^2.1.0" + tr46 "^2.0.2" webidl-conversions "^6.1.0" when@~3.6.x: @@ -25033,7 +25030,7 @@ xhr@^2.0.1: xlsx@^0.17.4: version "0.17.4" - resolved "https://registry.yarnpkg.com/xlsx/-/xlsx-0.17.4.tgz#dc3e3a0954c835f4d0fdd643645db6f4ac3f28f2" + resolved "https://registry.npmjs.org/xlsx/-/xlsx-0.17.4.tgz#dc3e3a0954c835f4d0fdd643645db6f4ac3f28f2" integrity sha512-9aKt8g9ZLP0CUdBX8L5xnoMDFwSiLI997eQnDThCaqQMYB9AEBIRzblSSNN/ICMGLYIHUO3VKaItcedZJ3ijIg== dependencies: adler-32 "~1.2.0" @@ -25100,9 +25097,9 @@ xss@^1.0.6: cssfilter "0.0.10" xstate@^4.26.0, xstate@^4.26.1: - version "4.26.1" - resolved "https://registry.yarnpkg.com/xstate/-/xstate-4.26.1.tgz#4fc1afd153f88cf302a9ee2b758f6629e6a829b6" - integrity sha512-JLofAEnN26l/1vbODgsDa+Phqa61PwDlxWu8+2pK+YbXf+y9pQSDLRvcYH2H1kkeUBA5fGp+xFL/zfE8jNMw4g== + version "4.27.0" + resolved "https://registry.npmjs.org/xstate/-/xstate-4.27.0.tgz#f3c918ac4229bd5e6dec2231e991ba55c6bfa559" + integrity sha512-ohOwDM9tViC/zSSmY9261CHblDPqiaAk5vyjVbi69uJv9fGWMzlm0VDQwM2OvC61GKfXVBeuWSMkL7LPUsTpfA== xtend@^4.0.0, xtend@^4.0.1, xtend@^4.0.2, xtend@~4.0.0, xtend@~4.0.1: version "4.0.2" @@ -25185,7 +25182,7 @@ yargs-parser@^20.2.2, yargs-parser@^20.2.3, yargs-parser@^20.2.7: yargs-parser@^21.0.0: version "21.0.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.0.0.tgz#a485d3966be4317426dd56bdb6a30131b281dc55" + resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.0.tgz#a485d3966be4317426dd56bdb6a30131b281dc55" integrity sha512-z9kApYUOCwoeZ78rfRYYWdiU/iNL6mwwYlkkZfJoyMR1xps+NEBX5X7XmRpxkZHhXJ6+Ey00IwKxBBSW9FIjyA== yargs@16.2.0, yargs@^16.2.0: @@ -25253,7 +25250,7 @@ yargs@^15.3.1, yargs@^15.4.0, yargs@^15.4.1: yargs@^17.0.1, yargs@^17.3.0: version "17.3.1" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.3.1.tgz#da56b28f32e2fd45aefb402ed9c26f42be4c07b9" + resolved "https://registry.npmjs.org/yargs/-/yargs-17.3.1.tgz#da56b28f32e2fd45aefb402ed9c26f42be4c07b9" integrity sha512-WUANQeVgjLbNsEmGk20f+nlHgOqzRFpiGWVaBrYGYIGANIIu3lWjoyi0fNlFmJkvfhCZ6BXINe7/W2O2bV4iaA== dependencies: cliui "^7.0.2" 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 16/34] 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 From d5c5d3755ac0995dfae5c8504cb8b060b1171b16 Mon Sep 17 00:00:00 2001 From: axe312ger Date: Thu, 20 May 2021 16:10:29 +0200 Subject: [PATCH 17/34] update e2e snapshots --- e2e-tests/contentful/snapshots.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/e2e-tests/contentful/snapshots.js b/e2e-tests/contentful/snapshots.js index 3cb165766826f..510ac872b98fd 100644 --- a/e2e-tests/contentful/snapshots.js +++ b/e2e-tests/contentful/snapshots.js @@ -45,14 +45,17 @@ module.exports = { "rich-text: Embedded Entry With Reference Loop": { "1": "
\n

Rich Text: Embedded entry with reference loop

\n

Embedded entry with reference loop

\n

[ContentfulReference]\n Content Reference: One (Loop B -> A)\n : [\n Content Reference: One (Loop A -> B)\n ]

\n

\n
\n
" }, + "rich-text: All Features": { + "1": "
\n

Rich Text: All Features

\n

The European languages

\n

are members of the same family. Their separate existence is a myth. For:

\n
    \n
  • \n

    science

    \n
  • \n
  • \n

    music

    \n
  • \n
  • \n

    sport

    \n
  • \n
  • \n

    etc

    \n
  • \n
\n

Europe uses the same vocabulary.

\n
\n
\"\"\n\n \n \n \n
\n

\n
\n

The languages only differ in:

\n
    \n
  1. \n

    their grammar

    \n
  2. \n
  3. \n

    their pronunciation

    \n
  4. \n
  5. \n

    their most common words

    \n
  6. \n
  7. \n

    [Inline-ContentfulText]\n :

    \n
  8. \n
\n

Everyone realizes why a new common language would be desirable: one could\n refuse to pay expensive translators.

\n

{\n \"userId\": 1,\n \"id\": 1,\n \"title\": \"delectus aut autem\",\n \"completed\": false\n }

\n

To achieve this, it would be necessary to have uniform grammar,\n pronunciation and more common words.

\n

[ContentfulLocation] Lat:\n 52.51627\n , Long:\n 13.3777

\n
\n

If several languages coalesce, the grammar of the resulting language is\n more simple and regular than that of the individual languages.

\n
\n

The new common language will be more simple and regular than the existing\n European languages. It will be as simple as Occidental; in fact, it will be\n

\n
\n
" + }, "rich-text: Inline Entry": { - "1": "
\n

Rich Text: Inline entry

\n

Inline entry with reference loop

\n

Should be rendered after this [Inline-ContentfulText]\n Text: Short\n :\n The quick brown fox jumps over the lazy dog. and before\n that

\n

\n

\n
\n
" + "1": "
\n

Rich Text: Inline entry

\n

Inline entry with reference loop

\n

Should be rendered after this [Inline-ContentfulText]\n : and before that

\n

\n

\n
\n
" }, "rich-text: Inline Entry With Deep Reference Loop": { - "1": "
\n

Rich Text: Inline entry with deep reference loop

\n

Inline entry with deep reference loop

\n

Should be rendered after this [Inline-\n ContentfulContentReference\n ]\n Content Reference: Many (2nd level loop) and before that\n

\n

\n

\n
\n
" + "1": "
\n

Rich Text: Inline entry with deep reference loop

\n

Inline entry with deep reference loop

\n

Should be rendered after this [Inline-\n ContentfulContentReference\n ] and before that

\n

\n

\n
\n
" }, "rich-text: Inline Entry With Reference Loop": { - "1": "
\n

Rich Text: Inline entry with reference loop

\n

Inline entry with reference loop

\n

Should be rendered after this [Inline-\n ContentfulContentReference\n ]\n Content Reference: One (Loop A -> B) and before that

\n

\n

\n
\n
" + "1": "
\n

Rich Text: Inline entry with reference loop

\n

Inline entry with reference loop

\n

Should be rendered after this [Inline-\n ContentfulContentReference\n ] and before that

\n

\n

\n
\n
", }, "rich-text: Localized": { "1": "
\n

Rich Text: Localized

\n

Rich Text in English

\n
\n
", From 9a4da0ebf0905116513d0dc661f08f21ed6d3732 Mon Sep 17 00:00:00 2001 From: axe312ger Date: Fri, 11 Jun 2021 10:18:28 +0200 Subject: [PATCH 18/34] fix: render RichText without links --- packages/gatsby-source-contentful/src/rich-text.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/gatsby-source-contentful/src/rich-text.js b/packages/gatsby-source-contentful/src/rich-text.js index 0019e715e59fc..26e3e19fe4a76 100644 --- a/packages/gatsby-source-contentful/src/rich-text.js +++ b/packages/gatsby-source-contentful/src/rich-text.js @@ -18,27 +18,27 @@ exports.renderRichText = renderRichText */ function generateLinkMaps(links) { const assetBlockMap = new Map() - for (const asset of links.assets.block || []) { + for (const asset of links?.assets.block || []) { assetBlockMap.set(asset.sys.id, asset) } const assetHyperlinkMap = new Map() - for (const asset of links.assets.hyperlink || []) { + for (const asset of links?.assets.hyperlink || []) { assetHyperlinkMap.set(asset.sys.id, asset) } const entryBlockMap = new Map() - for (const entry of links.entries.block || []) { + for (const entry of links?.entries.block || []) { entryBlockMap.set(entry.sys.id, entry) } const entryInlineMap = new Map() - for (const entry of links.entries.inline || []) { + for (const entry of links?.entries.inline || []) { entryInlineMap.set(entry.sys.id, entry) } const entryHyperlinkMap = new Map() - for (const entry of links.entries.hyperlink || []) { + for (const entry of links?.entries.hyperlink || []) { entryHyperlinkMap.set(entry.sys.id, entry) } From 0414814987b82467ee7642c0883f2474d05b7452 Mon Sep 17 00:00:00 2001 From: axe312ger Date: Fri, 11 Jun 2021 10:27:42 +0200 Subject: [PATCH 19/34] test(e2e): update snapshots --- .../gatsby-plugin-image.js/german-0.snap.png | Bin 4168 -> 2570 bytes e2e-tests/contentful/snapshots.js | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e-tests/contentful/cypress/snapshots/gatsby-plugin-image.js/german-0.snap.png b/e2e-tests/contentful/cypress/snapshots/gatsby-plugin-image.js/german-0.snap.png index e6f13231933f9e761eda1ea416b7ef7fcf8c6632..95de3c6a3c374eb622afd9bc6324232b9664610d 100644 GIT binary patch literal 2570 zcmds3VNeri8cwzeT@qmeCdMPQBsSGx<|x%eaLQ>&jLpiSX^?Oz3(_+byp#*Y$0q5IfNH z=mxC#ljPm5$FD%?r^c=%AF`6hRYHDcEUEoBC!=xVa;K%3W#c4vB1uRJ;BXmjCK z3u=$m^n15T+Jp)}Lf2*nEJZ1!M9K z_Ipd1Lo|Jn9My$t-Yv+L>O!LQS!(IL9PE+fpDt;7t=n2|Y!4!ao* z2zG4NI(^?HfOyqUtfUY8Pf;K=u~eDy?S$L3O|OrB(u!))kted%<(qTgFEzEpuW zx(EOG!JdBa2qR%#4{RkAUxVT&OAf=T(UVWgbfJ~32MRrG>8ap!DNm@-OQVQO)91aL zwL=kUi;To!OAGw&c+ELNitT(0?nld1PCJ*BMSJA$%uj3Cu!0-zV-?O*5B?^BE{-d@ zP~Oj87D*ci`{%=Ldtp5C)EiBi4Mz*y8?f4=odWp}GvTrvb;6i9Sm<2-t)$InJ{#NL z$~aV(BUN>q*UEpex7frNqSQQ`gs=!bue6(eL2}aai_ON8i;azm&0K^{(v`!igExg# z(U*se?OaNhf+iNNZ#UJpvorkTN_}=3oO&eDdT>-Eh>faA5UoOZ5yC5uv3vqYUNCBqd+ z^E`s~$i^r++Lw}%mjC7SlSkrxT!R5EkPBM(yqZv$49}CJg64=U$ZIk_Ps;xr@pnI& zVnPZZ2A{fBxjO0G1=Truc}Y0~;7ZH|`^mVzVDS7dcPMX&0dTWp51bRm_2Y&5jhXwh z_Avl%0&hEqaXlbZoUvVe?;-<02VOqHxQ_E&7+HP0ngO5#FWU;P(?wiLPG6!682~!) z>?&~Gd=@b|WA{OZ$!P{U@HA3zeWKF31?zYdWNg7EfDSwv<9b^DSjCB)JA|f8+)USZ zh#H8xUuw2+{R;}8b=y^80-q?H5t1d$pe4*zR0&~zO;&%#QYEY3kIs1Ot5LD&Ka`P{ zLc6L%Ay^=*!WSM-#TxpTABE92cPUvl;9lex5P1LcE8kKQT5E-SySmQPxvy{eV%S-n zSy>Y7_0He_I(EstR_B?!)>$JhcO3&4MugZGm#)x7b1pGAcZlc0yOF~A8V{{U_1P7n z#ltU@zo?g*#Gc0nF6qnf@y`Es`q_wVN)d>E-|O9ZZ(71dT!XRwdpQb!aiMedHwVi& z3V0n(<#?hbJPiiT;#MB?X{|gb*L&DJS^)Wx_psY|*r5h(>)|=v9uX+~F-P2JMIsJ_ z3p!_a4-j=8g2m=}J1@_1$Y%+2wLB@?cE@#t)S7bT$u}}KkwvP+%j_QS&hMr-k*8zE z?)Y;Rp@P?Ay9c=F3dwHJkJSXS<-jill?pyvF2^)QUeEjJ-Z?b)SUJ3)}xBXrQ_Kf^4;^TwG(BGsM zh+kU1O8xkuUuZ0R^uSwfkUsQRxUkSA?JL_)>`qPi{^8f{zaAUD;CcRsU2yZ|`t@7Q zVfd1k6f+cB(IPlw3ai+AAO*O%|9Ab163@$lGR2pZ-!X?RZFI>}%$GkcZ%H9v46A5S z%-2-4q>R7o>0O)gMm=jYt9dWZmObtnpk|2O<+(reN<|B4zSHAYq1C*ldPO#WvbmTS zE}t`UPf&sM2rIS5l?nw3 zRY81z8w-xJ5RChOHkcbcx4w5oy0UOZ>}MbbWPeuGHfJP@NQ68GOSM@9(IRZ>H0mSy z)?Bt~*7Odvlo(kRWE`*5(6+&GGM>&%uL{!7o~ztuq8)CW4e=Msq;tMH(j5x@a5-Kd zq8t`$m{@(kI=~BOBE)N%kIFCgJAyHj8_J7QVWJnVWGQB{nfItDwdV!fsSKkR?oii2 znohAGH*>sfpR=T1xN>D194FH4`CKgbvJnuh7j8_@I%m9R??e(KFxbux4P!uk9aycHLwTVMMGIFOnC4qX1k=AV-?TfY846tI>M2tjY zO4q$E2z@+QY9xd8$2(rDY@QG&JEKJcnKYxhn7XseRIkPB6hI65)W+Smq{W>E8Sk>5 zy|z0LJ|99odOoYz*LetH-5tFdLPeb}q!wb$6!|(0&-VUgisZ`k4`*Ro!-oTD+)Puw zb3_C+oEJflklLT~w9`Jl(cfRm48+6=bFO3BS4!7*cW>=s#|!Vw4&)+Zj`j@ggqed3 zSO_YZ{?CY*(G7De+J21WY1=XmRiicD$Wo$^%~vwf8gFFVAOOpr6Z+0yM|%2R#sh!Fu%zTVCi$6aSdzfiWo)wdAnL!aM+VZ9 zdXW9G*;C)u0LK9nl61L#MA{mqXe0 z3wEqm3tGjW&!z@Ynm$2=WhufE85^NY?9sRn4;f**xud>S*TBTNY z#gwL|DQT?oTDV(eb^4j>$kj#@{Y+EFp{dGupY$*K8GfU{L!sbT(0}!YLbBzD zdr76iT+M`8@p5`HqP(S=5a%CITL{U7`6*5M_8N-~`p=8q52neBj5R)@Xd;(3EjGmc zaBm9_wQs1?qaN6R?cHE_nuAB}uJ3NVb!7!u{`Q)z+a}ZoNuHb`qxS4A)%!;rz}`H$ z*f5~D`+8PzMT_J9ydh8@9mzOtC6gF|e5aXF)#7md&b5QFl<2N>78u7D|BQMjR?gxu z;H6cjn6DcgwL(pbd4*#?77hA)cCCw}R?u{Wik7^EwO#o6ZNkAw0F!d;TYJUT8$+b0 z`&&|`Yh5~)9&8h3yU}gcK3y0Oc9JOl^Rugcqr-h7Ex_y0KOX3jgPivl3>>hwD1H5w zNPy$sq9{v5k00ri+4@%UMe?yP3p%3!HK(r3s=jKgJIFo!#|}8GqT#;1&e?uyM?;9@ ziT<7xU|KRKN3TgHN{qI;LNuW&A66T)O~ru#pFh7geugZfF57ympnNv)km@|G1!jX)&jSnCZ?d-vi@?s8C33C5F~Sv66Usa1tRQ-O zA!_i-KDB!=P02(hK!4*qg=#f%kQh6;33#T3d}n)ArG^)nio#d8gioczpko8|j(-Ij z^Dsblcj?pFs#9=W?Bpo8he6Y;+BSF`mHac_Y5}UmVVAicVu2OceDb_mj7BcK4$z_% zU{C$*#~nH8-?*|0LDlfQ;S73H*%wzj&|{wddGsXdLG(jg9aD%tt}LOeFoKYDtn&lw z5SI=fdYyeShqh&Uqv0v<$u+Og-Ok_YWTwX>C^>9}d5|>oZ9lzi{ zF&FI5t44?-=WC_bddEm9XxBf}S&!Xw-?J~sNRAC4$tTA&ybJBK)^Qy-qH#}Vh!ZQ% zNGd_JmDTdObvv7R%LJ8`c-hLy$EY>e8V7si=Ar-Q0)eN@^U!0{=4hq;qQS_KbLTH+ zD40uQ1D5hHDD-^3?qJseVW`T?rFWZ#1g-t3`#O@8rkrR+^I{;c+sdsb@MFp? zotRCvFwnfVV6VFfMe2Y-UVNh0J%%EYv>-2+?R9feq#`z&H=se?=t3%LJ&tU5lshpe zvmhAC$Ke`{fIUEvfMEHkky7?_n}`8Wge?g*SpMh)#i-WMy1@8G3%6AZL#32pp=<&* zw61d&8&=vMAP7Z`Y{JS72X7YY2Yi#3;U zMPSTvZI56-HVug!teV&{Fv~n{${1KwFqduWMMeo2@fJ4;a}0RZoQY=WxB!MP10Fdo zNlu$oNF}8GV5XBK!$fCkbrl}tEcz5oTh3Aq4Kd8VSU`wt<(murCnYi(gMn!Ms_=PE ztQ6eO)Cdi{5&;lP4>n^84DPouqMU;fBs9*MIGIK@(BnLURe`!dnA`(0fnMT5DHwUe z<$WSY0Y;z!dX8oohazn(-$^h8$Y?%x40E46+jVq2tGHKt(|R9y16=MsIs`69Z^HLM^eng>&*Ff~4pXtC z;5gRX)l8gaLNY>(u^?ZTw>Z*|;PaZ9dxs;-+Xxk_O$%R|;y??=x1T)OFDyczE~A2j znM`DZ)Z!!Ok8enXY)LTfpoWK?VfntTZ0n;cQ{0XAP$|xccfc!`f|X2K6-R$+^H%f9 zChjVgwzhZeRWFY#$eFAbIhB1P0UHimdVFtMY(0HjOtQ$uGG@1xIN6+HE?dYPZQJL6 zsJgNJR9{Z!I%t`YH+iV~gH{~q{i}rwM?a(n<_Tmx79U!Iy4C>>(v{~ssyMz{W<$P_ zzRZr-@|FP`UgRol7J({@?Fn9fse-kmRI-u?|$ccFeRju@9oduYz6-i_|T!; KH^;Z{Yy1ba0{?9Q diff --git a/e2e-tests/contentful/snapshots.js b/e2e-tests/contentful/snapshots.js index 510ac872b98fd..f33eb8a0356fa 100644 --- a/e2e-tests/contentful/snapshots.js +++ b/e2e-tests/contentful/snapshots.js @@ -55,7 +55,7 @@ module.exports = { "1": "
\n

Rich Text: Inline entry with deep reference loop

\n

Inline entry with deep reference loop

\n

Should be rendered after this [Inline-\n ContentfulContentReference\n ] and before that

\n

\n

\n
\n
" }, "rich-text: Inline Entry With Reference Loop": { - "1": "
\n

Rich Text: Inline entry with reference loop

\n

Inline entry with reference loop

\n

Should be rendered after this [Inline-\n ContentfulContentReference\n ] and before that

\n

\n

\n
\n
", + "1": "
\n

Rich Text: Inline entry with reference loop

\n

Inline entry with reference loop

\n

Should be rendered after this [Inline-\n ContentfulContentReference\n ] and before that

\n

\n

\n
\n
" }, "rich-text: Localized": { "1": "
\n

Rich Text: Localized

\n

Rich Text in English

\n
\n
", From 93406b0ee211c05fc266623a065f5c3a89164992 Mon Sep 17 00:00:00 2001 From: axe312ger Date: Fri, 11 Jun 2021 11:18:51 +0200 Subject: [PATCH 20/34] Revert "test(e2e): update snapshots" This reverts commit 8d94396a4d35e7c52c61a64a9f4d1c2100d18008. --- .../gatsby-plugin-image.js/german-0.snap.png | Bin 2570 -> 4168 bytes e2e-tests/contentful/snapshots.js | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e-tests/contentful/cypress/snapshots/gatsby-plugin-image.js/german-0.snap.png b/e2e-tests/contentful/cypress/snapshots/gatsby-plugin-image.js/german-0.snap.png index 95de3c6a3c374eb622afd9bc6324232b9664610d..e6f13231933f9e761eda1ea416b7ef7fcf8c6632 100644 GIT binary patch literal 4168 zcmeHLYfw{X8m2Q?Q3n#jB{bz?kZVK3vPH-;0u$3?Ni+}=ZczgYc7uqeSxm?V)G3My z3E3)_GH$qqa!CNuNU7EkSZk80vtzXO#Ih8y4O^{8iJRJNP$Ajx#GU@xo$1U@JF~O1 zf8KM>dwHJkJSXS<-jill?pyvF2^)QUeEjJ-Z?b)SUJ3)}xBXrQ_Kf^4;^TwG(BGsM zh+kU1O8xkuUuZ0R^uSwfkUsQRxUkSA?JL_)>`qPi{^8f{zaAUD;CcRsU2yZ|`t@7Q zVfd1k6f+cB(IPlw3ai+AAO*O%|9Ab163@$lGR2pZ-!X?RZFI>}%$GkcZ%H9v46A5S z%-2-4q>R7o>0O)gMm=jYt9dWZmObtnpk|2O<+(reN<|B4zSHAYq1C*ldPO#WvbmTS zE}t`UPf&sM2rIS5l?nw3 zRY81z8w-xJ5RChOHkcbcx4w5oy0UOZ>}MbbWPeuGHfJP@NQ68GOSM@9(IRZ>H0mSy z)?Bt~*7Odvlo(kRWE`*5(6+&GGM>&%uL{!7o~ztuq8)CW4e=Msq;tMH(j5x@a5-Kd zq8t`$m{@(kI=~BOBE)N%kIFCgJAyHj8_J7QVWJnVWGQB{nfItDwdV!fsSKkR?oii2 znohAGH*>sfpR=T1xN>D194FH4`CKgbvJnuh7j8_@I%m9R??e(KFxbux4P!uk9aycHLwTVMMGIFOnC4qX1k=AV-?TfY846tI>M2tjY zO4q$E2z@+QY9xd8$2(rDY@QG&JEKJcnKYxhn7XseRIkPB6hI65)W+Smq{W>E8Sk>5 zy|z0LJ|99odOoYz*LetH-5tFdLPeb}q!wb$6!|(0&-VUgisZ`k4`*Ro!-oTD+)Puw zb3_C+oEJflklLT~w9`Jl(cfRm48+6=bFO3BS4!7*cW>=s#|!Vw4&)+Zj`j@ggqed3 zSO_YZ{?CY*(G7De+J21WY1=XmRiicD$Wo$^%~vwf8gFFVAOOpr6Z+0yM|%2R#sh!Fu%zTVCi$6aSdzfiWo)wdAnL!aM+VZ9 zdXW9G*;C)u0LK9nl61L#MA{mqXe0 z3wEqm3tGjW&!z@Ynm$2=WhufE85^NY?9sRn4;f**xud>S*TBTNY z#gwL|DQT?oTDV(eb^4j>$kj#@{Y+EFp{dGupY$*K8GfU{L!sbT(0}!YLbBzD zdr76iT+M`8@p5`HqP(S=5a%CITL{U7`6*5M_8N-~`p=8q52neBj5R)@Xd;(3EjGmc zaBm9_wQs1?qaN6R?cHE_nuAB}uJ3NVb!7!u{`Q)z+a}ZoNuHb`qxS4A)%!;rz}`H$ z*f5~D`+8PzMT_J9ydh8@9mzOtC6gF|e5aXF)#7md&b5QFl<2N>78u7D|BQMjR?gxu z;H6cjn6DcgwL(pbd4*#?77hA)cCCw}R?u{Wik7^EwO#o6ZNkAw0F!d;TYJUT8$+b0 z`&&|`Yh5~)9&8h3yU}gcK3y0Oc9JOl^Rugcqr-h7Ex_y0KOX3jgPivl3>>hwD1H5w zNPy$sq9{v5k00ri+4@%UMe?yP3p%3!HK(r3s=jKgJIFo!#|}8GqT#;1&e?uyM?;9@ ziT<7xU|KRKN3TgHN{qI;LNuW&A66T)O~ru#pFh7geugZfF57ympnNv)km@|G1!jX)&jSnCZ?d-vi@?s8C33C5F~Sv66Usa1tRQ-O zA!_i-KDB!=P02(hK!4*qg=#f%kQh6;33#T3d}n)ArG^)nio#d8gioczpko8|j(-Ij z^Dsblcj?pFs#9=W?Bpo8he6Y;+BSF`mHac_Y5}UmVVAicVu2OceDb_mj7BcK4$z_% zU{C$*#~nH8-?*|0LDlfQ;S73H*%wzj&|{wddGsXdLG(jg9aD%tt}LOeFoKYDtn&lw z5SI=fdYyeShqh&Uqv0v<$u+Og-Ok_YWTwX>C^>9}d5|>oZ9lzi{ zF&FI5t44?-=WC_bddEm9XxBf}S&!Xw-?J~sNRAC4$tTA&ybJBK)^Qy-qH#}Vh!ZQ% zNGd_JmDTdObvv7R%LJ8`c-hLy$EY>e8V7si=Ar-Q0)eN@^U!0{=4hq;qQS_KbLTH+ zD40uQ1D5hHDD-^3?qJseVW`T?rFWZ#1g-t3`#O@8rkrR+^I{;c+sdsb@MFp? zotRCvFwnfVV6VFfMe2Y-UVNh0J%%EYv>-2+?R9feq#`z&H=se?=t3%LJ&tU5lshpe zvmhAC$Ke`{fIUEvfMEHkky7?_n}`8Wge?g*SpMh)#i-WMy1@8G3%6AZL#32pp=<&* zw61d&8&=vMAP7Z`Y{JS72X7YY2Yi#3;U zMPSTvZI56-HVug!teV&{Fv~n{${1KwFqduWMMeo2@fJ4;a}0RZoQY=WxB!MP10Fdo zNlu$oNF}8GV5XBK!$fCkbrl}tEcz5oTh3Aq4Kd8VSU`wt<(murCnYi(gMn!Ms_=PE ztQ6eO)Cdi{5&;lP4>n^84DPouqMU;fBs9*MIGIK@(BnLURe`!dnA`(0fnMT5DHwUe z<$WSY0Y;z!dX8oohazn(-$^h8$Y?%x40E46+jVq2tGHKt(|R9y16=MsIs`69Z^HLM^eng>&*Ff~4pXtC z;5gRX)l8gaLNY>(u^?ZTw>Z*|;PaZ9dxs;-+Xxk_O$%R|;y??=x1T)OFDyczE~A2j znM`DZ)Z!!Ok8enXY)LTfpoWK?VfntTZ0n;cQ{0XAP$|xccfc!`f|X2K6-R$+^H%f9 zChjVgwzhZeRWFY#$eFAbIhB1P0UHimdVFtMY(0HjOtQ$uGG@1xIN6+HE?dYPZQJL6 zsJgNJR9{Z!I%t`YH+iV~gH{~q{i}rwM?a(n<_Tmx79U!Iy4C>>(v{~ssyMz{W<$P_ zzRZr-@|FP`UgRol7J({@?Fn9fse-kmRI-u?|$ccFeRju@9oduYz6-i_|T!; KH^;Z{Yy1ba0{?9Q literal 2570 zcmds3VNeri8cwzeT@qmeCdMPQBsSGx<|x%eaLQ>&jLpiSX^?Oz3(_+byp#*Y$0q5IfNH z=mxC#ljPm5$FD%?r^c=%AF`6hRYHDcEUEoBC!=xVa;K%3W#c4vB1uRJ;BXmjCK z3u=$m^n15T+Jp)}Lf2*nEJZ1!M9K z_Ipd1Lo|Jn9My$t-Yv+L>O!LQS!(IL9PE+fpDt;7t=n2|Y!4!ao* z2zG4NI(^?HfOyqUtfUY8Pf;K=u~eDy?S$L3O|OrB(u!))kted%<(qTgFEzEpuW zx(EOG!JdBa2qR%#4{RkAUxVT&OAf=T(UVWgbfJ~32MRrG>8ap!DNm@-OQVQO)91aL zwL=kUi;To!OAGw&c+ELNitT(0?nld1PCJ*BMSJA$%uj3Cu!0-zV-?O*5B?^BE{-d@ zP~Oj87D*ci`{%=Ldtp5C)EiBi4Mz*y8?f4=odWp}GvTrvb;6i9Sm<2-t)$InJ{#NL z$~aV(BUN>q*UEpex7frNqSQQ`gs=!bue6(eL2}aai_ON8i;azm&0K^{(v`!igExg# z(U*se?OaNhf+iNNZ#UJpvorkTN_}=3oO&eDdT>-Eh>faA5UoOZ5yC5uv3vqYUNCBqd+ z^E`s~$i^r++Lw}%mjC7SlSkrxT!R5EkPBM(yqZv$49}CJg64=U$ZIk_Ps;xr@pnI& zVnPZZ2A{fBxjO0G1=Truc}Y0~;7ZH|`^mVzVDS7dcPMX&0dTWp51bRm_2Y&5jhXwh z_Avl%0&hEqaXlbZoUvVe?;-<02VOqHxQ_E&7+HP0ngO5#FWU;P(?wiLPG6!682~!) z>?&~Gd=@b|WA{OZ$!P{U@HA3zeWKF31?zYdWNg7EfDSwv<9b^DSjCB)JA|f8+)USZ zh#H8xUuw2+{R;}8b=y^80-q?H5t1d$pe4*zR0&~zO;&%#QYEY3kIs1Ot5LD&Ka`P{ zLc6L%Ay^=*!WSM-#TxpTABE92cPUvl;9lex5P1LcE8kKQT5E-SySmQPxvy{eV%S-n zSy>Y7_0He_I(EstR_B?!)>$JhcO3&4MugZGm#)x7b1pGAcZlc0yOF~A8V{{U_1P7n z#ltU@zo?g*#Gc0nF6qnf@y`Es`q_wVN)d>E-|O9ZZ(71dT!XRwdpQb!aiMedHwVi& z3V0n(<#?hbJPiiT;#MB?X{|gb*L&DJS^)Wx_psY|*r5h(>)|=v9uX+~F-P2JMIsJ_ z3p!_a4-j=8g2m=}J1@_1$Y%+2wLB@?cE@#t)S7bT$u}}KkwvP+%j_QS&hMr-k*8zE z?)Y;Rp@P?Ay9c=F3\n

Rich Text: Inline entry with deep reference loop

\n

Inline entry with deep reference loop

\n

Should be rendered after this [Inline-\n ContentfulContentReference\n ] and before that

\n

\n

\n
\n
" }, "rich-text: Inline Entry With Reference Loop": { - "1": "
\n

Rich Text: Inline entry with reference loop

\n

Inline entry with reference loop

\n

Should be rendered after this [Inline-\n ContentfulContentReference\n ] and before that

\n

\n

\n
\n
" + "1": "
\n

Rich Text: Inline entry with reference loop

\n

Inline entry with reference loop

\n

Should be rendered after this [Inline-\n ContentfulContentReference\n ] and before that

\n

\n

\n
\n
", }, "rich-text: Localized": { "1": "
\n

Rich Text: Localized

\n

Rich Text in English

\n
\n
", From 7cbe1ba6511016b4c9945ddfbadb3cc5134df2d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benedikt=20R=C3=B6tsch?= Date: Fri, 11 Jun 2021 13:30:00 +0200 Subject: [PATCH 21/34] refactor: rename schema types to avoid conflicts --- e2e-tests/contentful/schema.gql | 810 ++++++++++-------- e2e-tests/contentful/snapshots.js | 39 +- .../references/content-reference.js | 4 +- .../src/components/references/index.js | 8 +- .../src/components/references/location.js | 4 +- .../src/components/references/number.js | 4 +- .../src/components/references/text.js | 4 +- e2e-tests/contentful/src/pages/boolean.js | 6 +- .../contentful/src/pages/content-reference.js | 54 +- e2e-tests/contentful/src/pages/date.js | 14 +- .../contentful/src/pages/download-local.js | 4 +- e2e-tests/contentful/src/pages/json.js | 12 +- e2e-tests/contentful/src/pages/location.js | 6 +- .../contentful/src/pages/media-reference.js | 6 +- e2e-tests/contentful/src/pages/number.js | 6 +- e2e-tests/contentful/src/pages/rich-text.js | 30 +- e2e-tests/contentful/src/pages/tags.js | 13 +- e2e-tests/contentful/src/pages/text.js | 18 +- .../__tests__/download-contentful-assets.js | 10 +- .../src/__tests__/gatsby-node.js | 1 - .../src/create-schema-customization.js | 111 +-- .../src/download-contentful-assets.js | 21 +- .../src/generate-schema.js | 64 +- .../gatsby-source-contentful/src/normalize.js | 8 +- 24 files changed, 618 insertions(+), 639 deletions(-) diff --git a/e2e-tests/contentful/schema.gql b/e2e-tests/contentful/schema.gql index 7a501577d38cb..5f4ef8d58f623 100644 --- a/e2e-tests/contentful/schema.gql +++ b/e2e-tests/contentful/schema.gql @@ -1,4 +1,4 @@ -### Type definitions saved at 2021-09-25T11:33:25.217Z ### +### Type definitions saved at 2021-11-18T12:37:07.683Z ### type File implements Node @dontInfer { sourceInstanceName: String! @@ -32,6 +32,9 @@ type File implements Node @dontInfer { ctime: Date! @dateformat birthtime: Date @deprecated(reason: "Use `birthTime` instead") birthtimeMs: Float @deprecated(reason: "Use `birthTime` instead") + blksize: Int + blocks: Int + url: String } type Directory implements Node @dontInfer { @@ -71,8 +74,11 @@ type Directory implements Node @dontInfer { type Site implements Node @dontInfer { buildTime: Date @dateformat siteMetadata: SiteSiteMetadata + port: Int + host: String polyfill: Boolean pathPrefix: String + jsxRuntime: String } type SiteSiteMetadata { @@ -96,7 +102,8 @@ type SitePage implements Node @dontInfer { internalComponentName: String! componentChunkName: String! matchPath: String - pageContext: JSON + pageContext: JSON @proxy(from: "context", fromNode: false) + pluginCreator: SitePlugin @link(by: "id", from: "pluginCreatorId") } type SitePlugin implements Node @dontInfer { @@ -115,429 +122,172 @@ type SiteBuildMetadata implements Node @dontInfer { buildTime: Date @dateformat } -interface ContentfulEntry implements Node { - contentful_id: String! +interface ContentfulReference implements Node { id: ID! - node_locale: String! + sys: ContentfulSys } -interface ContentfulReference { - contentful_id: String! - id: ID! +type ContentfulSys { + type: String! + id: String! + spaceId: String! + environmentId: String! + contentType: ContentfulContentType @link(by: "id", from: "contentType___NODE") + firstPublishedAt: Date! + publishedAt: Date! + publishedVersion: Int! + locale: String! } -type ContentfulAsset implements ContentfulReference & Node @derivedTypes @dontInfer { - contentful_id: String! - spaceId: String - createdAt: Date @dateformat - updatedAt: Date @dateformat - file: ContentfulAssetFile - title: String - description: String - node_locale: String - sys: ContentfulAssetSys +type ContentfulContentType implements Node @dontInfer { + name: String! + displayField: String! + description: String! } -type ContentfulAssetFile @derivedTypes { - url: String - details: ContentfulAssetFileDetails - fileName: String - contentType: String +interface ContentfulEntry implements Node { + id: ID! + sys: ContentfulSys } -type ContentfulAssetFileDetails @derivedTypes { +type ContentfulAsset implements ContentfulReference & Node @dontInfer { + sys: ContentfulSys + title: String + description: String + contentType: String + fileName: String + url: String size: Int - image: ContentfulAssetFileDetailsImage -} - -type ContentfulAssetFileDetailsImage { width: Int height: Int + fields: ContentfulAssetFields } -type ContentfulAssetSys { - type: String - revision: Int +type ContentfulAssetFields { + localFile: String } -type ContentfulNumber implements ContentfulReference & ContentfulEntry & Node @derivedTypes @dontInfer { +type ContentfulTag implements Node @dontInfer { + name: String! contentful_id: String! - node_locale: String! - title: String - integerLocalized: Int - spaceId: String - createdAt: Date @dateformat - updatedAt: Date @dateformat - sys: ContentfulNumberSys - metadata: ContentfulNumberMetadata - decimal: Float - integer: Int - content_reference: [ContentfulContentReference] @link(by: "id", from: "content reference___NODE") @proxy(from: "content reference___NODE") - decimalLocalized: Float } -type ContentfulNumberSys @derivedTypes { - type: String - revision: Int - contentType: ContentfulNumberSysContentType +type ContentfulRichTextAssets { + block: [ContentfulAsset]! + hyperlink: [ContentfulAsset]! } -type ContentfulNumberSysContentType @derivedTypes { - sys: ContentfulNumberSysContentTypeSys +type ContentfulRichTextEntries { + inline: [ContentfulEntry]! + block: [ContentfulEntry]! + hyperlink: [ContentfulEntry]! } -type ContentfulNumberSysContentTypeSys { - type: String - linkType: String - id: String +type ContentfulRichTextLinks { + assets: ContentfulRichTextAssets + entries: ContentfulRichTextEntries } -type ContentfulNumberMetadata { - tags: [ContentfulTag] @link(by: "id", from: "tags___NODE") +type ContentfulRichText @dontInfer { + json: JSON + links: ContentfulRichTextLinks } -type ContentfulTag implements Node @dontInfer { - name: String! - contentful_id: String! +type ContentfulLocation @dontInfer { + lat: Float! + lon: Float! } -type ContentfulContentReference implements ContentfulReference & ContentfulEntry & Node @derivedTypes @dontInfer { - contentful_id: String! - node_locale: String! - title: String - one: ContentfulContentReferenceContentfulTextUnion @link(by: "id", from: "one___NODE") - content_reference: [ContentfulContentReference] @link(by: "id", from: "content reference___NODE") @proxy(from: "content reference___NODE") - spaceId: String - createdAt: Date @dateformat - updatedAt: Date @dateformat - sys: ContentfulContentReferenceSys - oneLocalized: ContentfulNumber @link(by: "id", from: "oneLocalized___NODE") - many: [ContentfulContentReferenceContentfulNumberContentfulTextUnion] @link(by: "id", from: "many___NODE") - manyLocalized: [ContentfulNumberContentfulTextUnion] @link(by: "id", from: "manyLocalized___NODE") -} - -union ContentfulContentReferenceContentfulTextUnion = ContentfulContentReference | ContentfulText - -type ContentfulContentReferenceSys @derivedTypes { - type: String - revision: Int - contentType: ContentfulContentReferenceSysContentType -} - -type ContentfulContentReferenceSysContentType @derivedTypes { - sys: ContentfulContentReferenceSysContentTypeSys +type ContentfulText implements Node @dontInfer { + raw: String! } -type ContentfulContentReferenceSysContentTypeSys { - type: String - linkType: String - id: String +type ContentfulContentTypeNumber implements ContentfulReference & ContentfulEntry & Node @dontInfer { + sys: ContentfulSys + title: String + integer: Int + integerLocalized: Int + decimal: Float + decimalLocalized: Float } -union ContentfulContentReferenceContentfulNumberContentfulTextUnion = ContentfulContentReference | ContentfulNumber | ContentfulText - -union ContentfulNumberContentfulTextUnion = ContentfulNumber | ContentfulText - -type ContentfulText implements ContentfulReference & ContentfulEntry & Node @derivedTypes @dontInfer { - contentful_id: String! - node_locale: String! +type ContentfulContentTypeText implements ContentfulReference & ContentfulEntry & Node @dontInfer { + sys: ContentfulSys title: String - longLocalized: contentfulTextLongLocalizedTextNode @link(by: "id", from: "longLocalized___NODE") - spaceId: String - createdAt: Date @dateformat - updatedAt: Date @dateformat - sys: ContentfulTextSys - longMarkdown: contentfulTextLongMarkdownTextNode @link(by: "id", from: "longMarkdown___NODE") + short: String shortLocalized: String - longPlain: contentfulTextLongPlainTextNode @link(by: "id", from: "longPlain___NODE") shortList: [String] - short: String - content_reference: [ContentfulContentReference] @link(by: "id", from: "content reference___NODE") @proxy(from: "content reference___NODE") -} - -type contentfulTextLongLocalizedTextNode implements Node @derivedTypes @childOf(types: ["ContentfulText"]) @dontInfer { - longLocalized: String - sys: contentfulTextLongLocalizedTextNodeSys -} - -type contentfulTextLongLocalizedTextNodeSys { - type: String + shortListLocalized: [String] + longPlain: ContentfulText @link(by: "id", from: "longPlain___NODE") + longMarkdown: ContentfulText @link(by: "id", from: "longMarkdown___NODE") + longLocalized: ContentfulText @link(by: "id", from: "longLocalized___NODE") } -type ContentfulTextSys @derivedTypes { - type: String - revision: Int - contentType: ContentfulTextSysContentType -} - -type ContentfulTextSysContentType @derivedTypes { - sys: ContentfulTextSysContentTypeSys -} - -type ContentfulTextSysContentTypeSys { - type: String - linkType: String - id: String -} - -type contentfulTextLongMarkdownTextNode implements Node @derivedTypes @childOf(types: ["ContentfulText"]) @dontInfer { - longMarkdown: String - sys: contentfulTextLongMarkdownTextNodeSys -} - -type contentfulTextLongMarkdownTextNodeSys { - type: String -} - -type contentfulTextLongPlainTextNode implements Node @derivedTypes @childOf(types: ["ContentfulText"]) @dontInfer { - longPlain: String - sys: contentfulTextLongPlainTextNodeSys -} - -type contentfulTextLongPlainTextNodeSys { - type: String -} - -type ContentfulMediaReference implements ContentfulReference & ContentfulEntry & Node @derivedTypes @dontInfer { - contentful_id: String! - node_locale: String! +type ContentfulContentTypeMediaReference implements ContentfulReference & ContentfulEntry & Node @dontInfer { + sys: ContentfulSys title: String one: ContentfulAsset @link(by: "id", from: "one___NODE") - spaceId: String - createdAt: Date @dateformat - updatedAt: Date @dateformat - sys: ContentfulMediaReferenceSys oneLocalized: ContentfulAsset @link(by: "id", from: "oneLocalized___NODE") many: [ContentfulAsset] @link(by: "id", from: "many___NODE") manyLocalized: [ContentfulAsset] @link(by: "id", from: "manyLocalized___NODE") } -type ContentfulMediaReferenceSys @derivedTypes { - type: String - revision: Int - contentType: ContentfulMediaReferenceSysContentType -} - -type ContentfulMediaReferenceSysContentType @derivedTypes { - sys: ContentfulMediaReferenceSysContentTypeSys -} - -type ContentfulMediaReferenceSysContentTypeSys { - type: String - linkType: String - id: String -} - -type ContentfulBoolean implements ContentfulReference & ContentfulEntry & Node @derivedTypes @dontInfer { - contentful_id: String! - node_locale: String! +type ContentfulContentTypeBoolean implements ContentfulReference & ContentfulEntry & Node @dontInfer { + sys: ContentfulSys title: String - booleanLocalized: Boolean - spaceId: String - createdAt: Date @dateformat - updatedAt: Date @dateformat - sys: ContentfulBooleanSys boolean: Boolean + booleanLocalized: Boolean } -type ContentfulBooleanSys @derivedTypes { - type: String - revision: Int - contentType: ContentfulBooleanSysContentType -} - -type ContentfulBooleanSysContentType @derivedTypes { - sys: ContentfulBooleanSysContentTypeSys -} - -type ContentfulBooleanSysContentTypeSys { - type: String - linkType: String - id: String -} - -type ContentfulDate implements ContentfulReference & ContentfulEntry & Node @derivedTypes @dontInfer { - contentful_id: String! - node_locale: String! +type ContentfulContentTypeDate implements ContentfulReference & ContentfulEntry & Node @dontInfer { + sys: ContentfulSys title: String - dateTimeTimezone: Date @dateformat - spaceId: String - createdAt: Date @dateformat - updatedAt: Date @dateformat - sys: ContentfulDateSys date: Date @dateformat - dateLocalized: Date @dateformat dateTime: Date @dateformat + dateTimeTimezone: Date @dateformat + dateLocalized: Date @dateformat } -type ContentfulDateSys @derivedTypes { - type: String - revision: Int - contentType: ContentfulDateSysContentType -} - -type ContentfulDateSysContentType @derivedTypes { - sys: ContentfulDateSysContentTypeSys -} - -type ContentfulDateSysContentTypeSys { - type: String - linkType: String - id: String -} - -type ContentfulLocation implements ContentfulReference & ContentfulEntry & Node @derivedTypes @dontInfer { - contentful_id: String! - node_locale: String! +type ContentfulContentTypeLocation implements ContentfulReference & ContentfulEntry & Node @dontInfer { + sys: ContentfulSys title: String - locationLocalized: ContentfulLocationLocationLocalized - spaceId: String - createdAt: Date @dateformat - updatedAt: Date @dateformat - sys: ContentfulLocationSys - location: ContentfulLocationLocation -} - -type ContentfulLocationLocationLocalized { - lon: Float - lat: Float + location: ContentfulLocation + locationLocalized: ContentfulLocation } -type ContentfulLocationSys @derivedTypes { - type: String - revision: Int - contentType: ContentfulLocationSysContentType -} - -type ContentfulLocationSysContentType @derivedTypes { - sys: ContentfulLocationSysContentTypeSys -} - -type ContentfulLocationSysContentTypeSys { - type: String - linkType: String - id: String -} - -type ContentfulLocationLocation { - lat: Float - lon: Float -} - -type ContentfulJson implements ContentfulReference & ContentfulEntry & Node @derivedTypes @dontInfer { - contentful_id: String! - node_locale: String! +type ContentfulContentTypeJson implements ContentfulReference & ContentfulEntry & Node @dontInfer { + sys: ContentfulSys title: String - json: contentfulJsonJsonJsonNode @link(by: "id", from: "json___NODE") - spaceId: String - createdAt: Date @dateformat - updatedAt: Date @dateformat - sys: ContentfulJsonSys - jsonLocalized: contentfulJsonJsonLocalizedJsonNode @link(by: "id", from: "jsonLocalized___NODE") -} - -type contentfulJsonJsonJsonNode implements Node @derivedTypes @childOf(types: ["ContentfulJson"]) @dontInfer { - age: Int - city: String - name: String - sys: contentfulJsonJsonJsonNodeSys - Actors: [contentfulJsonJsonJsonNodeActors] -} - -type contentfulJsonJsonJsonNodeSys { - type: String -} - -type contentfulJsonJsonJsonNodeActors { - age: Int - name: String - wife: String - photo: String - weight: Float - Born_At: String @proxy(from: "Born At") - children: [String] - Birthdate: String - hasChildren: Boolean - hasGreyHair: Boolean -} - -type ContentfulJsonSys @derivedTypes { - type: String - revision: Int - contentType: ContentfulJsonSysContentType -} - -type ContentfulJsonSysContentType @derivedTypes { - sys: ContentfulJsonSysContentTypeSys + json: JSON + jsonLocalized: JSON } -type ContentfulJsonSysContentTypeSys { - type: String - linkType: String - id: String -} - -type contentfulJsonJsonLocalizedJsonNode implements Node @derivedTypes @childOf(types: ["ContentfulJson"]) @dontInfer { - name: String - age: Int - city: String - sys: contentfulJsonJsonLocalizedJsonNodeSys -} - -type contentfulJsonJsonLocalizedJsonNodeSys { - type: String -} - -type ContentfulRichText implements ContentfulReference & ContentfulEntry & Node @derivedTypes @dontInfer { - contentful_id: String! - node_locale: String! +type ContentfulContentTypeRichText implements ContentfulReference & ContentfulEntry & Node @dontInfer { + sys: ContentfulSys title: String - richText: ContentfulRichTextRichText - spaceId: String - createdAt: Date @dateformat - updatedAt: Date @dateformat - sys: ContentfulRichTextSys - richTextValidated: ContentfulRichTextRichTextValidated - richTextLocalized: ContentfulRichTextRichTextLocalized -} - -type ContentfulRichTextRichText { - raw: String - references: [ContentfulAssetContentfulContentReferenceContentfulLocationContentfulTextUnion] @link(by: "id", from: "references___NODE") -} - -union ContentfulAssetContentfulContentReferenceContentfulLocationContentfulTextUnion = ContentfulAsset | ContentfulContentReference | ContentfulLocation | ContentfulText - -type ContentfulRichTextSys @derivedTypes { - type: String - revision: Int - contentType: ContentfulRichTextSysContentType -} - -type ContentfulRichTextSysContentType @derivedTypes { - sys: ContentfulRichTextSysContentTypeSys -} - -type ContentfulRichTextSysContentTypeSys { - type: String - linkType: String - id: String -} - -type ContentfulRichTextRichTextValidated { - raw: String - references: [ContentfulAssetContentfulLocationContentfulNumberContentfulTextUnion] @link(by: "id", from: "references___NODE") + richText: ContentfulRichText + richTextLocalized: ContentfulRichText + richTextValidated: ContentfulRichText } -union ContentfulAssetContentfulLocationContentfulNumberContentfulTextUnion = ContentfulAsset | ContentfulLocation | ContentfulNumber | ContentfulText - -type ContentfulRichTextRichTextLocalized { - raw: String +type ContentfulContentTypeContentReference implements ContentfulReference & ContentfulEntry & Node @dontInfer { + sys: ContentfulSys + title: String + one: ContentfulEntry @link(by: "id", from: "one___NODE") + oneLocalized: ContentfulEntry @link(by: "id", from: "oneLocalized___NODE") + many: [ContentfulEntry] @link(by: "id", from: "many___NODE") + manyLocalized: [ContentfulEntry] @link(by: "id", from: "manyLocalized___NODE") } -type ContentfulValidatedContentReference implements ContentfulReference & ContentfulEntry & Node @dontInfer { - contentful_id: String! - node_locale: String! +type ContentfulContentTypeValidatedContentReference implements ContentfulReference & ContentfulEntry & Node @dontInfer { + sys: ContentfulSys + title: String + oneItemSingleType: ContentfulEntry @link(by: "id", from: "oneItemSingleType___NODE") + oneItemManyTypes: ContentfulEntry @link(by: "id", from: "oneItemManyTypes___NODE") + oneItemAllTypes: ContentfulEntry @link(by: "id", from: "oneItemAllTypes___NODE") + multipleItemsSingleType: [ContentfulEntry] @link(by: "id", from: "multipleItemsSingleType___NODE") + multipleItemsManyTypes: [ContentfulEntry] @link(by: "id", from: "multipleItemsManyTypes___NODE") + multipleItemsAllTypes: [ContentfulEntry] @link(by: "id", from: "multipleItemsAllTypes___NODE") } type MarkdownHeading { @@ -567,7 +317,7 @@ type MarkdownWordCount { words: Int } -type MarkdownRemark implements Node @childOf(mimeTypes: ["text/markdown", "text/x-markdown"], types: ["contentfulTextLongPlainTextNode", "contentfulTextLongMarkdownTextNode", "contentfulTextLongLocalizedTextNode"]) @derivedTypes @dontInfer { +type MarkdownRemark implements Node @childOf(mimeTypes: ["text/markdown", "text/x-markdown"], types: ["ContentfulText"]) @dontInfer { frontmatter: MarkdownRemarkFrontmatter excerpt: String rawMarkdownBody: String @@ -577,13 +327,345 @@ type MarkdownRemarkFrontmatter { title: String } -type ContentfulContentType implements Node @derivedTypes @dontInfer { +enum ImageFormat { + NO_CHANGE + AUTO + JPG + PNG + WEBP + AVIF +} + +enum ImageFit { + COVER + CONTAIN + FILL + INSIDE + OUTSIDE +} + +enum ImageLayout { + FIXED + FULL_WIDTH + CONSTRAINED +} + +enum ImageCropFocus { + CENTER + NORTH + NORTHEAST + EAST + SOUTHEAST + SOUTH + SOUTHWEST + WEST + NORTHWEST + ENTROPY + ATTENTION +} + +input DuotoneGradient { + highlight: String! + shadow: String! + opacity: Int +} + +enum PotraceTurnPolicy { + TURNPOLICY_BLACK + TURNPOLICY_WHITE + TURNPOLICY_LEFT + TURNPOLICY_RIGHT + TURNPOLICY_MINORITY + TURNPOLICY_MAJORITY +} + +input Potrace { + turnPolicy: PotraceTurnPolicy + turdSize: Float + alphaMax: Float + optCurve: Boolean + optTolerance: Float + threshold: Int + blackOnWhite: Boolean + color: String + background: String +} + +type ImageSharpFixed { + base64: String + tracedSVG: String + aspectRatio: Float + width: Float! + height: Float! + src: String! + srcSet: String! + srcWebp: String + srcSetWebp: String + originalName: String +} + +type ImageSharpFluid { + base64: String + tracedSVG: String + aspectRatio: Float! + src: String! + srcSet: String! + srcWebp: String + srcSetWebp: String + sizes: String! + originalImg: String + originalName: String + presentationWidth: Int! + presentationHeight: Int! +} + +enum ImagePlaceholder { + DOMINANT_COLOR + TRACED_SVG + BLURRED + NONE +} + +input BlurredOptions { + """Width of the generated low-res preview. Default is 20px""" + width: Int + + """ + Force the output format for the low-res preview. Default is to use the same + format as the input. You should rarely need to change this + """ + toFormat: ImageFormat +} + +input JPGOptions { + quality: Int + progressive: Boolean = true +} + +input PNGOptions { + quality: Int + compressionSpeed: Int = 4 +} + +input WebPOptions { + quality: Int +} + +input AVIFOptions { + quality: Int + lossless: Boolean + speed: Int +} + +input TransformOptions { + grayscale: Boolean = false + duotone: DuotoneGradient + rotate: Int = 0 + trim: Float = 0 + cropFocus: ImageCropFocus = ATTENTION + fit: ImageFit = COVER +} + +type ImageSharpOriginal { + width: Float + height: Float + src: String +} + +type ImageSharpResize { + src: String + tracedSVG: String + width: Int + height: Int + aspectRatio: Float + originalName: String +} + +type ImageSharp implements Node @childOf(mimeTypes: [], types: ["File"]) @dontInfer { + fixed(width: Int, height: Int, base64Width: Int, jpegProgressive: Boolean = true, pngCompressionSpeed: Int = 4, grayscale: Boolean = false, duotone: DuotoneGradient, traceSVG: Potrace, quality: Int, jpegQuality: Int, pngQuality: Int, webpQuality: Int, toFormat: ImageFormat = AUTO, toFormatBase64: ImageFormat = AUTO, cropFocus: ImageCropFocus = ATTENTION, fit: ImageFit = COVER, background: String = "rgba(0,0,0,1)", rotate: Int = 0, trim: Float = 0): ImageSharpFixed + fluid( + maxWidth: Int + maxHeight: Int + base64Width: Int + grayscale: Boolean = false + jpegProgressive: Boolean = true + pngCompressionSpeed: Int = 4 + duotone: DuotoneGradient + traceSVG: Potrace + quality: Int + jpegQuality: Int + pngQuality: Int + webpQuality: Int + toFormat: ImageFormat = AUTO + toFormatBase64: ImageFormat = AUTO + cropFocus: ImageCropFocus = ATTENTION + fit: ImageFit = COVER + background: String = "rgba(0,0,0,1)" + rotate: Int = 0 + trim: Float = 0 + sizes: String = "" + + """ + A list of image widths to be generated. Example: [ 200, 340, 520, 890 ] + """ + srcSetBreakpoints: [Int] = [] + ): ImageSharpFluid + gatsbyImageData( + """ + The layout for the image. + FIXED: A static image sized, that does not resize according to the screen width + FULL_WIDTH: The image resizes to fit its container. Pass a "sizes" option if + it isn't going to be the full width of the screen. + CONSTRAINED: Resizes to fit its container, up to a maximum width, at which point it will remain fixed in size. + """ + layout: ImageLayout = CONSTRAINED + + """ + The display width of the generated image for layout = FIXED, and the maximum + display width of the largest image for layout = CONSTRAINED. + Ignored if layout = FLUID. + """ + width: Int + + """ + The display height of the generated image for layout = FIXED, and the + maximum display height of the largest image for layout = CONSTRAINED. + The image will be cropped if the aspect ratio does not match the source + image. If omitted, it is calculated from the supplied width, + matching the aspect ratio of the source image. + """ + height: Int + + """ + If set along with width or height, this will set the value of the other + dimension to match the provided aspect ratio, cropping the image if needed. + If neither width or height is provided, height will be set based on the intrinsic width of the source image. + """ + aspectRatio: Float + + """ + Format of generated placeholder image, displayed while the main image loads. + BLURRED: a blurred, low resolution image, encoded as a base64 data URI (default) + DOMINANT_COLOR: a solid color, calculated from the dominant color of the image. + TRACED_SVG: a low-resolution traced SVG of the image. + NONE: no placeholder. Set "background" to use a fixed background color. + """ + placeholder: ImagePlaceholder + + """ + Options for the low-resolution placeholder image. Set placeholder to "BLURRED" to use this + """ + blurredOptions: BlurredOptions + + """ + Options for traced placeholder SVGs. You also should set placeholder to "TRACED_SVG". + """ + tracedSVGOptions: Potrace + + """ + The image formats to generate. Valid values are "AUTO" (meaning the same + format as the source image), "JPG", "PNG", "WEBP" and "AVIF". + The default value is [AUTO, WEBP], and you should rarely need to change + this. Take care if you specify JPG or PNG when you do + not know the formats of the source images, as this could lead to unwanted + results such as converting JPEGs to PNGs. Specifying + both PNG and JPG is not supported and will be ignored. + """ + formats: [ImageFormat] + + """ + A list of image pixel densities to generate. It will never generate images + larger than the source, and will always include a 1x image. + Default is [ 1, 2 ] for FIXED images, meaning 1x and 2x and [0.25, 0.5, 1, + 2] for CONSTRAINED. In this case, an image with a constrained layout + and width = 400 would generate images at 100, 200, 400 and 800px wide. + Ignored for FULL_WIDTH images, which use breakpoints instead + """ + outputPixelDensities: [Float] + + """ + Specifies the image widths to generate. For FIXED and CONSTRAINED images it + is better to allow these to be determined automatically, + based on the image size. For FULL_WIDTH images this can be used to override + the default, which is [750, 1080, 1366, 1920]. + It will never generate any images larger than the source. + """ + breakpoints: [Int] + + """ + The "sizes" property, passed to the img tag. This describes the display size of the image. + This does not affect the generated images, but is used by the browser to decide which images to download. + You should usually leave this blank, and a suitable value will be calculated. The exception is if a FULL_WIDTH image + does not actually span the full width of the screen, in which case you should pass the correct size here. + """ + sizes: String + + """The default quality. This is overridden by any format-specific options""" + quality: Int + + """Options to pass to sharp when generating JPG images.""" + jpgOptions: JPGOptions + + """Options to pass to sharp when generating PNG images.""" + pngOptions: PNGOptions + + """Options to pass to sharp when generating WebP images.""" + webpOptions: WebPOptions + + """Options to pass to sharp when generating AVIF images.""" + avifOptions: AVIFOptions + + """ + Options to pass to sharp to control cropping and other image manipulations. + """ + transformOptions: TransformOptions + + """ + Background color applied to the wrapper. Also passed to sharp to use as a + background when "letterboxing" an image to another aspect ratio. + """ + backgroundColor: String + ): JSON! + original: ImageSharpOriginal + resize(width: Int, height: Int, quality: Int, jpegQuality: Int, pngQuality: Int, webpQuality: Int, jpegProgressive: Boolean = true, pngCompressionLevel: Int = 9, pngCompressionSpeed: Int = 4, grayscale: Boolean = false, duotone: DuotoneGradient, base64: Boolean = false, traceSVG: Potrace, toFormat: ImageFormat = AUTO, cropFocus: ImageCropFocus = ATTENTION, fit: ImageFit = COVER, background: String = "rgba(0,0,0,1)", rotate: Int = 0, trim: Float = 0): ImageSharpResize +} + +enum GatsbyImageFormat { + NO_CHANGE + AUTO + JPG + PNG + WEBP + AVIF +} + +enum GatsbyImageLayout { + FIXED + FULL_WIDTH + CONSTRAINED +} + +enum GatsbyImagePlaceholder { + DOMINANT_COLOR + TRACED_SVG + BLURRED + NONE +} + +type ContentfulContentTypeContentType implements Node @dontInfer { name: String displayField: String description: String - sys: ContentfulContentTypeSys + sys: ContentfulContentTypeContentTypeSys } -type ContentfulContentTypeSys { +type ContentfulContentTypeContentTypeSys { type: String + id: String + locale: String + spaceId: String + environmentId: String + firstPublishedAt: Date @dateformat + publishedAt: Date @dateformat + publishedVersion: Int } \ No newline at end of file diff --git a/e2e-tests/contentful/snapshots.js b/e2e-tests/contentful/snapshots.js index 510ac872b98fd..4633f5746f014 100644 --- a/e2e-tests/contentful/snapshots.js +++ b/e2e-tests/contentful/snapshots.js @@ -2,28 +2,28 @@ module.exports = { "__version": "6.9.1", "content-reference": { "content-reference-many-2nd-level-loop": { - "1": "
\n

Content Reference: Many (2nd level loop)

\n

[ContentfulNumber]\n 42

\n

[ContentfulText]\n The quick brown fox jumps over the lazy dog.

\n

[ContentfulReference]\n Content Reference: One (Loop A -> B)\n : [\n Content Reference: One (Loop B -> A)\n ]

\n
" + "1": "
\n

Content Reference: Many (2nd level loop)

\n

[ContentfulContentTypeNumber]\n 42

\n

[ContentfulContentTypeText]\n The quick brown fox jumps over the lazy dog.

\n

[ContentfulContentTypeContentReference]\n Content Reference: One (Loop A -> B)\n : [\n Content Reference: One (Loop B -> A)\n ]

\n
" }, "content-reference-many-loop-a-greater-b": { - "1": "
\n

Content Reference: Many (Loop A -> B)

\n

[ContentfulNumber]\n 42

\n

[ContentfulText]\n The quick brown fox jumps over the lazy dog.

\n

[ContentfulReference]\n Content Reference: Many (Loop B -> A)\n : [\n Number: Integer, Text: Short, Content Reference: Many (Loop A ->\n B)\n ]

\n
" + "1": "
\n

Content Reference: Many (Loop A -> B)

\n

[ContentfulContentTypeNumber]\n 42

\n

[ContentfulContentTypeText]\n The quick brown fox jumps over the lazy dog.

\n

[ContentfulContentTypeContentReference]\n Content Reference: Many (Loop B -> A)\n : [\n Number: Integer, Text: Short, Content Reference: Many (Loop A ->\n B)\n ]

\n
" }, "content-reference-many-loop-b-greater-a": { - "1": "
\n

Content Reference: Many (Loop B -> A)

\n

[ContentfulNumber]\n 42

\n

[ContentfulText]\n The quick brown fox jumps over the lazy dog.

\n

[ContentfulReference]\n Content Reference: Many (Loop A -> B)\n : [\n Number: Integer, Text: Short, Content Reference: Many (Loop B ->\n A)\n ]

\n
" + "1": "
\n

Content Reference: Many (Loop B -> A)

\n

[ContentfulContentTypeNumber]\n 42

\n

[ContentfulContentTypeText]\n The quick brown fox jumps over the lazy dog.

\n

[ContentfulContentTypeContentReference]\n Content Reference: Many (Loop A -> B)\n : [\n Number: Integer, Text: Short, Content Reference: Many (Loop B ->\n A)\n ]

\n
" }, "content-reference-many-self-reference": { - "1": "
\n

Content Reference: Many (Self Reference)

\n

[ContentfulNumber]\n 42

\n

[ContentfulText]\n The quick brown fox jumps over the lazy dog.

\n

[ContentfulReference]\n Content Reference: Many (Self Reference)\n : [\n Number: Integer, Text: Short, Content Reference: Many (Self\n Reference)\n ]

\n
" + "1": "
\n

Content Reference: Many (Self Reference)

\n

[ContentfulContentTypeNumber]\n 42

\n

[ContentfulContentTypeText]\n The quick brown fox jumps over the lazy dog.

\n

[ContentfulContentTypeContentReference]\n Content Reference: Many (Self Reference)\n : [\n Number: Integer, Text: Short, Content Reference: Many (Self\n Reference)\n ]

\n
" }, "content-reference-one": { - "1": "
\n

Content Reference: One

\n

[ContentfulText]\n The quick brown fox jumps over the lazy dog.

\n
" + "1": "
\n

Content Reference: One

\n

[ContentfulContentTypeText]\n The quick brown fox jumps over the lazy dog.

\n
" }, "content-reference-one-loop-a-greater-b": { - "1": "
\n

Content Reference: One (Loop A -> B)

\n

[ContentfulReference]\n Content Reference: One (Loop B -> A)\n : [\n Content Reference: One (Loop A -> B)\n ]

\n
" + "1": "
\n

Content Reference: One (Loop A -> B)

\n

[ContentfulContentTypeContentReference]\n Content Reference: One (Loop B -> A)\n : [\n Content Reference: One (Loop A -> B)\n ]

\n
" }, "content-reference-one-loop-b-greater-a": { - "1": "
\n

Content Reference: One (Loop B -> A)

\n

[ContentfulReference]\n Content Reference: One (Loop A -> B)\n : [\n Content Reference: One (Loop B -> A)\n ]

\n
" + "1": "
\n

Content Reference: One (Loop B -> A)

\n

[ContentfulContentTypeContentReference]\n Content Reference: One (Loop A -> B)\n : [\n Content Reference: One (Loop B -> A)\n ]

\n
" }, "content-reference-one-self-reference": { - "1": "
\n

Content Reference: One (Self Reference)

\n

[ContentfulReference]\n Content Reference: One (Self Reference)\n : [\n Content Reference: One (Self Reference)\n ]

\n
" + "1": "
\n

Content Reference: One (Self Reference)

\n

[ContentfulContentTypeContentReference]\n Content Reference: One (Self Reference)\n : [\n Content Reference: One (Self Reference)\n ]

\n
" } }, "rich-text": { @@ -34,28 +34,25 @@ module.exports = { "1": "
\n

Rich Text: Basic

\n

The European languages

\n

are members of the same family. Their separate existence is a myth. For:

\n
    \n
  • \n

    science

    \n
  • \n
  • \n

    music

    \n
  • \n
  • \n

    sport

    \n
  • \n
  • \n

    etc

    \n
  • \n
\n

Europe uses the same vocabulary.

\n
\n

The languages only differ in:

\n
    \n
  1. \n

    their grammar

    \n
  2. \n
  3. \n

    their pronunciation

    \n
  4. \n
  5. \n

    their most common words

    \n
  6. \n
\n

Everyone realizes why a new common language would be desirable: one could\n refuse to pay expensive translators.

\n

{\n \"userId\": 1,\n \"id\": 1,\n \"title\": \"delectus aut autem\",\n \"completed\": false\n }

\n

To achieve this, it would be necessary to have uniform grammar,\n pronunciation and more common words.

\n
\n

If several languages coalesce, the grammar of the resulting language is\n more simple and regular than that of the individual languages.

\n
\n

The new common language will be more simple and regular than the existing\n European languages. It will be as simple as Occidental; in fact, it will be\n

\n
\n
" }, "rich-text: Embedded Entry": { - "1": "
\n

Rich Text: Embedded Entry

\n

Embedded Entry

\n

[ContentfulText]\n The quick brown fox jumps over the lazy dog.

\n

\n

\n
\n
" + "1": "
\n

Rich Text: Embedded Entry

\n

Embedded Entry

\n

[ContentfulContentTypeText]\n The quick brown fox jumps over the lazy dog.

\n

\n

\n
\n
" }, "rich-text: Embedded Asset": { "1": "
\n

Rich Text: Embedded asset

\n

Embedded Asset

\n
\n
\"\"\n\n
\n
\n \n \n \"\"\n\n \n \n
\n

\n

\n

\n
\n
" }, "rich-text: Embedded Entry With Deep Reference Loop": { - "1": "
\n

Rich Text: Embedded entry with deep reference loop

\n

Embedded entry with deep reference loop

\n

[ContentfulReference]\n Content Reference: Many (2nd level loop)\n : [\n Number: Integer, Text: Short, Content Reference: One (Loop A ->\n B)\n ]

\n

\n

\n
\n
" + "1": "
\n

Rich Text: Embedded entry with deep reference loop

\n

Embedded entry with deep reference loop

\n

[ContentfulContentTypeContentReference]\n Content Reference: Many (2nd level loop)\n : [\n Number: Integer, Text: Short, Content Reference: One (Loop A ->\n B)\n ]

\n

\n

\n
\n
" }, "rich-text: Embedded Entry With Reference Loop": { - "1": "
\n

Rich Text: Embedded entry with reference loop

\n

Embedded entry with reference loop

\n

[ContentfulReference]\n Content Reference: One (Loop B -> A)\n : [\n Content Reference: One (Loop A -> B)\n ]

\n

\n
\n
" - }, - "rich-text: All Features": { - "1": "
\n

Rich Text: All Features

\n

The European languages

\n

are members of the same family. Their separate existence is a myth. For:

\n
    \n
  • \n

    science

    \n
  • \n
  • \n

    music

    \n
  • \n
  • \n

    sport

    \n
  • \n
  • \n

    etc

    \n
  • \n
\n

Europe uses the same vocabulary.

\n
\n
\"\"\n\n \n \n \n
\n

\n
\n

The languages only differ in:

\n
    \n
  1. \n

    their grammar

    \n
  2. \n
  3. \n

    their pronunciation

    \n
  4. \n
  5. \n

    their most common words

    \n
  6. \n
  7. \n

    [Inline-ContentfulText]\n :

    \n
  8. \n
\n

Everyone realizes why a new common language would be desirable: one could\n refuse to pay expensive translators.

\n

{\n \"userId\": 1,\n \"id\": 1,\n \"title\": \"delectus aut autem\",\n \"completed\": false\n }

\n

To achieve this, it would be necessary to have uniform grammar,\n pronunciation and more common words.

\n

[ContentfulLocation] Lat:\n 52.51627\n , Long:\n 13.3777

\n
\n

If several languages coalesce, the grammar of the resulting language is\n more simple and regular than that of the individual languages.

\n
\n

The new common language will be more simple and regular than the existing\n European languages. It will be as simple as Occidental; in fact, it will be\n

\n
\n
" + "1": "
\n

Rich Text: Embedded entry with reference loop

\n

Embedded entry with reference loop

\n

[ContentfulContentTypeContentReference]\n Content Reference: One (Loop B -> A)\n : [\n Content Reference: One (Loop A -> B)\n ]

\n

\n
\n
" }, "rich-text: Inline Entry": { - "1": "
\n

Rich Text: Inline entry

\n

Inline entry with reference loop

\n

Should be rendered after this [Inline-ContentfulText]\n : and before that

\n

\n

\n
\n
" + "1": "
\n

Rich Text: Inline entry

\n

Inline entry with reference loop

\n

Should be rendered after this [Inline-\n ContentfulContentTypeText\n ] and before that

\n

\n

\n
\n
" }, "rich-text: Inline Entry With Deep Reference Loop": { - "1": "
\n

Rich Text: Inline entry with deep reference loop

\n

Inline entry with deep reference loop

\n

Should be rendered after this [Inline-\n ContentfulContentReference\n ] and before that

\n

\n

\n
\n
" + "1": "
\n

Rich Text: Inline entry with deep reference loop

\n

Inline entry with deep reference loop

\n

Should be rendered after this [Inline-\n ContentfulContentTypeContentReference\n ] and before that

\n

\n

\n
\n
" }, "rich-text: Inline Entry With Reference Loop": { - "1": "
\n

Rich Text: Inline entry with reference loop

\n

Inline entry with reference loop

\n

Should be rendered after this [Inline-\n ContentfulContentReference\n ] and before that

\n

\n

\n
\n
", + "1": "
\n

Rich Text: Inline entry with reference loop

\n

Inline entry with reference loop

\n

Should be rendered after this [Inline-\n ContentfulContentTypeContentReference\n ] and before that

\n

\n

\n
\n
" }, "rich-text: Localized": { "1": "
\n

Rich Text: Localized

\n

Rich Text in English

\n
\n
", @@ -85,16 +82,16 @@ module.exports = { }, "content-reference localized": { "english-content-reference-one-localized": { - "1": "
\n

Content Reference: One Localized

\n

[ContentfulNumber]\n 42

\n
" + "1": "
\n

Content Reference: One Localized

\n

[ContentfulContentTypeNumber]\n 42

\n
" }, "english-content-reference-many-localized": { - "1": "
\n

Content Reference: Many Localized

\n

[ContentfulText]\n The quick brown fox jumps over the lazy dog.

\n

[ContentfulNumber]\n 42

\n
" + "1": "
\n

Content Reference: Many Localized

\n

[ContentfulContentTypeText]\n The quick brown fox jumps over the lazy dog.

\n

[ContentfulContentTypeNumber]\n 42

\n
" }, "german-content-reference-one-localized": { - "1": "
\n

Content Reference: One Localized

\n

[ContentfulNumber]\n 4.2

\n
" + "1": "
\n

Content Reference: One Localized

\n

[ContentfulContentTypeNumber]\n 4.2

\n
" }, "german-content-reference-many-localized": { - "1": "
\n

Content Reference: Many Localized

\n

[ContentfulNumber]\n 4.2

\n

[ContentfulText]\n The European languages are members of the same family. Their\n separate existence is a myth. For science, music, sport, etc, Europe uses\n the same vocabulary.\n\n The languages only differ in their grammar, their pronunciation and their\n most common words. Everyone realizes why a new common language would be\n desirable: one could refuse to pay expensive translators.\n\n To achieve this, it would be necessary to have uniform grammar,\n pronunciation and more common words. If several languages coalesce, the\n grammar of the resulting language is more simple and regular than that of\n the individual languages. The new common language will be more simple and\n regular than the existing European languages. It will be as simple as\n Occidental; in fact, it will be.

\n
" + "1": "
\n

Content Reference: Many Localized

\n

[ContentfulContentTypeNumber]\n 4.2

\n

[ContentfulContentTypeText]\n The European languages are members of the same family. Their\n separate existence is a myth. For science, music, sport, etc, Europe uses\n the same vocabulary.\n\n The languages only differ in their grammar, their pronunciation and their\n most common words. Everyone realizes why a new common language would be\n desirable: one could refuse to pay expensive translators.\n\n To achieve this, it would be necessary to have uniform grammar,\n pronunciation and more common words. If several languages coalesce, the\n grammar of the resulting language is more simple and regular than that of\n the individual languages. The new common language will be more simple and\n regular than the existing European languages. It will be as simple as\n Occidental; in fact, it will be.

\n
" } }, "media-reference localized": { diff --git a/e2e-tests/contentful/src/components/references/content-reference.js b/e2e-tests/contentful/src/components/references/content-reference.js index d3b0e02d24cf3..60dcacd74512e 100644 --- a/e2e-tests/contentful/src/components/references/content-reference.js +++ b/e2e-tests/contentful/src/components/references/content-reference.js @@ -1,10 +1,10 @@ import React from "react" -export const ContentfulContentReference = ({ one, many, title }) => { +export const ContentfulContentTypeContentReference = ({ one, many, title }) => { const references = [one, ...(many || [])].filter(Boolean) return (

- [ContentfulReference] {title}: [ + [ContentfulContentTypeContentReference] {title}: [ {references.map(ref => ref.title).join(", ")}]

) diff --git a/e2e-tests/contentful/src/components/references/index.js b/e2e-tests/contentful/src/components/references/index.js index a9d0675bb1577..f9e79b30222d6 100644 --- a/e2e-tests/contentful/src/components/references/index.js +++ b/e2e-tests/contentful/src/components/references/index.js @@ -1,4 +1,4 @@ -export { ContentfulContentReference } from "./content-reference" -export { ContentfulLocation } from "./location" -export { ContentfulNumber } from "./number" -export { ContentfulText } from "./text" +export { ContentfulContentTypeContentReference } from "./content-reference" +export { ContentfulContentTypeLocation } from "./location" +export { ContentfulContentTypeNumber } from "./number" +export { ContentfulContentTypeText } from "./text" diff --git a/e2e-tests/contentful/src/components/references/location.js b/e2e-tests/contentful/src/components/references/location.js index d25a79e529402..2f67d64026e2a 100644 --- a/e2e-tests/contentful/src/components/references/location.js +++ b/e2e-tests/contentful/src/components/references/location.js @@ -1,7 +1,7 @@ import React from "react" -export const ContentfulLocation = ({ location }) => ( +export const ContentfulContentTypeLocation = ({ location }) => (

- [ContentfulLocation] Lat: {location.lat}, Long: {location.lon} + [ContentfulContentTypeLocation] Lat: {location.lat}, Long: {location.lon}

) diff --git a/e2e-tests/contentful/src/components/references/number.js b/e2e-tests/contentful/src/components/references/number.js index db7e048b14636..9d728fe93f554 100644 --- a/e2e-tests/contentful/src/components/references/number.js +++ b/e2e-tests/contentful/src/components/references/number.js @@ -1,5 +1,5 @@ import React from "react" -export const ContentfulNumber = ({ integer, decimal }) => ( -

[ContentfulNumber] {integer || decimal}

+export const ContentfulContentTypeNumber = ({ integer, decimal }) => ( +

[ContentfulContentTypeNumber] {integer || decimal}

) diff --git a/e2e-tests/contentful/src/components/references/text.js b/e2e-tests/contentful/src/components/references/text.js index a8647ece05b1d..eb4ac609836e8 100644 --- a/e2e-tests/contentful/src/components/references/text.js +++ b/e2e-tests/contentful/src/components/references/text.js @@ -1,5 +1,5 @@ import React from "react" -export const ContentfulText = ({ short, longPlain }) => ( -

[ContentfulText] {short || longPlain?.raw}

+export const ContentfulContentTypeText = ({ short, longPlain }) => ( +

[ContentfulContentTypeText] {short || longPlain?.raw}

) diff --git a/e2e-tests/contentful/src/pages/boolean.js b/e2e-tests/contentful/src/pages/boolean.js index d4bd20c11b096..a1392f06d065d 100644 --- a/e2e-tests/contentful/src/pages/boolean.js +++ b/e2e-tests/contentful/src/pages/boolean.js @@ -49,7 +49,7 @@ export default BooleanPage export const pageQuery = graphql` query BooleanQuery { - default: allContentfulBoolean( + default: allContentfulContentTypeBoolean( sort: { fields: sys___id } filter: { sys: { locale: { eq: "en-US" } } @@ -61,7 +61,7 @@ export const pageQuery = graphql` boolean } } - english: allContentfulBoolean( + english: allContentfulContentTypeBoolean( sort: { fields: sys___id } filter: { sys: { locale: { eq: "en-US" } } @@ -73,7 +73,7 @@ export const pageQuery = graphql` booleanLocalized } } - german: allContentfulBoolean( + german: allContentfulContentTypeBoolean( sort: { fields: sys___id } filter: { sys: { locale: { eq: "de-DE" } } diff --git a/e2e-tests/contentful/src/pages/content-reference.js b/e2e-tests/contentful/src/pages/content-reference.js index cc33294438c0d..af6400da98f3b 100644 --- a/e2e-tests/contentful/src/pages/content-reference.js +++ b/e2e-tests/contentful/src/pages/content-reference.js @@ -95,7 +95,7 @@ export default ContentReferencePage export const pageQuery = graphql` query ContentReferenceQuery { - default: allContentfulContentReference( + default: allContentfulContentTypeContentReference( sort: { fields: title } filter: { sys: { locale: { eq: "en-US" } } @@ -112,39 +112,39 @@ export const pageQuery = graphql` sys { id } - ... on ContentfulText { + ... on ContentfulContentTypeText { title short } - ... on ContentfulNumber { + ... on ContentfulContentTypeNumber { title integer } - ... on ContentfulContentReference { + ... on ContentfulContentTypeContentReference { title one { - ... on ContentfulText { + ... on ContentfulContentTypeText { title short } - ... on ContentfulNumber { + ... on ContentfulContentTypeNumber { title integer } - ... on ContentfulContentReference { + ... on ContentfulContentTypeContentReference { title } } many { - ... on ContentfulText { + ... on ContentfulContentTypeText { title short } - ... on ContentfulNumber { + ... on ContentfulContentTypeNumber { title integer } - ... on ContentfulContentReference { + ... on ContentfulContentTypeContentReference { title } } @@ -155,39 +155,39 @@ export const pageQuery = graphql` sys { id } - ... on ContentfulText { + ... on ContentfulContentTypeText { title short } - ... on ContentfulNumber { + ... on ContentfulContentTypeNumber { title integer } - ... on ContentfulContentReference { + ... on ContentfulContentTypeContentReference { title one { - ... on ContentfulText { + ... on ContentfulContentTypeText { title short } - ... on ContentfulNumber { + ... on ContentfulContentTypeNumber { title integer } - ... on ContentfulContentReference { + ... on ContentfulContentTypeContentReference { title } } many { - ... on ContentfulText { + ... on ContentfulContentTypeText { title short } - ... on ContentfulNumber { + ... on ContentfulContentTypeNumber { title integer } - ... on ContentfulContentReference { + ... on ContentfulContentTypeContentReference { title } } @@ -195,7 +195,7 @@ export const pageQuery = graphql` } } } - english: allContentfulContentReference( + english: allContentfulContentTypeContentReference( sort: { fields: title } filter: { sys: { locale: { eq: "en-US" } } @@ -209,7 +209,7 @@ export const pageQuery = graphql` } oneLocalized { __typename - ... on ContentfulNumber { + ... on ContentfulContentTypeNumber { title decimal integer @@ -217,12 +217,12 @@ export const pageQuery = graphql` } manyLocalized { __typename - ... on ContentfulNumber { + ... on ContentfulContentTypeNumber { title decimal integer } - ... on ContentfulText { + ... on ContentfulContentTypeText { title short longPlain { @@ -232,7 +232,7 @@ export const pageQuery = graphql` } } } - german: allContentfulContentReference( + german: allContentfulContentTypeContentReference( sort: { fields: title } filter: { sys: { locale: { eq: "de-DE" } } @@ -246,7 +246,7 @@ export const pageQuery = graphql` } oneLocalized { __typename - ... on ContentfulNumber { + ... on ContentfulContentTypeNumber { title decimal integer @@ -254,12 +254,12 @@ export const pageQuery = graphql` } manyLocalized { __typename - ... on ContentfulNumber { + ... on ContentfulContentTypeNumber { title decimal integer } - ... on ContentfulText { + ... on ContentfulContentTypeText { title short longPlain { diff --git a/e2e-tests/contentful/src/pages/date.js b/e2e-tests/contentful/src/pages/date.js index ef8cb42c32b86..81a2c72d0990e 100644 --- a/e2e-tests/contentful/src/pages/date.js +++ b/e2e-tests/contentful/src/pages/date.js @@ -32,31 +32,35 @@ export default DatePage export const pageQuery = graphql` query DateQuery { - dateTime: contentfulDate(sys: { id: { eq: "38akBjGb3T1t4AjB87wQjo" } }) { + dateTime: contentfulContentTypeDate( + sys: { id: { eq: "38akBjGb3T1t4AjB87wQjo" } } + ) { title date: dateTime formatted: dateTime(formatString: "D.M.YYYY - hh:mm") } - dateTimeTimezone: contentfulDate( + dateTimeTimezone: contentfulContentTypeDate( sys: { id: { eq: "6dZ8pK4tFWZDZPHgSC0tNS" } } ) { title date: dateTimeTimezone formatted: dateTimeTimezone(formatString: "D.M.YYYY - hh:mm (z)") } - date: contentfulDate(sys: { id: { eq: "5FuULz0jl0rKoKUKp2rshf" } }) { + date: contentfulContentTypeDate( + sys: { id: { eq: "5FuULz0jl0rKoKUKp2rshf" } } + ) { title date formatted: date(formatString: "D.M.YYYY") } - dateEnglish: contentfulDate( + dateEnglish: contentfulContentTypeDate( sys: { id: { eq: "1ERWZvDiYELryAZEP1dmKG" }, locale: { eq: "en-US" } } ) { title date: dateLocalized formatted: dateLocalized(formatString: "D.M.YYYY - HH:mm:ss") } - dateGerman: contentfulDate( + dateGerman: contentfulContentTypeDate( sys: { id: { eq: "1ERWZvDiYELryAZEP1dmKG" }, locale: { eq: "de-DE" } } ) { title diff --git a/e2e-tests/contentful/src/pages/download-local.js b/e2e-tests/contentful/src/pages/download-local.js index a5bdddb8a18f2..e5401942fb130 100644 --- a/e2e-tests/contentful/src/pages/download-local.js +++ b/e2e-tests/contentful/src/pages/download-local.js @@ -20,9 +20,7 @@ export default DownloadLocalPage export const pageQuery = graphql` query DownloadLocalQuery { - contentfulAsset(contentful_id: { eq: "3BSI9CgDdAn1JchXmY5IJi" }) { - contentful_id - title + contentfulAsset(sys: { id: { eq: "3BSI9CgDdAn1JchXmY5IJi" } }) { localFile { absolutePath childImageSharp { diff --git a/e2e-tests/contentful/src/pages/json.js b/e2e-tests/contentful/src/pages/json.js index bce1cb1edd3a1..548bce9c30608 100644 --- a/e2e-tests/contentful/src/pages/json.js +++ b/e2e-tests/contentful/src/pages/json.js @@ -61,19 +61,23 @@ export default JSONPage export const pageQuery = graphql` query JSONQuery { - simple: contentfulJson(sys: { id: { eq: "2r6tNjP8brkyy5yLR39hhh" } }) { + simple: contentfulContentTypeJson( + sys: { id: { eq: "2r6tNjP8brkyy5yLR39hhh" } } + ) { json } - complex: contentfulJson(sys: { id: { eq: "2y71nV0cpW9vzTmJybq571" } }) { + complex: contentfulContentTypeJson( + sys: { id: { eq: "2y71nV0cpW9vzTmJybq571" } } + ) { json } - english: contentfulJson( + english: contentfulContentTypeJson( sys: { id: { eq: "7DvTBEPg5P6TRC7dI9zXuO" }, locale: { eq: "en-US" } } ) { title jsonLocalized } - german: contentfulJson( + german: contentfulContentTypeJson( sys: { id: { eq: "7DvTBEPg5P6TRC7dI9zXuO" }, locale: { eq: "de-DE" } } ) { title diff --git a/e2e-tests/contentful/src/pages/location.js b/e2e-tests/contentful/src/pages/location.js index f9757a987d661..9314b17fabdc4 100644 --- a/e2e-tests/contentful/src/pages/location.js +++ b/e2e-tests/contentful/src/pages/location.js @@ -56,7 +56,7 @@ export default LocationPage export const pageQuery = graphql` query LocationQuery { - default: allContentfulLocation( + default: allContentfulContentTypeLocation( sort: { fields: sys___id } filter: { title: { glob: "!*Localized*" } @@ -71,7 +71,7 @@ export const pageQuery = graphql` } } } - english: allContentfulLocation( + english: allContentfulContentTypeLocation( sort: { fields: sys___id } filter: { title: { glob: "*Localized*" } @@ -86,7 +86,7 @@ export const pageQuery = graphql` } } } - german: allContentfulLocation( + german: allContentfulContentTypeLocation( sort: { fields: sys___id } filter: { title: { glob: "*Localized*" } diff --git a/e2e-tests/contentful/src/pages/media-reference.js b/e2e-tests/contentful/src/pages/media-reference.js index dfd9402cfeb8a..f521c3747450c 100644 --- a/e2e-tests/contentful/src/pages/media-reference.js +++ b/e2e-tests/contentful/src/pages/media-reference.js @@ -112,7 +112,7 @@ export default MediaReferencePage export const pageQuery = graphql` query MediaReferenceQuery { - default: allContentfulMediaReference( + default: allContentfulContentTypeMediaReference( sort: { fields: title } filter: { title: { glob: "!*Localized*" } @@ -132,7 +132,7 @@ export const pageQuery = graphql` } } } - english: allContentfulMediaReference( + english: allContentfulContentTypeMediaReference( sort: { fields: title } filter: { title: { glob: "*Localized*" } @@ -158,7 +158,7 @@ export const pageQuery = graphql` } } } - german: allContentfulMediaReference( + german: allContentfulContentTypeMediaReference( sort: { fields: title } filter: { title: { glob: "*Localized*" } diff --git a/e2e-tests/contentful/src/pages/number.js b/e2e-tests/contentful/src/pages/number.js index 946e9b71d3be1..e5d5dc2cc8066 100644 --- a/e2e-tests/contentful/src/pages/number.js +++ b/e2e-tests/contentful/src/pages/number.js @@ -53,7 +53,7 @@ export default NumberPage export const pageQuery = graphql` query NumberQuery { - default: allContentfulNumber( + default: allContentfulContentTypeNumber( sort: { fields: sys___id } filter: { title: { glob: "!*Localized*" } @@ -66,7 +66,7 @@ export const pageQuery = graphql` decimal } } - english: allContentfulNumber( + english: allContentfulContentTypeNumber( sort: { fields: sys___id } filter: { title: { glob: "*Localized*" } @@ -79,7 +79,7 @@ export const pageQuery = graphql` decimalLocalized } } - german: allContentfulNumber( + german: allContentfulContentTypeNumber( sort: { fields: sys___id } filter: { title: { glob: "*Localized*" } diff --git a/e2e-tests/contentful/src/pages/rich-text.js b/e2e-tests/contentful/src/pages/rich-text.js index 12c792bc4eea2..c3488ad37f63a 100644 --- a/e2e-tests/contentful/src/pages/rich-text.js +++ b/e2e-tests/contentful/src/pages/rich-text.js @@ -114,7 +114,7 @@ export default RichTextPage export const pageQuery = graphql` query RichTextQuery { - default: allContentfulRichText( + default: allContentfulContentTypeRichText( sort: { fields: title } filter: { title: { glob: "!*Localized*|*Validated*" } @@ -142,36 +142,36 @@ export const pageQuery = graphql` id type } - ... on ContentfulText { + ... on ContentfulContentTypeText { title short } - ... on ContentfulLocation { + ... on ContentfulContentTypeLocation { location { lat lon } } - ... on ContentfulContentReference { + ... on ContentfulContentTypeContentReference { title one { __typename sys { id } - ... on ContentfulText { + ... on ContentfulContentTypeText { title short } - ... on ContentfulContentReference { + ... on ContentfulContentTypeContentReference { title one { - ... on ContentfulContentReference { + ... on ContentfulContentTypeContentReference { title } } many { - ... on ContentfulContentReference { + ... on ContentfulContentTypeContentReference { title } } @@ -182,23 +182,23 @@ export const pageQuery = graphql` sys { id } - ... on ContentfulText { + ... on ContentfulContentTypeText { title short } - ... on ContentfulNumber { + ... on ContentfulContentTypeNumber { title integer } - ... on ContentfulContentReference { + ... on ContentfulContentTypeContentReference { title one { - ... on ContentfulContentReference { + ... on ContentfulContentTypeContentReference { title } } many { - ... on ContentfulContentReference { + ... on ContentfulContentTypeContentReference { title } } @@ -218,7 +218,7 @@ export const pageQuery = graphql` } } } - english: allContentfulRichText( + english: allContentfulContentTypeRichText( sort: { fields: title } filter: { title: { glob: "*Localized*" } @@ -233,7 +233,7 @@ export const pageQuery = graphql` } } } - german: allContentfulRichText( + german: allContentfulContentTypeRichText( sort: { fields: title } filter: { title: { glob: "*Localized*" } diff --git a/e2e-tests/contentful/src/pages/tags.js b/e2e-tests/contentful/src/pages/tags.js index 9d752ee279ba8..7367b97b9f471 100644 --- a/e2e-tests/contentful/src/pages/tags.js +++ b/e2e-tests/contentful/src/pages/tags.js @@ -88,7 +88,6 @@ const TagsPage = ({ data }) => {
) } - export default TagsPage export const pageQuery = graphql` @@ -99,13 +98,13 @@ export const pageQuery = graphql` contentful_id } } - integers: allContentfulNumber( - sort: { fields: contentful_id } + integers: allContentfulContentTypeNumber( + sort: { fields: sys___id } filter: { metadata: { tags: { elemMatch: { contentful_id: { eq: "numberInteger" } } } } - node_locale: { eq: "en-US" } + sys: { locale: { eq: "en-US" } } } ) { nodes { @@ -113,13 +112,13 @@ export const pageQuery = graphql` integer } } - decimals: allContentfulNumber( - sort: { fields: contentful_id } + decimals: allContentfulContentTypeNumber( + sort: { fields: sys___id } filter: { metadata: { tags: { elemMatch: { contentful_id: { eq: "numberDecimal" } } } } - node_locale: { eq: "en-US" } + sys: { locale: { eq: "en-US" } } } ) { nodes { diff --git a/e2e-tests/contentful/src/pages/text.js b/e2e-tests/contentful/src/pages/text.js index 923c86e743da5..b2e10ceeef546 100644 --- a/e2e-tests/contentful/src/pages/text.js +++ b/e2e-tests/contentful/src/pages/text.js @@ -77,24 +77,24 @@ export default TextPage export const pageQuery = graphql` query TextQuery { - short: contentfulText( + short: contentfulContentTypeText( sys: { id: { eq: "5ZtcN1o7KpN7J7xgiTyaXo" }, locale: { eq: "en-US" } } ) { short } - shortList: contentfulText( + shortList: contentfulContentTypeText( sys: { id: { eq: "7b5U927WTFcQXO2Gewwa2k" }, locale: { eq: "en-US" } } ) { shortList } - longPlain: contentfulText( + longPlain: contentfulContentTypeText( sys: { id: { eq: "6ru8cSC9hZi3Ekvtw7P77S" }, locale: { eq: "en-US" } } ) { longPlain { raw } } - longMarkdownSimple: contentfulText( + longMarkdownSimple: contentfulContentTypeText( sys: { id: { eq: "NyPJw0mcSuCwY2gV0zYny" }, locale: { eq: "en-US" } } ) { longMarkdown { @@ -103,7 +103,7 @@ export const pageQuery = graphql` } } } - longMarkdownComplex: contentfulText( + longMarkdownComplex: contentfulContentTypeText( sys: { id: { eq: "3pwKS9UWsYmOguo4UdE1EB" }, locale: { eq: "en-US" } } ) { longMarkdown { @@ -112,24 +112,24 @@ export const pageQuery = graphql` } } } - shortEnglish: contentfulText( + shortEnglish: contentfulContentTypeText( sys: { id: { eq: "2sQRyOLUexvWZj9nkzS3nN" }, locale: { eq: "en-US" } } ) { shortLocalized } - shortGerman: contentfulText( + shortGerman: contentfulContentTypeText( sys: { id: { eq: "2sQRyOLUexvWZj9nkzS3nN" }, locale: { eq: "de-DE" } } ) { shortLocalized } - longEnglish: contentfulText( + longEnglish: contentfulContentTypeText( sys: { id: { eq: "5csovkwdDBqTKwSblAOHvd" }, locale: { eq: "en-US" } } ) { longLocalized { raw } } - longGerman: contentfulText( + longGerman: contentfulContentTypeText( sys: { id: { eq: "5csovkwdDBqTKwSblAOHvd" }, locale: { eq: "de-DE" } } ) { longLocalized { diff --git a/packages/gatsby-source-contentful/src/__tests__/download-contentful-assets.js b/packages/gatsby-source-contentful/src/__tests__/download-contentful-assets.js index f3f6c21fdf6ee..401d85f409d72 100644 --- a/packages/gatsby-source-contentful/src/__tests__/download-contentful-assets.js +++ b/packages/gatsby-source-contentful/src/__tests__/download-contentful-assets.js @@ -38,8 +38,14 @@ const fixtures = [ fields: { title: { "en-US": `TundraUS`, fr: `TundraFR` }, file: { - "en-US": { url: `//images.ctfassets.net/testing/us-image.jpeg` }, - fr: { url: `//images.ctfassets.net/testing/fr-image.jpg` }, + "en-US": { + url: `//images.ctfassets.net/testing/us-image.jpeg`, + details: { size: 123, image: { width: 123, height: 123 } }, + }, + fr: { + url: `//images.ctfassets.net/testing/fr-image.jpg`, + details: { size: 123, image: { width: 123, height: 123 } }, + }, }, }, sys: { diff --git a/packages/gatsby-source-contentful/src/__tests__/gatsby-node.js b/packages/gatsby-source-contentful/src/__tests__/gatsby-node.js index dd7329213cf3c..104700f790a32 100644 --- a/packages/gatsby-source-contentful/src/__tests__/gatsby-node.js +++ b/packages/gatsby-source-contentful/src/__tests__/gatsby-node.js @@ -86,7 +86,6 @@ describe(`gatsby-node`, () => { getCache, reporter, parentSpan, - schema, }, pluginOptions ) diff --git a/packages/gatsby-source-contentful/src/create-schema-customization.js b/packages/gatsby-source-contentful/src/create-schema-customization.js index 6e16ef59330d3..ee4dc341b46f6 100644 --- a/packages/gatsby-source-contentful/src/create-schema-customization.js +++ b/packages/gatsby-source-contentful/src/create-schema-customization.js @@ -1,8 +1,8 @@ // @ts-check import _ from "lodash" import { fetchContentTypes } from "./fetch" +import { generateSchema } from "./generate-schema" import { createPluginConfig } from "./plugin-options" -import { CODES } from "./report" async function getContentTypesFromContentful({ cache, @@ -12,33 +12,6 @@ async function getContentTypesFromContentful({ // Get content type items from Contentful const contentTypeItems = await fetchContentTypes({ pluginConfig, reporter }) - // Check for restricted content type names and set id based on useNameForId - const useNameForId = pluginConfig.get(`useNameForId`) - const restrictedContentTypes = [`entity`, `reference`, `asset`] - - if (pluginConfig.get(`enableTags`)) { - restrictedContentTypes.push(`tag`) - } - - contentTypeItems.forEach(contentTypeItem => { - // Establish identifier for content type - // Use `name` if specified, otherwise, use internal id (usually a natural-language constant, - // but sometimes a base62 uuid generated by Contentful, hence the option) - let contentTypeItemId = contentTypeItem.sys.id - if (useNameForId) { - contentTypeItemId = contentTypeItem.name.toLowerCase() - } - - if (restrictedContentTypes.includes(contentTypeItemId)) { - reporter.panic({ - id: CODES.FetchContentTypes, - context: { - sourceMessage: `Restricted ContentType name found. The name "${contentTypeItemId}" is not allowed.`, - }, - }) - } - }) - // Store processed content types in cache for sourceNodes const sourceId = `${pluginConfig.get(`spaceId`)}-${pluginConfig.get( `environment` @@ -71,84 +44,6 @@ export async function createSchemaCustomization( }) } - const contentfulTypes = [ - schema.buildInterfaceType({ - name: `ContentfulEntry`, - fields: { - contentful_id: { type: `String!` }, - id: { type: `ID!` }, - node_locale: { type: `String!` }, - }, - extensions: { infer: false }, - interfaces: [`Node`], - }), - schema.buildInterfaceType({ - name: `ContentfulReference`, - fields: { - contentful_id: { type: `String!` }, - id: { type: `ID!` }, - }, - extensions: { infer: false }, - }), - schema.buildObjectType({ - name: `ContentfulAsset`, - fields: { - contentful_id: { type: `String!` }, - id: { type: `ID!` }, - ...(pluginConfig.get(`downloadLocal`) - ? { - localFile: { - type: `File`, - extensions: { - link: { - from: `fields.localFile`, - }, - }, - }, - } - : {}), - }, - interfaces: [`ContentfulReference`, `Node`], - }), - ] - - // Create types for each content type - contentTypeItems.forEach(contentTypeItem => - contentfulTypes.push( - schema.buildObjectType({ - name: _.upperFirst( - _.camelCase( - `Contentful ${ - pluginConfig.get(`useNameForId`) - ? contentTypeItem.name - : contentTypeItem.sys.id - }` - ) - ), - fields: { - contentful_id: { type: `String!` }, - id: { type: `ID!` }, - node_locale: { type: `String!` }, - }, - interfaces: [`ContentfulReference`, `ContentfulEntry`, `Node`], - }) - ) - ) - - if (pluginConfig.get(`enableTags`)) { - contentfulTypes.push( - schema.buildObjectType({ - name: `ContentfulTag`, - fields: { - name: { type: `String!` }, - contentful_id: { type: `String!` }, - id: { type: `ID!` }, - }, - interfaces: [`Node`], - extensions: { dontInfer: {} }, - }) - ) - } - - createTypes(contentfulTypes) + // Generate schemas based on Contentful content model + generateSchema({ createTypes, schema, pluginConfig, contentTypeItems }) } diff --git a/packages/gatsby-source-contentful/src/download-contentful-assets.js b/packages/gatsby-source-contentful/src/download-contentful-assets.js index f6d7f6f82ca0d..e6da9cfc0c5e1 100644 --- a/packages/gatsby-source-contentful/src/download-contentful-assets.js +++ b/packages/gatsby-source-contentful/src/download-contentful-assets.js @@ -48,26 +48,21 @@ export async function downloadContentfulAssets(gatsbyFunctions) { ) bar.start() await distributeWorkload( - assetNodes.map(node => async () => { + assetNodes.map(assetNode => async () => { let fileNodeID const { sys: { id, locale }, - } = node + } = assetNode const remoteDataCacheKey = `contentful-asset-${id}-${locale}` const cacheRemoteData = await cache.get(remoteDataCacheKey) - if (!node.file) { - reporter.log(id, locale) - reporter.warn(`The asset with id: ${id}, contains no file.`) - return Promise.resolve() - } - if (!node.file.url) { + if (!assetNode.url) { reporter.warn( `The asset with id: ${id} has a file but the file contains no url.` ) return Promise.resolve() } - const url = createUrl(node.file.url) + const url = createUrl(assetNode.url) // Avoid downloading the asset again if it's been cached // Note: Contentful Assets do not provide useful metadata @@ -97,10 +92,14 @@ export async function downloadContentfulAssets(gatsbyFunctions) { } if (fileNodeID) { - createNodeField({ node, name: `localFile`, value: fileNodeID }) + createNodeField({ + node: assetNode, + name: `localFile`, + value: fileNodeID, + }) } - return node + return assetNode }), assetDownloadWorkers ) diff --git a/packages/gatsby-source-contentful/src/generate-schema.js b/packages/gatsby-source-contentful/src/generate-schema.js index 27cef28b4c103..915f1a1ba4297 100644 --- a/packages/gatsby-source-contentful/src/generate-schema.js +++ b/packages/gatsby-source-contentful/src/generate-schema.js @@ -14,7 +14,7 @@ const ContentfulDataTypes = new Map([ `Text`, field => { return { - type: `ContentfulNodeTypeText`, + type: `ContentfulText`, extensions: { link: { by: `id`, from: `${field.id}___NODE` }, }, @@ -59,13 +59,13 @@ const ContentfulDataTypes = new Map([ [ `Location`, () => { - return { type: `ContentfulNodeTypeLocation` } + return { type: `ContentfulLocation` } }, ], [ `RichText`, () => { - return { type: `ContentfulNodeTypeRichText` } + return { type: `ContentfulRichText` } }, ], ]) @@ -106,8 +106,8 @@ const translateFieldType = field => { function generateAssetTypes({ createTypes }) { createTypes(` - type ContentfulAsset implements ContentfulInternalReference & Node { - sys: ContentfulInternalSys + type ContentfulAsset implements ContentfulReference & Node { + sys: ContentfulSys id: ID! title: String description: String @@ -129,9 +129,9 @@ export function generateSchema({ }) { // Generic Types createTypes(` - interface ContentfulInternalReference implements Node { + interface ContentfulReference implements Node { id: ID! - sys: ContentfulInternalSys + sys: ContentfulSys } `) @@ -145,7 +145,7 @@ export function generateSchema({ `) createTypes(` - type ContentfulInternalSys @dontInfer { + type ContentfulSys @dontInfer { type: String! id: String! spaceId: String! @@ -161,7 +161,7 @@ export function generateSchema({ createTypes(` interface ContentfulEntry implements Node @dontInfer { id: ID! - sys: ContentfulInternalSys + sys: ContentfulSys } `) @@ -203,7 +203,7 @@ export function generateSchema({ createTypes( schema.buildObjectType({ - name: `ContentfulNodeTypeRichTextAssets`, + name: `ContentfulRichTextAssets`, fields: { block: { type: `[ContentfulAsset]!`, @@ -219,7 +219,7 @@ export function generateSchema({ createTypes( schema.buildObjectType({ - name: `ContentfulNodeTypeRichTextEntries`, + name: `ContentfulRichTextEntries`, fields: { inline: { type: `[ContentfulEntry]!`, @@ -239,16 +239,16 @@ export function generateSchema({ createTypes( schema.buildObjectType({ - name: `ContentfulNodeTypeRichTextLinks`, + name: `ContentfulRichTextLinks`, fields: { assets: { - type: `ContentfulNodeTypeRichTextAssets`, + type: `ContentfulRichTextAssets`, resolve(source) { return source }, }, entries: { - type: `ContentfulNodeTypeRichTextEntries`, + type: `ContentfulRichTextEntries`, resolve(source) { return source }, @@ -259,7 +259,7 @@ export function generateSchema({ createTypes( schema.buildObjectType({ - name: `ContentfulNodeTypeRichText`, + name: `ContentfulRichText`, fields: { json: { type: `JSON`, @@ -268,7 +268,7 @@ export function generateSchema({ }, }, links: { - type: `ContentfulNodeTypeRichTextLinks`, + type: `ContentfulRichTextLinks`, resolve(source) { return source }, @@ -281,7 +281,7 @@ export function generateSchema({ // Location createTypes( schema.buildObjectType({ - name: `ContentfulNodeTypeLocation`, + name: `ContentfulLocation`, fields: { lat: { type: `Float!` }, lon: { type: `Float!` }, @@ -296,7 +296,7 @@ export function generateSchema({ // @todo Is there a way to have this as string and let transformer-remark replace it with an object? createTypes( schema.buildObjectType({ - name: `ContentfulNodeTypeText`, + name: `ContentfulText`, fields: { raw: `String!`, }, @@ -322,22 +322,18 @@ export function generateSchema({ ? contentTypeItem.name : contentTypeItem.sys.id - createTypes( - schema.buildObjectType({ - name: makeTypeName(type), - fields: { - id: { type: `ID!` }, - sys: { type: `ContentfulInternalSys` }, - ...fields, - }, - interfaces: [ - `ContentfulInternalReference`, - `ContentfulEntry`, - `Node`, - ], - extensions: { dontInfer: {} }, - }) - ) + const contentTypeType = { + name: makeTypeName(type), + fields: { + id: { type: `ID!` }, + sys: { type: `ContentfulSys` }, + ...fields, + }, + interfaces: [`ContentfulReference`, `ContentfulEntry`, `Node`], + extensions: { dontInfer: {} }, + } + + createTypes(schema.buildObjectType(contentTypeType)) } catch (err) { err.message = `Unable to create schema for Contentful Content Type ${ contentTypeItem.name || contentTypeItem.sys.id diff --git a/packages/gatsby-source-contentful/src/normalize.js b/packages/gatsby-source-contentful/src/normalize.js index cbe14764d5509..b7b23909fa181 100644 --- a/packages/gatsby-source-contentful/src/normalize.js +++ b/packages/gatsby-source-contentful/src/normalize.js @@ -3,7 +3,7 @@ import _ from "lodash" import { getGatsbyVersion } from "gatsby-core-utils" import { lt, prerelease } from "semver" -const typePrefix = `Contentful` +const typePrefix = `ContentfulContentType` export const makeTypeName = type => _.upperFirst(_.camelCase(`${typePrefix} ${type}`)) @@ -188,7 +188,7 @@ function prepareTextNode(id, node, key, text) { parent: node.id, raw: str, internal: { - type: `ContentfulNodeTypeText`, + type: `ContentfulText`, mediaType: `text/markdown`, content: str, // entryItem.sys.publishedAt is source of truth from contentful @@ -540,7 +540,7 @@ export const createNodesForContentType = ({ } // Link tags - if (pluginConfig.get(`enableTags`)) { + if (pluginConfig.get(`enableTags`) && entryItem.metadata.tags.length) { entryNode.metadata = { tags___NODE: entryItem.metadata.tags.map(tag => createNodeId(`ContentfulTag__${space.sys.id}__${tag.sys.id}`) @@ -592,7 +592,7 @@ export const createAssetNodes = ({ parent: null, children: [], internal: { - type: `${makeTypeName(`Asset`)}`, + type: `ContentfulAsset`, // The content of an asset is guaranteed to be updated if and only if the .sys.updatedAt field changed contentDigest: assetItem.sys.updatedAt, }, From c3f51b0a17216543db2f9ca67a90fc1685320a78 Mon Sep 17 00:00:00 2001 From: axe312ger Date: Wed, 21 Jul 2021 11:37:00 +0100 Subject: [PATCH 22/34] feat: tags are now enabled by default --- e2e-tests/contentful/src/pages/tags.js | 2 +- packages/gatsby-source-contentful/README.md | 8 -- .../src/__fixtures__/rich-text-data.js | 2 + .../src/__fixtures__/starter-blog-data.js | 6 ++ .../src/__tests__/fetch-backoff.js | 11 +++ .../src/__tests__/fetch-network-errors.js | 5 ++ .../src/__tests__/fetch.js | 2 +- .../gatsby-source-contentful/src/fetch.js | 30 ++++---- .../src/generate-schema.js | 73 +++++++++++-------- .../gatsby-source-contentful/src/normalize.js | 9 +-- .../src/plugin-options.js | 1 - 11 files changed, 84 insertions(+), 65 deletions(-) diff --git a/e2e-tests/contentful/src/pages/tags.js b/e2e-tests/contentful/src/pages/tags.js index 7367b97b9f471..0e0a430e1b6f3 100644 --- a/e2e-tests/contentful/src/pages/tags.js +++ b/e2e-tests/contentful/src/pages/tags.js @@ -92,7 +92,7 @@ export default TagsPage export const pageQuery = graphql` query TagsQuery { - tags: allContentfulTag(sort: { fields: contentful_id }) { + tags: allContentfulTag(sort: { fields: id }) { nodes { name contentful_id diff --git a/packages/gatsby-source-contentful/README.md b/packages/gatsby-source-contentful/README.md index 00f4e6a915bcf..59142a9263e69 100644 --- a/packages/gatsby-source-contentful/README.md +++ b/packages/gatsby-source-contentful/README.md @@ -174,12 +174,6 @@ Additional config which will get passed to [Contentfuls JS SDK](https://github.c Use this with caution, you might override values this plugin does set for you to connect to Contentful. -**`enableTags`** [boolean][optional] [default: `false`] - -Enable the new [tags feature](https://www.contentful.com/blog/2021/04/08/governance-tagging-metadata/). This will disallow the content type name `tags` till the next major version of this plugin. - -Learn how to use them at the [Contentful Tags](#contentful-tags) section. - ## How to query for nodes Two standard node types are available from Contentful: `Asset` and `ContentType`. @@ -387,8 +381,6 @@ Check the [Reference Guide of gatsby-plugin-image](https://www.gatsbyjs.com/docs ## [Contentful Tags](https://www.contentful.com/developers/docs/references/content-delivery-api/#/reference/content-tags) -You need to set the `enableTags` flag to `true` to use this new feature. - ### List available tags This example lists all available tags. The sorting is optional. diff --git a/packages/gatsby-source-contentful/src/__fixtures__/rich-text-data.js b/packages/gatsby-source-contentful/src/__fixtures__/rich-text-data.js index 0be1eaa13ee55..02ea0d1a342da 100644 --- a/packages/gatsby-source-contentful/src/__fixtures__/rich-text-data.js +++ b/packages/gatsby-source-contentful/src/__fixtures__/rich-text-data.js @@ -496,6 +496,7 @@ exports.initialSync = () => { }, }, }, + metadata: { tags: [] }, }, { sys: { @@ -658,6 +659,7 @@ exports.initialSync = () => { }, }, }, + metadata: { tags: [] }, }, ], assets: [ diff --git a/packages/gatsby-source-contentful/src/__fixtures__/starter-blog-data.js b/packages/gatsby-source-contentful/src/__fixtures__/starter-blog-data.js index 60dc97f683950..b2d94d44dde96 100644 --- a/packages/gatsby-source-contentful/src/__fixtures__/starter-blog-data.js +++ b/packages/gatsby-source-contentful/src/__fixtures__/starter-blog-data.js @@ -289,6 +289,7 @@ exports.initialSync = () => { publishDate: { "en-US": `2017-05-12T00:00+02:00` }, tags: { "en-US": [`javascript`] }, }, + metadata: { tags: [] }, }, { sys: { @@ -349,6 +350,7 @@ exports.initialSync = () => { publishDate: { "en-US": `2017-05-15T00:00+02:00` }, tags: { "en-US": [`general`] }, }, + metadata: { tags: [] }, }, { sys: { @@ -409,6 +411,7 @@ exports.initialSync = () => { publishDate: { "en-US": `2017-05-16T00:00+02:00` }, tags: { "en-US": [`javascript`, `static-sites`] }, }, + metadata: { tags: [] }, }, { sys: { @@ -461,6 +464,7 @@ exports.initialSync = () => { }, }, }, + metadata: { tags: [] }, }, ], assets: [ @@ -734,6 +738,7 @@ exports.createBlogPost = () => { }, publishDate: { "en-US": `2020-04-01T00:00+02:00` }, }, + metadata: { tags: [] }, }, ], assets: [ @@ -887,6 +892,7 @@ exports.updateBlogPost = () => { }, publishDate: { "en-US": `2020-05-15T00:00+02:00` }, }, + metadata: { tags: [] }, }, ], assets: [], diff --git a/packages/gatsby-source-contentful/src/__tests__/fetch-backoff.js b/packages/gatsby-source-contentful/src/__tests__/fetch-backoff.js index f9c951e172bd6..f9a10c5e40317 100644 --- a/packages/gatsby-source-contentful/src/__tests__/fetch-backoff.js +++ b/packages/gatsby-source-contentful/src/__tests__/fetch-backoff.js @@ -83,6 +83,12 @@ describe(`fetch-backoff`, () => { `/spaces/${options.spaceId}/environments/master/sync?initial=true&limit=444` ) .reply(200, { items: [] }) + // Tags + .get( + `/spaces/${options.spaceId}/environments/master/tags?skip=0&limit=1000&order=sys.createdAt` + ) + .reply(200, { items: [] }) + await fetchContent({ pluginConfig, reporter, syncToken: null }) expect(reporter.panic).not.toBeCalled() @@ -120,6 +126,11 @@ describe(`fetch-backoff`, () => { `/spaces/${options.spaceId}/environments/master/sync?initial=true&limit=1000` ) .reply(200, { items: [] }) + // Tags + .get( + `/spaces/${options.spaceId}/environments/master/tags?skip=0&limit=1000&order=sys.createdAt` + ) + .reply(200, { items: [] }) await fetchContent({ pluginConfig, reporter, syncToken: null }) diff --git a/packages/gatsby-source-contentful/src/__tests__/fetch-network-errors.js b/packages/gatsby-source-contentful/src/__tests__/fetch-network-errors.js index d629c5966cbce..abdda891b617b 100644 --- a/packages/gatsby-source-contentful/src/__tests__/fetch-network-errors.js +++ b/packages/gatsby-source-contentful/src/__tests__/fetch-network-errors.js @@ -66,6 +66,11 @@ describe(`fetch-retry`, () => { `/spaces/${options.spaceId}/environments/master/sync?initial=true&limit=1000` ) .reply(200, { items: [] }) + // Tags + .get( + `/spaces/${options.spaceId}/environments/master/tags?skip=0&limit=1000&order=sys.createdAt` + ) + .reply(200, { items: [] }) await fetchContent({ pluginConfig, reporter, syncToken: null }) diff --git a/packages/gatsby-source-contentful/src/__tests__/fetch.js b/packages/gatsby-source-contentful/src/__tests__/fetch.js index ee3da2e893090..a89034629a73d 100644 --- a/packages/gatsby-source-contentful/src/__tests__/fetch.js +++ b/packages/gatsby-source-contentful/src/__tests__/fetch.js @@ -194,7 +194,7 @@ it(`calls contentful.getContentTypes with custom plugin option page limit`, asyn }) describe(`Tags feature`, () => { - it(`tags are disabled by default`, async () => { + it(`calls contentful.getTags`, async () => { await fetchContent({ pluginConfig: createPluginConfig({ accessToken: `6f35edf0db39085e9b9c19bd92943e4519c77e72c852d961968665f1324bfc94`, diff --git a/packages/gatsby-source-contentful/src/fetch.js b/packages/gatsby-source-contentful/src/fetch.js index 209153198fefa..6815e6abb73c6 100644 --- a/packages/gatsby-source-contentful/src/fetch.js +++ b/packages/gatsby-source-contentful/src/fetch.js @@ -325,22 +325,20 @@ export async function fetchContent({ syncToken, pluginConfig, reporter }) { } // We need to fetch tags with the non-sync API as the sync API doesn't support this. - let tagItems = [] - if (pluginConfig.get(`enableTags`)) { - try { - const tagsResult = await pagedGet(client, `getTags`, pageLimit) - tagItems = tagsResult.items - reporter.verbose(`Tags fetched ${tagItems.length}`) - } catch (e) { - reporter.panic({ - id: CODES.FetchTags, - context: { - sourceMessage: `Error fetching tags: ${createContentfulErrorMessage( - e - )}`, - }, - }) - } + let tagItems + try { + const tagsResult = await pagedGet(client, `getTags`, pageLimit) + tagItems = tagsResult.items + reporter.verbose(`Tags fetched ${tagItems.length}`) + } catch (e) { + reporter.panic({ + id: CODES.FetchTags, + context: { + sourceMessage: `Error fetching tags: ${createContentfulErrorMessage( + e + )}`, + }, + }) } const result = { diff --git a/packages/gatsby-source-contentful/src/generate-schema.js b/packages/gatsby-source-contentful/src/generate-schema.js index 915f1a1ba4297..fe32586afa7a0 100644 --- a/packages/gatsby-source-contentful/src/generate-schema.js +++ b/packages/gatsby-source-contentful/src/generate-schema.js @@ -107,7 +107,7 @@ const translateFieldType = field => { function generateAssetTypes({ createTypes }) { createTypes(` type ContentfulAsset implements ContentfulReference & Node { - sys: ContentfulSys + sys: ContentfulSys! id: ID! title: String description: String @@ -131,7 +131,7 @@ export function generateSchema({ createTypes(` interface ContentfulReference implements Node { id: ID! - sys: ContentfulSys + sys: ContentfulSys! } `) @@ -159,12 +159,36 @@ export function generateSchema({ `) createTypes(` - interface ContentfulEntry implements Node @dontInfer { + interface ContentfulEntry implements ContentfulReference & Node @dontInfer { id: ID! - sys: ContentfulSys + sys: ContentfulSys! + metadata: ContentfulMetadata! } `) + createTypes( + schema.buildObjectType({ + name: `ContentfulMetadata`, + fields: { + tags: { type: `[ContentfulTag]!` }, + }, + extensions: { dontInfer: {} }, + }) + ) + + createTypes( + schema.buildObjectType({ + name: `ContentfulTag`, + fields: { + name: { type: `String!` }, + contentful_id: { type: `String!` }, + id: { type: `ID!` }, + }, + interfaces: [`Node`], + extensions: { dontInfer: {} }, + }) + ) + // Assets generateAssetTypes({ createTypes }) @@ -186,21 +210,6 @@ export function generateSchema({ } // Contentful specific types - if (pluginConfig.get(`enableTags`)) { - createTypes( - schema.buildObjectType({ - name: `ContentfulTag`, - fields: { - name: { type: `String!` }, - contentful_id: { type: `String!` }, - id: { type: `ID!` }, - }, - interfaces: [`Node`], - extensions: { dontInfer: {} }, - }) - ) - } - createTypes( schema.buildObjectType({ name: `ContentfulRichTextAssets`, @@ -300,6 +309,7 @@ export function generateSchema({ fields: { raw: `String!`, }, + // @todo do we need a node interface here? interfaces: [`Node`], extensions: { dontInfer: {}, @@ -322,18 +332,19 @@ export function generateSchema({ ? contentTypeItem.name : contentTypeItem.sys.id - const contentTypeType = { - name: makeTypeName(type), - fields: { - id: { type: `ID!` }, - sys: { type: `ContentfulSys` }, - ...fields, - }, - interfaces: [`ContentfulReference`, `ContentfulEntry`, `Node`], - extensions: { dontInfer: {} }, - } - - createTypes(schema.buildObjectType(contentTypeType)) + createTypes( + schema.buildObjectType({ + name: makeTypeName(type), + fields: { + id: { type: `ID!` }, + sys: { type: `ContentfulSys!` }, + metadata: { type: `ContentfulMetadata!` }, + ...fields, + }, + interfaces: [`ContentfulReference`, `ContentfulEntry`, `Node`], + extensions: { dontInfer: {} }, + }) + ) } catch (err) { err.message = `Unable to create schema for Contentful Content Type ${ contentTypeItem.name || contentTypeItem.sys.id diff --git a/packages/gatsby-source-contentful/src/normalize.js b/packages/gatsby-source-contentful/src/normalize.js index b7b23909fa181..13aefdbea2892 100644 --- a/packages/gatsby-source-contentful/src/normalize.js +++ b/packages/gatsby-source-contentful/src/normalize.js @@ -537,17 +537,12 @@ export const createNodesForContentType = ({ entryNode = { ...entryItemFields, ...entryNode, - } - - // Link tags - if (pluginConfig.get(`enableTags`) && entryItem.metadata.tags.length) { - entryNode.metadata = { + metadata: { tags___NODE: entryItem.metadata.tags.map(tag => createNodeId(`ContentfulTag__${space.sys.id}__${tag.sys.id}`) ), - } + }, } - return entryNode }) .filter(Boolean) diff --git a/packages/gatsby-source-contentful/src/plugin-options.js b/packages/gatsby-source-contentful/src/plugin-options.js index 397995090cd83..44ce4fff02ffa 100644 --- a/packages/gatsby-source-contentful/src/plugin-options.js +++ b/packages/gatsby-source-contentful/src/plugin-options.js @@ -11,7 +11,6 @@ const defaultOptions = { localeFilter: () => true, pageLimit: DEFAULT_PAGE_LIMIT, useNameForId: true, - enableTags: false, } const createPluginConfig = pluginOptions => { From d95e75c0225acd481143b633742341d75fa689e2 Mon Sep 17 00:00:00 2001 From: axe312ger Date: Tue, 27 Jul 2021 16:55:33 +0100 Subject: [PATCH 23/34] fix: tags schema --- e2e-tests/contentful/gatsby-config.js | 1 - packages/gatsby-source-contentful/src/generate-schema.js | 7 ++++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/e2e-tests/contentful/gatsby-config.js b/e2e-tests/contentful/gatsby-config.js index 5d2a8e90d134d..9d12a02b4e5ec 100644 --- a/e2e-tests/contentful/gatsby-config.js +++ b/e2e-tests/contentful/gatsby-config.js @@ -11,7 +11,6 @@ module.exports = { // Use: https://www.gatsbyjs.com/docs/how-to/local-development/environment-variables/ spaceId: `k8iqpp6u0ior`, accessToken: `hO_7N0bLaCJFbu5nL3QVekwNeB_TNtg6tOCB_9qzKUw`, - enableTags: true, downloadLocal: true, }, }, diff --git a/packages/gatsby-source-contentful/src/generate-schema.js b/packages/gatsby-source-contentful/src/generate-schema.js index fe32586afa7a0..3327bbfe6a9cc 100644 --- a/packages/gatsby-source-contentful/src/generate-schema.js +++ b/packages/gatsby-source-contentful/src/generate-schema.js @@ -170,7 +170,12 @@ export function generateSchema({ schema.buildObjectType({ name: `ContentfulMetadata`, fields: { - tags: { type: `[ContentfulTag]!` }, + tags: { + type: `[ContentfulTag]!`, + extensions: { + link: { by: `id`, from: `tags___NODE` }, + }, + }, }, extensions: { dontInfer: {} }, }) From 70841c7eac8f77374ae26bddf3c0dc8b56f47e88 Mon Sep 17 00:00:00 2001 From: axe312ger Date: Tue, 27 Jul 2021 16:55:53 +0100 Subject: [PATCH 24/34] refactor: clean up code and improve comments --- packages/gatsby-source-contentful/src/source-nodes.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/gatsby-source-contentful/src/source-nodes.js b/packages/gatsby-source-contentful/src/source-nodes.js index be4c23995180d..bed7bfd7118dd 100644 --- a/packages/gatsby-source-contentful/src/source-nodes.js +++ b/packages/gatsby-source-contentful/src/source-nodes.js @@ -337,6 +337,7 @@ export async function sourceNodes( ) creationActivity.start() + // Create nodes for each entry of each content type for (let i = 0; i < contentTypeItems.length; i++) { const contentTypeItem = contentTypeItems[i] From c5daf4b24b2495db2140773faffb795f5f2569fd Mon Sep 17 00:00:00 2001 From: axe312ger Date: Thu, 18 Nov 2021 17:50:42 +0100 Subject: [PATCH 25/34] clean up, fix tests, get downloadAssets working again --- .../contentful/src/pages/download-local.js | 10 ++- .../__fixtures__/restricted-content-type.js | 80 ------------------- .../__tests__/download-contentful-assets.js | 2 + .../src/__tests__/fetch.js | 15 ---- .../src/__tests__/gatsby-node.js | 1 - .../src/download-contentful-assets.js | 4 +- .../src/generate-schema.js | 7 ++ 7 files changed, 16 insertions(+), 103 deletions(-) delete mode 100644 packages/gatsby-source-contentful/src/__fixtures__/restricted-content-type.js diff --git a/e2e-tests/contentful/src/pages/download-local.js b/e2e-tests/contentful/src/pages/download-local.js index e5401942fb130..bd75f86a3d911 100644 --- a/e2e-tests/contentful/src/pages/download-local.js +++ b/e2e-tests/contentful/src/pages/download-local.js @@ -21,10 +21,12 @@ export default DownloadLocalPage export const pageQuery = graphql` query DownloadLocalQuery { contentfulAsset(sys: { id: { eq: "3BSI9CgDdAn1JchXmY5IJi" } }) { - localFile { - absolutePath - childImageSharp { - gatsbyImageData + fields { + localFile { + absolutePath + childImageSharp { + gatsbyImageData + } } } } diff --git a/packages/gatsby-source-contentful/src/__fixtures__/restricted-content-type.js b/packages/gatsby-source-contentful/src/__fixtures__/restricted-content-type.js deleted file mode 100644 index 8adda16238442..0000000000000 --- a/packages/gatsby-source-contentful/src/__fixtures__/restricted-content-type.js +++ /dev/null @@ -1,80 +0,0 @@ -exports.contentTypeItems = () => [ - { - sys: { - space: { - sys: { - type: `Link`, - linkType: `Space`, - id: `uzfinxahlog0`, - contentful_id: `uzfinxahlog0`, - }, - }, - id: `reference`, - type: `ContentType`, - createdAt: `2020-06-03T14:17:18.696Z`, - updatedAt: `2020-06-03T14:17:18.696Z`, - environment: { - sys: { - id: `master`, - type: `Link`, - linkType: `Environment`, - }, - }, - revision: 1, - contentful_id: `person`, - }, - displayField: `name`, - name: `Reference`, - description: ``, - fields: [ - { - id: `name`, - name: `Name`, - type: `Symbol`, - localized: false, - required: true, - disabled: false, - omitted: false, - }, - ], - }, -] - -exports.initialSync = () => { - return { - currentSyncData: { - entries: [], - assets: [], - deletedEntries: [], - deletedAssets: [], - nextSyncToken: `12345`, - }, - defaultLocale: `en-US`, - locales: [ - { - code: `en-US`, - name: `English (United States)`, - default: true, - fallbackCode: null, - sys: { - id: `1uSElBQA68GRKF30tpTxxT`, - type: `Locale`, - version: 1, - }, - }, - ], - space: { - sys: { type: `Space`, id: `uzfinxahlog0` }, - name: `Starter Gatsby Blog`, - locales: [ - { - code: `en-US`, - default: true, - name: `English (United States)`, - fallbackCode: null, - }, - ], - }, - tagItems: [], - } -} diff --git a/packages/gatsby-source-contentful/src/__tests__/download-contentful-assets.js b/packages/gatsby-source-contentful/src/__tests__/download-contentful-assets.js index 401d85f409d72..f9a018efb303e 100644 --- a/packages/gatsby-source-contentful/src/__tests__/download-contentful-assets.js +++ b/packages/gatsby-source-contentful/src/__tests__/download-contentful-assets.js @@ -16,6 +16,8 @@ jest.mock(`gatsby-source-filesystem`, () => { }) const reporter = { + info: jest.fn(), + warn: jest.fn(), createProgress: jest.fn(() => { return { start: jest.fn(), diff --git a/packages/gatsby-source-contentful/src/__tests__/fetch.js b/packages/gatsby-source-contentful/src/__tests__/fetch.js index a89034629a73d..b7541b0c94af7 100644 --- a/packages/gatsby-source-contentful/src/__tests__/fetch.js +++ b/packages/gatsby-source-contentful/src/__tests__/fetch.js @@ -205,21 +205,6 @@ describe(`Tags feature`, () => { syncToken: null, }) - expect(reporter.panic).not.toBeCalled() - expect(mockClient.getTags).not.toBeCalled() - }) - it(`calls contentful.getTags when enabled`, async () => { - await fetchContent({ - pluginConfig: createPluginConfig({ - accessToken: `6f35edf0db39085e9b9c19bd92943e4519c77e72c852d961968665f1324bfc94`, - spaceId: `rocybtov1ozk`, - pageLimit: 50, - enableTags: true, - }), - reporter, - syncToken: null, - }) - expect(reporter.panic).not.toBeCalled() expect(mockClient.getTags).toHaveBeenCalledWith({ limit: 50, diff --git a/packages/gatsby-source-contentful/src/__tests__/gatsby-node.js b/packages/gatsby-source-contentful/src/__tests__/gatsby-node.js index 104700f790a32..b7c01eb55d47a 100644 --- a/packages/gatsby-source-contentful/src/__tests__/gatsby-node.js +++ b/packages/gatsby-source-contentful/src/__tests__/gatsby-node.js @@ -7,7 +7,6 @@ import { makeId } from "../normalize" import startersBlogFixture from "../__fixtures__/starter-blog-data" import richTextFixture from "../__fixtures__/rich-text-data" -import restrictedContentTypeFixture from "../__fixtures__/restricted-content-type" jest.mock(`../fetch`) diff --git a/packages/gatsby-source-contentful/src/download-contentful-assets.js b/packages/gatsby-source-contentful/src/download-contentful-assets.js index e6da9cfc0c5e1..c15c162a9168f 100644 --- a/packages/gatsby-source-contentful/src/download-contentful-assets.js +++ b/packages/gatsby-source-contentful/src/download-contentful-assets.js @@ -57,9 +57,7 @@ export async function downloadContentfulAssets(gatsbyFunctions) { const cacheRemoteData = await cache.get(remoteDataCacheKey) if (!assetNode.url) { - reporter.warn( - `The asset with id: ${id} has a file but the file contains no url.` - ) + reporter.warn(`The asset with id: ${id} has no url.`) return Promise.resolve() } const url = createUrl(assetNode.url) diff --git a/packages/gatsby-source-contentful/src/generate-schema.js b/packages/gatsby-source-contentful/src/generate-schema.js index 3327bbfe6a9cc..27d38d3122aca 100644 --- a/packages/gatsby-source-contentful/src/generate-schema.js +++ b/packages/gatsby-source-contentful/src/generate-schema.js @@ -105,6 +105,12 @@ const translateFieldType = field => { } function generateAssetTypes({ createTypes }) { + // @todo can we avoid this subfield? + createTypes(` + type ContentfulAssetFields { + localFile: File + } + `) createTypes(` type ContentfulAsset implements ContentfulReference & Node { sys: ContentfulSys! @@ -117,6 +123,7 @@ function generateAssetTypes({ createTypes }) { size: Int width: Int height: Int + fields: ContentfulAssetFields } `) } From 1f1beb90141f8c0424f72d302958ae631fc741be Mon Sep 17 00:00:00 2001 From: axe312ger Date: Fri, 19 Nov 2021 11:10:33 +0100 Subject: [PATCH 26/34] more small fixes --- e2e-tests/contentful/src/pages/gatsby-plugin-image.js | 4 ++-- packages/gatsby-transformer-sqip/src/extend-node-type.js | 4 +--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/e2e-tests/contentful/src/pages/gatsby-plugin-image.js b/e2e-tests/contentful/src/pages/gatsby-plugin-image.js index deb54a7640138..0330f8f106ebf 100644 --- a/e2e-tests/contentful/src/pages/gatsby-plugin-image.js +++ b/e2e-tests/contentful/src/pages/gatsby-plugin-image.js @@ -129,14 +129,14 @@ const GatsbyPluginImagePage = ({ data }) => {

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

{node.description &&

{node.description}

} {node.customImageFormats ? ( ) : ( - + )}
))} diff --git a/packages/gatsby-transformer-sqip/src/extend-node-type.js b/packages/gatsby-transformer-sqip/src/extend-node-type.js index d07b79a382f2d..7673cee8d488a 100644 --- a/packages/gatsby-transformer-sqip/src/extend-node-type.js +++ b/packages/gatsby-transformer-sqip/src/extend-node-type.js @@ -194,9 +194,7 @@ async function sqipContentful({ type, cache, store }) { mimeTypeExtensions, } = require(`gatsby-source-contentful/image-helpers`) - const { - file: { contentType, url: imgUrl, fileName }, - } = asset + const { contentType, url: imgUrl, fileName } = asset if (!contentType.includes(`image/`)) { return null From 50beb260785e32ea33b8a410a85ecad936eecc3d Mon Sep 17 00:00:00 2001 From: axe312ger Date: Fri, 26 Nov 2021 13:59:14 +0100 Subject: [PATCH 27/34] fix: align downloadLocal scheme and gatsby-plugin-image --- .../contentful/src/pages/download-local.js | 4 +- .../src/gatsby-plugin-image.js | 10 +--- .../src/generate-schema.js | 56 ++++++++++--------- 3 files changed, 37 insertions(+), 33 deletions(-) diff --git a/e2e-tests/contentful/src/pages/download-local.js b/e2e-tests/contentful/src/pages/download-local.js index bd75f86a3d911..564302b009891 100644 --- a/e2e-tests/contentful/src/pages/download-local.js +++ b/e2e-tests/contentful/src/pages/download-local.js @@ -10,7 +10,9 @@ const DownloadLocalPage = ({ data }) => {

Test downloadLocal feature

) diff --git a/packages/gatsby-source-contentful/src/gatsby-plugin-image.js b/packages/gatsby-source-contentful/src/gatsby-plugin-image.js index 9b57ebd001ef2..73e4d9a78ee08 100644 --- a/packages/gatsby-source-contentful/src/gatsby-plugin-image.js +++ b/packages/gatsby-source-contentful/src/gatsby-plugin-image.js @@ -29,7 +29,7 @@ export const getBase64Image = (imageProps, cache) => { // Keep aspect ratio, image format and other transform options const { aspectRatio } = imageProps - const originalFormat = imageProps.image.file.contentType.split(`/`)[1] + const originalFormat = imageProps.image.contentType.split(`/`)[1] const toFormat = imageProps.options.toFormat const imageOptions = { ...imageProps.options, @@ -53,9 +53,7 @@ export const getBase64Image = (imageProps, cache) => { } const loadImage = async () => { - const { - file: { contentType }, - } = imageProps.image + const { contentType } = imageProps.image const extension = mimeTypeExtensions.get(contentType) @@ -124,9 +122,7 @@ const getDominantColor = async ({ image, options, cache }) => { } try { - const { - file: { contentType, url: imgUrl, fileName }, - } = image + const { contentType, url: imgUrl, fileName } = image if (contentType.indexOf(`image/`) !== 0) { return null diff --git a/packages/gatsby-source-contentful/src/generate-schema.js b/packages/gatsby-source-contentful/src/generate-schema.js index 27d38d3122aca..d3203d8f8abb4 100644 --- a/packages/gatsby-source-contentful/src/generate-schema.js +++ b/packages/gatsby-source-contentful/src/generate-schema.js @@ -104,30 +104,6 @@ const translateFieldType = field => { return fieldType } -function generateAssetTypes({ createTypes }) { - // @todo can we avoid this subfield? - createTypes(` - type ContentfulAssetFields { - localFile: File - } - `) - createTypes(` - type ContentfulAsset implements ContentfulReference & Node { - sys: ContentfulSys! - id: ID! - title: String - description: String - contentType: String - fileName: String - url: String - size: Int - width: Int - height: Int - fields: ContentfulAssetFields - } - `) -} - export function generateSchema({ createTypes, schema, @@ -202,7 +178,37 @@ export function generateSchema({ ) // Assets - generateAssetTypes({ createTypes }) + createTypes( + schema.buildObjectType({ + name: `ContentfulAssetFields`, + fields: { + localFile: { + type: `File`, + extensions: { + link: { + by: `id`, + }, + }, + }, + }, + extensions: { dontInfer: {} }, + }) + ) + createTypes(` + type ContentfulAsset implements ContentfulReference & Node { + sys: ContentfulSys! + id: ID! + title: String + description: String + contentType: String + fileName: String + url: String + size: Int + width: Int + height: Int + fields: ContentfulAssetFields + } + `) // Rich Text const makeRichTextLinksResolver = From 6c6953456e610df96d2ee809d01f0f3735990afd Mon Sep 17 00:00:00 2001 From: axe312ger Date: Fri, 26 Nov 2021 14:11:22 +0100 Subject: [PATCH 28/34] style: use object syntax everywhere to define schema --- .../src/generate-schema.js | 126 +++++++++++------- 1 file changed, 77 insertions(+), 49 deletions(-) diff --git a/packages/gatsby-source-contentful/src/generate-schema.js b/packages/gatsby-source-contentful/src/generate-schema.js index d3203d8f8abb4..24c0317047198 100644 --- a/packages/gatsby-source-contentful/src/generate-schema.js +++ b/packages/gatsby-source-contentful/src/generate-schema.js @@ -111,43 +111,66 @@ export function generateSchema({ contentTypeItems, }) { // Generic Types - createTypes(` - interface ContentfulReference implements Node { - id: ID! - sys: ContentfulSys! - } - `) + createTypes( + schema.buildInterfaceType({ + name: `ContentfulReference`, + fields: { + id: { type: `ID!` }, + sys: { type: `ContentfulSys!` }, + }, + interfaces: [`Node`], + }) + ) - createTypes(` - type ContentfulContentType implements Node { - id: ID! - name: String! - displayField: String! - description: String! - } - `) + createTypes( + schema.buildInterfaceType({ + name: `ContentfulEntry`, + fields: { + id: { type: `ID!` }, + sys: { type: `ContentfulSys!` }, + metadata: { type: `ContentfulMetadata!` }, + }, + interfaces: [`ContentfulReference`, `Node`], + }) + ) - createTypes(` - type ContentfulSys @dontInfer { - type: String! - id: String! - spaceId: String! - environmentId: String! - contentType: ContentfulContentType @link(by: "id", from: "contentType___NODE") - firstPublishedAt: Date! - publishedAt: Date! - publishedVersion: Int! - locale: String! - } - `) + createTypes( + schema.buildObjectType({ + name: `ContentfulContentType`, + fields: { + id: { type: `ID!` }, + name: { type: `String!` }, + displayField: { type: `String!` }, + description: { type: `String!` }, + }, + interfaces: [`Node`], + extensions: { dontInfer: {} }, + }) + ) - createTypes(` - interface ContentfulEntry implements ContentfulReference & Node @dontInfer { - id: ID! - sys: ContentfulSys! - metadata: ContentfulMetadata! - } - `) + createTypes( + schema.buildObjectType({ + name: `ContentfulSys`, + fields: { + id: { type: ` String!` }, + type: { type: ` String!` }, + spaceId: { type: ` String!` }, + environmentId: { type: ` String!` }, + contentType: { + type: `ContentfulContentType`, + extensions: { + link: { by: `id`, from: `contentType___NODE` }, + }, + }, + firstPublishedAt: { type: ` Date!` }, + publishedAt: { type: ` Date!` }, + publishedVersion: { type: ` Int!` }, + locale: { type: ` String!` }, + }, + interfaces: [`Node`], + extensions: { dontInfer: {} }, + }) + ) createTypes( schema.buildObjectType({ @@ -194,21 +217,26 @@ export function generateSchema({ extensions: { dontInfer: {} }, }) ) - createTypes(` - type ContentfulAsset implements ContentfulReference & Node { - sys: ContentfulSys! - id: ID! - title: String - description: String - contentType: String - fileName: String - url: String - size: Int - width: Int - height: Int - fields: ContentfulAssetFields - } - `) + createTypes( + schema.buildObjectType({ + name: `ContentfulAsset`, + fields: { + id: { type: `ID!` }, + sys: { type: `ContentfulSys!` }, + title: { type: `String` }, + description: { type: `String` }, + contentType: { type: `String` }, + fileName: { type: `String` }, + url: { type: `String` }, + size: { type: `Int` }, + width: { type: `Int` }, + height: { type: `Int` }, + fields: { type: `ContentfulAssetFields` }, + }, + interfaces: [`ContentfulReference`, `Node`], + extensions: { dontInfer: {} }, + }) + ) // Rich Text const makeRichTextLinksResolver = From fb3c6414c88d8ccc62d534907da8af6568ce607a Mon Sep 17 00:00:00 2001 From: axe312ger Date: Mon, 29 Nov 2021 14:08:13 +0100 Subject: [PATCH 29/34] fix: make unit tests pass. Solution for deleted entries still needs work --- .../src/__tests__/gatsby-node.js | 11 ++++++++--- .../src/__tests__/gatsby-plugin-image.js | 2 +- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/packages/gatsby-source-contentful/src/__tests__/gatsby-node.js b/packages/gatsby-source-contentful/src/__tests__/gatsby-node.js index b7c01eb55d47a..9768671b61256 100644 --- a/packages/gatsby-source-contentful/src/__tests__/gatsby-node.js +++ b/packages/gatsby-source-contentful/src/__tests__/gatsby-node.js @@ -157,9 +157,14 @@ describe(`gatsby-node`, () => { const referenceKey = `${currentContentType.name.toLowerCase()}___NODE` const reference = references.get(linkId) const linkedNode = getNode(linkId) - reference[referenceKey] = - reference[referenceKey] || linkedNode[referenceKey] || [] - reference[referenceKey].push(nodeId) + reference[referenceKey] = [ + ...(reference[referenceKey] || + linkedNode[referenceKey] || + []), + ] + if (!reference[referenceKey].includes(nodeId)) { + reference[referenceKey].push(nodeId) + } references.set(linkId, reference) } break diff --git a/packages/gatsby-source-contentful/src/__tests__/gatsby-plugin-image.js b/packages/gatsby-source-contentful/src/__tests__/gatsby-plugin-image.js index 571691402f9bd..f182b8158652e 100644 --- a/packages/gatsby-source-contentful/src/__tests__/gatsby-plugin-image.js +++ b/packages/gatsby-source-contentful/src/__tests__/gatsby-plugin-image.js @@ -95,7 +95,7 @@ describe(`contentful extend node type`, () => { spaceId: `k8iqpp6u0ior`, createdAt: `2021-03-22T10:10:34.647Z`, updatedAt: `2021-03-22T10:10:34.647Z`, - file: { contentType: `image/png` }, + contentType: `image/png`, title: `Contentful Logo PNG`, description: ``, node_locale: `en-US`, From a5af79f312e4a400224bbac47c05bb8e747dd693 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benedikt=20R=C3=B6tsch?= Date: Mon, 29 Nov 2021 16:38:41 +0100 Subject: [PATCH 30/34] feat: use union for reference fields with validation (#31395) Also: * test: add unit tests for schema customization * fix: rich text inline rendering * test: update e2e test schema dump --- e2e-tests/contentful/schema.gql | 88 +- e2e-tests/contentful/snapshots.js | 4 +- .../contentful/src/pages/content-reference.js | 17 +- e2e-tests/contentful/src/pages/rich-text.js | 20 +- .../src/__fixtures__/content-types.js | 786 ++++++++++++++++ .../create-schema-customization.js.snap | 843 ++++++++++++++++++ .../__tests__/create-schema-customization.js | 46 + .../src/generate-schema.js | 69 +- .../gatsby-source-contentful/src/normalize.js | 3 +- 9 files changed, 1820 insertions(+), 56 deletions(-) create mode 100644 packages/gatsby-source-contentful/src/__fixtures__/content-types.js create mode 100644 packages/gatsby-source-contentful/src/__tests__/__snapshots__/create-schema-customization.js.snap create mode 100644 packages/gatsby-source-contentful/src/__tests__/create-schema-customization.js diff --git a/e2e-tests/contentful/schema.gql b/e2e-tests/contentful/schema.gql index 5f4ef8d58f623..86b7511083dd6 100644 --- a/e2e-tests/contentful/schema.gql +++ b/e2e-tests/contentful/schema.gql @@ -74,8 +74,6 @@ type Directory implements Node @dontInfer { type Site implements Node @dontInfer { buildTime: Date @dateformat siteMetadata: SiteSiteMetadata - port: Int - host: String polyfill: Boolean pathPrefix: String jsxRuntime: String @@ -124,12 +122,11 @@ type SiteBuildMetadata implements Node @dontInfer { interface ContentfulReference implements Node { id: ID! - sys: ContentfulSys + sys: ContentfulSys! } -type ContentfulSys { +type ContentfulSys implements Node @dontInfer { type: String! - id: String! spaceId: String! environmentId: String! contentType: ContentfulContentType @link(by: "id", from: "contentType___NODE") @@ -145,13 +142,27 @@ type ContentfulContentType implements Node @dontInfer { description: String! } -interface ContentfulEntry implements Node { +interface ContentfulEntry implements ContentfulReference & Node { id: ID! - sys: ContentfulSys + sys: ContentfulSys! + metadata: ContentfulMetadata! +} + +type ContentfulMetadata @dontInfer { + tags: [ContentfulTag]! @link(by: "id", from: "tags___NODE") +} + +type ContentfulTag implements Node @dontInfer { + name: String! + contentful_id: String! +} + +type ContentfulAssetFields @dontInfer { + localFile: File @link(by: "id") } type ContentfulAsset implements ContentfulReference & Node @dontInfer { - sys: ContentfulSys + sys: ContentfulSys! title: String description: String contentType: String @@ -163,15 +174,6 @@ type ContentfulAsset implements ContentfulReference & Node @dontInfer { fields: ContentfulAssetFields } -type ContentfulAssetFields { - localFile: String -} - -type ContentfulTag implements Node @dontInfer { - name: String! - contentful_id: String! -} - type ContentfulRichTextAssets { block: [ContentfulAsset]! hyperlink: [ContentfulAsset]! @@ -203,7 +205,8 @@ type ContentfulText implements Node @dontInfer { } type ContentfulContentTypeNumber implements ContentfulReference & ContentfulEntry & Node @dontInfer { - sys: ContentfulSys + sys: ContentfulSys! + metadata: ContentfulMetadata! title: String integer: Int integerLocalized: Int @@ -212,7 +215,8 @@ type ContentfulContentTypeNumber implements ContentfulReference & ContentfulEntr } type ContentfulContentTypeText implements ContentfulReference & ContentfulEntry & Node @dontInfer { - sys: ContentfulSys + sys: ContentfulSys! + metadata: ContentfulMetadata! title: String short: String shortLocalized: String @@ -224,7 +228,8 @@ type ContentfulContentTypeText implements ContentfulReference & ContentfulEntry } type ContentfulContentTypeMediaReference implements ContentfulReference & ContentfulEntry & Node @dontInfer { - sys: ContentfulSys + sys: ContentfulSys! + metadata: ContentfulMetadata! title: String one: ContentfulAsset @link(by: "id", from: "one___NODE") oneLocalized: ContentfulAsset @link(by: "id", from: "oneLocalized___NODE") @@ -233,14 +238,16 @@ type ContentfulContentTypeMediaReference implements ContentfulReference & Conten } type ContentfulContentTypeBoolean implements ContentfulReference & ContentfulEntry & Node @dontInfer { - sys: ContentfulSys + sys: ContentfulSys! + metadata: ContentfulMetadata! title: String boolean: Boolean booleanLocalized: Boolean } type ContentfulContentTypeDate implements ContentfulReference & ContentfulEntry & Node @dontInfer { - sys: ContentfulSys + sys: ContentfulSys! + metadata: ContentfulMetadata! title: String date: Date @dateformat dateTime: Date @dateformat @@ -249,44 +256,53 @@ type ContentfulContentTypeDate implements ContentfulReference & ContentfulEntry } type ContentfulContentTypeLocation implements ContentfulReference & ContentfulEntry & Node @dontInfer { - sys: ContentfulSys + sys: ContentfulSys! + metadata: ContentfulMetadata! title: String location: ContentfulLocation locationLocalized: ContentfulLocation } type ContentfulContentTypeJson implements ContentfulReference & ContentfulEntry & Node @dontInfer { - sys: ContentfulSys + sys: ContentfulSys! + metadata: ContentfulMetadata! title: String json: JSON jsonLocalized: JSON } type ContentfulContentTypeRichText implements ContentfulReference & ContentfulEntry & Node @dontInfer { - sys: ContentfulSys + sys: ContentfulSys! + metadata: ContentfulMetadata! title: String richText: ContentfulRichText richTextLocalized: ContentfulRichText richTextValidated: ContentfulRichText } -type ContentfulContentTypeContentReference implements ContentfulReference & ContentfulEntry & Node @dontInfer { - sys: ContentfulSys +type ContentfulContentTypeContentReference implements ContentfulReference & ContentfulEntry & Node @isPlaceholder @dontInfer { + sys: ContentfulSys! + metadata: ContentfulMetadata! title: String one: ContentfulEntry @link(by: "id", from: "one___NODE") oneLocalized: ContentfulEntry @link(by: "id", from: "oneLocalized___NODE") - many: [ContentfulEntry] @link(by: "id", from: "many___NODE") + many: [UnionContentfulContentReferenceNumberText] @link(by: "id", from: "many___NODE") manyLocalized: [ContentfulEntry] @link(by: "id", from: "manyLocalized___NODE") } +union UnionContentfulContentReferenceNumberText = ContentfulContentTypeContentReference | ContentfulContentTypeNumber | ContentfulContentTypeText + +union UnionContentfulNumberText = ContentfulContentTypeNumber | ContentfulContentTypeText + type ContentfulContentTypeValidatedContentReference implements ContentfulReference & ContentfulEntry & Node @dontInfer { - sys: ContentfulSys + sys: ContentfulSys! + metadata: ContentfulMetadata! title: String - oneItemSingleType: ContentfulEntry @link(by: "id", from: "oneItemSingleType___NODE") - oneItemManyTypes: ContentfulEntry @link(by: "id", from: "oneItemManyTypes___NODE") + oneItemSingleType: ContentfulContentTypeText @link(by: "id", from: "oneItemSingleType___NODE") + oneItemManyTypes: UnionContentfulNumberText @link(by: "id", from: "oneItemManyTypes___NODE") oneItemAllTypes: ContentfulEntry @link(by: "id", from: "oneItemAllTypes___NODE") - multipleItemsSingleType: [ContentfulEntry] @link(by: "id", from: "multipleItemsSingleType___NODE") - multipleItemsManyTypes: [ContentfulEntry] @link(by: "id", from: "multipleItemsManyTypes___NODE") + multipleItemsSingleType: [ContentfulContentTypeText] @link(by: "id", from: "multipleItemsSingleType___NODE") + multipleItemsManyTypes: [UnionContentfulNumberText] @link(by: "id", from: "multipleItemsManyTypes___NODE") multipleItemsAllTypes: [ContentfulEntry] @link(by: "id", from: "multipleItemsAllTypes___NODE") } @@ -317,7 +333,7 @@ type MarkdownWordCount { words: Int } -type MarkdownRemark implements Node @childOf(mimeTypes: ["text/markdown", "text/x-markdown"], types: ["ContentfulText"]) @dontInfer { +type MarkdownRemark implements Node @childOf(mimeTypes: ["text/markdown", "text/x-markdown"], types: ["ContentfulText"]) @derivedTypes @dontInfer { frontmatter: MarkdownRemarkFrontmatter excerpt: String rawMarkdownBody: String @@ -481,7 +497,7 @@ type ImageSharpResize { originalName: String } -type ImageSharp implements Node @childOf(mimeTypes: [], types: ["File"]) @dontInfer { +type ImageSharp implements Node @childOf(types: ["File"]) @dontInfer { fixed(width: Int, height: Int, base64Width: Int, jpegProgressive: Boolean = true, pngCompressionSpeed: Int = 4, grayscale: Boolean = false, duotone: DuotoneGradient, traceSVG: Potrace, quality: Int, jpegQuality: Int, pngQuality: Int, webpQuality: Int, toFormat: ImageFormat = AUTO, toFormatBase64: ImageFormat = AUTO, cropFocus: ImageCropFocus = ATTENTION, fit: ImageFit = COVER, background: String = "rgba(0,0,0,1)", rotate: Int = 0, trim: Float = 0): ImageSharpFixed fluid( maxWidth: Int @@ -652,7 +668,7 @@ enum GatsbyImagePlaceholder { NONE } -type ContentfulContentTypeContentType implements Node @dontInfer { +type ContentfulContentTypeContentType implements Node @derivedTypes @dontInfer { name: String displayField: String description: String diff --git a/e2e-tests/contentful/snapshots.js b/e2e-tests/contentful/snapshots.js index 4633f5746f014..492be39f16f3e 100644 --- a/e2e-tests/contentful/snapshots.js +++ b/e2e-tests/contentful/snapshots.js @@ -28,7 +28,7 @@ module.exports = { }, "rich-text": { "rich-text: All Features": { - "1": "
\n

Rich Text: All Features

\n

The European languages

\n

are members of the same family. Their separate existence is a myth. For:

\n
    \n
  • \n

    science

    \n
  • \n
  • \n

    music

    \n
  • \n
  • \n

    sport

    \n
  • \n
  • \n

    etc

    \n
  • \n
\n

Europe uses the same vocabulary.

\n
\n
\"\"\n\n
\n
\n \n \n \"\"\n\n \n \n
\n

\n
\n

The languages only differ in:

\n
    \n
  1. \n

    their grammar

    \n
  2. \n
  3. \n

    their pronunciation

    \n
  4. \n
  5. \n

    their most common words

    \n
  6. \n
  7. \n

    [Inline-ContentfulText]\n Text: Short\n :\n The quick brown fox jumps over the lazy dog.

    \n
  8. \n
\n

Everyone realizes why a new common language would be desirable: one could\n refuse to pay expensive translators.

\n

{\n \"userId\": 1,\n \"id\": 1,\n \"title\": \"delectus aut autem\",\n \"completed\": false\n }

\n

To achieve this, it would be necessary to have uniform grammar,\n pronunciation and more common words.

\n

[ContentfulLocation] Lat:\n 52.51627\n , Long:\n 13.3777

\n
\n

If several languages coalesce, the grammar of the resulting language is\n more simple and regular than that of the individual languages.

\n
\n

The new common language will be more simple and regular than the existing\n European languages. It will be as simple as Occidental; in fact, it will be\n

\n
\n
" + "1": "
\n

Rich Text: All Features

\n

The European languages

\n

are members of the same family. Their separate existence is a myth. For:

\n
    \n
  • \n

    science

    \n
  • \n
  • \n

    music

    \n
  • \n
  • \n

    sport

    \n
  • \n
  • \n

    etc

    \n
  • \n
\n

Europe uses the same vocabulary.

\n
\n
\"\"\n\n
\n
\n \n \n \"\"\n\n \n \n
\n

\n
\n

The languages only differ in:

\n
    \n
  1. \n

    their grammar

    \n
  2. \n
  3. \n

    their pronunciation

    \n
  4. \n
  5. \n

    their most common words

    \n
  6. \n
  7. \n

    [Inline-ContentfulContentTypeText]\n The quick brown fox jumps over the lazy dog.

    \n
  8. \n
\n

Everyone realizes why a new common language would be desirable: one could\n refuse to pay expensive translators.

\n

{\n \"userId\": 1,\n \"id\": 1,\n \"title\": \"delectus aut autem\",\n \"completed\": false\n }

\n

To achieve this, it would be necessary to have uniform grammar,\n pronunciation and more common words.

\n

[ContentfulContentTypeLocation] Lat:\n 52.51627\n , Long:\n 13.3777

\n
\n

If several languages coalesce, the grammar of the resulting language is\n more simple and regular than that of the individual languages.

\n
\n

The new common language will be more simple and regular than the existing\n European languages. It will be as simple as Occidental; in fact, it will be\n

\n
\n
" }, "rich-text: Basic": { "1": "
\n

Rich Text: Basic

\n

The European languages

\n

are members of the same family. Their separate existence is a myth. For:

\n
    \n
  • \n

    science

    \n
  • \n
  • \n

    music

    \n
  • \n
  • \n

    sport

    \n
  • \n
  • \n

    etc

    \n
  • \n
\n

Europe uses the same vocabulary.

\n
\n

The languages only differ in:

\n
    \n
  1. \n

    their grammar

    \n
  2. \n
  3. \n

    their pronunciation

    \n
  4. \n
  5. \n

    their most common words

    \n
  6. \n
\n

Everyone realizes why a new common language would be desirable: one could\n refuse to pay expensive translators.

\n

{\n \"userId\": 1,\n \"id\": 1,\n \"title\": \"delectus aut autem\",\n \"completed\": false\n }

\n

To achieve this, it would be necessary to have uniform grammar,\n pronunciation and more common words.

\n
\n

If several languages coalesce, the grammar of the resulting language is\n more simple and regular than that of the individual languages.

\n
\n

The new common language will be more simple and regular than the existing\n European languages. It will be as simple as Occidental; in fact, it will be\n

\n
\n
" @@ -46,7 +46,7 @@ module.exports = { "1": "
\n

Rich Text: Embedded entry with reference loop

\n

Embedded entry with reference loop

\n

[ContentfulContentTypeContentReference]\n Content Reference: One (Loop B -> A)\n : [\n Content Reference: One (Loop A -> B)\n ]

\n

\n
\n
" }, "rich-text: Inline Entry": { - "1": "
\n

Rich Text: Inline entry

\n

Inline entry with reference loop

\n

Should be rendered after this [Inline-\n ContentfulContentTypeText\n ] and before that

\n

\n

\n
\n
" + "1": "
\n

Rich Text: Inline entry

\n

Inline entry with reference loop

\n

Should be rendered after this [Inline-ContentfulContentTypeText]\n The quick brown fox jumps over the lazy dog. and before\n that

\n

\n

\n
\n
" }, "rich-text: Inline Entry With Deep Reference Loop": { "1": "
\n

Rich Text: Inline entry with deep reference loop

\n

Inline entry with deep reference loop

\n

Should be rendered after this [Inline-\n ContentfulContentTypeContentReference\n ] and before that

\n

\n

\n
\n
" diff --git a/e2e-tests/contentful/src/pages/content-reference.js b/e2e-tests/contentful/src/pages/content-reference.js index af6400da98f3b..d31fdb8f8b14b 100644 --- a/e2e-tests/contentful/src/pages/content-reference.js +++ b/e2e-tests/contentful/src/pages/content-reference.js @@ -109,8 +109,10 @@ export const pageQuery = graphql` } one { __typename - sys { - id + ... on ContentfulEntry { + sys { + id + } } ... on ContentfulContentTypeText { title @@ -152,8 +154,10 @@ export const pageQuery = graphql` } many { __typename - sys { - id + ... on ContentfulEntry { + sys { + id + } } ... on ContentfulContentTypeText { title @@ -165,6 +169,11 @@ export const pageQuery = graphql` } ... on ContentfulContentTypeContentReference { title + ... on ContentfulEntry { + sys { + id + } + } one { ... on ContentfulContentTypeText { title diff --git a/e2e-tests/contentful/src/pages/rich-text.js b/e2e-tests/contentful/src/pages/rich-text.js index c3488ad37f63a..33c360059c08f 100644 --- a/e2e-tests/contentful/src/pages/rich-text.js +++ b/e2e-tests/contentful/src/pages/rich-text.js @@ -50,10 +50,10 @@ const makeOptions = ({ assetBlockMap, entryBlockMap, entryInlineMap }) => ({ }, [INLINES.EMBEDDED_ENTRY]: node => { const entry = entryInlineMap.get(node?.data?.target?.sys.id) - if (entry.__typename === "ContentfulText") { + if (entry.__typename === "ContentfulContentTypeText") { return ( - [Inline-ContentfulText] {entry.title}: {entry.short} + [Inline-ContentfulContentTypeText] {entry.short} ) } @@ -156,8 +156,10 @@ export const pageQuery = graphql` title one { __typename - sys { - id + ... on ContentfulEntry { + sys { + id + } } ... on ContentfulContentTypeText { title @@ -179,8 +181,10 @@ export const pageQuery = graphql` } many { __typename - sys { - id + ... on ContentfulEntry { + sys { + id + } } ... on ContentfulContentTypeText { title @@ -212,6 +216,10 @@ export const pageQuery = graphql` id type } + ... on ContentfulContentTypeText { + title + short + } } } } diff --git a/packages/gatsby-source-contentful/src/__fixtures__/content-types.js b/packages/gatsby-source-contentful/src/__fixtures__/content-types.js new file mode 100644 index 0000000000000..d3e4a10105aa7 --- /dev/null +++ b/packages/gatsby-source-contentful/src/__fixtures__/content-types.js @@ -0,0 +1,786 @@ +export const contentTypes = [ + { + sys: { + space: { + sys: { + type: `Link`, + linkType: `Space`, + id: `k8iqpp6u0ior`, + }, + }, + id: `number`, + type: `ContentType`, + createdAt: `2021-03-01T16:59:23.010Z`, + updatedAt: `2021-05-21T11:20:58.851Z`, + environment: { + sys: { + id: `master`, + type: `Link`, + linkType: `Environment`, + }, + }, + revision: 5, + }, + displayField: `title`, + name: `Number`, + description: ``, + fields: [ + { + id: `title`, + name: `Title`, + type: `Symbol`, + localized: false, + required: false, + disabled: false, + omitted: false, + }, + { + id: `integer`, + name: `Integer`, + type: `Integer`, + localized: false, + required: false, + disabled: false, + omitted: false, + }, + { + id: `integerLocalized`, + name: `Integer Localized`, + type: `Integer`, + localized: true, + required: false, + disabled: false, + omitted: false, + }, + { + id: `decimal`, + name: `Decimal`, + type: `Number`, + localized: false, + required: false, + disabled: false, + omitted: false, + }, + { + id: `decimalLocalized`, + name: `Decimal Localized`, + type: `Number`, + localized: true, + required: false, + disabled: false, + omitted: false, + }, + ], + }, + { + sys: { + space: { + sys: { + type: `Link`, + linkType: `Space`, + id: `k8iqpp6u0ior`, + }, + }, + id: `text`, + type: `ContentType`, + createdAt: `2021-03-01T17:02:35.612Z`, + updatedAt: `2021-05-21T10:48:06.210Z`, + environment: { + sys: { + id: `master`, + type: `Link`, + linkType: `Environment`, + }, + }, + revision: 3, + }, + displayField: `title`, + name: `Text`, + description: ``, + fields: [ + { + id: `title`, + name: `Title`, + type: `Symbol`, + localized: false, + required: false, + disabled: false, + omitted: false, + }, + { + id: `short`, + name: `Short`, + type: `Symbol`, + localized: false, + required: false, + disabled: false, + omitted: false, + }, + { + id: `shortLocalized`, + name: `Short Localized`, + type: `Symbol`, + localized: true, + required: false, + disabled: false, + omitted: false, + }, + { + id: `shortList`, + name: `Short List`, + type: `Array`, + localized: false, + required: false, + disabled: false, + omitted: false, + items: { + type: `Symbol`, + validations: [], + }, + }, + { + id: `shortListLocalized`, + name: `Short List Localized`, + type: `Array`, + localized: true, + required: false, + disabled: false, + omitted: false, + items: { + type: `Symbol`, + validations: [], + }, + }, + { + id: `longPlain`, + name: `Long Plain`, + type: `Text`, + localized: false, + required: false, + disabled: false, + omitted: false, + }, + { + id: `longMarkdown`, + name: `Long Markdown`, + type: `Text`, + localized: false, + required: false, + disabled: false, + omitted: false, + }, + { + id: `longLocalized`, + name: `Long Localized`, + type: `Text`, + localized: true, + required: false, + disabled: false, + omitted: false, + }, + ], + }, + { + sys: { + space: { + sys: { + type: `Link`, + linkType: `Space`, + id: `k8iqpp6u0ior`, + }, + }, + id: `mediaReference`, + type: `ContentType`, + createdAt: `2021-03-01T17:03:21.639Z`, + updatedAt: `2021-05-21T11:11:20.265Z`, + environment: { + sys: { + id: `master`, + type: `Link`, + linkType: `Environment`, + }, + }, + revision: 8, + }, + displayField: `title`, + name: `Media Reference`, + description: ``, + fields: [ + { + id: `title`, + name: `Title`, + type: `Symbol`, + localized: false, + required: false, + disabled: false, + omitted: false, + }, + { + id: `one`, + name: `One`, + type: `Link`, + localized: false, + required: false, + disabled: false, + omitted: false, + linkType: `Asset`, + }, + { + id: `oneLocalized`, + name: `One Localized`, + type: `Link`, + localized: true, + required: false, + disabled: false, + omitted: false, + linkType: `Asset`, + }, + { + id: `many`, + name: `Many`, + type: `Array`, + localized: false, + required: false, + disabled: false, + omitted: false, + items: { + type: `Link`, + validations: [], + linkType: `Asset`, + }, + }, + { + id: `manyLocalized`, + name: `Many Localized`, + type: `Array`, + localized: true, + required: false, + disabled: false, + omitted: false, + items: { + type: `Link`, + validations: [], + linkType: `Asset`, + }, + }, + ], + }, + { + sys: { + space: { + sys: { + type: `Link`, + linkType: `Space`, + id: `k8iqpp6u0ior`, + }, + }, + id: `boolean`, + type: `ContentType`, + createdAt: `2021-03-01T17:05:40.030Z`, + updatedAt: `2021-05-21T10:32:45.505Z`, + environment: { + sys: { + id: `master`, + type: `Link`, + linkType: `Environment`, + }, + }, + revision: 3, + }, + displayField: `title`, + name: `Boolean`, + description: ``, + fields: [ + { + id: `title`, + name: `Title`, + type: `Symbol`, + localized: false, + required: false, + disabled: false, + omitted: false, + }, + { + id: `boolean`, + name: `Boolean`, + type: `Boolean`, + localized: false, + required: false, + disabled: false, + omitted: false, + }, + { + id: `booleanLocalized`, + name: `Boolean Localized`, + type: `Boolean`, + localized: true, + required: false, + disabled: false, + omitted: false, + }, + ], + }, + { + sys: { + space: { + sys: { + type: `Link`, + linkType: `Space`, + id: `k8iqpp6u0ior`, + }, + }, + id: `date`, + type: `ContentType`, + createdAt: `2021-03-01T17:07:02.629Z`, + updatedAt: `2021-05-20T18:16:28.584Z`, + environment: { + sys: { + id: `master`, + type: `Link`, + linkType: `Environment`, + }, + }, + revision: 2, + }, + displayField: `title`, + name: `Date`, + description: ``, + fields: [ + { + id: `title`, + name: `Title`, + type: `Symbol`, + localized: false, + required: false, + disabled: false, + omitted: false, + }, + { + id: `date`, + name: `Date`, + type: `Date`, + localized: false, + required: false, + disabled: false, + omitted: false, + }, + { + id: `dateTime`, + name: `Date Time`, + type: `Date`, + localized: false, + required: false, + disabled: false, + omitted: false, + }, + { + id: `dateTimeTimezone`, + name: `Date Time Timezone`, + type: `Date`, + localized: false, + required: false, + disabled: false, + omitted: false, + }, + { + id: `dateLocalized`, + name: `Date Localized`, + type: `Date`, + localized: true, + required: false, + disabled: false, + omitted: false, + }, + ], + }, + { + sys: { + space: { + sys: { + type: `Link`, + linkType: `Space`, + id: `k8iqpp6u0ior`, + }, + }, + id: `location`, + type: `ContentType`, + createdAt: `2021-03-01T17:09:20.579Z`, + updatedAt: `2021-05-21T10:37:52.205Z`, + environment: { + sys: { + id: `master`, + type: `Link`, + linkType: `Environment`, + }, + }, + revision: 2, + }, + displayField: `title`, + name: `Location`, + description: ``, + fields: [ + { + id: `title`, + name: `Title`, + type: `Symbol`, + localized: false, + required: false, + disabled: false, + omitted: false, + }, + { + id: `location`, + name: `Location`, + type: `Location`, + localized: false, + required: false, + disabled: false, + omitted: false, + }, + { + id: `locationLocalized`, + name: `Location Localized`, + type: `Location`, + localized: true, + required: false, + disabled: false, + omitted: false, + }, + ], + }, + { + sys: { + space: { + sys: { + type: `Link`, + linkType: `Space`, + id: `k8iqpp6u0ior`, + }, + }, + id: `json`, + type: `ContentType`, + createdAt: `2021-03-01T17:09:56.970Z`, + updatedAt: `2021-05-21T10:36:57.432Z`, + environment: { + sys: { + id: `master`, + type: `Link`, + linkType: `Environment`, + }, + }, + revision: 2, + }, + displayField: `title`, + name: `JSON`, + description: ``, + fields: [ + { + id: `title`, + name: `Title`, + type: `Symbol`, + localized: false, + required: false, + disabled: false, + omitted: false, + }, + { + id: `json`, + name: `JSON`, + type: `Object`, + localized: false, + required: false, + disabled: false, + omitted: false, + }, + { + id: `jsonLocalized`, + name: `JSON Localized`, + type: `Object`, + localized: true, + required: false, + disabled: false, + omitted: false, + }, + ], + }, + { + sys: { + space: { + sys: { + type: `Link`, + linkType: `Space`, + id: `k8iqpp6u0ior`, + }, + }, + id: `richText`, + type: `ContentType`, + createdAt: `2021-03-01T17:11:01.406Z`, + updatedAt: `2021-11-05T12:56:39.942Z`, + environment: { + sys: { + id: `master`, + type: `Link`, + linkType: `Environment`, + }, + }, + revision: 7, + }, + displayField: `title`, + name: `Rich Text`, + description: ``, + fields: [ + { + id: `title`, + name: `Title`, + type: `Symbol`, + localized: false, + required: false, + disabled: false, + omitted: false, + }, + { + id: `richText`, + name: `Rich Text`, + type: `RichText`, + localized: false, + required: false, + disabled: false, + omitted: false, + }, + { + id: `richTextLocalized`, + name: `Rich Text Localized`, + type: `RichText`, + localized: true, + required: false, + disabled: false, + omitted: false, + }, + { + id: `richTextValidated`, + name: `Rich Text Validated`, + type: `RichText`, + localized: false, + required: false, + disabled: false, + omitted: false, + }, + ], + }, + { + sys: { + space: { + sys: { + type: `Link`, + linkType: `Space`, + id: `k8iqpp6u0ior`, + }, + }, + id: `contentReference`, + type: `ContentType`, + createdAt: `2021-03-02T09:17:08.210Z`, + updatedAt: `2021-05-21T10:36:34.506Z`, + environment: { + sys: { + id: `master`, + type: `Link`, + linkType: `Environment`, + }, + }, + revision: 7, + }, + displayField: `title`, + name: `Content Reference`, + description: ``, + fields: [ + { + id: `title`, + name: `Title`, + type: `Symbol`, + localized: false, + required: false, + disabled: false, + omitted: false, + }, + { + id: `one`, + name: `One`, + type: `Link`, + localized: false, + required: false, + disabled: false, + omitted: false, + linkType: `Entry`, + }, + { + id: `oneLocalized`, + name: `One Localized`, + type: `Link`, + localized: true, + required: false, + disabled: false, + omitted: false, + linkType: `Entry`, + }, + { + id: `many`, + name: `Many`, + type: `Array`, + localized: false, + required: false, + disabled: false, + omitted: false, + items: { + type: `Link`, + validations: [ + { + linkContentType: [`contentReference`, `number`, `text`], + }, + ], + linkType: `Entry`, + }, + }, + { + id: `manyLocalized`, + name: `Many Localized`, + type: `Array`, + localized: true, + required: false, + disabled: false, + omitted: false, + items: { + type: `Link`, + validations: [], + linkType: `Entry`, + }, + }, + ], + }, + { + sys: { + space: { + sys: { + type: `Link`, + linkType: `Space`, + id: `k8iqpp6u0ior`, + }, + }, + id: `validatedContentReference`, + type: `ContentType`, + createdAt: `2021-05-20T15:29:49.734Z`, + updatedAt: `2021-05-20T15:33:26.620Z`, + environment: { + sys: { + id: `master`, + type: `Link`, + linkType: `Environment`, + }, + }, + revision: 4, + }, + displayField: `title`, + name: `ValidatedContentReference`, + description: ``, + fields: [ + { + id: `title`, + name: `Title`, + type: `Symbol`, + localized: false, + required: false, + disabled: false, + omitted: false, + }, + { + id: `oneItemSingleType`, + name: `One Item: Single Type`, + type: `Link`, + localized: false, + required: false, + disabled: false, + omitted: false, + linkType: `Entry`, + validations: [ + { + linkContentType: [`text`], + }, + ], + }, + { + id: `oneItemManyTypes`, + name: `One Item: Many Types`, + type: `Link`, + localized: false, + required: false, + disabled: false, + omitted: false, + linkType: `Entry`, + validations: [ + { + linkContentType: [`number`, `text`], + }, + ], + }, + { + id: `oneItemAllTypes`, + name: `One Item: All Types`, + type: `Link`, + localized: false, + required: false, + disabled: false, + omitted: false, + linkType: `Entry`, + }, + { + id: `multipleItemsSingleType`, + name: `Multiple Items: Single Type`, + type: `Array`, + localized: false, + required: false, + disabled: false, + omitted: false, + items: { + type: `Link`, + validations: [ + { + linkContentType: [`text`], + }, + ], + linkType: `Entry`, + }, + }, + { + id: `multipleItemsManyTypes`, + name: `Multiple Items: Many Types`, + type: `Array`, + localized: false, + required: false, + disabled: false, + omitted: false, + items: { + type: `Link`, + validations: [ + { + linkContentType: [`number`, `text`], + }, + ], + linkType: `Entry`, + }, + }, + { + id: `multipleItemsAllTypes`, + name: `Multiple Items: All Types`, + type: `Array`, + localized: false, + required: false, + disabled: false, + omitted: false, + items: { + type: `Link`, + validations: [], + linkType: `Entry`, + }, + }, + ], + }, +] diff --git a/packages/gatsby-source-contentful/src/__tests__/__snapshots__/create-schema-customization.js.snap b/packages/gatsby-source-contentful/src/__tests__/__snapshots__/create-schema-customization.js.snap new file mode 100644 index 0000000000000..711739fd0aec2 --- /dev/null +++ b/packages/gatsby-source-contentful/src/__tests__/__snapshots__/create-schema-customization.js.snap @@ -0,0 +1,843 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`create-schema-customization builds schema based on Contentful Content Model 1`] = ` +Array [ + Array [ + Object { + "extensions": Object { + "dontInfer": Object {}, + }, + "fields": Object { + "description": Object { + "type": "String!", + }, + "displayField": Object { + "type": "String!", + }, + "id": Object { + "type": "ID!", + }, + "name": Object { + "type": "String!", + }, + }, + "interfaces": Array [ + "Node", + ], + "name": "ContentfulContentType", + }, + ], + Array [ + Object { + "extensions": Object { + "dontInfer": Object {}, + }, + "fields": Object { + "contentType": Object { + "extensions": Object { + "link": Object { + "by": "id", + "from": "contentType___NODE", + }, + }, + "type": "ContentfulContentType", + }, + "environmentId": Object { + "type": " String!", + }, + "firstPublishedAt": Object { + "type": " Date!", + }, + "id": Object { + "type": " String!", + }, + "locale": Object { + "type": " String!", + }, + "publishedAt": Object { + "type": " Date!", + }, + "publishedVersion": Object { + "type": " Int!", + }, + "spaceId": Object { + "type": " String!", + }, + "type": Object { + "type": " String!", + }, + }, + "interfaces": Array [ + "Node", + ], + "name": "ContentfulSys", + }, + ], + Array [ + Object { + "extensions": Object { + "dontInfer": Object {}, + }, + "fields": Object { + "tags": Object { + "extensions": Object { + "link": Object { + "by": "id", + "from": "tags___NODE", + }, + }, + "type": "[ContentfulTag]!", + }, + }, + "name": "ContentfulMetadata", + }, + ], + Array [ + Object { + "extensions": Object { + "dontInfer": Object {}, + }, + "fields": Object { + "contentful_id": Object { + "type": "String!", + }, + "id": Object { + "type": "ID!", + }, + "name": Object { + "type": "String!", + }, + }, + "interfaces": Array [ + "Node", + ], + "name": "ContentfulTag", + }, + ], + Array [ + Object { + "extensions": Object { + "dontInfer": Object {}, + }, + "fields": Object { + "localFile": Object { + "extensions": Object { + "link": Object { + "by": "id", + }, + }, + "type": "File", + }, + }, + "name": "ContentfulAssetFields", + }, + ], + Array [ + Object { + "extensions": Object { + "dontInfer": Object {}, + }, + "fields": Object { + "contentType": Object { + "type": "String", + }, + "description": Object { + "type": "String", + }, + "fields": Object { + "type": "ContentfulAssetFields", + }, + "fileName": Object { + "type": "String", + }, + "height": Object { + "type": "Int", + }, + "id": Object { + "type": "ID!", + }, + "size": Object { + "type": "Int", + }, + "sys": Object { + "type": "ContentfulSys!", + }, + "title": Object { + "type": "String", + }, + "url": Object { + "type": "String", + }, + "width": Object { + "type": "Int", + }, + }, + "interfaces": Array [ + "ContentfulReference", + "Node", + ], + "name": "ContentfulAsset", + }, + ], + Array [ + Object { + "fields": Object { + "block": Object { + "resolve": [Function], + "type": "[ContentfulAsset]!", + }, + "hyperlink": Object { + "resolve": [Function], + "type": "[ContentfulAsset]!", + }, + }, + "name": "ContentfulRichTextAssets", + }, + ], + Array [ + Object { + "fields": Object { + "block": Object { + "resolve": [Function], + "type": "[ContentfulEntry]!", + }, + "hyperlink": Object { + "resolve": [Function], + "type": "[ContentfulEntry]!", + }, + "inline": Object { + "resolve": [Function], + "type": "[ContentfulEntry]!", + }, + }, + "name": "ContentfulRichTextEntries", + }, + ], + Array [ + Object { + "fields": Object { + "assets": Object { + "resolve": [Function], + "type": "ContentfulRichTextAssets", + }, + "entries": Object { + "resolve": [Function], + "type": "ContentfulRichTextEntries", + }, + }, + "name": "ContentfulRichTextLinks", + }, + ], + Array [ + Object { + "extensions": Object { + "dontInfer": Object {}, + }, + "fields": Object { + "json": Object { + "resolve": [Function], + "type": "JSON", + }, + "links": Object { + "resolve": [Function], + "type": "ContentfulRichTextLinks", + }, + }, + "name": "ContentfulRichText", + }, + ], + Array [ + Object { + "extensions": Object { + "dontInfer": Object {}, + }, + "fields": Object { + "lat": Object { + "type": "Float!", + }, + "lon": Object { + "type": "Float!", + }, + }, + "name": "ContentfulLocation", + }, + ], + Array [ + Object { + "extensions": Object { + "dontInfer": Object {}, + }, + "fields": Object { + "raw": "String!", + }, + "interfaces": Array [ + "Node", + ], + "name": "ContentfulText", + }, + ], + Array [ + Object { + "extensions": Object { + "dontInfer": Object {}, + }, + "fields": Object { + "decimal": Object { + "type": "Float", + }, + "decimalLocalized": Object { + "type": "Float", + }, + "id": Object { + "type": "ID!", + }, + "integer": Object { + "type": "Int", + }, + "integerLocalized": Object { + "type": "Int", + }, + "metadata": Object { + "type": "ContentfulMetadata!", + }, + "sys": Object { + "type": "ContentfulSys!", + }, + "title": Object { + "type": "String", + }, + }, + "interfaces": Array [ + "ContentfulReference", + "ContentfulEntry", + "Node", + ], + "name": "ContentfulContentTypeNumber", + }, + ], + Array [ + Object { + "extensions": Object { + "dontInfer": Object {}, + }, + "fields": Object { + "id": Object { + "type": "ID!", + }, + "longLocalized": Object { + "extensions": Object { + "link": Object { + "by": "id", + "from": "longLocalized___NODE", + }, + }, + "type": "ContentfulText", + }, + "longMarkdown": Object { + "extensions": Object { + "link": Object { + "by": "id", + "from": "longMarkdown___NODE", + }, + }, + "type": "ContentfulText", + }, + "longPlain": Object { + "extensions": Object { + "link": Object { + "by": "id", + "from": "longPlain___NODE", + }, + }, + "type": "ContentfulText", + }, + "metadata": Object { + "type": "ContentfulMetadata!", + }, + "short": Object { + "type": "String", + }, + "shortList": Object { + "type": "[String]", + }, + "shortListLocalized": Object { + "type": "[String]", + }, + "shortLocalized": Object { + "type": "String", + }, + "sys": Object { + "type": "ContentfulSys!", + }, + "title": Object { + "type": "String", + }, + }, + "interfaces": Array [ + "ContentfulReference", + "ContentfulEntry", + "Node", + ], + "name": "ContentfulContentTypeText", + }, + ], + Array [ + Object { + "extensions": Object { + "dontInfer": Object {}, + }, + "fields": Object { + "id": Object { + "type": "ID!", + }, + "many": Object { + "extensions": Object { + "link": Object { + "by": "id", + "from": "many___NODE", + }, + }, + "type": "[ContentfulAsset]", + }, + "manyLocalized": Object { + "extensions": Object { + "link": Object { + "by": "id", + "from": "manyLocalized___NODE", + }, + }, + "type": "[ContentfulAsset]", + }, + "metadata": Object { + "type": "ContentfulMetadata!", + }, + "one": Object { + "extensions": Object { + "link": Object { + "by": "id", + "from": "one___NODE", + }, + }, + "type": "ContentfulAsset", + }, + "oneLocalized": Object { + "extensions": Object { + "link": Object { + "by": "id", + "from": "oneLocalized___NODE", + }, + }, + "type": "ContentfulAsset", + }, + "sys": Object { + "type": "ContentfulSys!", + }, + "title": Object { + "type": "String", + }, + }, + "interfaces": Array [ + "ContentfulReference", + "ContentfulEntry", + "Node", + ], + "name": "ContentfulContentTypeMediaReference", + }, + ], + Array [ + Object { + "extensions": Object { + "dontInfer": Object {}, + }, + "fields": Object { + "boolean": Object { + "type": "Boolean", + }, + "booleanLocalized": Object { + "type": "Boolean", + }, + "id": Object { + "type": "ID!", + }, + "metadata": Object { + "type": "ContentfulMetadata!", + }, + "sys": Object { + "type": "ContentfulSys!", + }, + "title": Object { + "type": "String", + }, + }, + "interfaces": Array [ + "ContentfulReference", + "ContentfulEntry", + "Node", + ], + "name": "ContentfulContentTypeBoolean", + }, + ], + Array [ + Object { + "extensions": Object { + "dontInfer": Object {}, + }, + "fields": Object { + "date": Object { + "extensions": Object { + "dateformat": Object {}, + }, + "type": "Date", + }, + "dateLocalized": Object { + "extensions": Object { + "dateformat": Object {}, + }, + "type": "Date", + }, + "dateTime": Object { + "extensions": Object { + "dateformat": Object {}, + }, + "type": "Date", + }, + "dateTimeTimezone": Object { + "extensions": Object { + "dateformat": Object {}, + }, + "type": "Date", + }, + "id": Object { + "type": "ID!", + }, + "metadata": Object { + "type": "ContentfulMetadata!", + }, + "sys": Object { + "type": "ContentfulSys!", + }, + "title": Object { + "type": "String", + }, + }, + "interfaces": Array [ + "ContentfulReference", + "ContentfulEntry", + "Node", + ], + "name": "ContentfulContentTypeDate", + }, + ], + Array [ + Object { + "extensions": Object { + "dontInfer": Object {}, + }, + "fields": Object { + "id": Object { + "type": "ID!", + }, + "location": Object { + "type": "ContentfulLocation", + }, + "locationLocalized": Object { + "type": "ContentfulLocation", + }, + "metadata": Object { + "type": "ContentfulMetadata!", + }, + "sys": Object { + "type": "ContentfulSys!", + }, + "title": Object { + "type": "String", + }, + }, + "interfaces": Array [ + "ContentfulReference", + "ContentfulEntry", + "Node", + ], + "name": "ContentfulContentTypeLocation", + }, + ], + Array [ + Object { + "extensions": Object { + "dontInfer": Object {}, + }, + "fields": Object { + "id": Object { + "type": "ID!", + }, + "json": Object { + "type": "JSON", + }, + "jsonLocalized": Object { + "type": "JSON", + }, + "metadata": Object { + "type": "ContentfulMetadata!", + }, + "sys": Object { + "type": "ContentfulSys!", + }, + "title": Object { + "type": "String", + }, + }, + "interfaces": Array [ + "ContentfulReference", + "ContentfulEntry", + "Node", + ], + "name": "ContentfulContentTypeJson", + }, + ], + Array [ + Object { + "extensions": Object { + "dontInfer": Object {}, + }, + "fields": Object { + "id": Object { + "type": "ID!", + }, + "metadata": Object { + "type": "ContentfulMetadata!", + }, + "richText": Object { + "type": "ContentfulRichText", + }, + "richTextLocalized": Object { + "type": "ContentfulRichText", + }, + "richTextValidated": Object { + "type": "ContentfulRichText", + }, + "sys": Object { + "type": "ContentfulSys!", + }, + "title": Object { + "type": "String", + }, + }, + "interfaces": Array [ + "ContentfulReference", + "ContentfulEntry", + "Node", + ], + "name": "ContentfulContentTypeRichText", + }, + ], + Array [ + Object { + "extensions": Object { + "dontInfer": Object {}, + }, + "fields": Object { + "id": Object { + "type": "ID!", + }, + "many": Object { + "extensions": Object { + "link": Object { + "by": "id", + "from": "many___NODE", + }, + }, + "type": "[UnionContentfulContentReferenceNumberText]", + }, + "manyLocalized": Object { + "extensions": Object { + "link": Object { + "by": "id", + "from": "manyLocalized___NODE", + }, + }, + "type": "[ContentfulEntry]", + }, + "metadata": Object { + "type": "ContentfulMetadata!", + }, + "one": Object { + "extensions": Object { + "link": Object { + "by": "id", + "from": "one___NODE", + }, + }, + "type": "ContentfulEntry", + }, + "oneLocalized": Object { + "extensions": Object { + "link": Object { + "by": "id", + "from": "oneLocalized___NODE", + }, + }, + "type": "ContentfulEntry", + }, + "sys": Object { + "type": "ContentfulSys!", + }, + "title": Object { + "type": "String", + }, + }, + "interfaces": Array [ + "ContentfulReference", + "ContentfulEntry", + "Node", + ], + "name": "ContentfulContentTypeContentReference", + }, + ], + Array [ + Object { + "extensions": Object { + "dontInfer": Object {}, + }, + "fields": Object { + "id": Object { + "type": "ID!", + }, + "metadata": Object { + "type": "ContentfulMetadata!", + }, + "multipleItemsAllTypes": Object { + "extensions": Object { + "link": Object { + "by": "id", + "from": "multipleItemsAllTypes___NODE", + }, + }, + "type": "[ContentfulEntry]", + }, + "multipleItemsManyTypes": Object { + "extensions": Object { + "link": Object { + "by": "id", + "from": "multipleItemsManyTypes___NODE", + }, + }, + "type": "[UnionContentfulNumberText]", + }, + "multipleItemsSingleType": Object { + "extensions": Object { + "link": Object { + "by": "id", + "from": "multipleItemsSingleType___NODE", + }, + }, + "type": "[ContentfulContentTypeText]", + }, + "oneItemAllTypes": Object { + "extensions": Object { + "link": Object { + "by": "id", + "from": "oneItemAllTypes___NODE", + }, + }, + "type": "ContentfulEntry", + }, + "oneItemManyTypes": Object { + "extensions": Object { + "link": Object { + "by": "id", + "from": "oneItemManyTypes___NODE", + }, + }, + "type": "UnionContentfulNumberText", + }, + "oneItemSingleType": Object { + "extensions": Object { + "link": Object { + "by": "id", + "from": "oneItemSingleType___NODE", + }, + }, + "type": "ContentfulContentTypeText", + }, + "sys": Object { + "type": "ContentfulSys!", + }, + "title": Object { + "type": "String", + }, + }, + "interfaces": Array [ + "ContentfulReference", + "ContentfulEntry", + "Node", + ], + "name": "ContentfulContentTypeValidatedContentReference", + }, + ], +] +`; + +exports[`create-schema-customization builds schema based on Contentful Content Model 2`] = ` +Array [ + Array [ + Object { + "fields": Object { + "id": Object { + "type": "ID!", + }, + "sys": Object { + "type": "ContentfulSys!", + }, + }, + "interfaces": Array [ + "Node", + ], + "name": "ContentfulReference", + }, + ], + Array [ + Object { + "fields": Object { + "id": Object { + "type": "ID!", + }, + "metadata": Object { + "type": "ContentfulMetadata!", + }, + "sys": Object { + "type": "ContentfulSys!", + }, + }, + "interfaces": Array [ + "ContentfulReference", + "Node", + ], + "name": "ContentfulEntry", + }, + ], +] +`; + +exports[`create-schema-customization builds schema based on Contentful Content Model 3`] = ` +Array [ + Array [ + Object { + "name": "UnionContentfulContentReferenceNumberText", + "types": Array [ + "ContentfulContentTypeContentReference", + "ContentfulContentTypeNumber", + "ContentfulContentTypeText", + ], + }, + ], + Array [ + Object { + "name": "UnionContentfulNumberText", + "types": Array [ + "ContentfulContentTypeNumber", + "ContentfulContentTypeText", + ], + }, + ], +] +`; diff --git a/packages/gatsby-source-contentful/src/__tests__/create-schema-customization.js b/packages/gatsby-source-contentful/src/__tests__/create-schema-customization.js new file mode 100644 index 0000000000000..9ae3027eddacc --- /dev/null +++ b/packages/gatsby-source-contentful/src/__tests__/create-schema-customization.js @@ -0,0 +1,46 @@ +// @ts-check +import { createSchemaCustomization } from "../create-schema-customization" +import { contentTypes } from "../__fixtures__/content-types" + +const createMockCache = () => { + return { + get: jest.fn(key => contentTypes), + } +} + +describe(`create-schema-customization`, () => { + const actions = { createTypes: jest.fn() } + const schema = { + buildObjectType: jest.fn(), + buildInterfaceType: jest.fn(), + buildUnionType: jest.fn(), + } + const cache = createMockCache() + const reporter = { + info: jest.fn(), + verbose: jest.fn(), + panic: jest.fn(), + activityTimer: () => { + return { start: jest.fn(), end: jest.fn() } + }, + } + + beforeEach(() => { + cache.get.mockClear() + process.env.GATSBY_WORKER_ID = `mocked` + }) + + it(`builds schema based on Contentful Content Model`, async () => { + await createSchemaCustomization( + { schema, actions, reporter, cache }, + { spaceId: `testSpaceId` } + ) + + expect(schema.buildObjectType).toHaveBeenCalled() + expect(schema.buildObjectType.mock.calls).toMatchSnapshot() + expect(schema.buildInterfaceType).toHaveBeenCalled() + expect(schema.buildInterfaceType.mock.calls).toMatchSnapshot() + expect(schema.buildUnionType).toHaveBeenCalled() + expect(schema.buildUnionType.mock.calls).toMatchSnapshot() + }) +}) diff --git a/packages/gatsby-source-contentful/src/generate-schema.js b/packages/gatsby-source-contentful/src/generate-schema.js index 24c0317047198..3a60c62e656d1 100644 --- a/packages/gatsby-source-contentful/src/generate-schema.js +++ b/packages/gatsby-source-contentful/src/generate-schema.js @@ -70,7 +70,64 @@ const ContentfulDataTypes = new Map([ ], ]) -const getLinkFieldType = (linkType, field) => { +const unionsNameSet = new Set() + +const getLinkFieldType = (linkType, field, schema, createTypes) => { + // Check for validations + const validations = + field.type === `Array` ? field.items?.validations : field?.validations + + if (validations) { + // We only handle content type validations + const linkContentTypeValidation = validations.find( + ({ linkContentType }) => !!linkContentType + ) + if (linkContentTypeValidation) { + const { linkContentType } = linkContentTypeValidation + const contentTypes = Array.isArray(linkContentType) + ? linkContentType + : [linkContentType] + + // Full type names for union members, shorter variant for the union type name + const translatedTypeNames = contentTypes.map(typeName => + makeTypeName(typeName) + ) + const shortTypeNames = contentTypes.map(typeName => + makeTypeName(typeName, ``) + ) + + // Single content type + if (translatedTypeNames.length === 1) { + return { + type: translatedTypeNames.shift(), + extensions: { + link: { by: `id`, from: `${field.id}___NODE` }, + }, + } + } + + // Multiple content types + const unionName = [`UnionContentful`, ...shortTypeNames].join(``) + + if (!unionsNameSet.has(unionName)) { + unionsNameSet.add(unionName) + createTypes( + schema.buildUnionType({ + name: unionName, + types: translatedTypeNames, + }) + ) + } + + return { + type: unionName, + extensions: { + link: { by: `id`, from: `${field.id}___NODE` }, + }, + } + } + } + return { type: `Contentful${linkType}`, extensions: { @@ -79,19 +136,19 @@ const getLinkFieldType = (linkType, field) => { } } -const translateFieldType = field => { +const translateFieldType = (field, schema, createTypes) => { let fieldType if (field.type === `Array`) { // Arrays of Contentful Links or primitive types const fieldData = field.items.type === `Link` - ? getLinkFieldType(field.items.linkType, field) - : translateFieldType(field.items) + ? getLinkFieldType(field.items.linkType, field, schema, createTypes) + : translateFieldType(field.items, schema, createTypes) fieldType = { ...fieldData, type: `[${fieldData.type}]` } } else if (field.type === `Link`) { // Contentful Link (reference) field types - fieldType = getLinkFieldType(field.linkType, field) + fieldType = getLinkFieldType(field.linkType, field, schema, createTypes) } else { // Primitive field types fieldType = ContentfulDataTypes.get(field.type)(field) @@ -371,7 +428,7 @@ export function generateSchema({ if (field.disabled || field.omitted) { return } - fields[field.id] = translateFieldType(field) + fields[field.id] = translateFieldType(field, schema, createTypes) }) const type = pluginConfig.get(`useNameForId`) diff --git a/packages/gatsby-source-contentful/src/normalize.js b/packages/gatsby-source-contentful/src/normalize.js index 13aefdbea2892..0062bafd6da9e 100644 --- a/packages/gatsby-source-contentful/src/normalize.js +++ b/packages/gatsby-source-contentful/src/normalize.js @@ -3,8 +3,7 @@ import _ from "lodash" import { getGatsbyVersion } from "gatsby-core-utils" import { lt, prerelease } from "semver" -const typePrefix = `ContentfulContentType` -export const makeTypeName = type => +export const makeTypeName = (type, typePrefix = `ContentfulContentType`) => _.upperFirst(_.camelCase(`${typePrefix} ${type}`)) const GATSBY_VERSION_MANIFEST_V2 = `4.3.0` From cc7354504302dd499849aa6f2304ebf6cb7086b3 Mon Sep 17 00:00:00 2001 From: axe312ger Date: Fri, 14 Jan 2022 16:16:33 +0100 Subject: [PATCH 31/34] style: rename ContentfulReference interface to ContentfulEntity --- e2e-tests/contentful/schema.gql | 145 ++++++++++++++---- .../create-schema-customization.js.snap | 26 ++-- .../src/generate-schema.js | 8 +- 3 files changed, 130 insertions(+), 49 deletions(-) diff --git a/e2e-tests/contentful/schema.gql b/e2e-tests/contentful/schema.gql index 86b7511083dd6..7118ffb9ac47c 100644 --- a/e2e-tests/contentful/schema.gql +++ b/e2e-tests/contentful/schema.gql @@ -120,7 +120,7 @@ type SiteBuildMetadata implements Node @dontInfer { buildTime: Date @dateformat } -interface ContentfulReference implements Node { +interface ContentfulEntity implements Node { id: ID! sys: ContentfulSys! } @@ -142,7 +142,7 @@ type ContentfulContentType implements Node @dontInfer { description: String! } -interface ContentfulEntry implements ContentfulReference & Node { +interface ContentfulEntry implements ContentfulEntity & Node { id: ID! sys: ContentfulSys! metadata: ContentfulMetadata! @@ -161,7 +161,7 @@ type ContentfulAssetFields @dontInfer { localFile: File @link(by: "id") } -type ContentfulAsset implements ContentfulReference & Node @dontInfer { +type ContentfulAsset implements ContentfulEntity & Node @dontInfer { sys: ContentfulSys! title: String description: String @@ -204,7 +204,8 @@ type ContentfulText implements Node @dontInfer { raw: String! } -type ContentfulContentTypeNumber implements ContentfulReference & ContentfulEntry & Node @dontInfer { +type ContentfulContentTypeNumber implements ContentfulEntity & ContentfulEntry & Node + @dontInfer { sys: ContentfulSys! metadata: ContentfulMetadata! title: String @@ -214,7 +215,8 @@ type ContentfulContentTypeNumber implements ContentfulReference & ContentfulEntr decimalLocalized: Float } -type ContentfulContentTypeText implements ContentfulReference & ContentfulEntry & Node @dontInfer { +type ContentfulContentTypeText implements ContentfulEntity & ContentfulEntry & Node + @dontInfer { sys: ContentfulSys! metadata: ContentfulMetadata! title: String @@ -227,7 +229,8 @@ type ContentfulContentTypeText implements ContentfulReference & ContentfulEntry longLocalized: ContentfulText @link(by: "id", from: "longLocalized___NODE") } -type ContentfulContentTypeMediaReference implements ContentfulReference & ContentfulEntry & Node @dontInfer { +type ContentfulContentTypeMediaReference implements ContentfulEntity & ContentfulEntry & Node + @dontInfer { sys: ContentfulSys! metadata: ContentfulMetadata! title: String @@ -237,7 +240,8 @@ type ContentfulContentTypeMediaReference implements ContentfulReference & Conten manyLocalized: [ContentfulAsset] @link(by: "id", from: "manyLocalized___NODE") } -type ContentfulContentTypeBoolean implements ContentfulReference & ContentfulEntry & Node @dontInfer { +type ContentfulContentTypeBoolean implements ContentfulEntity & ContentfulEntry & Node + @dontInfer { sys: ContentfulSys! metadata: ContentfulMetadata! title: String @@ -245,7 +249,8 @@ type ContentfulContentTypeBoolean implements ContentfulReference & ContentfulEnt booleanLocalized: Boolean } -type ContentfulContentTypeDate implements ContentfulReference & ContentfulEntry & Node @dontInfer { +type ContentfulContentTypeDate implements ContentfulEntity & ContentfulEntry & Node + @dontInfer { sys: ContentfulSys! metadata: ContentfulMetadata! title: String @@ -255,7 +260,8 @@ type ContentfulContentTypeDate implements ContentfulReference & ContentfulEntry dateLocalized: Date @dateformat } -type ContentfulContentTypeLocation implements ContentfulReference & ContentfulEntry & Node @dontInfer { +type ContentfulContentTypeLocation implements ContentfulEntity & ContentfulEntry & Node + @dontInfer { sys: ContentfulSys! metadata: ContentfulMetadata! title: String @@ -263,7 +269,8 @@ type ContentfulContentTypeLocation implements ContentfulReference & ContentfulEn locationLocalized: ContentfulLocation } -type ContentfulContentTypeJson implements ContentfulReference & ContentfulEntry & Node @dontInfer { +type ContentfulContentTypeJson implements ContentfulEntity & ContentfulEntry & Node + @dontInfer { sys: ContentfulSys! metadata: ContentfulMetadata! title: String @@ -271,7 +278,8 @@ type ContentfulContentTypeJson implements ContentfulReference & ContentfulEntry jsonLocalized: JSON } -type ContentfulContentTypeRichText implements ContentfulReference & ContentfulEntry & Node @dontInfer { +type ContentfulContentTypeRichText implements ContentfulEntity & ContentfulEntry & Node + @dontInfer { sys: ContentfulSys! metadata: ContentfulMetadata! title: String @@ -280,30 +288,45 @@ type ContentfulContentTypeRichText implements ContentfulReference & ContentfulEn richTextValidated: ContentfulRichText } -type ContentfulContentTypeContentReference implements ContentfulReference & ContentfulEntry & Node @isPlaceholder @dontInfer { +type ContentfulContentTypeContentReference implements ContentfulEntity & ContentfulEntry & Node + @isPlaceholder + @dontInfer { sys: ContentfulSys! metadata: ContentfulMetadata! title: String one: ContentfulEntry @link(by: "id", from: "one___NODE") oneLocalized: ContentfulEntry @link(by: "id", from: "oneLocalized___NODE") - many: [UnionContentfulContentReferenceNumberText] @link(by: "id", from: "many___NODE") + many: [UnionContentfulContentReferenceNumberText] + @link(by: "id", from: "many___NODE") manyLocalized: [ContentfulEntry] @link(by: "id", from: "manyLocalized___NODE") } -union UnionContentfulContentReferenceNumberText = ContentfulContentTypeContentReference | ContentfulContentTypeNumber | ContentfulContentTypeText +union UnionContentfulContentReferenceNumberText = + ContentfulContentTypeContentReference + | ContentfulContentTypeNumber + | ContentfulContentTypeText -union UnionContentfulNumberText = ContentfulContentTypeNumber | ContentfulContentTypeText +union UnionContentfulNumberText = + ContentfulContentTypeNumber + | ContentfulContentTypeText -type ContentfulContentTypeValidatedContentReference implements ContentfulReference & ContentfulEntry & Node @dontInfer { +type ContentfulContentTypeValidatedContentReference implements ContentfulEntity & ContentfulEntry & Node + @dontInfer { sys: ContentfulSys! metadata: ContentfulMetadata! title: String - oneItemSingleType: ContentfulContentTypeText @link(by: "id", from: "oneItemSingleType___NODE") - oneItemManyTypes: UnionContentfulNumberText @link(by: "id", from: "oneItemManyTypes___NODE") - oneItemAllTypes: ContentfulEntry @link(by: "id", from: "oneItemAllTypes___NODE") - multipleItemsSingleType: [ContentfulContentTypeText] @link(by: "id", from: "multipleItemsSingleType___NODE") - multipleItemsManyTypes: [UnionContentfulNumberText] @link(by: "id", from: "multipleItemsManyTypes___NODE") - multipleItemsAllTypes: [ContentfulEntry] @link(by: "id", from: "multipleItemsAllTypes___NODE") + oneItemSingleType: ContentfulContentTypeText + @link(by: "id", from: "oneItemSingleType___NODE") + oneItemManyTypes: UnionContentfulNumberText + @link(by: "id", from: "oneItemManyTypes___NODE") + oneItemAllTypes: ContentfulEntry + @link(by: "id", from: "oneItemAllTypes___NODE") + multipleItemsSingleType: [ContentfulContentTypeText] + @link(by: "id", from: "multipleItemsSingleType___NODE") + multipleItemsManyTypes: [UnionContentfulNumberText] + @link(by: "id", from: "multipleItemsManyTypes___NODE") + multipleItemsAllTypes: [ContentfulEntry] + @link(by: "id", from: "multipleItemsAllTypes___NODE") } type MarkdownHeading { @@ -333,7 +356,13 @@ type MarkdownWordCount { words: Int } -type MarkdownRemark implements Node @childOf(mimeTypes: ["text/markdown", "text/x-markdown"], types: ["ContentfulText"]) @derivedTypes @dontInfer { +type MarkdownRemark implements Node + @childOf( + mimeTypes: ["text/markdown", "text/x-markdown"] + types: ["ContentfulText"] + ) + @derivedTypes + @dontInfer { frontmatter: MarkdownRemarkFrontmatter excerpt: String rawMarkdownBody: String @@ -443,7 +472,9 @@ enum ImagePlaceholder { } input BlurredOptions { - """Width of the generated low-res preview. Default is 20px""" + """ + Width of the generated low-res preview. Default is 20px + """ width: Int """ @@ -498,7 +529,27 @@ type ImageSharpResize { } type ImageSharp implements Node @childOf(types: ["File"]) @dontInfer { - fixed(width: Int, height: Int, base64Width: Int, jpegProgressive: Boolean = true, pngCompressionSpeed: Int = 4, grayscale: Boolean = false, duotone: DuotoneGradient, traceSVG: Potrace, quality: Int, jpegQuality: Int, pngQuality: Int, webpQuality: Int, toFormat: ImageFormat = AUTO, toFormatBase64: ImageFormat = AUTO, cropFocus: ImageCropFocus = ATTENTION, fit: ImageFit = COVER, background: String = "rgba(0,0,0,1)", rotate: Int = 0, trim: Float = 0): ImageSharpFixed + fixed( + width: Int + height: Int + base64Width: Int + jpegProgressive: Boolean = true + pngCompressionSpeed: Int = 4 + grayscale: Boolean = false + duotone: DuotoneGradient + traceSVG: Potrace + quality: Int + jpegQuality: Int + pngQuality: Int + webpQuality: Int + toFormat: ImageFormat = AUTO + toFormatBase64: ImageFormat = AUTO + cropFocus: ImageCropFocus = ATTENTION + fit: ImageFit = COVER + background: String = "rgba(0,0,0,1)" + rotate: Int = 0 + trim: Float = 0 + ): ImageSharpFixed fluid( maxWidth: Int maxHeight: Int @@ -616,19 +667,29 @@ type ImageSharp implements Node @childOf(types: ["File"]) @dontInfer { """ sizes: String - """The default quality. This is overridden by any format-specific options""" + """ + The default quality. This is overridden by any format-specific options + """ quality: Int - """Options to pass to sharp when generating JPG images.""" + """ + Options to pass to sharp when generating JPG images. + """ jpgOptions: JPGOptions - """Options to pass to sharp when generating PNG images.""" + """ + Options to pass to sharp when generating PNG images. + """ pngOptions: PNGOptions - """Options to pass to sharp when generating WebP images.""" + """ + Options to pass to sharp when generating WebP images. + """ webpOptions: WebPOptions - """Options to pass to sharp when generating AVIF images.""" + """ + Options to pass to sharp when generating AVIF images. + """ avifOptions: AVIFOptions """ @@ -643,7 +704,27 @@ type ImageSharp implements Node @childOf(types: ["File"]) @dontInfer { backgroundColor: String ): JSON! original: ImageSharpOriginal - resize(width: Int, height: Int, quality: Int, jpegQuality: Int, pngQuality: Int, webpQuality: Int, jpegProgressive: Boolean = true, pngCompressionLevel: Int = 9, pngCompressionSpeed: Int = 4, grayscale: Boolean = false, duotone: DuotoneGradient, base64: Boolean = false, traceSVG: Potrace, toFormat: ImageFormat = AUTO, cropFocus: ImageCropFocus = ATTENTION, fit: ImageFit = COVER, background: String = "rgba(0,0,0,1)", rotate: Int = 0, trim: Float = 0): ImageSharpResize + resize( + width: Int + height: Int + quality: Int + jpegQuality: Int + pngQuality: Int + webpQuality: Int + jpegProgressive: Boolean = true + pngCompressionLevel: Int = 9 + pngCompressionSpeed: Int = 4 + grayscale: Boolean = false + duotone: DuotoneGradient + base64: Boolean = false + traceSVG: Potrace + toFormat: ImageFormat = AUTO + cropFocus: ImageCropFocus = ATTENTION + fit: ImageFit = COVER + background: String = "rgba(0,0,0,1)" + rotate: Int = 0 + trim: Float = 0 + ): ImageSharpResize } enum GatsbyImageFormat { @@ -684,4 +765,4 @@ type ContentfulContentTypeContentTypeSys { firstPublishedAt: Date @dateformat publishedAt: Date @dateformat publishedVersion: Int -} \ No newline at end of file +} diff --git a/packages/gatsby-source-contentful/src/__tests__/__snapshots__/create-schema-customization.js.snap b/packages/gatsby-source-contentful/src/__tests__/__snapshots__/create-schema-customization.js.snap index 711739fd0aec2..d735907275681 100644 --- a/packages/gatsby-source-contentful/src/__tests__/__snapshots__/create-schema-customization.js.snap +++ b/packages/gatsby-source-contentful/src/__tests__/__snapshots__/create-schema-customization.js.snap @@ -173,7 +173,7 @@ Array [ }, }, "interfaces": Array [ - "ContentfulReference", + "ContentfulEntity", "Node", ], "name": "ContentfulAsset", @@ -308,7 +308,7 @@ Array [ }, }, "interfaces": Array [ - "ContentfulReference", + "ContentfulEntity", "ContentfulEntry", "Node", ], @@ -374,7 +374,7 @@ Array [ }, }, "interfaces": Array [ - "ContentfulReference", + "ContentfulEntity", "ContentfulEntry", "Node", ], @@ -437,7 +437,7 @@ Array [ }, }, "interfaces": Array [ - "ContentfulReference", + "ContentfulEntity", "ContentfulEntry", "Node", ], @@ -470,7 +470,7 @@ Array [ }, }, "interfaces": Array [ - "ContentfulReference", + "ContentfulEntity", "ContentfulEntry", "Node", ], @@ -521,7 +521,7 @@ Array [ }, }, "interfaces": Array [ - "ContentfulReference", + "ContentfulEntity", "ContentfulEntry", "Node", ], @@ -554,7 +554,7 @@ Array [ }, }, "interfaces": Array [ - "ContentfulReference", + "ContentfulEntity", "ContentfulEntry", "Node", ], @@ -587,7 +587,7 @@ Array [ }, }, "interfaces": Array [ - "ContentfulReference", + "ContentfulEntity", "ContentfulEntry", "Node", ], @@ -623,7 +623,7 @@ Array [ }, }, "interfaces": Array [ - "ContentfulReference", + "ContentfulEntity", "ContentfulEntry", "Node", ], @@ -686,7 +686,7 @@ Array [ }, }, "interfaces": Array [ - "ContentfulReference", + "ContentfulEntity", "ContentfulEntry", "Node", ], @@ -767,7 +767,7 @@ Array [ }, }, "interfaces": Array [ - "ContentfulReference", + "ContentfulEntity", "ContentfulEntry", "Node", ], @@ -792,7 +792,7 @@ Array [ "interfaces": Array [ "Node", ], - "name": "ContentfulReference", + "name": "ContentfulEntity", }, ], Array [ @@ -809,7 +809,7 @@ Array [ }, }, "interfaces": Array [ - "ContentfulReference", + "ContentfulEntity", "Node", ], "name": "ContentfulEntry", diff --git a/packages/gatsby-source-contentful/src/generate-schema.js b/packages/gatsby-source-contentful/src/generate-schema.js index 3a60c62e656d1..6d40b0b927162 100644 --- a/packages/gatsby-source-contentful/src/generate-schema.js +++ b/packages/gatsby-source-contentful/src/generate-schema.js @@ -170,7 +170,7 @@ export function generateSchema({ // Generic Types createTypes( schema.buildInterfaceType({ - name: `ContentfulReference`, + name: `ContentfulEntity`, fields: { id: { type: `ID!` }, sys: { type: `ContentfulSys!` }, @@ -187,7 +187,7 @@ export function generateSchema({ sys: { type: `ContentfulSys!` }, metadata: { type: `ContentfulMetadata!` }, }, - interfaces: [`ContentfulReference`, `Node`], + interfaces: [`ContentfulEntity`, `Node`], }) ) @@ -290,7 +290,7 @@ export function generateSchema({ height: { type: `Int` }, fields: { type: `ContentfulAssetFields` }, }, - interfaces: [`ContentfulReference`, `Node`], + interfaces: [`ContentfulEntity`, `Node`], extensions: { dontInfer: {} }, }) ) @@ -444,7 +444,7 @@ export function generateSchema({ metadata: { type: `ContentfulMetadata!` }, ...fields, }, - interfaces: [`ContentfulReference`, `ContentfulEntry`, `Node`], + interfaces: [`ContentfulEntity`, `ContentfulEntry`, `Node`], extensions: { dontInfer: {} }, }) ) From c768a0843f965555b594e5607d23da7729e57fd8 Mon Sep 17 00:00:00 2001 From: axe312ger Date: Thu, 20 Jan 2022 15:50:04 +0100 Subject: [PATCH 32/34] fix: readd tag support for assets --- e2e-tests/contentful/src/pages/tags.js | 12 +++++------- .../src/generate-schema.js | 2 ++ packages/gatsby-source-contentful/src/normalize.js | 14 +++++--------- 3 files changed, 12 insertions(+), 16 deletions(-) diff --git a/e2e-tests/contentful/src/pages/tags.js b/e2e-tests/contentful/src/pages/tags.js index 0e0a430e1b6f3..7af26c1113330 100644 --- a/e2e-tests/contentful/src/pages/tags.js +++ b/e2e-tests/contentful/src/pages/tags.js @@ -55,13 +55,13 @@ const TagsPage = ({ data }) => { data-cy-assets style={{ display: "flex", justifyContent: "space-between" }} > - {assets.map(({ title, file, metadata }) => { + {assets.map(({ title, url, metadata }) => { const slug = slugify(title, { strict: true, lower: true }) return (

{title}

{title} @@ -127,17 +127,15 @@ export const pageQuery = graphql` } } assets: allContentfulAsset( - sort: { fields: contentful_id } + sort: { fields: sys___id } filter: { metadata: { tags: { elemMatch: { contentful_id: { eq: "animal" } } } } - node_locale: { eq: "en-US" } + sys: { locale: { eq: "en-US" } } } ) { nodes { title - file { - url - } + url metadata { tags { name diff --git a/packages/gatsby-source-contentful/src/generate-schema.js b/packages/gatsby-source-contentful/src/generate-schema.js index 6d40b0b927162..50dbd2096992f 100644 --- a/packages/gatsby-source-contentful/src/generate-schema.js +++ b/packages/gatsby-source-contentful/src/generate-schema.js @@ -174,6 +174,7 @@ export function generateSchema({ fields: { id: { type: `ID!` }, sys: { type: `ContentfulSys!` }, + metadata: { type: `ContentfulMetadata!` }, }, interfaces: [`Node`], }) @@ -280,6 +281,7 @@ export function generateSchema({ fields: { id: { type: `ID!` }, sys: { type: `ContentfulSys!` }, + metadata: { type: `ContentfulMetadata!` }, title: { type: `String` }, description: { type: `String` }, contentType: { type: `String` }, diff --git a/packages/gatsby-source-contentful/src/normalize.js b/packages/gatsby-source-contentful/src/normalize.js index 0062bafd6da9e..75da09981dc72 100644 --- a/packages/gatsby-source-contentful/src/normalize.js +++ b/packages/gatsby-source-contentful/src/normalize.js @@ -602,6 +602,11 @@ export const createAssetNodes = ({ publishedAt: assetItem.sys.updatedAt, publishedVersion: assetItem.sys.revision, }, + metadata: { + tags___NODE: assetItem.metadata.tags.map(tag => + createNodeId(`ContentfulTag__${space.sys.id}__${tag.sys.id}`) + ), + }, title: assetItem.fields.title ? getField(assetItem.fields.title) : ``, description: assetItem.fields.description ? getField(assetItem.fields.description) @@ -614,15 +619,6 @@ export const createAssetNodes = ({ height: file.details?.image?.height || null, } - // Link tags - if (pluginConfig.get(`enableTags`)) { - assetNode.metadata = { - tags___NODE: assetItem.metadata.tags.map(tag => - createNodeId(`ContentfulTag__${space.sys.id}__${tag.sys.id}`) - ), - } - } - // if the node hasn't changed, createNode may return `undefined` instead of a Promise on some versions of Gatsby const maybePromise = createNode(assetNode) From 6609fd2414eb48dd694477c56cc6adeacc3d8d16 Mon Sep 17 00:00:00 2001 From: axe312ger Date: Wed, 2 Feb 2022 14:04:01 +0100 Subject: [PATCH 33/34] fix reference resolving and adjust tests --- .../src/__fixtures__/rich-text-data.js | 2 + .../create-schema-customization.js.snap | 6 + .../__snapshots__/gatsby-node.js.snap | 409 ------------------ .../__tests__/download-contentful-assets.js | 5 +- .../src/__tests__/gatsby-node.js | 112 ++--- .../src/__tests__/normalize.js | 110 ++--- .../gatsby-source-contentful/src/normalize.js | 3 +- .../src/source-nodes.js | 136 ++++-- 8 files changed, 171 insertions(+), 612 deletions(-) delete mode 100644 packages/gatsby-source-contentful/src/__tests__/__snapshots__/gatsby-node.js.snap diff --git a/packages/gatsby-source-contentful/src/__fixtures__/rich-text-data.js b/packages/gatsby-source-contentful/src/__fixtures__/rich-text-data.js index 02ea0d1a342da..98ee4aa277268 100644 --- a/packages/gatsby-source-contentful/src/__fixtures__/rich-text-data.js +++ b/packages/gatsby-source-contentful/src/__fixtures__/rich-text-data.js @@ -704,6 +704,7 @@ exports.initialSync = () => { }, }, }, + metadata: { tags: [] }, }, { sys: { @@ -746,6 +747,7 @@ exports.initialSync = () => { }, }, }, + metadata: { tags: [] }, }, ], deletedEntries: [], diff --git a/packages/gatsby-source-contentful/src/__tests__/__snapshots__/create-schema-customization.js.snap b/packages/gatsby-source-contentful/src/__tests__/__snapshots__/create-schema-customization.js.snap index d735907275681..23204abdcac9b 100644 --- a/packages/gatsby-source-contentful/src/__tests__/__snapshots__/create-schema-customization.js.snap +++ b/packages/gatsby-source-contentful/src/__tests__/__snapshots__/create-schema-customization.js.snap @@ -156,6 +156,9 @@ Array [ "id": Object { "type": "ID!", }, + "metadata": Object { + "type": "ContentfulMetadata!", + }, "size": Object { "type": "Int", }, @@ -785,6 +788,9 @@ Array [ "id": Object { "type": "ID!", }, + "metadata": Object { + "type": "ContentfulMetadata!", + }, "sys": Object { "type": "ContentfulSys!", }, diff --git a/packages/gatsby-source-contentful/src/__tests__/__snapshots__/gatsby-node.js.snap b/packages/gatsby-source-contentful/src/__tests__/__snapshots__/gatsby-node.js.snap deleted file mode 100644 index 4e62cb24f807d..0000000000000 --- a/packages/gatsby-source-contentful/src/__tests__/__snapshots__/gatsby-node.js.snap +++ /dev/null @@ -1,409 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`gatsby-node stores rich text as raw with references attached 1`] = ` -Array [ - "ahntqop9oi7x___7oHxo6bs0us9wIkq27qdyK___Entry", - "ahntqop9oi7x___6KpLS2NZyB3KAvDzWf4Ukh___Entry", - "ahntqop9oi7x___4ZQrqcrTunWiuNaavhGYNT___Asset", -] -`; - -exports[`gatsby-node stores rich text as JSON 2`] = ` -Object { - "content": Array [ - Object { - "content": Array [ - Object { - "data": Object {}, - "marks": Array [], - "nodeType": "text", - "value": "This is the homepage", - }, - ], - "data": Object {}, - "nodeType": "paragraph", - }, - Object { - "content": Array [ - Object { - "data": Object {}, - "marks": Array [], - "nodeType": "text", - "value": "Heading 1", - }, - ], - "data": Object {}, - "nodeType": "heading-1", - }, - Object { - "content": Array [ - Object { - "data": Object {}, - "marks": Array [], - "nodeType": "text", - "value": "Heading 2", - }, - ], - "data": Object {}, - "nodeType": "heading-2", - }, - Object { - "content": Array [ - Object { - "data": Object {}, - "marks": Array [], - "nodeType": "text", - "value": "Heading 3", - }, - ], - "data": Object {}, - "nodeType": "heading-3", - }, - Object { - "content": Array [ - Object { - "data": Object {}, - "marks": Array [], - "nodeType": "text", - "value": "Heading 4", - }, - ], - "data": Object {}, - "nodeType": "heading-4", - }, - Object { - "content": Array [ - Object { - "data": Object {}, - "marks": Array [], - "nodeType": "text", - "value": "Heading 5", - }, - ], - "data": Object {}, - "nodeType": "heading-5", - }, - Object { - "content": Array [ - Object { - "data": Object {}, - "marks": Array [], - "nodeType": "text", - "value": "Heading 6", - }, - ], - "data": Object {}, - "nodeType": "heading-6", - }, - Object { - "content": Array [ - Object { - "data": Object {}, - "marks": Array [], - "nodeType": "text", - "value": "This is ", - }, - Object { - "data": Object {}, - "marks": Array [ - Object { - "type": "bold", - }, - ], - "nodeType": "text", - "value": "bold ", - }, - Object { - "data": Object {}, - "marks": Array [], - "nodeType": "text", - "value": "and ", - }, - Object { - "data": Object {}, - "marks": Array [ - Object { - "type": "italic", - }, - ], - "nodeType": "text", - "value": "italic", - }, - Object { - "data": Object {}, - "marks": Array [], - "nodeType": "text", - "value": " and ", - }, - Object { - "data": Object {}, - "marks": Array [ - Object { - "type": "bold", - }, - Object { - "type": "italic", - }, - ], - "nodeType": "text", - "value": "both", - }, - ], - "data": Object {}, - "nodeType": "paragraph", - }, - Object { - "content": Array [ - Object { - "content": Array [ - Object { - "content": Array [ - Object { - "data": Object {}, - "marks": Array [], - "nodeType": "text", - "value": "Very", - }, - ], - "data": Object {}, - "nodeType": "paragraph", - }, - ], - "data": Object {}, - "nodeType": "list-item", - }, - Object { - "content": Array [ - Object { - "content": Array [ - Object { - "data": Object {}, - "marks": Array [], - "nodeType": "text", - "value": "useful", - }, - ], - "data": Object {}, - "nodeType": "paragraph", - }, - ], - "data": Object {}, - "nodeType": "list-item", - }, - Object { - "content": Array [ - Object { - "content": Array [ - Object { - "data": Object {}, - "marks": Array [], - "nodeType": "text", - "value": "list", - }, - ], - "data": Object {}, - "nodeType": "paragraph", - }, - ], - "data": Object {}, - "nodeType": "list-item", - }, - ], - "data": Object {}, - "nodeType": "unordered-list", - }, - Object { - "content": Array [ - Object { - "content": Array [ - Object { - "data": Object {}, - "marks": Array [], - "nodeType": "text", - "value": "This is a quote", - }, - ], - "data": Object {}, - "nodeType": "paragraph", - }, - ], - "data": Object {}, - "nodeType": "blockquote", - }, - Object { - "content": Array [ - Object { - "data": Object {}, - "marks": Array [], - "nodeType": "text", - "value": "Reference tests:", - }, - ], - "data": Object {}, - "nodeType": "heading-2", - }, - Object { - "content": Array [ - Object { - "data": Object {}, - "marks": Array [], - "nodeType": "text", - "value": "Inline Link: ", - }, - Object { - "content": Array [], - "data": Object { - "target": Object { - "sys": Object { - "id": "7oHxo6bs0us9wIkq27qdyK", - "linkType": "Entry", - "type": "Link", - }, - }, - }, - "nodeType": "embedded-entry-inline", - }, - Object { - "data": Object {}, - "marks": Array [], - "nodeType": "text", - "value": "", - }, - ], - "data": Object {}, - "nodeType": "paragraph", - }, - Object { - "content": Array [ - Object { - "data": Object {}, - "marks": Array [], - "nodeType": "text", - "value": "Link in list:", - }, - ], - "data": Object {}, - "nodeType": "paragraph", - }, - Object { - "content": Array [ - Object { - "content": Array [ - Object { - "content": Array [ - Object { - "data": Object {}, - "marks": Array [], - "nodeType": "text", - "value": "", - }, - Object { - "content": Array [], - "data": Object { - "target": Object { - "sys": Object { - "id": "6KpLS2NZyB3KAvDzWf4Ukh", - "linkType": "Entry", - "type": "Link", - }, - }, - }, - "nodeType": "embedded-entry-inline", - }, - Object { - "data": Object {}, - "marks": Array [], - "nodeType": "text", - "value": "", - }, - ], - "data": Object {}, - "nodeType": "paragraph", - }, - ], - "data": Object {}, - "nodeType": "list-item", - }, - ], - "data": Object {}, - "nodeType": "ordered-list", - }, - Object { - "content": Array [ - Object { - "data": Object {}, - "marks": Array [], - "nodeType": "text", - "value": "Embedded Entity:", - }, - ], - "data": Object {}, - "nodeType": "paragraph", - }, - Object { - "content": Array [], - "data": Object { - "target": Object { - "sys": Object { - "id": "7oHxo6bs0us9wIkq27qdyK", - "linkType": "Entry", - "type": "Link", - }, - }, - }, - "nodeType": "embedded-entry-block", - }, - Object { - "content": Array [ - Object { - "data": Object {}, - "marks": Array [], - "nodeType": "text", - "value": "", - }, - ], - "data": Object {}, - "nodeType": "paragraph", - }, - Object { - "content": Array [ - Object { - "data": Object {}, - "marks": Array [], - "nodeType": "text", - "value": "Embedded Asset:", - }, - ], - "data": Object {}, - "nodeType": "heading-2", - }, - Object { - "content": Array [], - "data": Object { - "target": Object { - "sys": Object { - "id": "4ZQrqcrTunWiuNaavhGYNT", - "linkType": "Asset", - "type": "Link", - }, - }, - }, - "nodeType": "embedded-asset-block", - }, - Object { - "content": Array [ - Object { - "data": Object {}, - "marks": Array [], - "nodeType": "text", - "value": "", - }, - ], - "data": Object {}, - "nodeType": "paragraph", - }, - ], - "data": Object {}, - "nodeType": "document", -} -`; diff --git a/packages/gatsby-source-contentful/src/__tests__/download-contentful-assets.js b/packages/gatsby-source-contentful/src/__tests__/download-contentful-assets.js index f9a018efb303e..5412ba7461c13 100644 --- a/packages/gatsby-source-contentful/src/__tests__/download-contentful-assets.js +++ b/packages/gatsby-source-contentful/src/__tests__/download-contentful-assets.js @@ -1,9 +1,6 @@ // @ts-check import { downloadContentfulAssets } from "../download-contentful-assets" import { createAssetNodes } from "../normalize" -import { createPluginConfig } from "../plugin-options" - -const pluginConfig = createPluginConfig({}) jest.mock(`gatsby-source-filesystem`, () => { return { @@ -59,6 +56,7 @@ const fixtures = [ environment: mockedContentfulEntity, revision: 123, }, + metadata: { tags: [] }, }, ] @@ -86,7 +84,6 @@ describe(`downloadContentfulAssets`, () => { defaultLocale, locales, space, - pluginConfig, }) )) ) diff --git a/packages/gatsby-source-contentful/src/__tests__/gatsby-node.js b/packages/gatsby-source-contentful/src/__tests__/gatsby-node.js index 9768671b61256..4e7c495d4e3d9 100644 --- a/packages/gatsby-source-contentful/src/__tests__/gatsby-node.js +++ b/packages/gatsby-source-contentful/src/__tests__/gatsby-node.js @@ -6,7 +6,6 @@ import { fetchContent, fetchContentTypes } from "../fetch" import { makeId } from "../normalize" import startersBlogFixture from "../__fixtures__/starter-blog-data" -import richTextFixture from "../__fixtures__/rich-text-data" jest.mock(`../fetch`) @@ -33,20 +32,40 @@ describe(`gatsby-node`, () => { setPluginStatus: jest.fn(), createNode: jest.fn(async node => { node.internal.owner = `gatsby-source-contentful` - // don't allow mutations (this isn't traversing so only top level is frozen) - currentNodeMap.set(node.id, Object.freeze(node)) + currentNodeMap.set(node.id, node) }), deleteNode: jest.fn(node => { currentNodeMap.delete(node.id) }), touchNode: jest.fn(), } - const schema = { buildObjectType: jest.fn(), buildInterfaceType: jest.fn() } + + const schemaCustomizationTypes = [] + const schema = { + buildObjectType: jest.fn(config => { + schemaCustomizationTypes.push({ + typeOrTypeDef: { config }, + plugin: { name: `gatsby-source-contentful` }, + }) + }), + buildInterfaceType: jest.fn(config => { + schemaCustomizationTypes.push({ + typeOrTypeDef: { config }, + plugin: { name: `gatsby-source-contentful` }, + }) + }), + } + const store = { getState: jest.fn(() => { - return { program: { directory: process.cwd() }, status: {} } + return { + program: { directory: process.cwd() }, + status: {}, + schemaCustomization: { types: schemaCustomizationTypes }, + } }), } + const cache = createMockCache() const getCache = jest.fn(() => cache) const reporter = { @@ -322,6 +341,7 @@ describe(`gatsby-node`, () => { cache.set.mockClear() reporter.info.mockClear() reporter.panic.mockClear() + schemaCustomizationTypes.length = 0 }) it(`should create nodes from initial payload`, async () => { @@ -468,7 +488,7 @@ describe(`gatsby-node`, () => { "Contentful: 0 deleted entries", ], Array [ - "Contentful: 22 cached entries", + "Contentful: 8 cached entries", ], Array [ "Contentful: 1 new assets", @@ -558,7 +578,7 @@ describe(`gatsby-node`, () => { "Contentful: 0 deleted entries", ], Array [ - "Contentful: 28 cached entries", + "Contentful: 10 cached entries", ], Array [ "Contentful: 0 new assets", @@ -647,7 +667,7 @@ describe(`gatsby-node`, () => { expect(actions.createNode).toHaveBeenCalledTimes(44) expect(actions.deleteNode).toHaveBeenCalledTimes(2) - expect(actions.touchNode).toHaveBeenCalledTimes(74) + expect(actions.touchNode).toHaveBeenCalledTimes(72) expect(reporter.info.mock.calls).toMatchInlineSnapshot(` Array [ Array [ @@ -660,7 +680,7 @@ describe(`gatsby-node`, () => { "Contentful: 1 deleted entries", ], Array [ - "Contentful: 28 cached entries", + "Contentful: 10 cached entries", ], Array [ "Contentful: 0 new assets", @@ -733,7 +753,7 @@ describe(`gatsby-node`, () => { expect(actions.createNode).toHaveBeenCalledTimes(44) expect(actions.deleteNode).toHaveBeenCalledTimes(2) - expect(actions.touchNode).toHaveBeenCalledTimes(74) + expect(actions.touchNode).toHaveBeenCalledTimes(72) expect(reporter.info.mock.calls).toMatchInlineSnapshot(` Array [ Array [ @@ -746,7 +766,7 @@ describe(`gatsby-node`, () => { "Contentful: 0 deleted entries", ], Array [ - "Contentful: 28 cached entries", + "Contentful: 10 cached entries", ], Array [ "Contentful: 0 new assets", @@ -764,26 +784,6 @@ describe(`gatsby-node`, () => { `) }) - it(`stores rich text as JSON`, async () => { - // @ts-ignore - fetchContent.mockImplementationOnce(richTextFixture.initialSync) - // @ts-ignore - fetchContentTypes.mockImplementationOnce(richTextFixture.contentTypeItems) - - // initial sync - await simulateGatsbyBuild() - - const initNodes = getNodes() - - const homeNodes = initNodes.filter( - ({ sys: { id } }) => id === `6KpLS2NZyB3KAvDzWf4Ukh` - ) - expect(homeNodes).toHaveLength(2) - homeNodes.forEach(homeNode => { - expect(homeNode.content).toMatchSnapshot() - }) - }) - it(`panics when localeFilter reduces locale list to 0`, async () => { // @ts-ignore fetchContent.mockImplementationOnce(startersBlogFixture.initialSync) @@ -804,54 +804,4 @@ describe(`gatsby-node`, () => { }) ) }) - - it(`panics when response contains restricted content types`, async () => { - // @ts-ignore - fetchContent.mockImplementationOnce( - restrictedContentTypeFixture.initialSync - ) - // @ts-ignore - fetchContentTypes.mockImplementationOnce( - restrictedContentTypeFixture.contentTypeItems - ) - - await simulateGatsbyBuild() - - expect(reporter.panic).toBeCalledWith( - expect.objectContaining({ - context: { - sourceMessage: `Restricted ContentType name found. The name "reference" is not allowed.`, - }, - }) - ) - }) - - it(`panics when response contains content type Tag while enableTags is true`, async () => { - // @ts-ignore - fetchContent.mockImplementationOnce( - restrictedContentTypeFixture.initialSync - ) - const contentTypesWithTag = () => { - const manipulatedContentTypeItems = - restrictedContentTypeFixture.contentTypeItems() - manipulatedContentTypeItems[0].name = `Tag` - return manipulatedContentTypeItems - } - // @ts-ignore - fetchContentTypes.mockImplementationOnce(contentTypesWithTag) - - await simulateGatsbyBuild({ - spaceId: `mocked`, - enableTags: true, - useNameForId: true, - }) - - expect(reporter.panic).toBeCalledWith( - expect.objectContaining({ - context: { - sourceMessage: `Restricted ContentType name found. The name "tag" is not allowed.`, - }, - }) - ) - }) }) diff --git a/packages/gatsby-source-contentful/src/__tests__/normalize.js b/packages/gatsby-source-contentful/src/__tests__/normalize.js index 5e43a7d7d1235..491a976bb1501 100644 --- a/packages/gatsby-source-contentful/src/__tests__/normalize.js +++ b/packages/gatsby-source-contentful/src/__tests__/normalize.js @@ -210,35 +210,28 @@ describe(`Process contentful data (by name)`, () => { const nodeTypeCounts = countCreatedNodeTypesFromMock(createNode.mock) - expect(Object.keys(nodeTypeCounts)).toHaveLength(15) - expect(nodeTypeCounts).toEqual( expect.objectContaining({ + ContentfulContentType: contentTypeItems.length, + // Generated child entities + ContentfulText: 38, // 3 Brand Contentful entries - ContentfulBrand: 6, - contentfulBrandCompanyDescriptionTextNode: 6, - contentfulBrandCompanyNameTextNode: 6, + ContentfulContentTypeBrand: 6, // 2 Category Contentful entries - ContentfulCategory: 4, - contentfulCategoryCategoryDescriptionTextNode: 4, - contentfulCategoryTitleTextNode: 4, - ContentfulContentType: contentTypeItems.length, + ContentfulContentTypeCategory: 4, // 1 JSON Test Contentful entry - ContentfulJsonTest: 2, - contentfulJsonTestJsonStringTestJsonNode: 2, - contentfulJsonTestJsonTestJsonNode: 2, + ContentfulContentTypeJsonTest: 2, // 4 Product Contentful entries - ContentfulProduct: 8, - contentfulProductProductDescriptionTextNode: 8, - contentfulProductProductNameTextNode: 8, + ContentfulContentTypeProduct: 8, // 1 Remark Test Contentful entry - ContentfulRemarkTest: 2, - contentfulRemarkTestContentTextNode: 2, + ContentfulContentTypeRemarkTest: 2, }) ) + expect(Object.keys(nodeTypeCounts)).toHaveLength(7) + // Relevant to compare to compare warm and cold situation - expect(createNode.mock.calls.length).toBe(69) // "cold build entries" count + expect(createNode.mock.calls.length).toBe(65) // "cold build entries" count }) it(`creates nodes for each asset`, () => { @@ -253,7 +246,6 @@ describe(`Process contentful data (by name)`, () => { defaultLocale, locales, space, - pluginConfig, }) }) const nodeTypeCounts = countCreatedNodeTypesFromMock(createNode.mock) @@ -295,7 +287,7 @@ describe(`Skip existing nodes in warm build`, () => { // returned is not relevant to test so update if anything breaks. return { id, - internal: { contentDigest: entryList[0][0].sys.publishedAt }, + internal: { contentDigest: entryList[0][0].sys.updatedAt }, } } // All other nodes are new ("unknown") @@ -323,32 +315,13 @@ describe(`Skip existing nodes in warm build`, () => { const nodeTypeCounts = countCreatedNodeTypesFromMock(createNode.mock) - expect(Object.keys(nodeTypeCounts)).toHaveLength(15) + expect(nodeTypeCounts.ContentfulContentTypeCategory).toBe(3) - expect(nodeTypeCounts).toEqual( - expect.objectContaining({ - ContentfulBrand: 6, - contentfulBrandCompanyDescriptionTextNode: 6, - contentfulBrandCompanyNameTextNode: 6, - // These 3 category entities matter as the first node is skipped in the test - ContentfulCategory: 3, - contentfulCategoryCategoryDescriptionTextNode: 3, - contentfulCategoryTitleTextNode: 3, - ContentfulContentType: 5, - ContentfulJsonTest: 2, - contentfulJsonTestJsonStringTestJsonNode: 2, - contentfulJsonTestJsonTestJsonNode: 2, - ContentfulProduct: 8, - contentfulProductProductDescriptionTextNode: 8, - contentfulProductProductNameTextNode: 8, - ContentfulRemarkTest: 2, - contentfulRemarkTestContentTextNode: 2, - }) - ) + expect(Object.keys(nodeTypeCounts)).toHaveLength(7) // Relevant to compare to compare warm and cold situation // This number ought to be less than the cold build - expect(createNode.mock.calls.length).toBe(66) // "warm build where entry was not changed" count + expect(createNode.mock.calls.length).toBe(62) // "warm build where entry was not changed" count }) }) @@ -414,36 +387,28 @@ describe(`Process existing mutated nodes in warm build`, () => { const nodeTypeCounts = countCreatedNodeTypesFromMock(createNode.mock) - expect(Object.keys(nodeTypeCounts)).toHaveLength(15) - expect(nodeTypeCounts).toEqual( expect.objectContaining({ + ContentfulContentType: contentTypeItems.length, + // Child entities + ContentfulText: 38, // 3 Brand Contentful entries - ContentfulBrand: 6, - contentfulBrandCompanyDescriptionTextNode: 6, - contentfulBrandCompanyNameTextNode: 6, + ContentfulContentTypeBrand: 6, // 2 Category Contentful entries - ContentfulCategory: 4, - contentfulCategoryCategoryDescriptionTextNode: 4, - contentfulCategoryTitleTextNode: 4, - ContentfulContentType: contentTypeItems.length, + ContentfulContentTypeCategory: 4, // 1 JSON Test Contentful entry - ContentfulJsonTest: 2, - contentfulJsonTestJsonStringTestJsonNode: 2, - contentfulJsonTestJsonTestJsonNode: 2, + ContentfulContentTypeJsonTest: 2, // 4 Product Contentful entries - ContentfulProduct: 8, - contentfulProductProductDescriptionTextNode: 8, - contentfulProductProductNameTextNode: 8, + ContentfulContentTypeProduct: 8, // 1 Remark Test Contentful entry - ContentfulRemarkTest: 2, - contentfulRemarkTestContentTextNode: 2, + ContentfulContentTypeRemarkTest: 2, }) ) + expect(Object.keys(nodeTypeCounts)).toHaveLength(7) // Relevant to compare to compare warm and cold situation // This number ought to be the same as the cold build - expect(createNode.mock.calls.length).toBe(69) // "warm build where entry was changed" count + expect(createNode.mock.calls.length).toBe(65) // "warm build where entry was changed" count }) }) @@ -517,32 +482,23 @@ describe(`Process contentful data (by id)`, () => { }) const nodeTypeCounts = countCreatedNodeTypesFromMock(createNode.mock) - expect(Object.keys(nodeTypeCounts)).toHaveLength(15) - expect(nodeTypeCounts).toEqual( expect.objectContaining({ + ContentfulContentType: contentTypeItems.length, // 3 Brand Contentful entries - ContentfulSFzTZbSuM8CoEwygeUYes: 6, - contentfulSFzTZbSuM8CoEwygeUYesCompanyDescriptionTextNode: 6, - contentfulSFzTZbSuM8CoEwygeUYesCompanyNameTextNode: 6, + ContentfulContentTypeSFzTZbSuM8CoEwygeUYes: 6, // 2 Category Contentful entries - Contentful6XwpTaSiiI2Ak2Ww0Oi6Qa: 4, - contentful6XwpTaSiiI2Ak2Ww0Oi6QaCategoryDescriptionTextNode: 4, - contentful6XwpTaSiiI2Ak2Ww0Oi6QaTitleTextNode: 4, - ContentfulContentType: contentTypeItems.length, + ContentfulContentType6XwpTaSiiI2Ak2Ww0Oi6Qa: 4, // 1 JSON Test Contentful entry - ContentfulJsonTest: 2, - contentfulJsonTestJsonStringTestJsonNode: 2, - contentfulJsonTestJsonTestJsonNode: 2, + ContentfulContentTypeJsonTest: 2, // 4 Product Contentful entries - Contentful2PqfXuJwE8QSyKuM0U6W8M: 8, - contentful2PqfXuJwE8QSyKuM0U6W8MProductDescriptionTextNode: 8, - contentful2PqfXuJwE8QSyKuM0U6W8MProductNameTextNode: 8, + ContentfulContentType2PqfXuJwE8QSyKuM0U6W8M: 8, // 1 Remark Test Contentful entry - ContentfulRemarkTest: 2, - contentfulRemarkTestContentTextNode: 2, + ContentfulContentTypeRemarkTest: 2, }) ) + + expect(Object.keys(nodeTypeCounts)).toHaveLength(7) }) }) diff --git a/packages/gatsby-source-contentful/src/normalize.js b/packages/gatsby-source-contentful/src/normalize.js index 75da09981dc72..1a70117c62eb4 100644 --- a/packages/gatsby-source-contentful/src/normalize.js +++ b/packages/gatsby-source-contentful/src/normalize.js @@ -305,7 +305,7 @@ export const createNodesForContentType = ({ displayField: contentTypeItem.displayField, description: contentTypeItem.description, internal: { - type: `${makeTypeName(`ContentType`)}`, + type: `ContentfulContentType`, contentDigest: contentTypeItem.sys.updatedAt, }, // https://www.contentful.com/developers/docs/references/content-delivery-api/#/introduction/common-resource-attributes @@ -564,7 +564,6 @@ export const createAssetNodes = ({ defaultLocale, locales, space, - pluginConfig, }) => { const createNodePromises = [] locales.forEach(locale => { diff --git a/packages/gatsby-source-contentful/src/source-nodes.js b/packages/gatsby-source-contentful/src/source-nodes.js index bed7bfd7118dd..5d35d3c5e1fc0 100644 --- a/packages/gatsby-source-contentful/src/source-nodes.js +++ b/packages/gatsby-source-contentful/src/source-nodes.js @@ -4,7 +4,7 @@ import _ from "lodash" import { downloadContentfulAssets } from "./download-contentful-assets" import { fetchContent } from "./fetch" -import { generateSchema } from "./generate-schema" + import { buildEntryList, buildForeignReferenceMap, @@ -51,35 +51,29 @@ export async function sourceNodes( getCache, reporter, parentSpan, - schema, }, pluginOptions ) { - const { - createNode, - touchNode, - deleteNode, - unstable_createNodeManifest, - createTypes, - } = actions + const { createNode, touchNode, deleteNode, unstable_createNodeManifest } = + actions const online = await isOnline() + getNodes().forEach(node => { + if (node.internal.owner !== `gatsby-source-contentful`) { + return + } + touchNode(node) + if (node?.fields?.localFile) { + // Prevent GraphQL type inference from crashing on this property + touchNode(getNode(node.fields.localFile)) + } + }) + if ( !online && process.env.GATSBY_CONTENTFUL_OFFLINE === `true` && process.env.NODE_ENV !== `production` ) { - getNodes().forEach(node => { - if (node.internal.owner !== `gatsby-source-contentful`) { - return - } - touchNode(node) - if (node.localFile___NODE) { - // Prevent GraphQL type inference from crashing on this property - touchNode(getNode(node.localFile___NODE)) - } - }) - return } @@ -188,18 +182,13 @@ export async function sourceNodes( ) processingActivity.start() - // Generate schemas based on Contentful content model - generateSchema({ createTypes, schema, pluginConfig, contentTypeItems }) - - // Array of all existing Contentful nodes + // Array of all existing Contentful entry and asset nodes const existingNodes = getNodes().filter( n => - n.internal.owner === `gatsby-source-contentful` && - (pluginConfig.get(`enableTags`) - ? n.internal.type !== `ContentfulTag` - : true) + (n.internal.owner === `gatsby-source-contentful` && + n.internal.type.indexOf(`ContentfulContentType`) === 0) || + n.internal.type === `ContentfulAsset` ) - existingNodes.forEach(n => touchNode(n)) // Report existing, new and updated nodes const nodeCounts = { @@ -212,6 +201,7 @@ export async function sourceNodes( deletedEntry: currentSyncData.deletedEntries.length, deletedAsset: currentSyncData.deletedAssets.length, } + existingNodes.forEach(node => nodeCounts[`existing${node.sys.type}`]++) currentSyncData.entries.forEach(entry => entry.sys.revision === 1 ? nodeCounts.newEntry++ : nodeCounts.updatedEntry++ @@ -263,28 +253,101 @@ export async function sourceNodes( newOrUpdatedEntries.add(generateReferenceId(entry)) }) }) + // const state = store.getState() + // console.log( + // { schema, keys: Object.keys(schema) }, + // state + // ) + + // const typeMap = await schema.getTypeMap() + + // console.log({ typeMap }) + + // const contentfulTypeDefinitions = new Map() + // store + // .getState() + // .schemaCustomization.types.filter( + // ({ plugin }) => plugin.name === `gatsby-source-contentful` + // ) + // .forEach(({ typeOrTypeDef }) => { + // contentfulTypeDefinitions.set( + // typeOrTypeDef.config.name, + // typeOrTypeDef.config + // ) + // // console.log(typeOrTypeDef.config.fields) + // }) + + // console.log(contentfulTypeDefinitions) + + const { deletedEntries, deletedAssets } = currentSyncData + + const allDeletedNodes = [...deletedEntries, ...deletedAssets] + const deletedNodeIds = [] + + locales.forEach(locale => { + allDeletedNodes.forEach(n => { + deletedNodeIds.push( + makeId({ + spaceId: n.sys.space.sys.id, + id: n.sys.id, + type: n.sys.type, + currentLocale: locale.code, + defaultLocale, + }) + ) + }) + }) - // Update existing entry nodes that weren't updated but that need reverse links added. + // Update existing entry nodes that weren't updated but that need references updated. existingNodes .filter(n => !newOrUpdatedEntries.has(generateReferenceId(n))) .forEach(n => { const nodeId = generateReferenceId(n) + if (foreignReferenceMap[nodeId]) { foreignReferenceMap[nodeId].forEach(foreignReference => { - const { name, id } = foreignReference + const { name } = foreignReference + + const referencedNodeId = makeId({ + ...foreignReference, + currentLocale: n.sys.locale, + defaultLocale, + }) // Create new reference field when none exists if (!n[name]) { - n[name] = [id] + n[name] = [referencedNodeId] return } // Add non existing references to reference field - if (n[name] && !n[name].includes(id)) { - n[name].push(id) + if (n[name] && !n[name].includes(referencedNodeId)) { + n[name].push(referencedNodeId) } }) } + + // Remove references to deleted nodes in regular reference fields and reverse reference fields + Object.keys(n) + .filter(fieldName => fieldName.endsWith(`___NODE`)) + .forEach(fieldName => { + const referenceField = n[fieldName] + + if (!referenceField) { + return + } + + if (Array.isArray(referenceField)) { + n[fieldName] = referenceField.filter( + id => !deletedNodeIds.includes(id) + ) + return + } + + if (deletedNodeIds.includes(referenceField)) { + n[fieldName] = null + } + }) }) function deleteContentfulNode(node) { @@ -308,14 +371,10 @@ export async function sourceNodes( .filter(node => node) localizedNodes.forEach(node => { - // touchNode first, to populate typeOwners & avoid erroring - touchNode(node) deleteNode(node) }) } - const { deletedEntries, deletedAssets } = currentSyncData - if (deletedEntries.length || deletedAssets.length) { const deletionActivity = reporter.activityTimer( `Contentful: Deleting ${deletedEntries.length} nodes and ${deletedAssets.length} assets (${sourceId})`, @@ -391,7 +450,6 @@ export async function sourceNodes( defaultLocale, locales, space, - pluginConfig, }) )) ) From c9ffbc604b41cf205364c86e04c59a7c05e1efd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benedikt=20R=C3=B6tsch?= Date: Wed, 5 May 2021 23:53:23 +0200 Subject: [PATCH 34/34] refactor: rewrite using-contentful for schema customization --- .../pages/categories/{ContentfulCategory.id}.js | 10 +++++----- examples/using-contentful/src/pages/image-api.js | 2 +- examples/using-contentful/src/pages/index.js | 14 +++++++------- .../src/pages/products/{ContentfulProduct.id}.js | 14 +++++++------- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/examples/using-contentful/src/pages/categories/{ContentfulCategory.id}.js b/examples/using-contentful/src/pages/categories/{ContentfulCategory.id}.js index 1505b6d3b9136..3f8646a6de115 100644 --- a/examples/using-contentful/src/pages/categories/{ContentfulCategory.id}.js +++ b/examples/using-contentful/src/pages/categories/{ContentfulCategory.id}.js @@ -15,7 +15,7 @@ class CategoryTemplate extends React.Component { render() { const category = this.props.data.contentfulCategory const { - title: { title }, + title: { raw: title }, product, icon, } = category @@ -45,7 +45,7 @@ class CategoryTemplate extends React.Component { {product && product.map((p, i) => (
  • - {p.productName.productName} + {p.productName.raw}
  • ))} @@ -60,10 +60,10 @@ CategoryTemplate.propTypes = propTypes export default CategoryTemplate export const pageQuery = graphql` - query($id: String!) { + query ($id: String!) { contentfulCategory(id: { eq: $id }) { title { - title + raw } icon { gatsbyImageData(layout: FIXED, width: 75) @@ -72,7 +72,7 @@ export const pageQuery = graphql` gatsbyPath(filePath: "/products/{ContentfulProduct.id}") id productName { - productName + raw } } } diff --git a/examples/using-contentful/src/pages/image-api.js b/examples/using-contentful/src/pages/image-api.js index fb1104abe76ad..14126c469d708 100644 --- a/examples/using-contentful/src/pages/image-api.js +++ b/examples/using-contentful/src/pages/image-api.js @@ -317,7 +317,7 @@ export default ImageAPI export const pageQuery = graphql` query { - allContentfulAsset(filter: { node_locale: { eq: "en-US" } }) { + allContentfulAsset(filter: { sys: { locale: { eq: "en-US" } } }) { edges { node { title diff --git a/examples/using-contentful/src/pages/index.js b/examples/using-contentful/src/pages/index.js index 3f9ef900e998c..c93c2a1eaf5e3 100644 --- a/examples/using-contentful/src/pages/index.js +++ b/examples/using-contentful/src/pages/index.js @@ -34,7 +34,7 @@ const Product = ({ node }) => ( /> )}
    -
    {node.productName.productName}
    +
    {node.productName.raw}
    @@ -61,8 +61,8 @@ class IndexPage extends React.Component {

    An entry and asset node are created for each locale following fallback rules for missing localization. In addition, each node has - an additional field added, node_locale so you can - select for nodes from a single locale + an additional field added, sys.locale so you can select + for nodes from a single locale

    en-US

    {usProductEdges.map(({ node }, i) => ( @@ -86,13 +86,13 @@ export default IndexPage export const pageQuery = graphql` query { - us: allContentfulProduct(filter: { node_locale: { eq: "en-US" } }) { + us: allContentfulProduct(filter: { sys: { locale: { eq: "en-US" } } }) { edges { node { id gatsbyPath(filePath: "/products/{ContentfulProduct.id}") productName { - productName + raw } image { gatsbyImageData(layout: FIXED, width: 75) @@ -100,13 +100,13 @@ export const pageQuery = graphql` } } } - german: allContentfulProduct(filter: { node_locale: { eq: "de" } }) { + german: allContentfulProduct(filter: { sys: { locale: { eq: "de" } } }) { edges { node { id gatsbyPath(filePath: "/products/{ContentfulProduct.id}") productName { - productName + raw } image { gatsbyImageData(layout: FIXED, width: 75) diff --git a/examples/using-contentful/src/pages/products/{ContentfulProduct.id}.js b/examples/using-contentful/src/pages/products/{ContentfulProduct.id}.js index 14f574714916d..8e558768dee00 100644 --- a/examples/using-contentful/src/pages/products/{ContentfulProduct.id}.js +++ b/examples/using-contentful/src/pages/products/{ContentfulProduct.id}.js @@ -15,7 +15,7 @@ class ProductTemplate extends React.Component { render() { const product = this.props.data.contentfulProduct const { - productName: { productName }, + productName: { raw: productName }, productDescription, price, image, @@ -39,7 +39,7 @@ class ProductTemplate extends React.Component { )}

    {productName}

    -

    Made by {brand.companyName.companyName}

    +

    Made by {brand.companyName.raw}

    Price: ${price}
    (
  • - {category.title.title} + {category.title.raw}
  • ))} @@ -70,10 +70,10 @@ ProductTemplate.propTypes = propTypes export default ProductTemplate export const pageQuery = graphql` - query($id: String!) { + query ($id: String!) { contentfulProduct(id: { eq: $id }) { productName { - productName + raw } productDescription { childMarkdownRemark { @@ -86,14 +86,14 @@ export const pageQuery = graphql` } brand { companyName { - companyName + raw } } categories { id gatsbyPath(filePath: "/categories/{ContentfulCategory.id}") title { - title + raw } } }