@digitraffic/common 2024.6.26-2 → 2024.7.2-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.
@@ -1,7 +1,7 @@
1
1
  const madge = await import("madge");
2
2
  const WHITELISTED_DEPENDENCIES = [
3
3
  // aspect is using DigitrafficStack with instanceof, can't remove
4
- `["aws/infra/stack/stack.mjs","aws/infra/stack/stack-checking-aspect.mjs"]`
4
+ `["aws/infra/stack/stack.mjs","aws/infra/stack/stack-checking-aspect.mjs"]`,
5
5
  ];
6
6
  function whitelist(circular) {
7
7
  return !WHITELISTED_DEPENDENCIES.includes(JSON.stringify(circular));
@@ -11,7 +11,7 @@ function assertNoErrors(errors) {
11
11
  }
12
12
  test("circular dependencies", async () => {
13
13
  const instance = await madge.default("dist", {
14
- fileExtensions: ["mts", "mjs"]
14
+ fileExtensions: ["mts", "mjs"],
15
15
  });
16
16
  const circulars = instance.circular();
17
17
  const errors = circulars.filter(whitelist);
@@ -27,7 +27,7 @@ describe("acl-builder tests", () => {
27
27
  createBuilder().withThrottleDigitrafficUserIp(100),
28
28
  createBuilder().withThrottleDigitrafficUserIpAndUriPath(100),
29
29
  createBuilder().withThrottleAnonymousUserIp(100),
30
- createBuilder().withThrottleAnonymousUserIpAndUriPath(100)
30
+ createBuilder().withThrottleAnonymousUserIpAndUriPath(100),
31
31
  ]) {
32
32
  const acl = aclBuilder.build();
33
33
  // Check that the rule exists and a custom response is defined
@@ -40,19 +40,16 @@ describe("acl-builder tests", () => {
40
40
  }
41
41
  });
42
42
  test("Cannot define two rules with the same name", () => {
43
- expect(() => createBuilder()
44
- .withThrottleAnonymousUserIp(10)
45
- .withThrottleAnonymousUserIp(200)
46
- .build()).toThrow();
43
+ expect(() => createBuilder().withThrottleAnonymousUserIp(10).withThrottleAnonymousUserIp(200).build()).toThrow();
47
44
  });
48
45
  test("throtle rule without limit does nothing", () => {
49
46
  for (const aclBuilder of [
50
47
  createBuilder().withThrottleDigitrafficUserIp(undefined),
51
48
  createBuilder().withThrottleDigitrafficUserIpAndUriPath(undefined),
52
49
  createBuilder().withThrottleAnonymousUserIp(null),
53
- createBuilder().withThrottleAnonymousUserIpAndUriPath(null)
50
+ createBuilder().withThrottleAnonymousUserIpAndUriPath(null),
54
51
  ]) {
55
- expect(() => aclBuilder.build()).toThrowError('No rules');
52
+ expect(() => aclBuilder.build()).toThrowError("No rules");
56
53
  }
57
54
  });
58
55
  });
@@ -5,21 +5,23 @@ describe("response tests", () => {
5
5
  const integrationResponse = DigitrafficStaticIntegration.createIntegrationResponse("FakeResource", MediaType.APPLICATION_JSON, { "test-header": "test-value" });
6
6
  expect(integrationResponse).toEqual({
7
7
  responseParameters: {
8
- "method.response.header.test-header": "'test-value'"
8
+ "method.response.header.test-header": "'test-value'",
9
9
  },
10
10
  responseTemplates: {
11
- "application/json": "FakeResource"
11
+ "application/json": "FakeResource",
12
12
  },
13
- statusCode: "200"
13
+ statusCode: "200",
14
14
  });
15
15
  });
16
16
  it("createMethodResponse works", () => {
17
- const methodResponse = DigitrafficStaticIntegration.createMethodResponse({ "test-header": "test-value" });
17
+ const methodResponse = DigitrafficStaticIntegration.createMethodResponse({
18
+ "test-header": "test-value",
19
+ });
18
20
  expect(methodResponse).toEqual({
19
21
  responseParameters: {
20
- "method.response.header.test-header": true
22
+ "method.response.header.test-header": true,
21
23
  },
22
- statusCode: "200"
24
+ statusCode: "200",
23
25
  });
24
26
  });
25
27
  });
