mbkbucket 3.3.0 → 3.3.1

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.
Files changed (44) hide show
  1. package/index.js +7 -7
  2. package/{cli.js → lib/cli.js} +0 -1
  3. package/{src → lib/src}/config/index.js +1 -1
  4. package/package.json +13 -3
  5. package/.github/PACKAGE.md +0 -19
  6. package/.github/workflows/publish.yml +0 -88
  7. package/index.d.ts +0 -444
  8. package/lib/index.js +0 -17
  9. package/test/config-validation.test.js +0 -116
  10. /package/{public → lib/public}/bucketadmin.css +0 -0
  11. /package/{public → lib/public}/bucketadmin.js +0 -0
  12. /package/{public → lib/public}/mbkbucket-helper-demo.html +0 -0
  13. /package/{public → lib/public}/mbkbucket-helper.css +0 -0
  14. /package/{public → lib/public}/mbkbucket-helper.js +0 -0
  15. /package/{src → lib/src}/app.js +0 -0
  16. /package/{src → lib/src}/cli/auth-helper.js +0 -0
  17. /package/{src → lib/src}/config/validation.js +0 -0
  18. /package/{src → lib/src}/controllers/api.controller.js +0 -0
  19. /package/{src → lib/src}/controllers/dashboard.controller.js +0 -0
  20. /package/{src → lib/src}/controllers/info.controller.js +0 -0
  21. /package/{src → lib/src}/controllers/view.controller.js +0 -0
  22. /package/{src → lib/src}/middleware/async-handler.js +0 -0
  23. /package/{src → lib/src}/middleware/bucket-resolver.js +0 -0
  24. /package/{src → lib/src}/middleware/error-handler.js +0 -0
  25. /package/{src → lib/src}/middleware/rate-limiter.js +0 -0
  26. /package/{src → lib/src}/middleware/security.js +0 -0
  27. /package/{src → lib/src}/routes/api.routes.js +0 -0
  28. /package/{src → lib/src}/routes/index.js +0 -0
  29. /package/{src → lib/src}/routes/info.routes.js +0 -0
  30. /package/{src → lib/src}/routes/view.routes.js +0 -0
  31. /package/{src → lib/src}/services/s3.service.js +0 -0
  32. /package/{src → lib/src}/utils/errors.js +0 -0
  33. /package/{src → lib/src}/utils/helpers.js +0 -0
  34. /package/{src → lib/src}/utils/logger.js +0 -0
  35. /package/{views → lib/views}/bucket.handlebars +0 -0
  36. /package/{views → lib/views}/bucketadmin_alerts.handlebars +0 -0
  37. /package/{views → lib/views}/bucketadmin_delete_modal.handlebars +0 -0
  38. /package/{views → lib/views}/bucketadmin_filelist_skeleton.handlebars +0 -0
  39. /package/{views → lib/views}/bucketadmin_newfolder_modal.handlebars +0 -0
  40. /package/{views → lib/views}/bucketadmin_preview_modal.handlebars +0 -0
  41. /package/{views → lib/views}/bucketadmin_upload_modal.handlebars +0 -0
  42. /package/{views → lib/views}/bucketadmincontent.handlebars +0 -0
  43. /package/{views → lib/views}/bucketportal.handlebars +0 -0
  44. /package/{views → lib/views}/mbkbucket_info.handlebars +0 -0
package/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import dotenv from "dotenv";
2
- import { createApp } from "./src/app.js";
3
- import { checkVersion } from "./src/config/index.js";
4
- import { runHealthCheck } from "./src/services/s3.service.js";
5
- import { createLogger } from "./src/utils/logger.js";
2
+ import { createApp } from "./lib/src/app.js";
3
+ import { checkVersion } from "./lib/src/config/index.js";
4
+ import { runHealthCheck } from "./lib/src/services/s3.service.js";
5
+ import { createLogger } from "./lib/src/utils/logger.js";
6
6
 
7
7
  dotenv.config();
8
8
 
@@ -26,9 +26,9 @@ if (isDevMode) {
26
26
  }
27
27
 
