@vidyano-labs/virtual-service 0.1.0 → 0.1.1
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/index.d.ts +68 -55
- package/index.js +38 -14
- package/package.json +2 -2
package/index.d.ts
CHANGED
|
@@ -1,5 +1,58 @@
|
|
|
1
1
|
import { Dto, ServiceHooks, Service, Application } from '@vidyano/core';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* VirtualPersistentObjectAttribute combines a PersistentObjectAttributeDto with helper methods
|
|
5
|
+
* This allows clean syntax like attr.getValue() and attr.setValue() while keeping the underlying DTO unchanged
|
|
6
|
+
*/
|
|
7
|
+
type VirtualPersistentObjectAttribute = Dto.PersistentObjectAttributeDto & {
|
|
8
|
+
/**
|
|
9
|
+
* Gets the converted value of this attribute (e.g., Boolean as boolean, Int32 as number)
|
|
10
|
+
*/
|
|
11
|
+
getValue(): any;
|
|
12
|
+
/**
|
|
13
|
+
* Sets the value of this attribute with automatic type conversion
|
|
14
|
+
*/
|
|
15
|
+
setValue(value: any): void;
|
|
16
|
+
/**
|
|
17
|
+
* Sets a validation error on this attribute
|
|
18
|
+
*/
|
|
19
|
+
setValidationError(error: string): void;
|
|
20
|
+
/**
|
|
21
|
+
* Clears the validation error on this attribute
|
|
22
|
+
*/
|
|
23
|
+
clearValidationError(): void;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* VirtualPersistentObject combines a PersistentObjectDto with helper methods
|
|
27
|
+
* This allows clean syntax like obj.setAttributeValue() while keeping the underlying DTO unchanged
|
|
28
|
+
*/
|
|
29
|
+
type VirtualPersistentObject = Dto.PersistentObjectDto & {
|
|
30
|
+
/**
|
|
31
|
+
* Gets an attribute by name, wrapped with getValue/setValue methods
|
|
32
|
+
*/
|
|
33
|
+
getAttribute(name: string): VirtualPersistentObjectAttribute | undefined;
|
|
34
|
+
/**
|
|
35
|
+
* Gets the value of an attribute by name
|
|
36
|
+
*/
|
|
37
|
+
getAttributeValue(name: string): any;
|
|
38
|
+
/**
|
|
39
|
+
* Sets the value of an attribute by name
|
|
40
|
+
*/
|
|
41
|
+
setAttributeValue(name: string, value: any): void;
|
|
42
|
+
/**
|
|
43
|
+
* Sets a validation error for an attribute
|
|
44
|
+
*/
|
|
45
|
+
setValidationError(name: string, error: string): void;
|
|
46
|
+
/**
|
|
47
|
+
* Clears a validation error for an attribute
|
|
48
|
+
*/
|
|
49
|
+
clearValidationError(name: string): void;
|
|
50
|
+
/**
|
|
51
|
+
* Sets a notification message on the persistent object
|
|
52
|
+
*/
|
|
53
|
+
setNotification(message: string, type: Dto.NotificationType, duration?: number): void;
|
|
54
|
+
};
|
|
55
|
+
|
|
3
56
|
/**
|
|
4
57
|
* Simplified attribute configuration - converted to PersistentObjectAttributeDto
|
|
5
58
|
*/
|
|
@@ -184,6 +237,19 @@ type ActionContext = {
|
|
|
184
237
|
*/
|
|
185
238
|
setNotification: (message: string, type: Dto.NotificationType, duration?: number) => void;
|
|
186
239
|
};
|
|
240
|
+
/**
|
|
241
|
+
* Context provided to business rule validators for accessing the persistent object
|
|
242
|
+
*/
|
|
243
|
+
type RuleValidationContext = {
|
|
244
|
+
/**
|
|
245
|
+
* The persistent object being validated (wrapped with helper methods)
|
|
246
|
+
*/
|
|
247
|
+
persistentObject: VirtualPersistentObject;
|
|
248
|
+
/**
|
|
249
|
+
* The attribute being validated (wrapped with helper methods)
|
|
250
|
+
*/
|
|
251
|
+
attribute: VirtualPersistentObjectAttribute;
|
|
252
|
+
};
|
|
187
253
|
/**
|
|
188
254
|
* PersistentObject configuration - converted to PersistentObjectDto
|
|
189
255
|
*/
|
|
@@ -286,60 +352,7 @@ type VirtualQueryConfig = {
|
|
|
286
352
|
/**
|
|
287
353
|
* Rule validator function that throws an error if invalid, or returns nothing if valid
|
|
288
354
|
*/
|
|
289
|
-
type RuleValidatorFn = (value: any, ...params: any[]) => void;
|
|
290
|
-
|
|
291
|
-
/**
|
|
292
|
-
* VirtualPersistentObjectAttribute combines a PersistentObjectAttributeDto with helper methods
|
|
293
|
-
* This allows clean syntax like attr.getValue() and attr.setValue() while keeping the underlying DTO unchanged
|
|
294
|
-
*/
|
|
295
|
-
type VirtualPersistentObjectAttribute = Dto.PersistentObjectAttributeDto & {
|
|
296
|
-
/**
|
|
297
|
-
* Gets the converted value of this attribute (e.g., Boolean as boolean, Int32 as number)
|
|
298
|
-
*/
|
|
299
|
-
getValue(): any;
|
|
300
|
-
/**
|
|
301
|
-
* Sets the value of this attribute with automatic type conversion
|
|
302
|
-
*/
|
|
303
|
-
setValue(value: any): void;
|
|
304
|
-
/**
|
|
305
|
-
* Sets a validation error on this attribute
|
|
306
|
-
*/
|
|
307
|
-
setValidationError(error: string): void;
|
|
308
|
-
/**
|
|
309
|
-
* Clears the validation error on this attribute
|
|
310
|
-
*/
|
|
311
|
-
clearValidationError(): void;
|
|
312
|
-
};
|
|
313
|
-
/**
|
|
314
|
-
* VirtualPersistentObject combines a PersistentObjectDto with helper methods
|
|
315
|
-
* This allows clean syntax like obj.setAttributeValue() while keeping the underlying DTO unchanged
|
|
316
|
-
*/
|
|
317
|
-
type VirtualPersistentObject = Dto.PersistentObjectDto & {
|
|
318
|
-
/**
|
|
319
|
-
* Gets an attribute by name, wrapped with getValue/setValue methods
|
|
320
|
-
*/
|
|
321
|
-
getAttribute(name: string): VirtualPersistentObjectAttribute | undefined;
|
|
322
|
-
/**
|
|
323
|
-
* Gets the value of an attribute by name
|
|
324
|
-
*/
|
|
325
|
-
getAttributeValue(name: string): any;
|
|
326
|
-
/**
|
|
327
|
-
* Sets the value of an attribute by name
|
|
328
|
-
*/
|
|
329
|
-
setAttributeValue(name: string, value: any): void;
|
|
330
|
-
/**
|
|
331
|
-
* Sets a validation error for an attribute
|
|
332
|
-
*/
|
|
333
|
-
setValidationError(name: string, error: string): void;
|
|
334
|
-
/**
|
|
335
|
-
* Clears a validation error for an attribute
|
|
336
|
-
*/
|
|
337
|
-
clearValidationError(name: string): void;
|
|
338
|
-
/**
|
|
339
|
-
* Sets a notification message on the persistent object
|
|
340
|
-
*/
|
|
341
|
-
setNotification(message: string, type: Dto.NotificationType, duration?: number): void;
|
|
342
|
-
};
|
|
355
|
+
type RuleValidatorFn = (value: any, context: RuleValidationContext, ...params: any[]) => void;
|
|
343
356
|
|
|
344
357
|
/**
|
|
345
358
|
* Base class for PersistentObject lifecycle methods
|
|
@@ -556,4 +569,4 @@ declare class VirtualService extends Service {
|
|
|
556
569
|
}
|
|
557
570
|
|
|
558
571
|
export { VirtualPersistentObjectActions, VirtualService, VirtualServiceHooks };
|
|
559
|
-
export type { ActionArgs, ActionConfig, ActionContext, ActionHandler, RuleValidatorFn, VirtualPersistentObject, VirtualPersistentObjectAttribute, VirtualPersistentObjectAttributeConfig, VirtualPersistentObjectConfig, VirtualQueryConfig, VirtualQueryExecuteResult };
|
|
572
|
+
export type { ActionArgs, ActionConfig, ActionContext, ActionHandler, RuleValidationContext, RuleValidatorFn, VirtualPersistentObject, VirtualPersistentObjectAttribute, VirtualPersistentObjectAttributeConfig, VirtualPersistentObjectConfig, VirtualQueryConfig, VirtualQueryExecuteResult };
|
package/index.js
CHANGED
|
@@ -226,7 +226,7 @@ class VirtualPersistentObjectRegistry {
|
|
|
226
226
|
isRequired: attrConfig.isRequired || false
|
|
227
227
|
};
|
|
228
228
|
// Validate the attribute
|
|
229
|
-
const error = this.#validator.validateAttribute(attrWithRules);
|
|
229
|
+
const error = this.#validator.validateAttribute(attrWithRules, po);
|
|
230
230
|
if (error) {
|
|
231
231
|
attr.validationError = error;
|
|
232
232
|
hasErrors = true;
|
|
@@ -1234,13 +1234,33 @@ class BusinessRuleValidator {
|
|
|
1234
1234
|
}
|
|
1235
1235
|
/**
|
|
1236
1236
|
* Validate an attribute against its rules
|
|
1237
|
+
* @param attr - The attribute to validate
|
|
1238
|
+
* @param po - The persistent object containing the attribute
|
|
1237
1239
|
* @returns Error message if validation fails, null if valid
|
|
1238
1240
|
*/
|
|
1239
|
-
validateAttribute(attr) {
|
|
1241
|
+
validateAttribute(attr, po) {
|
|
1242
|
+
// Create conversion context for wrappers
|
|
1243
|
+
const conversionContext = {
|
|
1244
|
+
getConvertedValue: (attribute) => this.#getConvertedValue(attribute),
|
|
1245
|
+
setConvertedValue: (attribute, value) => {
|
|
1246
|
+
attribute.value = toServiceValue(value, attribute.type);
|
|
1247
|
+
attribute.isValueChanged = true;
|
|
1248
|
+
}
|
|
1249
|
+
};
|
|
1250
|
+
// Create wrapped objects for the validation context
|
|
1251
|
+
const wrappedPo = createVirtualPersistentObject(po, conversionContext);
|
|
1252
|
+
const wrappedAttr = createVirtualPersistentObjectAttribute(attr, conversionContext);
|
|
1253
|
+
// Create validation context
|
|
1254
|
+
const context = {
|
|
1255
|
+
persistentObject: wrappedPo,
|
|
1256
|
+
attribute: wrappedAttr
|
|
1257
|
+
};
|
|
1258
|
+
// Get the converted value (e.g., boolean from "True"/"False", number from string)
|
|
1259
|
+
const convertedValue = this.#getConvertedValue(attr);
|
|
1240
1260
|
// Check isRequired first
|
|
1241
1261
|
if (attr.isRequired) {
|
|
1242
1262
|
try {
|
|
1243
|
-
this.#validateNotEmpty(
|
|
1263
|
+
this.#validateNotEmpty(convertedValue, context);
|
|
1244
1264
|
}
|
|
1245
1265
|
catch (error) {
|
|
1246
1266
|
return error instanceof Error ? error.message : String(error);
|
|
@@ -1255,7 +1275,7 @@ class BusinessRuleValidator {
|
|
|
1255
1275
|
if (!validator)
|
|
1256
1276
|
throw new Error(`Unknown business rule: ${rule.name}`);
|
|
1257
1277
|
try {
|
|
1258
|
-
validator(
|
|
1278
|
+
validator(convertedValue, context, ...rule.params);
|
|
1259
1279
|
}
|
|
1260
1280
|
catch (error) {
|
|
1261
1281
|
return error instanceof Error ? error.message : String(error);
|
|
@@ -1308,15 +1328,19 @@ class BusinessRuleValidator {
|
|
|
1308
1328
|
});
|
|
1309
1329
|
return { name, params };
|
|
1310
1330
|
}
|
|
1331
|
+
// Helper to convert attribute values based on type
|
|
1332
|
+
#getConvertedValue(attr) {
|
|
1333
|
+
return fromServiceValue(attr.value, attr.type);
|
|
1334
|
+
}
|
|
1311
1335
|
// Built-in validators - throw errors instead of returning strings
|
|
1312
|
-
#validateIsBase64(value) {
|
|
1336
|
+
#validateIsBase64(value, context) {
|
|
1313
1337
|
if (value == null || value === "")
|
|
1314
1338
|
return;
|
|
1315
1339
|
const base64Regex = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;
|
|
1316
1340
|
if (!base64Regex.test(String(value)))
|
|
1317
1341
|
throw new Error("Value must be a valid base64 string");
|
|
1318
1342
|
}
|
|
1319
|
-
#validateIsEmail(value) {
|
|
1343
|
+
#validateIsEmail(value, context) {
|
|
1320
1344
|
if (value == null || value === "")
|
|
1321
1345
|
return;
|
|
1322
1346
|
// Only allow ASCII characters in email addresses
|
|
@@ -1324,7 +1348,7 @@ class BusinessRuleValidator {
|
|
|
1324
1348
|
if (!emailRegex.test(String(value)))
|
|
1325
1349
|
throw new Error("Email format is invalid");
|
|
1326
1350
|
}
|
|
1327
|
-
#validateIsRegex(value) {
|
|
1351
|
+
#validateIsRegex(value, context) {
|
|
1328
1352
|
if (value == null || value === "")
|
|
1329
1353
|
return;
|
|
1330
1354
|
try {
|
|
@@ -1334,7 +1358,7 @@ class BusinessRuleValidator {
|
|
|
1334
1358
|
throw new Error("Value must be a valid regular expression");
|
|
1335
1359
|
}
|
|
1336
1360
|
}
|
|
1337
|
-
#validateIsUrl(value) {
|
|
1361
|
+
#validateIsUrl(value, context) {
|
|
1338
1362
|
if (value == null || value === "")
|
|
1339
1363
|
return;
|
|
1340
1364
|
try {
|
|
@@ -1344,21 +1368,21 @@ class BusinessRuleValidator {
|
|
|
1344
1368
|
throw new Error("Value must be a valid URL");
|
|
1345
1369
|
}
|
|
1346
1370
|
}
|
|
1347
|
-
#validateIsWord(value) {
|
|
1371
|
+
#validateIsWord(value, context) {
|
|
1348
1372
|
if (value == null || value === "")
|
|
1349
1373
|
return;
|
|
1350
1374
|
const wordRegex = /^\w+$/;
|
|
1351
1375
|
if (!wordRegex.test(String(value)))
|
|
1352
1376
|
throw new Error("Value must contain only word characters");
|
|
1353
1377
|
}
|
|
1354
|
-
#validateMaxLength(value, maxLength) {
|
|
1378
|
+
#validateMaxLength(value, context, maxLength) {
|
|
1355
1379
|
if (value == null || value === "")
|
|
1356
1380
|
return;
|
|
1357
1381
|
const length = String(value).length;
|
|
1358
1382
|
if (length > maxLength)
|
|
1359
1383
|
throw new Error(`Maximum length is ${maxLength} characters`);
|
|
1360
1384
|
}
|
|
1361
|
-
#validateMaxValue(value, maximum) {
|
|
1385
|
+
#validateMaxValue(value, context, maximum) {
|
|
1362
1386
|
if (value == null || value === "")
|
|
1363
1387
|
return;
|
|
1364
1388
|
const num = Number(value);
|
|
@@ -1367,14 +1391,14 @@ class BusinessRuleValidator {
|
|
|
1367
1391
|
if (num > maximum)
|
|
1368
1392
|
throw new Error(`Maximum value is ${maximum}`);
|
|
1369
1393
|
}
|
|
1370
|
-
#validateMinLength(value, minLength) {
|
|
1394
|
+
#validateMinLength(value, context, minLength) {
|
|
1371
1395
|
if (value == null || value === "")
|
|
1372
1396
|
return;
|
|
1373
1397
|
const length = String(value).length;
|
|
1374
1398
|
if (length < minLength)
|
|
1375
1399
|
throw new Error(`Minimum length is ${minLength} characters`);
|
|
1376
1400
|
}
|
|
1377
|
-
#validateMinValue(value, minimum) {
|
|
1401
|
+
#validateMinValue(value, context, minimum) {
|
|
1378
1402
|
if (value == null || value === "")
|
|
1379
1403
|
return;
|
|
1380
1404
|
const num = Number(value);
|
|
@@ -1383,7 +1407,7 @@ class BusinessRuleValidator {
|
|
|
1383
1407
|
if (num < minimum)
|
|
1384
1408
|
throw new Error(`Minimum value is ${minimum}`);
|
|
1385
1409
|
}
|
|
1386
|
-
#validateNotEmpty(value) {
|
|
1410
|
+
#validateNotEmpty(value, context) {
|
|
1387
1411
|
if (value == null || value === "" || (typeof value === "string" && value.trim() === ""))
|
|
1388
1412
|
throw new Error("This field is required");
|
|
1389
1413
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vidyano-labs/virtual-service",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
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": "
|
|
23
|
+
"gitHash": "c69d76d2dd9e0289838ca50f1cc89a81fa9a89c3"
|
|
24
24
|
}
|