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 +76 -125
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +69 -118
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
- package/dist/base/.prettierignore +0 -4
- package/dist/base/.prettierrc.mjs +0 -27
- package/dist/base/README.md +0 -42
- package/dist/base/README_BASE.md +0 -62
- package/dist/base/astro.config.ts +0 -35
- package/dist/base/eslint.config.mjs +0 -44
- package/dist/base/package.json +0 -46
- package/dist/base/src/components/container/Container.astro +0 -10
- package/dist/base/src/components/cta/CtaBanner.astro +0 -101
- package/dist/base/src/components/footer/Footer.astro +0 -43
- package/dist/base/src/components/gallery-section/GallerySection.astro +0 -71
- package/dist/base/src/components/gallery-section/GallerySectionHeader.astro +0 -41
- package/dist/base/src/components/gallery-section/GallerySectionItem.astro +0 -92
- package/dist/base/src/components/hero/Hero.astro +0 -141
- package/dist/base/src/components/hero/HeroScrollToGalleryBtn.astro +0 -77
- package/dist/base/src/components/lightbox/PhotoSwipe.astro +0 -13
- package/dist/base/src/components/sub-galleries/SubGalleries.astro +0 -129
- package/dist/base/src/layouts/MainHead.astro +0 -123
- package/dist/base/src/layouts/MainLayout.astro +0 -160
- package/dist/base/src/pages/index.astro +0 -61
- package/dist/base/src/utils/queryParams.ts +0 -109
- package/dist/base/themeConfig.json +0 -6
- package/dist/base/tsconfig.json +0 -11
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
|
|
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
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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 (!
|
|
230
|
+
if (!fs8__default.default.existsSync(outputFolder)) {
|
|
231
231
|
return false;
|
|
232
232
|
}
|
|
233
|
-
const files =
|
|
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 (!
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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 (
|
|
275
|
+
if (fs8__default.default.existsSync(galleryJsonPath)) {
|
|
276
276
|
galleryDirs.push(basePath);
|
|
277
277
|
}
|
|
278
278
|
if (recursive) {
|
|
279
279
|
try {
|
|
280
|
-
const entries =
|
|
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 =
|
|
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
|
-
|
|
364
|
+
fs8__default.default.copyFileSync(galleryJsonPath, `${galleryJsonPath}.old`);
|
|
365
365
|
ui.debug("Writing gallery data to gallery.json file");
|
|
366
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 &&
|
|
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 &&
|
|
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 &&
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 (!
|
|
952
|
-
|
|
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 (
|
|
959
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1018
|
+
fs8__default.default.cpSync(buildDir, outputDir, { recursive: true });
|
|
1028
1019
|
ui.debug("Moving index.html to gallery directory");
|
|
1029
|
-
|
|
1030
|
-
|
|
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
|
-
|
|
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 (!
|
|
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 (
|
|
1086
|
+
if (fs8__default.default.existsSync(indexHtmlPath)) {
|
|
1106
1087
|
try {
|
|
1107
|
-
|
|
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 (
|
|
1096
|
+
if (fs8__default.default.existsSync(galleryPath)) {
|
|
1116
1097
|
try {
|
|
1117
|
-
|
|
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 (!
|
|
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 (
|
|
1138
|
+
if (fs8__default.default.existsSync(pkgPath)) {
|
|
1158
1139
|
try {
|
|
1159
|
-
const pkg = JSON.parse(
|
|
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
|
|
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
|
|
1208
|
-
const entries = await
|
|
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
|
|
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
|
|
1248
|
-
if (
|
|
1249
|
-
return
|
|
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 (
|
|
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
|
-
- ${
|
|
1268
|
-
- ${srcPath}
|
|
1219
|
+
- ${bundledTemplatePath}
|
|
1269
1220
|
- ${workspaceBaseThemePath}
|
|
1270
1221
|
|
|
1271
|
-
Please ensure the
|
|
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
|
|
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
|
|
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 (!
|
|
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
|
|
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
|
|
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 (!
|
|
1257
|
+
if (!fs8__default.default.existsSync(themesBaseDir)) {
|
|
1307
1258
|
await ensureDirectory(themesBaseDir, ui);
|
|
1308
1259
|
}
|
|
1309
1260
|
}
|
|
1310
|
-
if (
|
|
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.
|
|
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",
|
|
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",
|
|
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",
|
|
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));
|