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/__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..5d658f0f06b10 --- /dev/null +++ b/packages/gatsby-cli/src/__tests__/handlers/__snapshots__/plugin-add.ts.snap @@ -0,0 +1,104 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`addPlugins gatsby-config.js should not write with no plugins 1`] = ` +"module.exports = { + siteMetadata: { + siteUrl: \`https://www.yourdomain.tld\`, + }, + plugins: [], +} +" +`; + +exports[`addPlugins 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[`addPlugins gatsby-config.js should write a single plugin 1`] = ` +"module.exports = { + siteMetadata: { + siteUrl: \`https://www.yourdomain.tld\` + }, + plugins: [\\"gatsby-plugin-hello\\"] +};" +`; + +exports[`addPlugins gatsby-config.js should write multiple plugins 1`] = ` +"module.exports = { + siteMetadata: { + siteUrl: \`https://www.yourdomain.tld\` + }, + 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 new file mode 100644 index 0000000000000..74a26e33107ea --- /dev/null +++ b/packages/gatsby-cli/src/__tests__/handlers/plugin-add.ts @@ -0,0 +1,120 @@ +import { ensureDir, copyFile, readFile, rm } 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 + * 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 root = join(__dirname, `../../../../..`) +const fixtures = join(__dirname, `../fixtures`) +const config = { + js: { + starter: `${root}/starters/gatsby-starter-minimal/gatsby-config.js`, + fixture: `${fixtures}/gatsby-config.js`, + }, + ts: { + starter: `${root}/starters/gatsby-starter-minimal-ts/gatsby-config.ts`, + fixture: `${fixtures}/gatsby-config.ts`, + }, +} +const plugin = { + hello: `gatsby-plugin-hello`, + world: `gatsby-plugin-world`, +} + +describe(`addPlugins`, () => { + beforeAll(async () => { + await ensureDir(fixtures) + }) + + describe(`gatsby-config.js`, () => { + beforeEach(async () => { + await copyFile(config.js.starter, config.js.fixture) + }) + + afterEach(async () => { + await rm(config.js.fixture) + }) + + 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.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 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() + }) + }) + + describe.skip(`gatsby-config.ts`, () => { + beforeEach(async () => { + await copyFile(config.ts.starter, config.ts.fixture) + }) + + afterEach(async () => { + await rm(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.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 326f377619772..fd61a58d87a54 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. + // 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(`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 7ab57e5debe32..a8a3ae2331047 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,182 @@ 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 - - if (!isDefaultExport(left)) { - return - } - - 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 - } - ) - } - } - - path.stop() - }, - }, +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 + } + + 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, + }) + }) + } } } + +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. + * + * 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 default declare( + ( + api: ConfigAPI, + args: { + pluginOrThemeName: string + options: unknown + key: string + } + ): PluginObj => { + api.assertVersion(7) + + return { + visitor: { + /** + * 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 { + const { node } = path + if (!t.isAssignmentExpression(node.expression)) { + return + } + + const { left, right } = node.expression + if (!isDefaultExport(left) || !t.isObjectExpression(right)) { + return + } + + const pluginNodes = getPluginNodes(right.properties) + + 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 = getPluginNodes(config.properties) + + if ( + !t.isObjectProperty(pluginNodes) || + !t.isArrayExpression(pluginNodes.value) + ) { + return + } + + addPluginsToConfig({ pluginNodes, ...args }) + + path.stop() + }, + }, + } + } +) 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\\", 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/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 = ` diff --git a/starters/gatsby-starter-minimal-ts/gatsby-config.js b/starters/gatsby-starter-minimal-ts/gatsby-config.js index 14a259d1008f1..110cc039ac077 100644 --- a/starters/gatsby-starter-minimal-ts/gatsby-config.js +++ b/starters/gatsby-starter-minimal-ts/gatsby-config.js @@ -1,9 +1,7 @@ /** @type {import('gatsby').GatsbyConfig} */ module.exports = { siteMetadata: { - siteUrl: `https://www.yourdomain.tld`, + siteUrl: `https://www.yourdomain.tld`, }, - plugins: [ - - ] + plugins: [], } 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: [], +} 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"