@omnitronix/game-engine-sdk 1.0.4 → 2.0.2

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 (76) hide show
  1. package/CHANGELOG.md +86 -0
  2. package/MIGRATION.md +126 -0
  3. package/dist/bootstrap/index.d.ts +4 -1
  4. package/dist/bootstrap/index.d.ts.map +1 -1
  5. package/dist/bootstrap/index.js +32 -32
  6. package/dist/common/api-docs/setup-documentation.d.ts +1 -1
  7. package/dist/common/api-docs/setup-documentation.d.ts.map +1 -1
  8. package/dist/common/error-handling/all-exceptions.filter.d.ts +0 -3
  9. package/dist/common/error-handling/all-exceptions.filter.d.ts.map +1 -1
  10. package/dist/common/error-handling/all-exceptions.filter.js +35 -21
  11. package/dist/common/error-handling/error-code-mapper.d.ts.map +1 -1
  12. package/dist/common/error-handling/error-code-mapper.js +15 -70
  13. package/dist/common/error-handling/internal-error-code.d.ts +13 -59
  14. package/dist/common/error-handling/internal-error-code.d.ts.map +1 -1
  15. package/dist/common/error-handling/internal-error-code.js +16 -68
  16. package/dist/common/logger/logger.d.ts +2 -3
  17. package/dist/common/logger/logger.d.ts.map +1 -1
  18. package/dist/common/logger/logger.js +3 -16
  19. package/dist/common/logger/logging.middleware.d.ts.map +1 -1
  20. package/dist/common/logger/logging.middleware.js +16 -4
  21. package/dist/common/metrics/prometheus.service.d.ts +5 -0
  22. package/dist/common/metrics/prometheus.service.d.ts.map +1 -1
  23. package/dist/common/metrics/prometheus.service.js +43 -3
  24. package/dist/common/retry/retry-policy.d.ts.map +1 -1
  25. package/dist/common/retry/retry-policy.js +9 -4
  26. package/dist/common/secrets-provider/secrets-provider.aws.d.ts.map +1 -1
  27. package/dist/common/secrets-provider/secrets-provider.aws.js +2 -1
  28. package/dist/esm/bootstrap/index.js +33 -33
  29. package/dist/esm/common/error-handling/all-exceptions.filter.js +36 -22
  30. package/dist/esm/common/error-handling/error-code-mapper.js +15 -70
  31. package/dist/esm/common/error-handling/internal-error-code.js +16 -68
  32. package/dist/esm/common/logger/logger.js +3 -16
  33. package/dist/esm/common/logger/logging.middleware.js +16 -4
  34. package/dist/esm/common/metrics/prometheus.service.js +10 -3
  35. package/dist/esm/common/retry/retry-policy.js +9 -4
  36. package/dist/esm/common/secrets-provider/secrets-provider.aws.js +2 -1
  37. package/dist/esm/generated/game-engine-registry_pb.js +5 -11
  38. package/dist/esm/generated/game-engine_pb.js +10 -24
  39. package/dist/esm/grpc/connect-router.middleware.js +7 -1
  40. package/dist/esm/grpc/game-engine.grpc.in-adapter.js +64 -20
  41. package/dist/esm/health/application/services/health.service.js +33 -39
  42. package/dist/esm/health/health.module.js +1 -1
  43. package/dist/esm/health/infrastructure/adapters/out/shutdown/shutdown.out-adapter.js +19 -4
  44. package/dist/esm/registration/adapters/game-engine-registry.grpc.out-adapter.js +3 -4
  45. package/dist/esm/registration/services/game-engine-auto-register.service.js +11 -8
  46. package/dist/generated/game-engine-registry_pb.d.ts +5 -5
  47. package/dist/generated/game-engine-registry_pb.d.ts.map +1 -1
  48. package/dist/generated/game-engine-registry_pb.js +4 -10
  49. package/dist/generated/game-engine_pb.d.ts +26 -10
  50. package/dist/generated/game-engine_pb.d.ts.map +1 -1
  51. package/dist/generated/game-engine_pb.js +8 -22
  52. package/dist/grpc/connect-router.middleware.d.ts +9 -1
  53. package/dist/grpc/connect-router.middleware.d.ts.map +1 -1
  54. package/dist/grpc/connect-router.middleware.js +7 -1
  55. package/dist/grpc/game-engine.grpc.in-adapter.d.ts +18 -3
  56. package/dist/grpc/game-engine.grpc.in-adapter.d.ts.map +1 -1
  57. package/dist/grpc/game-engine.grpc.in-adapter.js +64 -20
  58. package/dist/grpc/index.d.ts +1 -1
  59. package/dist/grpc/index.d.ts.map +1 -1
  60. package/dist/health/application/ports/out/shutdown.out-port.d.ts +2 -0
  61. package/dist/health/application/ports/out/shutdown.out-port.d.ts.map +1 -1
  62. package/dist/health/application/services/health.service.d.ts.map +1 -1
  63. package/dist/health/application/services/health.service.js +33 -39
  64. package/dist/health/domain/health.d.ts +1 -1
  65. package/dist/health/domain/health.d.ts.map +1 -1
  66. package/dist/health/health.module.js +1 -1
  67. package/dist/health/infrastructure/adapters/out/shutdown/shutdown.out-adapter.d.ts +2 -1
  68. package/dist/health/infrastructure/adapters/out/shutdown/shutdown.out-adapter.d.ts.map +1 -1
  69. package/dist/health/infrastructure/adapters/out/shutdown/shutdown.out-adapter.js +19 -4
  70. package/dist/registration/adapters/game-engine-registry.grpc.out-adapter.d.ts.map +1 -1
  71. package/dist/registration/adapters/game-engine-registry.grpc.out-adapter.js +3 -4
  72. package/dist/registration/services/game-engine-auto-register.service.d.ts.map +1 -1
  73. package/dist/registration/services/game-engine-auto-register.service.js +11 -8
  74. package/dist/types.d.ts +6 -5
  75. package/dist/types.d.ts.map +1 -1
  76. package/package.json +5 -3
