Skip to content

Commit

Permalink
Merge branch 'master' of github.com:gatsbyjs/gatsby into ts-migration…
Browse files Browse the repository at this point in the history
…/merge-gatsby-config
  • Loading branch information
taejs committed May 12, 2020
2 parents eb09da2 + f5275a5 commit c5ad22e
Show file tree
Hide file tree
Showing 8 changed files with 123 additions and 3 deletions.
20 changes: 19 additions & 1 deletion docs/starters.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2984,7 +2984,7 @@
- Comment feature (disqus, utterances)
- Sponsor service (Buy-me-a-coffee)
- CLI Tool
- url: https://learn.hasura.io/graphql/react/introduction
- url: https://hasura.io/learn/graphql/react/introduction/
repo: https://github.com/hasura/gatsby-gitbook-starter
description: A starter to generate docs/tutorial websites based on GitBook theme.
tags:
Expand All @@ -3001,6 +3001,7 @@
- SEO Tags with MDX frontmatter
- Edit on GitHub button
- Fully Customisable with rich embeds using React in MDX.
- Search integration with Algolia
- url: https://gatsby-starter-blog-with-lunr.netlify.com/
repo: https://github.com/lukewhitehouse/gatsby-starter-blog-with-lunr
description: Building upon Gatsby's blog starter with a Lunr.js powered Site Search.
Expand Down Expand Up @@ -5412,11 +5413,15 @@
- CMS:Headless
- CMS:Contentful
- Portfolio
- PWA
- Testing
features:
- Styled components
- Responsive webpage
- Portfolio
- Blog
- Testing
- PWA
- url: https://example-site-for-square-starter.netlify.com/
repo: https://github.com/jonniebigodes/example-site-for-square-starter
description: A barebones starter to help you kickstart your next Gatsby project with Square payments
Expand Down Expand Up @@ -6177,6 +6182,19 @@
- Snipcart e-commerce starter
- Flotiq CMS as a product source
- Deploy to Heroku
- url: https://goodpraxis.coop
repo: https://github.com/GoodPraxis/gp-gatsby-starter-ts-sass-jest
description: A solid, basic Gatsby starter used by Good Praxis suitable for many different types of projects
tags:
- Language:TypeScript
- Styling:SCSS
- SEO
- Testing
features:
- TypeScript support
- SCSS for styling
- JEST tests
- Simple SEO setup
- url: https://gatsby-markdown-personal-website.netlify.app/
repo: https://github.com/SaimirKapaj/gatsby-markdown-personal-website
description: Gatsby Markdown Personal Website Starter, using Styled Components, Tailwindcss and Framer Motion.
Expand Down
1 change: 1 addition & 0 deletions packages/gatsby/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@
"json-stringify-safe": "^5.0.1",
"latest-version": "5.1.0",
"lodash": "^4.17.15",
"meant": "^1.0.1",
"md5": "^2.2.1",
"md5-file": "^3.2.3",
"micromatch": "^3.1.10",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ Array [
]
`;

exports[`Load plugins Loads plugins defined with an object but without an option key 1`] = `
exports[`Load plugins Loads plugins defined with an object but without an options key 1`] = `
Array [
Object {
"browserAPIs": Array [],
Expand Down Expand Up @@ -667,3 +667,5 @@ Array [
},
]
`;

exports[`Load plugins Throws an error when a plugin is defined with an option key 1`] = `"Plugin \\"___TEST___\\" has an \\"option\\" key in the configuration. Did you mean \\"options\\"?"`;
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ describe(`Load plugins`, () => {
expect(plugins).toMatchSnapshot()
})

it(`Loads plugins defined with an object but without an option key`, async () => {
it(`Loads plugins defined with an object but without an options key`, async () => {
const config = {
plugins: [
{
Expand All @@ -52,6 +52,26 @@ describe(`Load plugins`, () => {
expect(plugins).toMatchSnapshot()
})

it(`Throws an error when a plugin is defined with an option key`, async () => {
expect.assertions(1)
const config = {
plugins: [
{
resolve: `___TEST___`,
option: {
test: true,
},
},
],
}

try {
await loadPlugins(config)
} catch (err) {
expect(err.message).toMatchSnapshot()
}
})

it(`Overrides the options for gatsby-plugin-page-creator`, async () => {
const config = {
plugins: [
Expand Down
7 changes: 7 additions & 0 deletions packages/gatsby/src/bootstrap/load-plugins/load.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,13 @@ const loadPlugins = (config = {}, rootDir = null) => {
} else {
plugin.options = plugin.options || {}

// Throw an error if there is an "option" key.
if (_.isEmpty(plugin.options) && !_.isEmpty(plugin.option)) {
throw new Error(
`Plugin "${plugin.resolve}" has an "option" key in the configuration. Did you mean "options"?`
)
}

// Plugins can have plugins.
const subplugins = []
if (plugin.options.plugins) {
Expand Down
13 changes: 13 additions & 0 deletions packages/gatsby/src/redux/actions/__tests__/internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,17 @@ describe(`setSiteConfig`, () => {
const action = setSiteConfig({})
expect(action.payload.pathPrefix).toBe(``)
})

it(`It warns with a suggestion when an invalid key is passed`, () => {
setSiteConfig({
plugin: [],
})

expect(reporter.panic).toBeCalledWith({
id: `10122`,
context: {
sourceMessage: `"plugin" is not allowed. Did you mean "plugins"?`,
},
})
})
})
26 changes: 26 additions & 0 deletions packages/gatsby/src/redux/actions/internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
} from "../types"

import { gatsbyConfigSchema } from "../../joi-schemas/joi"
import { didYouMean } from "../../utils/did-you-mean"

/**
* Create a dependency between a page and data. Probably for
Expand Down Expand Up @@ -233,6 +234,31 @@ export const setSiteConfig = (config?: unknown): ISetSiteConfig => {
const normalizedPayload: IGatsbyConfig = result.value

if (result.error) {
const hasUnknownKeys = result.error.details.filter(
details => details.type === `object.allowUnknown`
)

if (Array.isArray(hasUnknownKeys) && hasUnknownKeys.length) {
const errorMessages = hasUnknownKeys.map(unknown => {
const { context, message } = unknown
const key = context?.key
const suggestion = key && didYouMean(key)

if (suggestion) {
return `${message}. ${suggestion}`
}

return message
})

reporter.panic({
id: `10122`,
context: {
sourceMessage: errorMessages.join(`\n`),
},
})
}

reporter.panic({
id: `10122`,
context: {
Expand Down
33 changes: 33 additions & 0 deletions packages/gatsby/src/utils/did-you-mean.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import meant from "meant"

export const KNOWN_CONFIG_KEYS = [
`__experimentalThemes`,
`polyfill`,
`assetPrefix`,
`pathPrefix`,
`siteMetadata`,
`mapping`,
`plugins`,
`proxy`,
`developMiddleware`,
]

export function didYouMean(
configKey: string,
commands: string[] = KNOWN_CONFIG_KEYS
): string {
const bestSimilarity = meant(configKey, commands)

if (bestSimilarity.length === 0) return ``
if (bestSimilarity.length === 1) {
return `Did you mean "${bestSimilarity[0]}"?`
} else {
return (
[`Did you mean one of these?`]
.concat(bestSimilarity.slice(0, 3))
.join(`\n`) + `\n`
)
}
}

export default didYouMean

0 comments on commit c5ad22e

Please sign in to comment.