@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,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const testing_1 = require("./core/testing");
4
+ const application_1 = require("./core/application");
5
+ describe("Avleon.createApplication", () => {
6
+ it("should return an instance of AvleonApplication", () => {
7
+ const app = testing_1.Avleon.createApplication();
8
+ expect(app).toBeInstanceOf(application_1.AvleonApplication);
9
+ });
10
+ it("should always return the same instance (singleton)", () => {
11
+ const app1 = testing_1.Avleon.createApplication();
12
+ const app2 = testing_1.Avleon.createApplication();
13
+ expect(app1).toBe(app2);
14
+ });
15
+ });
@@ -42,7 +42,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
42
42
  require("reflect-metadata");
43
43
  const controller_1 = require("./controller");
44
44
  const containerModule = __importStar(require("./container"));
45
- const typedi_1 = require("typedi");
46
45
  describe("Controller Decorators", () => {
47
46
  beforeEach(() => {
48
47
  jest.clearAllMocks();
@@ -94,18 +93,5 @@ describe("Controller Decorators", () => {
94
93
  options,
95
94
  });
96
95
  });
97
- const originalService = typedi_1.Service;
98
- // @ts-ignore
99
- containerModule.Service = undefined;
100
- expect(() => {
101
- let TestController = class TestController {
102
- };
103
- TestController = __decorate([
104
- controller_1.ApiController
105
- ], TestController);
106
- }).toThrow("Service decorator is not a function");
107
- // Restore
108
- // @ts-ignore
109
- containerModule.Service = originalService;
110
96
  });
111
97
  });
