* Clean up OpenAPI add source API * Update OpenAPI add source credential UI * Address OpenAPI add source PR feedback * Document OpenAPI credential configuration plan * Fix OpenAPI add flow CI
Showing the changes to packages/plugins/openapi/src/testing (1 of 20 files). Show all
Unified · Split
| @@ -13,7 +13,7 @@ import { · 12 unmodified lines | |||
| 13 | OpenApi, | 13 | OpenApi, |
| 14 | } from "effect/unstable/httpapi"; | 14 | } from "effect/unstable/httpapi"; |
| 15 | import { OAuthTestServer, serveTestHttpServerLayer } from "@executor-js/sdk/testing"; | 15 | import { OAuthTestServer, serveTestHttpServerLayer } from "@executor-js/sdk/testing"; |
| 16 | import { isToolResult, type ScopeId } from "@executor-js/sdk/core"; | 16 | import { isToolResult } from "@executor-js/sdk/core"; |
| 17 | import type { OpenApiPluginExtension, OpenApiSpecConfig } from "../sdk/plugin"; | 17 | import type { OpenApiPluginExtension, OpenApiSpecConfig } from "../sdk/plugin"; |
| 18 | 18 | ||
| 19 | export class OpenApiTestServerAddressError extends Data.TaggedError( | 19 | export class OpenApiTestServerAddressError extends Data.TaggedError( |
| @@ -80,22 +80,45 @@ export interface OpenApiEchoTestServerShape extends OpenApiTestServerShape { · 60 unmodified lines | |||
| 80 | readonly clearRequests: Effect.Effect<void>; | 80 | readonly clearRequests: Effect.Effect<void>; |
| 81 | } | 81 | } |
| 82 | 82 | ||
| 83 | export type OpenApiTestSourceOptions = Omit<OpenApiSpecConfig, "spec" | "baseUrl"> & { | 83 | export type OpenApiTestSourceOptions = Omit< |
| 84 | OpenApiSpecConfig, | ||
| 85 | "spec" | "baseUrl" | "name" | "namespace" | ||
| 86 | > & { | ||
| 84 | readonly baseUrl?: string | null; | 87 | readonly baseUrl?: string | null; |
| 88 | readonly name?: string; | ||
| 89 | readonly namespace?: string; | ||
| 85 | }; | 90 | }; |
| 86 | 91 | ||
| 87 | export type OpenApiHttpApiTestSourceOptions = Omit<OpenApiSpecConfig, "spec"> & { | 92 | export type OpenApiHttpApiTestSourceOptions = Omit< |
| 93 | OpenApiSpecConfig, | ||
| 94 | "spec" | "name" | "namespace" | "baseUrl" | ||
| 95 | > & { | ||
| 96 | readonly name?: string; | ||
| 97 | readonly namespace?: string; | ||
| 98 | readonly baseUrl?: string | null; | ||
| 88 | readonly specBaseUrl?: string; | 99 | readonly specBaseUrl?: string; |
| 89 | readonly transformSpec?: (spec: Record<string, unknown>) => Record<string, unknown>; | 100 | readonly transformSpec?: (spec: Record<string, unknown>) => Record<string, unknown>; |
| 90 | }; | 101 | }; |
| 91 | 102 | ||
| 103 | type OpenApiHttpApiAddSpecCredentialInput = | ||
| 104 | | string | ||
| 105 | | { | ||
| 106 | readonly kind: "secret"; | ||
| 107 | readonly prefix?: string; | ||
| 108 | }; | ||
| 109 | |||
| 110 | type OpenApiHttpApiAddSpecCredentialsInput = { | ||
| 111 | readonly headers?: Record<string, OpenApiHttpApiAddSpecCredentialInput>; | ||
| 112 | readonly queryParams?: Record<string, OpenApiHttpApiAddSpecCredentialInput>; | ||
| 113 | }; | ||
| 114 | |||
| 92 | export type OpenApiHttpApiTestAddSpecPayloadOptions = Omit< | 115 | export type OpenApiHttpApiTestAddSpecPayloadOptions = Omit< |
| 93 | OpenApiHttpApiTestSourceOptions, | 116 | OpenApiHttpApiTestSourceOptions, |
| 94 | "scope" | "credentialTargetScope" | 117 | "scope" | "headers" | "queryParams" | "specFetchCredentials" |
| 95 | > & { | 118 | > & |
| 96 | readonly targetScope: ScopeId; | 119 | OpenApiHttpApiAddSpecCredentialsInput & { |
| 97 | readonly credentialTargetScope?: ScopeId; | 120 | readonly specFetchCredentials?: OpenApiHttpApiAddSpecCredentialsInput; |
| 98 | }; | 121 | }; |
| 99 | 122 | ||
| 100 | export type OpenApiTestSourceExecutor = { | 123 | export type OpenApiTestSourceExecutor = { |
| 101 | readonly openapi: Pick<OpenApiPluginExtension, "addSpec">; | 124 | readonly openapi: Pick<OpenApiPluginExtension, "addSpec">; |
| @@ -125,9 +148,11 @@ export const makeOpenApiTestSourceConfig = ( · 23 unmodified lines | |||
| 125 | const { baseUrl, ...rest } = options; | 148 | const { baseUrl, ...rest } = options; |
| 126 | return { | 149 | return { |
| 127 | ...rest, | 150 | ...rest, |
| 128 | spec: server.specJson, | 151 | spec: { kind: "blob", value: server.specJson }, |
| 152 | name: rest.name ?? "Test API", | ||
| 153 | namespace: rest.namespace ?? "test_api", | ||
| 129 | ...(baseUrl === null ? {} : { baseUrl: baseUrl ?? server.baseUrl }), | 154 | ...(baseUrl === null ? {} : { baseUrl: baseUrl ?? server.baseUrl }), |
| 130 | }; | 155 | } as OpenApiSpecConfig; |
| 131 | }; | 156 | }; |
| 132 | 157 | ||
| 133 | export const addOpenApiTestSource = ( | 158 | export const addOpenApiTestSource = ( |
| @@ -140,11 +165,17 @@ export const makeOpenApiHttpApiTestSourceConfig = ( · 6 unmodified lines | |||
| 140 | api: HttpApi.Any, | 165 | api: HttpApi.Any, |
| 141 | options: OpenApiHttpApiTestSourceOptions, | 166 | options: OpenApiHttpApiTestSourceOptions, |
| 142 | ): OpenApiSpecConfig => { | 167 | ): OpenApiSpecConfig => { |
| 143 | const { specBaseUrl, transformSpec, ...config } = options; | 168 | const { baseUrl, specBaseUrl, transformSpec, ...config } = options; |
| 144 | return { | 169 | return { |
| 145 | ...config, | 170 | ...config, |
| 146 | spec: makeOpenApiTestSpecJson(api, { baseUrl: specBaseUrl, transformSpec }), | 171 | spec: { |
| 147 | }; | 172 | kind: "blob", |
| 173 | value: makeOpenApiTestSpecJson(api, { baseUrl: specBaseUrl, transformSpec }), | ||
| 174 | }, | ||
| 175 | name: config.name ?? "Test API", | ||
| 176 | namespace: config.namespace ?? "test_api", | ||
| 177 | ...(baseUrl === null ? {} : { baseUrl: baseUrl ?? specBaseUrl ?? "https://api.example.test" }), | ||
| 178 | } as OpenApiSpecConfig; | ||
| 148 | }; | 179 | }; |
| 149 | 180 | ||
| 150 | export const addOpenApiHttpApiTestSource = ( | 181 | export const addOpenApiHttpApiTestSource = ( |
| @@ -157,26 +188,21 @@ export const makeOpenApiHttpApiTestAddSpecPayload = ( · 6 unmodified lines | |||
| 157 | api: HttpApi.Any, | 188 | api: HttpApi.Any, |
| 158 | options: OpenApiHttpApiTestAddSpecPayloadOptions, | 189 | options: OpenApiHttpApiTestAddSpecPayloadOptions, |
| 159 | ) => { | 190 | ) => { |
| 160 | const { targetScope, credentialTargetScope, ...sourceOptions } = options; | 191 | const { ...sourceOptions } = options; |
| 161 | const config = makeOpenApiHttpApiTestSourceConfig(api, { | 192 | const config = makeOpenApiHttpApiTestSourceConfig(api, { |
| 162 | ...sourceOptions, | 193 | ...sourceOptions, |
| 163 | scope: String(targetScope), | 194 | scope: "unused-http-helper-scope", |
| 164 | ...(credentialTargetScope !== undefined | ||
| 165 | ? { credentialTargetScope: String(credentialTargetScope) } | ||
| 166 | : {}), | ||
| 167 | }); | 195 | }); |
| 168 | return { | 196 | return { |
| 169 | targetScope, | ||
| 170 | spec: config.spec, | 197 | spec: config.spec, |
| 171 | namespace: config.namespace, | 198 | namespace: config.namespace, |
| 172 | ...(config.name !== undefined ? { name: config.name } : {}), | 199 | name: config.name, |
| 173 | ...(config.baseUrl !== undefined ? { baseUrl: config.baseUrl } : {}), | 200 | baseUrl: config.baseUrl, |
| 174 | ...(config.headers !== undefined ? { headers: config.headers } : {}), | 201 | ...(sourceOptions.headers !== undefined ? { headers: sourceOptions.headers } : {}), |
| 175 | ...(config.queryParams !== undefined ? { queryParams: config.queryParams } : {}), | 202 | ...(sourceOptions.queryParams !== undefined ? { queryParams: sourceOptions.queryParams } : {}), |
| 176 | ...(config.oauth2 !== undefined ? { oauth2: config.oauth2 } : {}), | 203 | ...(config.oauth2 !== undefined ? { oauth2: config.oauth2 } : {}), |
| 177 | ...(credentialTargetScope !== undefined ? { credentialTargetScope } : {}), | 204 | ...(sourceOptions.specFetchCredentials !== undefined |
| 178 | ...(config.specFetchCredentials !== undefined | 205 | ? { specFetchCredentials: sourceOptions.specFetchCredentials } |
| 179 | ? { specFetchCredentials: config.specFetchCredentials } | ||
| 180 | : {}), | 206 | : {}), |
| 181 | }; | 207 | }; |
| 182 | }; | 208 | }; |