diff --git a/graphql/node-type-registry/package.json b/graphql/node-type-registry/package.json index d30ecff27..9dfcdce69 100644 --- a/graphql/node-type-registry/package.json +++ b/graphql/node-type-registry/package.json @@ -1,6 +1,6 @@ { "name": "node-type-registry", - "version": "0.14.0", + "version": "0.15.0", "description": "Node type definitions for the Constructive blueprint system. Single source of truth for all Authz*, Data*, Relation*, and View* node types.", "author": "Constructive ", "main": "index.js", diff --git a/graphql/node-type-registry/src/blueprint-types.generated.ts b/graphql/node-type-registry/src/blueprint-types.generated.ts index 394e566da..9c76ad327 100644 --- a/graphql/node-type-registry/src/blueprint-types.generated.ts +++ b/graphql/node-type-registry/src/blueprint-types.generated.ts @@ -1054,6 +1054,8 @@ export type BlueprintRelation = { target_table: string; source_schema_name?: string; target_schema_name?: string; + /** Name of the geometry/geography column on source_table that carries the @spatialRelation smart tag. */source_field: string; + /** Name of the geometry/geography column on target_table that the predicate is evaluated against. */target_field: string; } & Partial; /** * =========================================================================== diff --git a/graphql/node-type-registry/src/codegen/generate-types.ts b/graphql/node-type-registry/src/codegen/generate-types.ts index b3827ac78..b07e40cf4 100644 --- a/graphql/node-type-registry/src/codegen/generate-types.ts +++ b/graphql/node-type-registry/src/codegen/generate-types.ts @@ -537,13 +537,34 @@ function buildRelationTypes( relationNodes: NodeTypeDefinition[] ): t.ExportNamedDeclaration[] { const relationMembers: t.TSType[] = relationNodes.map((nt) => { - const baseType = t.tsTypeLiteral([ + const baseMembers: t.TSTypeElement[] = [ requiredProp('$type', strLit(nt.name)), requiredProp('source_table', t.tsStringKeyword()), requiredProp('target_table', t.tsStringKeyword()), optionalProp('source_schema_name', t.tsStringKeyword()), optionalProp('target_schema_name', t.tsStringKeyword()), - ]); + ]; + + // RelationSpatial is the only relation type that references *existing* + // columns rather than creating FK/junction fields. Its blueprint JSON + // therefore needs source_field / target_field (column *names* resolved + // server-side by resolve_blueprint_field), which have no ID-space + // equivalent in parameter_schema. Surface them here so blueprint authors + // get autocomplete without a cast. + if (nt.name === 'RelationSpatial') { + baseMembers.push( + addJSDoc( + requiredProp('source_field', t.tsStringKeyword()), + 'Name of the geometry/geography column on source_table that carries the @spatialRelation smart tag.' + ), + addJSDoc( + requiredProp('target_field', t.tsStringKeyword()), + 'Name of the geometry/geography column on target_table that the predicate is evaluated against.' + ) + ); + } + + const baseType = t.tsTypeLiteral(baseMembers); return t.tsIntersectionType([ baseType,