import assert from "node:assert/strict"; import { test } from "node:test"; import { compileCapabilityResourceSource } from "../src/capability-language/index.js"; import { packageBuildContract } from "../src/execution-world/build-contract.js"; import { generatePortableTypeScriptBindings } from "../src/bindings/portable.js"; import type { BindingSchema } from "../src/bindings/index.js"; import type { InterfaceRevision } from "../src/capability-model/types.js"; function fixture() { const source = { repository: "https://example.test/source", commit: "1".repeat(40) }; const interfaces = new Map(); for (const name of ["Value", "Unrelated"]) { const result = compileCapabilityResourceSource( `interface ${name} id "${name}" revision "${name}@1" { value text id "text" : string { get id "text:get" execution snapshot; } }`, { source }, ); assert.ok(result.ok && result.resource.kind === "interface", JSON.stringify(result.diagnostics)); interfaces.set(name, result.resource.revision); } const result = compileCapabilityResourceSource( `import interface Value; package Adapter id "adapter" revision "adapter@1" { operation fetchText id "read" : unit -> string mode call execution snapshot targets [server] receiver any requires { interface data id "value" : Value using [text.get]; }; }`, { source, environment: { interfaces, interfaceClosure: [...interfaces.values()] } }, ); assert.ok(result.ok && result.resource.kind === "package", JSON.stringify(result.diagnostics)); return { format: "quixos-bindings", version: 1, interfaces: [...interfaces.values()], packages: [result.resource.revision], } satisfies BindingSchema; } test("package builds ignore exact pins and unrelated declarations, and preserve generated port types", () => { const schema = fixture(); const original = packageBuildContract(schema, "adapter@1"); const changed = structuredClone(schema); changed.interfaces.forEach((iface) => { iface.source.commit = "2".repeat(40); }); changed.packages[0]!.source.commit = "3".repeat(40); changed.interfaces.find((iface) => iface.displayName === "Unrelated")!.members = []; assert.deepEqual(packageBuildContract(changed, "adapter@1"), original); assert.equal(JSON.stringify(original).includes("https://example.test/source"), false); assert.equal( generatePortableTypeScriptBindings(original.definition.bindings, "adapter@1", { target: "server" }), generatePortableTypeScriptBindings(schema, "adapter@1", { target: "server" }), ); }); test("changing a consumed interface or an owned port contract invalidates the build", () => { const schema = fixture(); const original = packageBuildContract(schema, "adapter@1"); const changed = structuredClone(schema); changed.interfaces[0]!.members[0]!.operations[0]!.outputType = { kind: "scalar", name: "bool" }; assert.notEqual(packageBuildContract(changed, "adapter@1").digest, original.digest); const own = structuredClone(schema); own.packages[0]!.exports[0]!.outputType = { kind: "scalar", name: "bool" }; assert.notEqual(packageBuildContract(own, "adapter@1").digest, original.digest); }); test("a nominal reference does not import the referenced interface's entire dependency graph", () => { const schema = fixture(); schema.packages[0]!.exports[0]!.inputType = { kind: "object-ref", expectation: { kind: "interface", interfaceRevisionId: schema.interfaces[1]!.revisionId }, }; const original = packageBuildContract(schema, "adapter@1"); schema.interfaces[1]!.members = []; assert.deepEqual(packageBuildContract(schema, "adapter@1"), original); schema.packages[0]!.exports[0]!.inputType = { kind: "scalar", name: "string" }; assert.notEqual(packageBuildContract(schema, "adapter@1").digest, original.digest); });