import { describe, expect, expectTypeOf, it } from "vitest"; import { imageExportModule } from "../modules/built-ins/image-export/image-export-module"; import { svgExportModule } from "../modules/built-ins/svg-export/svg-export-module"; import { videoExportModule } from "../modules/built-ins/video-export/video-export-module"; import { toolcraftRuntimeCommandTypes, type ToolcraftCommand } from "../state/types"; import { getBoundaryViolation } from "../modules/testing/module-layer-boundary-test-support"; import { toolcraftArtifactActions, type ToolcraftArtifactActionCatalog } from "./artifact-action-catalog"; // Compile-only: every registered role must retain its specific declared owner. function rejectForeignArtifactOwners() { // @ts-expect-error Another known module cannot own the Image Export adapter. const owner: ToolcraftArtifactActionCatalog["export-image"] = { ...toolcraftArtifactActions["export-image"], moduleId: "svg-export" }; // @ts-expect-error A catalog entry must carry its own role. const role: ToolcraftArtifactActionCatalog["export-image"] = { ...toolcraftArtifactActions["export-image"], role: "export-svg" }; return { owner, role }; } void rejectForeignArtifactOwners; describe("module composition coverage", () => { it("binds each artifact declaration to the matching role and module", () => { const declarations = [imageExportModule(), svgExportModule(), videoExportModule()] .flatMap(module => module.contributions) .filter(contribution => contribution.kind === "panel-action") .map(({ moduleId, role }) => ({ moduleId, role })); expect(Object.values(toolcraftArtifactActions).map(({ moduleId, role }) => ({ moduleId, role }))) .toEqual(declarations); }); it("keeps the public command inventory exhaustive after composing owner payload types", () => { expectTypeOf<(typeof toolcraftRuntimeCommandTypes)[number]>().toEqualTypeOf(); expect(new Set(toolcraftRuntimeCommandTypes).size).toBe(toolcraftRuntimeCommandTypes.length); }); it("allows owner contracts to reference shared document types without opening state implementation imports", () => { expect(getBoundaryViolation("built-ins/layers/contracts.ts", "state/types.ts")).toBeUndefined(); expect(getBoundaryViolation("built-ins/layers/contracts.ts", "state/toolcraft-external-store.ts")) .toBe("built-ins/layers/contracts.ts -> state/toolcraft-external-store.ts"); }); });