import * as Effect from "effect/Effect"; import { createExecutorApiEffectClient, type ExecutorApiEffectClient, } from "./effect"; type StripResponse = T extends readonly [infer Value, unknown] ? Value : T; type RemoveWithResponse = T extends object ? Omit : T; type MethodInput Effect.Effect> = RemoveWithResponse< Parameters[0] >; type MethodOutput Effect.Effect> = StripResponse< Effect.Effect.Success> >; type PromiseMethod Effect.Effect> = ( input: MethodInput, ) => Promise>; export type ExecutorApiClient = { local: { installation: PromiseMethod; config: PromiseMethod; listSecrets: PromiseMethod; createSecret: PromiseMethod; updateSecret: PromiseMethod; deleteSecret: PromiseMethod; }; policies: { list: PromiseMethod; create: PromiseMethod; get: PromiseMethod; update: PromiseMethod; remove: PromiseMethod; }; sources: { discover: PromiseMethod; connect: PromiseMethod; connectBatch: PromiseMethod; listWorkspaceOauthClients: PromiseMethod< ExecutorApiEffectClient["sources"]["listWorkspaceOauthClients"] >; createWorkspaceOauthClient: PromiseMethod< ExecutorApiEffectClient["sources"]["createWorkspaceOauthClient"] >; removeWorkspaceOauthClient: PromiseMethod< ExecutorApiEffectClient["sources"]["removeWorkspaceOauthClient"] >; removeProviderAuthGrant: PromiseMethod< ExecutorApiEffectClient["sources"]["removeProviderAuthGrant"] >; list: PromiseMethod; create: PromiseMethod; get: PromiseMethod; update: PromiseMethod; remove: PromiseMethod; inspection: PromiseMethod; inspectionTool: PromiseMethod; inspectionDiscover: PromiseMethod< ExecutorApiEffectClient["sources"]["inspectionDiscover"] >; credentialPage: PromiseMethod; credentialSubmit: PromiseMethod; credentialComplete: PromiseMethod< ExecutorApiEffectClient["sources"]["credentialComplete"] >; providerOauthComplete: PromiseMethod< ExecutorApiEffectClient["sources"]["providerOauthComplete"] >; }; oauth: { startSourceAuth: PromiseMethod; sourceAuthCallback: PromiseMethod; }; executions: { create: PromiseMethod; get: PromiseMethod; resume: PromiseMethod; }; }; const isResponseTuple = ( value: Value | readonly [Value, unknown], ): value is readonly [Value, unknown] => Array.isArray(value) && value.length === 2; function stripResponse(value: Value | readonly [Value, unknown]): Value { return isResponseTuple(value) ? value[0] : value; } const wrapMethod = < F extends (input: any) => Effect.Effect, >( effectClientPromise: Promise, select: (client: ExecutorApiEffectClient) => F, ): PromiseMethod => { const wrapped = (input: MethodInput): Promise> => effectClientPromise .then((client) => Effect.runPromise(select(client)(input))) .then(stripResponse); return wrapped; }; export const createExecutorApiClient = async (input: { baseUrl: string; accountId?: string; }): Promise => { const effectClientPromise = Effect.runPromise( createExecutorApiEffectClient(input), ); return { local: { installation: wrapMethod(effectClientPromise, (client) => client.local.installation), config: wrapMethod(effectClientPromise, (client) => client.local.config), listSecrets: wrapMethod(effectClientPromise, (client) => client.local.listSecrets), createSecret: wrapMethod(effectClientPromise, (client) => client.local.createSecret), updateSecret: wrapMethod(effectClientPromise, (client) => client.local.updateSecret), deleteSecret: wrapMethod(effectClientPromise, (client) => client.local.deleteSecret), }, policies: { list: wrapMethod(effectClientPromise, (client) => client.policies.list), create: wrapMethod(effectClientPromise, (client) => client.policies.create), get: wrapMethod(effectClientPromise, (client) => client.policies.get), update: wrapMethod(effectClientPromise, (client) => client.policies.update), remove: wrapMethod(effectClientPromise, (client) => client.policies.remove), }, sources: { discover: wrapMethod(effectClientPromise, (client) => client.sources.discover), connect: wrapMethod(effectClientPromise, (client) => client.sources.connect), connectBatch: wrapMethod(effectClientPromise, (client) => client.sources.connectBatch), listWorkspaceOauthClients: wrapMethod( effectClientPromise, (client) => client.sources.listWorkspaceOauthClients, ), createWorkspaceOauthClient: wrapMethod( effectClientPromise, (client) => client.sources.createWorkspaceOauthClient, ), removeWorkspaceOauthClient: wrapMethod( effectClientPromise, (client) => client.sources.removeWorkspaceOauthClient, ), removeProviderAuthGrant: wrapMethod( effectClientPromise, (client) => client.sources.removeProviderAuthGrant, ), list: wrapMethod(effectClientPromise, (client) => client.sources.list), create: wrapMethod(effectClientPromise, (client) => client.sources.create), get: wrapMethod(effectClientPromise, (client) => client.sources.get), update: wrapMethod(effectClientPromise, (client) => client.sources.update), remove: wrapMethod(effectClientPromise, (client) => client.sources.remove), inspection: wrapMethod(effectClientPromise, (client) => client.sources.inspection), inspectionTool: wrapMethod( effectClientPromise, (client) => client.sources.inspectionTool, ), inspectionDiscover: wrapMethod( effectClientPromise, (client) => client.sources.inspectionDiscover, ), credentialPage: wrapMethod( effectClientPromise, (client) => client.sources.credentialPage, ), credentialSubmit: wrapMethod( effectClientPromise, (client) => client.sources.credentialSubmit, ), credentialComplete: wrapMethod( effectClientPromise, (client) => client.sources.credentialComplete, ), providerOauthComplete: wrapMethod( effectClientPromise, (client) => client.sources.providerOauthComplete, ), }, oauth: { startSourceAuth: wrapMethod( effectClientPromise, (client) => client.oauth.startSourceAuth, ), sourceAuthCallback: wrapMethod( effectClientPromise, (client) => client.oauth.sourceAuthCallback, ), }, executions: { create: wrapMethod(effectClientPromise, (client) => client.executions.create), get: wrapMethod(effectClientPromise, (client) => client.executions.get), resume: wrapMethod(effectClientPromise, (client) => client.executions.resume), }, }; };