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): fix subplugin validation #27616

Merged
merged 13 commits into from
Oct 28, 2020
Merged

Conversation

mxstbr
Copy link
Contributor

@mxstbr mxstbr commented Oct 23, 2020

This (valid!) setup of gatsby-transformer-remark in gatsby-starter-blog:

    {
      resolve: `gatsby-transformer-remark`,
      options: {
        plugins: [
          {
            resolve: `gatsby-remark-images`,
            options: {
              maxWidth: 630,
            },
          },
          {
            resolve: `gatsby-remark-responsive-iframe`,
            options: {
              wrapperStyle: `margin-bottom: 1.0725rem`,
            },
          },
          `gatsby-remark-prismjs`,
          `gatsby-remark-copy-linked-files`,
          `gatsby-remark-smartypants`,
        ],
      },
    },

shows this error:

 ERROR #11331  PLUGIN

Invalid plugin options for "gatsby-transformer-remark":

- "plugins[0]" does not match any of the allowed types
- "plugins[1]" does not match any of the allowed types
- "plugins[2]" does not match any of the allowed types
- "plugins[3]" does not match any of the allowed types
- "plugins[4]" does not match any of the allowed types

However, the schema types this correctly, and in unit tests this configuration passes validation.

What our validation method does not account for is that Gatsby core adds more keys to the plugins array. When we try to validate it, it looks like this:

Click to see
{
  plugins: [
    {
      resolve: '/Users/mxstbr/projects/gatsbyjs/gatsby-starter-blog/node_modules/gatsby-remark-images',
      id: 'b5e9a088-5d85-5c5e-9368-bb3a9c7f3eb8',
      name: 'gatsby-remark-images',
      version: '3.3.36',
      pluginOptions: [Object],
      nodeAPIs: [Array],
      browserAPIs: [Array],
      ssrAPIs: []
    },
    {
      resolve: '/Users/mxstbr/projects/gatsbyjs/gatsby-starter-blog/node_modules/gatsby-remark-responsive-iframe',
      id: '1a3d9dbf-c3c7-50dc-9f59-97f0cf8bb163',
      name: 'gatsby-remark-responsive-iframe',
      version: '2.4.17',
      pluginOptions: [Object],
      nodeAPIs: [],
      browserAPIs: [],
      ssrAPIs: []
    },
    {
      resolve: '/Users/mxstbr/projects/gatsbyjs/gatsby-starter-blog/node_modules/gatsby-remark-prismjs',
      id: 'b8d3a2f5-5540-5699-b862-153e57b2c618',
      name: 'gatsby-remark-prismjs',
      version: '3.5.16',
      pluginOptions: [Object],
      nodeAPIs: [],
      browserAPIs: [],
      ssrAPIs: []
    },
    {
      resolve: '/Users/mxstbr/projects/gatsbyjs/gatsby-starter-blog/node_modules/gatsby-remark-copy-linked-files',
      id: '80533a5b-ad2d-50ff-af51-726674869458',
      name: 'gatsby-remark-copy-linked-files',
      version: '2.3.19',
      pluginOptions: [Object],
      nodeAPIs: [],
      browserAPIs: [],
      ssrAPIs: []
    },
    {
      resolve: '/Users/mxstbr/projects/gatsbyjs/gatsby-starter-blog/node_modules/gatsby-remark-smartypants',
      id: '90305615-131b-5991-a708-2c2d1c43d946',
      name: 'gatsby-remark-smartypants',
      version: '2.3.13',
      pluginOptions: [Object],
      nodeAPIs: [],
      browserAPIs: [],
      ssrAPIs: []
    }
  ]
}

As you can see, we add a lot of keys to the subplugins. However, we do not care about validating those as we only want to validate what the user actually specified (imagine getting a validation error on something that isn't even in your gatsby-config!).

To fix this, we now validate before "flattening" the plugins, which adds all those keys!

[ch17523]

@gatsbot gatsbot bot added the status: triage needed Issue or pull request that need to be triaged and assigned to a reviewer label Oct 23, 2020
@vladar vladar removed the status: triage needed Issue or pull request that need to be triaged and assigned to a reviewer label Oct 23, 2020
@mxstbr mxstbr requested a review from a team as a code owner October 24, 2020 14:03
@@ -233,15 +233,20 @@ export function loadPlugins(

// TypeScript support by default! use the user-provided one if it exists
const typescriptPlugin = (config.plugins || []).find(
plugin =>
(plugin as IPluginRefObject).resolve === `gatsby-plugin-typescript` ||
plugin === `gatsby-plugin-typescript`
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Note: removed the string case because plugin cannot be a string at this point anymore now that we normalize them ahead of time. TypeScript helpfully pointed that out to me!

@mxstbr mxstbr requested a review from a team October 24, 2020 15:33
)

if (typescriptPlugin === undefined) {
plugins.push(
processPlugin({
resolve: require.resolve(`gatsby-plugin-typescript`),
options: {
// TODO(@mxstbr): Do not hard-code these defaults but infer them from the
// pluginOptionsSchema of gatsby-plugin-typescript
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This doesn't have to happen for now, but would be a small cleanup in the future should we ever change the typescript plugins' defaults!

Copy link
Contributor

@wardpeet wardpeet left a comment

Choose a reason for hiding this comment

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

I've tested it on gatsby-starter-blog and it wasn't validating sub plugins.

@mxstbr
Copy link
Contributor Author

mxstbr commented Oct 27, 2020

Thanks Ward! Updated 👍

Copy link
Contributor

@wardpeet wardpeet left a comment

Choose a reason for hiding this comment

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

Looking good! I don't like that we make gatsby-transformer etc as a dev dep of gatsby. Pretty sure it will bite us in the future

Comment on lines +195 to +200
let optionsSchema = (gatsbyNode.pluginOptionsSchema as Exclude<
GatsbyNode["pluginOptionsSchema"],
undefined
>)({
Joi,
})
Copy link
Contributor

Choose a reason for hiding this comment

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

The fun parts of typescript 😂

Comment on lines 181 to 182
"gatsby-transformer-remark": "2.8.46",
"gatsby-remark-autolink-headers": "2.3.15",
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we have to do this? can't we mock these somehow? Feel free to rip out and do a follow up

Copy link
Contributor Author

@mxstbr mxstbr Oct 28, 2020

Choose a reason for hiding this comment

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

We currently have to do this for the tests, but I'm not sure we actually even need to add them as we require.resolve("${plugin}/gatsby-node") anyway. Let me test if it still works without them...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Works without them, removed! We should definitely mock these at some point, as currently the Gatsby tests depend on the shape of packages/(gatsby-transfomer-remark|gatsby-remark-autolink-headers)/gatsby-node.js, but this should be good enough for now 👍

Copy link
Contributor

@wardpeet wardpeet left a comment

Choose a reason for hiding this comment

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

LGTM!

@wardpeet wardpeet merged commit 65deab8 into master Oct 28, 2020
@wardpeet wardpeet deleted the fix-subplugin-options-schema branch October 28, 2020 12:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants