aws-sdk-vitest-mock 0.5.0 → 0.6.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 +48 -2
- package/index.cjs +9 -9
- package/index.d.ts +1 -1
- package/index.js +234 -227
- package/lib/mock-client.d.ts +21 -0
- package/lib/utils/debug-logger.d.ts +5 -3
- package/lib/utils/file-helpers.d.ts +1 -1
- package/lib/utils/paginator-helpers.d.ts +1 -1
- package/lib/utils/stream-helpers.d.ts +1 -1
- package/{matchers-Dkkl4vtx.cjs → matchers-CNhdB_9q.cjs} +1 -1
- package/{matchers-ClGOsQx8.js → matchers-DmTtFk31.js} +2 -2
- package/package.json +1 -1
- package/vitest-setup.cjs +1 -1
- package/vitest-setup.js +1 -1
package/README.md
CHANGED
|
@@ -564,6 +564,46 @@ s3Mock.restore();
|
|
|
564
564
|
s3Mock.disableDebug();
|
|
565
565
|
```
|
|
566
566
|
|
|
567
|
+
#### Global Debug Configuration
|
|
568
|
+
|
|
569
|
+
Enable debug logging for all mocks globally, with the ability to override at the individual mock level:
|
|
570
|
+
|
|
571
|
+
```typescript
|
|
572
|
+
import { setGlobalDebug, mockClient } from "aws-sdk-vitest-mock";
|
|
573
|
+
import { S3Client, GetObjectCommand } from "@aws-sdk/client-s3";
|
|
574
|
+
import { DynamoDBClient, GetItemCommand } from "@aws-sdk/client-dynamodb";
|
|
575
|
+
|
|
576
|
+
// Enable debug for all mocks
|
|
577
|
+
setGlobalDebug(true);
|
|
578
|
+
|
|
579
|
+
// All mocks will inherit the global debug setting
|
|
580
|
+
const s3Mock = mockClient(S3Client);
|
|
581
|
+
const dynamoMock = mockClient(DynamoDBClient);
|
|
582
|
+
|
|
583
|
+
// Both mocks will log debug information
|
|
584
|
+
s3Mock.on(GetObjectCommand).resolves({ Body: "data" });
|
|
585
|
+
dynamoMock.on(GetItemCommand).resolves({ Item: { id: { S: "1" } } });
|
|
586
|
+
|
|
587
|
+
// Override global setting for a specific mock
|
|
588
|
+
s3Mock.disableDebug(); // This mock won't log, but dynamoMock still will
|
|
589
|
+
|
|
590
|
+
// Disable global debug
|
|
591
|
+
setGlobalDebug(false);
|
|
592
|
+
```
|
|
593
|
+
|
|
594
|
+
**Debug Priority (highest to lowest):**
|
|
595
|
+
|
|
596
|
+
1. Individual mock's `enableDebug()` or `disableDebug()` call (explicit override)
|
|
597
|
+
2. Global debug setting via `setGlobalDebug()`
|
|
598
|
+
3. Default: disabled
|
|
599
|
+
|
|
600
|
+
**Key behaviors:**
|
|
601
|
+
|
|
602
|
+
- When global debug is enabled, all new and existing mocks will log unless explicitly disabled
|
|
603
|
+
- Individual mock settings always take priority over global settings
|
|
604
|
+
- `reset()` preserves individual debug settings
|
|
605
|
+
- Global debug can be changed at any time and affects all mocks without explicit settings
|
|
606
|
+
|
|
567
607
|
Debug mode provides comprehensive logging for:
|
|
568
608
|
|
|
569
609
|
**Mock Configuration:**
|
|
@@ -650,6 +690,8 @@ test("should call DynamoDB", async () => {
|
|
|
650
690
|
|
|
651
691
|
## 📚 API Reference
|
|
652
692
|
|
|
693
|
+
> TypeScript documentation for this library can be found at [here](https://sudokar.github.io/aws-sdk-vitest-mock/)
|
|
694
|
+
|
|
653
695
|
### `mockClient<TClient>(ClientConstructor)`
|
|
654
696
|
|
|
655
697
|
Creates a mock for an AWS SDK client constructor.
|
|
@@ -662,14 +704,18 @@ Mocks an existing AWS SDK client instance.
|
|
|
662
704
|
|
|
663
705
|
**Returns:** `AwsClientStub<TClient>`
|
|
664
706
|
|
|
707
|
+
### Global Debug Functions
|
|
708
|
+
|
|
709
|
+
- `setGlobalDebug(enabled: boolean)` - Enable or disable debug logging globally for all mocks
|
|
710
|
+
|
|
665
711
|
### `AwsClientStub` Methods
|
|
666
712
|
|
|
667
713
|
- `on(Command, matcher?, options?)` - Configure mock for a command
|
|
668
714
|
- `reset()` - Clear call history while preserving mock configurations
|
|
669
715
|
- `restore()` - Restore original client behavior
|
|
670
716
|
- `calls()` - Get call history
|
|
671
|
-
- `enableDebug()` - Enable debug logging for troubleshooting
|
|
672
|
-
- `disableDebug()` - Disable debug logging
|
|
717
|
+
- `enableDebug()` - Enable debug logging for troubleshooting (overrides global setting)
|
|
718
|
+
- `disableDebug()` - Disable debug logging (overrides global setting)
|
|
673
719
|
|
|
674
720
|
### `AwsCommandStub` Methods (Chainable)
|
|
675
721
|
|
package/index.cjs
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
2
|
-
${
|
|
3
|
-
`),
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const j=require("vitest"),D=require("./matchers-CNhdB_9q.cjs"),F=require("node:fs"),I=require("node:path"),M=require("node:stream");class d extends Error{constructor(t,o,i,n){super(t),this.name="AwsError",this.code=o,this.statusCode=i,this.retryable=n}}const T=e=>new d(e?`The specified key does not exist. Key: ${e}`:"The specified key does not exist.","NoSuchKey",404,!1),K=e=>new d(e?`The specified bucket does not exist. Bucket: ${e}`:"The specified bucket does not exist.","NoSuchBucket",404,!1),A=e=>new d(e?`Access Denied for resource: ${e}`:"Access Denied","AccessDenied",403,!1),B=e=>new d(e?`Requested resource not found: ${e}`:"Requested resource not found","ResourceNotFoundException",400,!1),q=()=>new d("The conditional request failed","ConditionalCheckFailedException",400,!1),J=()=>new d("Rate exceeded","Throttling",400,!0),_=()=>new d("We encountered an internal error. Please try again.","InternalServerError",500,!0),z=e=>{try{return JSON.stringify(e,void 0,2)}catch{return typeof e=="object"&&e!==null?"[Complex Object]":typeof e=="string"?e:typeof e=="number"||typeof e=="boolean"?String(e):"[Non-serializable value]"}},v=(e,t)=>{const o=D.colors.magenta("aws-sdk-vitest-mock(debug):");if(t===void 0)console.log(`${o} ${e}`);else{const i=z(t);console.log(`${o} ${e}
|
|
2
|
+
${i}`)}},L=(e=!1)=>({enabled:e,explicitlySet:!1,log(t,o){this.enabled&&v(t,o)},logDirect(t,o){v(t,o)}}),w=e=>{e.enabled=!0,e.explicitlySet=!0},$=e=>{e.enabled=!1,e.explicitlySet=!0},V=e=>{const t=I.resolve(e),o=F.readFileSync(t,"utf8");return e.endsWith(".json")?JSON.parse(o):o},G=(e,t={})=>{const{pageSize:o=10,tokenKey:i="NextToken",itemsKey:n="Items"}=t;if(e.length===0)return[{[n]:[]}];const s=[];for(let r=0;r<e.length;r+=o){const c=e.slice(r,r+o),l=r+o<e.length,u={[n]:c};if(l){const a=u,g=c[c.length-1];a[i]=g}s.push(u)}return s},U=()=>typeof process<"u"&&process.versions?.node?"node":typeof process<"u"&&process.versions?.bun?"bun":"browser",H=e=>{const t=typeof e=="string"?Buffer.from(e,"utf8"):Buffer.from(e);let o=!1;return new M.Readable({read(){o||(this.push(t),this.push(null),o=!0)}})},Q=e=>{let t;return typeof e=="string"?t=new TextEncoder().encode(e):e instanceof Buffer?t=new Uint8Array(e):t=e,new ReadableStream({start(o){o.enqueue(t),o.close()}})},S=e=>{const t=U();return t==="node"||t==="bun"?H(e):Q(e)};let N=!1;function X(e){N=e}function h(e){return e.explicitlySet?e.enabled:N}function C(e,t){return Object.keys(t).every(o=>{const i=t[o],n=e[o];return i&&typeof i=="object"&&!Array.isArray(i)?typeof n!="object"||n===null?!1:C(n,i):n===i})}function E(e,t){if(e===t)return!0;if(typeof e!="object"||e===null||typeof t!="object"||t===null)return e===t;const o=Object.keys(e),i=Object.keys(t);return o.length!==i.length?!1:i.every(n=>{if(!Object.prototype.hasOwnProperty.call(e,n))return!1;const s=e,r=t,c=s[n],l=r[n];return typeof c=="object"&&c!==null&&typeof l=="object"&&l!==null?E(c,l):c===l})}function Y(e,t,o){const i=t.map((s,r)=>{const c=s.matcher?JSON.stringify(s.matcher,void 0,2):"any input",l=s.strict?" (strict mode)":"";return` Mock #${r+1}: ${c}${l}`}).join(`
|
|
3
|
+
`),n=JSON.stringify(o,void 0,2);return new Error(`No matching mock found for ${e}.
|
|
4
4
|
|
|
5
|
-
Found ${
|
|
5
|
+
Found ${t.length} mock(s) but none matched the input.
|
|
6
6
|
|
|
7
7
|
Configured mocks:
|
|
8
|
-
${
|
|
8
|
+
${i}
|
|
9
9
|
|
|
10
10
|
Received input:
|
|
11
|
-
${
|
|
11
|
+
${n}
|
|
12
12
|
|
|
13
|
-
Tip: Enable debug mode with enableDebug() for detailed matching information.`)}
|
|
13
|
+
Tip: Enable debug mode with enableDebug() for detailed matching information.`)}function Z(e,t){const o=JSON.stringify(t,void 0,2);return new Error(`No mock configured for command: ${e}.
|
|
14
14
|
|
|
15
15
|
Received input:
|
|
16
|
-
${
|
|
16
|
+
${o}
|
|
17
17
|
|
|
18
|
-
Did you forget to call mockClient.on(${t.constructor.name})
|
|
18
|
+
Did you forget to call mockClient.on(${e})?`)}function ee(e,t){return e.findIndex(o=>o.strict?o.matcher&&E(t,o.matcher):!o.matcher||C(t,o.matcher))}function x(e){return async function(t){const o=()=>this,i=h(e.debugLogger),n=t.constructor.name;i&&e.debugLogger.logDirect(`Received command: ${n}`,t.input);const s=e.map.get(t.constructor);if(!s)throw i&&e.debugLogger.logDirect(`No mocks configured for ${n}`),Z(n,t.input);i&&e.debugLogger.logDirect(`Found ${s.length} mock(s) for ${n}`);const r=ee(s,t.input);if(r===-1)throw i&&e.debugLogger.logDirect(`No matching mock found for ${n}`,t.input),Y(n,s,t.input);const c=s[r];if(!c)throw new Error(`Mock at index ${r} not found`);return i&&e.debugLogger.logDirect(`Using mock at index ${r} for ${n}`),c.once&&(s.splice(r,1),i&&e.debugLogger.logDirect(`Removed one-time mock for ${n}`)),c.handler(t.input,o())}}function R(e,t,o,i={}){const n=(r,c,l)=>{const u={matcher:o,handler:r,once:c,strict:!!i.strict},a=e.map.get(t)??[],g=h(e.debugLogger);if(c){const f=a.findIndex(p=>!p.once);f===-1?a.push(u):a.splice(f,0,u),e.map.set(t,a),g&&e.debugLogger.logDirect(`Configured ${l}Once for ${t.name}`,o?{matcher:o,strict:!!i.strict}:void 0)}else{const f=a.filter(p=>p.once||JSON.stringify(p.matcher)!==JSON.stringify(o));f.push(u),e.map.set(t,f),g&&e.debugLogger.logDirect(`Configured ${l} for ${t.name}`,o?{matcher:o,strict:!!i.strict}:void 0)}},s={resolves(r){return n(()=>Promise.resolve(r),!1,"resolves"),s},rejects(r){return n(()=>{const c=typeof r=="string"?new Error(r):r;return Promise.reject(c)},!1,"rejects"),s},callsFake(r){return n(r,!1,"callsFake"),s},resolvesOnce(r){return n(()=>Promise.resolve(r),!0,"resolves"),s},rejectsOnce(r){return n(()=>{const c=typeof r=="string"?new Error(r):r;return Promise.reject(c)},!0,"rejects"),s},callsFakeOnce(r){return n(r,!0,"callsFake"),s},resolvesStream(r){return n(()=>Promise.resolve({Body:S(r)}),!1,"resolvesStream"),s},resolvesStreamOnce(r){return n(()=>Promise.resolve({Body:S(r)}),!0,"resolvesStream"),s},resolvesWithDelay(r,c){const l=u=>{setTimeout(()=>u(r),c)};return n(()=>new Promise(l),!1,"resolvesWithDelay"),s},rejectsWithDelay(r,c){const l=typeof r=="string"?new Error(r):r,u=(a,g)=>{setTimeout(()=>g(l),c)};return n(()=>new Promise(u),!1,"rejectsWithDelay"),s},rejectsWithNoSuchKey(r){return n(()=>Promise.reject(T(r)),!1,"rejectsWithNoSuchKey"),s},rejectsWithNoSuchBucket(r){return n(()=>Promise.reject(K(r)),!1,"rejectsWithNoSuchBucket"),s},rejectsWithAccessDenied(r){return n(()=>Promise.reject(A(r)),!1,"rejectsWithAccessDenied"),s},rejectsWithResourceNotFound(r){return n(()=>Promise.reject(B(r)),!1,"rejectsWithResourceNotFound"),s},rejectsWithConditionalCheckFailed(){return n(()=>Promise.reject(q()),!1,"rejectsWithConditionalCheckFailed"),s},rejectsWithThrottling(){return n(()=>Promise.reject(J()),!1,"rejectsWithThrottling"),s},rejectsWithInternalServerError(){return n(()=>Promise.reject(_()),!1,"rejectsWithInternalServerError"),s},resolvesPaginated(r,c={}){const l=G(r,c);let u=0;return e.debugLogger.log(`Configured resolvesPaginated for ${t.name}`,{pageSize:c.pageSize,itemsCount:r.length}),n(a=>{const g=c.tokenKey||"NextToken",f=c.inputTokenKey||g,m=a[f];if(m!=null){const W=c.itemsKey||"Items";let k=0;for(const P of l){const b=P[W];if(b&&b.length>0){const O=b[b.length-1];if(JSON.stringify(O)===JSON.stringify(m)){u=k+1;break}}k++}}else u=0;const y=l[u]||l[l.length-1]||l[0];if(!y)throw new Error("No paginated responses available");return u=Math.min(u+1,l.length-1),Promise.resolve(y)},!1,"resolvesPaginated"),s},resolvesFromFile(r){return e.debugLogger.log(`Configured resolvesFromFile for ${t.name}`,{filePath:r}),n(()=>{const c=V(r);return Promise.resolve(c)},!1,"resolvesFromFile"),s}};return s}const te=e=>{const t={map:new WeakMap,debugLogger:L()},o=e.prototype,i=j.vi.spyOn(o,"send").mockImplementation(x(t));return{client:void 0,on:(s,r,c)=>R(t,s,r,c),reset:()=>{h(t.debugLogger)&&t.debugLogger.logDirect("Clearing call history (mocks preserved)"),i.mockClear()},restore:()=>{h(t.debugLogger)&&t.debugLogger.logDirect("Restoring original client behavior and clearing all mocks"),i.mockRestore(),t.map=new WeakMap},calls:()=>i.mock.calls.map(s=>s[0]),__rawCalls:()=>i.mock.calls,enableDebug:()=>{w(t.debugLogger)},disableDebug:()=>{$(t.debugLogger)}}},re=e=>{const t={map:new WeakMap,debugLogger:L()},o=j.vi.spyOn(e,"send").mockImplementation(x(t));return{client:e,on:(n,s,r)=>R(t,n,s,r),reset:()=>{h(t.debugLogger)&&t.debugLogger.logDirect("Clearing call history (mocks preserved) for client instance"),o.mockClear()},restore:()=>{h(t.debugLogger)&&t.debugLogger.logDirect("Restoring original client behavior and clearing all mocks for client instance"),o.mockRestore(),t.map=new WeakMap},calls:()=>o.mock.calls.map(n=>n[0]),__rawCalls:()=>o.mock.calls,enableDebug:()=>{w(t.debugLogger)},disableDebug:()=>{$(t.debugLogger)}}};exports.matchers=D.matchers;exports.mockClient=te;exports.mockClientInstance=re;exports.setGlobalDebug=X;
|
package/index.d.ts
CHANGED
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
* Core Functions for mocking AWS SDK clients
|
|
30
30
|
* @category Core Functions
|
|
31
31
|
*/
|
|
32
|
-
export { mockClient, mockClientInstance } from './lib/mock-client.js';
|
|
32
|
+
export { mockClient, mockClientInstance, setGlobalDebug, } from './lib/mock-client.js';
|
|
33
33
|
/**
|
|
34
34
|
* Command stub interface for configuring mock behaviors
|
|
35
35
|
* @category Command Stub
|
package/index.js
CHANGED
|
@@ -1,233 +1,237 @@
|
|
|
1
|
-
import { vi as
|
|
2
|
-
import { c as
|
|
3
|
-
import { m as
|
|
4
|
-
import { readFileSync as
|
|
5
|
-
import
|
|
6
|
-
import { Readable as
|
|
7
|
-
class
|
|
8
|
-
constructor(t,
|
|
9
|
-
super(t), this.name = "AwsError", this.code =
|
|
1
|
+
import { vi as j } from "vitest";
|
|
2
|
+
import { c as F } from "./matchers-DmTtFk31.js";
|
|
3
|
+
import { m as ge } from "./matchers-DmTtFk31.js";
|
|
4
|
+
import { readFileSync as O } from "node:fs";
|
|
5
|
+
import I from "node:path";
|
|
6
|
+
import { Readable as M } from "node:stream";
|
|
7
|
+
class d extends Error {
|
|
8
|
+
constructor(t, o, i, n) {
|
|
9
|
+
super(t), this.name = "AwsError", this.code = o, this.statusCode = i, this.retryable = n;
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
12
|
+
const T = (e) => new d(
|
|
13
|
+
e ? `The specified key does not exist. Key: ${e}` : "The specified key does not exist.",
|
|
14
|
+
"NoSuchKey",
|
|
15
|
+
404,
|
|
16
|
+
!1
|
|
17
|
+
), K = (e) => new d(
|
|
18
|
+
e ? `The specified bucket does not exist. Bucket: ${e}` : "The specified bucket does not exist.",
|
|
19
|
+
"NoSuchBucket",
|
|
20
|
+
404,
|
|
21
|
+
!1
|
|
22
|
+
), A = (e) => new d(
|
|
23
|
+
e ? `Access Denied for resource: ${e}` : "Access Denied",
|
|
24
|
+
"AccessDenied",
|
|
25
|
+
403,
|
|
26
|
+
!1
|
|
27
|
+
), B = (e) => new d(
|
|
28
|
+
e ? `Requested resource not found: ${e}` : "Requested resource not found",
|
|
29
|
+
"ResourceNotFoundException",
|
|
30
|
+
400,
|
|
31
|
+
!1
|
|
32
|
+
), J = () => new d(
|
|
25
33
|
"The conditional request failed",
|
|
26
34
|
"ConditionalCheckFailedException",
|
|
27
35
|
400,
|
|
28
36
|
!1
|
|
29
|
-
),
|
|
37
|
+
), _ = () => new d("Rate exceeded", "Throttling", 400, !0), q = () => new d(
|
|
30
38
|
"We encountered an internal error. Please try again.",
|
|
31
39
|
"InternalServerError",
|
|
32
40
|
500,
|
|
33
41
|
!0
|
|
34
|
-
)
|
|
35
|
-
function B(e) {
|
|
42
|
+
), z = (e) => {
|
|
36
43
|
try {
|
|
37
44
|
return JSON.stringify(e, void 0, 2);
|
|
38
45
|
} catch {
|
|
39
46
|
return typeof e == "object" && e !== null ? "[Complex Object]" : typeof e == "string" ? e : typeof e == "number" || typeof e == "boolean" ? String(e) : "[Non-serializable value]";
|
|
40
47
|
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
e.enabled = !0;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
e.
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const t = F.resolve(e), n = P(t, "utf8");
|
|
69
|
-
return e.endsWith(".json") ? JSON.parse(n) : n;
|
|
70
|
-
}
|
|
71
|
-
function _(e, t = {}) {
|
|
72
|
-
const { pageSize: n = 10, tokenKey: i = "NextToken", itemsKey: o = "Items" } = t;
|
|
48
|
+
}, v = (e, t) => {
|
|
49
|
+
const o = F.magenta("aws-sdk-vitest-mock(debug):");
|
|
50
|
+
if (t === void 0)
|
|
51
|
+
console.log(`${o} ${e}`);
|
|
52
|
+
else {
|
|
53
|
+
const i = z(t);
|
|
54
|
+
console.log(`${o} ${e}
|
|
55
|
+
${i}`);
|
|
56
|
+
}
|
|
57
|
+
}, L = (e = !1) => ({
|
|
58
|
+
enabled: e,
|
|
59
|
+
explicitlySet: !1,
|
|
60
|
+
log(t, o) {
|
|
61
|
+
this.enabled && v(t, o);
|
|
62
|
+
},
|
|
63
|
+
logDirect(t, o) {
|
|
64
|
+
v(t, o);
|
|
65
|
+
}
|
|
66
|
+
}), w = (e) => {
|
|
67
|
+
e.enabled = !0, e.explicitlySet = !0;
|
|
68
|
+
}, D = (e) => {
|
|
69
|
+
e.enabled = !1, e.explicitlySet = !0;
|
|
70
|
+
}, V = (e) => {
|
|
71
|
+
const t = I.resolve(e), o = O(t, "utf8");
|
|
72
|
+
return e.endsWith(".json") ? JSON.parse(o) : o;
|
|
73
|
+
}, U = (e, t = {}) => {
|
|
74
|
+
const { pageSize: o = 10, tokenKey: i = "NextToken", itemsKey: n = "Items" } = t;
|
|
73
75
|
if (e.length === 0)
|
|
74
|
-
return [{ [
|
|
76
|
+
return [{ [n]: [] }];
|
|
75
77
|
const s = [];
|
|
76
|
-
for (let r = 0; r < e.length; r +=
|
|
77
|
-
const c = e.slice(r, r +
|
|
78
|
+
for (let r = 0; r < e.length; r += o) {
|
|
79
|
+
const c = e.slice(r, r + o), l = r + o < e.length, u = { [n]: c };
|
|
78
80
|
if (l) {
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
+
const a = u, g = c[c.length - 1];
|
|
82
|
+
a[i] = g;
|
|
81
83
|
}
|
|
82
84
|
s.push(u);
|
|
83
85
|
}
|
|
84
86
|
return s;
|
|
85
|
-
}
|
|
86
|
-
function q() {
|
|
87
|
-
return typeof process < "u" && process.versions?.node ? "node" : typeof process < "u" && process.versions?.bun ? "bun" : "browser";
|
|
88
|
-
}
|
|
89
|
-
function z(e) {
|
|
87
|
+
}, G = () => typeof process < "u" && process.versions?.node ? "node" : typeof process < "u" && process.versions?.bun ? "bun" : "browser", H = (e) => {
|
|
90
88
|
const t = typeof e == "string" ? Buffer.from(e, "utf8") : Buffer.from(e);
|
|
91
|
-
let
|
|
92
|
-
return new
|
|
89
|
+
let o = !1;
|
|
90
|
+
return new M({
|
|
93
91
|
read() {
|
|
94
|
-
|
|
92
|
+
o || (this.push(t), this.push(null), o = !0);
|
|
95
93
|
}
|
|
96
94
|
});
|
|
97
|
-
}
|
|
98
|
-
function V(e) {
|
|
95
|
+
}, Q = (e) => {
|
|
99
96
|
let t;
|
|
100
97
|
return typeof e == "string" ? t = new TextEncoder().encode(e) : e instanceof Buffer ? t = new Uint8Array(e) : t = e, new ReadableStream({
|
|
101
|
-
start(
|
|
102
|
-
|
|
98
|
+
start(o) {
|
|
99
|
+
o.enqueue(t), o.close();
|
|
103
100
|
}
|
|
104
101
|
});
|
|
102
|
+
}, S = (e) => {
|
|
103
|
+
const t = G();
|
|
104
|
+
return t === "node" || t === "bun" ? H(e) : Q(e);
|
|
105
|
+
};
|
|
106
|
+
let $ = !1;
|
|
107
|
+
function ce(e) {
|
|
108
|
+
$ = e;
|
|
105
109
|
}
|
|
106
|
-
function
|
|
107
|
-
|
|
108
|
-
return t === "node" || t === "bun" ? z(e) : V(e);
|
|
110
|
+
function p(e) {
|
|
111
|
+
return e.explicitlySet ? e.enabled : $;
|
|
109
112
|
}
|
|
110
|
-
function
|
|
111
|
-
return Object.keys(t).every((
|
|
112
|
-
const i = t[
|
|
113
|
-
return i && typeof i == "object" && !Array.isArray(i) ? typeof
|
|
114
|
-
|
|
113
|
+
function N(e, t) {
|
|
114
|
+
return Object.keys(t).every((o) => {
|
|
115
|
+
const i = t[o], n = e[o];
|
|
116
|
+
return i && typeof i == "object" && !Array.isArray(i) ? typeof n != "object" || n === null ? !1 : N(
|
|
117
|
+
n,
|
|
115
118
|
i
|
|
116
|
-
) :
|
|
119
|
+
) : n === i;
|
|
117
120
|
});
|
|
118
121
|
}
|
|
119
|
-
function
|
|
122
|
+
function x(e, t) {
|
|
120
123
|
if (e === t) return !0;
|
|
121
124
|
if (typeof e != "object" || e === null || typeof t != "object" || t === null)
|
|
122
125
|
return e === t;
|
|
123
|
-
const
|
|
124
|
-
return
|
|
125
|
-
if (!Object.prototype.hasOwnProperty.call(e,
|
|
126
|
-
const s = e, r = t, c = s[
|
|
127
|
-
return typeof c == "object" && c !== null && typeof l == "object" && l !== null ?
|
|
126
|
+
const o = Object.keys(e), i = Object.keys(t);
|
|
127
|
+
return o.length !== i.length ? !1 : i.every((n) => {
|
|
128
|
+
if (!Object.prototype.hasOwnProperty.call(e, n)) return !1;
|
|
129
|
+
const s = e, r = t, c = s[n], l = r[n];
|
|
130
|
+
return typeof c == "object" && c !== null && typeof l == "object" && l !== null ? x(c, l) : c === l;
|
|
128
131
|
});
|
|
129
132
|
}
|
|
130
|
-
function
|
|
131
|
-
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
t.constructor
|
|
139
|
-
);
|
|
140
|
-
if (i) {
|
|
141
|
-
e.debugLogger.log(
|
|
142
|
-
`Found ${i.length} mock(s) for ${t.constructor.name}`
|
|
143
|
-
);
|
|
144
|
-
const s = i.findIndex((r) => r.strict ? r.matcher && N(t.input, r.matcher) : !r.matcher || $(t.input, r.matcher));
|
|
145
|
-
if (s === -1) {
|
|
146
|
-
e.debugLogger.log(
|
|
147
|
-
`No matching mock found for ${t.constructor.name}`,
|
|
148
|
-
t.input
|
|
149
|
-
);
|
|
150
|
-
const r = i.map((l, u) => {
|
|
151
|
-
const g = l.matcher ? JSON.stringify(l.matcher, void 0, 2) : "any input", a = l.strict ? " (strict mode)" : "";
|
|
152
|
-
return ` Mock #${u + 1}: ${g}${a}`;
|
|
153
|
-
}).join(`
|
|
154
|
-
`), c = JSON.stringify(t.input, void 0, 2);
|
|
155
|
-
throw new Error(
|
|
156
|
-
`No matching mock found for ${t.constructor.name}.
|
|
133
|
+
function X(e, t, o) {
|
|
134
|
+
const i = t.map((s, r) => {
|
|
135
|
+
const c = s.matcher ? JSON.stringify(s.matcher, void 0, 2) : "any input", l = s.strict ? " (strict mode)" : "";
|
|
136
|
+
return ` Mock #${r + 1}: ${c}${l}`;
|
|
137
|
+
}).join(`
|
|
138
|
+
`), n = JSON.stringify(o, void 0, 2);
|
|
139
|
+
return new Error(
|
|
140
|
+
`No matching mock found for ${e}.
|
|
157
141
|
|
|
158
|
-
Found ${
|
|
142
|
+
Found ${t.length} mock(s) but none matched the input.
|
|
159
143
|
|
|
160
144
|
Configured mocks:
|
|
161
|
-
${
|
|
145
|
+
${i}
|
|
162
146
|
|
|
163
147
|
Received input:
|
|
164
|
-
${
|
|
148
|
+
${n}
|
|
165
149
|
|
|
166
150
|
Tip: Enable debug mode with enableDebug() for detailed matching information.`
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
`Using mock at index ${s} for ${t.constructor.name}`
|
|
174
|
-
), r.once && (i.splice(s, 1), e.debugLogger.log(
|
|
175
|
-
`Removed one-time mock for ${t.constructor.name}`
|
|
176
|
-
)), r.handler(
|
|
177
|
-
t.input,
|
|
178
|
-
n()
|
|
179
|
-
);
|
|
180
|
-
}
|
|
181
|
-
} else
|
|
182
|
-
e.debugLogger.log(
|
|
183
|
-
`No mocks configured for ${t.constructor.name}`
|
|
184
|
-
);
|
|
185
|
-
const o = JSON.stringify(t.input, void 0, 2);
|
|
186
|
-
throw new Error(
|
|
187
|
-
`No mock configured for command: ${t.constructor.name}.
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
function Y(e, t) {
|
|
154
|
+
const o = JSON.stringify(t, void 0, 2);
|
|
155
|
+
return new Error(
|
|
156
|
+
`No mock configured for command: ${e}.
|
|
188
157
|
|
|
189
158
|
Received input:
|
|
190
159
|
${o}
|
|
191
160
|
|
|
192
|
-
Did you forget to call mockClient.on(${
|
|
161
|
+
Did you forget to call mockClient.on(${e})?`
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
function Z(e, t) {
|
|
165
|
+
return e.findIndex((o) => o.strict ? o.matcher && x(t, o.matcher) : !o.matcher || N(t, o.matcher));
|
|
166
|
+
}
|
|
167
|
+
function E(e) {
|
|
168
|
+
return async function(t) {
|
|
169
|
+
const o = () => this, i = p(e.debugLogger), n = t.constructor.name;
|
|
170
|
+
i && e.debugLogger.logDirect(
|
|
171
|
+
`Received command: ${n}`,
|
|
172
|
+
t.input
|
|
173
|
+
);
|
|
174
|
+
const s = e.map.get(
|
|
175
|
+
t.constructor
|
|
193
176
|
);
|
|
177
|
+
if (!s)
|
|
178
|
+
throw i && e.debugLogger.logDirect(
|
|
179
|
+
`No mocks configured for ${n}`
|
|
180
|
+
), Y(n, t.input);
|
|
181
|
+
i && e.debugLogger.logDirect(
|
|
182
|
+
`Found ${s.length} mock(s) for ${n}`
|
|
183
|
+
);
|
|
184
|
+
const r = Z(s, t.input);
|
|
185
|
+
if (r === -1)
|
|
186
|
+
throw i && e.debugLogger.logDirect(
|
|
187
|
+
`No matching mock found for ${n}`,
|
|
188
|
+
t.input
|
|
189
|
+
), X(n, s, t.input);
|
|
190
|
+
const c = s[r];
|
|
191
|
+
if (!c)
|
|
192
|
+
throw new Error(`Mock at index ${r} not found`);
|
|
193
|
+
return i && e.debugLogger.logDirect(
|
|
194
|
+
`Using mock at index ${r} for ${n}`
|
|
195
|
+
), c.once && (s.splice(r, 1), i && e.debugLogger.logDirect(
|
|
196
|
+
`Removed one-time mock for ${n}`
|
|
197
|
+
)), c.handler(t.input, o());
|
|
194
198
|
};
|
|
195
199
|
}
|
|
196
|
-
function
|
|
197
|
-
const
|
|
200
|
+
function C(e, t, o, i = {}) {
|
|
201
|
+
const n = (r, c, l) => {
|
|
198
202
|
const u = {
|
|
199
|
-
matcher:
|
|
203
|
+
matcher: o,
|
|
200
204
|
handler: r,
|
|
201
205
|
once: c,
|
|
202
206
|
strict: !!i.strict
|
|
203
|
-
},
|
|
207
|
+
}, a = e.map.get(t) ?? [], g = p(e.debugLogger);
|
|
204
208
|
if (c) {
|
|
205
|
-
const
|
|
206
|
-
|
|
209
|
+
const f = a.findIndex((h) => !h.once);
|
|
210
|
+
f === -1 ? a.push(u) : a.splice(f, 0, u), e.map.set(
|
|
207
211
|
t,
|
|
208
|
-
|
|
209
|
-
), e.debugLogger.
|
|
212
|
+
a
|
|
213
|
+
), g && e.debugLogger.logDirect(
|
|
210
214
|
`Configured ${l}Once for ${t.name}`,
|
|
211
|
-
|
|
215
|
+
o ? { matcher: o, strict: !!i.strict } : void 0
|
|
212
216
|
);
|
|
213
217
|
} else {
|
|
214
|
-
const
|
|
215
|
-
(
|
|
218
|
+
const f = a.filter(
|
|
219
|
+
(h) => h.once || JSON.stringify(h.matcher) !== JSON.stringify(o)
|
|
216
220
|
);
|
|
217
|
-
|
|
221
|
+
f.push(u), e.map.set(
|
|
218
222
|
t,
|
|
219
|
-
|
|
220
|
-
), e.debugLogger.
|
|
223
|
+
f
|
|
224
|
+
), g && e.debugLogger.logDirect(
|
|
221
225
|
`Configured ${l} for ${t.name}`,
|
|
222
|
-
|
|
226
|
+
o ? { matcher: o, strict: !!i.strict } : void 0
|
|
223
227
|
);
|
|
224
228
|
}
|
|
225
229
|
}, s = {
|
|
226
230
|
resolves(r) {
|
|
227
|
-
return
|
|
231
|
+
return n(() => Promise.resolve(r), !1, "resolves"), s;
|
|
228
232
|
},
|
|
229
233
|
rejects(r) {
|
|
230
|
-
return
|
|
234
|
+
return n(
|
|
231
235
|
() => {
|
|
232
236
|
const c = typeof r == "string" ? new Error(r) : r;
|
|
233
237
|
return Promise.reject(c);
|
|
@@ -237,13 +241,13 @@ function R(e, t, n, i = {}) {
|
|
|
237
241
|
), s;
|
|
238
242
|
},
|
|
239
243
|
callsFake(r) {
|
|
240
|
-
return
|
|
244
|
+
return n(r, !1, "callsFake"), s;
|
|
241
245
|
},
|
|
242
246
|
resolvesOnce(r) {
|
|
243
|
-
return
|
|
247
|
+
return n(() => Promise.resolve(r), !0, "resolves"), s;
|
|
244
248
|
},
|
|
245
249
|
rejectsOnce(r) {
|
|
246
|
-
return
|
|
250
|
+
return n(
|
|
247
251
|
() => {
|
|
248
252
|
const c = typeof r == "string" ? new Error(r) : r;
|
|
249
253
|
return Promise.reject(c);
|
|
@@ -253,18 +257,18 @@ function R(e, t, n, i = {}) {
|
|
|
253
257
|
), s;
|
|
254
258
|
},
|
|
255
259
|
callsFakeOnce(r) {
|
|
256
|
-
return
|
|
260
|
+
return n(r, !0, "callsFake"), s;
|
|
257
261
|
},
|
|
258
262
|
resolvesStream(r) {
|
|
259
|
-
return
|
|
260
|
-
() => Promise.resolve({ Body:
|
|
263
|
+
return n(
|
|
264
|
+
() => Promise.resolve({ Body: S(r) }),
|
|
261
265
|
!1,
|
|
262
266
|
"resolvesStream"
|
|
263
267
|
), s;
|
|
264
268
|
},
|
|
265
269
|
resolvesStreamOnce(r) {
|
|
266
|
-
return
|
|
267
|
-
() => Promise.resolve({ Body:
|
|
270
|
+
return n(
|
|
271
|
+
() => Promise.resolve({ Body: S(r) }),
|
|
268
272
|
!0,
|
|
269
273
|
"resolvesStream"
|
|
270
274
|
), s;
|
|
@@ -273,96 +277,96 @@ function R(e, t, n, i = {}) {
|
|
|
273
277
|
const l = (u) => {
|
|
274
278
|
setTimeout(() => u(r), c);
|
|
275
279
|
};
|
|
276
|
-
return
|
|
280
|
+
return n(() => new Promise(l), !1, "resolvesWithDelay"), s;
|
|
277
281
|
},
|
|
278
282
|
rejectsWithDelay(r, c) {
|
|
279
|
-
const l = typeof r == "string" ? new Error(r) : r, u = (
|
|
280
|
-
setTimeout(() =>
|
|
283
|
+
const l = typeof r == "string" ? new Error(r) : r, u = (a, g) => {
|
|
284
|
+
setTimeout(() => g(l), c);
|
|
281
285
|
};
|
|
282
|
-
return
|
|
286
|
+
return n(() => new Promise(u), !1, "rejectsWithDelay"), s;
|
|
283
287
|
},
|
|
284
288
|
rejectsWithNoSuchKey(r) {
|
|
285
|
-
return
|
|
286
|
-
() => Promise.reject(
|
|
289
|
+
return n(
|
|
290
|
+
() => Promise.reject(T(r)),
|
|
287
291
|
!1,
|
|
288
292
|
"rejectsWithNoSuchKey"
|
|
289
293
|
), s;
|
|
290
294
|
},
|
|
291
295
|
rejectsWithNoSuchBucket(r) {
|
|
292
|
-
return
|
|
293
|
-
() => Promise.reject(
|
|
296
|
+
return n(
|
|
297
|
+
() => Promise.reject(K(r)),
|
|
294
298
|
!1,
|
|
295
299
|
"rejectsWithNoSuchBucket"
|
|
296
300
|
), s;
|
|
297
301
|
},
|
|
298
302
|
rejectsWithAccessDenied(r) {
|
|
299
|
-
return
|
|
300
|
-
() => Promise.reject(
|
|
303
|
+
return n(
|
|
304
|
+
() => Promise.reject(A(r)),
|
|
301
305
|
!1,
|
|
302
306
|
"rejectsWithAccessDenied"
|
|
303
307
|
), s;
|
|
304
308
|
},
|
|
305
309
|
rejectsWithResourceNotFound(r) {
|
|
306
|
-
return
|
|
307
|
-
() => Promise.reject(
|
|
310
|
+
return n(
|
|
311
|
+
() => Promise.reject(B(r)),
|
|
308
312
|
!1,
|
|
309
313
|
"rejectsWithResourceNotFound"
|
|
310
314
|
), s;
|
|
311
315
|
},
|
|
312
316
|
rejectsWithConditionalCheckFailed() {
|
|
313
|
-
return
|
|
314
|
-
() => Promise.reject(
|
|
317
|
+
return n(
|
|
318
|
+
() => Promise.reject(J()),
|
|
315
319
|
!1,
|
|
316
320
|
"rejectsWithConditionalCheckFailed"
|
|
317
321
|
), s;
|
|
318
322
|
},
|
|
319
323
|
rejectsWithThrottling() {
|
|
320
|
-
return
|
|
321
|
-
() => Promise.reject(
|
|
324
|
+
return n(
|
|
325
|
+
() => Promise.reject(_()),
|
|
322
326
|
!1,
|
|
323
327
|
"rejectsWithThrottling"
|
|
324
328
|
), s;
|
|
325
329
|
},
|
|
326
330
|
rejectsWithInternalServerError() {
|
|
327
|
-
return
|
|
328
|
-
() => Promise.reject(
|
|
331
|
+
return n(
|
|
332
|
+
() => Promise.reject(q()),
|
|
329
333
|
!1,
|
|
330
334
|
"rejectsWithInternalServerError"
|
|
331
335
|
), s;
|
|
332
336
|
},
|
|
333
337
|
resolvesPaginated(r, c = {}) {
|
|
334
|
-
const l =
|
|
338
|
+
const l = U(r, c);
|
|
335
339
|
let u = 0;
|
|
336
340
|
return e.debugLogger.log(
|
|
337
341
|
`Configured resolvesPaginated for ${t.name}`,
|
|
338
342
|
{ pageSize: c.pageSize, itemsCount: r.length }
|
|
339
|
-
),
|
|
340
|
-
(
|
|
341
|
-
const
|
|
342
|
-
if (
|
|
343
|
-
const
|
|
344
|
-
let
|
|
345
|
-
for (const
|
|
346
|
-
const
|
|
347
|
-
if (
|
|
348
|
-
const
|
|
349
|
-
if (JSON.stringify(
|
|
350
|
-
u =
|
|
343
|
+
), n(
|
|
344
|
+
(a) => {
|
|
345
|
+
const g = c.tokenKey || "NextToken", f = c.inputTokenKey || g, b = a[f];
|
|
346
|
+
if (b != null) {
|
|
347
|
+
const R = c.itemsKey || "Items";
|
|
348
|
+
let k = 0;
|
|
349
|
+
for (const W of l) {
|
|
350
|
+
const m = W[R];
|
|
351
|
+
if (m && m.length > 0) {
|
|
352
|
+
const P = m[m.length - 1];
|
|
353
|
+
if (JSON.stringify(P) === JSON.stringify(b)) {
|
|
354
|
+
u = k + 1;
|
|
351
355
|
break;
|
|
352
356
|
}
|
|
353
357
|
}
|
|
354
|
-
|
|
358
|
+
k++;
|
|
355
359
|
}
|
|
356
360
|
} else
|
|
357
361
|
u = 0;
|
|
358
|
-
const
|
|
362
|
+
const y = (
|
|
359
363
|
// eslint-disable-next-line security/detect-object-injection
|
|
360
364
|
l[u] || // eslint-disable-next-line unicorn/prefer-at -- TypeScript target doesn't support Array.at() method
|
|
361
365
|
l[l.length - 1] || l[0]
|
|
362
366
|
);
|
|
363
|
-
if (!
|
|
367
|
+
if (!y)
|
|
364
368
|
throw new Error("No paginated responses available");
|
|
365
|
-
return u = Math.min(u + 1, l.length - 1), Promise.resolve(
|
|
369
|
+
return u = Math.min(u + 1, l.length - 1), Promise.resolve(y);
|
|
366
370
|
},
|
|
367
371
|
!1,
|
|
368
372
|
"resolvesPaginated"
|
|
@@ -372,9 +376,9 @@ function R(e, t, n, i = {}) {
|
|
|
372
376
|
return e.debugLogger.log(
|
|
373
377
|
`Configured resolvesFromFile for ${t.name}`,
|
|
374
378
|
{ filePath: r }
|
|
375
|
-
),
|
|
379
|
+
), n(
|
|
376
380
|
() => {
|
|
377
|
-
const c =
|
|
381
|
+
const c = V(r);
|
|
378
382
|
return Promise.resolve(c);
|
|
379
383
|
},
|
|
380
384
|
!1,
|
|
@@ -384,71 +388,74 @@ function R(e, t, n, i = {}) {
|
|
|
384
388
|
};
|
|
385
389
|
return s;
|
|
386
390
|
}
|
|
387
|
-
const
|
|
391
|
+
const ie = (e) => {
|
|
388
392
|
const t = {
|
|
389
393
|
map: /* @__PURE__ */ new WeakMap(),
|
|
390
|
-
debugLogger:
|
|
391
|
-
},
|
|
394
|
+
debugLogger: L()
|
|
395
|
+
}, o = e.prototype, i = j.spyOn(o, "send").mockImplementation(E(t));
|
|
392
396
|
return {
|
|
393
397
|
client: void 0,
|
|
394
|
-
on: (s, r, c) =>
|
|
398
|
+
on: (s, r, c) => C(
|
|
395
399
|
t,
|
|
396
400
|
s,
|
|
397
401
|
r,
|
|
398
402
|
c
|
|
399
403
|
),
|
|
400
404
|
reset: () => {
|
|
401
|
-
t.debugLogger
|
|
405
|
+
p(t.debugLogger) && t.debugLogger.logDirect(
|
|
406
|
+
"Clearing call history (mocks preserved)"
|
|
407
|
+
), i.mockClear();
|
|
402
408
|
},
|
|
403
409
|
restore: () => {
|
|
404
|
-
t.debugLogger.
|
|
410
|
+
p(t.debugLogger) && t.debugLogger.logDirect(
|
|
405
411
|
"Restoring original client behavior and clearing all mocks"
|
|
406
412
|
), i.mockRestore(), t.map = /* @__PURE__ */ new WeakMap();
|
|
407
413
|
},
|
|
408
414
|
calls: () => i.mock.calls.map((s) => s[0]),
|
|
409
415
|
__rawCalls: () => i.mock.calls,
|
|
410
416
|
enableDebug: () => {
|
|
411
|
-
|
|
417
|
+
w(t.debugLogger);
|
|
412
418
|
},
|
|
413
419
|
disableDebug: () => {
|
|
414
|
-
|
|
420
|
+
D(t.debugLogger);
|
|
415
421
|
}
|
|
416
422
|
};
|
|
417
|
-
},
|
|
423
|
+
}, le = (e) => {
|
|
418
424
|
const t = {
|
|
419
425
|
map: /* @__PURE__ */ new WeakMap(),
|
|
420
|
-
debugLogger:
|
|
421
|
-
},
|
|
426
|
+
debugLogger: L()
|
|
427
|
+
}, o = j.spyOn(e, "send").mockImplementation(E(t));
|
|
422
428
|
return {
|
|
423
429
|
client: e,
|
|
424
|
-
on: (
|
|
430
|
+
on: (n, s, r) => C(
|
|
425
431
|
t,
|
|
426
|
-
|
|
432
|
+
n,
|
|
427
433
|
s,
|
|
428
434
|
r
|
|
429
435
|
),
|
|
430
436
|
reset: () => {
|
|
431
|
-
t.debugLogger.
|
|
437
|
+
p(t.debugLogger) && t.debugLogger.logDirect(
|
|
432
438
|
"Clearing call history (mocks preserved) for client instance"
|
|
433
|
-
),
|
|
439
|
+
), o.mockClear();
|
|
434
440
|
},
|
|
435
441
|
restore: () => {
|
|
436
|
-
t.debugLogger.
|
|
442
|
+
p(t.debugLogger) && t.debugLogger.logDirect(
|
|
437
443
|
"Restoring original client behavior and clearing all mocks for client instance"
|
|
438
|
-
),
|
|
444
|
+
), o.mockRestore(), t.map = /* @__PURE__ */ new WeakMap();
|
|
439
445
|
},
|
|
440
|
-
calls: () =>
|
|
441
|
-
__rawCalls: () =>
|
|
446
|
+
calls: () => o.mock.calls.map((n) => n[0]),
|
|
447
|
+
__rawCalls: () => o.mock.calls,
|
|
442
448
|
enableDebug: () => {
|
|
443
|
-
|
|
449
|
+
w(t.debugLogger);
|
|
444
450
|
},
|
|
445
451
|
disableDebug: () => {
|
|
446
|
-
|
|
452
|
+
D(t.debugLogger);
|
|
447
453
|
}
|
|
448
454
|
};
|
|
449
455
|
};
|
|
450
456
|
export {
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
457
|
+
ge as matchers,
|
|
458
|
+
ie as mockClient,
|
|
459
|
+
le as mockClientInstance,
|
|
460
|
+
ce as setGlobalDebug
|
|
454
461
|
};
|
package/lib/mock-client.d.ts
CHANGED
|
@@ -3,6 +3,27 @@ import { HttpHandlerOptions, MetadataBearer } from '@smithy/types';
|
|
|
3
3
|
import { Mock } from 'vitest';
|
|
4
4
|
import { PaginatorOptions } from './utils/paginator-helpers.js';
|
|
5
5
|
import { StreamInput } from './utils/stream-helpers.js';
|
|
6
|
+
/**
|
|
7
|
+
* Set global debug mode for all mocks.
|
|
8
|
+
* When enabled, all mocks will log debug information unless explicitly disabled at the mock level.
|
|
9
|
+
*
|
|
10
|
+
* @param enabled - Whether to enable debug logging globally
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* import { setGlobalDebug, mockClient } from 'aws-sdk-vitest-mock';
|
|
15
|
+
* import { S3Client } from '@aws-sdk/client-s3';
|
|
16
|
+
*
|
|
17
|
+
* // Enable debug for all mocks
|
|
18
|
+
* setGlobalDebug(true);
|
|
19
|
+
*
|
|
20
|
+
* const s3Mock = mockClient(S3Client); // Automatically has debug enabled
|
|
21
|
+
*
|
|
22
|
+
* // Disable debug for a specific mock
|
|
23
|
+
* s3Mock.disableDebug(); // This mock won't log, but others will
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export declare function setGlobalDebug(enabled: boolean): void;
|
|
6
27
|
export type StructuralCommand<TInput extends object, TOutput extends MetadataBearer> = SmithyCommand<TInput, TOutput, any, any, any> | {
|
|
7
28
|
readonly input: TInput;
|
|
8
29
|
readonly __awsSdkVitestMockOutput?: TOutput;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
export interface DebugLogger {
|
|
2
2
|
enabled: boolean;
|
|
3
|
+
explicitlySet: boolean;
|
|
3
4
|
log: (message: string, data?: unknown) => void;
|
|
5
|
+
logDirect: (message: string, data?: unknown) => void;
|
|
4
6
|
}
|
|
5
|
-
export declare
|
|
6
|
-
export declare
|
|
7
|
-
export declare
|
|
7
|
+
export declare const createDebugLogger: (initialEnabled?: boolean) => DebugLogger;
|
|
8
|
+
export declare const enableDebug: (logger: DebugLogger) => void;
|
|
9
|
+
export declare const disableDebug: (logger: DebugLogger) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare
|
|
1
|
+
export declare const loadFixture: (filePath: string) => unknown;
|
|
@@ -95,4 +95,4 @@ export interface PaginatedResponse<T = unknown> {
|
|
|
95
95
|
* // ]
|
|
96
96
|
* ```
|
|
97
97
|
*/
|
|
98
|
-
export declare
|
|
98
|
+
export declare const createPaginatedResponses: <T>(items: T[], options?: PaginatorOptions) => PaginatedResponse<T>[];
|
|
@@ -3,4 +3,4 @@ export type StreamInput = string | Buffer | Uint8Array;
|
|
|
3
3
|
/**
|
|
4
4
|
* Creates an appropriate stream for the current environment
|
|
5
5
|
*/
|
|
6
|
-
export declare
|
|
6
|
+
export declare const createStream: (data: StreamInput) => Readable | ReadableStream<Uint8Array>;
|
|
@@ -1,4 +1,4 @@
|
|
|
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.__rawCalls();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
|
|
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.__rawCalls();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 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.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
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
3
|
${u}
|
|
4
4
|
|
|
@@ -31,13 +31,13 @@ const e = {
|
|
|
31
31
|
* ```
|
|
32
32
|
*/
|
|
33
33
|
toHaveReceivedCommand(t, c) {
|
|
34
|
-
const a = $(t), r = a.some((o) => o
|
|
34
|
+
const a = $(t), r = a.some(([o]) => o instanceof c), m = c.name;
|
|
35
35
|
return {
|
|
36
36
|
pass: r,
|
|
37
37
|
message: () => {
|
|
38
38
|
if (r)
|
|
39
39
|
return `Expected AWS SDK mock not to have received command ${e.red(m)}`;
|
|
40
|
-
const o = a.map((n) => n
|
|
40
|
+
const o = a.map(([n]) => n.constructor?.name ?? "Unknown");
|
|
41
41
|
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(", "))}`;
|
|
42
42
|
}
|
|
43
43
|
};
|
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-CNhdB_9q.cjs");e.expect.extend(t.matchers);
|
package/vitest-setup.js
CHANGED