@avleon/core 0.0.45 → 0.0.46

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 (54) hide show
  1. package/License +21 -21
  2. package/README.md +667 -681
  3. package/dist/application.test.js +15 -0
  4. package/dist/controller.test.js +0 -14
  5. package/dist/core/application.d.ts +74 -0
  6. package/dist/core/application.js +424 -0
  7. package/dist/core/router.d.ts +44 -0
  8. package/dist/core/router.js +520 -0
  9. package/dist/core/testing.d.ts +21 -0
  10. package/dist/core/testing.js +104 -0
  11. package/dist/core/types.d.ts +67 -0
  12. package/dist/core/types.js +2 -0
  13. package/dist/event-dispatcher.d.ts +0 -1
  14. package/dist/event-dispatcher.js +4 -7
  15. package/dist/file-storage.test.js +15 -2
  16. package/dist/helpers.d.ts +9 -42
  17. package/dist/helpers.js +19 -411
  18. package/dist/index.d.ts +17 -15
  19. package/dist/index.js +18 -22
  20. package/dist/interfaces/avleon-application.d.ts +74 -26
  21. package/dist/interfaces/avleon-application.js +1 -0
  22. package/dist/middleware.d.ts +11 -4
  23. package/dist/middleware.js +9 -0
  24. package/dist/multipart.d.ts +2 -2
  25. package/dist/openapi.d.ts +70 -3
  26. package/dist/openapi.js +32 -0
  27. package/dist/params.js +1 -1
  28. package/dist/params.test.js +8 -8
  29. package/dist/route-methods.js +16 -5
  30. package/dist/swagger-schema.d.ts +11 -17
  31. package/dist/swagger-schema.js +84 -82
  32. package/dist/swagger-schema.test.js +32 -12
  33. package/dist/utils/common-utils.d.ts +17 -0
  34. package/dist/utils/common-utils.js +108 -0
  35. package/dist/utils/di-utils.d.ts +1 -0
  36. package/dist/utils/di-utils.js +22 -0
  37. package/dist/utils/hash.d.ts +0 -2
  38. package/dist/utils/hash.js +1 -5
  39. package/dist/utils/object-utils.d.ts +11 -0
  40. package/dist/utils/object-utils.js +198 -0
  41. package/dist/utils/validation-utils.d.ts +13 -0
  42. package/dist/utils/validation-utils.js +119 -0
  43. package/dist/validation.js +1 -4
  44. package/dist/websocket.d.ts +3 -0
  45. package/dist/websocket.js +2 -1
  46. package/package.json +53 -40
  47. package/dist/application.d.ts +0 -47
  48. package/dist/application.js +0 -50
  49. package/dist/icore.d.ts +0 -226
  50. package/dist/icore.js +0 -968
  51. package/dist/icore.test.js +0 -14
  52. package/dist/testing.d.ts +0 -55
  53. package/dist/testing.js +0 -196
  54. /package/dist/{icore.test.d.ts → application.test.d.ts} +0 -0
