simple-photo-gallery 2.0.14-rc.1 → 2.0.15

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
@@ -1,12 +1,11 @@
1
1
  #!/usr/bin/env node
2
- import process4, { stdout } from 'process';
2
+ import process3, { stdout } from 'process';
3
3
  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 path from 'path';
7
+ import path7 from 'path';
8
8
  import { Buffer } from 'buffer';
9
- import { fileURLToPath } from 'url';
10
9
  import sharp2 from 'sharp';
11
10
  import { encode } from 'blurhash';
12
11
  import { GalleryDataSchema, GalleryDataDeprecatedSchema } from '@simple-photo-gallery/common';
@@ -77,44 +76,9 @@ async function generateBlurHash(imagePath, componentX = 4, componentY = 3) {
77
76
  }
78
77
 
79
78
  // src/modules/build/utils/index.ts
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
- var socialCardFontBase64;
83
- function resolveFromCurrentDir(...segments) {
84
- return path.resolve(__dirname, ...segments);
85
- }
86
- function findSocialCardFontPath() {
87
- const fontCandidates = [
88
- resolveFromCurrentDir("../../../../", 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),
93
- path.resolve(process4.cwd(), "../simple-photo-gallery/", SOCIAL_CARD_FONT_RELATIVE_PATH)
94
- ];
95
- for (const candidate of fontCandidates) {
96
- if (fs8.existsSync(candidate)) {
97
- return candidate;
98
- }
99
- }
100
- return null;
101
- }
102
- function getSocialCardFontBase64() {
103
- if (socialCardFontBase64 !== void 0) {
104
- return socialCardFontBase64;
105
- }
106
- const fontPath = findSocialCardFontPath();
107
- console.log("DBG:", { fontPath, dirname: __dirname, cwd: process4.cwd() });
108
- if (!fontPath) {
109
- socialCardFontBase64 = null;
110
- return null;
111
- }
112
- socialCardFontBase64 = fs8.readFileSync(fontPath).toString("base64");
113
- return socialCardFontBase64;
114
- }
115
79
  async function createGallerySocialMediaCardImage(headerPhotoPath, title, ouputPath, ui) {
116
80
  ui?.start(`Creating social media card image`);
117
- const headerBasename = path.basename(headerPhotoPath, path.extname(headerPhotoPath));
81
+ const headerBasename = path7.basename(headerPhotoPath, path7.extname(headerPhotoPath));
118
82
  if (fs8.existsSync(ouputPath)) {
119
83
  ui?.success(`Social media card image already exists`);
120
84
  return headerBasename;
@@ -123,21 +87,11 @@ async function createGallerySocialMediaCardImage(headerPhotoPath, title, ouputPa
123
87
  const resizedImageBuffer = await image.resize(1200, 631, { fit: "cover" }).jpeg({ quality: 90 }).toBuffer();
124
88
  const outputPath = ouputPath;
125
89
  await sharp2(resizedImageBuffer).toFile(outputPath);
126
- const fontBase64 = getSocialCardFontBase64();
127
- const fontFace = fontBase64 ? `
128
- @font-face {
129
- font-family: 'DejaVu Sans';
130
- src: url('data:font/ttf;base64,${fontBase64}') format('truetype');
131
- font-weight: 700;
132
- font-style: normal;
133
- }` : "";
134
- const fontFamily = fontBase64 ? "'DejaVu Sans', Arial, sans-serif" : "Arial, sans-serif";
135
90
  const svgText = `
136
91
  <svg width="1200" height="631" xmlns="http://www.w3.org/2000/svg">
137
92
  <defs>
138
93
  <style>
139
- ${fontFace}
140
- .title { font-family: ${fontFamily}; font-size: 96px; font-weight: bold; fill: white; stroke: black; stroke-width: 5; paint-order: stroke; text-anchor: middle; }
94
+ .title { font-family: 'Arial, sans-serif'; font-size: 96px; font-weight: bold; fill: white; stroke: black; stroke-width: 5; paint-order: stroke; text-anchor: middle; }
141
95
  </style>
142
96
  </defs>
143
97
  <text x="600" y="250" class="title">${title}</text>
@@ -151,7 +105,7 @@ async function createGallerySocialMediaCardImage(headerPhotoPath, title, ouputPa
151
105
  async function createOptimizedHeaderImage(headerPhotoPath, outputFolder, ui) {
152
106
  ui?.start(`Creating optimized header images`);
153
107
  const image = await loadImage(headerPhotoPath);
154
- const headerBasename = path.basename(headerPhotoPath, path.extname(headerPhotoPath));
108
+ const headerBasename = path7.basename(headerPhotoPath, path7.extname(headerPhotoPath));
155
109
  const generatedFiles = [];
156
110
  ui?.debug("Generating blurhash for header image");
157
111
  const blurHash = await generateBlurHash(headerPhotoPath);
@@ -160,22 +114,22 @@ async function createOptimizedHeaderImage(headerPhotoPath, outputFolder, ui) {
160
114
  ui?.debug(`Creating landscape header image ${width}`);
161
115
  const avifFilename = `${headerBasename}_landscape_${width}.avif`;
162
116
  const jpgFilename = `${headerBasename}_landscape_${width}.jpg`;
163
- if (fs8.existsSync(path.join(outputFolder, avifFilename))) {
117
+ if (fs8.existsSync(path7.join(outputFolder, avifFilename))) {
164
118
  ui?.debug(`Landscape header image ${width} AVIF already exists`);
165
119
  } else {
166
120
  await cropAndResizeImage(
167
121
  image.clone(),
168
- path.join(outputFolder, avifFilename),
122
+ path7.join(outputFolder, avifFilename),
169
123
  width,
170
124
  width * landscapeYFactor,
171
125
  "avif"
172
126
  );
173
127
  }
174
128
  generatedFiles.push(avifFilename);
175
- if (fs8.existsSync(path.join(outputFolder, jpgFilename))) {
129
+ if (fs8.existsSync(path7.join(outputFolder, jpgFilename))) {
176
130
  ui?.debug(`Landscape header image ${width} JPG already exists`);
177
131
  } else {
178
- await cropAndResizeImage(image.clone(), path.join(outputFolder, jpgFilename), width, width * landscapeYFactor, "jpg");
132
+ await cropAndResizeImage(image.clone(), path7.join(outputFolder, jpgFilename), width, width * landscapeYFactor, "jpg");
179
133
  }
180
134
  generatedFiles.push(jpgFilename);
181
135
  }
@@ -184,16 +138,16 @@ async function createOptimizedHeaderImage(headerPhotoPath, outputFolder, ui) {
184
138
  ui?.debug(`Creating portrait header image ${width}`);
185
139
  const avifFilename = `${headerBasename}_portrait_${width}.avif`;
186
140
  const jpgFilename = `${headerBasename}_portrait_${width}.jpg`;
187
- if (fs8.existsSync(path.join(outputFolder, avifFilename))) {
141
+ if (fs8.existsSync(path7.join(outputFolder, avifFilename))) {
188
142
  ui?.debug(`Portrait header image ${width} AVIF already exists`);
189
143
  } else {
190
- await cropAndResizeImage(image.clone(), path.join(outputFolder, avifFilename), width, width * portraitYFactor, "avif");
144
+ await cropAndResizeImage(image.clone(), path7.join(outputFolder, avifFilename), width, width * portraitYFactor, "avif");
191
145
  }
192
146
  generatedFiles.push(avifFilename);
193
- if (fs8.existsSync(path.join(outputFolder, jpgFilename))) {
147
+ if (fs8.existsSync(path7.join(outputFolder, jpgFilename))) {
194
148
  ui?.debug(`Portrait header image ${width} JPG already exists`);
195
149
  } else {
196
- await cropAndResizeImage(image.clone(), path.join(outputFolder, jpgFilename), width, width * portraitYFactor, "jpg");
150
+ await cropAndResizeImage(image.clone(), path7.join(outputFolder, jpgFilename), width, width * portraitYFactor, "jpg");
197
151
  }
198
152
  generatedFiles.push(jpgFilename);
199
153
  }
@@ -226,12 +180,12 @@ function cleanupOldHeaderImages(outputFolder, currentHeaderBasename, ui) {
226
180
  const landscapeMatch = file.match(/^(.+)_landscape_\d+\.(avif|jpg)$/);
227
181
  const portraitMatch = file.match(/^(.+)_portrait_\d+\.(avif|jpg)$/);
228
182
  if (landscapeMatch && landscapeMatch[1] !== currentHeaderBasename) {
229
- const filePath = path.join(outputFolder, file);
183
+ const filePath = path7.join(outputFolder, file);
230
184
  ui?.debug(`Deleting old landscape header image: ${file}`);
231
185
  fs8.unlinkSync(filePath);
232
186
  deletedCount++;
233
187
  } else if (portraitMatch && portraitMatch[1] !== currentHeaderBasename) {
234
- const filePath = path.join(outputFolder, file);
188
+ const filePath = path7.join(outputFolder, file);
235
189
  ui?.debug(`Deleting old portrait header image: ${file}`);
236
190
  fs8.unlinkSync(filePath);
237
191
  deletedCount++;
@@ -245,7 +199,7 @@ function cleanupOldHeaderImages(outputFolder, currentHeaderBasename, ui) {
245
199
  }
246
200
  function findGalleries(basePath, recursive) {
247
201
  const galleryDirs = [];
248
- const galleryJsonPath = path.join(basePath, "gallery", "gallery.json");
202
+ const galleryJsonPath = path7.join(basePath, "gallery", "gallery.json");
249
203
  if (fs8.existsSync(galleryJsonPath)) {
250
204
  galleryDirs.push(basePath);
251
205
  }
@@ -254,7 +208,7 @@ function findGalleries(basePath, recursive) {
254
208
  const entries = fs8.readdirSync(basePath, { withFileTypes: true });
255
209
  for (const entry of entries) {
256
210
  if (entry.isDirectory() && entry.name !== "gallery") {
257
- const subPath = path.join(basePath, entry.name);
211
+ const subPath = path7.join(basePath, entry.name);
258
212
  const subResults = findGalleries(subPath, recursive);
259
213
  galleryDirs.push(...subResults);
260
214
  }
@@ -313,20 +267,20 @@ function migrateGalleryJson(deprecatedGalleryData, galleryJsonPath, ui) {
313
267
  ui.start("Old gallery.json format detected. Migrating gallery.json to the new data format.");
314
268
  let mediaBasePath;
315
269
  const imagePath = deprecatedGalleryData.sections[0].images[0].path;
316
- if (imagePath && imagePath !== path.join("..", path.basename(imagePath))) {
317
- mediaBasePath = path.resolve(path.join(path.dirname(galleryJsonPath)), path.dirname(imagePath));
270
+ if (imagePath && imagePath !== path7.join("..", path7.basename(imagePath))) {
271
+ mediaBasePath = path7.resolve(path7.join(path7.dirname(galleryJsonPath)), path7.dirname(imagePath));
318
272
  }
319
273
  const sections = deprecatedGalleryData.sections.map((section) => ({
320
274
  ...section,
321
275
  images: section.images.map((image) => ({
322
276
  ...image,
323
277
  path: void 0,
324
- filename: path.basename(image.path)
278
+ filename: path7.basename(image.path)
325
279
  }))
326
280
  }));
327
281
  const galleryData = {
328
282
  ...deprecatedGalleryData,
329
- headerImage: path.basename(deprecatedGalleryData.headerImage),
283
+ headerImage: path7.basename(deprecatedGalleryData.headerImage),
330
284
  sections,
331
285
  mediaBasePath
332
286
  };
@@ -338,7 +292,7 @@ function migrateGalleryJson(deprecatedGalleryData, galleryJsonPath, ui) {
338
292
  return galleryData;
339
293
  }
340
294
  function getMediaFileType(fileName) {
341
- const ext = path.extname(fileName).toLowerCase();
295
+ const ext = path7.extname(fileName).toLowerCase();
342
296
  if (IMAGE_EXTENSIONS.has(ext)) return "image";
343
297
  if (VIDEO_EXTENSIONS.has(ext)) return "video";
344
298
  return null;
@@ -366,7 +320,7 @@ async function scanDirectory(dirPath, ui) {
366
320
  mediaFiles.push(mediaFile);
367
321
  }
368
322
  } else if (entry.isDirectory() && entry.name !== "gallery") {
369
- subGalleryDirectories.push(path.join(dirPath, entry.name));
323
+ subGalleryDirectories.push(path7.join(dirPath, entry.name));
370
324
  }
371
325
  }
372
326
  } catch (error) {
@@ -402,12 +356,12 @@ async function getGallerySettingsFromUser(galleryName, defaultImage, ui) {
402
356
  return { title, description, url, headerImage };
403
357
  }
404
358
  async function createGalleryJson(mediaFiles, galleryJsonPath, scanPath, subGalleries = [], useDefaultSettings, ctaBanner, ui) {
405
- const galleryDir = path.dirname(galleryJsonPath);
406
- const isSameLocation = path.relative(scanPath, path.join(galleryDir, "..")) === "";
359
+ const galleryDir = path7.dirname(galleryJsonPath);
360
+ const isSameLocation = path7.relative(scanPath, path7.join(galleryDir, "..")) === "";
407
361
  const mediaBasePath = isSameLocation ? void 0 : scanPath;
408
362
  const relativeSubGalleries = subGalleries.map((subGallery) => ({
409
363
  ...subGallery,
410
- headerImage: subGallery.headerImage ? path.relative(galleryDir, subGallery.headerImage) : ""
364
+ headerImage: subGallery.headerImage ? path7.relative(galleryDir, subGallery.headerImage) : ""
411
365
  }));
412
366
  let galleryData = {
413
367
  title: "My Gallery",
@@ -430,8 +384,8 @@ async function createGalleryJson(mediaFiles, galleryJsonPath, scanPath, subGalle
430
384
  galleryData = {
431
385
  ...galleryData,
432
386
  ...await getGallerySettingsFromUser(
433
- path.basename(path.join(galleryDir, "..")),
434
- path.basename(mediaFiles[0]?.filename || ""),
387
+ path7.basename(path7.join(galleryDir, "..")),
388
+ path7.basename(mediaFiles[0]?.filename || ""),
435
389
  ui
436
390
  )
437
391
  };
@@ -439,8 +393,8 @@ async function createGalleryJson(mediaFiles, galleryJsonPath, scanPath, subGalle
439
393
  await promises.writeFile(galleryJsonPath, JSON.stringify(galleryData, null, 2));
440
394
  }
441
395
  async function galleryExists(outputPath) {
442
- const galleryPath = path.join(outputPath, "gallery");
443
- const galleryJsonPath = path.join(galleryPath, "gallery.json");
396
+ const galleryPath = path7.join(outputPath, "gallery");
397
+ const galleryJsonPath = path7.join(galleryPath, "gallery.json");
444
398
  try {
445
399
  await promises.access(galleryJsonPath);
446
400
  return true;
@@ -459,7 +413,7 @@ async function processDirectory(scanPath, outputPath, recursive, useDefaultSetti
459
413
  for (const subGalleryDir of subGalleryDirectories) {
460
414
  const result2 = await processDirectory(
461
415
  subGalleryDir,
462
- path.join(outputPath, path.basename(subGalleryDir)),
416
+ path7.join(outputPath, path7.basename(subGalleryDir)),
463
417
  recursive,
464
418
  useDefaultSettings,
465
419
  force,
@@ -474,8 +428,8 @@ async function processDirectory(scanPath, outputPath, recursive, useDefaultSetti
474
428
  }
475
429
  }
476
430
  if (mediaFiles.length > 0 || subGalleries.length > 0) {
477
- const galleryPath = path.join(outputPath, "gallery");
478
- const galleryJsonPath = path.join(galleryPath, "gallery.json");
431
+ const galleryPath = path7.join(outputPath, "gallery");
432
+ const galleryJsonPath = path7.join(galleryPath, "gallery.json");
479
433
  const exists = await galleryExists(outputPath);
480
434
  if (exists && !force) {
481
435
  const shouldOverride = await ui.prompt(`Gallery already exists at ${galleryJsonPath}. Do you want to override it?`, {
@@ -500,19 +454,19 @@ async function processDirectory(scanPath, outputPath, recursive, useDefaultSetti
500
454
  }
501
455
  const result = { totalFiles, totalGalleries };
502
456
  if (mediaFiles.length > 0 || subGalleries.length > 0) {
503
- const dirName = path.basename(scanPath);
457
+ const dirName = path7.basename(scanPath);
504
458
  result.subGallery = {
505
459
  title: capitalizeTitle(dirName),
506
460
  headerImage: mediaFiles[0]?.filename || "",
507
- path: path.join("..", dirName)
461
+ path: path7.join("..", dirName)
508
462
  };
509
463
  }
510
464
  return result;
511
465
  }
512
466
  async function init(options, ui) {
513
467
  try {
514
- const scanPath = path.resolve(options.photos);
515
- const outputPath = options.gallery ? path.resolve(options.gallery) : scanPath;
468
+ const scanPath = path7.resolve(options.photos);
469
+ const outputPath = options.gallery ? path7.resolve(options.gallery) : scanPath;
516
470
  const result = await processDirectory(
517
471
  scanPath,
518
472
  outputPath,
@@ -636,7 +590,7 @@ async function processImage(imagePath, thumbnailPath, thumbnailPathRetina, thumb
636
590
  const blurHash = await generateBlurHash(thumbnailPath);
637
591
  return {
638
592
  type: "image",
639
- filename: path.basename(imagePath),
593
+ filename: path7.basename(imagePath),
640
594
  alt: description,
641
595
  width: imageDimensions.width,
642
596
  height: imageDimensions.height,
@@ -667,7 +621,7 @@ async function processVideo(videoPath, thumbnailPath, thumbnailPathRetina, thumb
667
621
  const blurHash = await generateBlurHash(thumbnailPath);
668
622
  return {
669
623
  type: "video",
670
- filename: path.basename(videoPath),
624
+ filename: path7.basename(videoPath),
671
625
  alt: void 0,
672
626
  width: videoDimensions.width,
673
627
  height: videoDimensions.height,
@@ -683,11 +637,11 @@ async function processVideo(videoPath, thumbnailPath, thumbnailPathRetina, thumb
683
637
  }
684
638
  async function processMediaFile(mediaFile, mediaBasePath, thumbnailsPath, thumbnailSize, ui) {
685
639
  try {
686
- const filePath = path.resolve(path.join(mediaBasePath, mediaFile.filename));
640
+ const filePath = path7.resolve(path7.join(mediaBasePath, mediaFile.filename));
687
641
  const fileName = mediaFile.filename;
688
- const fileNameWithoutExt = path.parse(fileName).name;
642
+ const fileNameWithoutExt = path7.parse(fileName).name;
689
643
  const thumbnailFileName = `${fileNameWithoutExt}.avif`;
690
- const thumbnailPath = path.join(thumbnailsPath, thumbnailFileName);
644
+ const thumbnailPath = path7.join(thumbnailsPath, thumbnailFileName);
691
645
  const thumbnailPathRetina = thumbnailPath.replace(".avif", "@2x.avif");
692
646
  const lastMediaTimestamp = mediaFile.lastMediaTimestamp ? new Date(mediaFile.lastMediaTimestamp) : void 0;
693
647
  const verbose = ui.level === LogLevels.debug;
@@ -713,8 +667,8 @@ async function processMediaFile(mediaFile, mediaBasePath, thumbnailsPath, thumbn
713
667
  }
714
668
  updatedMediaFile.filename = mediaFile.filename;
715
669
  if (updatedMediaFile.thumbnail) {
716
- updatedMediaFile.thumbnail.path = path.basename(thumbnailPath);
717
- updatedMediaFile.thumbnail.pathRetina = path.basename(thumbnailPathRetina);
670
+ updatedMediaFile.thumbnail.path = path7.basename(thumbnailPath);
671
+ updatedMediaFile.thumbnail.pathRetina = path7.basename(thumbnailPathRetina);
718
672
  if (mediaFile.thumbnail?.baseUrl) {
719
673
  updatedMediaFile.thumbnail.baseUrl = mediaFile.thumbnail.baseUrl;
720
674
  }
@@ -729,14 +683,14 @@ async function processMediaFile(mediaFile, mediaBasePath, thumbnailsPath, thumbn
729
683
  }
730
684
  }
731
685
  async function processGalleryThumbnails(galleryDir, ui) {
732
- const galleryJsonPath = path.join(galleryDir, "gallery", "gallery.json");
733
- const thumbnailsPath = path.join(galleryDir, "gallery", "images");
686
+ const galleryJsonPath = path7.join(galleryDir, "gallery", "gallery.json");
687
+ const thumbnailsPath = path7.join(galleryDir, "gallery", "images");
734
688
  ui.start(`Creating thumbnails: ${galleryDir}`);
735
689
  try {
736
690
  fs8.mkdirSync(thumbnailsPath, { recursive: true });
737
691
  const galleryData = parseGalleryJson(galleryJsonPath, ui);
738
692
  const thumbnailSize = galleryData.thumbnailSize || DEFAULT_THUMBNAIL_SIZE;
739
- const mediaBasePath = galleryData.mediaBasePath ?? path.join(galleryDir);
693
+ const mediaBasePath = galleryData.mediaBasePath ?? path7.join(galleryDir);
740
694
  let processedCount = 0;
741
695
  for (const section of galleryData.sections) {
742
696
  for (const [index, mediaFile] of section.images.entries()) {
@@ -783,8 +737,8 @@ function copyPhotos(galleryData, galleryDir, ui) {
783
737
  for (const section of galleryData.sections) {
784
738
  for (const image of section.images) {
785
739
  if (galleryData.mediaBasePath) {
786
- const sourcePath = path.join(galleryData.mediaBasePath, image.filename);
787
- const destPath = path.join(galleryDir, image.filename);
740
+ const sourcePath = path7.join(galleryData.mediaBasePath, image.filename);
741
+ const destPath = path7.join(galleryDir, image.filename);
788
742
  ui.debug(`Copying photo to ${destPath}`);
789
743
  fs8.copyFileSync(sourcePath, destPath);
790
744
  }
@@ -823,17 +777,17 @@ async function scanAndAppendNewFiles(galleryDir, galleryJsonPath, galleryData, u
823
777
  }
824
778
  async function buildGallery(galleryDir, templateDir, scan, shouldCreateThumbnails, ui, baseUrl, thumbsBaseUrl) {
825
779
  ui.start(`Building gallery ${galleryDir}`);
826
- const galleryJsonPath = path.join(galleryDir, "gallery", "gallery.json");
780
+ const galleryJsonPath = path7.join(galleryDir, "gallery", "gallery.json");
827
781
  let galleryData = parseGalleryJson(galleryJsonPath, ui);
828
782
  if (scan) {
829
783
  galleryData = await scanAndAppendNewFiles(galleryDir, galleryJsonPath, galleryData, ui);
830
784
  }
831
- const socialMediaCardImagePath = path.join(galleryDir, "gallery", "images", "social-media-card.jpg");
785
+ const socialMediaCardImagePath = path7.join(galleryDir, "gallery", "images", "social-media-card.jpg");
832
786
  const mediaBasePath = galleryData.mediaBasePath;
833
787
  const mediaBaseUrl = baseUrl || galleryData.mediaBaseUrl;
834
- const headerImagePath = mediaBasePath ? path.join(mediaBasePath, galleryData.headerImage) : path.resolve(galleryDir, galleryData.headerImage);
835
- const imagesFolder = path.join(galleryDir, "gallery", "images");
836
- const currentHeaderBasename = path.basename(headerImagePath, path.extname(headerImagePath));
788
+ const headerImagePath = mediaBasePath ? path7.join(mediaBasePath, galleryData.headerImage) : path7.resolve(galleryDir, galleryData.headerImage);
789
+ const imagesFolder = path7.join(galleryDir, "gallery", "images");
790
+ const currentHeaderBasename = path7.basename(headerImagePath, path7.extname(headerImagePath));
837
791
  if (shouldCreateThumbnails) {
838
792
  if (!fs8.existsSync(imagesFolder)) {
839
793
  fs8.mkdirSync(imagesFolder, { recursive: true });
@@ -876,7 +830,7 @@ async function buildGallery(galleryDir, templateDir, scan, shouldCreateThumbnail
876
830
  }
877
831
  if (!galleryData.metadata.image) {
878
832
  ui.debug("Updating gallery.json with social media card URL");
879
- galleryData.metadata.image = thumbsBaseUrl ? `${thumbsBaseUrl}/${path.basename(socialMediaCardImagePath)}` : `${galleryData.url || ""}/${path.relative(galleryDir, socialMediaCardImagePath)}`;
833
+ galleryData.metadata.image = thumbsBaseUrl ? `${thumbsBaseUrl}/${path7.basename(socialMediaCardImagePath)}` : `${galleryData.url || ""}/${path7.relative(galleryDir, socialMediaCardImagePath)}`;
880
834
  fs8.writeFileSync(galleryJsonPath, JSON.stringify(galleryData, null, 2));
881
835
  }
882
836
  if (shouldCreateThumbnails) {
@@ -884,20 +838,20 @@ async function buildGallery(galleryDir, templateDir, scan, shouldCreateThumbnail
884
838
  }
885
839
  ui.debug("Building gallery from template");
886
840
  try {
887
- process4.env.GALLERY_JSON_PATH = galleryJsonPath;
888
- process4.env.GALLERY_OUTPUT_DIR = path.join(galleryDir, "gallery");
841
+ process3.env.GALLERY_JSON_PATH = galleryJsonPath;
842
+ process3.env.GALLERY_OUTPUT_DIR = path7.join(galleryDir, "gallery");
889
843
  execSync("npx astro build", { cwd: templateDir, stdio: ui.level === LogLevels.debug ? "inherit" : "ignore" });
890
844
  } catch (error) {
891
845
  ui.error(`Build failed for ${galleryDir}`);
892
846
  throw error;
893
847
  }
894
- const outputDir = path.join(galleryDir, "gallery");
895
- const buildDir = path.join(outputDir, "_build");
848
+ const outputDir = path7.join(galleryDir, "gallery");
849
+ const buildDir = path7.join(outputDir, "_build");
896
850
  ui.debug(`Copying build output to ${outputDir}`);
897
851
  fs8.cpSync(buildDir, outputDir, { recursive: true });
898
852
  ui.debug("Moving index.html to gallery directory");
899
- fs8.copyFileSync(path.join(outputDir, "index.html"), path.join(galleryDir, "index.html"));
900
- fs8.rmSync(path.join(outputDir, "index.html"));
853
+ fs8.copyFileSync(path7.join(outputDir, "index.html"), path7.join(galleryDir, "index.html"));
854
+ fs8.rmSync(path7.join(outputDir, "index.html"));
901
855
  ui.debug("Cleaning up build directory");
902
856
  fs8.rmSync(buildDir, { recursive: true, force: true });
903
857
  ui.success(`Gallery built successfully`);
@@ -910,12 +864,12 @@ async function build(options, ui) {
910
864
  return { processedGalleryCount: 0 };
911
865
  }
912
866
  const themePath = await import.meta.resolve("@simple-photo-gallery/theme-modern/package.json");
913
- const themeDir = path.dirname(new URL(themePath).pathname);
867
+ const themeDir = path7.dirname(new URL(themePath).pathname);
914
868
  let totalGalleries = 0;
915
869
  for (const dir of galleryDirs) {
916
- const baseUrl = options.baseUrl ? `${options.baseUrl}${path.relative(options.gallery, dir)}` : void 0;
917
- const thumbsBaseUrl = options.thumbsBaseUrl ? `${options.thumbsBaseUrl}${path.relative(options.gallery, dir)}` : void 0;
918
- await buildGallery(path.resolve(dir), themeDir, options.scan, options.thumbnails, ui, baseUrl, thumbsBaseUrl);
870
+ const baseUrl = options.baseUrl ? `${options.baseUrl}${path7.relative(options.gallery, dir)}` : void 0;
871
+ const thumbsBaseUrl = options.thumbsBaseUrl ? `${options.thumbsBaseUrl}${path7.relative(options.gallery, dir)}` : void 0;
872
+ await buildGallery(path7.resolve(dir), themeDir, options.scan, options.thumbnails, ui, baseUrl, thumbsBaseUrl);
919
873
  ++totalGalleries;
920
874
  }
921
875
  ui.box(`Built ${totalGalleries} ${totalGalleries === 1 ? "gallery" : "galleries"} successfully`);
@@ -931,7 +885,7 @@ async function build(options, ui) {
931
885
  }
932
886
  async function cleanGallery(galleryDir, ui) {
933
887
  let filesRemoved = 0;
934
- const indexHtmlPath = path.join(galleryDir, "index.html");
888
+ const indexHtmlPath = path7.join(galleryDir, "index.html");
935
889
  if (fs8.existsSync(indexHtmlPath)) {
936
890
  try {
937
891
  fs8.rmSync(indexHtmlPath);
@@ -941,7 +895,7 @@ async function cleanGallery(galleryDir, ui) {
941
895
  ui?.warn(`Failed to remove index.html: ${error}`);
942
896
  }
943
897
  }
944
- const galleryPath = path.join(galleryDir, "gallery");
898
+ const galleryPath = path7.join(galleryDir, "gallery");
945
899
  if (fs8.existsSync(galleryPath)) {
946
900
  try {
947
901
  fs8.rmSync(galleryPath, { recursive: true, force: true });
@@ -960,7 +914,7 @@ async function cleanGallery(galleryDir, ui) {
960
914
  }
961
915
  async function clean(options, ui) {
962
916
  try {
963
- const basePath = path.resolve(options.gallery);
917
+ const basePath = path7.resolve(options.gallery);
964
918
  if (!fs8.existsSync(basePath)) {
965
919
  ui.error(`Directory does not exist: ${basePath}`);
966
920
  return { processedGalleryCount: 0 };
@@ -1009,7 +963,7 @@ var ApiTelemetryClient = class {
1009
963
  axios.post(this.endpoint, event, {
1010
964
  headers: {
1011
965
  "content-type": "application/json",
1012
- "user-agent": `simple-photo-gallery/${event.packageVersion} (${process4.platform}; ${process4.arch})`
966
+ "user-agent": `simple-photo-gallery/${event.packageVersion} (${process3.platform}; ${process3.arch})`
1013
967
  }
1014
968
  });
1015
969
  } catch {
@@ -1046,11 +1000,11 @@ var TelemetryService = class {
1046
1000
  if (override) {
1047
1001
  return override === "1";
1048
1002
  }
1049
- if (process4.env.CI || process4.env.DO_NOT_TRACK) {
1003
+ if (process3.env.CI || process3.env.DO_NOT_TRACK) {
1050
1004
  return false;
1051
1005
  }
1052
- if (process4.env.SPG_TELEMETRY) {
1053
- return process4.env.SPG_TELEMETRY === "1";
1006
+ if (process3.env.SPG_TELEMETRY) {
1007
+ return process3.env.SPG_TELEMETRY === "1";
1054
1008
  }
1055
1009
  const stored = this.getStoredPreference();
1056
1010
  if (stored === void 0) {
@@ -1092,7 +1046,7 @@ var TelemetryService = class {
1092
1046
  durationMs: now - startedAt,
1093
1047
  packageName: this.packageName,
1094
1048
  packageVersion: this.packageVersion,
1095
- nodeVersion: process4.version,
1049
+ nodeVersion: process3.version,
1096
1050
  osPlatform: os.platform(),
1097
1051
  osRelease: os.release(),
1098
1052
  osArch: os.arch(),
@@ -1126,7 +1080,7 @@ var TelemetryService = class {
1126
1080
  /** Returns the telemetry client. */
1127
1081
  getClient() {
1128
1082
  if (!this.client) {
1129
- switch (process4.env.SPG_TELEMETRY_PROVIDER) {
1083
+ switch (process3.env.SPG_TELEMETRY_PROVIDER) {
1130
1084
  case "none": {
1131
1085
  this.client = void 0;
1132
1086
  break;
@@ -1218,7 +1172,7 @@ async function waitForUpdateCheck(checkPromise) {
1218
1172
  // package.json
1219
1173
  var package_default = {
1220
1174
  name: "simple-photo-gallery",
1221
- version: "2.0.14-rc.1"};
1175
+ version: "2.0.15"};
1222
1176
 
1223
1177
  // src/index.ts
1224
1178
  var program = new Command();
@@ -1260,7 +1214,7 @@ function withCommandContext(handler) {
1260
1214
  } catch (error) {
1261
1215
  ui.debug(error);
1262
1216
  errorInfo = error instanceof Error ? { name: error.name, message: error.message } : { name: "UnknownError", message: String(error) };
1263
- process4.exitCode = 1;
1217
+ process3.exitCode = 1;
1264
1218
  }
1265
1219
  const updateInfo = await waitForUpdateCheck(updateCheckPromise);
1266
1220
  if (updateInfo) {
@@ -1282,14 +1236,14 @@ function withCommandContext(handler) {
1282
1236
  program.command("init").description("Initialize a gallery by scaning a folder for images and videos").option(
1283
1237
  "-p, --photos <path>",
1284
1238
  "Path to the folder where the photos are stored. Default: current working directory",
1285
- process4.cwd()
1239
+ process3.cwd()
1286
1240
  ).option(
1287
1241
  "-g, --gallery <path>",
1288
1242
  "Path to the directory where the gallery will be initialized. Default: same directory as the photos folder"
1289
1243
  ).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).action(withCommandContext((options, ui) => init(options, ui)));
1290
- 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.cwd()).option("-r, --recursive", "Scan subdirectories recursively", false).action(withCommandContext((options, ui) => thumbnails(options, ui)));
1291
- 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.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).action(withCommandContext((options, ui) => build(options, ui)));
1292
- 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.cwd()).option("-r, --recursive", "Clean subdirectories recursively", false).action(withCommandContext((options, ui) => clean(options, ui)));
1244
+ 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", process3.cwd()).option("-r, --recursive", "Scan subdirectories recursively", false).action(withCommandContext((options, ui) => thumbnails(options, ui)));
1245
+ 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", process3.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).action(withCommandContext((options, ui) => build(options, ui)));
1246
+ 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", process3.cwd()).option("-r, --recursive", "Clean subdirectories recursively", false).action(withCommandContext((options, ui) => clean(options, ui)));
1293
1247
  program.command("telemetry").description("Manage anonymous telemetry preferences. Use 1 to enable, 0 to disable, or no argument to check status").option("-s, --state <state>", "Enable (1) or disable (0) telemetry", parseTelemetryOption).action(withCommandContext((options, ui) => telemetry(options, ui, telemetryService)));
1294
1248
  program.parse();
1295
1249
  //# sourceMappingURL=index.js.map