bootifyjs 0.1.0 → 0.1.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.
Files changed (2) hide show
  1. package/README.md +326 -76
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -2,6 +2,16 @@
2
2
 
3
3
  A Spring Boot inspired Node.js framework with TypeScript, Dependency Injection, and Validation.
4
4
 
5
+ ## Features
6
+
7
+ - **Dependency Injection**: Automatic constructor injection with `@Injectable`, `@Service`, and `@Repository` decorators
8
+ - **REST API**: Easy controller definition with `@Controller`, `@Get`, `@Post`, etc.
9
+ - **Validation**: Request validation with Zod schemas
10
+ - **Configuration**: Environment-based configuration with automatic mapping
11
+ - **OpenAPI**: Automatic OpenAPI documentation generation
12
+ - **Logging**: Comprehensive logging system with context tracking
13
+ - **Event System**: Type-safe event system with middleware support
14
+
5
15
  ## Installation
6
16
 
7
17
  ```bash
@@ -44,130 +54,370 @@ async function main() {
44
54
  main().catch(console.error);
45
55
  ```
46
56
 
47
- ## Simple Configuration Management
57
+ ## Core Concepts
58
+
59
+ ### Controllers
60
+
61
+ Controllers handle HTTP requests and define your API endpoints.
48
62
 
49
- The framework provides a very simple configuration management system that automatically maps environment variables to nested configuration properties.
63
+ ```typescript
64
+ import { Controller, Get, Post, Put, Delete, Param, Body, Query } from 'bootifyjs';
50
65
 
51
- ### How It Works
66
+ @Controller('/users')
67
+ export class UserController {
68
+ constructor(private userService: UserService) {}
69
+
70
+ @Get('/')
71
+ getAllUsers(@Query('limit') limit?: string) {
72
+ return this.userService.getAllUsers(limit ? parseInt(limit) : undefined);
73
+ }
74
+
75
+ @Get('/:id')
76
+ getUserById(@Param('id') id: string) {
77
+ return this.userService.getUserById(id);
78
+ }
79
+
80
+ @Post('/')
81
+ createUser(@Body() userData: CreateUserDto) {
82
+ return this.userService.createUser(userData);
83
+ }
84
+
85
+ @Put('/:id')
86
+ updateUser(@Param('id') id: string, @Body() userData: UpdateUserDto) {
87
+ return this.userService.updateUser(id, userData);
88
+ }
89
+
90
+ @Delete('/:id')
91
+ deleteUser(@Param('id') id: string) {
92
+ return this.userService.deleteUser(id);
93
+ }
94
+ }
95
+ ```
52
96
 
53
- 1. **Single Configuration Class**: Define one `AppConfig` class with your configuration structure
54
- 2. **Automatic Mapping**: Environment variables with `BOOTIFY_` prefix are automatically mapped to nested properties
55
- 3. **Type Conversion**: Values are automatically converted to numbers and booleans when possible
97
+ ### Services
56
98
 
57
- ### Usage
99
+ Services contain your business logic and can be injected into controllers or other services.
58
100
 
