node-type-registry 0.40.0 → 0.42.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.
Files changed (39) hide show
  1. package/authz/authz-member-owner.d.ts +2 -0
  2. package/authz/authz-member-owner.js +51 -0
  3. package/authz/index.d.ts +1 -0
  4. package/authz/index.js +3 -1
  5. package/blueprint-types.generated.d.ts +289 -63
  6. package/blueprint-types.generated.js +16 -4
  7. package/codegen/generate-types.js +119 -6
  8. package/data/data-member-owner.d.ts +2 -0
  9. package/data/data-member-owner.js +53 -0
  10. package/data/index.d.ts +1 -0
  11. package/data/index.js +3 -1
  12. package/esm/authz/authz-member-owner.d.ts +2 -0
  13. package/esm/authz/authz-member-owner.js +48 -0
  14. package/esm/authz/index.d.ts +1 -0
  15. package/esm/authz/index.js +1 -0
  16. package/esm/blueprint-types.generated.d.ts +289 -63
  17. package/esm/blueprint-types.generated.js +16 -4
  18. package/esm/codegen/generate-types.js +119 -6
  19. package/esm/data/data-member-owner.d.ts +2 -0
  20. package/esm/data/data-member-owner.js +50 -0
  21. package/esm/data/index.d.ts +1 -0
  22. package/esm/data/index.js +1 -0
  23. package/esm/job/trigger.js +28 -0
  24. package/esm/module-presets/full.d.ts +6 -6
  25. package/esm/module-presets/full.js +71 -16
  26. package/esm/process/chunks.js +16 -0
  27. package/esm/process/extraction.js +16 -0
  28. package/esm/process/file-embedding.js +16 -0
  29. package/esm/process/image-embedding.js +16 -0
  30. package/esm/process/image-versions.js +16 -0
  31. package/job/trigger.js +28 -0
  32. package/module-presets/full.d.ts +6 -6
  33. package/module-presets/full.js +71 -16
  34. package/package.json +4 -4
  35. package/process/chunks.js +16 -0
  36. package/process/extraction.js +16 -0
  37. package/process/file-embedding.js +16 -0
  38. package/process/image-embedding.js +16 -0
  39. package/process/image-versions.js +16 -0
@@ -0,0 +1,2 @@
1
+ import type { NodeTypeDefinition } from '../types';
2
+ export declare const AuthzMemberOwner: NodeTypeDefinition;
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AuthzMemberOwner = void 0;
4
+ exports.AuthzMemberOwner = {
5
+ name: 'AuthzMemberOwner',
6
+ slug: 'authz_member_owner',
7
+ category: 'authz',
8
+ display_name: 'Member Owner',
9
+ description: 'Compound policy: the row must be owned by the current user (owner_field = current_user_id) AND the current user must be a member of the entity referenced by entity_field. Combines direct ownership with entity membership — the actor can only access rows they own within entities they belong to.',
10
+ parameter_schema: {
11
+ type: 'object',
12
+ properties: {
13
+ owner_field: {
14
+ type: 'string',
15
+ format: 'column-ref',
16
+ description: 'Column name containing the owner user ID (e.g., owner_id)',
17
+ default: 'owner_id'
18
+ },
19
+ entity_field: {
20
+ type: 'string',
21
+ format: 'column-ref',
22
+ description: 'Column name referencing the entity (e.g., entity_id)',
23
+ default: 'entity_id'
24
+ },
25
+ sel_field: {
26
+ type: 'string',
27
+ description: 'SPRT column to select for the entity match',
28
+ default: 'entity_id'
29
+ },
30
+ membership_type: {
31
+ type: ['integer', 'string'],
32
+ description: 'Scope: 1=app, 2=org, 3+=dynamic entity types (or string name resolved via membership_types_module)'
33
+ },
34
+ entity_type: {
35
+ type: 'string',
36
+ description: "Entity type prefix (e.g. 'channel', 'department'). Resolved to membership_type integer via memberships_module lookup."
37
+ },
38
+ permission: {
39
+ type: 'string',
40
+ description: 'Single permission name to check (resolved to bitstring mask)'
41
+ },
42
+ permissions: {
43
+ type: 'array',
44
+ items: { type: 'string' },
45
+ description: 'Multiple permission names to check (ORed together into mask)'
46
+ }
47
+ },
48
+ required: ['owner_field', 'entity_field']
49
+ },
50
+ tags: ['ownership', 'membership', 'authz']
51
+ };
package/authz/index.d.ts CHANGED
@@ -9,6 +9,7 @@ export { AuthzEntityMembership } from './authz-entity-membership';
9
9
  export { AuthzMemberList } from './authz-member-list';
10
10
  export { AuthzNotReadOnly } from './authz-not-read-only';
11
11
  export { AuthzOrgHierarchy } from './authz-org-hierarchy';
12
+ export { AuthzMemberOwner } from './authz-member-owner';
12
13
  export { AuthzPeerOwnership } from './authz-peer-ownership';
13
14
  export { AuthzPublishable } from './authz-publishable';
14
15
  export { AuthzRelatedEntityMembership } from './authz-related-entity-membership';
package/authz/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.AuthzTemporal = exports.AuthzRelatedPeerOwnership = exports.AuthzRelatedMemberList = exports.AuthzRelatedEntityMembership = exports.AuthzPublishable = exports.AuthzPeerOwnership = exports.AuthzOrgHierarchy = exports.AuthzNotReadOnly = exports.AuthzMemberList = exports.AuthzEntityMembership = exports.AuthzDirectOwnerAny = exports.AuthzDirectOwner = exports.AuthzFilePath = exports.AuthzDenyAll = exports.AuthzComposite = exports.AuthzAppMembership = exports.AuthzAllowAll = void 0;
3
+ exports.AuthzTemporal = exports.AuthzRelatedPeerOwnership = exports.AuthzRelatedMemberList = exports.AuthzRelatedEntityMembership = exports.AuthzPublishable = exports.AuthzPeerOwnership = exports.AuthzMemberOwner = exports.AuthzOrgHierarchy = exports.AuthzNotReadOnly = exports.AuthzMemberList = exports.AuthzEntityMembership = exports.AuthzDirectOwnerAny = exports.AuthzDirectOwner = exports.AuthzFilePath = exports.AuthzDenyAll = exports.AuthzComposite = exports.AuthzAppMembership = exports.AuthzAllowAll = void 0;
4
4
  var authz_allow_all_1 = require("./authz-allow-all");
