@digitraffic/common 2026.2.5-2 → 2026.2.5-3

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 (42) hide show
  1. package/dist/__test__/imports.test.js +2 -6
  2. package/dist/__test__/infra/api/integration.test.js +1 -1
  3. package/dist/__test__/infra/api/response.test.js +7 -21
  4. package/dist/__test__/stack/dt-function.test.js +30 -6
  5. package/dist/__test__/types/lambda-proxy-types.test.d.ts +8 -0
  6. package/dist/__test__/types/lambda-proxy-types.test.js +154 -0
  7. package/dist/__test__/types/lambda-response-builder.test.d.ts +1 -0
  8. package/dist/__test__/types/lambda-response-builder.test.js +80 -0
  9. package/dist/__test__/types/lambda-response.test.d.ts +8 -7
  10. package/dist/__test__/types/lambda-response.test.js +15 -65
  11. package/dist/__test__/utils/base64.test.js +11 -1
  12. package/dist/__test__/utils/lambda-proxy-event.test.d.ts +1 -0
  13. package/dist/__test__/utils/lambda-proxy-event.test.js +44 -0
  14. package/dist/__test__/utils/logging.test.js +13 -1
  15. package/dist/aws/infra/api/response.d.ts +1 -1
  16. package/dist/aws/infra/api/response.js +18 -22
  17. package/dist/aws/infra/canaries/canary.js +1 -1
  18. package/dist/aws/infra/sqs-queue.js +1 -1
  19. package/dist/aws/infra/stack/dt-function.d.ts +5 -2
  20. package/dist/aws/infra/stack/dt-function.js +17 -4
  21. package/dist/aws/infra/stack/lambda-configs.d.ts +6 -0
  22. package/dist/aws/infra/stack/lambda-configs.js +8 -2
  23. package/dist/aws/infra/stack/rest-api.js +1 -1
  24. package/dist/aws/infra/stack/stack-checking-aspect.d.ts +1 -0
  25. package/dist/aws/infra/stack/stack-checking-aspect.js +7 -3
  26. package/dist/aws/types/lambda-proxy-types.d.ts +59 -0
  27. package/dist/aws/types/lambda-proxy-types.js +210 -0
  28. package/dist/aws/types/lambda-response.d.ts +22 -19
  29. package/dist/aws/types/lambda-response.js +65 -73
  30. package/dist/utils/base64.d.ts +5 -3
  31. package/dist/utils/base64.js +12 -4
  32. package/dist/utils/lambda-proxy-event.d.ts +9 -0
  33. package/dist/utils/lambda-proxy-event.js +31 -0
  34. package/dist/utils/logging.d.ts +12 -0
  35. package/dist/utils/logging.js +33 -0
  36. package/dist/utils/zod-utils.d.ts +14 -0
  37. package/dist/utils/zod-utils.js +29 -0
  38. package/package.json +1 -1
  39. package/dist/aws/types/proxytypes.d.ts +0 -26
  40. package/dist/aws/types/proxytypes.js +0 -2
  41. package/dist/database/cached.d.ts +0 -19
  42. package/dist/database/cached.js +0 -40
@@ -7,10 +7,6 @@ test("database import ok?", () => {
7
7
  const database = import("../database/database.js");
8
8
  return expect(database).resolves.toBeDefined();
9
9
  });
