balda-js 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/lib/cli.d.ts +6 -0
  2. package/lib/cli.js +929 -0
  3. package/lib/cli.js.map +1 -0
  4. package/lib/index.cjs +3384 -0
  5. package/lib/index.cjs.map +1 -0
  6. package/lib/index.d.cts +1492 -0
  7. package/lib/index.d.ts +1492 -0
  8. package/lib/index.js +3327 -0
  9. package/lib/index.js.map +1 -0
  10. package/package.json +1 -1
  11. package/.husky/pre-commit +0 -19
  12. package/.nvmrc +0 -1
  13. package/docs/README.md +0 -135
  14. package/docs/blog/authors.yml +0 -6
  15. package/docs/blog/tags.yml +0 -4
  16. package/docs/cli.md +0 -109
  17. package/docs/docs/core-concepts/controllers.md +0 -393
  18. package/docs/docs/core-concepts/middleware.md +0 -302
  19. package/docs/docs/core-concepts/request-response.md +0 -486
  20. package/docs/docs/core-concepts/routing.md +0 -388
  21. package/docs/docs/core-concepts/server.md +0 -332
  22. package/docs/docs/cron/overview.md +0 -70
  23. package/docs/docs/examples/rest-api.md +0 -595
  24. package/docs/docs/getting-started/configuration.md +0 -168
  25. package/docs/docs/getting-started/installation.md +0 -125
  26. package/docs/docs/getting-started/quick-start.md +0 -273
  27. package/docs/docs/intro.md +0 -46
  28. package/docs/docs/plugins/cookie.md +0 -424
  29. package/docs/docs/plugins/cors.md +0 -295
  30. package/docs/docs/plugins/file.md +0 -382
  31. package/docs/docs/plugins/helmet.md +0 -388
  32. package/docs/docs/plugins/json.md +0 -338
  33. package/docs/docs/plugins/log.md +0 -592
  34. package/docs/docs/plugins/overview.md +0 -390
  35. package/docs/docs/plugins/rate-limiter.md +0 -347
  36. package/docs/docs/plugins/static.md +0 -352
  37. package/docs/docs/plugins/swagger.md +0 -411
  38. package/docs/docs/plugins/urlencoded.md +0 -76
  39. package/docs/docs/testing/examples.md +0 -384
  40. package/docs/docs/testing/mock-server.md +0 -311
  41. package/docs/docs/testing/overview.md +0 -76
  42. package/docs/docusaurus.config.ts +0 -144
  43. package/docs/intro.md +0 -78
  44. package/docs/package.json +0 -46
  45. package/docs/sidebars.ts +0 -72
  46. package/docs/static/.nojekyll +0 -0
  47. package/docs/static/img/docusaurus-social-card.jpg +0 -0
  48. package/docs/static/img/docusaurus.png +0 -0
  49. package/docs/static/img/favicon.ico +0 -0
  50. package/docs/static/img/logo.svg +0 -1
  51. package/docs/static/img/undraw_docusaurus_mountain.svg +0 -37
  52. package/docs/static/img/undraw_docusaurus_react.svg +0 -170
  53. package/docs/static/img/undraw_docusaurus_tree.svg +0 -40
  54. package/docs/tsconfig.json +0 -8
  55. package/speed_test.sh +0 -3
  56. package/test/benchmark/index.ts +0 -17
  57. package/test/cli/cli.ts +0 -7
  58. package/test/commands/test.ts +0 -42
  59. package/test/controllers/file_upload.ts +0 -29
  60. package/test/controllers/urlencoded.ts +0 -13
  61. package/test/controllers/users.ts +0 -111
  62. package/test/cron/index.ts +0 -6
  63. package/test/cron/test_cron.ts +0 -8
  64. package/test/cron/test_cron_imported.ts +0 -8
  65. package/test/native_env.ts +0 -16
  66. package/test/resources/test.txt +0 -1
  67. package/test/server/index.ts +0 -3
  68. package/test/server/instance.ts +0 -63
  69. package/test/suite/upload.test.ts +0 -23
  70. package/test/suite/urlencoded.test.ts +0 -23
  71. package/test/suite/users.test.ts +0 -76
  72. package/todo.md +0 -9
  73. package/tsconfig.json +0 -24
  74. package/vitest.config.ts +0 -17