59
- **1. Define Your Configuration Structure:**
60
101
  ```typescript
61
- import { Config } from '../core/config';
102
+ import { Service } from 'bootifyjs';
62
103
 
63
- @Config('BOOTIFY')
104
+ @Service()
105
+ export class UserService {
106
+ constructor(private userRepository: UserRepository) {}
107
+
108
+ getAllUsers(limit?: number) {
109
+ return this.userRepository.findAll(limit);
110
+ }
111
+
112
+ getUserById(id: string) {
113
+ return this.userRepository.findById(id);
114
+ }
115
+
116
+ // More methods...
117
+ }
118
+ ```
119
+
120
+ ### Repositories
121
+
122
+ Repositories handle data access and can be injected into services.
123
+
124
+ ```typescript
125
+ import { Repository } from 'bootifyjs';
126
+
127
+ @Repository()
128
+ export class UserRepository {
129
+ private users = []; // In a real app, this would be a database connection
130
+
131
+ findAll(limit?: number) {
132
+ if (limit) {
133
+ return this.users.slice(0, limit);
134
+ }
135
+ return this.users;
136
+ }
137
+
138
+ findById(id: string) {
139
+ return this.users.find(user => user.id === id);
140
+ }
141
+
142
+ // More methods...
143
+ }
144
+ ```
145
+
146
+ ### Validation
147
+
148
+ Use Zod schemas to validate request data.
149
+
150
+ ```typescript
151
+ import { z } from 'zod';
152
+ import { Controller, Post, Body, ValidateBody } from 'bootifyjs';
153
+
154
+ const createUserSchema = z.object({
155
+ email: z.string().email(),
156
+ name: z.string().min(2).max(100),
157
+ age: z.number().min(18).optional()
158
+ });
159
+
160
+ @Controller('/users')
161
+ export class UserController {
162
+ @Post('/')
163
+ @ValidateBody(createUserSchema)
164
+ createUser(@Body() userData: z.infer<typeof createUserSchema>) {
165
+ // userData is now validated and typed
166
+ return this.userService.createUser(userData);
167
+ }
168
+ }
169
+ ```
170
+
171
+ ### Configuration
172
+
173
+ Define your configuration structure and automatically map environment variables.
174
+
175
+ ```typescript
176
+ import { Config, getConfigInstance } from 'bootifyjs';
177
+
178
+ @Config('APP')
64
179
  export class AppConfig {
65
- SERVICE_NAME: string = 'bootifyjs-app';
180
+ SERVICE_NAME: string = 'my-service';
66
181
 
67
182
  server: {
68
183
  port: number;
69
184
  host: string;
70
- name?: string;
71
185
  } = {
72
186
  port: 3000,
73
187
  host: 'localhost'
74
188
  };
75
189
 
76
190
  database: {
77
- host: string;
78
- port: number;
79
- name: string;
191
+ url: string;
192
+ poolSize: number;
80
193
  } = {
81
- host: 'localhost',
82
- port: 5432,
83
- name: 'myapp'
194
+ url: 'postgres://localhost:5432/mydb',
195
+ poolSize: 10
84
196
  };
85
197
  }
198
+
199
+ // Environment variables like APP_SERVER_PORT=8080 will be automatically mapped
200
+ const config = getConfigInstance(AppConfig);
201
+ console.log(config.server.port); // 8080
86
202
  ```
87
203
 
88
- **2. Set Environment Variables:**
89
- ```bash
90
- # Maps to appConfig.SERVICE_NAME
91
- BOOTIFY_SERVICE_NAME=my-awesome-app
204
+ ### Event System
92
205
 
93
- # Maps to appConfig.server.port
94
- BOOTIFY_SERVER_PORT=8080
206
+ Create a type-safe event system for decoupled communication.
95
207
 
96
- # Maps to appConfig.server.host
97
- BOOTIFY_SERVER_HOST=0.0.0.0
208
+ ```typescript
209
+ import { Event, EventEmitter, EventListener, EventHandler } from 'bootifyjs';
210
+
211
+ // Define an event
212
+ @Event('user.created')
213
+ class UserCreatedEvent {
214
+ id: string;
215
+ email: string;
216
+ timestamp: Date = new Date();
217
+ }
98
218
 
