Files
quixos-protocol/src/bindings/client.ts
T

30 lines
2.1 KiB
TypeScript

import type {InterfaceRevision, ValueType} from "../capability-model/types.js";
/** Host clients have no package receiver, but must use the same checked
* interface signatures and argument framing as generated package ports. */
export const generateClientContracts = (interfaces: InterfaceRevision[], messages: Record<string, string>) => {
const type = (value: ValueType): string => {
switch (value.kind) {
case "builtin": return value.name === "unit" ? "undefined" : "string";
case "scalar": return ({bool: "boolean", string: "string", bytes: "Uint8Array", int32: "number", uint32: "number", double: "number", int64: "bigint", uint64: "bigint"})[value.name];
case "object-ref": return `{readonly $quixosRef: string}`;
case "optional": return `(${type(value.value)} | null)`;
case "list": return `Array<${type(value.value)}>`;
case "record": return `{${Object.entries(value.fields).map(([name, field]) => `${JSON.stringify(name)}${field.kind === "optional" ? "?" : ""}: ${type(field)}`).join("; ")}}`;
case "message": {
const binding = messages[value.descriptorId];
if (!binding) throw new Error(`Missing host message type ${value.descriptorId}`);
return binding;
}
}
};
const operations = interfaces.flatMap(iface => iface.members.flatMap(member => member.operations
.filter(operation => operation.mode === "call").map(operation => ({...operation, interfaceRevisionId: iface.revisionId}))));
return `// Generated from checked QX interfaces. Regenerate with scripts/generate-platform-contracts.mjs.\n` +
`export type PlatformInputs = {\n${operations.map(operation => ` ${JSON.stringify(operation.id)}: ${type(operation.inputType)};`).join("\n")}\n};\n` +
`export const platformOperations = ${JSON.stringify(Object.fromEntries(operations.map(operation => [operation.id, {
interfaceRevisionId: operation.interfaceRevisionId,
input: operation.inputType.kind === "builtin" && operation.inputType.name === "unit" ? "unit" : ["record", "message"].includes(operation.inputType.kind) ? "fields" : "value",
}])), null, 2)} as const;\n`;
};