diff --git a/.eslintrc.js b/.eslintrc.js
index b584e0b742f..0c8e2e4f974 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -1,31 +1,29 @@
module.exports = {
- "root": true,
- "plugins": ["node"],
- "extends": ["eslint:recommended", "plugin:node/recommended"],
- "env": {
- "node": true,
- "es6": true,
- "jest": true
+ extends: ["eslint:recommended"],
+ env: {
+ node: true,
+ es6: true,
+ jest: true
},
- "parserOptions": { "ecmaVersion": 2017, "sourceType": "module"},
- "rules": {
+ parserOptions: { ecmaVersion: 2017, sourceType: "module" },
+ rules: {
"no-useless-escape": "off",
"quote-props": ["error", "as-needed"],
"no-dupe-keys": "error",
- "quotes": ["error", "double"],
+ quotes: ["error", "double"],
"no-undef": "error",
"no-extra-semi": "error",
- "semi": "error",
+ semi: "error",
"no-template-curly-in-string": "error",
"no-caller": "error",
- "yoda": "error",
- "eqeqeq": "error",
+ yoda: "error",
+ eqeqeq: "error",
"global-require": "off",
"brace-style": "error",
"key-spacing": "error",
"space-in-parens": ["error", "never"],
"space-infix-ops": "error",
- "indent": ["error", "tab", { "SwitchCase": 1 }],
+ indent: ["error", "tab", { SwitchCase: 1 }],
"no-extra-bind": "warn",
"no-empty": "off",
"no-multiple-empty-lines": "error",
@@ -33,78 +31,31 @@ module.exports = {
"no-process-exit": "off",
"no-trailing-spaces": "error",
"no-use-before-define": "off",
- "no-unused-vars": ["error", { "args": "none" }],
+ "no-unused-vars": ["error", { args: "none" }],
"no-unsafe-negation": "error",
"no-loop-func": "warn",
"space-before-function-paren": ["error", "never"],
"space-before-blocks": "error",
"object-curly-spacing": ["error", "always"],
- "object-curly-newline": ["error", { "consistent": true }],
- "keyword-spacing": ["error", {
- "after": true,
- "overrides": {
- "const": { "after": true },
- "try": { "after": true },
- "throw": { "after": true },
- "case": { "after": true },
- "return": { "after": true },
- "finally": { "after": true },
- "do": { "after": true }
- }
- }],
- "no-console": "off",
- "valid-jsdoc": "error",
- "node/no-unsupported-features": ["error", { "version": 6 }],
- "node/no-deprecated-api": "error",
- "node/no-missing-import": "error",
- "node/no-missing-require": [
- "error",
- {
- "resolvePaths": ["./packages"],
- "allowModules": [
- "webpack",
- "@webpack-cli/generators",
- "@webpack-cli/init",
- "@webpack-cli/migrate",
- "@webpack-cli/utils",
- "@webpack-cli/generate-loader",
- "@webpack-cli/generate-plugin",
- "@webpack-cli/webpack-scaffold"
- ]
- }
- ],
- "node/no-unpublished-bin": "error",
- "node/no-unpublished-require": [
+ "object-curly-newline": ["error", { consistent: true }],
+ "keyword-spacing": [
"error",
{
- "allowModules": [
- "webpack",
- "webpack-dev-server",
- "@webpack-cli/generators",
- "@webpack-cli/init",
- "@webpack-cli/migrate",
- "@webpack-cli/utils",
- "@webpack-cli/generate-loader",
- "@webpack-cli/generate-plugin",
- "@webpack-cli/webpack-scaffold"
- ]
- }
- ],
- "node/no-extraneous-require": [
- "error",
- {
- "allowModules": [
- "@webpack-cli/migrate",
- "@webpack-cli/generators",
- "@webpack-cli/utils",
- "@webpack-cli/generate-loader",
- "@webpack-cli/generate-plugin",
- "@webpack-cli/webpack-scaffold"
- ]
+ after: true,
+ overrides: {
+ const: { after: true },
+ try: { after: true },
+ throw: { after: true },
+ case: { after: true },
+ return: { after: true },
+ finally: { after: true },
+ do: { after: true }
+ }
}
],
+ "no-console": "off",
+ "valid-jsdoc": "error",
"eol-last": ["error", "always"],
- "newline-per-chained-call": "off",
- "node/process-exit-as-throw": "error"
+ "newline-per-chained-call": "off"
}
};
diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index 8f937259c0c..84c96d30ae1 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -111,7 +111,7 @@ In case you are suggesting a new feature, we will match your idea with our curre
* You can run the linters:
```bash
- npm run lint && npm run tslint
+ npm run lint
```
### Using yarn
@@ -150,7 +150,7 @@ In case you are suggesting a new feature, we will match your idea with our curre
* You can run the linters:
```bash
- yarn lint && yarn tslint
+ yarn lint
```
## Editor Config
diff --git a/.gitignore b/.gitignore
index ef696edb785..6fd2e644f89 100644
--- a/.gitignore
+++ b/.gitignore
@@ -37,3 +37,4 @@ yarn.lock
# source maps of docs
docs/**/*.map
+junit.xml
diff --git a/bin/.eslintrc.js b/bin/.eslintrc.js
new file mode 100644
index 00000000000..b32868dab61
--- /dev/null
+++ b/bin/.eslintrc.js
@@ -0,0 +1,63 @@
+module.exports = {
+ root: true,
+ plugins: ["node"],
+ extends: ["../.eslintrc.js", "plugin:node/recommended"],
+ env: {
+ node: true,
+ es6: true,
+ jest: true
+ },
+ parserOptions: { ecmaVersion: 2017, sourceType: "module" },
+ rules: {
+ "node/no-unsupported-features": ["error", { version: 6 }],
+ "node/no-deprecated-api": "error",
+ "node/no-missing-import": "error",
+ "node/no-missing-require": [
+ "error",
+ {
+ resolvePaths: ["./packages"],
+ allowModules: [
+ "webpack",
+ "@webpack-cli/generators",
+ "@webpack-cli/init",
+ "@webpack-cli/migrate",
+ "@webpack-cli/utils",
+ "@webpack-cli/generate-loader",
+ "@webpack-cli/generate-plugin",
+ "@webpack-cli/webpack-scaffold"
+ ]
+ }
+ ],
+ "node/no-unpublished-bin": "error",
+ "node/no-unpublished-require": [
+ "error",
+ {
+ allowModules: [
+ "webpack",
+ "webpack-dev-server",
+ "@webpack-cli/generators",
+ "@webpack-cli/init",
+ "@webpack-cli/migrate",
+ "@webpack-cli/utils",
+ "@webpack-cli/generate-loader",
+ "@webpack-cli/generate-plugin",
+ "@webpack-cli/webpack-scaffold"
+ ]
+ }
+ ],
+ "node/no-extraneous-require": [
+ "error",
+ {
+ allowModules: [
+ "@webpack-cli/migrate",
+ "@webpack-cli/generators",
+ "@webpack-cli/utils",
+ "@webpack-cli/generate-loader",
+ "@webpack-cli/generate-plugin",
+ "@webpack-cli/webpack-scaffold"
+ ]
+ }
+ ],
+ "node/process-exit-as-throw": "error"
+ }
+};
diff --git a/bin/utils/prompt-command.js b/bin/utils/prompt-command.js
index 907434c6c71..20a99a1655f 100644
--- a/bin/utils/prompt-command.js
+++ b/bin/utils/prompt-command.js
@@ -31,20 +31,20 @@ const npmGlobalRoot = () => {
const cp = require("child_process");
return new Promise((resolve, reject) => {
const command = cp.spawn("npm", ["root", "-g"]);
- command.on("error", (error) => reject(error));
- command.stdout.on("data", (data) => resolve(data.toString()));
- command.stderr.on("data", (data) => reject(data));
+ command.on("error", error => reject(error));
+ command.stdout.on("data", data => resolve(data.toString()));
+ command.stderr.on("data", data => reject(data));
});
};
const runWhenInstalled = (packages, pathForCmd, ...args) => {
- const package = require(pathForCmd);
- const func = package.default;
- if (typeof func !== 'function') {
+ const currentPackage = require(pathForCmd);
+ const func = currentPackage.default;
+ if (typeof func !== "function") {
throw new Error(`@webpack-cli/${packages} failed to export a default function`);
}
return func(...args);
-}
+};
module.exports = function promptForInstallation(packages, ...args) {
const nameOfPackage = "@webpack-cli/" + packages;
@@ -102,19 +102,18 @@ module.exports = function promptForInstallation(packages, ...args) {
case "y":
case "yes":
case "1": {
-
runCommand(packageManager, options)
- .then(_=> {
+ .then(_ => {
if (packages === "init") {
npmGlobalRoot()
- .then((root) => {
+ .then(root => {
const pathtoInit = path.resolve(root.trim(), "@webpack-cli", "init");
return pathtoInit;
})
- .then((pathForInit) => {
+ .then(pathForInit => {
return require(pathForInit).default(...args);
})
- .catch((error) => {
+ .catch(error => {
console.error(error);
process.exitCode = 1;
});
diff --git a/junit.xml b/junit.xml
deleted file mode 100644
index 304ccef7cc6..00000000000
--- a/junit.xml
+++ /dev/null
@@ -1,557 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 3fa90818763..f72cab5b2a6 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2567,6 +2567,58 @@
"integrity": "sha512-sCZy4SxP9rN2w30Hlmg5dtdRwgYQfYRiLo9usw8X9cxlf+H4FqM1xX7+sNH7NNKVdbXMJWqva7iyy+fxh/V7fA==",
"dev": true
},
+ "@typescript-eslint/eslint-plugin": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-1.6.0.tgz",
+ "integrity": "sha512-U224c29E2lo861TQZs6GSmyC0OYeRNg6bE9UVIiFBxN2MlA0nq2dCrgIVyyRbC05UOcrgf2Wk/CF2gGOPQKUSQ==",
+ "dev": true,
+ "requires": {
+ "@typescript-eslint/parser": "1.6.0",
+ "@typescript-eslint/typescript-estree": "1.6.0",
+ "requireindex": "^1.2.0",
+ "tsutils": "^3.7.0"
+ },
+ "dependencies": {
+ "tsutils": {
+ "version": "3.10.0",
+ "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.10.0.tgz",
+ "integrity": "sha512-q20XSMq7jutbGB8luhKKsQldRKWvyBO2BGqni3p4yq8Ys9bEP/xQw3KepKmMRt9gJ4lvQSScrihJrcKdKoSU7Q==",
+ "dev": true,
+ "requires": {
+ "tslib": "^1.8.1"
+ }
+ }
+ }
+ },
+ "@typescript-eslint/parser": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-1.6.0.tgz",
+ "integrity": "sha512-VB9xmSbfafI+/kI4gUK3PfrkGmrJQfh0N4EScT1gZXSZyUxpsBirPL99EWZg9MmPG0pzq/gMtgkk7/rAHj4aQw==",
+ "dev": true,
+ "requires": {
+ "@typescript-eslint/typescript-estree": "1.6.0",
+ "eslint-scope": "^4.0.0",
+ "eslint-visitor-keys": "^1.0.0"
+ }
+ },
+ "@typescript-eslint/typescript-estree": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-1.6.0.tgz",
+ "integrity": "sha512-A4CanUwfaG4oXobD5y7EXbsOHjCwn8tj1RDd820etpPAjH+Icjc2K9e/DQM1Hac5zH2BSy+u6bjvvF2wwREvYA==",
+ "dev": true,
+ "requires": {
+ "lodash.unescape": "4.0.1",
+ "semver": "5.5.0"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz",
+ "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==",
+ "dev": true
+ }
+ }
+ },
"@webassemblyjs/ast": {
"version": "1.8.5",
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz",
@@ -4341,12 +4393,6 @@
"integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=",
"dev": true
},
- "builtin-modules": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
- "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=",
- "dev": true
- },
"builtin-status-codes": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz",
@@ -6607,6 +6653,23 @@
}
}
},
+ "eslint-config-prettier": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-4.1.0.tgz",
+ "integrity": "sha512-zILwX9/Ocz4SV2vX7ox85AsrAgXV3f2o2gpIicdMIOra48WYqgUnWNH/cR/iHtmD2Vb3dLSC3LiEJnS05Gkw7w==",
+ "dev": true,
+ "requires": {
+ "get-stdin": "^6.0.0"
+ },
+ "dependencies": {
+ "get-stdin": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz",
+ "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==",
+ "dev": true
+ }
+ }
+ },
"eslint-plugin-es": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-1.4.0.tgz",
@@ -7480,7 +7543,8 @@
"ansi-regex": {
"version": "2.1.1",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"aproba": {
"version": "1.2.0",
@@ -7501,12 +7565,14 @@
"balanced-match": {
"version": "1.0.0",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@@ -7521,17 +7587,20 @@
"code-point-at": {
"version": "1.1.0",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"concat-map": {
"version": "0.0.1",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"console-control-strings": {
"version": "1.1.0",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"core-util-is": {
"version": "1.0.2",
@@ -7648,7 +7717,8 @@
"inherits": {
"version": "2.0.3",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"ini": {
"version": "1.3.5",
@@ -7660,6 +7730,7 @@
"version": "1.0.0",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@@ -7674,6 +7745,7 @@
"version": "3.0.4",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
@@ -7681,12 +7753,14 @@
"minimist": {
"version": "0.0.8",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"minipass": {
"version": "2.3.5",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"safe-buffer": "^5.1.2",
"yallist": "^3.0.0"
@@ -7705,6 +7779,7 @@
"version": "0.5.1",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"minimist": "0.0.8"
}
@@ -7785,7 +7860,8 @@
"number-is-nan": {
"version": "1.0.1",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"object-assign": {
"version": "4.1.1",
@@ -7797,6 +7873,7 @@
"version": "1.4.0",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"wrappy": "1"
}
@@ -7882,7 +7959,8 @@
"safe-buffer": {
"version": "5.1.2",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"safer-buffer": {
"version": "2.1.2",
@@ -7918,6 +7996,7 @@
"version": "1.0.2",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@@ -7937,6 +8016,7 @@
"version": "3.0.1",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"ansi-regex": "^2.0.0"
}
@@ -7980,12 +8060,14 @@
"wrappy": {
"version": "1.0.2",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"yallist": {
"version": "3.0.3",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
}
}
},
@@ -15367,6 +15449,12 @@
}
}
},
+ "requireindex": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz",
+ "integrity": "sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==",
+ "dev": true
+ },
"requires-port": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
@@ -16950,36 +17038,6 @@
"integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==",
"dev": true
},
- "tslint": {
- "version": "5.14.0",
- "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.14.0.tgz",
- "integrity": "sha512-IUla/ieHVnB8Le7LdQFRGlVJid2T/gaJe5VkjzRVSRR6pA2ODYrnfR1hmxi+5+au9l50jBwpbBL34txgv4NnTQ==",
- "dev": true,
- "requires": {
- "babel-code-frame": "^6.22.0",
- "builtin-modules": "^1.1.1",
- "chalk": "^2.3.0",
- "commander": "^2.12.1",
- "diff": "^3.2.0",
- "glob": "^7.1.1",
- "js-yaml": "^3.7.0",
- "minimatch": "^3.0.4",
- "mkdirp": "^0.5.1",
- "resolve": "^1.3.2",
- "semver": "^5.3.0",
- "tslib": "^1.8.0",
- "tsutils": "^2.29.0"
- }
- },
- "tsutils": {
- "version": "2.29.0",
- "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz",
- "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==",
- "dev": true,
- "requires": {
- "tslib": "^1.8.1"
- }
- },
"tty-browserify": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
diff --git a/package.json b/package.json
index a3d62ea17cc..7d4b80cf5ea 100644
--- a/package.json
+++ b/package.json
@@ -35,17 +35,16 @@
"docs": "typedoc",
"format": "prettier-eslint ./bin/*.js ./test/**/*.js ./packages/**/*.js --write",
"lint:codeOnly": "eslint \"{bin}/**/!(__testfixtures__)/*.js\" \"{bin}/**.js\"",
- "lint": "eslint \"./bin/*.js\" \"./test/**/*.js\" \"packages/**/!(node_modules)/*.test.js\"",
+ "lint": "eslint \"./bin/*.js\" \"./test/**/*.js\" \"packages/**/!(node_modules)/*.ts\"",
"postinstall": "node ./bin/opencollective.js",
- "pretest": "npm run build && npm run lint && npm run tslint",
+ "pretest": "npm run build && npm run lint",
"reportCoverage": "nyc report --reporter=json && codecov -f coverage/coverage-final.json --disable=gcov",
"test": "nyc jest --maxWorkers=4 --reporters=default --reporters=jest-junit",
"test:cli": "nyc jest test/ --maxWorkers=4 --reporters=default --reporters=jest-junit",
"test:packages": "nyc jest packages/ --maxWorkers=4 --reporters=default --reporters=jest-junit",
"test:ci": "nyc jest --maxWorkers=$(nproc) --reporters=default --reporters=jest-junit",
"travis:integration": "npm run build && npm run test && npm run reportCoverage",
- "travis:lint": "npm run build && npm run lint && npm run tslint",
- "tslint": "tslint -c tslint.json \"packages/**/*.ts\"",
+ "travis:lint": "npm run build && npm run lint",
"watch": "npm run build && tsc -w"
},
"husky": {
@@ -58,10 +57,6 @@
"{packages,bin}/**/!(__testfixtures__)/**.js": [
"eslint --fix",
"git add"
- ],
- "{packages,bin}/**/!(__testfixtures__)/**.ts": [
- "tslint --fix",
- "git add"
]
},
"jest": {
@@ -145,6 +140,8 @@
"@commitlint/travis-cli": "^7.2.1",
"@types/jest": "^23.3.14",
"@types/node": "^10.12.9",
+ "@typescript-eslint/eslint-plugin": "^1.6.0",
+ "@typescript-eslint/parser": "^1.6.0",
"babel-preset-env": "^1.7.0",
"babel-preset-jest": "^24.3.0",
"bundlesize": "^0.17.0",
@@ -154,6 +151,7 @@
"conventional-changelog-cli": "^2.0.11",
"cz-customizable": "^5.3.0",
"eslint": "^5.9.0",
+ "eslint-config-prettier": "^4.1.0",
"eslint-plugin-node": "^8.0.0",
"esm": "^3.2.14",
"execa": "^1.0.0",
@@ -170,7 +168,6 @@
"schema-utils": "^1.0.0",
"ts-jest": "^23.10.5",
"ts-node": "^7.0.1",
- "tslint": "^5.11.0",
"typedoc": "^0.13.0",
"typedoc-plugin-monorepo": "^0.1.0",
"typescript": "^3.3.1",
diff --git a/packages/add/.eslintrc b/packages/add/.eslintrc
new file mode 100644
index 00000000000..365d9f85d71
--- /dev/null
+++ b/packages/add/.eslintrc
@@ -0,0 +1,11 @@
+{
+ "root": true,
+ "extends": [
+ "../../.eslintrc.js",
+ "plugin:@typescript-eslint/recommended",
+ "prettier",
+ "prettier/@typescript-eslint"
+ ],
+ "parser": "@typescript-eslint/parser",
+ "plugins": ["@typescript-eslint"]
+}
diff --git a/packages/add/index.ts b/packages/add/index.ts
index bc5fe92f195..a63515c9347 100644
--- a/packages/add/index.ts
+++ b/packages/add/index.ts
@@ -12,11 +12,11 @@ import modifyConfigHelper from "@webpack-cli/utils/modify-config-helper";
const DEFAULT_WEBPACK_CONFIG_FILENAME = "webpack.config.js";
export default function add(...args: string[]): Function {
- const filePaths = args.slice(3);
- let configFile = DEFAULT_WEBPACK_CONFIG_FILENAME;
- if (filePaths.length) {
- configFile = filePaths[0];
- }
+ const filePaths = args.slice(3);
+ let configFile = DEFAULT_WEBPACK_CONFIG_FILENAME;
+ if (filePaths.length) {
+ configFile = filePaths[0];
+ }
- return modifyConfigHelper("add", defaultGenerator, configFile);
+ return modifyConfigHelper("add", defaultGenerator, configFile);
}
diff --git a/packages/add/package-lock.json b/packages/add/package-lock.json
index 61a703534e8..dfebd320fe5 100644
--- a/packages/add/package-lock.json
+++ b/packages/add/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "@webpack-cli/add",
- "version": "0.1.2",
+ "version": "0.1.5",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -10,6 +10,109 @@
"integrity": "sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ==",
"dev": true
},
+ "@typescript-eslint/eslint-plugin": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-1.6.0.tgz",
+ "integrity": "sha512-U224c29E2lo861TQZs6GSmyC0OYeRNg6bE9UVIiFBxN2MlA0nq2dCrgIVyyRbC05UOcrgf2Wk/CF2gGOPQKUSQ==",
+ "dev": true,
+ "requires": {
+ "@typescript-eslint/parser": "1.6.0",
+ "@typescript-eslint/typescript-estree": "1.6.0",
+ "requireindex": "^1.2.0",
+ "tsutils": "^3.7.0"
+ }
+ },
+ "@typescript-eslint/parser": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-1.6.0.tgz",
+ "integrity": "sha512-VB9xmSbfafI+/kI4gUK3PfrkGmrJQfh0N4EScT1gZXSZyUxpsBirPL99EWZg9MmPG0pzq/gMtgkk7/rAHj4aQw==",
+ "dev": true,
+ "requires": {
+ "@typescript-eslint/typescript-estree": "1.6.0",
+ "eslint-scope": "^4.0.0",
+ "eslint-visitor-keys": "^1.0.0"
+ }
+ },
+ "@typescript-eslint/typescript-estree": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-1.6.0.tgz",
+ "integrity": "sha512-A4CanUwfaG4oXobD5y7EXbsOHjCwn8tj1RDd820etpPAjH+Icjc2K9e/DQM1Hac5zH2BSy+u6bjvvF2wwREvYA==",
+ "dev": true,
+ "requires": {
+ "lodash.unescape": "4.0.1",
+ "semver": "5.5.0"
+ }
+ },
+ "eslint-scope": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz",
+ "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==",
+ "dev": true,
+ "requires": {
+ "esrecurse": "^4.1.0",
+ "estraverse": "^4.1.1"
+ }
+ },
+ "eslint-visitor-keys": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz",
+ "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==",
+ "dev": true
+ },
+ "esrecurse": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz",
+ "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==",
+ "dev": true,
+ "requires": {
+ "estraverse": "^4.1.0"
+ }
+ },
+ "estraverse": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
+ "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=",
+ "dev": true
+ },
+ "lodash.unescape": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/lodash.unescape/-/lodash.unescape-4.0.1.tgz",
+ "integrity": "sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw=",
+ "dev": true
+ },
+ "prettier": {
+ "version": "1.17.0",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.17.0.tgz",
+ "integrity": "sha512-sXe5lSt2WQlCbydGETgfm1YBShgOX4HxQkFPvbxkcwgDvGDeqVau8h+12+lmSVlP3rHPz0oavfddSZg/q+Szjw==",
+ "dev": true
+ },
+ "requireindex": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz",
+ "integrity": "sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==",
+ "dev": true
+ },
+ "semver": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz",
+ "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==",
+ "dev": true
+ },
+ "tslib": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz",
+ "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==",
+ "dev": true
+ },
+ "tsutils": {
+ "version": "3.10.0",
+ "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.10.0.tgz",
+ "integrity": "sha512-q20XSMq7jutbGB8luhKKsQldRKWvyBO2BGqni3p4yq8Ys9bEP/xQw3KepKmMRt9gJ4lvQSScrihJrcKdKoSU7Q==",
+ "dev": true,
+ "requires": {
+ "tslib": "^1.8.1"
+ }
+ },
"typescript": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.2.2.tgz",
diff --git a/packages/add/tsconfig.json b/packages/add/tsconfig.json
index 8b1269a36b6..2a74d10580a 100644
--- a/packages/add/tsconfig.json
+++ b/packages/add/tsconfig.json
@@ -1,3 +1,3 @@
{
- "extends": "../../tsconfig.packages.json"
+ "extends": "../../tsconfig.packages.json"
}
diff --git a/packages/generate-loader/.eslintrc b/packages/generate-loader/.eslintrc
new file mode 100644
index 00000000000..365d9f85d71
--- /dev/null
+++ b/packages/generate-loader/.eslintrc
@@ -0,0 +1,11 @@
+{
+ "root": true,
+ "extends": [
+ "../../.eslintrc.js",
+ "plugin:@typescript-eslint/recommended",
+ "prettier",
+ "prettier/@typescript-eslint"
+ ],
+ "parser": "@typescript-eslint/parser",
+ "plugins": ["@typescript-eslint"]
+}
diff --git a/packages/generate-loader/index.ts b/packages/generate-loader/index.ts
index b56835cfc97..8f280fc6226 100644
--- a/packages/generate-loader/index.ts
+++ b/packages/generate-loader/index.ts
@@ -1,8 +1,6 @@
import LoaderGenerator from "@webpack-cli/generators/loader-generator";
import * as yeoman from "yeoman-environment";
-import { IYeoman } from "./types/Yeoman";
-
/**
* Runs a yeoman generator to create a new webpack loader project
* @returns {void}
diff --git a/packages/generate-loader/package-lock.json b/packages/generate-loader/package-lock.json
index b9561b5e442..90c9c102e80 100644
--- a/packages/generate-loader/package-lock.json
+++ b/packages/generate-loader/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "@webpack-cli/generate-loader",
- "version": "0.1.2",
+ "version": "0.1.5",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -24,6 +24,47 @@
"integrity": "sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ==",
"dev": true
},
+ "@typescript-eslint/eslint-plugin": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-1.6.0.tgz",
+ "integrity": "sha512-U224c29E2lo861TQZs6GSmyC0OYeRNg6bE9UVIiFBxN2MlA0nq2dCrgIVyyRbC05UOcrgf2Wk/CF2gGOPQKUSQ==",
+ "dev": true,
+ "requires": {
+ "@typescript-eslint/parser": "1.6.0",
+ "@typescript-eslint/typescript-estree": "1.6.0",
+ "requireindex": "^1.2.0",
+ "tsutils": "^3.7.0"
+ }
+ },
+ "@typescript-eslint/parser": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-1.6.0.tgz",
+ "integrity": "sha512-VB9xmSbfafI+/kI4gUK3PfrkGmrJQfh0N4EScT1gZXSZyUxpsBirPL99EWZg9MmPG0pzq/gMtgkk7/rAHj4aQw==",
+ "dev": true,
+ "requires": {
+ "@typescript-eslint/typescript-estree": "1.6.0",
+ "eslint-scope": "^4.0.0",
+ "eslint-visitor-keys": "^1.0.0"
+ }
+ },
+ "@typescript-eslint/typescript-estree": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-1.6.0.tgz",
+ "integrity": "sha512-A4CanUwfaG4oXobD5y7EXbsOHjCwn8tj1RDd820etpPAjH+Icjc2K9e/DQM1Hac5zH2BSy+u6bjvvF2wwREvYA==",
+ "dev": true,
+ "requires": {
+ "lodash.unescape": "4.0.1",
+ "semver": "5.5.0"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz",
+ "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==",
+ "dev": true
+ }
+ }
+ },
"ansi-escapes": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz",
@@ -384,6 +425,37 @@
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
},
+ "eslint-scope": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz",
+ "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==",
+ "dev": true,
+ "requires": {
+ "esrecurse": "^4.1.0",
+ "estraverse": "^4.1.1"
+ }
+ },
+ "eslint-visitor-keys": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz",
+ "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==",
+ "dev": true
+ },
+ "esrecurse": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz",
+ "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==",
+ "dev": true,
+ "requires": {
+ "estraverse": "^4.1.0"
+ }
+ },
+ "estraverse": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
+ "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=",
+ "dev": true
+ },
"expand-brackets": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
@@ -905,6 +977,12 @@
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
"integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg=="
},
+ "lodash.unescape": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/lodash.unescape/-/lodash.unescape-4.0.1.tgz",
+ "integrity": "sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw=",
+ "dev": true
+ },
"log-symbols": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz",
@@ -1142,6 +1220,12 @@
"resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
"integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs="
},
+ "prettier": {
+ "version": "1.17.0",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.17.0.tgz",
+ "integrity": "sha512-sXe5lSt2WQlCbydGETgfm1YBShgOX4HxQkFPvbxkcwgDvGDeqVau8h+12+lmSVlP3rHPz0oavfddSZg/q+Szjw==",
+ "dev": true
+ },
"process-nextick-args": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
@@ -1185,6 +1269,12 @@
"resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz",
"integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ="
},
+ "requireindex": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz",
+ "integrity": "sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==",
+ "dev": true
+ },
"resolve-url": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
@@ -1571,6 +1661,15 @@
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz",
"integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ=="
},
+ "tsutils": {
+ "version": "3.10.0",
+ "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.10.0.tgz",
+ "integrity": "sha512-q20XSMq7jutbGB8luhKKsQldRKWvyBO2BGqni3p4yq8Ys9bEP/xQw3KepKmMRt9gJ4lvQSScrihJrcKdKoSU7Q==",
+ "dev": true,
+ "requires": {
+ "tslib": "^1.8.1"
+ }
+ },
"typescript": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.2.2.tgz",
diff --git a/packages/generate-loader/types/Yeoman.ts b/packages/generate-loader/types/Yeoman.ts
index 4c56a771c00..16615324c03 100644
--- a/packages/generate-loader/types/Yeoman.ts
+++ b/packages/generate-loader/types/Yeoman.ts
@@ -1,12 +1,12 @@
-interface IRunEnv extends Object {
+interface RunEnv extends Object {
on?: (event: string, callbackFn: Function) => void;
}
-export interface IYeoman extends Object {
- registerStub?(generator: IGenerator, namespace: string): void;
- run?(target: string, options?: object, done?: Function): IRunEnv;
+export interface Yeoman extends Object {
+ registerStub?(generator: YeoGenerator, namespace: string): void;
+ run?(target: string, options?: object, done?: Function): RunEnv;
}
-export interface IGenerator extends Object {
+export interface YeoGenerator extends Object {
composeWith?: (path: string) => void;
}
diff --git a/packages/generate-plugin/.eslintrc b/packages/generate-plugin/.eslintrc
new file mode 100644
index 00000000000..365d9f85d71
--- /dev/null
+++ b/packages/generate-plugin/.eslintrc
@@ -0,0 +1,11 @@
+{
+ "root": true,
+ "extends": [
+ "../../.eslintrc.js",
+ "plugin:@typescript-eslint/recommended",
+ "prettier",
+ "prettier/@typescript-eslint"
+ ],
+ "parser": "@typescript-eslint/parser",
+ "plugins": ["@typescript-eslint"]
+}
diff --git a/packages/generate-plugin/index.ts b/packages/generate-plugin/index.ts
index c5fab329c0a..50448da6713 100644
--- a/packages/generate-plugin/index.ts
+++ b/packages/generate-plugin/index.ts
@@ -1,8 +1,6 @@
import PluginGenerator from "@webpack-cli/generators/plugin-generator";
import * as yeoman from "yeoman-environment";
-import { IYeoman } from "./types/Yeoman";
-
/**
* Runs a yeoman generator to create a new webpack plugin project
* @returns {void}
diff --git a/packages/generate-plugin/types/Yeoman.ts b/packages/generate-plugin/types/Yeoman.ts
index 4c56a771c00..1eab3f4b3d5 100644
--- a/packages/generate-plugin/types/Yeoman.ts
+++ b/packages/generate-plugin/types/Yeoman.ts
@@ -1,12 +1,12 @@
-interface IRunEnv extends Object {
+interface RunEnv extends Object {
on?: (event: string, callbackFn: Function) => void;
}
-export interface IYeoman extends Object {
- registerStub?(generator: IGenerator, namespace: string): void;
- run?(target: string, options?: object, done?: Function): IRunEnv;
+export interface Yeoman extends Object {
+ registerStub?(generator: Generator, namespace: string): void;
+ run?(target: string, options?: object, done?: Function): RunEnv;
}
-export interface IGenerator extends Object {
+export interface Generator extends Object {
composeWith?: (path: string) => void;
}
diff --git a/packages/generators/.eslintrc b/packages/generators/.eslintrc
new file mode 100644
index 00000000000..365d9f85d71
--- /dev/null
+++ b/packages/generators/.eslintrc
@@ -0,0 +1,11 @@
+{
+ "root": true,
+ "extends": [
+ "../../.eslintrc.js",
+ "plugin:@typescript-eslint/recommended",
+ "prettier",
+ "prettier/@typescript-eslint"
+ ],
+ "parser": "@typescript-eslint/parser",
+ "plugins": ["@typescript-eslint"]
+}
diff --git a/packages/generators/__tests__/.eslintrc b/packages/generators/__tests__/.eslintrc
new file mode 100644
index 00000000000..e3e3b0884ac
--- /dev/null
+++ b/packages/generators/__tests__/.eslintrc
@@ -0,0 +1,9 @@
+{
+ "root": true,
+ "extends": [
+ "../.eslintrc"
+ ],
+ "rules": {
+ "@typescript-eslint/explicit-function-return-type": ["off"]
+ }
+}
diff --git a/packages/generators/loader-generator.test.js b/packages/generators/__tests__/loader-generator.test.ts
similarity index 84%
rename from packages/generators/loader-generator.test.js
rename to packages/generators/__tests__/loader-generator.test.ts
index 283f6bf551a..f8d6c4667c3 100644
--- a/packages/generators/loader-generator.test.js
+++ b/packages/generators/__tests__/loader-generator.test.ts
@@ -1,6 +1,4 @@
-"use strict";
-
-const { makeLoaderName } = require("./loader-generator");
+import { makeLoaderName } from "../loader-generator";
describe("makeLoaderName", () => {
it("should kebab-case loader name and append '-loader'", () => {
diff --git a/packages/generators/add-generator.ts b/packages/generators/add-generator.ts
index 134c10be8b4..e05da4d3c54 100644
--- a/packages/generators/add-generator.ts
+++ b/packages/generators/add-generator.ts
@@ -7,20 +7,13 @@ import * as path from "path";
import npmExists from "@webpack-cli/utils/npm-exists";
import { getPackageManager } from "@webpack-cli/utils/package-manager";
import PROP_TYPES from "@webpack-cli/utils/prop-types";
-import {
- AutoComplete,
- Confirm,
- IInquirerInput,
- Input,
- List,
-} from "@webpack-cli/webpack-scaffold";
+import { AutoComplete, Confirm, InquirerInput, Input, List } from "@webpack-cli/webpack-scaffold";
-import { ISchemaProperties, IWebpackOptions } from "./types";
+import { SchemaProperties, WebpackOptions } from "./types";
import entryQuestions from "./utils/entry";
-// tslint:disable:no-var-requires
-const webpackDevServerSchema = require("webpack-dev-server/lib/options.json");
-const webpackSchema = require("./utils/optionsSchema.json");
+import webpackDevServerSchema from "webpack-dev-server/lib/options.json";
+import webpackSchema from "./utils/optionsSchema.json";
const PROPS: string[] = Array.from(PROP_TYPES.keys());
/**
@@ -28,7 +21,7 @@ const PROPS: string[] = Array.from(PROP_TYPES.keys());
* Replaces the string with a substring at the given index
* https://gist.github.com/efenacigiray/9367920
*
- * @param {String} string - string to be modified
+ * @param {String} str - string to be modified
* @param {Number} index - index to replace from
* @param {String} replace - string to replace starting from index
*
@@ -51,11 +44,13 @@ function replaceAt(str: string, index: number, replace: string): string {
*/
const traverseAndGetProperties = (arr: object[], prop: string): boolean => {
let hasProp = false;
- arr.forEach((p: object): void => {
- if (p[prop]) {
- hasProp = true;
+ arr.forEach(
+ (p: object): void => {
+ if (p[prop]) {
+ hasProp = true;
+ }
}
- });
+ );
return hasProp;
};
@@ -71,11 +66,7 @@ const traverseAndGetProperties = (arr: object[], prop: string): boolean => {
*/
const searchProps = (answers: object, input: string): Promise => {
input = input || "";
- return Promise.resolve(
- PROPS.filter((prop: string): boolean =>
- prop.toLowerCase().includes(input.toLowerCase()),
- ),
- );
+ return Promise.resolve(PROPS.filter((prop: string): boolean => prop.toLowerCase().includes(input.toLowerCase())));
};
/**
@@ -91,452 +82,414 @@ export default class AddGenerator extends Generator {
private dependencies: string[];
private configuration: {
config: {
- configName?: string,
- topScope?: string[],
+ configName?: string;
+ topScope?: string[];
item?: string;
- webpackOptions?: IWebpackOptions,
- },
+ webpackOptions?: WebpackOptions;
+ };
};
- constructor(args, opts) {
+ public constructor(args, opts) {
super(args, opts);
this.dependencies = [];
this.configuration = {
config: {
topScope: ["const webpack = require('webpack')"],
- webpackOptions: {},
- },
+ webpackOptions: {}
+ }
};
const { registerPrompt } = this.env.adapter.promptModule;
registerPrompt("autocomplete", autoComplete);
}
- public prompting() {
- const done: (_?: void) => void | boolean = this.async();
+ public prompting(): void {
+ const done: () => void | boolean = this.async();
let action: string;
const self: this = this;
- const manualOrListInput: (promptAction: string) => IInquirerInput = (promptAction: string) =>
+ const manualOrListInput: (promptAction: string) => InquirerInput = (promptAction: string): InquirerInput =>
Input("actionAnswer", `What do you want to add to ${promptAction}?`);
- let inputPrompt: IInquirerInput;
+ let inputPrompt: InquirerInput;
// first index indicates if it has a deep prop, 2nd indicates what kind of
+ // TODO: this must be reviewed. It starts as an array of booleans but after that it get overridden
+ // Bye bye functional programming.
+ // eslint-disable-next-line
const isDeepProp: any[] = [false, false];
return this.prompt([
- AutoComplete(
- "actionType",
- "What property do you want to add to?",
- {
- pageSize: 7,
- source: searchProps,
- suggestOnly: false,
- },
- ),
- ])
- .then((actionTypeAnswer: {
- actionType: string,
- }) => {
- // Set initial prop, like devtool
- this.configuration.config.webpackOptions[
- actionTypeAnswer.actionType
- ] = null;
- // update the action variable, we're using it later
- action = actionTypeAnswer.actionType;
+ AutoComplete("actionType", "What property do you want to add to?", {
+ pageSize: 7,
+ source: searchProps,
+ suggestOnly: false
})
- .then((_: void) => {
- if (action === "entry") {
- return this.prompt([
- Confirm("entryType", "Will your application have multiple bundles?", false),
- ])
- .then((entryTypeAnswer: {
- entryType: boolean,
- }) => {
- // Ask different questions for entry points
- return entryQuestions(self, entryTypeAnswer);
- })
- .then((entryOptions: {
- entryType: boolean;
- }) => {
- this.configuration.config.webpackOptions.entry = entryOptions;
- this.configuration.config.item = action;
- });
+ ])
+ .then(
+ (actionTypeAnswer: { actionType: string }): void => {
+ // Set initial prop, like devtool
+ this.configuration.config.webpackOptions[actionTypeAnswer.actionType] = null;
+ // update the action variable, we're using it later
+ action = actionTypeAnswer.actionType;
+ }
+ )
+ .then(
+ (): void => {
+ if (action === "entry") {
+ return this.prompt([
+ Confirm("entryType", "Will your application have multiple bundles?", false)
+ ])
+ .then(
+ (entryTypeAnswer: { entryType: boolean }): Promise<{}> => {
+ // Ask different questions for entry points
+ return entryQuestions(self, entryTypeAnswer);
+ }
+ )
+ .then(
+ (entryOptions: { entryType: boolean }): void => {
+ this.configuration.config.webpackOptions.entry = entryOptions;
+ this.configuration.config.item = action;
+ }
+ );
} else {
if (action === "topScope") {
- return this.prompt([
- Input("topScope", "What do you want to add to topScope?"),
- ])
- .then((topScopeAnswer: {
- topScope: string;
- }) => {
- this.configuration.config.topScope.push(topScopeAnswer.topScope);
- done();
- });
+ return this.prompt([Input("topScope", "What do you want to add to topScope?")]).then(
+ (topScopeAnswer: { topScope: string }): void => {
+ this.configuration.config.topScope.push(topScopeAnswer.topScope);
+ done();
+ }
+ );
}
}
- const temp = action;
- if (action === "resolveLoader") {
- action = "resolve";
- }
- const webpackSchemaProp: ISchemaProperties = webpackSchema.definitions[action];
- /*
- * https://github.com/webpack/webpack/blob/next/schemas/WebpackOptions.json
- * Find the properties directly in the properties prop, or the anyOf prop
- */
- let defOrPropDescription: object = webpackSchemaProp
- ? webpackSchemaProp.properties
- : webpackSchema.properties[action].properties
+ const temp = action;
+ if (action === "resolveLoader") {
+ action = "resolve";
+ }
+ const webpackSchemaProp: SchemaProperties = webpackSchema.definitions[action];
+ /*
+ * https://github.com/webpack/webpack/blob/next/schemas/WebpackOptions.json
+ * Find the properties directly in the properties prop, or the anyOf prop
+ */
+ let defOrPropDescription: object = webpackSchemaProp
+ ? webpackSchemaProp.properties
+ : webpackSchema.properties[action].properties
? webpackSchema.properties[action].properties
: webpackSchema.properties[action].anyOf
- ? webpackSchema.properties[action].anyOf.filter(
- (p: {
- properties?: object,
- enum?: any[],
- }) => p.properties || p.enum,
- )
- : null;
- if (Array.isArray(defOrPropDescription)) {
- // Todo: Generalize these to go through the array, then merge enum with props if needed
- const hasPropertiesProp: boolean = traverseAndGetProperties(
- defOrPropDescription,
- "properties",
- );
- const hasEnumProp: boolean = traverseAndGetProperties(
- defOrPropDescription,
- "enum",
- );
- /* as we know he schema only has two arrays that might hold our values,
- * check them for either having arr.enum or arr.properties
- */
- if (hasPropertiesProp) {
- defOrPropDescription =
- defOrPropDescription[0].properties ||
- defOrPropDescription[1].properties;
- if (!defOrPropDescription) {
- defOrPropDescription = defOrPropDescription[0].enum;
- }
- // TODO: manually implement stats and devtools like sourcemaps
- } else if (hasEnumProp) {
- const originalPropDesc: object = defOrPropDescription[0].enum;
- // Array -> Object -> Merge objects into one for compat in manualOrListInput
- defOrPropDescription = Object.keys(defOrPropDescription[0].enum)
- .map((p: string): object => {
- return Object.assign(
- {},
- {
- [originalPropDesc[p]]: "noop",
- },
- );
- })
- .reduce((result: object, currentObject: object): object => {
- for (const key in currentObject) {
- if (currentObject.hasOwnProperty(key)) {
- result[key] = currentObject[key];
+ ? webpackSchema.properties[action].anyOf.filter(
+ (p: { properties?: object; enum?: string[] }): boolean => !!p.properties || !!p.enum
+ )
+ : null;
+ if (Array.isArray(defOrPropDescription)) {
+ // Todo: Generalize these to go through the array, then merge enum with props if needed
+ const hasPropertiesProp: boolean = traverseAndGetProperties(defOrPropDescription, "properties");
+ const hasEnumProp: boolean = traverseAndGetProperties(defOrPropDescription, "enum");
+ /* as we know he schema only has two arrays that might hold our values,
+ * check them for either having arr.enum or arr.properties
+ */
+ if (hasPropertiesProp) {
+ defOrPropDescription =
+ defOrPropDescription[0].properties || defOrPropDescription[1].properties;
+ if (!defOrPropDescription) {
+ defOrPropDescription = defOrPropDescription[0].enum;
+ }
+ // TODO: manually implement stats and devtools like sourcemaps
+ } else if (hasEnumProp) {
+ const originalPropDesc: object = defOrPropDescription[0].enum;
+ // Array -> Object -> Merge objects into one for compat in manualOrListInput
+ defOrPropDescription = Object.keys(defOrPropDescription[0].enum)
+ .map(
+ (p: string): object => {
+ return Object.assign(
+ {},
+ {
+ [originalPropDesc[p]]: "noop"
+ }
+ );
}
- }
- return result;
- }, {});
+ )
+ .reduce((result: object, currentObject: object): object => {
+ for (const key in currentObject) {
+ if (currentObject.hasOwnProperty(key)) {
+ result[key] = currentObject[key];
+ }
+ }
+ return result;
+ }, {});
+ }
}
- }
- // WDS has its own schema, so we gonna need to check that too
- const webpackDevserverSchemaProp: ISchemaProperties =
- action === "devServer" ? webpackDevServerSchema : null;
- // Watch has a boolean arg, but we need to append to it manually
- if (action === "watch") {
- defOrPropDescription = {
- false: {},
- true: {},
- };
- }
- if (action === "mode") {
- defOrPropDescription = {
- development: {},
- production: {},
- };
- }
- action = temp;
- if (action === "resolveLoader") {
- defOrPropDescription = Object.assign(defOrPropDescription, {
- moduleExtensions: {},
- });
- }
- // If we've got a schema prop or devServer Schema Prop
- if (defOrPropDescription || webpackDevserverSchemaProp) {
- // Check for properties in definitions[action] or properties[action]
- if (defOrPropDescription) {
- if (action !== "devtool") {
- // Add the option of adding an own variable if the user wants
- defOrPropDescription = Object.assign(defOrPropDescription, {
- other: {},
- });
+ // WDS has its own schema, so we gonna need to check that too
+ const webpackDevserverSchemaProp: SchemaProperties =
+ action === "devServer" ? webpackDevServerSchema : null;
+ // Watch has a boolean arg, but we need to append to it manually
+ if (action === "watch") {
+ defOrPropDescription = {
+ false: {},
+ true: {}
+ };
+ }
+ if (action === "mode") {
+ defOrPropDescription = {
+ development: {},
+ production: {}
+ };
+ }
+ action = temp;
+ if (action === "resolveLoader") {
+ defOrPropDescription = Object.assign(defOrPropDescription, {
+ moduleExtensions: {}
+ });
+ }
+ // If we've got a schema prop or devServer Schema Prop
+ if (defOrPropDescription || webpackDevserverSchemaProp) {
+ // Check for properties in definitions[action] or properties[action]
+ if (defOrPropDescription) {
+ if (action !== "devtool") {
+ // Add the option of adding an own variable if the user wants
+ defOrPropDescription = Object.assign(defOrPropDescription, {
+ other: {}
+ });
+ } else {
+ // The schema doesn't have the source maps we can prompt, so add those
+ defOrPropDescription = Object.assign(defOrPropDescription, {
+ "cheap-eval-source-map": {},
+ "cheap-module-eval-source-map": {},
+ "cheap-module-source-map": {},
+ "cheap-source-map": {},
+ eval: {},
+ "eval-source-map": {},
+ "hidden-source-map": {},
+ "inline-cheap-module-source-map": {},
+ "inline-cheap-source-map": {},
+ "inline-source-map": {},
+ "nosources-source-map": {},
+ "source-map": {}
+ });
+ }
+ inputPrompt = List(
+ "actionAnswer",
+ `What do you want to add to ${action}?`,
+ Object.keys(defOrPropDescription)
+ );
+ // We know we're gonna append some deep prop like module.rule
+ isDeepProp[0] = true;
+ } else if (webpackDevserverSchemaProp) {
+ // Append the custom property option
+ webpackDevserverSchemaProp.properties = Object.assign(
+ webpackDevserverSchemaProp.properties,
+ {
+ other: {}
+ }
+ );
+ inputPrompt = List(
+ "actionAnswer",
+ `What do you want to add to ${action}?`,
+ Object.keys(webpackDevserverSchemaProp.properties)
+ );
+ // We know we are in a devServer.prop scenario
+ isDeepProp[0] = true;
} else {
- // The schema doesn't have the source maps we can prompt, so add those
- defOrPropDescription = Object.assign(defOrPropDescription, {
- "cheap-eval-source-map": {},
- "cheap-module-eval-source-map": {},
- "cheap-module-source-map": {},
- "cheap-source-map": {},
- "eval": {},
- "eval-source-map": {},
- "hidden-source-map": {},
- "inline-cheap-module-source-map": {},
- "inline-cheap-source-map": {},
- "inline-source-map": {},
- "nosources-source-map": {},
- "source-map": {},
- });
+ // manual input if non-existent
+ inputPrompt = manualOrListInput(action);
}
- inputPrompt = List(
- "actionAnswer",
- `What do you want to add to ${action}?`,
- Object.keys(defOrPropDescription),
- );
- // We know we're gonna append some deep prop like module.rule
- isDeepProp[0] = true;
- } else if (webpackDevserverSchemaProp) {
- // Append the custom property option
- webpackDevserverSchemaProp.properties = Object.assign(
- webpackDevserverSchemaProp.properties,
- {
- other: {},
- },
- );
- inputPrompt = List(
- "actionAnswer",
- `What do you want to add to ${action}?`,
- Object.keys(webpackDevserverSchemaProp.properties),
- );
- // We know we are in a devServer.prop scenario
- isDeepProp[0] = true;
} else {
- // manual input if non-existent
inputPrompt = manualOrListInput(action);
}
- } else {
- inputPrompt = manualOrListInput(action);
- }
- return this.prompt([
- inputPrompt,
- ]);
- })
- .then((answerToAction: {
- actionAnswer: string,
- }) => {
- if (!answerToAction) {
- done();
- return;
+ return this.prompt([inputPrompt]);
}
- /*
- * Plugins got their own logic,
- * find the names of each natively plugin and check if it matches
- */
- if (action === "plugins") {
- const pluginExist: string = glob
- .sync([
- "node_modules/webpack/lib/*Plugin.js",
- "node_modules/webpack/lib/**/*Plugin.js",
- ])
- .map((p: string): string =>
- p
- .split("/")
- .pop()
- .replace(".js", ""),
- )
- .find(
- (p: string): boolean => p.toLowerCase().indexOf(answerToAction.actionAnswer) >= 0,
- );
-
- if (pluginExist) {
- this.configuration.config.item = pluginExist;
- const pluginsSchemaPath: string = glob
- .sync([
- "node_modules/webpack/schemas/plugins/*Plugin.json",
- "node_modules/webpack/schemas/plugins/**/*Plugin.json",
- ])
- .find(
- (p: string): boolean =>
+ )
+ .then(
+ (answerToAction: { actionAnswer: string }): void => {
+ if (!answerToAction) {
+ done();
+ return;
+ }
+ /*
+ * Plugins got their own logic,
+ * find the names of each natively plugin and check if it matches
+ */
+ if (action === "plugins") {
+ const pluginExist: string = glob
+ .sync(["node_modules/webpack/lib/*Plugin.js", "node_modules/webpack/lib/**/*Plugin.js"])
+ .map(
+ (p: string): string =>
p
.split("/")
.pop()
- .replace(".json", "")
- .toLowerCase()
- .indexOf(answerToAction.actionAnswer) >= 0,
- );
- if (pluginsSchemaPath) {
- const constructorPrefix: string =
- pluginsSchemaPath.indexOf("optimize") >= 0
- ? "webpack.optimize"
- : "webpack";
- const resolvePluginsPath: string = path.resolve(pluginsSchemaPath);
- const pluginSchema: object = resolvePluginsPath
- ? require(resolvePluginsPath)
- : null;
- let pluginsSchemaProps: string[] = ["other"];
- if (pluginSchema) {
- Object.keys(pluginSchema)
- .filter((p: string): boolean => Array.isArray(pluginSchema[p]))
- .forEach((p: string): void => {
- Object.keys(pluginSchema[p]).forEach((n: string): void => {
- if (pluginSchema[p][n].properties) {
- pluginsSchemaProps = Object.keys(
- pluginSchema[p][n].properties,
+ .replace(".js", "")
+ )
+ .find((p: string): boolean => p.toLowerCase().indexOf(answerToAction.actionAnswer) >= 0);
+
+ if (pluginExist) {
+ this.configuration.config.item = pluginExist;
+ const pluginsSchemaPath: string = glob
+ .sync([
+ "node_modules/webpack/schemas/plugins/*Plugin.json",
+ "node_modules/webpack/schemas/plugins/**/*Plugin.json"
+ ])
+ .find(
+ (p: string): boolean =>
+ p
+ .split("/")
+ .pop()
+ .replace(".json", "")
+ .toLowerCase()
+ .indexOf(answerToAction.actionAnswer) >= 0
+ );
+ if (pluginsSchemaPath) {
+ const constructorPrefix: string =
+ pluginsSchemaPath.indexOf("optimize") >= 0 ? "webpack.optimize" : "webpack";
+ const resolvePluginsPath: string = path.resolve(pluginsSchemaPath);
+ const pluginSchema: object = resolvePluginsPath ? require(resolvePluginsPath) : null;
+ let pluginsSchemaProps: string[] = ["other"];
+ if (pluginSchema) {
+ Object.keys(pluginSchema)
+ .filter((p: string): boolean => Array.isArray(pluginSchema[p]))
+ .forEach(
+ (p: string): void => {
+ Object.keys(pluginSchema[p]).forEach(
+ (n: string): void => {
+ if (pluginSchema[p][n].properties) {
+ pluginsSchemaProps = Object.keys(
+ pluginSchema[p][n].properties
+ );
+ }
+ }
);
}
- });
- });
- }
+ );
+ }
- return this.prompt([
- List(
- "pluginsPropType",
- `What property do you want to add ${pluginExist}?`,
- pluginsSchemaProps,
- ),
- ]).then((pluginsPropAnswer: {
- pluginsPropType: string,
- }) => {
return this.prompt([
- Input(
- "pluginsPropTypeVal",
- `What value should ${pluginExist}.${
- pluginsPropAnswer.pluginsPropType
- } have?`,
- ),
- ]).then((valForProp: {
- pluginsPropTypeVal: string,
- }) => {
- this.configuration.config.webpackOptions[action] = {
- [`${constructorPrefix}.${pluginExist}`]: {
- [pluginsPropAnswer.pluginsPropType]:
- valForProp.pluginsPropTypeVal,
- },
- };
- done();
- });
- });
+ List(
+ "pluginsPropType",
+ `What property do you want to add ${pluginExist}?`,
+ pluginsSchemaProps
+ )
+ ]).then(
+ (pluginsPropAnswer: { pluginsPropType: string }): Promise<{}> => {
+ return this.prompt([
+ Input(
+ "pluginsPropTypeVal",
+ `What value should ${pluginExist}.${
+ pluginsPropAnswer.pluginsPropType
+ } have?`
+ )
+ ]).then(
+ (valForProp: { pluginsPropTypeVal: string }): void => {
+ this.configuration.config.webpackOptions[action] = {
+ [`${constructorPrefix}.${pluginExist}`]: {
+ [pluginsPropAnswer.pluginsPropType]:
+ valForProp.pluginsPropTypeVal
+ }
+ };
+ done();
+ }
+ );
+ }
+ );
+ } else {
+ this.configuration.config.webpackOptions[action] = `new webpack.${pluginExist}`;
+ done();
+ }
} else {
- this.configuration.config.webpackOptions[
- action
- ] = `new webpack.${pluginExist}`;
- done();
+ // If its not in webpack, check npm
+ npmExists(answerToAction.actionAnswer).then(
+ (p: boolean): void => {
+ if (p) {
+ this.dependencies.push(answerToAction.actionAnswer);
+ const normalizePluginName = answerToAction.actionAnswer.replace(
+ "-webpack-plugin",
+ "Plugin"
+ );
+ const pluginName = replaceAt(
+ normalizePluginName,
+ 0,
+ normalizePluginName.charAt(0).toUpperCase()
+ );
+ this.configuration.config.topScope.push(
+ `const ${pluginName} = require("${answerToAction.actionAnswer}")`
+ );
+ this.configuration.config.webpackOptions[action] = `new ${pluginName}`;
+ this.configuration.config.item = answerToAction.actionAnswer;
+ done();
+ this.scheduleInstallTask(getPackageManager(), this.dependencies, {
+ "save-dev": true
+ });
+ } else {
+ console.error(
+ answerToAction.actionAnswer,
+ "doesn't exist on NPM or is built in webpack, please check for any misspellings."
+ );
+ process.exit(0);
+ }
+ }
+ );
}
} else {
- // If its not in webpack, check npm
- npmExists(answerToAction.actionAnswer)
- .then((p: string) => {
- if (p) {
- this.dependencies.push(answerToAction.actionAnswer);
- const normalizePluginName = answerToAction.actionAnswer.replace(
- "-webpack-plugin",
- "Plugin",
- );
- const pluginName = replaceAt(
- normalizePluginName,
- 0,
- normalizePluginName.charAt(0).toUpperCase(),
- );
- this.configuration.config.topScope.push(
- `const ${pluginName} = require("${
- answerToAction.actionAnswer
- }")`,
- );
- this.configuration.config.webpackOptions[
- action
- ] = `new ${pluginName}`;
- this.configuration.config.item = answerToAction.actionAnswer;
- done();
- this.scheduleInstallTask(getPackageManager(), this.dependencies, {
- "save-dev": true,
- });
- } else {
- console.error(
- answerToAction.actionAnswer,
- "doesn't exist on NPM or is built in webpack, please check for any misspellings.",
- );
- process.exit(0);
+ // If we're in the scenario with a deep-property
+ if (isDeepProp[0]) {
+ isDeepProp[1] = answerToAction.actionAnswer;
+ if (
+ isDeepProp[1] !== "other" &&
+ (action === "devtool" || action === "watch" || action === "mode")
+ ) {
+ this.configuration.config.item = action;
+ this.configuration.config.webpackOptions[action] = answerToAction.actionAnswer;
+ done();
+ return;
+ }
+ // Either we are adding directly at the property, else we're in a prop.theOne scenario
+ const actionMessage =
+ isDeepProp[1] === "other"
+ ? `What do you want the key on ${action} to be? (press enter if you want it directly as a value on the property)`
+ : `What do you want the value of ${isDeepProp[1]} to be?`;
+
+ this.prompt([Input("deepProp", actionMessage)]).then(
+ (deepPropAns: { deepProp: string }): void => {
+ // The other option needs to be validated of either being empty or not
+ if (isDeepProp[1] === "other") {
+ const othersDeepPropKey: string = deepPropAns.deepProp
+ ? `What do you want the value of ${deepPropAns.deepProp} to be?` // eslint-disable-line
+ : `What do you want to be the value of ${action} to be?`;
+ // Push the answer to the array we have created, so we can use it later
+ isDeepProp.push(deepPropAns.deepProp);
+ this.prompt([Input("innerProp", othersDeepPropKey)]).then(
+ (innerPropAns: { innerProp }): void => {
+ // Check length, if it has none, add the prop directly on the given action
+ if (isDeepProp[2].length === 0) {
+ this.configuration.config.item = action;
+ this.configuration.config.webpackOptions[action] =
+ innerPropAns.innerProp;
+ } else {
+ // If not, we're adding to something like devServer.myProp
+ this.configuration.config.item = action + "." + isDeepProp[2];
+ this.configuration.config.webpackOptions[action] = {
+ [isDeepProp[2]]: innerPropAns.innerProp
+ };
+ }
+ done();
+ }
+ );
+ } else {
+ // We got the schema prop, we've correctly prompted it, and can add it directly
+ this.configuration.config.item = `${action}.${isDeepProp[1]}`;
+ this.configuration.config.webpackOptions[action] = {
+ [isDeepProp[1]]: deepPropAns.deepProp
+ };
+ done();
+ }
}
- });
- }
- } else {
- // If we're in the scenario with a deep-property
- if (isDeepProp[0]) {
- isDeepProp[1] = answerToAction.actionAnswer;
- if (
- isDeepProp[1] !== "other" &&
- (action === "devtool" || action === "watch" || action === "mode")
- ) {
+ );
+ } else {
+ // We're asking for input-only
this.configuration.config.item = action;
- this.configuration.config.webpackOptions[action] =
- answerToAction.actionAnswer;
+ this.configuration.config.webpackOptions[action] = answerToAction.actionAnswer;
done();
- return;
}
- // Either we are adding directly at the property, else we're in a prop.theOne scenario
- const actionMessage =
- isDeepProp[1] === "other"
- ? `What do you want the key on ${
- action
- } to be? (press enter if you want it directly as a value on the property)`
- : `What do you want the value of ${isDeepProp[1]} to be?`;
-
- this.prompt([
- Input("deepProp", actionMessage),
- ]).then(
- (deepPropAns: {
- deepProp: string,
- }) => {
- // The other option needs to be validated of either being empty or not
- if (isDeepProp[1] === "other") {
- const othersDeepPropKey: string = deepPropAns.deepProp
- ? `What do you want the value of ${
- deepPropAns.deepProp
- } to be?` // eslint-disable-line
- : `What do you want to be the value of ${action} to be?`;
- // Push the answer to the array we have created, so we can use it later
- isDeepProp.push(deepPropAns.deepProp);
- this.prompt([
- Input("innerProp", othersDeepPropKey),
- ]).then(
- (innerPropAns: {
- innerProp,
- }) => {
- // Check length, if it has none, add the prop directly on the given action
- if (isDeepProp[2].length === 0) {
- this.configuration.config.item = action;
- this.configuration.config.webpackOptions[action] =
- innerPropAns.innerProp;
- } else {
- // If not, we're adding to something like devServer.myProp
- this.configuration.config.item =
- action + "." + isDeepProp[2];
- this.configuration.config.webpackOptions[action] = {
- [isDeepProp[2]]: innerPropAns.innerProp,
- };
- }
- done();
- },
- );
- } else {
- // We got the schema prop, we've correctly prompted it, and can add it directly
- this.configuration.config.item = `${action}.${isDeepProp[1]}`;
- this.configuration.config.webpackOptions[action] = {
- [isDeepProp[1]]: deepPropAns.deepProp,
- };
- done();
- }
- },
- );
- } else {
- // We're asking for input-only
- this.configuration.config.item = action;
- this.configuration.config.webpackOptions[action] =
- answerToAction.actionAnswer;
- done();
}
}
- });
+ );
}
- public writing() {
+ public writing(): void {
this.config.set("configuration", this.configuration);
}
}
diff --git a/packages/generators/addon-generator.ts b/packages/generators/addon-generator.ts
index 7f83dddf104..d81c2d0b378 100644
--- a/packages/generators/addon-generator.ts
+++ b/packages/generators/addon-generator.ts
@@ -3,7 +3,8 @@ import * as path from "path";
import Generator = require("yeoman-generator");
import * as copyUtils from "@webpack-cli/utils/copy-utils";
-import { IInquirerScaffoldObject } from "@webpack-cli/webpack-scaffold";
+import { InquirerScaffoldObject } from "@webpack-cli/webpack-scaffold";
+import { YeoGenerator } from "../generate-loader/types/Yeoman";
/**
* Creates a Yeoman Generator that generates a project conforming
@@ -27,58 +28,58 @@ import { IInquirerScaffoldObject } from "@webpack-cli/webpack-scaffold";
* @returns {Generator} A class extending Generator
*/
export default function addonGenerator(
- prompts: IInquirerScaffoldObject[],
+ prompts: InquirerScaffoldObject[],
templateDir: string,
copyFiles: string[],
copyTemplateFiles: string[],
- templateFn: Function,
-) {
+ templateFn: Function
+): YeoGenerator {
return class AddOnGenerator extends Generator {
- public props: IInquirerScaffoldObject;
- private copy: (value: string, index: number, array: string[]) => void;
- private copyTpl: (value: string, index: number, array: string[]) => void;
+ public props: InquirerScaffoldObject;
+ public copy: (value: string, index: number, array: string[]) => void;
+ public copyTpl: (value: string, index: number, array: string[]) => void;
public prompting(): Promise<{}> {
- return this.prompt(prompts)
- .then((props: IInquirerScaffoldObject): void => {
+ return this.prompt(prompts).then(
+ (props: InquirerScaffoldObject): void => {
this.props = props;
- });
+ }
+ );
}
- public default() {
+ public default(): void {
const currentDirName = path.basename(this.destinationPath());
if (currentDirName !== this.props.name) {
this.log(`
Your project must be inside a folder named ${this.props.name}
I will create this folder for you.
`);
- mkdirp(this.props.name, (err: object) => {
- console.error("Failed to create directory", err);
- });
+ mkdirp(
+ this.props.name,
+ (err: object): void => {
+ console.error("Failed to create directory", err);
+ }
+ );
const pathToProjectDir: string = this.destinationPath(this.props.name);
this.destinationRoot(pathToProjectDir);
}
}
- public writing() {
+ public writing(): void {
this.copy = copyUtils.generatorCopy(this, templateDir);
- this.copyTpl = copyUtils.generatorCopyTpl(
- this,
- templateDir,
- templateFn(this),
- );
+ this.copyTpl = copyUtils.generatorCopyTpl(this, templateDir, templateFn(this));
copyFiles.forEach(this.copy);
copyTemplateFiles.forEach(this.copyTpl);
}
- public install() {
+ public install(): void {
this.npmInstall(["webpack-defaults", "bluebird"], {
- "save-dev": true,
+ "save-dev": true
});
}
- public end() {
+ public end(): void {
this.spawnCommand("npm", ["run", "defaults"]);
}
};
diff --git a/packages/generators/init-generator.ts b/packages/generators/init-generator.ts
index 90207de3c61..c33e038a087 100644
--- a/packages/generators/init-generator.ts
+++ b/packages/generators/init-generator.ts
@@ -3,13 +3,9 @@ import * as logSymbols from "log-symbols";
import Generator = require("yeoman-generator");
import { getPackageManager } from "@webpack-cli/utils/package-manager";
-import {
- Confirm,
- Input,
- List,
-} from "@webpack-cli/webpack-scaffold";
+import { Confirm, Input, List } from "@webpack-cli/webpack-scaffold";
-import { IWebpackOptions } from "./types";
+import { WebpackOptions } from "./types";
import entryQuestions from "./utils/entry";
import getBabelPlugin from "./utils/module";
import getDefaultPlugins from "./utils/plugins";
@@ -30,32 +26,33 @@ export default class InitGenerator extends Generator {
private dependencies: string[];
private configuration: {
config: {
- configName?: string,
- topScope?: string[],
- webpackOptions?: IWebpackOptions,
- },
+ configName?: string;
+ topScope?: string[];
+ webpackOptions?: WebpackOptions;
+ };
};
- constructor(args, opts) {
+ public constructor(args, opts) {
super(args, opts);
this.isProd = false;
- this.usingDefaults = false,
- this.dependencies = [
- "webpack",
- "webpack-cli",
- "terser-webpack-plugin",
- "babel-plugin-syntax-dynamic-import",
- ];
+ (this.usingDefaults = false),
+ (this.dependencies = [
+ "webpack",
+ "webpack-cli",
+ "terser-webpack-plugin",
+ "babel-plugin-syntax-dynamic-import"
+ ]);
this.configuration = {
config: {
topScope: [],
- webpackOptions: {},
- },
+ webpackOptions: {}
+ }
};
}
- public prompting() {
- const done: (_?: void) => void | boolean = this.async();
+ // eslint-disable-next-line
+ public prompting(): any {
+ const done: () => void | boolean = this.async();
const self: this = this;
let regExpForStyles: string;
let ExtractUseProps: object[];
@@ -65,389 +62,361 @@ export default class InitGenerator extends Generator {
logSymbols.info +
chalk.blue(" INFO ") +
"For more information and a detailed description of each question, have a look at " +
- chalk.bold.green(
- "https://github.com/webpack/webpack-cli/blob/master/INIT.md",
- ) +
- "\n",
+ chalk.bold.green("https://github.com/webpack/webpack-cli/blob/master/INIT.md") +
+ "\n"
);
process.stdout.write(
logSymbols.info +
chalk.blue(" INFO ") +
"Alternatively, run `webpack(-cli) --help` for usage info." +
- "\n\n",
+ "\n\n"
);
this.configuration.config.webpackOptions.module = {
- rules: [],
+ rules: []
};
this.configuration.config.topScope.push(
"const webpack = require('webpack')",
"const path = require('path')",
- "\n",
+ "\n"
);
- return this.prompt([
- Confirm("entryType", "Will your application have multiple bundles?", false),
- ])
- .then((entryTypeAnswer: {
- entryType: boolean;
- }) => {
- // Ask different questions for entry points
- return entryQuestions(self, entryTypeAnswer);
- })
- .then((entryOptions: object | string) => {
- if (typeof entryOptions === "string" && entryOptions.length > 0) {
+ return this.prompt([Confirm("entryType", "Will your application have multiple bundles?", false)])
+ .then(
+ (entryTypeAnswer: { entryType: boolean }): Promise<{}> => {
+ // Ask different questions for entry points
+ return entryQuestions(self, entryTypeAnswer);
+ }
+ )
+ .then(
+ (entryOptions: object | string): Promise<{}> => {
+ if (typeof entryOptions === "string" && entryOptions.length > 0) {
+ return this.prompt([
+ Input("outputType", "In which folder do you want to store your generated bundles? (dist):")
+ ]);
+ }
+ if (entryOptions !== '""') {
+ this.configuration.config.webpackOptions.entry = entryOptions;
+ }
return this.prompt([
- Input(
- "outputType",
- "In which folder do you want to store your generated bundles? (dist):",
- ),
+ Input("outputType", "In which folder do you want to store your generated bundles? (dist):")
]);
}
- if (entryOptions !== "\"\"") {
- this.configuration.config.webpackOptions.entry = entryOptions;
- }
- return this.prompt([
- Input(
- "outputType",
- "In which folder do you want to store your generated bundles? (dist):",
- ),
- ]);
- })
- .then((outputTypeAnswer: {
- outputType: string;
- }) => {
- // As entry is not required anymore and we dont set it to be an empty string or """""
- // it can be undefined so falsy check is enough (vs entry.length);
- if (
- !this.configuration.config.webpackOptions.entry &&
- !this.usingDefaults
- ) {
- this.configuration.config.webpackOptions.output = {
- chunkFilename: "'[name].[chunkhash].js'",
- filename: "'[name].[chunkhash].js'",
- };
- } else if (!this.usingDefaults) {
- this.configuration.config.webpackOptions.output = {
- filename: "'[name].[chunkhash].js'",
- };
+ )
+ .then(
+ (outputTypeAnswer: { outputType: string }): void => {
+ // As entry is not required anymore and we dont set it to be an empty string or """""
+ // it can be undefined so falsy check is enough (vs entry.length);
+ if (!this.configuration.config.webpackOptions.entry && !this.usingDefaults) {
+ this.configuration.config.webpackOptions.output = {
+ chunkFilename: "'[name].[chunkhash].js'",
+ filename: "'[name].[chunkhash].js'"
+ };
+ } else if (!this.usingDefaults) {
+ this.configuration.config.webpackOptions.output = {
+ filename: "'[name].[chunkhash].js'"
+ };
+ }
+ if (!this.usingDefaults && outputTypeAnswer.outputType.length) {
+ this.configuration.config.webpackOptions.output.path = `path.resolve(__dirname, '${
+ outputTypeAnswer.outputType
+ }')`;
+ }
}
- if (!this.usingDefaults && outputTypeAnswer.outputType.length) {
- this.configuration.config.webpackOptions.output.path =
- `path.resolve(__dirname, '${outputTypeAnswer.outputType}')`;
+ )
+ .then(
+ (): void => {
+ this.isProd = this.usingDefaults ? true : false;
+ this.configuration.config.configName = this.isProd ? "prod" : "config";
+ if (!this.isProd) {
+ this.configuration.config.webpackOptions.mode = "'development'";
+ }
+ this.configuration.config.webpackOptions.plugins = this.isProd ? [] : getDefaultPlugins();
+ return this.prompt([Confirm("babelConfirm", "Will you be using ES2015?")]);
}
- })
- .then((_: void) => {
- this.isProd = this.usingDefaults ? true : false;
- this.configuration.config.configName = this.isProd ? "prod" : "config";
- if (!this.isProd) {
- this.configuration.config.webpackOptions.mode = "'development'";
+ )
+ .then(
+ (babelConfirmAnswer: { babelConfirm: boolean }): void => {
+ if (babelConfirmAnswer.babelConfirm) {
+ this.configuration.config.webpackOptions.module.rules.push(getBabelPlugin());
+ this.dependencies.push("babel-loader", "@babel/core", "@babel/preset-env");
+ }
}
- this.configuration.config.webpackOptions.plugins = this.isProd ? [] : getDefaultPlugins();
- return this.prompt([
- Confirm("babelConfirm", "Will you be using ES2015?"),
- ]);
- })
- .then((babelConfirmAnswer: {
- babelConfirm: boolean;
- }) => {
- if (babelConfirmAnswer.babelConfirm) {
- this.configuration.config.webpackOptions.module.rules.push(
- getBabelPlugin(),
- );
- this.dependencies.push(
- "babel-loader",
- "@babel/core",
- "@babel/preset-env",
- );
+ )
+ .then(
+ (): void => {
+ return this.prompt([
+ List("stylingType", "Will you use one of the below CSS solutions?", [
+ "No",
+ "CSS",
+ "SASS",
+ "LESS",
+ "PostCSS"
+ ])
+ ]);
}
- })
- .then((_: void) => {
- return this.prompt([
- List("stylingType", "Will you use one of the below CSS solutions?", [
- "No",
- "CSS",
- "SASS",
- "LESS",
- "PostCSS",
- ]),
- ]);
- })
- .then((stylingTypeAnswer: {
- stylingType: string;
- }) => {
- ExtractUseProps = [];
- switch (stylingTypeAnswer.stylingType) {
- case "SASS":
- this.dependencies.push(
- "sass-loader",
- "node-sass",
- "style-loader",
- "css-loader",
- );
- regExpForStyles = `${new RegExp(/\.(scss|css)$/)}`;
- if (this.isProd) {
- ExtractUseProps.push(
- {
- loader: "'css-loader'",
- options: {
- sourceMap: true,
+ )
+ .then(
+ (stylingTypeAnswer: { stylingType: string }): void => {
+ ExtractUseProps = [];
+ switch (stylingTypeAnswer.stylingType) {
+ case "SASS":
+ this.dependencies.push("sass-loader", "node-sass", "style-loader", "css-loader");
+ regExpForStyles = `${new RegExp(/\.(scss|css)$/)}`;
+ if (this.isProd) {
+ ExtractUseProps.push(
+ {
+ loader: "'css-loader'",
+ options: {
+ sourceMap: true
+ }
},
- },
- {
- loader: "'sass-loader'",
- options: {
- sourceMap: true,
+ {
+ loader: "'sass-loader'",
+ options: {
+ sourceMap: true
+ }
+ }
+ );
+ } else {
+ ExtractUseProps.push(
+ {
+ loader: "'style-loader'"
},
- },
- );
- } else {
- ExtractUseProps.push(
- {
- loader: "'style-loader'",
- },
- {
- loader: "'css-loader'",
- },
- {
- loader: "'sass-loader'",
- },
- );
- }
- break;
- case "LESS":
- regExpForStyles = `${new RegExp(/\.(less|css)$/)}`;
- this.dependencies.push(
- "less-loader",
- "less",
- "style-loader",
- "css-loader",
- );
- if (this.isProd) {
- ExtractUseProps.push(
- {
- loader: "'css-loader'",
- options: {
- sourceMap: true,
+ {
+ loader: "'css-loader'"
},
- },
- {
- loader: "'less-loader'",
- options: {
- sourceMap: true,
+ {
+ loader: "'sass-loader'"
+ }
+ );
+ }
+ break;
+ case "LESS":
+ regExpForStyles = `${new RegExp(/\.(less|css)$/)}`;
+ this.dependencies.push("less-loader", "less", "style-loader", "css-loader");
+ if (this.isProd) {
+ ExtractUseProps.push(
+ {
+ loader: "'css-loader'",
+ options: {
+ sourceMap: true
+ }
},
- },
- );
- } else {
- ExtractUseProps.push(
- {
- loader: "'css-loader'",
- options: {
- sourceMap: true,
+ {
+ loader: "'less-loader'",
+ options: {
+ sourceMap: true
+ }
+ }
+ );
+ } else {
+ ExtractUseProps.push(
+ {
+ loader: "'css-loader'",
+ options: {
+ sourceMap: true
+ }
},
- },
- {
- loader: "'less-loader'",
- options: {
- sourceMap: true,
- },
- },
+ {
+ loader: "'less-loader'",
+ options: {
+ sourceMap: true
+ }
+ }
+ );
+ }
+ break;
+ case "PostCSS":
+ this.configuration.config.topScope.push(
+ tooltip.postcss(),
+ "const autoprefixer = require('autoprefixer');",
+ "const precss = require('precss');",
+ "\n"
);
- }
- break;
- case "PostCSS":
- this.configuration.config.topScope.push(
- tooltip.postcss(),
- "const autoprefixer = require('autoprefixer');",
- "const precss = require('precss');",
- "\n",
- );
- this.dependencies.push(
- "style-loader",
- "css-loader",
- "postcss-loader",
- "precss",
- "autoprefixer",
- );
- regExpForStyles = `${new RegExp(/\.css$/)}`;
- if (this.isProd) {
- ExtractUseProps.push(
- {
- loader: "'css-loader'",
- options: {
- importLoaders: 1,
- sourceMap: true,
+ this.dependencies.push(
+ "style-loader",
+ "css-loader",
+ "postcss-loader",
+ "precss",
+ "autoprefixer"
+ );
+ regExpForStyles = `${new RegExp(/\.css$/)}`;
+ if (this.isProd) {
+ ExtractUseProps.push(
+ {
+ loader: "'css-loader'",
+ options: {
+ importLoaders: 1,
+ sourceMap: true
+ }
},
- },
- {
- loader: "'postcss-loader'",
- options: {
- plugins: `function () {
+ {
+ loader: "'postcss-loader'",
+ options: {
+ plugins: `function () {
return [
precss,
autoprefixer
];
- }`,
+ }`
+ }
+ }
+ );
+ } else {
+ ExtractUseProps.push(
+ {
+ loader: "'style-loader'"
},
- },
- );
- } else {
- ExtractUseProps.push(
- {
- loader: "'style-loader'",
- },
- {
- loader: "'css-loader'",
- options: {
- importLoaders: 1,
- sourceMap: true,
+ {
+ loader: "'css-loader'",
+ options: {
+ importLoaders: 1,
+ sourceMap: true
+ }
},
- },
- {
- loader: "'postcss-loader'",
- options: {
- plugins: `function () {
+ {
+ loader: "'postcss-loader'",
+ options: {
+ plugins: `function () {
return [
precss,
autoprefixer
];
- }`,
- },
- },
- );
- }
- break;
- case "CSS":
- this.dependencies.push("style-loader", "css-loader");
- regExpForStyles = `${new RegExp(/\.css$/)}`;
- if (this.isProd) {
- ExtractUseProps.push({
- loader: "'css-loader'",
- options: {
- sourceMap: true,
- },
- });
- } else {
- ExtractUseProps.push(
- {
- loader: "'style-loader'",
+ }`
+ }
+ }
+ );
+ }
+ break;
+ case "CSS":
+ this.dependencies.push("style-loader", "css-loader");
+ regExpForStyles = `${new RegExp(/\.css$/)}`;
+ if (this.isProd) {
+ ExtractUseProps.push({
+ loader: "'css-loader'",
options: {
- sourceMap: true,
+ sourceMap: true
+ }
+ });
+ } else {
+ ExtractUseProps.push(
+ {
+ loader: "'style-loader'",
+ options: {
+ sourceMap: true
+ }
},
- },
- {
- loader: "'css-loader'",
- },
- );
- }
- break;
- default:
- regExpForStyles = null;
- }
- })
- .then((_: void) => {
- if (this.isProd) {
- // Ask if the user wants to use extractPlugin
- return this.prompt([
- Input(
- "extractPlugin",
- "If you want to bundle your CSS files, what will you name the bundle? (press enter to skip)",
- ),
- ]);
+ {
+ loader: "'css-loader'"
+ }
+ );
+ }
+ break;
+ default:
+ regExpForStyles = null;
+ }
}
- })
- .then((extractPluginAnswer: {
- extractPlugin: string;
- }) => {
- if (regExpForStyles) {
+ )
+ .then(
+ (): void => {
if (this.isProd) {
- const cssBundleName: string = extractPluginAnswer.extractPlugin;
- this.configuration.config.topScope.push(tooltip.cssPlugin());
- this.dependencies.push("mini-css-extract-plugin");
+ // Ask if the user wants to use extractPlugin
+ return this.prompt([
+ Input(
+ "extractPlugin",
+ "If you want to bundle your CSS files, what will you name the bundle? (press enter to skip)"
+ )
+ ]);
+ }
+ }
+ )
+ .then(
+ (extractPluginAnswer: { extractPlugin: string }): void => {
+ if (regExpForStyles) {
+ if (this.isProd) {
+ const cssBundleName: string = extractPluginAnswer.extractPlugin;
+ this.configuration.config.topScope.push(tooltip.cssPlugin());
+ this.dependencies.push("mini-css-extract-plugin");
- if (cssBundleName.length !== 0) {
- this.configuration.config.webpackOptions.plugins.push(
- // TODO: use [contenthash] after it is supported
- `new MiniCssExtractPlugin({ filename:'${cssBundleName}.[chunkhash].css' })`,
- );
- } else {
- this.configuration.config.webpackOptions.plugins.push(
- "new MiniCssExtractPlugin({ filename:'style.css' })",
- );
- }
+ if (cssBundleName.length !== 0) {
+ (this.configuration.config.webpackOptions.plugins as string[]).push(
+ // TODO: use [contenthash] after it is supported
+ `new MiniCssExtractPlugin({ filename:'${cssBundleName}.[chunkhash].css' })`
+ );
+ } else {
+ (this.configuration.config.webpackOptions.plugins as string[]).push(
+ "new MiniCssExtractPlugin({ filename:'style.css' })"
+ );
+ }
- ExtractUseProps.unshift({
- loader: "MiniCssExtractPlugin.loader",
- });
+ ExtractUseProps.unshift({
+ loader: "MiniCssExtractPlugin.loader"
+ });
- const moduleRulesObj = {
- test: regExpForStyles,
- use: ExtractUseProps,
- };
+ const moduleRulesObj = {
+ test: regExpForStyles,
+ use: ExtractUseProps
+ };
- this.configuration.config.webpackOptions.module.rules.push(
- moduleRulesObj,
- );
- this.configuration.config.topScope.push(
- "const MiniCssExtractPlugin = require('mini-css-extract-plugin');",
- "\n",
- );
- } else {
- const moduleRulesObj: {
- test: string;
- use: object[];
- } = {
- test: regExpForStyles,
- use: ExtractUseProps,
- };
+ this.configuration.config.webpackOptions.module.rules.push(moduleRulesObj);
+ this.configuration.config.topScope.push(
+ "const MiniCssExtractPlugin = require('mini-css-extract-plugin');",
+ "\n"
+ );
+ } else {
+ const moduleRulesObj: {
+ test: string;
+ use: object[];
+ } = {
+ test: regExpForStyles,
+ use: ExtractUseProps
+ };
- this.configuration.config.webpackOptions.module.rules.push(
- moduleRulesObj,
- );
+ this.configuration.config.webpackOptions.module.rules.push(moduleRulesObj);
+ }
}
- }
- // add splitChunks options for transparency
- // defaults coming from: https://webpack.js.org/plugins/split-chunks-plugin/#optimization-splitchunks
- this.configuration.config.topScope.push(tooltip.splitChunks());
- this.configuration.config.webpackOptions.optimization = {
- splitChunks: {
- cacheGroups: {
- vendors: {
- priority: -10,
- test: "/[\\\\/]node_modules[\\\\/]/",
+ // add splitChunks options for transparency
+ // defaults coming from: https://webpack.js.org/plugins/split-chunks-plugin/#optimization-splitchunks
+ this.configuration.config.topScope.push(tooltip.splitChunks());
+ this.configuration.config.webpackOptions.optimization = {
+ splitChunks: {
+ cacheGroups: {
+ vendors: {
+ priority: -10,
+ test: "/[\\\\/]node_modules[\\\\/]/"
+ }
},
- },
- chunks: "'async'",
- minChunks: 1,
- minSize: 30000,
- // for production name is recommended to be off
- name: !this.isProd,
- },
- };
- done();
- });
+ chunks: "'async'",
+ minChunks: 1,
+ minSize: 30000,
+ // for production name is recommended to be off
+ name: !this.isProd
+ }
+ };
+ done();
+ }
+ );
}
- public installPlugins() {
+ public installPlugins(): void {
if (this.isProd) {
- this.dependencies = this.dependencies.filter(
- (p: string): boolean => p !== "terser-webpack-plugin",
- );
+ this.dependencies = this.dependencies.filter((p: string): boolean => p !== "terser-webpack-plugin");
} else {
this.configuration.config.topScope.push(
tooltip.terser(),
"const TerserPlugin = require('terser-webpack-plugin');",
- "\n",
+ "\n"
);
}
const packager = getPackageManager();
const opts: {
- dev?: boolean,
- "save-dev"?: boolean,
+ dev?: boolean;
+ "save-dev"?: boolean;
} = packager === "yarn" ? { dev: true } : { "save-dev": true };
this.scheduleInstallTask(packager, this.dependencies, opts);
}
- public writing() {
+ public writing(): void {
this.config.set("configuration", this.configuration);
}
}
diff --git a/packages/generators/remove-generator.ts b/packages/generators/remove-generator.ts
index d81bdeeaf94..a1ab387b847 100644
--- a/packages/generators/remove-generator.ts
+++ b/packages/generators/remove-generator.ts
@@ -4,7 +4,7 @@ import Generator = require("yeoman-generator");
import PROP_TYPES from "@webpack-cli/utils/prop-types";
import { List } from "@webpack-cli/webpack-scaffold";
-import { IWebpackOptions } from "./types";
+import { WebpackOptions } from "./types";
/**
*
@@ -18,19 +18,19 @@ import { IWebpackOptions } from "./types";
export default class RemoveGenerator extends Generator {
private configuration: {
config: {
- configName?: string,
- topScope?: string[],
- webpackOptions?: IWebpackOptions,
- },
+ configName?: string;
+ topScope?: string[];
+ webpackOptions?: WebpackOptions;
+ };
};
- private webpackOptions: IWebpackOptions | string;
+ private webpackOptions: WebpackOptions | string;
- constructor(args, opts) {
+ public constructor(args, opts) {
super(args, opts);
this.configuration = {
config: {
- webpackOptions: {},
- },
+ webpackOptions: {}
+ }
};
let configPath = path.resolve(process.cwd(), "webpack.config.js");
@@ -49,90 +49,96 @@ export default class RemoveGenerator extends Generator {
public getModuleLoadersNames(): string[] {
if (typeof this.webpackOptions === "object") {
if (this.webpackOptions.module && this.webpackOptions.module.rules) {
- return this.webpackOptions.module.rules.map((rule: {
- loader: string;
- }) => rule ? rule.loader : null);
+ return this.webpackOptions.module.rules.map(
+ (rule: { loader: string }): string | null => (rule ? rule.loader : null)
+ );
}
}
}
- public prompting() {
- const done: (_?: void) => void | boolean = this.async();
+ public prompting(): Promise<{}> {
+ const done: () => void | boolean = this.async();
let propValue: object | string | boolean;
- return this.prompt([
- List(
- "propType",
- "Which property do you want to remove?",
- Array.from(this.getPropTypes()),
- ),
- ])
- .then(({ propType }: { propType: string }): Promise<{}> => {
- if (!PROP_TYPES.has(propType)) {
- console.error("Invalid webpack config prop");
- return;
- }
+ return this.prompt([List("propType", "Which property do you want to remove?", Array.from(this.getPropTypes()))])
+ .then(
+ ({ propType }: { propType: string }): Promise<{}> => {
+ if (!PROP_TYPES.has(propType)) {
+ console.error("Invalid webpack config prop");
+ return;
+ }
- propValue = this.webpackOptions[propType];
- if (typeof propValue === "object") {
- if (Array.isArray(propValue)) {
- return this.prompt([
- List(
- "keyType",
- `Which key do you want to remove from ${propType}?`,
- Array.from(propValue),
- ),
- ]).then(({ keyType }: { keyType: string }): void => {
- this.configuration.config.webpackOptions[propType] = [ keyType ];
- });
- } else {
- return this.prompt([
- List(
- "keyType",
- `Which key do you want to remove from ${propType}?`,
- Array.from(Object.keys(propValue)),
- ),
- ])
- .then(({ keyType }: { keyType: string }): Promise<{}> => {
- if (propType === "module" && keyType === "rules") {
- return this.prompt([
- List(
- "rule",
- "Which loader do you want to remove?",
- Array.from(this.getModuleLoadersNames()),
- ),
- ])
- .then(({ rule }: { rule: string }): void => {
- if (typeof this.webpackOptions === "object") {
- const loaderIndex: number = this.getModuleLoadersNames().indexOf(rule);
- const loader: object = this.webpackOptions.module.rules[loaderIndex];
- this.configuration.config.webpackOptions.module = {
- rules: [ loader ],
- };
+ propValue = this.webpackOptions[propType];
+ if (typeof propValue === "object") {
+ if (Array.isArray(propValue)) {
+ return this.prompt([
+ List(
+ "keyType",
+ `Which key do you want to remove from ${propType}?`,
+ Array.from(propValue)
+ )
+ ]).then(
+ ({ keyType }: { keyType: string }): void => {
+ this.configuration.config.webpackOptions[propType] = [keyType];
+ }
+ );
+ } else {
+ return this.prompt([
+ List(
+ "keyType",
+ `Which key do you want to remove from ${propType}?`,
+ Array.from(Object.keys(propValue))
+ )
+ ]).then(
+ ({ keyType }: { keyType: string }): Promise<{}> => {
+ if (propType === "module" && keyType === "rules") {
+ return this.prompt([
+ List(
+ "rule",
+ "Which loader do you want to remove?",
+ Array.from(this.getModuleLoadersNames())
+ )
+ ]).then(
+ ({ rule }: { rule: string }): void => {
+ if (typeof this.webpackOptions === "object") {
+ const loaderIndex: number = this.getModuleLoadersNames().indexOf(
+ rule
+ );
+ const loader: object = this.webpackOptions.module.rules[
+ loaderIndex
+ ];
+ this.configuration.config.webpackOptions.module = {
+ rules: [loader]
+ };
+ }
}
- });
- } else {
- // remove the complete prop object if there is only one key
- if (Object.keys(this.webpackOptions[propType]).length <= 1) {
- this.configuration.config.webpackOptions[propType] = null;
+ );
} else {
- this.configuration.config.webpackOptions[propType] = {
- [keyType]: null,
- };
+ // remove the complete prop object if there is only one key
+ if (Object.keys(this.webpackOptions[propType]).length <= 1) {
+ this.configuration.config.webpackOptions[propType] = null;
+ } else {
+ this.configuration.config.webpackOptions[propType] = {
+ [keyType]: null
+ };
+ }
}
}
- });
+ );
+ }
+ } else {
+ this.configuration.config.webpackOptions[propType] = null;
}
- } else {
- this.configuration.config.webpackOptions[propType] = null;
}
- })
- .then((_: void): void => {
- done();
- });
+ )
+ .then(
+ (): void => {
+ done();
+ }
+ );
}
- public writing() {
+ public writing(): void {
this.config.set("configuration", this.configuration);
}
}
diff --git a/packages/generators/tslint.json b/packages/generators/tslint.json
deleted file mode 100644
index 0946f20963a..00000000000
--- a/packages/generators/tslint.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "extends": "../../tslint.json"
-}
diff --git a/packages/generators/types/index.ts b/packages/generators/types/index.ts
index 1adc7ee911c..449dc0cc477 100644
--- a/packages/generators/types/index.ts
+++ b/packages/generators/types/index.ts
@@ -1,11 +1,11 @@
-export interface ISchemaProperties {
+export interface SchemaProperties {
additionalProperties?: boolean;
definitions?: object;
properties?: object;
type?: string;
}
-interface IWebpackResolve {
+interface WebpackResolve {
alias?: object;
aliasFields?: string[];
cachePredicate?: Function;
@@ -27,7 +27,7 @@ interface IWebpackResolve {
type IRuleSetCondition = RegExp | string | Function | object;
-export interface IWebpackOptions {
+export interface WebpackOptions {
amd?: string;
bail?: boolean;
cache?: boolean | object;
@@ -47,10 +47,12 @@ export interface IWebpackOptions {
headers?: object;
logLevel?: string;
clientLogLevel?: string;
- overlay?: boolean | {
- errors?: boolean;
- warnings?: boolean;
- };
+ overlay?:
+ | boolean
+ | {
+ errors?: boolean;
+ warnings?: boolean;
+ };
progress?: boolean;
key?: string | Buffer;
cert?: string | Buffer;
@@ -69,10 +71,12 @@ export interface IWebpackOptions {
openPage?: string;
compress?: boolean;
proxy?: object[] | Function[];
- historyApiFallback?: boolean | {
- rewrites?: object[];
- disableDotRule?: boolean;
- };
+ historyApiFallback?:
+ | boolean
+ | {
+ rewrites?: object[];
+ disableDotRule?: boolean;
+ };
staticOptions?: object;
setup?: Function;
before?: Function;
@@ -97,25 +101,7 @@ export interface IWebpackOptions {
exprContextRegExp?: boolean | RegExp;
exprContextRequest?: string;
noParse?: string | string[] | Function | RegExp | RegExp[];
- rules?: Array<{
- enforce?: "pre" | "post";
- exclude?: IRuleSetCondition;
- include?: IRuleSetCondition;
- issuer?: IRuleSetCondition;
- loader?: string | Function | object;
- loaders?: Function[] | object[];
- options?: object;
- parser?: object;
- sideEffects?: boolean;
- type?: string;
- resource?: IRuleSetCondition;
- resourceQuery?: IRuleSetCondition;
- compiler?: IRuleSetCondition;
- rules?: object[];
- use?: object | object[] | Function;
- test?: IRuleSetCondition;
-
- }>;
+ rules?: Rule[];
unknownContextCritical?: boolean;
unknownContextRecursive?: boolean;
unknownContextRegExp?: boolean | RegExp;
@@ -127,15 +113,19 @@ export interface IWebpackOptions {
strictExportPresence?: boolean;
strictThisContextOnImports?: boolean;
};
- node?: false | true | string | {
- console?: boolean | string;
- process?: boolean | string;
- global?: boolean;
- __filename?: boolean | string;
- __dirname?: boolean | string;
- Buffer?: boolean | string;
- setImmediate?: boolean | string;
- };
+ node?:
+ | false
+ | true
+ | string
+ | {
+ console?: boolean | string;
+ process?: boolean | string;
+ global?: boolean;
+ __filename?: boolean | string;
+ __dirname?: boolean | string;
+ Buffer?: boolean | string;
+ setImmediate?: boolean | string;
+ };
output?: {
auxiliaryComment?: string | object;
chunkFilename?: string;
@@ -199,19 +189,21 @@ export interface IWebpackOptions {
};
};
parallelism?: number;
- performance?: false | {
- assetFilter?: Function;
- hints?: false | string;
- maxEntrypointSize?: number;
- maxAssetSize?: number;
- };
- plugins?: object[] | Function[] | string[] | string | any;
+ performance?:
+ | false
+ | {
+ assetFilter?: Function;
+ hints?: false | string;
+ maxEntrypointSize?: number;
+ maxAssetSize?: number;
+ };
+ plugins?: object[] | Function[] | string[] | string;
profile?: boolean;
recordsInputPath?: string;
recordsOutputPath?: string;
recordsPath?: string;
- resolve?: IWebpackResolve;
- resolveLoader?: IWebpackResolve;
+ resolve?: WebpackResolve;
+ resolveLoader?: WebpackResolve;
stats?: string | boolean | object;
target?: string | Function;
watch?: boolean;
@@ -221,3 +213,22 @@ export interface IWebpackOptions {
poll?: boolean | number;
};
}
+
+interface Rule {
+ enforce?: "pre" | "post";
+ exclude?: IRuleSetCondition;
+ include?: IRuleSetCondition;
+ issuer?: IRuleSetCondition;
+ loader?: string | Function | object;
+ loaders?: Function[] | object[];
+ options?: object;
+ parser?: object;
+ sideEffects?: boolean;
+ type?: string;
+ resource?: IRuleSetCondition;
+ resourceQuery?: IRuleSetCondition;
+ compiler?: IRuleSetCondition;
+ rules?: object[];
+ use?: object | object[] | Function;
+ test?: IRuleSetCondition;
+}
diff --git a/packages/generators/types/json-loader.d.ts b/packages/generators/types/json-loader.d.ts
index 0cb4cf5f44b..36396113911 100644
--- a/packages/generators/types/json-loader.d.ts
+++ b/packages/generators/types/json-loader.d.ts
@@ -1,4 +1,5 @@
declare module "*.json" {
+ // eslint-disable-next-line
const value: any;
export default value;
}
diff --git a/packages/generators/types/yeoman-generator.d.ts b/packages/generators/types/yeoman-generator.d.ts
index bc2425c458f..3ca7dd82c1a 100644
--- a/packages/generators/types/yeoman-generator.d.ts
+++ b/packages/generators/types/yeoman-generator.d.ts
@@ -4,7 +4,7 @@
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
///
-interface IYeoman {
+interface Yeoman {
public config: {
set: (setProperty: string, setValue: object) => void;
};
@@ -12,8 +12,8 @@ interface IYeoman {
adapter: {
promptModule: {
registerPrompt: (promptName: string, promptModule: object) => void;
- },
- },
+ };
+ };
};
public props: {
name: string;
@@ -24,16 +24,15 @@ interface IYeoman {
public run(target: string, options?: object, done?: Function): IRunEnv;
public scheduleInstallTask(packager: string, dependencies: string[], options?: object): void;
public on(event: string, listener: Function): this;
- public async(): (_?: void) => void | boolean;
+ public async(): () => void | boolean;
public prompt(opt: IPromptOptions[]): Promise<>;
public log(message: string): void;
public npmInstall(packages?: string[] | string, options?: object, cb?: Function): Promise<>;
- public spawnCommand(name: string, args?: string[], options?: Object): void;
+ public spawnCommand(name: string, args?: string[], options?: object): void;
}
declare module "yeoman-generator" {
-
- class YeomanGeneratorBase extends IYeoman {
+ class YeomanGeneratorBase implements Yeoman {
public config: {
set: (setProperty: string, setValue: object) => void;
};
@@ -41,8 +40,8 @@ declare module "yeoman-generator" {
adapter: {
promptModule: {
registerPrompt: (promptName: string, promptModule: object) => void;
- },
- },
+ };
+ };
};
public props: {
name: string;
@@ -50,39 +49,42 @@ declare module "yeoman-generator" {
public composeWith(namespace: string, options?: object, settings?: IComposeSetting): YeomanGeneratorBase;
public destinationRoot(rootPath?: string): string;
public destinationPath(...path: string[]): string;
- public run(target: string, options?: object, done?: Function): IRunEnv;
+ public run(target: string, options?: object, done?: Function): RunEnv;
public scheduleInstallTask(packager: string, dependencies: string[], options?: object): void;
public on(event: string, listener: Function): this;
- public async(): (_?: void) => void | boolean;
- public prompt(opt: IPromptOptions[]): Promise<>;
+ public async(): () => void | boolean;
+ public prompt(opt: PromptOptions[]): Promise<>;
public log(message: string): void;
public npmInstall(packages?: string[] | string, options?: object, cb?: Function): Promise<>;
- public spawnCommand(name: string, args?: string[], options?: Object): void;
+ public spawnCommand(name: string, args?: string[], options?: object): void;
}
- interface IRunEnv extends Object {
+ interface RunEnv extends object {
on: (event: string, callbackFn: Function) => void;
}
- interface IPromptOptions {
+ interface PromptOptions {
type?: string;
name: string;
- message: string | ((answers: Object) => string);
- choices?: string[] | ((answers: Object) => string);
- default?: string | number | boolean | string[] | number[]
- | ((answers: Object) => (string | number | boolean | string[] | number[]));
- validate?: ((input: string) => boolean | string);
- when?: ((answers: Object) => boolean) | boolean;
+ message: string | ((answers: object) => string);
+ choices?: string[] | ((answers: object) => string);
+ default?:
+ | string
+ | number
+ | boolean
+ | string[]
+ | number[]
+ | ((answers: object) => string | number | boolean | string[] | number[]);
+ validate?: (input: string) => boolean | string;
+ when?: ((answers: object) => boolean) | boolean;
store?: boolean;
filter?: (name: string) => string;
}
- // tslint:disable-next-line
class NamedBase extends YeomanGeneratorBase implements INamedBase {
- constructor(args: string | string[], options: object);
+ public constructor(args: string | string[], options: object);
}
- // tslint:disable-next-line
class Base extends NamedBase implements IBase {
public static extend(protoProps: IQueueProps): YeomanGeneratorBase;
}
diff --git a/packages/generators/utils/entry.ts b/packages/generators/utils/entry.ts
index aae92f38be1..f65af71cde8 100644
--- a/packages/generators/utils/entry.ts
+++ b/packages/generators/utils/entry.ts
@@ -2,7 +2,7 @@ import { InputValidate } from "@webpack-cli/webpack-scaffold";
import validate from "./validate";
-interface IEntry extends IYeoman {
+interface Entry extends Yeoman {
usingDefaults?: boolean;
}
@@ -15,9 +15,12 @@ interface IEntry extends IYeoman {
* @returns {Object} An Object that holds the answers given by the user, later used to scaffold
*/
-export default function entry(self: IEntry, answer: {
- entryType: boolean;
-}): Promise<{}> {
+export default function entry(
+ self: Entry,
+ answer: {
+ entryType: boolean;
+ }
+): Promise<{}> {
let entryIdentifiers: string[];
let result: Promise<{}>;
if (answer.entryType) {
@@ -26,82 +29,90 @@ export default function entry(self: IEntry, answer: {
InputValidate(
"multipleEntries",
"Type the names you want for your modules (entry files), separated by comma [example: app,vendor]",
- validate,
- ),
+ validate
+ )
])
- .then((multipleEntriesAnswer: {
- multipleEntries: string,
- }) => {
- const webpackEntryPoint: object = {};
- entryIdentifiers = multipleEntriesAnswer.multipleEntries.split(",");
+ .then(
+ (multipleEntriesAnswer: { multipleEntries: string }): Promise => {
+ const webpackEntryPoint: object = {};
+ entryIdentifiers = multipleEntriesAnswer.multipleEntries.split(",");
- function forEachPromise(entries: string[], fn: (entryProp: string) => Promise<{} | void>) {
- return entries.reduce((promise: Promise<{}>, prop: string) => {
- const trimmedProp: string = prop.trim();
+ function forEachPromise(
+ entries: string[],
+ fn: (entryProp: string) => Promise<{} | void>
+ ): Promise {
+ return entries.reduce((promise: Promise<{}>, prop: string): Promise => {
+ const trimmedProp: string = prop.trim();
- return promise.then((n: object) => {
- if (n) {
- Object.keys(n).forEach((val: string): void => {
+ return promise.then(
+ (n: object): Promise => {
+ if (n) {
+ Object.keys(n).forEach(
+ (val: string): void => {
+ if (
+ n[val].charAt(0) !== "(" &&
+ n[val].charAt(0) !== "[" &&
+ !n[val].includes("function") &&
+ !n[val].includes("path") &&
+ !n[val].includes("process")
+ ) {
+ n[val] = `\'${n[val].replace(/"|'/g, "").concat(".js")}\'`;
+ }
+ webpackEntryPoint[val] = n[val];
+ }
+ );
+ } else {
+ n = {};
+ }
+ return fn(trimmedProp);
+ }
+ );
+ }, Promise.resolve());
+ }
+ return forEachPromise(
+ entryIdentifiers,
+ (entryProp: string): Promise<{} | void> =>
+ self.prompt([
+ InputValidate(
+ `${entryProp}`,
+ `What is the location of "${entryProp}"? [example: ./src/${entryProp}]`,
+ validate
+ )
+ ])
+ ).then(
+ (entryPropAnswer: object): object => {
+ Object.keys(entryPropAnswer).forEach(
+ (val: string): void => {
if (
- n[val].charAt(0) !== "(" &&
- n[val].charAt(0) !== "[" &&
- !n[val].includes("function") &&
- !n[val].includes("path") &&
- !n[val].includes("process")
+ entryPropAnswer[val].charAt(0) !== "(" &&
+ entryPropAnswer[val].charAt(0) !== "[" &&
+ !entryPropAnswer[val].includes("function") &&
+ !entryPropAnswer[val].includes("path") &&
+ !entryPropAnswer[val].includes("process")
) {
- n[val] = `\'${n[val].replace(/"|'/g, "").concat(".js")}\'`;
+ entryPropAnswer[val] = `\'${entryPropAnswer[val].replace(/"|'/g, "")}\'`;
}
- webpackEntryPoint[val] = n[val];
- });
- } else {
- n = {};
- }
- return fn(trimmedProp);
- });
- }, Promise.resolve());
- }
- return forEachPromise(entryIdentifiers, (entryProp: string): Promise<{} | void> =>
- self.prompt([
- InputValidate(
- `${entryProp}`,
- `What is the location of "${entryProp}"? [example: ./src/${entryProp}]`,
- validate,
- ),
- ]),
- ).then((entryPropAnswer: object): object => {
- Object.keys(entryPropAnswer).forEach((val: string): void => {
- if (
- entryPropAnswer[val].charAt(0) !== "(" &&
- entryPropAnswer[val].charAt(0) !== "[" &&
- !entryPropAnswer[val].includes("function") &&
- !entryPropAnswer[val].includes("path") &&
- !entryPropAnswer[val].includes("process")
- ) {
- entryPropAnswer[val] = `\'${entryPropAnswer[val].replace(/"|'/g, "")}\'`;
+ webpackEntryPoint[val] = entryPropAnswer[val];
+ }
+ );
+ return webpackEntryPoint;
}
- webpackEntryPoint[val] = entryPropAnswer[val];
- });
- return webpackEntryPoint;
- });
- });
+ );
+ }
+ );
} else {
result = self
- .prompt([
- InputValidate(
- "singularEntry",
- "Which will be your application entry point? (src/index)",
- ),
- ])
- .then((singularEntryAnswer: {
- singularEntry: string,
- }): string => {
- let { singularEntry } = singularEntryAnswer;
- singularEntry = `\'${singularEntry.replace(/"|'/g, "")}\'`;
- if (singularEntry.length <= 0) {
- self.usingDefaults = true;
+ .prompt([InputValidate("singularEntry", "Which will be your application entry point? (src/index)")])
+ .then(
+ (singularEntryAnswer: { singularEntry: string }): string => {
+ let { singularEntry } = singularEntryAnswer;
+ singularEntry = `\'${singularEntry.replace(/"|'/g, "")}\'`;
+ if (singularEntry.length <= 0) {
+ self.usingDefaults = true;
+ }
+ return singularEntry;
}
- return singularEntry;
- });
+ );
}
return result;
}
diff --git a/packages/generators/utils/module.ts b/packages/generators/utils/module.ts
index 50c4b0deeea..25b846723f1 100644
--- a/packages/generators/utils/module.ts
+++ b/packages/generators/utils/module.ts
@@ -1,36 +1,36 @@
-interface IModule extends Object {
+interface Module extends Object {
include: string[];
loader: string;
options: {
plugins: string[];
- presets: Array>;
+ presets: Preset[][];
};
test: string;
}
+type Preset = string | object;
+
/**
*
* Returns an module.rule object that has the babel loader if invoked
*
* @returns {Function} A callable function that adds the babel-loader with env preset
*/
-export default function(): IModule {
+export default function(): Module {
return {
include: ["path.resolve(__dirname, 'src')"],
loader: "'babel-loader'",
options: {
- plugins: [
- "'syntax-dynamic-import'",
- ],
+ plugins: ["'syntax-dynamic-import'"],
presets: [
[
"'@babel/preset-env'",
{
- "'modules'": false,
- },
- ],
- ],
+ "'modules'": false
+ }
+ ]
+ ]
},
- test: `${new RegExp(/\.js$/)}`,
+ test: `${new RegExp(/\.js$/)}`
};
}
diff --git a/packages/generators/utils/plugins.ts b/packages/generators/utils/plugins.ts
index f94029dea51..6dedb1fab9e 100644
--- a/packages/generators/utils/plugins.ts
+++ b/packages/generators/utils/plugins.ts
@@ -6,6 +6,6 @@
* that consists of terser-webpack-plugin
*/
-export default function(_?: void): string[] {
+export default function(): string[] {
return ["new TerserPlugin()"];
}
diff --git a/packages/generators/utils/tooltip.ts b/packages/generators/utils/tooltip.ts
index 27580eee7ad..cd9dba4e7ec 100644
--- a/packages/generators/utils/tooltip.ts
+++ b/packages/generators/utils/tooltip.ts
@@ -7,7 +7,7 @@
*/
export default {
- cssPlugin: (_?: void): string => {
+ cssPlugin: (): string => {
return `/*
* We've enabled MiniCssExtractPlugin for you. This allows your app to
* use css modules that will be moved into a separate CSS file instead of inside
@@ -18,7 +18,7 @@ export default {
*/`;
},
- splitChunks: (_?: void): string => {
+ splitChunks: (): string => {
return `/*
* SplitChunksPlugin is enabled by default and replaced
* deprecated CommonsChunkPlugin. It automatically identifies modules which
@@ -33,7 +33,7 @@ export default {
*/`;
},
- postcss: (_?: void): string => {
+ postcss: (): string => {
return `/*
* We've enabled Postcss, autoprefixer and precss for you. This allows your app
* to lint CSS, support variables and mixins, transpile future CSS syntax,
@@ -50,7 +50,7 @@ export default {
*/`;
},
- terser: (_?: void): string => {
+ terser: (): string => {
return `/*
* We've enabled TerserPlugin for you! This minifies your app
* in order to load faster and run less javascript.
@@ -58,5 +58,5 @@ export default {
* https://github.com/webpack-contrib/terser-webpack-plugin
*
*/`;
- },
+ }
};
diff --git a/packages/info/.eslintrc b/packages/info/.eslintrc
new file mode 100644
index 00000000000..365d9f85d71
--- /dev/null
+++ b/packages/info/.eslintrc
@@ -0,0 +1,11 @@
+{
+ "root": true,
+ "extends": [
+ "../../.eslintrc.js",
+ "plugin:@typescript-eslint/recommended",
+ "prettier",
+ "prettier/@typescript-eslint"
+ ],
+ "parser": "@typescript-eslint/parser",
+ "plugins": ["@typescript-eslint"]
+}
diff --git a/packages/info/__tests__/.eslintrc b/packages/info/__tests__/.eslintrc
new file mode 100644
index 00000000000..5d4340a351d
--- /dev/null
+++ b/packages/info/__tests__/.eslintrc
@@ -0,0 +1,7 @@
+{
+ "root": true,
+ "extends": ["../.eslintrc"],
+ "rules": {
+ "@typescript-eslint/explicit-function-return-type": ["off"]
+ }
+}
diff --git a/packages/info/__tests__/index.test.ts b/packages/info/__tests__/index.test.ts
index fca23773708..7ddb1dae791 100644
--- a/packages/info/__tests__/index.test.ts
+++ b/packages/info/__tests__/index.test.ts
@@ -8,7 +8,7 @@ describe("info", () => {
Browsers: ["Chrome", "Firefox", "Safari"],
System: ["OS", "CPU"],
npmGlobalPackages: ["webpack", "webpack-cli"],
- npmPackages: "*webpack*",
+ npmPackages: "*webpack*"
};
expect(returnedInformation).toEqual(expectedInformation);
diff --git a/packages/info/index.ts b/packages/info/index.ts
index 43db20f6234..68c69c9ddf8 100644
--- a/packages/info/index.ts
+++ b/packages/info/index.ts
@@ -5,16 +5,18 @@ import * as process from "process";
* Prints debugging information for webpack issue reporting
*/
-export function information() {
+// TODO: define proper interface
+// eslint-disable-next-line
+export function information(): any {
return {
Binaries: ["Node", "Yarn", "npm"],
Browsers: ["Chrome", "Firefox", "Safari"],
System: ["OS", "CPU"],
npmGlobalPackages: ["webpack", "webpack-cli"],
- npmPackages: "*webpack*",
+ npmPackages: "*webpack*"
};
}
-export default async function info() {
+export default async function info(): Promise {
process.stdout.write(await envinfo.run(information()));
}
diff --git a/packages/init/.eslintrc b/packages/init/.eslintrc
new file mode 100644
index 00000000000..365d9f85d71
--- /dev/null
+++ b/packages/init/.eslintrc
@@ -0,0 +1,11 @@
+{
+ "root": true,
+ "extends": [
+ "../../.eslintrc.js",
+ "plugin:@typescript-eslint/recommended",
+ "prettier",
+ "prettier/@typescript-eslint"
+ ],
+ "parser": "@typescript-eslint/parser",
+ "plugins": ["@typescript-eslint"]
+}
diff --git a/packages/init/init.ts b/packages/init/init.ts
index 1b60fe34c7e..b4063cd15e9 100644
--- a/packages/init/init.ts
+++ b/packages/init/init.ts
@@ -7,9 +7,9 @@ import propTypes from "@webpack-cli/utils/prop-types";
import astTransform from "@webpack-cli/utils/recursive-parser";
import runPrettier from "@webpack-cli/utils/run-prettier";
-import { INode } from "@webpack-cli/utils/types/NodePath";
-import { IError } from "./types";
-import { IConfiguration, IWebpackProperties } from "./types/Transform";
+import { Node } from "@webpack-cli/utils/types/NodePath";
+import { Error } from "./types";
+import { Configuration, WebpackProperties } from "./types/Transform";
/**
*
@@ -21,9 +21,8 @@ import { IConfiguration, IWebpackProperties } from "./types/Transform";
* @returns {Array} - An array with the transformations to be run
*/
-const mapOptionsToTransform = (config: IConfiguration): string[] =>
- Object.keys(config.webpackOptions)
- .filter((key: string): boolean => propTypes.has(key));
+const mapOptionsToTransform = (config: Configuration): string[] =>
+ Object.keys(config.webpackOptions).filter((key: string): boolean => propTypes.has(key));
/**
*
@@ -35,53 +34,56 @@ const mapOptionsToTransform = (config: IConfiguration): string[] =>
* and writes the file
*/
-export default function runTransform(webpackProperties: IWebpackProperties, action: string): void {
+export default function runTransform(webpackProperties: WebpackProperties, action: string): void {
// webpackOptions.name sent to nameTransform if match
- const webpackConfig: string[] =
- Object
- .keys(webpackProperties)
- .filter((p: string): boolean => p !== "configFile" && p !== "configPath");
+ const webpackConfig: string[] = Object.keys(webpackProperties).filter(
+ (p: string): boolean => p !== "configFile" && p !== "configPath"
+ );
const initActionNotDefined = (action && action !== "init") || false;
- webpackConfig.forEach((scaffoldPiece: string): Promise => {
- const config: IConfiguration = webpackProperties[scaffoldPiece];
- const transformations = mapOptionsToTransform(config);
- const ast = j(
- initActionNotDefined
- ? webpackProperties.configFile
- : "module.exports = {}",
- );
- const transformAction: string | null = action || null;
+ webpackConfig.forEach(
+ (scaffoldPiece: string): Promise => {
+ const config: Configuration = webpackProperties[scaffoldPiece];
+ const transformations = mapOptionsToTransform(config);
+ const ast = j(initActionNotDefined ? webpackProperties.configFile : "module.exports = {}");
+ const transformAction: string | null = action || null;
- return pEachSeries(transformations, (f: string): boolean | INode => {
- return astTransform(j, ast, config.webpackOptions[f], transformAction, f);
- })
- .then((value: string[]): void | PromiseLike => {
- let configurationName = "webpack.config.js";
- if (config.configName) {
- configurationName = `webpack.${config.configName}.js`;
+ return pEachSeries(
+ transformations,
+ (f: string): boolean | Node => {
+ return astTransform(j, ast, config.webpackOptions[f], transformAction, f);
}
+ )
+ .then(
+ (): void | PromiseLike => {
+ let configurationName = "webpack.config.js";
+ if (config.configName) {
+ configurationName = `webpack.${config.configName}.js`;
+ }
- const outputPath = initActionNotDefined
- ? webpackProperties.configPath
- : path.join(process.cwd(), configurationName);
+ const outputPath = initActionNotDefined
+ ? webpackProperties.configPath
+ : path.join(process.cwd(), configurationName);
- const source: string = ast.toSource({
- quote: "single",
- });
+ const source: string = ast.toSource({
+ quote: "single"
+ });
- runPrettier(outputPath, source);
- })
- .catch((err: IError) => {
- console.error(err.message ? err.message : err);
- });
- });
+ runPrettier(outputPath, source);
+ }
+ )
+ .catch(
+ (err: Error): void => {
+ console.error(err.message ? err.message : err);
+ }
+ );
+ }
+ );
let successMessage: string = `Congratulations! Your new webpack configuration file has been created!`;
if (initActionNotDefined && webpackProperties.config.item) {
successMessage = `Congratulations! ${webpackProperties.config.item} has been ${action}ed!`;
-
}
process.stdout.write("\n" + chalk.green(`${successMessage}\n`));
}
diff --git a/packages/init/package-lock.json b/packages/init/package-lock.json
index fede4727f12..1695fbbf370 100644
--- a/packages/init/package-lock.json
+++ b/packages/init/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "@webpack-cli/init",
- "version": "0.1.3",
+ "version": "0.1.5",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/packages/init/types/Transform.ts b/packages/init/types/Transform.ts
index 89622b85f62..d117d93d558 100644
--- a/packages/init/types/Transform.ts
+++ b/packages/init/types/Transform.ts
@@ -1,14 +1,14 @@
-export interface IWebpackProperties extends Object {
+export interface WebpackProperties extends Object {
configFile: string;
configPath: string;
- webpackOptions: IConfiguration;
+ webpackOptions: Configuration;
config: {
item: string;
configName: string;
};
}
-export interface IConfiguration extends Object {
+export interface Configuration extends Object {
configName: string;
webpackOptions: object;
topScope: string[];
diff --git a/packages/init/types/index.ts b/packages/init/types/index.ts
index c0f13602567..9480d6ce9b0 100644
--- a/packages/init/types/index.ts
+++ b/packages/init/types/index.ts
@@ -1,3 +1,3 @@
-export interface IError {
+export interface Error {
message?: string;
}
diff --git a/packages/make/.eslintrc b/packages/make/.eslintrc
new file mode 100644
index 00000000000..365d9f85d71
--- /dev/null
+++ b/packages/make/.eslintrc
@@ -0,0 +1,11 @@
+{
+ "root": true,
+ "extends": [
+ "../../.eslintrc.js",
+ "plugin:@typescript-eslint/recommended",
+ "prettier",
+ "prettier/@typescript-eslint"
+ ],
+ "parser": "@typescript-eslint/parser",
+ "plugins": ["@typescript-eslint"]
+}
diff --git a/packages/migrate/.eslintrc b/packages/migrate/.eslintrc
new file mode 100644
index 00000000000..365d9f85d71
--- /dev/null
+++ b/packages/migrate/.eslintrc
@@ -0,0 +1,11 @@
+{
+ "root": true,
+ "extends": [
+ "../../.eslintrc.js",
+ "plugin:@typescript-eslint/recommended",
+ "prettier",
+ "prettier/@typescript-eslint"
+ ],
+ "parser": "@typescript-eslint/parser",
+ "plugins": ["@typescript-eslint"]
+}
diff --git a/packages/migrate/__tests__/.eslintrc b/packages/migrate/__tests__/.eslintrc
new file mode 100644
index 00000000000..5d4340a351d
--- /dev/null
+++ b/packages/migrate/__tests__/.eslintrc
@@ -0,0 +1,7 @@
+{
+ "root": true,
+ "extends": ["../.eslintrc"],
+ "rules": {
+ "@typescript-eslint/explicit-function-return-type": ["off"]
+ }
+}
diff --git a/packages/migrate/bannerPlugin/bannerPlugin.ts b/packages/migrate/bannerPlugin/bannerPlugin.ts
index 5d369f57ec9..422e1d40dd1 100644
--- a/packages/migrate/bannerPlugin/bannerPlugin.ts
+++ b/packages/migrate/bannerPlugin/bannerPlugin.ts
@@ -1,6 +1,6 @@
import * as utils from "@webpack-cli/utils/ast-utils";
-import { IJSCodeshift, INode } from "../types/NodePath";
+import { JSCodeshift, Node } from "../types/NodePath";
/**
*
@@ -12,24 +12,19 @@ import { IJSCodeshift, INode } from "../types/NodePath";
* @returns {Node} ast - jscodeshift ast
*/
-export default function(j: IJSCodeshift, ast: INode): INode {
- return utils
- .findPluginsByName(j, ast, ["webpack.BannerPlugin"])
- .forEach((path: INode): void => {
- const args: INode[] = path.value.arguments; // any node
+export default function(j: JSCodeshift, ast: Node): Node {
+ return utils.findPluginsByName(j, ast, ["webpack.BannerPlugin"]).forEach(
+ (path: Node): void => {
+ const args: Node[] = (path.value as Node).arguments; // any node
// If the first argument is a literal replace it with object notation
// See https://webpack.js.org/guides/migrating/#bannerplugin-breaking-change
if (args && args.length > 1 && args[0].type === j.Literal.name) {
// and remove the first argument
- path.value.arguments = [path.value.arguments[1]];
- utils.createOrUpdatePluginByName(
- j,
- path.parent,
- "webpack.BannerPlugin",
- {
- banner: args[0].value,
- },
- );
+ (path.value as Node).arguments = [(path.value as Node).arguments[1]];
+ utils.createOrUpdatePluginByName(j, path.parent, "webpack.BannerPlugin", {
+ banner: args[0].value
+ });
}
- });
+ }
+ );
}
diff --git a/packages/migrate/commonsChunkPlugin/commonsChunkPlugin.ts b/packages/migrate/commonsChunkPlugin/commonsChunkPlugin.ts
index ea86fb371ba..62bc6a090e2 100644
--- a/packages/migrate/commonsChunkPlugin/commonsChunkPlugin.ts
+++ b/packages/migrate/commonsChunkPlugin/commonsChunkPlugin.ts
@@ -4,10 +4,47 @@ import {
createProperty,
findAndRemovePluginByName,
findPluginsByName,
- findRootNodesByName,
+ findRootNodesByName
} from "@webpack-cli/utils/ast-utils";
-import { IJSCodeshift, INode } from "../types/NodePath";
+import { JSCodeshift, Node } from "../types/NodePath";
+
+// merge test entry prop and function expression. case 6[x]
+// TODO: set the proper type once moved to @types/jscodeshift
+// eslint-disable-next-line
+const mergeTestPropArrowFunction = (j, chunkKey, testFunc): any => {
+ return j.property(
+ "init",
+ createIdentifierOrLiteral(j, "test"),
+ j.arrowFunctionExpression(
+ [j.identifier("module")],
+ j.blockStatement([
+ j.ifStatement(
+ j.callExpression(
+ j.memberExpression(
+ j.callExpression(j.memberExpression(j.identifier("module"), j.identifier("getChunks")), []),
+ j.identifier("some"),
+ false
+ ),
+ [
+ j.arrowFunctionExpression(
+ [j.identifier("chunk")],
+ j.binaryExpression(
+ "===",
+ j.memberExpression(j.identifier("chunk"), j.identifier("name")),
+ j.literal(chunkKey)
+ )
+ )
+ ]
+ ),
+ j.returnStatement(j.literal(true))
+ ),
+ j.variableDeclaration("const", [j.variableDeclarator(j.identifier("fn"), testFunc)]),
+ j.returnStatement(j.callExpression(j.identifier("fn"), [j.identifier("module")]))
+ ])
+ )
+ );
+};
/**
*
@@ -18,20 +55,15 @@ import { IJSCodeshift, INode } from "../types/NodePath";
* @param {Node} ast - jscodeshift ast to transform
* @returns {Node} ast - jscodeshift ast
*/
-export default function(j: IJSCodeshift, ast: INode): INode {
- const splitChunksProps: INode[] = [];
- const cacheGroupsProps: INode[] = [];
+export default function(j: JSCodeshift, ast: Node): Node {
+ const splitChunksProps: Node[] = [];
+ const cacheGroupsProps: Node[] = [];
const optimizationProps: object = {};
- let commonCacheGroupsProps: INode[] = [
- createProperty(j, "chunks", "initial"),
- createProperty(j, "enforce", true),
- ];
+ let commonCacheGroupsProps: Node[] = [createProperty(j, "chunks", "initial"), createProperty(j, "enforce", true)];
// find old options
- const CommonsChunkPlugin: INode = findPluginsByName(j, ast, [
- "webpack.optimize.CommonsChunkPlugin",
- ]);
+ const CommonsChunkPlugin: Node = findPluginsByName(j, ast, ["webpack.optimize.CommonsChunkPlugin"]);
if (!CommonsChunkPlugin.size()) {
return ast;
@@ -39,64 +71,66 @@ export default function(j: IJSCodeshift, ast: INode): INode {
// cache group options based on keys
let cacheGroup: object = {};
- let cacheGroups: INode[] = [];
+ let cacheGroups: Node[] = [];
// iterate each CommonsChunkPlugin instance
CommonsChunkPlugin.forEach(
- (path: INode): void => {
- const CCPProps: INode[] = path.value.arguments[0].properties;
+ (path: Node): void => {
+ const CCPProps: Node[] = (path.value as Node).arguments[0].properties;
// reset chunks from old props
cacheGroup = {};
cacheGroups = [];
- commonCacheGroupsProps = [
- createProperty(j, "chunks", "initial"),
- createProperty(j, "enforce", true),
- ];
+ commonCacheGroupsProps = [createProperty(j, "chunks", "initial"), createProperty(j, "enforce", true)];
let chunkKey: string;
- let chunkCount: number = 0;
+ let chunkCount = 0;
// iterate CCP props and map SCP props
CCPProps.forEach(
- (p: INode): void => {
+ (p: Node): void => {
const propKey: string = p.key.name;
switch (propKey) {
case "names":
- p.value.elements.forEach(({ value: chunkValue }): void => {
- if (chunkValue === "runtime") {
- optimizationProps["runtimeChunk"] = j.objectExpression([ // tslint:disable-line
- createProperty(j, "name", chunkValue),
- ]);
- } else {
- if (!Array.isArray(cacheGroup[chunkValue])) {
- cacheGroup[chunkValue] = [];
- }
+ (p.value as Node).elements.forEach(
+ ({ value: chunkValue }): void => {
+ if (chunkValue === "runtime") {
+ optimizationProps["runtimeChunk"] = j.objectExpression([
+ createProperty(j, "name", chunkValue)
+ ]);
+ } else {
+ if (!Array.isArray(cacheGroup[chunkValue as string])) {
+ cacheGroup[chunkValue as string] = [];
+ }
- findRootNodesByName(j, ast, "entry").forEach(
- ({ value: { value: { properties: entries }} },
- ): void => {
- chunkCount = entries.length;
- entries.forEach(({ key: { name: entryName }}): void => {
- if (entryName === chunkValue) {
- cacheGroup[chunkValue].push(
- createProperty(j, "test", entryName),
+ findRootNodesByName(j, ast, "entry").forEach(
+ ({ value }): void => {
+ const { properties: entries } = (value as Node).value as Node;
+ chunkCount = entries.length;
+ entries.forEach(
+ ({ key: { name: entryName } }): void => {
+ if (entryName === chunkValue) {
+ cacheGroup[chunkValue as string].push(
+ createProperty(j, "test", entryName)
+ );
+ }
+ }
);
}
- });
- });
+ );
+ }
}
- });
+ );
break;
- case "name":
- const nameKey = p.value.value;
+ case "name": {
+ const nameKey = (p.value as Node).value as string;
if (nameKey === "runtime") {
- optimizationProps["runtimeChunk"] = j.objectExpression([ // tslint:disable-line
- createProperty(j, "name", nameKey),
+ optimizationProps["runtimeChunk"] = j.objectExpression([
+ createProperty(j, "name", nameKey)
]);
} else {
chunkKey = nameKey;
@@ -106,19 +140,21 @@ export default function(j: IJSCodeshift, ast: INode): INode {
}
findRootNodesByName(j, ast, "entry").forEach(
- ({ value: { value: { properties: entries }} },
- ): void => {
- chunkCount = entries.length;
- entries.forEach(({ key: { name: entryName }}): void => {
- if (entryName === nameKey) {
- cacheGroup[nameKey].push(
- createProperty(j, "test", entryName),
- );
- }
- });
- });
+ ({ value }): void => {
+ const { properties: entries } = (value as Node).value as Node;
+ chunkCount = entries.length;
+ entries.forEach(
+ ({ key: { name: entryName } }): void => {
+ if (entryName === nameKey) {
+ cacheGroup[nameKey].push(createProperty(j, "test", entryName));
+ }
+ }
+ );
+ }
+ );
}
break;
+ }
case "filename":
if (chunkKey) {
@@ -126,7 +162,7 @@ export default function(j: IJSCodeshift, ast: INode): INode {
cacheGroup[chunkKey] = [];
}
cacheGroup[chunkKey].push(
- createProperty(j, propKey, p.value.value),
+ createProperty(j, propKey, (p.value as Node).value as string)
);
}
break;
@@ -135,9 +171,7 @@ export default function(j: IJSCodeshift, ast: INode): INode {
if (!Array.isArray(cacheGroup[chunkKey])) {
cacheGroup[chunkKey] = [];
}
- cacheGroup[chunkKey].push(
- createProperty(j, "chunks", "async"),
- );
+ cacheGroup[chunkKey].push(createProperty(j, "chunks", "async"));
break;
case "minSize":
@@ -145,177 +179,104 @@ export default function(j: IJSCodeshift, ast: INode): INode {
cacheGroup[chunkKey] = [];
}
cacheGroup[chunkKey].push(
- j.property("init", createIdentifierOrLiteral(j, propKey), p.value),
+ j.property("init", createIdentifierOrLiteral(j, propKey), p.value as Node)
);
break;
- case "minChunks" :
- const { value: pathValue }: INode = p;
+ case "minChunks": {
+ const { value: pathValue }: Node = p;
// minChunk is a function
if (
- pathValue.type === "ArrowFunctionExpression" ||
- pathValue.type === "FunctionExpression"
+ (pathValue as Node).type === "ArrowFunctionExpression" ||
+ (pathValue as Node).type === "FunctionExpression"
) {
if (!Array.isArray(cacheGroup[chunkKey])) {
cacheGroup[chunkKey] = [];
}
- cacheGroup[chunkKey] = cacheGroup[chunkKey].map((prop) =>
- prop.key.name === "test" ? mergeTestPropArrowFunction(j, chunkKey, pathValue) : prop);
+ // eslint-disable-next-line
+ cacheGroup[chunkKey] = cacheGroup[chunkKey].map(
+ (prop): any =>
+ prop.key.name === "test"
+ ? mergeTestPropArrowFunction(j, chunkKey, pathValue)
+ : prop
+ );
}
break;
+ }
}
- },
+ }
);
- Object.keys(cacheGroup).forEach((chunkName: string): void => {
- let chunkProps: INode[] = [
- createProperty(j, "name", chunkName),
- ];
+ Object.keys(cacheGroup).forEach(
+ (chunkName: string): void => {
+ let chunkProps: Node[] = [createProperty(j, "name", chunkName)];
- const chunkPropsToAdd = cacheGroup[chunkName];
- const chunkPropsKeys = chunkPropsToAdd.map((prop) => prop.key.name);
+ const chunkPropsToAdd = cacheGroup[chunkName];
+ const chunkPropsKeys = chunkPropsToAdd.map((prop): string => prop.key.name);
- commonCacheGroupsProps =
- commonCacheGroupsProps.filter((commonProp) => !chunkPropsKeys.includes(commonProp.key.name));
+ commonCacheGroupsProps = commonCacheGroupsProps.filter(
+ (commonProp): boolean => !chunkPropsKeys.includes(commonProp.key.name)
+ );
- chunkProps.push(...commonCacheGroupsProps);
+ chunkProps.push(...commonCacheGroupsProps);
- if (chunkCount > 1) {
- chunkProps.push(
- j.property(
- "init",
- createIdentifierOrLiteral(j, "minChunks"),
- createIdentifierOrLiteral(j, chunkCount),
- ),
+ if (chunkCount > 1) {
+ chunkProps.push(
+ j.property(
+ "init",
+ createIdentifierOrLiteral(j, "minChunks"),
+ createIdentifierOrLiteral(j, chunkCount)
+ )
+ );
+ }
+
+ const chunkPropsContainTest = chunkPropsToAdd.some(
+ (prop): boolean => prop.key.name === "test" && prop.value.type === "Literal"
);
- }
- const chunkPropsContainTest =
- chunkPropsToAdd.some((prop) => prop.key.name === "test" && prop.value.type === "Literal");
+ if (chunkPropsContainTest) {
+ chunkProps = chunkProps.filter((prop): boolean => prop.key.name !== "minChunks");
+ }
- if (chunkPropsContainTest) {
- chunkProps = chunkProps.filter((prop) => prop.key.name !== "minChunks");
- }
+ if (chunkPropsToAdd && Array.isArray(chunkPropsToAdd) && chunkPropsToAdd.length > 0) {
+ chunkProps.push(...chunkPropsToAdd);
+ }
- if (
- chunkPropsToAdd &&
- Array.isArray(chunkPropsToAdd) &&
- chunkPropsToAdd.length > 0
- ) {
- chunkProps.push(...chunkPropsToAdd);
+ cacheGroups.push(
+ j.property("init", createIdentifierOrLiteral(j, chunkName), j.objectExpression([...chunkProps]))
+ );
}
-
- cacheGroups.push(
- j.property(
- "init",
- createIdentifierOrLiteral(j, chunkName),
- j.objectExpression([...chunkProps]),
- ),
- );
- });
+ );
if (cacheGroups.length > 0) {
cacheGroupsProps.push(...cacheGroups);
}
- },
+ }
);
// Remove old plugin
- const root: INode = findAndRemovePluginByName(
- j,
- ast,
- "webpack.optimize.CommonsChunkPlugin",
- );
+ const root: Node = findAndRemovePluginByName(j, ast, "webpack.optimize.CommonsChunkPlugin");
- const rootProps: INode[] = [...splitChunksProps];
+ const rootProps: Node[] = [...splitChunksProps];
if (cacheGroupsProps.length > 0) {
rootProps.push(
- j.property(
- "init",
- createIdentifierOrLiteral(j, "cacheGroups"),
- j.objectExpression([...cacheGroupsProps]),
- ),
+ j.property("init", createIdentifierOrLiteral(j, "cacheGroups"), j.objectExpression([...cacheGroupsProps]))
);
}
// Add new optimizations splitChunks option
if (root) {
- addOrUpdateConfigObject(
- j,
- root,
- "optimizations",
- "splitChunks",
- j.objectExpression([...rootProps]),
- );
+ addOrUpdateConfigObject(j, root, "optimizations", "splitChunks", j.objectExpression([...rootProps]));
- Object.keys(optimizationProps).forEach((key: string): void => {
- addOrUpdateConfigObject(
- j,
- root,
- "optimizations",
- key,
- optimizationProps[key],
- );
- });
+ Object.keys(optimizationProps).forEach(
+ (key: string): void => {
+ addOrUpdateConfigObject(j, root, "optimizations", key, optimizationProps[key]);
+ }
+ );
}
return ast;
}
-
-// merge test entry prop and function expression. case 6[x]
-const mergeTestPropArrowFunction = (j, chunkKey, testFunc) => {
- return j.property(
- "init",
- createIdentifierOrLiteral(j, "test"),
- j.arrowFunctionExpression(
- [j.identifier("module")],
- j.blockStatement([
- j.ifStatement(
- j.callExpression(
- j.memberExpression(
- j.callExpression(
- j.memberExpression(
- j.identifier("module"),
- j.identifier("getChunks"),
- ),
- [],
- ),
- j.identifier("some"),
- false,
- ),
- [j.arrowFunctionExpression(
- [j.identifier("chunk")],
- j.binaryExpression(
- "===",
- j.memberExpression(
- j.identifier("chunk"),
- j.identifier("name"),
- ),
- j.literal(chunkKey),
- ),
- )],
- ),
- j.returnStatement(
- j.literal(true),
- ),
- ),
- j.variableDeclaration(
- "const",
- [j.variableDeclarator(
- j.identifier("fn"),
- testFunc,
- )],
- ),
- j.returnStatement(
- j.callExpression(
- j.identifier("fn"),
- [j.identifier("module")],
- ),
- ),
- ]),
- ),
- );
-};
diff --git a/packages/migrate/extractTextPlugin/extractTextPlugin.ts b/packages/migrate/extractTextPlugin/extractTextPlugin.ts
index bf0cf39d937..fcc3931a394 100644
--- a/packages/migrate/extractTextPlugin/extractTextPlugin.ts
+++ b/packages/migrate/extractTextPlugin/extractTextPlugin.ts
@@ -1,6 +1,6 @@
import * as utils from "@webpack-cli/utils/ast-utils";
-import { IJSCodeshift, INode } from "../types/NodePath";
+import { JSCodeshift, Node } from "../types/NodePath";
/**
*
@@ -12,12 +12,12 @@ import { IJSCodeshift, INode } from "../types/NodePath";
* @returns {Boolean} isPluginInvocation - whether `node` is the invocation of the plugin denoted by `pluginName`
*/
-function findInvocation(j: IJSCodeshift, path: INode, pluginName: string): boolean {
- let found: boolean = false;
+function findInvocation(j: JSCodeshift, path: Node, pluginName: string): boolean {
+ let found = false;
found =
j(path)
.find(j.MemberExpression)
- .filter((p: INode): boolean => p.get("object").value.name === pluginName)
+ .filter((p: Node): boolean => (p.get("object").value as Node).name === pluginName)
.size() > 0;
return found;
}
@@ -31,30 +31,28 @@ function findInvocation(j: IJSCodeshift, path: INode, pluginName: string): boole
* @returns {Node} ast - jscodeshift ast
*/
-export default function(j: IJSCodeshift, ast: INode): void | INode {
- const changeArguments = (path: INode): INode => {
- const args: INode[] = path.value.arguments;
+export default function(j: JSCodeshift, ast: Node): void | Node {
+ const changeArguments = (path: Node): Node => {
+ const args: Node[] = (path.value as Node).arguments;
- const literalArgs: INode[] = args.filter((p: INode): boolean => utils.isType(p, "Literal"));
+ const literalArgs: Node[] = args.filter((p: Node): boolean => utils.isType(p, "Literal"));
if (literalArgs && literalArgs.length > 1) {
const newArgs: object = j.objectExpression(
- literalArgs.map((p: INode, index: number): INode =>
- utils.createProperty(j, index === 0 ? "fallback" : "use", p.value),
- ),
+ literalArgs.map(
+ (p: Node, index: number): Node => utils.createProperty(j, index === 0 ? "fallback" : "use", p.value as Node)
+ )
);
- path.value.arguments = [newArgs];
+ (path.value as Node).arguments = [newArgs];
}
return path;
};
- const name: string = utils.findVariableToPlugin(
- j,
- ast,
- "extract-text-webpack-plugin",
- );
- if (!name) { return ast; }
+ const name: string = utils.findVariableToPlugin(j, ast, "extract-text-webpack-plugin");
+ if (!name) {
+ return ast;
+ }
return ast
.find(j.CallExpression)
- .filter((p: INode): boolean => findInvocation(j, p, name))
+ .filter((p: Node): boolean => findInvocation(j, p, name))
.forEach(changeArguments);
}
diff --git a/packages/migrate/index.ts b/packages/migrate/index.ts
index 2a34c453438..09e6bcee346 100644
--- a/packages/migrate/index.ts
+++ b/packages/migrate/index.ts
@@ -10,19 +10,20 @@ import { validate, WebpackOptionsValidationError } from "webpack";
import runPrettier from "@webpack-cli/utils/run-prettier";
import { transformations } from "./migrate";
-import { IJSCodeshift, INode } from "./types/NodePath";
+import { Node } from "./types/NodePath";
+import jscodeshift from "jscodeshift";
declare var process: {
cwd: Function;
webpackModule: {
validate: Function;
- /* tslint:disable */
WebpackOptionsValidationError: {
- new: (errors: string[]) => {
+ new: (
+ errors: string[]
+ ) => {
message: string;
};
};
- /* tslint:enable */
};
stdout: {
write: Function;
@@ -30,6 +31,167 @@ declare var process: {
exitCode: number;
};
+/**
+ *
+ * Runs migration on a given configuration using AST's and promises
+ * to sequentially transform a configuration file.
+ *
+ * @param {String} currentConfigPath - input path for config
+ * @param {String} outputConfigPath - output path for config
+ * @returns {Promise} Runs the migration using a promise that
+ * will throw any errors during each transform or output if the
+ * user decides to abort the migration
+ */
+
+function runMigration(currentConfigPath: string, outputConfigPath: string): Promise | void {
+ const recastOptions: object = {
+ quote: "single"
+ };
+
+ const tasks: Listr = new Listr([
+ {
+ task: (ctx: Node): string | void | Listr | Promise<{}> =>
+ new pLazy(
+ (
+ resolve: (value?: object) => void,
+ reject: (reason?: string | object, err?: object) => void
+ ): void => {
+ fs.readFile(
+ currentConfigPath,
+ "utf8",
+ (err: object, content: string): void => {
+ if (err) {
+ reject(err);
+ }
+ try {
+ ctx.source = content;
+ ctx.ast = jscodeshift(content);
+ resolve();
+ } catch (err) {
+ reject("Error generating AST", err);
+ }
+ }
+ );
+ }
+ ),
+ title: "Reading webpack config"
+ },
+ {
+ task: (ctx: Node): string | void | Listr | Promise<{}> => {
+ return new Listr(
+ Object.keys(transformations).map(
+ (
+ key: string
+ ): {
+ task: () => string;
+ title: string;
+ } => {
+ const transform: Function = transformations[key];
+ return {
+ task: (): string => transform(ctx.ast, ctx.source),
+ title: key
+ };
+ }
+ )
+ );
+ },
+ title: "Migrating config to newest version"
+ }
+ ]);
+
+ tasks
+ .run()
+ .then(
+ (ctx: Node): void | Promise => {
+ const result: string = ctx.ast.toSource(recastOptions);
+ const diffOutput: diff.IDiffResult[] = diff.diffLines(ctx.source, result);
+
+ diffOutput.forEach(
+ (diffLine: diff.IDiffResult): void => {
+ if (diffLine.added) {
+ process.stdout.write(chalk.green(`+ ${diffLine.value}`));
+ } else if (diffLine.removed) {
+ process.stdout.write(chalk.red(`- ${diffLine.value}`));
+ }
+ }
+ );
+
+ return inquirer
+ .prompt([
+ {
+ default: "Y",
+ message: "Are you sure these changes are fine?",
+ name: "confirmMigration",
+ type: "confirm"
+ }
+ ])
+ .then(
+ (answers: { confirmMigration: boolean }): Promise<{}> => {
+ if (answers.confirmMigration) {
+ return inquirer.prompt([
+ {
+ default: "Y",
+ message:
+ "Do you want to validate your configuration? " +
+ "(If you're using webpack merge, validation isn't useful)",
+ name: "confirmValidation",
+ type: "confirm"
+ }
+ ]);
+ } else {
+ console.error(chalk.red("✖ Migration aborted"));
+ }
+ }
+ )
+ .then(
+ (answer: { confirmValidation: boolean }): void => {
+ if (!answer) {
+ return;
+ }
+
+ runPrettier(
+ outputConfigPath,
+ result,
+ (err: object): void => {
+ if (err) {
+ throw err;
+ }
+ }
+ );
+
+ if (answer.confirmValidation) {
+ const webpackOptionsValidationErrors: string[] = validate(require(outputConfigPath));
+
+ if (webpackOptionsValidationErrors.length) {
+ console.error(chalk.red("\n✖ Your configuration validation wasn't successful \n"));
+ console.error(
+ new WebpackOptionsValidationError(webpackOptionsValidationErrors).message
+ );
+ }
+ }
+
+ console.info(chalk.green(`\n✔︎ New webpack config file is at ${outputConfigPath}.`));
+ console.info(
+ chalk.green(
+ "✔︎ Heads up! Updating to the latest version could contain breaking changes."
+ )
+ );
+
+ console.info(chalk.green("✔︎ Plugin and loader dependencies may need to be updated."));
+ }
+ );
+ }
+ )
+ .catch(
+ (err: object): void => {
+ const errMsg = "\n ✖ ︎Migration aborted due to some errors: \n";
+ console.error(chalk.red(errMsg));
+ console.error(err);
+ process.exitCode = 1;
+ }
+ );
+}
+
/**
*
* Runs migration on a given configuration using AST's and promises
@@ -62,179 +224,25 @@ export default function migrate(...args: string[]): void | Promise {
"Do you want to use your existing webpack " +
"configuration?",
name: "confirmPath",
- type: "confirm",
- },
+ type: "confirm"
+ }
])
- .then((ans: {
- confirmPath: boolean;
- }): void | Promise => {
- if (!ans.confirmPath) {
- console.error(chalk.red("✖ ︎Migration aborted due no output path"));
- return;
+ .then(
+ (ans: { confirmPath: boolean }): void | Promise => {
+ if (!ans.confirmPath) {
+ console.error(chalk.red("✖ ︎Migration aborted due no output path"));
+ return;
+ }
+ outputConfigPath = path.resolve(process.cwd(), filePaths[0]);
+ return runMigration(currentConfigPath, outputConfigPath);
}
- outputConfigPath = path.resolve(process.cwd(), filePaths[0]);
- return runMigration(currentConfigPath, outputConfigPath);
- })
- .catch((err: object): void => {
- console.error(err);
- });
+ )
+ .catch(
+ (err: object): void => {
+ console.error(err);
+ }
+ );
}
outputConfigPath = path.resolve(process.cwd(), filePaths[1]);
return runMigration(currentConfigPath, outputConfigPath);
}
-
-/**
- *
- * Runs migration on a given configuration using AST's and promises
- * to sequentially transform a configuration file.
- *
- * @param {String} currentConfigPath - input path for config
- * @param {String} outputConfigPath - output path for config
- * @returns {Promise} Runs the migration using a promise that
- * will throw any errors during each transform or output if the
- * user decides to abort the migration
- */
-
-function runMigration(currentConfigPath: string, outputConfigPath: string): Promise | void {
- const recastOptions: object = {
- quote: "single",
- };
-
- const tasks: Listr = new Listr([
- {
- task: (ctx: INode): string | void | Listr | Promise<{}> =>
- new pLazy((
- resolve: (value?: object) => void,
- reject: (reason?: string | object, err?: object) => void,
- ) => {
- fs.readFile(currentConfigPath, "utf8", (err: object, content: string) => {
- if (err) {
- reject(err);
- }
- try {
- const jscodeshift: IJSCodeshift = require("jscodeshift");
- ctx.source = content;
- ctx.ast = jscodeshift(content);
- resolve();
- } catch (err) {
- reject("Error generating AST", err);
- }
- });
- }),
- title: "Reading webpack config",
- },
- {
- task: (ctx: INode): string | void | Listr | Promise => {
- return new Listr(
- Object.keys(transformations).map((key: string): {
- task: (_?: void) => string;
- title: string;
- } => {
- const transform: Function = transformations[key];
- return {
- task: (_?: void) => transform(ctx.ast, ctx.source),
- title: key,
- };
- }),
- );
- },
- title: "Migrating config to newest version",
- },
- ]);
-
- tasks
- .run()
- .then((ctx: INode): void | Promise => {
- const result: string = ctx.ast.toSource(recastOptions);
- const diffOutput: diff.IDiffResult[] = diff.diffLines(ctx.source, result);
-
- diffOutput.forEach((diffLine: diff.IDiffResult): void => {
- if (diffLine.added) {
- process.stdout.write(chalk.green(`+ ${diffLine.value}`));
- } else if (diffLine.removed) {
- process.stdout.write(chalk.red(`- ${diffLine.value}`));
- }
- });
-
- return inquirer
- .prompt([
- {
- default: "Y",
- message: "Are you sure these changes are fine?",
- name: "confirmMigration",
- type: "confirm",
- },
- ])
- .then((answers: {
- confirmMigration: boolean;
- }): Promise<{}> => {
- if (answers.confirmMigration) {
- return inquirer.prompt([
- {
- default: "Y",
- message:
- "Do you want to validate your configuration? " +
- "(If you're using webpack merge, validation isn't useful)",
- name: "confirmValidation",
- type: "confirm",
- },
- ]);
- } else {
- console.error(chalk.red("✖ Migration aborted"));
- }
- })
- .then((answer: {
- confirmValidation: boolean;
- }): void => {
- if (!answer) { return; }
-
- runPrettier(outputConfigPath, result, (err: object): void => {
- if (err) {
- throw err;
- }
- });
-
- if (answer.confirmValidation) {
- const webpackOptionsValidationErrors: string[] = validate(
- require(outputConfigPath),
- );
-
- if (webpackOptionsValidationErrors.length) {
- console.error(
- chalk.red(
- "\n✖ Your configuration validation wasn't successful \n",
- ),
- );
- console.error(
- new WebpackOptionsValidationError(
- webpackOptionsValidationErrors,
- ).message,
- );
- }
- }
-
- console.info(
- chalk.green(
- `\n✔︎ New webpack config file is at ${outputConfigPath}.`,
- ),
- );
- console.info(
- chalk.green(
- "✔︎ Heads up! Updating to the latest version could contain breaking changes.",
- ),
- );
-
- console.info(
- chalk.green(
- "✔︎ Plugin and loader dependencies may need to be updated.",
- ),
- );
- });
- })
- .catch((err: object): void => {
- const errMsg = "\n ✖ ︎Migration aborted due to some errors: \n";
- console.error(chalk.red(errMsg));
- console.error(err);
- process.exitCode = 1;
- });
-}
diff --git a/packages/migrate/loaderOptionsPlugin/loaderOptionsPlugin.ts b/packages/migrate/loaderOptionsPlugin/loaderOptionsPlugin.ts
index 681ff9579cd..b16a927d46b 100644
--- a/packages/migrate/loaderOptionsPlugin/loaderOptionsPlugin.ts
+++ b/packages/migrate/loaderOptionsPlugin/loaderOptionsPlugin.ts
@@ -1,14 +1,10 @@
import isEmpty = require("lodash/isEmpty");
-import {
- createOrUpdatePluginByName,
- findPluginsByName,
- safeTraverse,
-} from "@webpack-cli/utils/ast-utils";
+import { createOrUpdatePluginByName, findPluginsByName, safeTraverse } from "@webpack-cli/utils/ast-utils";
-import { IJSCodeshift, INode } from "../types/NodePath";
+import { JSCodeshift, Node } from "../types/NodePath";
-interface ILoaderOptions {
+interface LoaderOptions {
debug?: boolean;
minimize?: boolean;
}
@@ -23,18 +19,18 @@ interface ILoaderOptions {
*
*/
-export default function(j: IJSCodeshift, ast: INode): INode {
- const loaderOptions: ILoaderOptions = {};
+export default function(j: JSCodeshift, ast: Node): Node {
+ const loaderOptions: LoaderOptions = {};
// If there is debug: true, set debug: true in the plugin
if (ast.find(j.Identifier, { name: "debug" }).size()) {
loaderOptions.debug = true;
- ast
- .find(j.Identifier, { name: "debug" })
- .forEach((p: INode): void => {
+ ast.find(j.Identifier, { name: "debug" }).forEach(
+ (p: Node): void => {
p.parent.prune();
- });
+ }
+ );
}
// If there is UglifyJsPlugin, set minimize: true
@@ -44,18 +40,12 @@ export default function(j: IJSCodeshift, ast: INode): INode {
return ast
.find(j.ArrayExpression)
- .filter(
- (path: INode): boolean =>
- safeTraverse(path, ["parent", "value", "key", "name"]) === "plugins",
- )
- .forEach((path: INode): void => {
- if (!isEmpty(loaderOptions)) {
- createOrUpdatePluginByName(
- j,
- path,
- "webpack.LoaderOptionsPlugin",
- loaderOptions,
- );
+ .filter((path: Node): boolean => safeTraverse(path, ["parent", "value", "key", "name"]) === "plugins")
+ .forEach(
+ (path: Node): void => {
+ if (!isEmpty(loaderOptions)) {
+ createOrUpdatePluginByName(j, path, "webpack.LoaderOptionsPlugin", loaderOptions);
+ }
}
- });
+ );
}
diff --git a/packages/migrate/loaders/loaders.ts b/packages/migrate/loaders/loaders.ts
index e3b5b920fbb..0f5452c2ac1 100644
--- a/packages/migrate/loaders/loaders.ts
+++ b/packages/migrate/loaders/loaders.ts
@@ -1,6 +1,6 @@
import * as utils from "@webpack-cli/utils/ast-utils";
-import { IJSCodeshift, INode } from "../types/NodePath";
+import { JSCodeshift, Node } from "../types/NodePath";
/**
*
@@ -13,7 +13,7 @@ import { IJSCodeshift, INode } from "../types/NodePath";
* @returns {Node} ast - jscodeshift ast
*/
-export default function(j: IJSCodeshift, ast: INode): INode {
+export default function(j: JSCodeshift, ast: Node): Node {
/**
* Creates an Array expression out of loaders string
*
@@ -54,46 +54,46 @@ export default function(j: IJSCodeshift, ast: INode): INode {
* @returns {Node} path - object expression ast with array expression instead of loaders string
*/
- const createArrayExpressionFromArray = (path: INode): INode => {
- const value: INode = path.value;
+ const createArrayExpressionFromArray = (path: Node): Node => {
+ const value: Node = (path.value as Node);
// Find paths with `loaders` keys in the given Object
- const paths: INode[] = value.properties.filter((prop: INode): boolean =>
- prop.key.name.startsWith("loader"),
- );
+ const paths: Node[] = value.properties.filter((prop: Node): boolean => prop.key.name.startsWith("loader"));
// For each pair of key and value
- paths.forEach((pair: INode): void => {
- // Replace 'loaders' Identifier with 'use'
- pair.key.name = "use";
- // If the value is an Array
- if (pair.value.type === j.ArrayExpression.name) {
- // replace its elements
- const pairValue: INode = pair.value;
- pair.value = j.arrayExpression(
- pairValue.elements.map((arrElement: INode): INode => {
- // If items of the array are Strings
- if (arrElement.type === j.Literal.name) {
- // Replace with `{ loader: LOADER }` Object
- return j.objectExpression([
- utils.createProperty(j, "loader", arrElement.value),
- ]);
- }
- // otherwise keep the existing element
- return arrElement;
- }),
- );
- // If the value is String of loaders like 'style!css'
- } else if (pair.value.type === j.Literal.name) {
- // Replace it with Array expression of loaders
- const literalValue: INode = pair.value;
- pair.value = j.arrayExpression(
- literalValue.value.split("!").map((loader: string): INode => {
- return j.objectExpression([
- utils.createProperty(j, "loader", loader),
- ]);
- }),
- );
+ paths.forEach(
+ (pair: Node): void => {
+ // Replace 'loaders' Identifier with 'use'
+ pair.key.name = "use";
+ // If the value is an Array
+ if ((pair.value as Node).type === j.ArrayExpression.name) {
+ // replace its elements
+ const pairValue = pair.value as Node;
+ pair.value = j.arrayExpression(
+ pairValue.elements.map(
+ (arrElement: Node): Node => {
+ // If items of the array are Strings
+ if (arrElement.type === j.Literal.name) {
+ // Replace with `{ loader: LOADER }` Object
+ return j.objectExpression([utils.createProperty(j, "loader", (arrElement.value as Node))]);
+ }
+ // otherwise keep the existing element
+ return arrElement;
+ }
+ )
+ );
+ // If the value is String of loaders like 'style!css'
+ } else if ((pair.value as Node).type === j.Literal.name) {
+ // Replace it with Array expression of loaders
+ const literalValue = pair.value as Node;
+ pair.value = j.arrayExpression(
+ (literalValue.value as string).split("!").map(
+ (loader: string): Node => {
+ return j.objectExpression([utils.createProperty(j, "loader", loader)]);
+ }
+ )
+ );
+ }
}
- });
+ );
return path;
};
@@ -105,26 +105,24 @@ export default function(j: IJSCodeshift, ast: INode): INode {
* @returns {Node} objectExpression - an new object expression ast containing the query parameters
*/
- const createLoaderWithQuery = (p: INode): INode => {
- const properties: INode[] = p.value.properties;
+ const createLoaderWithQuery = (p: Node): Node => {
+ const properties: Node[] = (p.value as Node).properties;
const loaderValue: string = properties.reduce(
- (val: string, prop: INode): string => (prop.key.name === "loader" ? prop.value.value : val),
- "",
+ (val: string, prop: Node): string => (prop.key.name === "loader" ? (prop.value as Node).value as string: val),
+ ""
);
const loader: string = loaderValue.split("?")[0];
const query: string = loaderValue.split("?")[1];
- const options: INode[] = query.split("&").map((option: string): INode => {
- const param: string[] = option.split("=");
- const key: string = param[0];
- const val: string | boolean = param[1] || true; // No value in query string means it is truthy value
- return j.objectProperty(j.identifier(key), utils.createLiteral(j, val));
- });
- const loaderProp: INode = utils.createProperty(j, "loader", loader);
- const queryProp: INode = j.property(
- "init",
- j.identifier("options"),
- j.objectExpression(options),
+ const options: Node[] = query.split("&").map(
+ (option: string): Node => {
+ const param: string[] = option.split("=");
+ const key: string = param[0];
+ const val: string | boolean = param[1] || true; // No value in query string means it is truthy value
+ return j.objectProperty(j.identifier(key), utils.createLiteral(j, val));
+ }
);
+ const loaderProp: Node = utils.createProperty(j, "loader", loader);
+ const queryProp: Node = j.property("init", j.identifier("options"), j.objectExpression(options));
return j.objectExpression([loaderProp, queryProp]);
};
@@ -136,11 +134,10 @@ export default function(j: IJSCodeshift, ast: INode): INode {
* @returns {Boolean} hasLoaderQueryString - whether the loader object contains a query string
*/
- const findLoaderWithQueryString = (p: INode): boolean => {
- return p.value.properties.reduce((predicate: boolean, prop: INode): boolean => {
+ const findLoaderWithQueryString = (p: Node): boolean => {
+ return (p.value as Node).properties.reduce((predicate: boolean, prop: Node): boolean => {
return (
- (utils.safeTraverse(prop, ["value", "value", "indexOf"]) &&
- prop.value.value.indexOf("?") > -1) ||
+ (utils.safeTraverse(prop, ["value", "value", "indexOf"]) && ((prop.value as Node).value as string).indexOf("?") > -1) ||
predicate
);
}, false);
@@ -155,16 +152,9 @@ export default function(j: IJSCodeshift, ast: INode): INode {
* @returns {Boolean} isLoadersProp - whether the identifier is the `loaders` prop in the `module` object
*/
- const checkForLoader = (path: INode): boolean =>
- path.value.name === "loaders" &&
- utils.safeTraverse(path, [
- "parent",
- "parent",
- "parent",
- "node",
- "key",
- "name",
- ]) === "module";
+ const checkForLoader = (path: Node): boolean =>
+ (path.value as Node).name === "loaders" &&
+ utils.safeTraverse(path, ["parent", "parent", "parent", "node", "key", "name"]) === "module";
/**
* Puts pre- or postLoader into `loaders` object and adds the appropriate `enforce` property
@@ -173,32 +163,36 @@ export default function(j: IJSCodeshift, ast: INode): INode {
* @returns {Node} p - object expression with a `loaders` object and appropriate `enforce` properties
*/
- const fitIntoLoaders = (p: INode): INode => {
- let loaders: INode = null;
- p.value.properties.map((prop: INode): void => {
- const keyName = prop.key.name;
- if (keyName === "loaders") {
- loaders = prop.value;
+ const fitIntoLoaders = (p: Node): Node => {
+ let loaders: Node = null;
+ (p.value as Node).properties.map(
+ (prop: Node): void => {
+ const keyName = prop.key.name;
+ if (keyName === "loaders") {
+ loaders = prop.value as Node;
+ }
}
- });
- p.value.properties.map((prop: INode): void => {
- const keyName = prop.key.name;
- if (keyName !== "loaders") {
- const enforceVal: string = keyName === "preLoaders" ? "pre" : "post";
- prop.value.elements.map((elem: INode): void => {
- elem.properties.push(utils.createProperty(j, "enforce", enforceVal));
- if (loaders && loaders.type === "ArrayExpression") {
- loaders.elements.push(elem);
- } else {
- prop.key.name = "loaders";
- }
- });
+ );
+ (p.value as Node).properties.map(
+ (prop: Node): void => {
+ const keyName = prop.key.name;
+ if (keyName !== "loaders") {
+ const enforceVal: string = keyName === "preLoaders" ? "pre" : "post";
+ (prop.value as Node).elements.map(
+ (elem: Node): void => {
+ elem.properties.push(utils.createProperty(j, "enforce", enforceVal));
+ if (loaders && loaders.type === "ArrayExpression") {
+ loaders.elements.push(elem);
+ } else {
+ prop.key.name = "loaders";
+ }
+ }
+ );
+ }
}
- });
+ );
if (loaders) {
- p.value.properties = p.value.properties.filter(
- (prop: INode): boolean => prop.key.name === "loaders",
- );
+ (p.value as Node).properties = (p.value as Node).properties.filter((prop: Node): boolean => prop.key.name === "loaders");
}
return p;
};
@@ -209,10 +203,10 @@ export default function(j: IJSCodeshift, ast: INode): INode {
* @returns {Node} ast - jscodeshift ast
*/
- const prepostLoaders = (_?: void): INode =>
+ const prepostLoaders = (): Node =>
ast
.find(j.ObjectExpression)
- .filter((p: INode): boolean => utils.findObjWithOneOfKeys(p, ["preLoaders", "postLoaders"]))
+ .filter((p: Node): boolean => utils.findObjWithOneOfKeys(p, ["preLoaders", "postLoaders"]))
.forEach(fitIntoLoaders);
/**
@@ -221,11 +215,11 @@ export default function(j: IJSCodeshift, ast: INode): INode {
* @returns {Node} ast - jscodeshift ast
*/
- const loadersToRules = (_?: void): INode =>
+ const loadersToRules = (): Node =>
ast
.find(j.Identifier)
.filter(checkForLoader)
- .forEach((p: INode): string => (p.value.name = "rules"));
+ .forEach((p: Node): string => ((p.value as Node).name = "rules"));
/**
* Convert `loader` and `loaders` to Array of {Rule.Use}
@@ -233,19 +227,13 @@ export default function(j: IJSCodeshift, ast: INode): INode {
* @returns {Node} ast - jscodeshift ast
*/
- const loadersToArrayExpression = (_?: void): INode | void =>
+ const loadersToArrayExpression = (): Node | void =>
ast
.find(j.ObjectExpression)
- .filter((path: INode): boolean => utils.findObjWithOneOfKeys(path, ["loader", "loaders"]))
+ .filter((path: Node): boolean => utils.findObjWithOneOfKeys(path, ["loader", "loaders"]))
.filter(
- (path: INode): boolean =>
- utils.safeTraverse(path, [
- "parent",
- "parent",
- "node",
- "key",
- "name",
- ]) === "rules",
+ (path: Node): boolean =>
+ utils.safeTraverse(path, ["parent", "parent", "node", "key", "name"]) === "rules"
)
.forEach(createArrayExpressionFromArray);
@@ -271,10 +259,10 @@ export default function(j: IJSCodeshift, ast: INode): INode {
* @returns {Node} ast - jscodeshift ast
*/
- const loaderWithQueryParam = (_?: void): INode =>
+ const loaderWithQueryParam = (): Node =>
ast
.find(j.ObjectExpression)
- .filter((p: INode): boolean => utils.findObjWithOneOfKeys(p, ["loader"]))
+ .filter((p: Node): boolean => utils.findObjWithOneOfKeys(p, ["loader"]))
.filter(findLoaderWithQueryString)
.replaceWith(createLoaderWithQuery);
@@ -295,10 +283,10 @@ export default function(j: IJSCodeshift, ast: INode): INode {
* @returns {Node} ast - jscodeshift ast
*/
- const loaderWithQueryProp = (_?: void): INode =>
+ const loaderWithQueryProp = (): Node =>
ast
.find(j.Identifier)
- .filter((p: INode): boolean => p.value.name === "query")
+ .filter((p: Node): boolean => (p.value as Node).name === "query")
.replaceWith(j.identifier("options"));
/**
@@ -308,18 +296,22 @@ export default function(j: IJSCodeshift, ast: INode): INode {
* @returns {Node} ast - jscodeshift ast
*/
- const addLoaderSuffix = (_?: void): INode =>
- ast.find(j.ObjectExpression).forEach((path: INode): void => {
- path.value.properties.forEach((prop: INode): void => {
- if (
- prop.key.name === "loader" &&
- utils.safeTraverse(prop, ["value", "value"]) &&
- !prop.value.value.endsWith("-loader")
- ) {
- prop.value = j.literal(prop.value.value + "-loader");
- }
- });
- });
+ const addLoaderSuffix = (): Node =>
+ ast.find(j.ObjectExpression).forEach(
+ (path: Node): void => {
+ (path.value as Node).properties.forEach(
+ (prop: Node): void => {
+ if (
+ prop.key.name === "loader" &&
+ utils.safeTraverse(prop, ["value", "value"]) &&
+ !((prop.value as Node).value as string).endsWith("-loader")
+ ) {
+ prop.value = j.literal((prop.value as Node).value as string + "-loader");
+ }
+ }
+ );
+ }
+ );
/**
*
@@ -329,26 +321,28 @@ export default function(j: IJSCodeshift, ast: INode): INode {
* @returns {Node} objectExpression - an use object expression ast containing the options and loader
*/
- const fitOptionsToUse = (p: INode): INode => {
- let options: INode = null;
- p.value.properties.forEach((prop: INode): void => {
- const keyName: string = prop.key.name;
- if (keyName === "options") {
- options = prop;
+ const fitOptionsToUse = (p: Node): Node => {
+ let options: Node = null;
+ (p.value as Node).properties.forEach(
+ (prop: Node): void => {
+ const keyName: string = prop.key.name;
+ if (keyName === "options") {
+ options = prop;
+ }
}
- });
+ );
if (options) {
- p.value.properties = p.value.properties.filter(
- (prop: INode): boolean => prop.key.name !== "options",
- );
+ (p.value as Node).properties = (p.value as Node).properties.filter((prop: Node): boolean => prop.key.name !== "options");
- p.value.properties.forEach((prop: INode): void => {
- const keyName = prop.key.name;
- if (keyName === "use") {
- prop.value.elements[0].properties.push(options);
+ (p.value as Node).properties.forEach(
+ (prop: Node): void => {
+ const keyName = prop.key.name;
+ if (keyName === "use") {
+ (prop.value as Node).elements[0].properties.push(options);
+ }
}
- });
+ );
}
return p;
@@ -360,10 +354,10 @@ export default function(j: IJSCodeshift, ast: INode): INode {
* @returns {Node} ast - jscodeshift ast
*/
- const moveOptionsToUse = (_?: void): INode =>
+ const moveOptionsToUse = (): Node =>
ast
.find(j.ObjectExpression)
- .filter((p: INode): boolean => utils.findObjWithOneOfKeys(p, ["use"]))
+ .filter((p: Node): boolean => utils.findObjWithOneOfKeys(p, ["use"]))
.forEach(fitOptionsToUse);
const transforms = [
@@ -373,7 +367,7 @@ export default function(j: IJSCodeshift, ast: INode): INode {
loaderWithQueryParam,
loaderWithQueryProp,
addLoaderSuffix,
- moveOptionsToUse,
+ moveOptionsToUse
];
transforms.forEach((t: Function): void => t());
diff --git a/packages/migrate/migrate.ts b/packages/migrate/migrate.ts
index 09baf1b087d..bfed7bee56d 100644
--- a/packages/migrate/migrate.ts
+++ b/packages/migrate/migrate.ts
@@ -11,13 +11,12 @@ import noEmitOnErrorsPluginTransform from "./noEmitOnErrorsPlugin/noEmitOnErrors
import removeDeprecatedPluginsTransform from "./removeDeprecatedPlugins/removeDeprecatedPlugins";
import removeJsonLoaderTransform from "./removeJsonLoader/removeJsonLoader";
import resolveTransform from "./resolve/resolve";
-import { INode } from "./types/NodePath";
import uglifyJsPluginTransform from "./uglifyJsPlugin/uglifyJsPlugin";
-interface ITransformsObject {
+interface TransformsObject {
bannerPluginTransform: object;
commonsChunkPluginTransform?: object;
- extractTextPluginTransform: object; /* tslint:disable */
+ extractTextPluginTransform: object;
loaderOptionsPluginTransform: object;
loadersTransform: object;
noEmitOnErrorsPluginTransform: object;
@@ -27,8 +26,7 @@ interface ITransformsObject {
uglifyJsPluginTransform: object;
}
-/* tslint:disable object-literal-sort-keys */
-const transformsObject: ITransformsObject = {
+const transformsObject: TransformsObject = {
loadersTransform,
resolveTransform,
removeJsonLoaderTransform,
@@ -38,10 +36,10 @@ const transformsObject: ITransformsObject = {
extractTextPluginTransform,
noEmitOnErrorsPluginTransform,
removeDeprecatedPluginsTransform,
- commonsChunkPluginTransform,
+ commonsChunkPluginTransform
};
-interface ILazyTransformObject {
+interface LazyTransformObject {
loadersTransform?: (ast: object, source: string) => pLazy<{}>;
resolveTransform?: (ast: object, source: string) => pLazy<{}>;
removeJsonLoaderTransform?: (ast: object, source: string) => pLazy<{}>;
@@ -53,16 +51,6 @@ interface ILazyTransformObject {
removeDeprecatedPluginsTransform?: (ast: object, source: string) => pLazy<{}>;
commonsChunkPluginTransform?: (ast: object, source: string) => pLazy<{}>;
}
-/* tslint:enable object-literal-sort-keys */
-
-export const transformations: ILazyTransformObject =
- Object
- .keys(transformsObject)
- .reduce((res: object, key: string): ILazyTransformObject => {
- res[key] = (ast: object, source: string) =>
- transformSingleAST(ast, source, transformsObject[key]);
- return res;
- }, {});
/**
*
@@ -78,23 +66,29 @@ export const transformations: ILazyTransformObject =
export const transformSingleAST = (
ast: object,
source: string,
- transformFunction: (jscodeshift: object, ast: object, source: string) => object)
- : pLazy<{}> => {
-
- return new pLazy((
- resolve: (value?: {} | PromiseLike<{}>) => void,
- reject: (reason?: object) => void,
- ): void => {
- setTimeout((_?: void): void => {
- try {
- resolve(transformFunction(jscodeshift, ast, source));
- } catch (err) {
- reject(err);
- }
- }, 0);
- });
+ transformFunction: (jscodeshift: object, ast: object, source: string) => object
+): pLazy<{}> => {
+ return new pLazy(
+ (resolve: (value?: {} | PromiseLike<{}>) => void, reject: (reason?: object) => void): void => {
+ setTimeout((): void => {
+ try {
+ resolve(transformFunction(jscodeshift, ast, source));
+ } catch (err) {
+ reject(err);
+ }
+ }, 0);
+ }
+ );
};
+export const transformations: LazyTransformObject = Object.keys(transformsObject).reduce(
+ (res: object, key: string): LazyTransformObject => {
+ res[key] = (ast: object, source: string): object => transformSingleAST(ast, source, transformsObject[key]);
+ return res;
+ },
+ {}
+);
+
/**
*
* Transforms a given piece of source code by applying selected transformations to the AST.
@@ -111,24 +105,26 @@ export const transformSingleAST = (
export const transform = (
source: string,
transforms?: Iterable>,
- options?: object)
- : Promise => {
-
- const ast: INode = jscodeshift(source);
+ options?: object
+): Promise => {
+ const ast = jscodeshift(source);
const recastOptions: object = Object.assign(
{
- quote: "single",
+ quote: "single"
},
- options,
+ options
);
- transforms =
- transforms || Object.keys(transformations).map((k: string): Function => transformations[k]);
+ transforms = transforms || Object.keys(transformations).map((k: string): Function => transformations[k]);
- return pEachSeries(transforms, (f: Function) => f(ast, source))
- .then((value: Function[]): string | PromiseLike => {
- return ast.toSource(recastOptions);
- })
- .catch((err: object) => {
- console.error(err);
- });
+ return pEachSeries(transforms, (f: Function): void => f(ast, source))
+ .then(
+ (): string | PromiseLike => {
+ return ast.toSource(recastOptions);
+ }
+ )
+ .catch(
+ (err: object): void => {
+ console.error(err);
+ }
+ );
};
diff --git a/packages/migrate/moduleConcatenationPlugin/moduleConcatenationPlugin.ts b/packages/migrate/moduleConcatenationPlugin/moduleConcatenationPlugin.ts
index 21750bc8663..658d2c1359f 100644
--- a/packages/migrate/moduleConcatenationPlugin/moduleConcatenationPlugin.ts
+++ b/packages/migrate/moduleConcatenationPlugin/moduleConcatenationPlugin.ts
@@ -1,9 +1,6 @@
-import {
- addOrUpdateConfigObject,
- findAndRemovePluginByName,
-} from "@webpack-cli/utils/ast-utils";
+import { addOrUpdateConfigObject, findAndRemovePluginByName } from "@webpack-cli/utils/ast-utils";
-import { IJSCodeshift, INode } from "../types/NodePath";
+import { JSCodeshift, Node } from "../types/NodePath";
/**
*
@@ -14,23 +11,13 @@ import { IJSCodeshift, INode } from "../types/NodePath";
* @param {Node} ast - jscodeshift ast to transform
* @returns {Node} ast - jscodeshift ast
*/
-export default function(j: IJSCodeshift, ast: INode): INode {
+export default function(j: JSCodeshift, ast: Node): Node {
// Remove old plugin
- const root: INode = findAndRemovePluginByName(
- j,
- ast,
- "webpack.optimize.ModuleConcatenationPlugin",
- );
+ const root: Node = findAndRemovePluginByName(j, ast, "webpack.optimize.ModuleConcatenationPlugin");
// Add new optimizations option
if (root) {
- addOrUpdateConfigObject(
- j,
- root,
- "optimizations",
- "concatenateModules",
- j.booleanLiteral(true),
- );
+ addOrUpdateConfigObject(j, root, "optimizations", "concatenateModules", j.booleanLiteral(true));
}
return ast;
diff --git a/packages/migrate/namedModulesPlugin/namedModulesPlugin.ts b/packages/migrate/namedModulesPlugin/namedModulesPlugin.ts
index 98c7e2ceb9c..34faab3cd4b 100644
--- a/packages/migrate/namedModulesPlugin/namedModulesPlugin.ts
+++ b/packages/migrate/namedModulesPlugin/namedModulesPlugin.ts
@@ -1,9 +1,6 @@
-import {
- addOrUpdateConfigObject,
- findAndRemovePluginByName,
-} from "@webpack-cli/utils/ast-utils";
+import { addOrUpdateConfigObject, findAndRemovePluginByName } from "@webpack-cli/utils/ast-utils";
-import { IJSCodeshift, INode } from "../types/NodePath";
+import { JSCodeshift, Node } from "../types/NodePath";
/**
*
@@ -14,19 +11,13 @@ import { IJSCodeshift, INode } from "../types/NodePath";
* @param {Node} ast - jscodeshift ast to transform
* @returns {Node} ast - jscodeshift ast
*/
-export default function(j: IJSCodeshift, ast: INode): INode {
+export default function(j: JSCodeshift, ast: Node): Node {
// Remove old plugin
- const root: INode = findAndRemovePluginByName(j, ast, "webpack.NamedModulesPlugin");
+ const root: Node = findAndRemovePluginByName(j, ast, "webpack.NamedModulesPlugin");
// Add new optimizations option
if (root) {
- addOrUpdateConfigObject(
- j,
- root,
- "optimizations",
- "namedModules",
- j.booleanLiteral(true),
- );
+ addOrUpdateConfigObject(j, root, "optimizations", "namedModules", j.booleanLiteral(true));
}
return ast;
diff --git a/packages/migrate/noEmitOnErrorsPlugin/noEmitOnErrorsPlugin.ts b/packages/migrate/noEmitOnErrorsPlugin/noEmitOnErrorsPlugin.ts
index c45ce923185..567d688a47c 100644
--- a/packages/migrate/noEmitOnErrorsPlugin/noEmitOnErrorsPlugin.ts
+++ b/packages/migrate/noEmitOnErrorsPlugin/noEmitOnErrorsPlugin.ts
@@ -1,8 +1,5 @@
-import {
- addOrUpdateConfigObject,
- findAndRemovePluginByName,
-} from "@webpack-cli/utils/ast-utils";
-import { IJSCodeshift, INode } from "../types/NodePath";
+import { addOrUpdateConfigObject, findAndRemovePluginByName } from "@webpack-cli/utils/ast-utils";
+import { JSCodeshift, Node } from "../types/NodePath";
/**
*
@@ -13,23 +10,13 @@ import { IJSCodeshift, INode } from "../types/NodePath";
* @param {Node} ast - jscodeshift ast to transform
* @returns {Node} ast - jscodeshift ast
*/
-export default function(j: IJSCodeshift, ast: INode): INode {
+export default function(j: JSCodeshift, ast: Node): Node {
// Remove old plugin
- const root: INode = findAndRemovePluginByName(
- j,
- ast,
- "webpack.NoEmitOnErrorsPlugin",
- );
+ const root: Node = findAndRemovePluginByName(j, ast, "webpack.NoEmitOnErrorsPlugin");
// Add new optimizations option
if (root) {
- addOrUpdateConfigObject(
- j,
- root,
- "optimizations",
- "noEmitOnErrors",
- j.booleanLiteral(true),
- );
+ addOrUpdateConfigObject(j, root, "optimizations", "noEmitOnErrors", j.booleanLiteral(true));
}
return ast;
diff --git a/packages/migrate/outputPath/outputPath.ts b/packages/migrate/outputPath/outputPath.ts
index 5e88223d808..e3d1c0bd087 100644
--- a/packages/migrate/outputPath/outputPath.ts
+++ b/packages/migrate/outputPath/outputPath.ts
@@ -1,6 +1,20 @@
import * as utils from "@webpack-cli/utils/ast-utils";
-import { IJSCodeshift, INode } from "../types/NodePath";
+import { JSCodeshift, Node } from "../types/NodePath";
+
+
+function replaceWithPath(
+ j: JSCodeshift,
+ p: Node,
+ pathVarName: string,
+): Node {
+ const convertedPath: Node = j.callExpression(
+ j.memberExpression(j.identifier(pathVarName), j.identifier("join"), false),
+ [j.identifier("__dirname"), p.value as Node],
+ );
+
+ return convertedPath;
+}
/**
*
@@ -10,18 +24,17 @@ import { IJSCodeshift, INode } from "../types/NodePath";
* @param {Node} ast - jscodeshift ast to transform
* @returns {Node} ast - jscodeshift ast
*/
-
-export default function(j: IJSCodeshift, ast: INode): INode | void {
- const literalOutputPath: INode = ast
+export default function(j: JSCodeshift, ast: Node): Node | void {
+ const literalOutputPath: Node = ast
.find(j.ObjectExpression)
.filter(
- (p: INode): boolean =>
+ (p: Node): boolean =>
utils.safeTraverse(p, ["parentPath", "value", "key", "name"]) ===
"output",
)
.find(j.Property)
.filter(
- (p: INode): boolean =>
+ (p: Node): boolean =>
utils.safeTraverse(p, ["value", "key", "name"]) === "path" &&
utils.safeTraverse(p, ["value", "value", "type"]) === "Literal",
);
@@ -29,18 +42,20 @@ export default function(j: IJSCodeshift, ast: INode): INode | void {
if (literalOutputPath) {
let pathVarName = "path";
let isPathPresent = false;
- const pathDeclaration: INode = ast
+ const pathDeclaration: Node = ast
.find(j.VariableDeclarator)
.filter(
- (p: INode): boolean =>
+ (p: Node): boolean =>
utils.safeTraverse(p, ["value", "init", "callee", "name"]) ===
"require",
)
.filter(
- (p: INode): boolean =>
+ (p: Node): boolean =>
utils.safeTraverse(p, ["value", "init", "arguments"]) &&
- p.value.init.arguments.reduce(
- (isPresent: boolean, a: INode): boolean => {
+ // TODO: to fix when we have proper typing (@types/jscodeshift)
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ (p.value as any).init.arguments.reduce(
+ (isPresent: boolean, a: Node): boolean => {
return (a.type === "Literal" && a.value === "path") || isPresent;
},
false,
@@ -50,23 +65,23 @@ export default function(j: IJSCodeshift, ast: INode): INode | void {
if (pathDeclaration) {
isPathPresent = true;
pathDeclaration.forEach(
- (p: INode): void => {
- pathVarName = utils.safeTraverse(p, ["value", "id", "name"]);
+ (p: Node): void => {
+ pathVarName = utils.safeTraverse(p, ["value", "id", "name"]) as string;
},
);
}
const finalPathName = pathVarName;
literalOutputPath
.find(j.Literal)
- .replaceWith((p: INode): INode => replaceWithPath(j, p, finalPathName));
+ .replaceWith((p: Node): Node => replaceWithPath(j, p, finalPathName));
if (!isPathPresent) {
- const pathRequire: INode = utils.getRequire(j, "path", "path");
+ const pathRequire: Node = utils.getRequire(j, "path", "path");
return ast
.find(j.Program)
.replaceWith(
- (p: INode): INode =>
- j.program([].concat(pathRequire).concat(p.value.body)),
+ (p: Node): Node =>
+ j.program([].concat(pathRequire).concat((p.value as Node).body)),
);
}
}
@@ -74,15 +89,3 @@ export default function(j: IJSCodeshift, ast: INode): INode | void {
return ast;
}
-function replaceWithPath(
- j: IJSCodeshift,
- p: INode,
- pathVarName: string,
-): INode {
- const convertedPath: INode = j.callExpression(
- j.memberExpression(j.identifier(pathVarName), j.identifier("join"), false),
- [j.identifier("__dirname"), p.value],
- );
-
- return convertedPath;
-}
diff --git a/packages/migrate/package-lock.json b/packages/migrate/package-lock.json
index 4c6b238c144..c70bc03abc9 100644
--- a/packages/migrate/package-lock.json
+++ b/packages/migrate/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "@webpack-cli/migrate",
- "version": "0.1.3",
+ "version": "0.1.5",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -67,7 +67,7 @@
},
"@types/listr": {
"version": "0.13.0",
- "resolved": "http://registry.npmjs.org/@types/listr/-/listr-0.13.0.tgz",
+ "resolved": "https://registry.npmjs.org/@types/listr/-/listr-0.13.0.tgz",
"integrity": "sha512-8DOy0JCGwwAf76xmU0sRzSZCWKSPPA9djRcTYTsyqBPnMdGOjZ5tjmNswC4J9mgKZudte2tuTo1l14R1/t5l/g==",
"dev": true,
"requires": {
@@ -100,7 +100,7 @@
},
"@types/rx": {
"version": "4.1.1",
- "resolved": "http://registry.npmjs.org/@types/rx/-/rx-4.1.1.tgz",
+ "resolved": "https://registry.npmjs.org/@types/rx/-/rx-4.1.1.tgz",
"integrity": "sha1-WY/JSla67ZdfGUV04PVy/Y5iekg=",
"dev": true,
"requires": {
@@ -488,7 +488,7 @@
},
"ansi-escapes": {
"version": "3.1.0",
- "resolved": "http://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz",
"integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw=="
},
"ansi-regex": {
@@ -840,7 +840,7 @@
},
"array-equal": {
"version": "1.0.0",
- "resolved": "http://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz",
+ "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz",
"integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=",
"dev": true
},
@@ -991,7 +991,7 @@
},
"chalk": {
"version": "1.1.3",
- "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
"requires": {
"ansi-styles": "^2.2.1",
@@ -1011,7 +1011,7 @@
},
"supports-color": {
"version": "2.0.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "resolved": "http://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc="
}
}
@@ -1245,7 +1245,7 @@
},
"babel-plugin-istanbul": {
"version": "4.1.6",
- "resolved": "http://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.6.tgz",
+ "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.6.tgz",
"integrity": "sha512-PWP9FQ1AhZhS01T/4qLSKoHGY/xvkZdVBGlKM/HuxxS3+sC66HhTNR7+MpbO/so/cz/wY94MeSWJuP1hXIPfwQ==",
"dev": true,
"requires": {
@@ -1308,7 +1308,7 @@
},
"babel-plugin-syntax-object-rest-spread": {
"version": "6.13.0",
- "resolved": "http://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz",
+ "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz",
"integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U="
},
"babel-plugin-syntax-trailing-function-commas": {
@@ -1943,7 +1943,7 @@
},
"browserify-aes": {
"version": "1.2.0",
- "resolved": "http://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
+ "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
"integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
"dev": true,
"requires": {
@@ -1980,7 +1980,7 @@
},
"browserify-rsa": {
"version": "4.0.1",
- "resolved": "http://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
+ "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
"integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=",
"dev": true,
"requires": {
@@ -2023,7 +2023,7 @@
},
"buffer": {
"version": "4.9.1",
- "resolved": "http://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz",
"integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=",
"dev": true,
"requires": {
@@ -2458,7 +2458,7 @@
},
"string-width": {
"version": "1.0.2",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+ "resolved": "http://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
"dev": true,
"requires": {
@@ -2640,7 +2640,7 @@
},
"create-hash": {
"version": "1.2.0",
- "resolved": "http://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
+ "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
"integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
"dev": true,
"requires": {
@@ -2653,7 +2653,7 @@
},
"create-hmac": {
"version": "1.1.7",
- "resolved": "http://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
+ "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
"integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
"dev": true,
"requires": {
@@ -2894,7 +2894,7 @@
},
"diffie-hellman": {
"version": "5.0.3",
- "resolved": "http://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
+ "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
"integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==",
"dev": true,
"requires": {
@@ -3152,7 +3152,7 @@
},
"expand-range": {
"version": "1.8.2",
- "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz",
+ "resolved": "http://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz",
"integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=",
"requires": {
"fill-range": "^2.1.0"
@@ -4381,7 +4381,7 @@
},
"is-accessor-descriptor": {
"version": "0.1.6",
- "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "resolved": "http://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
"integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
"dev": true,
"requires": {
@@ -4434,7 +4434,7 @@
},
"is-data-descriptor": {
"version": "0.1.4",
- "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "resolved": "http://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
"integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
"dev": true,
"requires": {
@@ -4504,7 +4504,7 @@
},
"is-generator-fn": {
"version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-1.0.0.tgz",
+ "resolved": "http://registry.npmjs.org/is-generator-fn/-/is-generator-fn-1.0.0.tgz",
"integrity": "sha1-lp1J4bszKfa7fwkIm+JleLLd1Go=",
"dev": true
},
@@ -5412,7 +5412,7 @@
},
"chalk": {
"version": "1.1.3",
- "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
"requires": {
"ansi-styles": "^2.2.1",
@@ -5441,7 +5441,7 @@
},
"supports-color": {
"version": "2.0.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "resolved": "http://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc="
}
}
@@ -5551,7 +5551,7 @@
},
"chalk": {
"version": "1.1.3",
- "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
"requires": {
"ansi-styles": "^2.2.1",
@@ -5571,7 +5571,7 @@
},
"supports-color": {
"version": "2.0.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "resolved": "http://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc="
}
}
@@ -5849,7 +5849,7 @@
},
"mute-stream": {
"version": "0.0.7",
- "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
+ "resolved": "http://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
"integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s="
},
"nan": {
@@ -6327,7 +6327,7 @@
},
"path-browserify": {
"version": "0.0.0",
- "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz",
+ "resolved": "http://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz",
"integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=",
"dev": true
},
@@ -7151,7 +7151,7 @@
},
"resolve": {
"version": "1.1.7",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
+ "resolved": "http://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
"integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=",
"dev": true
},
@@ -7864,7 +7864,7 @@
},
"sprintf-js": {
"version": "1.0.3",
- "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "resolved": "http://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
"dev": true
},
@@ -7929,7 +7929,7 @@
},
"stream-browserify": {
"version": "2.0.1",
- "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz",
+ "resolved": "http://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz",
"integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=",
"dev": true,
"requires": {
@@ -8008,7 +8008,7 @@
},
"string_decoder": {
"version": "1.1.1",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"dev": true,
"requires": {
@@ -8284,7 +8284,7 @@
},
"tty-browserify": {
"version": "0.0.0",
- "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
+ "resolved": "http://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
"integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=",
"dev": true
},
@@ -8547,7 +8547,7 @@
},
"vm-browserify": {
"version": "0.0.4",
- "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz",
+ "resolved": "http://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz",
"integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=",
"dev": true,
"requires": {
@@ -8715,7 +8715,7 @@
},
"is-accessor-descriptor": {
"version": "0.1.6",
- "resolved": "http://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
"integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
"dev": true,
"requires": {
@@ -8735,7 +8735,7 @@
},
"is-data-descriptor": {
"version": "0.1.4",
- "resolved": "http://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
"integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
"dev": true,
"requires": {
diff --git a/packages/migrate/removeDeprecatedPlugins/removeDeprecatedPlugins.ts b/packages/migrate/removeDeprecatedPlugins/removeDeprecatedPlugins.ts
index 01030eb7686..e7f7518bdad 100644
--- a/packages/migrate/removeDeprecatedPlugins/removeDeprecatedPlugins.ts
+++ b/packages/migrate/removeDeprecatedPlugins/removeDeprecatedPlugins.ts
@@ -2,7 +2,7 @@ import chalk from "chalk";
import * as utils from "@webpack-cli/utils/ast-utils";
-import { IJSCodeshift, INode } from "../types/NodePath";
+import { JSCodeshift, Node } from "../types/NodePath";
/**
*
@@ -14,37 +14,34 @@ import { IJSCodeshift, INode } from "../types/NodePath";
* @returns {Node} ast - jscodeshift ast
*/
-export default function(j: IJSCodeshift, ast: INode) {
- // List of deprecated plugins to remove
- // each item refers to webpack.optimize.[NAME] construct
- const deprecatedPlugingsList: string[] = [
- "webpack.optimize.OccurrenceOrderPlugin",
- "webpack.optimize.DedupePlugin",
- ];
+export default function(j: JSCodeshift, ast: Node): Node {
+ // List of deprecated plugins to remove
+ // each item refers to webpack.optimize.[NAME] construct
+ const deprecatedPlugingsList: string[] = [
+ "webpack.optimize.OccurrenceOrderPlugin",
+ "webpack.optimize.DedupePlugin"
+ ];
- return utils.findPluginsByName(j, ast, deprecatedPlugingsList).forEach(
- (path: INode): void => {
- // For now we only support the case where plugins are defined in an Array
- const arrayPath: INode = utils.safeTraverse(path, ["parent", "value"]);
+ return utils.findPluginsByName(j, ast, deprecatedPlugingsList).forEach(
+ (path: Node): void => {
+ // For now we only support the case where plugins are defined in an Array
+ const arrayPath = utils.safeTraverse(path, ["parent", "value"]) as Node;
- if (arrayPath && utils.isType(arrayPath, "ArrayExpression")) {
- // Check how many plugins are defined and
- // if there is only last plugin left remove `plugins: []` node
- const arrayElementsPath: INode[] = utils.safeTraverse(arrayPath, [
- "elements",
- ]);
- if (arrayElementsPath && arrayElementsPath.length === 1) {
- j(path.parent.parent).remove();
- } else {
- j(path).remove();
- }
- } else {
- console.error(`
+ if (arrayPath && utils.isType(arrayPath, "ArrayExpression")) {
+ // Check how many plugins are defined and
+ // if there is only last plugin left remove `plugins: []` node
+ //
+ const arrayElementsPath = utils.safeTraverse(arrayPath, ["elements"]) as Node[];
+ if (arrayElementsPath && arrayElementsPath.length === 1) {
+ j(path.parent.parent).remove();
+ } else {
+ j(path).remove();
+ }
+ } else {
+ console.error(`
${chalk.red("Please remove deprecated plugins manually. ")}
-See ${chalk.underline(
- "https://webpack.js.org/guides/migrating/",
- )} for more information.`);
+See ${chalk.underline("https://webpack.js.org/guides/migrating/")} for more information.`);
+ }
}
- },
- );
+ );
}
diff --git a/packages/migrate/removeJsonLoader/removeJsonLoader.ts b/packages/migrate/removeJsonLoader/removeJsonLoader.ts
index 88d7a4fae5f..1fcd9c379cb 100644
--- a/packages/migrate/removeJsonLoader/removeJsonLoader.ts
+++ b/packages/migrate/removeJsonLoader/removeJsonLoader.ts
@@ -1,6 +1,8 @@
import * as utils from "@webpack-cli/utils/ast-utils";
-import { IJSCodeshift, INode } from "../types/NodePath";
+import { JSCodeshift, Node } from "../types/NodePath";
+
+type TransformCallback = (astNode: Node) => void;
/**
*
@@ -11,7 +13,7 @@ import { IJSCodeshift, INode } from "../types/NodePath";
* @returns {Node} ast - jscodeshift ast
*/
-export default function(j: IJSCodeshift, ast: INode): INode {
+export default function(j: JSCodeshift, ast: Node): Node {
/**
*
* Remove the loader with name `name` from the given NodePath
@@ -21,14 +23,16 @@ export default function(j: IJSCodeshift, ast: INode): INode {
* @returns {void}
*/
- function removeLoaderByName(path: INode, name: string): void {
- const loadersNode: INode = path.value.value;
+ function removeLoaderByName(path: Node, name: string): void {
+ const loadersNode = (path.value as Node).value as Node;
switch (loadersNode.type) {
case j.ArrayExpression.name: {
- const loaders: string[] = loadersNode.elements.map((p: INode): string => {
- return utils.safeTraverse(p, ["properties", "0", "value", "value"]);
- });
+ const loaders: Node[] = loadersNode.elements.map(
+ (p: Node): Node => {
+ return utils.safeTraverse(p, ["properties", "0", "value", "value"]) as Node;
+ }
+ );
const loaderIndex: number = loaders.indexOf(name);
if (loaders.length && loaderIndex > -1) {
@@ -55,19 +59,19 @@ export default function(j: IJSCodeshift, ast: INode): INode {
}
}
- function removeLoaders(astNode: INode) {
+ function removeLoaders(astNode: Node): void {
astNode
.find(j.Property, { key: { name: "use" } })
- .forEach((path: INode): void => removeLoaderByName(path, "json-loader"));
+ .forEach((path: Node): void => removeLoaderByName(path, "json-loader"));
astNode
.find(j.Property, { key: { name: "loader" } })
- .forEach((path: INode): void => removeLoaderByName(path, "json-loader"));
+ .forEach((path: Node): void => removeLoaderByName(path, "json-loader"));
}
- const transforms: Array<(astNode: INode) => void> = [removeLoaders];
+ const transforms: TransformCallback[] = [removeLoaders];
- transforms.forEach((t: (astNode: INode) => void): void => t(ast));
+ transforms.forEach((t: TransformCallback): void => t(ast));
return ast;
}
diff --git a/packages/migrate/resolve/resolve.ts b/packages/migrate/resolve/resolve.ts
index c79f5cca4c3..be60e4e69b0 100644
--- a/packages/migrate/resolve/resolve.ts
+++ b/packages/migrate/resolve/resolve.ts
@@ -1,4 +1,4 @@
-import { IJSCodeshift, INode } from "../types/NodePath";
+import { JSCodeshift, Node } from "../types/NodePath";
/**
*
@@ -9,22 +9,19 @@ import { IJSCodeshift, INode } from "../types/NodePath";
* @returns {Node} ast - jscodeshift ast
*/
-export default function transformer(j: IJSCodeshift, ast: INode): INode {
-
- const getRootVal = (p: INode): INode => {
- return p.node.value.properties.filter((prop: INode): boolean => prop.key.name === "root")[0];
+export default function transformer(j: JSCodeshift, ast: Node): Node {
+ const getRootVal = (p: Node): Node => {
+ return (p.node.value as Node).properties.filter((prop: Node): boolean => prop.key.name === "root")[0];
};
- const getRootIndex = (p: INode): number => {
- return p.node.value.properties.reduce((rootIndex: number, prop: INode, index: number): number => {
+ const getRootIndex = (p: Node): number => {
+ return (p.node.value as Node).properties.reduce((rootIndex: number, prop: Node, index: number): number => {
return prop.key.name === "root" ? index : rootIndex;
}, -1);
};
- const isModulePresent = (p: INode): INode | false => {
- const modules: INode[] = p.node.value.properties.filter(
- (prop: INode): boolean => prop.key.name === "modules",
- );
+ const isModulePresent = (p: Node): Node | false => {
+ const modules: Node[] = (p.node.value as Node).properties.filter((prop: Node): boolean => prop.key.name === "modules");
return modules.length > 0 && modules[0];
};
@@ -38,46 +35,42 @@ export default function transformer(j: IJSCodeshift, ast: INode): INode {
* @returns {Node} ast - ast node
*/
- const createModuleArray = (p: INode): INode => {
-
- const rootVal: INode = getRootVal(p);
+ const createModuleArray = (p: Node): Node => {
+ const rootVal: Node = getRootVal(p);
- let modulesVal: INode[] = null;
+ let modulesVal: Node[] = null;
- if (rootVal.value.type === "ArrayExpression") {
- modulesVal = rootVal.value.elements;
+ if ((rootVal.value as Node).type === "ArrayExpression") {
+ modulesVal = (rootVal.value as Node).elements;
} else {
- modulesVal = [rootVal.value];
+ modulesVal = [rootVal.value as Node];
}
- let module: INode | false = isModulePresent(p);
+ let module: Node | false = isModulePresent(p);
if (!module) {
- module = j.property(
- "init",
- j.identifier("modules"),
- j.arrayExpression(modulesVal),
- );
- p.node.value.properties = p.node.value.properties.concat([module]);
+ module = j.property("init", j.identifier("modules"), j.arrayExpression(modulesVal));
+ (p.node.value as Node).properties = (p.node.value as Node).properties.concat([module]);
} else {
- module.value.elements = module.value.elements.concat(modulesVal);
+ (module.value as Node).elements = (module.value as Node).elements.concat(modulesVal);
}
const rootIndex: number = getRootIndex(p);
- p.node.value.properties.splice(rootIndex, 1);
+ (p.node.value as Node).properties.splice(rootIndex, 1);
return p;
};
return ast
.find(j.Property)
- .filter((p: INode): boolean => {
- return (
- p.node.key.name === "resolve" &&
- p.node.value.properties.filter((prop: INode): boolean => prop.key.name === "root")
- .length === 1
- );
- })
+ .filter(
+ (p: Node): boolean => {
+ return (
+ p.node.key.name === "resolve" &&
+ (p.node.value as Node).properties.filter((prop: Node): boolean => prop.key.name === "root").length === 1
+ );
+ }
+ )
.forEach(createModuleArray);
}
diff --git a/packages/migrate/types/NodePath.ts b/packages/migrate/types/NodePath.ts
index e40bdf3cba8..1b828378ddb 100644
--- a/packages/migrate/types/NodePath.ts
+++ b/packages/migrate/types/NodePath.ts
@@ -1,100 +1,99 @@
-export interface INode extends Object {
+export interface Node extends Object {
id?: {
name: string;
};
- arguments?: INode[];
- body?: INode[];
- elements?: INode[];
+ arguments?: Node[];
+ body?: Node[];
+ elements?: Node[];
expression?: {
left: {
- computed: boolean,
- object: INode,
- property: INode,
- type: string,
- },
- operator: string,
- right: INode,
- type: string,
+ computed: boolean;
+ object: Node;
+ property: Node;
+ type: string;
+ };
+ operator: string;
+ right: Node;
+ type: string;
+ value?: string;
};
- filter?: (p: (p: INode) => boolean) => INode;
- find?: (objectExpression: object, filterExpression?: object) => INode;
- forEach?: (p: (p: INode) => void) => INode;
- get?: (property: string) => INode;
- remove?: (_?: void) => void;
- nodes?: (_?: void) => INode[];
- pop?: (_?: void) => INode;
+ filter?: (p: (p: Node) => boolean) => Node;
+ find?: (objectExpression: object, filterExpression?: object) => Node;
+ forEach?: (p: (p: Node) => void) => Node;
+ get?: (property: string) => Node;
+ remove?: () => void;
+ nodes?: () => Node[];
+ pop?: () => Node;
key?: {
name: string;
- value: INode | string;
+ value: Node | string;
};
- node?: INode;
+ node?: Node;
name?: string;
object?: object;
- parent?: INode;
- properties?: INode[];
- property?: INode;
+ parent?: Node;
+ properties?: Node[];
+ property?: Node;
prune?: Function;
- replaceWith?: (objectExpression: object) => INode;
- size?: (_?: void) => number;
+ replaceWith?: (objectExpression: object) => Node;
+ size?: () => number;
type?: string;
- value?: INode | string | any;
- toSource?: (object: {
- quote?: string,
- }) => string;
+ value?: Node | string | Node[];
+ toSource?: (
+ object: {
+ quote?: string;
+ }
+ ) => string;
source?: string;
- ast?: INode;
- rules?: IModuleRule[];
- __paths?: INode[];
+ ast?: Node;
+ rules?: ModuleRule[];
+
+ declarations?: Node[];
+
+ __paths?: Node[];
}
-interface IModuleRule {
+interface ModuleRule {
loader?: string;
}
-interface IExpressionObject {
+interface ExpressionObject {
name?: string;
}
-export interface IJSCodeshift extends Object {
- (source?: INode | string): INode;
- withParser?: (parser: string) => IJSCodeshift;
- identifier?: (key: string) => INode;
- literal?: (key: valueType) => INode;
- memberExpression?: (node1: INode, node2: INode, bool?: boolean) => INode;
- objectProperty?: (key: INode, property: valueType) => INode;
- objectExpression?: (properties: INode[]) => INode;
- newExpression?: (expression: INode, args: INode[]) => INode;
- callExpression?: (expression: INode, args: INode[]) => INode;
- variableDeclarator?: (key: INode, args: INode) => INode;
- variableDeclaration?: (key: string, args: INode[]) => INode;
- arrayExpression?: (args?: INode[]) => INode;
- property?: (type: string, key: INode, value: INode) => INode;
- program?: (nodes: INode[]) => INode;
- booleanLiteral?: (bool: boolean) => INode;
- arrowFunctionExpression?: (params: INode[], body: INode, exp: INode) => INode;
- blockStatement?: (body: INode[]) => INode;
- ifStatement?: (test: INode, consequent: INode, alternate?: INode) => INode;
- returnStatement?: (arg: INode) => INode;
- binaryExpression?: (operator: string, left: INode, right: INode) => INode;
-
- Property?: IExpressionObject;
- NewExpression?: IExpressionObject;
- CallExpression?: IExpressionObject;
- VariableDeclarator?: IExpressionObject;
- Identifier?: IExpressionObject;
- Literal?: IExpressionObject;
- ArrayExpression?: IExpressionObject;
- MemberExpression?: IExpressionObject;
- FunctionExpression?: IExpressionObject;
- ObjectExpression?: IExpressionObject;
- BlockStatement?: IExpressionObject;
- Program?: IExpressionObject;
- ArrowFunctionExpression?: IExpressionObject;
+export interface JSCodeshift extends Object {
+ (source?: Node | string): Node;
+ withParser?: (parser: string) => JSCodeshift;
+ identifier?: (key: string) => Node;
+ literal?: (key: valueType) => Node;
+ memberExpression?: (node1: Node, node2: Node, bool?: boolean) => Node;
+ objectProperty?: (key: Node, property: valueType) => Node;
+ objectExpression?: (properties: Node[]) => Node;
+ newExpression?: (expression: Node, args: Node[]) => Node;
+ callExpression?: (expression: Node, args: Node[]) => Node;
+ variableDeclarator?: (key: Node, args: Node) => Node;
+ variableDeclaration?: (key: string, args: Node[]) => Node;
+ arrayExpression?: (args?: Node[]) => Node;
+ property?: (type: string, key: Node, value: Node) => Node;
+ program?: (nodes: Node[]) => Node;
+ booleanLiteral?: (bool: boolean) => Node;
+ Property?: ExpressionObject;
+ NewExpression?: ExpressionObject;
+ CallExpression?: ExpressionObject;
+ VariableDeclarator?: ExpressionObject;
+ Identifier?: ExpressionObject;
+ Literal?: ExpressionObject;
+ ArrayExpression?: ExpressionObject;
+ MemberExpression?: ExpressionObject;
+ FunctionExpression?: ExpressionObject;
+ ObjectExpression?: ExpressionObject;
+ BlockStatement?: ExpressionObject;
+ Program?: ExpressionObject;
filters?: {
VariableDeclarator: {
- requiresModule: Function,
- },
+ requiresModule: Function;
+ };
};
}
-export type valueType = string | number | boolean | any[] | INode | null;
+export type valueType = string | number | boolean | Node | null;
diff --git a/packages/migrate/uglifyJsPlugin/uglifyJsPlugin.ts b/packages/migrate/uglifyJsPlugin/uglifyJsPlugin.ts
index ef74dec417f..71980715a60 100644
--- a/packages/migrate/uglifyJsPlugin/uglifyJsPlugin.ts
+++ b/packages/migrate/uglifyJsPlugin/uglifyJsPlugin.ts
@@ -3,10 +3,10 @@ import {
findPluginsArrayAndRemoveIfEmpty,
findPluginsByName,
getRequire,
- safeTraverse,
+ safeTraverse
} from "@webpack-cli/utils/ast-utils";
-import { IJSCodeshift, INode } from "../types/NodePath";
+import { JSCodeshift, Node } from "../types/NodePath";
/**
*
@@ -23,36 +23,33 @@ import { IJSCodeshift, INode } from "../types/NodePath";
* @returns {Node} ast - jscodeshift ast
*/
-export default function(j: IJSCodeshift, ast: INode): INode {
-
+export default function(j: JSCodeshift, ast: Node): Node {
let pluginVariableAssignment: string = null;
- const searchForRequirePlugin: INode = ast
+ const searchForRequirePlugin: Node = ast
.find(j.VariableDeclarator)
- .filter(
- j.filters.VariableDeclarator.requiresModule("uglifyjs-webpack-plugin"),
- );
+ .filter(j.filters.VariableDeclarator.requiresModule("uglifyjs-webpack-plugin"));
/**
* Look for a variable declaration which requires uglifyjs-webpack-plugin
* saves the name of this variable.
*/
- searchForRequirePlugin.forEach((node: INode): void => {
- pluginVariableAssignment = node.value.id.name;
- });
+ searchForRequirePlugin.forEach(
+ (node: Node): void => {
+ pluginVariableAssignment = (node.value as Node).id.name;
+ }
+ );
- pluginVariableAssignment = !pluginVariableAssignment
- ? "webpack.optimize.UglifyJsPlugin"
- : pluginVariableAssignment;
+ pluginVariableAssignment = !pluginVariableAssignment ? "webpack.optimize.UglifyJsPlugin" : pluginVariableAssignment;
- findPluginsByName(j, ast, [pluginVariableAssignment])
- .forEach((node: INode): void => {
+ findPluginsByName(j, ast, [pluginVariableAssignment]).forEach(
+ (node: Node): void => {
let expressionContent: object = null;
- const configBody: INode = safeTraverse(node, ["parent", "parent", "parent"]);
+ const configBody = safeTraverse(node, ["parent", "parent", "parent"]);
// options passed to plugin
- const pluginOptions: INode[] = node.value.arguments;
+ const pluginOptions: Node[] = (node.value as Node).arguments;
/**
* check if there are any options passed to UglifyWebpackPlugin
@@ -61,70 +58,55 @@ export default function(j: IJSCodeshift, ast: INode): INode {
*/
if (pluginOptions.length) {
/*
- * If user is using UglifyJsPlugin directly from webpack
- * transformation must:
- * - remove it
- * - add require for terser-webpack-plugin
- * - add to minimizer
- */
+ * If user is using UglifyJsPlugin directly from webpack
+ * transformation must:
+ * - remove it
+ * - add require for terser-webpack-plugin
+ * - add to minimizer
+ */
if (pluginVariableAssignment) {
// remove require for uglify-webpack-plugin
searchForRequirePlugin.remove();
// create require for terser-webpack-plugin
- const pathRequire: INode = getRequire(
- j,
- "TerserPlugin",
- "terser-webpack-plugin",
- );
+ const pathRequire: Node = getRequire(j, "TerserPlugin", "terser-webpack-plugin");
// prepend to source code.
- ast
- .find(j.Program)
- .replaceWith((p: INode): INode =>
- j.program([].concat(pathRequire).concat(p.value.body)),
- );
+ ast.find(j.Program).replaceWith(
+ (p: Node): Node => j.program([].concat(pathRequire).concat((p.value as Node).body))
+ );
expressionContent = j.property(
"init",
j.identifier("minimizer"),
- j.arrayExpression([
- j.newExpression(j.identifier("TerserPlugin"), [pluginOptions[0]]),
- ]),
+ j.arrayExpression([j.newExpression(j.identifier("TerserPlugin"), [pluginOptions[0]])])
);
} else {
- expressionContent = j.property(
- "init",
- j.identifier("minimizer"),
- j.arrayExpression([node.value]),
- );
+ expressionContent = j.property("init", j.identifier("minimizer"), j.arrayExpression([node.value as Node]));
}
} else {
- searchForRequirePlugin.forEach((n: INode): void => j(n).remove());
+ searchForRequirePlugin.forEach((n: Node): void => j(n).remove());
}
const minimizeProperty = createProperty(j, "minimize", "true");
// creates optimization property at the body of the config.
if (expressionContent) {
- configBody.value.properties.push(
+ ((configBody as Node).value as Node).properties.push(
j.property(
"init",
j.identifier("optimization"),
- j.objectExpression([minimizeProperty, expressionContent]),
- ),
+ j.objectExpression([minimizeProperty, expressionContent])
+ )
);
} else {
- configBody.value.properties.push(
- j.property(
- "init",
- j.identifier("optimization"),
- j.objectExpression([minimizeProperty]),
- ),
+ ((configBody as Node).value as Node).properties.push(
+ j.property("init", j.identifier("optimization"), j.objectExpression([minimizeProperty]))
);
}
// remove the old Uglify plugin from Plugins array.
j(node).remove();
- });
+ }
+ );
findPluginsArrayAndRemoveIfEmpty(j, ast);
diff --git a/packages/remove/.eslintrc b/packages/remove/.eslintrc
new file mode 100644
index 00000000000..365d9f85d71
--- /dev/null
+++ b/packages/remove/.eslintrc
@@ -0,0 +1,11 @@
+{
+ "root": true,
+ "extends": [
+ "../../.eslintrc.js",
+ "plugin:@typescript-eslint/recommended",
+ "prettier",
+ "prettier/@typescript-eslint"
+ ],
+ "parser": "@typescript-eslint/parser",
+ "plugins": ["@typescript-eslint"]
+}
diff --git a/packages/serve/.eslintrc b/packages/serve/.eslintrc
new file mode 100644
index 00000000000..365d9f85d71
--- /dev/null
+++ b/packages/serve/.eslintrc
@@ -0,0 +1,11 @@
+{
+ "root": true,
+ "extends": [
+ "../../.eslintrc.js",
+ "plugin:@typescript-eslint/recommended",
+ "prettier",
+ "prettier/@typescript-eslint"
+ ],
+ "parser": "@typescript-eslint/parser",
+ "plugins": ["@typescript-eslint"]
+}
diff --git a/packages/serve/index.ts b/packages/serve/index.ts
index 950ae78d3b7..8ae5a867368 100644
--- a/packages/serve/index.ts
+++ b/packages/serve/index.ts
@@ -17,7 +17,7 @@ import { List } from "@webpack-cli/webpack-scaffold";
const spawnNPMWithArg = (cmd: string): SpawnSyncReturns =>
spawn.sync("npm", ["install", "webpack-dev-server", cmd], {
- stdio: "inherit",
+ stdio: "inherit"
});
/**
@@ -30,7 +30,7 @@ const spawnNPMWithArg = (cmd: string): SpawnSyncReturns =>
const spawnYarnWithArg = (cmd: string): SpawnSyncReturns =>
spawn.sync("yarn", ["add", "webpack-dev-server", cmd], {
- stdio: "inherit",
+ stdio: "inherit"
});
/**
@@ -51,40 +51,34 @@ const getRootPathModule = (dep: string): string => path.resolve(process.cwd(), d
* @returns {Function} invokes the devServer API
*/
-export default function serve(...args: string[]) {
+export default function serve(): Promise {
const packageJSONPath = getRootPathModule("package.json");
if (!packageJSONPath) {
- console.error(
- "\n",
- chalk.red("✖ Could not find your package.json file"),
- "\n",
- );
+ console.error("\n", chalk.red("✖ Could not find your package.json file"), "\n");
process.exit(1);
}
+ // TODO: to refactor this dynamic require and use import()
+ // eslint-disable-next-line
const packageJSON: object = require(packageJSONPath);
/*
* We gotta do this, cause some configs might not have devdep,
* dep or optional dep, so we'd need sanity checks for each
- */
+ */
const hasDevServerDep: string[] = packageJSON
- ? Object.keys(packageJSON).filter((p: string) => packageJSON[p]["webpack-dev-server"])
+ ? Object.keys(packageJSON).filter((p: string): boolean => packageJSON[p]["webpack-dev-server"])
: [];
if (hasDevServerDep.length) {
- const WDSPath: string = getRootPathModule(
- "node_modules/webpack-dev-server/bin/webpack-dev-server.js",
- );
+ const WDSPath: string = getRootPathModule("node_modules/webpack-dev-server/bin/webpack-dev-server.js");
if (!WDSPath) {
console.error(
"\n",
- chalk.red(
- "✖ Could not find the webpack-dev-server dependency in node_modules root path",
- ),
+ chalk.red("✖ Could not find the webpack-dev-server dependency in node_modules root path")
);
console.info(
chalk.bold.green(" ✔︎"),
"Try this command:",
- chalk.bold.green("rm -rf node_modules && npm install"),
+ chalk.bold.green("rm -rf node_modules && npm install")
);
process.exit(1);
}
@@ -92,14 +86,12 @@ export default function serve(...args: string[]) {
} else {
process.stdout.write(
"\n" +
- chalk.bold(
- "✖ We didn't find any webpack-dev-server dependency in your project,",
- ) +
+ chalk.bold("✖ We didn't find any webpack-dev-server dependency in your project,") +
"\n" +
chalk.bold.green(" 'webpack serve'") +
" " +
chalk.bold("requires you to have it installed ") +
- "\n\n",
+ "\n\n"
);
return inquirer
.prompt([
@@ -107,65 +99,68 @@ export default function serve(...args: string[]) {
default: "Y",
message: "Do you want to install it? (default: Y)",
name: "confirmDevserver",
- type: "confirm",
- },
+ type: "confirm"
+ }
])
- .then((answer: {
- confirmDevserver: boolean,
- }) => {
- if (answer.confirmDevserver) {
- return inquirer
- .prompt(
- List(
- "confirmDepType",
- "What kind of dependency do you want it to be under? (default: devDependency)",
- ["devDependency", "optionalDependency", "dependency"],
- ),
- )
- .then((depTypeAns: {
- confirmDepType: string;
- }) => {
- const packager: string = getRootPathModule("package-lock.json")
- ? "npm"
- : "yarn";
- let spawnAction: (_?: void) => SpawnSyncReturns;
- if (depTypeAns.confirmDepType === "devDependency") {
- if (packager === "yarn") {
- spawnAction = (_?: void) => spawnYarnWithArg("--dev");
- } else {
- spawnAction = (_?: void) => spawnNPMWithArg("--save-dev");
- }
- }
- if (depTypeAns.confirmDepType === "dependency") {
- if (packager === "yarn") {
- spawnAction = (_?: void) => spawnYarnWithArg(" ");
- } else {
- spawnAction = (_?: void) => spawnNPMWithArg("--save");
+ .then(
+ (answer: { confirmDevserver: boolean }): Promise => {
+ if (answer.confirmDevserver) {
+ return inquirer
+ .prompt(
+ List(
+ "confirmDepType",
+ "What kind of dependency do you want it to be under? (default: devDependency)",
+ ["devDependency", "optionalDependency", "dependency"]
+ )
+ )
+ .then(
+ (depTypeAns: { confirmDepType: string }): Promise => {
+ const packager: string = getRootPathModule("package-lock.json") ? "npm" : "yarn";
+ let spawnAction: () => SpawnSyncReturns;
+ if (depTypeAns.confirmDepType === "devDependency") {
+ if (packager === "yarn") {
+ spawnAction = (): SpawnSyncReturns => spawnYarnWithArg("--dev");
+ } else {
+ spawnAction = (): SpawnSyncReturns => spawnNPMWithArg("--save-dev");
+ }
+ }
+ if (depTypeAns.confirmDepType === "dependency") {
+ if (packager === "yarn") {
+ spawnAction = (): SpawnSyncReturns => spawnYarnWithArg(" ");
+ } else {
+ spawnAction = (): SpawnSyncReturns => spawnNPMWithArg("--save");
+ }
+ }
+ if (depTypeAns.confirmDepType === "optionalDependency") {
+ if (packager === "yarn") {
+ spawnAction = (): SpawnSyncReturns =>
+ spawnYarnWithArg("--optional");
+ } else {
+ spawnAction = (): SpawnSyncReturns =>
+ spawnNPMWithArg("--save-optional");
+ }
+ }
+ return processPromise(spawnAction()).then(
+ (): Promise => {
+ // Recursion doesn't work well with require call being cached
+ delete require.cache[require.resolve(packageJSONPath)];
+ return serve();
+ }
+ );
}
- }
- if (depTypeAns.confirmDepType === "optionalDependency") {
- if (packager === "yarn") {
- spawnAction = (_?: void) => spawnYarnWithArg("--optional");
- } else {
- spawnAction = (_?: void) => spawnNPMWithArg("--save-optional");
- }
- }
- return processPromise(spawnAction())
- .then((_: void) => {
- // Recursion doesn't work well with require call being cached
- delete require.cache[require.resolve(packageJSONPath)];
- return serve();
- });
- });
- } else {
- console.error(chalk.bold.red("✖ Serve aborted due cancelling"));
+ );
+ } else {
+ console.error(chalk.bold.red("✖ Serve aborted due cancelling"));
+ process.exitCode = 1;
+ }
+ }
+ )
+ .catch(
+ (err: object): void => {
+ console.error(chalk.red("✖ Serve aborted due to some errors"));
+ console.error(err);
process.exitCode = 1;
}
- })
- .catch((err: object) => {
- console.error(chalk.red("✖ Serve aborted due to some errors"));
- console.error(err);
- process.exitCode = 1;
- });
+ );
}
}
diff --git a/packages/update/.eslintrc b/packages/update/.eslintrc
new file mode 100644
index 00000000000..365d9f85d71
--- /dev/null
+++ b/packages/update/.eslintrc
@@ -0,0 +1,11 @@
+{
+ "root": true,
+ "extends": [
+ "../../.eslintrc.js",
+ "plugin:@typescript-eslint/recommended",
+ "prettier",
+ "prettier/@typescript-eslint"
+ ],
+ "parser": "@typescript-eslint/parser",
+ "plugins": ["@typescript-eslint"]
+}
diff --git a/packages/utils/.eslintrc b/packages/utils/.eslintrc
new file mode 100644
index 00000000000..365d9f85d71
--- /dev/null
+++ b/packages/utils/.eslintrc
@@ -0,0 +1,11 @@
+{
+ "root": true,
+ "extends": [
+ "../../.eslintrc.js",
+ "plugin:@typescript-eslint/recommended",
+ "prettier",
+ "prettier/@typescript-eslint"
+ ],
+ "parser": "@typescript-eslint/parser",
+ "plugins": ["@typescript-eslint"]
+}
diff --git a/packages/utils/__tests__/.eslintrc b/packages/utils/__tests__/.eslintrc
new file mode 100644
index 00000000000..5d4340a351d
--- /dev/null
+++ b/packages/utils/__tests__/.eslintrc
@@ -0,0 +1,7 @@
+{
+ "root": true,
+ "extends": ["../.eslintrc"],
+ "rules": {
+ "@typescript-eslint/explicit-function-return-type": ["off"]
+ }
+}
diff --git a/packages/utils/__tests__/ast-utils.test.ts b/packages/utils/__tests__/ast-utils.test.ts
index b9c8e34576c..6883531049f 100644
--- a/packages/utils/__tests__/ast-utils.test.ts
+++ b/packages/utils/__tests__/ast-utils.test.ts
@@ -2,7 +2,7 @@
import * as j from "jscodeshift/dist/core";
import * as utils from "../ast-utils";
-import { INode } from "../types/NodePath";
+import { Node } from "../types/NodePath";
describe("utils", () => {
describe("createProperty", () => {
@@ -106,7 +106,7 @@ const a = { plugs: [] }
describe("createOrUpdatePluginByName", () => {
it("should create a new plugin without arguments", () => {
const ast = j("{ plugins: [] }");
- ast.find(j.ArrayExpression).forEach((node: INode) => {
+ ast.find(j.ArrayExpression).forEach((node: Node) => {
utils.createOrUpdatePluginByName(j, node, "Plugin");
});
expect(ast.toSource()).toMatchSnapshot();
@@ -114,9 +114,9 @@ const a = { plugs: [] }
it("should create a new plugin with arguments", () => {
const ast = j("{ plugins: [] }");
- ast.find(j.ArrayExpression).forEach((node: INode) => {
+ ast.find(j.ArrayExpression).forEach((node: Node) => {
utils.createOrUpdatePluginByName(j, node, "Plugin", {
- foo: "bar",
+ foo: "bar"
});
});
expect(ast.toSource()).toMatchSnapshot();
@@ -124,9 +124,9 @@ const a = { plugs: [] }
it("should add an object as an argument", () => {
const ast = j("[new Plugin()]");
- ast.find(j.ArrayExpression).forEach((node: INode) => {
+ ast.find(j.ArrayExpression).forEach((node: Node) => {
utils.createOrUpdatePluginByName(j, node, "Plugin", {
- foo: true,
+ foo: true
});
});
expect(ast.toSource()).toMatchSnapshot();
@@ -134,13 +134,13 @@ const a = { plugs: [] }
it("should merge options objects", () => {
const ast = j("[new Plugin({ foo: true })]");
- ast.find(j.ArrayExpression).forEach((node: INode) => {
+ ast.find(j.ArrayExpression).forEach((node: Node) => {
utils.createOrUpdatePluginByName(j, node, "Plugin", {
bar: "baz",
- foo: false,
+ foo: false
});
utils.createOrUpdatePluginByName(j, node, "Plugin", {
- "baz-long": true,
+ "baz-long": true
});
});
expect(ast.toSource()).toMatchSnapshot();
@@ -192,8 +192,8 @@ const a = { plugs: [] }
expect(
ast
.find(j.ObjectExpression)
- .filter((p) => utils.findObjWithOneOfKeys(p, ["a"]))
- .size(),
+ .filter(p => utils.findObjWithOneOfKeys(p, ["a"]))
+ .size()
).toEqual(1);
});
});
@@ -208,12 +208,12 @@ const a = { plugs: [] }
describe("safeTraverse", () => {
it("should safe traverse", () => {
const testObject = {
- type: "NodeType",
+ type: "NodeType"
};
const p = {
foo: {
- bar: testObject,
- },
+ bar: testObject
+ }
};
const require = utils.safeTraverse(p, ["foo", "bar"]);
expect(require).toEqual(testObject);
@@ -221,14 +221,14 @@ const a = { plugs: [] }
it("should safe traverse thrice", () => {
const type = {
- type: "NodeType",
+ type: "NodeType"
};
const p = {
parent: {
value: {
- value: type,
- },
- },
+ value: type
+ }
+ }
};
const traversedValue = utils.safeTraverse(p, ["parent", "value", "value"]);
expect(traversedValue).toEqual(type);
@@ -241,9 +241,9 @@ const a = { plugs: [] }
const p = {
value: {
value: {
- type: NODE_TYPE,
- },
- },
+ type: NODE_TYPE
+ }
+ }
};
const typeValue = utils.safeTraverseAndGetType(p);
expect(typeValue).toEqual(NODE_TYPE);
@@ -254,9 +254,9 @@ const a = { plugs: [] }
const p = {
foo: {
bar: {
- type: NODE_TYPE,
- },
- },
+ type: NODE_TYPE
+ }
+ }
};
const typeValue = utils.safeTraverseAndGetType(p);
expect(typeValue).toEqual(false);
@@ -273,14 +273,14 @@ const a = { plugs: [] }
super: [
"yeah",
{
- loader: "'eslint-loader'",
- },
- ],
+ loader: "'eslint-loader'"
+ }
+ ]
};
const root = ast.find(j.ObjectExpression);
- root.forEach((p) => {
+ root.forEach(p => {
utils.addProperty(j, p, "entry", propertyValue);
});
@@ -306,14 +306,14 @@ const a = { plugs: [] }
super: [
"yeah",
{
- loader: "'eslint-loader'",
- },
- ],
+ loader: "'eslint-loader'"
+ }
+ ]
};
const root = ast.find(j.ObjectExpression);
- utils.findRootNodesByName(j, root, "entry").forEach((p: INode) => {
+ utils.findRootNodesByName(j, root, "entry").forEach((p: Node) => {
j(p).replaceWith(utils.addProperty(j, p, "entry", propertyValue, "add"));
});
diff --git a/packages/utils/__tests__/package-manager.test.ts b/packages/utils/__tests__/package-manager.test.ts
index 036f10604bb..baa4204822a 100644
--- a/packages/utils/__tests__/package-manager.test.ts
+++ b/packages/utils/__tests__/package-manager.test.ts
@@ -7,7 +7,9 @@ jest.mock("cross-spawn");
jest.mock("fs");
describe("package-manager", () => {
+ // eslint-disable-next-line
const spawn = require("cross-spawn");
+ // eslint-disable-next-line
const fs = require("fs");
const defaultSyncResult = {
@@ -50,7 +52,7 @@ describe("package-manager", () => {
fs.existsSync.mockReturnValueOnce(true);
}
- spawn.sync.mockReturnValue(defaultSyncResult);
+ jest.spyOn(spawn, "sync").mockReturnValue(defaultSyncResult);
it("should return 'yarn' from getPackageManager if it's installed", () => {
expect(packageManager.getPackageManager()).toEqual("yarn");
diff --git a/packages/utils/__tests__/resolve-packages.test.ts b/packages/utils/__tests__/resolve-packages.test.ts
index d571dc01762..765b907f1d2 100644
--- a/packages/utils/__tests__/resolve-packages.test.ts
+++ b/packages/utils/__tests__/resolve-packages.test.ts
@@ -7,7 +7,7 @@ function mockPromise(value) {
const mockedPromise = {
then(callback) {
return mockPromise(callback(value));
- },
+ }
};
return isValueAPromise ? value : mockedPromise;
@@ -18,14 +18,14 @@ function spawnChild(pkg) {
function getLoc(option) {
const packageModule = [];
- option.filter((pkg) => {
- mockPromise(spawnChild(pkg)).then((_) => {
+ option.filter(pkg => {
+ mockPromise(spawnChild(pkg)).then(() => {
try {
const loc = path.join("..", "..", "node_modules", pkg);
packageModule.push(loc);
} catch (err) {
throw new Error(
- "Package wasn't validated correctly.." + "Submit an issue for " + pkg + " if this persists",
+ "Package wasn't validated correctly.." + "Submit an issue for " + pkg + " if this persists"
);
}
});
@@ -60,7 +60,7 @@ describe("resolve-packages", () => {
moduleLoc = getLoc(["webpack-scaffold-ylvis", "webpack-scaffold-noop"]);
expect(moduleLoc).toEqual([
path.normalize("../../node_modules/webpack-scaffold-ylvis"),
- path.normalize("../../node_modules/webpack-scaffold-noop"),
+ path.normalize("../../node_modules/webpack-scaffold-noop")
]);
});
});
diff --git a/packages/utils/ast-utils.ts b/packages/utils/ast-utils.ts
index 53e2e60e685..7a6fed5a657 100644
--- a/packages/utils/ast-utils.ts
+++ b/packages/utils/ast-utils.ts
@@ -1,4 +1,4 @@
-import { IJSCodeshift, INode, valueType } from "./types/NodePath";
+import { JSCodeshift, Node, valueType } from "./types/NodePath";
import * as validateIdentifier from "./validate-identifier";
/**
@@ -6,11 +6,13 @@ import * as validateIdentifier from "./validate-identifier";
* Traverse safely over a path object for array for paths
* @param {Object} obj - Object on which we traverse
* @param {Array} paths - Array of strings containing the traversal path
- * @returns {Any} Value at given traversal path
+ * @returns {Node} Value at given traversal path
*/
-function safeTraverse(obj: INode, paths: string[]): any {
- let val: INode = obj;
+function safeTraverse(obj: Node, paths: string[]): Node | Node[] {
+ // TODO: to revisit the type of this function, it's not clear what should return.
+ // Sometimes its return type is used as string
+ let val: Node = obj;
let idx = 0;
while (idx < paths.length) {
@@ -30,8 +32,8 @@ function safeTraverse(obj: INode, paths: string[]): any {
* @returns {String|Boolean} type at given path.
*/
-function safeTraverseAndGetType(path: INode): string | boolean {
- const pathValue: INode = safeTraverse(path, ["value", "value"]);
+function safeTraverseAndGetType(path: Node): string | boolean {
+ const pathValue = safeTraverse(path, ["value", "value"]) as Node;
return pathValue ? pathValue.type : false;
}
@@ -41,17 +43,15 @@ function safeTraverseAndGetType(path: INode): string | boolean {
* @returns {String} member expression string.
*/
-function memberExpressionToPathString(path: INode): string {
+function memberExpressionToPathString(path: Node): string {
if (path && path.object) {
- return [memberExpressionToPathString(path.object), path.property.name].join(
- ".",
- );
+ return [memberExpressionToPathString(path.object), path.property.name].join(".");
}
return path.name;
}
// Convert Array like ['webpack', 'optimize', 'DedupePlugin'] to nested MemberExpressions
-function pathsToMemberExpression(j: IJSCodeshift, paths: string[]): INode {
+function pathsToMemberExpression(j: JSCodeshift, paths: string[]): Node {
if (!paths.length) {
return null;
} else if (paths.length === 1) {
@@ -59,10 +59,7 @@ function pathsToMemberExpression(j: IJSCodeshift, paths: string[]): INode {
} else {
const first: string[] = paths.slice(0, 1);
const rest: string[] = paths.slice(1);
- return j.memberExpression(
- pathsToMemberExpression(j, rest),
- pathsToMemberExpression(j, first),
- );
+ return j.memberExpression(pathsToMemberExpression(j, rest), pathsToMemberExpression(j, first));
}
}
@@ -77,15 +74,14 @@ function pathsToMemberExpression(j: IJSCodeshift, paths: string[]): INode {
* @returns {Node} Node that has the pluginName
*/
-function findPluginsByName(j: IJSCodeshift, node: INode, pluginNamesArray: string[]): INode {
- return node
- .find(j.NewExpression)
- .filter((path: INode): boolean => {
+function findPluginsByName(j: JSCodeshift, node: Node, pluginNamesArray: string[]): Node {
+ return node.find(j.NewExpression).filter(
+ (path: Node): boolean => {
return pluginNamesArray.some(
- (plugin: string) =>
- memberExpressionToPathString(path.get("callee").value) === plugin,
+ (plugin: string): boolean => memberExpressionToPathString(path.get("callee").value as Node) === plugin
);
- });
+ }
+ );
}
/**
@@ -95,20 +91,15 @@ function findPluginsByName(j: IJSCodeshift, node: INode, pluginNamesArray: strin
* @returns {Node} rootNode modified AST.
*/
-function findPluginsArrayAndRemoveIfEmpty(j: IJSCodeshift, rootNode: INode): INode {
- return rootNode
- .find(j.Identifier, { name: "plugins" })
- .forEach((node: INode) => {
- const elements: INode[] = safeTraverse(node, [
- "parent",
- "value",
- "value",
- "elements",
- ]);
+function findPluginsArrayAndRemoveIfEmpty(j: JSCodeshift, rootNode: Node): Node {
+ return rootNode.find(j.Identifier, { name: "plugins" }).forEach(
+ (node: Node): void => {
+ const elements = safeTraverse(node, ["parent", "value", "value", "elements"]) as Node[];
if (!elements.length) {
j(node.parent).remove();
}
- });
+ }
+ );
}
/**
@@ -121,51 +112,10 @@ function findPluginsArrayAndRemoveIfEmpty(j: IJSCodeshift, rootNode: INode): INo
* @returns {Node} found node and
*/
-function findRootNodesByName(j: IJSCodeshift, node: INode, propName: string): INode {
+function findRootNodesByName(j: JSCodeshift, node: Node, propName: string): Node {
return node.find(j.Property, { key: { name: propName } });
}
-/**
- *
- * Creates an Object's property with a given key and value
- *
- * @param {any} j — jscodeshift API
- * @param {String | Number} key - Property key
- * @param {String | Number | Boolean} value - Property value
- * @returns {Node}
- */
-
-function createProperty(j: IJSCodeshift, key: string | number, value: valueType): INode {
- return j.property(
- "init",
- createIdentifierOrLiteral(j, key),
- createLiteral(j, value),
- );
-}
-
-/**
- *
- * Creates an appropriate literal property
- *
- * @param {any} j — jscodeshift API
- * @param {String | Boolean | Number} val
- * @returns {Node}
- */
-
-function createLiteral(j: IJSCodeshift, val: valueType): INode {
- let literalVal: valueType = val;
- // We'll need String to native type conversions
- if (typeof val === "string") {
- // 'true' => true
- if (val === "true") { literalVal = true; }
- // 'false' => false
- if (val === "false") { literalVal = false; }
- // '1' => 1
- if (!isNaN(Number(val))) { literalVal = Number(val); }
- }
- return j.literal(literalVal);
-}
-
/**
*
* Creates an appropriate identifier or literal property
@@ -175,12 +125,12 @@ function createLiteral(j: IJSCodeshift, val: valueType): INode {
* @returns {Node}
*/
-function createIdentifierOrLiteral(j: IJSCodeshift, val: valueType): INode {
+function createIdentifierOrLiteral(j: JSCodeshift, val: valueType): Node {
// IPath | IPath doesn't work, find another way
let literalVal = val;
// We'll need String to native type conversions
if (!Array.isArray(val)) {
- if (typeof val === "string" || typeof val === "object" && val.__paths) {
+ if (typeof val === "string" || (typeof val === "object" && val.__paths)) {
// 'true' => true
if (val === "true") {
literalVal = true;
@@ -197,7 +147,7 @@ function createIdentifierOrLiteral(j: IJSCodeshift, val: valueType): INode {
return j.literal(literalVal);
}
if (typeof val === "object" && val.__paths) {
- const regExpVal = val.__paths[0].value.program.body[0].expression;
+ const regExpVal = ((val.__paths[0].value as JSCodeshift).program as Node).body[0].expression;
return j.literal(regExpVal.value);
} else if (typeof literalVal === "string") {
// Use identifier instead
@@ -214,6 +164,49 @@ function createIdentifierOrLiteral(j: IJSCodeshift, val: valueType): INode {
return j.literal(literalVal);
}
+/**
+ *
+ * Creates an appropriate literal property
+ *
+ * @param {any} j — jscodeshift API
+ * @param {String | Boolean | Number} val
+ * @returns {Node}
+ */
+
+function createLiteral(j: JSCodeshift, val: valueType): Node {
+ let literalVal: valueType = val;
+ // We'll need String to native type conversions
+ if (typeof val === "string") {
+ // 'true' => true
+ if (val === "true") {
+ literalVal = true;
+ }
+ // 'false' => false
+ if (val === "false") {
+ literalVal = false;
+ }
+ // '1' => 1
+ if (!isNaN(Number(val))) {
+ literalVal = Number(val);
+ }
+ }
+ return j.literal(literalVal);
+}
+
+/**
+ *
+ * Creates an Object's property with a given key and value
+ *
+ * @param {any} j — jscodeshift API
+ * @param {String | Number} key - Property key
+ * @param {String | Number | Boolean} value - Property value
+ * @returns {Node}
+ */
+
+function createProperty(j: JSCodeshift, key: string | number, value: valueType): Node {
+ return j.property("init", createIdentifierOrLiteral(j, key), createLiteral(j, value));
+}
+
/**
*
* Adds or updates the value of a key within a root
@@ -228,35 +221,32 @@ function createIdentifierOrLiteral(j: IJSCodeshift, val: valueType): INode {
*/
function addOrUpdateConfigObject(
- j: IJSCodeshift, rootNode: INode, configProperty: string, key: string, value: valueType,
+ j: JSCodeshift,
+ rootNode: Node,
+ configProperty: string,
+ key: string,
+ value: valueType
): void {
-
- const propertyExists = rootNode.properties.filter(
- (node: INode): boolean => node.key.name === configProperty,
- ).length;
+ const propertyExists = rootNode.properties.filter((node: Node): boolean => node.key.name === configProperty).length;
if (propertyExists) {
rootNode.properties
- .filter((path: INode): boolean => path.key.name === configProperty)
- .forEach((path: INode) => {
- const newProperties = path.value.properties.filter(
- (p: INode) => p.key.name !== key,
- );
- newProperties.push(
- j.objectProperty(
- j.identifier(key), value,
- ),
- );
- path.value.properties = newProperties;
- });
+ .filter((path: Node): boolean => path.key.name === configProperty)
+ .forEach(
+ (path: Node): void => {
+ const newProperties = (path.value as Node).properties.filter(
+ (p: Node): boolean => p.key.name !== key
+ );
+ newProperties.push(j.objectProperty(j.identifier(key), value));
+ (path.value as Node).properties = newProperties;
+ }
+ );
} else {
rootNode.properties.push(
j.objectProperty(
j.identifier(configProperty),
- j.objectExpression(
- [j.objectProperty(j.identifier(key), value)],
- ),
- ),
+ j.objectExpression([j.objectProperty(j.identifier(key), value)])
+ )
);
}
}
@@ -272,20 +262,22 @@ function addOrUpdateConfigObject(
* @returns {Node | Void} - path to the root webpack configuration object if plugin is found
*/
-function findAndRemovePluginByName(j: IJSCodeshift, node: INode, pluginName: string): INode {
- let rootPath: INode;
+function findAndRemovePluginByName(j: JSCodeshift, node: Node, pluginName: string): Node {
+ let rootPath: Node;
findPluginsByName(j, node, [pluginName])
- .filter((path: INode): boolean => safeTraverse(path, ["parent", "value"]))
- .forEach((path: INode) => {
- rootPath = safeTraverse(path, ["parent", "parent", "parent", "value"]);
- const arrayPath: INode = path.parent.value;
- if (arrayPath.elements && arrayPath.elements.length === 1) {
- j(path.parent.parent).remove();
- } else {
- j(path).remove();
+ .filter((path: Node): boolean => !!safeTraverse(path, ["parent", "value"]))
+ .forEach(
+ (path: Node): void => {
+ rootPath = safeTraverse(path, ["parent", "parent", "parent", "value"]) as Node;
+ const arrayPath = path.parent.value as Node;
+ if (arrayPath.elements && arrayPath.elements.length === 1) {
+ j(path.parent.parent).remove();
+ } else {
+ j(path).remove();
+ }
}
- });
+ );
return rootPath;
}
@@ -303,62 +295,68 @@ function findAndRemovePluginByName(j: IJSCodeshift, node: INode, pluginName: str
* @returns {Void}
*/
-function createOrUpdatePluginByName(j: IJSCodeshift, rootNodePath: INode, pluginName: string, options?: object): void {
- const pluginInstancePath: INode = findPluginsByName(j, j(rootNodePath), [
- pluginName,
- ]);
- let optionsProps: INode[];
+function createOrUpdatePluginByName(j: JSCodeshift, rootNodePath: Node, pluginName: string, options?: object): void {
+ const pluginInstancePath: Node = findPluginsByName(j, j(rootNodePath), [pluginName]);
+ let optionsProps: Node[];
if (options) {
- optionsProps = Object.keys(options).map((key: string) => {
- return createProperty(j, key, options[key]);
- });
+ optionsProps = Object.keys(options).map(
+ (key: string): Node => {
+ return createProperty(j, key, options[key]);
+ }
+ );
}
// If plugin declaration already exist
if (pluginInstancePath.size()) {
- pluginInstancePath.forEach((path: INode) => {
- // There are options we want to pass as argument
- if (optionsProps) {
- const args: INode[] = path.value.arguments;
- if (args.length) {
- // Plugin is called with object as arguments
- // we will merge those objects
- const currentProps: INode = j(path)
- .find(j.ObjectExpression)
- .get("properties");
-
- optionsProps.forEach((opt: INode) => {
- // Search for same keys in the existing object
- const existingProps = j(currentProps)
- .find(j.Identifier)
- .filter((p: INode): boolean => opt.key.value === p.value.name);
-
- if (existingProps.size()) {
- // Replacing values for the same key
- existingProps.forEach((p: INode) => {
- j(p.parent).replaceWith(opt);
- });
- } else {
- // Adding new key:values
- currentProps.value.push(opt);
- }
- });
- } else {
- // Plugin is called without arguments
- args.push(j.objectExpression(optionsProps));
+ pluginInstancePath.forEach(
+ (path: Node): void => {
+ // There are options we want to pass as argument
+ if (optionsProps) {
+ const args: Node[] = (path.value as Node).arguments;
+ if (args.length) {
+ // Plugin is called with object as arguments
+ // we will merge those objects
+ const currentProps: Node = j(path)
+ .find(j.ObjectExpression)
+ .get("properties");
+
+ optionsProps.forEach(
+ (opt: Node): void => {
+ // Search for same keys in the existing object
+ const existingProps = j(currentProps)
+ .find(j.Identifier)
+ .filter((p: Node): boolean => opt.key.value === (p.value as Node).name);
+
+ if (existingProps.size()) {
+ // Replacing values for the same key
+ existingProps.forEach(
+ (p: Node): void => {
+ j(p.parent).replaceWith(opt);
+ }
+ );
+ } else {
+ // Adding new key:values
+ (currentProps.value as Node[]).push(opt);
+ }
+ }
+ );
+ } else {
+ // Plugin is called without arguments
+ args.push(j.objectExpression(optionsProps));
+ }
}
}
- });
+ );
} else {
- let argumentsArray: INode[] = [];
+ let argumentsArray: Node[] = [];
if (optionsProps) {
argumentsArray = [j.objectExpression(optionsProps)];
}
const loaderPluginInstance = j.newExpression(
pathsToMemberExpression(j, pluginName.split(".").reverse()),
- argumentsArray,
+ argumentsArray
);
- rootNodePath.value.elements.push(loaderPluginInstance);
+ (rootNodePath.value as Node).elements.push(loaderPluginInstance);
}
}
@@ -373,12 +371,14 @@ function createOrUpdatePluginByName(j: IJSCodeshift, rootNodePath: INode, plugin
* @returns {String} variable name - ex. 'const s = require(s) gives "s"`
*/
-function findVariableToPlugin(j: IJSCodeshift, rootNode: INode, pluginPackageName: string): string {
- const moduleVarNames: INode[] = rootNode
+function findVariableToPlugin(j: JSCodeshift, rootNode: Node, pluginPackageName: string): string {
+ const moduleVarNames: Node[] = rootNode
.find(j.VariableDeclarator)
.filter(j.filters.VariableDeclarator.requiresModule(pluginPackageName))
.nodes();
- if (moduleVarNames.length === 0) { return null; }
+ if (moduleVarNames.length === 0) {
+ return null;
+ }
return moduleVarNames.pop().id.name;
}
@@ -390,12 +390,12 @@ function findVariableToPlugin(j: IJSCodeshift, rootNode: INode, pluginPackageNam
* @returns {Boolean}
*/
-function isType(path: INode, type: string): boolean {
+function isType(path: Node, type: string): boolean {
return path.type === type;
}
-function findObjWithOneOfKeys(p: INode, keyNames: string[]) {
- return p.value.properties.reduce((predicate: boolean, prop: INode) => {
+function findObjWithOneOfKeys(p: Node, keyNames: string[]): boolean {
+ return (p.value as Node).properties.reduce((predicate: boolean, prop: Node): boolean => {
const name: string = prop.key.name;
return keyNames.indexOf(name) > -1 || predicate;
}, false);
@@ -410,12 +410,12 @@ function findObjWithOneOfKeys(p: INode, keyNames: string[]) {
* @returns {Node} - the created ast
*/
-function getRequire(j: IJSCodeshift, constName: string, packagePath: string): INode {
+function getRequire(j: JSCodeshift, constName: string, packagePath: string): Node {
return j.variableDeclaration("const", [
j.variableDeclarator(
j.identifier(constName),
- j.callExpression(j.identifier("require"), [j.literal(packagePath)]),
- ),
+ j.callExpression(j.identifier("require"), [j.literal(packagePath)])
+ )
]);
}
@@ -430,32 +430,33 @@ function getRequire(j: IJSCodeshift, constName: string, packagePath: string): IN
* @returns {Node} - the created ast
*/
-function addProperty(j: IJSCodeshift, p: INode, key: string, value: valueType, action?: string): INode {
+function addProperty(j: JSCodeshift, p: Node, key: string, value: valueType, action?: string): Node {
if (!p) {
return;
}
let valForNode: valueType;
if (Array.isArray(value)) {
- let arrExp: INode = j.arrayExpression([]);
+ let arrExp: Node = j.arrayExpression([]);
if (safeTraverseAndGetType(p) === "ArrayExpression") {
- arrExp = p.value.value;
+ arrExp = (p.value as Node).value as Node;
}
- value.forEach((val: valueType) => {
- addProperty(j, arrExp, null, val);
- });
+ value.forEach(
+ (val: valueType): void => {
+ addProperty(j, arrExp, null, val);
+ }
+ );
valForNode = arrExp;
- } else if (
- typeof value === "object" &&
- !(value.__paths || value instanceof RegExp)
- ) {
- let objectExp: INode = j.objectExpression([]);
+ } else if (typeof value === "object" && !(value.__paths || value instanceof RegExp)) {
+ let objectExp: Node = j.objectExpression([]);
if (safeTraverseAndGetType(p) === "ObjectExpression") {
- objectExp = p.value.value;
+ objectExp = (p.value as Node).value as Node;
}
// object -> loop through it
- Object.keys(value).forEach((prop: string) => {
- addProperty(j, objectExp, prop, value[prop]);
- });
+ Object.keys(value).forEach(
+ (prop: string): void => {
+ addProperty(j, objectExp, prop, value[prop]);
+ }
+ );
valForNode = objectExp;
} else {
valForNode = createIdentifierOrLiteral(j, value);
@@ -468,14 +469,16 @@ function addProperty(j: IJSCodeshift, p: INode, key: string, value: valueType, a
}
// we only return the generated pushVal which will be replace the node path
- if (action === "add") { return pushVal; }
+ if (action === "add") {
+ return pushVal;
+ }
if (p.properties) {
p.properties.push(pushVal);
return p;
}
- if (p.value && p.value.properties) {
- p.value.properties.push(pushVal);
+ if (p.value && (p.value as Node).properties) {
+ (p.value as Node).properties.push(pushVal);
return p;
}
if (p.elements) {
@@ -495,8 +498,7 @@ function addProperty(j: IJSCodeshift, p: INode, key: string, value: valueType, a
* @returns {Node} - the created ast
*/
-function removeProperty(j: IJSCodeshift, ast: INode, key: string, value: valueType): INode {
-
+function removeProperty(j: JSCodeshift, ast: Node, key: string, value: valueType): Node {
if (typeof value === "object" && !Array.isArray(value)) {
// override for module.rules / loaders
if (key === "module" && value.rules) {
@@ -504,12 +506,14 @@ function removeProperty(j: IJSCodeshift, ast: INode, key: string, value: valueTy
.find(j.Property, {
value: {
type: "Literal",
- value: value.rules[0].loader,
- },
+ value: value.rules[0].loader
+ }
})
- .forEach((p: INode) => {
- j(p.parent).remove();
- });
+ .forEach(
+ (p: Node): void => {
+ j(p.parent).remove();
+ }
+ );
}
}
@@ -517,14 +521,16 @@ function removeProperty(j: IJSCodeshift, ast: INode, key: string, value: valueTy
if (Array.isArray(value)) {
return ast
.find(j.Literal, {
- value: value[0],
+ value: value[0]
})
- .forEach((p: INode) => {
- const configKey = safeTraverse(p, ["parent", "parent", "node", "key", "name"]);
- if (configKey === key) {
- j(p).remove();
+ .forEach(
+ (p: Node): void => {
+ const configKey = safeTraverse(p, ["parent", "parent", "node", "key", "name"]);
+ if (configKey === key) {
+ j(p).remove();
+ }
}
- });
+ );
}
// value => literal string / boolean / nested object
@@ -533,19 +539,23 @@ function removeProperty(j: IJSCodeshift, ast: INode, key: string, value: valueTy
objKeyToRemove = key;
} else if (typeof value === "object") {
for (const innerKey in value) {
- if (value[innerKey] === null) { objKeyToRemove = innerKey; }
+ if (value[innerKey] === null) {
+ objKeyToRemove = innerKey;
+ }
}
}
return ast
.find(j.Property, {
key: {
name: objKeyToRemove,
- type: "Identifier",
- },
+ type: "Identifier"
+ }
})
- .forEach((p: INode) => {
- j(p).remove();
- });
+ .forEach(
+ (p: Node): void => {
+ j(p).remove();
+ }
+ );
}
/**
@@ -560,20 +570,23 @@ function removeProperty(j: IJSCodeshift, ast: INode, key: string, value: valueTy
* @returns ast - jscodeshift API
*/
-function parseTopScope(j: IJSCodeshift, ast: INode, value: string[], action: string): boolean | INode {
- function createTopScopeProperty(p: INode): boolean {
- value.forEach((n: string) => {
- if (
- !p.value.body[0].declarations ||
- n.indexOf(p.value.body[0].declarations[0].id.name) <= 0
- ) {
- p.value.body.splice(-1, 0, n);
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
+function parseTopScope(j: JSCodeshift, ast: Node, value: string[], action: string): boolean | Node {
+ function createTopScopeProperty(p: Node): boolean {
+ value.forEach(
+ (n: string): void => {
+ if (
+ !(p.value as Node).body[0].declarations ||
+ n.indexOf((p.value as Node).body[0].declarations[0].id.name) <= 0
+ ) {
+ (p.value as Node).body.splice(-1, 0, n);
+ }
}
- });
+ );
return false; // TODO: debug later
}
if (value) {
- return ast.find(j.Program).filter((p: INode): boolean => createTopScopeProperty(p));
+ return ast.find(j.Program).filter((p: Node): boolean => createTopScopeProperty(p));
} else {
return ast;
}
@@ -591,36 +604,36 @@ function parseTopScope(j: IJSCodeshift, ast: INode, value: string[], action: str
* @returns ast - jscodeshift API
*/
-function parseMerge(j: IJSCodeshift, ast: INode, value: string, action: string): boolean | INode {
- function createMergeProperty(p: INode) {
+// eslint-disable-next-line @typescript-eslint/no-unused-vars
+function parseMerge(j: JSCodeshift, ast: Node, value: string, action: string): boolean | Node {
+ function createMergeProperty(p: Node): boolean {
// FIXME Use j.callExp()
- const exportsDecl: INode[] = p.value.body.map((n: INode) => {
- if (n.expression) {
- return n.expression.right;
+ const exportsDecl: Node[] = (p.value as Node).body.map(
+ (n: Node): Node => {
+ if (n.expression) {
+ return n.expression.right;
+ }
}
- });
+ );
const bodyLength = exportsDecl.length;
- const newVal: INode = {};
+ const newVal: Node = {};
newVal.type = "ExpressionStatement";
newVal.expression = {
left: {
computed: false,
object: j.identifier("module"),
property: j.identifier("exports"),
- type: "MemberExpression",
+ type: "MemberExpression"
},
operator: "=",
- right: j.callExpression(j.identifier("merge"), [
- j.identifier(value),
- exportsDecl.pop(),
- ]),
- type: "AssignmentExpression",
+ right: j.callExpression(j.identifier("merge"), [j.identifier(value), exportsDecl.pop()]),
+ type: "AssignmentExpression"
};
- p.value.body[bodyLength - 1] = newVal;
+ (p.value as Node).body[bodyLength - 1] = newVal;
return false; // TODO: debug later
}
if (value) {
- return ast.find(j.Program).filter((p: INode): boolean => createMergeProperty(p));
+ return ast.find(j.Program).filter((p: Node): boolean => createMergeProperty(p));
} else {
return ast;
}
@@ -645,5 +658,5 @@ export {
addProperty,
removeProperty,
parseTopScope,
- parseMerge,
+ parseMerge
};
diff --git a/packages/utils/copy-utils.ts b/packages/utils/copy-utils.ts
index 5f78d92b3d4..4a593e95ae0 100644
--- a/packages/utils/copy-utils.ts
+++ b/packages/utils/copy-utils.ts
@@ -1,6 +1,6 @@
import * as path from "path";
-interface IGenerator {
+interface Generator {
fs: {
copy(from: string, to: string, options?: object): void;
copyTpl(from: string, to: string, context: object, templateOptions?: object, copyOptions?: object): void;
@@ -16,10 +16,9 @@ interface IGenerator {
* @param {string} templateDir Absolute path to template directory
* @returns {Function} A curried function that takes a file path and copies it
*/
-export const generatorCopy = (
- generator,
- templateDir: string,
-): (filePath: string) => void => (filePath: string): void => {
+export const generatorCopy = (generator, templateDir: string): ((filePath: string) => void) => (
+ filePath: string
+): void => {
const sourceParts = templateDir.split(path.delimiter);
sourceParts.push.apply(sourceParts, filePath.split("/"));
const targetParts = path.dirname(filePath).split("/");
@@ -27,7 +26,7 @@ export const generatorCopy = (
generator.fs.copy(
path.join.apply(null, sourceParts),
- generator.destinationPath(path.join.apply(null, targetParts)),
+ generator.destinationPath(path.join.apply(null, targetParts))
);
};
@@ -45,8 +44,8 @@ export const generatorCopy = (
export const generatorCopyTpl = (
generator,
templateDir: string,
- templateData: object,
-): (filePath: string) => void => (filePath: string): void => {
+ templateData: object
+): ((filePath: string) => void) => (filePath: string): void => {
const sourceParts = templateDir.split(path.delimiter);
sourceParts.push.apply(sourceParts, filePath.split("/"));
const targetParts = path.dirname(filePath).split("/");
@@ -55,6 +54,6 @@ export const generatorCopyTpl = (
generator.fs.copyTpl(
path.join.apply(null, sourceParts),
generator.destinationPath(path.join.apply(null, targetParts)),
- templateData,
+ templateData
);
};
diff --git a/packages/utils/defineTest.ts b/packages/utils/defineTest.ts
index a5ee041d26f..350e03a05ba 100644
--- a/packages/utils/defineTest.ts
+++ b/packages/utils/defineTest.ts
@@ -1,27 +1,28 @@
+/* eslint-disable @typescript-eslint/explicit-function-return-type */
import * as fs from "fs";
import * as path from "path";
-import { IJSCodeshift, INode } from "./types/NodePath";
+import { JSCodeshift, Node } from "./types/NodePath";
-interface IModule {
- (
- jscodeshift: IJSCodeshift,
- ast: INode,
- initOptions: string | boolean | object,
- action: string,
- transformName?: string,
- ): INode;
- default: transformType;
- parser: string;
+interface Module {
+ (
+ jscodeshift: JSCodeshift,
+ ast: Node,
+ initOptions: string | boolean | object,
+ action: string,
+ transformName?: string
+ ): Node;
+ default: transformType;
+ parser: string;
}
type transformType = (
- jscodeshift: IJSCodeshift,
- ast: INode,
- initOptions: string | boolean | object,
- action: object | string,
- transformName?: string,
-) => INode;
+ jscodeshift: JSCodeshift,
+ ast: Node,
+ initOptions: string | boolean | object,
+ action: object | string,
+ transformName?: string
+) => Node;
/**
* Utility function to run a jscodeshift script within a unit test.
@@ -48,54 +49,45 @@ type transformType = (
* @return {Function} Function that fires of the transforms
*/
function runSingleTransform(
- dirName: string,
- transformName: string,
- testFilePrefix: string,
- initOptions: object | boolean | string,
- action: object | string,
+ dirName: string,
+ transformName: string,
+ testFilePrefix: string,
+ initOptions: object | boolean | string,
+ action: object | string
): string {
- if (!testFilePrefix) {
- testFilePrefix = transformName;
- }
- const fixtureDir = path.join(
- dirName,
- "__tests__",
- "__testfixtures__",
- );
- const inputPath = path.join(fixtureDir, `${testFilePrefix}.input.js`);
- const source = fs.readFileSync(inputPath, "utf8");
+ if (!testFilePrefix) {
+ testFilePrefix = transformName;
+ }
+ const fixtureDir = path.join(dirName, "__tests__", "__testfixtures__");
+ const inputPath = path.join(fixtureDir, `${testFilePrefix}.input.js`);
+ const source = fs.readFileSync(inputPath, "utf8");
- let module: IModule;
- // Assumes transform and test are on the same level
- if (action) {
- module = require(path.join(dirName, "recursive-parser.ts"));
- } else {
- module = require(path.join(dirName, `${transformName}.ts`));
- }
- // Handle ES6 modules using default export for the transform
- const transform = module.default ? module.default : module;
+ let module: Module;
+ // Assumes transform and test are on the same level
+ if (action) {
+ module = require(path.join(dirName, "recursive-parser.ts"));
+ } else {
+ module = require(path.join(dirName, `${transformName}.ts`));
+ }
+ // Handle ES6 modules using default export for the transform
+ const transform = module.default ? module.default : module;
- // Jest resets the module registry after each test, so we need to always get
- // a fresh copy of jscodeshift on every test run.
- let jscodeshift: IJSCodeshift = require("jscodeshift/dist/core");
- if (module.parser) {
- jscodeshift = jscodeshift.withParser(module.parser);
- }
- const ast: INode = jscodeshift(source);
- if (initOptions || typeof initOptions === "boolean") {
- return transform(
- jscodeshift,
- ast,
- initOptions,
- action,
- transformName,
- ).toSource({
- quote: "single",
- });
- }
- return transform(jscodeshift, ast, source, action).toSource({
- quote: "single",
- });
+ // Jest resets the module registry after each test, so we need to always get
+ // a fresh copy of jscodeshift on every test run.
+ // eslint-disable-next-line
+ let jscodeshift: JSCodeshift = require("jscodeshift/dist/core");
+ if (module.parser) {
+ jscodeshift = jscodeshift.withParser(module.parser);
+ }
+ const ast: Node = jscodeshift(source);
+ if (initOptions || typeof initOptions === "boolean") {
+ return transform(jscodeshift, ast, initOptions, action, transformName).toSource({
+ quote: "single"
+ });
+ }
+ return transform(jscodeshift, ast, source, action).toSource({
+ quote: "single"
+ });
}
/**
@@ -116,19 +108,19 @@ function runSingleTransform(
* @return {Void} Jest makes sure to execute the globally defined functions
*/
export default function defineTest(
- dirName: string,
- transformName: string,
- testFilePrefix?: string,
- transformObject?: object | string,
- action?: object | string,
+ dirName: string,
+ transformName: string,
+ testFilePrefix?: string,
+ transformObject?: object | string,
+ action?: object | string
): void {
- const testName: string = testFilePrefix
- ? `transforms correctly using "${testFilePrefix}" data`
- : "transforms correctly";
- describe(transformName, () => {
- it(testName, () => {
- const output = runSingleTransform(dirName, transformName, testFilePrefix, transformObject, action);
- expect(output).toMatchSnapshot();
- });
- });
+ const testName: string = testFilePrefix
+ ? `transforms correctly using "${testFilePrefix}" data`
+ : "transforms correctly";
+ describe(transformName, () => {
+ it(testName, () => {
+ const output = runSingleTransform(dirName, transformName, testFilePrefix, transformObject, action);
+ expect(output).toMatchSnapshot();
+ });
+ });
}
diff --git a/packages/utils/modify-config-helper.ts b/packages/utils/modify-config-helper.ts
index 219a45ae5fe..c457a115e26 100644
--- a/packages/utils/modify-config-helper.ts
+++ b/packages/utils/modify-config-helper.ts
@@ -6,9 +6,9 @@ import * as yeoman from "yeoman-environment";
import Generator = require("yeoman-generator");
import runTransform from "./scaffold";
-import { IGenerator, IYeoman } from "./types/Yeoman";
+import { YeoGenerator } from "./types/Yeoman";
-export interface IConfig extends Object {
+export interface Config extends Object {
item?: {
name: string;
};
@@ -18,10 +18,10 @@ export interface IConfig extends Object {
webpackOptions: object;
}
-export interface ITransformConfig extends Object {
+export interface TransformConfig extends Object {
configPath?: string;
configFile?: string;
- config?: IConfig;
+ config?: Config;
}
const DEFAULT_WEBPACK_CONFIG_FILENAME = "webpack.config.js";
@@ -40,11 +40,10 @@ const DEFAULT_WEBPACK_CONFIG_FILENAME = "webpack.config.js";
export default function modifyHelperUtil(
action: string,
- generator: IGenerator,
+ generator: YeoGenerator,
configFile: string = DEFAULT_WEBPACK_CONFIG_FILENAME,
- packages?: string[])
- : Function {
-
+ packages?: string[]
+): Function {
let configPath: string | null = null;
if (action !== "init") {
@@ -57,7 +56,7 @@ export default function modifyHelperUtil(
chalk.green(" SUCCESS ") +
"Found config " +
chalk.cyan(configFile + "\n") +
- "\n",
+ "\n"
);
} else {
process.stdout.write(
@@ -68,7 +67,7 @@ export default function modifyHelperUtil(
" not found. Please specify a valid path to your webpack config like " +
chalk.white("$ ") +
chalk.cyan(`webpack-cli ${action} webpack.dev.js`) +
- "\n",
+ "\n"
);
return;
}
@@ -79,58 +78,68 @@ export default function modifyHelperUtil(
if (!generator) {
generator = class extends Generator {
- public initializing() {
- packages.forEach((pkgPath: string) => {
- return (this as IGenerator).composeWith(require.resolve(pkgPath));
- });
+ public initializing(): void {
+ packages.forEach(
+ (pkgPath: string): void => {
+ return (this as YeoGenerator).composeWith(require.resolve(pkgPath));
+ }
+ );
}
};
}
env.registerStub(generator, generatorName);
- env.run(generatorName).then((_: void) => {
- let configModule: object;
- try {
- const confPath = path.resolve(process.cwd(), ".yo-rc.json");
- configModule = require(confPath);
- // Change structure of the config to be transformed
- const tmpConfig: object = {};
- Object.keys(configModule).forEach((prop: string): void => {
- const configs = Object.keys(configModule[prop].configuration);
- configs.forEach((conf: string): void => {
- tmpConfig[conf] = configModule[prop].configuration[conf];
- });
- });
- configModule = tmpConfig;
- } catch (err) {
- console.error(
- chalk.red("\nCould not find a yeoman configuration file.\n"),
- );
- console.error(
- chalk.red(
- "\nPlease make sure to use 'this.config.set('configuration', this.configuration);' at the end of the generator.\n",
- ),
- );
- Error.stackTraceLimit = 0;
- process.exitCode = -1;
- }
- const transformConfig: ITransformConfig = Object.assign(
- {
- configFile: !configPath ? null : fs.readFileSync(configPath, "utf8"),
- configPath,
- },
- configModule,
- );
- return runTransform(transformConfig, action);
- }).catch((err) => {
- console.error(
- chalk.red(
- `
+ env.run(generatorName)
+ .then(
+ (): void => {
+ let configModule: object;
+ try {
+ const confPath = path.resolve(process.cwd(), ".yo-rc.json");
+ configModule = require(confPath);
+ // Change structure of the config to be transformed
+ const tmpConfig: object = {};
+ Object.keys(configModule).forEach(
+ (prop: string): void => {
+ const configs = Object.keys(configModule[prop].configuration);
+ configs.forEach(
+ (conf: string): void => {
+ tmpConfig[conf] = configModule[prop].configuration[conf];
+ }
+ );
+ }
+ );
+ configModule = tmpConfig;
+ } catch (err) {
+ console.error(chalk.red("\nCould not find a yeoman configuration file.\n"));
+ console.error(
+ chalk.red(
+ "\nPlease make sure to use 'this.config.set('configuration', this.configuration);' at the end of the generator.\n"
+ )
+ );
+ Error.stackTraceLimit = 0;
+ process.exitCode = -1;
+ }
+ const transformConfig: TransformConfig = Object.assign(
+ {
+ configFile: !configPath ? null : fs.readFileSync(configPath, "utf8"),
+ configPath
+ },
+ configModule
+ );
+ return runTransform(transformConfig, action);
+ }
+ )
+ .catch(
+ (err): void => {
+ console.error(
+ chalk.red(
+ `
Unexpected Error
please file an issue here https://github.com/webpack/webpack-cli/issues/new?template=Bug_report.md
- `,
- ),
+ `
+ )
+ );
+ console.error(err);
+ }
);
- console.error(err);
- });
}
diff --git a/packages/utils/npm-exists.ts b/packages/utils/npm-exists.ts
index 2abc29b40c3..0db70f11883 100644
--- a/packages/utils/npm-exists.ts
+++ b/packages/utils/npm-exists.ts
@@ -1,5 +1,7 @@
import * as got from "got";
+// TODO: to understand the type
+// eslint-disable-next-line
const constant = (value: boolean) => (res: got.Response): boolean | PromiseLike => value;
/**
@@ -11,11 +13,13 @@ const constant = (value: boolean) => (res: got.Response): boolean | Prom
* based on if it exists or not
*/
+// TODO: figure out the correct type here
+// eslint-disable-next-line
export default function npmExists(moduleName: string): Promise {
const hostname = "https://www.npmjs.org";
const pkgUrl = `${hostname}/package/${moduleName}`;
return got(pkgUrl, {
- method: "HEAD",
+ method: "HEAD"
})
.then(constant(true))
.catch(constant(false));
diff --git a/packages/utils/npm-packages-exists.ts b/packages/utils/npm-packages-exists.ts
index a1987c3332d..529da51ad2f 100644
--- a/packages/utils/npm-packages-exists.ts
+++ b/packages/utils/npm-packages-exists.ts
@@ -18,46 +18,52 @@ const WEBPACK_SCAFFOLD_PREFIX = "webpack-scaffold";
export default function npmPackagesExists(pkg: string[]): void {
const acceptedPackages: string[] = [];
- function resolvePackagesIfReady() {
+ function resolvePackagesIfReady(): void | Function {
if (acceptedPackages.length === pkg.length) {
return resolvePackages(acceptedPackages);
}
}
- pkg.forEach((scaffold: string): void => {
- if (isLocalPath(scaffold)) {
- // If the scaffold is a path to a local folder, no name validation is necessary.
- acceptedPackages.push(scaffold);
- resolvePackagesIfReady();
- return;
- }
+ pkg.forEach(
+ (scaffold: string): void => {
+ if (isLocalPath(scaffold)) {
+ // If the scaffold is a path to a local folder, no name validation is necessary.
+ acceptedPackages.push(scaffold);
+ resolvePackagesIfReady();
+ return;
+ }
- // The scaffold is on npm; validate name and existence
- if (
- scaffold.length <= WEBPACK_SCAFFOLD_PREFIX.length ||
- scaffold.slice(0, WEBPACK_SCAFFOLD_PREFIX.length) !== WEBPACK_SCAFFOLD_PREFIX
- ) {
- throw new TypeError(
- chalk.bold(`${scaffold} isn't a valid name.\n`) +
- chalk.red(
- `\nIt should be prefixed with '${WEBPACK_SCAFFOLD_PREFIX}', but have different suffix.\n`,
- ),
- );
- }
+ // The scaffold is on npm; validate name and existence
+ if (
+ scaffold.length <= WEBPACK_SCAFFOLD_PREFIX.length ||
+ scaffold.slice(0, WEBPACK_SCAFFOLD_PREFIX.length) !== WEBPACK_SCAFFOLD_PREFIX
+ ) {
+ throw new TypeError(
+ chalk.bold(`${scaffold} isn't a valid name.\n`) +
+ chalk.red(
+ `\nIt should be prefixed with '${WEBPACK_SCAFFOLD_PREFIX}', but have different suffix.\n`
+ )
+ );
+ }
- npmExists(scaffold)
- .then((moduleExists: boolean) => {
- if (moduleExists) {
- acceptedPackages.push(scaffold);
- } else {
- Error.stackTraceLimit = 0;
- throw new TypeError(`Cannot resolve location of package ${scaffold}.`);
- }
- })
- .catch((err: IError) => {
- console.error(err.stack || err);
- process.exit(0);
- })
- .then(resolvePackagesIfReady);
- });
+ npmExists(scaffold)
+ .then(
+ (moduleExists: boolean): void => {
+ if (moduleExists) {
+ acceptedPackages.push(scaffold);
+ } else {
+ Error.stackTraceLimit = 0;
+ throw new TypeError(`Cannot resolve location of package ${scaffold}.`);
+ }
+ }
+ )
+ .catch(
+ (err: Error): void => {
+ console.error(err.stack || err);
+ process.exit(0);
+ }
+ )
+ .then(resolvePackagesIfReady);
+ }
+ );
}
diff --git a/packages/utils/package-lock.json b/packages/utils/package-lock.json
index 5c04b28b295..be49655ae02 100644
--- a/packages/utils/package-lock.json
+++ b/packages/utils/package-lock.json
@@ -149,7 +149,7 @@
},
"ansi-escapes": {
"version": "3.1.0",
- "resolved": "http://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz",
"integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw=="
},
"ansi-regex": {
@@ -465,7 +465,7 @@
},
"array-equal": {
"version": "1.0.0",
- "resolved": "http://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz",
+ "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz",
"integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM="
},
"array-union": {
@@ -1619,7 +1619,7 @@
"dependencies": {
"colors": {
"version": "1.0.3",
- "resolved": "http://registry.npmjs.org/colors/-/colors-1.0.3.tgz",
+ "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz",
"integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs="
}
}
@@ -2942,7 +2942,8 @@
},
"ansi-regex": {
"version": "2.1.1",
- "bundled": true
+ "bundled": true,
+ "optional": true
},
"aproba": {
"version": "1.2.0",
@@ -2960,11 +2961,13 @@
},
"balanced-match": {
"version": "1.0.0",
- "bundled": true
+ "bundled": true,
+ "optional": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
+ "optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@@ -2977,15 +2980,18 @@
},
"code-point-at": {
"version": "1.1.0",
- "bundled": true
+ "bundled": true,
+ "optional": true
},
"concat-map": {
"version": "0.0.1",
- "bundled": true
+ "bundled": true,
+ "optional": true
},
"console-control-strings": {
"version": "1.1.0",
- "bundled": true
+ "bundled": true,
+ "optional": true
},
"core-util-is": {
"version": "1.0.2",
@@ -3088,7 +3094,8 @@
},
"inherits": {
"version": "2.0.3",
- "bundled": true
+ "bundled": true,
+ "optional": true
},
"ini": {
"version": "1.3.5",
@@ -3098,6 +3105,7 @@
"is-fullwidth-code-point": {
"version": "1.0.0",
"bundled": true,
+ "optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@@ -3110,17 +3118,20 @@
"minimatch": {
"version": "3.0.4",
"bundled": true,
+ "optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
},
"minimist": {
"version": "0.0.8",
- "bundled": true
+ "bundled": true,
+ "optional": true
},
"minipass": {
"version": "2.2.4",
"bundled": true,
+ "optional": true,
"requires": {
"safe-buffer": "^5.1.1",
"yallist": "^3.0.0"
@@ -3137,6 +3148,7 @@
"mkdirp": {
"version": "0.5.1",
"bundled": true,
+ "optional": true,
"requires": {
"minimist": "0.0.8"
}
@@ -3209,7 +3221,8 @@
},
"number-is-nan": {
"version": "1.0.1",
- "bundled": true
+ "bundled": true,
+ "optional": true
},
"object-assign": {
"version": "4.1.1",
@@ -3219,6 +3232,7 @@
"once": {
"version": "1.4.0",
"bundled": true,
+ "optional": true,
"requires": {
"wrappy": "1"
}
@@ -3294,7 +3308,8 @@
},
"safe-buffer": {
"version": "5.1.1",
- "bundled": true
+ "bundled": true,
+ "optional": true
},
"safer-buffer": {
"version": "2.1.2",
@@ -3324,6 +3339,7 @@
"string-width": {
"version": "1.0.2",
"bundled": true,
+ "optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@@ -3341,6 +3357,7 @@
"strip-ansi": {
"version": "3.0.1",
"bundled": true,
+ "optional": true,
"requires": {
"ansi-regex": "^2.0.0"
}
@@ -3379,11 +3396,13 @@
},
"wrappy": {
"version": "1.0.2",
- "bundled": true
+ "bundled": true,
+ "optional": true
},
"yallist": {
"version": "3.0.2",
- "bundled": true
+ "bundled": true,
+ "optional": true
}
}
},
@@ -3545,7 +3564,7 @@
},
"globby": {
"version": "8.0.1",
- "resolved": "http://registry.npmjs.org/globby/-/globby-8.0.1.tgz",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-8.0.1.tgz",
"integrity": "sha512-oMrYrJERnKBLXNLVTqhm3vPEdJ/b2ZE28xN4YARiix1NOIOBPEpOUnm844K1iu/BkphCaf2WNFwMszv8Soi1pw==",
"requires": {
"array-union": "^1.0.1",
@@ -4728,7 +4747,7 @@
},
"jsesc": {
"version": "1.3.0",
- "resolved": "http://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz",
"integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s="
},
"json-buffer": {
@@ -5395,7 +5414,7 @@
},
"os-homedir": {
"version": "1.0.2",
- "resolved": "http://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
+ "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
"integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M="
},
"os-locale": {
@@ -5410,7 +5429,7 @@
},
"os-tmpdir": {
"version": "1.0.2",
- "resolved": "http://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+ "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
"integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ="
},
"p-cancelable": {
@@ -5516,7 +5535,7 @@
},
"path-is-absolute": {
"version": "1.0.1",
- "resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
},
"path-key": {
@@ -6049,7 +6068,7 @@
},
"safe-regex": {
"version": "1.1.0",
- "resolved": "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
+ "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
"integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
"requires": {
"ret": "~0.1.10"
@@ -6711,7 +6730,7 @@
},
"strip-eof": {
"version": "1.0.0",
- "resolved": "http://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
+ "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
"integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8="
},
"supports-color": {
@@ -6729,7 +6748,7 @@
},
"temp": {
"version": "0.8.3",
- "resolved": "http://registry.npmjs.org/temp/-/temp-0.8.3.tgz",
+ "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.3.tgz",
"integrity": "sha1-4Ma8TSa5AxJEEOT+2BEDAU38H1k=",
"requires": {
"os-tmpdir": "^1.0.0",
diff --git a/packages/utils/package-manager.ts b/packages/utils/package-manager.ts
index 0a48e062607..888b974ef18 100644
--- a/packages/utils/package-manager.ts
+++ b/packages/utils/package-manager.ts
@@ -4,16 +4,11 @@ import * as spawn from "cross-spawn";
import * as fs from "fs";
import * as path from "path";
-interface ISpawnFunctions {
+interface SpawnFunctions {
npm: (pkg: string, isNew: boolean) => SpawnSyncReturns;
yarn: (pkg: string, isNew: boolean) => SpawnSyncReturns;
}
-const SPAWN_FUNCTIONS: ISpawnFunctions = {
- npm: spawnNPM,
- yarn: spawnYarn,
-};
-
/**
*
* Spawns a new process using npm
@@ -25,7 +20,7 @@ const SPAWN_FUNCTIONS: ISpawnFunctions = {
function spawnNPM(pkg: string, isNew: boolean): SpawnSyncReturns {
return spawn.sync("npm", [isNew ? "install" : "update", "-g", pkg], {
- stdio: "inherit",
+ stdio: "inherit"
});
}
@@ -40,25 +35,14 @@ function spawnNPM(pkg: string, isNew: boolean): SpawnSyncReturns {
function spawnYarn(pkg: string, isNew: boolean): SpawnSyncReturns {
return spawn.sync("yarn", ["global", isNew ? "add" : "upgrade", pkg], {
- stdio: "inherit",
+ stdio: "inherit"
});
}
-/**
- *
- * Spawns a new process that installs the scaffold/dependency
- *
- * @param {String} pkg - The dependency to be installed
- * @returns {Function} spawn - Installs the package
- */
-
-export function spawnChild(pkg: string): SpawnSyncReturns {
- const rootPath: string = getPathToGlobalPackages();
- const pkgPath: string = path.resolve(rootPath, pkg);
- const packageManager: string = getPackageManager();
- const isNew: boolean = !fs.existsSync(pkgPath);
- return SPAWN_FUNCTIONS[packageManager](pkg, isNew);
-}
+const SPAWN_FUNCTIONS: SpawnFunctions = {
+ npm: spawnNPM,
+ yarn: spawnYarn
+};
/**
*
@@ -69,9 +53,7 @@ export function spawnChild(pkg: string): SpawnSyncReturns {
*/
export function getPackageManager(): string {
- const hasLocalNPM = fs.existsSync(
- path.resolve(process.cwd(), "package-lock.json"),
- );
+ const hasLocalNPM = fs.existsSync(path.resolve(process.cwd(), "package-lock.json"));
const hasLocalYarn = fs.existsSync(path.resolve(process.cwd(), "yarn.lock"));
if (hasLocalNPM) {
return "npm";
@@ -109,3 +91,18 @@ export function getPathToGlobalPackages(): string {
return require("global-modules");
}
+/**
+ *
+ * Spawns a new process that installs the scaffold/dependency
+ *
+ * @param {String} pkg - The dependency to be installed
+ * @returns {SpawnSyncReturns} spawn - Installs the package
+ */
+export function spawnChild(pkg: string): SpawnSyncReturns {
+ const rootPath: string = getPathToGlobalPackages();
+ const pkgPath: string = path.resolve(rootPath, pkg);
+ const packageManager: string = getPackageManager();
+ const isNew: boolean = !fs.existsSync(pkgPath);
+
+ return SPAWN_FUNCTIONS[packageManager](pkg, isNew);
+}
diff --git a/packages/utils/recursive-parser.ts b/packages/utils/recursive-parser.ts
index f6c9f03b7eb..a6312798f5b 100644
--- a/packages/utils/recursive-parser.ts
+++ b/packages/utils/recursive-parser.ts
@@ -1,9 +1,13 @@
import * as utils from "./ast-utils";
-import { IJSCodeshift, INode, valueType } from "./types/NodePath";
+import { JSCodeshift, Node, valueType } from "./types/NodePath";
export default function recursiveTransform(
- j: IJSCodeshift, ast: INode, key: string, value: valueType, action: string,
-): boolean | INode {
+ j: JSCodeshift,
+ ast: Node,
+ key: string,
+ value: valueType,
+ action: string
+): boolean | Node {
if (key === "topScope") {
if (Array.isArray(value)) {
return utils.parseTopScope(j, ast, value, action);
@@ -15,46 +19,39 @@ export default function recursiveTransform(
return utils.parseMerge(j, ast, value, action);
}
}
- const node: INode = utils.findRootNodesByName(j, ast, key);
+ const node: Node = utils.findRootNodesByName(j, ast, key);
// get module.exports prop
const root = ast
.find(j.ObjectExpression)
- .filter((p: INode): boolean => {
- return (
- utils.safeTraverse(p, [
- "parentPath",
- "value",
- "left",
- "object",
- "name",
- ]) === "module" &&
- utils.safeTraverse(p, [
- "parentPath",
- "value",
- "left",
- "property",
- "name",
- ]) === "exports"
- );
- })
- .filter((p: INode): boolean => p.value.properties);
+ .filter(
+ (p: Node): boolean => {
+ return (
+ utils.safeTraverse(p, ["parentPath", "value", "left", "object", "name"]) === "module" &&
+ utils.safeTraverse(p, ["parentPath", "value", "left", "property", "name"]) === "exports"
+ );
+ }
+ )
+ .filter((p: Node): boolean => !!(p.value as Node).properties);
if (node.size() !== 0) {
if (action === "add") {
- return utils.findRootNodesByName(j, root, key)
- .forEach((p: INode) => {
+ return utils.findRootNodesByName(j, root, key).forEach(
+ (p: Node): void => {
j(p).replaceWith(utils.addProperty(j, p, key, value, action));
- });
+ }
+ );
} else if (action === "remove") {
return utils.removeProperty(j, root, key, value);
}
} else {
- return root.forEach((p: INode) => {
- if (value) {
- // init, add new property
- utils.addProperty(j, p, key, value, null);
+ return root.forEach(
+ (p: Node): void => {
+ if (value) {
+ // init, add new property
+ utils.addProperty(j, p, key, value, null);
+ }
}
- });
+ );
}
}
diff --git a/packages/utils/resolve-packages.ts b/packages/utils/resolve-packages.ts
index b16823509a9..c5dabe60474 100644
--- a/packages/utils/resolve-packages.ts
+++ b/packages/utils/resolve-packages.ts
@@ -6,7 +6,7 @@ import modifyConfigHelper from "./modify-config-helper";
import { getPathToGlobalPackages } from "./package-manager";
import { spawnChild } from "./package-manager";
-interface IChildProcess {
+interface ChildProcess {
status: number;
}
@@ -18,14 +18,16 @@ interface IChildProcess {
* @returns {Promise} promise - Returns a promise to the installation
*/
-export function processPromise(child: IChildProcess): Promise {
- return new Promise((resolve: (_?: void) => void, reject: (_?: void) => void) => {
- if (child.status !== 0) {
- reject();
- } else {
- resolve();
+export function processPromise(child: ChildProcess): Promise {
+ return new Promise(
+ (resolve: () => void, reject: () => void): void => {
+ if (child.status !== 0) {
+ reject();
+ } else {
+ resolve();
+ }
}
- });
+ );
}
/**
@@ -48,46 +50,52 @@ export function resolvePackages(pkg: string[]): Function | void {
}
}
- pkg.forEach((scaffold: string) => {
- // Resolve paths to modules on local filesystem
- if (isLocalPath(scaffold)) {
- let absolutePath: string = scaffold;
-
- try {
- absolutePath = path.resolve(process.cwd(), scaffold);
- require.resolve(absolutePath);
- packageLocations.push(absolutePath);
- } catch (err) {
- console.error(`Cannot find a generator at ${absolutePath}.`);
- console.error("\nReason:\n");
- console.error(chalk.bold.red(err));
- process.exitCode = 1;
- }
-
- invokeGeneratorIfReady();
- return;
- }
+ pkg.forEach(
+ (scaffold: string): void => {
+ // Resolve paths to modules on local filesystem
+ if (isLocalPath(scaffold)) {
+ let absolutePath: string = scaffold;
- // Resolve modules on npm registry
- processPromise(spawnChild(scaffold))
- .then((_: void) => {
try {
- const globalPath: string = getPathToGlobalPackages();
- packageLocations.push(path.resolve(globalPath, scaffold));
+ absolutePath = path.resolve(process.cwd(), scaffold);
+ require.resolve(absolutePath);
+ packageLocations.push(absolutePath);
} catch (err) {
- console.error("Package wasn't validated correctly..");
- console.error("Submit an issue for", pkg, "if this persists");
- console.error("\nReason: \n");
+ console.error(`Cannot find a generator at ${absolutePath}.`);
+ console.error("\nReason:\n");
console.error(chalk.bold.red(err));
process.exitCode = 1;
}
- })
- .catch((err: string) => {
- console.error("Package couldn't be installed, aborting..");
- console.error("\nReason: \n");
- console.error(chalk.bold.red(err));
- process.exitCode = 1;
- })
- .then(invokeGeneratorIfReady);
- });
+
+ invokeGeneratorIfReady();
+ return;
+ }
+
+ // Resolve modules on npm registry
+ processPromise(spawnChild(scaffold))
+ .then(
+ (): void => {
+ try {
+ const globalPath: string = getPathToGlobalPackages();
+ packageLocations.push(path.resolve(globalPath, scaffold));
+ } catch (err) {
+ console.error("Package wasn't validated correctly..");
+ console.error("Submit an issue for", pkg, "if this persists");
+ console.error("\nReason: \n");
+ console.error(chalk.bold.red(err));
+ process.exitCode = 1;
+ }
+ }
+ )
+ .catch(
+ (err: string): void => {
+ console.error("Package couldn't be installed, aborting..");
+ console.error("\nReason: \n");
+ console.error(chalk.bold.red(err));
+ process.exitCode = 1;
+ }
+ )
+ .then(invokeGeneratorIfReady);
+ }
+ );
}
diff --git a/packages/utils/scaffold.ts b/packages/utils/scaffold.ts
index a3add9ee769..2d2ece8a390 100644
--- a/packages/utils/scaffold.ts
+++ b/packages/utils/scaffold.ts
@@ -4,12 +4,12 @@ import pEachSeries = require("p-each-series");
import * as path from "path";
import { findProjectRoot } from "./find-root";
-import { IError } from "../init/types";
-import { IConfig, ITransformConfig } from "./modify-config-helper";
+import { Error } from "../init/types";
+import { Config, TransformConfig } from "./modify-config-helper";
import propTypes from "./prop-types";
import astTransform from "./recursive-parser";
import runPrettier from "./run-prettier";
-import { INode } from "./types/NodePath";
+import { Node } from "./types/NodePath";
/**
*
@@ -20,7 +20,7 @@ import { INode } from "./types/NodePath";
* @returns {Array} - An array with keys on which transformations need to be run
*/
-function mapOptionsToTransform(config: IConfig): string[] {
+function mapOptionsToTransform(config: Config): string[] {
return Object.keys(config.webpackOptions).filter((k: string): boolean => propTypes.has(k));
}
@@ -34,72 +34,73 @@ function mapOptionsToTransform(config: IConfig): string[] {
* and writes the file
*/
-export default function runTransform(transformConfig: ITransformConfig, action: string): void {
+export default function runTransform(transformConfig: TransformConfig, action: string): void {
// webpackOptions.name sent to nameTransform if match
- const webpackConfig = Object.keys(transformConfig).filter((p: string): boolean => {
- return p !== "configFile" && p !== "configPath";
- });
+ const webpackConfig = Object.keys(transformConfig).filter(
+ (p: string): boolean => {
+ return p !== "configFile" && p !== "configPath";
+ }
+ );
const initActionNotDefined = action && action !== "init" ? true : false;
- webpackConfig.forEach((scaffoldPiece: string) => {
- const config: IConfig = transformConfig[scaffoldPiece];
+ webpackConfig.forEach(
+ (scaffoldPiece: string): Promise => {
+ const config: Config = transformConfig[scaffoldPiece];
- const transformations = mapOptionsToTransform(config);
+ const transformations = mapOptionsToTransform(config);
- if (config.topScope && transformations.indexOf("topScope") === -1) {
- transformations.push("topScope");
- }
+ if (config.topScope && transformations.indexOf("topScope") === -1) {
+ transformations.push("topScope");
+ }
- if (config.merge) {
- transformations.push("merge");
- }
+ if (config.merge) {
+ transformations.push("merge");
+ }
- const ast: INode = j(
- initActionNotDefined
- ? transformConfig.configFile
- : "module.exports = {}",
- );
+ const ast: Node = j(initActionNotDefined ? transformConfig.configFile : "module.exports = {}");
- const transformAction: string = action || null;
+ const transformAction: string = action || null;
- return pEachSeries(transformations, (f: string): boolean | INode => {
- if (f === "merge" || f === "topScope") {
- return astTransform(j, ast, f, config[f], transformAction);
- }
- return astTransform(j, ast, f, config.webpackOptions[f], transformAction);
- })
- .then((value: string[]): void | PromiseLike => {
- let configurationName: string;
- if (!config.configName) {
- configurationName = "webpack.config.js";
- } else {
- configurationName = "webpack." + config.configName + ".js";
+ return pEachSeries(
+ transformations,
+ (f: string): boolean | Node => {
+ if (f === "merge" || f === "topScope") {
+ // TODO: typing here is difficult to understand
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ return astTransform(j, ast, f, config[f] as any, transformAction);
+ }
+ return astTransform(j, ast, f, config.webpackOptions[f], transformAction);
}
+ )
+ .then(
+ (): void | PromiseLike => {
+ let configurationName: string;
+ if (!config.configName) {
+ configurationName = "webpack.config.js";
+ } else {
+ configurationName = "webpack." + config.configName + ".js";
+ }
- const projectRoot = findProjectRoot();
- const outputPath: string = initActionNotDefined
- ? transformConfig.configPath
- : path.join(projectRoot || process.cwd(), configurationName);
- const source: string = ast.toSource({
- quote: "single",
- });
- runPrettier(outputPath, source);
-
- })
- .catch((err: IError) => {
- console.error(err.message ? err.message : err);
- });
- });
+ const projectRoot = findProjectRoot();
+ const outputPath: string = initActionNotDefined
+ ? transformConfig.configPath
+ : path.join(projectRoot || process.cwd(), configurationName);
+ const source: string = ast.toSource({
+ quote: "single"
+ });
+ runPrettier(outputPath, source);
+ }
+ )
+ .catch(
+ (err: Error): void => {
+ console.error(err.message ? err.message : err);
+ }
+ );
+ }
+ );
let successMessage: string = `Congratulations! Your new webpack configuration file has been created!\n`;
if (initActionNotDefined && transformConfig.config.item) {
- successMessage = `Congratulations! ${
- transformConfig.config.item
- } has been ${action}ed!\n`;
+ successMessage = `Congratulations! ${transformConfig.config.item} has been ${action}ed!\n`;
}
- process.stdout.write(
- "\n" +
- chalk.green(
- successMessage,
- ),
- );
+ process.stdout.write("\n" + chalk.green(successMessage));
}
diff --git a/packages/utils/types/NodePath.ts b/packages/utils/types/NodePath.ts
index d082ddc6587..1b828378ddb 100644
--- a/packages/utils/types/NodePath.ts
+++ b/packages/utils/types/NodePath.ts
@@ -1,93 +1,99 @@
-export interface INode extends Object {
+export interface Node extends Object {
id?: {
name: string;
};
- arguments?: INode[];
- body?: INode[];
- elements?: INode[];
+ arguments?: Node[];
+ body?: Node[];
+ elements?: Node[];
expression?: {
left: {
- computed: boolean,
- object: INode,
- property: INode,
- type: string,
- },
- operator: string,
- right: INode,
- type: string,
+ computed: boolean;
+ object: Node;
+ property: Node;
+ type: string;
+ };
+ operator: string;
+ right: Node;
+ type: string;
+ value?: string;
};
- filter?: (p: (p: INode) => boolean) => INode;
- find?: (objectExpression: object, filterExpression?: object) => INode;
- forEach?: (p: (p: INode) => void) => INode;
- get?: (property: string) => INode;
- remove?: (_?: void) => void;
- nodes?: (_?: void) => INode[];
- pop?: (_?: void) => INode;
+ filter?: (p: (p: Node) => boolean) => Node;
+ find?: (objectExpression: object, filterExpression?: object) => Node;
+ forEach?: (p: (p: Node) => void) => Node;
+ get?: (property: string) => Node;
+ remove?: () => void;
+ nodes?: () => Node[];
+ pop?: () => Node;
key?: {
name: string;
- value: INode | string;
+ value: Node | string;
};
- node?: INode;
+ node?: Node;
name?: string;
object?: object;
- parent?: INode;
- properties?: INode[];
- property?: INode;
+ parent?: Node;
+ properties?: Node[];
+ property?: Node;
prune?: Function;
- replaceWith?: (objectExpression: object) => INode;
- size?: (_?: void) => number;
+ replaceWith?: (objectExpression: object) => Node;
+ size?: () => number;
type?: string;
- value?: INode | string | any;
- toSource?: (object: {
- quote?: string,
- }) => string;
+ value?: Node | string | Node[];
+ toSource?: (
+ object: {
+ quote?: string;
+ }
+ ) => string;
source?: string;
- ast?: INode;
- rules?: IModuleRule[];
- __paths?: INode[];
+ ast?: Node;
+ rules?: ModuleRule[];
+
+ declarations?: Node[];
+
+ __paths?: Node[];
}
-interface IModuleRule {
+interface ModuleRule {
loader?: string;
}
-interface IExpressionObject {
+interface ExpressionObject {
name?: string;
}
-export interface IJSCodeshift extends Object {
- (source?: INode | string): INode;
- withParser?: (parser: string) => IJSCodeshift;
- identifier?: (key: string) => INode;
- literal?: (key: valueType) => INode;
- memberExpression?: (node1: INode, node2: INode, bool?: boolean) => INode;
- objectProperty?: (key: INode, property: valueType) => INode;
- objectExpression?: (properties: INode[]) => INode;
- newExpression?: (expression: INode, args: INode[]) => INode;
- callExpression?: (expression: INode, args: INode[]) => INode;
- variableDeclarator?: (key: INode, args: INode) => INode;
- variableDeclaration?: (key: string, args: INode[]) => INode;
- arrayExpression?: (args?: INode[]) => INode;
- property?: (type: string, key: INode, value: INode) => INode;
- program?: (nodes: INode[]) => INode;
- booleanLiteral?: (bool: boolean) => INode;
- Property?: IExpressionObject;
- NewExpression?: IExpressionObject;
- CallExpression?: IExpressionObject;
- VariableDeclarator?: IExpressionObject;
- Identifier?: IExpressionObject;
- Literal?: IExpressionObject;
- ArrayExpression?: IExpressionObject;
- MemberExpression?: IExpressionObject;
- FunctionExpression?: IExpressionObject;
- ObjectExpression?: IExpressionObject;
- BlockStatement?: IExpressionObject;
- Program?: IExpressionObject;
+export interface JSCodeshift extends Object {
+ (source?: Node | string): Node;
+ withParser?: (parser: string) => JSCodeshift;
+ identifier?: (key: string) => Node;
+ literal?: (key: valueType) => Node;
+ memberExpression?: (node1: Node, node2: Node, bool?: boolean) => Node;
+ objectProperty?: (key: Node, property: valueType) => Node;
+ objectExpression?: (properties: Node[]) => Node;
+ newExpression?: (expression: Node, args: Node[]) => Node;
+ callExpression?: (expression: Node, args: Node[]) => Node;
+ variableDeclarator?: (key: Node, args: Node) => Node;
+ variableDeclaration?: (key: string, args: Node[]) => Node;
+ arrayExpression?: (args?: Node[]) => Node;
+ property?: (type: string, key: Node, value: Node) => Node;
+ program?: (nodes: Node[]) => Node;
+ booleanLiteral?: (bool: boolean) => Node;
+ Property?: ExpressionObject;
+ NewExpression?: ExpressionObject;
+ CallExpression?: ExpressionObject;
+ VariableDeclarator?: ExpressionObject;
+ Identifier?: ExpressionObject;
+ Literal?: ExpressionObject;
+ ArrayExpression?: ExpressionObject;
+ MemberExpression?: ExpressionObject;
+ FunctionExpression?: ExpressionObject;
+ ObjectExpression?: ExpressionObject;
+ BlockStatement?: ExpressionObject;
+ Program?: ExpressionObject;
filters?: {
VariableDeclarator: {
- requiresModule: Function,
- },
+ requiresModule: Function;
+ };
};
}
-export type valueType = string | number | boolean | any[] | INode | null;
+export type valueType = string | number | boolean | Node | null;
diff --git a/packages/utils/types/Yeoman.ts b/packages/utils/types/Yeoman.ts
index 4c56a771c00..16615324c03 100644
--- a/packages/utils/types/Yeoman.ts
+++ b/packages/utils/types/Yeoman.ts
@@ -1,12 +1,12 @@
-interface IRunEnv extends Object {
+interface RunEnv extends Object {
on?: (event: string, callbackFn: Function) => void;
}
-export interface IYeoman extends Object {
- registerStub?(generator: IGenerator, namespace: string): void;
- run?(target: string, options?: object, done?: Function): IRunEnv;
+export interface Yeoman extends Object {
+ registerStub?(generator: YeoGenerator, namespace: string): void;
+ run?(target: string, options?: object, done?: Function): RunEnv;
}
-export interface IGenerator extends Object {
+export interface YeoGenerator extends Object {
composeWith?: (path: string) => void;
}
diff --git a/packages/utils/types/index.ts b/packages/utils/types/index.ts
index fd94138d988..dba558d3ccf 100644
--- a/packages/utils/types/index.ts
+++ b/packages/utils/types/index.ts
@@ -1,4 +1,4 @@
-interface IError {
- stack?: object;
- message?: string;
+interface Error {
+ stack?: string;
+ message: string;
}
diff --git a/packages/utils/validate-identifier.ts b/packages/utils/validate-identifier.ts
index b3d0b155acf..272b01f364a 100644
--- a/packages/utils/validate-identifier.ts
+++ b/packages/utils/validate-identifier.ts
@@ -8,13 +8,7 @@ function isKeyword(code: string): boolean {
case 2:
return code === "if" || code === "in" || code === "do";
case 3:
- return (
- code === "var" ||
- code === "for" ||
- code === "new" ||
- code === "try" ||
- code === "let"
- );
+ return code === "var" || code === "for" || code === "new" || code === "try" || code === "let";
case 4:
return (
code === "this" ||
@@ -61,9 +55,7 @@ function isKeyword(code: string): boolean {
case 8:
return code === "function" || code === "continue" || code === "debugger";
case 9:
- return (
- code === "protected" || code === "interface" || code === "arguments"
- );
+ return code === "protected" || code === "interface" || code === "arguments";
case 10:
return code === "instanceof" || code === "implements";
default:
@@ -77,19 +69,13 @@ function isKeyword(code: string): boolean {
// are only applied when a character is found to actually have a
// code point above 128.
-/* tslint:disable: max-line-length */
let nonASCIIidentifierStartChars =
-"\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u08a0-\u08b2\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58\u0c59\u0c60\u0c61\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d60\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19c1-\u19c7\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua7ad\ua7b0\ua7b1\ua7f7-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab5f\uab64\uab65\uabc0-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc";
+ "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u08a0-\u08b2\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58\u0c59\u0c60\u0c61\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d60\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19c1-\u19c7\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua7ad\ua7b0\ua7b1\ua7f7-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab5f\uab64\uab65\uabc0-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc";
let nonASCIIidentifierChars =
-"\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08e4-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c03\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0d01-\u0d03\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d82\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19b0-\u19c0\u19c8\u19c9\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf2-\u1cf4\u1cf8\u1cf9\u1dc0-\u1df5\u1dfc-\u1dff\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua620-\ua629\ua66f\ua674-\ua67d\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua880\ua881\ua8b4-\ua8c4\ua8d0-\ua8d9\ua8e0-\ua8f1\ua900-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2d\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f";
-/* tslint:enable: max-line-length */
+ "\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08e4-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c03\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0d01-\u0d03\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d82\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19b0-\u19c0\u19c8\u19c9\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf2-\u1cf4\u1cf8\u1cf9\u1dc0-\u1df5\u1dfc-\u1dff\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua620-\ua629\ua66f\ua674-\ua67d\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua880\ua881\ua8b4-\ua8c4\ua8d0-\ua8d9\ua8e0-\ua8f1\ua900-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2d\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f";
-const nonASCIIidentifierStart: RegExp = new RegExp(
- "[" + nonASCIIidentifierStartChars + "]",
-);
-const nonASCIIidentifier: RegExp = new RegExp(
- "[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]",
-);
+const nonASCIIidentifierStart: RegExp = new RegExp("[" + nonASCIIidentifierStartChars + "]");
+const nonASCIIidentifier: RegExp = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]");
nonASCIIidentifierStartChars = nonASCIIidentifierChars = null;
@@ -425,7 +411,7 @@ const astralIdentifierStartCodes = [
12,
221,
16355,
- 541,
+ 541
];
const astralIdentifierCodes = [
@@ -548,7 +534,7 @@ const astralIdentifierCodes = [
4305,
6,
792618,
- 239,
+ 239
];
// This has a complexity linear to the value of the code. The
@@ -558,10 +544,14 @@ function isInAstralSet(code: number, set: number[]): boolean {
let pos = 0x10000;
for (let i = 0; i < set.length; i += 2) {
pos += set[i];
- if (pos > code) { return false; }
+ if (pos > code) {
+ return false;
+ }
pos += set[i + 1];
- if (pos >= code) { return true; }
+ if (pos >= code) {
+ return true;
+ }
}
}
@@ -569,16 +559,49 @@ function isInAstralSet(code: number, set: number[]): boolean {
function isIdentifierStart(code: string): boolean {
const c: number = code.charCodeAt(0);
- if (c < 65) { return c === 36; }
- if (c < 91) { return true; }
- if (c < 97) { return c === 95; }
- if (c < 123) { return true; }
+ if (c < 65) {
+ return c === 36;
+ }
+ if (c < 91) {
+ return true;
+ }
+ if (c < 97) {
+ return c === 95;
+ }
+ if (c < 123) {
+ return true;
+ }
if (c <= 0xffff) {
return c >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(c));
}
return isInAstralSet(c, astralIdentifierStartCodes);
}
+function validationChar(charCode: number): boolean {
+ if (charCode < 48) {
+ return charCode === 36;
+ }
+ if (charCode < 58) {
+ return true;
+ }
+ if (charCode < 65) {
+ return false;
+ }
+ if (charCode < 91) {
+ return true;
+ }
+ if (charCode < 97) {
+ return charCode === 95;
+ }
+ if (charCode < 123) {
+ return true;
+ }
+ if (charCode <= 0xffff) {
+ return charCode >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(charCode));
+ }
+ return isInAstralSet(charCode, astralIdentifierStartCodes) || isInAstralSet(charCode, astralIdentifierCodes);
+}
+
// Test whether a given character is part of an identifier.
function isIdentifierChar(code: string): boolean {
@@ -595,24 +618,4 @@ function isIdentifierChar(code: string): boolean {
}
}
-function validationChar(charCode: number): boolean {
- if (charCode < 48) { return charCode === 36; }
- if (charCode < 58) { return true; }
- if (charCode < 65) { return false; }
- if (charCode < 91) { return true; }
- if (charCode < 97) { return charCode === 95; }
- if (charCode < 123) { return true; }
- if (charCode <= 0xffff) {
- return charCode >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(charCode));
- }
- return (
- isInAstralSet(charCode, astralIdentifierStartCodes) ||
- isInAstralSet(charCode, astralIdentifierCodes)
- );
-}
-
-export {
- isIdentifierChar,
- isIdentifierStart,
- isKeyword,
-};
+export { isIdentifierChar, isIdentifierStart, isKeyword };
diff --git a/packages/webpack-scaffold/.eslintrc b/packages/webpack-scaffold/.eslintrc
new file mode 100644
index 00000000000..365d9f85d71
--- /dev/null
+++ b/packages/webpack-scaffold/.eslintrc
@@ -0,0 +1,11 @@
+{
+ "root": true,
+ "extends": [
+ "../../.eslintrc.js",
+ "plugin:@typescript-eslint/recommended",
+ "prettier",
+ "prettier/@typescript-eslint"
+ ],
+ "parser": "@typescript-eslint/parser",
+ "plugins": ["@typescript-eslint"]
+}
diff --git a/packages/webpack-scaffold/__tests__/.eslintrc b/packages/webpack-scaffold/__tests__/.eslintrc
new file mode 100644
index 00000000000..5d4340a351d
--- /dev/null
+++ b/packages/webpack-scaffold/__tests__/.eslintrc
@@ -0,0 +1,7 @@
+{
+ "root": true,
+ "extends": ["../.eslintrc"],
+ "rules": {
+ "@typescript-eslint/explicit-function-return-type": ["off"]
+ }
+}
diff --git a/packages/webpack-scaffold/index.ts b/packages/webpack-scaffold/index.ts
index e666071046d..66303f5d989 100755
--- a/packages/webpack-scaffold/index.ts
+++ b/packages/webpack-scaffold/index.ts
@@ -1,23 +1,28 @@
import * as jscodeshift from "jscodeshift";
-export interface IInquirerScaffoldObject {
+export interface InquirerScaffoldObject {
type?: string;
name: string;
message: string;
- choices?: ((answers: Object) => string) | string[];
- default?: string | number | boolean | string[] | number[]
- | ((answers: Object) => (string | number | boolean | string[] | number[]));
- validate?: ((input: string) => boolean | string);
- when?: ((answers: Object) => boolean) | boolean;
+ choices?: ((answers: Record) => string) | string[];
+ default?:
+ | string
+ | number
+ | boolean
+ | string[]
+ | number[]
+ | ((answers: Record) => string | number | boolean | string[] | number[]);
+ validate?: (input: string) => boolean | string;
+ when?: ((answers: Record) => boolean) | boolean;
store?: boolean;
filter?: (name: string) => string;
}
-export interface IInquirerList extends IInquirerScaffoldObject {
+export interface InquirerList extends InquirerScaffoldObject {
choices?: string[];
}
-export interface IInquirerInput extends IInquirerScaffoldObject {
+export interface InquirerInput extends InquirerScaffoldObject {
validate?: (input: string) => string | boolean;
}
@@ -33,9 +38,11 @@ export function createDynamicPromise(arrOrString: string[] | string): string {
if (Array.isArray(arrOrString)) {
return (
"() => new Promise((resolve) => resolve([" +
- arrOrString.map((func: string): string => {
- return "'" + func + "'";
- }) +
+ arrOrString.map(
+ (func: string): string => {
+ return "'" + func + "'";
+ }
+ ) +
"]))"
);
} else {
@@ -67,63 +74,68 @@ export function createRequire(val: string): string {
return `const ${val} = require('${val}');`;
}
-export function List(name: string, message: string, choices: string[]): IInquirerList {
+export function List(name: string, message: string, choices: string[]): InquirerList {
return {
choices,
message,
name,
- type: "list",
+ type: "list"
};
}
-export function RawList(name: string, message: string, choices: string[]): IInquirerList {
+export function RawList(name: string, message: string, choices: string[]): InquirerList {
return {
choices,
message,
name,
- type: "rawlist",
+ type: "rawlist"
};
}
-export function CheckList(name: string, message: string, choices: string[]): IInquirerList {
+export function CheckList(name: string, message: string, choices: string[]): InquirerList {
return {
choices,
message,
name,
- type: "checkbox",
+ type: "checkbox"
};
}
-export function Input(name: string, message: string): IInquirerInput {
+export function Input(name: string, message: string): InquirerInput {
return {
message,
name,
- type: "input",
+ type: "input"
};
}
-export function InputValidate(name: string, message: string, cb?: (input: string) => string | boolean): IInquirerInput {
+export function InputValidate(name: string, message: string, cb?: (input: string) => string | boolean): InquirerInput {
return {
message,
name,
type: "input",
- validate: cb,
+ validate: cb
};
}
-export function Confirm(name: string, message: string, defaultChoice: boolean = true): IInquirerScaffoldObject {
+export function Confirm(name: string, message: string, defaultChoice: boolean = true): InquirerScaffoldObject {
return {
default: defaultChoice,
message,
name,
- type: "confirm",
+ type: "confirm"
};
}
-export function AutoComplete(name: string, message: string, options: object = {}) {
- return Object.assign({
- message,
- name,
- type: "autocomplete",
- }, options);
+// TODO: to understand this type
+// eslint-disable-next-line
+export function AutoComplete(name: string, message: string, options: object = {}): any {
+ return Object.assign(
+ {
+ message,
+ name,
+ type: "autocomplete"
+ },
+ options
+ );
}
diff --git a/packages/webpack-scaffold/package-lock.json b/packages/webpack-scaffold/package-lock.json
index 9ef7540efc7..c7674e406ae 100644
--- a/packages/webpack-scaffold/package-lock.json
+++ b/packages/webpack-scaffold/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "@webpack-cli/webpack-scaffold",
- "version": "0.1.3",
+ "version": "0.1.5",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -1248,7 +1248,7 @@
},
"os-tmpdir": {
"version": "1.0.2",
- "resolved": "http://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+ "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
"integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ="
},
"parse-glob": {
@@ -1439,7 +1439,7 @@
},
"temp": {
"version": "0.8.3",
- "resolved": "http://registry.npmjs.org/temp/-/temp-0.8.3.tgz",
+ "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.3.tgz",
"integrity": "sha1-4Ma8TSa5AxJEEOT+2BEDAU38H1k=",
"requires": {
"os-tmpdir": "^1.0.0",
diff --git a/tsconfig.packages.json b/tsconfig.packages.json
index 87eae9c0e2a..3f4af061bd6 100644
--- a/tsconfig.packages.json
+++ b/tsconfig.packages.json
@@ -1,5 +1,5 @@
{
- "extends": "tsconfig.base.json",
+ "extends": "./tsconfig.base.json",
"compilerOptions": {
"declaration": true
}
diff --git a/tslint.json b/tslint.json
deleted file mode 100644
index ee672ce2d93..00000000000
--- a/tslint.json
+++ /dev/null
@@ -1,25 +0,0 @@
-{
- "defaultSeverity": "error",
- "extends": [
- "tslint:recommended"
- ],
- "jsRules": {},
- "rules": {
- "indent": [
- true,
- "tabs",
- 4
- ],
- "ban-types": [
- false
- ],
- "no-console": [true, "log"]
- },
- "rulesDirectory": [],
- "linterOptions": {
- "exclude": [
- "node_modules/**",
- "packages/*/node_modules/**"
- ]
- }
-}