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

feat(gatsby-source-wordpress): allow path to js file for beforeChangeNode option #32901

Merged
merged 4 commits into from
Aug 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4380,6 +4380,7 @@ Array [
"title",
"uri",
"nodeType",
"beforeChangeNodeTest",
"parent",
"children",
"internal",
Expand Down Expand Up @@ -4596,6 +4597,7 @@ Array [
"toPing",
"uri",
"nodeType",
"beforeChangeNodeTest",
"parent",
"children",
"internal",
Expand Down
8 changes: 8 additions & 0 deletions integration-tests/gatsby-source-wordpress/gatsby-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ const wpPluginOptions = !process.env.DEFAULT_PLUGIN_OPTIONS
},
Page: {
excludeFieldNames: [`enclosure`],
beforeChangeNode: `./src/before-change-page.js`,
},
DatabaseIdentifier: {
exclude: true,
Expand All @@ -66,6 +67,13 @@ const wpPluginOptions = !process.env.DEFAULT_PLUGIN_OPTIONS
50
: // and we don't actually need more than 1000 in production
1000,

beforeChangeNode: ({ remoteNode }) => {
console.log(`Hi from an inline fn!`)
remoteNode.beforeChangeNodeTest = `TEST-${remoteNode.id}`

return remoteNode
},
},
// excluding this because it causes Gatsby to throw errors
BlockEditorContentNode: { exclude: true },
Expand Down
12 changes: 12 additions & 0 deletions integration-tests/gatsby-source-wordpress/gatsby-node.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
exports.createSchemaCustomization = ({ actions }) => {
const { createTypes } = actions
const typeDefs = `
type WpPage {
beforeChangeNodeTest: String
}
type WpPost {
beforeChangeNodeTest: String
}
`
createTypes(typeDefs)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = ({ remoteNode }) => {
remoteNode.beforeChangeNodeTest = `TEST-${remoteNode.id}`

return remoteNode
}
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,38 @@ describe(`data resolution`, () => {
expect(result.data.testUser.name).toEqual(`admin`)
})

it(`resolves data added via a fn file in onBeforeChangeNode type option`, async () => {
const result = await fetchGraphql({
url,
query: /* GraphQL */ `
{
# fn as a file path
allWpPage {
nodes {
id
beforeChangeNodeTest
}
}
# inline fn in gatsby-config.js
# support for this will be removed in future versions
allWpPost {
nodes {
id
beforeChangeNodeTest
}
}
}
`,
})

result.data.allWpPage.nodes.forEach(node => {
expect(node.beforeChangeNodeTest).toBe(`TEST-${node.id}`)
})
result.data.allWpPost.nodes.forEach(node => {
expect(node.beforeChangeNodeTest).toBe(`TEST-${node.id}`)
})
})

it(`resolves root fields`, async () => {
const result = await fetchGraphql({
url,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,14 @@ describe(`pluginOptionsSchema`, () => {
MenuItem: {
beforeChangeNode: null,
},
Page: {
beforeChangeNode: `./docs-generation.test.js`,
},
Post: {
beforeChangeNode: () => {
console.log(`Hi from an inline fn!`)
},
},
EnqueuedScript: {
exclude: true,
},
Expand Down
4 changes: 2 additions & 2 deletions packages/gatsby-source-wordpress/docs/plugin-options.md
Original file line number Diff line number Diff line change
Expand Up @@ -1107,9 +1107,9 @@ Determines whether or not this type will be treated as an interface comprised en

#### type.\_\_all.beforeChangeNode

A function which is invoked before a node is created, updated, or deleted. This is a hook in point to modify the node or perform side-effects related to it.
A function which is invoked before a node is created, updated, or deleted. This is a hook in point to modify the node or perform side-effects related to it. This option should be a path to a JS file where the default export is the beforeChangeNode function. The path can be relative to your gatsby-node.js or absolute. Currently you can inline a function by writing it out directly in this option but starting from Gatsby v4 only a path to a function file will work.
TylerBarnes marked this conversation as resolved.
Show resolved Hide resolved

**Field type**: `Function`
**Field type**: `String | Function`

### type.RootQuery

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,10 @@ function joiKeysToMD({
(value.meta && value.meta.find(meta => `trueType` in meta)) || {}

mdString += `\n\n`
mdString += `**Field type**: \`${_.startCase(trueType || value.type)}\``
mdString += `**Field type**: \`${(trueType || value.type)
.split(`|`)
.map(typename => _.startCase(typename))
.join(` | `)}\``
}

if (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,10 @@ const pluginOptionsSchema = ({ Joi }) => {
.allow(null)
.allow(false)
.meta({
trueType: `function`,
trueType: `string|function`,
})
.description(
`A function which is invoked before a node is created, updated, or deleted. This is a hook in point to modify the node or perform side-effects related to it.`
`A function which is invoked before a node is created, updated, or deleted. This is a hook in point to modify the node or perform side-effects related to it. This option should be a path to a JS file where the default export is the beforeChangeNode function. The path can be relative to your gatsby-node.js or absolute. Currently you can inline a function by writing it out directly in this option but starting from Gatsby v4 only a path to a function file will work.`
TylerBarnes marked this conversation as resolved.
Show resolved Hide resolved
),
})

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import path from "path"
import { formatLogMessage } from "~/utils/format-log-message"
import isInteger from "lodash/isInteger"
import { IPluginOptions } from "~/models/gatsby-api"
import { GatsbyNodeApiHelpers } from "~/utils/gatsby-types"
import { usingGatsbyV4OrGreater } from "~/utils/gatsby-version"
interface IProcessorOptions {
userPluginOptions: IPluginOptions
helpers: GatsbyNodeApiHelpers
Expand Down Expand Up @@ -46,6 +48,60 @@ const optionsProcessors: Array<IOptionsProcessor> = [

delete userPluginOptions.schema.queryDepth

return userPluginOptions
},
},
{
name: `Require beforeChangeNode type setting functions by absolute or relative path`,
test: ({ userPluginOptions }: IProcessorOptions): boolean =>
!!userPluginOptions?.type,
processor: ({
helpers,
userPluginOptions,
}: IProcessorOptions): IPluginOptions => {
const gatsbyStore = helpers.store.getState()
const typeSettings = Object.entries(userPluginOptions.type)

typeSettings.forEach(([typeName, settings]) => {
const beforeChangeNodePath = settings?.beforeChangeNode

if (
usingGatsbyV4OrGreater &&
typeof beforeChangeNodePath === `function`
) {
helpers.reporter.panic(
`Since Gatsby v4+ you cannot use the ${typeName}.beforeChangeNode option as a function. Please make the option a relative or absolute path to a JS file where the beforeChangeNode fn is the default export.`
)
}

if (!beforeChangeNodePath || typeof beforeChangeNodePath !== `string`) {
return
}

try {
const absoluteRequirePath: string | undefined = path.isAbsolute(
beforeChangeNodePath
)
? beforeChangeNodePath
: require.resolve(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wardpeet you mentioned gatsby-fs. Is that available now or will this need to be updated in the future?

path.join(gatsbyStore.program.directory, beforeChangeNodePath)
)

const beforeChangeNodeFn = require(absoluteRequirePath)

if (beforeChangeNodeFn) {
userPluginOptions.type[typeName].beforeChangeNode =
beforeChangeNodeFn
}
} catch (e) {
helpers.reporter.panic(
formatLogMessage(
`beforeChangeNode type setting for ${typeName} threw error:\n${e.message}`
)
)
}
})

return userPluginOptions
},
},
Expand Down
5 changes: 5 additions & 0 deletions packages/gatsby-source-wordpress/src/utils/gatsby-version.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import semver from "semver"
const gatsbyVersion = require(`gatsby/package.json`)?.version

// gt = greater than
export const usingGatsbyV4OrGreater = semver.gt(gatsbyVersion, `4.0.0`)