5
5
  Object.defineProperty(exports, "AuthzAllowAll", { enumerable: true, get: function () { return authz_allow_all_1.AuthzAllowAll; } });
6
6
  var authz_app_membership_1 = require("./authz-app-membership");
@@ -23,6 +23,8 @@ var authz_not_read_only_1 = require("./authz-not-read-only");
23
23
  Object.defineProperty(exports, "AuthzNotReadOnly", { enumerable: true, get: function () { return authz_not_read_only_1.AuthzNotReadOnly; } });
24
24
  var authz_org_hierarchy_1 = require("./authz-org-hierarchy");
25
25
  Object.defineProperty(exports, "AuthzOrgHierarchy", { enumerable: true, get: function () { return authz_org_hierarchy_1.AuthzOrgHierarchy; } });
26
+ var authz_member_owner_1 = require("./authz-member-owner");
27
+ Object.defineProperty(exports, "AuthzMemberOwner", { enumerable: true, get: function () { return authz_member_owner_1.AuthzMemberOwner; } });
26
28
  var authz_peer_ownership_1 = require("./authz-peer-ownership");
27
29
  Object.defineProperty(exports, "AuthzPeerOwnership", { enumerable: true, get: function () { return authz_peer_ownership_1.AuthzPeerOwnership; } });
28
30
  var authz_publishable_1 = require("./authz-publishable");
@@ -20,13 +20,6 @@ export interface TriggerCondition {
20
20
  /** Negated condition. */
21
21
  NOT?: TriggerCondition;
22
22
  }
23
- /** Declaratively attaches billing usage-recording triggers to a table. On INSERT the named meter is incremented via record_usage; on DELETE it is decremented (reversal). On UPDATE, if the entity_field changes, the old entity is decremented and the new entity is incremented. Requires a provisioned billing_module for the target database. */
24
- export interface BillingMeterParams {
25
- meter_slug: string;
26
- entity_field?: string;
27
- quantity?: number;
28
- events?: ('INSERT' | 'DELETE' | 'UPDATE')[];
29
- }
30
23
  /** Adds a CHECK constraint that validates a column value is greater than a threshold (single-column: column > value) or that one column is greater than another (cross-column: columns[0] > columns[1]). Compiled via AST helpers. */