@@ -1,67 +1,21 @@
1
+ /**
2
+ * Error codes relevant to game engine services.
3
+ *
4
+ * Scoped to game-engine SDK concerns only.
5
+ * Platform-level codes (sessions, operators, jackpots, geo, etc.)
6
+ * belong in the RGS platform, not in individual engine services.
7
+ */
1
8
  export declare enum InternalErrorCode {
2
- FORBIDDEN = "FORBIDDEN",
3
- INTERNAL_SERVER_ERROR = "INTERNAL_SERVER_ERROR",
4
- INSUFFICIENT_FUNDS = "INSUFFICIENT_FUNDS",
5
- INVALID_CURRENCY_CODE = "INVALID_CURRENCY_CODE",
6
- GAME_NOT_FOUND = "GAME_NOT_FOUND",
7
- GAME_CONFIG_NOT_FOUND = "GAME_CONFIG_NOT_FOUND",
8
- GAME_CONFIG_ALREADY_EXISTS_WITH_SAME_JURISDICTION_AND_RTP = "GAME_CONFIG_ALREADY_EXISTS_WITH_SAME_JURISDICTION_AND_RTP",
9
- OPERATOR_GAME_NOT_FOUND = "OPERATOR_GAME_NOT_FOUND",
10
- OPERATOR_GAME_ALREADY_ENABLED = "OPERATOR_GAME_ALREADY_ENABLED",
11
- INVALID_GAME_CONFIG_DATA = "INVALID_GAME_CONFIG_DATA",
12
- INVALID_GAME_UPDATE_DATA = "INVALID_GAME_UPDATE_DATA",
13
- GAME_CODE_ALREADY_EXISTS = "GAME_CODE_ALREADY_EXISTS",
14
9
  GAME_ENGINE_ERROR = "GAME_ENGINE_ERROR",
15
- GAME_OR_GAME_CONFIG_DISABLED = "GAME_OR_GAME_CONFIG_DISABLED",
16
10
  DEBUG_COMMANDS_DISABLED = "DEBUG_COMMANDS_DISABLED",
17
- INVALID_SESSION = "INVALID_SESSION",
18
- SESSION_NOT_FOUND = "SESSION_NOT_FOUND",
19
- SESSION_NOT_ACTIVE = "SESSION_NOT_ACTIVE",
20
- SESSION_MISMATCH = "SESSION_MISMATCH",
21
- INVALID_STATE_TRANSITION = "INVALID_STATE_TRANSITION",
22
- INVALID_BET_AMOUNT = "INVALID_BET_AMOUNT",
23
- REALITY_CHECK_IN_PROGRESS = "REALITY_CHECK_IN_PROGRESS",
24
- SESSION_TERMINATED = "SESSION_TERMINATED",
25
- SESSION_CANNOT_BE_TERMINATED = "SESSION_CANNOT_BE_TERMINATED",
26
- SESSION_AUTO_RESOLVE_FAILED = "SESSION_AUTO_RESOLVE_FAILED",
27
- SESSION_ALREADY_EXISTS = "SESSION_ALREADY_EXISTS",
28
- INCOMPATIBLE_GAMEPLAY_CONFIG = "INCOMPATIBLE_GAMEPLAY_CONFIG",
29
11
  UNKNOWN_COMMAND = "UNKNOWN_COMMAND",
30
- MISSING_OPERATOR_CODE = "MISSING_OPERATOR_CODE",
31
- INVALID_OPERATOR_CODE = "INVALID_OPERATOR_CODE",
32
- OPERATOR_NOT_FOUND = "OPERATOR_NOT_FOUND",
33
- OPERATOR_INACTIVE = "OPERATOR_INACTIVE",
34
- COUNTRY_CODE_RESTRICTED = "COUNTRY_CODE_RESTRICTED",
12
+ INVALID_COMMAND = "INVALID_COMMAND",
13
+ INVALID_RNG_SEED = "INVALID_RNG_SEED",
14
+ INTERNAL_SERVER_ERROR = "INTERNAL_SERVER_ERROR",
15
+ FORBIDDEN = "FORBIDDEN",
35
16
  UNAUTHORIZED = "UNAUTHORIZED",
36
- AUTH_VALIDATION_FAILED = "AUTH_VALIDATION_FAILED",
37
- BALANCE_NOT_FOUND = "BALANCE_NOT_FOUND",
38
- DEBIT_FAILED = "DEBIT_FAILED",
39
- CREDIT_FAILED = "CREDIT_FAILED",
40
- INVALID_AUTH_DATA = "INVALID_AUTH_DATA",
41
17
  VALIDATION_ERROR = "VALIDATION_ERROR",
42
- JURISDICTION_CONFIG_ALREADY_EXISTS = "JURISDICTION_CONFIG_ALREADY_EXISTS",
43
- JURISDICTION_CONFIG_NOT_FOUND = "JURISDICTION_CONFIG_NOT_FOUND",
44
- OPERATOR_JURISDICTION_CONFIG_NOT_FOUND = "OPERATOR_JURISDICTION_CONFIG_NOT_FOUND",
45
- GAME_ROUND_LOG_NOT_FOUND = "GAME_ROUND_LOG_NOT_FOUND",
46
- COUNTRY_NOT_PERMITTED = "COUNTRY_NOT_PERMITTED",
47
- GEO_VALIDATION_SERVICE_UNAVAILABLE = "GEO_VALIDATION_SERVICE_UNAVAILABLE",
48
- RESOURCE_NOT_FOUND = "RESOURCE_NOT_FOUND",
49
- FINANCIAL_TRANSACTION_NOT_FOUND = "FINANCIAL_TRANSACTION_NOT_FOUND",
50
- HEALTH_CHECK_FAILED = "HEALTH_CHECK_FAILED",
51
- JACKPOT_TYPE_NOT_FOUND = "JACKPOT_TYPE_NOT_FOUND",
52
- JACKPOT_TIER_NOT_FOUND = "JACKPOT_TIER_NOT_FOUND",
53
- JACKPOT_CONFIGURATION_NOT_FOUND = "JACKPOT_CONFIGURATION_NOT_FOUND",
54
- JACKPOT_CONFIGURATION_IS_ACTIVE = "JACKPOT_CONFIGURATION_IS_ACTIVE",
55
- JACKPOT_POOL_CONTRIBUTION_ALREADY_PROCESSED = "JACKPOT_POOL_CONTRIBUTION_ALREADY_PROCESSED",
56
- JACKPOT_TYPE_DOES_NOT_SUPPORT_TIERS = "JACKPOT_TYPE_DOES_NOT_SUPPORT_TIERS",
57
- RNG_SEED_NOT_FOUND = "RNG_SEED_NOT_FOUND",
58
- RNG_SEED_MISMATCH = "RNG_SEED_MISMATCH",
59
- MASTER_HASH_INVALID = "MASTER_HASH_INVALID",
60
- REPLAY_OUTCOME_MISMATCH = "REPLAY_OUTCOME_MISMATCH",
61
- CONCURRENT_MODIFICATION = "CONCURRENT_MODIFICATION",
62
- ACCOUNT_LOCKED = "ACCOUNT_LOCKED",
63
- DAILY_LIMIT_EXCEEDED = "DAILY_LIMIT_EXCEEDED",
64
- INVALID_AMOUNT = "INVALID_AMOUNT",
65
- SERVICE_UNAVAILABLE = "SERVICE_UNAVAILABLE"
18
+ SERVICE_UNAVAILABLE = "SERVICE_UNAVAILABLE",
19
+ HEALTH_CHECK_FAILED = "HEALTH_CHECK_FAILED"
66
20
  }
