ingeniuscliq-core 0.4.15 → 0.4.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/common/logo/Logo.tsx +1 -1
- package/dist/node_modules/@radix-ui/react-accordion/dist/index.js +3 -3
- package/dist/node_modules/@radix-ui/{react-select/node_modules/@radix-ui/react-popper/node_modules/@radix-ui/react-arrow → react-arrow}/dist/index.js +1 -1
- package/dist/node_modules/@radix-ui/react-avatar/dist/index.js +1 -1
- package/dist/node_modules/@radix-ui/react-checkbox/dist/index.js +2 -2
- package/dist/node_modules/@radix-ui/{react-accordion/node_modules/@radix-ui/react-collapsible → react-collapsible}/dist/index.js +7 -7
- package/dist/node_modules/@radix-ui/{react-select/node_modules/@radix-ui/react-collection → react-collection}/dist/index.js +3 -3
- package/dist/node_modules/@radix-ui/react-dialog/dist/index.js +5 -5
- package/dist/node_modules/@radix-ui/{react-select/node_modules/@radix-ui/react-dismissable-layer → react-dismissable-layer}/dist/index.js +4 -4
- package/dist/node_modules/@radix-ui/react-dropdown-menu/dist/index.js +2 -2
- package/dist/node_modules/@radix-ui/{react-dialog/node_modules/@radix-ui/react-focus-scope → react-focus-scope}/dist/index.js +2 -2
- package/dist/node_modules/@radix-ui/react-label/dist/index.js +1 -1
- package/dist/node_modules/@radix-ui/{react-dropdown-menu/node_modules/@radix-ui/react-menu → react-menu}/dist/index.js +17 -17
- package/dist/node_modules/@radix-ui/react-popover/dist/index.js +6 -6
- package/dist/node_modules/@radix-ui/{react-popover/node_modules/@radix-ui/react-popper → react-popper}/dist/index.js +8 -8
- package/dist/node_modules/@radix-ui/{react-popover/node_modules/@radix-ui/react-portal → react-portal}/dist/index.js +1 -1
- package/dist/node_modules/@radix-ui/{react-popover/node_modules/@radix-ui/react-presence → react-presence}/dist/index.js +2 -2
- package/dist/node_modules/@radix-ui/{react-dropdown-menu/node_modules/@radix-ui/react-primitive → react-primitive}/dist/index.js +1 -1
- package/dist/node_modules/@radix-ui/react-radio-group/dist/index.js +3 -3
- package/dist/node_modules/@radix-ui/{react-radio-group/node_modules/@radix-ui/react-roving-focus → react-roving-focus}/dist/index.js +8 -8
- package/dist/node_modules/@radix-ui/react-select/dist/index.js +7 -7
- package/dist/node_modules/@radix-ui/react-separator/dist/index.js +1 -1
- package/dist/node_modules/@radix-ui/react-slider/dist/index.js +2 -2
- package/dist/node_modules/@radix-ui/react-switch/dist/index.js +1 -1
- package/dist/node_modules/@radix-ui/react-tabs/dist/index.js +3 -3
- package/dist/node_modules/@radix-ui/react-tooltip/dist/index.js +5 -5
- package/dist/node_modules/react-i18next/dist/es/defaults.js +2 -1
- package/package.json +10 -10
- package/src/core/commands/create-core-module.js +288 -0
- package/src/core/commands/create-module.js +288 -0
- package/src/core/commands/create-template.js +169 -0
- package/src/core/commands/rollback-core-module.js +195 -0
- package/src/core/commands/rollback-module.js +208 -0
- package/dist/node_modules/@radix-ui/react-accordion/node_modules/@radix-ui/react-collapsible/node_modules/@radix-ui/react-presence/dist/index.js +0 -130
- package/dist/node_modules/@radix-ui/react-accordion/node_modules/@radix-ui/react-collection/dist/index.js +0 -70
- package/dist/node_modules/@radix-ui/react-accordion/node_modules/@radix-ui/react-primitive/dist/index.js +0 -40
- package/dist/node_modules/@radix-ui/react-avatar/node_modules/@radix-ui/react-primitive/dist/index.js +0 -40
- package/dist/node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-presence/dist/index.js +0 -130
- package/dist/node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-primitive/dist/index.js +0 -40
- package/dist/node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-dismissable-layer/dist/index.js +0 -211
- package/dist/node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-portal/dist/index.js +0 -17
- package/dist/node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-presence/dist/index.js +0 -130
- package/dist/node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-primitive/dist/index.js +0 -43
- package/dist/node_modules/@radix-ui/react-dropdown-menu/node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-collection/dist/index.js +0 -70
- package/dist/node_modules/@radix-ui/react-dropdown-menu/node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-dismissable-layer/dist/index.js +0 -211
- package/dist/node_modules/@radix-ui/react-dropdown-menu/node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-focus-scope/dist/index.js +0 -207
- package/dist/node_modules/@radix-ui/react-dropdown-menu/node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-popper/dist/index.js +0 -283
- package/dist/node_modules/@radix-ui/react-dropdown-menu/node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-popper/node_modules/@radix-ui/react-arrow/dist/index.js +0 -25
- package/dist/node_modules/@radix-ui/react-dropdown-menu/node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-portal/dist/index.js +0 -17
- package/dist/node_modules/@radix-ui/react-dropdown-menu/node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-presence/dist/index.js +0 -130
- package/dist/node_modules/@radix-ui/react-dropdown-menu/node_modules/@radix-ui/react-menu/node_modules/@radix-ui/react-roving-focus/dist/index.js +0 -223
- package/dist/node_modules/@radix-ui/react-label/node_modules/@radix-ui/react-primitive/dist/index.js +0 -40
- package/dist/node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-dismissable-layer/dist/index.js +0 -211
- package/dist/node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-focus-scope/dist/index.js +0 -207
- package/dist/node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-popper/node_modules/@radix-ui/react-arrow/dist/index.js +0 -25
- package/dist/node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-primitive/dist/index.js +0 -43
- package/dist/node_modules/@radix-ui/react-radio-group/node_modules/@radix-ui/react-presence/dist/index.js +0 -130
- package/dist/node_modules/@radix-ui/react-radio-group/node_modules/@radix-ui/react-primitive/dist/index.js +0 -40
- package/dist/node_modules/@radix-ui/react-radio-group/node_modules/@radix-ui/react-roving-focus/node_modules/@radix-ui/react-collection/dist/index.js +0 -70
- package/dist/node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-focus-scope/dist/index.js +0 -207
- package/dist/node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-popper/dist/index.js +0 -283
- package/dist/node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-portal/dist/index.js +0 -17
- package/dist/node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-primitive/dist/index.js +0 -43
- package/dist/node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-visually-hidden/dist/index.js +0 -34
- package/dist/node_modules/@radix-ui/react-separator/node_modules/@radix-ui/react-primitive/dist/index.js +0 -40
- package/dist/node_modules/@radix-ui/react-slider/node_modules/@radix-ui/react-collection/dist/index.js +0 -70
- package/dist/node_modules/@radix-ui/react-slider/node_modules/@radix-ui/react-primitive/dist/index.js +0 -40
- package/dist/node_modules/@radix-ui/react-switch/node_modules/@radix-ui/react-primitive/dist/index.js +0 -40
- package/dist/node_modules/@radix-ui/react-tabs/node_modules/@radix-ui/react-presence/dist/index.js +0 -130
- package/dist/node_modules/@radix-ui/react-tabs/node_modules/@radix-ui/react-primitive/dist/index.js +0 -40
- package/dist/node_modules/@radix-ui/react-tabs/node_modules/@radix-ui/react-roving-focus/dist/index.js +0 -223
- package/dist/node_modules/@radix-ui/react-tabs/node_modules/@radix-ui/react-roving-focus/node_modules/@radix-ui/react-collection/dist/index.js +0 -70
- package/dist/node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-dismissable-layer/dist/index.js +0 -211
- package/dist/node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-popper/dist/index.js +0 -283
- package/dist/node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-popper/node_modules/@radix-ui/react-arrow/dist/index.js +0 -25
- package/dist/node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-presence/dist/index.js +0 -130
- package/dist/node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-primitive/dist/index.js +0 -43
- /package/dist/node_modules/@radix-ui/{react-tooltip/node_modules/@radix-ui/react-visually-hidden → react-visually-hidden}/dist/index.js +0 -0
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { createBaseDir, joinPaths } from './helpers/index.js';
|
|
4
|
+
|
|
5
|
+
import { SUPPORTED_DIRECTORIES } from './common/constants.js'
|
|
6
|
+
import chalk from 'chalk';
|
|
7
|
+
import enquirer from 'enquirer';
|
|
8
|
+
import fs from 'fs';
|
|
9
|
+
import { serviceTemplate } from './templates/service.js';
|
|
10
|
+
import { localeTemplate } from './templates/locale.js';
|
|
11
|
+
import { typeTemplate } from './templates/type.js';
|
|
12
|
+
|
|
13
|
+
const { prompt } = enquirer;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Updates or creates the modules index file
|
|
17
|
+
* @param {string} moduleName The name of the module
|
|
18
|
+
*/
|
|
19
|
+
function updateModulesIndex(moduleName) {
|
|
20
|
+
const modulesDir = createBaseDir('modules', ['core']);
|
|
21
|
+
const indexPath = joinPaths(modulesDir, 'index.ts');
|
|
22
|
+
const importStatement = `import './${moduleName}'`;
|
|
23
|
+
|
|
24
|
+
try {
|
|
25
|
+
let content = '';
|
|
26
|
+
|
|
27
|
+
// If file exists, read its content
|
|
28
|
+
if (fs.existsSync(indexPath)) {
|
|
29
|
+
content = fs.readFileSync(indexPath, 'utf8');
|
|
30
|
+
|
|
31
|
+
// Check if import already exists
|
|
32
|
+
if (!content.includes(importStatement)) {
|
|
33
|
+
// Find the last import statement
|
|
34
|
+
const lines = content.split('\n');
|
|
35
|
+
let lastImportIndex = -1;
|
|
36
|
+
|
|
37
|
+
for (let i = 0; i < lines.length; i++) {
|
|
38
|
+
if (lines[i].startsWith('import ')) {
|
|
39
|
+
lastImportIndex = i;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (lastImportIndex !== -1) {
|
|
44
|
+
// Insert after the last import
|
|
45
|
+
lines.splice(lastImportIndex + 1, 0, importStatement);
|
|
46
|
+
} else {
|
|
47
|
+
// No imports found, add at the beginning
|
|
48
|
+
lines.unshift(importStatement);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
content = lines.join('\n');
|
|
52
|
+
}
|
|
53
|
+
} else {
|
|
54
|
+
// Create new file with initial import
|
|
55
|
+
content = `// Import all modules here\n${importStatement}\n\n// You can add more module imports here as needed`;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
fs.writeFileSync(indexPath, content);
|
|
59
|
+
console.log(chalk.green(`✓ Updated ${chalk.bold('modules/index.ts')} file`));
|
|
60
|
+
} catch (error) {
|
|
61
|
+
console.error(chalk.yellow(`⚠️ Warning: Could not update modules index: ${error.message}`));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Creates a new module with the selected folder structure
|
|
67
|
+
* @param {string} moduleName The name of the module to create
|
|
68
|
+
* @param {string[]} selectedDirectories Array of directories to create (defaults to all)
|
|
69
|
+
*/
|
|
70
|
+
function createModule(moduleName, selectedDirectories = SUPPORTED_DIRECTORIES) {
|
|
71
|
+
if (!moduleName) {
|
|
72
|
+
console.error(chalk.red.bold('❌ Error: Core module name is required'));
|
|
73
|
+
console.log(chalk.yellow('⚠️ Usage: npm run create:core-module <module-name>'));
|
|
74
|
+
process.exit(1);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const baseDir = createBaseDir(moduleName, ['core', 'modules']);
|
|
78
|
+
|
|
79
|
+
// Check if module already exists
|
|
80
|
+
if (fs.existsSync(baseDir)) {
|
|
81
|
+
console.error(chalk.red.bold(`❌ Error: Core module '${moduleName}' already exists`));
|
|
82
|
+
process.exit(1);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
try {
|
|
86
|
+
// Create module base directory
|
|
87
|
+
fs.mkdirSync(baseDir, { recursive: true });
|
|
88
|
+
console.log(chalk.green(`✓ Created core module directory: ${chalk.bold(moduleName)}`));
|
|
89
|
+
|
|
90
|
+
// Create selected subdirectories
|
|
91
|
+
for (const dir of selectedDirectories) {
|
|
92
|
+
const dirPath = joinPaths(baseDir, dir);
|
|
93
|
+
fs.mkdirSync(dirPath, { recursive: true });
|
|
94
|
+
console.log(chalk.green(`✓ Created ${chalk.bold(dir)} directory`));
|
|
95
|
+
|
|
96
|
+
// Create ui and layouts subdirectories inside components
|
|
97
|
+
if (dir === 'components') {
|
|
98
|
+
const componentsSubDirs = ['ui', 'layouts'];
|
|
99
|
+
for (const subDir of componentsSubDirs) {
|
|
100
|
+
const subDirPath = joinPaths(dirPath, subDir);
|
|
101
|
+
fs.mkdirSync(subDirPath, { recursive: true });
|
|
102
|
+
console.log(chalk.green(`✓ Created ${chalk.bold(`components/${subDir}`)} directory`));
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Create locale subdirectory inside components
|
|
107
|
+
if (dir === 'locale') {
|
|
108
|
+
const localeSubDirEn = joinPaths(dirPath, 'en.json');
|
|
109
|
+
fs.writeFileSync(localeSubDirEn, '{}');
|
|
110
|
+
console.log(chalk.green(`✓ Created ${chalk.bold('locale/en.json')} file`));
|
|
111
|
+
const localeSubDirEs = joinPaths(dirPath, 'es.json');
|
|
112
|
+
fs.writeFileSync(localeSubDirEs, '{}');
|
|
113
|
+
console.log(chalk.green(`✓ Created ${chalk.bold('locale/es.json')} file`));
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Create base.ts file inside services directory
|
|
117
|
+
if (dir === 'services') {
|
|
118
|
+
const baseServicePath = joinPaths(dirPath, 'base.ts');
|
|
119
|
+
const baseServiceContent = serviceTemplate(moduleName);
|
|
120
|
+
fs.writeFileSync(baseServicePath, baseServiceContent);
|
|
121
|
+
console.log(chalk.green(`✓ Created ${chalk.bold('services/base.ts')} file`));
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Create base entity file inside types directory
|
|
125
|
+
if(dir === 'types') {
|
|
126
|
+
const typesPath = joinPaths(dirPath, `${moduleName}.ts`);
|
|
127
|
+
const typesContent = typeTemplate(moduleName);
|
|
128
|
+
fs.writeFileSync(typesPath, typesContent);
|
|
129
|
+
console.log(chalk.green(`✓ Created ${chalk.bold(`types/${moduleName}.ts`)} file`));
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Create index.ts file
|
|
134
|
+
const indexPath = joinPaths(baseDir, 'index.ts');
|
|
135
|
+
if (selectedDirectories.includes('locale')) {
|
|
136
|
+
fs.writeFileSync(indexPath, localeTemplate(moduleName));
|
|
137
|
+
// Update modules/index.ts only if locale is selected
|
|
138
|
+
updateModulesIndex(moduleName);
|
|
139
|
+
} else {
|
|
140
|
+
fs.writeFileSync(indexPath, `// ${moduleName} module exports\n`);
|
|
141
|
+
}
|
|
142
|
+
console.log(chalk.green(`✓ Created ${chalk.bold('index.ts')} file`));
|
|
143
|
+
|
|
144
|
+
console.log(chalk.green.bold(`\n✨ Module '${moduleName}' successfully created at core/modules/${moduleName}`));
|
|
145
|
+
} catch (error) {
|
|
146
|
+
console.error(chalk.red.bold(`❌ Error creating module: ${error.message}`));
|
|
147
|
+
process.exit(1);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Prompts the user to select which directories to include
|
|
153
|
+
* @param {string} moduleName The name of the module to create
|
|
154
|
+
*/
|
|
155
|
+
async function promptDirectorySelection(moduleName) {
|
|
156
|
+
try {
|
|
157
|
+
console.log(chalk.cyan.bold('\n=== Feature Selection ===\n'));
|
|
158
|
+
|
|
159
|
+
const response = await prompt({
|
|
160
|
+
type: 'multiselect',
|
|
161
|
+
name: 'directories',
|
|
162
|
+
message: 'Select the directories to include (use space to select, enter to confirm):',
|
|
163
|
+
choices: SUPPORTED_DIRECTORIES.map(dir => ({
|
|
164
|
+
name: dir,
|
|
165
|
+
value: dir,
|
|
166
|
+
message: dir
|
|
167
|
+
})),
|
|
168
|
+
min: 1,
|
|
169
|
+
instructions: false,
|
|
170
|
+
symbols: {
|
|
171
|
+
indicator: {
|
|
172
|
+
on: '◉',
|
|
173
|
+
off: '◯'
|
|
174
|
+
}
|
|
175
|
+
},
|
|
176
|
+
styles: {
|
|
177
|
+
primary: chalk.cyan,
|
|
178
|
+
highlight: chalk.cyan.bold,
|
|
179
|
+
selected: chalk.green.bold
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
if (response.directories && response.directories.length > 0) {
|
|
184
|
+
console.log(chalk.cyan(`\nCreating core module with ${chalk.bold(response.directories.length)} selected features...\n`));
|
|
185
|
+
createModule(moduleName, response.directories);
|
|
186
|
+
} else {
|
|
187
|
+
console.log(chalk.yellow('⚠️ You must select at least one feature. Operation cancelled.'));
|
|
188
|
+
}
|
|
189
|
+
} catch (error) {
|
|
190
|
+
console.log(chalk.yellow('⚠️ Operation cancelled.'));
|
|
191
|
+
throw error;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Displays options and gets user choice using radio buttons
|
|
197
|
+
* @param {string} moduleName The name of the module to create
|
|
198
|
+
*/
|
|
199
|
+
async function promptOptions(moduleName) {
|
|
200
|
+
console.log(chalk.cyan.bold('\n==================================='));
|
|
201
|
+
console.log(chalk.cyan.bold(` Create Core Module: ${chalk.white(moduleName)}`));
|
|
202
|
+
console.log(chalk.cyan.bold('===================================\n'));
|
|
203
|
+
|
|
204
|
+
try {
|
|
205
|
+
const response = await prompt({
|
|
206
|
+
type: 'select',
|
|
207
|
+
name: 'action',
|
|
208
|
+
message: 'Select an option:',
|
|
209
|
+
choices: [
|
|
210
|
+
{ name: 'create_all', message: 'Create core module with all features', value: 'create_all' },
|
|
211
|
+
{ name: 'create_custom', message: 'Select features', value: 'create_custom' },
|
|
212
|
+
{ name: 'exit', message: 'Exit', value: 'exit' }
|
|
213
|
+
],
|
|
214
|
+
styles: {
|
|
215
|
+
primary: chalk.cyan,
|
|
216
|
+
highlight: chalk.cyan.bold,
|
|
217
|
+
selected: chalk.green.bold
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
switch (response.action) {
|
|
222
|
+
case 'create_all':
|
|
223
|
+
console.log(chalk.cyan(`\nCreating core module with all features: ${chalk.bold(moduleName)}...\n`));
|
|
224
|
+
createModule(moduleName);
|
|
225
|
+
break;
|
|
226
|
+
case 'create_custom':
|
|
227
|
+
await promptDirectorySelection(moduleName);
|
|
228
|
+
break;
|
|
229
|
+
default:
|
|
230
|
+
console.log(chalk.yellow('⚠️ Operation cancelled.'));
|
|
231
|
+
break;
|
|
232
|
+
}
|
|
233
|
+
} catch (error) {
|
|
234
|
+
console.log(chalk.yellow('⚠️ Operation cancelled.'));
|
|
235
|
+
throw error;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Prompts the user to enter a module name
|
|
241
|
+
* @returns {Promise<string>} The entered module name
|
|
242
|
+
*/
|
|
243
|
+
async function promptModuleName() {
|
|
244
|
+
console.log(chalk.cyan.bold('\n==================================='));
|
|
245
|
+
console.log(chalk.cyan.bold(' Create Core Module'));
|
|
246
|
+
console.log(chalk.cyan.bold('===================================\n'));
|
|
247
|
+
|
|
248
|
+
try {
|
|
249
|
+
const response = await prompt({
|
|
250
|
+
type: 'input',
|
|
251
|
+
name: 'moduleName',
|
|
252
|
+
message: 'Please enter the name of the core module to create:',
|
|
253
|
+
validate: (input) => {
|
|
254
|
+
if (!input.trim()) {
|
|
255
|
+
return 'Core module name is required';
|
|
256
|
+
}
|
|
257
|
+
const baseDir = createBaseDir(input, ['src', 'core', 'modules']);
|
|
258
|
+
if (fs.existsSync(baseDir)) {
|
|
259
|
+
return `Core module '${input}' already exists`;
|
|
260
|
+
}
|
|
261
|
+
return true;
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
return response.moduleName.trim();
|
|
266
|
+
} catch (error) {
|
|
267
|
+
console.log(chalk.yellow('⚠️ Operation cancelled.'));
|
|
268
|
+
throw error;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// Get module name from command line arguments or prompt
|
|
273
|
+
const moduleNameArg = process.argv[2];
|
|
274
|
+
|
|
275
|
+
async function main() {
|
|
276
|
+
let moduleName = moduleNameArg;
|
|
277
|
+
|
|
278
|
+
if (!moduleName) {
|
|
279
|
+
moduleName = await promptModuleName();
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
promptOptions(moduleName);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
main().catch(error => {
|
|
286
|
+
console.error(chalk.red.bold(`❌ Unexpected error: ${error.message}`));
|
|
287
|
+
process.exit(1);
|
|
288
|
+
});
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { createBaseDir, joinPaths } from './helpers/index.js';
|
|
4
|
+
|
|
5
|
+
import { SUPPORTED_DIRECTORIES } from './common/constants.js';
|
|
6
|
+
import chalk from 'chalk';
|
|
7
|
+
import enquirer from 'enquirer';
|
|
8
|
+
import fs from 'fs';
|
|
9
|
+
import { serviceTemplate } from './templates/service.js';
|
|
10
|
+
import { localeTemplate } from './templates/locale.js';
|
|
11
|
+
import { typeTemplate } from './templates/type.js';
|
|
12
|
+
|
|
13
|
+
const { prompt } = enquirer;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Updates or creates the modules index file
|
|
17
|
+
* @param {string} moduleName The name of the module
|
|
18
|
+
*/
|
|
19
|
+
function updateModulesIndex(moduleName) {
|
|
20
|
+
const modulesDir = createBaseDir('modules', ['src']);
|
|
21
|
+
const indexPath = joinPaths(modulesDir, 'index.ts');
|
|
22
|
+
const importStatement = `import './${moduleName}'`;
|
|
23
|
+
|
|
24
|
+
try {
|
|
25
|
+
let content = '';
|
|
26
|
+
|
|
27
|
+
// If file exists, read its content
|
|
28
|
+
if (fs.existsSync(indexPath)) {
|
|
29
|
+
content = fs.readFileSync(indexPath, 'utf8');
|
|
30
|
+
|
|
31
|
+
// Check if import already exists
|
|
32
|
+
if (!content.includes(importStatement)) {
|
|
33
|
+
// Find the last import statement
|
|
34
|
+
const lines = content.split('\n');
|
|
35
|
+
let lastImportIndex = -1;
|
|
36
|
+
|
|
37
|
+
for (let i = 0; i < lines.length; i++) {
|
|
38
|
+
if (lines[i].startsWith('import ')) {
|
|
39
|
+
lastImportIndex = i;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (lastImportIndex !== -1) {
|
|
44
|
+
// Insert after the last import
|
|
45
|
+
lines.splice(lastImportIndex + 1, 0, importStatement);
|
|
46
|
+
} else {
|
|
47
|
+
// No imports found, add at the beginning
|
|
48
|
+
lines.unshift(importStatement);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
content = lines.join('\n');
|
|
52
|
+
}
|
|
53
|
+
} else {
|
|
54
|
+
// Create new file with initial import
|
|
55
|
+
content = `// Import all modules here\n${importStatement}\n\n// You can add more module imports here as needed`;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
fs.writeFileSync(indexPath, content);
|
|
59
|
+
console.log(chalk.green(`✓ Updated ${chalk.bold('modules/index.ts')} file`));
|
|
60
|
+
} catch (error) {
|
|
61
|
+
console.error(chalk.yellow(`⚠️ Warning: Could not update modules index: ${error.message}`));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Creates a new module with the selected folder structure
|
|
67
|
+
* @param {string} moduleName The name of the module to create
|
|
68
|
+
* @param {string[]} selectedDirectories Array of directories to create (defaults to all)
|
|
69
|
+
*/
|
|
70
|
+
function createModule(moduleName, selectedDirectories = SUPPORTED_DIRECTORIES) {
|
|
71
|
+
if (!moduleName) {
|
|
72
|
+
console.error(chalk.red.bold('❌ Error: Module name is required'));
|
|
73
|
+
console.log(chalk.yellow('⚠️ Usage: npm run create:module <module-name>'));
|
|
74
|
+
process.exit(1);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const baseDir = createBaseDir(moduleName, ['src', 'modules'])
|
|
78
|
+
|
|
79
|
+
// Check if module already exists
|
|
80
|
+
if (fs.existsSync(baseDir)) {
|
|
81
|
+
console.error(chalk.red.bold(`❌ Error: Module '${moduleName}' already exists`));
|
|
82
|
+
process.exit(1);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
try {
|
|
86
|
+
// Create module base directory
|
|
87
|
+
fs.mkdirSync(baseDir, { recursive: true });
|
|
88
|
+
console.log(chalk.green(`✓ Created module directory: ${chalk.bold(moduleName)}`));
|
|
89
|
+
|
|
90
|
+
// Create selected subdirectories
|
|
91
|
+
for (const dir of selectedDirectories) {
|
|
92
|
+
const dirPath = joinPaths(baseDir, dir);
|
|
93
|
+
fs.mkdirSync(dirPath, { recursive: true });
|
|
94
|
+
console.log(chalk.green(`✓ Created ${chalk.bold(dir)} directory`));
|
|
95
|
+
|
|
96
|
+
// Create ui and layouts subdirectories inside components
|
|
97
|
+
if (dir === 'components') {
|
|
98
|
+
const componentsSubDirs = ['ui', 'layouts'];
|
|
99
|
+
for (const subDir of componentsSubDirs) {
|
|
100
|
+
const subDirPath = joinPaths(dirPath, subDir);
|
|
101
|
+
fs.mkdirSync(subDirPath, { recursive: true });
|
|
102
|
+
console.log(chalk.green(`✓ Created ${chalk.bold(`components/${subDir}`)} directory`));
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Create locale subdirectory inside components
|
|
107
|
+
if (dir === 'locale') {
|
|
108
|
+
const localeSubDirEn = joinPaths(dirPath, 'en.json');
|
|
109
|
+
fs.writeFileSync(localeSubDirEn, '{}');
|
|
110
|
+
console.log(chalk.green(`✓ Created ${chalk.bold('locale/en.json')} file`));
|
|
111
|
+
const localeSubDirEs = joinPaths(dirPath, 'es.json');
|
|
112
|
+
fs.writeFileSync(localeSubDirEs, '{}');
|
|
113
|
+
console.log(chalk.green(`✓ Created ${chalk.bold('locale/es.json')} file`));
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Create base.ts file inside services directory
|
|
117
|
+
if (dir === 'services') {
|
|
118
|
+
const baseServicePath = joinPaths(dirPath, 'base.ts');
|
|
119
|
+
const baseServiceContent = serviceTemplate(moduleName);
|
|
120
|
+
fs.writeFileSync(baseServicePath, baseServiceContent);
|
|
121
|
+
console.log(chalk.green(`✓ Created ${chalk.bold('services/base.ts')} file`));
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Create base entity file inside types directory
|
|
125
|
+
if(dir === 'types') {
|
|
126
|
+
const typesPath = joinPaths(dirPath, `${moduleName}.ts`);
|
|
127
|
+
const typesContent = typeTemplate(moduleName);
|
|
128
|
+
fs.writeFileSync(typesPath, typesContent);
|
|
129
|
+
console.log(chalk.green(`✓ Created ${chalk.bold(`types/${moduleName}.ts`)} file`));
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Create index.ts file
|
|
134
|
+
const indexPath = joinPaths(baseDir, 'index.ts');
|
|
135
|
+
if(selectedDirectories.includes('locale')){
|
|
136
|
+
fs.writeFileSync(indexPath, localeTemplate(moduleName));
|
|
137
|
+
// Update modules/index.ts only if locale is selected
|
|
138
|
+
updateModulesIndex(moduleName);
|
|
139
|
+
}else {
|
|
140
|
+
fs.writeFileSync(indexPath, `// ${moduleName} module exports\n`);
|
|
141
|
+
}
|
|
142
|
+
console.log(chalk.green(`✓ Created ${chalk.bold('index.ts')} file`));
|
|
143
|
+
|
|
144
|
+
console.log(chalk.green.bold(`\n✨ Module '${moduleName}' successfully created at src/modules/${moduleName}`));
|
|
145
|
+
} catch (error) {
|
|
146
|
+
console.error(chalk.red.bold(`❌ Error creating module: ${error.message}`));
|
|
147
|
+
process.exit(1);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Prompts the user to select which directories to include
|
|
153
|
+
* @param {string} moduleName The name of the module to create
|
|
154
|
+
*/
|
|
155
|
+
async function promptDirectorySelection(moduleName) {
|
|
156
|
+
try {
|
|
157
|
+
console.log(chalk.cyan.bold('\n=== Feature Selection ===\n'));
|
|
158
|
+
|
|
159
|
+
const response = await prompt({
|
|
160
|
+
type: 'multiselect',
|
|
161
|
+
name: 'directories',
|
|
162
|
+
message: 'Select the directories to include (use space to select, enter to confirm):',
|
|
163
|
+
choices: SUPPORTED_DIRECTORIES.map(dir => ({
|
|
164
|
+
name: dir,
|
|
165
|
+
value: dir,
|
|
166
|
+
message: dir
|
|
167
|
+
})),
|
|
168
|
+
min: 1,
|
|
169
|
+
instructions: false,
|
|
170
|
+
symbols: {
|
|
171
|
+
indicator: {
|
|
172
|
+
on: '◉',
|
|
173
|
+
off: '◯'
|
|
174
|
+
}
|
|
175
|
+
},
|
|
176
|
+
styles: {
|
|
177
|
+
primary: chalk.cyan,
|
|
178
|
+
highlight: chalk.cyan.bold,
|
|
179
|
+
selected: chalk.green.bold
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
if (response.directories && response.directories.length > 0) {
|
|
184
|
+
console.log(chalk.cyan(`\nCreating module with ${chalk.bold(response.directories.length)} selected features...\n`));
|
|
185
|
+
createModule(moduleName, response.directories);
|
|
186
|
+
} else {
|
|
187
|
+
console.log(chalk.yellow('⚠️ You must select at least one feature. Operation cancelled.'));
|
|
188
|
+
}
|
|
189
|
+
} catch (error) {
|
|
190
|
+
console.log(chalk.yellow('⚠️ Operation cancelled.'));
|
|
191
|
+
throw error;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Displays options and gets user choice using radio buttons
|
|
197
|
+
* @param {string} moduleName The name of the module to create
|
|
198
|
+
*/
|
|
199
|
+
async function promptOptions(moduleName) {
|
|
200
|
+
console.log(chalk.cyan.bold('\n==================================='));
|
|
201
|
+
console.log(chalk.cyan.bold(` Create Module: ${chalk.white(moduleName)}`));
|
|
202
|
+
console.log(chalk.cyan.bold('===================================\n'));
|
|
203
|
+
|
|
204
|
+
try {
|
|
205
|
+
const response = await prompt({
|
|
206
|
+
type: 'select',
|
|
207
|
+
name: 'action',
|
|
208
|
+
message: 'Select an option:',
|
|
209
|
+
choices: [
|
|
210
|
+
{ name: 'create_all', message: 'Create module with all features', value: 'create_all' },
|
|
211
|
+
{ name: 'create_custom', message: 'Select features', value: 'create_custom' },
|
|
212
|
+
{ name: 'exit', message: 'Exit', value: 'exit' }
|
|
213
|
+
],
|
|
214
|
+
styles: {
|
|
215
|
+
primary: chalk.cyan,
|
|
216
|
+
highlight: chalk.cyan.bold,
|
|
217
|
+
selected: chalk.green.bold
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
switch (response.action) {
|
|
222
|
+
case 'create_all':
|
|
223
|
+
console.log(chalk.cyan(`\nCreating module with all features: ${chalk.bold(moduleName)}...\n`));
|
|
224
|
+
createModule(moduleName);
|
|
225
|
+
break;
|
|
226
|
+
case 'create_custom':
|
|
227
|
+
await promptDirectorySelection(moduleName);
|
|
228
|
+
break;
|
|
229
|
+
default:
|
|
230
|
+
console.log(chalk.yellow('⚠️ Operation cancelled.'));
|
|
231
|
+
break;
|
|
232
|
+
}
|
|
233
|
+
} catch (error) {
|
|
234
|
+
console.log(chalk.yellow('⚠️ Operation cancelled.'));
|
|
235
|
+
throw error;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Prompts the user to enter a module name
|
|
241
|
+
* @returns {Promise<string>} The entered module name
|
|
242
|
+
*/
|
|
243
|
+
async function promptModuleName() {
|
|
244
|
+
console.log(chalk.cyan.bold('\n==================================='));
|
|
245
|
+
console.log(chalk.cyan.bold(' Create Module'));
|
|
246
|
+
console.log(chalk.cyan.bold('===================================\n'));
|
|
247
|
+
|
|
248
|
+
try {
|
|
249
|
+
const response = await prompt({
|
|
250
|
+
type: 'input',
|
|
251
|
+
name: 'moduleName',
|
|
252
|
+
message: 'Please enter the name of the module to create:',
|
|
253
|
+
validate: (input) => {
|
|
254
|
+
if (!input.trim()) {
|
|
255
|
+
return 'Module name is required';
|
|
256
|
+
}
|
|
257
|
+
const baseDir = createBaseDir(input, ['src', 'modules'])
|
|
258
|
+
if (fs.existsSync(baseDir)) {
|
|
259
|
+
return `Module '${input}' already exists`;
|
|
260
|
+
}
|
|
261
|
+
return true;
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
return response.moduleName.trim();
|
|
266
|
+
} catch (error) {
|
|
267
|
+
console.log(chalk.yellow('⚠️ Operation cancelled.'));
|
|
268
|
+
throw error;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// Get module name from command line arguments or prompt
|
|
273
|
+
const moduleNameArg = process.argv[2];
|
|
274
|
+
|
|
275
|
+
async function main() {
|
|
276
|
+
let moduleName = moduleNameArg;
|
|
277
|
+
|
|
278
|
+
if (!moduleName) {
|
|
279
|
+
moduleName = await promptModuleName();
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
promptOptions(moduleName);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
main().catch(error => {
|
|
286
|
+
console.error(chalk.red.bold(`❌ Unexpected error: ${error.message}`));
|
|
287
|
+
process.exit(1);
|
|
288
|
+
});
|