holygrail5 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +631 -0
- package/config.json +365 -0
- package/generator.js +58 -0
- package/package.json +48 -0
- package/src/cli-variables.js +147 -0
- package/src/config.js +62 -0
- package/src/dev.js +47 -0
- package/src/guide.js +1798 -0
- package/src/parser.js +624 -0
- package/src/utils.js +74 -0
- package/src/variables-manager.js +248 -0
- package/src/watch.js +88 -0
package/config.json
ADDED
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
{
|
|
2
|
+
"prefix": "hg",
|
|
3
|
+
"category": "typo",
|
|
4
|
+
"fontFamilyMap": {
|
|
5
|
+
"primary": "arial, sans-serif",
|
|
6
|
+
"secondary": "\"ms-serif\", serif"
|
|
7
|
+
},
|
|
8
|
+
"breakpoints": {
|
|
9
|
+
"mobile": "0px",
|
|
10
|
+
"desktop": "992px"
|
|
11
|
+
},
|
|
12
|
+
"spacingMap": {
|
|
13
|
+
"0": "0",
|
|
14
|
+
"4": "4px",
|
|
15
|
+
"8": "8px",
|
|
16
|
+
"12": "12px",
|
|
17
|
+
"16": "16px",
|
|
18
|
+
"20": "20px",
|
|
19
|
+
"24": "24px",
|
|
20
|
+
"32": "32px",
|
|
21
|
+
"36": "36px",
|
|
22
|
+
"40": "40px",
|
|
23
|
+
"64": "64px",
|
|
24
|
+
"72": "72px",
|
|
25
|
+
"80": "80px",
|
|
26
|
+
"88": "88px",
|
|
27
|
+
"96": "96px",
|
|
28
|
+
"104": "104px",
|
|
29
|
+
"112": "112px",
|
|
30
|
+
"120": "120px",
|
|
31
|
+
"128": "128px",
|
|
32
|
+
"136": "136px",
|
|
33
|
+
"144": "144px",
|
|
34
|
+
"152": "152px",
|
|
35
|
+
"160": "160px",
|
|
36
|
+
"20-percent": "20%",
|
|
37
|
+
"25-percent": "25%",
|
|
38
|
+
"33-percent": "33.333333%",
|
|
39
|
+
"40-percent": "40%",
|
|
40
|
+
"50-percent": "50%",
|
|
41
|
+
"60-percent": "60%",
|
|
42
|
+
"66-percent": "66.666667%",
|
|
43
|
+
"75-percent": "75%",
|
|
44
|
+
"100-percent": "100%"
|
|
45
|
+
},
|
|
46
|
+
"spacingImportant": ["0"],
|
|
47
|
+
"colors": {
|
|
48
|
+
"white": "#ffffff",
|
|
49
|
+
"black": "#000000",
|
|
50
|
+
"dark-grey": "#737373",
|
|
51
|
+
"middle-grey": "#a9a9a9",
|
|
52
|
+
"light-grey": "#f0f0f0",
|
|
53
|
+
"primary": "#000000",
|
|
54
|
+
"error": "#b40016",
|
|
55
|
+
"info": "#1a32a4",
|
|
56
|
+
"success": "#76ae4a",
|
|
57
|
+
"warning": "#ffc700",
|
|
58
|
+
"feel": "#fb9962",
|
|
59
|
+
"feel-dark": "#c94c07",
|
|
60
|
+
"special": "#b99d6b",
|
|
61
|
+
"bg-light": "#F0F0F0",
|
|
62
|
+
"c-bg-light": "#000000",
|
|
63
|
+
"sk-grey": "#e3e3e3",
|
|
64
|
+
"bg-cream": "#f4f2ed"
|
|
65
|
+
},
|
|
66
|
+
"helpers": {
|
|
67
|
+
"display": {
|
|
68
|
+
"property": "display",
|
|
69
|
+
"class": "d",
|
|
70
|
+
"responsive": true,
|
|
71
|
+
"description": "Tipo de caja de renderizado",
|
|
72
|
+
"values": ["contents", "inline", "inline-block", "block", "flex", "inline-flex", "none"]
|
|
73
|
+
},
|
|
74
|
+
"flex-direction": {
|
|
75
|
+
"property": "flex-direction",
|
|
76
|
+
"class": "flex",
|
|
77
|
+
"responsive": true,
|
|
78
|
+
"description": "Dirección del eje principal (horizontal o vertical)",
|
|
79
|
+
"values": {
|
|
80
|
+
"row": "row",
|
|
81
|
+
"column": "column"
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
"flex-wrap": {
|
|
85
|
+
"property": "flex-wrap",
|
|
86
|
+
"class": "flex",
|
|
87
|
+
"responsive": true,
|
|
88
|
+
"description": "Permite o no el ajuste en múltiples líneas",
|
|
89
|
+
"values": {
|
|
90
|
+
"nowrap": "nowrap",
|
|
91
|
+
"wrap": "wrap"
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
"flex-grow": {
|
|
95
|
+
"property": "flex-grow",
|
|
96
|
+
"class": "grow",
|
|
97
|
+
"responsive": true,
|
|
98
|
+
"description": "Capacidad de crecer para ocupar espacio disponible",
|
|
99
|
+
"values": {
|
|
100
|
+
"0": "0",
|
|
101
|
+
"1": "1",
|
|
102
|
+
"2": "2",
|
|
103
|
+
"3": "3",
|
|
104
|
+
"auto": "auto"
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
"flex-shrink": {
|
|
108
|
+
"property": "flex-shrink",
|
|
109
|
+
"class": "shrink",
|
|
110
|
+
"responsive": true,
|
|
111
|
+
"description": "Capacidad de encogerse cuando el espacio es limitado",
|
|
112
|
+
"values": {
|
|
113
|
+
"0": "0",
|
|
114
|
+
"1": "1",
|
|
115
|
+
"2": "2",
|
|
116
|
+
"3": "3",
|
|
117
|
+
"auto": "auto"
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
"order": {
|
|
121
|
+
"property": "order",
|
|
122
|
+
"class": "order",
|
|
123
|
+
"responsive": true,
|
|
124
|
+
"description": "Orden de visualización independiente del HTML",
|
|
125
|
+
"values": {
|
|
126
|
+
"3-neg": "-3",
|
|
127
|
+
"2-neg": "-2",
|
|
128
|
+
"1-neg": "-1",
|
|
129
|
+
"0": "0",
|
|
130
|
+
"1": "1",
|
|
131
|
+
"2": "2",
|
|
132
|
+
"3": "3",
|
|
133
|
+
"first": "-9999",
|
|
134
|
+
"last": "9999"
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
"justify-content": {
|
|
138
|
+
"property": "justify-content",
|
|
139
|
+
"class": "justify",
|
|
140
|
+
"responsive": true,
|
|
141
|
+
"description": "Alineación en el eje principal",
|
|
142
|
+
"values": {
|
|
143
|
+
"stretch": "stretch",
|
|
144
|
+
"start": "flex-start",
|
|
145
|
+
"end": "flex-end",
|
|
146
|
+
"center": "center",
|
|
147
|
+
"between": "space-between",
|
|
148
|
+
"around": "space-around",
|
|
149
|
+
"evenly": "space-evenly"
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
"justify-items": {
|
|
153
|
+
"property": "justify-items",
|
|
154
|
+
"class": "justify-items",
|
|
155
|
+
"responsive": true,
|
|
156
|
+
"description": "Alineación horizontal en grid",
|
|
157
|
+
"values": {
|
|
158
|
+
"stretch": "stretch",
|
|
159
|
+
"start": "flex-start",
|
|
160
|
+
"end": "flex-end",
|
|
161
|
+
"center": "center",
|
|
162
|
+
"between": "space-between",
|
|
163
|
+
"around": "space-around",
|
|
164
|
+
"evenly": "space-evenly"
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
"align-content": {
|
|
168
|
+
"property": "align-content",
|
|
169
|
+
"class": "content",
|
|
170
|
+
"responsive": true,
|
|
171
|
+
"description": "Alineación de líneas en el eje cruzado",
|
|
172
|
+
"values": {
|
|
173
|
+
"stretch": "stretch",
|
|
174
|
+
"start": "flex-start",
|
|
175
|
+
"end": "flex-end",
|
|
176
|
+
"center": "center",
|
|
177
|
+
"between": "space-between",
|
|
178
|
+
"around": "space-around",
|
|
179
|
+
"evenly": "space-evenly"
|
|
180
|
+
}
|
|
181
|
+
},
|
|
182
|
+
"align-items": {
|
|
183
|
+
"property": "align-items",
|
|
184
|
+
"class": "items",
|
|
185
|
+
"responsive": true,
|
|
186
|
+
"description": "Alineación en el eje cruzado",
|
|
187
|
+
"values": {
|
|
188
|
+
"stretch": "stretch",
|
|
189
|
+
"start": "flex-start",
|
|
190
|
+
"end": "flex-end",
|
|
191
|
+
"center": "center",
|
|
192
|
+
"baseline": "baseline"
|
|
193
|
+
}
|
|
194
|
+
},
|
|
195
|
+
"row-gap": {
|
|
196
|
+
"property": "row-gap",
|
|
197
|
+
"class": "gap-y",
|
|
198
|
+
"responsive": true,
|
|
199
|
+
"description": "Espacio entre filas",
|
|
200
|
+
"useSpacing": true
|
|
201
|
+
},
|
|
202
|
+
"column-gap": {
|
|
203
|
+
"property": "column-gap",
|
|
204
|
+
"class": "gap-x",
|
|
205
|
+
"responsive": true,
|
|
206
|
+
"description": "Espacio entre columnas",
|
|
207
|
+
"useSpacing": true
|
|
208
|
+
},
|
|
209
|
+
"gap": {
|
|
210
|
+
"property": "gap",
|
|
211
|
+
"class": "gap",
|
|
212
|
+
"responsive": true,
|
|
213
|
+
"description": "Espacio entre filas y columnas",
|
|
214
|
+
"useSpacing": true
|
|
215
|
+
}
|
|
216
|
+
},
|
|
217
|
+
|
|
218
|
+
"classes": {
|
|
219
|
+
"h2": {
|
|
220
|
+
"fontFamily": "arial, sans-serif",
|
|
221
|
+
"fontWeight": "900",
|
|
222
|
+
"letterSpacing": "0rem",
|
|
223
|
+
"textTransform": "none",
|
|
224
|
+
"mobile": {
|
|
225
|
+
"fontSize": "18px",
|
|
226
|
+
"lineHeight": "1.976"
|
|
227
|
+
},
|
|
228
|
+
"desktop": {
|
|
229
|
+
"fontSize": "24px",
|
|
230
|
+
"lineHeight": "1.2"
|
|
231
|
+
}
|
|
232
|
+
},
|
|
233
|
+
"title-l-b": {
|
|
234
|
+
"fontFamily": "arial, sans-serif",
|
|
235
|
+
"fontWeight": "700",
|
|
236
|
+
"letterSpacing": "0rem",
|
|
237
|
+
"textTransform": "uppercase",
|
|
238
|
+
"mobile": {
|
|
239
|
+
"fontSize": "14px",
|
|
240
|
+
"lineHeight": "1.2"
|
|
241
|
+
},
|
|
242
|
+
"desktop": {
|
|
243
|
+
"fontSize": "14px",
|
|
244
|
+
"lineHeight": "1.4"
|
|
245
|
+
}
|
|
246
|
+
},
|
|
247
|
+
"title-s": {
|
|
248
|
+
"fontFamily": "arial, sans-serif",
|
|
249
|
+
"fontWeight": "400",
|
|
250
|
+
"mobile": {
|
|
251
|
+
"fontSize": "12px",
|
|
252
|
+
"lineHeight": "1.4"
|
|
253
|
+
},
|
|
254
|
+
"desktop": {
|
|
255
|
+
"fontSize": "12px",
|
|
256
|
+
"lineHeight": "1.4"
|
|
257
|
+
}
|
|
258
|
+
},
|
|
259
|
+
"suisse-1": {
|
|
260
|
+
"fontFamily": "\"ms-serif\", serif",
|
|
261
|
+
"mobile": {
|
|
262
|
+
"fontSize": "16px",
|
|
263
|
+
"lineHeight": "1.5"
|
|
264
|
+
},
|
|
265
|
+
"desktop": {
|
|
266
|
+
"fontSize": "20px",
|
|
267
|
+
"lineHeight": "1.5"
|
|
268
|
+
}
|
|
269
|
+
},
|
|
270
|
+
"suisse-2": {
|
|
271
|
+
"fontFamily": "\"ms-serif\", serif",
|
|
272
|
+
"mobile": {
|
|
273
|
+
"fontSize": "13px",
|
|
274
|
+
"lineHeight": "1.1"
|
|
275
|
+
},
|
|
276
|
+
"desktop": {
|
|
277
|
+
"fontSize": "14px",
|
|
278
|
+
"lineHeight": "1.1"
|
|
279
|
+
}
|
|
280
|
+
},
|
|
281
|
+
"suisse-body": {
|
|
282
|
+
"fontFamily": "\"ms-serif\", serif",
|
|
283
|
+
"mobile": {
|
|
284
|
+
"fontSize": "10px",
|
|
285
|
+
"lineHeight": "1.1"
|
|
286
|
+
},
|
|
287
|
+
"desktop": {
|
|
288
|
+
"fontSize": "12px",
|
|
289
|
+
"lineHeight": "1.1"
|
|
290
|
+
}
|
|
291
|
+
},
|
|
292
|
+
"p-tag": {
|
|
293
|
+
"fontFamily": "arial, sans-serif",
|
|
294
|
+
"fontWeight": "100",
|
|
295
|
+
"mobile": {
|
|
296
|
+
"fontSize": "8px",
|
|
297
|
+
"lineHeight": "1"
|
|
298
|
+
},
|
|
299
|
+
"desktop": {
|
|
300
|
+
"fontSize": "8px",
|
|
301
|
+
"lineHeight": "1"
|
|
302
|
+
}
|
|
303
|
+
},
|
|
304
|
+
"semantic": {
|
|
305
|
+
"fontFamily": "arial, sans-serif",
|
|
306
|
+
"fontWeight": "100",
|
|
307
|
+
"mobile": {
|
|
308
|
+
"fontSize": "13px",
|
|
309
|
+
"lineHeight": "1"
|
|
310
|
+
},
|
|
311
|
+
"desktop": {
|
|
312
|
+
"fontSize": "13px",
|
|
313
|
+
"lineHeight": "1"
|
|
314
|
+
}
|
|
315
|
+
},
|
|
316
|
+
"title-l": {
|
|
317
|
+
"fontFamily": "arial, sans-serif",
|
|
318
|
+
"fontWeight": "100",
|
|
319
|
+
"mobile": {
|
|
320
|
+
"fontSize": "14px",
|
|
321
|
+
"lineHeight": "1.4"
|
|
322
|
+
},
|
|
323
|
+
"desktop": {
|
|
324
|
+
"fontSize": "14px",
|
|
325
|
+
"lineHeight": "1.4"
|
|
326
|
+
}
|
|
327
|
+
},
|
|
328
|
+
"title-m": {
|
|
329
|
+
"fontFamily": "arial, sans-serif",
|
|
330
|
+
"fontWeight": "100",
|
|
331
|
+
"mobile": {
|
|
332
|
+
"fontSize": "12px",
|
|
333
|
+
"lineHeight": "1.4"
|
|
334
|
+
},
|
|
335
|
+
"desktop": {
|
|
336
|
+
"fontSize": "12px",
|
|
337
|
+
"lineHeight": "1.4"
|
|
338
|
+
}
|
|
339
|
+
},
|
|
340
|
+
"text-m": {
|
|
341
|
+
"fontFamily": "arial, sans-serif",
|
|
342
|
+
"fontWeight": "100",
|
|
343
|
+
"mobile": {
|
|
344
|
+
"fontSize": "12px",
|
|
345
|
+
"lineHeight": "1.5"
|
|
346
|
+
},
|
|
347
|
+
"desktop": {
|
|
348
|
+
"fontSize": "13px",
|
|
349
|
+
"lineHeight": "1.5"
|
|
350
|
+
}
|
|
351
|
+
},
|
|
352
|
+
"text-l": {
|
|
353
|
+
"fontFamily": "arial, sans-serif",
|
|
354
|
+
"fontWeight": "100",
|
|
355
|
+
"mobile": {
|
|
356
|
+
"fontSize": "12px",
|
|
357
|
+
"lineHeight": "1.5"
|
|
358
|
+
},
|
|
359
|
+
"desktop": {
|
|
360
|
+
"fontSize": "12px",
|
|
361
|
+
"lineHeight": "1.5"
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}
|
package/generator.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// Orquestador principal - Genera CSS y HTML desde JSON
|
|
4
|
+
|
|
5
|
+
const path = require('path');
|
|
6
|
+
const { loadConfig } = require('./src/config');
|
|
7
|
+
const { generateCSS } = require('./src/parser');
|
|
8
|
+
const { generateHTML } = require('./src/guide');
|
|
9
|
+
const { writeFile } = require('./src/utils');
|
|
10
|
+
|
|
11
|
+
// Ejecución principal
|
|
12
|
+
if (require.main === module) {
|
|
13
|
+
try {
|
|
14
|
+
// Parsear argumentos de línea de comandos
|
|
15
|
+
const args = process.argv.slice(2);
|
|
16
|
+
const configPath = args.find(arg => arg.startsWith('--config='))?.split('=')[1] || path.join(__dirname, 'config.json');
|
|
17
|
+
const outputPath = args.find(arg => arg.startsWith('--output='))?.split('=')[1] || path.join(__dirname, 'dist', 'output.css');
|
|
18
|
+
const htmlPath = args.find(arg => arg.startsWith('--html='))?.split('=')[1] || path.join(__dirname, 'dist', 'index.html');
|
|
19
|
+
|
|
20
|
+
// Cargar configuración
|
|
21
|
+
const configData = loadConfig(configPath);
|
|
22
|
+
|
|
23
|
+
// Generar CSS
|
|
24
|
+
const cssContent = generateCSS(configData);
|
|
25
|
+
writeFile(outputPath, cssContent, 'CSS');
|
|
26
|
+
|
|
27
|
+
// Generar HTML (ajustar ruta del CSS en el HTML si está en carpeta diferente)
|
|
28
|
+
let htmlContent = generateHTML(configData);
|
|
29
|
+
|
|
30
|
+
// Si el HTML y CSS están en carpetas diferentes, ajustar la ruta del CSS
|
|
31
|
+
const outputDir = path.dirname(outputPath);
|
|
32
|
+
const htmlDir = path.dirname(htmlPath);
|
|
33
|
+
|
|
34
|
+
// Si el HTML y CSS están en carpetas diferentes, ajustar la ruta del CSS
|
|
35
|
+
// Si están en la misma carpeta (dist/), usar ruta relativa simple
|
|
36
|
+
if (outputDir !== htmlDir) {
|
|
37
|
+
// Calcular ruta relativa del HTML al CSS
|
|
38
|
+
const relativePath = path.relative(htmlDir, outputDir);
|
|
39
|
+
const cssFileName = path.basename(outputPath);
|
|
40
|
+
const cssRelativePath = path.join(relativePath, cssFileName).replace(/\\/g, '/');
|
|
41
|
+
// Reemplazar href con o sin query string
|
|
42
|
+
htmlContent = htmlContent.replace(/href="output\.css[^"]*"/, `href="${cssRelativePath}"`);
|
|
43
|
+
} else {
|
|
44
|
+
// Si están en la misma carpeta, usar solo el nombre del archivo
|
|
45
|
+
htmlContent = htmlContent.replace(/href="output\.css[^"]*"/, `href="output.css"`);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
writeFile(htmlPath, htmlContent, 'HTML');
|
|
49
|
+
|
|
50
|
+
console.log('\n🎉 Generación completada exitosamente!');
|
|
51
|
+
} catch (error) {
|
|
52
|
+
console.error('❌ Error:', error.message);
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Exportar funciones
|
|
58
|
+
module.exports = { generateCSS, generateHTML };
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "holygrail5",
|
|
3
|
+
"version": "1.0.2",
|
|
4
|
+
"description": "Framework CSS generator con Node.js - Genera CSS optimizado con variables CSS desde un archivo JSON de configuración",
|
|
5
|
+
"main": "generator.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"holygrail5": "./generator.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"generate": "node generator.js",
|
|
11
|
+
"start": "node generator.js && NODE_NO_WARNINGS=1 npx http-server dist -p 3000 -o index.html",
|
|
12
|
+
"dev": "node src/dev.js",
|
|
13
|
+
"watch": "node src/watch.js",
|
|
14
|
+
"serve": "NODE_NO_WARNINGS=1 npx http-server dist -p 3000 -o index.html",
|
|
15
|
+
"test": "node tests/run-all.js",
|
|
16
|
+
"prepublishOnly": "npm run generate",
|
|
17
|
+
"vars:list": "node src/cli-variables.js list",
|
|
18
|
+
"vars:report": "node src/cli-variables.js report",
|
|
19
|
+
"vars:remove": "node src/cli-variables.js remove",
|
|
20
|
+
"vars:remove-all-unused": "node src/cli-variables.js remove-all-unused",
|
|
21
|
+
"vars:show-all": "node src/cli-variables.js show-all"
|
|
22
|
+
},
|
|
23
|
+
"keywords": [
|
|
24
|
+
"css",
|
|
25
|
+
"framework",
|
|
26
|
+
"generator",
|
|
27
|
+
"css-variables",
|
|
28
|
+
"responsive",
|
|
29
|
+
"typography",
|
|
30
|
+
"css-framework",
|
|
31
|
+
"design-tokens"
|
|
32
|
+
],
|
|
33
|
+
"author": "HolyGrail CSS",
|
|
34
|
+
"license": "MIT",
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "https://github.com/holygrailcss/holygrail5.git"
|
|
38
|
+
},
|
|
39
|
+
"files": [
|
|
40
|
+
"generator.js",
|
|
41
|
+
"config.json",
|
|
42
|
+
"README.md",
|
|
43
|
+
"src/**/*"
|
|
44
|
+
],
|
|
45
|
+
"engines": {
|
|
46
|
+
"node": ">=12.0.0"
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// CLI para gestionar variables CSS
|
|
4
|
+
// Permite listar variables no usadas y eliminar variables del historial
|
|
5
|
+
|
|
6
|
+
const {
|
|
7
|
+
listUnusedVariables,
|
|
8
|
+
showVariablesReport,
|
|
9
|
+
getAllHistoricalVariables,
|
|
10
|
+
removeVariableFromHistory,
|
|
11
|
+
removeVariablesFromHistory,
|
|
12
|
+
loadHistoricalVariables
|
|
13
|
+
} = require('./variables-manager');
|
|
14
|
+
|
|
15
|
+
const path = require('path');
|
|
16
|
+
|
|
17
|
+
// Función para mostrar ayuda
|
|
18
|
+
function showHelp() {
|
|
19
|
+
console.log(`
|
|
20
|
+
📦 Gestor de Variables CSS
|
|
21
|
+
|
|
22
|
+
Uso:
|
|
23
|
+
node src/cli-variables.js <comando> [opciones]
|
|
24
|
+
|
|
25
|
+
Comandos:
|
|
26
|
+
list Lista todas las variables no usadas
|
|
27
|
+
report Muestra un reporte completo de variables
|
|
28
|
+
remove <variable> Elimina una variable específica del historial
|
|
29
|
+
remove-all-unused Elimina todas las variables no usadas del historial
|
|
30
|
+
show-all Muestra todas las variables históricas almacenadas
|
|
31
|
+
|
|
32
|
+
Opciones:
|
|
33
|
+
--css=<ruta> Ruta al archivo CSS (por defecto: dist/output.css)
|
|
34
|
+
--history=<ruta> Ruta al archivo de variables históricas (por defecto: .data/.historical-variables.json)
|
|
35
|
+
|
|
36
|
+
Ejemplos:
|
|
37
|
+
node src/cli-variables.js list
|
|
38
|
+
node src/cli-variables.js report
|
|
39
|
+
node src/cli-variables.js remove --hg-typo-font-size-18
|
|
40
|
+
node src/cli-variables.js remove-all-unused
|
|
41
|
+
node src/cli-variables.js show-all
|
|
42
|
+
`);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Función principal
|
|
46
|
+
function main() {
|
|
47
|
+
const args = process.argv.slice(2);
|
|
48
|
+
|
|
49
|
+
if (args.length === 0 || args[0] === '--help' || args[0] === '-h') {
|
|
50
|
+
showHelp();
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const command = args[0];
|
|
55
|
+
const cssPath = args.find(arg => arg.startsWith('--css='))?.split('=')[1] || null;
|
|
56
|
+
const historyPath = args.find(arg => arg.startsWith('--history='))?.split('=')[1] || null;
|
|
57
|
+
|
|
58
|
+
try {
|
|
59
|
+
switch (command) {
|
|
60
|
+
case 'list':
|
|
61
|
+
{
|
|
62
|
+
const unused = listUnusedVariables(cssPath, historyPath);
|
|
63
|
+
if (unused.length === 0) {
|
|
64
|
+
console.log('\n✅ No hay variables no usadas. Todas las variables están en uso.\n');
|
|
65
|
+
} else {
|
|
66
|
+
console.log(`\n⚠️ Variables no usadas (${unused.length}):\n`);
|
|
67
|
+
unused.forEach((varName, index) => {
|
|
68
|
+
console.log(` ${index + 1}. ${varName}`);
|
|
69
|
+
});
|
|
70
|
+
console.log('\n💡 Usa "remove-all-unused" para eliminarlas del historial\n');
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
break;
|
|
74
|
+
|
|
75
|
+
case 'report':
|
|
76
|
+
showVariablesReport(cssPath, historyPath);
|
|
77
|
+
break;
|
|
78
|
+
|
|
79
|
+
case 'remove':
|
|
80
|
+
{
|
|
81
|
+
const varName = args[1];
|
|
82
|
+
if (!varName) {
|
|
83
|
+
console.error('❌ Error: Debes especificar el nombre de la variable a eliminar');
|
|
84
|
+
console.log(' Ejemplo: node src/cli-variables.js remove --hg-typo-font-size-18');
|
|
85
|
+
process.exit(1);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const removed = removeVariableFromHistory(varName, historyPath);
|
|
89
|
+
if (removed) {
|
|
90
|
+
console.log(`\n✅ Variable "${varName}" eliminada del historial\n`);
|
|
91
|
+
} else {
|
|
92
|
+
console.log(`\n⚠️ Variable "${varName}" no encontrada en el historial\n`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
break;
|
|
96
|
+
|
|
97
|
+
case 'remove-all-unused':
|
|
98
|
+
{
|
|
99
|
+
const unused = listUnusedVariables(cssPath, historyPath);
|
|
100
|
+
if (unused.length === 0) {
|
|
101
|
+
console.log('\n✅ No hay variables no usadas para eliminar\n');
|
|
102
|
+
} else {
|
|
103
|
+
console.log(`\n⚠️ Eliminando ${unused.length} variables no usadas del historial...\n`);
|
|
104
|
+
const removedCount = removeVariablesFromHistory(unused, historyPath);
|
|
105
|
+
console.log(`✅ ${removedCount} variables eliminadas del historial\n`);
|
|
106
|
+
console.log('💡 Ejecuta "node generator.js" para regenerar el CSS sin estas variables\n');
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
break;
|
|
110
|
+
|
|
111
|
+
case 'show-all':
|
|
112
|
+
{
|
|
113
|
+
const historicalVars = loadHistoricalVariables(historyPath);
|
|
114
|
+
const allVars = getAllHistoricalVariables(historicalVars);
|
|
115
|
+
|
|
116
|
+
if (allVars.length === 0) {
|
|
117
|
+
console.log('\n📚 No hay variables históricas almacenadas\n');
|
|
118
|
+
} else {
|
|
119
|
+
console.log(`\n📚 Variables históricas (${allVars.length}):\n`);
|
|
120
|
+
allVars.forEach((varData, index) => {
|
|
121
|
+
console.log(` ${index + 1}. ${varData.varName}`);
|
|
122
|
+
console.log(` Categoría: ${varData.category}`);
|
|
123
|
+
console.log(` Valor: ${varData.value}`);
|
|
124
|
+
console.log('');
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
break;
|
|
129
|
+
|
|
130
|
+
default:
|
|
131
|
+
console.error(`❌ Comando desconocido: ${command}`);
|
|
132
|
+
showHelp();
|
|
133
|
+
process.exit(1);
|
|
134
|
+
}
|
|
135
|
+
} catch (error) {
|
|
136
|
+
console.error('❌ Error:', error.message);
|
|
137
|
+
process.exit(1);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Ejecutar si es el módulo principal
|
|
142
|
+
if (require.main === module) {
|
|
143
|
+
main();
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
module.exports = { main };
|
|
147
|
+
|
package/src/config.js
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// Carga y validación de configuración
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
|
|
6
|
+
const BREAKPOINTS = ['mobile', 'desktop'];
|
|
7
|
+
|
|
8
|
+
function loadConfig(configPath = path.join(__dirname, '..', 'config.json')) {
|
|
9
|
+
try {
|
|
10
|
+
if (!fs.existsSync(configPath)) {
|
|
11
|
+
throw new Error(`Archivo de configuración no encontrado: ${configPath}`);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const configContent = fs.readFileSync(configPath, 'utf8');
|
|
15
|
+
const config = JSON.parse(configContent);
|
|
16
|
+
|
|
17
|
+
// Validar estructura básica
|
|
18
|
+
if (!config.classes || typeof config.classes !== 'object') {
|
|
19
|
+
throw new Error('La configuración debe tener un objeto "classes"');
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (!config.breakpoints || typeof config.breakpoints !== 'object') {
|
|
23
|
+
throw new Error('La configuración debe tener un objeto "breakpoints"');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (!config.breakpoints.mobile || !config.breakpoints.desktop) {
|
|
27
|
+
throw new Error('Los breakpoints deben tener propiedades "mobile" y "desktop"');
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Validar clases
|
|
31
|
+
Object.entries(config.classes).forEach(([className, cls]) => {
|
|
32
|
+
if (!cls || typeof cls !== 'object') {
|
|
33
|
+
throw new Error(`La clase "${className}" debe ser un objeto`);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Validar que tenga al menos un breakpoint
|
|
37
|
+
if (!cls.mobile && !cls.desktop) {
|
|
38
|
+
throw new Error(`La clase "${className}" debe tener al menos un breakpoint (mobile o desktop)`);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Validar propiedades de breakpoints
|
|
42
|
+
BREAKPOINTS.forEach(bp => {
|
|
43
|
+
if (cls[bp] && (!cls[bp].fontSize && !cls[bp].lineHeight)) {
|
|
44
|
+
console.warn(`Advertencia: La clase "${className}" tiene breakpoint "${bp}" sin fontSize ni lineHeight`);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
return config;
|
|
50
|
+
} catch (error) {
|
|
51
|
+
if (error instanceof SyntaxError) {
|
|
52
|
+
throw new Error(`Error al parsear JSON: ${error.message}`);
|
|
53
|
+
}
|
|
54
|
+
throw error;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
module.exports = {
|
|
59
|
+
loadConfig,
|
|
60
|
+
BREAKPOINTS
|
|
61
|
+
};
|
|
62
|
+
|