67
21
  //# sourceMappingURL=internal-error-code.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"internal-error-code.d.ts","sourceRoot":"","sources":["../../../src/common/error-handling/internal-error-code.ts"],"names":[],"mappings":"AAAA,oBAAY,iBAAiB;IAC3B,SAAS,cAAc;IACvB,qBAAqB,0BAA0B;IAC/C,kBAAkB,uBAAuB;IACzC,qBAAqB,0BAA0B;IAE/C,cAAc,mBAAmB;IACjC,qBAAqB,0BAA0B;IAC/C,yDAAyD,8DAA8D;IACvH,uBAAuB,4BAA4B;IACnD,6BAA6B,kCAAkC;IAC/D,wBAAwB,6BAA6B;IACrD,wBAAwB,6BAA6B;IACrD,wBAAwB,6BAA6B;IACrD,iBAAiB,sBAAsB;IACvC,4BAA4B,iCAAiC;IAC7D,uBAAuB,4BAA4B;IAEnD,eAAe,oBAAoB;IACnC,iBAAiB,sBAAsB;IACvC,kBAAkB,uBAAuB;IACzC,gBAAgB,qBAAqB;IACrC,wBAAwB,6BAA6B;IACrD,kBAAkB,uBAAuB;IACzC,yBAAyB,8BAA8B;IACvD,kBAAkB,uBAAuB;IACzC,4BAA4B,iCAAiC;IAC7D,2BAA2B,gCAAgC;IAC3D,sBAAsB,2BAA2B;IACjD,4BAA4B,iCAAiC;IAC7D,eAAe,oBAAoB;IAEnC,qBAAqB,0BAA0B;IAC/C,qBAAqB,0BAA0B;IAC/C,kBAAkB,uBAAuB;IACzC,iBAAiB,sBAAsB;IACvC,uBAAuB,4BAA4B;IACnD,YAAY,iBAAiB;IAC7B,sBAAsB,2BAA2B;IACjD,iBAAiB,sBAAsB;IACvC,YAAY,iBAAiB;IAC7B,aAAa,kBAAkB;IAC/B,iBAAiB,sBAAsB;IACvC,gBAAgB,qBAAqB;IACrC,kCAAkC,uCAAuC;IACzE,6BAA6B,kCAAkC;IAC/D,sCAAsC,2CAA2C;IAGjF,wBAAwB,6BAA6B;IAErD,qBAAqB,0BAA0B;IAC/C,kCAAkC,uCAAuC;IACzE,kBAAkB,uBAAuB;IAGzC,+BAA+B,oCAAoC;IAGnE,mBAAmB,wBAAwB;IAG3C,sBAAsB,2BAA2B;IACjD,sBAAsB,2BAA2B;IACjD,+BAA+B,oCAAoC;IACnE,+BAA+B,oCAAoC;IACnE,2CAA2C,gDAAgD;IAC3F,mCAAmC,wCAAwC;IAG3E,kBAAkB,uBAAuB;IACzC,iBAAiB,sBAAsB;IACvC,mBAAmB,wBAAwB;IAC3C,uBAAuB,4BAA4B;IAEnD,uBAAuB,4BAA4B;IAEnD,cAAc,mBAAmB;IACjC,oBAAoB,yBAAyB;IAC7C,cAAc,mBAAmB;IACjC,mBAAmB,wBAAwB;CAC5C"}
