balda-js 0.0.1
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/.github/workflows/publish.yml +38 -0
- package/.husky/pre-commit +19 -0
- package/.nvmrc +1 -0
- package/LICENSE +21 -0
- package/README.md +46 -0
- package/deno.lock +2454 -0
- package/docs/README.md +135 -0
- package/docs/blog/authors.yml +6 -0
- package/docs/blog/tags.yml +4 -0
- package/docs/cli.md +109 -0
- package/docs/docs/core-concepts/controllers.md +393 -0
- package/docs/docs/core-concepts/middleware.md +302 -0
- package/docs/docs/core-concepts/request-response.md +486 -0
- package/docs/docs/core-concepts/routing.md +388 -0
- package/docs/docs/core-concepts/server.md +332 -0
- package/docs/docs/cron/overview.md +70 -0
- package/docs/docs/examples/rest-api.md +595 -0
- package/docs/docs/getting-started/configuration.md +168 -0
- package/docs/docs/getting-started/installation.md +125 -0
- package/docs/docs/getting-started/quick-start.md +273 -0
- package/docs/docs/intro.md +46 -0
- package/docs/docs/plugins/cookie.md +424 -0
- package/docs/docs/plugins/cors.md +295 -0
- package/docs/docs/plugins/file.md +382 -0
- package/docs/docs/plugins/helmet.md +388 -0
- package/docs/docs/plugins/json.md +338 -0
- package/docs/docs/plugins/log.md +592 -0
- package/docs/docs/plugins/overview.md +390 -0
- package/docs/docs/plugins/rate-limiter.md +347 -0
- package/docs/docs/plugins/static.md +352 -0
- package/docs/docs/plugins/swagger.md +411 -0
- package/docs/docs/plugins/urlencoded.md +76 -0
- package/docs/docs/testing/examples.md +384 -0
- package/docs/docs/testing/mock-server.md +311 -0
- package/docs/docs/testing/overview.md +76 -0
- package/docs/docusaurus.config.ts +144 -0
- package/docs/intro.md +78 -0
- package/docs/package.json +46 -0
- package/docs/sidebars.ts +72 -0
- 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 +1 -0
- package/docs/static/img/undraw_docusaurus_mountain.svg +37 -0
- package/docs/static/img/undraw_docusaurus_react.svg +170 -0
- package/docs/static/img/undraw_docusaurus_tree.svg +40 -0
- package/docs/tsconfig.json +8 -0
- package/package.json +91 -0
- package/speed_test.sh +3 -0
- package/test/benchmark/index.ts +17 -0
- package/test/cli/cli.ts +7 -0
- package/test/commands/test.ts +42 -0
- package/test/controllers/file_upload.ts +29 -0
- package/test/controllers/urlencoded.ts +13 -0
- package/test/controllers/users.ts +111 -0
- package/test/cron/index.ts +6 -0
- package/test/cron/test_cron.ts +8 -0
- package/test/cron/test_cron_imported.ts +8 -0
- package/test/native_env.ts +16 -0
- package/test/resources/test.txt +1 -0
- package/test/server/index.ts +3 -0
- package/test/server/instance.ts +63 -0
- package/test/suite/upload.test.ts +23 -0
- package/test/suite/urlencoded.test.ts +23 -0
- package/test/suite/users.test.ts +76 -0
- package/todo.md +9 -0
- package/tsconfig.json +24 -0
- package/vitest.config.ts +17 -0
@@ -0,0 +1,168 @@
|
|
1
|
+
---
|
2
|
+
sidebar_position: 3
|
3
|
+
---
|
4
|
+
|
5
|
+
# Configuration
|
6
|
+
|
7
|
+
Learn how to configure your Balda.js server with various options and plugins.
|
8
|
+
|
9
|
+
## Server Configuration
|
10
|
+
|
11
|
+
The `Server` constructor accepts a configuration object with the following options:
|
12
|
+
|
13
|
+
```typescript
|
14
|
+
import { Server } from 'balda-js';
|
15
|
+
|
16
|
+
const server = new Server({
|
17
|
+
port: 3000, // Server port (default: 80)
|
18
|
+
host: '0.0.0.0', // Server host (default: '0.0.0.0')
|
19
|
+
controllerPatterns: [ // Controller file patterns
|
20
|
+
'./controllers/**/*.ts'
|
21
|
+
],
|
22
|
+
plugins: { // Global Plugin configuration
|
23
|
+
cors: { origin: '*' },
|
24
|
+
json: { sizeLimit: '1mb' }
|
25
|
+
},
|
26
|
+
swagger: true, // Enable Swagger docs (default: true)
|
27
|
+
tapOptions: {} // Runtime-specific options applied before start
|
28
|
+
});
|
29
|
+
```
|
30
|
+
|
31
|
+
## Plugin Configuration
|
32
|
+
|
33
|
+
### CORS Plugin
|
34
|
+
|
35
|
+
Configure Cross-Origin Resource Sharing:
|
36
|
+
|
37
|
+
```typescript
|
38
|
+
plugins: {
|
39
|
+
cors: {
|
40
|
+
origin: ['http://localhost:3000', 'https://myapp.com'],
|
41
|
+
methods: ['GET', 'POST', 'PUT', 'DELETE'],
|
42
|
+
allowedHeaders: ['Content-Type', 'Authorization'],
|
43
|
+
credentials: true
|
44
|
+
}
|
45
|
+
}
|
46
|
+
```
|
47
|
+
|
48
|
+
### JSON Plugin
|
49
|
+
|
50
|
+
Configure JSON body parsing:
|
51
|
+
|
52
|
+
```typescript
|
53
|
+
plugins: {
|
54
|
+
json: {
|
55
|
+
sizeLimit: '10mb', // Maximum request body size
|
56
|
+
strict: true, // Strict JSON parsing
|
57
|
+
type: 'application/json' // Content type to parse
|
58
|
+
}
|
59
|
+
}
|
60
|
+
```
|
61
|
+
|
62
|
+
### Static Files Plugin
|
63
|
+
|
64
|
+
Serve static files:
|
65
|
+
|
66
|
+
```typescript
|
67
|
+
plugins: {
|
68
|
+
static: {
|
69
|
+
root: './public', // Static files directory
|
70
|
+
prefix: '/static', // URL prefix (optional)
|
71
|
+
index: 'index.html' // Default index file
|
72
|
+
}
|
73
|
+
}
|
74
|
+
```
|
75
|
+
|
76
|
+
### Cookie Plugin
|
77
|
+
|
78
|
+
Configure cookie parsing:
|
79
|
+
|
80
|
+
```typescript
|
81
|
+
plugins: {
|
82
|
+
cookie: {
|
83
|
+
secret: 'your-secret-key', // Secret for signed cookies
|
84
|
+
secure: false, // HTTPS only (production: true)
|
85
|
+
httpOnly: true, // Prevent XSS attacks
|
86
|
+
sameSite: 'Strict' // CSRF protection
|
87
|
+
}
|
88
|
+
}
|
89
|
+
```
|
90
|
+
|
91
|
+
### Helmet Plugin
|
92
|
+
|
93
|
+
Configure security headers:
|
94
|
+
|
95
|
+
```typescript
|
96
|
+
plugins: {
|
97
|
+
helmet: {
|
98
|
+
contentSecurityPolicy: {
|
99
|
+
directives: {
|
100
|
+
defaultSrc: ["'self'"],
|
101
|
+
styleSrc: ["'self'", "'unsafe-inline'"],
|
102
|
+
scriptSrc: ["'self'"]
|
103
|
+
}
|
104
|
+
},
|
105
|
+
hsts: {
|
106
|
+
maxAge: 31536000,
|
107
|
+
includeSubDomains: true
|
108
|
+
}
|
109
|
+
}
|
110
|
+
}
|
111
|
+
```
|
112
|
+
|
113
|
+
### Rate Limiter Plugin
|
114
|
+
|
115
|
+
Configure request rate limiting:
|
116
|
+
|
117
|
+
```typescript
|
118
|
+
plugins: {
|
119
|
+
rateLimiter: {
|
120
|
+
windowMs: 15 * 60 * 1000, // 15 minutes
|
121
|
+
max: 100, // Limit each IP to 100 requests per window
|
122
|
+
message: 'Too many requests',
|
123
|
+
standardHeaders: true,
|
124
|
+
legacyHeaders: false
|
125
|
+
}
|
126
|
+
}
|
127
|
+
```
|
128
|
+
|
129
|
+
### Log Plugin
|
130
|
+
|
131
|
+
Configure request/response logging:
|
132
|
+
|
133
|
+
```typescript
|
134
|
+
plugins: {
|
135
|
+
log: {
|
136
|
+
logRequest: true, // Log incoming requests
|
137
|
+
logResponse: true, // Log responses
|
138
|
+
logError: true, // Log errors
|
139
|
+
format: 'combined' // Log format
|
140
|
+
}
|
141
|
+
}
|
142
|
+
```
|
143
|
+
|
144
|
+
### File Upload Plugin
|
145
|
+
|
146
|
+
Configure file upload handling:
|
147
|
+
|
148
|
+
```typescript
|
149
|
+
plugins: {
|
150
|
+
file: {
|
151
|
+
maxFileSize: '10mb', // Maximum file size
|
152
|
+
}
|
153
|
+
}
|
154
|
+
```
|
155
|
+
|
156
|
+
### URL Encoded Plugin
|
157
|
+
|
158
|
+
Configure www-urlencoded data parsing:
|
159
|
+
|
160
|
+
```typescript
|
161
|
+
plugins: {
|
162
|
+
urlencoded: {
|
163
|
+
extended: true, // Use qs library for parsing
|
164
|
+
limit: '10mb', // Maximum body size
|
165
|
+
parameterLimit: 1000 // Maximum parameters
|
166
|
+
}
|
167
|
+
}
|
168
|
+
```
|
@@ -0,0 +1,125 @@
|
|
1
|
+
---
|
2
|
+
sidebar_position: 1
|
3
|
+
---
|
4
|
+
|
5
|
+
# Installation
|
6
|
+
|
7
|
+
Balda.js supports multiple JavaScript runtimes. Choose the installation method that best fits your project.
|
8
|
+
|
9
|
+
## Prerequisites
|
10
|
+
|
11
|
+
- **Node.js**: Version 18 or higher
|
12
|
+
- **Bun**: Version 1.0 or higher
|
13
|
+
- **Deno**: Version 1.40 or higher
|
14
|
+
- **TypeScript**: Version 5.0 or higher (recommended)
|
15
|
+
|
16
|
+
## Installation Options
|
17
|
+
|
18
|
+
### Node.js
|
19
|
+
|
20
|
+
```bash
|
21
|
+
# Using npm
|
22
|
+
npm install balda-js
|
23
|
+
|
24
|
+
# Using yarn
|
25
|
+
yarn add balda-js
|
26
|
+
|
27
|
+
# Using pnpm
|
28
|
+
pnpm add balda-js
|
29
|
+
```
|
30
|
+
|
31
|
+
### Bun
|
32
|
+
|
33
|
+
```bash
|
34
|
+
# Using bun
|
35
|
+
bun add balda-js
|
36
|
+
```
|
37
|
+
|
38
|
+
### Deno
|
39
|
+
|
40
|
+
```typescript
|
41
|
+
// deno.json
|
42
|
+
{
|
43
|
+
"imports": {
|
44
|
+
"balda-js": "npm:balda-js"
|
45
|
+
}
|
46
|
+
}
|
47
|
+
```
|
48
|
+
|
49
|
+
## TypeScript Setup
|
50
|
+
|
51
|
+
Balda.js is built with TypeScript and provides excellent type support. Make sure your `tsconfig.json` includes:
|
52
|
+
|
53
|
+
```json
|
54
|
+
{
|
55
|
+
"compilerOptions": {
|
56
|
+
"target": "ES2022",
|
57
|
+
"module": "ESNext",
|
58
|
+
"moduleResolution": "node",
|
59
|
+
"experimentalDecorators": true,
|
60
|
+
"emitDecoratorMetadata": true,
|
61
|
+
"strict": true,
|
62
|
+
"esModuleInterop": true,
|
63
|
+
"skipLibCheck": true,
|
64
|
+
"forceConsistentCasingInFileNames": true
|
65
|
+
}
|
66
|
+
}
|
67
|
+
```
|
68
|
+
|
69
|
+
## Development Dependencies
|
70
|
+
|
71
|
+
For development, you might want to install additional packages:
|
72
|
+
|
73
|
+
```bash
|
74
|
+
# TypeScript support
|
75
|
+
npm install -D typescript @types/node
|
76
|
+
|
77
|
+
# Testing
|
78
|
+
npm install -D vitest
|
79
|
+
|
80
|
+
# Development server
|
81
|
+
npm install -D tsx
|
82
|
+
|
83
|
+
# Code formatting
|
84
|
+
npm install -D prettier
|
85
|
+
```
|
86
|
+
|
87
|
+
## Verify Installation
|
88
|
+
|
89
|
+
Create a simple test file to verify your installation:
|
90
|
+
|
91
|
+
```typescript
|
92
|
+
// test-installation.ts
|
93
|
+
import { Server } from 'balda-js';
|
94
|
+
|
95
|
+
const server = new Server({
|
96
|
+
port: 3000
|
97
|
+
});
|
98
|
+
|
99
|
+
server.get('/', (req, res) => {
|
100
|
+
res.json({ message: 'Balda.js is working!' });
|
101
|
+
});
|
102
|
+
|
103
|
+
server.listen(() => {
|
104
|
+
console.log('Server running on http://localhost:3000');
|
105
|
+
});
|
106
|
+
```
|
107
|
+
|
108
|
+
Run the test:
|
109
|
+
|
110
|
+
```bash
|
111
|
+
# Node.js
|
112
|
+
npx tsx test-installation.ts
|
113
|
+
|
114
|
+
# Bun
|
115
|
+
bun run test-installation.ts
|
116
|
+
|
117
|
+
# Deno
|
118
|
+
deno run --allow-net test-installation.ts
|
119
|
+
```
|
120
|
+
|
121
|
+
Visit `http://localhost:3000` to see the welcome message.
|
122
|
+
|
123
|
+
## Next Steps
|
124
|
+
|
125
|
+
Now that you have Balda.js installed, check out our [Quick Start Guide](./quick-start) to build your first application.
|
@@ -0,0 +1,273 @@
|
|
1
|
+
---
|
2
|
+
sidebar_position: 2
|
3
|
+
---
|
4
|
+
|
5
|
+
# Quick Start
|
6
|
+
|
7
|
+
Get up and running with Balda.js in minutes. This guide will walk you through creating a simple REST API.
|
8
|
+
|
9
|
+
## Create Your First Server
|
10
|
+
|
11
|
+
Create a new file called `server.ts`:
|
12
|
+
|
13
|
+
```typescript
|
14
|
+
import { Server, controller, get, post } from 'balda-js';
|
15
|
+
|
16
|
+
// Create a new server instance
|
17
|
+
const server = new Server({
|
18
|
+
port: 3000,
|
19
|
+
host: 'localhost',
|
20
|
+
plugins: {
|
21
|
+
cors: { origin: '*' },
|
22
|
+
json: { sizeLimit: '1mb' }
|
23
|
+
}
|
24
|
+
});
|
25
|
+
|
26
|
+
// Define a controller
|
27
|
+
@controller('/users')
|
28
|
+
export class UsersController {
|
29
|
+
private users = [
|
30
|
+
{ id: 1, name: 'John Doe', email: 'john@example.com' },
|
31
|
+
{ id: 2, name: 'Jane Smith', email: 'jane@example.com' }
|
32
|
+
];
|
33
|
+
|
34
|
+
@get('/')
|
35
|
+
async getAllUsers(req, res) {
|
36
|
+
res.json(this.users);
|
37
|
+
}
|
38
|
+
|
39
|
+
@get('/:id')
|
40
|
+
async getUserById(req, res) {
|
41
|
+
const id = parseInt(req.params.id);
|
42
|
+
const user = this.users.find(u => u.id === id);
|
43
|
+
|
44
|
+
if (!user) {
|
45
|
+
return res.notFound({ error: 'User not found' });
|
46
|
+
}
|
47
|
+
|
48
|
+
res.json(user);
|
49
|
+
}
|
50
|
+
|
51
|
+
@post('/')
|
52
|
+
async createUser(req, res) {
|
53
|
+
const newUser = {
|
54
|
+
id: this.users.length + 1,
|
55
|
+
...req.body
|
56
|
+
};
|
57
|
+
|
58
|
+
this.users.push(newUser);
|
59
|
+
res.created(newUser);
|
60
|
+
}
|
61
|
+
}
|
62
|
+
|
63
|
+
// Start the server
|
64
|
+
server.listen(({ port, host }) => {
|
65
|
+
console.log(`Server running on http://${host}:${port}`);
|
66
|
+
});
|
67
|
+
```
|
68
|
+
|
69
|
+
## Run Your Server
|
70
|
+
|
71
|
+
```bash
|
72
|
+
# Node.js
|
73
|
+
npx tsx server.ts
|
74
|
+
|
75
|
+
# Bun
|
76
|
+
bun run server.ts
|
77
|
+
|
78
|
+
# Deno
|
79
|
+
deno run --allow-net server.ts
|
80
|
+
```
|
81
|
+
|
82
|
+
## Test Your API
|
83
|
+
|
84
|
+
Use curl or any HTTP client to test your endpoints:
|
85
|
+
|
86
|
+
```bash
|
87
|
+
# Get all users
|
88
|
+
curl http://localhost:3000/users
|
89
|
+
|
90
|
+
# Get user by ID
|
91
|
+
curl http://localhost:3000/users/1
|
92
|
+
|
93
|
+
# Create a new user
|
94
|
+
curl -X POST http://localhost:3000/users \
|
95
|
+
-H "Content-Type: application/json" \
|
96
|
+
-d '{"name": "Bob Wilson", "email": "bob@example.com"}'
|
97
|
+
```
|
98
|
+
|
99
|
+
## Add Validation
|
100
|
+
|
101
|
+
Enhance your API with request validation:
|
102
|
+
|
103
|
+
```typescript
|
104
|
+
import { Server, controller, get, post, validate } from 'balda-js';
|
105
|
+
import { Type, Static } from '@sinclair/typebox';
|
106
|
+
|
107
|
+
const CreateUserSchema = Type.Object({
|
108
|
+
name: Type.String({ minLength: 1 }),
|
109
|
+
email: Type.String({ format: 'email' })
|
110
|
+
});
|
111
|
+
|
112
|
+
@controller('/users')
|
113
|
+
export class UsersController {
|
114
|
+
// ... existing code ...
|
115
|
+
|
116
|
+
@post('/')
|
117
|
+
@validate.body(CreateUserSchema)
|
118
|
+
async createUser(req: Request, res: Response, body: Static<CreateUserSchema>) {
|
119
|
+
const newUser = {
|
120
|
+
id: this.users.length + 1,
|
121
|
+
...body
|
122
|
+
};
|
123
|
+
|
124
|
+
this.users.push(newUser);
|
125
|
+
res.created(newUser);
|
126
|
+
}
|
127
|
+
}
|
128
|
+
```
|
129
|
+
|
130
|
+
## Add Response Serialization
|
131
|
+
|
132
|
+
Define response schemas for better API documentation:
|
133
|
+
|
134
|
+
```typescript
|
135
|
+
import { serialize } from 'balda-js';
|
136
|
+
|
137
|
+
const UserSchema = Type.Object({
|
138
|
+
id: Type.Number(),
|
139
|
+
name: Type.String(),
|
140
|
+
email: Type.String()
|
141
|
+
});
|
142
|
+
|
143
|
+
@controller('/users')
|
144
|
+
export class UsersController {
|
145
|
+
@get('/')
|
146
|
+
@serialize(Type.Array(UserSchema))
|
147
|
+
async getAllUsers(req, res) {
|
148
|
+
res.json(this.users);
|
149
|
+
}
|
150
|
+
|
151
|
+
@get('/:id')
|
152
|
+
@serialize(UserSchema)
|
153
|
+
async getUserById(req, res) {
|
154
|
+
// ... existing code ...
|
155
|
+
}
|
156
|
+
}
|
157
|
+
```
|
158
|
+
|
159
|
+
## Add Middleware
|
160
|
+
|
161
|
+
Use middleware for cross-cutting concerns:
|
162
|
+
|
163
|
+
```typescript
|
164
|
+
import { middleware, Request, Response } from 'balda-js';
|
165
|
+
|
166
|
+
// Custom middleware
|
167
|
+
const logger = (req: Request, res: Response, next: () => void) => {
|
168
|
+
console.log(`${req.method} ${req.url} - ${new Date().toISOString()}`);
|
169
|
+
await next();
|
170
|
+
console.log(`${res} ${req.url} - ${new Date().toISOString()}`);
|
171
|
+
};
|
172
|
+
|
173
|
+
@controller('/users')
|
174
|
+
@middleware(logger)
|
175
|
+
export class UsersController {
|
176
|
+
// All routes in this controller will use the logger middleware
|
177
|
+
}
|
178
|
+
```
|
179
|
+
|
180
|
+
## Complete Example
|
181
|
+
|
182
|
+
Here's a complete example with all the features:
|
183
|
+
|
184
|
+
```typescript
|
185
|
+
import {
|
186
|
+
Server,
|
187
|
+
controller,
|
188
|
+
get,
|
189
|
+
post,
|
190
|
+
validate,
|
191
|
+
serialize,
|
192
|
+
middleware
|
193
|
+
} from 'balda-js';
|
194
|
+
import { Type } from '@sinclair/typebox';
|
195
|
+
|
196
|
+
const server = new Server({
|
197
|
+
port: 3000,
|
198
|
+
plugins: {
|
199
|
+
cors: { origin: '*' },
|
200
|
+
json: { sizeLimit: '1mb' },
|
201
|
+
log: { logResponse: true }
|
202
|
+
}
|
203
|
+
});
|
204
|
+
|
205
|
+
const UserSchema = Type.Object({
|
206
|
+
id: Type.Number(),
|
207
|
+
name: Type.String(),
|
208
|
+
email: Type.String()
|
209
|
+
});
|
210
|
+
|
211
|
+
const CreateUserSchema = Type.Object({
|
212
|
+
name: Type.String({ minLength: 1 }),
|
213
|
+
email: Type.String({ format: 'email' })
|
214
|
+
});
|
215
|
+
|
216
|
+
const logger = (req, res, next) => {
|
217
|
+
console.log(`${req.method} ${req.url}`);
|
218
|
+
next();
|
219
|
+
};
|
220
|
+
|
221
|
+
@controller('/users')
|
222
|
+
@middleware(logger)
|
223
|
+
export class UsersController {
|
224
|
+
private users = [
|
225
|
+
{ id: 1, name: 'John Doe', email: 'john@example.com' },
|
226
|
+
{ id: 2, name: 'Jane Smith', email: 'jane@example.com' }
|
227
|
+
];
|
228
|
+
|
229
|
+
@get('/')
|
230
|
+
@serialize(Type.Array(UserSchema))
|
231
|
+
async getAllUsers(req, res) {
|
232
|
+
res.json(this.users);
|
233
|
+
}
|
234
|
+
|
235
|
+
@get('/:id')
|
236
|
+
@serialize(UserSchema)
|
237
|
+
async getUserById(req, res) {
|
238
|
+
const id = parseInt(req.params.id);
|
239
|
+
const user = this.users.find(u => u.id === id);
|
240
|
+
|
241
|
+
if (!user) {
|
242
|
+
return res.notFound({ error: 'User not found' });
|
243
|
+
}
|
244
|
+
|
245
|
+
res.json(user);
|
246
|
+
}
|
247
|
+
|
248
|
+
@post('/')
|
249
|
+
@validate.body(CreateUserSchema)
|
250
|
+
@serialize(UserSchema)
|
251
|
+
async createUser(req, res, body) {
|
252
|
+
const newUser = {
|
253
|
+
id: this.users.length + 1,
|
254
|
+
...body
|
255
|
+
};
|
256
|
+
|
257
|
+
this.users.push(newUser);
|
258
|
+
res.created(newUser);
|
259
|
+
}
|
260
|
+
}
|
261
|
+
|
262
|
+
server.listen(({ port, host }) => {
|
263
|
+
console.log(`🚀 Server running on http://${host}:${port}`);
|
264
|
+
console.log(`📚 API Documentation: http://${host}:${port}/docs`);
|
265
|
+
});
|
266
|
+
```
|
267
|
+
|
268
|
+
## What's Next?
|
269
|
+
|
270
|
+
- Learn about [Core Concepts](../core-concepts/server) to understand how Balda.js works
|
271
|
+
- Explore [Plugins](../plugins/overview) to add more functionality
|
272
|
+
- Check out [Examples](../examples/rest-api) for more complex use cases
|
273
|
+
- Read the [Server API reference](../core-concepts/server) for detailed documentation
|
@@ -0,0 +1,46 @@
|
|
1
|
+
---
|
2
|
+
id: intro
|
3
|
+
title: Balda.js at a Glance
|
4
|
+
sidebar_position: 0
|
5
|
+
slug: /
|
6
|
+
---
|
7
|
+
|
8
|
+
# Balda.js
|
9
|
+
|
10
|
+
Balda.js is a runtime-agnostic backend framework that lets you write once and run anywhere—**Node.js**, **Bun**, and **Deno**—without changing a single line of code. Its minimal core and decorator-based API make building fast, type-safe HTTP services straightforward and clean.
|
11
|
+
|
12
|
+
## Key Ideas
|
13
|
+
|
14
|
+
- **Cross-Runtime**: One codebase, three runtimes. Choose the engine that best suits your deployment without vendor lock-in. It uses web apis that are available in all the runtimes and underling uses the specific `Deno` (Deno.serve), `Bun`(Bun.serve) or `Node.js`(http.createServer) APIs.
|
15
|
+
- **Performance First**: Tight, low-overhead abstractions keep the request/response path lean.
|
16
|
+
- **TypeScript-Native**: Written in TypeScript from the ground up for rich typings and editor autocompletion.
|
17
|
+
- **Batteries Included**: Controllers, middleware, validation, serialization, cron jobs, CLI, and a plugin ecosystem supplied out of the box.
|
18
|
+
- **Elegant API**: Decorators for routes and middleware promote self-documenting code and clean project structure.
|
19
|
+
- **Swagger/OpenAPI**: Built-in support for Swagger/OpenAPI documentation that merges with your codebase since validators and serializers directly generate the OpenAPI schema without any additional effort.
|
20
|
+
- **Validation**: Balda uses `ajv` for body and query strings validations under the hood, schemas can be built with `@sinclair/typebox` that provides a zod-like apis.
|
21
|
+
|
22
|
+
## Tiny Example
|
23
|
+
|
24
|
+
```typescript
|
25
|
+
import { Server, get, controller, Request, Response } from 'balda-js';
|
26
|
+
|
27
|
+
const server = new Server({ port: 3000 });
|
28
|
+
|
29
|
+
@controller()
|
30
|
+
class WelcomeController {
|
31
|
+
@get('/')
|
32
|
+
async hello(_: Request, res: response) {
|
33
|
+
res.text('Hello, World!');
|
34
|
+
}
|
35
|
+
}
|
36
|
+
|
37
|
+
server.listen();
|
38
|
+
```
|
39
|
+
|
40
|
+
## Learn More
|
41
|
+
|
42
|
+
- Start with the two-minute [Quick Start](./getting-started/quick-start)
|
43
|
+
- Understand the [Server lifecycle](./core-concepts/server)
|
44
|
+
- Explore [Plugins](./plugins/overview) to add CORS, logging, rate-limiting, and more
|
45
|
+
|
46
|
+
Balda.js—**simple**, **fast**, and **everywhere**.
|