From c67d63c6ddbfdbf07617e6441597f400b9797b33 Mon Sep 17 00:00:00 2001 From: Alex Moon Date: Thu, 2 Dec 2021 20:18:36 -0800 Subject: [PATCH 1/9] fix: don't throw on warnings --- packages/gatsby-plugin-utils/src/validate.ts | 27 ++++-- .../src/bootstrap/load-plugins/validate.ts | 84 ++++++++++--------- 2 files changed, 64 insertions(+), 47 deletions(-) diff --git a/packages/gatsby-plugin-utils/src/validate.ts b/packages/gatsby-plugin-utils/src/validate.ts index 3493481b07d31..a752e71c32209 100644 --- a/packages/gatsby-plugin-utils/src/validate.ts +++ b/packages/gatsby-plugin-utils/src/validate.ts @@ -1,6 +1,7 @@ import { ValidationOptions } from "joi" import { ObjectSchema } from "./joi" import { IPluginInfoOptions } from "./types" +// import type { warning } "./utils/plugin-options-schema-joi-type const validationOptions: ValidationOptions = { // Show all errors at once, rather than only the first one every time @@ -10,6 +11,20 @@ const validationOptions: ValidationOptions = { interface IOptions { validateExternalRules?: boolean + returnWarnings?: boolean +} + +interface IValidateAsyncResult { + value: IPluginInfoOptions + warning: { + message: string + details: { + message: string + path: Array + type: string + context: Array> + } + } } export async function validateOptionsSchema( @@ -17,14 +32,14 @@ export async function validateOptionsSchema( pluginOptions: IPluginInfoOptions, options: IOptions = { validateExternalRules: true, + returnWarnings: true, } -): Promise { - const { validateExternalRules } = options +): Promise { + const { validateExternalRules, returnWarnings } = options - const value = await pluginSchema.validateAsync(pluginOptions, { + return pluginSchema.validateAsync(pluginOptions, { ...validationOptions, externals: validateExternalRules, - }) - - return value + warnings: returnWarnings, + }) as Promise } diff --git a/packages/gatsby/src/bootstrap/load-plugins/validate.ts b/packages/gatsby/src/bootstrap/load-plugins/validate.ts index b98c44ea0e6d8..2d0c4b4daeed9 100644 --- a/packages/gatsby/src/bootstrap/load-plugins/validate.ts +++ b/packages/gatsby/src/bootstrap/load-plugins/validate.ts @@ -282,6 +282,14 @@ async function validatePluginsOptions( }), }) + // If rootDir and plugin.parentDir are the same, i.e. if this is a plugin a user configured in their gatsby-config.js (and not a sub-theme that added it), this will be "" + // Otherwise, this will contain (and show) the relative path + const configDir = + (plugin.parentDir && + rootDir && + path.relative(rootDir, plugin.parentDir)) || + null + if (!Joi.isSchema(optionsSchema) || optionsSchema.type !== `object`) { // Validate correct usage of pluginOptionsSchema reporter.warn( @@ -300,11 +308,44 @@ async function validatePluginsOptions( }) } - plugin.options = await validateOptionsSchema( + optionsSchema = optionsSchema + .raw() + .pattern(/.*/, Joi.any().warning(`any.unknown`)) + + const { value, warning } = await validateOptionsSchema( optionsSchema, (plugin.options as IPluginInfoOptions) || {} ) + plugin.options = value + + // console.log("warnings: ", validationWarnings); + // Handle unknown key warnings + const validationWarnings = warning?.details || [] + + if (validationWarnings?.length > 0) { + reporter.warn( + stripIndent(` + Warning: there are unknown plugin options for "${plugin.resolve}"${ + configDir ? `, configured by ${configDir}` : `` + }: ${validationWarnings + .map(error => error.path.join(`.`)) + .join(`, `)} + Please open an issue at ghub.io/${ + plugin.resolve + } if you believe this option is valid. + `) + ) + trackCli(`UNKNOWN_PLUGIN_OPTION`, { + name: plugin.resolve, + valueString: validationWarnings + .map(error => error.path.join(`.`)) + .join(`, `), + }) + // 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) { const { errors: subErrors, plugins: subPlugins } = await validatePluginsOptions( @@ -322,21 +363,7 @@ async function validatePluginsOptions( } } catch (error) { if (error instanceof Joi.ValidationError) { - // Show a small warning on unknown options rather than erroring - const validationWarnings = error.details.filter( - err => err.type === `object.unknown` - ) - const validationErrors = error.details.filter( - err => err.type !== `object.unknown` - ) - - // If rootDir and plugin.parentDir are the same, i.e. if this is a plugin a user configured in their gatsby-config.js (and not a sub-theme that added it), this will be "" - // Otherwise, this will contain (and show) the relative path - const configDir = - (plugin.parentDir && - rootDir && - path.relative(rootDir, plugin.parentDir)) || - null + const validationErrors = error.details if (validationErrors.length > 0) { reporter.error({ id: `11331`, @@ -348,31 +375,6 @@ async function validatePluginsOptions( }) errors++ } - - if (validationWarnings.length > 0) { - reporter.warn( - stripIndent(` - Warning: there are unknown plugin options for "${ - plugin.resolve - }"${ - configDir ? `, configured by ${configDir}` : `` - }: ${validationWarnings - .map(error => error.path.join(`.`)) - .join(`, `)} - Please open an issue at ghub.io/${ - plugin.resolve - } if you believe this option is valid. - `) - ) - trackCli(`UNKNOWN_PLUGIN_OPTION`, { - name: plugin.resolve, - valueString: validationWarnings - .map(error => error.path.join(`.`)) - .join(`, `), - }) - // We do not increment errors++ here as we do not want to process.exit if there are only warnings - } - return plugin } From 1f1039af42b911720a1a3b8a35bfbcbfe55c2487 Mon Sep 17 00:00:00 2001 From: Alex Moon Date: Thu, 2 Dec 2021 20:49:20 -0800 Subject: [PATCH 2/9] fix: typings --- packages/gatsby-plugin-utils/src/validate.ts | 4 ++-- packages/gatsby/src/bootstrap/load-plugins/validate.ts | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/gatsby-plugin-utils/src/validate.ts b/packages/gatsby-plugin-utils/src/validate.ts index a752e71c32209..9474f9d220a25 100644 --- a/packages/gatsby-plugin-utils/src/validate.ts +++ b/packages/gatsby-plugin-utils/src/validate.ts @@ -18,12 +18,12 @@ interface IValidateAsyncResult { value: IPluginInfoOptions warning: { message: string - details: { + details: Array<{ message: string path: Array type: string context: Array> - } + }> } } diff --git a/packages/gatsby/src/bootstrap/load-plugins/validate.ts b/packages/gatsby/src/bootstrap/load-plugins/validate.ts index 2d0c4b4daeed9..eb0e6e12b64b1 100644 --- a/packages/gatsby/src/bootstrap/load-plugins/validate.ts +++ b/packages/gatsby/src/bootstrap/load-plugins/validate.ts @@ -319,9 +319,8 @@ async function validatePluginsOptions( plugin.options = value - // console.log("warnings: ", validationWarnings); // Handle unknown key warnings - const validationWarnings = warning?.details || [] + const validationWarnings = warning?.details if (validationWarnings?.length > 0) { reporter.warn( From 71ab32fb17dcc0adf2ab8d380f4492e0275cf59e Mon Sep 17 00:00:00 2001 From: Alex Moon Date: Thu, 2 Dec 2021 20:59:12 -0800 Subject: [PATCH 3/9] fix: more type fixes --- .../src/utils/plugin-options-schema-joi-type.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gatsby-plugin-utils/src/utils/plugin-options-schema-joi-type.ts b/packages/gatsby-plugin-utils/src/utils/plugin-options-schema-joi-type.ts index c9811a58dc7fe..4336ca3aba599 100644 --- a/packages/gatsby-plugin-utils/src/utils/plugin-options-schema-joi-type.ts +++ b/packages/gatsby-plugin-utils/src/utils/plugin-options-schema-joi-type.ts @@ -1160,7 +1160,7 @@ interface AnySchema extends SchemaInternals { * Warnings are reported separately from errors alongside the result value via the warning key (i.e. `{ value, warning }`). * Warning are always included when calling `any.validate()`. */ - warning(code: string, context: Context): this + warning(code: string, context?: Context): this /** * Converts the type into an alternatives type where the conditions are merged into the type definition where: From abc1dbc3a6b31464053a17db04e05714aa9779d0 Mon Sep 17 00:00:00 2001 From: Alex Moon Date: Thu, 2 Dec 2021 22:11:07 -0800 Subject: [PATCH 4/9] fix: tests and add correct test --- .../src/__tests__/__snapshots__/index.ts.snap | 21 +++++++++++++++++++ .../src/__tests__/index.ts | 21 ++++++++----------- packages/gatsby-plugin-utils/src/validate.ts | 8 +++++-- .../src/bootstrap/load-plugins/validate.ts | 4 ---- 4 files changed, 36 insertions(+), 18 deletions(-) create mode 100644 packages/gatsby-plugin-utils/src/__tests__/__snapshots__/index.ts.snap diff --git a/packages/gatsby-plugin-utils/src/__tests__/__snapshots__/index.ts.snap b/packages/gatsby-plugin-utils/src/__tests__/__snapshots__/index.ts.snap new file mode 100644 index 0000000000000..8066297719b1f --- /dev/null +++ b/packages/gatsby-plugin-utils/src/__tests__/__snapshots__/index.ts.snap @@ -0,0 +1,21 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`throws an warning on unknown values 1`] = ` +Object { + "details": Array [ + Object { + "context": Object { + "key": "notInSchema", + "label": "notInSchema", + "value": true, + }, + "message": "\\"notInSchema\\" is not allowed", + "path": Array [ + "notInSchema", + ], + "type": "any.unknown", + }, + ], + "message": "\\"notInSchema\\" is not allowed", +} +`; diff --git a/packages/gatsby-plugin-utils/src/__tests__/index.ts b/packages/gatsby-plugin-utils/src/__tests__/index.ts index e1c2e276ace0d..6dd620740eb81 100644 --- a/packages/gatsby-plugin-utils/src/__tests__/index.ts +++ b/packages/gatsby-plugin-utils/src/__tests__/index.ts @@ -9,9 +9,9 @@ it(`validates a basic schema`, async () => { const validOptions = { str: `is a string`, } - expect(await validateOptionsSchema(pluginSchema, validOptions)).toEqual( - validOptions - ) + + const { value } = await validateOptionsSchema(pluginSchema, validOptions) + expect(value).toEqual(validOptions) const invalid = () => validateOptionsSchema(pluginSchema, { @@ -56,18 +56,15 @@ it(`does not validate async external validation rules when validateExternalRules expect(invalid).not.toThrowError() }) -it(`throws an error on unknown values`, async () => { +it(`throws an warning on unknown values`, async () => { const schema = Joi.object({ str: Joi.string(), }) - const invalid = () => - validateOptionsSchema(schema, { - str: `bla`, - notInSchema: true, - }) + const { warning } = await validateOptionsSchema(schema, { + str: `bla`, + notInSchema: true, + }) - expect(invalid()).rejects.toThrowErrorMatchingInlineSnapshot( - `"\\"notInSchema\\" is not allowed"` - ) + expect(warning).toMatchSnapshot() }) diff --git a/packages/gatsby-plugin-utils/src/validate.ts b/packages/gatsby-plugin-utils/src/validate.ts index 9474f9d220a25..d43cf23ae8fbc 100644 --- a/packages/gatsby-plugin-utils/src/validate.ts +++ b/packages/gatsby-plugin-utils/src/validate.ts @@ -1,5 +1,5 @@ import { ValidationOptions } from "joi" -import { ObjectSchema } from "./joi" +import { ObjectSchema, Joi } from "./joi" import { IPluginInfoOptions } from "./types" // import type { warning } "./utils/plugin-options-schema-joi-type @@ -37,7 +37,11 @@ export async function validateOptionsSchema( ): Promise { const { validateExternalRules, returnWarnings } = options - return pluginSchema.validateAsync(pluginOptions, { + const warnOnUnknownSchema = pluginSchema + .raw() + .pattern(/.*/, Joi.any().warning(`any.unknown`)) + + return warnOnUnknownSchema.validateAsync(pluginOptions, { ...validationOptions, externals: validateExternalRules, warnings: returnWarnings, diff --git a/packages/gatsby/src/bootstrap/load-plugins/validate.ts b/packages/gatsby/src/bootstrap/load-plugins/validate.ts index eb0e6e12b64b1..f525e305a8707 100644 --- a/packages/gatsby/src/bootstrap/load-plugins/validate.ts +++ b/packages/gatsby/src/bootstrap/load-plugins/validate.ts @@ -308,10 +308,6 @@ async function validatePluginsOptions( }) } - optionsSchema = optionsSchema - .raw() - .pattern(/.*/, Joi.any().warning(`any.unknown`)) - const { value, warning } = await validateOptionsSchema( optionsSchema, (plugin.options as IPluginInfoOptions) || {} From 6e400d7399e25e6348ee2e11285b6b1fc99fa477 Mon Sep 17 00:00:00 2001 From: Alex Moon Date: Wed, 5 Jan 2022 16:10:47 -0800 Subject: [PATCH 5/9] tests: fix tests based on cahnges --- .../src/__tests__/gatsby-node.js | 16 ++++++---- .../src/__tests__/gatsby-node.js | 9 +++--- .../src/__tests__/gatsby-node.js | 13 ++++---- .../src/__tests__/gatsby-node.js | 10 ++++-- .../src/__tests__/options-validation.js | 32 +++++++++++-------- .../src/options-validation.js | 6 ++-- .../src/__tests__/gatsby-node.js | 15 ++++++--- .../src/test-plugin-options-schema.ts | 22 ++++++++++--- 8 files changed, 77 insertions(+), 46 deletions(-) diff --git a/packages/gatsby-plugin-cxs/src/__tests__/gatsby-node.js b/packages/gatsby-plugin-cxs/src/__tests__/gatsby-node.js index 8494980faf068..e04d2ef2d5b19 100644 --- a/packages/gatsby-plugin-cxs/src/__tests__/gatsby-node.js +++ b/packages/gatsby-plugin-cxs/src/__tests__/gatsby-node.js @@ -3,13 +3,17 @@ import { testPluginOptionsSchema } from "gatsby-plugin-utils" import { pluginOptionsSchema } from "../gatsby-node" it(`should provide meaningful errors when fields are invalid`, async () => { - const expectedErrors = [`"optionA" is not allowed`] + const expectedWarnings = [`"optionA" is not allowed`] - const { errors } = await testPluginOptionsSchema(pluginOptionsSchema, { - optionA: `This options shouldn't exist`, - }) - - expect(errors).toEqual(expectedErrors) + const { warnings, isValid, hasWarnings } = await testPluginOptionsSchema( + pluginOptionsSchema, + { + optionA: `This options shouldn't exist`, + } + ) + expect(isValid).toBe(true) + expect(hasWarnings).toBe(true) + expect(warnings).toEqual(expectedWarnings) }) it.each` diff --git a/packages/gatsby-plugin-flow/src/__tests__/gatsby-node.js b/packages/gatsby-plugin-flow/src/__tests__/gatsby-node.js index 85934bc8380de..0bbae52fea874 100644 --- a/packages/gatsby-plugin-flow/src/__tests__/gatsby-node.js +++ b/packages/gatsby-plugin-flow/src/__tests__/gatsby-node.js @@ -19,17 +19,18 @@ describe(`onCreateBabelConfig`, () => { describe(`pluginOptionsSchema`, () => { it(`should provide meaningful errors when fields are invalid`, async () => { - const expectedErrors = [`"optionA" is not allowed`] + const expectedWarnings = [`"optionA" is not allowed`] - const { isValid, errors } = await testPluginOptionsSchema( + const { isValid, warnings, hasWarnings } = await testPluginOptionsSchema( pluginOptionsSchema, { optionA: `This option shouldn't exist`, } ) - expect(isValid).toBe(false) - expect(errors).toEqual(expectedErrors) + expect(isValid).toBe(true) + expect(hasWarnings).toBe(true) + expect(warnings).toEqual(expectedWarnings) }) it.each` diff --git a/packages/gatsby-plugin-manifest/src/__tests__/gatsby-node.js b/packages/gatsby-plugin-manifest/src/__tests__/gatsby-node.js index e9d1b8087969a..8c8412159bd27 100644 --- a/packages/gatsby-plugin-manifest/src/__tests__/gatsby-node.js +++ b/packages/gatsby-plugin-manifest/src/__tests__/gatsby-node.js @@ -532,12 +532,11 @@ describe(`Test plugin manifest options`, () => { describe(`pluginOptionsSchema`, () => { it(`validates options correctly`, async () => { - expect(await testPluginOptionsSchema(pluginOptionsSchema, manifestOptions)) - .toMatchInlineSnapshot(` - Object { - "errors": Array [], - "isValid": true, - } - `) + const { isValid } = await testPluginOptionsSchema( + pluginOptionsSchema, + manifestOptions + ) + + expect(isValid).toBe(true) }) }) diff --git a/packages/gatsby-plugin-sass/src/__tests__/gatsby-node.js b/packages/gatsby-plugin-sass/src/__tests__/gatsby-node.js index 373fa2b35bb02..74a9e2554a293 100644 --- a/packages/gatsby-plugin-sass/src/__tests__/gatsby-node.js +++ b/packages/gatsby-plugin-sass/src/__tests__/gatsby-node.js @@ -170,10 +170,14 @@ describe(`pluginOptionsSchema`, () => { }) it(`should allow unknown options`, async () => { - const { isValid } = await testPluginOptionsSchema(pluginOptionsSchema, { - webpackImporter: `unknown option`, - }) + const { isValid, hasWarnings } = await testPluginOptionsSchema( + pluginOptionsSchema, + { + webpackImporter: `unknown option`, + } + ) expect(isValid).toBe(true) + expect(hasWarnings).toBe(true) }) }) diff --git a/packages/gatsby-plugin-sitemap/src/__tests__/options-validation.js b/packages/gatsby-plugin-sitemap/src/__tests__/options-validation.js index d83f199342f67..3d9da3b7c81ff 100644 --- a/packages/gatsby-plugin-sitemap/src/__tests__/options-validation.js +++ b/packages/gatsby-plugin-sitemap/src/__tests__/options-validation.js @@ -3,25 +3,31 @@ import { testPluginOptionsSchema, Joi } from "gatsby-plugin-utils" describe(`pluginOptionsSchema`, () => { it(`should provide meaningful errors when fields are invalid`, async () => { - const expectedErrors = [`"wrong" is not allowed`] + const expectedErrors = [`"output" must be a string`] - const { errors } = await testPluginOptionsSchema(pluginOptionsSchema, { - wrong: `test`, - }) + const { isValid, errors } = await testPluginOptionsSchema( + pluginOptionsSchema, + { + output: 123, + } + ) + expect(isValid).toBe(false) expect(errors).toEqual(expectedErrors) }) - it(`should provide error for deprecated "exclude" option`, async () => { - const expectedErrors = [ - `As of v4 the \`exclude\` option was renamed to \`excludes\``, - ] + it(`should provide warning for deprecated "exclude" option`, async () => { + const expectedWarnings = [`"exclude" is not allowed`] - const { errors } = await testPluginOptionsSchema(pluginOptionsSchema, { - exclude: [`test`], - }) + const { warnings, hasWarnings } = await testPluginOptionsSchema( + pluginOptionsSchema, + { + exclude: [`test`], + } + ) - expect(errors).toEqual(expectedErrors) + expect(hasWarnings).toBe(true) + expect(warnings).toEqual(expectedWarnings) }) it(`creates correct defaults`, async () => { @@ -48,7 +54,7 @@ describe(`pluginOptionsSchema`, () => { ${undefined} ${{}} `(`should validate the schema: $options`, async ({ options }) => { - const { isValid } = await testPluginOptionsSchema( + const { isValid, errors } = await testPluginOptionsSchema( pluginOptionsSchema, options ) diff --git a/packages/gatsby-plugin-sitemap/src/options-validation.js b/packages/gatsby-plugin-sitemap/src/options-validation.js index 4ebbdf319e081..66bdc13c87dfa 100644 --- a/packages/gatsby-plugin-sitemap/src/options-validation.js +++ b/packages/gatsby-plugin-sitemap/src/options-validation.js @@ -41,7 +41,8 @@ export const pluginOptionsSchema = ({ Joi }) => } }` ) - .external(({ query }) => { + .external(pluginOptions => { + const query = pluginOptions?.query if (query) { try { parseGraphql(query) @@ -74,9 +75,6 @@ export const pluginOptionsSchema = ({ Joi }) => enter other data types into this array for custom filtering. Doing so will require customization of the \`filterPages\` function.` ), - exclude: Joi.forbidden().messages({ - "any.unknown": `As of v4 the \`exclude\` option was renamed to \`excludes\``, - }), resolveSiteUrl: Joi.function() .default(() => resolveSiteUrl) .description( diff --git a/packages/gatsby-plugin-twitter/src/__tests__/gatsby-node.js b/packages/gatsby-plugin-twitter/src/__tests__/gatsby-node.js index 8494980faf068..e340053e76973 100644 --- a/packages/gatsby-plugin-twitter/src/__tests__/gatsby-node.js +++ b/packages/gatsby-plugin-twitter/src/__tests__/gatsby-node.js @@ -3,13 +3,18 @@ import { testPluginOptionsSchema } from "gatsby-plugin-utils" import { pluginOptionsSchema } from "../gatsby-node" it(`should provide meaningful errors when fields are invalid`, async () => { - const expectedErrors = [`"optionA" is not allowed`] + const expectedWarnings = [`"optionA" is not allowed`] - const { errors } = await testPluginOptionsSchema(pluginOptionsSchema, { - optionA: `This options shouldn't exist`, - }) + const { warnings, isValid, hasWarnings } = await testPluginOptionsSchema( + pluginOptionsSchema, + { + optionA: `This options shouldn't exist`, + } + ) - expect(errors).toEqual(expectedErrors) + expect(isValid).toBe(true) + expect(hasWarnings).toBe(true) + expect(warnings).toEqual(expectedWarnings) }) it.each` diff --git a/packages/gatsby-plugin-utils/src/test-plugin-options-schema.ts b/packages/gatsby-plugin-utils/src/test-plugin-options-schema.ts index edd0e259b939c..1ac306419e168 100644 --- a/packages/gatsby-plugin-utils/src/test-plugin-options-schema.ts +++ b/packages/gatsby-plugin-utils/src/test-plugin-options-schema.ts @@ -5,7 +5,9 @@ import { IPluginInfoOptions } from "./types" interface ITestPluginOptionsSchemaReturnType { errors: Array + warnings: Array isValid: boolean + hasWarnings: boolean } export async function testPluginOptionsSchema( @@ -44,11 +46,23 @@ export async function testPluginOptionsSchema( }) try { - await validateOptionsSchema(pluginSchema, pluginOptions) + const { warning } = await validateOptionsSchema(pluginSchema, pluginOptions) + + console.log(`warning`, warning) + const warnings = warning?.details?.map(detail => detail.message) ?? [] + + if (warnings?.length > 0) { + return { + isValid: true, + errors: [], + hasWarnings: true, + warnings, + } + } } catch (e) { - const errors = e.details.map(detail => detail.message) - return { isValid: false, errors } + const errors = e?.details?.map(detail => detail.message) ?? [] + return { isValid: false, errors, hasWarnings: false, warnings: [] } } - return { isValid: true, errors: [] } + return { isValid: true, errors: [], hasWarnings: false, warnings: [] } } From 3113e2951e66ec6bd500581e753bf618101e9ee7 Mon Sep 17 00:00:00 2001 From: Alex Moon Date: Thu, 6 Jan 2022 08:36:05 -0800 Subject: [PATCH 6/9] fix: resolve final test issues --- .../src/__tests__/__snapshots__/index.ts.snap | 21 ------------ .../src/__tests__/index.ts | 32 ++++++++++++++++--- packages/gatsby-plugin-utils/src/validate.ts | 12 +++---- 3 files changed, 34 insertions(+), 31 deletions(-) delete mode 100644 packages/gatsby-plugin-utils/src/__tests__/__snapshots__/index.ts.snap diff --git a/packages/gatsby-plugin-utils/src/__tests__/__snapshots__/index.ts.snap b/packages/gatsby-plugin-utils/src/__tests__/__snapshots__/index.ts.snap deleted file mode 100644 index 8066297719b1f..0000000000000 --- a/packages/gatsby-plugin-utils/src/__tests__/__snapshots__/index.ts.snap +++ /dev/null @@ -1,21 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`throws an warning on unknown values 1`] = ` -Object { - "details": Array [ - Object { - "context": Object { - "key": "notInSchema", - "label": "notInSchema", - "value": true, - }, - "message": "\\"notInSchema\\" is not allowed", - "path": Array [ - "notInSchema", - ], - "type": "any.unknown", - }, - ], - "message": "\\"notInSchema\\" is not allowed", -} -`; diff --git a/packages/gatsby-plugin-utils/src/__tests__/index.ts b/packages/gatsby-plugin-utils/src/__tests__/index.ts index 6dd620740eb81..7b97c015cfdb9 100644 --- a/packages/gatsby-plugin-utils/src/__tests__/index.ts +++ b/packages/gatsby-plugin-utils/src/__tests__/index.ts @@ -1,5 +1,6 @@ /* eslint-disable @typescript-eslint/explicit-function-return-type */ import { validateOptionsSchema, Joi } from "../" +import { testPluginOptionsSchema } from "../test-plugin-options-schema" it(`validates a basic schema`, async () => { const pluginSchema = Joi.object({ @@ -61,10 +62,33 @@ it(`throws an warning on unknown values`, async () => { str: Joi.string(), }) - const { warning } = await validateOptionsSchema(schema, { - str: `bla`, - notInSchema: true, + const validWarnings = [`"notInSchema" is not allowed`] + + const { hasWarnings, warnings } = await testPluginOptionsSchema( + () => schema, + { + str: `bla`, + notInSchema: true, + } + ) + + expect(hasWarnings).toBe(true) + expect(warnings).toEqual(validWarnings) +}) + +it(`populates default values`, async () => { + const pluginSchema = Joi.object({ + str: Joi.string(), + default: Joi.string().default(`default`), }) - expect(warning).toMatchSnapshot() + const validOptions = { + str: `is a string`, + } + + const { value } = await validateOptionsSchema(pluginSchema, validOptions) + expect(value).toEqual({ + ...validOptions, + default: `default`, + }) }) diff --git a/packages/gatsby-plugin-utils/src/validate.ts b/packages/gatsby-plugin-utils/src/validate.ts index d43cf23ae8fbc..8be0e3c39fdcb 100644 --- a/packages/gatsby-plugin-utils/src/validate.ts +++ b/packages/gatsby-plugin-utils/src/validate.ts @@ -1,7 +1,6 @@ import { ValidationOptions } from "joi" import { ObjectSchema, Joi } from "./joi" import { IPluginInfoOptions } from "./types" -// import type { warning } "./utils/plugin-options-schema-joi-type const validationOptions: ValidationOptions = { // Show all errors at once, rather than only the first one every time @@ -37,13 +36,14 @@ export async function validateOptionsSchema( ): Promise { const { validateExternalRules, returnWarnings } = options - const warnOnUnknownSchema = pluginSchema - .raw() - .pattern(/.*/, Joi.any().warning(`any.unknown`)) + const warnOnUnknownSchema = pluginSchema.pattern( + /.*/, + Joi.any().warning(`any.unknown`) + ) - return warnOnUnknownSchema.validateAsync(pluginOptions, { + return (await warnOnUnknownSchema.validateAsync(pluginOptions, { ...validationOptions, externals: validateExternalRules, warnings: returnWarnings, - }) as Promise + })) as Promise } From 79cf7dd9028d21ae8a3af038028a783adfb78d8c Mon Sep 17 00:00:00 2001 From: Alex Moon Date: Wed, 12 Jan 2022 07:56:41 -0800 Subject: [PATCH 7/9] cleanup: remove test console.log --- packages/gatsby-plugin-utils/src/test-plugin-options-schema.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/gatsby-plugin-utils/src/test-plugin-options-schema.ts b/packages/gatsby-plugin-utils/src/test-plugin-options-schema.ts index 1ac306419e168..83a4c8777db00 100644 --- a/packages/gatsby-plugin-utils/src/test-plugin-options-schema.ts +++ b/packages/gatsby-plugin-utils/src/test-plugin-options-schema.ts @@ -48,7 +48,6 @@ export async function testPluginOptionsSchema( try { const { warning } = await validateOptionsSchema(pluginSchema, pluginOptions) - console.log(`warning`, warning) const warnings = warning?.details?.map(detail => detail.message) ?? [] if (warnings?.length > 0) { From effc95ab54fa0aa26ed2310f44b9c84520942b54 Mon Sep 17 00:00:00 2001 From: Alex Moon Date: Wed, 12 Jan 2022 07:58:32 -0800 Subject: [PATCH 8/9] add https to github link --- packages/gatsby/src/bootstrap/load-plugins/validate.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gatsby/src/bootstrap/load-plugins/validate.ts b/packages/gatsby/src/bootstrap/load-plugins/validate.ts index f525e305a8707..a66b44559759f 100644 --- a/packages/gatsby/src/bootstrap/load-plugins/validate.ts +++ b/packages/gatsby/src/bootstrap/load-plugins/validate.ts @@ -326,7 +326,7 @@ async function validatePluginsOptions( }: ${validationWarnings .map(error => error.path.join(`.`)) .join(`, `)} - Please open an issue at ghub.io/${ + Please open an issue at https://ghub.io/${ plugin.resolve } if you believe this option is valid. `) From 36fc3d4e6bcb0ccebdc9fc8ea43bff6a65dfda88 Mon Sep 17 00:00:00 2001 From: Alex Moon Date: Wed, 12 Jan 2022 11:04:10 -0800 Subject: [PATCH 9/9] test: fix incorect snapshot --- .../gatsby/src/bootstrap/load-plugins/__tests__/load-plugins.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gatsby/src/bootstrap/load-plugins/__tests__/load-plugins.ts b/packages/gatsby/src/bootstrap/load-plugins/__tests__/load-plugins.ts index 09203261f2ecc..192f457620b06 100644 --- a/packages/gatsby/src/bootstrap/load-plugins/__tests__/load-plugins.ts +++ b/packages/gatsby/src/bootstrap/load-plugins/__tests__/load-plugins.ts @@ -454,7 +454,7 @@ describe(`Load plugins`, () => { expect((reporter.warn as jest.Mock).mock.calls[0]).toMatchInlineSnapshot(` Array [ "Warning: there are unknown plugin options for \\"gatsby-plugin-google-analytics\\": doesThisExistInTheSchema - Please open an issue at ghub.io/gatsby-plugin-google-analytics if you believe this option is valid.", + Please open an issue at https://ghub.io/gatsby-plugin-google-analytics if you believe this option is valid.", ] `) expect(mockProcessExit).not.toHaveBeenCalled()