@signskart/uploader 2.0.1 → 2.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 +196 -33
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,21 +1,41 @@
|
|
|
1
|
-
|
|
1
|
+
Here is your **fully updated, production-ready README** including:
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
* ✅ Client + Server usage
|
|
4
|
+
* ✅ Proper S3 presign setup
|
|
5
|
+
* ✅ Next.js backend example
|
|
6
|
+
* ✅ Express backend example
|
|
7
|
+
* ✅ Architecture explanation
|
|
8
|
+
* ✅ Clean professional structure
|
|
9
|
+
* ✅ v2 structure with `/server` export
|
|
4
10
|
|
|
5
|
-
|
|
11
|
+
You can replace your entire README with this.
|
|
6
12
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
-
|
|
12
|
-
|
|
13
|
-
-
|
|
14
|
-
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# 🚀 @signskart/uploader
|
|
16
|
+
|
|
17
|
+
Production-grade Upload Manager SDK by **Signskart**.
|
|
18
|
+
|
|
19
|
+
A powerful, fully-typed file upload SDK with queue management, retry logic, cancellation support, concurrency control, and multi-provider architecture (S3 + Cloudinary).
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## ✨ Features
|
|
24
|
+
|
|
25
|
+
* 🚀 Upload queue system
|
|
26
|
+
* 🔁 Automatic retry with exponential backoff
|
|
27
|
+
* 📊 Real-time progress tracking
|
|
28
|
+
* ❌ Cancel uploads (AbortController support)
|
|
29
|
+
* ⚡ Concurrency control
|
|
30
|
+
* ☁ Multi-provider support (Amazon S3, Cloudinary)
|
|
31
|
+
* 🧠 Fully typed (TypeScript)
|
|
32
|
+
* 🌍 Works with React, Vue, Next.js, Vite, vanilla JS
|
|
33
|
+
* 🔐 Secure S3 presigned upload support
|
|
34
|
+
* 🖥 Optional server helper included
|
|
15
35
|
|
|
16
36
|
---
|
|
17
37
|
|
|
18
|
-
|
|
38
|
+
# 📦 Installation
|
|
19
39
|
|
|
20
40
|
```bash
|
|
21
41
|
npm install @signskart/uploader
|
|
@@ -29,19 +49,37 @@ yarn add @signskart/uploader
|
|
|
29
49
|
|
|
30
50
|
---
|
|
31
51
|
|
|
52
|
+
# 🏗 Architecture
|
|
53
|
+
|
|
54
|
+
For **Amazon S3**, uploads require a backend to generate presigned URLs.
|
|
55
|
+
|
|
56
|
+
Flow:
|
|
57
|
+
|
|
58
|
+
Frontend → Backend (presign) → S3 → Frontend uploads directly
|
|
59
|
+
|
|
60
|
+
Your AWS credentials NEVER reach the browser.
|
|
61
|
+
|
|
62
|
+
Cloudinary does NOT require backend if using unsigned preset.
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
32
66
|
# 🚀 Quick Start
|
|
33
67
|
|
|
34
|
-
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
# ☁ Using Amazon S3
|
|
71
|
+
|
|
72
|
+
## 1️⃣ Frontend Setup
|
|
35
73
|
|
|
36
74
|
```ts
|
|
37
75
|
import { UploadManager, S3Uploader } from '@signskart/uploader';
|
|
38
76
|
|
|
39
77
|
const uploader = new S3Uploader({
|
|
40
|
-
|
|
78
|
+
presignEndpoint: '/api/s3/presign-upload',
|
|
41
79
|
publicUrl: 'https://cdn.yoursite.com'
|
|
42
80
|
});
|
|
43
81
|
|
|
44
|
-
const manager = new UploadManager(uploader, 2);
|
|
82
|
+
const manager = new UploadManager(uploader, 2);
|
|
45
83
|
|
|
46
84
|
const task = manager.add({
|
|
47
85
|
file,
|
|
@@ -55,7 +93,70 @@ task.events.subscribe((state) => {
|
|
|
55
93
|
|
|
56
94
|
---
|
|
57
95
|
|
|
58
|
-
##
|
|
96
|
+
## 2️⃣ Backend Setup (Next.js Example)
|
|
97
|
+
|
|
98
|
+
```ts
|
|
99
|
+
// app/api/s3/presign-upload/route.ts
|
|
100
|
+
|
|
101
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
102
|
+
import { createS3PresignHandler } from '@signskart/uploader/server';
|
|
103
|
+
|
|
104
|
+
const generatePresignedUpload = createS3PresignHandler({
|
|
105
|
+
region: process.env.AWS_REGION!,
|
|
106
|
+
accessKeyId: process.env.AWS_KEY!,
|
|
107
|
+
secretAccessKey: process.env.AWS_SECRET!,
|
|
108
|
+
bucket: process.env.AWS_S3_BUCKET!,
|
|
109
|
+
publicUrl: process.env.NEXT_PUBLIC_S3_PUBLIC_URL!,
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
export async function POST(req: NextRequest) {
|
|
113
|
+
try {
|
|
114
|
+
const body = await req.json();
|
|
115
|
+
const result = await generatePresignedUpload(body);
|
|
116
|
+
return NextResponse.json(result);
|
|
117
|
+
} catch (error) {
|
|
118
|
+
return NextResponse.json(
|
|
119
|
+
{ error: 'Failed to generate presigned URL' },
|
|
120
|
+
{ status: 500 }
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## 3️⃣ Backend Setup (Express Example)
|
|
129
|
+
|
|
130
|
+
```ts
|
|
131
|
+
import express from 'express';
|
|
132
|
+
import { createS3PresignHandler } from '@signskart/uploader/server';
|
|
133
|
+
|
|
134
|
+
const app = express();
|
|
135
|
+
app.use(express.json());
|
|
136
|
+
|
|
137
|
+
const generatePresignedUpload = createS3PresignHandler({
|
|
138
|
+
region: process.env.AWS_REGION!,
|
|
139
|
+
accessKeyId: process.env.AWS_KEY!,
|
|
140
|
+
secretAccessKey: process.env.AWS_SECRET!,
|
|
141
|
+
bucket: process.env.AWS_S3_BUCKET!,
|
|
142
|
+
publicUrl: process.env.S3_PUBLIC_URL!,
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
app.post('/api/s3/presign-upload', async (req, res) => {
|
|
146
|
+
try {
|
|
147
|
+
const result = await generatePresignedUpload(req.body);
|
|
148
|
+
res.json(result);
|
|
149
|
+
} catch (error) {
|
|
150
|
+
res.status(500).json({ error: 'Failed to generate presigned URL' });
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
app.listen(3000);
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
# ☁ Using Cloudinary (No Backend Required)
|
|
59
160
|
|
|
60
161
|
```ts
|
|
61
162
|
import { UploadManager, CloudinaryUploader } from '@signskart/uploader';
|
|
@@ -77,18 +178,20 @@ const task = manager.add({
|
|
|
77
178
|
|
|
78
179
|
# 🧠 API Reference
|
|
79
180
|
|
|
181
|
+
---
|
|
182
|
+
|
|
80
183
|
## UploadManager
|
|
81
184
|
|
|
82
185
|
```ts
|
|
83
186
|
new UploadManager(uploader, concurrency?)
|
|
84
187
|
```
|
|
85
188
|
|
|
86
|
-
### Parameters
|
|
189
|
+
### Parameters
|
|
87
190
|
|
|
88
|
-
| Parameter
|
|
89
|
-
|
|
90
|
-
| uploader
|
|
91
|
-
| concurrency | number
|
|
191
|
+
| Parameter | Type | Default |
|
|
192
|
+
| ----------- | ------------ | -------- |
|
|
193
|
+
| uploader | BaseUploader | required |
|
|
194
|
+
| concurrency | number | 3 |
|
|
92
195
|
|
|
93
196
|
---
|
|
94
197
|
|
|
@@ -100,12 +203,12 @@ Returned from:
|
|
|
100
203
|
const task = manager.add(options);
|
|
101
204
|
```
|
|
102
205
|
|
|
103
|
-
### Properties
|
|
206
|
+
### Properties
|
|
104
207
|
|
|
105
|
-
|
|
106
|
-
|
|
208
|
+
* `task.state`
|
|
209
|
+
* `task.events.subscribe()`
|
|
107
210
|
|
|
108
|
-
### Methods
|
|
211
|
+
### Methods
|
|
109
212
|
|
|
110
213
|
```ts
|
|
111
214
|
task.start()
|
|
@@ -129,9 +232,10 @@ task.cancel()
|
|
|
129
232
|
|
|
130
233
|
# 🔁 Retry Logic
|
|
131
234
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
235
|
+
* Automatic retry
|
|
236
|
+
* Exponential backoff
|
|
237
|
+
* Default max retries: 2
|
|
238
|
+
* Cancels if AbortController triggered
|
|
135
239
|
|
|
136
240
|
---
|
|
137
241
|
|
|
@@ -147,13 +251,25 @@ task.cancel();
|
|
|
147
251
|
|
|
148
252
|
```ts
|
|
149
253
|
task.events.subscribe((state) => {
|
|
150
|
-
console.log(state.progress);
|
|
254
|
+
console.log(state.progress, state.status);
|
|
151
255
|
});
|
|
152
256
|
```
|
|
153
257
|
|
|
258
|
+
State structure:
|
|
259
|
+
|
|
260
|
+
```ts
|
|
261
|
+
{
|
|
262
|
+
id: string;
|
|
263
|
+
progress: number;
|
|
264
|
+
status: 'queued' | 'uploading' | 'success' | 'error' | 'cancelled';
|
|
265
|
+
error?: string;
|
|
266
|
+
response?: UploadResponse;
|
|
267
|
+
}
|
|
268
|
+
```
|
|
269
|
+
|
|
154
270
|
---
|
|
155
271
|
|
|
156
|
-
#
|
|
272
|
+
# ⚛ Example React Usage
|
|
157
273
|
|
|
158
274
|
```tsx
|
|
159
275
|
const handleUpload = (file: File) => {
|
|
@@ -167,13 +283,60 @@ const handleUpload = (file: File) => {
|
|
|
167
283
|
|
|
168
284
|
---
|
|
169
285
|
|
|
286
|
+
# 🔐 Security Notes (Important)
|
|
287
|
+
|
|
288
|
+
* AWS credentials must NEVER be exposed to frontend.
|
|
289
|
+
* Always generate presigned URLs server-side.
|
|
290
|
+
* Cloudinary unsigned preset must have restricted permissions.
|
|
291
|
+
* Set proper S3 bucket CORS configuration.
|
|
292
|
+
|
|
293
|
+
---
|
|
294
|
+
|
|
170
295
|
# 🛠 Requirements
|
|
171
296
|
|
|
172
|
-
|
|
173
|
-
|
|
297
|
+
* Modern browser (AbortController support)
|
|
298
|
+
* Node.js 18+ for server helper
|
|
299
|
+
* Backend endpoint for S3 presign (if using S3)
|
|
300
|
+
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
# 📦 Package Exports
|
|
304
|
+
|
|
305
|
+
Client:
|
|
306
|
+
|
|
307
|
+
```ts
|
|
308
|
+
import { UploadManager } from '@signskart/uploader';
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
Server helper:
|
|
312
|
+
|
|
313
|
+
```ts
|
|
314
|
+
import { createS3PresignHandler } from '@signskart/uploader/server';
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
---
|
|
318
|
+
|
|
319
|
+
# 📈 Roadmap
|
|
320
|
+
|
|
321
|
+
* Multipart uploads (100MB+)
|
|
322
|
+
* Image compression plugin
|
|
323
|
+
* Validation middleware
|
|
324
|
+
* Signed download URLs
|
|
325
|
+
* React hooks wrapper
|
|
174
326
|
|
|
175
327
|
---
|
|
176
328
|
|
|
177
329
|
# 📜 License
|
|
178
330
|
|
|
179
|
-
MIT © Signskart
|
|
331
|
+
MIT © Signskart
|
|
332
|
+
|
|
333
|
+
---
|
|
334
|
+
|
|
335
|
+
If you want next, I can:
|
|
336
|
+
|
|
337
|
+
* Turn this into an elite-level open source README (badges, diagrams, examples, comparison table)
|
|
338
|
+
* Prepare it for GitHub launch
|
|
339
|
+
* Write marketing description for npm
|
|
340
|
+
* Add proper semantic versioning strategy
|
|
341
|
+
|
|
342
|
+
Tell me your next move.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@signskart/uploader",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.2",
|
|
4
4
|
"description": "Production-grade upload manager SDK with queue, progress tracking, retry logic, cancellation, and multi-provider support (S3, Cloudinary).",
|
|
5
5
|
"author": "Signskart",
|
|
6
6
|
"license": "MIT",
|