exisjs 0.7.8 → 0.7.9

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 (79) hide show
  1. package/dist/cli/commands/dev.d.ts.map +1 -1
  2. package/dist/cli/commands/dev.js +14 -4
  3. package/dist/cli/commands/dev.js.map +1 -1
  4. package/dist/cli/resolve-aliases.js +1 -1
  5. package/dist/cli/resolve-aliases.js.map +1 -1
  6. package/dist/decorators/caching.d.ts +53 -0
  7. package/dist/decorators/caching.d.ts.map +1 -0
  8. package/dist/decorators/caching.js +154 -0
  9. package/dist/decorators/caching.js.map +1 -0
  10. package/dist/decorators/constants.d.ts +4 -0
  11. package/dist/decorators/constants.d.ts.map +1 -1
  12. package/dist/decorators/constants.js +5 -1
  13. package/dist/decorators/constants.js.map +1 -1
  14. package/dist/decorators/filters.d.ts +37 -0
  15. package/dist/decorators/filters.d.ts.map +1 -0
  16. package/dist/decorators/filters.js +30 -0
  17. package/dist/decorators/filters.js.map +1 -0
  18. package/dist/decorators/index.d.ts +6 -0
  19. package/dist/decorators/index.d.ts.map +1 -1
  20. package/dist/decorators/index.js +6 -0
  21. package/dist/decorators/index.js.map +1 -1
  22. package/dist/decorators/lifecycle.d.ts +37 -0
  23. package/dist/decorators/lifecycle.d.ts.map +1 -0
  24. package/dist/decorators/lifecycle.js +3 -0
  25. package/dist/decorators/lifecycle.js.map +1 -0
  26. package/dist/decorators/middleware.d.ts +24 -3
  27. package/dist/decorators/middleware.d.ts.map +1 -1
  28. package/dist/decorators/middleware.js +24 -3
  29. package/dist/decorators/middleware.js.map +1 -1
  30. package/dist/decorators/params.d.ts.map +1 -1
  31. package/dist/decorators/params.js +1 -7
  32. package/dist/decorators/params.js.map +1 -1
  33. package/dist/decorators/profile.d.ts +32 -0
  34. package/dist/decorators/profile.d.ts.map +1 -0
  35. package/dist/decorators/profile.js +61 -0
  36. package/dist/decorators/profile.js.map +1 -0
  37. package/dist/decorators/response.d.ts +0 -1
  38. package/dist/decorators/response.d.ts.map +1 -1
  39. package/dist/decorators/response.js +1 -18
  40. package/dist/decorators/response.js.map +1 -1
  41. package/dist/decorators/routing.d.ts +22 -12
  42. package/dist/decorators/routing.d.ts.map +1 -1
  43. package/dist/decorators/routing.js +49 -3
  44. package/dist/decorators/routing.js.map +1 -1
  45. package/dist/decorators/security.d.ts +42 -0
  46. package/dist/decorators/security.d.ts.map +1 -0
  47. package/dist/decorators/security.js +110 -0
  48. package/dist/decorators/security.js.map +1 -0
  49. package/dist/decorators/transaction.d.ts +29 -0
  50. package/dist/decorators/transaction.d.ts.map +1 -0
  51. package/dist/decorators/transaction.js +91 -0
  52. package/dist/decorators/transaction.js.map +1 -0
  53. package/dist/di/container.d.ts +2 -0
  54. package/dist/di/container.d.ts.map +1 -1
  55. package/dist/di/container.js +30 -0
  56. package/dist/di/container.js.map +1 -1
  57. package/dist/docs/content/decorators.mdx +89 -4
  58. package/dist/docs/content/errors.mdx +29 -13
  59. package/dist/docs/content/providers.mdx +48 -0
  60. package/dist/docs/reference/decorators.mdx +27 -4
  61. package/dist/docs/reference/di.mdx +26 -0
  62. package/dist/error/errors.d.ts +24 -12
  63. package/dist/error/errors.d.ts.map +1 -1
  64. package/dist/error/errors.js +36 -12
  65. package/dist/error/errors.js.map +1 -1
  66. package/dist/router/controller-registrar.d.ts.map +1 -1
  67. package/dist/router/controller-registrar.js +75 -7
  68. package/dist/router/controller-registrar.js.map +1 -1
  69. package/dist/server/app.d.ts.map +1 -1
  70. package/dist/server/app.js +2 -0
  71. package/dist/server/app.js.map +1 -1
  72. package/dist/testing/client.d.ts +1 -1
  73. package/dist/testing/client.d.ts.map +1 -1
  74. package/dist/testing/client.js +30 -15
  75. package/dist/testing/client.js.map +1 -1
  76. package/dist/testing/index.d.ts.map +1 -1
  77. package/dist/testing/index.js +10 -0
  78. package/dist/testing/index.js.map +1 -1
  79. package/package.json +1 -1
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AllowAnonymous = exports.IsPublic = void 0;
4
+ exports.Permissions = Permissions;
5
+ exports.Roles = Roles;
6
+ exports.Public = Public;
7
+ const constants_1 = require("./constants");
8
+ const metadata_1 = require("./core/metadata");
9
+ /**
10
+ * Declares required permission keys for a Controller class or route method.
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * @Controller('/roles')
15
+ * export class RolesController {
16
+ * @Post('/')
17
+ * @Permissions('role:create', 'role:manage')
18
+ * async createRole() {}
19
+ * }
20
+ * ```
21
+ */
22
+ function Permissions(...permissions) {
23
+ return function (target, contextOrPropertyKey, descriptor) {
24
+ const isStandard = typeof contextOrPropertyKey === 'object' && contextOrPropertyKey !== null;
25
+ const kind = isStandard ? contextOrPropertyKey.kind : undefined;
26
+ if (kind === 'class' ||
27
+ (!isStandard && typeof target === 'function' && !contextOrPropertyKey)) {
28
+ const proto = target.prototype || target;
29
+ metadata_1.MetadataEngine.set(proto, constants_1.PERMISSIONS_METADATA, permissions);
30
+ }
31
+ else {
32
+ const fn = isStandard
33
+ ? target
34
+ : descriptor
35
+ ? descriptor.value
36
+ : target[contextOrPropertyKey];
37
+ metadata_1.MetadataEngine.set(fn, constants_1.PERMISSIONS_METADATA, permissions);
38
+ const routeMeta = metadata_1.MetadataEngine.init(fn, constants_1.ROUTE_METADATA_PROP, {});
39
+ routeMeta.permissions = [...(routeMeta.permissions || []), ...permissions];
40
+ }
41
+ };
42
+ }
43
+ /**
44
+ * Declares required roles for a Controller class or route method.
45
+ *
46
+ * @example
47
+ * ```ts
48
+ * @Controller('/admin')
49
+ * @Roles('admin', 'superadmin')
50
+ * export class AdminController {}
51
+ * ```
52
+ */
53
+ function Roles(...roles) {
54
+ return function (target, contextOrPropertyKey, descriptor) {
55
+ const isStandard = typeof contextOrPropertyKey === 'object' && contextOrPropertyKey !== null;
56
+ const kind = isStandard ? contextOrPropertyKey.kind : undefined;
57
+ if (kind === 'class' ||
58
+ (!isStandard && typeof target === 'function' && !contextOrPropertyKey)) {
59
+ const proto = target.prototype || target;
60
+ metadata_1.MetadataEngine.set(proto, constants_1.ROLES_METADATA, roles);
61
+ }
62
+ else {
63
+ const fn = isStandard
64
+ ? target
65
+ : descriptor
66
+ ? descriptor.value
67
+ : target[contextOrPropertyKey];
68
+ metadata_1.MetadataEngine.set(fn, constants_1.ROLES_METADATA, roles);
69
+ const routeMeta = metadata_1.MetadataEngine.init(fn, constants_1.ROUTE_METADATA_PROP, {});
70
+ routeMeta.roles = [...(routeMeta.roles || []), ...roles];
71
+ }
72
+ };
73
+ }
74
+ /**
75
+ * Marks a Controller class or route method as public, bypassing global authentication guards.
76
+ *
77
+ * @example
78
+ * ```ts
79
+ * @Controller('/auth')
80
+ * export class AuthController {
81
+ * @Post('/login')
82
+ * @Public()
83
+ * async login() {}
84
+ * }
85
+ * ```
86
+ */
87
+ function Public() {
88
+ return function (target, contextOrPropertyKey, descriptor) {
89
+ const isStandard = typeof contextOrPropertyKey === 'object' && contextOrPropertyKey !== null;
90
+ const kind = isStandard ? contextOrPropertyKey.kind : undefined;
91
+ if (kind === 'class' ||
92
+ (!isStandard && typeof target === 'function' && !contextOrPropertyKey)) {
93
+ const proto = target.prototype || target;
94
+ metadata_1.MetadataEngine.set(proto, constants_1.IS_PUBLIC_METADATA, true);
95
+ }
96
+ else {
97
+ const fn = isStandard
98
+ ? target
99
+ : descriptor
100
+ ? descriptor.value
101
+ : target[contextOrPropertyKey];
102
+ metadata_1.MetadataEngine.set(fn, constants_1.IS_PUBLIC_METADATA, true);
103
+ const routeMeta = metadata_1.MetadataEngine.init(fn, constants_1.ROUTE_METADATA_PROP, {});
104
+ routeMeta.isPublic = true;
105
+ }
106
+ };
107
+ }
108
+ exports.IsPublic = Public;
109
+ exports.AllowAnonymous = Public;
110
+ //# sourceMappingURL=security.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security.js","sourceRoot":"","sources":["../../src/decorators/security.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ export interface TransactionalOptions {
2
+ /** Optional named database connection */
3
+ connection?: string;
4
+ /** Whether the transaction is read-only */
5
+ readOnly?: boolean;
6
+ }
7
+ /**
8
+ * Automatically wraps a service method inside a database transaction.
9
+ * Commits automatically on success, and rolls back if an unhandled exception is thrown.
10
+ *
11
+ * Compatible with ExisJS built-in Database client, Prisma, Drizzle, TypeORM, Knex, and raw SQL pools.
12
+ *
13
+ * @example
14
+ * ```ts
15
+ * @Injectable()
16
+ * export class OrderService {
17
+ * constructor(private db: DatabaseService) {}
18
+ *
19
+ * @Transactional()
20
+ * async placeOrder(userId: string, items: CartItem[]) {
21
+ * const order = await this.db.orders.create({ userId })
22
+ * await this.db.inventory.decrement(items)
23
+ * return order
24
+ * }
25
+ * }
26
+ * ```
27
+ */
28
+ export declare function Transactional(_options?: TransactionalOptions): MethodDecorator;
29
+ //# sourceMappingURL=transaction.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transaction.d.ts","sourceRoot":"","sources":["../../src/decorators/transaction.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,oBAAoB;IACnC,yCAAyC;IACzC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,GAAE,oBAAyB,GAClC,eAAe,CAmEjB"}
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Transactional = Transactional;
4
+ /**
5
+ * Automatically wraps a service method inside a database transaction.
6
+ * Commits automatically on success, and rolls back if an unhandled exception is thrown.
7
+ *
8
+ * Compatible with ExisJS built-in Database client, Prisma, Drizzle, TypeORM, Knex, and raw SQL pools.
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * @Injectable()
13
+ * export class OrderService {
14
+ * constructor(private db: DatabaseService) {}
15
+ *
16
+ * @Transactional()
17
+ * async placeOrder(userId: string, items: CartItem[]) {
18
+ * const order = await this.db.orders.create({ userId })
19
+ * await this.db.inventory.decrement(items)
20
+ * return order
21
+ * }
22
+ * }
23
+ * ```
24
+ */
25
+ function Transactional(_options = {}) {
26
+ return function (_target, _propertyKey, descriptor) {
27
+ const originalMethod = descriptor.value;
28
+ descriptor.value = async function (...args) {
29
+ const self = this;
30
+ const db = self.db ||
31
+ self.database ||
32
+ self.prisma ||
33
+ self.dataSource ||
34
+ self.connection ||
35
+ globalThis.__EXIS_DB__;
36
+ if (db) {
37
+ // 1. Functional transaction wrapper: db.transaction((tx) => ...)
38
+ if (typeof db.transaction === 'function') {
39
+ return db.transaction(async (tx) => {
40
+ const originalDb = self.db;
41
+ try {
42
+ self.db = tx;
43
+ return await originalMethod.apply(self, args);
44
+ }
45
+ finally {
46
+ self.db = originalDb;
47
+ }
48
+ });
49
+ }
50
+ // 2. Prisma-style $transaction: db.$transaction(async (tx) => ...)
51
+ if (typeof db.$transaction === 'function') {
52
+ return db.$transaction(async (tx) => {
53
+ const originalPrisma = self.prisma || self.db;
54
+ try {
55
+ if (self.prisma)
56
+ self.prisma = tx;
57
+ if (self.db)
58
+ self.db = tx;
59
+ return await originalMethod.apply(self, args);
60
+ }
61
+ finally {
62
+ if (self.prisma)
63
+ self.prisma = originalPrisma;
64
+ if (self.db)
65
+ self.db = originalPrisma;
66
+ }
67
+ });
68
+ }
69
+ // 3. Imperative beginTransaction / commit / rollback
70
+ if (typeof db.beginTransaction === 'function') {
71
+ await db.beginTransaction();
72
+ try {
73
+ const result = await originalMethod.apply(self, args);
74
+ if (typeof db.commit === 'function')
75
+ await db.commit();
76
+ return result;
77
+ }
78
+ catch (error) {
79
+ if (typeof db.rollback === 'function')
80
+ await db.rollback();
81
+ throw error;
82
+ }
83
+ }
84
+ }
85
+ // Default pass-through if no transaction provider is attached
86
+ return originalMethod.apply(self, args);
87
+ };
88
+ return descriptor;
89
+ };
90
+ }
91
+ //# sourceMappingURL=transaction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transaction.js","sourceRoot":"","sources":["../../src/decorators/transaction.ts"],"names":[],"mappings":";;AA4BA,sCAqEC;AA1FD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,SAAgB,aAAa,CAC3B,WAAiC,EAAE;IAEnC,OAAO,UACL,OAAY,EACZ,YAA6B,EAC7B,UAA8B;QAE9B,MAAM,cAAc,GAAG,UAAU,CAAC,KAAK,CAAA;QAEvC,UAAU,CAAC,KAAK,GAAG,KAAK,WAAW,GAAG,IAAW;YAC/C,MAAM,IAAI,GAAG,IAAW,CAAA;YACxB,MAAM,EAAE,GACN,IAAI,CAAC,EAAE;gBACP,IAAI,CAAC,QAAQ;gBACb,IAAI,CAAC,MAAM;gBACX,IAAI,CAAC,UAAU;gBACf,IAAI,CAAC,UAAU;gBACd,UAAkB,CAAC,WAAW,CAAA;YAEjC,IAAI,EAAE,EAAE,CAAC;gBACP,iEAAiE;gBACjE,IAAI,OAAO,EAAE,CAAC,WAAW,KAAK,UAAU,EAAE,CAAC;oBACzC,OAAO,EAAE,CAAC,WAAW,CAAC,KAAK,EAAE,EAAO,EAAE,EAAE;wBACtC,MAAM,UAAU,GAAG,IAAI,CAAC,EAAE,CAAA;wBAC1B,IAAI,CAAC;4BACH,IAAI,CAAC,EAAE,GAAG,EAAE,CAAA;4BACZ,OAAO,MAAM,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;wBAC/C,CAAC;gCAAS,CAAC;4BACT,IAAI,CAAC,EAAE,GAAG,UAAU,CAAA;wBACtB,CAAC;oBACH,CAAC,CAAC,CAAA;gBACJ,CAAC;gBAED,mEAAmE;gBACnE,IAAI,OAAO,EAAE,CAAC,YAAY,KAAK,UAAU,EAAE,CAAC;oBAC1C,OAAO,EAAE,CAAC,YAAY,CAAC,KAAK,EAAE,EAAO,EAAE,EAAE;wBACvC,MAAM,cAAc,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,EAAE,CAAA;wBAC7C,IAAI,CAAC;4BACH,IAAI,IAAI,CAAC,MAAM;gCAAE,IAAI,CAAC,MAAM,GAAG,EAAE,CAAA;4BACjC,IAAI,IAAI,CAAC,EAAE;gCAAE,IAAI,CAAC,EAAE,GAAG,EAAE,CAAA;4BACzB,OAAO,MAAM,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;wBAC/C,CAAC;gCAAS,CAAC;4BACT,IAAI,IAAI,CAAC,MAAM;gCAAE,IAAI,CAAC,MAAM,GAAG,cAAc,CAAA;4BAC7C,IAAI,IAAI,CAAC,EAAE;gCAAE,IAAI,CAAC,EAAE,GAAG,cAAc,CAAA;wBACvC,CAAC;oBACH,CAAC,CAAC,CAAA;gBACJ,CAAC;gBAED,qDAAqD;gBACrD,IAAI,OAAO,EAAE,CAAC,gBAAgB,KAAK,UAAU,EAAE,CAAC;oBAC9C,MAAM,EAAE,CAAC,gBAAgB,EAAE,CAAA;oBAC3B,IAAI,CAAC;wBACH,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;wBACrD,IAAI,OAAO,EAAE,CAAC,MAAM,KAAK,UAAU;4BAAE,MAAM,EAAE,CAAC,MAAM,EAAE,CAAA;wBACtD,OAAO,MAAM,CAAA;oBACf,CAAC;oBAAC,OAAO,KAAK,EAAE,CAAC;wBACf,IAAI,OAAO,EAAE,CAAC,QAAQ,KAAK,UAAU;4BAAE,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAA;wBAC1D,MAAM,KAAK,CAAA;oBACb,CAAC;gBACH,CAAC;YACH,CAAC;YAED,8DAA8D;YAC9D,OAAO,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;QACzC,CAAC,CAAA;QAED,OAAO,UAAU,CAAA;IACnB,CAAC,CAAA;AACH,CAAC"}
@@ -22,5 +22,7 @@ export declare class Container {
22
22
  clearCache(): void;
23
23
  instantiateClass<T>(TargetClass: new (...args: any[]) => T, requestCache?: Map<ProviderToken, any>): T;
24
24
  resolve<T>(token: ProviderToken<T>, requestCache?: Map<ProviderToken, any>): T;
25
+ initLifecycle(): Promise<void>;
26
+ destroyLifecycle(signal?: string): Promise<void>;
25
27
  }
