@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.
- package/dist/__test__/api/handler-factory.test.d.mts +1 -0
- package/dist/__test__/api/handler-factory.test.mjs +43 -0
- package/dist/__test__/api/response.test.d.mts +1 -0
- package/dist/__test__/api/response.test.mjs +86 -0
- package/dist/__test__/imports.test.d.mts +1 -0
- package/dist/__test__/imports.test.mjs +332 -0
- package/dist/__test__/marine/id_utils.test.d.mts +1 -0
- package/dist/__test__/marine/id_utils.test.mjs +44 -0
- package/dist/__test__/promise/promise.test.d.mts +1 -0
- package/dist/__test__/promise/promise.test.mjs +130 -0
- package/dist/__test__/runtime/dt-logger.test.d.mts +1 -0
- package/dist/__test__/runtime/dt-logger.test.mjs +108 -0
- package/dist/__test__/secrets/secret-holder.test.d.mts +1 -0
- package/dist/__test__/secrets/secret-holder.test.mjs +86 -0
- package/dist/__test__/secrets/secret.test.d.mts +1 -0
- package/dist/__test__/secrets/secret.test.mjs +38 -0
- package/dist/__test__/test/httpserver.test.d.mts +1 -0
- package/dist/__test__/test/httpserver.test.mjs +154 -0
- package/dist/__test__/test/mock-ky.test.d.mts +1 -0
- package/dist/__test__/test/mock-ky.test.mjs +46 -0
- package/dist/__test__/types/lambda-response.test.d.mts +1 -0
- package/dist/__test__/types/lambda-response.test.mjs +58 -0
- package/dist/__test__/utils/date-utils.test.d.mts +1 -0
- package/dist/__test__/utils/date-utils.test.mjs +27 -0
- package/dist/__test__/utils/geometry.test.d.mts +1 -0
- package/dist/__test__/utils/geometry.test.mjs +24 -0
- package/dist/__test__/utils/logging.test.d.mts +1 -0
- package/dist/__test__/utils/logging.test.mjs +78 -0
- package/dist/__test__/utils/utils.test.d.mts +1 -0
- package/dist/__test__/utils/utils.test.mjs +43 -0
- package/dist/aws/infra/api/handler-factory.mjs +4 -0
- package/dist/aws/infra/api/integration.d.mts +2 -2
- package/dist/aws/infra/api/integration.mjs +4 -1
- package/dist/aws/infra/api/response.d.mts +1 -1
- package/dist/aws/infra/api/responses.d.mts +1 -1
- package/dist/aws/infra/api/responses.mjs +2 -0
- package/dist/aws/infra/api/static-integration.mjs +1 -1
- package/dist/aws/infra/canaries/canary-alarm.d.mts +1 -1
- package/dist/aws/infra/canaries/canary-alarm.mjs +2 -0
- package/dist/aws/infra/canaries/canary-parameters.mjs +1 -1
- package/dist/aws/infra/canaries/canary-role.mjs +1 -0
- package/dist/aws/infra/canaries/canary.d.mts +2 -2
- package/dist/aws/infra/canaries/canary.mjs +2 -0
- package/dist/aws/infra/canaries/database-canary.d.mts +2 -2
- package/dist/aws/infra/canaries/database-canary.mjs +2 -0
- package/dist/aws/infra/canaries/database-checker.d.mts +1 -1
- package/dist/aws/infra/canaries/database-checker.mjs +7 -1
- package/dist/aws/infra/canaries/url-canary.d.mts +2 -2
- package/dist/aws/infra/canaries/url-canary.mjs +3 -0
- package/dist/aws/infra/canaries/url-checker.d.mts +1 -1
- package/dist/aws/infra/canaries/url-checker.mjs +4 -1
- package/dist/aws/infra/documentation.mjs +5 -1
- package/dist/aws/infra/import-util.d.mts +1 -1
- package/dist/aws/infra/import-util.mjs +4 -3
- package/dist/aws/infra/scheduler.mjs +2 -0
- package/dist/aws/infra/security-rule.d.mts +1 -1
- package/dist/aws/infra/security-rule.mjs +1 -0
- package/dist/aws/infra/sqs-integration.d.mts +1 -1
- package/dist/aws/infra/sqs-integration.mjs +3 -1
- package/dist/aws/infra/sqs-queue.d.mts +1 -1
- package/dist/aws/infra/sqs-queue.mjs +2 -1
- package/dist/aws/infra/stack/lambda-configs.d.mts +4 -4
- package/dist/aws/infra/stack/lambda-configs.mjs +4 -2
- package/dist/aws/infra/stack/monitoredfunction.d.mts +3 -3
- package/dist/aws/infra/stack/monitoredfunction.mjs +23 -18
- package/dist/aws/infra/stack/parameters.mjs +1 -0
- package/dist/aws/infra/stack/rest_apis.d.mts +2 -2
- package/dist/aws/infra/stack/rest_apis.mjs +6 -1
- package/dist/aws/infra/stack/stack-checking-aspect.d.mts +2 -2
- package/dist/aws/infra/stack/stack-checking-aspect.mjs +6 -1
- package/dist/aws/infra/stack/stack.d.mts +5 -5
- package/dist/aws/infra/stack/stack.mjs +9 -0
- package/dist/aws/infra/stack/subscription.mjs +4 -0
- package/dist/aws/infra/stacks/db-dns-stack.d.mts +1 -1
- package/dist/aws/infra/stacks/db-dns-stack.mjs +1 -0
- package/dist/aws/infra/stacks/db-proxy-stack.d.mts +3 -3
- package/dist/aws/infra/stacks/db-proxy-stack.mjs +4 -2
- package/dist/aws/infra/stacks/db-stack.d.mts +3 -3
- package/dist/aws/infra/stacks/db-stack.mjs +11 -7
- package/dist/aws/infra/stacks/intra-stack-configuration.d.mts +1 -1
- package/dist/aws/infra/stacks/network-stack.d.mts +2 -2
- package/dist/aws/infra/stacks/network-stack.mjs +8 -0
- package/dist/aws/infra/usage-plans.d.mts +1 -1
- package/dist/aws/infra/usage-plans.mjs +1 -0
- package/dist/aws/runtime/apikey.d.mts +2 -2
- package/dist/aws/runtime/apikey.mjs +2 -2
- package/dist/aws/runtime/digitraffic-integration-response.d.mts +1 -1
- package/dist/aws/runtime/dt-logger.mjs +6 -2
- package/dist/aws/runtime/messaging.d.mts +2 -2
- package/dist/aws/runtime/messaging.mjs +5 -4
- package/dist/aws/runtime/s3.d.mts +4 -2
- package/dist/aws/runtime/s3.mjs +15 -10
- package/dist/aws/runtime/secrets/dbsecret.d.mts +1 -1
- package/dist/aws/runtime/secrets/proxy-holder.mjs +1 -0
- package/dist/aws/runtime/secrets/rds-holder.mjs +1 -0
- package/dist/aws/runtime/secrets/secret-holder.d.mts +1 -1
- package/dist/aws/runtime/secrets/secret-holder.mjs +6 -1
- package/dist/aws/runtime/secrets/secret.mjs +5 -6
- package/dist/aws/types/errors.mjs +1 -0
- package/dist/aws/types/lambda-response.mjs +5 -0
- package/dist/aws/types/model-with-reference.mjs +1 -1
- package/dist/database/cached.d.mts +1 -1
- package/dist/database/database.mjs +1 -0
- package/dist/database/last-updated.d.mts +1 -1
- package/dist/test/db-testutils.d.mts +1 -1
- package/dist/test/db-testutils.mjs +1 -1
- package/dist/test/httpserver.mjs +7 -3
- package/dist/test/mock-ky.d.mts +2 -0
- package/dist/test/mock-ky.mjs +15 -0
- package/dist/test/secrets-manager.d.mts +3 -2
- package/dist/test/secrets-manager.mjs +14 -16
- package/dist/test/testutils.mjs +1 -1
- package/dist/types/http-error.mjs +1 -0
- package/dist/types/nullable.d.mts +1 -1
- package/dist/utils/api-model.d.mts +2 -2
- package/dist/utils/api-model.mjs +1 -1
- package/dist/utils/geojson-types.d.mts +1 -1
- package/dist/utils/geojson-types.mjs +4 -2
- package/dist/utils/geometry.d.mts +1 -1
- package/dist/utils/geometry.mjs +3 -0
- package/dist/utils/logging.mjs +2 -2
- package/dist/utils/retry.d.mts +2 -2
- package/dist/utils/retry.mjs +2 -2
- package/dist/utils/slack.mjs +4 -3
- package/dist/utils/utils.d.mts +2 -2
- package/package.json +25 -15
- package/src/@types/geojson-validation/index.d.mts +0 -4
- package/src/aws/infra/api/handler-factory.mts +0 -86
- package/src/aws/infra/api/integration.mts +0 -147
- package/src/aws/infra/api/response.mts +0 -165
- package/src/aws/infra/api/responses.mts +0 -127
- package/src/aws/infra/api/static-integration.mts +0 -108
- package/src/aws/infra/canaries/Synthetics.d.mts +0 -21
- package/src/aws/infra/canaries/canary-alarm.mts +0 -33
- package/src/aws/infra/canaries/canary-keys.mts +0 -3
- package/src/aws/infra/canaries/canary-parameters.mts +0 -19
- package/src/aws/infra/canaries/canary-role.mts +0 -73
- package/src/aws/infra/canaries/canary.mts +0 -44
- package/src/aws/infra/canaries/database-canary.mts +0 -98
- package/src/aws/infra/canaries/database-checker.mts +0 -163
- package/src/aws/infra/canaries/url-canary.mts +0 -98
- package/src/aws/infra/canaries/url-checker.mts +0 -388
- package/src/aws/infra/documentation.mts +0 -142
- package/src/aws/infra/import-util.mts +0 -57
- package/src/aws/infra/scheduler.mts +0 -59
- package/src/aws/infra/security-rule.mts +0 -38
- package/src/aws/infra/sqs-integration.mts +0 -106
- package/src/aws/infra/sqs-queue.mts +0 -162
- package/src/aws/infra/stack/lambda-configs.mts +0 -135
- package/src/aws/infra/stack/monitoredfunction.mts +0 -352
- package/src/aws/infra/stack/parameters.mts +0 -74
- package/src/aws/infra/stack/rest_apis.mts +0 -322
- package/src/aws/infra/stack/stack-checking-aspect.mts +0 -233
- package/src/aws/infra/stack/stack.mts +0 -144
- package/src/aws/infra/stack/subscription.mts +0 -58
- package/src/aws/infra/stacks/db-dns-stack.mts +0 -77
- package/src/aws/infra/stacks/db-proxy-stack.mts +0 -134
- package/src/aws/infra/stacks/db-stack.mts +0 -292
- package/src/aws/infra/stacks/intra-stack-configuration.mts +0 -6
- package/src/aws/infra/stacks/network-stack.mts +0 -76
- package/src/aws/infra/usage-plans.mts +0 -50
- package/src/aws/runtime/apikey.mts +0 -9
- package/src/aws/runtime/digitraffic-integration-response.mts +0 -35
- package/src/aws/runtime/dt-logger-default.mts +0 -11
- package/src/aws/runtime/dt-logger.mts +0 -184
- package/src/aws/runtime/environment.mts +0 -22
- package/src/aws/runtime/messaging.mts +0 -26
- package/src/aws/runtime/s3.mts +0 -44
- package/src/aws/runtime/secrets/dbsecret.mts +0 -31
- package/src/aws/runtime/secrets/node-ttl.d.mts +0 -12
- package/src/aws/runtime/secrets/proxy-holder.mts +0 -34
- package/src/aws/runtime/secrets/rds-holder.mts +0 -34
- package/src/aws/runtime/secrets/secret-holder.mts +0 -106
- package/src/aws/runtime/secrets/secret.mts +0 -58
- package/src/aws/types/errors.mts +0 -14
- package/src/aws/types/lambda-response.mts +0 -100
- package/src/aws/types/mediatypes.mts +0 -12
- package/src/aws/types/model-with-reference.mts +0 -8
- package/src/aws/types/proxytypes.mts +0 -27
- package/src/aws/types/tags.mts +0 -3
- package/src/database/cached.mts +0 -64
- package/src/database/database.mts +0 -107
- package/src/database/last-updated.mts +0 -103
- package/src/database/models.mts +0 -7
- package/src/index.mts +0 -2
- package/src/marine/id_utils.mts +0 -30
- package/src/marine/rtz.mts +0 -57
- package/src/test/asserter.mts +0 -58
- package/src/test/db-testutils.mts +0 -52
- package/src/test/httpserver.mts +0 -111
- package/src/test/secrets-manager.mts +0 -37
- package/src/test/testutils.mts +0 -39
- package/src/types/async-timeout-error.mts +0 -5
- package/src/types/aws-env.mts +0 -3
- package/src/types/either.mts +0 -9
- package/src/types/http-error.mts +0 -8
- package/src/types/input-error.mts +0 -2
- package/src/types/language.mts +0 -3
- package/src/types/nullable.mts +0 -21
- package/src/types/traffictype.mts +0 -8
- package/src/types/urn.mts +0 -1
- package/src/types/util-types.mts +0 -10
- package/src/types/validator.mts +0 -10
- package/src/utils/api-model.mts +0 -133
- package/src/utils/base64.mts +0 -16
- package/src/utils/date-utils.mts +0 -53
- package/src/utils/geojson-types.mts +0 -22
- package/src/utils/geometry.mts +0 -171
- package/src/utils/logging.mts +0 -75
- package/src/utils/retry.mts +0 -200
- package/src/utils/slack.mts +0 -26
- package/src/utils/utils.mts +0 -184
@@ -1,12 +1,14 @@
|
|
1
1
|
export class GeoJsonPoint {
|
2
|
+
type = "Point";
|
3
|
+
coordinates;
|
2
4
|
constructor(coordinates) {
|
3
|
-
this.type = "Point";
|
4
5
|
this.coordinates = coordinates;
|
5
6
|
}
|
6
7
|
}
|
7
8
|
export class GeoJsonLineString {
|
9
|
+
type = "LineString";
|
10
|
+
coordinates;
|
8
11
|
constructor(coordinates) {
|
9
|
-
this.type = "LineString";
|
10
12
|
this.coordinates = coordinates;
|
11
13
|
}
|
12
14
|
}
|
@@ -1,7 +1,7 @@
|
|
1
1
|
/**
|
2
2
|
* GeoJSON functions and tools
|
3
3
|
*/
|
4
|
-
import { Feature, FeatureCollection, Geometry, Position } from "geojson";
|
4
|
+
import type { Feature, FeatureCollection, Geometry, Position } from "geojson";
|
5
5
|
export declare const SRID_WGS84 = 4326;
|
6
6
|
/**
|
7
7
|
* Creates WKT geometry from GeoJSON geometry
|
package/dist/utils/geometry.mjs
CHANGED
@@ -87,6 +87,9 @@ function distanceBetweenWGS84PointsInKm(fromXLon, fromYLat, toXLon, toYLat) {
|
|
87
87
|
* @param pos2
|
88
88
|
*/
|
89
89
|
export function distanceBetweenPositionsInKm(pos1, pos2) {
|
90
|
+
if (pos1.length !== 2 && pos2.length !== 2) {
|
91
|
+
throw Error(`Positions ${pos1.toString()} and ${pos2.toString()} both must be arrays of length two`);
|
92
|
+
}
|
90
93
|
return distanceBetweenWGS84PointsInKm(pos1[0], pos1[1], pos2[0], pos2[1]);
|
91
94
|
}
|
92
95
|
export function areDistinctPositions(previous, next) {
|
package/dist/utils/logging.mjs
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
import { AxiosError } from "axios";
|
2
1
|
import { DtLogger } from "../aws/runtime/dt-logger.mjs";
|
3
2
|
import { getEnvVariableOrElse } from "./utils.mjs";
|
4
3
|
const functionName = getEnvVariableOrElse("AWS_LAMBDA_FUNCTION_NAME", "test");
|
@@ -49,7 +48,8 @@ export function logException(logger, error, includeStack = false) {
|
|
49
48
|
? error
|
50
49
|
: JSON.stringify(error);
|
51
50
|
const stack = error instanceof Error && includeStack ? error.stack : undefined;
|
52
|
-
|
51
|
+
// In case error is AxiosError, log the custom code property.
|
52
|
+
const customCode = error["code"];
|
53
53
|
logger.error({
|
54
54
|
type: "Error",
|
55
55
|
method: `${functionName}.logException`,
|
package/dist/utils/retry.d.mts
CHANGED
@@ -9,7 +9,7 @@ export type RetryPredicate = (error: unknown) => boolean;
|
|
9
9
|
* Utility timeout functions for "retry" function.
|
10
10
|
*/
|
11
11
|
export declare const timeoutFunctions: {
|
12
|
-
noTimeout: (
|
12
|
+
noTimeout: (_: number) => number;
|
13
13
|
exponentialTimeout: (retryCount: number) => number;
|
14
14
|
};
|
15
15
|
/**
|
@@ -17,7 +17,7 @@ export declare const timeoutFunctions: {
|
|
17
17
|
*/
|
18
18
|
export declare const retryPredicates: {
|
19
19
|
retryBasedOnStatusCode: (error: unknown) => boolean;
|
20
|
-
alwaysRetry: (
|
20
|
+
alwaysRetry: (_: unknown) => boolean;
|
21
21
|
};
|
22
22
|
export declare let retryCount: number;
|
23
23
|
/**
|
package/dist/utils/retry.mjs
CHANGED
@@ -13,7 +13,7 @@ export var RetryLogError;
|
|
13
13
|
export const timeoutFunctions = (function () {
|
14
14
|
return {
|
15
15
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
16
|
-
noTimeout: (
|
16
|
+
noTimeout: (_) => {
|
17
17
|
return 0;
|
18
18
|
},
|
19
19
|
exponentialTimeout: (retryCount) => {
|
@@ -39,7 +39,7 @@ export const retryPredicates = (function () {
|
|
39
39
|
return false;
|
40
40
|
},
|
41
41
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
42
|
-
alwaysRetry: (
|
42
|
+
alwaysRetry: (_) => {
|
43
43
|
return true;
|
44
44
|
},
|
45
45
|
};
|
package/dist/utils/slack.mjs
CHANGED
@@ -1,7 +1,8 @@
|
|
1
|
-
import
|
1
|
+
import ky from "ky";
|
2
2
|
import { logger } from "../aws/runtime/dt-logger-default.mjs";
|
3
3
|
import { logException } from "./logging.mjs";
|
4
4
|
export class SlackApi {
|
5
|
+
url;
|
5
6
|
constructor(url) {
|
6
7
|
this.url = url;
|
7
8
|
}
|
@@ -11,8 +12,8 @@ export class SlackApi {
|
|
11
12
|
method: "SlackApi.notify",
|
12
13
|
message: "Sending slack notification",
|
13
14
|
});
|
14
|
-
await
|
15
|
-
text
|
15
|
+
await ky.post(this.url, {
|
16
|
+
body: text
|
16
17
|
});
|
17
18
|
}
|
18
19
|
catch (error) {
|
package/dist/utils/utils.d.mts
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
import { AwsEnv } from "../types/aws-env.mjs";
|
2
|
-
import { Either } from "../types/either.mjs";
|
1
|
+
import type { AwsEnv } from "../types/aws-env.mjs";
|
2
|
+
import type { Either } from "../types/either.mjs";
|
3
3
|
/**
|
4
4
|
* Check if arrays have only elements that also exists also in other array.
|
5
5
|
* Individual element count doesn't matter.
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@digitraffic/common",
|
3
|
-
"version": "2024.
|
3
|
+
"version": "2024.3.11-1",
|
4
4
|
"description": "",
|
5
5
|
"type": "module",
|
6
6
|
"repository": {
|
@@ -14,8 +14,7 @@
|
|
14
14
|
"private": false,
|
15
15
|
"files": [
|
16
16
|
"dist/**/*.mjs",
|
17
|
-
"dist/**/*.d.mts"
|
18
|
-
"src/**/*.mts"
|
17
|
+
"dist/**/*.d.mts"
|
19
18
|
],
|
20
19
|
"exports": {
|
21
20
|
".": "./dist/index.mjs",
|
@@ -39,6 +38,7 @@
|
|
39
38
|
"./dist/test/httpserver": "./dist/test/httpserver.mjs",
|
40
39
|
"./dist/test/secrets-manager": "./dist/test/secrets-manager.mjs",
|
41
40
|
"./dist/test/asserter": "./dist/test/asserter.mjs",
|
41
|
+
"./dist/test/mock-ky": "./dist/test/mock-ky.mjs",
|
42
42
|
"./dist/marine/rtz": "./dist/marine/rtz.mjs",
|
43
43
|
"./dist/marine/id_utils": "./dist/marine/id_utils.mjs",
|
44
44
|
"./dist/index": "./dist/index.mjs",
|
@@ -104,23 +104,37 @@
|
|
104
104
|
"./dist/aws/runtime/digitraffic-integration-response": "./dist/aws/runtime/digitraffic-integration-response.mjs"
|
105
105
|
},
|
106
106
|
"peerDependencies": {
|
107
|
+
"@aws-sdk/client-s3": "^3.496.0",
|
108
|
+
"@aws-sdk/lib-storage": "^3.496.0",
|
109
|
+
"@aws-sdk/client-secrets-manager": "^3.496.0",
|
110
|
+
"@aws-sdk/client-api-gateway": "^3.496.0",
|
111
|
+
"@aws-sdk/client-sns": "^3.496.0",
|
107
112
|
"@types/geojson": "^7946.0.12",
|
108
|
-
"aws-cdk-lib": "^2.
|
109
|
-
"aws-sdk": "^2.1481.0",
|
110
|
-
"axios": "^1.6.2",
|
113
|
+
"aws-cdk-lib": "^2.132.0",
|
111
114
|
"change-case": "5.0.0",
|
112
115
|
"constructs": "^10.3.0",
|
113
116
|
"date-fns": "~2.30.0",
|
114
117
|
"date-fns-tz": "~2.0.0",
|
115
118
|
"etag": "^1.8.1",
|
116
119
|
"geojson-validation": "^1.0.2",
|
120
|
+
"ky": "^1.2.0",
|
117
121
|
"lodash": "~4.17.21",
|
118
122
|
"node-ttl": "^0.2.0",
|
119
123
|
"pg-native": "^3.0.1",
|
120
124
|
"pg-promise": "^11.5.4"
|
121
125
|
},
|
122
126
|
"devDependencies": {
|
127
|
+
"@aws-sdk/client-s3": "3.496.0",
|
128
|
+
"@aws-sdk/lib-storage": "3.496.0",
|
129
|
+
"@aws-sdk/client-secrets-manager": "3.496.0",
|
130
|
+
"@aws-sdk/client-api-gateway": "3.496.0",
|
131
|
+
"@aws-sdk/client-sns": "3.496.0",
|
123
132
|
"@jest/globals": "^29.7.0",
|
133
|
+
"@rushstack/eslint-config": "^3.6.2",
|
134
|
+
"@rushstack/heft": "^0.64.3",
|
135
|
+
"@rushstack/heft-jest-plugin": "^0.11.3",
|
136
|
+
"@rushstack/heft-lint-plugin": "^0.3.3",
|
137
|
+
"@rushstack/heft-typescript-plugin": "^0.3.3",
|
124
138
|
"@types/aws-lambda": "8.10.131",
|
125
139
|
"@types/etag": "1.8.3",
|
126
140
|
"@types/geojson": "7946.0.13",
|
@@ -130,10 +144,8 @@
|
|
130
144
|
"@types/node": "20.10.7",
|
131
145
|
"@types/sinon": "17.0.2",
|
132
146
|
"@typescript-eslint/eslint-plugin": "~6.18.1",
|
133
|
-
"@typescript-eslint/parser": "^6.
|
134
|
-
"aws-cdk-lib": "~2.
|
135
|
-
"aws-sdk": "~2.1531.0",
|
136
|
-
"axios": "^1.6.5",
|
147
|
+
"@typescript-eslint/parser": "^6.20.0",
|
148
|
+
"aws-cdk-lib": "~2.132.0",
|
137
149
|
"change-case": "5.3.0",
|
138
150
|
"constructs": "10.3.0",
|
139
151
|
"date-fns": "~2.30.0",
|
@@ -145,6 +157,7 @@
|
|
145
157
|
"geojson-validation": "^1.0.2",
|
146
158
|
"jest": "^29.7.0",
|
147
159
|
"jest-junit": "^16.0.0",
|
160
|
+
"ky": "^1.2.0",
|
148
161
|
"lodash": "~4.17.21",
|
149
162
|
"node-ttl": "^0.2.0",
|
150
163
|
"pg-promise": "^11.5.4",
|
@@ -155,10 +168,6 @@
|
|
155
168
|
"typescript": "~5.3.3",
|
156
169
|
"velocityjs": "2.0.6"
|
157
170
|
},
|
158
|
-
"dependencies": {
|
159
|
-
"@aws-sdk/client-s3": "~3.472.0",
|
160
|
-
"@aws-sdk/lib-storage": "~3.472.0"
|
161
|
-
},
|
162
171
|
"scripts": {
|
163
172
|
"build": "tsc",
|
164
173
|
"build:watch": "tsc --watch",
|
@@ -166,7 +175,8 @@
|
|
166
175
|
"eslint-report": "eslint . --format html",
|
167
176
|
"ci:eslint-report": "eslint . --format html -o report.html || true",
|
168
177
|
"clean": "rimraf dist output",
|
169
|
-
"test": "
|
178
|
+
"test": "NODE_OPTIONS='--experimental-vm-modules' heft test --clean --max-workers=1",
|
179
|
+
"test:jest": "node --trace-warnings --experimental-vm-modules --max-old-space-size=1536 --expose-gc ./node_modules/jest/bin/jest.js --detectOpenHandles --forceExit --coverage --coverageDirectory=output/coverage/jest --logHeapUsage --runInBand --verbose",
|
170
180
|
"test:inspect": "node --inspect-brk --expose-gc ./node_modules/jest/bin/jest.js --detectOpenHandles --forceExit --coverage --coverageDirectory=output/coverage/jest --logHeapUsage --runInBand",
|
171
181
|
"test:watch": "jest --detectOpenHandles --forceExit --coverage --coverageDirectory=output/coverage/jest --watch"
|
172
182
|
}
|
@@ -1,86 +0,0 @@
|
|
1
|
-
import { getEnvVariableOrElse } from "../../../utils/utils.mjs";
|
2
|
-
import { DtLogger } from "../../runtime/dt-logger.mjs";
|
3
|
-
import { LambdaResponse } from "../../types/lambda-response.mjs";
|
4
|
-
|
5
|
-
export type LoggingHandler = (
|
6
|
-
method: () => Promise<LambdaResponse>,
|
7
|
-
logger: DtLogger
|
8
|
-
) => Promise<LambdaResponse>;
|
9
|
-
|
10
|
-
export type ErrorHandler = (error: unknown, logger: DtLogger) => LambdaResponse;
|
11
|
-
|
12
|
-
const functionName = getEnvVariableOrElse("AWS_LAMBDA_FUNCTION_NAME", "test");
|
13
|
-
|
14
|
-
/**
|
15
|
-
* Factory class for creating lambda-handler functions. You can set functionality to handle logging and error-handling,
|
16
|
-
* with the defaults:
|
17
|
-
* * No error handling
|
18
|
-
* * Execution time logging
|
19
|
-
*
|
20
|
-
* You should instantiate HandlerFactory in your project with desired error handling and use the factory instance for
|
21
|
-
* creating handler-functions for your lambdas.
|
22
|
-
*/
|
23
|
-
export class HandlerFactory {
|
24
|
-
private loggingHandler: LoggingHandler;
|
25
|
-
private errorHandler: ErrorHandler;
|
26
|
-
|
27
|
-
constructor() {
|
28
|
-
this.loggingHandler = async (method: () => Promise<LambdaResponse>) => {
|
29
|
-
const start = Date.now();
|
30
|
-
|
31
|
-
try {
|
32
|
-
return await method();
|
33
|
-
} finally {
|
34
|
-
console.info(
|
35
|
-
"method=%s.handler tookMs=%d",
|
36
|
-
functionName,
|
37
|
-
Date.now() - start
|
38
|
-
);
|
39
|
-
}
|
40
|
-
};
|
41
|
-
|
42
|
-
this.errorHandler = (error: unknown) => {
|
43
|
-
throw error;
|
44
|
-
};
|
45
|
-
}
|
46
|
-
|
47
|
-
withLoggingHandler(loggingHandler: LoggingHandler) {
|
48
|
-
this.loggingHandler = loggingHandler;
|
49
|
-
return this;
|
50
|
-
}
|
51
|
-
|
52
|
-
withErrorHandler(errorHandler: ErrorHandler) {
|
53
|
-
this.errorHandler = errorHandler;
|
54
|
-
return this;
|
55
|
-
}
|
56
|
-
|
57
|
-
createEventHandler(
|
58
|
-
handler: (event: unknown) => Promise<LambdaResponse>,
|
59
|
-
logger: DtLogger
|
60
|
-
) {
|
61
|
-
return async (event: unknown) => {
|
62
|
-
return await this.loggingHandler(async () => {
|
63
|
-
try {
|
64
|
-
return await handler(event);
|
65
|
-
} catch (error) {
|
66
|
-
return this.errorHandler(error, logger);
|
67
|
-
}
|
68
|
-
}, logger);
|
69
|
-
};
|
70
|
-
}
|
71
|
-
}
|
72
|
-
|
73
|
-
export function createJsonLoggingHandler(): LoggingHandler {
|
74
|
-
return async (method: () => Promise<LambdaResponse>, logger: DtLogger) => {
|
75
|
-
const start = Date.now();
|
76
|
-
|
77
|
-
try {
|
78
|
-
return await method();
|
79
|
-
} finally {
|
80
|
-
logger.info({
|
81
|
-
method: `${functionName}.handler`,
|
82
|
-
tookMs: Date.now() - start,
|
83
|
-
});
|
84
|
-
}
|
85
|
-
};
|
86
|
-
}
|
@@ -1,147 +0,0 @@
|
|
1
|
-
import {
|
2
|
-
IntegrationResponse,
|
3
|
-
LambdaIntegration,
|
4
|
-
PassthroughBehavior,
|
5
|
-
} from "aws-cdk-lib/aws-apigateway";
|
6
|
-
import { IFunction } from "aws-cdk-lib/aws-lambda";
|
7
|
-
import { MediaType } from "../../types/mediatypes.mjs";
|
8
|
-
import { DigitrafficIntegrationResponse } from "../../runtime/digitraffic-integration-response.mjs";
|
9
|
-
|
10
|
-
type ParameterType =
|
11
|
-
| "path"
|
12
|
-
| "querystring"
|
13
|
-
| "multivaluequerystring"
|
14
|
-
| "context"
|
15
|
-
| "header";
|
16
|
-
|
17
|
-
interface ApiParameter {
|
18
|
-
type: ParameterType;
|
19
|
-
name: string;
|
20
|
-
}
|
21
|
-
|
22
|
-
export class DigitrafficIntegration<T extends string> {
|
23
|
-
readonly lambda: IFunction;
|
24
|
-
readonly mediaType: MediaType;
|
25
|
-
readonly parameters: ApiParameter[] = [];
|
26
|
-
readonly sunset?: string;
|
27
|
-
|
28
|
-
constructor(
|
29
|
-
lambda: IFunction,
|
30
|
-
mediaType = MediaType.TEXT_PLAIN,
|
31
|
-
sunset?: string
|
32
|
-
) {
|
33
|
-
this.lambda = lambda;
|
34
|
-
this.mediaType = mediaType;
|
35
|
-
this.sunset = sunset;
|
36
|
-
}
|
37
|
-
|
38
|
-
addPathParameter(...names: T[]): this {
|
39
|
-
names.forEach((name) => this.parameters.push({ type: "path", name }));
|
40
|
-
|
41
|
-
return this;
|
42
|
-
}
|
43
|
-
|
44
|
-
addQueryParameter(...names: T[]): this {
|
45
|
-
names.forEach((name) =>
|
46
|
-
this.parameters.push({ type: "querystring", name })
|
47
|
-
);
|
48
|
-
return this;
|
49
|
-
}
|
50
|
-
|
51
|
-
addMultiValueQueryParameter(...names: T[]): this {
|
52
|
-
names.forEach((name) =>
|
53
|
-
this.parameters.push({ type: "multivaluequerystring", name })
|
54
|
-
);
|
55
|
-
return this;
|
56
|
-
}
|
57
|
-
|
58
|
-
/**
|
59
|
-
* Note that context parameter values needs to be in json format as they will be parsed in template as json.
|
60
|
-
* See createRequestTemplates below.
|
61
|
-
* @param names for the parameters
|
62
|
-
* @returns
|
63
|
-
*/
|
64
|
-
addContextParameter(...names: T[]): this {
|
65
|
-
names.forEach((name) =>
|
66
|
-
this.parameters.push({ type: "context", name })
|
67
|
-
);
|
68
|
-
|
69
|
-
return this;
|
70
|
-
}
|
71
|
-
|
72
|
-
/**
|
73
|
-
* Do not use Authorization header as that will be consumed by ApiGW.
|
74
|
-
* If Authorization header is needed, use lambda authorizers.
|
75
|
-
* @param names for the headers
|
76
|
-
*/
|
77
|
-
addHeaderParameter(...names: T[]): this {
|
78
|
-
names.forEach((name) => this.parameters.push({ type: "header", name }));
|
79
|
-
|
80
|
-
return this;
|
81
|
-
}
|
82
|
-
|
83
|
-
build(): LambdaIntegration {
|
84
|
-
const integrationResponses = this.createResponses();
|
85
|
-
|
86
|
-
return new LambdaIntegration(this.lambda, {
|
87
|
-
proxy: false,
|
88
|
-
integrationResponses,
|
89
|
-
requestParameters:
|
90
|
-
this.parameters.length == 0
|
91
|
-
? undefined
|
92
|
-
: this.createRequestParameters(),
|
93
|
-
requestTemplates:
|
94
|
-
this.parameters.length == 0
|
95
|
-
? undefined
|
96
|
-
: this.createRequestTemplates(),
|
97
|
-
passthroughBehavior: PassthroughBehavior.WHEN_NO_MATCH,
|
98
|
-
});
|
99
|
-
}
|
100
|
-
|
101
|
-
createRequestParameters(): Record<string, string> {
|
102
|
-
const requestParameters: Record<string, string> = {};
|
103
|
-
|
104
|
-
// filter out context parameters
|
105
|
-
this.parameters
|
106
|
-
.filter((parameter) => parameter.type !== "context")
|
107
|
-
.forEach((parameter: ApiParameter) => {
|
108
|
-
requestParameters[
|
109
|
-
`integration.request.${parameter.type.replace(
|
110
|
-
"multivaluequerystring",
|
111
|
-
"querystring"
|
112
|
-
)}.${parameter.name}`
|
113
|
-
] = `method.request.${parameter.type}.${parameter.name}`;
|
114
|
-
});
|
115
|
-
|
116
|
-
return requestParameters;
|
117
|
-
}
|
118
|
-
|
119
|
-
createRequestTemplates(): Record<string, string> {
|
120
|
-
const requestJson: Record<string, string> = {};
|
121
|
-
|
122
|
-
this.parameters.forEach((parameter: ApiParameter) => {
|
123
|
-
if (parameter.type === "context") {
|
124
|
-
requestJson[
|
125
|
-
parameter.name
|
126
|
-
] = `$util.parseJson($context.${parameter.name})`;
|
127
|
-
} else if (parameter.type === "multivaluequerystring") {
|
128
|
-
// make multivaluequerystring values to array
|
129
|
-
requestJson[
|
130
|
-
parameter.name
|
131
|
-
] = `[#foreach($val in $method.request.multivaluequerystring.get('${parameter.name}'))"$util.escapeJavaScript($val)"#if($foreach.hasNext),#end#end]`;
|
132
|
-
} else {
|
133
|
-
requestJson[
|
134
|
-
parameter.name
|
135
|
-
] = `$util.escapeJavaScript($input.params('${parameter.name}'))`;
|
136
|
-
}
|
137
|
-
});
|
138
|
-
|
139
|
-
return {
|
140
|
-
[MediaType.APPLICATION_JSON]: JSON.stringify(requestJson),
|
141
|
-
};
|
142
|
-
}
|
143
|
-
|
144
|
-
createResponses(): IntegrationResponse[] {
|
145
|
-
return [DigitrafficIntegrationResponse.ok(this.mediaType, this.sunset)];
|
146
|
-
}
|
147
|
-
}
|
@@ -1,165 +0,0 @@
|
|
1
|
-
import { MediaType } from "../../types/mediatypes.mjs";
|
2
|
-
import {
|
3
|
-
JsonSchema,
|
4
|
-
JsonSchemaType,
|
5
|
-
JsonSchemaVersion,
|
6
|
-
MethodResponse,
|
7
|
-
Model,
|
8
|
-
type IModel
|
9
|
-
} from "aws-cdk-lib/aws-apigateway";
|
10
|
-
import { dateFromIsoString } from "../../../utils/date-utils.mjs";
|
11
|
-
|
12
|
-
/**
|
13
|
-
* This is velocity-script, that assumes the response to be LambdaResponse(status and body).
|
14
|
-
* It will always return the body and status, but if status in something else than 200 OK the content-type
|
15
|
-
* will be overridden to text/plain. (it's assumed, that lambda will return error text).
|
16
|
-
*
|
17
|
-
* Body content must be base64-encoded! use LambdaResponse for this! This way you can also return
|
18
|
-
* non-textual content.
|
19
|
-
*
|
20
|
-
* If fileName is set, then Content-Disposition-header will be set to use it
|
21
|
-
* If timestamp is set, then ETag & Last-Modified headers will be set
|
22
|
-
*/
|
23
|
-
export const RESPONSE_DEFAULT_LAMBDA = `#set($inputRoot = $input.path('$'))
|
24
|
-
#if ($inputRoot.status != 200)
|
25
|
-
#set ($context.responseOverride.status = $inputRoot.status)
|
26
|
-
#set ($context.responseOverride.header.Content-Type = 'text/plain')
|
27
|
-
#end
|
28
|
-
#set ($context.responseOverride.header.Access-Control-Allow-Origin = '*')
|
29
|
-
#if ("$!inputRoot.timestamp" != "")
|
30
|
-
#set ($context.responseOverride.header.Last-Modified = $inputRoot.timestamp)
|
31
|
-
#end
|
32
|
-
#if ("$!inputRoot.etag" != "")
|
33
|
-
#set ($context.responseOverride.header.ETag = $inputRoot.etag)
|
34
|
-
#end
|
35
|
-
#if ("$!inputRoot.fileName" != "")
|
36
|
-
#set ($disposition = 'attachment; filename="FN"')
|
37
|
-
#set ($context.responseOverride.header.Content-Disposition = $disposition.replaceAll('FN', $inputRoot.fileName))
|
38
|
-
#end
|
39
|
-
$util.base64Decode($inputRoot.body)`;
|
40
|
-
|
41
|
-
/**
|
42
|
-
* Use this for deprecated integrations.
|
43
|
-
* Will add HTTP headers Deprecation and Sunset to response.
|
44
|
-
* Example:
|
45
|
-
* Deprecation: true
|
46
|
-
* Sunset: Tue, 20 Dec 2022 00:00:00 GMT
|
47
|
-
* @param sunset Sunset date as string in ISO 8601 date-time format (YYYY-MM-DD)
|
48
|
-
*/
|
49
|
-
|
50
|
-
export const getDeprecatedDefaultLambdaResponse = (sunset: string) => {
|
51
|
-
const setDeprecationHeaders = `#set ($context.responseOverride.header.Deprecation = 'true')
|
52
|
-
#set ($context.responseOverride.header.Sunset = '${dateFromIsoString(
|
53
|
-
sunset
|
54
|
-
).toUTCString()}')`;
|
55
|
-
return RESPONSE_DEFAULT_LAMBDA.concat(setDeprecationHeaders);
|
56
|
-
};
|
57
|
-
|
58
|
-
const BODY_FROM_INPUT_PATH = "$input.path('$').body";
|
59
|
-
|
60
|
-
/// @deprecated
|
61
|
-
const messageSchema: JsonSchema = {
|
62
|
-
schema: JsonSchemaVersion.DRAFT4,
|
63
|
-
type: JsonSchemaType.OBJECT,
|
64
|
-
description: "Response with message",
|
65
|
-
properties: {
|
66
|
-
message: {
|
67
|
-
type: JsonSchemaType.STRING,
|
68
|
-
description: "Response message",
|
69
|
-
},
|
70
|
-
},
|
71
|
-
};
|
72
|
-
|
73
|
-
/// @deprecated
|
74
|
-
export const MessageModel = {
|
75
|
-
contentType: MediaType.APPLICATION_JSON,
|
76
|
-
modelName: "MessageResponseModel",
|
77
|
-
schema: messageSchema,
|
78
|
-
};
|
79
|
-
|
80
|
-
const NotFoundMessage = "Not found";
|
81
|
-
export const NotFoundResponse = JSON.stringify({ message: NotFoundMessage });
|
82
|
-
|
83
|
-
const InternalServerErrorMessage = "Error";
|
84
|
-
const InternalServerErrorResponse = JSON.stringify({
|
85
|
-
message: InternalServerErrorMessage,
|
86
|
-
});
|
87
|
-
|
88
|
-
const BadRequestMessage = "Bad request";
|
89
|
-
const BadRequestResponse = JSON.stringify({ message: BadRequestMessage });
|
90
|
-
|
91
|
-
/// @deprecated
|
92
|
-
export const BadRequestResponseTemplate = {
|
93
|
-
[MediaType.APPLICATION_JSON]: BadRequestResponse,
|
94
|
-
};
|
95
|
-
/// @deprecated
|
96
|
-
export const NotFoundResponseTemplate = {
|
97
|
-
[MediaType.APPLICATION_JSON]: NotFoundResponse,
|
98
|
-
};
|
99
|
-
/// @deprecated
|
100
|
-
export const XmlResponseTemplate = {
|
101
|
-
[MediaType.APPLICATION_XML]: BODY_FROM_INPUT_PATH,
|
102
|
-
};
|
103
|
-
/// @deprecated
|
104
|
-
export const InternalServerErrorResponseTemplate = {
|
105
|
-
[MediaType.APPLICATION_JSON]: InternalServerErrorResponse,
|
106
|
-
};
|
107
|
-
|
108
|
-
export class DigitrafficMethodResponse {
|
109
|
-
static response(
|
110
|
-
statusCode: string,
|
111
|
-
model: IModel,
|
112
|
-
mediaType: MediaType,
|
113
|
-
disableCors = false,
|
114
|
-
deprecation = false
|
115
|
-
): MethodResponse {
|
116
|
-
return {
|
117
|
-
statusCode,
|
118
|
-
responseModels: {
|
119
|
-
[mediaType]: model,
|
120
|
-
},
|
121
|
-
responseParameters: {
|
122
|
-
...(!disableCors && {
|
123
|
-
"method.response.header.Access-Control-Allow-Origin": true,
|
124
|
-
}),
|
125
|
-
...(deprecation && {
|
126
|
-
"method.response.header.Deprecation": true,
|
127
|
-
"method.response.header.Sunset": true,
|
128
|
-
}),
|
129
|
-
},
|
130
|
-
};
|
131
|
-
}
|
132
|
-
|
133
|
-
static response200(model: IModel, mediaType = MediaType.APPLICATION_JSON) {
|
134
|
-
return DigitrafficMethodResponse.response(
|
135
|
-
"200",
|
136
|
-
model,
|
137
|
-
mediaType,
|
138
|
-
false
|
139
|
-
);
|
140
|
-
}
|
141
|
-
|
142
|
-
static response500(
|
143
|
-
model = Model.EMPTY_MODEL,
|
144
|
-
mediaType = MediaType.APPLICATION_JSON
|
145
|
-
) {
|
146
|
-
return DigitrafficMethodResponse.response(
|
147
|
-
"500",
|
148
|
-
model,
|
149
|
-
mediaType,
|
150
|
-
false
|
151
|
-
);
|
152
|
-
}
|
153
|
-
|
154
|
-
static response400(
|
155
|
-
model = Model.EMPTY_MODEL,
|
156
|
-
mediaType = MediaType.APPLICATION_JSON
|
157
|
-
) {
|
158
|
-
return DigitrafficMethodResponse.response(
|
159
|
-
"400",
|
160
|
-
model,
|
161
|
-
mediaType,
|
162
|
-
false
|
163
|
-
);
|
164
|
-
}
|
165
|
-
}
|