@avleon/core 0.0.28 → 0.0.29
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/dist/application.js +1 -1
- package/dist/cache.d.ts +1 -1
- package/dist/cache.js +2 -2
- package/dist/collection.d.ts +25 -32
- package/dist/collection.js +50 -6
- package/dist/collection.test.d.ts +1 -0
- package/dist/collection.test.js +59 -0
- package/dist/config.d.ts +2 -0
- package/dist/config.js +30 -5
- package/dist/config.test.d.ts +1 -0
- package/dist/config.test.js +40 -0
- package/dist/controller.js +2 -2
- package/dist/environment-variables.js +42 -5
- package/dist/event-dispatcher.d.ts +23 -0
- package/dist/event-dispatcher.js +102 -0
- package/dist/event-subscriber.d.ts +15 -0
- package/dist/event-subscriber.js +96 -0
- package/dist/exceptions/http-exceptions.js +1 -1
- package/dist/exceptions/index.d.ts +1 -1
- package/dist/exceptions/system-exception.js +3 -1
- package/dist/file-storage.js +1 -1
- package/dist/helpers.js +1 -1
- package/dist/icore.d.ts +5 -0
- package/dist/icore.js +53 -18
- package/dist/index.d.ts +2 -0
- package/dist/index.js +6 -1
- package/dist/utils/index.d.ts +2 -2
- package/dist/utils/optional-require.js +2 -2
- package/dist/validation.d.ts +1 -1
- package/dist/websocket.d.ts +7 -0
- package/dist/websocket.js +20 -0
- package/dist/websocket.test.d.ts +0 -0
- package/dist/websocket.test.js +1 -0
- package/package.json +3 -1
- package/src/config.test.ts +2 -2
- package/src/config.ts +2 -2
- package/src/event-dispatcher.ts +100 -0
- package/src/event-subscriber.ts +79 -0
- package/src/icore.ts +1106 -1060
- package/src/index.ts +3 -1
- package/src/middleware.ts +6 -4
- package/src/websocket.ts +47 -0
package/dist/application.js
CHANGED
package/dist/cache.d.ts
CHANGED
package/dist/cache.js
CHANGED
|
@@ -25,7 +25,7 @@ class CacheManager {
|
|
|
25
25
|
timestamp: Date.now(),
|
|
26
26
|
};
|
|
27
27
|
if (this.redis) {
|
|
28
|
-
await this.redis.set(key, JSON.stringify(entry.data),
|
|
28
|
+
await this.redis.set(key, JSON.stringify(entry.data), "EX", ttl);
|
|
29
29
|
for (const tag of tags) {
|
|
30
30
|
await this.redis.sadd(this.redisTagKey(tag), key);
|
|
31
31
|
}
|
|
@@ -43,7 +43,7 @@ class CacheManager {
|
|
|
43
43
|
if (this.redis) {
|
|
44
44
|
await this.redis.del(key);
|
|
45
45
|
// Also clean up from any tag sets
|
|
46
|
-
const tagKeys = await this.redis.keys(
|
|
46
|
+
const tagKeys = await this.redis.keys("cache-tags:*");
|
|
47
47
|
for (const tagKey of tagKeys) {
|
|
48
48
|
await this.redis.srem(tagKey, key);
|
|
49
49
|
}
|
package/dist/collection.d.ts
CHANGED
|
@@ -1,9 +1,23 @@
|
|
|
1
|
-
import { EntityTarget,
|
|
2
|
-
type PaginationOptions = {
|
|
3
|
-
take: number;
|
|
4
|
-
skip?: number;
|
|
5
|
-
};
|
|
1
|
+
import { EntityTarget, ObjectLiteral, Repository } from "typeorm";
|
|
6
2
|
type Predicate<T> = (item: T) => boolean;
|
|
3
|
+
type ValueOperator<T> = {
|
|
4
|
+
$in?: T[];
|
|
5
|
+
};
|
|
6
|
+
type FieldCondition<T> = T | ValueOperator<T>;
|
|
7
|
+
type WhereCondition<T> = {
|
|
8
|
+
[K in keyof T]?: FieldCondition<T[K]>;
|
|
9
|
+
};
|
|
10
|
+
type LogicalOperators<T> = {
|
|
11
|
+
$and: Where<T>[];
|
|
12
|
+
} | {
|
|
13
|
+
$or: Where<T>[];
|
|
14
|
+
} | {
|
|
15
|
+
$not: Where<T>;
|
|
16
|
+
};
|
|
17
|
+
type Where<T> = WhereCondition<T> | LogicalOperators<T>;
|
|
18
|
+
export interface IFindOneOptions<T = any> {
|
|
19
|
+
where: Where<T>;
|
|
20
|
+
}
|
|
7
21
|
export type PaginationResult<T> = {
|
|
8
22
|
total: number;
|
|
9
23
|
data: T[];
|
|
@@ -13,33 +27,12 @@ export type PaginationResult<T> = {
|
|
|
13
27
|
last?: number | null;
|
|
14
28
|
totalPage?: number;
|
|
15
29
|
};
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
static from<T>(items: T[]): BasicCollection<T>;
|
|
23
|
-
findAll(predicate?: Predicate<T>): T[];
|
|
24
|
-
findOne(predicate: Predicate<T> | FindOneOptions<T>): T | Promise<T | null>;
|
|
25
|
-
private isFunction;
|
|
26
|
-
add(item: Partial<T>): T;
|
|
27
|
-
addAll(items: T[]): void;
|
|
28
|
-
update(predicate: (item: T) => boolean, updater: Partial<T>): void;
|
|
29
|
-
updateAll(predicate: (item: T) => boolean, updater: (item: T) => T): void;
|
|
30
|
-
delete(predicate: (item: T) => boolean): void;
|
|
31
|
-
deleteAll(predicate: (item: T) => boolean): void;
|
|
32
|
-
max<K extends keyof T>(key: K & string): number;
|
|
33
|
-
min<K extends keyof T>(key: K & string): number;
|
|
34
|
-
sum<K extends keyof T>(key: K & string): number;
|
|
35
|
-
avg<K extends keyof T>(key: K & string): number;
|
|
36
|
-
paginate(options?: PaginationOptions): {
|
|
37
|
-
total: number;
|
|
38
|
-
totalPage: number;
|
|
39
|
-
next: number | null;
|
|
40
|
-
data: T[];
|
|
41
|
-
};
|
|
42
|
-
private getDeepValue;
|
|
30
|
+
export interface BasicCollection<T> {
|
|
31
|
+
clear(): void;
|
|
32
|
+
find(predicate?: Predicate<T>): T[];
|
|
33
|
+
findAsync(predicate?: Predicate<T>): Promise<T[]>;
|
|
34
|
+
findOne(predicate: Predicate<T> | IFindOneOptions<T>): T | undefined;
|
|
35
|
+
findOneAsync(predicate: Predicate<T> | IFindOneOptions<T>): Promise<T | undefined>;
|
|
43
36
|
}
|
|
44
37
|
export declare class Collection {
|
|
45
38
|
private constructor();
|
package/dist/collection.js
CHANGED
|
@@ -13,22 +13,66 @@ exports.InjectRepository = InjectRepository;
|
|
|
13
13
|
*/
|
|
14
14
|
const typedi_1 = __importDefault(require("typedi"));
|
|
15
15
|
const exceptions_1 = require("./exceptions");
|
|
16
|
-
class
|
|
16
|
+
class BasicCollectionImpl {
|
|
17
17
|
constructor(items) {
|
|
18
18
|
this.items = items;
|
|
19
19
|
}
|
|
20
20
|
static from(items) {
|
|
21
|
-
return new
|
|
21
|
+
return new BasicCollectionImpl(items);
|
|
22
22
|
}
|
|
23
|
-
|
|
23
|
+
clear() {
|
|
24
|
+
this.items = [];
|
|
25
|
+
}
|
|
26
|
+
find(predicate) {
|
|
27
|
+
if (this.isFunction(predicate)) {
|
|
28
|
+
return this.items.filter(predicate);
|
|
29
|
+
}
|
|
24
30
|
const results = Array.from(this.items);
|
|
25
31
|
return results;
|
|
26
32
|
}
|
|
33
|
+
async findAsync(predicate) {
|
|
34
|
+
const results = Array.from(this.items);
|
|
35
|
+
return results;
|
|
36
|
+
}
|
|
37
|
+
_matches(item, where) {
|
|
38
|
+
if ("$or" in where) {
|
|
39
|
+
return where.$or.some((cond) => this._matches(item, cond));
|
|
40
|
+
}
|
|
41
|
+
if ("$and" in where) {
|
|
42
|
+
return where.$and.every((cond) => this._matches(item, cond));
|
|
43
|
+
}
|
|
44
|
+
if ("$not" in where) {
|
|
45
|
+
return !this._matches(item, where.$not);
|
|
46
|
+
}
|
|
47
|
+
// Field-based matching
|
|
48
|
+
return Object.entries(where).every(([key, condition]) => {
|
|
49
|
+
const itemValue = item[key];
|
|
50
|
+
if (condition &&
|
|
51
|
+
typeof condition === "object" &&
|
|
52
|
+
!Array.isArray(condition)) {
|
|
53
|
+
const op = condition;
|
|
54
|
+
if ("$in" in op && Array.isArray(op.$in)) {
|
|
55
|
+
return op.$in.includes(itemValue);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return itemValue === condition;
|
|
59
|
+
});
|
|
60
|
+
}
|
|
27
61
|
findOne(predicate) {
|
|
28
62
|
if (this.isFunction(predicate)) {
|
|
29
63
|
return this.items.find(predicate);
|
|
30
64
|
}
|
|
31
|
-
|
|
65
|
+
const result = this.items.filter((item) => this._matches(item, predicate.where));
|
|
66
|
+
if (result.length > 0) {
|
|
67
|
+
return result[0];
|
|
68
|
+
}
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
71
|
+
async findOneAsync(predicate) {
|
|
72
|
+
if (this.isFunction(predicate)) {
|
|
73
|
+
return this.items.find(predicate);
|
|
74
|
+
}
|
|
75
|
+
return this.items.find((item) => this._matches(item, predicate.where));
|
|
32
76
|
}
|
|
33
77
|
// Utility function to check if a value is a function
|
|
34
78
|
isFunction(value) {
|
|
@@ -110,7 +154,7 @@ class AsynchronousCollection {
|
|
|
110
154
|
if (!this.repo) {
|
|
111
155
|
const dataSourceKey = "idatasource";
|
|
112
156
|
const dataSource = typedi_1.default.get(dataSourceKey);
|
|
113
|
-
console.log(
|
|
157
|
+
console.log("datasource", dataSource);
|
|
114
158
|
const repository = dataSource.getRepository(this.model);
|
|
115
159
|
this.repo = repository;
|
|
116
160
|
return repository;
|
|
@@ -137,7 +181,7 @@ class AsynchronousCollection {
|
|
|
137
181
|
class Collection {
|
|
138
182
|
constructor() { }
|
|
139
183
|
static from(items) {
|
|
140
|
-
return
|
|
184
|
+
return BasicCollectionImpl.from(items);
|
|
141
185
|
}
|
|
142
186
|
// Example refactoring of Collection.fromRepository for better type safety
|
|
143
187
|
static fromRepository(entity) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const collection_1 = require("./collection");
|
|
4
|
+
describe("Collection", () => {
|
|
5
|
+
let collection;
|
|
6
|
+
beforeEach(() => {
|
|
7
|
+
collection = collection_1.Collection.from([
|
|
8
|
+
{
|
|
9
|
+
id: 1,
|
|
10
|
+
body: "test 1",
|
|
11
|
+
completed: false,
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
id: 2,
|
|
15
|
+
body: "test 2",
|
|
16
|
+
completed: true,
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
id: 3,
|
|
20
|
+
body: "test 2",
|
|
21
|
+
completed: true,
|
|
22
|
+
},
|
|
23
|
+
]);
|
|
24
|
+
});
|
|
25
|
+
afterEach(() => {
|
|
26
|
+
collection.clear();
|
|
27
|
+
});
|
|
28
|
+
describe("find()", () => {
|
|
29
|
+
it("should be return collection", () => {
|
|
30
|
+
const result = collection.find();
|
|
31
|
+
expect(result).toHaveProperty("length");
|
|
32
|
+
expect(result.length).toBe(3);
|
|
33
|
+
});
|
|
34
|
+
it("should return only completed task", () => {
|
|
35
|
+
const result = collection.find((todo) => todo.completed);
|
|
36
|
+
expect(result).toHaveProperty("length");
|
|
37
|
+
expect(result.length).toBe(2);
|
|
38
|
+
expect(result[0].id).toBe(2);
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
describe("findOne()", () => {
|
|
42
|
+
it("should be return todo", () => {
|
|
43
|
+
const result = collection.findOne({ where: { id: 1 } });
|
|
44
|
+
expect(result).toHaveProperty("id");
|
|
45
|
+
expect(result === null || result === void 0 ? void 0 : result.id).toBe(1);
|
|
46
|
+
});
|
|
47
|
+
it("should return only completed task", () => {
|
|
48
|
+
const result = collection.findOne({
|
|
49
|
+
where: {
|
|
50
|
+
id: {
|
|
51
|
+
$in: [3],
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
expect(result).toHaveProperty("id");
|
|
56
|
+
expect(result === null || result === void 0 ? void 0 : result.completed).toBe(true);
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
});
|
package/dist/config.d.ts
CHANGED
|
@@ -14,3 +14,5 @@ export declare class AppConfig {
|
|
|
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;
|
|
17
|
+
export declare function GetConfig<T = any>(config: string | symbol): T;
|
|
18
|
+
export declare function CreateConfig<T>(token: string | symbol, callback: (env: Environment) => T): void;
|
package/dist/config.js
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.AppConfig = void 0;
|
|
4
4
|
exports.Config = Config;
|
|
5
5
|
exports.GetConfig = GetConfig;
|
|
6
|
+
exports.CreateConfig = CreateConfig;
|
|
6
7
|
/**
|
|
7
8
|
* @copyright 2024
|
|
8
9
|
* @author Tareq Hossain
|
|
@@ -11,6 +12,7 @@ exports.GetConfig = GetConfig;
|
|
|
11
12
|
*/
|
|
12
13
|
const typedi_1 = require("typedi");
|
|
13
14
|
const environment_variables_1 = require("./environment-variables");
|
|
15
|
+
const helpers_1 = require("./helpers");
|
|
14
16
|
function Config(target) {
|
|
15
17
|
typedi_1.Container.set({ id: target, type: target });
|
|
16
18
|
}
|
|
@@ -24,10 +26,33 @@ class AppConfig {
|
|
|
24
26
|
}
|
|
25
27
|
}
|
|
26
28
|
exports.AppConfig = AppConfig;
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
// Implementation
|
|
30
|
+
function GetConfig(token) {
|
|
31
|
+
// 1. Class‐based: token.prototype.config is a function
|
|
32
|
+
if (typeof token === "function" &&
|
|
33
|
+
token.prototype != null &&
|
|
34
|
+
typeof token.prototype.config === "function") {
|
|
35
|
+
const instance = typedi_1.Container.get(token);
|
|
36
|
+
if (!instance) {
|
|
37
|
+
throw new Error(`Class "${token.name}" is not registered as a config.`);
|
|
38
|
+
}
|
|
39
|
+
return instance.config((0, helpers_1.inject)(environment_variables_1.Environment));
|
|
40
|
+
}
|
|
41
|
+
// 2. Functional: token is the callback itself
|
|
42
|
+
const stored = typedi_1.Container.get(token);
|
|
43
|
+
if (!stored) {
|
|
44
|
+
throw new Error("Config object is not registered.");
|
|
45
|
+
}
|
|
46
|
+
return stored;
|
|
47
|
+
}
|
|
48
|
+
function CreateConfig(token, callback) {
|
|
49
|
+
let env;
|
|
50
|
+
try {
|
|
51
|
+
env = typedi_1.Container.get(environment_variables_1.Environment);
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
env = new environment_variables_1.Environment();
|
|
31
55
|
}
|
|
32
|
-
|
|
56
|
+
let config = callback(env);
|
|
57
|
+
typedi_1.Container.set(token, config);
|
|
33
58
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import "reflect-metadata";
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
require("reflect-metadata");
|
|
10
|
+
const config_1 = require("./config");
|
|
11
|
+
describe("Config", () => {
|
|
12
|
+
describe("class", () => {
|
|
13
|
+
it("should be call by get config", () => {
|
|
14
|
+
let MyConfig = class MyConfig {
|
|
15
|
+
config(env) {
|
|
16
|
+
return {
|
|
17
|
+
name: "avleon",
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
MyConfig = __decorate([
|
|
22
|
+
config_1.Config
|
|
23
|
+
], MyConfig);
|
|
24
|
+
const mConfig = (0, config_1.GetConfig)(MyConfig);
|
|
25
|
+
expect(mConfig).toHaveProperty("name");
|
|
26
|
+
expect(mConfig["name"]).toBe("avleon");
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
describe("createConfig()", () => {
|
|
30
|
+
it("it should create config and called with GetConfig", () => {
|
|
31
|
+
(0, config_1.CreateConfig)("myconfig", (env) => ({
|
|
32
|
+
firstname: "tareq",
|
|
33
|
+
os: env.get("name"),
|
|
34
|
+
}));
|
|
35
|
+
const mConfig = (0, config_1.GetConfig)("myconfig");
|
|
36
|
+
expect(mConfig).toHaveProperty("firstname");
|
|
37
|
+
expect(mConfig.firstname).toBe("tareq");
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
});
|
package/dist/controller.js
CHANGED
|
@@ -37,13 +37,13 @@ function createControllerDecorator(type = "web") {
|
|
|
37
37
|
};
|
|
38
38
|
}
|
|
39
39
|
function ApiController(pathOrOptions = "/", mayBeOptions) {
|
|
40
|
-
if (typeof pathOrOptions ==
|
|
40
|
+
if (typeof pathOrOptions == "function") {
|
|
41
41
|
Reflect.defineMetadata(container_1.API_CONTROLLER_METADATA_KEY, true, pathOrOptions);
|
|
42
42
|
// Ensure Service is applied as a ClassDecorator
|
|
43
43
|
if (typeof typedi_1.Service === "function") {
|
|
44
44
|
(0, container_1.registerController)(pathOrOptions); // Add to custom registry
|
|
45
45
|
(0, typedi_1.Service)()(pathOrOptions); // Apply DI decorator
|
|
46
|
-
Reflect.defineMetadata(container_1.CONTROLLER_META_KEY, { type:
|
|
46
|
+
Reflect.defineMetadata(container_1.CONTROLLER_META_KEY, { type: "api", path: "/", options: {} }, pathOrOptions);
|
|
47
47
|
}
|
|
48
48
|
else {
|
|
49
49
|
throw new Error("Service decorator is not a function");
|
|
@@ -5,12 +5,45 @@
|
|
|
5
5
|
* @email xtrinsic96@gmail.com
|
|
6
6
|
* @url https://github.com/xtareq
|
|
7
7
|
*/
|
|
8
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
9
|
+
if (k2 === undefined) k2 = k;
|
|
10
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
11
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
12
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
13
|
+
}
|
|
14
|
+
Object.defineProperty(o, k2, desc);
|
|
15
|
+
}) : (function(o, m, k, k2) {
|
|
16
|
+
if (k2 === undefined) k2 = k;
|
|
17
|
+
o[k2] = m[k];
|
|
18
|
+
}));
|
|
19
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
20
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
21
|
+
}) : function(o, v) {
|
|
22
|
+
o["default"] = v;
|
|
23
|
+
});
|
|
8
24
|
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
9
25
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
10
26
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
11
27
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
12
28
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
13
29
|
};
|
|
30
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
31
|
+
var ownKeys = function(o) {
|
|
32
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
33
|
+
var ar = [];
|
|
34
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
35
|
+
return ar;
|
|
36
|
+
};
|
|
37
|
+
return ownKeys(o);
|
|
38
|
+
};
|
|
39
|
+
return function (mod) {
|
|
40
|
+
if (mod && mod.__esModule) return mod;
|
|
41
|
+
var result = {};
|
|
42
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
43
|
+
__setModuleDefault(result, mod);
|
|
44
|
+
return result;
|
|
45
|
+
};
|
|
46
|
+
})();
|
|
14
47
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
15
48
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
16
49
|
};
|
|
@@ -18,14 +51,18 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
18
51
|
exports.Environment = void 0;
|
|
19
52
|
const dotenv_1 = __importDefault(require("dotenv"));
|
|
20
53
|
const path_1 = __importDefault(require("path"));
|
|
21
|
-
const fs_1 =
|
|
54
|
+
const fs_1 = __importStar(require("fs"));
|
|
22
55
|
const typedi_1 = require("typedi");
|
|
23
56
|
const system_exception_1 = require("./exceptions/system-exception");
|
|
24
57
|
dotenv_1.default.config({ path: path_1.default.join(process.cwd(), ".env") });
|
|
25
58
|
let Environment = class Environment {
|
|
26
59
|
parseEnvFile(filePath) {
|
|
27
60
|
try {
|
|
28
|
-
const
|
|
61
|
+
const isExis = (0, fs_1.existsSync)(filePath);
|
|
62
|
+
if (!isExis) {
|
|
63
|
+
return { ...process.env };
|
|
64
|
+
}
|
|
65
|
+
const fileContent = fs_1.default.readFileSync(filePath, "utf8");
|
|
29
66
|
const parsedEnv = dotenv_1.default.parse(fileContent);
|
|
30
67
|
return { ...parsedEnv, ...process.env };
|
|
31
68
|
}
|
|
@@ -35,18 +72,18 @@ let Environment = class Environment {
|
|
|
35
72
|
}
|
|
36
73
|
}
|
|
37
74
|
get(key) {
|
|
38
|
-
const parsedEnv = this.parseEnvFile(path_1.default.join(process.cwd(),
|
|
75
|
+
const parsedEnv = this.parseEnvFile(path_1.default.join(process.cwd(), ".env"));
|
|
39
76
|
return parsedEnv[key];
|
|
40
77
|
}
|
|
41
78
|
getOrThrow(key) {
|
|
42
|
-
const parsedEnv = this.parseEnvFile(path_1.default.join(process.cwd(),
|
|
79
|
+
const parsedEnv = this.parseEnvFile(path_1.default.join(process.cwd(), ".env"));
|
|
43
80
|
if (!Object(parsedEnv).hasOwnProperty(key)) {
|
|
44
81
|
throw new system_exception_1.EnvironmentVariableNotFound(key);
|
|
45
82
|
}
|
|
46
83
|
return parsedEnv[key];
|
|
47
84
|
}
|
|
48
85
|
getAll() {
|
|
49
|
-
const parsedEnv = this.parseEnvFile(path_1.default.join(process.cwd(),
|
|
86
|
+
const parsedEnv = this.parseEnvFile(path_1.default.join(process.cwd(), ".env"));
|
|
50
87
|
return parsedEnv;
|
|
51
88
|
}
|
|
52
89
|
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Socket } from 'socket.io';
|
|
2
|
+
export declare class SocketContextService {
|
|
3
|
+
private readonly storage;
|
|
4
|
+
run(socket: Socket, fn: () => void | Promise<void>): void;
|
|
5
|
+
getSocket(): Socket | undefined;
|
|
6
|
+
}
|
|
7
|
+
export type DispatchOptions = {
|
|
8
|
+
room?: string;
|
|
9
|
+
broadcast?: boolean;
|
|
10
|
+
transports?: ('socket' | 'kafka' | 'rabbitmq')[];
|
|
11
|
+
retry?: number;
|
|
12
|
+
retryDelay?: number;
|
|
13
|
+
};
|
|
14
|
+
export declare function sleep(ms: number): Promise<unknown>;
|
|
15
|
+
export declare class EventDispatcher {
|
|
16
|
+
private readonly _context;
|
|
17
|
+
constructor(_context: SocketContextService);
|
|
18
|
+
dispatch<T = any>(event: string, data: T, options?: DispatchOptions): Promise<void>;
|
|
19
|
+
private dispatchToTransports;
|
|
20
|
+
}
|
|
21
|
+
export declare function Dispatch(event: string, options?: Omit<DispatchOptions, 'transports'> & {
|
|
22
|
+
transports?: DispatchOptions['transports'];
|
|
23
|
+
}): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.EventDispatcher = exports.SocketContextService = void 0;
|
|
13
|
+
exports.sleep = sleep;
|
|
14
|
+
exports.Dispatch = Dispatch;
|
|
15
|
+
const typedi_1 = require("typedi");
|
|
16
|
+
const socket_io_1 = require("socket.io");
|
|
17
|
+
// SocketContextService.ts
|
|
18
|
+
const node_async_hooks_1 = require("node:async_hooks");
|
|
19
|
+
let SocketContextService = class SocketContextService {
|
|
20
|
+
constructor() {
|
|
21
|
+
this.storage = new node_async_hooks_1.AsyncLocalStorage();
|
|
22
|
+
}
|
|
23
|
+
run(socket, fn) {
|
|
24
|
+
this.storage.run({ socket }, fn);
|
|
25
|
+
}
|
|
26
|
+
getSocket() {
|
|
27
|
+
var _a;
|
|
28
|
+
return (_a = this.storage.getStore()) === null || _a === void 0 ? void 0 : _a.socket;
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
exports.SocketContextService = SocketContextService;
|
|
32
|
+
exports.SocketContextService = SocketContextService = __decorate([
|
|
33
|
+
(0, typedi_1.Service)()
|
|
34
|
+
], SocketContextService);
|
|
35
|
+
function sleep(ms) {
|
|
36
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
37
|
+
}
|
|
38
|
+
let EventDispatcher = class EventDispatcher {
|
|
39
|
+
constructor(_context) {
|
|
40
|
+
this._context = _context;
|
|
41
|
+
}
|
|
42
|
+
async dispatch(event, data, options = {}) {
|
|
43
|
+
var _a, _b;
|
|
44
|
+
const retryCount = (_a = options.retry) !== null && _a !== void 0 ? _a : 0;
|
|
45
|
+
const delay = (_b = options.retryDelay) !== null && _b !== void 0 ? _b : 300;
|
|
46
|
+
for (let attempt = 0; attempt <= retryCount; attempt++) {
|
|
47
|
+
try {
|
|
48
|
+
await this.dispatchToTransports(event, data, options);
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
catch (err) {
|
|
52
|
+
if (attempt === retryCount)
|
|
53
|
+
throw err;
|
|
54
|
+
await sleep(delay * (attempt + 1));
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
async dispatchToTransports(event, data, options) {
|
|
59
|
+
var _a;
|
|
60
|
+
const transports = (_a = options.transports) !== null && _a !== void 0 ? _a : ['socket'];
|
|
61
|
+
for (const transport of transports) {
|
|
62
|
+
if (transport === 'socket') {
|
|
63
|
+
const io = typedi_1.Container.get(socket_io_1.Server);
|
|
64
|
+
//console.log('SOckert', Container.get(SocketContextService));
|
|
65
|
+
const context = typedi_1.Container.get(SocketContextService);
|
|
66
|
+
const socket = context.getSocket();
|
|
67
|
+
if (options.broadcast && socket) {
|
|
68
|
+
if (options.room) {
|
|
69
|
+
socket.broadcast.to(options.room).emit(event, data);
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
socket.broadcast.emit(event, data);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
if (options.room) {
|
|
77
|
+
io.to(options.room).emit(event, data);
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
io.emit(event, data);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
exports.EventDispatcher = EventDispatcher;
|
|
88
|
+
exports.EventDispatcher = EventDispatcher = __decorate([
|
|
89
|
+
(0, typedi_1.Service)(),
|
|
90
|
+
__metadata("design:paramtypes", [SocketContextService])
|
|
91
|
+
], EventDispatcher);
|
|
92
|
+
function Dispatch(event, options) {
|
|
93
|
+
return function (target, propertyKey, descriptor) {
|
|
94
|
+
const original = descriptor.value;
|
|
95
|
+
descriptor.value = async function (...args) {
|
|
96
|
+
const result = await original.apply(this, args);
|
|
97
|
+
const dispatcher = typedi_1.Container.get(EventDispatcher);
|
|
98
|
+
await dispatcher.dispatch(event, result, options);
|
|
99
|
+
return result;
|
|
100
|
+
};
|
|
101
|
+
};
|
|
102
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Socket } from 'socket.io';
|
|
2
|
+
import { SocketContextService } from './event-dispatcher';
|
|
3
|
+
import 'reflect-metadata';
|
|
4
|
+
export declare function Private(channelResolver?: (socket: any) => string): (target: any, propertyKey: string) => void;
|
|
5
|
+
export declare function isPrivate(target: any, propertyKey: string): boolean;
|
|
6
|
+
export declare function getPrivateChannelResolver(target: any, propertyKey: string): ((socket: any) => string) | undefined;
|
|
7
|
+
export declare function registerSocketSubscriber(target: Function): void;
|
|
8
|
+
export declare function getSocketSubscribers(): Function[];
|
|
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
|
+
export declare class EventSubscriberRegistry {
|
|
12
|
+
private readonly socketContext;
|
|
13
|
+
constructor(socketContext: SocketContextService);
|
|
14
|
+
register(socket: Socket): void;
|
|
15
|
+
}
|