From 9a60b3e16011869c8a5d79c55c1bb6287d3dd1ba Mon Sep 17 00:00:00 2001 From: Ty Hopp Date: Thu, 3 Mar 2022 17:52:16 +0800 Subject: [PATCH 01/16] Make getConfigPath in gatsby-core-utils check for TS and JS gatsby-config files --- packages/gatsby-core-utils/src/utils.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/gatsby-core-utils/src/utils.ts b/packages/gatsby-core-utils/src/utils.ts index d748958dd5146..10369bca21002 100644 --- a/packages/gatsby-core-utils/src/utils.ts +++ b/packages/gatsby-core-utils/src/utils.ts @@ -1,14 +1,18 @@ import * as path from "path" -import * as fs from "fs-extra" +import { readFile, pathExistsSync } from "fs-extra" export function getConfigPath(root: string): string { - return path.join(root, `gatsby-config.js`) + const { js, ts } = { + js: path.join(root, `gatsby-config.js`), + ts: path.join(root, `gatsby-config.ts`), + } + return pathExistsSync(ts) ? ts : js } export async function readConfigFile(root: string): Promise { let src try { - src = await fs.readFile(getConfigPath(root), `utf8`) + src = await readFile(getConfigPath(root), `utf8`) } catch (e) { if (e.code === `ENOENT`) { src = ` From c9b705ab52b57ac864f9a72d45ae5734b3074637 Mon Sep 17 00:00:00 2001 From: tyhopp Date: Mon, 7 Mar 2022 17:22:58 +0800 Subject: [PATCH 02/16] Update minimal TS starter to use gatsby-config.ts --- starters/gatsby-starter-minimal-ts/gatsby-config.js | 9 --------- starters/gatsby-starter-minimal-ts/gatsby-config.ts | 10 ++++++++++ starters/gatsby-starter-minimal/gatsby-config.js | 12 +++++------- 3 files changed, 15 insertions(+), 16 deletions(-) delete mode 100644 starters/gatsby-starter-minimal-ts/gatsby-config.js create mode 100644 starters/gatsby-starter-minimal-ts/gatsby-config.ts diff --git a/starters/gatsby-starter-minimal-ts/gatsby-config.js b/starters/gatsby-starter-minimal-ts/gatsby-config.js deleted file mode 100644 index 14a259d1008f1..0000000000000 --- a/starters/gatsby-starter-minimal-ts/gatsby-config.js +++ /dev/null @@ -1,9 +0,0 @@ -/** @type {import('gatsby').GatsbyConfig} */ -module.exports = { - siteMetadata: { - siteUrl: `https://www.yourdomain.tld`, - }, - plugins: [ - - ] -} diff --git a/starters/gatsby-starter-minimal-ts/gatsby-config.ts b/starters/gatsby-starter-minimal-ts/gatsby-config.ts new file mode 100644 index 0000000000000..0b6ec608e947d --- /dev/null +++ b/starters/gatsby-starter-minimal-ts/gatsby-config.ts @@ -0,0 +1,10 @@ +import type { GatsbyConfig } from "gatsby" + +const config: GatsbyConfig = { + siteMetadata: { + siteUrl: `https://www.yourdomain.tld`, + }, + plugins: [], +} + +export default config diff --git a/starters/gatsby-starter-minimal/gatsby-config.js b/starters/gatsby-starter-minimal/gatsby-config.js index dc695b7488f9b..e5ace721d287b 100644 --- a/starters/gatsby-starter-minimal/gatsby-config.js +++ b/starters/gatsby-starter-minimal/gatsby-config.js @@ -1,8 +1,6 @@ module.exports = { - siteMetadata: { - siteUrl: `https://www.yourdomain.tld`, - }, - plugins: [ - - ] -} \ No newline at end of file + siteMetadata: { + siteUrl: `https://www.yourdomain.tld`, + }, + plugins: [], +} From f457430e904fc0581fe006eddc27bf536eb6cb00 Mon Sep 17 00:00:00 2001 From: tyhopp Date: Tue, 8 Mar 2022 11:47:16 +0800 Subject: [PATCH 03/16] Extract common babel plugin logic to func --- .../src/handlers/plugin-babel-utils.ts | 251 +++++++++--------- 1 file changed, 124 insertions(+), 127 deletions(-) diff --git a/packages/gatsby-cli/src/handlers/plugin-babel-utils.ts b/packages/gatsby-cli/src/handlers/plugin-babel-utils.ts index 7ab57e5debe32..d978c0e6022b2 100644 --- a/packages/gatsby-cli/src/handlers/plugin-babel-utils.ts +++ b/packages/gatsby-cli/src/handlers/plugin-babel-utils.ts @@ -2,6 +2,7 @@ import * as t from "@babel/types" import generate from "@babel/generator" import template from "@babel/template" import { declare } from "@babel/helper-plugin-utils" +import type { ConfigAPI, PluginObj } from "@babel/core" const getKeyNameFromAttribute = (node: any): any => node.key.name || node.key.value @@ -183,137 +184,133 @@ function buildPluginNode({ name, options, key }): any { return pluginWithOptions.declarations[0].init } -export class BabelPluginAddPluginsToGatsbyConfig { - constructor({ pluginOrThemeName, shouldAdd, options, key }) { - // @ts-ignore - fix me - this.plugin = declare(api => { - api.assertVersion(7) - - return { - visitor: { - ExpressionStatement(path): void { - const { node } = path - const { left, right } = node.expression +function addPluginsToConfig({ + pluginNodes, + pluginOrThemeName, + options, + key, +}): void { + if (t.isCallExpression(pluginNodes.value)) { + const plugins = pluginNodes.value.callee.object.elements.map(getPlugin) + const matches = plugins.filter(plugin => { + if (!key) { + return plugin.name === pluginOrThemeName + } - if (!isDefaultExport(left)) { - return - } + return plugin.key === key + }) - const pluginNodes = right.properties.find( - p => p.key.name === `plugins` - ) - - if (shouldAdd) { - if (t.isCallExpression(pluginNodes.value)) { - const plugins = - pluginNodes.value.callee.object.elements.map(getPlugin) - const matches = plugins.filter(plugin => { - if (!key) { - return plugin.name === pluginOrThemeName - } - - return plugin.key === key - }) - - if (!matches.length) { - const pluginNode = buildPluginNode({ - name: pluginOrThemeName, - options, - key, - }) - - pluginNodes.value.callee.object.elements.push(pluginNode) - } else { - pluginNodes.value.callee.object.elements = - pluginNodes.value.callee.object.elements.map(node => { - const plugin = getPlugin(node) - - if (plugin.key !== key) { - return node - } - - if (!plugin.key && plugin.name !== pluginOrThemeName) { - return node - } - - return buildPluginNode({ - name: pluginOrThemeName, - options, - key, - }) - }) - } - } else { - const plugins = pluginNodes.value.elements.map(getPlugin) - const matches = plugins.filter(plugin => { - if (!key) { - return plugin.name === pluginOrThemeName - } - - return plugin.key === key - }) - - if (!matches.length) { - const pluginNode = buildPluginNode({ - name: pluginOrThemeName, - options, - key, - }) - - pluginNodes.value.elements.push(pluginNode) - } else { - pluginNodes.value.elements = pluginNodes.value.elements.map( - node => { - const plugin = getPlugin(node) - - if (plugin.key !== key) { - return node - } - - if (!plugin.key && plugin.name !== pluginOrThemeName) { - return node - } - - return buildPluginNode({ - name: pluginOrThemeName, - options, - key, - }) - } - ) - } - } - } else { - if (t.isCallExpression(pluginNodes.value)) { - pluginNodes.value.callee.object.elements = - pluginNodes.value.callee.object.elements.filter(node => { - const plugin = getPlugin(node) - - if (key) { - return plugin.key !== key - } - - return plugin.name !== pluginOrThemeName - }) - } else { - pluginNodes.value.elements = pluginNodes.value.elements.filter( - node => { - const plugin = getPlugin(node) - - if (key) { - return plugin.key !== key - } - - return plugin.name !== pluginOrThemeName - } - ) - } - } + if (!matches.length) { + const pluginNode = buildPluginNode({ + name: pluginOrThemeName, + options, + key, + }) - path.stop() - }, - }, + pluginNodes.value.callee.object.elements.push(pluginNode) + } else { + pluginNodes.value.callee.object.elements = + pluginNodes.value.callee.object.elements.map(node => { + const plugin = getPlugin(node) + + if (plugin.key !== key) { + return node + } + + if (!plugin.key && plugin.name !== pluginOrThemeName) { + return node + } + + return buildPluginNode({ + name: pluginOrThemeName, + options, + key, + }) + }) + } + } else { + const plugins = pluginNodes.value.elements.map(getPlugin) + const matches = plugins.filter(plugin => { + if (!key) { + return plugin.name === pluginOrThemeName } + + return plugin.key === key }) + + if (!matches.length) { + const pluginNode = buildPluginNode({ + name: pluginOrThemeName, + options, + key, + }) + + pluginNodes.value.elements.push(pluginNode) + } else { + pluginNodes.value.elements = pluginNodes.value.elements.map(node => { + const plugin = getPlugin(node) + + if (plugin.key !== key) { + return node + } + + if (!plugin.key && plugin.name !== pluginOrThemeName) { + return node + } + + return buildPluginNode({ + name: pluginOrThemeName, + options, + key, + }) + }) + } } } + +export const BabelPluginAddPluginsToGatsbyConfig = declare( + function BabelPluginAddPluginsToGatsbyConfig( + api: ConfigAPI, + args: { + pluginOrThemeName: string + options: unknown + key: string + } + ): PluginObj { + api.assertVersion(7) + + return { + visitor: { + ExpressionStatement(path): void { + const { node } = path + if (!t.isAssignmentExpression(node.expression)) { + return + } + + const { left, right } = node.expression + if (!isDefaultExport(left) || !t.isObjectExpression(right)) { + return + } + + const pluginNodes = right.properties.find(prop => { + if (t.isObjectProperty(prop) && t.isIdentifier(prop.key)) { + return prop.key.name === `plugins` + } + return false + }) + + if ( + !t.isObjectProperty(pluginNodes) || + !t.isArrayExpression(pluginNodes.value) + ) { + return + } + + addPluginsToConfig({ pluginNodes, ...args }) + + path.stop() + }, + }, + } + } +) From 277916c805728e3fc607fb5c4dbe07d37640bb1e Mon Sep 17 00:00:00 2001 From: tyhopp Date: Tue, 8 Mar 2022 11:55:38 +0800 Subject: [PATCH 04/16] Add comments for context --- .../gatsby-cli/src/handlers/plugin-babel-utils.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/packages/gatsby-cli/src/handlers/plugin-babel-utils.ts b/packages/gatsby-cli/src/handlers/plugin-babel-utils.ts index d978c0e6022b2..4fb4d87265dc5 100644 --- a/packages/gatsby-cli/src/handlers/plugin-babel-utils.ts +++ b/packages/gatsby-cli/src/handlers/plugin-babel-utils.ts @@ -268,6 +268,16 @@ function addPluginsToConfig({ } } +/** + * Insert plugins selected in create-gatsby questionnaire into `gatsby-config` files. + * + * Scope is limited to the `gatsby-config` files in `gatsby-starter-minimal` and + * `gatsby-starter-minimal-ts`. Does not support general usage with other `gatsby-config` files. + * Changes to the config object in those files may require a change to this transformer. + * + * @see {@link https://github.com/gatsbyjs/gatsby/blob/master/starters/gatsby-starter-minimal/gatsby-config.js} + * @see {@link https://github.com/gatsbyjs/gatsby/blob/master/starters/gatsby-starter-minimal-ts/gatsby-config.ts} + */ export const BabelPluginAddPluginsToGatsbyConfig = declare( function BabelPluginAddPluginsToGatsbyConfig( api: ConfigAPI, @@ -281,6 +291,10 @@ export const BabelPluginAddPluginsToGatsbyConfig = declare( return { visitor: { + /** + * Handle `module.exports = { ..., plugins: [] }` `gatsby-config.js` in `gatsby-starter-minimal`. + * @see {@link https://github.com/gatsbyjs/gatsby/blob/master/starters/gatsby-starter-minimal/gatsby-config.js} + */ ExpressionStatement(path): void { const { node } = path if (!t.isAssignmentExpression(node.expression)) { From ceaa938d161b133aa660262de12b68d4c10bf6ea Mon Sep 17 00:00:00 2001 From: tyhopp Date: Tue, 8 Mar 2022 16:41:10 +0800 Subject: [PATCH 05/16] Make it work --- packages/gatsby-cli/package.json | 1 + .../src/handlers/plugin-add-utils.ts | 60 +++++-- .../gatsby-cli/src/handlers/plugin-add.ts | 2 +- .../src/handlers/plugin-babel-utils.ts | 54 +++++-- .../gatsby-core-utils/src/site-metadata.ts | 2 +- yarn.lock | 150 ++++++++++++++++++ 6 files changed, 240 insertions(+), 29 deletions(-) diff --git a/packages/gatsby-cli/package.json b/packages/gatsby-cli/package.json index 2aa7b92fc796a..2a21aba02f451 100644 --- a/packages/gatsby-cli/package.json +++ b/packages/gatsby-cli/package.json @@ -14,6 +14,7 @@ "@babel/core": "^7.15.5", "@babel/generator": "^7.16.8", "@babel/helper-plugin-utils": "^7.16.7", + "@babel/preset-typescript": "^7.16.7", "@babel/runtime": "^7.15.4", "@babel/template": "^7.16.7", "@babel/types": "^7.16.8", diff --git a/packages/gatsby-cli/src/handlers/plugin-add-utils.ts b/packages/gatsby-cli/src/handlers/plugin-add-utils.ts index 326f377619772..2b3284e5ece8b 100644 --- a/packages/gatsby-cli/src/handlers/plugin-add-utils.ts +++ b/packages/gatsby-cli/src/handlers/plugin-add-utils.ts @@ -7,11 +7,12 @@ import { getConfigPath, getConfigStore, } from "gatsby-core-utils" -import { transform } from "@babel/core" -import { BabelPluginAddPluginsToGatsbyConfig } from "./plugin-babel-utils" +import { transform, TransformOptions } from "@babel/core" +import BabelPluginAddPluginsToGatsbyConfig from "./plugin-babel-utils" const addPluginToConfig = ( src: string, + srcPath: string, { name, options, @@ -22,19 +23,41 @@ const addPluginToConfig = ( key: string } ): string => { - const addPlugins = new BabelPluginAddPluginsToGatsbyConfig({ - pluginOrThemeName: name, - options, - shouldAdd: true, - key, - }) + let code - // @ts-ignore - fix me - const { code } = transform(src, { - // @ts-ignore - fix me - plugins: [addPlugins.plugin], - configFile: false, - }) + try { + const transformOptions: TransformOptions = { + plugins: [ + [ + BabelPluginAddPluginsToGatsbyConfig, + { + pluginOrThemeName: name, + options, + key, + }, + ], + ], + filename: srcPath, + configFile: false, + } + + // Use the Babel TS preset if we're operating on `gatsby-config.ts` + if (srcPath.endsWith(`ts`)) { + transformOptions.presets = [`@babel/preset-typescript`] + } + + code = transform(src, transformOptions)?.code + + // Add back stripped type import, do light formatting, remove added empty module export + if (srcPath.endsWith(`ts`)) { + code = `import type { GatsbyConfig } from 'gatsby'\n\n${code}` + code = code.replace(/;/g, ``) + code = code.replace(`export {}`, ``) + code = code.replace(`export default config`, `\nexport default config`) + } + } catch (error) { + console.error(`Failed to transform gatsby config`, error) + } return code } @@ -53,10 +76,13 @@ export const GatsbyPluginCreate = async ({ key, }: IGatsbyPluginCreateInput): Promise => { const release = await lock(`gatsby-config.js`) + const configSrcPath = getConfigPath(root) const configSrc = await readConfigFile(root) - - const code = addPluginToConfig(configSrc, { name, options, key }) - + const code = addPluginToConfig(configSrc, configSrcPath, { + name, + options, + key, + }) await fs.writeFile(getConfigPath(root), code) release() } diff --git a/packages/gatsby-cli/src/handlers/plugin-add.ts b/packages/gatsby-cli/src/handlers/plugin-add.ts index 335dbf3cf1aed..c8e507a5dea1a 100644 --- a/packages/gatsby-cli/src/handlers/plugin-add.ts +++ b/packages/gatsby-cli/src/handlers/plugin-add.ts @@ -54,7 +54,7 @@ async function installPluginConfig( options, key: pluginKey, }) - reporter.info(`Installed ${pluginName || pluginKey} in gatsby-config.js`) + reporter.info(`Installed ${pluginName || pluginKey} in gatsby-config`) } catch (err) { reporter.error(JSON.parse(err)?.message) installTimer.setStatus(`FAILED`) diff --git a/packages/gatsby-cli/src/handlers/plugin-babel-utils.ts b/packages/gatsby-cli/src/handlers/plugin-babel-utils.ts index 4fb4d87265dc5..0e8e3c72353d1 100644 --- a/packages/gatsby-cli/src/handlers/plugin-babel-utils.ts +++ b/packages/gatsby-cli/src/handlers/plugin-babel-utils.ts @@ -278,21 +278,21 @@ function addPluginsToConfig({ * @see {@link https://github.com/gatsbyjs/gatsby/blob/master/starters/gatsby-starter-minimal/gatsby-config.js} * @see {@link https://github.com/gatsbyjs/gatsby/blob/master/starters/gatsby-starter-minimal-ts/gatsby-config.ts} */ -export const BabelPluginAddPluginsToGatsbyConfig = declare( - function BabelPluginAddPluginsToGatsbyConfig( +export default declare( + ( api: ConfigAPI, args: { pluginOrThemeName: string options: unknown key: string } - ): PluginObj { + ): PluginObj => { api.assertVersion(7) return { visitor: { /** - * Handle `module.exports = { ..., plugins: [] }` `gatsby-config.js` in `gatsby-starter-minimal`. + * Handle `module.exports = { ..., plugins: [] }` from `gatsby-config.js` in `gatsby-starter-minimal`. * @see {@link https://github.com/gatsbyjs/gatsby/blob/master/starters/gatsby-starter-minimal/gatsby-config.js} */ ExpressionStatement(path): void { @@ -306,12 +306,46 @@ export const BabelPluginAddPluginsToGatsbyConfig = declare( return } - const pluginNodes = right.properties.find(prop => { - if (t.isObjectProperty(prop) && t.isIdentifier(prop.key)) { - return prop.key.name === `plugins` - } - return false - }) + const pluginNodes = right.properties.find( + prop => + t.isObjectProperty(prop) && + t.isIdentifier(prop.key) && + prop.key.name === `plugins` + ) + + if ( + !t.isObjectProperty(pluginNodes) || + !t.isArrayExpression(pluginNodes.value) + ) { + return + } + + addPluginsToConfig({ pluginNodes, ...args }) + + path.stop() + }, + + /** + * Handle `const config = { ..., plugins: [] }; export default config` in `gatsby-config.ts` in `gatsby-starter-minimal-ts`. + * @see {@link https://github.com/gatsbyjs/gatsby/blob/master/starters/gatsby-starter-minimal-ts/gatsby-config.ts} + */ + VariableDeclaration(path): void { + const { node } = path + const configDeclaration = node.declarations.find( + dec => + t.isIdentifier(dec.id) && dec.id.name === `config` && dec.init + ) + const config = configDeclaration?.init + if (!t.isObjectExpression(config)) { + return + } + + const pluginNodes = config.properties.find( + prop => + t.isObjectProperty(prop) && + t.isIdentifier(prop.key) && + prop.key.name === `plugins` + ) if ( !t.isObjectProperty(pluginNodes) || diff --git a/packages/gatsby-core-utils/src/site-metadata.ts b/packages/gatsby-core-utils/src/site-metadata.ts index 85ceb07008f8b..687dab5682651 100644 --- a/packages/gatsby-core-utils/src/site-metadata.ts +++ b/packages/gatsby-core-utils/src/site-metadata.ts @@ -44,7 +44,7 @@ function addField( { name, value }: { name: string; value: string } ): string { const FIND = ` siteMetadata: {\n` - const REPLACE = ` siteMetadata: {\n ${name}: \`${value}\`,\n` + const REPLACE = ` siteMetadata: {\n ${name}: \`${value}\`,\n` const modifiedConfig = src.replace(FIND, REPLACE) return modifiedConfig } diff --git a/yarn.lock b/yarn.lock index fcda475cc5bb0..f90dd8042c9d7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -315,6 +315,15 @@ jsesc "^2.5.1" source-map "^0.5.0" +"@babel/generator@^7.17.3": + version "7.17.3" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.17.3.tgz#a2c30b0c4f89858cb87050c3ffdfd36bdf443200" + integrity sha512-+R6Dctil/MgUsZsZAkYgK+ADNSZzJRRy0TvY65T71z/CR854xHQ1EweBYXdfT+HNeN7w0cSJJEzgxZMv40pxsg== + dependencies: + "@babel/types" "^7.17.0" + jsesc "^2.5.1" + source-map "^0.5.0" + "@babel/helper-annotate-as-pure@^7.14.5", "@babel/helper-annotate-as-pure@^7.15.4": version "7.15.4" resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.15.4.tgz#3d0e43b00c5e49fdb6c57e421601a7a658d5f835" @@ -322,6 +331,13 @@ dependencies: "@babel/types" "^7.15.4" +"@babel/helper-annotate-as-pure@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz#bb2339a7534a9c128e3102024c60760a3a7f3862" + integrity sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw== + dependencies: + "@babel/types" "^7.16.7" + "@babel/helper-builder-binary-assignment-operator-visitor@^7.14.5": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.14.5.tgz#b939b43f8c37765443a19ae74ad8b15978e0a191" @@ -352,6 +368,19 @@ "@babel/helper-replace-supers" "^7.15.4" "@babel/helper-split-export-declaration" "^7.15.4" +"@babel/helper-create-class-features-plugin@^7.16.7": + version "7.17.6" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.17.6.tgz#3778c1ed09a7f3e65e6d6e0f6fbfcc53809d92c9" + integrity sha512-SogLLSxXm2OkBbSsHZMM4tUi8fUzjs63AT/d0YQIzr6GSd8Hxsbk2KYDX0k0DweAzGMj/YWeiCsorIdtdcW8Eg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.16.7" + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-function-name" "^7.16.7" + "@babel/helper-member-expression-to-functions" "^7.16.7" + "@babel/helper-optimise-call-expression" "^7.16.7" + "@babel/helper-replace-supers" "^7.16.7" + "@babel/helper-split-export-declaration" "^7.16.7" + "@babel/helper-create-regexp-features-plugin@^7.14.5": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.14.5.tgz#c7d5ac5e9cf621c26057722fb7a8a4c5889358c4" @@ -374,6 +403,13 @@ resolve "^1.14.2" semver "^6.1.2" +"@babel/helper-environment-visitor@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz#ff484094a839bde9d89cd63cba017d7aae80ecd7" + integrity sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag== + dependencies: + "@babel/types" "^7.16.7" + "@babel/helper-explode-assignable-expression@^7.14.5": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.14.5.tgz#8aa72e708205c7bb643e45c73b4386cdf2a1f645" @@ -397,6 +433,15 @@ "@babel/template" "^7.15.4" "@babel/types" "^7.15.4" +"@babel/helper-function-name@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz#f1ec51551fb1c8956bc8dd95f38523b6cf375f8f" + integrity sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA== + dependencies: + "@babel/helper-get-function-arity" "^7.16.7" + "@babel/template" "^7.16.7" + "@babel/types" "^7.16.7" + "@babel/helper-get-function-arity@^7.15.4": version "7.15.4" resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.15.4.tgz#098818934a137fce78b536a3e015864be1e2879b" @@ -404,6 +449,13 @@ dependencies: "@babel/types" "^7.15.4" +"@babel/helper-get-function-arity@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz#ea08ac753117a669f1508ba06ebcc49156387419" + integrity sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw== + dependencies: + "@babel/types" "^7.16.7" + "@babel/helper-hoist-variables@^7.15.4": version "7.15.4" resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.15.4.tgz#09993a3259c0e918f99d104261dfdfc033f178df" @@ -411,6 +463,13 @@ dependencies: "@babel/types" "^7.15.4" +"@babel/helper-hoist-variables@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz#86bcb19a77a509c7b77d0e22323ef588fa58c246" + integrity sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg== + dependencies: + "@babel/types" "^7.16.7" + "@babel/helper-member-expression-to-functions@^7.15.4": version "7.15.4" resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.4.tgz#bfd34dc9bba9824a4658b0317ec2fd571a51e6ef" @@ -418,6 +477,13 @@ dependencies: "@babel/types" "^7.15.4" +"@babel/helper-member-expression-to-functions@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.7.tgz#42b9ca4b2b200123c3b7e726b0ae5153924905b0" + integrity sha512-VtJ/65tYiU/6AbMTDwyoXGPKHgTsfRarivm+YbB5uAzKUyuPjgZSgAFeG87FCigc7KNHu2Pegh1XIT3lXjvz3Q== + dependencies: + "@babel/types" "^7.16.7" + "@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.0.0-beta.49", "@babel/helper-module-imports@^7.10.4", "@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.14.5", "@babel/helper-module-imports@^7.15.4": version "7.15.4" resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.15.4.tgz#e18007d230632dea19b47853b984476e7b4e103f" @@ -446,6 +512,13 @@ dependencies: "@babel/types" "^7.15.4" +"@babel/helper-optimise-call-expression@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.7.tgz#a34e3560605abbd31a18546bd2aad3e6d9a174f2" + integrity sha512-EtgBhg7rd/JcnpZFXpBy0ze1YRfdm7BnBX4uKMBd3ixa3RGAE002JZB66FJyNH7g0F38U05pXmA5P8cBh7z+1w== + dependencies: + "@babel/types" "^7.16.7" + "@babel/helper-plugin-test-runner@7.14.5": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/helper-plugin-test-runner/-/helper-plugin-test-runner-7.14.5.tgz#8b05e821e8694703f6cec2ef988cd3e31e38193d" @@ -482,6 +555,17 @@ "@babel/traverse" "^7.15.4" "@babel/types" "^7.15.4" +"@babel/helper-replace-supers@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.16.7.tgz#e9f5f5f32ac90429c1a4bdec0f231ef0c2838ab1" + integrity sha512-y9vsWilTNaVnVh6xiJfABzsNpgDPKev9HnAgz6Gb1p6UUwf9NepdlsV7VXGCftJM+jqD5f7JIEubcpLjZj5dBw== + dependencies: + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-member-expression-to-functions" "^7.16.7" + "@babel/helper-optimise-call-expression" "^7.16.7" + "@babel/traverse" "^7.16.7" + "@babel/types" "^7.16.7" + "@babel/helper-simple-access@^7.15.4": version "7.15.4" resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.15.4.tgz#ac368905abf1de8e9781434b635d8f8674bcc13b" @@ -503,6 +587,13 @@ dependencies: "@babel/types" "^7.15.4" +"@babel/helper-split-export-declaration@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz#0b648c0c42da9d3920d85ad585f2778620b8726b" + integrity sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw== + dependencies: + "@babel/types" "^7.16.7" + "@babel/helper-transform-fixture-test-runner@^7.14.5": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/helper-transform-fixture-test-runner/-/helper-transform-fixture-test-runner-7.14.5.tgz#e72b564e2bd79f5e39b35175c1240ef21b37b7ca" @@ -526,6 +617,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz#6e72a1fff18d5dfcb878e1e62f1a021c4b72d5a3" integrity sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow== +"@babel/helper-validator-option@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz#b203ce62ce5fe153899b617c08957de860de4d23" + integrity sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ== + "@babel/helper-wrap-function@^7.10.4", "@babel/helper-wrap-function@^7.15.4": version "7.15.4" resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.15.4.tgz#6f754b2446cfaf3d612523e6ab8d79c27c3a3de7" @@ -576,6 +672,11 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.16.8.tgz#61c243a3875f7d0b0962b0543a33ece6ff2f1f17" integrity sha512-i7jDUfrVBWc+7OKcBzEe5n7fbv3i2fWtxKzzCvOjnzSxMfWMigAhtfJ7qzZNGFNMsCCd67+uz553dYKWXPvCKw== +"@babel/parser@^7.17.3": + version "7.17.3" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.17.3.tgz#b07702b982990bf6fdc1da5049a23fece4c5c3d0" + integrity sha512-7yJPvPV+ESz2IUTPbOL+YkIGyCqOyNIzdguKQuJGnH7bg1WTIifuM21YqokFt/THWh1AkCRn9IgoykTRCBVpzA== + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.15.4": version "7.15.4" resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.15.4.tgz#dbdeabb1e80f622d9f0b583efb2999605e0a567e" @@ -993,6 +1094,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" +"@babel/plugin-syntax-typescript@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.7.tgz#39c9b55ee153151990fb038651d58d3fd03f98f8" + integrity sha512-YhUIJHHGkqPgEcMYkPCKTyGUdoGKWtopIycQyjJH8OjvRgOYsXsaKehLVPScKJWAULPxMa4N1vCe6szREFlZ7A== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-transform-arrow-functions@^7.14.5": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.14.5.tgz#f7187d9588a768dd080bf4c9ffe117ea62f7862a" @@ -1288,6 +1396,15 @@ "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-typescript" "^7.14.5" +"@babel/plugin-transform-typescript@^7.16.7": + version "7.16.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.16.8.tgz#591ce9b6b83504903fa9dd3652c357c2ba7a1ee0" + integrity sha512-bHdQ9k7YpBDO2d0NVfkj51DpQcvwIzIusJ7mEUaMlbZq3Kt/U47j24inXZHQ5MDiYpCs+oZiwnXyKedE8+q7AQ== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-syntax-typescript" "^7.16.7" + "@babel/plugin-transform-unicode-escapes@^7.14.5": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.14.5.tgz#9d4bd2a681e3c5d7acf4f57fa9e51175d91d0c6b" @@ -1436,6 +1553,15 @@ "@babel/helper-validator-option" "^7.14.5" "@babel/plugin-transform-typescript" "^7.15.0" +"@babel/preset-typescript@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.16.7.tgz#ab114d68bb2020afc069cd51b37ff98a046a70b9" + integrity sha512-WbVEmgXdIyvzB77AQjGBEyYPZx+8tTsO50XtfozQrkW8QB2rLJpH2lgx0TRw5EJrBxOZQ+wCcyPVQvS8tjEHpQ== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-validator-option" "^7.16.7" + "@babel/plugin-transform-typescript" "^7.16.7" + "@babel/register@^7.13.16", "@babel/register@^7.15.3": version "7.15.3" resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.15.3.tgz#6b40a549e06ec06c885b2ec42c3dd711f55fe752" @@ -1486,6 +1612,22 @@ debug "^4.1.0" globals "^11.1.0" +"@babel/traverse@^7.16.7": + version "7.17.3" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.17.3.tgz#0ae0f15b27d9a92ba1f2263358ea7c4e7db47b57" + integrity sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw== + dependencies: + "@babel/code-frame" "^7.16.7" + "@babel/generator" "^7.17.3" + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-function-name" "^7.16.7" + "@babel/helper-hoist-variables" "^7.16.7" + "@babel/helper-split-export-declaration" "^7.16.7" + "@babel/parser" "^7.17.3" + "@babel/types" "^7.17.0" + debug "^4.1.0" + globals "^11.1.0" + "@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49", "@babel/types@^7.10.5", "@babel/types@^7.12.1", "@babel/types@^7.12.7", "@babel/types@^7.14.5", "@babel/types@^7.14.9", "@babel/types@^7.15.4", "@babel/types@^7.16.7", "@babel/types@^7.16.8", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4": version "7.16.8" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.16.8.tgz#0ba5da91dd71e0a4e7781a30f22770831062e3c1" @@ -1494,6 +1636,14 @@ "@babel/helper-validator-identifier" "^7.16.7" to-fast-properties "^2.0.0" +"@babel/types@^7.17.0": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.17.0.tgz#a826e368bccb6b3d84acd76acad5c0d87342390b" + integrity sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw== + dependencies: + "@babel/helper-validator-identifier" "^7.16.7" + to-fast-properties "^2.0.0" + "@bcoe/v8-coverage@^0.2.3": version "0.2.3" resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" From 62c406e617e62b004e64345181fcef0e6768f952 Mon Sep 17 00:00:00 2001 From: tyhopp Date: Tue, 8 Mar 2022 17:05:24 +0800 Subject: [PATCH 06/16] DRY get plugin nodes --- .../src/handlers/plugin-babel-utils.ts | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/packages/gatsby-cli/src/handlers/plugin-babel-utils.ts b/packages/gatsby-cli/src/handlers/plugin-babel-utils.ts index 0e8e3c72353d1..a8a3ae2331047 100644 --- a/packages/gatsby-cli/src/handlers/plugin-babel-utils.ts +++ b/packages/gatsby-cli/src/handlers/plugin-babel-utils.ts @@ -268,6 +268,17 @@ function addPluginsToConfig({ } } +function getPluginNodes( + properties: Array +): t.ObjectProperty | undefined { + return properties.find( + prop => + t.isObjectProperty(prop) && + t.isIdentifier(prop.key) && + prop.key.name === `plugins` + ) as t.ObjectProperty +} + /** * Insert plugins selected in create-gatsby questionnaire into `gatsby-config` files. * @@ -306,12 +317,7 @@ export default declare( return } - const pluginNodes = right.properties.find( - prop => - t.isObjectProperty(prop) && - t.isIdentifier(prop.key) && - prop.key.name === `plugins` - ) + const pluginNodes = getPluginNodes(right.properties) if ( !t.isObjectProperty(pluginNodes) || @@ -340,12 +346,7 @@ export default declare( return } - const pluginNodes = config.properties.find( - prop => - t.isObjectProperty(prop) && - t.isIdentifier(prop.key) && - prop.key.name === `plugins` - ) + const pluginNodes = getPluginNodes(config.properties) if ( !t.isObjectProperty(pluginNodes) || From a26e0bd248ec5d0086d8fd4b92152a587147bfa6 Mon Sep 17 00:00:00 2001 From: tyhopp Date: Wed, 9 Mar 2022 10:07:47 +0800 Subject: [PATCH 07/16] Fix unit test --- .../gatsby-core-utils/src/__tests__/fixtures/gatsby-config.js | 2 +- packages/gatsby-core-utils/src/__tests__/site-metadata.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/gatsby-core-utils/src/__tests__/fixtures/gatsby-config.js b/packages/gatsby-core-utils/src/__tests__/fixtures/gatsby-config.js index 87167a8b25d0d..e6f4d869b46d1 100644 --- a/packages/gatsby-core-utils/src/__tests__/fixtures/gatsby-config.js +++ b/packages/gatsby-core-utils/src/__tests__/fixtures/gatsby-config.js @@ -1,6 +1,6 @@ module.exports = { siteMetadata: { - siteUrl: `https://www.yourdomain.tld`, + siteUrl: `https://www.yourdomain.tld`, }, plugins: [ "gatsby-transformer-remark", diff --git a/packages/gatsby-core-utils/src/__tests__/site-metadata.ts b/packages/gatsby-core-utils/src/__tests__/site-metadata.ts index e7658000a31a5..a796a1b13f95a 100644 --- a/packages/gatsby-core-utils/src/__tests__/site-metadata.ts +++ b/packages/gatsby-core-utils/src/__tests__/site-metadata.ts @@ -26,8 +26,8 @@ describe(`site-metadata`, () => { expect(writeFileMock.mock.calls[0][1]).toMatchInlineSnapshot(` "module.exports = { siteMetadata: { - title: \`Arrakis\`, - siteUrl: \`https://www.yourdomain.tld\`, + title: \`Arrakis\`, + siteUrl: \`https://www.yourdomain.tld\`, }, plugins: [ \\"gatsby-transformer-remark\\", From d04a1464d4d5148181d81045be89d10241499017 Mon Sep 17 00:00:00 2001 From: tyhopp Date: Wed, 9 Mar 2022 11:39:48 +0800 Subject: [PATCH 08/16] Test coverage for existing functionality --- .../handlers/__snapshots__/plugin-add.ts.snap | 43 +++++++++++++ .../src/__tests__/handlers/plugin-add.ts | 64 +++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 packages/gatsby-cli/src/__tests__/handlers/__snapshots__/plugin-add.ts.snap create mode 100644 packages/gatsby-cli/src/__tests__/handlers/plugin-add.ts diff --git a/packages/gatsby-cli/src/__tests__/handlers/__snapshots__/plugin-add.ts.snap b/packages/gatsby-cli/src/__tests__/handlers/__snapshots__/plugin-add.ts.snap new file mode 100644 index 0000000000000..3a4225ac7ab34 --- /dev/null +++ b/packages/gatsby-cli/src/__tests__/handlers/__snapshots__/plugin-add.ts.snap @@ -0,0 +1,43 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`installPlugins write to gatsby-config.js should not write with no plugins 1`] = ` +"module.exports = { + siteMetadata: { + siteUrl: \`https://www.yourdomain.tld\`, + }, + plugins: [], +} +" +`; + +exports[`installPlugins write to gatsby-config.js should write a plugin with options 1`] = ` +"module.exports = { + siteMetadata: { + siteUrl: \`https://www.yourdomain.tld\` + }, + plugins: [{ + resolve: 'gatsby-plugin-hello', + options: { + \\"greet\\": true + } + }] +};" +`; + +exports[`installPlugins write to gatsby-config.js should write a single plugin 1`] = ` +"module.exports = { + siteMetadata: { + siteUrl: \`https://www.yourdomain.tld\` + }, + plugins: [\\"gatsby-plugin-hello\\"] +};" +`; + +exports[`installPlugins write to gatsby-config.js should write multiple plugins 1`] = ` +"module.exports = { + siteMetadata: { + siteUrl: \`https://www.yourdomain.tld\` + }, + plugins: [\\"gatsby-plugin-hello\\", \\"gatsby-plugin-world\\"] +};" +`; diff --git a/packages/gatsby-cli/src/__tests__/handlers/plugin-add.ts b/packages/gatsby-cli/src/__tests__/handlers/plugin-add.ts new file mode 100644 index 0000000000000..255f6dfbf2eeb --- /dev/null +++ b/packages/gatsby-cli/src/__tests__/handlers/plugin-add.ts @@ -0,0 +1,64 @@ +import { copyFile, readFile, rm } from "fs/promises" +import { resolve } from "path" +import { addPlugins } from "../../handlers/plugin-add" + +/** + * Copy files from minimal starters instead of testing against static gatsby-configs + * in fixtues so that these break if we change the starter configs in the future. + */ + +const fixtures = resolve(`packages/gatsby-cli/src/__tests__/fixtures`) +const config = { + starter: resolve(`starters/gatsby-starter-minimal/gatsby-config`), + fixture: `${fixtures}/gatsby-config`, +} +const plugin = { + hello: `gatsby-plugin-hello`, + world: `gatsby-plugin-world`, +} + +describe(`installPlugins write to gatsby-config.js`, () => { + beforeEach(async () => { + await copyFile( + resolve(`${config.starter}.js`), + resolve(`${config.fixture}.js`) + ) + }) + + afterEach(async () => { + await rm(resolve(`${config.fixture}.js`)) + }) + + it(`should not write with no plugins`, async () => { + await addPlugins([], {}, fixtures, []) + const gatsbyConfig = (await readFile(`${config.fixture}.js`)).toString() + expect(gatsbyConfig).toMatchSnapshot() + }) + + it(`should write a single plugin`, async () => { + await addPlugins([plugin.hello], {}, fixtures, []) + const gatsbyConfig = (await readFile(`${config.fixture}.js`)).toString() + expect(gatsbyConfig).toMatchSnapshot() + }) + + it(`should write multiple plugins`, async () => { + await addPlugins([plugin.hello, plugin.world], {}, fixtures, []) + const gatsbyConfig = (await readFile(`${config.fixture}.js`)).toString() + expect(gatsbyConfig).toMatchSnapshot() + }) + + it(`should write a plugin with options`, async () => { + await addPlugins( + [plugin.hello], + { + [plugin.hello]: { + greet: true, + }, + }, + fixtures, + [] + ) + const gatsbyConfig = (await readFile(`${config.fixture}.js`)).toString() + expect(gatsbyConfig).toMatchSnapshot() + }) +}) From 2fbde8416a56c5c51e493ab5e67744618d4c4130 Mon Sep 17 00:00:00 2001 From: tyhopp Date: Wed, 9 Mar 2022 11:55:59 +0800 Subject: [PATCH 09/16] Test coverage for TS config write --- .../handlers/__snapshots__/plugin-add.ts.snap | 69 +++++++++- .../src/__tests__/handlers/plugin-add.ts | 129 ++++++++++++------ .../src/handlers/plugin-add-utils.ts | 10 +- 3 files changed, 160 insertions(+), 48 deletions(-) diff --git a/packages/gatsby-cli/src/__tests__/handlers/__snapshots__/plugin-add.ts.snap b/packages/gatsby-cli/src/__tests__/handlers/__snapshots__/plugin-add.ts.snap index 3a4225ac7ab34..abe28168876c8 100644 --- a/packages/gatsby-cli/src/__tests__/handlers/__snapshots__/plugin-add.ts.snap +++ b/packages/gatsby-cli/src/__tests__/handlers/__snapshots__/plugin-add.ts.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`installPlugins write to gatsby-config.js should not write with no plugins 1`] = ` +exports[`addPlugins gatsby-config.js should not write with no plugins 1`] = ` "module.exports = { siteMetadata: { siteUrl: \`https://www.yourdomain.tld\`, @@ -10,7 +10,7 @@ exports[`installPlugins write to gatsby-config.js should not write with no plugi " `; -exports[`installPlugins write to gatsby-config.js should write a plugin with options 1`] = ` +exports[`addPlugins gatsby-config.js should write a plugin with options 1`] = ` "module.exports = { siteMetadata: { siteUrl: \`https://www.yourdomain.tld\` @@ -24,7 +24,7 @@ exports[`installPlugins write to gatsby-config.js should write a plugin with opt };" `; -exports[`installPlugins write to gatsby-config.js should write a single plugin 1`] = ` +exports[`addPlugins gatsby-config.js should write a single plugin 1`] = ` "module.exports = { siteMetadata: { siteUrl: \`https://www.yourdomain.tld\` @@ -33,7 +33,7 @@ exports[`installPlugins write to gatsby-config.js should write a single plugin 1 };" `; -exports[`installPlugins write to gatsby-config.js should write multiple plugins 1`] = ` +exports[`addPlugins gatsby-config.js should write multiple plugins 1`] = ` "module.exports = { siteMetadata: { siteUrl: \`https://www.yourdomain.tld\` @@ -41,3 +41,64 @@ exports[`installPlugins write to gatsby-config.js should write multiple plugins plugins: [\\"gatsby-plugin-hello\\", \\"gatsby-plugin-world\\"] };" `; + +exports[`addPlugins gatsby-config.ts should not write with no plugins 1`] = ` +"import type { GatsbyConfig } from \\"gatsby\\" + +const config: GatsbyConfig = { + siteMetadata: { + siteUrl: \`https://www.yourdomain.tld\`, + }, + plugins: [], +} + +export default config +" +`; + +exports[`addPlugins gatsby-config.ts should write a plugin with options 1`] = ` +"import type { GatsbyConfig } from 'gatsby;' + +const config: GatsbyConfig = { + siteMetadata: { + siteUrl: \`https://www.yourdomain.tld\` + }, + plugins: [{ + resolve: 'gatsby-plugin-hello', + options: { + \\"greet\\": true + } + }] +}; + +export default config; +" +`; + +exports[`addPlugins gatsby-config.ts should write a single plugin 1`] = ` +"import type { GatsbyConfig } from 'gatsby;' + +const config: GatsbyConfig = { + siteMetadata: { + siteUrl: \`https://www.yourdomain.tld\` + }, + plugins: [\\"gatsby-plugin-hello\\"] +}; + +export default config; +" +`; + +exports[`addPlugins gatsby-config.ts should write multiple plugins 1`] = ` +"import type { GatsbyConfig } from 'gatsby;' + +const config: GatsbyConfig = { + siteMetadata: { + siteUrl: \`https://www.yourdomain.tld\` + }, + plugins: [\\"gatsby-plugin-hello\\", \\"gatsby-plugin-world\\"] +}; + +export default config; +" +`; diff --git a/packages/gatsby-cli/src/__tests__/handlers/plugin-add.ts b/packages/gatsby-cli/src/__tests__/handlers/plugin-add.ts index 255f6dfbf2eeb..f20f511e0401c 100644 --- a/packages/gatsby-cli/src/__tests__/handlers/plugin-add.ts +++ b/packages/gatsby-cli/src/__tests__/handlers/plugin-add.ts @@ -4,61 +4,112 @@ import { addPlugins } from "../../handlers/plugin-add" /** * Copy files from minimal starters instead of testing against static gatsby-configs - * in fixtues so that these break if we change the starter configs in the future. + * in fixtues so that these break if we change the starter configs in a breaking way. + * + * Not using `jest.each` since I find that much harder to read and debug. + * @see {@link https://jestjs.io/docs/api#testeachtablename-fn-timeout} */ const fixtures = resolve(`packages/gatsby-cli/src/__tests__/fixtures`) const config = { - starter: resolve(`starters/gatsby-starter-minimal/gatsby-config`), - fixture: `${fixtures}/gatsby-config`, + js: { + starter: resolve(`starters/gatsby-starter-minimal/gatsby-config.js`), + fixture: `${fixtures}/gatsby-config.js`, + }, + ts: { + starter: resolve(`starters/gatsby-starter-minimal-ts/gatsby-config.ts`), + fixture: `${fixtures}/gatsby-config.ts`, + }, } const plugin = { hello: `gatsby-plugin-hello`, world: `gatsby-plugin-world`, } -describe(`installPlugins write to gatsby-config.js`, () => { - beforeEach(async () => { - await copyFile( - resolve(`${config.starter}.js`), - resolve(`${config.fixture}.js`) - ) - }) +describe(`addPlugins`, () => { + describe(`gatsby-config.js`, () => { + beforeEach(async () => { + await copyFile(resolve(config.js.starter), resolve(config.js.fixture)) + }) - afterEach(async () => { - await rm(resolve(`${config.fixture}.js`)) - }) + afterEach(async () => { + await rm(resolve(config.js.fixture)) + }) - it(`should not write with no plugins`, async () => { - await addPlugins([], {}, fixtures, []) - const gatsbyConfig = (await readFile(`${config.fixture}.js`)).toString() - expect(gatsbyConfig).toMatchSnapshot() - }) + it(`should not write with no plugins`, async () => { + await addPlugins([], {}, fixtures, []) + const gatsbyConfig = (await readFile(config.js.fixture)).toString() + expect(gatsbyConfig).toMatchSnapshot() + }) - it(`should write a single plugin`, async () => { - await addPlugins([plugin.hello], {}, fixtures, []) - const gatsbyConfig = (await readFile(`${config.fixture}.js`)).toString() - expect(gatsbyConfig).toMatchSnapshot() - }) + it(`should write a single plugin`, async () => { + await addPlugins([plugin.hello], {}, fixtures, []) + const gatsbyConfig = (await readFile(config.js.fixture)).toString() + expect(gatsbyConfig).toMatchSnapshot() + }) + + it(`should write multiple plugins`, async () => { + await addPlugins([plugin.hello, plugin.world], {}, fixtures, []) + const gatsbyConfig = (await readFile(config.js.fixture)).toString() + expect(gatsbyConfig).toMatchSnapshot() + }) - it(`should write multiple plugins`, async () => { - await addPlugins([plugin.hello, plugin.world], {}, fixtures, []) - const gatsbyConfig = (await readFile(`${config.fixture}.js`)).toString() - expect(gatsbyConfig).toMatchSnapshot() + it(`should write a plugin with options`, async () => { + await addPlugins( + [plugin.hello], + { + [plugin.hello]: { + greet: true, + }, + }, + fixtures, + [] + ) + const gatsbyConfig = (await readFile(config.js.fixture)).toString() + expect(gatsbyConfig).toMatchSnapshot() + }) }) - it(`should write a plugin with options`, async () => { - await addPlugins( - [plugin.hello], - { - [plugin.hello]: { - greet: true, + describe(`gatsby-config.ts`, () => { + beforeEach(async () => { + await copyFile(resolve(config.ts.starter), resolve(config.ts.fixture)) + }) + + afterEach(async () => { + await rm(resolve(config.ts.fixture)) + }) + + it(`should not write with no plugins`, async () => { + await addPlugins([], {}, fixtures, []) + const gatsbyConfig = (await readFile(config.ts.fixture)).toString() + expect(gatsbyConfig).toMatchSnapshot() + }) + + it(`should write a single plugin`, async () => { + await addPlugins([plugin.hello], {}, fixtures, []) + const gatsbyConfig = (await readFile(config.ts.fixture)).toString() + expect(gatsbyConfig).toMatchSnapshot() + }) + + it(`should write multiple plugins`, async () => { + await addPlugins([plugin.hello, plugin.world], {}, fixtures, []) + const gatsbyConfig = (await readFile(config.ts.fixture)).toString() + expect(gatsbyConfig).toMatchSnapshot() + }) + + it(`should write a plugin with options`, async () => { + await addPlugins( + [plugin.hello], + { + [plugin.hello]: { + greet: true, + }, }, - }, - fixtures, - [] - ) - const gatsbyConfig = (await readFile(`${config.fixture}.js`)).toString() - expect(gatsbyConfig).toMatchSnapshot() + fixtures, + [] + ) + const gatsbyConfig = (await readFile(config.ts.fixture)).toString() + expect(gatsbyConfig).toMatchSnapshot() + }) }) }) diff --git a/packages/gatsby-cli/src/handlers/plugin-add-utils.ts b/packages/gatsby-cli/src/handlers/plugin-add-utils.ts index 2b3284e5ece8b..1e193b459d169 100644 --- a/packages/gatsby-cli/src/handlers/plugin-add-utils.ts +++ b/packages/gatsby-cli/src/handlers/plugin-add-utils.ts @@ -48,12 +48,12 @@ const addPluginToConfig = ( code = transform(src, transformOptions)?.code - // Add back stripped type import, do light formatting, remove added empty module export + // Add back stripped type import, do light formatting, remove added empty module export. + // Use semicolon since Babel does that anyway, and we might as well be consistent. if (srcPath.endsWith(`ts`)) { - code = `import type { GatsbyConfig } from 'gatsby'\n\n${code}` - code = code.replace(/;/g, ``) - code = code.replace(`export {}`, ``) - code = code.replace(`export default config`, `\nexport default config`) + code = `import type { GatsbyConfig } from 'gatsby;'\n\n${code}` + code = code.replace(`export {};`, ``) + code = code.replace(`export default config;`, `\nexport default config;`) } } catch (error) { console.error(`Failed to transform gatsby config`, error) From 7ba5dfe3a0029e94fa32b89c07648544c7d8bf20 Mon Sep 17 00:00:00 2001 From: tyhopp Date: Wed, 9 Mar 2022 12:22:04 +0800 Subject: [PATCH 10/16] Use __dirname to make CI happy --- .../src/__tests__/handlers/plugin-add.ts | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/packages/gatsby-cli/src/__tests__/handlers/plugin-add.ts b/packages/gatsby-cli/src/__tests__/handlers/plugin-add.ts index f20f511e0401c..2f19162896d12 100644 --- a/packages/gatsby-cli/src/__tests__/handlers/plugin-add.ts +++ b/packages/gatsby-cli/src/__tests__/handlers/plugin-add.ts @@ -1,6 +1,6 @@ import { copyFile, readFile, rm } from "fs/promises" -import { resolve } from "path" import { addPlugins } from "../../handlers/plugin-add" +import { join } from "path" /** * Copy files from minimal starters instead of testing against static gatsby-configs @@ -10,14 +10,15 @@ import { addPlugins } from "../../handlers/plugin-add" * @see {@link https://jestjs.io/docs/api#testeachtablename-fn-timeout} */ -const fixtures = resolve(`packages/gatsby-cli/src/__tests__/fixtures`) +const root = join(__dirname, `../../../../..`) +const fixtures = join(__dirname, `../fixtures`) const config = { js: { - starter: resolve(`starters/gatsby-starter-minimal/gatsby-config.js`), + starter: `${root}/starters/gatsby-starter-minimal/gatsby-config.js`, fixture: `${fixtures}/gatsby-config.js`, }, ts: { - starter: resolve(`starters/gatsby-starter-minimal-ts/gatsby-config.ts`), + starter: `${root}/starters/gatsby-starter-minimal-ts/gatsby-config.ts`, fixture: `${fixtures}/gatsby-config.ts`, }, } @@ -29,11 +30,11 @@ const plugin = { describe(`addPlugins`, () => { describe(`gatsby-config.js`, () => { beforeEach(async () => { - await copyFile(resolve(config.js.starter), resolve(config.js.fixture)) + await copyFile(config.js.starter, config.js.fixture) }) afterEach(async () => { - await rm(resolve(config.js.fixture)) + await rm(config.js.fixture) }) it(`should not write with no plugins`, async () => { @@ -72,11 +73,11 @@ describe(`addPlugins`, () => { describe(`gatsby-config.ts`, () => { beforeEach(async () => { - await copyFile(resolve(config.ts.starter), resolve(config.ts.fixture)) + await copyFile(config.ts.starter, config.ts.fixture) }) afterEach(async () => { - await rm(resolve(config.ts.fixture)) + await rm(config.ts.fixture) }) it(`should not write with no plugins`, async () => { From 222444aaa72f81de83ed17861cdb8e2901c8f3db Mon Sep 17 00:00:00 2001 From: tyhopp Date: Wed, 9 Mar 2022 12:56:11 +0800 Subject: [PATCH 11/16] Ensure fixtures dir exists --- packages/gatsby-cli/src/__tests__/handlers/plugin-add.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/gatsby-cli/src/__tests__/handlers/plugin-add.ts b/packages/gatsby-cli/src/__tests__/handlers/plugin-add.ts index 2f19162896d12..4709e2e227dc8 100644 --- a/packages/gatsby-cli/src/__tests__/handlers/plugin-add.ts +++ b/packages/gatsby-cli/src/__tests__/handlers/plugin-add.ts @@ -1,6 +1,7 @@ import { copyFile, readFile, rm } from "fs/promises" -import { addPlugins } from "../../handlers/plugin-add" +import { ensureDir } from "fs-extra" import { join } from "path" +import { addPlugins } from "../../handlers/plugin-add" /** * Copy files from minimal starters instead of testing against static gatsby-configs @@ -28,6 +29,10 @@ const plugin = { } describe(`addPlugins`, () => { + beforeAll(async () => { + await ensureDir(fixtures) + }) + describe(`gatsby-config.js`, () => { beforeEach(async () => { await copyFile(config.js.starter, config.js.fixture) From 812c341b9c9bc92b55bf1b7e256cd933a146160b Mon Sep 17 00:00:00 2001 From: Ty Hopp Date: Fri, 11 Mar 2022 17:14:46 +0800 Subject: [PATCH 12/16] Fix type import string literal Co-authored-by: Lennart --- packages/gatsby-cli/src/handlers/plugin-add-utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gatsby-cli/src/handlers/plugin-add-utils.ts b/packages/gatsby-cli/src/handlers/plugin-add-utils.ts index 1e193b459d169..fd61a58d87a54 100644 --- a/packages/gatsby-cli/src/handlers/plugin-add-utils.ts +++ b/packages/gatsby-cli/src/handlers/plugin-add-utils.ts @@ -51,7 +51,7 @@ const addPluginToConfig = ( // Add back stripped type import, do light formatting, remove added empty module export. // Use semicolon since Babel does that anyway, and we might as well be consistent. if (srcPath.endsWith(`ts`)) { - code = `import type { GatsbyConfig } from 'gatsby;'\n\n${code}` + code = `import type { GatsbyConfig } from "gatsby";\n\n${code}` code = code.replace(`export {};`, ``) code = code.replace(`export default config;`, `\nexport default config;`) } From 7a6b6efb23f1378d972a504177cb48c1c8daab36 Mon Sep 17 00:00:00 2001 From: tyhopp Date: Fri, 11 Mar 2022 17:22:47 +0800 Subject: [PATCH 13/16] Update snapshot --- .../src/__tests__/handlers/__snapshots__/plugin-add.ts.snap | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/gatsby-cli/src/__tests__/handlers/__snapshots__/plugin-add.ts.snap b/packages/gatsby-cli/src/__tests__/handlers/__snapshots__/plugin-add.ts.snap index abe28168876c8..5d658f0f06b10 100644 --- a/packages/gatsby-cli/src/__tests__/handlers/__snapshots__/plugin-add.ts.snap +++ b/packages/gatsby-cli/src/__tests__/handlers/__snapshots__/plugin-add.ts.snap @@ -57,7 +57,7 @@ export default config `; exports[`addPlugins gatsby-config.ts should write a plugin with options 1`] = ` -"import type { GatsbyConfig } from 'gatsby;' +"import type { GatsbyConfig } from \\"gatsby\\"; const config: GatsbyConfig = { siteMetadata: { @@ -76,7 +76,7 @@ export default config; `; exports[`addPlugins gatsby-config.ts should write a single plugin 1`] = ` -"import type { GatsbyConfig } from 'gatsby;' +"import type { GatsbyConfig } from \\"gatsby\\"; const config: GatsbyConfig = { siteMetadata: { @@ -90,7 +90,7 @@ export default config; `; exports[`addPlugins gatsby-config.ts should write multiple plugins 1`] = ` -"import type { GatsbyConfig } from 'gatsby;' +"import type { GatsbyConfig } from \\"gatsby\\"; const config: GatsbyConfig = { siteMetadata: { From d85952d4de3a32d2fc5f0a6be80eb1e5f594136c Mon Sep 17 00:00:00 2001 From: tyhopp Date: Fri, 11 Mar 2022 17:23:31 +0800 Subject: [PATCH 14/16] Use fs-extra, not fs/promises --- packages/gatsby-cli/src/__tests__/handlers/plugin-add.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/gatsby-cli/src/__tests__/handlers/plugin-add.ts b/packages/gatsby-cli/src/__tests__/handlers/plugin-add.ts index 4709e2e227dc8..2c760f245416a 100644 --- a/packages/gatsby-cli/src/__tests__/handlers/plugin-add.ts +++ b/packages/gatsby-cli/src/__tests__/handlers/plugin-add.ts @@ -1,5 +1,4 @@ -import { copyFile, readFile, rm } from "fs/promises" -import { ensureDir } from "fs-extra" +import { ensureDir, copyFile, readFile, rm } from "fs-extra" import { join } from "path" import { addPlugins } from "../../handlers/plugin-add" From 1f8321ade42946b4f98c67c7ea2b9aa0a29947c2 Mon Sep 17 00:00:00 2001 From: tyhopp Date: Mon, 14 Mar 2022 16:44:06 +0800 Subject: [PATCH 15/16] Extract out starter gatsby-config.ts to #35128 --- packages/gatsby-cli/src/__tests__/handlers/plugin-add.ts | 2 +- starters/gatsby-starter-minimal-ts/gatsby-config.ts | 7 ++----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/packages/gatsby-cli/src/__tests__/handlers/plugin-add.ts b/packages/gatsby-cli/src/__tests__/handlers/plugin-add.ts index 2c760f245416a..74a26e33107ea 100644 --- a/packages/gatsby-cli/src/__tests__/handlers/plugin-add.ts +++ b/packages/gatsby-cli/src/__tests__/handlers/plugin-add.ts @@ -75,7 +75,7 @@ describe(`addPlugins`, () => { }) }) - describe(`gatsby-config.ts`, () => { + describe.skip(`gatsby-config.ts`, () => { beforeEach(async () => { await copyFile(config.ts.starter, config.ts.fixture) }) diff --git a/starters/gatsby-starter-minimal-ts/gatsby-config.ts b/starters/gatsby-starter-minimal-ts/gatsby-config.ts index 0b6ec608e947d..110cc039ac077 100644 --- a/starters/gatsby-starter-minimal-ts/gatsby-config.ts +++ b/starters/gatsby-starter-minimal-ts/gatsby-config.ts @@ -1,10 +1,7 @@ -import type { GatsbyConfig } from "gatsby" - -const config: GatsbyConfig = { +/** @type {import('gatsby').GatsbyConfig} */ +module.exports = { siteMetadata: { siteUrl: `https://www.yourdomain.tld`, }, plugins: [], } - -export default config From 084471ad10a00e200a494526e7da52328a560476 Mon Sep 17 00:00:00 2001 From: tyhopp Date: Mon, 14 Mar 2022 16:56:56 +0800 Subject: [PATCH 16/16] Actually make it a JS file --- .../{gatsby-config.ts => gatsby-config.js} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename starters/gatsby-starter-minimal-ts/{gatsby-config.ts => gatsby-config.js} (100%) diff --git a/starters/gatsby-starter-minimal-ts/gatsby-config.ts b/starters/gatsby-starter-minimal-ts/gatsby-config.js similarity index 100% rename from starters/gatsby-starter-minimal-ts/gatsby-config.ts rename to starters/gatsby-starter-minimal-ts/gatsby-config.js