@discover-cloud/shared 1.2.9 → 1.4.0

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 (183) hide show
  1. package/dist/authorization/index.d.ts +2 -2
  2. package/dist/authorization/index.js +1 -1
  3. package/dist/authorization/permission-cache.service.d.ts +104 -16
  4. package/dist/authorization/permission-cache.service.js +177 -148
  5. package/dist/authorization/permission-checker.d.ts +30 -0
  6. package/dist/authorization/permission-checker.js +40 -0
  7. package/dist/context/index.d.ts +1 -1
  8. package/dist/context/index.js +1 -1
  9. package/dist/context/request-context.storage.d.ts +21 -0
  10. package/dist/context/request-context.storage.js +37 -0
  11. package/dist/contracts/auth-service/account.dto.d.ts +30 -0
  12. package/dist/contracts/auth-service/account.dto.js +7 -0
  13. package/dist/contracts/auth-service/auth.dto.d.ts +21 -0
  14. package/dist/contracts/auth-service/auth.dto.js +10 -0
  15. package/dist/contracts/index.d.ts +1 -0
  16. package/dist/{security → contracts}/index.js +1 -1
  17. package/dist/contracts/visibility.d.ts +63 -0
  18. package/dist/contracts/visibility.js +10 -0
  19. package/dist/dtos/audit-service.types.d.ts +42 -0
  20. package/dist/dtos/audit-service.types.js +31 -0
  21. package/dist/dtos/auth-service.dto.d.ts +87 -26
  22. package/dist/dtos/auth-service.dto.js +4 -0
  23. package/dist/dtos/cloud-service.dto.d.ts +57 -27
  24. package/dist/dtos/cloud-service.dto.js +5 -0
  25. package/dist/dtos/index.d.ts +6 -5
  26. package/dist/dtos/index.js +1 -0
  27. package/dist/dtos/insights-service.dto.d.ts +184 -32
  28. package/dist/dtos/insights-service.dto.js +8 -0
  29. package/dist/dtos/response.dto.d.ts +12 -83
  30. package/dist/dtos/response.dto.js +2 -21
  31. package/dist/dtos/user-service.dto.d.ts +163 -13
  32. package/dist/enums/domain.enums.d.ts +272 -75
  33. package/dist/enums/domain.enums.js +329 -102
  34. package/dist/enums/index.d.ts +2 -2
  35. package/dist/enums/permissions.enums.d.ts +142 -80
  36. package/dist/enums/permissions.enums.js +174 -133
  37. package/dist/errors/app-error.d.ts +13 -18
  38. package/dist/errors/app-error.js +15 -21
  39. package/dist/errors/http-errors.d.ts +106 -18
  40. package/dist/errors/http-errors.js +136 -51
  41. package/dist/errors/index.d.ts +2 -2
  42. package/dist/http/index.d.ts +2 -1
  43. package/dist/http/index.js +1 -0
  44. package/dist/http/request-context.d.ts +8 -0
  45. package/dist/http/request-context.js +37 -0
  46. package/dist/http/service-client.d.ts +93 -40
  47. package/dist/http/service-client.js +104 -55
  48. package/dist/index.d.ts +11 -9
  49. package/dist/index.js +2 -0
  50. package/dist/jwt/index.d.ts +3 -2
  51. package/dist/jwt/index.js +2 -1
  52. package/dist/jwt/machine-jwt-verifier.d.ts +21 -0
  53. package/dist/jwt/machine-jwt-verifier.js +83 -0
  54. package/dist/jwt/machine-token-client.d.ts +36 -5
  55. package/dist/jwt/machine-token-client.js +61 -27
  56. package/dist/jwt/user-jwt-verifier.d.ts +31 -0
  57. package/dist/jwt/user-jwt-verifier.js +102 -0
  58. package/dist/messaging/audit.publisher.d.ts +14 -0
  59. package/dist/messaging/audit.publisher.js +49 -0
  60. package/dist/messaging/index.d.ts +2 -0
  61. package/dist/{dto → messaging}/index.js +2 -3
  62. package/dist/messaging/rabbitmq.client.d.ts +15 -0
  63. package/dist/messaging/rabbitmq.client.js +133 -0
  64. package/dist/middleware/error-handler.middleware.d.ts +8 -28
  65. package/dist/middleware/error-handler.middleware.js +63 -54
  66. package/dist/middleware/index.d.ts +10 -8
  67. package/dist/middleware/index.js +7 -5
  68. package/dist/middleware/request-context.middleware.d.ts +6 -0
  69. package/dist/middleware/request-context.middleware.js +48 -0
  70. package/dist/middleware/require-auth.middleware.d.ts +7 -76
  71. package/dist/middleware/require-auth.middleware.js +29 -117
  72. package/dist/middleware/require-machine.middleware.d.ts +13 -0
  73. package/dist/middleware/require-machine.middleware.js +128 -0
  74. package/dist/middleware/require-org-permission-from-body.middleware.d.ts +10 -0
  75. package/dist/middleware/require-org-permission-from-body.middleware.js +23 -0
  76. package/dist/middleware/require-org-permission.middleware.d.ts +19 -0
  77. package/dist/middleware/require-org-permission.middleware.js +115 -0
  78. package/dist/middleware/require-platform-permission.middleware.d.ts +19 -0
  79. package/dist/middleware/require-platform-permission.middleware.js +91 -0
  80. package/dist/middleware/require-user.middleware.d.ts +14 -0
  81. package/dist/middleware/require-user.middleware.js +30 -0
  82. package/dist/middleware/require-workspace-permission.middleware.d.ts +20 -0
  83. package/dist/middleware/require-workspace-permission.middleware.js +114 -0
  84. package/dist/middleware/validate.middleware.d.ts +31 -31
  85. package/dist/middleware/validate.middleware.js +31 -33
  86. package/dist/types/audit.types.d.ts +39 -0
  87. package/dist/types/audit.types.js +30 -0
  88. package/dist/types/express.types.d.ts +92 -124
  89. package/dist/types/express.types.js +30 -49
  90. package/dist/types/index.d.ts +1 -1
  91. package/dist/utils/date.util.d.ts +6 -0
  92. package/dist/utils/date.util.js +11 -0
  93. package/dist/utils/env.util.d.ts +6 -0
  94. package/dist/utils/env.util.js +19 -0
  95. package/dist/utils/index.d.ts +5 -4
  96. package/dist/utils/index.js +5 -4
  97. package/dist/utils/logger.util.d.ts +31 -0
  98. package/dist/utils/logger.util.js +91 -0
  99. package/dist/utils/pagination.util.d.ts +6 -0
  100. package/dist/utils/pagination.util.js +20 -0
  101. package/dist/utils/request-context.als.d.ts +10 -0
  102. package/dist/utils/request-context.als.js +5 -0
  103. package/dist/utils/response.util.d.ts +27 -0
  104. package/dist/utils/response.util.js +56 -0
  105. package/dist/utils/slug.util.d.ts +9 -0
  106. package/dist/utils/slug.util.js +32 -0
  107. package/dist/utils/url-safety.util.d.ts +6 -0
  108. package/dist/utils/url-safety.util.js +75 -0
  109. package/package.json +3 -1
  110. package/dist/authorization/permissions.d.ts +0 -78
  111. package/dist/authorization/permissions.js +0 -174
  112. package/dist/context/access-context.d.ts +0 -10
  113. package/dist/context/access-context.js +0 -2
  114. package/dist/dto/auth-service.dtos.d.ts +0 -44
  115. package/dist/dto/auth-service.dtos.js +0 -2
  116. package/dist/dto/index.d.ts +0 -3
  117. package/dist/dto/response.dtos.d.ts +0 -55
  118. package/dist/dto/response.dtos.js +0 -6
  119. package/dist/dto/user-service.dtos.d.ts +0 -50
  120. package/dist/dto/user-service.dtos.js +0 -2
  121. package/dist/enums/auth-service.enums.d.ts +0 -12
  122. package/dist/enums/auth-service.enums.js +0 -17
  123. package/dist/enums/permissions.types.d.ts +0 -12
  124. package/dist/enums/permissions.types.js +0 -17
  125. package/dist/enums/user-service.enums.d.ts +0 -32
  126. package/dist/enums/user-service.enums.js +0 -41
  127. package/dist/internal/index.d.ts +0 -4
  128. package/dist/internal/index.js +0 -20
  129. package/dist/internal/internal-jwt.service.d.ts +0 -13
  130. package/dist/internal/internal-jwt.service.js +0 -88
  131. package/dist/internal/internal-jwt.types.d.ts +0 -7
  132. package/dist/internal/internal-jwt.types.js +0 -2
  133. package/dist/internal/internal-key-manager.d.ts +0 -16
  134. package/dist/internal/internal-key-manager.js +0 -67
  135. package/dist/internal/registry.d.ts +0 -8
  136. package/dist/internal/registry.js +0 -34
  137. package/dist/internal/service-client.d.ts +0 -9
  138. package/dist/internal/service-client.js +0 -94
  139. package/dist/jwt/internal-jwt-verifier.d.ts +0 -41
  140. package/dist/jwt/internal-jwt-verifier.js +0 -185
  141. package/dist/jwt/jwt-verifier.d.ts +0 -9
  142. package/dist/jwt/jwt-verifier.js +0 -36
  143. package/dist/jwt/service-client.d.ts +0 -7
  144. package/dist/jwt/service-client.js +0 -87
  145. package/dist/middleware/authorize.d.ts +0 -3
  146. package/dist/middleware/authorize.js +0 -24
  147. package/dist/middleware/authorize.middleware.d.ts +0 -54
  148. package/dist/middleware/authorize.middleware.js +0 -104
  149. package/dist/middleware/error-handler.d.ts +0 -4
  150. package/dist/middleware/error-handler.js +0 -23
  151. package/dist/middleware/request-id.d.ts +0 -2
  152. package/dist/middleware/request-id.js +0 -9
  153. package/dist/middleware/request-id.middleware.d.ts +0 -22
  154. package/dist/middleware/request-id.middleware.js +0 -34
  155. package/dist/middleware/require-auth.d.ts +0 -10
  156. package/dist/middleware/require-auth.js +0 -34
  157. package/dist/middleware/require-human.middleware.d.ts +0 -2
  158. package/dist/middleware/require-human.middleware.js +0 -18
  159. package/dist/middleware/require-internal.middleware.d.ts +0 -18
  160. package/dist/middleware/require-internal.middleware.js +0 -183
  161. package/dist/middleware/validate.d.ts +0 -5
  162. package/dist/middleware/validate.js +0 -18
  163. package/dist/middleware/validated-merge.middleware.d.ts +0 -20
  164. package/dist/middleware/validated-merge.middleware.js +0 -33
  165. package/dist/middleware/verify-internal-jwt.d.ts +0 -7
  166. package/dist/middleware/verify-internal-jwt.js +0 -25
  167. package/dist/security/guard.d.ts +0 -10
  168. package/dist/security/guard.js +0 -40
  169. package/dist/security/index.d.ts +0 -1
  170. package/dist/types/express.d.ts +0 -22
  171. package/dist/types/express.js +0 -3
  172. package/dist/utils/date.utils.d.ts +0 -25
  173. package/dist/utils/date.utils.js +0 -30
  174. package/dist/utils/env.d.ts +0 -46
  175. package/dist/utils/env.js +0 -61
  176. package/dist/utils/env.utils.d.ts +0 -46
  177. package/dist/utils/env.utils.js +0 -61
  178. package/dist/utils/logger.utils.d.ts +0 -66
  179. package/dist/utils/logger.utils.js +0 -97
  180. package/dist/utils/response.d.ts +0 -4
  181. package/dist/utils/response.js +0 -35
  182. package/dist/utils/response.utils.d.ts +0 -54
  183. package/dist/utils/response.utils.js +0 -85
