@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.
- package/LICENSE +21 -0
- package/README.md +1183 -0
- package/dist/cjs/config.module.js +178 -0
- package/dist/cjs/config.module.js.map +1 -0
- package/dist/cjs/index.js +47 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/integration/index.js +23 -0
- package/dist/cjs/integration/index.js.map +1 -0
- package/dist/cjs/integration/interfaces/configuration-factory.interface.js +3 -0
- package/dist/cjs/integration/interfaces/configuration-factory.interface.js.map +1 -0
- package/dist/cjs/integration/interfaces/configuration-source.interface.js +3 -0
- package/dist/cjs/integration/interfaces/configuration-source.interface.js.map +1 -0
- package/dist/cjs/integration/interfaces/index.js +26 -0
- package/dist/cjs/integration/interfaces/index.js.map +1 -0
- package/dist/cjs/integration/interfaces/integration-options.interface.js +3 -0
- package/dist/cjs/integration/interfaces/integration-options.interface.js.map +1 -0
- package/dist/cjs/integration/interfaces/integration-state.interface.js +3 -0
- package/dist/cjs/integration/interfaces/integration-state.interface.js.map +1 -0
- package/dist/cjs/integration/interfaces/nestjs-config-compatibility.interface.js +73 -0
- package/dist/cjs/integration/interfaces/nestjs-config-compatibility.interface.js.map +1 -0
- package/dist/cjs/integration/interfaces/nestjs-config-integration.interface.js +3 -0
- package/dist/cjs/integration/interfaces/nestjs-config-integration.interface.js.map +1 -0
- package/dist/cjs/integration/interfaces/typed-configuration.interface.js +4 -0
- package/dist/cjs/integration/interfaces/typed-configuration.interface.js.map +1 -0
- package/dist/cjs/integration/interfaces/utility-types.interface.js +52 -0
- package/dist/cjs/integration/interfaces/utility-types.interface.js.map +1 -0
- package/dist/cjs/integration/nestjs-config-integration.module.js +124 -0
- package/dist/cjs/integration/nestjs-config-integration.module.js.map +1 -0
- package/dist/cjs/integration/providers/aws-configuration-loader.service.js +591 -0
- package/dist/cjs/integration/providers/aws-configuration-loader.service.js.map +1 -0
- package/dist/cjs/integration/providers/configuration-factory.provider.js +383 -0
- package/dist/cjs/integration/providers/configuration-factory.provider.js.map +1 -0
- package/dist/cjs/integration/providers/index.js +20 -0
- package/dist/cjs/integration/providers/index.js.map +1 -0
- package/dist/cjs/integration/services/async-config-helper.service.js +356 -0
- package/dist/cjs/integration/services/async-config-helper.service.js.map +1 -0
- package/dist/cjs/integration/services/error-handler.service.js +265 -0
- package/dist/cjs/integration/services/error-handler.service.js.map +1 -0
- package/dist/cjs/integration/services/factory-registration.service.js +512 -0
- package/dist/cjs/integration/services/factory-registration.service.js.map +1 -0
- package/dist/cjs/integration/services/index.js +26 -0
- package/dist/cjs/integration/services/index.js.map +1 -0
- package/dist/cjs/integration/services/integration-state.service.js +83 -0
- package/dist/cjs/integration/services/integration-state.service.js.map +1 -0
- package/dist/cjs/integration/services/namespace-handler.service.js +467 -0
- package/dist/cjs/integration/services/namespace-handler.service.js.map +1 -0
- package/dist/cjs/integration/services/nestjs-config-integration.service.js +316 -0
- package/dist/cjs/integration/services/nestjs-config-integration.service.js.map +1 -0
- package/dist/cjs/integration/services/precedence-handler.service.js +294 -0
- package/dist/cjs/integration/services/precedence-handler.service.js.map +1 -0
- package/dist/cjs/integration/services/validation-integration.service.js +591 -0
- package/dist/cjs/integration/services/validation-integration.service.js.map +1 -0
- package/dist/cjs/integration/utils/config-integration.util.js +283 -0
- package/dist/cjs/integration/utils/config-integration.util.js.map +1 -0
- package/dist/cjs/integration/utils/index.js +19 -0
- package/dist/cjs/integration/utils/index.js.map +1 -0
- package/dist/cjs/interfaces/config-loader.interface.js +3 -0
- package/dist/cjs/interfaces/config-loader.interface.js.map +1 -0
- package/dist/cjs/interfaces/config-service.interface.js +11 -0
- package/dist/cjs/interfaces/config-service.interface.js.map +1 -0
- package/dist/cjs/interfaces/default-schema.interface.js +63 -0
- package/dist/cjs/interfaces/default-schema.interface.js.map +1 -0
- package/dist/cjs/interfaces/errors.interface.js +77 -0
- package/dist/cjs/interfaces/errors.interface.js.map +1 -0
- package/dist/cjs/interfaces/index.js +25 -0
- package/dist/cjs/interfaces/index.js.map +1 -0
- package/dist/cjs/interfaces/module-options.interface.js +3 -0
- package/dist/cjs/interfaces/module-options.interface.js.map +1 -0
- package/dist/cjs/loaders/environment.loader.js +59 -0
- package/dist/cjs/loaders/environment.loader.js.map +1 -0
- package/dist/cjs/loaders/secrets-manager.loader.js +122 -0
- package/dist/cjs/loaders/secrets-manager.loader.js.map +1 -0
- package/dist/cjs/loaders/ssm-parameter-store.loader.js +146 -0
- package/dist/cjs/loaders/ssm-parameter-store.loader.js.map +1 -0
- package/dist/cjs/services/config.service.js +297 -0
- package/dist/cjs/services/config.service.js.map +1 -0
- package/dist/cjs/utils/validation.util.js +114 -0
- package/dist/cjs/utils/validation.util.js.map +1 -0
- package/dist/esm/config.module.js +175 -0
- package/dist/esm/config.module.js.map +1 -0
- package/dist/esm/index.js +18 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/integration/index.js +7 -0
- package/dist/esm/integration/index.js.map +1 -0
- package/dist/esm/integration/interfaces/configuration-factory.interface.js +2 -0
- package/dist/esm/integration/interfaces/configuration-factory.interface.js.map +1 -0
- package/dist/esm/integration/interfaces/configuration-source.interface.js +2 -0
- package/dist/esm/integration/interfaces/configuration-source.interface.js.map +1 -0
- package/dist/esm/integration/interfaces/index.js +10 -0
- package/dist/esm/integration/interfaces/index.js.map +1 -0
- package/dist/esm/integration/interfaces/integration-options.interface.js +2 -0
- package/dist/esm/integration/interfaces/integration-options.interface.js.map +1 -0
- package/dist/esm/integration/interfaces/integration-state.interface.js +2 -0
- package/dist/esm/integration/interfaces/integration-state.interface.js.map +1 -0
- package/dist/esm/integration/interfaces/nestjs-config-compatibility.interface.js +64 -0
- package/dist/esm/integration/interfaces/nestjs-config-compatibility.interface.js.map +1 -0
- package/dist/esm/integration/interfaces/nestjs-config-integration.interface.js +2 -0
- package/dist/esm/integration/interfaces/nestjs-config-integration.interface.js.map +1 -0
- package/dist/esm/integration/interfaces/typed-configuration.interface.js +3 -0
- package/dist/esm/integration/interfaces/typed-configuration.interface.js.map +1 -0
- package/dist/esm/integration/interfaces/utility-types.interface.js +44 -0
- package/dist/esm/integration/interfaces/utility-types.interface.js.map +1 -0
- package/dist/esm/integration/nestjs-config-integration.module.js +121 -0
- package/dist/esm/integration/nestjs-config-integration.module.js.map +1 -0
- package/dist/esm/integration/providers/aws-configuration-loader.service.js +588 -0
- package/dist/esm/integration/providers/aws-configuration-loader.service.js.map +1 -0
- package/dist/esm/integration/providers/configuration-factory.provider.js +380 -0
- package/dist/esm/integration/providers/configuration-factory.provider.js.map +1 -0
- package/dist/esm/integration/providers/index.js +4 -0
- package/dist/esm/integration/providers/index.js.map +1 -0
- package/dist/esm/integration/services/async-config-helper.service.js +353 -0
- package/dist/esm/integration/services/async-config-helper.service.js.map +1 -0
- package/dist/esm/integration/services/error-handler.service.js +262 -0
- package/dist/esm/integration/services/error-handler.service.js.map +1 -0
- package/dist/esm/integration/services/factory-registration.service.js +509 -0
- package/dist/esm/integration/services/factory-registration.service.js.map +1 -0
- package/dist/esm/integration/services/index.js +10 -0
- package/dist/esm/integration/services/index.js.map +1 -0
- package/dist/esm/integration/services/integration-state.service.js +80 -0
- package/dist/esm/integration/services/integration-state.service.js.map +1 -0
- package/dist/esm/integration/services/namespace-handler.service.js +464 -0
- package/dist/esm/integration/services/namespace-handler.service.js.map +1 -0
- package/dist/esm/integration/services/nestjs-config-integration.service.js +313 -0
- package/dist/esm/integration/services/nestjs-config-integration.service.js.map +1 -0
- package/dist/esm/integration/services/precedence-handler.service.js +291 -0
- package/dist/esm/integration/services/precedence-handler.service.js.map +1 -0
- package/dist/esm/integration/services/validation-integration.service.js +585 -0
- package/dist/esm/integration/services/validation-integration.service.js.map +1 -0
- package/dist/esm/integration/utils/config-integration.util.js +240 -0
- package/dist/esm/integration/utils/config-integration.util.js.map +1 -0
- package/dist/esm/integration/utils/index.js +3 -0
- package/dist/esm/integration/utils/index.js.map +1 -0
- package/dist/esm/interfaces/config-loader.interface.js +2 -0
- package/dist/esm/interfaces/config-loader.interface.js.map +1 -0
- package/dist/esm/interfaces/config-service.interface.js +7 -0
- package/dist/esm/interfaces/config-service.interface.js.map +1 -0
- package/dist/esm/interfaces/default-schema.interface.js +59 -0
- package/dist/esm/interfaces/default-schema.interface.js.map +1 -0
- package/dist/esm/interfaces/errors.interface.js +69 -0
- package/dist/esm/interfaces/errors.interface.js.map +1 -0
- package/dist/esm/interfaces/index.js +9 -0
- package/dist/esm/interfaces/index.js.map +1 -0
- package/dist/esm/interfaces/module-options.interface.js +2 -0
- package/dist/esm/interfaces/module-options.interface.js.map +1 -0
- package/dist/esm/loaders/environment.loader.js +55 -0
- package/dist/esm/loaders/environment.loader.js.map +1 -0
- package/dist/esm/loaders/secrets-manager.loader.js +118 -0
- package/dist/esm/loaders/secrets-manager.loader.js.map +1 -0
- package/dist/esm/loaders/ssm-parameter-store.loader.js +142 -0
- package/dist/esm/loaders/ssm-parameter-store.loader.js.map +1 -0
- package/dist/esm/services/config.service.js +261 -0
- package/dist/esm/services/config.service.js.map +1 -0
- package/dist/esm/utils/validation.util.js +110 -0
- package/dist/esm/utils/validation.util.js.map +1 -0
- package/dist/types/config.module.d.ts +46 -0
- package/dist/types/config.module.d.ts.map +1 -0
- package/dist/types/index.d.ts +13 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/integration/index.d.ts +6 -0
- package/dist/types/integration/index.d.ts.map +1 -0
- package/dist/types/integration/interfaces/configuration-factory.interface.d.ts +71 -0
- package/dist/types/integration/interfaces/configuration-factory.interface.d.ts.map +1 -0
- package/dist/types/integration/interfaces/configuration-source.interface.d.ts +24 -0
- package/dist/types/integration/interfaces/configuration-source.interface.d.ts.map +1 -0
- package/dist/types/integration/interfaces/index.d.ts +9 -0
- package/dist/types/integration/interfaces/index.d.ts.map +1 -0
- package/dist/types/integration/interfaces/integration-options.interface.d.ts +66 -0
- package/dist/types/integration/interfaces/integration-options.interface.d.ts.map +1 -0
- package/dist/types/integration/interfaces/integration-state.interface.d.ts +17 -0
- package/dist/types/integration/interfaces/integration-state.interface.d.ts.map +1 -0
- package/dist/types/integration/interfaces/nestjs-config-compatibility.interface.d.ts +332 -0
- package/dist/types/integration/interfaces/nestjs-config-compatibility.interface.d.ts.map +1 -0
- package/dist/types/integration/interfaces/nestjs-config-integration.interface.d.ts +259 -0
- package/dist/types/integration/interfaces/nestjs-config-integration.interface.d.ts.map +1 -0
- package/dist/types/integration/interfaces/typed-configuration.interface.d.ts +209 -0
- package/dist/types/integration/interfaces/typed-configuration.interface.d.ts.map +1 -0
- package/dist/types/integration/interfaces/utility-types.interface.d.ts +249 -0
- package/dist/types/integration/interfaces/utility-types.interface.d.ts.map +1 -0
- package/dist/types/integration/nestjs-config-integration.module.d.ts +36 -0
- package/dist/types/integration/nestjs-config-integration.module.d.ts.map +1 -0
- package/dist/types/integration/providers/aws-configuration-loader.service.d.ts +134 -0
- package/dist/types/integration/providers/aws-configuration-loader.service.d.ts.map +1 -0
- package/dist/types/integration/providers/configuration-factory.provider.d.ts +119 -0
- package/dist/types/integration/providers/configuration-factory.provider.d.ts.map +1 -0
- package/dist/types/integration/providers/index.d.ts +3 -0
- package/dist/types/integration/providers/index.d.ts.map +1 -0
- package/dist/types/integration/services/async-config-helper.service.d.ts +84 -0
- package/dist/types/integration/services/async-config-helper.service.d.ts.map +1 -0
- package/dist/types/integration/services/error-handler.service.d.ts +84 -0
- package/dist/types/integration/services/error-handler.service.d.ts.map +1 -0
- package/dist/types/integration/services/factory-registration.service.d.ts +158 -0
- package/dist/types/integration/services/factory-registration.service.d.ts.map +1 -0
- package/dist/types/integration/services/index.d.ts +9 -0
- package/dist/types/integration/services/index.d.ts.map +1 -0
- package/dist/types/integration/services/integration-state.service.d.ts +41 -0
- package/dist/types/integration/services/integration-state.service.d.ts.map +1 -0
- package/dist/types/integration/services/namespace-handler.service.d.ts +192 -0
- package/dist/types/integration/services/namespace-handler.service.d.ts.map +1 -0
- package/dist/types/integration/services/nestjs-config-integration.service.d.ts +87 -0
- package/dist/types/integration/services/nestjs-config-integration.service.d.ts.map +1 -0
- package/dist/types/integration/services/precedence-handler.service.d.ts +103 -0
- package/dist/types/integration/services/precedence-handler.service.d.ts.map +1 -0
- package/dist/types/integration/services/validation-integration.service.d.ts +222 -0
- package/dist/types/integration/services/validation-integration.service.d.ts.map +1 -0
- package/dist/types/integration/utils/config-integration.util.d.ts +81 -0
- package/dist/types/integration/utils/config-integration.util.d.ts.map +1 -0
- package/dist/types/integration/utils/index.d.ts +2 -0
- package/dist/types/integration/utils/index.d.ts.map +1 -0
- package/dist/types/interfaces/config-loader.interface.d.ts +22 -0
- package/dist/types/interfaces/config-loader.interface.d.ts.map +1 -0
- package/dist/types/interfaces/config-service.interface.d.ts +23 -0
- package/dist/types/interfaces/config-service.interface.d.ts.map +1 -0
- package/dist/types/interfaces/default-schema.interface.d.ts +195 -0
- package/dist/types/interfaces/default-schema.interface.d.ts.map +1 -0
- package/dist/types/interfaces/errors.interface.d.ts +38 -0
- package/dist/types/interfaces/errors.interface.d.ts.map +1 -0
- package/dist/types/interfaces/index.d.ts +6 -0
- package/dist/types/interfaces/index.d.ts.map +1 -0
- package/dist/types/interfaces/module-options.interface.d.ts +64 -0
- package/dist/types/interfaces/module-options.interface.d.ts.map +1 -0
- package/dist/types/loaders/environment.loader.d.ts +26 -0
- package/dist/types/loaders/environment.loader.d.ts.map +1 -0
- package/dist/types/loaders/secrets-manager.loader.d.ts +52 -0
- package/dist/types/loaders/secrets-manager.loader.d.ts.map +1 -0
- package/dist/types/loaders/ssm-parameter-store.loader.d.ts +68 -0
- package/dist/types/loaders/ssm-parameter-store.loader.d.ts.map +1 -0
- package/dist/types/services/config.service.d.ts +94 -0
- package/dist/types/services/config.service.d.ts.map +1 -0
- package/dist/types/utils/validation.util.d.ts +53 -0
- package/dist/types/utils/validation.util.d.ts.map +1 -0
- 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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"}
|