@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 +47 -48
- package/aws/services.js +1 -1
- package/config/index.d.ts +4 -3
- package/config/index.js +4 -3
- package/config/index.js.map +1 -1
- package/config/services.d.ts +13 -4
- package/config/services.js +56 -34
- package/config/services.js.map +1 -1
- package/config/types.d.ts +27 -33
- package/config/types.js +1 -14
- package/config/types.js.map +1 -1
- package/index.d.ts +1 -0
- package/index.js +1 -0
- package/index.js.map +1 -1
- package/package.json +35 -20
- package/secretsService.d.ts +16 -0
- package/secretsService.js +18 -0
- package/secretsService.js.map +1 -0
- package/types.d.ts +14 -0
- package/types.js +9 -0
- package/types.js.map +1 -1
- package/config/features.d.ts +0 -200
- package/config/features.js +0 -40
- package/config/features.js.map +0 -1
- package/config/globals.d.ts +0 -7
- package/config/globals.js +0 -37
- package/config/globals.js.map +0 -1
- package/config/lib.d.ts +0 -30
- package/config/lib.js +0 -66
- package/config/lib.js.map +0 -1
package/README.md
CHANGED
|
@@ -36,64 +36,63 @@ const awsConfig = {
|
|
|
36
36
|
|
|
37
37
|
## Config
|
|
38
38
|
|
|
39
|
-
|
|
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
|
-
|
|
44
|
+
### Setup With `@node-in-layers/secrets`
|
|
44
45
|
|
|
45
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
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
|
-
|
|
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
|
-
|
|
88
|
-
{
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
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
|
-
|
|
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) },
|
|
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
|
-
|
|
2
|
-
|
|
3
|
-
export
|
|
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
|
-
|
|
2
|
-
|
|
3
|
-
export
|
|
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
|
package/config/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
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"}
|
package/config/services.d.ts
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
|
-
import { ServicesContext } from '@node-in-layers/core
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
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 };
|
package/config/services.js
CHANGED
|
@@ -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
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
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
|
-
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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
|
-
|
|
46
|
-
|
|
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
|
package/config/services.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"services.js","sourceRoot":"","sources":["../../src/config/services.ts"],"names":[],"mappings":";;;;;;;;;
|
|
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 {
|
|
2
|
-
type
|
|
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
|
-
*
|
|
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
|
-
|
|
21
|
-
|
|
22
|
-
|
|
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
|
-
*
|
|
17
|
+
* AWS config domain services: nil-secret hydration and related helpers.
|
|
18
|
+
* @interface
|
|
33
19
|
*/
|
|
34
|
-
type
|
|
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
|
-
*
|
|
27
|
+
* Layer shape: `context.services[AwsNamespace.config]`.
|
|
28
|
+
* @interface
|
|
37
29
|
*/
|
|
38
|
-
type
|
|
30
|
+
export type AwsConfigServicesLayer = Readonly<{
|
|
31
|
+
[AwsNamespace.config]: AwsConfigServices;
|
|
32
|
+
}>;
|
|
39
33
|
/**
|
|
40
|
-
*
|
|
34
|
+
* Context for the AWS config services factory (loads after root AWS services).
|
|
35
|
+
* @interface
|
|
41
36
|
*/
|
|
42
|
-
type
|
|
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
|
-
|
|
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
|
package/config/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/config/types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/config/types.ts"],"names":[],"mappings":""}
|
package/index.d.ts
CHANGED
package/index.js
CHANGED
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": "
|
|
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.
|
|
54
|
-
"@eslint/eslintrc": "^3.
|
|
55
|
-
"@eslint/js": "^9.
|
|
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.
|
|
64
|
-
"@typescript-eslint/parser": "8.
|
|
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.
|
|
71
|
-
"eslint-config-prettier": "^
|
|
72
|
-
"eslint-import-resolver-typescript": "^
|
|
73
|
-
"eslint-plugin-functional": "
|
|
74
|
-
"eslint-plugin-import": "^2.
|
|
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": "^
|
|
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.
|
|
93
|
-
"@aws-sdk/client-ecs": "^3.
|
|
94
|
-
"@aws-sdk/client-s3": "^3.
|
|
95
|
-
"@aws-sdk/client-secrets-manager": "^3.
|
|
96
|
-
"@aws-sdk/client-sqs": "^3.
|
|
97
|
-
"@aws-sdk/client-ssm": "^3.
|
|
98
|
-
"@aws-sdk/lib-dynamodb": "^3.
|
|
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.
|
|
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"}
|
package/config/features.d.ts
DELETED
|
@@ -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 };
|
package/config/features.js
DELETED
|
@@ -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
|
package/config/features.js.map
DELETED
|
@@ -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"}
|
package/config/globals.d.ts
DELETED
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
|
package/config/globals.js.map
DELETED
|
@@ -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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"}
|