node-type-registry 0.17.0 → 0.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -39,12 +39,12 @@ export interface DataSoftDeleteParams {
39
39
  /** Dynamically creates PostgreSQL triggers that enqueue jobs via app_jobs.add_job() when table rows are inserted, updated, or deleted. Supports configurable payload strategies (full row, row ID, selected fields, or custom mapping), conditional firing via WHEN clauses, watched field changes, and extended job options (queue, priority, delay, max attempts). */
40
40
  export interface DataJobTriggerParams {
41
41
  task_identifier: string;
42
- payload_strategy?: "row" | "row_id" | "fields" | "custom";
42
+ payload_strategy?: 'row' | 'row_id' | 'fields' | 'custom';
43
43
  payload_fields?: string[];
44
44
  payload_custom?: {
45
45
  [key: string]: unknown;
46
46
  };
47
- events?: ("INSERT" | "UPDATE" | "DELETE")[];
47
+ events?: ('INSERT' | 'UPDATE' | 'DELETE')[];
48
48
  include_old?: boolean;
49
49
  include_meta?: boolean;
50
50
  condition_field?: string;
@@ -85,7 +85,7 @@ export interface DataSlugParams {
85
85
  /** Transforms field values using inflection operations (snake_case, camelCase, slugify, plural, singular, etc). Attaches BEFORE INSERT and BEFORE UPDATE triggers. References fields by name in data jsonb. */
86
86
  export interface DataInflectionParams {
87
87
  field_name: string;
88
- ops: ("plural" | "singular" | "camel" | "pascal" | "dashed" | "slugify" | "underscore" | "lower" | "upper")[];
88
+ ops: ('plural' | 'singular' | 'camel' | 'pascal' | 'dashed' | 'slugify' | 'underscore' | 'lower' | 'upper')[];
89
89
  }
90
90
  /** Restricts which user can modify specific columns in shared objects. Creates an AFTER UPDATE trigger that throws OWNED_PROPS when a non-owner tries to change protected fields. References fields by name in data jsonb. */
91
91
  export interface DataOwnedFieldsParams {
@@ -111,7 +111,7 @@ export interface DataImmutableFieldsParams {
111
111
  export interface DataCompositeFieldParams {
112
112
  target?: string;
113
113
  source_fields: string[];
114
- format?: "labeled" | "plain";
114
+ format?: 'labeled' | 'plain';
115
115
  }
116
116
  /** Creates a user profiles table with standard profile fields (profile_picture, bio, first_name, last_name, tags, desired). Uses AuthzDirectOwner for edit access and AuthzAllowAll for select. */
117
117
  export type TableUserProfilesParams = {};
@@ -123,8 +123,8 @@ export type TableUserSettingsParams = {};
123
123
  export interface SearchVectorParams {
124
124
  field_name?: string;
125
125
  dimensions?: number;
126
- index_method?: "hnsw" | "ivfflat";
127
- metric?: "cosine" | "l2" | "ip";
126
+ index_method?: 'hnsw' | 'ivfflat';
127
+ metric?: 'cosine' | 'l2' | 'ip';
128
128
  index_options?: {
129
129
  [key: string]: unknown;
130
130
  };
@@ -132,12 +132,12 @@ export interface SearchVectorParams {
132
132
  source_fields?: string[];
133
133
  enqueue_job?: boolean;
134
134
  job_task_name?: string;
135
- stale_strategy?: "column" | "null" | "hash";
135
+ stale_strategy?: 'column' | 'null' | 'hash';
136
136
  chunks?: {
137
137
  content_field_name?: string;
138
138
  chunk_size?: number;
139
139
  chunk_overlap?: number;
140
- chunk_strategy?: "fixed" | "sentence" | "paragraph" | "semantic";
140
+ chunk_strategy?: 'fixed' | 'sentence' | 'paragraph' | 'semantic';
141
141
  metadata_fields?: {
142
142
  [key: string]: unknown;
143
143
  };
@@ -150,7 +150,7 @@ export interface SearchFullTextParams {
150
150
  field_name?: string;
151
151
  source_fields: {
152
152
  field: string;
153
- weight?: "A" | "B" | "C" | "D";
153
+ weight?: 'A' | 'B' | 'C' | 'D';
154
154
  lang?: string;
155
155
  }[];
156
156
  search_score_weight?: number;
@@ -169,7 +169,7 @@ export interface SearchUnifiedParams {
169
169
  field_name?: string;
170
170
  source_fields?: {
171
171
  field: string;
172
- weight?: "A" | "B" | "C" | "D";
172
+ weight?: 'A' | 'B' | 'C' | 'D';
173
173
  lang?: string;
174
174
  }[];
175
175
  search_score_weight?: number;
@@ -184,15 +184,15 @@ export interface SearchUnifiedParams {
184
184
  embedding?: {
185
185
  field_name?: string;
186
186
  dimensions?: number;
187
- index_method?: "hnsw" | "ivfflat";
188
- metric?: "cosine" | "l2" | "ip";
187
+ index_method?: 'hnsw' | 'ivfflat';
188
+ metric?: 'cosine' | 'l2' | 'ip';
189
189
  source_fields?: string[];
190
190
  search_score_weight?: number;
191
191
  chunks?: {
192
192
  content_field_name?: string;
193
193
  chunk_size?: number;
194
194
  chunk_overlap?: number;
195
- chunk_strategy?: "fixed" | "sentence" | "paragraph" | "semantic";
195
+ chunk_strategy?: 'fixed' | 'sentence' | 'paragraph' | 'semantic';
196
196
  metadata_fields?: {
197
197
  [key: string]: unknown;
198
198
  };
@@ -205,7 +205,7 @@ export interface SearchUnifiedParams {
205
205
  weights?: {
206
206
  [key: string]: unknown;
207
207
  };
208
- normalization?: "linear" | "sigmoid";
208
+ normalization?: 'linear' | 'sigmoid';
209
209
  boost_recent?: boolean;
210
210
  boost_recency_field?: string;
211
211
  boost_recency_decay?: number;
@@ -214,11 +214,11 @@ export interface SearchUnifiedParams {
214
214
  /** Adds a PostGIS geometry or geography column with a spatial index (GiST or SP-GiST). Supports configurable geometry types (Point, Polygon, etc.), SRID, and dimensionality. The graphile-postgis plugin auto-detects geometry/geography columns by codec type for spatial filtering (ST_Contains, ST_DWithin, bbox operators). */
215
215
  export interface SearchSpatialParams {
216
216
  field_name?: string;
217
- geometry_type?: "Point" | "LineString" | "Polygon" | "MultiPoint" | "MultiLineString" | "MultiPolygon" | "GeometryCollection" | "Geometry";
217
+ geometry_type?: 'Point' | 'LineString' | 'Polygon' | 'MultiPoint' | 'MultiLineString' | 'MultiPolygon' | 'GeometryCollection' | 'Geometry';
218
218
  srid?: number;
219
219
  dimension?: 2 | 3 | 4;
220
220
  use_geography?: boolean;
221
- index_method?: "gist" | "spgist";
221
+ index_method?: 'gist' | 'spgist';
222
222
  }
223
223
  /** Creates a derived/materialized geometry field on the parent table that automatically aggregates geometries from a source (child) table via triggers. When child rows are inserted/updated/deleted, the parent aggregate field is recalculated using the specified PostGIS aggregation function (ST_Union, ST_Collect, ST_ConvexHull, ST_ConcaveHull). Useful for materializing spatial boundaries from collections of points or polygons. */
224
224
  export interface SearchSpatialAggregateParams {
@@ -226,12 +226,12 @@ export interface SearchSpatialAggregateParams {
226
226
  source_table_id: string;
227
227
  source_geom_field?: string;
228
228
  source_fk_field: string;
229
- aggregate_function?: "union" | "collect" | "convex_hull" | "concave_hull";
230
- geometry_type?: "Point" | "LineString" | "Polygon" | "MultiPoint" | "MultiLineString" | "MultiPolygon" | "GeometryCollection" | "Geometry";
229
+ aggregate_function?: 'union' | 'collect' | 'convex_hull' | 'concave_hull';
230
+ geometry_type?: 'Point' | 'LineString' | 'Polygon' | 'MultiPoint' | 'MultiLineString' | 'MultiPolygon' | 'GeometryCollection' | 'Geometry';
231
231
  srid?: number;
232
232
  dimension?: 2 | 3 | 4;
233
233
  use_geography?: boolean;
234
- index_method?: "gist" | "spgist";
234
+ index_method?: 'gist' | 'spgist';
235
235
  }
236
236
  /** Creates GIN trigram indexes (gin_trgm_ops) on specified text/citext fields for fuzzy LIKE/ILIKE/similarity search. Adds @trgmSearch smart tag for PostGraphile integration. Fields must already exist on the table. */
237
237
  export interface SearchTrgmParams {
@@ -281,7 +281,7 @@ export interface AuthzRelatedEntityMembershipParams {
281
281
  }
282
282
  /** Organizational hierarchy visibility using closure table. Managers can see subordinate data or subordinates can see manager data. */
283
283
  export interface AuthzOrgHierarchyParams {
284
- direction: "up" | "down";
284
+ direction: 'up' | 'down';
285
285
  entity_field?: string;
286
286
  anchor_field: string;
287
287
  max_depth?: number;
@@ -318,7 +318,7 @@ export type AuthzDenyAllParams = {};
318
318
  /** Composite authorization policy that combines multiple authorization nodes using boolean logic (AND/OR). The data field contains a JSONB AST with nested authorization nodes. */
319
319
  export interface AuthzCompositeParams {
320
320
  BoolExpr?: {
321
- boolop?: "AND_EXPR" | "OR_EXPR" | "NOT_EXPR";
321
+ boolop?: 'AND_EXPR' | 'OR_EXPR' | 'NOT_EXPR';
322
322
  args?: {
323
323
  [key: string]: unknown;
324
324
  }[];
@@ -360,7 +360,7 @@ export interface RelationBelongsToParams {
360
360
  source_table_id: string;
361
361
  target_table_id: string;
362
362
  field_name?: string;
363
- delete_action: "c" | "r" | "n" | "d" | "a";
363
+ delete_action: 'c' | 'r' | 'n' | 'd' | 'a';
364
364
  is_required?: boolean;
365
365
  }
366
366
  /** Creates a foreign key field with a unique constraint on the source table referencing the target table. Enforces 1:1 cardinality. Auto-derives the FK field name from the target table name using inflection. delete_action is required and must be explicitly provided by the caller. */
@@ -368,7 +368,7 @@ export interface RelationHasOneParams {
368
368
  source_table_id: string;
369
369
  target_table_id: string;
370
370
  field_name?: string;
371
- delete_action: "c" | "r" | "n" | "d" | "a";
371
+ delete_action: 'c' | 'r' | 'n' | 'd' | 'a';
372
372
  is_required?: boolean;
373
373
  }
374
374
  /** Creates a foreign key field on the target table referencing the source table. Inverse of RelationBelongsTo — same FK, different perspective. "projects has many tasks" creates tasks.project_id. Auto-derives the FK field name from the source table name using inflection. delete_action is required and must be explicitly provided by the caller. */
@@ -376,7 +376,7 @@ export interface RelationHasManyParams {
376
376
  source_table_id: string;
377
377
  target_table_id: string;
378
378
  field_name?: string;
379
- delete_action: "c" | "r" | "n" | "d" | "a";
379
+ delete_action: 'c' | 'r' | 'n' | 'd' | 'a';
380
380
  is_required?: boolean;
381
381
  }
382
382
  /** Creates a junction table between source and target tables with auto-derived naming and FK fields. The trigger creates a bare table (no implicit DataId), adds FK fields to both tables, optionally creates a composite PK (use_composite_key), then forwards all security config to secure_table_provision as-is. The trigger never injects values the caller did not provide. Junction table FKs always CASCADE on delete. */
@@ -391,15 +391,20 @@ export interface RelationManyToManyParams {
391
391
  nodes?: {
392
392
  [key: string]: unknown;
393
393
  }[];
394
- grant_roles?: string[];
395
- grant_privileges?: string[][];
396
- policy_type?: string;
397
- policy_privileges?: string[];
398
- policy_role?: string;
399
- policy_permissive?: boolean;
400
- policy_data?: {
401
- [key: string]: unknown;
402
- };
394
+ grants?: {
395
+ roles: string[];
396
+ privileges: string[][];
397
+ }[];
398
+ policies?: {
399
+ $type: string;
400
+ data?: {
401
+ [key: string]: unknown;
402
+ };
403
+ privileges?: string[];
404
+ policy_role?: string;
405
+ permissive?: boolean;
406
+ policy_name?: string;
407
+ }[];
403
408
  }
404
409
  /** Declares a spatial predicate between two existing geometry/geography columns. Inserts a metaschema_public.spatial_relation row; the sync_spatial_relation_tags trigger then projects a @spatialRelation smart tag onto the owner column so graphile-postgis' PostgisSpatialRelationsPlugin can expose it as a cross-table filter in GraphQL. Metadata-only: both source_field and target_field must already exist on their tables. Idempotent on (source_table_id, name). One direction per tag — author two RelationSpatial entries if symmetry is desired. */
405
410
  export interface RelationSpatialParams {
@@ -408,7 +413,7 @@ export interface RelationSpatialParams {
408
413
  target_table_id: string;
409
414
  target_field_id: string;
410
415
  name: string;
411
- operator: "st_contains" | "st_within" | "st_intersects" | "st_covers" | "st_coveredby" | "st_overlaps" | "st_touches" | "st_dwithin";
416
+ operator: 'st_contains' | 'st_within' | 'st_intersects' | 'st_covers' | 'st_coveredby' | 'st_overlaps' | 'st_touches' | 'st_dwithin';
412
417
  param_name?: string;
413
418
  }
414
419
  /** Simple column selection from a single source table. Projects all or specific fields. */
@@ -433,7 +438,7 @@ export interface ViewJoinedTablesParams {
433
438
  primary_columns?: string[];
434
439
  joins: {
435
440
  table_id: string;
436
- join_type?: "INNER" | "LEFT" | "RIGHT" | "FULL";
441
+ join_type?: 'INNER' | 'LEFT' | 'RIGHT' | 'FULL';
437
442
  primary_field: string;
438
443
  join_field: string;
439
444
  columns?: string[];
@@ -445,7 +450,7 @@ export interface ViewAggregatedParams {
445
450
  source_table_id: string;
446
451
  group_by_fields: string[];
447
452
  aggregates: {
448
- function: "COUNT" | "SUM" | "AVG" | "MIN" | "MAX";
453
+ function: 'COUNT' | 'SUM' | 'AVG' | 'MIN' | 'MAX';
449
454
  field?: string;
450
455
  alias: string;
451
456
  }[];
@@ -472,7 +477,7 @@ export interface BlueprintField {
472
477
  /** An RLS policy entry for a blueprint table. Uses $type to match the blueprint JSON convention. */
473
478
  export interface BlueprintPolicy {
474
479
  /** Authz* policy type name (e.g., "AuthzDirectOwner", "AuthzAllowAll"). */
475
- $type: "AuthzDirectOwner" | "AuthzDirectOwnerAny" | "AuthzMembership" | "AuthzEntityMembership" | "AuthzRelatedEntityMembership" | "AuthzOrgHierarchy" | "AuthzTemporal" | "AuthzPublishable" | "AuthzMemberList" | "AuthzRelatedMemberList" | "AuthzAllowAll" | "AuthzDenyAll" | "AuthzComposite" | "AuthzNotReadOnly" | "AuthzPeerOwnership" | "AuthzRelatedPeerOwnership";
480
+ $type: 'AuthzDirectOwner' | 'AuthzDirectOwnerAny' | 'AuthzMembership' | 'AuthzEntityMembership' | 'AuthzRelatedEntityMembership' | 'AuthzOrgHierarchy' | 'AuthzTemporal' | 'AuthzPublishable' | 'AuthzMemberList' | 'AuthzRelatedMemberList' | 'AuthzAllowAll' | 'AuthzDenyAll' | 'AuthzComposite' | 'AuthzNotReadOnly' | 'AuthzPeerOwnership' | 'AuthzRelatedPeerOwnership';
476
481
  /** Privileges this policy applies to (e.g., ["select"], ["insert", "update", "delete"]). */
477
482
  privileges?: string[];
478
483
  /** Whether this policy is permissive (true) or restrictive (false). Defaults to true. */
@@ -569,6 +574,49 @@ export interface BlueprintTableUniqueConstraint {
569
574
  /** Optional schema name override. */
570
575
  schema_name?: string;
571
576
  }
577
+ /** A storage-specific RLS policy object for apply_storage_security(). Each entry defines an Authz* policy with explicit privileges, scoped to specific storage tables. */
578
+ export interface BlueprintStoragePolicy {
579
+ /** Authz* policy generator type (e.g., "AuthzPublishable", "AuthzDirectOwner", "AuthzEntityMembership"). */
580
+ $type: string;
581
+ /** Privilege array (e.g., ["select", "insert", "update", "delete"]). Intersected with each storage table's supported operations. */
582
+ privileges: string[];
583
+ /** Policy data config. Auto-derived from $type when omitted (e.g., AuthzPublishable defaults to {"is_published_field": "is_public", "require_published_at": false}). */
584
+ data?: Record<string, unknown>;
585
+ /** Which storage tables to apply this policy to. Defaults to all three when omitted. Uses logical names (not prefixed). */
586
+ tables?: ('buckets' | 'files' | 'upload_requests')[];
587
+ /** Custom RLS policy name suffix. Auto-derived from $type when omitted (pub/own/mem). */
588
+ policy_name?: string;
589
+ }
590
+ /** A bucket seed entry for storage_config.buckets[]. Creates an initial bucket row in the {prefix}_buckets table during entity type provisioning. Only used for app-level storage (not entity-scoped). */
591
+ export interface BlueprintBucketSeed {
592
+ /** Bucket key name (e.g., "avatars", "documents"). Becomes the key column value. */
593
+ name: string;
594
+ /** Human-readable description of this bucket. */
595
+ description?: string;
596
+ /** Whether the bucket is publicly readable. Defaults to false. */
597
+ is_public?: boolean;
598
+ /** MIME type allowlist (e.g., ["image/png", "image/jpeg"]). NULL means all types allowed. */
599
+ allowed_mime_types?: string[];
600
+ /** Maximum file size in bytes for this bucket. NULL means no limit. */
601
+ max_file_size?: number;
602
+ /** CORS allowed origins for this bucket. */
603
+ allowed_origins?: string[];
604
+ }
605
+ /** Storage configuration for an entity type. Controls RLS policies on storage tables, seeds initial buckets, and overrides module-level settings (expiry times, file size limits, CORS). */
606
+ export interface BlueprintStorageConfig {
607
+ /** Custom RLS policies for storage tables. When provided, replaces the default policy set (AuthzPublishable + membership + AuthzDirectOwner). Each entry is a policy object with $type, privileges, and optional data/tables/policy_name. */
608
+ policies?: BlueprintStoragePolicy[];
609
+ /** Initial bucket seed entries. Each creates a row in {prefix}_buckets during provisioning. Only used for app-level storage (not entity-scoped). */
610
+ buckets?: BlueprintBucketSeed[];
611
+ /** Override for presigned upload URL expiry time in seconds. */
612
+ upload_url_expiry_seconds?: number;
613
+ /** Override for presigned download URL expiry time in seconds. */
614
+ download_url_expiry_seconds?: number;
615
+ /** Default maximum file size in bytes for the storage module. */
616
+ default_max_file_size?: number;
617
+ /** CORS allowed origins for the storage module. */
618
+ allowed_origins?: string[];
619
+ }
572
620
  /** Override object for the entity table created by a BlueprintMembershipType. Shape mirrors BlueprintTable / secure_table_provision vocabulary. When supplied, policies[] replaces the default entity-table policies entirely. */
573
621
  export interface BlueprintEntityTableProvision {
574
622
  /** Whether to enable RLS on the entity table. Forwarded to secure_table_provision. Defaults to true. */
@@ -577,10 +625,11 @@ export interface BlueprintEntityTableProvision {
577
625
  nodes?: BlueprintNode[];
578
626
  /** Custom fields (columns) to add to the entity table. Forwarded to secure_table_provision as-is. */
579
627
  fields?: BlueprintField[];
580
- /** Privilege grants for the entity table as [verb, columns] tuples (e.g. [["select","*"],["insert","*"]]). Forwarded to secure_table_provision as-is. */
581
- grant_privileges?: unknown[];
582
- /** Database roles to grant privileges to. Forwarded to secure_table_provision as-is. Defaults to ["authenticated"]. */
583
- grant_roles?: string[];
628
+ /** Unified grant objects for the entity table. Each entry is { roles: string[], privileges: unknown[] } where privileges are [verb, columns] tuples. Forwarded to secure_table_provision as-is. Defaults to []. */
629
+ grants?: {
630
+ roles: string[];
631
+ privileges: unknown[];
632
+ }[];
584
633
  /** RLS policies for the entity table. When present, these policies fully replace the five default entity-table policies (is_visible becomes a no-op). */
585
634
  policies?: BlueprintPolicy[];
586
635
  }
@@ -604,179 +653,183 @@ export interface BlueprintMembershipType {
604
653
  has_profiles?: boolean;
605
654
  /** Whether to provision a levels module for this entity type. Defaults to false. */
606
655
  has_levels?: boolean;
656
+ /** Whether to provision a storage module (buckets, files, upload_requests tables) for this entity type. Defaults to false. */
657
+ has_storage?: boolean;
607
658
  /** Escape hatch: when true AND table_provision is NULL, zero policies are provisioned on the entity table. Defaults to false. */
608
659
  skip_entity_policies?: boolean;
609
660
  /** Override for the entity table. Shape mirrors BlueprintTable / secure_table_provision vocabulary. When supplied, its policies[] replaces the five default entity-table policies; is_visible becomes a no-op. When NULL (default), the five default policies are applied (gated by is_visible). */
610
661
  table_provision?: BlueprintEntityTableProvision;
662
+ /** Storage configuration. Only used when has_storage is true. Controls RLS policies on storage tables, seeds initial buckets, and overrides module-level settings (expiry times, file size limits, CORS). */
663
+ storage?: BlueprintStorageConfig;
611
664
  }
612
665
  /** String shorthand -- just the node type name. */
613
- export type BlueprintNodeShorthand = "AuthzDirectOwner" | "AuthzDirectOwnerAny" | "AuthzMembership" | "AuthzEntityMembership" | "AuthzRelatedEntityMembership" | "AuthzOrgHierarchy" | "AuthzTemporal" | "AuthzPublishable" | "AuthzMemberList" | "AuthzRelatedMemberList" | "AuthzAllowAll" | "AuthzDenyAll" | "AuthzComposite" | "AuthzNotReadOnly" | "AuthzPeerOwnership" | "AuthzRelatedPeerOwnership" | "DataId" | "DataDirectOwner" | "DataEntityMembership" | "DataOwnershipInEntity" | "DataTimestamps" | "DataPeoplestamps" | "DataPublishable" | "DataSoftDelete" | "SearchVector" | "SearchFullText" | "SearchBm25" | "SearchUnified" | "SearchSpatial" | "SearchSpatialAggregate" | "DataJobTrigger" | "DataTags" | "DataStatusField" | "DataJsonb" | "SearchTrgm" | "DataSlug" | "DataInflection" | "DataOwnedFields" | "DataInheritFromParent" | "DataForceCurrentUser" | "DataImmutableFields" | "DataCompositeField" | "TableUserProfiles" | "TableOrganizationSettings" | "TableUserSettings";
666
+ export type BlueprintNodeShorthand = 'AuthzDirectOwner' | 'AuthzDirectOwnerAny' | 'AuthzMembership' | 'AuthzEntityMembership' | 'AuthzRelatedEntityMembership' | 'AuthzOrgHierarchy' | 'AuthzTemporal' | 'AuthzPublishable' | 'AuthzMemberList' | 'AuthzRelatedMemberList' | 'AuthzAllowAll' | 'AuthzDenyAll' | 'AuthzComposite' | 'AuthzNotReadOnly' | 'AuthzPeerOwnership' | 'AuthzRelatedPeerOwnership' | 'DataId' | 'DataDirectOwner' | 'DataEntityMembership' | 'DataOwnershipInEntity' | 'DataTimestamps' | 'DataPeoplestamps' | 'DataPublishable' | 'DataSoftDelete' | 'SearchVector' | 'SearchFullText' | 'SearchBm25' | 'SearchUnified' | 'SearchSpatial' | 'SearchSpatialAggregate' | 'DataJobTrigger' | 'DataTags' | 'DataStatusField' | 'DataJsonb' | 'SearchTrgm' | 'DataSlug' | 'DataInflection' | 'DataOwnedFields' | 'DataInheritFromParent' | 'DataForceCurrentUser' | 'DataImmutableFields' | 'DataCompositeField' | 'TableUserProfiles' | 'TableOrganizationSettings' | 'TableUserSettings';
614
667
  /** Object form -- { $type, data } with typed parameters. */
615
668
  export type BlueprintNodeObject = {
616
- $type: "AuthzDirectOwner";
669
+ $type: 'AuthzDirectOwner';
617
670
  data: AuthzDirectOwnerParams;
618
671
  } | {
619
- $type: "AuthzDirectOwnerAny";
672
+ $type: 'AuthzDirectOwnerAny';
620
673
  data: AuthzDirectOwnerAnyParams;
621
674
  } | {
622
- $type: "AuthzMembership";
675
+ $type: 'AuthzMembership';
623
676
  data: AuthzMembershipParams;
624
677
  } | {
625
- $type: "AuthzEntityMembership";
678
+ $type: 'AuthzEntityMembership';
626
679
  data: AuthzEntityMembershipParams;
627
680
  } | {
628
- $type: "AuthzRelatedEntityMembership";
681
+ $type: 'AuthzRelatedEntityMembership';
629
682
  data: AuthzRelatedEntityMembershipParams;
630
683
  } | {
631
- $type: "AuthzOrgHierarchy";
684
+ $type: 'AuthzOrgHierarchy';
632
685
  data: AuthzOrgHierarchyParams;
633
686
  } | {
634
- $type: "AuthzTemporal";
687
+ $type: 'AuthzTemporal';
635
688
  data: AuthzTemporalParams;
636
689
  } | {
637
- $type: "AuthzPublishable";
690
+ $type: 'AuthzPublishable';
638
691
  data: AuthzPublishableParams;
639
692
  } | {
640
- $type: "AuthzMemberList";
693
+ $type: 'AuthzMemberList';
641
694
  data: AuthzMemberListParams;
642
695
  } | {
643
- $type: "AuthzRelatedMemberList";
696
+ $type: 'AuthzRelatedMemberList';
644
697
  data: AuthzRelatedMemberListParams;
645
698
  } | {
646
- $type: "AuthzAllowAll";
699
+ $type: 'AuthzAllowAll';
647
700
  data?: Record<string, never>;
648
701
  } | {
649
- $type: "AuthzDenyAll";
702
+ $type: 'AuthzDenyAll';
650
703
  data?: Record<string, never>;
651
704
  } | {
652
- $type: "AuthzComposite";
705
+ $type: 'AuthzComposite';
653
706
  data: AuthzCompositeParams;
654
707
  } | {
655
- $type: "AuthzNotReadOnly";
708
+ $type: 'AuthzNotReadOnly';
656
709
  data: AuthzNotReadOnlyParams;
657
710
  } | {
658
- $type: "AuthzPeerOwnership";
711
+ $type: 'AuthzPeerOwnership';
659
712
  data: AuthzPeerOwnershipParams;
660
713
  } | {
661
- $type: "AuthzRelatedPeerOwnership";
714
+ $type: 'AuthzRelatedPeerOwnership';
662
715
  data: AuthzRelatedPeerOwnershipParams;
663
716
  } | {
664
- $type: "DataId";
717
+ $type: 'DataId';
665
718
  data: DataIdParams;
666
719
  } | {
667
- $type: "DataDirectOwner";
720
+ $type: 'DataDirectOwner';
668
721
  data: DataDirectOwnerParams;
669
722
  } | {
670
- $type: "DataEntityMembership";
723
+ $type: 'DataEntityMembership';
671
724
  data: DataEntityMembershipParams;
672
725
  } | {
673
- $type: "DataOwnershipInEntity";
726
+ $type: 'DataOwnershipInEntity';
674
727
  data: DataOwnershipInEntityParams;
675
728
  } | {
676
- $type: "DataTimestamps";
729
+ $type: 'DataTimestamps';
677
730
  data: DataTimestampsParams;
678
731
  } | {
679
- $type: "DataPeoplestamps";
732
+ $type: 'DataPeoplestamps';
680
733
  data: DataPeoplestampsParams;
681
734
  } | {
682
- $type: "DataPublishable";
735
+ $type: 'DataPublishable';
683
736
  data: DataPublishableParams;
684
737
  } | {
685
- $type: "DataSoftDelete";
738
+ $type: 'DataSoftDelete';
686
739
  data: DataSoftDeleteParams;
687
740
  } | {
688
- $type: "SearchVector";
741
+ $type: 'SearchVector';
689
742
  data: SearchVectorParams;
690
743
  } | {
691
- $type: "SearchFullText";
744
+ $type: 'SearchFullText';
692
745
  data: SearchFullTextParams;
693
746
  } | {
694
- $type: "SearchBm25";
747
+ $type: 'SearchBm25';
695
748
  data: SearchBm25Params;
696
749
  } | {
697
- $type: "SearchUnified";
750
+ $type: 'SearchUnified';
698
751
  data: SearchUnifiedParams;
699
752
  } | {
700
- $type: "SearchSpatial";
753
+ $type: 'SearchSpatial';
701
754
  data: SearchSpatialParams;
702
755
  } | {
703
- $type: "SearchSpatialAggregate";
756
+ $type: 'SearchSpatialAggregate';
704
757
  data: SearchSpatialAggregateParams;
705
758
  } | {
706
- $type: "DataJobTrigger";
759
+ $type: 'DataJobTrigger';
707
760
  data: DataJobTriggerParams;
708
761
  } | {
709
- $type: "DataTags";
762
+ $type: 'DataTags';
710
763
  data: DataTagsParams;
711
764
  } | {
712
- $type: "DataStatusField";
765
+ $type: 'DataStatusField';
713
766
  data: DataStatusFieldParams;
714
767
  } | {
715
- $type: "DataJsonb";
768
+ $type: 'DataJsonb';
716
769
  data: DataJsonbParams;
717
770
  } | {
718
- $type: "SearchTrgm";
771
+ $type: 'SearchTrgm';
719
772
  data: SearchTrgmParams;
720
773
  } | {
721
- $type: "DataSlug";
774
+ $type: 'DataSlug';
722
775
  data: DataSlugParams;
723
776
  } | {
724
- $type: "DataInflection";
777
+ $type: 'DataInflection';
725
778
  data: DataInflectionParams;
726
779
  } | {
727
- $type: "DataOwnedFields";
780
+ $type: 'DataOwnedFields';
728
781
  data: DataOwnedFieldsParams;
729
782
  } | {
730
- $type: "DataInheritFromParent";
783
+ $type: 'DataInheritFromParent';
731
784
  data: DataInheritFromParentParams;
732
785
  } | {
733
- $type: "DataForceCurrentUser";
786
+ $type: 'DataForceCurrentUser';
734
787
  data: DataForceCurrentUserParams;
735
788
  } | {
736
- $type: "DataImmutableFields";
789
+ $type: 'DataImmutableFields';
737
790
  data: DataImmutableFieldsParams;
738
791
  } | {
739
- $type: "DataCompositeField";
792
+ $type: 'DataCompositeField';
740
793
  data: DataCompositeFieldParams;
741
794
  } | {
742
- $type: "TableUserProfiles";
795
+ $type: 'TableUserProfiles';
743
796
  data?: Record<string, never>;
744
797
  } | {
745
- $type: "TableOrganizationSettings";
798
+ $type: 'TableOrganizationSettings';
746
799
  data?: Record<string, never>;
747
800
  } | {
748
- $type: "TableUserSettings";
801
+ $type: 'TableUserSettings';
749
802
  data?: Record<string, never>;
750
803
  };
751
804
  /** A node entry in a blueprint table. Either a string shorthand or a typed object. */
752
805
  export type BlueprintNode = BlueprintNodeShorthand | BlueprintNodeObject;
753
806
  /** A relation entry in a blueprint definition. */
754
807
  export type BlueprintRelation = {
755
- $type: "RelationBelongsTo";
808
+ $type: 'RelationBelongsTo';
756
809
  source_table: string;
757
810
  target_table: string;
758
811
  source_schema_name?: string;
759
812
  target_schema_name?: string;
760
813
  } & Partial<RelationBelongsToParams> | {
761
- $type: "RelationHasOne";
814
+ $type: 'RelationHasOne';
762
815
  source_table: string;
763
816
  target_table: string;
764
817
  source_schema_name?: string;
765
818
  target_schema_name?: string;
766
819
  } & Partial<RelationHasOneParams> | {
767
- $type: "RelationHasMany";
820
+ $type: 'RelationHasMany';
768
821
  source_table: string;
769
822
  target_table: string;
770
823
  source_schema_name?: string;
771
824
  target_schema_name?: string;
772
825
  } & Partial<RelationHasManyParams> | {
773
- $type: "RelationManyToMany";
826
+ $type: 'RelationManyToMany';
774
827
  source_table: string;
775
828
  target_table: string;
776
829
  source_schema_name?: string;
777
830
  target_schema_name?: string;
778
831
  } & Partial<RelationManyToManyParams> | {
779
- $type: "RelationSpatial";
832
+ $type: 'RelationSpatial';
780
833
  source_table: string;
781
834
  target_table: string;
782
835
  source_schema_name?: string;
@@ -796,10 +849,11 @@ export interface BlueprintTable {
796
849
  fields?: BlueprintField[];
797
850
  /** RLS policies for this table. */
798
851
  policies?: BlueprintPolicy[];
799
- /** Database roles to grant privileges to. Defaults to ["authenticated"]. */
800
- grant_roles?: string[];
801
- /** Privilege grants as [verb, column] tuples or objects. Defaults to empty (no grants — callers must explicitly specify). */
802
- grants?: unknown[];
852
+ /** Unified grant objects. Each entry is { roles: string[], privileges: unknown[] } where privileges are [verb, columns] tuples (e.g. [["select","*"]]). Enables per-role targeting. Defaults to []. */
853
+ grants?: {
854
+ roles: string[];
855
+ privileges: unknown[];
856
+ }[];
803
857
  /** Whether to enable RLS on this table. Defaults to true. */
804
858
  use_rls?: boolean;
805
859
  /** Table-level indexes (table_name inherited from parent). */
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  // GENERATED FILE — DO NOT EDIT
3
+ /* eslint-disable @typescript-eslint/no-empty-object-type */
3
4
  //
4
5
  // Regenerate with:
5
6
  // cd graphql/node-type-registry && pnpm generate:types