@@ -10,8 +10,8 @@ describe("scheduler tests", () => {
10
10
  template.hasResource("AWS::Events::Rule", {
11
11
  Properties: {
12
12
  ScheduleExpression: expectedRate,
13
- State: "ENABLED"
14
- }
13
+ State: "ENABLED",
14
+ },
15
15
  });
16
16
  }
17
17
  test("everyMinute", () => expectRate((stack) => Scheduler.everyMinute(stack, "test"), "rate(1 minute)"));
@@ -12,8 +12,8 @@ describe("security-rule tests", () => {
12
12
  template.hasResource("AWS::Events::Rule", {
13
13
  Properties: {
14
14
  EventPattern: {},
15
- State: "ENABLED"
16
- }
15
+ State: "ENABLED",
16
+ },
17
17
  });
18
18
  });
19
19
  });
@@ -1,4 +1,4 @@
1
- import { SecretsManager } from "@aws-sdk/client-secrets-manager";
1
+ import { SecretsManager, } from "@aws-sdk/client-secrets-manager";
2
2
  import { jest } from "@jest/globals";
3
3
  const SECRET_WITH_PREFIX = {
4
4
  "prefix.value": "value",
@@ -1,4 +1,4 @@
1
- import { SecretsManager } from "@aws-sdk/client-secrets-manager";
1
+ import { SecretsManager, } from "@aws-sdk/client-secrets-manager";
2
2
  import { jest } from "@jest/globals";
3
3
  const SECRET_ID = "test_secret";
4
4
  const SECRET_WITH_PREFIX = {
@@ -12,7 +12,7 @@ describe("Rest api test", () => {
12
12
  shortName: "test",
13
13
  stackProps: {},
14
14
  trafficType: TrafficType.ROAD,
15
- warningTopicArn: ""
15
+ warningTopicArn: "",
16
16
  });
17
17
  const publicApi = new DigitrafficRestApi(stack, "test", "testName");
18
18
  const apiResource = publicApi.root.addResource("api");
@@ -30,12 +30,12 @@ describe("Rest api test", () => {
30
30
  ResponseParameters: Match.objectEquals({
31
31
  "method.response.header.Access-Control-Allow-Headers": "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,Digitraffic-User'",
32
32
  "method.response.header.Access-Control-Allow-Origin": "'*'",
33
- "method.response.header.Access-Control-Allow-Methods": "'OPTIONS,GET,HEAD'"
33
+ "method.response.header.Access-Control-Allow-Methods": "'OPTIONS,GET,HEAD'",
34
34
  }),
35
- })
35
+ }),
36
36
  ]),
37
37
  },
38
- }
38
+ },
39
39
  });
40
40
  });
41
41
  });
@@ -39,5 +39,8 @@ describe("ArrayUtils", () => {
39
39
  test("getLast - two objects", () => {
40
40
  expect(ArrayUtils.getLast([1, 2])).toEqual(2);
41
41
  });
42
+ test("isDefined", () => {
43
+ expect([1, 2, undefined, null, 3].filter(ArrayUtils.isDefined)).toEqual([1, 2, 3]);
44
+ });
42
45
  });
43
46
  //# sourceMappingURL=utils.test.mjs.map
@@ -64,17 +64,17 @@ export class AclBuilder {
64
64
  visibilityConfig: {
65
65
  sampledRequestsEnabled: true,
66
66
  cloudWatchMetricsEnabled: true,
67
- metricName: name
67
+ metricName: name,
68
68
  },
69
69
  action: {
70
70
  block: {
71
71
  customResponse: {
72
72
  responseCode: 429,
73
- customResponseBodyKey
74
- }
75
- }
73
+ customResponseBodyKey,
74
+ },
75
+ },
76
76
  },
77
- statement: createThrottleStatement(limit, isHeaderRequired, isBasedOnIpAndUriPath)
77
+ statement: createThrottleStatement(limit, isHeaderRequired, isBasedOnIpAndUriPath),
78
78
  });
79
79
  return this;
80
80
  }
