1/**
2 * The server's implementation of `ProviderHost.ProviderHost`, the only server surface
3 * provider drivers and adapters may use.
4 *
5 * @module provider/ProviderHostLive
6 */
7import * as ProviderHost from "@t3tools/provider-core/server/ProviderHost";
8import { ProviderCredentialError } from "@t3tools/provider-core/server/errors";
9import * as Crypto from "effect/Crypto";
10import * as Effect from "effect/Effect";
11import * as Layer from "effect/Layer";
12
13import { resolveAttachmentPath } from "../attachmentStore.ts";
14import * as ServerSecretStore from "../auth/ServerSecretStore.ts";
15import * as BackgroundPolicy from "../background/BackgroundPolicy.ts";
16import * as ServerConfig from "../config.ts";
17import * as ServerSettings from "../serverSettings.ts";
18import * as ProviderCredentialStore from "./ProviderCredentialStore.ts";
19
20export const layer = Layer.effect(
21 ProviderHost.ProviderHost,
22 Effect.gen(function* () {
23 const config = yield* ServerConfig.ServerConfig;
24 const serverSettings = yield* ServerSettings.ServerSettingsService;
25 const backgroundPolicy = yield* BackgroundPolicy.BackgroundPolicy;
26 const secrets = yield* ServerSecretStore.ServerSecretStore;
27 const crypto = yield* Crypto.Crypto;
28 return ProviderHost.ProviderHost.of({
29 paths: {
30 cwd: config.cwd,
31 baseDir: config.baseDir,
32 stateDir: config.stateDir,
33 providerStatusCacheDir: config.providerStatusCacheDir,
34 attachmentsDir: config.attachmentsDir,
35 },
36 settings: {
37 get: serverSettings.getSettings,
38 withSnapshot: serverSettings.withSettingsSnapshot,
39 changes: serverSettings.streamChanges,
40 subscribe: serverSettings.subscribeChanges,
41 },
42 shouldRunBackgroundWork: backgroundPolicy.shouldRunScopeWork,
43 resolveAttachmentPath: (attachment) =>
44 resolveAttachmentPath({ attachmentsDir: config.attachmentsDir, attachment }),
45 credentials: (namespace, bindingId) =>
46 ProviderCredentialStore.make(namespace, bindingId).pipe(
47 Effect.map((store) => ({
48 binding: store.binding,
49 get: store.get.pipe(
50 Effect.mapError((cause) => new ProviderCredentialError({ operation: "get", cause })),
51 ),
52 set: (credentials: Uint8Array) =>
53 store
54 .set(credentials)
55 .pipe(
56 Effect.mapError(
57 (cause) => new ProviderCredentialError({ operation: "set", cause }),
58 ),
59 ),
60 remove: store.remove.pipe(
61 Effect.mapError(
62 (cause) => new ProviderCredentialError({ operation: "remove", cause }),
63 ),
64 ),
65 })),
66 Effect.provideService(ServerSecretStore.ServerSecretStore, secrets),
67 Effect.provideService(Crypto.Crypto, crypto),
68 ),
69 });
70 }),
71);