31
24
  export interface CheckGreaterThanParams {
32
25
  column?: string;
@@ -106,6 +99,15 @@ export interface DataJsonbParams {
106
99
  is_required?: boolean;
107
100
  create_index?: boolean;
108
101
  }
102
+ /** Adds owner_id and entity_id columns with a compound AuthzMemberOwner policy. The actor must own the row (owner_id = current_user_id()) AND be a member of the entity (entity_id in SPRT). Use for private data within an entity scope — e.g., personal chat threads that belong to the company but only the author can see. */
103
+ export interface DataMemberOwnerParams {
104
+ owner_field_name?: string;
105
+ entity_field_name?: string;
106
+ include_id?: boolean;
107
+ include_user_fk?: boolean;
108
+ create_index?: boolean;
109
+ membership_type?: number;
110
+ }
109
111
  /** 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. */
110
112
  export interface DataOwnedFieldsParams {
111
113
  role_key_field_name: string;
@@ -129,8 +131,8 @@ export interface DataPeoplestampsParams {
129
131
  }
130
132
  /** Adds publish state columns (is_published, published_at) for content visibility. Enables AuthzPublishable and AuthzTemporal authorization. */
131
133
  export interface DataPublishableParams {
132
- is_published_field?: string;
133
- published_at_field?: string;
134
+ is_published_field_name?: string;
135
+ published_at_field_name?: string;
134
136
  include_id?: boolean;
135
137
  }
136
138
  /** Creates per-table subscriber tables in subscriptions_public with RLS policies derived from source table SELECT policies. Attaches statement-level triggers to emit changes to subscribers. */
@@ -175,24 +177,82 @@ export type TableOrganizationSettingsParams = {};
175
177
  export type TableUserProfilesParams = {};
176
178
  /** Creates a user settings table for user-specific configuration. Uses AuthzDirectOwner for access control. */
177
179
  export type TableUserSettingsParams = {};
180
+ /** Creates triggers that record events for the referrer (inviter) when their invitees perform actions on a watched table. Resolves the referrer automatically via the invites module's claimed_invites table using the membership_type context. Supports the same compound condition system as EventTracker. Use with achievements to unlock levels and grant credits based on invitee activity. */
181
+ export interface EventReferralParams {
182
+ event_name: string;
183
+ events?: ('INSERT' | 'UPDATE' | 'DELETE')[];
184
+ actor_field?: string;
185
+ entity_field?: string;
186
+ max_depth?: number;
187
+ auto_register_type?: boolean;
188
+ condition_field?: string;
189
+ condition_value?: string;
190
+ conditions?: TriggerCondition | TriggerCondition[];
191
+ watch_fields?: string[];
192
+ }
193
+ /** Creates triggers that record events via the events module when table rows change. Supports the same compound condition system as JobTrigger (condition_field, watch_fields, or full AND/OR/NOT conditions). Events are recorded to app_events and aggregated automatically. Use with achievements (blueprint-level) to unlock levels and grant credits based on event accumulation. */
194
+ export interface EventTrackerParams {
195
+ event_name: string;
196
+ events?: ('INSERT' | 'UPDATE' | 'DELETE')[];
197
+ count?: number;
198
+ toggle?: boolean;
199
+ actor_field?: string;
200
+ entity_field?: string;
201
+ auto_register_type?: boolean;
202
+ condition_field?: string;
203
+ condition_value?: string;
204
+ conditions?: TriggerCondition | TriggerCondition[];
205
+ watch_fields?: string[];
206
+ }
178
207
  /** Declaratively attaches aggregate limit-tracking triggers to a table. On INSERT the named limit is incremented per entity; on DELETE it is decremented. Uses org_limit_aggregates_inc/dec for per-entity (org-level) aggregate limits rather than per-user limits. Requires a provisioned limits_module for the target database. */
179
- export interface LimitAggregateParams {
208
+ export interface LimitEnforceAggregateParams {
180
209
  limit_name: string;
181
210
  entity_field?: string;
182
211
  events?: ('INSERT' | 'DELETE' | 'UPDATE')[];
183
212
  }
213
+ /** Declaratively attaches limit-tracking triggers to a table. On INSERT the named limit is incremented; on DELETE it is decremented. Requires a provisioned limits_module for the target scope. */
214
+ export interface LimitEnforceCounterParams {
215
+ limit_name: string;
216
+ scope?: 'app' | 'org';
217
+ actor_field?: string;
218
+ events?: ('INSERT' | 'DELETE' | 'UPDATE')[];
219
+ }
184
220
  /** Gates a table behind a feature flag backed by the cap tables. Attaches a BEFORE INSERT trigger that checks whether the named feature cap value is > 0. Features are modeled as caps with max=0 (disabled) or max=1 (enabled) in limit_caps / limit_caps_defaults tables. Resolution: COALESCE(per-entity cap, scope default, 0). */
185
- export interface LimitFeatureFlagParams {
221
+ export interface LimitEnforceFeatureParams {
186
222
  feature_name: string;
187
223
  scope?: 'app' | 'org';
188
224
  entity_field?: string;
189
225
  }
190
- /** Declaratively attaches limit-tracking triggers to a table. On INSERT the named limit is incremented; on DELETE it is decremented. Requires a provisioned limits_module for the target scope. */
191
- export interface LimitCounterParams {
226
+ /** Attaches a BEFORE trigger that calls check_rate_limit() to enforce sliding-window rate limits before allowing mutations. The function checks all three scopes (entity, actor-in-entity, actor) in a single call; which scopes are actually enforced is controlled by what rows exist in rate_window_limits (plan-based config). Requires a provisioned meter_rate_limits_module and billing_module for the target database. */
227
+ export interface LimitEnforceRateParams {
228
+ meter_slug: string;
229
+ entity_field?: string;
230
+ actor_field?: string;
231
+ events?: ('INSERT' | 'UPDATE')[];
232
+ }
233
+ /** Declaratively attaches billing usage-recording triggers to a table. On INSERT the named meter is incremented via record_usage; on DELETE it is decremented (reversal). On UPDATE, if the entity_field changes, the old entity is decremented and the new entity is incremented. Requires a provisioned billing_module for the target database. */
234
+ export interface LimitTrackUsageParams {
235
+ meter_slug: string;
236
+ entity_field?: string;
237
+ quantity?: number;
238
+ events?: ('INSERT' | 'DELETE' | 'UPDATE')[];
239
+ }
240
+ /** Attaches an AFTER INSERT trigger that checks if the entity's aggregate usage has crossed any warning threshold configured in the limit_warnings table. If a threshold is reached for the first time, enqueues a background job (e.g. email notification). Uses limit_warning_state for one-time dedup per warning/actor/entity triple. Requires a provisioned limits_module with limit_warnings and aggregate limits enabled. */
241
+ export interface LimitWarningAggregateParams {
242
+ limit_name: string;
243
+ entity_field?: string;
244
+ }
245
+ /** Attaches an AFTER INSERT trigger that checks if the actor's current usage has crossed any warning threshold configured in the limit_warnings table. If a threshold is reached for the first time, enqueues a background job (e.g. email notification). Uses limit_warning_state for one-time dedup per warning/actor pair. Requires a provisioned limits_module with limit_warnings enabled. */
246
+ export interface LimitWarningCounterParams {
192
247
  limit_name: string;
193
248
  scope?: 'app' | 'org';
194
249
  actor_field?: string;
195
- events?: ('INSERT' | 'DELETE' | 'UPDATE')[];
250
+ }
251
+ /** Attaches an AFTER INSERT trigger that checks if the actor's current request count in the active sliding window has crossed any warning threshold configured in the limit_warnings table. If a threshold is reached for the first time, enqueues a background job (e.g. email notification). Uses limit_warning_state for one-time dedup per warning/actor pair. Requires both a limits_module with limit_warnings enabled and a rate_limit_meters_module. */
252
+ export interface LimitWarningRateParams {
253
+ meter_slug: string;
254
+ entity_field?: string;
255
+ actor_field?: string;
196
256
  }
197
257
  /** Creates a BM25 index on an existing text column using pg_textsearch. Enables statistical relevance ranking with configurable k1 and b parameters. The BM25 index is auto-detected by graphile-search. */
198
258
  export interface SearchBm25Params {
@@ -262,6 +322,8 @@ export interface SearchUnifiedParams {
262
322
  index_method?: 'hnsw' | 'ivfflat';
263
323
  metric?: 'cosine' | 'l2' | 'ip';
264
324
  source_fields?: string[];
325
+ embedding_model?: string;
326
+ embedding_provider?: string;
265
327
  search_score_weight?: number;
266
328
  chunks?: {
267
329
  content_field_name?: string;
@@ -298,6 +360,8 @@ export interface SearchVectorParams {
298
360
  [key: string]: unknown;
299
361
  };
300
362
  source_fields?: string[];
363
+ embedding_model?: string;
364
+ embedding_provider?: string;
301
365
  enqueue_job?: boolean;
302
366
  job_task_name?: string;
303
367
  chunks?: {
@@ -327,6 +391,12 @@ export interface JobTriggerParams {
327
391
  condition_value?: string;
328
392
  conditions?: TriggerCondition | TriggerCondition[];
329
393
  watch_fields?: string[];
394
+ entity_field?: string;
395
+ entity_lookup?: {
396
+ obj_table: string;
397
+ obj_schema?: string;
398
+ obj_field: string;
399
+ };
330
400
  job_key?: string;
331
401
  queue_name?: string;
332
402
  priority?: number;
@@ -341,11 +411,43 @@ export interface ProcessChunksParams {
341
411
  chunk_strategy?: 'fixed' | 'sentence' | 'paragraph' | 'semantic';
342
412
  dimensions?: number;
343
413
  metric?: 'cosine' | 'l2' | 'ip';
414
+ embedding_model?: string;
415
+ embedding_provider?: string;
344
416
  chunks_table_name?: string;
345
417
  metadata_fields?: string[];
418
+ search_indexes?: ('fulltext' | 'bm25' | 'trigram')[];
419
+ entity_field?: string;
420
+ entity_lookup?: {
421
+ obj_table: string;
422
+ obj_schema?: string;
423
+ obj_field: string;
424
+ };
346
425
  enqueue_chunking_job?: boolean;
347
426
  chunking_task_name?: string;
348
427
  }
428
+ /** Creates extraction output fields and a job trigger for file text extraction. Fires when a file is uploaded (status = 'uploaded') or on INSERT. The external worker extracts text/metadata from the file (PDF, DOCX, HTML, etc.) and writes the result back to the configured output fields. Typically used upstream of ProcessFileEmbedding or ProcessChunks. */
429
+ export interface ProcessExtractionParams {
430
+ text_field?: string;
431
+ metadata_field?: string;
432
+ extraction_model?: string;
433
+ extraction_provider?: string;
434
+ mime_patterns?: string[];
435
+ task_identifier?: string;
436
+ events?: ('INSERT' | 'UPDATE')[];
437
+ payload_custom?: {
438
+ [key: string]: unknown;
439
+ };
440
+ trigger_conditions?: TriggerCondition | TriggerCondition[];
441
+ entity_field?: string;
442
+ entity_lookup?: {
443
+ obj_table: string;
444
+ obj_schema?: string;
445
+ obj_field: string;
446
+ };
447
+ queue_name?: string;
448
+ max_attempts?: number;
449
+ priority?: number;
450
+ }
349
451
  /** Generic, MIME-scoped embedding node for file tables. Supports two modes: direct (whole-file to single vector, e.g. CLIP for images) when extraction is omitted, or extract (file to text to chunks to per-chunk vectors) when extraction config is provided. Composes SearchVector + JobTrigger + ProcessChunks (enabled by default in extract mode) internally. Multiple instances can coexist on the same table with different MIME scopes, field names, and embedding strategies. */
350
452
  export interface ProcessFileEmbeddingParams {
351
453
  field_name?: string;
@@ -355,6 +457,8 @@ export interface ProcessFileEmbeddingParams {
355
457
  index_options?: {
356
458
  [key: string]: unknown;
357
459
  };
460
+ embedding_model?: string;
461
+ embedding_provider?: string;
358
462
  mime_patterns?: string[];
359
463
  task_identifier?: string;
360
464
  events?: ('INSERT' | 'UPDATE')[];
@@ -362,6 +466,12 @@ export interface ProcessFileEmbeddingParams {
362
466
  [key: string]: unknown;
363
467
  };
364
468
  trigger_conditions?: TriggerCondition | TriggerCondition[];
469
+ entity_field?: string;
470
+ entity_lookup?: {
471
+ obj_table: string;
472
+ obj_schema?: string;
473
+ obj_field: string;
474
+ };
365
475
  extraction?: {
366
476
  text_field?: string;
367
477
  metadata_field?: string;
@@ -373,6 +483,7 @@ export interface ProcessFileEmbeddingParams {
373
483
  chunk_overlap?: number;
374
484
  chunk_strategy?: 'fixed' | 'sentence' | 'paragraph' | 'semantic';
375
485
  metadata_fields?: string[];
486
+ search_indexes?: ('fulltext' | 'bm25' | 'trigram')[];
376
487
  enqueue_chunking_job?: boolean;
377
488
  chunking_task_name?: string;
378
489
  };
@@ -386,6 +497,8 @@ export interface ProcessImageEmbeddingParams {
386
497
  index_options?: {
387
498
  [key: string]: unknown;
388
499
  };
500
+ embedding_model?: string;
501
+ embedding_provider?: string;
389
502
  mime_patterns?: string[];
390
503
  task_identifier?: string;
391
504
  events?: ('INSERT' | 'UPDATE')[];
@@ -393,6 +506,12 @@ export interface ProcessImageEmbeddingParams {
393
506
  [key: string]: unknown;
394
507
  };
395
508
  trigger_conditions?: TriggerCondition | TriggerCondition[];
509
+ entity_field?: string;
510
+ entity_lookup?: {
511
+ obj_table: string;
512
+ obj_schema?: string;
513
+ obj_field: string;
514
+ };
396
515
  extraction?: {
397
516
  text_field?: string;
398
517
  metadata_field?: string;
@@ -409,21 +528,6 @@ export interface ProcessImageEmbeddingParams {
409
528
  chunking_task_name?: string;
410
529
  };
411
530
  }
412
- /** Creates extraction output fields and a job trigger for file text extraction. Fires when a file is uploaded (status = 'uploaded') or on INSERT. The external worker extracts text/metadata from the file (PDF, DOCX, HTML, etc.) and writes the result back to the configured output fields. Typically used upstream of ProcessFileEmbedding or ProcessChunks. */
413
- export interface ProcessExtractionParams {
414
- text_field?: string;
415
- metadata_field?: string;
416
- mime_patterns?: string[];
417
- task_identifier?: string;
418
- events?: ('INSERT' | 'UPDATE')[];
419
- payload_custom?: {
420
- [key: string]: unknown;
421
- };
422
- trigger_conditions?: TriggerCondition | TriggerCondition[];
423
- queue_name?: string;
424
- max_attempts?: number;
425
- priority?: number;
426
- }
427
531
  /** Creates a job trigger for image variant generation. Fires when an image file is uploaded (status = 'uploaded') or on INSERT. The external worker generates resized, cropped, or reformatted versions (thumbnails, previews, WebP conversions, etc.) and stores them as new file records linked to the source image. */
428
532
  export interface ProcessImageVersionsParams {
429
533
  versions: {
@@ -441,6 +545,12 @@ export interface ProcessImageVersionsParams {
441
545
  [key: string]: unknown;
442
546
  };
443
547
  trigger_conditions?: TriggerCondition | TriggerCondition[];
548
+ entity_field?: string;
549
+ entity_lookup?: {
550
+ obj_table: string;
551
+ obj_schema?: string;
552
+ obj_field: string;
553
+ };
444
554
  queue_name?: string;
445
555
  max_attempts?: number;
446
556
  priority?: number;
@@ -510,6 +620,16 @@ export interface AuthzOrgHierarchyParams {
510
620
  anchor_field: string;
511
621
  max_depth?: number;
512
622
  }
623
+ /** Compound policy: the row must be owned by the current user (owner_field = current_user_id) AND the current user must be a member of the entity referenced by entity_field. Combines direct ownership with entity membership — the actor can only access rows they own within entities they belong to. */
624
+ export interface AuthzMemberOwnerParams {
625
+ owner_field: string;
626
+ entity_field: string;
627
+ sel_field?: string;
628
+ membership_type?: number | string;
629
+ entity_type?: string;
630
+ permission?: string;
631
+ permissions?: string[];
632
+ }
513
633
  /** Peer visibility through shared entity membership. Authorizes access to user-owned rows when the owner and current user are both members of the same entity. Self-joins the SPRT table to find peers. */
514
634
  export interface AuthzPeerOwnershipParams {
515
635
  owner_field: string;
@@ -696,7 +816,7 @@ export interface BlueprintField {
696
816
  /** An RLS policy entry for a blueprint table. Uses $type to match the blueprint JSON convention. */
697
817
  export interface BlueprintPolicy {
698
818
  /** Authz* policy type name (e.g., "AuthzDirectOwner", "AuthzAllowAll"). */
699
- $type: 'AuthzAllowAll' | 'AuthzAppMembership' | 'AuthzComposite' | 'AuthzDenyAll' | 'AuthzFilePath' | 'AuthzDirectOwner' | 'AuthzDirectOwnerAny' | 'AuthzEntityMembership' | 'AuthzMemberList' | 'AuthzNotReadOnly' | 'AuthzOrgHierarchy' | 'AuthzPeerOwnership' | 'AuthzPublishable' | 'AuthzRelatedEntityMembership' | 'AuthzRelatedMemberList' | 'AuthzRelatedPeerOwnership' | 'AuthzTemporal';
819
+ $type: 'AuthzAllowAll' | 'AuthzAppMembership' | 'AuthzComposite' | 'AuthzDenyAll' | 'AuthzFilePath' | 'AuthzDirectOwner' | 'AuthzDirectOwnerAny' | 'AuthzEntityMembership' | 'AuthzMemberList' | 'AuthzNotReadOnly' | 'AuthzOrgHierarchy' | 'AuthzMemberOwner' | 'AuthzPeerOwnership' | 'AuthzPublishable' | 'AuthzRelatedEntityMembership' | 'AuthzRelatedMemberList' | 'AuthzRelatedPeerOwnership' | 'AuthzTemporal';
700
820
  /** Privileges this policy applies to (e.g., ["select"], ["insert", "update", "delete"]). */
701
821
  privileges?: string[];
702
822
  /** Whether this policy is permissive (true) or restrictive (false). Defaults to true. */
@@ -793,7 +913,7 @@ export interface BlueprintTableUniqueConstraint {
793
913
  /** Optional schema name override. */
794
914
  schema_name?: string;
795
915
  }
796
- /** 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). */
916
+ /** A bucket seed entry for storage.buckets[]. Creates an initial bucket row in the {prefix}_buckets table during entity type provisioning. Only used for app-level storage (not entity-scoped). */
797
917
  export interface BlueprintBucketSeed {
798
918
  /** Bucket key name (e.g., "avatars", "documents"). Becomes the key column value. */
799
919
  name: string;
@@ -869,6 +989,74 @@ export interface BlueprintAchievement {
869
989
  /** Entity prefix to scope this achievement to (e.g., "org", "app"). Used to resolve the correct events_module. Defaults to "app". */
870
990
  entity_prefix?: string;
871
991
  }
992
+ /** Namespace module configuration. When used at the top level of a blueprint, the scope field controls whether namespaces are app-level ("app", default) or org-level ("org"). When used inside entity_types[], scope is inherited from the entity type. Provisions a namespaces table with computed-name proxy, rename trigger, and entity-scoped RLS. */
993
+ export interface BlueprintNamespaceConfig {
994
+ /** Namespace scope. "app" (default) creates app-level namespaces (membership_type = NULL). "org" creates per-org namespaces. Only used at the top level of a blueprint definition — entity-scoped namespaces inherit scope from the entity type. */
995
+ scope?: 'app' | 'org';
996
+ /** Module discriminator for multi-module namespaces. Defaults to "default" (omitted from table names). Non-default keys appear as an infix: {prefix}_{key}_namespaces. */
997
+ key?: string;
998
+ /** RLS policy overrides for the namespaces table. NULL = apply defaults from apply_namespace_security(). */
999
+ policies?: BlueprintPolicy[];
1000
+ /** Per-table overrides for namespace tables. Each key targets a specific table (namespaces, namespace_events) and uses the same shape as table_provision: { nodes, fields, grants, use_rls, policies }. Fanned out to secure_table_provision. */
1001
+ provisions?: {
1002
+ namespaces?: BlueprintEntityTableProvision;
1003
+ namespace_events?: BlueprintEntityTableProvision;
1004
+ };
1005
+ }
1006
+ /** Function module configuration. When used at the top level of a blueprint, the scope field controls whether functions are app-level ("app", default) or org-level ("org"). When used inside entity_types[], scope is inherited from the entity type. Provisions function_definitions, function_invocations (partitioned, 12-month retention), and function_execution_logs tables. */
1007
+ export interface BlueprintFunctionConfig {
1008
+ /** Function scope. "app" (default) creates app-level functions (membership_type = NULL). "org" creates per-org functions. Only used at the top level of a blueprint definition — entity-scoped functions inherit scope from the entity type. */
1009
+ scope?: 'app' | 'org';
1010
+ /** Module discriminator for multi-module functions. Defaults to "default" (omitted from table names). Non-default keys appear as an infix: {prefix}_{key}_function_definitions. */
1011
+ key?: string;
1012
+ /** RLS policy overrides for the function tables. NULL = apply defaults from apply_function_security(). */
1013
+ policies?: BlueprintPolicy[];
1014
+ /** Per-table overrides for function tables. Each key targets a specific table (definitions, invocations, execution_logs) and uses the same shape as table_provision: { nodes, fields, grants, use_rls, policies }. Fanned out to secure_table_provision. */
1015
+ provisions?: {
1016
+ definitions?: BlueprintEntityTableProvision;
1017
+ invocations?: BlueprintEntityTableProvision;
1018
+ execution_logs?: BlueprintEntityTableProvision;
1019
+ };
1020
+ }
1021
+ /** Agent module configuration. When used at the top level of a blueprint, the scope field controls whether agents are app-level ("app", default) or org-level ("org"). When used inside entity_types[], scope is inherited from the entity type. Provisions thread, message, task, prompt tables (and optionally knowledge with vector embeddings). */
1022
+ export interface BlueprintAgentConfig {
1023
+ /** Agent scope. "app" (default) creates app-level agent tables (membership_type = NULL). "org" creates per-org agent tables. Only used at the top level of a blueprint definition — entity-scoped agents inherit scope from the entity type. */
1024
+ scope?: 'app' | 'org';
1025
+ /** Module discriminator for multi-module agents. Defaults to "default" (omitted from table names). Non-default keys appear as an infix: {prefix}_{key}_agent_thread. */
1026
+ key?: string;
1027
+ /** API name for the agent module. Used in GraphQL naming. Defaults to "agent". */
1028
+ api_name?: string;
1029
+ /** Whether to provision the agent_knowledge table with vector embeddings, tags, and trigger_phrases. Also inferred when a "knowledge" key is present. Defaults to false. */
1030
+ has_knowledge?: boolean;
1031
+ /** Knowledge configuration overrides. Set has_chunks to false to disable the chunking pipeline. Controls vector dimensions, chunking strategy, embedding model/provider, and text search indexes for the agent_knowledge table. Presence implies has_knowledge = true. */
1032
+ knowledge?: {
1033
+ has_chunks?: boolean;
1034
+ dimensions?: number;
1035
+ chunk_size?: number;
1036
+ chunk_overlap?: number;
1037
+ chunk_strategy?: 'fixed' | 'sentence' | 'paragraph' | 'semantic';
1038
+ embedding_model?: string;
1039
+ embedding_provider?: string;
1040
+ search_indexes?: ('fulltext' | 'bm25' | 'trigram')[];
1041
+ };
1042
+ /** RLS policy overrides for the agent tables. NULL = apply defaults from apply_agent_security(). */
1043
+ policies?: BlueprintPolicy[];
1044
+ /** Per-table overrides for agent tables. Each key targets a specific table (thread, message, task, prompt, knowledge) and uses the same shape as table_provision: { nodes, fields, grants, use_rls, policies }. Fanned out to secure_table_provision. */
1045
+ provisions?: {
1046
+ thread?: BlueprintEntityTableProvision;
1047
+ message?: BlueprintEntityTableProvision;
1048
+ task?: BlueprintEntityTableProvision;
1049
+ prompt?: BlueprintEntityTableProvision;
1050
+ knowledge?: BlueprintEntityTableProvision;
1051
+ };
1052
+ }
1053
+ /** Graph module configuration. Presence triggers permission registration (manage_graphs, execute_graphs). The graph module requires a merkle_store_module_id dependency, so entity_type_provision only registers permissions here — the graph module itself must be provisioned separately. */
1054
+ export interface BlueprintGraphConfig {
1055
+ /** Module discriminator for multi-module graphs. Defaults to "default". */
1056
+ key?: string;
1057
+ /** RLS policy overrides for the graph tables. NULL = apply defaults from apply_graph_security(). */
1058
+ policies?: BlueprintPolicy[];
1059
+ }
872
1060
  /** Override object for the entity table created by a BlueprintEntityType. Shape mirrors BlueprintTable / secure_table_provision vocabulary. When supplied, policies[] replaces the default entity-table policies entirely. */
873
1061
  export interface BlueprintEntityTableProvision {
874
1062
  /** Whether to enable RLS on the entity table. Forwarded to secure_table_provision. Defaults to true. */
@@ -913,11 +1101,19 @@ export interface BlueprintEntityType {
913
1101
  skip_entity_policies?: boolean;
914
1102
  /** 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). */
915
1103
  table_provision?: BlueprintEntityTableProvision;
916
- /** Storage configuration (array-only). A non-empty array enables storage provisioning. Each entry creates a separate storage module with its own tables ({prefix}_{storage_key}_buckets/files). Controls RLS policies, bucket seeding, and module-level settings. */
1104
+ /** Storage module configuration array. Presence triggers provisioning (same inference model as namespaces, functions, agents). Each entry provisions a separate storage module with its own tables, RLS, and settings. Each entry may specify a storage_key for multi-module support (defaults to "default"). */
917
1105
  storage?: BlueprintStorageConfig[];
1106
+ /** Namespace module configuration array. Presence triggers provisioning. Each entry provisions a namespace_module with its own tables, computed-name proxy, and entity-scoped RLS. Registers manage_namespaces permission bit. "[{}]" = provision one default namespace module. */
1107
+ namespaces?: BlueprintNamespaceConfig[];
1108
+ /** Function module configuration array. Presence triggers provisioning. Each entry provisions function_definitions, function_invocations (partitioned), and function_execution_logs tables. Registers manage_functions + invoke_functions permission bits. "[{}]" = provision one default function module. */
1109
+ functions?: BlueprintFunctionConfig[];
1110
+ /** Agent module configuration array. Presence triggers provisioning. Each entry provisions thread, message, task, prompt tables (and optionally knowledge with vector embeddings). "[{}]" = provision one default agent module. */
1111
+ agents?: BlueprintAgentConfig[];
1112
+ /** Graph module configuration array. Presence triggers permission registration (manage_graphs, execute_graphs). Graph module requires a merkle_store_module_id dependency, so entity_type_provision only registers permissions here. "[{}]" = register default graph permissions. */
1113
+ graphs?: BlueprintGraphConfig[];
918
1114
  }
919
1115
  /** String shorthand -- just the node type name. */
920
- export type BlueprintNodeShorthand = 'AuthzAllowAll' | 'AuthzAppMembership' | 'AuthzComposite' | 'AuthzDenyAll' | 'AuthzFilePath' | 'AuthzDirectOwner' | 'AuthzDirectOwnerAny' | 'AuthzEntityMembership' | 'AuthzMemberList' | 'AuthzNotReadOnly' | 'AuthzOrgHierarchy' | 'AuthzPeerOwnership' | 'AuthzPublishable' | 'AuthzRelatedEntityMembership' | 'AuthzRelatedMemberList' | 'AuthzRelatedPeerOwnership' | 'AuthzTemporal' | 'CheckGreaterThan' | 'CheckLessThan' | 'CheckNotEqual' | 'CheckOneOf' | 'LimitAggregate' | 'BillingMeter' | 'DataBulk' | 'ProcessChunks' | 'DataCompositeField' | 'DataDirectOwner' | 'DataEntityMembership' | 'ProcessFileEmbedding' | 'LimitFeatureFlag' | 'DataForceCurrentUser' | 'DataId' | 'ProcessImageEmbedding' | 'DataImmutableFields' | 'DataInflection' | 'DataInheritFromParent' | 'JobTrigger' | 'LimitCounter' | 'DataJsonb' | 'DataOwnedFields' | 'ProcessExtraction' | 'ProcessImageVersions' | 'DataOwnershipInEntity' | 'DataPeoplestamps' | 'DataPublishable' | 'DataRealtime' | 'DataSlug' | 'DataSoftDelete' | 'DataStatusField' | 'DataTags' | 'DataTimestamps' | 'SearchBm25' | 'SearchFullText' | 'SearchSpatial' | 'SearchSpatialAggregate' | 'SearchTrgm' | 'SearchUnified' | 'SearchVector' | 'TableOrganizationSettings' | 'TableUserProfiles' | 'TableUserSettings';
1116
+ export type BlueprintNodeShorthand = 'AuthzAllowAll' | 'AuthzAppMembership' | 'AuthzComposite' | 'AuthzDenyAll' | 'AuthzFilePath' | 'AuthzDirectOwner' | 'AuthzDirectOwnerAny' | 'AuthzEntityMembership' | 'AuthzMemberList' | 'AuthzNotReadOnly' | 'AuthzOrgHierarchy' | 'AuthzMemberOwner' | 'AuthzPeerOwnership' | 'AuthzPublishable' | 'AuthzRelatedEntityMembership' | 'AuthzRelatedMemberList' | 'AuthzRelatedPeerOwnership' | 'AuthzTemporal' | 'CheckGreaterThan' | 'CheckLessThan' | 'CheckNotEqual' | 'CheckOneOf' | 'DataBulk' | 'DataCompositeField' | 'DataDirectOwner' | 'DataEntityMembership' | 'DataForceCurrentUser' | 'DataId' | 'DataImmutableFields' | 'DataInflection' | 'DataInheritFromParent' | 'DataJsonb' | 'DataMemberOwner' | 'DataOwnedFields' | 'DataOwnershipInEntity' | 'DataPeoplestamps' | 'DataPublishable' | 'DataRealtime' | 'DataSlug' | 'DataSoftDelete' | 'DataStatusField' | 'DataTags' | 'DataTimestamps' | 'SearchBm25' | 'SearchFullText' | 'SearchSpatial' | 'SearchSpatialAggregate' | 'SearchTrgm' | 'SearchUnified' | 'SearchVector' | 'TableOrganizationSettings' | 'TableUserProfiles' | 'TableUserSettings' | 'EventReferral' | 'EventTracker' | 'JobTrigger' | 'LimitEnforceAggregate' | 'LimitEnforceCounter' | 'LimitEnforceFeature' | 'LimitEnforceRate' | 'LimitTrackUsage' | 'LimitWarningAggregate' | 'LimitWarningCounter' | 'LimitWarningRate' | 'ProcessChunks' | 'ProcessExtraction' | 'ProcessFileEmbedding' | 'ProcessImageEmbedding' | 'ProcessImageVersions';
921
1117
  /** Object form -- { $type, data } with typed parameters. */
922
1118
  export type BlueprintNodeObject = {
923
1119
  $type: 'AuthzAllowAll';
@@ -952,6 +1148,9 @@ export type BlueprintNodeObject = {
952
1148
  } | {
953
1149
  $type: 'AuthzOrgHierarchy';
954
1150
  data: AuthzOrgHierarchyParams;
1151
+ } | {
1152
+ $type: 'AuthzMemberOwner';
1153
+ data: AuthzMemberOwnerParams;
955
1154
  } | {
956
1155
  $type: 'AuthzPeerOwnership';
957
1156
  data: AuthzPeerOwnershipParams;
@@ -982,18 +1181,9 @@ export type BlueprintNodeObject = {
982
1181
  } | {
983
1182
  $type: 'CheckOneOf';
984
1183
  data: CheckOneOfParams;
985
- } | {
986
- $type: 'LimitAggregate';
987
- data: LimitAggregateParams;
988
- } | {
989
- $type: 'BillingMeter';
990
- data: BillingMeterParams;
991
1184
  } | {
992
1185
  $type: 'DataBulk';
993
1186
  data: DataBulkParams;
994
- } | {
995
- $type: 'ProcessChunks';
996
- data: ProcessChunksParams;
997
1187
  } | {
998
1188
  $type: 'DataCompositeField';
999
1189
  data: DataCompositeFieldParams;
@@ -1003,21 +1193,12 @@ export type BlueprintNodeObject = {
1003
1193
  } | {
1004
1194
  $type: 'DataEntityMembership';
1005
1195
  data: DataEntityMembershipParams;
1006
- } | {
1007
- $type: 'ProcessFileEmbedding';
1008
- data: ProcessFileEmbeddingParams;
1009
- } | {
1010
- $type: 'LimitFeatureFlag';
1011
- data: LimitFeatureFlagParams;
1012
1196
  } | {
1013
1197
  $type: 'DataForceCurrentUser';
1014
1198
  data: DataForceCurrentUserParams;
1015
1199
  } | {
1016
1200
  $type: 'DataId';
1017
1201
  data: DataIdParams;
1018
- } | {
1019
- $type: 'ProcessImageEmbedding';
1020
- data: ProcessImageEmbeddingParams;
1021
1202
  } | {
1022
1203
  $type: 'DataImmutableFields';
1023
1204
  data: DataImmutableFieldsParams;
@@ -1027,24 +1208,15 @@ export type BlueprintNodeObject = {
1027
1208
  } | {
1028
1209
  $type: 'DataInheritFromParent';
1029
1210
  data: DataInheritFromParentParams;
1030
- } | {
1031
- $type: 'JobTrigger';
1032
- data: JobTriggerParams;
1033
- } | {
1034
- $type: 'LimitCounter';
1035
- data: LimitCounterParams;
1036
1211
  } | {
1037
1212
  $type: 'DataJsonb';
1038
1213
  data: DataJsonbParams;
1214
+ } | {
1215
+ $type: 'DataMemberOwner';
1216
+ data: DataMemberOwnerParams;
1039
1217
  } | {
1040
1218
  $type: 'DataOwnedFields';
1041
1219
  data: DataOwnedFieldsParams;
1042
- } | {
1043
- $type: 'ProcessExtraction';
1044
- data: ProcessExtractionParams;
1045
- } | {
1046
- $type: 'ProcessImageVersions';
1047
- data: ProcessImageVersionsParams;
1048
1220
  } | {
1049
1221
  $type: 'DataOwnershipInEntity';
1050
1222
  data: DataOwnershipInEntityParams;
@@ -1102,6 +1274,54 @@ export type BlueprintNodeObject = {
1102
1274
  } | {
1103
1275
  $type: 'TableUserSettings';
1104
1276
  data?: Record<string, never>;
1277
+ } | {
1278
+ $type: 'EventReferral';
1279
+ data: EventReferralParams;
1280
+ } | {
1281
+ $type: 'EventTracker';
1282
+ data: EventTrackerParams;
1283
+ } | {
1284
+ $type: 'JobTrigger';
1285
+ data: JobTriggerParams;
1286
+ } | {
1287
+ $type: 'LimitEnforceAggregate';
1288
+ data: LimitEnforceAggregateParams;
1289
+ } | {
1290
+ $type: 'LimitEnforceCounter';
1291
+ data: LimitEnforceCounterParams;
1292
+ } | {
1293
+ $type: 'LimitEnforceFeature';
1294
+ data: LimitEnforceFeatureParams;
1295
+ } | {
1296
+ $type: 'LimitEnforceRate';
1297
+ data: LimitEnforceRateParams;
1298
+ } | {
1299
+ $type: 'LimitTrackUsage';
1300
+ data: LimitTrackUsageParams;
1301
+ } | {
1302
+ $type: 'LimitWarningAggregate';
1303
+ data: LimitWarningAggregateParams;
1304
+ } | {
1305
+ $type: 'LimitWarningCounter';
1306
+ data: LimitWarningCounterParams;
1307
+ } | {
1308
+ $type: 'LimitWarningRate';
1309
+ data: LimitWarningRateParams;
1310
+ } | {
1311
+ $type: 'ProcessChunks';
1312
+ data: ProcessChunksParams;
1313
+ } | {
1314
+ $type: 'ProcessExtraction';
1315
+ data: ProcessExtractionParams;
1316
+ } | {
1317
+ $type: 'ProcessFileEmbedding';
1318
+ data: ProcessFileEmbeddingParams;
1319
+ } | {
1320
+ $type: 'ProcessImageEmbedding';
1321
+ data: ProcessImageEmbeddingParams;
1322
+ } | {
1323
+ $type: 'ProcessImageVersions';
1324
+ data: ProcessImageVersionsParams;
1105
1325
  };
1106
1326
  /** A node entry in a blueprint table. Either a string shorthand or a typed object. */
1107
1327
  export type BlueprintNode = BlueprintNodeShorthand | BlueprintNodeObject;
@@ -1183,4 +1403,10 @@ export interface BlueprintDefinition {
1183
1403
  storage?: BlueprintStorageConfig[];
1184
1404
  /** Achievement definitions. Each entry creates a level with requirements and optional rewards in the events_module. Requires events_module to be provisioned (e.g., via entity_types[].has_levels = true or modules includes events_module). */
1185
1405
  achievements?: BlueprintAchievement[];
1406
+ /** Top-level namespace configuration array (Phase 0.6). Each entry has an optional scope ("app" or "org"). App-scoped (default) creates namespace_module with membership_type = NULL. Org-scoped creates per-org namespaces. For entity-scoped namespaces, use entity_types[].namespaces instead. */
1407
+ namespaces?: BlueprintNamespaceConfig[];
1408
+ /** Top-level function configuration array (Phase 0.6). Each entry has an optional scope ("app" or "org"). App-scoped (default) creates function_module with membership_type = NULL. Org-scoped creates per-org functions. For entity-scoped functions, use entity_types[].functions instead. */
1409
+ functions?: BlueprintFunctionConfig[];
1410
+ /** Top-level agent configuration array (Phase 0.6). Each entry has an optional scope ("app" or "org"). App-scoped (default) creates agent_module with membership_type = NULL. Org-scoped creates per-org agents. For entity-scoped agents, use entity_types[].agents instead. */
1411
+ agents?: BlueprintAgentConfig[];
1186
1412
  }