UNPKG

mwts

Version:

MidwayJS TypeScript Style

247 lines 8.72 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.init = exports.installDefaultTemplate = exports.ESLINT_IGNORE = exports.ESLINT_CONFIG = exports.addDependencies = exports.addScripts = void 0; const cp = require("child_process"); const fs = require("fs"); const inquirer = require("inquirer"); const path = require("path"); const ncp_1 = require("ncp"); const util = require("util"); const util_1 = require("./util"); const chalk = require("chalk"); // eslint-disable-next-line @typescript-eslint/no-var-requires const pkg = require('../../package.json'); const ncpp = util.promisify(ncp_1.ncp); const DEFAULT_PACKAGE_JSON = { name: '', version: '0.0.0', description: '', main: 'dist/src/index.js', types: 'dist/src/index.d.ts', files: ['dist/src'], license: 'Apache-2.0', keywords: [], scripts: { test: 'echo "Error: no test specified" && exit 1' }, }; async function query(message, question, defaultVal, options) { if (options.yes) { return true; } else if (options.no) { return false; } if (message) { options.logger.log(message); } const answers = await inquirer.prompt({ type: 'confirm', name: 'query', message: question, default: defaultVal, }); return answers.query; } async function addScripts(packageJson, options) { let edits = false; const pkgManager = (0, util_1.getPkgManagerCommand)(options.yarn); const scripts = { lint: 'mwts lint', clean: 'mwts clean', build: 'tsc', fix: 'mwts fix', prepare: `${pkgManager} run build`, pretest: `${pkgManager} run build`, posttest: `${pkgManager} run lint`, }; if (!packageJson.scripts) { packageJson.scripts = {}; } for (const script of Object.keys(scripts)) { let install = true; const existing = packageJson.scripts[script]; const target = scripts[script]; if (existing !== target) { if (existing) { const message = `package.json already has a script for ${chalk.bold(script)}:\n` + `-${chalk.red(existing)}\n+${chalk.green(target)}`; install = await query(message, 'Replace', false, options); } if (install) { // eslint-disable-next-line require-atomic-updates packageJson.scripts[script] = scripts[script]; edits = true; } } } return edits; } exports.addScripts = addScripts; async function addDependencies(packageJson, options) { let edits = false; const deps = { mwts: `^${pkg.version}`, typescript: pkg.devDependencies.typescript, '@types/node': pkg.devDependencies['@types/node'], }; if (!packageJson.devDependencies) { packageJson.devDependencies = {}; } for (const dep of Object.keys(deps)) { let install = true; const existing = packageJson.devDependencies[dep]; const target = deps[dep]; if (existing !== target) { if (existing) { const message = `Already have devDependency for ${chalk.bold(dep)}:\n` + `-${chalk.red(existing)}\n+${chalk.green(target)}`; install = await query(message, 'Overwrite', false, options); } if (install) { // eslint-disable-next-line require-atomic-updates packageJson.devDependencies[dep] = deps[dep]; edits = true; } } } return edits; } exports.addDependencies = addDependencies; function formatJson(object) { const json = JSON.stringify(object, null, ' '); return `${json}\n`; } async function writePackageJson(packageJson, options) { options.logger.log('Writing package.json...'); if (!options.dryRun) { await (0, util_1.writeFileAtomicp)('./package.json', formatJson(packageJson)); } const preview = { scripts: packageJson.scripts, devDependencies: packageJson.devDependencies, }; options.logger.dir(preview); } exports.ESLINT_CONFIG = { extends: './node_modules/mwts/', }; exports.ESLINT_IGNORE = 'dist/\n'; async function generateConfigFile(options, filename, contents) { let existing; try { existing = await (0, util_1.readFilep)(filename, 'utf8'); } catch (exc) { const err = (0, util_1.safeError)(exc); if (err.code === 'ENOENT') { /* not found, create it. */ } else { throw new Error(`Unknown error reading ${filename}: ${err.message}`); } } let writeFile = true; if (existing && existing === contents) { options.logger.log(`No edits needed in ${filename}`); return; } else if (existing) { writeFile = await query(`${chalk.bold(filename)} already exists`, 'Overwrite', false, options); } if (writeFile) { options.logger.log(`Writing ${filename}...`); if (!options.dryRun) { await (0, util_1.writeFileAtomicp)(filename, contents); } options.logger.log(contents); } } async function generateESLintConfig(options) { return generateConfigFile(options, './.eslintrc.json', formatJson(exports.ESLINT_CONFIG)); } async function generateESLintIgnore(options) { return generateConfigFile(options, './.eslintignore', exports.ESLINT_IGNORE); } async function generateTsConfig(options) { const config = formatJson({ extends: './node_modules/mwts/tsconfig-midway.json', compilerOptions: { rootDir: '.', outDir: 'dist' }, include: ['src/**/*.ts', 'test/**/*.ts'], }); return generateConfigFile(options, './tsconfig.json', config); } async function generatePrettierConfig(options) { const style = `module.exports = { ...require('mwts/.prettierrc.json') } `; return generateConfigFile(options, './.prettierrc.js', style); } async function installDefaultTemplate(options) { const cwd = process.cwd(); const sourceDirName = path.join(__dirname, '../template'); const targetDirName = path.join(cwd, 'src'); try { fs.mkdirSync(targetDirName); } catch (exc) { const err = (0, util_1.safeError)(exc); if (err.code !== 'EEXIST') { throw err; } // Else, continue and populate files into the existing directory. } // Only install the template if no ts files exist in target directory. const files = fs.readdirSync(targetDirName); const tsFiles = files.filter(file => file.toLowerCase().endsWith('.ts')); if (tsFiles.length !== 0) { options.logger.log('Target src directory already has ts files. ' + 'Template files not installed.'); return false; } await ncpp(sourceDirName, targetDirName); options.logger.log('Default template installed.'); return true; } exports.installDefaultTemplate = installDefaultTemplate; async function init(options) { let generatedPackageJson = false; let packageJson; try { packageJson = (await (0, util_1.readJsonp)('./package.json')); } catch (exc) { const err = (0, util_1.safeError)(exc); if (err.code !== 'ENOENT') { throw new Error(`Unable to open package.json file: ${err.message}`); } const generate = await query(`${chalk.bold('package.json')} does not exist.`, 'Generate', true, options); if (!generate) { options.logger.log('Please run from a directory with your package.json.'); return false; } packageJson = DEFAULT_PACKAGE_JSON; generatedPackageJson = true; } const addedDeps = await addDependencies(packageJson, options); const addedScripts = await addScripts(packageJson, options); if (generatedPackageJson || addedDeps || addedScripts) { await writePackageJson(packageJson, options); } else { options.logger.log('No edits needed in package.json.'); } await generateTsConfig(options); await generateESLintConfig(options); await generateESLintIgnore(options); await generatePrettierConfig(options); await installDefaultTemplate(options); // Run `npm install` after initial setup so `npm run lint` works right away. if (!options.dryRun) { // --ignore-scripts so that compilation doesn't happen because there's no // source files yet. cp.spawnSync((0, util_1.getPkgManagerCommand)(options.yarn), ['install', '--ignore-scripts'], { stdio: 'inherit' }); } return true; } exports.init = init; //# sourceMappingURL=init.js.map