aws-sdk-vitest-mock 0.1.0 → 0.2.0
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 +324 -27
- package/index.cjs +1 -1
- package/index.js +297 -77
- package/lib/matchers.d.ts +4 -2
- package/lib/mock-client.d.ts +31 -1
- package/lib/utils/aws-errors.d.ts +17 -0
- package/lib/utils/colors.d.ts +10 -0
- package/lib/utils/debug-logger.d.ts +7 -0
- package/lib/utils/file-helpers.d.ts +1 -0
- package/lib/utils/paginator-helpers.d.ts +13 -0
- package/lib/utils/stream-helpers.d.ts +6 -0
- package/matchers-G36N2DNa.cjs +16 -0
- package/matchers-_zpN1oru.js +128 -0
- package/package.json +1 -1
- package/vitest-setup.cjs +1 -1
- package/vitest-setup.js +1 -1
- package/matchers-D1XEjFLq.cjs +0 -1
- package/matchers-DclpcT4f.js +0 -33
package/README.md
CHANGED
|
@@ -44,31 +44,53 @@ pnpm add -D aws-sdk-vitest-mock
|
|
|
44
44
|
### Basic Usage
|
|
45
45
|
|
|
46
46
|
```typescript
|
|
47
|
+
import { describe, test, expect, beforeEach, afterEach } from "vitest";
|
|
47
48
|
import { mockClient } from "aws-sdk-vitest-mock";
|
|
48
49
|
import { S3Client, GetObjectCommand } from "@aws-sdk/client-s3";
|
|
49
50
|
|
|
50
|
-
//
|
|
51
|
-
|
|
51
|
+
// Your application code
|
|
52
|
+
class DocumentService {
|
|
53
|
+
constructor(private s3Client: S3Client) {}
|
|
54
|
+
|
|
55
|
+
async getDocument(bucket: string, key: string) {
|
|
56
|
+
const result = await this.s3Client.send(
|
|
57
|
+
new GetObjectCommand({ Bucket: bucket, Key: key }),
|
|
58
|
+
);
|
|
59
|
+
return result.Body;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
describe("DocumentService", () => {
|
|
64
|
+
let s3Mock: ReturnType<typeof mockClient>;
|
|
65
|
+
let documentService: DocumentService;
|
|
66
|
+
|
|
67
|
+
beforeEach(() => {
|
|
68
|
+
// Mock the S3 client
|
|
69
|
+
s3Mock = mockClient(S3Client);
|
|
70
|
+
|
|
71
|
+
// Create service with real S3Client (which is now mocked)
|
|
72
|
+
const s3Client = new S3Client({ region: "us-east-1" });
|
|
73
|
+
documentService = new DocumentService(s3Client);
|
|
74
|
+
});
|
|
52
75
|
|
|
53
|
-
|
|
54
|
-
s3Mock.
|
|
55
|
-
|
|
56
|
-
ContentType: "text/plain",
|
|
57
|
-
});
|
|
76
|
+
afterEach(() => {
|
|
77
|
+
s3Mock.restore();
|
|
78
|
+
});
|
|
58
79
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
}),
|
|
66
|
-
);
|
|
80
|
+
test("should retrieve document from S3", async () => {
|
|
81
|
+
// Configure mock response
|
|
82
|
+
s3Mock.on(GetObjectCommand).resolves({
|
|
83
|
+
Body: "document content",
|
|
84
|
+
ContentType: "text/plain",
|
|
85
|
+
});
|
|
67
86
|
|
|
68
|
-
|
|
87
|
+
// Test your application code
|
|
88
|
+
const result = await documentService.getDocument("my-bucket", "doc.txt");
|
|
69
89
|
|
|
70
|
-
|
|
71
|
-
s3Mock.
|
|
90
|
+
expect(result).toBe("document content");
|
|
91
|
+
expect(s3Mock).toHaveReceivedCommand(GetObjectCommand);
|
|
92
|
+
});
|
|
93
|
+
});
|
|
72
94
|
```
|
|
73
95
|
|
|
74
96
|
### Request Matching
|
|
@@ -99,6 +121,199 @@ s3Mock
|
|
|
99
121
|
// All other calls return 'subsequent calls'
|
|
100
122
|
```
|
|
101
123
|
|
|
124
|
+
### Fixture Loading
|
|
125
|
+
|
|
126
|
+
Load mock responses from files for easier test data management:
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
// Load JSON response from file
|
|
130
|
+
s3Mock.on(GetObjectCommand).resolvesFromFile("./fixtures/s3-response.json");
|
|
131
|
+
|
|
132
|
+
// Load text response from file
|
|
133
|
+
s3Mock.on(GetObjectCommand).resolvesFromFile("./fixtures/response.txt");
|
|
134
|
+
|
|
135
|
+
// JSON files are automatically parsed, text files returned as strings
|
|
136
|
+
// File paths are resolved relative to current working directory
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Paginator Support
|
|
140
|
+
|
|
141
|
+
Mock AWS SDK v3 pagination with automatic token handling:
|
|
142
|
+
|
|
143
|
+
```typescript
|
|
144
|
+
// Mock DynamoDB scan with pagination
|
|
145
|
+
const items = Array.from({ length: 25 }, (_, i) => ({
|
|
146
|
+
id: { S: `item-${i + 1}` },
|
|
147
|
+
}));
|
|
148
|
+
|
|
149
|
+
dynamoMock.on(ScanCommand).resolvesPaginated(items, {
|
|
150
|
+
pageSize: 10,
|
|
151
|
+
itemsKey: "Items",
|
|
152
|
+
tokenKey: "NextToken",
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
// First call returns items 1-10 with NextToken
|
|
156
|
+
// Second call with NextToken returns items 11-20
|
|
157
|
+
// Third call returns items 21-25 without NextToken
|
|
158
|
+
|
|
159
|
+
// Mock S3 list objects with pagination
|
|
160
|
+
const objects = Array.from({ length: 15 }, (_, i) => ({
|
|
161
|
+
Key: `file-${i + 1}.txt`,
|
|
162
|
+
}));
|
|
163
|
+
|
|
164
|
+
s3Mock.on(ListObjectsV2Command).resolvesPaginated(objects, {
|
|
165
|
+
pageSize: 10,
|
|
166
|
+
itemsKey: "Contents",
|
|
167
|
+
tokenKey: "ContinuationToken",
|
|
168
|
+
});
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### DynamoDB with Marshal/Unmarshal
|
|
172
|
+
|
|
173
|
+
Mock DynamoDB operations using AWS SDK's marshal/unmarshal utilities for type-safe data handling:
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
import { describe, test, expect, beforeEach, afterEach } from "vitest";
|
|
177
|
+
import { mockClient } from "aws-sdk-vitest-mock";
|
|
178
|
+
import {
|
|
179
|
+
DynamoDBClient,
|
|
180
|
+
GetItemCommand,
|
|
181
|
+
PutItemCommand,
|
|
182
|
+
} from "@aws-sdk/client-dynamodb";
|
|
183
|
+
import { marshall, unmarshall } from "@aws-sdk/util-dynamodb";
|
|
184
|
+
|
|
185
|
+
// Your application service
|
|
186
|
+
class UserService {
|
|
187
|
+
constructor(private dynamoClient: DynamoDBClient) {}
|
|
188
|
+
|
|
189
|
+
async getUser(userId: string) {
|
|
190
|
+
const result = await this.dynamoClient.send(
|
|
191
|
+
new GetItemCommand({
|
|
192
|
+
TableName: "Users",
|
|
193
|
+
Key: marshall({ id: userId }),
|
|
194
|
+
}),
|
|
195
|
+
);
|
|
196
|
+
|
|
197
|
+
return result.Item ? unmarshall(result.Item) : null;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
async createUser(user: { id: string; name: string; email: string }) {
|
|
201
|
+
await this.dynamoClient.send(
|
|
202
|
+
new PutItemCommand({
|
|
203
|
+
TableName: "Users",
|
|
204
|
+
Item: marshall(user),
|
|
205
|
+
}),
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
describe("UserService with DynamoDB", () => {
|
|
211
|
+
let dynamoMock: ReturnType<typeof mockClient>;
|
|
212
|
+
let userService: UserService;
|
|
213
|
+
|
|
214
|
+
beforeEach(() => {
|
|
215
|
+
dynamoMock = mockClient(DynamoDBClient);
|
|
216
|
+
const dynamoClient = new DynamoDBClient({ region: "us-east-1" });
|
|
217
|
+
userService = new UserService(dynamoClient);
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
afterEach(() => {
|
|
221
|
+
dynamoMock.restore();
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
test("should get user by id", async () => {
|
|
225
|
+
const mockUser = { id: "123", name: "John Doe", email: "john@example.com" };
|
|
226
|
+
|
|
227
|
+
// Mock DynamoDB response with marshalled data
|
|
228
|
+
dynamoMock.on(GetItemCommand).resolves({
|
|
229
|
+
Item: marshall(mockUser),
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
const result = await userService.getUser("123");
|
|
233
|
+
|
|
234
|
+
expect(result).toEqual(mockUser);
|
|
235
|
+
expect(dynamoMock).toHaveReceivedCommandWith(GetItemCommand, {
|
|
236
|
+
TableName: "Users",
|
|
237
|
+
Key: marshall({ id: "123" }),
|
|
238
|
+
});
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
test("should create new user", async () => {
|
|
242
|
+
const newUser = {
|
|
243
|
+
id: "456",
|
|
244
|
+
name: "Jane Smith",
|
|
245
|
+
email: "jane@example.com",
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
dynamoMock.on(PutItemCommand).resolves({});
|
|
249
|
+
|
|
250
|
+
await userService.createUser(newUser);
|
|
251
|
+
|
|
252
|
+
expect(dynamoMock).toHaveReceivedCommandWith(PutItemCommand, {
|
|
253
|
+
TableName: "Users",
|
|
254
|
+
Item: marshall(newUser),
|
|
255
|
+
});
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
test("should return null for non-existent user", async () => {
|
|
259
|
+
dynamoMock.on(GetItemCommand).resolves({}); // No Item in response
|
|
260
|
+
|
|
261
|
+
const result = await userService.getUser("999");
|
|
262
|
+
|
|
263
|
+
expect(result).toBeNull();
|
|
264
|
+
});
|
|
265
|
+
});
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
### Stream Mocking (S3 Helper)
|
|
269
|
+
|
|
270
|
+
Mock S3 operations that return streams with automatic environment detection:
|
|
271
|
+
|
|
272
|
+
```typescript
|
|
273
|
+
// Mock with string content
|
|
274
|
+
s3Mock.on(GetObjectCommand).resolvesStream("Hello, World!");
|
|
275
|
+
|
|
276
|
+
// Mock with Buffer
|
|
277
|
+
s3Mock.on(GetObjectCommand).resolvesStream(Buffer.from("Binary data"));
|
|
278
|
+
|
|
279
|
+
// One-time stream response
|
|
280
|
+
s3Mock
|
|
281
|
+
.on(GetObjectCommand)
|
|
282
|
+
.resolvesStreamOnce("First call")
|
|
283
|
+
.resolvesStream("Subsequent calls");
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
### Delay/Latency Simulation
|
|
287
|
+
|
|
288
|
+
Simulate network delays for testing timeouts and race conditions:
|
|
289
|
+
|
|
290
|
+
```typescript
|
|
291
|
+
// Resolve with delay
|
|
292
|
+
s3Mock.on(GetObjectCommand).resolvesWithDelay({ Body: "data" }, 1000);
|
|
293
|
+
|
|
294
|
+
// Reject with delay
|
|
295
|
+
s3Mock.on(GetObjectCommand).rejectsWithDelay("Network timeout", 500);
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
### AWS Error Simulation
|
|
299
|
+
|
|
300
|
+
Convenient methods for common AWS errors:
|
|
301
|
+
|
|
302
|
+
```typescript
|
|
303
|
+
// S3 Errors
|
|
304
|
+
s3Mock.on(GetObjectCommand).rejectsWithNoSuchKey("missing-key");
|
|
305
|
+
s3Mock.on(GetObjectCommand).rejectsWithNoSuchBucket("missing-bucket");
|
|
306
|
+
s3Mock.on(GetObjectCommand).rejectsWithAccessDenied("protected-resource");
|
|
307
|
+
|
|
308
|
+
// DynamoDB Errors
|
|
309
|
+
dynamoMock.on(GetItemCommand).rejectsWithResourceNotFound("missing-table");
|
|
310
|
+
dynamoMock.on(PutItemCommand).rejectsWithConditionalCheckFailed();
|
|
311
|
+
|
|
312
|
+
// General AWS Errors
|
|
313
|
+
s3Mock.on(GetObjectCommand).rejectsWithThrottling();
|
|
314
|
+
s3Mock.on(GetObjectCommand).rejectsWithInternalServerError();
|
|
315
|
+
```
|
|
316
|
+
|
|
102
317
|
### Error Handling
|
|
103
318
|
|
|
104
319
|
```typescript
|
|
@@ -124,20 +339,80 @@ s3Mock.on(GetObjectCommand).callsFake(async (input, getClient) => {
|
|
|
124
339
|
### Mocking Existing Instances
|
|
125
340
|
|
|
126
341
|
```typescript
|
|
127
|
-
|
|
128
|
-
|
|
342
|
+
// Your application service that uses an injected S3 client
|
|
343
|
+
class FileUploadService {
|
|
344
|
+
constructor(private s3Client: S3Client) {}
|
|
345
|
+
|
|
346
|
+
async uploadFile(bucket: string, key: string, data: string) {
|
|
347
|
+
return await this.s3Client.send(
|
|
348
|
+
new PutObjectCommand({ Bucket: bucket, Key: key, Body: data }),
|
|
349
|
+
);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
test("should mock existing S3 client instance", async () => {
|
|
354
|
+
// Create the client your application will use
|
|
355
|
+
const s3Client = new S3Client({ region: "us-east-1" });
|
|
356
|
+
const service = new FileUploadService(s3Client);
|
|
357
|
+
|
|
358
|
+
// Mock the existing client instance
|
|
359
|
+
const mock = mockClientInstance(s3Client);
|
|
360
|
+
mock.on(PutObjectCommand).resolves({ ETag: "mock-etag" });
|
|
361
|
+
|
|
362
|
+
// Test your service
|
|
363
|
+
const result = await service.uploadFile("bucket", "key", "data");
|
|
364
|
+
|
|
365
|
+
expect(result.ETag).toBe("mock-etag");
|
|
366
|
+
expect(mock).toHaveReceivedCommand(PutObjectCommand);
|
|
367
|
+
});
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
### Debug Mode
|
|
129
371
|
|
|
130
|
-
mock
|
|
372
|
+
Enable debug logging to troubleshoot mock configurations and see detailed information about command matching:
|
|
131
373
|
|
|
132
|
-
|
|
133
|
-
const
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
374
|
+
```typescript
|
|
375
|
+
const s3Mock = mockClient(S3Client);
|
|
376
|
+
|
|
377
|
+
// Enable debug logging
|
|
378
|
+
s3Mock.enableDebug();
|
|
379
|
+
|
|
380
|
+
s3Mock
|
|
381
|
+
.on(GetObjectCommand, { Bucket: "test-bucket" })
|
|
382
|
+
.resolves({ Body: "data" });
|
|
383
|
+
|
|
384
|
+
// This will log:
|
|
385
|
+
// [AWS Mock Debug] Received command: GetObjectCommand
|
|
386
|
+
// [AWS Mock Debug] Found 1 mock(s) for GetObjectCommand
|
|
387
|
+
// [AWS Mock Debug] Using mock at index 0 for GetObjectCommand
|
|
388
|
+
await client.send(
|
|
389
|
+
new GetObjectCommand({ Bucket: "test-bucket", Key: "file.txt" }),
|
|
138
390
|
);
|
|
391
|
+
|
|
392
|
+
// Disable debug logging
|
|
393
|
+
s3Mock.disableDebug();
|
|
139
394
|
```
|
|
140
395
|
|
|
396
|
+
Debug mode logs include:
|
|
397
|
+
|
|
398
|
+
- Incoming commands and their inputs
|
|
399
|
+
- Number of configured mocks for each command
|
|
400
|
+
- Mock matching results and reasons for failures
|
|
401
|
+
- One-time mock removal notifications
|
|
402
|
+
|
|
403
|
+
## 🧪 Test Coverage
|
|
404
|
+
|
|
405
|
+
The library includes comprehensive test suites covering all features:
|
|
406
|
+
|
|
407
|
+
- **Core mocking functionality** - Command matching, response handling, sequential responses
|
|
408
|
+
- **Paginator support** - Automatic token handling for AWS pagination patterns
|
|
409
|
+
- **Debug logging** - Enable/disable functionality and proper console output formatting
|
|
410
|
+
- **Stream mocking** - S3 stream responses with environment detection
|
|
411
|
+
- **Error simulation** - AWS-specific errors and general error handling
|
|
412
|
+
- **Custom matchers** - Vitest integration for asserting command calls
|
|
413
|
+
|
|
414
|
+
All utilities have dedicated test files ensuring reliability and maintainability.
|
|
415
|
+
|
|
141
416
|
## 🧪 Custom Matchers
|
|
142
417
|
|
|
143
418
|
Import the custom matchers in your test setup:
|
|
@@ -182,6 +457,9 @@ test("should call DynamoDB", async () => {
|
|
|
182
457
|
expect(ddbMock).toHaveReceivedNthCommandWith(1, GetItemCommand, {
|
|
183
458
|
TableName: "users",
|
|
184
459
|
});
|
|
460
|
+
|
|
461
|
+
// Assert no other commands were received
|
|
462
|
+
expect(ddbMock).toHaveReceivedNoOtherCommands([GetItemCommand]);
|
|
185
463
|
});
|
|
186
464
|
```
|
|
187
465
|
|
|
@@ -205,6 +483,8 @@ Mocks an existing AWS SDK client instance.
|
|
|
205
483
|
- `reset()` - Clear all mocks and call history
|
|
206
484
|
- `restore()` - Restore original client behavior
|
|
207
485
|
- `calls()` - Get call history
|
|
486
|
+
- `enableDebug()` - Enable debug logging for troubleshooting
|
|
487
|
+
- `disableDebug()` - Disable debug logging
|
|
208
488
|
|
|
209
489
|
### `AwsCommandStub` Methods (Chainable)
|
|
210
490
|
|
|
@@ -214,6 +494,19 @@ Mocks an existing AWS SDK client instance.
|
|
|
214
494
|
- `rejectsOnce(error)` - Return error once
|
|
215
495
|
- `callsFake(handler)` - Custom response handler
|
|
216
496
|
- `callsFakeOnce(handler)` - Custom response handler (once)
|
|
497
|
+
- `resolvesStream(data)` - Return stream response (S3 helper)
|
|
498
|
+
- `resolvesStreamOnce(data)` - Return stream response once (S3 helper)
|
|
499
|
+
- `resolvesWithDelay(output, delayMs)` - Return response with delay
|
|
500
|
+
- `rejectsWithDelay(error, delayMs)` - Return error with delay
|
|
501
|
+
- `resolvesPaginated(items, options?)` - Return paginated responses with automatic token handling
|
|
502
|
+
- `resolvesFromFile(filePath)` - Load response from file (JSON files are parsed, others returned as strings)
|
|
503
|
+
- `rejectsWithNoSuchKey(key?)` - Reject with S3 NoSuchKey error
|
|
504
|
+
- `rejectsWithNoSuchBucket(bucket?)` - Reject with S3 NoSuchBucket error
|
|
505
|
+
- `rejectsWithAccessDenied(resource?)` - Reject with AccessDenied error
|
|
506
|
+
- `rejectsWithResourceNotFound(resource?)` - Reject with DynamoDB ResourceNotFound error
|
|
507
|
+
- `rejectsWithConditionalCheckFailed()` - Reject with DynamoDB ConditionalCheckFailed error
|
|
508
|
+
- `rejectsWithThrottling()` - Reject with Throttling error
|
|
509
|
+
- `rejectsWithInternalServerError()` - Reject with InternalServerError
|
|
217
510
|
|
|
218
511
|
## 🤝 Contributing
|
|
219
512
|
|
|
@@ -250,6 +543,10 @@ bun nx build
|
|
|
250
543
|
|
|
251
544
|
See [CONTRIBUTING.md](./CONTRIBUTING.md) for the complete guide.
|
|
252
545
|
|
|
546
|
+
## 🙏 Acknowledgements
|
|
547
|
+
|
|
548
|
+
This library was inspired by [aws-sdk-client-mock](https://github.com/m-radzikowski/aws-sdk-client-mock). Adapted the core concepts and API design for Vitest while adding additional features and capabilities.
|
|
549
|
+
|
|
253
550
|
## 📝 License
|
|
254
551
|
|
|
255
552
|
MIT
|
package/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const b=require("vitest"),P=require("node:fs"),R=require("node:path"),N=require("node:stream"),W=require("./matchers-G36N2DNa.cjs");class d extends Error{constructor(e,s,c,n){super(e),this.name="AwsError",this.code=s,this.statusCode=c,this.retryable=n}}const C=t=>{const e=t?`The specified key does not exist. Key: ${t}`:"The specified key does not exist.";return new d(e,"NoSuchKey",404,!1)},M=t=>{const e=t?`The specified bucket does not exist. Bucket: ${t}`:"The specified bucket does not exist.";return new d(e,"NoSuchBucket",404,!1)},$=t=>{const e=t?`Access Denied for resource: ${t}`:"Access Denied";return new d(e,"AccessDenied",403,!1)},D=t=>{const e=t?`Requested resource not found: ${t}`:"Requested resource not found";return new d(e,"ResourceNotFoundException",400,!1)},I=()=>new d("The conditional request failed","ConditionalCheckFailedException",400,!1),O=()=>new d("Rate exceeded","Throttling",400,!0),T=()=>new d("We encountered an internal error. Please try again.","InternalServerError",500,!0);function k(){return{enabled:!1,log(t,e){this.enabled&&(e===void 0?console.log(`[aws-sdk-vitest-mock](Debug) ${t}`):console.log(`[aws-sdk-vitest-mock](Debug) ${t}`,e))}}}function y(t){t.enabled=!0}function v(t){t.enabled=!1}function F(t){const e=R.resolve(t),s=P.readFileSync(e,"utf8");return t.endsWith(".json")?JSON.parse(s):s}function L(t,e={}){const{pageSize:s=10,tokenKey:c="NextToken",itemsKey:n="Items"}=e;if(t.length===0)return[{[n]:[]}];const o=[];for(let r=0;r<t.length;r+=s){const u=t.slice(r,r+s),i=r+s<t.length,l={[n]:u};if(i){const a=l;a[c]=`token-${r+s}`}o.push(l)}return o}function A(){return typeof process<"u"&&process.versions?.node?"node":typeof process<"u"&&process.versions?.bun?"bun":"browser"}function K(t){const e=typeof t=="string"?Buffer.from(t,"utf8"):Buffer.from(t);return new N.Readable({read(){this.push(e),this.push(void 0)}})}function q(t){let e;return typeof t=="string"?e=new TextEncoder().encode(t):t instanceof Buffer?e=new Uint8Array(t):e=t,new ReadableStream({start(s){s.enqueue(e),s.close()}})}function m(t){const e=A();return e==="node"||e==="bun"?K(t):q(t)}function w(t,e){return Object.keys(e).every(s=>{const c=e[s],n=t[s];return c&&typeof c=="object"&&!Array.isArray(c)?typeof n!="object"||n===null?!1:w(n,c):n===c})}function j(t,e){if(t===e)return!0;if(typeof t!="object"||t===null||typeof e!="object"||e===null)return t===e;const s=Object.keys(t),c=Object.keys(e);return s.length!==c.length?!1:c.every(n=>{if(!Object.prototype.hasOwnProperty.call(t,n))return!1;const o=t,r=e,u=o[n],i=r[n];return typeof u=="object"&&u!==null&&typeof i=="object"&&i!==null?j(u,i):u===i})}function S(t){return async function(e){const s=()=>this;t.debugLogger.log(`Received command: ${e.constructor.name}`,e.input);const c=t.map.get(e.constructor);if(c){t.debugLogger.log(`Found ${c.length} mock(s) for ${e.constructor.name}`);const n=c.findIndex(o=>o.strict?o.matcher&&j(e.input,o.matcher):!o.matcher||w(e.input,o.matcher));if(n===-1)t.debugLogger.log(`No matching mock found for ${e.constructor.name}`,e.input);else{const o=c[n];if(!o)throw new Error(`Mock at index ${n} not found`);return t.debugLogger.log(`Using mock at index ${n} for ${e.constructor.name}`),o.once&&(c.splice(n,1),t.debugLogger.log(`Removed one-time mock for ${e.constructor.name}`)),o.handler(e.input,s)}}else t.debugLogger.log(`No mocks configured for ${e.constructor.name}`);throw new Error(`No mock configured for command: ${e.constructor.name}`)}}function x(t,e,s,c={}){const n=(r,u)=>{const i={matcher:s,handler:r,once:u,strict:!!c.strict},l=t.map.get(e)??[];if(u){const a=l.findIndex(f=>!f.once);a===-1?l.push(i):l.splice(a,0,i),t.map.set(e,l)}else{const a=l.filter(f=>f.once||JSON.stringify(f.matcher)!==JSON.stringify(s));a.push(i),t.map.set(e,a)}},o={resolves(r){return n(()=>Promise.resolve(r),!1),o},rejects(r){return n(()=>{const u=typeof r=="string"?new Error(r):r;return Promise.reject(u)},!1),o},callsFake(r){return n(r,!1),o},resolvesOnce(r){return n(()=>Promise.resolve(r),!0),o},rejectsOnce(r){return n(()=>{const u=typeof r=="string"?new Error(r):r;return Promise.reject(u)},!0),o},callsFakeOnce(r){return n(r,!0),o},resolvesStream(r){return n(()=>Promise.resolve({Body:m(r)}),!1),o},resolvesStreamOnce(r){return n(()=>Promise.resolve({Body:m(r)}),!0),o},resolvesWithDelay(r,u){const i=l=>{setTimeout(()=>l(r),u)};return n(()=>new Promise(i),!1),o},rejectsWithDelay(r,u){const i=typeof r=="string"?new Error(r):r,l=(a,f)=>{setTimeout(()=>f(i),u)};return n(()=>new Promise(l),!1),o},rejectsWithNoSuchKey(r){return n(()=>Promise.reject(C(r)),!1),o},rejectsWithNoSuchBucket(r){return n(()=>Promise.reject(M(r)),!1),o},rejectsWithAccessDenied(r){return n(()=>Promise.reject($(r)),!1),o},rejectsWithResourceNotFound(r){return n(()=>Promise.reject(D(r)),!1),o},rejectsWithConditionalCheckFailed(){return n(()=>Promise.reject(I()),!1),o},rejectsWithThrottling(){return n(()=>Promise.reject(O()),!1),o},rejectsWithInternalServerError(){return n(()=>Promise.reject(T()),!1),o},resolvesPaginated(r,u={}){const i=L(r,u);let l=0;return n(a=>{const f=u.tokenKey||"NextToken",p=a[f];if(p){const g=/token-(\d+)/.exec(p);if(g&&g[1]){const E=g[1];l=Math.floor(Number.parseInt(E,10)/(u.pageSize||10))}}else l=0;const h=i[l]||i[i.length-1]||i[0];if(!h)throw new Error("No paginated responses available");return l=Math.min(l+1,i.length-1),Promise.resolve(h)},!1),o},resolvesFromFile(r){return n(()=>{const u=F(r);return Promise.resolve(u)},!1),o}};return o}const B=t=>{const e={map:new WeakMap,debugLogger:k()},s=t.prototype,c=b.vi.spyOn(s,"send").mockImplementation(S(e));return{client:void 0,on:(o,r,u)=>x(e,o,r,u),reset:()=>{c.mockClear(),e.map=new WeakMap},restore:()=>{c.mockRestore(),e.map=new WeakMap},calls:()=>c.mock.calls,enableDebug:()=>{y(e.debugLogger)},disableDebug:()=>{v(e.debugLogger)}}},V=t=>{const e={map:new WeakMap,debugLogger:k()},s=b.vi.spyOn(t,"send").mockImplementation(S(e));return{client:t,on:(n,o,r)=>x(e,n,o,r),reset:()=>{s.mockClear(),e.map=new WeakMap},restore:()=>{s.mockRestore(),e.map=new WeakMap},calls:()=>s.mock.calls,enableDebug:()=>{y(e.debugLogger)},disableDebug:()=>{v(e.debugLogger)}}};exports.matchers=W.matchers;exports.mockClient=B;exports.mockClientInstance=V;
|
package/index.js
CHANGED
|
@@ -1,113 +1,333 @@
|
|
|
1
|
-
import { vi as
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
import { vi as b } from "vitest";
|
|
2
|
+
import { readFileSync as P } from "node:fs";
|
|
3
|
+
import R from "node:path";
|
|
4
|
+
import { Readable as N } from "node:stream";
|
|
5
|
+
import { m as X } from "./matchers-_zpN1oru.js";
|
|
6
|
+
class d extends Error {
|
|
7
|
+
constructor(e, s, c, n) {
|
|
8
|
+
super(e), this.name = "AwsError", this.code = s, this.statusCode = c, this.retryable = n;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
const W = (t) => {
|
|
12
|
+
const e = t ? `The specified key does not exist. Key: ${t}` : "The specified key does not exist.";
|
|
13
|
+
return new d(e, "NoSuchKey", 404, !1);
|
|
14
|
+
}, $ = (t) => {
|
|
15
|
+
const e = t ? `The specified bucket does not exist. Bucket: ${t}` : "The specified bucket does not exist.";
|
|
16
|
+
return new d(e, "NoSuchBucket", 404, !1);
|
|
17
|
+
}, D = (t) => {
|
|
18
|
+
const e = t ? `Access Denied for resource: ${t}` : "Access Denied";
|
|
19
|
+
return new d(e, "AccessDenied", 403, !1);
|
|
20
|
+
}, M = (t) => {
|
|
21
|
+
const e = t ? `Requested resource not found: ${t}` : "Requested resource not found";
|
|
22
|
+
return new d(e, "ResourceNotFoundException", 400, !1);
|
|
23
|
+
}, C = () => new d(
|
|
24
|
+
"The conditional request failed",
|
|
25
|
+
"ConditionalCheckFailedException",
|
|
26
|
+
400,
|
|
27
|
+
!1
|
|
28
|
+
), I = () => new d("Rate exceeded", "Throttling", 400, !0), O = () => new d(
|
|
29
|
+
"We encountered an internal error. Please try again.",
|
|
30
|
+
"InternalServerError",
|
|
31
|
+
500,
|
|
32
|
+
!0
|
|
33
|
+
);
|
|
34
|
+
function k() {
|
|
35
|
+
return {
|
|
36
|
+
enabled: !1,
|
|
37
|
+
log(t, e) {
|
|
38
|
+
this.enabled && (e === void 0 ? console.log(`[aws-sdk-vitest-mock](Debug) ${t}`) : console.log(`[aws-sdk-vitest-mock](Debug) ${t}`, e));
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
function y(t) {
|
|
43
|
+
t.enabled = !0;
|
|
44
|
+
}
|
|
45
|
+
function v(t) {
|
|
46
|
+
t.enabled = !1;
|
|
47
|
+
}
|
|
48
|
+
function T(t) {
|
|
49
|
+
const e = R.resolve(t), s = P(e, "utf8");
|
|
50
|
+
return t.endsWith(".json") ? JSON.parse(s) : s;
|
|
51
|
+
}
|
|
52
|
+
function F(t, e = {}) {
|
|
53
|
+
const { pageSize: s = 10, tokenKey: c = "NextToken", itemsKey: n = "Items" } = e;
|
|
54
|
+
if (t.length === 0)
|
|
55
|
+
return [{ [n]: [] }];
|
|
56
|
+
const o = [];
|
|
57
|
+
for (let r = 0; r < t.length; r += s) {
|
|
58
|
+
const u = t.slice(r, r + s), i = r + s < t.length, l = { [n]: u };
|
|
59
|
+
if (i) {
|
|
60
|
+
const a = l;
|
|
61
|
+
a[c] = `token-${r + s}`;
|
|
62
|
+
}
|
|
63
|
+
o.push(l);
|
|
64
|
+
}
|
|
65
|
+
return o;
|
|
66
|
+
}
|
|
67
|
+
function L() {
|
|
68
|
+
return typeof process < "u" && process.versions?.node ? "node" : typeof process < "u" && process.versions?.bun ? "bun" : "browser";
|
|
69
|
+
}
|
|
70
|
+
function A(t) {
|
|
71
|
+
const e = typeof t == "string" ? Buffer.from(t, "utf8") : Buffer.from(t);
|
|
72
|
+
return new N({
|
|
73
|
+
read() {
|
|
74
|
+
this.push(e), this.push(void 0);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
function K(t) {
|
|
79
|
+
let e;
|
|
80
|
+
return typeof t == "string" ? e = new TextEncoder().encode(t) : t instanceof Buffer ? e = new Uint8Array(t) : e = t, new ReadableStream({
|
|
81
|
+
start(s) {
|
|
82
|
+
s.enqueue(e), s.close();
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
function h(t) {
|
|
87
|
+
const e = L();
|
|
88
|
+
return e === "node" || e === "bun" ? A(t) : K(t);
|
|
89
|
+
}
|
|
90
|
+
function w(t, e) {
|
|
91
|
+
return Object.keys(e).every((s) => {
|
|
92
|
+
const c = e[s], n = t[s];
|
|
93
|
+
return c && typeof c == "object" && !Array.isArray(c) ? typeof n != "object" || n === null ? !1 : w(
|
|
94
|
+
n,
|
|
95
|
+
c
|
|
96
|
+
) : n === c;
|
|
7
97
|
});
|
|
8
98
|
}
|
|
9
|
-
function
|
|
10
|
-
if (
|
|
11
|
-
if (typeof
|
|
12
|
-
return
|
|
13
|
-
const
|
|
14
|
-
return
|
|
15
|
-
if (!Object.prototype.hasOwnProperty.call(
|
|
16
|
-
const
|
|
17
|
-
return typeof
|
|
99
|
+
function j(t, e) {
|
|
100
|
+
if (t === e) return !0;
|
|
101
|
+
if (typeof t != "object" || t === null || typeof e != "object" || e === null)
|
|
102
|
+
return t === e;
|
|
103
|
+
const s = Object.keys(t), c = Object.keys(e);
|
|
104
|
+
return s.length !== c.length ? !1 : c.every((n) => {
|
|
105
|
+
if (!Object.prototype.hasOwnProperty.call(t, n)) return !1;
|
|
106
|
+
const o = t, r = e, u = o[n], i = r[n];
|
|
107
|
+
return typeof u == "object" && u !== null && typeof i == "object" && i !== null ? j(u, i) : u === i;
|
|
18
108
|
});
|
|
19
109
|
}
|
|
20
|
-
function
|
|
21
|
-
return async function(
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
110
|
+
function x(t) {
|
|
111
|
+
return async function(e) {
|
|
112
|
+
const s = () => this;
|
|
113
|
+
t.debugLogger.log(
|
|
114
|
+
`Received command: ${e.constructor.name}`,
|
|
115
|
+
e.input
|
|
116
|
+
);
|
|
117
|
+
const c = t.map.get(
|
|
118
|
+
e.constructor
|
|
119
|
+
);
|
|
120
|
+
if (c) {
|
|
121
|
+
t.debugLogger.log(
|
|
122
|
+
`Found ${c.length} mock(s) for ${e.constructor.name}`
|
|
123
|
+
);
|
|
124
|
+
const n = c.findIndex((o) => o.strict ? o.matcher && j(e.input, o.matcher) : !o.matcher || w(e.input, o.matcher));
|
|
125
|
+
if (n === -1)
|
|
126
|
+
t.debugLogger.log(
|
|
127
|
+
`No matching mock found for ${e.constructor.name}`,
|
|
128
|
+
e.input
|
|
129
|
+
);
|
|
130
|
+
else {
|
|
131
|
+
const o = c[n];
|
|
132
|
+
if (!o)
|
|
133
|
+
throw new Error(`Mock at index ${n} not found`);
|
|
134
|
+
return t.debugLogger.log(
|
|
135
|
+
`Using mock at index ${n} for ${e.constructor.name}`
|
|
136
|
+
), o.once && (c.splice(n, 1), t.debugLogger.log(
|
|
137
|
+
`Removed one-time mock for ${e.constructor.name}`
|
|
138
|
+
)), o.handler(e.input, s);
|
|
28
139
|
}
|
|
29
|
-
}
|
|
30
|
-
|
|
140
|
+
} else
|
|
141
|
+
t.debugLogger.log(
|
|
142
|
+
`No mocks configured for ${e.constructor.name}`
|
|
143
|
+
);
|
|
144
|
+
throw new Error(
|
|
145
|
+
`No mock configured for command: ${e.constructor.name}`
|
|
146
|
+
);
|
|
31
147
|
};
|
|
32
148
|
}
|
|
33
|
-
function
|
|
34
|
-
const n = (
|
|
35
|
-
const
|
|
36
|
-
matcher:
|
|
37
|
-
handler:
|
|
38
|
-
once:
|
|
39
|
-
strict: !!
|
|
40
|
-
},
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
149
|
+
function S(t, e, s, c = {}) {
|
|
150
|
+
const n = (r, u) => {
|
|
151
|
+
const i = {
|
|
152
|
+
matcher: s,
|
|
153
|
+
handler: r,
|
|
154
|
+
once: u,
|
|
155
|
+
strict: !!c.strict
|
|
156
|
+
}, l = t.map.get(
|
|
157
|
+
e
|
|
158
|
+
) ?? [];
|
|
159
|
+
if (u) {
|
|
160
|
+
const a = l.findIndex((f) => !f.once);
|
|
161
|
+
a === -1 ? l.push(i) : l.splice(a, 0, i), t.map.set(
|
|
162
|
+
e,
|
|
163
|
+
l
|
|
164
|
+
);
|
|
44
165
|
} else {
|
|
45
|
-
const
|
|
46
|
-
(
|
|
166
|
+
const a = l.filter(
|
|
167
|
+
(f) => f.once || JSON.stringify(f.matcher) !== JSON.stringify(s)
|
|
168
|
+
);
|
|
169
|
+
a.push(i), t.map.set(
|
|
170
|
+
e,
|
|
171
|
+
a
|
|
47
172
|
);
|
|
48
|
-
l.push(p), r.map.set(t, l);
|
|
49
173
|
}
|
|
50
|
-
},
|
|
51
|
-
resolves(
|
|
52
|
-
return n(() => Promise.resolve(
|
|
174
|
+
}, o = {
|
|
175
|
+
resolves(r) {
|
|
176
|
+
return n(() => Promise.resolve(r), !1), o;
|
|
53
177
|
},
|
|
54
|
-
rejects(
|
|
178
|
+
rejects(r) {
|
|
55
179
|
return n(() => {
|
|
56
|
-
const
|
|
57
|
-
return Promise.reject(
|
|
58
|
-
}, !1),
|
|
180
|
+
const u = typeof r == "string" ? new Error(r) : r;
|
|
181
|
+
return Promise.reject(u);
|
|
182
|
+
}, !1), o;
|
|
59
183
|
},
|
|
60
|
-
callsFake(
|
|
61
|
-
return n(
|
|
184
|
+
callsFake(r) {
|
|
185
|
+
return n(r, !1), o;
|
|
62
186
|
},
|
|
63
|
-
resolvesOnce(
|
|
64
|
-
return n(() => Promise.resolve(
|
|
187
|
+
resolvesOnce(r) {
|
|
188
|
+
return n(() => Promise.resolve(r), !0), o;
|
|
65
189
|
},
|
|
66
|
-
rejectsOnce(
|
|
190
|
+
rejectsOnce(r) {
|
|
67
191
|
return n(() => {
|
|
68
|
-
const
|
|
69
|
-
return Promise.reject(
|
|
70
|
-
}, !0),
|
|
192
|
+
const u = typeof r == "string" ? new Error(r) : r;
|
|
193
|
+
return Promise.reject(u);
|
|
194
|
+
}, !0), o;
|
|
195
|
+
},
|
|
196
|
+
callsFakeOnce(r) {
|
|
197
|
+
return n(r, !0), o;
|
|
198
|
+
},
|
|
199
|
+
resolvesStream(r) {
|
|
200
|
+
return n(
|
|
201
|
+
() => Promise.resolve({ Body: h(r) }),
|
|
202
|
+
!1
|
|
203
|
+
), o;
|
|
204
|
+
},
|
|
205
|
+
resolvesStreamOnce(r) {
|
|
206
|
+
return n(
|
|
207
|
+
() => Promise.resolve({ Body: h(r) }),
|
|
208
|
+
!0
|
|
209
|
+
), o;
|
|
210
|
+
},
|
|
211
|
+
resolvesWithDelay(r, u) {
|
|
212
|
+
const i = (l) => {
|
|
213
|
+
setTimeout(() => l(r), u);
|
|
214
|
+
};
|
|
215
|
+
return n(() => new Promise(i), !1), o;
|
|
216
|
+
},
|
|
217
|
+
rejectsWithDelay(r, u) {
|
|
218
|
+
const i = typeof r == "string" ? new Error(r) : r, l = (a, f) => {
|
|
219
|
+
setTimeout(() => f(i), u);
|
|
220
|
+
};
|
|
221
|
+
return n(() => new Promise(l), !1), o;
|
|
222
|
+
},
|
|
223
|
+
rejectsWithNoSuchKey(r) {
|
|
224
|
+
return n(() => Promise.reject(W(r)), !1), o;
|
|
225
|
+
},
|
|
226
|
+
rejectsWithNoSuchBucket(r) {
|
|
227
|
+
return n(() => Promise.reject($(r)), !1), o;
|
|
228
|
+
},
|
|
229
|
+
rejectsWithAccessDenied(r) {
|
|
230
|
+
return n(() => Promise.reject(D(r)), !1), o;
|
|
71
231
|
},
|
|
72
|
-
|
|
73
|
-
return n(
|
|
232
|
+
rejectsWithResourceNotFound(r) {
|
|
233
|
+
return n(
|
|
234
|
+
() => Promise.reject(M(r)),
|
|
235
|
+
!1
|
|
236
|
+
), o;
|
|
237
|
+
},
|
|
238
|
+
rejectsWithConditionalCheckFailed() {
|
|
239
|
+
return n(
|
|
240
|
+
() => Promise.reject(C()),
|
|
241
|
+
!1
|
|
242
|
+
), o;
|
|
243
|
+
},
|
|
244
|
+
rejectsWithThrottling() {
|
|
245
|
+
return n(() => Promise.reject(I()), !1), o;
|
|
246
|
+
},
|
|
247
|
+
rejectsWithInternalServerError() {
|
|
248
|
+
return n(() => Promise.reject(O()), !1), o;
|
|
249
|
+
},
|
|
250
|
+
resolvesPaginated(r, u = {}) {
|
|
251
|
+
const i = F(r, u);
|
|
252
|
+
let l = 0;
|
|
253
|
+
return n((a) => {
|
|
254
|
+
const f = u.tokenKey || "NextToken", p = a[f];
|
|
255
|
+
if (p) {
|
|
256
|
+
const g = /token-(\d+)/.exec(p);
|
|
257
|
+
if (g && g[1]) {
|
|
258
|
+
const E = g[1];
|
|
259
|
+
l = Math.floor(
|
|
260
|
+
Number.parseInt(E, 10) / (u.pageSize || 10)
|
|
261
|
+
);
|
|
262
|
+
}
|
|
263
|
+
} else
|
|
264
|
+
l = 0;
|
|
265
|
+
const m = (
|
|
266
|
+
// eslint-disable-next-line security/detect-object-injection
|
|
267
|
+
i[l] || // eslint-disable-next-line unicorn/prefer-at -- TypeScript target doesn't support Array.at() method
|
|
268
|
+
i[i.length - 1] || i[0]
|
|
269
|
+
);
|
|
270
|
+
if (!m)
|
|
271
|
+
throw new Error("No paginated responses available");
|
|
272
|
+
return l = Math.min(l + 1, i.length - 1), Promise.resolve(m);
|
|
273
|
+
}, !1), o;
|
|
274
|
+
},
|
|
275
|
+
resolvesFromFile(r) {
|
|
276
|
+
return n(() => {
|
|
277
|
+
const u = T(r);
|
|
278
|
+
return Promise.resolve(u);
|
|
279
|
+
}, !1), o;
|
|
74
280
|
}
|
|
75
281
|
};
|
|
76
|
-
return
|
|
282
|
+
return o;
|
|
77
283
|
}
|
|
78
|
-
const
|
|
79
|
-
const
|
|
80
|
-
map: /* @__PURE__ */ new WeakMap()
|
|
81
|
-
|
|
284
|
+
const _ = (t) => {
|
|
285
|
+
const e = {
|
|
286
|
+
map: /* @__PURE__ */ new WeakMap(),
|
|
287
|
+
debugLogger: k()
|
|
288
|
+
}, s = t.prototype, c = b.spyOn(s, "send").mockImplementation(x(e));
|
|
82
289
|
return {
|
|
83
290
|
client: void 0,
|
|
84
|
-
on: (
|
|
291
|
+
on: (o, r, u) => S(e, o, r, u),
|
|
85
292
|
reset: () => {
|
|
86
|
-
|
|
293
|
+
c.mockClear(), e.map = /* @__PURE__ */ new WeakMap();
|
|
87
294
|
},
|
|
88
295
|
restore: () => {
|
|
89
|
-
|
|
296
|
+
c.mockRestore(), e.map = /* @__PURE__ */ new WeakMap();
|
|
297
|
+
},
|
|
298
|
+
calls: () => c.mock.calls,
|
|
299
|
+
enableDebug: () => {
|
|
300
|
+
y(e.debugLogger);
|
|
90
301
|
},
|
|
91
|
-
|
|
302
|
+
disableDebug: () => {
|
|
303
|
+
v(e.debugLogger);
|
|
304
|
+
}
|
|
92
305
|
};
|
|
93
|
-
},
|
|
94
|
-
const
|
|
95
|
-
map: /* @__PURE__ */ new WeakMap()
|
|
96
|
-
|
|
306
|
+
}, G = (t) => {
|
|
307
|
+
const e = {
|
|
308
|
+
map: /* @__PURE__ */ new WeakMap(),
|
|
309
|
+
debugLogger: k()
|
|
310
|
+
}, s = b.spyOn(t, "send").mockImplementation(x(e));
|
|
97
311
|
return {
|
|
98
|
-
client:
|
|
99
|
-
on: (n,
|
|
312
|
+
client: t,
|
|
313
|
+
on: (n, o, r) => S(e, n, o, r),
|
|
100
314
|
reset: () => {
|
|
101
|
-
|
|
315
|
+
s.mockClear(), e.map = /* @__PURE__ */ new WeakMap();
|
|
102
316
|
},
|
|
103
317
|
restore: () => {
|
|
104
|
-
|
|
318
|
+
s.mockRestore(), e.map = /* @__PURE__ */ new WeakMap();
|
|
105
319
|
},
|
|
106
|
-
calls: () =>
|
|
320
|
+
calls: () => s.mock.calls,
|
|
321
|
+
enableDebug: () => {
|
|
322
|
+
y(e.debugLogger);
|
|
323
|
+
},
|
|
324
|
+
disableDebug: () => {
|
|
325
|
+
v(e.debugLogger);
|
|
326
|
+
}
|
|
107
327
|
};
|
|
108
328
|
};
|
|
109
329
|
export {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
330
|
+
X as matchers,
|
|
331
|
+
_ as mockClient,
|
|
332
|
+
G as mockClientInstance
|
|
113
333
|
};
|
package/lib/matchers.d.ts
CHANGED
|
@@ -13,17 +13,19 @@ export declare const matchers: {
|
|
|
13
13
|
toHaveReceivedNthCommandWith(this: {
|
|
14
14
|
equals: (a: unknown, b: unknown) => boolean;
|
|
15
15
|
}, received: AwsClientStub, n: number, command: CommandConstructor, input: Record<string, unknown>): MatcherResult;
|
|
16
|
+
toHaveReceivedNoOtherCommands(received: AwsClientStub, expectedCommands?: CommandConstructor[]): MatcherResult;
|
|
16
17
|
};
|
|
17
18
|
export interface AwsSdkMatchers<R = unknown> {
|
|
18
19
|
toHaveReceivedCommand(command: CommandConstructor): R;
|
|
19
20
|
toHaveReceivedCommandTimes(command: CommandConstructor, times: number): R;
|
|
20
21
|
toHaveReceivedCommandWith(command: CommandConstructor, input: Record<string, unknown>): R;
|
|
21
22
|
toHaveReceivedNthCommandWith(n: number, command: CommandConstructor, input: Record<string, unknown>): R;
|
|
23
|
+
toHaveReceivedNoOtherCommands(expectedCommands?: CommandConstructor[]): R;
|
|
22
24
|
}
|
|
23
|
-
|
|
25
|
+
export type { MatcherResult };
|
|
26
|
+
declare module "vitest" {
|
|
24
27
|
interface Assertion extends AwsSdkMatchers {
|
|
25
28
|
}
|
|
26
29
|
interface AsymmetricMatchersContaining extends AwsSdkMatchers {
|
|
27
30
|
}
|
|
28
31
|
}
|
|
29
|
-
export {};
|
package/lib/mock-client.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { SmithyResolvedConfiguration } from '@smithy/smithy-client';
|
|
2
2
|
import { MiddlewareStack, Handler } from '@smithy/types';
|
|
3
3
|
import { Mock } from 'vitest';
|
|
4
|
+
import { PaginatorOptions } from './utils/paginator-helpers.js';
|
|
5
|
+
import { StreamInput } from './utils/stream-helpers.js';
|
|
4
6
|
export interface MetadataBearer {
|
|
5
7
|
$metadata?: unknown;
|
|
6
8
|
}
|
|
@@ -27,7 +29,9 @@ export interface AwsClientStub<TClient extends AnyClient = AnyClient> {
|
|
|
27
29
|
on: <TInput extends object, TOutput extends MetadataBearer>(command: CommandConstructor<TInput, TOutput>, request?: Partial<TInput>, options?: MockOptions) => AwsCommandStub<TInput, TOutput, TClient>;
|
|
28
30
|
reset: () => void;
|
|
29
31
|
restore: () => void;
|
|
30
|
-
calls: () => ReturnType<Mock[
|
|
32
|
+
calls: () => ReturnType<Mock["mock"]["calls"]["slice"]>;
|
|
33
|
+
enableDebug: () => void;
|
|
34
|
+
disableDebug: () => void;
|
|
31
35
|
}
|
|
32
36
|
export interface AwsCommandStub<TInput extends object, TOutput extends MetadataBearer, TClient extends AnyClient = AnyClient> {
|
|
33
37
|
/** Set a permanent mock response (used after all once handlers are consumed) */
|
|
@@ -42,6 +46,32 @@ export interface AwsCommandStub<TInput extends object, TOutput extends MetadataB
|
|
|
42
46
|
rejectsOnce: (error: Error | string) => AwsCommandStub<TInput, TOutput, TClient>;
|
|
43
47
|
/** Add a one-time custom handler (consumed in order) */
|
|
44
48
|
callsFakeOnce: (fn: CommandHandler<TInput, TOutput, TClient>) => AwsCommandStub<TInput, TOutput, TClient>;
|
|
49
|
+
/** Set a permanent stream response for S3-like operations */
|
|
50
|
+
resolvesStream: (data: StreamInput) => AwsCommandStub<TInput, TOutput, TClient>;
|
|
51
|
+
/** Set a one-time stream response for S3-like operations */
|
|
52
|
+
resolvesStreamOnce: (data: StreamInput) => AwsCommandStub<TInput, TOutput, TClient>;
|
|
53
|
+
/** Set a permanent mock response with delay */
|
|
54
|
+
resolvesWithDelay: (output: Partial<TOutput>, delayMs: number) => AwsCommandStub<TInput, TOutput, TClient>;
|
|
55
|
+
/** Set a permanent mock rejection with delay */
|
|
56
|
+
rejectsWithDelay: (error: Error | string, delayMs: number) => AwsCommandStub<TInput, TOutput, TClient>;
|
|
57
|
+
/** Reject with S3 NoSuchKey error */
|
|
58
|
+
rejectsWithNoSuchKey: (key?: string) => AwsCommandStub<TInput, TOutput, TClient>;
|
|
59
|
+
/** Reject with S3 NoSuchBucket error */
|
|
60
|
+
rejectsWithNoSuchBucket: (bucket?: string) => AwsCommandStub<TInput, TOutput, TClient>;
|
|
61
|
+
/** Reject with AccessDenied error */
|
|
62
|
+
rejectsWithAccessDenied: (resource?: string) => AwsCommandStub<TInput, TOutput, TClient>;
|
|
63
|
+
/** Reject with DynamoDB ResourceNotFound error */
|
|
64
|
+
rejectsWithResourceNotFound: (resource?: string) => AwsCommandStub<TInput, TOutput, TClient>;
|
|
65
|
+
/** Reject with DynamoDB ConditionalCheckFailed error */
|
|
66
|
+
rejectsWithConditionalCheckFailed: () => AwsCommandStub<TInput, TOutput, TClient>;
|
|
67
|
+
/** Reject with Throttling error */
|
|
68
|
+
rejectsWithThrottling: () => AwsCommandStub<TInput, TOutput, TClient>;
|
|
69
|
+
/** Reject with InternalServerError */
|
|
70
|
+
rejectsWithInternalServerError: () => AwsCommandStub<TInput, TOutput, TClient>;
|
|
71
|
+
/** Set paginated responses for AWS pagination */
|
|
72
|
+
resolvesPaginated: <T = unknown>(items: T[], options?: PaginatorOptions) => AwsCommandStub<TInput, TOutput, TClient>;
|
|
73
|
+
/** Load response from file (JSON files are parsed, others returned as strings) */
|
|
74
|
+
resolvesFromFile: (filePath: string) => AwsCommandStub<TInput, TOutput, TClient>;
|
|
45
75
|
}
|
|
46
76
|
export declare const mockClient: <TClient extends AnyClient>(clientConstructor: ClientConstructor<TClient>) => AwsClientStub<TClient>;
|
|
47
77
|
export declare const mockClientInstance: <TClient extends AnyClient>(clientInstance: TClient) => AwsClientStub<AnyClient>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Common AWS SDK error types and factory functions
|
|
3
|
+
*/
|
|
4
|
+
export declare class AwsError extends Error {
|
|
5
|
+
readonly name: string;
|
|
6
|
+
readonly code: string;
|
|
7
|
+
readonly statusCode?: number;
|
|
8
|
+
readonly retryable?: boolean;
|
|
9
|
+
constructor(message: string, code: string, statusCode?: number, retryable?: boolean);
|
|
10
|
+
}
|
|
11
|
+
export declare const createNoSuchKeyError: (key?: string) => AwsError;
|
|
12
|
+
export declare const createNoSuchBucketError: (bucket?: string) => AwsError;
|
|
13
|
+
export declare const createAccessDeniedError: (resource?: string) => AwsError;
|
|
14
|
+
export declare const createResourceNotFoundError: (resource?: string) => AwsError;
|
|
15
|
+
export declare const createConditionalCheckFailedError: () => AwsError;
|
|
16
|
+
export declare const createThrottlingError: () => AwsError;
|
|
17
|
+
export declare const createInternalServerError: () => AwsError;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare const colors: {
|
|
2
|
+
readonly red: (text: string) => string;
|
|
3
|
+
readonly green: (text: string) => string;
|
|
4
|
+
readonly yellow: (text: string) => string;
|
|
5
|
+
readonly blue: (text: string) => string;
|
|
6
|
+
readonly magenta: (text: string) => string;
|
|
7
|
+
readonly cyan: (text: string) => string;
|
|
8
|
+
readonly gray: (text: string) => string;
|
|
9
|
+
readonly bold: (text: string) => string;
|
|
10
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export interface DebugLogger {
|
|
2
|
+
enabled: boolean;
|
|
3
|
+
log: (message: string, data?: unknown) => void;
|
|
4
|
+
}
|
|
5
|
+
export declare function createDebugLogger(): DebugLogger;
|
|
6
|
+
export declare function enableDebug(logger: DebugLogger): void;
|
|
7
|
+
export declare function disableDebug(logger: DebugLogger): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function loadFixture(filePath: string): unknown;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface PaginatorOptions {
|
|
2
|
+
pageSize?: number;
|
|
3
|
+
tokenKey?: string;
|
|
4
|
+
itemsKey?: string;
|
|
5
|
+
}
|
|
6
|
+
export interface PaginatedResponse<T = unknown> {
|
|
7
|
+
[key: string]: unknown;
|
|
8
|
+
NextToken?: string;
|
|
9
|
+
ContinuationToken?: string;
|
|
10
|
+
Items?: T[];
|
|
11
|
+
Contents?: T[];
|
|
12
|
+
}
|
|
13
|
+
export declare function createPaginatedResponses<T>(items: T[], options?: PaginatorOptions): PaginatedResponse<T>[];
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";const e={red:t=>`\x1B[31m${t}\x1B[39m`,green:t=>`\x1B[32m${t}\x1B[39m`,yellow:t=>`\x1B[33m${t}\x1B[39m`,blue:t=>`\x1B[34m${t}\x1B[39m`,magenta:t=>`\x1B[35m${t}\x1B[39m`,cyan:t=>`\x1B[36m${t}\x1B[39m`,gray:t=>`\x1B[90m${t}\x1B[39m`,bold:t=>`\x1B[1m${t}\x1B[22m`},$=t=>{const c=t.calls();return Array.isArray(c)?c.filter(a=>Array.isArray(a)&&a.length>0):[]},f={toHaveReceivedCommand(t,c){const a=$(t),r=a.some(o=>o[0]instanceof c),m=c.name;return{pass:r,message:()=>{if(r)return`Expected AWS SDK mock not to have received command ${e.red(m)}`;const o=a.map(n=>n[0].constructor?.name??"Unknown");return o.length===0?`Expected AWS SDK mock to have received command ${e.red(m)}, but ${e.gray("no commands were received")}`:`Expected AWS SDK mock to have received command ${e.red(m)}, but received: ${e.yellow(o.join(", "))}`}}},toHaveReceivedCommandTimes(t,c,a){const r=$(t).filter(n=>n[0]instanceof c),m=r.length===a,o=c.name;return{pass:m,message:()=>m?`Expected AWS SDK mock not to have received command ${o} ${a} times`:`Expected AWS SDK mock to have received command ${o} ${a} times, but received ${r.length} times`}},toHaveReceivedCommandWith(t,c,a){const r=$(t).filter(n=>n[0]instanceof c),m=r.some(n=>this.equals(n[0].input,a)),o=c.name;return{pass:m,message:()=>{if(m){const s=e.red(o),u=e.cyan(JSON.stringify(a,void 0,2));return`Expected AWS SDK mock not to have received command ${s} with input:
|
|
2
|
+
${u}`}if(r.length===0){const s=e.red(o),u=e.cyan(JSON.stringify(a,void 0,2)),i=e.gray(`${o} was never called`);return`Expected AWS SDK mock to have received command ${s} with input:
|
|
3
|
+
${u}
|
|
4
|
+
|
|
5
|
+
But ${i}`}const n=r.map(s=>s[0].input),d=e.red(o),h=e.cyan(JSON.stringify(a,void 0,2)),l=e.gray("But received"),g=e.yellow(o),S=e.gray("with"),p=e.yellow(n.map(s=>JSON.stringify(s,void 0,2)).join(`
|
|
6
|
+
|
|
7
|
+
`));return`Expected AWS SDK mock to have received command ${d} with input:
|
|
8
|
+
${h}
|
|
9
|
+
|
|
10
|
+
${l} ${g} ${S}:
|
|
11
|
+
${p}`}}},toHaveReceivedNthCommandWith(t,c,a,r){const m=$(t),o=m[c-1],n=o?.[0],d=n?.input,h=!!o&&n instanceof a&&this.equals(d,r),l=a.name;return{pass:h,message:()=>{if(h){const i=e.magenta(c.toString()),v=e.red(l),y=e.cyan(JSON.stringify(r,void 0,2));return`Expected AWS SDK mock not to have received nth (${i}) command ${v} with input:
|
|
12
|
+
${y}`}if(!o){const i=e.magenta(c.toString()),v=e.gray(`only received ${m.length} call(s)`);return`Expected AWS SDK mock to have received at least ${i} call(s), but ${v}`}if(!(n instanceof a)){const i=n?.constructor?.name??typeof n,v=e.magenta(c.toString()),y=e.red(l),x=e.yellow(i);return`Expected AWS SDK mock nth (${v}) call to be ${y}, but received ${x}`}const g=e.magenta(c.toString()),S=e.red(l),p=e.cyan(JSON.stringify(r,void 0,2)),s=e.gray("But received"),u=e.yellow(JSON.stringify(d,void 0,2));return`Expected AWS SDK mock nth (${g}) command ${S} with input:
|
|
13
|
+
${p}
|
|
14
|
+
|
|
15
|
+
${s}:
|
|
16
|
+
${u}`}}},toHaveReceivedNoOtherCommands(t,c=[]){const r=$(t).filter(o=>{const n=o[0];return!c.some(d=>n instanceof d)}),m=r.length===0;return{pass:m,message:()=>{if(m)return`Expected AWS SDK mock to have received other commands besides ${e.green(c.map(n=>n.name).join(", "))}`;const o=r.map(n=>n[0].constructor?.name??"Unknown");return`Expected AWS SDK mock to have received ${e.gray("no other commands")}, but received: ${e.red(o.join(", "))}`}}}};exports.matchers=f;
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
const e = {
|
|
2
|
+
red: (t) => `\x1B[31m${t}\x1B[39m`,
|
|
3
|
+
green: (t) => `\x1B[32m${t}\x1B[39m`,
|
|
4
|
+
yellow: (t) => `\x1B[33m${t}\x1B[39m`,
|
|
5
|
+
blue: (t) => `\x1B[34m${t}\x1B[39m`,
|
|
6
|
+
magenta: (t) => `\x1B[35m${t}\x1B[39m`,
|
|
7
|
+
cyan: (t) => `\x1B[36m${t}\x1B[39m`,
|
|
8
|
+
gray: (t) => `\x1B[90m${t}\x1B[39m`,
|
|
9
|
+
bold: (t) => `\x1B[1m${t}\x1B[22m`
|
|
10
|
+
}, $ = (t) => {
|
|
11
|
+
const c = t.calls();
|
|
12
|
+
return Array.isArray(c) ? c.filter(
|
|
13
|
+
(a) => Array.isArray(a) && a.length > 0
|
|
14
|
+
) : [];
|
|
15
|
+
}, f = {
|
|
16
|
+
toHaveReceivedCommand(t, c) {
|
|
17
|
+
const a = $(t), r = a.some((o) => o[0] instanceof c), m = c.name;
|
|
18
|
+
return {
|
|
19
|
+
pass: r,
|
|
20
|
+
message: () => {
|
|
21
|
+
if (r)
|
|
22
|
+
return `Expected AWS SDK mock not to have received command ${e.red(m)}`;
|
|
23
|
+
const o = a.map((n) => n[0].constructor?.name ?? "Unknown");
|
|
24
|
+
return o.length === 0 ? `Expected AWS SDK mock to have received command ${e.red(m)}, but ${e.gray("no commands were received")}` : `Expected AWS SDK mock to have received command ${e.red(m)}, but received: ${e.yellow(o.join(", "))}`;
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
},
|
|
28
|
+
toHaveReceivedCommandTimes(t, c, a) {
|
|
29
|
+
const r = $(t).filter(
|
|
30
|
+
(n) => n[0] instanceof c
|
|
31
|
+
), m = r.length === a, o = c.name;
|
|
32
|
+
return {
|
|
33
|
+
pass: m,
|
|
34
|
+
message: () => m ? `Expected AWS SDK mock not to have received command ${o} ${a} times` : `Expected AWS SDK mock to have received command ${o} ${a} times, but received ${r.length} times`
|
|
35
|
+
};
|
|
36
|
+
},
|
|
37
|
+
toHaveReceivedCommandWith(t, c, a) {
|
|
38
|
+
const r = $(t).filter(
|
|
39
|
+
(n) => n[0] instanceof c
|
|
40
|
+
), m = r.some(
|
|
41
|
+
(n) => this.equals(n[0].input, a)
|
|
42
|
+
), o = c.name;
|
|
43
|
+
return {
|
|
44
|
+
pass: m,
|
|
45
|
+
message: () => {
|
|
46
|
+
if (m) {
|
|
47
|
+
const s = e.red(o), u = e.cyan(
|
|
48
|
+
JSON.stringify(a, void 0, 2)
|
|
49
|
+
);
|
|
50
|
+
return `Expected AWS SDK mock not to have received command ${s} with input:
|
|
51
|
+
${u}`;
|
|
52
|
+
}
|
|
53
|
+
if (r.length === 0) {
|
|
54
|
+
const s = e.red(o), u = e.cyan(
|
|
55
|
+
JSON.stringify(a, void 0, 2)
|
|
56
|
+
), i = e.gray(`${o} was never called`);
|
|
57
|
+
return `Expected AWS SDK mock to have received command ${s} with input:
|
|
58
|
+
${u}
|
|
59
|
+
|
|
60
|
+
But ${i}`;
|
|
61
|
+
}
|
|
62
|
+
const n = r.map(
|
|
63
|
+
(s) => s[0].input
|
|
64
|
+
), d = e.red(o), g = e.cyan(JSON.stringify(a, void 0, 2)), l = e.gray("But received"), h = e.yellow(o), p = e.gray("with"), S = e.yellow(
|
|
65
|
+
n.map((s) => JSON.stringify(s, void 0, 2)).join(`
|
|
66
|
+
|
|
67
|
+
`)
|
|
68
|
+
);
|
|
69
|
+
return `Expected AWS SDK mock to have received command ${d} with input:
|
|
70
|
+
${g}
|
|
71
|
+
|
|
72
|
+
${l} ${h} ${p}:
|
|
73
|
+
${S}`;
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
},
|
|
77
|
+
toHaveReceivedNthCommandWith(t, c, a, r) {
|
|
78
|
+
const m = $(t), o = m[c - 1], n = o?.[0], d = n?.input, g = !!o && n instanceof a && this.equals(d, r), l = a.name;
|
|
79
|
+
return {
|
|
80
|
+
pass: g,
|
|
81
|
+
message: () => {
|
|
82
|
+
if (g) {
|
|
83
|
+
const i = e.magenta(c.toString()), v = e.red(l), y = e.cyan(JSON.stringify(r, void 0, 2));
|
|
84
|
+
return `Expected AWS SDK mock not to have received nth (${i}) command ${v} with input:
|
|
85
|
+
${y}`;
|
|
86
|
+
}
|
|
87
|
+
if (!o) {
|
|
88
|
+
const i = e.magenta(c.toString()), v = e.gray(
|
|
89
|
+
`only received ${m.length} call(s)`
|
|
90
|
+
);
|
|
91
|
+
return `Expected AWS SDK mock to have received at least ${i} call(s), but ${v}`;
|
|
92
|
+
}
|
|
93
|
+
if (!(n instanceof a)) {
|
|
94
|
+
const i = n?.constructor?.name ?? typeof n, v = e.magenta(c.toString()), y = e.red(l), x = e.yellow(i);
|
|
95
|
+
return `Expected AWS SDK mock nth (${v}) call to be ${y}, but received ${x}`;
|
|
96
|
+
}
|
|
97
|
+
const h = e.magenta(c.toString()), p = e.red(l), S = e.cyan(JSON.stringify(r, void 0, 2)), s = e.gray("But received"), u = e.yellow(
|
|
98
|
+
JSON.stringify(d, void 0, 2)
|
|
99
|
+
);
|
|
100
|
+
return `Expected AWS SDK mock nth (${h}) command ${p} with input:
|
|
101
|
+
${S}
|
|
102
|
+
|
|
103
|
+
${s}:
|
|
104
|
+
${u}`;
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
},
|
|
108
|
+
toHaveReceivedNoOtherCommands(t, c = []) {
|
|
109
|
+
const r = $(t).filter((o) => {
|
|
110
|
+
const n = o[0];
|
|
111
|
+
return !c.some(
|
|
112
|
+
(d) => n instanceof d
|
|
113
|
+
);
|
|
114
|
+
}), m = r.length === 0;
|
|
115
|
+
return {
|
|
116
|
+
pass: m,
|
|
117
|
+
message: () => {
|
|
118
|
+
if (m)
|
|
119
|
+
return `Expected AWS SDK mock to have received other commands besides ${e.green(c.map((n) => n.name).join(", "))}`;
|
|
120
|
+
const o = r.map((n) => n[0].constructor?.name ?? "Unknown");
|
|
121
|
+
return `Expected AWS SDK mock to have received ${e.gray("no other commands")}, but received: ${e.red(o.join(", "))}`;
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
export {
|
|
127
|
+
f as m
|
|
128
|
+
};
|
package/package.json
CHANGED
package/vitest-setup.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";const e=require("vitest"),t=require("./matchers-
|
|
1
|
+
"use strict";const e=require("vitest"),t=require("./matchers-G36N2DNa.cjs");e.expect.extend(t.matchers);
|
package/vitest-setup.js
CHANGED
package/matchers-D1XEjFLq.cjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";const d={toHaveReceivedCommand(n,e){const t=n.calls().some(a=>a[0]instanceof e),s=e.name;return{pass:t,message:()=>t?`Expected AWS SDK mock not to have received command ${s}`:`Expected AWS SDK mock to have received command ${s}`}},toHaveReceivedCommandTimes(n,e,c){const t=n.calls().filter(o=>o[0]instanceof e),s=t.length===c,a=e.name;return{pass:s,message:()=>s?`Expected AWS SDK mock not to have received command ${a} ${c} times`:`Expected AWS SDK mock to have received command ${a} ${c} times, but received ${t.length} times`}},toHaveReceivedCommandWith(n,e,c){const s=n.calls().filter(o=>o[0]instanceof e).some(o=>this.equals(o[0].input,c)),a=e.name;return{pass:s,message:()=>s?`Expected AWS SDK mock not to have received command ${a} with ${JSON.stringify(c)}`:`Expected AWS SDK mock to have received command ${a} with ${JSON.stringify(c)}`}},toHaveReceivedNthCommandWith(n,e,c,t){const a=n.calls().filter(i=>i[0]instanceof c)[e-1],o=!!(a&&this.equals(a[0].input,t)),m=c.name;return{pass:o,message:()=>o?`Expected AWS SDK mock not to have received nth (${e}) command ${m} with ${JSON.stringify(t)}`:`Expected AWS SDK mock to have received nth (${e}) command ${m} with ${JSON.stringify(t)}`}}};exports.matchers=d;
|
package/matchers-DclpcT4f.js
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
const d = {
|
|
2
|
-
toHaveReceivedCommand(n, e) {
|
|
3
|
-
const t = n.calls().some((a) => a[0] instanceof e), o = e.name;
|
|
4
|
-
return {
|
|
5
|
-
pass: t,
|
|
6
|
-
message: () => t ? `Expected AWS SDK mock not to have received command ${o}` : `Expected AWS SDK mock to have received command ${o}`
|
|
7
|
-
};
|
|
8
|
-
},
|
|
9
|
-
toHaveReceivedCommandTimes(n, e, c) {
|
|
10
|
-
const t = n.calls().filter((s) => s[0] instanceof e), o = t.length === c, a = e.name;
|
|
11
|
-
return {
|
|
12
|
-
pass: o,
|
|
13
|
-
message: () => o ? `Expected AWS SDK mock not to have received command ${a} ${c} times` : `Expected AWS SDK mock to have received command ${a} ${c} times, but received ${t.length} times`
|
|
14
|
-
};
|
|
15
|
-
},
|
|
16
|
-
toHaveReceivedCommandWith(n, e, c) {
|
|
17
|
-
const o = n.calls().filter((s) => s[0] instanceof e).some((s) => this.equals(s[0].input, c)), a = e.name;
|
|
18
|
-
return {
|
|
19
|
-
pass: o,
|
|
20
|
-
message: () => o ? `Expected AWS SDK mock not to have received command ${a} with ${JSON.stringify(c)}` : `Expected AWS SDK mock to have received command ${a} with ${JSON.stringify(c)}`
|
|
21
|
-
};
|
|
22
|
-
},
|
|
23
|
-
toHaveReceivedNthCommandWith(n, e, c, t) {
|
|
24
|
-
const a = n.calls().filter((i) => i[0] instanceof c)[e - 1], s = !!(a && this.equals(a[0].input, t)), m = c.name;
|
|
25
|
-
return {
|
|
26
|
-
pass: s,
|
|
27
|
-
message: () => s ? `Expected AWS SDK mock not to have received nth (${e}) command ${m} with ${JSON.stringify(t)}` : `Expected AWS SDK mock to have received nth (${e}) command ${m} with ${JSON.stringify(t)}`
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
};
|
|
31
|
-
export {
|
|
32
|
-
d as m
|
|
33
|
-
};
|