@@ -0,0 +1,198 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.pick = pick;
4
+ exports.exclude = exclude;
5
+ exports.autoCast = autoCast;
6
+ exports.normalizeQueryDeep = normalizeQueryDeep;
7
+ exports.transformObjectByInstanceToObject = transformObjectByInstanceToObject;
8
+ exports.jsonToJs = jsonToJs;
9
+ exports.jsonToInstance = jsonToInstance;
10
+ /**
11
+ * @copyright 2024
12
+ * @author Tareq Hossain
13
+ * @email xtrinsic96@gmail.com
14
+ * @url https://github.com/xtareq
15
+ */
16
+ const class_transformer_1 = require("class-transformer");
17
+ function pick(obj, paths) {
18
+ const result = {};
19
+ for (const path of paths) {
20
+ const keys = path.split(".");
21
+ let source = obj;
22
+ let target = result;
23
+ for (let i = 0; i < keys.length; i++) {
24
+ const key = keys[i];
25
+ if (!(key in source))
26
+ break;
27
+ if (i === keys.length - 1) {
28
+ target[key] = source[key];
29
+ }
30
+ else {
31
+ source = source[key];
32
+ target[key] = target[key] || {};
33
+ target = target[key];
34
+ }
35
+ }
36
+ }
37
+ return result;
38
+ }
39
+ function exclude(obj, paths) {
40
+ if (Array.isArray(obj)) {
41
+ return obj.map((item) => exclude(item, paths));
42
+ }
43
+ const clone = structuredClone(obj); // Or use lodash.cloneDeep
44
+ for (const path of paths) {
45
+ const keys = path.split(".");
46
+ let target = clone;
47
+ for (let i = 0; i < keys.length - 1; i++) {
48
+ if (!(keys[i] in target))
49
+ break;
50
+ target = target[keys[i]];
51
+ }
52
+ target === null || target === void 0 ? true : delete target[keys[keys.length - 1]];
53
+ }
54
+ return clone;
55
+ }
56
+ function autoCast(value, typeHint, schema) {
57
+ var _a, _b;
58
+ if (value === null || value === undefined)
59
+ return value;
60
+ if (Array.isArray(value)) {
61
+ const elementType = Array.isArray(typeHint) ? typeHint[0] : undefined;
62
+ return value.map((v) => autoCast(v, elementType));
63
+ }
64
+ if (typeof value === "object" && !(value instanceof Date)) {
65
+ const result = {};
66
+ for (const [key, val] of Object.entries(value)) {
67
+ let fieldType = undefined;
68
+ if ((_b = (_a = schema === null || schema === void 0 ? void 0 : schema.properties) === null || _a === void 0 ? void 0 : _a[key]) === null || _b === void 0 ? void 0 : _b.type) {
69
+ const t = schema.properties[key].type;
70
+ fieldType =
71
+ t === "integer" || t === "number"
72
+ ? Number
73
+ : t === "boolean"
74
+ ? Boolean
75
+ : t === "array"
76
+ ? Array
77
+ : t === "object"
78
+ ? Object
79
+ : String;
80
+ }
81
+ result[key] = autoCast(val, fieldType);
82
+ }
83
+ return result;
84
+ }
85
+ if (typeof value !== "string")
86
+ return value;
87
+ const trimmed = value.trim();
88
+ if (typeHint === Boolean || trimmed.toLowerCase() === "true")
89
+ return true;
90
+ if (trimmed.toLowerCase() === "false")
91
+ return false;
92
+ if (typeHint === Number || (!isNaN(Number(trimmed)) && trimmed !== "")) {
93
+ const n = Number(trimmed);
94
+ if (!isNaN(n))
95
+ return n;
96
+ }
97
+ if ((trimmed.startsWith("{") && trimmed.endsWith("}")) ||
98
+ (trimmed.startsWith("[") && trimmed.endsWith("]"))) {
99
+ try {
100
+ const parsed = JSON.parse(trimmed);
101
+ return autoCast(parsed, typeHint, schema);
102
+ }
103
+ catch (_c) {
104
+ return trimmed;
105
+ }
106
+ }
107
+ if (typeHint === Date ||
108
+ /^\d{4}-\d{2}-\d{2}([Tt]\d{2}:\d{2})?/.test(trimmed)) {
109
+ const d = new Date(trimmed);
110
+ if (!isNaN(d.getTime()))
111
+ return d;
112
+ }
113
+ return trimmed;
114
+ }
115
+ /**
116
+ * Deeply normalizes query strings into nested JS objects.
117
+ */
118
+ function normalizeQueryDeep(query) {
119
+ const result = {};
120
+ const setDeep = (obj, path, value) => {
121
+ let current = obj;
122
+ for (let i = 0; i < path.length; i++) {
123
+ const key = path[i];
124
+ const nextKey = path[i + 1];
125
+ if (i === path.length - 1) {
126
+ if (key === "") {
127
+ if (!Array.isArray(current))
128
+ current = [];
129
+ current.push(value);
130
+ }
131
+ else if (Array.isArray(current[key])) {
132
+ current[key].push(value);
133
+ }
134
+ else if (current[key] !== undefined) {
135
+ current[key] = [current[key], value];
136
+ }
137
+ else {
138
+ current[key] = value;
139
+ }
140
+ }
141
+ else {
142
+ if (!current[key]) {
143
+ current[key] = nextKey === "" || /^\d+$/.test(nextKey) ? [] : {};
144
+ }
145
+ current = current[key];
146
+ }
147
+ }
148
+ };
149
+ for (const [rawKey, rawValue] of Object.entries(query)) {
150
+ const path = [];
151
+ const regex = /([^\[\]]+)|(\[\])/g;
152
+ let match;
153
+ while ((match = regex.exec(rawKey)) !== null) {
154
+ if (match[1])
155
+ path.push(match[1]);
156
+ else if (match[2])
157
+ path.push("");
158
+ }
159
+ if (path.length === 0) {
160
+ if (result[rawKey]) {
161
+ if (Array.isArray(result[rawKey]))
162
+ result[rawKey].push(rawValue);
163
+ else
164
+ result[rawKey] = [result[rawKey], rawValue];
165
+ }
166
+ else {
167
+ result[rawKey] = rawValue;
168
+ }
169
+ }
170
+ else {
171
+ setDeep(result, path, rawValue);
172
+ }
173
+ }
174
+ return result;
175
+ }
176
+ function transformObjectByInstanceToObject(instance, value) {
177
+ return (0, class_transformer_1.instanceToPlain)((0, class_transformer_1.plainToInstance)(instance, value), {
178
+ excludeExtraneousValues: true,
179
+ exposeUnsetFields: true,
180
+ });
181
+ }
182
+ function jsonToJs(value) {
183
+ try {
184
+ return JSON.parse(value);
185
+ }
186
+ catch (err) {
187
+ return false;
188
+ }
189
+ }
190
+ function jsonToInstance(value, instance) {
191
+ try {
192
+ const parsedValue = JSON.parse(value);
193
+ return (0, class_transformer_1.plainToInstance)(instance, parsedValue);
194
+ }
195
+ catch (err) {
196
+ return false;
197
+ }
198
+ }
@@ -0,0 +1,13 @@
1
+ import { Constructor } from "./common-utils";
2
+ export declare const isClassValidator: (target: Constructor) => boolean;
3
+ export declare function getDataType(expectedType: any): any;
4
+ export declare function isValidType(value: any, expectedType: any): boolean;
5
+ export declare function isValidJsonString(value: string): object | boolean;
6
+ export declare const isClassValidatorClass: (target: Constructor) => boolean;
7
+ export declare function validateObjectByInstance(target: Constructor, value?: object, options?: "object" | "array"): Promise<any>;
8
+ type ValidationError = {
9
+ count: number;
10
+ errors: any;
11
+ };
12
+ export declare function validateRequestBody(target: Constructor, value: object, options?: "object" | "array"): ValidationError;
13
+ export {};
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isClassValidatorClass = exports.isClassValidator = void 0;
4
+ exports.getDataType = getDataType;
5
+ exports.isValidType = isValidType;
6
+ exports.isValidJsonString = isValidJsonString;
7
+ exports.validateObjectByInstance = validateObjectByInstance;
8
+ exports.validateRequestBody = validateRequestBody;
9
+ /**
10
+ * @copyright 2024
11
+ * @author Tareq Hossain
12
+ * @email xtrinsic96@gmail.com
13
+ * @url https://github.com/xtareq
14
+ */
15
+ const class_validator_1 = require("class-validator");
16
+ const exceptions_1 = require("../exceptions"); // Need to check path relative to utils
17
+ const class_transformer_1 = require("class-transformer");
18
+ const isClassValidator = (target) => {
19
+ try {
20
+ const clsval = require("class-validator");
21
+ const result = (0, class_validator_1.getMetadataStorage)().getTargetValidationMetadatas(target, "", false, false);
22
+ return result.length > 0;
23
+ }
24
+ catch (err) {
25
+ console.log(err);
26
+ return false;
27
+ }
28
+ };
29
+ exports.isClassValidator = isClassValidator;
30
+ function getDataType(expectedType) {
31
+ switch (expectedType.name) {
32
+ case "Object":
33
+ if (Array.isArray(expectedType)) {
34
+ return "array";
35
+ }
36
+ return "object";
37
+ case "String":
38
+ return "string";
39
+ case "Number":
40
+ return "number";
41
+ case "Boolean":
42
+ return "boolean";
43
+ default:
44
+ return expectedType;
45
+ }
46
+ }
47
+ function isValidType(value, expectedType) {
48
+ if (value === undefined || value === null)
49
+ return true;
50
+ switch (expectedType.name) {
51
+ case "String":
52
+ return typeof value === "string";
53
+ case "Number":
54
+ return typeof value === "number" || !isNaN(Number(value));
55
+ case "Boolean":
56
+ return typeof value === "boolean";
57
+ default:
58
+ return value instanceof expectedType;
59
+ }
60
+ }
61
+ function isValidJsonString(value) {
62
+ try {
63
+ return JSON.parse(value);
64
+ }
65
+ catch (err) {
66
+ return false;
67
+ }
68
+ }
69
+ const isClassValidatorClass = (target) => {
70
+ try {
71
+ const clsval = require("class-validator");
72
+ const result = clsval
73
+ .getMetadataStorage()
74
+ .getTargetValidationMetadatas(target, undefined, false, false);
75
+ return result.length > 0;
76
+ }
77
+ catch (err) {
78
+ return false;
79
+ }
80
+ };
81
+ exports.isClassValidatorClass = isClassValidatorClass;
82
+ async function validateObjectByInstance(target, value = {}, options = "array") {
83
+ try {
84
+ const { validateOrReject } = require("class-validator");
85
+ const { plainToInstance } = require("class-transformer");
86
+ await validateOrReject(plainToInstance(target, value));
87
+ }
88
+ catch (error) {
89
+ if (typeof error == "object" && Array.isArray(error)) {
90
+ const errors = options == "object"
91
+ ? error.reduce((acc, x) => {
92
+ //acc[x.property] = Object.values(x.constraints);
93
+ acc[x.property] = x.constraints;
94
+ return acc;
95
+ }, {})
96
+ : error.map((x) => ({
97
+ path: x.property,
98
+ constraints: x.constraints,
99
+ }));
100
+ return errors;
101
+ }
102
+ else {
103
+ throw new exceptions_1.InternalErrorException("Can't validate object");
104
+ }
105
+ }
106
+ }
107
+ function validateRequestBody(target, value, options = "array") {
108
+ if (!(0, exports.isClassValidatorClass)(target))
109
+ return { count: 0, errors: {} };
110
+ const error = (0, class_validator_1.validateSync)((0, class_transformer_1.plainToInstance)(target, value ? value : {}));
111
+ const errors = options == "object"
112
+ ? error.reduce((acc, x) => {
113
+ //acc[x.property] = Object.values(x.constraints);
114
+ acc[x.property] = x.constraints;
115
+ return acc;
116
+ }, {})
117
+ : error.map((x) => ({ path: x.property, constraints: x.constraints }));
118
+ return { count: error.length, errors };
119
+ }
@@ -90,16 +90,13 @@ const isBool = (val) => {
90
90
  const parseBoolean = (val) => {
91
91
  if (typeof val === "boolean")
92
92
  return val;
93
- // if (typeof val === "number") {
94
- // return val !== 0; // Common convention: 0 → false, any other number → true
95
- // }
96
93
  if (parseInt(val) == 1)
97
94
  return true;
98
95
  if (typeof val === "string") {
99
96
  const normalized = val.trim().toLowerCase();
100
97
  return normalized === "true";
101
98
  }
102
- return false; // Default for unsupported types (null, undefined, objects, etc.)
99
+ return false;
103
100
  };
104
101
  function validateOrThrow(obj, rules, options) {
105
102
  const valid = new Validator(rules, options);
@@ -1,3 +1,6 @@
1
+ import { Server } from "socket.io";
2
+ import { Token } from "typedi";
3
+ export declare const SocketIoServer: Token<Server<import("socket.io").DefaultEventsMap, import("socket.io").DefaultEventsMap, import("socket.io").DefaultEventsMap, any>>;
1
4
  export declare class AvleonSocketIo {
2
5
  private io?;
3
6
  sendToAll(): void;
package/dist/websocket.js CHANGED
@@ -6,8 +6,9 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
6
6
  return c > 3 && r && Object.defineProperty(target, key, r), r;
7
7
  };
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.AvleonSocketIo = void 0;
9
+ exports.AvleonSocketIo = exports.SocketIoServer = void 0;
10
10
  const typedi_1 = require("typedi");
11
+ exports.SocketIoServer = new typedi_1.Token("SocketIoServer");
11
12
  let AvleonSocketIo = class AvleonSocketIo {
12
13
  sendToAll() { }
13
14
  sendOnly() { }
package/package.json CHANGED
@@ -1,35 +1,40 @@
1
1
  {
2
2
  "name": "@avleon/core",
3
- "version": "0.0.45",
3
+ "version": "0.0.46",
4
+ "description": "TypeScript-first web framework built on Fastify",
5
+ "author": "Tareq Hossain",
6
+ "license": "ISC",
4
7
  "main": "./dist/index.js",
5
8
  "types": "./dist/index.d.ts",
9
+ "files": [
10
+ "dist",
11
+ "README.md",
12
+ "LICENSE"
13
+ ],
6
14
  "keywords": [
7
15
  "restapi",
8
16
  "avleon",
9
17
  "backend",
10
- "fastify"
11
- ],
12
- "author": "Tareq Hossain",
13
- "license": "ISC",
14
- "description": "avleon core",
15
- "repository": {
16
- "type": "git",
17
- "url": "git+https://github.com/avleonjs/avleon-core"
18
- },
19
- "files": [
20
- "dist"
18
+ "fastify",
19
+ "typescript"
21
20
  ],
22
- "directories": {
23
- "test": "."
21
+ "scripts": {
22
+ "build": "npm run clean && tsc",
23
+ "clean": "rimraf dist",
24
+ "prepublishOnly": "npm run build",
25
+ "watch": "tsc-watch",
26
+ "lint": "eslint .",
27
+ "lint:fix": "eslint . --fix",
28
+ "format": "prettier --write .",
29
+ "test": "jest",
30
+ "test:watch": "jest --watch",
31
+ "husky:init": "husky install"
24
32
  },
25
33
  "dependencies": {
26
- "bull": "^4.16.5",
27
34
  "class-transformer": "^0.5.1",
28
35
  "class-validator": "^0.14.2",
29
36
  "fastify": "^5.1.0",
30
- "mime": "^4.1.0",
31
- "pino": "^9.10.0",
32
- "pino-pretty": "^13.1.1",
37
+ "mime": "^3.0.0",
33
38
  "reflect-metadata": "^0.2.2",
34
39
  "typedi": "^0.10.0"
35
40
  },
@@ -42,23 +47,23 @@
42
47
  "@fastify/view": "^11.0.0",
43
48
  "@scalar/fastify-api-reference": "*",
44
49
  "bcryptjs": "3.0.2",
50
+ "bull": "^4.16.5",
45
51
  "dotenv": "*",
46
52
  "fastify-socket.io": "^4.0.0",
47
53
  "highlight.js": "*",
48
54
  "ioredis": "*",
49
55
  "knex": "*",
50
- "mssql": "*",
56
+ "mssql": ">=9.0.0",
51
57
  "mysql2": "*",
52
58
  "pg": "*",
59
+ "pino": "^9.0.0",
60
+ "pino-pretty": "^13.0.0",
53
61
  "sharp": "*",
54
62
  "socket.io": "*",
55
63
  "sqlite3": "*",
56
64
  "typeorm": "*"
57
65
  },
58
66
  "peerDependenciesMeta": {
59
- "bcryptjs": {
60
- "optional": true
61
- },
62
67
  "@fastify/cors": {
63
68
  "optional": true
64
69
  },
@@ -80,13 +85,22 @@
80
85
  "@scalar/fastify-api-reference": {
81
86
  "optional": true
82
87
  },
83
- "ioredis": {
88
+ "bcryptjs": {
84
89
  "optional": true
85
90
  },
86
- "sharp": {
91
+ "bull": {
87
92
  "optional": true
88
93
  },
89
- "typeorm": {
94
+ "dotenv": {
95
+ "optional": true
96
+ },
97
+ "fastify-socket.io": {
98
+ "optional": true
99
+ },
100
+ "highlight.js": {
101
+ "optional": true
102
+ },
103
+ "ioredis": {
90
104
  "optional": true
91
105
  },
92
106
  "knex": {
@@ -101,19 +115,22 @@
101
115
  "pg": {
102
116
  "optional": true
103
117
  },
104
- "sqlite3": {
118
+ "pino": {
105
119
  "optional": true
106
120
  },
107
- "fastify-socket.io": {
121
+ "pino-pretty": {
122
+ "optional": true
123
+ },
124
+ "sharp": {
108
125
  "optional": true
109
126
  },
110
127
  "socket.io": {
111
128
  "optional": true
112
129
  },
113
- "dotenv": {
130
+ "sqlite3": {
114
131
  "optional": true
115
132
  },
116
- "highlight.js": {
133
+ "typeorm": {
117
134
  "optional": true
118
135
  }
119
136
  },
@@ -141,15 +158,11 @@
141
158
  "cross-env CI=true jest --bail --findRelatedTests --passWithNoTests --config=jest.config.js"
142
159
  ]
143
160
  },
144
- "scripts": {
145
- "build": "npm run clean && tsc",
146
- "clean": "rimraf dist",
147
- "watch": "tsc-watch",
148
- "lint": "eslint .",
149
- "lint:fix": "eslint . --fix",
150
- "format": "prettier --write .",
151
- "test": "jest",
152
- "test:watch": "jest --watch",
153
- "husky:init": "husky install"
161
+ "repository": {
162
+ "type": "git",
163
+ "url": "git+https://github.com/avleonjs/avleon-core"
164
+ },
165
+ "publishConfig": {
166
+ "access": "public"
154
167
  }
155
- }
168
+ }
@@ -1,47 +0,0 @@
1
- import { Constructor } from "./helpers";
2
- import { RouteShorthandMethod } from "fastify";
3
- export interface AvleonApplication {
4
- useCors: () => void;
5
- useOpenApi: () => void;
6
- useView: () => void;
7
- useAuth: () => void;
8
- useMultipart: () => void;
9
- useDataSource: () => void;
10
- useMiddlewares: () => void;
11
- useControllers: () => void;
12
- useAutoControllers: () => void;
13
- useStaticFiles: () => void;
14
- useCustomErrorHandler: () => void;
15
- mapGroup: () => any;
16
- mapGet: () => any;
17
- mapPost: () => any;
18
- mapPut: () => any;
19
- mapPatch: () => any;
20
- mapDelete: () => any;
21
- mapView: () => any;
22
- run: (port: number) => void;
23
- }
24
- export interface InlineRoutes {
25
- get: RouteShorthandMethod;
26
- post: RouteShorthandMethod;
27
- put: RouteShorthandMethod;
28
- patch: RouteShorthandMethod;
29
- delete: RouteShorthandMethod;
30
- }
31
- export interface Application {
32
- inlineRoutes: () => InlineRoutes;
33
- mapGroup: (path?: string | RegExp) => InlineRoutes;
34
- /**
35
- * Start the application
36
- * @param port
37
- * @returns void
38
- */
39
- start: (port?: number) => void;
40
- }
41
- export interface TestApplication {
42
- getController: <T>(controller: Constructor<T>) => T;
43
- }
44
- export declare class Builder {
45
- static createApplication(): Application;
46
- static createTestApplication(app?: Application): TestApplication;
47
- }
@@ -1,50 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.Builder = void 0;
7
- const typedi_1 = __importDefault(require("typedi"));
8
- const fastify_1 = __importDefault(require("fastify"));
9
- class IqraTestApplication {
10
- getController(controller) {
11
- const con = typedi_1.default.get(controller);
12
- return con;
13
- }
14
- }
15
- class IqraApplication {
16
- constructor() {
17
- if (!this.app) {
18
- this.app = fastify_1.default.prototype;
19
- }
20
- }
21
- inlineRoutes() {
22
- return {
23
- get: this.app.get,
24
- post: this.app.post,
25
- put: this.app.put,
26
- patch: this.app.patch,
27
- delete: this.app.delete,
28
- };
29
- }
30
- mapGroup(path) {
31
- return this.inlineRoutes();
32
- }
33
- start(port) {
34
- const p = port ? port : 4000;
35
- this.app.listen({ port: p });
36
- }
37
- }
38
- class Builder {
39
- static createApplication() {
40
- const app = new IqraApplication();
41
- return app;
42
- }
43
- static createTestApplication(app) {
44
- const testApp = new IqraTestApplication();
45
- return testApp;
46
- }
47
- }
48
- exports.Builder = Builder;
49
- const app = Builder.createApplication();
50
- const route = app.inlineRoutes();