26
28
  //# sourceMappingURL=container.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"container.d.ts","sourceRoot":"","sources":["../../src/di/container.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,CAAC,CAAC,GAAG,GAAG,IAC/B,MAAM,GAAG,MAAM,GAAG,CAAC,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC,CAAA;AAE/C,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,WAAW,GAAG,SAAS,GAAG,WAAW,CAAA;CAC9C;AAED,MAAM,WAAW,aAAa,CAAC,CAAC,CAAE,SAAQ,YAAY;IACpD,QAAQ,EAAE,CAAC,CAAA;CACZ;AAED,MAAM,WAAW,eAAe,CAAC,CAAC,CAAE,SAAQ,YAAY;IACtD,UAAU,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;CACjC;AAED,MAAM,WAAW,aAAa,CAAC,CAAC,CAAE,SAAQ,YAAY;IACpD,QAAQ,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,CAAA;CACpC;AAED,MAAM,MAAM,kBAAkB,CAAC,CAAC,IAC9B,aAAa,CAAC,CAAC,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;AAE9D,eAAO,MAAM,eAAe,eAAqC,CAAA;AACjE,eAAO,MAAM,iBAAiB,eAAuC,CAAA;AACrE,eAAO,MAAM,cAAc,eAA6B,CAAA;AAExD,qBAAa,SAAS;IACpB,OAAO,CAAC,SAAS,CAAgC;IACjD,OAAO,CAAC,cAAc,CAAgC;IAEtD,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,kBAAkB,CAAC,CAAC,CAAC,GAAG,IAAI;IAK1E,UAAU,IAAI,IAAI;IAIlB,gBAAgB,CAAC,CAAC,EAChB,WAAW,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,EACtC,YAAY,CAAC,EAAE,GAAG,CAAC,aAAa,EAAE,GAAG,CAAC,GACrC,CAAC;IAmDJ,OAAO,CAAC,CAAC,EACP,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,EACvB,YAAY,CAAC,EAAE,GAAG,CAAC,aAAa,EAAE,GAAG,CAAC,GACrC,CAAC;CAkGL"}
