Add checked workspace-interface query roots
Implement scoped interface extents across QX, generated bindings, SDK, Orch, Camino and browser queries. Preserve native projection, aggregation, pagination and watch invalidation without synthetic persisted objects. Validate exact query grants and scope freshness on execution and replay. Add local PostgreSQL, transport, browser and code-generation coverage. C1 implementation slice only: full-text indexes and Studio search adoption (C2/C3) remain tracked in the implementation handoff. No publication or deployment.
This commit is contained in:
+6
-4
@@ -28,6 +28,7 @@ import type {
|
||||
} from "../capability-model/types.js";
|
||||
import { QueryCompileError, type QueryDeclaration } from "./types.js";
|
||||
import { relationalSchema, objectRow } from "./relational-schema.js";
|
||||
import { queryRootSchema, workspaceQueryRootId } from "./root.js";
|
||||
|
||||
// Validate losslessly; callers carry decimal strings across JSON transports.
|
||||
function integerParser(name: string, min: bigint, max: bigint, value: unknown): string {
|
||||
@@ -78,7 +79,8 @@ export function querySchema(
|
||||
interfaces: readonly InterfaceRevision[],
|
||||
document?: DocumentNode,
|
||||
) {
|
||||
const contracts = new Map(interfaces.map((entry) => [entry.revisionId, entry]));
|
||||
const root = queryRootSchema(declaration.root, interfaces);
|
||||
const contracts = new Map(root.interfaces.map((entry) => [entry.revisionId, entry]));
|
||||
const objects = new Map<InterfaceRevisionId, GraphQLObjectType>();
|
||||
const orders = new Map<InterfaceRevisionId, GraphQLInputObjectType>();
|
||||
const byName = new Map<string, InterfaceRevision>();
|
||||
@@ -150,7 +152,7 @@ export function querySchema(
|
||||
{ contracts, target, name, scalar, comparison, scalarTypes, direction, cursor: cursorScalar, pageInfo },
|
||||
document,
|
||||
);
|
||||
relational.discover(declaration.root);
|
||||
relational.discover(root.interface);
|
||||
const filter = (id: InterfaceRevisionId) => relational.where(objectRow(id));
|
||||
const order = (id: InterfaceRevisionId) => {
|
||||
let result = orders.get(id);
|
||||
@@ -177,7 +179,7 @@ export function querySchema(
|
||||
const metadata = new GraphQLObjectType({
|
||||
name: `QxMetadata_${name(id)}`,
|
||||
fields: {
|
||||
ref: { type: new GraphQLNonNull(relational.refs(id)) },
|
||||
...(id === workspaceQueryRootId ? {} : { ref: { type: new GraphQLNonNull(relational.refs(id)) } }),
|
||||
...(helpers ? { relations: { type: new GraphQLNonNull(helpers) } } : {}),
|
||||
},
|
||||
});
|
||||
@@ -247,7 +249,7 @@ export function querySchema(
|
||||
directives: [...specifiedDirectives, new GraphQLDirective({ name: "live", locations: [DirectiveLocation.FIELD] })],
|
||||
query: new GraphQLObjectType({
|
||||
name: "QxQuery",
|
||||
fields: { root: { type: new GraphQLNonNull(object(declaration.root)) } },
|
||||
fields: { root: { type: new GraphQLNonNull(object(root.interface)) } },
|
||||
}),
|
||||
});
|
||||
return { schema, byName, target, contracts, relational, scalarTypes };
|
||||
|
||||
Reference in New Issue
Block a user