@vidyano-labs/virtual-service 0.2.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 +352 -167
  2. package/index.d.ts +379 -127
  3. package/index.js +1427 -1611
  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.
105
+ */
106
+ setValidationError(error: string | null | undefined): void;
107
+ /**
108
+ * Reference to the parent persistent object
18
109
  */
19
- setValidationError(error: string): void;
110
+ readonly persistentObject: VirtualPersistentObject;
20
111
  /**
21
- * Clears the validation error on this attribute
112
+ * Reference to the VirtualService instance
22
113
  */
23
- clearValidationError(): void;
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,60 +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
- * Context provided to business rule validators for accessing the persistent object
238
- */
239
- type RuleValidationContext = {
240
- /**
241
- * The persistent object being validated (wrapped with helper methods)
242
- */
243
- persistentObject: VirtualPersistentObject;
244
- /**
245
- * The attribute being validated (wrapped with helper methods)
246
- */
247
- attribute: VirtualPersistentObjectAttribute;
248
281
  };
249
282
  /**
250
283
  * PersistentObject configuration - converted to PersistentObjectDto
@@ -345,17 +378,85 @@ type VirtualQueryConfig = {
345
378
  pageSize?: number;
346
379
  };
347
380
 
381
+ /**
382
+ * Parsed business rule with name and parameters
383
+ * @internal
384
+ */
385
+ type ParsedRule = {
386
+ name: string;
387
+ params: any[];
388
+ };
348
389
  /**
349
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
350
399
  */
351
- 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
+ }
352
431
 
432
+ /**
433
+ * @internal
434
+ */
435
+ declare const initializeActions: unique symbol;
353
436
  /**
354
437
  * Base class for PersistentObject lifecycle methods
355
438
  * Extend this class to override lifecycle hooks like onLoad, onSave, onRefresh, etc.
356
439
  * All methods have default implementations, so you only need to override what you need.
357
440
  */
358
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;
359
460
  /**
360
461
  * Called every time a PersistentObject DTO is created (both new and existing objects)
361
462
  * Use this to set metadata on attributes that can only be known at runtime
@@ -363,23 +464,28 @@ declare class VirtualPersistentObjectActions {
363
464
  */
364
465
  onConstruct(obj: VirtualPersistentObject): void;
365
466
  /**
366
- * Called when loading an existing PersistentObject by ID
367
- * Use this to load entity data and populate attribute values
368
- * @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
369
469
  * @param parent - The parent PersistentObject if loaded in a master-detail context, null otherwise
370
470
  * @returns The PersistentObject with loaded data
371
471
  */
372
- onLoad(obj: VirtualPersistentObject, parent: VirtualPersistentObject | null): Promise<VirtualPersistentObject>;
472
+ onLoad(objectId: string, parent: VirtualPersistentObject | null): Promise<VirtualPersistentObject>;
373
473
  /**
374
- * Called when creating a new PersistentObject via the "New" action
375
- * Use this to create a fresh entity instance with default values
376
- * @param obj - The constructed PersistentObject DTO (after onConstruct)
474
+ * Called when creating a new object.
377
475
  * @param parent - The parent PersistentObject if creating from a detail query, null otherwise
378
476
  * @param query - The Query from which the New action was invoked, null if not from a query
379
477
  * @param parameters - Optional parameters including "MenuOption" if NewOptions exist
380
478
  * @returns The PersistentObject with default values set
381
479
  */
382
- 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>;
383
489
  /**
384
490
  * Called when an attribute with triggersRefresh: true is changed
385
491
  * Use this to update other attributes based on the changed attribute
@@ -395,6 +501,13 @@ declare class VirtualPersistentObjectActions {
395
501
  * @returns The saved PersistentObject
396
502
  */
397
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;
398
511
  /**
399
512
  * Called by onSave when obj.isNew === true
400
513
  * Use this to save a new entity to the data store
@@ -418,7 +531,7 @@ declare class VirtualPersistentObjectActions {
418
531
  * @param query - The query that was used to select the reference
419
532
  * @param selectedItem - The QueryResultItem that was selected, or null if reference was cleared
420
533
  */
421
- 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>;
422
535
  /**
423
536
  * Called when the Delete action is executed on selected items in a Query
424
537
  * Use this to handle deletion of entities
@@ -426,14 +539,14 @@ declare class VirtualPersistentObjectActions {
426
539
  * @param query - The query from which items are being deleted
427
540
  * @param selectedItems - The QueryResultItems that are selected for deletion
428
541
  */
