Add queryable capability contracts and checked GraphQL artifacts

This commit is contained in:
Timothy J. Aveni
2026-09-17 14:34:16 -07:00
parent e3501772c5
commit 61a410f98f
27 changed files with 4798 additions and 2333 deletions
+41
View File
@@ -0,0 +1,41 @@
import assert from "node:assert/strict";
import { test } from "node:test";
import { compileCapabilityResourceSource } from "../src/capability-language/index.js";
import {
capabilityFixtureSource,
capabilityResourceSources,
compileCapabilityFixture,
} from "./fixtures/capability-model.js";
test("query contracts retain native reads and explicitly acknowledged package reads", () => {
const named = capabilityResourceSources.named.replace("value name", "queryable value name");
const native = compileCapabilityFixture({ named });
assert.equal(native.ok, true, JSON.stringify(native.diagnostics));
const summary = capabilityResourceSources.summary.replace("value summary", "queryable rpc value summary");
const missing = compileCapabilityFixture({ summary });
assert.equal(missing.ok, false);
assert.ok(missing.diagnostics.some((issue) => issue.code === "query-provider-reason-required"));
const workspace = capabilityFixtureSource.replace(
"person to constructor Person;\n };",
'person to constructor Person;\n } query-reason "Summary needs package execution; bounded query callers acknowledge this cost";',
);
const allowed = compileCapabilityFixture({ named, summary, workspace });
assert.equal(allowed.ok, true, JSON.stringify(allowed.diagnostics));
const denied = compileCapabilityFixture({ summary: summary.replace("queryable rpc", "queryable"), workspace });
assert.equal(denied.ok, false);
assert.ok(denied.diagnostics.some((issue) => issue.code === "invalid-query-contract"));
});
test("queryable fields need one authoritative getter and supported values", () => {
const compile = (member: string) =>
compileCapabilityResourceSource(`interface Facts id "facts" revision "facts@1" { ${member} }`, {
source: { repository: "https://example.test/facts.git", commit: "a".repeat(40) },
});
assert.equal(compile('queryable value title id "title" : string { get id "title:get"; }').ok, true);
for (const member of [
'queryable value title id "title" : string { set id "title:set"; }',
'queryable value title id "title" : list<string> { get id "title:get"; }',
'queryable value title id "title" : string { get id "title:get"; get id "other:get"; }',
])
assert.equal(compile(member).ok, false, member);
});