Showing the changes to packages/codemode-openapi/src/openapi-tools.ts (1 of 77 files). Show all
Unified · Split
| @@ -8,8 +8,12 @@ import * as Effect from "effect/Effect"; · 7 unmodified lines | ||
| 8 | 8 | import * as Layer from "effect/Layer"; |
| 9 | 9 | |
| 10 | 10 | import { |
| 11 | + applyCookiePlacementsToHeaders, | |
| 12 | + applyHttpQueryPlacementsToUrl, | |
| 13 | + applyJsonBodyPlacements, | |
| 11 | 14 | standardSchemaFromJsonSchema, |
| 12 | 15 | toTool, |
| 16 | + type HttpRequestPlacements, | |
| 13 | 17 | type ToolMap, |
| 14 | 18 | unknownInputSchema, |
| 15 | 19 | } from "@executor/codemode-core"; |
| @@ -288,6 +292,7 @@ export type CreateOpenApiToolsFromManifestInput = { · 272 unmodified lines | ||
| 288 | 292 | sourceKey?: string; |
| 289 | 293 | defaultHeaders?: Readonly<Record<string, string>>; |
| 290 | 294 | credentialHeaders?: Readonly<Record<string, string>>; |
| 295 | + credentialPlacements?: HttpRequestPlacements; | |
| 291 | 296 | httpClientLayer?: Layer.Layer<HttpClient.HttpClient, never, never>; |
| 292 | 297 | }; |
| 293 | 298 | |
| @@ -317,7 +322,7 @@ const buildFetchRequest = (input: { · 23 unmodified lines | ||
| 317 | 322 | args: OpenApiToolArgs; |
| 318 | 323 | baseUrl: string; |
| 319 | 324 | defaultHeaders: Readonly<Record<string, string>>; |
| 320 | − credentialHeaders: Readonly<Record<string, string>>; | |
| 325 | + credentialPlacements: HttpRequestPlacements; | |
| 321 | 326 | }): { |
| 322 | 327 | url: URL; |
| 323 | 328 | method: string; |
| @@ -369,9 +374,11 @@ const buildFetchRequest = (input: { · 45 unmodified lines | ||
| 369 | 374 | } |
| 370 | 375 | |
| 371 | 376 | let body: string | undefined; |
| 377 | + const bodyValues = input.credentialPlacements.bodyValues ?? {}; | |
| 378 | + const hasCredentialBodyValues = Object.keys(bodyValues).length > 0; | |
| 372 | 379 | |
| 373 | 380 | if (input.payload.requestBody !== null) { |
| 374 | − if (!hasRequestBody(input.args)) { | |
| 381 | + if (!hasRequestBody(input.args) && !hasCredentialBodyValues) { | |
| 375 | 382 | if (input.payload.requestBody.required) { |
| 376 | 383 | throw new OpenApiToolInvocationError({ |
| 377 | 384 | operation: "validate_args", |
| @@ -380,7 +387,13 @@ const buildFetchRequest = (input: { · 2 unmodified lines | ||
| 380 | 387 | }); |
| 381 | 388 | } |
| 382 | 389 | } else { |
| 383 | − body = JSON.stringify(input.args.body); | |
| 390 | + body = JSON.stringify( | |
| 391 | + applyJsonBodyPlacements({ | |
| 392 | + body: hasRequestBody(input.args) ? input.args.body : {}, | |
| 393 | + bodyValues, | |
| 394 | + label: `${input.payload.method.toUpperCase()} ${input.payload.pathTemplate}`, | |
| 395 | + }), | |
| 396 | + ); | |
| 384 | 397 | |
| 385 | 398 | const preferredContentType = input.payload.requestBody.contentTypes[0]; |
| 386 | 399 | if (preferredContentType) { |
| @@ -391,14 +404,23 @@ const buildFetchRequest = (input: { · 4 unmodified lines | ||
| 391 | 404 | } |
| 392 | 405 | } |
| 393 | 406 | |
| 394 | − for (const [key, value] of Object.entries(input.credentialHeaders)) { | |
| 395 | − headers[key] = value; | |
| 407 | + const urlWithAuth = applyHttpQueryPlacementsToUrl({ | |
| 408 | + url, | |
| 409 | + queryParams: input.credentialPlacements.queryParams, | |
| 410 | + }); | |
| 411 | + const headersWithAuthCookies = applyCookiePlacementsToHeaders({ | |
| 412 | + headers, | |
| 413 | + cookies: input.credentialPlacements.cookies, | |
| 414 | + }); | |
| 415 | + | |
| 416 | + for (const [key, value] of Object.entries(input.credentialPlacements.headers ?? {})) { | |
| 417 | + headersWithAuthCookies[key] = value; | |
| 396 | 418 | } |
| 397 | 419 | |
| 398 | 420 | return { |
| 399 | − url, | |
| 421 | + url: urlWithAuth, | |
| 400 | 422 | method: input.payload.method.toUpperCase(), |
| 401 | − headers, | |
| 423 | + headers: headersWithAuthCookies, | |
| 402 | 424 | body, |
| 403 | 425 | }; |
| 404 | 426 | }; |
| @@ -413,15 +435,32 @@ export type CreateOpenApiToolFromDefinitionInput = { · 8 unmodified lines | ||
| 413 | 435 | baseUrl: string; |
| 414 | 436 | defaultHeaders?: Readonly<Record<string, string>>; |
| 415 | 437 | credentialHeaders?: Readonly<Record<string, string>>; |
| 438 | + credentialPlacements?: HttpRequestPlacements; | |
| 416 | 439 | refHintTable?: Readonly<OpenApiRefHintTable>; |
| 417 | 440 | httpClientLayer?: Layer.Layer<HttpClient.HttpClient, never, never>; |
| 418 | 441 | }; |
| 419 | 442 | |
| 443 | +const normalizeCredentialPlacements = (input: { | |
| 444 | + credentialHeaders?: Readonly<Record<string, string>>; | |
| 445 | + credentialPlacements?: HttpRequestPlacements; | |
| 446 | +}): HttpRequestPlacements => ({ | |
| 447 | + headers: { | |
| 448 | + ...(input.credentialHeaders ?? {}), | |
| 449 | + ...(input.credentialPlacements?.headers ?? {}), | |
| 450 | + }, | |
| 451 | + queryParams: input.credentialPlacements?.queryParams, | |
| 452 | + cookies: input.credentialPlacements?.cookies, | |
| 453 | + bodyValues: input.credentialPlacements?.bodyValues, | |
| 454 | +}); | |
| 455 | + | |
| 420 | 456 | export const createOpenApiToolFromDefinition = ( |
| 421 | 457 | input: CreateOpenApiToolFromDefinitionInput, |
| 422 | 458 | ) => { |
| 423 | 459 | const defaultHeaders = input.defaultHeaders ?? {}; |
| 424 | − const credentialHeaders = input.credentialHeaders ?? {}; | |
| 460 | + const credentialPlacements = normalizeCredentialPlacements({ | |
| 461 | + credentialHeaders: input.credentialHeaders, | |
| 462 | + credentialPlacements: input.credentialPlacements, | |
| 463 | + }); | |
| 425 | 464 | const httpClientLayer = input.httpClientLayer ?? FetchHttpClient.layer; |
| 426 | 465 | const presentation = buildOpenApiToolPresentation({ |
| 427 | 466 | definition: input.definition, |
| @@ -441,7 +480,7 @@ export const createOpenApiToolFromDefinition = ( · 13 unmodified lines | ||
| 441 | 480 | args: decodedArgs, |
| 442 | 481 | baseUrl: input.baseUrl, |
| 443 | 482 | defaultHeaders, |
| 444 | − credentialHeaders, | |
| 483 | + credentialPlacements, | |
| 445 | 484 | }); |
| 446 | 485 | |
| 447 | 486 | return Effect.runPromise( |
| @@ -503,7 +542,6 @@ export const createOpenApiToolsFromManifest = ( · 55 unmodified lines | ||
| 503 | 542 | const baseUrl = normalizeHttpUrl(input.baseUrl); |
| 504 | 543 | const sourceKey = input.sourceKey ?? "openapi.generated"; |
| 505 | 544 | const defaultHeaders = input.defaultHeaders ?? {}; |
| 506 | − const credentialHeaders = input.credentialHeaders ?? {}; | |
| 507 | 545 | const httpClientLayer = input.httpClientLayer ?? FetchHttpClient.layer; |
| 508 | 546 | |
| 509 | 547 | const definitions = compileOpenApiToolDefinitions(input.manifest); |
| @@ -517,7 +555,8 @@ export const createOpenApiToolsFromManifest = ( · 7 unmodified lines | ||
| 517 | 555 | sourceKey, |
| 518 | 556 | baseUrl, |
| 519 | 557 | defaultHeaders, |
| 520 | − credentialHeaders, | |
| 558 | + credentialHeaders: input.credentialHeaders, | |
| 559 | + credentialPlacements: input.credentialPlacements, | |
| 521 | 560 | refHintTable: input.manifest.refHintTable, |
| 522 | 561 | httpClientLayer, |
| 523 | 562 | }); |
| @@ -534,6 +573,7 @@ export const createOpenApiToolsFromSpec = (input: { · 10 unmodified lines | ||
| 534 | 573 | sourceKey?: string; |
| 535 | 574 | defaultHeaders?: Readonly<Record<string, string>>; |
| 536 | 575 | credentialHeaders?: Readonly<Record<string, string>>; |
| 576 | + credentialPlacements?: HttpRequestPlacements; | |
| 537 | 577 | httpClientLayer?: Layer.Layer<HttpClient.HttpClient, never, never>; |
| 538 | 578 | }): Effect.Effect< |
| 539 | 579 | { manifest: OpenApiToolManifest; definitions: Array<OpenApiToolDefinition>; tools: ToolMap }, |
| @@ -551,6 +591,7 @@ export const createOpenApiToolsFromSpec = (input: { · 11 unmodified lines | ||
| 551 | 591 | sourceKey: input.sourceKey, |
| 552 | 592 | defaultHeaders: input.defaultHeaders, |
| 553 | 593 | credentialHeaders: input.credentialHeaders, |
| 594 | + credentialPlacements: input.credentialPlacements, | |
| 554 | 595 | httpClientLayer: input.httpClientLayer, |
| 555 | 596 | }), |
| 556 | 597 | }), |