@digitraffic/common 2024.1.24-3 → 2024.3.11-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 (212) 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 +86 -0
  15. package/dist/__test__/secrets/secret.test.d.mts +1 -0
  16. package/dist/__test__/secrets/secret.test.mjs +38 -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__/test/mock-ky.test.d.mts +1 -0
  20. package/dist/__test__/test/mock-ky.test.mjs +46 -0
  21. package/dist/__test__/types/lambda-response.test.d.mts +1 -0
  22. package/dist/__test__/types/lambda-response.test.mjs +58 -0
  23. package/dist/__test__/utils/date-utils.test.d.mts +1 -0
  24. package/dist/__test__/utils/date-utils.test.mjs +27 -0
  25. package/dist/__test__/utils/geometry.test.d.mts +1 -0
  26. package/dist/__test__/utils/geometry.test.mjs +24 -0
  27. package/dist/__test__/utils/logging.test.d.mts +1 -0
  28. package/dist/__test__/utils/logging.test.mjs +78 -0
  29. package/dist/__test__/utils/utils.test.d.mts +1 -0
  30. package/dist/__test__/utils/utils.test.mjs +43 -0
  31. package/dist/aws/infra/api/handler-factory.mjs +4 -0
  32. package/dist/aws/infra/api/integration.d.mts +2 -2
  33. package/dist/aws/infra/api/integration.mjs +4 -1
  34. package/dist/aws/infra/api/response.d.mts +1 -1
  35. package/dist/aws/infra/api/responses.d.mts +1 -1
  36. package/dist/aws/infra/api/responses.mjs +2 -0
  37. package/dist/aws/infra/api/static-integration.mjs +1 -1
  38. package/dist/aws/infra/canaries/canary-alarm.d.mts +1 -1
  39. package/dist/aws/infra/canaries/canary-alarm.mjs +2 -0
  40. package/dist/aws/infra/canaries/canary-parameters.mjs +1 -1
  41. package/dist/aws/infra/canaries/canary-role.mjs +1 -0
  42. package/dist/aws/infra/canaries/canary.d.mts +2 -2
  43. package/dist/aws/infra/canaries/canary.mjs +2 -0
  44. package/dist/aws/infra/canaries/database-canary.d.mts +2 -2
  45. package/dist/aws/infra/canaries/database-canary.mjs +2 -0
  46. package/dist/aws/infra/canaries/database-checker.d.mts +1 -1
  47. package/dist/aws/infra/canaries/database-checker.mjs +7 -1
  48. package/dist/aws/infra/canaries/url-canary.d.mts +2 -2
  49. package/dist/aws/infra/canaries/url-canary.mjs +3 -0
  50. package/dist/aws/infra/canaries/url-checker.d.mts +1 -1
  51. package/dist/aws/infra/canaries/url-checker.mjs +4 -1
  52. package/dist/aws/infra/documentation.mjs +5 -1
  53. package/dist/aws/infra/import-util.d.mts +1 -1
  54. package/dist/aws/infra/import-util.mjs +4 -3
  55. package/dist/aws/infra/scheduler.mjs +2 -0
  56. package/dist/aws/infra/security-rule.d.mts +1 -1
  57. package/dist/aws/infra/security-rule.mjs +1 -0
  58. package/dist/aws/infra/sqs-integration.d.mts +1 -1
  59. package/dist/aws/infra/sqs-integration.mjs +3 -1
  60. package/dist/aws/infra/sqs-queue.d.mts +1 -1
  61. package/dist/aws/infra/sqs-queue.mjs +2 -1
  62. package/dist/aws/infra/stack/lambda-configs.d.mts +4 -4
  63. package/dist/aws/infra/stack/lambda-configs.mjs +4 -2
  64. package/dist/aws/infra/stack/monitoredfunction.d.mts +3 -3
  65. package/dist/aws/infra/stack/monitoredfunction.mjs +23 -18
  66. package/dist/aws/infra/stack/parameters.mjs +1 -0
  67. package/dist/aws/infra/stack/rest_apis.d.mts +2 -2
  68. package/dist/aws/infra/stack/rest_apis.mjs +6 -1
  69. package/dist/aws/infra/stack/stack-checking-aspect.d.mts +2 -2
  70. package/dist/aws/infra/stack/stack-checking-aspect.mjs +6 -1
  71. package/dist/aws/infra/stack/stack.d.mts +5 -5
  72. package/dist/aws/infra/stack/stack.mjs +9 -0
  73. package/dist/aws/infra/stack/subscription.mjs +4 -0
  74. package/dist/aws/infra/stacks/db-dns-stack.d.mts +1 -1
  75. package/dist/aws/infra/stacks/db-dns-stack.mjs +1 -0
  76. package/dist/aws/infra/stacks/db-proxy-stack.d.mts +3 -3
  77. package/dist/aws/infra/stacks/db-proxy-stack.mjs +4 -2
  78. package/dist/aws/infra/stacks/db-stack.d.mts +3 -3
  79. package/dist/aws/infra/stacks/db-stack.mjs +11 -7
  80. package/dist/aws/infra/stacks/intra-stack-configuration.d.mts +1 -1
  81. package/dist/aws/infra/stacks/network-stack.d.mts +2 -2
  82. package/dist/aws/infra/stacks/network-stack.mjs +8 -0
  83. package/dist/aws/infra/usage-plans.d.mts +1 -1
  84. package/dist/aws/infra/usage-plans.mjs +1 -0
  85. package/dist/aws/runtime/apikey.d.mts +2 -2
  86. package/dist/aws/runtime/apikey.mjs +2 -2
  87. package/dist/aws/runtime/digitraffic-integration-response.d.mts +1 -1
  88. package/dist/aws/runtime/dt-logger.mjs +6 -2
  89. package/dist/aws/runtime/messaging.d.mts +2 -2
  90. package/dist/aws/runtime/messaging.mjs +5 -4
  91. package/dist/aws/runtime/s3.d.mts +4 -2
  92. package/dist/aws/runtime/s3.mjs +15 -10
  93. package/dist/aws/runtime/secrets/dbsecret.d.mts +1 -1
  94. package/dist/aws/runtime/secrets/proxy-holder.mjs +1 -0
  95. package/dist/aws/runtime/secrets/rds-holder.mjs +1 -0
  96. package/dist/aws/runtime/secrets/secret-holder.d.mts +1 -1
  97. package/dist/aws/runtime/secrets/secret-holder.mjs +6 -1
  98. package/dist/aws/runtime/secrets/secret.mjs +5 -6
  99. package/dist/aws/types/errors.mjs +1 -0
  100. package/dist/aws/types/lambda-response.mjs +5 -0
  101. package/dist/aws/types/model-with-reference.mjs +1 -1
  102. package/dist/database/cached.d.mts +1 -1
  103. package/dist/database/database.mjs +1 -0
  104. package/dist/database/last-updated.d.mts +1 -1
  105. package/dist/test/db-testutils.d.mts +1 -1
  106. package/dist/test/db-testutils.mjs +1 -1
  107. package/dist/test/httpserver.mjs +7 -3
  108. package/dist/test/mock-ky.d.mts +2 -0
  109. package/dist/test/mock-ky.mjs +15 -0
  110. package/dist/test/secrets-manager.d.mts +3 -2
  111. package/dist/test/secrets-manager.mjs +14 -16
  112. package/dist/test/testutils.mjs +1 -1
  113. package/dist/types/http-error.mjs +1 -0
  114. package/dist/types/nullable.d.mts +1 -1
  115. package/dist/utils/api-model.d.mts +2 -2
  116. package/dist/utils/api-model.mjs +1 -1
  117. package/dist/utils/geojson-types.d.mts +1 -1
  118. package/dist/utils/geojson-types.mjs +4 -2
  119. package/dist/utils/geometry.d.mts +1 -1
  120. package/dist/utils/geometry.mjs +3 -0
  121. package/dist/utils/logging.mjs +2 -2
  122. package/dist/utils/retry.d.mts +2 -2
  123. package/dist/utils/retry.mjs +2 -2
  124. package/dist/utils/slack.mjs +4 -3
  125. package/dist/utils/utils.d.mts +2 -2
  126. package/package.json +25 -15
  127. package/src/@types/geojson-validation/index.d.mts +0 -4
  128. package/src/aws/infra/api/handler-factory.mts +0 -86
  129. package/src/aws/infra/api/integration.mts +0 -147
  130. package/src/aws/infra/api/response.mts +0 -165
  131. package/src/aws/infra/api/responses.mts +0 -127
  132. package/src/aws/infra/api/static-integration.mts +0 -108
  133. package/src/aws/infra/canaries/Synthetics.d.mts +0 -21
  134. package/src/aws/infra/canaries/canary-alarm.mts +0 -33
  135. package/src/aws/infra/canaries/canary-keys.mts +0 -3
  136. package/src/aws/infra/canaries/canary-parameters.mts +0 -19
  137. package/src/aws/infra/canaries/canary-role.mts +0 -73
  138. package/src/aws/infra/canaries/canary.mts +0 -44
  139. package/src/aws/infra/canaries/database-canary.mts +0 -98
  140. package/src/aws/infra/canaries/database-checker.mts +0 -163
  141. package/src/aws/infra/canaries/url-canary.mts +0 -98
  142. package/src/aws/infra/canaries/url-checker.mts +0 -388
  143. package/src/aws/infra/documentation.mts +0 -142
  144. package/src/aws/infra/import-util.mts +0 -57
  145. package/src/aws/infra/scheduler.mts +0 -59
  146. package/src/aws/infra/security-rule.mts +0 -38
  147. package/src/aws/infra/sqs-integration.mts +0 -106
  148. package/src/aws/infra/sqs-queue.mts +0 -162
  149. package/src/aws/infra/stack/lambda-configs.mts +0 -135
  150. package/src/aws/infra/stack/monitoredfunction.mts +0 -352
  151. package/src/aws/infra/stack/parameters.mts +0 -74
  152. package/src/aws/infra/stack/rest_apis.mts +0 -322
  153. package/src/aws/infra/stack/stack-checking-aspect.mts +0 -233
  154. package/src/aws/infra/stack/stack.mts +0 -144
  155. package/src/aws/infra/stack/subscription.mts +0 -58
  156. package/src/aws/infra/stacks/db-dns-stack.mts +0 -77
  157. package/src/aws/infra/stacks/db-proxy-stack.mts +0 -134
  158. package/src/aws/infra/stacks/db-stack.mts +0 -292
  159. package/src/aws/infra/stacks/intra-stack-configuration.mts +0 -6
  160. package/src/aws/infra/stacks/network-stack.mts +0 -76
  161. package/src/aws/infra/usage-plans.mts +0 -50
  162. package/src/aws/runtime/apikey.mts +0 -9
  163. package/src/aws/runtime/digitraffic-integration-response.mts +0 -35
  164. package/src/aws/runtime/dt-logger-default.mts +0 -11
  165. package/src/aws/runtime/dt-logger.mts +0 -184
  166. package/src/aws/runtime/environment.mts +0 -22
  167. package/src/aws/runtime/messaging.mts +0 -26
  168. package/src/aws/runtime/s3.mts +0 -44
  169. package/src/aws/runtime/secrets/dbsecret.mts +0 -31
  170. package/src/aws/runtime/secrets/node-ttl.d.mts +0 -12
  171. package/src/aws/runtime/secrets/proxy-holder.mts +0 -34
  172. package/src/aws/runtime/secrets/rds-holder.mts +0 -34
  173. package/src/aws/runtime/secrets/secret-holder.mts +0 -106
  174. package/src/aws/runtime/secrets/secret.mts +0 -58
  175. package/src/aws/types/errors.mts +0 -14
  176. package/src/aws/types/lambda-response.mts +0 -100
  177. package/src/aws/types/mediatypes.mts +0 -12
  178. package/src/aws/types/model-with-reference.mts +0 -8
  179. package/src/aws/types/proxytypes.mts +0 -27
  180. package/src/aws/types/tags.mts +0 -3
  181. package/src/database/cached.mts +0 -64
  182. package/src/database/database.mts +0 -107
  183. package/src/database/last-updated.mts +0 -103
  184. package/src/database/models.mts +0 -7
  185. package/src/index.mts +0 -2
  186. package/src/marine/id_utils.mts +0 -30
  187. package/src/marine/rtz.mts +0 -57
  188. package/src/test/asserter.mts +0 -58
  189. package/src/test/db-testutils.mts +0 -52
  190. package/src/test/httpserver.mts +0 -111
  191. package/src/test/secrets-manager.mts +0 -37
  192. package/src/test/testutils.mts +0 -39
  193. package/src/types/async-timeout-error.mts +0 -5
  194. package/src/types/aws-env.mts +0 -3
  195. package/src/types/either.mts +0 -9
  196. package/src/types/http-error.mts +0 -8
  197. package/src/types/input-error.mts +0 -2
  198. package/src/types/language.mts +0 -3
  199. package/src/types/nullable.mts +0 -21
  200. package/src/types/traffictype.mts +0 -8
  201. package/src/types/urn.mts +0 -1
  202. package/src/types/util-types.mts +0 -10
  203. package/src/types/validator.mts +0 -10
  204. package/src/utils/api-model.mts +0 -133
  205. package/src/utils/base64.mts +0 -16
  206. package/src/utils/date-utils.mts +0 -53
  207. package/src/utils/geojson-types.mts +0 -22
  208. package/src/utils/geometry.mts +0 -171
  209. package/src/utils/logging.mts +0 -75
  210. package/src/utils/retry.mts +0 -200
  211. package/src/utils/slack.mts +0 -26
  212. 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,86 @@
