Skip to content

Commit 62a4121

Browse files
authored
feat(contentful): warn users when using restricted content type names (#30715)
* feat(contentful): warn users when using restricted content type names. Closes #30089 * docs(contentful): inform about field and content type name limitations
1 parent e5b9222 commit 62a4121

File tree

4 files changed

+143
-0
lines changed

4 files changed

+143
-0
lines changed

packages/gatsby-source-contentful/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ This plugin has several limitations, please be aware of these:
2929

3030
4. Using the preview functionallity might result in broken content over time, as syncing data on preview is not officially supported by Contentful. Make sure to regulary clean your cache when using Contentfuls preview API.
3131

32+
5. The following content type names are not allowed: `entity`, `reference`
33+
34+
6. The following field names are restricted and will be prefixed: `children`, `contentful_id`, `fields`, `id`, `internal`, `parent`,
35+
3236
### Using Delivery API
3337

3438
```javascript
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
exports.initialSync = () => {
2+
return {
3+
currentSyncData: {
4+
entries: [],
5+
assets: [],
6+
deletedEntries: [],
7+
deletedAssets: [],
8+
nextSyncToken: `12345`,
9+
},
10+
contentTypeItems: [
11+
{
12+
sys: {
13+
space: {
14+
sys: {
15+
type: `Link`,
16+
linkType: `Space`,
17+
id: `uzfinxahlog0`,
18+
contentful_id: `uzfinxahlog0`,
19+
},
20+
},
21+
id: `reference`,
22+
type: `ContentType`,
23+
createdAt: `2020-06-03T14:17:18.696Z`,
24+
updatedAt: `2020-06-03T14:17:18.696Z`,
25+
environment: {
26+
sys: {
27+
id: `master`,
28+
type: `Link`,
29+
linkType: `Environment`,
30+
},
31+
},
32+
revision: 1,
33+
contentful_id: `person`,
34+
},
35+
displayField: `name`,
36+
name: `Reference`,
37+
description: ``,
38+
fields: [
39+
{
40+
id: `name`,
41+
name: `Name`,
42+
type: `Symbol`,
43+
localized: false,
44+
required: true,
45+
disabled: false,
46+
omitted: false,
47+
},
48+
],
49+
},
50+
],
51+
defaultLocale: `en-US`,
52+
locales: [
53+
{
54+
code: `en-US`,
55+
name: `English (United States)`,
56+
default: true,
57+
fallbackCode: null,
58+
sys: {
59+
id: `1uSElBQA68GRKF30tpTxxT`,
60+
type: `Locale`,
61+
version: 1,
62+
},
63+
},
64+
],
65+
space: {
66+
sys: { type: `Space`, id: `uzfinxahlog0` },
67+
name: `Starter Gatsby Blog`,
68+
locales: [
69+
{
70+
code: `en-US`,
71+
default: true,
72+
name: `English (United States)`,
73+
fallbackCode: null,
74+
},
75+
],
76+
},
77+
}
78+
}

packages/gatsby-source-contentful/src/__tests__/gatsby-node.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ const normalize = require(`../normalize`)
1313

1414
const startersBlogFixture = require(`../__fixtures__/starter-blog-data`)
1515
const richTextFixture = require(`../__fixtures__/rich-text-data`)
16+
const restrictedContentTypeFixture = require(`../__fixtures__/restricted-content-type`)
1617

1718
const pluginOptions = { spaceId: `testSpaceId` }
1819

@@ -742,4 +743,38 @@ describe(`gatsby-node`, () => {
742743
})
743744
)
744745
})
746+
747+
it(`panics when response contains restricted content types`, async () => {
748+
cache.get.mockClear()
749+
cache.set.mockClear()
750+
fetch.mockImplementationOnce(restrictedContentTypeFixture.initialSync)
751+
752+
const mockPanicReporter = {
753+
...reporter,
754+
panic: jest.fn(),
755+
}
756+
757+
await gatsbyNode.sourceNodes(
758+
{
759+
actions,
760+
store,
761+
getNodes,
762+
getNode,
763+
reporter: mockPanicReporter,
764+
createNodeId,
765+
cache,
766+
getCache,
767+
schema,
768+
},
769+
pluginOptions
770+
)
771+
772+
expect(mockPanicReporter.panic).toBeCalledWith(
773+
expect.objectContaining({
774+
context: {
775+
sourceMessage: `Restricted ContentType name found. The name "reference" is not allowed.`,
776+
},
777+
})
778+
)
779+
})
745780
})

packages/gatsby-source-contentful/src/gatsby-node.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ const restrictedNodeFields = [
2424
`parent`,
2525
]
2626

27+
const restrictedContentTypes = [`entity`, `reference`]
28+
2729
exports.setFieldsOnGraphQLNodeType = require(`./extend-node-type`).extendNodeType
2830

2931
const validateContentfulAccess = async pluginOptions => {
@@ -311,6 +313,30 @@ exports.sourceNodes = async (
311313
}
312314
}
313315

316+
// Check for restricted content type names
317+
const useNameForId = pluginConfig.get(`useNameForId`)
318+
319+
contentTypeItems.forEach(contentTypeItem => {
320+
// Establish identifier for content type
321+
// Use `name` if specified, otherwise, use internal id (usually a natural-language constant,
322+
// but sometimes a base62 uuid generated by Contentful, hence the option)
323+
let contentTypeItemId
324+
if (useNameForId) {
325+
contentTypeItemId = contentTypeItem.name.toLowerCase()
326+
} else {
327+
contentTypeItemId = contentTypeItem.sys.id.toLowerCase()
328+
}
329+
330+
if (restrictedContentTypes.includes(contentTypeItemId)) {
331+
reporter.panic({
332+
id: CODES.FetchContentTypes,
333+
context: {
334+
sourceMessage: `Restricted ContentType name found. The name "${contentTypeItemId}" is not allowed.`,
335+
},
336+
})
337+
}
338+
})
339+
314340
const allLocales = locales
315341
locales = locales.filter(pluginConfig.get(`localeFilter`))
316342
reporter.verbose(

0 commit comments

Comments
 (0)