@razvan11/paladin 1.1.3 → 1.1.5

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/README.md CHANGED
@@ -1,15 +1,219 @@
1
- # backend_framwork
1
+ # @razvan11/paladin
2
2
 
3
- To install dependencies:
3
+ A modern, decorator-based backend framework for Bun with dependency injection, controller registration, and WebSocket support.
4
+
5
+ ## Features
6
+
7
+ - **Decorator-based routing** - Clean, expressive route definitions
8
+ - **Dependency Injection** - Powered by Inversify
9
+ - **Built for Bun** - Leverages Bun's performance
10
+ - **WebSocket support** - First-class WebSocket handling
11
+ - **React SSR** - Server-side rendering utilities
12
+ - **Middleware support** - Per-route middleware functions
13
+ - **Static file serving** - Built-in asset handling
14
+
15
+ ## Installation
4
16
 
5
17
  ```bash
6
- bun install
18
+ bun add @razvan11/paladin
7
19
  ```
8
20
 
9
- To run:
21
+ ## Quick Start
10
22
 
11
- ```bash
12
- bun run index.ts
23
+ ```typescript
24
+ import { App, controller, get, post, service, inject } from '@razvan11/paladin';
25
+
26
+ @service()
27
+ class UserService {
28
+ getUsers() {
29
+ return [{ id: 1, name: 'John' }];
30
+ }
31
+ }
32
+
33
+ @controller('/users')
34
+ class UserController {
35
+ constructor(@inject(UserService) private userService: UserService) {}
36
+
37
+ @get('/')
38
+ async list(c: Context) {
39
+ return c.json(this.userService.getUsers());
40
+ }
41
+
42
+ @post('/')
43
+ async create(c: Context) {
44
+ const body = await c.req.json();
45
+ return c.json({ created: body });
46
+ }
47
+ }
48
+
49
+ const app = new App({ name: 'MyApp' });
50
+ app.registerController(UserController);
51
+ app.run();
13
52
  ```
14
53
 
15
- This project was created using `bun init` in bun v1.3.5. [Bun](https://bun.com) is a fast all-in-one JavaScript runtime.
54
+ ## Decorators
55
+
56
+ ### Controller Decorators
57
+
58
+ | Decorator | Description |
59
+ |-----------|-------------|
60
+ | `@controller(prefix)` | Marks a class as a controller with a route prefix |
61
+ | `@get(path, ...middlewares)` | Handles GET requests |
62
+ | `@post(path, ...middlewares)` | Handles POST requests |
63
+ | `@put(path, ...middlewares)` | Handles PUT requests |
64
+ | `@patch(path, ...middlewares)` | Handles PATCH requests |
65
+ | `@del(path, ...middlewares)` | Handles DELETE requests |
66
+ | `@options(path, ...middlewares)` | Handles OPTIONS requests |
67
+ | `@all(path, ...middlewares)` | Handles all HTTP methods |
68
+
69
+ ### Service Decorators
70
+
71
+ | Decorator | Description |
72
+ |-----------|-------------|
73
+ | `@service()` | Marks a class as a service (singleton) |
74
+ | `@repository()` | Marks a class as a repository (singleton) |
75
+ | `@database(options)` | Marks a class as a database connection |
76
+
77
+ ### WebSocket Decorators
78
+
79
+ | Decorator | Description |
80
+ |-----------|-------------|
81
+ | `@websocket(path)` | Marks a class as a WebSocket handler |
82
+ | `@onMessage()` | Handles incoming messages |
83
+ | `@onOpen()` | Handles connection open |
84
+ | `@onClose()` | Handles connection close |
85
+ | `@onDrain()` | Handles backpressure drain |
86
+
87
+ ## Dependency Injection
88
+
89
+ Use the `@inject()` decorator to inject dependencies into your controllers and services:
90
+
91
+ ```typescript
92
+ @controller('/api')
93
+ class ApiController {
94
+ constructor(
95
+ @inject(UserService) private userService: UserService,
96
+ @inject(AuthService) private authService: AuthService,
97
+ ) {}
98
+ }
99
+ ```
100
+
101
+ ## Middleware
102
+
103
+ Add middleware to individual routes:
104
+
105
+ ```typescript
106
+ const authMiddleware = async (c: Context, next: Next) => {
107
+ const token = c.req.header('Authorization');
108
+ if (!token) return c.json({ error: 'Unauthorized' }, 401);
109
+ await next();
110
+ };
111
+
112
+ @controller('/protected')
113
+ class ProtectedController {
114
+ @get('/', authMiddleware)
115
+ async secure(c: Context) {
116
+ return c.json({ message: 'Secret data' });
117
+ }
118
+ }
119
+ ```
120
+
121
+ ## WebSockets
122
+
123
+ ```typescript
124
+ import { websocket, onMessage, onOpen, onClose } from '@razvan11/paladin';
125
+
126
+ @websocket('/chat')
127
+ class ChatHandler {
128
+ @onOpen()
129
+ handleOpen(ws: ServerWebSocket) {
130
+ console.log('Client connected');
131
+ }
132
+
133
+ @onMessage()
134
+ handleMessage(ws: ServerWebSocket, message: string | Buffer) {
135
+ ws.send(`Echo: ${message}`);
136
+ }
137
+
138
+ @onClose()
139
+ handleClose(ws: ServerWebSocket) {
140
+ console.log('Client disconnected');
141
+ }
142
+ }
143
+
144
+ const app = new App({ name: 'ChatApp' });
145
+ app.registerWebSocket(ChatHandler);
146
+ app.run();
147
+ ```
148
+
149
+ ## Static Files
150
+
151
+ ```typescript
152
+ const app = new App({ name: 'MyApp' });
153
+
154
+ app.serveStatic({
155
+ path: '/static',
156
+ root: './public'
157
+ });
158
+ ```
159
+
160
+ Use the `asset()` helper to generate URLs:
161
+
162
+ ```typescript
163
+ import { asset } from '@razvan11/paladin';
164
+
165
+ asset('dist', 'app.js'); // Returns '/static/dist/app.js'
166
+ ```
167
+
168
+ ## React SSR
169
+
170
+ Render React components on the server:
171
+
172
+ ```typescript
173
+ import { render, LayoutView } from '@razvan11/paladin';
174
+
175
+ @controller('/')
176
+ class IndexController {
177
+ @get('/')
178
+ index(c: Context) {
179
+ return render(c, LayoutView, {
180
+ title: 'My App',
181
+ scripts: [asset('dist', 'app.js')],
182
+ styles: [asset('dist', 'app.css')],
183
+ children: <div id="root" />,
184
+ });
185
+ }
186
+ }
187
+ ```
188
+
189
+ ## Configuration
190
+
191
+ ```typescript
192
+ const app = new App({
193
+ name: 'MyApp',
194
+ cors: ['https://example.com'], // CORS origins (default: ['*'])
195
+ validators: myValidators, // Optional validators
196
+ });
197
+ ```
198
+
199
+ Environment variables:
200
+ - `PORT` - Server port (default: 3000)
201
+ - `APP_ENV` - Environment mode (`local`, `development`, `staging`, `production`)
202
+
203
+ ## API Reference
204
+
205
+ ### App
206
+
207
+ | Method | Description |
208
+ |--------|-------------|
209
+ | `registerController(Controller)` | Register a controller class |
210
+ | `registerControllers(...Controllers)` | Register multiple controllers |
211
+ | `registerWebSocket(WSHandler)` | Register a WebSocket handler |
212
+ | `registerWebSockets(...WSHandlers)` | Register multiple WebSocket handlers |
213
+ | `serveStatic(options)` | Serve static files |
214
+ | `getAppInstance()` | Get the underlying Hono instance |
215
+ | `run()` | Start the server |
216
+
217
+ ## License
218
+
219
+ MIT © Razvan
package/dist/app/app.d.ts CHANGED
@@ -19,7 +19,6 @@ export declare class App {
19
19
  private cors;
20
20
  private logger;
21
21
  private wsHandlers;
22
- private server;
23
22
  constructor(options: AppConfigOptions);
24
23
  init(): void;
25
24
  /**
@@ -7,7 +7,7 @@ export interface RouteDefinition {
7
7
  handlerName: string | symbol;
8
8
  middlewares: MiddlewareHandler[];
9
9
  }
10
- export type MiddlewareHandler = (c: Context, next: Next) => Promise<Response | void> | Response | void;
10
+ export type MiddlewareHandler = (c: Context, next: Next) => Promise<Response> | Promise<void> | Response | void;
11
11
  /**
12
12
  * @controller decorator
13
13
  * Marks a class as a controller and registers it with the DI container
@@ -18,10 +18,6 @@ export declare function render<P extends object>(c: Context, Component: FC<P>, p
18
18
  * @returns HTML response
19
19
  */
20
20
  export declare function renderElement(c: Context, element: ReactElement): Response;
21
- /**
22
- * Create a render function bound to a context
23
- * Useful for cleaner controller code
24
- */
25
21
  export declare function createRenderer(c: Context): {
26
22
  render: <P extends object>(Component: FC<P>, props?: P) => Response;
27
23
  renderElement: (element: ReactElement) => Response;
package/dist/index.js CHANGED
@@ -19887,7 +19887,6 @@ class App {
19887
19887
  cors;
19888
19888
  logger;
19889
19889
  wsHandlers = new Map;
19890
- server = null;
19891
19890
  constructor(options2) {
19892
19891
  this.app = new Hono2;
19893
19892
  this.name = options2.name;
@@ -19925,8 +19924,6 @@ class App {
19925
19924
  } else {
19926
19925
  app[route.method](fullPath, handler);
19927
19926
  }
19928
- if (Bun.env.APP_ENV === "local")
19929
- this.logger.info(` ${route.method.toUpperCase().padEnd(7)} ${fullPath}`);
19930
19927
  }
19931
19928
  return this;
19932
19929
  }
@@ -19976,9 +19973,9 @@ class App {
19976
19973
  });
19977
19974
  try {
19978
19975
  const server = Bun.serve({
19979
- port: 3000,
19980
- hostname: "localhost",
19981
- development: false,
19976
+ port: Bun.env.PORT ? parseInt(Bun.env.PORT, 10) : 3000,
19977
+ hostname: "0.0.0.0",
19978
+ development: Bun.env.APP_ENV === "local",
19982
19979
  fetch(req, server2) {
19983
19980
  const url = new URL(req.url);
19984
19981
  if (wsPaths.has(url.pathname)) {
@@ -20015,7 +20012,6 @@ class App {
20015
20012
  }
20016
20013
  }
20017
20014
  });
20018
- this.server = server;
20019
20015
  this.logger.success(`Server started on port ${server.port}`);
20020
20016
  return server;
20021
20017
  } catch (error) {
@@ -20076,7 +20072,7 @@ function getDataSourceForCLI(DatabaseClass, url) {
20076
20072
  const source = instance.getSource();
20077
20073
  if (options2?.migrations) {
20078
20074
  source.setOptions({
20079
- migrations: [options2.migrations + "/*.ts"],
20075
+ migrations: [`${options2.migrations}/*.ts`],
20080
20076
  migrationsTableName: options2.migrationsTable || "migrations"
20081
20077
  });
20082
20078
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@razvan11/paladin",
3
- "version": "1.1.3",
3
+ "version": "1.1.5",
4
4
  "description": "A Bun-based backend framework with decorators, dependency injection, and controller registration",
5
5
  "keywords": [
6
6
  "bun",
@@ -64,4 +64,5 @@
64
64
  "reflect-metadata": "^0.2.2",
65
65
  "zod": "^4.2.1"
66
66
  }
67
- }
67
+ }
68
+