@digitraffic/common 2022.12.2-1 → 2022.12.22-2
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/dist/aws/infra/api/handler-factory.d.ts +9 -7
- package/dist/aws/infra/api/handler-factory.js +19 -16
- package/dist/aws/infra/api/integration.d.ts +2 -2
- package/dist/aws/infra/api/responses.js +4 -4
- package/dist/aws/infra/canaries/canary-parameters.d.ts +2 -2
- package/dist/aws/infra/canaries/canary-role.d.ts +1 -1
- package/dist/aws/infra/canaries/canary-role.js +3 -5
- package/dist/aws/infra/documentation.d.ts +1 -1
- package/dist/aws/infra/documentation.js +3 -3
- package/dist/aws/infra/stack/monitoredfunction.d.ts +4 -4
- package/dist/aws/infra/stack/monitoredfunction.js +2 -2
- package/dist/aws/infra/stack/stack-checking-aspect.js +6 -8
- package/dist/aws/infra/stacks/db-stack.js +2 -1
- package/dist/aws/runtime/dt-logger.d.ts +28 -0
- package/dist/aws/runtime/dt-logger.js +41 -0
- package/dist/aws/runtime/secrets/dbsecret.d.ts +4 -4
- package/dist/aws/runtime/secrets/dbsecret.js +1 -1
- package/dist/aws/types/proxytypes.d.ts +4 -4
- package/dist/database/last-updated.js +9 -7
- package/dist/marine/rtz.d.ts +20 -20
- package/dist/test/asserter.d.ts +6 -4
- package/dist/test/asserter.js +1 -1
- package/dist/test/httpserver.d.ts +1 -3
- package/dist/test/httpserver.js +10 -4
- package/dist/types/either.d.ts +4 -4
- package/package.json +1 -1
- package/src/aws/infra/api/handler-factory.ts +36 -26
- package/src/aws/infra/api/integration.ts +2 -2
- package/src/aws/infra/api/responses.ts +6 -4
- package/src/aws/infra/canaries/canary-parameters.ts +3 -3
- package/src/aws/infra/canaries/canary-role.ts +20 -10
- package/src/aws/infra/documentation.ts +42 -24
- package/src/aws/infra/stack/monitoredfunction.ts +6 -6
- package/src/aws/infra/stack/stack-checking-aspect.ts +15 -15
- package/src/aws/infra/stacks/db-stack.ts +2 -1
- package/src/aws/runtime/dt-logger.ts +61 -0
- package/src/aws/runtime/secrets/dbsecret.ts +5 -5
- package/src/aws/types/proxytypes.ts +14 -14
- package/src/database/last-updated.ts +75 -31
- package/src/marine/rtz.ts +29 -29
- package/src/test/asserter.ts +21 -11
- package/src/test/httpserver.ts +17 -8
- package/src/types/either.ts +8 -2
@@ -1,8 +1,12 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
1
|
+
import { DtLogger } from "../../runtime/dt-logger";
|
2
|
+
import { LambdaResponse } from "../../types/lambda-response";
|
3
|
+
|
4
|
+
export type LoggingHandler = (
|
5
|
+
method: () => Promise<LambdaResponse>,
|
6
|
+
logger: DtLogger
|
7
|
+
) => Promise<LambdaResponse>;
|
8
|
+
|
9
|
+
export type ErrorHandler = (error: unknown, logger: DtLogger) => LambdaResponse;
|
6
10
|
|
7
11
|
/**
|
8
12
|
* Factory class for creating lambda-handler functions. You can set functionality to handle logging and error-handling,
|
@@ -13,58 +17,64 @@ export type ErrorHandler<RESPONSE> = (error: unknown) => RESPONSE;
|
|
13
17
|
* You should instantiate HandlerFactory in your project with desired error handling and use the factory instance for
|
14
18
|
* creating handler-functions for your lambdas.
|
15
19
|
*/
|
16
|
-
export class HandlerFactory
|
17
|
-
private loggingHandler: LoggingHandler
|
18
|
-
private errorHandler: ErrorHandler
|
20
|
+
export class HandlerFactory {
|
21
|
+
private loggingHandler: LoggingHandler;
|
22
|
+
private errorHandler: ErrorHandler;
|
19
23
|
|
20
24
|
constructor() {
|
21
|
-
this.loggingHandler =
|
25
|
+
this.loggingHandler = async (method: () => Promise<LambdaResponse>) => {
|
26
|
+
const start = Date.now();
|
27
|
+
|
28
|
+
try {
|
29
|
+
return await method();
|
30
|
+
} finally {
|
31
|
+
console.info(
|
32
|
+
"method=%s.handler tookMs=%d",
|
33
|
+
process.env.AWS_LAMBDA_FUNCTION_NAME,
|
34
|
+
Date.now() - start
|
35
|
+
);
|
36
|
+
}
|
37
|
+
};
|
22
38
|
|
23
39
|
this.errorHandler = (error: unknown) => {
|
24
40
|
throw error;
|
25
41
|
};
|
26
42
|
}
|
27
43
|
|
28
|
-
withLoggingHandler(loggingHandler: LoggingHandler
|
44
|
+
withLoggingHandler(loggingHandler: LoggingHandler) {
|
29
45
|
this.loggingHandler = loggingHandler;
|
30
46
|
return this;
|
31
47
|
}
|
32
48
|
|
33
|
-
withErrorHandler(errorHandler: ErrorHandler
|
49
|
+
withErrorHandler(errorHandler: ErrorHandler) {
|
34
50
|
this.errorHandler = errorHandler;
|
35
51
|
return this;
|
36
52
|
}
|
37
53
|
|
38
54
|
createEventHandler(
|
39
|
-
|
40
|
-
|
55
|
+
handler: (event: unknown) => Promise<LambdaResponse>,
|
56
|
+
logger: DtLogger
|
41
57
|
) {
|
42
58
|
return async (event: unknown) => {
|
43
|
-
return await this.loggingHandler(
|
59
|
+
return await this.loggingHandler(async () => {
|
44
60
|
try {
|
45
61
|
return await handler(event);
|
46
62
|
} catch (error) {
|
47
|
-
return this.errorHandler(error);
|
63
|
+
return this.errorHandler(error, logger);
|
48
64
|
}
|
49
|
-
});
|
65
|
+
}, logger);
|
50
66
|
};
|
51
67
|
}
|
52
68
|
}
|
53
69
|
|
54
|
-
export function
|
55
|
-
return (
|
56
|
-
return method();
|
57
|
-
};
|
58
|
-
}
|
59
|
-
|
60
|
-
function createDefaultLoggingHandler<RESPONSE>(): LoggingHandler<RESPONSE> {
|
61
|
-
return (methodName: string, method: () => Promise<RESPONSE>) => {
|
70
|
+
export function createJsonLoggingHandler(): LoggingHandler {
|
71
|
+
return async (method: () => Promise<LambdaResponse>, logger: DtLogger) => {
|
62
72
|
const start = Date.now();
|
63
73
|
|
64
74
|
try {
|
65
|
-
return method();
|
75
|
+
return await method();
|
66
76
|
} finally {
|
67
|
-
|
77
|
+
logger.info({ tookMs: Date.now() - start });
|
68
78
|
}
|
69
79
|
};
|
70
80
|
}
|
@@ -25,13 +25,13 @@ export class DigitrafficIntegration {
|
|
25
25
|
this.mediaType = mediaType;
|
26
26
|
}
|
27
27
|
|
28
|
-
addPathParameter(...names: string[]):
|
28
|
+
addPathParameter(...names: string[]): this {
|
29
29
|
names.forEach((name) => this.parameters.push({ type: "path", name }));
|
30
30
|
|
31
31
|
return this;
|
32
32
|
}
|
33
33
|
|
34
|
-
addQueryParameter(...names: string[]):
|
34
|
+
addQueryParameter(...names: string[]): this {
|
35
35
|
names.forEach((name) =>
|
36
36
|
this.parameters.push({ type: "querystring", name })
|
37
37
|
);
|
@@ -64,7 +64,7 @@ export function methodResponse(
|
|
64
64
|
return {
|
65
65
|
statusCode: status,
|
66
66
|
responseModels: createResponses(contentType, model),
|
67
|
-
responseParameters: parameters
|
67
|
+
responseParameters: parameters ?? {},
|
68
68
|
};
|
69
69
|
}
|
70
70
|
|
@@ -83,7 +83,9 @@ export function corsMethod(response: MethodResponse): MethodResponse {
|
|
83
83
|
}
|
84
84
|
|
85
85
|
interface IntegrationOptions {
|
86
|
+
// eslint-disable-next-line @typescript-eslint/consistent-indexed-object-style
|
86
87
|
requestParameters?: { [dest: string]: string };
|
88
|
+
// eslint-disable-next-line @typescript-eslint/consistent-indexed-object-style
|
87
89
|
requestTemplates?: { [contentType: string]: string };
|
88
90
|
responses?: IntegrationResponse[];
|
89
91
|
disableCors?: boolean;
|
@@ -104,14 +106,14 @@ export function defaultIntegration(
|
|
104
106
|
): LambdaIntegration {
|
105
107
|
return new LambdaIntegration(lambdaFunction, {
|
106
108
|
proxy: false,
|
107
|
-
integrationResponses: options?.responses
|
109
|
+
integrationResponses: options?.responses ?? [
|
108
110
|
getResponse(RESPONSE_200_OK, options),
|
109
111
|
getResponse(RESPONSE_400_BAD_REQUEST, options),
|
110
112
|
getResponse(RESPONSE_404_NOT_FOUND, options),
|
111
113
|
getResponse(RESPONSE_500_SERVER_ERROR, options),
|
112
114
|
],
|
113
|
-
requestParameters: options?.requestParameters
|
114
|
-
requestTemplates: options?.requestTemplates
|
115
|
+
requestParameters: options?.requestParameters ?? {},
|
116
|
+
requestTemplates: options?.requestTemplates ?? {},
|
115
117
|
passthroughBehavior:
|
116
118
|
options?.passthroughBehavior ?? PassthroughBehavior.WHEN_NO_MATCH,
|
117
119
|
});
|
@@ -1,9 +1,9 @@
|
|
1
|
-
import {Schedule} from "@aws-cdk/aws-synthetics-alpha";
|
1
|
+
import { Schedule } from "@aws-cdk/aws-synthetics-alpha";
|
2
2
|
|
3
3
|
/** Optional env parameters for canary */
|
4
4
|
type CanaryEnv = Record<string, string>;
|
5
5
|
|
6
|
-
export
|
6
|
+
export interface CanaryParameters {
|
7
7
|
readonly name: string;
|
8
8
|
readonly schedule?: Schedule;
|
9
9
|
readonly secret?: string;
|
@@ -14,6 +14,6 @@ export type CanaryParameters = {
|
|
14
14
|
readonly evalutionPeriods?: number;
|
15
15
|
readonly threshold?: number;
|
16
16
|
readonly topicArn?: string;
|
17
|
-
}
|
17
|
+
};
|
18
18
|
readonly canaryEnv?: CanaryEnv;
|
19
19
|
}
|
@@ -1,5 +1,11 @@
|
|
1
|
-
import {
|
2
|
-
|
1
|
+
import {
|
2
|
+
ManagedPolicy,
|
3
|
+
PolicyStatement,
|
4
|
+
PolicyStatementProps,
|
5
|
+
Role,
|
6
|
+
ServicePrincipal,
|
7
|
+
} from "aws-cdk-lib/aws-iam";
|
8
|
+
import { Construct } from "constructs";
|
3
9
|
|
4
10
|
const BASE_POLICY_STATEMENT_PROPS: PolicyStatementProps = {
|
5
11
|
actions: [
|
@@ -13,12 +19,10 @@ const BASE_POLICY_STATEMENT_PROPS: PolicyStatementProps = {
|
|
13
19
|
};
|
14
20
|
|
15
21
|
const CLOUDWATCH_STATEMENT_PROPS: PolicyStatementProps = {
|
16
|
-
actions: [
|
17
|
-
"cloudwatch:PutMetricData",
|
18
|
-
],
|
22
|
+
actions: ["cloudwatch:PutMetricData"],
|
19
23
|
resources: ["*"],
|
20
24
|
conditions: {
|
21
|
-
|
25
|
+
StringEquals: {
|
22
26
|
"cloudwatch:namespace": "CloudWatchSynthetics",
|
23
27
|
},
|
24
28
|
},
|
@@ -26,10 +30,12 @@ const CLOUDWATCH_STATEMENT_PROPS: PolicyStatementProps = {
|
|
26
30
|
|
27
31
|
export class DigitrafficCanaryRole extends Role {
|
28
32
|
constructor(stack: Construct, canaryName: string) {
|
29
|
-
super(stack,
|
33
|
+
super(stack, "canary-role-" + canaryName, {
|
30
34
|
assumedBy: new ServicePrincipal("lambda.amazonaws.com"),
|
31
35
|
managedPolicies: [
|
32
|
-
ManagedPolicy.fromAwsManagedPolicyName(
|
36
|
+
ManagedPolicy.fromAwsManagedPolicyName(
|
37
|
+
"CloudWatchSyntheticsFullAccess"
|
38
|
+
),
|
33
39
|
],
|
34
40
|
});
|
35
41
|
|
@@ -37,11 +43,15 @@ export class DigitrafficCanaryRole extends Role {
|
|
37
43
|
this.addToPolicy(new PolicyStatement(CLOUDWATCH_STATEMENT_PROPS));
|
38
44
|
}
|
39
45
|
|
40
|
-
withDatabaseAccess():
|
46
|
+
withDatabaseAccess(): this {
|
41
47
|
// Won't work :(
|
42
48
|
// this.addToPolicy(new PolicyStatement(DB_STATEMENT_PROPS));
|
43
49
|
// Works
|
44
|
-
this.addManagedPolicy(
|
50
|
+
this.addManagedPolicy(
|
51
|
+
ManagedPolicy.fromAwsManagedPolicyName(
|
52
|
+
"service-role/AWSLambdaVPCAccessExecutionRole"
|
53
|
+
)
|
54
|
+
);
|
45
55
|
return this;
|
46
56
|
}
|
47
57
|
}
|
@@ -1,5 +1,5 @@
|
|
1
|
-
import {Construct} from "constructs";
|
2
|
-
import {CfnDocumentationPart, Resource} from "aws-cdk-lib/aws-apigateway";
|
1
|
+
import { Construct } from "constructs";
|
2
|
+
import { CfnDocumentationPart, Resource } from "aws-cdk-lib/aws-apigateway";
|
3
3
|
|
4
4
|
// Documentation parts are objects that describe an API Gateway API or parts of an API
|
5
5
|
// https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-documenting-api.html
|
@@ -13,18 +13,20 @@ import {CfnDocumentationPart, Resource} from "aws-cdk-lib/aws-apigateway";
|
|
13
13
|
*
|
14
14
|
* @deprecated Use DigitrafficRestApi.documentResource
|
15
15
|
*/
|
16
|
-
export function addQueryParameterDescription(
|
16
|
+
export function addQueryParameterDescription(
|
17
|
+
name: string,
|
17
18
|
description: string,
|
18
19
|
resource: Resource,
|
19
|
-
stack: Construct
|
20
|
+
stack: Construct
|
21
|
+
) {
|
20
22
|
new CfnDocumentationPart(stack, `${name}Documentation`, {
|
21
23
|
restApiId: resource.api.restApiId,
|
22
24
|
location: {
|
23
|
-
type:
|
25
|
+
type: "QUERY_PARAMETER",
|
24
26
|
name,
|
25
27
|
path: resource.path,
|
26
28
|
},
|
27
|
-
properties: JSON.stringify({description}),
|
29
|
+
properties: JSON.stringify({ description }),
|
28
30
|
});
|
29
31
|
}
|
30
32
|
|
@@ -35,14 +37,16 @@ export function addQueryParameterDescription(name: string,
|
|
35
37
|
* @param resource REST API resource
|
36
38
|
* @param stack CloudFormation stack
|
37
39
|
*/
|
38
|
-
export function addDocumentation(
|
40
|
+
export function addDocumentation(
|
41
|
+
methodDescription: string,
|
39
42
|
documentationProperties: object,
|
40
43
|
resource: Resource,
|
41
|
-
stack: Construct
|
44
|
+
stack: Construct
|
45
|
+
) {
|
42
46
|
new CfnDocumentationPart(stack, `${methodDescription}Documentation`, {
|
43
47
|
restApiId: resource.api.restApiId,
|
44
48
|
location: {
|
45
|
-
type:
|
49
|
+
type: "METHOD",
|
46
50
|
path: resource.path,
|
47
51
|
},
|
48
52
|
properties: JSON.stringify(documentationProperties),
|
@@ -56,11 +60,13 @@ export function addDocumentation(methodDescription: string,
|
|
56
60
|
* @param resource REST API resource
|
57
61
|
* @param stack CloudFormation stack
|
58
62
|
*/
|
59
|
-
export function addTags(
|
63
|
+
export function addTags(
|
64
|
+
methodDescription: string,
|
60
65
|
tags: string[],
|
61
66
|
resource: Resource,
|
62
|
-
stack: Construct
|
63
|
-
|
67
|
+
stack: Construct
|
68
|
+
) {
|
69
|
+
addDocumentation(methodDescription, { tags }, resource, stack);
|
64
70
|
}
|
65
71
|
|
66
72
|
/**
|
@@ -79,16 +85,16 @@ export function addTagsAndSummary(
|
|
79
85
|
tags: string[],
|
80
86
|
summary: string,
|
81
87
|
resource: Resource,
|
82
|
-
stack: Construct
|
88
|
+
stack: Construct
|
83
89
|
) {
|
84
|
-
addDocumentation(methodDescription, {tags, summary}, resource, stack);
|
90
|
+
addDocumentation(methodDescription, { tags, summary }, resource, stack);
|
85
91
|
}
|
86
92
|
|
87
93
|
export interface DocumentationProperties {
|
88
|
-
description?: string
|
89
|
-
tags?: string[]
|
90
|
-
summary?: string
|
91
|
-
deprecated?: boolean
|
94
|
+
description?: string;
|
95
|
+
tags?: string[];
|
96
|
+
summary?: string;
|
97
|
+
deprecated?: boolean;
|
92
98
|
}
|
93
99
|
|
94
100
|
export class DocumentationPart {
|
@@ -96,29 +102,41 @@ export class DocumentationPart {
|
|
96
102
|
readonly type: string;
|
97
103
|
readonly documentationProperties: DocumentationProperties;
|
98
104
|
|
99
|
-
private constructor(
|
105
|
+
private constructor(
|
106
|
+
parameterName: string,
|
107
|
+
documentationProperties: DocumentationProperties,
|
108
|
+
type: string
|
109
|
+
) {
|
100
110
|
this.parameterName = parameterName;
|
101
111
|
this.documentationProperties = documentationProperties;
|
102
112
|
this.type = type;
|
103
113
|
}
|
104
114
|
|
105
|
-
deprecated(note: string):
|
115
|
+
deprecated(note: string): this {
|
106
116
|
// deprecated is not supported ATM: https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-known-issues.html
|
107
117
|
this.documentationProperties.deprecated = true;
|
108
|
-
this.documentationProperties.summary+=
|
118
|
+
this.documentationProperties.summary += ". " + note;
|
109
119
|
|
110
120
|
return this;
|
111
121
|
}
|
112
122
|
|
113
123
|
static queryParameter(parameterName: string, description: string) {
|
114
|
-
return new DocumentationPart(
|
124
|
+
return new DocumentationPart(
|
125
|
+
parameterName,
|
126
|
+
{ description },
|
127
|
+
"QUERY_PARAMETER"
|
128
|
+
);
|
115
129
|
}
|
116
130
|
|
117
131
|
static pathParameter(parameterName: string, description: string) {
|
118
|
-
return new DocumentationPart(
|
132
|
+
return new DocumentationPart(
|
133
|
+
parameterName,
|
134
|
+
{ description },
|
135
|
+
"PATH_PARAMETER"
|
136
|
+
);
|
119
137
|
}
|
120
138
|
|
121
139
|
static method(tags: string[], name: string, summary: string) {
|
122
|
-
return new DocumentationPart(name, {tags, summary}, "METHOD");
|
140
|
+
return new DocumentationPart(name, { tags, summary }, "METHOD");
|
123
141
|
}
|
124
142
|
}
|
@@ -16,7 +16,7 @@ import { TrafficType } from "../../../types/traffictype";
|
|
16
16
|
/**
|
17
17
|
* Allows customization of CloudWatch Alarm properties
|
18
18
|
*/
|
19
|
-
export
|
19
|
+
export interface MonitoredFunctionAlarmProps {
|
20
20
|
/**
|
21
21
|
* Setting this to false will not create a CloudWatch alarm
|
22
22
|
*/
|
@@ -29,9 +29,9 @@ export type MonitoredFunctionAlarmProps = {
|
|
29
29
|
readonly datapointsToAlarm?: number;
|
30
30
|
|
31
31
|
readonly comparisonOperator?: ComparisonOperator;
|
32
|
-
}
|
32
|
+
}
|
33
33
|
|
34
|
-
export
|
34
|
+
export interface MonitoredFunctionProps {
|
35
35
|
readonly durationAlarmProps?: MonitoredFunctionAlarmProps;
|
36
36
|
|
37
37
|
readonly durationWarningProps?: MonitoredFunctionAlarmProps;
|
@@ -39,7 +39,7 @@ export type MonitoredFunctionProps = {
|
|
39
39
|
readonly errorAlarmProps?: MonitoredFunctionAlarmProps;
|
40
40
|
|
41
41
|
readonly throttleAlarmProps?: MonitoredFunctionAlarmProps;
|
42
|
-
}
|
42
|
+
}
|
43
43
|
|
44
44
|
/**
|
45
45
|
* Creates a Lambda function that monitors default CloudWatch Lambda metrics with CloudWatch Alarms.
|
@@ -115,7 +115,7 @@ export class MonitoredFunction extends Function {
|
|
115
115
|
functionParameters?: Partial<MonitoredFunctionParameters>
|
116
116
|
): MonitoredFunction {
|
117
117
|
const functionName =
|
118
|
-
functionParameters?.functionName
|
118
|
+
functionParameters?.functionName ??
|
119
119
|
`${stack.configuration.shortName}-${pascalCase(name)}`;
|
120
120
|
const functionProps = databaseFunctionProps(
|
121
121
|
stack,
|
@@ -313,7 +313,7 @@ export class MonitoredDBFunction {
|
|
313
313
|
functionParameters?: Partial<MonitoredFunctionParameters>
|
314
314
|
): MonitoredFunction {
|
315
315
|
const functionName =
|
316
|
-
functionParameters?.functionName
|
316
|
+
functionParameters?.functionName ??
|
317
317
|
`${stack.configuration.shortName}-${pascalCase(name)}`;
|
318
318
|
const env = environment ? environment : stack.createLambdaEnvironment();
|
319
319
|
const functionProps = databaseFunctionProps(
|
@@ -183,19 +183,17 @@ export class StackCheckingAspect implements IAspect {
|
|
183
183
|
const c =
|
184
184
|
node.publicAccessBlockConfiguration as CfnBucket.PublicAccessBlockConfigurationProperty;
|
185
185
|
|
186
|
-
if (
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
);
|
198
|
-
}
|
186
|
+
if (
|
187
|
+
!c.blockPublicAcls ||
|
188
|
+
!c.blockPublicPolicy ||
|
189
|
+
!c.ignorePublicAcls ||
|
190
|
+
!c.restrictPublicBuckets
|
191
|
+
) {
|
192
|
+
this.addAnnotation(
|
193
|
+
node,
|
194
|
+
ResourceType.bucketPublicity,
|
195
|
+
"Check bucket publicity"
|
196
|
+
);
|
199
197
|
}
|
200
198
|
}
|
201
199
|
}
|
@@ -227,9 +225,11 @@ export class StackCheckingAspect implements IAspect {
|
|
227
225
|
);
|
228
226
|
}
|
229
227
|
} else if (node instanceof CfnMethod) {
|
230
|
-
const integration = node.integration as
|
228
|
+
const integration = node.integration as
|
229
|
+
| IntegrationProperty
|
230
|
+
| undefined;
|
231
231
|
|
232
|
-
if (integration
|
232
|
+
if (integration?.requestParameters) {
|
233
233
|
Object.keys(integration.requestParameters).forEach((key) => {
|
234
234
|
const split = key.split(".");
|
235
235
|
const type = split[2];
|
@@ -0,0 +1,61 @@
|
|
1
|
+
import { Writable } from "stream";
|
2
|
+
|
3
|
+
type LOG_LEVEL = "DEBUG" | "INFO" | "ERROR";
|
4
|
+
|
5
|
+
export interface LoggerConfiguration {
|
6
|
+
lambdaName?: string;
|
7
|
+
fileName?: string;
|
8
|
+
runTime?: string;
|
9
|
+
writeStream?: Writable;
|
10
|
+
}
|
11
|
+
|
12
|
+
export type LoggableType = string | number | Record<string, unknown>;
|
13
|
+
|
14
|
+
/**
|
15
|
+
* Helper class for json-logging. Logged line will include
|
16
|
+
* * log-level (see LOG_LEVEL)
|
17
|
+
* * lambdaName (taken from process environment)
|
18
|
+
* * runtime (taken from process environment)
|
19
|
+
* * the actual message (as json or as string)
|
20
|
+
*/
|
21
|
+
export class DtLogger {
|
22
|
+
readonly lambdaName?: string;
|
23
|
+
readonly fileName?: string;
|
24
|
+
readonly runtime?: string;
|
25
|
+
|
26
|
+
readonly writeStream: Writable;
|
27
|
+
|
28
|
+
constructor(config?: LoggerConfiguration) {
|
29
|
+
this.lambdaName =
|
30
|
+
config?.lambdaName ?? process.env.AWS_LAMBDA_FUNCTION_NAME;
|
31
|
+
this.fileName = config?.fileName;
|
32
|
+
this.runtime = config?.runTime ?? process.env.AWS_EXECUTION_ENV;
|
33
|
+
this.writeStream = config?.writeStream ?? process.stdout;
|
34
|
+
}
|
35
|
+
|
36
|
+
info(message: LoggableType) {
|
37
|
+
this.log("INFO", message);
|
38
|
+
}
|
39
|
+
|
40
|
+
error(message: LoggableType) {
|
41
|
+
this.log("ERROR", message);
|
42
|
+
}
|
43
|
+
|
44
|
+
log(level: LOG_LEVEL, message: LoggableType) {
|
45
|
+
// put string/number messages into message object
|
46
|
+
const actualMessage =
|
47
|
+
typeof message == "object" ? message : { message: message };
|
48
|
+
|
49
|
+
const logMessage = {
|
50
|
+
...actualMessage,
|
51
|
+
...{
|
52
|
+
level,
|
53
|
+
fileName: this.fileName,
|
54
|
+
lambdaName: this.lambdaName,
|
55
|
+
runtime: this.runtime,
|
56
|
+
},
|
57
|
+
};
|
58
|
+
|
59
|
+
this.writeStream.write(JSON.stringify(logMessage) + "\n");
|
60
|
+
}
|
61
|
+
}
|
@@ -1,11 +1,11 @@
|
|
1
1
|
import { GenericSecret, withSecret, withSecretAndPrefix } from "./secret";
|
2
2
|
|
3
|
-
export
|
3
|
+
export interface DbSecret {
|
4
4
|
readonly username: string;
|
5
5
|
readonly password: string;
|
6
6
|
readonly host: string;
|
7
7
|
readonly ro_host: string;
|
8
|
-
}
|
8
|
+
}
|
9
9
|
|
10
10
|
export enum RdsProxySecretKey {
|
11
11
|
username = "username",
|
@@ -53,10 +53,10 @@ const missingSecretErrorText = "Missing or empty secretId";
|
|
53
53
|
* The secret that is passed to the given function will not include the prefix in it's keys.
|
54
54
|
|
55
55
|
*/
|
56
|
-
export
|
56
|
+
export interface SecretOptions {
|
57
57
|
readonly expectedKeys?: string[];
|
58
58
|
readonly prefix?: string;
|
59
|
-
}
|
59
|
+
}
|
60
60
|
|
61
61
|
export type SecretToPromiseFunction<Secret, Response = void> = (
|
62
62
|
secret: Secret
|
@@ -140,7 +140,7 @@ export function checkExpectedSecretKeys<Secret extends GenericSecret>(
|
|
140
140
|
const missingKeys = keys.filter((key) => !(key in secret));
|
141
141
|
if (missingKeys.length) {
|
142
142
|
console.error(
|
143
|
-
`method=checkExpectedSecretKeys secret didn't contain the key(s) ${missingKeys}`
|
143
|
+
`method=checkExpectedSecretKeys secret didn't contain the key(s) ${missingKeys.toString()}`
|
144
144
|
);
|
145
145
|
throw new Error("Expected keys were not found");
|
146
146
|
}
|
@@ -3,11 +3,11 @@
|
|
3
3
|
*
|
4
4
|
* Not fully described, extend if necessary.
|
5
5
|
*/
|
6
|
-
export
|
7
|
-
readonly statusCode: number
|
8
|
-
readonly body: string
|
9
|
-
readonly headers?: Record<string, string
|
10
|
-
readonly multiValueHeaders?: Record<string, string[]
|
6
|
+
export interface ProxyLambdaResponse {
|
7
|
+
readonly statusCode: number;
|
8
|
+
readonly body: string;
|
9
|
+
readonly headers?: Record<string, string>;
|
10
|
+
readonly multiValueHeaders?: Record<string, string[]>;
|
11
11
|
}
|
12
12
|
|
13
13
|
/**
|
@@ -15,13 +15,13 @@ export type ProxyLambdaResponse = {
|
|
15
15
|
*
|
16
16
|
* Not fully described, extend if necessary.
|
17
17
|
*/
|
18
|
-
export
|
19
|
-
readonly resource: string
|
20
|
-
readonly path: string
|
21
|
-
readonly httpMethod: string
|
22
|
-
readonly headers: Record<string, string
|
23
|
-
readonly multiValueHeaders: Record<string, string[]
|
24
|
-
readonly queryStringParameters: Record<string, string
|
25
|
-
readonly multiValueQueryStringParameters: Record<string, string[]
|
26
|
-
readonly body?: string
|
18
|
+
export interface ProxyLambdaRequest {
|
19
|
+
readonly resource: string;
|
20
|
+
readonly path: string;
|
21
|
+
readonly httpMethod: string;
|
22
|
+
readonly headers: Record<string, string>;
|
23
|
+
readonly multiValueHeaders: Record<string, string[]>;
|
24
|
+
readonly queryStringParameters: Record<string, string>;
|
25
|
+
readonly multiValueQueryStringParameters: Record<string, string[]>;
|
26
|
+
readonly body?: string;
|
27
27
|
}
|