slicejs-cli 2.8.6 → 2.9.1
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/README.md +347 -315
- package/client.js +526 -539
- package/commands/Print.js +167 -167
- package/commands/Validations.js +103 -103
- package/commands/build/build.js +40 -0
- package/commands/buildProduction/buildProduction.js +45 -10
- package/commands/bundle/bundle.js +235 -231
- package/commands/createComponent/VisualComponentTemplate.js +55 -55
- package/commands/createComponent/createComponent.js +126 -126
- package/commands/deleteComponent/deleteComponent.js +77 -77
- package/commands/doctor/doctor.js +369 -369
- package/commands/getComponent/getComponent.js +747 -747
- package/commands/init/init.js +261 -261
- package/commands/listComponents/listComponents.js +175 -175
- package/commands/startServer/startServer.js +260 -270
- package/commands/startServer/watchServer.js +79 -79
- package/commands/utils/PathHelper.js +68 -68
- package/commands/utils/VersionChecker.js +167 -167
- package/commands/utils/bundling/BundleGenerator.js +1331 -783
- package/commands/utils/bundling/DependencyAnalyzer.js +859 -679
- package/commands/utils/updateManager.js +437 -384
- package/package.json +46 -46
- package/post.js +25 -25
- package/refactor.md +271 -271
- package/tests/bundle-generator.test.js +38 -0
- package/tests/dependency-analyzer.test.js +24 -0
package/commands/Print.js
CHANGED
|
@@ -1,168 +1,168 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
|
-
|
|
3
|
-
export default class Print {
|
|
4
|
-
constructor() { }
|
|
5
|
-
|
|
6
|
-
static error(message) {
|
|
7
|
-
console.error(chalk.red(`❌ Error: ${message}`));
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
static success(message) {
|
|
11
|
-
console.log(chalk.green(`✅ Success: ${message}`));
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
static warning(message) {
|
|
15
|
-
console.log(chalk.yellow(`⚠️ Warning: ${message}`));
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
static info(message) {
|
|
19
|
-
console.log(chalk.cyan(`ℹ️ Info: ${message}`));
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
static title(message) {
|
|
23
|
-
console.log(chalk.magenta.bold(`🎯 ${message}`));
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
static subtitle(message) {
|
|
27
|
-
console.log(chalk.blue(`📋 ${message}`));
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
static step(stepNumber, message) {
|
|
31
|
-
console.log(chalk.cyan(`${stepNumber}. ${message}`));
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
static highlight(message) {
|
|
35
|
-
console.log(chalk.bgYellow.black(` ${message} `));
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
static newLine() {
|
|
39
|
-
console.log('');
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
static separator() {
|
|
43
|
-
console.log(chalk.gray('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// Métodos para el contexto específico del CLI
|
|
47
|
-
static componentSuccess(componentName, action = 'processed') {
|
|
48
|
-
console.log(chalk.green(`✅ ${componentName} ${action} successfully!`));
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
static componentError(componentName, action = 'processing', error) {
|
|
52
|
-
console.error(chalk.red(`❌ Error ${action} ${componentName}: ${error}`));
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
static downloadProgress(fileName) {
|
|
56
|
-
console.log(chalk.cyan(` 📥 Downloading ${fileName}...`));
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
static downloadSuccess(fileName) {
|
|
60
|
-
console.log(chalk.green(` ✅ ${fileName}`));
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
static downloadError(fileName, error) {
|
|
64
|
-
console.error(chalk.red(` ❌ Error downloading ${fileName}: ${error}`));
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
static registryUpdate(message) {
|
|
68
|
-
console.log(chalk.magenta(`📝 Registry: ${message}`));
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
static versionInfo(component, currentVersion, latestVersion = null) {
|
|
72
|
-
if (latestVersion && currentVersion !== latestVersion) {
|
|
73
|
-
console.log(chalk.yellow(`🔄 ${component}: v${currentVersion} → v${latestVersion}`));
|
|
74
|
-
} else {
|
|
75
|
-
console.log(chalk.green(`✅ ${component}: v${currentVersion}`));
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
static commandExample(description, command) {
|
|
80
|
-
console.log(chalk.gray(`💡 ${description}:`));
|
|
81
|
-
console.log(chalk.white(` ${command}`));
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
static summary(successful, failed, total) {
|
|
85
|
-
Print.separator();
|
|
86
|
-
console.log(chalk.bold('📊 Summary:'));
|
|
87
|
-
if (successful > 0) {
|
|
88
|
-
Print.success(`Successful: ${successful}/${total}`);
|
|
89
|
-
}
|
|
90
|
-
if (failed > 0) {
|
|
91
|
-
Print.error(`Failed: ${failed}/${total}`);
|
|
92
|
-
}
|
|
93
|
-
Print.separator();
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// Método para mostrar resultados de minificación
|
|
97
|
-
static minificationResult(filename, originalSize, minifiedSize, savingsPercent) {
|
|
98
|
-
const originalKB = (originalSize / 1024).toFixed(1);
|
|
99
|
-
const minifiedKB = (minifiedSize / 1024).toFixed(1);
|
|
100
|
-
|
|
101
|
-
console.log(chalk.green(` ✅ ${filename}`));
|
|
102
|
-
console.log(chalk.gray(` ${originalKB}KB → ${minifiedKB}KB (${savingsPercent}% saved)`));
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// Método para mostrar progreso de build
|
|
106
|
-
static buildProgress(message) {
|
|
107
|
-
console.log(chalk.cyan(`🔄 ${message}`));
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// Método para mostrar estadísticas de servidor
|
|
111
|
-
static serverStats(mode, port, directory) {
|
|
112
|
-
Print.newLine();
|
|
113
|
-
console.log(chalk.magenta(`🌐 Server Configuration:`));
|
|
114
|
-
console.log(chalk.gray(` Mode: ${mode}`));
|
|
115
|
-
console.log(chalk.gray(` Port: ${port}`));
|
|
116
|
-
console.log(chalk.gray(` Serving: /${directory}`));
|
|
117
|
-
Print.newLine();
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// Método para mostrar que el servidor está listo con URL destacada
|
|
121
|
-
static serverReady(port) {
|
|
122
|
-
Print.newLine();
|
|
123
|
-
console.log(chalk.bgGreen.black.bold(' ✓ SERVER READY '));
|
|
124
|
-
Print.newLine();
|
|
125
|
-
console.log(chalk.cyan.bold(` → Local: http://localhost:${port}`));
|
|
126
|
-
console.log(chalk.gray(` → Network: http://127.0.0.1:${port}`));
|
|
127
|
-
Print.newLine();
|
|
128
|
-
console.log(chalk.yellow(` Press Ctrl+C to stop the server`));
|
|
129
|
-
Print.newLine();
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
// Método para mostrar el estado del servidor durante inicio
|
|
133
|
-
static serverStatus(status, message = '') {
|
|
134
|
-
const icons = {
|
|
135
|
-
checking: '🔍',
|
|
136
|
-
starting: '🚀',
|
|
137
|
-
ready: '✅',
|
|
138
|
-
error: '❌'
|
|
139
|
-
};
|
|
140
|
-
const colors = {
|
|
141
|
-
checking: chalk.cyan,
|
|
142
|
-
starting: chalk.magenta,
|
|
143
|
-
ready: chalk.green,
|
|
144
|
-
error: chalk.red
|
|
145
|
-
};
|
|
146
|
-
|
|
147
|
-
const icon = icons[status] || 'ℹ️';
|
|
148
|
-
const color = colors[status] || chalk.white;
|
|
149
|
-
const displayMessage = message || status;
|
|
150
|
-
|
|
151
|
-
console.log(color(`${icon} ${displayMessage}`));
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
// Método para mostrar que se está verificando el puerto
|
|
155
|
-
static checkingPort(port) {
|
|
156
|
-
console.log(chalk.cyan(`🔍 Checking port ${port}...`));
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
// Nuevo: Método para debug
|
|
160
|
-
static debug(message) {
|
|
161
|
-
console.log(chalk.gray(`🐛 DEBUG: ${message}`));
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
// Nuevo: Método para logs verbosos
|
|
165
|
-
static verbose(message) {
|
|
166
|
-
console.log(chalk.gray(`📝 ${message}`));
|
|
167
|
-
}
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
|
|
3
|
+
export default class Print {
|
|
4
|
+
constructor() { }
|
|
5
|
+
|
|
6
|
+
static error(message) {
|
|
7
|
+
console.error(chalk.red(`❌ Error: ${message}`));
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
static success(message) {
|
|
11
|
+
console.log(chalk.green(`✅ Success: ${message}`));
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
static warning(message) {
|
|
15
|
+
console.log(chalk.yellow(`⚠️ Warning: ${message}`));
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
static info(message) {
|
|
19
|
+
console.log(chalk.cyan(`ℹ️ Info: ${message}`));
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
static title(message) {
|
|
23
|
+
console.log(chalk.magenta.bold(`🎯 ${message}`));
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
static subtitle(message) {
|
|
27
|
+
console.log(chalk.blue(`📋 ${message}`));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
static step(stepNumber, message) {
|
|
31
|
+
console.log(chalk.cyan(`${stepNumber}. ${message}`));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
static highlight(message) {
|
|
35
|
+
console.log(chalk.bgYellow.black(` ${message} `));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
static newLine() {
|
|
39
|
+
console.log('');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
static separator() {
|
|
43
|
+
console.log(chalk.gray('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Métodos para el contexto específico del CLI
|
|
47
|
+
static componentSuccess(componentName, action = 'processed') {
|
|
48
|
+
console.log(chalk.green(`✅ ${componentName} ${action} successfully!`));
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
static componentError(componentName, action = 'processing', error) {
|
|
52
|
+
console.error(chalk.red(`❌ Error ${action} ${componentName}: ${error}`));
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
static downloadProgress(fileName) {
|
|
56
|
+
console.log(chalk.cyan(` 📥 Downloading ${fileName}...`));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
static downloadSuccess(fileName) {
|
|
60
|
+
console.log(chalk.green(` ✅ ${fileName}`));
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
static downloadError(fileName, error) {
|
|
64
|
+
console.error(chalk.red(` ❌ Error downloading ${fileName}: ${error}`));
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
static registryUpdate(message) {
|
|
68
|
+
console.log(chalk.magenta(`📝 Registry: ${message}`));
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
static versionInfo(component, currentVersion, latestVersion = null) {
|
|
72
|
+
if (latestVersion && currentVersion !== latestVersion) {
|
|
73
|
+
console.log(chalk.yellow(`🔄 ${component}: v${currentVersion} → v${latestVersion}`));
|
|
74
|
+
} else {
|
|
75
|
+
console.log(chalk.green(`✅ ${component}: v${currentVersion}`));
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
static commandExample(description, command) {
|
|
80
|
+
console.log(chalk.gray(`💡 ${description}:`));
|
|
81
|
+
console.log(chalk.white(` ${command}`));
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
static summary(successful, failed, total) {
|
|
85
|
+
Print.separator();
|
|
86
|
+
console.log(chalk.bold('📊 Summary:'));
|
|
87
|
+
if (successful > 0) {
|
|
88
|
+
Print.success(`Successful: ${successful}/${total}`);
|
|
89
|
+
}
|
|
90
|
+
if (failed > 0) {
|
|
91
|
+
Print.error(`Failed: ${failed}/${total}`);
|
|
92
|
+
}
|
|
93
|
+
Print.separator();
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Método para mostrar resultados de minificación
|
|
97
|
+
static minificationResult(filename, originalSize, minifiedSize, savingsPercent) {
|
|
98
|
+
const originalKB = (originalSize / 1024).toFixed(1);
|
|
99
|
+
const minifiedKB = (minifiedSize / 1024).toFixed(1);
|
|
100
|
+
|
|
101
|
+
console.log(chalk.green(` ✅ ${filename}`));
|
|
102
|
+
console.log(chalk.gray(` ${originalKB}KB → ${minifiedKB}KB (${savingsPercent}% saved)`));
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Método para mostrar progreso de build
|
|
106
|
+
static buildProgress(message) {
|
|
107
|
+
console.log(chalk.cyan(`🔄 ${message}`));
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Método para mostrar estadísticas de servidor
|
|
111
|
+
static serverStats(mode, port, directory) {
|
|
112
|
+
Print.newLine();
|
|
113
|
+
console.log(chalk.magenta(`🌐 Server Configuration:`));
|
|
114
|
+
console.log(chalk.gray(` Mode: ${mode}`));
|
|
115
|
+
console.log(chalk.gray(` Port: ${port}`));
|
|
116
|
+
console.log(chalk.gray(` Serving: /${directory}`));
|
|
117
|
+
Print.newLine();
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Método para mostrar que el servidor está listo con URL destacada
|
|
121
|
+
static serverReady(port) {
|
|
122
|
+
Print.newLine();
|
|
123
|
+
console.log(chalk.bgGreen.black.bold(' ✓ SERVER READY '));
|
|
124
|
+
Print.newLine();
|
|
125
|
+
console.log(chalk.cyan.bold(` → Local: http://localhost:${port}`));
|
|
126
|
+
console.log(chalk.gray(` → Network: http://127.0.0.1:${port}`));
|
|
127
|
+
Print.newLine();
|
|
128
|
+
console.log(chalk.yellow(` Press Ctrl+C to stop the server`));
|
|
129
|
+
Print.newLine();
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Método para mostrar el estado del servidor durante inicio
|
|
133
|
+
static serverStatus(status, message = '') {
|
|
134
|
+
const icons = {
|
|
135
|
+
checking: '🔍',
|
|
136
|
+
starting: '🚀',
|
|
137
|
+
ready: '✅',
|
|
138
|
+
error: '❌'
|
|
139
|
+
};
|
|
140
|
+
const colors = {
|
|
141
|
+
checking: chalk.cyan,
|
|
142
|
+
starting: chalk.magenta,
|
|
143
|
+
ready: chalk.green,
|
|
144
|
+
error: chalk.red
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
const icon = icons[status] || 'ℹ️';
|
|
148
|
+
const color = colors[status] || chalk.white;
|
|
149
|
+
const displayMessage = message || status;
|
|
150
|
+
|
|
151
|
+
console.log(color(`${icon} ${displayMessage}`));
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// Método para mostrar que se está verificando el puerto
|
|
155
|
+
static checkingPort(port) {
|
|
156
|
+
console.log(chalk.cyan(`🔍 Checking port ${port}...`));
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Nuevo: Método para debug
|
|
160
|
+
static debug(message) {
|
|
161
|
+
console.log(chalk.gray(`🐛 DEBUG: ${message}`));
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Nuevo: Método para logs verbosos
|
|
165
|
+
static verbose(message) {
|
|
166
|
+
console.log(chalk.gray(`📝 ${message}`));
|
|
167
|
+
}
|
|
168
168
|
}
|
package/commands/Validations.js
CHANGED
|
@@ -1,103 +1,103 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
import { fileURLToPath } from 'url';
|
|
4
|
-
import { getConfigPath, getComponentsJsPath } from './utils/PathHelper.js';
|
|
5
|
-
|
|
6
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
7
|
-
|
|
8
|
-
class Validations {
|
|
9
|
-
constructor() {
|
|
10
|
-
this._config = null;
|
|
11
|
-
this._categories = null;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
_ensureConfig() {
|
|
15
|
-
if (!this._config) {
|
|
16
|
-
this._config = this.loadConfig();
|
|
17
|
-
if (this._config) {
|
|
18
|
-
this._categories = this._config.paths?.components;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
get config() {
|
|
24
|
-
this._ensureConfig();
|
|
25
|
-
return this._config;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
isValidComponentName(componentName) {
|
|
29
|
-
// Expresión regular para verificar si el nombre contiene caracteres especiales
|
|
30
|
-
const regex = /^[a-zA-Z][a-zA-Z0-9]*$/;
|
|
31
|
-
return regex.test(componentName);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
loadConfig() {
|
|
35
|
-
try {
|
|
36
|
-
const configPath = getConfigPath(import.meta.url);
|
|
37
|
-
if (!fs.existsSync(configPath)) {
|
|
38
|
-
// Return null silently - let commands handle missing config if needed
|
|
39
|
-
return null;
|
|
40
|
-
}
|
|
41
|
-
const rawData = fs.readFileSync(configPath, 'utf-8');
|
|
42
|
-
|
|
43
|
-
return JSON.parse(rawData);
|
|
44
|
-
} catch (error) {
|
|
45
|
-
console.error('\x1b[31m', `❌ Error loading configuration: ${error.message}`, '\x1b[0m');
|
|
46
|
-
return null;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
getCategories() {
|
|
51
|
-
this._ensureConfig();
|
|
52
|
-
return this._categories;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
getCategoryPath(category) {
|
|
56
|
-
this._ensureConfig();
|
|
57
|
-
return this._categories && this._categories[category] ? this._categories[category].path : null;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
getCategoryType(category) {
|
|
61
|
-
this._ensureConfig();
|
|
62
|
-
return this._categories && this._categories[category] ? this._categories[category].type : null;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
isValidCategory(category) {
|
|
66
|
-
this._ensureConfig();
|
|
67
|
-
if (!this._categories) return { isValid: false, category: null };
|
|
68
|
-
|
|
69
|
-
const availableCategories = Object.keys(this._categories).map(cat => cat.toLowerCase());
|
|
70
|
-
|
|
71
|
-
if (availableCategories.includes(category.toLowerCase())) {
|
|
72
|
-
return { isValid: true, category };
|
|
73
|
-
} else {
|
|
74
|
-
return { isValid: false, category: null };
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
componentExists(componentName) {
|
|
79
|
-
try {
|
|
80
|
-
const componentFilePath = getComponentsJsPath(import.meta.url);
|
|
81
|
-
|
|
82
|
-
if (!fs.existsSync(componentFilePath)) {
|
|
83
|
-
console.error('\x1b[31m', '❌ Error: components.js not found in expected path', '\x1b[0m');
|
|
84
|
-
console.log('\x1b[36m', 'ℹ️ Info: Run "slice component list" to generate components.js', '\x1b[0m');
|
|
85
|
-
return false;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
const fileContent = fs.readFileSync(componentFilePath, 'utf-8');
|
|
89
|
-
const components = eval(fileContent.replace('export default', '')); // Evalúa el contenido como objeto
|
|
90
|
-
|
|
91
|
-
return components.hasOwnProperty(componentName);
|
|
92
|
-
|
|
93
|
-
} catch (error) {
|
|
94
|
-
console.error('\x1b[31m', `❌ Error checking component existence: ${error.message}`, '\x1b[0m');
|
|
95
|
-
console.log('\x1b[36m', 'ℹ️ Info: The components.js file may be corrupted', '\x1b[0m');
|
|
96
|
-
return false;
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
const validations = new Validations();
|
|
102
|
-
|
|
103
|
-
export default validations;
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
import { getConfigPath, getComponentsJsPath } from './utils/PathHelper.js';
|
|
5
|
+
|
|
6
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
|
|
8
|
+
class Validations {
|
|
9
|
+
constructor() {
|
|
10
|
+
this._config = null;
|
|
11
|
+
this._categories = null;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
_ensureConfig() {
|
|
15
|
+
if (!this._config) {
|
|
16
|
+
this._config = this.loadConfig();
|
|
17
|
+
if (this._config) {
|
|
18
|
+
this._categories = this._config.paths?.components;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
get config() {
|
|
24
|
+
this._ensureConfig();
|
|
25
|
+
return this._config;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
isValidComponentName(componentName) {
|
|
29
|
+
// Expresión regular para verificar si el nombre contiene caracteres especiales
|
|
30
|
+
const regex = /^[a-zA-Z][a-zA-Z0-9]*$/;
|
|
31
|
+
return regex.test(componentName);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
loadConfig() {
|
|
35
|
+
try {
|
|
36
|
+
const configPath = getConfigPath(import.meta.url);
|
|
37
|
+
if (!fs.existsSync(configPath)) {
|
|
38
|
+
// Return null silently - let commands handle missing config if needed
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
const rawData = fs.readFileSync(configPath, 'utf-8');
|
|
42
|
+
|
|
43
|
+
return JSON.parse(rawData);
|
|
44
|
+
} catch (error) {
|
|
45
|
+
console.error('\x1b[31m', `❌ Error loading configuration: ${error.message}`, '\x1b[0m');
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
getCategories() {
|
|
51
|
+
this._ensureConfig();
|
|
52
|
+
return this._categories;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
getCategoryPath(category) {
|
|
56
|
+
this._ensureConfig();
|
|
57
|
+
return this._categories && this._categories[category] ? this._categories[category].path : null;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
getCategoryType(category) {
|
|
61
|
+
this._ensureConfig();
|
|
62
|
+
return this._categories && this._categories[category] ? this._categories[category].type : null;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
isValidCategory(category) {
|
|
66
|
+
this._ensureConfig();
|
|
67
|
+
if (!this._categories) return { isValid: false, category: null };
|
|
68
|
+
|
|
69
|
+
const availableCategories = Object.keys(this._categories).map(cat => cat.toLowerCase());
|
|
70
|
+
|
|
71
|
+
if (availableCategories.includes(category.toLowerCase())) {
|
|
72
|
+
return { isValid: true, category };
|
|
73
|
+
} else {
|
|
74
|
+
return { isValid: false, category: null };
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
componentExists(componentName) {
|
|
79
|
+
try {
|
|
80
|
+
const componentFilePath = getComponentsJsPath(import.meta.url);
|
|
81
|
+
|
|
82
|
+
if (!fs.existsSync(componentFilePath)) {
|
|
83
|
+
console.error('\x1b[31m', '❌ Error: components.js not found in expected path', '\x1b[0m');
|
|
84
|
+
console.log('\x1b[36m', 'ℹ️ Info: Run "slice component list" to generate components.js', '\x1b[0m');
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const fileContent = fs.readFileSync(componentFilePath, 'utf-8');
|
|
89
|
+
const components = eval(fileContent.replace('export default', '')); // Evalúa el contenido como objeto
|
|
90
|
+
|
|
91
|
+
return components.hasOwnProperty(componentName);
|
|
92
|
+
|
|
93
|
+
} catch (error) {
|
|
94
|
+
console.error('\x1b[31m', `❌ Error checking component existence: ${error.message}`, '\x1b[0m');
|
|
95
|
+
console.log('\x1b[36m', 'ℹ️ Info: The components.js file may be corrupted', '\x1b[0m');
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const validations = new Validations();
|
|
102
|
+
|
|
103
|
+
export default validations;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import bundle from '../bundle/bundle.js';
|
|
2
|
+
import buildProduction, { serveProductionBuild } from '../buildProduction/buildProduction.js';
|
|
3
|
+
import Print from '../Print.js';
|
|
4
|
+
|
|
5
|
+
export default async function build(options = {}) {
|
|
6
|
+
const minify = options.minify !== false;
|
|
7
|
+
const obfuscate = options.obfuscate !== false;
|
|
8
|
+
|
|
9
|
+
if (options.analyze) {
|
|
10
|
+
return bundle({ analyze: true, verbose: options.verbose });
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
if (options.serve) {
|
|
14
|
+
await serveProductionBuild(options.port);
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const success = await buildProduction({
|
|
19
|
+
...options,
|
|
20
|
+
minify,
|
|
21
|
+
obfuscate
|
|
22
|
+
});
|
|
23
|
+
if (!success) {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
Print.info('Generating bundles for production build...');
|
|
28
|
+
await bundle({
|
|
29
|
+
verbose: options.verbose,
|
|
30
|
+
minify,
|
|
31
|
+
obfuscate,
|
|
32
|
+
output: 'dist'
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
if (options.preview) {
|
|
36
|
+
await serveProductionBuild(options.port);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
@@ -116,7 +116,7 @@ async function copySliceConfig() {
|
|
|
116
116
|
/**
|
|
117
117
|
* Procesa un directorio completo
|
|
118
118
|
*/
|
|
119
|
-
async function processDirectory(srcPath, distPath, baseSrcPath) {
|
|
119
|
+
async function processDirectory(srcPath, distPath, baseSrcPath, options) {
|
|
120
120
|
const items = await fs.readdir(srcPath);
|
|
121
121
|
|
|
122
122
|
for (const item of items) {
|
|
@@ -126,9 +126,9 @@ async function processDirectory(srcPath, distPath, baseSrcPath) {
|
|
|
126
126
|
|
|
127
127
|
if (stat.isDirectory()) {
|
|
128
128
|
await fs.ensureDir(distItemPath);
|
|
129
|
-
await processDirectory(srcItemPath, distItemPath, baseSrcPath);
|
|
129
|
+
await processDirectory(srcItemPath, distItemPath, baseSrcPath, options);
|
|
130
130
|
} else {
|
|
131
|
-
await processFile(srcItemPath, distItemPath);
|
|
131
|
+
await processFile(srcItemPath, distItemPath, options);
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
134
|
}
|
|
@@ -136,19 +136,54 @@ async function processDirectory(srcPath, distPath, baseSrcPath) {
|
|
|
136
136
|
/**
|
|
137
137
|
* Procesa un archivo individual
|
|
138
138
|
*/
|
|
139
|
-
async function processFile(srcFilePath, distFilePath) {
|
|
139
|
+
async function processFile(srcFilePath, distFilePath, options) {
|
|
140
140
|
const ext = path.extname(srcFilePath).toLowerCase();
|
|
141
141
|
const fileName = path.basename(srcFilePath);
|
|
142
|
-
|
|
142
|
+
const isBundleConfig = fileName === 'bundle.config.json' || fileName === 'bundle.config.js';
|
|
143
|
+
const isBundleFolder = srcFilePath.includes(`${path.sep}bundles${path.sep}`);
|
|
144
|
+
|
|
145
|
+
if (isBundleConfig && isBundleFolder) {
|
|
146
|
+
const renamed = fileName.replace('bundle.config', 'bundle.build.config');
|
|
147
|
+
distFilePath = path.join(path.dirname(distFilePath), renamed);
|
|
148
|
+
}
|
|
149
|
+
|
|
143
150
|
try {
|
|
144
151
|
if (fileName === 'components.js') {
|
|
145
|
-
|
|
152
|
+
if (options?.minify === false) {
|
|
153
|
+
await fs.copy(srcFilePath, distFilePath);
|
|
154
|
+
const stat = await fs.stat(srcFilePath);
|
|
155
|
+
const sizeKB = (stat.size / 1024).toFixed(1);
|
|
156
|
+
Print.info(`📄 Copied: ${fileName} (${sizeKB} KB)`);
|
|
157
|
+
} else {
|
|
158
|
+
await processComponentsFile(srcFilePath, distFilePath);
|
|
159
|
+
}
|
|
146
160
|
} else if (ext === '.js') {
|
|
147
|
-
|
|
161
|
+
if (options?.minify === false) {
|
|
162
|
+
await fs.copy(srcFilePath, distFilePath);
|
|
163
|
+
const stat = await fs.stat(srcFilePath);
|
|
164
|
+
const sizeKB = (stat.size / 1024).toFixed(1);
|
|
165
|
+
Print.info(`📄 Copied: ${fileName} (${sizeKB} KB)`);
|
|
166
|
+
} else {
|
|
167
|
+
await minifyJavaScript(srcFilePath, distFilePath);
|
|
168
|
+
}
|
|
148
169
|
} else if (ext === '.css') {
|
|
149
|
-
|
|
170
|
+
if (options?.minify === false) {
|
|
171
|
+
await fs.copy(srcFilePath, distFilePath);
|
|
172
|
+
const stat = await fs.stat(srcFilePath);
|
|
173
|
+
const sizeKB = (stat.size / 1024).toFixed(1);
|
|
174
|
+
Print.info(`📄 Copied: ${fileName} (${sizeKB} KB)`);
|
|
175
|
+
} else {
|
|
176
|
+
await minifyCSS(srcFilePath, distFilePath);
|
|
177
|
+
}
|
|
150
178
|
} else if (ext === '.html') {
|
|
151
|
-
|
|
179
|
+
if (options?.minify === false) {
|
|
180
|
+
await fs.copy(srcFilePath, distFilePath);
|
|
181
|
+
const stat = await fs.stat(srcFilePath);
|
|
182
|
+
const sizeKB = (stat.size / 1024).toFixed(1);
|
|
183
|
+
Print.info(`📄 Copied: ${fileName} (${sizeKB} KB)`);
|
|
184
|
+
} else {
|
|
185
|
+
await minifyHTML(srcFilePath, distFilePath);
|
|
186
|
+
}
|
|
152
187
|
} else if (fileName === 'sliceConfig.json') {
|
|
153
188
|
await fs.copy(srcFilePath, distFilePath);
|
|
154
189
|
Print.info(`📄 Preserved: ${fileName} (configuration file)`);
|
|
@@ -437,7 +472,7 @@ export default async function buildProduction(options = {}) {
|
|
|
437
472
|
|
|
438
473
|
// Procesar archivos
|
|
439
474
|
Print.info('Processing and optimizing source files for Slice.js...');
|
|
440
|
-
await processDirectory(srcDir, distDir, srcDir);
|
|
475
|
+
await processDirectory(srcDir, distDir, srcDir, options);
|
|
441
476
|
Print.success('All source files processed and optimized');
|
|
442
477
|
|
|
443
478
|
await verifyBuildIntegrity(distDir);
|