10
- test("cached import ok?", () => {
11
- const cached = import("../database/cached.js");
12
- return expect(cached).resolves.toBeDefined();
13
- });
14
10
  test("models import ok?", () => {
15
11
  const models = import("../database/models.js");
16
12
  return expect(models).resolves.toBeDefined();
@@ -243,8 +239,8 @@ test("canaryKeys import ok?", () => {
243
239
  const canaryKeys = import("../aws/infra/canaries/canary-keys.js");
244
240
  return expect(canaryKeys).resolves.toBeDefined();
245
241
  });
246
- test("proxytypes import ok?", () => {
247
- const proxytypes = import("../aws/types/proxytypes.js");
242
+ test("lambda-proxy-types import ok?", () => {
243
+ const proxytypes = import("../aws/types/lambda-proxy-types.js");
248
244
  return expect(proxytypes).resolves.toBeDefined();
249
245
  });
250
246
  test("tags import ok?", () => {
@@ -58,7 +58,7 @@ describe("integration tests", () => {
58
58
  const app = new App();
59
59
  const stack = new Stack(app);
60
60
  const f = new LambdaFunction(stack, "id", {
61
- runtime: Runtime.NODEJS_22_X,
61
+ runtime: Runtime.NODEJS_24_X,
62
62
  code: Code.fromInline("placeholder"),
63
63
  handler: "handler",
64
64
  });
@@ -1,8 +1,6 @@
1
1
  import etag from "etag";
2
2
  import velocity from "velocityjs";
3
3
  import { RESPONSE_DEFAULT_LAMBDA } from "../../../aws/infra/api/response.js";
4
- import { compressBuffer, decodeBase64ToString, } from "../../../aws/types/lambda-response.js";
5
- import { TEST_BIG_JSON } from "../../types/lambda-response.test.js";
6
4
  const TEST_BODY = "Hello world!";
7
5
  describe("response tests", () => {
8
6
  function generateEtagValueFromString(body) {
@@ -11,24 +9,20 @@ describe("response tests", () => {
11
9
  function generateEtagValueFromBase64String(bodyBase64) {
12
10
  return etag(bodyBase64);
13
11
  }
14
- function generateResponse(status, fileName, timestamp, compressBody = false, body = TEST_BODY) {
12
+ function generateResponse(status, fileName, timestamp) {
15
13
  const compile = new velocity.Compile(velocity.parse(RESPONSE_DEFAULT_LAMBDA));
16
- const rawBuffer = Buffer.from(body, "utf8");
17
14
  const output = compile.render({
18
15
  input: {
19
16
  path: () => ({
20
- body: (compressBody
21
- ? compressBuffer(rawBuffer)
22
- : rawBuffer).toString("base64"),
17
+ body: Buffer.from(TEST_BODY).toString("base64"),
23
18
  status,
24
19
  fileName,
25
20
  timestamp: timestamp?.toUTCString(),
26
- etag: generateEtagValueFromString(body),
27
- compressed: compressBody,
21
+ etag: generateEtagValueFromString(TEST_BODY),
28
22
  }),
29
23
  },
30
24
  util: {
31
- base64Decode: (data) => decodeBase64ToString(data, compressBody),
25
+ base64Decode: (data) => Buffer.from(data, "base64").toString(),
32
26
  },
33
27
  context: {
34
28
  responseOverride: {
@@ -39,7 +33,6 @@ describe("response tests", () => {
39
33
  ETag: undefined,
40
34
  "Last-Modified": undefined,
41
35
  "Content-Disposition": undefined,
42
- "Content-Encoding": undefined,
43
36
  },
44
37
  },
45
38
  },
@@ -47,8 +40,8 @@ describe("response tests", () => {
47
40
  // @ts-expect-error: context is not in the type definition
48
41
  return [output, compile.context.context];
49
42
  }
50
- function assertOutputAndContext(output, context, status, contentType, fileName, timestamp, body = TEST_BODY, compressBody = false) {
51
- expect(output).toEqual(body);
43
+ function assertOutputAndContext(output, context, status, contentType, fileName, timestamp) {
44
+ expect(output).toEqual(TEST_BODY);
52
45
  expect(context).toMatchObject({
53
46
  responseOverride: {
54
47
  status,
@@ -57,8 +50,7 @@ describe("response tests", () => {
57
50
  "Access-Control-Allow-Origin": "*",
58
51
  "Content-Disposition": fileName,
59
52
  "Last-Modified": timestamp?.toUTCString(),
60
- ETag: generateEtagValueFromString(body),
61
- "Content-Encoding": compressBody ? "gzip" : undefined,
53
+ ETag: generateEtagValueFromString(TEST_BODY),
62
54
  },
63
55
  },
64
56
  });
@@ -80,11 +72,5 @@ describe("response tests", () => {
80
72
  const [output, context] = generateResponse(204);
81
73
  assertOutputAndContext(output, context, 204, "text/plain");
82
74
  });
83
- test("test 200 - compressed", () => {
84
- const now = new Date();
85
- const body = JSON.stringify(TEST_BIG_JSON);
86
- const [output, context] = generateResponse(200, "test.json", now, true, body);
87
- assertOutputAndContext(output, context, undefined, undefined, 'attachment; filename="test.json"', now, body, true);
88
- });
89
75
  });
90
76
  //# sourceMappingURL=response.test.js.map
@@ -8,8 +8,10 @@ import { EnvKeys } from "../../aws/runtime/environment.js";
8
8
  import { TrafficType } from "../../types/traffictype.js";
9
9
  const TEST_ENV_VAR = "TEST_ENV_VAR";
10
10
  const TEST_ENV_VALUE = "testValue";
11
+ // AWS::Lambda::Function Template Reference
12
+ // https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-lambda-function.html
11
13
  describe("FunctionBuilder test", () => {
12
- function createTemplate(tester, plain = false) {
14
+ function createTemplate(tester, plain = false, lambdaName = "test") {
13
15
  const app = new App();
14
16
  const stack = new DigitrafficStack(app, "test-stack", {
15
17
  alarmTopicArn: "",
@@ -24,10 +26,10 @@ describe("FunctionBuilder test", () => {
24
26
  [TEST_ENV_VAR]: TEST_ENV_VALUE,
25
27
  };
26
28
  const builder = plain
27
- ? FunctionBuilder.plain(stack, "test")
29
+ ? FunctionBuilder.plain(stack, lambdaName)
28
30
  .withEnvironment(environment)
29
31
  .withCode(Code.fromInline("{}"))
30
- : FunctionBuilder.create(stack, "test")
32
+ : FunctionBuilder.create(stack, lambdaName)
31
33
  .withoutDatabaseAccess()
32
34
  .withEnvironment(environment)
33
35
  .withCode(Code.fromInline("{}"));
@@ -62,7 +64,7 @@ describe("FunctionBuilder test", () => {
62
64
  [TEST_ENV_VAR]: TEST_ENV_VALUE,
63
65
  },
64
66
  },
65
- Runtime: Runtime.NODEJS_22_X.name,
67
+ Runtime: Runtime.NODEJS_24_X.name,
66
68
  MemorySize: 128,
67
69
  Timeout: 60,
68
70
  Handler: "test.handler",
@@ -81,10 +83,18 @@ describe("FunctionBuilder test", () => {
81
83
  });
82
84
  test("Lambda runtime is set", () => {
83
85
  const template = createTemplate((builder) => {
84
- builder.withRuntime(Runtime.NODEJS_20_X);
86
+ builder.withRuntime(Runtime.NODEJS_24_X);
85
87
  });
86
88
  template.hasResourceProperties("AWS::Lambda::Function", {
87
- Runtime: Runtime.NODEJS_20_X.name,
89
+ Runtime: Runtime.NODEJS_24_X.name,
90
+ });
91
+ });
92
+ test("Lambda description is set", () => {
93
+ const template = createTemplate((builder) => {
94
+ builder.withDescription("Does something useful");
95
+ });
96
+ template.hasResourceProperties("AWS::Lambda::Function", {
97
+ Description: "Does something useful",
88
98
  });
89
99
  });
90
100
  test("Lambda memory size is set", () => {
@@ -127,6 +137,20 @@ describe("FunctionBuilder test", () => {
127
137
  Handler: "custom.main",
128
138
  });
129
139
  });
140
+ test("Lambda handler module is resolved from path last element", () => {
141
+ const template = createTemplate((_builder) => { }, false, "api/charging-network/v1/operators");
142
+ // const lambdas = template.findResources("AWS::Lambda::Function");
143
+ // console.debug(JSON.stringify(lambdas, null, 2));
144
+ template.hasResourceProperties("AWS::Lambda::Function", {
145
+ Handler: "operators.handler",
146
+ });
147
+ });
148
+ test("Lambda handler module is same as lambda name", () => {
149
+ const template = createTemplate((_builder) => { }, false, "operators");
150
+ template.hasResourceProperties("AWS::Lambda::Function", {
151
+ Handler: "operators.handler",
152
+ });
153
+ });
130
154
  test("withRolePolicies adds custom policy to lambda role", () => {
131
155
  const template = createTemplate((builder) => {
132
156
  builder.withRolePolicies(new PolicyStatement({
@@ -0,0 +1,8 @@
1
+ export declare const TEST_BIG_JSON: {
2
+ items: {
3
+ id: number;
4
+ name: string;
5
+ description: string;
6
+ value: number;
7
+ }[];
8
+ };
@@ -0,0 +1,154 @@
1
+ import { LambdaProxyResponseBuilder } from "../../aws/types/lambda-proxy-types.js";
2
+ import { MediaType } from "../../aws/types/mediatypes.js";
3
+ import { decodeBase64ToUtf8 } from "../../utils/base64.js";
4
+ // About 18 MB will be compressed to 2 MB
5
+ export const TEST_BIG_JSON = {
6
+ items: Array.from({ length: 10 }, (_, i) => ({
7
+ id: i,
8
+ name: `Item ${i}`,
9
+ description: "This is a test description that repeats to allow compression",
10
+ value: Math.random(),
11
+ })),
12
+ };
13
+ describe("lambda-response", () => {
14
+ const TEST_MESSAGE = "HELLO";
15
+ const TEST_COUNT = 12;
16
+ const TEST_FILENAME = "file.txt";
17
+ const TEST_TIMESTAMP = new Date();
18
+ const TEST_TIMESTAMP_STR = TEST_TIMESTAMP.toISOString();
19
+ const TEST_JSON = {
20
+ message: TEST_MESSAGE,
21
+ count: TEST_COUNT,
22
+ };
23
+ function isCompressed(response) {
24
+ return response.headers?.["Content-Encoding"] === "gzip";
25
+ }
26
+ function assertContent(response, expectedBody, expectedStatus, expectedFilename, expectedTimestamp, expectContentType = MediaType.APPLICATION_JSON, compressed = false, isBase64Encoded = false) {
27
+ const isBinary = typeof expectedBody !== "string";
28
+ const decodedBody = response.isBase64Encoded
29
+ ? decodeBase64ToUtf8(response.body, isCompressed(response))
30
+ : response.body;
31
+ const body = isBinary ? JSON.parse(decodedBody) : decodedBody;
32
+ expect(body).toEqual(expectedBody);
33
+ // compressed responses are always base64 encoded
34
+ expect(response.isBase64Encoded).toEqual(compressed || isBase64Encoded);
35
+ expect(response.statusCode).toEqual(expectedStatus);
36
+ if (expectedFilename) {
37
+ expect(response.headers?.["Content-Disposition"]).toEqual(`attachment; filename="${expectedFilename}"`);
38
+ }
39
+ else {
40
+ expect(response.headers?.["Content-Disposition"]).toBeUndefined();
41
+ }
42
+ if (expectedTimestamp) {
43
+ expect(response.headers?.["Last-Modified"]).toEqual(expectedTimestamp?.toUTCString());
44
+ }
45
+ else {
46
+ expect(response.headers?.["Last-Modified"]).toBeUndefined();
47
+ }
48
+ if (compressed) {
49
+ expect(response.headers?.["Content-Encoding"]).toEqual("gzip");
50
+ }
51
+ else {
52
+ // No content-encoding header for uncompressed content
53
+ expect(response.headers?.["Content-Encoding"]).toBeUndefined();
54
+ }
55
+ expect(response.headers?.["Content-Type"]).toEqual(expectContentType);
56
+ }
57
+ test("okJson - create json", () => {
58
+ const response = LambdaProxyResponseBuilder.create(TEST_JSON).build();
59
+ assertContent(response, TEST_JSON, 200);
60
+ });
61
+ test("okJson - with json", () => {
62
+ const response = LambdaProxyResponseBuilder.create()
63
+ .withBody(TEST_JSON)
64
+ .build();
65
+ assertContent(response, TEST_JSON, 200);
66
+ });
67
+ test("okJson - with json and fileName", () => {
68
+ const response = LambdaProxyResponseBuilder.create()
69
+ .withBody(TEST_JSON)
70
+ .withFileName(TEST_FILENAME)
71
+ .build();
72
+ assertContent(response, TEST_JSON, 200, TEST_FILENAME);
73
+ });
74
+ test("okJson - with json, fileName and timestamp", () => {
75
+ const response = LambdaProxyResponseBuilder.create()
76
+ .withBody(TEST_JSON)
77
+ .withFileName(TEST_FILENAME)
78
+ .withTimestamp(TEST_TIMESTAMP)
79
+ .build();
80
+ const response2 = LambdaProxyResponseBuilder.create()
81
+ .withBody(TEST_JSON)
82
+ .withFileName(TEST_FILENAME)
83
+ .withTimestamp(TEST_TIMESTAMP_STR)
84
+ .build();
85
+ assertContent(response, TEST_JSON, 200, TEST_FILENAME, TEST_TIMESTAMP);
86
+ assertContent(response2, TEST_JSON, 200, TEST_FILENAME, TEST_TIMESTAMP);
87
+ });
88
+ test("okBinary - create binary, fileName and timestamp", () => {
89
+ const response = LambdaProxyResponseBuilder.create(Buffer.from(TEST_MESSAGE).toString("base64"), true)
90
+ .withFileName(TEST_FILENAME)
91
+ .withTimestamp(TEST_TIMESTAMP)
92
+ .withContentType(MediaType.TEXT_PLAIN)
93
+ .build();
94
+ assertContent(response, TEST_MESSAGE, 200, TEST_FILENAME, TEST_TIMESTAMP, MediaType.TEXT_PLAIN, false, true);
95
+ });
96
+ test("badRequest", () => {
97
+ const response = LambdaProxyResponseBuilder.badRequest(TEST_MESSAGE);
98
+ assertContent(response, TEST_MESSAGE, 400, undefined, undefined, MediaType.TEXT_PLAIN);
99
+ });
100
+ test("notFound", () => {
101
+ const response = LambdaProxyResponseBuilder.notFound();
102
+ assertContent(response, "Not Found", 404, undefined, undefined, MediaType.TEXT_PLAIN);
103
+ });
104
+ test("internalError", () => {
105
+ const response = LambdaProxyResponseBuilder.internalError();
106
+ assertContent(response, "Internal Error", 500, undefined, undefined, MediaType.TEXT_PLAIN);
107
+ });
108
+ test("notImplemented", () => {
109
+ const response = LambdaProxyResponseBuilder.notImplemented();
110
+ assertContent(response, "Not Implemented", 501, undefined, undefined, MediaType.TEXT_PLAIN);
111
+ });
112
+ test("notImplemented", () => {
113
+ const response = LambdaProxyResponseBuilder.unauthorized();
114
+ assertContent(response, "Unauthorized", 401, undefined, undefined, MediaType.TEXT_PLAIN);
115
+ });
116
+ test("okText - with fileName and timestamp", () => {
117
+ const response = LambdaProxyResponseBuilder.create()
118
+ .withBody(TEST_MESSAGE)
119
+ .withFileName(TEST_FILENAME)
120
+ .withTimestamp(TEST_TIMESTAMP)
121
+ .build();
122
+ assertContent(response, TEST_MESSAGE, 200, TEST_FILENAME, TEST_TIMESTAMP);
123
+ });
124
+ test("okJson - compression uneffective for small json", () => {
125
+ const response = LambdaProxyResponseBuilder.create()
126
+ .withBody(TEST_JSON)
127
+ .withFileName(TEST_FILENAME)
128
+ .withTimestamp(TEST_TIMESTAMP)
129
+ .withCompression()
130
+ .withDebug()
131
+ .build();
132
+ assertContent(response, TEST_JSON, 200, TEST_FILENAME, TEST_TIMESTAMP, MediaType.APPLICATION_JSON, false);
133
+ });
134
+ test("okJson - compression effective for large json", () => {
135
+ const response = LambdaProxyResponseBuilder.create()
136
+ .withBody(TEST_BIG_JSON)
137
+ .withFileName(TEST_FILENAME)
138
+ .withTimestamp(TEST_TIMESTAMP)
139
+ .withCompression()
140
+ .withDebug()
141
+ .build();
142
+ assertContent(response, TEST_BIG_JSON, 200, TEST_FILENAME, TEST_TIMESTAMP, MediaType.APPLICATION_JSON, true);
143
+ });
144
+ test("okText - as binary", () => {
145
+ const response = LambdaProxyResponseBuilder.create()
146
+ .withBody(Buffer.from(TEST_MESSAGE).toString("base64"), true)
147
+ .withFileName(TEST_FILENAME)
148
+ .withTimestamp(TEST_TIMESTAMP)
149
+ .withContentType(MediaType.TEXT_PLAIN)
150
+ .build();
151
+ assertContent(response, TEST_MESSAGE, 200, TEST_FILENAME, TEST_TIMESTAMP, MediaType.TEXT_PLAIN, false, true);
152
+ });
153
+ });
154
+ //# sourceMappingURL=lambda-proxy-types.test.js.map
@@ -0,0 +1,80 @@
1
+ import { LambdaResponseBuilder } from "../../aws/types/lambda-response.js";
2
+ import { decodeBase64ToUtf8 } from "../../utils/base64.js";
3
+ import { TEST_FILENAME, TEST_JSON, TEST_MESSAGE, TEST_TIMESTAMP, TEST_TIMESTAMP_STR, } from "./lambda-response.test.js";
4
+ describe("lambda-response", () => {
5
+ function assertJson(response, expectedJson, expectedStatus, expectedFilename, expectedTimestamp) {
6
+ const body = JSON.parse(decodeBase64ToUtf8(response.body));
7
+ expect(body).toEqual(expectedJson);
8
+ expect(response.status).toEqual(expectedStatus);
9
+ expect(response.fileName).toEqual(expectedFilename);
10
+ expect(response.timestamp).toEqual(expectedTimestamp?.toUTCString());
11
+ }
12
+ function assertBinary(response, expectedString, expectedStatus, expectedFilename, expectedTimestamp) {
13
+ const body = decodeBase64ToUtf8(response.body);
14
+ expect(body).toEqual(expectedString);
15
+ expect(response.status).toEqual(expectedStatus);
16
+ expect(response.fileName).toEqual(expectedFilename);
17
+ expect(response.timestamp).toEqual(expectedTimestamp?.toUTCString());
18
+ }
19
+ test("okJson - without fileName", () => {
20
+ const response = LambdaResponseBuilder.create(TEST_JSON).build();
21
+ assertJson(response, TEST_JSON, 200);
22
+ });
23
+ test("okJson - with fileName", () => {
24
+ const response = LambdaResponseBuilder.create(TEST_JSON)
25
+ .withFileName(TEST_FILENAME)
26
+ .build();
27
+ assertJson(response, TEST_JSON, 200, TEST_FILENAME);
28
+ });
29
+ test("okJson - with fileName and timestamp", () => {
30
+ const responseWithTimestampDate = LambdaResponseBuilder.create()
31
+ .withBody(TEST_JSON)
32
+ .withFileName(TEST_FILENAME)
33
+ .withTimestamp(TEST_TIMESTAMP)
34
+ .build();
35
+ const responseWithTimestampString = LambdaResponseBuilder.create()
36
+ .withBody(TEST_JSON)
37
+ .withFileName(TEST_FILENAME)
38
+ .withTimestamp(TEST_TIMESTAMP_STR)
39
+ .build();
40
+ assertJson(responseWithTimestampDate, TEST_JSON, 200, TEST_FILENAME, TEST_TIMESTAMP);
41
+ assertJson(responseWithTimestampString, TEST_JSON, 200, TEST_FILENAME, TEST_TIMESTAMP);
42
+ });
43
+ test("okBinary - with fileName and timestamp", () => {
44
+ const response = LambdaResponseBuilder.create()
45
+ .withBody(TEST_MESSAGE)
46
+ .withFileName(TEST_FILENAME)
47
+ .withTimestamp(TEST_TIMESTAMP)
48
+ .build();
49
+ assertBinary(response, TEST_MESSAGE, 200, TEST_FILENAME, TEST_TIMESTAMP);
50
+ });
51
+ test("badRequest", () => {
52
+ const response = LambdaResponseBuilder.badRequest(TEST_MESSAGE);
53
+ assertBinary(response, TEST_MESSAGE, 400);
54
+ });
55
+ test("notFound", () => {
56
+ const response = LambdaResponseBuilder.notFound();
57
+ assertBinary(response, "Not Found", 404);
58
+ });
59
+ test("internalError", () => {
60
+ const response = LambdaResponseBuilder.internalError();
61
+ assertBinary(response, "Internal Error", 500);
62
+ });
63
+ test("notImplemented", () => {
64
+ const response = LambdaResponseBuilder.notImplemented();
65
+ assertBinary(response, "Not Implemented", 501);
66
+ });
67
+ // Builder
68
+ test("Builder - okJson - without fileName", () => {
69
+ const response = LambdaResponseBuilder.create().withBody(TEST_JSON).build();
70
+ assertJson(response, TEST_JSON, 200);
71
+ });
72
+ test("Builder - okJson - with fileName", () => {
73
+ const response = LambdaResponseBuilder.create()
74
+ .withBody(TEST_JSON)
75
+ .withFileName(TEST_FILENAME)
76
+ .build();
77
+ assertJson(response, TEST_JSON, 200, TEST_FILENAME);
78
+ });
79
+ });
80
+ //# sourceMappingURL=lambda-response-builder.test.js.map
@@ -1,8 +1,9 @@
1
- export declare const TEST_BIG_JSON: {
2
- items: {
3
- id: number;
4
- name: string;
5
- description: string;
6
- value: number;
7
- }[];
1
+ export declare const TEST_MESSAGE = "HELLO";
2
+ export declare const TEST_COUNT = 12;
3
+ export declare const TEST_FILENAME = "file.txt";
4
+ export declare const TEST_TIMESTAMP: Date;
5
+ export declare const TEST_TIMESTAMP_STR: string;
6
+ export declare const TEST_JSON: {
7
+ message: string;
8
+ count: number;
8
9
  };
@@ -1,32 +1,24 @@
1
- import { decodeBase64ToString, LambdaResponse, LambdaResponseBuilder, } from "../../aws/types/lambda-response.js";
2
- // About 18 MB will be compressed to 2 MB
3
- export const TEST_BIG_JSON = {
4
- items: Array.from({ length: 10 }, (_, i) => ({
5
- id: i,
6
- name: `Item ${i}`,
7
- description: "This is a test description that repeats to allow compression",
8
- value: Math.random(),
9
- })),
1
+ import { LambdaResponse, LambdaResponseBuilder, } from "../../aws/types/lambda-response.js";
2
+ import { decodeBase64ToUtf8 } from "../../utils/base64.js";
3
+ export const TEST_MESSAGE = "HELLO";
4
+ export const TEST_COUNT = 12;
5
+ export const TEST_FILENAME = "file.txt";
6
+ export const TEST_TIMESTAMP = new Date();
7
+ export const TEST_TIMESTAMP_STR = TEST_TIMESTAMP.toISOString();
8
+ export const TEST_JSON = {
9
+ message: TEST_MESSAGE,
10
+ count: TEST_COUNT,
10
11
  };
11
12
  describe("lambda-response", () => {
12
- const TEST_MESSAGE = "HELLO";
13
- const TEST_COUNT = 12;
14
- const TEST_FILENAME = "file.txt";
15
- const TEST_TIMESTAMP = new Date();
16
- const TEST_TIMESTAMP_STR = TEST_TIMESTAMP.toISOString();
17
- const TEST_JSON = {
18
- message: TEST_MESSAGE,
19
- count: TEST_COUNT,
20
- };
21
13
  function assertJson(response, expectedJson, expectedStatus, expectedFilename, expectedTimestamp) {
22
- const body = JSON.parse(decodeBase64ToString(response.body, response.compressed));
14
+ const body = JSON.parse(decodeBase64ToUtf8(response.body));
23
15
  expect(body).toEqual(expectedJson);
24
16
  expect(response.status).toEqual(expectedStatus);
25
17
  expect(response.fileName).toEqual(expectedFilename);
26
18
  expect(response.timestamp).toEqual(expectedTimestamp?.toUTCString());
27
19
  }
28
20
  function assertBinary(response, expectedString, expectedStatus, expectedFilename, expectedTimestamp) {
29
- const body = decodeBase64ToString(response.body, response.compressed);
21
+ const body = decodeBase64ToUtf8(response.body);
30
22
  expect(body).toEqual(expectedString);
31
23
  expect(response.status).toEqual(expectedStatus);
32
24
  expect(response.fileName).toEqual(expectedFilename);
@@ -54,15 +46,15 @@ describe("lambda-response", () => {
54
46
  });
55
47
  test("notFound", () => {
56
48
  const response = LambdaResponse.notFound();
57
- assertBinary(response, "Not found", 404);
49
+ assertBinary(response, "Not Found", 404);
58
50
  });
59
51
  test("internalError", () => {
60
52
  const response = LambdaResponse.internalError();
61
- assertBinary(response, "Internal error", 500);
53
+ assertBinary(response, "Internal Error", 500);
62
54
  });
63
55
  test("notImplemented", () => {
64
56
  const response = LambdaResponse.notImplemented();
65
- assertBinary(response, "Not implemented", 501);
57
+ assertBinary(response, "Not Implemented", 501);
66
58
  });
67
59
  // Builder
68
60
  test("Builder - okJson - without fileName", () => {
@@ -76,47 +68,5 @@ describe("lambda-response", () => {
76
68
  .build();
77
69
  assertJson(response, TEST_JSON, 200, TEST_FILENAME);
78
70
  });
79
- test("Builder - okJson - with fileName and timestamp", () => {
80
- const response = LambdaResponseBuilder.create()
81
- .withBody(TEST_JSON)
82
- .withFileName(TEST_FILENAME)
83
- .withTimestamp(TEST_TIMESTAMP)
84
- .build();
85
- const response2 = LambdaResponseBuilder.create()
86
- .withBody(TEST_JSON)
87
- .withFileName(TEST_FILENAME)
88
- .withTimestamp(TEST_TIMESTAMP_STR)
89
- .build();
90
- assertJson(response, TEST_JSON, 200, TEST_FILENAME, TEST_TIMESTAMP);
91
- assertJson(response2, TEST_JSON, 200, TEST_FILENAME, TEST_TIMESTAMP);
92
- });
93
- test("Builder - okBinary - with fileName and timestamp", () => {
94
- const response = LambdaResponseBuilder.create()
95
- .withBody(TEST_MESSAGE)
96
- .withFileName(TEST_FILENAME)
97
- .withTimestamp(TEST_TIMESTAMP)
98
- .build();
99
- assertBinary(response, TEST_MESSAGE, 200, TEST_FILENAME, TEST_TIMESTAMP);
100
- });
101
- test("Builder - compression uneffective for small json", () => {
102
- const response = LambdaResponseBuilder.create()
103
- .withBody(TEST_JSON)
104
- .withFileName(TEST_FILENAME)
105
- .withCompression()
106
- .withDebug()
107
- .build();
108
- expect(response.compressed).toBe(false);
109
- assertJson(response, TEST_JSON, 200, TEST_FILENAME);
110
- });
111
- test("Builder - compression effective for large json", () => {
112
- const response = LambdaResponseBuilder.create()
113
- .withBody(TEST_BIG_JSON)
114
- .withFileName(TEST_FILENAME)
115
- .withCompression()
116
- .withDebug()
117
- .build();
118
- expect(response.compressed).toBe(true);
119
- assertJson(response, TEST_BIG_JSON, 200, TEST_FILENAME);
120
- });
121
71
  });
122
72
  //# sourceMappingURL=lambda-response.test.js.map
@@ -1,4 +1,4 @@
1
- import { decodeBase64ToAscii, decodeBase64ToUtf8, encodeAsciiToBase64, encodeUtf8ToBase64, } from "../../utils/base64.js";
1
+ import { compressBuffer, decodeBase64ToAscii, decodeBase64ToUtf8, encodeAsciiToBase64, encodeUtf8ToBase64, } from "../../utils/base64.js";
2
2
  describe("Base64UtilTest", () => {
3
3
  const EXPECTED_ASCII = "0a9f4967-faaa-445a-ba11-078f7f9556b4";
4
4
  const EXPECTED_ASCII_BASE64 = "MGE5ZjQ5NjctZmFhYS00NDVhLWJhMTEtMDc4ZjdmOTU1NmI0";
@@ -23,5 +23,15 @@ describe("Base64UtilTest", () => {
23
23
  expect(encodedUtf8).toEqual(EXPECTED_UTF8_BASE64);
24
24
  expect(decodedUtf8).toEqual(EXPECTED_UTF8);
25
25
  });
26
+ test("decode utf8 compressed", () => {
27
+ const originalBody = { message: EXPECTED_UTF8 };
28
+ const body = JSON.stringify(originalBody);
29
+ const rawBuffer = Buffer.from(body, "utf8");
30
+ const compressed = compressBuffer(rawBuffer);
31
+ const compressedBase64 = compressed.toString("base64");
32
+ const uncompressedBody = decodeBase64ToUtf8(compressedBase64, true);
33
+ const restoredBody = JSON.parse(uncompressedBody);
34
+ expect(originalBody).toEqual(restoredBody);
35
+ });
26
36
  });
27
37
  //# sourceMappingURL=base64.test.js.map
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,44 @@
1
+ import { parseQueryParams } from "../../utils/lambda-proxy-event.js";
2
+ describe("lambda-proxy-event.test", () => {
3
+ test("StopWatch start-stop", async () => {
4
+ const event = {
5
+ body: null,
6
+ headers: {},
7
+ multiValueHeaders: {},
8
+ httpMethod: "GET",
9
+ isBase64Encoded: false,
10
+ multiValueQueryStringParameters: {
11
+ evseStatus: ["CHARGING", "OUTOFORDER"],
12
+ operatorPartyId: ["LDL"],
13
+ },
14
+ queryStringParameters: {
15
+ evseStatus: "OUTOFORDER",
16
+ operatorPartyId: "LDL",
17
+ },
18
+ };
19
+ const parsed = parseQueryParams(event, ["evseStatus"]);
20
+ expect(parsed.evseStatus).toEqual(["CHARGING", "OUTOFORDER"]);
21
+ expect(parsed.operatorPartyId).toEqual("LDL");
22
+ });
23
+ test("StopWatch start-stop", async () => {
24
+ const event = {
25
+ body: null,
26
+ headers: {},
27
+ multiValueHeaders: {},
28
+ httpMethod: "GET",
29
+ isBase64Encoded: false,
30
+ multiValueQueryStringParameters: {
31
+ evseStatus: ["CHARGING", "OUTOFORDER"],
32
+ operatorPartyId: ["LDL"],
33
+ },
34
+ queryStringParameters: {
35
+ evseStatus: "OUTOFORDER",
36
+ operatorPartyId: "LDL",
37
+ },
38
+ };
39
+ const parsed = parseQueryParams(event, ["evseStatus"]);
40
+ expect(parsed.evseStatus).toEqual(["CHARGING", "OUTOFORDER"]);
41
+ expect(parsed.operatorPartyId).toEqual("LDL");
42
+ });
43
+ });
44
+ //# sourceMappingURL=lambda-proxy-event.test.js.map
@@ -1,6 +1,6 @@
1
1
  import { Writable } from "node:stream";
2
2
  import { DtLogger } from "../../aws/runtime/dt-logger.js";
3
- import { logException } from "../../utils/logging.js";
3
+ import { logException, truncateEnd, truncateMiddle, } from "../../utils/logging.js";
4
4
  const TEST_METHODNAME = "test.logException";
5
5
  describe("logging-test", () => {
6
6
  function assertLogError(error, expected, includeStack = false) {
@@ -58,5 +58,17 @@ describe("logging-test", () => {
58
58
  stack: true,
59
59
  }, true);
60
60
  });
61
+ test("truncateEnd - not truncated as would be longer", () => {
62
+ expect(truncateEnd("This is a test string", 10)).toBe("This is a test string");
63
+ });
64
+ test("truncateEnd", () => {
65
+ expect(truncateEnd("This is a test string that is long enough", 10)).toBe("This is a [TRUNCATED 31 CHARS]");
66
+ });
67
+ test("truncateMiddle - not truncated as would be longer", () => {
68
+ expect(truncateMiddle("This is a test string", 10)).toBe("This is a test string");
69
+ });
70
+ test("truncateMiddle", () => {
71
+ expect(truncateMiddle("This is a test string that is long enough", 20)).toBe("This is a [TRUNCATED 21 CHARS] ong enough");
72
+ });
61
73
  });
62
74
  //# sourceMappingURL=logging.test.js.map