* 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/api (2 of 20 files). Show all
Unified · Split
| @@ -1,11 +1,6 @@ | |||
| 1 | import { HttpApiEndpoint, HttpApiGroup } from "effect/unstable/httpapi"; | 1 | import { HttpApiEndpoint, HttpApiGroup } from "effect/unstable/httpapi"; |
| 2 | import { Schema } from "effect"; | 2 | import { Schema } from "effect"; |
| 3 | import { | 3 | import { InternalError, ScopeId, SecretBackedValue } from "@executor-js/sdk/shared"; |
| 4 | InternalError, | ||
| 5 | ScopeId, | ||
| 6 | ScopedSecretCredentialInput, | ||
| 7 | SecretBackedValue, | ||
| 8 | } from "@executor-js/sdk/shared"; | ||
| 9 | 4 | ||
| 10 | import { OpenApiParseError, OpenApiExtractionError, OpenApiOAuthError } from "../sdk/errors"; | 5 | import { OpenApiParseError, OpenApiExtractionError, OpenApiOAuthError } from "../sdk/errors"; |
| 11 | import { SpecPreview } from "../sdk/preview"; | 6 | import { SpecPreview } from "../sdk/preview"; |
| @@ -42,57 +37,54 @@ const SourceBindingParams = { · 30 unmodified lines | |||
| 42 | sourceScopeId: ScopeId, | 37 | sourceScopeId: ScopeId, |
| 43 | }; | 38 | }; |
| 44 | 39 | ||
| 45 | const SpecFetchCredentialsPayload = Schema.Struct({ | 40 | const OpenApiSpecInputPayload = Schema.Union([ |
| 41 | Schema.Struct({ kind: Schema.Literal("url"), url: Schema.String }), | ||
| 42 | Schema.Struct({ kind: Schema.Literal("blob"), value: Schema.String }), | ||
| 43 | ]); | ||
| 44 | |||
| 45 | const PreviewSpecFetchCredentialsPayload = Schema.Struct({ | ||
| 46 | headers: Schema.optional(Schema.Record(Schema.String, SecretBackedValue)), | 46 | headers: Schema.optional(Schema.Record(Schema.String, SecretBackedValue)), |
| 47 | queryParams: Schema.optional(Schema.Record(Schema.String, SecretBackedValue)), | 47 | queryParams: Schema.optional(Schema.Record(Schema.String, SecretBackedValue)), |
| 48 | }); | 48 | }); |
| 49 | 49 | ||
| 50 | const ConfiguredCredentialBindingPayload = Schema.Struct({ | 50 | const OpenApiSecretShapePayload = Schema.Struct({ |
| 51 | kind: Schema.Literal("binding"), | 51 | kind: Schema.Literal("secret"), |
| 52 | slot: Schema.String, | ||
| 53 | prefix: Schema.optional(Schema.String), | 52 | prefix: Schema.optional(Schema.String), |
| 54 | }); | 53 | }); |
| 55 | 54 | ||
| 56 | const ConfiguredCredentialValuePayload = Schema.Union([ | 55 | const OpenApiConfiguredValuePayload = Schema.Union([Schema.String, OpenApiSecretShapePayload]); |
| 57 | Schema.String, | ||
| 58 | ConfiguredCredentialBindingPayload, | ||
| 59 | ]); | ||
| 60 | 56 | ||
| 61 | const OpenApiCredentialInputPayload = Schema.Union([ | 57 | const SpecFetchCredentialsPayload = Schema.Struct({ |
| 62 | ScopedSecretCredentialInput, | 58 | headers: Schema.optional(Schema.Record(Schema.String, OpenApiConfiguredValuePayload)), |
| 63 | SecretBackedValue, | 59 | queryParams: Schema.optional(Schema.Record(Schema.String, OpenApiConfiguredValuePayload)), |
| 64 | ConfiguredCredentialValuePayload, | 60 | }); |
| 65 | ]); | ||
| 66 | 61 | ||
| 67 | // --------------------------------------------------------------------------- | 62 | // --------------------------------------------------------------------------- |
| 68 | // Payloads | 63 | // Payloads |
| 69 | // --------------------------------------------------------------------------- | 64 | // --------------------------------------------------------------------------- |
| 70 | 65 | ||
| 71 | const AddSpecPayload = Schema.Struct({ | 66 | const AddSpecPayload = Schema.Struct({ |
| 72 | targetScope: ScopeId, | 67 | spec: OpenApiSpecInputPayload, |
| 73 | credentialTargetScope: Schema.optional(ScopeId), | ||
| 74 | spec: Schema.String, | ||
| 75 | specFetchCredentials: Schema.optional(SpecFetchCredentialsPayload), | 68 | specFetchCredentials: Schema.optional(SpecFetchCredentialsPayload), |
| 76 | name: Schema.optional(Schema.String), | 69 | name: Schema.String, |
| 77 | baseUrl: Schema.optional(Schema.String), | 70 | baseUrl: Schema.String, |
| 78 | namespace: Schema.optional(Schema.String), | 71 | namespace: Schema.String, |
| 79 | headers: Schema.optional(Schema.Record(Schema.String, OpenApiCredentialInputPayload)), | 72 | headers: Schema.optional(Schema.Record(Schema.String, OpenApiConfiguredValuePayload)), |
| 80 | queryParams: Schema.optional(Schema.Record(Schema.String, OpenApiCredentialInputPayload)), | 73 | queryParams: Schema.optional(Schema.Record(Schema.String, OpenApiConfiguredValuePayload)), |
| 81 | oauth2: Schema.optional(OAuth2SourceConfig), | 74 | oauth2: Schema.optional(OAuth2SourceConfig), |
| 82 | }); | 75 | }); |
| 83 | 76 | ||
| 84 | const PreviewSpecPayload = Schema.Struct({ | 77 | const PreviewSpecPayload = Schema.Struct({ |
| 85 | spec: Schema.String, | 78 | spec: Schema.String, |
| 86 | specFetchCredentials: Schema.optional(SpecFetchCredentialsPayload), | 79 | specFetchCredentials: Schema.optional(PreviewSpecFetchCredentialsPayload), |
| 87 | }); | 80 | }); |
| 88 | 81 | ||
| 89 | const UpdateSourcePayload = Schema.Struct({ | 82 | const UpdateSourcePayload = Schema.Struct({ |
| 90 | sourceScope: ScopeId, | 83 | sourceScope: ScopeId, |
| 91 | name: Schema.optional(Schema.String), | 84 | name: Schema.optional(Schema.String), |
| 92 | baseUrl: Schema.optional(Schema.String), | 85 | baseUrl: Schema.optional(Schema.String), |
| 93 | headers: Schema.optional(Schema.Record(Schema.String, OpenApiCredentialInputPayload)), | 86 | headers: Schema.optional(Schema.Record(Schema.String, OpenApiConfiguredValuePayload)), |
| 94 | queryParams: Schema.optional(Schema.Record(Schema.String, OpenApiCredentialInputPayload)), | 87 | queryParams: Schema.optional(Schema.Record(Schema.String, OpenApiConfiguredValuePayload)), |
| 95 | credentialTargetScope: Schema.optional(ScopeId), | ||
| 96 | // Set after a successful re-authenticate to refresh the source's | 88 | // Set after a successful re-authenticate to refresh the source's |
| 97 | // stored OAuth2 metadata. | 89 | // stored OAuth2 metadata. |
| 98 | oauth2: Schema.optional(OAuth2SourceConfig), | 90 | oauth2: Schema.optional(OAuth2SourceConfig), |
| @@ -3,10 +3,9 @@ import { Context, Effect } from "effect"; · 2 unmodified lines | |||
| 3 | 3 | ||
| 4 | import { addGroup, capture } from "@executor-js/api"; | 4 | import { addGroup, capture } from "@executor-js/api"; |
| 5 | import type { | 5 | import type { |
| 6 | ConfiguredHeaderValue, | 6 | OpenApiConfiguredValueInput, |
| 7 | OpenApiPluginExtension, | 7 | OpenApiPluginExtension, |
| 8 | HeaderValue, | 8 | OpenApiPreviewSpecFetchCredentialsInput, |
| 9 | OpenApiCredentialInput, | ||
| 10 | OpenApiSpecFetchCredentialsInput, | 9 | OpenApiSpecFetchCredentialsInput, |
| 11 | OpenApiUpdateSourceInput, | 10 | OpenApiUpdateSourceInput, |
| 12 | } from "../sdk/plugin"; | 11 | } from "../sdk/plugin"; |
| @@ -55,13 +54,13 @@ export const OpenApiHandlers = HttpApiBuilder.group(ExecutorApiWithOpenApi, "ope · 42 unmodified lines | |||
| 55 | return yield* ext.previewSpec({ | 54 | return yield* ext.previewSpec({ |
| 56 | spec: payload.spec, | 55 | spec: payload.spec, |
| 57 | specFetchCredentials: payload.specFetchCredentials as | 56 | specFetchCredentials: payload.specFetchCredentials as |
| 58 | | OpenApiSpecFetchCredentialsInput | 57 | | OpenApiPreviewSpecFetchCredentialsInput |
| 59 | | undefined, | 58 | | undefined, |
| 60 | }); | 59 | }); |
| 61 | }), | 60 | }), |
| 62 | ), | 61 | ), |
| 63 | ) | 62 | ) |
| 64 | .handle("addSpec", ({ payload }) => | 63 | .handle("addSpec", ({ params: path, payload }) => |
| 65 | capture( | 64 | capture( |
| 66 | Effect.gen(function* () { | 65 | Effect.gen(function* () { |
| 67 | const ext = yield* OpenApiExtensionService; | 66 | const ext = yield* OpenApiExtensionService; |
| @@ -70,15 +69,14 @@ export const OpenApiHandlers = HttpApiBuilder.group(ExecutorApiWithOpenApi, "ope · 2 unmodified lines | |||
| 70 | specFetchCredentials: payload.specFetchCredentials as | 69 | specFetchCredentials: payload.specFetchCredentials as |
| 71 | | OpenApiSpecFetchCredentialsInput | 70 | | OpenApiSpecFetchCredentialsInput |
| 72 | | undefined, | 71 | | undefined, |
| 73 | scope: payload.targetScope, | 72 | scope: path.scopeId, |
| 74 | name: payload.name, | 73 | name: payload.name, |
| 75 | baseUrl: payload.baseUrl, | 74 | baseUrl: payload.baseUrl, |
| 76 | namespace: payload.namespace, | 75 | namespace: payload.namespace, |
| 77 | credentialTargetScope: payload.credentialTargetScope, | 76 | headers: payload.headers as Record<string, OpenApiConfiguredValueInput> | undefined, |
| 78 | headers: payload.headers as | 77 | queryParams: payload.queryParams as |
| 79 | | Record<string, HeaderValue | ConfiguredHeaderValue> | 78 | | Record<string, OpenApiConfiguredValueInput> |
| 80 | | undefined, | 79 | | undefined, |
| 81 | queryParams: payload.queryParams as Record<string, OpenApiCredentialInput> | undefined, | ||
| 82 | oauth2: payload.oauth2, | 80 | oauth2: payload.oauth2, |
| 83 | }); | 81 | }); |
| 84 | return { | 82 | return { |
| @@ -119,11 +117,10 @@ export const OpenApiHandlers = HttpApiBuilder.group(ExecutorApiWithOpenApi, "ope · 34 unmodified lines | |||
| 119 | yield* ext.updateSource(path.namespace, payload.sourceScope, { | 117 | yield* ext.updateSource(path.namespace, payload.sourceScope, { |
| 120 | name: payload.name, | 118 | name: payload.name, |
| 121 | baseUrl: payload.baseUrl, | 119 | baseUrl: payload.baseUrl, |
| 122 | headers: payload.headers as | 120 | headers: payload.headers as Record<string, OpenApiConfiguredValueInput> | undefined, |
| 123 | | Record<string, HeaderValue | ConfiguredHeaderValue> | 121 | queryParams: payload.queryParams as |
| 122 | | Record<string, OpenApiConfiguredValueInput> | ||
| 124 | | undefined, | 123 | | undefined, |
| 125 | queryParams: payload.queryParams as Record<string, OpenApiCredentialInput> | undefined, | ||
| 126 | credentialTargetScope: payload.credentialTargetScope, | ||
| 127 | oauth2: payload.oauth2, | 124 | oauth2: payload.oauth2, |
| 128 | } as OpenApiUpdateSourceInput); | 125 | } as OpenApiUpdateSourceInput); |
| 129 | return { updated: true }; | 126 | return { updated: true }; |