@vidyano-labs/virtual-service 0.3.0 → 0.4.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 (4) hide show
  1. package/README.md +283 -210
  2. package/index.d.ts +376 -150
  3. package/index.js +1420 -1649
  4. package/package.json +2 -2
package/index.d.ts CHANGED
@@ -1,10 +1,97 @@
1
- import { Dto, ServiceHooks, Service, Application } from '@vidyano/core';
1
+ import { ServiceHooks, Dto, Service, Application } from '@vidyano/core';
2
+
3
+ /**
4
+ * Virtual implementation of ServiceHooks for testing without a backend
5
+ */
6
+ declare class VirtualServiceHooks extends ServiceHooks {
7
+ #private;
8
+ constructor();
9
+ /** @internal */
10
+ initialize(service: VirtualService): void;
11
+ /**
12
+ * Intercepts fetch requests and routes them to virtual handlers
13
+ */
14
+ onFetch(request: Request): Promise<Response>;
15
+ }
16
+
17
+ /**
18
+ * VirtualQueryColumn combines a QueryColumnDto with helper methods
19
+ */
20
+ type VirtualQueryColumn = Dto.QueryColumnDto & {
21
+ /**
22
+ * Reference to config metadata (internal use)
23
+ */
24
+ readonly __configMeta?: {
25
+ canSort?: boolean;
26
+ };
27
+ /**
28
+ * Reference to the parent query
29
+ */
30
+ readonly query: VirtualQuery;
31
+ /**
32
+ * Reference to the VirtualService instance
33
+ */
34
+ readonly service: VirtualService;
35
+ };
36
+ /**
37
+ * VirtualQuery combines a QueryDto with helper methods
38
+ * This allows clean syntax for query manipulation while keeping the underlying DTO unchanged
39
+ */
40
+ type VirtualQuery = Dto.QueryDto & {
41
+ /**
42
+ * Gets a column by name
43
+ */
44
+ getColumn(name: string): VirtualQueryColumn | undefined;
45
+ /**
46
+ * Sets a notification message on the query
47
+ */
48
+ setNotification(message: string, type: Dto.NotificationType, duration?: number): void;
49
+ /**
50
+ * Whether the query results should be included when loading the parent PersistentObject.
51
+ * Defaults to true for detail queries - set to false to skip pre-execution.
52
+ */
53
+ isIncludedInParentObject: boolean;
54
+ /**
55
+ * Reference to config (internal use)
56
+ */
57
+ readonly __config?: VirtualQueryConfig;
58
+ /**
59
+ * Reference to the VirtualService instance
60
+ */
61
+ readonly service: VirtualService;
62
+ };
63
+ /**
64
+ * VirtualQueryResultItem combines a QueryResultItemDto with helper methods
65
+ */
66
+ type VirtualQueryResultItem = Dto.QueryResultItemDto & {
67
+ /**
68
+ * Gets a value from the item by column name
69
+ */
70
+ getValue(columnName: string): any;
71
+ /**
72
+ * Reference to the parent query
73
+ */
74
+ readonly query: VirtualQuery;
75
+ /**
76
+ * Reference to the VirtualService instance
77
+ */
78
+ readonly service: VirtualService;
79
+ };
2
80
 
3
81
  /**
4
82
  * VirtualPersistentObjectAttribute combines a PersistentObjectAttributeDto with helper methods
5
83
  * This allows clean syntax like attr.getValue() and attr.setValue() while keeping the underlying DTO unchanged
6
84
  */
