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