2026-09-08 14:27:24 -07:00
import assert from "node:assert/strict" ;
import test from "node:test" ;
import { compileCapabilityResourceSource } from "../src/capability-language/parser.js" ;
import { generateTypeScriptBindings , type BindingSchema } from "../src/bindings/index.js" ;
const source = { repository : "https://example.test/p.git" , commit : "1" . repeat ( 40 ) };
const schemaFor = ( body : string ) : BindingSchema => {
2026-09-15 15:23:24 -07:00
const compiled = compileCapabilityResourceSource (
`external atom Thing id "thing"; package Demo id "demo" revision "demo@1" { ${ body } }` ,
{ source },
);
2026-09-08 14:27:24 -07:00
assert . equal ( compiled . ok , true , JSON . stringify ( compiled . diagnostics ));
if ( ! compiled . ok || compiled . resource . kind !== "package" ) throw new Error ( "expected package" );
return { format : "quixos-bindings" , version : 1 , interfaces : [], packages : [ compiled . resource . revision ] };
};
2026-09-18 18:54:09 -07:00
test ( "reflection ports generate explicit selector-restricted package bindings" , () => {
const schema = schemaFor (
'function inspect id "inspect" : unit -> unit requires { reflection meta id "meta" [active, atoms, interfaces, conformances, queries, indexes]; };' ,
);
const generated = generateTypeScriptBindings ( schema , "demo@1" );
assert . match (
generated ,
/QxReflectionPort<"active" \| "atoms" \| "interfaces" \| "conformances" \| "queries" \| "indexes">/ ,
);
assert . match ( generated , /"kind": "reflection"/ );
});
2026-09-08 14:27:24 -07:00
test ( "generator uses exact IDs, restricted ports, nominal references, and lossless scalar types" , () => {
2026-09-15 15:23:24 -07:00
const schema = schemaFor (
'operation run id "run-id" : list<int64> -> optional<atom-ref<Thing>> mode call receiver atom Thing requires { state payload id "payload-id" : bytes [read]; };' ,
);
2026-09-08 14:27:24 -07:00
const generated = generateTypeScriptBindings ( schema , "demo@1" );
assert . match ( generated , /Array<bigint>/ );
assert . match ( generated , /Promise<Uint8Array>/ );
assert . match ( generated , /QxObjectRef<"atom:thing">/ );
assert . doesNotMatch ( generated , /"set":/ );
assert . match ( generated , /"run-id": bindQxHandler/ );
assert . equal ( generateTypeScriptBindings ( schema , "demo@1" ), generated );
});
test ( "missing external types and constructor signatures fail generation" , () => {
const schema = schemaFor ( 'function run id "run" : unit -> message "example.Payload";' );
assert . throws (() => generateTypeScriptBindings ( schema , "demo@1" ), /Missing TypeScript message binding/ );
2026-09-15 15:23:24 -07:00
assert . match (
generateTypeScriptBindings ( schema , "demo@1" , {
messages : { "example.Payload" : { module : "./payload.js" , export : "payload" } },
}),
/BindingValue<typeof message0>/ ,
);
const constructor = schemaFor (
'function run id "run" : unit -> unit requires { constructor thing id "ctor" : Thing; };' ,
);
2026-09-08 14:27:24 -07:00
assert . throws (() => generateTypeScriptBindings ( constructor , "demo@1" ), /explicit input contract/ );
2026-09-15 15:23:24 -07:00
const typed = schemaFor (
'function run id "run" : unit -> unit requires { constructor thing id "ctor" : Thing input string; };' ,
);
2026-09-08 14:27:24 -07:00
assert . match ( generateTypeScriptBindings ( typed , "demo@1" ), /construct.*input: string/ );
});