@praxisui/visual-builder 8.0.0-beta.1 → 8.0.0-beta.12

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/README.md CHANGED
@@ -86,10 +86,38 @@ Use the canonical public services:
86
86
 
87
87
  Main exports available from `@praxisui/visual-builder`:
88
88
 
89
+ - Agentic authoring: `PRAXIS_VISUAL_BUILDER_AUTHORING_MANIFEST`
89
90
  - Components: `RuleEditorComponent`, `RuleCanvasComponent`, `RuleNodeComponent`, `FieldConditionEditorComponent`, `ConditionalValidatorEditorComponent`, `CollectionValidatorEditorComponent`, `MetadataEditorComponent`, `JsonViewerComponent`, `ExportDialogComponent`, `VisualRuleBuilderComponent`, `TemplateGalleryComponent`, `TemplateEditorDialogComponent`, `TemplatePreviewDialogComponent`, `RuleListComponent`, `ContextVariableManagerComponent`
90
91
  - Services: `RuleBuilderService`, `ExportIntegrationService`, `WebhookIntegrationService`, `RuleTemplateService`, `RuleValidationService`, `RuleNodeRegistryService`, `ContextManagementService`, `FieldSchemaService`
91
92
  - Models/Types: `FieldSchema`, `RuleBuilderConfig`, `ArrayFieldSchema`, `ContextScope`, `ContextEntry`, `ContextValue`
92
93
 
94
+ ## Agentic Authoring Contract
95
+
96
+ `PRAXIS_VISUAL_BUILDER_AUTHORING_MANIFEST` is the executable AI authoring contract for this package.
97
+
98
+ The manifest governs visual graph and JSON Logic orchestration:
99
+
100
+ - `node.add`
101
+ - `node.remove`
102
+ - `node.configure`
103
+ - `edge.connect`
104
+ - `edge.remove`
105
+ - `variable.add`
106
+ - `condition.set`
107
+ - `effect.set`
108
+ - `dsl.roundTrip.validate`
109
+
110
+ Boundary rules:
111
+
112
+ - `RuleBuilderState` is the visual source of truth
113
+ - operations write canonical runtime paths under `RuleBuilderState`, `RuleBuilderConfig`, `RuleNodeRegistryService` and `ContextManagementService`
114
+ - node ids and context variable scope/name are stable identities
115
+ - graph edges must reference existing nodes and avoid cycles where required
116
+ - conditions persist as JSON Logic objects, not JavaScript or legacy textual DSL
117
+ - effects must be constrained by target property schemas and `RULE_PROPERTY_SCHEMA`
118
+ - `dsl.roundTrip.validate` validates the JSON export/import path currently implemented by `RuleBuilderService`; form-config import remains supported but is not advertised as a round-trip export target by this operation
119
+ - component-specific configuration belongs to child component manifests
120
+
93
121
  ## Legacy Note
94
122
 
95
123
  The old textual `ExpressionEditorComponent` and DSL validation path were removed from the canonical library surface. Legacy DSL migration material should not be used as a baseline for new integrations.
@@ -13320,6 +13320,403 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
13320
13320
  type: Output
13321
13321
  }] } });
13322
13322
 