@@ -0,0 +1,74 @@
1
+ /**
2
+ * @copyright 2024
3
+ * @author Tareq Hossain
4
+ * @email xtrinsic96@gmail.com
5
+ * @url https://github.com/xtareq
6
+ */
7
+ import { FastifyInstance } from "fastify";
8
+ import "@fastify/swagger";
9
+ import { IAvleonApplication, AvleonApplicationOptions, CorsOptions, GlobalOptions } from "../interfaces/avleon-application";
10
+ import { Constructor } from "../helpers";
11
+ import { OpenApiUiOptions } from "../openapi";
12
+ import { DataSource } from "typeorm";
13
+ import { AvleonMiddleware } from "../middleware";
14
+ import { AutoControllerOptions } from "./types";
15
+ export declare class AvleonApplication implements IAvleonApplication {
16
+ app: FastifyInstance;
17
+ private router;
18
+ private static instance;
19
+ private alreadyRun;
20
+ private hasSwagger;
21
+ private globalSwaggerOptions;
22
+ private dataSourceOptions;
23
+ private dataSource;
24
+ private isMapFeatures;
25
+ private registerControllerAuto;
26
+ private registerControllerPath;
27
+ private controllers;
28
+ private _hasWebsocket;
29
+ private io;
30
+ private constructor();
31
+ static getApp(options?: AvleonApplicationOptions): AvleonApplication;
32
+ /**
33
+ * @deprecated Use `getApp` instead. This is internal.
34
+ */
35
+ static getInternalApp(options?: AvleonApplicationOptions): AvleonApplication;
36
+ useCors(options: CorsOptions): this;
37
+ useDatasource(dataSource: DataSource): this;
38
+ useMultipart(options?: any): this;
39
+ useOpenApi(options: OpenApiUiOptions): this;
40
+ private initSwagger;
41
+ useMiddlewares(middlewares: Constructor<AvleonMiddleware>[]): this;
42
+ useAuthorization(authorization: Constructor<any>): this;
43
+ useSerialization(): this;
44
+ useControllers(controllers: Constructor[] | AutoControllerOptions): this;
45
+ useStaticFiles(options: any): this;
46
+ useHttps(options?: any): this;
47
+ useGlobal(options: GlobalOptions): this;
48
+ useSocketIo(options?: any): this;
49
+ useKnex(options: any): this;
50
+ mapFeatures(): this;
51
+ private _mapControllers;
52
+ private _resolveControllerDir;
53
+ private autoControllers;
54
+ private _mapFeatures;
55
+ initializeDatabase(): Promise<void>;
56
+ handleSocket(socket: any): void;
57
+ mapGet<T extends (...args: any[]) => any>(path: string | undefined, fn: T): {
58
+ useMiddleware: <M extends AvleonMiddleware>(middlewares: Constructor<AvleonMiddleware>[]) => /*elided*/ any;
59
+ useOpenApi: (options: import("../openapi").OpenApiOptions) => /*elided*/ any;
60
+ };
61
+ mapPost<T extends (...args: any[]) => any>(path: string | undefined, fn: T): {
62
+ useMiddleware: <M extends AvleonMiddleware>(middlewares: Constructor<AvleonMiddleware>[]) => /*elided*/ any;
63
+ useOpenApi: (options: import("../openapi").OpenApiOptions) => /*elided*/ any;
64
+ };
65
+ mapPut<T extends (...args: any[]) => any>(path: string | undefined, fn: T): {
66
+ useMiddleware: <M extends AvleonMiddleware>(middlewares: Constructor<AvleonMiddleware>[]) => /*elided*/ any;
67
+ useOpenApi: (options: import("../openapi").OpenApiOptions) => /*elided*/ any;
68
+ };
69
+ mapDelete<T extends (...args: any[]) => any>(path: string | undefined, fn: T): {
70
+ useMiddleware: <M extends AvleonMiddleware>(middlewares: Constructor<AvleonMiddleware>[]) => /*elided*/ any;
71
+ useOpenApi: (options: import("../openapi").OpenApiOptions) => /*elided*/ any;
72
+ };
73
+ run(port?: number, fn?: CallableFunction): Promise<void>;
74
+ }
@@ -0,0 +1,424 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.AvleonApplication = void 0;
40
+ /**
41
+ * @copyright 2024
42
+ * @author Tareq Hossain
43
+ * @email xtrinsic96@gmail.com
44
+ * @url https://github.com/xtareq
45
+ */
46
+ const fastify_1 = __importDefault(require("fastify"));
47
+ require("@fastify/swagger");
48
+ const path_1 = __importDefault(require("path"));
49
+ const fs_1 = __importDefault(require("fs"));
50
+ const router_1 = require("./router");
51
+ const typedi_1 = __importDefault(require("typedi"));
52
+ const exceptions_1 = require("../exceptions");
53
+ const system_exception_1 = require("../exceptions/system-exception");
54
+ const swagger_schema_1 = require("../swagger-schema");
55
+ const typeorm_1 = require("typeorm");
56
+ const kenx_provider_1 = require("../kenx-provider");
57
+ const event_dispatcher_1 = require("../event-dispatcher");
58
+ const event_subscriber_1 = require("../event-subscriber");
59
+ const websocket_1 = require("../websocket");
60
+ const container_1 = require("../container");
61
+ class AvleonApplication {
62
+ constructor(options) {
63
+ var _a;
64
+ this.alreadyRun = false;
65
+ this.hasSwagger = false;
66
+ this.dataSourceOptions = null;
67
+ this.dataSource = null;
68
+ this.isMapFeatures = false;
69
+ this.registerControllerAuto = false;
70
+ this.registerControllerPath = "src/controllers";
71
+ this.controllers = [];
72
+ this._hasWebsocket = false;
73
+ this.app = (0, fastify_1.default)({
74
+ ...options === null || options === void 0 ? void 0 : options.server,
75
+ ajv: {
76
+ customOptions: {
77
+ strict: false, // allows `example`, `examples` and other OpenAPI keywords
78
+ },
79
+ ...(_a = options === null || options === void 0 ? void 0 : options.server) === null || _a === void 0 ? void 0 : _a.ajv,
80
+ },
81
+ });
82
+ this.router = new router_1.AvleonRouter(this.app);
83
+ if (options === null || options === void 0 ? void 0 : options.dataSourceOptions) {
84
+ this.dataSourceOptions = options.dataSourceOptions;
85
+ if (this.dataSourceOptions) {
86
+ this.dataSource = new typeorm_1.DataSource(this.dataSourceOptions);
87
+ typedi_1.default.set(typeorm_1.DataSource, this.dataSource);
88
+ }
89
+ }
90
+ }
91
+ static getApp(options) {
92
+ if (!AvleonApplication.instance) {
93
+ AvleonApplication.instance = new AvleonApplication(options);
94
+ }
95
+ return AvleonApplication.instance;
96
+ }
97
+ /**
98
+ * @deprecated Use `getApp` instead. This is internal.
99
+ */
100
+ static getInternalApp(options) {
101
+ return new AvleonApplication(options);
102
+ }
103
+ useCors(options) {
104
+ this.app.register(require("@fastify/cors"), options);
105
+ return this;
106
+ }
107
+ useDatasource(dataSource) {
108
+ this.dataSource = dataSource;
109
+ typedi_1.default.set(typeorm_1.DataSource, this.dataSource);
110
+ return this;
111
+ }
112
+ useMultipart(options) {
113
+ this.app.register(require("@fastify/multipart"), {
114
+ attachFieldsToBody: true,
115
+ limits: {
116
+ fileSize: 10 * 1024 * 1024, // 10MB default
117
+ },
118
+ ...options,
119
+ });
120
+ return this;
121
+ }
122
+ useOpenApi(options) {
123
+ this.hasSwagger = true;
124
+ this.globalSwaggerOptions = options;
125
+ return this;
126
+ }
127
+ async initSwagger(options) {
128
+ var _a, _b, _c;
129
+ const safeControllers = ((_a = this.controllers) !== null && _a !== void 0 ? _a : []).filter((c) => c != null && typeof c === "function");
130
+ const baseSchema = (0, swagger_schema_1.generateSwaggerSchema)(safeControllers);
131
+ await this.app.register(require("@fastify/swagger"), {
132
+ openapi: {
133
+ ...baseSchema,
134
+ info: (options === null || options === void 0 ? void 0 : options.info) || { title: "API", version: "1.0.0" },
135
+ servers: options === null || options === void 0 ? void 0 : options.servers,
136
+ tags: options === null || options === void 0 ? void 0 : options.tags,
137
+ components: {
138
+ ...baseSchema === null || baseSchema === void 0 ? void 0 : baseSchema.components,
139
+ ...options === null || options === void 0 ? void 0 : options.components,
140
+ schemas: {
141
+ ...(_b = baseSchema === null || baseSchema === void 0 ? void 0 : baseSchema.components) === null || _b === void 0 ? void 0 : _b.schemas,
142
+ ...(_c = options === null || options === void 0 ? void 0 : options.components) === null || _c === void 0 ? void 0 : _c.schemas,
143
+ },
144
+ },
145
+ security: options === null || options === void 0 ? void 0 : options.security,
146
+ externalDocs: options === null || options === void 0 ? void 0 : options.externalDocs,
147
+ },
148
+ });
149
+ const routePrefix = (options === null || options === void 0 ? void 0 : options.routePrefix) || "/swagger";
150
+ if ((options === null || options === void 0 ? void 0 : options.provider) === "scalar") {
151
+ await this.app.register(require("@scalar/fastify-api-reference"), {
152
+ routePrefix,
153
+ configuration: {
154
+ spec: {
155
+ content: () => this.app.swagger(),
156
+ },
157
+ ...options === null || options === void 0 ? void 0 : options.uiConfig,
158
+ },
159
+ });
160
+ }
161
+ else {
162
+ await this.app.register(require("@fastify/swagger-ui"), {
163
+ routePrefix,
164
+ uiConfig: {
165
+ docExpansion: "full",
166
+ deepLinking: false,
167
+ ...options === null || options === void 0 ? void 0 : options.uiConfig,
168
+ },
169
+ uiHooks: {
170
+ onRequest: function (request, reply, next) {
171
+ next();
172
+ },
173
+ preHandler: function (request, reply, next) {
174
+ next();
175
+ },
176
+ },
177
+ staticCSP: true,
178
+ transformSpecificationClone: true,
179
+ });
180
+ }
181
+ }
182
+ useMiddlewares(middlewares) {
183
+ middlewares.forEach((m) => {
184
+ const cls = typedi_1.default.get(m);
185
+ this.app.addHook("preHandler", async (req, res) => {
186
+ await cls.invoke(req, res);
187
+ });
188
+ });
189
+ return this;
190
+ }
191
+ useAuthorization(authorization) {
192
+ this.router.setAuthorizeMiddleware(authorization);
193
+ return this;
194
+ }
195
+ useSerialization() {
196
+ // Implementation if needed, currently seemingly handled elsewhere or default
197
+ return this;
198
+ }
199
+ useControllers(controllers) {
200
+ if (Array.isArray(controllers)) {
201
+ this.controllers = controllers;
202
+ // Dedupe
203
+ controllers.forEach((controller) => {
204
+ if (!this.controllers.includes(controller)) {
205
+ this.controllers.push(controller);
206
+ }
207
+ });
208
+ }
209
+ else {
210
+ this.registerControllerAuto = true;
211
+ if (controllers.path) {
212
+ this.registerControllerPath = controllers.path;
213
+ }
214
+ }
215
+ return this;
216
+ }
217
+ useStaticFiles(options) {
218
+ this.app.register(require("@fastify/static"), options);
219
+ return this;
220
+ }
221
+ useHttps(options) {
222
+ // Fastify handles https via server options usually, but if this is strictly for https
223
+ // this might need logic. Original icore didn't show body for this.
224
+ return this;
225
+ }
226
+ useGlobal(options) {
227
+ if (options.cors)
228
+ this.useCors(options.cors);
229
+ if (options.openApi)
230
+ this.useOpenApi(options.openApi);
231
+ if (options.controllers)
232
+ this.useControllers(options.controllers);
233
+ if (options.middlewares)
234
+ this.useMiddlewares(options.middlewares);
235
+ if (options.authorization)
236
+ this.useAuthorization(options.authorization);
237
+ if (options.multipart)
238
+ this.useMultipart(options.multipart);
239
+ if (options.staticFiles)
240
+ this.useStaticFiles(options.staticFiles);
241
+ return this;
242
+ }
243
+ useSocketIo(options) {
244
+ this._hasWebsocket = true;
245
+ this.app.register(require("fastify-socket.io"), options);
246
+ return this;
247
+ }
248
+ useKnex(options) {
249
+ const db = typedi_1.default.get(kenx_provider_1.DB);
250
+ db.init(options.config);
251
+ return this;
252
+ }
253
+ mapFeatures() {
254
+ this.isMapFeatures = true;
255
+ return this;
256
+ }
257
+ async _mapControllers() {
258
+ if (this.controllers.length > 0) {
259
+ for (let controller of this.controllers) {
260
+ if ((0, container_1.isApiController)(controller)) {
261
+ await this.router.buildController(controller);
262
+ }
263
+ else {
264
+ throw new system_exception_1.SystemUseError("Not a api controller.");
265
+ }
266
+ }
267
+ }
268
+ }
269
+ // Auto controller discovery logic
270
+ _resolveControllerDir(dir) {
271
+ const isTsNode = process.env.TS_NODE_DEV ||
272
+ process.env.TS_NODE_PROJECT ||
273
+ process[Symbol.for("ts-node.register.instance")];
274
+ const controllerDir = path_1.default.join(process.cwd(), this.registerControllerPath);
275
+ return isTsNode ? controllerDir : controllerDir.replace("src", "dist");
276
+ }
277
+ async autoControllers(controllersPath) {
278
+ const conDir = this._resolveControllerDir(controllersPath);
279
+ // This relies on isTsNode logic which we might want to clean up, but keeping for parity
280
+ const isTsNode = process.env.TS_NODE_DEV ||
281
+ process.env.TS_NODE_PROJECT ||
282
+ process[Symbol.for("ts-node.register.instance")];
283
+ try {
284
+ const files = await fs_1.default.readdirSync(conDir, { recursive: true, encoding: 'utf-8' }); // recursive readdir is node 20+
285
+ for (const file of files) {
286
+ const isTestFile = /\.(test|spec|e2e-spec)\.ts$/.test(file);
287
+ if (isTestFile)
288
+ continue;
289
+ if (isTsNode ? file.endsWith(".ts") : file.endsWith(".js")) {
290
+ const filePath = path_1.default.join(conDir, file);
291
+ // Dynamically import
292
+ const module = await Promise.resolve(`${filePath}`).then(s => __importStar(require(s)));
293
+ for (const exported of Object.values(module)) {
294
+ if (typeof exported === "function" && (0, container_1.isApiController)(exported)) {
295
+ // double check if constructor
296
+ if (!this.controllers.some((con) => exported.name == con.name)) {
297
+ this.controllers.push(exported);
298
+ }
299
+ }
300
+ }
301
+ }
302
+ }
303
+ }
304
+ catch (e) {
305
+ console.warn("Could not auto-register controllers from " + conDir, e);
306
+ }
307
+ }
308
+ _mapFeatures() {
309
+ // Placeholder as per original
310
+ const features = typedi_1.default.get("features");
311
+ }
312
+ async initializeDatabase() {
313
+ if (this.dataSourceOptions && this.dataSource) {
314
+ await this.dataSource.initialize();
315
+ }
316
+ }
317
+ handleSocket(socket) {
318
+ const contextService = typedi_1.default.get(event_dispatcher_1.SocketContextService);
319
+ const subscriberRegistry = typedi_1.default.get(event_subscriber_1.EventSubscriberRegistry);
320
+ subscriberRegistry.register(socket);
321
+ // Wrap all future event handlers with context
322
+ const originalOn = socket.on.bind(socket);
323
+ socket.on = (event, handler) => {
324
+ return originalOn(event, (...args) => {
325
+ contextService.run(socket, () => handler(...args));
326
+ });
327
+ };
328
+ }
329
+ // Proxy routing methods to Router for functional usage
330
+ mapGet(path = "", fn) {
331
+ return this.router.mapGet(path, fn);
332
+ }
333
+ mapPost(path = "", fn) {
334
+ return this.router.mapPost(path, fn);
335
+ }
336
+ mapPut(path = "", fn) {
337
+ return this.router.mapPut(path, fn);
338
+ }
339
+ mapDelete(path = "", fn) {
340
+ return this.router.mapDelete(path, fn);
341
+ }
342
+ async run(port = 4000, fn) {
343
+ if (this.alreadyRun)
344
+ throw new system_exception_1.SystemUseError("App already running");
345
+ this.alreadyRun = true;
346
+ if (this.hasSwagger) {
347
+ await this.initSwagger(this.globalSwaggerOptions);
348
+ }
349
+ await this.initializeDatabase();
350
+ if (this.isMapFeatures) {
351
+ this._mapFeatures();
352
+ }
353
+ if (this.registerControllerAuto) {
354
+ await this.autoControllers();
355
+ }
356
+ await this._mapControllers();
357
+ // Process functional routes if any were added to router
358
+ this.router.processFunctionalRoutes();
359
+ this.app.setErrorHandler((error, request, reply) => {
360
+ var _a;
361
+ const isDev = process.env.NODE_ENV === "development";
362
+ const timestamp = new Date().toISOString();
363
+ const requestInfo = `${request.method} ${request.url}`;
364
+ if (error instanceof exceptions_1.BaseHttpException) {
365
+ // ✅ Expected HTTP errors — compact one-liner
366
+ console.warn(`[${timestamp}] HTTP ${error.code} ${requestInfo} — ${error.message}`);
367
+ return reply
368
+ .status(error.code || 500)
369
+ .type("application/json")
370
+ .serializer((payload) => JSON.stringify(payload))
371
+ .send({
372
+ code: error.code,
373
+ status: "Error",
374
+ message: error.message,
375
+ data: error.payload,
376
+ });
377
+ }
378
+ // ✅ Unexpected errors — full details
379
+ console.error(`\n❌ UNHANDLED ERROR @ ${timestamp}`);
380
+ console.error(` ${requestInfo}`);
381
+ console.error(` ${error.name}: ${error.message}`);
382
+ if (error.stack) {
383
+ console.error(` Stack:\n${error.stack
384
+ .split("\n")
385
+ .slice(1) // skip first line (duplicate of message)
386
+ .map((l) => ` ${l.trim()}`)
387
+ .join("\n")}`);
388
+ }
389
+ if (isDev) {
390
+ console.error(` Params:`, JSON.stringify(request.params));
391
+ console.error(` Query: `, JSON.stringify(request.query));
392
+ console.error(` Body: `, JSON.stringify(request.body));
393
+ }
394
+ console.error(""); // blank line for readability
395
+ return reply.status(500).send({
396
+ code: 500,
397
+ status: "Error",
398
+ message: isDev ? error.message : "Internal Server Error",
399
+ ...(isDev && {
400
+ error: error.name,
401
+ stack: (_a = error.stack) === null || _a === void 0 ? void 0 : _a.split("\n").slice(0, 5), // first 5 lines only
402
+ }),
403
+ });
404
+ });
405
+ await this.app.ready();
406
+ if (this._hasWebsocket) {
407
+ // @ts-ignore
408
+ if (!this.app.io) {
409
+ throw new Error("Socket.IO not initialized. Make sure fastify-socket.io is registered correctly.");
410
+ }
411
+ // Register the io instance in Container
412
+ // @ts-ignore
413
+ typedi_1.default.set(websocket_1.SocketIoServer, this.app.io);
414
+ // Then register connection handler
415
+ // @ts-ignore
416
+ await this.app.io.on("connection", this.handleSocket.bind(this));
417
+ }
418
+ await this.app.listen({ port });
419
+ console.log(`Application running on http://127.0.0.1:${port}`);
420
+ if (fn)
421
+ fn();
422
+ }
423
+ }
424
+ exports.AvleonApplication = AvleonApplication;
@@ -0,0 +1,44 @@
1
+ /**
2
+ * @copyright 2024
3
+ * @author Tareq Hossain
4
+ * @email xtrinsic96@gmail.com
5
+ * @url https://github.com/xtareq
6
+ */
7
+ import { Constructor } from "../helpers";
8
+ import { AvleonMiddleware } from "../middleware";
9
+ import { OpenApiOptions } from "../openapi";
10
+ import { FastifyInstance } from "fastify";
11
+ export declare class AvleonRouter {
12
+ private routeSet;
13
+ private metaCache;
14
+ private middlewares;
15
+ private rMap;
16
+ private app;
17
+ private authorizeMiddleware?;
18
+ constructor(app: FastifyInstance);
19
+ setAuthorizeMiddleware(middleware: Constructor<any>): void;
20
+ registerMiddleware(name: string, instance: AvleonMiddleware): void;
21
+ private _processMeta;
22
+ private executeMiddlewares;
23
+ buildController(controller: any): Promise<void>;
24
+ private _mapArgs;
25
+ private _routeHandler;
26
+ mapGet<T extends (...args: any[]) => any>(path: string | undefined, fn: T): {
27
+ useMiddleware: <M extends AvleonMiddleware>(middlewares: Constructor<AvleonMiddleware>[]) => /*elided*/ any;
28
+ useOpenApi: (options: OpenApiOptions) => /*elided*/ any;
29
+ };
30
+ mapPost<T extends (...args: any[]) => any>(path: string | undefined, fn: T): {
31
+ useMiddleware: <M extends AvleonMiddleware>(middlewares: Constructor<AvleonMiddleware>[]) => /*elided*/ any;
32
+ useOpenApi: (options: OpenApiOptions) => /*elided*/ any;
33
+ };
34
+ mapPut<T extends (...args: any[]) => any>(path: string | undefined, fn: T): {
35
+ useMiddleware: <M extends AvleonMiddleware>(middlewares: Constructor<AvleonMiddleware>[]) => /*elided*/ any;
36
+ useOpenApi: (options: OpenApiOptions) => /*elided*/ any;
37
+ };
38
+ mapDelete<T extends (...args: any[]) => any>(path: string | undefined, fn: T): {
39
+ useMiddleware: <M extends AvleonMiddleware>(middlewares: Constructor<AvleonMiddleware>[]) => /*elided*/ any;
40
+ useOpenApi: (options: OpenApiOptions) => /*elided*/ any;
41
+ };
42
+ mapRoute<T extends (...args: any[]) => any>(method: "get" | "post" | "put" | "delete", path: string | undefined, fn: T): Promise<void>;
43
+ processFunctionalRoutes(): void;
44
+ }