slidev-workspace 0.5.2 → 0.6.1

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/dist/cli.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import { fileURLToPath } from "node:url";
3
3
  import { dirname, join, resolve } from "node:path";
4
4
  import { existsSync, mkdirSync, readdirSync } from "node:fs";
5
- import { cp } from "node:fs/promises";
5
+ import { cp, rm } from "node:fs/promises";
6
6
  import { execSync } from "node:child_process";
7
7
  import { build, createServer } from "vite";
8
8
  import vue from "@vitejs/plugin-vue";
@@ -365,6 +365,46 @@ async function buildAllSlides() {
365
365
  }
366
366
  }
367
367
  }
368
+ async function exportOgImages() {
369
+ const workspaceCwd = process.env.SLIDEV_WORKSPACE_CWD || process.cwd();
370
+ const config = loadConfig(workspaceCwd);
371
+ const slidesDirs = resolveSlidesDirs(config, workspaceCwd);
372
+ console.log("🖼️ Exporting OG images for all slides...");
373
+ try {
374
+ execSync("pnpm -r export --format png --range 1", {
375
+ cwd: workspaceCwd,
376
+ stdio: "inherit"
377
+ });
378
+ console.log("📦 Copying exported images to og-image.png...");
379
+ for (const slidesDir of slidesDirs) {
380
+ if (!existsSync(slidesDir)) {
381
+ console.warn(`⚠️ Slides directory not found: ${slidesDir}`);
382
+ continue;
383
+ }
384
+ const slides = readdirSync(slidesDir, { withFileTypes: true }).filter((dirent) => dirent.isDirectory()).map((dirent) => dirent.name);
385
+ for (const slideName of slides) {
386
+ const slideDir = join(slidesDir, slideName);
387
+ const packageJsonPath = join(slideDir, "package.json");
388
+ if (!existsSync(packageJsonPath)) continue;
389
+ const exportedFile = join(slideDir, "slides-export", "1.png");
390
+ const targetFile = join(slideDir, "og-image.png");
391
+ const exportDir = join(slideDir, "slides-export");
392
+ if (existsSync(exportedFile)) {
393
+ await cp(exportedFile, targetFile);
394
+ console.log(`✅ Generated OG image for: ${slideName}`);
395
+ await rm(exportDir, {
396
+ recursive: true,
397
+ force: true
398
+ });
399
+ } else console.warn(`⚠️ Export file not found for ${slideName}: ${exportedFile}`);
400
+ }
401
+ }
402
+ console.log("✅ All OG images exported successfully!");
403
+ } catch (error) {
404
+ console.error("❌ Failed to export OG images:", error);
405
+ process.exit(1);
406
+ }
407
+ }
368
408
  async function copyToGhPages() {
369
409
  const workspaceCwd = process.env.SLIDEV_WORKSPACE_CWD || process.cwd();
370
410
  const config = loadConfig(workspaceCwd);
@@ -424,13 +464,15 @@ Usage:
424
464
  slidev-workspace <command> [options]
425
465
 
426
466
  Commands:
427
- dev Start the development server
428
- build Build the project for production
429
- help Show this help message
467
+ dev Start the development server
468
+ build Build the project for production
469
+ export-og Export OG images for all slides
470
+ help Show this help message
430
471
 
431
472
  Examples:
432
473
  slidev-workspace dev # Start development server
433
474
  slidev-workspace build # Build all slides and preview app
475
+ slidev-workspace export-og # Export OG images for all slides
434
476
 
435
477
  Configuration:
436
478
  Use slidev-workspace.yml to set baseUrl for all builds
@@ -449,6 +491,10 @@ async function main() {
449
491
  process.env.SLIDEV_WORKSPACE_CWD = process.cwd();
450
492
  await runViteBuild();
451
493
  break;
494
+ case "export-og":
495
+ process.env.SLIDEV_WORKSPACE_CWD = process.cwd();
496
+ await exportOgImages();
497
+ break;
452
498
  case "help":
453
499
  case "--help":
454
500
  case "-h":
package/dist/index.js CHANGED
@@ -64,7 +64,7 @@ function resolveImageUrl(slide, domain) {
64
64
  if (hasOgImage) {
65
65
  const imagePath = `og-image.png?v=${Date.now()}`;
66
66
  try {
67
- const path = IS_DEVELOPMENT ? pathJoin(slidePath, imagePath) : pathJoin(baseUrl, slidePath, imagePath);
67
+ const path = IS_DEVELOPMENT ? imagePath : pathJoin(baseUrl, slidePath, imagePath);
68
68
  return new URL(path, domain).href;
69
69
  } catch (error) {
70
70
  console.error("Failed to resolve og-image.png path:", error);
@@ -83,7 +83,7 @@ function resolveImageUrl(slide, domain) {
83
83
  if (background) {
84
84
  if (isUrl(background)) return background;
85
85
  try {
86
- return IS_DEVELOPMENT ? new URL(pathJoin(slidePath, background), domain).href : new URL(pathJoin(baseUrl, slidePath, background), domain).href;
86
+ return IS_DEVELOPMENT ? new URL(background, domain).href : new URL(pathJoin(baseUrl, slidePath, background), domain).href;
87
87
  } catch (error) {
88
88
  console.error("Failed to resolve background path:", error);
89
89
  return "https://cover.sli.dev";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "slidev-workspace",
3
- "version": "0.5.2",
3
+ "version": "0.6.1",
4
4
  "description": "A workspace tool for managing multiple Slidev presentations with API-based content management",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -45,7 +45,7 @@ describe("resolveImageUrl (Development Mode)", () => {
45
45
 
46
46
  const result = resolveImageUrl(slide, domain);
47
47
 
48
- expect(result).toBe("http://localhost:3001/og-image.png");
48
+ expect(result).toMatch(/^http:\/\/localhost:3001\/og-image\.png\?v=\d+$/);
49
49
  });
50
50
 
51
51
  it("should return seoMeta.ogImage when it's an absolute URL", async () => {
@@ -115,9 +115,7 @@ describe("resolveImageUrl (Development Mode)", () => {
115
115
 
116
116
  const result = resolveImageUrl(slide, domain);
117
117
 
118
- expect(result).toBe(
119
- "http://localhost:3001/slides-presentation-1/background.jpg",
120
- );
118
+ expect(result).toBe("http://localhost:3001/background.jpg");
121
119
  });
122
120
 
123
121
  it("should return default cover when no image sources provided", async () => {
@@ -150,7 +148,7 @@ describe("resolveImageUrl (Development Mode)", () => {
150
148
 
151
149
  const result = resolveImageUrl(slide, domain);
152
150
 
153
- expect(result).toBe("http://localhost:3001/og-image.png");
151
+ expect(result).toMatch(/^http:\/\/localhost:3001\/og-image\.png\?v=\d+$/);
154
152
  expect(result).not.toBe("https://example.com/image.jpg");
155
153
  });
156
154
 
@@ -217,13 +215,14 @@ describe("resolveImageUrl (Production Mode)", () => {
217
215
  const slide = createMockSlide({
218
216
  hasOgImage: true,
219
217
  baseUrl: "/slidev-workspace-starter",
218
+ path: "/slides-presentation-1/",
220
219
  });
221
220
  const domain = "https://my-slides.com";
222
221
 
223
222
  const result = resolveImageUrl(slide, domain);
224
223
 
225
- expect(result).toBe(
226
- "https://my-slides.com/slidev-workspace-starter/og-image.png",
224
+ expect(result).toMatch(
225
+ /^https:\/\/my-slides\.com\/slidev-workspace-starter\/slides-presentation-1\/og-image\.png\?v=\d+$/,
227
226
  );
228
227
  });
229
228
 
@@ -443,7 +442,9 @@ describe("useSlides (Development Mode)", () => {
443
442
 
444
443
  const firstSlide = slides.value[0];
445
444
 
446
- expect(firstSlide.image).toBe("http://localhost:3001/og-image.png");
445
+ expect(firstSlide.image).toMatch(
446
+ /^http:\/\/localhost:3001\/og-image\.png\?v=\d+$/,
447
+ );
447
448
  });
448
449
 
449
450
  it("should use default cover when no background is provided", async () => {
@@ -540,8 +541,8 @@ describe("useSlides (Production Mode)", () => {
540
541
  const result = await setupUseSlidesProduction();
541
542
  const firstSlide = result.slides.value[0];
542
543
 
543
- expect(firstSlide.image).toBe(
544
- "https://my-slides.com/slidev-workspace-starter/og-image.png",
544
+ expect(firstSlide.image).toMatch(
545
+ /^https:\/\/my-slides\.com\/slidev-workspace-starter\/slides-presentation-1\/og-image\.png\?v=\d+$/,
545
546
  );
546
547
  });
547
548
 
@@ -567,8 +568,8 @@ describe("useSlides (Production Mode)", () => {
567
568
 
568
569
  // First slide has hasOgImage: true, so should use og-image.png
569
570
  expect(firstSlide.image).toContain("og-image.png");
570
- expect(firstSlide.image).toBe(
571
- "https://my-slides.com/slidev-workspace-starter/og-image.png",
571
+ expect(firstSlide.image).toMatch(
572
+ /^https:\/\/my-slides\.com\/slidev-workspace-starter\/slides-presentation-1\/og-image\.png\?v=\d+$/,
572
573
  );
573
574
  });
574
575
 
@@ -40,7 +40,7 @@ export function resolveImageUrl(slide: SlideInfo, domain: string): string {
40
40
  const imagePath = `og-image.png?v=${Date.now()}`;
41
41
  try {
42
42
  const path = IS_DEVELOPMENT
43
- ? pathJoin(slidePath, imagePath)
43
+ ? imagePath
44
44
  : pathJoin(baseUrl, slidePath, imagePath);
45
45
 
46
46
  return new URL(path, domain).href;
@@ -74,7 +74,7 @@ export function resolveImageUrl(slide: SlideInfo, domain: string): string {
74
74
 
75
75
  try {
76
76
  return IS_DEVELOPMENT
77
- ? new URL(pathJoin(slidePath, background), domain).href
77
+ ? new URL(background, domain).href
78
78
  : new URL(pathJoin(baseUrl, slidePath, background), domain).href;
79
79
  } catch (error) {
80
80
  console.error("Failed to resolve background path:", error);