@carno.js/core 1.0.2 → 1.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/LICENSE +21 -674
- package/README.md +188 -188
- package/dist/Carno.js +466 -269
- package/dist/bun/index.js +6 -19
- package/dist/bun/index.js.map +27 -28
- package/package.json +3 -2
- package/src/Carno.ts +605 -605
- package/src/DefaultRoutes.ts +34 -34
- package/src/cache/CacheDriver.ts +50 -50
- package/src/cache/CacheService.ts +139 -139
- package/src/cache/MemoryDriver.ts +104 -104
- package/src/cache/RedisDriver.ts +116 -116
- package/src/compiler/JITCompiler.ts +167 -167
- package/src/container/Container.ts +168 -168
- package/src/context/Context.ts +128 -128
- package/src/cors/CorsHandler.ts +145 -145
- package/src/decorators/Controller.ts +63 -63
- package/src/decorators/Inject.ts +16 -16
- package/src/decorators/Middleware.ts +22 -22
- package/src/decorators/Service.ts +18 -18
- package/src/decorators/methods.ts +58 -58
- package/src/decorators/params.ts +47 -47
- package/src/events/Lifecycle.ts +97 -97
- package/src/exceptions/HttpException.ts +99 -99
- package/src/index.ts +92 -92
- package/src/metadata.ts +46 -46
- package/src/middleware/CarnoMiddleware.ts +14 -14
- package/src/router/RadixRouter.ts +225 -225
- package/src/testing/TestHarness.ts +177 -177
- package/src/utils/Metadata.ts +43 -43
- package/src/validation/ValibotAdapter.ts +95 -95
- package/src/validation/ValidatorAdapter.ts +69 -69
- package/src/validation/ZodAdapter.ts +102 -102
package/README.md
CHANGED
|
@@ -1,188 +1,188 @@
|
|
|
1
|
-
# @carno.js/core
|
|
2
|
-
|
|
3
|
-
Ultra-fast, performance-first HTTP framework for Bun.
|
|
4
|
-
|
|
5
|
-
## Installation
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
bun add @carno.js/core
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
## Prerequisites
|
|
12
|
-
|
|
13
|
-
Enable decorators in your `tsconfig.json`:
|
|
14
|
-
|
|
15
|
-
```json
|
|
16
|
-
{
|
|
17
|
-
"compilerOptions": {
|
|
18
|
-
"experimentalDecorators": true,
|
|
19
|
-
"emitDecoratorMetadata": true
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
## Quick Start
|
|
25
|
-
|
|
26
|
-
```typescript
|
|
27
|
-
import { Carno, Controller, Get, Service, Param } from '@carno.js/core';
|
|
28
|
-
|
|
29
|
-
@Service()
|
|
30
|
-
class GreetService {
|
|
31
|
-
greet(name: string) {
|
|
32
|
-
return `Hello, ${name}!`;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
@Controller('/greet')
|
|
37
|
-
class GreetController {
|
|
38
|
-
constructor(private greetService: GreetService) {}
|
|
39
|
-
|
|
40
|
-
@Get('/:name')
|
|
41
|
-
greet(@Param('name') name: string) {
|
|
42
|
-
return { message: this.greetService.greet(name) };
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const app = new Carno();
|
|
47
|
-
app.services([GreetService]);
|
|
48
|
-
app.controllers([GreetController]);
|
|
49
|
-
app.listen(3000);
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
## API Overview
|
|
53
|
-
|
|
54
|
-
### Application
|
|
55
|
-
|
|
56
|
-
```typescript
|
|
57
|
-
const app = new Carno(config?: CarnoConfig);
|
|
58
|
-
|
|
59
|
-
app.controllers([...]); // Register controllers
|
|
60
|
-
app.services([...]); // Register services
|
|
61
|
-
app.middlewares([...]); // Register global middlewares
|
|
62
|
-
app.use(plugin); // Use a plugin/module
|
|
63
|
-
await app.listen(3000); // Start server
|
|
64
|
-
await app.stop(); // Stop server
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
### Decorators
|
|
68
|
-
|
|
69
|
-
#### Controllers & Routes
|
|
70
|
-
|
|
71
|
-
| Decorator | Description |
|
|
72
|
-
| :--- | :--- |
|
|
73
|
-
| `@Controller(path?)` | Define a controller with optional base path |
|
|
74
|
-
| `@Get(path?)` | Handle GET requests |
|
|
75
|
-
| `@Post(path?)` | Handle POST requests |
|
|
76
|
-
| `@Put(path?)` | Handle PUT requests |
|
|
77
|
-
| `@Delete(path?)` | Handle DELETE requests |
|
|
78
|
-
| `@Patch(path?)` | Handle PATCH requests |
|
|
79
|
-
|
|
80
|
-
#### Parameters
|
|
81
|
-
|
|
82
|
-
| Decorator | Description |
|
|
83
|
-
| :--- | :--- |
|
|
84
|
-
| `@Param(key?)` | Route parameters |
|
|
85
|
-
| `@Query(key?)` | Query string parameters |
|
|
86
|
-
| `@Body(key?)` | Request body |
|
|
87
|
-
| `@Header(key?)` | Request headers |
|
|
88
|
-
| `@Req()` | Raw Request object |
|
|
89
|
-
| `@Ctx()` | Full Context object |
|
|
90
|
-
|
|
91
|
-
#### Dependency Injection
|
|
92
|
-
|
|
93
|
-
| Decorator | Description |
|
|
94
|
-
| :--- | :--- |
|
|
95
|
-
| `@Service(options?)` | Mark class as injectable service |
|
|
96
|
-
| `@Inject(token)` | Inject by token (for interfaces) |
|
|
97
|
-
|
|
98
|
-
#### Middleware
|
|
99
|
-
|
|
100
|
-
| Decorator | Description |
|
|
101
|
-
| :--- | :--- |
|
|
102
|
-
| `@
|
|
103
|
-
|
|
104
|
-
#### Lifecycle
|
|
105
|
-
|
|
106
|
-
| Decorator | Description |
|
|
107
|
-
| :--- | :--- |
|
|
108
|
-
| `@OnApplicationInit()` | Called after DI container is ready |
|
|
109
|
-
| `@OnApplicationBoot()` | Called when server starts listening |
|
|
110
|
-
| `@OnApplicationShutdown()` | Called when server is stopping |
|
|
111
|
-
|
|
112
|
-
### Validation
|
|
113
|
-
|
|
114
|
-
```typescript
|
|
115
|
-
import { z } from 'zod';
|
|
116
|
-
import { Schema, ZodAdapter } from '@carno.js/core';
|
|
117
|
-
|
|
118
|
-
@Schema(z.object({
|
|
119
|
-
name: z.string().min(2),
|
|
120
|
-
email: z.string().email(),
|
|
121
|
-
}))
|
|
122
|
-
class CreateUserDto {
|
|
123
|
-
name!: string;
|
|
124
|
-
email!: string;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
const app = new Carno({ validation: new ZodAdapter() });
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
### CORS
|
|
131
|
-
|
|
132
|
-
```typescript
|
|
133
|
-
const app = new Carno({
|
|
134
|
-
cors: {
|
|
135
|
-
origins: '*', // or specific origin(s)
|
|
136
|
-
methods: ['GET', 'POST'],
|
|
137
|
-
headers: ['Content-Type'],
|
|
138
|
-
credentials: true,
|
|
139
|
-
maxAge: 86400,
|
|
140
|
-
}
|
|
141
|
-
});
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
### Exceptions
|
|
145
|
-
|
|
146
|
-
```typescript
|
|
147
|
-
import {
|
|
148
|
-
BadRequestException,
|
|
149
|
-
UnauthorizedException,
|
|
150
|
-
ForbiddenException,
|
|
151
|
-
NotFoundException,
|
|
152
|
-
ConflictException,
|
|
153
|
-
InternalServerErrorException,
|
|
154
|
-
} from '@carno.js/core';
|
|
155
|
-
|
|
156
|
-
throw new NotFoundException('User not found');
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
### Testing
|
|
160
|
-
|
|
161
|
-
```typescript
|
|
162
|
-
import { withTestApp } from '@carno.js/core';
|
|
163
|
-
|
|
164
|
-
await withTestApp(
|
|
165
|
-
async (harness) => {
|
|
166
|
-
const res = await harness.get('/users');
|
|
167
|
-
expect(res.status).toBe(200);
|
|
168
|
-
},
|
|
169
|
-
{ controllers: [UserController], listen: true }
|
|
170
|
-
);
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
## Configuration
|
|
174
|
-
|
|
175
|
-
```typescript
|
|
176
|
-
interface CarnoConfig {
|
|
177
|
-
exports?: (Token | ProviderConfig)[];
|
|
178
|
-
globalMiddlewares?: MiddlewareHandler[];
|
|
179
|
-
disableStartupLog?: boolean;
|
|
180
|
-
cors?: CorsConfig;
|
|
181
|
-
validation?: ValidatorAdapter | boolean;
|
|
182
|
-
cache?: CacheConfig | boolean;
|
|
183
|
-
}
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
## License
|
|
187
|
-
|
|
188
|
-
MIT
|
|
1
|
+
# @carno.js/core
|
|
2
|
+
|
|
3
|
+
Ultra-fast, performance-first HTTP framework for Bun.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
bun add @carno.js/core
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Prerequisites
|
|
12
|
+
|
|
13
|
+
Enable decorators in your `tsconfig.json`:
|
|
14
|
+
|
|
15
|
+
```json
|
|
16
|
+
{
|
|
17
|
+
"compilerOptions": {
|
|
18
|
+
"experimentalDecorators": true,
|
|
19
|
+
"emitDecoratorMetadata": true
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Quick Start
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
import { Carno, Controller, Get, Service, Param } from '@carno.js/core';
|
|
28
|
+
|
|
29
|
+
@Service()
|
|
30
|
+
class GreetService {
|
|
31
|
+
greet(name: string) {
|
|
32
|
+
return `Hello, ${name}!`;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
@Controller('/greet')
|
|
37
|
+
class GreetController {
|
|
38
|
+
constructor(private greetService: GreetService) {}
|
|
39
|
+
|
|
40
|
+
@Get('/:name')
|
|
41
|
+
greet(@Param('name') name: string) {
|
|
42
|
+
return { message: this.greetService.greet(name) };
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const app = new Carno();
|
|
47
|
+
app.services([GreetService]);
|
|
48
|
+
app.controllers([GreetController]);
|
|
49
|
+
app.listen(3000);
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## API Overview
|
|
53
|
+
|
|
54
|
+
### Application
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
const app = new Carno(config?: CarnoConfig);
|
|
58
|
+
|
|
59
|
+
app.controllers([...]); // Register controllers
|
|
60
|
+
app.services([...]); // Register services
|
|
61
|
+
app.middlewares([...]); // Register global middlewares
|
|
62
|
+
app.use(plugin); // Use a plugin/module
|
|
63
|
+
await app.listen(3000); // Start server
|
|
64
|
+
await app.stop(); // Stop server
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Decorators
|
|
68
|
+
|
|
69
|
+
#### Controllers & Routes
|
|
70
|
+
|
|
71
|
+
| Decorator | Description |
|
|
72
|
+
| :--- | :--- |
|
|
73
|
+
| `@Controller(path?)` | Define a controller with optional base path |
|
|
74
|
+
| `@Get(path?)` | Handle GET requests |
|
|
75
|
+
| `@Post(path?)` | Handle POST requests |
|
|
76
|
+
| `@Put(path?)` | Handle PUT requests |
|
|
77
|
+
| `@Delete(path?)` | Handle DELETE requests |
|
|
78
|
+
| `@Patch(path?)` | Handle PATCH requests |
|
|
79
|
+
|
|
80
|
+
#### Parameters
|
|
81
|
+
|
|
82
|
+
| Decorator | Description |
|
|
83
|
+
| :--- | :--- |
|
|
84
|
+
| `@Param(key?)` | Route parameters |
|
|
85
|
+
| `@Query(key?)` | Query string parameters |
|
|
86
|
+
| `@Body(key?)` | Request body |
|
|
87
|
+
| `@Header(key?)` | Request headers |
|
|
88
|
+
| `@Req()` | Raw Request object |
|
|
89
|
+
| `@Ctx()` | Full Context object |
|
|
90
|
+
|
|
91
|
+
#### Dependency Injection
|
|
92
|
+
|
|
93
|
+
| Decorator | Description |
|
|
94
|
+
| :--- | :--- |
|
|
95
|
+
| `@Service(options?)` | Mark class as injectable service |
|
|
96
|
+
| `@Inject(token)` | Inject by token (for interfaces) |
|
|
97
|
+
|
|
98
|
+
#### Middleware
|
|
99
|
+
|
|
100
|
+
| Decorator | Description |
|
|
101
|
+
| :--- | :--- |
|
|
102
|
+
| `@Middleware(middleware)` | Apply middleware to controller/route |
|
|
103
|
+
|
|
104
|
+
#### Lifecycle
|
|
105
|
+
|
|
106
|
+
| Decorator | Description |
|
|
107
|
+
| :--- | :--- |
|
|
108
|
+
| `@OnApplicationInit()` | Called after DI container is ready |
|
|
109
|
+
| `@OnApplicationBoot()` | Called when server starts listening |
|
|
110
|
+
| `@OnApplicationShutdown()` | Called when server is stopping |
|
|
111
|
+
|
|
112
|
+
### Validation
|
|
113
|
+
|
|
114
|
+
```typescript
|
|
115
|
+
import { z } from 'zod';
|
|
116
|
+
import { Schema, ZodAdapter } from '@carno.js/core';
|
|
117
|
+
|
|
118
|
+
@Schema(z.object({
|
|
119
|
+
name: z.string().min(2),
|
|
120
|
+
email: z.string().email(),
|
|
121
|
+
}))
|
|
122
|
+
class CreateUserDto {
|
|
123
|
+
name!: string;
|
|
124
|
+
email!: string;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const app = new Carno({ validation: new ZodAdapter() });
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### CORS
|
|
131
|
+
|
|
132
|
+
```typescript
|
|
133
|
+
const app = new Carno({
|
|
134
|
+
cors: {
|
|
135
|
+
origins: '*', // or specific origin(s)
|
|
136
|
+
methods: ['GET', 'POST'],
|
|
137
|
+
headers: ['Content-Type'],
|
|
138
|
+
credentials: true,
|
|
139
|
+
maxAge: 86400,
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Exceptions
|
|
145
|
+
|
|
146
|
+
```typescript
|
|
147
|
+
import {
|
|
148
|
+
BadRequestException,
|
|
149
|
+
UnauthorizedException,
|
|
150
|
+
ForbiddenException,
|
|
151
|
+
NotFoundException,
|
|
152
|
+
ConflictException,
|
|
153
|
+
InternalServerErrorException,
|
|
154
|
+
} from '@carno.js/core';
|
|
155
|
+
|
|
156
|
+
throw new NotFoundException('User not found');
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Testing
|
|
160
|
+
|
|
161
|
+
```typescript
|
|
162
|
+
import { withTestApp } from '@carno.js/core';
|
|
163
|
+
|
|
164
|
+
await withTestApp(
|
|
165
|
+
async (harness) => {
|
|
166
|
+
const res = await harness.get('/users');
|
|
167
|
+
expect(res.status).toBe(200);
|
|
168
|
+
},
|
|
169
|
+
{ controllers: [UserController], listen: true }
|
|
170
|
+
);
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## Configuration
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
interface CarnoConfig {
|
|
177
|
+
exports?: (Token | ProviderConfig)[];
|
|
178
|
+
globalMiddlewares?: MiddlewareHandler[];
|
|
179
|
+
disableStartupLog?: boolean;
|
|
180
|
+
cors?: CorsConfig;
|
|
181
|
+
validation?: ValidatorAdapter | boolean;
|
|
182
|
+
cache?: CacheConfig | boolean;
|
|
183
|
+
}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## License
|
|
187
|
+
|
|
188
|
+
MIT
|