@kensio/yulin 1.21.7 → 1.21.9

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.
Files changed (99) hide show
  1. package/README.md +22 -2
  2. package/dist/service/lambda/cfn/event-source-mapping/sim-cfn-lambda-event-source-mapping-properties.js +2 -0
  3. package/dist/service/lambda/cfn/event-source-mapping/sim-cfn-lambda-event-source-mapping-property-rules.js +1 -1
  4. package/dist/service/lambda/command/event-source-mapping/create-event-source-mapping-input.d.ts +2 -0
  5. package/dist/service/lambda/command/event-source-mapping/create-event-source-mapping-input.js +4 -0
  6. package/dist/service/lambda/command/event-source-mapping/create-event-source-mapping-refusals.js +0 -5
  7. package/dist/service/lambda/command/event-source-mapping/create-event-source-mapping.handler.d.ts +2 -0
  8. package/dist/service/lambda/command/event-source-mapping/create-event-source-mapping.handler.js +2 -0
  9. package/dist/service/lambda/command/event-source-mapping/sim-lambda-event-source-mapping-commands.d.ts +2 -0
  10. package/dist/service/lambda/destination/sim-lambda-destination-targets.d.ts +2 -1
  11. package/dist/service/lambda/event-source/poll/kinesis/sim-lambda-kinesis-shard-poller.d.ts +0 -4
  12. package/dist/service/lambda/event-source/poll/kinesis/sim-lambda-kinesis-shard-poller.js +10 -15
  13. package/dist/service/lambda/event-source/poll/sim-lambda-dynamodb-stream-event-source-poller.d.ts +1 -6
  14. package/dist/service/lambda/event-source/poll/sim-lambda-dynamodb-stream-event-source-poller.js +9 -27
  15. package/dist/service/lambda/event-source/poll/sim-lambda-dynamodb-stream-polling.d.ts +19 -0
  16. package/dist/service/lambda/event-source/poll/sim-lambda-dynamodb-stream-polling.js +27 -0
  17. package/dist/service/lambda/event-source/poll/sim-lambda-event-source-function.d.ts +1 -1
  18. package/dist/service/lambda/event-source/poll/sim-lambda-event-source-function.js +3 -1
  19. package/dist/service/lambda/event-source/poll/sim-lambda-stream-batch-age.d.ts +13 -0
  20. package/dist/service/lambda/event-source/poll/sim-lambda-stream-batch-age.js +27 -0
  21. package/dist/service/lambda/event-source/poll/sim-lambda-stream-batch-info.d.ts +15 -0
  22. package/dist/service/lambda/event-source/poll/sim-lambda-stream-batch-info.js +26 -0
  23. package/dist/service/lambda/event-source/poll/sim-lambda-stream-batch-outcome.d.ts +1 -0
  24. package/dist/service/lambda/event-source/poll/sim-lambda-stream-batch-outcome.js +7 -1
  25. package/dist/service/lambda/event-source/poll/sim-lambda-stream-batch-processing.d.ts +17 -0
  26. package/dist/service/lambda/event-source/poll/sim-lambda-stream-batch-processing.js +12 -0
  27. package/dist/service/lambda/event-source/poll/sim-lambda-stream-cursor.d.ts +15 -0
  28. package/dist/service/lambda/event-source/poll/sim-lambda-stream-cursor.js +28 -0
  29. package/dist/service/lambda/event-source/poll/sim-lambda-stream-expiry.d.ts +19 -0
  30. package/dist/service/lambda/event-source/poll/sim-lambda-stream-expiry.js +23 -0
  31. package/dist/service/lambda/event-source/poll/sim-lambda-stream-failure-context.d.ts +3 -0
  32. package/dist/service/lambda/event-source/poll/sim-lambda-stream-failure-context.js +19 -0
  33. package/dist/service/lambda/event-source/poll/sim-lambda-stream-failure-destination.d.ts +15 -0
  34. package/dist/service/lambda/event-source/poll/sim-lambda-stream-failure-destination.js +38 -0
  35. package/dist/service/lambda/event-source/poll/sim-lambda-stream-failure-record.d.ts +41 -0
  36. package/dist/service/lambda/event-source/poll/sim-lambda-stream-failure-record.js +17 -0
  37. package/dist/service/lambda/event-source/poll/sim-lambda-stream-progress-state.d.ts +21 -0
  38. package/dist/service/lambda/event-source/poll/sim-lambda-stream-progress-state.js +39 -0
  39. package/dist/service/lambda/event-source/poll/sim-lambda-stream-progress.d.ts +7 -37
  40. package/dist/service/lambda/event-source/poll/sim-lambda-stream-progress.js +22 -62
  41. package/dist/service/lambda/event-source/poll/sim-lambda-stream-retry.d.ts +4 -39
  42. package/dist/service/lambda/event-source/poll/sim-lambda-stream-retry.js +12 -64
  43. package/dist/service/lambda/event-source/sim-lambda-event-source-mapping.d.ts +10 -3
  44. package/dist/service/lambda/event-source/sim-lambda-event-source-mapping.js +12 -3
  45. package/dist/service/lambda/event-source/sim-lambda-stream-destination-config.d.ts +7 -0
  46. package/dist/service/lambda/event-source/sim-lambda-stream-destination-config.js +38 -0
  47. package/dist/service/lambda/event-source/stream/kinesis/sim-kinesis-event-source-streams.js +1 -0
  48. package/dist/service/lambda/event-source/stream/sim-dynamodb-event-source-stream-reader.js +1 -0
  49. package/dist/service/lambda/event-source/stream/sim-dynamodb-event-source-stream-shard.d.ts +1 -0
  50. package/dist/service/lambda/event-source/stream/sim-dynamodb-event-source-stream-shard.js +7 -0
  51. package/dist/service/lambda/event-source/stream/sim-lambda-event-source-streams.d.ts +1 -0
  52. package/dist/service/lambda/index.d.ts +1 -0
  53. package/dist/service/lambda/sim-lambda-commands.js +1 -0
  54. package/dist/service/ses/command/authorize/sim-ses-authorizer.d.ts +9 -0
  55. package/dist/service/ses/command/authorize/sim-ses-authorizer.js +18 -2
  56. package/dist/service/ses/command/send/sim-ses-send-email.js +2 -1
  57. package/docs/README.md +7 -0
  58. package/docs/ai-skill/README.md +6 -1
  59. package/docs/sdk/README.md +15 -0
  60. package/docs/services/acm/README.md +24 -40
  61. package/docs/services/apigateway/README.md +52 -71
  62. package/docs/services/apigatewayv2/README.md +55 -74
  63. package/docs/services/athena/README.md +17 -26
  64. package/docs/services/backup/README.md +29 -39
  65. package/docs/services/bedrock/README.md +38 -52
  66. package/docs/services/cloudformation/README.md +43 -55
  67. package/docs/services/cloudfront/README.md +69 -95
  68. package/docs/services/cloudwatch/README.md +40 -54
  69. package/docs/services/cognito/README.md +30 -45
  70. package/docs/services/dynamodb/README.md +34 -51
  71. package/docs/services/ecr/README.md +36 -77
  72. package/docs/services/ecs/README.md +26 -46
  73. package/docs/services/elbv2/README.md +19 -29
  74. package/docs/services/eventbridge/README.md +14 -18
  75. package/docs/services/firehose/README.md +24 -32
  76. package/docs/services/glue/README.md +41 -78
  77. package/docs/services/iam/README.md +13 -15
  78. package/docs/services/kinesis/README.md +53 -93
  79. package/docs/services/kms/README.md +22 -32
  80. package/docs/services/lambda/README.md +112 -85
  81. package/docs/services/logs/README.md +41 -50
  82. package/docs/services/organizations/README.md +50 -85
  83. package/docs/services/personalize/README.md +28 -44
  84. package/docs/services/rekognition/README.md +26 -38
  85. package/docs/services/route53/README.md +17 -17
  86. package/docs/services/s3/README.md +47 -51
  87. package/docs/services/scheduler/README.md +41 -52
  88. package/docs/services/secretsmanager/README.md +27 -42
  89. package/docs/services/ses/README.md +24 -34
  90. package/docs/services/sns/README.md +18 -26
  91. package/docs/services/sqs/README.md +14 -14
  92. package/docs/services/ssm/README.md +13 -17
  93. package/docs/services/stepfunctions/README.md +18 -20
  94. package/docs/services/sts/README.md +32 -45
  95. package/docs/services/wafv2/README.md +12 -17
  96. package/docs/testing/README.md +228 -0
  97. package/docs/time/README.md +10 -0
  98. package/llms.txt +1 -0
  99. package/package.json +1 -1
