diff --git a/.eslintignore b/.eslintignore
new file mode 100644
index 0000000000000..2a372e586f19d
--- /dev/null
+++ b/.eslintignore
@@ -0,0 +1,25 @@
+
+**/coverage/**
+**/node_modules/**
+bin/
+packages/*/dist/**
+packages/*/lib/**
+packages/*/scripts/**
+**/dist/*
+**/__testfixtures__/**
+**/__tests__/fixtures/**
+peril
+docs
+plop-templates
+starters
+www
+benchmarks
+e2e-tests
+examples
+integration-tests
+**/*.d.ts
+
+packages/*/*.js
+packages/gatsby-plugin-preload-fonts/prepare/*.js
+packages/gatsby-image/withIEPolyfill/index.js
+packages/gatsby/cache-dir/commonjs/**/*
diff --git a/.eslintrc.js b/.eslintrc.js
new file mode 100644
index 0000000000000..5f114f29efc5a
--- /dev/null
+++ b/.eslintrc.js
@@ -0,0 +1,130 @@
+const TSEslint = require("@typescript-eslint/eslint-plugin")
+
+module.exports = {
+ parser: "babel-eslint",
+ extends: [
+ "google",
+ "eslint:recommended",
+ "plugin:flowtype/recommended",
+ "plugin:react/recommended",
+ "prettier",
+ "prettier/flowtype",
+ "prettier/react",
+ ],
+ plugins: ["flowtype", "prettier", "react", "filenames"],
+ parserOptions: {
+ ecmaVersion: 2016,
+ sourceType: "module",
+ ecmaFeatures: {
+ jsx: true,
+ },
+ },
+ env: {
+ browser: true,
+ es6: true,
+ node: true,
+ jest: true,
+ },
+ globals: {
+ before: true,
+ after: true,
+ spyOn: true,
+ __PATH_PREFIX__: true,
+ __BASE_PATH__: true,
+ __ASSET_PREFIX__: true,
+ },
+ rules: {
+ "arrow-body-style": [
+ "error",
+ "as-needed",
+ { requireReturnForObjectLiteral: true },
+ ],
+ "no-unused-expressions": [
+ "error",
+ {
+ allowTaggedTemplates: true,
+ },
+ ],
+ "consistent-return": ["error"],
+ "filenames/match-regex": ["error", "^[a-z-\\d\\.]+$", true],
+ "no-console": "off",
+ "no-inner-declarations": "off",
+ "prettier/prettier": "error",
+ quotes: ["error", "backtick"],
+ "react/display-name": "off",
+ "react/jsx-key": "warn",
+ "react/no-unescaped-entities": "off",
+ "react/prop-types": "off",
+ "require-jsdoc": "off",
+ "valid-jsdoc": "off",
+ },
+ overrides: [
+ {
+ files: [
+ "packages/**/gatsby-browser.js",
+ "packages/gatsby/cache-dir/**/*",
+ ],
+ env: {
+ browser: true,
+ },
+ globals: {
+ ___loader: false,
+ ___emitter: false,
+ },
+ },
+ {
+ files: ["**/cypress/integration/**/*", "**/cypress/support/**/*"],
+ globals: {
+ cy: false,
+ Cypress: false,
+ },
+ },
+ {
+ files: ["*.ts", "*.tsx"],
+ parser: "@typescript-eslint/parser",
+ plugins: ["@typescript-eslint/eslint-plugin"],
+ rules: {
+ ...TSEslint.configs.recommended.rules,
+ // This rule ensures that typescript types do not have semicolons
+ // at the end of their lines, since our prettier setup is to have no semicolons
+ // e.g.,
+ // interface Foo {
+ // - baz: string;
+ // + baz: string
+ // }
+ "@typescript-eslint/member-delimiter-style": [
+ "error",
+ {
+ multiline: {
+ delimiter: "none",
+ },
+ },
+ ],
+ // This ensures all interfaces are named with an I as a prefix
+ // e.g.,
+ // interface IFoo {}
+ "@typescript-eslint/interface-name-prefix": [
+ "error",
+ { prefixWithI: "always" },
+ ],
+ "@typescript-eslint/no-empty-function": "off",
+ // This ensures that we always type the return type of functions
+ // a high level focus of our TS setup is typing fn inputs and outputs.
+ "@typescript-eslint/explicit-function-return-type": "error",
+ // This forces us to use interfaces over types aliases for object defintions.
+ // Type is still useful for opaque types
+ // e.g.,
+ // type UUID = string
+ "@typescript-eslint/consistent-type-definitions": [
+ "error",
+ "interface",
+ ],
+ },
+ },
+ ],
+ settings: {
+ react: {
+ version: "16.4.2",
+ },
+ },
+}
diff --git a/.eslintrc.json b/.eslintrc.json
deleted file mode 100644
index c953f88345f75..0000000000000
--- a/.eslintrc.json
+++ /dev/null
@@ -1,86 +0,0 @@
-{
- "parser": "babel-eslint",
- "extends": [
- "google",
- "eslint:recommended",
- "plugin:flowtype/recommended",
- "plugin:react/recommended",
- "prettier",
- "prettier/flowtype",
- "prettier/react"
- ],
- "plugins": ["flowtype", "prettier", "react", "filenames"],
- "parserOptions": {
- "ecmaVersion": 2016,
- "sourceType": "module",
- "ecmaFeatures": {
- "jsx": true
- }
- },
- "env": {
- "browser": true,
- "es6": true,
- "node": true,
- "jest": true
- },
- "globals": {
- "before": true,
- "after": true,
- "spyOn": true,
- "__PATH_PREFIX__": true,
- "__BASE_PATH__": true,
- "__ASSET_PREFIX__": true
- },
- "rules": {
- "arrow-body-style": [
- "error",
- "as-needed",
- { "requireReturnForObjectLiteral": true }
- ],
- "no-unused-expressions": [
- "error",
- {
- "allowTaggedTemplates": true
- }
- ],
- "consistent-return": ["error"],
- "filenames/match-regex": ["error", "^[a-z-\\d\\.]+$", true],
- "no-console": "off",
- "no-inner-declarations": "off",
- "prettier/prettier": "error",
- "quotes": ["error", "backtick"],
- "react/display-name": "off",
- "react/jsx-key": "warn",
- "react/no-unescaped-entities": "off",
- "react/prop-types": "off",
- "require-jsdoc": "off",
- "valid-jsdoc": "off"
- },
- "overrides": [
- {
- "files": [
- "packages/**/gatsby-browser.js",
- "packages/gatsby/cache-dir/**/*"
- ],
- "env": {
- "browser": true
- },
- "globals": {
- "___loader": false,
- "___emitter": false
- }
- },
- {
- "files": ["**/cypress/integration/**/*", "**/cypress/support/**/*"],
- "globals": {
- "cy": false,
- "Cypress": false
- }
- }
- ],
- "settings": {
- "react": {
- "version": "16.4.2"
- }
- }
-}
diff --git a/.gitignore b/.gitignore
index 6811179d0d151..1336d6f4525fb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -52,6 +52,7 @@ node_modules/
# misc
.serverless/
+.eslintcache
# lock files
yarn.lock
diff --git a/package.json b/package.json
index 9ec23879ba7b5..257e58bfc7120 100644
--- a/package.json
+++ b/package.json
@@ -10,8 +10,8 @@
"@types/jest": "^24.0.23",
"@types/node": "^12.12.11",
"@types/webpack": "^4.41.0",
- "@typescript-eslint/eslint-plugin": "^2.11.0",
- "@typescript-eslint/parser": "^2.11.0",
+ "@typescript-eslint/eslint-plugin": "^2.12.0",
+ "@typescript-eslint/parser": "^2.12.0",
"babel-eslint": "^10.0.3",
"babel-jest": "^24.9.0",
"chalk": "^2.4.2",
@@ -62,7 +62,7 @@
"private": true,
"lint-staged": {
"*.{js,jsx}": [
- "eslint --ignore-path .gitignore --ignore-path .prettierignore --fix",
+ "eslint --cache --ext .js,.jsx,.ts,.tsx --fix",
"git add"
],
"*.{md,css,scss,yaml,yml}": [
@@ -94,7 +94,7 @@
"lerna": "lerna",
"lerna-prepare": "lerna run prepare",
"lint": "npm-run-all --continue-on-error -p lint:code lint:other",
- "lint:code": "eslint --ignore-path .gitignore --ignore-path .prettierignore --ext .js,.jsx .",
+ "lint:code": "eslint --cache --ext .js,.jsx,.ts,.tsx .",
"lint:scripts": "sh scripts/lint-shell-scripts.sh",
"lint:other": "npm run prettier -- --check",
"markdown": "md-magic --path \"starters/**/*.md\"",
diff --git a/packages/babel-preset-gatsby-package/__tests__/index.js b/packages/babel-preset-gatsby-package/__tests__/index.js
index 256fab822db0f..e6e692b62cf17 100644
--- a/packages/babel-preset-gatsby-package/__tests__/index.js
+++ b/packages/babel-preset-gatsby-package/__tests__/index.js
@@ -25,14 +25,16 @@ describe(`babel-preset-gatsby-package`, () => {
it(`can pass custom nodeVersion target`, () => {
process.env.BABEL_ENV = `production`
-
+
const nodeVersion = `6.0`
const { presets } = preset(null, {
- nodeVersion
+ nodeVersion,
})
- const [_, opts] = presets.find(preset => [].concat(preset).includes('@babel/preset-env'))
-
+ const [, opts] = presets.find(preset =>
+ [].concat(preset).includes(`@babel/preset-env`)
+ )
+
expect(opts.targets.node).toBe(nodeVersion)
})
})
diff --git a/packages/gatsby/cache-dir/__tests__/static-entry.js b/packages/gatsby/cache-dir/__tests__/static-entry.js
index 9149015bf2e7c..3b88e4d760e19 100644
--- a/packages/gatsby/cache-dir/__tests__/static-entry.js
+++ b/packages/gatsby/cache-dir/__tests__/static-entry.js
@@ -321,6 +321,7 @@ describe(`sanitizeComponents`, () => {
const sanitizedComponents = sanitizeComponents([
,
diff --git a/packages/gatsby/src/bootstrap/page-hot-reloader.js b/packages/gatsby/src/bootstrap/page-hot-reloader.js
index b3ac0d004dfd4..3e8ae7b980695 100644
--- a/packages/gatsby/src/bootstrap/page-hot-reloader.js
+++ b/packages/gatsby/src/bootstrap/page-hot-reloader.js
@@ -7,28 +7,6 @@ const report = require(`gatsby-cli/lib/reporter`)
let pagesDirty = false
let graphql
-emitter.on(`CREATE_NODE`, action => {
- if (action.payload.internal.type !== `SitePage`) {
- pagesDirty = true
- }
-})
-emitter.on(`DELETE_NODE`, action => {
- if (action.payload.internal.type !== `SitePage`) {
- pagesDirty = true
- // Make a fake API call to trigger `API_RUNNING_QUEUE_EMPTY` being called.
- // We don't want to call runCreatePages here as there might be work in
- // progress. So this is a safe way to make sure runCreatePages gets called
- // at a safe time.
- apiRunnerNode(`FAKE_API_CALL`)
- }
-})
-
-emitter.on(`API_RUNNING_QUEUE_EMPTY`, () => {
- if (pagesDirty) {
- runCreatePages()
- }
-})
-
const runCreatePages = async () => {
pagesDirty = false
@@ -65,4 +43,25 @@ const runCreatePages = async () => {
module.exports = graphqlRunner => {
graphql = graphqlRunner
+ emitter.on(`CREATE_NODE`, action => {
+ if (action.payload.internal.type !== `SitePage`) {
+ pagesDirty = true
+ }
+ })
+ emitter.on(`DELETE_NODE`, action => {
+ if (action.payload.internal.type !== `SitePage`) {
+ pagesDirty = true
+ // Make a fake API call to trigger `API_RUNNING_QUEUE_EMPTY` being called.
+ // We don't want to call runCreatePages here as there might be work in
+ // progress. So this is a safe way to make sure runCreatePages gets called
+ // at a safe time.
+ apiRunnerNode(`FAKE_API_CALL`)
+ }
+ })
+
+ emitter.on(`API_RUNNING_QUEUE_EMPTY`, () => {
+ if (pagesDirty) {
+ runCreatePages()
+ }
+ })
}
diff --git a/packages/gatsby/src/commands/develop.ts b/packages/gatsby/src/commands/develop.ts
index 514a7694e4599..9b0aba1d9aac3 100644
--- a/packages/gatsby/src/commands/develop.ts
+++ b/packages/gatsby/src/commands/develop.ts
@@ -3,6 +3,8 @@ import fs from "fs"
import openurl from "better-opn"
import chokidar from "chokidar"
+import webpackHotMiddleware from "webpack-hot-middleware"
+import webpackDevMiddleware from "webpack-dev-middleware"
import { PackageJson } from "gatsby"
import glob from "glob"
import express from "express"
@@ -30,6 +32,9 @@ import WorkerPool from "../utils/worker/pool"
import http from "http"
import https from "https"
+import bootstrapSchemaHotReloader from "../bootstrap/schema-hot-reloader"
+import bootstrapPageHotReloader from "../bootstrap/page-hot-reloader"
+import developStatic from "./develop-static"
import withResolverContext from "../schema/context"
import sourceNodes from "../utils/source-nodes"
import createSchemaCustomization from "../utils/create-schema-customization"
@@ -83,9 +88,9 @@ onExit(() => {
telemetry.trackCli(`DEVELOP_STOP`)
})
-const waitJobsFinished = () =>
+const waitJobsFinished = (): Promise =>
new Promise(resolve => {
- const onEndJob = () => {
+ const onEndJob = (): void => {
if (store.getState().jobs.active.length === 0) {
resolve()
emitter.off(`END_JOB`, onEndJob)
@@ -97,13 +102,19 @@ const waitJobsFinished = () =>
type ActivityTracker = any // TODO: Replace this with proper type once reporter is typed
-async function startServer(program: IProgram) {
+interface IServer {
+ compiler: webpack.Compiler
+ listener: http.Server | https.Server
+ webpackActivity: ActivityTracker
+}
+
+async function startServer(program: IProgram): Promise {
const indexHTMLActivity = report.phantomActivity(`building index.html`, {})
indexHTMLActivity.start()
const directory = program.directory
const directoryPath = withBasePath(directory)
const workerPool = WorkerPool.create()
- const createIndexHtml = async (activity: ActivityTracker) => {
+ const createIndexHtml = async (activity: ActivityTracker): Promise => {
try {
await buildHTML.buildPages({
program,
@@ -155,7 +166,7 @@ async function startServer(program: IProgram) {
const app = express()
app.use(telemetry.expressMiddleware(`DEVELOP`))
app.use(
- require(`webpack-hot-middleware`)(compiler, {
+ webpackHotMiddleware(compiler, {
log: false,
path: `/__webpack_hmr`,
heartbeat: 10 * 1000,
@@ -185,26 +196,28 @@ async function startServer(program: IProgram) {
app.use(
graphqlEndpoint,
- graphqlHTTP(() => {
- const { schema, schemaCustomization } = store.getState()
+ graphqlHTTP(
+ (): graphqlHTTP.OptionsData => {
+ const { schema, schemaCustomization } = store.getState()
- return {
- schema,
- graphiql: false,
- context: withResolverContext({
+ return {
schema,
- schemaComposer: schemaCustomization.composer,
- context: {},
- customContext: schemaCustomization.context,
- }),
- customFormatErrorFn(err) {
- return {
- ...formatError(err),
- stack: err.stack ? err.stack.split(`\n`) : [],
- }
- },
+ graphiql: false,
+ context: withResolverContext({
+ schema,
+ schemaComposer: schemaCustomization.composer,
+ context: {},
+ customContext: schemaCustomization.context,
+ }),
+ customFormatErrorFn(err): unknown {
+ return {
+ ...formatError(err),
+ stack: err.stack ? err.stack.split(`\n`) : [],
+ }
+ },
+ }
}
- })
+ )
)
/**
@@ -213,7 +226,7 @@ async function startServer(program: IProgram) {
* If no GATSBY_REFRESH_TOKEN env var is available, then no Authorization header is required
**/
const REFRESH_ENDPOINT = `/__refresh`
- const refresh = async (req: express.Request) => {
+ const refresh = async (req: express.Request): Promise => {
let activity = report.activityTimer(`createSchemaCustomization`, {})
activity.start()
await createSchemaCustomization({
@@ -249,10 +262,10 @@ async function startServer(program: IProgram) {
// This can lead to serving stale html files during development.
//
// We serve by default an empty index.html that sets up the dev environment.
- app.use(require(`./develop-static`)(`public`, { index: false }))
+ app.use(developStatic(`public`, { index: false }))
app.use(
- require(`webpack-dev-middleware`)(compiler, {
+ webpackDevMiddleware(compiler, {
logLevel: `silent`,
publicPath: devConfig.output.publicPath,
watchOptions: devConfig.devServer
@@ -277,7 +290,7 @@ async function startServer(program: IProgram) {
const proxiedUrl = url + req.originalUrl
const {
// remove `host` from copied headers
- // eslint-disable-next-line no-unused-vars
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
headers: { host, ...headers },
method,
} = req
@@ -286,11 +299,11 @@ async function startServer(program: IProgram) {
got
.stream(proxiedUrl, { headers, method, decompress: false })
.on(`response`, response =>
- res.writeHead(response.statusCode!, response.headers)
+ res.writeHead(response.statusCode || 200, response.headers)
)
.on(`error`, (err, _, response) => {
if (response) {
- res.writeHead(response.statusCode!, response.headers)
+ res.writeHead(response.statusCode || 400, response.headers)
} else {
const message = `Error when trying to proxy request "${req.originalUrl}" to "${proxiedUrl}"`
@@ -326,7 +339,7 @@ async function startServer(program: IProgram) {
* Set up the HTTP server and socket.io.
* If a SSL cert exists in program, use it with `createServer`.
**/
- let server = program.ssl
+ const server = program.ssl
? https.createServer(program.ssl, app)
: new http.Server(app)
@@ -348,7 +361,7 @@ async function startServer(program: IProgram) {
return { compiler, listener, webpackActivity }
}
-module.exports = async (program: IProgram) => {
+module.exports = async (program: IProgram): Promise => {
initTracer(program.openTracingConfigFile)
report.pendingActivity({ id: `webpack-develop` })
telemetry.trackCli(`DEVELOP_START`)
@@ -396,10 +409,10 @@ module.exports = async (program: IProgram) => {
const { graphqlRunner } = await bootstrap(program)
// Start the createPages hot reloader.
- require(`../bootstrap/page-hot-reloader`)(graphqlRunner)
+ bootstrapPageHotReloader(graphqlRunner)
// Start the schema hot reloader.
- require(`../bootstrap/schema-hot-reloader`)()
+ bootstrapSchemaHotReloader()
await queryUtil.initialProcessQueries()
@@ -415,7 +428,7 @@ module.exports = async (program: IProgram) => {
let { compiler, webpackActivity } = await startServer(program)
- type PreparedUrls = {
+ interface IPreparedUrls {
lanUrlForConfig: string
lanUrlForTerminal: string
localUrlForTerminal: string
@@ -423,18 +436,18 @@ module.exports = async (program: IProgram) => {
}
function prepareUrls(
- protocol: "http" | "https",
+ protocol: `http` | `https`,
host: string,
port: number
- ): PreparedUrls {
- const formatUrl = (hostname: string) =>
+ ): IPreparedUrls {
+ const formatUrl = (hostname: string): string =>
url.format({
protocol,
hostname,
port,
pathname: `/`,
})
- const prettyPrintUrl = (hostname: string) =>
+ const prettyPrintUrl = (hostname: string): string =>
url.format({
protocol,
hostname,
@@ -484,7 +497,7 @@ module.exports = async (program: IProgram) => {
}
}
- function printInstructions(appName: string, urls: PreparedUrls) {
+ function printInstructions(appName: string, urls: IPreparedUrls): void {
console.log()
console.log(`You can now view ${chalk.bold(appName)} in the browser.`)
console.log()
@@ -533,8 +546,9 @@ module.exports = async (program: IProgram) => {
console.log()
}
- function printDeprecationWarnings() {
- const deprecatedApis: ["boundActionCreators", "pathContext"] = [
+ function printDeprecationWarnings(): void {
+ type DeprecatedAPIList = ["boundActionCreators", "pathContext"] // eslint-disable-line
+ const deprecatedApis: DeprecatedAPIList = [
`boundActionCreators`,
`pathContext`,
]
@@ -617,7 +631,7 @@ module.exports = async (program: IProgram) => {
if (isSuccessful && isFirstCompile) {
printInstructions(
- program.sitePackageJson.name || "(Unnamed package)",
+ program.sitePackageJson.name || `(Unnamed package)`,
urls
)
printDeprecationWarnings()
diff --git a/yarn.lock b/yarn.lock
index cb70aded87375..3fc6ca013a9ee 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -4121,6 +4121,17 @@
regexpp "^3.0.0"
tsutils "^3.17.1"
+"@typescript-eslint/eslint-plugin@^2.12.0":
+ version "2.12.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.12.0.tgz#0da7cbca7b24f4c6919e9eb31c704bfb126f90ad"
+ integrity sha512-1t4r9rpLuEwl3hgt90jY18wJHSyb0E3orVL3DaqwmpiSDHmHiSspVsvsFF78BJ/3NNG3qmeso836jpuBWYziAA==
+ dependencies:
+ "@typescript-eslint/experimental-utils" "2.12.0"
+ eslint-utils "^1.4.3"
+ functional-red-black-tree "^1.0.1"
+ regexpp "^3.0.0"
+ tsutils "^3.17.1"
+
"@typescript-eslint/experimental-utils@2.11.0":
version "2.11.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-2.11.0.tgz#cef18e6b122706c65248a5d8984a9779ed1e52ac"
@@ -4130,6 +4141,15 @@
"@typescript-eslint/typescript-estree" "2.11.0"
eslint-scope "^5.0.0"
+"@typescript-eslint/experimental-utils@2.12.0":
+ version "2.12.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-2.12.0.tgz#e0a76ffb6293e058748408a191921e453c31d40d"
+ integrity sha512-jv4gYpw5N5BrWF3ntROvCuLe1IjRenLy5+U57J24NbPGwZFAjhnM45qpq0nDH1y/AZMb3Br25YiNVwyPbz6RkA==
+ dependencies:
+ "@types/json-schema" "^7.0.3"
+ "@typescript-eslint/typescript-estree" "2.12.0"
+ eslint-scope "^5.0.0"
+
"@typescript-eslint/parser@^2.11.0":
version "2.11.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-2.11.0.tgz#cdcc3be73ee31cbef089af5ff97ccaa380ef6e8b"
@@ -4140,6 +4160,16 @@
"@typescript-eslint/typescript-estree" "2.11.0"
eslint-visitor-keys "^1.1.0"
+"@typescript-eslint/parser@^2.12.0":
+ version "2.12.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-2.12.0.tgz#393f1604943a4ca570bb1a45bc8834e9b9158884"
+ integrity sha512-lPdkwpdzxEfjI8TyTzZqPatkrswLSVu4bqUgnB03fHSOwpC7KSerPgJRgIAf11UGNf7HKjJV6oaPZI4AghLU6g==
+ dependencies:
+ "@types/eslint-visitor-keys" "^1.0.0"
+ "@typescript-eslint/experimental-utils" "2.12.0"
+ "@typescript-eslint/typescript-estree" "2.12.0"
+ eslint-visitor-keys "^1.1.0"
+
"@typescript-eslint/typescript-estree@2.11.0":
version "2.11.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-2.11.0.tgz#21ada6504274cd1644855926312c798fc697e9fb"
@@ -4153,6 +4183,19 @@
semver "^6.3.0"
tsutils "^3.17.1"
+"@typescript-eslint/typescript-estree@2.12.0":
+ version "2.12.0"
+ resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-2.12.0.tgz#bd9e547ccffd17dfab0c3ab0947c80c8e2eb914c"
+ integrity sha512-rGehVfjHEn8Frh9UW02ZZIfJs6SIIxIu/K1bbci8rFfDE/1lQ8krIJy5OXOV3DVnNdDPtoiPOdEANkLMrwXbiQ==
+ dependencies:
+ debug "^4.1.1"
+ eslint-visitor-keys "^1.1.0"
+ glob "^7.1.6"
+ is-glob "^4.0.1"
+ lodash.unescape "4.0.1"
+ semver "^6.3.0"
+ tsutils "^3.17.1"
+
"@verdaccio/commons-api@8.3.0":
version "8.3.0"
resolved "https://registry.yarnpkg.com/@verdaccio/commons-api/-/commons-api-8.3.0.tgz#3a4b07b63561b21bfc8242330da528e12788635e"