feat: deliver module database ABI by manifest
CI / verify (pull_request) Successful in 1m0s
CI / infrastructure-smoke (pull_request) Successful in 36s
CI / migration-smoke (pull_request) Successful in 1m53s
CI / image-build (pull_request) Successful in 23s
CI / deploy-smoke (same-origin) (pull_request) Successful in 50s
CI / deploy-smoke (split) (pull_request) Successful in 1m30s

This commit is contained in:
ekklesia
2026-10-07 17:29:32 -05:00
parent a1cdcb3ad1
commit 49b4d4165d
60 changed files with 948 additions and 237 deletions
+27
View File
@@ -3,7 +3,11 @@ import type {
ModuleDatabaseParameter,
ModuleDatabaseQueryable,
ModuleDatabaseTransaction,
ModuleId,
ModuleSchemaMetadataDefinition,
} from "@ekklesia/contracts";
import { parseModuleSchemaMetadataDefinition } from "@ekklesia/contracts";
import { type AnyPgTable, getTableConfig } from "drizzle-orm/pg-core";
import { drizzle, type PgRemoteDatabase } from "drizzle-orm/pg-proxy";
import type { DrizzleConfig } from "drizzle-orm/utils";
@@ -83,3 +87,26 @@ export function moduleDrizzle<TSchema extends Record<string, unknown> = Record<s
executor.transaction((transaction) => callback(transactionDatabase(transaction, config))),
);
}
/** Derives the plain ABI-v1 schema entrypoint from a module's own Drizzle tables. Drizzle stays on
* this module-side adapter path; Core consumes only the returned strings and arrays. */
export function moduleDrizzleSchemaMetadata(
moduleId: ModuleId,
tables: Readonly<Record<string, AnyPgTable>>,
): ModuleSchemaMetadataDefinition {
const metadata = Object.entries(tables)
.sort(([left], [right]) => (left < right ? -1 : left > right ? 1 : 0))
.map(([_exportName, table]) => {
const config = getTableConfig(table);
if (config.schema !== undefined && config.schema !== "public") {
throw new TypeError("Module schema metadata supports only the public PostgreSQL schema.");
}
return {
name: config.name,
foreignKeys: config.foreignKeys.map((foreignKey) => ({
table: getTableConfig(foreignKey.reference().foreignTable).name,
})),
};
});
return parseModuleSchemaMetadataDefinition({ moduleId, tables: metadata });
}