create-openclass-uniminuto 1.6.2 → 1.6.4

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.
@@ -6,18 +6,27 @@ import { spawnSync } from "node:child_process";
6
6
 
7
7
  const __filename = fileURLToPath(import.meta.url);
8
8
  const __dirname = path.dirname(__filename);
9
+
9
10
  const packageRoot = path.resolve(__dirname, "..");
10
11
  const templateRoot = path.join(packageRoot, "template");
11
12
 
12
13
  const args = process.argv.slice(2);
13
14
  const flags = new Set(args.filter((arg) => arg.startsWith("--")));
14
15
  const positional = args.filter((arg) => !arg.startsWith("--"));
16
+
15
17
  const targetArg = positional[0] || "openclass-uniminuto";
16
18
  const targetDir = path.resolve(process.cwd(), targetArg);
17
19
  const isCurrentDirectoryTarget = targetArg === "." || targetArg === "./";
20
+
21
+ const IGNORED_DIRS = new Set(["node_modules", "dist", ".slidev", ".git"]);
22
+ const IGNORED_FILES = new Set(["audit-report.json"]);
23
+ const IGNORED_EXTENSIONS = new Set([".tgz"]);
24
+
18
25
  function envFlag(name) {
19
26
  const value = process.env[name];
27
+
20
28
  if (value === undefined) return false;
29
+
21
30
  return ["1", "true", "yes", "on"].includes(String(value).toLowerCase());
22
31
  }
23
32
 
@@ -40,31 +49,73 @@ function fail(message) {
40
49
  process.exit(1);
41
50
  }
42
51
 
52
+ function shouldIgnore(src) {
53
+ const base = path.basename(src);
54
+ const ext = path.extname(src).toLowerCase();
55
+
56
+ return IGNORED_DIRS.has(base) || IGNORED_FILES.has(base) || IGNORED_EXTENSIONS.has(ext);
57
+ }
58
+
43
59
  function cleanPackageName(value) {
44
- return String(value || "openclass-uniminuto")
45
- .normalize("NFD")
46
- .replace(/[\u0300-\u036f]/g, "")
47
- .toLowerCase()
48
- .replace(/[^a-z0-9.-]+/g, "-")
49
- .replace(/^-+|-+$/g, "") || "openclass-uniminuto";
60
+ return (
61
+ String(value || "openclass-uniminuto")
62
+ .normalize("NFD")
63
+ .replace(/[\u0300-\u036f]/g, "")
64
+ .toLowerCase()
65
+ .replace(/[^a-z0-9.-]+/g, "-")
66
+ .replace(/^-+|-+$/g, "") || "openclass-uniminuto"
67
+ );
68
+ }
69
+
70
+ function relativeToTarget(filePath) {
71
+ return path.relative(targetDir, filePath).replaceAll("\\", "/");
72
+ }
73
+
74
+ function readJson(filePath) {
75
+ if (!fs.existsSync(filePath)) return null;
76
+
77
+ try {
78
+ return JSON.parse(fs.readFileSync(filePath, "utf-8"));
79
+ } catch (error) {
80
+ fail(`No se pudo leer JSON válido en ${filePath}\n${error.message}`);
81
+ }
82
+ }
83
+
84
+ function writeJson(filePath, data) {
85
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
86
+ fs.writeFileSync(filePath, `${JSON.stringify(data, null, 2)}\n`, "utf-8");
87
+ }
88
+
89
+ function patchJson(filePath, patcher) {
90
+ const data = readJson(filePath);
91
+
92
+ if (!data) return false;
93
+
94
+ patcher(data);
95
+ writeJson(filePath, data);
96
+
97
+ return true;
50
98
  }
51
99
 
