@qubit-ltd/common-decorator 3.10.0 → 3.10.2
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 +334 -0
- package/README.zh_CN.md +334 -0
- package/dist/common-decorator.cjs +150 -75
- package/dist/common-decorator.cjs.map +1 -1
- package/dist/common-decorator.min.cjs +1 -1
- package/dist/common-decorator.min.cjs.map +1 -1
- package/dist/common-decorator.min.mjs +1 -1
- package/dist/common-decorator.min.mjs.map +1 -1
- package/dist/common-decorator.mjs +143 -76
- package/dist/common-decorator.mjs.map +1 -1
- package/doc/api/DefaultAssignmentOptions.html +2 -2
- package/doc/api/DefaultOptions.html +2 -2
- package/doc/api/DefaultToJsonOptions.html +2 -2
- package/doc/api/Enum.html +2 -2
- package/doc/api/Model.html +2 -2
- package/doc/api/Page.html +2 -2
- package/doc/api/global.html +1515 -2
- package/doc/api/index.html +369 -2
- package/doc/common-decorator.min.visualization.html +1 -1
- package/doc/common-decorator.visualization.html +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -21,6 +21,7 @@ With this library, you can easily add common methods to your domain classes, imp
|
|
|
21
21
|
- **Normalization Support**: `@Normalizable` decorator enables field normalization
|
|
22
22
|
- **Type Safety**: `@Type` and `@ElementType` decorators for type checking
|
|
23
23
|
- **Serialization Utilities**: Built-in JSON serialization/deserialization support
|
|
24
|
+
- **Utility Functions**: Standalone helper functions for ID conversion, JSON serialization, and more
|
|
24
25
|
- **High Test Coverage**: Comprehensive test suite ensuring reliability of all features
|
|
25
26
|
|
|
26
27
|
## Installation
|
|
@@ -79,6 +80,17 @@ pnpm add @qubit-ltd/common-decorator
|
|
|
79
80
|
- [Configuration](#configuration)
|
|
80
81
|
- [Bundling with webpack](#webpack)
|
|
81
82
|
- [Bundling with vite](#vite)
|
|
83
|
+
- [Utility Functions](#utility-functions)
|
|
84
|
+
- [stringifyId](#stringifyId)
|
|
85
|
+
- [toJSON](#util-toJSON)
|
|
86
|
+
- [toJsonString](#util-toJsonString)
|
|
87
|
+
- [hasOwnProperty](#hasOwnProperty)
|
|
88
|
+
- [hasOwnPrototypeFunction](#hasOwnPrototypeFunction)
|
|
89
|
+
- [hasPrototypeFunction](#hasPrototypeFunction)
|
|
90
|
+
- [getDefaultInstance](#getDefaultInstance)
|
|
91
|
+
- [getFieldType](#getFieldType)
|
|
92
|
+
- [getFieldElementType](#getFieldElementType)
|
|
93
|
+
- [getSourceField](#getSourceField)
|
|
82
94
|
- [Recent Updates](#recent-updates)
|
|
83
95
|
- [Contributing](#contributing)
|
|
84
96
|
- [License](#license)
|
|
@@ -1163,6 +1175,328 @@ must be at least `7.24.0`.
|
|
|
1163
1175
|
});
|
|
1164
1176
|
```
|
|
1165
1177
|
|
|
1178
|
+
## <span id="utility-functions">Utility Functions</span>
|
|
1179
|
+
|
|
1180
|
+
The library provides several standalone utility functions that can be used without decorating classes.
|
|
1181
|
+
|
|
1182
|
+
### <span id="stringifyId">stringifyId(id)</span>
|
|
1183
|
+
|
|
1184
|
+
- Parameters:
|
|
1185
|
+
- `id: string|number|bigint`: The ID to be converted to a string.
|
|
1186
|
+
- Returns:
|
|
1187
|
+
- `string`: The string representation of the ID, or an empty string if the ID is `null` or `undefined`.
|
|
1188
|
+
|
|
1189
|
+
This function converts an ID to a string representation. It handles different types of IDs:
|
|
1190
|
+
- If the ID is `null` or `undefined`, it returns an empty string.
|
|
1191
|
+
- If the ID is already a string, it returns the string as is.
|
|
1192
|
+
- If the ID is a number or bigint, it converts it to a string.
|
|
1193
|
+
- If the ID is any other type of object, it serializes it to a JSON string.
|
|
1194
|
+
|
|
1195
|
+
```javascript
|
|
1196
|
+
import { stringifyId } from '@qubit-ltd/common-decorator';
|
|
1197
|
+
|
|
1198
|
+
stringifyId(123); // "123"
|
|
1199
|
+
stringifyId("abc"); // "abc"
|
|
1200
|
+
stringifyId(123456789012345678901n); // "123456789012345678901"
|
|
1201
|
+
stringifyId(null); // ""
|
|
1202
|
+
stringifyId(undefined); // ""
|
|
1203
|
+
stringifyId({ id: 123 }); // '{"id":123}'
|
|
1204
|
+
```
|
|
1205
|
+
|
|
1206
|
+
### <span id="util-toJSON">toJSON(value, options)</span>
|
|
1207
|
+
|
|
1208
|
+
- Parameters:
|
|
1209
|
+
- `value: any`: The value to be converted to a JSON-serializable object.
|
|
1210
|
+
- `options: null|undefined|object`: Additional options for serialization.
|
|
1211
|
+
- Returns:
|
|
1212
|
+
- `object`: A plain JavaScript object ready to be serialized by `JSON.stringify()`.
|
|
1213
|
+
|
|
1214
|
+
This function converts a value to an object that can be serialized by `JSON.stringify()`. If the value has a `toJSON()` method, it will use that method to determine what data to serialize.
|
|
1215
|
+
|
|
1216
|
+
Available options include:
|
|
1217
|
+
- `normalize: boolean`: Whether to normalize the object before serializing (default: `true`).
|
|
1218
|
+
- `removeEmptyFields: boolean`: Whether to remove empty fields from the object (default: `false`).
|
|
1219
|
+
- `convertNaming: boolean`: Whether to convert property names to a different naming style (default: `false`).
|
|
1220
|
+
- `sourceNamingStyle: string`: The naming style of source object (default: `'LOWER_CAMEL'`).
|
|
1221
|
+
- `targetNamingStyle: string`: The naming style for the resulting object (default: `'LOWER_UNDERSCORE'`).
|
|
1222
|
+
- `space: string|number`: Whitespace for formatting (default: `null`).
|
|
1223
|
+
|
|
1224
|
+
```javascript
|
|
1225
|
+
import { toJSON } from '@qubit-ltd/common-decorator';
|
|
1226
|
+
|
|
1227
|
+
const user = {
|
|
1228
|
+
firstName: 'John',
|
|
1229
|
+
lastName: 'Doe',
|
|
1230
|
+
age: 30,
|
|
1231
|
+
toJSON() {
|
|
1232
|
+
return {
|
|
1233
|
+
fullName: `${this.firstName} ${this.lastName}`,
|
|
1234
|
+
age: this.age,
|
|
1235
|
+
};
|
|
1236
|
+
},
|
|
1237
|
+
};
|
|
1238
|
+
|
|
1239
|
+
// Using the object's toJSON method
|
|
1240
|
+
const result = toJSON(user);
|
|
1241
|
+
// { fullName: 'John Doe', age: 30 }
|
|
1242
|
+
|
|
1243
|
+
// Converting naming style
|
|
1244
|
+
const resultWithNaming = toJSON(user, {
|
|
1245
|
+
convertNaming: true,
|
|
1246
|
+
sourceNamingStyle: 'LOWER_CAMEL',
|
|
1247
|
+
targetNamingStyle: 'LOWER_UNDERSCORE',
|
|
1248
|
+
});
|
|
1249
|
+
// { full_name: 'John Doe', age: 30 }
|
|
1250
|
+
```
|
|
1251
|
+
|
|
1252
|
+
### <span id="util-toJsonString">toJsonString(obj, options)</span>
|
|
1253
|
+
|
|
1254
|
+
- Parameters:
|
|
1255
|
+
- `obj: object`: The object to be serialized into a JSON string.
|
|
1256
|
+
- `options: null|undefined|object`: Additional options for serialization.
|
|
1257
|
+
- Returns:
|
|
1258
|
+
- `string`: A JSON string representation of the object.
|
|
1259
|
+
|
|
1260
|
+
This function serializes an object to a JSON string with additional options. It supports native `bigint` values and other customization options.
|
|
1261
|
+
|
|
1262
|
+
Available options are the same as for `toJSON()`.
|
|
1263
|
+
|
|
1264
|
+
```javascript
|
|
1265
|
+
import { toJsonString } from '@qubit-ltd/common-decorator';
|
|
1266
|
+
|
|
1267
|
+
const user = {
|
|
1268
|
+
firstName: 'John',
|
|
1269
|
+
lastName: 'Doe',
|
|
1270
|
+
age: 30,
|
|
1271
|
+
};
|
|
1272
|
+
|
|
1273
|
+
// Basic serialization
|
|
1274
|
+
const json = toJsonString(user);
|
|
1275
|
+
// '{"firstName":"John","lastName":"Doe","age":30}'
|
|
1276
|
+
|
|
1277
|
+
// Pretty-printed JSON with naming style conversion
|
|
1278
|
+
const prettyJson = toJsonString(user, {
|
|
1279
|
+
convertNaming: true,
|
|
1280
|
+
sourceNamingStyle: 'LOWER_CAMEL',
|
|
1281
|
+
targetNamingStyle: 'LOWER_UNDERSCORE',
|
|
1282
|
+
space: 2,
|
|
1283
|
+
});
|
|
1284
|
+
/*
|
|
1285
|
+
{
|
|
1286
|
+
"first_name": "John",
|
|
1287
|
+
"last_name": "Doe",
|
|
1288
|
+
"age": 30
|
|
1289
|
+
}
|
|
1290
|
+
*/
|
|
1291
|
+
|
|
1292
|
+
// Handling bigint values
|
|
1293
|
+
const bigData = {
|
|
1294
|
+
id: 9223372036854775807n,
|
|
1295
|
+
name: 'Big Integer'
|
|
1296
|
+
};
|
|
1297
|
+
toJsonString(bigData);
|
|
1298
|
+
// '{"id":9223372036854775807,"name":"Big Integer"}'
|
|
1299
|
+
```
|
|
1300
|
+
|
|
1301
|
+
### <span id="hasOwnProperty">hasOwnProperty(Class, field)</span>
|
|
1302
|
+
|
|
1303
|
+
- Parameters:
|
|
1304
|
+
- `Class: function`: The constructor of the class to check.
|
|
1305
|
+
- `field: string`: The name of the property to check for.
|
|
1306
|
+
- Returns:
|
|
1307
|
+
- `boolean`: Returns true if and only if the property is directly defined by the class (either on its prototype or default instance), not inherited from parent classes.
|
|
1308
|
+
|
|
1309
|
+
This function determines whether a class directly owns a specific property. Unlike JavaScript's built-in `Object.prototype.hasOwnProperty`, this function accepts a class constructor rather than an object instance, checks both the prototype and default instance, and only reports properties owned directly by the class, not those inherited from parent classes.
|
|
1310
|
+
|
|
1311
|
+
```javascript
|
|
1312
|
+
import { hasOwnProperty } from '@qubit-ltd/common-decorator';
|
|
1313
|
+
|
|
1314
|
+
class Parent {
|
|
1315
|
+
constructor() {
|
|
1316
|
+
this.parentField = 'parent';
|
|
1317
|
+
}
|
|
1318
|
+
}
|
|
1319
|
+
|
|
1320
|
+
class Child extends Parent {
|
|
1321
|
+
constructor() {
|
|
1322
|
+
super();
|
|
1323
|
+
this.childField = 'child';
|
|
1324
|
+
}
|
|
1325
|
+
}
|
|
1326
|
+
|
|
1327
|
+
hasOwnProperty(Child, 'childField'); // true
|
|
1328
|
+
hasOwnProperty(Child, 'parentField'); // false (inherited from Parent)
|
|
1329
|
+
```
|
|
1330
|
+
|
|
1331
|
+
### <span id="hasOwnPrototypeFunction">hasOwnPrototypeFunction(Class, name)</span>
|
|
1332
|
+
|
|
1333
|
+
- Parameters:
|
|
1334
|
+
- `Class: function`: Constructor for the specified class.
|
|
1335
|
+
- `name: string`: The name of the specified prototype function.
|
|
1336
|
+
- Returns:
|
|
1337
|
+
- `boolean`: Returns true if and only if the specified function is directly defined on the prototype of the class itself (not inherited from parent classes).
|
|
1338
|
+
|
|
1339
|
+
This function determines whether the specified prototype function is directly defined in the prototype of a specified class (not inherited from parent classes). It uses `Object.prototype.hasOwnProperty` to ensure only "own properties" of the prototype are considered.
|
|
1340
|
+
|
|
1341
|
+
```javascript
|
|
1342
|
+
import { hasOwnPrototypeFunction } from '@qubit-ltd/common-decorator';
|
|
1343
|
+
|
|
1344
|
+
class Parent {
|
|
1345
|
+
parentMethod() { return 'parent'; }
|
|
1346
|
+
}
|
|
1347
|
+
|
|
1348
|
+
class Child extends Parent {
|
|
1349
|
+
childMethod() { return 'child'; }
|
|
1350
|
+
}
|
|
1351
|
+
|
|
1352
|
+
hasOwnPrototypeFunction(Child, 'childMethod'); // true
|
|
1353
|
+
hasOwnPrototypeFunction(Child, 'parentMethod'); // false (inherited from Parent)
|
|
1354
|
+
```
|
|
1355
|
+
|
|
1356
|
+
### <span id="hasPrototypeFunction">hasPrototypeFunction(Class, name)</span>
|
|
1357
|
+
|
|
1358
|
+
- Parameters:
|
|
1359
|
+
- `Class: function`: Constructor for the specified class.
|
|
1360
|
+
- `name: string`: The name of the specified prototype function.
|
|
1361
|
+
- Returns:
|
|
1362
|
+
- `boolean`: Returns true if the specified function exists anywhere in the prototype chain of the class, whether defined by the class itself or inherited from a parent class.
|
|
1363
|
+
|
|
1364
|
+
This function determines whether the specified prototype function exists anywhere in the prototype chain of a specified class. It checks the entire prototype chain, including methods inherited from parent classes, using `Reflect.has()`.
|
|
1365
|
+
|
|
1366
|
+
```javascript
|
|
1367
|
+
import { hasPrototypeFunction } from '@qubit-ltd/common-decorator';
|
|
1368
|
+
|
|
1369
|
+
class Parent {
|
|
1370
|
+
parentMethod() { return 'parent'; }
|
|
1371
|
+
}
|
|
1372
|
+
|
|
1373
|
+
class Child extends Parent {
|
|
1374
|
+
childMethod() { return 'child'; }
|
|
1375
|
+
}
|
|
1376
|
+
|
|
1377
|
+
hasPrototypeFunction(Child, 'childMethod'); // true
|
|
1378
|
+
hasPrototypeFunction(Child, 'parentMethod'); // true (inherited from Parent)
|
|
1379
|
+
```
|
|
1380
|
+
|
|
1381
|
+
### <span id="getDefaultInstance">getDefaultInstance(Class)</span>
|
|
1382
|
+
|
|
1383
|
+
- Parameters:
|
|
1384
|
+
- `Class: function`: The constructor of the specified class.
|
|
1385
|
+
- Returns:
|
|
1386
|
+
- `object`: The default instance of the specified class, or a new instance will be created if it does not exist.
|
|
1387
|
+
|
|
1388
|
+
This function gets the default instance of the specified class, or creates a new instance if it does not exist. It's used internally by many of the library's functions to get default values.
|
|
1389
|
+
|
|
1390
|
+
```javascript
|
|
1391
|
+
import { getDefaultInstance } from '@qubit-ltd/common-decorator';
|
|
1392
|
+
|
|
1393
|
+
class User {
|
|
1394
|
+
constructor() {
|
|
1395
|
+
this.name = '';
|
|
1396
|
+
this.age = 0;
|
|
1397
|
+
}
|
|
1398
|
+
}
|
|
1399
|
+
|
|
1400
|
+
const defaultUser = getDefaultInstance(User);
|
|
1401
|
+
console.log(defaultUser.name); // ''
|
|
1402
|
+
console.log(defaultUser.age); // 0
|
|
1403
|
+
```
|
|
1404
|
+
|
|
1405
|
+
### <span id="getFieldType">getFieldType(Class, field, path, options)</span>
|
|
1406
|
+
|
|
1407
|
+
- Parameters:
|
|
1408
|
+
- `Class: function`: The constructor of the class of the object.
|
|
1409
|
+
- `field: string`: The name of the field.
|
|
1410
|
+
- `path: string` (optional): The path of the field in the property tree of the original root object.
|
|
1411
|
+
- `options: object` (optional): Additional options for type resolution.
|
|
1412
|
+
- Returns:
|
|
1413
|
+
- `function|undefined`: The type of the specified field of the object, or `undefined` if the field type cannot be inferred.
|
|
1414
|
+
|
|
1415
|
+
This function gets the type of the specified field of an object. It first checks the annotated type information, then the additional type information in options, and finally tries to infer from the default field value.
|
|
1416
|
+
|
|
1417
|
+
```javascript
|
|
1418
|
+
import { getFieldType } from '@qubit-ltd/common-decorator';
|
|
1419
|
+
|
|
1420
|
+
class Address {
|
|
1421
|
+
constructor() {
|
|
1422
|
+
this.street = '';
|
|
1423
|
+
this.city = '';
|
|
1424
|
+
}
|
|
1425
|
+
}
|
|
1426
|
+
|
|
1427
|
+
class User {
|
|
1428
|
+
constructor() {
|
|
1429
|
+
this.name = '';
|
|
1430
|
+
this.address = new Address();
|
|
1431
|
+
}
|
|
1432
|
+
}
|
|
1433
|
+
|
|
1434
|
+
const addressType = getFieldType(User, 'address');
|
|
1435
|
+
console.log(addressType === Address); // true
|
|
1436
|
+
```
|
|
1437
|
+
|
|
1438
|
+
### <span id="getFieldElementType">getFieldElementType(Class, field, path, options)</span>
|
|
1439
|
+
|
|
1440
|
+
- Parameters:
|
|
1441
|
+
- `Class: function`: The constructor of the class of the object.
|
|
1442
|
+
- `field: string`: The name of the field.
|
|
1443
|
+
- `path: string` (optional): The path of the field in the property tree of the original root object.
|
|
1444
|
+
- `options: object` (optional): Additional options for type resolution.
|
|
1445
|
+
- Returns:
|
|
1446
|
+
- `function|null`: The element type of the specified field of the object, or `null` if the field element type cannot be inferred.
|
|
1447
|
+
|
|
1448
|
+
This function gets the element type of a field of an object, particularly useful for collections (arrays, sets, maps). It checks annotated element type information, additional type information in options, and tries to infer from default field values.
|
|
1449
|
+
|
|
1450
|
+
```javascript
|
|
1451
|
+
import { getFieldElementType, ElementType } from '@qubit-ltd/common-decorator';
|
|
1452
|
+
|
|
1453
|
+
class Item {
|
|
1454
|
+
constructor() {
|
|
1455
|
+
this.id = 0;
|
|
1456
|
+
this.name = '';
|
|
1457
|
+
}
|
|
1458
|
+
}
|
|
1459
|
+
|
|
1460
|
+
class Shop {
|
|
1461
|
+
constructor() {
|
|
1462
|
+
this.items = [];
|
|
1463
|
+
}
|
|
1464
|
+
}
|
|
1465
|
+
|
|
1466
|
+
// Using decorator to specify element type
|
|
1467
|
+
class DecoratedShop {
|
|
1468
|
+
constructor() {
|
|
1469
|
+
this.items = [];
|
|
1470
|
+
}
|
|
1471
|
+
}
|
|
1472
|
+
ElementType(Item)(DecoratedShop, 'items');
|
|
1473
|
+
|
|
1474
|
+
console.log(getFieldElementType(DecoratedShop, 'items') === Item); // true
|
|
1475
|
+
```
|
|
1476
|
+
|
|
1477
|
+
### <span id="getSourceField">getSourceField(targetField, options)</span>
|
|
1478
|
+
|
|
1479
|
+
- Parameters:
|
|
1480
|
+
- `targetField: string`: The key of the target object.
|
|
1481
|
+
- `options: object`: The options for naming style conversion.
|
|
1482
|
+
- Returns:
|
|
1483
|
+
- `string`: The corresponding key of the source object.
|
|
1484
|
+
|
|
1485
|
+
This function gets the name of the field of the source object from the corresponding field of the target object, supporting naming style conversion between different conventions (camelCase, snake_case, etc.).
|
|
1486
|
+
|
|
1487
|
+
```javascript
|
|
1488
|
+
import { getSourceField } from '@qubit-ltd/common-decorator';
|
|
1489
|
+
|
|
1490
|
+
const options = {
|
|
1491
|
+
convertNaming: true,
|
|
1492
|
+
sourceNamingStyle: 'LOWER_UNDERSCORE',
|
|
1493
|
+
targetNamingStyle: 'LOWER_CAMEL',
|
|
1494
|
+
};
|
|
1495
|
+
|
|
1496
|
+
const sourceField = getSourceField('firstName', options);
|
|
1497
|
+
console.log(sourceField); // 'first_name'
|
|
1498
|
+
```
|
|
1499
|
+
|
|
1166
1500
|
## <span id="recent-updates">Recent Updates</span>
|
|
1167
1501
|
|
|
1168
1502
|
### Test Coverage Enhancements (December 2023)
|
package/README.zh_CN.md
CHANGED
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
- **规范化支持**:`@Normalizable` 装饰器实现字段规范化
|
|
22
22
|
- **类型安全**:`@Type` 和 `@ElementType` 装饰器用于类型检查
|
|
23
23
|
- **序列化工具**:内置 JSON 序列化/反序列化支持
|
|
24
|
+
- **工具函数**:独立的辅助函数,用于ID转换、JSON序列化等功能
|
|
24
25
|
- **高测试覆盖率**:全面的测试套件确保所有功能的可靠性
|
|
25
26
|
|
|
26
27
|
## 安装
|
|
@@ -79,6 +80,17 @@ pnpm add @qubit-ltd/common-decorator
|
|
|
79
80
|
- [配置](#configuration)
|
|
80
81
|
- [使用 webpack 打包](#webpack)
|
|
81
82
|
- [使用 vite 打包](#vite)
|
|
83
|
+
- [工具函数](#utility-functions)
|
|
84
|
+
- [stringifyId](#stringifyId)
|
|
85
|
+
- [toJSON](#util-toJSON)
|
|
86
|
+
- [toJsonString](#util-toJsonString)
|
|
87
|
+
- [hasOwnProperty](#hasOwnProperty)
|
|
88
|
+
- [hasOwnPrototypeFunction](#hasOwnPrototypeFunction)
|
|
89
|
+
- [hasPrototypeFunction](#hasPrototypeFunction)
|
|
90
|
+
- [getDefaultInstance](#getDefaultInstance)
|
|
91
|
+
- [getFieldType](#getFieldType)
|
|
92
|
+
- [getFieldElementType](#getFieldElementType)
|
|
93
|
+
- [getSourceField](#getSourceField)
|
|
82
94
|
- [最新更新](#recent-updates)
|
|
83
95
|
- [贡献](#contributing)
|
|
84
96
|
- [许可证](#license)
|
|
@@ -939,6 +951,328 @@ expect(opt1.convertNaming).toBe(false);
|
|
|
939
951
|
});
|
|
940
952
|
```
|
|
941
953
|
|
|
954
|
+
## <span id="utility-functions">工具函数</span>
|
|
955
|
+
|
|
956
|
+
本库提供了几个独立的工具函数,可以在不装饰类的情况下使用。
|
|
957
|
+
|
|
958
|
+
### <span id="stringifyId">stringifyId(id)</span>
|
|
959
|
+
|
|
960
|
+
- 参数:
|
|
961
|
+
- `id: string|number|bigint`:要转换为字符串的ID。
|
|
962
|
+
- 返回值:
|
|
963
|
+
- `string`:ID的字符串表示形式,如果ID为`null`或`undefined`,则返回空字符串。
|
|
964
|
+
|
|
965
|
+
此函数将ID转换为字符串表示形式。它处理不同类型的ID:
|
|
966
|
+
- 如果ID为`null`或`undefined`,则返回空字符串。
|
|
967
|
+
- 如果ID已经是字符串,则按原样返回该字符串。
|
|
968
|
+
- 如果ID是数字或bigint,则将其转换为字符串。
|
|
969
|
+
- 如果ID是任何其他类型的对象,则将其序列化为JSON字符串。
|
|
970
|
+
|
|
971
|
+
```javascript
|
|
972
|
+
import { stringifyId } from '@qubit-ltd/common-decorator';
|
|
973
|
+
|
|
974
|
+
stringifyId(123); // "123"
|
|
975
|
+
stringifyId("abc"); // "abc"
|
|
976
|
+
stringifyId(123456789012345678901n); // "123456789012345678901"
|
|
977
|
+
stringifyId(null); // ""
|
|
978
|
+
stringifyId(undefined); // ""
|
|
979
|
+
stringifyId({ id: 123 }); // '{"id":123}'
|
|
980
|
+
```
|
|
981
|
+
|
|
982
|
+
### <span id="util-toJSON">toJSON(value, options)</span>
|
|
983
|
+
|
|
984
|
+
- 参数:
|
|
985
|
+
- `value: any`:要转换为可JSON序列化对象的值。
|
|
986
|
+
- `options: null|undefined|object`:序列化的附加选项。
|
|
987
|
+
- 返回值:
|
|
988
|
+
- `object`:可以被`JSON.stringify()`序列化的普通JavaScript对象。
|
|
989
|
+
|
|
990
|
+
此函数将值转换为可以被`JSON.stringify()`序列化的对象。如果该值具有`toJSON()`方法,则将使用该方法来确定要序列化的数据。
|
|
991
|
+
|
|
992
|
+
可用选项包括:
|
|
993
|
+
- `normalize: boolean`:是否在序列化前规范化对象(默认值:`true`)。
|
|
994
|
+
- `removeEmptyFields: boolean`:是否从对象中删除空字段(默认值:`false`)。
|
|
995
|
+
- `convertNaming: boolean`:是否将属性名转换为不同的命名风格(默认值:`false`)。
|
|
996
|
+
- `sourceNamingStyle: string`:源对象的命名风格(默认值:`'LOWER_CAMEL'`)。
|
|
997
|
+
- `targetNamingStyle: string`:结果对象的命名风格(默认值:`'LOWER_UNDERSCORE'`)。
|
|
998
|
+
- `space: string|number`:用于格式化的空白字符(默认值:`null`)。
|
|
999
|
+
|
|
1000
|
+
```javascript
|
|
1001
|
+
import { toJSON } from '@qubit-ltd/common-decorator';
|
|
1002
|
+
|
|
1003
|
+
const user = {
|
|
1004
|
+
firstName: 'John',
|
|
1005
|
+
lastName: 'Doe',
|
|
1006
|
+
age: 30,
|
|
1007
|
+
toJSON() {
|
|
1008
|
+
return {
|
|
1009
|
+
fullName: `${this.firstName} ${this.lastName}`,
|
|
1010
|
+
age: this.age,
|
|
1011
|
+
};
|
|
1012
|
+
},
|
|
1013
|
+
};
|
|
1014
|
+
|
|
1015
|
+
// 使用对象的toJSON方法
|
|
1016
|
+
const result = toJSON(user);
|
|
1017
|
+
// { fullName: 'John Doe', age: 30 }
|
|
1018
|
+
|
|
1019
|
+
// 转换命名风格
|
|
1020
|
+
const resultWithNaming = toJSON(user, {
|
|
1021
|
+
convertNaming: true,
|
|
1022
|
+
sourceNamingStyle: 'LOWER_CAMEL',
|
|
1023
|
+
targetNamingStyle: 'LOWER_UNDERSCORE',
|
|
1024
|
+
});
|
|
1025
|
+
// { full_name: 'John Doe', age: 30 }
|
|
1026
|
+
```
|
|
1027
|
+
|
|
1028
|
+
### <span id="util-toJsonString">toJsonString(obj, options)</span>
|
|
1029
|
+
|
|
1030
|
+
- 参数:
|
|
1031
|
+
- `obj: object`:要序列化为JSON字符串的对象。
|
|
1032
|
+
- `options: null|undefined|object`:序列化的附加选项。
|
|
1033
|
+
- 返回值:
|
|
1034
|
+
- `string`:对象的JSON字符串表示形式。
|
|
1035
|
+
|
|
1036
|
+
此函数将对象序列化为具有附加选项的JSON字符串。它支持原生`bigint`值和其他自定义选项。
|
|
1037
|
+
|
|
1038
|
+
可用选项与`toJSON()`相同。
|
|
1039
|
+
|
|
1040
|
+
```javascript
|
|
1041
|
+
import { toJsonString } from '@qubit-ltd/common-decorator';
|
|
1042
|
+
|
|
1043
|
+
const user = {
|
|
1044
|
+
firstName: 'John',
|
|
1045
|
+
lastName: 'Doe',
|
|
1046
|
+
age: 30,
|
|
1047
|
+
};
|
|
1048
|
+
|
|
1049
|
+
// 基本序列化
|
|
1050
|
+
const json = toJsonString(user);
|
|
1051
|
+
// '{"firstName":"John","lastName":"Doe","age":30}'
|
|
1052
|
+
|
|
1053
|
+
// 带有命名风格转换的美化JSON
|
|
1054
|
+
const prettyJson = toJsonString(user, {
|
|
1055
|
+
convertNaming: true,
|
|
1056
|
+
sourceNamingStyle: 'LOWER_CAMEL',
|
|
1057
|
+
targetNamingStyle: 'LOWER_UNDERSCORE',
|
|
1058
|
+
space: 2,
|
|
1059
|
+
});
|
|
1060
|
+
/*
|
|
1061
|
+
{
|
|
1062
|
+
"first_name": "John",
|
|
1063
|
+
"last_name": "Doe",
|
|
1064
|
+
"age": 30
|
|
1065
|
+
}
|
|
1066
|
+
*/
|
|
1067
|
+
|
|
1068
|
+
// 处理bigint值
|
|
1069
|
+
const bigData = {
|
|
1070
|
+
id: 9223372036854775807n,
|
|
1071
|
+
name: 'Big Integer'
|
|
1072
|
+
};
|
|
1073
|
+
toJsonString(bigData);
|
|
1074
|
+
// '{"id":9223372036854775807,"name":"Big Integer"}'
|
|
1075
|
+
```
|
|
1076
|
+
|
|
1077
|
+
### <span id="hasOwnProperty">hasOwnProperty(Class, field)</span>
|
|
1078
|
+
|
|
1079
|
+
- 参数:
|
|
1080
|
+
- `Class: function`:要检查的类的构造函数。
|
|
1081
|
+
- `field: string`:要检查的属性名称。
|
|
1082
|
+
- 返回值:
|
|
1083
|
+
- `boolean`:仅当该属性由类直接定义(无论是在其原型上还是在默认实例上)而非从父类继承时,返回true。
|
|
1084
|
+
|
|
1085
|
+
此函数确定一个类是否直接拥有特定属性。与JavaScript内置的`Object.prototype.hasOwnProperty`不同,此函数接受类构造函数而非对象实例,同时检查原型和默认实例,并且只报告由类直接拥有的属性,而非那些从父类继承的属性。
|
|
1086
|
+
|
|
1087
|
+
```javascript
|
|
1088
|
+
import { hasOwnProperty } from '@qubit-ltd/common-decorator';
|
|
1089
|
+
|
|
1090
|
+
class Parent {
|
|
1091
|
+
constructor() {
|
|
1092
|
+
this.parentField = 'parent';
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1095
|
+
|
|
1096
|
+
class Child extends Parent {
|
|
1097
|
+
constructor() {
|
|
1098
|
+
super();
|
|
1099
|
+
this.childField = 'child';
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1103
|
+
hasOwnProperty(Child, 'childField'); // true
|
|
1104
|
+
hasOwnProperty(Child, 'parentField'); // false (从Parent继承)
|
|
1105
|
+
```
|
|
1106
|
+
|
|
1107
|
+
### <span id="hasOwnPrototypeFunction">hasOwnPrototypeFunction(Class, name)</span>
|
|
1108
|
+
|
|
1109
|
+
- 参数:
|
|
1110
|
+
- `Class: function`:指定类的构造函数。
|
|
1111
|
+
- `name: string`:指定原型函数的名称。
|
|
1112
|
+
- 返回值:
|
|
1113
|
+
- `boolean`:当且仅当指定函数直接定义在类本身的原型上(不是从父类继承)时返回true。
|
|
1114
|
+
|
|
1115
|
+
此函数确定指定的原型函数是否直接定义在指定类的原型中(不是从父类继承)。它使用`Object.prototype.hasOwnProperty`来确保只考虑原型的"自有属性"。
|
|
1116
|
+
|
|
1117
|
+
```javascript
|
|
1118
|
+
import { hasOwnPrototypeFunction } from '@qubit-ltd/common-decorator';
|
|
1119
|
+
|
|
1120
|
+
class Parent {
|
|
1121
|
+
parentMethod() { return 'parent'; }
|
|
1122
|
+
}
|
|
1123
|
+
|
|
1124
|
+
class Child extends Parent {
|
|
1125
|
+
childMethod() { return 'child'; }
|
|
1126
|
+
}
|
|
1127
|
+
|
|
1128
|
+
hasOwnPrototypeFunction(Child, 'childMethod'); // true
|
|
1129
|
+
hasOwnPrototypeFunction(Child, 'parentMethod'); // false (从Parent继承)
|
|
1130
|
+
```
|
|
1131
|
+
|
|
1132
|
+
### <span id="hasPrototypeFunction">hasPrototypeFunction(Class, name)</span>
|
|
1133
|
+
|
|
1134
|
+
- 参数:
|
|
1135
|
+
- `Class: function`:指定类的构造函数。
|
|
1136
|
+
- `name: string`:指定原型函数的名称。
|
|
1137
|
+
- 返回值:
|
|
1138
|
+
- `boolean`:如果指定函数存在于类的原型链中的任何位置(无论是由类本身定义还是从父类继承),则返回true。
|
|
1139
|
+
|
|
1140
|
+
此函数确定指定的原型函数是否存在于指定类的原型链中的任何位置。它检查整个原型链,包括从父类继承的方法,使用`Reflect.has()`。
|
|
1141
|
+
|
|
1142
|
+
```javascript
|
|
1143
|
+
import { hasPrototypeFunction } from '@qubit-ltd/common-decorator';
|
|
1144
|
+
|
|
1145
|
+
class Parent {
|
|
1146
|
+
parentMethod() { return 'parent'; }
|
|
1147
|
+
}
|
|
1148
|
+
|
|
1149
|
+
class Child extends Parent {
|
|
1150
|
+
childMethod() { return 'child'; }
|
|
1151
|
+
}
|
|
1152
|
+
|
|
1153
|
+
hasPrototypeFunction(Child, 'childMethod'); // true
|
|
1154
|
+
hasPrototypeFunction(Child, 'parentMethod'); // true (从Parent继承)
|
|
1155
|
+
```
|
|
1156
|
+
|
|
1157
|
+
### <span id="getDefaultInstance">getDefaultInstance(Class)</span>
|
|
1158
|
+
|
|
1159
|
+
- 参数:
|
|
1160
|
+
- `Class: function`:指定类的构造函数。
|
|
1161
|
+
- 返回值:
|
|
1162
|
+
- `object`:指定类的默认实例,如果不存在则创建一个新实例。
|
|
1163
|
+
|
|
1164
|
+
此函数获取指定类的默认实例,如果不存在则创建一个新实例。它被库的许多函数内部使用,以获取默认值。
|
|
1165
|
+
|
|
1166
|
+
```javascript
|
|
1167
|
+
import { getDefaultInstance } from '@qubit-ltd/common-decorator';
|
|
1168
|
+
|
|
1169
|
+
class User {
|
|
1170
|
+
constructor() {
|
|
1171
|
+
this.name = '';
|
|
1172
|
+
this.age = 0;
|
|
1173
|
+
}
|
|
1174
|
+
}
|
|
1175
|
+
|
|
1176
|
+
const defaultUser = getDefaultInstance(User);
|
|
1177
|
+
console.log(defaultUser.name); // ''
|
|
1178
|
+
console.log(defaultUser.age); // 0
|
|
1179
|
+
```
|
|
1180
|
+
|
|
1181
|
+
### <span id="getFieldType">getFieldType(Class, field, path, options)</span>
|
|
1182
|
+
|
|
1183
|
+
- 参数:
|
|
1184
|
+
- `Class: function`:对象所属类的构造函数。
|
|
1185
|
+
- `field: string`:字段的名称。
|
|
1186
|
+
- `path: string`(可选):字段在原始根对象的属性树中的路径。
|
|
1187
|
+
- `options: object`(可选):类型解析的附加选项。
|
|
1188
|
+
- 返回值:
|
|
1189
|
+
- `function|undefined`:对象指定字段的类型,如果无法推断字段类型,则为`undefined`。
|
|
1190
|
+
|
|
1191
|
+
此函数获取对象指定字段的类型。它首先检查注解的类型信息,然后检查选项中的附加类型信息,最后尝试从默认字段值推断。
|
|
1192
|
+
|
|
1193
|
+
```javascript
|
|
1194
|
+
import { getFieldType } from '@qubit-ltd/common-decorator';
|
|
1195
|
+
|
|
1196
|
+
class Address {
|
|
1197
|
+
constructor() {
|
|
1198
|
+
this.street = '';
|
|
1199
|
+
this.city = '';
|
|
1200
|
+
}
|
|
1201
|
+
}
|
|
1202
|
+
|
|
1203
|
+
class User {
|
|
1204
|
+
constructor() {
|
|
1205
|
+
this.name = '';
|
|
1206
|
+
this.address = new Address();
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
1209
|
+
|
|
1210
|
+
const addressType = getFieldType(User, 'address');
|
|
1211
|
+
console.log(addressType === Address); // true
|
|
1212
|
+
```
|
|
1213
|
+
|
|
1214
|
+
### <span id="getFieldElementType">getFieldElementType(Class, field, path, options)</span>
|
|
1215
|
+
|
|
1216
|
+
- 参数:
|
|
1217
|
+
- `Class: function`:对象所属类的构造函数。
|
|
1218
|
+
- `field: string`:字段的名称。
|
|
1219
|
+
- `path: string`(可选):字段在原始根对象的属性树中的路径。
|
|
1220
|
+
- `options: object`(可选):类型解析的附加选项。
|
|
1221
|
+
- 返回值:
|
|
1222
|
+
- `function|null`:对象指定字段的元素类型,如果无法推断字段元素类型,则为`null`。
|
|
1223
|
+
|
|
1224
|
+
此函数获取对象字段的元素类型,特别适用于集合(数组、集合、映射)。它检查注解的元素类型信息,选项中的附加类型信息,并尝试从默认字段值推断。
|
|
1225
|
+
|
|
1226
|
+
```javascript
|
|
1227
|
+
import { getFieldElementType, ElementType } from '@qubit-ltd/common-decorator';
|
|
1228
|
+
|
|
1229
|
+
class Item {
|
|
1230
|
+
constructor() {
|
|
1231
|
+
this.id = 0;
|
|
1232
|
+
this.name = '';
|
|
1233
|
+
}
|
|
1234
|
+
}
|
|
1235
|
+
|
|
1236
|
+
class Shop {
|
|
1237
|
+
constructor() {
|
|
1238
|
+
this.items = [];
|
|
1239
|
+
}
|
|
1240
|
+
}
|
|
1241
|
+
|
|
1242
|
+
// 使用装饰器指定元素类型
|
|
1243
|
+
class DecoratedShop {
|
|
1244
|
+
constructor() {
|
|
1245
|
+
this.items = [];
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
ElementType(Item)(DecoratedShop, 'items');
|
|
1249
|
+
|
|
1250
|
+
console.log(getFieldElementType(DecoratedShop, 'items') === Item); // true
|
|
1251
|
+
```
|
|
1252
|
+
|
|
1253
|
+
### <span id="getSourceField">getSourceField(targetField, options)</span>
|
|
1254
|
+
|
|
1255
|
+
- 参数:
|
|
1256
|
+
- `targetField: string`:目标对象的键。
|
|
1257
|
+
- `options: object`:命名风格转换的选项。
|
|
1258
|
+
- 返回值:
|
|
1259
|
+
- `string`:源对象的对应键。
|
|
1260
|
+
|
|
1261
|
+
此函数从目标对象的对应字段获取源对象的字段名称,支持不同命名规范(驼峰命名法、蛇形命名法等)之间的命名风格转换。
|
|
1262
|
+
|
|
1263
|
+
```javascript
|
|
1264
|
+
import { getSourceField } from '@qubit-ltd/common-decorator';
|
|
1265
|
+
|
|
1266
|
+
const options = {
|
|
1267
|
+
convertNaming: true,
|
|
1268
|
+
sourceNamingStyle: 'LOWER_UNDERSCORE',
|
|
1269
|
+
targetNamingStyle: 'LOWER_CAMEL',
|
|
1270
|
+
};
|
|
1271
|
+
|
|
1272
|
+
const sourceField = getSourceField('firstName', options);
|
|
1273
|
+
console.log(sourceField); // 'first_name'
|
|
1274
|
+
```
|
|
1275
|
+
|
|
942
1276
|
## <span id="recent-updates">最新更新</span>
|
|
943
1277
|
|
|
944
1278
|
### 测试覆盖增强(2023年12月)
|