@digitraffic/common 2026.3.17-1 → 2026.3.26-1-beta

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 (238) hide show
  1. package/README.md +18 -1
  2. package/dist/__test__/asserter.d.ts +13 -0
  3. package/dist/__test__/asserter.js +39 -0
  4. package/dist/__test__/db-testutils.d.ts +3 -0
  5. package/dist/__test__/db-testutils.js +38 -0
  6. package/dist/__test__/dependencies.test.d.ts +1 -0
  7. package/dist/__test__/dependencies.test.js +21 -0
  8. package/dist/__test__/imports.test.d.ts +1 -0
  9. package/dist/__test__/imports.test.js +318 -0
  10. package/dist/__test__/infra/acl-builder.test.d.ts +1 -0
  11. package/dist/__test__/infra/acl-builder.test.js +72 -0
  12. package/dist/__test__/infra/api/handler-factory.test.d.ts +1 -0
  13. package/dist/__test__/infra/api/handler-factory.test.js +42 -0
  14. package/dist/__test__/infra/api/integration.test.d.ts +1 -0
  15. package/dist/__test__/infra/api/integration.test.js +162 -0
  16. package/dist/__test__/infra/api/response.test.d.ts +1 -0
  17. package/dist/__test__/infra/api/response.test.js +77 -0
  18. package/dist/__test__/infra/api/static-integration.test.d.ts +1 -0
  19. package/dist/__test__/infra/api/static-integration.test.js +35 -0
  20. package/dist/__test__/infra/documentation.test.d.ts +1 -0
  21. package/dist/__test__/infra/documentation.test.js +38 -0
  22. package/dist/__test__/infra/scheduler.test.d.ts +1 -0
  23. package/dist/__test__/infra/scheduler.test.js +23 -0
  24. package/dist/__test__/infra/security-rule.test.d.ts +1 -0
  25. package/dist/__test__/infra/security-rule.test.js +21 -0
  26. package/dist/__test__/infra/stack/rest-apis.test.d.ts +1 -0
  27. package/dist/__test__/infra/stack/rest-apis.test.js +47 -0
  28. package/dist/__test__/marine/id_utils.test.d.ts +1 -0
  29. package/dist/__test__/marine/id_utils.test.js +45 -0
  30. package/dist/__test__/mock-ky.d.ts +2 -0
  31. package/dist/__test__/mock-ky.js +15 -0
  32. package/dist/__test__/promise/promise.test.d.ts +1 -0
  33. package/dist/__test__/promise/promise.test.js +126 -0
  34. package/dist/__test__/runtime/dt-logger.test.d.ts +1 -0
  35. package/dist/__test__/runtime/dt-logger.test.js +193 -0
  36. package/dist/__test__/secrets/secret-holder.test.d.ts +1 -0
  37. package/dist/__test__/secrets/secret-holder.test.js +96 -0
  38. package/dist/__test__/secrets/secret.test.d.ts +1 -0
  39. package/dist/__test__/secrets/secret.test.js +57 -0
  40. package/dist/__test__/stack/dt-function.test.d.ts +1 -0
  41. package/dist/__test__/stack/dt-function.test.js +340 -0
  42. package/dist/__test__/stack/rest-apis.test.d.ts +1 -0
  43. package/dist/__test__/stack/rest-apis.test.js +45 -0
  44. package/dist/__test__/test/mock-ky.test.d.ts +1 -0
  45. package/dist/__test__/test/mock-ky.test.js +46 -0
  46. package/dist/__test__/testutils.d.ts +12 -0
  47. package/dist/__test__/testutils.js +32 -0
  48. package/dist/__test__/types/lambda-proxy-types.test.d.ts +8 -0
  49. package/dist/__test__/types/lambda-proxy-types.test.js +155 -0
  50. package/dist/__test__/types/lambda-response-builder.test.d.ts +1 -0
  51. package/dist/__test__/types/lambda-response-builder.test.js +81 -0
  52. package/dist/__test__/types/lambda-response.test.d.ts +9 -0
  53. package/dist/__test__/types/lambda-response.test.js +73 -0
  54. package/dist/__test__/utils/base64.test.d.ts +1 -0
  55. package/dist/__test__/utils/base64.test.js +38 -0
  56. package/dist/__test__/utils/date-utils.test.d.ts +1 -0
  57. package/dist/__test__/utils/date-utils.test.js +32 -0
  58. package/dist/__test__/utils/geometry.test.d.ts +1 -0
  59. package/dist/__test__/utils/geometry.test.js +25 -0
  60. package/dist/__test__/utils/lambda-proxy-event.test.d.ts +1 -0
  61. package/dist/__test__/utils/lambda-proxy-event.test.js +45 -0
  62. package/dist/__test__/utils/logging.test.d.ts +1 -0
  63. package/dist/__test__/utils/logging.test.js +75 -0
  64. package/dist/__test__/utils/stop-watch.test.d.ts +1 -0
  65. package/dist/__test__/utils/stop-watch.test.js +118 -0
  66. package/dist/__test__/utils/utils.test.d.ts +1 -0
  67. package/dist/__test__/utils/utils.test.js +48 -0
  68. package/dist/aws/infra/acl-builder.d.ts +53 -0
  69. package/dist/aws/infra/acl-builder.js +407 -0
  70. package/dist/aws/infra/api/handler-factory.d.ts +22 -0
  71. package/dist/aws/infra/api/handler-factory.js +68 -0
  72. package/dist/aws/infra/api/integration.d.ts +49 -0
  73. package/dist/aws/infra/api/integration.js +162 -0
  74. package/dist/aws/infra/api/response.d.ts +62 -0
  75. package/dist/aws/infra/api/response.js +132 -0
  76. package/dist/aws/infra/api/responses.d.ts +60 -0
  77. package/dist/aws/infra/api/responses.js +90 -0
  78. package/dist/aws/infra/api/static-integration.d.ts +16 -0
  79. package/dist/aws/infra/api/static-integration.js +76 -0
  80. package/dist/aws/infra/bucket-policy.d.ts +38 -0
  81. package/dist/aws/infra/bucket-policy.js +30 -0
  82. package/dist/aws/infra/canaries/canary-alarm.d.ts +6 -0
  83. package/dist/aws/infra/canaries/canary-alarm.js +20 -0
  84. package/dist/aws/infra/canaries/canary-keys.d.ts +3 -0
  85. package/dist/aws/infra/canaries/canary-keys.js +4 -0
  86. package/dist/aws/infra/canaries/canary-parameters.d.ts +19 -0
  87. package/dist/aws/infra/canaries/canary-parameters.js +2 -0
  88. package/dist/aws/infra/canaries/canary-role.d.ts +14 -0
  89. package/dist/aws/infra/canaries/canary-role.js +51 -0
  90. package/dist/aws/infra/canaries/canary.d.ts +8 -0
  91. package/dist/aws/infra/canaries/canary.js +26 -0
  92. package/dist/aws/infra/canaries/database-canary.d.ts +17 -0
  93. package/dist/aws/infra/canaries/database-canary.js +65 -0
  94. package/dist/aws/infra/canaries/database-checker.d.ts +33 -0
  95. package/dist/aws/infra/canaries/database-checker.js +119 -0
  96. package/dist/aws/infra/canaries/url-canary.d.ts +16 -0
  97. package/dist/aws/infra/canaries/url-canary.js +55 -0
  98. package/dist/aws/infra/canaries/url-checker.d.ts +45 -0
  99. package/dist/aws/infra/canaries/url-checker.js +256 -0
  100. package/dist/aws/infra/documentation.d.ts +56 -0
  101. package/dist/aws/infra/documentation.js +90 -0
  102. package/dist/aws/infra/import-util.d.ts +17 -0
  103. package/dist/aws/infra/import-util.js +41 -0
  104. package/dist/aws/infra/scheduler.d.ts +12 -0
  105. package/dist/aws/infra/scheduler.js +27 -0
  106. package/dist/aws/infra/security-rule.d.ts +12 -0
  107. package/dist/aws/infra/security-rule.js +35 -0
  108. package/dist/aws/infra/sqs-integration.d.ts +4 -0
  109. package/dist/aws/infra/sqs-integration.js +85 -0
  110. package/dist/aws/infra/sqs-queue.d.ts +19 -0
  111. package/dist/aws/infra/sqs-queue.js +145 -0
  112. package/dist/aws/infra/stack/dt-function-alarms.d.ts +29 -0
  113. package/dist/aws/infra/stack/dt-function-alarms.js +54 -0
  114. package/dist/aws/infra/stack/dt-function.d.ts +124 -0
  115. package/dist/aws/infra/stack/dt-function.js +315 -0
  116. package/dist/aws/infra/stack/lambda-configs.d.ts +44 -0
  117. package/dist/aws/infra/stack/lambda-configs.js +71 -0
  118. package/dist/aws/infra/stack/lambda-log-group.d.ts +15 -0
  119. package/dist/aws/infra/stack/lambda-log-group.js +24 -0
  120. package/dist/aws/infra/stack/monitoredfunction.d.ts +85 -0
  121. package/dist/aws/infra/stack/monitoredfunction.js +147 -0
  122. package/dist/aws/infra/stack/parameters.d.ts +40 -0
  123. package/dist/aws/infra/stack/parameters.js +50 -0
  124. package/dist/aws/infra/stack/rest-api.d.ts +74 -0
  125. package/dist/aws/infra/stack/rest-api.js +235 -0
  126. package/dist/aws/infra/stack/stack-checking-aspect.d.ts +20 -0
  127. package/dist/aws/infra/stack/stack-checking-aspect.js +183 -0
  128. package/dist/aws/infra/stack/stack.d.ts +56 -0
  129. package/dist/aws/infra/stack/stack.js +71 -0
  130. package/dist/aws/infra/stack/subscription.d.ts +17 -0
  131. package/dist/aws/infra/stack/subscription.js +37 -0
  132. package/dist/aws/infra/stacks/db-dns-stack.d.ts +13 -0
  133. package/dist/aws/infra/stacks/db-dns-stack.js +60 -0
  134. package/dist/aws/infra/stacks/db-proxy-stack.d.ts +24 -0
  135. package/dist/aws/infra/stacks/db-proxy-stack.js +74 -0
  136. package/dist/aws/infra/stacks/db-stack.d.ts +65 -0
  137. package/dist/aws/infra/stacks/db-stack.js +189 -0
  138. package/dist/aws/infra/stacks/intra-stack-configuration.d.ts +5 -0
  139. package/dist/aws/infra/stacks/intra-stack-configuration.js +2 -0
  140. package/dist/aws/infra/stacks/network-stack.d.ts +14 -0
  141. package/dist/aws/infra/stacks/network-stack.js +45 -0
  142. package/dist/aws/infra/usage-plans.d.ts +16 -0
  143. package/dist/aws/infra/usage-plans.js +38 -0
  144. package/dist/aws/runtime/apikey.d.ts +2 -0
  145. package/dist/aws/runtime/apikey.js +13 -0
  146. package/dist/aws/runtime/digitraffic-integration-response.d.ts +8 -0
  147. package/dist/aws/runtime/digitraffic-integration-response.js +25 -0
  148. package/dist/aws/runtime/dt-logger-default.d.ts +9 -0
  149. package/dist/aws/runtime/dt-logger-default.js +6 -0
  150. package/dist/aws/runtime/dt-logger.d.ts +117 -0
  151. package/dist/aws/runtime/dt-logger.js +159 -0
  152. package/dist/aws/runtime/environment.d.ts +5 -0
  153. package/dist/aws/runtime/environment.js +7 -0
  154. package/dist/aws/runtime/s3.d.ts +3 -0
  155. package/dist/aws/runtime/s3.js +21 -0
  156. package/dist/aws/runtime/secrets/dbsecret.d.ts +16 -0
  157. package/dist/aws/runtime/secrets/dbsecret.js +26 -0
  158. package/dist/aws/runtime/secrets/proxy-holder.d.ts +9 -0
  159. package/dist/aws/runtime/secrets/proxy-holder.js +25 -0
  160. package/dist/aws/runtime/secrets/rds-holder.d.ts +9 -0
  161. package/dist/aws/runtime/secrets/rds-holder.js +25 -0
  162. package/dist/aws/runtime/secrets/secret-holder.d.ts +30 -0
  163. package/dist/aws/runtime/secrets/secret-holder.js +81 -0
  164. package/dist/aws/runtime/secrets/secret.d.ts +8 -0
  165. package/dist/aws/runtime/secrets/secret.js +61 -0
  166. package/dist/aws/types/errors.d.ts +8 -0
  167. package/dist/aws/types/errors.js +13 -0
  168. package/dist/aws/types/lambda-proxy-types.d.ts +59 -0
  169. package/dist/aws/types/lambda-proxy-types.js +210 -0
  170. package/dist/aws/types/lambda-response.d.ts +89 -0
  171. package/dist/aws/types/lambda-response.js +204 -0
  172. package/dist/aws/types/mediatypes.d.ts +11 -0
  173. package/dist/aws/types/mediatypes.js +14 -0
  174. package/dist/aws/types/model-with-reference.d.ts +7 -0
  175. package/dist/aws/types/model-with-reference.js +2 -0
  176. package/dist/aws/types/tags.d.ts +2 -0
  177. package/dist/aws/types/tags.js +4 -0
  178. package/dist/database/database.d.ts +27 -0
  179. package/dist/database/database.js +95 -0
  180. package/dist/database/last-updated.d.ts +15 -0
  181. package/dist/database/last-updated.js +46 -0
  182. package/dist/database/models.d.ts +6 -0
  183. package/dist/database/models.js +2 -0
  184. package/dist/index.d.ts +2 -0
  185. package/dist/index.js +2 -0
  186. package/dist/marine/id_utils.d.ts +3 -0
  187. package/dist/marine/id_utils.js +36 -0
  188. package/dist/marine/rtz.d.ts +48 -0
  189. package/dist/marine/rtz.js +2 -0
  190. package/dist/types/async-timeout-error.d.ts +3 -0
  191. package/dist/types/async-timeout-error.js +6 -0
  192. package/dist/types/either.d.ts +9 -0
  193. package/dist/types/either.js +2 -0
  194. package/dist/types/geojson.d.ts +47 -0
  195. package/dist/types/geojson.js +51 -0
  196. package/dist/types/http-error.d.ts +4 -0
  197. package/dist/types/http-error.js +8 -0
  198. package/dist/types/input-error.d.ts +2 -0
  199. package/dist/types/input-error.js +3 -0
  200. package/dist/types/language.d.ts +5 -0
  201. package/dist/types/language.js +7 -0
  202. package/dist/types/nullable.d.ts +24 -0
  203. package/dist/types/nullable.js +2 -0
  204. package/dist/types/openapi-schema.d.ts +932 -0
  205. package/dist/types/openapi-schema.js +151 -0
  206. package/dist/types/traffictype.d.ts +11 -0
  207. package/dist/types/traffictype.js +13 -0
  208. package/dist/types/urn.d.ts +1 -0
  209. package/dist/types/urn.js +2 -0
  210. package/dist/types/util-types.d.ts +11 -0
  211. package/dist/types/util-types.js +2 -0
  212. package/dist/types/validator.d.ts +4 -0
  213. package/dist/types/validator.js +9 -0
  214. package/dist/utils/api-model.d.ts +51 -0
  215. package/dist/utils/api-model.js +118 -0
  216. package/dist/utils/base64.d.ts +34 -0
  217. package/dist/utils/base64.js +53 -0
  218. package/dist/utils/date-utils.d.ts +27 -0
  219. package/dist/utils/date-utils.js +45 -0
  220. package/dist/utils/geojson-types.d.ts +14 -0
  221. package/dist/utils/geojson-types.js +15 -0
  222. package/dist/utils/geometry.d.ts +44 -0
  223. package/dist/utils/geometry.js +154 -0
  224. package/dist/utils/lambda-proxy-event.d.ts +9 -0
  225. package/dist/utils/lambda-proxy-event.js +31 -0
  226. package/dist/utils/logging.d.ts +40 -0
  227. package/dist/utils/logging.js +88 -0
  228. package/dist/utils/retry.d.ts +33 -0
  229. package/dist/utils/retry.js +135 -0
  230. package/dist/utils/slack.d.ts +5 -0
  231. package/dist/utils/slack.js +24 -0
  232. package/dist/utils/stop-watch.d.ts +46 -0
  233. package/dist/utils/stop-watch.js +114 -0
  234. package/dist/utils/utils.d.ts +95 -0
  235. package/dist/utils/utils.js +178 -0
  236. package/dist/utils/zod-utils.d.ts +27 -0
  237. package/dist/utils/zod-utils.js +57 -0
  238. package/package.json +30 -28