99
- # Maps to appConfig.server.name
100
- BOOTIFY_SERVER_NAME=my-server
219
+ // Emit events from services
220
+ @Service()
221
+ @EventEmitter()
222
+ class UserService {
223
+ private eventBus; // Injected by @EventEmitter
224
+
225
+ async createUser(userData) {
226
+ const user = await this.userRepository.create(userData);
227
+
228
+ // Emit event
229
+ await this.eventBus.emit('user.created', {
230
+ id: user.id,
231
+ email: user.email
232
+ });
233
+
234
+ return user;
235
+ }
236
+ }
237
+
238
+ // Handle events
239
+ @EventListener()
240
+ class UserEventHandlers {
241
+ @EventHandler('user.created')
242
+ async onUserCreated(event: UserCreatedEvent) {
243
+ console.log(`User created: ${event.email}`);
244
+ // Send welcome email, update analytics, etc.
245
+ }
246
+ }
247
+ ```
101
248
 
102
- # Maps to appConfig.database.host
103
- BOOTIFY_DATABASE_HOST=postgres-server
249
+ ### Logging
104
250
 
105
- # Maps to appConfig.database.port
106
- BOOTIFY_DATABASE_PORT=5432
251
+ Comprehensive logging system with context tracking.
252
+
253
+ ```typescript
254
+ import { Logger, Log } from 'bootifyjs';
255
+
256
+ @Service()
257
+ @Logger('UserService')
258
+ export class UserService {
259
+ private logger; // Injected by @Logger
260
+
261
+ @Log({ logArgs: true, logDuration: true })
262
+ async createUser(userData) {
263
+ this.logger.info('Creating new user', { email: userData.email });
264
+
265
+ // Business logic...
266
+
267
+ this.logger.info('User created successfully');
268
+ return user;
269
+ }
270
+ }
107
271
  ```
108
272
 
109
- **3. Access Configuration:**
273
+ ## Bootstrapping Your Application
274
+
275
+ There are two ways to bootstrap your application:
276
+
277
+ ### 1. Using createBootifyApp (Recommended)
278
+
110
279
  ```typescript
111
- import { getConfigInstance } from './core/config';
112
- import { AppConfig } from './config/app.config';
280
+ import { createBootifyApp } from 'bootifyjs';
281
+ import { UserController } from './controllers/user.controller';
113
282
 
114
- const appConfig = getConfigInstance(AppConfig);
283
+ async function main() {
284
+ const { app, start, stop } = await createBootifyApp({
285
+ port: 3000,
286
+ controllers: [UserController],
287
+ enableSwagger: true,
288
+ enableCors: true
289
+ });
290
+
291
+ await start();
292
+ console.log('Server running at http://localhost:3000');
293
+ console.log('API docs available at http://localhost:3000/api-docs');
294
+ }
115
295
 
116
- console.log(appConfig.SERVICE_NAME); // 'my-awesome-app'
117
- console.log(appConfig.server.port); // 8080
118
- console.log(appConfig.server.host); // '0.0.0.0'
119
- console.log(appConfig.database.host); // 'postgres-server'
296
+ main().catch(console.error);
120
297
  ```
121
298
 
122
- **4. Inject into Services:**
123
- ```typescript
124
- import { InjectConfig } from './core/decorators';
299
+ ### 2. Manual Bootstrap
125
300
 
