@gallop.software/studio 0.1.91 → 0.1.92
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/{StudioUI-NNOVWAOQ.mjs → StudioUI-7VQHCHFQ.mjs} +1 -7
- package/dist/StudioUI-7VQHCHFQ.mjs.map +1 -0
- package/dist/{StudioUI-4376LEHU.js → StudioUI-VRSG32E3.js} +1 -7
- package/dist/StudioUI-VRSG32E3.js.map +1 -0
- package/dist/{chunk-63EAAMA3.mjs → chunk-DTVEVFQ2.mjs} +1 -1
- package/dist/chunk-DTVEVFQ2.mjs.map +1 -0
- package/dist/{chunk-RURSHIQJ.js → chunk-L36EH3PM.js} +1 -1
- package/dist/chunk-L36EH3PM.js.map +1 -0
- package/dist/handlers/index.d.mts +1 -1
- package/dist/handlers/index.d.ts +1 -1
- package/dist/handlers/index.js +54 -31
- package/dist/handlers/index.js.map +1 -1
- package/dist/handlers/index.mjs +35 -12
- package/dist/handlers/index.mjs.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3 -3
- package/dist/index.mjs +2 -2
- package/dist/{types-DuX-sfUL.d.mts → types-C4hCz2w8.d.mts} +2 -0
- package/dist/{types-DuX-sfUL.d.ts → types-C4hCz2w8.d.ts} +2 -0
- package/package.json +1 -1
- package/dist/StudioUI-4376LEHU.js.map +0 -1
- package/dist/StudioUI-NNOVWAOQ.mjs.map +0 -1
- package/dist/chunk-63EAAMA3.mjs.map +0 -1
- package/dist/chunk-RURSHIQJ.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/Users/chrisb/Sites/studio/dist/chunk-L36EH3PM.js","../src/types.ts"],"names":["ext","base","outputExt"],"mappings":"AAAA;AC6DO,SAAS,gBAAA,CAAiB,YAAA,EAAsB,IAAA,EAA2C;AAChG,EAAA,GAAA,CAAI,KAAA,IAAS,MAAA,EAAQ;AACnB,IAAA,MAAMA,KAAAA,kBAAM,YAAA,mBAAa,KAAA,mBAAM,QAAQ,CAAA,4BAAA,CAAI,CAAC,IAAA,GAAK,MAAA;AACjD,IAAA,MAAMC,MAAAA,EAAO,YAAA,CAAa,OAAA,CAAQ,QAAA,EAAU,EAAE,CAAA;AAC9C,IAAA,MAAMC,WAAAA,EAAYF,IAAAA,CAAI,WAAA,CAAY,EAAA,IAAM,OAAA,EAAS,OAAA,EAAS,MAAA;AAC1D,IAAA,OAAO,CAAA,OAAA,EAAUC,KAAI,CAAA,EAAA;AACvB,EAAA;AACyB,EAAA;AACZ,EAAA;AACS,EAAA;AACG,EAAA;AAC3B;AAKgB;AACP,EAAA;AACY,IAAA;AACA,IAAA;AACA,IAAA;AACA,IAAA;AACnB,EAAA;AACF;AD/D2B;AACA;AACA;AACA;AACA","file":"/Users/chrisb/Sites/studio/dist/chunk-L36EH3PM.js","sourcesContent":[null,"/**\n * Meta entry - works for images and non-images\n * Images have w, h, b (after processing)\n * Non-images just have c (if pushed to CDN)\n */\nexport interface MetaEntry {\n w?: number // original width (images only)\n h?: number // original height (images only)\n b?: string // blurhash (images only, after processing)\n p?: 1 // processed (has thumbnails and blurhash)\n c?: 1 // pushed to CDN (omit if not pushed)\n}\n\n/**\n * Meta schema - keyed by path from public folder\n * Example: { \"/portfolio/photo.jpg\": { w: 2400, h: 1600, blur: \"...\" } }\n */\nexport type LeanMeta = Record<string, MetaEntry>\n\n// Legacy alias for compatibility\nexport type LeanImageEntry = MetaEntry\n\n/**\n * File/folder item for browser\n */\nexport interface FileItem {\n name: string\n path: string\n type: 'file' | 'folder'\n size?: number\n dimensions?: { width: number; height: number }\n isProcessed?: boolean\n cdnPushed?: boolean\n // Folder-specific properties\n fileCount?: number\n totalSize?: number\n // For showing thumbnails - path to -sm version if exists\n thumbnail?: string\n // Whether a processed thumbnail exists\n hasThumbnail?: boolean\n}\n\n/**\n * Studio configuration\n */\nexport interface StudioConfig {\n r2AccountId?: string\n r2AccessKeyId?: string\n r2SecretAccessKey?: string\n r2BucketName?: string\n r2PublicUrl?: string\n thumbnailSizes?: {\n small: number\n medium: number\n large: number\n }\n}\n\n/**\n * Get thumbnail path from original image path\n */\nexport function getThumbnailPath(originalPath: string, size: 'sm' | 'md' | 'lg' | 'full'): string {\n if (size === 'full') {\n const ext = originalPath.match(/\\.\\w+$/)?.[0] || '.jpg'\n const base = originalPath.replace(/\\.\\w+$/, '')\n const outputExt = ext.toLowerCase() === '.png' ? '.png' : '.jpg'\n return `/images${base}${outputExt}`\n }\n const ext = originalPath.match(/\\.\\w+$/)?.[0] || '.jpg'\n const base = originalPath.replace(/\\.\\w+$/, '')\n const outputExt = ext.toLowerCase() === '.png' ? '.png' : '.jpg'\n return `/images${base}-${size}${outputExt}`\n}\n\n/**\n * Get all thumbnail paths for an image\n */\nexport function getAllThumbnailPaths(originalPath: string): string[] {\n return [\n getThumbnailPath(originalPath, 'full'),\n getThumbnailPath(originalPath, 'lg'),\n getThumbnailPath(originalPath, 'md'),\n getThumbnailPath(originalPath, 'sm'),\n ]\n}\n"]}
|
package/dist/handlers/index.d.ts
CHANGED
package/dist/handlers/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
var
|
|
4
|
+
var _chunkL36EH3PMjs = require('../chunk-L36EH3PM.js');
|
|
5
5
|
|
|
6
6
|
// src/handlers/index.ts
|
|
7
7
|
var _server = require('next/server');
|
|
@@ -156,7 +156,7 @@ async function uploadToCdn(imageKey) {
|
|
|
156
156
|
const bucketName = process.env.CLOUDFLARE_R2_BUCKET_NAME;
|
|
157
157
|
if (!bucketName) throw new Error("R2 bucket not configured");
|
|
158
158
|
const r2 = getR2Client();
|
|
159
|
-
for (const thumbPath of
|
|
159
|
+
for (const thumbPath of _chunkL36EH3PMjs.getAllThumbnailPaths.call(void 0, imageKey)) {
|
|
160
160
|
const localPath = _path2.default.join(process.cwd(), "public", thumbPath);
|
|
161
161
|
try {
|
|
162
162
|
const fileBuffer = await _fs.promises.readFile(localPath);
|
|
@@ -173,7 +173,7 @@ async function uploadToCdn(imageKey) {
|
|
|
173
173
|
}
|
|
174
174
|
}
|
|
175
175
|
async function deleteLocalThumbnails(imageKey) {
|
|
176
|
-
for (const thumbPath of
|
|
176
|
+
for (const thumbPath of _chunkL36EH3PMjs.getAllThumbnailPaths.call(void 0, imageKey)) {
|
|
177
177
|
const localPath = _path2.default.join(process.cwd(), "public", thumbPath);
|
|
178
178
|
try {
|
|
179
179
|
await _fs.promises.unlink(localPath);
|
|
@@ -227,7 +227,7 @@ async function handleList(request) {
|
|
|
227
227
|
let hasThumbnail = false;
|
|
228
228
|
let fileSize;
|
|
229
229
|
if (isImage && (entry.w || entry.b)) {
|
|
230
|
-
const thumbPath =
|
|
230
|
+
const thumbPath = _chunkL36EH3PMjs.getThumbnailPath.call(void 0, key, "sm");
|
|
231
231
|
if (isPushedToCloud) {
|
|
232
232
|
const cdnUrl = process.env.CLOUDFLARE_R2_PUBLIC_URL || process.env.NEXT_PUBLIC_CLOUDFLARE_R2_PUBLIC_URL;
|
|
233
233
|
if (cdnUrl) {
|
|
@@ -264,6 +264,7 @@ async function handleList(request) {
|
|
|
264
264
|
size: fileSize,
|
|
265
265
|
thumbnail,
|
|
266
266
|
hasThumbnail,
|
|
267
|
+
isProcessed: entry.p === 1,
|
|
267
268
|
cdnPushed: isPushedToCloud,
|
|
268
269
|
dimensions: entry.w && entry.h ? { width: entry.w, height: entry.h } : void 0
|
|
269
270
|
});
|
|
@@ -293,7 +294,7 @@ async function handleSearch(request) {
|
|
|
293
294
|
let thumbnail;
|
|
294
295
|
let hasThumbnail = false;
|
|
295
296
|
if (isImage && (entry.w || entry.b)) {
|
|
296
|
-
const thumbPath =
|
|
297
|
+
const thumbPath = _chunkL36EH3PMjs.getThumbnailPath.call(void 0, key, "sm");
|
|
297
298
|
if (isPushedToCloud) {
|
|
298
299
|
const cdnUrl = process.env.CLOUDFLARE_R2_PUBLIC_URL || process.env.NEXT_PUBLIC_CLOUDFLARE_R2_PUBLIC_URL;
|
|
299
300
|
if (cdnUrl) {
|
|
@@ -321,6 +322,7 @@ async function handleSearch(request) {
|
|
|
321
322
|
type: "file",
|
|
322
323
|
thumbnail,
|
|
323
324
|
hasThumbnail,
|
|
325
|
+
isProcessed: entry.p === 1,
|
|
324
326
|
cdnPushed: isPushedToCloud,
|
|
325
327
|
dimensions: entry.w && entry.h ? { width: entry.w, height: entry.h } : void 0
|
|
326
328
|
});
|
|
@@ -522,7 +524,7 @@ async function handleDelete(request) {
|
|
|
522
524
|
for (const key of Object.keys(meta)) {
|
|
523
525
|
if (key.startsWith(prefix) || key === imageKey) {
|
|
524
526
|
if (!meta[key].c) {
|
|
525
|
-
for (const thumbPath of
|
|
527
|
+
for (const thumbPath of _chunkL36EH3PMjs.getAllThumbnailPaths.call(void 0, key)) {
|
|
526
528
|
const absoluteThumbPath = _path2.default.join(process.cwd(), "public", thumbPath);
|
|
527
529
|
try {
|
|
528
530
|
await _fs.promises.unlink(absoluteThumbPath);
|
|
@@ -538,7 +540,7 @@ async function handleDelete(request) {
|
|
|
538
540
|
const isInImagesFolder = itemPath.startsWith("public/images/");
|
|
539
541
|
if (!isInImagesFolder && entry) {
|
|
540
542
|
if (!isPushedToCloud) {
|
|
541
|
-
for (const thumbPath of
|
|
543
|
+
for (const thumbPath of _chunkL36EH3PMjs.getAllThumbnailPaths.call(void 0, imageKey)) {
|
|
542
544
|
const absoluteThumbPath = _path2.default.join(process.cwd(), "public", thumbPath);
|
|
543
545
|
try {
|
|
544
546
|
await _fs.promises.unlink(absoluteThumbPath);
|
|
@@ -650,8 +652,8 @@ async function handleRename(request) {
|
|
|
650
652
|
const newKey = "/" + newRelativePath;
|
|
651
653
|
if (meta[oldKey]) {
|
|
652
654
|
const entry = meta[oldKey];
|
|
653
|
-
const oldThumbPaths =
|
|
654
|
-
const newThumbPaths =
|
|
655
|
+
const oldThumbPaths = _chunkL36EH3PMjs.getAllThumbnailPaths.call(void 0, oldKey);
|
|
656
|
+
const newThumbPaths = _chunkL36EH3PMjs.getAllThumbnailPaths.call(void 0, newKey);
|
|
655
657
|
for (let i = 0; i < oldThumbPaths.length; i++) {
|
|
656
658
|
const oldThumbPath = _path2.default.join(process.cwd(), "public", oldThumbPaths[i]);
|
|
657
659
|
const newThumbPath = _path2.default.join(process.cwd(), "public", newThumbPaths[i]);
|
|
@@ -730,8 +732,8 @@ async function handleMove(request) {
|
|
|
730
732
|
const newKey = "/" + newRelativePath;
|
|
731
733
|
if (meta[oldKey]) {
|
|
732
734
|
const entry = meta[oldKey];
|
|
733
|
-
const oldThumbPaths =
|
|
734
|
-
const newThumbPaths =
|
|
735
|
+
const oldThumbPaths = _chunkL36EH3PMjs.getAllThumbnailPaths.call(void 0, oldKey);
|
|
736
|
+
const newThumbPaths = _chunkL36EH3PMjs.getAllThumbnailPaths.call(void 0, newKey);
|
|
735
737
|
for (let i = 0; i < oldThumbPaths.length; i++) {
|
|
736
738
|
const oldThumbPath = _path2.default.join(process.cwd(), "public", oldThumbPaths[i]);
|
|
737
739
|
const newThumbPath = _path2.default.join(process.cwd(), "public", newThumbPaths[i]);
|
|
@@ -805,6 +807,10 @@ async function handleSync(request) {
|
|
|
805
807
|
pushed.push(imageKey);
|
|
806
808
|
continue;
|
|
807
809
|
}
|
|
810
|
+
if (!entry.p) {
|
|
811
|
+
errors.push(`Image not processed: ${imageKey}. Run Process Images first.`);
|
|
812
|
+
continue;
|
|
813
|
+
}
|
|
808
814
|
try {
|
|
809
815
|
const originalLocalPath = _path2.default.join(process.cwd(), "public", imageKey);
|
|
810
816
|
try {
|
|
@@ -821,7 +827,7 @@ async function handleSync(request) {
|
|
|
821
827
|
errors.push(`Original file not found: ${imageKey}`);
|
|
822
828
|
continue;
|
|
823
829
|
}
|
|
824
|
-
for (const thumbPath of
|
|
830
|
+
for (const thumbPath of _chunkL36EH3PMjs.getAllThumbnailPaths.call(void 0, imageKey)) {
|
|
825
831
|
const localPath = _path2.default.join(process.cwd(), "public", thumbPath);
|
|
826
832
|
try {
|
|
827
833
|
const fileBuffer = await _fs.promises.readFile(localPath);
|
|
@@ -837,7 +843,7 @@ async function handleSync(request) {
|
|
|
837
843
|
}
|
|
838
844
|
}
|
|
839
845
|
entry.c = 1;
|
|
840
|
-
for (const thumbPath of
|
|
846
|
+
for (const thumbPath of _chunkL36EH3PMjs.getAllThumbnailPaths.call(void 0, imageKey)) {
|
|
841
847
|
const localPath = _path2.default.join(process.cwd(), "public", thumbPath);
|
|
842
848
|
try {
|
|
843
849
|
await _fs.promises.unlink(localPath);
|
|
@@ -935,16 +941,11 @@ async function handleProcessAllStream() {
|
|
|
935
941
|
const errors = [];
|
|
936
942
|
const orphansRemoved = [];
|
|
937
943
|
let alreadyProcessed = 0;
|
|
938
|
-
let pushedToCloud = 0;
|
|
939
944
|
const imagesToProcess = [];
|
|
940
945
|
for (const [key, entry] of Object.entries(meta)) {
|
|
941
946
|
const fileName = _path2.default.basename(key);
|
|
942
947
|
if (!isImageFile(fileName)) continue;
|
|
943
|
-
if (entry.
|
|
944
|
-
pushedToCloud++;
|
|
945
|
-
continue;
|
|
946
|
-
}
|
|
947
|
-
if (!entry.b) {
|
|
948
|
+
if (!entry.p) {
|
|
948
949
|
imagesToProcess.push({ key, entry });
|
|
949
950
|
} else {
|
|
950
951
|
alreadyProcessed++;
|
|
@@ -953,8 +954,9 @@ async function handleProcessAllStream() {
|
|
|
953
954
|
const total = imagesToProcess.length;
|
|
954
955
|
sendEvent({ type: "start", total });
|
|
955
956
|
for (let i = 0; i < imagesToProcess.length; i++) {
|
|
956
|
-
const { key } = imagesToProcess[i];
|
|
957
|
+
const { key, entry } = imagesToProcess[i];
|
|
957
958
|
const fullPath = _path2.default.join(process.cwd(), "public", key);
|
|
959
|
+
const isInCloud = entry.c === 1;
|
|
958
960
|
sendEvent({
|
|
959
961
|
type: "progress",
|
|
960
962
|
current: i + 1,
|
|
@@ -964,7 +966,15 @@ async function handleProcessAllStream() {
|
|
|
964
966
|
// Remove leading /
|
|
965
967
|
});
|
|
966
968
|
try {
|
|
967
|
-
|
|
969
|
+
let buffer;
|
|
970
|
+
if (isInCloud) {
|
|
971
|
+
buffer = await downloadFromCdn(key);
|
|
972
|
+
const dir = _path2.default.dirname(fullPath);
|
|
973
|
+
await _fs.promises.mkdir(dir, { recursive: true });
|
|
974
|
+
await _fs.promises.writeFile(fullPath, buffer);
|
|
975
|
+
} else {
|
|
976
|
+
buffer = await _fs.promises.readFile(fullPath);
|
|
977
|
+
}
|
|
968
978
|
const ext = _path2.default.extname(key).toLowerCase();
|
|
969
979
|
const isSvg = ext === ".svg";
|
|
970
980
|
if (isSvg) {
|
|
@@ -975,13 +985,27 @@ async function handleProcessAllStream() {
|
|
|
975
985
|
const destPath = _path2.default.join(imagesPath, fileName);
|
|
976
986
|
await _fs.promises.writeFile(destPath, buffer);
|
|
977
987
|
meta[key] = {
|
|
988
|
+
...entry,
|
|
978
989
|
w: 0,
|
|
979
990
|
h: 0,
|
|
980
|
-
b: ""
|
|
991
|
+
b: "",
|
|
992
|
+
p: 1
|
|
981
993
|
};
|
|
982
994
|
} else {
|
|
983
995
|
const processedEntry = await processImage(buffer, key);
|
|
984
|
-
meta[key] =
|
|
996
|
+
meta[key] = {
|
|
997
|
+
...processedEntry,
|
|
998
|
+
p: 1,
|
|
999
|
+
...isInCloud ? { c: 1 } : {}
|
|
1000
|
+
};
|
|
1001
|
+
}
|
|
1002
|
+
if (isInCloud) {
|
|
1003
|
+
await uploadToCdn(key);
|
|
1004
|
+
await deleteLocalThumbnails(key);
|
|
1005
|
+
try {
|
|
1006
|
+
await _fs.promises.unlink(fullPath);
|
|
1007
|
+
} catch (e25) {
|
|
1008
|
+
}
|
|
985
1009
|
}
|
|
986
1010
|
processed.push(key.slice(1));
|
|
987
1011
|
} catch (error) {
|
|
@@ -993,7 +1017,7 @@ async function handleProcessAllStream() {
|
|
|
993
1017
|
const trackedPaths = /* @__PURE__ */ new Set();
|
|
994
1018
|
for (const imageKey of Object.keys(meta)) {
|
|
995
1019
|
if (!meta[imageKey].c) {
|
|
996
|
-
for (const thumbPath of
|
|
1020
|
+
for (const thumbPath of _chunkL36EH3PMjs.getAllThumbnailPaths.call(void 0, imageKey)) {
|
|
997
1021
|
trackedPaths.add(thumbPath);
|
|
998
1022
|
}
|
|
999
1023
|
}
|
|
@@ -1019,13 +1043,13 @@ async function handleProcessAllStream() {
|
|
|
1019
1043
|
}
|
|
1020
1044
|
}
|
|
1021
1045
|
}
|
|
1022
|
-
} catch (
|
|
1046
|
+
} catch (e26) {
|
|
1023
1047
|
}
|
|
1024
1048
|
}
|
|
1025
1049
|
const imagesDir = _path2.default.join(process.cwd(), "public", "images");
|
|
1026
1050
|
try {
|
|
1027
1051
|
await findOrphans(imagesDir);
|
|
1028
|
-
} catch (
|
|
1052
|
+
} catch (e27) {
|
|
1029
1053
|
}
|
|
1030
1054
|
async function removeEmptyDirs(dir) {
|
|
1031
1055
|
try {
|
|
@@ -1043,20 +1067,19 @@ async function handleProcessAllStream() {
|
|
|
1043
1067
|
await _fs.promises.rmdir(dir);
|
|
1044
1068
|
}
|
|
1045
1069
|
return isEmpty;
|
|
1046
|
-
} catch (
|
|
1070
|
+
} catch (e28) {
|
|
1047
1071
|
return true;
|
|
1048
1072
|
}
|
|
1049
1073
|
}
|
|
1050
1074
|
try {
|
|
1051
1075
|
await removeEmptyDirs(imagesDir);
|
|
1052
|
-
} catch (
|
|
1076
|
+
} catch (e29) {
|
|
1053
1077
|
}
|
|
1054
1078
|
await saveMeta(meta);
|
|
1055
1079
|
sendEvent({
|
|
1056
1080
|
type: "complete",
|
|
1057
1081
|
processed: processed.length,
|
|
1058
1082
|
alreadyProcessed,
|
|
1059
|
-
pushedToCloud,
|
|
1060
1083
|
orphansRemoved: orphansRemoved.length,
|
|
1061
1084
|
errors: errors.length
|
|
1062
1085
|
});
|
|
@@ -1111,7 +1134,7 @@ async function handleScanStream() {
|
|
|
1111
1134
|
allFiles.push({ relativePath: relPath, fullPath });
|
|
1112
1135
|
}
|
|
1113
1136
|
}
|
|
1114
|
-
} catch (
|
|
1137
|
+
} catch (e30) {
|
|
1115
1138
|
}
|
|
1116
1139
|
}
|
|
1117
1140
|
const publicDir = _path2.default.join(process.cwd(), "public");
|
|
@@ -1167,7 +1190,7 @@ async function handleScanStream() {
|
|
|
1167
1190
|
w: metadata.width || 0,
|
|
1168
1191
|
h: metadata.height || 0
|
|
1169
1192
|
};
|
|
1170
|
-
} catch (
|
|
1193
|
+
} catch (e31) {
|
|
1171
1194
|
meta[imageKey] = { w: 0, h: 0 };
|
|
1172
1195
|
}
|
|
1173
1196
|
}
|