Skip to content

Commit

Permalink
fix(gatsby): print childOf directive for implicit child fields
Browse files Browse the repository at this point in the history
  • Loading branch information
vladar committed Dec 21, 2020
1 parent 3727947 commit 4d7f4b3
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 20 deletions.
12 changes: 12 additions & 0 deletions packages/gatsby/src/schema/__tests__/__snapshots__/print.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,10 @@ input Baz {
qux: Boolean
}
type FooChild implements Node @childOf(types: [\\"Test\\"]) @dontInfer {
bar: String
}
type Test implements Node @dontInfer {
foo: Int
}"
Expand Down Expand Up @@ -266,6 +270,10 @@ type OneMoreTest implements Node @dontInfer {
union ThisOrThat = AnotherTest | OneMoreTest
type FooChild implements Node @childOf(types: [\\"Test\\"]) @dontInfer {
bar: String
}
type Test implements Node @dontInfer {
foo: Int
}"
Expand Down Expand Up @@ -423,6 +431,10 @@ input Baz {
qux: Boolean
}
type FooChild implements Node @childOf(types: [\\"Test\\"]) @dontInfer {
bar: String
}
type Test implements Node @dontInfer {
foo: Int
}"
Expand Down
17 changes: 15 additions & 2 deletions packages/gatsby/src/schema/__tests__/print.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ const { build } = require(`..`)
import { buildObjectType } from "../types/type-builders"
const { store } = require(`../../redux`)
const { actions } = require(`../../redux/actions/restricted`)
const { actions: publicActions } = require(`../../redux/actions/public`)
const { createParentChildLink } = publicActions
const { printTypeDefinitions } = actions

jest.mock(`fs-extra`)
Expand Down Expand Up @@ -41,14 +43,25 @@ jest.spyOn(global.Date.prototype, `toISOString`).mockReturnValue(`2019-01-01`)
describe(`Print type definitions`, () => {
beforeEach(() => {
store.dispatch({ type: `DELETE_CACHE` })
const node = {
const node1 = {
id: `test1`,
internal: {
type: `Test`,
},
children: [],
foo: 26,
}
store.dispatch({ type: `CREATE_NODE`, payload: { ...node } })
const node2 = {
id: `test2`,
parent: `test1`,
internal: {
type: `FooChild`,
},
bar: `bar`,
}
store.dispatch({ type: `CREATE_NODE`, payload: { ...node1 } })
store.dispatch({ type: `CREATE_NODE`, payload: { ...node2 } })
createParentChildLink({ parent: node1, child: node2 })
const typeDefs = []
typeDefs.push(`
type AnotherTest implements Node & ITest {
Expand Down
52 changes: 34 additions & 18 deletions packages/gatsby/src/schema/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,9 @@ const updateSchemaComposer = async ({
inferenceMetadata,
parentSpan: activity.span,
})
addInferredChildOfExtensions({
schemaComposer,
})
activity.end()

activity = report.phantomActivity(`Processing types`, {
Expand Down Expand Up @@ -202,11 +205,6 @@ const processTypeComposer = async ({

if (typeComposer.hasInterface(`Node`)) {
await addNodeInterfaceFields({ schemaComposer, typeComposer, parentSpan })
await addImplicitConvenienceChildrenFields({
schemaComposer,
typeComposer,
parentSpan,
})
}
await determineSearchableFields({
schemaComposer,
Expand Down Expand Up @@ -999,15 +997,26 @@ const addConvenienceChildrenFields = ({ schemaComposer }) => {
})
}

const addImplicitConvenienceChildrenFields = ({
schemaComposer,
typeComposer,
}) => {
const addInferredChildOfExtensions = ({ schemaComposer }) => {
schemaComposer.forEach(typeComposer => {
if (
typeComposer instanceof ObjectTypeComposer &&
typeComposer.hasInterface(`Node`)
) {
addInferredChildOfExtension({
schemaComposer,
typeComposer,
})
}
})
}

const addInferredChildOfExtension = ({ schemaComposer, typeComposer }) => {
const shouldInfer = typeComposer.getExtension(`infer`)
// In Gatsby v3, when `@dontInfer` is set, children fields will not be
// created for parent-child relations set by plugins with
// In Gatsby v3, when `@dontInfer` is set, `@childOf` extension will not be
// automatically created for parent-child relations set by plugins with
// `createParentChildLink`. With `@dontInfer`, only parent-child
// relations explicitly set with the `childOf` extension will be added.
// relations explicitly set with the `@childOf` extension will be added.
// if (shouldInfer === false) return

const parentTypeName = typeComposer.getTypeName()
Expand All @@ -1017,10 +1026,11 @@ const addImplicitConvenienceChildrenFields = ({

Object.keys(childNodesByType).forEach(typeName => {
// Adding children fields to types with the `@dontInfer` extension is deprecated
if (shouldInfer === false) {
const childTypeComposer = schemaComposer.getAnyTC(typeName)
const childOfExtension = childTypeComposer.getExtension(`childOf`)
const childTypeComposer = schemaComposer.getAnyTC(typeName)
let childOfExtension = childTypeComposer.getExtension(`childOf`)

if (shouldInfer === false) {
// Adding children fields to types with the `@dontInfer` extension is deprecated
// Only warn when the parent-child relation has not been explicitly set with
if (
!childOfExtension ||
Expand All @@ -1046,9 +1056,15 @@ const addImplicitConvenienceChildrenFields = ({
)
}
}

typeComposer.addFields(createChildrenField(typeName))
typeComposer.addFields(createChildField(typeName))
// Set `@childOf` extension automatically
// This will cause convenience children fields like `childImageSharp`
// to be added in `addConvenienceChildrenFields` method.
// Also required for proper printing of the `@childOf` directive in the snapshot plugin
if (!childOfExtension?.types) {
childOfExtension = { types: [] }
}
childOfExtension.types.push(parentTypeName)
childTypeComposer.setExtension(`childOf`, childOfExtension)
})
}

Expand Down

0 comments on commit 4d7f4b3

Please sign in to comment.