Skip to content

Commit

Permalink
fix(gatsby): Validate sub plugins options (#37804)
Browse files Browse the repository at this point in the history
* fix(gatsby): validate sub plugins options of gatsby-plugin-mdx

* revert hardcoded path to subplugins

* validate subplugins if they are not under 'options.plugins' field

---------

Co-authored-by: Michal Piechowiak <misiek.piechowiak@gmail.com>
  • Loading branch information
Talaxy009 and pieh authored Mar 30, 2023
1 parent 3b482bf commit f013bc3
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,58 @@ describe(`Load plugins`, () => {
expect(mockProcessExit).toHaveBeenCalledWith(1)
})

it(`validates subplugin schemas (if not in options.plugins)`, async () => {
await loadPlugins(
{
plugins: [
{
resolve: `gatsby-plugin-mdx`,
options: {
gatsbyRemarkPlugins: [
{
resolve: `gatsby-remark-autolink-headers`,
options: {
maintainCase: `should be boolean`,
},
},
],
},
},
],
},
process.cwd()
)

expect(reporter.error as jest.Mock).toHaveBeenCalledTimes(1)
expect((reporter.error as jest.Mock).mock.calls[0])
.toMatchInlineSnapshot(`
Array [
Object {
"context": Object {
"configDir": null,
"pluginName": "gatsby-remark-autolink-headers",
"validationErrors": Array [
Object {
"context": Object {
"key": "maintainCase",
"label": "maintainCase",
"value": "should be boolean",
},
"message": "\\"maintainCase\\" must be a boolean",
"path": Array [
"maintainCase",
],
"type": "boolean.base",
},
],
},
"id": "11331",
},
]
`)
expect(mockProcessExit).toHaveBeenCalledWith(1)
})

it(`subplugins are resolved using "main" in package.json`, async () => {
// in fixtures/subplugins/node_modules/gatsby-plugin-child-with-main/package.json
// "main" field points to "lib/index.js"
Expand Down
49 changes: 28 additions & 21 deletions packages/gatsby/src/bootstrap/load-plugins/validate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,26 +181,25 @@ export async function handleBadExports({
}
}

interface ISubPluginCustomReturn {
resolve: string
modulePath: string
options: {
[key: string]: unknown
}
module: any
}
const addModuleImportAndValidateOptions =
(rootDir: string, incErrors: (inc: number) => void) =>
async (value: Array<IPluginRefObject>): Promise<Array<IPluginRefObject>> => {
for (const plugin of value) {
if (plugin.modulePath) {
const importedModule = await import(
maybeAddFileProtocol(plugin.modulePath)
)
const pluginModule = preferDefault(importedModule)
plugin.module = pluginModule
}
}

const addModuleImport = async (
value: Array<ISubPluginCustomReturn>
): Promise<Array<ISubPluginCustomReturn>> => {
for (const plugin of value) {
const importedModule = await import(maybeAddFileProtocol(plugin.modulePath))
const pluginModule = preferDefault(importedModule)
plugin.module = pluginModule
}
const { errors: subErrors, plugins: subPlugins } =
await validatePluginsOptions(value as Array<IPluginRefObject>, rootDir)

return value
}
incErrors(subErrors)
return subPlugins
}

async function validatePluginsOptions(
plugins: Array<IPluginRefObject>,
Expand Down Expand Up @@ -290,7 +289,15 @@ async function validatePluginsOptions(
})
}, `Gatsby specific subplugin validation`)
.default([])
.external(addModuleImport, `add module key to subplugin`),
.external(
addModuleImportAndValidateOptions(
rootDir,
(inc: number): void => {
errors += inc
}
),
`add module key to subplugin`
),
args: (schema: any, args: any): any => {
if (
args?.entry &&
Expand Down Expand Up @@ -364,8 +371,8 @@ async function validatePluginsOptions(
// We do not increment errors++ here as we do not want to process.exit if there are only warnings
}

// Validate subplugins
if (plugin.options?.plugins) {
// Validate subplugins if they weren't handled already
if (!subPluginPaths.has(`plugins`) && plugin.options?.plugins) {
const { errors: subErrors, plugins: subPlugins } =
await validatePluginsOptions(
plugin.options.plugins as Array<IPluginRefObject>,
Expand Down

0 comments on commit f013bc3

Please sign in to comment.