@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.
Files changed (74) hide show
  1. package/README.md +22 -2
  2. package/dist/service/eventbridge/cfn/bus/sim-cfn-event-bus-creator.js +1 -0
  3. package/dist/service/eventbridge/cfn/bus/sim-cfn-event-bus-properties.d.ts +4 -0
  4. package/dist/service/eventbridge/cfn/bus/sim-cfn-event-bus-properties.js +26 -1
  5. package/dist/service/eventbridge/cfn/rule/sim-cfn-event-rule-creator.js +3 -1
  6. package/dist/service/eventbridge/cfn/rule/sim-cfn-event-rule-properties.d.ts +0 -7
  7. package/dist/service/eventbridge/cfn/rule/sim-cfn-event-rule-properties.js +0 -20
  8. package/dist/service/eventbridge/cfn/rule/sim-cfn-event-rule-unsimulated-properties.d.ts +13 -0
  9. package/dist/service/eventbridge/cfn/rule/sim-cfn-event-rule-unsimulated-properties.js +59 -0
  10. package/dist/service/eventbridge/cfn/sim-cfn-event-bridge-resource-error.d.ts +1 -1
  11. package/dist/service/eventbridge/cfn/sim-cfn-event-bridge-resource-error.js +1 -1
  12. package/dist/service/lambda/cfn/event-source-mapping/sim-cfn-lambda-event-source-mapping-properties.js +1 -1
  13. package/dist/service/lambda/cfn/event-source-mapping/sim-cfn-lambda-event-source-mapping-property-rules.d.ts +3 -2
  14. package/dist/service/lambda/cfn/event-source-mapping/sim-cfn-lambda-event-source-mapping-property-rules.js +25 -3
  15. package/dist/service/ses/command/authorize/sim-ses-authorizer.d.ts +9 -0
  16. package/dist/service/ses/command/authorize/sim-ses-authorizer.js +18 -2
  17. package/dist/service/ses/command/send/sim-ses-send-email.js +2 -1
  18. package/dist/service/sns/cfn/topic/sim-cfn-sns-topic-creator.js +1 -0
  19. package/dist/service/sns/cfn/topic/sim-cfn-sns-topic-properties.d.ts +9 -4
  20. package/dist/service/sns/cfn/topic/sim-cfn-sns-topic-properties.js +18 -6
  21. package/dist/service/sns/cfn/topic/sim-cfn-sns-topic-property-names.d.ts +10 -0
  22. package/dist/service/sns/cfn/topic/sim-cfn-sns-topic-property-names.js +16 -1
  23. package/dist/service/ssm/cfn/parameter/sim-cfn-ssm-parameter-creator.js +1 -1
  24. package/dist/service/ssm/cfn/parameter/sim-cfn-ssm-parameter-properties.d.ts +11 -6
  25. package/dist/service/ssm/cfn/parameter/sim-cfn-ssm-parameter-properties.js +18 -9
  26. package/docs/README.md +40 -4
  27. package/docs/ai-skill/README.md +57 -54
  28. package/docs/cli/README.md +84 -94
  29. package/docs/factories/README.md +42 -54
  30. package/docs/lint/README.md +41 -67
  31. package/docs/non-aws-dependencies/README.md +72 -168
  32. package/docs/sdk/README.md +109 -95
  33. package/docs/serve/README.md +192 -898
  34. package/docs/services/acm/README.md +24 -40
  35. package/docs/services/apigateway/README.md +52 -71
  36. package/docs/services/apigatewayv2/README.md +55 -74
  37. package/docs/services/athena/README.md +17 -26
  38. package/docs/services/backup/README.md +29 -39
  39. package/docs/services/bedrock/README.md +38 -52
  40. package/docs/services/cloudformation/README.md +43 -55
  41. package/docs/services/cloudfront/README.md +69 -95
  42. package/docs/services/cloudwatch/README.md +40 -54
  43. package/docs/services/cognito/README.md +30 -45
  44. package/docs/services/dynamodb/README.md +34 -51
  45. package/docs/services/ecr/README.md +36 -77
  46. package/docs/services/ecs/README.md +26 -46
  47. package/docs/services/elbv2/README.md +19 -29
  48. package/docs/services/eventbridge/README.md +24 -20
  49. package/docs/services/firehose/README.md +24 -32
  50. package/docs/services/glue/README.md +41 -78
  51. package/docs/services/iam/README.md +13 -15
  52. package/docs/services/kinesis/README.md +53 -93
  53. package/docs/services/kms/README.md +22 -32
  54. package/docs/services/lambda/README.md +60 -80
  55. package/docs/services/logs/README.md +41 -50
  56. package/docs/services/organizations/README.md +50 -85
  57. package/docs/services/personalize/README.md +28 -44
  58. package/docs/services/rekognition/README.md +26 -38
  59. package/docs/services/route53/README.md +17 -17
  60. package/docs/services/s3/README.md +47 -51
  61. package/docs/services/scheduler/README.md +41 -52
  62. package/docs/services/secretsmanager/README.md +27 -42
  63. package/docs/services/ses/README.md +24 -34
  64. package/docs/services/sns/README.md +31 -33
  65. package/docs/services/sqs/README.md +14 -14
  66. package/docs/services/ssm/README.md +19 -21
  67. package/docs/services/stepfunctions/README.md +18 -20
  68. package/docs/services/sts/README.md +32 -45
  69. package/docs/services/wafv2/README.md +12 -17
  70. package/docs/terraform/README.md +108 -126
  71. package/docs/testing/README.md +228 -0
  72. package/docs/time/README.md +87 -117
  73. package/llms.txt +2 -1
  74. package/package.json +1 -1
