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.
- package/package.json +1 -6
- package/.husky/pre-commit +0 -19
- package/.nvmrc +0 -1
- package/docs/README.md +0 -135
- package/docs/blog/authors.yml +0 -6
- package/docs/blog/tags.yml +0 -4
- package/docs/cli.md +0 -109
- package/docs/docs/core-concepts/controllers.md +0 -393
- package/docs/docs/core-concepts/middleware.md +0 -302
- package/docs/docs/core-concepts/request-response.md +0 -486
- package/docs/docs/core-concepts/routing.md +0 -388
- package/docs/docs/core-concepts/server.md +0 -332
- package/docs/docs/cron/overview.md +0 -70
- package/docs/docs/examples/rest-api.md +0 -595
- package/docs/docs/getting-started/configuration.md +0 -168
- package/docs/docs/getting-started/installation.md +0 -125
- package/docs/docs/getting-started/quick-start.md +0 -273
- package/docs/docs/intro.md +0 -46
- package/docs/docs/plugins/cookie.md +0 -424
- package/docs/docs/plugins/cors.md +0 -295
- package/docs/docs/plugins/file.md +0 -382
- package/docs/docs/plugins/helmet.md +0 -388
- package/docs/docs/plugins/json.md +0 -338
- package/docs/docs/plugins/log.md +0 -592
- package/docs/docs/plugins/overview.md +0 -390
- package/docs/docs/plugins/rate-limiter.md +0 -347
- package/docs/docs/plugins/static.md +0 -352
- package/docs/docs/plugins/swagger.md +0 -411
- package/docs/docs/plugins/urlencoded.md +0 -76
- package/docs/docs/testing/examples.md +0 -384
- package/docs/docs/testing/mock-server.md +0 -311
- package/docs/docs/testing/overview.md +0 -76
- package/docs/docusaurus.config.ts +0 -144
- package/docs/intro.md +0 -78
- package/docs/package.json +0 -46
- package/docs/sidebars.ts +0 -72
- package/docs/static/.nojekyll +0 -0
- package/docs/static/img/docusaurus-social-card.jpg +0 -0
- package/docs/static/img/docusaurus.png +0 -0
- package/docs/static/img/favicon.ico +0 -0
- package/docs/static/img/logo.svg +0 -1
- package/docs/static/img/undraw_docusaurus_mountain.svg +0 -37
- package/docs/static/img/undraw_docusaurus_react.svg +0 -170
- package/docs/static/img/undraw_docusaurus_tree.svg +0 -40
- package/docs/tsconfig.json +0 -8
- package/speed_test.sh +0 -3
- package/test/benchmark/index.ts +0 -17
- package/test/cli/cli.ts +0 -7
- package/test/commands/test.ts +0 -42
- package/test/controllers/file_upload.ts +0 -29
- package/test/controllers/urlencoded.ts +0 -13
- package/test/controllers/users.ts +0 -111
- package/test/cron/index.ts +0 -6
- package/test/cron/test_cron.ts +0 -8
- package/test/cron/test_cron_imported.ts +0 -8
- package/test/native_env.ts +0 -16
- package/test/resources/test.txt +0 -1
- package/test/server/index.ts +0 -3
- package/test/server/instance.ts +0 -63
- package/test/suite/upload.test.ts +0 -23
- package/test/suite/urlencoded.test.ts +0 -23
- package/test/suite/users.test.ts +0 -76
- package/todo.md +0 -9
- package/tsconfig.json +0 -24
- package/vitest.config.ts +0 -17
@@ -1,411 +0,0 @@
|
|
1
|
-
---
|
2
|
-
sidebar_position: 9
|
3
|
-
---
|
4
|
-
|
5
|
-
# Swagger Plugin
|
6
|
-
|
7
|
-
The Swagger plugin automatically generates OpenAPI 3.0 documentation for your Balda.js API. It provides interactive documentation with three UI options: Swagger UI, ReDoc, and RapiDoc.
|
8
|
-
|
9
|
-
## Features
|
10
|
-
|
11
|
-
- **Automatic Route Discovery**: Automatically discovers and documents all your routes
|
12
|
-
- **Multiple UI Options**: Choose between Swagger UI, ReDoc, or RapiDoc
|
13
|
-
- **Type Integration**: Uses your validation schemas to generate accurate request/response documentation
|
14
|
-
- **Security Support**: Document authentication schemes and security requirements
|
15
|
-
- **Custom Models**: Define reusable data models for your API
|
16
|
-
|
17
|
-
## Global Configuration
|
18
|
-
|
19
|
-
### Basic Setup
|
20
|
-
|
21
|
-
```typescript
|
22
|
-
import { Server } from 'balda-js';
|
23
|
-
|
24
|
-
const server = new Server({
|
25
|
-
port: 3000,
|
26
|
-
swagger: {
|
27
|
-
type: "standard", // "standard" | "redoc" | "rapidoc"
|
28
|
-
path: "/docs",
|
29
|
-
title: "My API Documentation",
|
30
|
-
description: "API documentation for my application",
|
31
|
-
version: "1.0.0",
|
32
|
-
servers: ["http://localhost:3000"]
|
33
|
-
}
|
34
|
-
});
|
35
|
-
```
|
36
|
-
|
37
|
-
### Advanced Configuration
|
38
|
-
|
39
|
-
```typescript
|
40
|
-
const server = new Server({
|
41
|
-
port: 3000,
|
42
|
-
swagger: {
|
43
|
-
type: "standard",
|
44
|
-
path: "/api-docs",
|
45
|
-
title: "E-Commerce API",
|
46
|
-
description: "Complete API for our e-commerce platform",
|
47
|
-
version: "2.1.0",
|
48
|
-
servers: [
|
49
|
-
"http://localhost:3000",
|
50
|
-
"https://api.staging.example.com",
|
51
|
-
"https://api.example.com"
|
52
|
-
],
|
53
|
-
security: [
|
54
|
-
{ bearer: [] }
|
55
|
-
],
|
56
|
-
securitySchemes: {
|
57
|
-
bearer: {
|
58
|
-
type: "http",
|
59
|
-
scheme: "bearer",
|
60
|
-
bearerFormat: "JWT"
|
61
|
-
},
|
62
|
-
apiKey: {
|
63
|
-
type: "apiKey",
|
64
|
-
name: "X-API-Key",
|
65
|
-
in: "header"
|
66
|
-
}
|
67
|
-
},
|
68
|
-
tags: {
|
69
|
-
users: {
|
70
|
-
description: "User management operations"
|
71
|
-
},
|
72
|
-
products: {
|
73
|
-
description: "Product catalog operations"
|
74
|
-
},
|
75
|
-
orders: {
|
76
|
-
description: "Order processing operations"
|
77
|
-
}
|
78
|
-
},
|
79
|
-
models: {
|
80
|
-
User: {
|
81
|
-
type: "object",
|
82
|
-
properties: {
|
83
|
-
id: { type: "string", format: "uuid" },
|
84
|
-
email: { type: "string", format: "email" },
|
85
|
-
name: { type: "string" },
|
86
|
-
createdAt: { type: "string", format: "date-time" }
|
87
|
-
},
|
88
|
-
required: ["email", "name"]
|
89
|
-
},
|
90
|
-
Product: {
|
91
|
-
type: "object",
|
92
|
-
properties: {
|
93
|
-
id: { type: "string" },
|
94
|
-
name: { type: "string" },
|
95
|
-
price: { type: "number" },
|
96
|
-
category: { type: "string" }
|
97
|
-
},
|
98
|
-
required: ["name", "price"]
|
99
|
-
}
|
100
|
-
}
|
101
|
-
}
|
102
|
-
});
|
103
|
-
```
|
104
|
-
|
105
|
-
## Route-Level Documentation
|
106
|
-
|
107
|
-
### Basic Route Documentation
|
108
|
-
|
109
|
-
```typescript
|
110
|
-
import { controller, get, post } from 'balda-js';
|
111
|
-
import { Request, Response } from 'balda-js';
|
112
|
-
|
113
|
-
@controller('/users')
|
114
|
-
export class UsersController {
|
115
|
-
@get('/', {
|
116
|
-
swagger: {
|
117
|
-
name: "Get All Users",
|
118
|
-
description: "Retrieve a list of all users",
|
119
|
-
service: "users",
|
120
|
-
responses: {
|
121
|
-
"200": {
|
122
|
-
type: "array",
|
123
|
-
items: { $ref: "#/components/schemas/User" }
|
124
|
-
}
|
125
|
-
}
|
126
|
-
}
|
127
|
-
})
|
128
|
-
async getAllUsers(req: Request, res: Response) {
|
129
|
-
const users = await getUsers();
|
130
|
-
res.json(users);
|
131
|
-
}
|
132
|
-
|
133
|
-
@post('/', {
|
134
|
-
swagger: {
|
135
|
-
name: "Create User",
|
136
|
-
description: "Create a new user account",
|
137
|
-
service: "users",
|
138
|
-
requestBody: {
|
139
|
-
type: "object",
|
140
|
-
properties: {
|
141
|
-
email: { type: "string", format: "email" },
|
142
|
-
name: { type: "string" },
|
143
|
-
password: { type: "string", minLength: 8 }
|
144
|
-
},
|
145
|
-
required: ["email", "name", "password"]
|
146
|
-
},
|
147
|
-
responses: {
|
148
|
-
"201": {
|
149
|
-
type: "object",
|
150
|
-
properties: {
|
151
|
-
user: { $ref: "#/components/schemas/User" },
|
152
|
-
message: { type: "string" }
|
153
|
-
}
|
154
|
-
},
|
155
|
-
"400": {
|
156
|
-
type: "object",
|
157
|
-
properties: {
|
158
|
-
error: { type: "string" },
|
159
|
-
details: { type: "array", items: { type: "string" } }
|
160
|
-
}
|
161
|
-
}
|
162
|
-
}
|
163
|
-
}
|
164
|
-
})
|
165
|
-
async createUser(req: Request, res: Response) {
|
166
|
-
const user = await createUser(req.body);
|
167
|
-
res.created({ user, message: "User created successfully" });
|
168
|
-
}
|
169
|
-
}
|
170
|
-
```
|
171
|
-
|
172
|
-
### Path Parameters
|
173
|
-
|
174
|
-
```typescript
|
175
|
-
@get('/:id', {
|
176
|
-
swagger: {
|
177
|
-
name: "Get User by ID",
|
178
|
-
description: "Retrieve a specific user by their ID",
|
179
|
-
service: "users",
|
180
|
-
params: {
|
181
|
-
type: "object",
|
182
|
-
properties: {
|
183
|
-
id: { type: "string", format: "uuid" }
|
184
|
-
}
|
185
|
-
},
|
186
|
-
responses: {
|
187
|
-
"200": { $ref: "#/components/schemas/User" },
|
188
|
-
"404": {
|
189
|
-
type: "object",
|
190
|
-
properties: {
|
191
|
-
error: { type: "string" }
|
192
|
-
}
|
193
|
-
}
|
194
|
-
}
|
195
|
-
}
|
196
|
-
})
|
197
|
-
async getUserById(req: Request, res: Response) {
|
198
|
-
const { id } = req.params;
|
199
|
-
const user = await getUserById(id);
|
200
|
-
if (!user) {
|
201
|
-
return res.notFound({ error: "User not found" });
|
202
|
-
}
|
203
|
-
res.json(user);
|
204
|
-
}
|
205
|
-
```
|
206
|
-
|
207
|
-
### Query Parameters
|
208
|
-
|
209
|
-
```typescript
|
210
|
-
@get('/search', {
|
211
|
-
swagger: {
|
212
|
-
name: "Search Users",
|
213
|
-
description: "Search users with filters",
|
214
|
-
service: "users",
|
215
|
-
query: {
|
216
|
-
type: "object",
|
217
|
-
properties: {
|
218
|
-
q: { type: "string", description: "Search query" },
|
219
|
-
limit: { type: "number", minimum: 1, maximum: 100, default: 10 },
|
220
|
-
offset: { type: "number", minimum: 0, default: 0 },
|
221
|
-
sort: { type: "string", enum: ["name", "email", "createdAt"] }
|
222
|
-
},
|
223
|
-
required: ["q"]
|
224
|
-
},
|
225
|
-
responses: {
|
226
|
-
"200": {
|
227
|
-
type: "object",
|
228
|
-
properties: {
|
229
|
-
users: {
|
230
|
-
type: "array",
|
231
|
-
items: { $ref: "#/components/schemas/User" }
|
232
|
-
},
|
233
|
-
total: { type: "number" },
|
234
|
-
limit: { type: "number" },
|
235
|
-
offset: { type: "number" }
|
236
|
-
}
|
237
|
-
}
|
238
|
-
}
|
239
|
-
}
|
240
|
-
})
|
241
|
-
async searchUsers(req: Request, res: Response) {
|
242
|
-
const { q, limit = 10, offset = 0, sort } = req.query;
|
243
|
-
const result = await searchUsers({ q, limit, offset, sort });
|
244
|
-
res.json(result);
|
245
|
-
}
|
246
|
-
```
|
247
|
-
|
248
|
-
### Security Requirements
|
249
|
-
|
250
|
-
```typescript
|
251
|
-
@post('/profile', {
|
252
|
-
swagger: {
|
253
|
-
name: "Update Profile",
|
254
|
-
description: "Update user profile (requires authentication)",
|
255
|
-
service: "users",
|
256
|
-
security: [
|
257
|
-
{ type: "bearer", bearerFormat: "JWT" }
|
258
|
-
],
|
259
|
-
requestBody: {
|
260
|
-
type: "object",
|
261
|
-
properties: {
|
262
|
-
name: { type: "string" },
|
263
|
-
bio: { type: "string" }
|
264
|
-
}
|
265
|
-
},
|
266
|
-
responses: {
|
267
|
-
"200": { $ref: "#/components/schemas/User" },
|
268
|
-
"401": {
|
269
|
-
type: "object",
|
270
|
-
properties: {
|
271
|
-
error: { type: "string" }
|
272
|
-
}
|
273
|
-
}
|
274
|
-
}
|
275
|
-
}
|
276
|
-
})
|
277
|
-
async updateProfile(req: Request, res: Response) {
|
278
|
-
// Implementation with authentication
|
279
|
-
const user = await updateUserProfile(req.user.id, req.body);
|
280
|
-
res.json(user);
|
281
|
-
}
|
282
|
-
```
|
283
|
-
|
284
|
-
### File Upload Documentation
|
285
|
-
|
286
|
-
```typescript
|
287
|
-
@post('/avatar', {
|
288
|
-
swagger: {
|
289
|
-
name: "Upload Avatar",
|
290
|
-
description: "Upload user avatar image",
|
291
|
-
service: "users",
|
292
|
-
bodyType: "form-data",
|
293
|
-
requestBody: {
|
294
|
-
type: "object",
|
295
|
-
properties: {
|
296
|
-
avatar: {
|
297
|
-
type: "string",
|
298
|
-
format: "binary",
|
299
|
-
description: "Avatar image file"
|
300
|
-
}
|
301
|
-
},
|
302
|
-
required: ["avatar"]
|
303
|
-
},
|
304
|
-
responses: {
|
305
|
-
"200": {
|
306
|
-
type: "object",
|
307
|
-
properties: {
|
308
|
-
url: { type: "string", format: "uri" },
|
309
|
-
message: { type: "string" }
|
310
|
-
}
|
311
|
-
}
|
312
|
-
}
|
313
|
-
}
|
314
|
-
})
|
315
|
-
async uploadAvatar(req: Request, res: Response) {
|
316
|
-
const file = req.files.avatar;
|
317
|
-
const url = await uploadFile(file);
|
318
|
-
res.json({ url, message: "Avatar uploaded successfully" });
|
319
|
-
}
|
320
|
-
```
|
321
|
-
|
322
|
-
### Excluding Routes
|
323
|
-
|
324
|
-
```typescript
|
325
|
-
@get('/internal/health', {
|
326
|
-
swagger: {
|
327
|
-
excludeFromSwagger: true
|
328
|
-
}
|
329
|
-
})
|
330
|
-
async healthCheck(req: Request, res: Response) {
|
331
|
-
res.json({ status: "ok" });
|
332
|
-
}
|
333
|
-
```
|
334
|
-
|
335
|
-
## UI Options
|
336
|
-
|
337
|
-
### Swagger UI (Standard)
|
338
|
-
|
339
|
-
```typescript
|
340
|
-
swagger: {
|
341
|
-
type: "standard",
|
342
|
-
path: "/docs"
|
343
|
-
}
|
344
|
-
```
|
345
|
-
|
346
|
-
### ReDoc
|
347
|
-
|
348
|
-
```typescript
|
349
|
-
swagger: {
|
350
|
-
type: "redoc",
|
351
|
-
path: "/docs"
|
352
|
-
}
|
353
|
-
```
|
354
|
-
|
355
|
-
### RapiDoc
|
356
|
-
|
357
|
-
```typescript
|
358
|
-
swagger: {
|
359
|
-
type: "rapidoc",
|
360
|
-
path: "/docs"
|
361
|
-
}
|
362
|
-
```
|
363
|
-
|
364
|
-
## Integration with Validation
|
365
|
-
|
366
|
-
Balda.js automatically integrates your validation schemas with Swagger documentation:
|
367
|
-
|
368
|
-
```typescript
|
369
|
-
import { Type } from '@sinclair/typebox';
|
370
|
-
|
371
|
-
const CreateUserSchema = Type.Object({
|
372
|
-
email: Type.String({ format: 'email' }),
|
373
|
-
name: Type.String({ minLength: 1 }),
|
374
|
-
password: Type.String({ minLength: 8 })
|
375
|
-
});
|
376
|
-
|
377
|
-
@post('/', {
|
378
|
-
validate: { body: CreateUserSchema },
|
379
|
-
swagger: {
|
380
|
-
name: "Create User",
|
381
|
-
requestBody: CreateUserSchema,
|
382
|
-
responses: {
|
383
|
-
"201": { $ref: "#/components/schemas/User" },
|
384
|
-
"400": { $ref: "#/components/schemas/ValidationError" }
|
385
|
-
}
|
386
|
-
}
|
387
|
-
})
|
388
|
-
async createUser(req: Request, res: Response) {
|
389
|
-
// The validation schema automatically becomes the OpenAPI schema
|
390
|
-
const user = await createUser(req.body);
|
391
|
-
res.created(user);
|
392
|
-
}
|
393
|
-
```
|
394
|
-
|
395
|
-
## Accessing Documentation
|
396
|
-
|
397
|
-
Once configured, your API documentation will be available at:
|
398
|
-
|
399
|
-
- **Swagger UI**: `http://localhost:3000/docs`
|
400
|
-
- **OpenAPI JSON**: `http://localhost:3000/docs/json`
|
401
|
-
|
402
|
-
The JSON specification can be used with other OpenAPI tools or imported into external documentation systems.
|
403
|
-
|
404
|
-
## Best Practices
|
405
|
-
|
406
|
-
1. **Use Descriptive Names**: Give your routes meaningful names and descriptions
|
407
|
-
2. **Group Related Routes**: Use the `service` property to group related endpoints
|
408
|
-
3. **Document All Responses**: Include success and error responses
|
409
|
-
4. **Use Reusable Models**: Define models in the global configuration for reuse
|
410
|
-
5. **Keep Security Simple**: Use standard security schemes when possible
|
411
|
-
6. **Test Your Documentation**: Use the generated documentation to test your API
|
@@ -1,76 +0,0 @@
|
|
1
|
-
---
|
2
|
-
sidebar_position: 3
|
3
|
-
---
|
4
|
-
|
5
|
-
# URL Encoded Plugin
|
6
|
-
|
7
|
-
The **URL Encoded** plugin parses `application/x-www-form-urlencoded` request bodies and exposes the parsed data on `req.body` for easy access.
|
8
|
-
|
9
|
-
## Features
|
10
|
-
|
11
|
-
- Parses standard HTML form submissions
|
12
|
-
- Supports nested objects and arrays
|
13
|
-
- Configurable size limit
|
14
|
-
- Works across Node.js, Bun, and Deno
|
15
|
-
|
16
|
-
## Basic Usage
|
17
|
-
|
18
|
-
```typescript
|
19
|
-
import { Server } from 'balda-js';
|
20
|
-
|
21
|
-
const server = new Server({
|
22
|
-
plugins: {
|
23
|
-
urlencoded: true // Enable with default options
|
24
|
-
}
|
25
|
-
});
|
26
|
-
```
|
27
|
-
|
28
|
-
## Custom Configuration
|
29
|
-
|
30
|
-
```typescript
|
31
|
-
const server = new Server({
|
32
|
-
plugins: {
|
33
|
-
urlencoded: {
|
34
|
-
limit: '2mb', // Maximum body size
|
35
|
-
extended: true // Use qs library for rich objects (default: true)
|
36
|
-
}
|
37
|
-
}
|
38
|
-
});
|
39
|
-
```
|
40
|
-
|
41
|
-
## Disabling the Plugin
|
42
|
-
|
43
|
-
```typescript
|
44
|
-
const server = new Server({
|
45
|
-
plugins: {
|
46
|
-
urlencoded: false // Disable entirely
|
47
|
-
}
|
48
|
-
});
|
49
|
-
```
|
50
|
-
|
51
|
-
## Options Reference
|
52
|
-
|
53
|
-
| Option | Type | Default | Description |
|
54
|
-
|----------|---------|---------|-----------------------------------------------|
|
55
|
-
| `limit` | string | `1mb` | Maximum allowed body size before rejection |
|
56
|
-
| `extended` | boolean | `true` | Use rich object parsing (qs) if `true`, or the built-in querystring parser if `false` |
|
57
|
-
|
58
|
-
## Example Route
|
59
|
-
|
60
|
-
```typescript
|
61
|
-
import { post, Server } from 'balda-js';
|
62
|
-
|
63
|
-
@post('/submit')
|
64
|
-
async handleSubmit(req, res) {
|
65
|
-
const data = req.body; // Parsed form data
|
66
|
-
res.json({ received: data });
|
67
|
-
}
|
68
|
-
|
69
|
-
const server = new Server({
|
70
|
-
plugins: { urlencoded: true }
|
71
|
-
});
|
72
|
-
|
73
|
-
server.listen();
|
74
|
-
```
|
75
|
-
|
76
|
-
The URL Encoded plugin makes handling traditional HTML form submissions in Balda.js straightforward and type-safe.
|