89 lines
3.9 KiB
TypeScript
89 lines
3.9 KiB
TypeScript
import { create, toJson } from "@bufbuild/protobuf";
|
|
import {
|
|
InstalledQuerySchema,
|
|
QueryArgumentSchema,
|
|
QuerySelectionSchema,
|
|
QueryReadBindingSchema,
|
|
Cardinality,
|
|
type QueryArgument as WireArgument,
|
|
} from "../gen/camino/schema_pb.js";
|
|
import type { LinkedQuery } from "./link.js";
|
|
import type { QueryArgument, QuerySelection } from "./types.js";
|
|
import type { WorkspaceRevision } from "../capability-model/types.js";
|
|
|
|
const argument = (entry: QueryArgument): WireArgument => {
|
|
switch (entry.kind) {
|
|
case "variable":
|
|
return create(QueryArgumentSchema, { value: { case: "variable", value: entry.name } });
|
|
case "literal":
|
|
return create(QueryArgumentSchema, { value: { case: "literalJson", value: JSON.stringify(entry.value) } });
|
|
case "list":
|
|
return create(QueryArgumentSchema, { value: { case: "list", value: { values: entry.values.map(argument) } } });
|
|
case "object":
|
|
return create(QueryArgumentSchema, {
|
|
value: {
|
|
case: "object",
|
|
value: { fields: Object.fromEntries(Object.entries(entry.fields).map(([k, v]) => [k, argument(v)])) },
|
|
},
|
|
});
|
|
}
|
|
};
|
|
const selection = (entry: QuerySelection): import("../gen/camino/schema_pb.js").QuerySelection =>
|
|
create(QuerySelectionSchema, {
|
|
...entry,
|
|
conditions: entry.conditions.map((condition) => ({ include: condition.include, value: argument(condition.value) })),
|
|
arguments: Object.fromEntries(Object.entries(entry.arguments).map(([k, v]) => [k, argument(v)])),
|
|
selection: entry.selection.map(selection),
|
|
});
|
|
|
|
export const queryRuntimePlan = (linked: LinkedQuery, workspace: WorkspaceRevision) =>
|
|
toJson(
|
|
InstalledQuerySchema,
|
|
create(InstalledQuerySchema, {
|
|
id: linked.id,
|
|
definitionDigest: linked.checked.definitionDigest,
|
|
bindingDigest: linked.bindingDigest,
|
|
rootInterfaceRevisionId: linked.checked.declaration.root,
|
|
selection: linked.checked.selection.map(selection),
|
|
budgets: linked.checked.declaration.budgets,
|
|
variablesTypeJson: JSON.stringify(linked.checked.variables),
|
|
outputTypeJson: JSON.stringify(linked.checked.output),
|
|
variableDefaults: Object.fromEntries(
|
|
Object.entries(linked.checked.variableDefaults).map(([k, v]) => [k, argument(v)]),
|
|
),
|
|
watch: linked.checked.declaration.watch,
|
|
pollingIntervalMs: linked.checked.declaration.polling?.intervalMs,
|
|
rpcPredicateOrOrder: linked.checked.effects.some(
|
|
(effect) => effect.execution === "rpc-permitted" && effect.uses.some((use) => use !== "select"),
|
|
),
|
|
bindings: linked.fields.map((field) => {
|
|
const member = workspace.interfaceImports
|
|
.find((entry) => entry.revisionId === field.interfaceRevisionId)!
|
|
.members.find((entry) => entry.id === field.memberId)!;
|
|
return create(QueryReadBindingSchema, {
|
|
atomId: field.atomId,
|
|
interfaceRevisionId: field.interfaceRevisionId,
|
|
memberId: field.memberId,
|
|
getterOperationId: field.getter,
|
|
fieldName: member.displayName,
|
|
valueTypeJson: member.kind === "value" ? JSON.stringify(member.valueType) : "",
|
|
cardinality:
|
|
member.kind === "relationship"
|
|
? {
|
|
"optional-one": Cardinality.OPTIONAL_ONE,
|
|
"exactly-one": Cardinality.EXACTLY_ONE,
|
|
many: Cardinality.MANY,
|
|
"many-unique": Cardinality.MANY_UNIQUE,
|
|
}[member.cardinality]
|
|
: undefined,
|
|
slotId: field.binding.kind === "state" ? field.binding.slotId : "",
|
|
edgeTypeId: field.binding.kind === "edge" ? field.binding.edgeTypeId : "",
|
|
projectionId: field.binding.kind === "edge" ? field.binding.projectionId : "",
|
|
rpc: field.binding.kind === "package",
|
|
watchStartOperationId: field.watch?.start,
|
|
watchStopOperationId: field.watch?.stop,
|
|
});
|
|
}),
|
|
}),
|
|
);
|