@kensio/yulin 1.21.6 → 1.21.8
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/README.md +22 -2
- package/dist/service/eventbridge/cfn/bus/sim-cfn-event-bus-creator.js +1 -0
- package/dist/service/eventbridge/cfn/bus/sim-cfn-event-bus-properties.d.ts +4 -0
- package/dist/service/eventbridge/cfn/bus/sim-cfn-event-bus-properties.js +26 -1
- package/dist/service/eventbridge/cfn/rule/sim-cfn-event-rule-creator.js +3 -1
- package/dist/service/eventbridge/cfn/rule/sim-cfn-event-rule-properties.d.ts +0 -7
- package/dist/service/eventbridge/cfn/rule/sim-cfn-event-rule-properties.js +0 -20
- package/dist/service/eventbridge/cfn/rule/sim-cfn-event-rule-unsimulated-properties.d.ts +13 -0
- package/dist/service/eventbridge/cfn/rule/sim-cfn-event-rule-unsimulated-properties.js +59 -0
- package/dist/service/eventbridge/cfn/sim-cfn-event-bridge-resource-error.d.ts +1 -1
- package/dist/service/eventbridge/cfn/sim-cfn-event-bridge-resource-error.js +1 -1
- package/dist/service/lambda/cfn/event-source-mapping/sim-cfn-lambda-event-source-mapping-properties.js +1 -1
- package/dist/service/lambda/cfn/event-source-mapping/sim-cfn-lambda-event-source-mapping-property-rules.d.ts +3 -2
- package/dist/service/lambda/cfn/event-source-mapping/sim-cfn-lambda-event-source-mapping-property-rules.js +25 -3
- package/dist/service/ses/command/authorize/sim-ses-authorizer.d.ts +9 -0
- package/dist/service/ses/command/authorize/sim-ses-authorizer.js +18 -2
- package/dist/service/ses/command/send/sim-ses-send-email.js +2 -1
- package/dist/service/sns/cfn/topic/sim-cfn-sns-topic-creator.js +1 -0
- package/dist/service/sns/cfn/topic/sim-cfn-sns-topic-properties.d.ts +9 -4
- package/dist/service/sns/cfn/topic/sim-cfn-sns-topic-properties.js +18 -6
- package/dist/service/sns/cfn/topic/sim-cfn-sns-topic-property-names.d.ts +10 -0
- package/dist/service/sns/cfn/topic/sim-cfn-sns-topic-property-names.js +16 -1
- package/dist/service/ssm/cfn/parameter/sim-cfn-ssm-parameter-creator.js +1 -1
- package/dist/service/ssm/cfn/parameter/sim-cfn-ssm-parameter-properties.d.ts +11 -6
- package/dist/service/ssm/cfn/parameter/sim-cfn-ssm-parameter-properties.js +18 -9
- package/docs/README.md +40 -4
- package/docs/ai-skill/README.md +57 -54
- package/docs/cli/README.md +84 -94
- package/docs/factories/README.md +42 -54
- package/docs/lint/README.md +41 -67
- package/docs/non-aws-dependencies/README.md +72 -168
- package/docs/sdk/README.md +109 -95
- package/docs/serve/README.md +192 -898
- package/docs/services/acm/README.md +24 -40
- package/docs/services/apigateway/README.md +52 -71
- package/docs/services/apigatewayv2/README.md +55 -74
- package/docs/services/athena/README.md +17 -26
- package/docs/services/backup/README.md +29 -39
- package/docs/services/bedrock/README.md +38 -52
- package/docs/services/cloudformation/README.md +43 -55
- package/docs/services/cloudfront/README.md +69 -95
- package/docs/services/cloudwatch/README.md +40 -54
- package/docs/services/cognito/README.md +30 -45
- package/docs/services/dynamodb/README.md +34 -51
- package/docs/services/ecr/README.md +36 -77
- package/docs/services/ecs/README.md +26 -46
- package/docs/services/elbv2/README.md +19 -29
- package/docs/services/eventbridge/README.md +24 -20
- package/docs/services/firehose/README.md +24 -32
- package/docs/services/glue/README.md +41 -78
- package/docs/services/iam/README.md +13 -15
- package/docs/services/kinesis/README.md +53 -93
- package/docs/services/kms/README.md +22 -32
- package/docs/services/lambda/README.md +60 -80
- package/docs/services/logs/README.md +41 -50
- package/docs/services/organizations/README.md +50 -85
- package/docs/services/personalize/README.md +28 -44
- package/docs/services/rekognition/README.md +26 -38
- package/docs/services/route53/README.md +17 -17
- package/docs/services/s3/README.md +47 -51
- package/docs/services/scheduler/README.md +41 -52
- package/docs/services/secretsmanager/README.md +27 -42
- package/docs/services/ses/README.md +24 -34
- package/docs/services/sns/README.md +31 -33
- package/docs/services/sqs/README.md +14 -14
- package/docs/services/ssm/README.md +19 -21
- package/docs/services/stepfunctions/README.md +18 -20
- package/docs/services/sts/README.md +32 -45
- package/docs/services/wafv2/README.md +12 -17
- package/docs/terraform/README.md +108 -126
- package/docs/testing/README.md +228 -0
- package/docs/time/README.md +87 -117
- package/llms.txt +2 -1
- package/package.json +1 -1
|
@@ -1,17 +1,14 @@
|
|
|
1
1
|
# Simulated Cognito IDP
|
|
2
2
|
|
|
3
|
-
Yulin
|
|
4
|
-
|
|
3
|
+
Yulin simulates Cognito user pools, app clients, users, groups, tokens, hosted domains and Lambda
|
|
4
|
+
triggers. Use `simAws.cognitoIdp()` directly or intercept a `CognitoIdentityProviderClient`.
|
|
5
|
+
Cognito types are available from `@kensio/yulin/cognito`.
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
are a different service and are outside the simulation.
|
|
8
|
-
|
|
9
|
-
Cognito-specific types are imported from the `@kensio/yulin/cognito` subpath.
|
|
7
|
+
Cognito identity pools are unsupported.
|
|
10
8
|
|
|
11
9
|
## Creating a pool and an app client
|
|
12
10
|
|
|
13
|
-
A pool needs a name.
|
|
14
|
-
applies.
|
|
11
|
+
A user pool needs a name. Other properties use Cognito's defaults.
|
|
15
12
|
|
|
16
13
|
```typescript sim-cognito-create-user-pool
|
|
17
14
|
/**
|
|
@@ -46,16 +43,14 @@ const appClient = await cognito.createUserPoolClient(
|
|
|
46
43
|
console.log(appClient.UserPoolClient?.ClientId); // 26 lowercase characters
|
|
47
44
|
```
|
|
48
45
|
|
|
49
|
-
A pool
|
|
50
|
-
splits the id on the underscore to find the region works here for the same reason it works on AWS.
|
|
46
|
+
A pool ID contains the region before its underscore, matching Cognito's ID format.
|
|
51
47
|
|
|
52
48
|
Two pools may share a name. Only the id identifies one.
|
|
53
49
|
|
|
54
50
|
## Password policy
|
|
55
51
|
|
|
56
|
-
A pool created without
|
|
57
|
-
|
|
58
|
-
those keeps the defaults for the rest.
|
|
52
|
+
A pool created without `Policies` requires at least eight characters with uppercase, lowercase,
|
|
53
|
+
numeric and symbol characters. Setting part of the policy keeps the defaults for omitted fields.
|
|
59
54
|
|
|
60
55
|
```typescript sim-cognito-password-policy
|
|
61
56
|
/**
|
|
@@ -86,10 +81,9 @@ with `InvalidPasswordException`, saying which rule it broke.
|
|
|
86
81
|
|
|
87
82
|
## Users
|
|
88
83
|
|
|
89
|
-
`AdminCreateUser` creates a user in `FORCE_CHANGE_PASSWORD
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
`FORCE_CHANGE_PASSWORD` gets the `NEW_PASSWORD_REQUIRED` challenge, not tokens.
|
|
84
|
+
`AdminCreateUser` creates a user in `FORCE_CHANGE_PASSWORD` with a temporary password. Sign-in
|
|
85
|
+
returns the `NEW_PASSWORD_REQUIRED` challenge until `AdminSetUserPassword` sets a permanent
|
|
86
|
+
password. A permanent password changes the status to `CONFIRMED`.
|
|
93
87
|
|
|
94
88
|
```typescript sim-cognito-create-user
|
|
95
89
|
/**
|
|
@@ -145,11 +139,9 @@ console.log(read.UserAttributes?.find((each) => each.Name === "sub")?.Value);
|
|
|
145
139
|
A password set without `Permanent: true` is temporary, and leaves the user in
|
|
146
140
|
`FORCE_CHANGE_PASSWORD` again.
|
|
147
141
|
|
|
148
|
-
A user's `sub` is a UUID
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
operation asks for a username. That is one thing that works there and not here. The refusal says so
|
|
152
|
-
when the username given is some user's `sub`.
|
|
142
|
+
A user's `sub` is a generated UUID and differs from the username. Yulin's admin operations accept
|
|
143
|
+
the username only. Cognito also accepts a `sub` for some operations, which Yulin reports as an
|
|
144
|
+
unsupported lookup.
|
|
153
145
|
|
|
154
146
|
Attributes come back under `Attributes` from `AdminCreateUser` and `ListUsers`, and under
|
|
155
147
|
`UserAttributes` from `AdminGetUser`, as the real API names them.
|
|
@@ -160,11 +152,9 @@ Attributes come back under `Attributes` from `AdminCreateUser` and `ListUsers`,
|
|
|
160
152
|
|
|
161
153
|
## Signing in by email or phone number
|
|
162
154
|
|
|
163
|
-
A pool
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
is what `AdminGetUser` reports and what the `cognito:username` claim carries. An application reading
|
|
167
|
-
"the username" off such a pool reads a UUID.
|
|
155
|
+
A pool with `UsernameAttributes` signs users in with an email address or phone number. Cognito
|
|
156
|
+
generates a UUID for the stored username. `AdminGetUser` and the `cognito:username` token claim
|
|
157
|
+
report that UUID.
|
|
168
158
|
|
|
169
159
|
A CDK `UserPool` with `signInAliases: { email: true }` emits `UsernameAttributes: ["email"]`, the
|
|
170
160
|
usual way to build an email sign-in pool.
|
|
@@ -384,13 +374,11 @@ outside the simulation.
|
|
|
384
374
|
|
|
385
375
|
## Signing up
|
|
386
376
|
|
|
387
|
-
`SignUp`
|
|
388
|
-
|
|
377
|
+
`SignUp` creates an `UNCONFIRMED` user through an app client. The operation does not use IAM
|
|
378
|
+
authorization.
|
|
389
379
|
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
deliberate divergence. Real Cognito never reports a code back to anyone, and reading one is what
|
|
393
|
-
makes a registration flow testable at all.
|
|
380
|
+
Read the confirmation code from `confirmationCode` on the simulated pool. Cognito sends the code by
|
|
381
|
+
email or text and never exposes it through the service API.
|
|
394
382
|
|
|
395
383
|
The pool also records the message it would have sent, holding the wording and the code a user
|
|
396
384
|
would have read. That is in [Messages a pool would have sent](#messages-a-pool-would-have-sent)
|
|
@@ -500,9 +488,8 @@ the deployed pool would give. A pool created without the setting allows sign-up,
|
|
|
500
488
|
|
|
501
489
|
## Resetting a forgotten password
|
|
502
490
|
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
are the pair an application calls when it has built its own sign-in screens.
|
|
491
|
+
`ForgotPassword` sends a code and `ConfirmForgotPassword` sets the new password. Both operations use
|
|
492
|
+
an app client and bypass IAM authorization.
|
|
506
493
|
|
|
507
494
|
The code goes to the same place a sign-up code goes, and is read back the same way, through
|
|
508
495
|
`confirmationCode` on the pool object. `ForgotPassword` answers with `CodeDeliveryDetails` naming
|
|
@@ -633,9 +620,8 @@ are refused for one.
|
|
|
633
620
|
|
|
634
621
|
## Messages a pool would have sent
|
|
635
622
|
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
medium, the subject, the body and the occasion it was sent on.
|
|
623
|
+
The pool records outgoing email and text messages in `sentMessages`. Each entry contains the
|
|
624
|
+
recipient, medium, subject, body and message type.
|
|
639
625
|
|
|
640
626
|
A message is recorded on five occasions. Those are a `SignUp`, a `ResendConfirmationCode`, an
|
|
641
627
|
`AdminCreateUser` that did not ask for `MessageAction: SUPPRESS`, an MFA code sent by text message,
|
|
@@ -2060,10 +2046,9 @@ own users at the same address, which real Cognito keeps as two accounts until
|
|
|
2060
2046
|
`AdminLinkProviderForUser` merges them. That operation is unsimulated.
|
|
2061
2047
|
|
|
2062
2048
|
Posting the page carries on into the sign-in the authorize endpoint already runs, ending in the same
|
|
2063
|
-
`<ProviderName>_<subject>` user and the same authorization code.
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
leaves a test that says who is signing in seeing none of this.
|
|
2049
|
+
`<ProviderName>_<subject>` user and the same authorization code. Provider state is discarded after
|
|
2050
|
+
the request. A later authorize request asks again because real Cognito asks the provider afresh each
|
|
2051
|
+
time. A provider configured with `signInAs` skips the page and uses the configured identity.
|
|
2067
2052
|
|
|
2068
2053
|
`/signup` is a link from that page. Its form asks for a username, a password and the attributes the
|
|
2069
2054
|
pool needs, which are the ones its `Schema` made required and the ones its `AutoVerifiedAttributes`
|
|
@@ -3704,8 +3689,8 @@ console.log(described.UserPoolClient?.ClientName);
|
|
|
3704
3689
|
|
|
3705
3690
|
A registered pool behaves like any other. It answers `DescribeUserPoolCommand` and
|
|
3706
3691
|
`ListUserPoolsCommand`, holds users, groups and app clients, and serves its JWKS and OpenID
|
|
3707
|
-
configuration on localhost.
|
|
3708
|
-
|
|
3692
|
+
configuration on localhost. The registered ID determines the pool ARN, issuer URL, token `iss` claim
|
|
3693
|
+
and `ProviderName`. A
|
|
3709
3694
|
policy naming `arn:aws:cognito-idp:eu-west-2:111111111111:userpool/eu-west-2_aBcDeFgHi` authorizes
|
|
3710
3695
|
the handler that reads the pool, which is what a template carrying the id in two places needs.
|
|
3711
3696
|
|
|
@@ -1,18 +1,13 @@
|
|
|
1
1
|
# Simulated DynamoDB
|
|
2
2
|
|
|
3
|
-
Yulin
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
This page covers creating, describing, listing and deleting tables. What a request says is checked
|
|
7
|
-
the way real DynamoDB checks it. A table that can be created here is one that could be created on
|
|
8
|
-
AWS.
|
|
9
|
-
|
|
10
|
-
DynamoDB-specific types are imported from the `@kensio/yulin/dynamodb` subpath.
|
|
3
|
+
Yulin simulates DynamoDB tables, indexes, items, streams and time to live in memory. Use
|
|
4
|
+
`simAws.dynamoDb()` directly or intercept a `DynamoDBClient`. DynamoDB types are available from
|
|
5
|
+
`@kensio/yulin/dynamodb`.
|
|
11
6
|
|
|
12
7
|
## Creating a table
|
|
13
8
|
|
|
14
|
-
`CreateTable`
|
|
15
|
-
attribute
|
|
9
|
+
`CreateTable` requires a table name, a key schema and an attribute definition for every key
|
|
10
|
+
attribute.
|
|
16
11
|
|
|
17
12
|
```typescript sim-dynamodb-create-table
|
|
18
13
|
/**
|
|
@@ -45,8 +40,7 @@ await simAws.backgroundTasksComplete();
|
|
|
45
40
|
A new table is `CREATING`, and activation is scheduled as background work. Call
|
|
46
41
|
`simAws.backgroundTasksComplete()` when a test needs the table to be `ACTIVE`.
|
|
47
42
|
|
|
48
|
-
The
|
|
49
|
-
definitions, the table ARN, a table ID, and the billing and capacity the table was created with.
|
|
43
|
+
The response describes the table's keys, attribute definitions, ARN, ID, billing mode and capacity.
|
|
50
44
|
|
|
51
45
|
## Key schema and attribute definitions
|
|
52
46
|
|
|
@@ -62,9 +56,8 @@ attribute as the type the table declared for it.
|
|
|
62
56
|
|
|
63
57
|
## Billing modes and throughput
|
|
64
58
|
|
|
65
|
-
`BillingMode` defaults to `PROVISIONED
|
|
66
|
-
|
|
67
|
-
no capacity, and is refused.
|
|
59
|
+
`BillingMode` defaults to `PROVISIONED`. A provisioned table requires at least one read and one write
|
|
60
|
+
capacity unit in `ProvisionedThroughput`.
|
|
68
61
|
|
|
69
62
|
`PAY_PER_REQUEST` refuses `ProvisionedThroughput`, since an on-demand table has no capacity to
|
|
70
63
|
provision.
|
|
@@ -111,8 +104,8 @@ reports for one.
|
|
|
111
104
|
|
|
112
105
|
## Global secondary indexes
|
|
113
106
|
|
|
114
|
-
`GlobalSecondaryIndexes`
|
|
115
|
-
|
|
107
|
+
`GlobalSecondaryIndexes` adds indexes over the table's items. Each index requires an `IndexName`,
|
|
108
|
+
`KeySchema` and `Projection`.
|
|
116
109
|
|
|
117
110
|
```typescript sim-dynamodb-global-secondary-index
|
|
118
111
|
/**
|
|
@@ -583,9 +576,8 @@ console.log(description.Table?.TableStatus); // "ACTIVE"
|
|
|
583
576
|
|
|
584
577
|
## Tagging tables
|
|
585
578
|
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
`ResourceArn`, where the table commands take a name or an ARN.
|
|
579
|
+
Add tags during `CreateTable` or later with `TagResource`. Remove them with `UntagResource` and read
|
|
580
|
+
them with `ListTagsOfResource`. Tag commands require the table ARN in `ResourceArn`.
|
|
589
581
|
|
|
590
582
|
```typescript sim-dynamodb-tag-table
|
|
591
583
|
/**
|
|
@@ -683,9 +675,8 @@ calling `Tags.of(stack).add("Environment", "test")` gets a tagged table.
|
|
|
683
675
|
|
|
684
676
|
## Writing items
|
|
685
677
|
|
|
686
|
-
`PutItem`
|
|
687
|
-
|
|
688
|
-
step in between.
|
|
678
|
+
`PutItem` replaces the complete item stored under the primary key. The write is visible when the
|
|
679
|
+
command returns.
|
|
689
680
|
|
|
690
681
|
```typescript sim-dynamodb-put-item
|
|
691
682
|
/**
|
|
@@ -739,10 +730,9 @@ anywhere else in the item.
|
|
|
739
730
|
|
|
740
731
|
## Reading and deleting items
|
|
741
732
|
|
|
742
|
-
`GetItem` reads
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
`ValidationException` naming the attribute at fault.
|
|
733
|
+
`GetItem` reads an item by primary key. `DeleteItem` removes it. The `Key` must contain every key
|
|
734
|
+
attribute and no others, using the types declared in `AttributeDefinitions`. Invalid keys raise
|
|
735
|
+
`ValidationException`.
|
|
746
736
|
|
|
747
737
|
```typescript sim-dynamodb-get-delete-item
|
|
748
738
|
/**
|
|
@@ -822,9 +812,8 @@ Both take the table's name or its ARN, as the table commands do.
|
|
|
822
812
|
|
|
823
813
|
## Updating items
|
|
824
814
|
|
|
825
|
-
`UpdateItem` changes
|
|
826
|
-
|
|
827
|
-
Each keyword appears at most once, and the actions inside a clause are separated by commas.
|
|
815
|
+
`UpdateItem` changes selected attributes. Its `UpdateExpression` may contain `SET`, `REMOVE`, `ADD`
|
|
816
|
+
and `DELETE` clauses in any order. Each clause may appear once and contain comma-separated actions.
|
|
828
817
|
|
|
829
818
|
A `SET` action is `path = operand`, where an operand is a value from `ExpressionAttributeValues`,
|
|
830
819
|
another document path, or a call to `if_not_exists(path, operand)` or `list_append(one, other)`. Two
|
|
@@ -1066,12 +1055,11 @@ placeholder used by either counts as used.
|
|
|
1066
1055
|
|
|
1067
1056
|
## Conditional writes
|
|
1068
1057
|
|
|
1069
|
-
`PutItem`, `DeleteItem` and `UpdateItem`
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
uses.
|
|
1058
|
+
`PutItem`, `DeleteItem` and `UpdateItem` evaluate `ConditionExpression` against the stored item before
|
|
1059
|
+
writing. A failed condition leaves the item unchanged and raises
|
|
1060
|
+
`ConditionalCheckFailedException`.
|
|
1073
1061
|
|
|
1074
|
-
|
|
1062
|
+
Use `attribute_not_exists` for insert-only writes or compare a version attribute for optimistic
|
|
1075
1063
|
locking.
|
|
1076
1064
|
|
|
1077
1065
|
```typescript sim-dynamodb-conditional-write
|
|
@@ -1176,9 +1164,8 @@ expression, in both directions. A placeholder the request leaves undefined is a
|
|
|
1176
1164
|
|
|
1177
1165
|
## Projecting attributes
|
|
1178
1166
|
|
|
1179
|
-
`
|
|
1180
|
-
|
|
1181
|
-
indexes, such as `address.city` or `lines[0].sku`.
|
|
1167
|
+
`ProjectionExpression` is a comma-separated list of document paths returned by `GetItem`. A path can
|
|
1168
|
+
contain map attributes and list indexes, such as `address.city` or `lines[0].sku`.
|
|
1182
1169
|
|
|
1183
1170
|
An attribute name that is a DynamoDB reserved word, or that has a character an expression cannot
|
|
1184
1171
|
carry, is written as a `#name` placeholder and defined in `ExpressionAttributeNames`.
|
|
@@ -1259,12 +1246,11 @@ index and a path past that depth are each a `ValidationException` naming the pat
|
|
|
1259
1246
|
|
|
1260
1247
|
## Querying an item collection
|
|
1261
1248
|
|
|
1262
|
-
A table with a sort key
|
|
1263
|
-
|
|
1249
|
+
A table with a sort key keeps one ordered item collection per partition key. `Query` reads one
|
|
1250
|
+
collection.
|
|
1264
1251
|
|
|
1265
|
-
`KeyConditionExpression`
|
|
1266
|
-
`AND
|
|
1267
|
-
`BETWEEN` or `begins_with`, and both bounds of a `BETWEEN` are inside the range.
|
|
1252
|
+
`KeyConditionExpression` requires equality on the partition key. It may add one sort key condition
|
|
1253
|
+
with `AND`. Sort key operators are `=`, `<`, `<=`, `>`, `>=`, `BETWEEN` and `begins_with`.
|
|
1268
1254
|
|
|
1269
1255
|
```typescript sim-dynamodb-query
|
|
1270
1256
|
/**
|
|
@@ -1371,8 +1357,8 @@ in `ExpressionAttributeNames`, as in any other expression.
|
|
|
1371
1357
|
|
|
1372
1358
|
### Paging a collection
|
|
1373
1359
|
|
|
1374
|
-
`Limit` counts
|
|
1375
|
-
|
|
1360
|
+
`Limit` counts evaluated items. Pass `LastEvaluatedKey` back as `ExclusiveStartKey` to continue after
|
|
1361
|
+
the last evaluated item.
|
|
1376
1362
|
|
|
1377
1363
|
```typescript sim-dynamodb-query-paging
|
|
1378
1364
|
/**
|
|
@@ -1447,9 +1433,7 @@ from a different partition key is refused, since it names a collection this quer
|
|
|
1447
1433
|
|
|
1448
1434
|
## Reading a global secondary index
|
|
1449
1435
|
|
|
1450
|
-
`IndexName` on `Query`
|
|
1451
|
-
the index key schema and not the table's, which is the point. The index is how an access pattern the
|
|
1452
|
-
table key cannot serve gets served.
|
|
1436
|
+
Set `IndexName` on `Query` or `Scan` to read an index. Key conditions then use the index key schema.
|
|
1453
1437
|
|
|
1454
1438
|
```typescript sim-dynamodb-query-index
|
|
1455
1439
|
/**
|
|
@@ -1572,9 +1556,8 @@ refused.
|
|
|
1572
1556
|
|
|
1573
1557
|
## Scanning a table
|
|
1574
1558
|
|
|
1575
|
-
`Scan` reads every item in a table
|
|
1576
|
-
|
|
1577
|
-
patterns, since it reads the whole table however few items the caller wanted.
|
|
1559
|
+
`Scan` reads every item in a table without a key condition. It is useful for test assertions but
|
|
1560
|
+
usually reads more data than application code needs.
|
|
1578
1561
|
|
|
1579
1562
|
```typescript sim-dynamodb-scan
|
|
1580
1563
|
/**
|
|
@@ -1,31 +1,20 @@
|
|
|
1
1
|
# Simulated ECR
|
|
2
2
|
|
|
3
|
-
Yulin
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
That is what this service is for. A container image Lambda function cannot run here, because Yulin
|
|
7
|
-
never reads an image, so something has to say what the code inside that image actually is. A
|
|
8
|
-
repository is the natural place to say it. It is the stable name for the thing that holds the code,
|
|
9
|
-
outliving any tag and any CDK construct ID, and a repository holding a registered handler outlives
|
|
10
|
-
the stack that declared it too.
|
|
3
|
+
Yulin represents an ECR image with an in-process Lambda handler. Register the handler against a
|
|
4
|
+
repository and tag, then deploy or create a container image function that uses the image URI.
|
|
11
5
|
|
|
12
6
|
ECR-specific types are imported from the `@kensio/yulin/ecr` subpath.
|
|
13
7
|
|
|
14
8
|
## What a simulated image is
|
|
15
9
|
|
|
16
|
-
An image URI
|
|
17
|
-
manifest, digest or scan finding exists. A simulated image is a handler function, registered against
|
|
18
|
-
a repository and a tag.
|
|
10
|
+
An image URI identifies a registered handler. Image content remains outside the simulation.
|
|
19
11
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
registry protocol. None of that happens in this process, and a simulated `PutImage` would be a
|
|
23
|
-
command taking an argument nothing could produce.
|
|
12
|
+
Use the Yulin-specific `simulateImage` method to register a handler. The simulated surface has no
|
|
13
|
+
ECR SDK or Docker registry operations.
|
|
24
14
|
|
|
25
15
|
## Registering a handler as an image
|
|
26
16
|
|
|
27
|
-
Register the handler
|
|
28
|
-
is created from it.
|
|
17
|
+
Register the handler during test setup. Lambda resolves image functions from the same repository.
|
|
29
18
|
|
|
30
19
|
```typescript sim-ecr-register-image
|
|
31
20
|
/**
|
|
@@ -82,36 +71,22 @@ console.log(Buffer.from(output.Payload).toString());
|
|
|
82
71
|
await simAws.backgroundTasksComplete();
|
|
83
72
|
```
|
|
84
73
|
|
|
85
|
-
|
|
86
|
-
declaration to make, and a test can name the repository its templates already point at.
|
|
74
|
+
Calling `repository(name)` creates the repository if it is absent.
|
|
87
75
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
belongs to. A name real ECR would refuse is refused here too.
|
|
76
|
+
Pass a repository name such as `orders` or `platform/orders`. The selected simulated account and
|
|
77
|
+
Region supply the registry host.
|
|
91
78
|
|
|
92
79
|
## How an image URI is matched
|
|
93
80
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
into a test. A CDK image asset is tagged with the asset content hash, which changes whenever the
|
|
99
|
-
image source does, and a pipeline-built image is usually tagged with a git sha or a build number
|
|
100
|
-
passed in as a stack parameter. An `ImageUri` built by `Fn::Sub` or from a stack parameter is
|
|
101
|
-
matched on what it resolves to.
|
|
81
|
+
Yulin first matches the registry host and repository name. It then looks for the requested tag. A
|
|
82
|
+
registered tag selects that handler. An unknown tag, a digest or no tag selects the most recently
|
|
83
|
+
registered handler. This fallback lets content-hash and build-number tags resolve without copying
|
|
84
|
+
those generated values into the test.
|
|
102
85
|
|
|
103
|
-
|
|
104
|
-
|
|
86
|
+
The registry host determines the account and Region. Repositories with the same name in different
|
|
87
|
+
scopes remain separate. Cross-account image references are supported.
|
|
105
88
|
|
|
106
|
-
|
|
107
|
-
run an image from another account's repository, as it can on real AWS, and a same-named repository
|
|
108
|
-
in another account is a different repository.
|
|
109
|
-
|
|
110
|
-
So `orders:blue` runs the handler registered under `blue` where the repository holds one, and the
|
|
111
|
-
handler registered most recently otherwise. That is how a blue/green pair of images in one
|
|
112
|
-
repository can back two functions differently, while a content hash tag nobody registered still
|
|
113
|
-
finds something to run. Registering a tag again both replaces what it held and makes it the most
|
|
114
|
-
recent registration.
|
|
89
|
+
Registering a tag again replaces its handler and makes that handler the most recent registration.
|
|
115
90
|
|
|
116
91
|
```typescript sim-ecr-image-tags
|
|
117
92
|
/**
|
|
@@ -152,18 +127,15 @@ console.log(Buffer.from(output.Payload).toString()); // "blue handler"
|
|
|
152
127
|
await simAws.backgroundTasksComplete();
|
|
153
128
|
```
|
|
154
129
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
the way real Lambda refuses a function whose image it cannot pull.
|
|
130
|
+
Direct `CreateFunction` calls and CloudFormation deployments use the same resolution rules. Lambda
|
|
131
|
+
refuses an image URI that resolves to no handler.
|
|
158
132
|
|
|
159
133
|
## Repositories in CloudFormation
|
|
160
134
|
|
|
161
|
-
`AWS::ECR::Repository
|
|
162
|
-
|
|
163
|
-
been registered in it.
|
|
135
|
+
Simulated CloudFormation creates `AWS::ECR::Repository`. The repository starts empty unless a
|
|
136
|
+
handler was already registered under its name.
|
|
164
137
|
|
|
165
|
-
`Ref` returns the repository name
|
|
166
|
-
application stack can build its function's `ImageUri` from the repository a platform stack declared.
|
|
138
|
+
`Ref` returns the repository name. `Fn::GetAtt` supports `Arn` and `RepositoryUri`.
|
|
167
139
|
|
|
168
140
|
```typescript sim-ecr-cloudformation-repository
|
|
169
141
|
/**
|
|
@@ -236,34 +208,23 @@ console.log(Buffer.from(output.Payload).toString());
|
|
|
236
208
|
await simAws.backgroundTasksComplete();
|
|
237
209
|
```
|
|
238
210
|
|
|
239
|
-
A
|
|
240
|
-
difference. The image can exist before the stack that declares the repository, as it does in real
|
|
241
|
-
life.
|
|
211
|
+
A deployment adopts a repository that already contains a registered handler.
|
|
242
212
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
registered outside any stack and is what every later deploy resolves to. Real ECR also refuses to
|
|
246
|
-
delete a repository that still holds images, which fails the stack unless the template says
|
|
247
|
-
`EmptyOnDelete`. Here the refusal is recorded and the teardown carries on, since what is being
|
|
248
|
-
protected is a test's own registration.
|
|
213
|
+
Stack teardown removes an empty repository. A repository containing a handler remains in place and
|
|
214
|
+
its deletion is recorded as skipped. Teardown continues after the skipped deletion.
|
|
249
215
|
|
|
250
|
-
|
|
251
|
-
is created without it. That covers `ImageScanningConfiguration`, `ImageTagMutability`,
|
|
216
|
+
Other repository properties are recorded as ignored. These include `ImageScanningConfiguration`, `ImageTagMutability`,
|
|
252
217
|
`LifecyclePolicy`, `RepositoryPolicyText`, `EncryptionConfiguration`, `EmptyOnDelete` and `Tags`.
|
|
253
218
|
|
|
254
219
|
## Where a function's handler comes from
|
|
255
220
|
|
|
256
|
-
|
|
221
|
+
Yulin resolves a container image function in this order:
|
|
257
222
|
|
|
258
|
-
1. An [executable binding](https://yulinsim.dev/services/lambda/#executable-bindings)
|
|
259
|
-
|
|
260
|
-
one deploy.
|
|
261
|
-
2. The simulated ECR repository the function's `Code.ImageUri` names. That is a standing statement
|
|
262
|
-
about what the image is, made once and good for every stack that runs it.
|
|
223
|
+
1. An [executable binding](https://yulinsim.dev/services/lambda/#executable-bindings) supplied for the deployment.
|
|
224
|
+
2. The handler registered in the ECR repository named by `Code.ImageUri`.
|
|
263
225
|
|
|
264
|
-
A function with no binding
|
|
265
|
-
|
|
266
|
-
different places. One is a wrong name, and the other is a handler that was never registered.
|
|
226
|
+
A function with no binding or registered image is skipped. The diagnostic distinguishes a missing
|
|
227
|
+
repository from a repository with no handlers.
|
|
267
228
|
|
|
268
229
|
## Available functionality
|
|
269
230
|
|
|
@@ -278,16 +239,14 @@ different places. One is a wrong name, and the other is a handler that was never
|
|
|
278
239
|
|
|
279
240
|
## Limitations
|
|
280
241
|
|
|
281
|
-
Current documented limitations:
|
|
282
|
-
|
|
283
242
|
- No image content, layer, digest, manifest or scan behaviour is simulated. A repository holds
|
|
284
243
|
handlers, and no image is ever pulled or inspected.
|
|
285
244
|
- There are no ECR SDK commands. `CreateRepository`, `DescribeRepositories`, `PutImage`,
|
|
286
245
|
`DescribeImages`, `BatchDeleteImage` and `GetAuthorizationToken` are all absent. Registering an
|
|
287
246
|
image is a Yulin-native operation because real `PutImage` takes a manifest for layers pushed over
|
|
288
247
|
the Docker registry protocol, and that protocol never runs in this process.
|
|
289
|
-
-
|
|
290
|
-
|
|
248
|
+
- CloudFormation authorizes `ecr:CreateRepository` and `ecr:DeleteRepository`. Handler registration
|
|
249
|
+
has no caller and skips authorization. Repository policies are ignored.
|
|
291
250
|
- Lifecycle policies go unevaluated, and no simulated image ever expires. Tag mutability goes
|
|
292
251
|
unenforced, and registering the same tag again replaces what it held.
|
|
293
252
|
- Naming a repository creates it. There is no `CreateRepository` to fail for a name already taken,
|
|
@@ -295,8 +254,8 @@ Current documented limitations:
|
|
|
295
254
|
- A stack teardown records the deletion of a repository holding a simulated image and carries on,
|
|
296
255
|
where real CloudFormation fails the stack unless the template says `EmptyOnDelete`. The repository
|
|
297
256
|
and its handler are left in place, and `EmptyOnDelete` itself goes unread.
|
|
298
|
-
-
|
|
299
|
-
|
|
257
|
+
- The repository model records no owning stack. Teardown of any declaring stack removes an empty
|
|
258
|
+
repository.
|
|
300
259
|
- Repository tags, registry policies, pull through cache rules, replication configuration and ECR
|
|
301
|
-
Public are
|
|
302
|
-
-
|
|
260
|
+
Public are absent.
|
|
261
|
+
- `serveSimAws` exposes no ECR HTTP API or Docker registry endpoint.
|