28
28
  // Re-export the public API for consumers of this package (named exports only)
29
- export * from "./src/services/s3.service.js";
30
- export * from "./src/config/index.js";
31
- export { default as bucket } from "./src/routes/index.js";
29
+ export * from "./lib/src/services/s3.service.js";
30
+ export * from "./lib/src/config/index.js";
31
+ export { default as bucket } from "./lib/src/routes/index.js";
32
32
 
33
33
  // Default export: the Express application instance
34
34
  export default server;
@@ -22,7 +22,6 @@
22
22
  import dotenv from 'dotenv';
23
23
  import path from 'node:path';
24
24
  import fs from 'node:fs';
25
- import os from 'node:os';
26
25
 
27
26
  // Load .env from cwd first so S3 service can pick up BucketConnection etc.
28
27
  dotenv.config();
@@ -14,7 +14,7 @@ try {
14
14
  packageJson = require("mbkbucket/package.json");
15
15
  } catch {
16
16
  // Fallback to relative path (for development/testing)
17
- packageJson = require("../../package.json");
17
+ packageJson = require("../../../package.json");
18
18
  }
19
19
 
20
20
  // Parent project version
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mbkbucket",
3
- "version": "3.3.0",
3
+ "version": "3.3.1",
4
4
  "description": "Flexible S3/R2 bucket management — library, Express router, and CLI for mbktech.org applications. Provides upload, download, listing, multipart utilities, signed URLs, and a command-line interface with built-in configuration validation and health checks",
5
5
  "author": "Muhammad Bin Khalid",
6
6
  "homepage": "https://github.com/MIbnEKhalid/mbkbucket#readme",
@@ -9,7 +9,7 @@
9
9
  "type": "module",
10
10
  "types": "index.d.ts",
11
11
  "bin": {
12
- "mbkbucket": "./cli.js"
12
+ "mbkbucket": "./lib/cli.js"
13
13
  },
