Primera versión del plugin
This commit is contained in:
63
README.md
Normal file
63
README.md
Normal file
@@ -0,0 +1,63 @@
|
||||
# 🎨 FontAwesome 6 Pro para Logseq
|
||||
|
||||
Plugin completo para integrar **FontAwesome 6 Pro** en Logseq con panel de íconos, slash commands, control de color y tamaño, y soporte para **todos los 11 estilos disponibles**.
|
||||
|
||||

|
||||

|
||||

|
||||
|
||||
## ✨ Características
|
||||
|
||||
### 🎨 **Todos los estilos FontAwesome 6 Pro**
|
||||
- ✅ **Solid** (fas) - 900 weight
|
||||
- ✅ **Regular** (far) - 400 weight
|
||||
- ✅ **Light** (fal) - 300 weight
|
||||
- ✅ **Thin** (fat) - 100 weight
|
||||
- ✅ **Duotone** (fad) - 900 weight
|
||||
- ✅ **Sharp Solid** (fass) - ⭐ Nuevo en FA6
|
||||
- ✅ **Sharp Regular** (fasr) - ⭐ Nuevo en FA6
|
||||
- ✅ **Sharp Light** (fasl) - ⭐ Nuevo en FA6
|
||||
- ✅ **Sharp Thin** (fast) - ⭐ Nuevo en FA6
|
||||
- ✅ **Sharp Duotone** (fasd) - ⭐ Nuevo en FA6
|
||||
- ✅ **Brands** (fab) - 400 weight (gratis)
|
||||
|
||||
### 🎯 **Funcionalidades avanzadas**
|
||||
- 🎨 **Control completo de color** - Predefinidos + personalizado (#hex, rgb(), nombres)
|
||||
- 📏 **Control de tamaño** - XS (0.75em) a 4X (4em)
|
||||
- 🌀 **8 animaciones** - Spin, Pulse, Beat, Fade, Bounce, Flip, Shake
|
||||
- 🔄 **Transformaciones** - Rotación (0°, 90°, 180°, 270°) + Flip
|
||||
- 🔍 **Buscador inteligente** - Por nombre, categoría, etiquetas en español/inglés
|
||||
- 🗂️ **58 categorías** - Organizadas y traducidas
|
||||
- ⭐ **Favoritos** - Guarda tus íconos más usados
|
||||
- 🕒 **Recientes** - Acceso rápido a íconos usados
|
||||
- 💾 **Presets guardados** - Configuraciones por ícono
|
||||
- ⌨️ **Slash commands** - Integración nativa con Logseq
|
||||
- 🌓 **Tema claro/oscuro** - Se adapta automáticamente
|
||||
|
||||
### ⚡ **Rendimiento y usabilidad**
|
||||
- 🚀 **Detección automática** - Solo carga los estilos que tienes instalados
|
||||
- 💾 **Archivos locales** - Funciona 100% offline
|
||||
- 🔄 **Actualización fácil** - Scripts automáticos
|
||||
- 📊 **Verificación** - Comprueba archivos faltantes
|
||||
- 🛡️ **Degradación elegante** - No se rompe si faltan estilos
|
||||
|
||||
## 🚀 Instalación
|
||||
|
||||
### Requisitos previos
|
||||
- **Logseq** v0.9.x o superior
|
||||
- **FontAwesome 6 Pro** (licencia válida)
|
||||
- **Node.js** (solo para generación de base de datos)
|
||||
|
||||
### Paso 1: Descargar FontAwesome 6 Pro
|
||||
1. Visita [fontawesome.com](https://fontawesome.com)
|
||||
2. Inicia sesión con tu cuenta Pro
|
||||
3. Descarga "Font Awesome 6 Pro - Web"
|
||||
|
||||
### Paso 2: Preparar archivos del plugin
|
||||
```bash
|
||||
# Crear estructura de carpetas
|
||||
mkdir logseq-fontawesome-pro
|
||||
cd logseq-fontawesome-pro
|
||||
|
||||
# Crear directorios necesarios
|
||||
mkdir -p assets/fontawesome/{css,webfonts,metadata}
|
||||
139
assets/dynamic-styles.css
Normal file
139
assets/dynamic-styles.css
Normal file
@@ -0,0 +1,139 @@
|
||||
/* ============================================
|
||||
FontAwesome Dynamic Styles
|
||||
Generado: 2025-12-15T04:11:59.767Z
|
||||
Estilos detectados: 10
|
||||
============================================ */
|
||||
|
||||
/* Font Awesome 6 Pro */
|
||||
@font-face {
|
||||
font-family: 'Font Awesome 6 Pro';
|
||||
font-style: normal;
|
||||
font-weight: 900;
|
||||
font-display: block;
|
||||
src: url("../webfonts/fa-solid-900.woff2") format("woff2");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Font Awesome 6 Pro';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: block;
|
||||
src: url("../webfonts/fa-regular-400.woff2") format("woff2");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Font Awesome 6 Pro';
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
font-display: block;
|
||||
src: url("../webfonts/fa-light-300.woff2") format("woff2");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Font Awesome 6 Pro';
|
||||
font-style: normal;
|
||||
font-weight: 100;
|
||||
font-display: block;
|
||||
src: url("../webfonts/fa-thin-100.woff2") format("woff2");
|
||||
}
|
||||
|
||||
/* Font Awesome 6 Duotone */
|
||||
@font-face {
|
||||
font-family: 'Font Awesome 6 Duotone';
|
||||
font-style: normal;
|
||||
font-weight: 900;
|
||||
font-display: block;
|
||||
src: url("../webfonts/fa-duotone-900.woff2") format("woff2");
|
||||
}
|
||||
|
||||
/* Font Awesome 6 Sharp */
|
||||
@font-face {
|
||||
font-family: 'Font Awesome 6 Sharp';
|
||||
font-style: normal;
|
||||
font-weight: 900;
|
||||
font-display: block;
|
||||
src: url("../webfonts/fa-sharp-solid-900.woff2") format("woff2");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Font Awesome 6 Sharp';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: block;
|
||||
src: url("../webfonts/fa-sharp-regular-400.woff2") format("woff2");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Font Awesome 6 Sharp';
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
font-display: block;
|
||||
src: url("../webfonts/fa-sharp-light-300.woff2") format("woff2");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Font Awesome 6 Sharp';
|
||||
font-style: normal;
|
||||
font-weight: 100;
|
||||
font-display: block;
|
||||
src: url("../webfonts/fa-sharp-thin-100.woff2") format("woff2");
|
||||
}
|
||||
|
||||
/* Font Awesome 6 Brands */
|
||||
@font-face {
|
||||
font-family: 'Font Awesome 6 Brands';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: block;
|
||||
src: url("../webfonts/fa-brands-400.woff2") format("woff2");
|
||||
}
|
||||
|
||||
/* Reglas de clase */
|
||||
.fas {
|
||||
font-family: 'Font Awesome 6 Pro';
|
||||
font-weight: 900;
|
||||
}
|
||||
.far {
|
||||
font-family: 'Font Awesome 6 Pro';
|
||||
font-weight: 400;
|
||||
}
|
||||
.fal {
|
||||
font-family: 'Font Awesome 6 Pro';
|
||||
font-weight: 300;
|
||||
}
|
||||
.fat {
|
||||
font-family: 'Font Awesome 6 Pro';
|
||||
font-weight: 100;
|
||||
}
|
||||
.fad {
|
||||
font-family: 'Font Awesome 6 Duotone';
|
||||
font-weight: 900;
|
||||
}
|
||||
.fass {
|
||||
font-family: 'Font Awesome 6 Sharp';
|
||||
font-weight: 900;
|
||||
}
|
||||
.fasr {
|
||||
font-family: 'Font Awesome 6 Sharp';
|
||||
font-weight: 400;
|
||||
}
|
||||
.fasl {
|
||||
font-family: 'Font Awesome 6 Sharp';
|
||||
font-weight: 300;
|
||||
}
|
||||
.fast {
|
||||
font-family: 'Font Awesome 6 Sharp';
|
||||
font-weight: 100;
|
||||
}
|
||||
.fab {
|
||||
font-family: 'Font Awesome 6 Brands';
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
/* Variables para Duotone */
|
||||
.fad, .fasd {
|
||||
--fa-primary-color: currentColor;
|
||||
--fa-secondary-color: rgba(0, 0, 0, 0.4);
|
||||
--fa-primary-opacity: 1;
|
||||
--fa-secondary-opacity: 0.4;
|
||||
}
|
||||
12
assets/fontawesome/css/all.min.css
vendored
Normal file
12
assets/fontawesome/css/all.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
9
assets/fontawesome/css/fontawesome.min.css
vendored
Normal file
9
assets/fontawesome/css/fontawesome.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
377398
assets/fontawesome/metadata/icons.json
Normal file
377398
assets/fontawesome/metadata/icons.json
Normal file
File diff suppressed because one or more lines are too long
BIN
assets/fontawesome/webfonts/fa-brands-400.woff2
Normal file
BIN
assets/fontawesome/webfonts/fa-brands-400.woff2
Normal file
Binary file not shown.
BIN
assets/fontawesome/webfonts/fa-duotone-900.woff2
Normal file
BIN
assets/fontawesome/webfonts/fa-duotone-900.woff2
Normal file
Binary file not shown.
BIN
assets/fontawesome/webfonts/fa-light-300.woff2
Normal file
BIN
assets/fontawesome/webfonts/fa-light-300.woff2
Normal file
Binary file not shown.
BIN
assets/fontawesome/webfonts/fa-regular-400.woff2
Normal file
BIN
assets/fontawesome/webfonts/fa-regular-400.woff2
Normal file
Binary file not shown.
BIN
assets/fontawesome/webfonts/fa-sharp-light-300.woff2
Normal file
BIN
assets/fontawesome/webfonts/fa-sharp-light-300.woff2
Normal file
Binary file not shown.
BIN
assets/fontawesome/webfonts/fa-sharp-regular-400.woff2
Normal file
BIN
assets/fontawesome/webfonts/fa-sharp-regular-400.woff2
Normal file
Binary file not shown.
BIN
assets/fontawesome/webfonts/fa-sharp-solid-900.woff2
Normal file
BIN
assets/fontawesome/webfonts/fa-sharp-solid-900.woff2
Normal file
Binary file not shown.
BIN
assets/fontawesome/webfonts/fa-sharp-thin-100.woff2
Normal file
BIN
assets/fontawesome/webfonts/fa-sharp-thin-100.woff2
Normal file
Binary file not shown.
BIN
assets/fontawesome/webfonts/fa-solid-900.woff2
Normal file
BIN
assets/fontawesome/webfonts/fa-solid-900.woff2
Normal file
Binary file not shown.
BIN
assets/fontawesome/webfonts/fa-thin-100.woff2
Normal file
BIN
assets/fontawesome/webfonts/fa-thin-100.woff2
Normal file
Binary file not shown.
BIN
assets/fontawesome/webfonts/fa-v4compatibility.woff2
Normal file
BIN
assets/fontawesome/webfonts/fa-v4compatibility.woff2
Normal file
Binary file not shown.
105
assets/icons.json
Normal file
105
assets/icons.json
Normal file
@@ -0,0 +1,105 @@
|
||||
{
|
||||
"meta": {
|
||||
"generated": "2025-12-15T04:11:59.773Z",
|
||||
"fontawesomeVersion": "6.0.0",
|
||||
"pluginVersion": "2.0.0",
|
||||
"totalIcons": 2,
|
||||
"totalCategories": 3,
|
||||
"detectedStyles": 3,
|
||||
"proIcons": 2,
|
||||
"freeIcons": 0,
|
||||
"note": "BASE DE DATOS DE EJEMPLO - Ejecuta 'npm run build' para generar la versión completa"
|
||||
},
|
||||
"icons": [
|
||||
{
|
||||
"id": "home",
|
||||
"name": "home",
|
||||
"label": "Home",
|
||||
"categories": [
|
||||
"household",
|
||||
"buildings"
|
||||
],
|
||||
"styles": [
|
||||
"solid",
|
||||
"regular",
|
||||
"light"
|
||||
],
|
||||
"searchTerms": [
|
||||
"casa",
|
||||
"hogar",
|
||||
"inicio"
|
||||
],
|
||||
"unicode": "f015",
|
||||
"version": "6.0.0",
|
||||
"free": true,
|
||||
"pro": true
|
||||
},
|
||||
{
|
||||
"id": "user",
|
||||
"name": "user",
|
||||
"label": "User",
|
||||
"categories": [
|
||||
"users-people"
|
||||
],
|
||||
"styles": [
|
||||
"solid",
|
||||
"regular"
|
||||
],
|
||||
"searchTerms": [
|
||||
"persona",
|
||||
"perfil",
|
||||
"cuenta"
|
||||
],
|
||||
"unicode": "f007",
|
||||
"version": "6.0.0",
|
||||
"free": true,
|
||||
"pro": true
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
{
|
||||
"id": "all",
|
||||
"name": "Todos los Íconos",
|
||||
"icon": "fas fa-th",
|
||||
"count": 2,
|
||||
"type": "special"
|
||||
},
|
||||
{
|
||||
"id": "household",
|
||||
"name": "Hogar",
|
||||
"icon": "fas fa-home",
|
||||
"count": 1,
|
||||
"type": "fontawesome"
|
||||
},
|
||||
{
|
||||
"id": "users-people",
|
||||
"name": "Personas",
|
||||
"icon": "fas fa-user",
|
||||
"count": 1,
|
||||
"type": "fontawesome"
|
||||
}
|
||||
],
|
||||
"styles": [
|
||||
{
|
||||
"id": "solid",
|
||||
"name": "Solid",
|
||||
"prefix": "fas",
|
||||
"class": "fas",
|
||||
"available": true
|
||||
},
|
||||
{
|
||||
"id": "regular",
|
||||
"name": "Regular",
|
||||
"prefix": "far",
|
||||
"class": "far",
|
||||
"available": true
|
||||
},
|
||||
{
|
||||
"id": "light",
|
||||
"name": "Light",
|
||||
"prefix": "fal",
|
||||
"class": "fal",
|
||||
"available": true
|
||||
}
|
||||
]
|
||||
}
|
||||
105
assets/processed/backup/2025-12-15T04-11-57-202Z/categories.json
Normal file
105
assets/processed/backup/2025-12-15T04-11-57-202Z/categories.json
Normal file
@@ -0,0 +1,105 @@
|
||||
{
|
||||
"meta": {
|
||||
"generated": "2025-12-15T04:03:05.442Z",
|
||||
"totalCategories": 4,
|
||||
"fontawesomeCategories": 1
|
||||
},
|
||||
"categories": [
|
||||
{
|
||||
"id": "favorites",
|
||||
"name": "Favoritos",
|
||||
"icon": "fas fa-star",
|
||||
"count": 0,
|
||||
"type": "special"
|
||||
},
|
||||
{
|
||||
"id": "recent",
|
||||
"name": "Recientes",
|
||||
"icon": "fas fa-history",
|
||||
"count": 0,
|
||||
"type": "special"
|
||||
},
|
||||
{
|
||||
"id": "all",
|
||||
"name": "Todos los Íconos",
|
||||
"icon": "fas fa-th",
|
||||
"count": 3787,
|
||||
"type": "special"
|
||||
},
|
||||
{
|
||||
"id": "uncategorized",
|
||||
"name": "Sin Categoría",
|
||||
"icon": "fas fa-folder",
|
||||
"count": 3787,
|
||||
"type": "fontawesome"
|
||||
}
|
||||
],
|
||||
"mapping": {
|
||||
"accessibility": "Accesibilidad",
|
||||
"alert": "Alertas",
|
||||
"animals": "Animales",
|
||||
"arrows": "Flechas",
|
||||
"automotive": "Automotriz",
|
||||
"buildings": "Edificios",
|
||||
"business": "Negocios",
|
||||
"camping": "Camping",
|
||||
"charity": "Caridad",
|
||||
"charts-diagrams": "Gráficos",
|
||||
"childhood": "Infancia",
|
||||
"clothing-fashion": "Ropa & Moda",
|
||||
"coding": "Programación",
|
||||
"communication": "Comunicación",
|
||||
"connectivity": "Conectividad",
|
||||
"construction": "Construcción",
|
||||
"design": "Diseño",
|
||||
"devices-hardware": "Dispositivos",
|
||||
"document": "Documentos",
|
||||
"editing": "Edición",
|
||||
"education": "Educación",
|
||||
"emoji": "Emoji",
|
||||
"energy": "Energía",
|
||||
"files": "Archivos",
|
||||
"film-video": "Video",
|
||||
"food-beverage": "Comida",
|
||||
"fruits-vegetables": "Frutas",
|
||||
"gaming": "Juegos",
|
||||
"gender": "Género",
|
||||
"halloween": "Halloween",
|
||||
"hands": "Manos",
|
||||
"holidays": "Fiestas",
|
||||
"household": "Hogar",
|
||||
"humanitarian": "Humanitario",
|
||||
"logistics": "Logística",
|
||||
"maps": "Mapas",
|
||||
"maritime": "Marítimo",
|
||||
"marketing": "Marketing",
|
||||
"mathematics": "Matemáticas",
|
||||
"medical-health": "Salud",
|
||||
"money": "Dinero",
|
||||
"moving": "Mudanza",
|
||||
"music-audio": "Música",
|
||||
"nature": "Naturaleza",
|
||||
"numbers": "Números",
|
||||
"photos-images": "Fotos",
|
||||
"political": "Política",
|
||||
"punctuation-symbols": "Símbolos",
|
||||
"religion": "Religión",
|
||||
"science": "Ciencia",
|
||||
"science-fiction": "Sci-Fi",
|
||||
"security": "Seguridad",
|
||||
"shapes": "Formas",
|
||||
"shopping": "Compras",
|
||||
"social": "Social",
|
||||
"spinners": "Spinners",
|
||||
"sports-fitness": "Deportes",
|
||||
"text-formatting": "Texto",
|
||||
"time": "Tiempo",
|
||||
"toggle": "Toggle",
|
||||
"transportation": "Transporte",
|
||||
"travel": "Viajes",
|
||||
"users-people": "Personas",
|
||||
"weather": "Clima",
|
||||
"writing": "Escritura",
|
||||
"uncategorized": "Sin Categoría"
|
||||
}
|
||||
}
|
||||
143138
assets/processed/backup/2025-12-15T04-11-57-202Z/metadata.json
Normal file
143138
assets/processed/backup/2025-12-15T04-11-57-202Z/metadata.json
Normal file
File diff suppressed because it is too large
Load Diff
230
assets/processed/backup/2025-12-15T04-11-57-202Z/styles.json
Normal file
230
assets/processed/backup/2025-12-15T04-11-57-202Z/styles.json
Normal file
@@ -0,0 +1,230 @@
|
||||
{
|
||||
"meta": {
|
||||
"generated": "2025-12-15T04:03:05.375Z",
|
||||
"totalStyles": 11,
|
||||
"stylesWithIcons": 6
|
||||
},
|
||||
"styles": {
|
||||
"solid": {
|
||||
"id": "solid",
|
||||
"name": "Solid",
|
||||
"prefix": "fas",
|
||||
"class": "fas",
|
||||
"weight": 900,
|
||||
"pro": true,
|
||||
"sharp": false,
|
||||
"family": "Font Awesome 6 Pro",
|
||||
"file": "fa-solid-900.woff2",
|
||||
"count": 3301,
|
||||
"availableInMetadata": true,
|
||||
"percentage": "87.2"
|
||||
},
|
||||
"regular": {
|
||||
"id": "regular",
|
||||
"name": "Regular",
|
||||
"prefix": "far",
|
||||
"class": "far",
|
||||
"weight": 400,
|
||||
"pro": true,
|
||||
"sharp": false,
|
||||
"family": "Font Awesome 6 Pro",
|
||||
"file": "fa-regular-400.woff2",
|
||||
"count": 3301,
|
||||
"availableInMetadata": true,
|
||||
"percentage": "87.2"
|
||||
},
|
||||
"light": {
|
||||
"id": "light",
|
||||
"name": "Light",
|
||||
"prefix": "fal",
|
||||
"class": "fal",
|
||||
"weight": 300,
|
||||
"pro": true,
|
||||
"sharp": false,
|
||||
"family": "Font Awesome 6 Pro",
|
||||
"file": "fa-light-300.woff2",
|
||||
"count": 3301,
|
||||
"availableInMetadata": true,
|
||||
"percentage": "87.2"
|
||||
},
|
||||
"thin": {
|
||||
"id": "thin",
|
||||
"name": "Thin",
|
||||
"prefix": "fat",
|
||||
"class": "fat",
|
||||
"weight": 100,
|
||||
"pro": true,
|
||||
"sharp": false,
|
||||
"family": "Font Awesome 6 Pro",
|
||||
"file": "fa-thin-100.woff2",
|
||||
"count": 3301,
|
||||
"availableInMetadata": true,
|
||||
"percentage": "87.2"
|
||||
},
|
||||
"duotone": {
|
||||
"id": "duotone",
|
||||
"name": "Duotone",
|
||||
"prefix": "fad",
|
||||
"class": "fad",
|
||||
"weight": 900,
|
||||
"pro": true,
|
||||
"sharp": false,
|
||||
"family": "Font Awesome 6 Duotone",
|
||||
"file": "fa-duotone-900.woff2",
|
||||
"count": 3301,
|
||||
"availableInMetadata": true,
|
||||
"percentage": "87.2"
|
||||
},
|
||||
"sharp-solid": {
|
||||
"id": "sharp-solid",
|
||||
"name": "Sharp Solid",
|
||||
"prefix": "fass",
|
||||
"class": "fass",
|
||||
"weight": 900,
|
||||
"pro": true,
|
||||
"sharp": true,
|
||||
"family": "Font Awesome 6 Sharp",
|
||||
"file": "fa-sharp-solid-900.woff2",
|
||||
"count": 0,
|
||||
"availableInMetadata": false,
|
||||
"percentage": "0.0"
|
||||
},
|
||||
"sharp-regular": {
|
||||
"id": "sharp-regular",
|
||||
"name": "Sharp Regular",
|
||||
"prefix": "fasr",
|
||||
"class": "fasr",
|
||||
"weight": 400,
|
||||
"pro": true,
|
||||
"sharp": true,
|
||||
"family": "Font Awesome 6 Sharp",
|
||||
"file": "fa-sharp-regular-400.woff2",
|
||||
"count": 0,
|
||||
"availableInMetadata": false,
|
||||
"percentage": "0.0"
|
||||
},
|
||||
"sharp-light": {
|
||||
"id": "sharp-light",
|
||||
"name": "Sharp Light",
|
||||
"prefix": "fasl",
|
||||
"class": "fasl",
|
||||
"weight": 300,
|
||||
"pro": true,
|
||||
"sharp": true,
|
||||
"family": "Font Awesome 6 Sharp",
|
||||
"file": "fa-sharp-light-300.woff2",
|
||||
"count": 0,
|
||||
"availableInMetadata": false,
|
||||
"percentage": "0.0"
|
||||
},
|
||||
"sharp-thin": {
|
||||
"id": "sharp-thin",
|
||||
"name": "Sharp Thin",
|
||||
"prefix": "fast",
|
||||
"class": "fast",
|
||||
"weight": 100,
|
||||
"pro": true,
|
||||
"sharp": true,
|
||||
"family": "Font Awesome 6 Sharp",
|
||||
"file": "fa-sharp-thin-100.woff2",
|
||||
"count": 0,
|
||||
"availableInMetadata": false,
|
||||
"percentage": "0.0"
|
||||
},
|
||||
"sharp-duotone": {
|
||||
"id": "sharp-duotone",
|
||||
"name": "Sharp Duotone",
|
||||
"prefix": "fasd",
|
||||
"class": "fasd",
|
||||
"weight": 900,
|
||||
"pro": true,
|
||||
"sharp": true,
|
||||
"family": "Font Awesome 6 Sharp Duotone",
|
||||
"file": "fa-sharp-duotone-900.woff2",
|
||||
"count": 0,
|
||||
"availableInMetadata": false,
|
||||
"percentage": "0.0"
|
||||
},
|
||||
"brands": {
|
||||
"id": "brands",
|
||||
"name": "Brands",
|
||||
"prefix": "fab",
|
||||
"class": "fab",
|
||||
"weight": 400,
|
||||
"pro": false,
|
||||
"sharp": false,
|
||||
"family": "Font Awesome 6 Brands",
|
||||
"file": "fa-brands-400.woff2",
|
||||
"count": 490,
|
||||
"availableInMetadata": true,
|
||||
"percentage": "12.9"
|
||||
}
|
||||
},
|
||||
"statistics": {
|
||||
"totalIconsByStyle": {
|
||||
"solid": 3301,
|
||||
"regular": 3301,
|
||||
"light": 3301,
|
||||
"thin": 3301,
|
||||
"duotone": 3301,
|
||||
"brands": 490
|
||||
},
|
||||
"styleCoverage": {
|
||||
"solid": {
|
||||
"hasIcons": true,
|
||||
"count": 3301,
|
||||
"percentage": "87.2"
|
||||
},
|
||||
"regular": {
|
||||
"hasIcons": true,
|
||||
"count": 3301,
|
||||
"percentage": "87.2"
|
||||
},
|
||||
"light": {
|
||||
"hasIcons": true,
|
||||
"count": 3301,
|
||||
"percentage": "87.2"
|
||||
},
|
||||
"thin": {
|
||||
"hasIcons": true,
|
||||
"count": 3301,
|
||||
"percentage": "87.2"
|
||||
},
|
||||
"duotone": {
|
||||
"hasIcons": true,
|
||||
"count": 3301,
|
||||
"percentage": "87.2"
|
||||
},
|
||||
"sharp-solid": {
|
||||
"hasIcons": false,
|
||||
"count": 0,
|
||||
"percentage": "0.0"
|
||||
},
|
||||
"sharp-regular": {
|
||||
"hasIcons": false,
|
||||
"count": 0,
|
||||
"percentage": "0.0"
|
||||
},
|
||||
"sharp-light": {
|
||||
"hasIcons": false,
|
||||
"count": 0,
|
||||
"percentage": "0.0"
|
||||
},
|
||||
"sharp-thin": {
|
||||
"hasIcons": false,
|
||||
"count": 0,
|
||||
"percentage": "0.0"
|
||||
},
|
||||
"sharp-duotone": {
|
||||
"hasIcons": false,
|
||||
"count": 0,
|
||||
"percentage": "0.0"
|
||||
},
|
||||
"brands": {
|
||||
"hasIcons": true,
|
||||
"count": 490,
|
||||
"percentage": "12.9"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
105
assets/processed/categories.json
Normal file
105
assets/processed/categories.json
Normal file
@@ -0,0 +1,105 @@
|
||||
{
|
||||
"meta": {
|
||||
"generated": "2025-12-15T04:11:58.708Z",
|
||||
"totalCategories": 4,
|
||||
"fontawesomeCategories": 1
|
||||
},
|
||||
"categories": [
|
||||
{
|
||||
"id": "favorites",
|
||||
"name": "Favoritos",
|
||||
"icon": "fas fa-star",
|
||||
"count": 0,
|
||||
"type": "special"
|
||||
},
|
||||
{
|
||||
"id": "recent",
|
||||
"name": "Recientes",
|
||||
"icon": "fas fa-history",
|
||||
"count": 0,
|
||||
"type": "special"
|
||||
},
|
||||
{
|
||||
"id": "all",
|
||||
"name": "Todos los Íconos",
|
||||
"icon": "fas fa-th",
|
||||
"count": 3787,
|
||||
"type": "special"
|
||||
},
|
||||
{
|
||||
"id": "uncategorized",
|
||||
"name": "Sin Categoría",
|
||||
"icon": "fas fa-folder",
|
||||
"count": 3787,
|
||||
"type": "fontawesome"
|
||||
}
|
||||
],
|
||||
"mapping": {
|
||||
"accessibility": "Accesibilidad",
|
||||
"alert": "Alertas",
|
||||
"animals": "Animales",
|
||||
"arrows": "Flechas",
|
||||
"automotive": "Automotriz",
|
||||
"buildings": "Edificios",
|
||||
"business": "Negocios",
|
||||
"camping": "Camping",
|
||||
"charity": "Caridad",
|
||||
"charts-diagrams": "Gráficos",
|
||||
"childhood": "Infancia",
|
||||
"clothing-fashion": "Ropa & Moda",
|
||||
"coding": "Programación",
|
||||
"communication": "Comunicación",
|
||||
"connectivity": "Conectividad",
|
||||
"construction": "Construcción",
|
||||
"design": "Diseño",
|
||||
"devices-hardware": "Dispositivos",
|
||||
"document": "Documentos",
|
||||
"editing": "Edición",
|
||||
"education": "Educación",
|
||||
"emoji": "Emoji",
|
||||
"energy": "Energía",
|
||||
"files": "Archivos",
|
||||
"film-video": "Video",
|
||||
"food-beverage": "Comida",
|
||||
"fruits-vegetables": "Frutas",
|
||||
"gaming": "Juegos",
|
||||
"gender": "Género",
|
||||
"halloween": "Halloween",
|
||||
"hands": "Manos",
|
||||
"holidays": "Fiestas",
|
||||
"household": "Hogar",
|
||||
"humanitarian": "Humanitario",
|
||||
"logistics": "Logística",
|
||||
"maps": "Mapas",
|
||||
"maritime": "Marítimo",
|
||||
"marketing": "Marketing",
|
||||
"mathematics": "Matemáticas",
|
||||
"medical-health": "Salud",
|
||||
"money": "Dinero",
|
||||
"moving": "Mudanza",
|
||||
"music-audio": "Música",
|
||||
"nature": "Naturaleza",
|
||||
"numbers": "Números",
|
||||
"photos-images": "Fotos",
|
||||
"political": "Política",
|
||||
"punctuation-symbols": "Símbolos",
|
||||
"religion": "Religión",
|
||||
"science": "Ciencia",
|
||||
"science-fiction": "Sci-Fi",
|
||||
"security": "Seguridad",
|
||||
"shapes": "Formas",
|
||||
"shopping": "Compras",
|
||||
"social": "Social",
|
||||
"spinners": "Spinners",
|
||||
"sports-fitness": "Deportes",
|
||||
"text-formatting": "Texto",
|
||||
"time": "Tiempo",
|
||||
"toggle": "Toggle",
|
||||
"transportation": "Transporte",
|
||||
"travel": "Viajes",
|
||||
"users-people": "Personas",
|
||||
"weather": "Clima",
|
||||
"writing": "Escritura",
|
||||
"uncategorized": "Sin Categoría"
|
||||
}
|
||||
}
|
||||
88
assets/processed/logs/report-2025-12-15T04-03-05-443Z.json
Normal file
88
assets/processed/logs/report-2025-12-15T04-03-05-443Z.json
Normal file
@@ -0,0 +1,88 @@
|
||||
{
|
||||
"meta": {
|
||||
"generated": "2025-12-15T04:03:05.444Z",
|
||||
"version": "2.0.0",
|
||||
"duration": 2744
|
||||
},
|
||||
"summary": {
|
||||
"totalIcons": 3787,
|
||||
"totalStyles": 11,
|
||||
"stylesWithIcons": 6,
|
||||
"totalCategories": 4
|
||||
},
|
||||
"files": {
|
||||
"metadata": "/home/monitor/Documents/Development/logseq-fontawesome-pro/assets/processed/metadata.json",
|
||||
"styles": "/home/monitor/Documents/Development/logseq-fontawesome-pro/assets/processed/styles.json",
|
||||
"categories": "/home/monitor/Documents/Development/logseq-fontawesome-pro/assets/processed/categories.json"
|
||||
},
|
||||
"statistics": {
|
||||
"iconsPerStyle": {
|
||||
"solid": 3301,
|
||||
"regular": 3301,
|
||||
"light": 3301,
|
||||
"thin": 3301,
|
||||
"duotone": 3301,
|
||||
"brands": 490
|
||||
},
|
||||
"iconsPerCategory": {
|
||||
"uncategorized": 3787
|
||||
},
|
||||
"styleCoverage": {
|
||||
"solid": {
|
||||
"hasIcons": true,
|
||||
"count": 3301,
|
||||
"percentage": "87.2"
|
||||
},
|
||||
"regular": {
|
||||
"hasIcons": true,
|
||||
"count": 3301,
|
||||
"percentage": "87.2"
|
||||
},
|
||||
"light": {
|
||||
"hasIcons": true,
|
||||
"count": 3301,
|
||||
"percentage": "87.2"
|
||||
},
|
||||
"thin": {
|
||||
"hasIcons": true,
|
||||
"count": 3301,
|
||||
"percentage": "87.2"
|
||||
},
|
||||
"duotone": {
|
||||
"hasIcons": true,
|
||||
"count": 3301,
|
||||
"percentage": "87.2"
|
||||
},
|
||||
"sharp-solid": {
|
||||
"hasIcons": false,
|
||||
"count": 0,
|
||||
"percentage": "0.0"
|
||||
},
|
||||
"sharp-regular": {
|
||||
"hasIcons": false,
|
||||
"count": 0,
|
||||
"percentage": "0.0"
|
||||
},
|
||||
"sharp-light": {
|
||||
"hasIcons": false,
|
||||
"count": 0,
|
||||
"percentage": "0.0"
|
||||
},
|
||||
"sharp-thin": {
|
||||
"hasIcons": false,
|
||||
"count": 0,
|
||||
"percentage": "0.0"
|
||||
},
|
||||
"sharp-duotone": {
|
||||
"hasIcons": false,
|
||||
"count": 0,
|
||||
"percentage": "0.0"
|
||||
},
|
||||
"brands": {
|
||||
"hasIcons": true,
|
||||
"count": 490,
|
||||
"percentage": "12.9"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
88
assets/processed/logs/report-2025-12-15T04-11-58-710Z.json
Normal file
88
assets/processed/logs/report-2025-12-15T04-11-58-710Z.json
Normal file
@@ -0,0 +1,88 @@
|
||||
{
|
||||
"meta": {
|
||||
"generated": "2025-12-15T04:11:58.710Z",
|
||||
"version": "2.0.0",
|
||||
"duration": 2553
|
||||
},
|
||||
"summary": {
|
||||
"totalIcons": 3787,
|
||||
"totalStyles": 11,
|
||||
"stylesWithIcons": 6,
|
||||
"totalCategories": 4
|
||||
},
|
||||
"files": {
|
||||
"metadata": "/home/monitor/Documents/Development/logseq-fontawesome-pro/assets/processed/metadata.json",
|
||||
"styles": "/home/monitor/Documents/Development/logseq-fontawesome-pro/assets/processed/styles.json",
|
||||
"categories": "/home/monitor/Documents/Development/logseq-fontawesome-pro/assets/processed/categories.json"
|
||||
},
|
||||
"statistics": {
|
||||
"iconsPerStyle": {
|
||||
"solid": 3301,
|
||||
"regular": 3301,
|
||||
"light": 3301,
|
||||
"thin": 3301,
|
||||
"duotone": 3301,
|
||||
"brands": 490
|
||||
},
|
||||
"iconsPerCategory": {
|
||||
"uncategorized": 3787
|
||||
},
|
||||
"styleCoverage": {
|
||||
"solid": {
|
||||
"hasIcons": true,
|
||||
"count": 3301,
|
||||
"percentage": "87.2"
|
||||
},
|
||||
"regular": {
|
||||
"hasIcons": true,
|
||||
"count": 3301,
|
||||
"percentage": "87.2"
|
||||
},
|
||||
"light": {
|
||||
"hasIcons": true,
|
||||
"count": 3301,
|
||||
"percentage": "87.2"
|
||||
},
|
||||
"thin": {
|
||||
"hasIcons": true,
|
||||
"count": 3301,
|
||||
"percentage": "87.2"
|
||||
},
|
||||
"duotone": {
|
||||
"hasIcons": true,
|
||||
"count": 3301,
|
||||
"percentage": "87.2"
|
||||
},
|
||||
"sharp-solid": {
|
||||
"hasIcons": false,
|
||||
"count": 0,
|
||||
"percentage": "0.0"
|
||||
},
|
||||
"sharp-regular": {
|
||||
"hasIcons": false,
|
||||
"count": 0,
|
||||
"percentage": "0.0"
|
||||
},
|
||||
"sharp-light": {
|
||||
"hasIcons": false,
|
||||
"count": 0,
|
||||
"percentage": "0.0"
|
||||
},
|
||||
"sharp-thin": {
|
||||
"hasIcons": false,
|
||||
"count": 0,
|
||||
"percentage": "0.0"
|
||||
},
|
||||
"sharp-duotone": {
|
||||
"hasIcons": false,
|
||||
"count": 0,
|
||||
"percentage": "0.0"
|
||||
},
|
||||
"brands": {
|
||||
"hasIcons": true,
|
||||
"count": 490,
|
||||
"percentage": "12.9"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
143138
assets/processed/metadata.json
Normal file
143138
assets/processed/metadata.json
Normal file
File diff suppressed because it is too large
Load Diff
230
assets/processed/styles.json
Normal file
230
assets/processed/styles.json
Normal file
@@ -0,0 +1,230 @@
|
||||
{
|
||||
"meta": {
|
||||
"generated": "2025-12-15T04:11:58.654Z",
|
||||
"totalStyles": 11,
|
||||
"stylesWithIcons": 6
|
||||
},
|
||||
"styles": {
|
||||
"solid": {
|
||||
"id": "solid",
|
||||
"name": "Solid",
|
||||
"prefix": "fas",
|
||||
"class": "fas",
|
||||
"weight": 900,
|
||||
"pro": true,
|
||||
"sharp": false,
|
||||
"family": "Font Awesome 6 Pro",
|
||||
"file": "fa-solid-900.woff2",
|
||||
"count": 3301,
|
||||
"availableInMetadata": true,
|
||||
"percentage": "87.2"
|
||||
},
|
||||
"regular": {
|
||||
"id": "regular",
|
||||
"name": "Regular",
|
||||
"prefix": "far",
|
||||
"class": "far",
|
||||
"weight": 400,
|
||||
"pro": true,
|
||||
"sharp": false,
|
||||
"family": "Font Awesome 6 Pro",
|
||||
"file": "fa-regular-400.woff2",
|
||||
"count": 3301,
|
||||
"availableInMetadata": true,
|
||||
"percentage": "87.2"
|
||||
},
|
||||
"light": {
|
||||
"id": "light",
|
||||
"name": "Light",
|
||||
"prefix": "fal",
|
||||
"class": "fal",
|
||||
"weight": 300,
|
||||
"pro": true,
|
||||
"sharp": false,
|
||||
"family": "Font Awesome 6 Pro",
|
||||
"file": "fa-light-300.woff2",
|
||||
"count": 3301,
|
||||
"availableInMetadata": true,
|
||||
"percentage": "87.2"
|
||||
},
|
||||
"thin": {
|
||||
"id": "thin",
|
||||
"name": "Thin",
|
||||
"prefix": "fat",
|
||||
"class": "fat",
|
||||
"weight": 100,
|
||||
"pro": true,
|
||||
"sharp": false,
|
||||
"family": "Font Awesome 6 Pro",
|
||||
"file": "fa-thin-100.woff2",
|
||||
"count": 3301,
|
||||
"availableInMetadata": true,
|
||||
"percentage": "87.2"
|
||||
},
|
||||
"duotone": {
|
||||
"id": "duotone",
|
||||
"name": "Duotone",
|
||||
"prefix": "fad",
|
||||
"class": "fad",
|
||||
"weight": 900,
|
||||
"pro": true,
|
||||
"sharp": false,
|
||||
"family": "Font Awesome 6 Duotone",
|
||||
"file": "fa-duotone-900.woff2",
|
||||
"count": 3301,
|
||||
"availableInMetadata": true,
|
||||
"percentage": "87.2"
|
||||
},
|
||||
"sharp-solid": {
|
||||
"id": "sharp-solid",
|
||||
"name": "Sharp Solid",
|
||||
"prefix": "fass",
|
||||
"class": "fass",
|
||||
"weight": 900,
|
||||
"pro": true,
|
||||
"sharp": true,
|
||||
"family": "Font Awesome 6 Sharp",
|
||||
"file": "fa-sharp-solid-900.woff2",
|
||||
"count": 0,
|
||||
"availableInMetadata": false,
|
||||
"percentage": "0.0"
|
||||
},
|
||||
"sharp-regular": {
|
||||
"id": "sharp-regular",
|
||||
"name": "Sharp Regular",
|
||||
"prefix": "fasr",
|
||||
"class": "fasr",
|
||||
"weight": 400,
|
||||
"pro": true,
|
||||
"sharp": true,
|
||||
"family": "Font Awesome 6 Sharp",
|
||||
"file": "fa-sharp-regular-400.woff2",
|
||||
"count": 0,
|
||||
"availableInMetadata": false,
|
||||
"percentage": "0.0"
|
||||
},
|
||||
"sharp-light": {
|
||||
"id": "sharp-light",
|
||||
"name": "Sharp Light",
|
||||
"prefix": "fasl",
|
||||
"class": "fasl",
|
||||
"weight": 300,
|
||||
"pro": true,
|
||||
"sharp": true,
|
||||
"family": "Font Awesome 6 Sharp",
|
||||
"file": "fa-sharp-light-300.woff2",
|
||||
"count": 0,
|
||||
"availableInMetadata": false,
|
||||
"percentage": "0.0"
|
||||
},
|
||||
"sharp-thin": {
|
||||
"id": "sharp-thin",
|
||||
"name": "Sharp Thin",
|
||||
"prefix": "fast",
|
||||
"class": "fast",
|
||||
"weight": 100,
|
||||
"pro": true,
|
||||
"sharp": true,
|
||||
"family": "Font Awesome 6 Sharp",
|
||||
"file": "fa-sharp-thin-100.woff2",
|
||||
"count": 0,
|
||||
"availableInMetadata": false,
|
||||
"percentage": "0.0"
|
||||
},
|
||||
"sharp-duotone": {
|
||||
"id": "sharp-duotone",
|
||||
"name": "Sharp Duotone",
|
||||
"prefix": "fasd",
|
||||
"class": "fasd",
|
||||
"weight": 900,
|
||||
"pro": true,
|
||||
"sharp": true,
|
||||
"family": "Font Awesome 6 Sharp Duotone",
|
||||
"file": "fa-sharp-duotone-900.woff2",
|
||||
"count": 0,
|
||||
"availableInMetadata": false,
|
||||
"percentage": "0.0"
|
||||
},
|
||||
"brands": {
|
||||
"id": "brands",
|
||||
"name": "Brands",
|
||||
"prefix": "fab",
|
||||
"class": "fab",
|
||||
"weight": 400,
|
||||
"pro": false,
|
||||
"sharp": false,
|
||||
"family": "Font Awesome 6 Brands",
|
||||
"file": "fa-brands-400.woff2",
|
||||
"count": 490,
|
||||
"availableInMetadata": true,
|
||||
"percentage": "12.9"
|
||||
}
|
||||
},
|
||||
"statistics": {
|
||||
"totalIconsByStyle": {
|
||||
"solid": 3301,
|
||||
"regular": 3301,
|
||||
"light": 3301,
|
||||
"thin": 3301,
|
||||
"duotone": 3301,
|
||||
"brands": 490
|
||||
},
|
||||
"styleCoverage": {
|
||||
"solid": {
|
||||
"hasIcons": true,
|
||||
"count": 3301,
|
||||
"percentage": "87.2"
|
||||
},
|
||||
"regular": {
|
||||
"hasIcons": true,
|
||||
"count": 3301,
|
||||
"percentage": "87.2"
|
||||
},
|
||||
"light": {
|
||||
"hasIcons": true,
|
||||
"count": 3301,
|
||||
"percentage": "87.2"
|
||||
},
|
||||
"thin": {
|
||||
"hasIcons": true,
|
||||
"count": 3301,
|
||||
"percentage": "87.2"
|
||||
},
|
||||
"duotone": {
|
||||
"hasIcons": true,
|
||||
"count": 3301,
|
||||
"percentage": "87.2"
|
||||
},
|
||||
"sharp-solid": {
|
||||
"hasIcons": false,
|
||||
"count": 0,
|
||||
"percentage": "0.0"
|
||||
},
|
||||
"sharp-regular": {
|
||||
"hasIcons": false,
|
||||
"count": 0,
|
||||
"percentage": "0.0"
|
||||
},
|
||||
"sharp-light": {
|
||||
"hasIcons": false,
|
||||
"count": 0,
|
||||
"percentage": "0.0"
|
||||
},
|
||||
"sharp-thin": {
|
||||
"hasIcons": false,
|
||||
"count": 0,
|
||||
"percentage": "0.0"
|
||||
},
|
||||
"sharp-duotone": {
|
||||
"hasIcons": false,
|
||||
"count": 0,
|
||||
"percentage": "0.0"
|
||||
},
|
||||
"brands": {
|
||||
"hasIcons": true,
|
||||
"count": 490,
|
||||
"percentage": "12.9"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
105
assets/processed/validation-report.json
Normal file
105
assets/processed/validation-report.json
Normal file
@@ -0,0 +1,105 @@
|
||||
{
|
||||
"meta": {
|
||||
"generated": "2025-12-15T04:11:59.617Z",
|
||||
"version": "2.0.0"
|
||||
},
|
||||
"fontFiles": {
|
||||
"total": 11,
|
||||
"found": 10,
|
||||
"missing": [
|
||||
"fa-sharp-duotone-900.woff2"
|
||||
],
|
||||
"details": {
|
||||
"fa-solid-900.woff2": {
|
||||
"exists": true,
|
||||
"path": "/home/monitor/Documents/Development/logseq-fontawesome-pro/assets/fontawesome/webfonts/fa-solid-900.woff2",
|
||||
"size": 350540
|
||||
},
|
||||
"fa-regular-400.woff2": {
|
||||
"exists": true,
|
||||
"path": "/home/monitor/Documents/Development/logseq-fontawesome-pro/assets/fontawesome/webfonts/fa-regular-400.woff2",
|
||||
"size": 421248
|
||||
},
|
||||
"fa-light-300.woff2": {
|
||||
"exists": true,
|
||||
"path": "/home/monitor/Documents/Development/logseq-fontawesome-pro/assets/fontawesome/webfonts/fa-light-300.woff2",
|
||||
"size": 460556
|
||||
},
|
||||
"fa-thin-100.woff2": {
|
||||
"exists": true,
|
||||
"path": "/home/monitor/Documents/Development/logseq-fontawesome-pro/assets/fontawesome/webfonts/fa-thin-100.woff2",
|
||||
"size": 498828
|
||||
},
|
||||
"fa-duotone-900.woff2": {
|
||||
"exists": true,
|
||||
"path": "/home/monitor/Documents/Development/logseq-fontawesome-pro/assets/fontawesome/webfonts/fa-duotone-900.woff2",
|
||||
"size": 451084
|
||||
},
|
||||
"fa-sharp-solid-900.woff2": {
|
||||
"exists": true,
|
||||
"path": "/home/monitor/Documents/Development/logseq-fontawesome-pro/assets/fontawesome/webfonts/fa-sharp-solid-900.woff2",
|
||||
"size": 283224
|
||||
},
|
||||
"fa-sharp-regular-400.woff2": {
|
||||
"exists": true,
|
||||
"path": "/home/monitor/Documents/Development/logseq-fontawesome-pro/assets/fontawesome/webfonts/fa-sharp-regular-400.woff2",
|
||||
"size": 361060
|
||||
},
|
||||
"fa-sharp-light-300.woff2": {
|
||||
"exists": true,
|
||||
"path": "/home/monitor/Documents/Development/logseq-fontawesome-pro/assets/fontawesome/webfonts/fa-sharp-light-300.woff2",
|
||||
"size": 399468
|
||||
},
|
||||
"fa-sharp-thin-100.woff2": {
|
||||
"exists": true,
|
||||
"path": "/home/monitor/Documents/Development/logseq-fontawesome-pro/assets/fontawesome/webfonts/fa-sharp-thin-100.woff2",
|
||||
"size": 428956
|
||||
},
|
||||
"fa-sharp-duotone-900.woff2": {
|
||||
"exists": false,
|
||||
"path": "/home/monitor/Documents/Development/logseq-fontawesome-pro/assets/fontawesome/webfonts/fa-sharp-duotone-900.woff2",
|
||||
"size": 0
|
||||
},
|
||||
"fa-brands-400.woff2": {
|
||||
"exists": true,
|
||||
"path": "/home/monitor/Documents/Development/logseq-fontawesome-pro/assets/fontawesome/webfonts/fa-brands-400.woff2",
|
||||
"size": 118872
|
||||
}
|
||||
}
|
||||
},
|
||||
"metadata": {
|
||||
"metadata": {
|
||||
"valid": true,
|
||||
"data": {
|
||||
"totalIcons": 3787,
|
||||
"totalStyles": 6,
|
||||
"totalCategories": 1
|
||||
}
|
||||
},
|
||||
"styles": {
|
||||
"valid": true,
|
||||
"data": {
|
||||
"totalStyles": 11,
|
||||
"stylesWithIcons": 6
|
||||
}
|
||||
},
|
||||
"categories": {
|
||||
"valid": true,
|
||||
"data": {
|
||||
"totalCategories": 4,
|
||||
"fontawesomeCategories": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"compatibility": {
|
||||
"issues": [],
|
||||
"status": "OK"
|
||||
},
|
||||
"recommendations": [
|
||||
{
|
||||
"priority": "high",
|
||||
"action": "download_missing_fonts",
|
||||
"message": "Descarga los archivos de fuentes faltantes de FontAwesome Pro"
|
||||
}
|
||||
]
|
||||
}
|
||||
495
assets/styles.css
Normal file
495
assets/styles.css
Normal file
@@ -0,0 +1,495 @@
|
||||
/* ============================================
|
||||
* FontAwesome Pro - Estilos Base para Logseq
|
||||
* Versión: 2.0.0
|
||||
* Generado automáticamente
|
||||
= *=========================================== */
|
||||
|
||||
/* Variables CSS para temas */
|
||||
:root {
|
||||
--fa-primary-color: var(--ls-link-text-color, #0451a5);
|
||||
--fa-secondary-color: var(--ls-secondary-text-color, #666666);
|
||||
--fa-border-radius: 8px;
|
||||
--fa-transition-speed: 0.2s;
|
||||
|
||||
/* Colores específicos para estilos FontAwesome */
|
||||
--fa-solid-color: #000000;
|
||||
--fa-regular-color: #666666;
|
||||
--fa-light-color: #999999;
|
||||
--fa-thin-color: #cccccc;
|
||||
--fa-duotone-primary: #8b5cf6;
|
||||
--fa-duotone-secondary: #ec4899;
|
||||
--fa-sharp-solid-color: #7c3aed;
|
||||
--fa-sharp-regular-color: #8b5cf6;
|
||||
--fa-sharp-light-color: #a78bfa;
|
||||
--fa-sharp-thin-color: #c4b5fd;
|
||||
--fa-brands-color: #1877f2;
|
||||
}
|
||||
|
||||
/* Tema oscuro */
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--fa-solid-color: #ffffff;
|
||||
--fa-regular-color: #cccccc;
|
||||
--fa-light-color: #aaaaaa;
|
||||
--fa-thin-color: #888888;
|
||||
--fa-duotone-primary: #a78bfa;
|
||||
--fa-duotone-secondary: #f472b6;
|
||||
--fa-sharp-solid-color: #a78bfa;
|
||||
--fa-sharp-regular-color: #c4b5fd;
|
||||
--fa-sharp-light-color: #ddd6fe;
|
||||
--fa-sharp-thin-color: #ede9fe;
|
||||
}
|
||||
}
|
||||
|
||||
/* Clases utilitarias para íconos */
|
||||
.fa-icon-xs { font-size: 0.75em !important; }
|
||||
.fa-icon-sm { font-size: 0.875em !important; }
|
||||
.fa-icon-md { font-size: 1em !important; }
|
||||
.fa-icon-lg { font-size: 1.33em !important; }
|
||||
.fa-icon-xl { font-size: 1.75em !important; }
|
||||
.fa-icon-2x { font-size: 2em !important; }
|
||||
.fa-icon-3x { font-size: 3em !important; }
|
||||
.fa-icon-4x { font-size: 4em !important; }
|
||||
.fa-icon-5x { font-size: 5em !important; }
|
||||
|
||||
/* Efectos hover para tarjetas de íconos */
|
||||
.icon-card:hover .fa-icon {
|
||||
transform: scale(1.1);
|
||||
transition: transform var(--fa-transition-speed) ease;
|
||||
}
|
||||
|
||||
/* Estilos para el buscador */
|
||||
.fa-search-highlight {
|
||||
background-color: rgba(var(--ls-link-text-color-rgb, 5, 81, 165), 0.1);
|
||||
border-radius: 2px;
|
||||
padding: 0 2px;
|
||||
}
|
||||
|
||||
/* Indicadores de estilo */
|
||||
.style-indicator {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
margin-right: 4px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.style-indicator.solid { background-color: var(--fa-solid-color); }
|
||||
.style-indicator.regular { background-color: var(--fa-regular-color); }
|
||||
.style-indicator.light { background-color: var(--fa-light-color); }
|
||||
.style-indicator.thin { background-color: var(--fa-thin-color); }
|
||||
.style-indicator.duotone {
|
||||
background: linear-gradient(45deg, var(--fa-duotone-primary), var(--fa-duotone-secondary));
|
||||
}
|
||||
.style-indicator.sharp-solid { background-color: var(--fa-sharp-solid-color); }
|
||||
.style-indicator.sharp-regular { background-color: var(--fa-sharp-regular-color); }
|
||||
.style-indicator.sharp-light { background-color: var(--fa-sharp-light-color); }
|
||||
.style-indicator.sharp-thin { background-color: var(--fa-sharp-thin-color); }
|
||||
.style-indicator.sharp-duotone {
|
||||
background: linear-gradient(45deg, var(--fa-sharp-solid-color), var(--fa-duotone-secondary));
|
||||
}
|
||||
.style-indicator.brands { background-color: var(--fa-brands-color); }
|
||||
|
||||
/* Badges para tarjetas */
|
||||
.fa-badge {
|
||||
position: absolute;
|
||||
top: 6px;
|
||||
right: 6px;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 10px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.fa-badge.favorite {
|
||||
background-color: #ef4444;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.fa-badge.recent {
|
||||
background-color: #f59e0b;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.fa-badge.pro {
|
||||
background-color: #8b5cf6;
|
||||
color: white;
|
||||
font-size: 9px;
|
||||
}
|
||||
|
||||
/* Estilos para categorías */
|
||||
.category-progress {
|
||||
height: 2px;
|
||||
background: var(--ls-border-color);
|
||||
border-radius: 1px;
|
||||
margin-top: 4px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.category-progress-fill {
|
||||
height: 100%;
|
||||
background: var(--ls-link-text-color);
|
||||
border-radius: 1px;
|
||||
transition: width 0.3s ease;
|
||||
}
|
||||
|
||||
/* Selectores de color */
|
||||
.color-swatch {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border-radius: 50%;
|
||||
border: 2px solid var(--ls-border-color);
|
||||
cursor: pointer;
|
||||
transition: all var(--fa-transition-speed);
|
||||
display: inline-block;
|
||||
margin: 2px;
|
||||
}
|
||||
|
||||
.color-swatch:hover {
|
||||
transform: scale(1.1);
|
||||
border-color: var(--ls-link-text-color);
|
||||
}
|
||||
|
||||
.color-swatch.active {
|
||||
border-color: var(--ls-primary-text-color);
|
||||
box-shadow: 0 0 0 2px var(--ls-link-text-color);
|
||||
}
|
||||
|
||||
/* Previsualización de tamaño */
|
||||
.size-preview {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border: 1px solid var(--ls-border-color);
|
||||
border-radius: var(--fa-border-radius);
|
||||
background: var(--ls-secondary-background-color);
|
||||
margin: 2px;
|
||||
cursor: pointer;
|
||||
transition: all var(--fa-transition-speed);
|
||||
}
|
||||
|
||||
.size-preview:hover {
|
||||
border-color: var(--ls-link-text-color);
|
||||
background: var(--ls-tertiary-background-color);
|
||||
}
|
||||
|
||||
.size-preview.active {
|
||||
border-color: var(--ls-link-text-color);
|
||||
background: var(--ls-link-text-color);
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* Animaciones de carga */
|
||||
.fa-loading {
|
||||
display: inline-block;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border: 2px solid var(--ls-border-color);
|
||||
border-radius: 50%;
|
||||
border-top-color: var(--ls-link-text-color);
|
||||
animation: fa-spin 1s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes fa-spin {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
/* Notificaciones */
|
||||
.fa-notification {
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
right: 20px;
|
||||
padding: 12px 16px;
|
||||
background: var(--ls-success-color);
|
||||
color: white;
|
||||
border-radius: 6px;
|
||||
font-size: 13px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
|
||||
z-index: 1000;
|
||||
animation: fa-slide-in 0.3s ease;
|
||||
}
|
||||
|
||||
@keyframes fa-slide-in {
|
||||
from {
|
||||
transform: translateX(100%);
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
transform: translateX(0);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Tooltips */
|
||||
.fa-tooltip {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.fa-tooltip .fa-tooltip-text {
|
||||
visibility: hidden;
|
||||
width: 200px;
|
||||
background-color: var(--ls-primary-background-color);
|
||||
color: var(--ls-primary-text-color);
|
||||
text-align: center;
|
||||
border-radius: 6px;
|
||||
padding: 8px;
|
||||
border: 1px solid var(--ls-border-color);
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
bottom: 125%;
|
||||
left: 50%;
|
||||
margin-left: -100px;
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s;
|
||||
font-size: 12px;
|
||||
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.fa-tooltip:hover .fa-tooltip-text {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* Estados de filtro */
|
||||
.filter-active {
|
||||
background: var(--ls-link-text-color) !important;
|
||||
color: white !important;
|
||||
border-color: var(--ls-link-text-color) !important;
|
||||
}
|
||||
|
||||
.filter-disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed !important;
|
||||
}
|
||||
|
||||
/* Separadores */
|
||||
.fa-separator {
|
||||
height: 1px;
|
||||
background: var(--ls-border-color);
|
||||
margin: 12px 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* Estilos para estadísticas */
|
||||
.fa-stats {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: 11px;
|
||||
color: var(--ls-secondary-text-color);
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.fa-stat-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
/* Estilos para preview en tiempo real */
|
||||
.fa-preview-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 20px;
|
||||
background: var(--ls-secondary-background-color);
|
||||
border-radius: var(--fa-border-radius);
|
||||
min-height: 100px;
|
||||
margin: 12px 0;
|
||||
}
|
||||
|
||||
.fa-preview-icon {
|
||||
transition: all 0.3s ease;
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* Estilos para código */
|
||||
.fa-code-block {
|
||||
background: var(--ls-tertiary-background-color);
|
||||
padding: 12px;
|
||||
border-radius: var(--fa-border-radius);
|
||||
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
|
||||
font-size: 12px;
|
||||
overflow-x: auto;
|
||||
margin: 8px 0;
|
||||
border: 1px solid var(--ls-border-color);
|
||||
}
|
||||
|
||||
.fa-code-block pre {
|
||||
margin: 0;
|
||||
white-space: pre-wrap;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
/* Botones de acción */
|
||||
.fa-action-btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 6px;
|
||||
padding: 8px 16px;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
background: var(--ls-link-text-color);
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
transition: all var(--fa-transition-speed);
|
||||
}
|
||||
|
||||
.fa-action-btn:hover {
|
||||
opacity: 0.9;
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.fa-action-btn.secondary {
|
||||
background: var(--ls-secondary-background-color);
|
||||
color: var(--ls-primary-text-color);
|
||||
border: 1px solid var(--ls-border-color);
|
||||
}
|
||||
|
||||
.fa-action-btn.success {
|
||||
background: var(--ls-success-color);
|
||||
}
|
||||
|
||||
.fa-action-btn.danger {
|
||||
background: var(--ls-error-color);
|
||||
}
|
||||
|
||||
/* Responsive */
|
||||
@media (max-width: 768px) {
|
||||
.fa-responsive-hide {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.fa-responsive-stack {
|
||||
flex-direction: column !important;
|
||||
}
|
||||
|
||||
.fa-responsive-grid {
|
||||
grid-template-columns: repeat(auto-fill, minmax(70px, 1fr)) !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* Utilidades de espaciado */
|
||||
.fa-mt-1 { margin-top: 4px; }
|
||||
.fa-mt-2 { margin-top: 8px; }
|
||||
.fa-mt-3 { margin-top: 12px; }
|
||||
.fa-mt-4 { margin-top: 16px; }
|
||||
|
||||
.fa-mb-1 { margin-bottom: 4px; }
|
||||
.fa-mb-2 { margin-bottom: 8px; }
|
||||
.fa-mb-3 { margin-bottom: 12px; }
|
||||
.fa-mb-4 { margin-bottom: 16px; }
|
||||
|
||||
.fa-ml-1 { margin-left: 4px; }
|
||||
.fa-ml-2 { margin-left: 8px; }
|
||||
.fa-ml-3 { margin-left: 12px; }
|
||||
.fa-ml-4 { margin-left: 16px; }
|
||||
|
||||
.fa-mr-1 { margin-right: 4px; }
|
||||
.fa-mr-2 { margin-right: 8px; }
|
||||
.fa-mr-3 { margin-right: 12px; }
|
||||
.fa-mr-4 { margin-right: 16px; }
|
||||
|
||||
/* Utilidades de texto */
|
||||
.fa-text-xs { font-size: 11px !important; }
|
||||
.fa-text-sm { font-size: 12px !important; }
|
||||
.fa-text-md { font-size: 13px !important; }
|
||||
.fa-text-lg { font-size: 14px !important; }
|
||||
.fa-text-xl { font-size: 16px !important; }
|
||||
|
||||
.fa-text-muted { color: var(--ls-secondary-text-color) !important; }
|
||||
.fa-text-primary { color: var(--ls-link-text-color) !important; }
|
||||
.fa-text-success { color: var(--ls-success-color) !important; }
|
||||
.fa-text-danger { color: var(--ls-error-color) !important; }
|
||||
.fa-text-warning { color: var(--ls-warning-color) !important; }
|
||||
|
||||
/* Utilidades de fondo */
|
||||
.fa-bg-primary { background: var(--ls-link-text-color) !important; }
|
||||
.fa-bg-secondary { background: var(--ls-secondary-background-color) !important; }
|
||||
.fa-bg-tertiary { background: var(--ls-tertiary-background-color) !important; }
|
||||
|
||||
/* Utilidades de borde */
|
||||
.fa-border { border: 1px solid var(--ls-border-color) !important; }
|
||||
.fa-border-top { border-top: 1px solid var(--ls-border-color) !important; }
|
||||
.fa-border-bottom { border-bottom: 1px solid var(--ls-border-color) !important; }
|
||||
.fa-border-left { border-left: 1px solid var(--ls-border-color) !important; }
|
||||
.fa-border-right { border-right: 1px solid var(--ls-border-color) !important; }
|
||||
|
||||
/* Utilidades de display */
|
||||
.fa-d-block { display: block !important; }
|
||||
.fa-d-inline { display: inline !important; }
|
||||
.fa-d-inline-block { display: inline-block !important; }
|
||||
.fa-d-flex { display: flex !important; }
|
||||
.fa-d-none { display: none !important; }
|
||||
|
||||
/* Utilidades de flexbox */
|
||||
.fa-flex-row { flex-direction: row !important; }
|
||||
.fa-flex-column { flex-direction: column !important; }
|
||||
.fa-align-items-center { align-items: center !important; }
|
||||
.fa-justify-content-center { justify-content: center !important; }
|
||||
.fa-justify-content-between { justify-content: space-between !important; }
|
||||
.fa-flex-wrap { flex-wrap: wrap !important; }
|
||||
.fa-gap-1 { gap: 4px !important; }
|
||||
.fa-gap-2 { gap: 8px !important; }
|
||||
.fa-gap-3 { gap: 12px !important; }
|
||||
.fa-gap-4 { gap: 16px !important; }
|
||||
|
||||
/* Utilidades de grid */
|
||||
.fa-grid { display: grid !important; }
|
||||
.fa-grid-cols-2 { grid-template-columns: repeat(2, 1fr) !important; }
|
||||
.fa-grid-cols-3 { grid-template-columns: repeat(3, 1fr) !important; }
|
||||
.fa-grid-cols-4 { grid-template-columns: repeat(4, 1fr) !important; }
|
||||
.fa-grid-cols-auto { grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)) !important; }
|
||||
|
||||
/* Utilidades de posición */
|
||||
.fa-position-relative { position: relative !important; }
|
||||
.fa-position-absolute { position: absolute !important; }
|
||||
.fa-position-fixed { position: fixed !important; }
|
||||
.fa-position-sticky { position: sticky !important; }
|
||||
|
||||
/* Utilidades de overflow */
|
||||
.fa-overflow-auto { overflow: auto !important; }
|
||||
.fa-overflow-hidden { overflow: hidden !important; }
|
||||
.fa-overflow-scroll { overflow: scroll !important; }
|
||||
|
||||
/* Utilidades de cursor */
|
||||
.fa-cursor-pointer { cursor: pointer !important; }
|
||||
.fa-cursor-default { cursor: default !important; }
|
||||
.fa-cursor-not-allowed { cursor: not-allowed !important; }
|
||||
|
||||
/* Utilidades de transición */
|
||||
.fa-transition-all { transition: all var(--fa-transition-speed) ease !important; }
|
||||
.fa-transition-transform { transition: transform var(--fa-transition-speed) ease !important; }
|
||||
.fa-transition-opacity { transition: opacity var(--fa-transition-speed) ease !important; }
|
||||
|
||||
/* Utilidades de transform */
|
||||
.fa-transform-scale-1 { transform: scale(1) !important; }
|
||||
.fa-transform-scale-1-1 { transform: scale(1.1) !important; }
|
||||
.fa-transform-rotate-0 { transform: rotate(0deg) !important; }
|
||||
.fa-transform-rotate-90 { transform: rotate(90deg) !important; }
|
||||
.fa-transform-rotate-180 { transform: rotate(180deg) !important; }
|
||||
.fa-transform-rotate-270 { transform: rotate(270deg) !important; }
|
||||
|
||||
/* Utilidades de animación */
|
||||
.fa-animation-spin { animation: fa-spin 2s linear infinite !important; }
|
||||
.fa-animation-pulse { animation: fa-spin 1s steps(8) infinite !important; }
|
||||
.fa-animation-bounce { animation: fa-bounce 1s ease infinite !important; }
|
||||
|
||||
@keyframes fa-bounce {
|
||||
0%, 100% { transform: translateY(0); }
|
||||
50% { transform: translateY(-5px); }
|
||||
}
|
||||
863
build-icons-json.js
Normal file
863
build-icons-json.js
Normal file
@@ -0,0 +1,863 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
// ================= CONFIGURACIÓN =================
|
||||
const CONFIG = {
|
||||
// Rutas de entrada (archivos procesados)
|
||||
PROCESSED_METADATA: path.join(__dirname, 'assets', 'processed', 'metadata.json'),
|
||||
PROCESSED_STYLES: path.join(__dirname, 'assets', 'processed', 'styles.json'),
|
||||
PROCESSED_CATEGORIES: path.join(__dirname, 'assets', 'processed', 'categories.json'),
|
||||
|
||||
// Rutas de salida (plugin)
|
||||
OUTPUT_ICONS: path.join(__dirname, 'assets', 'icons.json'),
|
||||
OUTPUT_DYNAMIC_CSS: path.join(__dirname, 'assets', 'dynamic-styles.css'),
|
||||
OUTPUT_CUSTOM_CSS: path.join(__dirname, 'assets', 'custom-styles.css'),
|
||||
|
||||
// Configuración del plugin
|
||||
PLUGIN_NAME: 'FontAwesome Pro',
|
||||
VERSION: '2.0.0'
|
||||
};
|
||||
|
||||
// ================= ESTILOS POSIBLES =================
|
||||
const ALL_STYLES = [
|
||||
// Estilos clásicos
|
||||
{
|
||||
id: 'solid',
|
||||
name: 'Solid',
|
||||
prefix: 'fas',
|
||||
class: 'fas',
|
||||
weight: 900,
|
||||
pro: true,
|
||||
sharp: false,
|
||||
family: 'Font Awesome 6 Pro',
|
||||
file: 'fa-solid-900.woff2'
|
||||
},
|
||||
{
|
||||
id: 'regular',
|
||||
name: 'Regular',
|
||||
prefix: 'far',
|
||||
class: 'far',
|
||||
weight: 400,
|
||||
pro: true,
|
||||
sharp: false,
|
||||
family: 'Font Awesome 6 Pro',
|
||||
file: 'fa-regular-400.woff2'
|
||||
},
|
||||
{
|
||||
id: 'light',
|
||||
name: 'Light',
|
||||
prefix: 'fal',
|
||||
class: 'fal',
|
||||
weight: 300,
|
||||
pro: true,
|
||||
sharp: false,
|
||||
family: 'Font Awesome 6 Pro',
|
||||
file: 'fa-light-300.woff2'
|
||||
},
|
||||
{
|
||||
id: 'thin',
|
||||
name: 'Thin',
|
||||
prefix: 'fat',
|
||||
class: 'fat',
|
||||
weight: 100,
|
||||
pro: true,
|
||||
sharp: false,
|
||||
family: 'Font Awesome 6 Pro',
|
||||
file: 'fa-thin-100.woff2'
|
||||
},
|
||||
{
|
||||
id: 'duotone',
|
||||
name: 'Duotone',
|
||||
prefix: 'fad',
|
||||
class: 'fad',
|
||||
weight: 900,
|
||||
pro: true,
|
||||
sharp: false,
|
||||
family: 'Font Awesome 6 Duotone',
|
||||
file: 'fa-duotone-900.woff2'
|
||||
},
|
||||
|
||||
// Estilos Sharp
|
||||
{
|
||||
id: 'sharp-solid',
|
||||
name: 'Sharp Solid',
|
||||
prefix: 'fass',
|
||||
class: 'fass',
|
||||
weight: 900,
|
||||
pro: true,
|
||||
sharp: true,
|
||||
family: 'Font Awesome 6 Sharp',
|
||||
file: 'fa-sharp-solid-900.woff2'
|
||||
},
|
||||
{
|
||||
id: 'sharp-regular',
|
||||
name: 'Sharp Regular',
|
||||
prefix: 'fasr',
|
||||
class: 'fasr',
|
||||
weight: 400,
|
||||
pro: true,
|
||||
sharp: true,
|
||||
family: 'Font Awesome 6 Sharp',
|
||||
file: 'fa-sharp-regular-400.woff2'
|
||||
},
|
||||
{
|
||||
id: 'sharp-light',
|
||||
name: 'Sharp Light',
|
||||
prefix: 'fasl',
|
||||
class: 'fasl',
|
||||
weight: 300,
|
||||
pro: true,
|
||||
sharp: true,
|
||||
family: 'Font Awesome 6 Sharp',
|
||||
file: 'fa-sharp-light-300.woff2'
|
||||
},
|
||||
{
|
||||
id: 'sharp-thin',
|
||||
name: 'Sharp Thin',
|
||||
prefix: 'fast',
|
||||
class: 'fast',
|
||||
weight: 100,
|
||||
pro: true,
|
||||
sharp: true,
|
||||
family: 'Font Awesome 6 Sharp',
|
||||
file: 'fa-sharp-thin-100.woff2'
|
||||
},
|
||||
{
|
||||
id: 'sharp-duotone',
|
||||
name: 'Sharp Duotone',
|
||||
prefix: 'fasd',
|
||||
class: 'fasd',
|
||||
weight: 900,
|
||||
pro: true,
|
||||
sharp: true,
|
||||
family: 'Font Awesome 6 Sharp Duotone',
|
||||
file: 'fa-sharp-duotone-900.woff2'
|
||||
},
|
||||
|
||||
// Brands
|
||||
{
|
||||
id: 'brands',
|
||||
name: 'Brands',
|
||||
prefix: 'fab',
|
||||
class: 'fab',
|
||||
weight: 400,
|
||||
pro: false,
|
||||
sharp: false,
|
||||
family: 'Font Awesome 6 Brands',
|
||||
file: 'fa-brands-400.woff2'
|
||||
}
|
||||
];
|
||||
|
||||
// Estilos detectados (se llenará automáticamente)
|
||||
let DETECTED_STYLES = [];
|
||||
|
||||
// ================= FUNCIONES PRINCIPALES =================
|
||||
|
||||
/**
|
||||
* Verificar si los archivos procesados existen
|
||||
*/
|
||||
function checkProcessedFiles() {
|
||||
console.log('🔍 Verificando archivos procesados...\n');
|
||||
|
||||
const requiredFiles = [
|
||||
{ path: CONFIG.PROCESSED_METADATA, name: 'metadata.json' },
|
||||
{ path: CONFIG.PROCESSED_STYLES, name: 'styles.json' },
|
||||
{ path: CONFIG.PROCESSED_CATEGORIES, name: 'categories.json' }
|
||||
];
|
||||
|
||||
let allExist = true;
|
||||
|
||||
requiredFiles.forEach(file => {
|
||||
if (fs.existsSync(file.path)) {
|
||||
const stats = fs.statSync(file.path);
|
||||
console.log(` ✅ ${file.name}: ${(stats.size / 1024).toFixed(2)} KB`);
|
||||
} else {
|
||||
console.log(` ❌ ${file.name}: NO ENCONTRADO`);
|
||||
allExist = false;
|
||||
}
|
||||
});
|
||||
|
||||
if (!allExist) {
|
||||
console.log('\n⚠️ Archivos procesados no encontrados.');
|
||||
console.log(' Ejecuta primero: npm run extract');
|
||||
console.log(' O: npm run build (que ejecuta extract automáticamente)');
|
||||
}
|
||||
|
||||
console.log('');
|
||||
return allExist;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detectar estilos disponibles automáticamente
|
||||
*/
|
||||
function detectAvailableStyles() {
|
||||
console.log('🔍 Detectando estilos disponibles...\n');
|
||||
|
||||
const webfontsDir = path.join(__dirname, 'assets', 'fontawesome', 'webfonts');
|
||||
|
||||
if (!fs.existsSync(webfontsDir)) {
|
||||
console.error('❌ Carpeta de webfonts no encontrada:', webfontsDir);
|
||||
console.log(' Asegúrate de copiar los archivos de FontAwesome Pro');
|
||||
return [];
|
||||
}
|
||||
|
||||
const availableStyles = [];
|
||||
const fontFiles = fs.readdirSync(webfontsDir);
|
||||
|
||||
ALL_STYLES.forEach(style => {
|
||||
const expectedFile = style.file;
|
||||
const fontPath = path.join(webfontsDir, expectedFile);
|
||||
|
||||
// Verificar archivo principal (.woff2)
|
||||
if (fs.existsSync(fontPath)) {
|
||||
availableStyles.push(style);
|
||||
console.log(` ✅ ${style.name.padEnd(20)} ${expectedFile}`);
|
||||
} else {
|
||||
// Verificar variantes
|
||||
const variants = ['.ttf', '.eot', '.woff'].map(ext =>
|
||||
expectedFile.replace('.woff2', ext)
|
||||
);
|
||||
|
||||
const foundVariant = variants.find(variant =>
|
||||
fs.existsSync(path.join(webfontsDir, variant))
|
||||
);
|
||||
|
||||
if (foundVariant) {
|
||||
availableStyles.push(style);
|
||||
console.log(` ✅ ${style.name.padEnd(20)} ${foundVariant} (variante)`);
|
||||
} else {
|
||||
console.log(` ⚠️ ${style.name.padEnd(20)} No encontrado`);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
console.log('\n' + '='.repeat(60));
|
||||
console.log(`📊 RESUMEN: ${availableStyles.length} de ${ALL_STYLES.length} estilos detectados`);
|
||||
|
||||
// Estadísticas
|
||||
const classicCount = availableStyles.filter(s => !s.sharp && s.id !== 'brands').length;
|
||||
const sharpCount = availableStyles.filter(s => s.sharp).length;
|
||||
const brandsCount = availableStyles.filter(s => s.id === 'brands').length;
|
||||
|
||||
console.log(` • Clásicos: ${classicCount}/5`);
|
||||
console.log(` • Sharp: ${sharpCount}/5`);
|
||||
console.log(` • Brands: ${brandsCount}/1`);
|
||||
console.log('='.repeat(60) + '\n');
|
||||
|
||||
return availableStyles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cargar metadata procesado
|
||||
*/
|
||||
function loadProcessedMetadata() {
|
||||
try {
|
||||
console.log('📥 Cargando metadata procesado...');
|
||||
|
||||
if (!fs.existsSync(CONFIG.PROCESSED_METADATA)) {
|
||||
throw new Error(`Archivo no encontrado: ${CONFIG.PROCESSED_METADATA}`);
|
||||
}
|
||||
|
||||
const content = fs.readFileSync(CONFIG.PROCESSED_METADATA, 'utf8');
|
||||
const data = JSON.parse(content);
|
||||
|
||||
if (!data.icons || typeof data.icons !== 'object') {
|
||||
throw new Error('Estructura de metadata inválida');
|
||||
}
|
||||
|
||||
console.log(`✅ Metadata cargado: ${Object.keys(data.icons).length} íconos`);
|
||||
|
||||
// Convertir objeto a array
|
||||
const iconsArray = Object.values(data.icons);
|
||||
|
||||
// Filtrar íconos que tienen estilos disponibles
|
||||
const filteredIcons = iconsArray.filter(icon => {
|
||||
if (!icon.styles || !Array.isArray(icon.styles)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Verificar si al menos un estilo está disponible
|
||||
return icon.styles.some(style =>
|
||||
DETECTED_STYLES.some(s => s.id === style)
|
||||
);
|
||||
});
|
||||
|
||||
console.log(`📊 Íconos con estilos disponibles: ${filteredIcons.length}/${iconsArray.length}`);
|
||||
|
||||
return filteredIcons;
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Error cargando metadata procesado:', error.message);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cargar información de estilos procesada
|
||||
*/
|
||||
function loadProcessedStylesInfo() {
|
||||
try {
|
||||
if (!fs.existsSync(CONFIG.PROCESSED_STYLES)) {
|
||||
console.log('⚠️ Archivo de estilos procesado no encontrado');
|
||||
return null;
|
||||
}
|
||||
|
||||
const content = fs.readFileSync(CONFIG.PROCESSED_STYLES, 'utf8');
|
||||
const data = JSON.parse(content);
|
||||
|
||||
if (!data.styles || typeof data.styles !== 'object') {
|
||||
console.log('⚠️ Estructura de estilos inválida');
|
||||
return null;
|
||||
}
|
||||
|
||||
console.log('✅ Información de estilos cargada');
|
||||
return data.styles;
|
||||
|
||||
} catch (error) {
|
||||
console.log('⚠️ Error cargando información de estilos:', error.message);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cargar categorías procesadas
|
||||
*/
|
||||
function loadProcessedCategories() {
|
||||
try {
|
||||
if (!fs.existsSync(CONFIG.PROCESSED_CATEGORIES)) {
|
||||
console.log('⚠️ Archivo de categorías procesado no encontrado');
|
||||
return null;
|
||||
}
|
||||
|
||||
const content = fs.readFileSync(CONFIG.PROCESSED_CATEGORIES, 'utf8');
|
||||
const data = JSON.parse(content);
|
||||
|
||||
if (!data.categories || !Array.isArray(data.categories)) {
|
||||
console.log('⚠️ Estructura de categorías inválida');
|
||||
return null;
|
||||
}
|
||||
|
||||
console.log(`✅ Categorías cargadas: ${data.categories.length}`);
|
||||
return data.categories;
|
||||
|
||||
} catch (error) {
|
||||
console.log('⚠️ Error cargando categorías:', error.message);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generar CSS dinámico basado en estilos detectados
|
||||
*/
|
||||
function generateDynamicCSS(styles) {
|
||||
console.log('🎨 Generando CSS dinámico...');
|
||||
|
||||
let cssContent = `/* ============================================\n`;
|
||||
cssContent += ` FontAwesome Dynamic Styles\n`;
|
||||
cssContent += ` Generado: ${new Date().toISOString()}\n`;
|
||||
cssContent += ` Estilos detectados: ${styles.length}\n`;
|
||||
cssContent += `============================================ */\n\n`;
|
||||
|
||||
// Agrupar por familia de fuentes
|
||||
const families = {};
|
||||
styles.forEach(style => {
|
||||
if (!families[style.family]) {
|
||||
families[style.family] = [];
|
||||
}
|
||||
families[style.family].push(style);
|
||||
});
|
||||
|
||||
// Generar @font-face para cada familia
|
||||
Object.entries(families).forEach(([familyName, familyStyles]) => {
|
||||
cssContent += `/* ${familyName} */\n`;
|
||||
|
||||
familyStyles.forEach(style => {
|
||||
const fontWeight = style.weight;
|
||||
const fontFile = style.file;
|
||||
const fontPath = `../webfonts/${fontFile}`;
|
||||
|
||||
cssContent += `@font-face {\n`;
|
||||
cssContent += ` font-family: '${familyName}';\n`;
|
||||
cssContent += ` font-style: normal;\n`;
|
||||
cssContent += ` font-weight: ${fontWeight};\n`;
|
||||
cssContent += ` font-display: block;\n`;
|
||||
cssContent += ` src: url("${fontPath}") format("woff2");\n`;
|
||||
cssContent += `}\n\n`;
|
||||
});
|
||||
});
|
||||
|
||||
// Reglas de clase para cada estilo
|
||||
cssContent += `/* Reglas de clase */\n`;
|
||||
styles.forEach(style => {
|
||||
cssContent += `.${style.prefix} {\n`;
|
||||
cssContent += ` font-family: '${style.family}';\n`;
|
||||
cssContent += ` font-weight: ${style.weight};\n`;
|
||||
cssContent += `}\n`;
|
||||
});
|
||||
|
||||
// Variables CSS para Duotone
|
||||
const hasDuotone = styles.some(s => s.id.includes('duotone'));
|
||||
if (hasDuotone) {
|
||||
cssContent += `\n/* Variables para Duotone */\n`;
|
||||
cssContent += `.fad, .fasd {\n`;
|
||||
cssContent += ` --fa-primary-color: currentColor;\n`;
|
||||
cssContent += ` --fa-secondary-color: rgba(0, 0, 0, 0.4);\n`;
|
||||
cssContent += ` --fa-primary-opacity: 1;\n`;
|
||||
cssContent += ` --fa-secondary-opacity: 0.4;\n`;
|
||||
cssContent += `}\n`;
|
||||
}
|
||||
|
||||
// Guardar archivo
|
||||
fs.writeFileSync(CONFIG.OUTPUT_DYNAMIC_CSS, cssContent, 'utf8');
|
||||
console.log(`✅ CSS dinámico generado: ${CONFIG.OUTPUT_DYNAMIC_CSS}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generar CSS personalizado para características avanzadas
|
||||
*/
|
||||
function generateCustomCSS() {
|
||||
console.log('🎨 Generando CSS personalizado...');
|
||||
|
||||
const cssContent = `/* ============================================\n`;
|
||||
cssContent += ` FontAwesome Custom Styles\n`;
|
||||
cssContent += ` Características avanzadas: Color, Tamaño, Animaciones\n`;
|
||||
cssContent += ` Generado: ${new Date().toISOString()}\n`;
|
||||
cssContent += `============================================ */\n\n`;
|
||||
|
||||
// Tamaños personalizados
|
||||
cssContent += `/* Tamaños */\n`;
|
||||
const sizes = [
|
||||
{ class: 'fa-xs', size: '0.75em' },
|
||||
{ class: 'fa-sm', size: '0.875em' },
|
||||
{ class: 'fa-lg', size: '1.33em' },
|
||||
{ class: 'fa-xl', size: '1.75em' },
|
||||
{ class: 'fa-2x', size: '2em' },
|
||||
{ class: 'fa-3x', size: '3em' },
|
||||
{ class: 'fa-4x', size: '4em' },
|
||||
{ class: 'fa-5x', size: '5em' },
|
||||
{ class: 'fa-6x', size: '6em' },
|
||||
{ class: 'fa-7x', size: '7em' },
|
||||
{ class: 'fa-8x', size: '8em' },
|
||||
{ class: 'fa-9x', size: '9em' },
|
||||
{ class: 'fa-10x', size: '10em' }
|
||||
];
|
||||
|
||||
sizes.forEach(({ class: sizeClass, size }) => {
|
||||
cssContent += `.${sizeClass} { font-size: ${size} !important; }\n`;
|
||||
});
|
||||
|
||||
// Animaciones
|
||||
cssContent += `\n/* Animaciones */\n`;
|
||||
cssContent += `.fa-spin { animation: fa-spin 2s linear infinite; }\n`;
|
||||
cssContent += `.fa-pulse { animation: fa-spin 1s steps(8) infinite; }\n`;
|
||||
cssContent += `.fa-beat { animation: fa-beat 1s ease infinite; }\n`;
|
||||
cssContent += `.fa-fade { animation: fa-fade 2s ease infinite; }\n`;
|
||||
cssContent += `.fa-bounce { animation: fa-bounce 1s ease infinite; }\n`;
|
||||
cssContent += `.fa-flip { animation: fa-flip 2s ease infinite; }\n`;
|
||||
cssContent += `.fa-shake { animation: fa-shake 1s ease infinite; }\n`;
|
||||
|
||||
// Keyframes para animaciones
|
||||
cssContent += `\n/* Keyframes */\n`;
|
||||
cssContent += `@keyframes fa-beat {\n`;
|
||||
cssContent += ` 0%, 90% { transform: scale(1); }\n`;
|
||||
cssContent += ` 45% { transform: scale(1.1); }\n`;
|
||||
cssContent += `}\n\n`;
|
||||
|
||||
cssContent += `@keyframes fa-fade {\n`;
|
||||
cssContent += ` 0%, 100% { opacity: 1; }\n`;
|
||||
cssContent += ` 50% { opacity: 0.5; }\n`;
|
||||
cssContent += `}\n\n`;
|
||||
|
||||
cssContent += `@keyframes fa-bounce {\n`;
|
||||
cssContent += ` 0%, 100% { transform: translateY(0); }\n`;
|
||||
cssContent += ` 50% { transform: translateY(-5px); }\n`;
|
||||
cssContent += `}\n\n`;
|
||||
|
||||
cssContent += `@keyframes fa-flip {\n`;
|
||||
cssContent += ` 0% { transform: perspective(400px) rotateY(0); }\n`;
|
||||
cssContent += ` 100% { transform: perspective(400px) rotateY(360deg); }\n`;
|
||||
cssContent += `}\n\n`;
|
||||
|
||||
cssContent += `@keyframes fa-shake {\n`;
|
||||
cssContent += ` 0%, 100% { transform: translateX(0); }\n`;
|
||||
cssContent += ` 25% { transform: translateX(-3px); }\n`;
|
||||
cssContent += ` 75% { transform: translateX(3px); }\n`;
|
||||
cssContent += `}\n`;
|
||||
|
||||
// Colores temáticos
|
||||
cssContent += `\n/* Colores temáticos */\n`;
|
||||
const themeColors = [
|
||||
{ class: 'fa-primary', color: 'var(--ls-link-text-color, #0451a5)' },
|
||||
{ class: 'fa-success', color: '#10b981' },
|
||||
{ class: 'fa-danger', color: '#ef4444' },
|
||||
{ class: 'fa-warning', color: '#f59e0b' },
|
||||
{ class: 'fa-info', color: '#3b82f6' },
|
||||
{ class: 'fa-purple', color: '#8b5cf6' },
|
||||
{ class: 'fa-pink', color: '#ec4899' },
|
||||
{ class: 'fa-gray', color: '#6b7280' },
|
||||
{ class: 'fa-black', color: '#000000' },
|
||||
{ class: 'fa-white', color: '#ffffff' }
|
||||
];
|
||||
|
||||
themeColors.forEach(({ class: colorClass, color }) => {
|
||||
cssContent += `.${colorClass} { color: ${color} !important; }\n`;
|
||||
});
|
||||
|
||||
// Efectos especiales
|
||||
cssContent += `\n/* Efectos especiales */\n`;
|
||||
cssContent += `.fa-shadow { filter: drop-shadow(0 2px 4px rgba(0,0,0,0.2)); }\n`;
|
||||
cssContent += `.fa-shadow-lg { filter: drop-shadow(0 4px 8px rgba(0,0,0,0.3)); }\n`;
|
||||
cssContent += `.fa-glow { filter: drop-shadow(0 0 8px currentColor); }\n`;
|
||||
|
||||
// Gradientes
|
||||
cssContent += `.fa-gradient {\n`;
|
||||
cssContent += ` background: linear-gradient(45deg, #8b5cf6, #3b82f6);\n`;
|
||||
cssContent += ` -webkit-background-clip: text;\n`;
|
||||
cssContent += ` -webkit-text-fill-color: transparent;\n`;
|
||||
cssContent += ` background-clip: text;\n`;
|
||||
cssContent += `}\n`;
|
||||
|
||||
// Guardar archivo
|
||||
fs.writeFileSync(CONFIG.OUTPUT_CUSTOM_CSS, cssContent, 'utf8');
|
||||
console.log(`✅ CSS personalizado generado: ${CONFIG.OUTPUT_CUSTOM_CSS}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Crear base de datos final
|
||||
*/
|
||||
function createDatabase(icons, categories, stylesInfo) {
|
||||
console.log('📊 Creando base de datos final...');
|
||||
|
||||
// Preparar estilos para la base de datos
|
||||
const dbStyles = DETECTED_STYLES.map(style => {
|
||||
const styleInfoData = stylesInfo && stylesInfo[style.id] ? stylesInfo[style.id] : {};
|
||||
return {
|
||||
id: style.id,
|
||||
name: style.name,
|
||||
prefix: style.prefix,
|
||||
class: style.class,
|
||||
weight: style.weight,
|
||||
pro: style.pro,
|
||||
sharp: style.sharp,
|
||||
available: true,
|
||||
count: styleInfoData.count || 0,
|
||||
percentage: styleInfoData.percentage || '0.0'
|
||||
};
|
||||
});
|
||||
|
||||
// Actualizar conteos en categorías
|
||||
const updatedCategories = categories ? categories.map(category => {
|
||||
if (category.id === 'all') {
|
||||
return { ...category, count: icons.length };
|
||||
} else if (category.type === 'fontawesome') {
|
||||
// Contar íconos en esta categoría
|
||||
const count = icons.filter(icon =>
|
||||
icon.categories && icon.categories.includes(category.id)
|
||||
).length;
|
||||
return { ...category, count };
|
||||
}
|
||||
return category;
|
||||
}) : getDefaultCategories(icons.length);
|
||||
|
||||
// Crear estructura final
|
||||
const database = {
|
||||
meta: {
|
||||
generated: new Date().toISOString(),
|
||||
fontawesomeVersion: '6.0.0',
|
||||
pluginVersion: CONFIG.VERSION,
|
||||
totalIcons: icons.length,
|
||||
totalCategories: updatedCategories.length,
|
||||
detectedStyles: DETECTED_STYLES.length,
|
||||
stylesAvailable: DETECTED_STYLES.map(s => s.id),
|
||||
proIcons: icons.filter(icon =>
|
||||
icon.styles && icon.styles.some(style =>
|
||||
['solid', 'regular', 'light', 'thin', 'duotone',
|
||||
'sharp-solid', 'sharp-regular', 'sharp-light', 'sharp-thin', 'sharp-duotone']
|
||||
.includes(style)
|
||||
)
|
||||
).length,
|
||||
freeIcons: icons.filter(icon =>
|
||||
icon.styles && icon.styles.includes('brands')
|
||||
).length
|
||||
},
|
||||
icons: icons.map(icon => ({
|
||||
id: icon.id,
|
||||
name: icon.name,
|
||||
label: icon.label,
|
||||
categories: icon.categories || ['uncategorized'],
|
||||
styles: icon.styles || [],
|
||||
searchTerms: icon.searchTerms || [],
|
||||
unicode: icon.unicode || '',
|
||||
version: icon.version || '6.0.0',
|
||||
free: (icon.styles && icon.styles.includes('brands')) || false,
|
||||
pro: icon.styles && icon.styles.some(style =>
|
||||
['solid', 'regular', 'light', 'thin', 'duotone',
|
||||
'sharp-solid', 'sharp-regular', 'sharp-light', 'sharp-thin', 'sharp-duotone']
|
||||
.includes(style)
|
||||
)
|
||||
})),
|
||||
categories: updatedCategories,
|
||||
styles: dbStyles,
|
||||
search: {
|
||||
languages: ['en', 'es'],
|
||||
synonyms: true
|
||||
},
|
||||
features: {
|
||||
colorCustomization: true,
|
||||
sizeCustomization: true,
|
||||
animations: true,
|
||||
transformations: true,
|
||||
presets: true
|
||||
}
|
||||
};
|
||||
|
||||
return database;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtener categorías por defecto
|
||||
*/
|
||||
function getDefaultCategories(totalIcons) {
|
||||
return [
|
||||
{
|
||||
id: 'all',
|
||||
name: 'Todos los Íconos',
|
||||
icon: 'fas fa-th',
|
||||
count: totalIcons,
|
||||
type: 'special'
|
||||
},
|
||||
{
|
||||
id: 'favorites',
|
||||
name: 'Favoritos',
|
||||
icon: 'fas fa-star',
|
||||
count: 0,
|
||||
type: 'special'
|
||||
},
|
||||
{
|
||||
id: 'recent',
|
||||
name: 'Recientes',
|
||||
icon: 'fas fa-history',
|
||||
count: 0,
|
||||
type: 'special'
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Guardar base de datos
|
||||
*/
|
||||
function saveDatabase(database) {
|
||||
try {
|
||||
// Asegurar directorio
|
||||
const assetsDir = path.dirname(CONFIG.OUTPUT_ICONS);
|
||||
if (!fs.existsSync(assetsDir)) {
|
||||
fs.mkdirSync(assetsDir, { recursive: true });
|
||||
}
|
||||
|
||||
// Guardar JSON
|
||||
fs.writeFileSync(
|
||||
CONFIG.OUTPUT_ICONS,
|
||||
JSON.stringify(database, null, 2),
|
||||
'utf8'
|
||||
);
|
||||
|
||||
console.log(`✅ Base de datos guardada: ${CONFIG.OUTPUT_ICONS}`);
|
||||
console.log(`📊 Tamaño: ${(fs.statSync(CONFIG.OUTPUT_ICONS).size / 1024 / 1024).toFixed(2)} MB`);
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Error guardando base de datos:', error.message);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generar base de datos de ejemplo
|
||||
*/
|
||||
function generateSampleDatabase() {
|
||||
console.log('📝 Generando base de datos de ejemplo...');
|
||||
|
||||
const sampleIcons = [
|
||||
{
|
||||
id: "home",
|
||||
name: "home",
|
||||
label: "Home",
|
||||
categories: ["household", "buildings"],
|
||||
styles: ["solid", "regular", "light"],
|
||||
searchTerms: ["casa", "hogar", "inicio"],
|
||||
unicode: "f015",
|
||||
version: "6.0.0",
|
||||
free: true,
|
||||
pro: true
|
||||
},
|
||||
{
|
||||
id: "user",
|
||||
name: "user",
|
||||
label: "User",
|
||||
categories: ["users-people"],
|
||||
styles: ["solid", "regular"],
|
||||
searchTerms: ["persona", "perfil", "cuenta"],
|
||||
unicode: "f007",
|
||||
version: "6.0.0",
|
||||
free: true,
|
||||
pro: true
|
||||
}
|
||||
];
|
||||
|
||||
const sampleStyles = DETECTED_STYLES.length > 0 ?
|
||||
DETECTED_STYLES.slice(0, 3) :
|
||||
ALL_STYLES.slice(0, 3);
|
||||
|
||||
const database = {
|
||||
meta: {
|
||||
generated: new Date().toISOString(),
|
||||
fontawesomeVersion: "6.0.0",
|
||||
pluginVersion: CONFIG.VERSION,
|
||||
totalIcons: sampleIcons.length,
|
||||
totalCategories: 3,
|
||||
detectedStyles: sampleStyles.length,
|
||||
proIcons: sampleIcons.length,
|
||||
freeIcons: 0,
|
||||
note: "BASE DE DATOS DE EJEMPLO - Ejecuta 'npm run build' para generar la versión completa"
|
||||
},
|
||||
icons: sampleIcons,
|
||||
categories: [
|
||||
{ id: "all", name: "Todos los Íconos", icon: "fas fa-th", count: sampleIcons.length, type: "special" },
|
||||
{ id: "household", name: "Hogar", icon: "fas fa-home", count: 1, type: "fontawesome" },
|
||||
{ id: "users-people", name: "Personas", icon: "fas fa-user", count: 1, type: "fontawesome" }
|
||||
],
|
||||
styles: sampleStyles.map(s => ({
|
||||
id: s.id,
|
||||
name: s.name,
|
||||
prefix: s.prefix,
|
||||
class: s.class,
|
||||
available: true
|
||||
}))
|
||||
};
|
||||
|
||||
saveDatabase(database);
|
||||
return database;
|
||||
}
|
||||
|
||||
/**
|
||||
* Función principal
|
||||
*/
|
||||
async function generateIconDatabase() {
|
||||
console.log('🎨 ' + '='.repeat(60));
|
||||
console.log(' GENERADOR DE BASE DE DATOS FONTAWESOME PRO');
|
||||
console.log(' Versión: ' + CONFIG.VERSION);
|
||||
console.log('='.repeat(60) + '\n');
|
||||
|
||||
try {
|
||||
// 1. Verificar archivos procesados
|
||||
const hasProcessedFiles = checkProcessedFiles();
|
||||
|
||||
if (!hasProcessedFiles) {
|
||||
console.log('⚠️ Ejecutando en modo fallback (sin archivos procesados)...');
|
||||
console.log(' Para mejor rendimiento, ejecuta: npm run extract');
|
||||
}
|
||||
|
||||
// 2. Detectar estilos disponibles
|
||||
DETECTED_STYLES = detectAvailableStyles();
|
||||
|
||||
if (DETECTED_STYLES.length === 0) {
|
||||
console.warn('⚠️ No se detectaron estilos. Generando base de datos de ejemplo...');
|
||||
return generateSampleDatabase();
|
||||
}
|
||||
|
||||
// 3. Generar CSS
|
||||
generateDynamicCSS(DETECTED_STYLES);
|
||||
generateCustomCSS();
|
||||
|
||||
// 4. Cargar datos procesados
|
||||
let icons, stylesInfo, categories;
|
||||
|
||||
if (hasProcessedFiles) {
|
||||
icons = loadProcessedMetadata();
|
||||
stylesInfo = loadProcessedStylesInfo();
|
||||
categories = loadProcessedCategories();
|
||||
|
||||
if (!icons || icons.length === 0) {
|
||||
throw new Error('No se pudieron cargar íconos del metadata procesado');
|
||||
}
|
||||
} else {
|
||||
// Modo fallback: cargar metadata original
|
||||
console.log('📥 Cargando metadata original (modo fallback)...');
|
||||
const metadataPath = path.join(__dirname, 'assets', 'fontawesome', 'metadata', 'icons.json');
|
||||
|
||||
if (!fs.existsSync(metadataPath)) {
|
||||
throw new Error('No se encontró metadata original. ¿Copiaste los archivos de FontAwesome?');
|
||||
}
|
||||
|
||||
const content = fs.readFileSync(metadataPath, 'utf8');
|
||||
const rawMetadata = JSON.parse(content);
|
||||
|
||||
// Procesar íconos básicamente
|
||||
icons = Object.values(rawMetadata).map(icon => ({
|
||||
id: icon.name || Object.keys(rawMetadata).find(key => rawMetadata[key] === icon),
|
||||
name: icon.name || '',
|
||||
label: icon.label || '',
|
||||
categories: icon.categories || ['uncategorized'],
|
||||
styles: icon.styles || [],
|
||||
searchTerms: [],
|
||||
unicode: icon.unicode || '',
|
||||
version: icon.version || '6.0.0'
|
||||
}));
|
||||
|
||||
categories = getDefaultCategories(icons.length);
|
||||
}
|
||||
|
||||
// 5. Crear base de datos
|
||||
console.log('\n📊 Creando estructura de datos...');
|
||||
const database = createDatabase(icons, categories, stylesInfo);
|
||||
|
||||
// 6. Guardar
|
||||
saveDatabase(database);
|
||||
|
||||
console.log('\n' + '='.repeat(60));
|
||||
console.log('✅ ¡GENERACIÓN COMPLETADA EXITOSAMENTE!');
|
||||
console.log('='.repeat(60));
|
||||
console.log(`📊 Total íconos: ${database.icons.length}`);
|
||||
console.log(`📁 Categorías: ${database.categories.length}`);
|
||||
console.log(`🎨 Estilos: ${database.meta.detectedStyles}`);
|
||||
console.log(`📍 Archivos generados:`);
|
||||
console.log(` • ${CONFIG.OUTPUT_ICONS}`);
|
||||
console.log(` • ${CONFIG.OUTPUT_DYNAMIC_CSS}`);
|
||||
console.log(` • ${CONFIG.OUTPUT_CUSTOM_CSS}`);
|
||||
console.log('='.repeat(60));
|
||||
|
||||
// Mostrar resumen de estilos
|
||||
console.log('\n🎨 ESTILOS DISPONIBLES:');
|
||||
database.styles.forEach(style => {
|
||||
if (style.available) {
|
||||
console.log(` • ${style.name.padEnd(15)}: ${style.count || 0} íconos`);
|
||||
}
|
||||
});
|
||||
|
||||
return database;
|
||||
|
||||
} catch (error) {
|
||||
console.error('\n❌ ERROR CRÍTICO:', error.message);
|
||||
console.log('\n🔄 Generando base de datos de ejemplo...');
|
||||
return generateSampleDatabase();
|
||||
}
|
||||
}
|
||||
|
||||
// ================= EJECUCIÓN =================
|
||||
const args = process.argv.slice(2);
|
||||
const isSampleMode = args.includes('--sample');
|
||||
|
||||
if (require.main === module) {
|
||||
if (isSampleMode) {
|
||||
generateSampleDatabase();
|
||||
} else {
|
||||
generateIconDatabase();
|
||||
}
|
||||
}
|
||||
|
||||
// Exportar
|
||||
module.exports = {
|
||||
generateIconDatabase,
|
||||
generateSampleDatabase,
|
||||
CONFIG,
|
||||
ALL_STYLES
|
||||
};
|
||||
2560
index.html
Normal file
2560
index.html
Normal file
File diff suppressed because it is too large
Load Diff
14
package-lock.json
generated
Normal file
14
package-lock.json
generated
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "logseq-fontawesome-pro",
|
||||
"version": "2.6.2",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "logseq-fontawesome-pro",
|
||||
"version": "2.6.2",
|
||||
"license": "MIT",
|
||||
"devDependencies": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
27
package.json
Normal file
27
package.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"name": "logseq-fontawesome-pro",
|
||||
"version": "2.6.2",
|
||||
"description": "FontAwesome 6 Pro completo con todos los estilos, color y tamaño para Logseq",
|
||||
"main": "index.html",
|
||||
"author": "MonitorDevs",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"extract": "node scripts/extract-metadata.js",
|
||||
"validate": "node scripts/validate-styles.js",
|
||||
"build": "npm run extract && npm run validate && node build-icons-json.js",
|
||||
"update": "node update-styles.js",
|
||||
"verify": "node verify-styles.js",
|
||||
"build:sample": "node build-icons-json.js --sample",
|
||||
"dev": "echo '✅ Plugin listo para Logseq'",
|
||||
"clean": "rm -rf assets/processed assets/icons.json assets/dynamic-styles.css assets/custom-styles.css",
|
||||
"reset": "npm run clean && npm run build"
|
||||
},
|
||||
"dependencies": {},
|
||||
"devDependencies": {},
|
||||
"logseq": {
|
||||
"id": "logseq-fontawesome-pro",
|
||||
"title": "FontAwesome Pro",
|
||||
"icon": "./icon.png",
|
||||
"description": "Íconos FontAwesome 6 Pro con todos los estilos, color y tamaño"
|
||||
}
|
||||
}
|
||||
886
scripts/extract-metadata.js
Normal file
886
scripts/extract-metadata.js
Normal file
@@ -0,0 +1,886 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
// Configuración
|
||||
const CONFIG = {
|
||||
// Rutas de entrada (FontAwesome Pro)
|
||||
FA_METADATA: path.join(__dirname, '..', 'assets', 'fontawesome', 'metadata', 'icons.json'),
|
||||
FA_CATEGORIES: path.join(__dirname, '..', 'assets', 'fontawesome', 'metadata', 'categories.yml'),
|
||||
|
||||
// Rutas de salida
|
||||
OUTPUT_DIR: path.join(__dirname, '..', 'assets', 'processed'),
|
||||
OUTPUT_METADATA: path.join(__dirname, '..', 'assets', 'processed', 'metadata.json'),
|
||||
OUTPUT_STYLES: path.join(__dirname, '..', 'assets', 'processed', 'styles.json'),
|
||||
OUTPUT_CATEGORIES: path.join(__dirname, '..', 'assets', 'processed', 'categories.json'),
|
||||
|
||||
// Configuración de procesamiento
|
||||
MIN_ICONS_TO_PROCESS: 100,
|
||||
VERSION: '2.0.0'
|
||||
};
|
||||
|
||||
// Colores para consola
|
||||
const colors = {
|
||||
reset: '\x1b[0m',
|
||||
green: '\x1b[32m',
|
||||
yellow: '\x1b[33m',
|
||||
blue: '\x1b[34m',
|
||||
red: '\x1b[31m',
|
||||
magenta: '\x1b[35m',
|
||||
cyan: '\x1b[36m'
|
||||
};
|
||||
|
||||
// Banner
|
||||
console.log(colors.cyan + '='.repeat(70));
|
||||
console.log(' EXTRACTOR DE METADATA FONTAWESOME PRO');
|
||||
console.log(' Versión: ' + CONFIG.VERSION);
|
||||
console.log('='.repeat(70) + colors.reset + '\n');
|
||||
|
||||
/**
|
||||
* Crear directorios necesarios
|
||||
*/
|
||||
function createDirectories() {
|
||||
console.log(colors.blue + '📁 Creando directorios...' + colors.reset);
|
||||
|
||||
const dirs = [
|
||||
CONFIG.OUTPUT_DIR,
|
||||
path.join(CONFIG.OUTPUT_DIR, 'backup'),
|
||||
path.join(CONFIG.OUTPUT_DIR, 'logs')
|
||||
];
|
||||
|
||||
dirs.forEach(dir => {
|
||||
if (!fs.existsSync(dir)) {
|
||||
fs.mkdirSync(dir, { recursive: true });
|
||||
console.log(` ✅ Creado: ${path.relative(process.cwd(), dir)}`);
|
||||
} else {
|
||||
console.log(` 📁 Existe: ${path.relative(process.cwd(), dir)}`);
|
||||
}
|
||||
});
|
||||
|
||||
console.log('');
|
||||
}
|
||||
|
||||
/**
|
||||
* Verificar archivos de entrada
|
||||
*/
|
||||
function checkInputFiles() {
|
||||
console.log(colors.blue + '🔍 Verificando archivos de entrada...' + colors.reset);
|
||||
|
||||
const files = [
|
||||
{ path: CONFIG.FA_METADATA, name: 'icons.json', required: true },
|
||||
{ path: CONFIG.FA_CATEGORIES, name: 'categories.yml', required: false }
|
||||
];
|
||||
|
||||
let allFound = true;
|
||||
|
||||
files.forEach(file => {
|
||||
if (fs.existsSync(file.path)) {
|
||||
const stats = fs.statSync(file.path);
|
||||
console.log(` ✅ ${file.name}: ${(stats.size / 1024).toFixed(2)} KB`);
|
||||
|
||||
if (file.name === 'icons.json') {
|
||||
try {
|
||||
const content = fs.readFileSync(file.path, 'utf8');
|
||||
const data = JSON.parse(content);
|
||||
console.log(` Íconos en metadata: ${Object.keys(data).length}`);
|
||||
} catch (error) {
|
||||
console.log(` ❌ ${file.name}: Error de formato - ${error.message}`);
|
||||
allFound = false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (file.required) {
|
||||
console.log(` ❌ ${file.name}: NO ENCONTRADO (requerido)`);
|
||||
allFound = false;
|
||||
} else {
|
||||
console.log(` ⚠️ ${file.name}: No encontrado (opcional)`);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
console.log('');
|
||||
return allFound;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hacer backup de archivos existentes
|
||||
*/
|
||||
function backupExistingFiles() {
|
||||
console.log(colors.blue + '💾 Creando respaldo de archivos existentes...' + colors.reset);
|
||||
|
||||
const filesToBackup = [
|
||||
CONFIG.OUTPUT_METADATA,
|
||||
CONFIG.OUTPUT_STYLES,
|
||||
CONFIG.OUTPUT_CATEGORIES
|
||||
];
|
||||
|
||||
const backupDir = path.join(CONFIG.OUTPUT_DIR, 'backup', new Date().toISOString().replace(/[:.]/g, '-'));
|
||||
|
||||
if (!fs.existsSync(backupDir)) {
|
||||
fs.mkdirSync(backupDir, { recursive: true });
|
||||
}
|
||||
|
||||
let backedUpCount = 0;
|
||||
|
||||
filesToBackup.forEach(file => {
|
||||
if (fs.existsSync(file)) {
|
||||
const fileName = path.basename(file);
|
||||
const backupPath = path.join(backupDir, fileName);
|
||||
|
||||
try {
|
||||
fs.copyFileSync(file, backupPath);
|
||||
console.log(` ✅ Respaldo: ${fileName}`);
|
||||
backedUpCount++;
|
||||
} catch (error) {
|
||||
console.log(` ❌ Error respaldando ${fileName}: ${error.message}`);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (backedUpCount > 0) {
|
||||
console.log(` 📊 Total respaldados: ${backedUpCount} archivos`);
|
||||
console.log(` 📍 Ubicación: ${path.relative(process.cwd(), backupDir)}`);
|
||||
} else {
|
||||
console.log(' ⚠️ No hay archivos existentes para respaldar');
|
||||
}
|
||||
|
||||
console.log('');
|
||||
return backupDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extraer y procesar metadata de íconos
|
||||
*/
|
||||
function extractIconMetadata() {
|
||||
console.log(colors.blue + '📊 Extrayendo metadata de íconos...' + colors.reset);
|
||||
|
||||
try {
|
||||
// Leer archivo original
|
||||
const content = fs.readFileSync(CONFIG.FA_METADATA, 'utf8');
|
||||
const rawMetadata = JSON.parse(content);
|
||||
|
||||
const totalIcons = Object.keys(rawMetadata).length;
|
||||
console.log(` 📈 Total íconos encontrados: ${totalIcons}`);
|
||||
|
||||
if (totalIcons < CONFIG.MIN_ICONS_TO_PROCESS) {
|
||||
throw new Error(`Muy pocos íconos (${totalIcons}). ¿Metadata corrupto?`);
|
||||
}
|
||||
|
||||
// Procesar cada ícono
|
||||
const processedIcons = {};
|
||||
let processedCount = 0;
|
||||
let stylesFound = new Set();
|
||||
let categoriesFound = new Set();
|
||||
|
||||
Object.entries(rawMetadata).forEach(([iconName, iconData]) => {
|
||||
processedCount++;
|
||||
|
||||
// Mostrar progreso cada 1000 íconos
|
||||
if (processedCount % 1000 === 0) {
|
||||
console.log(` ⏳ Procesados: ${processedCount}/${totalIcons} íconos...`);
|
||||
}
|
||||
|
||||
// Extraer información básica
|
||||
const processedIcon = {
|
||||
id: iconName,
|
||||
name: iconName,
|
||||
label: iconData.label || formatIconName(iconName),
|
||||
unicode: iconData.unicode || '',
|
||||
version: iconData.version || '6.0.0',
|
||||
search: iconData.search || {}
|
||||
};
|
||||
|
||||
// Estilos disponibles
|
||||
if (iconData.styles && Array.isArray(iconData.styles)) {
|
||||
processedIcon.styles = iconData.styles.map(style => style.toLowerCase());
|
||||
iconData.styles.forEach(style => stylesFound.add(style.toLowerCase()));
|
||||
} else {
|
||||
processedIcon.styles = [];
|
||||
}
|
||||
|
||||
// Categorías
|
||||
if (iconData.categories && Array.isArray(iconData.categories)) {
|
||||
processedIcon.categories = iconData.categories;
|
||||
iconData.categories.forEach(cat => categoriesFound.add(cat));
|
||||
} else {
|
||||
processedIcon.categories = ['uncategorized'];
|
||||
categoriesFound.add('uncategorized');
|
||||
}
|
||||
|
||||
// Información adicional
|
||||
if (iconData.svg) {
|
||||
processedIcon.svg = {
|
||||
width: iconData.svg.width,
|
||||
height: iconData.svg.height,
|
||||
path: iconData.svg.path
|
||||
};
|
||||
}
|
||||
|
||||
// Términos de búsqueda mejorados
|
||||
const searchTerms = new Set();
|
||||
|
||||
// Términos originales
|
||||
if (iconData.search && iconData.search.terms) {
|
||||
iconData.search.terms.forEach(term => {
|
||||
if (term && typeof term === 'string') {
|
||||
searchTerms.add(term.toLowerCase());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Agregar nombre y label
|
||||
searchTerms.add(iconName.toLowerCase());
|
||||
if (iconData.label) {
|
||||
searchTerms.add(iconData.label.toLowerCase());
|
||||
// Variantes sin espacios
|
||||
searchTerms.add(iconData.label.toLowerCase().replace(/\s+/g, '-'));
|
||||
}
|
||||
|
||||
// Agregar sinónimos comunes
|
||||
addCommonSynonyms(iconName, searchTerms);
|
||||
|
||||
processedIcon.searchTerms = Array.from(searchTerms);
|
||||
processedIcon.searchCount = searchTerms.size;
|
||||
|
||||
// Agregar a resultados
|
||||
processedIcons[iconName] = processedIcon;
|
||||
});
|
||||
|
||||
console.log(`\n ✅ Procesados: ${processedCount} íconos`);
|
||||
console.log(` 🎨 Estilos encontrados: ${stylesFound.size}`);
|
||||
console.log(` 📁 Categorías encontradas: ${categoriesFound.size}`);
|
||||
|
||||
// Guardar metadata procesado
|
||||
const metadataOutput = {
|
||||
meta: {
|
||||
generated: new Date().toISOString(),
|
||||
source: 'FontAwesome Pro',
|
||||
version: CONFIG.VERSION,
|
||||
totalIcons: processedCount,
|
||||
totalStyles: stylesFound.size,
|
||||
totalCategories: categoriesFound.size
|
||||
},
|
||||
icons: processedIcons,
|
||||
statistics: {
|
||||
styles: Array.from(stylesFound).sort(),
|
||||
categories: Array.from(categoriesFound).sort(),
|
||||
iconsPerStyle: countIconsPerStyle(processedIcons),
|
||||
iconsPerCategory: countIconsPerCategory(processedIcons)
|
||||
}
|
||||
};
|
||||
|
||||
fs.writeFileSync(CONFIG.OUTPUT_METADATA, JSON.stringify(metadataOutput, null, 2), 'utf8');
|
||||
console.log(`\n 💾 Metadata guardado: ${CONFIG.OUTPUT_METADATA}`);
|
||||
console.log(` 📊 Tamaño: ${(fs.statSync(CONFIG.OUTPUT_METADATA).size / 1024 / 1024).toFixed(2)} MB`);
|
||||
|
||||
return metadataOutput;
|
||||
|
||||
} catch (error) {
|
||||
console.error(colors.red + ` ❌ Error procesando metadata: ${error.message}` + colors.reset);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Formatear nombre de ícono
|
||||
*/
|
||||
function formatIconName(iconName) {
|
||||
return iconName
|
||||
.split('-')
|
||||
.map(word => word.charAt(0).toUpperCase() + word.slice(1))
|
||||
.join(' ');
|
||||
}
|
||||
|
||||
/**
|
||||
* Agregar sinónimos comunes
|
||||
*/
|
||||
function addCommonSynonyms(iconName, searchTerms) {
|
||||
const synonyms = {
|
||||
'home': ['house', 'casa', 'hogar', 'dwelling', 'residence'],
|
||||
'user': ['person', 'profile', 'persona', 'perfil', 'account', 'human'],
|
||||
'heart': ['love', 'like', 'favorite', 'amor', 'favorito', 'affection'],
|
||||
'star': ['favorite', 'rating', 'estrella', 'calificación', 'rate', 'review'],
|
||||
'settings': ['cog', 'gear', 'preferences', 'configuración', 'ajustes', 'options'],
|
||||
'bell': ['notification', 'alert', 'notificación', 'alerta', 'ring', 'chime'],
|
||||
'envelope': ['email', 'mail', 'correo', 'message', 'letter'],
|
||||
'calendar': ['date', 'schedule', 'fecha', 'calendario', 'agenda', 'planner'],
|
||||
'clock': ['time', 'hour', 'tiempo', 'hora', 'watch', 'timer'],
|
||||
'search': ['find', 'lookup', 'buscar', 'encontrar', 'seek', 'locate'],
|
||||
'plus': ['add', 'new', 'create', 'agregar', 'añadir', 'insert'],
|
||||
'minus': ['remove', 'delete', 'subtract', 'quitar', 'eliminar', 'restar'],
|
||||
'check': ['verify', 'confirm', 'mark', 'verificar', 'confirmar', 'tick'],
|
||||
'times': ['close', 'exit', 'cancel', 'cerrar', 'salir', 'cancelar'],
|
||||
'trash': ['delete', 'remove', 'garbage', 'eliminar', 'basura', 'waste'],
|
||||
'edit': ['modify', 'change', 'update', 'modificar', 'cambiar', 'actualizar'],
|
||||
'download': ['save', 'get', 'fetch', 'descargar', 'guardar', 'obtener'],
|
||||
'upload': ['send', 'share', 'post', 'subir', 'enviar', 'compartir'],
|
||||
'print': ['printer', 'hardcopy', 'paper', 'imprimir', 'copiar', 'document']
|
||||
};
|
||||
|
||||
Object.entries(synonyms).forEach(([key, words]) => {
|
||||
if (iconName.includes(key)) {
|
||||
words.forEach(word => searchTerms.add(word));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Contar íconos por estilo
|
||||
*/
|
||||
function countIconsPerStyle(icons) {
|
||||
const counts = {};
|
||||
|
||||
Object.values(icons).forEach(icon => {
|
||||
if (icon.styles) {
|
||||
icon.styles.forEach(style => {
|
||||
counts[style] = (counts[style] || 0) + 1;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return counts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Contar íconos por categoría
|
||||
*/
|
||||
function countIconsPerCategory(icons) {
|
||||
const counts = {};
|
||||
|
||||
Object.values(icons).forEach(icon => {
|
||||
if (icon.categories) {
|
||||
icon.categories.forEach(category => {
|
||||
counts[category] = (counts[category] || 0) + 1;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return counts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extraer información de estilos
|
||||
*/
|
||||
function extractStyleInfo(metadata) {
|
||||
console.log(colors.blue + '\n🎨 Extrayendo información de estilos...' + colors.reset);
|
||||
|
||||
// Definición de todos los estilos posibles
|
||||
const allStyles = {
|
||||
'solid': {
|
||||
id: 'solid',
|
||||
name: 'Solid',
|
||||
prefix: 'fas',
|
||||
class: 'fas',
|
||||
weight: 900,
|
||||
pro: true,
|
||||
sharp: false,
|
||||
family: 'Font Awesome 6 Pro',
|
||||
file: 'fa-solid-900.woff2'
|
||||
},
|
||||
'regular': {
|
||||
id: 'regular',
|
||||
name: 'Regular',
|
||||
prefix: 'far',
|
||||
class: 'far',
|
||||
weight: 400,
|
||||
pro: true,
|
||||
sharp: false,
|
||||
family: 'Font Awesome 6 Pro',
|
||||
file: 'fa-regular-400.woff2'
|
||||
},
|
||||
'light': {
|
||||
id: 'light',
|
||||
name: 'Light',
|
||||
prefix: 'fal',
|
||||
class: 'fal',
|
||||
weight: 300,
|
||||
pro: true,
|
||||
sharp: false,
|
||||
family: 'Font Awesome 6 Pro',
|
||||
file: 'fa-light-300.woff2'
|
||||
},
|
||||
'thin': {
|
||||
id: 'thin',
|
||||
name: 'Thin',
|
||||
prefix: 'fat',
|
||||
class: 'fat',
|
||||
weight: 100,
|
||||
pro: true,
|
||||
sharp: false,
|
||||
family: 'Font Awesome 6 Pro',
|
||||
file: 'fa-thin-100.woff2'
|
||||
},
|
||||
'duotone': {
|
||||
id: 'duotone',
|
||||
name: 'Duotone',
|
||||
prefix: 'fad',
|
||||
class: 'fad',
|
||||
weight: 900,
|
||||
pro: true,
|
||||
sharp: false,
|
||||
family: 'Font Awesome 6 Duotone',
|
||||
file: 'fa-duotone-900.woff2'
|
||||
},
|
||||
'sharp-solid': {
|
||||
id: 'sharp-solid',
|
||||
name: 'Sharp Solid',
|
||||
prefix: 'fass',
|
||||
class: 'fass',
|
||||
weight: 900,
|
||||
pro: true,
|
||||
sharp: true,
|
||||
family: 'Font Awesome 6 Sharp',
|
||||
file: 'fa-sharp-solid-900.woff2'
|
||||
},
|
||||
'sharp-regular': {
|
||||
id: 'sharp-regular',
|
||||
name: 'Sharp Regular',
|
||||
prefix: 'fasr',
|
||||
class: 'fasr',
|
||||
weight: 400,
|
||||
pro: true,
|
||||
sharp: true,
|
||||
family: 'Font Awesome 6 Sharp',
|
||||
file: 'fa-sharp-regular-400.woff2'
|
||||
},
|
||||
'sharp-light': {
|
||||
id: 'sharp-light',
|
||||
name: 'Sharp Light',
|
||||
prefix: 'fasl',
|
||||
class: 'fasl',
|
||||
weight: 300,
|
||||
pro: true,
|
||||
sharp: true,
|
||||
family: 'Font Awesome 6 Sharp',
|
||||
file: 'fa-sharp-light-300.woff2'
|
||||
},
|
||||
'sharp-thin': {
|
||||
id: 'sharp-thin',
|
||||
name: 'Sharp Thin',
|
||||
prefix: 'fast',
|
||||
class: 'fast',
|
||||
weight: 100,
|
||||
pro: true,
|
||||
sharp: true,
|
||||
family: 'Font Awesome 6 Sharp',
|
||||
file: 'fa-sharp-thin-100.woff2'
|
||||
},
|
||||
'sharp-duotone': {
|
||||
id: 'sharp-duotone',
|
||||
name: 'Sharp Duotone',
|
||||
prefix: 'fasd',
|
||||
class: 'fasd',
|
||||
weight: 900,
|
||||
pro: true,
|
||||
sharp: true,
|
||||
family: 'Font Awesome 6 Sharp Duotone',
|
||||
file: 'fa-sharp-duotone-900.woff2'
|
||||
},
|
||||
'brands': {
|
||||
id: 'brands',
|
||||
name: 'Brands',
|
||||
prefix: 'fab',
|
||||
class: 'fab',
|
||||
weight: 400,
|
||||
pro: false,
|
||||
sharp: false,
|
||||
family: 'Font Awesome 6 Brands',
|
||||
file: 'fa-brands-400.woff2'
|
||||
}
|
||||
};
|
||||
|
||||
// Contar íconos por estilo (desde metadata)
|
||||
const styleCounts = metadata.statistics.iconsPerStyle || {};
|
||||
|
||||
// Enriquecer información de estilos
|
||||
const stylesInfo = {};
|
||||
|
||||
Object.keys(allStyles).forEach(styleId => {
|
||||
const style = allStyles[styleId];
|
||||
const count = styleCounts[styleId] || 0;
|
||||
|
||||
stylesInfo[styleId] = {
|
||||
...style,
|
||||
count: count,
|
||||
availableInMetadata: count > 0,
|
||||
percentage: metadata.meta.totalIcons > 0
|
||||
? ((count / metadata.meta.totalIcons) * 100).toFixed(1)
|
||||
: '0.0'
|
||||
};
|
||||
});
|
||||
|
||||
// Guardar información de estilos
|
||||
const stylesOutput = {
|
||||
meta: {
|
||||
generated: new Date().toISOString(),
|
||||
totalStyles: Object.keys(stylesInfo).length,
|
||||
stylesWithIcons: Object.values(stylesInfo).filter(s => s.count > 0).length
|
||||
},
|
||||
styles: stylesInfo,
|
||||
statistics: {
|
||||
totalIconsByStyle: styleCounts,
|
||||
styleCoverage: calculateStyleCoverage(stylesInfo, metadata.meta.totalIcons)
|
||||
}
|
||||
};
|
||||
|
||||
fs.writeFileSync(CONFIG.OUTPUT_STYLES, JSON.stringify(stylesOutput, null, 2), 'utf8');
|
||||
console.log(` ✅ Información de estilos guardada: ${CONFIG.OUTPUT_STYLES}`);
|
||||
|
||||
// Mostrar resumen
|
||||
console.log('\n 📊 RESUMEN DE ESTILOS:');
|
||||
Object.values(stylesInfo)
|
||||
.filter(style => style.count > 0)
|
||||
.sort((a, b) => b.count - a.count)
|
||||
.forEach(style => {
|
||||
console.log(` ${style.name.padEnd(20)}: ${style.count.toString().padStart(5)} íconos (${style.percentage}%)`);
|
||||
});
|
||||
|
||||
return stylesOutput;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calcular cobertura de estilos
|
||||
*/
|
||||
function calculateStyleCoverage(stylesInfo, totalIcons) {
|
||||
const coverage = {};
|
||||
|
||||
Object.values(stylesInfo).forEach(style => {
|
||||
if (style.count > 0) {
|
||||
coverage[style.id] = {
|
||||
hasIcons: true,
|
||||
count: style.count,
|
||||
percentage: ((style.count / totalIcons) * 100).toFixed(1)
|
||||
};
|
||||
} else {
|
||||
coverage[style.id] = {
|
||||
hasIcons: false,
|
||||
count: 0,
|
||||
percentage: '0.0'
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
return coverage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extraer y procesar categorías
|
||||
*/
|
||||
function extractCategories(metadata) {
|
||||
console.log(colors.blue + '\n📁 Extrayendo información de categorías...' + colors.reset);
|
||||
|
||||
// Mapeo de categorías de FontAwesome a nombres en español
|
||||
const categoriesMap = {
|
||||
'accessibility': 'Accesibilidad',
|
||||
'alert': 'Alertas',
|
||||
'animals': 'Animales',
|
||||
'arrows': 'Flechas',
|
||||
'automotive': 'Automotriz',
|
||||
'buildings': 'Edificios',
|
||||
'business': 'Negocios',
|
||||
'camping': 'Camping',
|
||||
'charity': 'Caridad',
|
||||
'charts-diagrams': 'Gráficos',
|
||||
'childhood': 'Infancia',
|
||||
'clothing-fashion': 'Ropa & Moda',
|
||||
'coding': 'Programación',
|
||||
'communication': 'Comunicación',
|
||||
'connectivity': 'Conectividad',
|
||||
'construction': 'Construcción',
|
||||
'design': 'Diseño',
|
||||
'devices-hardware': 'Dispositivos',
|
||||
'document': 'Documentos',
|
||||
'editing': 'Edición',
|
||||
'education': 'Educación',
|
||||
'emoji': 'Emoji',
|
||||
'energy': 'Energía',
|
||||
'files': 'Archivos',
|
||||
'film-video': 'Video',
|
||||
'food-beverage': 'Comida',
|
||||
'fruits-vegetables': 'Frutas',
|
||||
'gaming': 'Juegos',
|
||||
'gender': 'Género',
|
||||
'halloween': 'Halloween',
|
||||
'hands': 'Manos',
|
||||
'holidays': 'Fiestas',
|
||||
'household': 'Hogar',
|
||||
'humanitarian': 'Humanitario',
|
||||
'logistics': 'Logística',
|
||||
'maps': 'Mapas',
|
||||
'maritime': 'Marítimo',
|
||||
'marketing': 'Marketing',
|
||||
'mathematics': 'Matemáticas',
|
||||
'medical-health': 'Salud',
|
||||
'money': 'Dinero',
|
||||
'moving': 'Mudanza',
|
||||
'music-audio': 'Música',
|
||||
'nature': 'Naturaleza',
|
||||
'numbers': 'Números',
|
||||
'photos-images': 'Fotos',
|
||||
'political': 'Política',
|
||||
'punctuation-symbols': 'Símbolos',
|
||||
'religion': 'Religión',
|
||||
'science': 'Ciencia',
|
||||
'science-fiction': 'Sci-Fi',
|
||||
'security': 'Seguridad',
|
||||
'shapes': 'Formas',
|
||||
'shopping': 'Compras',
|
||||
'social': 'Social',
|
||||
'spinners': 'Spinners',
|
||||
'sports-fitness': 'Deportes',
|
||||
'text-formatting': 'Texto',
|
||||
'time': 'Tiempo',
|
||||
'toggle': 'Toggle',
|
||||
'transportation': 'Transporte',
|
||||
'travel': 'Viajes',
|
||||
'users-people': 'Personas',
|
||||
'weather': 'Clima',
|
||||
'writing': 'Escritura',
|
||||
'uncategorized': 'Sin Categoría'
|
||||
};
|
||||
|
||||
// Obtener conteos de categorías desde metadata
|
||||
const categoryCounts = metadata.statistics.iconsPerCategory || {};
|
||||
|
||||
// Procesar categorías
|
||||
const categories = [];
|
||||
|
||||
// Categorías especiales
|
||||
categories.push({
|
||||
id: 'all',
|
||||
name: 'Todos los Íconos',
|
||||
icon: 'fas fa-th',
|
||||
count: metadata.meta.totalIcons,
|
||||
type: 'special'
|
||||
});
|
||||
|
||||
categories.push({
|
||||
id: 'favorites',
|
||||
name: 'Favoritos',
|
||||
icon: 'fas fa-star',
|
||||
count: 0,
|
||||
type: 'special'
|
||||
});
|
||||
|
||||
categories.push({
|
||||
id: 'recent',
|
||||
name: 'Recientes',
|
||||
icon: 'fas fa-history',
|
||||
count: 0,
|
||||
type: 'special'
|
||||
});
|
||||
|
||||
// Categorías de FontAwesome
|
||||
Object.entries(categoryCounts).forEach(([categoryId, count]) => {
|
||||
const categoryName = categoriesMap[categoryId] || formatCategoryName(categoryId);
|
||||
|
||||
categories.push({
|
||||
id: categoryId,
|
||||
name: categoryName,
|
||||
icon: getCategoryIcon(categoryId),
|
||||
count: count,
|
||||
type: 'fontawesome'
|
||||
});
|
||||
});
|
||||
|
||||
// Ordenar categorías
|
||||
categories.sort((a, b) => {
|
||||
// Categorías especiales primero
|
||||
if (a.type === 'special' && b.type !== 'special') return -1;
|
||||
if (a.type !== 'special' && b.type === 'special') return 1;
|
||||
|
||||
// Luego por nombre
|
||||
return a.name.localeCompare(b.name);
|
||||
});
|
||||
|
||||
// Guardar categorías
|
||||
const categoriesOutput = {
|
||||
meta: {
|
||||
generated: new Date().toISOString(),
|
||||
totalCategories: categories.length,
|
||||
fontawesomeCategories: Object.keys(categoryCounts).length
|
||||
},
|
||||
categories: categories,
|
||||
mapping: categoriesMap
|
||||
};
|
||||
|
||||
fs.writeFileSync(CONFIG.OUTPUT_CATEGORIES, JSON.stringify(categoriesOutput, null, 2), 'utf8');
|
||||
console.log(` ✅ Categorías guardadas: ${CONFIG.OUTPUT_CATEGORIES}`);
|
||||
console.log(` 📊 Total categorías: ${categories.length}`);
|
||||
|
||||
// Mostrar top 10 categorías
|
||||
console.log('\n 🏆 TOP 10 CATEGORÍAS:');
|
||||
categories
|
||||
.filter(cat => cat.type === 'fontawesome')
|
||||
.sort((a, b) => b.count - a.count)
|
||||
.slice(0, 10)
|
||||
.forEach((cat, index) => {
|
||||
console.log(` ${index + 1}. ${cat.name.padEnd(25)}: ${cat.count} íconos`);
|
||||
});
|
||||
|
||||
return categoriesOutput;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formatear nombre de categoría
|
||||
*/
|
||||
function formatCategoryName(categoryId) {
|
||||
return categoryId
|
||||
.split('-')
|
||||
.map(word => word.charAt(0).toUpperCase() + word.slice(1))
|
||||
.join(' ');
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtener ícono para categoría
|
||||
*/
|
||||
function getCategoryIcon(categoryId) {
|
||||
const iconMap = {
|
||||
'accessibility': 'fas fa-universal-access',
|
||||
'alert': 'fas fa-exclamation-triangle',
|
||||
'animals': 'fas fa-paw',
|
||||
'arrows': 'fas fa-arrow-right',
|
||||
'buildings': 'fas fa-building',
|
||||
'business': 'fas fa-briefcase',
|
||||
'coding': 'fas fa-code',
|
||||
'communication': 'fas fa-comments',
|
||||
'design': 'fas fa-palette',
|
||||
'devices-hardware': 'fas fa-laptop',
|
||||
'education': 'fas fa-graduation-cap',
|
||||
'files': 'fas fa-folder',
|
||||
'food-beverage': 'fas fa-utensils',
|
||||
'health': 'fas fa-heartbeat',
|
||||
'household': 'fas fa-home',
|
||||
'maps': 'fas fa-map',
|
||||
'music-audio': 'fas fa-music',
|
||||
'nature': 'fas fa-leaf',
|
||||
'shopping': 'fas fa-shopping-cart',
|
||||
'sports-fitness': 'fas fa-football-ball',
|
||||
'travel': 'fas fa-plane',
|
||||
'users-people': 'fas fa-user-friends',
|
||||
'weather': 'fas fa-cloud-sun',
|
||||
'writing': 'fas fa-pen-fancy'
|
||||
};
|
||||
|
||||
return iconMap[categoryId] || 'fas fa-folder';
|
||||
}
|
||||
|
||||
/**
|
||||
* Generar reporte de procesamiento
|
||||
*/
|
||||
function generateReport(metadata, styles, categories) {
|
||||
console.log(colors.blue + '\n📋 Generando reporte de procesamiento...' + colors.reset);
|
||||
|
||||
const reportPath = path.join(CONFIG.OUTPUT_DIR, 'logs', `report-${new Date().toISOString().replace(/[:.]/g, '-')}.json`);
|
||||
|
||||
const report = {
|
||||
meta: {
|
||||
generated: new Date().toISOString(),
|
||||
version: CONFIG.VERSION,
|
||||
duration: new Date() - startTime
|
||||
},
|
||||
summary: {
|
||||
totalIcons: metadata.meta.totalIcons,
|
||||
totalStyles: styles.meta.totalStyles,
|
||||
stylesWithIcons: styles.meta.stylesWithIcons,
|
||||
totalCategories: categories.meta.totalCategories
|
||||
},
|
||||
files: {
|
||||
metadata: CONFIG.OUTPUT_METADATA,
|
||||
styles: CONFIG.OUTPUT_STYLES,
|
||||
categories: CONFIG.OUTPUT_CATEGORIES
|
||||
},
|
||||
statistics: {
|
||||
iconsPerStyle: metadata.statistics.iconsPerStyle,
|
||||
iconsPerCategory: metadata.statistics.iconsPerCategory,
|
||||
styleCoverage: styles.statistics.styleCoverage
|
||||
}
|
||||
};
|
||||
|
||||
fs.writeFileSync(reportPath, JSON.stringify(report, null, 2), 'utf8');
|
||||
console.log(` ✅ Reporte guardado: ${reportPath}`);
|
||||
|
||||
return report;
|
||||
}
|
||||
|
||||
/**
|
||||
* Función principal
|
||||
*/
|
||||
async function main() {
|
||||
global.startTime = new Date();
|
||||
|
||||
try {
|
||||
console.log(colors.green + '🚀 Iniciando extracción de metadata...' + colors.reset);
|
||||
|
||||
// 1. Crear directorios
|
||||
createDirectories();
|
||||
|
||||
// 2. Verificar archivos de entrada
|
||||
if (!checkInputFiles()) {
|
||||
console.log(colors.red + '❌ Archivos requeridos no encontrados. Abortando.' + colors.reset);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// 3. Hacer backup
|
||||
backupExistingFiles();
|
||||
|
||||
// 4. Extraer metadata de íconos
|
||||
const metadata = extractIconMetadata();
|
||||
|
||||
// 5. Extraer información de estilos
|
||||
const styles = extractStyleInfo(metadata);
|
||||
|
||||
// 6. Extraer y procesar categorías
|
||||
const categories = extractCategories(metadata);
|
||||
|
||||
// 7. Generar reporte
|
||||
const report = generateReport(metadata, styles, categories);
|
||||
|
||||
// 8. Mostrar resumen final
|
||||
const duration = ((new Date() - startTime) / 1000).toFixed(2);
|
||||
|
||||
console.log(colors.green + '\n' + '='.repeat(70));
|
||||
console.log(' ✅ EXTRACCIÓN COMPLETADA EXITOSAMENTE');
|
||||
console.log('='.repeat(70) + colors.reset);
|
||||
|
||||
console.log(`\n📊 RESUMEN FINAL:`);
|
||||
console.log(` • Íconos procesados: ${metadata.meta.totalIcons}`);
|
||||
console.log(` • Estilos encontrados: ${styles.meta.stylesWithIcons}/${styles.meta.totalStyles}`);
|
||||
console.log(` • Categorías: ${categories.meta.totalCategories}`);
|
||||
console.log(` • Tiempo total: ${duration} segundos`);
|
||||
console.log(`\n📁 ARCHIVOS GENERADOS:`);
|
||||
console.log(` • ${path.relative(process.cwd(), CONFIG.OUTPUT_METADATA)}`);
|
||||
console.log(` • ${path.relative(process.cwd(), CONFIG.OUTPUT_STYLES)}`);
|
||||
console.log(` • ${path.relative(process.cwd(), CONFIG.OUTPUT_CATEGORIES)}`);
|
||||
console.log(`\n🚀 PRÓXIMOS PASOS:`);
|
||||
console.log(` • Ejecuta: npm run build`);
|
||||
console.log(` • Luego instala el plugin en Logseq`);
|
||||
|
||||
console.log(colors.green + '\n🎉 ¡Listo para construir la base de datos final!' + colors.reset);
|
||||
|
||||
} catch (error) {
|
||||
console.error(colors.red + '\n❌ ERROR CRÍTICO:' + colors.reset);
|
||||
console.error(` ${error.message}`);
|
||||
console.error(`\n🔧 Solución:`);
|
||||
console.error(` 1. Verifica que tengas FontAwesome 6 Pro instalado`);
|
||||
console.error(` 2. Asegúrate de que metadata/icons.json sea válido`);
|
||||
console.error(` 3. Intenta ejecutar 'npm run verify' primero`);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// Ejecutar
|
||||
if (require.main === module) {
|
||||
main();
|
||||
}
|
||||
|
||||
// Exportar funciones para uso en otros scripts
|
||||
module.exports = {
|
||||
extractIconMetadata,
|
||||
extractStyleInfo,
|
||||
extractCategories,
|
||||
createDirectories,
|
||||
checkInputFiles,
|
||||
CONFIG
|
||||
};
|
||||
331
scripts/validate-styles.js
Normal file
331
scripts/validate-styles.js
Normal file
@@ -0,0 +1,331 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { execSync } = require('child_process');
|
||||
|
||||
// Configuración
|
||||
const CONFIG = {
|
||||
WEBFONTS_DIR: path.join(__dirname, '..', 'assets', 'fontawesome', 'webfonts'),
|
||||
PROCESSED_DIR: path.join(__dirname, '..', 'assets', 'processed'),
|
||||
OUTPUT_REPORT: path.join(__dirname, '..', 'assets', 'processed', 'validation-report.json'),
|
||||
VERSION: '2.0.0'
|
||||
};
|
||||
|
||||
console.log('🔍 Validando estilos FontAwesome Pro...\n');
|
||||
|
||||
/**
|
||||
* Validar archivos de fuentes
|
||||
*/
|
||||
function validateFontFiles() {
|
||||
console.log('🎨 Validando archivos de fuentes...');
|
||||
|
||||
const expectedFiles = [
|
||||
'fa-solid-900.woff2',
|
||||
'fa-regular-400.woff2',
|
||||
'fa-light-300.woff2',
|
||||
'fa-thin-100.woff2',
|
||||
'fa-duotone-900.woff2',
|
||||
'fa-sharp-solid-900.woff2',
|
||||
'fa-sharp-regular-400.woff2',
|
||||
'fa-sharp-light-300.woff2',
|
||||
'fa-sharp-thin-100.woff2',
|
||||
'fa-sharp-duotone-900.woff2',
|
||||
'fa-brands-400.woff2'
|
||||
];
|
||||
|
||||
const results = {
|
||||
total: expectedFiles.length,
|
||||
found: 0,
|
||||
missing: [],
|
||||
details: {}
|
||||
};
|
||||
|
||||
expectedFiles.forEach(file => {
|
||||
const filePath = path.join(CONFIG.WEBFONTS_DIR, file);
|
||||
const exists = fs.existsSync(filePath);
|
||||
|
||||
results.details[file] = {
|
||||
exists: exists,
|
||||
path: filePath,
|
||||
size: exists ? fs.statSync(filePath).size : 0
|
||||
};
|
||||
|
||||
if (exists) {
|
||||
results.found++;
|
||||
console.log(` ✅ ${file}`);
|
||||
} else {
|
||||
results.missing.push(file);
|
||||
console.log(` ❌ ${file} (FALTANTE)`);
|
||||
}
|
||||
});
|
||||
|
||||
console.log(`\n📊 Resumen: ${results.found}/${results.total} archivos encontrados`);
|
||||
|
||||
if (results.missing.length > 0) {
|
||||
console.log('\n⚠️ Archivos faltantes:');
|
||||
results.missing.forEach(file => {
|
||||
console.log(` • ${file}`);
|
||||
});
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validar metadata procesado
|
||||
*/
|
||||
function validateProcessedMetadata() {
|
||||
console.log('\n📊 Validando metadata procesado...');
|
||||
|
||||
const metadataPath = path.join(CONFIG.PROCESSED_DIR, 'metadata.json');
|
||||
const stylesPath = path.join(CONFIG.PROCESSED_DIR, 'styles.json');
|
||||
const categoriesPath = path.join(CONFIG.PROCESSED_DIR, 'categories.json');
|
||||
|
||||
const results = {
|
||||
metadata: { valid: false, error: null, data: null },
|
||||
styles: { valid: false, error: null, data: null },
|
||||
categories: { valid: false, error: null, data: null }
|
||||
};
|
||||
|
||||
// Validar metadata.json
|
||||
try {
|
||||
if (fs.existsSync(metadataPath)) {
|
||||
const content = fs.readFileSync(metadataPath, 'utf8');
|
||||
const data = JSON.parse(content);
|
||||
|
||||
if (data.meta && data.icons && data.statistics) {
|
||||
results.metadata = {
|
||||
valid: true,
|
||||
data: {
|
||||
totalIcons: data.meta.totalIcons || 0,
|
||||
totalStyles: data.statistics.styles?.length || 0,
|
||||
totalCategories: data.statistics.categories?.length || 0
|
||||
}
|
||||
};
|
||||
console.log(` ✅ metadata.json: ${results.metadata.data.totalIcons} íconos`);
|
||||
} else {
|
||||
results.metadata.error = 'Estructura inválida';
|
||||
console.log(` ❌ metadata.json: Estructura inválida`);
|
||||
}
|
||||
} else {
|
||||
results.metadata.error = 'Archivo no encontrado';
|
||||
console.log(` ❌ metadata.json: No encontrado`);
|
||||
}
|
||||
} catch (error) {
|
||||
results.metadata.error = error.message;
|
||||
console.log(` ❌ metadata.json: Error - ${error.message}`);
|
||||
}
|
||||
|
||||
// Validar styles.json
|
||||
try {
|
||||
if (fs.existsSync(stylesPath)) {
|
||||
const content = fs.readFileSync(stylesPath, 'utf8');
|
||||
const data = JSON.parse(content);
|
||||
|
||||
if (data.meta && data.styles) {
|
||||
const stylesWithIcons = Object.values(data.styles).filter(s => s.count > 0).length;
|
||||
results.styles = {
|
||||
valid: true,
|
||||
data: {
|
||||
totalStyles: data.meta.totalStyles || 0,
|
||||
stylesWithIcons: stylesWithIcons
|
||||
}
|
||||
};
|
||||
console.log(` ✅ styles.json: ${stylesWithIcons}/${data.meta.totalStyles} estilos con íconos`);
|
||||
} else {
|
||||
results.styles.error = 'Estructura inválida';
|
||||
console.log(` ❌ styles.json: Estructura inválida`);
|
||||
}
|
||||
} else {
|
||||
results.styles.error = 'Archivo no encontrado';
|
||||
console.log(` ❌ styles.json: No encontrado`);
|
||||
}
|
||||
} catch (error) {
|
||||
results.styles.error = error.message;
|
||||
console.log(` ❌ styles.json: Error - ${error.message}`);
|
||||
}
|
||||
|
||||
// Validar categories.json
|
||||
try {
|
||||
if (fs.existsSync(categoriesPath)) {
|
||||
const content = fs.readFileSync(categoriesPath, 'utf8');
|
||||
const data = JSON.parse(content);
|
||||
|
||||
if (data.meta && data.categories) {
|
||||
const fontawesomeCategories = data.categories.filter(c => c.type === 'fontawesome').length;
|
||||
results.categories = {
|
||||
valid: true,
|
||||
data: {
|
||||
totalCategories: data.meta.totalCategories || 0,
|
||||
fontawesomeCategories: fontawesomeCategories
|
||||
}
|
||||
};
|
||||
console.log(` ✅ categories.json: ${data.meta.totalCategories} categorías totales`);
|
||||
} else {
|
||||
results.categories.error = 'Estructura inválida';
|
||||
console.log(` ❌ categories.json: Estructura inválida`);
|
||||
}
|
||||
} else {
|
||||
results.categories.error = 'Archivo no encontrado';
|
||||
console.log(` ❌ categories.json: No encontrado`);
|
||||
}
|
||||
} catch (error) {
|
||||
results.categories.error = error.message;
|
||||
console.log(` ❌ categories.json: Error - ${error.message}`);
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validar compatibilidad
|
||||
*/
|
||||
function validateCompatibility(fontResults, metadataResults) {
|
||||
console.log('\n🔗 Validando compatibilidad...');
|
||||
|
||||
const issues = [];
|
||||
|
||||
// Verificar si hay estilos en metadata pero no en archivos
|
||||
if (metadataResults.styles.valid && metadataResults.styles.data) {
|
||||
const stylesWithIcons = metadataResults.styles.data.stylesWithIcons;
|
||||
|
||||
if (stylesWithIcons > fontResults.found) {
|
||||
issues.push({
|
||||
type: 'warning',
|
||||
message: `Hay ${stylesWithIcons} estilos en metadata pero solo ${fontResults.found} archivos de fuentes`
|
||||
});
|
||||
console.log(` ⚠️ Posible falta de archivos de fuentes`);
|
||||
}
|
||||
}
|
||||
|
||||
// Verificar si hay muchos archivos faltantes
|
||||
if (fontResults.missing.length > 5) {
|
||||
issues.push({
|
||||
type: 'error',
|
||||
message: `Faltan ${fontResults.missing.length} archivos de fuentes esenciales`
|
||||
});
|
||||
console.log(` ❌ Faltan muchos archivos de fuentes`);
|
||||
}
|
||||
|
||||
return issues;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generar reporte de validación
|
||||
*/
|
||||
function generateValidationReport(fontResults, metadataResults, compatibilityIssues) {
|
||||
const report = {
|
||||
meta: {
|
||||
generated: new Date().toISOString(),
|
||||
version: CONFIG.VERSION
|
||||
},
|
||||
fontFiles: fontResults,
|
||||
metadata: metadataResults,
|
||||
compatibility: {
|
||||
issues: compatibilityIssues,
|
||||
status: compatibilityIssues.length === 0 ? 'OK' : 'ISSUES'
|
||||
},
|
||||
recommendations: []
|
||||
};
|
||||
|
||||
// Generar recomendaciones
|
||||
if (fontResults.missing.length > 0) {
|
||||
report.recommendations.push({
|
||||
priority: 'high',
|
||||
action: 'download_missing_fonts',
|
||||
message: 'Descarga los archivos de fuentes faltantes de FontAwesome Pro'
|
||||
});
|
||||
}
|
||||
|
||||
if (!metadataResults.metadata.valid) {
|
||||
report.recommendations.push({
|
||||
priority: 'high',
|
||||
action: 'run_extract_metadata',
|
||||
message: 'Ejecuta scripts/extract-metadata.js primero'
|
||||
});
|
||||
}
|
||||
|
||||
if (compatibilityIssues.length > 0) {
|
||||
report.recommendations.push({
|
||||
priority: 'medium',
|
||||
action: 'verify_fontawesome_version',
|
||||
message: 'Verifica que tengas la versión correcta de FontAwesome Pro'
|
||||
});
|
||||
}
|
||||
|
||||
// Guardar reporte
|
||||
fs.writeFileSync(CONFIG.OUTPUT_REPORT, JSON.stringify(report, null, 2), 'utf8');
|
||||
console.log(`\n📋 Reporte de validación guardado: ${CONFIG.OUTPUT_REPORT}`);
|
||||
|
||||
return report;
|
||||
}
|
||||
|
||||
/**
|
||||
* Función principal
|
||||
*/
|
||||
function main() {
|
||||
try {
|
||||
console.log('='.repeat(60));
|
||||
console.log(' VALIDACIÓN DE ESTILOS FONTAWESOME PRO');
|
||||
console.log('='.repeat(60));
|
||||
|
||||
// 1. Validar archivos de fuentes
|
||||
const fontResults = validateFontFiles();
|
||||
|
||||
// 2. Validar metadata procesado
|
||||
const metadataResults = validateProcessedMetadata();
|
||||
|
||||
// 3. Validar compatibilidad
|
||||
const compatibilityIssues = validateCompatibility(fontResults, metadataResults);
|
||||
|
||||
// 4. Generar reporte
|
||||
const report = generateValidationReport(fontResults, metadataResults, compatibilityIssues);
|
||||
|
||||
// 5. Mostrar resumen
|
||||
console.log('\n' + '='.repeat(60));
|
||||
console.log(' RESUMEN DE VALIDACIÓN');
|
||||
console.log('='.repeat(60));
|
||||
|
||||
console.log(`\n🎨 Archivos de fuentes: ${fontResults.found}/${fontResults.total}`);
|
||||
console.log(`📊 Metadata procesado: ${metadataResults.metadata.valid ? '✅ Válido' : '❌ Inválido'}`);
|
||||
console.log(`🔗 Compatibilidad: ${compatibilityIssues.length === 0 ? '✅ OK' : '⚠️ Issues'}`);
|
||||
|
||||
if (report.recommendations.length > 0) {
|
||||
console.log('\n🚀 RECOMENDACIONES:');
|
||||
report.recommendations.forEach((rec, index) => {
|
||||
console.log(` ${index + 1}. [${rec.priority.toUpperCase()}] ${rec.message}`);
|
||||
});
|
||||
}
|
||||
|
||||
console.log('\n' + '='.repeat(60));
|
||||
|
||||
// Retornar código de salida apropiado
|
||||
if (fontResults.found === 0 || !metadataResults.metadata.valid) {
|
||||
console.log('\n❌ Validación fallida. Revisa las recomendaciones.');
|
||||
process.exit(1);
|
||||
} else if (compatibilityIssues.length > 0) {
|
||||
console.log('\n⚠️ Validación con advertencias. El plugin puede funcionar con limitaciones.');
|
||||
process.exit(0);
|
||||
} else {
|
||||
console.log('\n✅ Validación exitosa. Listo para construir la base de datos.');
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error(`\n❌ Error durante la validación: ${error.message}`);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// Ejecutar
|
||||
if (require.main === module) {
|
||||
main();
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
validateFontFiles,
|
||||
validateProcessedMetadata,
|
||||
validateCompatibility,
|
||||
generateValidationReport
|
||||
};
|
||||
0
slash-commands.js
Normal file
0
slash-commands.js
Normal file
419
update-styles.js
Normal file
419
update-styles.js
Normal file
@@ -0,0 +1,419 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { execSync } = require('child_process');
|
||||
|
||||
// Configuración
|
||||
const CONFIG = {
|
||||
pluginDir: __dirname,
|
||||
assetsDir: path.join(__dirname, 'assets'),
|
||||
fontawesomeDir: path.join(__dirname, 'assets', 'fontawesome'),
|
||||
webfontsDir: path.join(__dirname, 'assets', 'fontawesome', 'webfonts'),
|
||||
metadataDir: path.join(__dirname, 'assets', 'fontawesome', 'metadata'),
|
||||
|
||||
// URLs de referencia (no para descargar directamente por licencia)
|
||||
fontawesomeUrl: 'https://fontawesome.com/download',
|
||||
proDownloadUrl: 'https://fontawesome.com/account/download'
|
||||
};
|
||||
|
||||
// Colores para la consola
|
||||
const colors = {
|
||||
reset: '\x1b[0m',
|
||||
bright: '\x1b[1m',
|
||||
green: '\x1b[32m',
|
||||
yellow: '\x1b[33m',
|
||||
blue: '\x1b[34m',
|
||||
magenta: '\x1b[35m',
|
||||
cyan: '\x1b[36m',
|
||||
red: '\x1b[31m'
|
||||
};
|
||||
|
||||
// Función para imprimir con estilo
|
||||
function log(message, color = 'reset', type = 'info') {
|
||||
const prefix = type === 'success' ? '✅' :
|
||||
type === 'warning' ? '⚠️' :
|
||||
type === 'error' ? '❌' :
|
||||
type === 'info' ? 'ℹ️' : '📝';
|
||||
|
||||
console.log(`${colors[color] || colors.reset}${prefix} ${message}${colors.reset}`);
|
||||
}
|
||||
|
||||
// Banner
|
||||
console.log(colors.cyan + '='.repeat(70));
|
||||
console.log(' ACTUALIZADOR DE ESTILOS FONTAWESOME PRO PARA LOGSEQ');
|
||||
console.log('='.repeat(70) + colors.reset + '\n');
|
||||
|
||||
/**
|
||||
* Verificar estructura de directorios
|
||||
*/
|
||||
function checkDirectoryStructure() {
|
||||
log('Verificando estructura de directorios...', 'blue');
|
||||
|
||||
const requiredDirs = [
|
||||
CONFIG.assetsDir,
|
||||
CONFIG.fontawesomeDir,
|
||||
CONFIG.webfontsDir,
|
||||
CONFIG.metadataDir
|
||||
];
|
||||
|
||||
let allExist = true;
|
||||
|
||||
requiredDirs.forEach(dir => {
|
||||
if (fs.existsSync(dir)) {
|
||||
log(` ${path.basename(dir)}: Existe`, 'green');
|
||||
} else {
|
||||
log(` ${path.basename(dir)}: No existe - Creando...`, 'yellow');
|
||||
try {
|
||||
fs.mkdirSync(dir, { recursive: true });
|
||||
log(` ${path.basename(dir)}: Creado`, 'green');
|
||||
} catch (error) {
|
||||
log(` Error creando ${dir}: ${error.message}`, 'red', 'error');
|
||||
allExist = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return allExist;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verificar archivos actuales
|
||||
*/
|
||||
function checkCurrentFiles() {
|
||||
log('Analizando archivos actuales...', 'blue');
|
||||
|
||||
const files = {
|
||||
webfonts: [],
|
||||
metadata: [],
|
||||
css: []
|
||||
};
|
||||
|
||||
// Verificar webfonts
|
||||
if (fs.existsSync(CONFIG.webfontsDir)) {
|
||||
files.webfonts = fs.readdirSync(CONFIG.webfontsDir)
|
||||
.filter(file => /\.(woff2|woff|ttf|eot)$/i.test(file));
|
||||
}
|
||||
|
||||
// Verificar metadata
|
||||
if (fs.existsSync(CONFIG.metadataDir)) {
|
||||
files.metadata = fs.readdirSync(CONFIG.metadataDir)
|
||||
.filter(file => /\.json$/i.test(file));
|
||||
}
|
||||
|
||||
// Verificar CSS
|
||||
const cssDir = path.join(CONFIG.fontawesomeDir, 'css');
|
||||
if (fs.existsSync(cssDir)) {
|
||||
files.css = fs.readdirSync(cssDir)
|
||||
.filter(file => /\.css$/i.test(file));
|
||||
}
|
||||
|
||||
// Mostrar resumen
|
||||
log(` Webfonts: ${files.webfonts.length} archivos encontrados`,
|
||||
files.webfonts.length > 0 ? 'green' : 'yellow');
|
||||
log(` Metadata: ${files.metadata.length} archivos encontrados`,
|
||||
files.metadata.length > 0 ? 'green' : 'yellow');
|
||||
log(` CSS: ${files.css.length} archivos encontrados`,
|
||||
files.css.length > 0 ? 'green' : 'yellow');
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mostrar instrucciones de actualización
|
||||
*/
|
||||
function showUpdateInstructions(currentFiles) {
|
||||
console.log('\n' + colors.yellow + '='.repeat(70));
|
||||
console.log(' INSTRUCCIONES PARA ACTUALIZAR ESTILOS');
|
||||
console.log('='.repeat(70) + colors.reset + '\n');
|
||||
|
||||
log('PASO 1: Descargar FontAwesome 6 Pro actualizado', 'magenta');
|
||||
console.log(' • Visita: ' + colors.cyan + CONFIG.proDownloadUrl + colors.reset);
|
||||
console.log(' • Inicia sesión con tu cuenta Pro');
|
||||
console.log(' • Descarga la versión más reciente\n');
|
||||
|
||||
log('PASO 2: Extraer archivos necesarios', 'magenta');
|
||||
console.log('Del ZIP descargado, copia estos archivos:\n');
|
||||
|
||||
console.log(colors.bright + ' 📁 css/' + colors.reset);
|
||||
console.log(' ├── all.min.css');
|
||||
console.log(' └── fontawesome.min.css\n');
|
||||
|
||||
console.log(colors.bright + ' 📁 webfonts/' + colors.reset);
|
||||
console.log(' ├── fa-solid-900.woff2');
|
||||
console.log(' ├── fa-regular-400.woff2');
|
||||
console.log(' ├── fa-light-300.woff2');
|
||||
console.log(' ├── fa-thin-100.woff2');
|
||||
console.log(' ├── fa-duotone-900.woff2');
|
||||
console.log(' ├── fa-sharp-solid-900.woff2');
|
||||
console.log(' ├── fa-sharp-regular-400.woff2');
|
||||
console.log(' ├── fa-sharp-light-300.woff2');
|
||||
console.log(' ├── fa-sharp-thin-100.woff2');
|
||||
console.log(' ├── fa-sharp-duotone-900.woff2');
|
||||
console.log(' └── fa-brands-400.woff2\n');
|
||||
|
||||
console.log(colors.bright + ' 📁 metadata/' + colors.reset);
|
||||
console.log(' └── icons.json\n');
|
||||
|
||||
log('PASO 3: Reemplazar archivos', 'magenta');
|
||||
console.log(` • Copia los archivos a: ${colors.cyan}${CONFIG.fontawesomeDir}${colors.reset}`);
|
||||
|
||||
log('PASO 4: Regenerar base de datos', 'magenta');
|
||||
console.log(' • Ejecuta: ' + colors.green + 'npm run build' + colors.reset);
|
||||
|
||||
console.log('\n' + colors.yellow + '='.repeat(70));
|
||||
}
|
||||
|
||||
/**
|
||||
* Detectar nuevos estilos disponibles
|
||||
*/
|
||||
function detectNewStyles() {
|
||||
log('Buscando nuevos estilos...', 'blue');
|
||||
|
||||
// Leer estilos actuales de la base de datos
|
||||
const dbPath = path.join(CONFIG.assetsDir, 'icons.json');
|
||||
let currentStyles = [];
|
||||
|
||||
if (fs.existsSync(dbPath)) {
|
||||
try {
|
||||
const db = JSON.parse(fs.readFileSync(dbPath, 'utf8'));
|
||||
currentStyles = db.meta?.stylesAvailable || [];
|
||||
log(` Estilos actuales en DB: ${currentStyles.length}`, 'green');
|
||||
} catch (error) {
|
||||
log(` Error leyendo DB: ${error.message}`, 'yellow', 'warning');
|
||||
}
|
||||
}
|
||||
|
||||
// Detectar estilos en webfonts
|
||||
let detectedStyles = [];
|
||||
if (fs.existsSync(CONFIG.webfontsDir)) {
|
||||
const fontFiles = fs.readdirSync(CONFIG.webfontsDir);
|
||||
|
||||
// Mapear archivos a estilos
|
||||
const styleMap = {
|
||||
'fa-solid': 'solid',
|
||||
'fa-regular': 'regular',
|
||||
'fa-light': 'light',
|
||||
'fa-thin': 'thin',
|
||||
'fa-duotone': 'duotone',
|
||||
'fa-sharp-solid': 'sharp-solid',
|
||||
'fa-sharp-regular': 'sharp-regular',
|
||||
'fa-sharp-light': 'sharp-light',
|
||||
'fa-sharp-thin': 'sharp-thin',
|
||||
'fa-sharp-duotone': 'sharp-duotone',
|
||||
'fa-brands': 'brands'
|
||||
};
|
||||
|
||||
fontFiles.forEach(file => {
|
||||
Object.keys(styleMap).forEach(key => {
|
||||
if (file.includes(key)) {
|
||||
const style = styleMap[key];
|
||||
if (!detectedStyles.includes(style)) {
|
||||
detectedStyles.push(style);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
log(` Estilos detectados en archivos: ${detectedStyles.length}`, 'green');
|
||||
|
||||
// Encontrar nuevos estilos
|
||||
const newStyles = detectedStyles.filter(style => !currentStyles.includes(style));
|
||||
|
||||
if (newStyles.length > 0) {
|
||||
log(` ¡Nuevos estilos encontrados: ${newStyles.length}!`, 'magenta', 'success');
|
||||
newStyles.forEach(style => {
|
||||
log(` • ${style}`, 'green');
|
||||
});
|
||||
} else {
|
||||
log(' No se encontraron nuevos estilos', 'yellow');
|
||||
}
|
||||
|
||||
return { currentStyles, detectedStyles, newStyles };
|
||||
}
|
||||
|
||||
/**
|
||||
* Verificar versiones
|
||||
*/
|
||||
function checkVersions() {
|
||||
log('Verificando versiones...', 'blue');
|
||||
|
||||
// Verificar metadata version
|
||||
const metadataPath = path.join(CONFIG.metadataDir, 'icons.json');
|
||||
let metadataVersion = 'Desconocida';
|
||||
|
||||
if (fs.existsSync(metadataPath)) {
|
||||
try {
|
||||
const metadata = JSON.parse(fs.readFileSync(metadataPath, 'utf8'));
|
||||
const firstIcon = Object.values(metadata)[0];
|
||||
metadataVersion = firstIcon?.version || 'Desconocida';
|
||||
} catch (error) {
|
||||
// Ignorar error
|
||||
}
|
||||
}
|
||||
|
||||
log(` Versión en metadata: ${metadataVersion}`, 'green');
|
||||
|
||||
// Verificar versión del plugin
|
||||
const packagePath = path.join(CONFIG.pluginDir, 'package.json');
|
||||
let pluginVersion = 'Desconocida';
|
||||
|
||||
if (fs.existsSync(packagePath)) {
|
||||
try {
|
||||
const pkg = JSON.parse(fs.readFileSync(packagePath, 'utf8'));
|
||||
pluginVersion = pkg.version || 'Desconocida';
|
||||
} catch (error) {
|
||||
// Ignorar error
|
||||
}
|
||||
}
|
||||
|
||||
log(` Versión del plugin: ${pluginVersion}`, 'green');
|
||||
|
||||
return { metadataVersion, pluginVersion };
|
||||
}
|
||||
|
||||
/**
|
||||
* Realizar respaldo de archivos actuales
|
||||
*/
|
||||
function backupCurrentFiles() {
|
||||
log('Creando respaldo de archivos actuales...', 'blue');
|
||||
|
||||
const backupDir = path.join(CONFIG.pluginDir, 'backup', new Date().toISOString().split('T')[0]);
|
||||
|
||||
try {
|
||||
if (!fs.existsSync(backupDir)) {
|
||||
fs.mkdirSync(backupDir, { recursive: true });
|
||||
}
|
||||
|
||||
// Archivos a respaldar
|
||||
const filesToBackup = [
|
||||
path.join(CONFIG.assetsDir, 'icons.json'),
|
||||
path.join(CONFIG.assetsDir, 'dynamic-styles.css'),
|
||||
path.join(CONFIG.assetsDir, 'custom-styles.css')
|
||||
];
|
||||
|
||||
let backedUpCount = 0;
|
||||
|
||||
filesToBackup.forEach(file => {
|
||||
if (fs.existsSync(file)) {
|
||||
const fileName = path.basename(file);
|
||||
const backupPath = path.join(backupDir, fileName);
|
||||
|
||||
fs.copyFileSync(file, backupPath);
|
||||
backedUpCount++;
|
||||
log(` Respaldo creado: ${fileName}`, 'green');
|
||||
}
|
||||
});
|
||||
|
||||
if (backedUpCount > 0) {
|
||||
log(`✅ Respaldo completado (${backedUpCount} archivos)`, 'green', 'success');
|
||||
log(` Ubicación: ${backupDir}`, 'cyan');
|
||||
} else {
|
||||
log('⚠️ No se encontraron archivos para respaldar', 'yellow', 'warning');
|
||||
}
|
||||
|
||||
return backupDir;
|
||||
|
||||
} catch (error) {
|
||||
log(`❌ Error creando respaldo: ${error.message}`, 'red', 'error');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Regenerar base de datos
|
||||
*/
|
||||
function regenerateDatabase() {
|
||||
log('Regenerando base de datos...', 'blue');
|
||||
|
||||
try {
|
||||
// Ejecutar el script de construcción
|
||||
log(' Ejecutando: npm run build', 'cyan');
|
||||
|
||||
const result = execSync('npm run build', {
|
||||
cwd: CONFIG.pluginDir,
|
||||
stdio: 'pipe',
|
||||
encoding: 'utf8'
|
||||
});
|
||||
|
||||
console.log(result);
|
||||
log('✅ Base de datos regenerada exitosamente', 'green', 'success');
|
||||
|
||||
return true;
|
||||
|
||||
} catch (error) {
|
||||
log(`❌ Error regenerando base de datos: ${error.message}`, 'red', 'error');
|
||||
if (error.stdout) console.log(error.stdout);
|
||||
if (error.stderr) console.log(error.stderr);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Función principal
|
||||
*/
|
||||
async function main() {
|
||||
try {
|
||||
// 1. Verificar estructura
|
||||
if (!checkDirectoryStructure()) {
|
||||
log('Error en la estructura de directorios', 'red', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. Verificar archivos actuales
|
||||
const currentFiles = checkCurrentFiles();
|
||||
|
||||
// 3. Verificar versiones
|
||||
const versions = checkVersions();
|
||||
|
||||
// 4. Detectar nuevos estilos
|
||||
const styles = detectNewStyles();
|
||||
|
||||
// 5. Mostrar resumen
|
||||
console.log('\n' + colors.cyan + '='.repeat(70));
|
||||
console.log(' RESUMEN DEL ANÁLISIS');
|
||||
console.log('='.repeat(70) + colors.reset);
|
||||
|
||||
console.log(`\n${colors.bright}📊 Estadísticas:${colors.reset}`);
|
||||
console.log(` • Webfonts: ${currentFiles.webfonts.length} archivos`);
|
||||
console.log(` • Estilos detectados: ${styles.detectedStyles.length}`);
|
||||
console.log(` • Estilos en DB: ${styles.currentStyles.length}`);
|
||||
console.log(` • Nuevos estilos: ${styles.newStyles.length}`);
|
||||
console.log(` • Versión metadata: ${versions.metadataVersion}`);
|
||||
console.log(` • Versión plugin: ${versions.pluginVersion}`);
|
||||
|
||||
if (styles.newStyles.length > 0) {
|
||||
console.log(`\n${colors.bright}🎉 ¡Nuevos estilos disponibles!${colors.reset}`);
|
||||
console.log(` Ejecuta 'npm run build' para actualizar la base de datos.`);
|
||||
}
|
||||
|
||||
// 6. Preguntar al usuario
|
||||
console.log(`\n${colors.bright}¿Qué deseas hacer?${colors.reset}`);
|
||||
console.log(' 1. Mostrar instrucciones de actualización');
|
||||
console.log(' 2. Crear respaldo y regenerar base de datos');
|
||||
console.log(' 3. Solo regenerar base de datos');
|
||||
console.log(' 4. Salir');
|
||||
|
||||
// En un entorno real, aquí usarías readline para interactuar
|
||||
// Por ahora, mostramos las instrucciones automáticamente
|
||||
|
||||
console.log('\n' + colors.yellow + 'Mostrando instrucciones...' + colors.reset);
|
||||
showUpdateInstructions(currentFiles);
|
||||
|
||||
// 7. Opción para regenerar
|
||||
console.log(`\n${colors.bright}Para regenerar la base de datos con los nuevos estilos:${colors.reset}`);
|
||||
console.log(` Ejecuta: ${colors.green}npm run build${colors.reset}`);
|
||||
|
||||
console.log('\n' + colors.cyan + '='.repeat(70));
|
||||
console.log(' ACTUALIZACIÓN COMPLETADA');
|
||||
console.log('='.repeat(70) + colors.reset);
|
||||
|
||||
} catch (error) {
|
||||
log(`Error en el proceso de actualización: ${error.message}`, 'red', 'error');
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// Ejecutar
|
||||
main();
|
||||
148
verify-styles.js
Normal file
148
verify-styles.js
Normal file
@@ -0,0 +1,148 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
console.log('🔍 Verificador de Estilos FontAwesome Pro\n');
|
||||
console.log('='.repeat(60));
|
||||
|
||||
// Configuración
|
||||
const WEBFONTS_DIR = path.join(__dirname, 'assets', 'fontawesome', 'webfonts');
|
||||
const METADATA_DIR = path.join(__dirname, 'assets', 'fontawesome', 'metadata');
|
||||
const CSS_DIR = path.join(__dirname, 'assets', 'fontawesome', 'css');
|
||||
|
||||
// Archivos requeridos para cada estilo
|
||||
const REQUIRED_FILES = {
|
||||
'solid': ['fa-solid-900.woff2', 'fa-solid-900.ttf'],
|
||||
'regular': ['fa-regular-400.woff2', 'fa-regular-400.ttf'],
|
||||
'light': ['fa-light-300.woff2', 'fa-light-300.ttf'],
|
||||
'thin': ['fa-thin-100.woff2', 'fa-thin-100.ttf'],
|
||||
'duotone': ['fa-duotone-900.woff2', 'fa-duotone-900.ttf'],
|
||||
'sharp-solid': ['fa-sharp-solid-900.woff2', 'fa-sharp-solid-900.ttf'],
|
||||
'sharp-regular': ['fa-sharp-regular-400.woff2', 'fa-sharp-regular-400.ttf'],
|
||||
'sharp-light': ['fa-sharp-light-300.woff2', 'fa-sharp-light-300.ttf'],
|
||||
'sharp-thin': ['fa-sharp-thin-100.woff2', 'fa-sharp-thin-100.ttf'],
|
||||
'sharp-duotone': ['fa-sharp-duotone-900.woff2', 'fa-sharp-duotone-900.ttf'],
|
||||
'brands': ['fa-brands-400.woff2', 'fa-brands-400.ttf']
|
||||
};
|
||||
|
||||
// Verificar directorios
|
||||
console.log('\n📁 Verificando directorios...');
|
||||
const directories = [
|
||||
{ name: 'webfonts', path: WEBFONTS_DIR },
|
||||
{ name: 'metadata', path: METADATA_DIR },
|
||||
{ name: 'css', path: CSS_DIR }
|
||||
];
|
||||
|
||||
directories.forEach(dir => {
|
||||
if (fs.existsSync(dir.path)) {
|
||||
console.log(` ✅ ${dir.name}: Existe`);
|
||||
const files = fs.readdirSync(dir.path);
|
||||
console.log(` Archivos: ${files.length}`);
|
||||
} else {
|
||||
console.log(` ❌ ${dir.name}: No existe`);
|
||||
}
|
||||
});
|
||||
|
||||
// Verificar archivos de fuentes
|
||||
console.log('\n🎨 Verificando archivos de fuentes...');
|
||||
let totalFound = 0;
|
||||
let totalRequired = 0;
|
||||
|
||||
Object.entries(REQUIRED_FILES).forEach(([style, files]) => {
|
||||
console.log(`\n ${style}:`);
|
||||
|
||||
let foundCount = 0;
|
||||
files.forEach(file => {
|
||||
const filePath = path.join(WEBFONTS_DIR, file);
|
||||
if (fs.existsSync(filePath)) {
|
||||
console.log(` ✅ ${file}`);
|
||||
foundCount++;
|
||||
totalFound++;
|
||||
} else {
|
||||
console.log(` ❌ ${file} (Faltante)`);
|
||||
}
|
||||
totalRequired++;
|
||||
});
|
||||
|
||||
if (foundCount === files.length) {
|
||||
console.log(` 🎉 ${style} completo`);
|
||||
} else if (foundCount > 0) {
|
||||
console.log(` ⚠️ ${style} parcial (${foundCount}/${files.length})`);
|
||||
} else {
|
||||
console.log(` ❌ ${style} no disponible`);
|
||||
}
|
||||
});
|
||||
|
||||
// Verificar metadata
|
||||
console.log('\n📊 Verificando metadata...');
|
||||
const metadataPath = path.join(METADATA_DIR, 'icons.json');
|
||||
if (fs.existsSync(metadataPath)) {
|
||||
try {
|
||||
const metadata = JSON.parse(fs.readFileSync(metadataPath, 'utf8'));
|
||||
const iconCount = Object.keys(metadata).length;
|
||||
console.log(` ✅ Metadata válido`);
|
||||
console.log(` Íconos: ${iconCount}`);
|
||||
|
||||
// Verificar si hay estilos sharp en metadata
|
||||
const sampleIcon = Object.values(metadata)[0];
|
||||
if (sampleIcon && sampleIcon.styles) {
|
||||
const hasSharp = sampleIcon.styles.some(s =>
|
||||
s.toLowerCase().includes('sharp')
|
||||
);
|
||||
console.log(` Estilos Sharp: ${hasSharp ? 'Sí' : 'No'}`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(` ❌ Error en metadata: ${error.message}`);
|
||||
}
|
||||
} else {
|
||||
console.log(' ❌ Metadata no encontrado');
|
||||
}
|
||||
|
||||
// Verificar archivos generados
|
||||
console.log('\n🛠️ Verificando archivos generados...');
|
||||
const generatedFiles = [
|
||||
{ name: 'Base de datos', path: path.join(__dirname, 'assets', 'icons.json') },
|
||||
{ name: 'CSS Dinámico', path: path.join(__dirname, 'assets', 'dynamic-styles.css') },
|
||||
{ name: 'CSS Personalizado', path: path.join(__dirname, 'assets', 'custom-styles.css') }
|
||||
];
|
||||
|
||||
generatedFiles.forEach(file => {
|
||||
if (fs.existsSync(file.path)) {
|
||||
const stats = fs.statSync(file.path);
|
||||
console.log(` ✅ ${file.name}: ${(stats.size / 1024).toFixed(2)} KB`);
|
||||
} else {
|
||||
console.log(` ❌ ${file.name}: No generado`);
|
||||
}
|
||||
});
|
||||
|
||||
// Resumen
|
||||
console.log('\n' + '='.repeat(60));
|
||||
console.log('📈 RESUMEN FINAL');
|
||||
console.log('='.repeat(60));
|
||||
|
||||
const percentage = ((totalFound / totalRequired) * 100).toFixed(1);
|
||||
console.log(`\nArchivos de fuentes: ${totalFound}/${totalRequired} (${percentage}%)`);
|
||||
|
||||
if (percentage >= 90) {
|
||||
console.log('✅ Excelente! Tienes casi todos los estilos.');
|
||||
} else if (percentage >= 50) {
|
||||
console.log('⚠️ Tienes la mayoría de estilos básicos.');
|
||||
} else {
|
||||
console.log('❌ Faltan muchos estilos. Considera actualizar FontAwesome Pro.');
|
||||
}
|
||||
|
||||
console.log('\n🎯 RECOMENDACIONES:');
|
||||
if (totalFound < totalRequired) {
|
||||
console.log(' 1. Descarga la versión completa de FontAwesome 6 Pro');
|
||||
console.log(' 2. Copia todos los archivos de webfonts/');
|
||||
console.log(' 3. Ejecuta: npm run build');
|
||||
} else {
|
||||
console.log(' 1. ¡Todo está listo!');
|
||||
console.log(' 2. Ejecuta: npm run build (si no lo has hecho)');
|
||||
}
|
||||
|
||||
console.log('\n🚀 COMANDOS DISPONIBLES:');
|
||||
console.log(' • npm run build - Generar/actualizar base de datos');
|
||||
console.log(' • npm run update - Verificar y actualizar estilos');
|
||||
console.log(' • npm run verify - Verificar archivos (este comando)');
|
||||
|
||||
console.log('\n' + '='.repeat(60));
|
||||
Reference in New Issue
Block a user