52
100
  function copyTemplate(src, dest) {
53
- const base = path.basename(src);
54
- if (["node_modules", "dist", ".slidev", ".git"].includes(base)) return;
101
+ if (shouldIgnore(src)) return;
55
102
 
56
103
  const stat = fs.statSync(src);
104
+
57
105
  if (stat.isDirectory()) {
58
106
  fs.mkdirSync(dest, { recursive: true });
107
+
59
108
  for (const child of fs.readdirSync(src)) {
60
109
  copyTemplate(path.join(src, child), path.join(dest, child));
61
110
  }
111
+
62
112
  return;
63
113
  }
64
114
 
65
115
  fs.mkdirSync(path.dirname(dest), { recursive: true });
116
+
66
117
  if (fs.existsSync(dest) && !forceOverwrite) {
67
- log(`↷ Conservado archivo existente: ${path.relative(targetDir, dest)}`);
118
+ log(`↷ Conservado archivo existente: ${relativeToTarget(dest)}`);
68
119
  return;
69
120
  }
70
121
 
@@ -72,33 +123,172 @@ function copyTemplate(src, dest) {
72
123
  }
73
124
 
74
125
  function copyPathAlways(src, dest) {
75
- const base = path.basename(src);
76
- if (["node_modules", "dist", ".slidev", ".git"].includes(base)) return;
77
-
78
- if (!fs.existsSync(src)) return;
126
+ if (!fs.existsSync(src) || shouldIgnore(src)) return;
79
127
 
80
128
  const stat = fs.statSync(src);
129
+
81
130
  if (stat.isDirectory()) {
82
131
  fs.mkdirSync(dest, { recursive: true });
132
+
83
133
  for (const child of fs.readdirSync(src)) {
84
134
  copyPathAlways(path.join(src, child), path.join(dest, child));
85
135
  }
136
+
86
137
  return;
87
138
  }
88
139
 
89
140
  fs.mkdirSync(path.dirname(dest), { recursive: true });
90
141
  fs.copyFileSync(src, dest);
91
- log(`✓ Actualizado: ${path.relative(targetDir, dest)}`);
142
+
143
+ log(`✓ Actualizado: ${relativeToTarget(dest)}`);
92
144
  }
93
145
 
94
- function ensureFileFromTemplate(relativePath, options = {}) {
95
- const src = path.join(templateRoot, relativePath);
96
- const dest = path.join(targetDir, relativePath);
97
- if (!fs.existsSync(src)) return;
98
- if (fs.existsSync(dest) && options.onlyIfMissing) return;
146
+ function copyPathIfMissing(src, dest) {
147
+ if (!fs.existsSync(src) || shouldIgnore(src)) return false;
148
+
149
+ if (fs.existsSync(dest)) {
150
+ log(`⏭ Conservado: ${relativeToTarget(dest)}`);
151
+ return false;
152
+ }
153
+
154
+ const stat = fs.statSync(src);
155
+
156
+ if (stat.isDirectory()) {
157
+ fs.mkdirSync(dest, { recursive: true });
158
+
159
+ for (const child of fs.readdirSync(src)) {
160
+ copyPathIfMissing(path.join(src, child), path.join(dest, child));
161
+ }
162
+
163
+ return true;
164
+ }
165
+
99
166
  fs.mkdirSync(path.dirname(dest), { recursive: true });
100
167
  fs.copyFileSync(src, dest);
101
- log(`✓ Actualizado: ${relativePath}`);
168
+
169
+ log(`✓ Creado: ${relativeToTarget(dest)}`);
170
+ return true;
171
+ }
172
+
173
+ function copyTemplatePathAlways(relativePath) {
174
+ copyPathAlways(path.join(templateRoot, relativePath), path.join(targetDir, relativePath));
175
+ }
176
+
177
+ function copyTemplatePathIfMissing(relativePath) {
178
+ copyPathIfMissing(path.join(templateRoot, relativePath), path.join(targetDir, relativePath));
179
+ }
180
+
181
+ function appendGitignoreRules() {
182
+ const gitignorePath = path.join(targetDir, ".gitignore");
183
+
184
+ const rules = [
185
+ "",
186
+ "# Archivos generados por exportación Slidev",
187
+ "public/descargas/*.pdf",
188
+ "public/descargas/*.pptx",
189
+ "!public/descargas/.gitkeep",
190
+ "",
191
+ "# Reportes locales de auditoría",
192
+ "audit-report.json",
193
+ "",
194
+ ];
195
+
196
+ const existing = fs.existsSync(gitignorePath)
197
+ ? fs.readFileSync(gitignorePath, "utf-8")
198
+ : "";
199
+
200
+ const missingRules = rules.filter((rule) => {
201
+ if (rule.trim() === "") return false;
202
+ if (rule.startsWith("#")) return false;
203
+ return !existing.split(/\r?\n/).includes(rule);
204
+ });
205
+
206
+ if (!missingRules.length) {
207
+ log("⏭ .gitignore ya contiene las reglas necesarias.");
208
+ return;
209
+ }
210
+
211
+ const block = rules.join("\n");
212
+ const separator = existing.endsWith("\n") || existing.length === 0 ? "" : "\n";
213
+
214
+ fs.writeFileSync(gitignorePath, `${existing}${separator}${block}`, "utf-8");
215
+ log("✓ Actualizado: .gitignore");
216
+ }
217
+
218
+ function mergeObject(target, source) {
219
+ if (!source || typeof source !== "object") return target || {};
220
+
221
+ const output = target && typeof target === "object" ? { ...target } : {};
222
+
223
+ for (const [key, value] of Object.entries(source)) {
224
+ output[key] = value;
225
+ }
226
+
227
+ return output;
228
+ }
229
+
230
+ function mergePackageFromTemplate({ updateName = false } = {}) {
231
+ const templatePackagePath = path.join(templateRoot, "package.json");
232
+ const targetPackagePath = path.join(targetDir, "package.json");
233
+
234
+ const templatePackage = readJson(templatePackagePath);
235
+ const targetPackage = readJson(targetPackagePath);
236
+
237
+ if (!templatePackage || !targetPackage) return;
238
+
239
+ if (updateName) {
240
+ targetPackage.name = cleanPackageName(path.basename(targetDir));
241
+ }
242
+
243
+ targetPackage.scripts = mergeObject(targetPackage.scripts, {
244
+ dev: targetPackage.scripts?.dev || "slidev slides.md --open --port 3000",
245
+ config: "node scripts/generar-desde-config.mjs",
246
+ semana: "node scripts/semana.mjs",
247
+ "pages:check": "node scripts/preparar-github-pages.mjs",
248
+ "actualizar:tema": "npm create openclass-uniminuto@latest . -- --update-theme",
249
+ "actualizar:tema:preview": "npm run actualizar:tema && npm run config && npm run dev",
250
+ "dev:all": "node scripts/dev-all.mjs",
251
+ "dev:todo": "node scripts/dev-all.mjs",
252
+ "build:all": "node scripts/build-site.mjs",
253
+ "build:incremental": "node scripts/build-incremental.mjs",
254
+ "export:downloads": "node scripts/export-downloads.mjs",
255
+ "export:incremental": "node scripts/export-incremental.mjs",
256
+ "pages:build": "npm run config && npm run export:downloads && npm run build:all",
257
+ "pages:preview": "npm run preview:pages",
258
+ publicar: "node scripts/publicar.mjs",
259
+ nuevo: "node scripts/nuevo-curso.mjs",
260
+ "zip:template": "node scripts/zip-template.mjs",
261
+ });
262
+
263
+ targetPackage.dependencies = mergeObject(
264
+ targetPackage.dependencies,
265
+ templatePackage.dependencies,
266
+ );
267
+
268
+ targetPackage.devDependencies = mergeObject(
269
+ targetPackage.devDependencies,
270
+ templatePackage.devDependencies,
271
+ );
272
+
273
+ writeJson(targetPackagePath, targetPackage);
274
+ log("✓ Actualizado: package.json");
275
+ }
276
+
277
+ function patchPackageLockName() {
278
+ const lockPath = path.join(targetDir, "package-lock.json");
279
+ const lock = readJson(lockPath);
280
+
281
+ if (!lock) return;
282
+
283
+ const innerName = cleanPackageName(path.basename(targetDir));
284
+
285
+ lock.name = innerName;
286
+
287
+ if (lock.packages && lock.packages[""]) {
288
+ lock.packages[""].name = innerName;
289
+ }
290
+
291
+ writeJson(lockPath, lock);
102
292
  }
103
293
 
104
294
  function updateThemeOnly() {
@@ -107,88 +297,79 @@ function updateThemeOnly() {
107
297
  }
108
298
 
109
299
  log("\n┌──────────────────────────────────────────────┐");
110
- log("│ Actualizar tema Open Class UNIMINUTO │");
300
+ log("│ Actualizar infraestructura Open Class │");
111
301
  log("└──────────────────────────────────────────────┘\n");
112
302
  log(`Destino: ${targetDir}`);
113
- log("Modo: solo theme/components/styles/layouts y recursos base seguros\n");
303
+ log("Modo: actualizar tema, scripts, plantillas y recursos base seguros.\n");
304
+ log("No se sobrescriben: semanas/, slides.md ni openclass.config.json existente.\n");
114
305
 
115
306
  const pathsToUpdate = [
116
307
  "README.md",
117
- "theme/uniminuto/components",
308
+
309
+ "theme/uniminuto/components",
118
310
  "theme/uniminuto/layouts",
119
311
  "theme/uniminuto/styles",
120
312
  "theme/uniminuto/package.json",
121
313
  "theme/uniminuto/README-AutoFit.md",
314
+
122
315
  "setup",
123
316
  "snippets",
317
+
124
318
  "scripts/build-site.mjs",
125
319
  "scripts/build-incremental.mjs",
126
320
  "scripts/decks.mjs",
127
321
  "scripts/dev-all.mjs",
128
322
  "scripts/export-downloads.mjs",
129
323
  "scripts/export-incremental.mjs",
324
+ "scripts/generar-desde-config.mjs",
325
+ "scripts/nuevo-curso.mjs",
130
326
  "scripts/preparar-github-pages.mjs",
327
+ "scripts/publicar.mjs",
131
328
  "scripts/semana.mjs",
132
- ".github/workflows/deploy.yml"
329
+ "scripts/zip-template.mjs",
330
+
331
+ "plantillas",
332
+
333
+ ".github/workflows/deploy.yml",
334
+
335
+ "public/fondos",
133
336
  ];
134
337
 
135
338
  for (const relativePath of pathsToUpdate) {
136
- copyPathAlways(path.join(templateRoot, relativePath), path.join(targetDir, relativePath));
339
+ copyTemplatePathAlways(relativePath);
137
340
  }
138
341
 
139
- ensureFileFromTemplate("public/favicon.png", { onlyIfMissing: true });
140
- ensureFileFromTemplate("public/imagenes/favicon.png", { onlyIfMissing: true });
141
- ensureFileFromTemplate("public/imagenes/avion.png", { onlyIfMissing: false });
142
-
143
- patchJson(path.join(targetDir, "package.json"), (pkg) => {
144
- pkg.scripts = pkg.scripts || {};
145
- pkg.scripts["dev"] = pkg.scripts["dev"] || "slidev slides.md --open --port 3000";
146
- pkg.scripts["dev:all"] = "node scripts/dev-all.mjs";
147
- pkg.scripts["dev:todo"] = "node scripts/dev-all.mjs";
148
- pkg.scripts["build:all"] = "node scripts/build-site.mjs";
149
- pkg.scripts["build:incremental"] = "node scripts/build-incremental.mjs";
150
- pkg.scripts["export:downloads"] = "node scripts/export-downloads.mjs";
151
- pkg.scripts["export:incremental"] = "node scripts/export-incremental.mjs";
152
- pkg.scripts["pages:check"] = "node scripts/preparar-github-pages.mjs";
153
- pkg.scripts["pages:build"] = "npm run export:downloads && npm run build:all";
154
- pkg.scripts["pages:preview"] = "npm run preview:pages";
155
- pkg.scripts["semana"] = "node scripts/semana.mjs";
156
- pkg.scripts["actualizar:tema"] = "npm create openclass-uniminuto@latest . -- --update-theme";
157
- });
342
+ copyTemplatePathIfMissing("openclass.config.json");
158
343
 
159
- patchJson(path.join(targetDir, "package.json"), (pkg) => {
160
- pkg.scripts = pkg.scripts || {};
161
- pkg.scripts["dev"] = pkg.scripts["dev"] || "slidev slides.md --open --port 3000";
162
- pkg.scripts["dev:all"] = "node scripts/dev-all.mjs";
163
- pkg.scripts["dev:todo"] = "node scripts/dev-all.mjs";
164
- pkg.scripts["build:all"] = "node scripts/build-site.mjs";
165
- pkg.scripts["build:incremental"] = "node scripts/build-incremental.mjs";
166
- pkg.scripts["export:downloads"] = "node scripts/export-downloads.mjs";
167
- pkg.scripts["export:incremental"] = "node scripts/export-incremental.mjs";
168
- pkg.scripts["pages:check"] = "node scripts/preparar-github-pages.mjs";
169
- pkg.scripts["pages:build"] = "npm run export:downloads && npm run build:all";
170
- pkg.scripts["pages:preview"] = "npm run preview:pages";
171
- pkg.scripts["semana"] = "node scripts/semana.mjs";
172
- pkg.scripts["actualizar:tema"] = "npm create openclass-uniminuto@latest . -- --update-theme";
173
- });
174
- log("\n✅ Tema actualizado sin tocar semanas, slides.md ni openclass.config.json.");
344
+ copyTemplatePathIfMissing("public/descargas/.gitkeep");
345
+ copyTemplatePathIfMissing("public/videos/.gitkeep");
346
+ copyTemplatePathIfMissing("public/imagenes/.gitkeep");
347
+
348
+ copyTemplatePathIfMissing("public/favicon.png");
349
+ copyTemplatePathIfMissing("public/imagenes/favicon.png");
350
+
351
+ copyTemplatePathAlways("public/imagenes/avion.png");
352
+
353
+ appendGitignoreRules();
354
+
355
+ mergePackageFromTemplate({ updateName: false });
356
+
357
+ log("\n✅ Infraestructura actualizada sin tocar el contenido académico.");
175
358
  log(" Recomendado ahora:");
176
- log(" npm run dev");
177
- log(" npm run export:downloads");
359
+ log(" npm install");
360
+ log(" npm run config");
361
+ log(" npm run pages:build");
178
362
  log("");
179
363
  }
180
364
 
181
365
  function isEffectivelyEmptyProject(dir) {
182
366
  if (!fs.existsSync(dir)) return true;
183
- const entries = fs.readdirSync(dir).filter((entry) => ![".git", ".gitkeep"].includes(entry));
184
- return entries.length === 0;
185
- }
186
367
 
187
- function patchJson(filePath, patcher) {
188
- if (!fs.existsSync(filePath)) return;
189
- const data = JSON.parse(fs.readFileSync(filePath, "utf-8"));
190
- patcher(data);
191
- fs.writeFileSync(filePath, JSON.stringify(data, null, 2) + "\n", "utf-8");
368
+ const entries = fs
369
+ .readdirSync(dir)
370
+ .filter((entry) => ![".git", ".gitkeep"].includes(entry));
371
+
372
+ return entries.length === 0;
192
373
  }
193
374
 
194
375
  if (!fs.existsSync(templateRoot)) {
@@ -204,10 +385,14 @@ if (fs.existsSync(targetDir) && !isEffectivelyEmptyProject(targetDir) && !forceO
204
385
  fail(`La carpeta destino ya contiene archivos: ${targetDir}
205
386
 
206
387
  Para trabajar dentro de un repositorio ya creado en GitHub, usa una carpeta vacía o ejecuta con --force si deseas sobrescribir archivos existentes.
388
+
207
389
  Ejemplo:
208
- npm create openclass-uniminuto@latest . -- --iot --force
390
+ npm create openclass-uniminuto@latest . -- --force
209
391
 
210
- Para actualizar únicamente layouts/tema de un proyecto existente, usa:
392
+ Para aplicar la configuración IoT inicial:
393
+ npm create openclass-uniminuto@latest . -- --iot
394
+
395
+ Para actualizar únicamente la infraestructura de un proyecto existente:
211
396
  npm create openclass-uniminuto@latest . -- --update-theme`);
212
397
  }
213
398
 
@@ -215,34 +400,57 @@ log("\n┌───────────────────────
215
400
  log("│ Crear proyecto Open Class UNIMINUTO · Slidev │");
216
401
  log("└──────────────────────────────────────────────┘\n");
217
402
  log(`Destino: ${targetDir}`);
218
- if (isCurrentDirectoryTarget) log("Modo: aplicar plantilla en el directorio actual");
219
- if (forceOverwrite) log("Modo: --force activo; se podrán sobrescribir archivos existentes");
403
+
404
+ if (isCurrentDirectoryTarget) {
405
+ log("Modo: aplicar plantilla en el directorio actual");
406
+ }
407
+
408
+ if (forceOverwrite) {
409
+ log("Modo: --force activo; se podrán sobrescribir archivos existentes");
410
+ }
220
411
 
221
412
  copyTemplate(templateRoot, targetDir);
222
413
 
223
414
  const innerName = cleanPackageName(path.basename(targetDir));
415
+
224
416
  patchJson(path.join(targetDir, "package.json"), (pkg) => {
225
417
  pkg.name = innerName;
226
418
  });
419
+
227
420
  patchJson(path.join(targetDir, "package-lock.json"), (lock) => {
228
421
  lock.name = innerName;
229
- if (lock.packages && lock.packages[""]) lock.packages[""].name = innerName;
422
+
423
+ if (lock.packages && lock.packages[""]) {
424
+ lock.packages[""].name = innerName;
425
+ }
230
426
  });
231
427
 
232
428
  if (flags.has("--iot")) {
233
- const sourceConfig = path.join(targetDir, "config", "openclass.config.iot-desde-openclass-iot.json");
429
+ const sourceConfig = path.join(
430
+ targetDir,
431
+ "config",
432
+ "openclass.config.iot-desde-openclass-iot.json",
433
+ );
434
+
234
435
  const destConfig = path.join(targetDir, "openclass.config.json");
436
+
235
437
  if (!fs.existsSync(sourceConfig)) {
236
438
  fail("No se encontró la configuración IoT incluida en la plantilla.");
237
439
  }
440
+
238
441
  fs.copyFileSync(sourceConfig, destConfig);
239
442
  log("✓ Configuración IoT aplicada en openclass.config.json");
240
443
 
241
- const result = spawnSync(process.execPath, ["scripts/generar-desde-config.mjs", "--force"], {
242
- cwd: targetDir,
243
- stdio: "inherit",
244
- shell: false,
245
- });
444
+ const result = spawnSync(
445
+ process.execPath,
446
+ ["scripts/generar-desde-config.mjs", "--force"],
447
+ {
448
+ cwd: targetDir,
449
+ stdio: "inherit",
450
+ shell: false,
451
+ },
452
+ );
453
+
246
454
  if (result.status !== 0) {
247
455
  fail("El generador de configuración no pudo completar el proyecto IoT.");
248
456
  }
@@ -250,29 +458,39 @@ if (flags.has("--iot")) {
250
458
 
251
459
  if (flags.has("--install")) {
252
460
  log("\nInstalando dependencias con npm install...\n");
461
+
253
462
  const result = spawnSync("npm", ["install"], {
254
463
  cwd: targetDir,
255
464
  stdio: "inherit",
256
465
  shell: process.platform === "win32",
257
466
  });
467
+
258
468
  if (result.status !== 0) {
259
469
  fail("npm install terminó con error. Revisa la salida de consola.");
260
470
  }
261
471
  }
262
472
 
263
473
  log("\n✅ Proyecto creado correctamente.\n");
264
- log(`Siguientes pasos:`);
474
+ log("Siguientes pasos:");
265
475
  log(` cd ${path.relative(process.cwd(), targetDir) || "."}`);
266
- if (!flags.has("--install")) log(" npm install");
267
- if (!flags.has("--iot")) log(" npm run nuevo");
476
+
477
+ if (!flags.has("--install")) {
478
+ log(" npm install");
479
+ }
480
+
481
+ if (!flags.has("--iot")) {
482
+ log(" npm run nuevo");
483
+ }
484
+
268
485
  log(" npm run semana -- 1");
269
486
  log(" npm run dev");
270
- log("\nPara activar una semana adicional:");
271
- log(" npm run semana -- 2 --title \"Título de la semana 2\"");
272
- log("\nPara actualizar layouts/tema en un proyecto existente:");
487
+ log("");
488
+ log("Para activar una semana adicional:");
489
+ log(' npm run semana -- 2 --title "Título de la semana 2"');
490
+ log("");
491
+ log("Para actualizar infraestructura en un proyecto existente:");
273
492
  log(" npm create openclass-uniminuto@latest . -- --update-theme");
274
- log("\nPara revisar la publicación en GitHub Pages:");
275
- log(" npm run pages:check");
276
493
  log("");
277
-
278
-
494
+ log("Para revisar la publicación en GitHub Pages:");
495
+ log(" npm run pages:check");
496
+ log("");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-openclass-uniminuto",
3
- "version": "1.6.2",
3
+ "version": "1.6.4",
4
4
  "description": "Creador de proyectos Open Class UNIMINUTO basados en Slidev, con generación incremental por semanas, actualización de tema y GitHub Pages.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -42,7 +42,7 @@ jobs:
42
42
  - name: Install Chromium for Slidev export
43
43
  run: npx playwright install chromium --with-deps
44
44
 
45
- - name: Generate and build Open Class
45
+ - name: Generate, export and build Open Class
46
46
  run: npm run pages:build
47
47
 
48
48
  - name: Upload GitHub Pages artifact
@@ -61,4 +61,4 @@ jobs:
61
61
  steps:
62
62
  - name: Deploy to GitHub Pages
63
63
  id: deployment
64
- uses: actions/deploy-pages@v4
64
+ uses: actions/deploy-pages@v4