1
+ {"version":3,"file":"container.d.ts","sourceRoot":"","sources":["../../src/di/container.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,CAAC,CAAC,GAAG,GAAG,IAC/B,MAAM,GAAG,MAAM,GAAG,CAAC,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC,CAAA;AAE/C,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,WAAW,GAAG,SAAS,GAAG,WAAW,CAAA;CAC9C;AAED,MAAM,WAAW,aAAa,CAAC,CAAC,CAAE,SAAQ,YAAY;IACpD,QAAQ,EAAE,CAAC,CAAA;CACZ;AAED,MAAM,WAAW,eAAe,CAAC,CAAC,CAAE,SAAQ,YAAY;IACtD,UAAU,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;CACjC;AAED,MAAM,WAAW,aAAa,CAAC,CAAC,CAAE,SAAQ,YAAY;IACpD,QAAQ,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,CAAA;CACpC;AAED,MAAM,MAAM,kBAAkB,CAAC,CAAC,IAC9B,aAAa,CAAC,CAAC,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;AAE9D,eAAO,MAAM,eAAe,eAAqC,CAAA;AACjE,eAAO,MAAM,iBAAiB,eAAuC,CAAA;AACrE,eAAO,MAAM,cAAc,eAA6B,CAAA;AAExD,qBAAa,SAAS;IACpB,OAAO,CAAC,SAAS,CAAgC;IACjD,OAAO,CAAC,cAAc,CAAgC;IAEtD,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,kBAAkB,CAAC,CAAC,CAAC,GAAG,IAAI;IAK1E,UAAU,IAAI,IAAI;IAIlB,gBAAgB,CAAC,CAAC,EAChB,WAAW,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,EACtC,YAAY,CAAC,EAAE,GAAG,CAAC,aAAa,EAAE,GAAG,CAAC,GACrC,CAAC;IAmDJ,OAAO,CAAC,CAAC,EACP,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,EACvB,YAAY,CAAC,EAAE,GAAG,CAAC,aAAa,EAAE,GAAG,CAAC,GACrC,CAAC;IAmGS,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAgB9B,gBAAgB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAe9D"}
@@ -135,6 +135,36 @@ class Container {
135
135
  }
136
136
  return resolvedValue;
137
137
  }
