diff --git a/packages/gatsby-plugin-netlify/package.json b/packages/gatsby-plugin-netlify/package.json index 686312f33191e..51215af6c172d 100644 --- a/packages/gatsby-plugin-netlify/package.json +++ b/packages/gatsby-plugin-netlify/package.json @@ -23,7 +23,8 @@ "@babel/cli": "^7.11.6", "@babel/core": "^7.11.6", "babel-preset-gatsby-package": "^0.5.3", - "cross-env": "^7.0.2" + "cross-env": "^7.0.2", + "gatsby-plugin-utils": "^0.2.27" }, "homepage": "https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-plugin-netlify#readme", "keywords": [ diff --git a/packages/gatsby-plugin-netlify/src/__tests__/gatsby-node.js b/packages/gatsby-plugin-netlify/src/__tests__/gatsby-node.js new file mode 100644 index 0000000000000..8eb6b9a55da8a --- /dev/null +++ b/packages/gatsby-plugin-netlify/src/__tests__/gatsby-node.js @@ -0,0 +1,45 @@ +import { testPluginOptionsSchema } from "gatsby-plugin-utils" +import { pluginOptionsSchema } from "../gatsby-node" + +describe(`gatsby-node.js`, () => { + it(`should provide meaningful errors when fields are invalid`, () => { + const expectedErrors = [ + `"headers" must be of type object`, + `"allPageHeaders" must be an array`, + `"mergeSecurityHeaders" must be a boolean`, + `"mergeLinkHeaders" must be a boolean`, + `"mergeCachingHeaders" must be a boolean`, + `"transformHeaders" must have an arity lesser or equal to 2`, + `"generateMatchPathRewrites" must be a boolean`, + ] + + const { errors } = testPluginOptionsSchema(pluginOptionsSchema, { + headers: `this should be an object`, + allPageHeaders: `this should be an array`, + mergeSecurityHeaders: `this should be a boolean`, + mergeLinkHeaders: `this should be a boolean`, + mergeCachingHeaders: `this should be a boolean`, + transformHeaders: (too, many, args) => ``, + generateMatchPathRewrites: `this should be a boolean`, + }) + + expect(errors).toEqual(expectedErrors) + }) + + it(`should validate the schema`, () => { + const { isValid } = testPluginOptionsSchema(pluginOptionsSchema, { + headers: { + "/some-page": [`Bearer: Some-Magic-Token`], + "/some-other-page": [`some`, `great`, `headers`], + }, + allPageHeaders: [`First header`, `Second header`], + mergeSecurityHeaders: true, + mergeLinkHeaders: false, + mergeCachingHeaders: true, + transformHeaders: () => null, + generateMatchPathRewrites: false, + }) + + expect(isValid).toBe(true) + }) +}) diff --git a/packages/gatsby-plugin-netlify/src/gatsby-node.js b/packages/gatsby-plugin-netlify/src/gatsby-node.js index 0aa878760a500..a4ec931517676 100644 --- a/packages/gatsby-plugin-netlify/src/gatsby-node.js +++ b/packages/gatsby-plugin-netlify/src/gatsby-node.js @@ -52,3 +52,39 @@ exports.onPostBuild = async ( createRedirects(pluginData, redirects, rewrites), ]) } + +const MATH_ALL_KEYS = /^/ +const pluginOptionsSchema = function ({ Joi }) { + // headers is a specific type used by Netlify: https://www.gatsbyjs.com/plugins/gatsby-plugin-netlify/#headers + const headersSchema = Joi.object() + .pattern(MATH_ALL_KEYS, Joi.array().items(Joi.string())) + .description(`Add more Netlify headers to specific pages`) + + return Joi.object({ + headers: headersSchema, + allPageHeaders: Joi.array() + .items(Joi.string()) + .description(`Add more headers to all the pages`), + mergeSecurityHeaders: Joi.boolean().description( + `When set to true, turns off the default security headers` + ), + mergeLinkHeaders: Joi.boolean().description( + `When set to true, turns off the default gatsby js headers` + ), + mergeCachingHeaders: Joi.boolean().description( + `When set to true, turns off the default caching headers` + ), + transformHeaders: Joi.function() + .maxArity(2) + .description( + `Transform function for manipulating headers under each path (e.g.sorting), etc. This should return an object of type: { key: Array }` + ), + generateMatchPathRewrites: Joi.boolean().description( + `When set to true, turns off automatic creation of redirect rules for client only paths` + ), + }) +} + +if (process.env.GATSBY_EXPERIMENTAL_PLUGIN_OPTION_VALIDATION) { + exports.pluginOptionsSchema = pluginOptionsSchema +}