@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,61 +0,0 @@
1
- "use strict";
2
- /**
3
- * ENVIRONMENT HELPERS (@discover-cloud/shared)
4
- * ───────────────────────────────────────────────
5
- * Typed accessors for process.env values.
6
- *
7
- * Why not read process.env directly?
8
- * - process.env values are always string | undefined. Reading them inline
9
- * forces every callsite to handle undefined or cast — this pushes that
10
- * contract to one place.
11
- * - getEnv() fails fast at startup (before serving any traffic) if a
12
- * required variable is absent, surfacing misconfiguration immediately
13
- * rather than at runtime inside a request handler.
14
- * - Centralised access makes it straightforward to add validation, type
15
- * coercion, or secret-redaction logic later without touching callsites.
16
- *
17
- * Usage:
18
- * // Required — throws at startup if missing
19
- * const dbUrl = getEnv("DATABASE_URL");
20
- * const jwtSecret = getEnv("JWT_SECRET");
21
- *
22
- * // Optional — returns undefined (or a typed default) when absent
23
- * const logLevel = getEnvOptional("LOG_LEVEL") ?? "info";
24
- * const port = Number(getEnvOptional("PORT") ?? "3000");
25
- */
26
- Object.defineProperty(exports, "__esModule", { value: true });
27
- exports.getEnv = getEnv;
28
- exports.getEnvOptional = getEnvOptional;
29
- /**
30
- * getEnv
31
- * Returns the value of a required environment variable.
32
- * Throws at call time (typically during service startup) if the variable
33
- * is absent or empty — this is intentional: missing required config should
34
- * crash the process before it begins serving traffic.
35
- *
36
- * Empty string ("") is treated as missing because it is almost always an
37
- * accidental misconfiguration (e.g. `SECRET=` with no value in a .env file).
38
- */
39
- function getEnv(name) {
40
- const value = process.env[name];
41
- if (!value) {
42
- throw new Error(`Missing required environment variable: ${name}. ` +
43
- `Ensure it is set in your .env file or deployment environment.`);
44
- }
45
- return value;
46
- }
47
- /**
48
- * getEnvOptional
49
- * Returns the value of an optional environment variable, or undefined
50
- * if it is absent or empty. Use with a nullish coalescing default:
51
- *
52
- * const logLevel = getEnvOptional("LOG_LEVEL") ?? "info";
53
- *
54
- * Returns undefined (not empty string) so callers can safely use `??`
55
- * and `||` without needing to guard against empty strings separately.
56
- */
57
- function getEnvOptional(name) {
58
- const value = process.env[name];
59
- // Normalise empty string to undefined — same convention as getEnv.
60
- return value === "" ? undefined : value;
61
- }
@@ -1,66 +0,0 @@
1
- /**
2
- * LOGGER INTERFACE (@discover-cloud/shared)
3
- * ────────────────────────────────────────────
4
- * A minimal logger contract that shared code can depend on.
5
- * Each service injects its own concrete implementation (pino, winston, etc.).
6
- *
7
- * Shared classes (RequireAuthMiddleware, PermissionCacheService, etc.)
8
- * accept ILogger via constructor injection — they never import a concrete
9
- * logger directly, keeping the shared package dependency-free.
10
- *
11
- * ─── Usage in shared classes ────────────────────────────────────────
12
- * class RequireAuthMiddleware {
13
- * constructor(
14
- * private readonly verifier: InternalJwtVerifier,
15
- * private readonly logger: ILogger = noopLogger,
16
- * ) {}
17
- * }
18
- *
19
- * ─── Wiring in each service ─────────────────────────────────────────
20
- * import pino from "pino";
21
- * const logger = pino({ level: "info" });
22
- * const requireAuth = new RequireAuthMiddleware(jwtVerifier, logger);
23
- *
24
- * // pino satisfies ILogger — its method signatures are compatible.
25
- *
26
- * ─── Signature convention ───────────────────────────────────────────
27
- * Follows pino's overloaded signature:
28
- * logger.info({ userId }, "User logged in") — object first, then message
29
- * logger.info("Simple message") — string only
30
- *
31
- * This matches pino natively and means a pino instance can be passed
32
- * directly without any wrapping.
33
- */
34
- export interface ILogger {
35
- debug(obj: object, msg?: string): void;
36
- debug(msg: string): void;
37
- info(obj: object, msg?: string): void;
38
- info(msg: string): void;
39
- warn(obj: object, msg?: string): void;
40
- warn(msg: string): void;
41
- error(obj: object, msg?: string): void;
42
- error(msg: string): void;
43
- }
44
- /**
45
- * noopLogger
46
- * Silent no-op implementation — the safe default when no logger is injected.
47
- * All log calls are discarded. Use in tests and library consumers that
48
- * don't want log noise.
49
- */
50
- export declare const noopLogger: ILogger;
51
- /**
52
- * consoleLogger
53
- * Thin console wrapper that follows the pino (obj, msg?) calling convention.
54
- * Useful for local development and simple services that don't need structured
55
- * logging — pass this instead of wiring up pino.
56
- *
57
- * Output order mirrors pino: message first, then the context object on a
58
- * separate argument so it appears as structured context in most terminals.
59
- *
60
- * consoleLogger.info({ userId: "abc" }, "User logged in")
61
- * → console.info("User logged in", { userId: "abc" })
62
- *
63
- * consoleLogger.info("Simple message")
64
- * → console.info("Simple message")
65
- */
66
- export declare const consoleLogger: ILogger;
@@ -1,97 +0,0 @@
1
- "use strict";
2
- /**
3
- * LOGGER INTERFACE (@discover-cloud/shared)
4
- * ────────────────────────────────────────────
5
- * A minimal logger contract that shared code can depend on.
6
- * Each service injects its own concrete implementation (pino, winston, etc.).
7
- *
8
- * Shared classes (RequireAuthMiddleware, PermissionCacheService, etc.)
9
- * accept ILogger via constructor injection — they never import a concrete
10
- * logger directly, keeping the shared package dependency-free.
11
- *
12
- * ─── Usage in shared classes ────────────────────────────────────────
13
- * class RequireAuthMiddleware {
14
- * constructor(
15
- * private readonly verifier: InternalJwtVerifier,
16
- * private readonly logger: ILogger = noopLogger,
17
- * ) {}
18
- * }
19
- *
20
- * ─── Wiring in each service ─────────────────────────────────────────
21
- * import pino from "pino";
22
- * const logger = pino({ level: "info" });
23
- * const requireAuth = new RequireAuthMiddleware(jwtVerifier, logger);
24
- *
25
- * // pino satisfies ILogger — its method signatures are compatible.
26
- *
27
- * ─── Signature convention ───────────────────────────────────────────
28
- * Follows pino's overloaded signature:
29
- * logger.info({ userId }, "User logged in") — object first, then message
30
- * logger.info("Simple message") — string only
31
- *
32
- * This matches pino natively and means a pino instance can be passed
33
- * directly without any wrapping.
34
- */
35
- Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.consoleLogger = exports.noopLogger = void 0;
37
- /**
38
- * noopLogger
39
- * Silent no-op implementation — the safe default when no logger is injected.
40
- * All log calls are discarded. Use in tests and library consumers that
41
- * don't want log noise.
42
- */
43
- exports.noopLogger = {
44
- debug: () => { },
45
- info: () => { },
46
- warn: () => { },
47
- error: () => { },
48
- };
49
- /**
50
- * consoleLogger
51
- * Thin console wrapper that follows the pino (obj, msg?) calling convention.
52
- * Useful for local development and simple services that don't need structured
53
- * logging — pass this instead of wiring up pino.
54
- *
55
- * Output order mirrors pino: message first, then the context object on a
56
- * separate argument so it appears as structured context in most terminals.
57
- *
58
- * consoleLogger.info({ userId: "abc" }, "User logged in")
59
- * → console.info("User logged in", { userId: "abc" })
60
- *
61
- * consoleLogger.info("Simple message")
62
- * → console.info("Simple message")
63
- */
64
- exports.consoleLogger = {
65
- debug: (objOrMsg, msg) => {
66
- if (typeof objOrMsg === "string") {
67
- console.debug(objOrMsg);
68
- }
69
- else {
70
- console.debug(msg ?? "", objOrMsg);
71
- }
72
- },
73
- info: (objOrMsg, msg) => {
74
- if (typeof objOrMsg === "string") {
75
- console.info(objOrMsg);
76
- }
77
- else {
78
- console.info(msg ?? "", objOrMsg);
79
- }
80
- },
81
- warn: (objOrMsg, msg) => {
82
- if (typeof objOrMsg === "string") {
83
- console.warn(objOrMsg);
84
- }
85
- else {
86
- console.warn(msg ?? "", objOrMsg);
87
- }
88
- },
89
- error: (objOrMsg, msg) => {
90
- if (typeof objOrMsg === "string") {
91
- console.error(objOrMsg);
92
- }
93
- else {
94
- console.error(msg ?? "", objOrMsg);
95
- }
96
- },
97
- };
@@ -1,4 +0,0 @@
1
- import { Response } from "express";
2
- export declare const success: <T>(res: Response, data: T, statusCode?: number) => Response<any, Record<string, any>>;
3
- export declare const failure: (res: Response, message: string, code: string, // <-- Added to match the DTO requirement
4
- statusCode?: number, details?: unknown) => Response<any, Record<string, any>>;
@@ -1,35 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.failure = exports.success = void 0;
4
- const success = (res, data, statusCode = 200) => {
5
- // Cast to Request to access properties safely, assuming module augmentation
6
- const req = res.req;
7
- const response = {
8
- success: true,
9
- data,
10
- meta: {
11
- requestId: req.id ?? "unknown", // Fallback if middleware failed
12
- timestamp: new Date().toISOString()
13
- }
14
- };
15
- return res.status(statusCode).json(response);
16
- };
17
- exports.success = success;
18
- const failure = (res, message, code, // <-- Added to match the DTO requirement
19
- statusCode = 400, details) => {
20
- const req = res.req;
21
- const response = {
22
- success: false,
23
- error: {
24
- code, // <-- Added here
25
- message,
26
- details: details ?? null
27
- },
28
- meta: {
29
- requestId: req.id ?? "unknown",
30
- timestamp: new Date().toISOString()
31
- }
32
- };
33
- return res.status(statusCode).json(response);
34
- };
35
- exports.failure = failure;
@@ -1,54 +0,0 @@
1
- import { Response, Request } from "express";
2
- /**
3
- * RESPONSE HELPERS (@discover-cloud/shared)
4
- * ────────────────────────────────────────────
5
- * Typed wrappers around res.json() that enforce the ApiSuccessResponse
6
- * and ApiErrorResponse envelope shapes across all services.
7
- *
8
- * Both helpers accept req explicitly rather than reading res.req — this
9
- * makes the dependency visible at the call site and avoids the res.req
10
- * cast anti-pattern.
11
- *
12
- * requestId fallback:
13
- * req.id is set by requestId middleware. The randomUUID() fallback should
14
- * never fire in a correctly wired service — if it does, it means requestId
15
- * middleware was not registered before this helper was called. The fallback
16
- * keeps the response well-formed but the generated ID won't correlate with
17
- * any upstream trace. Check middleware registration order if you see UUIDs
18
- * in responses that don't match the x-request-id header.
19
- */
20
- /**
21
- * success
22
- * Wraps data in an ApiSuccessResponse envelope and sends it.
23
- *
24
- * @param res - Express response object
25
- * @param req - Express request object (for requestId + timestamp)
26
- * @param data - The response payload; typed as T for type inference
27
- * @param statusCode - HTTP status code (default 200)
28
- *
29
- * Usage:
30
- * success<CloudAccountDto>(res, req, accountDto);
31
- * success<PaginatedResponseDto<CloudAccountDto>>(res, req, paginatedResult, 200);
32
- * success<MessageResponseDto>(res, req, { message: "Deleted" }, 200);
33
- */
34
- export declare const success: <T>(res: Response, req: Request, data: T, statusCode?: number) => void;
35
- /**
36
- * failure
37
- * Wraps an error in an ApiErrorResponse envelope and sends it.
38
- *
39
- * @param res - Express response object
40
- * @param req - Express request object (for requestId + timestamp)
41
- * @param message - Human-readable error description
42
- * @param code - Machine-readable error code (maps to AppError.code)
43
- * @param statusCode - HTTP status code (default 400)
44
- * @param details - Optional structured context (e.g. Zod flatten() output).
45
- * Never put secrets, stack traces, or raw DB errors here.
46
- *
47
- * details is omitted from the response body when not provided — this avoids
48
- * "details": null noise in responses and keeps the shape clean for clients.
49
- *
50
- * Usage:
51
- * failure(res, req, "Account not found", "NOT_FOUND", 404);
52
- * failure(res, req, "Validation failed", "VALIDATION_ERROR", 400, err.flatten());
53
- */
54
- export declare const failure: (res: Response, req: Request, message: string, code: string, statusCode?: number, details?: unknown) => void;
@@ -1,85 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.failure = exports.success = void 0;
4
- const crypto_1 = require("crypto");
5
- /**
6
- * RESPONSE HELPERS (@discover-cloud/shared)
7
- * ────────────────────────────────────────────
8
- * Typed wrappers around res.json() that enforce the ApiSuccessResponse
9
- * and ApiErrorResponse envelope shapes across all services.
10
- *
11
- * Both helpers accept req explicitly rather than reading res.req — this
12
- * makes the dependency visible at the call site and avoids the res.req
13
- * cast anti-pattern.
14
- *
15
- * requestId fallback:
16
- * req.id is set by requestId middleware. The randomUUID() fallback should
17
- * never fire in a correctly wired service — if it does, it means requestId
18
- * middleware was not registered before this helper was called. The fallback
19
- * keeps the response well-formed but the generated ID won't correlate with
20
- * any upstream trace. Check middleware registration order if you see UUIDs
21
- * in responses that don't match the x-request-id header.
22
- */
23
- /**
24
- * success
25
- * Wraps data in an ApiSuccessResponse envelope and sends it.
26
- *
27
- * @param res - Express response object
28
- * @param req - Express request object (for requestId + timestamp)
29
- * @param data - The response payload; typed as T for type inference
30
- * @param statusCode - HTTP status code (default 200)
31
- *
32
- * Usage:
33
- * success<CloudAccountDto>(res, req, accountDto);
34
- * success<PaginatedResponseDto<CloudAccountDto>>(res, req, paginatedResult, 200);
35
- * success<MessageResponseDto>(res, req, { message: "Deleted" }, 200);
36
- */
37
- const success = (res, req, data, statusCode = 200) => {
38
- const response = {
39
- success: true,
40
- data,
41
- meta: {
42
- requestId: req.id ?? (0, crypto_1.randomUUID)(),
43
- timestamp: new Date().toISOString(),
44
- },
45
- };
46
- res.status(statusCode).json(response);
47
- };
48
- exports.success = success;
49
- /**
50
- * failure
51
- * Wraps an error in an ApiErrorResponse envelope and sends it.
52
- *
53
- * @param res - Express response object
54
- * @param req - Express request object (for requestId + timestamp)
55
- * @param message - Human-readable error description
56
- * @param code - Machine-readable error code (maps to AppError.code)
57
- * @param statusCode - HTTP status code (default 400)
58
- * @param details - Optional structured context (e.g. Zod flatten() output).
59
- * Never put secrets, stack traces, or raw DB errors here.
60
- *
61
- * details is omitted from the response body when not provided — this avoids
62
- * "details": null noise in responses and keeps the shape clean for clients.
63
- *
64
- * Usage:
65
- * failure(res, req, "Account not found", "NOT_FOUND", 404);
66
- * failure(res, req, "Validation failed", "VALIDATION_ERROR", 400, err.flatten());
67
- */
68
- const failure = (res, req, message, code, statusCode = 400, details) => {
69
- const response = {
70
- success: false,
71
- error: {
72
- code,
73
- message,
74
- // Spread details only when present — omitting the key entirely is
75
- // cleaner than sending "details": undefined (which JSON.stringify drops anyway).
76
- ...(details !== undefined ? { details } : {}),
77
- },
78
- meta: {
79
- requestId: req.id ?? (0, crypto_1.randomUUID)(),
80
- timestamp: new Date().toISOString(),
81
- },
82
- };
83
- res.status(statusCode).json(response);
84
- };
85
- exports.failure = failure;