@@ -82,7 +82,7 @@ export class AclBuilder {
82
82
  if (key in this._customResponseBodies) {
83
83
  logger.warn({
84
84
  method: "acl-builder.withCustomResponseBody",
85
- message: `Overriding custom response body with key ${key}`
85
+ message: `Overriding custom response body with key ${key}`,
86
86
  });
87
87
  }
88
88
  this._customResponseBodies[key] = customResponseBody;
@@ -131,21 +131,21 @@ export class AclBuilder {
131
131
  if (!this._isCustomResponseBodyKeySet(customResponseBodyKey)) {
132
132
  this.withCustomResponseBody(customResponseBodyKey, {
133
133
  content: `Request rate is limited to ${limit} requests in a 5 minute window.`,
134
- contentType: "TEXT_PLAIN"
134
+ contentType: "TEXT_PLAIN",
135
135
  });
136
136
  }
137
137
  }
138
138
  _logMissingLimit(method) {
139
139
  logger.warn({
140
140
  method: `acl-builder.${method}`,
141
- message: `'limit' was not defined. Not setting a throttle rule`
141
+ message: `'limit' was not defined. Not setting a throttle rule`,
142
142
  });
143
143
  }
144
144
  build() {
145
145
  if (this._rules.length === 0) {
146
146
  throw new Error("No rules defined for WebACL");
147
147
  }
148
- const uniqueRuleNames = new Set(this._rules.map(rule => rule.name));
148
+ const uniqueRuleNames = new Set(this._rules.map((rule) => rule.name));
149
149
  if (uniqueRuleNames.size != this._rules.length) {
150
150
  throw new Error("Tried to create an Access Control List with multiple rules having the same name");
151
151
  }
@@ -155,7 +155,7 @@ export class AclBuilder {
155
155
  visibilityConfig: {
156
156
  cloudWatchMetricsEnabled: true,
157
157
  metricName: "WAF-Blocked",
158
- sampledRequestsEnabled: false
158
+ sampledRequestsEnabled: false,
159
159
  },
160
160
  rules: this._rules,
161
161
  customResponseBodies: this._customResponseBodies,
@@ -169,28 +169,28 @@ const CUSTOM_KEYS_IP_AND_URI_PATH = [
169
169
  textTransformations: [
170
170
  {
171
171
  priority: 1,
172
- type: "LOWERCASE"
172
+ type: "LOWERCASE",
173
173
  },
174
174
  {
175
175
  priority: 2,
176
- type: "NORMALIZE_PATH"
176
+ type: "NORMALIZE_PATH",
177
177
  },
178
178
  {
179
179
  priority: 3,
180
- type: "MD5"
181
- }
182
- ]
183
- }
180
+ type: "MD5",
181
+ },
182
+ ],
183
+ },
184
184
  },
185
185
  {
186
- ip: {}
187
- }
186
+ ip: {},
187
+ },
188
188
  ];
189
189
  function notStatement(statement) {
190
190
  return {
191
191
  notStatement: {
192
- statement
193
- }
192
+ statement,
193
+ },
194
194
  };
195
195
  }
196
196
  function createThrottleStatement(limit, isHeaderRequired, isBasedOnIpAndUriPath) {
@@ -200,12 +200,12 @@ function createThrottleStatement(limit, isHeaderRequired, isBasedOnIpAndUriPath)
200
200
  comparisonOperator: isHeaderRequired ? "GT" : "GE",
201
201
  fieldToMatch: {
202
202
  singleHeader: {
203
- Name: "digitraffic-user"
204
- }
203
+ Name: "digitraffic-user",
204
+ },
205
205
  },
206
206
  textTransformations: [{ priority: 0, type: "NONE" }],
207
- size: 0
208
- }
207
+ size: 0,
208
+ },
209
209
  };
210
210
  // header present -> size > 0
211
211
  // header not present -> NOT(size >= 0)
@@ -215,16 +215,16 @@ function createThrottleStatement(limit, isHeaderRequired, isBasedOnIpAndUriPath)
215
215
  aggregateKeyType: "CUSTOM_KEYS",
216
216
  customKeys: CUSTOM_KEYS_IP_AND_URI_PATH,
217
217
  limit: limit,
218
- scopeDownStatement: isHeaderRequired ? matchStatement : notStatement(matchStatement)
219
- }
218
+ scopeDownStatement: isHeaderRequired ? matchStatement : notStatement(matchStatement),
219
+ },
220
220
  };
221
221
  }
222
222
  return {
223
223
  rateBasedStatement: {
224
224
  aggregateKeyType: "IP",
225
225
  limit: limit,
226
- scopeDownStatement: isHeaderRequired ? matchStatement : notStatement(matchStatement)
227
- }
226
+ scopeDownStatement: isHeaderRequired ? matchStatement : notStatement(matchStatement),
227
+ },
228
228
  };
229
229
  }
