balda-js 0.0.1 → 0.0.3

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 (65) hide show
  1. package/package.json +1 -6
  2. package/.husky/pre-commit +0 -19
  3. package/.nvmrc +0 -1
  4. package/docs/README.md +0 -135
  5. package/docs/blog/authors.yml +0 -6
  6. package/docs/blog/tags.yml +0 -4
  7. package/docs/cli.md +0 -109
  8. package/docs/docs/core-concepts/controllers.md +0 -393
  9. package/docs/docs/core-concepts/middleware.md +0 -302
  10. package/docs/docs/core-concepts/request-response.md +0 -486
  11. package/docs/docs/core-concepts/routing.md +0 -388
  12. package/docs/docs/core-concepts/server.md +0 -332
  13. package/docs/docs/cron/overview.md +0 -70
  14. package/docs/docs/examples/rest-api.md +0 -595
  15. package/docs/docs/getting-started/configuration.md +0 -168
  16. package/docs/docs/getting-started/installation.md +0 -125
  17. package/docs/docs/getting-started/quick-start.md +0 -273
  18. package/docs/docs/intro.md +0 -46
  19. package/docs/docs/plugins/cookie.md +0 -424
  20. package/docs/docs/plugins/cors.md +0 -295
  21. package/docs/docs/plugins/file.md +0 -382
  22. package/docs/docs/plugins/helmet.md +0 -388
  23. package/docs/docs/plugins/json.md +0 -338
  24. package/docs/docs/plugins/log.md +0 -592
  25. package/docs/docs/plugins/overview.md +0 -390
  26. package/docs/docs/plugins/rate-limiter.md +0 -347
  27. package/docs/docs/plugins/static.md +0 -352
  28. package/docs/docs/plugins/swagger.md +0 -411
  29. package/docs/docs/plugins/urlencoded.md +0 -76
  30. package/docs/docs/testing/examples.md +0 -384
  31. package/docs/docs/testing/mock-server.md +0 -311
  32. package/docs/docs/testing/overview.md +0 -76
  33. package/docs/docusaurus.config.ts +0 -144
  34. package/docs/intro.md +0 -78
  35. package/docs/package.json +0 -46
  36. package/docs/sidebars.ts +0 -72
  37. package/docs/static/.nojekyll +0 -0
  38. package/docs/static/img/docusaurus-social-card.jpg +0 -0
  39. package/docs/static/img/docusaurus.png +0 -0
  40. package/docs/static/img/favicon.ico +0 -0
  41. package/docs/static/img/logo.svg +0 -1
  42. package/docs/static/img/undraw_docusaurus_mountain.svg +0 -37
  43. package/docs/static/img/undraw_docusaurus_react.svg +0 -170
  44. package/docs/static/img/undraw_docusaurus_tree.svg +0 -40
  45. package/docs/tsconfig.json +0 -8
  46. package/speed_test.sh +0 -3
  47. package/test/benchmark/index.ts +0 -17
  48. package/test/cli/cli.ts +0 -7
  49. package/test/commands/test.ts +0 -42
  50. package/test/controllers/file_upload.ts +0 -29
  51. package/test/controllers/urlencoded.ts +0 -13
  52. package/test/controllers/users.ts +0 -111
  53. package/test/cron/index.ts +0 -6
  54. package/test/cron/test_cron.ts +0 -8
  55. package/test/cron/test_cron_imported.ts +0 -8
  56. package/test/native_env.ts +0 -16
  57. package/test/resources/test.txt +0 -1
  58. package/test/server/index.ts +0 -3
  59. package/test/server/instance.ts +0 -63
  60. package/test/suite/upload.test.ts +0 -23
  61. package/test/suite/urlencoded.test.ts +0 -23
  62. package/test/suite/users.test.ts +0 -76
  63. package/todo.md +0 -9
  64. package/tsconfig.json +0 -24
  65. package/vitest.config.ts +0 -17
