@avleon/core 0.0.32 → 0.0.36

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
@@ -48,6 +48,7 @@ Avleon is a powerful, TypeScript-based web framework built on top of Fastify, de
48
48
  - [mapPost](#mappost)
49
49
  - [mapPut](#mapput)
50
50
  - [mapDelete](#mapdelete)
51
+ - [Testing](#testing)
51
52
 
52
53
  ## Features
53
54
 
@@ -77,7 +78,7 @@ pnpm add @avleon/core
77
78
 
78
79
  ## Quick Start
79
80
 
80
- ### Route Based
81
+ ### Minimal
81
82
 
82
83
  ```typescript
83
84
  import { Avleon, ApiController, Get, Results } from "@avleon/core";
@@ -430,6 +431,27 @@ app.useDataSource(DataSourceConfig);
430
431
  // ... other impments
431
432
  ```
432
433
 
434
+ Now in your Controller or Injected service use can use like this
435
+
436
+ ```typescript
437
+ import { AppService, InjectRepository } from "@avleon/core";
438
+ import { Repository } from "typeorm";
439
+ import { User } from "model_path";
440
+
441
+ @AppService
442
+ export class UserService {
443
+ constructor(
444
+ @InjectRepository(User)
445
+ private readonly _userRepository: Repository<User>,
446
+ ) {}
447
+
448
+ async findAll() {
449
+ const users = await this._userRepository.find();
450
+ return users;
451
+ }
452
+ }
453
+ ```
454
+
433
455
  ### File Uploads
434
456
 
435
457
  Handle file uploads with multipart support:
@@ -445,7 +467,7 @@ app.useMultipart({
445
467
 
446
468
  // In your controller
447
469
  @Post('/upload')
448
- async uploadFile(@File() file: any) {
470
+ async uploadFile(@MultipartFile() file: any) {
449
471
  // Process uploaded file
450
472
  return HttpResponse.Ok({ filename: file.filename });
451
473
  }
@@ -462,46 +484,9 @@ app.useStaticFiles({
462
484
  });
463
485
  ```
464
486
 
465
- ### Testing
466
-
467
- Test your API endpoints with the built-in testing utilities:
468
-
469
- ```typescript
470
- import { TestBuilder } from "@avleon/core";
471
-
472
- const testBuilder = TestBuilder.createBuilder();
473
- const app = testBuilder.getTestApplication({
474
- controllers: [UserController],
475
- });
476
-
477
- // Test your API endpoints
478
- const response = await app.get("/users");
479
- expect(response.statusCode).toBe(200);
480
- ```
481
-
482
487
  ## Configuration
483
488
 
484
- Configure your application with environment variables:
485
-
486
- ```typescript
487
- // .env
488
- PORT=3000
489
- DATABASE_URL=postgres://user:password@localhost:5432/db
490
-
491
- // app.ts
492
- import { Environment } from '@avleon/core';
493
-
494
- const env = new Environment();
495
- env.load();
496
-
497
- const app = new Avleon({
498
- controllers: [UserController],
499
- env: {
500
- port: 'PORT',
501
- databaseUrl: 'DATABASE_URL',
502
- },
503
- });
504
- ```
489
+ Coming soon...
505
490
 
506
491
  ## Route Mapping
507
492
 
@@ -558,6 +543,8 @@ app.mapDelete("/users/:id", async (req, res) => {
558
543
  });
559
544
  ```
560
545
 
546
+ ### Add openapi and middleware support for inline route
547
+
561
548
  Each of these methods returns a route object that can be used to add middleware or Swagger documentation to the route.
562
549
 
563
550
  ```typescript
@@ -592,6 +579,12 @@ app
592
579
  });
593
580
  ```
594
581
 
582
+ ### Testing
583
+
584
+ Test your API endpoints with the built-in testing utilities:
585
+
586
+ Coming soon...
587
+
595
588
  ## License
596
589
 
597
590
  ISC
@@ -223,7 +223,6 @@ function InjectRepository(model) {
223
223
  });
224
224
  }
225
225
  catch (error) {
226
- console.log(error);
227
226
  if (error.name && error.name == "ServiceNotFoundError") {
228
227
  console.log("Database didn't initialized.");
229
228
  }
package/dist/icore.js CHANGED
@@ -308,7 +308,6 @@ class AvleonApplication {
308
308
  method: methodmetaOptions.method.toUpperCase(),
309
309
  schema: { ...schema },
310
310
  handler: async (req, res) => {
311
- var _a;
312
311
  let reqClone = req;
313
312
  // class level authrization
314
313
  if (authClsMeata.authorize && this.authorizeMiddleware) {
@@ -368,18 +367,44 @@ class AvleonApplication {
368
367
  }
369
368
  }
370
369
  const result = await prototype[method].apply(ctrl, args);
371
- if (result instanceof stream_1.default || (result === null || result === void 0 ? void 0 : result.pipe)) {
372
- if (!res.sent && ((_a = result.options) === null || _a === void 0 ? void 0 : _a.downloadName)) {
373
- res.header('Content-Type', 'application/octet-stream');
374
- res.header('Content-Disposition', `attachment; filename="${result.options.downloadName}"`);
370
+ // Custom wrapped file download
371
+ if (result === null || result === void 0 ? void 0 : result.__isFileDownload) {
372
+ const { stream, filename, contentType = "application/octet-stream", } = result;
373
+ if (!stream || typeof stream.pipe !== "function") {
374
+ return res.code(500).send({
375
+ code: 500,
376
+ error: "INTERNAL_ERROR",
377
+ message: "Invalid stream object",
378
+ });
375
379
  }
376
- return result.pipe(res.raw);
380
+ res.header("Content-Type", contentType);
381
+ res.header("Content-Disposition", `attachment; filename="${filename}"`);
382
+ stream.on("error", (err) => {
383
+ console.error("Stream error:", err);
384
+ if (!res.sent) {
385
+ res.code(500).send({
386
+ code: 500,
387
+ error: "StreamError",
388
+ message: "Error while streaming file.",
389
+ });
390
+ }
391
+ });
392
+ return res.send(stream);
377
393
  }
378
- if (result && result.__isFileDownload) {
379
- const { stream, filename, contentType = 'application/octet-stream' } = result;
380
- res.header('Content-Type', contentType);
381
- res.header('Content-Disposition', `attachment; filename="${filename}"`);
382
- return stream.pipe(res.raw);
394
+ // Native stream (not wrapped)
395
+ if (result instanceof stream_1.default || typeof (result === null || result === void 0 ? void 0 : result.pipe) === "function") {
396
+ result.on("error", (err) => {
397
+ console.error("Stream error:", err);
398
+ if (!res.sent) {
399
+ res.code(500).send({
400
+ code: 500,
401
+ error: "StreamError",
402
+ message: "Error while streaming file.",
403
+ });
404
+ }
405
+ });
406
+ res.header("Content-Type", "application/octet-stream");
407
+ return res.send(result);
383
408
  }
384
409
  return res.send(result);
385
410
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@avleon/core",
3
- "version": "0.0.32",
3
+ "version": "0.0.36",
4
4
  "main": "./dist/index.js",
5
5
  "types": "./dist/index.d.ts",
6
6
  "scripts": {
@@ -12,7 +12,7 @@
12
12
  "format": "prettier --write .",
13
13
  "test": "jest",
14
14
  "test:watch": "jest --watch",
15
- "prepare": "husky install"
15
+ "husky:init": "husky install"
16
16
  },
17
17
  "keywords": [
18
18
  "restapi",