node-type-registry 0.41.0 → 0.43.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.
- package/authz/authz-app-membership.js +8 -8
- package/authz/authz-member-owner.d.ts +2 -0
- package/authz/authz-member-owner.js +51 -0
- package/authz/index.d.ts +2 -1
- package/authz/index.js +5 -3
- package/blueprint-types.generated.d.ts +355 -77
- package/blueprint-types.generated.js +16 -4
- package/codegen/generate-types.js +175 -8
- package/data/check-greater-than.js +6 -6
- package/data/check-less-than.js +6 -6
- package/data/check-not-equal.js +4 -4
- package/data/check-one-of.js +5 -5
- package/data/data-jsonb.js +4 -3
- package/data/data-member-owner.d.ts +2 -0
- package/data/data-member-owner.js +53 -0
- package/data/data-status-field.js +4 -3
- package/data/data-tags.js +4 -3
- package/data/index.d.ts +1 -0
- package/data/index.js +3 -1
- package/esm/authz/authz-app-membership.js +8 -8
- package/esm/authz/authz-member-owner.d.ts +2 -0
- package/esm/authz/authz-member-owner.js +48 -0
- package/esm/authz/index.d.ts +2 -1
- package/esm/authz/index.js +2 -1
- package/esm/blueprint-types.generated.d.ts +355 -77
- package/esm/blueprint-types.generated.js +16 -4
- package/esm/codegen/generate-types.js +175 -8
- package/esm/data/check-greater-than.js +6 -6
- package/esm/data/check-less-than.js +6 -6
- package/esm/data/check-not-equal.js +4 -4
- package/esm/data/check-one-of.js +5 -5
- package/esm/data/data-jsonb.js +4 -3
- package/esm/data/data-member-owner.d.ts +2 -0
- package/esm/data/data-member-owner.js +50 -0
- package/esm/data/data-status-field.js +4 -3
- package/esm/data/data-tags.js +4 -3
- package/esm/data/index.d.ts +1 -0
- package/esm/data/index.js +1 -0
- package/esm/event/referral.js +21 -2
- package/esm/event/tracker.js +20 -1
- package/esm/index.d.ts +1 -1
- package/esm/limit/enforce-aggregate.js +32 -8
- package/esm/limit/enforce-counter.js +33 -10
- package/esm/limit/enforce-feature.js +26 -8
- package/esm/limit/enforce-rate.js +28 -9
- package/esm/limit/track-usage.js +28 -9
- package/esm/limit/warning-aggregate.js +29 -5
- package/esm/limit/warning-counter.js +30 -7
- package/esm/limit/warning-rate.js +31 -7
- package/esm/module-presets/full.js +2 -2
- package/esm/process/chunks.js +1 -1
- package/esm/process/file-embedding.js +1 -1
- package/esm/types.d.ts +92 -0
- package/esm/types.js +1 -0
- package/event/referral.js +21 -2
- package/event/tracker.js +20 -1
- package/index.d.ts +1 -1
- package/limit/enforce-aggregate.js +32 -8
- package/limit/enforce-counter.js +33 -10
- package/limit/enforce-feature.js +26 -8
- package/limit/enforce-rate.js +28 -9
- package/limit/track-usage.js +28 -9
- package/limit/warning-aggregate.js +29 -5
- package/limit/warning-counter.js +30 -7
- package/limit/warning-rate.js +31 -7
- package/module-presets/full.js +2 -2
- package/package.json +2 -2
- package/process/chunks.js +1 -1
- package/process/file-embedding.js +1 -1
- package/types.d.ts +92 -0
- package/types.js +1 -0
|
@@ -16,25 +16,37 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
16
16
|
;
|
|
17
17
|
/**
|
|
18
18
|
* ===========================================================================
|
|
19
|
-
*
|
|
19
|
+
* Check node type parameters
|
|
20
20
|
* ===========================================================================
|
|
21
21
|
*/
|
|
22
22
|
;
|
|
23
23
|
/**
|
|
24
24
|
* ===========================================================================
|
|
25
|
-
*
|
|
25
|
+
* Data node type parameters
|
|
26
26
|
* ===========================================================================
|
|
27
27
|
*/
|
|
28
28
|
;
|
|
29
29
|
/**
|
|
30
30
|
* ===========================================================================
|
|
31
|
-
*
|
|
31
|
+
* Event node type parameters
|
|
32
|
+
* ===========================================================================
|
|
33
|
+
*/
|
|
34
|
+
;
|
|
35
|
+
/**
|
|
36
|
+
* ===========================================================================
|
|
37
|
+
* Limit_enforce node type parameters
|
|
38
|
+
* ===========================================================================
|
|
39
|
+
*/
|
|
40
|
+
;
|
|
41
|
+
/**
|
|
42
|
+
* ===========================================================================
|
|
43
|
+
* Limit_track node type parameters
|
|
32
44
|
* ===========================================================================
|
|
33
45
|
*/
|
|
34
46
|
;
|
|
35
47
|
/**
|
|
36
48
|
* ===========================================================================
|
|
37
|
-
*
|
|
49
|
+
* Limit_warning node type parameters
|
|
38
50
|
* ===========================================================================
|
|
39
51
|
*/
|
|
40
52
|
;
|
|
@@ -172,6 +172,56 @@ function buildTriggerConditionInterface() {
|
|
|
172
172
|
]), 'Recursive condition type for compound trigger WHEN clauses. Leaf conditions specify {field, op, value?, row?, ref?}. Combinators nest via AND, OR, NOT.');
|
|
173
173
|
}
|
|
174
174
|
// ---------------------------------------------------------------------------
|
|
175
|
+
// FieldType — structured PostgreSQL type representation.
|
|
176
|
+
// ---------------------------------------------------------------------------
|
|
177
|
+
function buildFieldTypeInterface() {
|
|
178
|
+
const argType = t.tsUnionType([
|
|
179
|
+
t.tsStringKeyword(),
|
|
180
|
+
t.tsNumberKeyword(),
|
|
181
|
+
t.tsBooleanKeyword()
|
|
182
|
+
]);
|
|
183
|
+
return addJSDoc(exportInterface('FieldType', [
|
|
184
|
+
addJSDoc(requiredProp('name', t.tsStringKeyword()), 'Type name. Must be a valid SQL identifier.'),
|
|
185
|
+
addJSDoc(optionalProp('schema', t.tsStringKeyword()), 'Schema qualifier.'),
|
|
186
|
+
addJSDoc(optionalProp('args', t.tsArrayType(argType)), 'Type arguments (e.g., [10, 2] for numeric(10,2), ["Point", 4326] for geometry).'),
|
|
187
|
+
addJSDoc(optionalProp('array_dimensions', t.tsNumberKeyword()), 'Number of array dimensions. 1 = text[], 2 = text[][].'),
|
|
188
|
+
addJSDoc(optionalProp('range', t.tsArrayType(t.tsStringKeyword())), 'Interval field range. 1-2 elements: ["day"] or ["day", "second"].')
|
|
189
|
+
]), 'Structured representation of a PostgreSQL data type. Stored as JSONB in metaschema_public.field.type.');
|
|
190
|
+
}
|
|
191
|
+
// ---------------------------------------------------------------------------
|
|
192
|
+
// FieldDefault — structured PostgreSQL default value expression.
|
|
193
|
+
// ---------------------------------------------------------------------------
|
|
194
|
+
function buildFieldDefaultInterface() {
|
|
195
|
+
const defaultRef = t.tsTypeReference(t.identifier('FieldDefault'));
|
|
196
|
+
const fieldTypeRef = t.tsTypeReference(t.identifier('FieldType'));
|
|
197
|
+
const valueType = t.tsUnionType([
|
|
198
|
+
t.tsStringKeyword(),
|
|
199
|
+
t.tsNumberKeyword(),
|
|
200
|
+
t.tsBooleanKeyword(),
|
|
201
|
+
t.tsNullKeyword(),
|
|
202
|
+
t.tsArrayType(t.tsUnknownKeyword()),
|
|
203
|
+
recordType(t.tsStringKeyword(), t.tsUnknownKeyword())
|
|
204
|
+
]);
|
|
205
|
+
const argType = t.tsUnionType([
|
|
206
|
+
t.tsStringKeyword(),
|
|
207
|
+
t.tsNumberKeyword(),
|
|
208
|
+
t.tsBooleanKeyword(),
|
|
209
|
+
t.tsNullKeyword(),
|
|
210
|
+
defaultRef
|
|
211
|
+
]);
|
|
212
|
+
return addJSDoc(exportInterface('FieldDefault', [
|
|
213
|
+
addJSDoc(optionalProp('value', valueType), 'Literal value (string, number, boolean, null, array, or object).'),
|
|
214
|
+
addJSDoc(optionalProp('function', t.tsStringKeyword()), 'Function name. Must be a valid SQL identifier.'),
|
|
215
|
+
addJSDoc(optionalProp('schema', t.tsStringKeyword()), 'Schema qualifier for function.'),
|
|
216
|
+
addJSDoc(optionalProp('args', t.tsArrayType(argType)), 'Function arguments (recursive).'),
|
|
217
|
+
addJSDoc(optionalProp('cast', fieldTypeRef), 'Output type cast.'),
|
|
218
|
+
addJSDoc(optionalProp('operator', t.tsStringKeyword()), 'Binary operator (e.g., "+", "-", "||").'),
|
|
219
|
+
addJSDoc(optionalProp('left', defaultRef), 'Left operand for operator expression.'),
|
|
220
|
+
addJSDoc(optionalProp('right', defaultRef), 'Right operand for operator expression.'),
|
|
221
|
+
addJSDoc(optionalProp('sql_keyword', t.tsStringKeyword()), 'SQL keyword (e.g., "CURRENT_TIMESTAMP", "CURRENT_USER").')
|
|
222
|
+
]), 'Structured representation of a PostgreSQL default value expression. Stored as JSONB in metaschema_public.field.default_value.');
|
|
223
|
+
}
|
|
224
|
+
// ---------------------------------------------------------------------------
|
|
175
225
|
// x-codegen-type post-processing — replaces properties that have an
|
|
176
226
|
// 'x-codegen-type' marker in their JSON Schema with a hand-written TS type
|
|
177
227
|
// reference. This lets node type definitions delegate complex types
|
|
@@ -337,11 +387,13 @@ function buildBlueprintField(meta) {
|
|
|
337
387
|
return deriveInterfaceFromTable(table, 'BlueprintField', 'A custom field (column) to add to a blueprint table. Derived from _meta.');
|
|
338
388
|
}
|
|
339
389
|
// Static fallback
|
|
390
|
+
const fieldTypeRef = t.tsTypeReference(t.identifier('FieldType'));
|
|
391
|
+
const fieldDefaultRef = t.tsTypeReference(t.identifier('FieldDefault'));
|
|
340
392
|
return addJSDoc(exportInterface('BlueprintField', [
|
|
341
393
|
addJSDoc(requiredProp('name', t.tsStringKeyword()), 'The column name.'),
|
|
342
|
-
addJSDoc(requiredProp('type', t.tsStringKeyword()), '
|
|
394
|
+
addJSDoc(requiredProp('type', t.tsUnionType([fieldTypeRef, t.tsStringKeyword()])), 'PostgreSQL type as a FieldType object (e.g., { name: "text" }) or legacy string.'),
|
|
343
395
|
addJSDoc(optionalProp('is_required', t.tsBooleanKeyword()), 'Whether the column has a NOT NULL constraint.'),
|
|
344
|
-
addJSDoc(optionalProp('default_value', t.tsStringKeyword()), '
|
|
396
|
+
addJSDoc(optionalProp('default_value', t.tsUnionType([fieldDefaultRef, t.tsStringKeyword()])), 'Default value as a FieldDefault object (e.g., { function: "now" }) or legacy string.'),
|
|
345
397
|
addJSDoc(optionalProp('description', t.tsStringKeyword()), 'Comment/description for this field.')
|
|
346
398
|
]), 'A custom field (column) to add to a blueprint table.');
|
|
347
399
|
}
|
|
@@ -496,7 +548,7 @@ function buildBlueprintTableUniqueConstraint() {
|
|
|
496
548
|
/**
|
|
497
549
|
* Build the BlueprintBucketSeed interface.
|
|
498
550
|
*
|
|
499
|
-
* Matches the bucket entries in
|
|
551
|
+
* Matches the bucket entries in storage.buckets[].
|
|
500
552
|
*/
|
|
501
553
|
function buildBlueprintBucketSeed() {
|
|
502
554
|
return addJSDoc(exportInterface('BlueprintBucketSeed', [
|
|
@@ -506,12 +558,12 @@ function buildBlueprintBucketSeed() {
|
|
|
506
558
|
addJSDoc(optionalProp('allowed_mime_types', t.tsArrayType(t.tsStringKeyword())), 'MIME type allowlist (e.g., ["image/png", "image/jpeg"]). NULL means all types allowed.'),
|
|
507
559
|
addJSDoc(optionalProp('max_file_size', t.tsNumberKeyword()), 'Maximum file size in bytes for this bucket. NULL means no limit.'),
|
|
508
560
|
addJSDoc(optionalProp('allowed_origins', t.tsArrayType(t.tsStringKeyword())), 'CORS allowed origins for this bucket.')
|
|
509
|
-
]), 'A bucket seed entry for
|
|
561
|
+
]), '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).');
|
|
510
562
|
}
|
|
511
563
|
/**
|
|
512
564
|
* Build the BlueprintStorageConfig interface.
|
|
513
565
|
*
|
|
514
|
-
* Matches the jsonb shape accepted by
|
|
566
|
+
* Matches the jsonb shape accepted by storage on entity_type_provision.
|
|
515
567
|
*/
|
|
516
568
|
function buildBlueprintStorageConfig() {
|
|
517
569
|
return addJSDoc(exportInterface('BlueprintStorageConfig', [
|
|
@@ -564,6 +616,108 @@ function buildBlueprintAchievement() {
|
|
|
564
616
|
addJSDoc(optionalProp('entity_prefix', t.tsStringKeyword()), 'Entity prefix to scope this achievement to (e.g., "org", "app"). Used to resolve the correct events_module. Defaults to "app".')
|
|
565
617
|
]), 'An achievement entry for the blueprint achievements[] section. 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).');
|
|
566
618
|
}
|
|
619
|
+
// ---------------------------------------------------------------------------
|
|
620
|
+
// Module config types (namespace, function, agent, graph)
|
|
621
|
+
// ---------------------------------------------------------------------------
|
|
622
|
+
/**
|
|
623
|
+
* Build the BlueprintNamespaceConfig interface.
|
|
624
|
+
*
|
|
625
|
+
* Matches the jsonb shape accepted by namespaces on entity_type_provision
|
|
626
|
+
* and the top-level definition.namespaces[] array in construct_blueprint().
|
|
627
|
+
*/
|
|
628
|
+
function buildBlueprintNamespaceConfig() {
|
|
629
|
+
return addJSDoc(exportInterface('BlueprintNamespaceConfig', [
|
|
630
|
+
addJSDoc(optionalProp('scope', t.tsUnionType([
|
|
631
|
+
t.tsLiteralType(t.stringLiteral('app')),
|
|
632
|
+
t.tsLiteralType(t.stringLiteral('org'))
|
|
633
|
+
])), '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.'),
|
|
634
|
+
addJSDoc(optionalProp('key', t.tsStringKeyword()), 'Module discriminator for multi-module namespaces. Defaults to "default" (omitted from table names). Non-default keys appear as an infix: {prefix}_{key}_namespaces.'),
|
|
635
|
+
addJSDoc(optionalProp('policies', t.tsArrayType(t.tsTypeReference(t.identifier('BlueprintPolicy')))), 'RLS policy overrides for the namespaces table. NULL = apply defaults from apply_namespace_security().'),
|
|
636
|
+
addJSDoc(optionalProp('provisions', t.tsTypeLiteral([
|
|
637
|
+
optionalProp('namespaces', t.tsTypeReference(t.identifier('BlueprintEntityTableProvision'))),
|
|
638
|
+
optionalProp('namespace_events', t.tsTypeReference(t.identifier('BlueprintEntityTableProvision')))
|
|
639
|
+
])), '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.')
|
|
640
|
+
]), '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.');
|
|
641
|
+
}
|
|
642
|
+
/**
|
|
643
|
+
* Build the BlueprintFunctionConfig interface.
|
|
644
|
+
*
|
|
645
|
+
* Matches the jsonb shape accepted by functions on entity_type_provision
|
|
646
|
+
* and the top-level definition.functions[] array in construct_blueprint().
|
|
647
|
+
*/
|
|
648
|
+
function buildBlueprintFunctionConfig() {
|
|
649
|
+
return addJSDoc(exportInterface('BlueprintFunctionConfig', [
|
|
650
|
+
addJSDoc(optionalProp('scope', t.tsUnionType([
|
|
651
|
+
t.tsLiteralType(t.stringLiteral('app')),
|
|
652
|
+
t.tsLiteralType(t.stringLiteral('org'))
|
|
653
|
+
])), '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.'),
|
|
654
|
+
addJSDoc(optionalProp('key', t.tsStringKeyword()), 'Module discriminator for multi-module functions. Defaults to "default" (omitted from table names). Non-default keys appear as an infix: {prefix}_{key}_function_definitions.'),
|
|
655
|
+
addJSDoc(optionalProp('policies', t.tsArrayType(t.tsTypeReference(t.identifier('BlueprintPolicy')))), 'RLS policy overrides for the function tables. NULL = apply defaults from apply_function_security().'),
|
|
656
|
+
addJSDoc(optionalProp('provisions', t.tsTypeLiteral([
|
|
657
|
+
optionalProp('definitions', t.tsTypeReference(t.identifier('BlueprintEntityTableProvision'))),
|
|
658
|
+
optionalProp('invocations', t.tsTypeReference(t.identifier('BlueprintEntityTableProvision'))),
|
|
659
|
+
optionalProp('execution_logs', t.tsTypeReference(t.identifier('BlueprintEntityTableProvision')))
|
|
660
|
+
])), '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.')
|
|
661
|
+
]), '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.');
|
|
662
|
+
}
|
|
663
|
+
/**
|
|
664
|
+
* Build the BlueprintAgentConfig interface.
|
|
665
|
+
*
|
|
666
|
+
* Matches the jsonb shape accepted by agents on entity_type_provision
|
|
667
|
+
* and the top-level definition.agents[] array in construct_blueprint().
|
|
668
|
+
*/
|
|
669
|
+
function buildBlueprintAgentConfig() {
|
|
670
|
+
return addJSDoc(exportInterface('BlueprintAgentConfig', [
|
|
671
|
+
addJSDoc(optionalProp('scope', t.tsUnionType([
|
|
672
|
+
t.tsLiteralType(t.stringLiteral('app')),
|
|
673
|
+
t.tsLiteralType(t.stringLiteral('org'))
|
|
674
|
+
])), '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.'),
|
|
675
|
+
addJSDoc(optionalProp('key', t.tsStringKeyword()), 'Module discriminator for multi-module agents. Defaults to "default" (omitted from table names). Non-default keys appear as an infix: {prefix}_{key}_agent_thread.'),
|
|
676
|
+
addJSDoc(optionalProp('api_name', t.tsStringKeyword()), 'API name for the agent module. Used in GraphQL naming. Defaults to "agent".'),
|
|
677
|
+
addJSDoc(optionalProp('has_knowledge', t.tsBooleanKeyword()), '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.'),
|
|
678
|
+
addJSDoc(optionalProp('knowledge', t.tsTypeLiteral([
|
|
679
|
+
optionalProp('has_chunks', t.tsBooleanKeyword()),
|
|
680
|
+
optionalProp('dimensions', t.tsNumberKeyword()),
|
|
681
|
+
optionalProp('chunk_size', t.tsNumberKeyword()),
|
|
682
|
+
optionalProp('chunk_overlap', t.tsNumberKeyword()),
|
|
683
|
+
optionalProp('chunk_strategy', t.tsUnionType([
|
|
684
|
+
t.tsLiteralType(t.stringLiteral('fixed')),
|
|
685
|
+
t.tsLiteralType(t.stringLiteral('sentence')),
|
|
686
|
+
t.tsLiteralType(t.stringLiteral('paragraph')),
|
|
687
|
+
t.tsLiteralType(t.stringLiteral('semantic'))
|
|
688
|
+
])),
|
|
689
|
+
optionalProp('embedding_model', t.tsStringKeyword()),
|
|
690
|
+
optionalProp('embedding_provider', t.tsStringKeyword()),
|
|
691
|
+
optionalProp('search_indexes', t.tsArrayType(t.tsUnionType([
|
|
692
|
+
t.tsLiteralType(t.stringLiteral('fulltext')),
|
|
693
|
+
t.tsLiteralType(t.stringLiteral('bm25')),
|
|
694
|
+
t.tsLiteralType(t.stringLiteral('trigram'))
|
|
695
|
+
])))
|
|
696
|
+
])), '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.'),
|
|
697
|
+
addJSDoc(optionalProp('policies', t.tsArrayType(t.tsTypeReference(t.identifier('BlueprintPolicy')))), 'RLS policy overrides for the agent tables. NULL = apply defaults from apply_agent_security().'),
|
|
698
|
+
addJSDoc(optionalProp('provisions', t.tsTypeLiteral([
|
|
699
|
+
optionalProp('thread', t.tsTypeReference(t.identifier('BlueprintEntityTableProvision'))),
|
|
700
|
+
optionalProp('message', t.tsTypeReference(t.identifier('BlueprintEntityTableProvision'))),
|
|
701
|
+
optionalProp('task', t.tsTypeReference(t.identifier('BlueprintEntityTableProvision'))),
|
|
702
|
+
optionalProp('prompt', t.tsTypeReference(t.identifier('BlueprintEntityTableProvision'))),
|
|
703
|
+
optionalProp('knowledge', t.tsTypeReference(t.identifier('BlueprintEntityTableProvision')))
|
|
704
|
+
])), '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.')
|
|
705
|
+
]), '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).');
|
|
706
|
+
}
|
|
707
|
+
/**
|
|
708
|
+
* Build the BlueprintGraphConfig interface.
|
|
709
|
+
*
|
|
710
|
+
* Matches the jsonb shape accepted by graphs on entity_type_provision.
|
|
711
|
+
* Graph module requires a merkle_store_module_id dependency, so
|
|
712
|
+
* entity_type_provision only registers permissions. The graph module itself
|
|
713
|
+
* must be provisioned separately with the merkle store dependency resolved.
|
|
714
|
+
*/
|
|
715
|
+
function buildBlueprintGraphConfig() {
|
|
716
|
+
return addJSDoc(exportInterface('BlueprintGraphConfig', [
|
|
717
|
+
addJSDoc(optionalProp('key', t.tsStringKeyword()), 'Module discriminator for multi-module graphs. Defaults to "default".'),
|
|
718
|
+
addJSDoc(optionalProp('policies', t.tsArrayType(t.tsTypeReference(t.identifier('BlueprintPolicy')))), 'RLS policy overrides for the graph tables. NULL = apply defaults from apply_graph_security().')
|
|
719
|
+
]), '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.');
|
|
720
|
+
}
|
|
567
721
|
function buildBlueprintEntityTableProvision() {
|
|
568
722
|
return addJSDoc(exportInterface('BlueprintEntityTableProvision', [
|
|
569
723
|
addJSDoc(optionalProp('use_rls', t.tsBooleanKeyword()), 'Whether to enable RLS on the entity table. Forwarded to secure_table_provision. Defaults to true.'),
|
|
@@ -591,7 +745,11 @@ function buildBlueprintEntityType() {
|
|
|
591
745
|
addJSDoc(optionalProp('has_invite_achievements', t.tsBooleanKeyword()), "Whether to auto-attach an EventTracker to the claimed_invites table for invite-based achievements. Requires has_invites=true AND has_levels=true. When true, records 'invite_claimed' events credited to the sender (inviter) on each claimed invite. Defaults to false."),
|
|
592
746
|
addJSDoc(optionalProp('skip_entity_policies', t.tsBooleanKeyword()), 'Escape hatch: when true AND table_provision is NULL, zero policies are provisioned on the entity table. Defaults to false.'),
|
|
593
747
|
addJSDoc(optionalProp('table_provision', t.tsTypeReference(t.identifier('BlueprintEntityTableProvision'))), '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).'),
|
|
594
|
-
addJSDoc(optionalProp('storage', t.tsArrayType(t.tsTypeReference(t.identifier('BlueprintStorageConfig')))), 'Storage module configuration array. Each entry provisions a separate storage module with its own tables, RLS, and settings.
|
|
748
|
+
addJSDoc(optionalProp('storage', t.tsArrayType(t.tsTypeReference(t.identifier('BlueprintStorageConfig')))), '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").'),
|
|
749
|
+
addJSDoc(optionalProp('namespaces', t.tsArrayType(t.tsTypeReference(t.identifier('BlueprintNamespaceConfig')))), '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.'),
|
|
750
|
+
addJSDoc(optionalProp('functions', t.tsArrayType(t.tsTypeReference(t.identifier('BlueprintFunctionConfig')))), '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.'),
|
|
751
|
+
addJSDoc(optionalProp('agents', t.tsArrayType(t.tsTypeReference(t.identifier('BlueprintAgentConfig')))), '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.'),
|
|
752
|
+
addJSDoc(optionalProp('graphs', t.tsArrayType(t.tsTypeReference(t.identifier('BlueprintGraphConfig')))), '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.')
|
|
595
753
|
]), 'An entity type entry for Phase 0 of construct_blueprint(). When name is provided, provisions a new entity type with its own entity table, membership modules, and security policies via entity_type_provision. When name is omitted and only prefix is given, extends an existing entity type (e.g., the built-in "org") with additional capabilities like storage — without creating a new entity type.');
|
|
596
754
|
}
|
|
597
755
|
function buildBlueprintTable() {
|
|
@@ -620,7 +778,10 @@ function buildBlueprintDefinition() {
|
|
|
620
778
|
addJSDoc(optionalProp('unique_constraints', t.tsArrayType(t.tsTypeReference(t.identifier('BlueprintUniqueConstraint')))), 'Unique constraints on table columns.'),
|
|
621
779
|
addJSDoc(optionalProp('entity_types', t.tsArrayType(t.tsTypeReference(t.identifier('BlueprintEntityType')))), 'Entity types to provision in Phase 0 (before tables). Each entry creates an entity table with membership modules and security.'),
|
|
622
780
|
addJSDoc(optionalProp('storage', t.tsArrayType(t.tsTypeReference(t.identifier('BlueprintStorageConfig')))), 'Top-level storage configuration array. Each entry has an optional scope ("app" or "org"). App-scoped (default) creates storage_module with membership_type = NULL. Org-scoped creates per-org/user storage with owner_id and AFTER INSERT bucket seeding. When infra is installed, a private "functions" bucket is auto-injected into org-scoped entries. For child entity type storage, use entity_types[].storage instead.'),
|
|
623
|
-
addJSDoc(optionalProp('achievements', t.tsArrayType(t.tsTypeReference(t.identifier('BlueprintAchievement')))), '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).')
|
|
781
|
+
addJSDoc(optionalProp('achievements', t.tsArrayType(t.tsTypeReference(t.identifier('BlueprintAchievement')))), '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).'),
|
|
782
|
+
addJSDoc(optionalProp('namespaces', t.tsArrayType(t.tsTypeReference(t.identifier('BlueprintNamespaceConfig')))), '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.'),
|
|
783
|
+
addJSDoc(optionalProp('functions', t.tsArrayType(t.tsTypeReference(t.identifier('BlueprintFunctionConfig')))), '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.'),
|
|
784
|
+
addJSDoc(optionalProp('agents', t.tsArrayType(t.tsTypeReference(t.identifier('BlueprintAgentConfig')))), '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.')
|
|
624
785
|
]), 'The complete blueprint definition -- the JSONB shape accepted by construct_blueprint().');
|
|
625
786
|
}
|
|
626
787
|
// ---------------------------------------------------------------------------
|
|
@@ -654,8 +815,10 @@ function buildProgram(meta) {
|
|
|
654
815
|
// -- Shared recursive types (emitted before parameter interfaces) --
|
|
655
816
|
statements.push(sectionComment('Shared recursive types'));
|
|
656
817
|
statements.push(buildTriggerConditionInterface());
|
|
818
|
+
statements.push(buildFieldTypeInterface());
|
|
819
|
+
statements.push(buildFieldDefaultInterface());
|
|
657
820
|
// -- Parameter interfaces grouped by category --
|
|
658
|
-
const categoryOrder = ['billing', 'check', 'data', 'limit', 'search', 'job', 'process', 'authz', 'relation', 'view'];
|
|
821
|
+
const categoryOrder = ['billing', 'check', 'data', 'event', 'limit', 'limit_enforce', 'limit_track', 'limit_warning', 'search', 'job', 'process', 'authz', 'relation', 'view'];
|
|
659
822
|
for (const cat of categoryOrder) {
|
|
660
823
|
const nts = categories.get(cat);
|
|
661
824
|
if (!nts || nts.length === 0)
|
|
@@ -682,6 +845,10 @@ function buildProgram(meta) {
|
|
|
682
845
|
statements.push(buildBlueprintAchievementRequirement());
|
|
683
846
|
statements.push(buildBlueprintAchievementReward());
|
|
684
847
|
statements.push(buildBlueprintAchievement());
|
|
848
|
+
statements.push(buildBlueprintNamespaceConfig());
|
|
849
|
+
statements.push(buildBlueprintFunctionConfig());
|
|
850
|
+
statements.push(buildBlueprintAgentConfig());
|
|
851
|
+
statements.push(buildBlueprintGraphConfig());
|
|
685
852
|
statements.push(buildBlueprintEntityTableProvision());
|
|
686
853
|
statements.push(buildBlueprintEntityType());
|
|
687
854
|
// -- Node types discriminated union --
|
|
@@ -13,21 +13,21 @@ exports.CheckGreaterThan = {
|
|
|
13
13
|
column: {
|
|
14
14
|
type: 'string',
|
|
15
15
|
format: 'column-ref',
|
|
16
|
-
description: 'Single column to compare against value (mutually exclusive with columns)'
|
|
16
|
+
description: 'Single column to compare against value (mutually exclusive with columns)'
|
|
17
17
|
},
|
|
18
18
|
value: {
|
|
19
19
|
type: 'number',
|
|
20
20
|
description: 'Threshold value for single-column comparison (column > value)',
|
|
21
|
-
default: 0
|
|
21
|
+
default: 0
|
|
22
22
|
},
|
|
23
23
|
columns: {
|
|
24
24
|
type: 'array',
|
|
25
25
|
items: { type: 'string', format: 'column-ref' },
|
|
26
26
|
description: 'Two columns for cross-column comparison (columns[0] > columns[1])',
|
|
27
27
|
minItems: 2,
|
|
28
|
-
maxItems: 2
|
|
29
|
-
}
|
|
30
|
-
}
|
|
28
|
+
maxItems: 2
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
31
|
},
|
|
32
|
-
tags: ['check', 'constraint', 'validation', 'comparison']
|
|
32
|
+
tags: ['check', 'constraint', 'validation', 'comparison']
|
|
33
33
|
};
|
package/data/check-less-than.js
CHANGED
|
@@ -13,20 +13,20 @@ exports.CheckLessThan = {
|
|
|
13
13
|
column: {
|
|
14
14
|
type: 'string',
|
|
15
15
|
format: 'column-ref',
|
|
16
|
-
description: 'Single column to compare against value (mutually exclusive with columns)'
|
|
16
|
+
description: 'Single column to compare against value (mutually exclusive with columns)'
|
|
17
17
|
},
|
|
18
18
|
value: {
|
|
19
19
|
type: 'number',
|
|
20
|
-
description: 'Threshold value for single-column comparison (column < value)'
|
|
20
|
+
description: 'Threshold value for single-column comparison (column < value)'
|
|
21
21
|
},
|
|
22
22
|
columns: {
|
|
23
23
|
type: 'array',
|
|
24
24
|
items: { type: 'string', format: 'column-ref' },
|
|
25
25
|
description: 'Two columns for cross-column comparison (columns[0] < columns[1])',
|
|
26
26
|
minItems: 2,
|
|
27
|
-
maxItems: 2
|
|
28
|
-
}
|
|
29
|
-
}
|
|
27
|
+
maxItems: 2
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
30
|
},
|
|
31
|
-
tags: ['check', 'constraint', 'validation', 'comparison']
|
|
31
|
+
tags: ['check', 'constraint', 'validation', 'comparison']
|
|
32
32
|
};
|
package/data/check-not-equal.js
CHANGED
|
@@ -15,10 +15,10 @@ exports.CheckNotEqual = {
|
|
|
15
15
|
items: { type: 'string', format: 'column-ref' },
|
|
16
16
|
description: 'Two columns that must not be equal',
|
|
17
17
|
minItems: 2,
|
|
18
|
-
maxItems: 2
|
|
19
|
-
}
|
|
18
|
+
maxItems: 2
|
|
19
|
+
}
|
|
20
20
|
},
|
|
21
|
-
required: ['columns']
|
|
21
|
+
required: ['columns']
|
|
22
22
|
},
|
|
23
|
-
tags: ['check', 'constraint', 'validation', 'inequality']
|
|
23
|
+
tags: ['check', 'constraint', 'validation', 'inequality']
|
|
24
24
|
};
|
package/data/check-one-of.js
CHANGED
|
@@ -13,15 +13,15 @@ exports.CheckOneOf = {
|
|
|
13
13
|
column: {
|
|
14
14
|
type: 'string',
|
|
15
15
|
format: 'column-ref',
|
|
16
|
-
description: 'Column to validate against the allowed values'
|
|
16
|
+
description: 'Column to validate against the allowed values'
|
|
17
17
|
},
|
|
18
18
|
values: {
|
|
19
19
|
type: 'array',
|
|
20
20
|
items: { type: 'string' },
|
|
21
|
-
description: 'Array of allowed values for the column'
|
|
22
|
-
}
|
|
21
|
+
description: 'Array of allowed values for the column'
|
|
22
|
+
}
|
|
23
23
|
},
|
|
24
|
-
required: ['column', 'values']
|
|
24
|
+
required: ['column', 'values']
|
|
25
25
|
},
|
|
26
|
-
tags: ['check', 'constraint', 'validation', 'enum']
|
|
26
|
+
tags: ['check', 'constraint', 'validation', 'enum']
|
|
27
27
|
};
|
package/data/data-jsonb.js
CHANGED
|
@@ -17,9 +17,10 @@ exports.DataJsonb = {
|
|
|
17
17
|
default: 'metadata'
|
|
18
18
|
},
|
|
19
19
|
default_value: {
|
|
20
|
-
type: '
|
|
21
|
-
description: 'Default value
|
|
22
|
-
|
|
20
|
+
type: 'object',
|
|
21
|
+
description: 'Default value as a FieldDefault object',
|
|
22
|
+
'x-codegen-type': 'FieldDefault',
|
|
23
|
+
default: { value: {}, cast: { name: 'jsonb' } }
|
|
23
24
|
},
|
|
24
25
|
is_required: {
|
|
25
26
|
type: 'boolean',
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DataMemberOwner = void 0;
|
|
4
|
+
exports.DataMemberOwner = {
|
|
5
|
+
name: 'DataMemberOwner',
|
|
6
|
+
slug: 'data_member_owner',
|
|
7
|
+
category: 'data',
|
|
8
|
+
display_name: 'Member Owner',
|
|
9
|
+
description: '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.',
|
|
10
|
+
parameter_schema: {
|
|
11
|
+
type: 'object',
|
|
12
|
+
properties: {
|
|
13
|
+
owner_field_name: {
|
|
14
|
+
type: 'string',
|
|
15
|
+
format: 'column-ref',
|
|
16
|
+
description: 'Column name for the owner reference',
|
|
17
|
+
default: 'owner_id'
|
|
18
|
+
},
|
|
19
|
+
entity_field_name: {
|
|
20
|
+
type: 'string',
|
|
21
|
+
format: 'column-ref',
|
|
22
|
+
description: 'Column name for the entity reference',
|
|
23
|
+
default: 'entity_id'
|
|
24
|
+
},
|
|
25
|
+
include_id: {
|
|
26
|
+
type: 'boolean',
|
|
27
|
+
description: 'If true, also adds a UUID primary key column with auto-generation',
|
|
28
|
+
default: true
|
|
29
|
+
},
|
|
30
|
+
include_user_fk: {
|
|
31
|
+
type: 'boolean',
|
|
32
|
+
description: 'If true, adds foreign key constraints from owner_id and entity_id to the users table',
|
|
33
|
+
default: true
|
|
34
|
+
},
|
|
35
|
+
create_index: {
|
|
36
|
+
type: 'boolean',
|
|
37
|
+
description: 'If true, creates B-tree indexes on the owner and entity columns',
|
|
38
|
+
default: true
|
|
39
|
+
},
|
|
40
|
+
membership_type: {
|
|
41
|
+
type: 'integer',
|
|
42
|
+
description: 'Membership type for SPRT resolution. Required for entity-scoped provisioning.',
|
|
43
|
+
default: null
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
tags: [
|
|
48
|
+
'ownership',
|
|
49
|
+
'membership',
|
|
50
|
+
'security',
|
|
51
|
+
'schema'
|
|
52
|
+
]
|
|
53
|
+
};
|
|
@@ -17,9 +17,10 @@ exports.DataStatusField = {
|
|
|
17
17
|
default: 'status'
|
|
18
18
|
},
|
|
19
19
|
type: {
|
|
20
|
-
type: '
|
|
21
|
-
description: 'Column type
|
|
22
|
-
|
|
20
|
+
type: 'object',
|
|
21
|
+
description: 'Column type as a FieldType object',
|
|
22
|
+
'x-codegen-type': 'FieldType',
|
|
23
|
+
default: { name: 'text' }
|
|
23
24
|
},
|
|
24
25
|
default_value: {
|
|
25
26
|
type: 'string',
|
package/data/data-tags.js
CHANGED
|
@@ -17,9 +17,10 @@ exports.DataTags = {
|
|
|
17
17
|
default: 'tags'
|
|
18
18
|
},
|
|
19
19
|
default_value: {
|
|
20
|
-
type: '
|
|
21
|
-
description: 'Default value
|
|
22
|
-
|
|
20
|
+
type: 'object',
|
|
21
|
+
description: 'Default value as a FieldDefault object',
|
|
22
|
+
'x-codegen-type': 'FieldDefault',
|
|
23
|
+
default: { value: [], cast: { name: 'citext', array_dimensions: 1 } }
|
|
23
24
|
},
|
|
24
25
|
is_required: {
|
|
25
26
|
type: 'boolean',
|
package/data/index.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ export { DataImmutableFields } from './data-immutable-fields';
|
|
|
12
12
|
export { DataInflection } from './data-inflection';
|
|
13
13
|
export { DataInheritFromParent } from './data-inherit-from-parent';
|
|
14
14
|
export { DataJsonb } from './data-jsonb';
|
|
15
|
+
export { DataMemberOwner } from './data-member-owner';
|
|
15
16
|
export { DataOwnedFields } from './data-owned-fields';
|
|
16
17
|
export { DataOwnershipInEntity } from './data-ownership-in-entity';
|
|
17
18
|
export { DataPeoplestamps } from './data-peoplestamps';
|
package/data/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.TableUserSettings = exports.TableUserProfiles = exports.TableOrganizationSettings = exports.SearchVector = exports.SearchUnified = exports.SearchTrgm = exports.SearchSpatialAggregate = exports.SearchSpatial = exports.SearchFullText = exports.SearchBm25 = exports.DataTimestamps = exports.DataTags = exports.DataStatusField = exports.DataSoftDelete = exports.DataSlug = exports.DataRealtime = exports.DataPublishable = exports.DataPeoplestamps = exports.DataOwnershipInEntity = exports.DataOwnedFields = exports.DataJsonb = exports.DataInheritFromParent = exports.DataInflection = exports.DataImmutableFields = exports.DataId = exports.DataForceCurrentUser = exports.DataEntityMembership = exports.DataDirectOwner = exports.DataCompositeField = exports.DataBulk = exports.CheckOneOf = exports.CheckNotEqual = exports.CheckLessThan = exports.CheckGreaterThan = void 0;
|
|
3
|
+
exports.TableUserSettings = exports.TableUserProfiles = exports.TableOrganizationSettings = exports.SearchVector = exports.SearchUnified = exports.SearchTrgm = exports.SearchSpatialAggregate = exports.SearchSpatial = exports.SearchFullText = exports.SearchBm25 = exports.DataTimestamps = exports.DataTags = exports.DataStatusField = exports.DataSoftDelete = exports.DataSlug = exports.DataRealtime = exports.DataPublishable = exports.DataPeoplestamps = exports.DataOwnershipInEntity = exports.DataOwnedFields = exports.DataMemberOwner = exports.DataJsonb = exports.DataInheritFromParent = exports.DataInflection = exports.DataImmutableFields = exports.DataId = exports.DataForceCurrentUser = exports.DataEntityMembership = exports.DataDirectOwner = exports.DataCompositeField = exports.DataBulk = exports.CheckOneOf = exports.CheckNotEqual = exports.CheckLessThan = exports.CheckGreaterThan = void 0;
|
|
4
4
|
var check_greater_than_1 = require("./check-greater-than");
|
|
5
5
|
Object.defineProperty(exports, "CheckGreaterThan", { enumerable: true, get: function () { return check_greater_than_1.CheckGreaterThan; } });
|
|
6
6
|
var check_less_than_1 = require("./check-less-than");
|
|
@@ -29,6 +29,8 @@ var data_inherit_from_parent_1 = require("./data-inherit-from-parent");
|
|
|
29
29
|
Object.defineProperty(exports, "DataInheritFromParent", { enumerable: true, get: function () { return data_inherit_from_parent_1.DataInheritFromParent; } });
|
|
30
30
|
var data_jsonb_1 = require("./data-jsonb");
|
|
31
31
|
Object.defineProperty(exports, "DataJsonb", { enumerable: true, get: function () { return data_jsonb_1.DataJsonb; } });
|
|
32
|
+
var data_member_owner_1 = require("./data-member-owner");
|
|
33
|
+
Object.defineProperty(exports, "DataMemberOwner", { enumerable: true, get: function () { return data_member_owner_1.DataMemberOwner; } });
|
|
32
34
|
var data_owned_fields_1 = require("./data-owned-fields");
|
|
33
35
|
Object.defineProperty(exports, "DataOwnedFields", { enumerable: true, get: function () { return data_owned_fields_1.DataOwnedFields; } });
|
|
34
36
|
var data_ownership_in_entity_1 = require("./data-ownership-in-entity");
|
|
@@ -9,25 +9,25 @@ export const AuthzAppMembership = {
|
|
|
9
9
|
properties: {
|
|
10
10
|
permission: {
|
|
11
11
|
type: 'string',
|
|
12
|
-
description: 'Single permission name to check (resolved to bitstring mask)'
|
|
12
|
+
description: 'Single permission name to check (resolved to bitstring mask)'
|
|
13
13
|
},
|
|
14
14
|
permissions: {
|
|
15
15
|
type: 'array',
|
|
16
16
|
items: {
|
|
17
|
-
type: 'string'
|
|
17
|
+
type: 'string'
|
|
18
18
|
},
|
|
19
|
-
description: 'Multiple permission names to check (ORed together into mask)'
|
|
19
|
+
description: 'Multiple permission names to check (ORed together into mask)'
|
|
20
20
|
},
|
|
21
21
|
is_admin: {
|
|
22
22
|
type: 'boolean',
|
|
23
|
-
description: 'If true, require is_admin flag'
|
|
23
|
+
description: 'If true, require is_admin flag'
|
|
24
24
|
},
|
|
25
25
|
is_owner: {
|
|
26
26
|
type: 'boolean',
|
|
27
|
-
description: 'If true, require is_owner flag'
|
|
28
|
-
}
|
|
27
|
+
description: 'If true, require is_owner flag'
|
|
28
|
+
}
|
|
29
29
|
},
|
|
30
|
-
required: []
|
|
30
|
+
required: []
|
|
31
31
|
},
|
|
32
|
-
tags: ['membership', 'authz']
|
|
32
|
+
tags: ['membership', 'authz']
|
|
33
33
|
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
export const AuthzMemberOwner = {
|
|
2
|
+
name: 'AuthzMemberOwner',
|
|
3
|
+
slug: 'authz_member_owner',
|
|
4
|
+
category: 'authz',
|
|
5
|
+
display_name: 'Member Owner',
|
|
6
|
+
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.',
|
|
7
|
+
parameter_schema: {
|
|
8
|
+
type: 'object',
|
|
9
|
+
properties: {
|
|
10
|
+
owner_field: {
|
|
11
|
+
type: 'string',
|
|
12
|
+
format: 'column-ref',
|
|
13
|
+
description: 'Column name containing the owner user ID (e.g., owner_id)',
|
|
14
|
+
default: 'owner_id'
|
|
15
|
+
},
|
|
16
|
+
entity_field: {
|
|
17
|
+
type: 'string',
|
|
18
|
+
format: 'column-ref',
|
|
19
|
+
description: 'Column name referencing the entity (e.g., entity_id)',
|
|
20
|
+
default: 'entity_id'
|
|
21
|
+
},
|
|
22
|
+
sel_field: {
|
|
23
|
+
type: 'string',
|
|
24
|
+
description: 'SPRT column to select for the entity match',
|
|
25
|
+
default: 'entity_id'
|
|
26
|
+
},
|
|
27
|
+
membership_type: {
|
|
28
|
+
type: ['integer', 'string'],
|
|
29
|
+
description: 'Scope: 1=app, 2=org, 3+=dynamic entity types (or string name resolved via membership_types_module)'
|
|
30
|
+
},
|
|
31
|
+
entity_type: {
|
|
32
|
+
type: 'string',
|
|
33
|
+
description: "Entity type prefix (e.g. 'channel', 'department'). Resolved to membership_type integer via memberships_module lookup."
|
|
34
|
+
},
|
|
35
|
+
permission: {
|
|
36
|
+
type: 'string',
|
|
37
|
+
description: 'Single permission name to check (resolved to bitstring mask)'
|
|
38
|
+
},
|
|
39
|
+
permissions: {
|
|
40
|
+
type: 'array',
|
|
41
|
+
items: { type: 'string' },
|
|
42
|
+
description: 'Multiple permission names to check (ORed together into mask)'
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
required: ['owner_field', 'entity_field']
|
|
46
|
+
},
|
|
47
|
+
tags: ['ownership', 'membership', 'authz']
|
|
48
|
+
};
|