1
+ import { mockSecret, stubSecretsManager } from "../../test/secrets-manager.mjs";
2
+ const SECRET_WITH_PREFIX = {
3
+ "prefix.value": "value",
4
+ "prefix.name": "name",
5
+ "wrong.value": "value",
6
+ username: "DB_USER",
7
+ };
8
+ const SECRET_EMPTY = {};
9
+ const stubSM = stubSecretsManager();
10
+ const secretHolder = await import("../../aws/runtime/secrets/secret-holder.mjs");
11
+ const database = await import("../../database/database.mjs");
12
+ const { SecretHolder } = secretHolder;
13
+ const { DatabaseEnvironmentKeys } = database;
14
+ describe("SecretHolder - tests", () => {
15
+ beforeEach(() => {
16
+ process.env["SECRET_ID"] = "test-id";
17
+ });
18
+ afterEach(() => {
19
+ // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
20
+ delete process.env[DatabaseEnvironmentKeys.DB_USER];
21
+ });
22
+ test("get - no secret", () => {
23
+ mockSecret(null);
24
+ const holder = SecretHolder.create();
25
+ const secret = holder.get();
26
+ return expect(secret).rejects.toThrow("No secret found!");
27
+ }, 10000);
28
+ test("get - empty secret", () => {
29
+ mockSecret(SECRET_EMPTY);
30
+ const holder = SecretHolder.create();
31
+ const secret = holder.get();
32
+ return expect(secret).resolves.toEqual(SECRET_EMPTY);
33
+ });
34
+ test("get - no prefix", () => {
35
+ mockSecret(SECRET_WITH_PREFIX);
36
+ const holder = SecretHolder.create();
37
+ const secret = holder.get();
38
+ return expect(secret).resolves.toEqual(SECRET_WITH_PREFIX);
39
+ });
40
+ test("get - check keys - not found", () => {
41
+ mockSecret(SECRET_WITH_PREFIX);
42
+ const holder = SecretHolder.create("", ["not_found"]);
43
+ const secret = holder.get();
44
+ return expect(secret).rejects.toThrow();
45
+ });
46
+ test("get - check keys - found", () => {
47
+ mockSecret(SECRET_WITH_PREFIX);
48
+ const holder = SecretHolder.create("", ["prefix.value", "username"]);
49
+ return expect(holder.get()).resolves.toBeDefined();
50
+ });
51
+ test("getSecret - with prefix", () => {
52
+ mockSecret(SECRET_WITH_PREFIX);
53
+ const holder = SecretHolder.create("prefix");
54
+ const secret = holder.get();
55
+ return expect(secret).resolves.toEqual({
56
+ value: "value",
57
+ name: "name",
58
+ });
59
+ });
60
+ test("get - ttl - do not fetch", async () => {
61
+ mockSecret(SECRET_WITH_PREFIX);
62
+ const holder = SecretHolder.create();
63
+ const callCount = stubSM.getSecretValue.callCount;
64
+ await holder.get();
65
+ expect(stubSM.getSecretValue.callCount).toEqual(callCount + 1);
66
+ // gets cached secret
67
+ await holder.get();
68
+ expect(stubSM.getSecretValue.callCount).toEqual(callCount + 1);
69
+ });
70
+ test("get - ttl - fetch", async () => {
71
+ mockSecret(SECRET_WITH_PREFIX);
72
+ const holder = new SecretHolder("", "", [], {
73
+ ttl: 1,
74
+ });
75
+ const callCount = stubSM.getSecretValue.callCount;
76
+ await holder.get();
77
+ expect(stubSM.getSecretValue.callCount).toEqual(callCount + 1);
78
+ // cache expires, fetches secret again
79
+ const start = Date.now();
80
+ while (Date.now() < start + 2000)
81
+ ;
82
+ await holder.get();
83
+ expect(stubSM.getSecretValue.callCount).toEqual(callCount + 2);
84
+ });
85
+ });
86
+ //# sourceMappingURL=secret-holder.test.mjs.map
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,38 @@
1
+ import { mockSecret, stubSecretsManager } from "../../test/secrets-manager.mjs";
2
+ const SECRET_ID = "test_secret";
3
+ const SECRET_WITH_PREFIX = {
4
+ "prefix.value": "value",
5
+ "prefix.name": "name",
6
+ "wrong.value": "value",
7
+ };
8
+ const SECRET_EMPTY = {};
9
+ stubSecretsManager();
10
+ const secret = await import("../../aws/runtime/secrets/secret.mjs");
11
+ const { getSecret } = secret;
12
+ describe("secret - test", () => {
13
+ test("getSecret - no secret", async () => {
14
+ mockSecret(null);
15
+ await expect(async () => {
16
+ await getSecret(SECRET_ID, "");
17
+ }).rejects.toThrow("No secret found!");
18
+ });
19
+ test("getSecret - empty secret", async () => {
20
+ mockSecret(SECRET_EMPTY);
21
+ const secret = await getSecret(SECRET_ID, "");
22
+ expect(secret).toEqual(SECRET_EMPTY);
23
+ });
24
+ test("getSecret - no prefix", async () => {
25
+ mockSecret(SECRET_WITH_PREFIX);
26
+ const secret = await getSecret(SECRET_ID, "");
27
+ expect(secret).toEqual(SECRET_WITH_PREFIX);
28
+ });
29
+ test("getSecret - with prefix", async () => {
30
+ mockSecret(SECRET_WITH_PREFIX);
31
+ const secret = await getSecret(SECRET_ID, "prefix");
32
+ expect(secret).toEqual({
33
+ value: "value",
34
+ name: "name",
35
+ });
36
+ });
37
+ });
38
+ //# 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,46 @@
1
+ import { mockKyResponse } from "../../test/mock-ky.mjs";
2
+ import { describe, test, jest } from "@jest/globals";
3
+ const ky = (await import("ky")).default;
4
+ describe("mockKyResponse", () => {
5
+ const testObj = { test: "data" };
6
+ const testJson = JSON.stringify(testObj);
7
+ const url = "https://example.com";
8
+ afterEach(() => {
9
+ jest.restoreAllMocks();
10
+ });
11
+ test("works with all methods", async () => {
12
+ jest.spyOn(ky, "get").mockImplementation(() => mockKyResponse(200, testJson));
13
+ jest.spyOn(ky, "post").mockImplementation(() => mockKyResponse(200, testJson));
14
+ jest.spyOn(ky, "put").mockImplementation(() => mockKyResponse(200, testJson));
15
+ jest.spyOn(ky, "delete").mockImplementation(() => mockKyResponse(200, testJson));
16
+ expect(await ky.get(url).text()).toEqual(testJson);
17
+ expect(await ky.put(url).text()).toEqual(testJson);
18
+ expect(await ky.post(url).text()).toEqual(testJson);
19
+ expect(await ky.delete(url).text()).toEqual(testJson);
20
+ });
21
+ test("returns correct status", async () => {
22
+ jest.spyOn(ky, "get").mockImplementation(() => mockKyResponse(200, testJson));
23
+ expect((await ky.get(url)).status).toEqual(200);
24
+ jest.spyOn(ky, "get").mockImplementation(() => mockKyResponse(400, testJson));
25
+ expect((await ky.get(url)).status).toEqual(400);
26
+ });
27
+ test("returns correct ok", async () => {
28
+ jest.spyOn(ky, "get").mockImplementation(() => mockKyResponse(200, testJson));
29
+ expect((await ky.get(url)).ok).toEqual(true);
30
+ jest.spyOn(ky, "get").mockImplementation(() => mockKyResponse(299, testJson));
31
+ expect((await ky.get(url)).ok).toEqual(true);
32
+ jest.spyOn(ky, "get").mockImplementation(() => mockKyResponse(300, testJson));
33
+ expect((await ky.get(url)).ok).toEqual(false);
34
+ });
35
+ test("convenience methods work: text", async () => {
36
+ jest.spyOn(ky, "get").mockImplementation(() => mockKyResponse(200, testJson));
37
+ expect(await ky.get(url).text()).toEqual(testJson);
38
+ expect(await (await ky.get(url)).text()).toEqual(testJson);
39
+ });
40
+ test("convenience methods work: json", async () => {
41
+ jest.spyOn(ky, "get").mockImplementation(() => mockKyResponse(200, testJson));
42
+ expect(await ky.get(url).json()).toEqual(testObj);
43
+ expect(await (await ky.get(url)).json()).toEqual(testObj);
44
+ });
45
+ });
46
+ //# sourceMappingURL=mock-ky.test.mjs.map
@@ -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 { Writable } from "stream";
2
+ import { DtLogger } from "../../aws/runtime/dt-logger.mjs";
3
+ import { logException } from "../../utils/logging.mjs";
4
+ const TEST_METHODNAME = "test.logException";
5
+ describe("dt-logger", () => {
6
+ function assertLogError(error, expected, includeStack = false) {
7
+ assertWrite((logger) => {
8
+ logException(logger, error, includeStack);
9
+ }, expected);
10
+ }
11
+ function assertAxiosError(error, expected) {
12
+ assertWrite((logger) => {
13
+ logException(logger, error);
14
+ }, expected);
15
+ }
16
+ function assertWrite(writeFunction, expected) {
17
+ const logged = [];
18
+ const writeStream = new Writable({
19
+ write: (chunk) => {
20
+ logged.push(chunk.toString());
21
+ },
22
+ });
23
+ const logger = new DtLogger({
24
+ ...{ writeStream: writeStream },
25
+ });
26
+ writeFunction(logger);
27
+ expect(logged.length).toBe(1);
28
+ const loggedLine = JSON.parse(logged[0]);
29
+ console.info(loggedLine);
30
+ if (expected.stack) {
31
+ const stack = loggedLine.stack;
32
+ delete loggedLine.stack;
33
+ delete expected.stack;
34
+ expect(stack).toBeDefined();
35
+ }
36
+ expect(loggedLine).toEqual(expected);
37
+ }
38
+ test("log error - string", () => {
39
+ const STRING_ERROR = "string error";
40
+ assertLogError(STRING_ERROR, {
41
+ type: "Error",
42
+ method: TEST_METHODNAME,
43
+ message: STRING_ERROR,
44
+ level: "ERROR",
45
+ });
46
+ });
47
+ test("log error - error", () => {
48
+ const ERROR = new Error("Errormessage");
49
+ assertLogError(ERROR, {
50
+ type: "Error",
51
+ method: TEST_METHODNAME,
52
+ message: ERROR.message,
53
+ level: "ERROR",
54
+ });
55
+ });
56
+ test("log error - error with stack", () => {
57
+ const ERROR = new Error("Errormessage");
58
+ assertLogError(ERROR, {
59
+ type: "Error",
60
+ method: TEST_METHODNAME,
61
+ message: ERROR.message,
62
+ level: "ERROR",
63
+ stack: true,
64
+ }, true);
65
+ });
66
+ test("log error - AxiosError", () => {
67
+ const ERROR = new Error("ErrorFromAxios");
68
+ ERROR.code = "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 {};