@avleon/core 0.0.31 → 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 +33 -40
- package/dist/collection.js +0 -1
- package/dist/config.d.ts +2 -2
- package/dist/config.js +5 -5
- package/dist/config.test.js +1 -1
- package/dist/event-dispatcher.d.ts +4 -4
- package/dist/event-dispatcher.js +2 -3
- package/dist/event-subscriber.d.ts +3 -4
- package/dist/event-subscriber.js +8 -17
- package/dist/icore.d.ts +8 -8
- package/dist/icore.js +48 -10
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -3
- package/dist/middleware.d.ts +4 -4
- package/dist/middleware.js +7 -7
- package/package.json +10 -2
- package/dist/websocket.test.d.ts +0 -0
- package/dist/websocket.test.js +0 -1
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
|
-
###
|
|
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(@
|
|
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
|
-
|
|
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
|
package/dist/collection.js
CHANGED
package/dist/config.d.ts
CHANGED
|
@@ -9,8 +9,8 @@ import { Environment } from "./environment-variables";
|
|
|
9
9
|
export interface IConfig<T = any> {
|
|
10
10
|
config(env: Environment): T;
|
|
11
11
|
}
|
|
12
|
-
export declare function
|
|
13
|
-
export declare class
|
|
12
|
+
export declare function AppConfig<T extends IConfig>(target: Constructable<T>): void;
|
|
13
|
+
export declare class AvleonConfig {
|
|
14
14
|
get<T extends IConfig<R>, R>(configClass: Constructable<T>): R;
|
|
15
15
|
}
|
|
16
16
|
export declare function GetConfig<T extends IConfig<R>, R = ReturnType<InstanceType<Constructable<T>>["config"]>>(ConfigClass: Constructable<T>): R;
|
package/dist/config.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
exports.
|
|
3
|
+
exports.AvleonConfig = void 0;
|
|
4
|
+
exports.AppConfig = AppConfig;
|
|
5
5
|
exports.GetConfig = GetConfig;
|
|
6
6
|
exports.CreateConfig = CreateConfig;
|
|
7
7
|
/**
|
|
@@ -13,10 +13,10 @@ exports.CreateConfig = CreateConfig;
|
|
|
13
13
|
const typedi_1 = require("typedi");
|
|
14
14
|
const environment_variables_1 = require("./environment-variables");
|
|
15
15
|
const helpers_1 = require("./helpers");
|
|
16
|
-
function
|
|
16
|
+
function AppConfig(target) {
|
|
17
17
|
typedi_1.Container.set({ id: target, type: target });
|
|
18
18
|
}
|
|
19
|
-
class
|
|
19
|
+
class AvleonConfig {
|
|
20
20
|
get(configClass) {
|
|
21
21
|
const instance = typedi_1.Container.get(configClass);
|
|
22
22
|
if (!instance) {
|
|
@@ -25,7 +25,7 @@ class AppConfig {
|
|
|
25
25
|
return instance.config(new environment_variables_1.Environment());
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
|
-
exports.
|
|
28
|
+
exports.AvleonConfig = AvleonConfig;
|
|
29
29
|
// Implementation
|
|
30
30
|
function GetConfig(token) {
|
|
31
31
|
// 1. Class‐based: token.prototype.config is a function
|
package/dist/config.test.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Socket } from
|
|
1
|
+
import { Socket } from "socket.io";
|
|
2
2
|
export declare class SocketContextService {
|
|
3
3
|
private readonly storage;
|
|
4
4
|
run(socket: Socket, fn: () => void | Promise<void>): void;
|
|
@@ -7,7 +7,7 @@ export declare class SocketContextService {
|
|
|
7
7
|
export type DispatchOptions = {
|
|
8
8
|
room?: string;
|
|
9
9
|
broadcast?: boolean;
|
|
10
|
-
transports?: (
|
|
10
|
+
transports?: ("socket" | "kafka" | "rabbitmq")[];
|
|
11
11
|
retry?: number;
|
|
12
12
|
retryDelay?: number;
|
|
13
13
|
};
|
|
@@ -18,6 +18,6 @@ export declare class EventDispatcher {
|
|
|
18
18
|
dispatch<T = any>(event: string, data: T, options?: DispatchOptions): Promise<void>;
|
|
19
19
|
private dispatchToTransports;
|
|
20
20
|
}
|
|
21
|
-
export declare function Dispatch(event: string, options?: Omit<DispatchOptions,
|
|
22
|
-
transports?: DispatchOptions[
|
|
21
|
+
export declare function Dispatch(event: string, options?: Omit<DispatchOptions, "transports"> & {
|
|
22
|
+
transports?: DispatchOptions["transports"];
|
|
23
23
|
}): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void;
|
package/dist/event-dispatcher.js
CHANGED
|
@@ -14,7 +14,6 @@ exports.sleep = sleep;
|
|
|
14
14
|
exports.Dispatch = Dispatch;
|
|
15
15
|
const typedi_1 = require("typedi");
|
|
16
16
|
const socket_io_1 = require("socket.io");
|
|
17
|
-
// SocketContextService.ts
|
|
18
17
|
const node_async_hooks_1 = require("node:async_hooks");
|
|
19
18
|
let SocketContextService = class SocketContextService {
|
|
20
19
|
constructor() {
|
|
@@ -57,9 +56,9 @@ let EventDispatcher = class EventDispatcher {
|
|
|
57
56
|
}
|
|
58
57
|
async dispatchToTransports(event, data, options) {
|
|
59
58
|
var _a;
|
|
60
|
-
const transports = (_a = options.transports) !== null && _a !== void 0 ? _a : [
|
|
59
|
+
const transports = (_a = options.transports) !== null && _a !== void 0 ? _a : ["socket"];
|
|
61
60
|
for (const transport of transports) {
|
|
62
|
-
if (transport ===
|
|
61
|
+
if (transport === "socket") {
|
|
63
62
|
const io = typedi_1.Container.get(socket_io_1.Server);
|
|
64
63
|
//console.log('SOckert', Container.get(SocketContextService));
|
|
65
64
|
const context = typedi_1.Container.get(SocketContextService);
|
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
import { Socket } from
|
|
2
|
-
import { SocketContextService } from
|
|
3
|
-
import
|
|
1
|
+
import { Socket } from "socket.io";
|
|
2
|
+
import { SocketContextService } from "./event-dispatcher";
|
|
3
|
+
import "reflect-metadata";
|
|
4
4
|
export declare function Private(channelResolver?: (socket: any) => string): (target: any, propertyKey: string) => void;
|
|
5
5
|
export declare function isPrivate(target: any, propertyKey: string): boolean;
|
|
6
6
|
export declare function getPrivateChannelResolver(target: any, propertyKey: string): ((socket: any) => string) | undefined;
|
|
7
7
|
export declare function registerSocketSubscriber(target: Function): void;
|
|
8
8
|
export declare function getSocketSubscribers(): Function[];
|
|
9
9
|
export declare function Subscribe(event: string): MethodDecorator;
|
|
10
|
-
export declare function PrivateSubscribe(resolver: (user: any, socket: any) => string): (target: any, propertyKey: string) => void;
|
|
11
10
|
export declare class EventSubscriberRegistry {
|
|
12
11
|
private readonly socketContext;
|
|
13
12
|
constructor(socketContext: SocketContextService);
|
package/dist/event-subscriber.js
CHANGED
|
@@ -16,11 +16,10 @@ exports.getPrivateChannelResolver = getPrivateChannelResolver;
|
|
|
16
16
|
exports.registerSocketSubscriber = registerSocketSubscriber;
|
|
17
17
|
exports.getSocketSubscribers = getSocketSubscribers;
|
|
18
18
|
exports.Subscribe = Subscribe;
|
|
19
|
-
exports.PrivateSubscribe = PrivateSubscribe;
|
|
20
19
|
const typedi_1 = require("typedi");
|
|
21
20
|
const event_dispatcher_1 = require("./event-dispatcher");
|
|
22
21
|
require("reflect-metadata");
|
|
23
|
-
const PRIVATE_META_KEY =
|
|
22
|
+
const PRIVATE_META_KEY = "avleon:private";
|
|
24
23
|
function Private(channelResolver) {
|
|
25
24
|
return function (target, propertyKey) {
|
|
26
25
|
Reflect.defineMetadata(PRIVATE_META_KEY, true, target, propertyKey);
|
|
@@ -40,20 +39,12 @@ function registerSocketSubscriber(target) {
|
|
|
40
39
|
function getSocketSubscribers() {
|
|
41
40
|
return Array.from(socketSubscriberClasses);
|
|
42
41
|
}
|
|
43
|
-
// decorators/Subscribe.ts
|
|
44
42
|
function Subscribe(event) {
|
|
45
43
|
return (target, propertyKey) => {
|
|
46
|
-
Reflect.defineMetadata(
|
|
44
|
+
Reflect.defineMetadata("socket:event", event, target, propertyKey);
|
|
47
45
|
registerSocketSubscriber(target.constructor);
|
|
48
46
|
};
|
|
49
47
|
}
|
|
50
|
-
// decorators/Private.ts
|
|
51
|
-
function PrivateSubscribe(resolver) {
|
|
52
|
-
return function (target, propertyKey) {
|
|
53
|
-
Reflect.defineMetadata('avleon:private', true, target, propertyKey);
|
|
54
|
-
Reflect.defineMetadata(`private:channel:${propertyKey}`, resolver, target);
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
48
|
let EventSubscriberRegistry = class EventSubscriberRegistry {
|
|
58
49
|
constructor(socketContext) {
|
|
59
50
|
this.socketContext = socketContext;
|
|
@@ -63,16 +54,16 @@ let EventSubscriberRegistry = class EventSubscriberRegistry {
|
|
|
63
54
|
for (const SubscriberClass of subscriberClasses) {
|
|
64
55
|
const instance = typedi_1.Container.get(SubscriberClass);
|
|
65
56
|
const prototype = Object.getPrototypeOf(instance);
|
|
66
|
-
const methodNames = Object.getOwnPropertyNames(prototype)
|
|
67
|
-
.filter(name => typeof prototype[name] === 'function');
|
|
57
|
+
const methodNames = Object.getOwnPropertyNames(prototype).filter((name) => typeof prototype[name] === "function");
|
|
68
58
|
for (const methodName of methodNames) {
|
|
69
|
-
const event = Reflect.getMetadata(
|
|
59
|
+
const event = Reflect.getMetadata("socket:event", prototype, methodName);
|
|
70
60
|
const isPrivateListener = isPrivate(instance, methodName);
|
|
71
61
|
const channelResolver = getPrivateChannelResolver(instance, methodName);
|
|
72
|
-
//const event = Reflect.getMetadata(`subscribe:event:${method}`, instance);
|
|
73
62
|
if (event) {
|
|
74
|
-
const channel = isPrivateListener && channelResolver
|
|
75
|
-
|
|
63
|
+
const channel = isPrivateListener && channelResolver
|
|
64
|
+
? channelResolver(socket)
|
|
65
|
+
: event;
|
|
66
|
+
console.log("Channel", channel);
|
|
76
67
|
socket.on(channel, (payload) => {
|
|
77
68
|
this.socketContext.run(socket, async () => {
|
|
78
69
|
if (isPrivateListener) {
|
package/dist/icore.d.ts
CHANGED
|
@@ -9,13 +9,13 @@ import { Constructable } from "typedi";
|
|
|
9
9
|
import { Constructor } from "./helpers";
|
|
10
10
|
import { PathLike } from "fs";
|
|
11
11
|
import { DataSource, DataSourceOptions } from "typeorm";
|
|
12
|
-
import {
|
|
12
|
+
import { AvleonMiddleware } from "./middleware";
|
|
13
13
|
import { OpenApiOptions, OpenApiUiOptions } from "./openapi";
|
|
14
14
|
import { IConfig } from "./config";
|
|
15
15
|
import { FastifyCorsOptions } from "@fastify/cors";
|
|
16
16
|
import { FastifyMultipartOptions } from "@fastify/multipart";
|
|
17
17
|
import { MultipartFile } from "./multipart";
|
|
18
|
-
import { ServerOptions } from
|
|
18
|
+
import { ServerOptions } from "socket.io";
|
|
19
19
|
export type FuncRoute = {
|
|
20
20
|
handler: any;
|
|
21
21
|
middlewares?: any[];
|
|
@@ -97,7 +97,7 @@ export interface IAvleonApplication {
|
|
|
97
97
|
useOpenApi<T extends IConfig<R>, R = ReturnType<InstanceType<Constructable<T>>["config"]>>(ConfigClass: Constructable<T>, modifyConfig?: (config: R) => R): void;
|
|
98
98
|
useMultipart(options: MultipartOptions): void;
|
|
99
99
|
useCache(options: any): void;
|
|
100
|
-
useMiddlewares<T extends
|
|
100
|
+
useMiddlewares<T extends AvleonMiddleware>(mclasses: Constructor<T>[]): void;
|
|
101
101
|
useAuthoriztion<T extends any>(middleware: Constructor<T>): void;
|
|
102
102
|
mapRoute<T extends (...args: any[]) => any>(method: "get" | "post" | "put" | "delete", path: string, fn: T): Promise<void>;
|
|
103
103
|
mapGet<T extends (...args: any[]) => any>(path: string, fn: T): any;
|
|
@@ -150,7 +150,7 @@ export declare class AvleonApplication {
|
|
|
150
150
|
useMultipart<T extends MultipartOptions>(options: ConfigInput<T>): void;
|
|
151
151
|
useDataSource<T extends DataSourceOptions>(options: ConfigInput<T>): void;
|
|
152
152
|
private _useCache;
|
|
153
|
-
useMiddlewares<T extends
|
|
153
|
+
useMiddlewares<T extends AvleonMiddleware>(mclasses: Constructor<T>[]): void;
|
|
154
154
|
useAuthoriztion<T extends any>(middleware: Constructor<T>): void;
|
|
155
155
|
useStaticFiles(options?: StaticFileOptions): void;
|
|
156
156
|
private handleMiddlewares;
|
|
@@ -184,19 +184,19 @@ export declare class AvleonApplication {
|
|
|
184
184
|
mapRoute<T extends (...args: any[]) => any>(method: "get" | "post" | "put" | "delete", path: string | undefined, fn: T): Promise<void>;
|
|
185
185
|
private _routeHandler;
|
|
186
186
|
mapGet<T extends (...args: any[]) => any>(path: string | undefined, fn: T): {
|
|
187
|
-
useMiddleware: <M extends
|
|
187
|
+
useMiddleware: <M extends AvleonMiddleware>(middlewares: Constructor<AvleonMiddleware>[]) => /*elided*/ any;
|
|
188
188
|
useOpenApi: (options: OpenApiOptions) => /*elided*/ any;
|
|
189
189
|
};
|
|
190
190
|
mapPost<T extends (...args: any[]) => any>(path: string | undefined, fn: T): {
|
|
191
|
-
useMiddleware: <M extends
|
|
191
|
+
useMiddleware: <M extends AvleonMiddleware>(middlewares: Constructor<AvleonMiddleware>[]) => /*elided*/ any;
|
|
192
192
|
useOpenApi: (options: OpenApiOptions) => /*elided*/ any;
|
|
193
193
|
};
|
|
194
194
|
mapPut<T extends (...args: any[]) => any>(path: string | undefined, fn: T): {
|
|
195
|
-
useMiddleware: <M extends
|
|
195
|
+
useMiddleware: <M extends AvleonMiddleware>(middlewares: Constructor<AvleonMiddleware>[]) => /*elided*/ any;
|
|
196
196
|
useOpenApi: (options: OpenApiOptions) => /*elided*/ any;
|
|
197
197
|
};
|
|
198
198
|
mapDelete<T extends (...args: any[]) => any>(path: string | undefined, fn: T): {
|
|
199
|
-
useMiddleware: <M extends
|
|
199
|
+
useMiddleware: <M extends AvleonMiddleware>(middlewares: Constructor<AvleonMiddleware>[]) => /*elided*/ any;
|
|
200
200
|
useOpenApi: (options: OpenApiOptions) => /*elided*/ any;
|
|
201
201
|
};
|
|
202
202
|
private _mapFeatures;
|
package/dist/icore.js
CHANGED
|
@@ -60,6 +60,7 @@ const validation_1 = require("./validation");
|
|
|
60
60
|
const utils_1 = require("./utils");
|
|
61
61
|
const socket_io_1 = require("socket.io");
|
|
62
62
|
const event_subscriber_1 = require("./event-subscriber");
|
|
63
|
+
const stream_1 = __importDefault(require("stream"));
|
|
63
64
|
const isTsNode = process.env.TS_NODE_DEV ||
|
|
64
65
|
process.env.TS_NODE_PROJECT ||
|
|
65
66
|
process[Symbol.for("ts-node.register.instance")];
|
|
@@ -85,7 +86,7 @@ class AvleonApplication {
|
|
|
85
86
|
this.registerControllerPath = "./src";
|
|
86
87
|
this.metaCache = new Map();
|
|
87
88
|
this.app = (0, fastify_1.default)();
|
|
88
|
-
this.appConfig = new config_1.
|
|
89
|
+
this.appConfig = new config_1.AvleonConfig();
|
|
89
90
|
}
|
|
90
91
|
static getApp() {
|
|
91
92
|
let isTestEnv = process.env.NODE_ENV == "test";
|
|
@@ -366,7 +367,46 @@ class AvleonApplication {
|
|
|
366
367
|
}
|
|
367
368
|
}
|
|
368
369
|
const result = await prototype[method].apply(ctrl, args);
|
|
369
|
-
|
|
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
|
+
});
|
|
379
|
+
}
|
|
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);
|
|
393
|
+
}
|
|
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);
|
|
408
|
+
}
|
|
409
|
+
return res.send(result);
|
|
370
410
|
},
|
|
371
411
|
});
|
|
372
412
|
}
|
|
@@ -545,16 +585,15 @@ class AvleonApplication {
|
|
|
545
585
|
};
|
|
546
586
|
}
|
|
547
587
|
async mapRoute(method, path = "", fn) {
|
|
548
|
-
await this.mapFn(fn);
|
|
588
|
+
await this.mapFn(fn);
|
|
549
589
|
this.app[method](path, async (req, res) => {
|
|
550
|
-
// Dynamic method call
|
|
551
590
|
try {
|
|
552
591
|
const result = await fn.apply(this, [req, res]);
|
|
553
592
|
if (typeof result === "object" && result !== null) {
|
|
554
|
-
res.json(result);
|
|
593
|
+
res.json(result);
|
|
555
594
|
}
|
|
556
595
|
else {
|
|
557
|
-
res.send(result);
|
|
596
|
+
res.send(result);
|
|
558
597
|
}
|
|
559
598
|
}
|
|
560
599
|
catch (error) {
|
|
@@ -571,7 +610,6 @@ class AvleonApplication {
|
|
|
571
610
|
middlewares: [],
|
|
572
611
|
schema: {},
|
|
573
612
|
});
|
|
574
|
-
// this.mapFn(fn);
|
|
575
613
|
const route = {
|
|
576
614
|
useMiddleware: (middlewares) => {
|
|
577
615
|
const midds = Array.isArray(middlewares) ? middlewares : [middlewares];
|
|
@@ -662,17 +700,17 @@ class AvleonApplication {
|
|
|
662
700
|
});
|
|
663
701
|
await this.app.ready();
|
|
664
702
|
if (this._hasWebsocket) {
|
|
665
|
-
await this.app.io.on(
|
|
703
|
+
await this.app.io.on("connection", this.handleSocket);
|
|
666
704
|
await this.app.io.use((socket, next) => {
|
|
667
705
|
const token = socket.handshake.auth.token;
|
|
668
706
|
try {
|
|
669
|
-
console.log(
|
|
707
|
+
console.log("token", token);
|
|
670
708
|
const user = { id: 1, name: "tareq" };
|
|
671
709
|
socket.data.user = user; // this powers @AuthUser()
|
|
672
710
|
next();
|
|
673
711
|
}
|
|
674
712
|
catch (_a) {
|
|
675
|
-
next(new Error(
|
|
713
|
+
next(new Error("Unauthorized"));
|
|
676
714
|
}
|
|
677
715
|
});
|
|
678
716
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -25,6 +25,6 @@ export * from "./multipart";
|
|
|
25
25
|
export * from "./file-storage";
|
|
26
26
|
export * from "./logger";
|
|
27
27
|
export * from "./event-dispatcher";
|
|
28
|
-
export { Subscribe, Private
|
|
28
|
+
export { Subscribe, Private } from "./event-subscriber";
|
|
29
29
|
export declare const GetSchema: typeof sw.generateSwaggerSchema;
|
|
30
|
-
export { default as
|
|
30
|
+
export { default as AvleonContainer } from "./container";
|
package/dist/index.js
CHANGED
|
@@ -39,7 +39,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
39
39
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
40
40
|
};
|
|
41
41
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
-
exports.
|
|
42
|
+
exports.AvleonContainer = exports.GetSchema = exports.Private = exports.Subscribe = exports.exclude = exports.pick = exports.validateRequestBody = exports.inject = void 0;
|
|
43
43
|
/**
|
|
44
44
|
* @copyright 2024
|
|
45
45
|
* @author Tareq Hossain
|
|
@@ -74,7 +74,6 @@ __exportStar(require("./event-dispatcher"), exports);
|
|
|
74
74
|
var event_subscriber_1 = require("./event-subscriber");
|
|
75
75
|
Object.defineProperty(exports, "Subscribe", { enumerable: true, get: function () { return event_subscriber_1.Subscribe; } });
|
|
76
76
|
Object.defineProperty(exports, "Private", { enumerable: true, get: function () { return event_subscriber_1.Private; } });
|
|
77
|
-
Object.defineProperty(exports, "PrivateSubscribe", { enumerable: true, get: function () { return event_subscriber_1.PrivateSubscribe; } });
|
|
78
77
|
exports.GetSchema = sw.generateSwaggerSchema;
|
|
79
78
|
var container_1 = require("./container");
|
|
80
|
-
Object.defineProperty(exports, "
|
|
79
|
+
Object.defineProperty(exports, "AvleonContainer", { enumerable: true, get: function () { return __importDefault(container_1).default; } });
|
package/dist/middleware.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { IRequest, IResponse } from "./icore";
|
|
2
2
|
import { HttpExceptionTypes as HttpException } from "./exceptions";
|
|
3
|
-
export declare abstract class
|
|
3
|
+
export declare abstract class AvleonMiddleware {
|
|
4
4
|
abstract invoke(req: IRequest, res?: IResponse): Promise<IRequest | HttpException>;
|
|
5
5
|
}
|
|
6
6
|
export type AuthHandler = (req: IRequest, roles?: string[]) => Promise<IRequest | HttpException>;
|
|
@@ -14,11 +14,11 @@ export type AuthReturnTypes = IRequest | Promise<IRequest>;
|
|
|
14
14
|
interface AuthorizeClass {
|
|
15
15
|
authorize(req: IRequest, options?: any): AuthReturnTypes;
|
|
16
16
|
}
|
|
17
|
-
export declare function
|
|
17
|
+
export declare function AppAuthorization(target: {
|
|
18
18
|
new (...args: any[]): AuthorizeClass;
|
|
19
19
|
}): void;
|
|
20
20
|
export declare function Authorized(): ClassDecorator & MethodDecorator;
|
|
21
21
|
export declare function Authorized(options?: any): ClassDecorator & MethodDecorator;
|
|
22
|
-
export declare function
|
|
23
|
-
export declare function UseMiddleware<T extends
|
|
22
|
+
export declare function AppMiddleware(target: Constructor<AvleonMiddleware>): void;
|
|
23
|
+
export declare function UseMiddleware<T extends AvleonMiddleware | (new (...args: any[]) => AvleonMiddleware)>(options: T | T[]): MethodDecorator & ClassDecorator;
|
|
24
24
|
export {};
|
package/dist/middleware.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.AuthorizeMiddleware = exports.
|
|
4
|
-
exports.
|
|
3
|
+
exports.AuthorizeMiddleware = exports.AvleonMiddleware = void 0;
|
|
4
|
+
exports.AppAuthorization = AppAuthorization;
|
|
5
5
|
exports.Authorized = Authorized;
|
|
6
|
-
exports.
|
|
6
|
+
exports.AppMiddleware = AppMiddleware;
|
|
7
7
|
exports.UseMiddleware = UseMiddleware;
|
|
8
8
|
/**
|
|
9
9
|
* @copyright 2024
|
|
@@ -13,13 +13,13 @@ exports.UseMiddleware = UseMiddleware;
|
|
|
13
13
|
*/
|
|
14
14
|
const typedi_1 = require("typedi");
|
|
15
15
|
const container_1 = require("./container");
|
|
16
|
-
class
|
|
16
|
+
class AvleonMiddleware {
|
|
17
17
|
}
|
|
18
|
-
exports.
|
|
18
|
+
exports.AvleonMiddleware = AvleonMiddleware;
|
|
19
19
|
class AuthorizeMiddleware {
|
|
20
20
|
}
|
|
21
21
|
exports.AuthorizeMiddleware = AuthorizeMiddleware;
|
|
22
|
-
function
|
|
22
|
+
function AppAuthorization(target) {
|
|
23
23
|
if (typeof target.prototype.authorize !== "function") {
|
|
24
24
|
throw new Error(`Class "${target.name}" must implement an "authorize" method.`);
|
|
25
25
|
}
|
|
@@ -35,7 +35,7 @@ function Authorized(options = {}) {
|
|
|
35
35
|
}
|
|
36
36
|
};
|
|
37
37
|
}
|
|
38
|
-
function
|
|
38
|
+
function AppMiddleware(target) {
|
|
39
39
|
if (typeof target.prototype.invoke !== "function") {
|
|
40
40
|
throw new Error(`Class "${target.name}" must implement an "invoke" method.`);
|
|
41
41
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@avleon/core",
|
|
3
|
-
"version": "0.0.
|
|
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
|
-
"
|
|
15
|
+
"husky:init": "husky install"
|
|
16
16
|
},
|
|
17
17
|
"keywords": [
|
|
18
18
|
"restapi",
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
"devDependencies": {
|
|
26
26
|
"@types/jest": "^29.5.14",
|
|
27
27
|
"@types/node": "^20.17.25",
|
|
28
|
+
"@types/pg": "^8.15.2",
|
|
28
29
|
"@typescript-eslint/eslint-plugin": "^8.32.0",
|
|
29
30
|
"@typescript-eslint/parser": "^8.32.0",
|
|
30
31
|
"class-transformer": "^0.5.1",
|
|
@@ -35,9 +36,14 @@
|
|
|
35
36
|
"ioredis": "^5.6.1",
|
|
36
37
|
"jest": "^29.7.0",
|
|
37
38
|
"lint-staged": "^16.0.0",
|
|
39
|
+
"mssql": "^11.0.1",
|
|
40
|
+
"mysql2": "^3.14.1",
|
|
38
41
|
"nodemon": "^3.1.7",
|
|
42
|
+
"pg": "^8.16.0",
|
|
39
43
|
"prettier": "^3.5.3",
|
|
40
44
|
"sharp": "^0.33.5",
|
|
45
|
+
"sqlite": "^5.1.1",
|
|
46
|
+
"sqlite3": "^5.1.7",
|
|
41
47
|
"ts-jest": "^29.2.5",
|
|
42
48
|
"ts-node": "^10.9.2",
|
|
43
49
|
"tsc-watch": "^6.2.1",
|
|
@@ -51,6 +57,7 @@
|
|
|
51
57
|
"@fastify/swagger": "^9.4.0",
|
|
52
58
|
"@fastify/swagger-ui": "^5.1.0",
|
|
53
59
|
"@fastify/view": "^11.0.0",
|
|
60
|
+
"@types/mssql": "^9.1.7",
|
|
54
61
|
"bcryptjs": "^3.0.2",
|
|
55
62
|
"cross-env": "^7.0.3",
|
|
56
63
|
"dotenv": "^16.4.7",
|
|
@@ -60,6 +67,7 @@
|
|
|
60
67
|
"pino": "^9.6.0",
|
|
61
68
|
"pino-pretty": "^13.0.0",
|
|
62
69
|
"reflect-metadata": "^0.2.2",
|
|
70
|
+
"rimraf": "^6.0.1",
|
|
63
71
|
"socket.io": "^4.8.1",
|
|
64
72
|
"typedi": "^0.10.0"
|
|
65
73
|
},
|
package/dist/websocket.test.d.ts
DELETED
|
File without changes
|
package/dist/websocket.test.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";
|