UNPKG

everything-dev

Version:

A consolidated product package for building Module Federation apps with oRPC APIs.

1 lines • 6.9 kB
{"version":3,"file":"bindings.cjs","names":["Data","Context","workspaceIdentityFromWorkspaceDir","resolve","pluginMigrationSlug","getDatabaseUrlSecretName","getMigrationStorage","Layer","Effect"],"sources":["../../src/db/bindings.ts"],"sourcesContent":["import { resolve } from \"node:path\";\nimport { Context, Data, Effect, Layer } from \"effect\";\nimport type { RuntimeConfig } from \"../types\";\nimport { getDatabaseUrlSecretName, getMigrationStorage, pluginMigrationSlug } from \"./core\";\nimport { type WorkspaceIdentity, workspaceIdentityFromWorkspaceDir } from \"./identity\";\n\nexport interface DatabaseBinding {\n readonly key: string;\n readonly source: \"local\" | \"remote\";\n readonly section: \"app.api\" | \"app.auth\" | \"plugins\";\n readonly identity: WorkspaceIdentity;\n readonly url: string;\n}\n\nexport class DatabaseBindingError extends Data.TaggedError(\"DatabaseBindingError\")<{\n readonly pluginKey: string;\n readonly message: string;\n}> {}\n\nexport interface DatabaseBindingsService {\n readonly forPluginKey: (\n pluginKey: string,\n ) => Effect.Effect<DatabaseBinding, DatabaseBindingError>;\n}\n\nexport class DatabaseBindings extends Context.Service<DatabaseBindings, DatabaseBindingsService>()(\n \"everything-dev/DatabaseBindings\",\n) {}\n\ninterface RuntimePluginEntry {\n readonly source?: string;\n readonly secrets?: string[];\n readonly localPath?: string;\n}\n\nfunction resolvePluginBinding(\n pluginKey: string,\n runtimeConfig: RuntimeConfig | null,\n projectDir: string,\n env: Record<string, string | undefined>,\n): DatabaseBinding {\n if (!runtimeConfig) {\n throw new Error(\"Runtime config not loaded — cannot resolve plugin database binding\");\n }\n\n let source: \"local\" | \"remote\" | undefined;\n let section: DatabaseBinding[\"section\"];\n let secrets: string[] | undefined;\n let localPath: string | undefined;\n let key: string;\n\n if (pluginKey === \"api\" && runtimeConfig.api) {\n source = runtimeConfig.api.source as \"local\" | \"remote\";\n section = \"app.api\";\n secrets = runtimeConfig.api.secrets;\n localPath = runtimeConfig.api.localPath;\n key = \"api\";\n } else if (pluginKey === \"auth\" && runtimeConfig.auth) {\n source = runtimeConfig.auth.source as \"local\" | \"remote\";\n section = \"app.auth\";\n secrets = runtimeConfig.auth.secrets;\n localPath = runtimeConfig.auth.localPath;\n key = \"auth\";\n } else if (runtimeConfig.plugins?.[pluginKey]) {\n const plugin = runtimeConfig.plugins[pluginKey] as RuntimePluginEntry;\n source = plugin.source as \"local\" | \"remote\";\n section = \"plugins\";\n secrets = plugin.secrets;\n localPath = plugin.localPath;\n key = pluginKey;\n } else {\n const available = [\n \"api\",\n ...(runtimeConfig.auth ? [\"auth\"] : []),\n ...Object.keys(runtimeConfig.plugins ?? {}),\n ].join(\", \");\n throw new Error(\n `Plugin \"${pluginKey}\" not found in app.api, app.auth, or plugins. Available: ${available}`,\n );\n }\n\n const identity: WorkspaceIdentity = localPath\n ? workspaceIdentityFromWorkspaceDir(resolve(projectDir, localPath))\n : {\n slug: pluginMigrationSlug(key),\n secretName: getDatabaseUrlSecretName(pluginMigrationSlug(key)),\n journal: getMigrationStorage(pluginMigrationSlug(key)),\n workspaceDir: undefined,\n };\n\n const url = env[identity.secretName];\n if (!url) {\n const declaredDatabaseSecrets = (secrets ?? []).filter((s) => s.endsWith(\"_DATABASE_URL\"));\n const mismatch =\n declaredDatabaseSecrets.length > 0 && !declaredDatabaseSecrets.includes(identity.secretName)\n ? ` Config declares ${declaredDatabaseSecrets.join(\", \")} — the workspace package name and the declared secret disagree.`\n : \"\";\n throw new Error(\n `.env missing ${identity.secretName} for plugin \"${key}\".` +\n mismatch +\n ` Add it to your .env file (see .env.example).`,\n );\n }\n\n return {\n key,\n source: source ?? \"remote\",\n section,\n identity,\n url,\n };\n}\n\nexport interface DatabaseBindingsOptions {\n readonly projectDir: string;\n readonly loadRuntimeConfig: () => Promise<RuntimeConfig | null>;\n /** May return a promise — a rejection propagates into the binding error instead of silently proceeding with an unloaded .env. */\n readonly loadEnv?: () => void | Promise<void>;\n readonly env?: Record<string, string | undefined>;\n}\n\nexport const makeDatabaseBindings = (\n options: DatabaseBindingsOptions,\n): Layer.Layer<DatabaseBindings> =>\n Layer.succeed(DatabaseBindings, {\n forPluginKey: (pluginKey) =>\n Effect.tryPromise({\n try: async () => {\n await options.loadEnv?.();\n const runtimeConfig = await options.loadRuntimeConfig();\n return resolvePluginBinding(\n pluginKey,\n runtimeConfig,\n options.projectDir,\n options.env ?? process.env,\n );\n },\n catch: (error) =>\n new DatabaseBindingError({\n pluginKey,\n message: error instanceof Error ? error.message : String(error),\n }),\n }),\n });\n"],"mappings":";;;;;;AAcA,IAAa,uBAAb,cAA0CA,YAAK,YAAY,sBAAsB,CAAC,CAG/E,CAAC;AAQJ,IAAa,mBAAb,cAAsCC,eAAQ,QAAmD,CAAC,CAChG,iCACF,CAAC,CAAC,CAAC;AAQH,SAAS,qBACP,WACA,eACA,YACA,KACiB;CACjB,IAAI,CAAC,eACH,MAAM,IAAI,MAAM,oEAAoE;CAGtF,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CAEJ,IAAI,cAAc,SAAS,cAAc,KAAK;EAC5C,SAAS,cAAc,IAAI;EAC3B,UAAU;EACV,UAAU,cAAc,IAAI;EAC5B,YAAY,cAAc,IAAI;EAC9B,MAAM;CACR,OAAO,IAAI,cAAc,UAAU,cAAc,MAAM;EACrD,SAAS,cAAc,KAAK;EAC5B,UAAU;EACV,UAAU,cAAc,KAAK;EAC7B,YAAY,cAAc,KAAK;EAC/B,MAAM;CACR,OAAO,IAAI,cAAc,UAAU,YAAY;EAC7C,MAAM,SAAS,cAAc,QAAQ;EACrC,SAAS,OAAO;EAChB,UAAU;EACV,UAAU,OAAO;EACjB,YAAY,OAAO;EACnB,MAAM;CACR,OAAO;EACL,MAAM,YAAY;GAChB;GACA,GAAI,cAAc,OAAO,CAAC,MAAM,IAAI,CAAC;GACrC,GAAG,OAAO,KAAK,cAAc,WAAW,CAAC,CAAC;EAC5C,CAAC,CAAC,KAAK,IAAI;EACX,MAAM,IAAI,MACR,WAAW,UAAU,2DAA2D,WAClF;CACF;CAEA,MAAM,WAA8B,YAChCC,uDAAkCC,mBAAQ,YAAY,SAAS,CAAC,IAChE;EACE,MAAMC,iCAAoB,GAAG;EAC7B,YAAYC,sCAAyBD,iCAAoB,GAAG,CAAC;EAC7D,SAASE,iCAAoBF,iCAAoB,GAAG,CAAC;EACrD,cAAc;CAChB;CAEJ,MAAM,MAAM,IAAI,SAAS;CACzB,IAAI,CAAC,KAAK;EACR,MAAM,2BAA2B,WAAW,CAAC,EAAC,CAAE,QAAQ,MAAM,EAAE,SAAS,eAAe,CAAC;EACzF,MAAM,WACJ,wBAAwB,SAAS,KAAK,CAAC,wBAAwB,SAAS,SAAS,UAAU,IACvF,oBAAoB,wBAAwB,KAAK,IAAI,EAAE,mEACvD;EACN,MAAM,IAAI,MACR,gBAAgB,SAAS,WAAW,eAAe,IAAI,MACrD,WACA,+CACJ;CACF;CAEA,OAAO;EACL;EACA,QAAQ,UAAU;EAClB;EACA;EACA;CACF;AACF;AAUA,MAAa,wBACX,YAEAG,aAAM,QAAQ,kBAAkB,EAC9B,eAAe,cACbC,cAAO,WAAW;CAChB,KAAK,YAAY;EACf,MAAM,QAAQ,UAAU;EAExB,OAAO,qBACL,WACA,MAH0B,QAAQ,kBAAkB,GAIpD,QAAQ,YACR,QAAQ,OAAO,QAAQ,GACzB;CACF;CACA,QAAQ,UACN,IAAI,qBAAqB;EACvB;EACA,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;CAChE,CAAC;AACL,CAAC,EACL,CAAC"}