@dyanet/config-aws 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/README.md +195 -0
  2. package/dist/cjs/config-manager.js +360 -0
  3. package/dist/cjs/config-manager.js.map +1 -0
  4. package/dist/cjs/errors/index.js +65 -0
  5. package/dist/cjs/errors/index.js.map +1 -0
  6. package/dist/cjs/index.js +37 -0
  7. package/dist/cjs/index.js.map +1 -0
  8. package/dist/cjs/interfaces/config-loader.interface.js +3 -0
  9. package/dist/cjs/interfaces/config-loader.interface.js.map +1 -0
  10. package/dist/cjs/interfaces/config-manager.interface.js +3 -0
  11. package/dist/cjs/interfaces/config-manager.interface.js.map +1 -0
  12. package/dist/cjs/interfaces/env-file-loader.interface.js +3 -0
  13. package/dist/cjs/interfaces/env-file-loader.interface.js.map +1 -0
  14. package/dist/cjs/interfaces/environment-loader.interface.js +3 -0
  15. package/dist/cjs/interfaces/environment-loader.interface.js.map +1 -0
  16. package/dist/cjs/interfaces/index.js +3 -0
  17. package/dist/cjs/interfaces/index.js.map +1 -0
  18. package/dist/cjs/interfaces/s3-loader.interface.js +3 -0
  19. package/dist/cjs/interfaces/s3-loader.interface.js.map +1 -0
  20. package/dist/cjs/interfaces/secrets-manager-loader.interface.js +3 -0
  21. package/dist/cjs/interfaces/secrets-manager-loader.interface.js.map +1 -0
  22. package/dist/cjs/interfaces/ssm-parameter-store-loader.interface.js +3 -0
  23. package/dist/cjs/interfaces/ssm-parameter-store-loader.interface.js.map +1 -0
  24. package/dist/cjs/loaders/env-file.loader.js +167 -0
  25. package/dist/cjs/loaders/env-file.loader.js.map +1 -0
  26. package/dist/cjs/loaders/environment.loader.js +83 -0
  27. package/dist/cjs/loaders/environment.loader.js.map +1 -0
  28. package/dist/cjs/loaders/index.js +14 -0
  29. package/dist/cjs/loaders/index.js.map +1 -0
  30. package/dist/cjs/loaders/s3.loader.js +141 -0
  31. package/dist/cjs/loaders/s3.loader.js.map +1 -0
  32. package/dist/cjs/loaders/secrets-manager.loader.js +156 -0
  33. package/dist/cjs/loaders/secrets-manager.loader.js.map +1 -0
  34. package/dist/cjs/loaders/ssm-parameter-store.loader.js +193 -0
  35. package/dist/cjs/loaders/ssm-parameter-store.loader.js.map +1 -0
  36. package/dist/cjs/utils/env-file-parser.util.js +98 -0
  37. package/dist/cjs/utils/env-file-parser.util.js.map +1 -0
  38. package/dist/cjs/utils/index.js +8 -0
  39. package/dist/cjs/utils/index.js.map +1 -0
  40. package/dist/cjs/utils/validation.util.js +116 -0
  41. package/dist/cjs/utils/validation.util.js.map +1 -0
  42. package/dist/esm/config-manager.js +356 -0
  43. package/dist/esm/config-manager.js.map +1 -0
  44. package/dist/esm/errors/index.js +57 -0
  45. package/dist/esm/errors/index.js.map +1 -0
  46. package/dist/esm/index.js +21 -0
  47. package/dist/esm/index.js.map +1 -0
  48. package/dist/esm/interfaces/config-loader.interface.js +2 -0
  49. package/dist/esm/interfaces/config-loader.interface.js.map +1 -0
  50. package/dist/esm/interfaces/config-manager.interface.js +2 -0
  51. package/dist/esm/interfaces/config-manager.interface.js.map +1 -0
  52. package/dist/esm/interfaces/env-file-loader.interface.js +2 -0
  53. package/dist/esm/interfaces/env-file-loader.interface.js.map +1 -0
  54. package/dist/esm/interfaces/environment-loader.interface.js +2 -0
  55. package/dist/esm/interfaces/environment-loader.interface.js.map +1 -0
  56. package/dist/esm/interfaces/index.js +2 -0
  57. package/dist/esm/interfaces/index.js.map +1 -0
  58. package/dist/esm/interfaces/s3-loader.interface.js +2 -0
  59. package/dist/esm/interfaces/s3-loader.interface.js.map +1 -0
  60. package/dist/esm/interfaces/secrets-manager-loader.interface.js +2 -0
  61. package/dist/esm/interfaces/secrets-manager-loader.interface.js.map +1 -0
  62. package/dist/esm/interfaces/ssm-parameter-store-loader.interface.js +2 -0
  63. package/dist/esm/interfaces/ssm-parameter-store-loader.interface.js.map +1 -0
  64. package/dist/esm/loaders/env-file.loader.js +130 -0
  65. package/dist/esm/loaders/env-file.loader.js.map +1 -0
  66. package/dist/esm/loaders/environment.loader.js +79 -0
  67. package/dist/esm/loaders/environment.loader.js.map +1 -0
  68. package/dist/esm/loaders/index.js +6 -0
  69. package/dist/esm/loaders/index.js.map +1 -0
  70. package/dist/esm/loaders/s3.loader.js +137 -0
  71. package/dist/esm/loaders/s3.loader.js.map +1 -0
  72. package/dist/esm/loaders/secrets-manager.loader.js +152 -0
  73. package/dist/esm/loaders/secrets-manager.loader.js.map +1 -0
  74. package/dist/esm/loaders/ssm-parameter-store.loader.js +189 -0
  75. package/dist/esm/loaders/ssm-parameter-store.loader.js.map +1 -0
  76. package/dist/esm/utils/env-file-parser.util.js +94 -0
  77. package/dist/esm/utils/env-file-parser.util.js.map +1 -0
  78. package/dist/esm/utils/index.js +3 -0
  79. package/dist/esm/utils/index.js.map +1 -0
  80. package/dist/esm/utils/validation.util.js +112 -0
  81. package/dist/esm/utils/validation.util.js.map +1 -0
  82. package/dist/types/config-manager.d.ts +119 -0
  83. package/dist/types/config-manager.d.ts.map +1 -0
  84. package/dist/types/errors/index.d.ts +43 -0
  85. package/dist/types/errors/index.d.ts.map +1 -0
  86. package/dist/types/index.d.ts +24 -0
  87. package/dist/types/index.d.ts.map +1 -0
  88. package/dist/types/interfaces/config-loader.interface.d.ts +33 -0
  89. package/dist/types/interfaces/config-loader.interface.d.ts.map +1 -0
  90. package/dist/types/interfaces/config-manager.interface.d.ts +86 -0
  91. package/dist/types/interfaces/config-manager.interface.d.ts.map +1 -0
  92. package/dist/types/interfaces/env-file-loader.interface.d.ts +12 -0
  93. package/dist/types/interfaces/env-file-loader.interface.d.ts.map +1 -0
  94. package/dist/types/interfaces/environment-loader.interface.d.ts +10 -0
  95. package/dist/types/interfaces/environment-loader.interface.d.ts.map +1 -0
  96. package/dist/types/interfaces/index.d.ts +8 -0
  97. package/dist/types/interfaces/index.d.ts.map +1 -0
  98. package/dist/types/interfaces/s3-loader.interface.d.ts +14 -0
  99. package/dist/types/interfaces/s3-loader.interface.d.ts.map +1 -0
  100. package/dist/types/interfaces/secrets-manager-loader.interface.d.ts +12 -0
  101. package/dist/types/interfaces/secrets-manager-loader.interface.d.ts.map +1 -0
  102. package/dist/types/interfaces/ssm-parameter-store-loader.interface.d.ts +14 -0
  103. package/dist/types/interfaces/ssm-parameter-store-loader.interface.d.ts.map +1 -0
  104. package/dist/types/loaders/env-file.loader.d.ts +69 -0
  105. package/dist/types/loaders/env-file.loader.d.ts.map +1 -0
  106. package/dist/types/loaders/environment.loader.d.ts +46 -0
  107. package/dist/types/loaders/environment.loader.d.ts.map +1 -0
  108. package/dist/types/loaders/index.d.ts +6 -0
  109. package/dist/types/loaders/index.d.ts.map +1 -0
  110. package/dist/types/loaders/s3.loader.d.ts +62 -0
  111. package/dist/types/loaders/s3.loader.d.ts.map +1 -0
  112. package/dist/types/loaders/secrets-manager.loader.d.ts +68 -0
  113. package/dist/types/loaders/secrets-manager.loader.d.ts.map +1 -0
  114. package/dist/types/loaders/ssm-parameter-store.loader.d.ts +78 -0
  115. package/dist/types/loaders/ssm-parameter-store.loader.d.ts.map +1 -0
  116. package/dist/types/utils/env-file-parser.util.d.ts +45 -0
  117. package/dist/types/utils/env-file-parser.util.d.ts.map +1 -0
  118. package/dist/types/utils/index.d.ts +3 -0
  119. package/dist/types/utils/index.d.ts.map +1 -0
  120. package/dist/types/utils/validation.util.d.ts +53 -0
  121. package/dist/types/utils/validation.util.d.ts.map +1 -0
  122. package/package.json +97 -0
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=config-loader.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-loader.interface.js","sourceRoot":"","sources":["../../../src/interfaces/config-loader.interface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=config-manager.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-manager.interface.js","sourceRoot":"","sources":["../../../src/interfaces/config-manager.interface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=env-file-loader.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-file-loader.interface.js","sourceRoot":"","sources":["../../../src/interfaces/env-file-loader.interface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=environment-loader.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"environment-loader.interface.js","sourceRoot":"","sources":["../../../src/interfaces/environment-loader.interface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/interfaces/index.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=s3-loader.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"s3-loader.interface.js","sourceRoot":"","sources":["../../../src/interfaces/s3-loader.interface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=secrets-manager-loader.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secrets-manager-loader.interface.js","sourceRoot":"","sources":["../../../src/interfaces/secrets-manager-loader.interface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=ssm-parameter-store-loader.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ssm-parameter-store-loader.interface.js","sourceRoot":"","sources":["../../../src/interfaces/ssm-parameter-store-loader.interface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,167 @@
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 __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.EnvFileLoader = void 0;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ const env_file_parser_util_1 = require("../utils/env-file-parser.util");
40
+ const errors_1 = require("../errors");
41
+ /**
42
+ * Loader that reads configuration from .env files on the filesystem.
43
+ * Uses AWS ECS-compatible format for parsing.
44
+ *
45
+ * @example
46
+ * ```typescript
47
+ * // Load from default paths (.env, .env.local)
48
+ * const loader = new EnvFileLoader();
49
+ *
50
+ * // Load from specific paths
51
+ * const loader = new EnvFileLoader({
52
+ * paths: ['.env', '.env.production']
53
+ * });
54
+ *
55
+ * // Disable override (first file wins)
56
+ * const loader = new EnvFileLoader({
57
+ * paths: ['.env', '.env.local'],
58
+ * override: false
59
+ * });
60
+ * ```
61
+ *
62
+ * @see https://docs.aws.amazon.com/AmazonECS/latest/developerguide/use-environment-file.html
63
+ */
64
+ class EnvFileLoader {
65
+ constructor(config = {}) {
66
+ this._config = {
67
+ paths: config.paths ?? EnvFileLoader.DEFAULT_PATHS,
68
+ encoding: config.encoding ?? EnvFileLoader.DEFAULT_ENCODING,
69
+ override: config.override ?? true,
70
+ };
71
+ }
72
+ getName() {
73
+ return 'EnvFileLoader';
74
+ }
75
+ /**
76
+ * Check if at least one of the configured .env files exists.
77
+ * @returns Promise resolving to true if any file exists
78
+ */
79
+ async isAvailable() {
80
+ for (const filePath of this._config.paths) {
81
+ const resolvedPath = this.resolvePath(filePath);
82
+ if (await this.fileExists(resolvedPath)) {
83
+ return true;
84
+ }
85
+ }
86
+ return false;
87
+ }
88
+ /**
89
+ * Load configuration from .env files.
90
+ *
91
+ * Files are processed in order. When override is true (default),
92
+ * later files override earlier ones. When override is false,
93
+ * earlier files take precedence.
94
+ *
95
+ * Missing files are silently skipped.
96
+ *
97
+ * @returns Promise resolving to the merged configuration
98
+ * @throws ConfigurationLoadError if a file exists but cannot be read
99
+ */
100
+ async load() {
101
+ const result = {};
102
+ for (const filePath of this._config.paths) {
103
+ const resolvedPath = this.resolvePath(filePath);
104
+ if (!(await this.fileExists(resolvedPath))) {
105
+ // Skip missing files silently
106
+ continue;
107
+ }
108
+ try {
109
+ const content = await this.readFile(resolvedPath);
110
+ const parsed = env_file_parser_util_1.EnvFileParser.parse(content);
111
+ // Merge based on override setting
112
+ if (this._config.override) {
113
+ // Later files override earlier ones
114
+ Object.assign(result, parsed);
115
+ }
116
+ else {
117
+ // Earlier files take precedence - only add keys that don't exist
118
+ for (const [key, value] of Object.entries(parsed)) {
119
+ if (!(key in result)) {
120
+ result[key] = value;
121
+ }
122
+ }
123
+ }
124
+ }
125
+ catch (error) {
126
+ throw new errors_1.ConfigurationLoadError(`Failed to read env file: ${resolvedPath}`, this.getName(), error instanceof Error ? error : undefined);
127
+ }
128
+ }
129
+ return result;
130
+ }
131
+ /**
132
+ * Resolve a file path relative to the current working directory.
133
+ * @internal
134
+ */
135
+ resolvePath(filePath) {
136
+ if (path.isAbsolute(filePath)) {
137
+ return filePath;
138
+ }
139
+ return path.resolve(process.cwd(), filePath);
140
+ }
141
+ /**
142
+ * Check if a file exists.
143
+ * @internal
144
+ */
145
+ async fileExists(filePath) {
146
+ try {
147
+ await fs.promises.access(filePath, fs.constants.R_OK);
148
+ return true;
149
+ }
150
+ catch {
151
+ return false;
152
+ }
153
+ }
154
+ /**
155
+ * Read a file's contents.
156
+ * @internal
157
+ */
158
+ async readFile(filePath) {
159
+ return fs.promises.readFile(filePath, { encoding: this._config.encoding });
160
+ }
161
+ }
162
+ exports.EnvFileLoader = EnvFileLoader;
163
+ /** Default paths to search for .env files */
164
+ EnvFileLoader.DEFAULT_PATHS = ['.env', '.env.local'];
165
+ /** Default file encoding */
166
+ EnvFileLoader.DEFAULT_ENCODING = 'utf-8';
167
+ //# sourceMappingURL=env-file.loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-file.loader.js","sourceRoot":"","sources":["../../../src/loaders/env-file.loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EnvironmentLoader = void 0;
4
+ /**
5
+ * Loader that reads configuration from process.env.
6
+ * Supports prefix filtering and exclusion lists.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * // Load all environment variables
11
+ * const loader = new EnvironmentLoader();
12
+ *
13
+ * // Load only variables starting with 'APP_', stripping the prefix
14
+ * const loader = new EnvironmentLoader({ prefix: 'APP_' });
15
+ *
16
+ * // Load all except specific variables
17
+ * const loader = new EnvironmentLoader({ exclude: ['PATH', 'HOME'] });
18
+ *
19
+ * // Combine prefix and exclusion
20
+ * const loader = new EnvironmentLoader({
21
+ * prefix: 'APP_',
22
+ * exclude: ['APP_DEBUG']
23
+ * });
24
+ * ```
25
+ */
26
+ class EnvironmentLoader {
27
+ constructor(config = {}) {
28
+ this._config = config;
29
+ }
30
+ getName() {
31
+ return 'EnvironmentLoader';
32
+ }
33
+ async isAvailable() {
34
+ return true;
35
+ }
36
+ /**
37
+ * Load configuration from process.env.
38
+ *
39
+ * When a prefix is specified:
40
+ * - Only variables starting with the prefix are included
41
+ * - The prefix is stripped from the resulting key names
42
+ *
43
+ * When an exclusion list is specified:
44
+ * - Variables in the list are excluded from the result
45
+ * - Exclusion is checked against the original key (before prefix stripping)
46
+ *
47
+ * @returns Promise resolving to the loaded configuration
48
+ */
49
+ async load() {
50
+ const result = {};
51
+ const { prefix, exclude = [] } = this._config;
52
+ const excludeSet = new Set(exclude);
53
+ for (const [key, value] of Object.entries(process.env)) {
54
+ // Skip undefined values
55
+ if (value === undefined) {
56
+ continue;
57
+ }
58
+ // Check exclusion list (against original key)
59
+ if (excludeSet.has(key)) {
60
+ continue;
61
+ }
62
+ // Handle prefix filtering
63
+ if (prefix) {
64
+ if (key.startsWith(prefix)) {
65
+ // Strip prefix from key
66
+ const strippedKey = key.slice(prefix.length);
67
+ // Only include if there's a key remaining after stripping
68
+ if (strippedKey) {
69
+ result[strippedKey] = value;
70
+ }
71
+ }
72
+ // Skip keys that don't match the prefix
73
+ }
74
+ else {
75
+ // No prefix - include all non-excluded keys
76
+ result[key] = value;
77
+ }
78
+ }
79
+ return result;
80
+ }
81
+ }
82
+ exports.EnvironmentLoader = EnvironmentLoader;
83
+ //# sourceMappingURL=environment.loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"environment.loader.js","sourceRoot":"","sources":["../../../src/loaders/environment.loader.ts"],"names":[],"mappings":";;;AAGA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAa,iBAAiB;IAI5B,YAAY,SAAkC,EAAE;QAC9C,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;IACxB,CAAC;IAED,OAAO;QACL,OAAO,mBAAmB,CAAC;IAC7B,CAAC;IAED,KAAK,CAAC,WAAW;QACf,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;;;;;;OAYG;IACH,KAAK,CAAC,IAAI;QACR,MAAM,MAAM,GAA4B,EAAE,CAAC;QAC3C,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;QAC9C,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;QAEpC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YACvD,wBAAwB;YACxB,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACxB,SAAS;YACX,CAAC;YAED,8CAA8C;YAC9C,IAAI,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;gBACxB,SAAS;YACX,CAAC;YAED,0BAA0B;YAC1B,IAAI,MAAM,EAAE,CAAC;gBACX,IAAI,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;oBAC3B,wBAAwB;oBACxB,MAAM,WAAW,GAAG,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;oBAC7C,0DAA0D;oBAC1D,IAAI,WAAW,EAAE,CAAC;wBAChB,MAAM,CAAC,WAAW,CAAC,GAAG,KAAK,CAAC;oBAC9B,CAAC;gBACH,CAAC;gBACD,wCAAwC;YAC1C,CAAC;iBAAM,CAAC;gBACN,4CAA4C;gBAC5C,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;YACtB,CAAC;QACH,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;CACF;AAhED,8CAgEC"}
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SSMParameterStoreLoader = exports.SecretsManagerLoader = exports.S3Loader = exports.EnvFileLoader = exports.EnvironmentLoader = void 0;
4
+ var environment_loader_1 = require("./environment.loader");
5
+ Object.defineProperty(exports, "EnvironmentLoader", { enumerable: true, get: function () { return environment_loader_1.EnvironmentLoader; } });
6
+ var env_file_loader_1 = require("./env-file.loader");
7
+ Object.defineProperty(exports, "EnvFileLoader", { enumerable: true, get: function () { return env_file_loader_1.EnvFileLoader; } });
8
+ var s3_loader_1 = require("./s3.loader");
9
+ Object.defineProperty(exports, "S3Loader", { enumerable: true, get: function () { return s3_loader_1.S3Loader; } });
10
+ var secrets_manager_loader_1 = require("./secrets-manager.loader");
11
+ Object.defineProperty(exports, "SecretsManagerLoader", { enumerable: true, get: function () { return secrets_manager_loader_1.SecretsManagerLoader; } });
12
+ var ssm_parameter_store_loader_1 = require("./ssm-parameter-store.loader");
13
+ Object.defineProperty(exports, "SSMParameterStoreLoader", { enumerable: true, get: function () { return ssm_parameter_store_loader_1.SSMParameterStoreLoader; } });
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/loaders/index.ts"],"names":[],"mappings":";;;AAAA,2DAAyD;AAAhD,uHAAA,iBAAiB,OAAA;AAC1B,qDAAkD;AAAzC,gHAAA,aAAa,OAAA;AACtB,yCAAuC;AAA9B,qGAAA,QAAQ,OAAA;AACjB,mEAAgE;AAAvD,8HAAA,oBAAoB,OAAA;AAC7B,2EAAuE;AAA9D,qIAAA,uBAAuB,OAAA"}
@@ -0,0 +1,141 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.S3Loader = void 0;
4
+ const client_s3_1 = require("@aws-sdk/client-s3");
5
+ const credential_providers_1 = require("@aws-sdk/credential-providers");
6
+ const env_file_parser_util_1 = require("../utils/env-file-parser.util");
7
+ const errors_1 = require("../errors");
8
+ /**
9
+ * Loader that reads configuration from S3 buckets.
10
+ * Supports JSON and .env file formats with auto-detection.
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * // Load JSON config from S3
15
+ * const loader = new S3Loader({
16
+ * bucket: 'my-config-bucket',
17
+ * key: 'config/app.json',
18
+ * format: 'json'
19
+ * });
20
+ *
21
+ * // Load .env file from S3 with auto-detection
22
+ * const loader = new S3Loader({
23
+ * bucket: 'my-config-bucket',
24
+ * key: 'config/.env'
25
+ * });
26
+ * ```
27
+ *
28
+ * @see https://docs.aws.amazon.com/AmazonECS/latest/developerguide/use-environment-file.html
29
+ */
30
+ class S3Loader {
31
+ constructor(config) {
32
+ this._config = {
33
+ bucket: config.bucket,
34
+ key: config.key,
35
+ region: config.region || process.env['AWS_REGION'] || 'us-east-1',
36
+ format: config.format || 'auto',
37
+ };
38
+ this._client = new client_s3_1.S3Client({
39
+ credentials: (0, credential_providers_1.fromNodeProviderChain)(),
40
+ region: this._config.region,
41
+ });
42
+ }
43
+ getName() {
44
+ return `S3Loader(s3://${this._config.bucket}/${this._config.key})`;
45
+ }
46
+ /**
47
+ * Check if this loader is available by verifying AWS credentials.
48
+ * @returns Promise resolving to true if AWS credentials are available
49
+ */
50
+ async isAvailable() {
51
+ try {
52
+ await this._client.config.credentials();
53
+ return true;
54
+ }
55
+ catch {
56
+ return false;
57
+ }
58
+ }
59
+ /**
60
+ * Load configuration from S3.
61
+ * @returns Promise resolving to configuration key-value pairs
62
+ * @throws AWSServiceError if S3 operation fails
63
+ * @throws ConfigurationLoadError if content cannot be parsed
64
+ */
65
+ async load() {
66
+ try {
67
+ const command = new client_s3_1.GetObjectCommand({
68
+ Bucket: this._config.bucket,
69
+ Key: this._config.key,
70
+ });
71
+ const response = await this._client.send(command);
72
+ if (!response.Body) {
73
+ return {};
74
+ }
75
+ const content = await response.Body.transformToString();
76
+ if (!content || content.trim() === '') {
77
+ return {};
78
+ }
79
+ return this.parseContent(content);
80
+ }
81
+ catch (error) {
82
+ if (error instanceof errors_1.ConfigurationLoadError) {
83
+ throw error;
84
+ }
85
+ if (error instanceof Error) {
86
+ if (error.name === 'NoSuchKey' || error.name === 'NoSuchBucket') {
87
+ // Object or bucket doesn't exist - return empty config
88
+ return {};
89
+ }
90
+ if (error.name === 'AccessDenied') {
91
+ throw new errors_1.AWSServiceError(`Access denied when retrieving s3://${this._config.bucket}/${this._config.key}. Check AWS credentials and permissions.`, 'S3', 'GetObject', error);
92
+ }
93
+ }
94
+ throw new errors_1.AWSServiceError(`Failed to retrieve s3://${this._config.bucket}/${this._config.key}: ${error instanceof Error ? error.message : String(error)}`, 'S3', 'GetObject', error instanceof Error ? error : undefined);
95
+ }
96
+ }
97
+ /**
98
+ * Parse content based on format setting or auto-detection.
99
+ * @internal
100
+ */
101
+ parseContent(content) {
102
+ const format = this._config.format === 'auto' ? this.detectFormat(content) : this._config.format;
103
+ if (format === 'json') {
104
+ return this.parseJson(content);
105
+ }
106
+ else {
107
+ return env_file_parser_util_1.EnvFileParser.parse(content);
108
+ }
109
+ }
110
+ /**
111
+ * Detect content format based on structure.
112
+ * JSON content starts with '{' after trimming whitespace.
113
+ * @internal
114
+ */
115
+ detectFormat(content) {
116
+ const trimmed = content.trim();
117
+ if (trimmed.startsWith('{')) {
118
+ return 'json';
119
+ }
120
+ return 'env';
121
+ }
122
+ /**
123
+ * Parse JSON content.
124
+ * @internal
125
+ */
126
+ parseJson(content) {
127
+ try {
128
+ const parsed = JSON.parse(content);
129
+ if (typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)) {
130
+ return parsed;
131
+ }
132
+ // If not an object, wrap it
133
+ return { CONFIG_VALUE: parsed };
134
+ }
135
+ catch (error) {
136
+ throw new errors_1.ConfigurationLoadError(`Failed to parse JSON from s3://${this._config.bucket}/${this._config.key}: ${error instanceof Error ? error.message : String(error)}`, this.getName(), error instanceof Error ? error : undefined);
137
+ }
138
+ }
139
+ }
140
+ exports.S3Loader = S3Loader;
141
+ //# sourceMappingURL=s3.loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"s3.loader.js","sourceRoot":"","sources":["../../../src/loaders/s3.loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,156 @@
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_1 = require("../errors");
7
+ /**
8
+ * Loader that reads configuration from AWS Secrets Manager.
9
+ * Supports environment-aware path construction.
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * // Basic usage
14
+ * const loader = new SecretsManagerLoader({
15
+ * secretName: '/my-app/config',
16
+ * region: 'us-east-1'
17
+ * });
18
+ *
19
+ * // With environment mapping
20
+ * const loader = new SecretsManagerLoader({
21
+ * secretName: '/my-app/config',
22
+ * environmentMapping: {
23
+ * development: 'dev',
24
+ * staging: 'stg',
25
+ * production: 'prod'
26
+ * }
27
+ * });
28
+ * ```
29
+ */
30
+ class SecretsManagerLoader {
31
+ constructor(config = {}) {
32
+ this._appEnv = process.env['APP_ENV'] || process.env['NODE_ENV'] || 'local';
33
+ // Set default configuration
34
+ this._config = {
35
+ secretName: config.secretName || '/nestjs-config-aws',
36
+ region: config.region || process.env['AWS_REGION'] || 'us-east-1',
37
+ environmentMapping: config.environmentMapping || {
38
+ development: 'dev',
39
+ test: 'test',
40
+ production: 'production',
41
+ },
42
+ };
43
+ // Initialize AWS Secrets Manager client
44
+ this._client = new client_secrets_manager_1.SecretsManagerClient({
45
+ credentials: (0, credential_providers_1.fromNodeProviderChain)(),
46
+ region: this._config.region,
47
+ });
48
+ }
49
+ /**
50
+ * Get the name of this loader for logging and debugging.
51
+ * @returns The loader name with secret path
52
+ */
53
+ getName() {
54
+ const secretName = this.buildSecretName();
55
+ return `SecretsManagerLoader(${secretName})`;
56
+ }
57
+ /**
58
+ * Check if this loader is available in the current environment.
59
+ * @returns Promise resolving to true if not in local environment and AWS credentials are available
60
+ */
61
+ async isAvailable() {
62
+ // Skip in local environment
63
+ if (this._appEnv === 'local') {
64
+ return false;
65
+ }
66
+ try {
67
+ // Test AWS credentials by attempting to get caller identity
68
+ await this._client.config.credentials();
69
+ return true;
70
+ }
71
+ catch {
72
+ return false;
73
+ }
74
+ }
75
+ /**
76
+ * Load configuration from AWS Secrets Manager.
77
+ * @returns Promise resolving to configuration key-value pairs from the secret
78
+ * @throws AWSServiceError if AWS operation fails
79
+ * @throws ConfigurationLoadError if secret cannot be parsed
80
+ */
81
+ async load() {
82
+ // Skip loading in local environment
83
+ if (this._appEnv === 'local') {
84
+ return {};
85
+ }
86
+ const secretName = this.buildSecretName();
87
+ try {
88
+ const command = new client_secrets_manager_1.GetSecretValueCommand({ SecretId: secretName });
89
+ const response = await this._client.send(command);
90
+ if (!response.SecretString) {
91
+ return {};
92
+ }
93
+ // Try to parse as JSON, fallback to string value
94
+ try {
95
+ const parsed = JSON.parse(response.SecretString);
96
+ // Ensure we return an object for configuration merging
97
+ if (typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)) {
98
+ return parsed;
99
+ }
100
+ else {
101
+ // If it's not an object, wrap it in a configuration object
102
+ return { SECRET_VALUE: parsed };
103
+ }
104
+ }
105
+ catch {
106
+ // If JSON parsing fails, treat as a single string value
107
+ return { SECRET_VALUE: response.SecretString };
108
+ }
109
+ }
110
+ catch (error) {
111
+ // Handle specific AWS errors
112
+ if (error instanceof Error) {
113
+ if (error.name === 'ResourceNotFoundException') {
114
+ // Secret doesn't exist - this is not necessarily an error in all environments
115
+ return {};
116
+ }
117
+ if (error.name === 'AccessDeniedException') {
118
+ throw new errors_1.AWSServiceError(`Access denied when retrieving secret '${secretName}'. Check AWS credentials and permissions.`, 'SecretsManager', 'GetSecretValue', error);
119
+ }
120
+ if (error.name === 'InvalidRequestException') {
121
+ throw new errors_1.AWSServiceError(`Invalid request when retrieving secret '${secretName}'. Check secret name format.`, 'SecretsManager', 'GetSecretValue', error);
122
+ }
123
+ }
124
+ // For other errors, wrap in AWSServiceError
125
+ throw new errors_1.AWSServiceError(`Failed to retrieve secret '${secretName}' from AWS Secrets Manager: ${error instanceof Error ? error.message : String(error)}`, 'SecretsManager', 'GetSecretValue', error instanceof Error ? error : undefined);
126
+ }
127
+ }
128
+ /**
129
+ * Build the environment-aware secret name/path.
130
+ * @returns The full secret name with environment prefix
131
+ */
132
+ buildSecretName() {
133
+ const envPrefix = this._config.environmentMapping[this._appEnv];
134
+ if (!envPrefix) {
135
+ throw new errors_1.ConfigurationLoadError(`No environment mapping found for APP_ENV '${this._appEnv}'. ` +
136
+ `Available environments: ${Object.keys(this._config.environmentMapping).join(', ')}`, this.getName());
137
+ }
138
+ return `/${envPrefix}${this._config.secretName}`;
139
+ }
140
+ /**
141
+ * Get the current app environment.
142
+ * @returns The current APP_ENV or NODE_ENV value
143
+ */
144
+ getAppEnv() {
145
+ return this._appEnv;
146
+ }
147
+ /**
148
+ * Get the environment mapping configuration.
149
+ * @returns The environment mapping record
150
+ */
151
+ getEnvironmentMapping() {
152
+ return { ...this._config.environmentMapping };
153
+ }
154
+ }
155
+ exports.SecretsManagerLoader = SecretsManagerLoader;
156
+ //# sourceMappingURL=secrets-manager.loader.js.map