UNPKG

create-feli

Version:

The npm-initializer for creating a new feli package

270 lines (261 loc) 7.32 kB
#!/usr/bin/env node // src/create-feli-cli.ts import * as prom from "@clack/prompts"; import chalk from "chalk"; // package.json var package_default = { name: "create-feli", version: "1.0.1", description: "The npm-initializer for creating a new feli package", private: false, repository: { type: "git", url: "git+https://github.com/charlyoleg2/feli_mono.git" }, homepage: "https://www.npmjs.com/package/create-feli", author: "charlyoleg", license: "ISC", keywords: [ "front-end only", "locally installed", "web-UI deployment", "feli" ], type: "module", exports: { ".": { types: "./dist/create-feli-api.d.ts", default: "./dist/create-feli-api.js" } }, bin: { "create-feli": "dist/create-feli-cli.js" }, files: [ "dist/create-feli-cli.js", "dist/template/", "!dist/**/*.map", "!dist/**/*.spec.*" ], tsup: { entry: [ "src/create-feli-api.ts", "src/create-feli-ref.ts", "src/create-feli-cli.ts" ], format: "esm", splitting: false, dts: false, sourcemap: false, clean: true }, prettier: { useTabs: true, singleQuote: true, trailingComma: "none", printWidth: 100, plugins: [], overrides: [] }, scripts: { dev: "tsup --watch", build: "tsup", check: "tsc --noEmit", pretty: "prettier --check .", format: "prettier --write .", lint: "eslint .", "test:unit": "vitest", "test:unit:once": "vitest --run", copy_template: "shx cp -r template dist/", cleanCopy_template: "run-s clean:template copy_template", ci: "run-s check build pretty lint test:unit:once cleanCopy_template", run: "dist/create-feli-cli.js", "run:ref": "dist/create-feli-ref.js tmp2", "run:diff": "diff -rq tmp tmp2", "run:check": "run-s run:ref run:diff", cycle: "run-s clean ci run", "clean:template": "shx rm -fr dist/template", "clean:build": "shx rm -fr dist node_modules", "clean:output": "shx rm -fr tmp tmp2", clean: "run-s clean:build clean:output" }, dependencies: { "@clack/prompts": "^0.11.0", chalk: "^5.3.0", handlebars: "^4.7.8" }, devDependencies: { "@eslint/js": "^9.28.0", "@types/eslint__js": "^8.42.3", "@types/node": "^24.0.10", eslint: "^9.30.1", "eslint-config-prettier": "^10.1.5", "npm-run-all2": "^8.0.4", prettier: "^3.6.2", shx: "^0.4.0", tsup: "^8.5.0", typescript: "^5.8.3", "typescript-eslint": "^8.35.1", vitest: "^3.2.4" } }; // src/create-feli-cli.ts import { setTimeout as sleep2 } from "timers/promises"; // src/create-feli-api.ts import { setTimeout as sleep } from "timers/promises"; import { readFile, writeFile, access, mkdir } from "fs/promises"; import { dirname, extname } from "path"; import Handlebars from "handlebars"; // src/create-feli-common.ts function firstLetterCapital(str) { const rStr = str.charAt(0).toUpperCase() + str.slice(1); return rStr; } function underline(str) { const strLen = str.length; const rStr = "=".repeat(strLen); return rStr; } function prefixOutputPath() { let rPreDir = "."; const scriptDir = new URL("", import.meta.url).toString(); const regex = new RegExp("/node_modules/"); if (!regex.test(scriptDir)) { rPreDir = "./tmp"; } return rPreDir; } // src/create-feli-list.ts var template_file_list = [ ".gitignore", ".prettierignore", "README.md", "eslint.config.js", "package.json", "tsconfig.json", "src/{{pkgName}}.test.ts", "src/{{pkgName}}.ts" ]; // src/create-feli-api.ts async function createMissingDir(outPath) { const outDir = dirname(outPath); try { await access(outDir); } catch (err) { if (err) { await mkdir(outDir, { recursive: true }); } } } function isFileBinary(fpath) { const binaryExts = /* @__PURE__ */ new Set([".png"]); const infileExt = extname(fpath.toString()); const rBool = binaryExts.has(infileExt); return rBool; } async function oneFile(onePath, cfg2, preDir2) { try { const onePathIn = Handlebars.compile(onePath)({ pkgName: "webAppAbc-uis" }); const onePathOut = Handlebars.compile(onePath)(cfg2); const fileIn1 = new URL(`./template/${onePathIn}.handlebars`, import.meta.url); const fileIn2 = new URL(`./template/${onePathIn}`, import.meta.url); let fileBin = false; let fileStr2 = ""; const outPath = `${preDir2}/${cfg2.pkgName}/${onePathOut}`; try { await access(fileIn1); try { const fileStr1 = await readFile(fileIn1, { encoding: "utf8" }); const templateStr = Handlebars.compile(fileStr1); fileStr2 = templateStr(cfg2); } catch (err) { console.log(`err392: error while processing ${fileIn1.toString()}`); console.log(err); } } catch (err) { if (err) { if (isFileBinary(fileIn2)) { fileBin = true; const fileBuffer2 = await readFile(fileIn2); await createMissingDir(outPath); await writeFile(outPath, fileBuffer2); } else { fileStr2 = await readFile(fileIn2, { encoding: "utf8" }); } } } if (!fileBin) { await createMissingDir(outPath); await writeFile(outPath, fileStr2); } } catch (err) { console.log(`err213: error while generating file ${onePath}`); console.error(err); throw `err214: error with path ${onePath}`; } } async function generate_boirlerplate(cfg12, preDir2) { console.log(`Boilerplate with: package name : ${cfg12.pkgName}`); const cfg2 = { pkgName: cfg12.pkgName, PkgName: firstLetterCapital(cfg12.pkgName), PkgNameUnderline: underline(cfg12.pkgName) }; for (const fpath of template_file_list) { await oneFile(fpath, cfg2, preDir2); } console.log(`generate ${template_file_list.length} files in ${preDir2}/${cfg12.pkgName}/`); await sleep(100); const rResp = { vim: `vim ${cfg12.pkgName}/package.json` }; return rResp; } // src/create-feli-cli.ts var firstMsg = `Create a new ${chalk.italic("feli-package")} with ${chalk.italic(package_default.name)} version ${chalk.italic(package_default.version)}`; console.log(firstMsg); var pkgNameInit = process.argv[2] || "webAppAbc-uis"; var argN = process.argv.length - 2; if (argN > 1) { console.log(`warn376: ${argN} arguments provided but only one supported!`); } prom.intro(chalk.inverse(" Your new feli-package ")); var pCfg = await prom.group( { pkgName: () => prom.text({ message: "Name of the package?", initialValue: `${pkgNameInit}` //placeholder: `${pkgNameInit}` }) }, { onCancel: () => { prom.cancel("Operation aborted!"); process.exit(0); } } ); prom.outro(`Your package ${pCfg.pkgName} will be boilerplated!`); var cfg1 = { pkgName: pCfg.pkgName }; var preDir = prefixOutputPath(); var resp = await generate_boirlerplate(cfg1, preDir); await sleep2(100); function styl(str) { const rStr = chalk.bold.cyan(str); return rStr; } var lastMsg = ` Next steps: 1: ${styl(`# adapt the path of copy-from`)} ${resp.vim} 2: ${styl(`# integrate ${pCfg.pkgName} in the mono-repo scripts`)} vim ../package.json 3: ${styl(`# install the dependencies of ${pCfg.pkgName}`)} npm install `; console.log(lastMsg);