canopycms-cdk 0.0.66-int.84 → 0.0.66-int.85
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/constructs/asset-support.d.ts +26 -0
- package/dist/constructs/asset-support.js +12 -0
- package/dist/constructs/cms-service.d.ts +33 -1
- package/dist/constructs/cms-service.js +12 -0
- package/dist/constructs/lambda-execution-role.d.ts +60 -0
- package/dist/constructs/lambda-execution-role.js +90 -0
- package/package.json +6 -6
|
@@ -96,6 +96,32 @@ export interface AssetSupportProps {
|
|
|
96
96
|
* never affected.
|
|
97
97
|
*/
|
|
98
98
|
readonly transformOutputRetention?: Duration;
|
|
99
|
+
/**
|
|
100
|
+
* Execution role for the transform Lambda (default: CDK creates one).
|
|
101
|
+
*
|
|
102
|
+
* Set this when the role's ARN has to be computable WITHOUT a reference to
|
|
103
|
+
* this construct - the case that motivated the prop is an asset bucket in a
|
|
104
|
+
* different AWS account from the compute, where the resource-policy half of
|
|
105
|
+
* the cross-account grant must be written in the bucket's own stack and needs
|
|
106
|
+
* the principal as a plain string. Reading `transformFunction.role` across an
|
|
107
|
+
* account boundary does not give you that: CDK emits `Fn::GetStackOutput`, a
|
|
108
|
+
* CDK-CLI-only intrinsic resolved at deploy time, so the coupling is
|
|
109
|
+
* invisible to CloudFormation and unusable by any deploy path that is not
|
|
110
|
+
* `cdk deploy`. Create a deterministically NAMED role instead and both stacks
|
|
111
|
+
* can compute `arn:aws:iam::<account>:role/<name>` from literals, with
|
|
112
|
+
* nothing crossing between them.
|
|
113
|
+
*
|
|
114
|
+
* A named IAM role means the consuming stack needs `CAPABILITY_NAMED_IAM`,
|
|
115
|
+
* and cannot be replaced in place without a rename - that trade is yours to
|
|
116
|
+
* make here, which is the point of taking a role rather than a name.
|
|
117
|
+
*
|
|
118
|
+
* `iam.Role`, not `iam.IRole`, ON PURPOSE - an imported role silently
|
|
119
|
+
* discards the managed policies this construct has to re-attach. See
|
|
120
|
+
* `attachLambdaExecutionPolicies` (./lambda-execution-role) for what CDK
|
|
121
|
+
* drops when a role is passed, and why the narrower type is what makes the
|
|
122
|
+
* compensation reliable.
|
|
123
|
+
*/
|
|
124
|
+
readonly transformRole?: iam.Role;
|
|
99
125
|
/**
|
|
100
126
|
* Name for the transform Lambda's CloudWatch log group (default:
|
|
101
127
|
* `/canopycms/<stackName>/transform`). Deliberately NOT
|
|
@@ -3,6 +3,7 @@ import * as path from 'node:path';
|
|
|
3
3
|
import { fileURLToPath } from 'node:url';
|
|
4
4
|
import { Construct } from 'constructs';
|
|
5
5
|
import { Duration, RemovalPolicy, Stack, aws_cloudfront as cloudfront, aws_cloudfront_origins as origins, aws_lambda as lambda, aws_logs as logs, aws_s3 as s3, } from 'aws-cdk-lib';
|
|
6
|
+
import { attachLambdaExecutionPolicies } from './lambda-execution-role.js';
|
|
6
7
|
// This package (`canopycms-cdk`) is `"type": "module"`, so its compiled
|
|
7
8
|
// output is real ESM - `__dirname` is not a global there. Derive it from
|
|
8
9
|
// `import.meta.url` instead (mirrors ../../lambda/asset-transform/build.mjs).
|
|
@@ -257,7 +258,18 @@ export class AssetSupport extends Construct {
|
|
|
257
258
|
retention: props.transformLogRetention ?? logs.RetentionDays.THREE_MONTHS,
|
|
258
259
|
removalPolicy: RemovalPolicy.DESTROY,
|
|
259
260
|
});
|
|
261
|
+
// Re-attach what CDK silently drops for a caller-supplied role. MUST run
|
|
262
|
+
// for every passed role - see that function's doc comment. This function
|
|
263
|
+
// is not VPC-attached, so it takes basic execution only; the test suite
|
|
264
|
+
// pins the absence of the VPC-ENI policy here specifically, so that this
|
|
265
|
+
// call site and the CMS Lambda's cannot be collapsed into one.
|
|
266
|
+
if (props.transformRole) {
|
|
267
|
+
attachLambdaExecutionPolicies(props.transformRole, { vpc: false });
|
|
268
|
+
}
|
|
260
269
|
this.transformFunction = new lambda.Function(this, 'TransformFunction', {
|
|
270
|
+
// Default (unset) leaves CDK to create the execution role, with its own
|
|
271
|
+
// managed policies intact. See `transformRole`'s doc comment.
|
|
272
|
+
role: props.transformRole,
|
|
261
273
|
// Built by `pnpm run build:lambda` (lambda/asset-transform/build.mjs) -
|
|
262
274
|
// esbuild bundle + a real linux/arm64 `npm install sharp` alongside it,
|
|
263
275
|
// no Docker. `cdk synth`/`deploy` need that script run first; it is
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Construct } from 'constructs';
|
|
2
|
-
import { Duration, RemovalPolicy, aws_ec2 as ec2, aws_efs as efs, aws_lambda as lambda, aws_autoscaling as autoscaling, aws_logs as logs } from 'aws-cdk-lib';
|
|
2
|
+
import { Duration, RemovalPolicy, aws_ec2 as ec2, aws_efs as efs, aws_iam as iam, aws_lambda as lambda, aws_autoscaling as autoscaling, aws_logs as logs } from 'aws-cdk-lib';
|
|
3
3
|
import type { IBucket } from 'aws-cdk-lib/aws-s3';
|
|
4
4
|
/**
|
|
5
5
|
* Default CMS Lambda timeout.
|
|
@@ -168,6 +168,38 @@ export interface CanopyCmsServiceProps {
|
|
|
168
168
|
* default name would collide).
|
|
169
169
|
*/
|
|
170
170
|
workerLogGroupName?: string;
|
|
171
|
+
/**
|
|
172
|
+
* Execution role for the CMS Lambda (default: CDK creates one).
|
|
173
|
+
*
|
|
174
|
+
* Set this when the role's ARN has to be computable WITHOUT a reference to
|
|
175
|
+
* this construct - the motivating case is an asset bucket in a different AWS
|
|
176
|
+
* account from the compute, where the resource-policy half of the
|
|
177
|
+
* cross-account grant must be written in the bucket's own stack and needs the
|
|
178
|
+
* principal as a plain string. Reading `lambdaFunction.role` across an
|
|
179
|
+
* account boundary does not give you that: CDK emits `Fn::GetStackOutput`, a
|
|
180
|
+
* CDK-CLI-only intrinsic resolved at deploy time, so the coupling is
|
|
181
|
+
* invisible to CloudFormation and unusable by any deploy path that is not
|
|
182
|
+
* `cdk deploy`. Create a deterministically NAMED role instead and both stacks
|
|
183
|
+
* can compute `arn:aws:iam::<account>:role/<name>` from literals, with
|
|
184
|
+
* nothing crossing between them.
|
|
185
|
+
*
|
|
186
|
+
* A named IAM role means the consuming stack needs `CAPABILITY_NAMED_IAM`,
|
|
187
|
+
* and cannot be replaced in place without a rename - that trade is yours to
|
|
188
|
+
* make here, which is the point of taking a role rather than a name.
|
|
189
|
+
*
|
|
190
|
+
* This Lambda is VPC-attached, which makes the compensation in
|
|
191
|
+
* `attachLambdaExecutionPolicies` (./lambda-execution-role) load-bearing
|
|
192
|
+
* rather than cosmetic: CDK discards `AWSLambdaVPCAccessExecutionRole` for a
|
|
193
|
+
* passed role, and without it the function cannot create ENIs and so cannot
|
|
194
|
+
* start - after synthesizing and deploying clean. The construct re-attaches
|
|
195
|
+
* it, which is also why this is `iam.Role` and not `iam.IRole` (an imported
|
|
196
|
+
* role would drop it again, silently). Everything else survives a passed role
|
|
197
|
+
* untouched: the EFS access-point statements, the `cmsLogGroup` write grant
|
|
198
|
+
* and the `assetBucket` grants all land on it.
|
|
199
|
+
*
|
|
200
|
+
* The EC2 worker has its own instance role and is unaffected by this prop.
|
|
201
|
+
*/
|
|
202
|
+
lambdaRole?: iam.Role;
|
|
171
203
|
/**
|
|
172
204
|
* Retention for the CMS Lambda's CloudWatch log group (default: three
|
|
173
205
|
* months / 90 days).
|
|
@@ -2,6 +2,7 @@ import * as path from 'node:path';
|
|
|
2
2
|
import { fileURLToPath } from 'node:url';
|
|
3
3
|
import { Construct } from 'constructs';
|
|
4
4
|
import { Duration, RemovalPolicy, Stack, aws_ec2 as ec2, aws_efs as efs, aws_iam as iam, aws_lambda as lambda, aws_autoscaling as autoscaling, aws_s3_assets as s3assets, aws_logs as logs, } from 'aws-cdk-lib';
|
|
5
|
+
import { attachLambdaExecutionPolicies } from './lambda-execution-role.js';
|
|
5
6
|
// This package (`canopycms-cdk`) is `"type": "module"`, so its compiled
|
|
6
7
|
// output is real ESM - `__dirname` is not a global there. Found while
|
|
7
8
|
// fixing this construct's B1 deploy blocker below: the worker asset path a
|
|
@@ -404,8 +405,19 @@ export class CanopyCmsService extends Construct {
|
|
|
404
405
|
removalPolicy: RemovalPolicy.DESTROY,
|
|
405
406
|
});
|
|
406
407
|
this.timeout = props.timeout ?? DEFAULT_CMS_LAMBDA_TIMEOUT;
|
|
408
|
+
// Re-attach what CDK silently drops for a caller-supplied role. MUST run
|
|
409
|
+
// for every passed role, and `vpc: true` here is the load-bearing part:
|
|
410
|
+
// this function is VPC-attached, so a role without
|
|
411
|
+
// AWSLambdaVPCAccessExecutionRole cannot create ENIs and the Lambda cannot
|
|
412
|
+
// start, having deployed clean. See that function's doc comment.
|
|
413
|
+
if (props.lambdaRole) {
|
|
414
|
+
attachLambdaExecutionPolicies(props.lambdaRole, { vpc: true });
|
|
415
|
+
}
|
|
407
416
|
this.lambdaFunction = new lambda.DockerImageFunction(this, 'CmsFunction', {
|
|
408
417
|
code: props.cmsDockerImage,
|
|
418
|
+
// Default (unset) leaves CDK to create the execution role, with its own
|
|
419
|
+
// managed policies intact. See `lambdaRole`'s doc comment.
|
|
420
|
+
role: props.lambdaRole,
|
|
409
421
|
memorySize: props.memorySize ?? 2048,
|
|
410
422
|
timeout: this.timeout,
|
|
411
423
|
reservedConcurrentExecutions: props.reservedConcurrency ?? 10,
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { aws_iam as iam } from 'aws-cdk-lib';
|
|
2
|
+
export interface LambdaExecutionPolicyOptions {
|
|
3
|
+
/**
|
|
4
|
+
* Whether the function this role belongs to is VPC-attached (i.e. was given
|
|
5
|
+
* a `vpc` prop). Mirrors the `props.vpc &&` condition in the CDK snippet
|
|
6
|
+
* above rather than being decided here, so the two cannot drift.
|
|
7
|
+
*
|
|
8
|
+
* Required rather than defaulted: getting it wrong on a VPC function
|
|
9
|
+
* produces a Lambda that cannot start, and a default would let a new call
|
|
10
|
+
* site inherit the wrong answer by saying nothing.
|
|
11
|
+
*/
|
|
12
|
+
readonly vpc: boolean;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Re-attach what CDK drops when a `lambda.Function` is handed a pre-built
|
|
16
|
+
* execution role. Call this for every caller-supplied role, alongside passing
|
|
17
|
+
* that role to the function.
|
|
18
|
+
*
|
|
19
|
+
* The contract this maintains is deliberately the strong one: **passing a role
|
|
20
|
+
* yields the same effective permissions as letting the construct create one.**
|
|
21
|
+
* The weaker alternative - attach only what each function demonstrably still
|
|
22
|
+
* needs - is a judgment call that goes stale silently. Concretely, neither
|
|
23
|
+
* Lambda in this package strictly needs `AWSLambdaBasicExecutionRole` today:
|
|
24
|
+
* both log to a custom-named group (`/canopycms/<stackName>/...`), that
|
|
25
|
+
* policy's `logs:CreateLogStream`/`logs:PutLogEvents` are scoped to
|
|
26
|
+
* `arn:aws:logs:*:*:log-group:/aws/lambda/*:*` and so grant nothing for such a
|
|
27
|
+
* group, and an explicit `logGroup.grantWrite()` is what actually enables
|
|
28
|
+
* their logging. Attaching it regardless costs one managed-policy ARN and
|
|
29
|
+
* means the first change to either function's logging cannot quietly leave
|
|
30
|
+
* passed-role deployments behind.
|
|
31
|
+
*
|
|
32
|
+
* WHY THE PARAMETER IS THE CONCRETE `iam.Role` AND NOT `iam.IRole`, which is
|
|
33
|
+
* the type a CDK prop would normally take: `addManagedPolicy` does nothing
|
|
34
|
+
* useful on an imported role, in two distinct ways, neither of which surfaces
|
|
35
|
+
* an error.
|
|
36
|
+
*
|
|
37
|
+
* - `ImmutableRole.addManagedPolicy(_policy) {}` - an empty method body. This
|
|
38
|
+
* is what `Role.fromRoleArn` returns for a CROSS-ACCOUNT role, or for any
|
|
39
|
+
* role imported with `mutable: false`.
|
|
40
|
+
* - `ImportedRole.addManagedPolicy` (the same-account, still-mutable case)
|
|
41
|
+
* attaches the policy only if it exposes `attachToRole`, which
|
|
42
|
+
* `ManagedPolicy.fromAwsManagedPolicyName` does not - so it takes the
|
|
43
|
+
* warning branch and emits nothing.
|
|
44
|
+
*
|
|
45
|
+
* Both confirmed on a synthesized template: no `AWS::IAM::Role` and no
|
|
46
|
+
* `AWS::IAM::Policy` resource appears in either case. So typed `IRole`, this
|
|
47
|
+
* function would silently no-op for every imported role and ship exactly the
|
|
48
|
+
* cannot-start Lambda it exists to prevent. There is no runtime guard
|
|
49
|
+
* available either - `ImmutableRole.addToPrincipalPolicy` returns
|
|
50
|
+
* `statementAdded: true` while emitting nothing, so the one signal CDK offers
|
|
51
|
+
* lies. Narrowing the type moves the failure to COMPILE time instead, which is
|
|
52
|
+
* the earliest it can be caught; `attachTo(distribution:
|
|
53
|
+
* cloudfront.Distribution)` in asset-support.ts narrows to a concrete class for
|
|
54
|
+
* the same kind of reason.
|
|
55
|
+
*
|
|
56
|
+
* Residual, documented rather than guarded because of its rarity: a role
|
|
57
|
+
* produced under `Role.customizeRoles` carries a precreated `ImportedRole` that
|
|
58
|
+
* `addManagedPolicy` delegates to, landing on the warning branch above.
|
|
59
|
+
*/
|
|
60
|
+
export declare function attachLambdaExecutionPolicies(role: iam.Role, options: LambdaExecutionPolicyOptions): void;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { aws_iam as iam } from 'aws-cdk-lib';
|
|
2
|
+
/**
|
|
3
|
+
* The two AWS managed policies CDK's `lambda.Function` attaches to an
|
|
4
|
+
* execution role IT creates, and silently DISCARDS when one is passed in.
|
|
5
|
+
*
|
|
6
|
+
* Verbatim from `aws-cdk-lib/aws-lambda/lib/function.js` (checked against
|
|
7
|
+
* 2.265.0 here, and independently against 2.267.0 by the adopter who filed
|
|
8
|
+
* this):
|
|
9
|
+
*
|
|
10
|
+
* ```js
|
|
11
|
+
* managedPolicies.push(ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSLambdaBasicExecutionRole'))
|
|
12
|
+
* props.vpc && managedPolicies.push(ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSLambdaVPCAccessExecutionRole'))
|
|
13
|
+
* this.role = props.role || new iam.Role(this, 'ServiceRole', { assumedBy: ..., managedPolicies })
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
* The array is built unconditionally and then reaches ONLY the `||` fallback.
|
|
17
|
+
* Pass a role and both entries are dropped with nothing logged. Confirmed on a
|
|
18
|
+
* synthesized template, not inferred: a VPC-attached function given a bare role
|
|
19
|
+
* emits an `AWS::IAM::Role` whose `ManagedPolicyArns` is absent entirely.
|
|
20
|
+
*
|
|
21
|
+
* For the VPC-attached CMS Lambda that is not a degradation, it is fatal and
|
|
22
|
+
* invisible: without `AWSLambdaVPCAccessExecutionRole` the function cannot
|
|
23
|
+
* create ENIs, so it cannot start at all - while synthesizing and deploying
|
|
24
|
+
* perfectly clean and failing only at invoke, a long way from the cause. Which
|
|
25
|
+
* is why every `role` prop in this package routes through here.
|
|
26
|
+
*
|
|
27
|
+
* NOT affected by passing a role, so deliberately not re-applied below (all
|
|
28
|
+
* three verified in the same CDK source):
|
|
29
|
+
*
|
|
30
|
+
* - EFS access-point statements - `config.policies.forEach(p => this.role?.addToPrincipalPolicy(p))`.
|
|
31
|
+
* - `initialPolicy` - `this.role.addToPrincipalPolicy(statement)` per statement.
|
|
32
|
+
* - Every `grant*` call, because `this.grantPrincipal = this.role`. That covers
|
|
33
|
+
* `cmsLogGroup`/`transformLogGroup`'s `grantWrite` and all asset-bucket
|
|
34
|
+
* grants, which land on the passed role exactly as they would on a created
|
|
35
|
+
* one.
|
|
36
|
+
*/
|
|
37
|
+
const BASIC_EXECUTION_POLICY = 'service-role/AWSLambdaBasicExecutionRole';
|
|
38
|
+
const VPC_ACCESS_POLICY = 'service-role/AWSLambdaVPCAccessExecutionRole';
|
|
39
|
+
/**
|
|
40
|
+
* Re-attach what CDK drops when a `lambda.Function` is handed a pre-built
|
|
41
|
+
* execution role. Call this for every caller-supplied role, alongside passing
|
|
42
|
+
* that role to the function.
|
|
43
|
+
*
|
|
44
|
+
* The contract this maintains is deliberately the strong one: **passing a role
|
|
45
|
+
* yields the same effective permissions as letting the construct create one.**
|
|
46
|
+
* The weaker alternative - attach only what each function demonstrably still
|
|
47
|
+
* needs - is a judgment call that goes stale silently. Concretely, neither
|
|
48
|
+
* Lambda in this package strictly needs `AWSLambdaBasicExecutionRole` today:
|
|
49
|
+
* both log to a custom-named group (`/canopycms/<stackName>/...`), that
|
|
50
|
+
* policy's `logs:CreateLogStream`/`logs:PutLogEvents` are scoped to
|
|
51
|
+
* `arn:aws:logs:*:*:log-group:/aws/lambda/*:*` and so grant nothing for such a
|
|
52
|
+
* group, and an explicit `logGroup.grantWrite()` is what actually enables
|
|
53
|
+
* their logging. Attaching it regardless costs one managed-policy ARN and
|
|
54
|
+
* means the first change to either function's logging cannot quietly leave
|
|
55
|
+
* passed-role deployments behind.
|
|
56
|
+
*
|
|
57
|
+
* WHY THE PARAMETER IS THE CONCRETE `iam.Role` AND NOT `iam.IRole`, which is
|
|
58
|
+
* the type a CDK prop would normally take: `addManagedPolicy` does nothing
|
|
59
|
+
* useful on an imported role, in two distinct ways, neither of which surfaces
|
|
60
|
+
* an error.
|
|
61
|
+
*
|
|
62
|
+
* - `ImmutableRole.addManagedPolicy(_policy) {}` - an empty method body. This
|
|
63
|
+
* is what `Role.fromRoleArn` returns for a CROSS-ACCOUNT role, or for any
|
|
64
|
+
* role imported with `mutable: false`.
|
|
65
|
+
* - `ImportedRole.addManagedPolicy` (the same-account, still-mutable case)
|
|
66
|
+
* attaches the policy only if it exposes `attachToRole`, which
|
|
67
|
+
* `ManagedPolicy.fromAwsManagedPolicyName` does not - so it takes the
|
|
68
|
+
* warning branch and emits nothing.
|
|
69
|
+
*
|
|
70
|
+
* Both confirmed on a synthesized template: no `AWS::IAM::Role` and no
|
|
71
|
+
* `AWS::IAM::Policy` resource appears in either case. So typed `IRole`, this
|
|
72
|
+
* function would silently no-op for every imported role and ship exactly the
|
|
73
|
+
* cannot-start Lambda it exists to prevent. There is no runtime guard
|
|
74
|
+
* available either - `ImmutableRole.addToPrincipalPolicy` returns
|
|
75
|
+
* `statementAdded: true` while emitting nothing, so the one signal CDK offers
|
|
76
|
+
* lies. Narrowing the type moves the failure to COMPILE time instead, which is
|
|
77
|
+
* the earliest it can be caught; `attachTo(distribution:
|
|
78
|
+
* cloudfront.Distribution)` in asset-support.ts narrows to a concrete class for
|
|
79
|
+
* the same kind of reason.
|
|
80
|
+
*
|
|
81
|
+
* Residual, documented rather than guarded because of its rarity: a role
|
|
82
|
+
* produced under `Role.customizeRoles` carries a precreated `ImportedRole` that
|
|
83
|
+
* `addManagedPolicy` delegates to, landing on the warning branch above.
|
|
84
|
+
*/
|
|
85
|
+
export function attachLambdaExecutionPolicies(role, options) {
|
|
86
|
+
role.addManagedPolicy(iam.ManagedPolicy.fromAwsManagedPolicyName(BASIC_EXECUTION_POLICY));
|
|
87
|
+
if (options.vpc) {
|
|
88
|
+
role.addManagedPolicy(iam.ManagedPolicy.fromAwsManagedPolicyName(VPC_ACCESS_POLICY));
|
|
89
|
+
}
|
|
90
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "canopycms-cdk",
|
|
3
|
-
"version": "0.0.66-int.
|
|
3
|
+
"version": "0.0.66-int.85",
|
|
4
4
|
"description": "AWS CDK constructs and EC2 worker for CanopyCMS deployment",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"peerDependencies": {
|
|
31
31
|
"aws-cdk-lib": "^2.260.0",
|
|
32
32
|
"constructs": "^10.0.0",
|
|
33
|
-
"canopycms": "0.0.66-int.
|
|
33
|
+
"canopycms": "0.0.66-int.85"
|
|
34
34
|
},
|
|
35
35
|
"peerDependenciesMeta": {
|
|
36
36
|
"aws-cdk-lib": {
|
|
@@ -54,16 +54,16 @@
|
|
|
54
54
|
"tsx": "^4.19.0",
|
|
55
55
|
"typescript": "^5.6.3",
|
|
56
56
|
"vitest": "^4.1.0",
|
|
57
|
-
"canopycms": "0.0.66-int.
|
|
58
|
-
"canopycms
|
|
57
|
+
"canopycms-auth-clerk": "0.0.66-int.85",
|
|
58
|
+
"canopycms": "0.0.66-int.85"
|
|
59
59
|
},
|
|
60
60
|
"scripts": {
|
|
61
61
|
"build": "rm -rf dist && tsc && node ../../scripts/add-js-extensions.mjs dist",
|
|
62
62
|
"build:worker": "esbuild worker/index.ts --bundle --platform=node --target=node20 --format=esm --outfile=worker/dist/index.js --banner:js=\"import { createRequire } from 'module'; const require = createRequire(import.meta.url);\"",
|
|
63
63
|
"build:lambda": "node lambda/asset-transform/build.mjs",
|
|
64
64
|
"build:test-fixtures": "pnpm run build:worker && node lambda/asset-transform/build.mjs --skip-native",
|
|
65
|
-
"lint": "eslint src/ 'lambda/**/*.ts' 'canary/**/*.ts' 'worker/**/*.ts'",
|
|
65
|
+
"lint": "eslint src/ 'lambda/**/*.ts' 'canary/**/*.ts' 'worker/**/*.ts' 'test-support/**/*.ts'",
|
|
66
66
|
"test": "pnpm run build:test-fixtures && vitest run",
|
|
67
|
-
"typecheck": "tsc --noEmit && tsc --noEmit -p lambda/tsconfig.json && tsc --noEmit -p canary/tsconfig.json && tsc --noEmit -p worker/tsconfig.json"
|
|
67
|
+
"typecheck": "tsc --noEmit && tsc --noEmit -p lambda/tsconfig.json && tsc --noEmit -p canary/tsconfig.json && tsc --noEmit -p worker/tsconfig.json && tsc --noEmit -p test-support/tsconfig.json"
|
|
68
68
|
}
|
|
69
69
|
}
|