mwts
Version:
MidwayJS TypeScript Style
247 lines • 8.72 kB
JavaScript
;
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