@mastra/client-js 0.0.0-storage-20250225005900 → 0.0.0-trigger-playground-ui-package-20250506151043

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/src/index.test.ts CHANGED
@@ -1,4 +1,3 @@
1
- import type { MessageType } from '@mastra/core';
2
1
  import { describe, expect, beforeEach, it, vi } from 'vitest';
3
2
 
4
3
  import { MastraClient } from './client';
@@ -12,33 +11,51 @@ describe('MastraClient Resources', () => {
12
11
  baseUrl: 'http://localhost:4111',
13
12
  headers: {
14
13
  Authorization: 'Bearer test-key',
14
+ 'x-mastra-client-type': 'js',
15
15
  },
16
16
  };
17
17
 
18
18
  // Helper to mock successful API responses
19
19
  const mockFetchResponse = (data: any, options: { isStream?: boolean } = {}) => {
20
20
  if (options.isStream) {
21
- const stream = new ReadableStream({
22
- start(controller) {
23
- controller.enqueue(new TextEncoder().encode(JSON.stringify(data)));
24
- controller.close();
25
- },
26
- });
27
- (global.fetch as any).mockResolvedValueOnce({
28
- ok: true,
29
- headers: {
30
- get: (name: string) => (name === 'Content-Type' ? 'text/event-stream' : null),
31
- },
32
- body: stream,
33
- });
21
+ let contentType = 'text/event-stream';
22
+ let responseBody: ReadableStream;
23
+
24
+ if (data instanceof ReadableStream) {
25
+ responseBody = data;
26
+ contentType = 'audio/mp3';
27
+ } else {
28
+ responseBody = new ReadableStream({
29
+ start(controller) {
30
+ controller.enqueue(new TextEncoder().encode(JSON.stringify(data)));
31
+ controller.close();
32
+ },
33
+ });
34
+ }
35
+
36
+ const headers = new Headers();
37
+ if (contentType === 'audio/mp3') {
38
+ headers.set('Transfer-Encoding', 'chunked');
39
+ }
40
+ headers.set('Content-Type', contentType);
41
+
42
+ (global.fetch as any).mockResolvedValueOnce(
43
+ new Response(responseBody, {
44
+ status: 200,
45
+ statusText: 'OK',
46
+ headers,
47
+ }),
48
+ );
34
49
  } else {
35
- (global.fetch as any).mockResolvedValueOnce({
36
- ok: true,
37
- headers: {
38
- get: (name: string) => (name === 'Content-Type' ? 'application/json' : null),
39
- },
40
- json: async () => data,
50
+ const response = new Response(undefined, {
51
+ status: 200,
52
+ statusText: 'OK',
53
+ headers: new Headers({
54
+ 'Content-Type': 'application/json',
55
+ }),
41
56
  });
57
+ response.json = () => Promise.resolve(data);
58
+ (global.fetch as any).mockResolvedValueOnce(response);
42
59
  }
43
60
  };
44
61
 
@@ -241,7 +258,7 @@ describe('MastraClient Resources', () => {
241
258
  const result = await agent.generate({
242
259
  messages: [],
243
260
  threadId: 'test-thread',
244
- resourceid: 'test-resource',
261
+ resourceId: 'test-resource',
245
262
  output: {},
246
263
  });
247
264
  expect(result).toEqual(mockResponse);
@@ -253,7 +270,7 @@ describe('MastraClient Resources', () => {
253
270
  body: JSON.stringify({
254
271
  messages: [],
255
272
  threadId: 'test-thread',
256
- resourceid: 'test-resource',
273
+ resourceId: 'test-resource',
257
274
  output: {},
258
275
  }),
259
276
  }),
@@ -301,19 +318,18 @@ describe('MastraClient Resources', () => {
301
318
  });
302
319
 
303
320
  it('should get agent evals', async () => {
304
- const mockResponse = {
305
- name: 'Test Agent',
306
- evals: [{ id: 'eval1' }],
307
- };
321
+ const mockResponse = { data: 'test' };
308
322
  mockFetchResponse(mockResponse);
309
323
  const result = await agent.evals();
310
324
  expect(result).toEqual(mockResponse);
311
- expect(global.fetch).toHaveBeenCalledWith(`${clientOptions.baseUrl}/api/agents/test-agent/evals/ci`, {
312
- headers: {
313
- Authorization: 'Bearer test-key',
314
- 'Content-Type': 'application/json',
315
- },
316
- });
325
+ expect(global.fetch).toHaveBeenCalledWith(
326
+ `${clientOptions.baseUrl}/api/agents/test-agent/evals/ci`,
327
+ expect.objectContaining({
328
+ headers: expect.objectContaining({
329
+ Authorization: 'Bearer test-key',
330
+ }),
331
+ }),
332
+ );
317
333
  });
318
334
 
319
335
  it('should get live evals', async () => {
@@ -333,6 +349,106 @@ describe('MastraClient Resources', () => {
333
349
  });
334
350
  });
335
351
 
352
+ describe('Agent Voice Resource', () => {
353
+ const agentId = 'test-agent';
354
+ let agent: ReturnType<typeof client.getAgent>;
355
+ beforeEach(() => {
356
+ agent = client.getAgent(agentId);
357
+ });
358
+ it('should get available speakers', async () => {
359
+ const mockResponse = [{ voiceId: 'speaker1' }];
360
+ mockFetchResponse(mockResponse);
361
+
362
+ const result = await agent.voice.getSpeakers();
363
+
364
+ expect(result).toEqual(mockResponse);
365
+ expect(global.fetch).toHaveBeenCalledWith(
366
+ `${clientOptions.baseUrl}/api/agents/test-agent/voice/speakers`,
367
+ expect.objectContaining({
368
+ headers: expect.objectContaining(clientOptions.headers),
369
+ }),
370
+ );
371
+ });
372
+
373
+ it(`should call speak without options`, async () => {
374
+ const mockAudioStream = new ReadableStream();
375
+ mockFetchResponse(mockAudioStream, { isStream: true });
376
+
377
+ const result = await agent.voice.speak('test');
378
+
379
+ expect(result).toBeInstanceOf(Response);
380
+ expect(result.body).toBeInstanceOf(ReadableStream);
381
+ expect(global.fetch).toHaveBeenCalledWith(
382
+ `${clientOptions.baseUrl}/api/agents/test-agent/voice/speak`,
383
+ expect.objectContaining({
384
+ method: 'POST',
385
+ headers: expect.objectContaining(clientOptions.headers),
386
+ }),
387
+ );
388
+ });
389
+
390
+ it(`should call speak with options`, async () => {
391
+ const mockAudioStream = new ReadableStream();
392
+ mockFetchResponse(mockAudioStream, { isStream: true });
393
+
394
+ const result = await agent.voice.speak('test', { speaker: 'speaker1' });
395
+ expect(result).toBeInstanceOf(Response);
396
+ expect(result.body).toBeInstanceOf(ReadableStream);
397
+ expect(global.fetch).toHaveBeenCalledWith(
398
+ `${clientOptions.baseUrl}/api/agents/test-agent/voice/speak`,
399
+ expect.objectContaining({
400
+ method: 'POST',
401
+ headers: expect.objectContaining(clientOptions.headers),
402
+ }),
403
+ );
404
+ });
405
+
406
+ it(`should call listen with audio file`, async () => {
407
+ const transcriptionResponse = { text: 'Hello world' };
408
+ mockFetchResponse(transcriptionResponse);
409
+
410
+ const audioBlob = new Blob(['test audio data'], { type: 'audio/wav' });
411
+
412
+ const result = await agent.voice.listen(audioBlob, { filetype: 'wav' });
413
+ expect(result).toEqual(transcriptionResponse);
414
+
415
+ expect(global.fetch).toHaveBeenCalledTimes(1);
416
+ const [url, config] = (global.fetch as any).mock.calls[0];
417
+ expect(url).toBe(`${clientOptions.baseUrl}/api/agents/test-agent/voice/listen`);
418
+ expect(config.method).toBe('POST');
419
+ expect(config.headers).toMatchObject(clientOptions.headers);
420
+
421
+ const formData = config.body;
422
+ expect(formData).toBeInstanceOf(FormData);
423
+ const audioContent = formData.get('audio');
424
+ expect(audioContent).toBeInstanceOf(Blob);
425
+ expect(audioContent.type).toBe('audio/wav');
426
+ });
427
+
428
+ it(`should call listen with audio blob and options`, async () => {
429
+ const transcriptionResponse = { text: 'Hello world' };
430
+ mockFetchResponse(transcriptionResponse);
431
+
432
+ const audioBlob = new Blob(['test audio data'], { type: 'audio/mp3' });
433
+
434
+ const result = await agent.voice.listen(audioBlob, { filetype: 'mp3' });
435
+
436
+ expect(result).toEqual(transcriptionResponse);
437
+
438
+ expect(global.fetch).toHaveBeenCalledTimes(1);
439
+ const [url, config] = (global.fetch as any).mock.calls[0];
440
+ expect(url).toBe(`${clientOptions.baseUrl}/api/agents/test-agent/voice/listen`);
441
+ expect(config.method).toBe('POST');
442
+ expect(config.headers).toMatchObject(clientOptions.headers);
443
+
444
+ const formData = config.body as FormData;
445
+ expect(formData).toBeInstanceOf(FormData);
446
+ const audioContent = formData.get('audio');
447
+ expect(audioContent).toBeInstanceOf(Blob);
448
+ expect(formData.get('options')).toBe(JSON.stringify({ filetype: 'mp3' }));
449
+ });
450
+ });
451
+
336
452
  const agentId = 'test-agent';
337
453
 
338
454
  describe('Memory Thread Resource', () => {
@@ -372,7 +488,7 @@ describe('MastraClient Resources', () => {
372
488
  const result = await memoryThread.update({
373
489
  title: 'Updated Thread',
374
490
  metadata: { updated: true },
375
- resourceid: 'test-resource',
491
+ resourceId: 'test-resource',
376
492
  });
377
493
  expect(result).toEqual(mockResponse);
378
494
  expect(global.fetch).toHaveBeenCalledWith(
@@ -412,29 +528,28 @@ describe('MastraClient Resources', () => {
412
528
  });
413
529
 
414
530
  it('should save messages to memory', async () => {
415
- const messages: MessageType[] = [
531
+ const messages = [
416
532
  {
417
533
  id: '1',
418
- type: 'text',
534
+ type: 'text' as const,
419
535
  content: 'test',
420
- role: 'user',
536
+ role: 'user' as const,
421
537
  threadId: 'test-thread',
422
- createdAt: new Date(),
538
+ resourceId: 'test-resource',
539
+ createdAt: new Date('2025-03-26T10:40:55.116Z'),
423
540
  },
424
541
  ];
425
542
  mockFetchResponse(messages);
426
- const result = await client.saveMessageToMemory({ messages, agentId });
543
+ const result = await client.saveMessageToMemory({ agentId, messages });
427
544
  expect(result).toEqual(messages);
428
545
  expect(global.fetch).toHaveBeenCalledWith(
429
546
  `${clientOptions.baseUrl}/api/memory/save-messages?agentId=${agentId}`,
430
- {
547
+ expect.objectContaining({
431
548
  method: 'POST',
432
- headers: {
549
+ headers: expect.objectContaining({
433
550
  Authorization: 'Bearer test-key',
434
- 'Content-Type': 'application/json',
435
- },
436
- body: JSON.stringify({ messages, agentId }),
437
- },
551
+ }),
552
+ }),
438
553
  );
439
554
  });
440
555
  });
@@ -467,21 +582,19 @@ describe('MastraClient Resources', () => {
467
582
  });
468
583
 
469
584
  it('should execute tool', async () => {
470
- const mockResponse = {
471
- result: 'Tool execution result',
472
- };
585
+ const mockResponse = { data: 'test' };
473
586
  mockFetchResponse(mockResponse);
474
-
475
- const result = await tool.execute({ data: '' });
587
+ const result = await tool.execute({ data: '', runId: 'test-run-id' });
476
588
  expect(result).toEqual(mockResponse);
477
- expect(global.fetch).toHaveBeenCalledWith(`${clientOptions.baseUrl}/api/tools/test-tool/execute`, {
478
- method: 'POST',
479
- headers: {
480
- Authorization: 'Bearer test-key',
481
- 'Content-Type': 'application/json',
482
- },
483
- body: JSON.stringify({ data: '' }),
484
- });
589
+ expect(global.fetch).toHaveBeenCalledWith(
590
+ `${clientOptions.baseUrl}/api/tools/test-tool/execute?runId=test-run-id`,
591
+ expect.objectContaining({
592
+ method: 'POST',
593
+ headers: expect.objectContaining({
594
+ Authorization: 'Bearer test-key',
595
+ }),
596
+ }),
597
+ );
485
598
  });
486
599
  });
487
600
 
@@ -519,14 +632,14 @@ describe('MastraClient Resources', () => {
519
632
  };
520
633
  mockFetchResponse(mockResponse);
521
634
 
522
- const result = await workflow.execute({ trigger: 'test' });
635
+ const result = await workflow.startAsync({ triggerData: { test: 'test' } });
523
636
  expect(result).toEqual(mockResponse);
524
637
  expect(global.fetch).toHaveBeenCalledWith(
525
- `${clientOptions.baseUrl}/api/workflows/test-workflow/execute`,
638
+ `${clientOptions.baseUrl}/api/workflows/test-workflow/start-async?`,
526
639
  expect.objectContaining({
527
640
  method: 'POST',
528
641
  headers: expect.objectContaining(clientOptions.headers),
529
- body: JSON.stringify({ trigger: 'test' }),
642
+ body: JSON.stringify({ test: 'test' }),
530
643
  }),
531
644
  );
532
645
  });
@@ -1,4 +1,5 @@
1
- import type { GenerateReturn, StreamReturn } from '@mastra/core';
1
+ import { processDataStream } from '@ai-sdk/ui-utils';
2
+ import type { GenerateReturn } from '@mastra/core';
2
3
  import type { JSONSchema7 } from 'json-schema';
3
4
  import { ZodSchema } from 'zod';
4
5
  import { zodToJsonSchema } from 'zod-to-json-schema';
@@ -36,12 +37,70 @@ export class AgentTool extends BaseResource {
36
37
  }
37
38
  }
38
39
 
40
+ export class AgentVoice extends BaseResource {
41
+ constructor(
42
+ options: ClientOptions,
43
+ private agentId: string,
44
+ ) {
45
+ super(options);
46
+ this.agentId = agentId;
47
+ }
48
+
49
+ /**
50
+ * Convert text to speech using the agent's voice provider
51
+ * @param text - Text to convert to speech
52
+ * @param options - Optional provider-specific options for speech generation
53
+ * @returns Promise containing the audio data
54
+ */
55
+ async speak(text: string, options?: { speaker?: string; [key: string]: any }): Promise<Response> {
56
+ return this.request<Response>(`/api/agents/${this.agentId}/voice/speak`, {
57
+ method: 'POST',
58
+ headers: {
59
+ 'Content-Type': 'application/json',
60
+ },
61
+ body: { input: text, options },
62
+ stream: true,
63
+ });
64
+ }
65
+
66
+ /**
67
+ * Convert speech to text using the agent's voice provider
68
+ * @param audio - Audio data to transcribe
69
+ * @param options - Optional provider-specific options
70
+ * @returns Promise containing the transcribed text
71
+ */
72
+ listen(audio: Blob, options?: Record<string, any>): Promise<Response> {
73
+ const formData = new FormData();
74
+ formData.append('audio', audio);
75
+
76
+ if (options) {
77
+ formData.append('options', JSON.stringify(options));
78
+ }
79
+
80
+ return this.request(`/api/agents/${this.agentId}/voice/listen`, {
81
+ method: 'POST',
82
+ body: formData,
83
+ });
84
+ }
85
+
86
+ /**
87
+ * Get available speakers for the agent's voice provider
88
+ * @returns Promise containing list of available speakers
89
+ */
90
+ getSpeakers(): Promise<Array<{ voiceId: string; [key: string]: any }>> {
91
+ return this.request(`/api/agents/${this.agentId}/voice/speakers`);
92
+ }
93
+ }
94
+
39
95
  export class Agent extends BaseResource {
96
+ public readonly voice: AgentVoice;
97
+
40
98
  constructor(
41
99
  options: ClientOptions,
42
100
  private agentId: string,
43
101
  ) {
44
102
  super(options);
103
+ this.voice = new AgentVoice(options, this.agentId);
45
104
  }
46
105
 
47
106
  /**
@@ -63,6 +122,10 @@ export class Agent extends BaseResource {
63
122
  const processedParams = {
64
123
  ...params,
65
124
  output: params.output instanceof ZodSchema ? zodToJsonSchema(params.output) : params.output,
125
+ experimental_output:
126
+ params.experimental_output instanceof ZodSchema
127
+ ? zodToJsonSchema(params.experimental_output)
128
+ : params.experimental_output,
66
129
  };
67
130
 
68
131
  return this.request(`/api/agents/${this.agentId}/generate`, {
@@ -74,19 +137,44 @@ export class Agent extends BaseResource {
74
137
  /**
75
138
  * Streams a response from the agent
76
139
  * @param params - Stream parameters including prompt
77
- * @returns Promise containing the streamed response
140
+ * @returns Promise containing the enhanced Response object with processDataStream method
78
141
  */
79
- stream<T extends JSONSchema7 | ZodSchema | undefined = undefined>(params: StreamParams<T>): Promise<Response> {
142
+ async stream<T extends JSONSchema7 | ZodSchema | undefined = undefined>(
143
+ params: StreamParams<T>,
144
+ ): Promise<
145
+ Response & {
146
+ processDataStream: (options?: Omit<Parameters<typeof processDataStream>[0], 'stream'>) => Promise<void>;
147
+ }
148
+ > {
80
149
  const processedParams = {
81
150
  ...params,
82
151
  output: params.output instanceof ZodSchema ? zodToJsonSchema(params.output) : params.output,
152
+ experimental_output:
153
+ params.experimental_output instanceof ZodSchema
154
+ ? zodToJsonSchema(params.experimental_output)
155
+ : params.experimental_output,
83
156
  };
84
157
 
85
- return this.request(`/api/agents/${this.agentId}/stream`, {
158
+ const response: Response & {
159
+ processDataStream: (options?: Omit<Parameters<typeof processDataStream>[0], 'stream'>) => Promise<void>;
160
+ } = await this.request(`/api/agents/${this.agentId}/stream`, {
86
161
  method: 'POST',
87
162
  body: processedParams,
88
163
  stream: true,
89
164
  });
165
+
166
+ if (!response.body) {
167
+ throw new Error('No response body');
168
+ }
169
+
170
+ response.processDataStream = async (options = {}) => {
171
+ await processDataStream({
172
+ stream: response.body as ReadableStream<Uint8Array>,
173
+ ...options,
174
+ });
175
+ };
176
+
177
+ return response;
90
178
  }
91
179
 
92
180
  /**
@@ -1,4 +1,4 @@
1
- import type { RequestFunction, RequestOptions, ClientOptions } from '../types';
1
+ import type { RequestOptions, ClientOptions } from '../types';
2
2
 
3
3
  export class BaseResource {
4
4
  readonly options: ClientOptions;
@@ -24,11 +24,13 @@ export class BaseResource {
24
24
  const response = await fetch(`${baseUrl}${path}`, {
25
25
  ...options,
26
26
  headers: {
27
- 'Content-Type': 'application/json',
28
27
  ...headers,
29
28
  ...options.headers,
29
+ // TODO: Bring this back once we figure out what we/users need to do to make this work with cross-origin requests
30
+ // 'x-mastra-client-type': 'js',
30
31
  },
31
- body: options.body ? JSON.stringify(options.body) : undefined,
32
+ body:
33
+ options.body instanceof FormData ? options.body : options.body ? JSON.stringify(options.body) : undefined,
32
34
  });
33
35
 
34
36
  if (!response.ok) {
@@ -1,6 +1,8 @@
1
1
  export * from './agent';
2
+ export * from './network';
2
3
  export * from './memory-thread';
3
4
  export * from './vector';
4
5
  export * from './workflow';
5
6
  export * from './tool';
6
7
  export * from './base';
8
+ export * from './vnext-workflow';
@@ -1,13 +1,6 @@
1
1
  import type { StorageThreadType } from '@mastra/core';
2
2
 
3
- import type {
4
- CreateMemoryThreadParams,
5
- GetMemoryThreadMessagesResponse,
6
- GetMemoryThreadResponse,
7
- ClientOptions,
8
- SaveMessageToMemoryParams,
9
- UpdateMemoryThreadParams,
10
- } from '../types';
3
+ import type { GetMemoryThreadMessagesResponse, ClientOptions, UpdateMemoryThreadParams } from '../types';
11
4
 
12
5
  import { BaseResource } from './base';
13
6
 
@@ -0,0 +1,92 @@
1
+ import { processDataStream } from '@ai-sdk/ui-utils';
2
+ import type { GenerateReturn } from '@mastra/core';
3
+ import type { JSONSchema7 } from 'json-schema';
4
+ import { ZodSchema } from 'zod';
5
+ import { zodToJsonSchema } from 'zod-to-json-schema';
6
+
7
+ import type { GenerateParams, ClientOptions, StreamParams, GetNetworkResponse } from '../types';
8
+
9
+ import { BaseResource } from './base';
10
+
11
+ export class Network extends BaseResource {
12
+ constructor(
13
+ options: ClientOptions,
14
+ private networkId: string,
15
+ ) {
16
+ super(options);
17
+ }
18
+
19
+ /**
20
+ * Retrieves details about the network
21
+ * @returns Promise containing network details
22
+ */
23
+ details(): Promise<GetNetworkResponse> {
24
+ return this.request(`/api/networks/${this.networkId}`);
25
+ }
26
+
27
+ /**
28
+ * Generates a response from the agent
29
+ * @param params - Generation parameters including prompt
30
+ * @returns Promise containing the generated response
31
+ */
32
+ generate<T extends JSONSchema7 | ZodSchema | undefined = undefined>(
33
+ params: GenerateParams<T>,
34
+ ): Promise<GenerateReturn<T>> {
35
+ const processedParams = {
36
+ ...params,
37
+ output: params.output instanceof ZodSchema ? zodToJsonSchema(params.output) : params.output,
38
+ experimental_output:
39
+ params.experimental_output instanceof ZodSchema
40
+ ? zodToJsonSchema(params.experimental_output)
41
+ : params.experimental_output,
42
+ };
43
+
44
+ return this.request(`/api/networks/${this.networkId}/generate`, {
45
+ method: 'POST',
46
+ body: processedParams,
47
+ });
48
+ }
49
+
50
+ /**
51
+ * Streams a response from the agent
52
+ * @param params - Stream parameters including prompt
53
+ * @returns Promise containing the enhanced Response object with processDataStream method
54
+ */
55
+ async stream<T extends JSONSchema7 | ZodSchema | undefined = undefined>(
56
+ params: StreamParams<T>,
57
+ ): Promise<
58
+ Response & {
59
+ processDataStream: (options?: Omit<Parameters<typeof processDataStream>[0], 'stream'>) => Promise<void>;
60
+ }
61
+ > {
62
+ const processedParams = {
63
+ ...params,
64
+ output: params.output instanceof ZodSchema ? zodToJsonSchema(params.output) : params.output,
65
+ experimental_output:
66
+ params.experimental_output instanceof ZodSchema
67
+ ? zodToJsonSchema(params.experimental_output)
68
+ : params.experimental_output,
69
+ };
70
+
71
+ const response: Response & {
72
+ processDataStream: (options?: Omit<Parameters<typeof processDataStream>[0], 'stream'>) => Promise<void>;
73
+ } = await this.request(`/api/networks/${this.networkId}/stream`, {
74
+ method: 'POST',
75
+ body: processedParams,
76
+ stream: true,
77
+ });
78
+
79
+ if (!response.body) {
80
+ throw new Error('No response body');
81
+ }
82
+
83
+ response.processDataStream = async (options = {}) => {
84
+ await processDataStream({
85
+ stream: response.body as ReadableStream<Uint8Array>,
86
+ ...options,
87
+ });
88
+ };
89
+
90
+ return response;
91
+ }
92
+ }
@@ -23,10 +23,16 @@ export class Tool extends BaseResource {
23
23
  * @param params - Parameters required for tool execution
24
24
  * @returns Promise containing the tool execution results
25
25
  */
26
- execute(params: { data: any }): Promise<any> {
27
- return this.request(`/api/tools/${this.toolId}/execute`, {
26
+ execute(params: { data: any; runId?: string }): Promise<any> {
27
+ const url = new URLSearchParams();
28
+
29
+ if (params.runId) {
30
+ url.set('runId', params.runId);
31
+ }
32
+
33
+ return this.request(`/api/tools/${this.toolId}/execute?${url.toString()}`, {
28
34
  method: 'POST',
29
- body: params,
35
+ body: params.data,
30
36
  });
31
37
  }
32
38
  }