@dyanet/nestjs-config-aws 1.0.1

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 (231) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1183 -0
  3. package/dist/cjs/config.module.js +178 -0
  4. package/dist/cjs/config.module.js.map +1 -0
  5. package/dist/cjs/index.js +47 -0
  6. package/dist/cjs/index.js.map +1 -0
  7. package/dist/cjs/integration/index.js +23 -0
  8. package/dist/cjs/integration/index.js.map +1 -0
  9. package/dist/cjs/integration/interfaces/configuration-factory.interface.js +3 -0
  10. package/dist/cjs/integration/interfaces/configuration-factory.interface.js.map +1 -0
  11. package/dist/cjs/integration/interfaces/configuration-source.interface.js +3 -0
  12. package/dist/cjs/integration/interfaces/configuration-source.interface.js.map +1 -0
  13. package/dist/cjs/integration/interfaces/index.js +26 -0
  14. package/dist/cjs/integration/interfaces/index.js.map +1 -0
  15. package/dist/cjs/integration/interfaces/integration-options.interface.js +3 -0
  16. package/dist/cjs/integration/interfaces/integration-options.interface.js.map +1 -0
  17. package/dist/cjs/integration/interfaces/integration-state.interface.js +3 -0
  18. package/dist/cjs/integration/interfaces/integration-state.interface.js.map +1 -0
  19. package/dist/cjs/integration/interfaces/nestjs-config-compatibility.interface.js +73 -0
  20. package/dist/cjs/integration/interfaces/nestjs-config-compatibility.interface.js.map +1 -0
  21. package/dist/cjs/integration/interfaces/nestjs-config-integration.interface.js +3 -0
  22. package/dist/cjs/integration/interfaces/nestjs-config-integration.interface.js.map +1 -0
  23. package/dist/cjs/integration/interfaces/typed-configuration.interface.js +4 -0
  24. package/dist/cjs/integration/interfaces/typed-configuration.interface.js.map +1 -0
  25. package/dist/cjs/integration/interfaces/utility-types.interface.js +52 -0
  26. package/dist/cjs/integration/interfaces/utility-types.interface.js.map +1 -0
  27. package/dist/cjs/integration/nestjs-config-integration.module.js +124 -0
  28. package/dist/cjs/integration/nestjs-config-integration.module.js.map +1 -0
  29. package/dist/cjs/integration/providers/aws-configuration-loader.service.js +591 -0
  30. package/dist/cjs/integration/providers/aws-configuration-loader.service.js.map +1 -0
  31. package/dist/cjs/integration/providers/configuration-factory.provider.js +383 -0
  32. package/dist/cjs/integration/providers/configuration-factory.provider.js.map +1 -0
  33. package/dist/cjs/integration/providers/index.js +20 -0
  34. package/dist/cjs/integration/providers/index.js.map +1 -0
  35. package/dist/cjs/integration/services/async-config-helper.service.js +356 -0
  36. package/dist/cjs/integration/services/async-config-helper.service.js.map +1 -0
  37. package/dist/cjs/integration/services/error-handler.service.js +265 -0
  38. package/dist/cjs/integration/services/error-handler.service.js.map +1 -0
  39. package/dist/cjs/integration/services/factory-registration.service.js +512 -0
  40. package/dist/cjs/integration/services/factory-registration.service.js.map +1 -0
  41. package/dist/cjs/integration/services/index.js +26 -0
  42. package/dist/cjs/integration/services/index.js.map +1 -0
  43. package/dist/cjs/integration/services/integration-state.service.js +83 -0
  44. package/dist/cjs/integration/services/integration-state.service.js.map +1 -0
  45. package/dist/cjs/integration/services/namespace-handler.service.js +467 -0
  46. package/dist/cjs/integration/services/namespace-handler.service.js.map +1 -0
  47. package/dist/cjs/integration/services/nestjs-config-integration.service.js +316 -0
  48. package/dist/cjs/integration/services/nestjs-config-integration.service.js.map +1 -0
  49. package/dist/cjs/integration/services/precedence-handler.service.js +294 -0
  50. package/dist/cjs/integration/services/precedence-handler.service.js.map +1 -0
  51. package/dist/cjs/integration/services/validation-integration.service.js +591 -0
  52. package/dist/cjs/integration/services/validation-integration.service.js.map +1 -0
  53. package/dist/cjs/integration/utils/config-integration.util.js +283 -0
  54. package/dist/cjs/integration/utils/config-integration.util.js.map +1 -0
  55. package/dist/cjs/integration/utils/index.js +19 -0
  56. package/dist/cjs/integration/utils/index.js.map +1 -0
  57. package/dist/cjs/interfaces/config-loader.interface.js +3 -0
  58. package/dist/cjs/interfaces/config-loader.interface.js.map +1 -0
  59. package/dist/cjs/interfaces/config-service.interface.js +11 -0
  60. package/dist/cjs/interfaces/config-service.interface.js.map +1 -0
  61. package/dist/cjs/interfaces/default-schema.interface.js +63 -0
  62. package/dist/cjs/interfaces/default-schema.interface.js.map +1 -0
  63. package/dist/cjs/interfaces/errors.interface.js +77 -0
  64. package/dist/cjs/interfaces/errors.interface.js.map +1 -0
  65. package/dist/cjs/interfaces/index.js +25 -0
  66. package/dist/cjs/interfaces/index.js.map +1 -0
  67. package/dist/cjs/interfaces/module-options.interface.js +3 -0
  68. package/dist/cjs/interfaces/module-options.interface.js.map +1 -0
  69. package/dist/cjs/loaders/environment.loader.js +59 -0
  70. package/dist/cjs/loaders/environment.loader.js.map +1 -0
  71. package/dist/cjs/loaders/secrets-manager.loader.js +122 -0
  72. package/dist/cjs/loaders/secrets-manager.loader.js.map +1 -0
  73. package/dist/cjs/loaders/ssm-parameter-store.loader.js +146 -0
  74. package/dist/cjs/loaders/ssm-parameter-store.loader.js.map +1 -0
  75. package/dist/cjs/services/config.service.js +297 -0
  76. package/dist/cjs/services/config.service.js.map +1 -0
  77. package/dist/cjs/utils/validation.util.js +114 -0
  78. package/dist/cjs/utils/validation.util.js.map +1 -0
  79. package/dist/esm/config.module.js +175 -0
  80. package/dist/esm/config.module.js.map +1 -0
  81. package/dist/esm/index.js +18 -0
  82. package/dist/esm/index.js.map +1 -0
  83. package/dist/esm/integration/index.js +7 -0
  84. package/dist/esm/integration/index.js.map +1 -0
  85. package/dist/esm/integration/interfaces/configuration-factory.interface.js +2 -0
  86. package/dist/esm/integration/interfaces/configuration-factory.interface.js.map +1 -0
  87. package/dist/esm/integration/interfaces/configuration-source.interface.js +2 -0
  88. package/dist/esm/integration/interfaces/configuration-source.interface.js.map +1 -0
  89. package/dist/esm/integration/interfaces/index.js +10 -0
  90. package/dist/esm/integration/interfaces/index.js.map +1 -0
  91. package/dist/esm/integration/interfaces/integration-options.interface.js +2 -0
  92. package/dist/esm/integration/interfaces/integration-options.interface.js.map +1 -0
  93. package/dist/esm/integration/interfaces/integration-state.interface.js +2 -0
  94. package/dist/esm/integration/interfaces/integration-state.interface.js.map +1 -0
  95. package/dist/esm/integration/interfaces/nestjs-config-compatibility.interface.js +64 -0
  96. package/dist/esm/integration/interfaces/nestjs-config-compatibility.interface.js.map +1 -0
  97. package/dist/esm/integration/interfaces/nestjs-config-integration.interface.js +2 -0
  98. package/dist/esm/integration/interfaces/nestjs-config-integration.interface.js.map +1 -0
  99. package/dist/esm/integration/interfaces/typed-configuration.interface.js +3 -0
  100. package/dist/esm/integration/interfaces/typed-configuration.interface.js.map +1 -0
  101. package/dist/esm/integration/interfaces/utility-types.interface.js +44 -0
  102. package/dist/esm/integration/interfaces/utility-types.interface.js.map +1 -0
  103. package/dist/esm/integration/nestjs-config-integration.module.js +121 -0
  104. package/dist/esm/integration/nestjs-config-integration.module.js.map +1 -0
  105. package/dist/esm/integration/providers/aws-configuration-loader.service.js +588 -0
  106. package/dist/esm/integration/providers/aws-configuration-loader.service.js.map +1 -0
  107. package/dist/esm/integration/providers/configuration-factory.provider.js +380 -0
  108. package/dist/esm/integration/providers/configuration-factory.provider.js.map +1 -0
  109. package/dist/esm/integration/providers/index.js +4 -0
  110. package/dist/esm/integration/providers/index.js.map +1 -0
  111. package/dist/esm/integration/services/async-config-helper.service.js +353 -0
  112. package/dist/esm/integration/services/async-config-helper.service.js.map +1 -0
  113. package/dist/esm/integration/services/error-handler.service.js +262 -0
  114. package/dist/esm/integration/services/error-handler.service.js.map +1 -0
  115. package/dist/esm/integration/services/factory-registration.service.js +509 -0
  116. package/dist/esm/integration/services/factory-registration.service.js.map +1 -0
  117. package/dist/esm/integration/services/index.js +10 -0
  118. package/dist/esm/integration/services/index.js.map +1 -0
  119. package/dist/esm/integration/services/integration-state.service.js +80 -0
  120. package/dist/esm/integration/services/integration-state.service.js.map +1 -0
  121. package/dist/esm/integration/services/namespace-handler.service.js +464 -0
  122. package/dist/esm/integration/services/namespace-handler.service.js.map +1 -0
  123. package/dist/esm/integration/services/nestjs-config-integration.service.js +313 -0
  124. package/dist/esm/integration/services/nestjs-config-integration.service.js.map +1 -0
  125. package/dist/esm/integration/services/precedence-handler.service.js +291 -0
  126. package/dist/esm/integration/services/precedence-handler.service.js.map +1 -0
  127. package/dist/esm/integration/services/validation-integration.service.js +585 -0
  128. package/dist/esm/integration/services/validation-integration.service.js.map +1 -0
  129. package/dist/esm/integration/utils/config-integration.util.js +240 -0
  130. package/dist/esm/integration/utils/config-integration.util.js.map +1 -0
  131. package/dist/esm/integration/utils/index.js +3 -0
  132. package/dist/esm/integration/utils/index.js.map +1 -0
  133. package/dist/esm/interfaces/config-loader.interface.js +2 -0
  134. package/dist/esm/interfaces/config-loader.interface.js.map +1 -0
  135. package/dist/esm/interfaces/config-service.interface.js +7 -0
  136. package/dist/esm/interfaces/config-service.interface.js.map +1 -0
  137. package/dist/esm/interfaces/default-schema.interface.js +59 -0
  138. package/dist/esm/interfaces/default-schema.interface.js.map +1 -0
  139. package/dist/esm/interfaces/errors.interface.js +69 -0
  140. package/dist/esm/interfaces/errors.interface.js.map +1 -0
  141. package/dist/esm/interfaces/index.js +9 -0
  142. package/dist/esm/interfaces/index.js.map +1 -0
  143. package/dist/esm/interfaces/module-options.interface.js +2 -0
  144. package/dist/esm/interfaces/module-options.interface.js.map +1 -0
  145. package/dist/esm/loaders/environment.loader.js +55 -0
  146. package/dist/esm/loaders/environment.loader.js.map +1 -0
  147. package/dist/esm/loaders/secrets-manager.loader.js +118 -0
  148. package/dist/esm/loaders/secrets-manager.loader.js.map +1 -0
  149. package/dist/esm/loaders/ssm-parameter-store.loader.js +142 -0
  150. package/dist/esm/loaders/ssm-parameter-store.loader.js.map +1 -0
  151. package/dist/esm/services/config.service.js +261 -0
  152. package/dist/esm/services/config.service.js.map +1 -0
  153. package/dist/esm/utils/validation.util.js +110 -0
  154. package/dist/esm/utils/validation.util.js.map +1 -0
  155. package/dist/types/config.module.d.ts +46 -0
  156. package/dist/types/config.module.d.ts.map +1 -0
  157. package/dist/types/index.d.ts +13 -0
  158. package/dist/types/index.d.ts.map +1 -0
  159. package/dist/types/integration/index.d.ts +6 -0
  160. package/dist/types/integration/index.d.ts.map +1 -0
  161. package/dist/types/integration/interfaces/configuration-factory.interface.d.ts +71 -0
  162. package/dist/types/integration/interfaces/configuration-factory.interface.d.ts.map +1 -0
  163. package/dist/types/integration/interfaces/configuration-source.interface.d.ts +24 -0
  164. package/dist/types/integration/interfaces/configuration-source.interface.d.ts.map +1 -0
  165. package/dist/types/integration/interfaces/index.d.ts +9 -0
  166. package/dist/types/integration/interfaces/index.d.ts.map +1 -0
  167. package/dist/types/integration/interfaces/integration-options.interface.d.ts +66 -0
  168. package/dist/types/integration/interfaces/integration-options.interface.d.ts.map +1 -0
  169. package/dist/types/integration/interfaces/integration-state.interface.d.ts +17 -0
  170. package/dist/types/integration/interfaces/integration-state.interface.d.ts.map +1 -0
  171. package/dist/types/integration/interfaces/nestjs-config-compatibility.interface.d.ts +332 -0
  172. package/dist/types/integration/interfaces/nestjs-config-compatibility.interface.d.ts.map +1 -0
  173. package/dist/types/integration/interfaces/nestjs-config-integration.interface.d.ts +259 -0
  174. package/dist/types/integration/interfaces/nestjs-config-integration.interface.d.ts.map +1 -0
  175. package/dist/types/integration/interfaces/typed-configuration.interface.d.ts +209 -0
  176. package/dist/types/integration/interfaces/typed-configuration.interface.d.ts.map +1 -0
  177. package/dist/types/integration/interfaces/utility-types.interface.d.ts +249 -0
  178. package/dist/types/integration/interfaces/utility-types.interface.d.ts.map +1 -0
  179. package/dist/types/integration/nestjs-config-integration.module.d.ts +36 -0
  180. package/dist/types/integration/nestjs-config-integration.module.d.ts.map +1 -0
  181. package/dist/types/integration/providers/aws-configuration-loader.service.d.ts +134 -0
  182. package/dist/types/integration/providers/aws-configuration-loader.service.d.ts.map +1 -0
  183. package/dist/types/integration/providers/configuration-factory.provider.d.ts +119 -0
  184. package/dist/types/integration/providers/configuration-factory.provider.d.ts.map +1 -0
  185. package/dist/types/integration/providers/index.d.ts +3 -0
  186. package/dist/types/integration/providers/index.d.ts.map +1 -0
  187. package/dist/types/integration/services/async-config-helper.service.d.ts +84 -0
  188. package/dist/types/integration/services/async-config-helper.service.d.ts.map +1 -0
  189. package/dist/types/integration/services/error-handler.service.d.ts +84 -0
  190. package/dist/types/integration/services/error-handler.service.d.ts.map +1 -0
  191. package/dist/types/integration/services/factory-registration.service.d.ts +158 -0
  192. package/dist/types/integration/services/factory-registration.service.d.ts.map +1 -0
  193. package/dist/types/integration/services/index.d.ts +9 -0
  194. package/dist/types/integration/services/index.d.ts.map +1 -0
  195. package/dist/types/integration/services/integration-state.service.d.ts +41 -0
  196. package/dist/types/integration/services/integration-state.service.d.ts.map +1 -0
  197. package/dist/types/integration/services/namespace-handler.service.d.ts +192 -0
  198. package/dist/types/integration/services/namespace-handler.service.d.ts.map +1 -0
  199. package/dist/types/integration/services/nestjs-config-integration.service.d.ts +87 -0
  200. package/dist/types/integration/services/nestjs-config-integration.service.d.ts.map +1 -0
  201. package/dist/types/integration/services/precedence-handler.service.d.ts +103 -0
  202. package/dist/types/integration/services/precedence-handler.service.d.ts.map +1 -0
  203. package/dist/types/integration/services/validation-integration.service.d.ts +222 -0
  204. package/dist/types/integration/services/validation-integration.service.d.ts.map +1 -0
  205. package/dist/types/integration/utils/config-integration.util.d.ts +81 -0
  206. package/dist/types/integration/utils/config-integration.util.d.ts.map +1 -0
  207. package/dist/types/integration/utils/index.d.ts +2 -0
  208. package/dist/types/integration/utils/index.d.ts.map +1 -0
  209. package/dist/types/interfaces/config-loader.interface.d.ts +22 -0
  210. package/dist/types/interfaces/config-loader.interface.d.ts.map +1 -0
  211. package/dist/types/interfaces/config-service.interface.d.ts +23 -0
  212. package/dist/types/interfaces/config-service.interface.d.ts.map +1 -0
  213. package/dist/types/interfaces/default-schema.interface.d.ts +195 -0
  214. package/dist/types/interfaces/default-schema.interface.d.ts.map +1 -0
  215. package/dist/types/interfaces/errors.interface.d.ts +38 -0
  216. package/dist/types/interfaces/errors.interface.d.ts.map +1 -0
  217. package/dist/types/interfaces/index.d.ts +6 -0
  218. package/dist/types/interfaces/index.d.ts.map +1 -0
  219. package/dist/types/interfaces/module-options.interface.d.ts +64 -0
  220. package/dist/types/interfaces/module-options.interface.d.ts.map +1 -0
  221. package/dist/types/loaders/environment.loader.d.ts +26 -0
  222. package/dist/types/loaders/environment.loader.d.ts.map +1 -0
  223. package/dist/types/loaders/secrets-manager.loader.d.ts +52 -0
  224. package/dist/types/loaders/secrets-manager.loader.d.ts.map +1 -0
  225. package/dist/types/loaders/ssm-parameter-store.loader.d.ts +68 -0
  226. package/dist/types/loaders/ssm-parameter-store.loader.d.ts.map +1 -0
  227. package/dist/types/services/config.service.d.ts +94 -0
  228. package/dist/types/services/config.service.d.ts.map +1 -0
  229. package/dist/types/utils/validation.util.d.ts +53 -0
  230. package/dist/types/utils/validation.util.d.ts.map +1 -0
  231. package/package.json +102 -0
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SecretsManagerLoader = void 0;
4
+ const client_secrets_manager_1 = require("@aws-sdk/client-secrets-manager");
5
+ const credential_providers_1 = require("@aws-sdk/credential-providers");
6
+ const errors_interface_1 = require("../interfaces/errors.interface");
7
+ /**
8
+ * Configuration loader that loads values from AWS Secrets Manager.
9
+ * Supports environment-aware secret path construction and JSON parsing with string fallback.
10
+ */
11
+ class SecretsManagerLoader {
12
+ constructor(config = {}) {
13
+ this.appEnv = process.env['APP_ENV'] || process.env['NODE_ENV'] || 'local';
14
+ // Set default configuration
15
+ this.config = {
16
+ secretName: config.secretName || '/nestjs-config-aws',
17
+ region: config.region || process.env['AWS_REGION'] || 'us-east-1',
18
+ environmentMapping: config.environmentMapping || {
19
+ development: 'dev',
20
+ test: 'test',
21
+ production: 'production'
22
+ }
23
+ };
24
+ // Initialize AWS Secrets Manager client
25
+ this.client = new client_secrets_manager_1.SecretsManagerClient({
26
+ credentials: (0, credential_providers_1.fromNodeProviderChain)(),
27
+ region: this.config.region,
28
+ });
29
+ }
30
+ /**
31
+ * Load configuration from AWS Secrets Manager.
32
+ * @returns Promise resolving to configuration key-value pairs from the secret
33
+ */
34
+ async load() {
35
+ // Skip loading in local environment
36
+ if (this.appEnv === 'local') {
37
+ return {};
38
+ }
39
+ const secretName = this.buildSecretName();
40
+ try {
41
+ const command = new client_secrets_manager_1.GetSecretValueCommand({ SecretId: secretName });
42
+ const response = await this.client.send(command);
43
+ if (!response.SecretString) {
44
+ return {};
45
+ }
46
+ // Try to parse as JSON, fallback to string value
47
+ try {
48
+ const parsed = JSON.parse(response.SecretString);
49
+ // Ensure we return an object for configuration merging
50
+ if (typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)) {
51
+ return parsed;
52
+ }
53
+ else {
54
+ // If it's not an object, wrap it in a configuration object
55
+ return { SECRET_VALUE: parsed };
56
+ }
57
+ }
58
+ catch {
59
+ // If JSON parsing fails, treat as a single string value
60
+ return { SECRET_VALUE: response.SecretString };
61
+ }
62
+ }
63
+ catch (error) {
64
+ // Handle specific AWS errors
65
+ if (error instanceof Error) {
66
+ if (error.name === 'ResourceNotFoundException') {
67
+ // Secret doesn't exist - this is not necessarily an error in all environments
68
+ return {};
69
+ }
70
+ if (error.name === 'AccessDeniedException') {
71
+ throw new errors_interface_1.ConfigurationError(`Access denied when retrieving secret '${secretName}'. Check AWS credentials and permissions.`, error);
72
+ }
73
+ if (error.name === 'InvalidRequestException') {
74
+ throw new errors_interface_1.ConfigurationError(`Invalid request when retrieving secret '${secretName}'. Check secret name format.`, error);
75
+ }
76
+ }
77
+ // For other errors, wrap in ConfigurationError
78
+ throw new errors_interface_1.ConfigurationError(`Failed to retrieve secret '${secretName}' from AWS Secrets Manager: ${error instanceof Error ? error.message : String(error)}`, error instanceof Error ? error : undefined);
79
+ }
80
+ }
81
+ /**
82
+ * Get the name of this loader for logging and debugging.
83
+ * @returns The loader name with secret path
84
+ */
85
+ getName() {
86
+ const secretName = this.buildSecretName();
87
+ return `SecretsManagerLoader(${secretName})`;
88
+ }
89
+ /**
90
+ * Check if this loader is available in the current environment.
91
+ * @returns Promise resolving to true if not in local environment and AWS credentials are available
92
+ */
93
+ async isAvailable() {
94
+ // Skip in local environment
95
+ if (this.appEnv === 'local') {
96
+ return false;
97
+ }
98
+ try {
99
+ // Test AWS credentials by attempting to get caller identity
100
+ // This is a lightweight way to verify AWS access without making actual Secrets Manager calls
101
+ await this.client.config.credentials();
102
+ return true;
103
+ }
104
+ catch {
105
+ return false;
106
+ }
107
+ }
108
+ /**
109
+ * Build the environment-aware secret name/path.
110
+ * @returns The full secret name with environment prefix
111
+ */
112
+ buildSecretName() {
113
+ const envPrefix = this.config.environmentMapping[this.appEnv];
114
+ if (!envPrefix) {
115
+ throw new errors_interface_1.ConfigurationError(`No environment mapping found for APP_ENV '${this.appEnv}'. ` +
116
+ `Available environments: ${Object.keys(this.config.environmentMapping).join(', ')}`);
117
+ }
118
+ return `/${envPrefix}${this.config.secretName}`;
119
+ }
120
+ }
121
+ exports.SecretsManagerLoader = SecretsManagerLoader;
122
+ //# sourceMappingURL=secrets-manager.loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secrets-manager.loader.js","sourceRoot":"","sources":["../../../src/loaders/secrets-manager.loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,146 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SSMParameterStoreLoader = void 0;
4
+ const client_ssm_1 = require("@aws-sdk/client-ssm");
5
+ const credential_providers_1 = require("@aws-sdk/credential-providers");
6
+ const errors_interface_1 = require("../interfaces/errors.interface");
7
+ /**
8
+ * Configuration loader that loads values from AWS Systems Manager Parameter Store.
9
+ * Supports environment-aware parameter path construction, recursive parameter fetching with pagination,
10
+ * and parameter name transformation (remove prefix, convert to uppercase).
11
+ */
12
+ class SSMParameterStoreLoader {
13
+ constructor(config = {}) {
14
+ this.appEnv = process.env['APP_ENV'] || process.env['NODE_ENV'] || 'local';
15
+ // Set default configuration
16
+ this.config = {
17
+ parameterPath: config.parameterPath || '/nestjs-config-aws',
18
+ region: config.region || process.env['AWS_REGION'] || 'us-east-1',
19
+ environmentMapping: config.environmentMapping || {
20
+ development: 'dev',
21
+ test: 'test',
22
+ production: 'production'
23
+ },
24
+ withDecryption: config.withDecryption ?? true
25
+ };
26
+ // Initialize AWS SSM client
27
+ this.client = new client_ssm_1.SSMClient({
28
+ credentials: (0, credential_providers_1.fromNodeProviderChain)(),
29
+ region: this.config.region,
30
+ });
31
+ }
32
+ /**
33
+ * Load configuration from AWS Systems Manager Parameter Store.
34
+ * Implements recursive parameter fetching with NextToken handling for pagination.
35
+ * @returns Promise resolving to configuration key-value pairs from parameters
36
+ */
37
+ async load() {
38
+ // Skip loading in local environment or if AWS_REGION is not available
39
+ if (this.appEnv === 'local' || !process.env['AWS_REGION']) {
40
+ return {};
41
+ }
42
+ const parameterPath = this.buildParameterPath();
43
+ const result = {};
44
+ let nextToken;
45
+ try {
46
+ do {
47
+ const command = new client_ssm_1.GetParametersByPathCommand({
48
+ Path: parameterPath,
49
+ Recursive: true,
50
+ WithDecryption: this.config.withDecryption,
51
+ NextToken: nextToken,
52
+ });
53
+ const response = await this.client.send(command);
54
+ if (!response.Parameters) {
55
+ // No parameters found - this is not necessarily an error
56
+ break;
57
+ }
58
+ // Process each parameter
59
+ for (const param of response.Parameters) {
60
+ const key = this.transformParameterName(param.Name, parameterPath);
61
+ if (key && param.Value !== undefined) {
62
+ result[key] = param.Value;
63
+ }
64
+ }
65
+ nextToken = response.NextToken;
66
+ } while (nextToken);
67
+ return result;
68
+ }
69
+ catch (error) {
70
+ // Handle specific AWS errors
71
+ if (error instanceof Error) {
72
+ if (error.name === 'AccessDeniedException') {
73
+ throw new errors_interface_1.ConfigurationError(`Access denied when retrieving parameters from path '${parameterPath}'. Check AWS credentials and permissions.`, error);
74
+ }
75
+ if (error.name === 'InvalidFilterKey' || error.name === 'InvalidFilterValue') {
76
+ throw new errors_interface_1.ConfigurationError(`Invalid parameter path '${parameterPath}'. Check path format.`, error);
77
+ }
78
+ if (error.name === 'ParameterNotFound') {
79
+ // No parameters found at path - this is not necessarily an error
80
+ return {};
81
+ }
82
+ }
83
+ // For other errors, wrap in ConfigurationError
84
+ throw new errors_interface_1.ConfigurationError(`Failed to retrieve parameters from path '${parameterPath}' in AWS SSM Parameter Store: ${error instanceof Error ? error.message : String(error)}`, error instanceof Error ? error : undefined);
85
+ }
86
+ }
87
+ /**
88
+ * Get the name of this loader for logging and debugging.
89
+ * @returns The loader name with parameter path
90
+ */
91
+ getName() {
92
+ const parameterPath = this.buildParameterPath();
93
+ return `SSMParameterStoreLoader(${parameterPath})`;
94
+ }
95
+ /**
96
+ * Check if this loader is available in the current environment.
97
+ * @returns Promise resolving to true if not in local environment, AWS_REGION is set, and AWS credentials are available
98
+ */
99
+ async isAvailable() {
100
+ // Skip in local environment or if AWS_REGION is not available
101
+ if (this.appEnv === 'local' || !process.env['AWS_REGION']) {
102
+ return false;
103
+ }
104
+ try {
105
+ // Test AWS credentials by attempting to get caller identity
106
+ // This is a lightweight way to verify AWS access without making actual SSM calls
107
+ await this.client.config.credentials();
108
+ return true;
109
+ }
110
+ catch {
111
+ return false;
112
+ }
113
+ }
114
+ /**
115
+ * Build the environment-aware parameter path.
116
+ * @returns The full parameter path with environment prefix
117
+ */
118
+ buildParameterPath() {
119
+ const envPrefix = this.config.environmentMapping[this.appEnv];
120
+ if (!envPrefix) {
121
+ throw new errors_interface_1.ConfigurationError(`No environment mapping found for APP_ENV '${this.appEnv}'. ` +
122
+ `Available environments: ${Object.keys(this.config.environmentMapping).join(', ')}`);
123
+ }
124
+ return `/${envPrefix}${this.config.parameterPath}`;
125
+ }
126
+ /**
127
+ * Transform parameter name by removing the prefix and converting to uppercase.
128
+ * Example: '/dev/nestjs-config-aws/database/host' -> 'DATABASEHOST'
129
+ * This matches the original prospectory-backend implementation
130
+ * @param parameterName The full parameter name from AWS
131
+ * @param pathPrefix The path prefix to remove
132
+ * @returns The transformed parameter name or null if invalid
133
+ */
134
+ transformParameterName(parameterName, pathPrefix) {
135
+ if (!parameterName) {
136
+ return null;
137
+ }
138
+ // Remove the path prefix and all slashes, then convert to uppercase
139
+ // This matches the original implementation: .replace(envPrefix, '').replace(/\//g, '').toUpperCase()
140
+ const key = parameterName.replace(pathPrefix, '').replace(/\//g, '').toUpperCase();
141
+ // Return null for empty keys
142
+ return key || null;
143
+ }
144
+ }
145
+ exports.SSMParameterStoreLoader = SSMParameterStoreLoader;
146
+ //# sourceMappingURL=ssm-parameter-store.loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ssm-parameter-store.loader.js","sourceRoot":"","sources":["../../../src/loaders/ssm-parameter-store.loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,297 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
19
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
20
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
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;
22
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
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
+ })();
41
+ var __metadata = (this && this.__metadata) || function (k, v) {
42
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
43
+ };
44
+ var ConfigServiceImpl_1;
45
+ Object.defineProperty(exports, "__esModule", { value: true });
46
+ exports.ConfigServiceImpl = void 0;
47
+ const common_1 = require("@nestjs/common");
48
+ const config_service_interface_1 = require("../interfaces/config-service.interface");
49
+ const default_schema_interface_1 = require("../interfaces/default-schema.interface");
50
+ const errors_interface_1 = require("../interfaces/errors.interface");
51
+ const validation_util_1 = require("../utils/validation.util");
52
+ const environment_loader_1 = require("../loaders/environment.loader");
53
+ const secrets_manager_loader_1 = require("../loaders/secrets-manager.loader");
54
+ const ssm_parameter_store_loader_1 = require("../loaders/ssm-parameter-store.loader");
55
+ /**
56
+ * Implementation of ConfigService with AWS integration and APP_ENV logic.
57
+ * Provides type-safe configuration access with orchestrated loading from multiple sources.
58
+ */
59
+ let ConfigServiceImpl = ConfigServiceImpl_1 = class ConfigServiceImpl extends config_service_interface_1.ConfigService {
60
+ constructor(options = {}) {
61
+ super();
62
+ this.logger = new common_1.Logger(ConfigServiceImpl_1.name);
63
+ this.config = null;
64
+ this.initialized = false;
65
+ // Set default options
66
+ this.options = {
67
+ envPrefix: options.envPrefix,
68
+ validateOnLoad: options.validateOnLoad ?? true,
69
+ enableLogging: options.enableLogging ?? true,
70
+ };
71
+ // Initialize APP_ENV logic
72
+ this.appEnv = this.initializeAppEnv();
73
+ // Set schema - use environment-specific schema if no custom schema provided
74
+ this.schema = options.schema || (0, default_schema_interface_1.getSchemaForEnvironment)(this.appEnv);
75
+ // Initialize loaders
76
+ this.loaders = options.loaders || this.createDefaultLoaders();
77
+ }
78
+ /**
79
+ * Initialize the configuration service by loading and validating configuration.
80
+ * This method should be called during application startup.
81
+ */
82
+ async initialize() {
83
+ if (this.initialized) {
84
+ return;
85
+ }
86
+ try {
87
+ if (this.options.enableLogging) {
88
+ this.logger.log(`Initializing configuration service with APP_ENV: ${this.appEnv}`);
89
+ }
90
+ // Load configuration from all sources
91
+ const rawConfig = await this.loadConfiguration();
92
+ // Validate configuration if enabled
93
+ if (this.options.validateOnLoad) {
94
+ this.config = validation_util_1.ConfigValidationUtil.validateConfiguration(this.schema, rawConfig, 'merged configuration');
95
+ }
96
+ else {
97
+ this.config = rawConfig;
98
+ }
99
+ this.initialized = true;
100
+ if (this.options.enableLogging) {
101
+ this.logger.log('Configuration service initialized successfully');
102
+ }
103
+ }
104
+ catch (error) {
105
+ const errorMessage = `Failed to initialize configuration service: ${error instanceof Error ? error.message : String(error)}`;
106
+ this.logger.error(errorMessage);
107
+ throw new errors_interface_1.ConfigurationError(errorMessage, error instanceof Error ? error : undefined);
108
+ }
109
+ }
110
+ /**
111
+ * Get a configuration value by key with type safety.
112
+ * @param key - The configuration key to retrieve
113
+ * @returns The configuration value with proper typing
114
+ */
115
+ get(key) {
116
+ if (!this.initialized || !this.config) {
117
+ throw new errors_interface_1.ConfigurationError('Configuration service not initialized. Call initialize() first.');
118
+ }
119
+ return this.config[key];
120
+ }
121
+ /**
122
+ * Check if the configuration service has been initialized.
123
+ * @returns True if the service is ready to serve configuration values
124
+ */
125
+ isInitialized() {
126
+ return this.initialized;
127
+ }
128
+ /**
129
+ * Get all configuration values.
130
+ * @returns The complete configuration object
131
+ */
132
+ getAll() {
133
+ if (!this.initialized || !this.config) {
134
+ throw new errors_interface_1.ConfigurationError('Configuration service not initialized. Call initialize() first.');
135
+ }
136
+ return this.config;
137
+ }
138
+ /**
139
+ * Get the current APP_ENV value.
140
+ * @returns The current application environment
141
+ */
142
+ getAppEnv() {
143
+ return this.appEnv;
144
+ }
145
+ /**
146
+ * Initialize APP_ENV with NODE_ENV mirroring and warning logic.
147
+ * Implements requirement 2.0: APP_ENV mirroring NODE_ENV with "local" default and warning logic.
148
+ */
149
+ initializeAppEnv() {
150
+ const nodeEnv = process.env['NODE_ENV'];
151
+ const appEnv = process.env['APP_ENV'];
152
+ // If APP_ENV is explicitly set
153
+ if (appEnv) {
154
+ // Validate APP_ENV value
155
+ const validation = validation_util_1.ConfigValidationUtil.safeValidate(default_schema_interface_1.appEnvSchema, appEnv);
156
+ if (!validation.success) {
157
+ // If APP_ENV is invalid, try to use NODE_ENV as fallback
158
+ if (nodeEnv) {
159
+ const nodeEnvValidation = validation_util_1.ConfigValidationUtil.safeValidate(default_schema_interface_1.appEnvSchema, nodeEnv);
160
+ if (nodeEnvValidation.success) {
161
+ if (this.options.enableLogging) {
162
+ this.logger.warn(`Invalid APP_ENV value '${appEnv}'. Using NODE_ENV '${nodeEnv}' as fallback.`);
163
+ }
164
+ return nodeEnv;
165
+ }
166
+ }
167
+ // Both APP_ENV and NODE_ENV are invalid, default to 'local'
168
+ if (this.options.enableLogging) {
169
+ this.logger.warn(`Invalid APP_ENV value '${appEnv}' and no valid NODE_ENV fallback. Defaulting to 'local'.`);
170
+ }
171
+ return 'local';
172
+ }
173
+ // APP_ENV is valid, check if it differs from NODE_ENV
174
+ if (nodeEnv && nodeEnv !== appEnv) {
175
+ if (this.options.enableLogging) {
176
+ this.logger.warn(`APP_ENV '${appEnv}' differs from NODE_ENV '${nodeEnv}'. Using APP_ENV value.`);
177
+ }
178
+ }
179
+ return appEnv;
180
+ }
181
+ // APP_ENV not set, try to use NODE_ENV
182
+ if (nodeEnv) {
183
+ const validation = validation_util_1.ConfigValidationUtil.safeValidate(default_schema_interface_1.appEnvSchema, nodeEnv);
184
+ if (validation.success) {
185
+ return nodeEnv;
186
+ }
187
+ // NODE_ENV is invalid, log warning and default to 'local'
188
+ if (this.options.enableLogging) {
189
+ this.logger.warn(`Invalid NODE_ENV value '${nodeEnv}'. Defaulting to 'local'.`);
190
+ }
191
+ }
192
+ // Neither APP_ENV nor NODE_ENV set, default to 'local'
193
+ return 'local';
194
+ }
195
+ /**
196
+ * Create default configuration loaders.
197
+ * @returns Array of default loaders in precedence order
198
+ */
199
+ createDefaultLoaders() {
200
+ return [
201
+ new environment_loader_1.EnvironmentLoader(this.options.envPrefix),
202
+ new secrets_manager_loader_1.SecretsManagerLoader(),
203
+ new ssm_parameter_store_loader_1.SSMParameterStoreLoader(),
204
+ ];
205
+ }
206
+ /**
207
+ * Load configuration from all sources with proper precedence order.
208
+ * Implements orchestration: env -> secrets -> ssm with proper merging.
209
+ */
210
+ async loadConfiguration() {
211
+ const mergedConfig = {};
212
+ for (const loader of this.loaders) {
213
+ try {
214
+ // Check if loader is available in current environment
215
+ const isAvailable = await loader.isAvailable();
216
+ if (!isAvailable) {
217
+ if (this.options.enableLogging) {
218
+ this.logger.debug(`Skipping ${loader.getName()} - not available in current environment`);
219
+ }
220
+ continue;
221
+ }
222
+ if (this.options.enableLogging) {
223
+ this.logger.debug(`Loading configuration from ${loader.getName()}`);
224
+ }
225
+ // Load configuration from this source
226
+ const loaderConfig = await loader.load();
227
+ // Merge with existing configuration
228
+ // Later loaders override earlier ones (environment variables have lowest precedence)
229
+ Object.assign(mergedConfig, loaderConfig);
230
+ if (this.options.enableLogging) {
231
+ const keyCount = Object.keys(loaderConfig).length;
232
+ this.logger.debug(`Loaded ${keyCount} configuration values from ${loader.getName()}`);
233
+ }
234
+ }
235
+ catch (error) {
236
+ const errorMessage = `Failed to load configuration from ${loader.getName()}: ${error instanceof Error ? error.message : String(error)}`;
237
+ if (this.options.enableLogging) {
238
+ this.logger.error(errorMessage);
239
+ }
240
+ throw new errors_interface_1.ConfigurationLoadError(errorMessage, loader.getName(), error instanceof Error ? error : undefined);
241
+ }
242
+ }
243
+ // Handle special case for local environment with .env file override
244
+ if (this.appEnv === 'local') {
245
+ await this.handleLocalEnvironmentOverrides(mergedConfig);
246
+ }
247
+ return mergedConfig;
248
+ }
249
+ /**
250
+ * Handle local environment overrides according to requirement 2.4.
251
+ * In local mode with valid AWS profile and .env file, .env values override AWS values.
252
+ */
253
+ async handleLocalEnvironmentOverrides(config) {
254
+ // Check if we have a valid AWS profile in the credential chain
255
+ const awsProfile = process.env['AWS_PROFILE'];
256
+ if (!awsProfile) {
257
+ return; // No AWS profile, no special handling needed
258
+ }
259
+ // Check if .env file exists (this is a simplified check - in real implementation
260
+ // you might want to use a library like dotenv to properly detect .env files)
261
+ try {
262
+ const fs = await Promise.resolve().then(() => __importStar(require('fs')));
263
+ const path = await Promise.resolve().then(() => __importStar(require('path')));
264
+ const envFilePath = path.resolve(process.cwd(), '.env');
265
+ const envFileExists = fs.existsSync(envFilePath);
266
+ if (envFileExists) {
267
+ if (this.options.enableLogging) {
268
+ this.logger.debug('Local environment detected with AWS profile and .env file. ' +
269
+ 'Environment variables from .env will override AWS values.');
270
+ }
271
+ // Load .env file and override AWS values
272
+ const dotenv = await Promise.resolve().then(() => __importStar(require('dotenv')));
273
+ const envConfig = dotenv.config({ path: envFilePath });
274
+ if (envConfig.parsed) {
275
+ // Override AWS values with .env values
276
+ Object.assign(config, envConfig.parsed);
277
+ if (this.options.enableLogging) {
278
+ const overrideCount = Object.keys(envConfig.parsed).length;
279
+ this.logger.debug(`Applied ${overrideCount} overrides from .env file`);
280
+ }
281
+ }
282
+ }
283
+ }
284
+ catch (error) {
285
+ // If we can't load .env file, just log a warning and continue
286
+ if (this.options.enableLogging) {
287
+ this.logger.warn(`Failed to load .env file for local overrides: ${error instanceof Error ? error.message : String(error)}`);
288
+ }
289
+ }
290
+ }
291
+ };
292
+ exports.ConfigServiceImpl = ConfigServiceImpl;
293
+ exports.ConfigServiceImpl = ConfigServiceImpl = ConfigServiceImpl_1 = __decorate([
294
+ (0, common_1.Injectable)(),
295
+ __metadata("design:paramtypes", [Object])
296
+ ], ConfigServiceImpl);
297
+ //# sourceMappingURL=config.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.service.js","sourceRoot":"","sources":["../../../src/services/config.service.ts"],"names":[],"mappings":"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"}