simple-photo-gallery 2.0.11 → 2.0.12

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/index.js CHANGED
@@ -4,7 +4,7 @@ import { Command } from 'commander';
4
4
  import { LogLevels, createConsola } from 'consola';
5
5
  import { execSync, spawn } from 'child_process';
6
6
  import fs8, { promises } from 'fs';
7
- import path7 from 'path';
7
+ import path from 'path';
8
8
  import { Buffer } from 'buffer';
9
9
  import { fileURLToPath } from 'url';
10
10
  import sharp2 from 'sharp';
@@ -77,36 +77,42 @@ async function generateBlurHash(imagePath, componentX = 4, componentY = 3) {
77
77
  }
78
78
 
79
79
  // src/modules/build/utils/index.ts
80
- var __dirname = path7.dirname(fileURLToPath(import.meta.url));
81
- var SOCIAL_CARD_FONT_RELATIVE_PATH = path7.join("assets", "fonts", "dejavu", "DejaVuSans-Bold.ttf");
80
+ var __dirname = path.dirname(fileURLToPath(import.meta.url));
81
+ var SOCIAL_CARD_FONT_RELATIVE_PATH = path.join("assets", "fonts", "dejavu", "DejaVuSans-Bold.ttf");
82
82
  var socialCardFontBase64;
83
83
  function resolveFromCurrentDir(...segments) {
84
- return path7.resolve(__dirname, ...segments);
84
+ return path.resolve(__dirname, ...segments);
85
85
  }
86
86
  function findSocialCardFontPath() {
87
87
  const fontCandidates = [
88
88
  resolveFromCurrentDir("../../../../", SOCIAL_CARD_FONT_RELATIVE_PATH),
89
- path7.resolve(__dirname, "../", SOCIAL_CARD_FONT_RELATIVE_PATH),
90
- path7.resolve(process4.cwd(), SOCIAL_CARD_FONT_RELATIVE_PATH)
89
+ path.resolve(__dirname, "../", SOCIAL_CARD_FONT_RELATIVE_PATH),
90
+ path.resolve(__dirname, "../../", SOCIAL_CARD_FONT_RELATIVE_PATH),
91
+ path.resolve(process4.cwd(), SOCIAL_CARD_FONT_RELATIVE_PATH),
92
+ path.resolve(process4.cwd(), "../", SOCIAL_CARD_FONT_RELATIVE_PATH)
91
93
  ];
92
94
  for (const candidate of fontCandidates) {
93
95
  if (fs8.existsSync(candidate)) {
94
96
  return candidate;
95
97
  }
96
98
  }
97
- throw new Error("Social media card font file not found");
99
+ return null;
98
100
  }