126
- @Service()
127
- export class MyService {
128
- constructor(@InjectConfig(AppConfig) private config: AppConfig) {}
301
+ ```typescript
302
+ import {
303
+ Application,
304
+ configureLogging,
305
+ configureEventSystem,
306
+ corsMiddleware,
307
+ contextMiddleware,
308
+ createRequestLoggingMiddleware,
309
+ swaggerMiddleware,
310
+ OpenAPIGenerator
311
+ } from 'bootifyjs';
312
+ import { UserController } from './controllers/user.controller';
313
+
314
+ async function bootstrap() {
315
+ // Initialize logging
316
+ const { logger, startupLogger } = configureLogging();
129
317
 
130
- doSomething() {
131
- console.log(`Service: ${this.config.SERVICE_NAME}`);
132
- console.log(`Running on port: ${this.config.server.port}`);
133
- }
318
+ // Initialize event system
319
+ const eventBus = configureEventSystem();
320
+
321
+ // Generate OpenAPI documentation
322
+ const openApiGenerator = new OpenAPIGenerator({
323
+ title: 'My API',
324
+ version: '1.0.0',
325
+ description: 'My API description'
326
+ });
327
+
328
+ const controllers = [UserController];
329
+ openApiGenerator.addControllers(controllers);
330
+ const openApiSpec = openApiGenerator.getSpec();
331
+
332
+ // Create application
333
+ const app = new Application({
334
+ controllers,
335
+ middlewares: [
336
+ contextMiddleware,
337
+ corsMiddleware,
338
+ createRequestLoggingMiddleware(),
339
+ swaggerMiddleware(openApiSpec)
340
+ ],
341
+ port: 3000,
342
+ hostname: 'localhost'
343
+ });
344
+
345
+ await app.start();
346
+ logger.info('Server started');
134
347
  }
348
+
349
+ bootstrap().catch(console.error);
135
350
  ```
136
351
 
137
- ### Environment Variable Mapping Rules
352
+ ## Middleware
138
353
 
139
- The system automatically converts environment variable names to nested property paths:
354
+ Create custom middleware to handle cross-cutting concerns.
140
355
 
141
- - `BOOTIFY_SERVICE_NAME` → `appConfig.SERVICE_NAME`
142
- - `BOOTIFY_SERVER_PORT` `appConfig.server.port`
143
- - `BOOTIFY_SERVER_HOST` → `appConfig.server.host`
144
- - `BOOTIFY_DATABASE_HOST` → `appConfig.database.host`
145
- - `BOOTIFY_DATABASE_PORT` → `appConfig.database.port`
356
+ ```typescript
357
+ import { Middleware } from 'bootifyjs';
146
358
 
147
- ### Automatic Type Conversion
359
+ export const loggingMiddleware: Middleware = async (req, res, next) => {
360
+ const start = Date.now();
361
+ console.log(`${req.method} ${req.url} - Request started`);
362
+
363
+ await next();
364
+
365
+ const duration = Date.now() - start;
366
+ console.log(`${req.method} ${req.url} - Request completed in ${duration}ms`);
367
+ };
368
+ ```
148
369
 
149
- - **Numbers**: `"8080"` → `8080`
150
- - **Booleans**: `"true"` → `true`, `"false"` → `false`
151
- - **Strings**: Everything else remains as string
370
+ ## OpenAPI Documentation
152
371
 
153
- ### Getting Started
372
+ BootifyJS automatically generates OpenAPI documentation for your API.
154
373
 
155
- 1. Copy `example.env` to `.env` and modify values
156
- 2. Set your environment variables following the `BOOTIFY_*` pattern
157
- 3. Access your configuration using `getConfigInstance(AppConfig)`
374
+ ```typescript
375
+ import { Controller, Get, ApiTags, ApiOperation, ApiResponse } from 'bootifyjs';
376
+
377
+ @Controller('/health')
378
+ @ApiTags('Health')
379
+ export class HealthController {
380
+ @Get('/')
381
+ @ApiOperation({
382
+ summary: 'Health check',
383
+ description: 'Check if the API is running'
384
+ })
385
+ @ApiResponse(200, {
386
+ description: 'API is healthy',
387
+ schema: healthResponseSchema
388
+ })
389
+ health() {
390
+ return { status: 'OK', timestamp: new Date().toISOString() };
391
+ }
392
+ }
393
+ ```
158
394
 
159
- That's it! No complex setup, no manual property mapping - just define your structure and set your environment variables.
395
+ ## Error Handling
160
396
 
161
- ## Features
397
+ BootifyJS provides built-in error classes for common HTTP errors.
162
398
 
163
- - **Dependency Injection**: Automatic constructor injection with `@Injectable`, `@Service`, and `@Repository` decorators
164
- - **REST API**: Easy controller definition with `@Controller`, `@Get`, `@Post`, etc.
165
- - **Validation**: Request validation with Zod schemas
166
- - **Configuration**: Environment-based configuration with automatic mapping
167
- - **OpenAPI**: Automatic OpenAPI documentation generation
168
- - **Logging**: Comprehensive logging system with context tracking
169
- - **Event System**: Type-safe event system with middleware support
399
+ ```typescript
400
+ import { NotFoundError, ValidationError } from 'bootifyjs';
401
+
402
+ @Service()
403
+ export class UserService {
404
+ getUserById(id: string) {
405
+ const user = this.userRepository.findById(id);
406
+ if (!user) {
407
+ throw new NotFoundError(`User with id ${id} not found`);
408
+ }
409
+ return user;
410
+ }
411
+
412
+ createUser(userData) {
413
+ if (!userData.email) {
414
+ throw new ValidationError('Email is required');
415
+ }
416
+ // ...
417
+ }
418
+ }
419
+ ```
170
420
 
171
- ## Documentation
421
+ ## License
172
422
 
173
- For more detailed documentation, please visit our [GitHub repository](https://github.com/bootifyjs/bootifyjs).
423
+ MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bootifyjs",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Spring Boot inspired Node.js framework with custom DI",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",