History

[codex] Clean up OpenAPI add source API (#843)

* 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

Rhys Sullivan committed 6 months ago

Commit 529a54f1 parent 1d16b0b20 files · +1477 −467Browse files

Showing the changes to packages/plugins/openapi/src/api (2 of 20 files). Show all

Unified · Split

2 files
  1. packages/plugins/openapi/src/api/group.ts +23 −31
  2. packages/plugins/openapi/src/api/handlers.ts +11 −14
packages/plugins/openapi/src/api/group.ts+23−31
@@ -1,11 +1,6 @@
1import { HttpApiEndpoint, HttpApiGroup } from "effect/unstable/httpapi";1import { HttpApiEndpoint, HttpApiGroup } from "effect/unstable/httpapi";
2import { Schema } from "effect";2import { Schema } from "effect";
3import {3import { InternalError, ScopeId, SecretBackedValue } from "@executor-js/sdk/shared";
4 InternalError,
5 ScopeId,
6 ScopedSecretCredentialInput,
7 SecretBackedValue,
8} from "@executor-js/sdk/shared";
9 4
10import { OpenApiParseError, OpenApiExtractionError, OpenApiOAuthError } from "../sdk/errors";5import { OpenApiParseError, OpenApiExtractionError, OpenApiOAuthError } from "../sdk/errors";
11import { SpecPreview } from "../sdk/preview";6import { SpecPreview } from "../sdk/preview";
@@ -42,57 +37,54 @@ const SourceBindingParams = { · 30 unmodified lines
42 sourceScopeId: ScopeId,37 sourceScopeId: ScopeId,
43};38};
44 39
45const SpecFetchCredentialsPayload = Schema.Struct({40const 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
45const 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
50const ConfiguredCredentialBindingPayload = Schema.Struct({50const 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
56const ConfiguredCredentialValuePayload = Schema.Union([55const OpenApiConfiguredValuePayload = Schema.Union([Schema.String, OpenApiSecretShapePayload]);
57 Schema.String,
58 ConfiguredCredentialBindingPayload,
59]);
60 56
61const OpenApiCredentialInputPayload = Schema.Union([57const 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// Payloads63// Payloads
69// ---------------------------------------------------------------------------64// ---------------------------------------------------------------------------
70 65
71const AddSpecPayload = Schema.Struct({66const 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
84const PreviewSpecPayload = Schema.Struct({77const 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
89const UpdateSourcePayload = Schema.Struct({82const 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's88 // 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),
packages/plugins/openapi/src/api/handlers.ts+11−14
@@ -3,10 +3,9 @@ import { Context, Effect } from "effect"; · 2 unmodified lines
3 3
4import { addGroup, capture } from "@executor-js/api";4import { addGroup, capture } from "@executor-js/api";
5import type {5import 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 as56 specFetchCredentials: payload.specFetchCredentials as
58 | OpenApiSpecFetchCredentialsInput57 | 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 as69 specFetchCredentials: payload.specFetchCredentials as
71 | OpenApiSpecFetchCredentialsInput70 | 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 as77 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 as120 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 };