@pelatform/storage 1.0.1 → 1.0.2
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/README.md +253 -5
- package/dist/cloudinary.d.ts +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/s3.d.ts +1 -1
- package/dist/s3.js +3 -3
- package/dist/{storage-interface-UizTndyU.d.ts → storage-interface-BKeDAlGP.d.ts} +1 -1
- package/package.json +16 -15
- package/LICENSE +0 -21
package/README.md
CHANGED
|
@@ -1,10 +1,258 @@
|
|
|
1
1
|
# @pelatform/storage
|
|
2
2
|
|
|
3
|
-
A comprehensive storage utilities for SaaS applications. This package provides a unified interface for working with various storage providers including AWS S3, Cloudflare R2, MinIO, DigitalOcean Spaces, Supabase, and Cloudinary Storage.
|
|
4
|
-
|
|
5
3
|
[](https://www.npmjs.com/package/@pelatform/storage)
|
|
6
|
-
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
|
|
6
|
+
A comprehensive storage utilities package for SaaS applications. This package provides a unified interface for working with various storage providers including AWS S3, Cloudflare R2, MinIO, DigitalOcean Spaces, Supabase Storage, and Cloudinary.
|
|
7
|
+
|
|
8
|
+
## Installation
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm install @pelatform/storage
|
|
12
|
+
# or
|
|
13
|
+
bun add @pelatform/storage
|
|
14
|
+
|
|
15
|
+
# Install peer dependencies for the provider(s) you need
|
|
16
|
+
npm install @aws-sdk/client-s3 @aws-sdk/s3-request-presigner # For S3-compatible providers
|
|
17
|
+
npm install cloudinary # For Cloudinary
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Quick Start
|
|
21
|
+
|
|
22
|
+
### S3-Compatible Storage (AWS, R2, MinIO, etc.)
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
import { S3Storage } from "@pelatform/storage/s3";
|
|
26
|
+
|
|
27
|
+
const storage = new S3Storage({
|
|
28
|
+
provider: "aws", // or 'cloudflare-r2', 'minio', 'digitalocean', 'supabase'
|
|
29
|
+
region: "us-east-1",
|
|
30
|
+
bucket: "my-bucket",
|
|
31
|
+
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
|
|
32
|
+
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
// Upload a file
|
|
36
|
+
await storage.upload({
|
|
37
|
+
key: "documents/file.pdf",
|
|
38
|
+
file: fileBuffer,
|
|
39
|
+
contentType: "application/pdf",
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
// Download a file
|
|
43
|
+
const result = await storage.download({ key: "documents/file.pdf" });
|
|
44
|
+
|
|
45
|
+
// Generate a presigned URL (temporary access)
|
|
46
|
+
const url = await storage.getPresignedUrl({
|
|
47
|
+
key: "documents/file.pdf",
|
|
48
|
+
operation: "get",
|
|
49
|
+
expiresIn: 3600, // 1 hour
|
|
50
|
+
});
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Cloudinary Storage
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
import { CloudinaryStorage } from "@pelatform/storage/cloudinary";
|
|
57
|
+
|
|
58
|
+
const storage = new CloudinaryStorage({
|
|
59
|
+
provider: "cloudinary",
|
|
60
|
+
cloudName: process.env.CLOUDINARY_CLOUD_NAME,
|
|
61
|
+
apiKey: process.env.CLOUDINARY_API_KEY,
|
|
62
|
+
apiSecret: process.env.CLOUDINARY_API_SECRET,
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
// Upload an image
|
|
66
|
+
await storage.upload({
|
|
67
|
+
key: "images/photo.jpg",
|
|
68
|
+
file: imageBuffer,
|
|
69
|
+
contentType: "image/jpeg",
|
|
70
|
+
});
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Key Features
|
|
74
|
+
|
|
75
|
+
- **Unified Interface**: Single API for multiple storage providers
|
|
76
|
+
- **S3-Compatible Providers**: AWS S3, Cloudflare R2, MinIO, DigitalOcean Spaces, Supabase Storage
|
|
77
|
+
- **Cloudinary Support**: Image and media management with built-in optimizations
|
|
78
|
+
- **File Operations**: Upload, download, delete, copy, move, and check existence
|
|
79
|
+
- **Folder Operations**: Create, delete, list, and manage folders
|
|
80
|
+
- **Presigned URLs**: Generate time-limited access URLs for secure sharing
|
|
81
|
+
- **Public URLs**: Get public access URLs with optional CDN support
|
|
82
|
+
- **Type-Safe**: Full TypeScript support with comprehensive types
|
|
83
|
+
- **Flexible Configuration**: Support for custom endpoints and CDN URLs
|
|
84
|
+
|
|
85
|
+
## Supported Providers
|
|
86
|
+
|
|
87
|
+
### S3-Compatible
|
|
88
|
+
|
|
89
|
+
- **AWS S3** - Amazon's object storage service
|
|
90
|
+
- **Cloudflare R2** - Cloudflare's S3-compatible storage (no egress fees)
|
|
91
|
+
- **MinIO** - Self-hosted S3-compatible storage
|
|
92
|
+
- **DigitalOcean Spaces** - DigitalOcean's object storage
|
|
93
|
+
- **Supabase Storage** - Supabase's S3-compatible storage
|
|
94
|
+
|
|
95
|
+
### Other Providers
|
|
96
|
+
|
|
97
|
+
- **Cloudinary** - Image and video management platform
|
|
98
|
+
|
|
99
|
+
## Configuration
|
|
100
|
+
|
|
101
|
+
### AWS S3
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
const storage = new S3Storage({
|
|
105
|
+
provider: "aws",
|
|
106
|
+
region: "us-east-1",
|
|
107
|
+
bucket: "my-bucket",
|
|
108
|
+
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
|
|
109
|
+
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
|
|
110
|
+
publicUrl: "https://cdn.example.com", // Optional CDN URL
|
|
111
|
+
});
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Cloudflare R2
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
const storage = new S3Storage({
|
|
118
|
+
provider: "cloudflare-r2",
|
|
119
|
+
region: "auto",
|
|
120
|
+
bucket: "my-bucket",
|
|
121
|
+
accessKeyId: process.env.R2_ACCESS_KEY_ID,
|
|
122
|
+
secretAccessKey: process.env.R2_SECRET_ACCESS_KEY,
|
|
123
|
+
endpoint: "https://<account-id>.r2.cloudflarestorage.com",
|
|
124
|
+
});
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### MinIO
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
const storage = new S3Storage({
|
|
131
|
+
provider: "minio",
|
|
132
|
+
region: "us-east-1",
|
|
133
|
+
bucket: "my-bucket",
|
|
134
|
+
accessKeyId: "minioadmin",
|
|
135
|
+
secretAccessKey: "minioadmin",
|
|
136
|
+
endpoint: "http://localhost:9000",
|
|
137
|
+
forcePathStyle: true, // Required for MinIO
|
|
138
|
+
});
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Basic Usage
|
|
142
|
+
|
|
143
|
+
### File Operations
|
|
144
|
+
|
|
145
|
+
```typescript
|
|
146
|
+
// Upload with options
|
|
147
|
+
await storage.upload({
|
|
148
|
+
key: "uploads/document.pdf",
|
|
149
|
+
file: buffer,
|
|
150
|
+
contentType: "application/pdf",
|
|
151
|
+
metadata: { userId: "123", category: "documents" },
|
|
152
|
+
cacheControl: "max-age=31536000",
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
// Download file
|
|
156
|
+
const { content, metadata } = await storage.download({
|
|
157
|
+
key: "uploads/document.pdf",
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
// Check if file exists
|
|
161
|
+
const exists = await storage.exists("uploads/document.pdf");
|
|
162
|
+
|
|
163
|
+
// Delete file
|
|
164
|
+
await storage.delete({ key: "uploads/document.pdf" });
|
|
165
|
+
|
|
166
|
+
// Copy file
|
|
167
|
+
await storage.copy({
|
|
168
|
+
sourceKey: "uploads/old.pdf",
|
|
169
|
+
destinationKey: "uploads/new.pdf",
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
// Move file
|
|
173
|
+
await storage.move({
|
|
174
|
+
sourceKey: "uploads/temp.pdf",
|
|
175
|
+
destinationKey: "uploads/final.pdf",
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
// List files
|
|
179
|
+
const files = await storage.list({
|
|
180
|
+
prefix: "uploads/",
|
|
181
|
+
maxKeys: 100,
|
|
182
|
+
});
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Folder Operations
|
|
186
|
+
|
|
187
|
+
```typescript
|
|
188
|
+
// Create folder
|
|
189
|
+
await storage.createFolder({ path: "documents/" });
|
|
190
|
+
|
|
191
|
+
// Delete folder (recursive)
|
|
192
|
+
await storage.deleteFolder({
|
|
193
|
+
path: "documents/",
|
|
194
|
+
recursive: true,
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
// List folders
|
|
198
|
+
const folders = await storage.listFolders({
|
|
199
|
+
prefix: "uploads/",
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
// Check if folder exists
|
|
203
|
+
const exists = await storage.folderExists("documents/");
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### URL Generation
|
|
207
|
+
|
|
208
|
+
```typescript
|
|
209
|
+
// Get public URL
|
|
210
|
+
const publicUrl = storage.getPublicUrl("images/photo.jpg");
|
|
211
|
+
|
|
212
|
+
// Generate presigned URL for download
|
|
213
|
+
const downloadUrl = await storage.getPresignedUrl({
|
|
214
|
+
key: "documents/private.pdf",
|
|
215
|
+
operation: "get",
|
|
216
|
+
expiresIn: 3600, // 1 hour
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
// Generate presigned URL for upload
|
|
220
|
+
const uploadUrl = await storage.getPresignedUrl({
|
|
221
|
+
key: "uploads/new-file.pdf",
|
|
222
|
+
operation: "put",
|
|
223
|
+
expiresIn: 900, // 15 minutes
|
|
224
|
+
contentType: "application/pdf",
|
|
225
|
+
});
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
## API Reference
|
|
229
|
+
|
|
230
|
+
### File Operations
|
|
231
|
+
|
|
232
|
+
- `upload(options)` - Upload a file
|
|
233
|
+
- `download(options)` - Download a file
|
|
234
|
+
- `delete(options)` - Delete a file
|
|
235
|
+
- `exists(key)` - Check if file exists
|
|
236
|
+
- `copy(options)` - Copy a file
|
|
237
|
+
- `move(options)` - Move a file
|
|
238
|
+
- `list(options)` - List files with prefix
|
|
239
|
+
- `getPresignedUrl(options)` - Generate presigned URL
|
|
240
|
+
- `getPublicUrl(key)` - Get public URL
|
|
241
|
+
|
|
242
|
+
### Folder Operations
|
|
243
|
+
|
|
244
|
+
- `createFolder(options)` - Create a folder
|
|
245
|
+
- `deleteFolder(options)` - Delete a folder
|
|
246
|
+
- `listFolders(options)` - List folders
|
|
247
|
+
- `folderExists(path)` - Check if folder exists
|
|
248
|
+
|
|
249
|
+
## Links
|
|
250
|
+
|
|
251
|
+
- [npm Package](https://www.npmjs.com/package/@pelatform/storage)
|
|
252
|
+
- [Contributing Guide](../../CONTRIBUTING.md)
|
|
253
|
+
- [Code of Conduct](../../CODE_OF_CONDUCT.md)
|
|
254
|
+
- [License](../../LICENSE)
|
|
7
255
|
|
|
8
|
-
##
|
|
256
|
+
## License
|
|
9
257
|
|
|
10
|
-
|
|
258
|
+
MIT © [Pelatform Inc.](../../LICENSE)
|
package/dist/cloudinary.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { S as StorageInterface, C as CloudinaryConfig, U as UploadOptions, a as UploadResult, D as DownloadOptions, b as DownloadResult, c as DeleteOptions, d as DeleteResult, B as BatchDeleteOptions, e as BatchDeleteResult, L as ListOptions, f as ListResult, E as ExistsResult, g as CopyOptions, h as CopyResult, M as MoveOptions, i as MoveResult, j as DuplicateOptions, k as DuplicateResult, P as PresignedUrlOptions, l as PresignedUrlResult, m as CreateFolderOptions, n as CreateFolderResult, o as DeleteFolderOptions, p as DeleteFolderResult, q as ListFoldersOptions, r as ListFoldersResult, F as FolderExistsResult, R as RenameFolderOptions, s as RenameFolderResult, t as CopyFolderOptions, u as CopyFolderResult } from './storage-interface-BKeDAlGP.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Cloudinary storage service implementation
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export { B as BatchDeleteOptions,
|
|
1
|
+
import { v as S3Config, C as CloudinaryConfig, w as StorageConfig } from './storage-interface-BKeDAlGP.js';
|
|
2
|
+
export { B as BatchDeleteOptions, e as BatchDeleteResult, t as CopyFolderOptions, u as CopyFolderResult, g as CopyOptions, h as CopyResult, m as CreateFolderOptions, n as CreateFolderResult, o as DeleteFolderOptions, p as DeleteFolderResult, c as DeleteOptions, d as DeleteResult, D as DownloadOptions, b as DownloadResult, j as DuplicateOptions, k as DuplicateResult, E as ExistsResult, z as FileInfo, F as FolderExistsResult, A as FolderInfo, q as ListFoldersOptions, r as ListFoldersResult, L as ListOptions, f as ListResult, M as MoveOptions, i as MoveResult, P as PresignedUrlOptions, l as PresignedUrlResult, R as RenameFolderOptions, s as RenameFolderResult, x as S3ProviderType, S as StorageInterface, y as StorageProvider, U as UploadOptions, a as UploadResult } from './storage-interface-BKeDAlGP.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Storage configuration from environment variables
|
package/dist/s3.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { S as StorageInterface, v as S3Config, U as UploadOptions, a as UploadResult, D as DownloadOptions, b as DownloadResult, c as DeleteOptions, d as DeleteResult, B as BatchDeleteOptions, e as BatchDeleteResult, L as ListOptions, f as ListResult, E as ExistsResult, g as CopyOptions, h as CopyResult, M as MoveOptions, i as MoveResult, j as DuplicateOptions, k as DuplicateResult, P as PresignedUrlOptions, l as PresignedUrlResult, m as CreateFolderOptions, n as CreateFolderResult, o as DeleteFolderOptions, p as DeleteFolderResult, q as ListFoldersOptions, r as ListFoldersResult, F as FolderExistsResult, R as RenameFolderOptions, s as RenameFolderResult, t as CopyFolderOptions, u as CopyFolderResult } from './storage-interface-BKeDAlGP.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* S3 storage service implementation
|
package/dist/s3.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
loadS3Config
|
|
3
|
-
} from "./chunk-ZTZZCC52.js";
|
|
4
1
|
import {
|
|
5
2
|
buildPublicUrl,
|
|
6
3
|
getMimeType
|
|
7
4
|
} from "./chunk-KJMGBTTL.js";
|
|
5
|
+
import {
|
|
6
|
+
loadS3Config
|
|
7
|
+
} from "./chunk-ZTZZCC52.js";
|
|
8
8
|
|
|
9
9
|
// src/providers/s3.ts
|
|
10
10
|
import { S3Client } from "@aws-sdk/client-s3";
|
|
@@ -313,4 +313,4 @@ interface StorageInterface {
|
|
|
313
313
|
copyFolder(options: CopyFolderOptions): Promise<CopyFolderResult>;
|
|
314
314
|
}
|
|
315
315
|
|
|
316
|
-
export type {
|
|
316
|
+
export type { FolderInfo as A, BatchDeleteOptions as B, CloudinaryConfig as C, DownloadOptions as D, ExistsResult as E, FolderExistsResult as F, ListOptions as L, MoveOptions as M, PresignedUrlOptions as P, RenameFolderOptions as R, StorageInterface as S, UploadOptions as U, UploadResult as a, DownloadResult as b, DeleteOptions as c, DeleteResult as d, BatchDeleteResult as e, ListResult as f, CopyOptions as g, CopyResult as h, MoveResult as i, DuplicateOptions as j, DuplicateResult as k, PresignedUrlResult as l, CreateFolderOptions as m, CreateFolderResult as n, DeleteFolderOptions as o, DeleteFolderResult as p, ListFoldersOptions as q, ListFoldersResult as r, RenameFolderResult as s, CopyFolderOptions as t, CopyFolderResult as u, S3Config as v, StorageConfig as w, S3ProviderType as x, StorageProvider as y, FileInfo as z };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pelatform/storage",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Storage utilities for SaaS applications.",
|
|
5
5
|
"author": "Pelatform Dev",
|
|
6
6
|
"license": "MIT",
|
|
@@ -26,10 +26,15 @@
|
|
|
26
26
|
"default": "./dist/helpers.js"
|
|
27
27
|
}
|
|
28
28
|
},
|
|
29
|
-
"
|
|
29
|
+
"scripts": {
|
|
30
|
+
"clean": "rimraf dist",
|
|
31
|
+
"clean:all": "rimraf .turbo dist node_modules",
|
|
32
|
+
"dev": "tsup --watch",
|
|
33
|
+
"build": "tsup",
|
|
34
|
+
"types:check": "tsc --noEmit"
|
|
35
|
+
},
|
|
30
36
|
"files": [
|
|
31
|
-
"dist
|
|
32
|
-
"README.md"
|
|
37
|
+
"dist"
|
|
33
38
|
],
|
|
34
39
|
"keywords": [
|
|
35
40
|
"pelatform",
|
|
@@ -44,15 +49,18 @@
|
|
|
44
49
|
"mime-types": "^3.0.2"
|
|
45
50
|
},
|
|
46
51
|
"devDependencies": {
|
|
52
|
+
"@aws-sdk/client-s3": "^3.939.0",
|
|
53
|
+
"@aws-sdk/s3-request-presigner": "^3.939.0",
|
|
47
54
|
"@types/mime-types": "^3.0.1",
|
|
48
55
|
"@types/node": "^24.10.1",
|
|
56
|
+
"cloudinary": "^2.8.0",
|
|
49
57
|
"tsup": "^8.5.1",
|
|
50
58
|
"typescript": "^5.9.3"
|
|
51
59
|
},
|
|
52
60
|
"peerDependencies": {
|
|
53
|
-
"@aws-sdk/client-s3": ">=3.
|
|
54
|
-
"@aws-sdk/s3-request-presigner": ">=3.
|
|
55
|
-
"cloudinary": ">=2.
|
|
61
|
+
"@aws-sdk/client-s3": ">=3.8.0",
|
|
62
|
+
"@aws-sdk/s3-request-presigner": ">=3.8.0",
|
|
63
|
+
"cloudinary": ">=2.8.0"
|
|
56
64
|
},
|
|
57
65
|
"peerDependenciesMeta": {
|
|
58
66
|
"@aws-sdk/client-s3": {
|
|
@@ -67,12 +75,5 @@
|
|
|
67
75
|
},
|
|
68
76
|
"publishConfig": {
|
|
69
77
|
"access": "public"
|
|
70
|
-
},
|
|
71
|
-
"scripts": {
|
|
72
|
-
"clean": "rimraf dist",
|
|
73
|
-
"clean:all": "rimraf .turbo dist node_modules",
|
|
74
|
-
"dev": "tsup --watch",
|
|
75
|
-
"build": "tsup --clean",
|
|
76
|
-
"types:check": "tsc --noEmit"
|
|
77
78
|
}
|
|
78
|
-
}
|
|
79
|
+
}
|
package/LICENSE
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2025 Pelatform
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|