mbkbucket 4.0.0 โ 4.1.0
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/.env.example +16 -15
- package/README.md +613 -561
- package/index.js +36 -33
- package/lib/cli.js +239 -239
- package/lib/public/bucketadmin.css +2042 -2042
- package/lib/public/bucketadmin.js +1844 -1622
- package/lib/public/mbkbucket-helper-demo.html +0 -58
- package/lib/public/mbkbucket-helper.js +1 -9
- package/lib/src/config/validation.js +91 -86
- package/lib/src/controllers/api.controller.js +486 -459
- package/lib/src/controllers/dashboard.controller.js +69 -69
- package/lib/src/controllers/info.controller.js +13 -13
- package/lib/src/controllers/view.controller.js +234 -233
- package/lib/src/core/metrics.js +134 -0
- package/lib/src/core/storage/capabilities.js +58 -0
- package/lib/src/core/storage/errors.js +0 -5
- package/lib/src/core/storage/gdrive-auth.js +0 -36
- package/lib/src/core/storage/gdrive-provider.js +101 -43
- package/lib/src/core/storage/index.js +4 -1
- package/lib/src/core/storage/local-provider.js +507 -0
- package/lib/src/core/storage/models.js +90 -50
- package/lib/src/core/storage/path-strategy.js +14 -1
- package/lib/src/core/storage/s3-provider.js +17 -37
- package/lib/src/core/storage/storage-manager.js +70 -50
- package/lib/src/core/storage/storage-provider.js +49 -120
- package/lib/src/middleware/bucket-resolver.js +37 -37
- package/lib/src/routes/api.routes.js +4 -1
- package/lib/src/routes/index.js +60 -60
- package/lib/src/routes/view.routes.js +28 -28
- package/lib/src/services/s3.service.js +42 -42
- package/lib/src/services/storage.service.js +311 -213
- package/lib/src/utils/cleanup-scheduler.js +91 -0
- package/lib/src/utils/errors.js +56 -56
- package/lib/src/utils/helpers.js +6 -6
- package/package.json +3 -5
- package/views/bucket.hbs +0 -5
- package/views/bucketadmin_move_modal.hbs +35 -35
- package/views/bucketadmin_preview_modal.hbs +108 -108
- package/views/bucketadmincontent.hbs +193 -193
- package/views/mbkbucket_info.hbs +134 -134
package/README.md
CHANGED
|
@@ -1,562 +1,614 @@
|
|
|
1
|
-
# mbkbucket
|
|
2
|
-
|
|
3
|
-
> Flexible S3, Cloudflare R2,
|
|
4
|
-
|
|
5
|
-
[](https://www.npmjs.com/package/mbkbucket)
|
|
6
|
-
[](https://www.npmjs.com/package/mbkbucket)
|
|
7
|
-
[](LICENSE)
|
|
8
|
-
[](https://nodejs.org/)
|
|
9
|
-
[](tests)
|
|
10
|
-
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
## Table of Contents
|
|
14
|
-
|
|
15
|
-
- [What's New in v4.
|
|
16
|
-
- [Installation](#installation-)
|
|
17
|
-
- [Quick Start](#quick-start-)
|
|
18
|
-
- [Supported Storage Providers](#supported-storage-providers-)
|
|
19
|
-
- [CLI Usage](#cli-usage-)
|
|
20
|
-
- [Library API](#library-api-)
|
|
21
|
-
- [File Operations](#file-operations)
|
|
22
|
-
- [Folder, Copy & Move Operations](#folder-copy--move-operations)
|
|
23
|
-
- [Multipart Upload](#multipart-upload)
|
|
24
|
-
- [Storage & Connection Management](#storage--connection-management)
|
|
25
|
-
- [Storage Core & Custom Drivers](#storage-core--custom-drivers)
|
|
26
|
-
- [
|
|
27
|
-
- [
|
|
28
|
-
- [
|
|
29
|
-
- [
|
|
30
|
-
- [Express
|
|
31
|
-
|
|
32
|
-
- [
|
|
33
|
-
- [
|
|
34
|
-
- [
|
|
35
|
-
- [
|
|
36
|
-
|
|
37
|
-
- [
|
|
38
|
-
- [
|
|
39
|
-
- [
|
|
40
|
-
- [
|
|
41
|
-
- [
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
- **
|
|
49
|
-
- **
|
|
50
|
-
- **
|
|
51
|
-
- **
|
|
52
|
-
- **
|
|
53
|
-
- **
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
'
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
await
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
app
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
mbkbucket
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
|
150
|
-
|
|
151
|
-
| **
|
|
152
|
-
| **
|
|
153
|
-
| **
|
|
154
|
-
| **
|
|
155
|
-
| **
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
|
180
|
-
|
|
181
|
-
| `--
|
|
182
|
-
| `--
|
|
183
|
-
| `--
|
|
184
|
-
| `--
|
|
185
|
-
| `--
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
|
210
|
-
|
|
211
|
-
| `
|
|
212
|
-
| `
|
|
213
|
-
| `
|
|
214
|
-
| `
|
|
215
|
-
| `
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
|
223
|
-
|
|
224
|
-
| `
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
|
234
|
-
|
|
235
|
-
| `
|
|
236
|
-
| `
|
|
237
|
-
| `
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
|
331
|
-
|
|
332
|
-
|
|
|
333
|
-
|
|
|
334
|
-
|
|
|
335
|
-
|
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
|
340
|
-
|
|
341
|
-
|
|
|
342
|
-
|
|
|
343
|
-
|
|
|
344
|
-
|
|
|
345
|
-
|
|
|
346
|
-
|
|
|
347
|
-
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
|
377
|
-
|
|
378
|
-
| `
|
|
379
|
-
| `
|
|
380
|
-
| `
|
|
381
|
-
| `
|
|
382
|
-
| `
|
|
383
|
-
| `
|
|
384
|
-
| `
|
|
385
|
-
| `
|
|
386
|
-
| `
|
|
387
|
-
| `
|
|
388
|
-
| `
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
```
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
1
|
+
# mbkbucket
|
|
2
|
+
|
|
3
|
+
> Flexible S3, Cloudflare R2, Google Drive, and Local Disk storage management โ library, Express router, dashboard, and standalone server CLI for mbktech.org applications.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/mbkbucket)
|
|
6
|
+
[](https://www.npmjs.com/package/mbkbucket)
|
|
7
|
+
[](LICENSE)
|
|
8
|
+
[](https://nodejs.org/)
|
|
9
|
+
[](tests)
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Table of Contents
|
|
14
|
+
|
|
15
|
+
- [What's New in v4.1.0](#whats-new-in-v410-)
|
|
16
|
+
- [Installation](#installation-)
|
|
17
|
+
- [Quick Start](#quick-start-)
|
|
18
|
+
- [Supported Storage Providers](#supported-storage-providers-)
|
|
19
|
+
- [CLI Usage](#cli-usage-)
|
|
20
|
+
- [Library API](#library-api-)
|
|
21
|
+
- [File Operations](#file-operations)
|
|
22
|
+
- [Folder, Copy & Move Operations](#folder-copy--move-operations)
|
|
23
|
+
- [Multipart Upload & Cleanup Scheduler](#multipart-upload--cleanup-scheduler)
|
|
24
|
+
- [Storage & Connection Management](#storage--connection-management)
|
|
25
|
+
- [Storage Core & Custom Drivers](#storage-core--custom-drivers)
|
|
26
|
+
- [Metrics & Observability](#metrics--observability)
|
|
27
|
+
- [Google Drive Authentication Helpers](#google-drive-authentication-helpers)
|
|
28
|
+
- [Key Prefixing & App Isolation](#key-prefixing--app-isolation)
|
|
29
|
+
- [Config & Diagnostics](#config--diagnostics)
|
|
30
|
+
- [Express Integration](#express-integration)
|
|
31
|
+
- [Express Router & HTTP API](#express-router--http-api-)
|
|
32
|
+
- [Endpoints](#endpoints)
|
|
33
|
+
- [Host-Controlled Permissions](#host-controlled-permissions)
|
|
34
|
+
- [Templates & Views](#templates--views)
|
|
35
|
+
- [Frontend Helper Client](#frontend-helper-client-)
|
|
36
|
+
- [Environment Configuration](#environment-configuration-)
|
|
37
|
+
- [BucketConnection](#bucketconnection-required)
|
|
38
|
+
- [mbkautheVar](#mbkauthevar-required)
|
|
39
|
+
- [mbkbucketVar](#mbkbucketvar-optional)
|
|
40
|
+
- [Automated Tests](#automated-tests-)
|
|
41
|
+
- [Contact & Support](#contact--support)
|
|
42
|
+
- [License](#license)
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## What's New in v4.1.0 ๐
|
|
47
|
+
|
|
48
|
+
- **Cross-Platform Local Disk Provider (`LocalStorageProvider`)**: First-class local filesystem storage provider with full Windows, Linux, and macOS compatibility, path sanitization against directory traversal, quota enforcement (`maxBytes`), recursive directory scanning, and byte-range streaming.
|
|
49
|
+
- **Metrics & Observability Registry (`MetricsRegistry`)**: Built-in Prometheus-compatible metrics registry (`metricsRegistry`) and endpoints (`/mbkbucket/api/metrics` and `/mbkbucket/metrics`) tracking operation counts, duration summaries, transferred byte throughput, error counts, and active multipart sessions.
|
|
50
|
+
- **Event-Driven Lifecycle & Storage Orchestration**: `StorageManager` now extends `EventEmitter`, broadcasting real-time lifecycle events (`file:uploaded`, `file:deleted`, `files:deleted`, `folder:created`, `folder:deleted`, `connection:registered`, `driver:registered`) with full lifecycle methods (`initialize()`, `dispose()`, `ping()`).
|
|
51
|
+
- **Automated Incomplete Multipart Cleanup Scheduler (`CleanupScheduler`)**: Background cron-like scheduler (`cleanupScheduler`) to automatically identify and abort abandoned multipart upload chunks older than a configurable threshold.
|
|
52
|
+
- **RFC 7233 Open-Ended Byte-Range Streaming**: High-performance range streaming for PDF documents (Chrome PDF viewer, Firefox PDF.js), HTML5 video, and audio players (`206 Partial Content`) with proper inline content disposition.
|
|
53
|
+
- **Native Google Drive & S3/R2 Enhancements**: Unified error handling, exponential backoff retries on rate limits (429/503), and automatic driver inference for local paths.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Installation ๐ฆ
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
npm install mbkbucket
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Quick Start ๐
|
|
66
|
+
|
|
67
|
+
### As a Library
|
|
68
|
+
|
|
69
|
+
```js
|
|
70
|
+
import { uploadFile, downloadFile, listfiles, copyFile, moveFile, createFolder, deleteFile, storageManager, metricsRegistry } from 'mbkbucket';
|
|
71
|
+
|
|
72
|
+
// Upload a file to default storage (or specify connectionName / bucketName)
|
|
73
|
+
const upload = await uploadFile(
|
|
74
|
+
'documents/invoice.pdf',
|
|
75
|
+
fileBuffer,
|
|
76
|
+
'application/pdf',
|
|
77
|
+
{ connectionName: 'Local_Disk' } // or 'R2_Bucket', 'Google_Drive'
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
// List files and directories
|
|
81
|
+
const { Contents, CommonPrefixes } = await listfiles('documents/', {
|
|
82
|
+
delimiter: '/',
|
|
83
|
+
maxKeys: 100
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
// Copy or move files
|
|
87
|
+
await copyFile('documents/invoice.pdf', 'backup/invoice.pdf');
|
|
88
|
+
await moveFile('documents/invoice.pdf', 'archive/invoice-2026.pdf');
|
|
89
|
+
|
|
90
|
+
// Create a folder marker
|
|
91
|
+
await createFolder('projects/2026');
|
|
92
|
+
|
|
93
|
+
// Download a file stream (with optional byte ranges for streaming)
|
|
94
|
+
const { Body, ContentType, ContentLength } = await downloadFile('archive/invoice-2026.pdf', {
|
|
95
|
+
range: 'bytes=0-1048575'
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
// Listen to storage lifecycle events
|
|
99
|
+
storageManager.on('file:uploaded', ({ key, provider, size }) => {
|
|
100
|
+
console.log(`[Event] File uploaded: ${key} (${size} bytes) to ${provider}`);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
// Check health across active connections
|
|
104
|
+
const health = await storageManager.checkHealth('Local_Disk');
|
|
105
|
+
console.log('Storage status:', health.status);
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### As Express Middleware
|
|
109
|
+
|
|
110
|
+
```js
|
|
111
|
+
import express from 'express';
|
|
112
|
+
import { createBucketRouter } from 'mbkbucket';
|
|
113
|
+
import { sessRole, sessPerm } from 'mbkauthe';
|
|
114
|
+
|
|
115
|
+
const app = express();
|
|
116
|
+
|
|
117
|
+
// Mount the bucket dashboard and API under /mbkbucket
|
|
118
|
+
app.use(createBucketRouter({
|
|
119
|
+
authorization: {
|
|
120
|
+
view: sessRole('admin'),
|
|
121
|
+
upload: sessPerm('storage.upload'),
|
|
122
|
+
delete: sessRole('superadmin'),
|
|
123
|
+
},
|
|
124
|
+
publiViewEnabled: true,
|
|
125
|
+
}));
|
|
126
|
+
|
|
127
|
+
app.listen(3004, () => {
|
|
128
|
+
console.log('Server running on http://localhost:3004');
|
|
129
|
+
});
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### As a Standalone Application
|
|
133
|
+
|
|
134
|
+
```js
|
|
135
|
+
import mbkbucket from 'mbkbucket';
|
|
136
|
+
|
|
137
|
+
// mbkbucket is a pre-configured Express app with mbkauthe sessions, views, and routes
|
|
138
|
+
mbkbucket.listen(3004, () => {
|
|
139
|
+
console.log('mbkbucket running on http://localhost:3004/mbkbucket');
|
|
140
|
+
});
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## Supported Storage Providers ๐๏ธ
|
|
146
|
+
|
|
147
|
+
mbkbucket v4.1.0 supports multiple object and file storage providers simultaneously:
|
|
148
|
+
|
|
149
|
+
| Provider | Type Identifier | Features / Capabilities |
|
|
150
|
+
|---|---|---|
|
|
151
|
+
| **Local Filesystem** | `local` / `local-disk` / `disk` | Cross-platform (Win/Linux/macOS), local directory storage, quota limits, range streaming, zero cloud latency |
|
|
152
|
+
| **AWS S3** | `s3` | Multipart upload, range streaming, server-side copy/move |
|
|
153
|
+
| **Cloudflare R2** | `s3` / `r2` | S3-compatible, zero egress fees, multipart upload, range streaming |
|
|
154
|
+
| **Google Drive** | `gdrive` / `google-drive` | OAuth 2.0 & Service Account auth, native folder hierarchy, direct download URLs, range requests |
|
|
155
|
+
| **MinIO** | `s3` / `minio` | Self-hosted S3-compatible storage, multipart upload |
|
|
156
|
+
| **IDrive e2** | `s3` | S3-compatible high-performance object storage |
|
|
157
|
+
| **Backblaze B2** | `s3` | S3-compatible API endpoints |
|
|
158
|
+
| **DigitalOcean Spaces** | `s3` | S3-compatible object storage |
|
|
159
|
+
| **Custom Drivers** | Any custom name | Register via `storageManager.registerDriver(type, factory)` |
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## CLI Usage ๐ป
|
|
164
|
+
|
|
165
|
+
mbkbucket includes a standalone CLI server runner with built-in configuration verification, port binding, and browser launching.
|
|
166
|
+
|
|
167
|
+
### Run Standalone Server
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
# Run with npx without installation
|
|
171
|
+
npx mbkbucket
|
|
172
|
+
|
|
173
|
+
# Or after installing globally or in your repository
|
|
174
|
+
mbkbucket
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### CLI Options
|
|
178
|
+
|
|
179
|
+
| Option | Shorthand | Description |
|
|
180
|
+
|---|---|---|
|
|
181
|
+
| `--port <number>` | `-p` | Port to listen on (default: `3004` or `$PORT`) |
|
|
182
|
+
| `--host <host>` | `-H` | Host address to bind to (default: `0.0.0.0` or `$HOST`) |
|
|
183
|
+
| `--app <name>` | `-a` | Override `APP_NAME` for bucket key prefix isolation |
|
|
184
|
+
| `--bucket <name>` | `-b` | Override default bucket / storage connection name |
|
|
185
|
+
| `--env <path>` | `-e` | Load environment variables from a custom `.env` file |
|
|
186
|
+
| `--dev` | `-d` | Run in development mode (`NODE_ENV=dev`) |
|
|
187
|
+
| `--open` | `-o` | Automatically open dashboard in default browser |
|
|
188
|
+
| `--version` | `-v` | Show version number |
|
|
189
|
+
| `--help` | `-h` | Show help text |
|
|
190
|
+
|
|
191
|
+
### CLI Examples
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
# Start server on custom port and open browser
|
|
195
|
+
mbkbucket -p 8080 --open
|
|
196
|
+
|
|
197
|
+
# Start with a specific production .env file and application prefix
|
|
198
|
+
mbkbucket --env ./configs/.env.prod -a portalapp
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## Library API ๐
|
|
204
|
+
|
|
205
|
+
Full TypeScript declarations are available in [index.d.ts](index.d.ts).
|
|
206
|
+
|
|
207
|
+
### File Operations
|
|
208
|
+
|
|
209
|
+
| Function | Description |
|
|
210
|
+
|---|---|
|
|
211
|
+
| `uploadFile(key, buffer, contentType, options?)` | Upload a file buffer/stream with options (`preventOverwrite`, `metadata`, `bucketName`/`connectionName`) |
|
|
212
|
+
| `downloadFile(key, options?)` | Download a file as a readable stream with metadata and headers |
|
|
213
|
+
| `deleteFile(key, connectionName?)` | Delete a single file |
|
|
214
|
+
| `deleteFiles(keys, connectionName?)` | Batch delete an array of files |
|
|
215
|
+
| `listfiles(prefix?, options?)` | List files and folders with pagination, search, or delimiter filtering |
|
|
216
|
+
| `getFileMetadata(key, connectionName?)` | Retrieve file metadata without downloading content |
|
|
217
|
+
| `fileExists(key, connectionName?)` | Check if a file exists |
|
|
218
|
+
| `getFileSize(key, connectionName?)` | Get file size in bytes (returns `number` or `null`) |
|
|
219
|
+
|
|
220
|
+
### Folder, Copy & Move Operations
|
|
221
|
+
|
|
222
|
+
| Function | Description |
|
|
223
|
+
|---|---|
|
|
224
|
+
| `createFolder(prefix, connectionName?, options?)` | Create a folder / directory marker |
|
|
225
|
+
| `copyFile(sourceKey, destKey, options?, connectionName?)` | Copy a file within storage |
|
|
226
|
+
| `moveFile(sourceKey, destKey, options?, connectionName?)` | Move or rename a file within storage |
|
|
227
|
+
| `deleteFolder(prefix, connectionName?)` | Recursively delete all files under a folder prefix |
|
|
228
|
+
|
|
229
|
+
### Multipart Upload & Cleanup Scheduler
|
|
230
|
+
|
|
231
|
+
*(Supported on S3-compatible providers)*
|
|
232
|
+
|
|
233
|
+
| Function / Export | Description |
|
|
234
|
+
|---|---|
|
|
235
|
+
| `createMultipartUpload(key, contentType?, metadata?, connectionName?)` | Initialize a multipart upload session |
|
|
236
|
+
| `uploadPart(key, uploadId, partNumber, buffer, connectionName?)` | Upload an individual chunk part |
|
|
237
|
+
| `completeMultipartUpload(key, uploadId, parts, connectionName?)` | Finalize and assemble multipart upload |
|
|
238
|
+
| `abortMultipartUpload(key, uploadId, connectionName?)` | Abort and cancel a multipart upload |
|
|
239
|
+
| `listIncompleteMultipartUploads(prefix?, connectionName?)` | List pending / incomplete multipart uploads |
|
|
240
|
+
| `cleanupIncompleteMultipartUploads(olderThanDays?, prefix?, connectionName?)` | Clean up abandoned multipart chunks |
|
|
241
|
+
| `CleanupScheduler` / `cleanupScheduler` | Automated background scheduler to purge incomplete uploads on a recurring interval |
|
|
242
|
+
|
|
243
|
+
```js
|
|
244
|
+
import { cleanupScheduler } from 'mbkbucket';
|
|
245
|
+
|
|
246
|
+
// Start automated daily background cleanup for uploads older than 7 days
|
|
247
|
+
cleanupScheduler.start({
|
|
248
|
+
intervalHours: 24,
|
|
249
|
+
olderThanDays: 7
|
|
250
|
+
});
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### Storage & Connection Management
|
|
254
|
+
|
|
255
|
+
| Function / Export | Description |
|
|
256
|
+
|---|---|
|
|
257
|
+
| `getAvailableStorageNames()` / `getAvailableBucketNames()` | List all configured storage connection identifiers |
|
|
258
|
+
| `resolveStorageName(name?)` / `resolveBucketName(name?)` | Resolve and validate target connection name (falls back to default) |
|
|
259
|
+
| `getStorageProvider(name?)` | Get the initialized `StorageProvider` instance for a connection |
|
|
260
|
+
| `getStorageConfig(name?)` / `getBucketConfig(name?)` | Retrieve connection credentials and configuration object |
|
|
261
|
+
| `getBucketClient(bucketName?)` | Get the underlying AWS SDK S3Client instance (for S3 connections) |
|
|
262
|
+
| `checkHealth(name?)` | Execute health and connectivity check on a storage connection |
|
|
263
|
+
| `runHealthCheck(name?)` | Run diagnostic health check with console / debug output |
|
|
264
|
+
|
|
265
|
+
### Storage Core & Custom Drivers
|
|
266
|
+
|
|
267
|
+
mbkbucket exposes its core abstraction classes so you can extend, inspect, or listen to storage events programmatically:
|
|
268
|
+
|
|
269
|
+
```js
|
|
270
|
+
import { StorageProvider, LocalStorageProvider, StorageManager, storageManager } from 'mbkbucket';
|
|
271
|
+
|
|
272
|
+
// Listen to lifecycle events
|
|
273
|
+
storageManager.on('file:uploaded', (e) => console.log('Uploaded:', e.key, e.provider));
|
|
274
|
+
storageManager.on('file:deleted', (e) => console.log('Deleted:', e.key));
|
|
275
|
+
storageManager.on('folder:created', (e) => console.log('Folder created:', e.prefix));
|
|
276
|
+
|
|
277
|
+
// Register a custom storage driver
|
|
278
|
+
storageManager.registerDriver('custom-ftp', (name, config) => {
|
|
279
|
+
return new MyCustomFtpProvider(name, config);
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
// Register a runtime connection using the driver
|
|
283
|
+
storageManager.registerConnection('backup_ftp', {
|
|
284
|
+
type: 'custom-ftp',
|
|
285
|
+
host: 'ftp.example.com'
|
|
286
|
+
});
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
Exported classes:
|
|
290
|
+
- `StorageProvider`: Abstract base class with required contracts (`uploadFile`, `downloadFile`, `listFiles`, `deleteFile`, `copyFile`, `moveFile`, `createFolder`, `checkHealth`, etc.) and capability assertions.
|
|
291
|
+
- `LocalStorageProvider`: Cross-platform local disk provider (Windows, Linux, macOS) with quota calculation and path sanitization.
|
|
292
|
+
- `S3StorageProvider`: AWS S3, Cloudflare R2, MinIO, IDrive e2 implementation.
|
|
293
|
+
- `GoogleDriveStorageProvider`: Google Drive OAuth 2.0 and Service Account implementation.
|
|
294
|
+
- `StorageManager` / `storageManager`: Connection registry, driver repository, `EventEmitter` lifecycle orchestrator, and health monitor.
|
|
295
|
+
- `StorageItem`, `StorageFile`, `StorageFolder`, `StorageListResult`: Standardized metadata models.
|
|
296
|
+
- Custom Errors: `StorageError`, `StorageNotFoundError`, `StorageAccessDeniedError`, `StorageConflictError`, `StorageValidationError`, `StorageConfigError`, `StorageQuotaExceededError`, `StorageUnsupportedOperationError`.
|
|
297
|
+
|
|
298
|
+
### Metrics & Observability
|
|
299
|
+
|
|
300
|
+
mbkbucket includes a Prometheus-compatible metrics registry tracking storage operations, throughput, durations, errors, and active sessions:
|
|
301
|
+
|
|
302
|
+
```js
|
|
303
|
+
import { metricsRegistry } from 'mbkbucket';
|
|
304
|
+
|
|
305
|
+
// Retrieve snapshot statistics
|
|
306
|
+
const stats = metricsRegistry.getStats();
|
|
307
|
+
console.log('Total ops:', stats.operations);
|
|
308
|
+
console.log('Bytes transferred:', stats.bytesTransferred);
|
|
309
|
+
|
|
310
|
+
// Export Prometheus exposition format
|
|
311
|
+
const prometheusText = metricsRegistry.toPrometheusText();
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
Endpoints `/mbkbucket/api/metrics` (JSON) and `/mbkbucket/metrics` (Prometheus text) are automatically exposed when mounting the router.
|
|
315
|
+
|
|
316
|
+
### Google Drive Authentication Helpers
|
|
317
|
+
|
|
318
|
+
mbkbucket exports helper functions for handling Google Drive OAuth 2.0 flows:
|
|
319
|
+
|
|
320
|
+
| Export | Description |
|
|
321
|
+
|---|---|
|
|
322
|
+
| `getGoogleAuthUrl(options)` | Generate Google OAuth 2.0 consent URL (`clientId`, `redirectUri`, `state`) |
|
|
323
|
+
| `exchangeCodeForTokens(options)` | Exchange authorization code for access and refresh tokens |
|
|
324
|
+
| `refreshGoogleAccessToken(options)` | Refresh an expired access token using a refresh token |
|
|
325
|
+
| `getServiceAccountAccessToken(options)` | Generate access token using Google Cloud Service Account credentials |
|
|
326
|
+
| `GOOGLE_DRIVE_SCOPES` | Standard OAuth scope strings for Google Drive (`drive.file`, `drive`, etc.) |
|
|
327
|
+
|
|
328
|
+
### Key Prefixing & App Isolation
|
|
329
|
+
|
|
330
|
+
| Function | Description |
|
|
331
|
+
|---|---|
|
|
332
|
+
| `getAppName()` | Retrieve the active application namespace from `mbkautheVar.APP_NAME` |
|
|
333
|
+
| `ensureKeyHasAppPrefix(key?)` | Prefix a file key with the app prefix to enforce tenant isolation |
|
|
334
|
+
| `ensurePrefix(prefix?)` | Prefix a folder path with the app prefix |
|
|
335
|
+
| `validateKeySafety(str, isKey?)` | Guard against path traversal attacks (`..`, null bytes, illegal characters) |
|
|
336
|
+
|
|
337
|
+
### Config & Diagnostics
|
|
338
|
+
|
|
339
|
+
| Export | Description |
|
|
340
|
+
|---|---|
|
|
341
|
+
| `packageJson` | mbkbucket package metadata (version, license, etc.) |
|
|
342
|
+
| `appVersion` | Detected version of the host application |
|
|
343
|
+
| `mbkbucketVar` | Parsed and validated `mbkbucketVar` configuration |
|
|
344
|
+
| `checkVersion()` | Check GitHub releases for newer versions of mbkbucket |
|
|
345
|
+
| `validateConfiguration()` | Validate `mbkbucketVar` settings |
|
|
346
|
+
| `validateBucketConnection()` | Validate `BucketConnection` syntax and provider schemas |
|
|
347
|
+
| `validateAllConfiguration()` | Run all configuration validations |
|
|
348
|
+
|
|
349
|
+
### Express Integration
|
|
350
|
+
|
|
351
|
+
| Export | Description |
|
|
352
|
+
|---|---|
|
|
353
|
+
| `bucket` (named) | Pre-configured Express router with superadmin protection |
|
|
354
|
+
| `createBucketRouter(options)` | Configurable router factory with custom permission middleware |
|
|
355
|
+
| `default` | Standalone Express server application ready for `.listen()` |
|
|
356
|
+
|
|
357
|
+
---
|
|
358
|
+
|
|
359
|
+
## Express Router & HTTP API ๐ฅ๏ธ
|
|
360
|
+
|
|
361
|
+
### Endpoints
|
|
362
|
+
|
|
363
|
+
All routes are mounted relative to the router path (typically `/mbkbucket`):
|
|
364
|
+
|
|
365
|
+
| Endpoint | Method | Default Access | Description |
|
|
366
|
+
|---|---|---|---|
|
|
367
|
+
| `/mbkbucket` | `GET` | `view` auth | Admin file manager dashboard UI |
|
|
368
|
+
| `/mbkbucket/info` | `GET` | Public / Any | Health check, provider capabilities, and runtime config info |
|
|
369
|
+
| `/mbkbucket/view/*key` | `GET` | `view` auth | Inline viewer with byte-range streaming for video, audio, PDF, images, text |
|
|
370
|
+
| `/mbkbucket/player/*key` | `GET` | `view` auth | Dedicated media player page for video and audio playback |
|
|
371
|
+
| `/mbkbucket/p_view/*key` | `GET` | Public | Public file viewer (enabled when `publiView_enabled` is `"true"`) |
|
|
372
|
+
| `/mbkbucket/download/*key` | `GET` | `view` auth | Download file with `Content-Disposition: attachment` headers |
|
|
373
|
+
| `/mbkbucket/api/files` | `GET` | `view` auth | List files and folders with pagination, search, and continuation tokens |
|
|
374
|
+
| `/mbkbucket/api/file-info/*key`| `GET` | `view` auth | Get metadata (Content-Type, size, ETag, last modified) for a key |
|
|
375
|
+
| `/mbkbucket/api/health` | `GET` | `view` auth | Check connectivity for active storage connection |
|
|
376
|
+
| `/mbkbucket/api/metrics` | `GET` | `view` auth | Prometheus metrics serialized as JSON |
|
|
377
|
+
| `/mbkbucket/metrics` | `GET` | `view` auth | Prometheus exposition format text output |
|
|
378
|
+
| `/mbkbucket/api/signed-url` | `GET` | `upload` auth | Generate pre-signed URL for direct client uploads/downloads |
|
|
379
|
+
| `/mbkbucket/api/incomplete-uploads` | `GET` | `view` auth | List incomplete multipart uploads |
|
|
380
|
+
| `/mbkbucket/api/cleanup-uploads` | `POST` | `delete` auth | Clean up incomplete multipart uploads older than specified days |
|
|
381
|
+
| `/mbkbucket/upload` | `POST` | `upload` auth | Upload a single file via `multipart/form-data` with conflict detection |
|
|
382
|
+
| `/mbkbucket/upload-init` | `POST` | `upload` auth | Initiate multipart upload session |
|
|
383
|
+
| `/mbkbucket/upload-chunk` | `POST` | `upload` auth | Upload individual multipart chunk (up to 50MB) |
|
|
384
|
+
| `/mbkbucket/upload-complete` | `POST` | `upload` auth | Assemble and complete multipart upload |
|
|
385
|
+
| `/mbkbucket/upload-abort` | `POST` | `delete` auth | Abort pending multipart upload session |
|
|
386
|
+
| `/mbkbucket/create-folder` | `POST` | `upload` auth | Create a new directory folder marker |
|
|
387
|
+
| `/mbkbucket/delete` | `POST` | `delete` auth | Delete a single file, batch array of keys, or folder |
|
|
388
|
+
| `/mbkbucket/move` | `POST` | `upload` auth | Move or rename a file (`sourceKey` to `destKey`) |
|
|
389
|
+
| `/mbkbucket/copy` | `POST` | `upload` auth | Copy or duplicate a file (`sourceKey` to `destKey`) |
|
|
390
|
+
|
|
391
|
+
### Host-Controlled Permissions
|
|
392
|
+
|
|
393
|
+
You can configure granular authorization per operation using `createBucketRouter`:
|
|
394
|
+
|
|
395
|
+
```js
|
|
396
|
+
import { createBucketRouter } from 'mbkbucket';
|
|
397
|
+
import { sessPerm } from 'mbkauthe';
|
|
398
|
+
import { Permissions } from './permissions.js';
|
|
399
|
+
|
|
400
|
+
app.use(createBucketRouter({
|
|
401
|
+
authorization: {
|
|
402
|
+
view: sessPerm(Permissions.storage.view),
|
|
403
|
+
upload: sessPerm(Permissions.storage.upload),
|
|
404
|
+
delete: sessPerm(Permissions.storage.delete),
|
|
405
|
+
},
|
|
406
|
+
publiViewEnabled: false,
|
|
407
|
+
}));
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
- When no custom authorization is passed, `sessRole('superadmin')` protects all private endpoints by default.
|
|
411
|
+
- Passing a single middleware function to `authorization` applies that guard across all three operations.
|
|
412
|
+
|
|
413
|
+
### Templates & Views
|
|
414
|
+
|
|
415
|
+
The Express router renders Handlebars (`.hbs`) views located in `views/`:
|
|
416
|
+
|
|
417
|
+
| Template / Partial | Description |
|
|
418
|
+
|---|---|
|
|
419
|
+
| `bucketportal.hbs` | Dashboard shell layout |
|
|
420
|
+
| `bucketadmincontent.hbs` | File manager interface with tree sidebar and storage switcher |
|
|
421
|
+
| `bucketadmin_alerts.hbs` | UI alerts and toast partial |
|
|
422
|
+
| `bucketadmin_delete_modal.hbs` | Item and folder deletion confirmation modal |
|
|
423
|
+
| `bucketadmin_move_modal.hbs` | File move and rename modal with destination selection |
|
|
424
|
+
| `bucketadmin_newfolder_modal.hbs` | New folder creation modal |
|
|
425
|
+
| `bucketadmin_preview_modal.hbs` | Full-screen media preview modal (images, video, audio, code, PDF) |
|
|
426
|
+
| `bucketadmin_upload_modal.hbs` | Chunked file upload modal with progress bars |
|
|
427
|
+
| `bucketadmin_filelist_skeleton.hbs`| Loading state placeholder skeleton |
|
|
428
|
+
| `bucket.hbs` | Public file viewer page |
|
|
429
|
+
| `mbkbucket_info.hbs` | Diagnostics, active connections, and environment info page |
|
|
430
|
+
|
|
431
|
+
---
|
|
432
|
+
|
|
433
|
+
## Frontend Helper Client ๐จ
|
|
434
|
+
|
|
435
|
+
mbkbucket bundles a lightweight, zero-dependency client library served directly from your app:
|
|
436
|
+
|
|
437
|
+
- Script: `/mbkbucket/mbkbucket-helper.js`
|
|
438
|
+
- Styles: `/mbkbucket/mbkbucket-helper.css`
|
|
439
|
+
- Live interactive demo: `/mbkbucket/helper-demo`
|
|
440
|
+
|
|
441
|
+
### Including the Helper
|
|
442
|
+
|
|
443
|
+
```html
|
|
444
|
+
<link rel="stylesheet" href="/mbkbucket/mbkbucket-helper.css">
|
|
445
|
+
<script src="/mbkbucket/mbkbucket-helper.js"></script>
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
### Features
|
|
449
|
+
|
|
450
|
+
#### 1. Gallery Browser Modal
|
|
451
|
+
Open a rich modal browser to allow users to select one or multiple files directly from storage:
|
|
452
|
+
|
|
453
|
+
```js
|
|
454
|
+
MBKBucket.openGallery({
|
|
455
|
+
title: 'Choose Profile Banner',
|
|
456
|
+
filter: 'image', // 'image' | 'video' | 'audio' | 'pdf' | 'all'
|
|
457
|
+
multiple: false,
|
|
458
|
+
onSelect: (selectedFiles) => {
|
|
459
|
+
console.log('Selected:', selectedFiles[0].url, selectedFiles[0].key);
|
|
460
|
+
}
|
|
461
|
+
});
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
#### 2. File Picker Inputs
|
|
465
|
+
Bind an existing `<input>` element with auto-attached browse buttons and live thumbnail previews:
|
|
466
|
+
|
|
467
|
+
```html
|
|
468
|
+
<input type="text" data-mbk-picker data-filter="image" data-preview="#avatar-preview">
|
|
469
|
+
<img id="avatar-preview" src="/placeholder.png" alt="Preview">
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
Or programmatically:
|
|
473
|
+
```js
|
|
474
|
+
MBKBucket.createPicker(document.getElementById('my-input'), {
|
|
475
|
+
filter: 'image',
|
|
476
|
+
onSelect: (file) => console.log('Picked:', file)
|
|
477
|
+
});
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
#### 3. Upload Widget
|
|
481
|
+
Add a drag-and-drop uploader with automatic chunking for large files:
|
|
482
|
+
|
|
483
|
+
```html
|
|
484
|
+
<div data-mbk-uploader data-prefix="uploads/users" data-allowed="image/*,video/*"></div>
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
#### 4. Client URL Builders
|
|
488
|
+
```js
|
|
489
|
+
MBKBucket.url.view('photos/cover.jpg'); // -> /mbkbucket/view/photos/cover.jpg
|
|
490
|
+
MBKBucket.url.download('reports/data.xlsx'); // -> /mbkbucket/download/reports/data.xlsx
|
|
491
|
+
MBKBucket.url.publicView('public/logo.png'); // -> /mbkbucket/p_view/public/logo.png
|
|
492
|
+
MBKBucket.url.player('media/intro.mp4'); // -> /mbkbucket/player/media/intro.mp4
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
---
|
|
496
|
+
|
|
497
|
+
## Environment Configuration โ๏ธ
|
|
498
|
+
|
|
499
|
+
### `BucketConnection` (required)
|
|
500
|
+
|
|
501
|
+
A JSON string defining one or more storage connections. You can configure **Local Disk**, **S3/R2**, and **Google Drive** connections together:
|
|
502
|
+
|
|
503
|
+
```env
|
|
504
|
+
BucketConnection={"Local_Disk":{"type":"local","basePath":"./mbkbucket_storage","maxBytes":10737418240},"R2_Bucket":{"BUCKET_NAME":"my-bucket","ACCESS_KEY_ID":"your-key","SECRET_ACCESS_KEY":"your-secret","ENDPOINT":"https://<account-id>.r2.cloudflarestorage.com"},"Google_Drive":{"type":"gdrive","client_id":"your-client-id.apps.googleusercontent.com","client_secret":"your-client-secret","refresh_token":"your-refresh-token","folder_id":"root"}}
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
#### Local Disk Connection Fields
|
|
508
|
+
|
|
509
|
+
| Field | Required | Description |
|
|
510
|
+
|---|---|---|
|
|
511
|
+
| `type` | Yes | Provider tag: `"local"`, `"local-disk"`, or `"disk"` |
|
|
512
|
+
| `basePath` | No | Base directory path on local disk (supports relative `./storage` or absolute `D:\storage` / `/var/storage`). Defaults to `./mbkbucket_storage`. |
|
|
513
|
+
| `maxBytes` | No | Storage quota limit in bytes (e.g. `10737418240` for 10 GB) |
|
|
514
|
+
|
|
515
|
+
#### S3 / Cloudflare R2 Connection Fields
|
|
516
|
+
|
|
517
|
+
| Field | Required | Description |
|
|
518
|
+
|---|---|---|
|
|
519
|
+
| `BUCKET_NAME` | Yes | Target bucket name |
|
|
520
|
+
| `ACCESS_KEY_ID` | Yes | S3 Access Key ID |
|
|
521
|
+
| `SECRET_ACCESS_KEY` | Yes | S3 Secret Access Key |
|
|
522
|
+
| `ENDPOINT` | Yes | S3 API endpoint URL (e.g. `https://<id>.r2.cloudflarestorage.com` or `https://s3.us-east-1.amazonaws.com`) |
|
|
523
|
+
| `region` | No | Region (defaults to `'auto'` for Cloudflare R2 / custom endpoints) |
|
|
524
|
+
|
|
525
|
+
#### Google Drive Connection Fields
|
|
526
|
+
|
|
527
|
+
| Field | Required | Description |
|
|
528
|
+
|---|---|---|
|
|
529
|
+
| `type` | Yes | Provider tag: `"gdrive"` or `"google-drive"` |
|
|
530
|
+
| `client_id` | OAuth | Google OAuth 2.0 Client ID |
|
|
531
|
+
| `client_secret` | OAuth | Google OAuth 2.0 Client Secret |
|
|
532
|
+
| `refresh_token` | OAuth | Long-lived Google OAuth 2.0 refresh token |
|
|
533
|
+
| `folder_id` | No | Target root folder ID in Google Drive (defaults to `"root"`) |
|
|
534
|
+
| `client_email` | Service Account | Service Account client email (alternative to OAuth) |
|
|
535
|
+
| `private_key` | Service Account | Service Account PEM private key (alternative to OAuth) |
|
|
536
|
+
|
|
537
|
+
#### Google Drive via Service Account Example
|
|
538
|
+
|
|
539
|
+
```env
|
|
540
|
+
BucketConnection={"Google_Drive_SA":{"type":"gdrive","client_email":"storage-sa@project.iam.gserviceaccount.com","private_key":"-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----","folder_id":"1A2B3C4D5E6F"}}
|
|
541
|
+
```
|
|
542
|
+
|
|
543
|
+
### `mbkautheVar` (required)
|
|
544
|
+
|
|
545
|
+
Standard mbkauthe configuration. Key fields relevant to storage:
|
|
546
|
+
|
|
547
|
+
| Field | Required | Description |
|
|
548
|
+
|---|---|---|
|
|
549
|
+
| `APP_NAME` | Yes | Namespace used for automatic key prefix isolation |
|
|
550
|
+
| `bucket` | No | Default active connection name (falls back to first key in `BucketConnection`) |
|
|
551
|
+
| `loginRedirectURL` | No | URL to redirect upon authentication |
|
|
552
|
+
|
|
553
|
+
### `mbkbucketVar` (optional)
|
|
554
|
+
|
|
555
|
+
Optional behavioral toggles for viewers and streaming:
|
|
556
|
+
|
|
557
|
+
```env
|
|
558
|
+
mbkbucketVar={"publiView_enabled":"true","p_view_inline":"true"}
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
| Field | Default | Description |
|
|
562
|
+
|---|---|---|
|
|
563
|
+
| `publiView_enabled` | `false` | Enable or disable unauthenticated public file access under `/mbkbucket/p_view/*` |
|
|
564
|
+
| `p_view_inline` | `true` | Stream files inline in browser response (vs redirecting to external signed URLs) |
|
|
565
|
+
|
|
566
|
+
---
|
|
567
|
+
|
|
568
|
+
## Automated Tests ๐งช
|
|
569
|
+
|
|
570
|
+
mbkbucket uses [Vitest](https://vitest.dev/) for unit and integration testing:
|
|
571
|
+
|
|
572
|
+
```bash
|
|
573
|
+
npm test
|
|
574
|
+
```
|
|
575
|
+
|
|
576
|
+
### Test Suites Covered
|
|
577
|
+
|
|
578
|
+
- **Storage Provider & Core Abstractions**: `StorageProvider` interface contracts, capability inspection, `PathStrategy` traversal security, `StorageError` hierarchy, Google Drive consent URL generation.
|
|
579
|
+
- **Local Storage Provider & Features**: Cross-platform path resolution, directory isolation, quota tracking (`maxBytes`), recursive directory scanning, and byte-range streaming.
|
|
580
|
+
- **Architecture Hardening & Reliability**: Exponential backoff on rate-limits (429/503), `StorageManager` `EventEmitter` lifecycle events, `MetricsRegistry` tracking, and `CleanupScheduler`.
|
|
581
|
+
- **API Routes Logic**: File listing, single and chunked multipart uploads, conflict detection (409), folder creation, single/batch deletion, move and copy operations, health endpoint, metadata inspection.
|
|
582
|
+
- **View Controller & Streaming**: Inline viewer, open-ended RFC 7233 byte-range streaming for PDF documents and media (`206 Partial Content`), unsupported MIME rejection (`415`), public file viewing.
|
|
583
|
+
- **Helpers & Error Hierarchy**: Utility helpers, range header parsing, stream buffers, cache control builders, and domain-specific error classes.
|
|
584
|
+
- **Configuration Validation**: S3, Local Disk, and Google Drive connection validation, malformed JSON recovery, boolean normalization, and error messaging.
|
|
585
|
+
- **S3 Prefix & Name Resolution**: Application namespace prefixing, delimiter handling, and bucket resolution.
|
|
586
|
+
- **Public API Exports**: Verification of all exported functions, classes, and proxy objects from package root.
|
|
587
|
+
|
|
588
|
+
---
|
|
589
|
+
|
|
590
|
+
## Contact & Support
|
|
591
|
+
|
|
592
|
+
- **Website**: [mbktech.org/Support](https://mbktech.org/Support/?Project=MIbnEKhalidWeb)
|
|
593
|
+
- **Email**: [support@mbktech.org](mailto:support@mbktech.org)
|
|
594
|
+
- **GitHub**: [MIbnEKhalid/mbkbucket](https://github.com/MIbnEKhalid/mbkbucket)
|
|
595
|
+
|
|
596
|
+
---
|
|
597
|
+
|
|
598
|
+
## About
|
|
599
|
+
|
|
600
|
+
Developed by [Muhammad Bin Khalid](https://github.com/MIbnEKhalid)
|
|
601
|
+
Part of [MBK Tech](https://mbktech.org/)
|
|
602
|
+
|
|
603
|
+
---
|
|
604
|
+
|
|
605
|
+
## License
|
|
606
|
+
|
|
607
|
+
Licensed under the MIT License. See [LICENSE](LICENSE) for details.
|
|
608
|
+
|
|
609
|
+
<!--
|
|
610
|
+
* MBKBucket
|
|
611
|
+
* Copyright (c) 2026 Muhammad Bin Khalid, MBKTech.org and contributors
|
|
612
|
+
* Licensed under the MIT License.
|
|
613
|
+
* Source: https://github.com/MIbnEKhalid/mbkbucket
|
|
562
614
|
-->
|