@@ -1,424 +0,0 @@
1
- ---
2
- sidebar_position: 5
3
- ---
4
-
5
- # Cookie Plugin
6
-
7
- The Cookie plugin provides comprehensive cookie parsing and management for your Balda.js application. It automatically parses incoming cookies and provides convenient methods for setting and clearing cookies on responses.
8
-
9
- ## Features
10
-
11
- - **Automatic Cookie Parsing**: Parses cookies from incoming requests
12
- - **Cookie Setting**: Easy methods to set cookies on responses
13
- - **Cookie Signing**: Optional cookie signing for security
14
- - **Flexible Configuration**: Customizable defaults and options
15
- - **Security Features**: HttpOnly, Secure, SameSite support
16
-
17
- ## Basic Configuration
18
-
19
- ### Simple Setup
20
-
21
- ```typescript
22
- import { Server } from 'balda-js';
23
-
24
- const server = new Server({
25
- port: 3000,
26
- plugins: {
27
- cookie: {
28
- secret: 'your-secret-key'
29
- }
30
- }
31
- });
32
- ```
33
-
34
- ### Development Configuration
35
-
36
- ```typescript
37
- const server = new Server({
38
- port: 3000,
39
- plugins: {
40
- cookie: {
41
- secret: 'dev-secret-key',
42
- defaults: {
43
- httpOnly: true,
44
- secure: false,
45
- sameSite: 'Lax'
46
- }
47
- }
48
- }
49
- });
50
- ```
51
-
52
- ## Configuration Options
53
-
54
- ### Basic Options
55
-
56
- ```typescript
57
- cookie: {
58
- secret: 'your-secret-key', // Required for signed cookies
59
- parse: true, // Enable cookie parsing (default: true)
60
- sign: false, // Enable cookie signing (default: false)
61
- defaults: {
62
- path: '/', // Cookie path (default: '/')
63
- httpOnly: true, // HttpOnly flag (default: true)
64
- secure: false, // Secure flag (default: false)
65
- sameSite: 'Lax' // SameSite attribute (default: 'Lax')
66
- }
67
- }
68
- ```
69
-
70
- ### Production Configuration
71
-
72
- ```typescript
73
- const server = new Server({
74
- port: 3000,
75
- plugins: {
76
- cookie: {
77
- secret: process.env.COOKIE_SECRET,
78
- sign: true,
79
- defaults: {
80
- httpOnly: true,
81
- secure: true, // HTTPS only
82
- sameSite: 'Strict',
83
- domain: '.myapp.com'
84
- }
85
- }
86
- }
87
- });
88
- ```
89
-
90
- ## Usage Examples
91
-
92
- ### Basic Cookie Operations
93
-
94
- ```typescript
95
- @controller('/auth')
96
- export class AuthController {
97
- @post('/login')
98
- async login(req: Request, res: Response) {
99
- const { username, password } = req.body;
100
-
101
- // Validate credentials
102
- const user = await validateUser(username, password);
103
-
104
- if (user) {
105
- // Set session cookie
106
- res.cookie('sessionId', user.sessionId, {
107
- maxAge: 24 * 60 * 60 * 1000, // 24 hours
108
- httpOnly: true,
109
- secure: true
110
- });
111
-
112
- res.json({ message: 'Login successful' });
113
- } else {
114
- res.unauthorized({ error: 'Invalid credentials' });
115
- }
116
- }
117
-
118
- @post('/logout')
119
- async logout(req: Request, res: Response) {
120
- // Clear session cookie
121
- res.clearCookie('sessionId');
122
- res.json({ message: 'Logout successful' });
123
- }
124
- }
125
- ```
126
-
127
- ### Reading Cookies
128
-
129
- ```typescript
130
- @controller('/api')
131
- export class ApiController {
132
- @get('/profile')
133
- async getProfile(req: Request, res: Response) {
134
- // Access parsed cookies
135
- const sessionId = req.cookies.sessionId;
136
- const theme = req.cookies.theme || 'light';
137
- const language = req.cookies.language || 'en';
138
-
139
- if (!sessionId) {
140
- return res.unauthorized({ error: 'No session found' });
141
- }
142
-
143
- const user = await getUserBySession(sessionId);
144
- res.json({ user, theme, language });
145
- }
146
- }
147
- ```
148
-
149
- ### Setting Multiple Cookies
150
-
151
- ```typescript
152
- @post('/preferences')
153
- async updatePreferences(req: Request, res: Response) {
154
- const { theme, language } = req.body;
155
-
156
- // Set multiple cookies
157
- res.cookie('theme', theme, {
158
- maxAge: 365 * 24 * 60 * 60 * 1000, // 1 year
159
- httpOnly: false // Allow JavaScript access
160
- });
161
-
162
- res.cookie('language', language, {
163
- maxAge: 365 * 24 * 60 * 60 * 1000,
164
- httpOnly: false
165
- });
166
-
167
- res.json({ message: 'Preferences updated' });
168
- }
169
- ```
170
-
171
- ### Signed Cookies
172
-
173
- ```typescript
174
- const server = new Server({
175
- port: 3000,
176
- plugins: {
177
- cookie: {
178
- secret: 'your-secret-key',
179
- sign: true,
180
- defaults: {
181
- httpOnly: true,
182
- secure: true
183
- }
184
- }
185
- }
186
- });
187
-
188
- @controller('/secure')
189
- export class SecureController {
190
- @post('/set-secure-cookie')
191
- async setSecureCookie(req: Request, res: Response) {
192
- // Set signed cookie
193
- res.cookie('secureData', 'sensitive-information', {
194
- signed: true,
195
- maxAge: 60 * 60 * 1000 // 1 hour
196
- });
197
-
198
- res.json({ message: 'Secure cookie set' });
199
- }
200
-
201
- @get('/read-secure-cookie')
202
- async readSecureCookie(req: Request, res: Response) {
203
- // Read signed cookie
204
- const secureData = req.cookies.secureData;
205
-
206
- if (secureData) {
207
- res.json({ data: secureData });
208
- } else {
209
- res.json({ error: 'No secure data found' });
210
- }
211
- }
212
- }
213
- ```
214
-
215
- ## Cookie Options
216
-
217
- ### Domain Configuration
218
-
219
- ```typescript
220
- // Set cookie for specific domain
221
- res.cookie('sessionId', 'value', {
222
- domain: '.myapp.com' // Available on all subdomains
223
- });
224
-
225
- // Set cookie for current domain only
226
- res.cookie('sessionId', 'value', {
227
- domain: 'api.myapp.com' // Only on this subdomain
228
- });
229
- ```
230
-
231
- ### Path Configuration
232
-
233
- ```typescript
234
- // Set cookie for specific path
235
- res.cookie('adminToken', 'value', {
236
- path: '/admin' // Only available on /admin routes
237
- });
238
-
239
- // Set cookie for entire site
240
- res.cookie('sessionId', 'value', {
241
- path: '/' // Available everywhere
242
- });
243
- ```
244
-
245
- ### Expiration Options
246
-
247
- ```typescript
248
- // Expire at specific date
249
- res.cookie('sessionId', 'value', {
250
- expires: new Date('2024-12-31')
251
- });
252
-
253
- // Expire after specific time
254
- res.cookie('sessionId', 'value', {
255
- maxAge: 24 * 60 * 60 * 1000 // 24 hours
256
- });
257
-
258
- // Session cookie (expires when browser closes)
259
- res.cookie('sessionId', 'value', {
260
- // No expires or maxAge
261
- });
262
- ```
263
-
264
- ### Security Options
265
-
266
- ```typescript
267
- // Secure cookie (HTTPS only)
268
- res.cookie('sessionId', 'value', {
269
- secure: true,
270
- httpOnly: true,
271
- sameSite: 'Strict'
272
- });
273
-
274
- // Cross-site cookie
275
- res.cookie('trackingId', 'value', {
276
- secure: true,
277
- sameSite: 'None' // Requires secure: true
278
- });
279
- ```
280
-
281
- ## SameSite Configuration
282
-
283
- ### SameSite Options
284
-
285
- ```typescript
286
- // Strict - only same site
287
- res.cookie('sessionId', 'value', {
288
- sameSite: 'Strict'
289
- });
290
-
291
- // Lax - same site + top-level navigation
292
- res.cookie('sessionId', 'value', {
293
- sameSite: 'Lax'
294
- });
295
-
296
- // None - cross-site (requires secure: true)
297
- res.cookie('trackingId', 'value', {
298
- sameSite: 'None',
299
- secure: true
300
- });
301
- ```
302
-
303
- ## Environment-Based Configuration
304
-
305
- ### Development vs Production
306
-
307
- ```typescript
308
- const isProduction = process.env.NODE_ENV === 'production';
309
-
310
- const server = new Server({
311
- port: 3000,
312
- plugins: {
313
- cookie: {
314
- secret: process.env.COOKIE_SECRET,
315
- sign: isProduction,
316
- defaults: {
317
- httpOnly: true,
318
- secure: isProduction, // HTTPS only in production
319
- sameSite: isProduction ? 'Strict' : 'Lax',
320
- domain: isProduction ? '.myapp.com' : undefined
321
- }
322
- }
323
- }
324
- });
325
- ```
326
-
327
- ## Error Handling
328
-
329
- ### Invalid Signed Cookies
330
-
331
- ```typescript
332
- @get('/verify-cookie')
333
- async verifyCookie(req: Request, res: Response) {
334
- const signedCookie = req.cookies.secureData;
335
-
336
- if (!signedCookie) {
337
- return res.unauthorized({ error: 'No signed cookie found' });
338
- }
339
-
340
- // The cookie plugin automatically verifies signed cookies
341
- // If verification fails, the cookie won't be available
342
- res.json({ verified: true, data: signedCookie });
343
- }
344
- ```
345
-
346
- ## Integration Examples
347
-
348
- ### With Authentication
349
-
350
- ```typescript
351
- @controller('/auth')
352
- export class AuthController {
353
- @post('/login')
354
- async login(req: Request, res: Response) {
355
- const { username, password } = req.body;
356
-
357
- const user = await authenticateUser(username, password);
358
-
359
- if (user) {
360
- // Set authentication cookies
361
- res.cookie('authToken', user.token, {
362
- httpOnly: true,
363
- secure: true,
364
- sameSite: 'Strict',
365
- maxAge: 24 * 60 * 60 * 1000
366
- });
367
-
368
- res.cookie('userId', user.id.toString(), {
369
- httpOnly: true,
370
- secure: true,
371
- sameSite: 'Strict',
372
- maxAge: 24 * 60 * 60 * 1000
373
- });
374
-
375
- res.json({ message: 'Login successful' });
376
- } else {
377
- res.unauthorized({ error: 'Invalid credentials' });
378
- }
379
- }
380
-
381
- @post('/logout')
382
- async logout(req: Request, res: Response) {
383
- // Clear all authentication cookies
384
- res.clearCookie('authToken');
385
- res.clearCookie('userId');
386
-
387
- res.json({ message: 'Logout successful' });
388
- }
389
- }
390
- ```
391
-
392
- ### With Session Management
393
-
394
- ```typescript
395
- @controller('/session')
396
- export class SessionController {
397
- @post('/create')
398
- async createSession(req: Request, res: Response) {
399
- const sessionId = generateSessionId();
400
-
401
- res.cookie('sessionId', sessionId, {
402
- httpOnly: true,
403
- secure: true,
404
- sameSite: 'Strict',
405
- maxAge: 30 * 24 * 60 * 60 * 1000 // 30 days
406
- });
407
-
408
- await createSession(sessionId, req.body);
409
- res.json({ sessionId });
410
- }
411
-
412
- @get('/data')
413
- async getSessionData(req: Request, res: Response) {
414
- const sessionId = req.cookies.sessionId;
415
-
416
- if (!sessionId) {
417
- return res.unauthorized({ error: 'No session found' });
418
- }
419
-
420
- const sessionData = await getSession(sessionId);
421
- res.json(sessionData);
422
- }
423
- }
424
- ```
@@ -1,295 +0,0 @@
1
- ---
2
- sidebar_position: 2
3
- ---
4
-
5
- # CORS Plugin
6
-
7
- The CORS (Cross-Origin Resource Sharing) plugin enables cross-origin requests in your Balda.js application. It handles preflight requests and sets appropriate CORS headers for both simple and complex requests.
8
-
9
- ## Features
10
-
11
- - **Automatic Preflight Handling**: Automatically handles OPTIONS requests
12
- - **Flexible Origin Configuration**: Support for strings, arrays, and regex patterns
13
- - **Customizable Headers**: Configurable allowed and exposed headers
14
- - **Credentials Support**: Enable/disable credentials for cross-origin requests
15
- - **Method Control**: Specify allowed HTTP methods
16
-
17
- ## Basic Configuration
18
-
19
- ### Simple Setup
20
-
21
- ```typescript
22
- import { Server } from 'balda-js';
23
-
24
- const server = new Server({
25
- port: 3000,
26
- plugins: {
27
- cors: {
28
- origin: '*'
29
- }
30
- }
31
- });
32
- ```
33
-
34
- ### Development Configuration
35
-
36
- ```typescript
37
- const server = new Server({
38
- port: 3000,
39
- plugins: {
40
- cors: {
41
- origin: ['http://localhost:3000', 'http://localhost:3001'],
42
- credentials: true,
43
- methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'],
44
- allowedHeaders: ['Content-Type', 'Authorization']
45
- }
46
- }
47
- });
48
- ```
49
-
50
- ## Configuration Options
51
-
52
- ### Origin Configuration
53
-
54
- ```typescript
55
- // Allow all origins (not recommended for production)
56
- cors: {
57
- origin: '*'
58
- }
59
-
60
- // Allow specific origins
61
- cors: {
62
- origin: ['https://myapp.com', 'https://admin.myapp.com']
63
- }
64
-
65
- // Allow origins with regex patterns
66
- cors: {
67
- origin: [
68
- 'https://myapp.com',
69
- /^https:\/\/.*\.myapp\.com$/
70
- ]
71
- }
72
-
73
- // Function-based origin validation
74
- cors: {
75
- origin: (origin) => {
76
- const allowedOrigins = ['https://myapp.com', 'https://admin.myapp.com'];
77
- return allowedOrigins.includes(origin);
78
- }
79
- }
80
- ```
81
-
82
- ### Methods Configuration
83
-
84
- ```typescript
85
- // Default methods (GET, HEAD, PUT, PATCH, POST, DELETE)
86
- cors: {
87
- methods: ['GET', 'HEAD', 'PUT', 'PATCH', 'POST', 'DELETE']
88
- }
89
-
90
- // Custom methods
91
- cors: {
92
- methods: ['GET', 'POST', 'PUT', 'DELETE']
93
- }
94
-
95
- // String format
96
- cors: {
97
- methods: 'GET,POST,PUT,DELETE'
98
- }
99
- ```
100
-
101
- ### Headers Configuration
102
-
103
- ```typescript
104
- // Allow specific headers
105
- cors: {
106
- allowedHeaders: ['Content-Type', 'Authorization', 'X-API-Key']
107
- }
108
-
109
- // Allow all headers
110
- cors: {
111
- allowedHeaders: '*'
112
- }
113
-
114
- // Expose headers to the client
115
- cors: {
116
- exposedHeaders: ['X-Total-Count', 'X-Page-Count']
117
- }
118
- ```
119
-
120
- ### Advanced Configuration
121
-
122
- ```typescript
123
- const server = new Server({
124
- port: 3000,
125
- plugins: {
126
- cors: {
127
- origin: ['https://myapp.com', 'https://admin.myapp.com'],
128
- methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'],
129
- allowedHeaders: ['Content-Type', 'Authorization', 'X-API-Key'],
130
- exposedHeaders: ['X-Total-Count', 'X-Page-Count'],
131
- credentials: true,
132
- maxAge: 86400, // 24 hours
133
- preflightContinue: false,
134
- optionsSuccessStatus: 204
135
- }
136
- }
137
- });
138
- ```
139
-
140
- ## Environment-Based Configuration
141
-
142
- ```typescript
143
- const isProduction = process.env.NODE_ENV === 'production';
144
-
145
- const server = new Server({
146
- port: 3000,
147
- plugins: {
148
- cors: {
149
- origin: isProduction
150
- ? ['https://myapp.com']
151
- : ['http://localhost:3000', 'http://localhost:3001'],
152
- credentials: isProduction,
153
- maxAge: isProduction ? 86400 : undefined
154
- }
155
- }
156
- });
157
- ```
158
-
159
- ## Route-Level CORS
160
-
161
- You can also apply CORS middleware to specific routes:
162
-
163
- ```typescript
164
- import { cors } from 'balda-js';
165
-
166
- @controller('/api')
167
- export class ApiController {
168
- @get('/public', {
169
- middleware: [cors({ origin: '*' })]
170
- })
171
- async publicEndpoint(req: Request, res: Response) {
172
- res.json({ message: 'Public endpoint' });
173
- }
174
-
175
- @get('/private', {
176
- middleware: [cors({
177
- origin: ['https://myapp.com'],
178
- credentials: true
179
- })]
180
- })
181
- async privateEndpoint(req: Request, res: Response) {
182
- res.json({ message: 'Private endpoint' });
183
- }
184
- }
185
- ```
186
-
187
- ## CORS Headers Explained
188
-
189
- ### Request Headers
190
-
191
- - **Origin**: The origin of the request (set by browser)
192
- - **Access-Control-Request-Method**: The HTTP method for the actual request
193
- - **Access-Control-Request-Headers**: The headers for the actual request
194
-
195
- ### Response Headers
196
-
197
- - **Access-Control-Allow-Origin**: Which origins are allowed
198
- - **Access-Control-Allow-Methods**: Which HTTP methods are allowed
199
- - **Access-Control-Allow-Headers**: Which headers are allowed
200
- - **Access-Control-Expose-Headers**: Which headers are exposed to the client
201
- - **Access-Control-Allow-Credentials**: Whether credentials are allowed
202
- - **Access-Control-Max-Age**: How long preflight results can be cached
203
-
204
- ## Preflight Requests
205
-
206
- CORS automatically handles preflight OPTIONS requests:
207
-
208
- ```typescript
209
- // This OPTIONS request is handled automatically
210
- // OPTIONS /api/users
211
- // Origin: https://myapp.com
212
- // Access-Control-Request-Method: POST
213
- // Access-Control-Request-Headers: Content-Type, Authorization
214
-
215
- // Response:
216
- // Access-Control-Allow-Origin: https://myapp.com
217
- // Access-Control-Allow-Methods: GET, POST, PUT, DELETE, PATCH
218
- // Access-Control-Allow-Headers: Content-Type, Authorization
219
- // Access-Control-Max-Age: 86400
220
- ```
221
-
222
- ## Security Considerations
223
-
224
- ### Production Configuration
225
-
226
- ```typescript
227
- // Secure production configuration
228
- cors: {
229
- origin: ['https://myapp.com'], // Specific origins only
230
- credentials: true,
231
- methods: ['GET', 'POST', 'PUT', 'DELETE'],
232
- allowedHeaders: ['Content-Type', 'Authorization'],
233
- maxAge: 86400
234
- }
235
- ```
236
-
237
- ### Development vs Production
238
-
239
- ```typescript
240
- const corsConfig = process.env.NODE_ENV === 'production'
241
- ? {
242
- origin: ['https://myapp.com'],
243
- credentials: true,
244
- maxAge: 86400
245
- }
246
- : {
247
- origin: ['http://localhost:3000'],
248
- credentials: false
249
- };
250
-
251
- const server = new Server({
252
- port: 3000,
253
- plugins: {
254
- cors: corsConfig
255
- }
256
- });
257
- ```
258
-
259
- ## Common Issues and Solutions
260
-
261
- ### Credentials with Wildcard Origin
262
-
263
- ```typescript
264
- // ❌ This won't work - credentials require specific origins
265
- cors: {
266
- origin: '*',
267
- credentials: true
268
- }
269
-
270
- // ✅ This works - specific origins with credentials
271
- cors: {
272
- origin: ['https://myapp.com'],
273
- credentials: true
274
- }
275
- ```
276
-
277
- ### Multiple Origins with Credentials
278
-
279
- ```typescript
280
- // ✅ Multiple specific origins with credentials
281
- cors: {
282
- origin: ['https://myapp.com', 'https://admin.myapp.com'],
283
- credentials: true
284
- }
285
- ```
286
-
287
- ### Custom Headers
288
-
289
- ```typescript
290
- // ✅ Include custom headers
291
- cors: {
292
- allowedHeaders: ['Content-Type', 'Authorization', 'X-Custom-Header'],
293
- exposedHeaders: ['X-Total-Count', 'X-Page-Count']
294
- }
295
- ```