@digitraffic/common 2026.4.17-3 → 2026.4.20-2
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/aws/infra/canaries/canary-role.d.ts +5 -0
- package/dist/aws/infra/canaries/canary-role.js +11 -0
- package/dist/aws/infra/canaries/url-canary.js +4 -0
- package/dist/aws/infra/stack/dt-function.d.ts +5 -8
- package/dist/aws/infra/stack/dt-function.js +1 -12
- package/dist/aws/infra/stack/lambda-configs.d.ts +0 -1
- package/dist/aws/infra/stack/lambda-configs.js +3 -6
- package/dist/aws/infra/stack/lambda-log-group.d.ts +2 -2
- package/dist/aws/infra/stack/rest-api.d.ts +3 -2
- package/dist/aws/infra/stack/stack.d.ts +12 -1
- package/dist/aws/infra/stacks/network-stack.d.ts +2 -0
- package/dist/aws/infra/stacks/network-stack.js +16 -2
- package/dist/aws/runtime/dt-logger.js +2 -3
- package/dist/index.d.ts +1 -0
- package/package.json +1 -4
|
@@ -11,4 +11,9 @@ export declare class DigitrafficCanaryRole extends Role {
|
|
|
11
11
|
* A UrlCanary needs these permissions to e.g. access a private API Gateway endpoint in a VPC.
|
|
12
12
|
*/
|
|
13
13
|
withVpcAccess(): this;
|
|
14
|
+
/**
|
|
15
|
+
* Provides permissions to read API keys from API Gateway.
|
|
16
|
+
* Required for URL canaries that validate API-key-protected endpoints.
|
|
17
|
+
*/
|
|
18
|
+
withApiGatewayAccess(): this;
|
|
14
19
|
}
|
|
@@ -47,5 +47,16 @@ export class DigitrafficCanaryRole extends Role {
|
|
|
47
47
|
this.addManagedPolicy(ManagedPolicy.fromAwsManagedPolicyName("service-role/AWSLambdaVPCAccessExecutionRole"));
|
|
48
48
|
return this;
|
|
49
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* Provides permissions to read API keys from API Gateway.
|
|
52
|
+
* Required for URL canaries that validate API-key-protected endpoints.
|
|
53
|
+
*/
|
|
54
|
+
withApiGatewayAccess() {
|
|
55
|
+
this.addToPolicy(new PolicyStatement({
|
|
56
|
+
actions: ["apigateway:GET"],
|
|
57
|
+
resources: ["arn:aws:apigateway:*::/apikeys/*"],
|
|
58
|
+
}));
|
|
59
|
+
return this;
|
|
60
|
+
}
|
|
50
61
|
}
|
|
51
62
|
//# sourceMappingURL=canary-role.js.map
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { CfnCanary } from "aws-cdk-lib/aws-synthetics";
|
|
2
2
|
import { DigitrafficCanary } from "./canary.js";
|
|
3
3
|
import { ENV_API_KEY, ENV_HOSTNAME, ENV_SECRET } from "./canary-keys.js";
|
|
4
|
+
import { DigitrafficCanaryRole } from "./canary-role.js";
|
|
4
5
|
export class UrlCanary extends DigitrafficCanary {
|
|
5
6
|
constructor(stack, role, params, secret) {
|
|
6
7
|
const canaryName = `${params.name}-url`;
|
|
@@ -32,6 +33,9 @@ export class UrlCanary extends DigitrafficCanary {
|
|
|
32
33
|
}
|
|
33
34
|
}
|
|
34
35
|
static create(stack, role, publicApi, params, secret) {
|
|
36
|
+
if (role instanceof DigitrafficCanaryRole) {
|
|
37
|
+
role.withApiGatewayAccess();
|
|
38
|
+
}
|
|
35
39
|
return new UrlCanary(stack, role, {
|
|
36
40
|
handler: `${params.name ?? undefined}.handler`,
|
|
37
41
|
hostname: publicApi.hostname(),
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Stack } from "aws-cdk-lib";
|
|
1
2
|
import { Duration } from "aws-cdk-lib";
|
|
2
3
|
import type { ISecurityGroup } from "aws-cdk-lib/aws-ec2";
|
|
3
4
|
import type { IRole } from "aws-cdk-lib/aws-iam";
|
|
@@ -6,7 +7,7 @@ import type { ILayerVersion } from "aws-cdk-lib/aws-lambda";
|
|
|
6
7
|
import { Architecture, Function as AwsFunction, Code, Runtime } from "aws-cdk-lib/aws-lambda";
|
|
7
8
|
import { DtFunctionAlarms } from "./dt-function-alarms.js";
|
|
8
9
|
import type { LambdaEnvironment } from "./lambda-configs.js";
|
|
9
|
-
import type {
|
|
10
|
+
import type { DigitrafficStackInterface } from "./stack.js";
|
|
10
11
|
export declare class FunctionBuilder {
|
|
11
12
|
private readonly _stack;
|
|
12
13
|
private readonly _name;
|
|
@@ -28,20 +29,16 @@ export declare class FunctionBuilder {
|
|
|
28
29
|
private readonly policyStatements;
|
|
29
30
|
private readonly allowedActions;
|
|
30
31
|
private readonly _features;
|
|
31
|
-
constructor(stack:
|
|
32
|
+
constructor(stack: Stack & DigitrafficStackInterface, lambdaName: string);
|
|
32
33
|
/**
|
|
33
34
|
* Creates a new builder with defaults, using the lambdaName as a source for the lambda implementation (dist/lambdaName/lambdaName.js).
|
|
34
35
|
* Database access is given by default.
|
|
35
36
|
*/
|
|
36
|
-
static create(stack:
|
|
37
|
+
static create(stack: Stack & DigitrafficStackInterface, lambdaName: string): FunctionBuilder;
|
|
37
38
|
/**
|
|
38
39
|
* Creates a new builder with defaults, but without database or secret access.
|
|
39
40
|
*/
|
|
40
|
-
static plain(stack:
|
|
41
|
-
/**
|
|
42
|
-
* Stack only has one lambda. Default is that it has multiple lambdas.
|
|
43
|
-
*/
|
|
44
|
-
singleLambda(): this;
|
|
41
|
+
static plain(stack: Stack & DigitrafficStackInterface, lambdaName: string): FunctionBuilder;
|
|
45
42
|
/**
|
|
46
43
|
* Use AssetCode from given path(dist/lambda/${path}). Default path is lambdaName. Also calls withHandler with the same value.
|
|
47
44
|
*/
|
|
@@ -30,7 +30,6 @@ export class FunctionBuilder {
|
|
|
30
30
|
policyStatements = [];
|
|
31
31
|
allowedActions = [];
|
|
32
32
|
_features = {
|
|
33
|
-
singleLambda: false,
|
|
34
33
|
databaseAccess: true,
|
|
35
34
|
secretAccess: true,
|
|
36
35
|
};
|
|
@@ -63,21 +62,11 @@ export class FunctionBuilder {
|
|
|
63
62
|
.withoutDatabaseAccess()
|
|
64
63
|
.withoutSecretAccess();
|
|
65
64
|
}
|
|
66
|
-
/**
|
|
67
|
-
* Stack only has one lambda. Default is that it has multiple lambdas.
|
|
68
|
-
*/
|
|
69
|
-
singleLambda() {
|
|
70
|
-
this._features.singleLambda = true;
|
|
71
|
-
return this;
|
|
72
|
-
}
|
|
73
65
|
/**
|
|
74
66
|
* Use AssetCode from given path(dist/lambda/${path}). Default path is lambdaName. Also calls withHandler with the same value.
|
|
75
67
|
*/
|
|
76
68
|
withAssetCode(path = this._name) {
|
|
77
|
-
|
|
78
|
-
? `dist/lambda/`
|
|
79
|
-
: `dist/lambda/${path}`;
|
|
80
|
-
this.code = new AssetCode(lambdaPath);
|
|
69
|
+
this.code = new AssetCode(`dist/lambda/${path}`);
|
|
81
70
|
this.withHandler(path);
|
|
82
71
|
return this;
|
|
83
72
|
}
|
|
@@ -34,7 +34,6 @@ export interface FunctionParameters {
|
|
|
34
34
|
vpcSubnets?: SubnetSelection;
|
|
35
35
|
runtime?: Runtime;
|
|
36
36
|
architecture?: Architecture;
|
|
37
|
-
singleLambda?: boolean;
|
|
38
37
|
}
|
|
39
38
|
export type MonitoredFunctionParameters = FunctionParameters & {
|
|
40
39
|
readonly durationAlarmProps?: MonitoredFunctionAlarmProps;
|
|
@@ -31,16 +31,13 @@ export function lambdaFunctionProps(_, environment, lambdaName, simpleLambdaName
|
|
|
31
31
|
timeout: Duration.seconds(config?.timeout ?? 60),
|
|
32
32
|
logGroup: logGroup,
|
|
33
33
|
reservedConcurrentExecutions: config?.reservedConcurrentExecutions ?? 2,
|
|
34
|
-
code: getAssetCode(simpleLambdaName
|
|
34
|
+
code: getAssetCode(simpleLambdaName),
|
|
35
35
|
handler: `${simpleLambdaName}.handler`,
|
|
36
36
|
environment,
|
|
37
37
|
};
|
|
38
38
|
}
|
|
39
|
-
function getAssetCode(simpleLambdaName
|
|
40
|
-
|
|
41
|
-
? `dist/lambda/`
|
|
42
|
-
: `dist/lambda/${simpleLambdaName}`;
|
|
43
|
-
return new AssetCode(lambdaPath);
|
|
39
|
+
function getAssetCode(simpleLambdaName) {
|
|
40
|
+
return new AssetCode(`dist/lambda/${simpleLambdaName}`);
|
|
44
41
|
}
|
|
45
42
|
export function defaultLambdaConfiguration(config) {
|
|
46
43
|
const props = {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Stack } from "aws-cdk-lib";
|
|
2
2
|
import { LogGroup, RetentionDays } from "aws-cdk-lib/aws-logs";
|
|
3
|
-
import type {
|
|
3
|
+
import type { DigitrafficStackInterface } from "./stack.js";
|
|
4
4
|
export interface CreateLambdaLogGroupParams {
|
|
5
5
|
functionName: string;
|
|
6
6
|
retention?: RetentionDays;
|
|
@@ -10,6 +10,6 @@ export interface CreateLambdaLogGroupParamsForStack extends CreateLambdaLogGroup
|
|
|
10
10
|
shortName: string;
|
|
11
11
|
}
|
|
12
12
|
export interface CreateLambdaLogGroupParamsForDigitrafficStack extends CreateLambdaLogGroupParams {
|
|
13
|
-
stack:
|
|
13
|
+
stack: Stack & DigitrafficStackInterface;
|
|
14
14
|
}
|
|
15
15
|
export declare function createLambdaLogGroup(params: CreateLambdaLogGroupParamsForStack | CreateLambdaLogGroupParamsForDigitrafficStack): LogGroup;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Stack } from "aws-cdk-lib";
|
|
1
2
|
import type { IResource, JsonSchema, Resource, ResourceOptions, RestApiProps } from "aws-cdk-lib/aws-apigateway";
|
|
2
3
|
import { RestApi } from "aws-cdk-lib/aws-apigateway";
|
|
3
4
|
import { PolicyDocument } from "aws-cdk-lib/aws-iam";
|
|
@@ -5,7 +6,7 @@ import { StringParameter } from "aws-cdk-lib/aws-ssm";
|
|
|
5
6
|
import type { Construct } from "constructs";
|
|
6
7
|
import type { ModelWithReference } from "../../types/model-with-reference.js";
|
|
7
8
|
import type { DocumentationPart } from "../documentation.js";
|
|
8
|
-
import type {
|
|
9
|
+
import type { DigitrafficStackInterface } from "./stack.js";
|
|
9
10
|
export declare const PUBLIC_REST_API_CORS_CONFIG: {
|
|
10
11
|
readonly defaultCorsPreflightOptions: {
|
|
11
12
|
readonly allowOrigins: string[];
|
|
@@ -23,7 +24,7 @@ export declare class DigitrafficRestApi extends RestApi {
|
|
|
23
24
|
readonly apiKeyIds: string[];
|
|
24
25
|
readonly enableDocumentation: boolean;
|
|
25
26
|
private readonly _stack;
|
|
26
|
-
constructor(stack:
|
|
27
|
+
constructor(stack: Stack & DigitrafficStackInterface, apiId: string, apiName: string, allowFromIpAddresses?: string[] | undefined, config?: Partial<RestApiProps>);
|
|
27
28
|
hostname(): string;
|
|
28
29
|
/** Export end point and api key to Parameter store */
|
|
29
30
|
exportEndpoint(): [StringParameter, StringParameter];
|
|
@@ -29,7 +29,18 @@ export interface StackConfiguration {
|
|
|
29
29
|
};
|
|
30
30
|
readonly whitelistedResources?: string[];
|
|
31
31
|
}
|
|
32
|
-
export
|
|
32
|
+
export interface DigitrafficStackInterface {
|
|
33
|
+
readonly configuration: StackConfiguration;
|
|
34
|
+
readonly vpc?: IVpc;
|
|
35
|
+
readonly lambdaDbSg?: ISecurityGroup;
|
|
36
|
+
readonly alarmTopic: ITopic;
|
|
37
|
+
readonly warningTopic: ITopic;
|
|
38
|
+
createLambdaEnvironment(): DBLambdaEnvironment;
|
|
39
|
+
createDefaultLambdaEnvironment(dbApplication: string): DBLambdaEnvironment;
|
|
40
|
+
getSecret(): ISecret;
|
|
41
|
+
grantSecret(...lambdas: AWSFunction[]): void;
|
|
42
|
+
}
|
|
43
|
+
export declare class DigitrafficStack extends Stack implements DigitrafficStackInterface {
|
|
33
44
|
readonly vpc?: IVpc;
|
|
34
45
|
readonly lambdaDbSg?: ISecurityGroup;
|
|
35
46
|
readonly alarmTopic: ITopic;
|
|
@@ -6,7 +6,9 @@ import type { InfraStackConfiguration } from "./intra-stack-configuration.js";
|
|
|
6
6
|
export interface NetworkConfiguration {
|
|
7
7
|
readonly vpcName: string;
|
|
8
8
|
readonly cidr: string;
|
|
9
|
+
readonly transitGatewayId?: string;
|
|
9
10
|
}
|
|
11
|
+
/** Creates a network stack with VPC and optional transit gateway routing */
|
|
10
12
|
export declare class NetworkStack extends Stack {
|
|
11
13
|
readonly vpc: IVpc;
|
|
12
14
|
constructor(scope: Construct, id: string, isc: InfraStackConfiguration, configuration: NetworkConfiguration);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { IpAddresses, SubnetType, Vpc } from "aws-cdk-lib/aws-ec2";
|
|
1
|
+
import { CfnRoute, IpAddresses, SubnetType, Vpc } from "aws-cdk-lib/aws-ec2";
|
|
2
2
|
import { Stack } from "aws-cdk-lib/core";
|
|
3
3
|
import { exportValue } from "../import-util.js";
|
|
4
|
+
/** Creates a network stack with VPC and optional transit gateway routing */
|
|
4
5
|
export class NetworkStack extends Stack {
|
|
5
6
|
vpc;
|
|
6
7
|
constructor(scope, id, isc, configuration) {
|
|
@@ -21,11 +22,13 @@ export class NetworkStack extends Stack {
|
|
|
21
22
|
exportValue(this, isc.environmentName, "digitrafficprivateBSubnet", this.vpc.privateSubnets[1].subnetId);
|
|
22
23
|
}
|
|
23
24
|
createVpc(configuration) {
|
|
24
|
-
|
|
25
|
+
const vpc = new Vpc(this, "DigitrafficVPC", {
|
|
25
26
|
vpcName: configuration.vpcName,
|
|
27
|
+
restrictDefaultSecurityGroup: false,
|
|
26
28
|
availabilityZones: Stack.of(this).availabilityZones.sort().slice(0, 2), // take two first azs
|
|
27
29
|
enableDnsHostnames: true,
|
|
28
30
|
enableDnsSupport: true,
|
|
31
|
+
natGateways: configuration.transitGatewayId ? 0 : 2, // one for each AZ, or none if using transit gateway
|
|
29
32
|
ipAddresses: IpAddresses.cidr(configuration.cidr),
|
|
30
33
|
subnetConfiguration: [
|
|
31
34
|
{
|
|
@@ -40,6 +43,17 @@ export class NetworkStack extends Stack {
|
|
|
40
43
|
},
|
|
41
44
|
],
|
|
42
45
|
});
|
|
46
|
+
// route traffic to transit gateway
|
|
47
|
+
if (configuration.transitGatewayId) {
|
|
48
|
+
vpc.selectSubnets(undefined).subnets.forEach((subnet) => {
|
|
49
|
+
new CfnRoute(this, `SubnetRouteToTgw${subnet.node.id}`, {
|
|
50
|
+
routeTableId: subnet.routeTable.routeTableId,
|
|
51
|
+
destinationCidrBlock: "0.0.0.0/0",
|
|
52
|
+
transitGatewayId: configuration.transitGatewayId,
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
return vpc;
|
|
43
57
|
}
|
|
44
58
|
}
|
|
45
59
|
//# sourceMappingURL=network-stack.js.map
|
|
@@ -88,9 +88,8 @@ export class DtLogger {
|
|
|
88
88
|
*/
|
|
89
89
|
log(message) {
|
|
90
90
|
// Append always method to message
|
|
91
|
-
if (!message.message ||
|
|
92
|
-
!message.message.
|
|
93
|
-
!message.message.includes(message.method)) {
|
|
91
|
+
if (!message.message?.length ||
|
|
92
|
+
!message.message?.includes(message.method)) {
|
|
94
93
|
message.message = `${message.method} ${message.message ?? ""}`;
|
|
95
94
|
}
|
|
96
95
|
const error = message.error
|
package/dist/index.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@digitraffic/common",
|
|
3
|
-
"version": "2026.4.
|
|
3
|
+
"version": "2026.4.20-2",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "",
|
|
6
6
|
"repository": {
|
|
@@ -124,7 +124,6 @@
|
|
|
124
124
|
"@types/etag": "1.8.4",
|
|
125
125
|
"@types/geojson": "7946.0.16",
|
|
126
126
|
"@types/geojson-validation": "1.0.3",
|
|
127
|
-
"@types/lodash-es": "4.17.12",
|
|
128
127
|
"@types/madge": "5.0.3",
|
|
129
128
|
"@types/node": "24.12.2",
|
|
130
129
|
"@vitest/coverage-v8": "4.1.4",
|
|
@@ -137,7 +136,6 @@
|
|
|
137
136
|
"geojson-validation": "1.0.2",
|
|
138
137
|
"ky": "1.14.3",
|
|
139
138
|
"lefthook": "2.1.5",
|
|
140
|
-
"lodash-es": "4.18.1",
|
|
141
139
|
"madge": "8.0.0",
|
|
142
140
|
"pg-native": "3.7.0",
|
|
143
141
|
"pg-promise": "12.6.2",
|
|
@@ -165,7 +163,6 @@
|
|
|
165
163
|
"es-toolkit": "1.45.1",
|
|
166
164
|
"geojson-validation": "1.0.2",
|
|
167
165
|
"ky": "1.14.3",
|
|
168
|
-
"lodash-es": "4.18.1",
|
|
169
166
|
"pg-native": "3.7.0",
|
|
170
167
|
"pg-promise": "12.6.2",
|
|
171
168
|
"zod": "4.3.6"
|