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); };