simple-photo-gallery 2.1.2 → 2.1.3

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.cjs CHANGED
@@ -5,7 +5,7 @@ var process4 = require('process');
5
5
  var commander = require('commander');
6
6
  var consola = require('consola');
7
7
  var child_process = require('child_process');
8
- var fs10 = require('fs');
8
+ var fs8 = require('fs');
9
9
  var path7 = require('path');
10
10
  var buffer = require('buffer');
11
11
  var sharp2 = require('sharp');
@@ -24,7 +24,7 @@ var _documentCurrentScript = typeof document !== 'undefined' ? document.currentS
24
24
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
25
25
 
26
26
  var process4__default = /*#__PURE__*/_interopDefault(process4);
27
- var fs10__default = /*#__PURE__*/_interopDefault(fs10);
27
+ var fs8__default = /*#__PURE__*/_interopDefault(fs8);
28
28
  var path7__default = /*#__PURE__*/_interopDefault(path7);
29
29
  var sharp2__default = /*#__PURE__*/_interopDefault(sharp2);
30
30
  var ExifReader__default = /*#__PURE__*/_interopDefault(ExifReader);
@@ -127,7 +127,7 @@ function wrapText(text, maxCharsPerLine) {
127
127
  async function createGallerySocialMediaCardImage(headerPhotoPath, title, ouputPath, ui) {
128
128
  ui?.start(`Creating social media card image`);
129
129
  const headerBasename = path7__default.default.basename(headerPhotoPath, path7__default.default.extname(headerPhotoPath));
130
- if (fs10__default.default.existsSync(ouputPath)) {
130
+ if (fs8__default.default.existsSync(ouputPath)) {
131
131
  ui?.success(`Social media card image already exists`);
132
132
  return headerBasename;
133
133
  }
@@ -186,7 +186,7 @@ async function createOptimizedHeaderImage(headerPhotoPath, outputFolder, ui) {
186
186
  ui?.debug(`Creating landscape header image ${width}`);
187
187
  const avifFilename = `${headerBasename}_landscape_${width}.avif`;
188
188
  const jpgFilename = `${headerBasename}_landscape_${width}.jpg`;
189
- if (fs10__default.default.existsSync(path7__default.default.join(outputFolder, avifFilename))) {
189
+ if (fs8__default.default.existsSync(path7__default.default.join(outputFolder, avifFilename))) {
190
190
  ui?.debug(`Landscape header image ${width} AVIF already exists`);
191
191
  } else {
192
192
  await cropAndResizeImage(
@@ -198,7 +198,7 @@ async function createOptimizedHeaderImage(headerPhotoPath, outputFolder, ui) {
198
198
  );
199
199
  }
200
200
  generatedFiles.push(avifFilename);
201
- if (fs10__default.default.existsSync(path7__default.default.join(outputFolder, jpgFilename))) {
201
+ if (fs8__default.default.existsSync(path7__default.default.join(outputFolder, jpgFilename))) {
202
202
  ui?.debug(`Landscape header image ${width} JPG already exists`);
203
203
  } else {
204
204
  await cropAndResizeImage(image.clone(), path7__default.default.join(outputFolder, jpgFilename), width, width * landscapeYFactor, "jpg");
@@ -210,13 +210,13 @@ async function createOptimizedHeaderImage(headerPhotoPath, outputFolder, ui) {
210
210
  ui?.debug(`Creating portrait header image ${width}`);
211
211
  const avifFilename = `${headerBasename}_portrait_${width}.avif`;
212
212
  const jpgFilename = `${headerBasename}_portrait_${width}.jpg`;
213
- if (fs10__default.default.existsSync(path7__default.default.join(outputFolder, avifFilename))) {
213
+ if (fs8__default.default.existsSync(path7__default.default.join(outputFolder, avifFilename))) {
214
214
  ui?.debug(`Portrait header image ${width} AVIF already exists`);
215
215
  } else {
216
216
  await cropAndResizeImage(image.clone(), path7__default.default.join(outputFolder, avifFilename), width, width * portraitYFactor, "avif");
217
217
  }
218
218
  generatedFiles.push(avifFilename);
219
- if (fs10__default.default.existsSync(path7__default.default.join(outputFolder, jpgFilename))) {
219
+ if (fs8__default.default.existsSync(path7__default.default.join(outputFolder, jpgFilename))) {
220
220
  ui?.debug(`Portrait header image ${width} JPG already exists`);
221
221
  } else {
222
222
  await cropAndResizeImage(image.clone(), path7__default.default.join(outputFolder, jpgFilename), width, width * portraitYFactor, "jpg");
@@ -227,10 +227,10 @@ async function createOptimizedHeaderImage(headerPhotoPath, outputFolder, ui) {
227
227
  return { headerBasename, generatedFiles, blurHash };
228
228
  }
229
229
  function hasOldHeaderImages(outputFolder, currentHeaderBasename) {
230
- if (!fs10__default.default.existsSync(outputFolder)) {
230
+ if (!fs8__default.default.existsSync(outputFolder)) {
231
231
  return false;
232
232
  }
233
- const files = fs10__default.default.readdirSync(outputFolder);
233
+ const files = fs8__default.default.readdirSync(outputFolder);
234
234
  for (const file of files) {
235
235
  const landscapeMatch = file.match(/^(.+)_landscape_\d+\.(avif|jpg)$/);
236
236
  const portraitMatch = file.match(/^(.+)_portrait_\d+\.(avif|jpg)$/);
@@ -242,11 +242,11 @@ function hasOldHeaderImages(outputFolder, currentHeaderBasename) {
242
242
  }
243
243
  function cleanupOldHeaderImages(outputFolder, currentHeaderBasename, ui) {
244
244
  ui?.start(`Cleaning up old header images`);
245
- if (!fs10__default.default.existsSync(outputFolder)) {
245
+ if (!fs8__default.default.existsSync(outputFolder)) {
246
246
  ui?.debug(`Output folder ${outputFolder} does not exist, skipping cleanup`);
247
247
  return;
248
248
  }
249
- const files = fs10__default.default.readdirSync(outputFolder);
249
+ const files = fs8__default.default.readdirSync(outputFolder);
250
250
  let deletedCount = 0;
251
251
  for (const file of files) {
252
252
  const landscapeMatch = file.match(/^(.+)_landscape_\d+\.(avif|jpg)$/);
@@ -254,12 +254,12 @@ function cleanupOldHeaderImages(outputFolder, currentHeaderBasename, ui) {
254
254
  if (landscapeMatch && landscapeMatch[1] !== currentHeaderBasename) {
255
255
  const filePath = path7__default.default.join(outputFolder, file);
256
256
  ui?.debug(`Deleting old landscape header image: ${file}`);
257
- fs10__default.default.unlinkSync(filePath);
257
+ fs8__default.default.unlinkSync(filePath);
258
258
  deletedCount++;
259
259
  } else if (portraitMatch && portraitMatch[1] !== currentHeaderBasename) {
260
260
  const filePath = path7__default.default.join(outputFolder, file);
261
261
  ui?.debug(`Deleting old portrait header image: ${file}`);
262
- fs10__default.default.unlinkSync(filePath);
262
+ fs8__default.default.unlinkSync(filePath);
263
263
  deletedCount++;
264
264
  }
265
265
  }
@@ -272,12 +272,12 @@ function cleanupOldHeaderImages(outputFolder, currentHeaderBasename, ui) {
272
272
  function findGalleries(basePath, recursive) {
273
273
  const galleryDirs = [];
274
274
  const galleryJsonPath = path7__default.default.join(basePath, "gallery", "gallery.json");
275
- if (fs10__default.default.existsSync(galleryJsonPath)) {
275
+ if (fs8__default.default.existsSync(galleryJsonPath)) {
276
276
  galleryDirs.push(basePath);
277
277
  }
278
278
  if (recursive) {
279
279
  try {
280
- const entries = fs10__default.default.readdirSync(basePath, { withFileTypes: true });
280
+ const entries = fs8__default.default.readdirSync(basePath, { withFileTypes: true });
281
281
  for (const entry of entries) {
282
282
  if (entry.isDirectory() && entry.name !== "gallery") {
283
283
  const subPath = path7__default.default.join(basePath, entry.name);
@@ -311,7 +311,7 @@ function parseTelemetryOption(value) {
311
311
  function parseGalleryJson(galleryJsonPath, ui) {
312
312
  let galleryContent;
313
313
  try {
314
- galleryContent = fs10__default.default.readFileSync(galleryJsonPath, "utf8");
314
+ galleryContent = fs8__default.default.readFileSync(galleryJsonPath, "utf8");
315
315
  } catch (error) {
316
316
  ui.error("Error parsing gallery.json: file not found");
317
317
  throw error;
@@ -361,9 +361,9 @@ function migrateGalleryJson(deprecatedGalleryData, galleryJsonPath, ui) {
361
361
  thumbnails: thumbnails2
362
362
  };
363
363
  ui.debug("Backing up old gallery.json file");
364
- fs10__default.default.copyFileSync(galleryJsonPath, `${galleryJsonPath}.old`);
364
+ fs8__default.default.copyFileSync(galleryJsonPath, `${galleryJsonPath}.old`);
365
365
  ui.debug("Writing gallery data to gallery.json file");
366
- fs10__default.default.writeFileSync(galleryJsonPath, JSON.stringify(galleryData, null, 2));
366
+ fs8__default.default.writeFileSync(galleryJsonPath, JSON.stringify(galleryData, null, 2));
367
367
  ui.success("Gallery data migrated to the new data format successfully.");
368
368
  return galleryData;
369
369
  }
@@ -382,7 +382,7 @@ async function scanDirectory(dirPath, ui) {
382
382
  const mediaFiles = [];
383
383
  const subGalleryDirectories = [];
384
384
  try {
385
- const entries = await fs10.promises.readdir(dirPath, { withFileTypes: true });
385
+ const entries = await fs8.promises.readdir(dirPath, { withFileTypes: true });
386
386
  for (const entry of entries) {
387
387
  if (entry.isFile()) {
388
388
  const mediaType = getMediaFileType(entry.name);
@@ -488,13 +488,13 @@ async function createGalleryJson(mediaFiles, galleryJsonPath, scanPath, subGalle
488
488
  ...otherSettings
489
489
  };
490
490
  }
491
- await fs10.promises.writeFile(galleryJsonPath, JSON.stringify(galleryData, null, 2));
491
+ await fs8.promises.writeFile(galleryJsonPath, JSON.stringify(galleryData, null, 2));
492
492
  }
493
493
  async function galleryExists(outputPath) {
494
494
  const galleryPath = path7__default.default.join(outputPath, "gallery");
495
495
  const galleryJsonPath = path7__default.default.join(galleryPath, "gallery.json");
496
496
  try {
497
- await fs10.promises.access(galleryJsonPath);
497
+ await fs8.promises.access(galleryJsonPath);
498
498
  return true;
499
499
  } catch {
500
500
  return false;
@@ -541,17 +541,8 @@ async function processDirectory(scanPath, outputPath, recursive, useDefaultSetti
541
541
  }
542
542
  }
543
543
  try {
544
- await fs10.promises.mkdir(galleryPath, { recursive: true });
545
- await createGalleryJson(
546
- mediaFiles,
547
- galleryJsonPath,
548
- scanPath,
549
- subGalleries,
550
- useDefaultSettings,
551
- ctaBanner,
552
- configOptions,
553
- ui
554
- );
544
+ await fs8.promises.mkdir(galleryPath, { recursive: true });
545
+ await createGalleryJson(mediaFiles, galleryJsonPath, scanPath, subGalleries, useDefaultSettings, ctaBanner, configOptions, ui);
555
546
  ui.success(
556
547
  `Create gallery with ${mediaFiles.length} files and ${subGalleries.length} subgalleries at: ${galleryJsonPath}`
557
548
  );
@@ -603,7 +594,7 @@ async function init(options, ui) {
603
594
  }
604
595
  }
605
596
  async function getFileMtime(filePath) {
606
- const stats = await fs10.promises.stat(filePath);
597
+ const stats = await fs8.promises.stat(filePath);
607
598
  return stats.mtime;
608
599
  }
609
600
  async function getImageDescription(image) {
@@ -678,7 +669,7 @@ async function createVideoThumbnails(inputPath, videoDimensions, outputPath, out
678
669
  await resizeImage(frameImage, outputPath, width, height);
679
670
  await resizeImage(frameImage, outputPathRetina, width * 2, height * 2);
680
671
  try {
681
- await fs10.promises.unlink(tempFramePath);
672
+ await fs8.promises.unlink(tempFramePath);
682
673
  } catch {
683
674
  }
684
675
  resolve({ width, height });
@@ -698,7 +689,7 @@ async function createVideoThumbnails(inputPath, videoDimensions, outputPath, out
698
689
  // src/modules/thumbnails/index.ts
699
690
  async function processImage(imagePath, thumbnailPath, thumbnailPathRetina, thumbnailSize, thumbnailSizeDimension = "auto", lastMediaTimestamp) {
700
691
  const fileMtime = await getFileMtime(imagePath);
701
- if (lastMediaTimestamp && fileMtime <= lastMediaTimestamp && fs10__default.default.existsSync(thumbnailPath)) {
692
+ if (lastMediaTimestamp && fileMtime <= lastMediaTimestamp && fs8__default.default.existsSync(thumbnailPath)) {
702
693
  return void 0;
703
694
  }
704
695
  const { image, metadata } = await loadImageWithMetadata(imagePath);
@@ -737,7 +728,7 @@ async function processImage(imagePath, thumbnailPath, thumbnailPathRetina, thumb
737
728
  }
738
729
  async function processVideo(videoPath, thumbnailPath, thumbnailPathRetina, thumbnailSize, thumbnailSizeDimension = "auto", verbose, lastMediaTimestamp) {
739
730
  const fileMtime = await getFileMtime(videoPath);
740
- if (lastMediaTimestamp && fileMtime <= lastMediaTimestamp && fs10__default.default.existsSync(thumbnailPath)) {
731
+ if (lastMediaTimestamp && fileMtime <= lastMediaTimestamp && fs8__default.default.existsSync(thumbnailPath)) {
741
732
  return void 0;
742
733
  }
743
734
  const videoDimensions = await getVideoDimensions(videoPath);
@@ -796,7 +787,7 @@ async function processMediaFile(mediaFile, mediaBasePath, thumbnailsPath, thumbn
796
787
  ));
797
788
  if (!updatedMediaFile) {
798
789
  ui.debug(` Skipping ${fileName} because it has already been processed`);
799
- if (mediaFile.thumbnail && !mediaFile.thumbnail.blurHash && fs10__default.default.existsSync(thumbnailPath)) {
790
+ if (mediaFile.thumbnail && !mediaFile.thumbnail.blurHash && fs8__default.default.existsSync(thumbnailPath)) {
800
791
  try {
801
792
  const blurHash = await generateBlurHash(thumbnailPath);
802
793
  return {
@@ -834,7 +825,7 @@ async function processGalleryThumbnails(galleryDir, ui, cliThumbnailConfig) {
834
825
  const thumbnailsPath = path7__default.default.join(galleryDir, "gallery", "images");
835
826
  ui.start(`Creating thumbnails: ${galleryDir}`);
836
827
  try {
837
- fs10__default.default.mkdirSync(thumbnailsPath, { recursive: true });
828
+ fs8__default.default.mkdirSync(thumbnailsPath, { recursive: true });
838
829
  const galleryData = parseGalleryJson(galleryJsonPath, ui);
839
830
  const galleryThumbnailConfig = theme.extractThumbnailConfigFromGallery(galleryData);
840
831
  let themeConfig;
@@ -856,7 +847,7 @@ async function processGalleryThumbnails(galleryDir, ui, cliThumbnailConfig) {
856
847
  }
857
848
  processedCount += section.images.length;
858
849
  }
859
- fs10__default.default.writeFileSync(galleryJsonPath, JSON.stringify(galleryData, null, 2));
850
+ fs8__default.default.writeFileSync(galleryJsonPath, JSON.stringify(galleryData, null, 2));
860
851
  ui.success(`Created thumbnails for ${processedCount} media files`);
861
852
  return processedCount;
862
853
  } catch (error) {
@@ -899,7 +890,7 @@ function copyPhotos(galleryData, galleryDir, ui) {
899
890
  const sourcePath = path7__default.default.join(galleryData.mediaBasePath, image.filename);
900
891
  const destPath = path7__default.default.join(galleryDir, image.filename);
901
892
  ui.debug(`Copying photo to ${destPath}`);
902
- fs10__default.default.copyFileSync(sourcePath, destPath);
893
+ fs8__default.default.copyFileSync(sourcePath, destPath);
903
894
  }
904
895
  }
905
896
  }
@@ -927,7 +918,7 @@ async function scanAndAppendNewFiles(galleryDir, galleryJsonPath, galleryData, u
927
918
  const lastSection = galleryData.sections[lastSectionIndex];
928
919
  lastSection.images.push(...newMediaFiles);
929
920
  ui.debug("Updating gallery.json with new files");
930
- fs10__default.default.writeFileSync(galleryJsonPath, JSON.stringify(galleryData, null, 2));
921
+ fs8__default.default.writeFileSync(galleryJsonPath, JSON.stringify(galleryData, null, 2));
931
922
  ui.success(`Added ${newMediaFiles.length} new ${newMediaFiles.length === 1 ? "file" : "files"} to gallery.json`);
932
923
  } else {
933
924
  ui.debug("No new media files found");
@@ -948,15 +939,15 @@ async function buildGallery(galleryDir, templateDir, scan, shouldCreateThumbnail
948
939
  const imagesFolder = path7__default.default.join(galleryDir, "gallery", "images");
949
940
  const currentHeaderBasename = path7__default.default.basename(headerImagePath, path7__default.default.extname(headerImagePath));
950
941
  if (shouldCreateThumbnails) {
951
- if (!fs10__default.default.existsSync(imagesFolder)) {
952
- fs10__default.default.mkdirSync(imagesFolder, { recursive: true });
942
+ if (!fs8__default.default.existsSync(imagesFolder)) {
943
+ fs8__default.default.mkdirSync(imagesFolder, { recursive: true });
953
944
  }
954
945
  const headerImageChanged = hasOldHeaderImages(imagesFolder, currentHeaderBasename);
955
946
  if (headerImageChanged) {
956
947
  ui.info("Header image changed, cleaning up old assets");
957
948
  cleanupOldHeaderImages(imagesFolder, currentHeaderBasename, ui);
958
- if (fs10__default.default.existsSync(socialMediaCardImagePath)) {
959
- fs10__default.default.unlinkSync(socialMediaCardImagePath);
949
+ if (fs8__default.default.existsSync(socialMediaCardImagePath)) {
950
+ fs8__default.default.unlinkSync(socialMediaCardImagePath);
960
951
  ui.debug("Deleted old social media card");
961
952
  }
962
953
  }
@@ -965,7 +956,7 @@ async function buildGallery(galleryDir, templateDir, scan, shouldCreateThumbnail
965
956
  if (galleryData.headerImageBlurHash !== blurHash) {
966
957
  ui.debug("Updating gallery.json with header image blurhash");
967
958
  galleryData.headerImageBlurHash = blurHash;
968
- fs10__default.default.writeFileSync(galleryJsonPath, JSON.stringify(galleryData, null, 2));
959
+ fs8__default.default.writeFileSync(galleryJsonPath, JSON.stringify(galleryData, null, 2));
969
960
  }
970
961
  }
971
962
  if (!mediaBaseUrl && mediaBasePath) {
@@ -980,17 +971,17 @@ async function buildGallery(galleryDir, templateDir, scan, shouldCreateThumbnail
980
971
  if (mediaBaseUrl && galleryData.mediaBaseUrl !== mediaBaseUrl) {
981
972
  ui.debug("Updating gallery.json with baseUrl");
982
973
  galleryData.mediaBaseUrl = mediaBaseUrl;
983
- fs10__default.default.writeFileSync(galleryJsonPath, JSON.stringify(galleryData, null, 2));
974
+ fs8__default.default.writeFileSync(galleryJsonPath, JSON.stringify(galleryData, null, 2));
984
975
  }
985
976
  if (thumbsBaseUrl && galleryData.thumbsBaseUrl !== thumbsBaseUrl) {
986
977
  ui.debug("Updating gallery.json with thumbsBaseUrl");
987
978
  galleryData.thumbsBaseUrl = thumbsBaseUrl;
988
- fs10__default.default.writeFileSync(galleryJsonPath, JSON.stringify(galleryData, null, 2));
979
+ fs8__default.default.writeFileSync(galleryJsonPath, JSON.stringify(galleryData, null, 2));
989
980
  }
990
981
  if (cliTheme && galleryData.theme !== cliTheme) {
991
982
  ui.debug("Updating gallery.json with theme");
992
983
  galleryData.theme = cliTheme;
993
- fs10__default.default.writeFileSync(galleryJsonPath, JSON.stringify(galleryData, null, 2));
984
+ fs8__default.default.writeFileSync(galleryJsonPath, JSON.stringify(galleryData, null, 2));
994
985
  }
995
986
  if (cliThumbnailConfig) {
996
987
  const needsUpdate = cliThumbnailConfig.size !== void 0 && galleryData.thumbnails?.size !== cliThumbnailConfig.size || cliThumbnailConfig.edge !== void 0 && galleryData.thumbnails?.edge !== cliThumbnailConfig.edge;
@@ -1001,13 +992,13 @@ async function buildGallery(galleryDir, templateDir, scan, shouldCreateThumbnail
1001
992
  ...cliThumbnailConfig.size !== void 0 && { size: cliThumbnailConfig.size },
1002
993
  ...cliThumbnailConfig.edge !== void 0 && { edge: cliThumbnailConfig.edge }
1003
994
  };
1004
- fs10__default.default.writeFileSync(galleryJsonPath, JSON.stringify(galleryData, null, 2));
995
+ fs8__default.default.writeFileSync(galleryJsonPath, JSON.stringify(galleryData, null, 2));
1005
996
  }
1006
997
  }
1007
998
  if (!galleryData.metadata.image) {
1008
999
  ui.debug("Updating gallery.json with social media card URL");
1009
1000
  galleryData.metadata.image = thumbsBaseUrl ? `${thumbsBaseUrl}/${path7__default.default.basename(socialMediaCardImagePath)}` : `${galleryData.url || ""}/${path7__default.default.relative(galleryDir, socialMediaCardImagePath)}`;
1010
- fs10__default.default.writeFileSync(galleryJsonPath, JSON.stringify(galleryData, null, 2));
1001
+ fs8__default.default.writeFileSync(galleryJsonPath, JSON.stringify(galleryData, null, 2));
1011
1002
  }
1012
1003
  if (shouldCreateThumbnails) {
1013
1004
  await processGalleryThumbnails(galleryDir, ui, cliThumbnailConfig);
@@ -1024,12 +1015,12 @@ async function buildGallery(galleryDir, templateDir, scan, shouldCreateThumbnail
1024
1015
  const outputDir = path7__default.default.join(galleryDir, "gallery");
1025
1016
  const buildDir = path7__default.default.join(outputDir, "_build");
1026
1017
  ui.debug(`Copying build output to ${outputDir}`);
1027
- fs10__default.default.cpSync(buildDir, outputDir, { recursive: true });
1018
+ fs8__default.default.cpSync(buildDir, outputDir, { recursive: true });
1028
1019
  ui.debug("Moving index.html to gallery directory");
1029
- fs10__default.default.copyFileSync(path7__default.default.join(outputDir, "index.html"), path7__default.default.join(galleryDir, "index.html"));
1030
- fs10__default.default.rmSync(path7__default.default.join(outputDir, "index.html"));
1020
+ fs8__default.default.copyFileSync(path7__default.default.join(outputDir, "index.html"), path7__default.default.join(galleryDir, "index.html"));
1021
+ fs8__default.default.rmSync(path7__default.default.join(outputDir, "index.html"));
1031
1022
  ui.debug("Cleaning up build directory");
1032
- fs10__default.default.rmSync(buildDir, { recursive: true, force: true });
1023
+ fs8__default.default.rmSync(buildDir, { recursive: true, force: true });
1033
1024
  ui.success(`Gallery built successfully`);
1034
1025
  }
1035
1026
  function isLocalThemePath(theme) {
@@ -1039,7 +1030,7 @@ async function resolveThemeDir(theme, ui) {
1039
1030
  if (isLocalThemePath(theme)) {
1040
1031
  const themeDir = path7__default.default.resolve(theme);
1041
1032
  const packageJsonPath = path7__default.default.join(themeDir, "package.json");
1042
- if (!fs10__default.default.existsSync(packageJsonPath)) {
1033
+ if (!fs8__default.default.existsSync(packageJsonPath)) {
1043
1034
  throw new Error(`Theme directory not found or invalid: ${themeDir}. package.json not found.`);
1044
1035
  }
1045
1036
  ui.debug(`Using local theme: ${themeDir}`);
@@ -1067,17 +1058,7 @@ async function build(options, ui) {
1067
1058
  const themeDir = await resolveThemeDir(themeIdentifier, ui);
1068
1059
  const baseUrl = options.baseUrl ? `${options.baseUrl}${path7__default.default.relative(options.gallery, dir)}` : void 0;
1069
1060
  const thumbsBaseUrl = options.thumbsBaseUrl ? `${options.thumbsBaseUrl}${path7__default.default.relative(options.gallery, dir)}` : void 0;
1070
- await buildGallery(
1071
- path7__default.default.resolve(dir),
1072
- themeDir,
1073
- options.scan,
1074
- options.thumbnails,
1075
- ui,
1076
- baseUrl,
1077
- thumbsBaseUrl,
1078
- cliThumbnailConfig,
1079
- options.theme
1080
- );
1061
+ await buildGallery(path7__default.default.resolve(dir), themeDir, options.scan, options.thumbnails, ui, baseUrl, thumbsBaseUrl, cliThumbnailConfig, options.theme);
1081
1062
  ++totalGalleries;
1082
1063
  }
1083
1064
  ui.box(`Built ${totalGalleries} ${totalGalleries === 1 ? "gallery" : "galleries"} successfully`);
@@ -1102,9 +1083,9 @@ async function build(options, ui) {
1102
1083
  async function cleanGallery(galleryDir, ui) {
1103
1084
  let filesRemoved = 0;
1104
1085
  const indexHtmlPath = path7__default.default.join(galleryDir, "index.html");
1105
- if (fs10__default.default.existsSync(indexHtmlPath)) {
1086
+ if (fs8__default.default.existsSync(indexHtmlPath)) {
1106
1087
  try {
1107
- fs10__default.default.rmSync(indexHtmlPath);
1088
+ fs8__default.default.rmSync(indexHtmlPath);
1108
1089
  ui?.debug(`Removed: ${indexHtmlPath}`);
1109
1090
  filesRemoved++;
1110
1091
  } catch (error) {
@@ -1112,9 +1093,9 @@ async function cleanGallery(galleryDir, ui) {
1112
1093
  }
1113
1094
  }
1114
1095
  const galleryPath = path7__default.default.join(galleryDir, "gallery");
1115
- if (fs10__default.default.existsSync(galleryPath)) {
1096
+ if (fs8__default.default.existsSync(galleryPath)) {
1116
1097
  try {
1117
- fs10__default.default.rmSync(galleryPath, { recursive: true, force: true });
1098
+ fs8__default.default.rmSync(galleryPath, { recursive: true, force: true });
1118
1099
  ui?.debug(`Removed directory: ${galleryPath}`);
1119
1100
  filesRemoved++;
1120
1101
  } catch (error) {
@@ -1131,7 +1112,7 @@ async function cleanGallery(galleryDir, ui) {
1131
1112
  async function clean(options, ui) {
1132
1113
  try {
1133
1114
  const basePath = path7__default.default.resolve(options.gallery);
1134
- if (!fs10__default.default.existsSync(basePath)) {
1115
+ if (!fs8__default.default.existsSync(basePath)) {
1135
1116
  ui.error(`Directory does not exist: ${basePath}`);
1136
1117
  return { processedGalleryCount: 0 };
1137
1118
  }
@@ -1154,9 +1135,9 @@ function findMonorepoRoot(startDir) {
1154
1135
  let dir = path7__default.default.resolve(startDir);
1155
1136
  while (true) {
1156
1137
  const pkgPath = path7__default.default.join(dir, "package.json");
1157
- if (fs10__default.default.existsSync(pkgPath)) {
1138
+ if (fs8__default.default.existsSync(pkgPath)) {
1158
1139
  try {
1159
- const pkg = JSON.parse(fs10__default.default.readFileSync(pkgPath, "utf8"));
1140
+ const pkg = JSON.parse(fs8__default.default.readFileSync(pkgPath, "utf8"));
1160
1141
  if (pkg && typeof pkg === "object" && "workspaces" in pkg) {
1161
1142
  return dir;
1162
1143
  }
@@ -1181,7 +1162,7 @@ function validateThemeName(name) {
1181
1162
  }
1182
1163
  async function ensureDirectory(dirPath, ui) {
1183
1164
  try {
1184
- await fs10__default.default.promises.mkdir(dirPath, { recursive: true });
1165
+ await fs8__default.default.promises.mkdir(dirPath, { recursive: true });
1185
1166
  ui.debug(`Created directory: ${dirPath}`);
1186
1167
  } catch (error) {
1187
1168
  if (error instanceof Error && "code" in error && error.code !== "EEXIST") {
@@ -1204,8 +1185,8 @@ function shouldExclude(name) {
1204
1185
  });
1205
1186
  }
1206
1187
  async function copyDirectory(src, dest, ui) {
1207
- await fs10__default.default.promises.mkdir(dest, { recursive: true });
1208
- const entries = await fs10__default.default.promises.readdir(src, { withFileTypes: true });
1188
+ await fs8__default.default.promises.mkdir(dest, { recursive: true });
1189
+ const entries = await fs8__default.default.promises.readdir(src, { withFileTypes: true });
1209
1190
  for (const entry of entries) {
1210
1191
  if (shouldExclude(entry.name)) {
1211
1192
  ui.debug(`Skipping excluded file/directory: ${entry.name}`);
@@ -1216,80 +1197,50 @@ async function copyDirectory(src, dest, ui) {
1216
1197
  if (entry.isDirectory()) {
1217
1198
  await copyDirectory(srcPath, destPath, ui);
1218
1199
  } else {
1219
- await fs10__default.default.promises.copyFile(srcPath, destPath);
1200
+ await fs8__default.default.promises.copyFile(srcPath, destPath);
1220
1201
  ui.debug(`Copied file: ${destPath}`);
1221
1202
  }
1222
1203
  }
1223
1204
  }
1224
- var PACKAGE_NAME = "simple-photo-gallery";
1225
- function findPackageRoot(startDir) {
1226
- let dir = path7__default.default.resolve(startDir);
1227
- while (true) {
1228
- const pkgPath = path7__default.default.join(dir, "package.json");
1229
- if (fs10__default.default.existsSync(pkgPath)) {
1230
- try {
1231
- const pkg = JSON.parse(fs10__default.default.readFileSync(pkgPath, "utf8"));
1232
- if (pkg?.name === PACKAGE_NAME) {
1233
- return dir;
1234
- }
1235
- } catch {
1236
- }
1237
- }
1238
- const parent = path7__default.default.dirname(dir);
1239
- if (parent === dir) {
1240
- return void 0;
1241
- }
1242
- dir = parent;
1243
- }
1244
- }
1245
1205
  function findBaseThemePath() {
1246
1206
  const moduleDir = path7__default.default.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href))));
1247
- const distTemplatesPath = path7__default.default.join(moduleDir, "base");
1248
- if (fs10__default.default.existsSync(distTemplatesPath)) {
1249
- return distTemplatesPath;
1250
- }
1251
- const packageRoot = findPackageRoot(moduleDir);
1252
- if (packageRoot) {
1253
- const srcTemplatesPath = path7__default.default.join(packageRoot, "src/modules/create-theme/templates/base");
1254
- if (fs10__default.default.existsSync(srcTemplatesPath)) {
1255
- return srcTemplatesPath;
1256
- }
1207
+ const bundledTemplatePath = path7__default.default.resolve(moduleDir, "../../../src/modules/create-theme/templates/base");
1208
+ if (fs8__default.default.existsSync(bundledTemplatePath)) {
1209
+ return bundledTemplatePath;
1257
1210
  }
1258
1211
  const monorepoRoot = findMonorepoRoot(process4__default.default.cwd());
1259
1212
  const workspaceRoot = monorepoRoot ?? process4__default.default.cwd();
1260
1213
  const workspaceBaseThemePath = path7__default.default.join(workspaceRoot, "themes", "base");
1261
- if (fs10__default.default.existsSync(workspaceBaseThemePath)) {
1214
+ if (fs8__default.default.existsSync(workspaceBaseThemePath)) {
1262
1215
  return workspaceBaseThemePath;
1263
1216
  }
1264
- const srcPath = packageRoot ? path7__default.default.join(packageRoot, "src/modules/create-theme/templates/base") : "N/A";
1265
1217
  throw new Error(
1266
1218
  `Base theme template not found. Tried:
1267
- - ${distTemplatesPath}
1268
- - ${srcPath}
1219
+ - ${bundledTemplatePath}
1269
1220
  - ${workspaceBaseThemePath}
1270
1221
 
1271
- Please ensure the package is built (templates are copied to dist) or themes/base exists in the workspace.`
1222
+ Please ensure the templates are included in the package or themes/base exists in the workspace.`
1272
1223
  );
1273
1224
  }
1274
1225
  async function updatePackageJson(themeDir, themeName, ui) {
1275
1226
  const packageJsonPath = path7__default.default.join(themeDir, "package.json");
1276
- const packageJsonContent = await fs10__default.default.promises.readFile(packageJsonPath, "utf8");
1227
+ const packageJsonContent = await fs8__default.default.promises.readFile(packageJsonPath, "utf8");
1277
1228
  const packageJson = JSON.parse(packageJsonContent);
1278
1229
  packageJson.name = themeName;
1279
- await fs10__default.default.promises.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2) + "\n", "utf8");
1230
+ await fs8__default.default.promises.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2) + "\n", "utf8");
1280
1231
  ui.debug(`Updated package.json with theme name: ${themeName}`);
1281
1232
  }
1282
1233
  async function createReadmeFromBase(baseThemePath, themeDir, themeName, ui) {
1283
1234
  const readmeBasePath = path7__default.default.join(baseThemePath, "README_BASE.md");
1284
1235
  const readmePath = path7__default.default.join(themeDir, "README.md");
1285
- if (!fs10__default.default.existsSync(readmeBasePath)) {
1236
+ if (!fs8__default.default.existsSync(readmeBasePath)) {
1286
1237
  throw new Error(`README_BASE.md not found in template: ${readmeBasePath}`);
1287
1238
  }
1288
- let readme = await fs10__default.default.promises.readFile(readmeBasePath, "utf8");
1239
+ let readme = await fs8__default.default.promises.readFile(readmeBasePath, "utf8");
1289
1240
  const displayName = themeName.split("-").filter(Boolean).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
1290
1241
  readme = readme.replaceAll("{THEME_NAME}", displayName);
1291
1242
  readme = readme.replaceAll("{THEME_NAME_LOWER}", displayName.toLowerCase());
1292
- await fs10__default.default.promises.writeFile(readmePath, readme, "utf8");
1243
+ await fs8__default.default.promises.writeFile(readmePath, readme, "utf8");
1293
1244
  ui.debug(`Created README.md from README_BASE.md for theme: ${themeName}`);
1294
1245
  }
1295
1246
  async function createTheme(options, ui) {
@@ -1303,11 +1254,11 @@ async function createTheme(options, ui) {
1303
1254
  const baseDir = monorepoRoot ?? process4__default.default.cwd();
1304
1255
  const themesBaseDir = path7__default.default.resolve(baseDir, "themes");
1305
1256
  themeDir = path7__default.default.join(themesBaseDir, options.name);
1306
- if (!fs10__default.default.existsSync(themesBaseDir)) {
1257
+ if (!fs8__default.default.existsSync(themesBaseDir)) {
1307
1258
  await ensureDirectory(themesBaseDir, ui);
1308
1259
  }
1309
1260
  }
1310
- if (fs10__default.default.existsSync(themeDir)) {
1261
+ if (fs8__default.default.existsSync(themeDir)) {
1311
1262
  throw new Error(`Theme directory already exists: ${themeDir}. Cannot overwrite existing theme.`);
1312
1263
  }
1313
1264
  ui.start(`Creating theme: ${options.name}`);
@@ -1574,7 +1525,7 @@ async function waitForUpdateCheck(checkPromise) {
1574
1525
  // package.json
1575
1526
  var package_default = {
1576
1527
  name: "simple-photo-gallery",
1577
- version: "2.1.2"};
1528
+ version: "2.0.18"};
1578
1529
 
1579
1530
  // src/index.ts
1580
1531
  var program = new commander.Command();
@@ -1642,12 +1593,12 @@ program.command("init").description("Initialize a gallery by scaning a folder fo
1642
1593
  ).option(
1643
1594
  "-g, --gallery <path>",
1644
1595
  "Path to the directory where the gallery will be initialized. Default: same directory as the photos folder"
1645
- ).option("-r, --recursive", "Recursively create galleries from all photos subdirectories", false).option("-d, --default", "Use default gallery settings instead of asking the user", false).option("-f, --force", "Force override existing galleries without asking", false).option("--cta-banner", "Add a Simple Photo Gallery call-to-action banner to the end of the gallery", false).option("--theme <package|path>", "Theme package name or local path to store in gallery.json").option("--thumbnail-size <pixels>", "Thumbnail size in pixels to store in gallery.json", Number.parseInt).option("--thumbnail-edge <mode>", "How thumbnail size is applied: auto, width, or height").action(withCommandContext((options, ui) => init(options, ui)));
1646
- program.command("thumbnails").description("Create thumbnails for all media files in the gallery").option("-g, --gallery <path>", "Path to the directory of the gallery. Default: current working directory", process4__default.default.cwd()).option("-r, --recursive", "Scan subdirectories recursively", false).option("--thumbnail-size <pixels>", "Override thumbnail size in pixels", Number.parseInt).option("--thumbnail-edge <mode>", "Override how thumbnail size is applied: auto, width, or height").action(withCommandContext((options, ui) => thumbnails(options, ui)));
1596
+ ).option("-r, --recursive", "Recursively create galleries from all photos subdirectories", false).option("-d, --default", "Use default gallery settings instead of asking the user", false).option("-f, --force", "Force override existing galleries without asking", false).option("--cta-banner", "Add a Simple Photo Gallery call-to-action banner to the end of the gallery", false).option("--theme <package|path>", "Theme package name or local path to store in gallery.json").option("--thumbnail-size <pixels>", "Thumbnail size in pixels to store in gallery.json", parseInt).option("--thumbnail-edge <mode>", "How thumbnail size is applied: auto, width, or height").action(withCommandContext((options, ui) => init(options, ui)));
1597
+ program.command("thumbnails").description("Create thumbnails for all media files in the gallery").option("-g, --gallery <path>", "Path to the directory of the gallery. Default: current working directory", process4__default.default.cwd()).option("-r, --recursive", "Scan subdirectories recursively", false).option("--thumbnail-size <pixels>", "Override thumbnail size in pixels", parseInt).option("--thumbnail-edge <mode>", "Override how thumbnail size is applied: auto, width, or height").action(withCommandContext((options, ui) => thumbnails(options, ui)));
1647
1598
  program.command("build").description("Build the HTML gallery in the specified directory").option("-g, --gallery <path>", "Path to the directory of the gallery. Default: current working directory", process4__default.default.cwd()).option("-r, --recursive", "Scan subdirectories recursively", false).option("-b, --base-url <url>", "Base URL where the photos are hosted").option("-t, --thumbs-base-url <url>", "Base URL where the thumbnails are hosted").option("--no-thumbnails", "Skip creating thumbnails when building the gallery", true).option("--no-scan", "Do not scan for new photos when building the gallery", true).option(
1648
1599
  "--theme <package|path>",
1649
1600
  "Theme package name (e.g., @simple-photo-gallery/theme-modern) or local path (e.g., ./themes/my-theme)"
1650
- ).option("--thumbnail-size <pixels>", "Override thumbnail size in pixels", Number.parseInt).option("--thumbnail-edge <mode>", "Override how thumbnail size is applied: auto, width, or height").action(withCommandContext((options, ui) => build(options, ui)));
1601
+ ).option("--thumbnail-size <pixels>", "Override thumbnail size in pixels", parseInt).option("--thumbnail-edge <mode>", "Override how thumbnail size is applied: auto, width, or height").action(withCommandContext((options, ui) => build(options, ui)));
1651
1602
  program.command("clean").description("Remove all gallery files and folders (index.html, gallery/)").option("-g, --gallery <path>", "Path to the directory of the gallery. Default: current working directory", process4__default.default.cwd()).option("-r, --recursive", "Clean subdirectories recursively", false).action(withCommandContext((options, ui) => clean(options, ui)));
1652
1603
  program.command("create-theme").description("Create a new theme template").argument("<name>", "Name of the theme to create").option("-p, --path <path>", "Path where the theme should be created. Default: ./themes/<name>").action(async (name, options, command) => {
1653
1604
  const handler = withCommandContext((opts, ui) => createTheme({ name, path: opts.path }, ui));