comfytype
Version:
Comfiest TypeScript Style Boilerplate
186 lines (178 loc) • 6.21 kB
JavaScript
#!/usr/bin/env node
import meow from "meow";
import * as fs from "fs";
import { execa } from "execa";
export var ComfyTypeCommands;
(function (ComfyTypeCommands) {
ComfyTypeCommands["None"] = "";
ComfyTypeCommands["Init"] = "init";
})(ComfyTypeCommands || (ComfyTypeCommands = {}));
;
const cli = meow(`
Usage $ comfytype <command> [options]
Commands
init Configures project for TypeScript with the comfiest settings
Options
--help Prints this help message
Examples
$ comfytype init
`, {
importMeta: import.meta,
flags: {
help: { type: "boolean" },
},
});
const comfyPackage = cli.pkg;
function addScripts(packageJson) {
console.info("Adding package.json script commands...");
// Ensure a scripts section
if (!packageJson.scripts) {
packageJson.scripts = {};
}
packageJson.scripts["start"] = "npm run build && node build/index.js";
packageJson.scripts["build"] = "tsc";
packageJson.scripts["clean"] = "rimraf ./build/";
packageJson.scripts["test"] = "jest";
packageJson.scripts["lint"] = "eslint . --ext .js,.ts";
}
function addDependencies(packageJson) {
console.info("Adding package.json dependencies...");
// Ensure a scripts section
if (!packageJson.devDependencies) {
packageJson.devDependencies = {};
}
if (comfyPackage?.devDependencies) {
packageJson.devDependencies["@types/jest"] = comfyPackage.devDependencies["@types/jest"];
packageJson.devDependencies["@typescript-eslint/eslint-plugin"] = comfyPackage.devDependencies["@typescript-eslint/eslint-plugin"];
packageJson.devDependencies["@typescript-eslint/parser"] = comfyPackage.devDependencies["@typescript-eslint/parser"];
packageJson.devDependencies["eslint"] = comfyPackage.devDependencies["eslint"];
packageJson.devDependencies["eslint-config-comfycase"] = comfyPackage.devDependencies["eslint-config-comfycase"];
packageJson.devDependencies["jest"] = comfyPackage.devDependencies["jest"];
packageJson.devDependencies["rimraf"] = comfyPackage.devDependencies["rimraf"];
packageJson.devDependencies["typescript"] = comfyPackage.devDependencies["typescript"];
}
}
async function saveOrUpdatePackageJson() {
console.info("Configuring package.json...");
if (!fs.existsSync("package.json")) {
console.info("package.json does not exist. Creating one in the directory...");
// run npm init for the user
const { stdout } = await execa("npm", ["init", "-y"]);
console.log(stdout);
}
const packageJson = JSON.parse(fs.readFileSync("package.json").toString());
addScripts(packageJson);
addDependencies(packageJson);
fs.writeFileSync("package.json", JSON.stringify(packageJson, null, " ") + "\n");
}
function saveTsconfigJson() {
console.info("Creating tsconfig.json...");
const tsconfigJson = {
"compilerOptions": {
"outDir": "./build",
"sourceMap": true,
"declaration": true,
"strict": true,
"target": "ES6",
"lib": ["ES6", "DOM"],
"module": "CommonJS",
"allowJs": true,
"moduleResolution": "node",
"esModuleInterop": true,
"resolveJsonModule": true,
"allowSyntheticDefaultImports": true,
"experimentalDecorators": true,
},
"include": [
"./src/**/*",
],
"exclude": [
"node_modules",
],
};
fs.writeFileSync("tsconfig.json", JSON.stringify(tsconfigJson, null, "\t") + "\n");
}
function createEslintConfig() {
console.info("Creating eslint.config.js..");
const eslintConfig = `import typescriptEslint from "@typescript-eslint/eslint-plugin";
import globals from "globals";
import tsParser from "@typescript-eslint/parser";
import path from "node:path";
import { fileURLToPath } from "node:url";
import js from "@eslint/js";
import { FlatCompat } from "@eslint/eslintrc";
const __filename = fileURLToPath( import.meta.url );
const __dirname = path.dirname( __filename );
const compat = new FlatCompat( {
baseDirectory: __dirname,
recommendedConfig: js.configs.recommended,
allConfig: js.configs.all,
} );
export default [ ...compat.extends( "comfycase" ), {
ignores: [ "build/*" ],
}, {
files: [ "**/**.{,c,m}{js,ts}" ],
plugins: {
"@typescript-eslint": typescriptEslint,
},
languageOptions: {
globals: {
...globals.node,
...globals.browser,
...globals.commonjs,
...globals.es2021,
},
parser: tsParser,
ecmaVersion: "latest",
sourceType: "module",
},
rules: {
"no-unused-vars": "off",
"@typescript-eslint/no-unused-vars": [ "warn" ],
},
} ];
`;
fs.writeFileSync("eslint.config.js", eslintConfig);
}
function saveEditorConfig() {
console.info("Saving .editorconfig...");
const editorConfig = `root = true
[*.ts]
indent_style = tab
indent_size = 4
charset = utf-8
end_of_line = lf
insert_final_newline = true
`;
fs.writeFileSync(".editorconfig", editorConfig);
}
function setupFolderStructure() {
if (!fs.existsSync("./src")) {
console.info("/src folder does not exist. Creating project folder structure...");
fs.mkdirSync("./src");
fs.writeFileSync("./src/index.ts", `console.log( "Hello Comfy World!" );`);
}
}
switch (cli.input[0] || ComfyTypeCommands.None) {
case ComfyTypeCommands.None:
case ComfyTypeCommands.Init:
{
try {
console.info("Configuring TypeScript project in this directory...");
await saveOrUpdatePackageJson();
saveTsconfigJson();
createEslintConfig();
saveEditorConfig();
setupFolderStructure();
console.info("Complete! 'npm install' and then 'npm start' to build and run");
}
catch (error) {
console.error(error);
}
}
break;
default:
cli.showHelp();
break;
}
//# sourceMappingURL=index.js.map