@@ -1,12 +1,11 @@
1
1
  # Simulated CloudFormation
2
2
 
3
- Yulin includes a simulated CloudFormation service for tests and local development. It creates
4
- simulated AWS resources from CloudFormation templates, and works with hand-written templates, AWS
5
- SDK-style `CreateStackCommand` calls, or synthesized CDK template files.
3
+ Yulin deploys CloudFormation templates into a simulated AWS environment. It accepts inline
4
+ templates, AWS SDK command inputs, template files and synthesized CDK cloud assemblies.
6
5
 
7
6
  ## Basic usage
8
7
 
9
- Create a simulated AWS environment, get simulated CloudFormation, and deploy a template.
8
+ Call `deployTemplate(...)` with a template and wait for the stack to finish deploying.
10
9
 
11
10
  ```typescript sim-cloudformation-basic-template
12
11
  /**
@@ -84,7 +83,7 @@ console.log(simAws.s3().getSimBucketByName("typed-site-bucket")?.bucketName);
84
83
 
85
84
  ## Creating stacks with AWS SDK command shapes
86
85
 
87
- You can also use AWS SDK-style CloudFormation commands.
86
+ Use `createStack(...)` when the code under test works with AWS SDK command shapes.
88
87
 
89
88
  ```typescript sim-cloudformation-create-stack-command
