@venizia/ignis-docs 0.0.5 → 0.0.6-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.
Files changed (98) hide show
  1. package/package.json +1 -1
  2. package/wiki/best-practices/architecture-decisions.md +0 -8
  3. package/wiki/best-practices/code-style-standards/control-flow.md +1 -1
  4. package/wiki/best-practices/performance-optimization.md +3 -3
  5. package/wiki/best-practices/security-guidelines.md +2 -2
  6. package/wiki/best-practices/troubleshooting-tips.md +1 -1
  7. package/wiki/guides/core-concepts/components-guide.md +1 -1
  8. package/wiki/guides/core-concepts/components.md +2 -2
  9. package/wiki/guides/core-concepts/dependency-injection.md +1 -1
  10. package/wiki/guides/core-concepts/services.md +1 -1
  11. package/wiki/guides/tutorials/building-a-crud-api.md +1 -1
  12. package/wiki/guides/tutorials/ecommerce-api.md +2 -2
  13. package/wiki/guides/tutorials/realtime-chat.md +6 -6
  14. package/wiki/guides/tutorials/testing.md +1 -1
  15. package/wiki/references/base/bootstrapping.md +0 -2
  16. package/wiki/references/base/components.md +2 -2
  17. package/wiki/references/base/controllers.md +0 -1
  18. package/wiki/references/base/datasources.md +1 -1
  19. package/wiki/references/base/dependency-injection.md +1 -1
  20. package/wiki/references/base/filter-system/quick-reference.md +0 -14
  21. package/wiki/references/base/middlewares.md +0 -8
  22. package/wiki/references/base/providers.md +0 -9
  23. package/wiki/references/base/services.md +0 -1
  24. package/wiki/references/components/authentication/api.md +444 -0
  25. package/wiki/references/components/authentication/errors.md +177 -0
  26. package/wiki/references/components/authentication/index.md +571 -0
  27. package/wiki/references/components/authentication/usage.md +781 -0
  28. package/wiki/references/components/health-check.md +292 -103
  29. package/wiki/references/components/index.md +14 -12
  30. package/wiki/references/components/mail/api.md +505 -0
  31. package/wiki/references/components/mail/errors.md +176 -0
  32. package/wiki/references/components/mail/index.md +535 -0
  33. package/wiki/references/components/mail/usage.md +404 -0
  34. package/wiki/references/components/request-tracker.md +229 -25
  35. package/wiki/references/components/socket-io/api.md +1051 -0
  36. package/wiki/references/components/socket-io/errors.md +119 -0
  37. package/wiki/references/components/socket-io/index.md +410 -0
  38. package/wiki/references/components/socket-io/usage.md +322 -0
  39. package/wiki/references/components/static-asset/api.md +261 -0
  40. package/wiki/references/components/static-asset/errors.md +89 -0
  41. package/wiki/references/components/static-asset/index.md +617 -0
  42. package/wiki/references/components/static-asset/usage.md +364 -0
  43. package/wiki/references/components/swagger.md +390 -110
  44. package/wiki/references/components/template/api-page.md +125 -0
  45. package/wiki/references/components/template/errors-page.md +100 -0
  46. package/wiki/references/components/template/index.md +104 -0
  47. package/wiki/references/components/template/setup-page.md +134 -0
  48. package/wiki/references/components/template/single-page.md +132 -0
  49. package/wiki/references/components/template/usage-page.md +127 -0
  50. package/wiki/references/components/websocket/api.md +508 -0
  51. package/wiki/references/components/websocket/errors.md +123 -0
  52. package/wiki/references/components/websocket/index.md +453 -0
  53. package/wiki/references/components/websocket/usage.md +475 -0
  54. package/wiki/references/helpers/cron/index.md +224 -0
  55. package/wiki/references/helpers/crypto/index.md +537 -0
  56. package/wiki/references/helpers/env/index.md +214 -0
  57. package/wiki/references/helpers/error/index.md +232 -0
  58. package/wiki/references/helpers/index.md +16 -15
  59. package/wiki/references/helpers/inversion/index.md +608 -0
  60. package/wiki/references/helpers/logger/index.md +600 -0
  61. package/wiki/references/helpers/network/api.md +986 -0
  62. package/wiki/references/helpers/network/index.md +620 -0
  63. package/wiki/references/helpers/queue/index.md +589 -0
  64. package/wiki/references/helpers/redis/index.md +495 -0
  65. package/wiki/references/helpers/socket-io/api.md +497 -0
  66. package/wiki/references/helpers/socket-io/index.md +513 -0
  67. package/wiki/references/helpers/storage/api.md +705 -0
  68. package/wiki/references/helpers/storage/index.md +583 -0
  69. package/wiki/references/helpers/template/index.md +66 -0
  70. package/wiki/references/helpers/template/single-page.md +126 -0
  71. package/wiki/references/helpers/testing/index.md +510 -0
  72. package/wiki/references/helpers/types/index.md +512 -0
  73. package/wiki/references/helpers/uid/index.md +272 -0
  74. package/wiki/references/helpers/websocket/api.md +736 -0
  75. package/wiki/references/helpers/websocket/index.md +574 -0
  76. package/wiki/references/helpers/worker-thread/index.md +470 -0
  77. package/wiki/references/quick-reference.md +3 -18
  78. package/wiki/references/utilities/jsx.md +1 -8
  79. package/wiki/references/utilities/statuses.md +0 -7
  80. package/wiki/references/components/authentication.md +0 -476
  81. package/wiki/references/components/mail.md +0 -687
  82. package/wiki/references/components/socket-io.md +0 -562
  83. package/wiki/references/components/static-asset.md +0 -1277
  84. package/wiki/references/helpers/cron.md +0 -108
  85. package/wiki/references/helpers/crypto.md +0 -132
  86. package/wiki/references/helpers/env.md +0 -83
  87. package/wiki/references/helpers/error.md +0 -97
  88. package/wiki/references/helpers/inversion.md +0 -176
  89. package/wiki/references/helpers/logger.md +0 -296
  90. package/wiki/references/helpers/network.md +0 -396
  91. package/wiki/references/helpers/queue.md +0 -150
  92. package/wiki/references/helpers/redis.md +0 -142
  93. package/wiki/references/helpers/socket-io.md +0 -932
  94. package/wiki/references/helpers/storage.md +0 -665
  95. package/wiki/references/helpers/testing.md +0 -133
  96. package/wiki/references/helpers/types.md +0 -167
  97. package/wiki/references/helpers/uid.md +0 -167
  98. package/wiki/references/helpers/worker-thread.md +0 -178