@@ -0,0 +1,117 @@
1
+ import type { Writable } from "node:stream";
2
+ /** Logging level */
3
+ export type LOG_LEVEL = "DEBUG" | "INFO" | "WARN" | "ERROR";
4
+ export type LoggerMethodType = `${string}.${string}`;
5
+ /**
6
+ * Configuration object for configuring the Digitraffic logging utility
7
+ * @see {@link DtLogger}
8
+ */
9
+ export interface LoggerConfiguration {
10
+ /** Name of the lambda */
11
+ lambdaName?: string;
12
+ /** The file name where the logging occurs */
13
+ fileName?: string;
14
+ /** The lambda runtime environment */
15
+ runTime?: string;
16
+ /** Custom end point to write the logs to */
17
+ writeStream?: Writable;
18
+ }
19
+ /**
20
+ * CustomParams allows to add keys prefixed with `custom` keyword to be added to an
21
+ * object.
22
+ */
23
+ export interface CustomParams {
24
+ /** do not log your apikey! */
25
+ customApikey?: never;
26
+ /** do not log your apikey! */
27
+ customApiKey?: never;
28
+ [key: `custom${Capitalize<string>}Count`]: number;
29
+ [key: `custom${Capitalize<string>}`]: string | number | bigint | boolean | Date | null | undefined;
30
+ }
31
+ /**
32
+ * Digitraffic logging object.
33
+ *
34
+ * `method` property is the only required propetry. {@link CustomParams} can be added by
35
+ * prefixin the property with keyword `custom`. The prefix is removed before writing to
36
+ * logging end point.
37
+ *
38
+ * @see {@link CustomParams}
39
+ */
40
+ export interface LoggableType extends CustomParams {
41
+ /** Name of the method logging the message */
42
+ method: LoggerMethodType;
43
+ /** Message to log, optional */
44
+ message?: string;
45
+ /** Type of message, optional */
46
+ type?: string;
47
+ /** Stack trace, optional */
48
+ stack?: string | undefined;
49
+ /** Amount of time some operation took in milliseconds, optional */
50
+ tookMs?: number;
51
+ /** Pass error object, which will be stringified before logging */
52
+ error?: unknown;
53
+ }
54
+ /**
55
+ * Helper class for json-logging.
56
+ *
57
+ * Logged line will include:
58
+ * * log-level
59
+ * * lambdaName (taken from process environment)
60
+ * * runtime (taken from process environment)
61
+ * * the actual message (as json or as string)
62
+ */
63
+ export declare class DtLogger {
64
+ readonly lambdaName?: string;
65
+ readonly runtime?: string;
66
+ readonly writeStream: Writable;
67
+ /**
68
+ * Create a new Logger instance.
69
+ * @constructor
70
+ * @param {LoggerConfiguration?} [config] - Accepts configuration options @see {@link LoggerConfiguration}
71
+ */
72
+ constructor(config?: LoggerConfiguration);
73
+ /**
74
+ * Log given message with level DEBUG. This will not be forwarded to centralized logging system!.
75
+ *
76
+ * @param message anything
77
+ * @see {@link LoggableType}
78
+ * @see {@link DtLogger.log}
79
+ */
80
+ debug(message: unknown): void;
81
+ /**
82
+ * Log given message with level INFO
83
+ *
84
+ * @param message Json-object to log
85
+ * @see {@link LoggableType}
86
+ * @see {@link DtLogger.log}
87
+ */
88
+ info(message: LoggableType): void;
89
+ /**
90
+ * Log given message with level WARN
91
+ *
92
+ * @param message Json-object to log
93
+ * @see {@link LoggableType}
94
+ * @see {@link DtLogger.log}
95
+ */
96
+ warn(message: LoggableType): void;
97
+ /**
98
+ * Log given message with level INFO
99
+ *
100
+ * @param message Json-object to log
101
+ * @see {@link LoggableType}
102
+ * @see {@link DtLogger.log}
103
+ */
104
+ error(message: LoggableType): void;
105
+ /**
106
+ * Log message with given log level.
107
+ *
108
+ * Some metadata is also added to the message:
109
+ * * runtime - can be configured with constructor or inferred from environment
110
+ * * lambdaName - can be configured with constructor or inferred from environment
111
+ *
112
+ * @param message Json-object to log
113
+ * @see {@link LoggableType}
114
+ */
115
+ private log;
116
+ private appendMessageFieldsToMessage;
117
+ }
@@ -0,0 +1,159 @@
1
+ import { lowerFirst, mapKeys } from "es-toolkit";
2
+ import { getEnvVariableOrElse } from "../../utils/utils.js";
3
+ /**
4
+ * Helper class for json-logging.
5
+ *
6
+ * Logged line will include:
7
+ * * log-level
8
+ * * lambdaName (taken from process environment)
9
+ * * runtime (taken from process environment)
10
+ * * the actual message (as json or as string)
11
+ */
12
+ export class DtLogger {
13
+ lambdaName;
14
+ runtime;
15
+ writeStream;
16
+ /**
17
+ * Create a new Logger instance.
18
+ * @constructor
19
+ * @param {LoggerConfiguration?} [config] - Accepts configuration options @see {@link LoggerConfiguration}
20
+ */
21
+ constructor(config) {
22
+ this.lambdaName =
23
+ config?.lambdaName ??
24
+ getEnvVariableOrElse("AWS_LAMBDA_FUNCTION_NAME", "unknown lambda name");
25
+ this.runtime =
26
+ config?.runTime ??
27
+ getEnvVariableOrElse("AWS_EXECUTION_ENV", "unknown runtime");
28
+ this.writeStream = config?.writeStream ?? process.stdout;
29
+ }
30
+ /**
31
+ * Log given message with level DEBUG. This will not be forwarded to centralized logging system!.
32
+ *
33
+ * @param message anything
34
+ * @see {@link LoggableType}
35
+ * @see {@link DtLogger.log}
36
+ */
37
+ debug(message) {
38
+ const logMessage = {
39
+ message,
40
+ level: "DEBUG",
41
+ lambdaName: this.lambdaName,
42
+ runtime: this.runtime,
43
+ };
44
+ this.writeStream.write(`${JSON.stringify(logMessage)}\n`);
45
+ }
46
+ /**
47
+ * Log given message with level INFO
48
+ *
49
+ * @param message Json-object to log
50
+ * @see {@link LoggableType}
51
+ * @see {@link DtLogger.log}
52
+ */
53
+ info(message) {
54
+ this.log({ ...message, level: "INFO" });
55
+ }
56
+ /**
57
+ * Log given message with level WARN
58
+ *
59
+ * @param message Json-object to log
60
+ * @see {@link LoggableType}
61
+ * @see {@link DtLogger.log}
62
+ */
63
+ warn(message) {
64
+ this.log({ ...message, level: "WARN" });
65
+ }
66
+ /**
67
+ * Log given message with level INFO
68
+ *
69
+ * @param message Json-object to log
70
+ * @see {@link LoggableType}
71
+ * @see {@link DtLogger.log}
72
+ */
73
+ error(message) {
74
+ this.log({
75
+ ...message,
76
+ level: "ERROR",
77
+ });
78
+ }
79
+ /**
80
+ * Log message with given log level.
81
+ *
82
+ * Some metadata is also added to the message:
83
+ * * runtime - can be configured with constructor or inferred from environment
84
+ * * lambdaName - can be configured with constructor or inferred from environment
85
+ *
86
+ * @param message Json-object to log
87
+ * @see {@link LoggableType}
88
+ */
89
+ log(message) {
90
+ // Append always method to message
91
+ if (!message.message ||
92
+ !message.message.length ||
93
+ !message.message.includes(message.method)) {
94
+ message.message = `${message.method} ${message.message ?? ""}`;
95
+ }
96
+ const error = message.error
97
+ ? message.error instanceof Error
98
+ ? `${message.error.name}: ${message.error.message}`
99
+ : typeof message.error === "string"
100
+ ? message.error
101
+ : JSON.stringify(message.error)
102
+ : undefined;
103
+ const stack = message.stack
104
+ ? message.stack
105
+ : message.error
106
+ ? message.error instanceof Error
107
+ ? message.error.stack
108
+ : undefined
109
+ : undefined;
110
+ const messageFields = removePrefix("custom", message);
111
+ messageFields.message = this.appendMessageFieldsToMessage(messageFields);
112
+ const logMessage = {
113
+ ...messageFields,
114
+ error,
115
+ stack,
116
+ lambdaName: this.lambdaName,
117
+ runtime: this.runtime,
118
+ };
119
+ this.writeStream.write(`${JSON.stringify(logMessage)}\n`);
120
+ }
121
+ appendMessageFieldsToMessage(message) {
122
+ // The order is not guaranteed to be alphabetical etc.
123
+ const fielValuePairs = Object.entries(message)
124
+ // Remove fields not logged in message field
125
+ .filter(([key]) => {
126
+ return (!["message", "level", "method", "stack", "error"].includes(key) &&
127
+ !(message.message ?? "").includes(`${key}=`));
128
+ })
129
+ // Map value to string
130
+ .map(([key, value]) => `${key}=${valueToString(value)}`)
131
+ .join(" ");
132
+ return `${message.message ?? ""}${fielValuePairs ? ` ${fielValuePairs}` : ""}`;
133
+ }
134
+ }
135
+ /**
136
+ * Removes given prefixes from the keys of the object.
137
+ */
138
+ function removePrefix(prefix, loggable) {
139
+ return mapKeys(loggable, (_index, key) => key.startsWith(prefix) ? lowerFirst(key.replace(prefix, "")) : key);
140
+ }
141
+ function valueToString(value) {
142
+ if (value === undefined) {
143
+ return "undefined";
144
+ }
145
+ else if (value === null) {
146
+ return "null";
147
+ }
148
+ else if (value instanceof Date) {
149
+ return value.toISOString();
150
+ }
151
+ else if (typeof value !== "string") {
152
+ return JSON.stringify(value);
153
+ }
154
+ else if (value.includes("=")) {
155
+ return JSON.stringify(value);
156
+ }
157
+ return value;
158
+ }
159
+ //# sourceMappingURL=dt-logger.js.map
@@ -0,0 +1,5 @@
1
+ export declare enum EnvKeys {
2
+ AWS_REGION = "AWS_REGION",
3
+ SECRET_ID = "SECRET_ID",
4
+ SECRET_OVERRIDE_AWS_REGION = "SECRET_OVERRIDE_AWS_REGION"
5
+ }
@@ -0,0 +1,7 @@
1
+ export var EnvKeys;
2
+ (function (EnvKeys) {
3
+ EnvKeys["AWS_REGION"] = "AWS_REGION";
4
+ EnvKeys["SECRET_ID"] = "SECRET_ID";
5
+ EnvKeys["SECRET_OVERRIDE_AWS_REGION"] = "SECRET_OVERRIDE_AWS_REGION";
6
+ })(EnvKeys || (EnvKeys = {}));
7
+ //# sourceMappingURL=environment.js.map
@@ -0,0 +1,3 @@
1
+ import type { ObjectCannedACL, S3Client } from "@aws-sdk/client-s3";
2
+ import type { NodeJsRuntimeStreamingBlobPayloadInputTypes } from "@smithy/types";
3
+ export declare function uploadToS3(s3: S3Client, bucketName: string, body: NodeJsRuntimeStreamingBlobPayloadInputTypes, objectName: string, cannedAcl?: ObjectCannedACL, contentType?: string): Promise<void>;
@@ -0,0 +1,21 @@
1
+ import { PutObjectCommand } from "@aws-sdk/client-s3";
2
+ import { logger } from "./dt-logger-default.js";
3
+ export async function uploadToS3(s3, bucketName, body, objectName, cannedAcl, contentType) {
4
+ const command = new PutObjectCommand({
5
+ Bucket: bucketName,
6
+ Key: objectName,
7
+ Body: body,
8
+ ACL: cannedAcl,
9
+ ContentType: contentType,
10
+ });
11
+ try {
12
+ await s3.send(command);
13
+ }
14
+ catch (_error) {
15
+ logger.error({
16
+ method: "s3.uploadToS3",
17
+ message: `upload failed to bucket ${bucketName}`,
18
+ });
19
+ }
20
+ }
21
+ //# sourceMappingURL=s3.js.map
@@ -0,0 +1,16 @@
1
+ import type { GenericSecret } from "./secret.js";
2
+ export declare enum RdsProxySecretKey {
3
+ username = "username",
4
+ password = "password",
5
+ proxy_host = "proxy_host",
6
+ proxy_ro_host = "proxy_ro_host"
7
+ }
8
+ export declare enum RdsSecretKey {
9
+ username = "username",
10
+ password = "password",
11
+ host = "host",
12
+ ro_host = "ro_host"
13
+ }
14
+ export type RdsProxySecret = Record<RdsProxySecretKey, string>;
15
+ export type RdsSecret = Record<RdsSecretKey, string>;
16
+ export declare function checkExpectedSecretKeys<Secret extends GenericSecret>(keys: string[], secret: Secret): void;
@@ -0,0 +1,26 @@
1
+ import { logger } from "../dt-logger-default.js";
2
+ export var RdsProxySecretKey;
3
+ (function (RdsProxySecretKey) {
4
+ RdsProxySecretKey["username"] = "username";
5
+ RdsProxySecretKey["password"] = "password";
6
+ RdsProxySecretKey["proxy_host"] = "proxy_host";
7
+ RdsProxySecretKey["proxy_ro_host"] = "proxy_ro_host";
8
+ })(RdsProxySecretKey || (RdsProxySecretKey = {}));
9
+ export var RdsSecretKey;
10
+ (function (RdsSecretKey) {
11
+ RdsSecretKey["username"] = "username";
12
+ RdsSecretKey["password"] = "password";
13
+ RdsSecretKey["host"] = "host";
14
+ RdsSecretKey["ro_host"] = "ro_host";
15
+ })(RdsSecretKey || (RdsSecretKey = {}));
16
+ export function checkExpectedSecretKeys(keys, secret) {
17
+ const missingKeys = keys.filter((key) => !(key in secret));
18
+ if (missingKeys.length) {
19
+ logger.error({
20
+ method: "dbsecret.checkExpectedSecretKeys",
21
+ message: `secret didn't contain the key(s) ${missingKeys.toString()}`,
22
+ });
23
+ throw new Error("Expected keys were not found");
24
+ }
25
+ }
26
+ //# sourceMappingURL=dbsecret.js.map
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Holds credentials for RDS Proxy access.
3
+ */
4
+ export declare class ProxyHolder {
5
+ private readonly secretHolder;
6
+ constructor(secretId: string);
7
+ static create(): ProxyHolder;
8
+ setCredentials(): Promise<void>;
9
+ }
@@ -0,0 +1,25 @@
1
+ import { DatabaseEnvironmentKeys } from "../../../database/database.js";
2
+ import { getEnvVariable, setEnvVariable } from "../../../utils/utils.js";
3
+ import { RdsProxySecretKey } from "./dbsecret.js";
4
+ import { SecretHolder } from "./secret-holder.js";
5
+ const RDS_PROXY_SECRET_KEYS = Object.values(RdsProxySecretKey);
6
+ /**
7
+ * Holds credentials for RDS Proxy access.
8
+ */
9
+ export class ProxyHolder {
10
+ secretHolder;
11
+ constructor(secretId) {
12
+ this.secretHolder = new SecretHolder(secretId, "", RDS_PROXY_SECRET_KEYS);
13
+ }
14
+ static create() {
15
+ return new ProxyHolder(getEnvVariable("SECRET_ID"));
16
+ }
17
+ async setCredentials() {
18
+ const secret = await this.secretHolder.get();
19
+ setEnvVariable(DatabaseEnvironmentKeys.DB_USER, secret.username);
20
+ setEnvVariable(DatabaseEnvironmentKeys.DB_PASS, secret.password);
21
+ setEnvVariable(DatabaseEnvironmentKeys.DB_URI, secret.proxy_host);
22
+ setEnvVariable(DatabaseEnvironmentKeys.DB_RO_URI, secret.proxy_ro_host);
23
+ }
24
+ }
25
+ //# sourceMappingURL=proxy-holder.js.map
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Holds credentials for RDS access.
3
+ */
4
+ export declare class RdsHolder {
5
+ private readonly secretHolder;
6
+ constructor(secretId: string);
7
+ static create(): RdsHolder;
8
+ setCredentials(): Promise<void>;
9
+ }
@@ -0,0 +1,25 @@
1
+ import { DatabaseEnvironmentKeys } from "../../../database/database.js";
2
+ import { getEnvVariable, setEnvVariable } from "../../../utils/utils.js";
3
+ import { RdsSecretKey } from "./dbsecret.js";
4
+ import { SecretHolder } from "./secret-holder.js";
5
+ const RDS_SECRET_KEYS = Object.values(RdsSecretKey);
6
+ /**
7
+ * Holds credentials for RDS access.
8
+ */
9
+ export class RdsHolder {
10
+ secretHolder;
11
+ constructor(secretId) {
12
+ this.secretHolder = new SecretHolder(secretId, "", RDS_SECRET_KEYS);
13
+ }
14
+ static create() {
15
+ return new RdsHolder(getEnvVariable("SECRET_ID"));
16
+ }
17
+ async setCredentials() {
18
+ const secret = await this.secretHolder.get();
19
+ setEnvVariable(DatabaseEnvironmentKeys.DB_USER, secret.username);
20
+ setEnvVariable(DatabaseEnvironmentKeys.DB_PASS, secret.password);
21
+ setEnvVariable(DatabaseEnvironmentKeys.DB_URI, secret.host);
22
+ setEnvVariable(DatabaseEnvironmentKeys.DB_RO_URI, secret.ro_host);
23
+ }
24
+ }
25
+ //# sourceMappingURL=rds-holder.js.map
@@ -0,0 +1,30 @@
1
+ import type { GenericSecret } from "./secret.js";
2
+ declare const DEFAULT_CONFIGURATION: {
3
+ readonly ttl: number;
4
+ };
5
+ /**
6
+ * Utility class for getting secrets from Secret Manager.
7
+ * Supports prefix for secrets, checking of expected keys and ttl-configuration.
8
+ *
9
+ * By default, secrets are cached for 5 minutes and then reread from the Secrets Manager(This can be overridden with configuration).
10
+ *
11
+ * Supports setting the database environment paramaters from the secret too.
12
+ *
13
+ * If you want secret manager to get values from different region than the lambda runtime is running, you can override this by
14
+ * setting the region with utils setSecretOverideAwsRegionEnv method.
15
+ */
16
+ export declare class SecretHolder<Secret extends GenericSecret> {
17
+ private readonly secretId;
18
+ private readonly prefix;
19
+ private readonly expectedKeys;
20
+ private cachedSecret?;
21
+ private expirationTime;
22
+ private readonly ttl;
23
+ constructor(secretId: string, prefix?: string, expectedKeys?: string[], configuration?: typeof DEFAULT_CONFIGURATION);
24
+ private initSecret;
25
+ static create<S extends GenericSecret>(prefix?: string, expectedKeys?: string[]): SecretHolder<S>;
26
+ get(): Promise<Secret>;
27
+ private parseSecret;
28
+ private getSecret;
29
+ }
30
+ export {};
@@ -0,0 +1,81 @@
1
+ import { getEnvVariable } from "../../../utils/utils.js";
2
+ import { logger } from "../dt-logger-default.js";
3
+ import { checkExpectedSecretKeys } from "./dbsecret.js";
4
+ import { getSecret } from "./secret.js";
5
+ const DEFAULT_PREFIX = "";
6
+ const DEFAULT_CONFIGURATION = {
7
+ ttl: 5 * 60, // timeout secrets in 5 minutes
8
+ };
9
+ /**
10
+ * Utility class for getting secrets from Secret Manager.
11
+ * Supports prefix for secrets, checking of expected keys and ttl-configuration.
12
+ *
13
+ * By default, secrets are cached for 5 minutes and then reread from the Secrets Manager(This can be overridden with configuration).
14
+ *
15
+ * Supports setting the database environment paramaters from the secret too.
16
+ *
17
+ * If you want secret manager to get values from different region than the lambda runtime is running, you can override this by
18
+ * setting the region with utils setSecretOverideAwsRegionEnv method.
19
+ */
20
+ export class SecretHolder {
21
+ secretId;
22
+ prefix;
23
+ expectedKeys;
24
+ cachedSecret;
25
+ expirationTime;
26
+ ttl; // seconds
27
+ constructor(secretId, prefix = "", expectedKeys = [], configuration = DEFAULT_CONFIGURATION) {
28
+ this.secretId = secretId;
29
+ this.prefix = prefix;
30
+ this.expectedKeys = expectedKeys;
31
+ this.expirationTime = new Date(0);
32
+ this.ttl = configuration.ttl;
33
+ }
34
+ async initSecret() {
35
+ const secretValue = await getSecret(this.secretId);
36
+ logger.info({
37
+ method: "SecretHolder.initSecret",
38
+ message: `Refreshing secret ${this.secretId}`,
39
+ });
40
+ this.cachedSecret = secretValue;
41
+ this.expirationTime = new Date(Date.now() + this.ttl * 1000);
42
+ }
43
+ static create(prefix = DEFAULT_PREFIX, expectedKeys = []) {
44
+ return new SecretHolder(getEnvVariable("SECRET_ID"), prefix, expectedKeys);
45
+ }
46
+ async get() {
47
+ const secret = await this.getSecret();
48
+ const parsedSecret = this.prefix === DEFAULT_PREFIX
49
+ ? secret
50
+ : this.parseSecret(secret, `${this.prefix}.`);
51
+ if (this.expectedKeys.length > 0) {
52
+ checkExpectedSecretKeys(this.expectedKeys, parsedSecret);
53
+ }
54
+ return parsedSecret;
55
+ }
56
+ parseSecret(secret, prefix) {
57
+ const parsed = {};
58
+ const skip = prefix.length;
59
+ for (const key in secret) {
60
+ if (key.startsWith(prefix)) {
61
+ const withoutPrefix = key.substring(skip);
62
+ // skip undefined values
63
+ if (!secret[key]) {
64
+ continue;
65
+ }
66
+ parsed[withoutPrefix] = secret[key];
67
+ }
68
+ }
69
+ return parsed;
70
+ }
71
+ async getSecret() {
72
+ if (this.expirationTime.getTime() < Date.now()) {
73
+ await this.initSecret();
74
+ }
75
+ if (this.cachedSecret === undefined) {
76
+ throw new Error("SecretHolder in illegal state");
77
+ }
78
+ return this.cachedSecret;
79
+ }
80
+ }
81
+ //# sourceMappingURL=secret-holder.js.map
@@ -0,0 +1,8 @@
1
+ export type GenericSecret = Record<string, string>;
2
+ export declare function getSecret<Secret>(secretId: string, prefix?: string): Promise<Secret>;
3
+ /**
4
+ * Gets variable from environment or from an AWS Secrets Manager secret if not found in the environment.
5
+ * @param Environment key
6
+ * @param Secret id in Secrets Manager
7
+ */
8
+ export declare function getFromEnvOrSecret(key: string, secretId: string): Promise<string>;
@@ -0,0 +1,61 @@
1
+ import { SecretsManager } from "@aws-sdk/client-secrets-manager";
2
+ import { getEnvVariable, getEnvVariableOrElse, getEnvVariableSafe, } from "../../../utils/utils.js";
3
+ import { EnvKeys } from "../environment.js";
4
+ // SECRET_OVERRIDE_AWS_REGION might not have been set before import of
5
+ // secret, so we need to lazy initialize SecretsManager
6
+ let smClient;
7
+ function getSmClient() {
8
+ if (!smClient) {
9
+ smClient = new SecretsManager({
10
+ region: getEnvVariableOrElse(EnvKeys.SECRET_OVERRIDE_AWS_REGION, // this is override secret region
11
+ getEnvVariable(EnvKeys.AWS_REGION)),
12
+ });
13
+ }
14
+ return smClient;
15
+ }
16
+ export async function getSecret(secretId, prefix = "") {
17
+ const secretObj = await getSmClient().getSecretValue({
18
+ SecretId: secretId,
19
+ });
20
+ if (!secretObj.SecretString) {
21
+ throw new Error("No secret found!");
22
+ }
23
+ const secret = JSON.parse(secretObj.SecretString);
24
+ if (!prefix) {
25
+ return secret;
26
+ }
27
+ return parseSecret(secret, `${prefix}.`);
28
+ }
29
+ function parseSecret(secret, prefix) {
30
+ const parsed = {};
31
+ const skip = prefix.length;
32
+ for (const key in secret) {
33
+ if (key.startsWith(prefix)) {
34
+ const withoutPrefix = key.substring(skip);
35
+ // skip undefined values
36
+ if (!secret[key]) {
37
+ continue;
38
+ }
39
+ parsed[withoutPrefix] = secret[key];
40
+ }
41
+ }
42
+ return parsed;
43
+ }
44
+ /**
45
+ * Gets variable from environment or from an AWS Secrets Manager secret if not found in the environment.
46
+ * @param Environment key
47
+ * @param Secret id in Secrets Manager
48
+ */
49
+ export async function getFromEnvOrSecret(key, secretId) {
50
+ const envValue = getEnvVariableSafe(key);
51
+ if (envValue.result === "ok") {
52
+ return envValue.value;
53
+ }
54
+ const secret = await getSecret(secretId);
55
+ const secretValue = secret[key];
56
+ if (secretValue !== undefined) {
57
+ return secretValue;
58
+ }
59
+ throw new Error(`Cannot get value with key ${key} from env or secret`);
60
+ }
61
+ //# sourceMappingURL=secret.js.map
@@ -0,0 +1,8 @@
1
+ export declare const NOT_FOUND_MESSAGE = "NOT_FOUND";
2
+ export declare const ERROR_MESSAGE = "ERROR";
3
+ export declare const OK_MESSAGE = "OK";
4
+ export declare const BAD_REQUEST_MESSAGE = "BAD REQUEST";
5
+ export declare class ValidationError extends Error {
6
+ statusCode: number;
7
+ constructor(statusCode: number, body: string);
8
+ }
@@ -0,0 +1,13 @@
1
+ // DEPRECATED, remove these!
2
+ export const NOT_FOUND_MESSAGE = "NOT_FOUND";
3
+ export const ERROR_MESSAGE = "ERROR";
4
+ export const OK_MESSAGE = "OK";
5
+ export const BAD_REQUEST_MESSAGE = "BAD REQUEST";
6
+ export class ValidationError extends Error {
7
+ statusCode;
8
+ constructor(statusCode, body) {
9
+ super(body);
10
+ this.statusCode = statusCode;
11
+ }
12
+ }
13
+ //# sourceMappingURL=errors.js.map