@kensio/yulin 1.21.6 → 1.21.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/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/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 +33 -4
- package/docs/ai-skill/README.md +52 -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 +97 -98
- package/docs/serve/README.md +192 -898
- package/docs/services/eventbridge/README.md +10 -2
- package/docs/services/lambda/README.md +7 -1
- package/docs/services/sns/README.md +13 -7
- package/docs/services/ssm/README.md +6 -4
- package/docs/terraform/README.md +108 -126
- package/docs/time/README.md +80 -120
- package/llms.txt +1 -1
- package/package.json +1 -1
package/docs/time/README.md
CHANGED
|
@@ -1,24 +1,12 @@
|
|
|
1
1
|
# Simulated time
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
depends on time passing, such as a temporary session expiring, can be tested without waiting for it.
|
|
3
|
+
Each `SimAws` has its own clock. Yulin uses that clock for resource timestamps, expiry checks, and
|
|
4
|
+
scheduled work.
|
|
6
5
|
|
|
7
|
-
|
|
8
|
-
simulation running in the same test file, and any other code in the process all carry on unchanged.
|
|
6
|
+
## Start at a known time
|
|
9
7
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
`simAws.now()` is what the simulation means by "now". The host clock may say something different. It
|
|
13
|
-
also stamps simulated resources, such as an IAM User's `CreateDate` and an `AssumeRole` session's
|
|
14
|
-
`Expiration`.
|
|
15
|
-
|
|
16
|
-
By default a new `SimAws` runs in step with the real system clock.
|
|
17
|
-
|
|
18
|
-
## Starting at a known instant
|
|
19
|
-
|
|
20
|
-
Pass a clock to start somewhere specific. `SimFixedClock` is the usual choice, since it reports one
|
|
21
|
-
instant and stays there:
|
|
8
|
+
A new simulation follows the system clock by default. Pass a `SimFixedClock` when a test needs an
|
|
9
|
+
exact starting time:
|
|
22
10
|
|
|
23
11
|
```typescript sim-clock-freeze-and-advance
|
|
24
12
|
/**
|
|
@@ -47,41 +35,33 @@ console.log(simAws.now()); // 2026-07-26T11:30:00.000Z
|
|
|
47
35
|
simAws.clock().resume();
|
|
48
36
|
```
|
|
49
37
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
built on a `SimFixedClock` puts it back in running mode, and its time then moves whenever the clock
|
|
53
|
-
underneath moves. A fixed clock stays where it is. Leave the default real clock in place for a
|
|
54
|
-
simulation whose time should pass by itself.
|
|
38
|
+
`simAws.now()` returns the current simulated time. Services use the same value when they create
|
|
39
|
+
timestamps such as an IAM user's `CreateDate`.
|
|
55
40
|
|
|
56
|
-
|
|
41
|
+
The controllable clock sits on top of the clock passed to `SimAws`. Calling `resume()` makes time
|
|
42
|
+
follow that underlying clock again. A `SimFixedClock` never moves, so resuming it still reports a
|
|
43
|
+
fixed time. Keep the default system clock when resumed time should move normally.
|
|
57
44
|
|
|
58
|
-
|
|
45
|
+
## Frozen and running
|
|
59
46
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
- **Running**: simulated time tracks the clock underneath, offset from it. On the default real clock
|
|
64
|
-
time passes by itself. Use it to jump forward an hour and carry on.
|
|
47
|
+
Call `freeze()` to stop the clock at its current time. Both `setTo(...)` and `advanceBy(...)` also
|
|
48
|
+
leave the clock frozen at the resulting time. This keeps timestamps stable while the test makes its
|
|
49
|
+
assertions.
|
|
65
50
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
long the assertion takes. `resume()` is the way back to running, and it carries on from where the
|
|
69
|
-
clock stopped.
|
|
51
|
+
Call `resume()` to let the underlying clock move time again. Any offset remains in place. For
|
|
52
|
+
example, a simulation advanced by one hour continues to run one hour ahead of the system clock.
|
|
70
53
|
|
|
71
|
-
`simAws.clock().isFrozen`
|
|
54
|
+
Read `simAws.clock().isFrozen` to check the current mode.
|
|
72
55
|
|
|
73
56
|
## Advancing time
|
|
74
57
|
|
|
75
|
-
`advanceBy(...)`
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
passing only runs forwards. `setTo(...)` is the explicit way to move a clock back.
|
|
58
|
+
`advanceBy(...)` accepts days, hours, minutes, seconds, and milliseconds. The values are added
|
|
59
|
+
together. A number means milliseconds, so `advanceBy(3_600_000)` advances by one hour. Durations
|
|
60
|
+
must be zero or greater. Use `setTo(...)` to move to an earlier time.
|
|
79
61
|
|
|
80
|
-
Advancing
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
that work is itself due by the new time, and stays queued where it falls later. So a test can
|
|
84
|
-
advance and then assert, with no additional waiting:
|
|
62
|
+
Advancing the clock also runs scheduled work due within the interval. Yulin runs each task at its
|
|
63
|
+
due time and waits for the simulation to settle before returning. The test can assert on the result
|
|
64
|
+
immediately:
|
|
85
65
|
|
|
86
66
|
```typescript sim-clock-session-expiry
|
|
87
67
|
/**
|
|
@@ -138,31 +118,16 @@ try {
|
|
|
138
118
|
}
|
|
139
119
|
```
|
|
140
120
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
Delivery to a target is the exception, and deliberately so. An EventBridge rule or a Scheduler
|
|
145
|
-
schedule that cannot reach its target records the failure instead of throwing. Real AWS reports a
|
|
146
|
-
failed delivery to nobody, and one rejected delivery would otherwise fail an unrelated
|
|
147
|
-
`advanceBy(...)` elsewhere in the same test. Read the failures from `eventBridge().deliveryFailures`
|
|
148
|
-
and `scheduler().deliveryFailures`.
|
|
121
|
+
If scheduled work throws, `advanceBy(...)` throws the same failure. The clock stops at the failed
|
|
122
|
+
task's due time, and later work remains queued.
|
|
149
123
|
|
|
150
|
-
|
|
151
|
-
|
|
124
|
+
EventBridge and EventBridge Scheduler delivery failures are recorded instead. Read them from
|
|
125
|
+
`eventBridge().deliveryFailures` or `scheduler().deliveryFailures`. Step Functions also records a
|
|
126
|
+
failed state on the execution for `DescribeExecution` to return.
|
|
152
127
|
|
|
153
|
-
|
|
154
|
-
timestamps and expiry checks see. A scheduled EventBridge rule fires, an EventBridge Scheduler
|
|
155
|
-
schedule invokes its target, a DynamoDB item passes its time to live, a Secrets Manager deletion
|
|
156
|
-
falls due, a Step Functions execution moves on from a `Wait` state, and a Lambda event source
|
|
157
|
-
mapping polls again. Each of those runs at its own due instant inside the interval, in the order
|
|
158
|
-
they fall due.
|
|
128
|
+
## Read simulated time in a Lambda handler
|
|
159
129
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
A simulated Lambda function runs on its simulation's clock, and that reaches the JavaScript clock
|
|
163
|
-
the function code itself reads. `Date.now()` and `new Date()` inside a handler report simulated
|
|
164
|
-
time. Code stamping an expiry or building a date-partitioned key can be tested against a clock the
|
|
165
|
-
test controls:
|
|
130
|
+
Inside a simulated Lambda invocation, `Date.now()` and `new Date()` read the simulation's clock:
|
|
166
131
|
|
|
167
132
|
```typescript sim-clock-lambda-handler
|
|
168
133
|
/**
|
|
@@ -203,30 +168,22 @@ const second = await lambda.invoke(
|
|
|
203
168
|
console.log(Buffer.from(second.Payload!).toString()); // {"at":"2026-07-26T11:00:00.000Z"}
|
|
204
169
|
```
|
|
205
170
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
- **Zip code** runs in a vm sandbox owning its own globals, and is handed a `Date` bound to the
|
|
210
|
-
simulation's clock. The globals outside the sandbox are left alone.
|
|
211
|
-
- **A real in-process handler function** is a closure over the module scope it was written in, and
|
|
212
|
-
reads the global `Date` like everything else in the test run. So the global is substituted for one
|
|
213
|
-
reporting the invocation's clock while an invocation is running, and the host clock otherwise,
|
|
214
|
-
tracked with `AsyncLocalStorage` so concurrent invocations of different simulations stay apart. It
|
|
215
|
-
is installed on the first in-process invocation and never removed, and with no invocation running
|
|
216
|
-
it behaves exactly as the host's own `Date` does.
|
|
171
|
+
Zip code runs in a VM with a `Date` constructor connected to the simulation. An in-process handler
|
|
172
|
+
uses the same simulated time during its invocation. Code outside the invocation continues to read
|
|
173
|
+
the system clock, including code running concurrently in another simulation.
|
|
217
174
|
|
|
218
|
-
Only the current time
|
|
219
|
-
`Date.UTC(...)
|
|
175
|
+
Only calls that ask for the current time are changed. `new Date("2020-03-12")`, `Date.parse(...)`,
|
|
176
|
+
`Date.UTC(...)`, and `instanceof Date` keep their usual behaviour.
|
|
220
177
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
178
|
+
The global `setTimeout`, `clearTimeout`, `setInterval`, and `clearInterval` functions also use the
|
|
179
|
+
simulation's clock during an invocation. Start an invocation without awaiting it, advance the
|
|
180
|
+
clock past the timer delay, then await the invocation. Lambda's configured timeout and
|
|
181
|
+
`context.getRemainingTimeInMillis()` use the same clock.
|
|
224
182
|
|
|
225
183
|
### Where real AWS gets the time
|
|
226
184
|
|
|
227
|
-
Real Lambda has no current-time API.
|
|
228
|
-
|
|
229
|
-
Date()` is reading the machine clock. AWS does provide the time on the event:
|
|
185
|
+
Real Lambda has no current-time API. A production handler gets the current time from the machine
|
|
186
|
+
clock or from a timestamp in its event:
|
|
230
187
|
|
|
231
188
|
| Event source | Field |
|
|
232
189
|
| ------------------------- | ------------------------------------------------- |
|
|
@@ -236,49 +193,52 @@ Date()` is reading the machine clock. AWS does provide the time on the event:
|
|
|
236
193
|
| SNS | `Records[].Sns.Timestamp` |
|
|
237
194
|
| SQS | `Records[].attributes.SentTimestamp` |
|
|
238
195
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
An SQS event source mapping does the same. The `SentTimestamp` and
|
|
245
|
-
`ApproximateFirstReceiveTimestamp` attributes on a delivered record are simulated time, and a
|
|
246
|
-
handler reading the event's time reads the clock the test controls. See
|
|
247
|
-
[simulated Lambda](https://yulinsim.dev/services/lambda/#triggering-a-function-from-an-sqs-queue "Simulated Lambda event source mapping docs").
|
|
196
|
+
Yulin puts simulated time into the events it builds. Function URL events include
|
|
197
|
+
`requestContext.time` and `requestContext.timeEpoch`. SQS records include simulated
|
|
198
|
+
`SentTimestamp` and `ApproximateFirstReceiveTimestamp` values. The
|
|
199
|
+
[Lambda documentation](https://yulinsim.dev/services/lambda/#triggering-a-function-from-an-sqs-queue "Simulated Lambda event source mapping docs")
|
|
200
|
+
describes the event source mapping behaviour.
|
|
248
201
|
|
|
249
|
-
|
|
250
|
-
|
|
202
|
+
A handler can also accept a clock as a dependency. That approach works without Lambda-specific
|
|
203
|
+
clock handling.
|
|
251
204
|
|
|
252
205
|
## Time over HTTP
|
|
253
206
|
|
|
254
|
-
A simulation served
|
|
255
|
-
response
|
|
256
|
-
time. Advancing the clock changes what that header reports. A client talking to the simulation sees
|
|
257
|
-
the same "now" the simulation does, with no need to know it is talking to a simulator.
|
|
207
|
+
A simulation served through `serveSimAws` or `SimAwsHttp.fetch(...)` uses simulated time in each
|
|
208
|
+
response's `Date` header. Advancing the clock changes the header on later responses.
|
|
258
209
|
|
|
259
210
|
## Time and SDK interception
|
|
260
211
|
|
|
261
|
-
A `SimSdk`
|
|
262
|
-
|
|
212
|
+
A `SimSdk` exposes its simulation as `simSdk.simAws`. Advance its clock with
|
|
213
|
+
`await simSdk.simAws.clock().advanceBy({ hours: 1 })`.
|
|
214
|
+
|
|
215
|
+
## Uses of simulated time
|
|
216
|
+
|
|
217
|
+
Yulin uses the clock for:
|
|
218
|
+
|
|
219
|
+
- Resource timestamps and expiry checks
|
|
220
|
+
- EventBridge rules and EventBridge Scheduler schedules
|
|
221
|
+
- DynamoDB time to live and scheduled Secrets Manager deletion
|
|
222
|
+
- Step Functions `Wait` states
|
|
223
|
+
- Lambda event source polling and event timestamps
|
|
224
|
+
- `Date`, global timers, and invocation deadlines inside a simulated Lambda invocation
|
|
225
|
+
- HTTP response `Date` headers
|
|
263
226
|
|
|
264
227
|
## Limitations
|
|
265
228
|
|
|
266
|
-
-
|
|
267
|
-
[EventBridge
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
-
|
|
273
|
-
|
|
274
|
-
-
|
|
275
|
-
|
|
276
|
-
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
module scope read it when the test file imported the module, long before any invocation.
|
|
283
|
-
- Advancing time does not re-evaluate simulated state that was already computed, such as an ACM
|
|
284
|
-
certificate that has finished validating. It changes what is read from the clock next.
|
|
229
|
+
- Scheduled [EventBridge rules](https://yulinsim.dev/services/eventbridge/#rules-that-fire-on-a-schedule)
|
|
230
|
+
and [EventBridge Scheduler schedules](https://yulinsim.dev/services/scheduler/#firing-a-schedule)
|
|
231
|
+
run when `advanceBy(...)` or a forward `setTo(...)` reaches their due time. Elapsed system time
|
|
232
|
+
does not run them.
|
|
233
|
+
- Time control is available through `SimAws`. A standalone service such as `new SimS3()` uses the
|
|
234
|
+
system clock and has no clock controls.
|
|
235
|
+
- A `SimAws` created with a custom `background` scheduler cannot control time because the scheduler
|
|
236
|
+
owns its clock. Calling `simAws.clock()` throws `SimAwsTimeNotControllable`.
|
|
237
|
+
- JavaScript's `Date` and global timer functions use simulated time only during a simulated Lambda
|
|
238
|
+
invocation. Other application code continues to use system time.
|
|
239
|
+
- Lambda code imported from `node:timers` or `node:timers/promises` uses system time. The same is
|
|
240
|
+
true of `util.promisify(setTimeout)`.
|
|
241
|
+
- A module-level `Date.now()` runs when the module is imported, before the Lambda invocation begins.
|
|
242
|
+
It reads system time.
|
|
243
|
+
- Moving the clock does not recalculate state that has already been computed. For example, it does
|
|
244
|
+
not restart validation for an ACM certificate that is already issued.
|
package/llms.txt
CHANGED
|
@@ -47,7 +47,7 @@ The same pages are on the web at https://yulinsim.dev/ for whichever release is
|
|
|
47
47
|
- [STS](docs/services/sts/README.md): Simulated STS usage docs
|
|
48
48
|
- [WAFv2](docs/services/wafv2/README.md): Simulated WAFv2 usage docs
|
|
49
49
|
|
|
50
|
-
## Feature
|
|
50
|
+
## Feature guides
|
|
51
51
|
|
|
52
52
|
- [AI skill](docs/ai-skill/README.md): Yulin AI skill usage docs
|
|
53
53
|
- [The AWS CLI](docs/cli/README.md): The AWS CLI against simulated AWS usage docs
|
package/package.json
CHANGED