pull/715/head
Travis Fischer 2025-06-05 08:52:10 +07:00
rodzic 87d75237c0
commit 924330c759
2 zmienionych plików z 21 dodań i 25 usunięć

Wyświetl plik

@ -50,9 +50,7 @@ export async function createRequestForOpenAPIOperation(
assert(incomingRequestParamsRaw, 400, 'Invalid empty request body') assert(incomingRequestParamsRaw, 400, 'Invalid empty request body')
} }
// TODO: Validate incoming request params against the tool's input JSON schema // Validate incoming request params against the tool's input JSON schema.
// TODO: we want to coerce data types to match the schema for booleans, dates, etc
// Currently, these will fail if given as body params, for instance, on the origin server.
const incomingRequestParams = cfValidateJsonSchemaObject({ const incomingRequestParams = cfValidateJsonSchemaObject({
schema: tool.inputSchema, schema: tool.inputSchema,
data: incomingRequestParamsRaw, data: incomingRequestParamsRaw,
@ -95,18 +93,27 @@ export async function createRequestForOpenAPIOperation(
if (bodyParams.length > 0) { if (bodyParams.length > 0) {
body = JSON.stringify( body = JSON.stringify(
Object.fromEntries( Object.fromEntries(
bodyParams.map(([key]) => [key, incomingRequestParams[key]]) bodyParams
.map(([key]) => [key, incomingRequestParams[key]])
// Prune undefined values. We know these aren't required fields,
// because the incoming request params have already been validated
// against the tool's input schema.
.filter(([, value]) => value !== undefined)
) )
) )
headers['content-type'] ??= 'application/json' headers['content-type'] ??= 'application/json'
} else if (formDataParams.length > 0) { } else if (formDataParams.length > 0) {
body = JSON.stringify( // TODO: Double-check FormData usage.
Object.fromEntries( const formData = new FormData()
formDataParams.map(([key]) => [key, incomingRequestParams[key]]) for (const [key] of formDataParams) {
) const value = incomingRequestParams[key]
) if (value !== undefined) {
formData.append(key, value)
}
}
body = formData.toString()
headers['content-type'] ??= 'application/x-www-form-urlencoded' headers['content-type'] ??= 'application/x-www-form-urlencoded'
} }

Wyświetl plik

@ -20,6 +20,7 @@ import { camelCase, mergeJsonSchemaObjects } from './utils'
const jsonContentType = 'application/json' const jsonContentType = 'application/json'
const multipartFormData = 'multipart/form-data' const multipartFormData = 'multipart/form-data'
// const applicationFormUrlEncoded = 'application/x-www-form-urlencoded'
const httpMethods = ['get', 'post', 'put', 'delete', 'patch', 'trace'] as const const httpMethods = ['get', 'post', 'put', 'delete', 'patch', 'trace'] as const
const paramSources = ['body', 'formData', 'header', 'path', 'query'] as const const paramSources = ['body', 'formData', 'header', 'path', 'query'] as const
@ -41,20 +42,6 @@ export async function getToolsFromOpenAPISpec(
const tools: Tool[] = [] const tools: Tool[] = []
const toolToOperationMap: Record<string, OpenAPIToolOperation> = {} const toolToOperationMap: Record<string, OpenAPIToolOperation> = {}
const requestBodyJsonSchemaPaths = [
'requestBody',
'content',
jsonContentType,
'schema'
]
const requestBodyFormDataJsonSchemaPaths = [
'requestBody',
'content',
multipartFormData,
'schema'
]
const operationResponsePaths = [ const operationResponsePaths = [
['responses', '200', 'content', jsonContentType, 'schema'], ['responses', '200', 'content', jsonContentType, 'schema'],
['responses', '201', 'content', jsonContentType, 'schema'] ['responses', '201', 'content', jsonContentType, 'schema']
@ -62,8 +49,10 @@ export async function getToolsFromOpenAPISpec(
] ]
const operationRequestPaths = [ const operationRequestPaths = [
requestBodyJsonSchemaPaths, ['requestBody', 'content', jsonContentType, 'schema'],
requestBodyFormDataJsonSchemaPaths ['requestBody', 'content', multipartFormData, 'schema']
// TODO: Support application/x-www-form-urlencoded bodies
// ['requestBody', 'content', applicationFormUrlEncoded, 'schema']
] ]
const operationNames = new Set<string>() const operationNames = new Set<string>()