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
@@ -16,7 +16,7 @@ import {
function validManifest(): Record<string, unknown> {
return {
manifestVersion: 7,
manifestVersion: 8,
id: "calendar",
name: "Calendar",
version: "0.1.0",
@@ -42,6 +42,24 @@ function validManifest(): Record<string, unknown> {
}
describe("module manifest contract", () => {
it("accepts both manifest-v8 database modes", () => {
expect(parseModuleManifest(validManifest()).database).toBeUndefined();
expect(parseModuleManifest({ ...validManifest(), database: { abi: 1 } }).database).toEqual({
abi: 1,
});
});
it("rejects manifest v7, unsupported ABIs, malformed declarations, and unknown database fields", () => {
expect(safeParseModuleManifest({ ...validManifest(), manifestVersion: 7 }).success).toBe(false);
expect(safeParseModuleManifest({ ...validManifest(), database: { abi: 2 } }).success).toBe(
false,
);
expect(safeParseModuleManifest({ ...validManifest(), database: "abi-v1" }).success).toBe(false);
expect(
safeParseModuleManifest({ ...validManifest(), database: { abi: 1, driver: "drizzle" } })
.success,
).toBe(false);
});
it("normalizes a valid manifest with safe defaults", () => {
const manifest = parseModuleManifest(validManifest());
@@ -232,15 +250,15 @@ describe("module manifest contract", () => {
expect(safeParseModuleManifest(version5Manifest).success).toBe(false);
});
it("rejects a version 6 manifest rather than silently interpreting it as version 7", () => {
it("rejects a version 6 manifest rather than silently interpreting it as version 8", () => {
const version6Manifest = { ...validManifest(), manifestVersion: 6 };
expect(safeParseModuleManifest(version6Manifest).success).toBe(false);
});
it("accepts exactly one manifest version, so no document can be read as two versions", () => {
expect(MODULE_MANIFEST_VERSION).toBe(7);
for (const manifestVersion of [1, 2, 3, 4, 5, 6, 8, "7", 7.5, null]) {
expect(MODULE_MANIFEST_VERSION).toBe(8);
for (const manifestVersion of [1, 2, 3, 4, 5, 6, 7, 9, "8", 8.5, null]) {
expect(safeParseModuleManifest({ ...validManifest(), manifestVersion }).success).toBe(false);
}
expect(
@@ -0,0 +1,44 @@
import { describe, expect, it } from "vitest";
import { parseModuleSchemaMetadataDefinition } from "../src/index.js";
describe("module schema metadata contract", () => {
it("accepts and freezes plain ABI-v1 metadata", () => {
const definition = parseModuleSchemaMetadataDefinition({
moduleId: "calendar",
tables: [
{ name: "calendar_events" },
{ name: "calendar_attendees", foreignKeys: [{ table: "calendar_events" }] },
],
});
expect(definition).toEqual({
moduleId: "calendar",
tables: [
{ name: "calendar_events", foreignKeys: [] },
{ name: "calendar_attendees", foreignKeys: [{ table: "calendar_events" }] },
],
});
expect(Object.isFrozen(definition)).toBe(true);
expect(Object.isFrozen(definition.tables)).toBe(true);
expect(Object.isFrozen(definition.tables[1]?.foreignKeys)).toBe(true);
});
it("strictly rejects malformed, executable, and class-backed metadata", () => {
class Metadata {
moduleId = "calendar";
tables = [{ name: "calendar_events" }];
}
for (const value of [
{ moduleId: "calendar", tables: [] },
{ moduleId: "calendar", tables: [{ name: "calendar_events", unknown: true }] },
{ moduleId: "calendar", tables: [{ name: "calendar_events", foreignKeys: [{}] }] },
{ moduleId: "calendar", tables: [{ name: "calendar_events", inspect: () => undefined }] },
new Metadata(),
]) {
expect(() => parseModuleSchemaMetadataDefinition(value)).toThrow(
"Invalid Ekklesia module schema metadata definition.",
);
}
});
});