Unified · Split
| @@ -1,4 +1,4 @@ | |||
| 1 | import type { ExecutorApiClient } from "@executor/platform-api"; | 1 | import type { ExecutorApiEffectClient as ExecutorApiClient } from "@executor/platform-api/effect"; |
| 2 | import { ScopeIdSchema } from "@executor/platform-sdk/schema"; | 2 | import { ScopeIdSchema } from "@executor/platform-sdk/schema"; |
| 3 | import * as Effect from "effect/Effect"; | 3 | import * as Effect from "effect/Effect"; |
| 4 | 4 | ||
| @@ -10,9 +10,9 @@ import { · 9 unmodified lines | |||
| 10 | NodeRuntime, | 10 | NodeRuntime, |
| 11 | } from "@effect/platform-node"; | 11 | } from "@effect/platform-node"; |
| 12 | import { | 12 | import { |
| 13 | createExecutorApiClient, | 13 | createExecutorApiEffectClient as createExecutorApiClient, |
| 14 | type ExecutorApiClient, | 14 | type ExecutorApiEffectClient as ExecutorApiClient, |
| 15 | } from "@executor/platform-api"; | 15 | } from "@executor/platform-api/effect"; |
| 16 | import { createWorkspaceExecutorAdminToolMap } from "@executor/platform-internal"; | 16 | import { createWorkspaceExecutorAdminToolMap } from "@executor/platform-internal"; |
| 17 | import { | 17 | import { |
| 18 | EXECUTOR_SOURCES_ADD_HELP_LINES, | 18 | EXECUTOR_SOURCES_ADD_HELP_LINES, |
| @@ -20,8 +20,8 @@ import { · 1 unmodified line | |||
| 20 | } from "@executor/platform-sdk/runtime"; | 20 | } from "@executor/platform-sdk/runtime"; |
| 21 | import { | 21 | import { |
| 22 | createExecutorEffect, | 22 | createExecutorEffect, |
| 23 | type Executor, | 23 | type ExecutorEffect as Executor, |
| 24 | } from "@executor/platform-sdk"; | 24 | } from "@executor/platform-sdk/effect"; |
| 25 | import { createLocalExecutorBackend } from "@executor/platform-sdk-file"; | 25 | import { createLocalExecutorBackend } from "@executor/platform-sdk-file"; |
| 26 | import { | 26 | import { |
| 27 | ExecutionIdSchema, | 27 | ExecutionIdSchema, |
| @@ -4,8 +4,8 @@ import { describe, expect, it } from "@effect/vitest"; · 3 unmodified lines | |||
| 4 | import * as Effect from "effect/Effect"; | 4 | import * as Effect from "effect/Effect"; |
| 5 | 5 | ||
| 6 | import { | 6 | import { |
| 7 | createExecutorApiClient, | 7 | createExecutorApiEffectClient as createExecutorApiClient, |
| 8 | } from "@executor/platform-api"; | 8 | } from "@executor/platform-api/effect"; |
| 9 | import { type SourceDiscoveryKind } from "@executor/platform-sdk/schema"; | 9 | import { type SourceDiscoveryKind } from "@executor/platform-sdk/schema"; |
| 10 | import { createLocalExecutorServer } from "@executor/server"; | 10 | import { createLocalExecutorServer } from "@executor/server"; |
| 11 | 11 | ||
| @@ -20,9 +20,11 @@ import { startMcpElicitationDemoServer } from "@executor/mcp-elicitation-demo"; · 19 unmodified lines | |||
| 20 | import { makeToolInvokerFromTools, toTool } from "@executor/codemode-core"; | 20 | import { makeToolInvokerFromTools, toTool } from "@executor/codemode-core"; |
| 21 | import { startOpenApiTestServer } from "@executor/effect-test-utils"; | 21 | import { startOpenApiTestServer } from "@executor/effect-test-utils"; |
| 22 | import { | 22 | import { |
| 23 | createExecutorApiClient, | ||
| 24 | executorOpenApiSpec, | 23 | executorOpenApiSpec, |
| 25 | } from "@executor/platform-api"; | 24 | } from "@executor/platform-api"; |
| 25 | import { | ||
| 26 | createExecutorApiEffectClient as createExecutorApiClient, | ||
| 27 | } from "@executor/platform-api/effect"; | ||
| 26 | import { | 28 | import { |
| 27 | catalogSyncResultFromMcpManifest, | 29 | catalogSyncResultFromMcpManifest, |
| 28 | type ResolveExecutionEnvironment, | 30 | type ResolveExecutionEnvironment, |
| @@ -33,7 +35,7 @@ import { · 4 unmodified lines | |||
| 33 | resolveLocalWorkspaceContext, | 35 | resolveLocalWorkspaceContext, |
| 34 | writeLocalSourceArtifact, | 36 | writeLocalSourceArtifact, |
| 35 | writeProjectLocalExecutorConfig, | 37 | writeProjectLocalExecutorConfig, |
| 36 | } from "@executor/platform-sdk-file"; | 38 | } from "@executor/platform-sdk-file/effect"; |
| 37 | import { SourceIdSchema } from "@executor/platform-sdk/schema"; | 39 | import { SourceIdSchema } from "@executor/platform-sdk/schema"; |
| 38 | import { makeSesExecutor } from "@executor/runtime-ses"; | 40 | import { makeSesExecutor } from "@executor/runtime-ses"; |
| 39 | import { Client } from "@modelcontextprotocol/sdk/client/index.js"; | 41 | import { Client } from "@modelcontextprotocol/sdk/client/index.js"; |
| @@ -16,10 +16,10 @@ import { · 15 unmodified lines | |||
| 16 | } from "@executor/effect-test-utils"; | 16 | } from "@executor/effect-test-utils"; |
| 17 | import { | 17 | import { |
| 18 | createExecutorApiLayer, | 18 | createExecutorApiLayer, |
| 19 | } from "@executor/platform-api"; | 19 | } from "@executor/platform-api/http"; |
| 20 | import { createExecutorEffect } from "@executor/platform-sdk"; | 20 | import { createExecutorEffect } from "@executor/platform-sdk/effect"; |
| 21 | import type { ExecutorRuntime } from "@executor/platform-sdk/runtime"; | 21 | import type { ExecutorRuntime } from "@executor/platform-sdk/runtime"; |
| 22 | import { createLocalExecutorRuntime as createExecutorRuntime } from "@executor/platform-sdk-file"; | 22 | import { createLocalExecutorRuntime as createExecutorRuntime } from "@executor/platform-sdk-file/runtime"; |
| 23 | import type { | 23 | import type { |
| 24 | LocalInstallation, | 24 | LocalInstallation, |
| 25 | Source, | 25 | Source, |
| @@ -36,7 +36,6 @@ import type { · 35 unmodified lines | |||
| 36 | } from "@executor/platform-sdk/schema"; | 36 | } from "@executor/platform-sdk/schema"; |
| 37 | import * as Cause from "effect/Cause"; | 37 | import * as Cause from "effect/Cause"; |
| 38 | import * as Effect from "effect/Effect"; | 38 | import * as Effect from "effect/Effect"; |
| 39 | import * as Exit from "effect/Exit"; | ||
| 40 | import * as Option from "effect/Option"; | 39 | import * as Option from "effect/Option"; |
| 41 | import * as Runtime from "effect/Runtime"; | 40 | import * as Runtime from "effect/Runtime"; |
| 42 | import * as React from "react"; | 41 | import * as React from "react"; |
| @@ -189,12 +188,12 @@ const encodeWorkspaceOauthClientsKey = ( · 146 unmodified lines | |||
| 189 | [enabled, workspaceId, accountId, providerKey] satisfies WorkspaceOauthClientsKeyParts, | 188 | [enabled, workspaceId, accountId, providerKey] satisfies WorkspaceOauthClientsKeyParts, |
| 190 | ); | 189 | ); |
| 191 | 190 | ||
| 192 | const causeMessage = (cause: Cause.Cause<unknown>): Error => | ||
| 193 | new Error(Cause.pretty(cause)); | ||
| 194 | |||
| 195 | const toError = (cause: unknown): Error => | 191 | const toError = (cause: unknown): Error => |
| 196 | cause instanceof Error ? cause : new Error(String(cause)); | 192 | cause instanceof Error ? cause : new Error(String(cause)); |
| 197 | 193 | ||
| 194 | const causeMessage = (cause: Cause.Cause<unknown>): Error => | ||
| 195 | new Error(Cause.pretty(cause)); | ||
| 196 | |||
| 198 | const shouldLogExecutorDevErrors = (): boolean => { | 197 | const shouldLogExecutorDevErrors = (): boolean => { |
| 199 | if (typeof window === "undefined") { | 198 | if (typeof window === "undefined") { |
| 200 | return false; | 199 | return false; |
| @@ -238,36 +237,32 @@ const logExecutorDevError = (label: string, details: Record<string, unknown>): v · 37 unmodified lines | |||
| 238 | const runControlPlane = async <A>(input: { | 237 | const runControlPlane = async <A>(input: { |
| 239 | baseUrl?: string; | 238 | baseUrl?: string; |
| 240 | accountId?: string; | 239 | accountId?: string; |
| 241 | execute: (client: ExecutorApiClient) => Effect.Effect<A, unknown, never>; | 240 | execute: (client: ExecutorApiClient) => Promise<A>; |
| 242 | }): Promise<A> => { | 241 | }): Promise<A> => { |
| 243 | const baseUrl = input.baseUrl ?? apiBaseUrl; | 242 | const baseUrl = input.baseUrl ?? apiBaseUrl; |
| 244 | const accountId = input.accountId; | 243 | const accountId = input.accountId; |
| 245 | 244 | ||
| 246 | const exit = await Effect.runPromiseExit( | 245 | try { |
| 247 | createExecutorApiClient({ | 246 | const client = await createExecutorApiClient({ |
| 248 | baseUrl, | 247 | baseUrl, |
| 249 | ...(accountId !== undefined ? { accountId } : {}), | 248 | ...(accountId !== undefined ? { accountId } : {}), |
| 250 | }).pipe(Effect.flatMap(input.execute)), | 249 | }); |
| 251 | ); | 250 | return await input.execute(client); |
| 252 | 251 | } catch (cause) { | |
| 253 | if (Exit.isSuccess(exit)) { | 252 | const error = toError(cause); |
| 254 | return exit.value; | 253 | logExecutorDevError("control-plane request failed", { |
| 254 | baseUrl, | ||
| 255 | accountId, | ||
| 256 | error: describeExecutorDevError(error), | ||
| 257 | }); | ||
| 258 | throw error; | ||
| 255 | } | 259 | } |
| 256 | |||
| 257 | const error = Cause.squash(exit.cause); | ||
| 258 | logExecutorDevError("control-plane request failed", { | ||
| 259 | baseUrl, | ||
| 260 | accountId, | ||
| 261 | error: describeExecutorDevError(error), | ||
| 262 | cause: Cause.pretty(exit.cause), | ||
| 263 | }); | ||
| 264 | throw error; | ||
| 265 | }; | 260 | }; |
| 266 | 261 | ||
| 267 | const controlPlaneRequest = <A>(input: { | 262 | const controlPlaneRequest = <A>(input: { |
| 268 | baseUrl?: string; | 263 | baseUrl?: string; |
| 269 | accountId?: string; | 264 | accountId?: string; |
| 270 | execute: (client: ExecutorApiClient) => Effect.Effect<A, unknown, never>; | 265 | execute: (client: ExecutorApiClient) => Promise<A>; |
| 271 | }): Effect.Effect<A, Error> => | 266 | }): Effect.Effect<A, Error> => |
| 272 | Effect.tryPromise({ | 267 | Effect.tryPromise({ |
| 273 | try: () => runControlPlane(input), | 268 | try: () => runControlPlane(input), |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | |||
| 6 | ".": "./src/index.ts", | 6 | ".": "./src/index.ts", |
| 7 | "./api": "./src/api.ts", | 7 | "./api": "./src/api.ts", |
| 8 | "./client": "./src/client.ts", | 8 | "./client": "./src/client.ts", |
| 9 | "./effect": "./src/effect.ts", | ||
| 9 | "./http": "./src/http.ts", | 10 | "./http": "./src/http.ts", |
| 10 | "./errors": "./src/errors.ts", | 11 | "./errors": "./src/errors.ts", |
| 11 | "./local/api": "./src/local/api.ts", | 12 | "./local/api": "./src/local/api.ts", |
| @@ -1,19 +1,196 @@ | |||
| 1 | import { | ||
| 2 | FetchHttpClient, | ||
| 3 | HttpApiClient, | ||
| 4 | } from "@effect/platform"; | ||
| 5 | import * as Effect from "effect/Effect"; | 1 | import * as Effect from "effect/Effect"; |
| 6 | 2 | ||
| 7 | import { ExecutorApi } from "./api"; | 3 | import { |
| 4 | createExecutorApiEffectClient, | ||
| 5 | type ExecutorApiEffectClient, | ||
| 6 | } from "./effect"; | ||
| 7 | |||
| 8 | type StripResponse<T> = T extends readonly [infer Value, unknown] ? Value : T; | ||
| 9 | type RemoveWithResponse<T> = T extends object ? Omit<T, "withResponse"> : T; | ||
| 10 | type MethodInput<F extends (input: any) => Effect.Effect<any, any, any>> = RemoveWithResponse< | ||
| 11 | Parameters<F>[0] | ||
| 12 | >; | ||
| 13 | type MethodOutput<F extends (input: any) => Effect.Effect<any, any, any>> = StripResponse< | ||
| 14 | Effect.Effect.Success<ReturnType<F>> | ||
| 15 | >; | ||
| 16 | type PromiseMethod<F extends (input: any) => Effect.Effect<any, any, any>> = ( | ||
| 17 | input: MethodInput<F>, | ||
| 18 | ) => Promise<MethodOutput<F>>; | ||
| 19 | |||
| 20 | export type ExecutorApiClient = { | ||
| 21 | local: { | ||
| 22 | installation: PromiseMethod<ExecutorApiEffectClient["local"]["installation"]>; | ||
| 23 | config: PromiseMethod<ExecutorApiEffectClient["local"]["config"]>; | ||
| 24 | listSecrets: PromiseMethod<ExecutorApiEffectClient["local"]["listSecrets"]>; | ||
| 25 | createSecret: PromiseMethod<ExecutorApiEffectClient["local"]["createSecret"]>; | ||
| 26 | updateSecret: PromiseMethod<ExecutorApiEffectClient["local"]["updateSecret"]>; | ||
| 27 | deleteSecret: PromiseMethod<ExecutorApiEffectClient["local"]["deleteSecret"]>; | ||
| 28 | }; | ||
| 29 | policies: { | ||
| 30 | list: PromiseMethod<ExecutorApiEffectClient["policies"]["list"]>; | ||
| 31 | create: PromiseMethod<ExecutorApiEffectClient["policies"]["create"]>; | ||
| 32 | get: PromiseMethod<ExecutorApiEffectClient["policies"]["get"]>; | ||
| 33 | update: PromiseMethod<ExecutorApiEffectClient["policies"]["update"]>; | ||
| 34 | remove: PromiseMethod<ExecutorApiEffectClient["policies"]["remove"]>; | ||
| 35 | }; | ||
| 36 | sources: { | ||
| 37 | discover: PromiseMethod<ExecutorApiEffectClient["sources"]["discover"]>; | ||
| 38 | connect: PromiseMethod<ExecutorApiEffectClient["sources"]["connect"]>; | ||
| 39 | connectBatch: PromiseMethod<ExecutorApiEffectClient["sources"]["connectBatch"]>; | ||
| 40 | listWorkspaceOauthClients: PromiseMethod< | ||
| 41 | ExecutorApiEffectClient["sources"]["listWorkspaceOauthClients"] | ||
| 42 | >; | ||
| 43 | createWorkspaceOauthClient: PromiseMethod< | ||
| 44 | ExecutorApiEffectClient["sources"]["createWorkspaceOauthClient"] | ||
| 45 | >; | ||
| 46 | removeWorkspaceOauthClient: PromiseMethod< | ||
| 47 | ExecutorApiEffectClient["sources"]["removeWorkspaceOauthClient"] | ||
| 48 | >; | ||
| 49 | removeProviderAuthGrant: PromiseMethod< | ||
| 50 | ExecutorApiEffectClient["sources"]["removeProviderAuthGrant"] | ||
| 51 | >; | ||
| 52 | list: PromiseMethod<ExecutorApiEffectClient["sources"]["list"]>; | ||
| 53 | create: PromiseMethod<ExecutorApiEffectClient["sources"]["create"]>; | ||
| 54 | get: PromiseMethod<ExecutorApiEffectClient["sources"]["get"]>; | ||
| 55 | update: PromiseMethod<ExecutorApiEffectClient["sources"]["update"]>; | ||
| 56 | remove: PromiseMethod<ExecutorApiEffectClient["sources"]["remove"]>; | ||
| 57 | inspection: PromiseMethod<ExecutorApiEffectClient["sources"]["inspection"]>; | ||
| 58 | inspectionTool: PromiseMethod<ExecutorApiEffectClient["sources"]["inspectionTool"]>; | ||
| 59 | inspectionDiscover: PromiseMethod< | ||
| 60 | ExecutorApiEffectClient["sources"]["inspectionDiscover"] | ||
| 61 | >; | ||
| 62 | credentialPage: PromiseMethod<ExecutorApiEffectClient["sources"]["credentialPage"]>; | ||
| 63 | credentialSubmit: PromiseMethod<ExecutorApiEffectClient["sources"]["credentialSubmit"]>; | ||
| 64 | credentialComplete: PromiseMethod< | ||
| 65 | ExecutorApiEffectClient["sources"]["credentialComplete"] | ||
| 66 | >; | ||
| 67 | providerOauthComplete: PromiseMethod< | ||
| 68 | ExecutorApiEffectClient["sources"]["providerOauthComplete"] | ||
| 69 | >; | ||
| 70 | }; | ||
| 71 | oauth: { | ||
| 72 | startSourceAuth: PromiseMethod<ExecutorApiEffectClient["oauth"]["startSourceAuth"]>; | ||
| 73 | sourceAuthCallback: PromiseMethod<ExecutorApiEffectClient["oauth"]["sourceAuthCallback"]>; | ||
| 74 | }; | ||
| 75 | executions: { | ||
| 76 | create: PromiseMethod<ExecutorApiEffectClient["executions"]["create"]>; | ||
| 77 | get: PromiseMethod<ExecutorApiEffectClient["executions"]["get"]>; | ||
| 78 | resume: PromiseMethod<ExecutorApiEffectClient["executions"]["resume"]>; | ||
| 79 | }; | ||
| 80 | }; | ||
| 8 | 81 | ||
| 9 | export const createExecutorApiClient = (input: { | 82 | const isResponseTuple = <Value>( |
| 83 | value: Value | readonly [Value, unknown], | ||
| 84 | ): value is readonly [Value, unknown] => | ||
| 85 | Array.isArray(value) && value.length === 2; | ||
| 86 | |||
| 87 | function stripResponse<Value>(value: Value | readonly [Value, unknown]): Value { | ||
| 88 | return isResponseTuple(value) ? value[0] : value; | ||
| 89 | } | ||
| 90 | |||
| 91 | const wrapMethod = < | ||
| 92 | F extends (input: any) => Effect.Effect<any, unknown, never>, | ||
| 93 | >( | ||
| 94 | effectClientPromise: Promise<ExecutorApiEffectClient>, | ||
| 95 | select: (client: ExecutorApiEffectClient) => F, | ||
| 96 | ): PromiseMethod<F> => { | ||
| 97 | const wrapped = (input: MethodInput<F>): Promise<MethodOutput<F>> => | ||
| 98 | effectClientPromise | ||
| 99 | .then((client) => Effect.runPromise(select(client)(input))) | ||
| 100 | .then(stripResponse); | ||
| 101 | |||
| 102 | return wrapped; | ||
| 103 | }; | ||
| 104 | |||
| 105 | export const createExecutorApiClient = async (input: { | ||
| 10 | baseUrl: string; | 106 | baseUrl: string; |
| 11 | accountId?: string; | 107 | accountId?: string; |
| 12 | }) => | 108 | }): Promise<ExecutorApiClient> => { |
| 13 | HttpApiClient.make(ExecutorApi, { | 109 | const effectClientPromise = Effect.runPromise( |
| 14 | baseUrl: input.baseUrl, | 110 | createExecutorApiEffectClient(input), |
| 15 | }).pipe(Effect.provide(FetchHttpClient.layer)); | 111 | ); |
| 16 | 112 | ||
| 17 | export type ExecutorApiClient = Effect.Effect.Success< | 113 | return { |
| 18 | ReturnType<typeof createExecutorApiClient> | 114 | local: { |
| 19 | >; | 115 | installation: wrapMethod(effectClientPromise, (client) => client.local.installation), |
| 116 | config: wrapMethod(effectClientPromise, (client) => client.local.config), | ||
| 117 | listSecrets: wrapMethod(effectClientPromise, (client) => client.local.listSecrets), | ||
| 118 | createSecret: wrapMethod(effectClientPromise, (client) => client.local.createSecret), | ||
| 119 | updateSecret: wrapMethod(effectClientPromise, (client) => client.local.updateSecret), | ||
| 120 | deleteSecret: wrapMethod(effectClientPromise, (client) => client.local.deleteSecret), | ||
| 121 | }, | ||
| 122 | policies: { | ||
| 123 | list: wrapMethod(effectClientPromise, (client) => client.policies.list), | ||
| 124 | create: wrapMethod(effectClientPromise, (client) => client.policies.create), | ||
| 125 | get: wrapMethod(effectClientPromise, (client) => client.policies.get), | ||
| 126 | update: wrapMethod(effectClientPromise, (client) => client.policies.update), | ||
| 127 | remove: wrapMethod(effectClientPromise, (client) => client.policies.remove), | ||
| 128 | }, | ||
| 129 | sources: { | ||
| 130 | discover: wrapMethod(effectClientPromise, (client) => client.sources.discover), | ||
| 131 | connect: wrapMethod(effectClientPromise, (client) => client.sources.connect), | ||
| 132 | connectBatch: wrapMethod(effectClientPromise, (client) => client.sources.connectBatch), | ||
| 133 | listWorkspaceOauthClients: wrapMethod( | ||
| 134 | effectClientPromise, | ||
| 135 | (client) => client.sources.listWorkspaceOauthClients, | ||
| 136 | ), | ||
| 137 | createWorkspaceOauthClient: wrapMethod( | ||
| 138 | effectClientPromise, | ||
| 139 | (client) => client.sources.createWorkspaceOauthClient, | ||
| 140 | ), | ||
| 141 | removeWorkspaceOauthClient: wrapMethod( | ||
| 142 | effectClientPromise, | ||
| 143 | (client) => client.sources.removeWorkspaceOauthClient, | ||
| 144 | ), | ||
| 145 | removeProviderAuthGrant: wrapMethod( | ||
| 146 | effectClientPromise, | ||
| 147 | (client) => client.sources.removeProviderAuthGrant, | ||
| 148 | ), | ||
| 149 | list: wrapMethod(effectClientPromise, (client) => client.sources.list), | ||
| 150 | create: wrapMethod(effectClientPromise, (client) => client.sources.create), | ||
| 151 | get: wrapMethod(effectClientPromise, (client) => client.sources.get), | ||
| 152 | update: wrapMethod(effectClientPromise, (client) => client.sources.update), | ||
| 153 | remove: wrapMethod(effectClientPromise, (client) => client.sources.remove), | ||
| 154 | inspection: wrapMethod(effectClientPromise, (client) => client.sources.inspection), | ||
| 155 | inspectionTool: wrapMethod( | ||
| 156 | effectClientPromise, | ||
| 157 | (client) => client.sources.inspectionTool, | ||
| 158 | ), | ||
| 159 | inspectionDiscover: wrapMethod( | ||
| 160 | effectClientPromise, | ||
| 161 | (client) => client.sources.inspectionDiscover, | ||
| 162 | ), | ||
| 163 | credentialPage: wrapMethod( | ||
| 164 | effectClientPromise, | ||
| 165 | (client) => client.sources.credentialPage, | ||
| 166 | ), | ||
| 167 | credentialSubmit: wrapMethod( | ||
| 168 | effectClientPromise, | ||
| 169 | (client) => client.sources.credentialSubmit, | ||
| 170 | ), | ||
| 171 | credentialComplete: wrapMethod( | ||
| 172 | effectClientPromise, | ||
| 173 | (client) => client.sources.credentialComplete, | ||
| 174 | ), | ||
| 175 | providerOauthComplete: wrapMethod( | ||
| 176 | effectClientPromise, | ||
| 177 | (client) => client.sources.providerOauthComplete, | ||
| 178 | ), | ||
| 179 | }, | ||
| 180 | oauth: { | ||
| 181 | startSourceAuth: wrapMethod( | ||
| 182 | effectClientPromise, | ||
| 183 | (client) => client.oauth.startSourceAuth, | ||
| 184 | ), | ||
| 185 | sourceAuthCallback: wrapMethod( | ||
| 186 | effectClientPromise, | ||
| 187 | (client) => client.oauth.sourceAuthCallback, | ||
| 188 | ), | ||
| 189 | }, | ||
| 190 | executions: { | ||
| 191 | create: wrapMethod(effectClientPromise, (client) => client.executions.create), | ||
| 192 | get: wrapMethod(effectClientPromise, (client) => client.executions.get), | ||
| 193 | resume: wrapMethod(effectClientPromise, (client) => client.executions.resume), | ||
| 194 | }, | ||
| 195 | }; | ||
| 196 | }; | ||
| @@ -0,0 +1,19 @@ | |||
| 1 | import { | ||
| 2 | FetchHttpClient, | ||
| 3 | HttpApiClient, | ||
| 4 | } from "@effect/platform"; | ||
| 5 | import * as Effect from "effect/Effect"; | ||
| 6 | |||
| 7 | import { ExecutorApi } from "./api"; | ||
| 8 | |||
| 9 | export const createExecutorApiEffectClient = (input: { | ||
| 10 | baseUrl: string; | ||
| 11 | accountId?: string; | ||
| 12 | }) => | ||
| 13 | HttpApiClient.make(ExecutorApi, { | ||
| 14 | baseUrl: input.baseUrl, | ||
| 15 | }).pipe(Effect.provide(FetchHttpClient.layer)); | ||
| 16 | |||
| 17 | export type ExecutorApiEffectClient = Effect.Effect.Success< | ||
| 18 | ReturnType<typeof createExecutorApiEffectClient> | ||
| 19 | >; | ||
| @@ -11,19 +11,17 @@ export const ExecutorExecutionsLive = HttpApiBuilder.group( · 10 unmodified lines | |||
| 11 | handlers | 11 | handlers |
| 12 | .handle("create", ({ path, payload }) => | 12 | .handle("create", ({ path, payload }) => |
| 13 | resolveRequestedLocalWorkspace("executions.create", path.workspaceId).pipe( | 13 | resolveRequestedLocalWorkspace("executions.create", path.workspaceId).pipe( |
| 14 | Effect.flatMap((executor) => executor.effect.executions.create(payload)), | 14 | Effect.flatMap((executor) => executor.executions.create(payload)), |
| 15 | ), | 15 | ), |
| 16 | ) | 16 | ) |
| 17 | .handle("get", ({ path }) => | 17 | .handle("get", ({ path }) => |
| 18 | resolveRequestedLocalWorkspace("executions.get", path.workspaceId).pipe( | 18 | resolveRequestedLocalWorkspace("executions.get", path.workspaceId).pipe( |
| 19 | Effect.flatMap((executor) => executor.effect.executions.get(path.executionId)), | 19 | Effect.flatMap((executor) => executor.executions.get(path.executionId)), |
| 20 | ), | 20 | ), |
| 21 | ) | 21 | ) |
| 22 | .handle("resume", ({ path, payload }) => | 22 | .handle("resume", ({ path, payload }) => |
| 23 | resolveRequestedLocalWorkspace("executions.resume", path.workspaceId).pipe( | 23 | resolveRequestedLocalWorkspace("executions.resume", path.workspaceId).pipe( |
| 24 | Effect.flatMap((executor) => | 24 | Effect.flatMap((executor) => executor.executions.resume(path.executionId, payload)), |
| 25 | executor.effect.executions.resume(path.executionId, payload) | ||
| 26 | ), | ||
| 27 | ), | 25 | ), |
| 28 | ), | 26 | ), |
| 29 | ); | 27 | ); |
| @@ -1,4 +1,4 @@ | |||
| 1 | import type { Executor } from "@executor/platform-sdk"; | 1 | import type { ExecutorEffect } from "@executor/platform-sdk/effect"; |
| 2 | import type { ScopeId as WorkspaceId } from "@executor/platform-sdk/schema"; | 2 | import type { ScopeId as WorkspaceId } from "@executor/platform-sdk/schema"; |
| 3 | import { | 3 | import { |
| 4 | ControlPlaneBadRequestError, | 4 | ControlPlaneBadRequestError, |
| @@ -11,9 +11,9 @@ import * as Layer from "effect/Layer"; · 6 unmodified lines | |||
| 11 | 11 | ||
| 12 | export class ControlPlaneExecutor extends Context.Tag( | 12 | export class ControlPlaneExecutor extends Context.Tag( |
| 13 | "@executor/platform-api/ControlPlaneExecutor", | 13 | "@executor/platform-api/ControlPlaneExecutor", |
| 14 | )<ControlPlaneExecutor, Executor>() {} | 14 | )<ControlPlaneExecutor, ExecutorEffect>() {} |
| 15 | 15 | ||
| 16 | export const createControlPlaneExecutorLayer = (executor: Executor) => | 16 | export const createControlPlaneExecutorLayer = (executor: ExecutorEffect) => |
| 17 | Layer.succeed(ControlPlaneExecutor, executor); | 17 | Layer.succeed(ControlPlaneExecutor, executor); |
| 18 | 18 | ||
| 19 | export const getControlPlaneExecutor = () => ControlPlaneExecutor; | 19 | export const getControlPlaneExecutor = () => ControlPlaneExecutor; |
| @@ -1,6 +1,6 @@ | |||
| 1 | import { HttpApiBuilder } from "@effect/platform"; | 1 | import { HttpApiBuilder } from "@effect/platform"; |
| 2 | import * as Layer from "effect/Layer"; | 2 | import * as Layer from "effect/Layer"; |
| 3 | import type { Executor } from "@executor/platform-sdk"; | 3 | import type { ExecutorEffect } from "@executor/platform-sdk/effect"; |
| 4 | 4 | ||
| 5 | import { ExecutorApi } from "./api"; | 5 | import { ExecutorApi } from "./api"; |
| 6 | import { createControlPlaneExecutorLayer } from "./executor-context"; | 6 | import { createControlPlaneExecutorLayer } from "./executor-context"; |
| @@ -20,7 +20,7 @@ export const ExecutorApiLive = HttpApiBuilder.api(ExecutorApi).pipe( · 13 unmodified lines | |||
| 20 | 20 | ||
| 21 | export type ExecutorApiRuntimeContext = Layer.Layer.Context<typeof ExecutorApiLive>; | 21 | export type ExecutorApiRuntimeContext = Layer.Layer.Context<typeof ExecutorApiLive>; |
| 22 | 22 | ||
| 23 | export const createExecutorApiLayer = (executor: Executor) => | 23 | export const createExecutorApiLayer = (executor: ExecutorEffect) => |
| 24 | ExecutorApiLive.pipe( | 24 | ExecutorApiLive.pipe( |
| 25 | Layer.provide(createControlPlaneExecutorLayer(executor)), | 25 | Layer.provide(createControlPlaneExecutorLayer(executor)), |
| 26 | ); | 26 | ); |
| @@ -17,13 +17,6 @@ export { · 16 unmodified lines | |||
| 17 | ControlPlaneUnauthorizedError, | 17 | ControlPlaneUnauthorizedError, |
| 18 | } from "./errors"; | 18 | } from "./errors"; |
| 19 | 19 | ||
| 20 | export { | ||
| 21 | ExecutorApiLive, | ||
| 22 | type ExecutorApiRuntimeContext, | ||
| 23 | type BuiltExecutorApiLayer, | ||
| 24 | createExecutorApiLayer, | ||
| 25 | } from "./http"; | ||
| 26 | |||
| 27 | export { | 20 | export { |
| 28 | CreateExecutionPayloadSchema, | 21 | CreateExecutionPayloadSchema, |
| 29 | ExecutionsApi, | 22 | ExecutionsApi, |
| @@ -31,7 +24,6 @@ export { · 1 unmodified line | |||
| 31 | type CreateExecutionPayload, | 24 | type CreateExecutionPayload, |
| 32 | type ResumeExecutionPayload, | 25 | type ResumeExecutionPayload, |
| 33 | } from "./executions/api"; | 26 | } from "./executions/api"; |
| 34 | export { ExecutorExecutionsLive } from "./executions/http"; | ||
| 35 | 27 | ||
| 36 | export { | 28 | export { |
| 37 | LocalApi, | 29 | LocalApi, |
| @@ -44,7 +36,6 @@ export { · 6 unmodified lines | |||
| 44 | type UpdateSecretResult, | 36 | type UpdateSecretResult, |
| 45 | type DeleteSecretResult, | 37 | type DeleteSecretResult, |
| 46 | } from "./local/api"; | 38 | } from "./local/api"; |
| 47 | export { ExecutorLocalLive } from "./local/http"; | ||
| 48 | 39 | ||
| 49 | export { | 40 | export { |
| 50 | OAuthApi, | 41 | OAuthApi, |
| @@ -59,7 +50,6 @@ export { · 8 unmodified lines | |||
| 59 | type CompleteSourceOAuthResult, | 50 | type CompleteSourceOAuthResult, |
| 60 | type SourceOAuthPopupResult, | 51 | type SourceOAuthPopupResult, |
| 61 | } from "./oauth/api"; | 52 | } from "./oauth/api"; |
| 62 | export { ExecutorOAuthLive } from "./oauth/http"; | ||
| 63 | 53 | ||
| 64 | export { | 54 | export { |
| 65 | ConnectSourceBatchPayloadSchema, | 55 | ConnectSourceBatchPayloadSchema, |
| @@ -80,7 +70,6 @@ export { · 14 unmodified lines | |||
| 80 | type DiscoverSourcePayload, | 70 | type DiscoverSourcePayload, |
| 81 | type UpdateSourcePayload, | 71 | type UpdateSourcePayload, |
| 82 | } from "./sources/api"; | 72 | } from "./sources/api"; |
| 83 | export { ExecutorSourcesLive } from "./sources/http"; | ||
| 84 | 73 | ||
| 85 | export { | 74 | export { |
| 86 | CreatePolicyPayloadSchema, | 75 | CreatePolicyPayloadSchema, |
| @@ -89,6 +78,3 @@ export { · 2 unmodified lines | |||
| 89 | type CreatePolicyPayload, | 78 | type CreatePolicyPayload, |
| 90 | type UpdatePolicyPayload, | 79 | type UpdatePolicyPayload, |
| 91 | } from "./policies/api"; | 80 | } from "./policies/api"; |
| 92 | export { ExecutorPoliciesLive } from "./policies/http"; | ||
| 93 | |||
| 94 | export { resolveRequestedLocalWorkspace } from "./local-context"; | ||
| @@ -19,35 +19,35 @@ export const ExecutorLocalLive = HttpApiBuilder.group( · 18 unmodified lines | |||
| 19 | handlers | 19 | handlers |
| 20 | .handle("installation", () => | 20 | .handle("installation", () => |
| 21 | Effect.flatMap(getControlPlaneExecutor(), (executor) => | 21 | Effect.flatMap(getControlPlaneExecutor(), (executor) => |
| 22 | executor.effect.local.installation().pipe( | 22 | executor.local.installation().pipe( |
| 23 | Effect.mapError(toStorageError("local.installation")), | 23 | Effect.mapError(toStorageError("local.installation")), |
| 24 | ) | 24 | ) |
| 25 | ) | 25 | ) |
| 26 | ) | 26 | ) |
| 27 | .handle("config", () => | 27 | .handle("config", () => |
| 28 | Effect.flatMap(getControlPlaneExecutor(), (executor) => | 28 | Effect.flatMap(getControlPlaneExecutor(), (executor) => |
| 29 | executor.effect.local.config().pipe( | 29 | executor.local.config().pipe( |
| 30 | Effect.mapError(toStorageError("local.config")), | 30 | Effect.mapError(toStorageError("local.config")), |
| 31 | ) | 31 | ) |
| 32 | ) | 32 | ) |
| 33 | ) | 33 | ) |
| 34 | .handle("listSecrets", () => | 34 | .handle("listSecrets", () => |
| 35 | Effect.flatMap(getControlPlaneExecutor(), (executor) => | 35 | Effect.flatMap(getControlPlaneExecutor(), (executor) => |
| 36 | executor.effect.secrets.list().pipe( | 36 | executor.secrets.list().pipe( |
| 37 | Effect.mapError(toStorageError("local.listSecrets")), | 37 | Effect.mapError(toStorageError("local.listSecrets")), |
| 38 | ) | 38 | ) |
| 39 | ) | 39 | ) |
| 40 | ) | 40 | ) |
| 41 | .handle("createSecret", ({ payload }) => | 41 | .handle("createSecret", ({ payload }) => |
| 42 | Effect.flatMap(getControlPlaneExecutor(), (executor) => | 42 | Effect.flatMap(getControlPlaneExecutor(), (executor) => |
| 43 | executor.effect.secrets.create(payload).pipe( | 43 | executor.secrets.create(payload).pipe( |
| 44 | Effect.mapError(toStorageError("local.createSecret")), | 44 | Effect.mapError(toStorageError("local.createSecret")), |
| 45 | ) | 45 | ) |
| 46 | ) | 46 | ) |
| 47 | ) | 47 | ) |
| 48 | .handle("updateSecret", ({ path, payload }) => | 48 | .handle("updateSecret", ({ path, payload }) => |
| 49 | Effect.flatMap(getControlPlaneExecutor(), (executor) => | 49 | Effect.flatMap(getControlPlaneExecutor(), (executor) => |
| 50 | executor.effect.secrets.update({ | 50 | executor.secrets.update({ |
| 51 | secretId: path.secretId, | 51 | secretId: path.secretId, |
| 52 | payload, | 52 | payload, |
| 53 | }).pipe(Effect.mapError(toStorageError("local.updateSecret"))) | 53 | }).pipe(Effect.mapError(toStorageError("local.updateSecret"))) |
| @@ -55,7 +55,7 @@ export const ExecutorLocalLive = HttpApiBuilder.group( · 1 unmodified line | |||
| 55 | ) | 55 | ) |
| 56 | .handle("deleteSecret", ({ path }) => | 56 | .handle("deleteSecret", ({ path }) => |
| 57 | Effect.flatMap(getControlPlaneExecutor(), (executor) => | 57 | Effect.flatMap(getControlPlaneExecutor(), (executor) => |
| 58 | executor.effect.secrets.remove(path.secretId).pipe( | 58 | executor.secrets.remove(path.secretId).pipe( |
| 59 | Effect.mapError(toStorageError("local.deleteSecret")), | 59 | Effect.mapError(toStorageError("local.deleteSecret")), |
| 60 | ) | 60 | ) |
| 61 | ) | 61 | ) |
| @@ -241,7 +241,7 @@ export const ExecutorOAuthLive = HttpApiBuilder.group( · 240 unmodified lines | |||
| 241 | Effect.flatMap((executor) => | 241 | Effect.flatMap((executor) => |
| 242 | Effect.gen(function* () { | 242 | Effect.gen(function* () { |
| 243 | const request = yield* HttpServerRequest.HttpServerRequest; | 243 | const request = yield* HttpServerRequest.HttpServerRequest; |
| 244 | return yield* executor.effect.oauth.startSourceAuth({ | 244 | return yield* executor.oauth.startSourceAuth({ |
| 245 | baseUrl: resolveRequestOrigin(request), | 245 | baseUrl: resolveRequestOrigin(request), |
| 246 | displayName: payload.name, | 246 | displayName: payload.name, |
| 247 | provider: { | 247 | provider: { |
| @@ -271,7 +271,7 @@ export const ExecutorOAuthLive = HttpApiBuilder.group( · 23 unmodified lines | |||
| 271 | Effect.flatMap(getControlPlaneExecutor(), (executor) => | 271 | Effect.flatMap(getControlPlaneExecutor(), (executor) => |
| 272 | Effect.gen(function* () { | 272 | Effect.gen(function* () { |
| 273 | const completed = yield* Effect.either( | 273 | const completed = yield* Effect.either( |
| 274 | executor.effect.oauth.completeSourceAuth({ | 274 | executor.oauth.completeSourceAuth({ |
| 275 | state: urlParams.state, | 275 | state: urlParams.state, |
| 276 | code: urlParams.code, | 276 | code: urlParams.code, |
| 277 | error: urlParams.error, | 277 | error: urlParams.error, |
| @@ -11,7 +11,7 @@ export const ExecutorPoliciesLive = HttpApiBuilder.group( · 10 unmodified lines | |||
| 11 | handlers | 11 | handlers |
| 12 | .handle("list", ({ path }) => | 12 | .handle("list", ({ path }) => |
| 13 | resolveRequestedLocalWorkspace("policies.list", path.workspaceId).pipe( | 13 | resolveRequestedLocalWorkspace("policies.list", path.workspaceId).pipe( |
| 14 | Effect.flatMap((executor) => executor.effect.policies.list()), | 14 | Effect.flatMap((executor) => executor.policies.list()), |
| 15 | ), | 15 | ), |
| 16 | ) | 16 | ) |
| 17 | .handle("create", ({ path, payload }) => | 17 | .handle("create", ({ path, payload }) => |
| @@ -19,12 +19,12 @@ export const ExecutorPoliciesLive = HttpApiBuilder.group( · 1 unmodified line | |||
| 19 | "policies.create", | 19 | "policies.create", |
| 20 | path.workspaceId, | 20 | path.workspaceId, |
| 21 | ).pipe( | 21 | ).pipe( |
| 22 | Effect.flatMap((executor) => executor.effect.policies.create(payload)), | 22 | Effect.flatMap((executor) => executor.policies.create(payload)), |
| 23 | ), | 23 | ), |
| 24 | ) | 24 | ) |
| 25 | .handle("get", ({ path }) => | 25 | .handle("get", ({ path }) => |
| 26 | resolveRequestedLocalWorkspace("policies.get", path.workspaceId).pipe( | 26 | resolveRequestedLocalWorkspace("policies.get", path.workspaceId).pipe( |
| 27 | Effect.flatMap((executor) => executor.effect.policies.get(path.policyId)), | 27 | Effect.flatMap((executor) => executor.policies.get(path.policyId)), |
| 28 | ), | 28 | ), |
| 29 | ) | 29 | ) |
| 30 | .handle("update", ({ path, payload }) => | 30 | .handle("update", ({ path, payload }) => |
| @@ -32,9 +32,7 @@ export const ExecutorPoliciesLive = HttpApiBuilder.group( · 1 unmodified line | |||
| 32 | "policies.update", | 32 | "policies.update", |
| 33 | path.workspaceId, | 33 | path.workspaceId, |
| 34 | ).pipe( | 34 | ).pipe( |
| 35 | Effect.flatMap((executor) => | 35 | Effect.flatMap((executor) => executor.policies.update(path.policyId, payload)), |
| 36 | executor.effect.policies.update(path.policyId, payload) | ||
| 37 | ), | ||
| 38 | ), | 36 | ), |
| 39 | ) | 37 | ) |
| 40 | .handle("remove", ({ path }) => | 38 | .handle("remove", ({ path }) => |
| @@ -42,10 +40,8 @@ export const ExecutorPoliciesLive = HttpApiBuilder.group( · 1 unmodified line | |||
| 42 | "policies.remove", | 40 | "policies.remove", |
| 43 | path.workspaceId, | 41 | path.workspaceId, |
| 44 | ).pipe( | 42 | ).pipe( |
| 45 | Effect.flatMap((executor) => executor.effect.policies.remove(path.policyId)), | 43 | Effect.flatMap((executor) => executor.policies.remove(path.policyId)), |
| 46 | Effect.map((result) => ({ | 44 | Effect.map((removed) => ({ removed })), |
| 47 | removed: result.removed, | ||
| 48 | })), | ||
| 49 | ), | 45 | ), |
| 50 | ), | 46 | ), |
| 51 | ); | 47 | ); |
| @@ -713,7 +713,7 @@ const credentialSubmitErrorResponse = (input: { · 712 unmodified lines | |||
| 713 | input.workspaceId, | 713 | input.workspaceId, |
| 714 | ).pipe( | 714 | ).pipe( |
| 715 | Effect.flatMap((executor) => | 715 | Effect.flatMap((executor) => |
| 716 | executor.effect.local.credentials.get({ | 716 | executor.local.credentials.get({ |
| 717 | sourceId: input.sourceId, | 717 | sourceId: input.sourceId, |
| 718 | interactionId: input.interactionId, | 718 | interactionId: input.interactionId, |
| 719 | }), | 719 | }), |
| @@ -749,7 +749,7 @@ export const ExecutorSourcesLive = HttpApiBuilder.group( · 29 unmodified lines | |||
| 749 | handlers | 749 | handlers |
| 750 | .handle("discover", ({ payload }) => | 750 | .handle("discover", ({ payload }) => |
| 751 | Effect.flatMap(getControlPlaneExecutor(), (executor) => | 751 | Effect.flatMap(getControlPlaneExecutor(), (executor) => |
| 752 | executor.effect.sources.discover({ | 752 | executor.sources.discover({ |
| 753 | url: payload.url, | 753 | url: payload.url, |
| 754 | probeAuth: payload.probeAuth, | 754 | probeAuth: payload.probeAuth, |
| 755 | }).pipe( | 755 | }).pipe( |
| @@ -770,14 +770,14 @@ export const ExecutorSourcesLive = HttpApiBuilder.group( · 14 unmodified lines | |||
| 770 | const baseUrl = resolveRequestOrigin(request); | 770 | const baseUrl = resolveRequestOrigin(request); |
| 771 | 771 | ||
| 772 | if (isInteractiveConnectPayload(payload)) { | 772 | if (isInteractiveConnectPayload(payload)) { |
| 773 | return yield* executor.effect.sources.connect( | 773 | return yield* executor.sources.connect( |
| 774 | toExecutorMcpSourceInput(payload, baseUrl), | 774 | toExecutorMcpSourceInput(payload, baseUrl), |
| 775 | ); | 775 | ); |
| 776 | } | 776 | } |
| 777 | 777 | ||
| 778 | const sourceInput = toExecutorSourceInput(payload); | 778 | const sourceInput = toExecutorSourceInput(payload); |
| 779 | if (sourceInput) { | 779 | if (sourceInput) { |
| 780 | return yield* executor.effect.sources.add(sourceInput, { | 780 | return yield* executor.sources.add(sourceInput, { |
| 781 | baseUrl, | 781 | baseUrl, |
| 782 | }); | 782 | }); |
| 783 | } | 783 | } |
| @@ -804,7 +804,7 @@ export const ExecutorSourcesLive = HttpApiBuilder.group( · 20 unmodified lines | |||
| 804 | Effect.flatMap((executor) => | 804 | Effect.flatMap((executor) => |
| 805 | Effect.gen(function* () { | 805 | Effect.gen(function* () { |
| 806 | const request = yield* HttpServerRequest.HttpServerRequest; | 806 | const request = yield* HttpServerRequest.HttpServerRequest; |
| 807 | return yield* executor.effect.sources.connectBatch({ | 807 | return yield* executor.sources.connectBatch({ |
| 808 | ...payload, | 808 | ...payload, |
| 809 | baseUrl: resolveRequestOrigin(request), | 809 | baseUrl: resolveRequestOrigin(request), |
| 810 | }); | 810 | }); |
| @@ -822,7 +822,7 @@ export const ExecutorSourcesLive = HttpApiBuilder.group( · 11 unmodified lines | |||
| 822 | path.workspaceId, | 822 | path.workspaceId, |
| 823 | ).pipe( | 823 | ).pipe( |
| 824 | Effect.flatMap((executor) => | 824 | Effect.flatMap((executor) => |
| 825 | executor.effect.sources.oauthClients.list(urlParams.providerKey).pipe( | 825 | executor.sources.oauthClients.list(urlParams.providerKey).pipe( |
| 826 | Effect.catchAll((cause) => | 826 | Effect.catchAll((cause) => |
| 827 | Effect.fail( | 827 | Effect.fail( |
| 828 | toBadRequestError("sources.listWorkspaceOauthClients", cause), | 828 | toBadRequestError("sources.listWorkspaceOauthClients", cause), |
| @@ -838,7 +838,7 @@ export const ExecutorSourcesLive = HttpApiBuilder.group( · 9 unmodified lines | |||
| 838 | path.workspaceId, | 838 | path.workspaceId, |
| 839 | ).pipe( | 839 | ).pipe( |
| 840 | Effect.flatMap((executor) => | 840 | Effect.flatMap((executor) => |
| 841 | executor.effect.sources.oauthClients.create(payload).pipe( | 841 | executor.sources.oauthClients.create(payload).pipe( |
| 842 | Effect.catchAll((cause) => | 842 | Effect.catchAll((cause) => |
| 843 | Effect.fail( | 843 | Effect.fail( |
| 844 | toBadRequestError( | 844 | toBadRequestError( |
| @@ -857,7 +857,7 @@ export const ExecutorSourcesLive = HttpApiBuilder.group( · 12 unmodified lines | |||
| 857 | path.workspaceId, | 857 | path.workspaceId, |
| 858 | ).pipe( | 858 | ).pipe( |
| 859 | Effect.flatMap((executor) => | 859 | Effect.flatMap((executor) => |
| 860 | executor.effect.sources.oauthClients.remove(path.oauthClientId).pipe( | 860 | executor.sources.oauthClients.remove(path.oauthClientId).pipe( |
| 861 | Effect.map((result) => ({ removed: result })), | 861 | Effect.map((result) => ({ removed: result })), |
| 862 | Effect.catchAll((cause) => | 862 | Effect.catchAll((cause) => |
| 863 | Effect.fail( | 863 | Effect.fail( |
| @@ -877,7 +877,7 @@ export const ExecutorSourcesLive = HttpApiBuilder.group( · 13 unmodified lines | |||
| 877 | path.workspaceId, | 877 | path.workspaceId, |
| 878 | ).pipe( | 878 | ).pipe( |
| 879 | Effect.flatMap((executor) => | 879 | Effect.flatMap((executor) => |
| 880 | executor.effect.sources.providerGrants.remove(path.grantId).pipe( | 880 | executor.sources.providerGrants.remove(path.grantId).pipe( |
| 881 | Effect.map((result) => ({ removed: result })), | 881 | Effect.map((result) => ({ removed: result })), |
| 882 | Effect.catchAll((cause) => | 882 | Effect.catchAll((cause) => |
| 883 | Effect.fail( | 883 | Effect.fail( |
| @@ -893,17 +893,17 @@ export const ExecutorSourcesLive = HttpApiBuilder.group( · 9 unmodified lines | |||
| 893 | ) | 893 | ) |
| 894 | .handle("list", ({ path }) => | 894 | .handle("list", ({ path }) => |
| 895 | resolveRequestedLocalWorkspace("sources.list", path.workspaceId).pipe( | 895 | resolveRequestedLocalWorkspace("sources.list", path.workspaceId).pipe( |
| 896 | Effect.flatMap((executor) => executor.effect.sources.list()), | 896 | Effect.flatMap((executor) => executor.sources.list()), |
| 897 | ), | 897 | ), |
| 898 | ) | 898 | ) |
| 899 | .handle("create", ({ path, payload }) => | 899 | .handle("create", ({ path, payload }) => |
| 900 | resolveRequestedLocalWorkspace("sources.create", path.workspaceId).pipe( | 900 | resolveRequestedLocalWorkspace("sources.create", path.workspaceId).pipe( |
| 901 | Effect.flatMap((executor) => executor.effect.sources.create(payload)), | 901 | Effect.flatMap((executor) => executor.sources.create(payload)), |
| 902 | ), | 902 | ), |
| 903 | ) | 903 | ) |
| 904 | .handle("get", ({ path }) => | 904 | .handle("get", ({ path }) => |
| 905 | resolveRequestedLocalWorkspace("sources.get", path.workspaceId).pipe( | 905 | resolveRequestedLocalWorkspace("sources.get", path.workspaceId).pipe( |
| 906 | Effect.flatMap((executor) => executor.effect.sources.get(path.sourceId)), | 906 | Effect.flatMap((executor) => executor.sources.get(path.sourceId)), |
| 907 | ), | 907 | ), |
| 908 | ) | 908 | ) |
| 909 | .handle("inspection", ({ path }) => | 909 | .handle("inspection", ({ path }) => |
| @@ -911,9 +911,7 @@ export const ExecutorSourcesLive = HttpApiBuilder.group( · 1 unmodified line | |||
| 911 | "sources.inspection", | 911 | "sources.inspection", |
| 912 | path.workspaceId, | 912 | path.workspaceId, |
| 913 | ).pipe( | 913 | ).pipe( |
| 914 | Effect.flatMap((executor) => | 914 | Effect.flatMap((executor) => executor.sources.inspection.get(path.sourceId)), |
| 915 | executor.effect.sources.inspection.get(path.sourceId), | ||
| 916 | ), | ||
| 917 | ), | 915 | ), |
| 918 | ) | 916 | ) |
| 919 | .handle("inspectionTool", ({ path }) => | 917 | .handle("inspectionTool", ({ path }) => |
| @@ -922,7 +920,7 @@ export const ExecutorSourcesLive = HttpApiBuilder.group( · 2 unmodified lines | |||
| 922 | path.workspaceId, | 920 | path.workspaceId, |
| 923 | ).pipe( | 921 | ).pipe( |
| 924 | Effect.flatMap((executor) => | 922 | Effect.flatMap((executor) => |
| 925 | executor.effect.sources.inspection.tool({ | 923 | executor.sources.inspection.tool({ |
| 926 | sourceId: path.sourceId, | 924 | sourceId: path.sourceId, |
| 927 | toolPath: path.toolPath, | 925 | toolPath: path.toolPath, |
| 928 | }), | 926 | }), |
| @@ -935,7 +933,7 @@ export const ExecutorSourcesLive = HttpApiBuilder.group( · 6 unmodified lines | |||
| 935 | path.workspaceId, | 933 | path.workspaceId, |
| 936 | ).pipe( | 934 | ).pipe( |
| 937 | Effect.flatMap((executor) => | 935 | Effect.flatMap((executor) => |
| 938 | executor.effect.sources.inspection.discover({ | 936 | executor.sources.inspection.discover({ |
| 939 | sourceId: path.sourceId, | 937 | sourceId: path.sourceId, |
| 940 | payload, | 938 | payload, |
| 941 | }), | 939 | }), |
| @@ -944,15 +942,13 @@ export const ExecutorSourcesLive = HttpApiBuilder.group( · 2 unmodified lines | |||
| 944 | ) | 942 | ) |
| 945 | .handle("update", ({ path, payload }) => | 943 | .handle("update", ({ path, payload }) => |
| 946 | resolveRequestedLocalWorkspace("sources.update", path.workspaceId).pipe( | 944 | resolveRequestedLocalWorkspace("sources.update", path.workspaceId).pipe( |
| 947 | Effect.flatMap((executor) => | 945 | Effect.flatMap((executor) => executor.sources.update(path.sourceId, payload)), |
| 948 | executor.effect.sources.update(path.sourceId, payload) | ||
| 949 | ), | ||
| 950 | ), | 946 | ), |
| 951 | ) | 947 | ) |
| 952 | .handle("remove", ({ path }) => | 948 | .handle("remove", ({ path }) => |
| 953 | resolveRequestedLocalWorkspace("sources.remove", path.workspaceId).pipe( | 949 | resolveRequestedLocalWorkspace("sources.remove", path.workspaceId).pipe( |
| 954 | Effect.flatMap((executor) => executor.effect.sources.remove(path.sourceId)), | 950 | Effect.flatMap((executor) => executor.sources.remove(path.sourceId)), |
| 955 | Effect.map((result) => ({ removed: result.removed })), | 951 | Effect.map((removed) => ({ removed })), |
| 956 | ), | 952 | ), |
| 957 | ) | 953 | ) |
| 958 | .handle("credentialPage", ({ path, urlParams }) => | 954 | .handle("credentialPage", ({ path, urlParams }) => |
| @@ -961,7 +957,7 @@ export const ExecutorSourcesLive = HttpApiBuilder.group( · 2 unmodified lines | |||
| 961 | path.workspaceId, | 957 | path.workspaceId, |
| 962 | ).pipe( | 958 | ).pipe( |
| 963 | Effect.flatMap((executor) => | 959 | Effect.flatMap((executor) => |
| 964 | executor.effect.local.credentials.get({ | 960 | executor.local.credentials.get({ |
| 965 | sourceId: path.sourceId, | 961 | sourceId: path.sourceId, |
| 966 | interactionId: urlParams.interactionId, | 962 | interactionId: urlParams.interactionId, |
| 967 | }), | 963 | }), |
| @@ -1006,7 +1002,7 @@ export const ExecutorSourcesLive = HttpApiBuilder.group( · 38 unmodified lines | |||
| 1006 | path.workspaceId, | 1002 | path.workspaceId, |
| 1007 | ).pipe( | 1003 | ).pipe( |
| 1008 | Effect.flatMap((executor) => | 1004 | Effect.flatMap((executor) => |
| 1009 | executor.effect.local.credentials.submit({ | 1005 | executor.local.credentials.submit({ |
| 1010 | sourceId: path.sourceId, | 1006 | sourceId: path.sourceId, |
| 1011 | interactionId: urlParams.interactionId, | 1007 | interactionId: urlParams.interactionId, |
| 1012 | action: | 1008 | action: |
| @@ -1081,7 +1077,7 @@ export const ExecutorSourcesLive = HttpApiBuilder.group( · 68 unmodified lines | |||
| 1081 | path.workspaceId, | 1077 | path.workspaceId, |
| 1082 | ).pipe( | 1078 | ).pipe( |
| 1083 | Effect.flatMap((executor) => | 1079 | Effect.flatMap((executor) => |
| 1084 | executor.effect.local.credentials.complete({ | 1080 | executor.local.credentials.complete({ |
| 1085 | sourceId: path.sourceId, | 1081 | sourceId: path.sourceId, |
| 1086 | state: urlParams.state, | 1082 | state: urlParams.state, |
| 1087 | code: urlParams.code, | 1083 | code: urlParams.code, |
| @@ -1136,7 +1132,7 @@ export const ExecutorSourcesLive = HttpApiBuilder.group( · 48 unmodified lines | |||
| 1136 | ).pipe( | 1132 | ).pipe( |
| 1137 | Effect.flatMap((executor) => | 1133 | Effect.flatMap((executor) => |
| 1138 | Effect.gen(function* () { | 1134 | Effect.gen(function* () { |
| 1139 | const completed = yield* executor.effect.oauth.completeProviderCallback({ | 1135 | const completed = yield* executor.oauth.completeProviderCallback({ |
| 1140 | scopeId: path.workspaceId, | 1136 | scopeId: path.workspaceId, |
| 1141 | state: urlParams.state, | 1137 | state: urlParams.state, |
| 1142 | code: urlParams.code, | 1138 | code: urlParams.code, |
| @@ -3,7 +3,9 @@ · 2 unmodified lines | |||
| 3 | "private": true, | 3 | "private": true, |
| 4 | "type": "module", | 4 | "type": "module", |
| 5 | "exports": { | 5 | "exports": { |
| 6 | ".": "./src/index.ts" | 6 | ".": "./src/client.ts", |
| 7 | "./effect": "./src/effect.ts", | ||
| 8 | "./runtime": "./src/runtime.ts" | ||
| 7 | }, | 9 | }, |
| 8 | "scripts": { | 10 | "scripts": { |
| 9 | "fixture:release:capture": "bun run ./src/capture-release-workspace-fixture.ts", | 11 | "fixture:release:capture": "bun run ./src/capture-release-workspace-fixture.ts", |
| @@ -0,0 +1,5 @@ | |||
| 1 | export type { CreateLocalExecutorBackendOptions } from "./index"; | ||
| 2 | export { | ||
| 3 | createLocalExecutor, | ||
| 4 | createLocalExecutorBackend, | ||
| 5 | } from "./index"; | ||
| @@ -0,0 +1,28 @@ | |||
| 1 | export type { CreateLocalExecutorBackendOptions } from "./index"; | ||
| 2 | export { | ||
| 3 | buildLocalSourceArtifact, | ||
| 4 | createLocalExecutorEffect, | ||
| 5 | createLocalExecutorServicesEffect, | ||
| 6 | deriveLocalInstallation, | ||
| 7 | getOrProvisionLocalInstallation, | ||
| 8 | loadLocalExecutorConfig, | ||
| 9 | loadLocalExecutorStateSnapshot, | ||
| 10 | loadLocalInstallation, | ||
| 11 | loadLocalWorkspaceState, | ||
| 12 | readLocalSourceArtifact, | ||
| 13 | refreshSourceTypeDeclarationInBackground, | ||
| 14 | refreshWorkspaceSourceTypeDeclarationsInBackground, | ||
| 15 | removeLocalSourceArtifact, | ||
| 16 | resolveConfigRelativePath, | ||
| 17 | resolveLocalWorkspaceContext, | ||
| 18 | syncSourceTypeDeclarationNode, | ||
| 19 | syncWorkspaceSourceTypeDeclarationsNode, | ||
| 20 | writeLocalExecutorStateSnapshot, | ||
| 21 | writeLocalSourceArtifact, | ||
| 22 | writeLocalWorkspaceState, | ||
| 23 | writeProjectLocalExecutorConfig, | ||
| 24 | } from "./index"; | ||
| 25 | export type { | ||
| 26 | LoadedLocalExecutorConfig, | ||
| 27 | ResolvedLocalWorkspaceContext, | ||
| 28 | } from "./index"; | ||
| @@ -3,8 +3,6 @@ import { NodeFileSystem } from "@effect/platform-node"; · 2 unmodified lines | |||
| 3 | import { | 3 | import { |
| 4 | createExecutor, | 4 | createExecutor, |
| 5 | createExecutorBackend, | 5 | createExecutorBackend, |
| 6 | createExecutorEffect, | ||
| 7 | type CreateExecutorOptions, | ||
| 8 | type Executor, | 6 | type Executor, |
| 9 | type ExecutorBackend, | 7 | type ExecutorBackend, |
| 10 | type ExecutorBackendServices, | 8 | type ExecutorBackendServices, |
| @@ -12,6 +10,11 @@ import { · 1 unmodified line | |||
| 12 | type ExecutorSourceTypeDeclarationsBackend, | 10 | type ExecutorSourceTypeDeclarationsBackend, |
| 13 | type ExecutorScopeDescriptor, | 11 | type ExecutorScopeDescriptor, |
| 14 | } from "@executor/platform-sdk"; | 12 | } from "@executor/platform-sdk"; |
| 13 | import { | ||
| 14 | createExecutorEffect, | ||
| 15 | type ExecutorEffect, | ||
| 16 | type CreateExecutorEffectOptions as CreateExecutorOptions, | ||
| 17 | } from "@executor/platform-sdk/effect"; | ||
| 15 | import type { | 18 | import type { |
| 16 | LocalExecutorConfig, | 19 | LocalExecutorConfig, |
| 17 | LocalInstallation, | 20 | LocalInstallation, |
| @@ -307,7 +310,7 @@ export const createLocalExecutorRuntime = ( · 289 unmodified lines | |||
| 307 | 310 | ||
| 308 | export const createLocalExecutorEffect = ( | 311 | export const createLocalExecutorEffect = ( |
| 309 | options: CreateLocalExecutorBackendOptions & ExecutorRuntimeOptions = {}, | 312 | options: CreateLocalExecutorBackendOptions & ExecutorRuntimeOptions = {}, |
| 310 | ): Effect.Effect<Executor, Error> => | 313 | ): Effect.Effect<ExecutorEffect, Error> => |
| 311 | createExecutorEffect({ | 314 | createExecutorEffect({ |
| 312 | backend: createLocalExecutorBackend(options), | 315 | backend: createLocalExecutorBackend(options), |
| 313 | executionResolver: options.executionResolver, | 316 | executionResolver: options.executionResolver, |
| @@ -318,7 +321,14 @@ export const createLocalExecutorEffect = ( · 4 unmodified lines | |||
| 318 | 321 | ||
| 319 | export const createLocalExecutor = ( | 322 | export const createLocalExecutor = ( |
| 320 | options: CreateLocalExecutorBackendOptions & ExecutorRuntimeOptions = {}, | 323 | options: CreateLocalExecutorBackendOptions & ExecutorRuntimeOptions = {}, |
| 321 | ): Promise<Executor> => Effect.runPromise(createLocalExecutorEffect(options)); | 324 | ): Promise<Executor> => |
| 325 | createExecutor({ | ||
| 326 | backend: createLocalExecutorBackend(options), | ||
| 327 | executionResolver: options.executionResolver, | ||
| 328 | createInternalToolMap: options.createInternalToolMap, | ||
| 329 | resolveSecretMaterial: options.resolveSecretMaterial, | ||
| 330 | getLocalServerBaseUrl: options.getLocalServerBaseUrl, | ||
| 331 | }); | ||
| 322 | 332 | ||
| 323 | export { | 333 | export { |
| 324 | deriveLocalInstallation, | 334 | deriveLocalInstallation, |
| @@ -0,0 +1,2 @@ | |||
| 1 | export type { CreateLocalExecutorBackendOptions } from "./index"; | ||
| 2 | export { createLocalExecutorRuntime } from "./index"; | ||
| @@ -6,6 +6,7 @@ · 5 unmodified lines | |||
| 6 | ".": "./src/index.ts", | 6 | ".": "./src/index.ts", |
| 7 | "./backend": "./src/backend.ts", | 7 | "./backend": "./src/backend.ts", |
| 8 | "./contracts": "./src/contracts.ts", | 8 | "./contracts": "./src/contracts.ts", |
| 9 | "./effect": "./src/effect.ts", | ||
| 9 | "./executor": "./src/executor.ts", | 10 | "./executor": "./src/executor.ts", |
| 10 | "./errors": "./src/errors.ts", | 11 | "./errors": "./src/errors.ts", |
| 11 | "./operations": "./src/operations.ts", | 12 | "./operations": "./src/operations.ts", |
| @@ -0,0 +1 @@ | |||
| 1 | export * from "./executor-effect"; | ||
| @@ -0,0 +1,533 @@ | |||
| 1 | import * as Effect from "effect/Effect"; | ||
| 2 | |||
| 3 | import type { | ||
| 4 | ScopeId, | ||
| 5 | Execution, | ||
| 6 | ExecutionEnvelope, | ||
| 7 | ExecutionInteraction, | ||
| 8 | LocalInstallation, | ||
| 9 | LocalScopePolicy, | ||
| 10 | ProviderAuthGrant, | ||
| 11 | ScopeOauthClient, | ||
| 12 | Source, | ||
| 13 | } from "./schema"; | ||
| 14 | import { ExecutionIdSchema } from "./schema"; | ||
| 15 | import type { | ||
| 16 | CreateExecutionPayload, | ||
| 17 | ResumeExecutionPayload, | ||
| 18 | } from "./executions/contracts"; | ||
| 19 | import type { | ||
| 20 | CreateSecretPayload, | ||
| 21 | CreateSecretResult, | ||
| 22 | DeleteSecretResult, | ||
| 23 | InstanceConfig, | ||
| 24 | SecretListItem, | ||
| 25 | UpdateSecretPayload, | ||
| 26 | UpdateSecretResult, | ||
| 27 | } from "./local/contracts"; | ||
| 28 | import { | ||
| 29 | completeSourceCredentialSetup, | ||
| 30 | getLocalInstallation, | ||
| 31 | getSourceCredentialInteraction, | ||
| 32 | submitSourceCredentialInteraction, | ||
| 33 | } from "./local/operations"; | ||
| 34 | import { | ||
| 35 | createLocalSecret, | ||
| 36 | deleteLocalSecret, | ||
| 37 | getLocalInstanceConfig, | ||
| 38 | listLocalSecrets, | ||
| 39 | updateLocalSecret, | ||
| 40 | } from "./local/secrets"; | ||
| 41 | import type { | ||
| 42 | CreatePolicyPayload, | ||
| 43 | UpdatePolicyPayload, | ||
| 44 | } from "./policies/contracts"; | ||
| 45 | import { | ||
| 46 | createPolicy, | ||
| 47 | getPolicy, | ||
| 48 | listPolicies, | ||
| 49 | removePolicy, | ||
| 50 | updatePolicy, | ||
| 51 | } from "./policies/operations"; | ||
| 52 | import type { | ||
| 53 | CreateScopeOauthClientPayload, | ||
| 54 | CreateSourcePayload, | ||
| 55 | UpdateSourcePayload, | ||
| 56 | } from "./sources/contracts"; | ||
| 57 | import { discoverSource } from "./sources/discovery"; | ||
| 58 | import { | ||
| 59 | discoverSourceInspectionTools, | ||
| 60 | getSourceInspection, | ||
| 61 | getSourceInspectionToolDetail, | ||
| 62 | } from "./sources/inspection"; | ||
| 63 | import { | ||
| 64 | createSource, | ||
| 65 | getSource, | ||
| 66 | listSources, | ||
| 67 | removeSource, | ||
| 68 | updateSource, | ||
| 69 | } from "./sources/operations"; | ||
| 70 | import type { ExecutorBackend } from "./backend"; | ||
| 71 | import { | ||
| 72 | provideExecutorRuntime, | ||
| 73 | type CreateScopeInternalToolMap, | ||
| 74 | type ExecutorRuntime, | ||
| 75 | type ExecutorRuntimeOptions, | ||
| 76 | type ResolveExecutionEnvironment, | ||
| 77 | type ResolveSecretMaterial, | ||
| 78 | RuntimeSourceAuthServiceTag, | ||
| 79 | } from "./runtime"; | ||
| 80 | import { | ||
| 81 | createExecution, | ||
| 82 | getExecution, | ||
| 83 | resumeExecution, | ||
| 84 | } from "./runtime/execution/service"; | ||
| 85 | import type { | ||
| 86 | CompleteProviderOauthCallbackResult, | ||
| 87 | CompleteSourceCredentialSetupResult, | ||
| 88 | CompleteSourceOAuthSessionResult, | ||
| 89 | ConnectGoogleDiscoveryBatchInput, | ||
| 90 | ConnectGoogleDiscoveryBatchResult, | ||
| 91 | ConnectMcpSourceInput, | ||
| 92 | ExecutorAddSourceInput, | ||
| 93 | ExecutorSourceAddResult, | ||
| 94 | McpSourceConnectResult, | ||
| 95 | StartSourceOAuthSessionInput, | ||
| 96 | StartSourceOAuthSessionResult, | ||
| 97 | } from "./runtime/sources/source-auth-service"; | ||
| 98 | |||
| 99 | type DistributiveOmit<T, Keys extends PropertyKey> = T extends unknown | ||
| 100 | ? Omit<T, Keys> | ||
| 101 | : never; | ||
| 102 | type ProvidedEffect<T extends Effect.Effect<any, any, any>> = Effect.Effect< | ||
| 103 | Effect.Effect.Success<T>, | ||
| 104 | Effect.Effect.Error<T>, | ||
| 105 | never | ||
| 106 | >; | ||
| 107 | type MappedProvidedEffect< | ||
| 108 | T extends Effect.Effect<any, any, any>, | ||
| 109 | A, | ||
| 110 | > = Effect.Effect<A, Effect.Effect.Error<T>, never>; | ||
| 111 | |||
| 112 | export type ExecutorSourceInput = DistributiveOmit< | ||
| 113 | ExecutorAddSourceInput, | ||
| 114 | "scopeId" | "actorScopeId" | "executionId" | "interactionId" | ||
| 115 | >; | ||
| 116 | |||
| 117 | export type ExecutorSourceBatchInput = DistributiveOmit< | ||
| 118 | ConnectGoogleDiscoveryBatchInput, | ||
| 119 | "scopeId" | "actorScopeId" | "executionId" | "interactionId" | ||
| 120 | >; | ||
| 121 | |||
| 122 | export type ExecutorMcpSourceInput = DistributiveOmit< | ||
| 123 | ConnectMcpSourceInput, | ||
| 124 | "scopeId" | "actorScopeId" | ||
| 125 | >; | ||
| 126 | |||
| 127 | export type ExecutorSourceOAuthInput = DistributiveOmit< | ||
| 128 | StartSourceOAuthSessionInput, | ||
| 129 | "scopeId" | "actorScopeId" | ||
| 130 | >; | ||
| 131 | |||
| 132 | export type ExecutorEffect = { | ||
| 133 | runtime: ExecutorRuntime; | ||
| 134 | installation: LocalInstallation; | ||
| 135 | scopeId: ScopeId; | ||
| 136 | actorScopeId: ScopeId; | ||
| 137 | resolutionScopeIds: ReadonlyArray<ScopeId>; | ||
| 138 | close: () => Promise<void>; | ||
| 139 | local: { | ||
| 140 | installation: () => ProvidedEffect<ReturnType<typeof getLocalInstallation>>; | ||
| 141 | config: () => ProvidedEffect<ReturnType<typeof getLocalInstanceConfig>>; | ||
| 142 | credentials: { | ||
| 143 | get: (input: { | ||
| 144 | sourceId: Source["id"]; | ||
| 145 | interactionId: ExecutionInteraction["id"]; | ||
| 146 | }) => ProvidedEffect<ReturnType<typeof getSourceCredentialInteraction>>; | ||
| 147 | submit: (input: { | ||
| 148 | sourceId: Source["id"]; | ||
| 149 | interactionId: ExecutionInteraction["id"]; | ||
| 150 | action: "submit" | "continue" | "cancel"; | ||
| 151 | token?: string | null; | ||
| 152 | }) => ProvidedEffect< | ||
| 153 | ReturnType<typeof submitSourceCredentialInteraction> | ||
| 154 | >; | ||
| 155 | complete: (input: { | ||
| 156 | sourceId: Source["id"]; | ||
| 157 | state: string; | ||
| 158 | code?: string | null; | ||
| 159 | error?: string | null; | ||
| 160 | errorDescription?: string | null; | ||
| 161 | }) => MappedProvidedEffect< | ||
| 162 | ReturnType<typeof completeSourceCredentialSetup>, | ||
| 163 | CompleteSourceCredentialSetupResult | ||
| 164 | >; | ||
| 165 | }; | ||
| 166 | }; | ||
| 167 | secrets: { | ||
| 168 | list: () => ProvidedEffect<ReturnType<typeof listLocalSecrets>>; | ||
| 169 | create: ( | ||
| 170 | payload: CreateSecretPayload, | ||
| 171 | ) => ProvidedEffect<ReturnType<typeof createLocalSecret>>; | ||
| 172 | update: (input: { | ||
| 173 | secretId: string; | ||
| 174 | payload: UpdateSecretPayload; | ||
| 175 | }) => ProvidedEffect<ReturnType<typeof updateLocalSecret>>; | ||
| 176 | remove: ( | ||
| 177 | secretId: string, | ||
| 178 | ) => MappedProvidedEffect< | ||
| 179 | ReturnType<typeof deleteLocalSecret>, | ||
| 180 | DeleteSecretResult | ||
| 181 | >; | ||
| 182 | }; | ||
| 183 | policies: { | ||
| 184 | list: () => ProvidedEffect<ReturnType<typeof listPolicies>>; | ||
| 185 | create: ( | ||
| 186 | payload: CreatePolicyPayload, | ||
| 187 | ) => ProvidedEffect<ReturnType<typeof createPolicy>>; | ||
| 188 | get: (policyId: string) => ProvidedEffect<ReturnType<typeof getPolicy>>; | ||
| 189 | update: ( | ||
| 190 | policyId: string, | ||
| 191 | payload: UpdatePolicyPayload, | ||
| 192 | ) => ProvidedEffect<ReturnType<typeof updatePolicy>>; | ||
| 193 | remove: ( | ||
| 194 | policyId: string, | ||
| 195 | ) => MappedProvidedEffect<ReturnType<typeof removePolicy>, boolean>; | ||
| 196 | }; | ||
| 197 | sources: { | ||
| 198 | add: ( | ||
| 199 | input: ExecutorSourceInput, | ||
| 200 | options?: { | ||
| 201 | baseUrl?: string | null; | ||
| 202 | }, | ||
| 203 | ) => Effect.Effect<ExecutorSourceAddResult, Error, never>; | ||
| 204 | connect: ( | ||
| 205 | payload: ExecutorMcpSourceInput, | ||
| 206 | ) => Effect.Effect<McpSourceConnectResult, Error, never>; | ||
| 207 | connectBatch: ( | ||
| 208 | payload: ExecutorSourceBatchInput, | ||
| 209 | ) => Effect.Effect<ConnectGoogleDiscoveryBatchResult, Error, never>; | ||
| 210 | discover: (input: { | ||
| 211 | url: string; | ||
| 212 | probeAuth?: Parameters<typeof discoverSource>[0]["probeAuth"]; | ||
| 213 | }) => ProvidedEffect<ReturnType<typeof discoverSource>>; | ||
| 214 | list: () => ProvidedEffect<ReturnType<typeof listSources>>; | ||
| 215 | create: ( | ||
| 216 | payload: CreateSourcePayload, | ||
| 217 | ) => ProvidedEffect<ReturnType<typeof createSource>>; | ||
| 218 | get: (sourceId: Source["id"]) => ProvidedEffect<ReturnType<typeof getSource>>; | ||
| 219 | update: ( | ||
| 220 | sourceId: Source["id"], | ||
| 221 | payload: UpdateSourcePayload, | ||
| 222 | ) => ProvidedEffect<ReturnType<typeof updateSource>>; | ||
| 223 | remove: ( | ||
| 224 | sourceId: Source["id"], | ||
| 225 | ) => MappedProvidedEffect<ReturnType<typeof removeSource>, boolean>; | ||
| 226 | inspection: { | ||
| 227 | get: ( | ||
| 228 | sourceId: Source["id"], | ||
| 229 | ) => ProvidedEffect<ReturnType<typeof getSourceInspection>>; | ||
| 230 | tool: (input: { | ||
| 231 | sourceId: Source["id"]; | ||
| 232 | toolPath: string; | ||
| 233 | }) => ProvidedEffect<ReturnType<typeof getSourceInspectionToolDetail>>; | ||
| 234 | discover: (input: { | ||
| 235 | sourceId: Source["id"]; | ||
| 236 | payload: Parameters<typeof discoverSourceInspectionTools>[0]["payload"]; | ||
| 237 | }) => ProvidedEffect< | ||
| 238 | ReturnType<typeof discoverSourceInspectionTools> | ||
| 239 | >; | ||
| 240 | }; | ||
| 241 | oauthClients: { | ||
| 242 | list: ( | ||
| 243 | providerKey: string, | ||
| 244 | ) => Effect.Effect<ReadonlyArray<ScopeOauthClient>, Error, never>; | ||
| 245 | create: ( | ||
| 246 | payload: CreateScopeOauthClientPayload, | ||
| 247 | ) => Effect.Effect<ScopeOauthClient, Error, never>; | ||
| 248 | remove: ( | ||
| 249 | oauthClientId: ScopeOauthClient["id"], | ||
| 250 | ) => Effect.Effect<boolean, Error, never>; | ||
| 251 | }; | ||
| 252 | providerGrants: { | ||
| 253 | remove: ( | ||
| 254 | grantId: ProviderAuthGrant["id"], | ||
| 255 | ) => Effect.Effect<boolean, Error, never>; | ||
| 256 | }; | ||
| 257 | }; | ||
| 258 | oauth: { | ||
| 259 | startSourceAuth: ( | ||
| 260 | input: ExecutorSourceOAuthInput, | ||
| 261 | ) => Effect.Effect<StartSourceOAuthSessionResult, Error, never>; | ||
| 262 | completeSourceAuth: (input: { | ||
| 263 | state: string; | ||
| 264 | code?: string | null; | ||
| 265 | error?: string | null; | ||
| 266 | errorDescription?: string | null; | ||
| 267 | }) => Effect.Effect<CompleteSourceOAuthSessionResult, Error, never>; | ||
| 268 | completeProviderCallback: (input: { | ||
| 269 | scopeId?: ScopeId; | ||
| 270 | actorScopeId?: ScopeId | null; | ||
| 271 | state: string; | ||
| 272 | code?: string | null; | ||
| 273 | error?: string | null; | ||
| 274 | errorDescription?: string | null; | ||
| 275 | }) => Effect.Effect<CompleteProviderOauthCallbackResult, Error, never>; | ||
| 276 | }; | ||
| 277 | executions: { | ||
| 278 | create: ( | ||
| 279 | payload: CreateExecutionPayload, | ||
| 280 | ) => ProvidedEffect<ReturnType<typeof createExecution>>; | ||
| 281 | get: ( | ||
| 282 | executionId: Execution["id"], | ||
| 283 | ) => ProvidedEffect<ReturnType<typeof getExecution>>; | ||
| 284 | resume: ( | ||
| 285 | executionId: Execution["id"], | ||
| 286 | payload: ResumeExecutionPayload, | ||
| 287 | ) => ProvidedEffect<ReturnType<typeof resumeExecution>>; | ||
| 288 | }; | ||
| 289 | }; | ||
| 290 | |||
| 291 | export type CreateExecutorEffectOptions = ExecutorRuntimeOptions & { | ||
| 292 | backend: ExecutorBackend; | ||
| 293 | }; | ||
| 294 | |||
| 295 | const fromRuntime = (runtime: ExecutorRuntime): ExecutorEffect => { | ||
| 296 | const installation = runtime.localInstallation; | ||
| 297 | const scopeId = installation.scopeId; | ||
| 298 | const actorScopeId = installation.actorScopeId; | ||
| 299 | const provide = <A, E, R>(effect: Effect.Effect<A, E, R>) => | ||
| 300 | provideExecutorRuntime(effect, runtime); | ||
| 301 | const provideSourceAuth = <A, E>( | ||
| 302 | execute: ( | ||
| 303 | service: Effect.Effect.Success<typeof RuntimeSourceAuthServiceTag>, | ||
| 304 | ) => Effect.Effect<A, E, any>, | ||
| 305 | ) => provide(Effect.flatMap(RuntimeSourceAuthServiceTag, execute)); | ||
| 306 | const createSdkSourceSession = () => { | ||
| 307 | const id = crypto.randomUUID(); | ||
| 308 | return { | ||
| 309 | executionId: ExecutionIdSchema.make(`exec_sdk_${id}`), | ||
| 310 | interactionId: `executor.sdk.${id}` as never, | ||
| 311 | }; | ||
| 312 | }; | ||
| 313 | |||
| 314 | return { | ||
| 315 | runtime, | ||
| 316 | installation, | ||
| 317 | scopeId, | ||
| 318 | actorScopeId, | ||
| 319 | resolutionScopeIds: installation.resolutionScopeIds, | ||
| 320 | close: () => runtime.close(), | ||
| 321 | local: { | ||
| 322 | installation: () => provide(getLocalInstallation()), | ||
| 323 | config: () => provide(getLocalInstanceConfig()), | ||
| 324 | credentials: { | ||
| 325 | get: ({ sourceId, interactionId }) => | ||
| 326 | provide( | ||
| 327 | getSourceCredentialInteraction({ | ||
| 328 | scopeId, | ||
| 329 | sourceId, | ||
| 330 | interactionId, | ||
| 331 | }), | ||
| 332 | ), | ||
| 333 | submit: ({ sourceId, interactionId, action, token }) => | ||
| 334 | provide( | ||
| 335 | submitSourceCredentialInteraction({ | ||
| 336 | scopeId, | ||
| 337 | sourceId, | ||
| 338 | interactionId, | ||
| 339 | action, | ||
| 340 | token, | ||
| 341 | }), | ||
| 342 | ), | ||
| 343 | complete: ({ sourceId, state, code, error, errorDescription }) => | ||
| 344 | provide( | ||
| 345 | completeSourceCredentialSetup({ | ||
| 346 | scopeId, | ||
| 347 | sourceId, | ||
| 348 | state, | ||
| 349 | code, | ||
| 350 | error, | ||
| 351 | errorDescription, | ||
| 352 | }), | ||
| 353 | ), | ||
| 354 | }, | ||
| 355 | }, | ||
| 356 | secrets: { | ||
| 357 | list: () => provide(listLocalSecrets()), | ||
| 358 | create: (payload) => provide(createLocalSecret(payload)), | ||
| 359 | update: (input) => provide(updateLocalSecret(input)), | ||
| 360 | remove: (secretId) => provide(deleteLocalSecret(secretId)), | ||
| 361 | }, | ||
| 362 | policies: { | ||
| 363 | list: () => provide(listPolicies(scopeId)), | ||
| 364 | create: (payload) => provide(createPolicy({ scopeId, payload })), | ||
| 365 | get: (policyId) => | ||
| 366 | provide(getPolicy({ scopeId, policyId: policyId as never })), | ||
| 367 | update: (policyId, payload) => | ||
| 368 | provide(updatePolicy({ scopeId, policyId: policyId as never, payload })), | ||
| 369 | remove: (policyId) => | ||
| 370 | provide(removePolicy({ scopeId, policyId: policyId as never })).pipe( | ||
| 371 | Effect.map((result) => result.removed), | ||
| 372 | ), | ||
| 373 | }, | ||
| 374 | sources: { | ||
| 375 | add: (input, options) => | ||
| 376 | provideSourceAuth((service) => { | ||
| 377 | const session = createSdkSourceSession(); | ||
| 378 | return service.addExecutorSource( | ||
| 379 | { | ||
| 380 | ...input, | ||
| 381 | scopeId, | ||
| 382 | actorScopeId, | ||
| 383 | executionId: session.executionId, | ||
| 384 | interactionId: session.interactionId, | ||
| 385 | }, | ||
| 386 | options, | ||
| 387 | ); | ||
| 388 | }), | ||
| 389 | connect: (payload) => | ||
| 390 | provideSourceAuth((service) => | ||
| 391 | service.connectMcpSource({ | ||
| 392 | ...payload, | ||
| 393 | scopeId, | ||
| 394 | actorScopeId, | ||
| 395 | }), | ||
| 396 | ), | ||
| 397 | connectBatch: (payload) => | ||
| 398 | provideSourceAuth((service) => { | ||
| 399 | const session = createSdkSourceSession(); | ||
| 400 | return service.connectGoogleDiscoveryBatch({ | ||
| 401 | ...payload, | ||
| 402 | scopeId, | ||
| 403 | actorScopeId, | ||
| 404 | executionId: session.executionId, | ||
| 405 | interactionId: session.interactionId, | ||
| 406 | }); | ||
| 407 | }), | ||
| 408 | discover: (input) => provide(discoverSource(input)), | ||
| 409 | list: () => provide(listSources({ scopeId, actorScopeId })), | ||
| 410 | create: (payload) => provide(createSource({ scopeId, actorScopeId, payload })), | ||
| 411 | get: (sourceId) => provide(getSource({ scopeId, sourceId, actorScopeId })), | ||
| 412 | update: (sourceId, payload) => | ||
| 413 | provide(updateSource({ scopeId, sourceId, actorScopeId, payload })), | ||
| 414 | remove: (sourceId) => | ||
| 415 | provide(removeSource({ scopeId, sourceId })).pipe( | ||
| 416 | Effect.map((result) => result.removed), | ||
| 417 | ), | ||
| 418 | inspection: { | ||
| 419 | get: (sourceId) => provide(getSourceInspection({ scopeId, sourceId })), | ||
| 420 | tool: ({ sourceId, toolPath }) => | ||
| 421 | provide( | ||
| 422 | getSourceInspectionToolDetail({ | ||
| 423 | scopeId, | ||
| 424 | sourceId, | ||
| 425 | toolPath, | ||
| 426 | }), | ||
| 427 | ), | ||
| 428 | discover: ({ sourceId, payload }) => | ||
| 429 | provide( | ||
| 430 | discoverSourceInspectionTools({ | ||
| 431 | scopeId, | ||
| 432 | sourceId, | ||
| 433 | payload, | ||
| 434 | }), | ||
| 435 | ), | ||
| 436 | }, | ||
| 437 | oauthClients: { | ||
| 438 | list: (providerKey) => | ||
| 439 | provideSourceAuth((service) => | ||
| 440 | service.listScopeOauthClients({ | ||
| 441 | scopeId, | ||
| 442 | providerKey, | ||
| 443 | }), | ||
| 444 | ), | ||
| 445 | create: (payload) => | ||
| 446 | provideSourceAuth((service) => | ||
| 447 | service.createScopeOauthClient({ | ||
| 448 | scopeId, | ||
| 449 | providerKey: payload.providerKey, | ||
| 450 | label: payload.label, | ||
| 451 | oauthClient: payload.oauthClient, | ||
| 452 | }), | ||
| 453 | ), | ||
| 454 | remove: (oauthClientId) => | ||
| 455 | provideSourceAuth((service) => | ||
| 456 | service.removeScopeOauthClient({ | ||
| 457 | scopeId, | ||
| 458 | oauthClientId, | ||
| 459 | }), | ||
| 460 | ), | ||
| 461 | }, | ||
| 462 | providerGrants: { | ||
| 463 | remove: (grantId) => | ||
| 464 | provideSourceAuth((service) => | ||
| 465 | service.removeProviderAuthGrant({ | ||
| 466 | scopeId, | ||
| 467 | grantId, | ||
| 468 | }), | ||
| 469 | ), | ||
| 470 | }, | ||
| 471 | }, | ||
| 472 | oauth: { | ||
| 473 | startSourceAuth: (input) => | ||
| 474 | provideSourceAuth((service) => | ||
| 475 | service.startSourceOAuthSession({ | ||
| 476 | ...input, | ||
| 477 | scopeId, | ||
| 478 | actorScopeId, | ||
| 479 | }), | ||
| 480 | ), | ||
| 481 | completeSourceAuth: ({ state, code, error, errorDescription }) => | ||
| 482 | provideSourceAuth((service) => | ||
| 483 | service.completeSourceOAuthSession({ | ||
| 484 | state, | ||
| 485 | code, | ||
| 486 | error, | ||
| 487 | errorDescription, | ||
| 488 | }), | ||
| 489 | ), | ||
| 490 | completeProviderCallback: (input) => | ||
| 491 | provideSourceAuth((service) => | ||
| 492 | service.completeProviderOauthCallback({ | ||
| 493 | ...input, | ||
| 494 | scopeId: input.scopeId ?? scopeId, | ||
| 495 | actorScopeId: input.actorScopeId ?? actorScopeId, | ||
| 496 | }), | ||
| 497 | ), | ||
| 498 | }, | ||
| 499 | executions: { | ||
| 500 | create: (payload) => | ||
| 501 | provide( | ||
| 502 | createExecution({ | ||
| 503 | scopeId, | ||
| 504 | payload, | ||
| 505 | createdByScopeId: actorScopeId, | ||
| 506 | }), | ||
| 507 | ), | ||
| 508 | get: (executionId) => provide(getExecution({ scopeId, executionId })), | ||
| 509 | resume: (executionId, payload) => | ||
| 510 | provide( | ||
| 511 | resumeExecution({ | ||
| 512 | scopeId, | ||
| 513 | executionId, | ||
| 514 | payload, | ||
| 515 | resumedByScopeId: actorScopeId, | ||
| 516 | }), | ||
| 517 | ), | ||
| 518 | }, | ||
| 519 | }; | ||
| 520 | }; | ||
| 521 | |||
| 522 | export const createExecutorEffect = ( | ||
| 523 | options: CreateExecutorEffectOptions, | ||
| 524 | ): Effect.Effect<ExecutorEffect, Error> => | ||
| 525 | Effect.map( | ||
| 526 | options.backend.createRuntime({ | ||
| 527 | executionResolver: options.executionResolver, | ||
| 528 | createInternalToolMap: options.createInternalToolMap, | ||
| 529 | resolveSecretMaterial: options.resolveSecretMaterial, | ||
| 530 | getLocalServerBaseUrl: options.getLocalServerBaseUrl, | ||
| 531 | }), | ||
| 532 | fromRuntime, | ||
| 533 | ); | ||
| @@ -30,19 +30,23 @@ import { · 29 unmodified lines | |||
| 30 | 30 | ||
| 31 | import { | 31 | import { |
| 32 | createExecutorBackend, | 32 | createExecutorBackend, |
| 33 | createExecutorEffect, | ||
| 34 | type Executor, | ||
| 35 | } from "./index"; | 33 | } from "./index"; |
| 34 | import { | ||
| 35 | createExecutorEffect, | ||
| 36 | type ExecutorEffect as Executor, | ||
| 37 | } from "./effect"; | ||
| 36 | import { | 38 | import { |
| 37 | type LocalInstallation, | 39 | type LocalInstallation, |
| 38 | ScopeIdSchema, | 40 | ScopeIdSchema, |
| 39 | } from "./schema"; | 41 | } from "./schema"; |
| 40 | import { | 42 | import { |
| 41 | createLocalExecutorServicesEffect, | 43 | createLocalExecutorServicesEffect, |
| 42 | } from "../../sdk-file/src/index"; | 44 | } from "../../sdk-file/src/effect"; |
| 43 | import { | 45 | import { |
| 44 | ExecutorApi, | ||
| 45 | createExecutorApiLayer, | 46 | createExecutorApiLayer, |
| 47 | } from "../../api/src/http"; | ||
| 48 | import { | ||
| 49 | ExecutorApi, | ||
| 46 | } from "../../api/src/index"; | 50 | } from "../../api/src/index"; |
| 47 | 51 | ||
| 48 | type LocalExecutorServices = Effect.Effect.Success< | 52 | type LocalExecutorServices = Effect.Effect.Success< |
| @@ -1,705 +1,111 @@ | |||
| 1 | import * as Effect from "effect/Effect"; | 1 | import * as Effect from "effect/Effect"; |
| 2 | 2 | ||
| 3 | import type { | ||
| 4 | ScopeId, | ||
| 5 | Execution, | ||
| 6 | ExecutionEnvelope, | ||
| 7 | ExecutionInteraction, | ||
| 8 | LocalInstallation, | ||
| 9 | LocalScopePolicy, | ||
| 10 | ProviderAuthGrant, | ||
| 11 | Source, | ||
| 12 | ScopeOauthClient, | ||
| 13 | } from "./schema"; | ||
| 14 | import { | 3 | import { |
| 15 | ExecutionIdSchema, | 4 | createExecutorEffect, |
| 16 | } from "./schema"; | 5 | type CreateExecutorEffectOptions, |
| 17 | import type { | 6 | type ExecutorEffect, |
| 18 | CreateExecutionPayload, | 7 | type ExecutorMcpSourceInput, |
| 19 | ResumeExecutionPayload, | 8 | type ExecutorSourceBatchInput, |
| 20 | } from "./executions/contracts"; | 9 | type ExecutorSourceInput, |
| 21 | import type { | 10 | type ExecutorSourceOAuthInput, |
| 22 | CreateSecretPayload, | 11 | } from "./executor-effect"; |
| 23 | CreateSecretResult, | ||
| 24 | DeleteSecretResult, | ||
| 25 | InstanceConfig, | ||
| 26 | SecretListItem, | ||
| 27 | UpdateSecretPayload, | ||
| 28 | UpdateSecretResult, | ||
| 29 | } from "./local/contracts"; | ||
| 30 | import { | ||
| 31 | completeSourceCredentialSetup, | ||
| 32 | getLocalInstallation, | ||
| 33 | getSourceCredentialInteraction, | ||
| 34 | submitSourceCredentialInteraction, | ||
| 35 | } from "./local/operations"; | ||
| 36 | import { | ||
| 37 | createLocalSecret, | ||
| 38 | deleteLocalSecret, | ||
| 39 | getLocalInstanceConfig, | ||
| 40 | listLocalSecrets, | ||
| 41 | updateLocalSecret, | ||
| 42 | } from "./local/secrets"; | ||
| 43 | import type { | ||
| 44 | CreatePolicyPayload, | ||
| 45 | UpdatePolicyPayload, | ||
| 46 | } from "./policies/contracts"; | ||
| 47 | import { | ||
| 48 | createPolicy, | ||
| 49 | getPolicy, | ||
| 50 | listPolicies, | ||
| 51 | removePolicy, | ||
| 52 | updatePolicy, | ||
| 53 | } from "./policies/operations"; | ||
| 54 | import type { | ||
| 55 | CreateSourcePayload, | ||
| 56 | CreateScopeOauthClientPayload, | ||
| 57 | UpdateSourcePayload, | ||
| 58 | } from "./sources/contracts"; | ||
| 59 | import { | ||
| 60 | discoverSource, | ||
| 61 | } from "./sources/discovery"; | ||
| 62 | import { | ||
| 63 | discoverSourceInspectionTools, | ||
| 64 | getSourceInspection, | ||
| 65 | getSourceInspectionToolDetail, | ||
| 66 | } from "./sources/inspection"; | ||
| 67 | import { | ||
| 68 | createSource, | ||
| 69 | getSource, | ||
| 70 | listSources, | ||
| 71 | removeSource, | ||
| 72 | updateSource, | ||
| 73 | } from "./sources/operations"; | ||
| 74 | import type { | ||
| 75 | ExecutorBackend, | ||
| 76 | } from "./backend"; | ||
| 77 | import { | ||
| 78 | provideExecutorRuntime, | ||
| 79 | type ExecutorRuntime, | ||
| 80 | type ExecutorRuntimeOptions, | ||
| 81 | type CreateScopeInternalToolMap, | ||
| 82 | type ResolveExecutionEnvironment, | ||
| 83 | type ResolveSecretMaterial, | ||
| 84 | RuntimeSourceAuthServiceTag, | ||
| 85 | } from "./runtime"; | ||
| 86 | import { | ||
| 87 | createExecution, | ||
| 88 | getExecution, | ||
| 89 | resumeExecution, | ||
| 90 | } from "./runtime/execution/service"; | ||
| 91 | import type { | ||
| 92 | CompleteProviderOauthCallbackResult, | ||
| 93 | CompleteSourceCredentialSetupResult, | ||
| 94 | CompleteSourceOAuthSessionResult, | ||
| 95 | ConnectGoogleDiscoveryBatchInput, | ||
| 96 | ConnectGoogleDiscoveryBatchResult, | ||
| 97 | ConnectMcpSourceInput, | ||
| 98 | ExecutorAddSourceInput, | ||
| 99 | ExecutorSourceAddResult, | ||
| 100 | McpSourceConnectResult, | ||
| 101 | StartSourceOAuthSessionInput, | ||
| 102 | StartSourceOAuthSessionResult, | ||
| 103 | } from "./runtime/sources/source-auth-service"; | ||
| 104 | |||
| 105 | type DistributiveOmit<T, Keys extends PropertyKey> = T extends unknown ? Omit<T, Keys> : never; | ||
| 106 | type ProvidedEffect<T extends Effect.Effect<any, any, any>> = Effect.Effect< | ||
| 107 | Effect.Effect.Success<T>, | ||
| 108 | Effect.Effect.Error<T>, | ||
| 109 | never | ||
| 110 | >; | ||
| 111 | |||
| 112 | export type ExecutorSourceInput = DistributiveOmit< | ||
| 113 | ExecutorAddSourceInput, | ||
| 114 | "scopeId" | "actorScopeId" | "executionId" | "interactionId" | ||
| 115 | >; | ||
| 116 | |||
| 117 | export type ExecutorSourceBatchInput = DistributiveOmit< | ||
| 118 | ConnectGoogleDiscoveryBatchInput, | ||
| 119 | "scopeId" | "actorScopeId" | "executionId" | "interactionId" | ||
| 120 | >; | ||
| 121 | 12 | ||
| 122 | export type ExecutorMcpSourceInput = DistributiveOmit< | 13 | type Promiseify<T> = T extends Effect.Effect<infer A, any, any> |
| 123 | ConnectMcpSourceInput, | 14 | ? Promise<A> |
| 124 | "scopeId" | "actorScopeId" | 15 | : T extends (...args: infer Args) => infer Result |
| 125 | >; | 16 | ? (...args: Args) => Promiseify<Result> |
| 126 | 17 | : T extends Promise<infer A> | |
| 127 | export type ExecutorSourceOAuthInput = DistributiveOmit< | 18 | ? Promise<A> |
| 128 | StartSourceOAuthSessionInput, | 19 | : T extends object |
| 129 | "scopeId" | "actorScopeId" | 20 | ? { [Key in keyof T]: Promiseify<T[Key]> } |
| 130 | >; | 21 | : T; |
| 131 | |||
| 132 | export type Executor = { | ||
| 133 | runtime: ExecutorRuntime; | ||
| 134 | installation: LocalInstallation; | ||
| 135 | scopeId: ScopeId; | ||
| 136 | actorScopeId: ScopeId; | ||
| 137 | resolutionScopeIds: ReadonlyArray<ScopeId>; | ||
| 138 | provide: <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, any>; | ||
| 139 | run: <A, E, R>(effect: Effect.Effect<A, E, R>) => Promise<A>; | ||
| 140 | close: () => Promise<void>; | ||
| 141 | effect: { | ||
| 142 | local: { | ||
| 143 | installation: () => ProvidedEffect<ReturnType<typeof getLocalInstallation>>; | ||
| 144 | config: () => ProvidedEffect<ReturnType<typeof getLocalInstanceConfig>>; | ||
| 145 | credentials: { | ||
| 146 | get: (input: { | ||
| 147 | sourceId: Source["id"]; | ||
| 148 | interactionId: ExecutionInteraction["id"]; | ||
| 149 | }) => ProvidedEffect<ReturnType<typeof getSourceCredentialInteraction>>; | ||
| 150 | submit: (input: { | ||
| 151 | sourceId: Source["id"]; | ||
| 152 | interactionId: ExecutionInteraction["id"]; | ||
| 153 | action: "submit" | "continue" | "cancel"; | ||
| 154 | token?: string | null; | ||
| 155 | }) => ProvidedEffect<ReturnType<typeof submitSourceCredentialInteraction>>; | ||
| 156 | complete: (input: { | ||
| 157 | sourceId: Source["id"]; | ||
| 158 | state: string; | ||
| 159 | code?: string | null; | ||
| 160 | error?: string | null; | ||
| 161 | errorDescription?: string | null; | ||
| 162 | }) => ProvidedEffect<ReturnType<typeof completeSourceCredentialSetup>>; | ||
| 163 | }; | ||
| 164 | }; | ||
| 165 | secrets: { | ||
| 166 | list: () => ProvidedEffect<ReturnType<typeof listLocalSecrets>>; | ||
| 167 | create: (payload: CreateSecretPayload) => ProvidedEffect<ReturnType<typeof createLocalSecret>>; | ||
| 168 | update: (input: { | ||
| 169 | secretId: string; | ||
| 170 | payload: UpdateSecretPayload; | ||
| 171 | }) => ProvidedEffect<ReturnType<typeof updateLocalSecret>>; | ||
| 172 | remove: (secretId: string) => ProvidedEffect<ReturnType<typeof deleteLocalSecret>>; | ||
| 173 | }; | ||
| 174 | policies: { | ||
| 175 | list: () => ProvidedEffect<ReturnType<typeof listPolicies>>; | ||
| 176 | create: (payload: CreatePolicyPayload) => ProvidedEffect<ReturnType<typeof createPolicy>>; | ||
| 177 | get: (policyId: string) => ProvidedEffect<ReturnType<typeof getPolicy>>; | ||
| 178 | update: ( | ||
| 179 | policyId: string, | ||
| 180 | payload: UpdatePolicyPayload, | ||
| 181 | ) => ProvidedEffect<ReturnType<typeof updatePolicy>>; | ||
| 182 | remove: (policyId: string) => ProvidedEffect<ReturnType<typeof removePolicy>>; | ||
| 183 | }; | ||
| 184 | sources: { | ||
| 185 | add: ( | ||
| 186 | input: ExecutorSourceInput, | ||
| 187 | options?: { | ||
| 188 | baseUrl?: string | null; | ||
| 189 | }, | ||
| 190 | ) => Effect.Effect<ExecutorSourceAddResult, Error, never>; | ||
| 191 | connect: (payload: ExecutorMcpSourceInput) => Effect.Effect<McpSourceConnectResult, Error, never>; | ||
| 192 | connectBatch: ( | ||
| 193 | payload: ExecutorSourceBatchInput, | ||
| 194 | ) => Effect.Effect<ConnectGoogleDiscoveryBatchResult, Error, never>; | ||
| 195 | discover: (input: { | ||
| 196 | url: string; | ||
| 197 | probeAuth?: Parameters<typeof discoverSource>[0]["probeAuth"]; | ||
| 198 | }) => ProvidedEffect<ReturnType<typeof discoverSource>>; | ||
| 199 | list: () => ProvidedEffect<ReturnType<typeof listSources>>; | ||
| 200 | create: (payload: CreateSourcePayload) => ProvidedEffect<ReturnType<typeof createSource>>; | ||
| 201 | get: (sourceId: Source["id"]) => ProvidedEffect<ReturnType<typeof getSource>>; | ||
| 202 | update: ( | ||
| 203 | sourceId: Source["id"], | ||
| 204 | payload: UpdateSourcePayload, | ||
| 205 | ) => ProvidedEffect<ReturnType<typeof updateSource>>; | ||
| 206 | remove: (sourceId: Source["id"]) => ProvidedEffect<ReturnType<typeof removeSource>>; | ||
| 207 | inspection: { | ||
| 208 | get: (sourceId: Source["id"]) => ProvidedEffect<ReturnType<typeof getSourceInspection>>; | ||
| 209 | tool: (input: { | ||
| 210 | sourceId: Source["id"]; | ||
| 211 | toolPath: string; | ||
| 212 | }) => ProvidedEffect<ReturnType<typeof getSourceInspectionToolDetail>>; | ||
| 213 | discover: (input: { | ||
| 214 | sourceId: Source["id"]; | ||
| 215 | payload: Parameters<typeof discoverSourceInspectionTools>[0]["payload"]; | ||
| 216 | }) => ProvidedEffect<ReturnType<typeof discoverSourceInspectionTools>>; | ||
| 217 | }; | ||
| 218 | oauthClients: { | ||
| 219 | list: ( | ||
| 220 | providerKey: string, | ||
| 221 | ) => Effect.Effect<ReadonlyArray<ScopeOauthClient>, Error, never>; | ||
| 222 | create: ( | ||
| 223 | payload: CreateScopeOauthClientPayload, | ||
| 224 | ) => Effect.Effect<ScopeOauthClient, Error, never>; | ||
| 225 | remove: ( | ||
| 226 | oauthClientId: ScopeOauthClient["id"], | ||
| 227 | ) => Effect.Effect<boolean, Error, never>; | ||
| 228 | }; | ||
| 229 | providerGrants: { | ||
| 230 | remove: (grantId: ProviderAuthGrant["id"]) => Effect.Effect<boolean, Error, never>; | ||
| 231 | }; | ||
| 232 | }; | ||
| 233 | oauth: { | ||
| 234 | startSourceAuth: ( | ||
| 235 | input: ExecutorSourceOAuthInput, | ||
| 236 | ) => Effect.Effect<StartSourceOAuthSessionResult, Error, never>; | ||
| 237 | completeSourceAuth: (input: { | ||
| 238 | state: string; | ||
| 239 | code?: string | null; | ||
| 240 | error?: string | null; | ||
| 241 | errorDescription?: string | null; | ||
| 242 | }) => Effect.Effect<CompleteSourceOAuthSessionResult, Error, never>; | ||
| 243 | completeProviderCallback: (input: { | ||
| 244 | scopeId?: ScopeId; | ||
| 245 | actorScopeId?: ScopeId | null; | ||
| 246 | state: string; | ||
| 247 | code?: string | null; | ||
| 248 | error?: string | null; | ||
| 249 | errorDescription?: string | null; | ||
| 250 | }) => Effect.Effect<CompleteProviderOauthCallbackResult, Error, never>; | ||
| 251 | }; | ||
| 252 | executions: { | ||
| 253 | create: (payload: CreateExecutionPayload) => ProvidedEffect<ReturnType<typeof createExecution>>; | ||
| 254 | get: (executionId: Execution["id"]) => ProvidedEffect<ReturnType<typeof getExecution>>; | ||
| 255 | resume: ( | ||
| 256 | executionId: Execution["id"], | ||
| 257 | payload: ResumeExecutionPayload, | ||
| 258 | ) => ProvidedEffect<ReturnType<typeof resumeExecution>>; | ||
| 259 | }; | ||
| 260 | }; | ||
| 261 | local: { | ||
| 262 | installation: () => Promise<LocalInstallation>; | ||
| 263 | config: () => Promise<InstanceConfig>; | ||
| 264 | credentials: { | ||
| 265 | get: (input: { | ||
| 266 | sourceId: Source["id"]; | ||
| 267 | interactionId: ExecutionInteraction["id"]; | ||
| 268 | }) => Promise<Effect.Effect.Success<ReturnType<typeof getSourceCredentialInteraction>>>; | ||
| 269 | submit: (input: { | ||
| 270 | sourceId: Source["id"]; | ||
| 271 | interactionId: ExecutionInteraction["id"]; | ||
| 272 | action: "submit" | "continue" | "cancel"; | ||
| 273 | token?: string | null; | ||
| 274 | }) => Promise<Effect.Effect.Success<ReturnType<typeof submitSourceCredentialInteraction>>>; | ||
| 275 | complete: (input: { | ||
| 276 | sourceId: Source["id"]; | ||
| 277 | state: string; | ||
| 278 | code?: string | null; | ||
| 279 | error?: string | null; | ||
| 280 | errorDescription?: string | null; | ||
| 281 | }) => Promise<CompleteSourceCredentialSetupResult>; | ||
| 282 | }; | ||
| 283 | }; | ||
| 284 | secrets: { | ||
| 285 | list: () => Promise<ReadonlyArray<SecretListItem>>; | ||
| 286 | create: (payload: CreateSecretPayload) => Promise<CreateSecretResult>; | ||
| 287 | update: (input: { | ||
| 288 | secretId: string; | ||
| 289 | payload: UpdateSecretPayload; | ||
| 290 | }) => Promise<UpdateSecretResult>; | ||
| 291 | remove: (secretId: string) => Promise<DeleteSecretResult>; | ||
| 292 | }; | ||
| 293 | policies: { | ||
| 294 | list: () => Promise<ReadonlyArray<LocalScopePolicy>>; | ||
| 295 | create: (payload: CreatePolicyPayload) => Promise<LocalScopePolicy>; | ||
| 296 | get: (policyId: string) => Promise<LocalScopePolicy>; | ||
| 297 | update: ( | ||
| 298 | policyId: string, | ||
| 299 | payload: UpdatePolicyPayload, | ||
| 300 | ) => Promise<LocalScopePolicy>; | ||
| 301 | remove: (policyId: string) => Promise<boolean>; | ||
| 302 | }; | ||
| 303 | sources: { | ||
| 304 | add: ( | ||
| 305 | input: ExecutorSourceInput, | ||
| 306 | options?: { | ||
| 307 | baseUrl?: string | null; | ||
| 308 | }, | ||
| 309 | ) => Promise<ExecutorSourceAddResult>; | ||
| 310 | connect: (payload: ExecutorMcpSourceInput) => Promise<McpSourceConnectResult>; | ||
| 311 | connectBatch: (payload: ExecutorSourceBatchInput) => Promise<ConnectGoogleDiscoveryBatchResult>; | ||
| 312 | discover: (input: { | ||
| 313 | url: string; | ||
| 314 | probeAuth?: Parameters<typeof discoverSource>[0]["probeAuth"]; | ||
| 315 | }) => Promise<Effect.Effect.Success<ReturnType<typeof discoverSource>>>; | ||
| 316 | list: () => Promise<ReadonlyArray<Source>>; | ||
| 317 | create: (payload: CreateSourcePayload) => Promise<Source>; | ||
| 318 | get: (sourceId: Source["id"]) => Promise<Source>; | ||
| 319 | update: (sourceId: Source["id"], payload: UpdateSourcePayload) => Promise<Source>; | ||
| 320 | remove: (sourceId: Source["id"]) => Promise<boolean>; | ||
| 321 | inspection: { | ||
| 322 | get: (sourceId: Source["id"]) => Promise<Effect.Effect.Success<ReturnType<typeof getSourceInspection>>>; | ||
| 323 | tool: (input: { | ||
| 324 | sourceId: Source["id"]; | ||
| 325 | toolPath: string; | ||
| 326 | }) => Promise<Effect.Effect.Success<ReturnType<typeof getSourceInspectionToolDetail>>>; | ||
| 327 | discover: (input: { | ||
| 328 | sourceId: Source["id"]; | ||
| 329 | payload: Parameters<typeof discoverSourceInspectionTools>[0]["payload"]; | ||
| 330 | }) => Promise<Effect.Effect.Success<ReturnType<typeof discoverSourceInspectionTools>>>; | ||
| 331 | }; | ||
| 332 | oauthClients: { | ||
| 333 | list: (providerKey: string) => Promise<ReadonlyArray<ScopeOauthClient>>; | ||
| 334 | create: ( | ||
| 335 | payload: CreateScopeOauthClientPayload, | ||
| 336 | ) => Promise<ScopeOauthClient>; | ||
| 337 | remove: (oauthClientId: ScopeOauthClient["id"]) => Promise<boolean>; | ||
| 338 | }; | ||
| 339 | providerGrants: { | ||
| 340 | remove: (grantId: ProviderAuthGrant["id"]) => Promise<boolean>; | ||
| 341 | }; | ||
| 342 | }; | ||
| 343 | oauth: { | ||
| 344 | startSourceAuth: (input: ExecutorSourceOAuthInput) => Promise<StartSourceOAuthSessionResult>; | ||
| 345 | completeSourceAuth: (input: { | ||
| 346 | state: string; | ||
| 347 | code?: string | null; | ||
| 348 | error?: string | null; | ||
| 349 | errorDescription?: string | null; | ||
| 350 | }) => Promise<CompleteSourceOAuthSessionResult>; | ||
| 351 | completeProviderCallback: (input: { | ||
| 352 | scopeId?: ScopeId; | ||
| 353 | actorScopeId?: ScopeId | null; | ||
| 354 | state: string; | ||
| 355 | code?: string | null; | ||
| 356 | error?: string | null; | ||
| 357 | errorDescription?: string | null; | ||
| 358 | }) => Promise<CompleteProviderOauthCallbackResult>; | ||
| 359 | }; | ||
| 360 | executions: { | ||
| 361 | create: (payload: CreateExecutionPayload) => Promise<ExecutionEnvelope>; | ||
| 362 | get: (executionId: Execution["id"]) => Promise<ExecutionEnvelope>; | ||
| 363 | resume: ( | ||
| 364 | executionId: Execution["id"], | ||
| 365 | payload: ResumeExecutionPayload, | ||
| 366 | ) => Promise<ExecutionEnvelope>; | ||
| 367 | }; | ||
| 368 | }; | ||
| 369 | 22 | ||
| 370 | export type CreateExecutorOptions = ExecutorRuntimeOptions & { | 23 | export type Executor = Omit<Promiseify<ExecutorEffect>, "runtime">; |
| 371 | backend: ExecutorBackend; | 24 | export type CreateExecutorOptions = CreateExecutorEffectOptions; |
| 25 | export type { | ||
| 26 | ExecutorMcpSourceInput, | ||
| 27 | ExecutorSourceBatchInput, | ||
| 28 | ExecutorSourceInput, | ||
| 29 | ExecutorSourceOAuthInput, | ||
| 372 | }; | 30 | }; |
| 373 | 31 | ||
| 374 | const fromRuntime = (runtime: ExecutorRuntime): Executor => { | 32 | const toPromiseExecutor = (executor: ExecutorEffect): Executor => { |
| 375 | const installation = runtime.localInstallation; | 33 | const run = <A, E>(effect: Effect.Effect<A, E, never>) => |
| 376 | const scopeId = installation.scopeId; | 34 | Effect.runPromise(effect); |
| 377 | const actorScopeId = installation.actorScopeId; | ||
| 378 | const provide = <A, E, R>(effect: Effect.Effect<A, E, R>) => | ||
| 379 | provideExecutorRuntime(effect, runtime); | ||
| 380 | const run = <A, E, R>(effect: Effect.Effect<A, E, R>) => | ||
| 381 | Effect.runPromise(provide(effect) as Effect.Effect<A, E, never>); | ||
| 382 | const provideSourceAuth = <A, E>( | ||
| 383 | execute: ( | ||
| 384 | service: Effect.Effect.Success<typeof RuntimeSourceAuthServiceTag>, | ||
| 385 | ) => Effect.Effect<A, E, any>, | ||
| 386 | ) => provide(Effect.flatMap(RuntimeSourceAuthServiceTag, execute)); | ||
| 387 | const createSdkSourceSession = () => { | ||
| 388 | const id = crypto.randomUUID(); | ||
| 389 | return { | ||
| 390 | executionId: ExecutionIdSchema.make(`exec_sdk_${id}`), | ||
| 391 | interactionId: `executor.sdk.${id}` as never, | ||
| 392 | }; | ||
| 393 | }; | ||
| 394 | const effect = { | ||
| 395 | local: { | ||
| 396 | installation: () => provide(getLocalInstallation()), | ||
| 397 | config: () => provide(getLocalInstanceConfig()), | ||
| 398 | credentials: { | ||
| 399 | get: ({ sourceId, interactionId }) => | ||
| 400 | provide( | ||
| 401 | getSourceCredentialInteraction({ | ||
| 402 | scopeId, | ||
| 403 | sourceId, | ||
| 404 | interactionId, | ||
| 405 | }), | ||
| 406 | ), | ||
| 407 | submit: ({ sourceId, interactionId, action, token }) => | ||
| 408 | provide( | ||
| 409 | submitSourceCredentialInteraction({ | ||
| 410 | scopeId, | ||
| 411 | sourceId, | ||
| 412 | interactionId, | ||
| 413 | action, | ||
| 414 | token, | ||
| 415 | }), | ||
| 416 | ), | ||
| 417 | complete: ({ sourceId, state, code, error, errorDescription }) => | ||
| 418 | provide( | ||
| 419 | completeSourceCredentialSetup({ | ||
| 420 | scopeId, | ||
| 421 | sourceId, | ||
| 422 | state, | ||
| 423 | code, | ||
| 424 | error, | ||
| 425 | errorDescription, | ||
| 426 | }), | ||
| 427 | ), | ||
| 428 | }, | ||
| 429 | }, | ||
| 430 | secrets: { | ||
| 431 | list: () => provide(listLocalSecrets()), | ||
| 432 | create: (payload: CreateSecretPayload) => provide(createLocalSecret(payload)), | ||
| 433 | update: (input: { secretId: string; payload: UpdateSecretPayload }) => | ||
| 434 | provide(updateLocalSecret(input)), | ||
| 435 | remove: (secretId: string) => provide(deleteLocalSecret(secretId)), | ||
| 436 | }, | ||
| 437 | policies: { | ||
| 438 | list: () => provide(listPolicies(scopeId)), | ||
| 439 | create: (payload: CreatePolicyPayload) => | ||
| 440 | provide(createPolicy({ scopeId, payload })), | ||
| 441 | get: (policyId: string) => | ||
| 442 | provide(getPolicy({ scopeId, policyId: policyId as never })), | ||
| 443 | update: (policyId: string, payload: UpdatePolicyPayload) => | ||
| 444 | provide(updatePolicy({ scopeId, policyId: policyId as never, payload })), | ||
| 445 | remove: (policyId: string) => | ||
| 446 | provide(removePolicy({ scopeId, policyId: policyId as never })), | ||
| 447 | }, | ||
| 448 | sources: { | ||
| 449 | add: (input: ExecutorSourceInput, options?: { baseUrl?: string | null }) => | ||
| 450 | provideSourceAuth((service) => { | ||
| 451 | const session = createSdkSourceSession(); | ||
| 452 | return service.addExecutorSource( | ||
| 453 | { | ||
| 454 | ...input, | ||
| 455 | scopeId, | ||
| 456 | actorScopeId: actorScopeId, | ||
| 457 | executionId: session.executionId, | ||
| 458 | interactionId: session.interactionId, | ||
| 459 | }, | ||
| 460 | options, | ||
| 461 | ); | ||
| 462 | }), | ||
| 463 | connect: (payload: ExecutorMcpSourceInput) => | ||
| 464 | provideSourceAuth((service) => | ||
| 465 | service.connectMcpSource({ | ||
| 466 | ...payload, | ||
| 467 | scopeId, | ||
| 468 | actorScopeId: actorScopeId, | ||
| 469 | }), | ||
| 470 | ), | ||
| 471 | connectBatch: (payload: ExecutorSourceBatchInput) => | ||
| 472 | provideSourceAuth((service) => { | ||
| 473 | const session = createSdkSourceSession(); | ||
| 474 | return service.connectGoogleDiscoveryBatch({ | ||
| 475 | ...payload, | ||
| 476 | scopeId, | ||
| 477 | actorScopeId: actorScopeId, | ||
| 478 | executionId: session.executionId, | ||
| 479 | interactionId: session.interactionId, | ||
| 480 | }); | ||
| 481 | }), | ||
| 482 | discover: (input: { | ||
| 483 | url: string; | ||
| 484 | probeAuth?: Parameters<typeof discoverSource>[0]["probeAuth"]; | ||
| 485 | }) => provide(discoverSource(input)), | ||
| 486 | list: () => provide(listSources({ scopeId, actorScopeId })), | ||
| 487 | create: (payload: CreateSourcePayload) => | ||
| 488 | provide(createSource({ scopeId, actorScopeId, payload })), | ||
| 489 | get: (sourceId: Source["id"]) => | ||
| 490 | provide(getSource({ scopeId, sourceId, actorScopeId })), | ||
| 491 | update: (sourceId: Source["id"], payload: UpdateSourcePayload) => | ||
| 492 | provide(updateSource({ scopeId, sourceId, actorScopeId, payload })), | ||
| 493 | remove: (sourceId: Source["id"]) => | ||
| 494 | provide(removeSource({ scopeId, sourceId })), | ||
| 495 | inspection: { | ||
| 496 | get: (sourceId: Source["id"]) => | ||
| 497 | provide(getSourceInspection({ scopeId, sourceId })), | ||
| 498 | tool: ({ sourceId, toolPath }: { sourceId: Source["id"]; toolPath: string }) => | ||
| 499 | provide( | ||
| 500 | getSourceInspectionToolDetail({ | ||
| 501 | scopeId, | ||
| 502 | sourceId, | ||
| 503 | toolPath, | ||
| 504 | }), | ||
| 505 | ), | ||
| 506 | discover: ({ | ||
| 507 | sourceId, | ||
| 508 | payload, | ||
| 509 | }: { | ||
| 510 | sourceId: Source["id"]; | ||
| 511 | payload: Parameters<typeof discoverSourceInspectionTools>[0]["payload"]; | ||
| 512 | }) => | ||
| 513 | provide( | ||
| 514 | discoverSourceInspectionTools({ | ||
| 515 | scopeId, | ||
| 516 | sourceId, | ||
| 517 | payload, | ||
| 518 | }), | ||
| 519 | ), | ||
| 520 | }, | ||
| 521 | oauthClients: { | ||
| 522 | list: (providerKey: string) => | ||
| 523 | provideSourceAuth((service) => | ||
| 524 | service.listScopeOauthClients({ | ||
| 525 | scopeId, | ||
| 526 | providerKey, | ||
| 527 | }), | ||
| 528 | ), | ||
| 529 | create: (payload: CreateScopeOauthClientPayload) => | ||
| 530 | provideSourceAuth((service) => | ||
| 531 | service.createScopeOauthClient({ | ||
| 532 | scopeId, | ||
| 533 | providerKey: payload.providerKey, | ||
| 534 | label: payload.label, | ||
| 535 | oauthClient: payload.oauthClient, | ||
| 536 | }), | ||
| 537 | ), | ||
| 538 | remove: (oauthClientId: ScopeOauthClient["id"]) => | ||
| 539 | provideSourceAuth((service) => | ||
| 540 | service.removeScopeOauthClient({ | ||
| 541 | scopeId, | ||
| 542 | oauthClientId, | ||
| 543 | }), | ||
| 544 | ), | ||
| 545 | }, | ||
| 546 | providerGrants: { | ||
| 547 | remove: (grantId: ProviderAuthGrant["id"]) => | ||
| 548 | provideSourceAuth((service) => | ||
| 549 | service.removeProviderAuthGrant({ | ||
| 550 | scopeId, | ||
| 551 | grantId, | ||
| 552 | }), | ||
| 553 | ), | ||
| 554 | }, | ||
| 555 | }, | ||
| 556 | oauth: { | ||
| 557 | startSourceAuth: (input: ExecutorSourceOAuthInput) => | ||
| 558 | provideSourceAuth((service) => | ||
| 559 | service.startSourceOAuthSession({ | ||
| 560 | ...input, | ||
| 561 | scopeId, | ||
| 562 | actorScopeId: actorScopeId, | ||
| 563 | }), | ||
| 564 | ), | ||
| 565 | completeSourceAuth: ({ state, code, error, errorDescription }) => | ||
| 566 | provideSourceAuth((service) => | ||
| 567 | service.completeSourceOAuthSession({ | ||
| 568 | state, | ||
| 569 | code, | ||
| 570 | error, | ||
| 571 | errorDescription, | ||
| 572 | }), | ||
| 573 | ), | ||
| 574 | completeProviderCallback: (input) => | ||
| 575 | provideSourceAuth((service) => | ||
| 576 | service.completeProviderOauthCallback({ | ||
| 577 | ...input, | ||
| 578 | scopeId: input.scopeId ?? scopeId, | ||
| 579 | actorScopeId: input.actorScopeId ?? actorScopeId, | ||
| 580 | }), | ||
| 581 | ), | ||
| 582 | }, | ||
| 583 | executions: { | ||
| 584 | create: (payload: CreateExecutionPayload) => | ||
| 585 | provide( | ||
| 586 | createExecution({ | ||
| 587 | scopeId, | ||
| 588 | payload, | ||
| 589 | createdByScopeId: actorScopeId, | ||
| 590 | }), | ||
| 591 | ), | ||
| 592 | get: (executionId: Execution["id"]) => | ||
| 593 | provide(getExecution({ scopeId, executionId })), | ||
| 594 | resume: (executionId: Execution["id"], payload: ResumeExecutionPayload) => | ||
| 595 | provide( | ||
| 596 | resumeExecution({ | ||
| 597 | scopeId, | ||
| 598 | executionId, | ||
| 599 | payload, | ||
| 600 | resumedByScopeId: actorScopeId, | ||
| 601 | }), | ||
| 602 | ), | ||
| 603 | }, | ||
| 604 | } satisfies Executor["effect"]; | ||
| 605 | 35 | ||
| 606 | return { | 36 | return { |
| 607 | runtime, | 37 | installation: executor.installation, |
| 608 | installation, | 38 | scopeId: executor.scopeId, |
| 609 | scopeId, | 39 | actorScopeId: executor.actorScopeId, |
| 610 | actorScopeId, | 40 | resolutionScopeIds: executor.resolutionScopeIds, |
| 611 | resolutionScopeIds: installation.resolutionScopeIds, | 41 | close: () => executor.close(), |
| 612 | provide, | ||
| 613 | run, | ||
| 614 | close: () => runtime.close(), | ||
| 615 | effect, | ||
| 616 | local: { | 42 | local: { |
| 617 | installation: () => run(effect.local.installation()), | 43 | installation: () => run(executor.local.installation()), |
| 618 | config: () => run(effect.local.config()), | 44 | config: () => run(executor.local.config()), |
| 619 | credentials: { | 45 | credentials: { |
| 620 | get: ({ sourceId, interactionId }) => | 46 | get: (input) => run(executor.local.credentials.get(input)), |
| 621 | run(effect.local.credentials.get({ sourceId, interactionId })), | 47 | submit: (input) => run(executor.local.credentials.submit(input)), |
| 622 | submit: ({ sourceId, interactionId, action, token }) => | 48 | complete: (input) => run(executor.local.credentials.complete(input)), |
| 623 | run(effect.local.credentials.submit({ sourceId, interactionId, action, token })), | ||
| 624 | complete: ({ sourceId, state, code, error, errorDescription }) => | ||
| 625 | run(effect.local.credentials.complete({ sourceId, state, code, error, errorDescription })), | ||
| 626 | }, | 49 | }, |
| 627 | }, | 50 | }, |
| 628 | secrets: { | 51 | secrets: { |
| 629 | list: () => run(effect.secrets.list()), | 52 | list: () => run(executor.secrets.list()), |
| 630 | create: (payload) => run(effect.secrets.create(payload)), | 53 | create: (payload) => run(executor.secrets.create(payload)), |
| 631 | update: (input) => run(effect.secrets.update(input)), | 54 | update: (input) => run(executor.secrets.update(input)), |
| 632 | remove: (secretId) => run(effect.secrets.remove(secretId)), | 55 | remove: (secretId) => run(executor.secrets.remove(secretId)), |
| 633 | }, | 56 | }, |
| 634 | policies: { | 57 | policies: { |
| 635 | list: () => run(effect.policies.list()), | 58 | list: () => run(executor.policies.list()), |
| 636 | create: (payload) => run(effect.policies.create(payload)), | 59 | create: (payload) => run(executor.policies.create(payload)), |
| 637 | get: (policyId) => run(effect.policies.get(policyId)), | 60 | get: (policyId) => run(executor.policies.get(policyId)), |
| 638 | update: (policyId, payload) => | 61 | update: (policyId, payload) => |
| 639 | run(effect.policies.update(policyId, payload)), | 62 | run(executor.policies.update(policyId, payload)), |
| 640 | remove: async (policyId) => | 63 | remove: (policyId) => run(executor.policies.remove(policyId)), |
| 641 | (await run(effect.policies.remove(policyId))).removed, | ||
| 642 | }, | 64 | }, |
| 643 | sources: { | 65 | sources: { |
| 644 | add: (input, options) => run(effect.sources.add(input, options)), | 66 | add: (input, options) => run(executor.sources.add(input, options)), |
| 645 | connect: (payload) => run(effect.sources.connect(payload)), | 67 | connect: (payload) => run(executor.sources.connect(payload)), |
| 646 | connectBatch: (payload) => run(effect.sources.connectBatch(payload)), | 68 | connectBatch: (payload) => run(executor.sources.connectBatch(payload)), |
| 647 | discover: (input) => run(effect.sources.discover(input)), | 69 | discover: (input) => run(executor.sources.discover(input)), |
| 648 | list: () => run(effect.sources.list()), | 70 | list: () => run(executor.sources.list()), |
| 649 | create: (payload) => run(effect.sources.create(payload)), | 71 | create: (payload) => run(executor.sources.create(payload)), |
| 650 | get: (sourceId) => run(effect.sources.get(sourceId)), | 72 | get: (sourceId) => run(executor.sources.get(sourceId)), |
| 651 | update: (sourceId, payload) => | 73 | update: (sourceId, payload) => |
| 652 | run(effect.sources.update(sourceId, payload)), | 74 | run(executor.sources.update(sourceId, payload)), |
| 653 | remove: async (sourceId) => | 75 | remove: (sourceId) => run(executor.sources.remove(sourceId)), |
| 654 | (await run(effect.sources.remove(sourceId))).removed, | ||
| 655 | inspection: { | 76 | inspection: { |
| 656 | get: (sourceId) => run(effect.sources.inspection.get(sourceId)), | 77 | get: (sourceId) => run(executor.sources.inspection.get(sourceId)), |
| 657 | tool: ({ sourceId, toolPath }) => | 78 | tool: (input) => run(executor.sources.inspection.tool(input)), |
| 658 | run(effect.sources.inspection.tool({ sourceId, toolPath })), | 79 | discover: (input) => run(executor.sources.inspection.discover(input)), |
| 659 | discover: ({ sourceId, payload }) => | ||
| 660 | run(effect.sources.inspection.discover({ sourceId, payload })), | ||
| 661 | }, | 80 | }, |
| 662 | oauthClients: { | 81 | oauthClients: { |
| 663 | list: (providerKey) => | 82 | list: (providerKey) => |
| 664 | run(effect.sources.oauthClients.list(providerKey)), | 83 | run(executor.sources.oauthClients.list(providerKey)), |
| 665 | create: (payload) => run(effect.sources.oauthClients.create(payload)), | 84 | create: (payload) => run(executor.sources.oauthClients.create(payload)), |
| 666 | remove: (oauthClientId) => | 85 | remove: (oauthClientId) => |
| 667 | run(effect.sources.oauthClients.remove(oauthClientId)), | 86 | run(executor.sources.oauthClients.remove(oauthClientId)), |
| 668 | }, | 87 | }, |
| 669 | providerGrants: { | 88 | providerGrants: { |
| 670 | remove: (grantId) => | 89 | remove: (grantId) => |
| 671 | run(effect.sources.providerGrants.remove(grantId)), | 90 | run(executor.sources.providerGrants.remove(grantId)), |
| 672 | }, | 91 | }, |
| 673 | }, | 92 | }, |
| 674 | oauth: { | 93 | oauth: { |
| 675 | startSourceAuth: (input) => run(effect.oauth.startSourceAuth(input)), | 94 | startSourceAuth: (input) => run(executor.oauth.startSourceAuth(input)), |
| 676 | completeSourceAuth: ({ state, code, error, errorDescription }) => | 95 | completeSourceAuth: (input) => |
| 677 | run(effect.oauth.completeSourceAuth({ state, code, error, errorDescription })), | 96 | run(executor.oauth.completeSourceAuth(input)), |
| 678 | completeProviderCallback: (input) => | 97 | completeProviderCallback: (input) => |
| 679 | run(effect.oauth.completeProviderCallback(input)), | 98 | run(executor.oauth.completeProviderCallback(input)), |
| 680 | }, | 99 | }, |
| 681 | executions: { | 100 | executions: { |
| 682 | create: (payload) => run(effect.executions.create(payload)), | 101 | create: (payload) => run(executor.executions.create(payload)), |
| 683 | get: (executionId) => run(effect.executions.get(executionId)), | 102 | get: (executionId) => run(executor.executions.get(executionId)), |
| 684 | resume: (executionId, payload) => | 103 | resume: (executionId, payload) => |
| 685 | run(effect.executions.resume(executionId, payload)), | 104 | run(executor.executions.resume(executionId, payload)), |
| 686 | }, | 105 | }, |
| 687 | }; | 106 | }; |
| 688 | }; | 107 | }; |
| 689 | 108 | ||
| 690 | export const createExecutorEffect = ( | ||
| 691 | options: CreateExecutorOptions, | ||
| 692 | ): Effect.Effect<Executor, Error> => | ||
| 693 | Effect.map( | ||
| 694 | options.backend.createRuntime({ | ||
| 695 | executionResolver: options.executionResolver, | ||
| 696 | createInternalToolMap: options.createInternalToolMap, | ||
| 697 | resolveSecretMaterial: options.resolveSecretMaterial, | ||
| 698 | getLocalServerBaseUrl: options.getLocalServerBaseUrl, | ||
| 699 | }), | ||
| 700 | fromRuntime, | ||
| 701 | ); | ||
| 702 | |||
| 703 | export const createExecutor = async ( | 109 | export const createExecutor = async ( |
| 704 | options: CreateExecutorOptions, | 110 | options: CreateExecutorOptions, |
| 705 | ): Promise<Executor> => Effect.runPromise(createExecutorEffect(options)); | 111 | ): Promise<Executor> => toPromiseExecutor(await Effect.runPromise(createExecutorEffect(options))); |
| @@ -27,7 +27,7 @@ import { · 26 unmodified lines | |||
| 27 | 27 | ||
| 28 | import { | 28 | import { |
| 29 | createLocalExecutorRuntime as createExecutorRuntime, | 29 | createLocalExecutorRuntime as createExecutorRuntime, |
| 30 | } from "../../../../sdk-file/src/index"; | 30 | } from "../../../../sdk-file/src/runtime"; |
| 31 | import { | 31 | import { |
| 32 | withExecutorApiClient, | 32 | withExecutorApiClient, |
| 33 | } from "./test-http-client"; | 33 | } from "./test-http-client"; |
| @@ -100,7 +100,7 @@ describe("execution-http", () => { · 66 unmodified lines | |||
| 100 | (client) => | 100 | (client) => |
| 101 | client.executions.create({ | 101 | client.executions.create({ |
| 102 | path: { | 102 | path: { |
| 103 | scopeId: installation.scopeId, | 103 | workspaceId: installation.scopeId, |
| 104 | }, | 104 | }, |
| 105 | payload: { | 105 | payload: { |
| 106 | code: "return await tools.math.add({ a: 20, b: 22 });", | 106 | code: "return await tools.math.add({ a: 20, b: 22 });", |
| @@ -120,7 +120,7 @@ describe("execution-http", () => { · 13 unmodified lines | |||
| 120 | (client) => | 120 | (client) => |
| 121 | client.executions.get({ | 121 | client.executions.get({ |
| 122 | path: { | 122 | path: { |
| 123 | scopeId: installation.scopeId, | 123 | workspaceId: installation.scopeId, |
| 124 | executionId: createExecution.execution.id, | 124 | executionId: createExecution.execution.id, |
| 125 | }, | 125 | }, |
| 126 | }), | 126 | }), |
| @@ -58,7 +58,7 @@ import { · 57 unmodified lines | |||
| 58 | } from "../index"; | 58 | } from "../index"; |
| 59 | import { | 59 | import { |
| 60 | createLocalExecutorRuntime as createExecutorRuntime, | 60 | createLocalExecutorRuntime as createExecutorRuntime, |
| 61 | } from "../../../../sdk-file/src/index"; | 61 | } from "../../../../sdk-file/src/runtime"; |
| 62 | import { | 62 | import { |
| 63 | withExecutorApiClient, | 63 | withExecutorApiClient, |
| 64 | } from "./test-http-client"; | 64 | } from "./test-http-client"; |
| @@ -353,7 +353,7 @@ describe("execution-mcp-resume", () => { · 288 unmodified lines | |||
| 353 | (client) => | 353 | (client) => |
| 354 | client.executions.create({ | 354 | client.executions.create({ |
| 355 | path: { | 355 | path: { |
| 356 | scopeId: installation.scopeId, | 356 | workspaceId: installation.scopeId, |
| 357 | }, | 357 | }, |
| 358 | payload: { | 358 | payload: { |
| 359 | code: 'return await tools.source.form.gated_echo({ value: "from-control-plane" });', | 359 | code: 'return await tools.source.form.gated_echo({ value: "from-control-plane" });', |
| @@ -387,7 +387,7 @@ describe("execution-mcp-resume", () => { · 27 unmodified lines | |||
| 387 | (client) => | 387 | (client) => |
| 388 | client.executions.resume({ | 388 | client.executions.resume({ |
| 389 | path: { | 389 | path: { |
| 390 | scopeId: installation.scopeId, | 390 | workspaceId: installation.scopeId, |
| 391 | executionId: created.execution.id, | 391 | executionId: created.execution.id, |
| 392 | }, | 392 | }, |
| 393 | payload: { | 393 | payload: { |
| @@ -19,7 +19,7 @@ import * as Effect from "effect/Effect"; · 18 unmodified lines | |||
| 19 | 19 | ||
| 20 | import { | 20 | import { |
| 21 | createLocalExecutorRuntime as createExecutorRuntime, | 21 | createLocalExecutorRuntime as createExecutorRuntime, |
| 22 | } from "../../../../sdk-file/src/index"; | 22 | } from "../../../../sdk-file/src/runtime"; |
| 23 | import { | 23 | import { |
| 24 | withExecutorApiClient, | 24 | withExecutorApiClient, |
| 25 | } from "./test-http-client"; | 25 | } from "./test-http-client"; |
| @@ -74,7 +74,7 @@ describe("execution runtime config", () => { · 48 unmodified lines | |||
| 74 | (client) => | 74 | (client) => |
| 75 | client.executions.create({ | 75 | client.executions.create({ |
| 76 | path: { | 76 | path: { |
| 77 | scopeId: installation.scopeId, | 77 | workspaceId: installation.scopeId, |
| 78 | }, | 78 | }, |
| 79 | payload: { | 79 | payload: { |
| 80 | code: 'await fetch("https://example.com"); return 1;', | 80 | code: 'await fetch("https://example.com"); return 1;', |
| @@ -106,7 +106,7 @@ describe("execution runtime config", () => { · 25 unmodified lines | |||
| 106 | (client) => | 106 | (client) => |
| 107 | client.executions.create({ | 107 | client.executions.create({ |
| 108 | path: { | 108 | path: { |
| 109 | scopeId: installation.scopeId, | 109 | workspaceId: installation.scopeId, |
| 110 | }, | 110 | }, |
| 111 | payload: { | 111 | payload: { |
| 112 | code: 'await fetch("https://example.com"); return 1;', | 112 | code: 'await fetch("https://example.com"); return 1;', |
| @@ -138,7 +138,7 @@ describe("execution runtime config", () => { · 25 unmodified lines | |||
| 138 | (client) => | 138 | (client) => |
| 139 | client.executions.create({ | 139 | client.executions.create({ |
| 140 | path: { | 140 | path: { |
| 141 | scopeId: installation.scopeId, | 141 | workspaceId: installation.scopeId, |
| 142 | }, | 142 | }, |
| 143 | payload: { | 143 | payload: { |
| 144 | code: 'return typeof Deno !== "undefined";', | 144 | code: 'return typeof Deno !== "undefined";', |
| @@ -8,13 +8,17 @@ import { · 7 unmodified lines | |||
| 8 | } from "@effect/platform-node"; | 8 | } from "@effect/platform-node"; |
| 9 | import { | 9 | import { |
| 10 | ExecutorApi, | 10 | ExecutorApi, |
| 11 | createExecutorApiLayer, | ||
| 12 | } from "../../../../api/src/index"; | 11 | } from "../../../../api/src/index"; |
| 12 | import { | ||
| 13 | createExecutorApiLayer, | ||
| 14 | } from "../../../../api/src/http"; | ||
| 13 | import * as Effect from "effect/Effect"; | 15 | import * as Effect from "effect/Effect"; |
| 14 | import * as Layer from "effect/Layer"; | 16 | import * as Layer from "effect/Layer"; |
| 15 | 17 | ||
| 16 | import { | 18 | import { |
| 17 | createExecutorEffect, | 19 | createExecutorEffect, |
| 20 | } from "../../effect"; | ||
| 21 | import { | ||
| 18 | type ExecutorRuntime, | 22 | type ExecutorRuntime, |
| 19 | } from "../../index"; | 23 | } from "../../index"; |
| 20 | 24 | ||
| @@ -81,7 +81,6 @@ import { · 80 unmodified lines | |||
| 81 | } from "./effect-errors"; | 81 | } from "./effect-errors"; |
| 82 | import { | 82 | import { |
| 83 | buildLocalSourceArtifact, | 83 | buildLocalSourceArtifact, |
| 84 | createLocalExecutorRuntime as createExecutorRuntime, | ||
| 85 | deriveLocalInstallation, | 84 | deriveLocalInstallation, |
| 86 | readLocalSourceArtifact, | 85 | readLocalSourceArtifact, |
| 87 | resolveLocalWorkspaceContext, | 86 | resolveLocalWorkspaceContext, |
| @@ -89,7 +88,10 @@ import { · 1 unmodified line | |||
| 89 | writeLocalSourceArtifact, | 88 | writeLocalSourceArtifact, |
| 90 | writeProjectLocalExecutorConfig, | 89 | writeProjectLocalExecutorConfig, |
| 91 | writeLocalWorkspaceState, | 90 | writeLocalWorkspaceState, |
| 92 | } from "../../../sdk-file/src/index"; | 91 | } from "../../../sdk-file/src/effect"; |
| 92 | import { | ||
| 93 | createLocalExecutorRuntime as createExecutorRuntime, | ||
| 94 | } from "../../../sdk-file/src/runtime"; | ||
| 93 | import { | 95 | import { |
| 94 | decodeSourceCredentialInteraction, | 96 | decodeSourceCredentialInteraction, |
| 95 | submitSourceCredentialInteraction, | 97 | submitSourceCredentialInteraction, |
| @@ -10,13 +10,13 @@ import { FileSystem, HttpApiBuilder, HttpServer } from "@effect/platform"; · 9 unmodified lines | |||
| 10 | import { NodeFileSystem } from "@effect/platform-node"; | 10 | import { NodeFileSystem } from "@effect/platform-node"; |
| 11 | import { | 11 | import { |
| 12 | createExecutorApiLayer, | 12 | createExecutorApiLayer, |
| 13 | } from "@executor/platform-api"; | 13 | } from "@executor/platform-api/http"; |
| 14 | import { createExecutorMcpRequestHandler } from "@executor/executor-mcp"; | 14 | import { createExecutorMcpRequestHandler } from "@executor/executor-mcp"; |
| 15 | import { createWorkspaceExecutorAdminToolMap } from "@executor/platform-internal"; | 15 | import { createWorkspaceExecutorAdminToolMap } from "@executor/platform-internal"; |
| 16 | import { | 16 | import { |
| 17 | createExecutorEffect, | 17 | createExecutorEffect, |
| 18 | type Executor, | 18 | type ExecutorEffect as Executor, |
| 19 | } from "@executor/platform-sdk"; | 19 | } from "@executor/platform-sdk/effect"; |
| 20 | import { createLocalExecutorBackend } from "@executor/platform-sdk-file"; | 20 | import { createLocalExecutorBackend } from "@executor/platform-sdk-file"; |
| 21 | import { | 21 | import { |
| 22 | type ResolveExecutionEnvironment, | 22 | type ResolveExecutionEnvironment, |