Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(gatsby-source-wordpress): schema customization errors #30358

Merged
merged 21 commits into from Mar 24, 2021
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
6e00be4
simplify with optional chaining
TylerBarnes Mar 18, 2021
76da8b3
use new reporter.panic signature with error code
TylerBarnes Mar 18, 2021
7ae6078
add the prefixed typename as a node property when creating nodes to p…
TylerBarnes Mar 18, 2021
22504a2
fix union types that have a field called "type"
TylerBarnes Mar 18, 2021
13d51c2
prevent excluded types from throwing errors in connection fields
TylerBarnes Mar 18, 2021
f21c4f3
test node interface resolution
TylerBarnes Mar 19, 2021
ebb13ea
prevent double-prefixing
TylerBarnes Mar 19, 2021
4c57fe7
test that interfaces that are mixed node and non-node resolve
TylerBarnes Mar 20, 2021
43d1dbe
prefix the __typename field in the default resolver for Gatsby v3
TylerBarnes Mar 20, 2021
e45fa4b
an interface type is only a gatsby node type if all implementing type…
TylerBarnes Mar 20, 2021
2d5d070
exclude Commenter.databaseId in int tests to get around WPGQL bug
TylerBarnes Mar 23, 2021
c47f2b9
only return null if there's no gatsby node AND no resolved field data
TylerBarnes Mar 23, 2021
923a8eb
fix util name spelling
TylerBarnes Mar 23, 2021
864d1d6
add comment author schema to snapshot
TylerBarnes Mar 23, 2021
4876a84
add index page so wait-on doesn't think the 404 means it's not ready
TylerBarnes Mar 23, 2021
6899445
use correct property path in tests
TylerBarnes Mar 23, 2021
0504d19
update comment
TylerBarnes Mar 23, 2021
5112a66
remove duplicate logic
TylerBarnes Mar 23, 2021
9160d3b
remove unused import
TylerBarnes Mar 23, 2021
d5ef7ce
pass full error object to reporter.panic
TylerBarnes Mar 23, 2021
b72322d
Merge remote-tracking branch 'upstream/master' into fix/wp-schema-cus…
Mar 24, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -551,6 +551,62 @@ Array [
],
"name": "WpComment",
},
Object {
"fields": Array [
"databaseId",
"email",
"id",
"name",
"url",
"nodeType",
"parent",
"children",
"internal",
],
"name": "WpCommentAuthor",
},
Object {
"fields": Array [
"totalCount",
"edges",
"nodes",
"pageInfo",
"distinct",
"group",
],
"name": "WpCommentAuthorConnection",
},
Object {
"fields": Array [
"next",
"node",
"previous",
],
"name": "WpCommentAuthorEdge",
},
Object {
"fields": null,
"name": "WpCommentAuthorFieldsEnum",
},
Object {
"fields": null,
"name": "WpCommentAuthorFilterInput",
},
Object {
"fields": Array [
"totalCount",
"edges",
"nodes",
"pageInfo",
"field",
"fieldValue",
],
"name": "WpCommentAuthorGroupConnection",
},
Object {
"fields": null,
"name": "WpCommentAuthorSortInput",
},
Object {
"fields": Array [
"totalCount",
Expand Down
3 changes: 3 additions & 0 deletions integration-tests/gatsby-source-wordpress/gatsby-config.js
Expand Up @@ -48,6 +48,9 @@ const wpPluginOptions = !process.env.DEFAULT_PLUGIN_OPTIONS
`registeredDate`,
],
},
Commenter: {
excludeFieldNames: [`databaseId`],
},
Post: {
limit:
process.env.NODE_ENV === `development`
Expand Down
5 changes: 5 additions & 0 deletions integration-tests/gatsby-source-wordpress/src/pages/index.js
@@ -0,0 +1,5 @@
import React from "react"

export default function index() {
return <div>Index page</div>
}
Expand Up @@ -29,12 +29,10 @@ describe(`data resolution`, () => {
expect(data[`allWpPage`].totalCount).toBe(1)
expect(data[`allWpPost`].totalCount).toBe(1)
expect(data[`allWpComment`].totalCount).toBe(1)
// expect(data[`allWpProject`].totalCount).toBe(1)
expect(data[`allWpTaxonomy`].totalCount).toBe(3)
expect(data[`allWpCategory`].totalCount).toBe(9)
expect(data[`allWpMenu`].totalCount).toBe(1)
expect(data[`allWpMenuItem`].totalCount).toBe(4)
// expect(data[`allWpTeamMember`].totalCount).toBe(1)
expect(data[`allWpPostFormat`].totalCount).toBe(0)
expect(data[`allWpContentType`].totalCount).toBe(6)
})
Expand All @@ -53,6 +51,61 @@ describe(`data resolution`, () => {
},
})

it(`resolves node interfaces without errors`, async () => {
const query = /* GraphQL */ `
query {
allWpTermNode {
nodes {
id
}
}

allWpContentNode {
nodes {
id
}
}
}
`

// this will throw if there are gql errors
const gatsbyResult = await fetchGraphql({
url,
query,
})

expect(gatsbyResult.data.allWpTermNode.nodes.length).toBe(14)
expect(gatsbyResult.data.allWpContentNode.nodes.length).toBe(12)
})

