@mastra/client-js 0.1.0-alpha.2 → 0.1.0-alpha.3
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/.eslintrc.js +10 -0
- package/.prettierignore +3 -0
- package/.prettierrc.json +26 -0
- package/LICENSE +44 -201
- package/README.md +90 -271
- package/dist/index.d.mts +346 -0
- package/dist/index.mjs +399 -0
- package/package.json +28 -95
- package/src/client.ts +201 -0
- package/src/index.test.ts +507 -0
- package/src/index.ts +2 -200
- package/src/resources/agent.ts +94 -0
- package/src/resources/index.ts +5 -14
- package/src/resources/memory-thread.ts +51 -0
- package/src/resources/tool.ts +28 -0
- package/src/resources/vector.ts +79 -0
- package/src/resources/workflow.ts +28 -0
- package/src/types.ts +121 -0
- package/tsconfig.json +29 -0
- package/vitest.config.js +8 -0
- package/CHANGELOG.md +0 -29
- package/_shims/MultipartBody.d.ts +0 -9
- package/_shims/MultipartBody.d.ts.map +0 -1
- package/_shims/MultipartBody.js +0 -16
- package/_shims/MultipartBody.js.map +0 -1
- package/_shims/MultipartBody.mjs +0 -12
- package/_shims/MultipartBody.mjs.map +0 -1
- package/_shims/README.md +0 -46
- package/_shims/auto/runtime-bun.d.ts +0 -5
- package/_shims/auto/runtime-bun.d.ts.map +0 -1
- package/_shims/auto/runtime-bun.js +0 -21
- package/_shims/auto/runtime-bun.js.map +0 -1
- package/_shims/auto/runtime-bun.mjs +0 -2
- package/_shims/auto/runtime-bun.mjs.map +0 -1
- package/_shims/auto/runtime-node.d.ts +0 -5
- package/_shims/auto/runtime-node.d.ts.map +0 -1
- package/_shims/auto/runtime-node.js +0 -21
- package/_shims/auto/runtime-node.js.map +0 -1
- package/_shims/auto/runtime-node.mjs +0 -2
- package/_shims/auto/runtime-node.mjs.map +0 -1
- package/_shims/auto/runtime.d.ts +0 -5
- package/_shims/auto/runtime.d.ts.map +0 -1
- package/_shims/auto/runtime.js +0 -21
- package/_shims/auto/runtime.js.map +0 -1
- package/_shims/auto/runtime.mjs +0 -2
- package/_shims/auto/runtime.mjs.map +0 -1
- package/_shims/auto/types-node.d.ts +0 -5
- package/_shims/auto/types-node.d.ts.map +0 -1
- package/_shims/auto/types-node.js +0 -21
- package/_shims/auto/types-node.js.map +0 -1
- package/_shims/auto/types-node.mjs +0 -2
- package/_shims/auto/types-node.mjs.map +0 -1
- package/_shims/auto/types.d.ts +0 -101
- package/_shims/auto/types.js +0 -3
- package/_shims/auto/types.mjs +0 -3
- package/_shims/bun-runtime.d.ts +0 -6
- package/_shims/bun-runtime.d.ts.map +0 -1
- package/_shims/bun-runtime.js +0 -14
- package/_shims/bun-runtime.js.map +0 -1
- package/_shims/bun-runtime.mjs +0 -10
- package/_shims/bun-runtime.mjs.map +0 -1
- package/_shims/index.d.ts +0 -81
- package/_shims/index.js +0 -13
- package/_shims/index.mjs +0 -7
- package/_shims/manual-types.d.ts +0 -12
- package/_shims/manual-types.js +0 -3
- package/_shims/manual-types.mjs +0 -3
- package/_shims/node-runtime.d.ts +0 -3
- package/_shims/node-runtime.d.ts.map +0 -1
- package/_shims/node-runtime.js +0 -89
- package/_shims/node-runtime.js.map +0 -1
- package/_shims/node-runtime.mjs +0 -56
- package/_shims/node-runtime.mjs.map +0 -1
- package/_shims/node-types.d.ts +0 -42
- package/_shims/node-types.js +0 -3
- package/_shims/node-types.mjs +0 -3
- package/_shims/registry.d.ts +0 -37
- package/_shims/registry.d.ts.map +0 -1
- package/_shims/registry.js +0 -41
- package/_shims/registry.js.map +0 -1
- package/_shims/registry.mjs +0 -37
- package/_shims/registry.mjs.map +0 -1
- package/_shims/web-runtime.d.ts +0 -5
- package/_shims/web-runtime.d.ts.map +0 -1
- package/_shims/web-runtime.js +0 -78
- package/_shims/web-runtime.js.map +0 -1
- package/_shims/web-runtime.mjs +0 -71
- package/_shims/web-runtime.mjs.map +0 -1
- package/_shims/web-types.d.ts +0 -83
- package/_shims/web-types.js +0 -3
- package/_shims/web-types.mjs +0 -3
- package/core.d.ts +0 -241
- package/core.d.ts.map +0 -1
- package/core.js +0 -908
- package/core.js.map +0 -1
- package/core.mjs +0 -876
- package/core.mjs.map +0 -1
- package/error.d.ts +0 -47
- package/error.d.ts.map +0 -1
- package/error.js +0 -113
- package/error.js.map +0 -1
- package/error.mjs +0 -97
- package/error.mjs.map +0 -1
- package/index.d.mts +0 -121
- package/index.d.ts +0 -121
- package/index.d.ts.map +0 -1
- package/index.js +0 -131
- package/index.js.map +0 -1
- package/index.mjs +0 -88
- package/index.mjs.map +0 -1
- package/resource.d.ts +0 -6
- package/resource.d.ts.map +0 -1
- package/resource.js +0 -11
- package/resource.js.map +0 -1
- package/resource.mjs +0 -7
- package/resource.mjs.map +0 -1
- package/resources/agents/agents.d.ts +0 -41
- package/resources/agents/agents.d.ts.map +0 -1
- package/resources/agents/agents.js +0 -74
- package/resources/agents/agents.js.map +0 -1
- package/resources/agents/agents.mjs +0 -47
- package/resources/agents/agents.mjs.map +0 -1
- package/resources/agents/index.d.ts +0 -3
- package/resources/agents/index.d.ts.map +0 -1
- package/resources/agents/index.js +0 -9
- package/resources/agents/index.js.map +0 -1
- package/resources/agents/index.mjs +0 -4
- package/resources/agents/index.mjs.map +0 -1
- package/resources/agents/tools.d.ts +0 -17
- package/resources/agents/tools.d.ts.map +0 -1
- package/resources/agents/tools.js +0 -19
- package/resources/agents/tools.js.map +0 -1
- package/resources/agents/tools.mjs +0 -15
- package/resources/agents/tools.mjs.map +0 -1
- package/resources/index.d.ts +0 -8
- package/resources/index.d.ts.map +0 -1
- package/resources/index.js +0 -19
- package/resources/index.js.map +0 -1
- package/resources/index.mjs +0 -9
- package/resources/index.mjs.map +0 -1
- package/resources/logs.d.ts +0 -13
- package/resources/logs.d.ts.map +0 -1
- package/resources/logs.js +0 -24
- package/resources/logs.js.map +0 -1
- package/resources/logs.mjs +0 -20
- package/resources/logs.mjs.map +0 -1
- package/resources/memory/index.d.ts +0 -4
- package/resources/memory/index.d.ts.map +0 -1
- package/resources/memory/index.js +0 -11
- package/resources/memory/index.js.map +0 -1
- package/resources/memory/index.mjs +0 -5
- package/resources/memory/index.mjs.map +0 -1
- package/resources/memory/memory.d.ts +0 -23
- package/resources/memory/memory.d.ts.map +0 -1
- package/resources/memory/memory.js +0 -53
- package/resources/memory/memory.js.map +0 -1
- package/resources/memory/memory.mjs +0 -26
- package/resources/memory/memory.mjs.map +0 -1
- package/resources/memory/status.d.ts +0 -9
- package/resources/memory/status.d.ts.map +0 -1
- package/resources/memory/status.js +0 -18
- package/resources/memory/status.js.map +0 -1
- package/resources/memory/status.mjs +0 -14
- package/resources/memory/status.mjs.map +0 -1
- package/resources/memory/threads/index.d.ts +0 -3
- package/resources/memory/threads/index.d.ts.map +0 -1
- package/resources/memory/threads/index.js +0 -9
- package/resources/memory/threads/index.js.map +0 -1
- package/resources/memory/threads/index.mjs +0 -4
- package/resources/memory/threads/index.mjs.map +0 -1
- package/resources/memory/threads/messages.d.ts +0 -9
- package/resources/memory/threads/messages.d.ts.map +0 -1
- package/resources/memory/threads/messages.js +0 -18
- package/resources/memory/threads/messages.js.map +0 -1
- package/resources/memory/threads/messages.mjs +0 -14
- package/resources/memory/threads/messages.mjs.map +0 -1
- package/resources/memory/threads/threads.d.ts +0 -45
- package/resources/memory/threads/threads.d.ts.map +0 -1
- package/resources/memory/threads/threads.js +0 -104
- package/resources/memory/threads/threads.js.map +0 -1
- package/resources/memory/threads/threads.mjs +0 -77
- package/resources/memory/threads/threads.mjs.map +0 -1
- package/resources/syncs.d.ts +0 -15
- package/resources/syncs.d.ts.map +0 -1
- package/resources/syncs.js +0 -19
- package/resources/syncs.js.map +0 -1
- package/resources/syncs.mjs +0 -15
- package/resources/syncs.mjs.map +0 -1
- package/resources/system.d.ts +0 -9
- package/resources/system.d.ts.map +0 -1
- package/resources/system.js +0 -15
- package/resources/system.js.map +0 -1
- package/resources/system.mjs +0 -11
- package/resources/system.mjs.map +0 -1
- package/resources/tools/index.d.ts +0 -3
- package/resources/tools/index.d.ts.map +0 -1
- package/resources/tools/index.js +0 -9
- package/resources/tools/index.js.map +0 -1
- package/resources/tools/index.mjs +0 -4
- package/resources/tools/index.mjs.map +0 -1
- package/resources/tools/result.d.ts +0 -9
- package/resources/tools/result.d.ts.map +0 -1
- package/resources/tools/result.js +0 -18
- package/resources/tools/result.js.map +0 -1
- package/resources/tools/result.mjs +0 -14
- package/resources/tools/result.mjs.map +0 -1
- package/resources/tools/tools.d.ts +0 -29
- package/resources/tools/tools.d.ts.map +0 -1
- package/resources/tools/tools.js +0 -64
- package/resources/tools/tools.js.map +0 -1
- package/resources/tools/tools.mjs +0 -37
- package/resources/tools/tools.mjs.map +0 -1
- package/resources/workflows.d.ts +0 -23
- package/resources/workflows.d.ts.map +0 -1
- package/resources/workflows.js +0 -37
- package/resources/workflows.js.map +0 -1
- package/resources/workflows.mjs +0 -33
- package/resources/workflows.mjs.map +0 -1
- package/shims/node.d.ts +0 -30
- package/shims/node.d.ts.map +0 -1
- package/shims/node.js +0 -31
- package/shims/node.js.map +0 -1
- package/shims/node.mjs +0 -5
- package/shims/node.mjs.map +0 -1
- package/shims/web.d.ts +0 -26
- package/shims/web.d.ts.map +0 -1
- package/shims/web.js +0 -31
- package/shims/web.js.map +0 -1
- package/shims/web.mjs +0 -5
- package/shims/web.mjs.map +0 -1
- package/src/_shims/MultipartBody.ts +0 -9
- package/src/_shims/README.md +0 -46
- package/src/_shims/auto/runtime-bun.ts +0 -4
- package/src/_shims/auto/runtime-node.ts +0 -4
- package/src/_shims/auto/runtime.ts +0 -4
- package/src/_shims/auto/types-node.ts +0 -4
- package/src/_shims/auto/types.d.ts +0 -101
- package/src/_shims/auto/types.js +0 -3
- package/src/_shims/auto/types.mjs +0 -3
- package/src/_shims/bun-runtime.ts +0 -14
- package/src/_shims/index.d.ts +0 -81
- package/src/_shims/index.js +0 -13
- package/src/_shims/index.mjs +0 -7
- package/src/_shims/manual-types.d.ts +0 -12
- package/src/_shims/manual-types.js +0 -3
- package/src/_shims/manual-types.mjs +0 -3
- package/src/_shims/node-runtime.ts +0 -81
- package/src/_shims/node-types.d.ts +0 -42
- package/src/_shims/node-types.js +0 -3
- package/src/_shims/node-types.mjs +0 -3
- package/src/_shims/registry.ts +0 -67
- package/src/_shims/web-runtime.ts +0 -103
- package/src/_shims/web-types.d.ts +0 -83
- package/src/_shims/web-types.js +0 -3
- package/src/_shims/web-types.mjs +0 -3
- package/src/core.ts +0 -1201
- package/src/error.ts +0 -130
- package/src/lib/.keep +0 -4
- package/src/resource.ts +0 -11
- package/src/resources/agents/agents.ts +0 -83
- package/src/resources/agents/index.ts +0 -4
- package/src/resources/agents/tools.ts +0 -34
- package/src/resources/logs.ts +0 -23
- package/src/resources/memory/index.ts +0 -5
- package/src/resources/memory/memory.ts +0 -43
- package/src/resources/memory/status.ts +0 -16
- package/src/resources/memory/threads/index.ts +0 -4
- package/src/resources/memory/threads/messages.ts +0 -16
- package/src/resources/memory/threads/threads.ts +0 -105
- package/src/resources/syncs.ts +0 -25
- package/src/resources/system.ts +0 -13
- package/src/resources/tools/index.ts +0 -4
- package/src/resources/tools/result.ts +0 -16
- package/src/resources/tools/tools.ts +0 -54
- package/src/resources/workflows.ts +0 -49
- package/src/shims/node.ts +0 -50
- package/src/shims/web.ts +0 -50
- package/src/tsconfig.json +0 -11
- package/src/uploads.ts +0 -255
- package/src/version.ts +0 -1
- package/uploads.d.ts +0 -75
- package/uploads.d.ts.map +0 -1
- package/uploads.js +0 -171
- package/uploads.js.map +0 -1
- package/uploads.mjs +0 -158
- package/uploads.mjs.map +0 -1
- package/version.d.ts +0 -2
- package/version.d.ts.map +0 -1
- package/version.js +0 -5
- package/version.js.map +0 -1
- package/version.mjs +0 -2
- package/version.mjs.map +0 -1
package/src/client.ts
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import type { ClientOptions, CreateMemoryThreadParams, CreateMemoryThreadResponse, GetAgentResponse, GetLogParams, GetLogsParams, GetLogsResponse, GetMemoryThreadParams, GetMemoryThreadResponse, GetToolResponse, GetWorkflowResponse, RequestOptions, SaveMessageToMemoryParams, SaveMessageToMemoryResponse } from './types';
|
|
2
|
+
import { Agent, MemoryThread, Tool, Workflow, Vector } from './resources';
|
|
3
|
+
|
|
4
|
+
export class MastraClient {
|
|
5
|
+
readonly baseUrl: string;
|
|
6
|
+
private readonly retries: number;
|
|
7
|
+
private readonly backoffMs: number;
|
|
8
|
+
private readonly maxBackoffMs: number;
|
|
9
|
+
private readonly headers: Record<string, string>;
|
|
10
|
+
|
|
11
|
+
constructor(options: ClientOptions) {
|
|
12
|
+
this.baseUrl = options.baseUrl.replace(/\/$/, '');
|
|
13
|
+
this.retries = options.retries ?? 3;
|
|
14
|
+
this.backoffMs = options.backoffMs ?? 300;
|
|
15
|
+
this.maxBackoffMs = options.maxBackoffMs ?? 5000;
|
|
16
|
+
this.headers = {
|
|
17
|
+
'Content-Type': 'application/json',
|
|
18
|
+
...options.headers,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Makes an HTTP request to the Mastra API
|
|
24
|
+
* @param path - API endpoint path
|
|
25
|
+
* @param options - Request options including method, headers, and body
|
|
26
|
+
* @returns Promise containing the API response
|
|
27
|
+
* @throws Error if the request fails after all retries
|
|
28
|
+
*/
|
|
29
|
+
async request(path: string, options: RequestOptions = {}): Promise<any> {
|
|
30
|
+
const url = `${this.baseUrl}${path}`;
|
|
31
|
+
let lastError: Error | null = null;
|
|
32
|
+
let currentBackoff = this.backoffMs;
|
|
33
|
+
|
|
34
|
+
for (let attempt = 0; attempt <= this.retries; attempt++) {
|
|
35
|
+
try {
|
|
36
|
+
const response = await fetch(url, {
|
|
37
|
+
method: options.method ?? 'GET',
|
|
38
|
+
headers: {
|
|
39
|
+
...this.headers,
|
|
40
|
+
...options.headers,
|
|
41
|
+
},
|
|
42
|
+
body: options.body ? JSON.stringify(options.body) : undefined,
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
if (!response.ok) {
|
|
46
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return await response.json();
|
|
50
|
+
} catch (error) {
|
|
51
|
+
lastError = error as Error;
|
|
52
|
+
if (attempt === this.retries) break;
|
|
53
|
+
|
|
54
|
+
await new Promise(resolve => setTimeout(resolve, currentBackoff));
|
|
55
|
+
currentBackoff = Math.min(currentBackoff * 2, this.maxBackoffMs);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
throw lastError;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Retrieves all available agents
|
|
64
|
+
* @returns Promise containing map of agent IDs to agent details
|
|
65
|
+
*/
|
|
66
|
+
public getAgents(): Promise<Record<string, GetAgentResponse>> {
|
|
67
|
+
return this.request('/api/agents');
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Gets an agent instance by ID
|
|
72
|
+
* @param agentId - ID of the agent to retrieve
|
|
73
|
+
* @returns Agent instance
|
|
74
|
+
*/
|
|
75
|
+
public getAgent(agentId: string) {
|
|
76
|
+
return new Agent(
|
|
77
|
+
(path: string, options?: RequestOptions) => this.request(path, options),
|
|
78
|
+
agentId
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Retrieves memory threads for a resource
|
|
84
|
+
* @param params - Parameters containing the resource ID
|
|
85
|
+
* @returns Promise containing array of memory threads
|
|
86
|
+
*/
|
|
87
|
+
public getMemoryThreads(params: GetMemoryThreadParams): Promise<GetMemoryThreadResponse> {
|
|
88
|
+
return this.request(`/api/memory/threads?resourceid=${params.resourceId}`);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Creates a new memory thread
|
|
93
|
+
* @param params - Parameters for creating the memory thread
|
|
94
|
+
* @returns Promise containing the created memory thread
|
|
95
|
+
*/
|
|
96
|
+
public createMemoryThread(params: CreateMemoryThreadParams): Promise<CreateMemoryThreadResponse> {
|
|
97
|
+
return this.request('/api/memory/threads', { method: 'POST', body: params });
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Gets a memory thread instance by ID
|
|
102
|
+
* @param threadId - ID of the memory thread to retrieve
|
|
103
|
+
* @returns MemoryThread instance
|
|
104
|
+
*/
|
|
105
|
+
public getMemoryThread(threadId: string) {
|
|
106
|
+
return new MemoryThread(
|
|
107
|
+
(path: string, options?: RequestOptions) => this.request(path, options),
|
|
108
|
+
threadId
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Saves messages to memory
|
|
114
|
+
* @param params - Parameters containing messages to save
|
|
115
|
+
* @returns Promise containing the saved messages
|
|
116
|
+
*/
|
|
117
|
+
public saveMessageToMemory(params: SaveMessageToMemoryParams): Promise<SaveMessageToMemoryResponse> {
|
|
118
|
+
return this.request('/api/memory/save-messages', {
|
|
119
|
+
method: 'POST',
|
|
120
|
+
body: params,
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Gets the status of the memory system
|
|
126
|
+
* @returns Promise containing memory system status
|
|
127
|
+
*/
|
|
128
|
+
public getMemoryStatus(): Promise<{ result: boolean }> {
|
|
129
|
+
return this.request('/api/memory/status');
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Retrieves all available tools
|
|
134
|
+
* @returns Promise containing map of tool IDs to tool details
|
|
135
|
+
*/
|
|
136
|
+
public getTools(): Promise<Record<string, GetToolResponse>> {
|
|
137
|
+
return this.request('/api/tools');
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Gets a tool instance by ID
|
|
142
|
+
* @param toolId - ID of the tool to retrieve
|
|
143
|
+
* @returns Tool instance
|
|
144
|
+
*/
|
|
145
|
+
public getTool(toolId: string) {
|
|
146
|
+
return new Tool(
|
|
147
|
+
(path: string, options?: RequestOptions) => this.request(path, options),
|
|
148
|
+
toolId
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Retrieves all available workflows
|
|
154
|
+
* @returns Promise containing map of workflow IDs to workflow details
|
|
155
|
+
*/
|
|
156
|
+
public getWorkflows(): Promise<Record<string, GetWorkflowResponse>> {
|
|
157
|
+
return this.request('/api/workflows');
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Gets a workflow instance by ID
|
|
162
|
+
* @param workflowId - ID of the workflow to retrieve
|
|
163
|
+
* @returns Workflow instance
|
|
164
|
+
*/
|
|
165
|
+
public getWorkflow(workflowId: string) {
|
|
166
|
+
return new Workflow(
|
|
167
|
+
(path: string, options?: RequestOptions) => this.request(path, options),
|
|
168
|
+
workflowId
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Gets a vector instance by name
|
|
174
|
+
* @param vectorName - Name of the vector to retrieve
|
|
175
|
+
* @returns Vector instance
|
|
176
|
+
*/
|
|
177
|
+
public getVector(vectorName: string) {
|
|
178
|
+
return new Vector(
|
|
179
|
+
(path: string, options?: RequestOptions) => this.request(path, options),
|
|
180
|
+
vectorName
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Retrieves logs
|
|
186
|
+
* @param params - Parameters for filtering logs
|
|
187
|
+
* @returns Promise containing array of log messages
|
|
188
|
+
*/
|
|
189
|
+
public getLogs(params: GetLogsParams): Promise<GetLogsResponse> {
|
|
190
|
+
return this.request(`/api/logs?transportId=${params.transportId}`);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Gets logs for a specific run
|
|
195
|
+
* @param params - Parameters containing run ID to retrieve
|
|
196
|
+
* @returns Promise containing array of log messages
|
|
197
|
+
*/
|
|
198
|
+
public getLogForRun(params: GetLogParams): Promise<GetLogsResponse> {
|
|
199
|
+
return this.request(`/api/logs/${params.runId}?transportId=${params.transportId}`);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
@@ -0,0 +1,507 @@
|
|
|
1
|
+
import { describe, expect, beforeEach, it, vi } from 'vitest';
|
|
2
|
+
import { MastraClient } from "./client";
|
|
3
|
+
import type { MessageType } from '@mastra/core';
|
|
4
|
+
|
|
5
|
+
// Mock fetch globally
|
|
6
|
+
global.fetch = vi.fn();
|
|
7
|
+
|
|
8
|
+
describe('MastraClient Resources', () => {
|
|
9
|
+
let client: MastraClient;
|
|
10
|
+
|
|
11
|
+
// Helper to mock successful API responses
|
|
12
|
+
const mockFetchResponse = (data: any) => {
|
|
13
|
+
(global.fetch as any).mockResolvedValueOnce({
|
|
14
|
+
ok: true,
|
|
15
|
+
json: async () => data
|
|
16
|
+
});
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
beforeEach(() => {
|
|
20
|
+
// Reset mocks
|
|
21
|
+
vi.clearAllMocks();
|
|
22
|
+
|
|
23
|
+
// Create fresh client for each test
|
|
24
|
+
client = new MastraClient({
|
|
25
|
+
baseUrl: 'http://localhost:4111',
|
|
26
|
+
headers: {
|
|
27
|
+
'Authorization': 'Bearer test-key'
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
describe('Vector Resource', () => {
|
|
33
|
+
const vectorName = 'test-vector';
|
|
34
|
+
let vector: ReturnType<typeof client.getVector>;
|
|
35
|
+
|
|
36
|
+
beforeEach(() => {
|
|
37
|
+
vector = client.getVector(vectorName);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('should get vector index details', async () => {
|
|
41
|
+
const mockResponse = {
|
|
42
|
+
dimension: 128,
|
|
43
|
+
metric: 'cosine',
|
|
44
|
+
count: 1000
|
|
45
|
+
};
|
|
46
|
+
mockFetchResponse(mockResponse);
|
|
47
|
+
|
|
48
|
+
const result = await vector.details('test-index');
|
|
49
|
+
expect(result).toEqual(mockResponse);
|
|
50
|
+
expect(global.fetch).toHaveBeenCalledWith(
|
|
51
|
+
`${client.baseUrl}/api/vector/test-vector/indexes/test-index`,
|
|
52
|
+
expect.any(Object)
|
|
53
|
+
);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('should delete vector index', async () => {
|
|
57
|
+
mockFetchResponse({ success: true });
|
|
58
|
+
const result = await vector.delete('test-index');
|
|
59
|
+
expect(result).toEqual({ success: true });
|
|
60
|
+
expect(global.fetch).toHaveBeenCalledWith(
|
|
61
|
+
`${client.baseUrl}/api/vector/test-vector/indexes/test-index`,
|
|
62
|
+
expect.objectContaining({ method: 'DELETE' })
|
|
63
|
+
);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('should get all indexes', async () => {
|
|
67
|
+
const mockResponse = { indexes: ['index1', 'index2'] };
|
|
68
|
+
mockFetchResponse(mockResponse);
|
|
69
|
+
const result = await vector.getIndexes();
|
|
70
|
+
expect(result).toEqual(mockResponse);
|
|
71
|
+
expect(global.fetch).toHaveBeenCalledWith(
|
|
72
|
+
`${client.baseUrl}/api/vector/test-vector/indexes`,
|
|
73
|
+
expect.any(Object)
|
|
74
|
+
);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('should create vector index with all parameters', async () => {
|
|
78
|
+
mockFetchResponse({ success: true });
|
|
79
|
+
const result = await vector.createIndex({
|
|
80
|
+
indexName: 'test-index',
|
|
81
|
+
dimension: 128,
|
|
82
|
+
metric: 'cosine'
|
|
83
|
+
});
|
|
84
|
+
expect(result).toEqual({ success: true });
|
|
85
|
+
expect(global.fetch).toHaveBeenCalledWith(
|
|
86
|
+
`${client.baseUrl}/api/vector/test-vector/create-index`,
|
|
87
|
+
expect.objectContaining({
|
|
88
|
+
method: 'POST',
|
|
89
|
+
body: JSON.stringify({
|
|
90
|
+
indexName: 'test-index',
|
|
91
|
+
dimension: 128,
|
|
92
|
+
metric: 'cosine'
|
|
93
|
+
})
|
|
94
|
+
})
|
|
95
|
+
);
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it('should upsert vectors with metadata and ids', async () => {
|
|
99
|
+
const mockResponse = ['id1', 'id2'];
|
|
100
|
+
mockFetchResponse(mockResponse);
|
|
101
|
+
const result = await vector.upsert({
|
|
102
|
+
indexName: 'test-index',
|
|
103
|
+
vectors: [[1, 2], [3, 4]],
|
|
104
|
+
metadata: [{ label: 'a' }, { label: 'b' }],
|
|
105
|
+
ids: ['id1', 'id2']
|
|
106
|
+
});
|
|
107
|
+
expect(result).toEqual(mockResponse);
|
|
108
|
+
expect(global.fetch).toHaveBeenCalledWith(
|
|
109
|
+
`${client.baseUrl}/api/vector/test-vector/upsert`,
|
|
110
|
+
expect.objectContaining({
|
|
111
|
+
method: 'POST',
|
|
112
|
+
body: JSON.stringify({
|
|
113
|
+
indexName: 'test-index',
|
|
114
|
+
vectors: [[1, 2], [3, 4]],
|
|
115
|
+
metadata: [{ label: 'a' }, { label: 'b' }],
|
|
116
|
+
ids: ['id1', 'id2']
|
|
117
|
+
})
|
|
118
|
+
})
|
|
119
|
+
);
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
it('should query vectors with all parameters', async () => {
|
|
123
|
+
const mockResponse = {
|
|
124
|
+
results: [{
|
|
125
|
+
id: 'id1',
|
|
126
|
+
score: 0.9,
|
|
127
|
+
metadata: { label: 'a' },
|
|
128
|
+
vector: [1, 2]
|
|
129
|
+
}]
|
|
130
|
+
};
|
|
131
|
+
mockFetchResponse(mockResponse);
|
|
132
|
+
const result = await vector.query({
|
|
133
|
+
indexName: 'test-index',
|
|
134
|
+
queryVector: [1, 2],
|
|
135
|
+
topK: 10,
|
|
136
|
+
filter: { label: 'a' },
|
|
137
|
+
includeVector: true
|
|
138
|
+
});
|
|
139
|
+
expect(result).toEqual(mockResponse);
|
|
140
|
+
expect(global.fetch).toHaveBeenCalledWith(
|
|
141
|
+
`${client.baseUrl}/api/vector/test-vector/query`,
|
|
142
|
+
expect.objectContaining({
|
|
143
|
+
method: 'POST',
|
|
144
|
+
body: JSON.stringify({
|
|
145
|
+
indexName: 'test-index',
|
|
146
|
+
queryVector: [1, 2],
|
|
147
|
+
topK: 10,
|
|
148
|
+
filter: { label: 'a' },
|
|
149
|
+
includeVector: true
|
|
150
|
+
})
|
|
151
|
+
})
|
|
152
|
+
);
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
describe('Agent Resource', () => {
|
|
157
|
+
const agentId = 'test-agent';
|
|
158
|
+
let agent: ReturnType<typeof client.getAgent>;
|
|
159
|
+
|
|
160
|
+
beforeEach(() => {
|
|
161
|
+
agent = client.getAgent(agentId);
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
it('should get all agents', async () => {
|
|
165
|
+
const mockResponse = {
|
|
166
|
+
'agent1': { name: 'Agent 1', model: 'gpt-4' },
|
|
167
|
+
'agent2': { name: 'Agent 2', model: 'gpt-3.5' }
|
|
168
|
+
};
|
|
169
|
+
mockFetchResponse(mockResponse);
|
|
170
|
+
const result = await client.getAgents();
|
|
171
|
+
expect(result).toEqual(mockResponse);
|
|
172
|
+
expect(global.fetch).toHaveBeenCalledWith(
|
|
173
|
+
`${client.baseUrl}/api/agents`,
|
|
174
|
+
expect.any(Object)
|
|
175
|
+
);
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
it('should get agent details', async () => {
|
|
179
|
+
const mockResponse = {
|
|
180
|
+
name: 'Test Agent',
|
|
181
|
+
model: 'gpt-4',
|
|
182
|
+
instructions: 'Test instructions',
|
|
183
|
+
tools: {}
|
|
184
|
+
};
|
|
185
|
+
mockFetchResponse(mockResponse);
|
|
186
|
+
|
|
187
|
+
const result = await agent.details();
|
|
188
|
+
expect(result).toEqual(mockResponse);
|
|
189
|
+
expect(global.fetch).toHaveBeenCalledWith(
|
|
190
|
+
`${client.baseUrl}/api/agents/test-agent`,
|
|
191
|
+
expect.any(Object)
|
|
192
|
+
);
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
it('should generate response', async () => {
|
|
196
|
+
const mockResponse = {
|
|
197
|
+
response: 'Generated response'
|
|
198
|
+
};
|
|
199
|
+
mockFetchResponse(mockResponse);
|
|
200
|
+
|
|
201
|
+
const result = await agent.generate({ prompt: 'Test prompt' });
|
|
202
|
+
expect(result).toEqual(mockResponse);
|
|
203
|
+
expect(global.fetch).toHaveBeenCalledWith(
|
|
204
|
+
`${client.baseUrl}/api/agents/test-agent/generate`,
|
|
205
|
+
expect.objectContaining({
|
|
206
|
+
method: 'POST',
|
|
207
|
+
body: JSON.stringify({ prompt: 'Test prompt' })
|
|
208
|
+
})
|
|
209
|
+
);
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
it('should stream responses', async () => {
|
|
213
|
+
const mockResponse = {
|
|
214
|
+
stream: true,
|
|
215
|
+
chunks: ['chunk1', 'chunk2']
|
|
216
|
+
};
|
|
217
|
+
mockFetchResponse(mockResponse);
|
|
218
|
+
const result = await agent.stream({ prompt: 'Test prompt' });
|
|
219
|
+
expect(result).toEqual(mockResponse);
|
|
220
|
+
expect(global.fetch).toHaveBeenCalledWith(
|
|
221
|
+
`${client.baseUrl}/api/agents/test-agent/generate`,
|
|
222
|
+
expect.objectContaining({
|
|
223
|
+
method: 'POST',
|
|
224
|
+
body: JSON.stringify({ prompt: 'Test prompt', stream: true })
|
|
225
|
+
})
|
|
226
|
+
);
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
it('should get agent tool', async () => {
|
|
230
|
+
const mockResponse = {
|
|
231
|
+
id: 'tool1',
|
|
232
|
+
description: 'Test Tool'
|
|
233
|
+
};
|
|
234
|
+
mockFetchResponse(mockResponse);
|
|
235
|
+
const result = await agent.getTool('tool1');
|
|
236
|
+
expect(result).toEqual(mockResponse);
|
|
237
|
+
expect(global.fetch).toHaveBeenCalledWith(
|
|
238
|
+
`${client.baseUrl}/api/agents/test-agent/tools/tool1`,
|
|
239
|
+
expect.any(Object)
|
|
240
|
+
);
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
it('should get agent evals', async () => {
|
|
244
|
+
const mockResponse = {
|
|
245
|
+
name: 'Test Agent',
|
|
246
|
+
evals: [{ id: 'eval1' }]
|
|
247
|
+
};
|
|
248
|
+
mockFetchResponse(mockResponse);
|
|
249
|
+
const result = await agent.evals();
|
|
250
|
+
expect(result).toEqual(mockResponse);
|
|
251
|
+
expect(global.fetch).toHaveBeenCalledWith(
|
|
252
|
+
`${client.baseUrl}/api/agents/test-agent/evals`,
|
|
253
|
+
expect.any(Object)
|
|
254
|
+
);
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
it('should get live evals', async () => {
|
|
258
|
+
const mockResponse = {
|
|
259
|
+
name: 'Test Agent',
|
|
260
|
+
evals: [{ id: 'eval1', live: true }]
|
|
261
|
+
};
|
|
262
|
+
mockFetchResponse(mockResponse);
|
|
263
|
+
const result = await agent.liveEvals();
|
|
264
|
+
expect(result).toEqual(mockResponse);
|
|
265
|
+
expect(global.fetch).toHaveBeenCalledWith(
|
|
266
|
+
`${client.baseUrl}/api/agents/test-agent/evals/live`,
|
|
267
|
+
expect.any(Object)
|
|
268
|
+
);
|
|
269
|
+
});
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
describe('Memory Thread Resource', () => {
|
|
273
|
+
const threadId = 'test-thread';
|
|
274
|
+
let memoryThread: ReturnType<typeof client.getMemoryThread>;
|
|
275
|
+
|
|
276
|
+
beforeEach(() => {
|
|
277
|
+
memoryThread = client.getMemoryThread(threadId);
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
it('should get thread details', async () => {
|
|
281
|
+
const mockResponse = {
|
|
282
|
+
id: threadId,
|
|
283
|
+
title: 'Test Thread',
|
|
284
|
+
metadata: {}
|
|
285
|
+
};
|
|
286
|
+
mockFetchResponse(mockResponse);
|
|
287
|
+
|
|
288
|
+
const result = await memoryThread.get();
|
|
289
|
+
expect(result).toEqual(mockResponse);
|
|
290
|
+
expect(global.fetch).toHaveBeenCalledWith(
|
|
291
|
+
`${client.baseUrl}/api/memory/threads/test-thread`,
|
|
292
|
+
expect.any(Object)
|
|
293
|
+
);
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
it('should update thread', async () => {
|
|
297
|
+
const mockResponse = {
|
|
298
|
+
id: threadId,
|
|
299
|
+
title: 'Updated Thread',
|
|
300
|
+
metadata: { updated: true }
|
|
301
|
+
};
|
|
302
|
+
mockFetchResponse(mockResponse);
|
|
303
|
+
|
|
304
|
+
const result = await memoryThread.update({
|
|
305
|
+
title: 'Updated Thread',
|
|
306
|
+
metadata: { updated: true },
|
|
307
|
+
resourceid: 'test-resource'
|
|
308
|
+
});
|
|
309
|
+
expect(result).toEqual(mockResponse);
|
|
310
|
+
expect(global.fetch).toHaveBeenCalledWith(
|
|
311
|
+
`${client.baseUrl}/api/memory/threads/test-thread`,
|
|
312
|
+
expect.objectContaining({
|
|
313
|
+
method: 'PATCH'
|
|
314
|
+
})
|
|
315
|
+
);
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
it('should delete thread', async () => {
|
|
319
|
+
const mockResponse = { result: 'deleted' };
|
|
320
|
+
mockFetchResponse(mockResponse);
|
|
321
|
+
const result = await memoryThread.delete();
|
|
322
|
+
expect(result).toEqual(mockResponse);
|
|
323
|
+
expect(global.fetch).toHaveBeenCalledWith(
|
|
324
|
+
`${client.baseUrl}/api/memory/threads/test-thread`,
|
|
325
|
+
expect.objectContaining({ method: 'DELETE' })
|
|
326
|
+
);
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
it('should get memory status', async () => {
|
|
330
|
+
const mockResponse = { result: true };
|
|
331
|
+
mockFetchResponse(mockResponse);
|
|
332
|
+
const result = await client.getMemoryStatus();
|
|
333
|
+
expect(result).toEqual(mockResponse);
|
|
334
|
+
expect(global.fetch).toHaveBeenCalledWith(
|
|
335
|
+
`${client.baseUrl}/api/memory/status`,
|
|
336
|
+
expect.any(Object)
|
|
337
|
+
);
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
it('should save messages to memory', async () => {
|
|
341
|
+
const messages: MessageType[] = [{
|
|
342
|
+
id: '1',
|
|
343
|
+
type: 'text',
|
|
344
|
+
content: 'test',
|
|
345
|
+
role: 'user',
|
|
346
|
+
threadId: 'test-thread',
|
|
347
|
+
createdAt: new Date()
|
|
348
|
+
}];
|
|
349
|
+
mockFetchResponse(messages);
|
|
350
|
+
const result = await client.saveMessageToMemory({ messages });
|
|
351
|
+
expect(result).toEqual(messages);
|
|
352
|
+
expect(global.fetch).toHaveBeenCalledWith(
|
|
353
|
+
`${client.baseUrl}/api/memory/save-messages`,
|
|
354
|
+
expect.objectContaining({
|
|
355
|
+
method: 'POST',
|
|
356
|
+
body: JSON.stringify({ messages })
|
|
357
|
+
})
|
|
358
|
+
);
|
|
359
|
+
});
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
describe('Tool Resource', () => {
|
|
363
|
+
const toolId = 'test-tool';
|
|
364
|
+
let tool: ReturnType<typeof client.getTool>;
|
|
365
|
+
|
|
366
|
+
beforeEach(() => {
|
|
367
|
+
tool = client.getTool(toolId);
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
it('should get tool details', async () => {
|
|
371
|
+
const mockResponse = {
|
|
372
|
+
id: toolId,
|
|
373
|
+
description: 'Test Tool',
|
|
374
|
+
inputSchema: '{}',
|
|
375
|
+
outputSchema: '{}'
|
|
376
|
+
};
|
|
377
|
+
mockFetchResponse(mockResponse);
|
|
378
|
+
|
|
379
|
+
const result = await tool.details();
|
|
380
|
+
expect(result).toEqual(mockResponse);
|
|
381
|
+
expect(global.fetch).toHaveBeenCalledWith(
|
|
382
|
+
`${client.baseUrl}/api/tools/test-tool`,
|
|
383
|
+
expect.any(Object)
|
|
384
|
+
);
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
it('should execute tool', async () => {
|
|
388
|
+
const mockResponse = {
|
|
389
|
+
result: 'Tool execution result'
|
|
390
|
+
};
|
|
391
|
+
mockFetchResponse(mockResponse);
|
|
392
|
+
|
|
393
|
+
const result = await tool.execute({ input: 'test' });
|
|
394
|
+
expect(result).toEqual(mockResponse);
|
|
395
|
+
expect(global.fetch).toHaveBeenCalledWith(
|
|
396
|
+
`${client.baseUrl}/api/tools/test-tool/execute`,
|
|
397
|
+
expect.objectContaining({
|
|
398
|
+
method: 'POST',
|
|
399
|
+
body: JSON.stringify({ input: 'test' })
|
|
400
|
+
})
|
|
401
|
+
);
|
|
402
|
+
});
|
|
403
|
+
});
|
|
404
|
+
|
|
405
|
+
describe('Workflow Resource', () => {
|
|
406
|
+
const workflowId = 'test-workflow';
|
|
407
|
+
let workflow: ReturnType<typeof client.getWorkflow>;
|
|
408
|
+
|
|
409
|
+
beforeEach(() => {
|
|
410
|
+
workflow = client.getWorkflow(workflowId);
|
|
411
|
+
});
|
|
412
|
+
|
|
413
|
+
it('should get workflow details', async () => {
|
|
414
|
+
const mockResponse = {
|
|
415
|
+
name: 'Test Workflow',
|
|
416
|
+
triggerSchema: '{}',
|
|
417
|
+
steps: {},
|
|
418
|
+
stepGraph: {},
|
|
419
|
+
stepSubscriberGraph: {}
|
|
420
|
+
};
|
|
421
|
+
mockFetchResponse(mockResponse);
|
|
422
|
+
|
|
423
|
+
const result = await workflow.details();
|
|
424
|
+
expect(result).toEqual(mockResponse);
|
|
425
|
+
expect(global.fetch).toHaveBeenCalledWith(
|
|
426
|
+
`${client.baseUrl}/api/workflows/test-workflow`,
|
|
427
|
+
expect.any(Object)
|
|
428
|
+
);
|
|
429
|
+
});
|
|
430
|
+
|
|
431
|
+
it('should execute workflow', async () => {
|
|
432
|
+
const mockResponse = {
|
|
433
|
+
result: 'Workflow execution result'
|
|
434
|
+
};
|
|
435
|
+
mockFetchResponse(mockResponse);
|
|
436
|
+
|
|
437
|
+
const result = await workflow.execute({ trigger: 'test' });
|
|
438
|
+
expect(result).toEqual(mockResponse);
|
|
439
|
+
expect(global.fetch).toHaveBeenCalledWith(
|
|
440
|
+
`${client.baseUrl}/api/workflows/test-workflow/execute`,
|
|
441
|
+
expect.objectContaining({
|
|
442
|
+
method: 'POST',
|
|
443
|
+
body: JSON.stringify({ trigger: 'test' })
|
|
444
|
+
})
|
|
445
|
+
);
|
|
446
|
+
});
|
|
447
|
+
});
|
|
448
|
+
|
|
449
|
+
describe('Client Error Handling', () => {
|
|
450
|
+
it('should retry failed requests', async () => {
|
|
451
|
+
// Mock first two calls to fail, third to succeed
|
|
452
|
+
(global.fetch as any)
|
|
453
|
+
.mockRejectedValueOnce(new Error('Network error'))
|
|
454
|
+
.mockRejectedValueOnce(new Error('Network error'))
|
|
455
|
+
.mockResolvedValueOnce({
|
|
456
|
+
ok: true,
|
|
457
|
+
json: async () => ({ success: true })
|
|
458
|
+
});
|
|
459
|
+
|
|
460
|
+
const result = await client.request('/test-endpoint');
|
|
461
|
+
expect(result).toEqual({ success: true });
|
|
462
|
+
expect(global.fetch).toHaveBeenCalledTimes(3);
|
|
463
|
+
});
|
|
464
|
+
|
|
465
|
+
it('should throw error after max retries', async () => {
|
|
466
|
+
(global.fetch as any).mockRejectedValue(new Error('Network error'));
|
|
467
|
+
|
|
468
|
+
await expect(client.request('/test-endpoint'))
|
|
469
|
+
.rejects
|
|
470
|
+
.toThrow('Network error');
|
|
471
|
+
|
|
472
|
+
expect(global.fetch).toHaveBeenCalledTimes(4);
|
|
473
|
+
});
|
|
474
|
+
});
|
|
475
|
+
|
|
476
|
+
describe('Client Configuration', () => {
|
|
477
|
+
it('should handle custom retry configuration', async () => {
|
|
478
|
+
const customClient = new MastraClient({
|
|
479
|
+
baseUrl: 'http://localhost:4111',
|
|
480
|
+
retries: 2,
|
|
481
|
+
backoffMs: 100,
|
|
482
|
+
maxBackoffMs: 1000,
|
|
483
|
+
headers: { 'Custom-Header': 'value' }
|
|
484
|
+
});
|
|
485
|
+
|
|
486
|
+
(global.fetch as any)
|
|
487
|
+
.mockRejectedValueOnce(new Error('Network error'))
|
|
488
|
+
.mockRejectedValueOnce(new Error('Network error'))
|
|
489
|
+
.mockResolvedValueOnce({
|
|
490
|
+
ok: true,
|
|
491
|
+
json: async () => ({ success: true })
|
|
492
|
+
});
|
|
493
|
+
|
|
494
|
+
const result = await customClient.request('/test');
|
|
495
|
+
expect(result).toEqual({ success: true });
|
|
496
|
+
expect(global.fetch).toHaveBeenCalledTimes(3);
|
|
497
|
+
expect(global.fetch).toHaveBeenCalledWith(
|
|
498
|
+
'http://localhost:4111/test',
|
|
499
|
+
expect.objectContaining({
|
|
500
|
+
headers: expect.objectContaining({
|
|
501
|
+
'Custom-Header': 'value'
|
|
502
|
+
})
|
|
503
|
+
})
|
|
504
|
+
);
|
|
505
|
+
});
|
|
506
|
+
});
|
|
507
|
+
});
|