@kensio/yulin 1.21.31 → 1.21.33

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 (78) hide show
  1. package/dist/serve/message/sim-message-log-console.js +3 -3
  2. package/dist/service/apigateway/api/deployment/sim-rest-api-deployment.js +3 -3
  3. package/dist/service/apigateway/api/method/sim-rest-api-method.js +12 -12
  4. package/dist/service/apigateway/api/resource/sim-rest-api-resource.js +11 -9
  5. package/dist/service/apigateway/api/sim-rest-api-view.js +3 -3
  6. package/dist/service/apigateway/api/stage/sim-rest-api-stage.js +8 -10
  7. package/dist/service/apigatewayv2/api/integration/sim-http-api-integration.js +3 -3
  8. package/dist/service/apigatewayv2/api/route/sim-http-api-route-view.js +6 -6
  9. package/dist/service/apigatewayv2/api/sim-http-api-view.js +3 -3
  10. package/dist/service/apigatewayv2/api/stage/settings/sim-http-api-stage-route-settings.js +8 -7
  11. package/dist/service/apigatewayv2/api/stage/sim-http-api-stage.js +9 -9
  12. package/dist/service/athena/engine/sim-athena-partitioned-objects.js +7 -7
  13. package/dist/service/athena/sim-athena-engine.fixture.js +3 -0
  14. package/dist/service/athena/table/sim-athena-partition-filters.js +6 -5
  15. package/dist/service/backup/command/sim-backup-authorizer.js +5 -4
  16. package/dist/service/bedrock/response/sim-bedrock-declared-content.js +5 -10
  17. package/dist/service/cloudformation/stack/update/sim-cfn-stack-resource-changes.js +19 -10
  18. package/dist/service/cloudfront/cfn/response-headers-policy/sim-cfn-cf-rh-policy-security-values.js +2 -6
  19. package/dist/service/cognito/user-pool/trigger/sim-cognito-pre-sign-up-response.js +4 -7
  20. package/dist/service/dynamodb/command/transact/sim-dynamodb-transact-write.js +34 -25
  21. package/dist/service/dynamodb/secondary-index/sim-dynamodb-index-limits.js +5 -4
  22. package/dist/service/dynamodb/stream/sim-dynamodb-stream-shard-iterator.js +1 -3
  23. package/dist/service/dynamodb/time-to-live/sim-dynamodb-time-to-live.js +4 -3
  24. package/dist/service/glue/expression/sim-glue-partition-comparisons.js +1 -1
  25. package/dist/service/iam/authorize/context/sim-iam-auth-z-allow-requirement.js +6 -6
  26. package/dist/service/iam/authorize/match/condition/null/sim-iam-null.js +4 -1
  27. package/dist/service/kinesis/stream/sim-kinesis-shard-iterator.js +1 -3
  28. package/dist/service/lambda/command/create-function/create-function.handler.js +1 -0
  29. package/dist/service/lambda/destination/sim-lambda-destination-record.js +7 -7
  30. package/dist/service/lambda/function/environment/sim-lambda-environment-conflict.d.ts +22 -0
  31. package/dist/service/lambda/function/environment/sim-lambda-environment-conflict.js +33 -0
  32. package/dist/service/lambda/function/environment/sim-lambda-environment-conflicts.d.ts +53 -11
  33. package/dist/service/lambda/function/environment/sim-lambda-environment-conflicts.js +78 -24
  34. package/dist/service/lambda/function/policy/sim-lambda-permission.js +15 -14
  35. package/dist/service/lambda/function/sim-lambda-function.js +1 -0
  36. package/dist/service/lambda/function/sim-lambda-function.type.d.ts +8 -0
  37. package/dist/service/lambda/metric/sim-lambda-function-metrics.js +11 -9
  38. package/dist/service/lambda/sim-lambda-commands.js +3 -1
  39. package/dist/service/logs/metric/sim-logs-metric-filter.js +1 -8
  40. package/dist/service/route53/dns/answer/sim-route53-dns-zone-finder.js +5 -4
  41. package/dist/service/route53/resolve/sim-r53-zone-record-finder.js +8 -6
  42. package/dist/service/s3/bucket/notification/sim-s3-notification-filter.js +4 -7
  43. package/dist/service/s3/bucket/sim-s3-bucket.d.ts +8 -0
  44. package/dist/service/s3/bucket/sim-s3-bucket.js +11 -0
  45. package/dist/service/s3/bucket/sim-s3-key-writes.d.ts +16 -0
  46. package/dist/service/s3/bucket/sim-s3-key-writes.js +43 -0
  47. package/dist/service/s3/bucket/versioning/sim-s3-bucket-versioning.js +1 -3
  48. package/dist/service/s3/command/complete-multipart-upload/complete-multipart-upload.command.d.ts +2 -1
  49. package/dist/service/s3/command/complete-multipart-upload/complete-multipart-upload.handler.js +5 -1
  50. package/dist/service/s3/command/copy-object/copy-object-precondition.d.ts +23 -0
  51. package/dist/service/s3/command/copy-object/copy-object-precondition.js +34 -0
  52. package/dist/service/s3/command/copy-object/copy-object.command.d.ts +3 -1
  53. package/dist/service/s3/command/copy-object/copy-object.handler.d.ts +4 -0
  54. package/dist/service/s3/command/copy-object/copy-object.handler.js +11 -1
  55. package/dist/service/s3/command/object/sim-s3-write-precondition.d.ts +34 -0
  56. package/dist/service/s3/command/object/sim-s3-write-precondition.js +47 -0
  57. package/dist/service/s3/command/put-object/put-object.command.d.ts +2 -1
  58. package/dist/service/s3/command/put-object/put-object.handler.js +5 -1
  59. package/dist/service/s3/error/sim-s3.error.d.ts +10 -0
  60. package/dist/service/s3/error/sim-s3.error.js +12 -0
  61. package/dist/service/s3/object/s3-object-listing.js +4 -3
  62. package/dist/service/s3/serve/api/sim-s3-api-input.d.ts +4 -0
  63. package/dist/service/s3/serve/api/sim-s3-api-input.js +10 -0
  64. package/dist/service/s3/serve/api/sim-s3-api-multipart-input.js +2 -0
  65. package/dist/service/s3/serve/api/sim-s3-api-object-input.d.ts +6 -0
  66. package/dist/service/s3/serve/api/sim-s3-api-object-input.js +34 -2
  67. package/dist/service/s3/storage/filesystem/s3-filesystem-object-keys.js +9 -8
  68. package/dist/service/secretsmanager/cfn/secret/sim-cfn-secrets-manager-secret-template.test-support.js +15 -23
  69. package/dist/service/sqs/message/sim-sqs-message.js +3 -3
  70. package/dist/service/stepfunctions/machine/sim-state-machine.js +4 -3
  71. package/dist/util/process/sim-process-environment-reads.d.ts +52 -0
  72. package/dist/util/process/sim-process-environment-reads.js +94 -0
  73. package/dist/util/process/sim-process-environment.d.ts +32 -9
  74. package/dist/util/process/sim-process-environment.js +43 -17
  75. package/dist/util/schedule/cron/sim-cron-field-bounds.js +1 -1
  76. package/docs/services/lambda/README.md +6 -0
  77. package/docs/services/s3/README.md +84 -3
  78. package/package.json +3 -3
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Records the names code reads from the host process.env.
3
+ *
4
+ * SimLambdaEnvironmentConflicts warns that a module-scope read sees the host
5
+ * value of a variable instead of the function's own. Whether that matters
6
+ * depends on a read having happened at all, which configuration cannot tell.
7
+ * This keeps the evidence: the host environment is handed out behind a Proxy
8
+ * that notes each name read through it.
9
+ *
10
+ * Enumerating the whole environment is not counted as reading every name in
11
+ * it. Node.js copies process.env key by key when it spawns a child process,
12
+ * and so does any tool that snapshots it, and none of that is handler code
13
+ * capturing a value it later depends on. An enumeration is recognised by its
14
+ * shape: the property reads that follow a listing of the keys, in the order
15
+ * the listing gave them. Its reads are recorded as they happen and taken off
16
+ * the record again once every key has been read, so a listing that is not
17
+ * followed by a complete copy hides nothing. A module copying the environment
18
+ * with a spread at module scope is missed as a result.
19
+ */
20
+ export class SimProcessEnvironmentReads {
21
+ names = new Set();
22
+ /**
23
+ * The environment objects each watching Proxy stands in front of, so that
24
+ * assigning one back to process.env does not stack a Proxy on a Proxy.
25
+ */
26
+ targets = new WeakMap();
27
+ /**
28
+ * The keys of an enumeration in progress, and how far its reads have got.
29
+ */
30
+ enumeration;
31
+ /**
32
+ * Whether code has read the name through a watched environment.
33
+ */
34
+ wasRead(name) {
35
+ return this.names.has(name);
36
+ }
37
+ /**
38
+ * A view of the environment that records the names read through it.
39
+ *
40
+ * Writes and deletes go straight to the environment, so a value assigned
41
+ * through the view is coerced to a string as process.env would coerce it.
42
+ */
43
+ watch(environment) {
44
+ const target = this.unwrap(environment);
45
+ const view = new Proxy(target, {
46
+ get: (watched, key) => {
47
+ if (typeof key === "string") {
48
+ this.recordRead(key);
49
+ }
50
+ return Reflect.get(watched, key);
51
+ },
52
+ set: (watched, key, value) => Reflect.set(watched, key, value),
53
+ ownKeys: (watched) => {
54
+ const keys = Reflect.ownKeys(watched);
55
+ this.enumeration = { keys, next: 0, added: [] };
56
+ return keys;
57
+ },
58
+ });
59
+ this.targets.set(view, target);
60
+ return view;
61
+ }
62
+ /**
63
+ * The environment behind a watching view, or the environment itself when it
64
+ * is not one.
65
+ */
66
+ unwrap(environment) {
67
+ return this.targets.get(environment) ?? environment;
68
+ }
69
+ /**
70
+ * Note a read, and take an enumeration's reads off the record once it has
71
+ * read every key.
72
+ */
73
+ recordRead(name) {
74
+ const enumeration = this.enumeration;
75
+ if (enumeration === undefined ||
76
+ enumeration.keys[enumeration.next] !== name) {
77
+ this.enumeration = undefined;
78
+ this.names.add(name);
79
+ return;
80
+ }
81
+ enumeration.next += 1;
82
+ if (!this.names.has(name)) {
83
+ this.names.add(name);
84
+ enumeration.added.push(name);
85
+ }
86
+ if (enumeration.next < enumeration.keys.length) {
87
+ return;
88
+ }
89
+ for (const added of enumeration.added) {
90
+ this.names.delete(added);
91
+ }
92
+ this.enumeration = undefined;
93
+ }
94
+ }
@@ -20,19 +20,33 @@
20
20
  *