7
- type VirtualPersistentObjectAttribute = Dto.PersistentObjectAttributeDto & {
85
+ type VirtualPersistentObjectAttribute = Dto.PersistentObjectAttributeDto & VirtualPersistentObjectAttributeHelpers;
86
+ /**
87
+ * VirtualPersistentObjectAttributeWithReference extends VirtualPersistentObjectAttribute with reference-specific properties
88
+ * Use this type when the attribute type is "Reference"
89
+ */
90
+ type VirtualPersistentObjectAttributeWithReference = Dto.PersistentObjectAttributeWithReferenceDto & VirtualPersistentObjectAttributeHelpers;
91
+ /**
92
+ * Helper methods added to VirtualPersistentObjectAttribute
93
+ */
94
+ type VirtualPersistentObjectAttributeHelpers = {
8
95
  /**
9
96
  * Gets the converted value of this attribute (e.g., Boolean as boolean, Int32 as number)
10
97
  */
@@ -14,19 +101,23 @@ type VirtualPersistentObjectAttribute = Dto.PersistentObjectAttributeDto & {
14
101
  */
15
102
  setValue(value: any): void;
16
103
  /**
17
- * Sets a validation error on this attribute
104
+ * Sets a validation error on this attribute. Pass null/empty to clear.
18
105
  */
19
- setValidationError(error: string): void;
106
+ setValidationError(error: string | null | undefined): void;
20
107
  /**
21
- * Clears the validation error on this attribute
108
+ * Reference to the parent persistent object
22
109
  */
23
- clearValidationError(): void;
110
+ readonly persistentObject: VirtualPersistentObject;
111
+ /**
112
+ * Reference to the VirtualService instance
113
+ */
114
+ readonly service: VirtualService;
24
115
  };
25
116
  /**
26
117
  * VirtualPersistentObject combines a PersistentObjectDto with helper methods
27
118
  * This allows clean syntax like obj.setAttributeValue() while keeping the underlying DTO unchanged
28
119
  */
29
- type VirtualPersistentObject = Dto.PersistentObjectDto & {
120
+ type VirtualPersistentObject = Omit<Dto.PersistentObjectDto, "queries"> & {
30
121
  /**
31
122
  * Gets an attribute by name, wrapped with getValue/setValue methods
32
123
  */
@@ -40,17 +131,17 @@ type VirtualPersistentObject = Dto.PersistentObjectDto & {
40
131
  */
41
132
  setAttributeValue(name: string, value: any): void;
42
133
  /**
43
- * Sets a validation error for an attribute
134
+ * Sets a notification message on the persistent object
44
135
  */
45
- setValidationError(name: string, error: string): void;
136
+ setNotification(message: string, type: Dto.NotificationType, duration?: number): void;
46
137
  /**
47
- * Clears a validation error for an attribute
138
+ * Detail queries attached to this persistent object, wrapped as VirtualQuery
48
139
  */
49
- clearValidationError(name: string): void;
140
+ queries?: VirtualQuery[];
50
141
  /**
51
- * Sets a notification message on the persistent object
142
+ * Reference to the VirtualService instance
52
143
  */
53
- setNotification(message: string, type: Dto.NotificationType, duration?: number): void;
144
+ readonly service: VirtualService;
54
145
  };
55
146
 
56
147
  /**
@@ -152,29 +243,25 @@ type ActionArgs = {
152
243
  * For PersistentObject actions: the PersistentObject itself
153
244
  * For Query actions: the parent PO that owns the query, or null for top-level queries
154
245
  */
155
- parent: Dto.PersistentObjectDto | null;
246
+ parent: VirtualPersistentObject | null;
156
247
  /**
157
248
  * The query context (like args.Query in C#) - present if action invoked from query
158
249
  */
159
- query?: Dto.QueryDto;
250
+ query?: VirtualQuery;
160
251
  /**
161
252
  * Selected items (like args.SelectedItems in C#) - present if query action with selections
162
253
  */
163
- selectedItems?: Dto.QueryResultItemDto[];
254
+ selectedItems?: VirtualQueryResultItem[];
164
255
  /**
165
256
  * Additional parameters (like args.Parameters in C#)
166
257
  */
167
258
  parameters?: Record<string, any>;
168
- /**
169
- * Helper context for modifying attributes and setting notifications
170
- */
171
- context: ActionContext;
172
259
  };
173
260
  /**
174
261
  * Unified action handler (matches C# CustomAction Execute signature)
175
262
  * Return the PersistentObject to refresh UI, or null to complete silently
176
263
  */
177
- type ActionHandler = (args: ActionArgs) => Promise<Dto.PersistentObjectDto | null> | Dto.PersistentObjectDto | null;
264
+ type ActionHandler = (args: ActionArgs) => Promise<VirtualPersistentObject | null> | VirtualPersistentObject | null;
178
265
  /**
179
266
  * Action configuration
180
267
  */
@@ -191,75 +278,6 @@ type ActionConfig = {
191
278
  * Indicates whether the action is pinned. Defaults to false.
192
279
  */
193
280
  isPinned?: boolean;
194
- /**
195
- * Custom action logic handler.
196
- */
197
- handler: ActionHandler;
198
- };
199
- /**
200
- * Context provides safe API to modify the persistent object during actions
201
- */
202
- type ActionContext = {
203
- /**
204
- * Gets an attribute by name.
205
- */
206
- getAttribute: (name: string) => Dto.PersistentObjectAttributeDto | undefined;
207
- /**
208
- * Gets the value of an attribute by name.
209
- */
210
- getAttributeValue: (name: string) => any;
211
- /**
212
- * Sets the value of an attribute by name.
213
- */
214
- setAttributeValue: (name: string, value: any) => void;
215
- /**
216
- * Gets the converted value of an attribute DTO (e.g., Boolean as boolean, Int32 as number).
217
- */
218
- getConvertedValue: (attr: Dto.PersistentObjectAttributeDto) => any;
219
- /**
220
- * Sets the value on an attribute DTO with automatic type conversion.
221
- */
222
- setConvertedValue: (attr: Dto.PersistentObjectAttributeDto, value: any) => void;
223
- /**
224
- * Sets a validation error for an attribute.
225
- */
226
- setValidationError: (name: string, error: string) => void;
227
- /**
228
- * Clears the validation error for an attribute.
229
- */
230
- clearValidationError: (name: string) => void;
231
- /**
232
- * Sets a notification message.
233
- */
234
- setNotification: (message: string, type: Dto.NotificationType, duration?: number) => void;
235
- };
236
- /**
237
- * Translation function for system messages
238
- * @param key - The message key (e.g., "Required", "MaxLength")
239
- * @param params - Positional parameters for the message
240
- * @returns Translated message with parameters interpolated
241
- *
242
- * Example:
243
- * translate("MaxLength", 50) => "Maximum length is 50 characters"
244
- * translate("MinValue", 18) => "Minimum value is 18"
245
- */
246
- type TranslateFunction = (key: string, ...params: any[]) => string;
247
- /**
248
- * Context provided to business rule validators for accessing the persistent object
249
- */
250
- type RuleValidationContext = {
251
- /**
252
- * The persistent object being validated (wrapped with helper methods)
253
- */
254
- persistentObject: VirtualPersistentObject;
255
- /**
256
- * The attribute being validated (wrapped with helper methods)
257
- */
258
- attribute: VirtualPersistentObjectAttribute;
259
- /**
260
- * Translation function for system messages
261
- */
262
- translate: TranslateFunction;
263
281
  };
264
282
  /**
265
283
  * PersistentObject configuration - converted to PersistentObjectDto
@@ -360,17 +378,85 @@ type VirtualQueryConfig = {
360
378
  pageSize?: number;
361
379
  };
362
380
 
381
+ /**
382
+ * Parsed business rule with name and parameters
383
+ * @internal
384
+ */
385
+ type ParsedRule = {
386
+ name: string;
387
+ params: any[];
388
+ };
363
389
  /**
364
390
  * Rule validator function that throws an error if invalid, or returns nothing if valid
391
+ * @param value - The converted attribute value
392
+ * @param attribute - The wrapped attribute with access to persistentObject and service
393
+ * @param params - Additional parameters from the rule definition
394
+ * @internal - Exported for internal package use only, not re-exported from index.ts
395
+ */
396
+ type RuleValidatorFn = (value: any, attribute: VirtualPersistentObjectAttribute, ...params: any[]) => void;
397
+ /**
398
+ * Business rule validator that supports built-in and custom rules
365
399
  */
366
- type RuleValidatorFn = (value: any, context: RuleValidationContext, ...params: any[]) => void;
400
+ declare class BusinessRuleValidator {
401
+ #private;
402
+ /**
403
+ * Checks if a rules string contains NotEmpty or Required rule
404
+ * @param rules - The rules string (semicolon-separated)
405
+ * @returns true if rules contain NotEmpty or Required
406
+ */
407
+ static hasRequiredRule(rules?: string): boolean;
408
+ constructor(service: VirtualService);
409
+ /**
410
+ * Register a custom business rule
411
+ * @throws Error if attempting to override a built-in rule
412
+ */
413
+ registerCustomRule(name: string, validator: RuleValidatorFn): void;
414
+ /**
415
+ * Validate an attribute against its rules
416
+ * @param attr - The wrapped attribute to validate (has getValue/setValue methods and persistentObject reference)
417
+ * @param _po - Deprecated: The persistent object is now accessible via attr.persistentObject
418
+ * @returns Error message if validation fails, null if valid
419
+ */
420
+ validateAttribute(attr: VirtualPersistentObjectAttribute, _po: VirtualPersistentObject): string | null;
421
+ /**
422
+ * Parse a rules string into individual rules with parameters
423
+ * Example: "NotEmpty; MaxLength(40); IsEmail" -> [
424
+ * { name: "NotEmpty", params: [] },
425
+ * { name: "MaxLength", params: [40] },
426
+ * { name: "IsEmail", params: [] }
427
+ * ]
428
+ */
429
+ parseRules(rulesString: string): ParsedRule[];
430
+ }
367
431
 
432
+ /**
433
+ * @internal
434
+ */
435
+ declare const initializeActions: unique symbol;
368
436
  /**
369
437
  * Base class for PersistentObject lifecycle methods
370
438
  * Extend this class to override lifecycle hooks like onLoad, onSave, onRefresh, etc.
371
439
  * All methods have default implementations, so you only need to override what you need.
372
440
  */
373
441
  declare class VirtualPersistentObjectActions {
442
+ #private;
443
+ /**
444
+ * Validator instance for business rule validation (injected by registry)
445
+ */
446
+ protected validator?: BusinessRuleValidator;
447
+ /**
448
+ * VirtualService instance for message translation (injected by registry)
449
+ */
450
+ protected service?: VirtualService;
451
+ /**
452
+ * The PersistentObject type name (injected by registry during instance creation)
453
+ */
454
+ protected type?: string;
455
+ /**
456
+ * Internal initialization method (called by registry during instance creation)
457
+ * @internal
458
+ */
459
+ [initializeActions](validator: BusinessRuleValidator, service: VirtualService, type?: string): void;
374
460
  /**
375
461
  * Called every time a PersistentObject DTO is created (both new and existing objects)
376
462
  * Use this to set metadata on attributes that can only be known at runtime
@@ -378,23 +464,28 @@ declare class VirtualPersistentObjectActions {
378
464
  */
379
465
  onConstruct(obj: VirtualPersistentObject): void;
380
466
  /**
381
- * Called when loading an existing PersistentObject by ID
382
- * Use this to load entity data and populate attribute values
383
- * @param obj - The constructed PersistentObject DTO (after onConstruct)
467
+ * Called when loading an existing object.
468
+ * @param objectId - The ID of the object to load
384
469
  * @param parent - The parent PersistentObject if loaded in a master-detail context, null otherwise
385
470
  * @returns The PersistentObject with loaded data
386
471
  */
387
- onLoad(obj: VirtualPersistentObject, parent: VirtualPersistentObject | null): Promise<VirtualPersistentObject>;
472
+ onLoad(objectId: string, parent: VirtualPersistentObject | null): Promise<VirtualPersistentObject>;
388
473
  /**
389
- * Called when creating a new PersistentObject via the "New" action
390
- * Use this to create a fresh entity instance with default values
391
- * @param obj - The constructed PersistentObject DTO (after onConstruct)
474
+ * Called when creating a new object.
392
475
  * @param parent - The parent PersistentObject if creating from a detail query, null otherwise
393
476
  * @param query - The Query from which the New action was invoked, null if not from a query
394
477
  * @param parameters - Optional parameters including "MenuOption" if NewOptions exist
395
478
  * @returns The PersistentObject with default values set
396
479
  */
397
- onNew(obj: VirtualPersistentObject, parent: VirtualPersistentObject | null, query: Dto.QueryDto | null, parameters: Record<string, string> | null): Promise<VirtualPersistentObject>;
480
+ onNew(parent: VirtualPersistentObject | null, query: VirtualQuery | null, parameters: Record<string, string> | null): Promise<VirtualPersistentObject>;
481
+ /**
482
+ * Full query lifecycle - builds query, calls onConstructQuery, auto-executes if configured
483
+ * Override this to customize how queries are retrieved
484
+ * @param queryName - The name of the query to get
485
+ * @param parent - The parent PersistentObject if this is a detail query, null otherwise
486
+ * @returns The Query with results if autoQuery is enabled
487
+ */
488
+ onGetQuery(queryName: string, parent: VirtualPersistentObject | null): Promise<VirtualQuery>;
398
489
  /**
399
490
  * Called when an attribute with triggersRefresh: true is changed
400
491
  * Use this to update other attributes based on the changed attribute
@@ -410,6 +501,13 @@ declare class VirtualPersistentObjectActions {
410
501
  * @returns The saved PersistentObject
411
502
  */
412
503
  onSave(obj: VirtualPersistentObject): Promise<VirtualPersistentObject>;
504
+ /**
505
+ * Validates all attributes against their business rules
506
+ * Override this to customize validation behavior
507
+ * @param obj - The wrapped PersistentObject to validate (already has config metadata merged)
508
+ * @returns true if all rules pass, false if any validation errors
509
+ */
510
+ checkRules(obj: VirtualPersistentObject): boolean;
413
511
  /**
414
512
  * Called by onSave when obj.isNew === true
415
513
  * Use this to save a new entity to the data store
@@ -433,7 +531,7 @@ declare class VirtualPersistentObjectActions {
433
531
  * @param query - The query that was used to select the reference
434
532
  * @param selectedItem - The QueryResultItem that was selected, or null if reference was cleared
435
533
  */
436
- onSelectReference(_parent: VirtualPersistentObject, referenceAttribute: Dto.PersistentObjectAttributeDto, _query: Dto.QueryDto, selectedItem: Dto.QueryResultItemDto | null): Promise<void>;
534
+ onSelectReference(_parent: VirtualPersistentObject, referenceAttribute: VirtualPersistentObjectAttribute, _query: VirtualQuery, selectedItem: VirtualQueryResultItem | null): Promise<void>;
437
535
  /**
438
536
  * Called when the Delete action is executed on selected items in a Query
439
537
  * Use this to handle deletion of entities
@@ -441,14 +539,14 @@ declare class VirtualPersistentObjectActions {
441
539
  * @param query - The query from which items are being deleted
442
540
  * @param selectedItems - The QueryResultItems that are selected for deletion
443
541
  */
444
- onDelete(parent: VirtualPersistentObject | null, query: Dto.QueryDto, selectedItems: Dto.QueryResultItemDto[]): Promise<void>;
542
+ onDelete(parent: VirtualPersistentObject | null, query: VirtualQuery, selectedItems: VirtualQueryResultItem[]): Promise<void>;
445
543
  /**
446
544
  * Called when a Query of this PersistentObject type is constructed
447
545
  * Use this to set metadata on query columns that can only be known at runtime
448
546
  * @param query - The Query DTO being constructed
449
547
  * @param parent - The parent PersistentObject if this is a detail query, null for top-level queries
450
548
  */
451
- onConstructQuery(query: Dto.QueryDto, parent: VirtualPersistentObject | null): void;
549
+ onConstructQuery(query: VirtualQuery, parent: VirtualPersistentObject | null): void;
452
550
  /**
453
551
  * Called when a Query is executed.
454
552
  * The base implementation calls getEntities() and applies text search, sorting, and pagination.
@@ -457,7 +555,7 @@ declare class VirtualPersistentObjectActions {
457
555
  * @param data - Default data from the query config (used if getEntities is not overridden)
458
556
  * @returns The items matching the query criteria and the total count before pagination
459
557
  */
460
- onExecuteQuery(query: Dto.QueryDto, parent: VirtualPersistentObject | null, data: Record<string, any>[]): Promise<VirtualQueryExecuteResult>;
558
+ onExecuteQuery(query: VirtualQuery, parent: VirtualPersistentObject | null, data: Record<string, any>[]): Promise<VirtualQueryExecuteResult>;
461
559
  /**
462
560
  * Override this to provide the full list of items for a query.
463
561
  * The base onExecuteQuery will handle text search, sorting, and pagination automatically.
@@ -466,48 +564,140 @@ declare class VirtualPersistentObjectActions {
466
564
  * @param data - Default data from the query config
467
565
  * @returns All items matching the query criteria (before pagination)
468
566
  */
469
- getEntities(_query: Dto.QueryDto, _parent: VirtualPersistentObject | null, data: Record<string, any>[]): Promise<Record<string, any>[]>;
567
+ getEntities(_query: VirtualQuery, _parent: VirtualPersistentObject | null, data: Record<string, any>[]): Promise<Record<string, any>[]>;
568
+ /**
569
+ * Builds a PersistentObject from configuration
570
+ * @param objectId - The object ID
571
+ * @param isNew - Whether this is a new object
572
+ * @returns The wrapped VirtualPersistentObject
573
+ */
574
+ protected buildPersistentObject(objectId: string, isNew: boolean): Promise<VirtualPersistentObject>;
575
+ /**
576
+ * Builds a Query from configuration
577
+ * @param name - The query name
578
+ * @returns The wrapped VirtualQuery
579
+ */
580
+ protected buildQuery(name: string): Promise<VirtualQuery>;
581
+ /**
582
+ * Executes queries that have isIncludedInParentObject set (defaults to true).
583
+ * Called automatically after onLoad/onNew completes.
584
+ * @param obj - The PersistentObject to execute queries for
585
+ */
586
+ executeIncludedQueries(obj: VirtualPersistentObject): Promise<void>;
587
+ /**
588
+ * Gets the default data for a query from configuration
589
+ * @param name - The query name
590
+ * @returns The default data array
591
+ */
592
+ protected getQueryData(name: string): Record<string, any>[];
470
593
  }
471
594
 
595
+ /** Lifecycle methods that can be overridden in VirtualPersistentObjectActions */
596
+ type LifecycleMethod = "onSave" | "onNew" | "onDelete" | "onRefresh" | "onLoad" | "onConstruct" | "onConstructQuery" | "onSelectReference" | "onExecuteQuery" | "getEntities";
472
597
  /**
473
- * Virtual implementation of ServiceHooks for testing without a backend
598
+ * Registry for managing VirtualPersistentObjectActions classes
599
+ * Provides methods to register actions classes and create instances
474
600
  */
475
- declare class VirtualServiceHooks extends ServiceHooks {
601
+ declare class VirtualPersistentObjectActionsRegistry {
476
602
  #private;
477
- constructor();
603
+ constructor(validator: BusinessRuleValidator, service: VirtualService);
478
604
  /**
479
- * Sets the translation function for system messages
605
+ * Registers a VirtualPersistentObjectActions class for a specific type
606
+ * @param type - The PersistentObject type name
607
+ * @param ActionsClass - The VirtualPersistentObjectActions class constructor
480
608
  */
481
- setTranslate(translate: TranslateFunction): void;
609
+ register(type: string, ActionsClass: typeof VirtualPersistentObjectActions): void;
482
610
  /**
483
- * Intercepts fetch requests and routes them to virtual handlers
611
+ * Checks if a specific lifecycle method is overridden for a type
612
+ * @param type - The PersistentObject type name
613
+ * @param methodName - The lifecycle method name
614
+ * @returns true if the method is overridden, false otherwise
484
615
  */
485
- onFetch(request: Request): Promise<Response>;
616
+ isMethodOverridden(type: string, methodName: LifecycleMethod): boolean;
617
+ /**
618
+ * Checks if a type has registered actions
619
+ * @param type - The PersistentObject type name
620
+ * @returns true if the type has registered actions, false otherwise
621
+ */
622
+ has(type: string): boolean;
623
+ /**
624
+ * Creates a new instance of the actions class for a type
625
+ * Returns a default VirtualPersistentObjectActions if no custom actions are registered
626
+ * Injects validator, service, and type into the instance
627
+ * @param type - The PersistentObject type name
628
+ * @returns A new instance of the VirtualPersistentObjectActions class
629
+ */
630
+ createInstance(type: string): VirtualPersistentObjectActions;
631
+ }
632
+
633
+ /**
634
+ * Registry for managing PersistentObject configurations (pure config store)
635
+ */
636
+ declare class VirtualPersistentObjectRegistry {
637
+ #private;
486
638
  /**
487
639
  * Registers a PersistentObject configuration
488
640
  */
489
- registerPersistentObject(config: VirtualPersistentObjectConfig): void;
641
+ register(config: VirtualPersistentObjectConfig): void;
490
642
  /**
491
- * Registers a Query configuration
643
+ * Gets a registered PersistentObject configuration
492
644
  */
493
- registerQuery(config: VirtualQueryConfig): void;
645
+ getConfig(type: string): VirtualPersistentObjectConfig | undefined;
494
646
  /**
495
- * Registers a custom action that can be used on PersistentObjects and Queries
496
- * @param config - The action configuration with handler
647
+ * Checks if a type has a registered configuration
497
648
  */
498
- registerAction(config: ActionConfig): void;
649
+ hasConfig(type: string): boolean;
650
+ }
651
+
652
+ /**
653
+ * Registry for managing Query configurations (config + columns store)
654
+ */
655
+ declare class VirtualQueryRegistry {
656
+ #private;
499
657
  /**
500
- * Registers a custom business rule for validation
501
- * @param name - The rule name (cannot override built-in rules)
502
- * @param validator - The validation function
658
+ * Checks if a query is registered
659
+ * @param name - The query name
503
660
  */
504
- registerBusinessRule(name: string, validator: RuleValidatorFn): void;
661
+ hasQuery(name: string): boolean;
505
662
  /**
506
- * Registers a VirtualPersistentObjectActions class for a specific type
507
- * @param type - The PersistentObject type name
508
- * @param ActionsClass - The VirtualPersistentObjectActions class constructor
663
+ * Gets a registered Query configuration
664
+ * @param name - The query name
665
+ */
666
+ getQueryConfig(name: string): VirtualQueryConfig | undefined;
667
+ /**
668
+ * Gets the PersistentObject configuration for a query
669
+ * @param name - The query name
509
670
  */
510
- registerPersistentObjectActions(type: string, ActionsClass: typeof VirtualPersistentObjectActions): void;
671
+ getPersistentObjectConfig(name: string): VirtualPersistentObjectConfig | undefined;
672
+ /**
673
+ * Gets the columns for a query
674
+ * @param name - The query name
675
+ */
676
+ getColumns(name: string): Dto.QueryColumnDto[];
677
+ /**
678
+ * Gets the default data for a query
679
+ * @param name - The query name
680
+ */
681
+ getData(name: string): Record<string, any>[];
682
+ /**
683
+ * Registers a Query configuration
684
+ */
685
+ register(config: VirtualQueryConfig, persistentObjectConfig: VirtualPersistentObjectConfig): void;
686
+ /**
687
+ * Builds a QueryResultDto from execution result
688
+ * @param result - The query execution result with items and totalItems
689
+ * @param columns - The query columns
690
+ * @param pageSize - The page size
691
+ * @returns The QueryResultDto
692
+ */
693
+ static buildQueryResultDto(result: VirtualQueryExecuteResult, columns: Dto.QueryColumnDto[], pageSize: number): Dto.QueryResultDto;
694
+ /**
695
+ * Builds a QueryResultItemDto from a data row
696
+ * @param data - The data row
697
+ * @param columns - The query columns
698
+ * @returns The QueryResultItemDto
699
+ */
700
+ static buildQueryResultItemDto(data: Record<string, any>, columns: Dto.QueryColumnDto[]): Dto.QueryResultItemDto;
511
701
  }
512
702
 
513
703
  /**
@@ -529,28 +719,70 @@ declare class VirtualServiceHooks extends ServiceHooks {
529
719
  */
530
720
  declare class VirtualService extends Service {
531
721
  #private;
722
+ /**
723
+ * Gets a copy of the global messages dictionary.
724
+ */
725
+ static get messages(): Record<string, string>;
726
+ /**
727
+ * Sets the global messages dictionary.
728
+ * Use this to provide translations or override default messages.
729
+ * @example
730
+ * VirtualService.messages = {
731
+ * "Required": "Dit veld is verplicht",
732
+ * "MaxLength": "Maximale lengte is {0} tekens"
733
+ * };
734
+ */
735
+ static set messages(value: Record<string, string>);
736
+ /**
737
+ * Converts a service string value to a primitive JavaScript type.
738
+ * Unlike DataType.fromServiceString, this returns number instead of BigNumber
739
+ * for numeric types (Decimal, Double, Int64, etc.).
740
+ */
741
+ static fromServiceValue(value: any, type: string): any;
742
+ /**
743
+ * Converts a primitive JavaScript value to a service string.
744
+ */
745
+ static toServiceValue(value: any, type: string): string;
746
+ /**
747
+ * Gets a message by key with optional parameters.
748
+ * Resolution: static messages → return key unchanged
749
+ * @param key - The message key (e.g., "Required", "MaxLength")
750
+ * @param params - Positional parameters for {0}, {1} placeholders
751
+ * @returns The formatted message, or the key if not found
752
+ */
753
+ getMessage(key: string, ...params: any[]): string;
532
754
  /**
533
755
  * Creates a new VirtualService instance.
534
756
  * @param hooks - Optional custom hooks instance.
535
757
  */
536
758
  constructor(hooks?: VirtualServiceHooks);
537
- /**
538
- * Gets the VirtualServiceHooks instance.
539
- */
540
- get virtualHooks(): VirtualServiceHooks;
759
+ /** @internal */
760
+ get persistentObjectRegistry(): VirtualPersistentObjectRegistry;
761
+ /** @internal */
762
+ get queryRegistry(): VirtualQueryRegistry;
763
+ /** @internal */
764
+ get actionsRegistry(): VirtualPersistentObjectActionsRegistry;
765
+ /** @internal */
766
+ get _actionDefinitions(): Map<string, {
767
+ name: string;
768
+ displayName: string;
769
+ isPinned: boolean;
770
+ }>;
771
+ /** @internal */
772
+ get actionHandlers(): Map<string, ActionHandler>;
541
773
  /**
542
774
  * Initializes the service and finalizes all registrations.
543
775
  * After this method is called, no more registrations are allowed.
544
776
  */
545
- initialize(skipDefaultCredentialLogin?: boolean): Promise<Application>;
546
- initialize(oneTimeSignInToken: string): Promise<Application>;
777
+ initialize(): Promise<Application>;
547
778
  /**
548
779
  * Registers a PersistentObject configuration.
549
780
  * Must be called before initialize().
550
781
  * @param config - The PersistentObject configuration.
782
+ * @param lifecycle - Optional lifecycle class for hooks (onLoad, onSave, onNew, etc.).
551
783
  * @throws Error if called after initialize().
552
784
  */
553
- registerPersistentObject(config: VirtualPersistentObjectConfig): void;
785
+ registerPersistentObject(config: VirtualPersistentObjectConfig, lifecycle?: typeof VirtualPersistentObjectActions): void;
554
786
  /**
555
787
  * Registers a Query configuration.
556
788
  * Must be called before initialize().
@@ -561,34 +793,28 @@ declare class VirtualService extends Service {
561
793
  /**
562
794
  * Registers a custom action that can be used on PersistentObjects and Queries.
563
795
  * Must be called before initialize().
564
- * @param config - The action configuration with handler.
565
- * @throws Error if called after initialize().
566
- */
567
- registerAction(config: ActionConfig): void;
568
- /**
569
- * Registers a custom business rule for validation.
570
- * Must be called before initialize().
571
- * @param name - The rule name (cannot override built-in rules).
572
- * @param validator - The validation function.
796
+ * @param name - The action name.
797
+ * @param handler - The action handler function.
573
798
  * @throws Error if called after initialize().
574
799
  */
575
- registerBusinessRule(name: string, validator: RuleValidatorFn): void;
800
+ registerCustomAction(name: string, handler: ActionHandler): void;
576
801
  /**
577
- * Registers a VirtualPersistentObjectActions class for a specific type.
802
+ * Registers a custom action that can be used on PersistentObjects and Queries.
578
803
  * Must be called before initialize().
579
- * @param type - The PersistentObject type name.
580
- * @param ActionsClass - The VirtualPersistentObjectActions class constructor.
804
+ * @param config - The action configuration.
805
+ * @param handler - The action handler function.
581
806
  * @throws Error if called after initialize().
582
807
  */
583
- registerPersistentObjectActions(type: string, ActionsClass: typeof VirtualPersistentObjectActions): void;
808
+ registerCustomAction(config: ActionConfig, handler: ActionHandler): void;
584
809
  /**
585
- * Registers a message translator for translating system messages.
810
+ * Registers a custom business rule for validation.
586
811
  * Must be called before initialize().
587
- * @param translate - The translation function.
812
+ * @param name - The rule name (cannot override built-in rules).
813
+ * @param validator - The validation function.
588
814
  * @throws Error if called after initialize().
589
815
  */
590
- registerMessageTranslator(translate: TranslateFunction): void;
816
+ registerBusinessRule(name: string, validator: RuleValidatorFn): void;
591
817
  }
592
818
 
593
819
  export { VirtualPersistentObjectActions, VirtualService, VirtualServiceHooks };
594
- export type { ActionArgs, ActionConfig, ActionContext, ActionHandler, RuleValidationContext, RuleValidatorFn, TranslateFunction, VirtualPersistentObject, VirtualPersistentObjectAttribute, VirtualPersistentObjectAttributeConfig, VirtualPersistentObjectConfig, VirtualQueryConfig, VirtualQueryExecuteResult };
820
+ export type { VirtualPersistentObject, VirtualPersistentObjectAttribute, VirtualPersistentObjectAttributeConfig, VirtualPersistentObjectAttributeWithReference, VirtualPersistentObjectConfig, VirtualQuery, VirtualQueryConfig, VirtualQueryExecuteResult, VirtualQueryResultItem };