429
- onDelete(parent: VirtualPersistentObject | null, query: Dto.QueryDto, selectedItems: Dto.QueryResultItemDto[]): Promise<void>;
542
+ onDelete(parent: VirtualPersistentObject | null, query: VirtualQuery, selectedItems: VirtualQueryResultItem[]): Promise<void>;
430
543
  /**
431
544
  * Called when a Query of this PersistentObject type is constructed
432
545
  * Use this to set metadata on query columns that can only be known at runtime
433
546
  * @param query - The Query DTO being constructed
434
547
  * @param parent - The parent PersistentObject if this is a detail query, null for top-level queries
435
548
  */
436
- onConstructQuery(query: Dto.QueryDto, parent: VirtualPersistentObject | null): void;
549
+ onConstructQuery(query: VirtualQuery, parent: VirtualPersistentObject | null): void;
437
550
  /**
438
551
  * Called when a Query is executed.
439
552
  * The base implementation calls getEntities() and applies text search, sorting, and pagination.
@@ -442,7 +555,7 @@ declare class VirtualPersistentObjectActions {
442
555
  * @param data - Default data from the query config (used if getEntities is not overridden)
443
556
  * @returns The items matching the query criteria and the total count before pagination
444
557
  */
445
- 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>;
446
559
  /**
447
560
  * Override this to provide the full list of items for a query.
448
561
  * The base onExecuteQuery will handle text search, sorting, and pagination automatically.
@@ -451,44 +564,140 @@ declare class VirtualPersistentObjectActions {
451
564
  * @param data - Default data from the query config
452
565
  * @returns All items matching the query criteria (before pagination)
453
566
  */
454
- 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>[];
455
593
  }
456
594
 
595
+ /** Lifecycle methods that can be overridden in VirtualPersistentObjectActions */
596
+ type LifecycleMethod = "onSave" | "onNew" | "onDelete" | "onRefresh" | "onLoad" | "onConstruct" | "onConstructQuery" | "onSelectReference" | "onExecuteQuery" | "getEntities";
457
597
  /**
458
- * 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
459
600
  */
460
- declare class VirtualServiceHooks extends ServiceHooks {
601
+ declare class VirtualPersistentObjectActionsRegistry {
461
602
  #private;
462
- constructor();
603
+ constructor(validator: BusinessRuleValidator, service: VirtualService);
463
604
  /**
464
- * Intercepts fetch requests and routes them to virtual handlers
605
+ * Registers a VirtualPersistentObjectActions class for a specific type
606
+ * @param type - The PersistentObject type name
607
+ * @param ActionsClass - The VirtualPersistentObjectActions class constructor
465
608
  */
466
- onFetch(request: Request): Promise<Response>;
609
+ register(type: string, ActionsClass: typeof VirtualPersistentObjectActions): void;
610
+ /**
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
615
+ */
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;
467
638
  /**
468
639
  * Registers a PersistentObject configuration
469
640
  */
470
- registerPersistentObject(config: VirtualPersistentObjectConfig): void;
641
+ register(config: VirtualPersistentObjectConfig): void;
471
642
  /**
472
- * Registers a Query configuration
643
+ * Gets a registered PersistentObject configuration
473
644
  */
474
- registerQuery(config: VirtualQueryConfig): void;
645
+ getConfig(type: string): VirtualPersistentObjectConfig | undefined;
475
646
  /**
476
- * Registers a custom action that can be used on PersistentObjects and Queries
477
- * @param config - The action configuration with handler
647
+ * Checks if a type has a registered configuration
478
648
  */
479
- 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;
480
657
  /**
481
- * Registers a custom business rule for validation
482
- * @param name - The rule name (cannot override built-in rules)
483
- * @param validator - The validation function
658
+ * Checks if a query is registered
659
+ * @param name - The query name
484
660
  */
485
- registerBusinessRule(name: string, validator: RuleValidatorFn): void;
661
+ hasQuery(name: string): boolean;
486
662
  /**
487
- * Registers a VirtualPersistentObjectActions class for a specific type
488
- * @param type - The PersistentObject type name
489
- * @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
670
+ */
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
490
692
  */
491
- registerPersistentObjectActions(type: string, ActionsClass: typeof VirtualPersistentObjectActions): void;
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;
492
701
  }
493
702
 
494
703
  /**
@@ -511,27 +720,69 @@ declare class VirtualServiceHooks extends ServiceHooks {
511
720
  declare class VirtualService extends Service {
512
721
  #private;
513
722
  /**
514
- * Creates a new VirtualService instance.
515
- * @param hooks - Optional custom VirtualServiceHooks. If not provided, a default instance is created.
723
+ * Gets a copy of the global messages dictionary.
516
724
  */
517
- constructor(hooks?: VirtualServiceHooks);
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>);
518
736
  /**
519
- * Gets the VirtualServiceHooks instance.
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.).
520
740
  */
521
- get virtualHooks(): VirtualServiceHooks;
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;
754
+ /**
755
+ * Creates a new VirtualService instance.
756
+ * @param hooks - Optional custom hooks instance.
757
+ */
758
+ constructor(hooks?: 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>;
522
773
  /**
523
774
  * Initializes the service and finalizes all registrations.
524
775
  * After this method is called, no more registrations are allowed.
525
776
  */
526
- initialize(skipDefaultCredentialLogin?: boolean): Promise<Application>;
527
- initialize(oneTimeSignInToken: string): Promise<Application>;
777
+ initialize(): Promise<Application>;
528
778
  /**
529
779
  * Registers a PersistentObject configuration.
530
780
  * Must be called before initialize().
531
781
  * @param config - The PersistentObject configuration.
782
+ * @param lifecycle - Optional lifecycle class for hooks (onLoad, onSave, onNew, etc.).
532
783
  * @throws Error if called after initialize().
533
784
  */
534
- registerPersistentObject(config: VirtualPersistentObjectConfig): void;
785
+ registerPersistentObject(config: VirtualPersistentObjectConfig, lifecycle?: typeof VirtualPersistentObjectActions): void;
535
786
  /**
536
787
  * Registers a Query configuration.
537
788
  * Must be called before initialize().
@@ -542,27 +793,28 @@ declare class VirtualService extends Service {
542
793
  /**
543
794
  * Registers a custom action that can be used on PersistentObjects and Queries.
544
795
  * Must be called before initialize().
545
- * @param config - The action configuration with handler.
796
+ * @param name - The action name.
797
+ * @param handler - The action handler function.
546
798
  * @throws Error if called after initialize().
547
799
  */
548
- registerAction(config: ActionConfig): void;
800
+ registerCustomAction(name: string, handler: ActionHandler): void;
549
801
  /**
550
- * Registers a custom business rule for validation.
802
+ * Registers a custom action that can be used on PersistentObjects and Queries.
551
803
  * Must be called before initialize().
552
- * @param name - The rule name (cannot override built-in rules).
553
- * @param validator - The validation function.
804
+ * @param config - The action configuration.
805
+ * @param handler - The action handler function.
554
806
  * @throws Error if called after initialize().
555
807
  */
556
- registerBusinessRule(name: string, validator: RuleValidatorFn): void;
808
+ registerCustomAction(config: ActionConfig, handler: ActionHandler): void;
557
809
  /**
558
- * Registers a VirtualPersistentObjectActions class for a specific type.
810
+ * Registers a custom business rule for validation.
559
811
  * Must be called before initialize().
560
- * @param type - The PersistentObject type name.
561
- * @param ActionsClass - The VirtualPersistentObjectActions class constructor.
812
+ * @param name - The rule name (cannot override built-in rules).
813
+ * @param validator - The validation function.
562
814
  * @throws Error if called after initialize().
563
815
  */
564
- registerPersistentObjectActions(type: string, ActionsClass: typeof VirtualPersistentObjectActions): void;
816
+ registerBusinessRule(name: string, validator: RuleValidatorFn): void;
565
817
  }
566
818
 
567
819
  export { VirtualPersistentObjectActions, VirtualService, VirtualServiceHooks };
568
- export type { ActionArgs, ActionConfig, ActionContext, ActionHandler, RuleValidationContext, RuleValidatorFn, VirtualPersistentObject, VirtualPersistentObjectAttribute, VirtualPersistentObjectAttributeConfig, VirtualPersistentObjectConfig, VirtualQueryConfig, VirtualQueryExecuteResult };
820
+ export type { VirtualPersistentObject, VirtualPersistentObjectAttribute, VirtualPersistentObjectAttributeConfig, VirtualPersistentObjectAttributeWithReference, VirtualPersistentObjectConfig, VirtualQuery, VirtualQueryConfig, VirtualQueryExecuteResult, VirtualQueryResultItem };