1
+ {"version":3,"file":"internal-error-code.d.ts","sourceRoot":"","sources":["../../../src/common/error-handling/internal-error-code.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,oBAAY,iBAAiB;IAE3B,iBAAiB,sBAAsB;IACvC,uBAAuB,4BAA4B;IACnD,eAAe,oBAAoB;IACnC,eAAe,oBAAoB;IAGnC,gBAAgB,qBAAqB;IAGrC,qBAAqB,0BAA0B;IAC/C,SAAS,cAAc;IACvB,YAAY,iBAAiB;IAC7B,gBAAgB,qBAAqB;IACrC,mBAAmB,wBAAwB;IAG3C,mBAAmB,wBAAwB;CAC5C"}
@@ -1,80 +1,28 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.InternalErrorCode = void 0;
4
+ /**
5
+ * Error codes relevant to game engine services.
6
+ *
7
+ * Scoped to game-engine SDK concerns only.
8
+ * Platform-level codes (sessions, operators, jackpots, geo, etc.)
9
+ * belong in the RGS platform, not in individual engine services.
10
+ */
4
11
  var InternalErrorCode;
5
12
  (function (InternalErrorCode) {
6
- InternalErrorCode["FORBIDDEN"] = "FORBIDDEN";
7
- InternalErrorCode["INTERNAL_SERVER_ERROR"] = "INTERNAL_SERVER_ERROR";
8
- InternalErrorCode["INSUFFICIENT_FUNDS"] = "INSUFFICIENT_FUNDS";
9
- InternalErrorCode["INVALID_CURRENCY_CODE"] = "INVALID_CURRENCY_CODE";
10
- // Game Catalog errors
11
- InternalErrorCode["GAME_NOT_FOUND"] = "GAME_NOT_FOUND";
12
- InternalErrorCode["GAME_CONFIG_NOT_FOUND"] = "GAME_CONFIG_NOT_FOUND";
13
- InternalErrorCode["GAME_CONFIG_ALREADY_EXISTS_WITH_SAME_JURISDICTION_AND_RTP"] = "GAME_CONFIG_ALREADY_EXISTS_WITH_SAME_JURISDICTION_AND_RTP";
14
- InternalErrorCode["OPERATOR_GAME_NOT_FOUND"] = "OPERATOR_GAME_NOT_FOUND";
15
- InternalErrorCode["OPERATOR_GAME_ALREADY_ENABLED"] = "OPERATOR_GAME_ALREADY_ENABLED";
16
- InternalErrorCode["INVALID_GAME_CONFIG_DATA"] = "INVALID_GAME_CONFIG_DATA";
17
- InternalErrorCode["INVALID_GAME_UPDATE_DATA"] = "INVALID_GAME_UPDATE_DATA";
18
- InternalErrorCode["GAME_CODE_ALREADY_EXISTS"] = "GAME_CODE_ALREADY_EXISTS";
13
+ // Core game engine errors
19
14
  InternalErrorCode["GAME_ENGINE_ERROR"] = "GAME_ENGINE_ERROR";
20
- InternalErrorCode["GAME_OR_GAME_CONFIG_DISABLED"] = "GAME_OR_GAME_CONFIG_DISABLED";
21
15
  InternalErrorCode["DEBUG_COMMANDS_DISABLED"] = "DEBUG_COMMANDS_DISABLED";
22
- // Game Orchestrator errors
23
- InternalErrorCode["INVALID_SESSION"] = "INVALID_SESSION";
24
- InternalErrorCode["SESSION_NOT_FOUND"] = "SESSION_NOT_FOUND";
25
- InternalErrorCode["SESSION_NOT_ACTIVE"] = "SESSION_NOT_ACTIVE";
26
- InternalErrorCode["SESSION_MISMATCH"] = "SESSION_MISMATCH";
27
- InternalErrorCode["INVALID_STATE_TRANSITION"] = "INVALID_STATE_TRANSITION";
28
- InternalErrorCode["INVALID_BET_AMOUNT"] = "INVALID_BET_AMOUNT";
29
- InternalErrorCode["REALITY_CHECK_IN_PROGRESS"] = "REALITY_CHECK_IN_PROGRESS";
30
- InternalErrorCode["SESSION_TERMINATED"] = "SESSION_TERMINATED";
31
- InternalErrorCode["SESSION_CANNOT_BE_TERMINATED"] = "SESSION_CANNOT_BE_TERMINATED";
32
- InternalErrorCode["SESSION_AUTO_RESOLVE_FAILED"] = "SESSION_AUTO_RESOLVE_FAILED";
33
- InternalErrorCode["SESSION_ALREADY_EXISTS"] = "SESSION_ALREADY_EXISTS";
34
- InternalErrorCode["INCOMPATIBLE_GAMEPLAY_CONFIG"] = "INCOMPATIBLE_GAMEPLAY_CONFIG";
35
16
  InternalErrorCode["UNKNOWN_COMMAND"] = "UNKNOWN_COMMAND";
36
- // Operator errors
37
- InternalErrorCode["MISSING_OPERATOR_CODE"] = "MISSING_OPERATOR_CODE";
38
- InternalErrorCode["INVALID_OPERATOR_CODE"] = "INVALID_OPERATOR_CODE";
39
- InternalErrorCode["OPERATOR_NOT_FOUND"] = "OPERATOR_NOT_FOUND";
40
- InternalErrorCode["OPERATOR_INACTIVE"] = "OPERATOR_INACTIVE";
41
- InternalErrorCode["COUNTRY_CODE_RESTRICTED"] = "COUNTRY_CODE_RESTRICTED";
17
+ InternalErrorCode["INVALID_COMMAND"] = "INVALID_COMMAND";
18
+ // RNG integrity (GLI-19)
19
+ InternalErrorCode["INVALID_RNG_SEED"] = "INVALID_RNG_SEED";
20
+ // Infrastructure errors
21
+ InternalErrorCode["INTERNAL_SERVER_ERROR"] = "INTERNAL_SERVER_ERROR";
22
+ InternalErrorCode["FORBIDDEN"] = "FORBIDDEN";
42
23
  InternalErrorCode["UNAUTHORIZED"] = "UNAUTHORIZED";
43
- InternalErrorCode["AUTH_VALIDATION_FAILED"] = "AUTH_VALIDATION_FAILED";
44
- InternalErrorCode["BALANCE_NOT_FOUND"] = "BALANCE_NOT_FOUND";
45
- InternalErrorCode["DEBIT_FAILED"] = "DEBIT_FAILED";
46
- InternalErrorCode["CREDIT_FAILED"] = "CREDIT_FAILED";
47
- InternalErrorCode["INVALID_AUTH_DATA"] = "INVALID_AUTH_DATA";
48
24
  InternalErrorCode["VALIDATION_ERROR"] = "VALIDATION_ERROR";
49
- InternalErrorCode["JURISDICTION_CONFIG_ALREADY_EXISTS"] = "JURISDICTION_CONFIG_ALREADY_EXISTS";
50
- InternalErrorCode["JURISDICTION_CONFIG_NOT_FOUND"] = "JURISDICTION_CONFIG_NOT_FOUND";
51
- InternalErrorCode["OPERATOR_JURISDICTION_CONFIG_NOT_FOUND"] = "OPERATOR_JURISDICTION_CONFIG_NOT_FOUND";
52
- // Game round log errors
53
- InternalErrorCode["GAME_ROUND_LOG_NOT_FOUND"] = "GAME_ROUND_LOG_NOT_FOUND";
54
- // Geo Validation errors
55
- InternalErrorCode["COUNTRY_NOT_PERMITTED"] = "COUNTRY_NOT_PERMITTED";
56
- InternalErrorCode["GEO_VALIDATION_SERVICE_UNAVAILABLE"] = "GEO_VALIDATION_SERVICE_UNAVAILABLE";
57
- InternalErrorCode["RESOURCE_NOT_FOUND"] = "RESOURCE_NOT_FOUND";
58
- // Financial transaction errors
59
- InternalErrorCode["FINANCIAL_TRANSACTION_NOT_FOUND"] = "FINANCIAL_TRANSACTION_NOT_FOUND";
60
- //Health check errors
61
- InternalErrorCode["HEALTH_CHECK_FAILED"] = "HEALTH_CHECK_FAILED";
62
- //Jackpot errors
63
- InternalErrorCode["JACKPOT_TYPE_NOT_FOUND"] = "JACKPOT_TYPE_NOT_FOUND";
64
- InternalErrorCode["JACKPOT_TIER_NOT_FOUND"] = "JACKPOT_TIER_NOT_FOUND";
65
- InternalErrorCode["JACKPOT_CONFIGURATION_NOT_FOUND"] = "JACKPOT_CONFIGURATION_NOT_FOUND";
66
- InternalErrorCode["JACKPOT_CONFIGURATION_IS_ACTIVE"] = "JACKPOT_CONFIGURATION_IS_ACTIVE";
67
- InternalErrorCode["JACKPOT_POOL_CONTRIBUTION_ALREADY_PROCESSED"] = "JACKPOT_POOL_CONTRIBUTION_ALREADY_PROCESSED";
68
- InternalErrorCode["JACKPOT_TYPE_DOES_NOT_SUPPORT_TIERS"] = "JACKPOT_TYPE_DOES_NOT_SUPPORT_TIERS";
69
- // RNG and Replay errors
70
- InternalErrorCode["RNG_SEED_NOT_FOUND"] = "RNG_SEED_NOT_FOUND";
71
- InternalErrorCode["RNG_SEED_MISMATCH"] = "RNG_SEED_MISMATCH";
72
- InternalErrorCode["MASTER_HASH_INVALID"] = "MASTER_HASH_INVALID";
73
- InternalErrorCode["REPLAY_OUTCOME_MISMATCH"] = "REPLAY_OUTCOME_MISMATCH";
74
- // Concurrency
75
- InternalErrorCode["CONCURRENT_MODIFICATION"] = "CONCURRENT_MODIFICATION";
76
- InternalErrorCode["ACCOUNT_LOCKED"] = "ACCOUNT_LOCKED";
77
- InternalErrorCode["DAILY_LIMIT_EXCEEDED"] = "DAILY_LIMIT_EXCEEDED";
78
- InternalErrorCode["INVALID_AMOUNT"] = "INVALID_AMOUNT";
79
25
  InternalErrorCode["SERVICE_UNAVAILABLE"] = "SERVICE_UNAVAILABLE";
26
+ // Health check
27
+ InternalErrorCode["HEALTH_CHECK_FAILED"] = "HEALTH_CHECK_FAILED";
80
28
  })(InternalErrorCode || (exports.InternalErrorCode = InternalErrorCode = {}));
@@ -10,11 +10,10 @@ export declare class Logger implements NestLoggerService {
10
10
  private selectFormat;
11
11
  private getJsonFormat;
12
12
  private getPrettyFormat;
13
- private safeStringify;
14
13
  private getTransports;
15
- log(message: any, { level, ...rest }?: {
14
+ log(message: string, { level, ...rest }?: {
16
15
  level?: string;
17
- } & Record<string, any>): void;
16
+ } & Record<string, unknown>): void;
18
17
  error(message: any, ...optionalParams: any[]): void;
19
18
  warn(message: any, ...optionalParams: any[]): void;
20
19
  debug(message: any, ...optionalParams: any[]): void;
@@ -1 +1 @@
1
- {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../../src/common/logger/logger.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,IAAI,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAGpE,KAAK,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC;AAEnC,qBAAa,MAAO,YAAW,iBAAiB;IAC9C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,SAAS;IAMlD,OAAO,CAAC,eAAe;IAavB,OAAO,CAAC,mBAAmB;IAU3B,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,YAAY;IAWpB,OAAO,CAAC,aAAa;IAYrB,OAAO,CAAC,eAAe;IA+BvB,OAAO,CAAC,aAAa;IAarB,OAAO,CAAC,aAAa;IAUrB,GAAG,CAAC,OAAO,EAAE,GAAG,EAAE,EAAE,KAAc,EAAE,GAAG,IAAI,EAAE,GAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM;IAoB5F,KAAK,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,cAAc,EAAE,GAAG,EAAE;IAsB5C,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,cAAc,EAAE,GAAG,EAAE;IAI3C,KAAK,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,cAAc,EAAE,GAAG,EAAE;IAI5C,OAAO,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,cAAc,EAAE,GAAG,EAAE;CAG/C"}
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../../src/common/logger/logger.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,IAAI,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAGpE,KAAK,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC;AAEnC,qBAAa,MAAO,YAAW,iBAAiB;IAC9C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,SAAS;IAMlD,OAAO,CAAC,eAAe;IAavB,OAAO,CAAC,mBAAmB;IAU3B,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,YAAY;IAWpB,OAAO,CAAC,aAAa;IAYrB,OAAO,CAAC,eAAe;IA+BvB,OAAO,CAAC,aAAa;IAUrB,GAAG,CACD,OAAO,EAAE,MAAM,EACf,EAAE,KAAc,EAAE,GAAG,IAAI,EAAE,GAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM;IAqBhF,KAAK,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,cAAc,EAAE,GAAG,EAAE;IAsB5C,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,cAAc,EAAE,GAAG,EAAE;IAI3C,KAAK,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,cAAc,EAAE,GAAG,EAAE;IAI5C,OAAO,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,cAAc,EAAE,GAAG,EAAE;CAG/C"}
@@ -69,25 +69,12 @@ class Logger {
69
69
  return output;
70
70
  }));
71
71
  }
