@digitraffic/common 2025.1.20-1 → 2025.2.4-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.
Files changed (47) hide show
  1. package/README.md +28 -20
  2. package/dist/__test__/db-testutils.js +1 -1
  3. package/dist/__test__/infra/acl-builder.test.js +14 -6
  4. package/dist/__test__/infra/api/integration.test.js +21 -20
  5. package/dist/__test__/infra/api/static-integration.test.js +5 -4
  6. package/dist/__test__/marine/id_utils.test.js +2 -1
  7. package/dist/__test__/promise/promise.test.js +6 -3
  8. package/dist/__test__/runtime/dt-logger.test.js +1 -1
  9. package/dist/__test__/secrets/secret-holder.test.js +4 -1
  10. package/dist/__test__/secrets/secret.test.js +4 -1
  11. package/dist/__test__/stack/rest-apis.test.js +3 -1
  12. package/dist/__test__/types/lambda-response.test.js +2 -1
  13. package/dist/__test__/utils/utils.test.js +7 -2
  14. package/dist/aws/infra/acl-builder.js +7 -3
  15. package/dist/aws/infra/api/integration.js +5 -3
  16. package/dist/aws/infra/api/responses.js +3 -2
  17. package/dist/aws/infra/api/static-integration.js +7 -4
  18. package/dist/aws/infra/canaries/canary-role.js +3 -1
  19. package/dist/aws/infra/canaries/canary.js +1 -1
  20. package/dist/aws/infra/canaries/database-canary.js +6 -2
  21. package/dist/aws/infra/canaries/database-checker.js +5 -3
  22. package/dist/aws/infra/canaries/url-canary.js +6 -2
  23. package/dist/aws/infra/canaries/url-checker.js +2 -1
  24. package/dist/aws/infra/documentation.js +1 -1
  25. package/dist/aws/infra/sqs-integration.js +3 -1
  26. package/dist/aws/infra/sqs-queue.js +3 -3
  27. package/dist/aws/infra/stack/lambda-configs.js +4 -2
  28. package/dist/aws/infra/stack/monitoredfunction.js +6 -3
  29. package/dist/aws/infra/stack/rest_apis.js +3 -2
  30. package/dist/aws/infra/stack/stack-checking-aspect.js +2 -1
  31. package/dist/aws/infra/stack/stack.js +1 -1
  32. package/dist/aws/infra/stacks/db-dns-stack.js +1 -1
  33. package/dist/aws/infra/stacks/db-stack.d.ts +8 -5
  34. package/dist/aws/infra/stacks/db-stack.js +25 -23
  35. package/dist/aws/runtime/apikey.js +3 -3
  36. package/dist/aws/runtime/digitraffic-integration-response.js +4 -2
  37. package/dist/aws/runtime/dt-logger.js +4 -3
  38. package/dist/aws/runtime/secrets/secret-holder.js +3 -1
  39. package/dist/aws/runtime/secrets/secret.js +1 -1
  40. package/dist/database/cached.d.ts +0 -1
  41. package/dist/database/cached.js +0 -1
  42. package/dist/marine/id_utils.js +6 -2
  43. package/dist/types/openapi-schema.js +15 -3
  44. package/dist/types/traffictype.d.ts +1 -0
  45. package/dist/types/traffictype.js +1 -0
  46. package/dist/utils/logging.js +8 -2
  47. package/package.json +16 -14
package/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # Digitraffic-common
2
2
 
3
- This is a place for common utilities and classes that can be used in other cdk-projects.
3
+ This is a place for common utilities and classes that can be used in other
4
+ cdk-projects.
4
5
 
5
6
  ## How to build
6
7
 
@@ -10,14 +11,19 @@ Use `pnpm` to build the code i.e.
10
11
  pnpm build
11
12
  pnpm test
12
13
 
14
+ Format code
15
+
16
+ pnpm run:format-changed # Formats stagged files
17
+ pnpm run:format # Format all files
18
+
13
19
  ## How to use
14
20
 
15
21
  In package.json dependencies:
16
22
 
17
23
  ```
18
- "dependencies": {
19
- "@digitraffic/common": "*",
20
- }
24
+ "dependencies": {
25
+ "@digitraffic/common": "*",
26
+ }
21
27
  ```
22
28
 
23
29
  In code:
@@ -30,46 +36,48 @@ import {DigitrafficStack, StackConfiguration} from "@digitraffic/common/dist/aws
30
36
 
31
37
  If you extend your stack from DigitrafficStack you get many benefits:
32
38
 
33
- - Secret, VPC, Sg & alarmTopics automatically
34
- - Stack validation with StackCheckingAspect
35
- - Easier configuration with StackConfiguration
39
+ - Secret, VPC, Sg & alarmTopics automatically
40
+ - Stack validation with StackCheckingAspect
41
+ - Easier configuration with StackConfiguration
36
42
 
37
43
  If you do not need those things, you should not use DigitrafficStack.
38
44
 
39
45
  ### StackConfiguration
40
46
 
41
- Some commonly used parameters is predefined configuration. You can write configuration for your
42
- environments once and use across cdk-projects.
47
+ Some commonly used parameters is predefined configuration. You can write
48
+ configuration for your environments once and use across cdk-projects.
43
49
 
44
50
  ### StackCheckingAspect
45
51
 
46
52
  Uses cdk aspects to do some sanity checking for your cdk stack:
47
53
 
48
- - Stack naming check(Test/Prod in name)
49
- - Function configuration(memory, timeout, runtime, reservedConcurrency)
50
- - Tags, must have Solution tag defined
51
- - S3 Buckets, no public access
52
- - Api Gateway resource casing(kebabCase and snake_case)
53
- - Queue encrypting
54
- - LogGroup Retention
54
+ - Stack naming check(Test/Prod in name)
55
+ - Function configuration(memory, timeout, runtime, reservedConcurrency)
56
+ - Tags, must have Solution tag defined
57
+ - S3 Buckets, no public access
58
+ - Api Gateway resource casing(kebabCase and snake_case)
59
+ - Queue encrypting
60
+ - LogGroup Retention
55
61
 
56
- You can use StackCheckingAspect for any stack, DigitrafficStack does it automatically, but you can call it manually:
62
+ You can use StackCheckingAspect for any stack, DigitrafficStack does it
63
+ automatically, but you can call it manually:
57
64
 
58
65
  ```
59
66
  Aspects.of(this).add(StackCheckingAspect.create(this));
60
67
  ```
61
68
 
62
- Any resource can be whitelisted by giving it as a parameter or in the StackConfiguration
69
+ Any resource can be whitelisted by giving it as a parameter or in the
70
+ StackConfiguration
63
71
 
64
72
  ### MonitoredFunction
65
73
 
66
74
  MonitoredFunction extends Function with alarms on memory usage and timeouts.
67
75
 
68
- If you need database access in your Function, you can use MonitoredDBFunction. Creating a Function with it is this easy:
76
+ If you need database access in your Function, you can use MonitoredDBFunction.
77
+ Creating a Function with it is this easy:
69
78
 
70
79
  ```
71
80
  const lambda = MonitoredDBFunction.create(stack, 'get-metadata');
72
81
  ```
73
82
 
74
83
  See the documentation for more information.
75
-
@@ -1,4 +1,4 @@
1
- import { DatabaseEnvironmentKeys, initDbConnection } from "../database/database.js";
1
+ import { DatabaseEnvironmentKeys, initDbConnection, } from "../database/database.js";
2
2
  import { getEnvVariableOrElse } from "../utils/utils.js";