@@ -1,382 +0,0 @@
1
- ---
2
- sidebar_position: 10
3
- ---
4
-
5
- # File Plugin
6
-
7
- The File plugin handles multipart/form-data file uploads in your Balda.js application. It automatically parses uploaded files, validates them against size limits, and provides convenient access to file data through `req.files` and `req.file`.
8
-
9
- ## Features
10
-
11
- - **Multipart Form Data**: Handles file uploads from HTML forms
12
- - **Size Validation**: Configurable file size limits
13
- - **Automatic Cleanup**: Temporary files are cleaned up automatically
14
- - **Multiple Files**: Support for single and multiple file uploads
15
- - **File Metadata**: Access to file name, size, MIME type, and temporary path
16
- - **Error Handling**: Graceful handling of file upload errors
17
-
18
- ## Basic Configuration
19
-
20
- ### Simple Setup
21
-
22
- ```typescript
23
- import { Server } from 'balda-js';
24
-
25
- const server = new Server({
26
- port: 3000,
27
- plugins: {
28
- file: {
29
- maxFileSize: 5 * 1024 * 1024 // 5MB
30
- }
31
- }
32
- });
33
- ```
34
-
35
- ### Advanced Configuration
36
-
37
- ```typescript
38
- const server = new Server({
39
- port: 3000,
40
- plugins: {
41
- file: {
42
- maxFileSize: 10 * 1024 * 1024, // 10MB
43
- allowedMimeTypes: ['image/jpeg', 'image/png', 'application/pdf']
44
- }
45
- }
46
- });
47
- ```
48
-
49
- ## Configuration Options
50
-
51
- ### Basic Options
52
-
53
- ```typescript
54
- file: {
55
- maxFileSize: 5 * 1024 * 1024, // Maximum file size in bytes (default: 5MB)
56
- }
57
- ```
58
-
59
- ### Advanced Options
60
-
61
- ```typescript
62
- file: {
63
- maxFileSize: 10 * 1024 * 1024, // 10MB
64
- allowedMimeTypes: ['image/jpeg', 'image/png', 'application/pdf'],
65
- maxFiles: 5, // Maximum number of files per request
66
- preserveExtension: true // Preserve original file extensions
67
- }
68
- ```
69
-
70
- ## Usage Examples
71
-
72
- ### Basic File Upload
73
-
74
- ```typescript
75
- @controller('/upload')
76
- export class UploadController {
77
- @post('/single')
78
- async uploadSingleFile(req: Request, res: Response) {
79
- if (!req.files || req.files.length === 0) {
80
- return res.badRequest({ error: 'No file uploaded' });
81
- }
82
-
83
- const file = req.files[0];
84
-
85
- // Access file properties
86
- console.log('File name:', file.originalName);
87
- console.log('File size:', file.size);
88
- console.log('MIME type:', file.mimeType);
89
- console.log('Temporary path:', file.tmpPath);
90
-
91
- // Process the file (e.g., move to permanent location)
92
- const permanentPath = await moveFileToPermanentLocation(file.tmpPath, file.originalName);
93
-
94
- res.json({
95
- message: 'File uploaded successfully',
96
- file: {
97
- name: file.originalName,
98
- size: file.size,
99
- path: permanentPath
100
- }
101
- });
102
- }
103
- }
104
- ```
105
-
106
- ### Multiple File Upload
107
-
108
- ```typescript
109
- @controller('/upload')
110
- export class UploadController {
111
- @post('/multiple')
112
- async uploadMultipleFiles(req: Request, res: Response) {
113
- if (!req.files || req.files.length === 0) {
114
- return res.badRequest({ error: 'No files uploaded' });
115
- }
116
-
117
- const uploadedFiles = [];
118
-
119
- for (const file of req.files) {
120
- // Process each file
121
- const permanentPath = await moveFileToPermanentLocation(file.tmpPath, file.originalName);
122
-
123
- uploadedFiles.push({
124
- name: file.originalName,
125
- size: file.size,
126
- mimeType: file.mimeType,
127
- path: permanentPath
128
- });
129
- }
130
-
131
- res.json({
132
- message: `${uploadedFiles.length} files uploaded successfully`,
133
- files: uploadedFiles
134
- });
135
- }
136
- }
137
- ```
138
-
139
- ### File Upload with Form Data
140
-
141
- ```typescript
142
- @controller('/upload')
143
- export class UploadController {
144
- @post('/with-data')
145
- async uploadWithData(req: Request, res: Response) {
146
- // Access uploaded files
147
- const files = req.files || [];
148
-
149
- // Access form data
150
- const title = req.body.title;
151
- const description = req.body.description;
152
- const category = req.body.category;
153
-
154
- if (files.length === 0) {
155
- return res.badRequest({ error: 'No file uploaded' });
156
- }
157
-
158
- const file = files[0];
159
-
160
- // Save file and metadata to database
161
- const savedFile = await saveFileToDatabase({
162
- title,
163
- description,
164
- category,
165
- fileName: file.originalName,
166
- fileSize: file.size,
167
- mimeType: file.mimeType,
168
- filePath: await moveFileToPermanentLocation(file.tmpPath, file.originalName)
169
- });
170
-
171
- res.json({
172
- message: 'File uploaded with metadata',
173
- file: savedFile
174
- });
175
- }
176
- }
177
- ```
178
-
179
- ### Image Upload with Validation
180
-
181
- ```typescript
182
- @controller('/upload')
183
- export class ImageController {
184
- @post('/image')
185
- async uploadImage(req: Request, res: Response) {
186
- if (!req.files || req.files.length === 0) {
187
- return res.badRequest({ error: 'No image uploaded' });
188
- }
189
-
190
- const file = req.files[0];
191
-
192
- // Validate image type
193
- const allowedTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
194
- if (!allowedTypes.includes(file.mimeType)) {
195
- return res.badRequest({
196
- error: 'Invalid file type. Only JPEG, PNG, GIF, and WebP are allowed.'
197
- });
198
- }
199
-
200
- // Validate file size (max 2MB for images)
201
- const maxSize = 2 * 1024 * 1024; // 2MB
202
- if (file.size > maxSize) {
203
- return res.badRequest({
204
- error: 'File too large. Maximum size is 2MB.'
205
- });
206
- }
207
-
208
- // Process image (e.g., resize, compress)
209
- const processedPath = await processImage(file.tmpPath);
210
-
211
- res.json({
212
- message: 'Image uploaded successfully',
213
- image: {
214
- name: file.originalName,
215
- size: file.size,
216
- type: file.mimeType,
217
- path: processedPath
218
- }
219
- });
220
- }
221
- }
222
- ```
223
-
224
- ## File Object Properties
225
-
226
- ### File Structure
227
-
228
- ```typescript
229
- interface FormFile {
230
- formName: string; // The name of the form field
231
- mimeType: string; // MIME type (e.g., "image/png")
232
- size: number; // File size in bytes
233
- tmpPath: string; // Temporary file path
234
- originalName: string; // Original filename with extension
235
- }
236
- ```
237
-
238
- ### Accessing File Properties
239
-
240
- ```typescript
241
- @post('/file-info')
242
- async getFileInfo(req: Request, res: Response) {
243
- if (!req.files || req.files.length === 0) {
244
- return res.badRequest({ error: 'No file uploaded' });
245
- }
246
-
247
- const file = req.files[0];
248
-
249
- res.json({
250
- formField: file.formName,
251
- originalName: file.originalName,
252
- mimeType: file.mimeType,
253
- size: file.size,
254
- sizeInMB: (file.size / (1024 * 1024)).toFixed(2),
255
- temporaryPath: file.tmpPath
256
- });
257
- }
258
- ```
259
-
260
- ## Error Handling
261
-
262
- ### File Too Large
263
-
264
- ```typescript
265
- // When a file exceeds maxFileSize
266
- // Response: 400 Bad Request
267
- {
268
- "error": "File too large",
269
- "message": "File 'large-file.zip' (15MB) exceeds the maximum allowed size of 5MB"
270
- }
271
- ```
272
-
273
- ### No Files Uploaded
274
-
275
- ```typescript
276
- @post('/upload')
277
- async uploadFile(req: Request, res: Response) {
278
- if (!req.files || req.files.length === 0) {
279
- return res.badRequest({
280
- error: 'No file uploaded',
281
- message: 'Please select a file to upload'
282
- });
283
- }
284
-
285
- // Process file...
286
- }
287
- ```
288
-
289
- ### Invalid File Type
290
-
291
- ```typescript
292
- @post('/upload')
293
- async uploadFile(req: Request, res: Response) {
294
- if (!req.files || req.files.length === 0) {
295
- return res.badRequest({ error: 'No file uploaded' });
296
- }
297
-
298
- const file = req.files[0];
299
- const allowedTypes = ['image/jpeg', 'image/png', 'application/pdf'];
300
-
301
- if (!allowedTypes.includes(file.mimeType)) {
302
- return res.badRequest({
303
- error: 'Invalid file type',
304
- message: `File type '${file.mimeType}' is not allowed. Allowed types: ${allowedTypes.join(', ')}`
305
- });
306
- }
307
-
308
- // Process file...
309
- }
310
- ```
311
-
312
- ## File Processing Examples
313
-
314
- ### Moving Files to Permanent Location
315
-
316
- ```typescript
317
- @post('/upload')
318
- async uploadFile(req: Request, res: Response) {
319
- if (!req.files || req.files.length === 0) {
320
- return res.badRequest({ error: 'No file uploaded' });
321
- }
322
-
323
- const file = req.files[0];
324
- const permanentPath = await moveFileToPermanentLocation(file.tmpPath, file.originalName);
325
-
326
- res.json({
327
- message: 'File uploaded successfully',
328
- path: permanentPath
329
- });
330
- }
331
-
332
- @post('/image')
333
- async uploadImage(req: Request, res: Response) {
334
- if (!req.files || req.files.length === 0) {
335
- return res.badRequest({ error: 'No image uploaded' });
336
- }
337
-
338
- const file = req.files[0];
339
- const processedPath = await processImage(file.tmpPath);
340
-
341
- res.json({
342
- message: 'Image processed and uploaded',
343
- path: processedPath
344
- });
345
- }
346
- ```
347
-
348
- ## HTML Form Examples
349
-
350
- ### Single File Upload
351
-
352
- ```html
353
- <form action="/upload/single" method="post" enctype="multipart/form-data">
354
- <input type="file" name="file" required>
355
- <button type="submit">Upload File</button>
356
- </form>
357
- ```
358
-
359
- ### Multiple File Upload
360
-
361
- ```html
362
- <form action="/upload/multiple" method="post" enctype="multipart/form-data">
363
- <input type="file" name="files" multiple required>
364
- <button type="submit">Upload Files</button>
365
- </form>
366
- ```
367
-
368
- ### File Upload with Form Data
369
-
370
- ```html
371
- <form action="/upload/with-data" method="post" enctype="multipart/form-data">
372
- <input type="text" name="title" placeholder="File title" required>
373
- <textarea name="description" placeholder="File description"></textarea>
374
- <select name="category">
375
- <option value="document">Document</option>
376
- <option value="image">Image</option>
377
- <option value="video">Video</option>
378
- </select>
379
- <input type="file" name="file" required>
380
- <button type="submit">Upload</button>
381
- </form>
382
- ```