Skip to content

Commit 142443f

Browse files
committed
feat: add table-level BlueprintTableIndex, BlueprintTableFullTextSearch, BlueprintTableUniqueConstraint types
- BlueprintTable now supports nested indexes[], full_text_searches[], unique_constraints[] - Table-level types omit table_name (inherited from parent table) - Top-level types still require table_name - Updated codegen to generate all three table-level type variants - Matches the three-tier blueprint definition system in construct_blueprint()
1 parent a5f0852 commit 142443f

2 files changed

Lines changed: 126 additions & 6 deletions

File tree

graphql/node-type-registry/src/blueprint-types.generated.ts

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -707,7 +707,7 @@ export interface BlueprintFtsSource {
707707
/** Language for text search. Defaults to "english". */
708708
lang?: string;
709709
}
710-
/** A full-text search configuration for a blueprint table. */
710+
/** A full-text search configuration for a blueprint table (top-level, requires table_name). */
711711
export interface BlueprintFullTextSearch {
712712
/** Table name this full-text search belongs to. */
713713
table_name: string;
@@ -718,7 +718,16 @@ export interface BlueprintFullTextSearch {
718718
/** Source fields that feed into this tsvector. */
719719
sources: BlueprintFtsSource[];
720720
}
721-
/** An index definition within a blueprint. */
721+
/** A full-text search configuration nested inside a table definition (table_name not required). */
722+
export interface BlueprintTableFullTextSearch {
723+
/** Name of the tsvector field on the table. */
724+
field: string;
725+
/** Source fields that feed into this tsvector. */
726+
sources: BlueprintFtsSource[];
727+
/** Optional schema name override. */
728+
schema_name?: string;
729+
}
730+
/** An index definition within a blueprint (top-level, requires table_name). */
722731
export interface BlueprintIndex {
723732
/** Table name this index belongs to. */
724733
table_name: string;
@@ -739,6 +748,25 @@ export interface BlueprintIndex {
739748
/** Additional index-specific options. */
740749
options?: Record<string, unknown>;
741750
}
751+
/** An index definition nested inside a table definition (table_name not required). */
752+
export interface BlueprintTableIndex {
753+
/** Single column name for the index. */
754+
column?: string;
755+
/** Array of column names for a multi-column index. */
756+
columns?: string[];
757+
/** Index access method (e.g., "BTREE", "GIN", "GIST", "HNSW", "BM25"). */
758+
access_method: string;
759+
/** Whether this is a unique index. */
760+
is_unique?: boolean;
761+
/** Optional custom name for the index. */
762+
name?: string;
763+
/** Operator classes for the index columns. */
764+
op_classes?: string[];
765+
/** Additional index-specific options. */
766+
options?: Record<string, unknown>;
767+
/** Optional schema name override. */
768+
schema_name?: string;
769+
}
742770
/**
743771
* ===========================================================================
744772
* Node types -- discriminated union for nodes[] entries
@@ -918,7 +946,7 @@ export type BlueprintRelation = {
918946
* ===========================================================================
919947
*/
920948
;
921-
/** A unique constraint definition within a blueprint. */
949+
/** A unique constraint definition within a blueprint (top-level, requires table_name). */
922950
export interface BlueprintUniqueConstraint {
923951
/** Table name this unique constraint belongs to. */
924952
table_name: string;
@@ -927,6 +955,13 @@ export interface BlueprintUniqueConstraint {
927955
/** Column names that form the unique constraint. */
928956
columns: string[];
929957
}
958+
/** A unique constraint nested inside a table definition (table_name not required). */
959+
export interface BlueprintTableUniqueConstraint {
960+
/** Column names that form the unique constraint. */
961+
columns: string[];
962+
/** Optional schema name override. */
963+
schema_name?: string;
964+
}
930965
/** A table definition within a blueprint. */
931966
export interface BlueprintTable {
932967
/** The PostgreSQL table name to create. */
@@ -945,6 +980,12 @@ export interface BlueprintTable {
945980
grants?: unknown[];
946981
/** Whether to enable RLS on this table. Defaults to true. */
947982
use_rls?: boolean;
983+
/** Table-level indexes (table_name inherited from parent). */
984+
indexes?: BlueprintTableIndex[];
985+
/** Table-level full-text search configurations (table_name inherited from parent). */
986+
full_text_searches?: BlueprintTableFullTextSearch[];
987+
/** Table-level unique constraints (table_name inherited from parent). */
988+
unique_constraints?: BlueprintTableUniqueConstraint[];
948989
}
949990
/** The complete blueprint definition -- the JSONB shape accepted by construct_blueprint(). */
950991
export interface BlueprintDefinition {

graphql/node-type-registry/src/codegen/generate-types.ts

Lines changed: 82 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,30 @@ function buildBlueprintFullTextSearch(): t.ExportNamedDeclaration {
402402
'Source fields that feed into this tsvector.'
403403
),
404404
]),
405-
'A full-text search configuration for a blueprint table.'
405+
'A full-text search configuration for a blueprint table (top-level, requires table_name).'
406+
);
407+
}
408+
409+
function buildBlueprintTableFullTextSearch(): t.ExportNamedDeclaration {
410+
return addJSDoc(
411+
exportInterface('BlueprintTableFullTextSearch', [
412+
addJSDoc(
413+
requiredProp('field', t.tsStringKeyword()),
414+
'Name of the tsvector field on the table.'
415+
),
416+
addJSDoc(
417+
requiredProp(
418+
'sources',
419+
t.tsArrayType(t.tsTypeReference(t.identifier('BlueprintFtsSource')))
420+
),
421+
'Source fields that feed into this tsvector.'
422+
),
423+
addJSDoc(
424+
optionalProp('schema_name', t.tsStringKeyword()),
425+
'Optional schema name override.'
426+
),
427+
]),
428+
'A full-text search configuration nested inside a table definition (table_name not required).'
406429
);
407430
}
408431

@@ -436,7 +459,23 @@ function buildBlueprintIndex(
436459
addJSDoc(optionalProp('op_classes', t.tsArrayType(t.tsStringKeyword())), 'Operator classes for the index columns.'),
437460
addJSDoc(optionalProp('options', recordType(t.tsStringKeyword(), t.tsUnknownKeyword())), 'Additional index-specific options.'),
438461
]),
439-
'An index definition within a blueprint.'
462+
'An index definition within a blueprint (top-level, requires table_name).'
463+
);
464+
}
465+
466+
function buildBlueprintTableIndex(): t.ExportNamedDeclaration {
467+
return addJSDoc(
468+
exportInterface('BlueprintTableIndex', [
469+
addJSDoc(optionalProp('column', t.tsStringKeyword()), 'Single column name for the index.'),
470+
addJSDoc(optionalProp('columns', t.tsArrayType(t.tsStringKeyword())), 'Array of column names for a multi-column index.'),
471+
addJSDoc(requiredProp('access_method', t.tsStringKeyword()), 'Index access method (e.g., "BTREE", "GIN", "GIST", "HNSW", "BM25").'),
472+
addJSDoc(optionalProp('is_unique', t.tsBooleanKeyword()), 'Whether this is a unique index.'),
473+
addJSDoc(optionalProp('name', t.tsStringKeyword()), 'Optional custom name for the index.'),
474+
addJSDoc(optionalProp('op_classes', t.tsArrayType(t.tsStringKeyword())), 'Operator classes for the index columns.'),
475+
addJSDoc(optionalProp('options', recordType(t.tsStringKeyword(), t.tsUnknownKeyword())), 'Additional index-specific options.'),
476+
addJSDoc(optionalProp('schema_name', t.tsStringKeyword()), 'Optional schema name override.'),
477+
]),
478+
'An index definition nested inside a table definition (table_name not required).'
440479
);
441480
}
442481

