g360-cli 1.3.0 → 1.5.0
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 +209 -5
- package/package.json +15 -8
- package/src/assets/brand/brand.json +43 -0
- package/src/assets/brand/cipsa/logotypes/Logo_cipsa_borde.png +0 -0
- package/src/assets/brand/cipsa/logotypes/Logo_cipsa_borde.svg +9 -0
- package/src/assets/brand/cipsa/logotypes/Logo_cipsa_solid.png +0 -0
- package/src/assets/brand/cipsa/logotypes/Logo_cipsa_solid.svg +9 -0
- package/src/assets/brand/g360/logotypes/logo-g360-dark.svg +19 -0
- package/src/assets/brand/g360/logotypes/logo-g360-light.svg +19 -0
- package/src/assets/brand/g360/logotypes/logo_g360_dark_b64.txt +1 -0
- package/src/assets/brand/g360/logotypes/logo_g360_light_b64.txt +1 -0
- package/src/assets/config/g360-skills.json +112 -0
- package/src/assets/config/project-types.json +16 -0
- package/src/assets/config/skills.json +12 -0
- package/src/assets/snippets/snippets.json +293 -24
- package/src/assets/templates/lit-web/src/core/skill.json +12 -5
- package/src/assets/templates/python-cli/build-portable.bat +43 -0
- package/src/assets/templates/python-cli/src/core/skill.json +25 -6
- package/src/assets/templates/python-cli/src/main.py +107 -3
- package/src/assets/templates/python-customtkinter/README.md +48 -0
- package/src/assets/templates/python-customtkinter/assets/images/logo-g360-dark.svg +19 -0
- package/src/assets/templates/python-customtkinter/assets/images/logo-g360-light.svg +19 -0
- package/src/assets/templates/python-customtkinter/build.bat +50 -0
- package/src/assets/templates/python-customtkinter/pyproject.toml +26 -0
- package/src/assets/templates/python-customtkinter/run.bat +20 -0
- package/src/assets/templates/python-customtkinter/src/core/g360_theme.py +101 -0
- package/src/assets/templates/python-customtkinter/src/core/skill.json +35 -0
- package/src/assets/templates/python-customtkinter/src/main.py +103 -0
- package/src/assets/templates/python-flet/README.md +89 -0
- package/src/assets/templates/python-flet/assets/images/Logo_cipsa_borde.png +0 -0
- package/src/assets/templates/python-flet/assets/images/Logo_cipsa_borde.svg +9 -0
- package/src/assets/templates/python-flet/assets/images/Logo_cipsa_solid.png +0 -0
- package/src/assets/templates/python-flet/assets/images/Logo_cipsa_solid.svg +9 -0
- package/src/assets/templates/python-flet/assets/images/logo-g360-dark.svg +19 -0
- package/src/assets/templates/python-flet/assets/images/logo-g360-light.svg +19 -0
- package/src/assets/templates/python-flet/build.bat +36 -0
- package/src/assets/templates/python-flet/pyproject.toml +26 -0
- package/src/assets/templates/python-flet/run.bat +20 -0
- package/src/assets/templates/python-flet/src/core/__init__.py +0 -0
- package/src/assets/templates/python-flet/src/core/g360_theme.py +186 -0
- package/src/assets/templates/python-flet/src/core/skill.json +41 -0
- package/src/assets/templates/python-flet/src/export/__init__.py +0 -0
- package/src/assets/templates/python-flet/src/main.py +146 -0
- package/src/assets/templates/python-flet/src/test_app.py +107 -0
- package/src/assets/templates/python-flet/src/ui/__init__.py +0 -0
- package/src/assets/templates/python-flet-migrate/README.md +70 -0
- package/src/assets/templates/python-flet-migrate/assets/images/logo-g360-dark.svg +19 -0
- package/src/assets/templates/python-flet-migrate/assets/images/logo-g360-light.svg +19 -0
- package/src/assets/templates/python-flet-migrate/build.bat +36 -0
- package/src/assets/templates/python-flet-migrate/pyproject.toml +26 -0
- package/src/assets/templates/python-flet-migrate/run.bat +20 -0
- package/src/assets/templates/python-flet-migrate/src/core/__init__.py +0 -0
- package/src/assets/templates/python-flet-migrate/src/core/g360_theme.py +186 -0
- package/src/assets/templates/python-flet-migrate/src/core/skill.json +34 -0
- package/src/assets/templates/python-flet-migrate/src/main.py +97 -0
- package/src/assets/templates/python-flet-migrate/src/migrate_tkinter.py +56 -0
- package/src/assets/templates/solid-web/src/core/skill.json +12 -5
- package/src/assets/templates/svelte-web/src/core/skill.json +12 -5
- package/src/assets/templates/web-pwa/index.html +2 -7
- package/src/assets/templates/web-pwa/public/favicon.svg +4 -0
- package/src/assets/templates/web-pwa/public/manifest.json +11 -0
- package/src/assets/templates/web-pwa/src/App.jsx +22 -0
- package/src/assets/templates/web-pwa/src/components/FooterSignature.jsx +9 -0
- package/src/assets/templates/web-pwa/src/components/Header.jsx +12 -0
- package/src/assets/templates/web-pwa/src/components/LoadingOverlay.jsx +10 -0
- package/src/assets/templates/web-pwa/src/core/skill.json +25 -0
- package/src/assets/templates/web-pwa/src/main.jsx +9 -0
- package/src/assets/templates/web-pwa/src/styles/main.css +133 -0
- package/src/assets/templates/web-pwa/vite.config.js +12 -0
- package/src/cli.js +8 -4
- package/src/commands/bring.js +81 -6
- package/src/commands/clean.js +51 -4
- package/src/commands/init.js +60 -8
- package/src/commands/list.js +79 -9
- package/src/commands/signature.js +12 -8
- package/src/lib/asset-validator.js +145 -0
- package/src/lib/auditor.js +48 -0
- package/src/lib/global-config.js +260 -0
- package/src/lib/i18n.js +238 -0
- package/src/lib/logger.js +100 -0
- package/src/lib/manifest.js +70 -1
- package/src/lib/validator.js +39 -0
- package/src/schemas/skills-schema.json +1 -0
- package/src/schemas/snippets-schema.json +1 -0
- package/src/assets/templates/web-pwa/app.js +0 -1
- package/src/assets/templates/web-pwa/styles.css +0 -28
package/src/lib/i18n.js
ADDED
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file i18n.js
|
|
3
|
+
* @description Sistema de internacionalización para G360-CLI
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Traducciones disponibles
|
|
8
|
+
* @type {Object.<string, Object.<string, string>>}
|
|
9
|
+
*/
|
|
10
|
+
const translations = {
|
|
11
|
+
es: {
|
|
12
|
+
// Comandos
|
|
13
|
+
'command.init.title': '🚀 Inicialización de Proyecto G360',
|
|
14
|
+
'command.init.project': 'Proyecto',
|
|
15
|
+
'command.init.template': 'Plantilla',
|
|
16
|
+
'command.init.skill': 'Skill',
|
|
17
|
+
'command.init.target': 'Destino',
|
|
18
|
+
'command.init.success': '✅ Proyecto creado exitosamente',
|
|
19
|
+
'command.init.portable': '📦 Versión portable habilitada',
|
|
20
|
+
'command.init.next_steps': 'Próximos pasos',
|
|
21
|
+
|
|
22
|
+
'command.list.title': '📋 Assets G360',
|
|
23
|
+
'command.list.templates': '📁 Plantillas',
|
|
24
|
+
'command.list.components': '🧩 Componentes',
|
|
25
|
+
'command.list.skills': '⚡ Skills',
|
|
26
|
+
'command.list.snippets': '📝 Snippets',
|
|
27
|
+
'command.list.no_templates': 'No se encontraron plantillas',
|
|
28
|
+
'command.list.no_components': 'No se encontraron componentes',
|
|
29
|
+
'command.list.no_skills': 'No se encontraron skills',
|
|
30
|
+
'command.list.no_snippets': 'No se encontraron snippets',
|
|
31
|
+
|
|
32
|
+
'command.set-skill.title': '🎨 Selector de Skill G360',
|
|
33
|
+
'command.set-skill.success': '✅ Skill configurado correctamente',
|
|
34
|
+
'command.set-skill.not_found': '❌ Skill no encontrado',
|
|
35
|
+
'command.set-skill.already_exists': '⚠️ El proyecto ya tiene un skill configurado',
|
|
36
|
+
'command.set-skill.use_force': 'Usa --force para sobrescribir',
|
|
37
|
+
|
|
38
|
+
'command.audit.title': '🔍 Auditoría de Proyecto G360',
|
|
39
|
+
'command.audit.results': '📊 Resultados de Auditoría',
|
|
40
|
+
'command.audit.passed': 'Pasaron',
|
|
41
|
+
'command.audit.failed': 'Fallaron',
|
|
42
|
+
'command.audit.warnings': 'Advertencias',
|
|
43
|
+
'command.audit.issues': 'Issues Encontrados',
|
|
44
|
+
'command.audit.compliant': '✅ El proyecto es compliant con G360',
|
|
45
|
+
'command.audit.issues_found': '⚠️ Algunos issues necesitan atención',
|
|
46
|
+
|
|
47
|
+
'command.health.title': '🏥 Verificación de Salud G360',
|
|
48
|
+
'command.health.status': 'Estado del Sistema',
|
|
49
|
+
'command.health.healthy': '✅ El sistema está saludable',
|
|
50
|
+
'command.health.failed': '❌ Algunos checks fallaron',
|
|
51
|
+
|
|
52
|
+
'command.clean.title': '🧹 Limpieza de Proyecto G360',
|
|
53
|
+
'command.clean.preview': '📋 DRY RUN - No se eliminarán archivos',
|
|
54
|
+
'command.clean.success': '✅ Limpieza completada',
|
|
55
|
+
|
|
56
|
+
// Errores
|
|
57
|
+
'error.templates_not_found': '❌ Plantillas no encontradas. Ejecuta: g360 update',
|
|
58
|
+
'error.template_not_found': '❌ Plantilla no encontrada',
|
|
59
|
+
'error.directory_exists': '❌ El directorio ya existe. Usa --force para sobrescribir',
|
|
60
|
+
'error.path_not_found': '❌ Ruta no encontrada',
|
|
61
|
+
'error.config_not_found': '❌ No se pudo cargar la configuración de skills',
|
|
62
|
+
|
|
63
|
+
// General
|
|
64
|
+
'general.available': 'Disponibles',
|
|
65
|
+
'general.device': 'Dispositivo',
|
|
66
|
+
'general.description': 'Descripción',
|
|
67
|
+
'general.language': 'Lenguaje',
|
|
68
|
+
'general.loading': 'Cargando...',
|
|
69
|
+
'general.done': 'Completado',
|
|
70
|
+
'general.cancelled': 'Cancelado',
|
|
71
|
+
'general.error': 'Error',
|
|
72
|
+
'general.warning': 'Advertencia',
|
|
73
|
+
'general.info': 'Información',
|
|
74
|
+
'general.success': 'Éxito'
|
|
75
|
+
},
|
|
76
|
+
|
|
77
|
+
en: {
|
|
78
|
+
// Commands
|
|
79
|
+
'command.init.title': '🚀 G360 Project Initialization',
|
|
80
|
+
'command.init.project': 'Project',
|
|
81
|
+
'command.init.template': 'Template',
|
|
82
|
+
'command.init.skill': 'Skill',
|
|
83
|
+
'command.init.target': 'Target',
|
|
84
|
+
'command.init.success': '✅ Project created successfully',
|
|
85
|
+
'command.init.portable': '📦 Portable version enabled',
|
|
86
|
+
'command.init.next_steps': 'Next steps',
|
|
87
|
+
|
|
88
|
+
'command.list.title': '📋 G360 Assets',
|
|
89
|
+
'command.list.templates': '📁 Templates',
|
|
90
|
+
'command.list.components': '🧩 Components',
|
|
91
|
+
'command.list.skills': '⚡ Skills',
|
|
92
|
+
'command.list.snippets': '📝 Snippets',
|
|
93
|
+
'command.list.no_templates': 'No templates found',
|
|
94
|
+
'command.list.no_components': 'No components found',
|
|
95
|
+
'command.list.no_skills': 'No skills found',
|
|
96
|
+
'command.list.no_snippets': 'No snippets found',
|
|
97
|
+
|
|
98
|
+
'command.set-skill.title': '🎨 G360 Skill Selector',
|
|
99
|
+
'command.set-skill.success': '✅ Skill configured successfully',
|
|
100
|
+
'command.set-skill.not_found': '❌ Skill not found',
|
|
101
|
+
'command.set-skill.already_exists': '⚠️ Project already has a skill configured',
|
|
102
|
+
'command.set-skill.use_force': 'Use --force to overwrite',
|
|
103
|
+
|
|
104
|
+
'command.audit.title': '🔍 G360 Project Audit',
|
|
105
|
+
'command.audit.results': '📊 Audit Results',
|
|
106
|
+
'command.audit.passed': 'Passed',
|
|
107
|
+
'command.audit.failed': 'Failed',
|
|
108
|
+
'command.audit.warnings': 'Warnings',
|
|
109
|
+
'command.audit.issues': 'Issues Found',
|
|
110
|
+
'command.audit.compliant': '✅ Project is G360 compliant',
|
|
111
|
+
'command.audit.issues_found': '⚠️ Some issues need attention',
|
|
112
|
+
|
|
113
|
+
'command.health.title': '🏥 G360 Health Check',
|
|
114
|
+
'command.health.status': 'System Status',
|
|
115
|
+
'command.health.healthy': '✅ System is healthy',
|
|
116
|
+
'command.health.failed': '❌ Some checks failed',
|
|
117
|
+
|
|
118
|
+
'command.clean.title': '🧹 G360 Project Clean',
|
|
119
|
+
'command.clean.preview': '📋 DRY RUN - No files will be removed',
|
|
120
|
+
'command.clean.success': '✅ Cleanup completed',
|
|
121
|
+
|
|
122
|
+
// Errors
|
|
123
|
+
'error.templates_not_found': '❌ Templates not found. Run: g360 update',
|
|
124
|
+
'error.template_not_found': '❌ Template not found',
|
|
125
|
+
'error.directory_exists': '❌ Directory already exists. Use --force to overwrite',
|
|
126
|
+
'error.path_not_found': '❌ Path not found',
|
|
127
|
+
'error.config_not_found': '❌ Could not load skills configuration',
|
|
128
|
+
|
|
129
|
+
// General
|
|
130
|
+
'general.available': 'Available',
|
|
131
|
+
'general.device': 'Device',
|
|
132
|
+
'general.description': 'Description',
|
|
133
|
+
'general.language': 'Language',
|
|
134
|
+
'general.loading': 'Loading...',
|
|
135
|
+
'general.done': 'Done',
|
|
136
|
+
'general.cancelled': 'Cancelled',
|
|
137
|
+
'general.error': 'Error',
|
|
138
|
+
'general.warning': 'Warning',
|
|
139
|
+
'general.info': 'Info',
|
|
140
|
+
'general.success': 'Success'
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Idioma actual
|
|
146
|
+
* @type {string}
|
|
147
|
+
*/
|
|
148
|
+
let currentLanguage = 'es';
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Módulo de internacionalización para G360-CLI
|
|
152
|
+
* @namespace i18n
|
|
153
|
+
*/
|
|
154
|
+
export const i18n = {
|
|
155
|
+
/**
|
|
156
|
+
* Establece el idioma actual
|
|
157
|
+
* @param {string} language - Código de idioma ('es' | 'en')
|
|
158
|
+
* @returns {void}
|
|
159
|
+
* @example
|
|
160
|
+
* i18n.setLanguage('en');
|
|
161
|
+
*/
|
|
162
|
+
setLanguage(language) {
|
|
163
|
+
if (translations[language]) {
|
|
164
|
+
currentLanguage = language;
|
|
165
|
+
} else {
|
|
166
|
+
console.warn(`Language '${language}' not supported, using 'es'`);
|
|
167
|
+
}
|
|
168
|
+
},
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Obtiene el idioma actual
|
|
172
|
+
* @returns {string} Código de idioma actual
|
|
173
|
+
* @example
|
|
174
|
+
* const lang = i18n.getLanguage();
|
|
175
|
+
*/
|
|
176
|
+
getLanguage() {
|
|
177
|
+
return currentLanguage;
|
|
178
|
+
},
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Traduce una clave de texto
|
|
182
|
+
* @param {string} key - Clave de traducción
|
|
183
|
+
* @param {Object} [params] - Parámetros para interpolación
|
|
184
|
+
* @returns {string} Texto traducido
|
|
185
|
+
* @example
|
|
186
|
+
* const text = i18n.t('command.init.success');
|
|
187
|
+
* const text = i18n.t('command.init.project', { name: 'my-project' });
|
|
188
|
+
*/
|
|
189
|
+
t(key, params = {}) {
|
|
190
|
+
const lang = translations[currentLanguage] || translations.es;
|
|
191
|
+
let text = lang[key] || translations.es[key] || key;
|
|
192
|
+
|
|
193
|
+
// Interpolación de parámetros
|
|
194
|
+
Object.keys(params).forEach(param => {
|
|
195
|
+
text = text.replace(`{${param}}`, params[param]);
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
return text;
|
|
199
|
+
},
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Verifica si una clave de traducción existe
|
|
203
|
+
* @param {string} key - Clave de traducción
|
|
204
|
+
* @returns {boolean} true si existe, false en caso contrario
|
|
205
|
+
* @example
|
|
206
|
+
* if (i18n.has('command.init.success')) {
|
|
207
|
+
* console.log(i18n.t('command.init.success'));
|
|
208
|
+
* }
|
|
209
|
+
*/
|
|
210
|
+
has(key) {
|
|
211
|
+
const lang = translations[currentLanguage] || translations.es;
|
|
212
|
+
return key in lang;
|
|
213
|
+
},
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Obtiene todos los idiomas disponibles
|
|
217
|
+
* @returns {string[]} Lista de códigos de idioma
|
|
218
|
+
* @example
|
|
219
|
+
* const languages = i18n.getAvailableLanguages();
|
|
220
|
+
* console.log('Available languages:', languages);
|
|
221
|
+
*/
|
|
222
|
+
getAvailableLanguages() {
|
|
223
|
+
return Object.keys(translations);
|
|
224
|
+
},
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Obtiene las traducciones para un idioma específico
|
|
228
|
+
* @param {string} language - Código de idioma
|
|
229
|
+
* @returns {Object|null} Objeto de traducciones o null si no existe
|
|
230
|
+
* @example
|
|
231
|
+
* const esTranslations = i18n.getTranslations('es');
|
|
232
|
+
*/
|
|
233
|
+
getTranslations(language) {
|
|
234
|
+
return translations[language] || null;
|
|
235
|
+
}
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
export default i18n;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import winston from 'winston';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
|
|
5
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Niveles de log disponibles
|
|
9
|
+
* @enum {string}
|
|
10
|
+
*/
|
|
11
|
+
const LogLevel = {
|
|
12
|
+
ERROR: 'error',
|
|
13
|
+
WARN: 'warn',
|
|
14
|
+
INFO: 'info',
|
|
15
|
+
DEBUG: 'debug'
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Formato personalizado para logs
|
|
20
|
+
* @param {Object} info - Información del log
|
|
21
|
+
* @returns {string} Log formateado
|
|
22
|
+
*/
|
|
23
|
+
const customFormat = winston.format.combine(
|
|
24
|
+
winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
|
|
25
|
+
winston.format.errors({ stack: true }),
|
|
26
|
+
winston.format.printf(({ level, message, timestamp, ...metadata }) => {
|
|
27
|
+
let msg = `${timestamp} [${level.toUpperCase()}]: ${message}`;
|
|
28
|
+
|
|
29
|
+
if (Object.keys(metadata).length > 0) {
|
|
30
|
+
msg += ` ${JSON.stringify(metadata)}`;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return msg;
|
|
34
|
+
})
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Logger configurado para G360-CLI
|
|
39
|
+
* @type {winston.Logger}
|
|
40
|
+
*/
|
|
41
|
+
export const logger = winston.createLogger({
|
|
42
|
+
level: process.env.LOG_LEVEL || 'info',
|
|
43
|
+
format: customFormat,
|
|
44
|
+
transports: [
|
|
45
|
+
// Console transport para desarrollo
|
|
46
|
+
new winston.transports.Console({
|
|
47
|
+
format: winston.format.combine(
|
|
48
|
+
winston.format.colorize(),
|
|
49
|
+
customFormat
|
|
50
|
+
)
|
|
51
|
+
}),
|
|
52
|
+
|
|
53
|
+
// File transport para logs persistentes
|
|
54
|
+
new winston.transports.File({
|
|
55
|
+
filename: path.join(__dirname, '../../logs/g360-cli.log'),
|
|
56
|
+
level: 'info',
|
|
57
|
+
maxsize: 5242880, // 5MB
|
|
58
|
+
maxFiles: 3
|
|
59
|
+
}),
|
|
60
|
+
|
|
61
|
+
// Error file transport
|
|
62
|
+
new winston.transports.File({
|
|
63
|
+
filename: path.join(__dirname, '../../logs/error.log'),
|
|
64
|
+
level: 'error',
|
|
65
|
+
maxsize: 5242880, // 5MB
|
|
66
|
+
maxFiles: 3
|
|
67
|
+
})
|
|
68
|
+
]
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Crea un logger hijo con contexto específico
|
|
73
|
+
* @param {string} context - Contexto del logger
|
|
74
|
+
* @returns {winston.Logger} Logger hijo con contexto
|
|
75
|
+
*/
|
|
76
|
+
export function createChildLogger(context) {
|
|
77
|
+
return logger.child({ context });
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Logger para comandos CLI
|
|
82
|
+
*/
|
|
83
|
+
export const commandLogger = createChildLogger('command');
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Logger para operaciones de archivos
|
|
87
|
+
*/
|
|
88
|
+
export const fileLogger = createChildLogger('file');
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Logger para validaciones
|
|
92
|
+
*/
|
|
93
|
+
export const validationLogger = createChildLogger('validation');
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Logger para auditoría
|
|
97
|
+
*/
|
|
98
|
+
export const auditLogger = createChildLogger('audit');
|
|
99
|
+
|
|
100
|
+
export default logger;
|
package/src/lib/manifest.js
CHANGED
|
@@ -1,7 +1,42 @@
|
|
|
1
1
|
import fs from 'fs-extra';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* @typedef {Object} ProjectManifest
|
|
6
|
+
* @property {string} name - Nombre del proyecto
|
|
7
|
+
* @property {string} template - Plantilla utilizada
|
|
8
|
+
* @property {string} version - Versión del proyecto
|
|
9
|
+
* @property {string} createdAt - Fecha de creación en formato ISO
|
|
10
|
+
* @property {Asset[]} assets - Lista de assets del proyecto
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @typedef {Object} Asset
|
|
15
|
+
* @property {string} name - Nombre del asset
|
|
16
|
+
* @property {string} type - Tipo del asset
|
|
17
|
+
* @property {string} addedAt - Fecha de adición en formato ISO
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Módulo para gestión de manifiestos de proyectos G360
|
|
22
|
+
* @namespace manifest
|
|
23
|
+
*/
|
|
4
24
|
export const manifest = {
|
|
25
|
+
/**
|
|
26
|
+
* Inicializa un nuevo manifiesto de proyecto
|
|
27
|
+
* @param {string} projectDir - Directorio del proyecto
|
|
28
|
+
* @param {Object} data - Datos del proyecto
|
|
29
|
+
* @param {string} data.name - Nombre del proyecto
|
|
30
|
+
* @param {string} data.template - Plantilla utilizada
|
|
31
|
+
* @param {string} data.version - Versión del proyecto
|
|
32
|
+
* @returns {Promise<ProjectManifest>} Manifiesto creado
|
|
33
|
+
* @example
|
|
34
|
+
* const manifest = await manifest.init('/my/project', {
|
|
35
|
+
* name: 'my-project',
|
|
36
|
+
* template: 'web-pwa',
|
|
37
|
+
* version: '1.0.0'
|
|
38
|
+
* });
|
|
39
|
+
*/
|
|
5
40
|
async init(projectDir, data) {
|
|
6
41
|
const manifestPath = path.join(projectDir, 'g360-manifest.json');
|
|
7
42
|
const manifest = {
|
|
@@ -15,14 +50,41 @@ export const manifest = {
|
|
|
15
50
|
return manifest;
|
|
16
51
|
},
|
|
17
52
|
|
|
53
|
+
/**
|
|
54
|
+
* Carga el manifiesto de un proyecto existente
|
|
55
|
+
* @param {string} projectDir - Directorio del proyecto
|
|
56
|
+
* @returns {Promise<ProjectManifest|null>} Manifiesto del proyecto o null si no existe
|
|
57
|
+
* @example
|
|
58
|
+
* const manifest = await manifest.load('/my/project');
|
|
59
|
+
* if (manifest) {
|
|
60
|
+
* console.log('Proyecto:', manifest.name);
|
|
61
|
+
* }
|
|
62
|
+
*/
|
|
18
63
|
async load(projectDir) {
|
|
19
64
|
const manifestPath = path.join(projectDir, 'g360-manifest.json');
|
|
20
65
|
if (fs.existsSync(manifestPath)) {
|
|
21
|
-
|
|
66
|
+
try {
|
|
67
|
+
return await fs.readJson(manifestPath);
|
|
68
|
+
} catch (error) {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
22
71
|
}
|
|
23
72
|
return null;
|
|
24
73
|
},
|
|
25
74
|
|
|
75
|
+
/**
|
|
76
|
+
* Agrega un asset al manifiesto del proyecto
|
|
77
|
+
* @param {string} projectDir - Directorio del proyecto
|
|
78
|
+
* @param {Object} asset - Asset a agregar
|
|
79
|
+
* @param {string} asset.name - Nombre del asset
|
|
80
|
+
* @param {string} asset.type - Tipo del asset
|
|
81
|
+
* @returns {Promise<void>}
|
|
82
|
+
* @example
|
|
83
|
+
* await manifest.addAsset('/my/project', {
|
|
84
|
+
* name: 'components',
|
|
85
|
+
* type: 'directory'
|
|
86
|
+
* });
|
|
87
|
+
*/
|
|
26
88
|
async addAsset(projectDir, asset) {
|
|
27
89
|
const data = await this.load(projectDir);
|
|
28
90
|
if (data) {
|
|
@@ -34,6 +96,13 @@ export const manifest = {
|
|
|
34
96
|
}
|
|
35
97
|
},
|
|
36
98
|
|
|
99
|
+
/**
|
|
100
|
+
* Elimina el manifiesto del proyecto
|
|
101
|
+
* @param {string} projectDir - Directorio del proyecto
|
|
102
|
+
* @returns {Promise<void>}
|
|
103
|
+
* @example
|
|
104
|
+
* await manifest.remove('/my/project');
|
|
105
|
+
*/
|
|
37
106
|
async remove(projectDir) {
|
|
38
107
|
const manifestPath = path.join(projectDir, 'g360-manifest.json');
|
|
39
108
|
if (fs.existsSync(manifestPath)) {
|
package/src/lib/validator.js
CHANGED
|
@@ -1,10 +1,37 @@
|
|
|
1
1
|
import fs from 'fs-extra';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* @typedef {Object} ValidationResult
|
|
5
|
+
* @property {boolean} valid - Indica si la validación fue exitosa
|
|
6
|
+
* @property {string[]} errors - Lista de errores encontrados
|
|
7
|
+
* @property {string[]} warnings - Lista de advertencias encontradas
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Módulo de validación para proyectos G360
|
|
12
|
+
* @namespace validator
|
|
13
|
+
*/
|
|
3
14
|
export const validator = {
|
|
15
|
+
/**
|
|
16
|
+
* Valida si un nombre de proyecto es válido
|
|
17
|
+
* @param {string} name - Nombre del proyecto a validar
|
|
18
|
+
* @returns {boolean} true si el nombre es válido, false en caso contrario
|
|
19
|
+
* @example
|
|
20
|
+
* validator.isValidProjectName('my-project') // true
|
|
21
|
+
* validator.isValidProjectName('My-Project') // false
|
|
22
|
+
*/
|
|
4
23
|
isValidProjectName(name) {
|
|
5
24
|
return /^[a-z0-9][a-z0-9-]*$/.test(name);
|
|
6
25
|
},
|
|
7
26
|
|
|
27
|
+
/**
|
|
28
|
+
* Valida si una ruta existe en el sistema de archivos
|
|
29
|
+
* @param {string} path - Ruta a validar
|
|
30
|
+
* @returns {boolean} true si la ruta existe, false en caso contrario
|
|
31
|
+
* @example
|
|
32
|
+
* validator.isValidPath('/existing/path') // true
|
|
33
|
+
* validator.isValidPath('/non/existing') // false
|
|
34
|
+
*/
|
|
8
35
|
isValidPath(path) {
|
|
9
36
|
try {
|
|
10
37
|
return fs.existsSync(path);
|
|
@@ -13,6 +40,18 @@ export const validator = {
|
|
|
13
40
|
}
|
|
14
41
|
},
|
|
15
42
|
|
|
43
|
+
/**
|
|
44
|
+
* Valida si un directorio es un proyecto G360 válido
|
|
45
|
+
* @param {string} projectDir - Ruta del directorio del proyecto
|
|
46
|
+
* @returns {ValidationResult} Objeto con resultado de la validación
|
|
47
|
+
* @example
|
|
48
|
+
* const result = validator.validateProject('/my/project');
|
|
49
|
+
* if (result.valid) {
|
|
50
|
+
* console.log('Proyecto válido');
|
|
51
|
+
* } else {
|
|
52
|
+
* console.error('Errores:', result.errors);
|
|
53
|
+
* }
|
|
54
|
+
*/
|
|
16
55
|
validateProject(projectDir) {
|
|
17
56
|
const errors = [];
|
|
18
57
|
const warnings = [];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"$schema":"http://json-schema.org/draft-07/schema#","properties":{"skills":{"items":{"properties":{"colors":{"properties":{"accent":{"pattern":"^#[0-9a-fA-F]{6}$","type":"string"},"bg":{"pattern":"^#[0-9a-fA-F]{6}$","type":"string"},"muted":{"pattern":"^#[0-9a-fA-F]{6}$","type":"string"},"surface":{"pattern":"^#[0-9a-fA-F]{6}$","type":"string"},"text":{"pattern":"^#[0-9a-fA-F]{6}$","type":"string"}},"required":["bg","surface","accent","text","muted"],"type":"object"},"description":{"minLength":1,"type":"string"},"device":{"enum":["pc","movil","both"],"type":"string"},"name":{"pattern":"^[a-z0-9-]+$","type":"string"},"signature":{"properties":{"mode":{"enum":["powered","own","optional","custom"],"type":"string"},"text":{"minLength":1,"type":"string"}},"required":["mode","text"],"type":"object"}},"required":["name","description","device","colors","signature"],"type":"object"},"type":"array"}},"required":["skills"],"title":"G360 Skills Configuration","type":"object"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"$schema":"http://json-schema.org/draft-07/schema#","properties":{"snippets":{"items":{"properties":{"code":{"minLength":1,"type":"string"},"description":{"minLength":1,"type":"string"},"language":{"minLength":1,"type":"string"},"name":{"pattern":"^[a-z0-9-]+$","type":"string"}},"required":["name","description","code"],"type":"object"},"type":"array"}},"required":["snippets"],"title":"G360 Snippets Configuration","type":"object"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
console.log('G360 Project initialized');
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
:root {
|
|
2
|
-
--g360-primary: #3B82F6;
|
|
3
|
-
--g360-secondary: #10B981;
|
|
4
|
-
--g360-accent: #8B5CF6;
|
|
5
|
-
--g360-bg: #ffffff;
|
|
6
|
-
--g360-text: #1f2937;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
10
|
-
|
|
11
|
-
body {
|
|
12
|
-
font-family: system-ui, sans-serif;
|
|
13
|
-
background: var(--g360-bg);
|
|
14
|
-
color: var(--g360-text);
|
|
15
|
-
line-height: 1.6;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
.g360-header {
|
|
19
|
-
background: var(--g360-primary);
|
|
20
|
-
color: white;
|
|
21
|
-
padding: 1rem 2rem;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
.g360-footer {
|
|
25
|
-
text-align: center;
|
|
26
|
-
padding: 1rem;
|
|
27
|
-
color: #6b7280;
|
|
28
|
-
}
|