@pelatform/storage 1.0.6 → 1.0.7
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/{chunk-CT5YOIGU.js → chunk-7IPYXDG4.js} +8 -10
- package/dist/cloudinary.d.ts +1 -1
- package/dist/cloudinary.js +21 -8
- package/dist/helpers.d.ts +2 -15
- package/dist/helpers.js +1 -3
- package/dist/s3.d.ts +1 -0
- package/dist/s3.js +13 -3
- package/package.json +1 -1
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
// src/helpers.ts
|
|
2
2
|
import { lookup } from "mime-types";
|
|
3
|
-
function getSupabasePublicUrl(key) {
|
|
4
|
-
const bucket = process.env.PELATFORM_S3_BUCKET || "";
|
|
5
|
-
const endpoint = process.env.PELATFORM_S3_ENDPOINT || "";
|
|
6
|
-
const publicUrl = endpoint.replace(/\.storage/, "").replace(/\/storage\/v1\/s3$/, "");
|
|
7
|
-
return `${publicUrl}/storage/v1/object/public/${bucket}/${key}?v=${Date.now()}`;
|
|
8
|
-
}
|
|
9
3
|
function generateFileKey(originalName, prefix) {
|
|
10
4
|
const timestamp = Date.now();
|
|
11
5
|
const random = Math.random().toString(36).substring(2, 8);
|
|
@@ -89,10 +83,15 @@ function parseS3Url(url) {
|
|
|
89
83
|
return {};
|
|
90
84
|
}
|
|
91
85
|
}
|
|
92
|
-
function buildPublicUrl(baseUrl, bucket, key) {
|
|
93
|
-
|
|
86
|
+
function buildPublicUrl(baseUrl, bucket, key, supabase) {
|
|
87
|
+
let cleanBaseUrl;
|
|
88
|
+
cleanBaseUrl = baseUrl.replace(/\/$/, "");
|
|
94
89
|
const cleanKey = key.replace(/^\//, "");
|
|
95
|
-
|
|
90
|
+
if (supabase) {
|
|
91
|
+
cleanBaseUrl = cleanBaseUrl.replace(/\.storage/, "").replace(/\/storage\/v1\/s3$/, "");
|
|
92
|
+
cleanBaseUrl = `${cleanBaseUrl}/storage/v1/object/public`;
|
|
93
|
+
}
|
|
94
|
+
return `${cleanBaseUrl}/${bucket === "" ? "" : `${bucket}/`}${cleanKey}`;
|
|
96
95
|
}
|
|
97
96
|
function validateS3Key(key) {
|
|
98
97
|
if (!key || key.length === 0) {
|
|
@@ -384,7 +383,6 @@ function detectFileTypeFromContent(buffer) {
|
|
|
384
383
|
}
|
|
385
384
|
|
|
386
385
|
export {
|
|
387
|
-
getSupabasePublicUrl,
|
|
388
386
|
generateFileKey,
|
|
389
387
|
getMimeType,
|
|
390
388
|
validateFileSize,
|
package/dist/cloudinary.d.ts
CHANGED
|
@@ -38,12 +38,12 @@ declare class CloudinaryService implements StorageInterface {
|
|
|
38
38
|
downloadFile(key: string): Promise<DownloadResult>;
|
|
39
39
|
deleteFile(key: string): Promise<DeleteResult>;
|
|
40
40
|
deleteFiles(keys: string[]): Promise<BatchDeleteResult>;
|
|
41
|
+
listFiles(prefix?: string, maxKeys?: number): Promise<ListResult>;
|
|
41
42
|
fileExists(key: string): Promise<boolean>;
|
|
42
43
|
copyFile(sourceKey: string, destinationKey: string, metadata?: Record<string, string>): Promise<CopyResult>;
|
|
43
44
|
moveFile(sourceKey: string, destinationKey: string, metadata?: Record<string, string>): Promise<MoveResult>;
|
|
44
45
|
duplicateFile(sourceKey: string, destinationKey: string, metadata?: Record<string, string>): Promise<DuplicateResult>;
|
|
45
46
|
renameFile(sourceKey: string, destinationKey: string, metadata?: Record<string, string>): Promise<MoveResult>;
|
|
46
|
-
listFiles(prefix?: string, maxKeys?: number): Promise<ListResult>;
|
|
47
47
|
getDownloadUrl(key: string, expiresIn?: number): Promise<PresignedUrlResult>;
|
|
48
48
|
getUploadUrl(key: string, contentType?: string, expiresIn?: number): Promise<PresignedUrlResult>;
|
|
49
49
|
createFolderPath(path: string): Promise<CreateFolderResult>;
|
package/dist/cloudinary.js
CHANGED
|
@@ -32,10 +32,13 @@ var CloudinaryProvider = class {
|
|
|
32
32
|
}
|
|
33
33
|
const keyParts = options.key.split("/");
|
|
34
34
|
let folder = "";
|
|
35
|
-
let publicId =
|
|
35
|
+
let publicId = keyParts[keyParts.length - 1];
|
|
36
36
|
if (keyParts.length > 1) {
|
|
37
37
|
folder = keyParts.slice(0, -1).join("/");
|
|
38
|
-
|
|
38
|
+
}
|
|
39
|
+
const dotIndex = publicId.lastIndexOf(".");
|
|
40
|
+
if (dotIndex > 0) {
|
|
41
|
+
publicId = publicId.slice(0, dotIndex);
|
|
39
42
|
}
|
|
40
43
|
const uploadOptions = {
|
|
41
44
|
public_id: publicId,
|
|
@@ -47,8 +50,11 @@ var CloudinaryProvider = class {
|
|
|
47
50
|
if (folder) {
|
|
48
51
|
uploadOptions.folder = folder;
|
|
49
52
|
}
|
|
53
|
+
if (this.config.folder) {
|
|
54
|
+
uploadOptions.folder = `${this.config.folder}/${folder}`;
|
|
55
|
+
}
|
|
50
56
|
const result = await cloudinary.uploader.upload(fileData, uploadOptions);
|
|
51
|
-
const publicUrl = this.getPublicUrl(result.public_id);
|
|
57
|
+
const publicUrl = this.getPublicUrl(result.public_id, result.format);
|
|
52
58
|
return {
|
|
53
59
|
success: true,
|
|
54
60
|
key: result.public_id,
|
|
@@ -102,6 +108,13 @@ var CloudinaryProvider = class {
|
|
|
102
108
|
const filename = keyParts[keyParts.length - 1];
|
|
103
109
|
publicId = `${folder}/${filename}`;
|
|
104
110
|
}
|
|
111
|
+
const dotIndex = publicId.lastIndexOf(".");
|
|
112
|
+
if (dotIndex > 0) {
|
|
113
|
+
publicId = publicId.slice(0, dotIndex);
|
|
114
|
+
}
|
|
115
|
+
if (this.config.folder) {
|
|
116
|
+
publicId = `${this.config.folder}/${publicId}`;
|
|
117
|
+
}
|
|
105
118
|
let resourceType = "raw";
|
|
106
119
|
try {
|
|
107
120
|
await cloudinary.api.resource(publicId, { resource_type: "image" });
|
|
@@ -254,11 +267,11 @@ var CloudinaryProvider = class {
|
|
|
254
267
|
};
|
|
255
268
|
}
|
|
256
269
|
}
|
|
257
|
-
getPublicUrl(key) {
|
|
270
|
+
getPublicUrl(key, extension) {
|
|
258
271
|
const protocol = this.config.secure !== false ? "https" : "http";
|
|
259
272
|
const baseUrl = `${protocol}://res.cloudinary.com/${this.config.cloudName}`;
|
|
260
273
|
const publicId = key;
|
|
261
|
-
return `${baseUrl}/image/upload/${publicId}`;
|
|
274
|
+
return `${baseUrl}/image/upload/${publicId}${extension ? `.${extension}` : ""}`;
|
|
262
275
|
}
|
|
263
276
|
// Folder operations
|
|
264
277
|
async createFolder(options) {
|
|
@@ -433,6 +446,9 @@ var CloudinaryService = class {
|
|
|
433
446
|
async deleteFiles(keys) {
|
|
434
447
|
return this.batchDelete({ keys });
|
|
435
448
|
}
|
|
449
|
+
async listFiles(prefix, maxKeys) {
|
|
450
|
+
return this.list({ prefix, maxKeys });
|
|
451
|
+
}
|
|
436
452
|
async fileExists(key) {
|
|
437
453
|
const result = await this.exists(key);
|
|
438
454
|
return result.exists;
|
|
@@ -449,9 +465,6 @@ var CloudinaryService = class {
|
|
|
449
465
|
async renameFile(sourceKey, destinationKey, metadata) {
|
|
450
466
|
return this.moveFile(sourceKey, destinationKey, metadata);
|
|
451
467
|
}
|
|
452
|
-
async listFiles(prefix, maxKeys) {
|
|
453
|
-
return this.list({ prefix, maxKeys });
|
|
454
|
-
}
|
|
455
468
|
async getDownloadUrl(key, expiresIn) {
|
|
456
469
|
return this.getPresignedUrl({ key, operation: "get", expiresIn });
|
|
457
470
|
}
|
package/dist/helpers.d.ts
CHANGED
|
@@ -2,19 +2,6 @@
|
|
|
2
2
|
* Storage helper utilities
|
|
3
3
|
* Provides utility functions for file operations, MIME type detection, and path manipulation
|
|
4
4
|
*/
|
|
5
|
-
/**
|
|
6
|
-
* Generate public URL for a storage key using environment variables
|
|
7
|
-
* @param key The storage key/path
|
|
8
|
-
* @returns Constructed public URL with timestamp versioning
|
|
9
|
-
* @public
|
|
10
|
-
*
|
|
11
|
-
* @example
|
|
12
|
-
* ```typescript
|
|
13
|
-
* // Requires env vars: PELATFORM_S3_BUCKET, PELATFORM_S3_ENDPOINT
|
|
14
|
-
* const url = getSupabasePublicUrl('folder/image.png');
|
|
15
|
-
* ```
|
|
16
|
-
*/
|
|
17
|
-
declare function getSupabasePublicUrl(key: string): string;
|
|
18
5
|
/**
|
|
19
6
|
* Generate a unique file key with timestamp and random string
|
|
20
7
|
* @param originalName Original file name
|
|
@@ -234,7 +221,7 @@ declare function parseS3Url(url: string): {
|
|
|
234
221
|
* // Returns: "https://storage.example.com/assets/images/logo.png"
|
|
235
222
|
* ```
|
|
236
223
|
*/
|
|
237
|
-
declare function buildPublicUrl(baseUrl: string, bucket: string, key: string): string;
|
|
224
|
+
declare function buildPublicUrl(baseUrl: string, bucket: string, key: string, supabase?: boolean): string;
|
|
238
225
|
/**
|
|
239
226
|
* Validate S3 key format according to AWS S3 naming rules
|
|
240
227
|
* @param key S3 object key to validate
|
|
@@ -772,4 +759,4 @@ declare function validateBatchFiles(files: File[], options: {
|
|
|
772
759
|
*/
|
|
773
760
|
declare function detectFileTypeFromContent(buffer: Buffer): string;
|
|
774
761
|
|
|
775
|
-
export { base64ToBuffer, bufferToBase64, buildPublicUrl, detectFileTypeFromContent, extractS3Info, fileToBuffer, formatFileSize, generateBatchKeys, generateCacheControl, generateFileHash, generateFileKey, generateUniqueKey, getContentDisposition, getFileExtension, getFileInfo, getFileName, getMimeType, getParentPath,
|
|
762
|
+
export { base64ToBuffer, bufferToBase64, buildPublicUrl, detectFileTypeFromContent, extractS3Info, fileToBuffer, formatFileSize, generateBatchKeys, generateCacheControl, generateFileHash, generateFileKey, generateUniqueKey, getContentDisposition, getFileExtension, getFileInfo, getFileName, getMimeType, getParentPath, isAudioFile, isDocumentFile, isImageFile, isVideoFile, joinPath, normalizePath, parseS3Url, sanitizeFileName, validateBatchFiles, validateBucketName, validateFileSize, validateFileType, validateS3Config, validateS3Key };
|
package/dist/helpers.js
CHANGED
|
@@ -17,7 +17,6 @@ import {
|
|
|
17
17
|
getFileName,
|
|
18
18
|
getMimeType,
|
|
19
19
|
getParentPath,
|
|
20
|
-
getSupabasePublicUrl,
|
|
21
20
|
isAudioFile,
|
|
22
21
|
isDocumentFile,
|
|
23
22
|
isImageFile,
|
|
@@ -32,7 +31,7 @@ import {
|
|
|
32
31
|
validateFileType,
|
|
33
32
|
validateS3Config,
|
|
34
33
|
validateS3Key
|
|
35
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-7IPYXDG4.js";
|
|
36
35
|
export {
|
|
37
36
|
base64ToBuffer,
|
|
38
37
|
bufferToBase64,
|
|
@@ -52,7 +51,6 @@ export {
|
|
|
52
51
|
getFileName,
|
|
53
52
|
getMimeType,
|
|
54
53
|
getParentPath,
|
|
55
|
-
getSupabasePublicUrl,
|
|
56
54
|
isAudioFile,
|
|
57
55
|
isDocumentFile,
|
|
58
56
|
isImageFile,
|
package/dist/s3.d.ts
CHANGED
|
@@ -41,6 +41,7 @@ declare class S3Service implements StorageInterface {
|
|
|
41
41
|
downloadFile(key: string): Promise<DownloadResult>;
|
|
42
42
|
deleteFile(key: string): Promise<DeleteResult>;
|
|
43
43
|
deleteFiles(keys: string[]): Promise<BatchDeleteResult>;
|
|
44
|
+
listFiles(prefix?: string, maxKeys?: number): Promise<ListResult>;
|
|
44
45
|
fileExists(key: string): Promise<boolean>;
|
|
45
46
|
copyFile(sourceKey: string, destinationKey: string, options?: Partial<CopyOptions>): Promise<CopyResult>;
|
|
46
47
|
moveFile(sourceKey: string, destinationKey: string, options?: Partial<MoveOptions>): Promise<MoveResult>;
|
package/dist/s3.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
buildPublicUrl,
|
|
3
3
|
getMimeType
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-7IPYXDG4.js";
|
|
5
5
|
import {
|
|
6
6
|
loadS3Config
|
|
7
7
|
} from "./chunk-ZTZZCC52.js";
|
|
@@ -291,11 +291,18 @@ var FileOperations = class {
|
|
|
291
291
|
}
|
|
292
292
|
}
|
|
293
293
|
getPublicUrl(key) {
|
|
294
|
+
const isCloudflare = this.config.provider === "cloudflare-r2";
|
|
295
|
+
const isSupabase = this.config.provider === "supabase";
|
|
294
296
|
if (this.config.publicUrl) {
|
|
295
|
-
return buildPublicUrl(
|
|
297
|
+
return buildPublicUrl(
|
|
298
|
+
this.config.publicUrl,
|
|
299
|
+
isCloudflare ? "" : this.config.bucket,
|
|
300
|
+
key,
|
|
301
|
+
isSupabase
|
|
302
|
+
);
|
|
296
303
|
}
|
|
297
304
|
if (this.config.endpoint) {
|
|
298
|
-
return buildPublicUrl(this.config.endpoint, this.config.bucket, key);
|
|
305
|
+
return buildPublicUrl(this.config.endpoint, this.config.bucket, key, isSupabase);
|
|
299
306
|
}
|
|
300
307
|
return `https://${this.config.bucket}.s3.${this.config.region}.amazonaws.com/${key}`;
|
|
301
308
|
}
|
|
@@ -723,6 +730,9 @@ var S3Service = class {
|
|
|
723
730
|
async deleteFiles(keys) {
|
|
724
731
|
return this.batchDelete({ keys });
|
|
725
732
|
}
|
|
733
|
+
async listFiles(prefix, maxKeys) {
|
|
734
|
+
return this.list({ prefix, maxKeys });
|
|
735
|
+
}
|
|
726
736
|
async fileExists(key) {
|
|
727
737
|
const result = await this.exists(key);
|
|
728
738
|
return result.exists;
|