21
21
  * The one thing this cannot reach is a read that already happened. A handler
22
22
  * module doing `const TABLE = process.env.TABLE_NAME` at module scope is
23
- * evaluated when the test file imports it, long before any run, so it captures
23
+ * evaluated when the test file imports it, long before any run, and captures
24
24
  * the host value. Reads inside the handler body see the run's own variables.
25
- * See SimLambdaEnvironmentConflicts, which warns when that distinction
26
- * actually changes what the code sees.
25
+ *
26
+ * Outside a run, process.env is the host environment behind a
27
+ * SimProcessEnvironmentReads view, which records the names read. The patch is
28
+ * installed when this module loads, which is when Yulin is imported, so a
29
+ * module-scope read in a handler imported after Yulin is on record.
30
+ * SimLambdaEnvironmentConflicts warns from that record, and only for a name
31
+ * whose early read changed what the code saw. A read made before Yulin was
32
+ * imported is invisible to it.
27
33
  */
28
34
  declare class SimProcessEnvironment {
29
35
  private readonly storage;
36
+ private readonly reads;
30
37
  private hostEnvironment;
31
- private installed;
38
+ private hostView;
39
+ constructor();
32
40
  /**
33
41
  * Run something with the given variables as its process.env.
34
42
  */
35
43
  run<T>(variables: Record<string, string>, run: () => Promise<T>): Promise<T>;
44
+ /**
45
+ * Whether code read the name from process.env while no run was active.
46
+ *
47
+ * Reads made before this module loaded are not on record.
48
+ */
49
+ wasReadOutsideRun(name: string): boolean;
36
50
  /**
37
51
  * The host process environment, ignoring any run in progress.
38
52
  */
@@ -51,14 +65,23 @@ declare class SimProcessEnvironment {
51
65
  *
52
66
  * process.env is a plain configurable data property on process, so it can
53
67
  * be replaced with a getter. Outside a simulated run the getter hands back
54
- * the untouched host environment object, so the patch is inert: anything
55
- * that reads, writes, or stubs process.env normally is unaffected.
68
+ * the host environment behind a view that records the names read, and
69
+ * passes every read, write and delete through to it. Anything that reads,
70
+ * writes, or stubs process.env normally is unaffected.
56
71
  *
57
- * Installed once and never removed. Removing it would be unsafe while
58
- * another run is in flight, and there is nothing to gain: an installed patch
59
- * with no run in progress behaves exactly like no patch at all.
72
+ * Installed once, at construction, and never removed. Removing it would be
73
+ * unsafe while another run is in flight, and there is nothing to gain. With
74
+ * no run in progress, the patch passes everything through to the host
75
+ * environment.
60
76
  */
61
77
  private install;
78
+ /**
79
+ * Make the environment the host environment, and watch reads of it.
80
+ *
81
+ * Code saving process.env and assigning it back hands over the watching
82
+ * view, which is unwrapped so that views do not nest.
83
+ */
84
+ private useHostEnvironment;
62
85
  /**
63
86
  * Apply an assignment to process.env as a whole.
64
87
  *
@@ -1,4 +1,5 @@
1
1
  import { AsyncLocalStorage } from "node:async_hooks";
2
+ import { SimProcessEnvironmentReads } from "./sim-process-environment-reads.js";
2
3
  /**
3
4
  * The process.env in-process handler code sees while a simulated run lasts.
4
5
  *
@@ -21,22 +22,39 @@ import { AsyncLocalStorage } from "node:async_hooks";
21
22
  *
22
23
  * The one thing this cannot reach is a read that already happened. A handler
23
24
  * module doing `const TABLE = process.env.TABLE_NAME` at module scope is
24
- * evaluated when the test file imports it, long before any run, so it captures
25
+ * evaluated when the test file imports it, long before any run, and captures
25
26
  * the host value. Reads inside the handler body see the run's own variables.
26
- * See SimLambdaEnvironmentConflicts, which warns when that distinction
27
- * actually changes what the code sees.
27
+ *
28
+ * Outside a run, process.env is the host environment behind a
29
+ * SimProcessEnvironmentReads view, which records the names read. The patch is
30
+ * installed when this module loads, which is when Yulin is imported, so a
31
+ * module-scope read in a handler imported after Yulin is on record.
32
+ * SimLambdaEnvironmentConflicts warns from that record, and only for a name
33
+ * whose early read changed what the code saw. A read made before Yulin was
34
+ * imported is invisible to it.
28
35
  */
29
36
  class SimProcessEnvironment {
30
37
  storage = new AsyncLocalStorage();
38
+ reads = new SimProcessEnvironmentReads();
31
39
  hostEnvironment = process.env;
32
- installed = false;
40
+ hostView = process.env;
41
+ constructor() {
42
+ this.install();
43
+ }
33
44
  /**
34
45
  * Run something with the given variables as its process.env.
35
46
  */
36
47
  async run(variables, run) {
37
- this.install();
38
48
  return await this.storage.run(variables, run);
39
49
  }
50
+ /**
51
+ * Whether code read the name from process.env while no run was active.
52
+ *
53
+ * Reads made before this module loaded are not on record.
54
+ */
55
+ wasReadOutsideRun(name) {
56
+ return this.reads.wasRead(name);
57
+ }
40
58
  /**
41
59
  * The host process environment, ignoring any run in progress.
42
60
  */
@@ -65,27 +83,35 @@ class SimProcessEnvironment {
65
83
  *
66
84
  * process.env is a plain configurable data property on process, so it can
67
85
  * be replaced with a getter. Outside a simulated run the getter hands back
68
- * the untouched host environment object, so the patch is inert: anything
69
- * that reads, writes, or stubs process.env normally is unaffected.
86
+ * the host environment behind a view that records the names read, and
87
+ * passes every read, write and delete through to it. Anything that reads,
88
+ * writes, or stubs process.env normally is unaffected.
70
89
  *
71
- * Installed once and never removed. Removing it would be unsafe while
72
- * another run is in flight, and there is nothing to gain: an installed patch
73
- * with no run in progress behaves exactly like no patch at all.
90
+ * Installed once, at construction, and never removed. Removing it would be
91
+ * unsafe while another run is in flight, and there is nothing to gain. With
92
+ * no run in progress, the patch passes everything through to the host
93
+ * environment.
74
94
  */
75
95
  install() {
76
- if (this.installed) {
77
- return;
78
- }
79
- this.hostEnvironment = process.env;
96
+ this.useHostEnvironment(process.env);
80
97
  Object.defineProperty(process, "env", {
81
98
  configurable: true,
82
99
  enumerable: true,
83
- get: () => this.storage.getStore() ?? this.hostEnvironment,
100
+ get: () => this.storage.getStore() ?? this.hostView,
84
101
  set: (replacement) => {
85
102
  this.replaceVariables(replacement);
86
103
  },
87
104
  });
88
- this.installed = true;
105
+ }
106
+ /**
107
+ * Make the environment the host environment, and watch reads of it.
108
+ *
109
+ * Code saving process.env and assigning it back hands over the watching
110
+ * view, which is unwrapped so that views do not nest.
111
+ */
112
+ useHostEnvironment(environment) {
113
+ this.hostEnvironment = this.reads.unwrap(environment);
114
+ this.hostView = this.reads.watch(this.hostEnvironment);
89
115
  }
90
116
  /**
91
117
  * Apply an assignment to process.env as a whole.
@@ -104,7 +130,7 @@ class SimProcessEnvironment {
104
130
  replaceVariables(replacement) {
105
131
  const store = this.storage.getStore();
106
132
  if (store === undefined) {
107
- this.hostEnvironment = replacement;
133
+ this.useHostEnvironment(replacement);
108
134
  return;
109
135
  }
110
136
  const replacing = Object.entries(replacement);
@@ -58,5 +58,5 @@ export function boundsOf(spec, written, stepped) {
58
58
  ];
59
59
  }
60
60
  const only = valueOf(spec, written);
61
- return stepped ? [only, spec.maximum] : [only, only];
61
+ return [only, stepped ? spec.maximum : only];
62
62
  }
@@ -3355,6 +3355,12 @@ console in the two situations where the difference changes what your code sees:
3355
3355
  - a declared variable whose name the host process also sets, with a different value
3356
3356
  - two simulated functions declaring the same variable name with different values
3357
3357
 
3358
+ Either one is reported only once code has read that name from `process.env` with no invocation
3359
+ running. Yulin records those reads from the moment it is imported. A read made earlier is invisible
3360
+ to it (a handler module imported ahead of Yulin, or a setup file that loads first), and so is a copy
3361
+ of the whole environment such as `{ ...process.env }`. Neither produces a warning. A handler that
3362
+ reads its variables inside the handler function produces none either.
3363
+
3358
3364
  ## The time inside a handler
3359
3365
 
3360
3366
  A function runs on its simulation's clock, and so does the function code. `Date.now()` and
@@ -531,6 +531,74 @@ reports it there.
531
531
  An Object uploaded in parts gets a different form. See
532
532
  [Uploading an Object in parts](#uploading-an-object-in-parts).
533
533
 
534
+ ## Conditional writes
535
+
536
+ `PutObject`, `CopyObject` and `CompleteMultipartUpload` take `IfNoneMatch` and `IfMatch`, which
537
+ state what the key has to hold before the write goes ahead. `IfNoneMatch: "*"` writes only to a key
538
+ that holds nothing. `IfMatch` writes only over an Object with that ETag. A write whose condition
539
+ fails is refused with `PreconditionFailed` (status `412`), and the Object already under the key is
540
+ left as it was.
541
+
542
+ ```typescript sim-s3-conditional-write
543
+ /**
544
+ * Writing a simulated S3 Object only where the key is free.
545
+ */
546
+
547
+ import {
548
+ CopyObjectCommand,
549
+ CreateBucketCommand,
550
+ PutObjectCommand,
551
+ } from "@aws-sdk/client-s3";
552
+ import { SimAws } from "@kensio/yulin";
553
+
554
+ const simAws = new SimAws();
555
+ const simS3 = simAws.s3();
556
+
557
+ await simS3.createBucket(new CreateBucketCommand({ Bucket: "audio-bucket" }));
558
+
559
+ await simS3.putObject(
560
+ new PutObjectCommand({
561
+ Bucket: "audio-bucket",
562
+ Key: "uploads/take-1.mp3",
563
+ Body: "first take",
564
+ }),
565
+ );
566
+
567
+ for (let attempt = 0; attempt < 2; attempt++) {
568
+ try {
569
+ await simS3.copyObject(
570
+ new CopyObjectCommand({
571
+ Bucket: "audio-bucket",
572
+ Key: "shared/take.mp3",
573
+ CopySource: "audio-bucket/uploads/take-1.mp3",
574
+ IfNoneMatch: "*",
575
+ }),
576
+ );
577
+ console.log("copied");
578
+ } catch (error) {
579
+ // The second attempt finds the shared key taken.
580
+ if (error instanceof Error && error.name === "PreconditionFailed") {
581
+ console.log("already there");
582
+ } else {
583
+ throw error;
584
+ }
585
+ }
586
+ }
587
+ ```
588
+
589
+ Writes to one key run one at a time. Of several conditional writes racing for an empty key, the first
590
+ to finish succeeds and the rest are refused. `IfMatch` on a key holding nothing answers `NoSuchKey`. On a versioned Bucket both conditions look at
591
+ the current version, and a delete marker counts as nothing. `IfNoneMatch` on a write accepts only
592
+ `*`, and real S3 refuses anything else with `NotImplemented`.
593
+
594
+ A copy also takes conditions on its source. `CopySourceIfMatch`, `CopySourceIfNoneMatch`,
595
+ `CopySourceIfModifiedSince` and `CopySourceIfUnmodifiedSince` refuse the copy with
596
+ `PreconditionFailed` when the source does not meet them. An ETag condition outranks the date
597
+ condition paired with it, as RFC 7232 has it. The served endpoint reads all of these from the same
598
+ headers real S3 does.
599
+
600
+ A failed completion leaves the upload in place, and it can be completed again.
601
+
534
602
  ## Uploading an Object in parts
535
603
 
536
604
  Yulin supports multipart upload through the SDK and served S3 endpoint. This covers the operations
@@ -834,9 +902,6 @@ See [Serve simulated S3 on localhost](#serve-simulated-s3-on-localhost) for sett
834
902
  - Both Buckets have to belong to the same simulated S3. A copy across Accounts or Regions is left
835
903
  out.
836
904
  - A presigned copy is left out, and so is a copy reaching a Bucket through simulated CloudFront.
837
- - `CopySourceIfMatch`, `CopySourceIfNoneMatch`, `CopySourceIfModifiedSince` and
838
- `CopySourceIfUnmodifiedSince` are ignored. A conditional copy happens whatever the condition
839
- says.
840
905
  - `ACL` is ignored. Sim S3 models no Object ACL.
841
906
  - A `versionId` in `CopySource` is refused with `NotImplemented`.
842
907
  - A copy of an Object that was uploaded in parts gets a plain ETag rather than the multipart form.
@@ -3252,6 +3317,22 @@ The `getBucketWebsiteUrl(...)` method returns the simulated S3 website URL for t
3252
3317
  `localUrl(...)` method on the localhost server adapts that URL so the request is sent to the local
3253
3318
  server while preserving the simulated S3 website hostname.
3254
3319
 
3320
+ ### AWS CLI uploads
3321
+
3322
+ Set `preferred_transfer_client` to `classic` in the AWS config file used for the simulated
3323
+ endpoint:
3324
+
3325
+ ```ini
3326
+ [default]
3327
+ s3 =
3328
+ preferred_transfer_client = classic
3329
+ ```
3330
+
3331
+ The CLI's [automatic transfer-client selection](https://docs.aws.amazon.com/cli/latest/topic/s3-config.html#preferred-transfer-client)
3332
+ can choose CRT. Its uploads use streaming payload trailers, which Yulin's signature verifier
3333
+ does not support. Those requests fail with `403`. The classic client supports the single-file
3334
+ and multipart uploads exercised by Yulin's CLI tests.
3335
+
3255
3336
  ## Presigned URLs
3256
3337
 
3257
3338
  Sim S3 serves a REST API endpoint alongside the website endpoint, and it accepts presigned URLs
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kensio/yulin",
3
- "version": "1.21.31",
3
+ "version": "1.21.33",
4
4
  "description": "AWS system behaviour simulation for isolated unit testing",
5
5
  "repository": "https://github.com/KensioSoftware/yulin",
6
6
  "homepage": "https://yulinsim.dev/",
@@ -293,13 +293,13 @@
293
293
  "eslint-plugin-jsdoc": "^64.0.1",
294
294
  "eslint-plugin-no-secrets": "^2.3.3",
295
295
  "eslint-plugin-security": "^4.0.1",
296
- "eslint-plugin-unicorn": "^74.0.0",
296
+ "eslint-plugin-unicorn": "^76.0.0",
297
297
  "execa": "^10.0.0",
298
298
  "fta-cli": "^3.0.0",
299
299
  "hyparquet": "^1.29.2",
300
300
  "hyparquet-writer": "^0.16.9",
301
301
  "node-sql-parser": "^5.4.0",
302
- "oxfmt": "^0.72.0",
302
+ "oxfmt": "^0.73.0",
303
303
  "oxlint": "^1.77.0",
304
304
  "oxlint-tsgolint": "^7.0.2001",
305
305
  "semantic-release": "25.0.9",