13323
+ const nodeAddSchema = {
13324
+ type: 'object',
13325
+ required: ['nodeId', 'nodeType'],
13326
+ properties: {
13327
+ nodeId: { type: 'string' },
13328
+ nodeType: {
13329
+ enum: [
13330
+ 'fieldCondition',
13331
+ 'propertyRule',
13332
+ 'andGroup',
13333
+ 'orGroup',
13334
+ 'notGroup',
13335
+ 'xorGroup',
13336
+ 'impliesGroup',
13337
+ 'requiredIf',
13338
+ 'visibleIf',
13339
+ 'disabledIf',
13340
+ 'readonlyIf',
13341
+ 'forEach',
13342
+ 'uniqueBy',
13343
+ 'minLength',
13344
+ 'maxLength',
13345
+ 'ifDefined',
13346
+ 'ifNotNull',
13347
+ 'ifExists',
13348
+ 'withDefault',
13349
+ 'functionCall',
13350
+ 'fieldToField',
13351
+ 'contextual',
13352
+ 'atLeast',
13353
+ 'exactly',
13354
+ 'expression',
13355
+ 'contextualTemplate',
13356
+ 'custom',
13357
+ ],
13358
+ },
13359
+ label: { type: 'string' },
13360
+ parentId: { type: 'string' },
13361
+ config: { type: 'object' },
13362
+ metadata: { type: 'object' },
13363
+ },
13364
+ };
13365
+ const nodeRemoveSchema = {
13366
+ type: 'object',
13367
+ required: ['nodeId'],
13368
+ properties: {
13369
+ nodeId: { type: 'string' },
13370
+ removeDescendants: { type: 'boolean' },
13371
+ preserveDisconnectedChildren: { type: 'boolean' },
13372
+ },
13373
+ };
13374
+ const nodeConfigureSchema = {
13375
+ type: 'object',
13376
+ required: ['nodeId'],
13377
+ properties: {
13378
+ nodeId: { type: 'string' },
13379
+ label: { type: 'string' },
13380
+ configPatch: { type: 'object' },
13381
+ metadataPatch: { type: 'object' },
13382
+ expanded: { type: 'boolean' },
13383
+ },
13384
+ };
13385
+ const edgeConnectSchema = {
13386
+ type: 'object',
13387
+ required: ['sourceNodeId', 'targetNodeId'],
13388
+ properties: {
13389
+ sourceNodeId: { type: 'string' },
13390
+ targetNodeId: { type: 'string' },
13391
+ edgeKind: { enum: ['child', 'condition', 'effect'] },
13392
+ insertIndex: { type: 'number' },
13393
+ },
13394
+ };
13395
+ const edgeRemoveSchema = {
13396
+ type: 'object',
13397
+ required: ['sourceNodeId', 'targetNodeId'],
13398
+ properties: {
13399
+ sourceNodeId: { type: 'string' },
13400
+ targetNodeId: { type: 'string' },
13401
+ edgeKind: { enum: ['child', 'condition', 'effect'] },
13402
+ removeOrphanTarget: { type: 'boolean' },
13403
+ },
13404
+ };
13405
+ const variableAddSchema = {
13406
+ type: 'object',
13407
+ required: ['name', 'scope', 'type'],
13408
+ properties: {
13409
+ name: { type: 'string' },
13410
+ scope: { type: 'string' },
13411
+ type: { enum: ['string', 'number', 'boolean', 'object', 'array'] },
13412
+ valueType: { enum: ['literal', 'field', 'context', 'function'] },
13413
+ defaultValue: {},
13414
+ description: { type: 'string' },
13415
+ },
13416
+ };
13417
+ const conditionSetSchema = {
13418
+ type: 'object',
13419
+ required: ['nodeId', 'condition'],
13420
+ properties: {
13421
+ nodeId: { type: 'string' },
13422
+ condition: { type: 'object' },
13423
+ mode: { enum: ['replace', 'merge'] },
13424
+ source: { enum: ['visual', 'jsonLogic'] },
13425
+ },
13426
+ };
13427
+ const effectSetSchema = {
13428
+ type: 'object',
13429
+ required: ['nodeId', 'targetType', 'targets', 'properties'],
13430
+ properties: {
13431
+ nodeId: { type: 'string' },
13432
+ targetType: { enum: ['field', 'section', 'action', 'row', 'column'] },
13433
+ targets: {
13434
+ type: 'array',
13435
+ items: { type: 'string' },
13436
+ },
13437
+ properties: { type: 'object' },
13438
+ propertiesWhenFalse: { type: 'object' },
13439
+ conditionNodeId: { type: 'string' },
13440
+ },
13441
+ };
13442
+ const dslRoundTripValidateSchema = {
13443
+ type: 'object',
13444
+ properties: {
13445
+ format: { enum: ['json'] },
13446
+ requireStableIds: { type: 'boolean' },
13447
+ compareMode: { enum: ['semantic', 'exact'] },
13448
+ },
13449
+ };
13450
+ const PRAXIS_VISUAL_BUILDER_AUTHORING_MANIFEST = {
13451
+ schemaVersion: '1.0.0',
13452
+ componentId: 'praxis-visual-builder',
13453
+ ownerPackage: '@praxisui/visual-builder',
13454
+ configSchemaId: 'RuleBuilderState',
13455
+ manifestVersion: '1.0.0',
13456
+ runtimeInputs: [
13457
+ { name: 'config', type: 'RuleBuilderConfig | null', description: 'Builder configuration with field schemas, target schemas, context variables, validation and export/import settings.' },
13458
+ { name: 'initialRules', type: 'RuleBuilderState | FormLayoutRule[] | JsonLogicExpression | null', description: 'Initial rules loaded into the visual builder.' },
13459
+ { name: 'rulesChanged', type: 'RuleBuilderState', description: 'Emitted visual builder state after graph or JSON Logic changes.' },
13460
+ { name: 'exportRequested', type: 'ExportOptions', description: 'Emitted export request for JSON, TypeScript or form-config payloads.' },
13461
+ { name: 'importRequested', type: 'ImportOptions', description: 'Emitted import request for JSON or form-config payloads.' },
13462
+ ],
13463
+ editableTargets: [
13464
+ { kind: 'node', resolver: 'rule-node-by-id', description: 'Visual rule graph node keyed by stable RuleNode.id.' },
13465
+ { kind: 'edge', resolver: 'rule-node-edge-by-source-target', description: 'Parent-child or semantic graph edge between existing rule nodes.' },
13466
+ { kind: 'variable', resolver: 'context-variable-by-name-scope', description: 'Context variable available to rule conditions and contextual nodes.' },
13467
+ { kind: 'condition', resolver: 'json-logic-condition-by-node', description: 'JSON Logic condition attached to a node or represented by condition nodes.' },
13468
+ { kind: 'effect', resolver: 'property-effect-by-node', description: 'Targeted property effect persisted as propertyRule/FormLayoutRule semantics.' },
13469
+ { kind: 'dslDocument', resolver: 'rule-builder-json-logic-document', description: 'Serialized JSON Logic/form-config document produced from the visual model.' },
13470
+ ],
13471
+ operations: [
13472
+ {
13473
+ operationId: 'node.add',
13474
+ title: 'Add visual rule node',
13475
+ scope: 'rules',
13476
+ targetKind: 'node',
13477
+ target: { kind: 'node', resolver: 'rule-node-by-id', ambiguityPolicy: 'fail', required: true },
13478
+ inputSchema: nodeAddSchema,
13479
+ effects: [{ kind: 'compile-domain-patch', handler: 'visual-builder-node-add', handlerContract: {
13480
+ reads: ['RuleBuilderState.nodes', 'RuleBuilderState.rootNodes', 'RuleNodeRegistryService', 'RuleBuilderService.addNode'],
13481
+ writes: ['RuleBuilderState.nodes', 'RuleBuilderState.rootNodes', 'RuleNodeRegistryService'],
13482
+ identityKeys: ['nodeId'],
13483
+ inputSchema: nodeAddSchema,
13484
+ failureModes: ['duplicate-node-id', 'unsupported-node-type', 'parent-node-not-found', 'graph-cycle-created'],
13485
+ description: 'Adds a rule node by stable id and validates graph integrity before the state can be serialized.',
13486
+ } }],
13487
+ validators: ['node-id-unique', 'node-type-supported', 'parent-node-exists', 'graph-valid', 'dsl-round-trip-stable'],
13488
+ affectedPaths: ['RuleBuilderState.nodes', 'RuleBuilderState.rootNodes', 'RuleNodeRegistryService'],
13489
+ submissionImpact: 'config-only',
13490
+ preconditions: ['rule-builder-state-loaded'],
13491
+ destructive: false,
13492
+ requiresConfirmation: false,
13493
+ },
13494
+ {
13495
+ operationId: 'node.remove',
13496
+ title: 'Remove visual rule node',
13497
+ scope: 'rules',
13498
+ targetKind: 'node',
13499
+ target: { kind: 'node', resolver: 'rule-node-by-id', ambiguityPolicy: 'fail', required: true },
13500
+ inputSchema: nodeRemoveSchema,
13501
+ effects: [{ kind: 'compile-domain-patch', handler: 'visual-builder-node-remove', handlerContract: {
13502
+ reads: ['RuleBuilderState.nodes', 'RuleBuilderState.rootNodes', 'RuleNodeRegistryService', 'RuleBuilderService.removeNode'],
13503
+ writes: ['RuleBuilderState.nodes', 'RuleBuilderState.rootNodes', 'RuleNodeRegistryService'],
13504
+ identityKeys: ['nodeId'],
13505
+ inputSchema: nodeRemoveSchema,
13506
+ failureModes: ['node-not-found', 'destructive-removal-not-confirmed', 'orphaned-edge-created', 'dsl-round-trip-failed'],
13507
+ description: 'Removes a node and governed descendants by id, requiring confirmation because conditions/effects can be lost.',
13508
+ } }],
13509
+ destructive: true,
13510
+ requiresConfirmation: true,
13511
+ validators: ['node-exists', 'destructive-removal-confirmed', 'edges-reference-existing-nodes', 'dsl-round-trip-stable'],
13512
+ affectedPaths: ['RuleBuilderState.nodes', 'RuleBuilderState.rootNodes', 'RuleNodeRegistryService'],
13513
+ submissionImpact: 'config-only',
13514
+ preconditions: ['rule-builder-state-loaded', 'explicit-confirmation-provided'],
13515
+ },
13516
+ {
13517
+ operationId: 'node.configure',
13518
+ title: 'Configure visual rule node',
13519
+ scope: 'rules',
13520
+ targetKind: 'node',
13521
+ target: { kind: 'node', resolver: 'rule-node-by-id', ambiguityPolicy: 'fail', required: true },
13522
+ inputSchema: nodeConfigureSchema,
13523
+ effects: [{ kind: 'compile-domain-patch', handler: 'visual-builder-node-configure', handlerContract: {
13524
+ reads: ['RuleBuilderState.nodes', 'RuleBuilderService.updateNode', 'RuleNodeRegistryService'],
13525
+ writes: ['RuleBuilderState.nodes', 'RuleBuilderState.currentJSON'],
13526
+ identityKeys: ['nodeId'],
13527
+ inputSchema: nodeConfigureSchema,
13528
+ failureModes: ['node-not-found', 'config-shape-invalid', 'node-type-config-mismatch', 'dsl-round-trip-failed'],
13529
+ description: 'Applies a typed patch to a rule node while preserving node identity and JSON Logic serialization.',
13530
+ } }],
13531
+ validators: ['node-exists', 'node-config-compatible', 'graph-valid', 'dsl-round-trip-stable'],
13532
+ affectedPaths: ['RuleBuilderState.nodes', 'RuleBuilderState.currentJSON'],
13533
+ submissionImpact: 'config-only',
13534
+ preconditions: ['rule-builder-state-loaded'],
13535
+ destructive: false,
13536
+ requiresConfirmation: false,
13537
+ },
13538
+ {
13539
+ operationId: 'edge.connect',
13540
+ title: 'Connect visual graph edge',
13541
+ scope: 'interaction',
13542
+ targetKind: 'edge',
13543
+ target: { kind: 'edge', resolver: 'rule-node-edge-by-source-target', ambiguityPolicy: 'fail', required: true },
13544
+ inputSchema: edgeConnectSchema,
13545
+ effects: [{ kind: 'compile-domain-patch', handler: 'visual-builder-edge-connect', handlerContract: {
13546
+ reads: ['RuleBuilderState.nodes', 'RuleNodeRegistryService.validateIntegrity'],
13547
+ writes: ['RuleBuilderState.nodes[].children', 'RuleBuilderState.nodes[].parentId'],
13548
+ identityKeys: ['sourceNodeId', 'targetNodeId', 'edgeKind'],
13549
+ inputSchema: edgeConnectSchema,
13550
+ failureModes: ['source-node-not-found', 'target-node-not-found', 'duplicate-edge', 'graph-cycle-created'],
13551
+ description: 'Connects two existing nodes and rejects edges that break registry integrity or acyclic graph requirements.',
13552
+ } }],
13553
+ validators: ['node-exists', 'edges-reference-existing-nodes', 'graph-acyclic-where-required', 'dsl-round-trip-stable'],
13554
+ affectedPaths: ['RuleBuilderState.nodes[].children', 'RuleBuilderState.nodes[].parentId'],
13555
+ submissionImpact: 'config-only',
13556
+ preconditions: ['rule-builder-state-loaded'],
13557
+ destructive: false,
13558
+ requiresConfirmation: false,
13559
+ },
13560
+ {
13561
+ operationId: 'edge.remove',
13562
+ title: 'Remove visual graph edge',
13563
+ scope: 'interaction',
13564
+ targetKind: 'edge',
13565
+ target: { kind: 'edge', resolver: 'rule-node-edge-by-source-target', ambiguityPolicy: 'fail', required: true },
13566
+ inputSchema: edgeRemoveSchema,
13567
+ effects: [{ kind: 'compile-domain-patch', handler: 'visual-builder-edge-remove', handlerContract: {
13568
+ reads: ['RuleBuilderState.nodes', 'RuleNodeRegistryService.validateIntegrity'],
13569
+ writes: ['RuleBuilderState.nodes[].children', 'RuleBuilderState.nodes[].parentId'],
13570
+ identityKeys: ['sourceNodeId', 'targetNodeId', 'edgeKind'],
13571
+ inputSchema: edgeRemoveSchema,
13572
+ failureModes: ['edge-not-found', 'destructive-removal-not-confirmed', 'orphaned-node-created', 'dsl-round-trip-failed'],
13573
+ description: 'Removes a graph edge by source and target ids with confirmation when the target can become orphaned.',
13574
+ } }],
13575
+ destructive: true,
13576
+ requiresConfirmation: true,
13577
+ validators: ['edge-exists', 'destructive-removal-confirmed', 'graph-valid', 'dsl-round-trip-stable'],
13578
+ affectedPaths: ['RuleBuilderState.nodes[].children', 'RuleBuilderState.nodes[].parentId'],
13579
+ submissionImpact: 'config-only',
13580
+ preconditions: ['rule-builder-state-loaded', 'explicit-confirmation-provided'],
13581
+ },
13582
+ {
13583
+ operationId: 'variable.add',
13584
+ title: 'Add context variable',
13585
+ scope: 'dataBinding',
13586
+ targetKind: 'variable',
13587
+ target: { kind: 'variable', resolver: 'context-variable-by-name-scope', ambiguityPolicy: 'fail', required: true },
13588
+ inputSchema: variableAddSchema,
13589
+ effects: [{ kind: 'compile-domain-patch', handler: 'visual-builder-variable-add', handlerContract: {
13590
+ reads: ['RuleBuilderConfig.contextVariables', 'ContextManagementService'],
13591
+ writes: ['RuleBuilderConfig.contextVariables', 'ContextManagementService'],
13592
+ identityKeys: ['scope', 'name'],
13593
+ inputSchema: variableAddSchema,
13594
+ failureModes: ['duplicate-variable', 'scope-not-found', 'variable-type-invalid', 'context-token-conflict'],
13595
+ description: 'Adds a governed context variable that can be referenced by contextual and field condition nodes.',
13596
+ } }],
13597
+ validators: ['variable-id-unique', 'variable-scope-exists', 'context-variable-reference-valid', 'dsl-round-trip-stable'],
13598
+ affectedPaths: ['RuleBuilderConfig.contextVariables', 'ContextManagementService'],
13599
+ submissionImpact: 'config-only',
13600
+ preconditions: ['rule-builder-config-loaded'],
13601
+ destructive: false,
13602
+ requiresConfirmation: false,
13603
+ },
13604
+ {
13605
+ operationId: 'condition.set',
13606
+ title: 'Set JSON Logic condition',
13607
+ scope: 'rules',
13608
+ targetKind: 'condition',
13609
+ target: { kind: 'condition', resolver: 'json-logic-condition-by-node', ambiguityPolicy: 'fail', required: true },
13610
+ inputSchema: conditionSetSchema,
13611
+ effects: [{ kind: 'compile-domain-patch', handler: 'visual-builder-condition-set', handlerContract: {
13612
+ reads: ['RuleBuilderState.nodes', 'RuleBuilderService.loadFromConditionExpression', 'RuleBuilderService.buildConditionExpressionFromGraph'],
13613
+ writes: ['RuleBuilderState.nodes[].config.condition', 'RuleBuilderState.currentJSON'],
13614
+ identityKeys: ['nodeId'],
13615
+ inputSchema: conditionSetSchema,
13616
+ failureModes: ['node-not-found', 'json-logic-invalid', 'unsupported-operator', 'visual-parse-failed', 'dsl-round-trip-failed'],
13617
+ description: 'Sets a canonical JSON Logic condition and proves it can parse back into the visual graph.',
13618
+ } }],
13619
+ validators: ['json-logic-valid', 'condition-operators-supported', 'condition-fields-known', 'dsl-round-trip-stable'],
13620
+ affectedPaths: ['RuleBuilderState.nodes[].config.condition', 'RuleBuilderState.currentJSON'],
13621
+ submissionImpact: 'config-only',
13622
+ preconditions: ['rule-builder-state-loaded'],
13623
+ destructive: false,
13624
+ requiresConfirmation: false,
13625
+ },
13626
+ {
13627
+ operationId: 'effect.set',
13628
+ title: 'Set visual property effect',
13629
+ scope: 'rules',
13630
+ targetKind: 'effect',
13631
+ target: { kind: 'effect', resolver: 'property-effect-by-node', ambiguityPolicy: 'fail', required: true },
13632
+ inputSchema: effectSetSchema,
13633
+ effects: [{ kind: 'compile-domain-patch', handler: 'visual-builder-effect-set', handlerContract: {
13634
+ reads: ['RuleBuilderState.nodes', 'RuleBuilderConfig.targetPropertySchemas', 'RULE_PROPERTY_SCHEMA', 'RuleBuilderService.export'],
13635
+ writes: ['RuleBuilderState.nodes[].config.targetType', 'RuleBuilderState.nodes[].config.targets', 'RuleBuilderState.nodes[].config.properties', 'RuleBuilderState.nodes[].config.propertiesWhenFalse', 'RuleBuilderState.currentJSON'],
13636
+ identityKeys: ['nodeId', 'targetType', 'targets'],
13637
+ inputSchema: effectSetSchema,
13638
+ failureModes: ['node-not-found', 'target-not-found', 'property-not-allowed-for-target', 'effect-value-invalid', 'dsl-round-trip-failed'],
13639
+ description: 'Sets a property effect using governed target property schemas so export to FormLayoutRule remains deterministic.',
13640
+ } }],
13641
+ validators: ['effect-targets-exist', 'effect-properties-governed', 'effect-values-valid', 'dsl-round-trip-stable'],
13642
+ affectedPaths: ['RuleBuilderState.nodes[].config.targetType', 'RuleBuilderState.nodes[].config.targets', 'RuleBuilderState.nodes[].config.properties', 'RuleBuilderState.nodes[].config.propertiesWhenFalse', 'RuleBuilderState.currentJSON'],
13643
+ submissionImpact: 'affects-schema-backed-data',
13644
+ preconditions: ['rule-builder-state-loaded', 'target-schema-loaded'],
13645
+ destructive: false,
13646
+ requiresConfirmation: false,
13647
+ },
13648
+ {
13649
+ operationId: 'dsl.roundTrip.validate',
13650
+ title: 'Validate visual and DSL round trip',
13651
+ scope: 'runtimeCoverage',
13652
+ targetKind: 'dslDocument',
13653
+ target: { kind: 'dslDocument', resolver: 'rule-builder-json-logic-document', ambiguityPolicy: 'fail', required: false },
13654
+ inputSchema: dslRoundTripValidateSchema,
13655
+ effects: [{ kind: 'compile-domain-patch', handler: 'visual-builder-dsl-round-trip-validate', handlerContract: {
13656
+ reads: ['RuleBuilderState', 'RuleBuilderService.export', 'RuleBuilderService.import', 'RuleBuilderService.buildConditionExpressionFromGraph', 'RuleNodeRegistryService.validateIntegrity'],
13657
+ writes: ['RuleBuilderState.validationErrors', 'RuleBuilderState.currentJSON'],
13658
+ identityKeys: ['format', 'compareMode'],
13659
+ inputSchema: dslRoundTripValidateSchema,
13660
+ failureModes: ['graph-invalid', 'export-failed', 'import-failed', 'semantic-drift', 'unstable-node-identity'],
13661
+ description: 'Exports the visual model to JSON, imports it back and rejects semantic drift or unstable identity.',
13662
+ } }],
13663
+ validators: ['graph-valid', 'dsl-round-trip-stable', 'json-logic-valid', 'registry-integrity-valid'],
13664
+ affectedPaths: ['RuleBuilderState.currentJSON', 'RuleBuilderState.validationErrors'],
13665
+ submissionImpact: 'none',
13666
+ preconditions: ['rule-builder-state-loaded'],
13667
+ destructive: false,
13668
+ requiresConfirmation: false,
13669
+ },
13670
+ ],
13671
+ validators: [
13672
+ { validatorId: 'node-id-unique', level: 'error', code: 'VISUAL_BUILDER_NODE_ID_UNIQUE', description: 'Rule node ids must be unique and stable.' },
13673
+ { validatorId: 'node-exists', level: 'error', code: 'VISUAL_BUILDER_NODE_EXISTS', description: 'Target node must exist before it is configured or removed.' },
13674
+ { validatorId: 'node-type-supported', level: 'error', code: 'VISUAL_BUILDER_NODE_TYPE_SUPPORTED', description: 'Node type must be supported by the rule node registry and visual editor.' },
13675
+ { validatorId: 'node-config-compatible', level: 'error', code: 'VISUAL_BUILDER_NODE_CONFIG_COMPATIBLE', description: 'Node config must match the declared node type.' },
13676
+ { validatorId: 'parent-node-exists', level: 'error', code: 'VISUAL_BUILDER_PARENT_NODE_EXISTS', description: 'Parent node must exist when adding a child node.' },
13677
+ { validatorId: 'edge-exists', level: 'error', code: 'VISUAL_BUILDER_EDGE_EXISTS', description: 'Target edge must exist before removal.' },
13678
+ { validatorId: 'edges-reference-existing-nodes', level: 'error', code: 'VISUAL_BUILDER_EDGES_REFERENCE_NODES', description: 'Every edge must reference existing source and target nodes.' },
13679
+ { validatorId: 'graph-valid', level: 'error', code: 'VISUAL_BUILDER_GRAPH_VALID', description: 'Graph structure must pass registry integrity validation.' },
13680
+ { validatorId: 'graph-acyclic-where-required', level: 'error', code: 'VISUAL_BUILDER_GRAPH_ACYCLIC', description: 'Hierarchical rule graph edges must not introduce cycles.' },
13681
+ { validatorId: 'destructive-removal-confirmed', level: 'error', code: 'VISUAL_BUILDER_DESTRUCTIVE_REMOVAL_CONFIRMED', description: 'Destructive node or edge removal requires explicit confirmation.' },
13682
+ { validatorId: 'variable-id-unique', level: 'error', code: 'VISUAL_BUILDER_VARIABLE_ID_UNIQUE', description: 'Context variable name and scope must be unique.' },
13683
+ { validatorId: 'variable-scope-exists', level: 'error', code: 'VISUAL_BUILDER_VARIABLE_SCOPE_EXISTS', description: 'Context variable scope must exist in ContextManagementService before variables are added.' },
13684
+ { validatorId: 'context-variable-reference-valid', level: 'error', code: 'VISUAL_BUILDER_CONTEXT_VARIABLE_VALID', description: 'Context variable references must resolve to declared variables.' },
13685
+ { validatorId: 'json-logic-valid', level: 'error', code: 'VISUAL_BUILDER_JSON_LOGIC_VALID', description: 'Conditions must be valid JSON Logic objects, not JavaScript or legacy textual DSL.' },
13686
+ { validatorId: 'condition-operators-supported', level: 'error', code: 'VISUAL_BUILDER_CONDITION_OPERATORS_SUPPORTED', description: 'Condition operators must be supported by visual parsing and export.' },
13687
+ { validatorId: 'condition-fields-known', level: 'error', code: 'VISUAL_BUILDER_CONDITION_FIELDS_KNOWN', description: 'Condition field references must resolve to configured field schemas or context variables.' },
13688
+ { validatorId: 'effect-targets-exist', level: 'error', code: 'VISUAL_BUILDER_EFFECT_TARGETS_EXIST', description: 'Effect targets must exist in configured target schemas.' },
13689
+ { validatorId: 'effect-properties-governed', level: 'error', code: 'VISUAL_BUILDER_EFFECT_PROPERTIES_GOVERNED', description: 'Effect properties must be allowed for the target type.' },
13690
+ { validatorId: 'effect-values-valid', level: 'error', code: 'VISUAL_BUILDER_EFFECT_VALUES_VALID', description: 'Effect property values must satisfy target property schema types.' },
13691
+ { validatorId: 'registry-integrity-valid', level: 'error', code: 'VISUAL_BUILDER_REGISTRY_INTEGRITY_VALID', description: 'RuleNodeRegistryService integrity checks must pass.' },
13692
+ { validatorId: 'dsl-round-trip-stable', level: 'error', code: 'VISUAL_BUILDER_DSL_ROUND_TRIP_STABLE', description: 'Serialized JSON output must import back to the same semantic visual model.' },
13693
+ ],
13694
+ roundTripRequirements: [
13695
+ 'RuleBuilderState is the visual source of truth; JSON export must import back without semantic drift.',
13696
+ 'RuleNode.id and context variable scope/name are canonical identities; array indexes are not canonical identities.',
13697
+ 'Edges must reference existing nodes and must not create cycles in hierarchical rule graphs.',
13698
+ 'Conditions are canonical JSON Logic objects. JavaScript expressions and legacy textual DSL must not be introduced as persisted authoring payloads.',
13699
+ 'Effects must be constrained by target property schemas and RULE_PROPERTY_SCHEMA so exported FormLayoutRule payloads stay deterministic.',
13700
+ 'Component-specific configuration belongs to child component manifests; visual-builder owns graph, JSON Logic, variables and property-effect orchestration.',
13701
+ ],
13702
+ examples: [
13703
+ { id: 'add-field-condition', request: 'Add a condition that age is greater than 18.', operationId: 'node.add', params: { nodeId: 'age-gt-18', nodeType: 'fieldCondition', label: 'Age over 18', config: { type: 'fieldCondition', fieldName: 'age', operator: 'gt', value: 18 } }, isPositive: true },
13704
+ { id: 'add-property-rule', request: 'Add a rule that hides the spouse section.', operationId: 'node.add', params: { nodeId: 'hide-spouse-section', nodeType: 'propertyRule', config: { type: 'propertyRule', targetType: 'section', targets: ['spouse'], properties: { visible: false } } }, isPositive: true },
13705
+ { id: 'configure-node', request: 'Rename the eligibility rule and mark it expanded.', operationId: 'node.configure', params: { nodeId: 'eligibility', label: 'Eligibility rule', expanded: true }, isPositive: true },
13706
+ { id: 'connect-edge', request: 'Make the age condition a child of the AND group.', operationId: 'edge.connect', params: { sourceNodeId: 'eligibility-and', targetNodeId: 'age-gt-18', edgeKind: 'child' }, isPositive: true },
13707
+ { id: 'remove-edge', request: 'Disconnect the age condition from the AND group.', operationId: 'edge.remove', params: { sourceNodeId: 'eligibility-and', targetNodeId: 'age-gt-18', edgeKind: 'child' }, isPositive: true },
13708
+ { id: 'add-variable', request: 'Add a global variable for current tenant.', operationId: 'variable.add', params: { name: 'tenantId', scope: 'global', type: 'string', valueType: 'context', description: 'Current tenant id' }, isPositive: true },
13709
+ { id: 'set-condition', request: 'Set this condition to require country equal Brazil.', operationId: 'condition.set', params: { nodeId: 'country-br', condition: { '===': [{ var: 'country' }, 'BR'] }, source: 'jsonLogic' }, isPositive: true },
13710
+ { id: 'set-effect', request: 'Make the salary field readonly when the condition is true.', operationId: 'effect.set', params: { nodeId: 'salary-readonly', targetType: 'field', targets: ['salary'], properties: { readonly: true } }, isPositive: true },
13711
+ { id: 'validate-round-trip', request: 'Validate that this graph exports and imports without drift.', operationId: 'dsl.roundTrip.validate', params: { format: 'json', requireStableIds: true, compareMode: 'semantic' }, isPositive: true },
13712
+ { id: 'reject-duplicate-node', request: 'Add another node with id age-gt-18.', operationId: 'node.add', params: { nodeId: 'age-gt-18', nodeType: 'fieldCondition' }, isPositive: false },
13713
+ { id: 'reject-cycle', request: 'Connect a child back to its parent and create a cycle.', operationId: 'edge.connect', params: { sourceNodeId: 'age-gt-18', targetNodeId: 'eligibility-and', edgeKind: 'child' }, isPositive: false },
13714
+ { id: 'reject-javascript-condition', request: 'Use age > 18 as a JavaScript expression.', operationId: 'condition.set', params: { nodeId: 'age-gt-18', condition: 'age > 18' }, isPositive: false },
13715
+ { id: 'reject-unknown-effect-property', request: 'Set an unknown field property named sparkle.', operationId: 'effect.set', params: { nodeId: 'sparkle-field', targetType: 'field', targets: ['name'], properties: { sparkle: true } }, isPositive: false },
13716
+ { id: 'reject-drift', request: 'Accept the graph even though export/import changes node meaning.', operationId: 'dsl.roundTrip.validate', params: { format: 'json', compareMode: 'exact' }, isPositive: false },
13717
+ ],
13718
+ };
13719
+
13323
13720
  /**
13324
13721
  * Array Field Schema Support for Collection Validators
13325
13722
  * Phase 2 Implementation
@@ -20427,4 +20824,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.17", ngImpo
20427
20824
  * Generated bundle index. Do not edit.
20428
20825
  */
