import { readFileSync } from "node:fs"; import { resolve } from "node:path"; import { capabilityId, type WorkspaceRevision } from "../../src/capability-model/index.js"; import { compileCapabilityResourceSource, compileCapabilitySource, type CapabilityImportEnvironment, } from "../../src/capability-language/index.js"; import type { InterfaceRevision, PackageRevision } from "../../src/capability-model/index.js"; export const fixtureId = { workspace: capabilityId.workspace("workspace:todo"), workspaceRevision: capabilityId.workspaceRevision("workspace:todo@1"), project: capabilityId.atom("atom:project"), person: capabilityId.atom("atom:person"), namedV1: capabilityId.interfaceRevision("interface:named@1"), ownedV1: capabilityId.interfaceRevision("interface:owned@1"), summaryV1: capabilityId.interfaceRevision("interface:summary@1"), namedGet: capabilityId.operation("operation:named:name:get"), namedSet: capabilityId.operation("operation:named:name:set"), ownerResolve: capabilityId.operation("operation:owned:owner:resolve"), summaryGet: capabilityId.operation("operation:summary:summary:get"), projectTitle: capabilityId.slot("slot:project:title"), personName: capabilityId.slot("slot:person:name"), projectOwner: capabilityId.edgeType("edge:project:owner"), projectOwnerProjection: capabilityId.edgeProjection("projection:project-owner:owner"), projectNamedConformance: { atomId: capabilityId.atom("atom:project"), interfaceRevisionId: capabilityId.interfaceRevision("interface:named@1"), }, personNamedConformance: { atomId: capabilityId.atom("atom:person"), interfaceRevisionId: capabilityId.interfaceRevision("interface:named@1"), }, projectOwnedConformance: { atomId: capabilityId.atom("atom:project"), interfaceRevisionId: capabilityId.interfaceRevision("interface:owned@1"), }, projectSummaryConformance: { atomId: capabilityId.atom("atom:project"), interfaceRevisionId: capabilityId.interfaceRevision("interface:summary@1"), }, todoRuntimeV1: capabilityId.packageRevision("package:todo-runtime@1"), summaryGetExport: capabilityId.packageExport("export:todo-runtime:summary-get"), createPersonExport: capabilityId.packageExport("export:todo-runtime:create-person"), titlePort: capabilityId.dependencyPort("port:summary:title"), namedPort: capabilityId.dependencyPort("port:summary:named"), personPort: capabilityId.dependencyPort("port:summary:person"), } as const; export const capabilityFixturePath = resolve(process.cwd(), "test/fixtures/todo.capabilities.qx"); export const capabilityFixtureSource = readFileSync(capabilityFixturePath, "utf8"); const resourceSource = (name: string) => readFileSync(resolve(process.cwd(), "test/fixtures", name), "utf8"); export const capabilityResourceSources = { named: resourceSource("named.interface.qx"), owned: resourceSource("owned.interface.qx"), summary: resourceSource("summary.interface.qx"), todo: resourceSource("todo.package.qx"), } as const; const source = (repository: string, commit: string) => ({ repository, commit }); const interfaceRevision = ( resource: { kind: "interface"; revision: InterfaceRevision } | { kind: "package"; revision: PackageRevision }, ) => { if (resource.kind !== "interface") throw new Error("Expected interface fixture"); return resource.revision; }; const packageRevision = ( resource: { kind: "interface"; revision: InterfaceRevision } | { kind: "package"; revision: PackageRevision }, ) => { if (resource.kind !== "package") throw new Error("Expected package fixture"); return resource.revision; }; export const compileCapabilityFixture = ( overrides: Partial<{ workspace: string; named: string; owned: string; summary: string; todo: string; }> = {}, ) => { const named = compileCapabilityResourceSource(overrides.named ?? capabilityResourceSources.named, { source: source("https://repos.quixos.org/quixos-todo/interface-named.git", "2".repeat(40)), fileName: "named.interface.qx", }); if (!named.ok) return named; const namedRevision = interfaceRevision(named.resource); const namedEnvironment: CapabilityImportEnvironment = { interfaces: new Map([["Named", namedRevision]]), interfaceClosure: [namedRevision], }; const owned = compileCapabilityResourceSource(overrides.owned ?? capabilityResourceSources.owned, { source: source("https://repos.quixos.org/quixos-todo/interface-owned.git", "3".repeat(40)), fileName: "owned.interface.qx", environment: namedEnvironment, }); if (!owned.ok) return owned; const ownedRevision = interfaceRevision(owned.resource); const summary = compileCapabilityResourceSource(overrides.summary ?? capabilityResourceSources.summary, { source: source("https://repos.quixos.org/quixos-todo/interface-summary.git", "4".repeat(40)), fileName: "summary.interface.qx", }); if (!summary.ok) return summary; const summaryRevision = interfaceRevision(summary.resource); const todo = compileCapabilityResourceSource(overrides.todo ?? capabilityResourceSources.todo, { source: source("https://repos.quixos.org/quixos-todo/package-todo-runtime.git", "5".repeat(40)), fileName: "todo.package.qx", environment: namedEnvironment, }); if (!todo.ok) return todo; const todoRevision = packageRevision(todo.resource); return compileCapabilitySource(overrides.workspace ?? capabilityFixtureSource, capabilityFixturePath, { interfaces: new Map([ ["Named", namedRevision], ["Owned", ownedRevision], ["Summary", summaryRevision], ]), packages: new Map([["TodoRuntime", todoRevision]]), interfaceClosure: [namedRevision, ownedRevision, summaryRevision], packageClosure: [todoRevision], }); }; export const makeValidCapabilityWorkspace = (): WorkspaceRevision => { const result = compileCapabilityFixture(); if (!result.ok) { throw new Error(result.diagnostics.map((entry) => `${entry.phase}/${entry.code}: ${entry.message}`).join("\n")); } return structuredClone(result.workspace); };