230
230
  function createAWSCommonRuleSet() {
@@ -236,10 +236,10 @@ function createAWSCommonRuleSet() {
236
236
  excludedRules: [
237
237
  { name: "NoUserAgent_HEADER" },
238
238
  { name: "SizeRestrictions_BODY" },
239
- { name: "GenericRFI_BODY" }
240
- ]
241
- }
242
- }
239
+ { name: "GenericRFI_BODY" },
240
+ ],
241
+ },
242
+ },
243
243
  });
244
244
  }
245
245
  function createAWSReputationList() {
@@ -247,9 +247,9 @@ function createAWSReputationList() {
247
247
  statement: {
248
248
  managedRuleGroupStatement: {
249
249
  vendorName: "AWS",
250
- name: "AWSManagedRulesAmazonIpReputationList"
251
- }
252
- }
250
+ name: "AWSManagedRulesAmazonIpReputationList",
251
+ },
252
+ },
253
253
  });
254
254
  }
255
255
  function createAWSKnownBadInput() {
@@ -257,9 +257,9 @@ function createAWSKnownBadInput() {
257
257
  statement: {
258
258
  managedRuleGroupStatement: {
259
259
  vendorName: "AWS",
260
- name: "AWSManagedRulesKnownBadInputsRuleSet"
261
- }
262
- }
260
+ name: "AWSManagedRulesKnownBadInputsRuleSet",
261
+ },
262
+ },
263
263
  });
264
264
  }
265
265
  function createAWSAntiSQLInjection() {
@@ -267,9 +267,9 @@ function createAWSAntiSQLInjection() {
267
267
  statement: {
268
268
  managedRuleGroupStatement: {
269
269
  vendorName: "AWS",
270
- name: "AWSManagedRulesSQLiRuleSet"
271
- }
272
- }
270
+ name: "AWSManagedRulesSQLiRuleSet",
271
+ },
272
+ },
273
273
  });
274
274
  }
275
275
  function createRuleProperty(name, priority, rule, overrideAction = true) {
@@ -280,11 +280,11 @@ function createRuleProperty(name, priority, rule, overrideAction = true) {
280
280
  visibilityConfig: {
281
281
  sampledRequestsEnabled: true,
282
282
  cloudWatchMetricsEnabled: true,
283
- metricName: name
284
- }
283
+ metricName: name,
284
+ },
285
285
  },
286
286
  ...rule,
287
- ...(overrideAction ? { overrideAction: { none: {} } } : {})
287
+ ...(overrideAction ? { overrideAction: { none: {} } } : {}),
288
288
  };
289
289
  }
290
290
  //# sourceMappingURL=acl-builder.mjs.map
@@ -26,9 +26,7 @@ export class DigitrafficStaticIntegration extends MockIntegration {
26
26
  ["GET", "HEAD"].forEach((httpMethod) => {
27
27
  resource.addMethod(httpMethod, this, {
28
28
  apiKeyRequired,
29
- methodResponses: [
30
- DigitrafficStaticIntegration.createMethodResponse(headers),
31
- ],
29
+ methodResponses: [DigitrafficStaticIntegration.createMethodResponse(headers)],
32
30
  });
33
31
  });
34
32
  }
@@ -42,7 +40,7 @@ export class DigitrafficStaticIntegration extends MockIntegration {
42
40
  responseTemplates: {
43
41
  [mediaType]: response,
44
42
  },
45
- responseParameters: params
43
+ responseParameters: params,
46
44
  };
47
45
  }
48
46
  static createMethodResponse(headers) {
@@ -50,7 +48,7 @@ export class DigitrafficStaticIntegration extends MockIntegration {
50
48
  const entries = Object.fromEntries(allowedHeaders.map((key) => [key, true]));
51
49
  return {
52
50
  statusCode: "200",
53
- responseParameters: prefixKeys("method.response.header.", entries)
51
+ responseParameters: prefixKeys("method.response.header.", entries),
54
52
  };
55
53
  }
56
54
  }
