canopycms-cdk 0.0.57 → 0.0.58
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 +137 -0
- package/dist/constructs/asset-support.d.ts.map +1 -0
- package/dist/constructs/asset-support.js +205 -0
- package/dist/constructs/asset-support.js.map +1 -0
- package/dist/constructs/cms-service.d.ts +10 -0
- package/dist/constructs/cms-service.d.ts.map +1 -1
- package/dist/constructs/cms-service.js +60 -0
- package/dist/constructs/cms-service.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/package.json +13 -7
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { Construct } from 'constructs';
|
|
2
|
+
import { RemovalPolicy, aws_cloudfront as cloudfront, aws_iam as iam, aws_lambda as lambda, aws_s3 as s3 } from 'aws-cdk-lib';
|
|
3
|
+
export interface AssetSupportProps {
|
|
4
|
+
/**
|
|
5
|
+
* Use an existing bucket (BYO mode - e.g. a site's existing content
|
|
6
|
+
* bucket) instead of creating one. The caller owns that bucket's
|
|
7
|
+
* lifecycle rules and CORS configuration in this mode: `IBucket` (an
|
|
8
|
+
* imported bucket reference) has no CDK-level `addLifecycleRule`/
|
|
9
|
+
* `addCorsRule` - only a bucket this construct creates itself does. See
|
|
10
|
+
* `.claude/future-tasks/docs-site-assets-wiring.md` for the BYO-mode
|
|
11
|
+
* wiring this is designed for.
|
|
12
|
+
*
|
|
13
|
+
* @default - a new private bucket is created (standalone mode)
|
|
14
|
+
*/
|
|
15
|
+
readonly bucket?: s3.IBucket;
|
|
16
|
+
/**
|
|
17
|
+
* Origins allowed to presigned-POST/PUT/GET upload directly to the bucket
|
|
18
|
+
* (the editor's own origin(s) - e.g. `http://localhost:3000` in dev, or
|
|
19
|
+
* the deployed editor's domain). Only applied in standalone mode (see
|
|
20
|
+
* `bucket`).
|
|
21
|
+
*/
|
|
22
|
+
readonly editorOrigins: string[];
|
|
23
|
+
/**
|
|
24
|
+
* Advisory upload-size cap in bytes. Not enforced by this construct -
|
|
25
|
+
* the actual cap comes from the presigned POST's `content-length-range`
|
|
26
|
+
* condition, set by `S3AssetStoreOptions.maxUploadBytes` at runtime
|
|
27
|
+
* (packages/canopycms/src/assets/store-s3.ts). Exposed here only so the
|
|
28
|
+
* consuming stack can wire the SAME number into the CMS Lambda's
|
|
29
|
+
* environment (e.g. as `MEDIA_MAX_UPLOAD_BYTES`) and keep infra and app
|
|
30
|
+
* config from silently drifting apart.
|
|
31
|
+
*
|
|
32
|
+
* @default 52428800 (50 MiB)
|
|
33
|
+
*/
|
|
34
|
+
readonly maxUploadBytes?: number;
|
|
35
|
+
/**
|
|
36
|
+
* Enable S3 versioning on the created bucket. Standalone mode only.
|
|
37
|
+
*
|
|
38
|
+
* @default false
|
|
39
|
+
*/
|
|
40
|
+
readonly versioned?: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Removal policy for the created bucket. Standalone mode only.
|
|
43
|
+
*
|
|
44
|
+
* @default RemovalPolicy.RETAIN
|
|
45
|
+
*/
|
|
46
|
+
readonly removalPolicy?: RemovalPolicy;
|
|
47
|
+
/**
|
|
48
|
+
* Auto-delete objects when the created bucket is destroyed. Only takes
|
|
49
|
+
* effect alongside `removalPolicy: RemovalPolicy.DESTROY` - useful for
|
|
50
|
+
* ephemeral canary/test stacks. Standalone mode only.
|
|
51
|
+
*
|
|
52
|
+
* @default false
|
|
53
|
+
*/
|
|
54
|
+
readonly autoDeleteObjects?: boolean;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* The two CloudFront behavior configs the asset system needs, keyed by the
|
|
58
|
+
* path pattern they belong under. Each value is a full `BehaviorOptions`
|
|
59
|
+
* (origin included), so a consumer can use it either way:
|
|
60
|
+
*
|
|
61
|
+
* ```ts
|
|
62
|
+
* const behaviors = assetSupport.assetBehaviors()
|
|
63
|
+
*
|
|
64
|
+
* // Building a new distribution:
|
|
65
|
+
* new cloudfront.Distribution(this, 'Dist', {
|
|
66
|
+
* defaultBehavior: ...,
|
|
67
|
+
* additionalBehaviors: {
|
|
68
|
+
* '/assets/*': behaviors.assets,
|
|
69
|
+
* '/assets/t/*': behaviors.assetsTransform,
|
|
70
|
+
* },
|
|
71
|
+
* })
|
|
72
|
+
*
|
|
73
|
+
* // Adding to an existing distribution:
|
|
74
|
+
* distribution.addBehavior('/assets/*', behaviors.assets.origin, behaviors.assets)
|
|
75
|
+
* distribution.addBehavior('/assets/t/*', behaviors.assetsTransform.origin, behaviors.assetsTransform)
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
78
|
+
export interface AssetCloudFrontBehaviors {
|
|
79
|
+
/**
|
|
80
|
+
* `/assets/*` - static objects only (sanitized SVG/PDF the finalize
|
|
81
|
+
* pipeline wrote, plus already-computed transform outputs under
|
|
82
|
+
* `assets/t/...`, which also live under this prefix). S3 origin only -
|
|
83
|
+
* nothing here is ever computed on demand.
|
|
84
|
+
*/
|
|
85
|
+
readonly assets: cloudfront.BehaviorOptions;
|
|
86
|
+
/**
|
|
87
|
+
* `/assets/t/*` - transform outputs specifically. Origin group: the same
|
|
88
|
+
* S3 origin as `assets` primary, falling over to the transform Lambda's
|
|
89
|
+
* Function URL on 403 OR 404 (a signed OAC origin reports a miss as 403;
|
|
90
|
+
* configuring both is defense-in-depth). See the SPIKE RESULT in
|
|
91
|
+
* `.claude/future-tasks/assets-media-system.md` - this design is
|
|
92
|
+
* confirmed working with CloudFront caching the failover response.
|
|
93
|
+
*/
|
|
94
|
+
readonly assetsTransform: cloudfront.BehaviorOptions;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Per-site CDK construct for the asset/media delivery system (see
|
|
98
|
+
* `.claude/future-tasks/assets-media-system.md` for the full design record).
|
|
99
|
+
* Wires:
|
|
100
|
+
*
|
|
101
|
+
* - The bucket's asset-prefix lifecycle rule + CORS (standalone mode only).
|
|
102
|
+
* - The transform Lambda (`../../lambda/asset-transform/handler.ts`, built
|
|
103
|
+
* via `pnpm run build:lambda` - see that script's doc comment for the
|
|
104
|
+
* no-Docker sharp bundling approach) and its OAC-locked Function URL.
|
|
105
|
+
* - `assetBehaviors()`, the two CloudFront behavior configs a consuming
|
|
106
|
+
* distribution attaches (see `AssetCloudFrontBehaviors`'s doc comment for
|
|
107
|
+
* both attachment shapes).
|
|
108
|
+
* - `grantUploadAccess()`, the exact prefix-scoped grants the CMS/editor
|
|
109
|
+
* principal needs to run `S3AssetStore` (packages/canopycms/src/assets/store-s3.ts).
|
|
110
|
+
*/
|
|
111
|
+
export declare class AssetSupport extends Construct {
|
|
112
|
+
/** The bucket in use (either created here, or the BYO `props.bucket`). */
|
|
113
|
+
readonly bucket: s3.IBucket;
|
|
114
|
+
/** The transform Lambda function. */
|
|
115
|
+
readonly transformFunction: lambda.Function;
|
|
116
|
+
/** The transform Lambda's Function URL - use as a CloudFront origin (see `assetBehaviors()`). */
|
|
117
|
+
readonly transformFunctionUrl: lambda.FunctionUrl;
|
|
118
|
+
/** Effective advisory upload-size cap (see `AssetSupportProps.maxUploadBytes`). */
|
|
119
|
+
readonly maxUploadBytes: number;
|
|
120
|
+
private readonly behaviors;
|
|
121
|
+
constructor(scope: Construct, id: string, props: AssetSupportProps);
|
|
122
|
+
private buildBehaviors;
|
|
123
|
+
/** The two CloudFront behavior configs this system needs - see `AssetCloudFrontBehaviors`'s doc comment for both attachment shapes. */
|
|
124
|
+
assetBehaviors(): AssetCloudFrontBehaviors;
|
|
125
|
+
/**
|
|
126
|
+
* Grant the CMS/editor principal (the CMS Lambda's role, typically) the
|
|
127
|
+
* exact permissions `S3AssetStore` (packages/canopycms/src/assets/store-s3.ts)
|
|
128
|
+
* calls for:
|
|
129
|
+
*
|
|
130
|
+
* - put on `asset-staging/` (presigned POST + proxied `writeStaging`)
|
|
131
|
+
* - get on `asset-staging/` + `asset-originals/` + `asset-meta/` + `assets/`
|
|
132
|
+
* - put on `asset-originals/` + `asset-meta/` + `assets/`
|
|
133
|
+
* - delete on `asset-staging/` + `asset-meta/`
|
|
134
|
+
*/
|
|
135
|
+
grantUploadAccess(grantee: iam.IGrantable): void;
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=asset-support.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"asset-support.d.ts","sourceRoot":"","sources":["../../src/constructs/asset-support.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AACtC,OAAO,EAEL,aAAa,EACb,cAAc,IAAI,UAAU,EAE5B,OAAO,IAAI,GAAG,EACd,UAAU,IAAI,MAAM,EACpB,MAAM,IAAI,EAAE,EACb,MAAM,aAAa,CAAA;AAwDpB,MAAM,WAAW,iBAAiB;IAChC;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,OAAO,CAAA;IAE5B;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,EAAE,MAAM,EAAE,CAAA;IAEhC;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAA;IAEhC;;;;OAIG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAA;IAE5B;;;;OAIG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,aAAa,CAAA;IAEtC;;;;;;OAMG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,OAAO,CAAA;CACrC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,WAAW,wBAAwB;IACvC;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC,eAAe,CAAA;IAE3C;;;;;;;OAOG;IACH,QAAQ,CAAC,eAAe,EAAE,UAAU,CAAC,eAAe,CAAA;CACrD;AAED;;;;;;;;;;;;;;GAcG;AACH,qBAAa,YAAa,SAAQ,SAAS;IACzC,0EAA0E;IAC1E,SAAgB,MAAM,EAAE,EAAE,CAAC,OAAO,CAAA;IAElC,qCAAqC;IACrC,SAAgB,iBAAiB,EAAE,MAAM,CAAC,QAAQ,CAAA;IAElD,iGAAiG;IACjG,SAAgB,oBAAoB,EAAE,MAAM,CAAC,WAAW,CAAA;IAExD,mFAAmF;IACnF,SAAgB,cAAc,EAAE,MAAM,CAAA;IAEtC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA0B;gBAExC,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,iBAAiB;IA6ElE,OAAO,CAAC,cAAc;IA+CtB,uIAAuI;IAChI,cAAc,IAAI,wBAAwB;IAIjD;;;;;;;;;OASG;IACI,iBAAiB,CAAC,OAAO,EAAE,GAAG,CAAC,UAAU,GAAG,IAAI;CAexD"}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import * as path from 'node:path';
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
3
|
+
import { Construct } from 'constructs';
|
|
4
|
+
import { Duration, RemovalPolicy, aws_cloudfront as cloudfront, aws_cloudfront_origins as origins, aws_lambda as lambda, aws_s3 as s3, } from 'aws-cdk-lib';
|
|
5
|
+
// This package (`canopycms-cdk`) is `"type": "module"`, so its compiled
|
|
6
|
+
// output is real ESM - `__dirname` is not a global there. Derive it from
|
|
7
|
+
// `import.meta.url` instead (mirrors ../../lambda/asset-transform/build.mjs).
|
|
8
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
9
|
+
/**
|
|
10
|
+
* The four S3 key prefixes the asset system uses, mirrored from
|
|
11
|
+
* `packages/canopycms/src/assets/asset-prefixes.ts` (the source of truth).
|
|
12
|
+
* Duplicated as plain string literals - not imported from `canopycms` -
|
|
13
|
+
* because this construct must synth cleanly for ANY consumer's CDK app
|
|
14
|
+
* (e.g. a site's own `infrastructure/` package), which has no reason to
|
|
15
|
+
* have `canopycms` itself resolvable from wherever its CDK code runs. The
|
|
16
|
+
* transform Lambda (../../lambda/asset-transform/handler.ts), by contrast,
|
|
17
|
+
* is bundled at build time from WITHIN this package (where `canopycms` is a
|
|
18
|
+
* real workspace devDependency), so it imports the canonical constants
|
|
19
|
+
* directly from `canopycms/server` instead of duplicating them - see that
|
|
20
|
+
* file's doc comment.
|
|
21
|
+
*/
|
|
22
|
+
const PREFIXES = {
|
|
23
|
+
originals: 'asset-originals',
|
|
24
|
+
staging: 'asset-staging',
|
|
25
|
+
meta: 'asset-meta',
|
|
26
|
+
public: 'assets',
|
|
27
|
+
transform: 'assets/t',
|
|
28
|
+
};
|
|
29
|
+
/** S3 CORS preflight cache duration for presigned-POST uploads from the editor. */
|
|
30
|
+
const CORS_MAX_AGE_SECONDS = 3000;
|
|
31
|
+
/** Matches packages/canopycms/src/assets/store-s3.ts's `DEFAULT_MAX_UPLOAD_BYTES`. */
|
|
32
|
+
const DEFAULT_MAX_UPLOAD_BYTES = 50 * 1024 * 1024;
|
|
33
|
+
const TRANSFORM_LAMBDA_MEMORY_MB = 1536;
|
|
34
|
+
const TRANSFORM_LAMBDA_TIMEOUT = Duration.seconds(30);
|
|
35
|
+
/**
|
|
36
|
+
* `/assets/t/*`-specific cache TTLs. The managed `CachePolicy.CACHING_OPTIMIZED`
|
|
37
|
+
* (used for the plain `/assets/*` static behavior) has a 1-second MIN TTL,
|
|
38
|
+
* which is exactly the bug this policy exists to avoid: the transform
|
|
39
|
+
* Lambda's oversized-output path (handler.ts) returns a `Cache-Control:
|
|
40
|
+
* no-store` 302 redirect specifically so CloudFront never caches it - but a
|
|
41
|
+
* managed policy with ANY nonzero min TTL still caches that response for at
|
|
42
|
+
* least that long regardless of the origin's own `no-store`, so the redirect
|
|
43
|
+
* (to the now-written canonical S3 key) gets cached and re-served, and
|
|
44
|
+
* CloudFront's next hit for that same canonical key 404s/403s off S3 (or
|
|
45
|
+
* hasn't propagated yet), falling back to the Lambda again - a self-sustaining
|
|
46
|
+
* redirect loop. `minTtl: 0` lets an origin's own `Cache-Control` (including
|
|
47
|
+
* `no-store`) be honored immediately; `maxTtl`/`defaultTtl` stay generous so
|
|
48
|
+
* the normal case (an immutable 200 with a real `max-age`) still caches well.
|
|
49
|
+
*/
|
|
50
|
+
const TRANSFORM_CACHE_MIN_TTL = Duration.seconds(0);
|
|
51
|
+
const TRANSFORM_CACHE_DEFAULT_TTL = Duration.days(1);
|
|
52
|
+
const TRANSFORM_CACHE_MAX_TTL = Duration.days(365);
|
|
53
|
+
/**
|
|
54
|
+
* Per-site CDK construct for the asset/media delivery system (see
|
|
55
|
+
* `.claude/future-tasks/assets-media-system.md` for the full design record).
|
|
56
|
+
* Wires:
|
|
57
|
+
*
|
|
58
|
+
* - The bucket's asset-prefix lifecycle rule + CORS (standalone mode only).
|
|
59
|
+
* - The transform Lambda (`../../lambda/asset-transform/handler.ts`, built
|
|
60
|
+
* via `pnpm run build:lambda` - see that script's doc comment for the
|
|
61
|
+
* no-Docker sharp bundling approach) and its OAC-locked Function URL.
|
|
62
|
+
* - `assetBehaviors()`, the two CloudFront behavior configs a consuming
|
|
63
|
+
* distribution attaches (see `AssetCloudFrontBehaviors`'s doc comment for
|
|
64
|
+
* both attachment shapes).
|
|
65
|
+
* - `grantUploadAccess()`, the exact prefix-scoped grants the CMS/editor
|
|
66
|
+
* principal needs to run `S3AssetStore` (packages/canopycms/src/assets/store-s3.ts).
|
|
67
|
+
*/
|
|
68
|
+
export class AssetSupport extends Construct {
|
|
69
|
+
constructor(scope, id, props) {
|
|
70
|
+
super(scope, id);
|
|
71
|
+
this.maxUploadBytes = props.maxUploadBytes ?? DEFAULT_MAX_UPLOAD_BYTES;
|
|
72
|
+
if (props.bucket) {
|
|
73
|
+
this.bucket = props.bucket;
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
this.bucket = new s3.Bucket(this, 'Bucket', {
|
|
77
|
+
blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
|
|
78
|
+
encryption: s3.BucketEncryption.S3_MANAGED,
|
|
79
|
+
versioned: props.versioned ?? false,
|
|
80
|
+
removalPolicy: props.removalPolicy ?? RemovalPolicy.RETAIN,
|
|
81
|
+
autoDeleteObjects: props.autoDeleteObjects ?? false,
|
|
82
|
+
// Only `asset-staging/` expires - originals/meta/public/transform
|
|
83
|
+
// outputs are all kept forever by design (content-addressed,
|
|
84
|
+
// immutable - see the design record's "Storage" section).
|
|
85
|
+
lifecycleRules: [
|
|
86
|
+
{
|
|
87
|
+
id: 'expire-asset-staging',
|
|
88
|
+
enabled: true,
|
|
89
|
+
prefix: `${PREFIXES.staging}/`,
|
|
90
|
+
expiration: Duration.days(1),
|
|
91
|
+
},
|
|
92
|
+
],
|
|
93
|
+
cors: [
|
|
94
|
+
{
|
|
95
|
+
id: 'editor-presigned-upload',
|
|
96
|
+
allowedOrigins: props.editorOrigins,
|
|
97
|
+
allowedMethods: [s3.HttpMethods.POST, s3.HttpMethods.PUT, s3.HttpMethods.GET],
|
|
98
|
+
allowedHeaders: ['*'],
|
|
99
|
+
maxAge: CORS_MAX_AGE_SECONDS,
|
|
100
|
+
},
|
|
101
|
+
],
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
this.transformFunction = new lambda.Function(this, 'TransformFunction', {
|
|
105
|
+
// Built by `pnpm run build:lambda` (lambda/asset-transform/build.mjs) -
|
|
106
|
+
// esbuild bundle + a real linux/arm64 `npm install sharp` alongside it,
|
|
107
|
+
// no Docker. `cdk synth`/`deploy` need that script run first; it is
|
|
108
|
+
// NOT run automatically here (kept explicit rather than magic - see
|
|
109
|
+
// this construct's class doc comment).
|
|
110
|
+
code: lambda.Code.fromAsset(path.join(__dirname, '..', '..', 'lambda', 'asset-transform', 'dist')),
|
|
111
|
+
handler: 'handler.handler',
|
|
112
|
+
runtime: lambda.Runtime.NODEJS_20_X,
|
|
113
|
+
architecture: lambda.Architecture.ARM_64,
|
|
114
|
+
memorySize: TRANSFORM_LAMBDA_MEMORY_MB,
|
|
115
|
+
timeout: TRANSFORM_LAMBDA_TIMEOUT,
|
|
116
|
+
environment: {
|
|
117
|
+
ASSET_BUCKET: this.bucket.bucketName,
|
|
118
|
+
},
|
|
119
|
+
});
|
|
120
|
+
// Read access to originals (what it transforms) - deviation from the PR
|
|
121
|
+
// spec's literal "read asset-originals/, write assets/" grant list: the
|
|
122
|
+
// handler must also read `asset-meta/{hash32}.json` to look up kind/ext
|
|
123
|
+
// before it can transform anything, so meta read access is granted too.
|
|
124
|
+
this.bucket.grantRead(this.transformFunction, `${PREFIXES.originals}/*`);
|
|
125
|
+
this.bucket.grantRead(this.transformFunction, `${PREFIXES.meta}/*`);
|
|
126
|
+
// Write access to `assets/*` covers both the public prefix and
|
|
127
|
+
// `assets/t/*` (transform outputs nest under it) in one grant.
|
|
128
|
+
this.bucket.grantPut(this.transformFunction, `${PREFIXES.public}/*`);
|
|
129
|
+
// AWS_IAM (not NONE): only reachable through CloudFront's Origin Access
|
|
130
|
+
// Control, matching CanopyCmsService/CanopyCmsDistribution's existing
|
|
131
|
+
// Function URL pattern (see cms-service.ts / cms-distribution.ts) -
|
|
132
|
+
// direct hits to the Function URL are rejected.
|
|
133
|
+
this.transformFunctionUrl = this.transformFunction.addFunctionUrl({
|
|
134
|
+
authType: lambda.FunctionUrlAuthType.AWS_IAM,
|
|
135
|
+
});
|
|
136
|
+
this.behaviors = this.buildBehaviors();
|
|
137
|
+
}
|
|
138
|
+
buildBehaviors() {
|
|
139
|
+
const s3Origin = origins.S3BucketOrigin.withOriginAccessControl(this.bucket);
|
|
140
|
+
const transformLambdaOrigin = origins.FunctionUrlOrigin.withOriginAccessControl(this.transformFunctionUrl);
|
|
141
|
+
const assets = {
|
|
142
|
+
origin: s3Origin,
|
|
143
|
+
viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
|
|
144
|
+
cachePolicy: cloudfront.CachePolicy.CACHING_OPTIMIZED,
|
|
145
|
+
compress: true,
|
|
146
|
+
};
|
|
147
|
+
// Custom (not managed CACHING_OPTIMIZED) - see TRANSFORM_CACHE_MIN_TTL's
|
|
148
|
+
// doc comment for why this behavior specifically needs minTtl: 0.
|
|
149
|
+
// Directives live entirely in the path (no query string), and the
|
|
150
|
+
// response never varies by cookie/request header, so nothing is
|
|
151
|
+
// forwarded into the cache key.
|
|
152
|
+
const transformCachePolicy = new cloudfront.CachePolicy(this, 'AssetsTransformCachePolicy', {
|
|
153
|
+
minTtl: TRANSFORM_CACHE_MIN_TTL,
|
|
154
|
+
defaultTtl: TRANSFORM_CACHE_DEFAULT_TTL,
|
|
155
|
+
maxTtl: TRANSFORM_CACHE_MAX_TTL,
|
|
156
|
+
enableAcceptEncodingGzip: true,
|
|
157
|
+
enableAcceptEncodingBrotli: true,
|
|
158
|
+
queryStringBehavior: cloudfront.CacheQueryStringBehavior.none(),
|
|
159
|
+
headerBehavior: cloudfront.CacheHeaderBehavior.none(),
|
|
160
|
+
cookieBehavior: cloudfront.CacheCookieBehavior.none(),
|
|
161
|
+
});
|
|
162
|
+
const assetsTransform = {
|
|
163
|
+
origin: new origins.OriginGroup({
|
|
164
|
+
primaryOrigin: s3Origin,
|
|
165
|
+
fallbackOrigin: transformLambdaOrigin,
|
|
166
|
+
// A signed OAC origin reports a miss as 403 (not 404, since it
|
|
167
|
+
// never reveals object existence) - CloudFront's own S3 origin
|
|
168
|
+
// handling can still surface 404 in some paths, so both are
|
|
169
|
+
// configured. Confirmed working end-to-end by the sandbox spike
|
|
170
|
+
// (.claude/future-tasks/assets-media-system.md's SPIKE RESULT).
|
|
171
|
+
fallbackStatusCodes: [403, 404],
|
|
172
|
+
}),
|
|
173
|
+
viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
|
|
174
|
+
cachePolicy: transformCachePolicy,
|
|
175
|
+
};
|
|
176
|
+
return { assets, assetsTransform };
|
|
177
|
+
}
|
|
178
|
+
/** The two CloudFront behavior configs this system needs - see `AssetCloudFrontBehaviors`'s doc comment for both attachment shapes. */
|
|
179
|
+
assetBehaviors() {
|
|
180
|
+
return this.behaviors;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Grant the CMS/editor principal (the CMS Lambda's role, typically) the
|
|
184
|
+
* exact permissions `S3AssetStore` (packages/canopycms/src/assets/store-s3.ts)
|
|
185
|
+
* calls for:
|
|
186
|
+
*
|
|
187
|
+
* - put on `asset-staging/` (presigned POST + proxied `writeStaging`)
|
|
188
|
+
* - get on `asset-staging/` + `asset-originals/` + `asset-meta/` + `assets/`
|
|
189
|
+
* - put on `asset-originals/` + `asset-meta/` + `assets/`
|
|
190
|
+
* - delete on `asset-staging/` + `asset-meta/`
|
|
191
|
+
*/
|
|
192
|
+
grantUploadAccess(grantee) {
|
|
193
|
+
this.bucket.grantPut(grantee, `${PREFIXES.staging}/*`);
|
|
194
|
+
this.bucket.grantRead(grantee, `${PREFIXES.staging}/*`);
|
|
195
|
+
this.bucket.grantRead(grantee, `${PREFIXES.originals}/*`);
|
|
196
|
+
this.bucket.grantRead(grantee, `${PREFIXES.meta}/*`);
|
|
197
|
+
this.bucket.grantRead(grantee, `${PREFIXES.public}/*`);
|
|
198
|
+
this.bucket.grantPut(grantee, `${PREFIXES.originals}/*`);
|
|
199
|
+
this.bucket.grantPut(grantee, `${PREFIXES.meta}/*`);
|
|
200
|
+
this.bucket.grantPut(grantee, `${PREFIXES.public}/*`);
|
|
201
|
+
this.bucket.grantDelete(grantee, `${PREFIXES.staging}/*`);
|
|
202
|
+
this.bucket.grantDelete(grantee, `${PREFIXES.meta}/*`);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
//# sourceMappingURL=asset-support.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"asset-support.js","sourceRoot":"","sources":["../../src/constructs/asset-support.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Construct } from 'constructs';
|
|
2
2
|
import { Duration, RemovalPolicy, aws_ec2 as ec2, aws_efs as efs, aws_lambda as lambda, aws_autoscaling as autoscaling } from 'aws-cdk-lib';
|
|
3
|
+
import type { IBucket } from 'aws-cdk-lib/aws-s3';
|
|
3
4
|
export interface CanopyCmsServiceProps {
|
|
4
5
|
/** Docker image for the CMS Lambda function */
|
|
5
6
|
cmsDockerImage: lambda.DockerImageCode;
|
|
@@ -29,6 +30,15 @@ export interface CanopyCmsServiceProps {
|
|
|
29
30
|
clerkSecretKeySecretArn?: string;
|
|
30
31
|
/** Base branch name (default: 'main') */
|
|
31
32
|
baseBranch?: string;
|
|
33
|
+
/**
|
|
34
|
+
* The asset bucket (from `AssetSupport`, or any bucket following its
|
|
35
|
+
* prefix layout) the CMS Lambda's role should be granted access to. When
|
|
36
|
+
* provided, grants the exact prefix-scoped put/get/delete permissions
|
|
37
|
+
* `S3AssetStore` calls for (packages/canopycms/src/assets/store-s3.ts) -
|
|
38
|
+
* mirrors `AssetSupport.grantUploadAccess()` rather than depending on that
|
|
39
|
+
* construct directly, so `canopycms-cdk`'s two constructs stay decoupled.
|
|
40
|
+
*/
|
|
41
|
+
assetBucket?: IBucket;
|
|
32
42
|
}
|
|
33
43
|
/**
|
|
34
44
|
* Core CDK construct for CanopyCMS deployment.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cms-service.d.ts","sourceRoot":"","sources":["../../src/constructs/cms-service.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cms-service.d.ts","sourceRoot":"","sources":["../../src/constructs/cms-service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AACtC,OAAO,EACL,QAAQ,EACR,aAAa,EACb,OAAO,IAAI,GAAG,EACd,OAAO,IAAI,GAAG,EAEd,UAAU,IAAI,MAAM,EACpB,eAAe,IAAI,WAAW,EAE/B,MAAM,aAAa,CAAA;AACpB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAWjD,MAAM,WAAW,qBAAqB;IACpC,+CAA+C;IAC/C,cAAc,EAAE,MAAM,CAAC,eAAe,CAAA;IAEtC,4DAA4D;IAC5D,GAAG,CAAC,EAAE,GAAG,CAAC,IAAI,CAAA;IAEd,0CAA0C;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAA;IAEnB,2CAA2C;IAC3C,OAAO,CAAC,EAAE,QAAQ,CAAA;IAElB,oDAAoD;IACpD,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAE5B,gEAAgE;IAChE,YAAY,CAAC,EAAE,MAAM,CAAA;IAErB,8EAA8E;IAC9E,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;IAEtB,oDAAoD;IACpD,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAEpC,2CAA2C;IAC3C,gBAAgB,CAAC,EAAE,aAAa,CAAA;IAEhC,oEAAoE;IACpE,WAAW,EAAE,MAAM,CAAA;IAEnB,qEAAqE;IACrE,UAAU,EAAE,MAAM,CAAA;IAElB,mDAAmD;IACnD,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAE7B,mDAAmD;IACnD,uBAAuB,CAAC,EAAE,MAAM,CAAA;IAEhC,yCAAyC;IACzC,UAAU,CAAC,EAAE,MAAM,CAAA;IAEnB;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,gBAAiB,SAAQ,SAAS;IAC7C,qDAAqD;IACrD,SAAgB,WAAW,EAAE,MAAM,CAAC,WAAW,CAAA;IAE/C,yBAAyB;IACzB,SAAgB,UAAU,EAAE,GAAG,CAAC,UAAU,CAAA;IAE1C,cAAc;IACd,SAAgB,GAAG,EAAE,GAAG,CAAC,IAAI,CAAA;IAE7B,0BAA0B;IAC1B,SAAgB,cAAc,EAAE,MAAM,CAAC,QAAQ,CAAA;IAE/C,wCAAwC;IACxC,SAAgB,SAAS,EAAE,WAAW,CAAC,gBAAgB,CAAA;gBAE3C,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,qBAAqB;CAkTvE"}
|
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import * as path from 'node:path';
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
2
3
|
import { Construct } from 'constructs';
|
|
3
4
|
import { Duration, RemovalPolicy, 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, } from 'aws-cdk-lib';
|
|
5
|
+
// This package (`canopycms-cdk`) is `"type": "module"`, so its compiled
|
|
6
|
+
// output is real ESM - `__dirname` is not a global there. Found while
|
|
7
|
+
// fixing this construct's B1 deploy blocker below: the worker asset path a
|
|
8
|
+
// few lines down threw `__dirname is not defined` under a real ESM runtime
|
|
9
|
+
// (e.g. `tsx`) - masked in this file's own tests only because Vitest's
|
|
10
|
+
// SSR/CJS-interop transform shims `__dirname` automatically. Same fix as
|
|
11
|
+
// ../../lambda/asset-transform/build.mjs and ./asset-support.ts.
|
|
12
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
4
13
|
/**
|
|
5
14
|
* Core CDK construct for CanopyCMS deployment.
|
|
6
15
|
*
|
|
@@ -37,6 +46,16 @@ export class CanopyCmsService extends Construct {
|
|
|
37
46
|
},
|
|
38
47
|
],
|
|
39
48
|
});
|
|
49
|
+
// Gateway VPC endpoint for S3 (free - no hourly/data charge, unlike an
|
|
50
|
+
// interface endpoint). Without this the PRIVATE_ISOLATED subnet has NO
|
|
51
|
+
// route to S3 at all (no NAT, no IGW) - the CMS Lambda's S3AssetStore
|
|
52
|
+
// calls (presigned POST generation, finalize's originals/meta writes)
|
|
53
|
+
// would hang/fail outright (adversarial finding B1). `addGatewayEndpoint`
|
|
54
|
+
// is on `IVpc` itself, so this works whether `this.vpc` was created here
|
|
55
|
+
// or supplied via `props.vpc`.
|
|
56
|
+
this.vpc.addGatewayEndpoint('S3Endpoint', {
|
|
57
|
+
service: ec2.GatewayVpcEndpointAwsService.S3,
|
|
58
|
+
});
|
|
40
59
|
// ========================================================================
|
|
41
60
|
// EFS — persistent filesystem for content, git repos, cache
|
|
42
61
|
// ========================================================================
|
|
@@ -79,6 +98,22 @@ export class CanopyCmsService extends Construct {
|
|
|
79
98
|
// /mnt/efs (DEP-C1). Mirrors the worker's ingress+egress pair below.
|
|
80
99
|
efsSg.addIngressRule(lambdaSg, ec2.Port.tcp(2049), 'Lambda NFS access');
|
|
81
100
|
lambdaSg.addEgressRule(efsSg, ec2.Port.tcp(2049), 'NFS to EFS');
|
|
101
|
+
// Lambda -> S3 (via the gateway endpoint above), HTTPS only. The tight
|
|
102
|
+
// option - `ec2.Peer.prefixList(<S3 managed prefix list id>)` - needs a
|
|
103
|
+
// region-specific literal id (there is no CFN attribute exposing it off
|
|
104
|
+
// `GatewayVpcEndpoint`, and `PrefixList.fromLookup` does a real AWS
|
|
105
|
+
// context-provider lookup at synth time, which would make this
|
|
106
|
+
// construct's synth require live AWS credentials - unacceptable for a
|
|
107
|
+
// construct whose own unit tests synth with a fake account/region).
|
|
108
|
+
// `anyIpv4()` on 443 is safe here specifically because the route table
|
|
109
|
+
// for this PRIVATE_ISOLATED subnet has no route to 0.0.0.0/0 at all (no
|
|
110
|
+
// NAT, no IGW) - only to the VPC CIDR and to configured endpoints'
|
|
111
|
+
// prefix-list routes - so this rule cannot actually reach the general
|
|
112
|
+
// internet; the route table, not the security group, is the real
|
|
113
|
+
// boundary here. Narrow this to `Peer.prefixList(...)` if/when a
|
|
114
|
+
// region-agnostic way to reference the S3 managed prefix list lands in
|
|
115
|
+
// CDK, or if this VPC ever gains a NAT/IGW route.
|
|
116
|
+
lambdaSg.addEgressRule(ec2.Peer.anyIpv4(), ec2.Port.tcp(443), 'HTTPS to S3 (via gateway endpoint)');
|
|
82
117
|
this.lambdaFunction = new lambda.DockerImageFunction(this, 'CmsFunction', {
|
|
83
118
|
code: props.cmsDockerImage,
|
|
84
119
|
memorySize: props.memorySize ?? 2048,
|
|
@@ -103,6 +138,31 @@ export class CanopyCmsService extends Construct {
|
|
|
103
138
|
this.functionUrl = this.lambdaFunction.addFunctionUrl({
|
|
104
139
|
authType: lambda.FunctionUrlAuthType.AWS_IAM,
|
|
105
140
|
});
|
|
141
|
+
// Asset bucket access (optional) - grants the CMS Lambda's role the same
|
|
142
|
+
// prefix-scoped put/get/delete permissions `AssetSupport.grantUploadAccess()`
|
|
143
|
+
// grants, without this construct depending on `AssetSupport` directly
|
|
144
|
+
// (kept decoupled - a consumer wires both constructs together in their
|
|
145
|
+
// own stack). Duplicated rather than shared because the two constructs
|
|
146
|
+
// must stay independently usable (`AssetSupport` has no CMS-service
|
|
147
|
+
// dependency either).
|
|
148
|
+
if (props.assetBucket) {
|
|
149
|
+
const prefixes = {
|
|
150
|
+
staging: 'asset-staging',
|
|
151
|
+
originals: 'asset-originals',
|
|
152
|
+
meta: 'asset-meta',
|
|
153
|
+
public: 'assets',
|
|
154
|
+
};
|
|
155
|
+
props.assetBucket.grantPut(this.lambdaFunction, `${prefixes.staging}/*`);
|
|
156
|
+
props.assetBucket.grantRead(this.lambdaFunction, `${prefixes.staging}/*`);
|
|
157
|
+
props.assetBucket.grantRead(this.lambdaFunction, `${prefixes.originals}/*`);
|
|
158
|
+
props.assetBucket.grantRead(this.lambdaFunction, `${prefixes.meta}/*`);
|
|
159
|
+
props.assetBucket.grantRead(this.lambdaFunction, `${prefixes.public}/*`);
|
|
160
|
+
props.assetBucket.grantPut(this.lambdaFunction, `${prefixes.originals}/*`);
|
|
161
|
+
props.assetBucket.grantPut(this.lambdaFunction, `${prefixes.meta}/*`);
|
|
162
|
+
props.assetBucket.grantPut(this.lambdaFunction, `${prefixes.public}/*`);
|
|
163
|
+
props.assetBucket.grantDelete(this.lambdaFunction, `${prefixes.staging}/*`);
|
|
164
|
+
props.assetBucket.grantDelete(this.lambdaFunction, `${prefixes.meta}/*`);
|
|
165
|
+
}
|
|
106
166
|
// ========================================================================
|
|
107
167
|
// EC2 Worker — t4g.nano spot, public subnet, internet, EFS mount
|
|
108
168
|
// ========================================================================
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cms-service.js","sourceRoot":"","sources":["../../src/constructs/cms-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AACtC,OAAO,EACL,QAAQ,EACR,aAAa,EACb,OAAO,IAAI,GAAG,EACd,OAAO,IAAI,GAAG,EACd,OAAO,IAAI,GAAG,EACd,UAAU,IAAI,MAAM,EACpB,eAAe,IAAI,WAAW,EAC9B,aAAa,IAAI,QAAQ,GAC1B,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"cms-service.js","sourceRoot":"","sources":["../../src/constructs/cms-service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AACtC,OAAO,EACL,QAAQ,EACR,aAAa,EACb,OAAO,IAAI,GAAG,EACd,OAAO,IAAI,GAAG,EACd,OAAO,IAAI,GAAG,EACd,UAAU,IAAI,MAAM,EACpB,eAAe,IAAI,WAAW,EAC9B,aAAa,IAAI,QAAQ,GAC1B,MAAM,aAAa,CAAA;AAGpB,wEAAwE;AACxE,sEAAsE;AACtE,2EAA2E;AAC3E,2EAA2E;AAC3E,uEAAuE;AACvE,yEAAyE;AACzE,iEAAiE;AACjE,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;AAwD9D;;;;;;;;;;;GAWG;AACH,MAAM,OAAO,gBAAiB,SAAQ,SAAS;IAgB7C,YAAY,KAAgB,EAAE,EAAU,EAAE,KAA4B;QACpE,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;QAEhB,2EAA2E;QAC3E,gDAAgD;QAChD,2EAA2E;QAE3E,IAAI,CAAC,GAAG;YACN,KAAK,CAAC,GAAG;gBACT,IAAI,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE;oBACvB,MAAM,EAAE,CAAC;oBACT,WAAW,EAAE,CAAC,EAAE,yCAAyC;oBACzD,mBAAmB,EAAE;wBACnB;4BACE,IAAI,EAAE,QAAQ;4BACd,UAAU,EAAE,GAAG,CAAC,UAAU,CAAC,MAAM;4BACjC,QAAQ,EAAE,EAAE;yBACb;wBACD;4BACE,IAAI,EAAE,SAAS;4BACf,UAAU,EAAE,GAAG,CAAC,UAAU,CAAC,gBAAgB;4BAC3C,QAAQ,EAAE,EAAE;yBACb;qBACF;iBACF,CAAC,CAAA;QAEJ,uEAAuE;QACvE,uEAAuE;QACvE,sEAAsE;QACtE,sEAAsE;QACtE,0EAA0E;QAC1E,yEAAyE;QACzE,+BAA+B;QAC/B,IAAI,CAAC,GAAG,CAAC,kBAAkB,CAAC,YAAY,EAAE;YACxC,OAAO,EAAE,GAAG,CAAC,4BAA4B,CAAC,EAAE;SAC7C,CAAC,CAAA;QAEF,2EAA2E;QAC3E,4DAA4D;QAC5D,2EAA2E;QAE3E,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,IAAI,EAAE,OAAO,EAAE;YACjD,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,WAAW,EAAE,eAAe;YAC5B,gBAAgB,EAAE,KAAK;SACxB,CAAC,CAAA;QAEF,IAAI,CAAC,UAAU,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,YAAY,EAAE;YACvD,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,SAAS,EAAE,IAAI;YACf,eAAe,EAAE,GAAG,CAAC,eAAe,CAAC,eAAe;YACpD,aAAa,EAAE,KAAK,CAAC,gBAAgB,IAAI,aAAa,CAAC,MAAM;YAC7D,UAAU,EAAE,EAAE,UAAU,EAAE,GAAG,CAAC,UAAU,CAAC,gBAAgB,EAAE;YAC3D,aAAa,EAAE,KAAK;SACrB,CAAC,CAAA;QAEF,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,aAAa,EAAE;YAChE,IAAI,EAAE,YAAY;YAClB,SAAS,EAAE;gBACT,QAAQ,EAAE,MAAM;gBAChB,QAAQ,EAAE,MAAM;gBAChB,WAAW,EAAE,KAAK;aACnB;YACD,SAAS,EAAE;gBACT,GAAG,EAAE,MAAM;gBACX,GAAG,EAAE,MAAM;aACZ;SACF,CAAC,CAAA;QAEF,2EAA2E;QAC3E,2DAA2D;QAC3D,2EAA2E;QAE3E,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,IAAI,EAAE,UAAU,EAAE;YACvD,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,WAAW,EAAE,kBAAkB;YAC/B,gBAAgB,EAAE,KAAK,EAAE,qBAAqB;SAC/C,CAAC,CAAA;QAEF,0DAA0D;QAC1D,2EAA2E;QAC3E,wEAAwE;QACxE,qEAAqE;QACrE,KAAK,CAAC,cAAc,CAAC,QAAQ,EAAE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,mBAAmB,CAAC,CAAA;QACvE,QAAQ,CAAC,aAAa,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,YAAY,CAAC,CAAA;QAE/D,uEAAuE;QACvE,wEAAwE;QACxE,wEAAwE;QACxE,oEAAoE;QACpE,+DAA+D;QAC/D,sEAAsE;QACtE,oEAAoE;QACpE,uEAAuE;QACvE,wEAAwE;QACxE,mEAAmE;QACnE,sEAAsE;QACtE,iEAAiE;QACjE,iEAAiE;QACjE,uEAAuE;QACvE,kDAAkD;QAClD,QAAQ,CAAC,aAAa,CACpB,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,EAClB,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EACjB,oCAAoC,CACrC,CAAA;QAED,IAAI,CAAC,cAAc,GAAG,IAAI,MAAM,CAAC,mBAAmB,CAAC,IAAI,EAAE,aAAa,EAAE;YACxE,IAAI,EAAE,KAAK,CAAC,cAAc;YAC1B,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,IAAI;YACpC,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YAC9C,4BAA4B,EAAE,KAAK,CAAC,mBAAmB,IAAI,EAAE;YAC7D,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,UAAU,EAAE,EAAE,UAAU,EAAE,GAAG,CAAC,UAAU,CAAC,gBAAgB,EAAE;YAC3D,cAAc,EAAE,CAAC,QAAQ,CAAC;YAC1B,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC,kBAAkB,CAAC,WAAW,EAAE,UAAU,CAAC;YACzE,WAAW,EAAE;gBACX,wBAAwB,EAAE,oBAAoB;gBAC9C,sBAAsB,EAAE,2BAA2B;gBACnD,GAAG,KAAK,CAAC,WAAW;aACrB;SACF,CAAC,CAAA;QAEF,sCAAsC;QACtC,yEAAyE;QACzE,6DAA6D;QAC7D,4EAA4E;QAC5E,qEAAqE;QACrE,0EAA0E;QAC1E,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC;YACpD,QAAQ,EAAE,MAAM,CAAC,mBAAmB,CAAC,OAAO;SAC7C,CAAC,CAAA;QAEF,yEAAyE;QACzE,8EAA8E;QAC9E,sEAAsE;QACtE,uEAAuE;QACvE,uEAAuE;QACvE,oEAAoE;QACpE,sBAAsB;QACtB,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;YACtB,MAAM,QAAQ,GAAG;gBACf,OAAO,EAAE,eAAe;gBACxB,SAAS,EAAE,iBAAiB;gBAC5B,IAAI,EAAE,YAAY;gBAClB,MAAM,EAAE,QAAQ;aACjB,CAAA;YACD,KAAK,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,cAAc,EAAE,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAA;YACxE,KAAK,CAAC,WAAW,CAAC,SAAS,CAAC,IAAI,CAAC,cAAc,EAAE,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAA;YACzE,KAAK,CAAC,WAAW,CAAC,SAAS,CAAC,IAAI,CAAC,cAAc,EAAE,GAAG,QAAQ,CAAC,SAAS,IAAI,CAAC,CAAA;YAC3E,KAAK,CAAC,WAAW,CAAC,SAAS,CAAC,IAAI,CAAC,cAAc,EAAE,GAAG,QAAQ,CAAC,IAAI,IAAI,CAAC,CAAA;YACtE,KAAK,CAAC,WAAW,CAAC,SAAS,CAAC,IAAI,CAAC,cAAc,EAAE,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,CAAA;YACxE,KAAK,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,cAAc,EAAE,GAAG,QAAQ,CAAC,SAAS,IAAI,CAAC,CAAA;YAC1E,KAAK,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,cAAc,EAAE,GAAG,QAAQ,CAAC,IAAI,IAAI,CAAC,CAAA;YACrE,KAAK,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,cAAc,EAAE,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,CAAA;YACvE,KAAK,CAAC,WAAW,CAAC,WAAW,CAAC,IAAI,CAAC,cAAc,EAAE,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAA;YAC3E,KAAK,CAAC,WAAW,CAAC,WAAW,CAAC,IAAI,CAAC,cAAc,EAAE,GAAG,QAAQ,CAAC,IAAI,IAAI,CAAC,CAAA;QAC1E,CAAC;QAED,2EAA2E;QAC3E,iEAAiE;QACjE,2EAA2E;QAE3E,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,IAAI,EAAE,UAAU,EAAE;YACvD,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,WAAW,EAAE,sBAAsB;YACnC,gBAAgB,EAAE,KAAK;SACxB,CAAC,CAAA;QAEF,yDAAyD;QACzD,KAAK,CAAC,cAAc,CAAC,QAAQ,EAAE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,mBAAmB,CAAC,CAAA;QACvE,QAAQ,CAAC,aAAa,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,YAAY,CAAC,CAAA;QAE/D,iCAAiC;QACjC,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,gBAAgB,CAAC,CAAA;QAE/E,wDAAwD;QACxD,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,CAAA;QACvE,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,CAAA;QAEvE,kBAAkB;QAClB,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,EAAE;YAClD,SAAS,EAAE,IAAI,GAAG,CAAC,gBAAgB,CAAC,mBAAmB,CAAC;YACxD,WAAW,EAAE,2BAA2B;SACzC,CAAC,CAAA;QAEF,+BAA+B;QAC/B,IAAI,KAAK,CAAC,WAAW,IAAI,KAAK,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtD,UAAU,CAAC,WAAW,CACpB,IAAI,GAAG,CAAC,eAAe,CAAC;gBACtB,OAAO,EAAE,CAAC,+BAA+B,CAAC;gBAC1C,SAAS,EAAE,KAAK,CAAC,WAAW;aAC7B,CAAC,CACH,CAAA;QACH,CAAC;QAED,sGAAsG;QACtG,UAAU,CAAC,gBAAgB,CACzB,GAAG,CAAC,aAAa,CAAC,wBAAwB,CAAC,8CAA8C,CAAC,CAC3F,CAAA;QAED,oEAAoE;QACpE,kFAAkF;QAClF,MAAM,WAAW,GAAG,IAAI,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,YAAY,EAAE;YACzD,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,mBAAmB,CAAC;SAChD,CAAC,CAAA;QACF,WAAW,CAAC,SAAS,CAAC,UAAU,CAAC,CAAA;QAEjC,gDAAgD;QAChD,MAAM,QAAQ,GAAG;YACf,6CAA6C;YAC7C,0BAA0B,KAAK,CAAC,WAAW,EAAE;YAC7C,yBAAyB,KAAK,CAAC,UAAU,EAAE;YAC3C,yBAAyB,KAAK,CAAC,UAAU,IAAI,MAAM,EAAE;SACtD,CAAA;QACD,IAAI,KAAK,CAAC,oBAAoB,EAAE,CAAC;YAC/B,QAAQ,CAAC,IAAI,CAAC,qCAAqC,KAAK,CAAC,oBAAoB,EAAE,CAAC,CAAA;QAClF,CAAC;QACD,IAAI,KAAK,CAAC,uBAAuB,EAAE,CAAC;YAClC,QAAQ,CAAC,IAAI,CAAC,+BAA+B,KAAK,CAAC,uBAAuB,EAAE,CAAC,CAAA;QAC/E,CAAC;QACD,MAAM,cAAc,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAE1C,kBAAkB;QAClB,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAA;QACxC,QAAQ,CAAC,WAAW,CAClB,aAAa,EACb,mBAAmB,EACnB,EAAE,EACF,wBAAwB,EACxB,oBAAoB,EACpB,2DAA2D,EAC3D,uBAAuB,EACvB,EAAE,EACF,aAAa,EACb,iCAAiC,EACjC,mBAAmB,EACnB,gBAAgB,IAAI,CAAC,UAAU,CAAC,YAAY,aAAa,EACzD,EAAE,EACF,qCAAqC,EACrC,kBAAkB,WAAW,CAAC,YAAY,IAAI,WAAW,CAAC,WAAW,yBAAyB,EAC9F,6BAA6B,EAC7B,uBAAuB,EACvB,iCAAiC,EACjC,EAAE,EACF,8CAA8C,EAC9C,2CAA2C,EAC3C,cAAc,EACd,QAAQ,EACR,EAAE,EACF,0BAA0B,EAC1B,6DAA6D,EAC7D,QAAQ,EACR,qCAAqC,EACrC,sBAAsB,EACtB,EAAE,EACF,WAAW,EACX,aAAa,EACb,eAAe,EACf,qCAAqC,EACrC,kCAAkC,EAClC,gBAAgB,EAChB,cAAc,EACd,qBAAqB,EACrB,wBAAwB,EACxB,uBAAuB,EACvB,yCAAyC,EACzC,EAAE,EACF,WAAW,EACX,4BAA4B,EAC5B,QAAQ,EACR,EAAE,EACF,8BAA8B,EAC9B,+CAA+C,EAC/C,iEAAiE,EACjE,gEAAgE,EAChE,sEAAsE,EACtE,kCAAkC,EAClC,6BAA6B,EAC7B,4CAA4C,EAC5C,EAAE,EACF,gBAAgB,EAChB,yBAAyB,EACzB,gCAAgC,EAChC,+BAA+B,CAChC,CAAA;QAED,qBAAqB;QACrB,IAAI,CAAC,SAAS,GAAG,IAAI,WAAW,CAAC,gBAAgB,CAAC,IAAI,EAAE,WAAW,EAAE;YACnE,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,UAAU,EAAE,EAAE,UAAU,EAAE,GAAG,CAAC,UAAU,CAAC,MAAM,EAAE;YACjD,YAAY,EAAE,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC;YAC/E,YAAY,EAAE,GAAG,CAAC,YAAY,CAAC,qBAAqB,CAAC;gBACnD,OAAO,EAAE,GAAG,CAAC,kBAAkB,CAAC,MAAM;aACvC,CAAC;YACF,IAAI,EAAE,UAAU;YAChB,aAAa,EAAE,QAAQ;YACvB,WAAW,EAAE,CAAC;YACd,WAAW,EAAE,CAAC;YACd,QAAQ;YACR,SAAS,EAAE,KAAK,CAAC,YAAY,IAAI,QAAQ,EAAE,8BAA8B;YACzE,WAAW,EAAE,WAAW,CAAC,WAAW,CAAC,GAAG,CAAC;gBACvC,KAAK,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;aAC3B,CAAC;SACH,CAAC,CAAA;IACJ,CAAC;CACF"}
|
package/dist/index.d.ts
CHANGED
|
@@ -4,4 +4,6 @@ export { CanopyCmsService } from './constructs/cms-service';
|
|
|
4
4
|
export type { CanopyCmsServiceProps } from './constructs/cms-service';
|
|
5
5
|
export { CanopyCmsDistribution } from './constructs/cms-distribution';
|
|
6
6
|
export type { CanopyCmsDistributionProps } from './constructs/cms-distribution';
|
|
7
|
+
export { AssetSupport } from './constructs/asset-support';
|
|
8
|
+
export type { AssetSupportProps, AssetCloudFrontBehaviors } from './constructs/asset-support';
|
|
7
9
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AACpC,YAAY,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAG/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAA;AAC3D,YAAY,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAA;AACrE,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAA;AACrE,YAAY,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AACpC,YAAY,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAG/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAA;AAC3D,YAAY,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAA;AACrE,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAA;AACrE,YAAY,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAA;AAC/E,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AACzD,YAAY,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -3,4 +3,5 @@ export { CmsWorker } from './worker';
|
|
|
3
3
|
// CDK Constructs
|
|
4
4
|
export { CanopyCmsService } from './constructs/cms-service';
|
|
5
5
|
export { CanopyCmsDistribution } from './constructs/cms-distribution';
|
|
6
|
+
export { AssetSupport } from './constructs/asset-support';
|
|
6
7
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,gBAAgB;AAChB,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAGpC,iBAAiB;AACjB,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAA;AAE3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,gBAAgB;AAChB,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAGpC,iBAAiB;AACjB,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAA;AAE3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAA;AAErE,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "canopycms-cdk",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.58",
|
|
4
4
|
"description": "AWS CDK constructs and EC2 worker for CanopyCMS deployment",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"node": ">=18"
|
|
28
28
|
},
|
|
29
29
|
"peerDependencies": {
|
|
30
|
-
"aws-cdk-lib": "^2.
|
|
30
|
+
"aws-cdk-lib": "^2.192.0",
|
|
31
31
|
"constructs": "^10.0.0"
|
|
32
32
|
},
|
|
33
33
|
"peerDependenciesMeta": {
|
|
@@ -41,20 +41,26 @@
|
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@types/node": "^22.9.0",
|
|
43
43
|
"@types/react": "^18.3.12",
|
|
44
|
-
"aws-
|
|
44
|
+
"@types/aws-lambda": "^8.10.145",
|
|
45
|
+
"aws-cdk-lib": "^2.192.0",
|
|
46
|
+
"@aws-sdk/client-s3": "^3.600.0",
|
|
45
47
|
"@aws-sdk/client-secrets-manager": "^3.600.0",
|
|
48
|
+
"@smithy/util-stream": "^3.0.0 || ^4.0.0",
|
|
49
|
+
"aws-sdk-client-mock": "^4.0.0",
|
|
46
50
|
"constructs": "^10.0.0",
|
|
47
51
|
"esbuild": "^0.25.0",
|
|
52
|
+
"tsx": "^4.19.0",
|
|
48
53
|
"typescript": "^5.6.3",
|
|
49
54
|
"vitest": "^4.1.0",
|
|
50
|
-
"canopycms": "0.0.
|
|
51
|
-
"canopycms-auth-clerk": "0.0.
|
|
55
|
+
"canopycms": "0.0.58",
|
|
56
|
+
"canopycms-auth-clerk": "0.0.58"
|
|
52
57
|
},
|
|
53
58
|
"scripts": {
|
|
54
59
|
"build": "tsc",
|
|
55
60
|
"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);\"",
|
|
56
|
-
"
|
|
61
|
+
"build:lambda": "node lambda/asset-transform/build.mjs",
|
|
62
|
+
"lint": "eslint src/ 'lambda/**/*.ts' 'canary/**/*.ts'",
|
|
57
63
|
"test": "vitest run",
|
|
58
|
-
"typecheck": "tsc --noEmit"
|
|
64
|
+
"typecheck": "tsc --noEmit && tsc --noEmit -p lambda/tsconfig.json && tsc --noEmit -p canary/tsconfig.json"
|
|
59
65
|
}
|
|
60
66
|
}
|