aws-sdk-vitest-mock 0.3.1 → 0.5.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 +279 -92
- package/index.cjs +18 -1
- package/index.d.ts +46 -1
- package/index.js +328 -221
- package/lib/matchers.d.ts +141 -0
- package/lib/mock-client.d.ts +436 -19
- package/lib/utils/paginator-helpers.d.ts +85 -0
- package/{matchers-C6AtmwWz.js → matchers-ClGOsQx8.js} +99 -0
- package/{matchers-Rq18z2C7.cjs → matchers-Dkkl4vtx.cjs} +1 -1
- package/package.json +11 -2
- package/vitest-setup.cjs +1 -1
- package/vitest-setup.js +1 -1
|
@@ -1,6 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration options for paginated responses.
|
|
3
|
+
*
|
|
4
|
+
* Tokens are automatically set to the last item of each page, which works for both
|
|
5
|
+
* DynamoDB-style pagination (object tokens) and S3-style pagination (object tokens).
|
|
6
|
+
*
|
|
7
|
+
* @example DynamoDB configuration
|
|
8
|
+
* ```typescript
|
|
9
|
+
* {
|
|
10
|
+
* pageSize: 10,
|
|
11
|
+
* tokenKey: "LastEvaluatedKey", // DynamoDB response key
|
|
12
|
+
* inputTokenKey: "ExclusiveStartKey", // DynamoDB request key
|
|
13
|
+
* itemsKey: "Items"
|
|
14
|
+
* }
|
|
15
|
+
* ```
|
|
16
|
+
*
|
|
17
|
+
* @example S3 configuration
|
|
18
|
+
* ```typescript
|
|
19
|
+
* {
|
|
20
|
+
* pageSize: 50,
|
|
21
|
+
* tokenKey: "NextContinuationToken", // S3 response key
|
|
22
|
+
* inputTokenKey: "ContinuationToken", // S3 request key
|
|
23
|
+
* itemsKey: "Contents"
|
|
24
|
+
* }
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
1
27
|
export interface PaginatorOptions {
|
|
28
|
+
/**
|
|
29
|
+
* Number of items per page.
|
|
30
|
+
* @default 10
|
|
31
|
+
*/
|
|
2
32
|
pageSize?: number;
|
|
33
|
+
/**
|
|
34
|
+
* Property name for the pagination token in the response.
|
|
35
|
+
* The token will be set to the last item of the page.
|
|
36
|
+
*
|
|
37
|
+
* Common values:
|
|
38
|
+
* - DynamoDB: "LastEvaluatedKey"
|
|
39
|
+
* - S3: "NextContinuationToken"
|
|
40
|
+
* - Generic: "NextToken"
|
|
41
|
+
*
|
|
42
|
+
* @default "NextToken"
|
|
43
|
+
*/
|
|
3
44
|
tokenKey?: string;
|
|
45
|
+
/**
|
|
46
|
+
* Property name for the pagination token in the request.
|
|
47
|
+
* If not specified, uses the same value as tokenKey.
|
|
48
|
+
*
|
|
49
|
+
* Use this when the service uses different names for input and output tokens.
|
|
50
|
+
*
|
|
51
|
+
* Common values:
|
|
52
|
+
* - DynamoDB: "ExclusiveStartKey" (when tokenKey is "LastEvaluatedKey")
|
|
53
|
+
* - S3: "ContinuationToken" (when tokenKey is "NextContinuationToken")
|
|
54
|
+
*
|
|
55
|
+
* @default Same as tokenKey
|
|
56
|
+
*/
|
|
57
|
+
inputTokenKey?: string;
|
|
58
|
+
/**
|
|
59
|
+
* Property name for the items array in the response.
|
|
60
|
+
*
|
|
61
|
+
* Common values:
|
|
62
|
+
* - DynamoDB: "Items"
|
|
63
|
+
* - S3: "Contents"
|
|
64
|
+
*
|
|
65
|
+
* @default "Items"
|
|
66
|
+
*/
|
|
4
67
|
itemsKey?: string;
|
|
5
68
|
}
|
|
6
69
|
export interface PaginatedResponse<T = unknown> {
|
|
@@ -10,4 +73,26 @@ export interface PaginatedResponse<T = unknown> {
|
|
|
10
73
|
Items?: T[];
|
|
11
74
|
Contents?: T[];
|
|
12
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* Creates paginated responses from an array of items.
|
|
78
|
+
*
|
|
79
|
+
* Each page's token is set to the last item of that page, enabling proper
|
|
80
|
+
* pagination for services like DynamoDB (where tokens are objects) and S3.
|
|
81
|
+
*
|
|
82
|
+
* @param items - Array of items to paginate
|
|
83
|
+
* @param options - Pagination configuration options
|
|
84
|
+
* @returns Array of paginated responses, each containing a subset of items
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* ```typescript
|
|
88
|
+
* const items = [1, 2, 3, 4, 5];
|
|
89
|
+
* const responses = createPaginatedResponses(items, { pageSize: 2 });
|
|
90
|
+
* // Returns:
|
|
91
|
+
* // [
|
|
92
|
+
* // { Items: [1, 2], NextToken: 2 },
|
|
93
|
+
* // { Items: [3, 4], NextToken: 4 },
|
|
94
|
+
* // { Items: [5] }
|
|
95
|
+
* // ]
|
|
96
|
+
* ```
|
|
97
|
+
*/
|
|
13
98
|
export declare function createPaginatedResponses<T>(items: T[], options?: PaginatorOptions): PaginatedResponse<T>[];
|
|
@@ -13,6 +13,23 @@ const e = {
|
|
|
13
13
|
(a) => Array.isArray(a) && a.length > 0
|
|
14
14
|
) : [];
|
|
15
15
|
}, f = {
|
|
16
|
+
/**
|
|
17
|
+
* Assert that a command was received at least once.
|
|
18
|
+
*
|
|
19
|
+
* @param received - The AWS client stub
|
|
20
|
+
* @param command - The command constructor to check for
|
|
21
|
+
* @returns Matcher result
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```typescript
|
|
25
|
+
* const s3Mock = mockClient(S3Client);
|
|
26
|
+
* const client = new S3Client({});
|
|
27
|
+
*
|
|
28
|
+
* await client.send(new GetObjectCommand({ Bucket: 'test', Key: 'file.txt' }));
|
|
29
|
+
*
|
|
30
|
+
* expect(s3Mock).toHaveReceivedCommand(GetObjectCommand);
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
16
33
|
toHaveReceivedCommand(t, c) {
|
|
17
34
|
const a = $(t), r = a.some((o) => o[0] instanceof c), m = c.name;
|
|
18
35
|
return {
|
|
@@ -25,6 +42,25 @@ const e = {
|
|
|
25
42
|
}
|
|
26
43
|
};
|
|
27
44
|
},
|
|
45
|
+
/**
|
|
46
|
+
* Assert that a command was received exactly N times.
|
|
47
|
+
*
|
|
48
|
+
* @param received - The AWS client stub
|
|
49
|
+
* @param command - The command constructor to check for
|
|
50
|
+
* @param times - The exact number of times the command should have been received
|
|
51
|
+
* @returns Matcher result
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* ```typescript
|
|
55
|
+
* const s3Mock = mockClient(S3Client);
|
|
56
|
+
* const client = new S3Client({});
|
|
57
|
+
*
|
|
58
|
+
* await client.send(new GetObjectCommand({ Bucket: 'test', Key: 'file1.txt' }));
|
|
59
|
+
* await client.send(new GetObjectCommand({ Bucket: 'test', Key: 'file2.txt' }));
|
|
60
|
+
*
|
|
61
|
+
* expect(s3Mock).toHaveReceivedCommandTimes(GetObjectCommand, 2);
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
28
64
|
toHaveReceivedCommandTimes(t, c, a) {
|
|
29
65
|
const r = $(t).filter(
|
|
30
66
|
(n) => n[0] instanceof c
|
|
@@ -34,6 +70,27 @@ const e = {
|
|
|
34
70
|
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
71
|
};
|
|
36
72
|
},
|
|
73
|
+
/**
|
|
74
|
+
* Assert that a command was received with specific input parameters.
|
|
75
|
+
*
|
|
76
|
+
* @param received - The AWS client stub
|
|
77
|
+
* @param command - The command constructor to check for
|
|
78
|
+
* @param input - The expected input parameters
|
|
79
|
+
* @returns Matcher result
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* ```typescript
|
|
83
|
+
* const s3Mock = mockClient(S3Client);
|
|
84
|
+
* const client = new S3Client({});
|
|
85
|
+
*
|
|
86
|
+
* await client.send(new GetObjectCommand({ Bucket: 'test', Key: 'file.txt' }));
|
|
87
|
+
*
|
|
88
|
+
* expect(s3Mock).toHaveReceivedCommandWith(GetObjectCommand, {
|
|
89
|
+
* Bucket: 'test',
|
|
90
|
+
* Key: 'file.txt'
|
|
91
|
+
* });
|
|
92
|
+
* ```
|
|
93
|
+
*/
|
|
37
94
|
toHaveReceivedCommandWith(t, c, a) {
|
|
38
95
|
const r = $(t).filter(
|
|
39
96
|
(n) => n[0] instanceof c
|
|
@@ -70,6 +127,29 @@ ${S}`;
|
|
|
70
127
|
}
|
|
71
128
|
};
|
|
72
129
|
},
|
|
130
|
+
/**
|
|
131
|
+
* Assert that the Nth command call was a specific command with specific input.
|
|
132
|
+
*
|
|
133
|
+
* @param received - The AWS client stub
|
|
134
|
+
* @param n - The call number (1-indexed)
|
|
135
|
+
* @param command - The command constructor to check for
|
|
136
|
+
* @param input - The expected input parameters
|
|
137
|
+
* @returns Matcher result
|
|
138
|
+
*
|
|
139
|
+
* @example
|
|
140
|
+
* ```typescript
|
|
141
|
+
* const s3Mock = mockClient(S3Client);
|
|
142
|
+
* const client = new S3Client({});
|
|
143
|
+
*
|
|
144
|
+
* await client.send(new PutObjectCommand({ Bucket: 'test', Key: 'file1.txt' }));
|
|
145
|
+
* await client.send(new GetObjectCommand({ Bucket: 'test', Key: 'file2.txt' }));
|
|
146
|
+
*
|
|
147
|
+
* expect(s3Mock).toHaveReceivedNthCommandWith(2, GetObjectCommand, {
|
|
148
|
+
* Bucket: 'test',
|
|
149
|
+
* Key: 'file2.txt'
|
|
150
|
+
* });
|
|
151
|
+
* ```
|
|
152
|
+
*/
|
|
73
153
|
toHaveReceivedNthCommandWith(t, c, a, r) {
|
|
74
154
|
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;
|
|
75
155
|
return {
|
|
@@ -101,6 +181,24 @@ ${u}`;
|
|
|
101
181
|
}
|
|
102
182
|
};
|
|
103
183
|
},
|
|
184
|
+
/**
|
|
185
|
+
* Assert that no commands other than the expected ones were received.
|
|
186
|
+
*
|
|
187
|
+
* @param received - The AWS client stub
|
|
188
|
+
* @param expectedCommands - Array of command constructors that are allowed
|
|
189
|
+
* @returns Matcher result
|
|
190
|
+
*
|
|
191
|
+
* @example
|
|
192
|
+
* ```typescript
|
|
193
|
+
* const s3Mock = mockClient(S3Client);
|
|
194
|
+
* const client = new S3Client({});
|
|
195
|
+
*
|
|
196
|
+
* await client.send(new GetObjectCommand({ Bucket: 'test', Key: 'file.txt' }));
|
|
197
|
+
* await client.send(new GetObjectCommand({ Bucket: 'test', Key: 'other.txt' }));
|
|
198
|
+
*
|
|
199
|
+
* expect(s3Mock).toHaveReceivedNoOtherCommands([GetObjectCommand]);
|
|
200
|
+
* ```
|
|
201
|
+
*/
|
|
104
202
|
toHaveReceivedNoOtherCommands(t, c = []) {
|
|
105
203
|
const r = $(t).filter((o) => {
|
|
106
204
|
const n = o[0];
|
|
@@ -120,5 +218,6 @@ ${u}`;
|
|
|
120
218
|
}
|
|
121
219
|
};
|
|
122
220
|
export {
|
|
221
|
+
e as c,
|
|
123
222
|
f as m
|
|
124
223
|
};
|
|
@@ -13,4 +13,4 @@ ${y}`}if(!o){const i=e.magenta(c.toString()),v=e.gray(`only received ${m.length}
|
|
|
13
13
|
${p}
|
|
14
14
|
|
|
15
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;
|
|
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.colors=e;exports.matchers=f;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aws-sdk-vitest-mock",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./index.cjs",
|
|
6
6
|
"module": "./index.js",
|
|
@@ -24,8 +24,16 @@
|
|
|
24
24
|
"license": "MIT",
|
|
25
25
|
"author": "sudokar",
|
|
26
26
|
"scripts": {
|
|
27
|
+
"ci": "bun install --frozen-lockfile",
|
|
27
28
|
"prepare": "husky",
|
|
28
|
-
"prepublishOnly": "HUSKY=0"
|
|
29
|
+
"prepublishOnly": "HUSKY=0",
|
|
30
|
+
"lint": "nx lint",
|
|
31
|
+
"lint:fix": "nx lint --fix",
|
|
32
|
+
"test": "nx test",
|
|
33
|
+
"build": "nx build",
|
|
34
|
+
"docs": "typedoc && touch docs/.nojekyll",
|
|
35
|
+
"docs:watch": "typedoc --watch",
|
|
36
|
+
"docs:serve": "bun run docs && bunx http-server docs -o"
|
|
29
37
|
},
|
|
30
38
|
"nx": {
|
|
31
39
|
"includedScripts": []
|
|
@@ -61,6 +69,7 @@
|
|
|
61
69
|
"lint-staged": "16.2.7",
|
|
62
70
|
"nx": "22.2.2",
|
|
63
71
|
"prettier": "3.7.4",
|
|
72
|
+
"typedoc": "0.28.15",
|
|
64
73
|
"typescript": "5.9.3",
|
|
65
74
|
"typescript-eslint": "8.49.0",
|
|
66
75
|
"vite": "7.2.7",
|
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-Dkkl4vtx.cjs");e.expect.extend(t.matchers);
|
package/vitest-setup.js
CHANGED