aws-sdk-vitest-mock 0.2.1 → 0.3.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/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
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"),
|
|
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"),C=require("./matchers-Rq18z2C7.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 W=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 h(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:h(r)}),!1),o},resolvesStreamOnce(r){return n(()=>Promise.resolve({Body:h(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(W(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 m=i[l]||i[i.length-1]||i[0];if(!m)throw new Error("No paginated responses available");return l=Math.min(l+1,i.length-1),Promise.resolve(m)},!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.map(o=>o[0]),__rawCalls:()=>c.mock.calls,enableDebug:()=>{y(e.debugLogger)},disableDebug:()=>{v(e.debugLogger)}}},_=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.map(n=>n[0]),__rawCalls:()=>s.mock.calls,enableDebug:()=>{y(e.debugLogger)},disableDebug:()=>{v(e.debugLogger)}}};exports.matchers=C.matchers;exports.mockClient=B;exports.mockClientInstance=_;
|
package/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import { vi as b } from "vitest";
|
|
|
2
2
|
import { readFileSync as P } from "node:fs";
|
|
3
3
|
import R from "node:path";
|
|
4
4
|
import { Readable as N } from "node:stream";
|
|
5
|
-
import { m as X } from "./matchers-
|
|
5
|
+
import { m as X } from "./matchers-C6AtmwWz.js";
|
|
6
6
|
class d extends Error {
|
|
7
7
|
constructor(e, s, c, n) {
|
|
8
8
|
super(e), this.name = "AwsError", this.code = s, this.statusCode = c, this.retryable = n;
|
|
@@ -11,16 +11,16 @@ class d extends Error {
|
|
|
11
11
|
const W = (t) => {
|
|
12
12
|
const e = t ? `The specified key does not exist. Key: ${t}` : "The specified key does not exist.";
|
|
13
13
|
return new d(e, "NoSuchKey", 404, !1);
|
|
14
|
-
},
|
|
14
|
+
}, C = (t) => {
|
|
15
15
|
const e = t ? `The specified bucket does not exist. Bucket: ${t}` : "The specified bucket does not exist.";
|
|
16
16
|
return new d(e, "NoSuchBucket", 404, !1);
|
|
17
|
-
},
|
|
17
|
+
}, $ = (t) => {
|
|
18
18
|
const e = t ? `Access Denied for resource: ${t}` : "Access Denied";
|
|
19
19
|
return new d(e, "AccessDenied", 403, !1);
|
|
20
|
-
},
|
|
20
|
+
}, D = (t) => {
|
|
21
21
|
const e = t ? `Requested resource not found: ${t}` : "Requested resource not found";
|
|
22
22
|
return new d(e, "ResourceNotFoundException", 400, !1);
|
|
23
|
-
},
|
|
23
|
+
}, M = () => new d(
|
|
24
24
|
"The conditional request failed",
|
|
25
25
|
"ConditionalCheckFailedException",
|
|
26
26
|
400,
|
|
@@ -42,7 +42,7 @@ function k() {
|
|
|
42
42
|
function y(t) {
|
|
43
43
|
t.enabled = !0;
|
|
44
44
|
}
|
|
45
|
-
function
|
|
45
|
+
function w(t) {
|
|
46
46
|
t.enabled = !1;
|
|
47
47
|
}
|
|
48
48
|
function T(t) {
|
|
@@ -87,10 +87,10 @@ function h(t) {
|
|
|
87
87
|
const e = L();
|
|
88
88
|
return e === "node" || e === "bun" ? A(t) : K(t);
|
|
89
89
|
}
|
|
90
|
-
function
|
|
90
|
+
function v(t, e) {
|
|
91
91
|
return Object.keys(e).every((s) => {
|
|
92
92
|
const c = e[s], n = t[s];
|
|
93
|
-
return c && typeof c == "object" && !Array.isArray(c) ? typeof n != "object" || n === null ? !1 :
|
|
93
|
+
return c && typeof c == "object" && !Array.isArray(c) ? typeof n != "object" || n === null ? !1 : v(
|
|
94
94
|
n,
|
|
95
95
|
c
|
|
96
96
|
) : n === c;
|
|
@@ -121,7 +121,7 @@ function x(t) {
|
|
|
121
121
|
t.debugLogger.log(
|
|
122
122
|
`Found ${c.length} mock(s) for ${e.constructor.name}`
|
|
123
123
|
);
|
|
124
|
-
const n = c.findIndex((o) => o.strict ? o.matcher && j(e.input, o.matcher) : !o.matcher ||
|
|
124
|
+
const n = c.findIndex((o) => o.strict ? o.matcher && j(e.input, o.matcher) : !o.matcher || v(e.input, o.matcher));
|
|
125
125
|
if (n === -1)
|
|
126
126
|
t.debugLogger.log(
|
|
127
127
|
`No matching mock found for ${e.constructor.name}`,
|
|
@@ -225,20 +225,20 @@ function S(t, e, s, c = {}) {
|
|
|
225
225
|
return n(() => Promise.reject(W(r)), !1), o;
|
|
226
226
|
},
|
|
227
227
|
rejectsWithNoSuchBucket(r) {
|
|
228
|
-
return n(() => Promise.reject(
|
|
228
|
+
return n(() => Promise.reject(C(r)), !1), o;
|
|
229
229
|
},
|
|
230
230
|
rejectsWithAccessDenied(r) {
|
|
231
|
-
return n(() => Promise.reject(
|
|
231
|
+
return n(() => Promise.reject($(r)), !1), o;
|
|
232
232
|
},
|
|
233
233
|
rejectsWithResourceNotFound(r) {
|
|
234
234
|
return n(
|
|
235
|
-
() => Promise.reject(
|
|
235
|
+
() => Promise.reject(D(r)),
|
|
236
236
|
!1
|
|
237
237
|
), o;
|
|
238
238
|
},
|
|
239
239
|
rejectsWithConditionalCheckFailed() {
|
|
240
240
|
return n(
|
|
241
|
-
() => Promise.reject(
|
|
241
|
+
() => Promise.reject(M()),
|
|
242
242
|
!1
|
|
243
243
|
), o;
|
|
244
244
|
},
|
|
@@ -282,7 +282,7 @@ function S(t, e, s, c = {}) {
|
|
|
282
282
|
};
|
|
283
283
|
return o;
|
|
284
284
|
}
|
|
285
|
-
const
|
|
285
|
+
const U = (t) => {
|
|
286
286
|
const e = {
|
|
287
287
|
map: /* @__PURE__ */ new WeakMap(),
|
|
288
288
|
debugLogger: k()
|
|
@@ -301,12 +301,13 @@ const _ = (t) => {
|
|
|
301
301
|
restore: () => {
|
|
302
302
|
c.mockRestore(), e.map = /* @__PURE__ */ new WeakMap();
|
|
303
303
|
},
|
|
304
|
-
calls: () => c.mock.calls,
|
|
304
|
+
calls: () => c.mock.calls.map((o) => o[0]),
|
|
305
|
+
__rawCalls: () => c.mock.calls,
|
|
305
306
|
enableDebug: () => {
|
|
306
307
|
y(e.debugLogger);
|
|
307
308
|
},
|
|
308
309
|
disableDebug: () => {
|
|
309
|
-
|
|
310
|
+
w(e.debugLogger);
|
|
310
311
|
}
|
|
311
312
|
};
|
|
312
313
|
}, G = (t) => {
|
|
@@ -328,17 +329,18 @@ const _ = (t) => {
|
|
|
328
329
|
restore: () => {
|
|
329
330
|
s.mockRestore(), e.map = /* @__PURE__ */ new WeakMap();
|
|
330
331
|
},
|
|
331
|
-
calls: () => s.mock.calls,
|
|
332
|
+
calls: () => s.mock.calls.map((n) => n[0]),
|
|
333
|
+
__rawCalls: () => s.mock.calls,
|
|
332
334
|
enableDebug: () => {
|
|
333
335
|
y(e.debugLogger);
|
|
334
336
|
},
|
|
335
337
|
disableDebug: () => {
|
|
336
|
-
|
|
338
|
+
w(e.debugLogger);
|
|
337
339
|
}
|
|
338
340
|
};
|
|
339
341
|
};
|
|
340
342
|
export {
|
|
341
343
|
X as matchers,
|
|
342
|
-
|
|
344
|
+
U as mockClient,
|
|
343
345
|
G as mockClientInstance
|
|
344
346
|
};
|
package/lib/mock-client.d.ts
CHANGED
|
@@ -12,10 +12,10 @@ type AwsCommandConstructor = CommandConstructor<any, MetadataBearer>;
|
|
|
12
12
|
export type CommandInputType<TCtor extends AwsCommandConstructor> = ConstructorParameters<TCtor>[0];
|
|
13
13
|
export type CommandOutputType<TCtor extends AwsCommandConstructor> = InstanceType<TCtor> extends StructuralCommand<any, infer TOutput> ? TOutput : MetadataBearer;
|
|
14
14
|
export type AnyClient = {
|
|
15
|
-
send(command:
|
|
15
|
+
send(command: AwsSdkCommand): Promise<MetadataBearer>;
|
|
16
16
|
config: SmithyResolvedConfiguration<HttpHandlerOptions> | Record<string, unknown>;
|
|
17
17
|
};
|
|
18
|
-
export type
|
|
18
|
+
export type AwsSdkCommand = StructuralCommand<object, MetadataBearer>;
|
|
19
19
|
export type ClientConstructor<TClient extends AnyClient> = (abstract new (...args: unknown[]) => TClient) | {
|
|
20
20
|
prototype: TClient;
|
|
21
21
|
};
|
|
@@ -28,7 +28,9 @@ export interface AwsClientStub<TClient extends AnyClient = AnyClient> {
|
|
|
28
28
|
on: <TCtor extends AwsCommandConstructor>(command: TCtor, request?: Partial<CommandInputType<TCtor>>, options?: MockOptions) => AwsCommandStub<CommandInputType<TCtor>, CommandOutputType<TCtor>, TClient>;
|
|
29
29
|
reset: () => void;
|
|
30
30
|
restore: () => void;
|
|
31
|
-
calls: () =>
|
|
31
|
+
calls: () => AwsSdkCommand[];
|
|
32
|
+
/** @internal - For use by matchers only */
|
|
33
|
+
__rawCalls: () => ReturnType<Mock["mock"]["calls"]["slice"]>;
|
|
32
34
|
enableDebug: () => void;
|
|
33
35
|
disableDebug: () => void;
|
|
34
36
|
}
|
|
@@ -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.
|
|
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[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
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
|
|
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-Rq18z2C7.cjs");e.expect.extend(t.matchers);
|
package/vitest-setup.js
CHANGED