@node-in-layers/aws 1.1.4 → 2.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.
package/README.md CHANGED
@@ -36,64 +36,63 @@ const awsConfig = {
36
36
 
37
37
  ## Config
38
38
 
39
- The config app provides the ability to have configurations inside a config file that use values from Parameter store and Secrets manager. In order to do this, the config app provides a globals file, that will take your configuration object, see if there are parameter store and secrets manager objects in it. If there are, it will reach out to each of those services to find and the replace them within the config.
39
+ Provides a Secret Service for the `@node-in-layers/secrets` package.
40
+ This creates the ability for configurations to have paths for parameter store and secrets manager, that are then populated at runtime.
40
41
 
41
42
  ### How To Use
42
43
 
43
- Within the apps of your system's configuration:
44
+ ### Setup With `@node-in-layers/secrets`
44
45
 
45
- ```javascript
46
- import { CoreNamespace } from '@node-in-layers/core/index.js'
46
+ This package can be used as the `secretServiceFactory` for `@node-in-layers/secrets`.
47
47
 
48
- const core = {
49
- apps: await Promise.all([
50
- // Adds support for aws config files.
51
- import('@node-in-layers/aws/config/index.js'),
52
- ]),
53
- layerOrder: ['services', 'features', 'express'],
54
- logLevel: 'debug',
55
- logFormat: 'full',
56
- }
48
+ Example system config:
57
49
 
58
- export default () => ({
50
+ ```typescript
51
+ import { CoreNamespace } from '@node-in-layers/core'
52
+ import {
53
+ config as secretsConfig,
54
+ SecretsNamespace,
55
+ } from '@node-in-layers/secrets'
56
+ import { secretsService, AwsNamespace, AwsService } from '@node-in-layers/aws'
57
+
58
+ export default async () => ({
59
59
  systemName: 'my-example-system',
60
60
  environment: 'dev',
61
- [CoreNamespace.root]: core,
62
- })
63
- ```
64
61
 
65
- ### Example Config
66
-
67
- ```json
68
- {
69
- "myApp": {
70
- "myClient": {
71
- "url": "https://some-url",
72
- "key": {
73
- "type": "secretsManager",
74
- "key": "/path/with-in/secrets-manager"
75
- }
76
- },
77
- "aDynamicAwsPath": {
78
- "type": "parameterStore",
79
- "key": "/path/with-in/parameter-store"
80
- }
81
- }
82
- }
83
- ```
62
+ // Used by the AWS secrets adapter to create AWS SDK clients
63
+ [AwsNamespace.root]: {
64
+ awsClientProps: { region: 'us-east-1' },
65
+ services: [AwsService.secretsManager, AwsService.ssm],
66
+ },
84
67
 
85
- Gets turned into...
68
+ [CoreNamespace.root]: {
69
+ apps: [
70
+ secretsConfig,
71
+ // your domains...
72
+ ],
73
+ layerOrder: ['services', 'features', 'express'],
74
+ },
75
+
76
+ [SecretsNamespace.Core]: {
77
+ secretServiceFactory: secretsService,
78
+ },
86
79
 
87
- ```json
88
- {
89
- "myApp": {
90
- "myClient": {
91
- "url": "https://some-url",
92
- "key": "the-value-from-secrets-manager"
80
+ // Example configurations, to be replaced
81
+ myApp: {
82
+ myClient: {
83
+ key: {
84
+ type: 'nil-secret',
85
+ //awsService: "secretsManager", // don't need to put this, but can be helpful for making explicit.
86
+ format: 'string',
87
+ key: '/path/with-in/secrets-manager',
88
+ },
93
89
  },
94
- "aDynamicAwsPath": "the-value-from-parameter-store"
95
- }
96
- }
90
+ aDynamicAwsPath: {
91
+ type: 'nil-secret',
92
+ awsService: 'parameterStore',
93
+ format: 'string',
94
+ key: '/path/with-in/parameter-store',
95
+ },
96
+ },
97
+ })
97
98
  ```
98
-
99
- search parameter store and secrets
package/aws/services.js CHANGED
@@ -15,7 +15,7 @@ const _awsServiceToBuilder = {
15
15
  s3: Object.assign({ s3Client: new s3.S3Client(awsConfig) }, s3),
16
16
  }),
17
17
  [AwsService.ecs]: awsConfig => ({
18
- ecs: Object.assign({ ecsClient: new ecs.ECSClient(awsConfig) }, ssm),
18
+ ecs: Object.assign({ ecsClient: new ecs.ECSClient(awsConfig) }, ecs),
19
19
  }),
20
20
  [AwsService.ssm]: awsConfig => ({
21
21
  ssm: Object.assign({ ssmClient: new ssm.SSMClient(awsConfig) }, ssm),
package/config/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
- export * as globals from './globals.js';
2
- declare const name = "@node-in-layers/aws-config";
3
- export { name };
1
+ import { AwsNamespace } from '../types.js';
2
+ export * as services from './services.js';
3
+ export * from './types.js';
4
+ export declare const name = AwsNamespace.config;
package/config/index.js CHANGED
@@ -1,4 +1,5 @@
1
- export * as globals from './globals.js';
2
- const name = '@node-in-layers/aws-config';
3
- export { name };
1
+ import { AwsNamespace } from '../types.js';
2
+ export * as services from './services.js';
3
+ export * from './types.js';
4
+ export const name = AwsNamespace.config;
4
5
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AAEvC,MAAM,IAAI,GAAG,4BAA4B,CAAA;AACzC,OAAO,EAAE,IAAI,EAAE,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE1C,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AACzC,cAAc,YAAY,CAAA;AAE1B,MAAM,CAAC,MAAM,IAAI,GAAG,YAAY,CAAC,MAAM,CAAA"}
@@ -1,4 +1,13 @@
1
- import { ServicesContext } from '@node-in-layers/core/index.js';
2
- import { AwsConfigServices } from './types.js';
3
- declare const create: (context: ServicesContext) => AwsConfigServices;
4
- export { create };
1
+ import { ServicesContext } from '@node-in-layers/core';
2
+ import type { Aws3Config, AwsServicesLayer } from '../types.js';
3
+ import type { AwsConfigSecretsService, AwsConfigServices } from './types.js';
4
+ /**
5
+ * Builds the secrets backend from config alone (for `secretServiceFactory` / globals where
6
+ * full `ServicesContext` is not available).
7
+ */
8
+ declare const createAwsConfigSecretsService: (context: ServicesContext<Aws3Config, AwsServicesLayer>) => AwsConfigSecretsService;
9
+ /**
10
+ * AWS config domain services factory (Node In Layers `services` layer).
11
+ */
12
+ declare const create: (context: ServicesContext<Aws3Config, AwsServicesLayer>) => AwsConfigServices;
13
+ export { create, createAwsConfigSecretsService };
@@ -7,44 +7,66 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
- import merge from 'lodash/merge.js';
11
- import { asyncMap } from 'modern-async';
12
- import { AwsNamespace } from '../types.js';
13
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
14
- const create = (context) => {
15
- const readSecretsInSecretsManager = (keys) => __awaiter(void 0, void 0, void 0, function* () {
16
- const secretsManager = context.services[AwsNamespace.root].aws3.secretsManager
17
- .secretsManagerClient;
18
- const mapped = yield asyncMap(keys, (secretId) => __awaiter(void 0, void 0, void 0, function* () {
19
- const command = new context.services[AwsNamespace.root].aws3.secretsManager.GetSecretValueCommand({
20
- SecretId: secretId,
21
- });
22
- const result = yield secretsManager.send(command);
23
- return [secretId, result.SecretString];
24
- }), 1);
25
- return mapped.reduce((acc, [key, secret]) => {
26
- return merge(acc, { [key]: secret });
27
- }, {});
28
- });
29
- const readParameters = (keys) => __awaiter(void 0, void 0, void 0, function* () {
10
+ import { AwsNamespace, AwsSecretHydrationService } from '../types.js';
11
+ const _isHydrationService = (value) => value === AwsSecretHydrationService.SecretsManager ||
12
+ value === AwsSecretHydrationService.ParameterStore;
13
+ /**
14
+ * Builds the secrets backend from config alone (for `secretServiceFactory` / globals where
15
+ * full `ServicesContext` is not available).
16
+ */
17
+ const createAwsConfigSecretsService = (context) => {
18
+ const aws3 = context.services[AwsNamespace.root].aws3;
19
+ if (aws3.secretsManager === undefined) {
20
+ throw new Error('@node-in-layers/aws/config: secretsManager client is not available for secrets hydration.');
21
+ }
22
+ if (aws3.ssm === undefined) {
23
+ throw new Error('@node-in-layers/aws/config: ssm client is not available for secrets hydration.');
24
+ }
25
+ const secretsManager = aws3.secretsManager;
26
+ const ssm = aws3.ssm;
27
+ const getStoredSecret = (props) => __awaiter(void 0, void 0, void 0, function* () {
30
28
  return Promise.resolve().then(() => __awaiter(void 0, void 0, void 0, function* () {
31
- const ssm = context.services[AwsNamespace.root].aws3.ssm.ssmClient;
32
- const mapped = yield asyncMap(keys, (key) => __awaiter(void 0, void 0, void 0, function* () {
33
- const command = new context.services[AwsNamespace.root].aws3.ssm.GetParameterCommand({
34
- Name: key,
35
- });
36
- const result = yield ssm.send(command);
37
- return [key, result.Parameter.Value];
38
- }), 1);
39
- return mapped.reduce((acc, [key, secret]) => {
40
- return merge(acc, { [key]: secret });
41
- }, {});
29
+ var _a;
30
+ const { key } = props;
31
+ const rawService = props.awsService || AwsSecretHydrationService.SecretsManager;
32
+ const svc = _isHydrationService(rawService)
33
+ ? rawService
34
+ : rawService === undefined
35
+ ? AwsSecretHydrationService.SecretsManager
36
+ : undefined;
37
+ if (svc === AwsSecretHydrationService.ParameterStore) {
38
+ const result = yield ssm.ssmClient.send(new ssm.GetParameterCommand({ Name: key, WithDecryption: true }));
39
+ if (((_a = result.Parameter) === null || _a === void 0 ? void 0 : _a.Value) === undefined) {
40
+ throw new Error(`AWS SSM GetParameter returned no value for Name: ${key}`);
41
+ }
42
+ return result.Parameter.Value;
43
+ }
44
+ if (svc === AwsSecretHydrationService.SecretsManager) {
45
+ const result = yield secretsManager.secretsManagerClient.send(new secretsManager.GetSecretValueCommand({ SecretId: key }));
46
+ if (result.SecretString === undefined) {
47
+ throw new Error(`AWS Secrets Manager returned no SecretString for SecretId: ${key}`);
48
+ }
49
+ return result.SecretString;
50
+ }
51
+ /* c8 ignore start */
52
+ throw new Error(`Unsupported awsService for @node-in-layers/aws secrets hydration: ${String(rawService)}`);
53
+ /* c8 ignore stop */
42
54
  }));
43
55
  });
44
56
  return {
45
- readSecretsInSecretsManager,
46
- readParameters,
57
+ getStoredSecret,
58
+ storeSecret: () => __awaiter(void 0, void 0, void 0, function* () {
59
+ throw new Error('@node-in-layers/aws/config: storeSecret is not implemented');
60
+ }),
61
+ };
62
+ };
63
+ /**
64
+ * AWS config domain services factory (Node In Layers `services` layer).
65
+ */
66
+ const create = (context) => {
67
+ return {
68
+ createSecretsService: () => createAwsConfigSecretsService(context),
47
69
  };
48
70
  };
49
- export { create };
71
+ export { create, createAwsConfigSecretsService };
50
72
  //# sourceMappingURL=services.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"services.js","sourceRoot":"","sources":["../../src/config/services.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,KAAK,MAAM,iBAAiB,CAAA;AACnC,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAEvC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAG1C,6DAA6D;AAC7D,MAAM,MAAM,GAAG,CAAC,OAAwB,EAAqB,EAAE;IAC7D,MAAM,2BAA2B,GAAG,CAAO,IAAc,EAAE,EAAE;QAC3D,MAAM,cAAc,GAClB,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,cAAc;aACpD,oBAAoB,CAAA;QACzB,MAAM,MAAM,GAAG,MAAM,QAAQ,CAC3B,IAAI,EACJ,CAAM,QAAQ,EAAC,EAAE;YACf,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,QAAQ,CAClC,YAAY,CAAC,IAAI,CAClB,CAAC,IAAI,CAAC,cAAc,CAAC,qBAAqB,CAAC;gBAC1C,QAAQ,EAAE,QAAQ;aACnB,CAAC,CAAA;YACF,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;YACjD,OAAO,CAAC,QAAQ,EAAE,MAAM,CAAC,YAAY,CAAC,CAAA;QACxC,CAAC,CAAA,EACD,CAAC,CACF,CAAA;QACD,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,EAAE;YAC1C,OAAO,KAAK,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC,CAAA;QACtC,CAAC,EAAE,EAAE,CAAC,CAAA;IACR,CAAC,CAAA,CAAA;IAED,MAAM,cAAc,GAAG,CAAO,IAAc,EAAE,EAAE;QAC9C,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,GAAS,EAAE;YACvC,MAAM,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAA;YAClE,MAAM,MAAM,GAAG,MAAM,QAAQ,CAC3B,IAAI,EACJ,CAAM,GAAG,EAAC,EAAE;gBACV,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,QAAQ,CAClC,YAAY,CAAC,IAAI,CAClB,CAAC,IAAI,CAAC,GAAG,CAAC,mBAAmB,CAAC;oBAC7B,IAAI,EAAE,GAAG;iBACV,CAAC,CAAA;gBACF,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;gBACtC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;YACtC,CAAC,CAAA,EACD,CAAC,CACF,CAAA;YACD,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,EAAE;gBAC1C,OAAO,KAAK,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC,CAAA;YACtC,CAAC,EAAE,EAAE,CAAC,CAAA;QACR,CAAC,CAAA,CAAC,CAAA;IACJ,CAAC,CAAA,CAAA;IAED,OAAO;QACL,2BAA2B;QAC3B,cAAc;KACf,CAAA;AACH,CAAC,CAAA;AACD,OAAO,EAAE,MAAM,EAAE,CAAA"}
1
+ {"version":3,"file":"services.js","sourceRoot":"","sources":["../../src/config/services.ts"],"names":[],"mappings":"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"}
package/config/types.d.ts CHANGED
@@ -1,43 +1,37 @@
1
- import { AwsNamespace } from '../types.js';
2
- type AwsConfigServices = Readonly<{
3
- readSecretsInSecretsManager: (keys: string[]) => Promise<Record<string, string>>;
4
- readParameters: (keys: string[]) => Promise<Record<string, string>>;
5
- }>;
6
- type AwsConfigServicesLayer = Readonly<{
7
- [AwsNamespace.config]: AwsConfigServices;
8
- }>;
9
- type AwsConfigFeatures = Readonly<object>;
10
- type AwsConfigFeaturesLayer = Readonly<{
11
- [AwsNamespace.config]: AwsConfigFeatures;
12
- }>;
13
- /**
14
- * The key that defines an aws entry
15
- */
16
- declare const AwsEntryKey = "type";
1
+ import type { ServicesContext } from '@node-in-layers/core';
2
+ import type { Aws3Config, AwsGetStoredSecretProps, AwsNamespace, AwsServicesLayer } from '../types.js';
17
3
  /**
18
- * The type of supported aws entries in a config.
4
+ * Backend returned for `@node-in-layers/secrets` nil-secret hydration (AWS Secrets Manager / SSM).
5
+ * Matches the string surface of `SecretsService` from `@node-in-layers/secrets` for `getStoredSecret` props
6
+ * (including optional `awsService`).
19
7
  */
20
- declare enum AwsEntryType {
21
- secretsManager = "secretsManager",
22
- parameterStore = "parameterStore"
23
- }
24
- /**
25
- * An AWS entry that has not been replaced yet.
26
- */
27
- type PartialAwsEntry<T extends AwsEntryType> = Readonly<{
28
- type: T;
8
+ export type AwsConfigSecretsService = Readonly<{
9
+ getStoredSecret: (props: AwsGetStoredSecretProps) => Promise<string>;
10
+ storeSecret: (props: AwsConfigStoreSecretProps) => Promise<void>;
11
+ }>;
12
+ export type AwsConfigStoreSecretProps = Readonly<{
29
13
  key: string;
14
+ value: string;
30
15
  }>;
31
16
  /**
32
- * An object that holds multiple Aws entries to replace.
17
+ * AWS config domain services: nil-secret hydration and related helpers.
18
+ * @interface
33
19
  */
34
- type AwsEntriesToReplace<T extends AwsEntryType> = Readonly<Record<string, PartialAwsEntry<T>>>;
20
+ export type AwsConfigServices = Readonly<{
21
+ /**
22
+ * Builds a secrets backend for config hydration (`secretServiceFactory` uses this shape).
23
+ */
24
+ createSecretsService: () => AwsConfigSecretsService;
25
+ }>;
35
26
  /**
36
- * All the secrets manager entries to replace
27
+ * Layer shape: `context.services[AwsNamespace.config]`.
28
+ * @interface
37
29
  */
38
- type SecretsToReplace = AwsEntriesToReplace<AwsEntryType.secretsManager>;
30
+ export type AwsConfigServicesLayer = Readonly<{
31
+ [AwsNamespace.config]: AwsConfigServices;
32
+ }>;
39
33
  /**
40
- * All the parameter store entries to replace
34
+ * Context for the AWS config services factory (loads after root AWS services).
35
+ * @interface
41
36
  */
42
- type ParameterStoreToReplace = AwsEntriesToReplace<AwsEntryType.parameterStore>;
43
- export { AwsConfigServices, AwsConfigServicesLayer, AwsConfigFeatures, AwsConfigFeaturesLayer, AwsEntriesToReplace, AwsEntryKey, AwsEntryType, ParameterStoreToReplace, SecretsToReplace, };
37
+ export type AwsConfigServicesContext = ServicesContext<Aws3Config, AwsServicesLayer>;
package/config/types.js CHANGED
@@ -1,15 +1,2 @@
1
- import { AwsNamespace } from '../types.js';
2
- /**
3
- * The key that defines an aws entry
4
- */
5
- const AwsEntryKey = 'type';
6
- /**
7
- * The type of supported aws entries in a config.
8
- */
9
- var AwsEntryType;
10
- (function (AwsEntryType) {
11
- AwsEntryType["secretsManager"] = "secretsManager";
12
- AwsEntryType["parameterStore"] = "parameterStore";
13
- })(AwsEntryType || (AwsEntryType = {}));
14
- export { AwsEntryKey, AwsEntryType, };
1
+ export {};
15
2
  //# sourceMappingURL=types.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/config/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAmB1C;;GAEG;AACH,MAAM,WAAW,GAAG,MAAM,CAAA;AAE1B;;GAEG;AACH,IAAK,YAGJ;AAHD,WAAK,YAAY;IACf,iDAAiC,CAAA;IACjC,iDAAiC,CAAA;AACnC,CAAC,EAHI,YAAY,KAAZ,YAAY,QAGhB;AA2BD,OAAO,EAML,WAAW,EACX,YAAY,GAGb,CAAA"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/config/types.ts"],"names":[],"mappings":""}
package/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export * from './types.js';
2
2
  export * from './config/types.js';
3
+ export { secretsService } from './secretsService.js';
3
4
  export * from './aws/index.js';
4
5
  export * as aws from './aws/index.js';
5
6
  export * as config from './config/index.js';
package/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  // Export Types
2
2
  export * from './types.js';
3
3
  export * from './config/types.js';
4
+ export { secretsService } from './secretsService.js';
4
5
  // Export default domain
5
6
  export * from './aws/index.js';
6
7
  // Export named domains
package/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,eAAe;AACf,cAAc,YAAY,CAAA;AAC1B,cAAc,mBAAmB,CAAA;AAEjC,wBAAwB;AACxB,cAAc,gBAAgB,CAAA;AAE9B,uBAAuB;AACvB,OAAO,KAAK,GAAG,MAAM,gBAAgB,CAAA;AACrC,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,eAAe;AACf,cAAc,YAAY,CAAA;AAC1B,cAAc,mBAAmB,CAAA;AAEjC,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAEpD,wBAAwB;AACxB,cAAc,gBAAgB,CAAA;AAE9B,uBAAuB;AACvB,OAAO,KAAK,GAAG,MAAM,gBAAgB,CAAA;AACrC,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAA"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@node-in-layers/aws",
3
3
  "type": "module",
4
- "version": "1.1.4",
4
+ "version": "2.0.0",
5
5
  "description": "A Node In Layers Package for handling AWS.",
6
6
  "main": "index.js",
7
7
  "scripts": {
@@ -48,11 +48,23 @@
48
48
  },
49
49
  "author": "Mike Cornwell",
50
50
  "license": "GPLV3",
51
+ "overrides": {
52
+ "fast-xml-parser": ">=5.3.6",
53
+ "external-editor": {
54
+ "tmp": ">=0.2.4"
55
+ },
56
+ "commitizen": {
57
+ "lodash": ">=4.17.23"
58
+ },
59
+ "mocha": {
60
+ "diff": ">=8.0.3"
61
+ }
62
+ },
51
63
  "devDependencies": {
52
64
  "@cucumber/cucumber": "^12.6.0",
53
- "@eslint/compat": "^1.2.0",
54
- "@eslint/eslintrc": "^3.1.0",
55
- "@eslint/js": "^9.12.0",
65
+ "@eslint/compat": "^1.4.1",
66
+ "@eslint/eslintrc": "^3.3.3",
67
+ "@eslint/js": "^9.39.2",
56
68
  "@types/chai-as-promised": "^8.0.1",
57
69
  "@types/json-stringify-safe": "^5.0.3",
58
70
  "@types/lodash": "^4.17.13",
@@ -60,44 +72,47 @@
60
72
  "@types/node": "^22.9.0",
61
73
  "@types/proxyquire": "^1.3.31",
62
74
  "@types/sinon": "^17.0.3",
63
- "@typescript-eslint/eslint-plugin": "8.13.0",
64
- "@typescript-eslint/parser": "8.13.0",
75
+ "@typescript-eslint/eslint-plugin": "^8.56.0",
76
+ "@typescript-eslint/parser": "^8.56.0",
65
77
  "argparse": "^2.0.1",
78
+ "aws-sdk-client-mock": "^4.1.0",
66
79
  "c8": "^10.1.3",
67
80
  "chai": "^4.2.0",
68
81
  "chai-as-promised": "^7.1.1",
69
82
  "cz-conventional-changelog": "^3.3.0",
70
- "eslint": "9.14.0",
71
- "eslint-config-prettier": "^9.1.0",
72
- "eslint-import-resolver-typescript": "^3.6.3",
73
- "eslint-plugin-functional": "~7.1.0",
74
- "eslint-plugin-import": "^2.31.0",
83
+ "eslint": "^9.39.2",
84
+ "eslint-config-prettier": "^10.1.8",
85
+ "eslint-import-resolver-typescript": "^4.4.4",
86
+ "eslint-plugin-functional": "^9.0.2",
87
+ "eslint-plugin-import": "^2.32.0",
75
88
  "esprima": "^4.0.1",
76
89
  "globals": "^15.12.0",
77
90
  "handlebars": "^4.7.8",
91
+ "inquirer": "^13.2.5",
78
92
  "js-yaml": "^4.1.0",
79
93
  "mocha": "^11.0.1",
80
94
  "nodemon": "^3.1.7",
81
95
  "prettier": "^3.3.3",
82
96
  "proxyquire": "^2.1.3",
83
- "sinon": "^19.0.2",
97
+ "sinon": "^21.0.1",
84
98
  "sinon-chai": "^3.5.0",
85
99
  "source-map-support": "^0.5.21",
100
+ "tmp": "^0.2.5",
86
101
  "ts-mocha": "^11.1.0",
87
102
  "ts-node": "^10.9.2",
88
103
  "tsx": "^4.19.3",
89
104
  "typescript": "5.3.3"
90
105
  },
91
106
  "dependencies": {
92
- "@aws-sdk/client-dynamodb": "^3.758.0",
93
- "@aws-sdk/client-ecs": "^3.758.0",
94
- "@aws-sdk/client-s3": "^3.758.0",
95
- "@aws-sdk/client-secrets-manager": "^3.758.0",
96
- "@aws-sdk/client-sqs": "^3.758.0",
97
- "@aws-sdk/client-ssm": "^3.759.0",
98
- "@aws-sdk/lib-dynamodb": "^3.758.0",
107
+ "@aws-sdk/client-dynamodb": "^3.992.0",
108
+ "@aws-sdk/client-ecs": "^3.992.0",
109
+ "@aws-sdk/client-s3": "^3.992.0",
110
+ "@aws-sdk/client-secrets-manager": "^3.992.0",
111
+ "@aws-sdk/client-sqs": "^3.992.0",
112
+ "@aws-sdk/client-ssm": "^3.992.0",
113
+ "@aws-sdk/lib-dynamodb": "^3.992.0",
99
114
  "@node-in-layers/core": "^1.12.5",
100
- "lodash": "^4.17.21",
115
+ "lodash": "^4.17.23",
101
116
  "modern-async": "^2.0.4"
102
117
  }
103
118
  }
@@ -0,0 +1,16 @@
1
+ import type { CommonContext } from '@node-in-layers/core';
2
+ import { type Aws3Config } from './types.js';
3
+ /**
4
+ * Thin adapter for `secretServiceFactory` in `@node-in-layers/secrets`.
5
+ */
6
+ declare const secretsService: (context: CommonContext<Aws3Config>) => Readonly<{
7
+ getStoredSecret: (props: Readonly<{
8
+ key: string;
9
+ awsService?: import("./types.js").AwsSecretHydrationService | undefined;
10
+ }>) => Promise<string>;
11
+ storeSecret: (props: Readonly<{
12
+ key: string;
13
+ value: string;
14
+ }>) => Promise<void>;
15
+ }>;
16
+ export { secretsService };
@@ -0,0 +1,18 @@
1
+ import merge from 'lodash/merge.js';
2
+ import { create } from './config/services.js';
3
+ import { create as createAwsService } from './aws/services.js';
4
+ import { AwsNamespace } from './types.js';
5
+ /**
6
+ * Thin adapter for `secretServiceFactory` in `@node-in-layers/secrets`.
7
+ */
8
+ const secretsService = (context) => {
9
+ const awsService = createAwsService(context);
10
+ const merged = merge({}, {
11
+ services: {
12
+ [AwsNamespace.root]: awsService,
13
+ },
14
+ });
15
+ return create(merged).createSecretsService();
16
+ };
17
+ export { secretsService };
18
+ //# sourceMappingURL=secretsService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secretsService.js","sourceRoot":"","sources":["../src/secretsService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,iBAAiB,CAAA;AAGnC,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAC7C,OAAO,EAAE,MAAM,IAAI,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAC9D,OAAO,EAAE,YAAY,EAAqC,MAAM,YAAY,CAAA;AAE5E;;GAEG;AACH,MAAM,cAAc,GAAG,CAAC,OAAkC,EAAE,EAAE;IAC5D,MAAM,UAAU,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAA;IAC5C,MAAM,MAAM,GAAG,KAAK,CAClB,EAAE,EACF;QACE,QAAQ,EAAE;YACR,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,UAAU;SAChC;KACF,CAC+C,CAAA;IAClD,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,oBAAoB,EAAE,CAAA;AAC9C,CAAC,CAAA;AAED,OAAO,EAAE,cAAc,EAAE,CAAA"}
package/types.d.ts CHANGED
@@ -33,6 +33,20 @@ export declare enum AwsService {
33
33
  ecs = "ecs",
34
34
  sqs = "sqs"
35
35
  }
36
+ /**
37
+ * Which AWS API backs a `nil-secret` placeholder when using `secretsService` from this package
38
+ * with `@node-in-layers/secrets` (`awsService` on the placeholder).
39
+ */
40
+ export declare enum AwsSecretHydrationService {
41
+ SecretsManager = "secretsManager",
42
+ ParameterStore = "parameterStore"
43
+ }
44
+ /** Props passed through from nil-secret hydration (minus `type` / `format`). */
45
+ export type AwsGetStoredSecretProps = Readonly<{
46
+ key: string;
47
+ /** When omitted, Secrets Manager is used. */
48
+ awsService?: AwsSecretHydrationService;
49
+ }>;
36
50
  export type AwsServices = Readonly<{
37
51
  aws3: Partial<Aws3>;
38
52
  }>;
package/types.js CHANGED
@@ -12,4 +12,13 @@ export var AwsService;
12
12
  AwsService["ecs"] = "ecs";
13
13
  AwsService["sqs"] = "sqs";
14
14
  })(AwsService || (AwsService = {}));
15
+ /**
16
+ * Which AWS API backs a `nil-secret` placeholder when using `secretsService` from this package
17
+ * with `@node-in-layers/secrets` (`awsService` on the placeholder).
18
+ */
19
+ export var AwsSecretHydrationService;
20
+ (function (AwsSecretHydrationService) {
21
+ AwsSecretHydrationService["SecretsManager"] = "secretsManager";
22
+ AwsSecretHydrationService["ParameterStore"] = "parameterStore";
23
+ })(AwsSecretHydrationService || (AwsSecretHydrationService = {}));
15
24
  //# sourceMappingURL=types.js.map
package/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAyBA,MAAM,CAAN,IAAY,YAGX;AAHD,WAAY,YAAY;IACtB,4CAA4B,CAAA;IAC5B,qDAAqC,CAAA;AACvC,CAAC,EAHW,YAAY,KAAZ,YAAY,QAGvB;AAED,MAAM,CAAN,IAAY,UAOX;AAPD,WAAY,UAAU;IACpB,uBAAS,CAAA;IACT,yBAAW,CAAA;IACX,+CAAiC,CAAA;IACjC,mCAAqB,CAAA;IACrB,yBAAW,CAAA;IACX,yBAAW,CAAA;AACb,CAAC,EAPW,UAAU,KAAV,UAAU,QAOrB"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAyBA,MAAM,CAAN,IAAY,YAGX;AAHD,WAAY,YAAY;IACtB,4CAA4B,CAAA;IAC5B,qDAAqC,CAAA;AACvC,CAAC,EAHW,YAAY,KAAZ,YAAY,QAGvB;AAED,MAAM,CAAN,IAAY,UAOX;AAPD,WAAY,UAAU;IACpB,uBAAS,CAAA;IACT,yBAAW,CAAA;IACX,+CAAiC,CAAA;IACjC,mCAAqB,CAAA;IACrB,yBAAW,CAAA;IACX,yBAAW,CAAA;AACb,CAAC,EAPW,UAAU,KAAV,UAAU,QAOrB;AAED;;;GAGG;AACH,MAAM,CAAN,IAAY,yBAGX;AAHD,WAAY,yBAAyB;IACnC,8DAAiC,CAAA;IACjC,8DAAiC,CAAA;AACnC,CAAC,EAHW,yBAAyB,KAAzB,yBAAyB,QAGpC"}
@@ -1,200 +0,0 @@
1
- import { Config, FeaturesContext } from '@node-in-layers/core/index.js';
2
- import { AwsConfigServicesLayer, AwsConfigFeaturesLayer } from './types.js';
3
- declare const create: (context: FeaturesContext<Config, AwsConfigServicesLayer, AwsConfigFeaturesLayer>) => {
4
- replaceAwsConfigObjects: <TConfig extends Readonly<{
5
- systemName: string;
6
- environment: string;
7
- "@node-in-layers/core": Readonly<{
8
- logging: {
9
- logLevel: import("@node-in-layers/core/types.js").LogLevelNames;
10
- logFormat: import("@node-in-layers/core/types.js").LogFormat | readonly import("@node-in-layers/core/types.js").LogFormat[];
11
- maxLogSizeInCharacters?: number | undefined;
12
- tcpLoggingOptions?: Readonly<{
13
- url: string;
14
- headers?: Record<string, string | object> | undefined;
15
- }> | undefined;
16
- customLogger?: Readonly<{
17
- getLogger: (context: Readonly<{
18
- config: Readonly<any>;
19
- rootLogger: Readonly<any>;
20
- constants: {
21
- environment: string;
22
- workingDirectory: string;
23
- runtimeId: string;
24
- };
25
- }>, props?: {
26
- ids?: readonly Readonly<Record<string, string>>[] | undefined;
27
- data?: Record<string, any> | undefined;
28
- } | undefined) => import("@node-in-layers/core/types.js").HighLevelLogger;
29
- }> | undefined;
30
- getFunctionWrapLogLevel?: ((layerName: string, functionName?: string | undefined) => import("@node-in-layers/core/types.js").LogLevelNames) | undefined;
31
- ignoreLayerFunctions?: Record<string, boolean | Record<string, boolean | Record<string, boolean>>> | undefined;
32
- };
33
- layerOrder: readonly import("@node-in-layers/core/types.js").LayerDescription[];
34
- apps: readonly Readonly<{
35
- name: string;
36
- description?: string | undefined;
37
- services?: Readonly<{
38
- create: (context: any) => import("@node-in-layers/core/types.js").MaybePromise<object>;
39
- }> | undefined;
40
- features?: Readonly<{
41
- create: (context: any) => import("@node-in-layers/core/types.js").MaybePromise<object>;
42
- }> | undefined;
43
- globals?: Readonly<{
44
- create: (context: Readonly<{
45
- config: Readonly<any>;
46
- rootLogger: Readonly<{
47
- getLogger: (context: Readonly<{
48
- config: Readonly<any>;
49
- rootLogger: Readonly<any>;
50
- constants: {
51
- environment: string;
52
- workingDirectory: string;
53
- runtimeId: string;
54
- };
55
- }>, props?: {
56
- ids?: readonly Readonly<Record<string, string>>[] | undefined;
57
- data?: Record<string, any> | undefined;
58
- } | undefined) => import("@node-in-layers/core/types.js").HighLevelLogger;
59
- }>;
60
- constants: {
61
- environment: string;
62
- workingDirectory: string;
63
- runtimeId: string;
64
- };
65
- }>) => Promise<any>;
66
- }> | undefined;
67
- models?: Record<string, Readonly<{
68
- create: <T extends Readonly<{
69
- [s: string]: any;
70
- }>, TModelExtensions extends object = object, TModelInstanceExtensions extends object = object>(modelProps: Readonly<{
71
- context: Readonly<{
72
- config: Readonly<any>;
73
- rootLogger: Readonly<{
74
- getLogger: (context: Readonly<any>, props?: {
75
- ids?: readonly Readonly<Record<string, string>>[] | undefined;
76
- data?: Record<string, any> | undefined;
77
- } | undefined) => import("@node-in-layers/core/types.js").HighLevelLogger;
78
- }>;
79
- constants: {
80
- environment: string;
81
- workingDirectory: string;
82
- runtimeId: string;
83
- };
84
- }>;
85
- Model: import("functional-models/types.js").ModelFactory<object, object>;
86
- fetcher: import("functional-models/types.js").ModelInstanceFetcher<object, object>;
87
- getModel: <T_1 extends Readonly<{
88
- [s: string]: any;
89
- }>>(namespace: string, modelName: string) => () => import("functional-models/types.js").ModelType<T_1, object, object>;
90
- }>) => import("functional-models/types.js").ModelType<T, TModelExtensions, TModelInstanceExtensions>;
91
- }>> | undefined;
92
- }>[];
93
- modelFactory?: string | undefined;
94
- modelCruds?: boolean | undefined;
95
- customModelFactory?: {
96
- [x: string]: {
97
- [x: string]: string | [string, string] | [string, string, any[]];
98
- };
99
- } | undefined;
100
- }>;
101
- }> = Readonly<{
102
- systemName: string;
103
- environment: string;
104
- "@node-in-layers/core": Readonly<{
105
- logging: {
106
- logLevel: import("@node-in-layers/core/types.js").LogLevelNames;
107
- logFormat: import("@node-in-layers/core/types.js").LogFormat | readonly import("@node-in-layers/core/types.js").LogFormat[];
108
- maxLogSizeInCharacters?: number | undefined;
109
- tcpLoggingOptions?: Readonly<{
110
- url: string;
111
- headers?: Record<string, string | object> | undefined;
112
- }> | undefined;
113
- customLogger?: Readonly<{
114
- getLogger: (context: Readonly<{
115
- config: Readonly<any>;
116
- rootLogger: Readonly<any>;
117
- constants: {
118
- environment: string;
119
- workingDirectory: string;
120
- runtimeId: string;
121
- };
122
- }>, props?: {
123
- ids?: readonly Readonly<Record<string, string>>[] | undefined;
124
- data?: Record<string, any> | undefined;
125
- } | undefined) => import("@node-in-layers/core/types.js").HighLevelLogger;
126
- }> | undefined;
127
- getFunctionWrapLogLevel?: ((layerName: string, functionName?: string | undefined) => import("@node-in-layers/core/types.js").LogLevelNames) | undefined;
128
- ignoreLayerFunctions?: Record<string, boolean | Record<string, boolean | Record<string, boolean>>> | undefined;
129
- };
130
- layerOrder: readonly import("@node-in-layers/core/types.js").LayerDescription[];
131
- apps: readonly Readonly<{
132
- name: string;
133
- description?: string | undefined;
134
- services?: Readonly<{
135
- create: (context: any) => import("@node-in-layers/core/types.js").MaybePromise<object>;
136
- }> | undefined;
137
- features?: Readonly<{
138
- create: (context: any) => import("@node-in-layers/core/types.js").MaybePromise<object>;
139
- }> | undefined;
140
- globals?: Readonly<{
141
- create: (context: Readonly<{
142
- config: Readonly<any>;
143
- rootLogger: Readonly<{
144
- getLogger: (context: Readonly<{
145
- config: Readonly<any>;
146
- rootLogger: Readonly<any>;
147
- constants: {
148
- environment: string;
149
- workingDirectory: string;
150
- runtimeId: string;
151
- };
152
- }>, props?: {
153
- ids?: readonly Readonly<Record<string, string>>[] | undefined;
154
- data?: Record<string, any> | undefined;
155
- } | undefined) => import("@node-in-layers/core/types.js").HighLevelLogger;
156
- }>;
157
- constants: {
158
- environment: string;
159
- workingDirectory: string;
160
- runtimeId: string;
161
- };
162
- }>) => Promise<any>;
163
- }> | undefined;
164
- models?: Record<string, Readonly<{
165
- create: <T extends Readonly<{
166
- [s: string]: any;
167
- }>, TModelExtensions extends object = object, TModelInstanceExtensions extends object = object>(modelProps: Readonly<{
168
- context: Readonly<{
169
- config: Readonly<any>;
170
- rootLogger: Readonly<{
171
- getLogger: (context: Readonly<any>, props?: {
172
- ids?: readonly Readonly<Record<string, string>>[] | undefined;
173
- data?: Record<string, any> | undefined;
174
- } | undefined) => import("@node-in-layers/core/types.js").HighLevelLogger;
175
- }>;
176
- constants: {
177
- environment: string;
178
- workingDirectory: string;
179
- runtimeId: string;
180
- };
181
- }>;
182
- Model: import("functional-models/types.js").ModelFactory<object, object>;
183
- fetcher: import("functional-models/types.js").ModelInstanceFetcher<object, object>;
184
- getModel: <T_1 extends Readonly<{
185
- [s: string]: any;
186
- }>>(namespace: string, modelName: string) => () => import("functional-models/types.js").ModelType<T_1, object, object>;
187
- }>) => import("functional-models/types.js").ModelType<T, TModelExtensions, TModelInstanceExtensions>;
188
- }>> | undefined;
189
- }>[];
190
- modelFactory?: string | undefined;
191
- modelCruds?: boolean | undefined;
192
- customModelFactory?: {
193
- [x: string]: {
194
- [x: string]: string | [string, string] | [string, string, any[]];
195
- };
196
- } | undefined;
197
- }>;
198
- }>>(rawConfig: TConfig) => Promise<TConfig>;
199
- };
200
- export { create };
@@ -1,40 +0,0 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
- import isEmpty from 'lodash/isEmpty.js';
11
- import { AwsNamespace } from '../types.js';
12
- import { findSecretsManagerEntries, findParameterStoreEntries, applyParameterStore, applySecrets, } from './lib.js';
13
- const create = (
14
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
15
- context) => {
16
- const replaceAwsConfigObjects = (rawConfig) => {
17
- return Promise.resolve().then(() => __awaiter(void 0, void 0, void 0, function* () {
18
- const secretsNeeded = findSecretsManagerEntries(rawConfig);
19
- const secretsApplied = yield (isEmpty(secretsNeeded) === false
20
- ? (() => __awaiter(void 0, void 0, void 0, function* () {
21
- const secrets = yield context.services[AwsNamespace.config].readSecretsInSecretsManager(Object.values(secretsNeeded).map(x => x.key));
22
- return applySecrets(rawConfig, secretsNeeded, secrets);
23
- }))()
24
- : rawConfig);
25
- const parameterStoreNeeded = findParameterStoreEntries(rawConfig);
26
- const parametersApplied = yield (isEmpty(parameterStoreNeeded) === false
27
- ? (() => __awaiter(void 0, void 0, void 0, function* () {
28
- const parameters = yield context.services[AwsNamespace.config].readParameters(Object.values(parameterStoreNeeded).map(x => x.key));
29
- return applyParameterStore(secretsApplied, parameterStoreNeeded, parameters);
30
- }))()
31
- : rawConfig);
32
- return parametersApplied;
33
- }));
34
- };
35
- return {
36
- replaceAwsConfigObjects,
37
- };
38
- };
39
- export { create };
40
- //# sourceMappingURL=features.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"features.js","sourceRoot":"","sources":["../../src/config/features.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,OAAO,MAAM,mBAAmB,CAAA;AAEvC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE1C,OAAO,EACL,yBAAyB,EACzB,yBAAyB,EACzB,mBAAmB,EACnB,YAAY,GACb,MAAM,UAAU,CAAA;AAEjB,MAAM,MAAM,GAAG;AACb,6DAA6D;AAC7D,OAIC,EACD,EAAE;IACF,MAAM,uBAAuB,GAAG,CAC9B,SAAkB,EACA,EAAE;QACpB,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,GAAS,EAAE;YACvC,MAAM,aAAa,GAAG,yBAAyB,CAAC,SAAS,CAAC,CAAA;YAC1D,MAAM,cAAc,GAAG,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,KAAK,KAAK;gBAC5D,CAAC,CAAC,CAAC,GAAS,EAAE;oBACV,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,QAAQ,CACpC,YAAY,CAAC,MAAM,CACpB,CAAC,2BAA2B,CAC3B,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAC7C,CAAA;oBACD,OAAO,YAAY,CAAC,SAAS,EAAE,aAAa,EAAE,OAAO,CAAY,CAAA;gBACnE,CAAC,CAAA,CAAC,EAAE;gBACN,CAAC,CAAC,SAAS,CAAC,CAAA;YAEd,MAAM,oBAAoB,GAAG,yBAAyB,CAAC,SAAS,CAAC,CAAA;YACjE,MAAM,iBAAiB,GAAG,MAAM,CAAC,OAAO,CAAC,oBAAoB,CAAC,KAAK,KAAK;gBACtE,CAAC,CAAC,CAAC,GAAS,EAAE;oBACV,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,QAAQ,CACvC,YAAY,CAAC,MAAM,CACpB,CAAC,cAAc,CACd,MAAM,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CACpD,CAAA;oBACD,OAAO,mBAAmB,CACxB,cAAc,EACd,oBAAoB,EACpB,UAAU,CACA,CAAA;gBACd,CAAC,CAAA,CAAC,EAAE;gBACN,CAAC,CAAC,SAAS,CAAC,CAAA;YAEd,OAAO,iBAA4B,CAAA;QACrC,CAAC,CAAA,CAAC,CAAA;IACJ,CAAC,CAAA;IAED,OAAO;QACL,uBAAuB;KACxB,CAAA;AACH,CAAC,CAAA;AAED,OAAO,EAAE,MAAM,EAAE,CAAA"}
@@ -1,7 +0,0 @@
1
- /**
2
- * Replaces objects within the config
3
- */
4
- declare const create: (context: any) => Promise<{
5
- config: any;
6
- }>;
7
- export { create };
package/config/globals.js DELETED
@@ -1,37 +0,0 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
- import merge from 'lodash/merge.js';
11
- import * as rootServices from '../aws/services.js';
12
- import { AwsNamespace } from '../types.js';
13
- import * as services from './services.js';
14
- import * as features from './features.js';
15
- /**
16
- * Replaces objects within the config
17
- */
18
- const create = (context) => __awaiter(void 0, void 0, void 0, function* () {
19
- // We have to create services and features, because globals happens before services or features.
20
- const rServices = rootServices.create(context);
21
- const sInstance = services.create(merge(context, {
22
- services: {
23
- [AwsNamespace.root]: rServices,
24
- },
25
- }));
26
- const f = features.create(merge(context, {
27
- services: {
28
- [AwsNamespace.config]: sInstance,
29
- },
30
- }));
31
- const newConfig = yield f.replaceAwsConfigObjects(context.config);
32
- return {
33
- config: newConfig,
34
- };
35
- });
36
- export { create };
37
- //# sourceMappingURL=globals.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"globals.js","sourceRoot":"","sources":["../../src/config/globals.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,KAAK,MAAM,iBAAiB,CAAA;AACnC,OAAO,KAAK,YAAY,MAAM,oBAAoB,CAAA;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AACzC,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AAEzC;;GAEG;AACH,MAAM,MAAM,GAAG,CAAM,OAAO,EAAC,EAAE;IAC7B,gGAAgG;IAChG,MAAM,SAAS,GAAG,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IAC9C,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAC/B,KAAK,CAAC,OAAO,EAAE;QACb,QAAQ,EAAE;YACR,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,SAAS;SAC/B;KACF,CAAC,CACH,CAAA;IACD,MAAM,CAAC,GAAG,QAAQ,CAAC,MAAM,CACvB,KAAK,CAAC,OAAO,EAAE;QACb,QAAQ,EAAE;YACR,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,SAAS;SACjC;KACF,CAAC,CACH,CAAA;IAED,MAAM,SAAS,GAAG,MAAM,CAAC,CAAC,uBAAuB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;IAEjE,OAAO;QACL,MAAM,EAAE,SAAS;KAClB,CAAA;AACH,CAAC,CAAA,CAAA;AAED,OAAO,EAAE,MAAM,EAAE,CAAA"}
package/config/lib.d.ts DELETED
@@ -1,30 +0,0 @@
1
- import { AwsEntryType } from './types.js';
2
- /**
3
- * Finds the secrets manager entries in the config file.
4
- */
5
- declare const findSecretsManagerEntries: (rawConfig: object) => Readonly<Record<string, Readonly<{
6
- type: AwsEntryType.secretsManager;
7
- key: string;
8
- }>>>;
9
- /**
10
- * Finds parameter store entries in the configuration file
11
- */
12
- declare const findParameterStoreEntries: (rawConfig: object) => Readonly<Record<string, Readonly<{
13
- type: AwsEntryType.parameterStore;
14
- key: string;
15
- }>>>;
16
- /**
17
- * Replaces secrets manager entries with their value.
18
- */
19
- declare const applySecrets: (rawConfig: object, toReplace: Readonly<Record<string, Readonly<{
20
- type: AwsEntryType.secretsManager;
21
- key: string;
22
- }>>>, entries: object) => object;
23
- /**
24
- * Replaces parameter store entries with their value.
25
- */
26
- declare const applyParameterStore: (rawConfig: object, toReplace: Readonly<Record<string, Readonly<{
27
- type: AwsEntryType.parameterStore;
28
- key: string;
29
- }>>>, entries: object) => object;
30
- export { applyParameterStore, applySecrets, findParameterStoreEntries, findSecretsManagerEntries, };
package/config/lib.js DELETED
@@ -1,66 +0,0 @@
1
- import get from 'lodash/get.js';
2
- import merge from 'lodash/merge.js';
3
- import set from 'lodash/set.js';
4
- import isPlainObject from 'lodash/isPlainObject.js';
5
- import { AwsEntryKey, AwsEntryType, } from './types.js';
6
- const _findObjects = (path, obj, isMatch) => {
7
- if (isPlainObject(obj)) {
8
- const match = isMatch(obj);
9
- if (match) {
10
- if (!path) {
11
- throw new Error(`Cannot match base object`);
12
- }
13
- return [path];
14
- }
15
- return Object.entries(obj).reduce((acc, [key, value]) => {
16
- const fullPath = path ? `${path}.${key}` : key;
17
- return acc.concat(_findObjects(fullPath, value, isMatch));
18
- }, []);
19
- }
20
- return [];
21
- };
22
- const findNestedObjects = (obj, isMatch) => {
23
- return _findObjects(undefined, obj, isMatch);
24
- };
25
- const _findAwsEntries = (type) => (rawConfig) => {
26
- return findNestedObjects(rawConfig, (obj) => {
27
- return AwsEntryKey in obj && obj[AwsEntryKey] === type;
28
- }).reduce((acc, path) => {
29
- return merge(acc, {
30
- [path]: get(rawConfig, path),
31
- });
32
- }, {});
33
- };
34
- /**
35
- * Finds the secrets manager entries in the config file.
36
- */
37
- const findSecretsManagerEntries = _findAwsEntries(AwsEntryType.secretsManager);
38
- /**
39
- * Finds parameter store entries in the configuration file
40
- */
41
- const findParameterStoreEntries = _findAwsEntries(AwsEntryType.parameterStore);
42
- /**
43
- * Finds an entry within the configuration file that needs to be replaced.
44
- * @param rawConfig
45
- * @param toReplace
46
- * @param entries
47
- */
48
- const applyAwsEntry = (rawConfig, toReplace, entries) => {
49
- return Object.entries(toReplace).reduce((acc, [path, partial]) => {
50
- const secret = entries[partial.key];
51
- if (!secret) {
52
- throw new Error(`Must include secret for ${partial.key}`);
53
- }
54
- return set(acc, path, secret);
55
- }, rawConfig);
56
- };
57
- /**
58
- * Replaces secrets manager entries with their value.
59
- */
60
- const applySecrets = (applyAwsEntry);
61
- /**
62
- * Replaces parameter store entries with their value.
63
- */
64
- const applyParameterStore = (applyAwsEntry);
65
- export { applyParameterStore, applySecrets, findParameterStoreEntries, findSecretsManagerEntries, };
66
- //# sourceMappingURL=lib.js.map
package/config/lib.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"lib.js","sourceRoot":"","sources":["../../src/config/lib.ts"],"names":[],"mappings":"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"}