@vidyano-labs/virtual-service 0.4.2 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -144,7 +144,7 @@ Common attribute types supported by the virtual service:
144
144
  | `Date` | Dates only | `"2026-01-23"` |
145
145
  | `Byte` | Small integers (0-255) | `128` |
146
146
 
147
- > **Note:** Values are stored as strings in DTOs but converted to JavaScript types when accessed through `getValue()`. Boolean attributes accept both native booleans and string values `"True"`/`"False"`.
147
+ > **Note:** Use native JavaScript types (boolean, number, Date, etc.) when setting attribute values. The `getValue<T>()` and `setValue<T>()` methods work directly with these types and support generics for type safety (e.g., `getValue<number>()`).
148
148
 
149
149
  ### Attribute Configuration
150
150
 
@@ -1142,8 +1142,8 @@ async onSave(obj: VirtualPersistentObject): Promise<VirtualPersistentObject> {
1142
1142
  | Method | Description |
1143
1143
  |--------|-------------|
1144
1144
  | `getAttribute(name)` | Get attribute by name |
1145
- | `getAttributeValue(name)` | Get converted attribute value |
1146
- | `setAttributeValue(name, value)` | Set attribute value with conversion |
1145
+ | `getAttributeValue<T>(name)` | Get attribute value |
1146
+ | `setAttributeValue<T>(name, value)` | Set attribute value |
1147
1147
  | `setValidationError(name, error)` | Set validation error (pass `null`/empty to clear) |
1148
1148
  | `setNotification(msg, type, duration?)` | Set notification |
1149
1149
  | `service` | Reference to the VirtualService instance |
@@ -1152,8 +1152,8 @@ async onSave(obj: VirtualPersistentObject): Promise<VirtualPersistentObject> {
1152
1152
 
1153
1153
  | Method | Description |
1154
1154
  |--------|-------------|
1155
- | `getValue()` | Get converted value |
1156
- | `setValue(value)` | Set value with conversion |
1155
+ | `getValue<T>()` | Get value |
1156
+ | `setValue<T>(value)` | Set value |
1157
1157
  | `setValidationError(error)` | Set validation error (pass `null`/empty to clear) |
1158
1158
  | `persistentObject` | Reference to the parent VirtualPersistentObject |
1159
1159
  | `service` | Reference to the VirtualService instance |
package/index.d.ts CHANGED
@@ -93,13 +93,13 @@ type VirtualPersistentObjectAttributeWithReference = Dto.PersistentObjectAttribu
93
93
  */
94
94
  type VirtualPersistentObjectAttributeHelpers = {
95
95
  /**
96
- * Gets the converted value of this attribute (e.g., Boolean as boolean, Int32 as number)
96
+ * Gets the value of this attribute
97
97
  */
98
- getValue(): any;
98
+ getValue<T = any>(): T;
99
99
  /**
100
- * Sets the value of this attribute with automatic type conversion
100
+ * Sets the value of this attribute
101
101
  */
102
- setValue(value: any): void;
102
+ setValue<T = any>(value: T): void;
103
103
  /**
104
104
  * Sets a validation error on this attribute. Pass null/empty to clear.
105
105
  */
@@ -125,11 +125,11 @@ type VirtualPersistentObject = Omit<Dto.PersistentObjectDto, "queries"> & {
125
125
  /**
126
126
  * Gets the value of an attribute by name
127
127
  */
128
- getAttributeValue(name: string): any;
128
+ getAttributeValue<T = any>(name: string): T;
129
129
  /**
130
130
  * Sets the value of an attribute by name
131
131
  */
132
- setAttributeValue(name: string, value: any): void;
132
+ setAttributeValue<T = any>(name: string, value: T): void;
133
133
  /**
134
134
  * Sets a notification message on the persistent object
135
135
  */
@@ -735,14 +735,10 @@ declare class VirtualService extends Service {
735
735
  static set messages(value: Record<string, string>);
736
736
  /**
737
737
  * Converts a service string value to a primitive JavaScript type.
738
- * Unlike DataType.fromServiceString, this returns number instead of BigNumber
738
+ * Unlike Service.fromServiceString, this returns number instead of BigNumber
739
739
  * for numeric types (Decimal, Double, Int64, etc.).
740
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;
741
+ static fromServiceString(value: string, typeName: string): any;
746
742
  /**
747
743
  * Gets a message by key with optional parameters.
748
744
  * Resolution: static messages → return key unchanged
package/index.js CHANGED
@@ -1,27 +1,20 @@
1
1
  import { DataType, ServiceHooks, Service } from '@vidyano/core';
2
2
 
3
3
  /**
4
- * Value conversion utilities for the virtual service.
5
- * Wraps core DataType conversions to return JavaScript primitives instead of BigNumber.
4
+ * Internal value conversion utilities for the virtual service.
6
5
  *
7
- * @example
8
- * // Convert from service string to primitive
9
- * fromServiceValue("100.50", "Decimal") // => 100.5 (number)
10
- * fromServiceValue("True", "Boolean") // => true (boolean)
11
- * fromServiceValue("15-01-2024 10:30:00", "DateTime") // => Date object
6
+ * NOTE: This file exists to avoid circular dependencies. Files like
7
+ * virtual-persistent-object.ts cannot import VirtualService directly
8
+ * (it would create a cycle), so they import these helpers instead.
12
9
  *
13
- * @example
14
- * // Convert from primitive to service string
15
- * toServiceValue(100.5, "Decimal") // => "100.5"
16
- * toServiceValue(true, "Boolean") // => "True"
17
- * toServiceValue(new Date(2024, 0, 15), "Date") // => "15-01-2024 00:00:00"
10
+ * Public API: Use VirtualService.fromServiceString() and VirtualService.toServiceString().
18
11
  */
19
12
  /**
20
13
  * Converts a service string value to a primitive JavaScript type.
21
14
  * Unlike DataType.fromServiceString, this returns number instead of BigNumber
22
15
  * for numeric types (Decimal, Double, Int64, etc.).
23
16
  */
24
- function fromServiceValue(value, type) {
17
+ function fromServiceString(value, type) {
25
18
  const result = DataType.fromServiceString(value, type);
26
19
  // Check for BigNumber (has toNumber method) and convert to number primitive
27
20
  if (result && typeof result.toNumber === "function")
@@ -31,7 +24,7 @@ function fromServiceValue(value, type) {
31
24
  /**
32
25
  * Converts a primitive JavaScript value to a service string.
33
26
  */
34
- function toServiceValue(value, type) {
27
+ function toServiceString(value, type) {
35
28
  return DataType.toServiceString(value, type);
36
29
  }
37
30
 
@@ -389,7 +382,7 @@ class VirtualQueryRegistry {
389
382
  const rawValue = data[column.name];
390
383
  return {
391
384
  key: column.name,
392
- value: rawValue == null ? null : toServiceValue(rawValue, column.type),
385
+ value: rawValue == null ? null : toServiceString(rawValue, column.type),
393
386
  objectId: data[column.name + "Id"],
394
387
  typeHints: data[column.name + "$typeHints"]
395
388
  };
@@ -478,8 +471,9 @@ function createVirtualQuery(dto, config, service) {
478
471
  return proxy;
479
472
  }
480
473
  /**
481
- * Unwraps a VirtualQuery to get the underlying DTO
482
- * @param wrapped - The VirtualQuery to unwrap
474
+ * Unwraps a VirtualQuery to get the underlying DTO.
475
+ * Also accepts raw DTOs for recursive handling.
476
+ * @param wrapped - The VirtualQuery or QueryDto to unwrap
483
477
  * @returns The underlying QueryDto
484
478
  */
485
479
  function unwrapVirtualQuery(wrapped) {
@@ -528,13 +522,14 @@ function createVirtualQueryResultItem(dto, query) {
528
522
  * @returns A VirtualPersistentObjectAttribute that combines DTO properties with helper methods
529
523
  */
530
524
  function createVirtualPersistentObjectAttribute(attr, persistentObject, service) {
525
+ const internalAttr = attr;
531
526
  const helpers = {
532
527
  getValue() {
533
- return fromServiceValue(attr.value, attr.type);
528
+ return internalAttr.value;
534
529
  },
535
530
  setValue(value) {
536
- attr.value = toServiceValue(value, attr.type);
537
- attr.isValueChanged = true;
531
+ internalAttr.value = value;
532
+ internalAttr.isValueChanged = true;
538
533
  },
539
534
  setValidationError(error) {
540
535
  attr.validationError = error || undefined;
@@ -546,7 +541,7 @@ function createVirtualPersistentObjectAttribute(attr, persistentObject, service)
546
541
  return service;
547
542
  }
548
543
  };
549
- return new Proxy(attr, {
544
+ return new Proxy(internalAttr, {
550
545
  get(target, prop) {
551
546
  if (prop in helpers) {
552
547
  const value = helpers[prop];
@@ -554,8 +549,19 @@ function createVirtualPersistentObjectAttribute(attr, persistentObject, service)
554
549
  }
555
550
  return target[prop];
556
551
  },
557
- set(target, prop, value) {
558
- target[prop] = value;
552
+ set(target, prop, newValue) {
553
+ if (prop === "value") {
554
+ const oldValue = target.value;
555
+ const hasChanged = oldValue instanceof Date && newValue instanceof Date
556
+ ? oldValue.getTime() !== newValue.getTime()
557
+ : oldValue !== newValue;
558
+ if (hasChanged) {
559
+ target.value = newValue;
560
+ target.isValueChanged = true;
561
+ }
562
+ }
563
+ else
564
+ target[prop] = newValue;
559
565
  return true;
560
566
  }
561
567
  });
@@ -623,15 +629,21 @@ function createVirtualPersistentObject(dto, service) {
623
629
  return proxy;
624
630
  }
625
631
  /**
626
- * Unwraps a VirtualPersistentObject to get the underlying DTO
627
- * Since the Proxy wraps the DTO, we can safely cast it back
628
- * @param wrapped - The VirtualPersistentObject to unwrap
629
- * @returns The underlying PersistentObjectDto
632
+ * Unwraps a VirtualPersistentObject to get a DTO suitable for wire transmission.
633
+ * Converts primitive values to service string format.
634
+ * Also accepts raw DTOs for recursive handling of parent/nested objects.
630
635
  */
631
636
  function unwrapVirtualPersistentObject(wrapped) {
632
- // The wrapped object is a Proxy around the DTO
633
- // We can return it as-is since the DTO is the target of the Proxy
634
- return wrapped;
637
+ const dto = wrapped;
638
+ return {
639
+ ...dto,
640
+ attributes: dto.attributes?.map(attr => ({
641
+ ...attr,
642
+ value: attr.value != null ? toServiceString(attr.value, attr.type) : attr.value
643
+ })),
644
+ parent: dto.parent ? unwrapVirtualPersistentObject(dto.parent) : undefined,
645
+ queries: dto.queries?.map(q => unwrapVirtualQuery(q))
646
+ };
635
647
  }
636
648
 
637
649
  var _a;
@@ -858,6 +870,9 @@ class VirtualServiceHooks extends ServiceHooks {
858
870
  clientAttr.tab = configAttr.tab || "";
859
871
  clientAttr.column = configAttr.column;
860
872
  clientAttr.columnSpan = configAttr.columnSpan;
873
+ // Convert incoming service string to primitive
874
+ if (clientAttr.value != null)
875
+ clientAttr.value = fromServiceString(clientAttr.value, clientAttr.type);
861
876
  // Reference attribute properties - only set if explicitly configured
862
877
  if (configAttr.lookup) {
863
878
  const refAttr = clientAttr;
@@ -1703,17 +1718,11 @@ class VirtualService extends Service {
1703
1718
  }
1704
1719
  /**
1705
1720
  * Converts a service string value to a primitive JavaScript type.
1706
- * Unlike DataType.fromServiceString, this returns number instead of BigNumber
1721
+ * Unlike Service.fromServiceString, this returns number instead of BigNumber
1707
1722
  * for numeric types (Decimal, Double, Int64, etc.).
1708
1723
  */
1709
- static fromServiceValue(value, type) {
1710
- return fromServiceValue(value, type);
1711
- }
1712
- /**
1713
- * Converts a primitive JavaScript value to a service string.
1714
- */
1715
- static toServiceValue(value, type) {
1716
- return toServiceValue(value, type);
1724
+ static fromServiceString(value, typeName) {
1725
+ return fromServiceString(value, typeName);
1717
1726
  }
1718
1727
  /**
1719
1728
  * Gets a message by key with optional parameters.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vidyano-labs/virtual-service",
3
- "version": "0.4.2",
3
+ "version": "0.5.0",
4
4
  "description": "Virtual service implementation for testing Vidyano applications",
5
5
  "type": "module",
6
6
  "main": "index.js",
@@ -20,5 +20,5 @@
20
20
  "publishConfig": {
21
21
  "access": "public"
22
22
  },
23
- "gitHash": "79e3626e489dad1001f311fcec3fb18e06b0a85a"
23
+ "gitHash": "3d37759c3014945a12137766692d4501d0eb465a"
24
24
  }