@@ -1,49 +1,11 @@
1
1
  /**
2
- * EXPRESS TYPE AUGMENTATION + JWT PAYLOAD TYPES (@discover-cloud/shared)
3
- * ──────────────────────────────────────────────────────────────────────────
4
- * Single source of truth for everything attached to Express's Request object
5
- * and all internal JWT payload shapes.
6
- *
7
- * Import in each service's entrypoint to activate the augmentation:
8
- * import "@discover-cloud/shared/types/express";
9
- *
10
- * ─── Permission flow ────────────────────────────────────────────────────
11
- * JWT carries: accountId + accountRole (lean payload, no perms)
12
- * Redis derives: GlobalPermission[] (role map on cache miss)
13
- * AccessContext has: perms (resolved by auth middleware)
14
- *
15
- * perms never touch the JWT — they live in the Redis permission cache and
16
- * are resolved into req.accessContext by RequireAuthMiddleware per request.
17
- * ────────────────────────────────────────────────────────────────────────
2
+ * @file express.types.ts
3
+ * @description Express Request type augmentations and authentication context definitions.
18
4
  */
19
- import { JWTPayload } from "jose";
20
- import { AccountRole, GlobalPermission } from "../enums";
21
- interface BaseInternalJwtPayload extends JWTPayload {
22
- /**
23
- * JWT ID — required.
24
- * Used for the Redis kill-switch (session revocation / account suspension).
25
- * Overrides JWTPayload's optional jti with a required string.
26
- */
5
+ import { JWTPayload } from 'jose';
6
+ import { ResourceQueryScope } from '../contracts';
7
+ interface BaseTokenPayload extends JWTPayload {
27
8
  jti: string;
28
- /**
29
- * Token type discriminator — guards against token confusion attacks.
30
- * InternalJwtVerifier rejects any token where typ !== "internal",
31
- * even if it passes signature verification.
32
- */
33
- typ: "internal";
34
- /**
35
- * The entity that last minted or forwarded this token.
36
- * "api-gateway" → direct user-initiated request
37
- * "notification-service" → service-to-service call on behalf of a user
38
- * Used for audit logging and conditional authorization.
39
- */
40
- caller: string;
41
- /**
42
- * Propagated request ID for distributed tracing.
43
- * Ties together logs across the entire service call chain.
44
- * Set by the gateway from the incoming x-request-id header.
45
- */
46
- requestId?: string;
47
9
  iss: string;
48
10
  aud: string | string[];
49
11
  iat: number;
@@ -51,116 +13,122 @@ interface BaseInternalJwtPayload extends JWTPayload {
51
13
  nbf: number;
52
14
  }
53
15
  /**
54
- * HumanInternalJwtPayload
55
- * Issued on behalf of an authenticated user after external JWT verification.
56
- * accountRole is carried so the permission cache can derive perms from
57
- * globalRolePermissions on a cold cache miss — without a DB call.
16
+ * Short-lived user access token.
17
+ *
18
+ * Contains authentication identity only.
19
+ * Authorization is resolved dynamically using RBAC.
58
20
  */
59
- export interface HumanInternalJwtPayload extends BaseInternalJwtPayload {
60
- isMachine: false;
21
+ export interface AccessTokenPayload extends BaseTokenPayload {
22
+ typ: 'access';
23
+ /** Account identifier. */
61
24
  accountId: string;
62
- accountRole: AccountRole;
63
- externalJti: string;
64
- externalExp: number;
25
+ /** Active session identifier. */
26
+ sessionId: string;
27
+ /** Token/version invalidation marker. */
28
+ ver: number;
29
+ /** Whether the session was generated via impersonation. */
30
+ impersonated?: boolean;
65
31
  }
66
32
  /**
67
- * MachineInternalJwtPayload
68
- * Issued for service-to-service calls with no user context.
69
- * Intentionally carries no user fields their absence is enforced by the type.
33
+ * Long-lived refresh token payload.
34
+ *
35
+ * Refresh tokens are only used for rotation.
70
36
  */
71
- export interface MachineInternalJwtPayload extends BaseInternalJwtPayload {
72
- isMachine: true;
37
+ export interface RefreshTokenPayload extends BaseTokenPayload {
38
+ typ: 'refresh';
39
+ accountId: string;
40
+ }
41
+ /**
42
+ * Service-to-service authentication token.
43
+ */
44
+ export interface MachineTokenPayload extends BaseTokenPayload {
45
+ typ: 'machine';
73
46
  serviceId: string;
47
+ scopes: string[];
48
+ requestId?: string;
74
49
  }
75
- /** Full internal JWT payload union — use in verifiers and auth middleware */
76
- export type InternalJwtPayload = HumanInternalJwtPayload | MachineInternalJwtPayload;
50
+ /**
51
+ * Any verified JWT generated by auth-service.
52
+ */
53
+ export type VerifiedTokenPayload = AccessTokenPayload | RefreshTokenPayload | MachineTokenPayload;
54
+ /**
55
+ * Minimal data needed to revoke a JWT.
56
+ */
77
57
  export interface TokenRevocationContext {
78
58
  jti: string;
79
59
  exp: number;
80
60
  }
81
- export interface HumanAccessContext {
82
- kind: "human";
61
+ /**
62
+ * Authenticated user request context.
63
+ *
64
+ * Created from access tokens only.
65
+ */
66
+ export interface UserContext {
67
+ type: 'user';
83
68
  accountId: string;
84
- accountRole: AccountRole;
85
- /**
86
- * Resolved from Redis permission cache — NOT from the JWT.
87
- * Always present by the time req.accessContext is populated.
88
- * Invalidated on role change, suspension, and account deletion.
89
- */
90
- perms: GlobalPermission[];
69
+ sessionId: string;
91
70
  }
92
- export interface MachineAccessContext {
93
- kind: "machine";
71
+ /**
72
+ * Authenticated internal service context.
73
+ */
74
+ export interface MachineContext {
75
+ type: 'machine';
94
76
  serviceId: string;
77
+ scopes: string[];
78
+ }
79
+ export type AuthContext = UserContext | MachineContext;
80
+ export interface RequestMetadataContext {
81
+ requestId: string;
82
+ ipAddress: string | null;
83
+ userAgent: string | null;
95
84
  }
96
- export type AccessContext = HumanAccessContext | MachineAccessContext;
97
- export declare function isHumanPayload(payload: InternalJwtPayload): payload is HumanInternalJwtPayload;
98
- export declare function isMachinePayload(payload: InternalJwtPayload): payload is MachineInternalJwtPayload;
99
85
  /**
100
- * Runtime assertion for jose.jwtVerify() results.
101
- *
102
- * jose returns a generic JWTPayload because it cannot know
103
- * our custom claims. After verification + this assertion,
104
- * TypeScript safely treats it as MachineInternalJwtPayload.
86
+ * Passed into application services for immutable auditing.
105
87
  */
106
- export declare function assertMachinePayload(payload: JWTPayload): asserts payload is MachineInternalJwtPayload;
107
- export declare function isHumanContext(ctx: AccessContext): ctx is HumanAccessContext;
108
- export declare function isMachineContext(ctx: AccessContext): ctx is MachineAccessContext;
109
- export interface VerifiedAccessPayload {
110
- accountId: string;
111
- accountRole: AccountRole;
112
- typ: "access";
113
- iss: string;
114
- aud: string | string[];
115
- iat: number;
116
- exp: number;
117
- nbf: number;
118
- jti: string;
88
+ export interface AuditContext extends Partial<RequestMetadataContext> {
89
+ actorId: string | null;
119
90
  }
120
- export interface VerifiedRefreshPayload {
121
- accountId: string;
122
- typ: "refresh";
123
- iss: string;
124
- aud: string | string[];
125
- iat: number;
126
- exp: number;
127
- nbf: number;
128
- jti: string;
91
+ export declare function isAccessToken(payload: VerifiedTokenPayload): payload is AccessTokenPayload;
92
+ export declare function isRefreshToken(payload: VerifiedTokenPayload): payload is RefreshTokenPayload;
93
+ export declare function isMachineToken(payload: VerifiedTokenPayload): payload is MachineTokenPayload;
94
+ export declare function isUserContext(ctx: AuthContext): ctx is UserContext;
95
+ export declare function isMachineContext(ctx: AuthContext): ctx is MachineContext;
96
+ /**
97
+ * Runtime assertion for service tokens.
98
+ */
99
+ export declare function assertMachineToken(payload: JWTPayload): asserts payload is MachineTokenPayload;
100
+ export interface ValidatedRequestData {
101
+ params?: Record<string, unknown>;
102
+ query?: Record<string, unknown>;
103
+ body?: Record<string, unknown>;
104
+ headers?: Record<string, unknown>;
129
105
  }
130
- declare module "express-serve-static-core" {
106
+ declare module 'express-serve-static-core' {
131
107
  interface Request {
132
108
  /**
133
- * Unique request ID — set by requestId middleware.
134
- * Respects upstream x-request-id forwarded by the gateway / load balancer.
135
- * Always present after requestId middleware runs.
109
+ * Request correlation ID.
136
110
  */
137
111
  id: string;
138
112
  /**
139
- * Validated + parsed request input (body / params / query / headers).
140
- * Typed as unknown — narrow at the route level using z.infer:
141
- *
142
- * const body = req.validated as z.infer<typeof CreateOrderSchema>;
143
- *
144
- * Never cast to any.
113
+ * Request metadata.
114
+ */
115
+ requestContext: RequestMetadataContext;
116
+ /**
117
+ * Validated request data.
118
+ */
119
+ validated?: ValidatedRequestData;
120
+ /**
121
+ * Raw verified JWT payload.
145
122
  */
146
- validated?: unknown;
123
+ authPayload?: VerifiedTokenPayload;
147
124
  /**
148
- * Raw verified internal JWT payload.
149
- * Set by RequireAuthMiddleware after InternalJwtVerifier.verifyInternal().
150
- *
151
- * Prefer req.accessContext in route handlers and controllers.
152
- * Access internalAuth only when you need raw JWT claims (e.g. jti).
125
+ * Runtime authenticated identity.
153
126
  */
154
- internalAuth?: InternalJwtPayload;
127
+ authContext?: AuthContext;
155
128
  /**
156
- * Clean access context built from internalAuth + Redis permission cache.
157
- * This is what route handlers, controllers, and domain services consume.
158
- *
159
- * if (isHumanContext(req.accessContext)) {
160
- * const { accountId, accountRole, perms } = req.accessContext;
161
- * }
129
+ * Resolved resource query scope for insights queries.
162
130
  */
163
- accessContext?: AccessContext;
131
+ visibilityScope?: ResourceQueryScope;
164
132
  }
165
133
  }
166
134
  export {};
@@ -1,60 +1,41 @@
1
1
  "use strict";
2
2
  /**
3
- * EXPRESS TYPE AUGMENTATION + JWT PAYLOAD TYPES (@discover-cloud/shared)
4
- * ──────────────────────────────────────────────────────────────────────────
5
- * Single source of truth for everything attached to Express's Request object
6
- * and all internal JWT payload shapes.
7
- *
8
- * Import in each service's entrypoint to activate the augmentation:
9
- * import "@discover-cloud/shared/types/express";
10
- *
11
- * ─── Permission flow ────────────────────────────────────────────────────
12
- * JWT carries: accountId + accountRole (lean payload, no perms)
13
- * Redis derives: GlobalPermission[] (role map on cache miss)
14
- * AccessContext has: perms (resolved by auth middleware)
15
- *
16
- * perms never touch the JWT — they live in the Redis permission cache and
17
- * are resolved into req.accessContext by RequireAuthMiddleware per request.
18
- * ────────────────────────────────────────────────────────────────────────
3
+ * @file express.types.ts
4
+ * @description Express Request type augmentations and authentication context definitions.
19
5
  */
20
6
  Object.defineProperty(exports, "__esModule", { value: true });
21
- exports.isHumanPayload = isHumanPayload;
22
- exports.isMachinePayload = isMachinePayload;
23
- exports.assertMachinePayload = assertMachinePayload;
24
- exports.isHumanContext = isHumanContext;
7
+ exports.isAccessToken = isAccessToken;
8
+ exports.isRefreshToken = isRefreshToken;
9
+ exports.isMachineToken = isMachineToken;
10
+ exports.isUserContext = isUserContext;
25
11
  exports.isMachineContext = isMachineContext;
26
- /* ====================================================================
27
- 4. TYPE GUARDS
28
-
29
- Use these over raw property checks — TypeScript narrows the union
30
- correctly through predicate functions on both InternalJwtPayload
31
- and AccessContext.
32
- ==================================================================== */
33
- function isHumanPayload(payload) {
34
- return payload.isMachine === false;
12
+ exports.assertMachineToken = assertMachineToken;
13
+ /* ---------------------------------------------------------------------------
14
+ Type Guards
15
+ --------------------------------------------------------------------------- */
16
+ function isAccessToken(payload) {
17
+ return payload.typ === 'access';
35
18
  }
36
- function isMachinePayload(payload) {
37
- return payload.isMachine === true;
19
+ function isRefreshToken(payload) {
20
+ return payload.typ === 'refresh';
38
21
  }
39
- /**
40
- * Runtime assertion for jose.jwtVerify() results.
41
- *
42
- * jose returns a generic JWTPayload because it cannot know
43
- * our custom claims. After verification + this assertion,
44
- * TypeScript safely treats it as MachineInternalJwtPayload.
45
- */
46
- function assertMachinePayload(payload) {
47
- if (payload["typ"] !== "internal" ||
48
- payload["isMachine"] !== true ||
49
- typeof payload["serviceId"] !== "string" ||
50
- typeof payload["jti"] !== "string" ||
51
- typeof payload["caller"] !== "string") {
52
- throw new Error("Invalid machine JWT payload");
53
- }
22
+ function isMachineToken(payload) {
23
+ return payload.typ === 'machine';
54
24
  }
55
- function isHumanContext(ctx) {
56
- return ctx.kind === "human";
25
+ function isUserContext(ctx) {
26
+ return ctx.type === 'user';
57
27
  }
58
28
  function isMachineContext(ctx) {
59
- return ctx.kind === "machine";
29
+ return ctx.type === 'machine';
30
+ }
31
+ /**
32
+ * Runtime assertion for service tokens.
33
+ */
34
+ function assertMachineToken(payload) {
35
+ if (payload['typ'] !== 'machine' ||
36
+ typeof payload['serviceId'] !== 'string' ||
37
+ typeof payload['jti'] !== 'string' ||
38
+ !Array.isArray(payload['scopes'])) {
39
+ throw new Error('Invalid machine token payload');
40
+ }
60
41
  }
@@ -1 +1 @@
1
- export * from "./express.types";
1
+ export * from './express.types';
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @file date.util.ts
3
+ * @description Date formatting and serialization helper utilities.
4
+ */
5
+ export declare const toIso: (date: Date) => string;
6
+ export declare const toIsoOrNull: (date: Date | null | undefined) => string | null;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ /**
3
+ * @file date.util.ts
4
+ * @description Date formatting and serialization helper utilities.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.toIsoOrNull = exports.toIso = void 0;
8
+ const toIso = (date) => date.toISOString();
9
+ exports.toIso = toIso;
10
+ const toIsoOrNull = (date) => date ? date.toISOString() : null;
11
+ exports.toIsoOrNull = toIsoOrNull;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @file env.util.ts
3
+ * @description Helper functions to retrieve and validate environment variable settings safely.
4
+ */
5
+ export declare function getEnv(name: string): string;
6
+ export declare function getEnvOptional(name: string): string | undefined;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ /**
3
+ * @file env.util.ts
4
+ * @description Helper functions to retrieve and validate environment variable settings safely.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.getEnv = getEnv;
8
+ exports.getEnvOptional = getEnvOptional;
9
+ function getEnv(name) {
10
+ const value = process.env[name];
11
+ if (!value) {
12
+ throw new Error(`Missing required environment variable: ${name}. Ensure it is set in your .env file.`);
13
+ }
14
+ return value;
15
+ }
16
+ function getEnvOptional(name) {
17
+ const value = process.env[name];
18
+ return value === '' ? undefined : value;
19
+ }
@@ -1,4 +1,5 @@
1
- export * from "./response.utils";
2
- export * from "./logger.utils";
3
- export * from "./date.utils";
4
- export * from "./env.utils";
1
+ export * from './response.util';
2
+ export * from './logger.util';
3
+ export * from './date.util';
4
+ export * from './env.util';
5
+ export * from './pagination.util';
@@ -14,7 +14,8 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./response.utils"), exports);
18
- __exportStar(require("./logger.utils"), exports);
19
- __exportStar(require("./date.utils"), exports);
20
- __exportStar(require("./env.utils"), exports);
17
+ __exportStar(require("./response.util"), exports);
18
+ __exportStar(require("./logger.util"), exports);
19
+ __exportStar(require("./date.util"), exports);
20
+ __exportStar(require("./env.util"), exports);
21
+ __exportStar(require("./pagination.util"), exports);
@@ -0,0 +1,31 @@
1
+ /**
2
+ * @file logger.utils.ts
3
+ * @description Minimal logger contract interface and common logger implementations (console, silent no-op).
4
+ */
5
+ /**
6
+ * Standard logger interface that components can depend on to avoid coupling to
7
+ * specific third-party logging engines.
8
+ */
9
+ export interface ILogger {
10
+ debug(obj: object, msg?: string): void;
11
+ debug(msg: string): void;
12
+ info(obj: object, msg?: string): void;
13
+ info(msg: string): void;
14
+ warn(obj: object, msg?: string): void;
15
+ warn(msg: string): void;
16
+ error(obj: object, msg?: string): void;
17
+ error(msg: string): void;
18
+ }
19
+ /**
20
+ * Silent no-op implementation discarded all log payloads.
21
+ */
22
+ export declare const noopLogger: ILogger;
23
+ /**
24
+ * Console logger implementing the ILogger interface mapping to native console output.
25
+ */
26
+ export declare const consoleLogger: ILogger;
27
+ /**
28
+ * Creates an ILogger adapter for a given Pino logger instance.
29
+ * @param pinoLogger Any Pino logger instance.
30
+ */
31
+ export declare function createPinoAdapter(pinoLogger: any): ILogger;
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ /**
3
+ * @file logger.utils.ts
4
+ * @description Minimal logger contract interface and common logger implementations (console, silent no-op).
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.consoleLogger = exports.noopLogger = void 0;
8
+ exports.createPinoAdapter = createPinoAdapter;
9
+ /**
10
+ * Silent no-op implementation discarded all log payloads.
11
+ */
12
+ exports.noopLogger = {
13
+ debug: () => { },
14
+ info: () => { },
15
+ warn: () => { },
16
+ error: () => { },
17
+ };
18
+ /**
19
+ * Console logger implementing the ILogger interface mapping to native console output.
20
+ */
21
+ exports.consoleLogger = {
22
+ debug: (objOrMsg, msg) => {
23
+ if (typeof objOrMsg === 'string') {
24
+ console.debug(objOrMsg);
25
+ }
26
+ else {
27
+ console.debug(msg ?? '', objOrMsg);
28
+ }
29
+ },
30
+ info: (objOrMsg, msg) => {
31
+ if (typeof objOrMsg === 'string') {
32
+ console.info(objOrMsg);
33
+ }
34
+ else {
35
+ console.info(msg ?? '', objOrMsg);
36
+ }
37
+ },
38
+ warn: (objOrMsg, msg) => {
39
+ if (typeof objOrMsg === 'string') {
40
+ console.warn(objOrMsg);
41
+ }
42
+ else {
43
+ console.warn(msg ?? '', objOrMsg);
44
+ }
45
+ },
46
+ error: (objOrMsg, msg) => {
47
+ if (typeof objOrMsg === 'string') {
48
+ console.error(objOrMsg);
49
+ }
50
+ else {
51
+ console.error(msg ?? '', objOrMsg);
52
+ }
53
+ },
54
+ };
55
+ /**
56
+ * Creates an ILogger adapter for a given Pino logger instance.
57
+ * @param pinoLogger Any Pino logger instance.
58
+ */
59
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
60
+ function createPinoAdapter(pinoLogger) {
61
+ return {
62
+ debug(objOrMsg, msg) {
63
+ if (typeof objOrMsg === 'string') {
64
+ pinoLogger.debug(objOrMsg);
65
+ return;
66
+ }
67
+ pinoLogger.debug(objOrMsg, msg);
68
+ },
69
+ info(objOrMsg, msg) {
70
+ if (typeof objOrMsg === 'string') {
71
+ pinoLogger.info(objOrMsg);
72
+ return;
73
+ }
74
+ pinoLogger.info(objOrMsg, msg);
75
+ },
76
+ warn(objOrMsg, msg) {
77
+ if (typeof objOrMsg === 'string') {
78
+ pinoLogger.warn(objOrMsg);
79
+ return;
80
+ }
81
+ pinoLogger.warn(objOrMsg, msg);
82
+ },
83
+ error(objOrMsg, msg) {
84
+ if (typeof objOrMsg === 'string') {
85
+ pinoLogger.error(objOrMsg);
86
+ return;
87
+ }
88
+ pinoLogger.error(objOrMsg, msg);
89
+ },
90
+ };
91
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @file pagination.utils.ts
3
+ * @description Helper functions to calculate pagination metadata from repository outputs.
4
+ */
5
+ import { PaginationMeta } from '../dtos';
6
+ export declare function buildPaginationMeta(totalItems: number, limit: number, offset: number): PaginationMeta;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ /**
3
+ * @file pagination.utils.ts
4
+ * @description Helper functions to calculate pagination metadata from repository outputs.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.buildPaginationMeta = buildPaginationMeta;
8
+ function buildPaginationMeta(totalItems, limit, offset) {
9
+ const pageSize = limit > 0 ? limit : 1;
10
+ const totalPages = Math.ceil(totalItems / pageSize);
11
+ const currentPage = Math.floor(offset / pageSize) + 1;
12
+ return {
13
+ page: currentPage,
14
+ pageSize,
15
+ totalItems,
16
+ totalPages,
17
+ hasNext: currentPage < totalPages,
18
+ hasPrev: currentPage > 1,
19
+ };
20
+ }
@@ -0,0 +1,10 @@
1
+ import { AsyncLocalStorage } from 'async_hooks';
2
+ import { AuditActorType } from '../types/audit.types';
3
+ export interface RequestContextData {
4
+ requestId: string;
5
+ ipAddress: string | null;
6
+ userAgent: string | null;
7
+ actorId?: string | null;
8
+ actorType?: AuditActorType;
9
+ }
10
+ export declare const requestContextStorage: AsyncLocalStorage<RequestContextData>;
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.requestContextStorage = void 0;
4
+ const async_hooks_1 = require("async_hooks");
5
+ exports.requestContextStorage = new async_hooks_1.AsyncLocalStorage();
@@ -0,0 +1,27 @@
1
+ /**
2
+ * @file response.utils.ts
3
+ * @description Helper functions to construct and send standardized API success and error response envelopes.
4
+ */
5
+ import { Response, Request } from 'express';
6
+ /**
7
+ * Sends a successful standardized API response containing the data payload.
8
+ *
9
+ * @param {Response} res - Express response object.
10
+ * @param {Request} req - Express request object.
11
+ * @param {T} data - The payload data.
12
+ * @param {number} [statusCode=200] - HTTP status code.
13
+ * @returns {void}
14
+ */
15
+ export declare const success: <T>(res: Response, req: Request, data: T, statusCode?: number) => void;
16
+ /**
17
+ * Sends a failed standardized API response containing error details.
18
+ *
19
+ * @param {Response} res - Express response object.
20
+ * @param {Request} req - Express request object.
21
+ * @param {string} message - Human-readable error message.
22
+ * @param {string} code - Error code mapping.
23
+ * @param {number} [statusCode=400] - HTTP status code.
24
+ * @param {unknown} [details] - Optional error metadata details.
25
+ * @returns {void}
26
+ */
27
+ export declare const failure: (res: Response, req: Request, message: string, code: string, statusCode?: number, details?: unknown) => void;