3
3
  export async function assertCount(db, sql, count) {
4
4
  await db.one(sql).then((x) => expect(x.count).toEqual(count));
@@ -15,11 +15,15 @@ describe("acl-builder tests", () => {
15
15
  expect(acl.rules).toHaveLength(4);
16
16
  });
17
17
  test("two aws rules", () => {
18
- const acl = createBuilder().withAWSManagedRules(["CommonRuleSet", "AmazonIpReputationList"]).build();
18
+ const acl = createBuilder().withAWSManagedRules([
19
+ "CommonRuleSet",
20
+ "AmazonIpReputationList",
21
+ ]).build();
19
22
  expect(acl.rules).toHaveLength(2);
20
23
  });
21
24
  test("ip restriction", () => {
22
- const acl = createBuilder().withIpRestrictionRule(["1.2.3.4", "1.2.6.6"]).build();
25
+ const acl = createBuilder().withIpRestrictionRule(["1.2.3.4", "1.2.6.6"])
26
+ .build();
23
27
  expect(acl.rules).toHaveLength(1);
24
28
  });
25
29
  test("throttle rules", () => {
@@ -32,15 +36,19 @@ describe("acl-builder tests", () => {
32
36
  const acl = aclBuilder.build();
33
37
  // Check that the rule exists and a custom response is defined
34
38
  expect(acl.rules).toHaveLength(1);
35
- expect(Object.keys(acl.customResponseBodies)).toHaveLength(1);
39
+ expect(Object.keys(acl.customResponseBodies))
40
+ .toHaveLength(1);
36
41
  // Check that the rule does throttle
37
42
  const throttleRule = acl.rules[0];
38
- expect(throttleRule.statement.rateBasedStatement).toBeDefined();
39
- expect(throttleRule.action.block).toBeDefined();
43
+ expect(throttleRule.statement
44
+ .rateBasedStatement).toBeDefined();
45
+ expect(throttleRule.action.block)
46
+ .toBeDefined();
40
47
  }
41
48
  });
42
49
  test("Cannot define two rules with the same name", () => {
43
- expect(() => createBuilder().withThrottleAnonymousUserIp(10).withThrottleAnonymousUserIp(200).build()).toThrow();
50
+ expect(() => createBuilder().withThrottleAnonymousUserIp(10)
51
+ .withThrottleAnonymousUserIp(200).build()).toThrow();
44
52
  });
45
53
  test("throtle rule without limit does nothing", () => {
46
54
  for (const aclBuilder of [
@@ -5,7 +5,8 @@ import { MediaType } from "../../../aws/types/mediatypes.js";
5
5
  import velocity from "velocityjs";
6
6
  describe("integration tests", () => {
7
7
  function createTemplate(i) {
8
- const template = i.createRequestTemplates()[MediaType.APPLICATION_JSON].trim();
8
+ const template = i.createRequestTemplates()[MediaType.APPLICATION_JSON]
9
+ .trim();
9
10
  // assert template parses
10
11
  const response = createResponseFromTemplate(template);
11
12
  // assert response parses
@@ -19,9 +20,9 @@ describe("integration tests", () => {
19
20
  method: {
20
21
  request: {
21
22
  multivaluequerystring: {
22
- m1: ["multi1", "multi2"]
23
- }
24
- }
23
+ m1: ["multi1", "multi2"],
24
+ },
25
+ },
25
26
  },
26
27
  input: {
27
28
  params: () => ({
@@ -30,24 +31,24 @@ describe("integration tests", () => {
30
31
  },
31
32
  querystring: {
32
33
  q1: "querystring1",
33
- q2: "querystring2"
34
+ q2: "querystring2",
34
35
  },
35
36
  path: {
36
- p1: "path1"
37
+ p1: "path1",
37
38
  },
38
- })
39
+ }),
39
40
  },
40
41
  util: {
41
42
  base64Decode: (data) => Buffer.from(data, "base64").toString(),
42
43
  escapeJavaScript: (data) => encodeURIComponent(data),
43
- parseJson: (data) => JSON.stringify(data)
44
+ parseJson: (data) => JSON.stringify(data),
44
45
  },
45
46
  context: {
46
47
  c1: "context1",
47
48
  authorizer: {
48
- c2: "context2"
49
- }
50
- }
49
+ c2: "context2",
50
+ },
51
+ },
51
52
  });
52
53
  }
53
54
  function createIntegration() {
@@ -70,7 +71,7 @@ describe("integration tests", () => {
70
71
  .addQueryParameter("q1");
71
72
  const t = createTemplate(i);
72
73
  expect(t).toEqual({
73
- q1: "querystring1"
74
+ q1: "querystring1",
74
75
  });
75
76
  });
76
77
  test("two query parameters", () => {
@@ -80,7 +81,7 @@ describe("integration tests", () => {
80
81
  const t = createTemplate(i);
81
82
  expect(t).toEqual({
82
83
  q1: "querystring1",
83
- q2: "querystring2"
84
+ q2: "querystring2",
84
85
  });
85
86
  });
86
87
  test("multivaluequery parameter", () => {
@@ -88,7 +89,7 @@ describe("integration tests", () => {
88
89
  .addMultiValueQueryParameter("m1");
89
90
  const t = createTemplate(i);
90
91
  expect(t).toEqual({
91
- m1: ["multi1", "multi2"]
92
+ m1: ["multi1", "multi2"],
92
93
  });
93
94
  });
94
95
  test("all parameters", () => {
@@ -97,7 +98,7 @@ describe("integration tests", () => {
97
98
  const t = createTemplate(i);
98
99
  expect(t).toEqual({
99
100
  q1: "querystring1",
100
- q2: "querystring2"
101
+ q2: "querystring2",
101
102
  });
102
103
  });
103
104
  test("path parameter", () => {
@@ -105,7 +106,7 @@ describe("integration tests", () => {
105
106
  .addPathParameter("p1");
106
107
  const t = createTemplate(i);
107
108
  expect(t).toEqual({
108
- p1: "path1"
109
+ p1: "path1",
109
110
  });
110
111
  });
111
112
  test("context parameter", () => {
@@ -113,7 +114,7 @@ describe("integration tests", () => {
113
114
  .addContextParameter("c1");
114
115
  const t = createTemplate(i);
115
116
  expect(t).toEqual({
116
- c1: "context1"
117
+ c1: "context1",
117
118
  });
118
119
  });
119
120
  test("context parameter authorizer", () => {
@@ -121,7 +122,7 @@ describe("integration tests", () => {
121
122
  .addContextParameter("authorizer.c2");
122
123
  const t = createTemplate(i);
123
124
  expect(t).toEqual({
124
- "authorizer.c2": "context2"
125
+ "authorizer.c2": "context2",
125
126
  });
126
127
  });
127
128
  test("all parameters and header", () => {
@@ -132,7 +133,7 @@ describe("integration tests", () => {
132
133
  expect(t).toEqual({
133
134
  h1: "header1",
134
135
  q1: "querystring1",
135
- q2: "querystring2"
136
+ q2: "querystring2",
136
137
  });
137
138
  });
138
139
  test("all parameters & parameter - fail", () => {
@@ -150,7 +151,7 @@ describe("integration tests", () => {
150
151
  expect(t).toEqual({
151
152
  p1: "path1",
152
153
  q1: "querystring1",
153
- q2: "querystring2"
154
+ q2: "querystring2",
154
155
  });
155
156
  });
156
157
  });
@@ -3,7 +3,8 @@ import { DigitrafficStaticIntegration } from "../../../aws/infra/api/static-inte
3
3
  import { MediaType } from "../../../aws/types/mediatypes.js";
4
4
  describe("response tests", () => {
5
5
  it("createIntegrationResponse works", () => {
6
- const integrationResponse = DigitrafficStaticIntegration.createIntegrationResponse("FakeResource", MediaType.APPLICATION_JSON, { "test-header": "test-value" });
6
+ const integrationResponse = DigitrafficStaticIntegration
7
+ .createIntegrationResponse("FakeResource", MediaType.APPLICATION_JSON, { "test-header": "test-value" });
7
8
  expect(integrationResponse).toEqual({
8
9
  responseParameters: {
9
10
  "method.response.header.test-header": "'test-value'",
@@ -16,13 +17,13 @@ describe("response tests", () => {
16
17
  });
17
18
  it("createMethodResponse works", () => {
18
19
  const methodResponse = DigitrafficStaticIntegration.createMethodResponse({
19
- "test-header": "test-value"
20
+ "test-header": "test-value",
20
21
  }, MediaType.TEXT_PLAIN, Model.EMPTY_MODEL);
21
22
  expect(methodResponse).toEqual({
22
23
  responseModels: {
23
24
  "text/plain": {
24
- modelId: "Empty"
25
- }
25
+ modelId: "Empty",
26
+ },
26
27
  },
27
28
  responseParameters: {
28
29
  "method.response.header.test-header": true,
@@ -38,7 +38,8 @@ describe("IdUtils tests", () => {
38
38
  expect(IdUtils.isValidMMSI(getRandomNumber(0, 100000000 - 1))).toBe(false);
39
39
  });
40
40
  test("isValidMMSI - fail with number larger than 999999999", () => {
41
- expect(IdUtils.isValidMMSI(getRandomNumber(999999999 + 1, 9999999999))).toBe(false);
41
+ expect(IdUtils.isValidMMSI(getRandomNumber(999999999 + 1, 9999999999)))
42
+ .toBe(false);
42
43
  });
43
44
  });
44
45
  //# sourceMappingURL=id_utils.test.js.map
@@ -75,7 +75,8 @@ describe("Promise utils tests", () => {
75
75
  });
76
76
  test("retry - exceeded retry count throws error", async () => {
77
77
  const fn = jest.fn(() => Promise.reject("error"));
78
- await expect(() => retry(fn, 3, RetryLogError.LOG_ALL_AS_ERRORS)).rejects.toThrow();
78
+ await expect(() => retry(fn, 3, RetryLogError.LOG_ALL_AS_ERRORS)).rejects
79
+ .toThrow();
79
80
  });
80
81
  test("retry - defaults", async () => {
81
82
  const fn = jest.fn(() => Promise.reject("error"));
@@ -93,11 +94,13 @@ describe("Promise utils tests", () => {
93
94
  });
94
95
  test("retry - NaN throws error", async () => {
95
96
  const fn = jest.fn(() => Promise.resolve(NaN));
96
- await expect(() => retry(fn, NaN, RetryLogError.NO_LOGGING)).rejects.toThrow();
97
+ await expect(() => retry(fn, NaN, RetryLogError.NO_LOGGING)).rejects
98
+ .toThrow();
97
99
  });
98
100
  test("retry - Infinity throws error", async () => {
99
101
  const fn = jest.fn(() => Promise.resolve(NaN));
100
- await expect(() => retry(fn, Infinity, RetryLogError.NO_LOGGING)).rejects.toThrow();
102
+ await expect(() => retry(fn, Infinity, RetryLogError.NO_LOGGING)).rejects
103
+ .toThrow();
101
104
  });
102
105
  test("retry - exceeded maximum retry count throws error", async () => {
103
106
  const fn = jest.fn(() => Promise.resolve(NaN));
@@ -1,5 +1,5 @@
1
1
  import { Writable } from "stream";
2
- import { DtLogger } from "../../aws/runtime/dt-logger.js";
2
+ import { DtLogger, } from "../../aws/runtime/dt-logger.js";
3
3
  const LOG_LINE = {
4
4
  method: "dt-logger.test",
5
5
  message: "FOO",
@@ -18,7 +18,10 @@ function mockSecret(secret) {
18
18
  getSecretValueMock.mockImplementation(() => Promise.resolve(emptySecret));
19
19
  }
20
20
  else {
21
- getSecretValueMock.mockImplementation(() => Promise.resolve({ ...emptySecret, ...{ SecretString: JSON.stringify(secret) } }));
21
+ getSecretValueMock.mockImplementation(() => Promise.resolve({
22
+ ...emptySecret,
23
+ ...{ SecretString: JSON.stringify(secret) },
24
+ }));
22
25
  }
23
26
  }
24
27
  describe("SecretHolder - tests", () => {
@@ -16,7 +16,10 @@ function mockSecret(secret) {
16
16
  getSecretValueMock.mockImplementation(() => Promise.resolve(emptySecret));
17
17
  }
18
18
  else {
19
- getSecretValueMock.mockImplementation(() => Promise.resolve({ ...emptySecret, ...{ SecretString: JSON.stringify(secret) } }));
19
+ getSecretValueMock.mockImplementation(() => Promise.resolve({
20
+ ...emptySecret,
21
+ ...{ SecretString: JSON.stringify(secret) },
22
+ }));
20
23
  }
21
24
  }
22
25
  // eslint-disable-next-line dot-notation
@@ -20,7 +20,9 @@ describe("Rest api test", () => {
20
20
  const testsResource = publicApi.addResourceWithCorsOptionsSubTree(versionResource, "tests");
21
21
  testsResource.addResource("{testId}");
22
22
  const template = Template.fromStack(stack);
23
- template.resourcePropertiesCountIs("AWS::ApiGateway::Method", { HttpMethod: "OPTIONS" }, 2);
23
+ template.resourcePropertiesCountIs("AWS::ApiGateway::Method", {
24
+ HttpMethod: "OPTIONS",
25
+ }, 2);
24
26
  template.hasResource("AWS::ApiGateway::Method", {
25
27
  Properties: {
26
28
  HttpMethod: "OPTIONS",
@@ -31,7 +31,8 @@ describe("lambda-response", () => {
31
31
  assertJson(response, TEST_JSON, 200, TEST_FILENAME);
32
32
  });
33
33
  test("okJson - with fileName and timestamp", () => {
34
- const response = LambdaResponse.okJson(TEST_JSON, TEST_FILENAME).withTimestamp(TEST_TIMESTAMP);
34
+ const response = LambdaResponse.okJson(TEST_JSON, TEST_FILENAME)
35
+ .withTimestamp(TEST_TIMESTAMP);
35
36
  assertJson(response, TEST_JSON, 200, TEST_FILENAME, TEST_TIMESTAMP);
36
37
  });
37
38
  test("okBinary - with fileName and timestamp", () => {
@@ -11,7 +11,8 @@ describe("ArrayUtils", () => {
11
11
  expect(ArrayUtils.bothArraysHasSameValues(["a"], undefined)).toEqual(false);
12
12
  expect(ArrayUtils.bothArraysHasSameValues(["a"], null)).toEqual(false);
13
13
  expect(ArrayUtils.bothArraysHasSameValues(["a", "b"], ["a", "a"])).toEqual(false);
14
- expect(ArrayUtils.bothArraysHasSameValues(["a", "a", "a"], ["a", "b", "c"])).toEqual(false);
14
+ expect(ArrayUtils.bothArraysHasSameValues(["a", "a", "a"], ["a", "b", "c"]))
15
+ .toEqual(false);
15
16
  const o1 = { a: 1, b: 2 };
16
17
  const o2 = { a: 1, b: 2 };
17
18
  // Objects are references to same
@@ -39,7 +40,11 @@ describe("ArrayUtils", () => {
39
40
  expect(ArrayUtils.getLast([1, 2])).toEqual(2);
40
41
  });
41
42
  test("isDefined", () => {
42
- expect([1, 2, undefined, null, 3].filter(ArrayUtils.isDefined)).toEqual([1, 2, 3]);
43
+ expect([1, 2, undefined, null, 3].filter(ArrayUtils.isDefined)).toEqual([
44
+ 1,
45
+ 2,
46
+ 3,
47
+ ]);
43
48
  });
44
49
  });
45
50
  //# sourceMappingURL=utils.test.js.map
@@ -1,6 +1,6 @@
1
1
  import { CfnIPSet, CfnWebACL } from "aws-cdk-lib/aws-wafv2";
2
2
  import { logger } from "../runtime/dt-logger-default.js";
3
- import { zipWith, range, concat } from "lodash-es";
3
+ import { concat, range, zipWith } from "lodash-es";
4
4
  /**
5
5
  * Builder class for building CfnWebACL.
6
6
  *
@@ -243,7 +243,9 @@ function createThrottleStatement(limit, isHeaderRequired, isBasedOnIpAndUriPath)
243
243
  aggregateKeyType: "CUSTOM_KEYS",
244
244
  customKeys: CUSTOM_KEYS_IP_AND_URI_PATH,
245
245
  limit: limit,
246
- scopeDownStatement: isHeaderRequired ? matchStatement : notStatement(matchStatement),
246
+ scopeDownStatement: isHeaderRequired
247
+ ? matchStatement
248
+ : notStatement(matchStatement),
247
249
  },
248
250
  };
249
251
  }
@@ -251,7 +253,9 @@ function createThrottleStatement(limit, isHeaderRequired, isBasedOnIpAndUriPath)
251
253
  rateBasedStatement: {
252
254
  aggregateKeyType: "IP",
253
255
  limit: limit,
254
- scopeDownStatement: isHeaderRequired ? matchStatement : notStatement(matchStatement),
256
+ scopeDownStatement: isHeaderRequired
257
+ ? matchStatement
258
+ : notStatement(matchStatement),
255
259
  },
256
260
  };
257
261
  }
@@ -1,4 +1,4 @@
1
- import { LambdaIntegration, PassthroughBehavior } from "aws-cdk-lib/aws-apigateway";
1
+ import { LambdaIntegration, PassthroughBehavior, } from "aws-cdk-lib/aws-apigateway";
2
2
  import { MediaType } from "../../types/mediatypes.js";
3
3
  import { DigitrafficIntegrationResponse } from "../../runtime/digitraffic-integration-response.js";
4
4
  const VELOCITY_ALL_PARAMS = `#foreach($paramName in $params.keySet())
@@ -20,8 +20,9 @@ export class DigitrafficIntegration {
20
20
  this._passBody = false;
21
21
  }
22
22
  passAllQueryParameters() {
23
- if (this.parameters.some((p) => p.type === "querystring"))
23
+ if (this.parameters.some((p) => p.type === "querystring")) {
24
24
  throw new Error("Can't add query parameters with pass all");
25
+ }
25
26
  this._passAllQueryParameters = true;
26
27
  return this;
27
28
  }
@@ -38,8 +39,9 @@ export class DigitrafficIntegration {
38
39
  return this;
39
40
  }
40
41
  addQueryParameter(...names) {
41
- if (this._passAllQueryParameters)
42
+ if (this._passAllQueryParameters) {
42
43
  throw new Error("Can't add query parameters with pass all");
44
+ }
43
45
  names.forEach((name) => this.parameters.push({ type: "querystring", name }));
44
46
  return this;
45
47
  }
@@ -1,6 +1,6 @@
1
1
  import { BadRequestResponseTemplate, InternalServerErrorResponseTemplate, NotFoundResponseTemplate, XmlResponseTemplate, } from "./response.js";
2
2
  import { LambdaIntegration, PassthroughBehavior, } from "aws-cdk-lib/aws-apigateway";
3
- import { BAD_REQUEST_MESSAGE, ERROR_MESSAGE, NOT_FOUND_MESSAGE } from "../../types/errors.js";
3
+ import { BAD_REQUEST_MESSAGE, ERROR_MESSAGE, NOT_FOUND_MESSAGE, } from "../../types/errors.js";
4
4
  /// @deprecated
5
5
  export const RESPONSE_200_OK = {
6
6
  statusCode: "200",
@@ -63,7 +63,8 @@ export function defaultIntegration(lambdaFunction, options) {
63
63
  ],
64
64
  requestParameters: options?.requestParameters ?? {},
65
65
  requestTemplates: options?.requestTemplates ?? {},
66
- passthroughBehavior: options?.passthroughBehavior ?? PassthroughBehavior.WHEN_NO_MATCH,
66
+ passthroughBehavior: options?.passthroughBehavior ??
67
+ PassthroughBehavior.WHEN_NO_MATCH,
67
68
  });
68
69
  }
69
70
  export function getResponse(response, options) {
@@ -15,7 +15,8 @@ export class DigitrafficStaticIntegration extends MockIntegration {
15
15
  if (enableCors) {
16
16
  headers = { ...headers, "Access-Control-Allow-Origin": "*" };
17
17
  }
18
- const integrationResponse = DigitrafficStaticIntegration.createIntegrationResponse(response, mediaType, headers);
18
+ const integrationResponse = DigitrafficStaticIntegration
19
+ .createIntegrationResponse(response, mediaType, headers);
19
20
  super({
20
21
  passthroughBehavior: PassthroughBehavior.WHEN_NO_TEMPLATES,
21
22
  requestTemplates: {
@@ -26,7 +27,9 @@ export class DigitrafficStaticIntegration extends MockIntegration {
26
27
  ["GET", "HEAD"].forEach((httpMethod) => {
27
28
  resource.addMethod(httpMethod, this, {
28
29
  apiKeyRequired,
29
- methodResponses: [DigitrafficStaticIntegration.createMethodResponse(headers, mediaType, model)],
30
+ methodResponses: [
31
+ DigitrafficStaticIntegration.createMethodResponse(headers, mediaType, model),
32
+ ],
30
33
  });
31
34
  });
32
35
  }
@@ -50,8 +53,8 @@ export class DigitrafficStaticIntegration extends MockIntegration {
50
53
  statusCode: "200",
51
54
  responseParameters: prefixKeys("method.response.header.", entries),
52
55
  responseModels: {
53
- [mediaType]: model
54
- }
56
+ [mediaType]: model,
57
+ },
55
58
  };
56
59
  }
57
60
  }
@@ -22,7 +22,9 @@ export class DigitrafficCanaryRole extends Role {
22
22
  constructor(stack, canaryName) {
23
23
  super(stack, "canary-role-" + canaryName, {
24
24
  assumedBy: new ServicePrincipal("lambda.amazonaws.com"),
25
- managedPolicies: [ManagedPolicy.fromAwsManagedPolicyName("CloudWatchSyntheticsFullAccess")],
25
+ managedPolicies: [
26
+ ManagedPolicy.fromAwsManagedPolicyName("CloudWatchSyntheticsFullAccess"),
27
+ ],
26
28
  });
27
29
  this.addToPolicy(new PolicyStatement(BASE_POLICY_STATEMENT_PROPS));
28
30
  this.addToPolicy(new PolicyStatement(CLOUDWATCH_STATEMENT_PROPS));
@@ -1,5 +1,5 @@
1
1
  import { Duration } from "aws-cdk-lib";
2
- import { AssetCode, Canary, Runtime, Schedule, Test } from "aws-cdk-lib/aws-synthetics";
2
+ import { AssetCode, Canary, Runtime, Schedule, Test, } from "aws-cdk-lib/aws-synthetics";
3
3
  import { CanaryAlarm } from "./canary-alarm.js";
4
4
  export class DigitrafficCanary extends Canary {
5
5
  constructor(scope, canaryName, role, params, environmentVariables) {
@@ -12,8 +12,12 @@ export class DatabaseCanary extends DigitrafficCanary {
12
12
  secret.grantRead(this.role);
13
13
  // need to override vpc and security group, can't do this with cdk
14
14
  if (this.node.defaultChild instanceof CfnCanary) {
15
- const subnetIds = stack.vpc === undefined ? [] : stack.vpc.privateSubnets.map((subnet) => subnet.subnetId);
16
- const securityGroupIds = stack.lambdaDbSg === undefined ? [] : [stack.lambdaDbSg.securityGroupId];
15
+ const subnetIds = stack.vpc === undefined
16
+ ? []
17
+ : stack.vpc.privateSubnets.map((subnet) => subnet.subnetId);
18
+ const securityGroupIds = stack.lambdaDbSg === undefined
19
+ ? []
20
+ : [stack.lambdaDbSg.securityGroupId];
17
21
  this.node.defaultChild.vpcConfig = {
18
22
  vpcId: stack.vpc?.vpcId,
19
23
  securityGroupIds,
@@ -1,4 +1,4 @@
1
- import { inDatabaseReadonly } from "../../../database/database.js";
1
+ import { inDatabaseReadonly, } from "../../../database/database.js";
2
2
  import { ProxyHolder } from "../../runtime/secrets/proxy-holder.js";
3
3
  import { RdsHolder } from "../../runtime/secrets/rds-holder.js";
4
4
  import { getEnvVariable } from "../../../utils/utils.js";
@@ -25,10 +25,12 @@ class CountDatabaseCheck extends DatabaseCheck {
25
25
  // eslint-disable-next-line @rushstack/no-new-null
26
26
  maxCount) {
27
27
  super(name, sql);
28
- if (!sql.toLowerCase().includes("select") || !sql.toLowerCase().includes("count")) {
28
+ if (!sql.toLowerCase().includes("select") ||
29
+ !sql.toLowerCase().includes("count")) {
29
30
  throw new Error("sql must contain select count(*)");
30
31
  }
31
- if ((minCount === null || minCount === undefined) && (maxCount === null || maxCount === undefined)) {
32
+ if ((minCount === null || minCount === undefined) &&
33
+ (maxCount === null || maxCount === undefined)) {
32
34
  throw new Error("no max or min given");
33
35
  }
34
36
  this.minCount = minCount;
@@ -18,8 +18,12 @@ export class UrlCanary extends DigitrafficCanary {
18
18
  // the handler code is defined at the actual project using this
19
19
  super(stack, canaryName, role, params, environmentVariables);
20
20
  if (params.inVpc && this.node.defaultChild instanceof CfnCanary) {
21
- const subnetIds = stack.vpc === undefined ? [] : stack.vpc.privateSubnets.map((subnet) => subnet.subnetId);
22
- const securityGroupIds = stack.lambdaDbSg === undefined ? [] : [stack.lambdaDbSg.securityGroupId];
21
+ const subnetIds = stack.vpc === undefined
22
+ ? []
23
+ : stack.vpc.privateSubnets.map((subnet) => subnet.subnetId);
24
+ const securityGroupIds = stack.lambdaDbSg === undefined
25
+ ? []
26
+ : [stack.lambdaDbSg.securityGroupId];
23
27
  this.node.defaultChild.vpcConfig = {
24
28
  vpcId: stack.vpc?.vpcId,
25
29
  securityGroupIds,
@@ -77,7 +77,8 @@ export class UrlChecker {
77
77
  return synthetics.executeHttpStep(`Verify 400 for ${url}`, requestOptions, validateStatusCodeAndContentType(400, MediaType.TEXT_PLAIN));
78
78
  }
79
79
  expect403WithoutApiKey(url, mediaType) {
80
- if (!this.requestOptions.headers || !this.requestOptions.headers[API_KEY_HEADER]) {
80
+ if (!this.requestOptions.headers ||
81
+ !this.requestOptions.headers[API_KEY_HEADER]) {
81
82
  logger.error({
82
83
  method: "UrlChecker.expect403WithoutApiKey",
83
84
  message: "No Api-key defined",
@@ -1,4 +1,4 @@
1
- import { CfnDocumentationPart } from "aws-cdk-lib/aws-apigateway";
1
+ import { CfnDocumentationPart, } from "aws-cdk-lib/aws-apigateway";
2
2
  // Documentation parts are objects that describe an API Gateway API or parts of an API
3
3
  // https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-documenting-api.html
4
4
  /**
@@ -25,7 +25,9 @@ export function attachQueueToApiGatewayResource(stack, queue, resource, requestV
25
25
  ],
26
26
  }));
27
27
  // create an integration between API Gateway and an SQS queue
28
- const fifoMessageGroupId = queue.fifo ? "&MessageGroupId=AlwaysSameFifoGroup" : "";
28
+ const fifoMessageGroupId = queue.fifo
29
+ ? "&MessageGroupId=AlwaysSameFifoGroup"
30
+ : "";
29
31
  const sqsIntegration = new AwsIntegration({
30
32
  service: "sqs",
31
33
  integrationHttpMethod: "POST",
@@ -5,10 +5,10 @@ import { PolicyStatement } from "aws-cdk-lib/aws-iam";
5
5
  import { InlineCode, Runtime } from "aws-cdk-lib/aws-lambda";
6
6
  import { RetentionDays } from "aws-cdk-lib/aws-logs";
7
7
  import { SqsEventSource } from "aws-cdk-lib/aws-lambda-event-sources";
8
- import { ComparisonOperator, TreatMissingData } from "aws-cdk-lib/aws-cloudwatch";
8
+ import { ComparisonOperator, TreatMissingData, } from "aws-cdk-lib/aws-cloudwatch";
9
9
  import { SnsAction } from "aws-cdk-lib/aws-cloudwatch-actions";
10
10
  import { MonitoredFunction } from "./stack/monitoredfunction.js";
11
- import { PutObjectCommand, S3Client } from "@aws-sdk/client-s3";
11
+ import { PutObjectCommand, S3Client, } from "@aws-sdk/client-s3";
12
12
  import { logger } from "../runtime/dt-logger-default.js";
13
13
  const DLQ_LAMBDA_CODE = `
14
14
  import type { ObjectCannedACL } from "@aws-sdk/client-s3";
@@ -52,7 +52,7 @@ export class DigitrafficSqsQueue extends Queue {
52
52
  const queueProps = {
53
53
  ...props,
54
54
  encryption: QueueEncryption.KMS_MANAGED,
55
- queueName
55
+ queueName,
56
56
  };
57
57
  return new DigitrafficSqsQueue(stack, queueName, queueProps);
58
58
  }
@@ -1,4 +1,4 @@
1
- import { Architecture, AssetCode, Runtime } from "aws-cdk-lib/aws-lambda";
1
+ import { Architecture, AssetCode, Runtime, } from "aws-cdk-lib/aws-lambda";
2
2
  import { Duration } from "aws-cdk-lib";
3
3
  import { RetentionDays } from "aws-cdk-lib/aws-logs";
4
4
  export function databaseFunctionProps(stack, environment, lambdaName, simpleLambdaName, config) {
@@ -32,7 +32,9 @@ export function lambdaFunctionProps(_, environment, lambdaName, simpleLambdaName
32
32
  };
33
33
  }
34
34
  function getAssetCode(simpleLambdaName, isSingleLambda) {
35
- const lambdaPath = isSingleLambda ? `dist/lambda/` : `dist/lambda/${simpleLambdaName}`;
35
+ const lambdaPath = isSingleLambda
36
+ ? `dist/lambda/`
37
+ : `dist/lambda/${simpleLambdaName}`;
36
38
  return new AssetCode(lambdaPath);
37
39
  }
38
40
  export function defaultLambdaConfiguration(config) {
@@ -79,10 +79,12 @@ export class MonitoredFunction extends Function {
79
79
  * @param props Monitored function properties
80
80
  */
81
81
  static create(stack, id, functionProps, props) {
82
- if (props === MonitoredFunction.DISABLE_ALARMS && stack.configuration.production) {
82
+ if (props === MonitoredFunction.DISABLE_ALARMS &&
83
+ stack.configuration.production) {
83
84
  throw new Error(
84
85
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
85
- `Function ${functionProps.functionName} has DISABLE_ALARMS. Remove before installing to production or define your own properties!`);
86
+ `Function ${functionProps
87
+ .functionName} has DISABLE_ALARMS. Remove before installing to production or define your own properties!`);
86
88
  }
87
89
  return new MonitoredFunction(stack, id, functionProps, stack.alarmTopic, stack.warningTopic, stack.configuration.production, stack.configuration.trafficType, props);
88
90
  }
@@ -114,7 +116,8 @@ export class MonitoredFunction extends Function {
114
116
  threshold: alarmProps?.threshold ?? threshold,
115
117
  evaluationPeriods: alarmProps?.evaluationPeriods ?? evaluationPeriods,
116
118
  datapointsToAlarm: alarmProps?.datapointsToAlarm ?? datapointsToAlarm,
117
- comparisonOperator: alarmProps?.comparisonOperator ?? comparisonOperator,
119
+ comparisonOperator: alarmProps?.comparisonOperator ??
120
+ comparisonOperator,
118
121
  })
119
122
  .addAlarmAction(alarmSnsAction);
120
123
  }
@@ -1,5 +1,5 @@
1
1
  import { CfnDocumentationPart, Cors, EndpointType, GatewayResponse, MethodLoggingLevel, ResponseType, RestApi, } from "aws-cdk-lib/aws-apigateway";
2
- import { AnyPrincipal, Effect, PolicyDocument, PolicyStatement } from "aws-cdk-lib/aws-iam";
2
+ import { AnyPrincipal, Effect, PolicyDocument, PolicyStatement, } from "aws-cdk-lib/aws-iam";
3
3
  import { getModelReference } from "../../../utils/api-model.js";
4
4
  import { MediaType } from "../../types/mediatypes.js";
5
5
  import { createDefaultUsagePlan, createUsagePlan } from "../usage-plans.js";
@@ -39,7 +39,8 @@ export class DigitrafficRestApi extends RestApi {
39
39
  };
40
40
  super(stack, apiId, apiConfig);
41
41
  this.apiKeyIds = [];
42
- this.enableDocumentation = stack.configuration.stackFeatures?.enableDocumentation ?? true;
42
+ this.enableDocumentation =
43
+ stack.configuration.stackFeatures?.enableDocumentation ?? true;
43
44
  add404Support(this, stack);
44
45
  }
45
46
  hostname() {
@@ -146,7 +146,8 @@ export class StackCheckingAspect {
146
146
  if (name === undefined) {
147
147
  throw Error("Name should not be undefined");
148
148
  }
149
- if (type === "querystring" && !StackCheckingAspect.isValidQueryString(name)) {
149
+ if (type === "querystring" &&
150
+ !StackCheckingAspect.isValidQueryString(name)) {
150
151
  this.addAnnotation(node, name, "Querystring should be in snake_case");
151
152
  }
152
153
  });
@@ -1,5 +1,5 @@
1
1
  import { Aspects, Stack } from "aws-cdk-lib";
2
- import { SecurityGroup, Vpc } from "aws-cdk-lib/aws-ec2";
2
+ import { SecurityGroup, Vpc, } from "aws-cdk-lib/aws-ec2";
3
3
  import { Topic } from "aws-cdk-lib/aws-sns";
4
4
  import { StringParameter } from "aws-cdk-lib/aws-ssm";
5
5
  import { Secret } from "aws-cdk-lib/aws-secretsmanager";
@@ -1,6 +1,6 @@
1
1
  import { Duration, RemovalPolicy, Stack } from "aws-cdk-lib";
2
2
  import {} from "constructs";
3
- import { PrivateHostedZone, RecordSet, RecordTarget, RecordType } from "aws-cdk-lib/aws-route53";
3
+ import { PrivateHostedZone, RecordSet, RecordTarget, RecordType, } from "aws-cdk-lib/aws-route53";
4
4
  import { importVpc } from "../import-util.js";
5
5
  import { getParameterValue } from "../stack/parameters.js";
6
6
  const DEFAULT_RECORD_TTL = Duration.seconds(30);
@@ -23,18 +23,21 @@ export interface ClusterConfiguration {
23
23
  readonly securityGroupId: string;
24
24
  readonly snapshotIdentifier?: string;
25
25
  readonly dbVersion: AuroraPostgresEngineVersion;
26
+ readonly storageEncrypted?: boolean;
26
27
  readonly writer: ClusterDbInstanceConfiguration;
27
28
  readonly readers: ClusterDbInstanceConfiguration[];
28
29
  }
29
30
  export interface ClusterImportConfiguration {
30
31
  readonly clusterReadEndpoint: string;
31
32
  readonly clusterWriteEndpoint: string;
32
- /** Override clusterIdentifier if clusterWriteEndpoint name doesn't contain
33
- * clusterIdentifier before '.cluster' substring.
34
- * clusterWriteEndpoint name that is normally formed stackenv-stackenvxxx-xxx.cluster-xxx.region.rds.amazonaws.com
35
- * and we can parse clusterIdentifier from it. */
36
- readonly clusterIdentifier?: string;
37
33
  }
34
+ /**
35
+ * Parse cluster identifier from cluster writer endpoint.
36
+ * i.e. <i>stackenv-stackenvxxx-xxx.cluster-xxx.region.rds.amazonaws.com</i>
37
+ * -> <i>stackenv-stackenvxxx-xxx</i>
38
+ * @param clusterImport
39
+ */
40
+ export declare function parseClusterIdentifier(clusterImport: ClusterImportConfiguration): string;
38
41
  /**
39
42
  * Stack that creates DatabaseCluster.
40
43
  *
@@ -4,6 +4,22 @@ import { Secret } from "aws-cdk-lib/aws-secretsmanager";
4
4
  import { Duration, RemovalPolicy, Stack } from "aws-cdk-lib/core";
5
5
  import { exportValue, importVpc } from "../import-util.js";
6
6
  import { createParameter } from "../stack/parameters.js";
7
+ /**
8
+ * Parse cluster identifier from cluster writer endpoint.
9
+ * i.e. <i>stackenv-stackenvxxx-xxx.cluster-xxx.region.rds.amazonaws.com</i>
10
+ * -> <i>stackenv-stackenvxxx-xxx</i>
11
+ * @param clusterImport
12
+ */
13
+ export function parseClusterIdentifier(clusterImport) {
14
+ if (clusterImport.clusterWriteEndpoint.includes(".cluster") &&
15
+ clusterImport.clusterWriteEndpoint.split(".cluster")[0]) {
16
+ // @ts-ignore this is checked above
17
+ return clusterImport.clusterWriteEndpoint.split(".cluster")[0];
18
+ }
19
+ throw new Error("Could not resolve 'clusterIdentifier' from 'configuration.clusterImport': " +
20
+ clusterImport.clusterWriteEndpoint +
21
+ ". 'configuration.clusterImport.clusterWriteEndpoint' didn't contain '.cluster'");
22
+ }
7
23
  /**
8
24
  * Stack that creates DatabaseCluster.
9
25
  *
@@ -40,24 +56,7 @@ export class DbStack extends Stack {
40
56
  this.clusterIdentifier = cluster.clusterIdentifier;
41
57
  }
42
58
  if (configuration.clusterImport) {
43
- // If clusterIdentifier is provided we use it and otherwise we try to parse it from
44
- // from clusterWriteEndpoint name that is normally formed stackenv-stackenvxxx-xxx.cluster-xxx.region.rds.amazonaws.com
45
- // and part before .cluster is clusterIdentifier.
46
- if (configuration.clusterImport.clusterIdentifier) {
47
- this.clusterIdentifier = configuration.clusterImport.clusterIdentifier;
48
- }
49
- else if (configuration.clusterImport.clusterWriteEndpoint !== undefined &&
50
- configuration.clusterImport.clusterWriteEndpoint.split('.cluster')[0] !== undefined &&
51
- configuration.clusterImport.clusterWriteEndpoint.split('.cluster')[0] !== configuration.clusterImport.clusterWriteEndpoint) {
52
- // @ts-ignore We check that this is defined
53
- this.clusterIdentifier = configuration.clusterImport.clusterWriteEndpoint.split('.cluster')[0];
54
- }
55
- else {
56
- throw new Error("Could not resolve 'clusterIdentifier' from 'configuration.clusterImport': " +
57
- configuration.clusterImport.clusterWriteEndpoint +
58
- " Either 'configuration.clusterImport.clusterReadEndpoint' didn't contain '.cluster' or " +
59
- "configuration.clusterImport.clusterIdentifier was not defined to override default value.");
60
- }
59
+ this.clusterIdentifier = parseClusterIdentifier(configuration.clusterImport);
61
60
  createParameter(this, "cluster.reader", configuration.clusterImport.clusterReadEndpoint);
62
61
  createParameter(this, "cluster.writer", configuration.clusterImport.clusterWriteEndpoint);
63
62
  createParameter(this, "cluster.identifier", this.clusterIdentifier);
@@ -87,21 +86,21 @@ export class DbStack extends Stack {
87
86
  autoMinorVersionUpgrade: true,
88
87
  allowMajorVersionUpgrade: false,
89
88
  enablePerformanceInsights: true,
90
- parameterGroup: parameterGroup
89
+ parameterGroup: parameterGroup,
91
90
  };
92
91
  const writer = ClusterInstance.provisioned("WriterInstance", {
93
92
  ...{
94
93
  instanceType: clusterConfiguration.writer.instanceType,
95
- isFromLegacyInstanceProps: clusterConfiguration.writer.isFromLegacyInstanceProps
94
+ isFromLegacyInstanceProps: clusterConfiguration.writer.isFromLegacyInstanceProps,
96
95
  },
97
- ...defaultDbInstanceProps
96
+ ...defaultDbInstanceProps,
98
97
  });
99
98
  const readers = clusterConfiguration.readers.map((reader, index) => ClusterInstance.provisioned(`ReaderInstance${index}`, {
100
99
  ...{
101
100
  instanceType: reader.instanceType,
102
101
  isFromLegacyInstanceProps: reader.isFromLegacyInstanceProps,
103
102
  },
104
- ...defaultDbInstanceProps
103
+ ...defaultDbInstanceProps,
105
104
  }));
106
105
  return {
107
106
  engine: DatabaseClusterEngine.auroraPostgres({
@@ -128,12 +127,15 @@ export class DbStack extends Stack {
128
127
  credentials: Credentials.fromPassword(secret.secretValueFromJson("db.superuser").unsafeUnwrap(), secret.secretValueFromJson("db.superuser.password")),
129
128
  parameterGroup,
130
129
  monitoringInterval: Duration.seconds(30),
130
+ storageEncrypted: clusterConfiguration.storageEncrypted ?? true,
131
131
  };
132
132
  }
133
133
  createAuroraCluster(isc, configuration, clusterConfiguration, parameterGroups) {
134
134
  const instanceName = isc.environmentName + "-db";
135
135
  const securityGroup = SecurityGroup.fromSecurityGroupId(this, "securitygroup", clusterConfiguration.securityGroupId);
136
- const vpc = configuration.vpc ? configuration.vpc : importVpc(this, isc.environmentName);
136
+ const vpc = configuration.vpc
137
+ ? configuration.vpc
138
+ : importVpc(this, isc.environmentName);
137
139
  if (parameterGroups[0] === undefined) {
138
140
  throw Error("ParameterGroups should not be empty");
139
141
  }
@@ -1,12 +1,12 @@
1
- import { APIGatewayClient, GetApiKeyCommand } from "@aws-sdk/client-api-gateway";
1
+ import { APIGatewayClient, GetApiKeyCommand, } from "@aws-sdk/client-api-gateway";
2
2
  import { FetchHttpHandler } from "@smithy/fetch-http-handler";
3
3
  export async function getApiKeyFromAPIGateway(keyId) {
4
4
  const client = new APIGatewayClient({
5
- requestHandler: new FetchHttpHandler()
5
+ requestHandler: new FetchHttpHandler(),
6
6
  });
7
7
  const command = new GetApiKeyCommand({
8
8
  apiKey: keyId,
9
- includeValue: true
9
+ includeValue: true,
10
10
  });
11
11
  return (await client.send(command));
12
12
  }
@@ -1,5 +1,5 @@
1
1
  import { MediaType } from "../types/mediatypes.js";
2
- import { getDeprecatedDefaultLambdaResponse, RESPONSE_DEFAULT_LAMBDA } from "../infra/api/response.js";
2
+ import { getDeprecatedDefaultLambdaResponse, RESPONSE_DEFAULT_LAMBDA, } from "../infra/api/response.js";
3
3
  export class DigitrafficIntegrationResponse {
4
4
  static ok(mediaType, sunset) {
5
5
  return this.create("200", mediaType, sunset);
@@ -14,7 +14,9 @@ export class DigitrafficIntegrationResponse {
14
14
  return {
15
15
  statusCode,
16
16
  responseTemplates: {
17
- [mediaType]: sunset ? getDeprecatedDefaultLambdaResponse(sunset) : RESPONSE_DEFAULT_LAMBDA,
17
+ [mediaType]: sunset
18
+ ? getDeprecatedDefaultLambdaResponse(sunset)
19
+ : RESPONSE_DEFAULT_LAMBDA,
18
20
  },
19
21
  };
20
22
  }
@@ -19,9 +19,10 @@ export class DtLogger {
19
19
  * @param {LoggerConfiguration?} [config] - Accepts configuration options @see {@link LoggerConfiguration}
20
20
  */
21
21
  constructor(config) {
22
- this.lambdaName =
23
- config?.lambdaName ?? getEnvVariableOrElse("AWS_LAMBDA_FUNCTION_NAME", "unknown lambda name");
24
- this.runtime = config?.runTime ?? getEnvVariableOrElse("AWS_EXECUTION_ENV", "unknown runtime");
22
+ this.lambdaName = config?.lambdaName ??
23
+ getEnvVariableOrElse("AWS_LAMBDA_FUNCTION_NAME", "unknown lambda name");
24
+ this.runtime = config?.runTime ??
25
+ getEnvVariableOrElse("AWS_EXECUTION_ENV", "unknown runtime");
25
26
  this.writeStream = config?.writeStream ?? process.stdout;
26
27
  }
27
28
  /**
@@ -43,7 +43,9 @@ export class SecretHolder {
43
43
  }
44
44
  async get() {
45
45
  const secret = await this.getSecret();
46
- const parsedSecret = this.prefix === DEFAULT_PREFIX ? secret : this.parseSecret(secret, `${this.prefix}.`);
46
+ const parsedSecret = this.prefix === DEFAULT_PREFIX
47
+ ? secret
48
+ : this.parseSecret(secret, `${this.prefix}.`);
47
49
  if (this.expectedKeys.length > 0) {
48
50
  checkExpectedSecretKeys(this.expectedKeys, parsedSecret);
49
51
  }
@@ -1,5 +1,5 @@
1
1
  import { SecretsManager } from "@aws-sdk/client-secrets-manager";
2
- import { getEnvVariable, getEnvVariableOrElse, getEnvVariableSafe } from "../../../utils/utils.js";
2
+ import { getEnvVariable, getEnvVariableOrElse, getEnvVariableSafe, } from "../../../utils/utils.js";
3
3
  import { EnvKeys } from "../environment.js";
4
4
  // SECRET_OVERRIDE_AWS_REGION might not have been set before import of
5
5
  // secret, so we need to lazy initialize SecretsManager
@@ -9,7 +9,6 @@ export declare enum JSON_CACHE_KEY {
9
9
  NAUTICAL_WARNINGS_ARCHIVED = "nautical-warnings-archived"
10
10
  }
11
11
  /**
12
- *
13
12
  * @param db
14
13
  * @param cacheKey
15
14
  * @param value
@@ -17,7 +17,6 @@ export var JSON_CACHE_KEY;
17
17
  JSON_CACHE_KEY["NAUTICAL_WARNINGS_ARCHIVED"] = "nautical-warnings-archived";
18
18
  })(JSON_CACHE_KEY || (JSON_CACHE_KEY = {}));
19
19
  /**
20
- *
21
20
  * @param db
22
21
  * @param cacheKey
23
22
  * @param value
@@ -11,10 +11,14 @@ function imoChecksumIsValid(imo) {
11
11
  const imoDigit5 = Number(imoStr[4]);
12
12
  const imoDigit6 = Number(imoStr[5]);
13
13
  const checkDigit = Number(imoStr[6]);
14
- const checkCalculation = Number(imoDigit1 * 7 + imoDigit2 * 6 + imoDigit3 * 5 + imoDigit4 * 4 + imoDigit5 * 3 + imoDigit6 * 2);
14
+ const checkCalculation = Number(imoDigit1 * 7 + imoDigit2 * 6 + imoDigit3 * 5 + imoDigit4 * 4 +
15
+ imoDigit5 * 3 + imoDigit6 * 2);
15
16
  const checkResult = checkCalculation % 10 === checkDigit;
16
17
  if (!checkResult) {
17
- logger.warn({ method: "idUtils.imoChecksumIsValid", message: `IMO checksum failed ${imo}` });
18
+ logger.warn({
19
+ method: "idUtils.imoChecksumIsValid",
20
+ message: `IMO checksum failed ${imo}`,
21
+ });
18
22
  }
19
23
  return checkResult;
20
24
  }
@@ -12,7 +12,15 @@ export const parameterObject = z.object({
12
12
  deprecated: z.boolean().optional(),
13
13
  allowEmptyValue: z.boolean().optional(),
14
14
  style: z
15
- .enum(["matrix", "label", "form", "simple", "spaceDelimited", "pipeDelimited", "deepObject"])
15
+ .enum([
16
+ "matrix",
17
+ "label",
18
+ "form",
19
+ "simple",
20
+ "spaceDelimited",
21
+ "pipeDelimited",
22
+ "deepObject",
23
+ ])
16
24
  .optional(),
17
25
  explode: z.string().optional(),
18
26
  allowReserved: z.boolean().optional(),
@@ -76,11 +84,15 @@ export const openapiSchema = z
76
84
  })
77
85
  .strict()
78
86
  .optional(),
79
- license: z.object({ name: z.string(), url: z.string().optional() }).strict().optional(),
87
+ license: z.object({ name: z.string(), url: z.string().optional() })
88
+ .strict().optional(),
80
89
  version: z.string(),
81
90
  })
82
91
  .strict(),
83
- externalDocs: z.object({ description: z.string().optional(), url: z.string() }).strict().optional(),
92
+ externalDocs: z.object({
93
+ description: z.string().optional(),
94
+ url: z.string(),
95
+ }).strict().optional(),
84
96
  servers: z
85
97
  .array(z
86
98
  .object({
@@ -3,6 +3,7 @@ export declare enum TrafficType {
3
3
  MARINE = "Marine",
4
4
  RAIL = "Rail",
5
5
  AVIATION = "Aviation",
6
+ AFIR = "Afir",
6
7
  MCP = "MCP",
7
8
  OTHER = "Other"
8
9
  }
@@ -4,6 +4,7 @@ export var TrafficType;
4
4
  TrafficType["MARINE"] = "Marine";
5
5
  TrafficType["RAIL"] = "Rail";
6
6
  TrafficType["AVIATION"] = "Aviation";
7
+ TrafficType["AFIR"] = "Afir";
7
8
  TrafficType["MCP"] = "MCP";
8
9
  TrafficType["OTHER"] = "Other";
9
10
  })(TrafficType || (TrafficType = {}));
@@ -42,8 +42,14 @@ export function createExceptionLogger(logger = undefined, includeStack = false)
42
42
  * @see {@link createExceptionLogger} for a curried setup
43
43
  */
44
44
  export function logException(logger, error, includeStack = false) {
45
- const message = error instanceof Error ? error.message : typeof error === "string" ? error : JSON.stringify(error);
46
- const stack = error instanceof Error && includeStack ? error.stack : undefined;
45
+ const message = error instanceof Error
46
+ ? error.message
47
+ : typeof error === "string"
48
+ ? error
49
+ : JSON.stringify(error);
50
+ const stack = error instanceof Error && includeStack
51
+ ? error.stack
52
+ : undefined;
47
53
  // In case error is AxiosError, log the custom code property.
48
54
  // eslint-disable-next-line dot-notation
49
55
  const customCode = error["code"];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@digitraffic/common",
3
- "version": "2025.1.20-1",
3
+ "version": "2025.2.4-1",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "repository": {
@@ -111,7 +111,7 @@
111
111
  "@aws-sdk/lib-storage": "^3.721.0",
112
112
  "@date-fns/tz": "1.2.0",
113
113
  "@smithy/fetch-http-handler": "4.1.3",
114
- "aws-cdk-lib": "^2.173.4",
114
+ "aws-cdk-lib": "^2.177.0",
115
115
  "change-case": "^5.4.4",
116
116
  "constructs": "~10.4.2",
117
117
  "date-fns": "~4.1.0",
@@ -126,19 +126,19 @@
126
126
  "zod": "^3.24.1"
127
127
  },
128
128
  "devDependencies": {
129
- "@aws-sdk/client-api-gateway": "^3.721.0",
130
- "@aws-sdk/client-s3": "^3.721.0",
131
- "@aws-sdk/client-secrets-manager": "^3.721.0",
132
- "@aws-sdk/client-sns": "^3.721.0",
133
- "@aws-sdk/lib-storage": "^3.721.0",
129
+ "@aws-sdk/client-api-gateway": "^3.738.0",
130
+ "@aws-sdk/client-s3": "^3.738.0",
131
+ "@aws-sdk/client-secrets-manager": "^3.738.0",
132
+ "@aws-sdk/client-sns": "^3.738.0",
133
+ "@aws-sdk/lib-storage": "^3.738.0",
134
134
  "@date-fns/tz": "1.2.0",
135
135
  "@digitraffic/eslint-config": "^3.1.1",
136
136
  "@jest/globals": "^29.7.0",
137
137
  "@rushstack/eslint-config": "^3.7.1",
138
- "@rushstack/heft": "^0.68.11",
139
- "@rushstack/heft-jest-plugin": "^0.14.1",
140
- "@rushstack/heft-lint-plugin": "^0.5.10",
141
- "@rushstack/heft-typescript-plugin": "^0.6.4",
138
+ "@rushstack/heft": "^0.68.15",
139
+ "@rushstack/heft-jest-plugin": "^0.14.5",
140
+ "@rushstack/heft-lint-plugin": "^0.5.14",
141
+ "@rushstack/heft-typescript-plugin": "^0.6.8",
142
142
  "@smithy/fetch-http-handler": "4.1.3",
143
143
  "@smithy/types": "^3.7.2",
144
144
  "@types/aws-lambda": "8.10.147",
@@ -151,7 +151,7 @@
151
151
  "@types/node": "20.17.6",
152
152
  "@typescript-eslint/eslint-plugin": "~7.14.1",
153
153
  "@typescript-eslint/parser": "^7.18.0",
154
- "aws-cdk-lib": "^2.173.4",
154
+ "aws-cdk-lib": "^2.177.0",
155
155
  "aws-sdk": "^2.1692.0",
156
156
  "change-case": "^5.4.4",
157
157
  "constructs": "~10.4.2",
@@ -164,6 +164,7 @@
164
164
  "jest": "^29.7.0",
165
165
  "jest-junit": "^16.0.0",
166
166
  "ky": "^1.7.4",
167
+ "lefthook": "^1.10.10",
167
168
  "lodash": "^4.17.21",
168
169
  "lodash-es": "~4.17.21",
169
170
  "madge": "^8.0.0",
@@ -171,7 +172,6 @@
171
172
  "pg-native": "^3.2.0",
172
173
  "pg-promise": "^11.10.2",
173
174
  "pg-query-stream": "4.7.1",
174
- "prettier": "^3.4.2",
175
175
  "rimraf": "^6.0.1",
176
176
  "ts-jest": "^29.2.5",
177
177
  "typescript": "~5.6.3",
@@ -188,6 +188,8 @@
188
188
  "test:jest": "node --trace-warnings --experimental-vm-modules --max-old-space-size=1536 --expose-gc ./node_modules/jest/bin/jest.js --detectOpenHandles --forceExit --coverage --coverageDirectory=output/coverage/jest --logHeapUsage --runInBand --verbose",
189
189
  "test:inspect": "node --inspect-brk --expose-gc ./node_modules/jest/bin/jest.js --detectOpenHandles --forceExit --coverage --coverageDirectory=output/coverage/jest --logHeapUsage --runInBand",
190
190
  "test:watch": "NODE_OPTIONS='--experimental-vm-modules' heft test-watch --max-workers=1",
191
- "test:watch:no-coverage": "NODE_OPTIONS='--experimental-vm-modules' heft test-watch --disable-code-coverage --max-workers=1"
191
+ "test:watch:no-coverage": "NODE_OPTIONS='--experimental-vm-modules' heft test-watch --disable-code-coverage --max-workers=1",
192
+ "run:format-changed": "lefthook run pre-commit",
193
+ "run:format": "deno fmt"
192
194
  }
193
195
  }