72
- safeStringify(obj) {
73
- try {
74
- return JSON.stringify(obj, (key, value) => {
75
- if (typeof value === 'bigint') {
76
- return value.toString();
77
- }
78
- return value;
79
- });
80
- }
81
- catch (_error) {
82
- return '[Object cannot be serialized]';
83
- }
84
- }
85
72
  getTransports() {
86
- const logTransports = [new winston_1.transports.Console()];
73
+ const consoleTransport = new winston_1.transports.Console();
87
74
  if (process.env.LOG_TO_FILE === 'true') {
88
- logTransports.push(new winston_1.transports.File({ filename: 'logs/app.log' }));
75
+ return [consoleTransport, new winston_1.transports.File({ filename: 'logs/app.log' })];
89
76
  }
90
- return logTransports;
77
+ return [consoleTransport];
91
78
  }
92
79
  log(message, { level = 'info', ...rest } = {}) {
93
80
  switch (level) {
@@ -1 +1 @@
1
- {"version":3,"file":"logging.middleware.d.ts","sourceRoot":"","sources":["../../../src/common/logger/logging.middleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AA4B1D,qBACa,iBAAkB,YAAW,cAAc;IACtD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;;IAMhC,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY;CAkBpD"}
1
+ {"version":3,"file":"logging.middleware.d.ts","sourceRoot":"","sources":["../../../src/common/logger/logging.middleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAwC1D,qBACa,iBAAkB,YAAW,cAAc;IACtD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;;IAMhC,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY;CAkBpD"}
@@ -13,11 +13,23 @@ Object.defineProperty(exports, "__esModule", { value: true });
13
13
  exports.LoggingMiddleware = void 0;
14
14
  const common_1 = require("@nestjs/common");
15
15
  const logger_1 = require("./logger");
16
- const BLOCKED_ENDPOINTS = ['/api/races/active'];
16
+ /** Endpoints to suppress from logging on success. Configurable via LOG_BLOCKED_ENDPOINTS env var (comma-separated). */
17
+ const BLOCKED_ENDPOINTS = process.env.LOG_BLOCKED_ENDPOINTS
18
+ ? process.env.LOG_BLOCKED_ENDPOINTS.split(',').map(e => e.trim())
19
+ : [];
17
20
  const SENSITIVE_FIELDS = new Set([
18
- 'password', 'token', 'secret', 'authorization',
19
- 'apikey', 'api_key', 'accesstoken', 'refreshtoken',
20
- 'creditcard', 'ssn', 'private_key', 'privatekey',
21
+ 'password',
22
+ 'token',
23
+ 'secret',
24
+ 'authorization',
25
+ 'apikey',
26
+ 'api_key',
27
+ 'accesstoken',
28
+ 'refreshtoken',
29
+ 'creditcard',
30
+ 'ssn',
31
+ 'private_key',
32
+ 'privatekey',
21
33
  ]);
22
34
  function sanitize(obj) {
23
35
  if (obj === null || obj === undefined || typeof obj !== 'object')
@@ -20,6 +20,11 @@ export declare class PrometheusService implements MetricsPort {
20
20
  getCounter(name: string): Counter;
21
21
  getGauge(name: string): Gauge;
22
22
  getHistogram(name: string): Histogram;
23
+ /**
24
+ * Returns Prometheus text format metrics from the default prom-client registry.
25
+ * The @willsoto/nestjs-prometheus module also exposes a /metrics HTTP endpoint
26
+ * automatically — this method is for programmatic access via the MetricsPort.
27
+ */
23
28
  getMetrics(): Promise<string>;
24
29
  }
25
30
  //# sourceMappingURL=prometheus.service.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"prometheus.service.d.ts","sourceRoot":"","sources":["../../../src/common/metrics/prometheus.service.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,OAAO,IAAI,WAAW,EACtB,KAAK,IAAI,SAAS,EAClB,SAAS,IAAI,aAAa,EAC3B,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAExE,qBACa,iBAAkB,YAAW,WAAW;IAKjD,OAAO,CAAC,QAAQ,CAAC,mBAAmB;IAEpC,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAElC,OAAO,CAAC,QAAQ,CAAC,mBAAmB;IAEpC,OAAO,CAAC,QAAQ,CAAC,qBAAqB;IAEtC,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAElC,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IAEnC,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IAEnC,OAAO,CAAC,QAAQ,CAAC,4BAA4B;IAE7C,OAAO,CAAC,QAAQ,CAAC,4BAA4B;IAE7C,OAAO,CAAC,QAAQ,CAAC,uBAAuB;IAExC,OAAO,CAAC,QAAQ,CAAC,8BAA8B;IAE/C,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IA1BnC,OAAO,CAAC,eAAe,CAAmE;gBAIvE,mBAAmB,EAAE,WAAW,EAEhC,iBAAiB,EAAE,WAAW,EAE9B,mBAAmB,EAAE,WAAW,EAEhC,qBAAqB,EAAE,aAAa,EAEpC,iBAAiB,EAAE,SAAS,EAE5B,kBAAkB,EAAE,SAAS,EAE7B,kBAAkB,EAAE,SAAS,EAE7B,4BAA4B,EAAE,WAAW,EAEzC,4BAA4B,EAAE,WAAW,EAEzC,uBAAuB,EAAE,aAAa,EAEtC,8BAA8B,EAAE,WAAW,EAE3C,gBAAgB,EAAE,aAAa;IAKlD,6BAA6B,IAAI,OAAO,CAAC,IAAI,CAAC;IAI9C,OAAO,CAAC,kBAAkB;IAkB1B,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAQjC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK;IAQ7B,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS;IAQ/B,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;CAGpC"}
1
+ {"version":3,"file":"prometheus.service.d.ts","sourceRoot":"","sources":["../../../src/common/metrics/prometheus.service.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,OAAO,IAAI,WAAW,EACtB,KAAK,IAAI,SAAS,EAClB,SAAS,IAAI,aAAa,EAC3B,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAExE,qBACa,iBAAkB,YAAW,WAAW;IAKjD,OAAO,CAAC,QAAQ,CAAC,mBAAmB;IAEpC,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAElC,OAAO,CAAC,QAAQ,CAAC,mBAAmB;IAEpC,OAAO,CAAC,QAAQ,CAAC,qBAAqB;IAEtC,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAElC,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IAEnC,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IAEnC,OAAO,CAAC,QAAQ,CAAC,4BAA4B;IAE7C,OAAO,CAAC,QAAQ,CAAC,4BAA4B;IAE7C,OAAO,CAAC,QAAQ,CAAC,uBAAuB;IAExC,OAAO,CAAC,QAAQ,CAAC,8BAA8B;IAE/C,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IA1BnC,OAAO,CAAC,eAAe,CAAmE;gBAIvE,mBAAmB,EAAE,WAAW,EAEhC,iBAAiB,EAAE,WAAW,EAE9B,mBAAmB,EAAE,WAAW,EAEhC,qBAAqB,EAAE,aAAa,EAEpC,iBAAiB,EAAE,SAAS,EAE5B,kBAAkB,EAAE,SAAS,EAE7B,kBAAkB,EAAE,SAAS,EAE7B,4BAA4B,EAAE,WAAW,EAEzC,4BAA4B,EAAE,WAAW,EAEzC,uBAAuB,EAAE,aAAa,EAEtC,8BAA8B,EAAE,WAAW,EAE3C,gBAAgB,EAAE,aAAa;IAK5C,6BAA6B,IAAI,OAAO,CAAC,IAAI,CAAC;IAKpD,OAAO,CAAC,kBAAkB;IAkB1B,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAQjC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK;IAQ7B,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS;IAQrC;;;;OAIG;IACG,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;CAIpC"}
@@ -1,10 +1,43 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
2
18
  var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
19
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
20
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
21
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
22
  return c > 3 && r && Object.defineProperty(target, key, r), r;
7
23
  };
24
+ var __importStar = (this && this.__importStar) || (function () {
25
+ var ownKeys = function(o) {
26
+ ownKeys = Object.getOwnPropertyNames || function (o) {
27
+ var ar = [];
28
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
+ return ar;
30
+ };
31
+ return ownKeys(o);
32
+ };
33
+ return function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
40
+ })();
8
41
  var __metadata = (this && this.__metadata) || function (k, v) {
9
42
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
43
  };
@@ -33,8 +66,9 @@ let PrometheusService = class PrometheusService {
33
66
  this.metricsRegistry = new Map();
34
67
  this.initializeRegistry();
35
68
  }
36
- initializeMetricsFromDatabase() {
37
- throw new Error('Method not implemented.');
69
+ async initializeMetricsFromDatabase() {
70
+ // No-op: Game engine metrics are initialized from Prometheus registry, not database.
71
+ // Override in subclass if database-backed metric initialization is needed.
38
72
  }
39
73
  initializeRegistry() {
40
74
  this.metricsRegistry.set('game_engine_commands_total', this.engineCommandsTotal);
@@ -71,8 +105,14 @@ let PrometheusService = class PrometheusService {
71
105
  }
72
106
  return metric;
73
107
  }
108
+ /**
109
+ * Returns Prometheus text format metrics from the default prom-client registry.
110
+ * The @willsoto/nestjs-prometheus module also exposes a /metrics HTTP endpoint
111
+ * automatically — this method is for programmatic access via the MetricsPort.
112
+ */
74
113
  async getMetrics() {
75
- return '';
114
+ const { register } = await Promise.resolve().then(() => __importStar(require('prom-client')));
115
+ return register.metrics();
76
116
  }
77
117
  };
78
118
  exports.PrometheusService = PrometheusService;
@@ -1 +1 @@
1
- {"version":3,"file":"retry-policy.d.ts","sourceRoot":"","sources":["../../../src/common/retry/retry-policy.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAClD,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgC;IACvD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAW;IAC5C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAA0C;IACnE,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAS;gBAE5B,OAAO,EAAE,YAAY;IAUpB,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IA4CzD,OAAO,CAAC,WAAW;IASnB,OAAO,CAAC,cAAc;YAMR,KAAK;CAGpB"}
1
+ {"version":3,"file":"retry-policy.d.ts","sourceRoot":"","sources":["../../../src/common/retry/retry-policy.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAClD,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgC;IACvD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAW;IAC5C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAA0C;IACnE,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAS;gBAE5B,OAAO,EAAE,YAAY;IAUpB,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAgDzD,OAAO,CAAC,WAAW;IAUnB,OAAO,CAAC,cAAc;YAMR,KAAK;CAGpB"}
@@ -24,7 +24,7 @@ class RetryPolicy {
24
24
  return result;
25
25
  }
26
26
  catch (error) {
27
- const err = error;
27
+ const err = error instanceof Error ? error : new Error(String(error));
28
28
  lastError = err;
29
29
  if (!this.isRetryable(err)) {
30
30
  throw err;
@@ -39,7 +39,9 @@ class RetryPolicy {
39
39
  try {
40
40
  this.onRetry(attempt, err);
41
41
  }
42
- catch { }
42
+ catch (callbackError) {
43
+ this.logger.debug(`onRetry callback threw: ${callbackError instanceof Error ? callbackError.message : String(callbackError)}`);
44
+ }
43
45
  }
44
46
  await this.sleep(delay);
45
47
  }
@@ -49,8 +51,11 @@ class RetryPolicy {
49
51
  isRetryable(error) {
50
52
  if (!this.retryableErrors || this.retryableErrors.length === 0)
51
53
  return true;
52
- const causeCode = error?.cause?.code ?? '';
53
- const text = `${error?.code ?? ''} ${error?.name ?? ''} ${error.message} ${causeCode}`;
54
+ const errorRecord = error;
55
+ const cause = errorRecord.cause;
56
+ const causeCode = typeof cause?.code === 'string' ? cause.code : '';
57
+ const errorCode = typeof errorRecord.code === 'string' ? errorRecord.code : '';
58
+ const text = `${errorCode} ${error.name} ${error.message} ${causeCode}`;
54
59
  return this.retryableErrors.some(pattern => text.includes(pattern));
55
60
  }
56
61
  calculateDelay(attempt) {
@@ -1 +1 @@
1
- {"version":3,"file":"secrets-provider.aws.d.ts","sourceRoot":"","sources":["../../../src/common/secrets-provider/secrets-provider.aws.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAG/C,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD,qBACa,kBAAmB,YAAW,eAAe;IAKrB,OAAO,CAAC,QAAQ,CAAC,aAAa;IAJjE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuC;IAC9D,OAAO,CAAC,YAAY,CAAkC;IACtD,OAAO,CAAC,cAAc,CAAiB;gBAEa,aAAa,EAAE,aAAa;IAM1E,QAAQ;YAIA,WAAW;IAiCnB,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAO/C"}
1
+ {"version":3,"file":"secrets-provider.aws.d.ts","sourceRoot":"","sources":["../../../src/common/secrets-provider/secrets-provider.aws.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAG/C,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD,qBACa,kBAAmB,YAAW,eAAe;IAKrB,OAAO,CAAC,QAAQ,CAAC,aAAa;IAJjE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuC;IAC9D,OAAO,CAAC,YAAY,CAAkC;IACtD,OAAO,CAAC,cAAc,CAAiB;gBAEa,aAAa,EAAE,aAAa;IAM1E,QAAQ;YAIA,WAAW;IAkCnB,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAO/C"}
@@ -53,7 +53,8 @@ let AwsSecretsProvider = AwsSecretsProvider_1 = class AwsSecretsProvider {
53
53
  this.logger.log(`Successfully loaded secrets from AWS Secrets Manager.`);
54
54
  }
55
55
  catch (error) {
56
- this.logger.error(`Failed to retrieve secrets from AWS: ${error.message}`);
56
+ const errorMessage = error instanceof Error ? error.message : String(error);
57
+ this.logger.error(`Failed to retrieve secrets from AWS: ${errorMessage}`);
57
58
  throw error;
58
59
  }
59
60
  }
@@ -5,22 +5,24 @@ import { setupDocumentation } from '../common/api-docs/setup-documentation';
5
5
  import { SHUTDOWN_OUT_PORT, } from '../health/application/ports/out/shutdown.out-port';
6
6
  import { GameEngineGrpcInAdapter } from '../grpc/game-engine.grpc.in-adapter';
7
7
  import { createConnectRouter } from '../grpc/connect-router.middleware';
8
- import { BadRequestException, RequestMethod, ValidationPipe } from '@nestjs/common';
8
+ import { BadRequestException, RequestMethod, ValidationPipe, } from '@nestjs/common';
9
9
  import { ConfigService } from '@nestjs/config';
10
10
  import { NestFactory } from '@nestjs/core';
11
11
  import * as http2 from 'http2';
12
+ /** Type guard for NestJS dynamic modules with a static `register` method. */
13
+ function hasRegisterMethod(module) {
14
+ return 'register' in module && typeof module.register === 'function';
15
+ }
12
16
  /**
13
17
  * Creates and bootstraps a game engine NestJS application with
14
18
  * standard configuration: CORS, validation pipes, exception filters,
15
19
  * Swagger docs, Connect RPC gRPC server, and graceful shutdown.
16
20
  */
17
21
  export async function createGameEngineApp(options) {
18
- const { serviceName, appModule, bootstrapOptions, corsOrigins = false } = options;
22
+ const { serviceName, appModule, bootstrapOptions, corsOrigins = false, additionalRoutes, } = options;
19
23
  const logger = new Logger(serviceName);
20
- const moduleArg = bootstrapOptions
21
- ? appModule.register
22
- ? appModule.register(bootstrapOptions)
23
- : appModule
24
+ const moduleArg = bootstrapOptions && hasRegisterMethod(appModule)
25
+ ? appModule.register(bootstrapOptions)
24
26
  : appModule;
25
27
  const app = await NestFactory.create(moduleArg, {
26
28
  logger: logger,
@@ -30,42 +32,33 @@ export async function createGameEngineApp(options) {
30
32
  }
31
33
  const configService = app.get(ConfigService);
32
34
  const shutdownService = app.get(SHUTDOWN_OUT_PORT);
33
- let isShuttingDown = false;
35
+ // Fatal error handler uses ShutdownOutPort's guard to prevent duplicate shutdowns.
36
+ // No separate local flag — single source of truth avoids desync.
34
37
  const handleFatalError = async (errorType, error) => {
35
- logger.error(`${errorType}:`, {
36
- error: error.message,
37
- stack: error.stack,
38
- });
39
- if (isShuttingDown) {
38
+ const errorMessage = error instanceof Error ? error.message : String(error);
39
+ const errorStack = error instanceof Error ? error.stack : undefined;
40
+ logger.error(`${errorType}:`, { error: errorMessage, stack: errorStack });
41
+ if (shutdownService.isShuttingDown()) {
40
42
  logger.warn('Shutdown already in progress, ignoring additional error');
41
43
  return;
42
44
  }
43
- isShuttingDown = true;
44
45
  try {
45
46
  logger.warn(`Initiating graceful shutdown due to ${errorType}...`);
46
47
  await shutdownService.startGracefulShutdown();
47
48
  logger.log('Graceful shutdown completed, exiting process');
48
49
  }
49
50
  catch (shutdownError) {
50
- logger.error('Error during graceful shutdown:', shutdownError);
51
+ const shutdownMsg = shutdownError instanceof Error ? shutdownError.message : String(shutdownError);
52
+ logger.error(`Error during graceful shutdown: ${shutdownMsg}`);
51
53
  }
52
54
  finally {
53
55
  process.exit(1);
54
56
  }
55
57
  };
56
58
  process.on('uncaughtException', (error) => {
57
- logger.error('Uncaught Exception:', {
58
- error: error.message,
59
- stack: error.stack,
60
- });
61
59
  void handleFatalError('uncaughtException', error);
62
60
  });
63
- process.on('unhandledRejection', (reason, promise) => {
64
- logger.error('Unhandled Rejection:', {
65
- reason: reason.message,
66
- stack: reason.stack,
67
- promise,
68
- });
61
+ process.on('unhandledRejection', (reason) => {
69
62
  void handleFatalError('unhandledRejection', reason);
70
63
  });
71
64
  app.setGlobalPrefix('api', {
@@ -91,11 +84,11 @@ export async function createGameEngineApp(options) {
91
84
  },
92
85
  }));
93
86
  app.useGlobalFilters(app.get(ExceptionsFilter));
94
- const PORT = configService.get('PORT') || 3000;
87
+ const PORT = configService.get('PORT') ?? 3000;
95
88
  await setupDocumentation(app, PORT, serviceName);
96
89
  // Setup Connect RPC server
97
90
  const gameEngineAdapter = app.get(GameEngineGrpcInAdapter);
98
- const connectRouter = createConnectRouter(gameEngineAdapter);
91
+ const connectRouter = createConnectRouter(gameEngineAdapter, { additionalRoutes });
99
92
  // Mount Connect router on /connect path
100
93
  app.use('/connect', connectRouter);
101
94
  app.enableShutdownHooks(['SIGTERM', 'SIGINT']);
@@ -108,14 +101,21 @@ export async function createGameEngineApp(options) {
108
101
  h2cServer.listen(GRPC_PORT, '0.0.0.0', () => {
109
102
  logger.log(`Connect RPC (h2c) is available on: http://localhost:${GRPC_PORT}`);
110
103
  });
111
- // Close h2c server during graceful shutdown
112
- const closeH2c = () => {
113
- h2cServer.close(() => {
114
- logger.log('h2c gRPC server closed');
104
+ // Register h2c server closure with graceful shutdown service
105
+ shutdownService.registerCleanupCallback('h2c-grpc-server', () => {
106
+ return new Promise((resolve, reject) => {
107
+ h2cServer.close(err => {
108
+ if (err) {
109
+ logger.error('Error closing h2c gRPC server:', err);
110
+ reject(err);
111
+ }
112
+ else {
113
+ logger.log('h2c gRPC server closed');
114
+ resolve();
115
+ }
116
+ });
115
117
  });
116
- };
117
- process.on('SIGTERM', closeH2c);
118
- process.on('SIGINT', closeH2c);
118
+ });
119
119
  await app.listen(PORT, '0.0.0.0');
120
120
  logger.log(`Application is running on: http://localhost:${PORT}`);
121
121
  return app;