@@ -0,0 +1,705 @@
1
+ # Storage -- API Reference
2
+
3
+ ## Architecture
4
+
5
+ The storage system uses a class hierarchy with an abstract base class providing shared logic and two concrete implementations for different backends. `MemoryStorageHelper` is a separate, standalone class that does not participate in the `IStorageHelper` hierarchy.
6
+
7
+ ```
8
+ BaseHelper
9
+ ├── BaseStorageHelper (abstract, implements IStorageHelper)
10
+ │ ├── MinioHelper -- S3-compatible object storage
11
+ │ └── DiskHelper -- Local filesystem storage
12
+ └── MemoryStorageHelper -- In-memory key-value store
13
+ ```
14
+
15
+ ## BaseStorageHelper
16
+
17
+ Abstract base class that extends `BaseHelper` and implements `IStorageHelper`. Provides name validation, MIME type detection, and file type categorization. All bucket and file operation methods are abstract and must be implemented by subclasses.
18
+
19
+ ### Constructor
20
+
21
+ ```typescript
22
+ constructor(opts: { scope: string; identifier: string })
23
+ ```
24
+
25
+ | Parameter | Type | Description |
26
+ |-----------|------|-------------|
27
+ | `scope` | `string` | Logger scope name. |
28
+ | `identifier` | `string` | Helper identifier. |
29
+
30
+ ### Static Properties
31
+
32
+ #### MIME_MAP
33
+
34
+ ```typescript
35
+ protected static MIME_MAP: Record<string, string>
36
+ ```
37
+
38
+ Extension-to-MIME-type mapping used by `getMimeType()`:
39
+
40
+ | Extension | MIME Type |
41
+ |-----------|-----------|
42
+ | `.png` | `image/png` |
43
+ | `.jpg`, `.jpeg` | `image/jpeg` |
44
+ | `.gif` | `image/gif` |
45
+ | `.webp` | `image/webp` |
46
+ | `.svg` | `image/svg+xml` |
47
+ | `.pdf` | `application/pdf` |
48
+ | `.json` | `application/json` |
49
+ | `.txt` | `text/plain` |
50
+ | `.html` | `text/html` |
51
+ | `.css` | `text/css` |
52
+ | `.js` | `text/javascript` |
53
+ | `.mp4` | `video/mp4` |
54
+ | `.webm` | `video/webm` |
55
+ | `.mp3` | `audio/mpeg` |
56
+ | `.wav` | `audio/wav` |
57
+ | `.zip` | `application/zip` |
58
+ | `.csv` | `text/csv` |
59
+ | `.xml` | `application/xml` |
60
+
61
+ Falls back to `application/octet-stream` for unrecognized extensions.
62
+
63
+ ### Methods
64
+
65
+ #### getMimeType
66
+
67
+ ```typescript
68
+ getMimeType(filename: string): string
69
+ ```
70
+
71
+ Returns the MIME type for a filename based on its extension. Extracts the extension using `path.extname()`, converts to lowercase, and looks it up in `MIME_MAP`.
72
+
73
+ | Parameter | Type | Description |
74
+ |-----------|------|-------------|
75
+ | `filename` | `string` | Filename with extension (e.g., `'photo.jpg'`). |
76
+
77
+ **Returns:** MIME type string, or `'application/octet-stream'` if unrecognized.
78
+
79
+ #### isValidName
80
+
81
+ ```typescript
82
+ isValidName(name: string): boolean
83
+ ```
84
+
85
+ Validates a bucket or file name against security rules. Logs specific error messages for each validation failure.
86
+
87
+ | Parameter | Type | Description |
88
+ |-----------|------|-------------|
89
+ | `name` | `string` | Name to validate. |
90
+
91
+ **Returns:** `true` if the name passes all checks, `false` otherwise.
92
+
93
+ **Validation rules (checked in order):**
94
+
95
+ 1. Must be a string type
96
+ 2. Must not be empty or null
97
+ 3. Must not contain `..`, `/`, or `\` (path traversal)
98
+ 4. Must not start with `.` (hidden files)
99
+ 5. Must not contain `;`, `|`, `&`, `$`, `` ` ``, `<`, `>`, `{`, `}`, `[`, `]`, `!`, `#` (shell injection)
100
+ 6. Must not contain `\n`, `\r`, or `\0` (header injection)
101
+ 7. Must not exceed 255 characters (DoS prevention)
102
+ 8. Must not be whitespace-only
103
+
104
+ #### getFileType
105
+
106
+ ```typescript
107
+ getFileType(opts: { mimeType: string }): string
108
+ ```
109
+
110
+ Categorizes a MIME type into a broad file type group using the `MimeTypes` constants.
111
+
112
+ | Parameter | Type | Description |
113
+ |-----------|------|-------------|
114
+ | `opts.mimeType` | `string` | Full MIME type string (e.g., `'image/png'`). |
115
+
116
+ **Returns:** One of `'image'`, `'video'`, `'text'`, or `'unknown'`.
117
+
118
+ ### Abstract Methods
119
+
120
+ The following methods are declared abstract in `BaseStorageHelper` and implemented by `MinioHelper` and `DiskHelper`:
121
+
122
+ ```typescript
123
+ abstract isBucketExists(opts: { name: string }): Promise<boolean>;
124
+ abstract getBuckets(): Promise<IBucketInfo[]>;
125
+ abstract getBucket(opts: { name: string }): Promise<IBucketInfo | null>;
126
+ abstract createBucket(opts: { name: string }): Promise<IBucketInfo | null>;
127
+ abstract removeBucket(opts: { name: string }): Promise<boolean>;
128
+
129
+ abstract upload(opts: {
130
+ bucket: string;
131
+ files: IUploadFile[];
132
+ normalizeNameFn?: (opts: { originalName: string; folderPath?: string }) => string;
133
+ normalizeLinkFn?: (opts: { bucketName: string; normalizeName: string }) => string;
134
+ }): Promise<IUploadResult[]>;
135
+
136
+ abstract getFile(opts: { bucket: string; name: string; options?: any }): Promise<Readable>;
137
+ abstract getStat(opts: { bucket: string; name: string }): Promise<IFileStat>;
138
+ abstract removeObject(opts: { bucket: string; name: string }): Promise<void>;
139
+ abstract removeObjects(opts: { bucket: string; names: string[] }): Promise<void>;
140
+ abstract listObjects(opts: {
141
+ bucket: string;
142
+ prefix?: string;
143
+ useRecursive?: boolean;
144
+ maxKeys?: number;
145
+ }): Promise<IObjectInfo[]>;
146
+ ```
147
+
148
+ ## MinioHelper
149
+
150
+ S3-compatible object storage client built on the `minio` package. Extends `BaseStorageHelper`.
151
+
152
+ ### Constructor
153
+
154
+ ```typescript
155
+ constructor(options: IMinioHelperOptions)
156
+ ```
157
+
158
+ Creates a new `minio.Client` internally and stores it as `this.client`.
159
+
160
+ ```typescript
161
+ interface IMinioHelperOptions extends IStorageHelperOptions, ClientOptions {}
162
+ ```
163
+
164
+ | Parameter | Type | Default | Description |
165
+ |-----------|------|---------|-------------|
166
+ | `options.endPoint` | `string` | -- | MinIO server hostname. |
167
+ | `options.port` | `number` | -- | Server port. |
168
+ | `options.useSSL` | `boolean` | -- | Enable HTTPS. |
169
+ | `options.accessKey` | `string` | -- | Access key credential. |
170
+ | `options.secretKey` | `string` | -- | Secret key credential. |
171
+ | `options.scope` | `string` | `'MinioHelper'` | Logger scope name. |
172
+ | `options.identifier` | `string` | `'MinioHelper'` | Helper identifier. |
173
+
174
+ All additional `minio.ClientOptions` properties are also accepted and passed to the underlying client.
175
+
176
+ ### Properties
177
+
178
+ | Property | Type | Description |
179
+ |----------|------|-------------|
180
+ | `client` | `minio.Client` | The underlying MinIO client instance. Accessible for direct SDK operations. |
181
+
182
+ ### Methods
183
+
184
+ #### isBucketExists
185
+
186
+ ```typescript
187
+ async isBucketExists(opts: { name: string }): Promise<boolean>
188
+ ```
189
+
190
+ Returns `false` if the name fails `isValidName()`. Otherwise delegates to `client.bucketExists()`.
191
+
192
+ #### getBuckets
193
+
194
+ ```typescript
195
+ async getBuckets(): Promise<IBucketInfo[]>
196
+ ```
197
+
198
+ Lists all buckets via `client.listBuckets()`.
199
+
200
+ #### getBucket
201
+
202
+ ```typescript
203
+ async getBucket(opts: { name: string }): Promise<IBucketInfo | null>
204
+ ```
205
+
206
+ Returns the bucket info if it exists, or `null` if not found. Calls `isBucketExists()` first, then searches the full bucket list.
207
+
208
+ #### createBucket
209
+
210
+ ```typescript
211
+ async createBucket(opts: { name: string }): Promise<IBucketInfo | null>
212
+ ```
213
+
214
+ Creates a bucket via `client.makeBucket()`. Throws if the name fails validation.
215
+
216
+ **Throws:** `'[createBucket] Invalid name to create bucket!'`
217
+
218
+ #### removeBucket
219
+
220
+ ```typescript
221
+ async removeBucket(opts: { name: string }): Promise<boolean>
222
+ ```
223
+
224
+ Removes a bucket via `client.removeBucket()`. Throws if the name fails validation.
225
+
226
+ **Throws:** `'[removeBucket] Invalid name to remove bucket!'`
227
+
228
+ #### upload
229
+
230
+ ```typescript
231
+ async upload(opts: {
232
+ bucket: string;
233
+ files: IUploadFile[];
234
+ normalizeNameFn?: (opts: { originalName: string; folderPath?: string }) => string;
235
+ normalizeLinkFn?: (opts: { bucketName: string; normalizeName: string }) => string;
236
+ }): Promise<IUploadResult[]>
237
+ ```
238
+
239
+ Uploads files to a MinIO bucket. Returns `[]` if `files` is empty. Validates the bucket exists and all file names/sizes before uploading. Uploads run in parallel via `Promise.all()`.
240
+
241
+ **Default name normalization:** Lowercased with spaces replaced by `_`. If `folderPath` is set, prepends `{folderPath}/`.
242
+
243
+ **Default link format:** `/static-assets/{bucket}/{encodeURIComponent(normalizeName)}`
244
+
245
+ **Metadata stored:** `originalName`, `normalizeName`, `size`, `encoding`, `mimeType`.
246
+
247
+ **Throws:**
248
+ - `'[upload] Bucket does not exist | name: {bucket}'`
249
+ - `'[upload] Invalid original file name'`
250
+ - `'[upload] Invalid folder path'`
251
+ - `'[upload] Invalid file size'`
252
+
253
+ #### getFile
254
+
255
+ ```typescript
256
+ getFile(opts: {
257
+ bucket: string;
258
+ name: string;
259
+ options?: {
260
+ versionId?: string;
261
+ SSECustomerAlgorithm?: string;
262
+ SSECustomerKey?: string;
263
+ SSECustomerKeyMD5?: string;
264
+ };
265
+ }): Promise<Readable>
266
+ ```
267
+
268
+ Returns a readable stream for the file via `client.getObject()`. Supports versioning and server-side encryption options.
269
+
270
+ | Parameter | Type | Description |
271
+ |-----------|------|-------------|
272
+ | `opts.bucket` | `string` | Bucket name. |
273
+ | `opts.name` | `string` | Object name. |
274
+ | `opts.options.versionId` | `string` | Specific version to retrieve. |
275
+ | `opts.options.SSECustomerAlgorithm` | `string` | SSE-C algorithm (e.g., `'AES256'`). |
276
+ | `opts.options.SSECustomerKey` | `string` | SSE-C encryption key. |
277
+ | `opts.options.SSECustomerKeyMD5` | `string` | MD5 hash of the encryption key. |
278
+
279
+ #### getStat
280
+
281
+ ```typescript
282
+ async getStat(opts: { bucket: string; name: string }): Promise<IFileStat>
283
+ ```
284
+
285
+ Returns file metadata via `client.statObject()`.
286
+
287
+ **Returns:** `IFileStat` with `size`, `metadata` (from MinIO's `metaData`), `lastModified`, `etag`, and `versionId`.
288
+
289
+ #### removeObject
290
+
291
+ ```typescript
292
+ async removeObject(opts: { bucket: string; name: string }): Promise<void>
293
+ ```
294
+
295
+ Removes a single object via `client.removeObject()`.
296
+
297
+ #### removeObjects
298
+
299
+ ```typescript
300
+ async removeObjects(opts: { bucket: string; names: string[] }): Promise<void>
301
+ ```
302
+
303
+ Removes multiple objects in a single batch via `client.removeObjects()`.
304
+
305
+ #### listObjects
306
+
307
+ ```typescript
308
+ async listObjects(opts: {
309
+ bucket: string;
310
+ prefix?: string;
311
+ useRecursive?: boolean;
312
+ maxKeys?: number;
313
+ }): Promise<IObjectInfo[]>
314
+ ```
315
+
316
+ Lists objects in a bucket using a streaming approach via `client.listObjects()`. The stream is destroyed early if `maxKeys` is reached.
317
+
318
+ | Parameter | Type | Default | Description |
319
+ |-----------|------|---------|-------------|
320
+ | `opts.bucket` | `string` | -- | Bucket to list. |
321
+ | `opts.prefix` | `string` | `''` | Filter by prefix. |
322
+ | `opts.useRecursive` | `boolean` | `false` | List recursively through subdirectories. |
323
+ | `opts.maxKeys` | `number` | `undefined` | Maximum number of objects to return. |
324
+
325
+ ## DiskHelper
326
+
327
+ Local filesystem storage using directory-based buckets. Extends `BaseStorageHelper`.
328
+
329
+ ### Constructor
330
+
331
+ ```typescript
332
+ constructor(options: IDiskHelperOptions)
333
+ ```
334
+
335
+ Resolves `basePath` to an absolute path and creates it if it does not exist.
336
+
337
+ ```typescript
338
+ interface IDiskHelperOptions extends IStorageHelperOptions {
339
+ basePath: string;
340
+ }
341
+ ```
342
+
343
+ | Parameter | Type | Default | Description |
344
+ |-----------|------|---------|-------------|
345
+ | `options.basePath` | `string` | -- | Base directory for storage. Resolved to an absolute path. Created automatically. |
346
+ | `options.scope` | `string` | `'DiskHelper'` | Logger scope name. |
347
+ | `options.identifier` | `string` | `'DiskHelper'` | Helper identifier. |
348
+
349
+ ### Methods
350
+
351
+ #### isBucketExists
352
+
353
+ ```typescript
354
+ async isBucketExists(opts: { name: string }): Promise<boolean>
355
+ ```
356
+
357
+ Returns `false` if the name fails validation. Otherwise checks if the bucket path exists and is a directory.
358
+
359
+ #### getBuckets
360
+
361
+ ```typescript
362
+ async getBuckets(): Promise<IBucketInfo[]>
363
+ ```
364
+
365
+ Lists all directories under `basePath`. Returns each directory as a bucket with its `birthtime` as `creationDate`. Returns `[]` if the base path does not exist.
366
+
367
+ #### getBucket
368
+
369
+ ```typescript
370
+ async getBucket(opts: { name: string }): Promise<IBucketInfo | null>
371
+ ```
372
+
373
+ Returns bucket info with `birthtime` as `creationDate`, or `null` if the bucket does not exist.
374
+
375
+ #### createBucket
376
+
377
+ ```typescript
378
+ async createBucket(opts: { name: string }): Promise<IBucketInfo | null>
379
+ ```
380
+
381
+ Creates a directory under `basePath`. Throws if the name fails validation or the bucket already exists.
382
+
383
+ **Throws:**
384
+ - `'[createBucket] Invalid name to create bucket!'`
385
+ - `'[createBucket] Bucket already exists | name: {name}'`
386
+
387
+ #### removeBucket
388
+
389
+ ```typescript
390
+ async removeBucket(opts: { name: string }): Promise<boolean>
391
+ ```
392
+
393
+ Removes the bucket directory. Throws if the name fails validation, the bucket does not exist, or the bucket is not empty.
394
+
395
+ **Throws:**
396
+ - `'[removeBucket] Invalid name to remove bucket!'`
397
+ - `'[removeBucket] Bucket does not exist | name: {name}'`
398
+ - `'[removeBucket] Bucket is not empty | name: {name}'`
399
+
400
+ #### upload
401
+
402
+ ```typescript
403
+ async upload(opts: {
404
+ bucket: string;
405
+ files: IUploadFile[];
406
+ normalizeNameFn?: (opts: { originalName: string; folderPath?: string }) => string;
407
+ normalizeLinkFn?: (opts: { bucketName: string; normalizeName: string }) => string;
408
+ }): Promise<IUploadResult[]>
409
+ ```
410
+
411
+ Writes files to the bucket directory. Returns `[]` if `files` is empty. Validates the bucket exists and all file names/sizes before writing. Uploads run in parallel via `Promise.all()`. Subdirectories are created automatically if `normalizeName` contains path separators.
412
+
413
+ **Default name normalization:** Same as MinioHelper -- lowercased with spaces replaced by `_`.
414
+
415
+ **Default link format:** `/static-resources/{bucket}/{encodeURIComponent(normalizeName)}`
416
+
417
+ **Throws:**
418
+ - `'[upload] Bucket does not exist | name: {bucket}'`
419
+ - `'[upload] Invalid original file name'`
420
+ - `'[upload] Invalid folder path'`
421
+ - `'[upload] Invalid file size'`
422
+
423
+ #### getFile
424
+
425
+ ```typescript
426
+ async getFile(opts: { bucket: string; name: string; options?: any }): Promise<Readable>
427
+ ```
428
+
429
+ Returns a `fs.createReadStream()` for the file. Throws if the file does not exist. The `options` parameter is accepted for interface compatibility but is not used.
430
+
431
+ **Throws:** `'[getFile] File not found | bucket: {bucket} | name: {name}'`
432
+
433
+ #### getStat
434
+
435
+ ```typescript
436
+ async getStat(opts: { bucket: string; name: string }): Promise<IFileStat>
437
+ ```
438
+
439
+ Returns file metadata from the filesystem. The `metadata` field contains `mimetype` detected via `getMimeType()`. Does not return `etag` or `versionId`.
440
+
441
+ **Throws:** `'[getStat] File not found | bucket: {bucket} | name: {name}'`
442
+
443
+ **Returns:**
444
+
445
+ ```typescript
446
+ {
447
+ size: number; // from fs stat
448
+ lastModified: Date; // from fs stat mtime
449
+ metadata: {
450
+ mimetype: string; // detected via getMimeType()
451
+ };
452
+ }
453
+ ```
454
+
455
+ #### removeObject
456
+
457
+ ```typescript
458
+ async removeObject(opts: { bucket: string; name: string }): Promise<void>
459
+ ```
460
+
461
+ Deletes a file via `fsp.unlink()`. Throws if the file does not exist.
462
+
463
+ **Throws:** `'[removeObject] File not found | bucket: {bucket} | name: {name}'`
464
+
465
+ #### removeObjects
466
+
467
+ ```typescript
468
+ async removeObjects(opts: { bucket: string; names: string[] }): Promise<void>
469
+ ```
470
+
471
+ Deletes multiple files sequentially by calling `removeObject()` for each name. If any file does not exist, the error propagates immediately.
472
+
473
+ #### listObjects
474
+
475
+ ```typescript
476
+ async listObjects(opts: {
477
+ bucket: string;
478
+ prefix?: string;
479
+ useRecursive?: boolean;
480
+ maxKeys?: number;
481
+ }): Promise<IObjectInfo[]>
482
+ ```
483
+
484
+ Scans the bucket directory. Returns `[]` if the bucket path does not exist. Only files matching the `prefix` are included. Subdirectories are only traversed when `useRecursive` is `true`. Stops scanning when `maxKeys` is reached.
485
+
486
+ | Parameter | Type | Default | Description |
487
+ |-----------|------|---------|-------------|
488
+ | `opts.bucket` | `string` | -- | Bucket to list. |
489
+ | `opts.prefix` | `string` | `''` | Filter by name prefix. |
490
+ | `opts.useRecursive` | `boolean` | `false` | Traverse subdirectories. |
491
+ | `opts.maxKeys` | `number` | `undefined` | Maximum objects to return. |
492
+
493
+ **Returns:** Array of `IObjectInfo` with `name`, `size`, `lastModified`. The `etag` field is always `undefined` for disk storage.
494
+
495
+ ## MemoryStorageHelper
496
+
497
+ Generic in-memory key-value store. Extends `BaseHelper` directly. Does **not** implement `IStorageHelper`.
498
+
499
+ ```typescript
500
+ class MemoryStorageHelper<T extends object = AnyObject> extends BaseHelper
501
+ ```
502
+
503
+ ### Constructor
504
+
505
+ ```typescript
506
+ constructor(opts?: { scope?: string })
507
+ ```
508
+
509
+ | Parameter | Type | Default | Description |
510
+ |-----------|------|---------|-------------|
511
+ | `opts.scope` | `string` | `'MemoryStorageHelper'` | Logger scope name. |
512
+
513
+ ### Static Methods
514
+
515
+ #### newInstance
516
+
517
+ ```typescript
518
+ static newInstance<T extends object = AnyObject>(): MemoryStorageHelper<T>
519
+ ```
520
+
521
+ Factory method that creates and returns a new `MemoryStorageHelper` instance.
522
+
523
+ ### Methods
524
+
525
+ #### isBound
526
+
527
+ ```typescript
528
+ isBound(key: string): boolean
529
+ ```
530
+
531
+ Returns `true` if the key exists in the container (uses the `in` operator).
532
+
533
+ #### get
534
+
535
+ ```typescript
536
+ get<R>(key: keyof T): R
537
+ ```
538
+
539
+ Returns the value for the given key, cast to type `R`.
540
+
541
+ #### set
542
+
543
+ ```typescript
544
+ set<R>(key: string, value: R): void
545
+ ```
546
+
547
+ Stores a value under the given key using `Object.assign`.
548
+
549
+ #### keys
550
+
551
+ ```typescript
552
+ keys(): string[]
553
+ ```
554
+
555
+ Returns all keys in the container via `Object.keys()`.
556
+
557
+ #### clear
558
+
559
+ ```typescript
560
+ clear(): void
561
+ ```
562
+
563
+ Replaces the container with a new empty object.
564
+
565
+ #### getContainer
566
+
567
+ ```typescript
568
+ getContainer(): T
569
+ ```
570
+
571
+ Returns the underlying container object.
572
+
573
+ ## Types Reference
574
+
575
+ ### IStorageHelper
576
+
577
+ The unified interface implemented by `MinioHelper` and `DiskHelper`:
578
+
579
+ ```typescript
580
+ interface IStorageHelper {
581
+ isValidName(name: string): boolean;
582
+
583
+ isBucketExists(opts: { name: string }): Promise<boolean>;
584
+ getBuckets(): Promise<IBucketInfo[]>;
585
+ getBucket(opts: { name: string }): Promise<IBucketInfo | null>;
586
+ createBucket(opts: { name: string }): Promise<IBucketInfo | null>;
587
+ removeBucket(opts: { name: string }): Promise<boolean>;
588
+
589
+ upload(opts: {
590
+ bucket: string;
591
+ files: IUploadFile[];
592
+ normalizeNameFn?: (opts: { originalName: string; folderPath?: string }) => string;
593
+ normalizeLinkFn?: (opts: { bucketName: string; normalizeName: string }) => string;
594
+ }): Promise<IUploadResult[]>;
595
+
596
+ getFile(opts: { bucket: string; name: string; options?: any }): Promise<Readable>;
597
+ getStat(opts: { bucket: string; name: string }): Promise<IFileStat>;
598
+ removeObject(opts: { bucket: string; name: string }): Promise<void>;
599
+ removeObjects(opts: { bucket: string; names: string[] }): Promise<void>;
600
+ listObjects(opts: IListObjectsOptions): Promise<IObjectInfo[]>;
601
+
602
+ getFileType(opts: { mimeType: string }): string;
603
+ }
604
+ ```
605
+
606
+ ### IStorageHelperOptions
607
+
608
+ ```typescript
609
+ interface IStorageHelperOptions {
610
+ scope?: string;
611
+ identifier?: string;
612
+ }
613
+ ```
614
+
615
+ ### IUploadFile
616
+
617
+ ```typescript
618
+ interface IUploadFile {
619
+ originalName: string; // Original filename
620
+ mimetype: string; // MIME type (e.g., 'image/png')
621
+ buffer: Buffer; // File content
622
+ size: number; // File size in bytes
623
+ encoding?: string; // Optional encoding (e.g., '7bit', 'base64')
624
+ folderPath?: string; // Optional folder path for organization
625
+ [key: string | symbol]: any; // Additional properties allowed
626
+ }
627
+ ```
628
+
629
+ ### IUploadResult
630
+
631
+ ```typescript
632
+ interface IUploadResult {
633
+ bucketName: string; // Bucket where file was stored
634
+ objectName: string; // Stored filename (normalized)
635
+ link: string; // Access URL
636
+ metaLink?: any; // Optional metadata link
637
+ metaLinkError?: any; // Error if metadata link creation failed
638
+ }
639
+ ```
640
+
641
+ ### IFileStat
642
+
643
+ ```typescript
644
+ interface IFileStat {
645
+ size: number; // File size in bytes
646
+ metadata: Record<string, any>; // Storage-specific metadata
647
+ lastModified?: Date; // Last modification date
648
+ etag?: string; // Entity tag (MinioHelper only)
649
+ versionId?: string; // Version ID (MinioHelper only)
650
+ }
651
+ ```
652
+
653
+ ### IBucketInfo
654
+
655
+ ```typescript
656
+ interface IBucketInfo {
657
+ name: string; // Bucket name
658
+ creationDate: Date; // When the bucket was created
659
+ }
660
+ ```
661
+
662
+ ### IObjectInfo
663
+
664
+ ```typescript
665
+ interface IObjectInfo {
666
+ name?: string; // Object name
667
+ size?: number; // Object size in bytes
668
+ lastModified?: Date; // Last modification date
669
+ etag?: string; // Entity tag
670
+ prefix?: string; // Prefix (for directory-like listing)
671
+ }
672
+ ```
673
+
674
+ ### IListObjectsOptions
675
+
676
+ ```typescript
677
+ interface IListObjectsOptions {
678
+ bucket: string; // Bucket to list
679
+ prefix?: string; // Filter by prefix
680
+ useRecursive?: boolean; // Recursive listing (default: false)
681
+ maxKeys?: number; // Maximum objects to return
682
+ }
683
+ ```
684
+
685
+ ### IDiskHelperOptions
686
+
687
+ ```typescript
688
+ interface IDiskHelperOptions extends IStorageHelperOptions {
689
+ basePath: string; // Base directory for storage
690
+ }
691
+ ```
692
+
693
+ ### IMinioHelperOptions
694
+
695
+ ```typescript
696
+ interface IMinioHelperOptions extends IStorageHelperOptions, ClientOptions {}
697
+ ```
698
+
699
+ Inherits all `minio.ClientOptions` properties: `endPoint`, `port`, `useSSL`, `accessKey`, `secretKey`, `region`, `transport`, `sessionToken`, `partSize`, `pathStyle`, and others.
700
+
701
+ ## See Also
702
+
703
+ - [Setup & Usage](./) -- Getting started, examples, and troubleshooting
704
+ - [Helpers Index](../index) -- All available helpers
705
+ - [Static Asset Component](/references/components/static-asset/) -- Serving stored files via HTTP