@truenorthit/d365-webresources-setup
Version:
Scaffolds a new WebResources project for D365.
140 lines (118 loc) • 5.33 kB
JavaScript
#!/usr/bin/env node
const fs = require("fs");
const path = require("path");
const { execSync } = require("child_process");
const inquirerPkg = require("inquirer");
const inquirer = inquirerPkg.prompt ? inquirerPkg : inquirerPkg.default;
// ─── Block-Logo in Color ───────────────────────
const DARK_BLUE = "\x1b[38;5;24m"; // dark blue
const RESET = "\x1b[0m";
function printLogo() {
const raw = [
"████████████████",
"█ █ ██████████ ██ ██ ████████ ██████████",
"████████████████ ██ ███ ██ ██ ██",
"█ ██ █ ██ ██████ ██ ██ ██████ ██ █ ██ ██████ ██████ ██ ██ ██ ██",
"████████████████ ██ ██ ██ ██ ██ ██ ██ █ ██ ██ ██ ██ ████ ██ ██ ██",
"█ ██ █ ██ ██ ██ ██ ██████ ██ █ ██ ██ ██ ██ ██ ██████ ██ ██",
"████████████████ ██ ██ ██ ██ ██ ██ ███ ██ ██ ██ ██ ██ ██ ██ ██",
"█ ██ █ ██ ██ ██████ ██████ ██ ██ ██████ ██ █████ ██ ██ ████████ ██",
"████████████████",
];
for (const line of raw) {
let out = "";
for (const ch of line) {
if (ch === "█") out += DARK_BLUE + ch;
else if (ch === " ") out += ch;
else out += ch;
}
console.log(out + RESET);
}
console.log(); // extra newline
}
// ────────────────────────────────────────────────
async function main() {
printLogo();
// 1) Ask for folder name
const { folderName } = await inquirer.prompt([
{
type: "input",
name: "folderName",
message: "Enter target folder name (leave empty for current directory):",
default: "",
},
]);
const { proceed } = await inquirer.prompt([
{
type: "confirm",
name: "proceed",
message: `Scaffold tn_webresources project in ${folderName}?`,
default: true,
},
]);
if (!proceed) {
console.log("Aborting.");
process.exit(0);
}
// Determine and prepare target directory
const cwd = process.cwd();
const targetDir =
folderName.trim() === "" ? cwd : path.resolve(cwd, folderName.trim());
if (targetDir !== cwd) {
if (!fs.existsSync(targetDir)) {
fs.mkdirSync(targetDir, { recursive: true });
console.log(`✔️ Created folder: ${targetDir}`);
}
process.chdir(targetDir);
}
// 2) Check if directory is empty
const entries = fs.readdirSync(process.cwd()).filter((n) => n !== ".git");
if (entries.length > 0) {
console.error("❌ Error: this folder is not empty.");
console.error("Contents:", entries.join(", "));
process.exit(1);
}
// 3) Copy templates
const templateDir = path.join(__dirname, "templates");
if (!fs.existsSync(templateDir)) {
console.error(`Template directory not found: ${templateDir}`);
process.exit(1);
}
// 4) List all the options from the templates dir
const templateOptions = fs.readdirSync(templateDir).filter((f) => {
return fs.statSync(path.join(templateDir, f)).isDirectory();
});
if (templateOptions.length === 0) {
console.error("❌ No templates found in the templates directory.");
process.exit(1);
}
// 5) Ask user to select a template
const { template } = await inquirer.prompt([
{
type: "list",
name: "template",
message: "Select a template to scaffold:",
choices: templateOptions,
default: "Vite + Vitest",
},
]);
console.log(`\n🚀 Scaffolding project with template: ${template}...`);
// Copy the contents of the selected template directory
const selectedTemplateDir = path.join(templateDir, template);
if (!fs.existsSync(selectedTemplateDir)) {
console.error(`Selected template directory not found: ${selectedTemplateDir}`);
process.exit(1);
}
fs.cpSync(selectedTemplateDir, process.cwd(), { recursive: true, force: true });
console.log(`✔️ Copied template: ${template}`);
// 4) Install devDependencies
console.log("📦 Installing Dependencies (this may take a moment)…");
execSync("npm install", { stdio: "inherit" });
console.log("\n🎉 Project scaffolded successfully!");
}
if (require.main === module) {
main().catch((err) => {
console.error("Unexpected error:", err);
process.exit(1);
});
}