slicejs-cli 2.1.10 → 2.1.11

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.
@@ -109,8 +109,7 @@ class ComponentRegistry {
109
109
  updatableComponents.push({
110
110
  name,
111
111
  category,
112
- path: componentPath,
113
- description: this.getComponentDescription(name, category)
112
+ path: componentPath
114
113
  });
115
114
  }
116
115
  }
@@ -125,13 +124,25 @@ class ComponentRegistry {
125
124
  const components = {};
126
125
  Object.entries(this.componentsRegistry).forEach(([name, componentCategory]) => {
127
126
  if (!category || componentCategory === category) {
127
+ // ✅ CORREGIDO: Componentes especiales que no necesitan todos los archivos
128
+ let files;
129
+ if (componentCategory === 'Visual') {
130
+ // Componentes de routing lógico solo necesitan JS
131
+ if (['Route', 'MultiRoute', 'NotFound'].includes(name)) {
132
+ files = [`${name}.js`];
133
+ } else {
134
+ // Componentes visuales normales necesitan JS, HTML, CSS
135
+ files = [`${name}.js`, `${name}.html`, `${name}.css`];
136
+ }
137
+ } else {
138
+ // Service components solo necesitan JS
139
+ files = [`${name}.js`];
140
+ }
141
+
128
142
  components[name] = {
129
143
  name,
130
144
  category: componentCategory,
131
- files: componentCategory === 'Visual' ?
132
- [`${name}.js`, `${name}.html`, `${name}.css`] :
133
- [`${name}.js`],
134
- description: this.getComponentDescription(name, componentCategory)
145
+ files: files
135
146
  };
136
147
  }
137
148
  });
@@ -139,37 +150,42 @@ class ComponentRegistry {
139
150
  return components;
140
151
  }
141
152
 
142
- getComponentDescription(componentName, category) {
143
- const descriptions = {
144
- // Visual Components
145
- 'Button': 'Interactive button component with customizable styling and events',
146
- 'Card': 'Flexible container component for displaying content in card format',
147
- 'Input': 'Form input component with validation and multiple input types support',
148
- 'Checkbox': 'Checkbox input component with custom styling and state management',
149
- 'Switch': 'Toggle switch component for binary state selection',
150
- 'Select': 'Dropdown selection component with search and multi-select support',
151
- 'Details': 'Collapsible details component for expandable content sections',
152
- 'Grid': 'Responsive grid layout component for organizing content',
153
- 'Icon': 'Icon display component with multiple icon libraries support',
154
- 'Layout': 'Main layout component for application page structure',
155
- 'Loading': 'Loading indicator component with multiple animation styles',
156
- 'Navbar': 'Navigation bar component with responsive design and menu support',
157
- 'TreeView': 'Hierarchical tree view component for nested data display',
158
- 'TreeItem': 'Individual tree item component used within TreeView',
159
- 'DropDown': 'Dropdown menu component for contextual actions',
160
- 'Route': 'Single route component for client-side routing',
161
- 'MultiRoute': 'Multiple route handler component for complex routing',
162
- 'NotFound': '404 error page component for unmatched routes',
163
-
164
- // Service Components
165
- 'FetchManager': 'HTTP request manager service for API communication',
166
- 'LocalStorageManager': 'Local storage management service for browser storage',
167
- 'IndexedDbManager': 'IndexedDB database management service for client-side storage',
168
- 'Translator': 'Internationalization service for multi-language support',
169
- 'Link': 'Navigation link service for programmatic routing'
170
- };
171
-
172
- return descriptions[componentName] || `${componentName} component from Slice.js framework (${category})`;
153
+ displayAvailableComponents() {
154
+ if (!this.componentsRegistry) {
155
+ Print.error('❌ No se pudo cargar el registro de componentes');
156
+ return;
157
+ }
158
+
159
+ console.log('\n📚 Componentes disponibles en el repositorio oficial de Slice.js:\n');
160
+
161
+ const visualComponents = this.getAvailableComponents('Visual');
162
+ const serviceComponents = this.getAvailableComponents('Service');
163
+
164
+ // SIMPLIFICADO: Solo mostrar nombres sin descripciones
165
+ Print.info('🎨 Visual Components (UI):');
166
+ Object.keys(visualComponents).forEach(name => {
167
+ const files = visualComponents[name].files;
168
+ const fileIcons = files.map(file => {
169
+ if (file.endsWith('.js')) return '📜';
170
+ if (file.endsWith('.html')) return '🌐';
171
+ if (file.endsWith('.css')) return '🎨';
172
+ return '📄';
173
+ }).join(' ');
174
+ console.log(` • ${name} ${fileIcons}`);
175
+ });
176
+
177
+ Print.info('\n⚙️ Service Components (Logic):');
178
+ Object.keys(serviceComponents).forEach(name => {
179
+ console.log(` • ${name} 📜`);
180
+ });
181
+
182
+ Print.newLine();
183
+ Print.info(`Total: ${Object.keys(visualComponents).length} Visual + ${Object.keys(serviceComponents).length} Service components`);
184
+
185
+ console.log(`\n💡 Ejemplos de uso:`);
186
+ console.log(`slice get Button Card Input # Obtener componentes Visual`);
187
+ console.log(`slice get FetchManager --service # Obtener componente Service`);
188
+ console.log(`slice sync # Sincronizar componentes Visual`);
173
189
  }
174
190
 
175
191
  async downloadComponentFiles(componentName, category, targetPath) {
@@ -180,6 +196,7 @@ class ComponentRegistry {
180
196
  }
181
197
 
182
198
  const downloadedFiles = [];
199
+ const failedFiles = [];
183
200
  Print.info(`Downloading ${componentName} from official repository...`);
184
201
 
185
202
  for (const fileName of component.files) {
@@ -190,7 +207,9 @@ class ComponentRegistry {
190
207
  const response = await fetch(githubUrl);
191
208
 
192
209
  if (!response.ok) {
193
- throw new Error(`HTTP ${response.status}: ${response.statusText} for ${fileName}`);
210
+ Print.downloadError(fileName, `HTTP ${response.status}: ${response.statusText}`);
211
+ failedFiles.push(fileName);
212
+ continue; // ✅ CONTINUAR en lugar de lanzar error
194
213
  }
195
214
 
196
215
  const content = await response.text();
@@ -200,10 +219,24 @@ class ComponentRegistry {
200
219
  Print.downloadSuccess(fileName);
201
220
  } catch (error) {
202
221
  Print.downloadError(fileName, error.message);
203
- throw error;
222
+ failedFiles.push(fileName);
223
+ continue; // ✅ CONTINUAR en lugar de lanzar error
204
224
  }
205
225
  }
206
226
 
227
+ // ✅ NUEVO: Solo lanzar error si NO se descargó el archivo principal (.js)
228
+ const mainFileDownloaded = downloadedFiles.some(file => file.endsWith('.js'));
229
+
230
+ if (!mainFileDownloaded) {
231
+ throw new Error(`Failed to download main component file (${componentName}.js)`);
232
+ }
233
+
234
+ // ✅ ADVERTENCIA: Informar sobre archivos que fallaron (pero no detener el proceso)
235
+ if (failedFiles.length > 0) {
236
+ Print.warning(`Some files couldn't be downloaded: ${failedFiles.join(', ')}`);
237
+ Print.info('Component installed with available files');
238
+ }
239
+
207
240
  return downloadedFiles;
208
241
  }
209
242
 
@@ -295,18 +328,27 @@ class ComponentRegistry {
295
328
  // Update components registry
296
329
  await this.updateLocalRegistry(componentName, category);
297
330
 
298
- Print.success(`${componentName} updated successfully from official repository!`);
331
+ Print.success(`${componentName} installed successfully from official repository!`);
299
332
  console.log(`📁 Location: ${folderSuffix}/${categoryPath}/${componentName}/`);
300
333
  console.log(`📄 Files: ${downloadedFiles.join(', ')}`);
301
334
 
302
335
  return true;
303
336
 
304
337
  } catch (error) {
305
- Print.error(`Error updating ${componentName}: ${error.message}`);
306
- // Clean up partial installation
307
- if (await fs.pathExists(targetPath)) {
338
+ Print.error(`Error installing ${componentName}: ${error.message}`);
339
+
340
+ // ✅ MEJORADO: Solo borrar si el archivo principal (.js) no existe
341
+ const mainFilePath = path.join(targetPath, `${componentName}.js`);
342
+ const mainFileExists = await fs.pathExists(mainFilePath);
343
+
344
+ if (!mainFileExists && await fs.pathExists(targetPath)) {
345
+ // Solo limpiar si no se instaló el archivo principal
308
346
  await fs.remove(targetPath);
347
+ Print.info('Cleaned up failed installation');
348
+ } else if (mainFileExists) {
349
+ Print.warning('Component partially installed - main file exists');
309
350
  }
351
+
310
352
  throw error;
311
353
  }
312
354
  }
@@ -420,20 +462,31 @@ class ComponentRegistry {
420
462
  const visualComponents = this.getAvailableComponents('Visual');
421
463
  const serviceComponents = this.getAvailableComponents('Service');
422
464
 
465
+ // ✅ SIMPLIFICADO: Solo mostrar nombres sin descripciones
423
466
  Print.info('🎨 Visual Components (UI):');
424
- Object.entries(visualComponents).forEach(([name, info]) => {
425
- console.log(` • ${name}: ${info.description}`);
467
+ Object.keys(visualComponents).forEach(name => {
468
+ const files = visualComponents[name].files;
469
+ const fileIcons = files.map(file => {
470
+ if (file.endsWith('.js')) return '📜';
471
+ if (file.endsWith('.html')) return '🌐';
472
+ if (file.endsWith('.css')) return '🎨';
473
+ return '📄';
474
+ }).join(' ');
475
+ console.log(` • ${name} ${fileIcons}`);
426
476
  });
427
477
 
428
478
  Print.info('\n⚙️ Service Components (Logic):');
429
- Object.entries(serviceComponents).forEach(([name, info]) => {
430
- console.log(` • ${name}: ${info.description}`);
479
+ Object.keys(serviceComponents).forEach(name => {
480
+ console.log(` • ${name} 📜`);
431
481
  });
432
482
 
483
+ Print.newLine();
484
+ Print.info(`Total: ${Object.keys(visualComponents).length} Visual + ${Object.keys(serviceComponents).length} Service components`);
485
+
433
486
  console.log(`\n💡 Ejemplos de uso:`);
434
- console.log(`npm run slice:get Button Card Input`);
435
- console.log(`npm run slice:get FetchManager --service`);
436
- console.log(`npm run slice:sync # Actualizar componentes existentes`);
487
+ console.log(`slice get Button Card Input # Obtener componentes Visual`);
488
+ console.log(`slice get FetchManager --service # Obtener componente Service`);
489
+ console.log(`slice sync # Sincronizar componentes Visual`);
437
490
  }
438
491
 
439
492
  async interactiveInstall() {
@@ -450,8 +503,8 @@ class ComponentRegistry {
450
503
  ]);
451
504
 
452
505
  const availableComponents = this.getAvailableComponents(componentType);
453
- const componentChoices = Object.entries(availableComponents).map(([name, info]) => ({
454
- name: `${name} - ${info.description}`,
506
+ const componentChoices = Object.keys(availableComponents).map(name => ({
507
+ name: name,
455
508
  value: name
456
509
  }));
457
510
 
@@ -554,7 +607,7 @@ async function getComponents(componentNames = [], options = {}) {
554
607
 
555
608
  if (!componentInfo) {
556
609
  Print.error(`Component '${componentNames[0]}' not found in official repository`);
557
- Print.commandExample('View available components', 'npm run slice:browse');
610
+ Print.commandExample('View available components', 'slice browse');
558
611
  return false;
559
612
  }
560
613
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "slicejs-cli",
3
- "version": "2.1.10",
3
+ "version": "2.1.11",
4
4
  "description": "Command client for developing web applications with Slice.js framework",
5
5
  "main": "client.js",
6
6
  "scripts": {