@@ -1,27 +1,23 @@
1
- # Simulated AWS SDK
1
+ # AWS SDK interception
2
2
 
3
- Yulin can intercept AWS SDK clients and route their Commands to simulated AWS services. The code
4
- under test uses the AWS SDK as it would in production, and needs no knowledge of the simulator.
3
+ `SimSdk` routes AWS SDK for JavaScript v3 commands to Yulin. Use it to test code that already sends
4
+ commands through AWS SDK clients.
5
5
 
6
- This is the recommended way to test implementation code that already uses the AWS SDK. Direct
7
- interaction with `SimAws` remains useful for seeding and inspecting simulated state from within
8
- tests.
6
+ ## Install interception in suite setup
9
7
 
10
- ## How it works
8
+ Application tests should normally create one `SimSdk` in Vitest suite setup and keep its class
9
+ interceptions installed for the whole suite. Every SDK client then reaches the same simulated state,
10
+ including clients created in different test files.
11
11
 
12
- `SimSdk` replaces the `send` method of an intercepted SDK client. Each sent Command is routed by
13
- name to the matching operation of a simulated AWS service, and the result comes back to the caller
14
- as a normal SDK response. Every Command is served in process.
12
+ The [test suite setup guide](https://yulinsim.dev/testing/) shows how to share one in-process
13
+ environment across Vitest files. It also covers the worker and isolation settings this requires.
14
+ A separate `SimSdk` for each test or file remains supported when a case needs an empty environment.
15
+ Tests that control the simulation's clock should use a separate `SimSdk` so their time changes cannot
16
+ affect the shared suite.
15
17
 
16
- Every `SimSdk` owns a simulated AWS environment. You can let it create its own, or give it an
17
- existing one to share:
18
+ ## Intercept a client
18
19
 
19
- - `new SimSdk()` creates an isolated `SimAws` internally, available as `simSdk.simAws`.
20
- - `new SimSdk({ simAws })` wraps a `SimAws` you already have.
21
-
22
- ## Basic usage
23
-
24
- Intercept an SDK client class, then use the SDK as normal:
20
+ Create a `SimSdk`, intercept a client class, and run the code under test:
25
21
 
26
22
  ```typescript sim-sdk-intercept-s3
27
23
  /**
@@ -58,36 +54,33 @@ console.log(await output.Body?.transformToString()); // "Hello, world!"
58
54
  simSdk.restoreAll();
59
55
  ```
60
56
 
61
- You can intercept a client class or a client instance:
57
+ Intercepting a class affects every instance of that class. This includes clients created after the
58
+ call to `intercept`. Intercepting an object affects that client only.
59
+
60
+ `SimSdk` replaces the intercepted client's `send` method. It routes each command to the matching
61
+ Yulin service and returns an SDK-shaped response. The request stays inside the process.
62
62
 
63
- - **A class** (`simSdk.intercept(S3Client)`) intercepts every instance of it, including instances
64
- the code under test constructs later. This is the most common choice.
65
- - **An instance** (`simSdk.intercept(s3Client)`) intercepts only that instance. Use it when one
66
- client should hit the simulator and the others are handled some other way.
63
+ A client can have one active interception. A second interception throws
64
+ `SimSdkAlreadyInterceptedError` and leaves the first one in place.
67
65
 
68
- A client can only have one interception at a time. Intercepting an already-intercepted client
69
- throws a diagnostic error, and the existing interception stays in place.
66
+ ## Access simulated state
70
67
 
71
- ## Account and Region scope
68
+ `new SimSdk()` creates a `SimAws` instance and exposes it as `simSdk.simAws`. Use that instance to
69
+ prepare state before running the application, or to inspect state afterwards.
72
70
 
73
- Each sent Command resolves its own simulated Account and Region scope:
71
+ Pass an existing instance as `new SimSdk({ simAws })` when several parts of a test need to share the
72
+ same simulation.
74
73
 
75
- 1. The **Region** comes from the sending client's own configuration, such as
76
- `new S3Client({ region: "eu-west-2" })`, falling back to the simulation default.
77
- 2. The **Account** comes from the ambient `simAws.runAs(...)` caller when one is set, falling back
78
- to the simulation default Account.
74
+ ## Account and region
79
75
 
80
- The resolved caller reaches the simulated service, and simulated [IAM](https://yulinsim.dev/services/iam/)
81
- authorization applies to it exactly as it does for direct sim service use. A caller without
82
- permission for a Command is denied, as on real AWS. Where no caller can be identified, Commands run
83
- as the simulation's `defaultCaller`, and as the default Account root where the simulation was given
84
- none. See
85
- [Name the caller a simulation uses by default](https://yulinsim.dev/services/iam/#name-the-caller-a-simulation-uses-by-default).
76
+ Yulin resolves the account and region for every `send` call. The client's `region` configuration
77
+ selects the simulated region. Yulin uses its default region when the client has none.
86
78
 
87
- `runAs` runs a function with an ambient simulated caller, such as an IAM Role. Commands sent during
88
- the run are attributed to that caller, with no changes to the client or the code under test. A
89
- direct sim service call inside the run is attributed to it too, covered in
90
- [Run a block of calls as one caller](https://yulinsim.dev/services/iam/#run-a-block-of-calls-as-one-caller):
79
+ The current `simAws.runAs(...)` caller selects the account. Without a `runAs` caller, Yulin uses the
80
+ simulation's default account and caller. Simulated [IAM](https://yulinsim.dev/services/iam/)
81
+ authorization applies to intercepted commands.
82
+
83
+ Use `runAs` to send commands as a role without changing the client or the application code:
91
84
 
92
85
  ```typescript sim-sdk-run-as
93
86
  /**
@@ -155,31 +148,34 @@ await simAws.runAs(
155
148
  simSdk.restoreAll();
156
149
  ```
157
150
 
158
- The ambient caller belongs to its own `SimAws` instance. Separate simulations in the same process
159
- each keep their own.
151
+ `runAs` applies only to the `SimAws` instance on which it was called. A caller set on another
152
+ simulation does not affect these commands.
153
+
154
+ ## Restore the client
155
+
156
+ Restore an interception before later code needs the client's original `send` method:
160
157
 
161
- ## Restoring interception
158
+ - Save the result of `simSdk.intercept(...)` and call its `restore()` method to restore one client.
159
+ - Call `simSdk.restoreAll()` to restore every client intercepted by that `SimSdk`.
160
+ - Declare `SimSdk` or an interception handle with `using` to restore it when the scope ends.
162
161
 
163
- Restoring puts back the client's real SDK `send`:
162
+ A suite-wide interception stays installed until the test worker exits. Do not restore it in a
163
+ per-file `afterAll`, since later files use the same interception and simulated state.
164
164
 
165
- - `interception.restore()` restores one interception. `simSdk.intercept(...)` returns the handle.
166
- - `simSdk.restoreAll()` restores everything intercepted through that `SimSdk`.
167
- - `SimSdk` and interception handles are disposable. `using simSdk = new SimSdk();` restores
168
- automatically at the end of the scope.
165
+ ## Limit the intercepted commands
169
166
 
170
- ## Choosing Commands to intercept
167
+ An interception handles every command by default. Pass an allow list when a test should accept only
168
+ specific commands:
171
169
 
172
- By default every Command sent through an intercepted client is routed to the simulator. To
173
- intercept only specific Commands, pass an allow list of Command classes or names:
174
- `simSdk.intercept(s3Client, { commands: [GetObjectCommand] })`. Commands outside the allow list
175
- throw a diagnostic error.
170
+ `simSdk.intercept(s3Client, { commands: [GetObjectCommand] })`
176
171
 
177
- ## The DynamoDB document client
172
+ The list accepts command classes or command names. Sending another command throws
173
+ `SimSdkCommandNotInterceptedError`.
178
174
 
179
- `@aws-sdk/lib-dynamodb` takes plain JavaScript values. Application code writes
180
- `{ id: "a", count: 1 }` where the base client wants `{ id: { S: "a" }, count: { N: "1" } }`.
181
- Intercept the document client and its Commands reach simulated DynamoDB with the values already
182
- converted. Code written against the document client runs against the simulator unchanged.
175
+ ## Intercept the DynamoDB document client
176
+
177
+ The DynamoDB document client accepts plain JavaScript values. Intercept the document client object,
178
+ then send `@aws-sdk/lib-dynamodb` commands through it:
183
179
 
184
180
  ```typescript sim-sdk-document-client
185
181
  /**
@@ -232,43 +228,61 @@ console.log(read.Item?.["total"]); // 42
232
228
  console.log(read.Item?.["paid"]); // true
233
229
  ```
234
230
 
235
- `DynamoDBDocumentClient.from(client)` builds a separate object of its own class. Intercepting the
236
- base client therefore leaves Commands sent through the document client alone. Intercept the
237
- document client. Both can be intercepted at once, and they reach
238
- the same simulated tables, since the document client shares the base client's config and so
239
- resolves the same Account and Region.
240
-
241
- The real document client converts values in middleware, which runs inside the `send` that
242
- interception replaces. So the conversion happens at the interception boundary instead, using the
243
- option defaults `lib-dynamodb` sets (not the `util-dynamodb` ones). Which native types map to which
244
- descriptors is in [the sim DynamoDB docs](https://yulinsim.dev/services/dynamodb/#the-document-client).
245
-
246
- ## Supported services and Commands
247
-
248
- These simulated services support SDK interception: ACM, API Gateway v2, CloudFormation, CloudFront,
249
- CloudWatch, CloudWatch Logs, Cognito, DynamoDB, DynamoDB Streams, ECS, Elastic Load Balancing v2,
250
- EventBridge, EventBridge Scheduler, IAM, KMS, Lambda, Rekognition, Route53, S3, Secrets Manager,
251
- SES, SNS, SQS, SSM, STS and WAFv2. Each service's own docs list the Commands it
252
- simulates.
253
-
254
- A gap in that coverage is refused on send, with a different error for each kind:
255
-
256
- - A Command the simulated service doesn't support throws `SimSdkUnsupportedCommandError`, naming the
257
- Command and listing the Commands that service does support.
258
- - A client for an AWS service Yulin doesn't simulate at all throws `SimSdkUnknownServiceError`,
259
- naming the service. There is no Command list to report, since no simulated service was resolved.
231
+ `DynamoDBDocumentClient.from(client)` returns a separate client object. Intercept that object, not
232
+ the base `DynamoDBClient`. You may intercept both clients. They use the same simulated tables when
233
+ their account and region match.
234
+
235
+ Yulin converts document values at the interception boundary. It uses the default translation
236
+ options from `@aws-sdk/lib-dynamodb`. The [DynamoDB documentation](https://yulinsim.dev/services/dynamodb/#the-document-client)
237
+ lists the supported value conversions.
238
+
239
+ ## Available functionality
240
+
241
+ SDK interception supports these service clients:
242
+
243
+ - ACM
244
+ - API Gateway REST APIs and HTTP APIs
245
+ - Athena
246
+ - AWS Backup
247
+ - Bedrock Runtime
248
+ - CloudFormation
249
+ - CloudFront and CloudFront KeyValueStore
250
+ - CloudWatch metrics and CloudWatch Logs
251
+ - Cognito Identity Provider
252
+ - DynamoDB and DynamoDB Streams
253
+ - ECS and Elastic Load Balancing v2
254
+ - EventBridge and EventBridge Scheduler
255
+ - Glue
256
+ - IAM
257
+ - Kinesis Data Firehose and Kinesis Data Streams
258
+ - KMS
259
+ - Lambda
260
+ - Personalize, Personalize Events, and Personalize Runtime
261
+ - Rekognition
262
+ - Route 53
263
+ - S3
264
+ - Secrets Manager
265
+ - SESv2
266
+ - SNS and SQS
267
+ - SSM
268
+ - Step Functions
269
+ - STS
270
+ - WAFv2
271
+
272
+ Each service page lists the commands that service accepts. An unsupported command throws
273
+ `SimSdkUnsupportedCommandError` and includes the supported command names. A client for an unknown
274
+ service throws `SimSdkUnknownServiceError`.
260
275
 
261
276
  ## Limitations
262
277
 
263
- - Only `client.send(command)` is intercepted. SDK utilities that bypass `send`, such as
264
- `getSignedUrl`, run against real AWS. Paginators and waiters go through `send`, so they work. Presigning works without interception. Point the client at the simulated endpoint, as
265
- [the sim S3 presigned URL docs](https://yulinsim.dev/services/s3/#presigned-urls) show.
266
- - Simulated errors carry SDK-shaped `name` and `$metadata`, but are not instances of the real SDK
267
- exception classes. Match an error by its `error.name`. An `instanceof` check against the SDK class
268
- fails.
278
+ - Yulin intercepts `client.send(command)`. SDK utilities that bypass `send`, including
279
+ `getSignedUrl`, bypass interception. Paginators and waiters use `send` and can be intercepted. To
280
+ use a presigned URL with Yulin, point the client at a served endpoint as shown in the
281
+ [S3 documentation](https://yulinsim.dev/services/s3/#presigned-urls).
282
+ - Simulated errors have SDK-shaped `name` and `$metadata` fields. They are separate classes from the
283
+ SDK exceptions, so match them by `error.name` instead of `instanceof`.
269
284
  - The callback form of `send(command, callback)` is not supported. Use the promise form.
270
- - The translate config a document client is built with,
271
- `DynamoDBDocumentClient.from(client, { marshallOptions, unmarshallOptions })`, is ignored. The
272
- conversion always uses the defaults. `removeUndefinedValues: true` in particular has no effect
273
- here, and an `undefined` attribute is refused where AWS would have dropped it. The refusal names
274
- the attribute and says so.
285
+ - Yulin ignores the translation options in
286
+ `DynamoDBDocumentClient.from(client, { marshallOptions, unmarshallOptions })`. The conversion uses
287
+ the defaults. `removeUndefinedValues: true` has no effect. Yulin refuses an `undefined` attribute
288
+ that the configured document client would otherwise remove.