@digitraffic/common 2024.1.24-2 → 2024.1.30-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 (206) hide show
  1. package/dist/__test__/api/handler-factory.test.d.mts +1 -0
  2. package/dist/__test__/api/handler-factory.test.mjs +43 -0
  3. package/dist/__test__/api/response.test.d.mts +1 -0
  4. package/dist/__test__/api/response.test.mjs +86 -0
  5. package/dist/__test__/imports.test.d.mts +1 -0
  6. package/dist/__test__/imports.test.mjs +332 -0
  7. package/dist/__test__/marine/id_utils.test.d.mts +1 -0
  8. package/dist/__test__/marine/id_utils.test.mjs +44 -0
  9. package/dist/__test__/promise/promise.test.d.mts +1 -0
  10. package/dist/__test__/promise/promise.test.mjs +130 -0
  11. package/dist/__test__/runtime/dt-logger.test.d.mts +1 -0
  12. package/dist/__test__/runtime/dt-logger.test.mjs +108 -0
  13. package/dist/__test__/secrets/secret-holder.test.d.mts +1 -0
  14. package/dist/__test__/secrets/secret-holder.test.mjs +89 -0
  15. package/dist/__test__/secrets/secret.test.d.mts +1 -0
  16. package/dist/__test__/secrets/secret.test.mjs +42 -0
  17. package/dist/__test__/test/httpserver.test.d.mts +1 -0
  18. package/dist/__test__/test/httpserver.test.mjs +154 -0
  19. package/dist/__test__/types/lambda-response.test.d.mts +1 -0
  20. package/dist/__test__/types/lambda-response.test.mjs +58 -0
  21. package/dist/__test__/utils/date-utils.test.d.mts +1 -0
  22. package/dist/__test__/utils/date-utils.test.mjs +27 -0
  23. package/dist/__test__/utils/geometry.test.d.mts +1 -0
  24. package/dist/__test__/utils/geometry.test.mjs +24 -0
  25. package/dist/__test__/utils/logging.test.d.mts +1 -0
  26. package/dist/__test__/utils/logging.test.mjs +78 -0
  27. package/dist/__test__/utils/utils.test.d.mts +1 -0
  28. package/dist/__test__/utils/utils.test.mjs +43 -0
  29. package/dist/aws/infra/api/handler-factory.mjs +4 -0
  30. package/dist/aws/infra/api/integration.d.mts +2 -2
  31. package/dist/aws/infra/api/integration.mjs +4 -1
  32. package/dist/aws/infra/api/response.d.mts +1 -1
  33. package/dist/aws/infra/api/responses.d.mts +1 -1
  34. package/dist/aws/infra/api/responses.mjs +2 -0
  35. package/dist/aws/infra/api/static-integration.mjs +1 -1
  36. package/dist/aws/infra/canaries/canary-alarm.d.mts +1 -1
  37. package/dist/aws/infra/canaries/canary-alarm.mjs +2 -0
  38. package/dist/aws/infra/canaries/canary-parameters.mjs +1 -1
  39. package/dist/aws/infra/canaries/canary-role.mjs +1 -0
  40. package/dist/aws/infra/canaries/canary.d.mts +2 -2
  41. package/dist/aws/infra/canaries/canary.mjs +2 -0
  42. package/dist/aws/infra/canaries/database-canary.d.mts +2 -2
  43. package/dist/aws/infra/canaries/database-canary.mjs +2 -0
  44. package/dist/aws/infra/canaries/database-checker.d.mts +1 -1
  45. package/dist/aws/infra/canaries/database-checker.mjs +7 -1
  46. package/dist/aws/infra/canaries/url-canary.d.mts +2 -2
  47. package/dist/aws/infra/canaries/url-canary.mjs +3 -0
  48. package/dist/aws/infra/canaries/url-checker.d.mts +1 -1
  49. package/dist/aws/infra/canaries/url-checker.mjs +5 -4
  50. package/dist/aws/infra/documentation.mjs +5 -1
  51. package/dist/aws/infra/import-util.d.mts +1 -1
  52. package/dist/aws/infra/import-util.mjs +4 -3
  53. package/dist/aws/infra/scheduler.mjs +2 -0
  54. package/dist/aws/infra/security-rule.d.mts +1 -1
  55. package/dist/aws/infra/security-rule.mjs +1 -0
  56. package/dist/aws/infra/sqs-integration.d.mts +1 -1
  57. package/dist/aws/infra/sqs-integration.mjs +3 -1
  58. package/dist/aws/infra/sqs-queue.d.mts +1 -1
  59. package/dist/aws/infra/sqs-queue.mjs +2 -1
  60. package/dist/aws/infra/stack/lambda-configs.d.mts +4 -4
  61. package/dist/aws/infra/stack/lambda-configs.mjs +4 -2
  62. package/dist/aws/infra/stack/monitoredfunction.d.mts +3 -3
  63. package/dist/aws/infra/stack/monitoredfunction.mjs +20 -16
  64. package/dist/aws/infra/stack/parameters.mjs +1 -0
  65. package/dist/aws/infra/stack/rest_apis.d.mts +2 -2
  66. package/dist/aws/infra/stack/rest_apis.mjs +6 -1
  67. package/dist/aws/infra/stack/stack-checking-aspect.d.mts +2 -2
  68. package/dist/aws/infra/stack/stack-checking-aspect.mjs +6 -1
  69. package/dist/aws/infra/stack/stack.d.mts +5 -5
  70. package/dist/aws/infra/stack/stack.mjs +9 -0
  71. package/dist/aws/infra/stack/subscription.mjs +4 -0
  72. package/dist/aws/infra/stacks/db-dns-stack.d.mts +1 -1
  73. package/dist/aws/infra/stacks/db-dns-stack.mjs +1 -0
  74. package/dist/aws/infra/stacks/db-proxy-stack.d.mts +3 -3
  75. package/dist/aws/infra/stacks/db-proxy-stack.mjs +4 -2
  76. package/dist/aws/infra/stacks/db-stack.d.mts +3 -3
  77. package/dist/aws/infra/stacks/db-stack.mjs +11 -7
  78. package/dist/aws/infra/stacks/intra-stack-configuration.d.mts +1 -1
  79. package/dist/aws/infra/stacks/network-stack.d.mts +2 -2
  80. package/dist/aws/infra/stacks/network-stack.mjs +8 -0
  81. package/dist/aws/infra/usage-plans.d.mts +1 -1
  82. package/dist/aws/infra/usage-plans.mjs +1 -0
  83. package/dist/aws/runtime/apikey.d.mts +2 -2
  84. package/dist/aws/runtime/apikey.mjs +2 -1
  85. package/dist/aws/runtime/digitraffic-integration-response.d.mts +1 -1
  86. package/dist/aws/runtime/dt-logger.mjs +6 -2
  87. package/dist/aws/runtime/messaging.d.mts +2 -2
  88. package/dist/aws/runtime/s3.d.mts +2 -2
  89. package/dist/aws/runtime/s3.mjs +2 -1
  90. package/dist/aws/runtime/secrets/dbsecret.d.mts +1 -1
  91. package/dist/aws/runtime/secrets/proxy-holder.mjs +1 -0
  92. package/dist/aws/runtime/secrets/rds-holder.mjs +1 -0
  93. package/dist/aws/runtime/secrets/secret-holder.d.mts +1 -1
  94. package/dist/aws/runtime/secrets/secret-holder.mjs +6 -1
  95. package/dist/aws/runtime/secrets/secret.mjs +4 -2
  96. package/dist/aws/types/errors.mjs +1 -0
  97. package/dist/aws/types/lambda-response.mjs +5 -0
  98. package/dist/aws/types/model-with-reference.mjs +1 -1
  99. package/dist/database/cached.d.mts +1 -1
  100. package/dist/database/database.mjs +1 -0
  101. package/dist/database/last-updated.d.mts +1 -1
  102. package/dist/test/db-testutils.d.mts +1 -1
  103. package/dist/test/db-testutils.mjs +1 -1
  104. package/dist/test/httpserver.mjs +7 -3
  105. package/dist/test/secrets-manager.d.mts +1 -1
  106. package/dist/test/secrets-manager.mjs +1 -1
  107. package/dist/test/testutils.mjs +1 -1
  108. package/dist/types/http-error.mjs +1 -0
  109. package/dist/types/nullable.d.mts +1 -1
  110. package/dist/utils/api-model.d.mts +2 -2
  111. package/dist/utils/api-model.mjs +1 -1
  112. package/dist/utils/geojson-types.d.mts +1 -1
  113. package/dist/utils/geojson-types.mjs +4 -2
  114. package/dist/utils/geometry.d.mts +1 -1
  115. package/dist/utils/geometry.mjs +3 -0
  116. package/dist/utils/retry.d.mts +2 -2
  117. package/dist/utils/retry.mjs +2 -2
  118. package/dist/utils/slack.mjs +1 -0
  119. package/dist/utils/utils.d.mts +2 -2
  120. package/package.json +11 -6
  121. package/src/@types/geojson-validation/index.d.mts +0 -4
  122. package/src/aws/infra/api/handler-factory.mts +0 -86
  123. package/src/aws/infra/api/integration.mts +0 -147
  124. package/src/aws/infra/api/response.mts +0 -165
  125. package/src/aws/infra/api/responses.mts +0 -127
  126. package/src/aws/infra/api/static-integration.mts +0 -108
  127. package/src/aws/infra/canaries/Synthetics.d.mts +0 -21
  128. package/src/aws/infra/canaries/canary-alarm.mts +0 -33
  129. package/src/aws/infra/canaries/canary-keys.mts +0 -3
  130. package/src/aws/infra/canaries/canary-parameters.mts +0 -19
  131. package/src/aws/infra/canaries/canary-role.mts +0 -73
  132. package/src/aws/infra/canaries/canary.mts +0 -44
  133. package/src/aws/infra/canaries/database-canary.mts +0 -98
  134. package/src/aws/infra/canaries/database-checker.mts +0 -163
  135. package/src/aws/infra/canaries/url-canary.mts +0 -98
  136. package/src/aws/infra/canaries/url-checker.mts +0 -388
  137. package/src/aws/infra/documentation.mts +0 -142
  138. package/src/aws/infra/import-util.mts +0 -57
  139. package/src/aws/infra/scheduler.mts +0 -59
  140. package/src/aws/infra/security-rule.mts +0 -38
  141. package/src/aws/infra/sqs-integration.mts +0 -106
  142. package/src/aws/infra/sqs-queue.mts +0 -162
  143. package/src/aws/infra/stack/lambda-configs.mts +0 -135
  144. package/src/aws/infra/stack/monitoredfunction.mts +0 -352
  145. package/src/aws/infra/stack/parameters.mts +0 -74
  146. package/src/aws/infra/stack/rest_apis.mts +0 -322
  147. package/src/aws/infra/stack/stack-checking-aspect.mts +0 -233
  148. package/src/aws/infra/stack/stack.mts +0 -144
  149. package/src/aws/infra/stack/subscription.mts +0 -58
  150. package/src/aws/infra/stacks/db-dns-stack.mts +0 -77
  151. package/src/aws/infra/stacks/db-proxy-stack.mts +0 -134
  152. package/src/aws/infra/stacks/db-stack.mts +0 -292
  153. package/src/aws/infra/stacks/intra-stack-configuration.mts +0 -6
  154. package/src/aws/infra/stacks/network-stack.mts +0 -76
  155. package/src/aws/infra/usage-plans.mts +0 -50
  156. package/src/aws/runtime/apikey.mts +0 -9
  157. package/src/aws/runtime/digitraffic-integration-response.mts +0 -35
  158. package/src/aws/runtime/dt-logger-default.mts +0 -11
  159. package/src/aws/runtime/dt-logger.mts +0 -184
  160. package/src/aws/runtime/environment.mts +0 -22
  161. package/src/aws/runtime/messaging.mts +0 -26
  162. package/src/aws/runtime/s3.mts +0 -44
  163. package/src/aws/runtime/secrets/dbsecret.mts +0 -31
  164. package/src/aws/runtime/secrets/node-ttl.d.mts +0 -12
  165. package/src/aws/runtime/secrets/proxy-holder.mts +0 -34
  166. package/src/aws/runtime/secrets/rds-holder.mts +0 -34
  167. package/src/aws/runtime/secrets/secret-holder.mts +0 -106
  168. package/src/aws/runtime/secrets/secret.mts +0 -58
  169. package/src/aws/types/errors.mts +0 -14
  170. package/src/aws/types/lambda-response.mts +0 -100
  171. package/src/aws/types/mediatypes.mts +0 -12
  172. package/src/aws/types/model-with-reference.mts +0 -8
  173. package/src/aws/types/proxytypes.mts +0 -27
  174. package/src/aws/types/tags.mts +0 -3
  175. package/src/database/cached.mts +0 -64
  176. package/src/database/database.mts +0 -107
  177. package/src/database/last-updated.mts +0 -103
  178. package/src/database/models.mts +0 -7
  179. package/src/index.mts +0 -2
  180. package/src/marine/id_utils.mts +0 -30
  181. package/src/marine/rtz.mts +0 -57
  182. package/src/test/asserter.mts +0 -58
  183. package/src/test/db-testutils.mts +0 -52
  184. package/src/test/httpserver.mts +0 -111
  185. package/src/test/secrets-manager.mts +0 -37
  186. package/src/test/testutils.mts +0 -39
  187. package/src/types/async-timeout-error.mts +0 -5
  188. package/src/types/aws-env.mts +0 -3
  189. package/src/types/either.mts +0 -9
  190. package/src/types/http-error.mts +0 -8
  191. package/src/types/input-error.mts +0 -2
  192. package/src/types/language.mts +0 -3
  193. package/src/types/nullable.mts +0 -21
  194. package/src/types/traffictype.mts +0 -8
  195. package/src/types/urn.mts +0 -1
  196. package/src/types/util-types.mts +0 -10
  197. package/src/types/validator.mts +0 -10
  198. package/src/utils/api-model.mts +0 -133
  199. package/src/utils/base64.mts +0 -16
  200. package/src/utils/date-utils.mts +0 -53
  201. package/src/utils/geojson-types.mts +0 -22
  202. package/src/utils/geometry.mts +0 -171
  203. package/src/utils/logging.mts +0 -75
  204. package/src/utils/retry.mts +0 -200
  205. package/src/utils/slack.mts +0 -26
  206. package/src/utils/utils.mts +0 -184
