@avleon/core 0.0.36 → 0.0.38

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/License ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Tareq Hossain
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -350,10 +350,9 @@ class UserDto {
350
350
 
351
351
  Generate API documentation automatically:
352
352
 
353
- ```typescript
354
- const app = new Avleon({
355
- controllers: [UserController],
356
- openapi: {
353
+ ```typescript
354
+
355
+ app.useOpenApi({
357
356
  info: {
358
357
  title: "User API",
359
358
  version: "1.0.0",
@@ -365,9 +364,9 @@ const app = new Avleon({
365
364
  description: "Development server",
366
365
  },
367
366
  ],
368
- },
369
- });
370
- ```
367
+ });
368
+
369
+ ```
371
370
 
372
371
  You can also customize the OpenAPI UI:
373
372
 
@@ -4,6 +4,7 @@
4
4
  * @email xtrinsic96@gmail.com
5
5
  * @url https://github.com/xtareq
6
6
  */
7
+ import { Knex } from "knex";
7
8
  import TypediContainer from "typedi";
8
9
  export declare const FEATURE_KEY: unique symbol;
9
10
  export declare const ROUTE_META_KEY: unique symbol;
@@ -25,4 +26,5 @@ export declare function getRegisteredControllers(): Function[];
25
26
  export declare const API_CONTROLLER_METADATA_KEY: unique symbol;
26
27
  export declare function isApiController(target: Function): boolean;
27
28
  export declare function registerDataSource(dataSource: any): void;
29
+ export declare function registerKnex(dataSource: Knex.Config): void;
28
30
  export default Container;
package/dist/container.js CHANGED
@@ -10,12 +10,7 @@ exports.getRegisteredServices = getRegisteredServices;
10
10
  exports.getRegisteredControllers = getRegisteredControllers;
11
11
  exports.isApiController = isApiController;
12
12
  exports.registerDataSource = registerDataSource;
13
- /**
14
- * @copyright 2024
15
- * @author Tareq Hossain
16
- * @email xtrinsic96@gmail.com
17
- * @url https://github.com/xtareq
18
- */
13
+ exports.registerKnex = registerKnex;
19
14
  const typedi_1 = __importDefault(require("typedi"));
20
15
  exports.FEATURE_KEY = Symbol.for("features");
21
16
  exports.ROUTE_META_KEY = Symbol("iroute:options");
@@ -54,4 +49,7 @@ Container.set("appName", "Iqra");
54
49
  function registerDataSource(dataSource) {
55
50
  Container.set("idatasource", dataSource);
56
51
  }
52
+ function registerKnex(dataSource) {
53
+ Container.set("KnexConnection", dataSource);
54
+ }
57
55
  exports.default = Container;
@@ -4,9 +4,46 @@
4
4
  * @email xtrinsic96@gmail.com
5
5
  * @url https://github.com/xtareq
6
6
  */
7
+ /**
8
+ * @class Environment
9
+ * @description A service class to manage access to environment variables.
10
+ * It loads variables from `.env` file and merges them with `process.env`,
11
+ * giving precedence to `process.env` values.
12
+ */
7
13
  export declare class Environment {
14
+ /**
15
+ * Parses the given `.env` file and merges it with `process.env`.
16
+ * Values from `process.env` take precedence.
17
+ *
18
+ * @private
19
+ * @param filePath - Absolute path to the `.env` file.
20
+ * @returns A dictionary of merged environment variables.
21
+ */
8
22
  private parseEnvFile;
23
+ /**
24
+ * Retrieves the value of the specified environment variable.
25
+ *
26
+ * @template T
27
+ * @param key - The name of the environment variable.
28
+ * @returns The value of the variable, or `undefined` if not found.
29
+ */
9
30
  get<T = any>(key: string): T;
31
+ /**
32
+ * Retrieves the value of the specified environment variable.
33
+ * Throws an error if the variable is not found.
34
+ *
35
+ * @template T
36
+ * @param key - The name of the environment variable.
37
+ * @throws {EnvironmentVariableNotFound} If the variable does not exist.
38
+ * @returns The value of the variable.
39
+ */
10
40
  getOrThrow<T = any>(key: string): T;
41
+ /**
42
+ * Retrieves all available environment variables,
43
+ * with `process.env` values taking precedence over `.env` values.
44
+ *
45
+ * @template T
46
+ * @returns An object containing all environment variables.
47
+ */
11
48
  getAll<T = any>(): T;
12
49
  }
@@ -55,7 +55,21 @@ const fs_1 = __importStar(require("fs"));
55
55
  const typedi_1 = require("typedi");
56
56
  const system_exception_1 = require("./exceptions/system-exception");
57
57
  dotenv_1.default.config({ path: path_1.default.join(process.cwd(), ".env") });
58
+ /**
59
+ * @class Environment
60
+ * @description A service class to manage access to environment variables.
61
+ * It loads variables from `.env` file and merges them with `process.env`,
62
+ * giving precedence to `process.env` values.
63
+ */
58
64
  let Environment = class Environment {
65
+ /**
66
+ * Parses the given `.env` file and merges it with `process.env`.
67
+ * Values from `process.env` take precedence.
68
+ *
69
+ * @private
70
+ * @param filePath - Absolute path to the `.env` file.
71
+ * @returns A dictionary of merged environment variables.
72
+ */
59
73
  parseEnvFile(filePath) {
60
74
  try {
61
75
  const isExis = (0, fs_1.existsSync)(filePath);
@@ -71,10 +85,26 @@ let Environment = class Environment {
71
85
  return {};
72
86
  }
73
87
  }
88
+ /**
89
+ * Retrieves the value of the specified environment variable.
90
+ *
91
+ * @template T
92
+ * @param key - The name of the environment variable.
93
+ * @returns The value of the variable, or `undefined` if not found.
94
+ */
74
95
  get(key) {
75
96
  const parsedEnv = this.parseEnvFile(path_1.default.join(process.cwd(), ".env"));
76
97
  return parsedEnv[key];
77
98
  }
99
+ /**
100
+ * Retrieves the value of the specified environment variable.
101
+ * Throws an error if the variable is not found.
102
+ *
103
+ * @template T
104
+ * @param key - The name of the environment variable.
105
+ * @throws {EnvironmentVariableNotFound} If the variable does not exist.
106
+ * @returns The value of the variable.
107
+ */
78
108
  getOrThrow(key) {
79
109
  const parsedEnv = this.parseEnvFile(path_1.default.join(process.cwd(), ".env"));
80
110
  if (!Object(parsedEnv).hasOwnProperty(key)) {
@@ -82,6 +112,13 @@ let Environment = class Environment {
82
112
  }
83
113
  return parsedEnv[key];
84
114
  }
115
+ /**
116
+ * Retrieves all available environment variables,
117
+ * with `process.env` values taking precedence over `.env` values.
118
+ *
119
+ * @template T
120
+ * @returns An object containing all environment variables.
121
+ */
85
122
  getAll() {
86
123
  const parsedEnv = this.parseEnvFile(path_1.default.join(process.cwd(), ".env"));
87
124
  return parsedEnv;
package/dist/icore.d.ts CHANGED
@@ -16,6 +16,7 @@ import { FastifyCorsOptions } from "@fastify/cors";
16
16
  import { FastifyMultipartOptions } from "@fastify/multipart";
17
17
  import { MultipartFile } from "./multipart";
18
18
  import { ServerOptions } from "socket.io";
19
+ import { Knex } from "knex";
19
20
  export type FuncRoute = {
20
21
  handler: any;
21
22
  middlewares?: any[];
@@ -149,6 +150,7 @@ export declare class AvleonApplication {
149
150
  useOpenApi<T = OpenApiUiOptions>(configOrClass: OpenApiConfigInput<T>): void;
150
151
  useMultipart<T extends MultipartOptions>(options: ConfigInput<T>): void;
151
152
  useDataSource<T extends DataSourceOptions>(options: ConfigInput<T>): void;
153
+ useKnex<T extends Knex.Config>(options: ConfigInput<T>): void;
152
154
  private _useCache;
153
155
  useMiddlewares<T extends AvleonMiddleware>(mclasses: Constructor<T>[]): void;
154
156
  useAuthoriztion<T extends any>(middleware: Constructor<T>): void;
@@ -218,12 +220,13 @@ export interface IAppBuilder {
218
220
  export declare class AvleonTest {
219
221
  private constructor();
220
222
  static getController<T>(controller: Constructor<T>, deps?: any[]): T;
221
- private getService;
223
+ static getProvider<T>(service: Constructor<T>, deps?: any[]): T;
222
224
  static createTestApplication(options: TestAppOptions): TestApplication;
223
225
  static from(app: AvleonApplication): TestApplication;
224
226
  static clean(): void;
225
227
  }
226
228
  export declare class Avleon {
227
229
  static createApplication(): AvleonApplication;
230
+ static createTestApplication(options: TestAppOptions): TestApplication;
228
231
  }
229
232
  export {};
package/dist/icore.js CHANGED
@@ -61,6 +61,7 @@ const utils_1 = require("./utils");
61
61
  const socket_io_1 = require("socket.io");
62
62
  const event_subscriber_1 = require("./event-subscriber");
63
63
  const stream_1 = __importDefault(require("stream"));
64
+ const kenx_provider_1 = require("./kenx-provider");
64
65
  const isTsNode = process.env.TS_NODE_DEV ||
65
66
  process.env.TS_NODE_PROJECT ||
66
67
  process[Symbol.for("ts-node.register.instance")];
@@ -229,6 +230,20 @@ class AvleonApplication {
229
230
  this.dataSource = datasource;
230
231
  typedi_1.default.set("idatasource", datasource);
231
232
  }
233
+ useKnex(options) {
234
+ let dataSourceOptions;
235
+ if (this._isConfigClass(options)) {
236
+ dataSourceOptions = this.appConfig.get(options);
237
+ }
238
+ else {
239
+ dataSourceOptions = options;
240
+ }
241
+ if (!dataSourceOptions)
242
+ throw new system_exception_1.SystemUseError("Invlaid datasource options.");
243
+ //registerKnex(dataSourceOptions);
244
+ const db = typedi_1.default.get(kenx_provider_1.DB);
245
+ db.init(dataSourceOptions);
246
+ }
232
247
  _useCache(options) { }
233
248
  useMiddlewares(mclasses) {
234
249
  for (const mclass of mclasses) {
@@ -539,14 +554,6 @@ class AvleonApplication {
539
554
  }
540
555
  }
541
556
  }
542
- // addFeature(feature:{controllers:Function[]}){
543
- // feature.controllers.forEach(c=> this.controllers.push(c))
544
- // }
545
- // mapFeature(){
546
- // if(!this.isMapFeatures){
547
- // this.isMapFeatures = true;
548
- // }
549
- // }
550
557
  async _mapControllers() {
551
558
  if (this.controllers.length > 0) {
552
559
  for (let controller of this.controllers) {
@@ -559,10 +566,6 @@ class AvleonApplication {
559
566
  }
560
567
  }
561
568
  }
562
- // useControllersAuto(controllerPath?:string) {
563
- // this.registerControllerAuto = true;
564
- // //this.autoControllers();
565
- // }
566
569
  async mapFn(fn) {
567
570
  const original = fn;
568
571
  fn = function () { };
@@ -719,8 +722,6 @@ class AvleonApplication {
719
722
  }
720
723
  getTestApp(buildOptions) {
721
724
  try {
722
- // }
723
- // this.initializeDatabase();
724
725
  this._mapControllers();
725
726
  this.rMap.forEach((value, key) => {
726
727
  const [m, r] = key.split(":");
@@ -783,7 +784,11 @@ class AvleonTest {
783
784
  });
784
785
  return typedi_1.default.get(controller);
785
786
  }
786
- getService(service) {
787
+ static getProvider(service, deps = []) {
788
+ const paramTypes = Reflect.getMetadata("design:paramtypes", service) || [];
789
+ deps.forEach((dep, i) => {
790
+ typedi_1.default.set(paramTypes[i], dep);
791
+ });
787
792
  return typedi_1.default.get(service);
788
793
  }
789
794
  static createTestApplication(options) {
@@ -806,5 +811,9 @@ class Avleon {
806
811
  const app = AvleonApplication.getApp();
807
812
  return app;
808
813
  }
814
+ static createTestApplication(options) {
815
+ const app = AvleonTest.createTestApplication(options);
816
+ return app;
817
+ }
809
818
  }
810
819
  exports.Avleon = Avleon;
package/dist/index.d.ts CHANGED
@@ -25,6 +25,7 @@ export * from "./multipart";
25
25
  export * from "./file-storage";
26
26
  export * from "./logger";
27
27
  export * from "./event-dispatcher";
28
+ export * from "./kenx-provider";
28
29
  export { Subscribe, Private } from "./event-subscriber";
29
30
  export declare const GetSchema: typeof sw.generateSwaggerSchema;
30
31
  export { default as AvleonContainer } from "./container";
package/dist/index.js CHANGED
@@ -71,6 +71,7 @@ __exportStar(require("./multipart"), exports);
71
71
  __exportStar(require("./file-storage"), exports);
72
72
  __exportStar(require("./logger"), exports);
73
73
  __exportStar(require("./event-dispatcher"), exports);
74
+ __exportStar(require("./kenx-provider"), exports);
74
75
  var event_subscriber_1 = require("./event-subscriber");
75
76
  Object.defineProperty(exports, "Subscribe", { enumerable: true, get: function () { return event_subscriber_1.Subscribe; } });
76
77
  Object.defineProperty(exports, "Private", { enumerable: true, get: function () { return event_subscriber_1.Private; } });
@@ -0,0 +1,7 @@
1
+ import type { Knex } from "knex";
2
+ export declare class DB {
3
+ private connection;
4
+ constructor();
5
+ init(config: Knex.Config): Knex<any, any[]>;
6
+ get client(): Knex;
7
+ }
@@ -0,0 +1,44 @@
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.DB = void 0;
13
+ const typedi_1 = require("typedi");
14
+ const typedi_2 = require("typedi");
15
+ let DB = class DB {
16
+ constructor() {
17
+ const existing = typedi_2.Container.has("KnexConnection")
18
+ ? typedi_2.Container.get("KnexConnection")
19
+ : null;
20
+ if (existing) {
21
+ this.connection = existing;
22
+ }
23
+ }
24
+ // Initialize manually (call this in main if you want)
25
+ init(config) {
26
+ if (!this.connection) {
27
+ const knex = require("knex");
28
+ this.connection = knex(config);
29
+ typedi_2.Container.set("KnexConnection", this.connection);
30
+ }
31
+ return this.connection;
32
+ }
33
+ get client() {
34
+ if (!this.connection) {
35
+ throw new Error("Knex is not initialized. Call DB.init(config) first.");
36
+ }
37
+ return this.connection;
38
+ }
39
+ };
40
+ exports.DB = DB;
41
+ exports.DB = DB = __decorate([
42
+ (0, typedi_1.Service)(),
43
+ __metadata("design:paramtypes", [])
44
+ ], DB);
package/package.json CHANGED
@@ -1,19 +1,8 @@
1
1
  {
2
2
  "name": "@avleon/core",
3
- "version": "0.0.36",
3
+ "version": "0.0.38",
4
4
  "main": "./dist/index.js",
5
5
  "types": "./dist/index.d.ts",
6
- "scripts": {
7
- "build": "npm run clean && tsc",
8
- "clean": "rimraf dist",
9
- "watch": "tsc-watch",
10
- "lint": "eslint .",
11
- "lint:fix": "eslint . --fix",
12
- "format": "prettier --write .",
13
- "test": "jest",
14
- "test:watch": "jest --watch",
15
- "husky:init": "husky install"
16
- },
17
6
  "keywords": [
18
7
  "restapi",
19
8
  "avleon",
@@ -35,6 +24,7 @@
35
24
  "husky": "^8.0.0",
36
25
  "ioredis": "^5.6.1",
37
26
  "jest": "^29.7.0",
27
+ "knex": "^3.1.0",
38
28
  "lint-staged": "^16.0.0",
39
29
  "mssql": "^11.0.1",
40
30
  "mysql2": "^3.14.1",
@@ -75,7 +65,8 @@
75
65
  "@scalar/fastify-api-reference": "*",
76
66
  "ioredis": "*",
77
67
  "sharp": "*",
78
- "typeorm": "*"
68
+ "typeorm": "*",
69
+ "knex": "*"
79
70
  },
80
71
  "peerDependenciesMeta": {
81
72
  "@scalar/fastify-api-reference": {
@@ -89,6 +80,9 @@
89
80
  },
90
81
  "typeorm": {
91
82
  "optional": true
83
+ },
84
+ "knex": {
85
+ "optional": true
92
86
  }
93
87
  },
94
88
  "lint-staged": {
@@ -111,5 +105,16 @@
111
105
  },
112
106
  "files": [
113
107
  "dist"
114
- ]
115
- }
108
+ ],
109
+ "scripts": {
110
+ "build": "npm run clean && tsc",
111
+ "clean": "rimraf dist",
112
+ "watch": "tsc-watch",
113
+ "lint": "eslint .",
114
+ "lint:fix": "eslint . --fix",
115
+ "format": "prettier --write .",
116
+ "test": "jest",
117
+ "test:watch": "jest --watch",
118
+ "husky:init": "husky install"
119
+ }
120
+ }