@lorenzo.franzone/tws
Version:
Tailwind 4 Styles Generator
171 lines (170 loc) • 7.35 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.configCommand = configCommand;
const chalk_1 = __importDefault(require("chalk"));
const fs = __importStar(require("fs-extra"));
const promises_1 = require("node:timers/promises");
const path_1 = __importDefault(require("path"));
const prompts_1 = require("@clack/prompts");
const consts_1 = require("../../data/consts");
const logger_1 = require("../../utils/logger");
// Wrapper for prompts that gracefully handle user cancellations
async function safePrompt(promptFn, cancelMessage) {
const result = await promptFn();
if ((0, prompts_1.isCancel)(result)) {
(0, prompts_1.cancel)(cancelMessage);
return null;
}
return result;
}
async function configCommand(options, clearConsole = false) {
if (clearConsole) {
console.clear();
}
// Intro banner
(0, prompts_1.intro)(chalk_1.default.bgBlue.white(` ${consts_1.APP_NAME.toUpperCase()} - Style configuration files `));
// Make sure the configuration directory exists
if (!(await fs.pathExists(consts_1.CONFIG_DIR))) {
(0, logger_1.logError)(`Looks like the "${consts_1.CONFIG_DIR}" folder is missing. Run 'tws init' first.`);
return;
}
let selectedModules = [];
// Automatically select all modules if --all flag is used
if (options.all) {
selectedModules = consts_1.AVAILABLE_STYLES;
}
else {
// Otherwise, check which specific modules were selected via flags
for (const mod of consts_1.AVAILABLE_STYLES) {
if (options[mod])
selectedModules.push(mod);
}
}
// If no modules selected yet, ask the user to choose via multiselect
if (selectedModules.length === 0) {
const result = await safePrompt(() => (0, prompts_1.multiselect)({
message: 'Which modules would you like to configure?',
options: consts_1.AVAILABLE_STYLES.map((mod) => ({
value: mod,
label: mod,
})),
}), 'No styles selected. Configuration was cancelled.');
if (!result)
return;
selectedModules = result;
}
let type = options.type;
// If no type provided, ask the user which type of configuration to use
if (!type) {
const result = await safePrompt(() => (0, prompts_1.select)({
message: 'Choose a configuration type:',
options: [
{ value: 'base', label: 'Base' },
{ value: 'example', label: 'Example' },
],
}), 'No type selected. Configuration was cancelled.');
if (!result)
return;
type = result;
}
// Prepare the file creation plan
const filesToCreate = selectedModules.map((mod) => {
const configFileName = `${mod}.config.json`;
const targetFile = path_1.default.join(consts_1.CONFIG_DIR, configFileName);
const templatePath = path_1.default.resolve(__dirname, '..', '..', 'modules', mod, 'config', `config-${type}.json`);
return { mod, configFileName, targetFile, templatePath };
});
// Check for already existing config files
const alreadyExisting = await Promise.all(filesToCreate.map(async (file) => ({
...file,
exists: await fs.pathExists(file.targetFile),
}))).then((result) => result.filter((file) => file.exists));
let overwriteSelection = [];
// Handle user confirmation for overwriting existing files
if (alreadyExisting.length > 0 && !options.force) {
if (alreadyExisting.length === 1) {
const file = alreadyExisting[0];
const confirmOverwrite = await safePrompt(() => (0, prompts_1.confirm)({
message: `The file "${file.configFileName}" already exists. Do you want to replace it?`,
}), 'No problem. We didn’t overwrite anything.');
if (confirmOverwrite === null)
return;
if (confirmOverwrite) {
overwriteSelection = [file.mod];
}
}
else {
const result = await safePrompt(() => (0, prompts_1.multiselect)({
message: 'Some configuration files already exist. Select which ones to overwrite:',
options: alreadyExisting.map(({ mod, configFileName }) => ({
value: mod,
label: configFileName,
})),
}), 'Overwrite selection cancelled. No files were changed.');
if (!result)
return;
overwriteSelection = result;
}
}
// Start spinner to indicate progress
const s = (0, prompts_1.spinner)();
s.start(`Creating your configuration files...`);
for (const { mod, configFileName, targetFile, templatePath } of filesToCreate) {
const alreadyExists = await fs.pathExists(targetFile);
// Skip file creation unless force is enabled or user selected to overwrite
if (alreadyExists && !options.force && !overwriteSelection.includes(mod)) {
continue;
}
await (0, promises_1.setTimeout)(500); // Optional delay to smooth UX
try {
if (!(await fs.pathExists(templatePath))) {
s.stop(chalk_1.default.green(`Skipped: template not found for "${mod}"`));
continue;
}
await fs.copy(templatePath, targetFile);
s.stop(chalk_1.default.green(`"${configFileName}" has been created.`));
}
catch (err) {
s.stop(chalk_1.default.red(`Failed to create "${configFileName}".`));
console.error(err);
}
}
// Final message after everything is done
(0, prompts_1.outro)(chalk_1.default.blue.bold.underline(`Style configuration complete. You're all set.`));
}