canopycms-cdk 0.0.67-int.90 → 0.0.67-int.91
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 -269
- package/dist/constructs/asset-support.js +275 -455
- package/dist/constructs/cms-distribution.d.ts +23 -40
- package/dist/constructs/cms-distribution.js +61 -88
- package/dist/constructs/cms-service.d.ts +38 -60
- package/dist/constructs/cms-service.js +246 -390
- package/dist/constructs/lambda-execution-role.d.ts +23 -39
- package/dist/constructs/lambda-execution-role.js +37 -60
- package/dist/index.js +0 -2
- package/dist/worker.d.ts +0 -2
- package/dist/worker.js +0 -2
- package/lambda/asset-transform/dist/handler.js +33 -49
- package/lambda/asset-transform/dist/node_modules/.package-lock.json +38 -38
- package/lambda/asset-transform/dist/node_modules/@img/sharp-libvips-linux-arm64/README.md +1 -1
- package/lambda/asset-transform/dist/node_modules/@img/sharp-libvips-linux-arm64/lib/glib-2.0/include/glibconfig.h +2 -2
- package/lambda/asset-transform/dist/node_modules/@img/sharp-libvips-linux-arm64/lib/{libvips-cpp.so.8.18.6 → libvips-cpp.so.8.18.7} +0 -0
- package/lambda/asset-transform/dist/node_modules/@img/sharp-libvips-linux-arm64/package.json +2 -2
- package/lambda/asset-transform/dist/node_modules/@img/sharp-libvips-linux-arm64/versions.json +11 -11
- package/lambda/asset-transform/dist/node_modules/@img/sharp-linux-arm64/index.cjs +1 -1
- package/lambda/asset-transform/dist/node_modules/@img/sharp-linux-arm64/lib/{sharp-linux-arm64-0.35.4.node → sharp-linux-arm64-0.35.5.node} +0 -0
- package/lambda/asset-transform/dist/node_modules/@img/sharp-linux-arm64/package.json +2 -2
- package/lambda/asset-transform/dist/node_modules/@img/sharp-wasm32/index.cjs +1 -1
- package/lambda/asset-transform/dist/node_modules/@img/sharp-wasm32/lib/sharp-wasm32-0.35.5.node.js +1 -0
- package/lambda/asset-transform/dist/node_modules/@img/sharp-wasm32/lib/{sharp-wasm32-0.35.4.node.wasm → sharp-wasm32-0.35.5.node.wasm} +0 -0
- package/lambda/asset-transform/dist/node_modules/@img/sharp-wasm32/package.json +1 -1
- package/lambda/asset-transform/dist/node_modules/@img/sharp-wasm32/versions.json +7 -7
- package/lambda/asset-transform/dist/node_modules/sharp/dist/index.d.cts +2 -2
- package/lambda/asset-transform/dist/node_modules/sharp/dist/index.d.mts +3 -3
- package/lambda/asset-transform/dist/node_modules/sharp/dist/is.cjs +8 -2
- package/lambda/asset-transform/dist/node_modules/sharp/dist/is.mjs +8 -2
- package/lambda/asset-transform/dist/node_modules/sharp/dist/operation.cjs +2 -2
- package/lambda/asset-transform/dist/node_modules/sharp/dist/operation.mjs +2 -2
- package/lambda/asset-transform/dist/node_modules/sharp/dist/output.cjs +1 -0
- package/lambda/asset-transform/dist/node_modules/sharp/dist/output.mjs +1 -0
- package/lambda/asset-transform/dist/node_modules/sharp/dist/resize.cjs +14 -14
- package/lambda/asset-transform/dist/node_modules/sharp/dist/resize.mjs +14 -14
- package/lambda/asset-transform/dist/node_modules/sharp/dist/sharp.cjs +3 -3
- package/lambda/asset-transform/dist/node_modules/sharp/dist/sharp.mjs +3 -3
- package/lambda/asset-transform/dist/node_modules/sharp/lib/index.d.ts +2 -2
- package/lambda/asset-transform/dist/node_modules/sharp/package.json +35 -35
- package/lambda/asset-transform/dist/node_modules/sharp/src/binding.gyp +1 -1
- package/lambda/asset-transform/dist/node_modules/sharp/src/common.cc +4 -4
- package/lambda/asset-transform/dist/node_modules/sharp/src/common.h +2 -2
- package/lambda/asset-transform/dist/node_modules/sharp/src/pipeline.cc +31 -6
- package/lambda/asset-transform/dist/node_modules/sharp/src/utilities.cc +1 -1
- package/package.json +4 -4
- package/worker/dist/index.js +251 -364
- package/lambda/asset-transform/dist/node_modules/@img/sharp-wasm32/lib/sharp-wasm32-0.35.4.node.js +0 -1
|
@@ -11,15 +11,13 @@ export interface AssetUploadBehaviorOptions {
|
|
|
11
11
|
* this behavior alone.
|
|
12
12
|
*
|
|
13
13
|
* `['*']` by default, and a wildcard is defensible HERE in a way a
|
|
14
|
-
* bucket-wide CORS rule is not, because **the edge authorises nothing**:
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* Narrow it to your editor origin(s) if you would rather; nothing else here
|
|
22
|
-
* depends on the wildcard.
|
|
14
|
+
* bucket-wide CORS rule is not, because **the edge authorises nothing**: a
|
|
15
|
+
* presigned POST with a corrupted signature sent through this exact path
|
|
16
|
+
* returns 403 and nothing lands. Authority is entirely the presigned policy,
|
|
17
|
+
* which pins the bucket, the exact key, the content type, a size range and a
|
|
18
|
+
* 15-minute expiry. So the wildcard widens who may READ the response, not who
|
|
19
|
+
* may write - and the response is an empty 204. Narrow it to your editor
|
|
20
|
+
* origin(s) if you would rather; nothing else here depends on it.
|
|
23
21
|
*
|
|
24
22
|
* ORIGINS ARE MATCHED EXACTLY, and `'*'` is honoured only as the sole entry.
|
|
25
23
|
* CloudFront's response headers policy would accept a leftmost-subdomain
|
|
@@ -58,12 +56,10 @@ export interface AssetSupportProps {
|
|
|
58
56
|
* `Access-Control-Allow-Origin` from the edge instead, so no bucket rule is
|
|
59
57
|
* written and no exact origin has to be named anywhere.
|
|
60
58
|
*
|
|
61
|
-
* Optional
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
* rejects a CORS rule with no origins, so it can only ever have been a
|
|
66
|
-
* mistake.
|
|
59
|
+
* Optional, but standalone mode refuses to synth with NEITHER, because the
|
|
60
|
+
* resulting failure is a genuinely misleading one (see the error's own text).
|
|
61
|
+
* An empty array counts as absent: CloudFormation rejects a CORS rule with no
|
|
62
|
+
* origins, so it can only ever have been a mistake.
|
|
67
63
|
*
|
|
68
64
|
* @default - no bucket CORS rule; standalone mode then requires `uploadBehavior`
|
|
69
65
|
*/
|
|
@@ -71,37 +67,30 @@ export interface AssetSupportProps {
|
|
|
71
67
|
/**
|
|
72
68
|
* Build a CloudFront behavior that accepts the editor's presigned-POST
|
|
73
69
|
* uploads - the infrastructure half of `media.uploadUrl` (see the README's
|
|
74
|
-
* "Routing uploads through your own CDN"). Retrieve
|
|
75
|
-
* `uploadBehavior()`, which
|
|
76
|
-
*
|
|
77
|
-
* OFF unless set, and deliberately so: this is the only thing in this
|
|
70
|
+
* "Routing uploads through your own CDN"). Retrieve it with
|
|
71
|
+
* `uploadBehavior()`, which documents the distribution it belongs on. OFF
|
|
72
|
+
* unless set, and deliberately so: this is the only thing in this
|
|
78
73
|
* construct that puts a write-capable, OAC-UNSIGNED origin in front of the
|
|
79
|
-
* bucket, and that must never
|
|
80
|
-
* `uploadBehavior: {}`
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
* this one is a custom origin and does not, so S3's 301 reaches the
|
|
100
|
-
* browser, where a redirected cross-origin POST surfaces as an opaque
|
|
101
|
-
* network error. Import a cross-region bucket with
|
|
102
|
-
* `Bucket.fromBucketAttributes({ region })` so the domain name is right.
|
|
103
|
-
* 3. A DOT in the bucket name breaks this origin specifically - refused at
|
|
104
|
-
* synth, with the reason, in `buildUploadBehavior`.
|
|
74
|
+
* bucket, and that must never reach a template by accident. Pass
|
|
75
|
+
* `uploadBehavior: {}` for the defaults. BYO-BUCKET CAVEATS:
|
|
76
|
+
*
|
|
77
|
+
* 1. YOUR BUCKET POLICY IS THE ONLY GATE ON THIS ROUTE. The read behaviors go
|
|
78
|
+
* through an OAC-SIGNED origin, so a permissive policy there is still
|
|
79
|
+
* gated by a signature CloudFront adds; this origin cannot be signed
|
|
80
|
+
* (CloudFront never hashes the body, so an OAC-signed origin rejects every
|
|
81
|
+
* multipart POST). The route is contained by rewriting every request to
|
|
82
|
+
* `/`, so what your policy grants anonymously AT THE BUCKET ROOT is what is
|
|
83
|
+
* reachable. A bucket this construct creates refuses all of it (BLOCK_ALL,
|
|
84
|
+
* no public policy); an existing one is yours, and a read path that already
|
|
85
|
+
* works is not evidence that it is right.
|
|
86
|
+
* 2. This origin addresses the bucket by `bucketRegionalDomainName`, which for
|
|
87
|
+
* a bucket imported with `Bucket.fromBucketName()` resolves to the STACK's
|
|
88
|
+
* region, not the bucket's. The read path tolerates a mismatch because
|
|
89
|
+
* CloudFront follows S3's region redirect on an S3-type origin; this custom
|
|
90
|
+
* origin does not, so S3's 301 reaches the browser as an opaque network
|
|
91
|
+
* error. Import cross-region with `Bucket.fromBucketAttributes({ region })`.
|
|
92
|
+
* 3. A DOT in the bucket name breaks this origin; `buildUploadBehavior`
|
|
93
|
+
* refuses it at synth, with the reason.
|
|
105
94
|
*
|
|
106
95
|
* @default - no upload behavior is built
|
|
107
96
|
*/
|
|
@@ -144,12 +133,11 @@ export interface AssetSupportProps {
|
|
|
144
133
|
* `build:lambda`). Leave this ON for anything that can reach a real
|
|
145
134
|
* deploy.
|
|
146
135
|
*
|
|
147
|
-
* Set to `false` ONLY in this package's own tests, which
|
|
148
|
-
*
|
|
149
|
-
*
|
|
150
|
-
*
|
|
151
|
-
*
|
|
152
|
-
* run (which is what kept these tests out of CI in the first place).
|
|
136
|
+
* Set to `false` ONLY in this package's own tests, which synth against the
|
|
137
|
+
* cheap `--skip-native` fixture bundle `build:test-fixtures` produces: the
|
|
138
|
+
* suite never executes the handler, so the binary is irrelevant to what it
|
|
139
|
+
* asserts, and requiring a real build would put a live `npm install sharp` in
|
|
140
|
+
* front of every test run and price the suite out of CI.
|
|
153
141
|
*
|
|
154
142
|
* Adopters never need this: the published package's asset is built by
|
|
155
143
|
* `prepack`'s full `build:lambda`, so the marker is always present.
|
|
@@ -186,26 +174,21 @@ export interface AssetSupportProps {
|
|
|
186
174
|
* Execution role for the transform Lambda (default: CDK creates one).
|
|
187
175
|
*
|
|
188
176
|
* Set this when the role's ARN has to be computable WITHOUT a reference to
|
|
189
|
-
* this construct - the case
|
|
190
|
-
*
|
|
191
|
-
*
|
|
192
|
-
*
|
|
177
|
+
* this construct - the motivating case is an asset bucket in a different AWS
|
|
178
|
+
* account from the compute, where the resource-policy half of the
|
|
179
|
+
* cross-account grant is written in the bucket's own stack and needs the
|
|
180
|
+
* principal as a plain string. Reading `transformFunction.role` across an
|
|
193
181
|
* account boundary does not give you that: CDK emits `Fn::GetStackOutput`, a
|
|
194
|
-
* CDK-CLI-only intrinsic resolved at deploy time, so the coupling is
|
|
195
|
-
*
|
|
196
|
-
*
|
|
197
|
-
*
|
|
198
|
-
*
|
|
199
|
-
*
|
|
200
|
-
* A named IAM role means the consuming stack needs `CAPABILITY_NAMED_IAM`,
|
|
201
|
-
* and cannot be replaced in place without a rename - that trade is yours to
|
|
202
|
-
* make here, which is the point of taking a role rather than a name.
|
|
182
|
+
* CDK-CLI-only intrinsic resolved at deploy time, so the coupling is invisible
|
|
183
|
+
* to CloudFormation and unusable by any deploy path that is not `cdk deploy`.
|
|
184
|
+
* A deterministically NAMED role lets both stacks compute
|
|
185
|
+
* `arn:aws:iam::<account>:role/<name>` from literals instead, with nothing
|
|
186
|
+
* crossing between them - at the cost of `CAPABILITY_NAMED_IAM` in the
|
|
187
|
+
* consuming stack and no in-place replacement without a rename.
|
|
203
188
|
*
|
|
204
189
|
* `iam.Role`, not `iam.IRole`, ON PURPOSE - an imported role silently
|
|
205
190
|
* discards the managed policies this construct has to re-attach. See
|
|
206
|
-
* `attachLambdaExecutionPolicies` (./lambda-execution-role)
|
|
207
|
-
* drops when a role is passed, and why the narrower type is what makes the
|
|
208
|
-
* compensation reliable.
|
|
191
|
+
* `attachLambdaExecutionPolicies` (./lambda-execution-role).
|
|
209
192
|
*/
|
|
210
193
|
readonly transformRole?: iam.Role;
|
|
211
194
|
/**
|
|
@@ -240,15 +223,13 @@ export declare const ASSETS_TRANSFORM_PATH_PATTERN: string;
|
|
|
240
223
|
* instead. Exported so `cms-distribution.ts`'s synth-time guard can
|
|
241
224
|
* recognize the mistake and name it in its error.
|
|
242
225
|
*
|
|
243
|
-
* `uploadBehavior()` deliberately adds NO key here
|
|
244
|
-
*
|
|
245
|
-
*
|
|
246
|
-
*
|
|
247
|
-
*
|
|
248
|
-
*
|
|
249
|
-
*
|
|
250
|
-
* Keep this list to property names that actually exist on
|
|
251
|
-
* `AssetCloudFrontBehaviors`.
|
|
226
|
+
* `uploadBehavior()` deliberately adds NO key here: it returns a bare
|
|
227
|
+
* `BehaviorOptions` rather than a named property, so there is no spread to get
|
|
228
|
+
* wrong, and a speculative `'upload'` entry would misfire on an adopter whose
|
|
229
|
+
* distribution has a real upload route - CloudFront treats a path pattern's
|
|
230
|
+
* leading slash as optional, so `upload` is a legal spelling of `/upload` (see
|
|
231
|
+
* `normalizePathPattern` in cms-distribution.ts). Keep this list to property
|
|
232
|
+
* names that actually exist on `AssetCloudFrontBehaviors`.
|
|
252
233
|
*/
|
|
253
234
|
export declare const ASSET_BEHAVIOR_SPREAD_MISTAKE_KEYS: readonly ["assets", "assetsTransform"];
|
|
254
235
|
/**
|
|
@@ -257,29 +238,21 @@ export declare const ASSET_BEHAVIOR_SPREAD_MISTAKE_KEYS: readonly ["assets", "as
|
|
|
257
238
|
* (origin included).
|
|
258
239
|
*
|
|
259
240
|
* Prefer `AssetSupport.attachTo(distribution)` or `CanopyCmsDistribution`'s
|
|
260
|
-
* `assetSupport` prop over consuming this directly - both encode the
|
|
261
|
-
*
|
|
262
|
-
*
|
|
263
|
-
* ESCAPE HATCH for a
|
|
264
|
-
*
|
|
265
|
-
*
|
|
266
|
-
*
|
|
267
|
-
* `CanopyCmsDistribution`'s synth-time guard (`mergeBehaviors`) actively
|
|
268
|
-
* rejects three ways this goes wrong: `/assets/*` listed before
|
|
269
|
-
* `/assets/t/*`; the literal keys `assets`/`assetsTransform` (see
|
|
270
|
-
* `ASSET_BEHAVIOR_SPREAD_MISTAKE_KEYS`) from spreading this object directly
|
|
271
|
-
* into a `Record`; or an asset pattern listed here at all while
|
|
272
|
-
* `CanopyCmsDistribution`'s `assetSupport` prop is also passed. See
|
|
273
|
-
* `assertNoAssetBehaviorOrderingHazards`'s doc comment for the full list.
|
|
241
|
+
* `assetSupport` prop over consuming this directly - both encode the required
|
|
242
|
+
* attachment order in exactly one place, and the latter's synth-time guard
|
|
243
|
+
* rejects the three ways manual wiring goes wrong (see
|
|
244
|
+
* `assertNoAssetBehaviorOrderingHazards`). This value is the ESCAPE HATCH for a
|
|
245
|
+
* bespoke `new cloudfront.Distribution(...)` assembled entirely inline, whose
|
|
246
|
+
* `additionalBehaviors` is fixed at construction with no distribution yet to
|
|
247
|
+
* call `addBehavior` on - there you own the ordering:
|
|
274
248
|
*
|
|
275
249
|
* ```ts
|
|
276
250
|
* const behaviors = assetSupport.assetBehaviors()
|
|
277
251
|
*
|
|
278
|
-
* //
|
|
279
|
-
* //
|
|
280
|
-
* //
|
|
281
|
-
* //
|
|
282
|
-
* // 403 with no Lambda fallback.
|
|
252
|
+
* // CloudFront matches path patterns in the order listed and stops at the
|
|
253
|
+
* // first match, so the more specific '/assets/t/*' MUST come before
|
|
254
|
+
* // '/assets/*' - otherwise the broader S3-only pattern swallows transform
|
|
255
|
+
* // requests and they 403 with no Lambda fallback.
|
|
283
256
|
* new cloudfront.Distribution(this, 'Dist', {
|
|
284
257
|
* defaultBehavior: ...,
|
|
285
258
|
* additionalBehaviors: {
|
|
@@ -301,9 +274,8 @@ export interface AssetCloudFrontBehaviors {
|
|
|
301
274
|
* `/assets/t/*` - transform outputs specifically. Origin group: the same
|
|
302
275
|
* S3 origin as `assets` primary, falling over to the transform Lambda's
|
|
303
276
|
* Function URL on 403 OR 404 (a signed OAC origin reports a miss as 403;
|
|
304
|
-
* configuring both is defense-in-depth).
|
|
305
|
-
*
|
|
306
|
-
* confirmed working with CloudFront caching the failover response.
|
|
277
|
+
* configuring both is defense-in-depth). CloudFront caches the failover
|
|
278
|
+
* response.
|
|
307
279
|
*/
|
|
308
280
|
readonly assetsTransform: cloudfront.BehaviorOptions;
|
|
309
281
|
}
|
|
@@ -339,82 +311,28 @@ export interface AssetUploadBehaviorRouteOptions extends AssetUploadBehaviorOpti
|
|
|
339
311
|
* // media.uploadUrl = `https://${uploads.distributionDomainName}/`
|
|
340
312
|
* ```
|
|
341
313
|
*
|
|
342
|
-
*
|
|
343
|
-
*
|
|
344
|
-
*
|
|
345
|
-
*
|
|
346
|
-
*
|
|
347
|
-
*
|
|
348
|
-
*
|
|
349
|
-
*
|
|
350
|
-
*
|
|
351
|
-
*
|
|
352
|
-
* because the opposite is easy to assume: those grants do NOT land in the
|
|
353
|
-
* bucket policy. `Grant.addToPrincipalOrResource` (aws-cdk-lib,
|
|
354
|
-
* `aws-iam/lib/grant.ts`) adds the identity statement first and returns right
|
|
355
|
-
* there when two things hold - the identity statement was actually added, AND
|
|
356
|
-
* the grantee's account is known to match the resource's (`TokenComparison`
|
|
357
|
-
* SAME, or both unresolved). Only when one of those fails does it also write a
|
|
358
|
-
* resource statement. A same-account Lambda with a CDK-managed role satisfies
|
|
359
|
-
* both, so its grants go to that function's OWN execution role and nowhere
|
|
360
|
-
* else. Measured on a synthesized template, an owned bucket plus a
|
|
361
|
-
* same-account `AssetSupport` emits no `AWS::S3::BucketPolicy` at all.
|
|
362
|
-
* Deleting the construct therefore takes the whole footprint with it and
|
|
363
|
-
* leaves nothing behind on a shared bucket's policy.
|
|
364
|
-
*
|
|
365
|
-
* Nor does the cross-account shape invert it, which is the obvious next
|
|
366
|
-
* guess and is also wrong. Measured across all three shapes - an owned
|
|
367
|
-
* bucket, one imported by name, and one imported by ARN with an explicitly
|
|
368
|
-
* DIFFERENT account - every one emits zero `AWS::S3::BucketPolicy`. The
|
|
369
|
-
* second half of `addToPrincipalOrResource` does run for an import, but
|
|
370
|
-
* `addToResourcePolicy` on a bucket CDK does not own is a no-op: it cannot
|
|
371
|
-
* write a policy onto a resource it did not create. So a cross-account
|
|
372
|
-
* adopter gets the identity half here and writes the resource half
|
|
373
|
-
* themselves, on the bucket's own side.
|
|
374
|
-
*
|
|
375
|
-
* What it costs instead is legibility: a second `AssetSupport` standing in a
|
|
376
|
-
* stack that has no asset pipeline, existing only so that a method can be
|
|
377
|
-
* called on it, is fine on the day and unexplainable six months later. That
|
|
378
|
-
* is what this function removes, and it matters most for the shape the
|
|
379
|
-
* one-route topology invites - one bucket shared by every environment, owned
|
|
380
|
-
* by a stack that holds no per-environment resources, with reads and
|
|
381
|
-
* transforms staying per-environment.
|
|
382
|
-
*
|
|
383
|
-
* `AssetSupport.uploadBehavior()` remains the right call when you already have
|
|
384
|
-
* an `AssetSupport`; both funnel into the same builder, so the two cannot
|
|
385
|
-
* drift.
|
|
386
|
-
*
|
|
387
|
-
* TWO THINGS TO KNOW ABOUT `scope`. It receives the CloudFront Function and
|
|
388
|
-
* the two policies as children under fixed ids, so calling this twice with
|
|
389
|
-
* the SAME scope throws CDK's duplicate-construct-id error rather than
|
|
390
|
-
* returning a second behavior - one call per scope. And because the children
|
|
391
|
-
* hang off `scope`, moving an EXISTING deployment from
|
|
392
|
-
* `AssetSupport.uploadBehavior()` to this function changes their construct
|
|
393
|
-
* path and therefore their logical IDs, which replaces all three CloudFront
|
|
394
|
-
* resources. There is no reason to make that move on a stack that already has
|
|
395
|
-
* an `AssetSupport`; this function is for the stack that would otherwise have
|
|
396
|
-
* to grow one.
|
|
397
|
-
*
|
|
398
|
-
* TWO THINGS THIS DOES NOT DO, both deliberate:
|
|
314
|
+
* Separate from `AssetSupport.uploadBehavior()` because the upload route needs
|
|
315
|
+
* the bucket and nothing else, while that construct's CONSTRUCTOR always builds
|
|
316
|
+
* the transform Lambda, a log group, a Function URL, a role and prefix grants.
|
|
317
|
+
* Those grants never reach the BUCKET policy: `Grant.addToPrincipalOrResource`
|
|
318
|
+
* stops after the identity statement for a same-account grantee, and
|
|
319
|
+
* `addToResourcePolicy` on a bucket CDK does not own is a no-op - an owned
|
|
320
|
+
* bucket, one imported by name, and one imported by ARN in another account all
|
|
321
|
+
* emit zero `AWS::S3::BucketPolicy`, so a cross-account adopter writes the
|
|
322
|
+
* resource half on the bucket's own side. Prefer the method when you already
|
|
323
|
+
* have an `AssetSupport`; both funnel into the same builder and cannot drift.
|
|
399
324
|
*
|
|
400
|
-
*
|
|
401
|
-
*
|
|
402
|
-
*
|
|
403
|
-
*
|
|
404
|
-
*
|
|
405
|
-
*
|
|
406
|
-
* distribution". `AssetSupport` has one, but it fires only in standalone
|
|
407
|
-
* mode with no `editorOrigins` - where opting into `uploadBehavior` is what
|
|
408
|
-
* satisfied the "something must supply ACAO" guard, so opting in and
|
|
409
|
-
* stopping leaves a bucket with neither. A caller here always brings their
|
|
410
|
-
* own bucket and never passes through that guard, so there is no invariant
|
|
411
|
-
* to protect: a discarded return value is an obviously unfinished call, not
|
|
412
|
-
* a silently broken one.
|
|
325
|
+
* No bucket CORS rule is written and none is needed: the edge supplies
|
|
326
|
+
* `Access-Control-Allow-Origin`, and S3's ACCEPTANCE of a presigned POST is
|
|
327
|
+
* independent of its ADVERTISEMENT of CORS, which is all a bucket rule governs
|
|
328
|
+
* (`AssetSupportProps.editorOrigins` writes one, for the construct). No
|
|
329
|
+
* "built but never attached" guard either: a caller here brings their own
|
|
330
|
+
* bucket, so never reaches the construct's "something must supply ACAO" guard.
|
|
413
331
|
*/
|
|
414
332
|
export declare function assetUploadBehavior(scope: Construct, options: AssetUploadBehaviorRouteOptions): cloudfront.BehaviorOptions;
|
|
415
333
|
/**
|
|
416
334
|
* Per-site CDK construct for the asset/media delivery system (see
|
|
417
|
-
* `.claude/future-tasks/assets-media-system.md` for the full design record).
|
|
335
|
+
* `.claude/future-tasks/resolved/assets-media-system.md` for the full design record).
|
|
418
336
|
* Wires:
|
|
419
337
|
*
|
|
420
338
|
* - The bucket's asset-prefix lifecycle rule + CORS (standalone mode only).
|
|
@@ -438,7 +356,6 @@ export declare function assetUploadBehavior(scope: Construct, options: AssetUplo
|
|
|
438
356
|
export declare class AssetSupport extends Construct {
|
|
439
357
|
/** The bucket in use (either created here, or the BYO `props.bucket`). */
|
|
440
358
|
readonly bucket: s3.IBucket;
|
|
441
|
-
/** The transform Lambda function. */
|
|
442
359
|
readonly transformFunction: lambda.Function;
|
|
443
360
|
/** The transform Lambda's CloudWatch log group (Lambda stdout/stderr). */
|
|
444
361
|
readonly transformLogGroup: logs.LogGroup;
|
|
@@ -453,14 +370,12 @@ export declare class AssetSupport extends Construct {
|
|
|
453
370
|
* Memoized on the first `uploadBehavior()` call, NOT built in the
|
|
454
371
|
* constructor. Opting in creates three CloudFront resources (function,
|
|
455
372
|
* origin request policy, response headers policy) and response headers
|
|
456
|
-
* policies have a default account quota of 20
|
|
373
|
+
* policies have a default account quota of 20, so an adopter who sets the
|
|
457
374
|
* prop on a per-environment `AssetSupport` while building the single shared
|
|
458
375
|
* upload distribution the accessor recommends would otherwise mint a set per
|
|
459
|
-
* environment for one route. Deferring is invisible
|
|
460
|
-
*
|
|
461
|
-
*
|
|
462
|
-
* refuses that with `ConstructTreeModifiedAfterSynth` naming the constructs
|
|
463
|
-
* added. Loud, not silent.
|
|
376
|
+
* environment for one route. Deferring is invisible except that calling the
|
|
377
|
+
* accessor AFTER a synth has run modifies the construct tree, which CDK
|
|
378
|
+
* refuses with `ConstructTreeModifiedAfterSynth`. Loud, not silent.
|
|
464
379
|
*/
|
|
465
380
|
private upload?;
|
|
466
381
|
/**
|
|
@@ -477,17 +392,13 @@ export declare class AssetSupport extends Construct {
|
|
|
477
392
|
/**
|
|
478
393
|
* The two CloudFront behavior configs this system needs.
|
|
479
394
|
*
|
|
480
|
-
*
|
|
481
|
-
*
|
|
482
|
-
*
|
|
483
|
-
*
|
|
484
|
-
*
|
|
485
|
-
*
|
|
486
|
-
*
|
|
487
|
-
* `assetSupport` prop, which attach these to a distribution in the only
|
|
488
|
-
* safe order automatically. This method exists as the escape hatch for a
|
|
489
|
-
* distribution assembled entirely by hand - see `AssetCloudFrontBehaviors`'s
|
|
490
|
-
* doc comment for that shape and its ordering requirements.
|
|
395
|
+
* Prefer `attachTo(distribution)` or `CanopyCmsDistribution`'s `assetSupport`
|
|
396
|
+
* prop, which attach these in the only safe order automatically; `attachTo`
|
|
397
|
+
* takes an `overrides` parameter, so needing per-behavior options is not a
|
|
398
|
+
* reason to fall back here. Use this only for a distribution assembled
|
|
399
|
+
* entirely by hand - you then own the ordering, and should assert it against
|
|
400
|
+
* the SYNTHESIZED template's `CacheBehaviors` array index rather than your own
|
|
401
|
+
* source object, since the property is about emitted order.
|
|
491
402
|
*/
|
|
492
403
|
assetBehaviors(): AssetCloudFrontBehaviors;
|
|
493
404
|
/**
|
|
@@ -503,95 +414,52 @@ export declare class AssetSupport extends Construct {
|
|
|
503
414
|
* })
|
|
504
415
|
* // media.uploadUrl = `https://${uploads.distributionDomainName}/`
|
|
505
416
|
* ```
|
|
506
|
-
*
|
|
507
|
-
*
|
|
508
|
-
*
|
|
509
|
-
*
|
|
510
|
-
*
|
|
511
|
-
*
|
|
512
|
-
*
|
|
513
|
-
*
|
|
514
|
-
*
|
|
515
|
-
* - NOT a behavior on the site's own distribution. `CustomErrorResponses`
|
|
516
|
-
* are distribution-wide, so a site that maps 403 to its own 404 page
|
|
517
|
-
* applies that to S3's upload errors too and the editor reports the
|
|
518
|
-
* substituted status. The site's cookies and any cached basic-auth
|
|
519
|
-
* credential are also live hazards there that have to be stripped by
|
|
520
|
-
* policy and function (`buildUploadBehavior` removes both - cookies via
|
|
521
|
-
* the origin request policy, `Authorization` in the viewer-request
|
|
522
|
-
* function) rather than simply never
|
|
523
|
-
* being sent. It works; it is just strictly worse.
|
|
417
|
+
* No custom domain or certificate is needed, and as the default behavior of a
|
|
418
|
+
* one-route distribution there is no path pattern, so no ordering question of
|
|
419
|
+
* the kind `attachTo()` settles. Two shapes this deliberately is NOT:
|
|
420
|
+
*
|
|
421
|
+
* - NOT a behavior on the site's own distribution. `CustomErrorResponses` are
|
|
422
|
+
* distribution-wide, so a site mapping 403 to its own 404 page applies that
|
|
423
|
+
* to S3's upload errors and the editor reports the substituted status; the
|
|
424
|
+
* site's cookies and any cached basic-auth credential are live hazards
|
|
425
|
+
* there, stripped by policy and function rather than never sent at all.
|
|
524
426
|
* - NOT one shared distribution serving asset reads AND writes for every
|
|
525
|
-
* environment.
|
|
526
|
-
*
|
|
527
|
-
*
|
|
528
|
-
*
|
|
529
|
-
*
|
|
530
|
-
* traded away for an upload path. Reads and transforms stay
|
|
531
|
-
* per-environment; only the upload route moves.
|
|
532
|
-
*
|
|
533
|
-
* The upload route is the one part of this system with no per-environment
|
|
534
|
-
* code in it - it depends on the bucket and nothing else - which is why it
|
|
535
|
-
* is the part that can be split off this way.
|
|
536
|
-
*
|
|
537
|
-
* That same property is why `assetUploadBehavior` exists as a free function:
|
|
538
|
-
* it builds this behavior from a bucket alone, for a caller who wants the
|
|
539
|
-
* one-route distribution above and has no other use for an `AssetSupport`.
|
|
540
|
-
* Prefer this method when you already have one; both funnel into the same
|
|
541
|
-
* builder. See that function for what instantiating the construct purely to
|
|
542
|
-
* reach this method actually costs.
|
|
427
|
+
* environment. That means one `AssetSupport`, which owns the transform
|
|
428
|
+
* Lambda shipping inside this package, so a `canopycms-cdk` bump would move
|
|
429
|
+
* every environment's asset pipeline at once. Only the upload route moves;
|
|
430
|
+
* it depends on the bucket and nothing else, the same property that lets
|
|
431
|
+
* `assetUploadBehavior` build it from a bucket alone.
|
|
543
432
|
*/
|
|
544
433
|
uploadBehavior(): cloudfront.BehaviorOptions;
|
|
545
434
|
/**
|
|
546
435
|
* Attach both asset behaviors to a concrete CloudFront distribution, in the
|
|
547
436
|
* only safe order.
|
|
548
437
|
*
|
|
549
|
-
*
|
|
550
|
-
*
|
|
551
|
-
* pattern
|
|
552
|
-
*
|
|
553
|
-
*
|
|
554
|
-
*
|
|
555
|
-
* also
|
|
556
|
-
*
|
|
557
|
-
*
|
|
558
|
-
*
|
|
559
|
-
*
|
|
560
|
-
*
|
|
561
|
-
*
|
|
562
|
-
*
|
|
563
|
-
*
|
|
564
|
-
*
|
|
565
|
-
*
|
|
566
|
-
*
|
|
567
|
-
*
|
|
568
|
-
*
|
|
569
|
-
*
|
|
570
|
-
*
|
|
571
|
-
*
|
|
572
|
-
*
|
|
573
|
-
*
|
|
574
|
-
* story for a repo with a shared security-headers policy.)
|
|
575
|
-
*
|
|
576
|
-
* Merged into both rather than per-behavior on purpose: applying one set to
|
|
577
|
-
* both is what preserves the ordering guarantee as the only thing this
|
|
578
|
-
* method decides. A caller who genuinely needs the two behaviors to differ
|
|
579
|
-
* has left this method's remit and should use `assetBehaviors()` - and keep
|
|
580
|
-
* their own ordering assertion.
|
|
581
|
-
*
|
|
582
|
-
* Typed `Partial<AddBehaviorOptions>`, not `BehaviorOptions`, because
|
|
583
|
-
* `addBehavior` takes `origin` positionally - so an `origin` key here would be
|
|
584
|
-
* a silently ignored no-op. (Measured: passing one changes nothing in the
|
|
585
|
-
* emitted template. It is a confusing no-op being prevented, not a broken
|
|
586
|
-
* origin group.)
|
|
587
|
-
*
|
|
588
|
-
* Needs a concrete `cloudfront.Distribution` - `addBehavior` is an instance
|
|
589
|
-
* method on that class, not on `IDistribution` (what an imported/looked-up
|
|
590
|
-
* distribution reference gives you). For a distribution built entirely
|
|
591
|
-
* inline (its `additionalBehaviors` fixed at construction, with no
|
|
592
|
-
* distribution yet to call `addBehavior` on), call `assetBehaviors()`
|
|
593
|
-
* directly instead and list `/assets/t/*` before `/assets/*` yourself - see
|
|
594
|
-
* `AssetCloudFrontBehaviors`'s doc comment.
|
|
438
|
+
* THE ORDER IS THE WHOLE POINT. CloudFront matches path patterns in the order
|
|
439
|
+
* given and stops at the first match. `/assets/*` is a broader, S3-only
|
|
440
|
+
* pattern that also matches every `/assets/t/*` request; `/assets/t/*` is an
|
|
441
|
+
* origin group that fails over to the transform Lambda on a miss. Attach
|
|
442
|
+
* `/assets/*` first and every never-yet-computed transform gets a permanent
|
|
443
|
+
* 403 (an OAC-signed S3 miss reports 403) while already-computed transforms
|
|
444
|
+
* keep working. `'/assets/*'` also sorts BEFORE `'/assets/t/*'`
|
|
445
|
+
* lexicographically (`*` = 0x2A, `t` = 0x74), so alphabetizing the keys
|
|
446
|
+
* reproduces exactly this failure with no synth or deploy error to catch it -
|
|
447
|
+
* and `assetBehaviors()` attaches no path pattern, so nothing there stops a
|
|
448
|
+
* caller getting it wrong.
|
|
449
|
+
*
|
|
450
|
+
* `overrides` is merged into BOTH behaviors. The motivating case is a
|
|
451
|
+
* distribution running a viewer-request function on every behavior - tier
|
|
452
|
+
* basic-auth - where without the same `functionAssociations` `/assets/*` is
|
|
453
|
+
* anonymously readable on an authenticated tier (`responseHeadersPolicy` is
|
|
454
|
+
* the same story for a shared security-headers policy). One set for both is
|
|
455
|
+
* what keeps ordering the only thing this method decides; a caller who needs
|
|
456
|
+
* the two to differ should use `assetBehaviors()` and assert their own order.
|
|
457
|
+
*
|
|
458
|
+
* Typed `Partial<AddBehaviorOptions>`, not `BehaviorOptions`: `addBehavior`
|
|
459
|
+
* takes `origin` positionally, so an `origin` key here is a silent no-op. It
|
|
460
|
+
* needs a concrete `cloudfront.Distribution` too - `addBehavior` is an
|
|
461
|
+
* instance method on that class, not on `IDistribution`. For a distribution
|
|
462
|
+
* built entirely inline, call `assetBehaviors()` and order it yourself.
|
|
595
463
|
*/
|
|
596
464
|
attachTo(distribution: cloudfront.Distribution, overrides?: Partial<cloudfront.AddBehaviorOptions>): void;
|
|
597
465
|
/**
|