20429
20826
 
20430
- export { ArrayFieldAnalyzer, CollectionValidatorEditorComponent, ConditionalValidatorEditorComponent, ConditionalValidatorType, ConfigurationError, ContextError, ContextManagementService, ConversionError, ErrorCategory, ErrorHandler, ErrorSeverity, ExportDialogComponent, ExportIntegrationService, ExpressionError, FIELD_TYPE_OPERATORS, FieldConditionEditorComponent, FieldSchemaService, FieldType, InternalError, JsonViewerComponent, MetadataEditorComponent, OPERATOR_LABELS, PraxisVisualBuilder, RegistryError, RuleBuilderService, RuleCanvasComponent, RuleEditorComponent, RuleListComponent, RuleNodeComponent, RuleNodeRegistryService, RuleNodeType, RuleTemplateService, RuleValidationService, TemplateEditorDialogComponent, TemplateGalleryComponent, TemplatePreviewDialogComponent, ValidationError as VBValidationError, ValidationCategory, ValidationSeverity, VisualBuilderError, VisualRuleBuilderComponent, WebhookIntegrationService, createError, getArrayItemFieldPaths, globalErrorHandler, isArrayFieldSchema };
20827
+ export { ArrayFieldAnalyzer, CollectionValidatorEditorComponent, ConditionalValidatorEditorComponent, ConditionalValidatorType, ConfigurationError, ContextError, ContextManagementService, ConversionError, ErrorCategory, ErrorHandler, ErrorSeverity, ExportDialogComponent, ExportIntegrationService, ExpressionError, FIELD_TYPE_OPERATORS, FieldConditionEditorComponent, FieldSchemaService, FieldType, InternalError, JsonViewerComponent, MetadataEditorComponent, OPERATOR_LABELS, PRAXIS_VISUAL_BUILDER_AUTHORING_MANIFEST, PraxisVisualBuilder, RegistryError, RuleBuilderService, RuleCanvasComponent, RuleEditorComponent, RuleListComponent, RuleNodeComponent, RuleNodeRegistryService, RuleNodeType, RuleTemplateService, RuleValidationService, TemplateEditorDialogComponent, TemplateGalleryComponent, TemplatePreviewDialogComponent, ValidationError as VBValidationError, ValidationCategory, ValidationSeverity, VisualBuilderError, VisualRuleBuilderComponent, WebhookIntegrationService, createError, getArrayItemFieldPaths, globalErrorHandler, isArrayFieldSchema };
package/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { EventEmitter, OnInit, OnDestroy, OnChanges, AfterViewInit, ElementRef, ChangeDetectorRef, SimpleChanges } from '@angular/core';
3
- import { JsonLogicExpression, FormLayoutRule, RulePropertySchema, PraxisI18nService } from '@praxisui/core';
3
+ import { JsonLogicExpression, ComponentAuthoringManifest, FormLayoutRule, RulePropertySchema, PraxisI18nService } from '@praxisui/core';
4
4
  import { Observable } from 'rxjs';