90
89
  /**
@@ -263,11 +262,9 @@ await simAws.backgroundTasksComplete();
263
262
 
264
263
  ## Updating a stack
265
264
 
266
- `UpdateStackCommand` applies a changed template to a stack that is already deployed. Resources the
267
- new template adds are created, resources it drops are deleted, and resources it changed are
268
- replaced. Everything else is left alone, holding whatever it holds in simulated S3, DynamoDB or
269
- anywhere else. That is what lets a long-running local process pick up an infrastructure change
270
- without restarting and losing its data.
265
+ `UpdateStackCommand` applies a changed template to an existing stack. It creates added resources,
266
+ deletes removed resources and replaces changed resources. Unchanged resources keep their simulated
267
+ state.
271
268
 
272
269
  ```typescript sim-cloudformation-update-stack
273
270
  /**
@@ -352,11 +349,9 @@ could mean nothing else.
352
349
 
353
350
  ### What counts as a change
354
351
 
355
- Resources are compared as they resolve, not as they are written. A changed parameter value shows up
356
- as a changed resource even when the template body is identical, and a template reordered without
357
- being changed shows up as no change at all. Outputs are compared the same way. The rest of the
358
- template body is compared as written. A change to a section the simulator ignores, such as
359
- `Description`, is still an update.
352
+ Yulin compares resolved resources and outputs. Changing a parameter can therefore change a resource
353
+ without changing the template body. Reordering an unchanged template has no effect. Other template
354
+ sections are compared as written, including ignored sections such as `Description`.
360
355
 
361
356
  A template that changes nothing at all is refused with a `ValidationError` reading
362
357
  `No updates are to be performed.`, the same answer CloudFormation gives. So is an update asked for
@@ -436,12 +431,11 @@ An update from the held template with the deployed values changes nothing, and i
436
431
 
437
432
  ### Changed resources are replaced
438
433
 
439
- A resource whose template entry changed is deleted and created again from the new template. Real
440
- CloudFormation updates most properties in place and keeps what the resource holds. That makes this a
441
- divergence worth knowing about. A bucket that gains a property loses its objects here, where in AWS
442
- it would keep them. In-place update is the obvious next step, still to be built.
434
+ Yulin replaces a resource when its resolved template entry changes. It deletes the old resource and
435
+ creates a new one. AWS updates many properties in place. A simulated bucket therefore loses its
436
+ objects when a property change replaces it.
443
437
 
444
- Three things follow from replacement:
438
+ Replacement also affects dependencies and retention policies:
445
439
 
446
440
  - A resource naming a replaced resource is replaced too, all the way up the dependency chain, and
447
441
  nothing is left pointing at a resource that has gone. Real CloudFormation hands the dependent the
@@ -618,9 +612,8 @@ to create. Name the replacement in the template, as the example above does, to h
618
612
 
619
613
  ## Deploying through a change set
620
614
 
621
- A change set says what a template would do to a stack before anything happens to it. `cdk deploy`
622
- goes through one by default, and so does any deployment script that wants to see what an update will
623
- touch. Simulated CloudFormation serves `CreateChangeSetCommand`, `DescribeChangeSetCommand`,
615
+ A change set describes a proposed stack operation without applying it. Simulated CloudFormation
616
+ serves `CreateChangeSetCommand`, `DescribeChangeSetCommand`,
624
617
  `ExecuteChangeSetCommand`, `DeleteChangeSetCommand` and `ListChangeSetsCommand`.
625
618
 
626
619
  ```typescript sim-cloudformation-change-set
@@ -735,8 +728,7 @@ holds, in the order they were created.
735
728
 
736
729
  ## Deleting a stack
737
730
 
738
- `DeleteStackCommand` deletes the resources a stack created, in the reverse of the order they were
739
- created in, and then releases the stack name.
731
+ `DeleteStackCommand` deletes resources in reverse creation order, then releases the stack name.
740
732
 
741
733
  ```typescript sim-cloudformation-delete-stack
742
734
  /**
@@ -801,9 +793,8 @@ Deleting a stack name that was never deployed succeeds, as it does in CloudForma
801
793
 
802
794
  ### When a resource cannot be deleted
803
795
 
804
- Some resources refuse to go, the same way they do in AWS. An S3 bucket that still holds objects is
805
- the common one. CloudFormation fails there and never empties the bucket for you. That is why CDK
806
- ships an `autoDeleteObjects` custom resource.
796
+ Resource deletion can fail. For example, S3 refuses to delete a non-empty bucket. CloudFormation
797
+ leaves the stack in `DELETE_FAILED` and does not empty the bucket automatically.
807
798
 
808
799
  A refusal leaves the stack in `DELETE_FAILED` with the reason on it, and keeps the stack name in use.
809
800
  `waitForStackDeleteComplete(...)` rethrows the error, and `DescribeStacksCommand` reports it as
@@ -896,7 +887,7 @@ takes either.
896
887
 
897
888
  ## Parameters
898
889
 
899
- Template parameters can be supplied when creating a stack.
890
+ Pass template parameter values when creating or updating a stack.
900
891
 
901
892
  ```typescript sim-cloudformation-parameters
902
893
  /**
@@ -949,7 +940,7 @@ the type.
949
940
 
950
941
  ## Intrinsic functions
951
942
 
952
- Sim CloudFormation supports common intrinsic functions used by supported resources.
943
+ Yulin resolves the following intrinsic functions in resource properties and outputs.
953
944
 
954
945
  ### `Ref`
955
946
 
@@ -991,8 +982,8 @@ console.log(
991
982
  );
992
983
  ```
993
984
 
994
- For supported resource types, `Ref` returns the resource-specific CloudFormation value. For example,
995
- an S3 Bucket `Ref` returns the Bucket name.
985
+ `Ref` returns the CloudFormation value for a resource type. For an S3 bucket, it returns the bucket
986
+ name.
996
987
 
997
988
  ### `Fn::GetAtt`
998
989
 
@@ -1251,8 +1242,8 @@ console.log(simAws.s3().getSimBucketByName("docs-site-bucket")?.bucketName);
1251
1242
 
1252
1243
  ### `Fn::FindInMap`
1253
1244
 
1254
- A template `Mappings` section holds two levels of keys against a value. `Fn::FindInMap` reads one of
1255
- those values, given the map name, the top-level key and the second-level key.
1245
+ A template `Mappings` section stores values under two levels of keys. `Fn::FindInMap` reads a value
1246
+ using the map name and both keys.
1256
1247
 
1257
1248
  ```typescript sim-cloudformation-fn-find-in-map
1258
1249
  /**
@@ -1330,9 +1321,7 @@ expression. A lookup that finds its value in the map ignores the default.
1330
1321
 
1331
1322
  ### `Fn::Split` and `Fn::Select`
1332
1323
 
1333
- `Fn::Split` cuts a string into a list on a delimiter. `Fn::Select` reads one value out of a list by
1334
- its zero-based index. They are usually written together, to pull one part out of a string another
1335
- resource gave.
1324
+ `Fn::Split` divides a string by a delimiter. `Fn::Select` reads a list value by zero-based index.
1336
1325
 
1337
1326
  ```typescript sim-cloudformation-fn-select-split
1338
1327
  /**
@@ -1418,8 +1407,7 @@ resource and the property path the value sat at, for example
1418
1407
 
1419
1408
  ### `Fn::ImportValue`
1420
1409
 
1421
- `Fn::ImportValue` reads a value another Stack exported. A Stack exports one by giving an Output an
1422
- `Export.Name`, and a Stack in the same Account and Region imports it by that name.
1410
+ `Fn::ImportValue` reads a named output exported by another stack in the same account and region.
1423
1411
 
1424
1412
  CDK writes both halves on its own. Referencing a resource in another Stack of the same app puts an
1425
1413
  `Export` on the producer and an `Fn::ImportValue` on the consumer, with no opt-in.
@@ -1486,8 +1474,8 @@ exports published in that Region.
1486
1474
 
1487
1475
  ## Dynamic references
1488
1476
 
1489
- A `{{resolve:...}}` dynamic reference reads a value from another service while a resource is being
1490
- created. It is written into the template as ordinary text, so it can sit inside a longer string.
1477
+ A `{{resolve:...}}` dynamic reference reads an SSM parameter or Secrets Manager secret while
1478
+ creating a resource. A reference can appear inside a longer string.
1491
1479
 
1492
1480
  `Fn::Sub` and `Fn::Join` resolve first, and the reference is read from the string they built. CDK
1493
1481
  writes that shape whenever a secret sits in the same stack as the resource reading it (the secret's
@@ -1506,9 +1494,8 @@ for the segments and for what a reference Secrets Manager cannot answer resolves
1506
1494
 
1507
1495
  ## Conditions
1508
1496
 
1509
- A template `Conditions` section names boolean expressions over the stack's parameter values. A
1510
- condition decides whether a resource is created, and which value `Fn::If` gives a property or an
1511
- output.
1497
+ The `Conditions` section defines boolean expressions over parameter and pseudo-parameter values.
1498
+ Conditions control resource creation and select `Fn::If` values.
1512
1499
 
1513
1500
  ```typescript sim-cloudformation-conditions
1514
1501
  /**
@@ -1632,7 +1619,7 @@ condition the template leaves undefined fails the deployment.
1632
1619
 
1633
1620
  ## Resource dependencies
1634
1621
 
1635
- Resources can depend on each other explicitly with `DependsOn`.
1622
+ Use `DependsOn` to declare an explicit resource dependency.
1636
1623
 
1637
1624
  ```typescript sim-cloudformation-depends-on
1638
1625
  /**
@@ -1765,8 +1752,7 @@ in the assembly, and a Stack named in `stackOptions` carries its own.
1765
1752
 
1766
1753
  ## Deploying synthesized CDK templates
1767
1754
 
1768
- Use `deployTemplateFile(...)` to deploy a template file, including the JSON templates CDK synthesis
1769
- produces.
1755
+ Use `deployTemplateFile(...)` to deploy a JSON or YAML template file, including CDK synth output.
1770
1756
 
1771
1757
  ```typescript sim-cloudformation-cdk-template-file
1772
1758
  /**
@@ -1805,8 +1791,7 @@ const stack = await simAws.cloudFormation().deployTemplateFile({
1805
1791
  await stack.waitForDeployComplete();
1806
1792
  ```
1807
1793
 
1808
- This is useful for local integration tests where you want CDK to produce the template, then Yulin to
1809
- create the simulated resources from that synthesized output template.
1794
+ This lets an integration test synthesize with CDK and deploy the resulting template through Yulin.
1810
1795
 
1811
1796
  A template path with no file at it is refused with
1812
1797
  `No Sim CloudFormation template file at <path>`, naming the resolved path. A synthesized template
@@ -1814,8 +1799,7 @@ is build output, and a checkout that has yet to synthesize one meets this on the
1814
1799
 
1815
1800
  ## Deploying a template written as YAML
1816
1801
 
1817
- CloudFormation takes a template in JSON or in YAML, and a template written by hand is usually YAML.
1818
- `deployTemplateFile(...)` reads a `.yaml` or `.yml` file as YAML.
1802
+ `deployTemplateFile(...)` parses `.yaml` and `.yml` files as YAML.
1819
1803
 
1820
1804
  ```yaml
1821
1805
  Resources:
@@ -1917,6 +1901,10 @@ it.
1917
1901
  environment names. The assembly's `manifest.json` is where that comes from, so an app synthesizing
1918
1902
  several Stacks across several regions needs no loop of its own and no region constants beside it.
1919
1903
 
1904
+ An application test suite should normally call `deployCdkOut(...)` once from its shared Yulin setup.
1905
+ Every test then uses the same deployed Stacks. The [test suite setup guide](https://yulinsim.dev/testing/)
1906
+ shows this arrangement with Vitest and SDK interception.
1907
+
1920
1908
  ```typescript sim-cloudformation-cdk-out-assembly
1921
1909
  /**
1922
1910
  * Deploying every Stack a synthesized CDK cloud assembly holds.
@@ -3250,10 +3238,10 @@ another function's event put there.
3250
3238
  Two shapes are refused rather than expanded. A bucket writing its `NotificationConfiguration` or its
3251
3239
  `LambdaConfigurations` as an intrinsic such as `Fn::If` is one, because there is no appending to a
3252
3240
  list CloudFormation has not resolved yet, and adding the event's own entries would drop whatever the
3253
- intrinsic resolved to. The other is a function the template conditions out, which real CloudFormation
3254
- refuses for the same reason SAM cannot fix it: the notification belongs to the bucket, the bucket is
3255
- not conditioned, and nothing can condition one entry of somebody else's property. Condition the
3256
- bucket along with the function, or declare the notification on the bucket yourself.
3241
+ intrinsic resolved to. The other is a function the template conditions out. Real CloudFormation
3242
+ refuses this because the notification belongs to the unconditioned bucket, and one entry of that
3243
+ property cannot have its own condition. Condition the bucket along with the function, or declare the
3244
+ notification on the bucket yourself.
3257
3245
 
3258
3246
  ### Simple tables
3259
3247
 
@@ -1,18 +1,12 @@
1
1
  # Simulated CloudFront
2
2
 
3
- Yulin includes a simulated CloudFront service for tests and local development.
3
+ Yulin simulates CloudFront distributions, origins, cache behaviour and edge functions. Use
4
+ `simAws.cloudFront()` as part of a simulated AWS environment or create a standalone
5
+ `SimCloudFront`. `serveSimAws` exposes distributions over localhost.
4
6
 
5
- Sim CloudFront can be used directly through `SimAws`, and it can also be served on localhost
6
- alongside other simulated AWS services, so application code can make HTTP requests through a
7
- CloudFront-like layer without talking to real AWS.
7
+ ## Create a distribution
8
8
 
9
- `SimCloudFront` can also be instantiated on its own, in which case it has its own isolated state,
10
- standing apart from any wider simulated AWS environment.
11
-
12
- ## Basic Distribution setup
13
-
14
- Create a simulated AWS environment, add a sim S3 Bucket, and create a sim CloudFront Distribution
15
- pointing at that Bucket.
9
+ Create an S3 bucket, then create a distribution whose origin uses the bucket's REST endpoint.
16
10
 
17
11
  ```typescript sim-cloudfront-distribution-s3-origin
18
12
  /**
@@ -95,19 +89,16 @@ console.log(distributionCreation.Distribution?.DomainName);
95
89
 
96
90
  ## What an S3 Origin can read
97
91
 
98
- An S3 Origin reads its Bucket through the ordinary GetObject command. The Bucket policy decides what
99
- the Distribution can serve. An Origin with no origin access control reads anonymously, the unsigned
100
- request real CloudFront sends to the S3 REST endpoint. An Object has to be publicly readable for the
101
- Distribution to serve it, and a Bucket with no policy answers 403 for every Object.
92
+ An S3 Origin reads its bucket through `GetObject`. The bucket policy decides what the distribution
93
+ can serve. Without an origin access control, CloudFront reads anonymously and the object must be
94
+ publicly readable. A private bucket returns 403.
102
95
 
103
96
  An Origin that does have an origin access control reads as the CloudFront service principal. The
104
97
  Bucket stays private and its policy names the Distribution. See
105
98
  [Origin access controls](#origin-access-controls) for the Bucket policy that takes.
106
99
 
107
- That is what the two commands in the example above do. `PutPublicAccessBlockCommand` opts out of the
108
- block on public Bucket policies, then `PutBucketPolicyCommand` grants `s3:GetObject` to
109
- `Principal: "*"`. The same pair is what a static website Bucket needs, and it is what CDK's
110
- `publicReadAccess: true` generates.
100
+ The example disables the block on public bucket policies, then grants `s3:GetObject` to
101
+ `Principal: "*"`. CDK's `publicReadAccess: true` produces the same result.
111
102
 
112
103
  A denied read reaches the viewer as a 403 from the Origin, and a Distribution's custom error
113
104
  response for 403 replaces it. The usual single-page-app setup, rewriting 403 to `/index.html`,
@@ -118,10 +109,8 @@ an Origin that signs nothing.
118
109
 
119
110
  ## Static sites, default root objects and error pages
120
111
 
121
- A static site behind CloudFront usually leans on two Distribution settings. `DefaultRootObject`
122
- makes a request for the site root return the home page. `CustomErrorResponses` makes a URL that
123
- matches no object return the site's own error page in place of the Origin's. Sim CloudFront applies
124
- both, and a test can assert what a visitor would actually see.
112
+ `DefaultRootObject` maps the distribution root to an object such as `index.html`.
113
+ `CustomErrorResponses` replaces selected Origin errors with another object and status code.
125
114
 
126
115
  ```typescript sim-cloudfront-static-site
127
116
  /**
@@ -242,13 +231,10 @@ try {
242
231
  }
243
232
  ```
244
233
 
245
- The default root object stands in for a request to the root of the Distribution and nothing else. A
246
- request for `/blog/` is passed to the Origin as it arrived, even where that folder holds its own
247
- `index.html`. That is where CloudFront differs from an S3 website index document. The substituted
248
- path is what the rest of request handling sees, and a Cache Behavior pattern and a `viewer-request`
249
- CloudFront Function both act on the object being served. The value names an object at the Origin. It may be a
250
- path such as `public/index.html`, and it must not begin with a forward slash. Sim CloudFront refuses one that does with `InvalidDefaultRootObject`. The alternative would
251
- be a Distribution that answers its own root with a 403.
234
+ The default root object applies only to `/`. A request for `/blog/` reaches the Origin unchanged,
235
+ even if the Origin contains `/blog/index.html`. Cache Behaviors and viewer-request functions see the
236
+ substituted root path. The value may contain a path such as `public/index.html`, but it must not start
237
+ with `/`. Invalid values raise `InvalidDefaultRootObject`.
252
238
 
253
239
  A custom error response replaces the Origin's response when its status matches `ErrorCode`. The
254
240
  codes CloudFront supports are 400, 403, 404, 405, 414, 416, 500, 501, 502, 503 and 504. The response
@@ -276,7 +262,7 @@ status the Distribution serves no page for. See
276
262
 
277
263
  ## Serve simulated CloudFront on localhost
278
264
 
279
- Use `serveSimAws` when you want to make real HTTP requests to the simulated system on localhost.
265
+ Use `serveSimAws` to send HTTP requests through the simulated distribution on localhost.
280
266
 
281
267
  ```typescript serve-sim-cloudfront-localhost
282
268
  /**
@@ -390,15 +376,14 @@ the Distribution behind it. See
390
376
 
391
377
  ## Custom Origins
392
378
 
393
- An Origin with a `CustomOriginConfig` is one CloudFront reaches over HTTP, in place of reading an S3
394
- Bucket. Sim CloudFront resolves its `DomainName` in the simulated environment and serves the request
395
- in process. A Distribution can front a simulated HTTP API endpoint
379
+ An Origin with `CustomOriginConfig` routes requests to another simulated HTTP service. CloudFront
380
+ resolves `DomainName` in the simulated environment and serves the request in process. A distribution
381
+ can front a simulated HTTP API endpoint
396
382
  (`<api-id>.execute-api.<region>.amazonaws.com`), a simulated Lambda Function URL
397
383
  (`<url-id>.lambda-url.<region>.on.aws`), or anything a simulated Route53 record points at one of
398
384
  those.
399
385
 
400
- That covers the common arrangement of one Distribution serving static assets from a Bucket and
401
- sending `/api/*` to an API:
386
+ The following distribution serves static files from S3 and sends `/api/*` to an HTTP API:
402
387
 
403
388
  ```typescript sim-cloudfront-distribution-custom-origin
404
389
  /**
@@ -568,14 +553,13 @@ try {
568
553
  }
569
554
  ```
570
555
 
571
- The Origin domain is resolved when a request is served, and the Distribution and the service behind
572
- its Origin can be created in either order, whichever way round a CloudFormation template happens to
573
- declare them.
556
+ The Origin domain is resolved for each request. The distribution and Origin service may be created
557
+ in either order.
574
558
 
575
559
  `OriginPath` is prefixed to the request path, as it is for an S3 Origin. An Origin path of `/v1`
576
560
  sends a request for `/things` on to `/v1/things`.
577
561
 
578
- Three things follow from the request never leaving the process:
562
+ In-process routing has these limits:
579
563
 
580
564
  - A domain unknown to the simulation fails with an error naming the Origin and the
581
565
  domain. No real request is made to it, and external HTTP Origins are unsupported.
@@ -588,10 +572,9 @@ Three things follow from the request never leaving the process:
588
572
 
589
573
  ## Custom headers on an Origin
590
574
 
591
- CloudFront adds an Origin's custom headers to every request it sends that Origin. An origin that
592
- answers only requests carrying a header nothing else knows is how AWS documents
593
- [restricting a custom origin to CloudFront](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-overview.html#forward-custom-headers-restrict-access),
594
- and a sim Distribution sends them the same way.
575
+ CloudFront adds an Origin's custom headers to every request sent to that Origin. A service can use a
576
+ private header value to
577
+ [restrict access to CloudFront](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-overview.html#forward-custom-headers-restrict-access).
595
578
 
596
579
  The CloudFront API and CloudFormation name the field differently, and both spellings are accepted
597
580
  here. The API has `CustomHeaders` inside an `Origin`, and `AWS::CloudFront::Distribution` has
@@ -741,10 +724,10 @@ An S3 Origin takes the headers and reaches nothing with them. Sim CloudFront rea
741
724
  `GetObject` and builds no HTTP request for a header to travel on, and real S3 ignores a header it
742
725
  has no use for.
743
726
 
744
- ## An Origin declared twice
727
+ ## Duplicate Origins
745
728
 
746
- Two Origins over one domain name are ordinary. They differ by `OriginPath`, by their custom headers
747
- or by how CloudFront connects, and a Behavior points at whichever one it wants.
729
+ Several Origins may use the same domain when their paths, headers, or connection settings differ.
730
+ Each Behavior selects an Origin by ID.
748
731
 
749
732
  Two Origins that match in every property but the `Id` are one Origin written twice. Copying a
750
733
  Behavior and its Origin together, then editing the path pattern, leaves exactly that behind. Sim
@@ -840,9 +823,8 @@ value however they were ordered or cased.
840
823
 
841
824
  ## Viewer certificates
842
825
 
843
- A Distribution with alternate domain names needs an ACM certificate, and CloudFront accepts only
844
- certain ones. Sim CloudFront applies the same rules. A Distribution that real CloudFront would
845
- reject at deploy time is rejected here first, with `InvalidViewerCertificate`:
826
+ A distribution with alternate domain names requires a valid ACM certificate. Yulin raises
827
+ `InvalidViewerCertificate` when:
846
828
 
847
829
  - the certificate must be in `us-east-1`, wherever the rest of your infrastructure lives
848
830
  - the certificate must exist and be `ISSUED`
@@ -912,8 +894,8 @@ as well.
912
894
 
913
895
  ## Disabling and deleting a Distribution
914
896
 
915
- `DeleteDistributionCommand` removes a Distribution. CloudFront will only delete one that has stopped
916
- serving. The sequence is `UpdateDistributionCommand` with `Enabled: false` first, then the deletion. Deleting an enabled Distribution answers `DistributionNotDisabled`, as it does in AWS.
897
+ Disable a distribution with `UpdateDistributionCommand` before deleting it. Deleting an enabled
898
+ distribution raises `DistributionNotDisabled`.
917
899
 
918
900
  `UpdateDistributionCommand` takes a whole `DistributionConfig`, and applies the update as a
919
901
  replacement. Anything left out of the new config is dropped, including alternate domain names and
@@ -1012,17 +994,16 @@ Function code.
1012
994
 
1013
995
  ## Simulated CloudFront Functions
1014
996
 
1015
- The sim CloudFront supports `viewer-request` and `viewer-response` CloudFront Functions.
997
+ Yulin supports `viewer-request` and `viewer-response` CloudFront Functions.
1016
998
 
1017
999
  A `viewer-response` Function runs for an Origin status below 400. CloudFront skips the
1018
1000
  viewer-response event once the Origin has answered 400 or higher (see
1019
1001
  [Limitations](#limitations)), and so does this simulation.
1020
1002
 
1021
- Use `makeCffFunctionCodeInput` to pass a JavaScript handler function to `CreateFunctionCommand`, or
1003
+ Use `makeCffFunctionCodeInput` to pass a JavaScript handler to `CreateFunctionCommand`. Use
1022
1004
  [CloudFormation bindings](https://yulinsim.dev/services/cloudformation/#cloudfront-function-bindings "CloudFront Function bindings usage docs")
1023
- to back a template Resource with one. A handler reference is what to reach for first. It stops on a
1024
- breakpoint and can close over the test's own state. Publish the source itself where the test is
1025
- about the code the Distribution carries, down to the 10 KB it has to fit in. A
1005
+ for a function declared in a template. Handler references support breakpoints and local state. Use
1006
+ source code when the test covers the deployed function or its 10 KB size limit. A
1026
1007
  [Lambda@Edge](#simulated-lambdaedge) function is an ordinary simulated Lambda function, and the same
1027
1008
  choice covers it.
1028
1009
 
@@ -1851,8 +1832,7 @@ parameter holding the version ARN into a support stack in us-east-1. The stack u
1851
1832
  reads that parameter back through a `Custom::CrossRegionStringParameterReader` resource, and the
1852
1833
  Behavior's `LambdaFunctionARN` is an `Fn::GetAtt` on it. Simulated CloudFormation makes that read
1853
1834
  itself, against the Region the resource names, and the association ends up holding the ARN the
1854
- support stack published. Both stacks have to deploy, which is what deploying the whole cloud
1855
- assembly does:
1835
+ support stack published. Deploy the whole cloud assembly to deploy both stacks:
1856
1836
 
1857
1837
  ```typescript
1858
1838
  await simAws.cloudFormation().deployCdkOut("cdk.out");
@@ -2014,8 +1994,8 @@ answered.
2014
1994
  ## Response headers policies
2015
1995
 
2016
1996
  A response headers policy sets headers on everything a cache Behavior serves. Declare one as
2017
- `AWS::CloudFront::ResponseHeadersPolicy` and point a Behavior's `ResponseHeadersPolicyId` at it with
2018
- a `Ref`, which is what CDK's `ResponseHeadersPolicy` construct synthesizes.
1997
+ `AWS::CloudFront::ResponseHeadersPolicy` and reference it from the Behavior's
1998
+ `ResponseHeadersPolicyId`. CDK's `ResponseHeadersPolicy` construct synthesizes this shape.
2019
1999
 
2020
2000
  ```typescript sim-cloudfront-response-headers-policy
2021
2001
  /**
@@ -2206,9 +2186,9 @@ it.
2206
2186
 
2207
2187
  ## Cache policies
2208
2188
 
2209
- A cache policy decides what a cache Behavior keys its cache on and how long an object stays there.
2210
- Declare one as `AWS::CloudFront::CachePolicy` and point a Behavior's `CachePolicyId` at it with a
2211
- `Ref`, which is what CDK's `CachePolicy` construct synthesizes.
2189
+ A cache policy controls the cache key and time to live. Declare one as
2190
+ `AWS::CloudFront::CachePolicy` and reference it from the Behavior's `CachePolicyId`. CDK's
2191
+ `CachePolicy` construct synthesizes this shape.
2212
2192
 
2213
2193
  ```typescript sim-cloudfront-cache-policy
2214
2194
  /**
@@ -2652,8 +2632,8 @@ try {
2652
2632
 
2653
2633
  The Origin's own headers and the cache policy settle the TTL between them, the way they settle it in
2654
2634
  AWS. `s-maxage` is preferred to `max-age`, and `max-age` to `Expires`. Whatever the Origin asks for
2655
- is held between the policy's `MinTTL` and `MaxTTL`. An Origin that asks for nothing gets the greater
2656
- of `MinTTL` and `DefaultTTL`, which is a day on `CachingOptimized`.
2635
+ is held between the policy's `MinTTL` and `MaxTTL`. When the Origin supplies no cache lifetime,
2636
+ CloudFront uses the greater of `MinTTL` and `DefaultTTL`. `CachingOptimized` uses one day.
2657
2637
 
2658
2638
  An `Expires` header has to carry one of the three date formats HTTP allows. Anything else, a
2659
2639
  locale-formatted date included, is read as an object that expired already, the way any HTTP cache
@@ -2878,10 +2858,9 @@ different paths is `InvalidationBatchAlreadyExists`.
2878
2858
 
2879
2859
  ## Origin request policies
2880
2860
 
2881
- An origin request policy decides which of the viewer's headers, cookies and query strings a cache
2882
- Behavior carries to its Origin. Declare one as `AWS::CloudFront::OriginRequestPolicy` and point a
2883
- Behavior's `OriginRequestPolicyId` at it with a `Ref`, which is what CDK's `OriginRequestPolicy`
2884
- construct synthesizes.
2861
+ An origin request policy selects the viewer headers, cookies and query strings sent to the Origin.
2862
+ Declare one as `AWS::CloudFront::OriginRequestPolicy` and reference it from the Behavior's
2863
+ `OriginRequestPolicyId`. CDK's `OriginRequestPolicy` construct synthesizes this shape.
2885
2864
 
2886
2865
  ```typescript sim-cloudfront-origin-request-policy
2887
2866
  /**
@@ -3171,9 +3150,9 @@ Behavior names one without a template creating anything. `AllViewer`
3171
3150
  for it. CDK's `OriginRequestPolicy.ALL_VIEWER` and its seven siblings synthesize those IDs. A stack
3172
3151
  reaching for one deploys.
3173
3152
 
3174
- Each also carries the three sections AWS publishes for it. A Behavior on `AllViewer` here sends the
3175
- Origin everything the viewer sent bar its `Host`, which is the Origin's own domain under every
3176
- policy. One on `CORS-CustomOrigin` sends the `Origin` header alone. One on
3153
+ Each also carries the three sections AWS publishes for it. A Behavior on `AllViewer` sends every
3154
+ viewer value except `Host`. The Origin's domain is used for `Host` under every policy. A Behavior on
3155
+ `CORS-CustomOrigin` sends the `Origin` header alone. One on
3177
3156
  `AllViewerExceptHostHeader` sends what `AllViewer` sends, since the `Host` it withholds was never
3178
3157
  the viewer's here.
3179
3158
 
@@ -3189,10 +3168,9 @@ Behavior, the way an absent cache policy does, and the Behavior reports no polic
3189
3168
 
3190
3169
  ## Origin access controls
3191
3170
 
3192
- An origin access control is how a Distribution authenticates to a private Origin. The Origin then
3193
- admits the Distribution and nothing else. Declare one as `AWS::CloudFront::OriginAccessControl` and
3194
- point an Origin's `OriginAccessControlId` at it with a `Ref`, which is what CDK's
3195
- `S3BucketOrigin.withOriginAccessControl` synthesizes.
3171
+ An origin access control lets a Distribution authenticate to a private Origin. Declare one as
3172
+ `AWS::CloudFront::OriginAccessControl` and reference it from the Origin's `OriginAccessControlId`.
3173
+ CDK's `S3BucketOrigin.withOriginAccessControl` synthesizes this shape.
3196
3174
 
3197
3175
  An `OriginAccessControlOriginType` of `s3` signs for an S3 Bucket Origin, and one of `lambda` signs
3198
3176
  for a Lambda Function URL Origin. The origin type has to match the Origin it is attached to. An `s3`
@@ -3635,11 +3613,9 @@ CloudFront. `await simAws.backgroundTasksComplete()` waits for that.
3635
3613
 
3636
3614
  ### ETags
3637
3615
 
3638
- The key value store commands do check `IfMatch`, where the Distribution and Function commands ignore
3639
- it. Both APIs require it on every write and CloudFront refuses a stale one, which is what stops two
3640
- writers overwriting each other. A write carrying a stale ETag is refused with `PreconditionFailed`,
3641
- and a caller has to thread the ETag through the way it does against CloudFront. Each write returns
3642
- the new ETag for the next one.
3616
+ Key value store commands check `IfMatch`. Distribution and Function commands ignore it. Both key
3617
+ value store APIs require the current ETag for every write. A stale ETag raises
3618
+ `PreconditionFailed`, and each successful write returns the ETag for the next one.
3643
3619
 
3644
3620
  A store has two ETags and they are not interchangeable, as in AWS. Each `DescribeKeyValueStore`
3645
3621
  returns its own. The CloudFront client's versions the store's configuration, and the key value store
@@ -3993,8 +3969,8 @@ Where sim CloudFront knowingly behaves differently from AWS:
3993
3969
  response an `origin-request` function generated has no Origin status behind it, and its own status
3994
3970
  stands in.
3995
3971
  - **CloudFront's disallowed and read-only header lists go unchecked.** Real CloudFront answers 502
3996
- when an edge function adds `Connection` or edits `Content-Length`. Both kinds of function here
3997
- write what they like, apart from the viewer-request `host`, which is restored.
3972
+ when an edge function adds `Connection` or edits `Content-Length`. Yulin accepts those changes.
3973
+ It restores the `host` after a viewer-request function.
3998
3974
  - **An S3 Origin with no origin access control reads its Bucket anonymously.** That is the unsigned
3999
3975
  request real CloudFront sends to the S3 REST endpoint without one. The Bucket policy has to make
4000
3976
  an Object publicly readable for the Distribution to serve it. A legacy
@@ -4020,9 +3996,9 @@ Where sim CloudFront knowingly behaves differently from AWS:
4020
3996
  are absent, and `AWS::CloudFront::OriginAccessControl` is the only way to make one.
4021
3997
  - **A list's `Quantity` is only checked when it is there.** Every CloudFront list carries a count
4022
3998
  alongside its items, and a `Quantity` that disagrees with `Items` is refused with
4023
- `InconsistentQuantities`, as CloudFront refuses it. A list arriving as a plain array, which is the
4024
- CloudFormation shape, has no count to disagree with, and a template goes unchecked this way. So
4025
- does a hand-written `{ Items: [...] }` with the count left out. The AWS SDK types make omitting
3999
+ `InconsistentQuantities`, as CloudFront refuses it. CloudFormation uses a plain array without a
4000
+ count, so templates skip this validation. A hand-written `{ Items: [...] }` also skips it when the
4001
+ count is absent. The AWS SDK types make omitting
4026
4002
  `Quantity` a compile error, so what arrives without one is a different mistake from the one this
4027
4003
  catches.
4028
4004
  - **A web ACL a Distribution names has to exist here.** `WebACLId` resolves to a web ACL created in
@@ -4075,11 +4051,9 @@ Where sim CloudFront knowingly behaves differently from AWS:
4075
4051
  share of real responses carry `Server-Timing`. This simulation adds it to every response once
4076
4052
  `Enabled` is true. A test asserting on it never depends on chance. The header's value is a
4077
4053
  fixed placeholder, since nothing here measures an Origin fetch the way CloudFront's edge does.
4078
- - **A viewer's `Host` header never reaches an Origin.** Real CloudFront forwards it where a policy
4079
- names it, which is what `AllViewerExceptHostHeader` exists to stop. Here an Origin request always
4080
- carries the Origin's own domain as `Host`, since the request has to reach the simulated service
4081
- its URL names.
4082
- - **CloudFront's own headers are not generated.** `X-Amz-Cf-Id`, `Via`, `X-Forwarded-For` and the
4083
- `CloudFront-Viewer-*` family are absent from an Origin request, so a policy naming one of them
4084
- forwards nothing. `Host`, `User-Agent` and the normalized `Accept-Encoding` are the three this
4085
- simulation sends of its own accord.
4054
+ - **Origin requests use the Origin's `Host` header.** Real CloudFront can forward the viewer's value
4055
+ when a policy includes it. Yulin always sends the Origin domain because the request must reach the
4056
+ simulated service named by the URL.
4057
+ - **CloudFront-generated headers are absent.** Yulin omits `X-Amz-Cf-Id`, `Via`,
4058
+ `X-Forwarded-For` and the `CloudFront-Viewer-*` family. It generates `Host`, `User-Agent` and a
4059
+ normalized `Accept-Encoding` value.