99
101
  function getSocialCardFontBase64() {
100
- if (socialCardFontBase64) {
102
+ if (socialCardFontBase64 !== void 0) {
101
103
  return socialCardFontBase64;
102
104
  }
103
105
  const fontPath = findSocialCardFontPath();
106
+ if (!fontPath) {
107
+ socialCardFontBase64 = null;
108
+ return null;
109
+ }
104
110
  socialCardFontBase64 = fs8.readFileSync(fontPath).toString("base64");
105
111
  return socialCardFontBase64;
106
112
  }
107
113
  async function createGallerySocialMediaCardImage(headerPhotoPath, title, ouputPath, ui) {
108
114
  ui?.start(`Creating social media card image`);
109
- const headerBasename = path7.basename(headerPhotoPath, path7.extname(headerPhotoPath));
115
+ const headerBasename = path.basename(headerPhotoPath, path.extname(headerPhotoPath));
110
116
  if (fs8.existsSync(ouputPath)) {
111
117
  ui?.success(`Social media card image already exists`);
112
118
  return headerBasename;
@@ -116,17 +122,20 @@ async function createGallerySocialMediaCardImage(headerPhotoPath, title, ouputPa
116
122
  const outputPath = ouputPath;
117
123
  await sharp2(resizedImageBuffer).toFile(outputPath);
118
124
  const fontBase64 = getSocialCardFontBase64();
119
- const svgText = `
120
- <svg width="1200" height="631" xmlns="http://www.w3.org/2000/svg">
121
- <defs>
122
- <style>
125
+ const fontFace = fontBase64 ? `
123
126
  @font-face {
124
127
  font-family: 'DejaVu Sans';
125
128
  src: url('data:font/ttf;base64,${fontBase64}') format('truetype');
126
129
  font-weight: 700;
127
130
  font-style: normal;
128
- }
129
- .title { font-family: 'DejaVu Sans', Arial, sans-serif; font-size: 96px; font-weight: bold; fill: white; stroke: black; stroke-width: 5; paint-order: stroke; text-anchor: middle; }
131
+ }` : "";
132
+ const fontFamily = fontBase64 ? "'DejaVu Sans', Arial, sans-serif" : "Arial, sans-serif";
133
+ const svgText = `
134
+ <svg width="1200" height="631" xmlns="http://www.w3.org/2000/svg">
135
+ <defs>
136
+ <style>
137
+ ${fontFace}
138
+ .title { font-family: ${fontFamily}; font-size: 96px; font-weight: bold; fill: white; stroke: black; stroke-width: 5; paint-order: stroke; text-anchor: middle; }
130
139
  </style>
131
140
  </defs>
132
141
  <text x="600" y="250" class="title">${title}</text>
@@ -140,7 +149,7 @@ async function createGallerySocialMediaCardImage(headerPhotoPath, title, ouputPa
140
149
  async function createOptimizedHeaderImage(headerPhotoPath, outputFolder, ui) {
141
150
  ui?.start(`Creating optimized header images`);
142
151
  const image = await loadImage(headerPhotoPath);
143
- const headerBasename = path7.basename(headerPhotoPath, path7.extname(headerPhotoPath));
152
+ const headerBasename = path.basename(headerPhotoPath, path.extname(headerPhotoPath));
144
153
  const generatedFiles = [];
145
154
  ui?.debug("Generating blurhash for header image");
146
155
  const blurHash = await generateBlurHash(headerPhotoPath);
@@ -149,22 +158,22 @@ async function createOptimizedHeaderImage(headerPhotoPath, outputFolder, ui) {
149
158
  ui?.debug(`Creating landscape header image ${width}`);
150
159
  const avifFilename = `${headerBasename}_landscape_${width}.avif`;
151
160
  const jpgFilename = `${headerBasename}_landscape_${width}.jpg`;
152
- if (fs8.existsSync(path7.join(outputFolder, avifFilename))) {
161
+ if (fs8.existsSync(path.join(outputFolder, avifFilename))) {
153
162
  ui?.debug(`Landscape header image ${width} AVIF already exists`);
154
163
  } else {
155
164
  await cropAndResizeImage(
156
165
  image.clone(),
157
- path7.join(outputFolder, avifFilename),
166
+ path.join(outputFolder, avifFilename),
158
167
  width,
159
168
  width * landscapeYFactor,
160
169
  "avif"
161
170
  );
162
171
  }
163
172
  generatedFiles.push(avifFilename);
164
- if (fs8.existsSync(path7.join(outputFolder, jpgFilename))) {
173
+ if (fs8.existsSync(path.join(outputFolder, jpgFilename))) {
165
174
  ui?.debug(`Landscape header image ${width} JPG already exists`);
166
175
  } else {
167
- await cropAndResizeImage(image.clone(), path7.join(outputFolder, jpgFilename), width, width * landscapeYFactor, "jpg");
176
+ await cropAndResizeImage(image.clone(), path.join(outputFolder, jpgFilename), width, width * landscapeYFactor, "jpg");
168
177
  }
169
178
  generatedFiles.push(jpgFilename);
170
179
  }
@@ -173,16 +182,16 @@ async function createOptimizedHeaderImage(headerPhotoPath, outputFolder, ui) {
173
182
  ui?.debug(`Creating portrait header image ${width}`);
174
183
  const avifFilename = `${headerBasename}_portrait_${width}.avif`;
175
184
  const jpgFilename = `${headerBasename}_portrait_${width}.jpg`;
176
- if (fs8.existsSync(path7.join(outputFolder, avifFilename))) {
185
+ if (fs8.existsSync(path.join(outputFolder, avifFilename))) {
177
186
  ui?.debug(`Portrait header image ${width} AVIF already exists`);
178
187
  } else {
179
- await cropAndResizeImage(image.clone(), path7.join(outputFolder, avifFilename), width, width * portraitYFactor, "avif");
188
+ await cropAndResizeImage(image.clone(), path.join(outputFolder, avifFilename), width, width * portraitYFactor, "avif");
180
189
  }
181
190
  generatedFiles.push(avifFilename);
182
- if (fs8.existsSync(path7.join(outputFolder, jpgFilename))) {
191
+ if (fs8.existsSync(path.join(outputFolder, jpgFilename))) {
183
192
  ui?.debug(`Portrait header image ${width} JPG already exists`);
184
193
  } else {
185
- await cropAndResizeImage(image.clone(), path7.join(outputFolder, jpgFilename), width, width * portraitYFactor, "jpg");
194
+ await cropAndResizeImage(image.clone(), path.join(outputFolder, jpgFilename), width, width * portraitYFactor, "jpg");
186
195
  }
187
196
  generatedFiles.push(jpgFilename);
188
197
  }
@@ -215,12 +224,12 @@ function cleanupOldHeaderImages(outputFolder, currentHeaderBasename, ui) {
215
224
  const landscapeMatch = file.match(/^(.+)_landscape_\d+\.(avif|jpg)$/);
216
225
  const portraitMatch = file.match(/^(.+)_portrait_\d+\.(avif|jpg)$/);
217
226
  if (landscapeMatch && landscapeMatch[1] !== currentHeaderBasename) {
218
- const filePath = path7.join(outputFolder, file);
227
+ const filePath = path.join(outputFolder, file);
219
228
  ui?.debug(`Deleting old landscape header image: ${file}`);
220
229
  fs8.unlinkSync(filePath);
221
230
  deletedCount++;
222
231
  } else if (portraitMatch && portraitMatch[1] !== currentHeaderBasename) {
223
- const filePath = path7.join(outputFolder, file);
232
+ const filePath = path.join(outputFolder, file);
224
233
  ui?.debug(`Deleting old portrait header image: ${file}`);
225
234
  fs8.unlinkSync(filePath);
226
235
  deletedCount++;
@@ -234,7 +243,7 @@ function cleanupOldHeaderImages(outputFolder, currentHeaderBasename, ui) {
234
243
  }
235
244
  function findGalleries(basePath, recursive) {
236
245
  const galleryDirs = [];
237
- const galleryJsonPath = path7.join(basePath, "gallery", "gallery.json");
246
+ const galleryJsonPath = path.join(basePath, "gallery", "gallery.json");
238
247
  if (fs8.existsSync(galleryJsonPath)) {
239
248
  galleryDirs.push(basePath);
240
249
  }
@@ -243,7 +252,7 @@ function findGalleries(basePath, recursive) {
243
252
  const entries = fs8.readdirSync(basePath, { withFileTypes: true });
244
253
  for (const entry of entries) {
245
254
  if (entry.isDirectory() && entry.name !== "gallery") {
246
- const subPath = path7.join(basePath, entry.name);
255
+ const subPath = path.join(basePath, entry.name);
247
256
  const subResults = findGalleries(subPath, recursive);
248
257
  galleryDirs.push(...subResults);
249
258
  }
@@ -302,20 +311,20 @@ function migrateGalleryJson(deprecatedGalleryData, galleryJsonPath, ui) {
302
311
  ui.start("Old gallery.json format detected. Migrating gallery.json to the new data format.");
303
312
  let mediaBasePath;
304
313
  const imagePath = deprecatedGalleryData.sections[0].images[0].path;
305
- if (imagePath && imagePath !== path7.join("..", path7.basename(imagePath))) {
306
- mediaBasePath = path7.resolve(path7.join(path7.dirname(galleryJsonPath)), path7.dirname(imagePath));
314
+ if (imagePath && imagePath !== path.join("..", path.basename(imagePath))) {
315
+ mediaBasePath = path.resolve(path.join(path.dirname(galleryJsonPath)), path.dirname(imagePath));
307
316
  }
308
317
  const sections = deprecatedGalleryData.sections.map((section) => ({
309
318
  ...section,
310
319
  images: section.images.map((image) => ({
311
320
  ...image,
312
321
  path: void 0,
313
- filename: path7.basename(image.path)
322
+ filename: path.basename(image.path)
314
323
  }))
315
324
  }));
316
325
  const galleryData = {
317
326
  ...deprecatedGalleryData,
318
- headerImage: path7.basename(deprecatedGalleryData.headerImage),
327
+ headerImage: path.basename(deprecatedGalleryData.headerImage),
319
328
  sections,
320
329
  mediaBasePath
321
330
  };
@@ -327,7 +336,7 @@ function migrateGalleryJson(deprecatedGalleryData, galleryJsonPath, ui) {
327
336
  return galleryData;
328
337
  }
329
338
  function getMediaFileType(fileName) {
330
- const ext = path7.extname(fileName).toLowerCase();
339
+ const ext = path.extname(fileName).toLowerCase();
331
340
  if (IMAGE_EXTENSIONS.has(ext)) return "image";
332
341
  if (VIDEO_EXTENSIONS.has(ext)) return "video";
333
342
  return null;
@@ -355,7 +364,7 @@ async function scanDirectory(dirPath, ui) {
355
364
  mediaFiles.push(mediaFile);
356
365
  }
357
366
  } else if (entry.isDirectory() && entry.name !== "gallery") {
358
- subGalleryDirectories.push(path7.join(dirPath, entry.name));
367
+ subGalleryDirectories.push(path.join(dirPath, entry.name));
359
368
  }
360
369
  }
361
370
  } catch (error) {
@@ -391,12 +400,12 @@ async function getGallerySettingsFromUser(galleryName, defaultImage, ui) {
391
400
  return { title, description, url, headerImage };
392
401
  }
393
402
  async function createGalleryJson(mediaFiles, galleryJsonPath, scanPath, subGalleries = [], useDefaultSettings, ctaBanner, ui) {
394
- const galleryDir = path7.dirname(galleryJsonPath);
395
- const isSameLocation = path7.relative(scanPath, path7.join(galleryDir, "..")) === "";
403
+ const galleryDir = path.dirname(galleryJsonPath);
404
+ const isSameLocation = path.relative(scanPath, path.join(galleryDir, "..")) === "";
396
405
  const mediaBasePath = isSameLocation ? void 0 : scanPath;
397
406
  const relativeSubGalleries = subGalleries.map((subGallery) => ({
398
407
  ...subGallery,
399
- headerImage: subGallery.headerImage ? path7.relative(galleryDir, subGallery.headerImage) : ""
408
+ headerImage: subGallery.headerImage ? path.relative(galleryDir, subGallery.headerImage) : ""
400
409
  }));
401
410
  let galleryData = {
402
411
  title: "My Gallery",
@@ -419,8 +428,8 @@ async function createGalleryJson(mediaFiles, galleryJsonPath, scanPath, subGalle
419
428
  galleryData = {
420
429
  ...galleryData,
421
430
  ...await getGallerySettingsFromUser(
422
- path7.basename(path7.join(galleryDir, "..")),
423
- path7.basename(mediaFiles[0]?.filename || ""),
431
+ path.basename(path.join(galleryDir, "..")),
432
+ path.basename(mediaFiles[0]?.filename || ""),
424
433
  ui
425
434
  )
426
435
  };
@@ -428,8 +437,8 @@ async function createGalleryJson(mediaFiles, galleryJsonPath, scanPath, subGalle
428
437
  await promises.writeFile(galleryJsonPath, JSON.stringify(galleryData, null, 2));
429
438
  }
430
439
  async function galleryExists(outputPath) {
431
- const galleryPath = path7.join(outputPath, "gallery");
432
- const galleryJsonPath = path7.join(galleryPath, "gallery.json");
440
+ const galleryPath = path.join(outputPath, "gallery");
441
+ const galleryJsonPath = path.join(galleryPath, "gallery.json");
433
442
  try {
434
443
  await promises.access(galleryJsonPath);
435
444
  return true;
@@ -448,7 +457,7 @@ async function processDirectory(scanPath, outputPath, recursive, useDefaultSetti
448
457
  for (const subGalleryDir of subGalleryDirectories) {
449
458
  const result2 = await processDirectory(
450
459
  subGalleryDir,
451
- path7.join(outputPath, path7.basename(subGalleryDir)),
460
+ path.join(outputPath, path.basename(subGalleryDir)),
452
461
  recursive,
453
462
  useDefaultSettings,
454
463
  force,
@@ -463,8 +472,8 @@ async function processDirectory(scanPath, outputPath, recursive, useDefaultSetti
463
472
  }
464
473
  }
465
474
  if (mediaFiles.length > 0 || subGalleries.length > 0) {
466
- const galleryPath = path7.join(outputPath, "gallery");
467
- const galleryJsonPath = path7.join(galleryPath, "gallery.json");
475
+ const galleryPath = path.join(outputPath, "gallery");
476
+ const galleryJsonPath = path.join(galleryPath, "gallery.json");
468
477
  const exists = await galleryExists(outputPath);
469
478
  if (exists && !force) {
470
479
  const shouldOverride = await ui.prompt(`Gallery already exists at ${galleryJsonPath}. Do you want to override it?`, {
@@ -489,19 +498,19 @@ async function processDirectory(scanPath, outputPath, recursive, useDefaultSetti
489
498
  }
490
499
  const result = { totalFiles, totalGalleries };
491
500
  if (mediaFiles.length > 0 || subGalleries.length > 0) {
492
- const dirName = path7.basename(scanPath);
501
+ const dirName = path.basename(scanPath);
493
502
  result.subGallery = {
494
503
  title: capitalizeTitle(dirName),
495
504
  headerImage: mediaFiles[0]?.filename || "",
496
- path: path7.join("..", dirName)
505
+ path: path.join("..", dirName)
497
506
  };
498
507
  }
499
508
  return result;
500
509
  }
501
510
  async function init(options, ui) {
502
511
  try {
503
- const scanPath = path7.resolve(options.photos);
504
- const outputPath = options.gallery ? path7.resolve(options.gallery) : scanPath;
512
+ const scanPath = path.resolve(options.photos);
513
+ const outputPath = options.gallery ? path.resolve(options.gallery) : scanPath;
505
514
  const result = await processDirectory(
506
515
  scanPath,
507
516
  outputPath,
@@ -625,7 +634,7 @@ async function processImage(imagePath, thumbnailPath, thumbnailPathRetina, thumb
625
634
  const blurHash = await generateBlurHash(thumbnailPath);
626
635
  return {
627
636
  type: "image",
628
- filename: path7.basename(imagePath),
637
+ filename: path.basename(imagePath),
629
638
  alt: description,
630
639
  width: imageDimensions.width,
631
640
  height: imageDimensions.height,
@@ -656,7 +665,7 @@ async function processVideo(videoPath, thumbnailPath, thumbnailPathRetina, thumb
656
665
  const blurHash = await generateBlurHash(thumbnailPath);
657
666
  return {
658
667
  type: "video",
659
- filename: path7.basename(videoPath),
668
+ filename: path.basename(videoPath),
660
669
  alt: void 0,
661
670
  width: videoDimensions.width,
662
671
  height: videoDimensions.height,
@@ -672,11 +681,11 @@ async function processVideo(videoPath, thumbnailPath, thumbnailPathRetina, thumb
672
681
  }
673
682
  async function processMediaFile(mediaFile, mediaBasePath, thumbnailsPath, thumbnailSize, ui) {
674
683
  try {
675
- const filePath = path7.resolve(path7.join(mediaBasePath, mediaFile.filename));
684
+ const filePath = path.resolve(path.join(mediaBasePath, mediaFile.filename));
676
685
  const fileName = mediaFile.filename;
677
- const fileNameWithoutExt = path7.parse(fileName).name;
686
+ const fileNameWithoutExt = path.parse(fileName).name;
678
687
  const thumbnailFileName = `${fileNameWithoutExt}.avif`;
679
- const thumbnailPath = path7.join(thumbnailsPath, thumbnailFileName);
688
+ const thumbnailPath = path.join(thumbnailsPath, thumbnailFileName);
680
689
  const thumbnailPathRetina = thumbnailPath.replace(".avif", "@2x.avif");
681
690
  const lastMediaTimestamp = mediaFile.lastMediaTimestamp ? new Date(mediaFile.lastMediaTimestamp) : void 0;
682
691
  const verbose = ui.level === LogLevels.debug;
@@ -702,8 +711,8 @@ async function processMediaFile(mediaFile, mediaBasePath, thumbnailsPath, thumbn
702
711
  }
703
712
  updatedMediaFile.filename = mediaFile.filename;
704
713
  if (updatedMediaFile.thumbnail) {
705
- updatedMediaFile.thumbnail.path = path7.basename(thumbnailPath);
706
- updatedMediaFile.thumbnail.pathRetina = path7.basename(thumbnailPathRetina);
714
+ updatedMediaFile.thumbnail.path = path.basename(thumbnailPath);
715
+ updatedMediaFile.thumbnail.pathRetina = path.basename(thumbnailPathRetina);
707
716
  if (mediaFile.thumbnail?.baseUrl) {
708
717
  updatedMediaFile.thumbnail.baseUrl = mediaFile.thumbnail.baseUrl;
709
718
  }
@@ -718,14 +727,14 @@ async function processMediaFile(mediaFile, mediaBasePath, thumbnailsPath, thumbn
718
727
  }
719
728
  }
720
729
  async function processGalleryThumbnails(galleryDir, ui) {
721
- const galleryJsonPath = path7.join(galleryDir, "gallery", "gallery.json");
722
- const thumbnailsPath = path7.join(galleryDir, "gallery", "images");
730
+ const galleryJsonPath = path.join(galleryDir, "gallery", "gallery.json");
731
+ const thumbnailsPath = path.join(galleryDir, "gallery", "images");
723
732
  ui.start(`Creating thumbnails: ${galleryDir}`);
724
733
  try {
725
734
  fs8.mkdirSync(thumbnailsPath, { recursive: true });
726
735
  const galleryData = parseGalleryJson(galleryJsonPath, ui);
727
736
  const thumbnailSize = galleryData.thumbnailSize || DEFAULT_THUMBNAIL_SIZE;
728
- const mediaBasePath = galleryData.mediaBasePath ?? path7.join(galleryDir);
737
+ const mediaBasePath = galleryData.mediaBasePath ?? path.join(galleryDir);
729
738
  let processedCount = 0;
730
739
  for (const section of galleryData.sections) {
731
740
  for (const [index, mediaFile] of section.images.entries()) {
@@ -772,8 +781,8 @@ function copyPhotos(galleryData, galleryDir, ui) {
772
781
  for (const section of galleryData.sections) {
773
782
  for (const image of section.images) {
774
783
  if (galleryData.mediaBasePath) {
775
- const sourcePath = path7.join(galleryData.mediaBasePath, image.filename);
776
- const destPath = path7.join(galleryDir, image.filename);
784
+ const sourcePath = path.join(galleryData.mediaBasePath, image.filename);
785
+ const destPath = path.join(galleryDir, image.filename);
777
786
  ui.debug(`Copying photo to ${destPath}`);
778
787
  fs8.copyFileSync(sourcePath, destPath);
779
788
  }
@@ -812,17 +821,17 @@ async function scanAndAppendNewFiles(galleryDir, galleryJsonPath, galleryData, u
812
821
  }
813
822
  async function buildGallery(galleryDir, templateDir, scan, shouldCreateThumbnails, ui, baseUrl, thumbsBaseUrl) {
814
823
  ui.start(`Building gallery ${galleryDir}`);
815
- const galleryJsonPath = path7.join(galleryDir, "gallery", "gallery.json");
824
+ const galleryJsonPath = path.join(galleryDir, "gallery", "gallery.json");
816
825
  let galleryData = parseGalleryJson(galleryJsonPath, ui);
817
826
  if (scan) {
818
827
  galleryData = await scanAndAppendNewFiles(galleryDir, galleryJsonPath, galleryData, ui);
819
828
  }
820
- const socialMediaCardImagePath = path7.join(galleryDir, "gallery", "images", "social-media-card.jpg");
829
+ const socialMediaCardImagePath = path.join(galleryDir, "gallery", "images", "social-media-card.jpg");
821
830
  const mediaBasePath = galleryData.mediaBasePath;
822
831
  const mediaBaseUrl = baseUrl || galleryData.mediaBaseUrl;
823
- const headerImagePath = mediaBasePath ? path7.join(mediaBasePath, galleryData.headerImage) : path7.resolve(galleryDir, galleryData.headerImage);
824
- const imagesFolder = path7.join(galleryDir, "gallery", "images");
825
- const currentHeaderBasename = path7.basename(headerImagePath, path7.extname(headerImagePath));
832
+ const headerImagePath = mediaBasePath ? path.join(mediaBasePath, galleryData.headerImage) : path.resolve(galleryDir, galleryData.headerImage);
833
+ const imagesFolder = path.join(galleryDir, "gallery", "images");
834
+ const currentHeaderBasename = path.basename(headerImagePath, path.extname(headerImagePath));
826
835
  if (shouldCreateThumbnails) {
827
836
  if (!fs8.existsSync(imagesFolder)) {
828
837
  fs8.mkdirSync(imagesFolder, { recursive: true });
@@ -865,7 +874,7 @@ async function buildGallery(galleryDir, templateDir, scan, shouldCreateThumbnail
865
874
  }
866
875
  if (!galleryData.metadata.image) {
867
876
  ui.debug("Updating gallery.json with social media card URL");
868
- galleryData.metadata.image = thumbsBaseUrl ? `${thumbsBaseUrl}/${path7.basename(socialMediaCardImagePath)}` : `${galleryData.url || ""}/${path7.relative(galleryDir, socialMediaCardImagePath)}`;
877
+ galleryData.metadata.image = thumbsBaseUrl ? `${thumbsBaseUrl}/${path.basename(socialMediaCardImagePath)}` : `${galleryData.url || ""}/${path.relative(galleryDir, socialMediaCardImagePath)}`;
869
878
  fs8.writeFileSync(galleryJsonPath, JSON.stringify(galleryData, null, 2));
870
879
  }
871
880
  if (shouldCreateThumbnails) {
@@ -874,19 +883,19 @@ async function buildGallery(galleryDir, templateDir, scan, shouldCreateThumbnail
874
883
  ui.debug("Building gallery from template");
875
884
  try {
876
885
  process4.env.GALLERY_JSON_PATH = galleryJsonPath;
877
- process4.env.GALLERY_OUTPUT_DIR = path7.join(galleryDir, "gallery");
886
+ process4.env.GALLERY_OUTPUT_DIR = path.join(galleryDir, "gallery");
878
887
  execSync("npx astro build", { cwd: templateDir, stdio: ui.level === LogLevels.debug ? "inherit" : "ignore" });
879
888
  } catch (error) {
880
889
  ui.error(`Build failed for ${galleryDir}`);
881
890
  throw error;
882
891
  }
883
- const outputDir = path7.join(galleryDir, "gallery");
884
- const buildDir = path7.join(outputDir, "_build");
892
+ const outputDir = path.join(galleryDir, "gallery");
893
+ const buildDir = path.join(outputDir, "_build");
885
894
  ui.debug(`Copying build output to ${outputDir}`);
886
895
  fs8.cpSync(buildDir, outputDir, { recursive: true });
887
896
  ui.debug("Moving index.html to gallery directory");
888
- fs8.copyFileSync(path7.join(outputDir, "index.html"), path7.join(galleryDir, "index.html"));
889
- fs8.rmSync(path7.join(outputDir, "index.html"));
897
+ fs8.copyFileSync(path.join(outputDir, "index.html"), path.join(galleryDir, "index.html"));
898
+ fs8.rmSync(path.join(outputDir, "index.html"));
890
899
  ui.debug("Cleaning up build directory");
891
900
  fs8.rmSync(buildDir, { recursive: true, force: true });
892
901
  ui.success(`Gallery built successfully`);
@@ -899,12 +908,12 @@ async function build(options, ui) {
899
908
  return { processedGalleryCount: 0 };
900
909
  }
901
910
  const themePath = await import.meta.resolve("@simple-photo-gallery/theme-modern/package.json");
902
- const themeDir = path7.dirname(new URL(themePath).pathname);
911
+ const themeDir = path.dirname(new URL(themePath).pathname);
903
912
  let totalGalleries = 0;
904
913
  for (const dir of galleryDirs) {
905
- const baseUrl = options.baseUrl ? `${options.baseUrl}${path7.relative(options.gallery, dir)}` : void 0;
906
- const thumbsBaseUrl = options.thumbsBaseUrl ? `${options.thumbsBaseUrl}${path7.relative(options.gallery, dir)}` : void 0;
907
- await buildGallery(path7.resolve(dir), themeDir, options.scan, options.thumbnails, ui, baseUrl, thumbsBaseUrl);
914
+ const baseUrl = options.baseUrl ? `${options.baseUrl}${path.relative(options.gallery, dir)}` : void 0;
915
+ const thumbsBaseUrl = options.thumbsBaseUrl ? `${options.thumbsBaseUrl}${path.relative(options.gallery, dir)}` : void 0;
916
+ await buildGallery(path.resolve(dir), themeDir, options.scan, options.thumbnails, ui, baseUrl, thumbsBaseUrl);
908
917
  ++totalGalleries;
909
918
  }
910
919
  ui.box(`Built ${totalGalleries} ${totalGalleries === 1 ? "gallery" : "galleries"} successfully`);
@@ -920,7 +929,7 @@ async function build(options, ui) {
920
929
  }
921
930
  async function cleanGallery(galleryDir, ui) {
922
931
  let filesRemoved = 0;
923
- const indexHtmlPath = path7.join(galleryDir, "index.html");
932
+ const indexHtmlPath = path.join(galleryDir, "index.html");
924
933
  if (fs8.existsSync(indexHtmlPath)) {
925
934
  try {
926
935
  fs8.rmSync(indexHtmlPath);
@@ -930,7 +939,7 @@ async function cleanGallery(galleryDir, ui) {
930
939
  ui?.warn(`Failed to remove index.html: ${error}`);
931
940
  }
932
941
  }
933
- const galleryPath = path7.join(galleryDir, "gallery");
942
+ const galleryPath = path.join(galleryDir, "gallery");
934
943
  if (fs8.existsSync(galleryPath)) {
935
944
  try {
936
945
  fs8.rmSync(galleryPath, { recursive: true, force: true });
@@ -949,7 +958,7 @@ async function cleanGallery(galleryDir, ui) {
949
958
  }
950
959
  async function clean(options, ui) {
951
960
  try {
952
- const basePath = path7.resolve(options.gallery);
961
+ const basePath = path.resolve(options.gallery);
953
962
  if (!fs8.existsSync(basePath)) {
954
963
  ui.error(`Directory does not exist: ${basePath}`);
955
964
  return { processedGalleryCount: 0 };
@@ -1207,7 +1216,7 @@ async function waitForUpdateCheck(checkPromise) {
1207
1216
  // package.json
1208
1217
  var package_default = {
1209
1218
  name: "simple-photo-gallery",
1210
- version: "2.0.11"};
1219
+ version: "2.0.12"};
1211
1220
 
1212
1221
  // src/index.ts
1213
1222
  var program = new Command();