138
+ async initLifecycle() {
139
+ for (const [, instance] of this.singletonCache) {
140
+ if (instance && typeof instance === 'object') {
141
+ if (typeof instance.onInit === 'function') {
142
+ await instance.onInit();
143
+ }
144
+ if (typeof instance.onModuleInit === 'function') {
145
+ await instance.onModuleInit();
146
+ }
147
+ if (typeof instance.onApplicationBootstrap === 'function') {
148
+ await instance.onApplicationBootstrap();
149
+ }
150
+ }
151
+ }
152
+ }
153
+ async destroyLifecycle(signal) {
154
+ for (const [, instance] of this.singletonCache) {
155
+ if (instance && typeof instance === 'object') {
156
+ if (typeof instance.onDestroy === 'function') {
157
+ await instance.onDestroy();
158
+ }
159
+ if (typeof instance.onModuleDestroy === 'function') {
160
+ await instance.onModuleDestroy();
161
+ }
162
+ if (typeof instance.onApplicationShutdown === 'function') {
163
+ await instance.onApplicationShutdown(signal);
164
+ }
165
+ }
166
+ }
167
+ }
138
168
  }
139
169
  exports.Container = Container;
140
170
  //# sourceMappingURL=container.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"container.js","sourceRoot":"","sources":["../../src/di/container.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"container.js","sourceRoot":"","sources":["../../src/di/container.ts"],"names":[],"mappings":"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"}