@@ -0,0 +1,108 @@
1
+ import { Writable } from "stream";
2
+ import { DtLogger } from "../../aws/runtime/dt-logger.mjs";
3
+ const LOG_LINE = {
4
+ method: "dt-logger.test",
5
+ message: "FOO",
6
+ };
7
+ describe("dt-logger", () => {
8
+ function assertLog(config, message, expected) {
9
+ assertWrite(config, (logger) => {
10
+ logger.info(message);
11
+ }, expected);
12
+ }
13
+ function assertDebug(config, message, expected) {
14
+ assertWrite(config, (logger) => {
15
+ logger.debug(message);
16
+ }, expected);
17
+ }
18
+ function assertWrite(config, writeFunction, expected) {
19
+ const logged = [];
20
+ const writeStream = new Writable({
21
+ write: (chunk) => {
22
+ logged.push(chunk.toString());
23
+ },
24
+ });
25
+ const logger = new DtLogger({
26
+ ...config,
27
+ ...{ writeStream: writeStream },
28
+ });
29
+ writeFunction(logger);
30
+ expect(logged.length).toBe(1);
31
+ const loggedLine = JSON.parse(logged[0]);
32
+ console.info(loggedLine);
33
+ if (typeof expected === "object" &&
34
+ "stack" in expected &&
35
+ expected.stack) {
36
+ const stack = loggedLine['stack'];
37
+ delete loggedLine['stack'];
38
+ delete expected.stack;
39
+ expect(stack).toBeDefined();
40
+ }
41
+ expect(loggedLine).toMatchObject(expected);
42
+ }
43
+ test("custom values", () => {
44
+ const date = new Date();
45
+ assertLog({}, {
46
+ ...LOG_LINE,
47
+ customDate: date,
48
+ }, {
49
+ ...LOG_LINE,
50
+ date: date.toISOString(),
51
+ });
52
+ });
53
+ test("custom count should be a number", () => {
54
+ assertLog({}, {
55
+ ...LOG_LINE,
56
+ customFooCount: 123,
57
+ }, {
58
+ ...LOG_LINE,
59
+ fooCount: 123,
60
+ });
61
+ });
62
+ test("default values", () => {
63
+ assertLog({}, LOG_LINE, {
64
+ method: LOG_LINE.method,
65
+ message: LOG_LINE.message,
66
+ level: "INFO",
67
+ });
68
+ });
69
+ test("set lambdaName", () => {
70
+ const LAMBDA_NAME = "test_lambda_name";
71
+ assertLog({ lambdaName: LAMBDA_NAME }, LOG_LINE, {
72
+ lambdaName: LAMBDA_NAME,
73
+ method: LOG_LINE.method,
74
+ message: LOG_LINE.message,
75
+ level: "INFO",
76
+ });
77
+ });
78
+ test("set runtime", () => {
79
+ const RUNTIME = "test_runtime";
80
+ assertLog({ runTime: RUNTIME }, LOG_LINE, {
81
+ message: LOG_LINE.message,
82
+ method: LOG_LINE.method,
83
+ level: "INFO",
84
+ runtime: RUNTIME,
85
+ });
86
+ });
87
+ test("debug - string", () => {
88
+ const DEBUG_STRING = "debug string";
89
+ assertDebug({}, DEBUG_STRING, {
90
+ message: DEBUG_STRING,
91
+ level: "DEBUG",
92
+ });
93
+ });
94
+ test("debug - json", () => {
95
+ const DEBUG_JSON = {
96
+ debug: "debug",
97
+ thing: 42,
98
+ };
99
+ assertDebug({}, DEBUG_JSON, {
100
+ message: {
101
+ debug: "debug",
102
+ thing: 42,
103
+ },
104
+ level: "DEBUG",
105
+ });
106
+ });
107
+ });
108
+ //# sourceMappingURL=dt-logger.test.mjs.map
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,89 @@
1
+ import { mockSecret, stubSecretsManager } from "../../test/secrets-manager.mjs";
2
+ import sinon from "sinon";
3
+ const SECRET_WITH_PREFIX = {
4
+ "prefix.value": "value",
5
+ "prefix.name": "name",
6
+ "wrong.value": "value",
7
+ username: "DB_USER",
8
+ };
9
+ const SECRET_EMPTY = {};
10
+ const stubSM = stubSecretsManager();
11
+ const secretHolder = await import("../../aws/runtime/secrets/secret-holder.mjs");
12
+ const database = await import("../../database/database.mjs");
13
+ const { SecretHolder } = secretHolder;
14
+ const { DatabaseEnvironmentKeys } = database;
15
+ describe("SecretHolder - tests", () => {
16
+ beforeEach(() => {
17
+ process.env['SECRET_ID'] = "test-id";
18
+ });
19
+ afterEach(() => {
20
+ sinon.restore();
21
+ sinon.reset();
22
+ // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
23
+ delete process.env[DatabaseEnvironmentKeys.DB_USER];
24
+ });
25
+ test("get - no secret", () => {
26
+ mockSecret(null);
27
+ const holder = SecretHolder.create();
28
+ const secret = holder.get();
29
+ return expect(secret).rejects.toThrowError("No secret found!");
30
+ }, 10000);
31
+ test("get - empty secret", () => {
32
+ mockSecret(SECRET_EMPTY);
33
+ const holder = SecretHolder.create();
34
+ const secret = holder.get();
35
+ return expect(secret).resolves.toEqual(SECRET_EMPTY);
36
+ });
37
+ test("get - no prefix", () => {
38
+ mockSecret(SECRET_WITH_PREFIX);
39
+ const holder = SecretHolder.create();
40
+ const secret = holder.get();
41
+ return expect(secret).resolves.toEqual(SECRET_WITH_PREFIX);
42
+ });
43
+ test("get - check keys - not found", () => {
44
+ mockSecret(SECRET_WITH_PREFIX);
45
+ const holder = SecretHolder.create("", ["not_found"]);
46
+ const secret = holder.get();
47
+ return expect(secret).rejects.toThrow();
48
+ });
49
+ test("get - check keys - found", () => {
50
+ mockSecret(SECRET_WITH_PREFIX);
51
+ const holder = SecretHolder.create("", ["prefix.value", "username"]);
52
+ return expect(holder.get()).resolves.toBeDefined();
53
+ });
54
+ test("getSecret - with prefix", () => {
55
+ mockSecret(SECRET_WITH_PREFIX);
56
+ const holder = SecretHolder.create("prefix");
57
+ const secret = holder.get();
58
+ return expect(secret).resolves.toEqual({
59
+ value: "value",
60
+ name: "name",
61
+ });
62
+ });
63
+ test("get - ttl - do not fetch", async () => {
64
+ mockSecret(SECRET_WITH_PREFIX);
65
+ const holder = SecretHolder.create();
66
+ const callCount = stubSM.callCount;
67
+ await holder.get();
68
+ expect(stubSM.callCount).toEqual(callCount + 1);
69
+ // gets cached secret
70
+ await holder.get();
71
+ expect(stubSM.callCount).toEqual(callCount + 1);
72
+ });
73
+ test("get - ttl - fetch", async () => {
74
+ mockSecret(SECRET_WITH_PREFIX);
75
+ const holder = new SecretHolder("", "", [], {
76
+ ttl: 1,
77
+ });
78
+ const callCount = stubSM.callCount;
79
+ await holder.get();
80
+ expect(stubSM.callCount).toEqual(callCount + 1);
81
+ // cache expires, fetches secret again
82
+ const start = Date.now();
83
+ while (Date.now() < start + 2000)
84
+ ;
85
+ await holder.get();
86
+ expect(stubSM.callCount).toEqual(callCount + 2);
87
+ });
88
+ });
89
+ //# sourceMappingURL=secret-holder.test.mjs.map
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,42 @@
1
+ import { mockSecret, stubSecretsManager } from "../../test/secrets-manager.mjs";
2
+ import sinon from "sinon";
3
+ const SECRET_ID = "test_secret";
4
+ const SECRET_WITH_PREFIX = {
5
+ "prefix.value": "value",
6
+ "prefix.name": "name",
7
+ "wrong.value": "value",
8
+ };
9
+ const SECRET_EMPTY = {};
10
+ stubSecretsManager();
11
+ const secret = await import("../../aws/runtime/secrets/secret.mjs");
12
+ const { getSecret } = secret;
13
+ describe("secret - test", () => {
14
+ afterEach(() => {
15
+ sinon.restore();
16
+ });
17
+ test("getSecret - no secret", async () => {
18
+ mockSecret(null);
19
+ await expect(async () => {
20
+ await getSecret(SECRET_ID, "");
21
+ }).rejects.toThrowError("No secret found!");
22
+ });
23
+ test("getSecret - empty secret", async () => {
24
+ mockSecret(SECRET_EMPTY);
25
+ const secret = await getSecret(SECRET_ID, "");
26
+ expect(secret).toEqual(SECRET_EMPTY);
27
+ });
28
+ test("getSecret - no prefix", async () => {
29
+ mockSecret(SECRET_WITH_PREFIX);
30
+ const secret = await getSecret(SECRET_ID, "");
31
+ expect(secret).toEqual(SECRET_WITH_PREFIX);
32
+ });
33
+ test("getSecret - with prefix", async () => {
34
+ mockSecret(SECRET_WITH_PREFIX);
35
+ const secret = await getSecret(SECRET_ID, "prefix");
36
+ expect(secret).toEqual({
37
+ value: "value",
38
+ name: "name",
39
+ });
40
+ });
41
+ });
42
+ //# sourceMappingURL=secret.test.mjs.map
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,154 @@
1
+ import { TestHttpServer, ERROR_NO_MATCH, ERRORCODE_NOT_FOUND, } from "../../test/httpserver.mjs";
2
+ import { IncomingMessage } from "http";
3
+ import { Socket } from "net";
4
+ import { AsyncLocalStorage } from "node:async_hooks";
5
+ import * as http from "http";
6
+ import { expect } from "@jest/globals";
7
+ const threadLocalPort = new AsyncLocalStorage();
8
+ const DEFAULT_PATH = "/";
9
+ const DEFAULT_PROPS = {
10
+ "/": () => "",
11
+ };
12
+ const findOpenPort = async (excludedPorts) => {
13
+ const ephemeralPorts = Array.from({ length: 65535 - 1024 + 1 }, (__, i) => 1024 + i);
14
+ const allSocketEvents = [
15
+ "close",
16
+ "connect",
17
+ "data",
18
+ "drain",
19
+ "end",
20
+ "error",
21
+ "lookup",
22
+ "ready",
23
+ "timeout",
24
+ ];
25
+ let openPort = null;
26
+ for (const testPort of ephemeralPorts) {
27
+ if (openPort !== null) {
28
+ break;
29
+ }
30
+ if (excludedPorts.has(testPort)) {
31
+ continue;
32
+ }
33
+ const portConnected = new Promise((resolve) => {
34
+ const socket = new Socket();
35
+ socket.setTimeout(500);
36
+ for (const socketEvent of allSocketEvents) {
37
+ if (socketEvent === "error") {
38
+ socket.on(socketEvent, (error) => {
39
+ socket.destroy();
40
+ if (error.code === "ECONNREFUSED") {
41
+ resolve(testPort);
42
+ }
43
+ else {
44
+ resolve(null);
45
+ }
46
+ });
47
+ }
48
+ else {
49
+ socket.on(socketEvent, () => {
50
+ socket.destroy();
51
+ resolve(null);
52
+ });
53
+ }
54
+ }
55
+ // connect method is asynchronous. That is why we wrap this thing inside of a promise.
56
+ socket.connect({ port: testPort, host: "127.0.0.1" });
57
+ });
58
+ openPort = await portConnected;
59
+ }
60
+ if (openPort === null) {
61
+ throw Error("All ephemeral ports in use!");
62
+ }
63
+ return openPort;
64
+ };
65
+ const usedPorts = new Set();
66
+ async function withServer(fn, props = DEFAULT_PROPS, statusCode = 200) {
67
+ const server = new TestHttpServer();
68
+ let openPort;
69
+ while (!openPort) {
70
+ const foundPort = await findOpenPort(usedPorts);
71
+ console.info(`foundPort ${foundPort}`);
72
+ if (!usedPorts.has(foundPort)) {
73
+ usedPorts.add(foundPort);
74
+ openPort = foundPort;
75
+ }
76
+ }
77
+ console.info(`Using port ${openPort} to run the test`);
78
+ server.listen(openPort, props, false, statusCode);
79
+ threadLocalPort.enterWith(openPort);
80
+ try {
81
+ await fn(server);
82
+ }
83
+ finally {
84
+ await server.close();
85
+ console.info("Server closed");
86
+ }
87
+ }
88
+ function sendGetRequest(path = DEFAULT_PATH) {
89
+ return sendRequest("GET", path);
90
+ }
91
+ function sendPostRequest(path = DEFAULT_PATH, body) {
92
+ return sendRequest("POST", path, body);
93
+ }
94
+ function sendRequest(method, path, body) {
95
+ return new Promise((resolve, reject) => {
96
+ const port = threadLocalPort.getStore();
97
+ const request = http.request({
98
+ path,
99
+ port,
100
+ method,
101
+ }, (response) => {
102
+ response.on("data", () => {
103
+ // do nothing
104
+ });
105
+ //the whole response has been received, so we just print it out here
106
+ response.on("end", () => {
107
+ resolve(response);
108
+ });
109
+ response.on("error", (error) => {
110
+ reject(error);
111
+ });
112
+ });
113
+ if (method === "POST") {
114
+ request.write(body);
115
+ }
116
+ request.end();
117
+ });
118
+ }
119
+ test("no calls", () => {
120
+ return withServer((server) => {
121
+ expect(server.getCallCount()).toEqual(0);
122
+ });
123
+ });
124
+ test("one get", async () => {
125
+ await withServer(async (server) => {
126
+ await sendGetRequest();
127
+ expect(server.getCallCount()).toEqual(1);
128
+ });
129
+ });
130
+ test("one get - no MATCH", async () => {
131
+ await withServer(async (server) => {
132
+ const response = await sendGetRequest("/no-match");
133
+ expect(server.getCallCount()).toEqual(1);
134
+ expect(server.getRequestBody(0)).toEqual(ERROR_NO_MATCH);
135
+ expect(response.statusCode).toEqual(ERRORCODE_NOT_FOUND);
136
+ });
137
+ });
138
+ test("get - error 405", async () => {
139
+ const ERROR_CODE = 405;
140
+ await withServer(async (server) => {
141
+ const response = await sendGetRequest();
142
+ expect(server.getCallCount()).toEqual(1);
143
+ expect(response.statusCode).toEqual(ERROR_CODE);
144
+ }, DEFAULT_PROPS, ERROR_CODE);
145
+ });
146
+ test("one post", async () => {
147
+ await withServer(async (server) => {
148
+ const testBody = "Testing123!";
149
+ await sendPostRequest(DEFAULT_PATH, testBody);
150
+ expect(server.getCallCount()).toEqual(1);
151
+ expect(server.getRequestBody(0)).toEqual(testBody);
152
+ });
153
+ });
154
+ //# sourceMappingURL=httpserver.test.mjs.map
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,58 @@
1
+ import { LambdaResponse } from "../../aws/types/lambda-response.mjs";
2
+ describe("lambda-response", () => {
3
+ const TEST_MESSAGE = "HELLO";
4
+ const TEST_COUNT = 12;
5
+ const TEST_FILENAME = "file.txt";
6
+ const TEST_TIMESTAMP = new Date();
7
+ const TEST_JSON = {
8
+ message: TEST_MESSAGE,
9
+ count: TEST_COUNT,
10
+ };
11
+ function assertJson(response, expectedJson, expectedStatus, expectedFilename, expectedTimestamp) {
12
+ const body = JSON.parse(Buffer.from(response.body, "base64").toString());
13
+ expect(body).toEqual(expectedJson);
14
+ expect(response.status).toEqual(expectedStatus);
15
+ expect(response.fileName).toEqual(expectedFilename);
16
+ expect(response.timestamp).toEqual(expectedTimestamp?.toUTCString());
17
+ }
18
+ function assertBinary(response, expectedString, expectedStatus, expectedFilename, expectedTimestamp) {
19
+ const body = Buffer.from(response.body, "base64").toString();
20
+ expect(body).toEqual(expectedString);
21
+ expect(response.status).toEqual(expectedStatus);
22
+ expect(response.fileName).toEqual(expectedFilename);
23
+ expect(response.timestamp).toEqual(expectedTimestamp?.toUTCString());
24
+ }
25
+ test("okJson - without fileName", () => {
26
+ const response = LambdaResponse.okJson(TEST_JSON);
27
+ assertJson(response, TEST_JSON, 200);
28
+ });
29
+ test("okJson - with fileName", () => {
30
+ const response = LambdaResponse.okJson(TEST_JSON, TEST_FILENAME);
31
+ assertJson(response, TEST_JSON, 200, TEST_FILENAME);
32
+ });
33
+ test("okJson - with fileName and timestamp", () => {
34
+ const response = LambdaResponse.okJson(TEST_JSON, TEST_FILENAME).withTimestamp(TEST_TIMESTAMP);
35
+ assertJson(response, TEST_JSON, 200, TEST_FILENAME, TEST_TIMESTAMP);
36
+ });
37
+ test("okBinary - with fileName and timestamp", () => {
38
+ const response = LambdaResponse.okBinary(Buffer.from(TEST_MESSAGE).toString("base64"), TEST_FILENAME).withTimestamp(TEST_TIMESTAMP);
39
+ assertBinary(response, TEST_MESSAGE, 200, TEST_FILENAME, TEST_TIMESTAMP);
40
+ });
41
+ test("badRequest", () => {
42
+ const response = LambdaResponse.badRequest(TEST_MESSAGE);
43
+ assertBinary(response, TEST_MESSAGE, 400);
44
+ });
45
+ test("notFound", () => {
46
+ const response = LambdaResponse.notFound();
47
+ assertBinary(response, "Not found", 404);
48
+ });
49
+ test("internalError", () => {
50
+ const response = LambdaResponse.internalError();
51
+ assertBinary(response, "Internal error", 500);
52
+ });
53
+ test("notImplemented", () => {
54
+ const response = LambdaResponse.notImplemented();
55
+ assertBinary(response, "Not implemented", 501);
56
+ });
57
+ });
58
+ //# sourceMappingURL=lambda-response.test.mjs.map
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,27 @@
1
+ import { parseISO } from "date-fns";
2
+ import * as CommonDateUtils from "../../utils/date-utils.mjs";
3
+ const ISO = "2022-01-02T01:02:03.004Z";
4
+ describe("CommonDateUtilsTest", () => {
5
+ test("dateFromIsoString", () => {
6
+ const parsed = CommonDateUtils.dateFromIsoString(ISO);
7
+ expect(parsed.toISOString()).toEqual(ISO);
8
+ });
9
+ test("dateFromIsoString fails", () => {
10
+ expect(() => CommonDateUtils.dateFromIsoString(ISO + "foobar")).toThrowError();
11
+ });
12
+ test("countDiffMs", () => {
13
+ const start = new Date();
14
+ const end = new Date(start.getTime() + 1234);
15
+ expect(CommonDateUtils.countDiffMs(start, end)).toEqual(1234);
16
+ });
17
+ test("countDiffMs", () => {
18
+ const start = new Date();
19
+ const end = new Date(start.getTime() + 1234 * 1000);
20
+ expect(CommonDateUtils.countDiffInSeconds(start, end)).toEqual(1234);
21
+ });
22
+ test("dateFromIsoString", () => {
23
+ const date = parseISO("2023-01-01T00:00Z");
24
+ expect(CommonDateUtils.dateToUTCString(date, CommonDateUtils.MYSQL_DATETIME_FORMAT)).toEqual("2023-01-01 00:00");
25
+ });
26
+ });
27
+ //# sourceMappingURL=date-utils.test.mjs.map
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,24 @@
1
+ import { Asserter } from "../../test/asserter.mjs";
2
+ import * as Geometry from "../../utils/geometry.mjs";
3
+ const TAMPERE_WGS84_X = 23.761290078;
4
+ const TAMPERE_WGS84_Y = 61.49774257;
5
+ const KUOPIO_WGS84_X = 27.688935;
6
+ const KUOPIO_WGS84_Y = 62.892983;
7
+ const TAMPERE_KUOPIO_DISTANCE_KM = 255.8;
8
+ describe("CommonGeometryTest", () => {
9
+ test("distanceBetweenWGS84PointsInKm", () => {
10
+ Asserter.assertToBeCloseTo(Geometry.distanceBetweenPositionsInKm([TAMPERE_WGS84_X, TAMPERE_WGS84_Y], [KUOPIO_WGS84_X, KUOPIO_WGS84_Y]), TAMPERE_KUOPIO_DISTANCE_KM, 0.5);
11
+ console.info(Geometry.distanceBetweenPositionsInKm([TAMPERE_WGS84_X, TAMPERE_WGS84_Y], [KUOPIO_WGS84_X, KUOPIO_WGS84_Y]));
12
+ });
13
+ test("distanceBetweenWGS84PointsInKm", () => {
14
+ Asserter.assertToBeCloseTo(Geometry.distanceBetweenPositionsInM([TAMPERE_WGS84_X, TAMPERE_WGS84_Y], [KUOPIO_WGS84_X, KUOPIO_WGS84_Y]), TAMPERE_KUOPIO_DISTANCE_KM * 1000, 500);
15
+ console.info(Geometry.distanceBetweenPositionsInM([TAMPERE_WGS84_X, TAMPERE_WGS84_Y], [KUOPIO_WGS84_X, KUOPIO_WGS84_Y]));
16
+ });
17
+ test("areDistinctPositions", () => {
18
+ expect(Geometry.areDistinctPositions([1, 2], [1, 2])).toBe(false);
19
+ expect(Geometry.areDistinctPositions([1.1, 2.2], [1.1, 2.2])).toBe(false);
20
+ expect(Geometry.areDistinctPositions([1, 2.1], [1, 2])).toBe(true);
21
+ expect(Geometry.areDistinctPositions([1, 2], [1, 2.000000000000001])).toBe(true);
22
+ });
23
+ });
24
+ //# sourceMappingURL=geometry.test.mjs.map
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,78 @@
1
+ import { AxiosError } from "axios";
2
+ import { Writable } from "stream";
3
+ import { DtLogger } from "../../aws/runtime/dt-logger.mjs";
4
+ import { logException } from "../../utils/logging.mjs";
5
+ const TEST_METHODNAME = "test.logException";
6
+ describe("dt-logger", () => {
7
+ function assertLogError(error, expected, includeStack = false) {
8
+ assertWrite((logger) => {
9
+ logException(logger, error, includeStack);
10
+ }, expected);
11
+ }
12
+ function assertAxiosError(error, expected) {
13
+ assertWrite((logger) => {
14
+ logException(logger, error);
15
+ }, expected);
16
+ }
17
+ function assertWrite(writeFunction, expected) {
18
+ const logged = [];
19
+ const writeStream = new Writable({
20
+ write: (chunk) => {
21
+ logged.push(chunk.toString());
22
+ },
23
+ });
24
+ const logger = new DtLogger({
25
+ ...{ writeStream: writeStream },
26
+ });
27
+ writeFunction(logger);
28
+ expect(logged.length).toBe(1);
29
+ const loggedLine = JSON.parse(logged[0]);
30
+ console.info(loggedLine);
31
+ if (expected.stack) {
32
+ const stack = loggedLine.stack;
33
+ delete loggedLine.stack;
34
+ delete expected.stack;
35
+ expect(stack).toBeDefined();
36
+ }
37
+ expect(loggedLine).toEqual(expected);
38
+ }
39
+ test("log error - string", () => {
40
+ const STRING_ERROR = "string error";
41
+ assertLogError(STRING_ERROR, {
42
+ type: "Error",
43
+ method: TEST_METHODNAME,
44
+ message: STRING_ERROR,
45
+ level: "ERROR",
46
+ });
47
+ });
48
+ test("log error - error", () => {
49
+ const ERROR = new Error("Errormessage");
50
+ assertLogError(ERROR, {
51
+ type: "Error",
52
+ method: TEST_METHODNAME,
53
+ message: ERROR.message,
54
+ level: "ERROR",
55
+ });
56
+ });
57
+ test("log error - error with stack", () => {
58
+ const ERROR = new Error("Errormessage");
59
+ assertLogError(ERROR, {
60
+ type: "Error",
61
+ method: TEST_METHODNAME,
62
+ message: ERROR.message,
63
+ level: "ERROR",
64
+ stack: true,
65
+ }, true);
66
+ });
67
+ test("log error - AxiosError", () => {
68
+ const ERROR = new AxiosError("ErrorFromAxios", "12");
69
+ assertAxiosError(ERROR, {
70
+ type: "Error",
71
+ method: TEST_METHODNAME,
72
+ message: ERROR.message,
73
+ level: "ERROR",
74
+ code: ERROR.code,
75
+ });
76
+ });
77
+ });
78
+ //# sourceMappingURL=logging.test.mjs.map
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,43 @@
1
+ import * as ArrayUtils from "../../utils/utils.mjs";
2
+ describe("ArrayUtils", () => {
3
+ test("bothArraysHasSameValues", () => {
4
+ expect(ArrayUtils.bothArraysHasSameValues([], [])).toEqual(true);
5
+ expect(ArrayUtils.bothArraysHasSameValues(["a"], ["a"])).toEqual(true);
6
+ expect(ArrayUtils.bothArraysHasSameValues(["a"], ["a", "a"])).toEqual(true);
7
+ expect(ArrayUtils.bothArraysHasSameValues(["a", "a"], ["a", "a"])).toEqual(true);
8
+ expect(ArrayUtils.bothArraysHasSameValues(null, null)).toEqual(true);
9
+ expect(ArrayUtils.bothArraysHasSameValues(undefined, undefined)).toEqual(true);
10
+ expect(ArrayUtils.bothArraysHasSameValues(null, undefined)).toEqual(true);
11
+ expect(ArrayUtils.bothArraysHasSameValues(["a"], undefined)).toEqual(false);
12
+ expect(ArrayUtils.bothArraysHasSameValues(["a"], null)).toEqual(false);
13
+ /* eslint-enable */
14
+ expect(ArrayUtils.bothArraysHasSameValues(["a", "b"], ["a", "a"])).toEqual(false);
15
+ expect(ArrayUtils.bothArraysHasSameValues(["a", "a", "a"], ["a", "b", "c"])).toEqual(false);
16
+ const o1 = { a: 1, b: 2 };
17
+ const o2 = { a: 1, b: 2 };
18
+ // Objects are references to same
19
+ expect(ArrayUtils.bothArraysHasSameValues([o1], [o1])).toEqual(true);
20
+ // Object's are not the same but the contents are the same
21
+ expect(ArrayUtils.bothArraysHasSameValues([o1], [o2])).toEqual(false);
22
+ });
23
+ test("getFirst - empty throws", () => {
24
+ expect(() => {
25
+ ArrayUtils.getFirst([]);
26
+ }).toThrow();
27
+ });
28
+ test("getFirst - two objects", () => {
29
+ expect(ArrayUtils.getFirst([1, 2])).toEqual(1);
30
+ });
31
+ test("getFirst - two objects with sort function", () => {
32
+ expect(ArrayUtils.getFirst([1, 2], (a) => -a)).toEqual(2);
33
+ });
34
+ test("getLast - empty throws", () => {
35
+ expect(() => {
36
+ ArrayUtils.getLast([]);
37
+ }).toThrow();
38
+ });
39
+ test("getLast - two objects", () => {
40
+ expect(ArrayUtils.getLast([1, 2])).toEqual(2);
41
+ });
42
+ });
43
+ //# sourceMappingURL=utils.test.mjs.map
@@ -1,4 +1,6 @@
1
1
  import { getEnvVariableOrElse } from "../../../utils/utils.mjs";
2
+ import { DtLogger } from "../../runtime/dt-logger.mjs";
3
+ import { LambdaResponse } from "../../types/lambda-response.mjs";
2
4
  const functionName = getEnvVariableOrElse("AWS_LAMBDA_FUNCTION_NAME", "test");
3
5
  /**
4
6
  * Factory class for creating lambda-handler functions. You can set functionality to handle logging and error-handling,
@@ -10,6 +12,8 @@ const functionName = getEnvVariableOrElse("AWS_LAMBDA_FUNCTION_NAME", "test");
10
12
  * creating handler-functions for your lambdas.
11
13
  */
12
14
  export class HandlerFactory {
15
+ loggingHandler;
16
+ errorHandler;
13
17
  constructor() {
14
18
  this.loggingHandler = async (method) => {
15
19
  const start = Date.now();