5
5
  import { MatDialog, MatDialogRef } from '@angular/material/dialog';
6
6
  import { MatSnackBar } from '@angular/material/snack-bar';
@@ -630,6 +630,8 @@ declare class PraxisVisualBuilder {
630
630
  static ɵcmp: i0.ɵɵComponentDeclaration<PraxisVisualBuilder, "praxis-visual-builder", never, { "config": { "alias": "config"; "required": false; }; "initialRules": { "alias": "initialRules"; "required": false; }; }, { "rulesChanged": "rulesChanged"; "exportRequested": "exportRequested"; "importRequested": "importRequested"; }, never, never, true, never>;
631
631
  }
632
632
 
633
+ declare const PRAXIS_VISUAL_BUILDER_AUTHORING_MANIFEST: ComponentAuthoringManifest;
634
+
633
635
  /**
634
636
  * Field schema model for dynamic field configuration in the Visual Builder
635
637
  */
@@ -2905,5 +2907,5 @@ declare class RuleListComponent {
2905
2907
  static ɵcmp: i0.ɵɵComponentDeclaration<RuleListComponent, "praxis-rule-list", never, { "rules": { "alias": "rules"; "required": false; }; "selectedRuleId": { "alias": "selectedRuleId"; "required": false; }; "nodeMap": { "alias": "nodeMap"; "required": false; }; "validationErrors": { "alias": "validationErrors"; "required": false; }; }, { "ruleSelected": "ruleSelected"; "ruleDeleted": "ruleDeleted"; "ruleDuplicated": "ruleDuplicated"; "ruleAdded": "ruleAdded"; "aiRequested": "aiRequested"; }, never, never, true, never>;
2906
2908
  }
