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,388 +0,0 @@
1
- ---
2
- sidebar_position: 3
3
- ---
4
-
5
- # Routing
6
-
7
- Balda.js provides a flexible and intuitive routing system that supports both direct route registration and controller-based routing with decorators.
8
-
9
- ## Route Registration
10
-
11
- ### Direct Route Registration
12
-
13
- You can register routes directly on the server instance:
14
-
15
- ```typescript
16
- import { Server } from 'balda-js';
17
-
18
- const server = new Server({ port: 3000 });
19
-
20
- // GET route
21
- server.get('/users', (req, res) => {
22
- res.json({ users: [] });
23
- });
24
-
25
- // POST route
26
- server.post('/users', (req, res) => {
27
- res.created(req.body);
28
- });
29
-
30
- // PUT route
31
- server.put('/users/:id', (req, res) => {
32
- res.json({ id: req.params.id, ...req.body });
33
- });
34
-
35
- // PATCH route
36
- server.patch('/users/:id', (req, res) => {
37
- res.json({ id: req.params.id, ...req.body });
38
- });
39
-
40
- // DELETE route
41
- server.delete('/users/:id', (req, res) => {
42
- res.noContent();
43
- });
44
- ```
45
-
46
- ### Controller-Based Routing
47
-
48
- Controllers provide a more organized way to define routes:
49
-
50
- ```typescript
51
- import { controller, get, post, put, del } from 'balda-js';
52
-
53
- @controller('/users')
54
- export class UsersController {
55
- @get('/')
56
- async getAllUsers(req, res) {
57
- res.json({ users: [] });
58
- }
59
-
60
- @get('/:id')
61
- async getUserById(req, res) {
62
- res.json({ id: req.params.id });
63
- }
64
-
65
- @post('/')
66
- async createUser(req, res) {
67
- res.created(req.body);
68
- }
69
-
70
- @put('/:id')
71
- async updateUser(req, res) {
72
- res.json({ id: req.params.id, ...req.body });
73
- }
74
-
75
- @del('/:id')
76
- async deleteUser(req, res) {
77
- res.noContent();
78
- }
79
- }
80
- ```
81
-
82
- ## Route Parameters
83
-
84
- ### Path Parameters
85
-
86
- Define dynamic segments in your routes:
87
-
88
- ```typescript
89
- @controller('/users')
90
- export class UsersController {
91
- @get('/:id')
92
- async getUserById(req, res) {
93
- const id = req.params.id;
94
- res.json({ id });
95
- }
96
-
97
- @get('/:userId/posts/:postId')
98
- async getUserPost(req, res) {
99
- const { userId, postId } = req.params;
100
- res.json({ userId, postId });
101
- }
102
- }
103
- ```
104
-
105
- ### Query Parameters
106
-
107
- Access query string parameters:
108
-
109
- ```typescript
110
- @get('/users')
111
- async getUsers(req, res) {
112
- const { page = 1, limit = 10, search } = req.query;
113
-
114
- // Handle pagination and search
115
- res.json({
116
- page: parseInt(page),
117
- limit: parseInt(limit),
118
- search
119
- });
120
- }
121
- ```
122
-
123
- ## Route Options
124
-
125
- ### Middleware
126
-
127
- Apply middleware to specific routes:
128
-
129
- ```typescript
130
- @get('/admin/users', { middleware: [authMiddleware, adminMiddleware] })
131
- async getAdminUsers(req, res) {
132
- res.json({ users: [] });
133
- }
134
- ```
135
-
136
- ### Swagger Documentation
137
-
138
- Add OpenAPI documentation to routes:
139
-
140
- ```typescript
141
- @get('/', {
142
- swagger: {
143
- summary: 'Get all users',
144
- description: 'Retrieve a list of all users with pagination',
145
- tags: ['Users'],
146
- responses: {
147
- 200: {
148
- description: 'List of users',
149
- content: {
150
- 'application/json': {
151
- schema: {
152
- type: 'array',
153
- items: { $ref: '#/components/schemas/User' }
154
- }
155
- }
156
- }
157
- }
158
- }
159
- }
160
- })
161
- async getAllUsers(req, res) {
162
- res.json({ users: [] });
163
- }
164
- ```
165
-
166
- ## Route Patterns
167
-
168
- ### Static Routes
169
-
170
- ```typescript
171
- @get('/about')
172
- async getAbout(req, res) {
173
- res.json({ message: 'About page' });
174
- }
175
- ```
176
-
177
- ### Dynamic Routes
178
-
179
- ```typescript
180
- @get('/users/:id')
181
- async getUser(req, res) {
182
- const id = req.params.id;
183
- res.json({ id });
184
- }
185
- ```
186
-
187
- ### Optional Parameters
188
-
189
- ```typescript
190
- @get('/posts/:id?')
191
- async getPost(req, res) {
192
- const id = req.params.id;
193
- if (id) {
194
- res.json({ id });
195
- } else {
196
- res.json({ posts: [] });
197
- }
198
- }
199
- ```
200
-
201
- ### Wildcard Routes
202
-
203
- ```typescript
204
- @get('/files/*')
205
- async getFile(req, res) {
206
- const filePath = req.params['*'];
207
- res.json({ filePath });
208
- }
209
- ```
210
-
211
- ## Route Precedence
212
-
213
- Routes are matched in the order they are registered. More specific routes should be defined before more general ones:
214
-
215
- ```typescript
216
- @controller('/users')
217
- export class UsersController {
218
- // Specific route first
219
- @get('/admin')
220
- async getAdminUsers(req, res) {
221
- res.json({ users: [] });
222
- }
223
-
224
- // General route after
225
- @get('/:id')
226
- async getUserById(req, res) {
227
- res.json({ id: req.params.id });
228
- }
229
- }
230
- ```
231
-
232
- ## Route Groups
233
-
234
- Organize related routes using controllers:
235
-
236
- ```typescript
237
- @controller('/api/v1/users')
238
- export class UsersController {
239
- @get('/')
240
- async getAllUsers(req, res) {
241
- res.json({ users: [] });
242
- }
243
- }
244
-
245
- @controller('/api/v1/posts')
246
- export class PostsController {
247
- @get('/')
248
- async getAllPosts(req, res) {
249
- res.json({ posts: [] });
250
- }
251
- }
252
- ```
253
-
254
- ## Error Handling
255
-
256
- ### 404 Not Found
257
-
258
- Routes that don't match any pattern return a 404 response:
259
-
260
- ```typescript
261
- // This will be handled by the 404 handler
262
- server.get('/nonexistent', (req, res) => {
263
- // This won't be reached
264
- });
265
- ```
266
-
267
- ### Custom 404 Handler
268
-
269
- ```typescript
270
- server.setErrorHandler((req, res, next, error) => {
271
- if (error.name === 'RouteNotFoundError') {
272
- return res.notFound({
273
- error: 'Route not found',
274
- path: req.url
275
- });
276
- }
277
- next(error);
278
- });
279
- ```
280
-
281
- ## Route Testing
282
-
283
- ### Mock Server
284
-
285
- Use the mock server for testing routes:
286
-
287
- ```typescript
288
- import { Server } from 'balda-js';
289
-
290
- const server = new Server({ port: 3000 });
291
-
292
- server.get('/users', (req, res) => {
293
- res.json({ users: [] });
294
- });
295
-
296
- // Get mock server for testing
297
- const mockServer = await server.getMockServer();
298
-
299
- // Test the route
300
- const response = await mockServer.get('/users');
301
- console.log(response.statusCode()); // 200
302
- console.log(response.body()); // { users: [] }
303
- ```
304
-
305
- ## Best Practices
306
-
307
- ### 1. Use Controllers for Organization
308
-
309
- ```typescript
310
- // Good: Organized by resource
311
- @controller('/users')
312
- export class UsersController {}
313
-
314
- @controller('/posts')
315
- export class PostsController {}
316
-
317
- // Avoid: Mixed resources in one controller
318
- @controller('/api')
319
- export class ApiController {} // Too broad
320
- ```
321
-
322
- ### 2. Consistent Naming
323
-
324
- ```typescript
325
- // Good: RESTful naming
326
- @get('/users') // GET /users
327
- @get('/users/:id') // GET /users/123
328
- @post('/users') // POST /users
329
- @put('/users/:id') // PUT /users/123
330
- @del('/users/:id') // DELETE /users/123
331
-
332
- // Avoid: Inconsistent naming
333
- @get('/getUsers')
334
- @post('/createUser')
335
- @put('/updateUser')
336
- ```
337
-
338
- ### 3. Parameter Validation
339
-
340
- ```typescript
341
- @get('/users/:id')
342
- async getUserById(req, res) {
343
- const id = parseInt(req.params.id);
344
-
345
- if (isNaN(id)) {
346
- return res.badRequest({ error: 'Invalid user ID' });
347
- }
348
-
349
- res.json({ id });
350
- }
351
- ```
352
-
353
- ### 4. Query Parameter Handling
354
-
355
- ```typescript
356
- @get('/users')
357
- async getUsers(req, res) {
358
- const page = Math.max(1, parseInt(req.query.page) || 1);
359
- const limit = Math.min(100, Math.max(1, parseInt(req.query.limit) || 10));
360
-
361
- res.json({ page, limit });
362
- }
363
- ```
364
-
365
- ### 5. Route Documentation
366
-
367
- ```typescript
368
- @get('/', {
369
- swagger: {
370
- summary: 'Get all users',
371
- description: 'Retrieve a paginated list of users',
372
- tags: ['Users'],
373
- parameters: [
374
- {
375
- name: 'page',
376
- in: 'query',
377
- description: 'Page number',
378
- schema: { type: 'integer', default: 1 }
379
- }
380
- ]
381
- }
382
- })
383
- async getAllUsers(req, res) {
384
- res.json({ users: [] });
385
- }
386
- ```
387
-
388
- Balda.js routing provides a powerful and flexible system for defining your application's endpoints with support for both simple and complex routing patterns.
@@ -1,332 +0,0 @@
1
- ---
2
- sidebar_position: 1
3
- ---
4
-
5
- # Server
6
-
7
- The `Server` class is the main entry point for creating Balda.js applications. It handles HTTP requests, manages middleware, and orchestrates the entire application lifecycle.
8
-
9
- ## Creating a Server
10
-
11
- ```typescript
12
- import { Server } from 'balda-js';
13
-
14
- const server = new Server({
15
- port: 3000,
16
- host: 'localhost'
17
- });
18
- ```
19
-
20
- ## Server Lifecycle
21
-
22
- ### 1. Initialization
23
-
24
- When you create a server instance, it:
25
-
26
- - Sets up the runtime connector (Node.js, Bun, or Deno)
27
- - Initializes the router
28
- - Applies global middleware
29
- - Sets up the body parser
30
-
31
- ```typescript
32
- const server = new Server({
33
- port: 3000,
34
- plugins: {
35
- cors: { origin: '*' },
36
- json: { sizeLimit: '1mb' }
37
- }
38
- });
39
- ```
40
-
41
- ### 2. Route Registration
42
-
43
- Routes can be registered in two ways:
44
-
45
- **Direct registration:**
46
- ```typescript
47
- server.get('/users', (req, res) => {
48
- res.json({ users: [] });
49
- });
50
- ```
51
-
52
- **Controller-based registration:**
53
- ```typescript
54
- @controller('/users')
55
- export class UsersController {
56
- @get('/')
57
- async getUsers(req, res) {
58
- res.json({ users: [] });
59
- }
60
- }
61
- ```
62
-
63
- ### 3. Server Startup
64
-
65
- When you call `server.listen()`, the server:
66
-
67
- - Imports controllers based on patterns
68
- - Registers all routes
69
- - Applies plugins
70
- - Starts listening for requests
71
-
72
- ```typescript
73
- server.listen(({ port, host }) => {
74
- console.log(`Server running on http://${host}:${port}`);
75
- });
76
- ```
77
-
78
- ## Server Configuration
79
-
80
- ### Basic Options
81
-
82
- ```typescript
83
- const server = new Server({
84
- port: 3000, // Server port
85
- host: 'localhost', // Server host
86
- controllerPatterns: [ // Controller file patterns
87
- './controllers/**/*.ts'
88
- ],
89
- plugins: {}, // Plugin configuration
90
- swagger: true, // Enable Swagger docs
91
- tapOptions: {} // Runtime-specific options
92
- });
93
- ```
94
-
95
- ### Advanced Configuration
96
-
97
- ```typescript
98
- const server = new Server({
99
- port: process.env.PORT || 3000,
100
- host: process.env.HOST || '0.0.0.0',
101
- controllerPatterns: [
102
- './src/controllers/**/*.ts',
103
- './src/api/**/*.ts'
104
- ],
105
- plugins: {
106
- cors: { origin: '*' },
107
- json: { sizeLimit: '10mb' },
108
- static: { root: './public' }
109
- },
110
- swagger: {
111
- type: 'standard',
112
- models: {
113
- User: {
114
- type: 'object',
115
- properties: {
116
- id: { type: 'number' },
117
- name: { type: 'string' }
118
- }
119
- }
120
- }
121
- }
122
- });
123
- ```
124
-
125
- ## Server Methods
126
-
127
- ### HTTP Methods
128
-
129
- ```typescript
130
- // GET requests
131
- server.get('/users', (req, res) => {
132
- res.json({ users: [] });
133
- });
134
-
135
- // POST requests
136
- server.post('/users', (req, res) => {
137
- res.created({ id: 1, name: 'John' });
138
- });
139
-
140
- // PUT requests
141
- server.put('/users/:id', (req, res) => {
142
- res.json({ id: req.params.id, name: 'Updated' });
143
- });
144
-
145
- // PATCH requests
146
- server.patch('/users/:id', (req, res) => {
147
- res.json({ id: req.params.id, ...req.body });
148
- });
149
-
150
- // DELETE requests
151
- server.delete('/users/:id', (req, res) => {
152
- res.noContent();
153
- });
154
- ```
155
-
156
- ### Middleware Management
157
-
158
- ```typescript
159
- // Add global middleware
160
- server.use((req, res, next) => {
161
- console.log(`${req.method} ${req.url}`);
162
- next();
163
- });
164
-
165
- // Add multiple middleware
166
- server.use(
167
- (req, res, next) => {
168
- req.startTime = Date.now();
169
- next();
170
- },
171
- (req, res, next) => {
172
- res.on('finish', () => {
173
- const duration = Date.now() - req.startTime;
174
- console.log(`${req.method} ${req.url} - ${duration}ms`);
175
- });
176
- next();
177
- }
178
- );
179
- ```
180
-
181
- ### Error Handling
182
-
183
- ```typescript
184
- server.setErrorHandler((req, res, next, error) => {
185
- console.error('Error:', error);
186
-
187
- if (error.name === 'ValidationError') {
188
- return res.badRequest({ error: error.message });
189
- }
190
-
191
- res.internalServerError({ error: 'Internal server error' });
192
- });
193
- ```
194
-
195
- ## Server Properties
196
-
197
- ### Read-only Properties
198
-
199
- ```typescript
200
- // Get server URL
201
- console.log(server.url); // http://localhost:3000
202
-
203
- // Get server port
204
- console.log(server.port); // 3000
205
-
206
- // Get server host
207
- console.log(server.host); // localhost
208
-
209
- // Check if server is listening
210
- console.log(server.isListening); // true/false
211
- ```
212
-
213
- ### Utility Methods
214
-
215
- ```typescript
216
- // Get temporary directory
217
- const tmpDir = server.tmpDir('uploads', 'images');
218
-
219
- // Embed data for later use
220
- server.embed('config', { apiKey: 'secret' });
221
-
222
- // Get embedded data
223
- const config = server.embed('config');
224
-
225
- // Exit the server
226
- server.exit(0);
227
- ```
228
-
229
- ## Event Handling
230
-
231
- ```typescript
232
- // Handle graceful shutdown
233
- server.on('SIGTERM', () => {
234
- console.log('Received SIGTERM, shutting down gracefully');
235
- server.close();
236
- });
237
-
238
- server.on('SIGINT', () => {
239
- console.log('Received SIGINT, shutting down gracefully');
240
- server.close();
241
- });
242
- ```
243
-
244
- ## Server Shutdown
245
-
246
- ```typescript
247
- // Graceful shutdown
248
- async function shutdown() {
249
- console.log('Shutting down server...');
250
- await server.close();
251
- console.log('Server shut down successfully');
252
- process.exit(0);
253
- }
254
-
255
- // Handle shutdown signals
256
- process.on('SIGTERM', shutdown);
257
- process.on('SIGINT', shutdown);
258
- ```
259
-
260
- ## Runtime Support
261
-
262
- Balda.js automatically detects and adapts to your runtime:
263
-
264
- ### Node.js
265
- ```typescript
266
- // Uses Node.js http module
267
- const server = new Server({
268
- port: 3000
269
- });
270
- ```
271
-
272
- ### Bun
273
- ```typescript
274
- // Uses Bun's HTTP server
275
- const server = new Server({
276
- port: 3000
277
- });
278
- ```
279
-
280
- ### Deno
281
- ```typescript
282
- // Uses Deno's HTTP server
283
- const server = new Server({
284
- port: 3000
285
- });
286
- ```
287
-
288
- ## Complete Example
289
-
290
- ```typescript
291
- import { Server } from 'balda-js';
292
-
293
- const server = new Server({
294
- port: 3000,
295
- host: 'localhost',
296
- controllerPatterns: ['./src/controllers/**/*.ts'],
297
- plugins: {
298
- cors: { origin: '*' },
299
- json: { sizeLimit: '10mb' },
300
- log: { logRequest: true }
301
- }
302
- });
303
-
304
- // Global middleware
305
- server.use((req, res, next) => {
306
- req.startTime = Date.now();
307
- next();
308
- });
309
-
310
- // Error handler
311
- server.setErrorHandler((req, res, next, error) => {
312
- console.error('Error:', error);
313
- res.internalServerError({ error: 'Something went wrong' });
314
- });
315
-
316
- // Direct route registration
317
- server.get('/health', (req, res) => {
318
- res.json({ status: 'ok', uptime: process.uptime() });
319
- });
320
-
321
- // Start server
322
- server.listen(({ port, host }) => {
323
- console.log(`🚀 Server running on http://${host}:${port}`);
324
- console.log(`📚 API Documentation: http://${host}:${port}/docs`);
325
- });
326
-
327
- // Graceful shutdown
328
- process.on('SIGTERM', () => server.close());
329
- process.on('SIGINT', () => server.close());
330
- ```
331
-
332
- The Server class provides a solid foundation for building scalable web applications with Balda.js.