|
| 1 | +import { defu } from 'defu'; |
1 | 2 | import type { Arrayable } from 'type-fest'; |
2 | 3 | import { DEFAULT_BASE_URL } from './consts'; |
| 4 | +import { createFeedbackTool } from './feedback'; |
| 5 | +import { type StackOneHeaders, normaliseHeaders, stackOneHeadersSchema } from './headers'; |
3 | 6 | import { createMCPClient } from './mcp-client'; |
4 | 7 | import { type RpcActionResponse, RpcClient } from './rpc-client'; |
5 | 8 | import { BaseTool, type StackOneTool, Tools } from './tool'; |
6 | | -import { createFeedbackTool } from './feedback'; |
7 | 9 | import type { |
8 | 10 | ExecuteOptions, |
9 | 11 | JsonDict, |
@@ -473,23 +475,14 @@ export class StackOneToolSet { |
473 | 475 | typeof inputParams === 'string' ? JSON.parse(inputParams) : (inputParams ?? {}); |
474 | 476 |
|
475 | 477 | const currentHeaders = tool.getHeaders(); |
476 | | - const actionHeaders = this.buildActionHeaders(currentHeaders); |
| 478 | + const baseHeaders = this.buildActionHeaders(currentHeaders); |
477 | 479 |
|
478 | 480 | const pathParams = this.extractRecord(parsedParams, 'path'); |
479 | 481 | const queryParams = this.extractRecord(parsedParams, 'query'); |
480 | 482 | const additionalHeaders = this.extractRecord(parsedParams, 'headers'); |
481 | | - if (additionalHeaders) { |
482 | | - for (const [key, value] of Object.entries(additionalHeaders)) { |
483 | | - if (value === undefined || value === null) continue; |
484 | | - if (typeof value === 'string') { |
485 | | - actionHeaders[key] = value; |
486 | | - } else if (typeof value === 'number' || typeof value === 'boolean') { |
487 | | - actionHeaders[key] = String(value); |
488 | | - } else { |
489 | | - actionHeaders[key] = JSON.stringify(value); |
490 | | - } |
491 | | - } |
492 | | - } |
| 483 | + const extraHeaders = normaliseHeaders(additionalHeaders); |
| 484 | + // defu merges extraHeaders into baseHeaders, both are already branded types |
| 485 | + const actionHeaders = defu(extraHeaders, baseHeaders) as StackOneHeaders; |
493 | 486 |
|
494 | 487 | const bodyPayload = this.extractRecord(parsedParams, 'body'); |
495 | 488 | const rpcBody: JsonDict = bodyPayload ? { ...bodyPayload } : {}; |
@@ -538,12 +531,14 @@ export class StackOneToolSet { |
538 | 531 | return tool; |
539 | 532 | } |
540 | 533 |
|
541 | | - private buildActionHeaders(headers: Record<string, string>): Record<string, string> { |
| 534 | + private buildActionHeaders(headers: Record<string, string>): StackOneHeaders { |
542 | 535 | const sanitizedEntries = Object.entries(headers).filter( |
543 | 536 | ([key]) => key.toLowerCase() !== 'authorization', |
544 | 537 | ); |
545 | 538 |
|
546 | | - return Object.fromEntries(sanitizedEntries.map(([key, value]) => [key, String(value)])); |
| 539 | + return stackOneHeadersSchema.parse( |
| 540 | + Object.fromEntries(sanitizedEntries.map(([key, value]) => [key, String(value)])), |
| 541 | + ); |
547 | 542 | } |
548 | 543 |
|
549 | 544 | private extractRecord( |
|
0 commit comments