2907
2909
 
2908
- export { ArrayFieldAnalyzer, CollectionValidatorEditorComponent, ConditionalValidatorEditorComponent, ConditionalValidatorType, ConfigurationError, ContextError, ContextManagementService, ConversionError, ErrorCategory, ErrorHandler, ErrorSeverity, ExportDialogComponent, ExportIntegrationService, ExpressionError, FIELD_TYPE_OPERATORS, FieldConditionEditorComponent, FieldSchemaService, FieldType, InternalError, JsonViewerComponent, MetadataEditorComponent, OPERATOR_LABELS, PraxisVisualBuilder, RegistryError, RuleBuilderService, RuleCanvasComponent, RuleEditorComponent, RuleListComponent, RuleNodeComponent, RuleNodeRegistryService, RuleNodeType, RuleTemplateService, RuleValidationService, TemplateEditorDialogComponent, TemplateGalleryComponent, TemplatePreviewDialogComponent, ValidationError as VBValidationError, ValidationCategory, ValidationSeverity, VisualBuilderError, VisualRuleBuilderComponent, WebhookIntegrationService, createError, getArrayItemFieldPaths, globalErrorHandler, isArrayFieldSchema };
2910
+ export { ArrayFieldAnalyzer, CollectionValidatorEditorComponent, ConditionalValidatorEditorComponent, ConditionalValidatorType, ConfigurationError, ContextError, ContextManagementService, ConversionError, ErrorCategory, ErrorHandler, ErrorSeverity, ExportDialogComponent, ExportIntegrationService, ExpressionError, FIELD_TYPE_OPERATORS, FieldConditionEditorComponent, FieldSchemaService, FieldType, InternalError, JsonViewerComponent, MetadataEditorComponent, OPERATOR_LABELS, PRAXIS_VISUAL_BUILDER_AUTHORING_MANIFEST, PraxisVisualBuilder, RegistryError, RuleBuilderService, RuleCanvasComponent, RuleEditorComponent, RuleListComponent, RuleNodeComponent, RuleNodeRegistryService, RuleNodeType, RuleTemplateService, RuleValidationService, TemplateEditorDialogComponent, TemplateGalleryComponent, TemplatePreviewDialogComponent, ValidationError as VBValidationError, ValidationCategory, ValidationSeverity, VisualBuilderError, VisualRuleBuilderComponent, WebhookIntegrationService, createError, getArrayItemFieldPaths, globalErrorHandler, isArrayFieldSchema };
2909
2911
  export type { ArrayCollectionValidationRule, ArrayFieldSchema, ArrayValidationContext, ArrayValidationError, BooleanGroupConfig, CardinalityConfig, CircularReference, CleanupResult, CollectionValidationConfig, CollectionValidatorConfig, ConditionalValidatorConfig, ConditionalValidatorPreview, ContextEntry, ContextScope, ContextValue, ContextVariable, ContextualConfig, ContextualTemplateConfig, CustomConfig, CustomFunction, DocumentationLink, EnhancedFieldSchema, ErrorInfo, ErrorStatistics, ExportDialogData, ExportFormat, ExportOptions, ExportResult, ExpressionConfig, ExternalSystemConfig, FieldConditionConfig, FieldFormat, FieldOption, FieldSchema, FieldSchemaContext, FieldToFieldConfig, FieldUIConfig, FunctionCallConfig, FunctionParameter, ImportOptions, IntegrationEndpoint, IntegrationResult, MemoryStats, OptionalFieldConfig, PropertyRuleConfig, RegistryIntegrityResult, RegistryValidationResult, RuleBuilderConfig, RuleBuilderSnapshot, RuleBuilderState, RuleContextProvider, RuleFunctionRegistry, RuleNode, RuleNodeConfig, RuleNodeTree, RuleNodeTypeString, RuleTemplate, RuleValidationResult, SpecificationMetadata, TemplateApplicationResult, TemplateCategory, TemplateDisplayMode, TemplateEditorDialogData, TemplateEditorResult, TemplateMetadata, TemplatePreviewDialogData, TemplateSearchCriteria, TemplateSortOption, TemplateStats, TemplateValidationResult, ValidComparisonOperator, ValidationConfig, ValidationContext, ValidationError$1 as ValidationError, ValidationIssue, ValidationResult, ValidationRule, ValueType, WebhookConfig, WebhookDelivery, WebhookEvent, WebhookStats };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@praxisui/visual-builder",
3
- "version": "8.0.0-beta.1",
3
+ "version": "8.0.0-beta.12",
4
4
  "description": "Visual rule and expression builder for Praxis UI with JSON Logic authoring, validation and context variables.",
5
5
  "peerDependencies": {
6
6
  "@angular/common": "^20.0.0",
@@ -8,7 +8,7 @@
8
8
  "@angular/cdk": "^20.0.0",
9
9
  "@angular/material": "^20.0.0",
10
10
  "@angular/forms": "^20.0.0",
11
- "@praxisui/settings-panel": "^8.0.0-beta.1"
11
+ "@praxisui/settings-panel": "^8.0.0-beta.12"
12
12
  },
13
13
  "dependencies": {
14
14
  "tslib": "^2.3.0",