@@ -17,14 +17,14 @@ export class DigitrafficSecurityRule extends Rule {
17
17
  detailType: ["Security Hub Findings - Imported"],
18
18
  detail: {
19
19
  findings: {
20
- "Compliance": {
21
- "Status": ["FAILED"],
20
+ Compliance: {
21
+ Status: ["FAILED"],
22
22
  },
23
- "Workflow": {
24
- "Status": ["NEW"],
23
+ Workflow: {
24
+ Status: ["NEW"],
25
25
  },
26
- "Severity": {
27
- "Label": ["HIGH", "CRITICAL"],
26
+ Severity: {
27
+ Label: ["HIGH", "CRITICAL"],
28
28
  },
29
29
  },
30
30
  },
@@ -1,4 +1,4 @@
1
- import { ApplicationLogLevel, Function, LoggingFormat, SystemLogLevel } from "aws-cdk-lib/aws-lambda";
1
+ import { ApplicationLogLevel, Function, LoggingFormat, SystemLogLevel, } from "aws-cdk-lib/aws-lambda";
2
2
  import { Stack } from "aws-cdk-lib";
3
3
  import { SnsAction } from "aws-cdk-lib/aws-cloudwatch-actions";
4
4
  import { ComparisonOperator, Metric } from "aws-cdk-lib/aws-cloudwatch";
@@ -35,8 +35,7 @@ export class MonitoredFunction extends Function {
35
35
  * @param props Monitored function properties
36
36
  */
37
37
  static create(stack, id, functionProps, props) {
38
- if (props === MonitoredFunction.DISABLE_ALARMS &&
39
- stack.configuration.production) {
38
+ if (props === MonitoredFunction.DISABLE_ALARMS && stack.configuration.production) {
40
39
  throw new Error(
41
40
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
42
41
  `Function ${functionProps.functionName} has DISABLE_ALARMS. Remove before installing to production or define your own properties!`);
@@ -78,9 +77,10 @@ export class MonitoredFunction extends Function {
78
77
  super(scope, id, {
79
78
  ...{
80
79
  loggingFormat: LoggingFormat.JSON,
81
- applicationLogLevel: ApplicationLogLevel.DEBUG,
82
- systemLogLevel: SystemLogLevel.INFO
83
- }, ...functionProps
80
+ applicationLogLevelV2: ApplicationLogLevel.DEBUG,
81
+ systemLogLevelV2: SystemLogLevel.INFO,
82
+ },
83
+ ...functionProps,
84
84
  });
85
85
  if (functionProps.functionName === undefined) {
86
86
  throw new Error("Function name not provided");
@@ -1,5 +1,5 @@
1
1
  import { CfnDocumentationPart, Cors, EndpointType, GatewayResponse, MethodLoggingLevel, Model, Resource, ResponseType, RestApi, } from "aws-cdk-lib/aws-apigateway";
2
- import { AnyPrincipal, Effect, PolicyDocument, PolicyStatement, } from "aws-cdk-lib/aws-iam";
2
+ import { AnyPrincipal, Effect, PolicyDocument, PolicyStatement } from "aws-cdk-lib/aws-iam";
3
3
  import { Construct } from "constructs";
4
4
  import { getModelReference } from "../../../utils/api-model.mjs";
5
5
  import { MediaType } from "../../types/mediatypes.mjs";
@@ -28,8 +28,7 @@ export class DigitrafficRestApi extends RestApi {
28
28
  };
29
29
  super(stack, apiId, apiConfig);
30
30
  this.apiKeyIds = [];
31
- this.enableDocumentation =
32
- stack.configuration.stackFeatures?.enableDocumentation ?? true;
31
+ this.enableDocumentation = stack.configuration.stackFeatures?.enableDocumentation ?? true;
33
32
  add404Support(this, stack);
34
33
  }
35
34
  hostname() {
@@ -85,7 +84,7 @@ export class DigitrafficRestApi extends RestApi {
85
84
  addResourceWithCorsOptionsSubTree(resource, pathPart, config) {
86
85
  const mergedConfig = {
87
86
  ...PUBLIC_REST_API_CORS_CONFIG,
88
- ...config
87
+ ...config,
89
88
  };
90
89
  return resource.addResource(pathPart, mergedConfig);
91
90
  }
@@ -191,8 +190,15 @@ export function createIpRestrictionPolicyDocument(allowFromIpAddresses) {
191
190
  export const PUBLIC_REST_API_CORS_CONFIG = {
192
191
  defaultCorsPreflightOptions: {
193
192
  allowOrigins: Cors.ALL_ORIGINS,
194
- allowHeaders: ["Content-Type", "X-Amz-Date", "Authorization", "X-Api-Key", "X-Amz-Security-Token", "Digitraffic-User"],
195
- allowMethods: ["OPTIONS", "GET", "HEAD"]
196
- }
193
+ allowHeaders: [
194
+ "Content-Type",
195
+ "X-Amz-Date",
196
+ "Authorization",
197
+ "X-Api-Key",
198
+ "X-Amz-Security-Token",
199
+ "Digitraffic-User",
200
+ ],
201
+ allowMethods: ["OPTIONS", "GET", "HEAD"],
202
+ },
197
203
  };
198
204
  //# sourceMappingURL=rest_apis.mjs.map
@@ -140,7 +140,7 @@ export class StackCheckingAspect {
140
140
  const type = split[2];
141
141
  const name = split[3];
142
142
  if (name === undefined) {
143
- throw Error('Name should not be undefined');
143
+ throw Error("Name should not be undefined");
144
144
  }
145
145
  if (type === "querystring" && !StackCheckingAspect.isValidQueryString(name)) {
146
146
  this.addAnnotation(node, name, "Querystring should be in snake_case");
@@ -159,7 +159,7 @@ export class StackCheckingAspect {
159
159
  checkLogGroupRetention(node) {
160
160
  if (node instanceof LogRetention) {
161
161
  const child = node.node.defaultChild;
162
- const retention = child?.['_cfnProperties']?.['RetentionInDays'];
162
+ const retention = child?.["_cfnProperties"]?.["RetentionInDays"];
163
163
  if (!retention) {
164
164
  this.addAnnotation(node, ResourceType.logGroupRetention, "Log group must define log group retention");
165
165
  }
@@ -39,7 +39,8 @@ export class DigitrafficStack extends Stack {
39
39
  this.lambdaDbSg = SecurityGroup.fromSecurityGroupId(this, "LambdaDbSG", configuration.lambdaDbSgId);
40
40
  }
41
41
  this.alarmTopic = Topic.fromTopicArn(this, "AlarmTopic", StringParameter.fromStringParameterName(this, "AlarmTopicParam", SSM_KEY_ALARM_TOPIC).stringValue);
42
- this.warningTopic = Topic.fromTopicArn(this, "WarningTopic", StringParameter.fromStringParameterName(this, "WarningTopicParam", SSM_KEY_WARNING_TOPIC).stringValue);
42
+ this.warningTopic = Topic.fromTopicArn(this, "WarningTopic", StringParameter.fromStringParameterName(this, "WarningTopicParam", SSM_KEY_WARNING_TOPIC)
43
+ .stringValue);
43
44
  this.addAspects();
44
45
  }
45
46
  addAspects() {
@@ -3,10 +3,12 @@
3
3
  import { APIGateway } from "aws-sdk";
4
4
  export async function getApiKeyFromAPIGateway(keyId) {
5
5
  const ag = new APIGateway();
6
- return ag.getApiKey({
6
+ return ag
7
+ .getApiKey({
7
8
  apiKey: keyId,
8
- includeValue: true
9
- }).promise();
9
+ includeValue: true,
10
+ })
11
+ .promise();
10
12
  /*
11
13
  const client = new APIGatewayClient();
12
14
  const command = new GetApiKeyCommand({
@@ -1,9 +1,9 @@
1
- import { DatabaseEnvironmentKeys, initDbConnection, } from "../database/database.mjs";
1
+ import { DatabaseEnvironmentKeys, initDbConnection } from "../database/database.mjs";
2
2
  export async function assertCount(db, sql, count) {
3
3
  await db.one(sql).then((x) => expect(x.count).toEqual(count));
4
4
  }
5
5
  export function dbTestBase(fn, truncateFn, dbUser, dbPass, dbUri) {
6
- const theDbUri = process.env['DB_URI'] ?? dbUri;
6
+ const theDbUri = process.env["DB_URI"] ?? dbUri;
7
7
  console.log(`Test database URI: ${theDbUri}`);
8
8
  return () => {
9
9
  const db = initDbConnection(dbUser, dbPass, "test", theDbUri, {
@@ -17,9 +17,12 @@ export declare function createFeatureCollection(features: Feature[], lastUpdated
17
17
  export declare function isValidGeoJson<T>(json: T): boolean;
18
18
  export declare function isFeatureCollection<T>(json: T): boolean;
19
19
  /**
20
- * Calculates distance between two GeoJSON points (WGS84)
21
- * @param pos1
22
- * @param pos2
20
+ * Returns the distance between two WGS84 GeoJSON positions in kilometers. Doesn't take in account altitude.
21
+ * Based on the following Stack Overflow question:
22
+ * http://stackoverflow.com/questions/27928/calculate-distance-between-two-latitude-longitude-points-haversine-formula,
23
+ * which is based on https://en.wikipedia.org/wiki/Haversine_formula (error rate: ~0.55%).
24
+ * @param pos1 first position
25
+ * @param pos2 second position
23
26
  */
24
27
  export declare function distanceBetweenPositionsInKm(pos1: Position, pos2: Position): number;
25
28
  export declare function areDistinctPositions(previous: Position, next: Position): boolean;
@@ -65,10 +65,14 @@ export function isFeatureCollection(json) {
65
65
  const DEGREES_TO_RADIANS = 0.017453292519943295; // = Math.PI / 180
66
66
  const EARTH_RADIUS_KM = 6371;
67
67
  /**
68
- * Returns the distance between this and given GeoJSON point in kilometers. Doesn't take in account altitude.
68
+ * Returns the distance between two WGS84 points in kilometers. Doesn't take in account altitude.
69
69
  * Based on the following Stack Overflow question:
70
70
  * http://stackoverflow.com/questions/27928/calculate-distance-between-two-latitude-longitude-points-haversine-formula,
71
71
  * which is based on https://en.wikipedia.org/wiki/Haversine_formula (error rate: ~0.55%).
72
+ * @param fromXLon first point longitude
73
+ * @param fromYLat first point latitude
74
+ * @param toXLon second point longitude
75
+ * @param toYLat second point latitude
72
76
  */
73
77
  function distanceBetweenWGS84PointsInKm(fromXLon, fromYLat, toXLon, toYLat) {
74
78
  const diffLat = toRadians(toYLat - fromYLat);
@@ -82,9 +86,12 @@ function distanceBetweenWGS84PointsInKm(fromXLon, fromYLat, toXLon, toYLat) {
82
86
  return EARTH_RADIUS_KM * c;
83
87
  }
84
88
  /**
85
- * Calculates distance between two GeoJSON points (WGS84)
86
- * @param pos1
87
- * @param pos2
89
+ * Returns the distance between two WGS84 GeoJSON positions in kilometers. Doesn't take in account altitude.
90
+ * Based on the following Stack Overflow question:
91
+ * http://stackoverflow.com/questions/27928/calculate-distance-between-two-latitude-longitude-points-haversine-formula,
92
+ * which is based on https://en.wikipedia.org/wiki/Haversine_formula (error rate: ~0.55%).
93
+ * @param pos1 first position
94
+ * @param pos2 second position
88
95
  */
89
96
  export function distanceBetweenPositionsInKm(pos1, pos2) {
90
97
  if (pos1.length < 2 || pos1.length > 3 || pos2.length < 2 || pos2.length > 3) {
@@ -13,7 +13,7 @@ export class SlackApi {
13
13
  message: "Sending slack notification",
14
14
  });
15
15
  await ky.post(this.url, {
16
- json: { "text": text }
16
+ json: { text: text },
17
17
  });
18
18
  }
19
19
  catch (error) {
@@ -89,3 +89,8 @@ export declare function hasOwnPropertySafe(object: object, propertyName: string)
89
89
  * @param maybeError
90
90
  */
91
91
  export declare function getErrorMessage(maybeError: unknown): string;
92
+ /**
93
+ *
94
+ * @param value
95
+ */
96
+ export declare function isDefined<T>(value: T | undefined | null): value is T;
@@ -153,4 +153,11 @@ export function getErrorMessage(maybeError) {
153
153
  }
154
154
  return String(maybeError);
155
155
  }
156
+ /**
157
+ *
158
+ * @param value
159
+ */
160
+ export function isDefined(value) {
161
+ return value !== undefined && value !== null;
162
+ }
156
163
  //# sourceMappingURL=utils.mjs.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@digitraffic/common",
3
- "version": "2024.6.26-2",
3
+ "version": "2024.7.2-1",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "repository": {
@@ -138,7 +138,6 @@
138
138
  "ky": "^1.3.0",
139
139
  "lodash": "^4.17.21",
140
140
  "node-ttl": "^0.2.0",
141
- "pg-native": "^3.1.0",
142
141
  "pg-promise": "^11.8.0",
143
142
  "@jest/globals": "^29.7.0",
144
143
  "@rushstack/eslint-config": "^3.7.0",