diff --git a/lib/cli.js b/lib/cli.js index bab98ea5..cac7a190 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -5,7 +5,7 @@ module.exports = function cli() { // eslint-disable-next-line no-unused-expressions yargs .usage("$0 ") - .command("init", init.desc, {}, init) + .command("init", init.desc, {}, () => init()) .demandCommand(1) .strict() .alias("help", "h") diff --git a/lib/init.js b/lib/init.js index 685a36d0..7e41a437 100644 --- a/lib/init.js +++ b/lib/init.js @@ -9,20 +9,45 @@ const write = promisify(fs.writeFile); const read = promisify(fs.readFile); const mkdir = promisify(fs.mkdir); +/** + * @param {string} elem + * @param {...string} elems + */ const packagePath = (elem, ...elems) => path.join(...[__dirname, "..", elem, ...elems]); +/** @typedef {(msg: string) => boolean} Logger */ + +/** + * @param {string} baseDir + * @param {Logger} logger + */ // eslint-disable-next-line max-lines-per-function const initCommand = (baseDir, logger) => { + /** + * @param {string} elem + * @param {...string} elems + */ const currentPath = (elem, ...elems) => path.join(...[baseDir, elem, ...elems]); + /** + * @param {string} fileName + */ const readFile = (fileName) => read(currentPath(fileName), "utf8"); + /** + * @param {string} src + * @param {string} dest + */ const copyFile = async (src, dest) => { await mkdir(path.resolve(dest, ".."), { recursive: true }); await copy(src, dest); logger(`=> \`${path.relative(baseDir, dest)}\` was updated`); }; + /** + * @param {string} fileName + * @param {string} fileContent + */ const writeFile = async (fileName, fileContent) => { const file = currentPath(fileName); await write(file, `${fileContent}\n`); @@ -47,23 +72,31 @@ const initCommand = (baseDir, logger) => { Object.keys(originalPackage.scripts) .filter((key) => !(key === "test" || key.startsWith("test:"))) .forEach((key) => { + // @ts-ignore scripts[key] = originalPackage.scripts[key]; }); - // update other keys - const keys = ["husky", "lint-staged", "standard-version", "remarkConfig"]; - keys.forEach((key) => { + /** + * @param {"husky" | "lint-staged" | "standard-version" | "remarkConfig"} key + */ + const updateOtherKey = (key) => { if (!(key in packageInfo)) { packageInfo[key] = {}; } Object.assign(packageInfo[key], originalPackage[key]); - }); + }; + updateOtherKey("husky"); + updateOtherKey("lint-staged"); + updateOtherKey("standard-version"); + updateOtherKey("remarkConfig"); + packageInfo.commitlint = { extends: ["@commitlint/config-conventional"], rules: { "body-max-line-length": [1, "always", 100], }, }; + packageInfo.eslintConfig = { root: true, extends: ["ybiquitous"], @@ -72,14 +105,22 @@ const initCommand = (baseDir, logger) => { await writeFile("package.json", JSON.stringify(packageInfo, null, 2)); }, + /** + * @param {string} name + * @param {...string} names + */ async writePackageFile(name, ...names) { await copyFile(packagePath(name, ...names), currentPath(name, ...names)); }, }; }; +/** @type {Logger} */ const defaultLogger = (msg) => process.stdout.write(`${msg}${EOL}`); +/** + * @param {{ cwd?: string, logger?: Logger }} params + */ module.exports = async function init({ cwd = process.cwd(), logger = defaultLogger } = {}) { const cmd = initCommand(cwd, logger); diff --git a/package-lock.json b/package-lock.json index 6ae9d034..aae7dedc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -836,6 +836,12 @@ "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-aaI6OtKcrwCX8G7aWbNh7i8GOfY=" }, + "@types/node": { + "version": "14.0.27", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.27.tgz", + "integrity": "sha512-kVrqXhbclHNHGu9ztnAwSncIgJv/FaxmzXJvGXNdcCpV1b8u1/Mi6z6m0vwy0LzKeXFTPLH0NzwmoJ3fNCIq0g==", + "dev": true + }, "@types/normalize-package-data": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", @@ -851,6 +857,21 @@ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.2.tgz", "integrity": "sha512-iHI60IbyfQilNubmxsq4zqSjdynlmc2Q/QvH9kjzg9+CCYVVzq1O6tc7VBzSygIwnmOt07w80IG6HDQvjv3Liw==" }, + "@types/yargs": { + "version": "15.0.5", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.5.tgz", + "integrity": "sha512-Dk/IDOPtOgubt/IaevIUbTgV7doaKkoorvOyYM2CMwuDyP89bekI7H4xLIwunNYiK9jhCkmc6pUrJk3cj2AB9w==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "@types/yargs-parser": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-15.0.0.tgz", + "integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==", + "dev": true + }, "JSONStream": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", @@ -8920,6 +8941,12 @@ "is-typedarray": "^1.0.0" } }, + "typescript": { + "version": "3.9.7", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.7.tgz", + "integrity": "sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw==", + "dev": true + }, "uglify-js": { "version": "3.10.0", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.10.0.tgz", diff --git a/package.json b/package.json index 4e6cff23..5aa9eafb 100644 --- a/package.json +++ b/package.json @@ -42,11 +42,14 @@ "yargs": "^15.4.1" }, "devDependencies": { + "@types/node": "^14.0.27", + "@types/yargs": "^15.0.5", "eslint-config-ybiquitous": "^11.0.0", "fs-extra": "^9.0.1", "nodemon": "^2.0.4", "nyc": "^15.1.0", - "tape": "^5.0.1" + "tape": "^5.0.1", + "typescript": "^3.9.7" }, "scripts": { "test": "nyc --check-coverage --lines 100 --branches 90 tape \"test/**/*.test.js\"", @@ -56,6 +59,7 @@ "lint:js:fix": "npm run lint:js -- --fix", "lint:md": "remark . --frail", "lint:md:fix": "remark . --output", + "lint:types": "tsc --noEmit", "lint": "npm-run-all --print-label --parallel lint:*", "prettier": "prettier --ignore-path .gitignore .", "prettier:check": "npm run prettier -- --check", diff --git a/test/fixtures/package-empty_expected.json b/test/fixtures/package-empty_expected.json index 1cb23f95..070b497a 100644 --- a/test/fixtures/package-empty_expected.json +++ b/test/fixtures/package-empty_expected.json @@ -7,6 +7,7 @@ "lint:js:fix": "npm run lint:js -- --fix", "lint:md": "remark . --frail", "lint:md:fix": "remark . --output", + "lint:types": "tsc --noEmit", "lint": "npm-run-all --print-label --parallel lint:*", "prettier": "prettier --ignore-path .gitignore .", "prettier:check": "npm run prettier -- --check", diff --git a/test/fixtures/package-normal_expected.json b/test/fixtures/package-normal_expected.json index c1f02a97..942aa7d6 100644 --- a/test/fixtures/package-normal_expected.json +++ b/test/fixtures/package-normal_expected.json @@ -7,6 +7,7 @@ "lint:js:fix": "npm run lint:js -- --fix", "lint:md": "remark . --frail", "lint:md:fix": "remark . --output", + "lint:types": "tsc --noEmit", "lint": "npm-run-all --print-label --parallel lint:*", "prettier": "prettier --ignore-path .gitignore .", "prettier:check": "npm run prettier -- --check", diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000..55db7b51 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "allowJs": true, + "checkJs": true, + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true + }, + "include": ["lib"] +}