@digitraffic/common 2024.1.30-1 → 2024.3.13-1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/__test__/api/handler-factory.test.mjs +6 -6
- package/dist/__test__/secrets/secret-holder.test.mjs +8 -11
- package/dist/__test__/secrets/secret.test.mjs +1 -5
- package/dist/__test__/test/mock-ky.test.d.mts +1 -0
- package/dist/__test__/test/mock-ky.test.mjs +46 -0
- package/dist/__test__/utils/logging.test.mjs +2 -2
- package/dist/aws/infra/canaries/canary-parameters.d.mts +2 -1
- package/dist/aws/infra/canaries/canary-parameters.mjs +1 -1
- package/dist/aws/infra/canaries/canary.mjs +2 -2
- package/dist/aws/infra/stack/monitoredfunction.mjs +3 -2
- package/dist/aws/runtime/apikey.d.mts +2 -2
- package/dist/aws/runtime/apikey.mjs +2 -3
- package/dist/aws/runtime/messaging.d.mts +1 -1
- package/dist/aws/runtime/messaging.mjs +5 -4
- package/dist/aws/runtime/s3.d.mts +4 -2
- package/dist/aws/runtime/s3.mjs +15 -11
- package/dist/aws/runtime/secrets/secret.mjs +3 -6
- package/dist/test/mock-ky.d.mts +2 -0
- package/dist/test/mock-ky.mjs +15 -0
- package/dist/test/secrets-manager.d.mts +2 -1
- package/dist/test/secrets-manager.mjs +13 -15
- package/dist/utils/logging.mjs +2 -2
- package/dist/utils/slack.mjs +3 -3
- package/package.json +16 -11
@@ -1,7 +1,7 @@
|
|
1
1
|
import { HandlerFactory } from "../../aws/infra/api/handler-factory.mjs";
|
2
2
|
import { DtLogger } from "../../aws/runtime/dt-logger.mjs";
|
3
3
|
import { LambdaResponse } from "../../aws/types/lambda-response.mjs";
|
4
|
-
import { jest } from
|
4
|
+
import { jest } from "@jest/globals";
|
5
5
|
const logger = new DtLogger();
|
6
6
|
describe("handler-factory tests", () => {
|
7
7
|
test("test defaults", async () => {
|
@@ -11,7 +11,7 @@ describe("handler-factory tests", () => {
|
|
11
11
|
});
|
12
12
|
const handler = factory.createEventHandler(method, logger);
|
13
13
|
await handler({});
|
14
|
-
expect(method).
|
14
|
+
expect(method).toHaveBeenCalledTimes(1);
|
15
15
|
});
|
16
16
|
test("test logging", async () => {
|
17
17
|
const loggingHandler = jest.fn((method) => {
|
@@ -23,8 +23,8 @@ describe("handler-factory tests", () => {
|
|
23
23
|
});
|
24
24
|
const handler = factory.createEventHandler(method, logger);
|
25
25
|
await handler({});
|
26
|
-
expect(method).
|
27
|
-
expect(loggingHandler).
|
26
|
+
expect(method).toHaveBeenCalledTimes(1);
|
27
|
+
expect(loggingHandler).toHaveBeenCalledTimes(1);
|
28
28
|
});
|
29
29
|
test("test error handling", async () => {
|
30
30
|
const eh = jest.fn((method) => {
|
@@ -36,8 +36,8 @@ describe("handler-factory tests", () => {
|
|
36
36
|
});
|
37
37
|
const handler = factory.createEventHandler(method, logger);
|
38
38
|
await handler({});
|
39
|
-
expect(method).
|
40
|
-
expect(eh).
|
39
|
+
expect(method).toHaveBeenCalledTimes(1);
|
40
|
+
expect(eh).toHaveBeenCalledTimes(1);
|
41
41
|
});
|
42
42
|
});
|
43
43
|
//# sourceMappingURL=handler-factory.test.mjs.map
|
@@ -1,5 +1,4 @@
|
|
1
1
|
import { mockSecret, stubSecretsManager } from "../../test/secrets-manager.mjs";
|
2
|
-
import sinon from "sinon";
|
3
2
|
const SECRET_WITH_PREFIX = {
|
4
3
|
"prefix.value": "value",
|
5
4
|
"prefix.name": "name",
|
@@ -14,11 +13,9 @@ const { SecretHolder } = secretHolder;
|
|
14
13
|
const { DatabaseEnvironmentKeys } = database;
|
15
14
|
describe("SecretHolder - tests", () => {
|
16
15
|
beforeEach(() => {
|
17
|
-
process.env[
|
16
|
+
process.env["SECRET_ID"] = "test-id";
|
18
17
|
});
|
19
18
|
afterEach(() => {
|
20
|
-
sinon.restore();
|
21
|
-
sinon.reset();
|
22
19
|
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
|
23
20
|
delete process.env[DatabaseEnvironmentKeys.DB_USER];
|
24
21
|
});
|
@@ -26,7 +23,7 @@ describe("SecretHolder - tests", () => {
|
|
26
23
|
mockSecret(null);
|
27
24
|
const holder = SecretHolder.create();
|
28
25
|
const secret = holder.get();
|
29
|
-
return expect(secret).rejects.
|
26
|
+
return expect(secret).rejects.toThrow("No secret found!");
|
30
27
|
}, 10000);
|
31
28
|
test("get - empty secret", () => {
|
32
29
|
mockSecret(SECRET_EMPTY);
|
@@ -63,27 +60,27 @@ describe("SecretHolder - tests", () => {
|
|
63
60
|
test("get - ttl - do not fetch", async () => {
|
64
61
|
mockSecret(SECRET_WITH_PREFIX);
|
65
62
|
const holder = SecretHolder.create();
|
66
|
-
const callCount = stubSM.callCount;
|
63
|
+
const callCount = stubSM.getSecretValue.callCount;
|
67
64
|
await holder.get();
|
68
|
-
expect(stubSM.callCount).toEqual(callCount + 1);
|
65
|
+
expect(stubSM.getSecretValue.callCount).toEqual(callCount + 1);
|
69
66
|
// gets cached secret
|
70
67
|
await holder.get();
|
71
|
-
expect(stubSM.callCount).toEqual(callCount + 1);
|
68
|
+
expect(stubSM.getSecretValue.callCount).toEqual(callCount + 1);
|
72
69
|
});
|
73
70
|
test("get - ttl - fetch", async () => {
|
74
71
|
mockSecret(SECRET_WITH_PREFIX);
|
75
72
|
const holder = new SecretHolder("", "", [], {
|
76
73
|
ttl: 1,
|
77
74
|
});
|
78
|
-
const callCount = stubSM.callCount;
|
75
|
+
const callCount = stubSM.getSecretValue.callCount;
|
79
76
|
await holder.get();
|
80
|
-
expect(stubSM.callCount).toEqual(callCount + 1);
|
77
|
+
expect(stubSM.getSecretValue.callCount).toEqual(callCount + 1);
|
81
78
|
// cache expires, fetches secret again
|
82
79
|
const start = Date.now();
|
83
80
|
while (Date.now() < start + 2000)
|
84
81
|
;
|
85
82
|
await holder.get();
|
86
|
-
expect(stubSM.callCount).toEqual(callCount + 2);
|
83
|
+
expect(stubSM.getSecretValue.callCount).toEqual(callCount + 2);
|
87
84
|
});
|
88
85
|
});
|
89
86
|
//# sourceMappingURL=secret-holder.test.mjs.map
|
@@ -1,5 +1,4 @@
|
|
1
1
|
import { mockSecret, stubSecretsManager } from "../../test/secrets-manager.mjs";
|
2
|
-
import sinon from "sinon";
|
3
2
|
const SECRET_ID = "test_secret";
|
4
3
|
const SECRET_WITH_PREFIX = {
|
5
4
|
"prefix.value": "value",
|
@@ -11,14 +10,11 @@ stubSecretsManager();
|
|
11
10
|
const secret = await import("../../aws/runtime/secrets/secret.mjs");
|
12
11
|
const { getSecret } = secret;
|
13
12
|
describe("secret - test", () => {
|
14
|
-
afterEach(() => {
|
15
|
-
sinon.restore();
|
16
|
-
});
|
17
13
|
test("getSecret - no secret", async () => {
|
18
14
|
mockSecret(null);
|
19
15
|
await expect(async () => {
|
20
16
|
await getSecret(SECRET_ID, "");
|
21
|
-
}).rejects.
|
17
|
+
}).rejects.toThrow("No secret found!");
|
22
18
|
});
|
23
19
|
test("getSecret - empty secret", async () => {
|
24
20
|
mockSecret(SECRET_EMPTY);
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1,46 @@
|
|
1
|
+
import { mockKyResponse } from "../../test/mock-ky.mjs";
|
2
|
+
import { describe, test, jest } from "@jest/globals";
|
3
|
+
const ky = (await import("ky")).default;
|
4
|
+
describe("mockKyResponse", () => {
|
5
|
+
const testObj = { test: "data" };
|
6
|
+
const testJson = JSON.stringify(testObj);
|
7
|
+
const url = "https://example.com";
|
8
|
+
afterEach(() => {
|
9
|
+
jest.restoreAllMocks();
|
10
|
+
});
|
11
|
+
test("works with all methods", async () => {
|
12
|
+
jest.spyOn(ky, "get").mockImplementation(() => mockKyResponse(200, testJson));
|
13
|
+
jest.spyOn(ky, "post").mockImplementation(() => mockKyResponse(200, testJson));
|
14
|
+
jest.spyOn(ky, "put").mockImplementation(() => mockKyResponse(200, testJson));
|
15
|
+
jest.spyOn(ky, "delete").mockImplementation(() => mockKyResponse(200, testJson));
|
16
|
+
expect(await ky.get(url).text()).toEqual(testJson);
|
17
|
+
expect(await ky.put(url).text()).toEqual(testJson);
|
18
|
+
expect(await ky.post(url).text()).toEqual(testJson);
|
19
|
+
expect(await ky.delete(url).text()).toEqual(testJson);
|
20
|
+
});
|
21
|
+
test("returns correct status", async () => {
|
22
|
+
jest.spyOn(ky, "get").mockImplementation(() => mockKyResponse(200, testJson));
|
23
|
+
expect((await ky.get(url)).status).toEqual(200);
|
24
|
+
jest.spyOn(ky, "get").mockImplementation(() => mockKyResponse(400, testJson));
|
25
|
+
expect((await ky.get(url)).status).toEqual(400);
|
26
|
+
});
|
27
|
+
test("returns correct ok", async () => {
|
28
|
+
jest.spyOn(ky, "get").mockImplementation(() => mockKyResponse(200, testJson));
|
29
|
+
expect((await ky.get(url)).ok).toEqual(true);
|
30
|
+
jest.spyOn(ky, "get").mockImplementation(() => mockKyResponse(299, testJson));
|
31
|
+
expect((await ky.get(url)).ok).toEqual(true);
|
32
|
+
jest.spyOn(ky, "get").mockImplementation(() => mockKyResponse(300, testJson));
|
33
|
+
expect((await ky.get(url)).ok).toEqual(false);
|
34
|
+
});
|
35
|
+
test("convenience methods work: text", async () => {
|
36
|
+
jest.spyOn(ky, "get").mockImplementation(() => mockKyResponse(200, testJson));
|
37
|
+
expect(await ky.get(url).text()).toEqual(testJson);
|
38
|
+
expect(await (await ky.get(url)).text()).toEqual(testJson);
|
39
|
+
});
|
40
|
+
test("convenience methods work: json", async () => {
|
41
|
+
jest.spyOn(ky, "get").mockImplementation(() => mockKyResponse(200, testJson));
|
42
|
+
expect(await ky.get(url).json()).toEqual(testObj);
|
43
|
+
expect(await (await ky.get(url)).json()).toEqual(testObj);
|
44
|
+
});
|
45
|
+
});
|
46
|
+
//# sourceMappingURL=mock-ky.test.mjs.map
|
@@ -1,4 +1,3 @@
|
|
1
|
-
import { AxiosError } from "axios";
|
2
1
|
import { Writable } from "stream";
|
3
2
|
import { DtLogger } from "../../aws/runtime/dt-logger.mjs";
|
4
3
|
import { logException } from "../../utils/logging.mjs";
|
@@ -65,7 +64,8 @@ describe("dt-logger", () => {
|
|
65
64
|
}, true);
|
66
65
|
});
|
67
66
|
test("log error - AxiosError", () => {
|
68
|
-
const ERROR = new
|
67
|
+
const ERROR = new Error("ErrorFromAxios");
|
68
|
+
ERROR.code = "12";
|
69
69
|
assertAxiosError(ERROR, {
|
70
70
|
type: "Error",
|
71
71
|
method: TEST_METHODNAME,
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import { Schedule } from "aws-cdk-lib/aws-synthetics";
|
1
|
+
import { Runtime, Schedule } from "aws-cdk-lib/aws-synthetics";
|
2
2
|
/** Optional env parameters for canary */
|
3
3
|
type CanaryEnv = Record<string, string>;
|
4
4
|
export interface CanaryParameters {
|
@@ -14,5 +14,6 @@ export interface CanaryParameters {
|
|
14
14
|
readonly topicArn?: string;
|
15
15
|
};
|
16
16
|
readonly canaryEnv?: CanaryEnv;
|
17
|
+
readonly runtime?: Runtime;
|
17
18
|
}
|
18
19
|
export {};
|
@@ -1,2 +1,2 @@
|
|
1
|
-
import { Schedule } from "aws-cdk-lib/aws-synthetics";
|
1
|
+
import { Runtime, Schedule } from "aws-cdk-lib/aws-synthetics";
|
2
2
|
//# sourceMappingURL=canary-parameters.mjs.map
|
@@ -1,12 +1,12 @@
|
|
1
1
|
import { Duration } from "aws-cdk-lib";
|
2
|
-
import { AssetCode, Canary, Runtime, Schedule, Test
|
2
|
+
import { AssetCode, Canary, Runtime, Schedule, Test } from "aws-cdk-lib/aws-synthetics";
|
3
3
|
import { Role } from "aws-cdk-lib/aws-iam";
|
4
4
|
import { CanaryAlarm } from "./canary-alarm.mjs";
|
5
5
|
import { Construct } from "constructs";
|
6
6
|
export class DigitrafficCanary extends Canary {
|
7
7
|
constructor(scope, canaryName, role, params, environmentVariables) {
|
8
8
|
super(scope, canaryName, {
|
9
|
-
runtime: Runtime.
|
9
|
+
runtime: params.runtime ?? Runtime.SYNTHETICS_NODEJS_PUPPETEER_6_2,
|
10
10
|
role,
|
11
11
|
test: Test.custom({
|
12
12
|
code: new AssetCode("dist", {
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import { Function } from "aws-cdk-lib/aws-lambda";
|
1
|
+
import { Function, LoggingFormat } from "aws-cdk-lib/aws-lambda";
|
2
2
|
import { Stack } from "aws-cdk-lib";
|
3
3
|
import { SnsAction } from "aws-cdk-lib/aws-cloudwatch-actions";
|
4
4
|
import { ComparisonOperator, Metric } from "aws-cdk-lib/aws-cloudwatch";
|
@@ -75,7 +75,8 @@ export class MonitoredFunction extends Function {
|
|
75
75
|
* @param props Monitored function properties
|
76
76
|
*/
|
77
77
|
constructor(scope, id, functionProps, alarmSnsTopic, warningSnsTopic, production, trafficType, props) {
|
78
|
-
|
78
|
+
// Set default loggingFormat to JSON if not explicitly set to TEXT
|
79
|
+
super(scope, id, { ...{ loggingFormat: LoggingFormat.JSON }, ...functionProps });
|
79
80
|
if (functionProps.functionName === undefined) {
|
80
81
|
throw new Error("Function name not provided");
|
81
82
|
}
|
@@ -1,2 +1,2 @@
|
|
1
|
-
import type {
|
2
|
-
export declare function getApiKeyFromAPIGateway(keyId: string): Promise<
|
1
|
+
import type { UpdateApiKeyCommandOutput } from "@aws-sdk/client-api-gateway";
|
2
|
+
export declare function getApiKeyFromAPIGateway(keyId: string): Promise<UpdateApiKeyCommandOutput>;
|
@@ -1,10 +1,9 @@
|
|
1
|
-
import
|
2
|
-
const { APIGateway } = awsSdk;
|
1
|
+
import { APIGateway } from "@aws-sdk/client-api-gateway";
|
3
2
|
export function getApiKeyFromAPIGateway(keyId) {
|
4
3
|
const agw = new APIGateway();
|
5
4
|
return agw.getApiKey({
|
6
5
|
apiKey: keyId,
|
7
6
|
includeValue: true,
|
8
|
-
})
|
7
|
+
});
|
9
8
|
}
|
10
9
|
//# sourceMappingURL=apikey.mjs.map
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import
|
1
|
+
import { SNS as SNSType } from "@aws-sdk/client-sns";
|
2
2
|
/**
|
3
3
|
* Utility function for publishing SNS messages.
|
4
4
|
* Made because using *await* with AWS APIs doesn't require calling promise() but nothing works if it isn't called.
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import { SNS as SNSType } from "@aws-sdk/client-sns";
|
1
2
|
/**
|
2
3
|
* Utility function for publishing SNS messages.
|
3
4
|
* Made because using *await* with AWS APIs doesn't require calling promise() but nothing works if it isn't called.
|
@@ -12,15 +13,15 @@ export async function snsPublish(message, topicArn, sns) {
|
|
12
13
|
TopicArn: topicArn,
|
13
14
|
};
|
14
15
|
try {
|
15
|
-
await sns.publish(publishParams)
|
16
|
+
await sns.publish(publishParams);
|
16
17
|
}
|
17
18
|
catch (error) {
|
18
|
-
console.error(
|
19
|
+
console.error("method=snsPublish error, retrying", error);
|
19
20
|
try {
|
20
|
-
await sns.publish(publishParams)
|
21
|
+
await sns.publish(publishParams);
|
21
22
|
}
|
22
23
|
catch (e2) {
|
23
|
-
console.error(
|
24
|
+
console.error("method=snsPublish error after retry", e2);
|
24
25
|
}
|
25
26
|
}
|
26
27
|
}
|
@@ -1,2 +1,4 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
/// <reference types="node" resolution-mode="require"/>
|
2
|
+
import type { ObjectCannedACL } from "@aws-sdk/client-s3";
|
3
|
+
import { Readable } from "node:stream";
|
4
|
+
export declare function uploadToS3(bucketName: string, body: Readable, objectName: string, cannedAcl?: ObjectCannedACL, contentType?: string): Promise<void>;
|
package/dist/aws/runtime/s3.mjs
CHANGED
@@ -1,27 +1,31 @@
|
|
1
|
-
import
|
2
|
-
|
1
|
+
import { Upload } from "@aws-sdk/lib-storage";
|
2
|
+
import { S3 } from "@aws-sdk/client-s3";
|
3
|
+
import { Readable } from "node:stream";
|
3
4
|
export async function uploadToS3(bucketName, body, objectName, cannedAcl, contentType) {
|
4
5
|
const s3 = new S3();
|
5
6
|
try {
|
6
7
|
await doUpload(s3, bucketName, body, objectName, cannedAcl, contentType);
|
7
8
|
}
|
8
9
|
catch (error) {
|
9
|
-
console.warn(
|
10
|
+
console.warn("method=uploadToS3 retrying upload to bucket %s", bucketName);
|
10
11
|
try {
|
11
12
|
await doUpload(s3, bucketName, body, objectName, cannedAcl, contentType);
|
12
13
|
}
|
13
14
|
catch (e2) {
|
14
|
-
console.error(
|
15
|
+
console.error("method=uploadToS3 failed retrying upload to bucket %s", bucketName);
|
15
16
|
}
|
16
17
|
}
|
17
18
|
}
|
18
19
|
function doUpload(s3, bucketName, body, filename, cannedAcl, contentType) {
|
19
|
-
return
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
20
|
+
return new Upload({
|
21
|
+
client: s3,
|
22
|
+
params: {
|
23
|
+
Bucket: bucketName,
|
24
|
+
Body: body,
|
25
|
+
Key: filename,
|
26
|
+
ACL: cannedAcl,
|
27
|
+
ContentType: contentType,
|
28
|
+
},
|
29
|
+
}).done();
|
26
30
|
}
|
27
31
|
//# sourceMappingURL=s3.mjs.map
|
@@ -1,7 +1,6 @@
|
|
1
|
-
import awsSdk from "aws-sdk";
|
2
1
|
import { getEnvVariable, getEnvVariableOrElse } from "../../../utils/utils.mjs";
|
3
2
|
import { EnvKeys } from "../environment.mjs";
|
4
|
-
const { SecretsManager } =
|
3
|
+
const { SecretsManager } = await import("@aws-sdk/client-secrets-manager");
|
5
4
|
// SECRET_OVERRIDE_AWS_REGION might not have been set before import of
|
6
5
|
// secret, so we need to lazy initialize SecretsManager
|
7
6
|
let smClient;
|
@@ -15,11 +14,9 @@ function getSmClient() {
|
|
15
14
|
return smClient;
|
16
15
|
}
|
17
16
|
export async function getSecret(secretId, prefix = "") {
|
18
|
-
const secretObj = await getSmClient()
|
19
|
-
.getSecretValue({
|
17
|
+
const secretObj = await getSmClient().getSecretValue({
|
20
18
|
SecretId: secretId,
|
21
|
-
})
|
22
|
-
.promise();
|
19
|
+
});
|
23
20
|
if (!secretObj.SecretString) {
|
24
21
|
throw new Error("No secret found!");
|
25
22
|
}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
export function mockKyResponse(status, body) {
|
2
|
+
const response = new Response(body, {
|
3
|
+
status: status,
|
4
|
+
});
|
5
|
+
const promise = Promise.resolve(response);
|
6
|
+
// The ky ResponsePromise is just Promise<Response> with some convenience methods.
|
7
|
+
return Object.assign(promise, {
|
8
|
+
arrayBuffer: () => response.arrayBuffer(),
|
9
|
+
blob: () => response.blob(),
|
10
|
+
formData: () => response.formData(),
|
11
|
+
json: () => response.json(),
|
12
|
+
text: () => response.text(),
|
13
|
+
});
|
14
|
+
}
|
15
|
+
//# sourceMappingURL=mock-ky.mjs.map
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import { SecretsManager } from "@aws-sdk/client-secrets-manager";
|
1
2
|
import sinon from "sinon";
|
2
3
|
/**
|
3
4
|
* Stub Secrets Manager for tests. You must call this
|
@@ -5,5 +6,5 @@ import sinon from "sinon";
|
|
5
6
|
*
|
6
7
|
* To mock the actual secret, call mockSecret()
|
7
8
|
*/
|
8
|
-
export declare function stubSecretsManager(): sinon.
|
9
|
+
export declare function stubSecretsManager(): sinon.SinonStubbedInstance<SecretsManager>;
|
9
10
|
export declare function mockSecret<Secret>(secret: Secret): void;
|
@@ -1,9 +1,12 @@
|
|
1
|
-
import
|
1
|
+
import { SecretsManager } from "@aws-sdk/client-secrets-manager";
|
2
2
|
import sinon from "sinon";
|
3
3
|
import { EnvKeys } from "../aws/runtime/environment.mjs";
|
4
4
|
import { setEnvVariable } from "../utils/utils.mjs";
|
5
|
+
import { jest } from '@jest/globals';
|
5
6
|
setEnvVariable(EnvKeys.AWS_REGION, "eu-west-1");
|
6
|
-
const
|
7
|
+
const emptySecret = { $metadata: {} };
|
8
|
+
const SecretsManagerStubInstance = sinon.createStubInstance(SecretsManager);
|
9
|
+
SecretsManagerStubInstance.getSecretValue.resolves(emptySecret);
|
7
10
|
/**
|
8
11
|
* Stub Secrets Manager for tests. You must call this
|
9
12
|
* before you instantiate Secrets Manager(this might happen when you import the function that uses Secrets Manager).
|
@@ -11,24 +14,19 @@ const secretValue = sinon.stub();
|
|
11
14
|
* To mock the actual secret, call mockSecret()
|
12
15
|
*/
|
13
16
|
export function stubSecretsManager() {
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
17
|
+
jest.unstable_mockModule("@aws-sdk/client-secrets-manager", function () {
|
18
|
+
return {
|
19
|
+
SecretsManager: sinon.stub().returns(SecretsManagerStubInstance)
|
20
|
+
};
|
21
|
+
});
|
22
|
+
return SecretsManagerStubInstance;
|
19
23
|
}
|
20
24
|
export function mockSecret(secret) {
|
21
25
|
if (!secret) {
|
22
|
-
|
23
|
-
promise: sinon.stub().returns({}),
|
24
|
-
});
|
26
|
+
SecretsManagerStubInstance.getSecretValue.resolves({ ...emptySecret });
|
25
27
|
}
|
26
28
|
else {
|
27
|
-
|
28
|
-
promise: sinon.stub().returns({
|
29
|
-
SecretString: JSON.stringify(secret),
|
30
|
-
}),
|
31
|
-
});
|
29
|
+
SecretsManagerStubInstance.getSecretValue.resolves({ SecretString: JSON.stringify(secret) });
|
32
30
|
}
|
33
31
|
}
|
34
32
|
//# sourceMappingURL=secrets-manager.mjs.map
|
package/dist/utils/logging.mjs
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
import { AxiosError } from "axios";
|
2
1
|
import { DtLogger } from "../aws/runtime/dt-logger.mjs";
|
3
2
|
import { getEnvVariableOrElse } from "./utils.mjs";
|
4
3
|
const functionName = getEnvVariableOrElse("AWS_LAMBDA_FUNCTION_NAME", "test");
|
@@ -49,7 +48,8 @@ export function logException(logger, error, includeStack = false) {
|
|
49
48
|
? error
|
50
49
|
: JSON.stringify(error);
|
51
50
|
const stack = error instanceof Error && includeStack ? error.stack : undefined;
|
52
|
-
|
51
|
+
// In case error is AxiosError, log the custom code property.
|
52
|
+
const customCode = error["code"];
|
53
53
|
logger.error({
|
54
54
|
type: "Error",
|
55
55
|
method: `${functionName}.logException`,
|
package/dist/utils/slack.mjs
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import
|
1
|
+
import ky from "ky";
|
2
2
|
import { logger } from "../aws/runtime/dt-logger-default.mjs";
|
3
3
|
import { logException } from "./logging.mjs";
|
4
4
|
export class SlackApi {
|
@@ -12,8 +12,8 @@ export class SlackApi {
|
|
12
12
|
method: "SlackApi.notify",
|
13
13
|
message: "Sending slack notification",
|
14
14
|
});
|
15
|
-
await
|
16
|
-
text
|
15
|
+
await ky.post(this.url, {
|
16
|
+
body: text
|
17
17
|
});
|
18
18
|
}
|
19
19
|
catch (error) {
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@digitraffic/common",
|
3
|
-
"version": "2024.
|
3
|
+
"version": "2024.3.13-1",
|
4
4
|
"description": "",
|
5
5
|
"type": "module",
|
6
6
|
"repository": {
|
@@ -38,6 +38,7 @@
|
|
38
38
|
"./dist/test/httpserver": "./dist/test/httpserver.mjs",
|
39
39
|
"./dist/test/secrets-manager": "./dist/test/secrets-manager.mjs",
|
40
40
|
"./dist/test/asserter": "./dist/test/asserter.mjs",
|
41
|
+
"./dist/test/mock-ky": "./dist/test/mock-ky.mjs",
|
41
42
|
"./dist/marine/rtz": "./dist/marine/rtz.mjs",
|
42
43
|
"./dist/marine/id_utils": "./dist/marine/id_utils.mjs",
|
43
44
|
"./dist/index": "./dist/index.mjs",
|
@@ -103,22 +104,31 @@
|
|
103
104
|
"./dist/aws/runtime/digitraffic-integration-response": "./dist/aws/runtime/digitraffic-integration-response.mjs"
|
104
105
|
},
|
105
106
|
"peerDependencies": {
|
107
|
+
"@aws-sdk/client-s3": "^3.496.0",
|
108
|
+
"@aws-sdk/lib-storage": "^3.496.0",
|
109
|
+
"@aws-sdk/client-secrets-manager": "^3.496.0",
|
110
|
+
"@aws-sdk/client-api-gateway": "^3.496.0",
|
111
|
+
"@aws-sdk/client-sns": "^3.496.0",
|
106
112
|
"@types/geojson": "^7946.0.12",
|
107
|
-
"aws-cdk-lib": "^2.
|
108
|
-
"aws-sdk": "^2.1481.0",
|
109
|
-
"axios": "^1.6.2",
|
113
|
+
"aws-cdk-lib": "^2.132.1",
|
110
114
|
"change-case": "5.0.0",
|
111
115
|
"constructs": "^10.3.0",
|
112
116
|
"date-fns": "~2.30.0",
|
113
117
|
"date-fns-tz": "~2.0.0",
|
114
118
|
"etag": "^1.8.1",
|
115
119
|
"geojson-validation": "^1.0.2",
|
120
|
+
"ky": "^1.2.0",
|
116
121
|
"lodash": "~4.17.21",
|
117
122
|
"node-ttl": "^0.2.0",
|
118
123
|
"pg-native": "^3.0.1",
|
119
124
|
"pg-promise": "^11.5.4"
|
120
125
|
},
|
121
126
|
"devDependencies": {
|
127
|
+
"@aws-sdk/client-s3": "3.496.0",
|
128
|
+
"@aws-sdk/lib-storage": "3.496.0",
|
129
|
+
"@aws-sdk/client-secrets-manager": "3.496.0",
|
130
|
+
"@aws-sdk/client-api-gateway": "3.496.0",
|
131
|
+
"@aws-sdk/client-sns": "3.496.0",
|
122
132
|
"@jest/globals": "^29.7.0",
|
123
133
|
"@rushstack/eslint-config": "^3.6.2",
|
124
134
|
"@rushstack/heft": "^0.64.3",
|
@@ -135,9 +145,7 @@
|
|
135
145
|
"@types/sinon": "17.0.2",
|
136
146
|
"@typescript-eslint/eslint-plugin": "~6.18.1",
|
137
147
|
"@typescript-eslint/parser": "^6.20.0",
|
138
|
-
"aws-cdk-lib": "~2.
|
139
|
-
"aws-sdk": "~2.1531.0",
|
140
|
-
"axios": "^1.6.7",
|
148
|
+
"aws-cdk-lib": "~2.132.1",
|
141
149
|
"change-case": "5.3.0",
|
142
150
|
"constructs": "10.3.0",
|
143
151
|
"date-fns": "~2.30.0",
|
@@ -149,6 +157,7 @@
|
|
149
157
|
"geojson-validation": "^1.0.2",
|
150
158
|
"jest": "^29.7.0",
|
151
159
|
"jest-junit": "^16.0.0",
|
160
|
+
"ky": "^1.2.0",
|
152
161
|
"lodash": "~4.17.21",
|
153
162
|
"node-ttl": "^0.2.0",
|
154
163
|
"pg-promise": "^11.5.4",
|
@@ -159,10 +168,6 @@
|
|
159
168
|
"typescript": "~5.3.3",
|
160
169
|
"velocityjs": "2.0.6"
|
161
170
|
},
|
162
|
-
"dependencies": {
|
163
|
-
"@aws-sdk/client-s3": "~3.472.0",
|
164
|
-
"@aws-sdk/lib-storage": "~3.472.0"
|
165
|
-
},
|
166
171
|
"scripts": {
|
167
172
|
"build": "tsc",
|
168
173
|
"build:watch": "tsc --watch",
|