diff --git a/src/Extensions/FileGenerator/generateAbility.js b/src/Extensions/FileGenerator/generateAbility.js new file mode 100644 index 0000000..b29ca13 --- /dev/null +++ b/src/Extensions/FileGenerator/generateAbility.js @@ -0,0 +1,84 @@ +const fs = require("fs"); +const path = require("path"); + +// File path where the abilities are stored +const ABILITIES_FILE = path.join(__dirname, "./src/utils/hasAbilityFn.ts"); + +// Function to normalize the input name to UPPER_SNAKE_CASE (e.g., test_moaz => TEST_MOAZ, TestMoaz => TEST_MOAZ) +const normalizeToUpperSnakeCase = (input) => { + return input + .replace(/([a-z])([A-Z])/g, "$1_$2") // camelCase to snake_case + .replace(/[_\s]+/g, "_") // normalize multiple underscores or spaces + .toUpperCase(); // Convert to uppercase +}; + +// Function to capitalize the first letter of a word +const capitalizeFirstLetter = (word) => word.charAt(0).toUpperCase() + word.slice(1); + +// Take the name dynamically from the terminal +const nameInput = process.argv[2]; + +if (!nameInput) { + console.error("Please provide a name as an argument."); + process.exit(1); +} + +// Normalize input name (handle camelCase, snake_case, PascalCase) +const normalizedInput = normalizeToUpperSnakeCase(nameInput); + +// Generate ability functions for the given name +const generateAbilityFunctions = (name) => { + const capitalized = capitalizeFirstLetter(name.toLowerCase()); + return ` +export const canAdd${capitalized} = hasAbility( + ABILITIES_ENUM.${name}, + ABILITIES_VALUES_ENUM.STORE, +); +export const canEdit${capitalized} = hasAbility( + ABILITIES_ENUM.${name}, + ABILITIES_VALUES_ENUM.UPDATE, +); +export const canDelete${capitalized} = hasAbility( + ABILITIES_ENUM.${name}, + ABILITIES_VALUES_ENUM.DELETE, +); +export const canShow${capitalized} = hasAbility( + ABILITIES_ENUM.${name}, + ABILITIES_VALUES_ENUM.SHOW, +); +export const canIndex${capitalized} = hasAbility( + ABILITIES_ENUM.${name}, + ABILITIES_VALUES_ENUM.INDEX, +); +`.trim(); +}; + +const updateAbilitiesFile = () => { + if (!fs.existsSync(ABILITIES_FILE)) { + console.error(`Error: File ${ABILITIES_FILE} does not exist.`); + return; + } + + // Read the existing content of the file + const fileContent = fs.readFileSync(ABILITIES_FILE, "utf-8"); + + // Check for duplicates + const alreadyExists = fileContent.includes(`canAdd${capitalizeFirstLetter(normalizedInput)}`); + if (alreadyExists) { + console.log(`Abilities for "${normalizedInput}" already exist. No changes made.`); + return; + } + + // Generate new abilities + const newAbilities = generateAbilityFunctions(normalizedInput); + + // Append the new abilities at the end of the file + const updatedContent = `${fileContent.trim()}\n\n${newAbilities}\n`; + + // Write the updated content back to the file + fs.writeFileSync(ABILITIES_FILE, updatedContent, "utf-8"); + console.log(`Abilities for "${normalizedInput}" added successfully to hasAbilityFn.ts.`); +}; + +// Run the update +updateAbilitiesFile(); diff --git a/src/Extensions/FileGenerator/generateDashboard.js b/src/Extensions/FileGenerator/generateDashboard.js index 8a86060..600cb88 100644 --- a/src/Extensions/FileGenerator/generateDashboard.js +++ b/src/Extensions/FileGenerator/generateDashboard.js @@ -17,7 +17,9 @@ const commands = [ `node src/Extensions/FileGenerator/generateType.js ${fileName}`, `node src/Extensions/FileGenerator/generateParamsEnum.js ${fileName}`, `node src/Extensions/FileGenerator/generateRoute.js ${fileName}`, - `node src/Extensions/FileGenerator/generateModelEnum.js ${fileName}` + `node src/Extensions/FileGenerator/generateModelEnum.js ${fileName}`, + `node src/Extensions/FileGenerator/generateAbility.js ${fileName}` + ]; // Execute each command sequentially diff --git a/src/Extensions/FileGenerator/generateModelEnum.js b/src/Extensions/FileGenerator/generateModelEnum.js index ed92765..eeb9b98 100644 --- a/src/Extensions/FileGenerator/generateModelEnum.js +++ b/src/Extensions/FileGenerator/generateModelEnum.js @@ -1,53 +1,73 @@ const fs = require("fs"); const path = require("path"); -const MODEL_ENUM_FILE = "./src/enums/Model.ts"; // Path to the ModalEnum file +// Path to the ModalEnum file +const MODEL_ENUM_FILE = "./src/enums/Model.ts"; -const newEnums = [ - { key: "TEST_EDIT", value: "TEST.edit" }, - { key: "TEST_ADD", value: "TEST.add" }, - { key: "TEST_DELETE", value: "TEST.delete" }, -]; +// Function to convert input to UPPER_SNAKE_CASE +const toUpperSnakeCase = (input) => { + return input + .replace(/([a-z])([A-Z])/g, "$1_$2") // Convert camelCase to snake_case + .replace(/[_\s]+/g, "_") // Normalize underscores or spaces + .toUpperCase(); // Convert to uppercase +}; -const enumName = "ModalEnum"; // Update this to match your enum name +// Take the name dynamically from the terminal +const nameInput = process.argv[2]; -const generateEnumEntries = (enums) => - enums.map(({ key, value }) => ` ${key} = "${value}",`).join("\n"); +if (!nameInput) { + console.error("Please provide a name as an argument."); + process.exit(1); +} +// Generate the enum entries for the given name +const generateEnumEntries = (name) => { + const baseName = toUpperSnakeCase(name); + return [ + ` ${baseName}_EDIT = "${baseName.toLowerCase()}.edit",`, + ` ${baseName}_ADD = "${baseName.toLowerCase()}.add",`, + ` ${baseName}_DELETE = "${baseName.toLowerCase()}.delete",` + ].join("\n"); +}; + +// Update the ModalEnum file const updateModelEnumFile = () => { if (!fs.existsSync(MODEL_ENUM_FILE)) { console.error(`Error: File ${MODEL_ENUM_FILE} does not exist.`); return; } + // Read the existing content of the file const fileContent = fs.readFileSync(MODEL_ENUM_FILE, "utf-8"); - const existingEnums = new Set( - Array.from(fileContent.matchAll(/(\w+)\s*=\s*"([\w.]+)"/g), (match) => - match[1].toLowerCase() - ) + // Generate the new entries for the given name + const newEntries = generateEnumEntries(nameInput); + + // Check if any of the new keys already exist in the file + const existingKeys = Array.from( + fileContent.matchAll(/(\w+)\s*=\s*".+?"/g), + (match) => match[1] + ); + const baseName = toUpperSnakeCase(nameInput); + + const duplicateKeys = existingKeys.filter((key) => + [`${baseName}_EDIT`, `${baseName}_ADD`, `${baseName}_DELETE`].includes(key) ); - const uniqueEnums = newEnums.filter( - ({ key }) => !existingEnums.has(key.toLowerCase()) - ); - - if (uniqueEnums.length === 0) { - console.log("No new enums to add. All enums already exist."); + if (duplicateKeys.length > 0) { + console.log(`The keys ${duplicateKeys.join(", ")} already exist. No changes made.`); return; } - const newEnumEntries = generateEnumEntries(uniqueEnums); - + // Inject the new entries before the closing brace of the enum const updatedContent = fileContent.replace( - new RegExp(`export\\s+enum\\s+${enumName}\\s*{([\\s\\S]*?)}`), - (match, existingContent) => { - return `export enum ${enumName} {\n${existingContent.trim()}\n\n${newEnumEntries}\n}`; - } + /(export enum ModalEnum {\n)/, + `$1${newEntries}\n` ); + // Write the updated content back to the file fs.writeFileSync(MODEL_ENUM_FILE, updatedContent, "utf-8"); - console.log("ModalEnum file updated successfully!"); + console.log(`Enum entries for "${nameInput}" added successfully to ModalEnum.`); }; updateModelEnumFile();