14
14
  "scripts": {
15
15
  "dev": "cross-env NODE_ENV=dev nodemon index.js",
@@ -44,6 +44,16 @@
44
44
  "bugs": {
45
45
  "url": "https://github.com/MIbnEKhalid/mbkbucket/issues"
46
46
  },
47
+ "files": [
48
+ "lib",
49
+ ".env.example",
50
+ ".mbkbucket.config.example.json",
51
+ "cli.js",
52
+ "index.js",
53
+ "LICENSE",
54
+ "package.json",
55
+ "README.md"
56
+ ],
47
57
  "keywords": [
48
58
  "mbkbucket",
49
59
  "s3-bucket",
@@ -62,4 +72,4 @@
62
72
  "file-upload",
63
73
  "file-download"
64
74
  ]
65
- }
75
+ }
@@ -1,19 +0,0 @@
1
- # Package Information
2
-
3
- This package is published on npm: [mbkbucket](https://www.npmjs.com/package/mbkbucket)
4
-
5
- ## Installation
6
-
7
- ```bash
8
- npm install mbkbucket
9
- ```
10
-
11
- ## What's Included
12
-
13
- - **Library** — Full S3/R2 bucket management API (upload, download, list, delete, multipart, signed URLs)
14
- - **Express Router** — Ready-to-use admin dashboard with Handlebars templates
15
- - **CLI** — Command-line interface for managing buckets from the terminal ⚠️ *under development*
16
-
17
- ## Registry
18
-
19
- Published to: npm Registry (https://registry.npmjs.org/)
@@ -1,88 +0,0 @@
1
- name: Publish to npm and GitHub Packages
2
- on:
3
- push:
4
- branches:
5
- - main
6
- - master
7
-
8
- permissions:
9
- contents: read
10
- packages: write
11
-
12
- jobs:
13
- publish:
14
- runs-on: ubuntu-latest
15
- permissions:
16
- contents: read
17
- packages: write
18
- steps:
19
- - name: Checkout code
20
- uses: actions/checkout@v3
21
-
22
- - name: Setup Node.js for npm
23
- uses: actions/setup-node@v3
24
- with:
25
- node-version: '18'
26
- registry-url: 'https://registry.npmjs.org'
27
-
28
- - name: Cache Node.js modules
29
- uses: actions/cache@v3
30
- with:
31
- path: ~/.npm
32
- key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
33
- restore-keys: |
34
- ${{ runner.os }}-node-
35
-
36
- - name: Install dependencies
37
- run: |
38
- for i in {1..3}; do npm install && break || sleep 10; done
39
-
40
- - name: Check if version exists on npm
41
- id: check_version
42
- run: |
43
- PACKAGE_NAME=$(node -p "require('./package.json').name")
44
- VERSION=$(node -p "require('./package.json').version")
45
- if npm view $PACKAGE_NAME@$VERSION version 2>/dev/null; then
46
- echo "exists=true" >> $GITHUB_OUTPUT
47
- echo "Version $VERSION already exists on npm"
48
- else
49
- echo "exists=false" >> $GITHUB_OUTPUT
50
- echo "Version $VERSION does not exist, will publish"
51
- fi
52
-
53
- - name: Publish to npm
54
- if: steps.check_version.outputs.exists == 'false'
55
- run: npm publish
56
- env:
57
- NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
58
-
59
- - name: Check if version exists on GitHub Packages
60
- id: check_github_version
61
- run: |
62
- VERSION=$(node -p "require('./package.json').version")
63
- if curl -f -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \
64
- https://npm.pkg.github.com/@mibnekhalid/mbkbucket/$VERSION 2>/dev/null; then
65
- echo "exists=true" >> $GITHUB_OUTPUT
66
- echo "Version $VERSION already exists on GitHub Packages"
67
- else
68
- echo "exists=false" >> $GITHUB_OUTPUT
69
- echo "Version $VERSION does not exist on GitHub Packages, will publish"
70
- fi
71
-
72
- - name: Modify package.json for GitHub Packages
73
- if: steps.check_github_version.outputs.exists == 'false'
74
- run: |
75
- node -e "const pkg = require('./package.json'); pkg.name = '@mibnekhalid/mbkbucket'; pkg.publishConfig = { registry: 'https://npm.pkg.github.com' }; require('fs').writeFileSync('package.json', JSON.stringify(pkg, null, 2));"
76
-
77
- - name: Setup Node.js for GitHub Packages
78
- if: steps.check_github_version.outputs.exists == 'false'
79
- uses: actions/setup-node@v3
80
- with:
81
- node-version: '18'
82
- registry-url: 'https://npm.pkg.github.com'
83
-
84
- - name: Publish to GitHub Packages
85
- if: steps.check_github_version.outputs.exists == 'false'
86
- run: npm publish
87
- env:
88
- NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
package/index.d.ts DELETED
@@ -1,444 +0,0 @@
1
- // Type definitions for mbkbucket
2
- // Project: https://github.com/MIbnEKhalid/mbkbucket
3
-
4
- import { Readable } from "stream";
5
- import { Router, Application } from "express";
6
-
7
- /**
8
- * Shared types used across the package
9
- */
10
- export interface BucketConfig {
11
- BUCKET_NAME: string;
12
- ENDPOINT?: string;
13
- ACCESS_KEY_ID?: string;
14
- SECRET_ACCESS_KEY?: string;
15
- region?: string;
16
- [key: string]: any;
17
- }
18
-
19
- export type BucketConnectionMap = Record<string, BucketConfig>;
20
-
21
- export interface S3ObjectResult {
22
- Body: Readable;
23
- ContentLength?: number;
24
- ContentType?: string;
25
- LastModified?: Date;
26
- Key?: string;
27
- [key: string]: any;
28
- }
29
-
30
- export interface UploadOptions {
31
- metadata?: Record<string, string>;
32
- cacheControl?: string;
33
- storageClass?: string;
34
- serverSideEncryption?: string;
35
- bucketName?: string;
36
- preventOverwrite?: boolean;
37
- [key: string]: any;
38
- }
39
-
40
- export interface ListFilesOptions {
41
- maxKeys?: number;
42
- continuationToken?: string | null;
43
- delimiter?: string | null;
44
- fetchOwner?: boolean;
45
- startAfter?: string | null;
46
- bucketName?: string;
47
- [key: string]: any;
48
- }
49
-
50
- export interface ListFilesResult extends Record<string, any> {
51
- requestedAt: string;
52
- totalFiles: number;
53
- hasMore: boolean;
54
- nextToken: string | null;
55
- }
56
-
57
- export interface IncompleteMultipartUpload {
58
- Key?: string;
59
- UploadId?: string;
60
- Initiated?: string;
61
- Initiator?: { DisplayName?: string; [key: string]: any };
62
- [key: string]: any;
63
- }
64
-
65
- export interface CleanupResult {
66
- abortedCount: number;
67
- uploads: Array<{ key: string; uploadId: string; initiated?: string }>;
68
- cleanedAt?: string;
69
- [key: string]: any;
70
- }
71
-
72
- export interface ConfigVars {
73
- publiView_enabled: boolean;
74
- p_view_inline: boolean;
75
- [key: string]: any;
76
- }
77
-
78
- /**
79
- * S3 exports (re-exported from lib/s3.js at package root)
80
- */
81
- export function getAvailableBucketNames(): string[];
82
- export function resolveBucketName(bucketName?: string | null): string;
83
- export function getBucketConfig(bucketName?: string): BucketConfig;
84
- export const bucketClient: any;
85
- export function getAppName(): string;
86
- export function ensureKeyHasAppPrefix(key?: string): string;
87
- export function ensurePrefix(prefix?: string): string;
88
- export function getBucketClient(bucketName?: string): any;
89
- export function checkHealth(): Promise<{ status: string; responseTime?: number; bucket?: string; error?: string; checkedAt: string; region?: string; }>;
90
-
91
- export function uploadFile(
92
- key: string,
93
- fileBuffer: Buffer | Uint8Array,
94
- contentType: string,
95
- options?: UploadOptions
96
- ): Promise<{ fileSize?: number; key: string; contentType?: string; uploadedAt?: string; } & Record<string, any>>;
97
-
98
- export function downloadFile(
99
- key: string,
100
- options?: {
101
- range?: string | null;
102
- ifNoneMatch?: string | null;
103
- ifModifiedSince?: Date | string | null;
104
- responseCacheControl?: string | null;
105
- responseContentType?: string | null;
106
- bucketName?: string;
107
- [key: string]: any;
108
- }
109
- ): Promise<S3ObjectResult>;
110
-
111
- export function deleteFile(key: string, bucketName?: string): Promise<{ key: string; deletedAt?: string } & Record<string, any>>;
112
-
113
- export function deleteFiles(keys: string[], bucketName?: string): Promise<{
114
- results: any[];
115
- deletedCount: number;
116
- errors: any[];
117
- deletedAt: string;
118
- }>;
119
-
120
- export function deleteFolder(prefix: string, bucketName?: string): Promise<{
121
- results?: any[];
122
- deletedCount: number;
123
- errors?: any[];
124
- deletedAt: string;
125
- prefix?: string;
126
- }>;
127
-
128
- export function listfiles(prefix?: string, options?: ListFilesOptions): Promise<ListFilesResult>;
129
-
130
- export function getFileMetadata(key: string, bucketName?: string): Promise<{
131
- key: string;
132
- exists: boolean;
133
- queriedAt: string;
134
- ContentLength?: number;
135
- ContentType?: string;
136
- LastModified?: Date;
137
- [key: string]: any;
138
- }>;
139
-
140
- export function fileExists(key: string, bucketName?: string): Promise<boolean>;
141
- export function getFileSize(key: string, bucketName?: string): Promise<number | null>;
142
-
143
- export function generateSignedUrl(
144
- key: string,
145
- operation?: "getObject" | "putObject" | string,
146
- expiresIn?: number,
147
- bucketName?: string
148
- ): Promise<{
149
- url: string;
150
- key: string;
151
- operation: string;
152
- expiresIn: number;
153
- expiresAt: string;
154
- generatedAt: string;
155
- }>;
156
-
157
- export function createMultipartUpload(
158
- key: string,
159
- contentType?: string,
160
- metadata?: Record<string, string>,
161
- bucketName?: string
162
- ): Promise<{ uploadId: string; key: string }>;
163
-
164
- export function uploadPart(
165
- key: string,
166
- uploadId: string,
167
- partNumber: number,
168
- buffer: Buffer | Uint8Array,
169
- bucketName?: string
170
- ): Promise<{ ETag: string; partNumber: number }>;
171
-
172
- export function completeMultipartUpload(
173
- key: string,
174
- uploadId: string,
175
- parts: Array<{ partNumber: number; ETag: string }>,
176
- bucketName?: string
177
- ): Promise<{ key: string }>;
178
-
179
- export function abortMultipartUpload(
180
- key: string,
181
- uploadId: string,
182
- bucketName?: string
183
- ): Promise<{ key: string; abortedAt: string }>;
184
-
185
- export function listIncompleteMultipartUploads(
186
- prefix?: string,
187
- bucketName?: string
188
- ): Promise<IncompleteMultipartUpload[]>;
189
-
190
- export function cleanupIncompleteMultipartUploads(
191
- olderThanDays?: number,
192
- prefix?: string,
193
- bucketName?: string
194
- ): Promise<CleanupResult>;
195
-
196
- /**
197
- * Config exports (re-exported from lib/config/index.js at package root)
198
- */
199
- export const packageJson: Record<string, any>;
200
- export const appVersion: string;
201
- export const mbkbucketVar: ConfigVars;
202
- export function getLatestVersion(): Promise<string | null>;
203
- export function checkVersion(): Promise<void>;
204
- export function parseAndValidateMbkbucketVar(rawValue?: string): ConfigVars;
205
- export function parseAndValidateBucketConnection(rawValue?: string): BucketConnectionMap | null;
206
-
207
- /**
208
- * Router export (re-exported from lib/routes/index.js at package root as `bucket`)
209
- */
210
- export const bucket: Router;
211
-
212
- /**
213
- * Root default export from index.js: configured Express application
214
- */
215
- declare const server: Application;
216
- export default server;
217
-
218
- /**
219
- * Subpath module declarations
220
- */
221
- declare module "mbkbucket/lib/s3" {
222
- import { Readable } from "stream";
223
-
224
- export interface BucketConfig {
225
- BUCKET_NAME: string;
226
- ENDPOINT?: string;
227
- ACCESS_KEY_ID?: string;
228
- SECRET_ACCESS_KEY?: string;
229
- region?: string;
230
- [key: string]: any;
231
- }
232
-
233
- export type BucketConnectionMap = Record<string, BucketConfig>;
234
-
235
- export interface S3ObjectResult {
236
- Body: Readable;
237
- ContentLength?: number;
238
- ContentType?: string;
239
- LastModified?: Date;
240
- Key?: string;
241
- [key: string]: any;
242
- }
243
-
244
- export interface UploadOptions {
245
- metadata?: Record<string, string>;
246
- cacheControl?: string;
247
- storageClass?: string;
248
- serverSideEncryption?: string;
249
- bucketName?: string;
250
- preventOverwrite?: boolean;
251
- [key: string]: any;
252
- }
253
-
254
- export interface ListFilesOptions {
255
- maxKeys?: number;
256
- continuationToken?: string | null;
257
- delimiter?: string | null;
258
- fetchOwner?: boolean;
259
- startAfter?: string | null;
260
- bucketName?: string;
261
- [key: string]: any;
262
- }
263
-
264
- export interface ListFilesResult extends Record<string, any> {
265
- requestedAt: string;
266
- totalFiles: number;
267
- hasMore: boolean;
268
- nextToken: string | null;
269
- }
270
-
271
- export interface IncompleteMultipartUpload {
272
- Key?: string;
273
- UploadId?: string;
274
- Initiated?: string;
275
- Initiator?: { DisplayName?: string; [key: string]: any };
276
- [key: string]: any;
277
- }
278
-
279
- export interface CleanupResult {
280
- abortedCount: number;
281
- uploads: Array<{ key: string; uploadId: string; initiated?: string }>;
282
- cleanedAt?: string;
283
- [key: string]: any;
284
- }
285
-
286
- export function getAvailableBucketNames(): string[];
287
- export function resolveBucketName(bucketName?: string | null): string;
288
- export function getBucketConfig(bucketName?: string): BucketConfig;
289
- export const bucketClient: any;
290
- export function getAppName(): string;
291
- export function ensureKeyHasAppPrefix(key?: string): string;
292
- export function ensurePrefix(prefix?: string): string;
293
- export function getBucketClient(bucketName?: string): any;
294
- export function checkHealth(): Promise<{ status: string; responseTime?: number; bucket?: string; error?: string; checkedAt: string; region?: string; }>;
295
-
296
- export function uploadFile(
297
- key: string,
298
- fileBuffer: Buffer | Uint8Array,
299
- contentType: string,
300
- options?: UploadOptions
301
- ): Promise<{ fileSize?: number; key: string; contentType?: string; uploadedAt?: string } & Record<string, any>>;
302
-
303
- export function downloadFile(
304
- key: string,
305
- options?: {
306
- range?: string | null;
307
- ifNoneMatch?: string | null;
308
- ifModifiedSince?: Date | string | null;
309
- responseCacheControl?: string | null;
310
- responseContentType?: string | null;
311
- bucketName?: string;
312
- [key: string]: any;
313
- }
314
- ): Promise<S3ObjectResult>;
315
-
316
- export function deleteFile(key: string, bucketName?: string): Promise<{ key: string; deletedAt?: string } & Record<string, any>>;
317
- export function deleteFiles(keys: string[], bucketName?: string): Promise<{
318
- results: any[];
319
- deletedCount: number;
320
- errors: any[];
321
- deletedAt: string;
322
- }>;
323
-
324
- export function deleteFolder(prefix: string, bucketName?: string): Promise<{
325
- results?: any[];
326
- deletedCount: number;
327
- errors?: any[];
328
- deletedAt: string;
329
- prefix?: string;
330
- }>;
331
-
332
- export function listfiles(prefix?: string, options?: ListFilesOptions): Promise<ListFilesResult>;
333
-
334
- export function getFileMetadata(key: string, bucketName?: string): Promise<{
335
- key: string;
336
- exists: boolean;
337
- queriedAt: string;
338
- ContentLength?: number;
339
- ContentType?: string;
340
- LastModified?: Date;
341
- [key: string]: any;
342
- }>;
343
-
344
- export function fileExists(key: string, bucketName?: string): Promise<boolean>;
345
- export function getFileSize(key: string, bucketName?: string): Promise<number | null>;
346
-
347
- export function generateSignedUrl(
348
- key: string,
349
- operation?: "getObject" | "putObject" | string,
350
- expiresIn?: number,
351
- bucketName?: string
352
- ): Promise<{
353
- url: string;
354
- key: string;
355
- operation: string;
356
- expiresIn: number;
357
- expiresAt: string;
358
- generatedAt: string;
359
- }>;
360
-
361
- export function createMultipartUpload(
362
- key: string,
363
- contentType?: string,
364
- metadata?: Record<string, string>,
365
- bucketName?: string
366
- ): Promise<{ uploadId: string; key: string }>;
367
-
368
- export function uploadPart(
369
- key: string,
370
- uploadId: string,
371
- partNumber: number,
372
- buffer: Buffer | Uint8Array,
373
- bucketName?: string
374
- ): Promise<{ ETag: string; partNumber: number }>;
375
-
376
- export function completeMultipartUpload(
377
- key: string,
378
- uploadId: string,
379
- parts: Array<{ partNumber: number; ETag: string }>,
380
- bucketName?: string
381
- ): Promise<{ key: string }>;
382
-
383
- export function abortMultipartUpload(
384
- key: string,
385
- uploadId: string,
386
- bucketName?: string
387
- ): Promise<{ key: string; abortedAt: string }>;
388
-
389
- export function listIncompleteMultipartUploads(
390
- prefix?: string,
391
- bucketName?: string
392
- ): Promise<IncompleteMultipartUpload[]>;
393
-
394
- export function cleanupIncompleteMultipartUploads(
395
- olderThanDays?: number,
396
- prefix?: string,
397
- bucketName?: string
398
- ): Promise<CleanupResult>;
399
- }
400
-
401
- declare module "mbkbucket/lib/config/index" {
402
- export interface ConfigVars {
403
- publiView_enabled: boolean;
404
- p_view_inline: boolean;
405
- [key: string]: any;
406
- }
407
-
408
- export interface BucketConfig {
409
- BUCKET_NAME: string;
410
- ENDPOINT?: string;
411
- ACCESS_KEY_ID?: string;
412
- SECRET_ACCESS_KEY?: string;
413
- region?: string;
414
- [key: string]: any;
415
- }
416
-
417
- export type BucketConnectionMap = Record<string, BucketConfig>;
418
-
419
- export const packageJson: Record<string, any>;
420
- export const appVersion: string;
421
- export const mbkbucketVar: ConfigVars;
422
- export function getLatestVersion(): Promise<string | null>;
423
- export function checkVersion(): Promise<void>;
424
- export function parseAndValidateMbkbucketVar(rawValue?: string): ConfigVars;
425
- export function parseAndValidateBucketConnection(rawValue?: string): BucketConnectionMap | null;
426
- }
427
-
428
- declare module "mbkbucket/lib/config/validation" {
429
- export function normalizeBooleanLike(value: any): any;
430
- export function parseAndValidateMbkbucketVar(rawValue?: string): { [key: string]: any };
431
- export function parseAndValidateBucketConnection(rawValue?: string): Record<string, any> | null;
432
- }
433
-
434
- declare module "mbkbucket/lib/routes/index" {
435
- import { Router } from "express";
436
- const router: Router;
437
- export default router;
438
- }
439
-
440
- declare module "mbkbucket/lib/bucket" {
441
- import { Router } from "express";
442
- const router: Router;
443
- export default router;
444
- }
package/lib/index.js DELETED
@@ -1,17 +0,0 @@
1
- // Barrel file: re-export all public items from the restructured src/ directory
2
- export * from '../src/services/s3.service.js';
3
- export * from '../src/config/index.js';
4
- export { default as bucket } from '../src/routes/index.js';
5
-
6
- import * as s3 from '../src/services/s3.service.js';
7
- import * as config from '../src/config/index.js';
8
- import bucket from '../src/routes/index.js';
9
-
10
- // Default aggregate export for convenience
11
- const defaultExport = {
12
- ...s3,
13
- ...config,
14
- bucket,
15
- };
16
-
17
- export default defaultExport;
@@ -1,116 +0,0 @@
1
- import test from 'node:test';
2
- import assert from 'node:assert/strict';
3
- import { parseAndValidateMbkbucketVar, parseAndValidateBucketConnection, normalizeBooleanLike } from '../src/config/validation.js';
4
-
5
- test('parseAndValidateMbkbucketVar applies defaults when empty', () => {
6
- const cfg = parseAndValidateMbkbucketVar(undefined);
7
- assert.equal(cfg.p_view_inline, true);
8
- assert.equal(cfg.publiView_enabled, false);
9
- });
10
-
11
- test('parseAndValidateMbkbucketVar normalizes boolean-like strings', () => {
12
- const cfg = parseAndValidateMbkbucketVar(JSON.stringify({
13
- p_view_inline: 'false',
14
- publiView_enabled: 'true'
15
- }));
16
-
17
- assert.equal(cfg.p_view_inline, false);
18
- assert.equal(cfg.publiView_enabled, true);
19
- });
20
-
21
- test('parseAndValidateMbkbucketVar rejects invalid JSON', () => {
22
- assert.throws(() => parseAndValidateMbkbucketVar('{oops'), /Invalid JSON/);
23
- });
24
-
25
- test('parseAndValidateMbkbucketVar rejects invalid boolean values', () => {
26
- assert.throws(() => parseAndValidateMbkbucketVar(JSON.stringify({
27
- p_view_inline: 'not-bool'
28
- })), /must be a boolean/);
29
- });
30
-
31
- test('parseAndValidateMbkbucketVar accepts common boolean aliases', () => {
32
- const cfg = parseAndValidateMbkbucketVar(JSON.stringify({
33
- p_view_inline: ' ON ',
34
- publiView_enabled: '0'
35
- }));
36
-
37
- assert.equal(cfg.p_view_inline, true);
38
- assert.equal(cfg.publiView_enabled, false);
39
- });
40
-
41
- test('parseAndValidateMbkbucketVar rejects non-object values', () => {
42
- assert.throws(() => parseAndValidateMbkbucketVar('null'), /must be a valid object/);
43
- assert.throws(() => parseAndValidateMbkbucketVar('[]'), /must be a valid object/);
44
- });
45
-
46
- test('normalizeBooleanLike returns untouched for unsupported values', () => {
47
- assert.equal(normalizeBooleanLike('maybe'), 'maybe');
48
- assert.equal(normalizeBooleanLike(123), 123);
49
- });
50
-
51
- test('parseAndValidateBucketConnection accepts multi-bucket config', () => {
52
- const raw = JSON.stringify({
53
- R2_Bucket: {
54
- BUCKET_NAME: 'my-r2-bucket',
55
- ACCESS_KEY_ID: 'abc',
56
- SECRET_ACCESS_KEY: 'def',
57
- ENDPOINT: 'https://example.r2.cloudflarestorage.com'
58
- },
59
- S3_Bucket: {
60
- BUCKET_NAME: 'my-s3-bucket',
61
- ACCESS_KEY_ID: 'ghi',
62
- SECRET_ACCESS_KEY: 'jkl',
63
- ENDPOINT: 'https://s3.ap-southeast-1.amazonaws.com'
64
- }
65
- });
66
-
67
- const cfg = parseAndValidateBucketConnection(raw);
68
- assert.deepEqual(Object.keys(cfg), ['R2_Bucket', 'S3_Bucket']);
69
- });
70
-
71
- test('parseAndValidateBucketConnection returns null when unset', () => {
72
- assert.equal(parseAndValidateBucketConnection(undefined), null);
73
- assert.equal(parseAndValidateBucketConnection(''), null);
74
- });
75
-
76
- test('parseAndValidateBucketConnection rejects invalid JSON', () => {
77
- assert.throws(() => parseAndValidateBucketConnection('{oops'), /not valid JSON/);
78
- });
79
-
80
- test('parseAndValidateBucketConnection rejects empty object and array', () => {
81
- assert.throws(() => parseAndValidateBucketConnection('{}'), /non-empty object/);
82
- assert.throws(() => parseAndValidateBucketConnection('[]'), /non-empty object/);
83
- });
84
-
85
- test('parseAndValidateBucketConnection rejects missing required fields', () => {
86
- const raw = JSON.stringify({
87
- bad: {
88
- BUCKET_NAME: 'x',
89
- ACCESS_KEY_ID: 'y',
90
- ENDPOINT: 'https://example.com'
91
- }
92
- });
93
-
94
- assert.throws(() => parseAndValidateBucketConnection(raw), /missing required fields/);
95
- });
96
-
97
- test('parseAndValidateBucketConnection rejects quoted inner object shape', () => {
98
- const raw = JSON.stringify({
99
- bad: '{"BUCKET_NAME":"x"}'
100
- });
101
-
102
- assert.throws(() => parseAndValidateBucketConnection(raw), /must be an object/);
103
- });
104
-
105
- test('parseAndValidateBucketConnection rejects empty required fields', () => {
106
- const raw = JSON.stringify({
107
- bad: {
108
- BUCKET_NAME: '',
109
- ACCESS_KEY_ID: 'abc',
110
- SECRET_ACCESS_KEY: 'def',
111
- ENDPOINT: 'https://example.com'
112
- }
113
- });
114
-
115
- assert.throws(() => parseAndValidateBucketConnection(raw), /missing required fields/);
116
- });
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes