everything-dev
Version:
A consolidated product package for building Module Federation apps with oRPC APIs.
76 lines (74 loc) • 3.1 kB
JavaScript
import { getDatabaseUrlSecretName, getMigrationStorage, pluginMigrationSlug } from "./core.mjs";
import { workspaceIdentityFromWorkspaceDir } from "./identity.mjs";
import { resolve } from "node:path";
import { Context, Data, Effect, Layer } from "effect";
//#region src/db/bindings.ts
var DatabaseBindingError = class extends Data.TaggedError("DatabaseBindingError") {};
var DatabaseBindings = class extends Context.Service()("everything-dev/DatabaseBindings") {};
function resolvePluginBinding(pluginKey, runtimeConfig, projectDir, env) {
if (!runtimeConfig) throw new Error("Runtime config not loaded — cannot resolve plugin database binding");
let source;
let section;
let secrets;
let localPath;
let key;
if (pluginKey === "api" && runtimeConfig.api) {
source = runtimeConfig.api.source;
section = "app.api";
secrets = runtimeConfig.api.secrets;
localPath = runtimeConfig.api.localPath;
key = "api";
} else if (pluginKey === "auth" && runtimeConfig.auth) {
source = runtimeConfig.auth.source;
section = "app.auth";
secrets = runtimeConfig.auth.secrets;
localPath = runtimeConfig.auth.localPath;
key = "auth";
} else if (runtimeConfig.plugins?.[pluginKey]) {
const plugin = runtimeConfig.plugins[pluginKey];
source = plugin.source;
section = "plugins";
secrets = plugin.secrets;
localPath = plugin.localPath;
key = pluginKey;
} else {
const available = [
"api",
...runtimeConfig.auth ? ["auth"] : [],
...Object.keys(runtimeConfig.plugins ?? {})
].join(", ");
throw new Error(`Plugin "${pluginKey}" not found in app.api, app.auth, or plugins. Available: ${available}`);
}
const identity = localPath ? workspaceIdentityFromWorkspaceDir(resolve(projectDir, localPath)) : {
slug: pluginMigrationSlug(key),
secretName: getDatabaseUrlSecretName(pluginMigrationSlug(key)),
journal: getMigrationStorage(pluginMigrationSlug(key)),
workspaceDir: void 0
};
const url = env[identity.secretName];
if (!url) {
const declaredDatabaseSecrets = (secrets ?? []).filter((s) => s.endsWith("_DATABASE_URL"));
const mismatch = declaredDatabaseSecrets.length > 0 && !declaredDatabaseSecrets.includes(identity.secretName) ? ` Config declares ${declaredDatabaseSecrets.join(", ")} — the workspace package name and the declared secret disagree.` : "";
throw new Error(`.env missing ${identity.secretName} for plugin "${key}".` + mismatch + ` Add it to your .env file (see .env.example).`);
}
return {
key,
source: source ?? "remote",
section,
identity,
url
};
}
const makeDatabaseBindings = (options) => Layer.succeed(DatabaseBindings, { forPluginKey: (pluginKey) => Effect.tryPromise({
try: async () => {
await options.loadEnv?.();
return resolvePluginBinding(pluginKey, await options.loadRuntimeConfig(), options.projectDir, options.env ?? process.env);
},
catch: (error) => new DatabaseBindingError({
pluginKey,
message: error instanceof Error ? error.message : String(error)
})
}) });
//#endregion
export { DatabaseBindingError, DatabaseBindings, makeDatabaseBindings };
//# sourceMappingURL=bindings.mjs.map