131 lines · 4.4 KB · TypeScript
RawDownload
import {  ConnectionPersistenceError,  ConnectionRegistrationStore,  ConnectionTargetStore,  putRemoteDpopTokenInCatalog,  registerConnectionInCatalog,  removeConnectionFromCatalog,  removeCatalogValue,  replaceCatalogValue,} from "@t3tools/client-runtime/platform";import { TokenStore } from "@t3tools/client-runtime/authorization";import {  ConnectionTransientError,  CredentialStore,  ProfileStore,} from "@t3tools/client-runtime/connection";import * as Context from "effect/Context";import * as Effect from "effect/Effect";import * as Layer from "effect/Layer";import * as Option from "effect/Option";import * as CatalogStore from "./catalog-store"; function targetPersistenceError(  operation: "list-targets" | "register-connection" | "remove-connection",  error: ConnectionTransientError,) {  return new ConnectionPersistenceError({    operation,    message: error.message,  });} export const connectionStorageLayer = Layer.effectContext(  Effect.gen(function* () {    const catalog = yield* CatalogStore.make();     const targetStore = ConnectionTargetStore.of({      list: catalog.read.pipe(        Effect.map((document) => document.targets),        Effect.mapError((error) => targetPersistenceError("list-targets", error)),      ),    });    const registrationStore = ConnectionRegistrationStore.of({      register: (registration) =>        catalog          .update((document) => registerConnectionInCatalog(document, registration))          .pipe(Effect.mapError((error) => targetPersistenceError("register-connection", error))),      remove: (target) =>        catalog          .update((document) => removeConnectionFromCatalog(document, target))          .pipe(Effect.mapError((error) => targetPersistenceError("remove-connection", error))),    });    const profileStore = ProfileStore.make({      get: (connectionId) =>        catalog.read.pipe(          Effect.map((document) =>            Option.fromUndefinedOr(              document.profiles.find((candidate) => candidate.connectionId === connectionId),            ),          ),        ),      put: (profile) =>        catalog.update((document) => ({          ...document,          profiles: replaceCatalogValue(document.profiles, (value) => value.connectionId, profile),        })),      remove: (connectionId) =>        catalog.update((document) => ({          ...document,          profiles: removeCatalogValue(            document.profiles,            (value) => value.connectionId,            connectionId,          ),        })),    });    const credentialStore = CredentialStore.make({      get: (connectionId) =>        catalog.read.pipe(          Effect.map((document) =>            Option.fromUndefinedOr(              document.credentials.find((entry) => entry.connectionId === connectionId)?.credential,            ),          ),        ),      put: (connectionId, credential) =>        catalog.update((document) => ({          ...document,          credentials: replaceCatalogValue(document.credentials, (value) => value.connectionId, {            connectionId,            credential,          }),        })),      remove: (connectionId) =>        catalog.update((document) => ({          ...document,          credentials: removeCatalogValue(            document.credentials,            (value) => value.connectionId,            connectionId,          ),        })),    });    const remoteTokenStore = TokenStore.make({      get: (environmentId) =>        catalog.read.pipe(          Effect.map((document) =>            Option.fromUndefinedOr(              document.remoteDpopTokens.find((token) => token.environmentId === environmentId),            ),          ),        ),      put: (token) => catalog.update((document) => putRemoteDpopTokenInCatalog(document, token)),      remove: (environmentId) =>        catalog.update((document) => ({          ...document,          remoteDpopTokens: removeCatalogValue(            document.remoteDpopTokens,            (value) => value.environmentId,            environmentId,          ),        })),    });    return Context.make(ConnectionTargetStore, targetStore).pipe(      Context.add(ConnectionRegistrationStore, registrationStore),      Context.add(ProfileStore.ConnectionProfileStore, profileStore),      Context.add(CredentialStore.ConnectionCredentialStore, credentialStore),      Context.add(TokenStore.RemoteDpopAccessTokenStore, remoteTokenStore),    );  }),);