@@ -551,7 +590,23 @@ function buildBlueprintUniqueConstraint(): t.ExportNamedDeclaration {
551590
'Column names that form the unique constraint.'
552591
),
553592
]),
554-
'A unique constraint definition within a blueprint.'
593+
'A unique constraint definition within a blueprint (top-level, requires table_name).'
594+
);
595+
}
596+
597+
function buildBlueprintTableUniqueConstraint(): t.ExportNamedDeclaration {
598+
return addJSDoc(
599+
exportInterface('BlueprintTableUniqueConstraint', [
600+
addJSDoc(
601+
requiredProp('columns', t.tsArrayType(t.tsStringKeyword())),
602+
'Column names that form the unique constraint.'
603+
),
604+
addJSDoc(
605+
optionalProp('schema_name', t.tsStringKeyword()),
606+
'Optional schema name override.'
607+
),
608+
]),
609+
'A unique constraint nested inside a table definition (table_name not required).'
555610
);
556611
}
557612

@@ -599,6 +654,27 @@ function buildBlueprintTable(): t.ExportNamedDeclaration {
599654
optionalProp('use_rls', t.tsBooleanKeyword()),
600655
'Whether to enable RLS on this table. Defaults to true.'
601656
),
657+
addJSDoc(
658+
optionalProp(
659+
'indexes',
660+
t.tsArrayType(t.tsTypeReference(t.identifier('BlueprintTableIndex')))
661+
),
662+
'Table-level indexes (table_name inherited from parent).'
663+
),
664+
addJSDoc(
665+
optionalProp(
666+
'full_text_searches',
667+
t.tsArrayType(t.tsTypeReference(t.identifier('BlueprintTableFullTextSearch')))
668+
),
669+
'Table-level full-text search configurations (table_name inherited from parent).'
670+
),
671+
addJSDoc(
672+
optionalProp(
673+
'unique_constraints',
674+
t.tsArrayType(t.tsTypeReference(t.identifier('BlueprintTableUniqueConstraint')))
675+
),
676+
'Table-level unique constraints (table_name inherited from parent).'
677+
),
602678
]),
603679
'A table definition within a blueprint.'
604680
);
@@ -712,8 +788,11 @@ function buildProgram(meta?: MetaTableInfo[]): string {
712788
statements.push(buildBlueprintPolicy(authzNodes, meta));
713789
statements.push(buildBlueprintFtsSource());
714790
statements.push(buildBlueprintFullTextSearch());
791+
statements.push(buildBlueprintTableFullTextSearch());
715792
statements.push(buildBlueprintIndex(meta));
793+
statements.push(buildBlueprintTableIndex());
716794
statements.push(buildBlueprintUniqueConstraint());
795+
statements.push(buildBlueprintTableUniqueConstraint());
717796

718797
// -- Node types discriminated union --
719798
statements.push(

0 commit comments

Comments
 (0)