@@ -178,6 +178,10 @@ export default class CheckoutController {
178
178
 
179
179
  ### Available Lifecycle & Middleware Decorators
180
180
  - `@Use(...items)` — Unified decorator that attaches middlewares, guards (`canActivate`), interceptors (`intercept`), or exception filters (`catch`) to a class or method.
181
+ - `@UseGuards(...guards)` — Explicit alias for `@Use` dedicated to route guards.
182
+ - `@UseInterceptors(...interceptors)` — Explicit alias for `@Use` dedicated to interceptors.
183
+ - `@UseFilters(...filters)` — Explicit alias for `@Use` dedicated to exception filters.
184
+ - `@Catch(...exceptions)` — Declares exception classes handled by an Exception Filter.
181
185
  - `@Timeout(ms: number | TimeoutOptions)` — Overrides the request timeout for a class or method.
182
186
  - `@Idempotent(options?)` — Caches responses based on the `Idempotency-Key` header using native in-memory off-heap storage.
183
187
  - `@RateLimit(options?)` — Enforces request rate limits on a controller class or route method.
@@ -190,7 +194,88 @@ export default class CheckoutController {
190
194
 
191
195
  ---
192
196
 
193
- ## 5. Response & Metadata Modifiers
197
+ ## 5. Security & Authorization Decorators
198
+
199
+ Declare access control rules directly on controller classes and route methods:
200
+
201
+ ```typescript filename="src/http/roles/route.ts"
202
+ import { Controller, Get, Post, Body, Use, Permissions, Roles, Public } from 'exisjs/decorators'
203
+ import { AuthGuard } from '@/common/guards/auth.guard'
204
+
205
+ @Controller('/roles')
206
+ @Use(AuthGuard) // Enforced on all routes in this controller
207
+ export default class RolesController {
208
+ @Get('/public')
209
+ @Public() // Bypasses auth guard for public inspection
210
+ async getPublicInfo() {
211
+ return { status: 'public' }
212
+ }
213
+
214
+ @Get('/')
215
+ @Roles('admin', 'manager') // Requires user to have admin or manager role
216
+ async getRoles() {
217
+ return { roles: [] }
218
+ }
219
+
220
+ @Post('/')
221
+ @Permissions('role:create', 'role:manage') // Granular permission check
222
+ async createRole(@Body() body: any) {
223
+ return { success: true }
224
+ }
225
+ }
226
+ ```
227
+
228
+ ### Available Security Decorators
229
+ - `@Permissions(...permissions: string[])` — Declares required permissions (auto-bypassed when `req.user.isSuperAdmin` is true).
230
+ - `@Roles(...roles: string[])` — Declares required role names.
231
+ - `@Public()` / `@IsPublic()` / `@AllowAnonymous()` — Marks an endpoint or controller as public, instructing global auth guards to skip credential verification.
232
+
233
+ ---
234
+
235
+ ## 6. Service Enhancements: Caching, Transactions & Profiling
236
+
237
+ ExisJS provides high-performance method decorators for `@Injectable()` services:
238
+
239
+ ```typescript filename="src/http/orders/service.ts"
240
+ import { Injectable, Cacheable, CacheEvict, Transactional, Profile, type OnInit, type OnDestroy } from 'exisjs/decorators'
241
+
242
+ @Injectable()
243
+ export class OrderService implements OnInit, OnDestroy {
244
+ async onInit() {
245
+ console.log('OrderService initialized')
246
+ }
247
+
248
+ async onDestroy() {
249
+ console.log('OrderService destroyed')
250
+ }
251
+
252
+ // Caches result in off-heap Rust cache for 300 seconds
253
+ @Cacheable({ ttl: 300, key: (id: string) => `order:${id}` })
254
+ @Profile({ thresholdMs: 50, warnSlow: true })
255
+ async getOrder(id: string) {
256
+ return this.db.query('SELECT * FROM orders WHERE id = $1', [id])
257
+ }
258
+
259
+ // Automatically runs in a database transaction and evicts cached entries
260
+ @Transactional()
261
+ @CacheEvict({ key: (id: string) => `order:${id}` })
262
+ async updateOrder(id: string, data: any) {
263
+ return this.db.update('orders', id, data)
264
+ }
265
+ }
266
+ ```
267
+
268
+ ### Available Service Decorators & Lifecycle Interfaces
269
+ - `@Cacheable({ ttl?: number, key?: string | ((...args) => string) })` — Caches method return values in off-heap memory.
270
+ - `@CacheEvict({ key: string | ((...args) => string) })` — Evicts cached keys on mutation.
271
+ - `@Transactional(options?)` — Wraps service operations in an atomic database transaction.
272
+ - `@Profile({ thresholdMs?: number, warnSlow?: boolean, log?: Function })` — Measures method execution time with sub-millisecond precision.
273
+ - `OnInit` (`onInit()`) & `OnDestroy` (`onDestroy()`) — Service startup and shutdown lifecycle hooks.
274
+ - `OnModuleInit`, `OnModuleDestroy`, `OnApplicationBootstrap` — Module lifecycle hooks.
275
+
276
+ ---
277
+
278
+ ## 7. Response & Metadata Modifiers
194
279
 
195
280
  Modify HTTP response status codes, redirect clients, or set headers declaratively:
196
281
 
@@ -219,14 +304,13 @@ export default class ApiController {
219
304
  - `@Header(name: string, value: string)` — Injects a response header.
220
305
  - `@Returns(schema)` — Attaches response schema for OpenAPI/Swagger generation.
221
306
  - `@Redirect(url: string, statusCode?: number)` — Redirects the client.
222
- - `@Permissions(...permissions: string[])` — Attaches route permissions metadata.
223
307
  - `@Hosts(...hosts: string[])` — Restricts route/controller to specific Host headers.
224
308
  - `@SetMetadata(key, value)` — Attaches custom metadata to a class or method.
225
- - `Reflector` — Static utility to inspect metadata attached via `@SetMetadata` across classes and methods (`Reflector.get`, `Reflector.getAllAndOverride`, `Reflector.getAllAndMerge`).
309
+ - `Reflector` — Static utility to inspect metadata attached via `@SetMetadata` across classes and methods.
226
310
 
227
311
  ---
228
312
 
229
- ## 6. Dependency Injection & Modules
313
+ ## 8. Dependency Injection & Modules
230
314
 
231
315
  To mark a service class as an injectable provider for the IoC container, use the `@Injectable()` decorator. ExisJS supports `singleton` (default), `request`, and `transient` scopes:
232
316
 
@@ -281,3 +365,4 @@ import { UserService } from './service'
281
365
  })
282
366
  export class UsersModule {}
283
367
  ```
368
+
@@ -335,26 +335,42 @@ export default controller({
335
335
 
336
336
  ### Class-Based (OOP) Paradigm
337
337
 
338
- ```typescript filename="src/http/users/route.ts"
339
- import { Controller, Get, UseFilters } from 'exisjs/decorators'
340
- import type { Request, Response } from 'exisjs/router'
341
-
342
- function localErrorHandler(err: any, req: Request, res: Response, next: any) {
343
- console.log('Users Controller Error Handler Caught:', err.message)
344
- res.status(400).json({ success: false, localError: err.message })
338
+ You can use function handlers or structured class-based `ExceptionFilter` implementations with `@Catch()`:
339
+
340
+ ```typescript filename="src/http/filters/not-found.filter.ts"
341
+ import { Catch, type ExceptionFilter, type ArgumentsHost } from 'exisjs/decorators'
342
+ import { NotFoundException } from 'exisjs/error'
343
+
344
+ @Catch(NotFoundException)
345
+ export class NotFoundExceptionFilter implements ExceptionFilter<NotFoundException> {
346
+ catch(exception: NotFoundException, host: ArgumentsHost) {
347
+ const { res } = host
348
+ res.status(404).json({
349
+ statusCode: 404,
350
+ error: 'Not Found',
351
+ message: exception.message,
352
+ timestamp: new Date().toISOString(),
353
+ })
354
+ }
345
355
  }
356
+ ```
346
357
 
347
- @Controller()
348
- @UseFilters(localErrorHandler)
358
+ ```typescript filename="src/http/users/route.ts"
359
+ import { Controller, Get, UseFilters, Use } from 'exisjs/decorators'
360
+ import { NotFoundException } from 'exisjs/error'
361
+ import { NotFoundExceptionFilter } from '../filters/not-found.filter'
362
+
363
+ @Controller('/users')
364
+ @Use(NotFoundExceptionFilter) // or @UseFilters(NotFoundExceptionFilter)
349
365
  export default class UsersController {
350
- @Get('/crash')
351
- async crash() {
352
- throw new Error("Something went wrong in the users module")
366
+ @Get('/:id')
367
+ async getUser() {
368
+ throw new NotFoundException('User')
353
369
  }
354
370
  }
355
371
  ```
356
372
 
357
- By combining Exception Filters and Local Error Hooks, ExisJS gives you control over your error boundaries.
373
+ By combining Exception Filters and Local Error Hooks, ExisJS gives you complete control over your error boundaries.
358
374
 
359
375
  ## Observability (BYOM/BYOT)
360
376
 
@@ -78,6 +78,54 @@ const app = getActiveApp()
78
78
  const usersService = app.container.resolve(UsersService)
79
79
  ```
80
80
 
81
+ ## Service Lifecycle Hooks
82
+
83
+ ExisJS `@Injectable()` services can implement lifecycle interfaces. When the application starts up or shuts down gracefully, ExisJS automatically triggers these hooks on all managed singletons:
84
+
85
+ ```typescript filename="src/http/database/service.ts"
86
+ import { Injectable, type OnInit, type OnDestroy } from 'exisjs/decorators'
87
+
88
+ @Injectable()
89
+ export class DatabaseService implements OnInit, OnDestroy {
90
+ async onInit(): Promise<void> {
91
+ // Invoked automatically during app startup (app.create / app.listen)
92
+ await this.connectPool()
93
+ }
94
+
95
+ async onDestroy(): Promise<void> {
96
+ // Invoked automatically during graceful termination (app.close / SIGINT / SIGTERM)
97
+ await this.drainPool()
98
+ }
99
+ }
100
+ ```
101
+
102
+ ## Service Method Enhancements
103
+
104
+ You can supercharge service methods with off-heap caching, automated transaction wrapping, and SLA performance profiling:
105
+
106
+ ```typescript filename="src/http/users/service.ts"
107
+ import { Injectable, Cacheable, CacheEvict, Transactional, Profile } from 'exisjs/decorators'
108
+
109
+ @Injectable()
110
+ export class UsersService {
111
+ constructor(private db: DatabaseService) {}
112
+
113
+ // Caches return values off-heap in Rust LRU cache
114
+ @Cacheable({ ttl: 300, key: (id: string) => `user:${id}` })
115
+ @Profile({ thresholdMs: 100, warnSlow: true })
116
+ async findById(id: string) {
117
+ return this.db.query('SELECT * FROM users WHERE id = $1', [id])
118
+ }
119
+
120
+ // Runs in an atomic transaction; automatically rolls back on error
121
+ @Transactional()
122
+ @CacheEvict({ key: (id: string) => `user:${id}` })
123
+ async updateUser(id: string, data: any) {
124
+ return this.db.update('users', id, data)
125
+ }
126
+ }
127
+ ```
128
+
81
129
  ## Custom Providers
82
130
 
83
131
  ExisJS's DI container is flexible. By default, when you register a class, ExisJS instantiates it for you. However, you often need more control. You can register standard classes, raw values, factories, or aliased classes natively using `app.provide()`.
@@ -86,6 +86,10 @@ Parameter decorators automatically extract data from the incoming request and in
86
86
  ## 3. Middleware & Pipeline Decorators
87
87
 
88
88
  - `@Use(...middlewaresOrGuardsOrInterceptorsOrFilters)`: Unified decorator that binds middlewares, guards (`canActivate`), interceptors (`intercept`), or exception filters (`catch`) to a controller class or method.
89
+ - `@UseGuards(...guards)`: Dedicated decorator to apply guards to a class or method.
90
+ - `@UseInterceptors(...interceptors)`: Dedicated decorator to apply interceptors to a class or method.
91
+ - `@UseFilters(...filters)`: Dedicated decorator to apply exception filters to a class or method.
92
+ - `@Catch(...exceptions)`: Class decorator for `ExceptionFilter` implementations declaring handled exception types.
89
93
  - `@Upload(fieldName, options?)` / `@UseUpload(...)`: Configures multipart file upload handling for a method, populating `@UploadedFile()` or `@UploadedFiles()`.
90
94
  - `@Timeout(ms: number | TimeoutOptions)`: Overrides the request timeout for a class or method (e.g. `@Timeout(120000)`). Passing `0` disables timeouts for long-running streaming or exports.
91
95
  - `@Idempotent(options?)`: Caches responses based on the `Idempotency-Key` header using native in-memory off-heap storage. Works at class and method level.
@@ -98,13 +102,32 @@ Parameter decorators automatically extract data from the incoming request and in
98
102
 
99
103
  ---
100
104
 
101
- ## 4. Response & Metadata Modifiers
105
+ ## 4. Security & Access Control Decorators
106
+
107
+ - `@Permissions(...permissions: string[])`: Sets required permission keys for a controller or route method (automatically bypassed if `req.user.isSuperAdmin` is true).
108
+ - `@Roles(...roles: string[])`: Sets required role names for a controller or route method.
109
+ - `@Public()` / `@IsPublic()` / `@AllowAnonymous()`: Marks a controller or route as public, instructing global authentication guards to bypass credential checks.
110
+
111
+ ---
112
+
113
+ ## 5. Service Enhancements: Caching, Transactions & Profiling
114
+
115
+ - `@Cacheable({ ttl?: number, key?: string | ((...args) => string) })`: Caches method return values in ExisJS's off-heap native memory LRU cache.
116
+ - `@CacheEvict({ key: string | ((...args) => string) })`: Evicts cached entries matching the key when the method completes.
117
+ - `@Transactional(options?)`: Automatically wraps service operations in an atomic database transaction.
118
+ - `@Profile({ thresholdMs?: number, warnSlow?: boolean, log?: Function })`: Profiles method execution time with sub-millisecond precision.
119
+ - `OnInit` (`onInit()`): Invoked when the application or service boots up.
120
+ - `OnDestroy` (`onDestroy()`): Invoked when the application gracefully terminates.
121
+ - `OnModuleInit`, `OnModuleDestroy`, `OnApplicationBootstrap`: Modular lifecycle hooks.
122
+
123
+ ---
124
+
125
+ ## 6. Response & Metadata Modifiers
102
126
 
103
127
  - `@HttpCode(code: number)`: Enforces a custom HTTP status code on success.
104
128
  - `@Header(name: string, value: string)`: Appends an HTTP header to the response.
105
129
  - `@Returns(schema)`: Attaches response schema for OpenAPI documentation.
106
130
  - `@Redirect(url: string, statusCode?: number)`: Redirects request to target URL.
107
- - `@Permissions(...permissions: string[])`: Sets required permissions on the route.
108
131
  - `@Hosts(...hosts: string[])`: Restricts routes to specific Host headers.
109
132
  - `@SetMetadata(key, value)`: Attaches arbitrary custom metadata to a class or handler method, retrievable via `Reflector`.
110
133
  - `Reflector`: Utility class to inspect metadata attached by `@SetMetadata`:
@@ -114,7 +137,7 @@ Parameter decorators automatically extract data from the incoming request and in
114
137
 
115
138
  ---
116
139
 
117
- ## 5. Dependency Injection & Modules
140
+ ## 7. Dependency Injection & Modules
118
141
 
119
142
  - `@Module({ imports?, controllers?, providers?, exports? })`: OOP class decorator equivalent to `defineModule()` for structuring application modules.
120
143
  - `@Injectable(options?)`: Marks a service class as an IoC provider managed by the container. Supports `{ scope: 'singleton' | 'request' | 'transient' }`.
@@ -125,7 +148,7 @@ Parameter decorators automatically extract data from the incoming request and in
125
148
 
126
149
  ---
127
150
 
128
- ## 6. Cron & Task Scheduling
151
+ ## 8. Cron & Task Scheduling
129
152
 
130
153
  - `@Cron(schedule: string, options?: CronJobOptions)`: Schedules a class method as a recurring cron job on any `@Injectable()` service.
131
154
  - `@Interval(ms: number, options?: IntervalOptions)`: Schedules a class method to execute repeatedly every `ms` milliseconds.