@questwork/q-utilities 0.1.12 → 0.1.13
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/dist/index.min.cjs +938 -719
- package/dist/q-utilities.min.js +938 -719
- package/package.json +5 -12
- package/dist/index.min.js +0 -2407
package/dist/index.min.cjs
CHANGED
|
@@ -56,6 +56,8 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
56
56
|
Repo: () => (/* reexport */ Repo),
|
|
57
57
|
Service: () => (/* reexport */ Service),
|
|
58
58
|
TemplateCompiler: () => (/* reexport */ TemplateCompiler),
|
|
59
|
+
TenantAwareEntity: () => (/* reexport */ TenantAwareEntity),
|
|
60
|
+
TrackedEntity: () => (/* reexport */ TrackedEntity),
|
|
59
61
|
UniqueKeyGenerator: () => (/* reexport */ UniqueKeyGenerator),
|
|
60
62
|
concatStringByArray: () => (/* reexport */ concatStringByArray),
|
|
61
63
|
convertString: () => (/* reexport */ convertString),
|
|
@@ -63,6 +65,9 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
63
65
|
generalPost: () => (/* reexport */ generalPost),
|
|
64
66
|
getValidation: () => (/* reexport */ getValidation),
|
|
65
67
|
getValueByKeys: () => (/* reexport */ getValueByKeys_getValueByKeys),
|
|
68
|
+
init: () => (/* reexport */ init),
|
|
69
|
+
initFromArray: () => (/* reexport */ initFromArray),
|
|
70
|
+
initOnlyValidFromArray: () => (/* reexport */ initOnlyValidFromArray),
|
|
66
71
|
makeApiResponse: () => (/* reexport */ makeApiResponse),
|
|
67
72
|
makeService: () => (/* reexport */ makeService),
|
|
68
73
|
objectHelper: () => (/* reexport */ objectHelper),
|
|
@@ -289,7 +294,6 @@ function getValueByKeys_getValueByKeys(keys, data) {
|
|
|
289
294
|
});
|
|
290
295
|
|
|
291
296
|
|
|
292
|
-
|
|
293
297
|
;// ./lib/helpers/getValueByKeys/index.js
|
|
294
298
|
|
|
295
299
|
|
|
@@ -317,7 +321,25 @@ class TemplateCompilerException extends Error {
|
|
|
317
321
|
;// ./lib/models/templateCompiler/constants.js
|
|
318
322
|
const _EMPTY = '_EMPTY'
|
|
319
323
|
const _FN_NAMES = [
|
|
320
|
-
'
|
|
324
|
+
'concatIf',
|
|
325
|
+
'divide',
|
|
326
|
+
'eq',
|
|
327
|
+
'exec',
|
|
328
|
+
'filterAll',
|
|
329
|
+
'filterOne',
|
|
330
|
+
'formatDate',
|
|
331
|
+
'get',
|
|
332
|
+
'gt',
|
|
333
|
+
'gte',
|
|
334
|
+
'isEmpty',
|
|
335
|
+
'isNotEmpty',
|
|
336
|
+
'join',
|
|
337
|
+
'lt',
|
|
338
|
+
'lte',
|
|
339
|
+
'map',
|
|
340
|
+
'neq',
|
|
341
|
+
'toLowerCase',
|
|
342
|
+
'toUpperCase',
|
|
321
343
|
]
|
|
322
344
|
const _HIDE = '_HIDE'
|
|
323
345
|
const _NOT_EMPTY = '_NOT_EMPTY'
|
|
@@ -358,6 +380,20 @@ function _concatIf(data, args) {
|
|
|
358
380
|
|
|
359
381
|
|
|
360
382
|
|
|
383
|
+
;// ./lib/models/templateCompiler/helpers/_divide.js
|
|
384
|
+
function _divide(value, divisor) {
|
|
385
|
+
try {
|
|
386
|
+
if (Number.isNaN(value)) {
|
|
387
|
+
return value
|
|
388
|
+
}
|
|
389
|
+
return (value / divisor)
|
|
390
|
+
} catch (e) {
|
|
391
|
+
throw e
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
|
|
361
397
|
;// ./lib/models/templateCompiler/helpers/_eq.js
|
|
362
398
|
|
|
363
399
|
|
|
@@ -943,6 +979,7 @@ function _toUpperCase(data, args) {
|
|
|
943
979
|
|
|
944
980
|
|
|
945
981
|
|
|
982
|
+
|
|
946
983
|
|
|
947
984
|
|
|
948
985
|
;// ./lib/models/templateCompiler/templateCompiler.js
|
|
@@ -969,6 +1006,9 @@ class TemplateCompiler {
|
|
|
969
1006
|
static concatIf(data, args) {
|
|
970
1007
|
return _concatIf(data, args)
|
|
971
1008
|
}
|
|
1009
|
+
static divide(data, args) {
|
|
1010
|
+
return _divide(data, args)
|
|
1011
|
+
}
|
|
972
1012
|
static eq(data, args) {
|
|
973
1013
|
return _eq(data, args)
|
|
974
1014
|
}
|
|
@@ -980,7 +1020,6 @@ class TemplateCompiler {
|
|
|
980
1020
|
static formatDate(data, args) {
|
|
981
1021
|
return _formatDate(data, args)
|
|
982
1022
|
}
|
|
983
|
-
|
|
984
1023
|
static get(data, key, failover = null) {
|
|
985
1024
|
return _get(data, key, failover)
|
|
986
1025
|
}
|
|
@@ -1102,6 +1141,10 @@ function _parseSinglePart(input) {
|
|
|
1102
1141
|
// 去掉双引号,返回
|
|
1103
1142
|
return input.substring(1, input.length - 1)
|
|
1104
1143
|
}
|
|
1144
|
+
if (input.startsWith("'") && input.endsWith("'")) {
|
|
1145
|
+
// 去掉双引号,返回
|
|
1146
|
+
return input.substring(1, input.length - 1)
|
|
1147
|
+
}
|
|
1105
1148
|
|
|
1106
1149
|
const _input = _toBasicType(input)
|
|
1107
1150
|
|
|
@@ -1129,6 +1172,10 @@ function _toBasicType(input) {
|
|
|
1129
1172
|
// 去掉双引号,返回
|
|
1130
1173
|
return input.substring(1, input.length - 1)
|
|
1131
1174
|
}
|
|
1175
|
+
if (input.startsWith("'") && input.endsWith("'")) {
|
|
1176
|
+
// 去掉双引号,返回
|
|
1177
|
+
return input.substring(1, input.length - 1)
|
|
1178
|
+
}
|
|
1132
1179
|
if (input === 'true') {
|
|
1133
1180
|
return true
|
|
1134
1181
|
}
|
|
@@ -1151,8 +1198,20 @@ function _callFunction(data, functionName, parameters) {
|
|
|
1151
1198
|
try {
|
|
1152
1199
|
let failover
|
|
1153
1200
|
switch (functionName) {
|
|
1201
|
+
case 'concatIf':
|
|
1202
|
+
return _concatIf(data, parameters)
|
|
1203
|
+
case 'divide':
|
|
1204
|
+
return _divide(data, parameters)
|
|
1205
|
+
case 'eq':
|
|
1206
|
+
return _eq(data, parameters)
|
|
1154
1207
|
case 'exec':
|
|
1155
1208
|
return _exec(data, parameters)
|
|
1209
|
+
case 'filterAll':
|
|
1210
|
+
return _filterAll(data, parameters)
|
|
1211
|
+
case 'filterOne':
|
|
1212
|
+
return _filterOne(data, parameters)
|
|
1213
|
+
case 'formatDate':
|
|
1214
|
+
return _formatDate(data, parameters)
|
|
1156
1215
|
case 'get':
|
|
1157
1216
|
if (parameters.length > 2) {
|
|
1158
1217
|
throw new TemplateCompilerException(TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException)
|
|
@@ -1161,34 +1220,24 @@ function _callFunction(data, functionName, parameters) {
|
|
|
1161
1220
|
failover = parameters[parameters.length - 1]
|
|
1162
1221
|
}
|
|
1163
1222
|
return _get(data, parameters[0], failover)
|
|
1164
|
-
case 'join':
|
|
1165
|
-
return _join(data, parameters[0])
|
|
1166
|
-
case 'map':
|
|
1167
|
-
return _map(data, parameters)
|
|
1168
|
-
case 'concatIf':
|
|
1169
|
-
return _concatIf(data, parameters)
|
|
1170
|
-
case 'filterOne':
|
|
1171
|
-
return _filterOne(data, parameters)
|
|
1172
|
-
case 'filterAll':
|
|
1173
|
-
return _filterAll(data, parameters)
|
|
1174
|
-
case 'formatDate':
|
|
1175
|
-
return _formatDate(data, parameters)
|
|
1176
|
-
case 'eq':
|
|
1177
|
-
return _eq(data, parameters)
|
|
1178
|
-
case 'neq':
|
|
1179
|
-
return _neq(data, parameters)
|
|
1180
1223
|
case 'gt':
|
|
1181
1224
|
return _gt(data, parameters)
|
|
1182
1225
|
case 'gte':
|
|
1183
1226
|
return _gte(data, parameters)
|
|
1184
|
-
case 'lt':
|
|
1185
|
-
return _lt(data, parameters)
|
|
1186
|
-
case 'lte':
|
|
1187
|
-
return _lte(data, parameters)
|
|
1188
1227
|
case 'isEmpty':
|
|
1189
1228
|
return _isEmpty(data, parameters)
|
|
1190
1229
|
case 'isNotEmpty':
|
|
1191
1230
|
return _isNotEmpty(data, parameters)
|
|
1231
|
+
case 'join':
|
|
1232
|
+
return _join(data, parameters[0])
|
|
1233
|
+
case 'lt':
|
|
1234
|
+
return _lt(data, parameters)
|
|
1235
|
+
case 'lte':
|
|
1236
|
+
return _lte(data, parameters)
|
|
1237
|
+
case 'map':
|
|
1238
|
+
return _map(data, parameters)
|
|
1239
|
+
case 'neq':
|
|
1240
|
+
return _neq(data, parameters)
|
|
1192
1241
|
case 'toLowerCase':
|
|
1193
1242
|
return _toLowerCase(data)
|
|
1194
1243
|
case 'toUpperCase':
|
|
@@ -1440,282 +1489,468 @@ async function pReduce(iterable, reducer, initialValue) {
|
|
|
1440
1489
|
|
|
1441
1490
|
|
|
1442
1491
|
|
|
1443
|
-
;// ./lib/models/
|
|
1444
|
-
class
|
|
1445
|
-
constructor(options
|
|
1492
|
+
;// ./lib/models/repo/repo.js
|
|
1493
|
+
class Repo {
|
|
1494
|
+
constructor(options) {
|
|
1446
1495
|
options = options || {}
|
|
1447
|
-
this.
|
|
1448
|
-
this.
|
|
1449
|
-
this.
|
|
1450
|
-
this.
|
|
1451
|
-
this.
|
|
1452
|
-
|
|
1496
|
+
this.model = options.model
|
|
1497
|
+
this._sharedOptions = options._sharedOptions // { session: this.dbTransaction }
|
|
1498
|
+
this._queryOptions = options._queryOptions
|
|
1499
|
+
this._saveOptions = options._saveOptions
|
|
1500
|
+
this._Class = options._constructor && options._constructor._Class
|
|
1501
|
+
? options._constructor._Class
|
|
1502
|
+
: null
|
|
1453
1503
|
}
|
|
1454
|
-
|
|
1455
1504
|
static init(options = {}) {
|
|
1456
1505
|
if (options instanceof this) {
|
|
1457
1506
|
return options
|
|
1458
1507
|
}
|
|
1459
1508
|
const instance = new this(options)
|
|
1460
|
-
return instance
|
|
1509
|
+
return instance.isValid ? instance : null
|
|
1461
1510
|
}
|
|
1462
1511
|
static get _classname() {
|
|
1463
|
-
return '
|
|
1512
|
+
return 'Repo'
|
|
1464
1513
|
}
|
|
1465
1514
|
static get _superclass() {
|
|
1466
|
-
return '
|
|
1515
|
+
return 'Repo'
|
|
1467
1516
|
}
|
|
1468
1517
|
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
if (this._instanceBuilder && (typeof this._instanceBuilder === 'function')) {
|
|
1472
|
-
return this._data.map(this._instanceBuilder)
|
|
1473
|
-
}
|
|
1474
|
-
return this._data
|
|
1518
|
+
get _classname() {
|
|
1519
|
+
return 'Repo'
|
|
1475
1520
|
}
|
|
1476
|
-
}
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
1521
|
|
|
1480
|
-
|
|
1522
|
+
get _superclass() {
|
|
1523
|
+
return 'Repo'
|
|
1524
|
+
}
|
|
1481
1525
|
|
|
1526
|
+
get isValid() {
|
|
1527
|
+
return this.model
|
|
1528
|
+
&& (typeof this.model.deleteOne === 'function')
|
|
1529
|
+
&& (typeof this.model.findAll === 'function')
|
|
1530
|
+
&& (typeof this.model.saveOne === 'function')
|
|
1531
|
+
}
|
|
1482
1532
|
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
return repo.init(i)
|
|
1533
|
+
get queryOptions() {
|
|
1534
|
+
return {
|
|
1535
|
+
...this._sharedOptions,
|
|
1536
|
+
...this._queryOptions,
|
|
1488
1537
|
}
|
|
1489
|
-
})
|
|
1490
|
-
}
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
;// ./lib/models/apiResponse/index.js
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
;// ./lib/models/keyValueObject/keyValueObject.js
|
|
1501
|
-
class KeyValueObject {
|
|
1502
|
-
constructor(options = {}) {
|
|
1503
|
-
options = options || {}
|
|
1504
|
-
this.key = options.key || null
|
|
1505
|
-
this.value = (typeof options.value !== 'undefined') ? options.value : ''
|
|
1506
1538
|
}
|
|
1507
1539
|
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1540
|
+
get saveOptions() {
|
|
1541
|
+
return {
|
|
1542
|
+
...this._sharedOptions,
|
|
1543
|
+
...this._saveOptions,
|
|
1512
1544
|
}
|
|
1513
|
-
const instance = new this(options)
|
|
1514
|
-
return instance.isValid ? instance : null
|
|
1515
1545
|
}
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1546
|
+
|
|
1547
|
+
init(options) {
|
|
1548
|
+
if (this._Class && typeof this._Class.init === 'function') {
|
|
1549
|
+
return this._Class.init(options)
|
|
1519
1550
|
}
|
|
1520
|
-
return
|
|
1521
|
-
}
|
|
1522
|
-
static initOnlyValidFromArray(arr = []) {
|
|
1523
|
-
return this.initFromArray(arr).filter((i) => i)
|
|
1524
|
-
}
|
|
1525
|
-
static get _classname() {
|
|
1526
|
-
return 'KeyValueObject'
|
|
1527
|
-
}
|
|
1528
|
-
static get _superclass() {
|
|
1529
|
-
return 'KeyValueObject'
|
|
1551
|
+
return options
|
|
1530
1552
|
}
|
|
1531
1553
|
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1554
|
+
async deleteOne({ id }) {
|
|
1555
|
+
try {
|
|
1556
|
+
const result = await this.model.deleteOne({ _id: id })
|
|
1557
|
+
return {
|
|
1558
|
+
...result, // { message: 'ok', total }
|
|
1559
|
+
isNew: false,
|
|
1560
|
+
data: []
|
|
1561
|
+
}
|
|
1562
|
+
} catch (err) {
|
|
1563
|
+
throw err
|
|
1538
1564
|
}
|
|
1539
|
-
return arr
|
|
1540
1565
|
}
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1566
|
+
|
|
1567
|
+
// systemLog is optional
|
|
1568
|
+
findAll({ query, systemLog }) {
|
|
1569
|
+
const log = _makeLog({
|
|
1570
|
+
systemLog,
|
|
1571
|
+
label: 'REPO_READ',
|
|
1572
|
+
message: `fn ${this._classname}.prototype.findAll`,
|
|
1573
|
+
input: [{ query: { ...query }, systemLog: { ...systemLog } }]
|
|
1547
1574
|
})
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1575
|
+
return new Promise((resolve, reject) => {
|
|
1576
|
+
this.model.findAll(query, this.queryOptions, (err, data, total) => {
|
|
1577
|
+
if (err) {
|
|
1578
|
+
log({ level: 'warn', output: err.toString() })
|
|
1579
|
+
reject(err)
|
|
1580
|
+
} else {
|
|
1581
|
+
const result = {
|
|
1582
|
+
isNew: false,
|
|
1583
|
+
data,
|
|
1584
|
+
total: total || data.length
|
|
1585
|
+
}
|
|
1586
|
+
log({ level: 'info', output: { ...result } })
|
|
1587
|
+
resolve(result)
|
|
1588
|
+
}
|
|
1589
|
+
})
|
|
1555
1590
|
})
|
|
1556
1591
|
}
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1592
|
+
|
|
1593
|
+
findOne({ query, systemLog }) {
|
|
1594
|
+
const log = _makeLog({
|
|
1595
|
+
systemLog,
|
|
1596
|
+
label: 'REPO_READ',
|
|
1597
|
+
message: `fn ${this._classname}.prototype.findOne`,
|
|
1598
|
+
input: [{ query: { ...query }, systemLog: { ...systemLog } }]
|
|
1560
1599
|
})
|
|
1561
|
-
return
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1600
|
+
return new Promise((resolve, reject) => {
|
|
1601
|
+
this.model.findAll(query, this.queryOptions, (err, data) => {
|
|
1602
|
+
if (err) {
|
|
1603
|
+
reject(err)
|
|
1604
|
+
} else if (data.length === 1) {
|
|
1605
|
+
const result = {
|
|
1606
|
+
isNew: false,
|
|
1607
|
+
data,
|
|
1608
|
+
total: 1
|
|
1609
|
+
}
|
|
1610
|
+
log({ level: 'info', output: { ...result } })
|
|
1611
|
+
resolve(result)
|
|
1612
|
+
} else if (data.length === 0) {
|
|
1613
|
+
reject(new Error('record not found'))
|
|
1614
|
+
} else {
|
|
1615
|
+
reject(new Error('more than one is found'))
|
|
1616
|
+
}
|
|
1617
|
+
})
|
|
1618
|
+
})
|
|
1619
|
+
.catch((err) => {
|
|
1620
|
+
log({ level: 'warn', output: err.toString() })
|
|
1621
|
+
throw err
|
|
1622
|
+
})
|
|
1566
1623
|
}
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1624
|
+
|
|
1625
|
+
saveAll({ docs, systemLog }) {
|
|
1626
|
+
let isNew
|
|
1627
|
+
const log = _makeLog({
|
|
1628
|
+
systemLog,
|
|
1629
|
+
label: 'REPO_WRITE',
|
|
1630
|
+
message: `fn ${this._classname}.prototype.saveAll`,
|
|
1631
|
+
input: [{ docs: [...docs], systemLog: { ...systemLog } }]
|
|
1632
|
+
})
|
|
1633
|
+
const promise = typeof this.model.saveAll === 'function'
|
|
1634
|
+
? this.model.saveAll({ docs })
|
|
1635
|
+
: Promise.all(docs.map(async (doc) => {
|
|
1636
|
+
if (doc) {
|
|
1637
|
+
const result = await this.saveOne({ doc })
|
|
1638
|
+
isNew = result.isNew
|
|
1639
|
+
const _data = result._data || result.data
|
|
1640
|
+
return _data[0]
|
|
1641
|
+
}
|
|
1642
|
+
return null
|
|
1643
|
+
}))
|
|
1644
|
+
return promise.then((savedData) => {
|
|
1645
|
+
if (savedData.length !== 1) isNew = null
|
|
1646
|
+
const result = {
|
|
1647
|
+
data: savedData,
|
|
1648
|
+
isNew,
|
|
1649
|
+
total: savedData.length
|
|
1650
|
+
}
|
|
1651
|
+
log({ level: 'info', output: { ...result } })
|
|
1652
|
+
return result
|
|
1653
|
+
}).catch((err) => {
|
|
1654
|
+
log({ level: 'warn', output: err.toString() })
|
|
1655
|
+
throw err
|
|
1656
|
+
})
|
|
1575
1657
|
}
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1658
|
+
|
|
1659
|
+
saveOne({ doc, systemLog }) {
|
|
1660
|
+
const log = _makeLog({
|
|
1661
|
+
systemLog,
|
|
1662
|
+
label: 'REPO_WRITE',
|
|
1663
|
+
message: `fn ${this._classname}.prototype.saveOne`,
|
|
1664
|
+
input: [{ doc: { ...doc }, systemLog: { ...systemLog } }]
|
|
1583
1665
|
})
|
|
1584
|
-
|
|
1585
|
-
|
|
1666
|
+
return new Promise((resolve, reject) => {
|
|
1667
|
+
this.model.saveOne(doc, this.saveOptions, (err, result) => {
|
|
1668
|
+
if (err) {
|
|
1669
|
+
log({ level: 'warn', output: err.toString() })
|
|
1670
|
+
reject(err)
|
|
1671
|
+
} else {
|
|
1672
|
+
log({ level: 'info', output: { ...result } })
|
|
1673
|
+
resolve(result)
|
|
1674
|
+
}
|
|
1675
|
+
})
|
|
1676
|
+
})
|
|
1677
|
+
}
|
|
1678
|
+
}
|
|
1679
|
+
|
|
1680
|
+
function _makeLog({ systemLog, label, message: message1, input } = {}) {
|
|
1681
|
+
return ({ level, messgae: massage2, output } = {}) => {
|
|
1682
|
+
if (systemLog && systemLog.systemLogHelper) {
|
|
1683
|
+
systemLog.systemLogHelper.log({
|
|
1684
|
+
batchId: systemLog.batchId,
|
|
1685
|
+
label,
|
|
1686
|
+
level,
|
|
1687
|
+
message: massage2 || message1,
|
|
1688
|
+
data: {
|
|
1689
|
+
payload: {
|
|
1690
|
+
input,
|
|
1691
|
+
output
|
|
1692
|
+
}
|
|
1693
|
+
}
|
|
1694
|
+
})
|
|
1586
1695
|
}
|
|
1587
|
-
return this.getValueByKeyFromArray(arr, key)
|
|
1588
1696
|
}
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1697
|
+
}
|
|
1698
|
+
|
|
1699
|
+
|
|
1700
|
+
|
|
1701
|
+
;// ./lib/models/apiResponse/apiResponse.js
|
|
1702
|
+
class ApiResponse {
|
|
1703
|
+
constructor(options = {}) {
|
|
1704
|
+
options = options || {}
|
|
1705
|
+
this._data = options.data || options._data || []
|
|
1706
|
+
this.err = options.err
|
|
1707
|
+
this.isNew = options.isNew || false
|
|
1708
|
+
this.message = options.message
|
|
1709
|
+
this.total = options.total || 0
|
|
1710
|
+
this._instanceBuilder = options._instanceBuilder
|
|
1596
1711
|
}
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1712
|
+
|
|
1713
|
+
static init(options = {}) {
|
|
1714
|
+
if (options instanceof this) {
|
|
1715
|
+
return options
|
|
1600
1716
|
}
|
|
1601
|
-
|
|
1717
|
+
const instance = new this(options)
|
|
1718
|
+
return instance
|
|
1602
1719
|
}
|
|
1603
|
-
static
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1720
|
+
static get _classname() {
|
|
1721
|
+
return 'ApiResponse'
|
|
1722
|
+
}
|
|
1723
|
+
static get _superclass() {
|
|
1724
|
+
return 'ApiResponse'
|
|
1725
|
+
}
|
|
1726
|
+
|
|
1727
|
+
// getters
|
|
1728
|
+
get data() {
|
|
1729
|
+
if (this._instanceBuilder && (typeof this._instanceBuilder === 'function')) {
|
|
1730
|
+
return this._data.map(this._instanceBuilder)
|
|
1609
1731
|
}
|
|
1610
|
-
return
|
|
1732
|
+
return this._data
|
|
1611
1733
|
}
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1734
|
+
}
|
|
1735
|
+
|
|
1736
|
+
|
|
1737
|
+
|
|
1738
|
+
;// ./lib/models/apiResponse/makeApiResponse.js
|
|
1739
|
+
|
|
1740
|
+
|
|
1741
|
+
function makeApiResponse({ repo, result }) {
|
|
1742
|
+
return ApiResponse.init({
|
|
1743
|
+
...result,
|
|
1744
|
+
_instanceBuilder: (i) => {
|
|
1745
|
+
return repo.init(i)
|
|
1618
1746
|
}
|
|
1619
|
-
|
|
1747
|
+
})
|
|
1748
|
+
}
|
|
1749
|
+
|
|
1750
|
+
|
|
1751
|
+
|
|
1752
|
+
;// ./lib/models/service/service.js
|
|
1753
|
+
|
|
1754
|
+
|
|
1755
|
+
|
|
1756
|
+
class Service {
|
|
1757
|
+
constructor({ repo }) {
|
|
1758
|
+
this.repo = repo
|
|
1620
1759
|
}
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1760
|
+
|
|
1761
|
+
static get _classname() {
|
|
1762
|
+
return 'Service'
|
|
1763
|
+
}
|
|
1764
|
+
static get _superclass() {
|
|
1765
|
+
return 'Service'
|
|
1766
|
+
}
|
|
1767
|
+
|
|
1768
|
+
deleteOne({ id }) {
|
|
1769
|
+
return this.repo.deleteOne({ id })
|
|
1770
|
+
.catch(() => {
|
|
1771
|
+
throw new Error(`Not found for query: ${id}`)
|
|
1625
1772
|
})
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1773
|
+
}
|
|
1774
|
+
|
|
1775
|
+
async findAll({ query = {}, systemLog } = {}) {
|
|
1776
|
+
const result = await this.repo.findAll({ query, systemLog })
|
|
1777
|
+
return makeApiResponse({
|
|
1778
|
+
repo: this.repo,
|
|
1779
|
+
result
|
|
1631
1780
|
})
|
|
1632
|
-
return toArr
|
|
1633
1781
|
}
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
}
|
|
1782
|
+
|
|
1783
|
+
async findOne({ query = {}, systemLog } = {}) {
|
|
1784
|
+
const result = await this.repo.findOne({ query, systemLog })
|
|
1785
|
+
return makeApiResponse({
|
|
1786
|
+
repo: this.repo,
|
|
1787
|
+
result
|
|
1788
|
+
})
|
|
1641
1789
|
}
|
|
1642
|
-
|
|
1643
|
-
|
|
1790
|
+
|
|
1791
|
+
init(options) {
|
|
1792
|
+
return this.repo.init(options)
|
|
1644
1793
|
}
|
|
1645
|
-
|
|
1794
|
+
initFromArray(arr = []) {
|
|
1646
1795
|
if (Array.isArray(arr)) {
|
|
1647
|
-
return arr.
|
|
1648
|
-
acc[item.key] = item.value
|
|
1649
|
-
return acc
|
|
1650
|
-
}, {})
|
|
1796
|
+
return arr.map((a) => this.init(a))
|
|
1651
1797
|
}
|
|
1652
|
-
return
|
|
1798
|
+
return []
|
|
1653
1799
|
}
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
return arr.reduce((acc, item) => {
|
|
1657
|
-
acc.push(`${item.key}: ${item.value}`)
|
|
1658
|
-
return acc
|
|
1659
|
-
}, []).join(delimiter)
|
|
1660
|
-
}
|
|
1661
|
-
return ''
|
|
1800
|
+
initOnlyValidFromArray(arr = []) {
|
|
1801
|
+
return this.initFromArray(arr).filter((i) => i)
|
|
1662
1802
|
}
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1803
|
+
|
|
1804
|
+
async saveAll({ docs = [], config = {}, systemLog } = {}) {
|
|
1805
|
+
const copies = docs.map((doc) => {
|
|
1806
|
+
return config.skipInit ? doc : this.init(doc)
|
|
1807
|
+
})
|
|
1808
|
+
const result = await this.repo.saveAll({ docs: copies, systemLog })
|
|
1809
|
+
return makeApiResponse({
|
|
1810
|
+
repo: this.repo,
|
|
1811
|
+
result
|
|
1672
1812
|
})
|
|
1673
1813
|
}
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
}
|
|
1677
|
-
|
|
1678
|
-
if (
|
|
1679
|
-
const
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
...obj2
|
|
1814
|
+
|
|
1815
|
+
// set skipInit to true if we want to use POST for query
|
|
1816
|
+
async saveOne({ doc = {}, config = {}, systemLog } = {}) {
|
|
1817
|
+
const copy = config.skipInit ? doc : this.init(doc)
|
|
1818
|
+
if (copy) {
|
|
1819
|
+
const result = await this.repo.saveOne({ doc: copy, systemLog })
|
|
1820
|
+
return makeApiResponse({
|
|
1821
|
+
repo: this.repo,
|
|
1822
|
+
result
|
|
1684
1823
|
})
|
|
1685
1824
|
}
|
|
1686
|
-
return
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
return arr.reduce((acc, item) => {
|
|
1691
|
-
acc.push(item.value)
|
|
1692
|
-
return acc
|
|
1693
|
-
}, [])
|
|
1825
|
+
return {
|
|
1826
|
+
isNew: null,
|
|
1827
|
+
data: [],
|
|
1828
|
+
err: new Error('doc is not a valid instance')
|
|
1694
1829
|
}
|
|
1695
|
-
return []
|
|
1696
1830
|
}
|
|
1831
|
+
}
|
|
1697
1832
|
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1833
|
+
function makeService({ repo }) {
|
|
1834
|
+
if (repo === undefined) {
|
|
1835
|
+
throw new Error('repo is required.')
|
|
1701
1836
|
}
|
|
1837
|
+
if (repo._superclass !== Repo._superclass) {
|
|
1838
|
+
throw new Error('repo is not an instance of Repo.')
|
|
1839
|
+
}
|
|
1840
|
+
return new Service({ repo })
|
|
1841
|
+
}
|
|
1702
1842
|
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1843
|
+
|
|
1844
|
+
|
|
1845
|
+
;// ./lib/helpers/generalPost/generalPost.js
|
|
1846
|
+
|
|
1847
|
+
|
|
1848
|
+
|
|
1849
|
+
|
|
1850
|
+
|
|
1851
|
+
async function generalPost({ body = {}, GeneralModel, UniqueKeyGenerator, resourceInfo }) {
|
|
1852
|
+
const { resources, data, globalShared = {}, shared = {}, relationship = {} } = body
|
|
1853
|
+
const _resourceInfo = resourceInfo || body.resourceInfo
|
|
1854
|
+
_attachShared(data, globalShared, shared)
|
|
1855
|
+
const obj = await pReduce(resources, async (acc, resource) => {
|
|
1856
|
+
const service = _makeService(resource, _resourceInfo, UniqueKeyGenerator, GeneralModel)
|
|
1857
|
+
_createRelationship(data, relationship[resource], acc)
|
|
1858
|
+
const _data = data[resource]
|
|
1859
|
+
const result = await service.saveAll({ docs: [].concat(_data) })
|
|
1860
|
+
acc[resource] = Array.isArray(_data) ? result._data : result._data[0]
|
|
1861
|
+
return acc
|
|
1862
|
+
}, {})
|
|
1863
|
+
return obj
|
|
1864
|
+
}
|
|
1865
|
+
|
|
1866
|
+
function _attachShared(data, globalShared = {}, shared = {}) {
|
|
1867
|
+
Object.keys(shared).forEach((key) => {
|
|
1868
|
+
const _data = data[key]
|
|
1869
|
+
data[key] = objectHelper.merge({}, _data, globalShared, shared[key] || {})
|
|
1870
|
+
})
|
|
1871
|
+
}
|
|
1872
|
+
|
|
1873
|
+
function _createRelationship(data, relationship = {}, object) {
|
|
1874
|
+
Object.keys(relationship).forEach((key) => {
|
|
1875
|
+
const path = relationship[key]
|
|
1876
|
+
const val = objectHelper.get(object, path)
|
|
1877
|
+
objectHelper.set(data, key, val)
|
|
1878
|
+
})
|
|
1879
|
+
}
|
|
1880
|
+
|
|
1881
|
+
function _makeService(resource, resourceInfo, UniqueKeyGenerator, GeneralModel) {
|
|
1882
|
+
const { collectionName, fields } = resourceInfo[resource]
|
|
1883
|
+
const uniqueKeyGenerator = UniqueKeyGenerator.makeGenerator(fields)
|
|
1884
|
+
const model = new GeneralModel({ collectionName, uniqueKeyGenerator })
|
|
1885
|
+
return makeService({
|
|
1886
|
+
repo: new Repo({ model })
|
|
1887
|
+
})
|
|
1888
|
+
}
|
|
1889
|
+
|
|
1890
|
+
|
|
1891
|
+
|
|
1892
|
+
;// ./lib/helpers/generalPost/index.js
|
|
1893
|
+
|
|
1894
|
+
|
|
1895
|
+
|
|
1896
|
+
|
|
1897
|
+
;// ./lib/helpers/init/init.js
|
|
1898
|
+
function init(_class, options) {
|
|
1899
|
+
if (options instanceof _class) {
|
|
1900
|
+
return options
|
|
1901
|
+
}
|
|
1902
|
+
try {
|
|
1903
|
+
const instance = new _class(options)
|
|
1904
|
+
return instance.isValid ? instance : null
|
|
1905
|
+
} catch (e) {
|
|
1906
|
+
console.log(`init failed for class: ${_class._classname || 'no _classname'}`, e)
|
|
1907
|
+
return null
|
|
1709
1908
|
}
|
|
1710
1909
|
}
|
|
1711
1910
|
|
|
1712
|
-
|
|
1713
|
-
|
|
1911
|
+
;// ./lib/helpers/init/index.js
|
|
1912
|
+
|
|
1913
|
+
|
|
1914
|
+
;// ./lib/helpers/initFromArray/initFromArray.js
|
|
1915
|
+
|
|
1916
|
+
|
|
1917
|
+
function initFromArray(_class, arr) {
|
|
1918
|
+
if (Array.isArray(arr)) {
|
|
1919
|
+
return arr.map((a) => init(_class, a))
|
|
1920
|
+
}
|
|
1921
|
+
return []
|
|
1714
1922
|
}
|
|
1715
1923
|
|
|
1924
|
+
;// ./lib/helpers/initFromArray/index.js
|
|
1716
1925
|
|
|
1717
1926
|
|
|
1718
|
-
;// ./lib/
|
|
1927
|
+
;// ./lib/helpers/initOnlyValidFromArray/initOnlyValidFromArray.js
|
|
1928
|
+
|
|
1929
|
+
|
|
1930
|
+
function initOnlyValidFromArray(_class, arr) {
|
|
1931
|
+
return initFromArray(_class, arr).filter((i) => i)
|
|
1932
|
+
}
|
|
1933
|
+
|
|
1934
|
+
;// ./lib/helpers/initOnlyValidFromArray/index.js
|
|
1935
|
+
|
|
1936
|
+
|
|
1937
|
+
;// ./lib/helpers/padZeros/padZeros.js
|
|
1938
|
+
function padZeros(num, minLength = 6) {
|
|
1939
|
+
num = num.toString()
|
|
1940
|
+
if (num.length < minLength) {
|
|
1941
|
+
return padZeros('0' + num, minLength)
|
|
1942
|
+
}
|
|
1943
|
+
return num
|
|
1944
|
+
}
|
|
1945
|
+
|
|
1946
|
+
|
|
1947
|
+
|
|
1948
|
+
;// ./lib/helpers/padZeros/index.js
|
|
1949
|
+
|
|
1950
|
+
|
|
1951
|
+
|
|
1952
|
+
|
|
1953
|
+
;// ./lib/helpers/pReduce/index.js
|
|
1719
1954
|
|
|
1720
1955
|
|
|
1721
1956
|
|
|
@@ -1734,129 +1969,161 @@ function stringFormatter(str, delimiter = '_') {
|
|
|
1734
1969
|
|
|
1735
1970
|
|
|
1736
1971
|
|
|
1737
|
-
;// ./lib/
|
|
1972
|
+
;// ./lib/helpers/stringFormatter/index.js
|
|
1738
1973
|
|
|
1739
1974
|
|
|
1740
1975
|
|
|
1741
|
-
const DELIMITER = '_'
|
|
1742
1976
|
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
return
|
|
1977
|
+
;// ./lib/helpers/stringHelper/stringHelper.js
|
|
1978
|
+
function baseXEncode(num, base = 34) {
|
|
1979
|
+
const charset = getBaseCharset(base)
|
|
1980
|
+
return encode(num, charset)
|
|
1981
|
+
}
|
|
1982
|
+
|
|
1983
|
+
function encode(int, charset) {
|
|
1984
|
+
const { byCode } = charset
|
|
1985
|
+
if (int === 0) {
|
|
1986
|
+
return byCode[0]
|
|
1753
1987
|
}
|
|
1754
|
-
|
|
1755
|
-
|
|
1988
|
+
|
|
1989
|
+
let res = ''
|
|
1990
|
+
const max = charset.length
|
|
1991
|
+
while (int > 0) {
|
|
1992
|
+
res = byCode[int % max] + res
|
|
1993
|
+
int = Math.floor(int / max)
|
|
1756
1994
|
}
|
|
1995
|
+
return res
|
|
1996
|
+
}
|
|
1757
1997
|
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1998
|
+
function getBaseCharset(base) {
|
|
1999
|
+
let charset = '9876543210ABCDEFGHJKLMNPQRSTUVWXYZ'
|
|
2000
|
+
if (base === 58) {
|
|
2001
|
+
charset = '9876543210ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz'
|
|
2002
|
+
}
|
|
2003
|
+
return indexCharset(charset)
|
|
2004
|
+
}
|
|
2005
|
+
|
|
2006
|
+
function indexCharset(str) {
|
|
2007
|
+
const byCode = {}
|
|
2008
|
+
const byChar = {}
|
|
2009
|
+
const { length } = str
|
|
2010
|
+
let char
|
|
2011
|
+
for (let i = 0; i < length; i++) {
|
|
2012
|
+
char = str[i]
|
|
2013
|
+
byCode[i] = char
|
|
2014
|
+
byChar[char] = i;
|
|
2015
|
+
}
|
|
2016
|
+
return { byCode, byChar, length }
|
|
2017
|
+
}
|
|
2018
|
+
|
|
2019
|
+
function isSame(str1, str2) {
|
|
2020
|
+
if (typeof str1 !== 'string' || typeof str2 !== 'string') {
|
|
2021
|
+
return false
|
|
2022
|
+
}
|
|
2023
|
+
return str1.trim().toUpperCase() === str2.trim().toUpperCase()
|
|
2024
|
+
}
|
|
2025
|
+
|
|
2026
|
+
function randomString({ len = 16, pattern = 'a1' } = {}) {
|
|
2027
|
+
const A = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
|
2028
|
+
const a = 'abcdefghijklmnopqrstuvwxyz'
|
|
2029
|
+
const num = '1234567890'
|
|
2030
|
+
const mark = '~!@#$%^&*_+-='
|
|
2031
|
+
let str = ''
|
|
2032
|
+
if (pattern.includes('A')) {
|
|
2033
|
+
str += A
|
|
2034
|
+
}
|
|
2035
|
+
if (pattern.includes('a')) {
|
|
2036
|
+
str += a
|
|
2037
|
+
}
|
|
2038
|
+
if (pattern.includes('1')) {
|
|
2039
|
+
str += num
|
|
2040
|
+
}
|
|
2041
|
+
if (pattern.includes('#')) {
|
|
2042
|
+
str += mark
|
|
2043
|
+
}
|
|
2044
|
+
const chars = [...str]
|
|
2045
|
+
return [...Array(len)].map(i => {
|
|
2046
|
+
return chars[(Math.random() * chars.length) | 0]
|
|
2047
|
+
}).join``
|
|
2048
|
+
}
|
|
2049
|
+
|
|
2050
|
+
function reverse(str) {
|
|
2051
|
+
const _str = (typeof str !== 'string') ? str.toString() : str
|
|
2052
|
+
const splitString = _str.split('')
|
|
2053
|
+
const reverseArray = splitString.reverse()
|
|
2054
|
+
return reverseArray.join('')
|
|
2055
|
+
}
|
|
2056
|
+
|
|
2057
|
+
function setCode(base = 34) {
|
|
2058
|
+
const now = (new Date()).valueOf()
|
|
2059
|
+
const random = randomString({
|
|
2060
|
+
len: 8,
|
|
2061
|
+
pattern: '1'
|
|
2062
|
+
})
|
|
2063
|
+
const str = reverse(`${now}${random}`)
|
|
2064
|
+
// const str = `${now}${random}`
|
|
2065
|
+
return baseXEncode(str, base)
|
|
2066
|
+
}
|
|
2067
|
+
|
|
2068
|
+
function toCamelCase(str) {
|
|
2069
|
+
if (!str) return ''
|
|
2070
|
+
return str
|
|
2071
|
+
.trim()
|
|
2072
|
+
.split(/\s+/)
|
|
2073
|
+
.map((word, index) => {
|
|
2074
|
+
if (!word) return ''
|
|
2075
|
+
if (index === 0) {
|
|
2076
|
+
return word.toLowerCase()
|
|
1767
2077
|
}
|
|
2078
|
+
return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()
|
|
1768
2079
|
})
|
|
1769
|
-
|
|
1770
|
-
}
|
|
1771
|
-
static sameKey(item, key) {
|
|
1772
|
-
return metadata_isSame(item.key, key)
|
|
1773
|
-
}
|
|
2080
|
+
.join('')
|
|
1774
2081
|
}
|
|
1775
2082
|
|
|
1776
|
-
|
|
1777
|
-
|
|
2083
|
+
const stringHelper = {
|
|
2084
|
+
isSame,
|
|
2085
|
+
setCode,
|
|
2086
|
+
toCamelCase,
|
|
1778
2087
|
}
|
|
1779
2088
|
|
|
1780
2089
|
|
|
1781
2090
|
|
|
1782
|
-
;// ./lib/
|
|
2091
|
+
;// ./lib/helpers/stringHelper/index.js
|
|
1783
2092
|
|
|
1784
2093
|
|
|
1785
2094
|
|
|
1786
2095
|
|
|
1787
|
-
;// ./lib/
|
|
2096
|
+
;// ./lib/helpers/index.js
|
|
1788
2097
|
|
|
1789
2098
|
|
|
1790
|
-
const updateAllowedProps = [
|
|
1791
|
-
'attributes',
|
|
1792
|
-
'ref'
|
|
1793
|
-
]
|
|
1794
2099
|
|
|
1795
|
-
class QMeta {
|
|
1796
|
-
constructor(options = {}) {
|
|
1797
|
-
options = options || {}
|
|
1798
|
-
this.attributes = KeyValueObject.initOnlyValidFromArray(options.attributes)
|
|
1799
|
-
this.ref = options.ref || {}
|
|
1800
|
-
}
|
|
1801
2100
|
|
|
1802
|
-
static get _classname() {
|
|
1803
|
-
return 'QMeta'
|
|
1804
|
-
}
|
|
1805
|
-
static get _superclass() {
|
|
1806
|
-
return 'QMeta'
|
|
1807
|
-
}
|
|
1808
2101
|
|
|
1809
|
-
// Class methods
|
|
1810
|
-
static init(options = {}) {
|
|
1811
|
-
if (options instanceof QMeta) {
|
|
1812
|
-
return options
|
|
1813
|
-
}
|
|
1814
|
-
return new QMeta(options)
|
|
1815
|
-
}
|
|
1816
2102
|
|
|
1817
|
-
// instance methods
|
|
1818
|
-
addAttribute(obj) {
|
|
1819
|
-
const kvObject = KeyValueObject.init(obj)
|
|
1820
|
-
if (!kvObject) {
|
|
1821
|
-
throw new Error('invalid meta attribute')
|
|
1822
|
-
}
|
|
1823
|
-
this.attributes.push(kvObject)
|
|
1824
|
-
return this
|
|
1825
|
-
}
|
|
1826
2103
|
|
|
1827
|
-
update(obj) {
|
|
1828
|
-
Object.keys(obj).forEach((key) => {
|
|
1829
|
-
if (updateAllowedProps.includes(key)) {
|
|
1830
|
-
if (key === 'attributes') {
|
|
1831
|
-
this[key] = KeyValueObject.initOnlyValidFromArray(obj[key])
|
|
1832
|
-
} else {
|
|
1833
|
-
this[key] = obj[key]
|
|
1834
|
-
}
|
|
1835
|
-
}
|
|
1836
|
-
})
|
|
1837
|
-
return this
|
|
1838
|
-
}
|
|
1839
|
-
}
|
|
1840
2104
|
|
|
1841
2105
|
|
|
1842
2106
|
|
|
1843
|
-
;// ./lib/models/qMeta/index.js
|
|
1844
2107
|
|
|
1845
2108
|
|
|
1846
2109
|
|
|
1847
2110
|
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
2111
|
+
|
|
2112
|
+
;// ./lib/models/apiResponse/index.js
|
|
2113
|
+
|
|
2114
|
+
|
|
2115
|
+
|
|
2116
|
+
|
|
2117
|
+
|
|
2118
|
+
;// ./lib/models/keyValueObject/keyValueObject.js
|
|
2119
|
+
class KeyValueObject {
|
|
2120
|
+
constructor(options = {}) {
|
|
1851
2121
|
options = options || {}
|
|
1852
|
-
this.
|
|
1853
|
-
this.
|
|
1854
|
-
this._queryOptions = options._queryOptions
|
|
1855
|
-
this._saveOptions = options._saveOptions
|
|
1856
|
-
this._Class = options._constructor && options._constructor._Class
|
|
1857
|
-
? options._constructor._Class
|
|
1858
|
-
: null
|
|
2122
|
+
this.key = options.key || null
|
|
2123
|
+
this.value = (typeof options.value !== 'undefined') ? options.value : ''
|
|
1859
2124
|
}
|
|
2125
|
+
|
|
2126
|
+
// Class methods
|
|
1860
2127
|
static init(options = {}) {
|
|
1861
2128
|
if (options instanceof this) {
|
|
1862
2129
|
return options
|
|
@@ -1864,532 +2131,484 @@ class Repo {
|
|
|
1864
2131
|
const instance = new this(options)
|
|
1865
2132
|
return instance.isValid ? instance : null
|
|
1866
2133
|
}
|
|
2134
|
+
static initFromArray(arr = []) {
|
|
2135
|
+
if (Array.isArray(arr)) {
|
|
2136
|
+
return arr.map((a) => this.init(a))
|
|
2137
|
+
}
|
|
2138
|
+
return []
|
|
2139
|
+
}
|
|
2140
|
+
static initOnlyValidFromArray(arr = []) {
|
|
2141
|
+
return this.initFromArray(arr).filter((i) => i)
|
|
2142
|
+
}
|
|
1867
2143
|
static get _classname() {
|
|
1868
|
-
return '
|
|
2144
|
+
return 'KeyValueObject'
|
|
1869
2145
|
}
|
|
1870
2146
|
static get _superclass() {
|
|
1871
|
-
return '
|
|
2147
|
+
return 'KeyValueObject'
|
|
1872
2148
|
}
|
|
1873
2149
|
|
|
1874
|
-
|
|
1875
|
-
|
|
2150
|
+
static addItem(arr, key, value) {
|
|
2151
|
+
arr.push(this.init({ key, value }))
|
|
1876
2152
|
}
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
2153
|
+
static addRecord(arr = [], key, value) {
|
|
2154
|
+
if (!this.hasKeyValue(arr, key, value)) {
|
|
2155
|
+
arr.push(this.init({ key, value }))
|
|
2156
|
+
}
|
|
2157
|
+
return arr
|
|
1880
2158
|
}
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
2159
|
+
static appendRecord(arr = [], key, value) {
|
|
2160
|
+
return arr.map((item) => {
|
|
2161
|
+
if (this.sameKey(item, key)) {
|
|
2162
|
+
item.value = [...item.value, ...value]
|
|
2163
|
+
}
|
|
2164
|
+
return item
|
|
2165
|
+
})
|
|
1887
2166
|
}
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
2167
|
+
static appendValueArray(arr = [], key, value) {
|
|
2168
|
+
return arr.map((item) => {
|
|
2169
|
+
if (this.sameKey(item, key)) {
|
|
2170
|
+
item.value = [...item.value, ...value]
|
|
2171
|
+
}
|
|
2172
|
+
return item
|
|
2173
|
+
})
|
|
1894
2174
|
}
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
}
|
|
2175
|
+
static foundByKey(arr = [], key) {
|
|
2176
|
+
const found = arr.find((m) => {
|
|
2177
|
+
return this.sameKey(m, key)
|
|
2178
|
+
})
|
|
2179
|
+
return found || null
|
|
1901
2180
|
}
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
2181
|
+
static foundValueByKey(arr = [], key) {
|
|
2182
|
+
const found = this.foundByKey(arr, key)
|
|
2183
|
+
return found ? found.value : null
|
|
2184
|
+
}
|
|
2185
|
+
static fromObject(options = {}) {
|
|
2186
|
+
return Object.keys(options).reduce((acc, key) => {
|
|
2187
|
+
acc.push(this.init({ key, value: options[key] }))
|
|
2188
|
+
return acc
|
|
2189
|
+
}, [])
|
|
2190
|
+
}
|
|
2191
|
+
static getValueByKey(arr = [], key) {
|
|
2192
|
+
return this.foundValueByKey(arr, key)
|
|
2193
|
+
}
|
|
2194
|
+
static getValueByKeyFromArray(arr = [], key) {
|
|
2195
|
+
if (arr.length === 0) {
|
|
2196
|
+
return null
|
|
1906
2197
|
}
|
|
1907
|
-
|
|
2198
|
+
const firstArr = arr.shift()
|
|
2199
|
+
const found = firstArr.find((i) => {
|
|
2200
|
+
return this.sameKey(i, key)
|
|
2201
|
+
})
|
|
2202
|
+
if (found && found.value) {
|
|
2203
|
+
return found.value
|
|
2204
|
+
}
|
|
2205
|
+
return this.getValueByKeyFromArray(arr, key)
|
|
1908
2206
|
}
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
return {
|
|
1914
|
-
...result, // { message: 'ok', total }
|
|
1915
|
-
isNew: false,
|
|
1916
|
-
data: []
|
|
2207
|
+
static getValuesByKey(arr = [], key) {
|
|
2208
|
+
return arr.reduce((acc, item) => {
|
|
2209
|
+
if (this.sameKey(item, key)) {
|
|
2210
|
+
acc.push(item.value)
|
|
1917
2211
|
}
|
|
1918
|
-
|
|
1919
|
-
|
|
2212
|
+
return acc
|
|
2213
|
+
}, [])
|
|
2214
|
+
}
|
|
2215
|
+
static hasKeyValue(arr = [], key, value) {
|
|
2216
|
+
if (typeof value === 'undefined') {
|
|
2217
|
+
return arr.filter((item) => this.sameKey(item, key)).length > 0
|
|
1920
2218
|
}
|
|
2219
|
+
return arr.filter((item) => (this.sameKey(item, key) && _isSame(item.value, value))).length > 0
|
|
1921
2220
|
}
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
})
|
|
1931
|
-
return new Promise((resolve, reject) => {
|
|
1932
|
-
this.model.findAll(query, this.queryOptions, (err, data, total) => {
|
|
1933
|
-
if (err) {
|
|
1934
|
-
log({ level: 'warn', output: err.toString() })
|
|
1935
|
-
reject(err)
|
|
1936
|
-
} else {
|
|
1937
|
-
const result = {
|
|
1938
|
-
isNew: false,
|
|
1939
|
-
data,
|
|
1940
|
-
total: total || data.length
|
|
1941
|
-
}
|
|
1942
|
-
log({ level: 'info', output: { ...result } })
|
|
1943
|
-
resolve(result)
|
|
1944
|
-
}
|
|
1945
|
-
})
|
|
1946
|
-
})
|
|
2221
|
+
static insertOrUpdateRecord(arr = [], key, value) {
|
|
2222
|
+
let copy = [...arr]
|
|
2223
|
+
if (!this.hasKeyValue(arr, key)) {
|
|
2224
|
+
copy.push(this.init({ key, value }))
|
|
2225
|
+
} else {
|
|
2226
|
+
copy = this.updateRecord(arr, key, value)
|
|
2227
|
+
}
|
|
2228
|
+
return copy
|
|
1947
2229
|
}
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
const result = {
|
|
1962
|
-
isNew: false,
|
|
1963
|
-
data,
|
|
1964
|
-
total: 1
|
|
1965
|
-
}
|
|
1966
|
-
log({ level: 'info', output: { ...result } })
|
|
1967
|
-
resolve(result)
|
|
1968
|
-
} else if (data.length === 0) {
|
|
1969
|
-
reject(new Error('record not found'))
|
|
1970
|
-
} else {
|
|
1971
|
-
reject(new Error('more than one is found'))
|
|
1972
|
-
}
|
|
2230
|
+
static keys(arr = []) {
|
|
2231
|
+
if (Array.isArray(arr)) {
|
|
2232
|
+
return arr.reduce((acc, item) => {
|
|
2233
|
+
acc.push(item.key)
|
|
2234
|
+
return acc
|
|
2235
|
+
}, [])
|
|
2236
|
+
}
|
|
2237
|
+
return []
|
|
2238
|
+
}
|
|
2239
|
+
static merge(toArr, fromArr) {
|
|
2240
|
+
(fromArr || []).map((from) => {
|
|
2241
|
+
const found = toArr.find((to) => {
|
|
2242
|
+
return to.key === from.key
|
|
1973
2243
|
})
|
|
2244
|
+
if (found) {
|
|
2245
|
+
found.value = (found.value || []).concat(from.value)
|
|
2246
|
+
} else {
|
|
2247
|
+
toArr.push(from)
|
|
2248
|
+
}
|
|
1974
2249
|
})
|
|
1975
|
-
|
|
1976
|
-
log({ level: 'warn', output: err.toString() })
|
|
1977
|
-
throw err
|
|
1978
|
-
})
|
|
2250
|
+
return toArr
|
|
1979
2251
|
}
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
systemLog,
|
|
1985
|
-
label: 'REPO_WRITE',
|
|
1986
|
-
message: `fn ${this._classname}.prototype.saveAll`,
|
|
1987
|
-
input: [{ docs: [...docs], systemLog: { ...systemLog } }]
|
|
1988
|
-
})
|
|
1989
|
-
const promise = typeof this.model.saveAll === 'function'
|
|
1990
|
-
? this.model.saveAll({ docs })
|
|
1991
|
-
: Promise.all(docs.map(async (doc) => {
|
|
1992
|
-
if (doc) {
|
|
1993
|
-
const result = await this.saveOne({ doc })
|
|
1994
|
-
isNew = result.isNew
|
|
1995
|
-
const _data = result._data || result.data
|
|
1996
|
-
return _data[0]
|
|
1997
|
-
}
|
|
1998
|
-
return null
|
|
1999
|
-
}))
|
|
2000
|
-
return promise.then((savedData) => {
|
|
2001
|
-
if (savedData.length !== 1) isNew = null
|
|
2002
|
-
const result = {
|
|
2003
|
-
data: savedData,
|
|
2004
|
-
isNew,
|
|
2005
|
-
total: savedData.length
|
|
2252
|
+
static removeByKey(arr, key) {
|
|
2253
|
+
return arr.reduce((acc, item) => {
|
|
2254
|
+
if (!this.sameKey(item, key)) {
|
|
2255
|
+
acc.push(item)
|
|
2006
2256
|
}
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
}).catch((err) => {
|
|
2010
|
-
log({ level: 'warn', output: err.toString() })
|
|
2011
|
-
throw err
|
|
2012
|
-
})
|
|
2257
|
+
return acc
|
|
2258
|
+
}, [])
|
|
2013
2259
|
}
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2260
|
+
static sameKey(item, key) {
|
|
2261
|
+
return _isSame(item.key, key)
|
|
2262
|
+
}
|
|
2263
|
+
static toObject(arr = []) {
|
|
2264
|
+
if (Array.isArray(arr)) {
|
|
2265
|
+
return arr.reduce((acc, item) => {
|
|
2266
|
+
acc[item.key] = item.value
|
|
2267
|
+
return acc
|
|
2268
|
+
}, {})
|
|
2269
|
+
}
|
|
2270
|
+
return {}
|
|
2271
|
+
}
|
|
2272
|
+
static toString(arr = [], delimiter = '; ') {
|
|
2273
|
+
if (Array.isArray(arr)) {
|
|
2274
|
+
return arr.reduce((acc, item) => {
|
|
2275
|
+
acc.push(`${item.key}: ${item.value}`)
|
|
2276
|
+
return acc
|
|
2277
|
+
}, []).join(delimiter)
|
|
2278
|
+
}
|
|
2279
|
+
return ''
|
|
2280
|
+
}
|
|
2281
|
+
static updateRecord(arr = [], key, value) {
|
|
2282
|
+
return arr.map((item) => {
|
|
2283
|
+
if (this.sameKey(item, key)) {
|
|
2284
|
+
return {
|
|
2285
|
+
...item,
|
|
2286
|
+
value
|
|
2030
2287
|
}
|
|
2031
|
-
}
|
|
2288
|
+
}
|
|
2289
|
+
return item
|
|
2032
2290
|
})
|
|
2033
2291
|
}
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
if (
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
data: {
|
|
2045
|
-
payload: {
|
|
2046
|
-
input,
|
|
2047
|
-
output
|
|
2048
|
-
}
|
|
2049
|
-
}
|
|
2292
|
+
static updateOrInsertRecord(arr = [], key, value) {
|
|
2293
|
+
return this.insertOrUpdateRecord(arr, key, value)
|
|
2294
|
+
}
|
|
2295
|
+
static updateRecordsFromArray(arr = [], updateArr = []) {
|
|
2296
|
+
if (Array.isArray(arr) && Array.isArray(updateArr)) {
|
|
2297
|
+
const obj1 = this.toObject(arr)
|
|
2298
|
+
const obj2 = this.toObject(updateArr)
|
|
2299
|
+
return this.fromObject({
|
|
2300
|
+
...obj1,
|
|
2301
|
+
...obj2
|
|
2050
2302
|
})
|
|
2051
2303
|
}
|
|
2304
|
+
return []
|
|
2305
|
+
}
|
|
2306
|
+
static values(arr = []) {
|
|
2307
|
+
if (Array.isArray(arr)) {
|
|
2308
|
+
return arr.reduce((acc, item) => {
|
|
2309
|
+
acc.push(item.value)
|
|
2310
|
+
return acc
|
|
2311
|
+
}, [])
|
|
2312
|
+
}
|
|
2313
|
+
return []
|
|
2052
2314
|
}
|
|
2053
|
-
}
|
|
2054
|
-
|
|
2055
2315
|
|
|
2316
|
+
// getters
|
|
2317
|
+
get isValid() {
|
|
2318
|
+
return !!this.key
|
|
2319
|
+
}
|
|
2056
2320
|
|
|
2057
|
-
|
|
2321
|
+
get toObject() {
|
|
2322
|
+
const obj = {}
|
|
2323
|
+
if (this.isValid) {
|
|
2324
|
+
obj[this.key] = this.value
|
|
2325
|
+
}
|
|
2326
|
+
return obj
|
|
2327
|
+
}
|
|
2328
|
+
}
|
|
2058
2329
|
|
|
2330
|
+
function _isSame(key1, key2) {
|
|
2331
|
+
return key1 === key2
|
|
2332
|
+
}
|
|
2059
2333
|
|
|
2060
2334
|
|
|
2061
2335
|
|
|
2062
|
-
;// ./lib/models/
|
|
2336
|
+
;// ./lib/models/keyValueObject/index.js
|
|
2063
2337
|
|
|
2064
2338
|
|
|
2065
2339
|
|
|
2066
|
-
class Service {
|
|
2067
|
-
constructor({ repo }) {
|
|
2068
|
-
this.repo = repo
|
|
2069
|
-
}
|
|
2070
2340
|
|
|
2071
|
-
|
|
2072
|
-
return 'Service'
|
|
2073
|
-
}
|
|
2074
|
-
static get _superclass() {
|
|
2075
|
-
return 'Service'
|
|
2076
|
-
}
|
|
2341
|
+
;// ./lib/models/metadata/metadata.js
|
|
2077
2342
|
|
|
2078
|
-
deleteOne({ id }) {
|
|
2079
|
-
return this.repo.deleteOne({ id })
|
|
2080
|
-
.catch(() => {
|
|
2081
|
-
throw new Error(`Not found for query: ${id}`)
|
|
2082
|
-
})
|
|
2083
|
-
}
|
|
2084
2343
|
|
|
2085
|
-
async findAll({ query = {}, systemLog } = {}) {
|
|
2086
|
-
const result = await this.repo.findAll({ query, systemLog })
|
|
2087
|
-
return makeApiResponse({
|
|
2088
|
-
repo: this.repo,
|
|
2089
|
-
result
|
|
2090
|
-
})
|
|
2091
|
-
}
|
|
2092
2344
|
|
|
2093
|
-
|
|
2094
|
-
const result = await this.repo.findOne({ query, systemLog })
|
|
2095
|
-
return makeApiResponse({
|
|
2096
|
-
repo: this.repo,
|
|
2097
|
-
result
|
|
2098
|
-
})
|
|
2099
|
-
}
|
|
2345
|
+
const DELIMITER = '_'
|
|
2100
2346
|
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
if (Array.isArray(arr)) {
|
|
2106
|
-
return arr.map((a) => this.init(a))
|
|
2347
|
+
class Metadata extends KeyValueObject {
|
|
2348
|
+
static init(options = {}) {
|
|
2349
|
+
if (options instanceof this) {
|
|
2350
|
+
return options
|
|
2107
2351
|
}
|
|
2108
|
-
|
|
2352
|
+
const instance = new this({
|
|
2353
|
+
...options,
|
|
2354
|
+
key: stringFormatter(options.key, DELIMITER),
|
|
2355
|
+
})
|
|
2356
|
+
return instance.isValid ? instance : null
|
|
2109
2357
|
}
|
|
2110
|
-
|
|
2111
|
-
return
|
|
2358
|
+
static get _classname() {
|
|
2359
|
+
return 'Metadata'
|
|
2112
2360
|
}
|
|
2113
2361
|
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2362
|
+
static merge(toArr, fromArr) {
|
|
2363
|
+
(fromArr || []).map((from) => {
|
|
2364
|
+
const found = toArr.find((to) => {
|
|
2365
|
+
return metadata_isSame(to.key, from.key)
|
|
2366
|
+
})
|
|
2367
|
+
if (found) {
|
|
2368
|
+
found.value = (found.value || []).concat(from.value)
|
|
2369
|
+
} else {
|
|
2370
|
+
toArr.push(from)
|
|
2371
|
+
}
|
|
2122
2372
|
})
|
|
2373
|
+
return toArr
|
|
2123
2374
|
}
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
const copy = this.init(doc)
|
|
2127
|
-
if (copy) {
|
|
2128
|
-
const result = await this.repo.saveOne({ doc: copy, systemLog })
|
|
2129
|
-
return makeApiResponse({
|
|
2130
|
-
repo: this.repo,
|
|
2131
|
-
result
|
|
2132
|
-
})
|
|
2133
|
-
}
|
|
2134
|
-
return {
|
|
2135
|
-
isNew: null,
|
|
2136
|
-
data: [],
|
|
2137
|
-
err: new Error('doc is not a valid instance')
|
|
2138
|
-
}
|
|
2375
|
+
static sameKey(item, key) {
|
|
2376
|
+
return metadata_isSame(item.key, key)
|
|
2139
2377
|
}
|
|
2140
2378
|
}
|
|
2141
2379
|
|
|
2142
|
-
function
|
|
2143
|
-
|
|
2144
|
-
throw new Error('repo is required.')
|
|
2145
|
-
}
|
|
2146
|
-
if (repo._superclass !== Repo._superclass) {
|
|
2147
|
-
throw new Error('repo is not an instance of Repo.')
|
|
2148
|
-
}
|
|
2149
|
-
return new Service({ repo })
|
|
2380
|
+
function metadata_isSame(key1, key2) {
|
|
2381
|
+
return stringFormatter(key1, DELIMITER) === stringFormatter(key2, DELIMITER)
|
|
2150
2382
|
}
|
|
2151
2383
|
|
|
2152
2384
|
|
|
2153
2385
|
|
|
2154
|
-
;// ./lib/models/
|
|
2386
|
+
;// ./lib/models/metadata/index.js
|
|
2155
2387
|
|
|
2156
2388
|
|
|
2157
2389
|
|
|
2158
2390
|
|
|
2159
|
-
;// ./lib/models/
|
|
2391
|
+
;// ./lib/models/qMeta/qMeta.js
|
|
2160
2392
|
|
|
2161
2393
|
|
|
2162
|
-
|
|
2394
|
+
const updateAllowedProps = [
|
|
2395
|
+
'attributes',
|
|
2396
|
+
'ref'
|
|
2397
|
+
]
|
|
2398
|
+
|
|
2399
|
+
class QMeta {
|
|
2400
|
+
constructor(options = {}) {
|
|
2401
|
+
options = options || {}
|
|
2402
|
+
this.attributes = KeyValueObject.initOnlyValidFromArray(options.attributes)
|
|
2403
|
+
this.ref = options.ref || {}
|
|
2404
|
+
}
|
|
2405
|
+
|
|
2163
2406
|
static get _classname() {
|
|
2164
|
-
return '
|
|
2407
|
+
return 'QMeta'
|
|
2165
2408
|
}
|
|
2166
2409
|
static get _superclass() {
|
|
2167
|
-
return '
|
|
2410
|
+
return 'QMeta'
|
|
2168
2411
|
}
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
return _makeSetCode(fieldName, options)
|
|
2412
|
+
|
|
2413
|
+
// Class methods
|
|
2414
|
+
static init(options = {}) {
|
|
2415
|
+
if (options instanceof QMeta) {
|
|
2416
|
+
return options
|
|
2175
2417
|
}
|
|
2418
|
+
return new QMeta(options)
|
|
2176
2419
|
}
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
}, obj)
|
|
2184
|
-
return output
|
|
2420
|
+
|
|
2421
|
+
// instance methods
|
|
2422
|
+
addAttribute(obj) {
|
|
2423
|
+
const kvObject = KeyValueObject.init(obj)
|
|
2424
|
+
if (!kvObject) {
|
|
2425
|
+
throw new Error('invalid meta attribute')
|
|
2185
2426
|
}
|
|
2427
|
+
this.attributes.push(kvObject)
|
|
2428
|
+
return this
|
|
2186
2429
|
}
|
|
2187
|
-
}
|
|
2188
2430
|
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2431
|
+
update(obj) {
|
|
2432
|
+
Object.keys(obj).forEach((key) => {
|
|
2433
|
+
if (updateAllowedProps.includes(key)) {
|
|
2434
|
+
if (key === 'attributes') {
|
|
2435
|
+
this[key] = KeyValueObject.initOnlyValidFromArray(obj[key])
|
|
2436
|
+
} else {
|
|
2437
|
+
this[key] = obj[key]
|
|
2438
|
+
}
|
|
2439
|
+
}
|
|
2440
|
+
})
|
|
2441
|
+
return this
|
|
2197
2442
|
}
|
|
2198
2443
|
}
|
|
2199
2444
|
|
|
2200
2445
|
|
|
2201
2446
|
|
|
2202
|
-
;// ./lib/models/
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
;// ./lib/models/index.js
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2447
|
+
;// ./lib/models/qMeta/index.js
|
|
2212
2448
|
|
|
2213
2449
|
|
|
2214
2450
|
|
|
2215
2451
|
|
|
2452
|
+
;// ./lib/models/repo/index.js
|
|
2216
2453
|
|
|
2217
|
-
;// ./lib/helpers/generalPost/generalPost.js
|
|
2218
2454
|
|
|
2219
2455
|
|
|
2220
2456
|
|
|
2457
|
+
;// ./lib/models/service/index.js
|
|
2221
2458
|
|
|
2222
|
-
async function generalPost({ body = {}, GeneralModel, UniqueKeyGenerator, resourceInfo }) {
|
|
2223
|
-
const { resources, data, globalShared = {}, shared = {}, relationship = {} } = body
|
|
2224
|
-
const _resourceInfo = resourceInfo || body.resourceInfo
|
|
2225
|
-
_attachShared(data, globalShared, shared)
|
|
2226
|
-
const obj = await pReduce(resources, async (acc, resource) => {
|
|
2227
|
-
const service = _makeService(resource, _resourceInfo, UniqueKeyGenerator, GeneralModel)
|
|
2228
|
-
_createRelationship(data, relationship[resource], acc)
|
|
2229
|
-
const _data = data[resource]
|
|
2230
|
-
const result = await service.saveAll({ docs: [].concat(_data) })
|
|
2231
|
-
acc[resource] = Array.isArray(_data) ? result._data : result._data[0]
|
|
2232
|
-
return acc
|
|
2233
|
-
}, {})
|
|
2234
|
-
return obj
|
|
2235
|
-
}
|
|
2236
2459
|
|
|
2237
|
-
function _attachShared(data, globalShared = {}, shared = {}) {
|
|
2238
|
-
Object.keys(shared).forEach((key) => {
|
|
2239
|
-
const _data = data[key]
|
|
2240
|
-
data[key] = objectHelper.merge({}, _data, globalShared, shared[key] || {})
|
|
2241
|
-
})
|
|
2242
|
-
}
|
|
2243
2460
|
|
|
2244
|
-
function _createRelationship(data, relationship = {}, object) {
|
|
2245
|
-
Object.keys(relationship).forEach((key) => {
|
|
2246
|
-
const path = relationship[key]
|
|
2247
|
-
const val = objectHelper.get(object, path)
|
|
2248
|
-
objectHelper.set(data, key, val)
|
|
2249
|
-
})
|
|
2250
|
-
}
|
|
2251
2461
|
|
|
2252
|
-
|
|
2253
|
-
const { collectionName, fields } = resourceInfo[resource]
|
|
2254
|
-
const uniqueKeyGenerator = UniqueKeyGenerator.makeGenerator(fields)
|
|
2255
|
-
const model = new GeneralModel({ collectionName, uniqueKeyGenerator })
|
|
2256
|
-
return makeService({
|
|
2257
|
-
repo: new Repo({ model })
|
|
2258
|
-
})
|
|
2259
|
-
}
|
|
2462
|
+
;// ./lib/models/trackedEntity/trackedEntity.js
|
|
2260
2463
|
|
|
2261
2464
|
|
|
2465
|
+
class TrackedEntity {
|
|
2466
|
+
constructor(options = {}, { trackFlat = false } = {}) {
|
|
2467
|
+
const timestamp = Date.now()
|
|
2468
|
+
const _tracking = {
|
|
2469
|
+
active: options.active ?? true,
|
|
2470
|
+
created: options.created ?? timestamp,
|
|
2471
|
+
creator: options.creator ?? '',
|
|
2472
|
+
deleted: options.deleted ?? false,
|
|
2473
|
+
modified: options.modified ?? timestamp,
|
|
2474
|
+
owner: options.owner ?? '',
|
|
2475
|
+
}
|
|
2262
2476
|
|
|
2263
|
-
|
|
2477
|
+
if (trackFlat) {
|
|
2478
|
+
Object.assign(this, _tracking)
|
|
2479
|
+
} else {
|
|
2480
|
+
this.meta = { ..._tracking, ...options.meta }
|
|
2481
|
+
}
|
|
2482
|
+
}
|
|
2264
2483
|
|
|
2484
|
+
// Class methods
|
|
2485
|
+
static get _classname() {
|
|
2486
|
+
return 'TrackedEntity'
|
|
2487
|
+
}
|
|
2488
|
+
static get _superclass() {
|
|
2489
|
+
return 'TrackedEntity'
|
|
2490
|
+
}
|
|
2265
2491
|
|
|
2492
|
+
static init(options = {}) {
|
|
2493
|
+
return init(this, options)
|
|
2494
|
+
}
|
|
2495
|
+
static initFromArray(arr = []) {
|
|
2496
|
+
return initFromArray(this, arr)
|
|
2497
|
+
}
|
|
2498
|
+
static initOnlyValidFromArray(arr = []) {
|
|
2499
|
+
return initOnlyValidFromArray(this, arr)
|
|
2500
|
+
}
|
|
2501
|
+
static nest(entity) {
|
|
2502
|
+
const { active, created, creator, deleted, modified, owner, ...rest } = entity
|
|
2503
|
+
return { ...rest, meta: { active, created, creator, deleted, modified, owner } }
|
|
2504
|
+
}
|
|
2266
2505
|
|
|
2506
|
+
// getters
|
|
2507
|
+
get isValid() {
|
|
2508
|
+
return !!this
|
|
2509
|
+
}
|
|
2267
2510
|
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2511
|
+
setModified() {
|
|
2512
|
+
const timestamp = Date.now()
|
|
2513
|
+
if (this.meta) {
|
|
2514
|
+
this.meta.modified = timestamp
|
|
2515
|
+
} else {
|
|
2516
|
+
this.modified = timestamp
|
|
2517
|
+
}
|
|
2273
2518
|
}
|
|
2274
|
-
return num
|
|
2275
2519
|
}
|
|
2276
2520
|
|
|
2521
|
+
;// ./lib/models/trackedEntity/index.js
|
|
2277
2522
|
|
|
2523
|
+
// Explicit named export (optional)
|
|
2278
2524
|
|
|
2279
|
-
;// ./lib/
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
;// ./lib/helpers/pReduce/index.js
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
;// ./lib/helpers/stringFormatter/index.js
|
|
2525
|
+
;// ./lib/models/tenantAwareEntity/tenantAwareEntity.js
|
|
2290
2526
|
|
|
2291
2527
|
|
|
2528
|
+
class TenantAwareEntity extends TrackedEntity {
|
|
2529
|
+
constructor(options = {}) {
|
|
2530
|
+
options = options || {}
|
|
2292
2531
|
|
|
2532
|
+
/**
|
|
2533
|
+
* instead of throw error, we choose to implement the isValid checking
|
|
2534
|
+
*/
|
|
2535
|
+
// if (!options.tenantCode) {
|
|
2536
|
+
// throw new Error('tenantCode required')
|
|
2537
|
+
// }
|
|
2293
2538
|
|
|
2294
|
-
|
|
2295
|
-
function baseXEncode(num, base = 34) {
|
|
2296
|
-
const charset = getBaseCharset(base)
|
|
2297
|
-
return encode(num, charset)
|
|
2298
|
-
}
|
|
2539
|
+
super(options)
|
|
2299
2540
|
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
if (int === 0) {
|
|
2303
|
-
return byCode[0];
|
|
2541
|
+
this._tenant = options._tenant
|
|
2542
|
+
this.tenantCode = options.tenantCode // Required for multi-tenancy
|
|
2304
2543
|
}
|
|
2305
2544
|
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
res = byCode[int % max] + res;
|
|
2310
|
-
int = Math.floor(int / max);
|
|
2545
|
+
// Class methods
|
|
2546
|
+
static get _classname() {
|
|
2547
|
+
return 'TenantAwareEntity'
|
|
2311
2548
|
}
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
function getBaseCharset(base) {
|
|
2316
|
-
let charset = '9876543210ABCDEFGHJKLMNPQRSTUVWXYZ'
|
|
2317
|
-
if (base === 58) {
|
|
2318
|
-
charset = '9876543210ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz'
|
|
2549
|
+
static get _superclass() {
|
|
2550
|
+
return 'TenantAwareEntity'
|
|
2319
2551
|
}
|
|
2320
|
-
return indexCharset(charset)
|
|
2321
|
-
}
|
|
2322
2552
|
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
length = str.length,
|
|
2327
|
-
i, char;
|
|
2328
|
-
for (i = 0; i < length; i++) {
|
|
2329
|
-
char = str[i];
|
|
2330
|
-
byCode[i] = char;
|
|
2331
|
-
byChar[char] = i;
|
|
2553
|
+
// getters
|
|
2554
|
+
get isValid() {
|
|
2555
|
+
return super.isValid && !!this.tenantCode // Required for multi-tenancy
|
|
2332
2556
|
}
|
|
2333
|
-
return { byCode: byCode, byChar: byChar, length: length };
|
|
2334
2557
|
}
|
|
2335
2558
|
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2559
|
+
;// ./lib/models/tenantAwareEntity/index.js
|
|
2560
|
+
|
|
2561
|
+
|
|
2562
|
+
|
|
2563
|
+
;// ./lib/models/uniqueKeyGenerator/uniqueKeyGenerator.js
|
|
2564
|
+
|
|
2565
|
+
|
|
2566
|
+
class UniqueKeyGenerator {
|
|
2567
|
+
static get _classname() {
|
|
2568
|
+
return 'UniqueKeyGenerator'
|
|
2344
2569
|
}
|
|
2345
|
-
|
|
2346
|
-
|
|
2570
|
+
static get _superclass() {
|
|
2571
|
+
return 'UniqueKeyGenerator'
|
|
2347
2572
|
}
|
|
2348
|
-
|
|
2349
|
-
|
|
2573
|
+
static makeFormatter({ fieldName, format, options }) {
|
|
2574
|
+
switch (format) {
|
|
2575
|
+
case 'set_code':
|
|
2576
|
+
return _makeSetCode(fieldName, options)
|
|
2577
|
+
default:
|
|
2578
|
+
return _makeSetCode(fieldName, options)
|
|
2579
|
+
}
|
|
2350
2580
|
}
|
|
2351
|
-
|
|
2352
|
-
|
|
2581
|
+
static makeGenerator(arr) {
|
|
2582
|
+
const fns = arr.map((item) => this.makeFormatter(item))
|
|
2583
|
+
return async (obj) => {
|
|
2584
|
+
const output = await pReduce(fns, async (acc, fn) => {
|
|
2585
|
+
const _obj = await fn(obj)
|
|
2586
|
+
return Object.assign(acc, _obj)
|
|
2587
|
+
}, obj)
|
|
2588
|
+
return output
|
|
2589
|
+
}
|
|
2353
2590
|
}
|
|
2354
|
-
const chars = [...str]
|
|
2355
|
-
return [...Array(len)].map(i => {
|
|
2356
|
-
return chars[(Math.random() * chars.length) | 0]
|
|
2357
|
-
}).join``
|
|
2358
2591
|
}
|
|
2359
2592
|
|
|
2360
|
-
function
|
|
2361
|
-
|
|
2362
|
-
|
|
2593
|
+
function _makeSetCode(fieldName, options) {
|
|
2594
|
+
return async (obj = {}) => {
|
|
2595
|
+
if (obj[fieldName]) {
|
|
2596
|
+
return {}
|
|
2597
|
+
}
|
|
2598
|
+
return {
|
|
2599
|
+
[fieldName]: stringHelper.setCode()
|
|
2600
|
+
}
|
|
2363
2601
|
}
|
|
2364
|
-
const splitString = str.split('')
|
|
2365
|
-
const reverseArray = splitString.reverse()
|
|
2366
|
-
return reverseArray.join('')
|
|
2367
|
-
}
|
|
2368
|
-
|
|
2369
|
-
function setCode(base = 34) {
|
|
2370
|
-
const now = (new Date()).valueOf()
|
|
2371
|
-
const random = randomString({
|
|
2372
|
-
len: 8,
|
|
2373
|
-
pattern: '1'
|
|
2374
|
-
})
|
|
2375
|
-
const str = reverse(`${now}${random}`)
|
|
2376
|
-
// const str = `${now}${random}`
|
|
2377
|
-
return baseXEncode(str, base)
|
|
2378
2602
|
}
|
|
2379
2603
|
|
|
2380
|
-
const stringHelper = {
|
|
2381
|
-
setCode
|
|
2382
|
-
}
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
;// ./lib/helpers/stringHelper/index.js
|
|
2386
2604
|
|
|
2387
2605
|
|
|
2606
|
+
;// ./lib/models/uniqueKeyGenerator/index.js
|
|
2388
2607
|
|
|
2389
2608
|
|
|
2390
2609
|
|
|
2391
|
-
;// ./lib/helpers/index.js
|
|
2392
2610
|
|
|
2611
|
+
;// ./lib/models/index.js
|
|
2393
2612
|
|
|
2394
2613
|
|
|
2395
2614
|
|