it(`resolves interface fields which are a mix of Gatsby nodes and regular object data with no node`, async () => {
const query = /* GraphQL */ `
query {
wpPost(id: { eq: "cG9zdDox" }) {
id
comments {
nodes {
author {
# this is an interface of WpUser (Gatsby node type) and WpCommentAuthor (no node for this so needs to be fetched on the comment)
node {
name
}
}
}
}
}
}
`

// this will throw an error if there are gql errors
const gatsbyResult = await fetchGraphql({
url,
query,
})

expect(gatsbyResult.data.wpPost.comments.nodes.length).toBe(1)
})

it(`resolves hierarchichal categories`, async () => {
const gatsbyResult = await fetchGraphql({
url,
Expand Down
Expand Up @@ -29,10 +29,6 @@ const unionType = typeBuilderApi => {
name: buildTypeName(type.name),
types,
resolveType: node => {
if (node.type) {
return buildTypeName(node.type)
}

if (node.__typename) {
return buildTypeName(node.__typename)
}
Expand Down Expand Up @@ -104,7 +100,7 @@ const interfaceType = typeBuilderApi => {
} else {
// otherwise this is a regular interface type so we need to resolve the type name
typeDef.resolveType = node =>
node && node.__typename ? buildTypeName(node.__typename) : null
node?.__typename ? buildTypeName(node.__typename) : null
}

// @todo add this as a plugin option
Expand Down
Expand Up @@ -24,6 +24,10 @@ export const buildTypeName = name => {
name = `FilterType`
}

if (name.startsWith(prefix)) {
return name
}

return prefix + name
}

Expand Down
Expand Up @@ -5,6 +5,8 @@ import { fieldOfTypeWasFetched } from "./helpers"
import buildType from "./build-types"
import { getGatsbyNodeTypeNames } from "../source-nodes/fetch-nodes/fetch-nodes"
import { typeIsExcluded } from "~/steps/ingest-remote-schema/is-excluded"
import { formatLogMessage } from "../../utils/format-log-message"
import { CODES } from "../../utils/report"

/**
* createSchemaCustomization
Expand Down Expand Up @@ -96,7 +98,13 @@ const createSchemaCustomization = async api => {
try {
await customizeSchema(api)
} catch (e) {
api.reporter.panic(e)
api.reporter.panic({
id: CODES.SourcePluginCodeError,
error: e,
context: {
sourceMessage: formatLogMessage(e.message),
},
})
}
}

Expand Down
@@ -1,6 +1,7 @@
import { findTypeName } from "~/steps/create-schema-customization/helpers"

import { buildGatsbyNodeObjectResolver } from "~/steps/create-schema-customization/transform-fields/transform-object"
import { buildTypeName } from "../helpers"

export const buildDefaultResolver = transformerApi => (source, _, context) => {
const { fieldName, field, gatsbyNodeTypes } = transformerApi
Expand Down Expand Up @@ -45,6 +46,12 @@ export const buildDefaultResolver = transformerApi => (source, _, context) => {
finalFieldValue = aliasedField2
}

if (finalFieldValue?.__typename) {
// in Gatsby V3 this property is used to determine the type of an interface field
TylerBarnes marked this conversation as resolved.
Show resolved Hide resolved
// instead of the resolveType fn. This means we need to prefix it so that gql doesn't throw errors about missing types.
finalFieldValue.__typename = buildTypeName(finalFieldValue.__typename)
}

const isANodeConnection =
// if this field has just an id and typename
finalFieldValue?.id &&
Expand Down
Expand Up @@ -64,6 +64,12 @@ export const buildGatsbyNodeObjectResolver = ({ field, fieldName }) => async (

const queryInfo = getQueryInfoByTypeName(field.type.name)

if (!queryInfo) {
// if we don't have query info for a type
// it probably means this type is excluded in plugin options
return null
}

const isLazyMediaItem =
queryInfo.typeInfo.nodesTypeName === `MediaItem` &&
queryInfo.settings.lazyNodes
Expand Down
Expand Up @@ -16,12 +16,10 @@ export const transformUnion = ({ field, fieldName }) => {

if (gatsbyNode) {
return gatsbyNode
} else {
return null
}
}

return resolvedField
return resolvedField ?? null
},
}
}
Expand Down
Expand Up @@ -303,10 +303,10 @@ export function transformField({
const isAGatsbyNode =
// if this is a gatsby node type
gatsbyNodesInfo.typeNames.includes(typeName) ||
// or this type has a possible type which is a gatsby node type
// or all possible types on this type are Gatsby node types
typeMap
.get(typeName)
?.possibleTypes?.find(possibleType =>
?.possibleTypes?.every(possibleType =>
gatsbyNodesInfo.typeNames.includes(possibleType.name)
)

Expand Down
Expand Up @@ -48,13 +48,16 @@ export const createNodeWithSideEffects = ({
})
}

const builtTypename = buildTypeName(node.__typename)

let remoteNode = {
...node,
__typename: builtTypename,
id: node.id,
parent: null,
internal: {
contentDigest: createContentDigest(node),
type: type || buildTypeName(node.type),
type: type || builtTypename,
},
}

Expand Down