@questwork/q-utilities 0.1.11 → 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 +960 -738
- package/dist/{index.min.js → q-utilities.min.js} +1027 -799
- package/package.json +5 -12
package/dist/index.min.cjs
CHANGED
|
@@ -56,13 +56,18 @@ __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),
|
|
62
64
|
formatDate: () => (/* reexport */ formatDate),
|
|
63
65
|
generalPost: () => (/* reexport */ generalPost),
|
|
64
66
|
getValidation: () => (/* reexport */ getValidation),
|
|
65
|
-
getValueByKeys: () => (/* reexport */
|
|
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),
|
|
@@ -260,7 +265,7 @@ function padding(m) {
|
|
|
260
265
|
|
|
261
266
|
;// ./lib/helpers/getValueByKeys/getValueByKeys.js
|
|
262
267
|
// keys can be array or object or string
|
|
263
|
-
function
|
|
268
|
+
function getValueByKeys_getValueByKeys(keys, data) {
|
|
264
269
|
let _keys = keys
|
|
265
270
|
let _data = data
|
|
266
271
|
if (typeof keys === 'string') {
|
|
@@ -276,7 +281,7 @@ function getValueByKeys(keys, data) {
|
|
|
276
281
|
}
|
|
277
282
|
const firstKey = _keys.shift()
|
|
278
283
|
if (_data && Object.prototype.hasOwnProperty.call(_data, firstKey)) {
|
|
279
|
-
return
|
|
284
|
+
return getValueByKeys_getValueByKeys(_keys, _data[firstKey])
|
|
280
285
|
}
|
|
281
286
|
if (_data && firstKey) {
|
|
282
287
|
return _data[firstKey]
|
|
@@ -284,12 +289,11 @@ function getValueByKeys(keys, data) {
|
|
|
284
289
|
return _data
|
|
285
290
|
|
|
286
291
|
}
|
|
287
|
-
/* harmony default export */ const
|
|
288
|
-
getValueByKeys
|
|
292
|
+
/* harmony default export */ const getValueByKeys = ({
|
|
293
|
+
getValueByKeys: getValueByKeys_getValueByKeys
|
|
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
|
|
|
@@ -429,7 +465,7 @@ function _existObject(data, args) {
|
|
|
429
465
|
const arg = args[0]
|
|
430
466
|
return data.filter((e) => {
|
|
431
467
|
if (arg.includes('.')) {
|
|
432
|
-
return
|
|
468
|
+
return getValueByKeys_getValueByKeys(arg.split('.'), e)
|
|
433
469
|
}
|
|
434
470
|
return Object.prototype.hasOwnProperty.call(e, arg)
|
|
435
471
|
})
|
|
@@ -447,7 +483,7 @@ function _existObject(data, args) {
|
|
|
447
483
|
const [key, ..._argsArr] = args
|
|
448
484
|
const _args = _argsArr.flat()
|
|
449
485
|
return data.filter((e) => {
|
|
450
|
-
const value = key.includes('.') ?
|
|
486
|
+
const value = key.includes('.') ? getValueByKeys_getValueByKeys(key.split('.'), e) : e[key]
|
|
451
487
|
return _args.some((arg) => _performOperation(arg, value))
|
|
452
488
|
})
|
|
453
489
|
}
|
|
@@ -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':
|
|
@@ -1219,21 +1268,21 @@ function concatStringByArray(arrTemplate, data) {
|
|
|
1219
1268
|
const { type, value = '', restriction, template, format, showMinutes } = item
|
|
1220
1269
|
switch (type) {
|
|
1221
1270
|
case('label'): {
|
|
1222
|
-
if (getValidation(restriction, data,
|
|
1271
|
+
if (getValidation(restriction, data, getValueByKeys_getValueByKeys)) {
|
|
1223
1272
|
acc += (value.toString())
|
|
1224
1273
|
}
|
|
1225
1274
|
break
|
|
1226
1275
|
}
|
|
1227
1276
|
case('value'): {
|
|
1228
|
-
if (getValidation(restriction, data,
|
|
1229
|
-
const _value =
|
|
1277
|
+
if (getValidation(restriction, data, getValueByKeys_getValueByKeys)) {
|
|
1278
|
+
const _value = getValueByKeys_getValueByKeys(value.split('.'), data) || ''
|
|
1230
1279
|
acc += (_value.toString())
|
|
1231
1280
|
}
|
|
1232
1281
|
break
|
|
1233
1282
|
}
|
|
1234
1283
|
case('array'): {
|
|
1235
|
-
if (getValidation(restriction, data,
|
|
1236
|
-
const _value =
|
|
1284
|
+
if (getValidation(restriction, data, getValueByKeys_getValueByKeys)) {
|
|
1285
|
+
const _value = getValueByKeys_getValueByKeys(value.split('.'), data) || []
|
|
1237
1286
|
acc += _value.reduce((_acc, item) => {
|
|
1238
1287
|
return _acc += concatStringByArray(template, item)
|
|
1239
1288
|
}, '')
|
|
@@ -1241,9 +1290,9 @@ function concatStringByArray(arrTemplate, data) {
|
|
|
1241
1290
|
break
|
|
1242
1291
|
}
|
|
1243
1292
|
case('ellipsis'): {
|
|
1244
|
-
if (getValidation(restriction, data,
|
|
1293
|
+
if (getValidation(restriction, data, getValueByKeys_getValueByKeys)) {
|
|
1245
1294
|
const { maxLength } = item
|
|
1246
|
-
const _value =
|
|
1295
|
+
const _value = getValueByKeys_getValueByKeys(value.split('.'), data) || ''
|
|
1247
1296
|
if (_value.length <= maxLength) {
|
|
1248
1297
|
acc += (_value.toString())
|
|
1249
1298
|
} else {
|
|
@@ -1253,14 +1302,14 @@ function concatStringByArray(arrTemplate, data) {
|
|
|
1253
1302
|
break
|
|
1254
1303
|
}
|
|
1255
1304
|
case ('date'): {
|
|
1256
|
-
if (getValidation(restriction, data,
|
|
1257
|
-
const _value =
|
|
1305
|
+
if (getValidation(restriction, data, getValueByKeys_getValueByKeys)) {
|
|
1306
|
+
const _value = getValueByKeys_getValueByKeys(value.split('.'), data) || ''
|
|
1258
1307
|
acc += (formatDate(_value, format).toString())
|
|
1259
1308
|
}
|
|
1260
1309
|
break
|
|
1261
1310
|
}
|
|
1262
1311
|
case ('templateCompiler'): {
|
|
1263
|
-
if (getValidation(restriction, data,
|
|
1312
|
+
if (getValidation(restriction, data, getValueByKeys_getValueByKeys)) {
|
|
1264
1313
|
const templateCompiler = new TemplateCompiler({ data })
|
|
1265
1314
|
acc += templateCompiler.pipe(value)
|
|
1266
1315
|
}
|
|
@@ -1280,13 +1329,16 @@ function concatStringByArray(arrTemplate, data) {
|
|
|
1280
1329
|
|
|
1281
1330
|
|
|
1282
1331
|
;// ./lib/helpers/convertString/convertString.js
|
|
1332
|
+
|
|
1333
|
+
|
|
1283
1334
|
function convertString(string, patternMatch = /\$\{(.+?)\}/g, value, getValueByKeys) {
|
|
1284
|
-
if (!string
|
|
1335
|
+
if (!string) {
|
|
1285
1336
|
return ''
|
|
1286
1337
|
}
|
|
1338
|
+
let _getValueByKeys = typeof getValueByKeys !== 'function' ? getValueByKeys : getValueByKeys_getValueByKeys
|
|
1287
1339
|
const reg = new RegExp(patternMatch, 'g')
|
|
1288
1340
|
return string.replace(reg, (match, key) => {
|
|
1289
|
-
const result =
|
|
1341
|
+
const result = _getValueByKeys({ keys: key.split('.'), obj: value })
|
|
1290
1342
|
if (result === null || result === undefined) {
|
|
1291
1343
|
return ''
|
|
1292
1344
|
}
|
|
@@ -1437,282 +1489,468 @@ async function pReduce(iterable, reducer, initialValue) {
|
|
|
1437
1489
|
|
|
1438
1490
|
|
|
1439
1491
|
|
|
1440
|
-
;// ./lib/models/
|
|
1441
|
-
class
|
|
1442
|
-
constructor(options
|
|
1492
|
+
;// ./lib/models/repo/repo.js
|
|
1493
|
+
class Repo {
|
|
1494
|
+
constructor(options) {
|
|
1443
1495
|
options = options || {}
|
|
1444
|
-
this.
|
|
1445
|
-
this.
|
|
1446
|
-
this.
|
|
1447
|
-
this.
|
|
1448
|
-
this.
|
|
1449
|
-
|
|
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
|
|
1450
1503
|
}
|
|
1451
|
-
|
|
1452
1504
|
static init(options = {}) {
|
|
1453
1505
|
if (options instanceof this) {
|
|
1454
1506
|
return options
|
|
1455
1507
|
}
|
|
1456
1508
|
const instance = new this(options)
|
|
1457
|
-
return instance
|
|
1509
|
+
return instance.isValid ? instance : null
|
|
1458
1510
|
}
|
|
1459
1511
|
static get _classname() {
|
|
1460
|
-
return '
|
|
1512
|
+
return 'Repo'
|
|
1461
1513
|
}
|
|
1462
1514
|
static get _superclass() {
|
|
1463
|
-
return '
|
|
1515
|
+
return 'Repo'
|
|
1464
1516
|
}
|
|
1465
1517
|
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
if (this._instanceBuilder && (typeof this._instanceBuilder === 'function')) {
|
|
1469
|
-
return this._data.map(this._instanceBuilder)
|
|
1470
|
-
}
|
|
1471
|
-
return this._data
|
|
1518
|
+
get _classname() {
|
|
1519
|
+
return 'Repo'
|
|
1472
1520
|
}
|
|
1473
|
-
}
|
|
1474
1521
|
|
|
1522
|
+
get _superclass() {
|
|
1523
|
+
return 'Repo'
|
|
1524
|
+
}
|
|
1475
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
|
+
}
|
|
1476
1532
|
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
return ApiResponse.init({
|
|
1482
|
-
...result,
|
|
1483
|
-
_instanceBuilder: (i) => {
|
|
1484
|
-
return repo.init(i)
|
|
1533
|
+
get queryOptions() {
|
|
1534
|
+
return {
|
|
1535
|
+
...this._sharedOptions,
|
|
1536
|
+
...this._queryOptions,
|
|
1485
1537
|
}
|
|
1486
|
-
})
|
|
1487
|
-
}
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
;// ./lib/models/apiResponse/index.js
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
;// ./lib/models/keyValueObject/keyValueObject.js
|
|
1498
|
-
class KeyValueObject {
|
|
1499
|
-
constructor(options = {}) {
|
|
1500
|
-
options = options || {}
|
|
1501
|
-
this.key = options.key || null
|
|
1502
|
-
this.value = (typeof options.value !== 'undefined') ? options.value : ''
|
|
1503
1538
|
}
|
|
1504
1539
|
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1540
|
+
get saveOptions() {
|
|
1541
|
+
return {
|
|
1542
|
+
...this._sharedOptions,
|
|
1543
|
+
...this._saveOptions,
|
|
1509
1544
|
}
|
|
1510
|
-
const instance = new this(options)
|
|
1511
|
-
return instance.isValid ? instance : null
|
|
1512
1545
|
}
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1546
|
+
|
|
1547
|
+
init(options) {
|
|
1548
|
+
if (this._Class && typeof this._Class.init === 'function') {
|
|
1549
|
+
return this._Class.init(options)
|
|
1516
1550
|
}
|
|
1517
|
-
return
|
|
1518
|
-
}
|
|
1519
|
-
static initOnlyValidFromArray(arr = []) {
|
|
1520
|
-
return this.initFromArray(arr).filter((i) => i)
|
|
1521
|
-
}
|
|
1522
|
-
static get _classname() {
|
|
1523
|
-
return 'KeyValueObject'
|
|
1524
|
-
}
|
|
1525
|
-
static get _superclass() {
|
|
1526
|
-
return 'KeyValueObject'
|
|
1551
|
+
return options
|
|
1527
1552
|
}
|
|
1528
1553
|
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
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
|
|
1535
1564
|
}
|
|
1536
|
-
return arr
|
|
1537
1565
|
}
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
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 } }]
|
|
1544
1574
|
})
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
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
|
+
})
|
|
1552
1590
|
})
|
|
1553
1591
|
}
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
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 } }]
|
|
1557
1599
|
})
|
|
1558
|
-
return
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
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
|
+
})
|
|
1563
1623
|
}
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
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
|
+
})
|
|
1572
1657
|
}
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
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 } }]
|
|
1580
1665
|
})
|
|
1581
|
-
|
|
1582
|
-
|
|
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
|
+
})
|
|
1583
1695
|
}
|
|
1584
|
-
return this.getValueByKeyFromArray(arr, key)
|
|
1585
1696
|
}
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
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
|
|
1593
1711
|
}
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1712
|
+
|
|
1713
|
+
static init(options = {}) {
|
|
1714
|
+
if (options instanceof this) {
|
|
1715
|
+
return options
|
|
1597
1716
|
}
|
|
1598
|
-
|
|
1717
|
+
const instance = new this(options)
|
|
1718
|
+
return instance
|
|
1599
1719
|
}
|
|
1600
|
-
static
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
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)
|
|
1606
1731
|
}
|
|
1607
|
-
return
|
|
1732
|
+
return this._data
|
|
1608
1733
|
}
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
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)
|
|
1615
1746
|
}
|
|
1616
|
-
|
|
1747
|
+
})
|
|
1748
|
+
}
|
|
1749
|
+
|
|
1750
|
+
|
|
1751
|
+
|
|
1752
|
+
;// ./lib/models/service/service.js
|
|
1753
|
+
|
|
1754
|
+
|
|
1755
|
+
|
|
1756
|
+
class Service {
|
|
1757
|
+
constructor({ repo }) {
|
|
1758
|
+
this.repo = repo
|
|
1617
1759
|
}
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
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}`)
|
|
1622
1772
|
})
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
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
|
|
1628
1780
|
})
|
|
1629
|
-
return toArr
|
|
1630
1781
|
}
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
}
|
|
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
|
+
})
|
|
1638
1789
|
}
|
|
1639
|
-
|
|
1640
|
-
|
|
1790
|
+
|
|
1791
|
+
init(options) {
|
|
1792
|
+
return this.repo.init(options)
|
|
1641
1793
|
}
|
|
1642
|
-
|
|
1794
|
+
initFromArray(arr = []) {
|
|
1643
1795
|
if (Array.isArray(arr)) {
|
|
1644
|
-
return arr.
|
|
1645
|
-
acc[item.key] = item.value
|
|
1646
|
-
return acc
|
|
1647
|
-
}, {})
|
|
1796
|
+
return arr.map((a) => this.init(a))
|
|
1648
1797
|
}
|
|
1649
|
-
return
|
|
1798
|
+
return []
|
|
1650
1799
|
}
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
return arr.reduce((acc, item) => {
|
|
1654
|
-
acc.push(`${item.key}: ${item.value}`)
|
|
1655
|
-
return acc
|
|
1656
|
-
}, []).join(delimiter)
|
|
1657
|
-
}
|
|
1658
|
-
return ''
|
|
1800
|
+
initOnlyValidFromArray(arr = []) {
|
|
1801
|
+
return this.initFromArray(arr).filter((i) => i)
|
|
1659
1802
|
}
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
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
|
|
1669
1812
|
})
|
|
1670
1813
|
}
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
}
|
|
1674
|
-
|
|
1675
|
-
if (
|
|
1676
|
-
const
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
...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
|
|
1681
1823
|
})
|
|
1682
1824
|
}
|
|
1683
|
-
return
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
return arr.reduce((acc, item) => {
|
|
1688
|
-
acc.push(item.value)
|
|
1689
|
-
return acc
|
|
1690
|
-
}, [])
|
|
1825
|
+
return {
|
|
1826
|
+
isNew: null,
|
|
1827
|
+
data: [],
|
|
1828
|
+
err: new Error('doc is not a valid instance')
|
|
1691
1829
|
}
|
|
1692
|
-
return []
|
|
1693
1830
|
}
|
|
1831
|
+
}
|
|
1694
1832
|
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1833
|
+
function makeService({ repo }) {
|
|
1834
|
+
if (repo === undefined) {
|
|
1835
|
+
throw new Error('repo is required.')
|
|
1836
|
+
}
|
|
1837
|
+
if (repo._superclass !== Repo._superclass) {
|
|
1838
|
+
throw new Error('repo is not an instance of Repo.')
|
|
1698
1839
|
}
|
|
1840
|
+
return new Service({ repo })
|
|
1841
|
+
}
|
|
1699
1842
|
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
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
|
|
1706
1908
|
}
|
|
1707
1909
|
}
|
|
1708
1910
|
|
|
1709
|
-
|
|
1710
|
-
|
|
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 []
|
|
1711
1922
|
}
|
|
1712
1923
|
|
|
1924
|
+
;// ./lib/helpers/initFromArray/index.js
|
|
1713
1925
|
|
|
1714
1926
|
|
|
1715
|
-
;// ./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
|
|
1716
1954
|
|
|
1717
1955
|
|
|
1718
1956
|
|
|
@@ -1731,129 +1969,161 @@ function stringFormatter(str, delimiter = '_') {
|
|
|
1731
1969
|
|
|
1732
1970
|
|
|
1733
1971
|
|
|
1734
|
-
;// ./lib/
|
|
1972
|
+
;// ./lib/helpers/stringFormatter/index.js
|
|
1735
1973
|
|
|
1736
1974
|
|
|
1737
1975
|
|
|
1738
|
-
const DELIMITER = '_'
|
|
1739
1976
|
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
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]
|
|
1750
1987
|
}
|
|
1751
|
-
|
|
1752
|
-
|
|
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)
|
|
1753
1994
|
}
|
|
1995
|
+
return res
|
|
1996
|
+
}
|
|
1754
1997
|
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
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()
|
|
1764
2077
|
}
|
|
2078
|
+
return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()
|
|
1765
2079
|
})
|
|
1766
|
-
|
|
1767
|
-
}
|
|
1768
|
-
static sameKey(item, key) {
|
|
1769
|
-
return metadata_isSame(item.key, key)
|
|
1770
|
-
}
|
|
2080
|
+
.join('')
|
|
1771
2081
|
}
|
|
1772
2082
|
|
|
1773
|
-
|
|
1774
|
-
|
|
2083
|
+
const stringHelper = {
|
|
2084
|
+
isSame,
|
|
2085
|
+
setCode,
|
|
2086
|
+
toCamelCase,
|
|
1775
2087
|
}
|
|
1776
2088
|
|
|
1777
2089
|
|
|
1778
2090
|
|
|
1779
|
-
;// ./lib/
|
|
2091
|
+
;// ./lib/helpers/stringHelper/index.js
|
|
1780
2092
|
|
|
1781
2093
|
|
|
1782
2094
|
|
|
1783
2095
|
|
|
1784
|
-
;// ./lib/
|
|
2096
|
+
;// ./lib/helpers/index.js
|
|
1785
2097
|
|
|
1786
2098
|
|
|
1787
|
-
const updateAllowedProps = [
|
|
1788
|
-
'attributes',
|
|
1789
|
-
'ref'
|
|
1790
|
-
]
|
|
1791
2099
|
|
|
1792
|
-
class QMeta {
|
|
1793
|
-
constructor(options = {}) {
|
|
1794
|
-
options = options || {}
|
|
1795
|
-
this.attributes = KeyValueObject.initOnlyValidFromArray(options.attributes)
|
|
1796
|
-
this.ref = options.ref || {}
|
|
1797
|
-
}
|
|
1798
2100
|
|
|
1799
|
-
static get _classname() {
|
|
1800
|
-
return 'QMeta'
|
|
1801
|
-
}
|
|
1802
|
-
static get _superclass() {
|
|
1803
|
-
return 'QMeta'
|
|
1804
|
-
}
|
|
1805
2101
|
|
|
1806
|
-
// Class methods
|
|
1807
|
-
static init(options = {}) {
|
|
1808
|
-
if (options instanceof QMeta) {
|
|
1809
|
-
return options
|
|
1810
|
-
}
|
|
1811
|
-
return new QMeta(options)
|
|
1812
|
-
}
|
|
1813
2102
|
|
|
1814
|
-
// instance methods
|
|
1815
|
-
addAttribute(obj) {
|
|
1816
|
-
const kvObject = KeyValueObject.init(obj)
|
|
1817
|
-
if (!kvObject) {
|
|
1818
|
-
throw new Error('invalid meta attribute')
|
|
1819
|
-
}
|
|
1820
|
-
this.attributes.push(kvObject)
|
|
1821
|
-
return this
|
|
1822
|
-
}
|
|
1823
2103
|
|
|
1824
|
-
update(obj) {
|
|
1825
|
-
Object.keys(obj).forEach((key) => {
|
|
1826
|
-
if (updateAllowedProps.includes(key)) {
|
|
1827
|
-
if (key === 'attributes') {
|
|
1828
|
-
this[key] = KeyValueObject.initOnlyValidFromArray(obj[key])
|
|
1829
|
-
} else {
|
|
1830
|
-
this[key] = obj[key]
|
|
1831
|
-
}
|
|
1832
|
-
}
|
|
1833
|
-
})
|
|
1834
|
-
return this
|
|
1835
|
-
}
|
|
1836
|
-
}
|
|
1837
2104
|
|
|
1838
2105
|
|
|
1839
2106
|
|
|
1840
|
-
;// ./lib/models/qMeta/index.js
|
|
1841
2107
|
|
|
1842
2108
|
|
|
1843
2109
|
|
|
1844
2110
|
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
2111
|
+
|
|
2112
|
+
;// ./lib/models/apiResponse/index.js
|
|
2113
|
+
|
|
2114
|
+
|
|
2115
|
+
|
|
2116
|
+
|
|
2117
|
+
|
|
2118
|
+
;// ./lib/models/keyValueObject/keyValueObject.js
|
|
2119
|
+
class KeyValueObject {
|
|
2120
|
+
constructor(options = {}) {
|
|
1848
2121
|
options = options || {}
|
|
1849
|
-
this.
|
|
1850
|
-
this.
|
|
1851
|
-
this._queryOptions = options._queryOptions
|
|
1852
|
-
this._saveOptions = options._saveOptions
|
|
1853
|
-
this._Class = options._constructor && options._constructor._Class
|
|
1854
|
-
? options._constructor._Class
|
|
1855
|
-
: null
|
|
2122
|
+
this.key = options.key || null
|
|
2123
|
+
this.value = (typeof options.value !== 'undefined') ? options.value : ''
|
|
1856
2124
|
}
|
|
2125
|
+
|
|
2126
|
+
// Class methods
|
|
1857
2127
|
static init(options = {}) {
|
|
1858
2128
|
if (options instanceof this) {
|
|
1859
2129
|
return options
|
|
@@ -1861,532 +2131,484 @@ class Repo {
|
|
|
1861
2131
|
const instance = new this(options)
|
|
1862
2132
|
return instance.isValid ? instance : null
|
|
1863
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
|
+
}
|
|
1864
2143
|
static get _classname() {
|
|
1865
|
-
return '
|
|
2144
|
+
return 'KeyValueObject'
|
|
1866
2145
|
}
|
|
1867
2146
|
static get _superclass() {
|
|
1868
|
-
return '
|
|
2147
|
+
return 'KeyValueObject'
|
|
1869
2148
|
}
|
|
1870
2149
|
|
|
1871
|
-
|
|
1872
|
-
|
|
2150
|
+
static addItem(arr, key, value) {
|
|
2151
|
+
arr.push(this.init({ key, value }))
|
|
1873
2152
|
}
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
2153
|
+
static addRecord(arr = [], key, value) {
|
|
2154
|
+
if (!this.hasKeyValue(arr, key, value)) {
|
|
2155
|
+
arr.push(this.init({ key, value }))
|
|
2156
|
+
}
|
|
2157
|
+
return arr
|
|
1877
2158
|
}
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
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
|
+
})
|
|
1884
2166
|
}
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
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
|
+
})
|
|
1891
2174
|
}
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
}
|
|
2175
|
+
static foundByKey(arr = [], key) {
|
|
2176
|
+
const found = arr.find((m) => {
|
|
2177
|
+
return this.sameKey(m, key)
|
|
2178
|
+
})
|
|
2179
|
+
return found || null
|
|
1898
2180
|
}
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
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
|
|
1903
2197
|
}
|
|
1904
|
-
|
|
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)
|
|
1905
2206
|
}
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
return {
|
|
1911
|
-
...result, // { message: 'ok', total }
|
|
1912
|
-
isNew: false,
|
|
1913
|
-
data: []
|
|
2207
|
+
static getValuesByKey(arr = [], key) {
|
|
2208
|
+
return arr.reduce((acc, item) => {
|
|
2209
|
+
if (this.sameKey(item, key)) {
|
|
2210
|
+
acc.push(item.value)
|
|
1914
2211
|
}
|
|
1915
|
-
|
|
1916
|
-
|
|
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
|
|
1917
2218
|
}
|
|
2219
|
+
return arr.filter((item) => (this.sameKey(item, key) && _isSame(item.value, value))).length > 0
|
|
1918
2220
|
}
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
})
|
|
1928
|
-
return new Promise((resolve, reject) => {
|
|
1929
|
-
this.model.findAll(query, this.queryOptions, (err, data, total) => {
|
|
1930
|
-
if (err) {
|
|
1931
|
-
log({ level: 'warn', output: err.toString() })
|
|
1932
|
-
reject(err)
|
|
1933
|
-
} else {
|
|
1934
|
-
const result = {
|
|
1935
|
-
isNew: false,
|
|
1936
|
-
data,
|
|
1937
|
-
total: total || data.length
|
|
1938
|
-
}
|
|
1939
|
-
log({ level: 'info', output: { ...result } })
|
|
1940
|
-
resolve(result)
|
|
1941
|
-
}
|
|
1942
|
-
})
|
|
1943
|
-
})
|
|
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
|
|
1944
2229
|
}
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
const result = {
|
|
1959
|
-
isNew: false,
|
|
1960
|
-
data,
|
|
1961
|
-
total: 1
|
|
1962
|
-
}
|
|
1963
|
-
log({ level: 'info', output: { ...result } })
|
|
1964
|
-
resolve(result)
|
|
1965
|
-
} else if (data.length === 0) {
|
|
1966
|
-
reject(new Error('record not found'))
|
|
1967
|
-
} else {
|
|
1968
|
-
reject(new Error('more than one is found'))
|
|
1969
|
-
}
|
|
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
|
|
1970
2243
|
})
|
|
2244
|
+
if (found) {
|
|
2245
|
+
found.value = (found.value || []).concat(from.value)
|
|
2246
|
+
} else {
|
|
2247
|
+
toArr.push(from)
|
|
2248
|
+
}
|
|
1971
2249
|
})
|
|
1972
|
-
|
|
1973
|
-
log({ level: 'warn', output: err.toString() })
|
|
1974
|
-
throw err
|
|
1975
|
-
})
|
|
2250
|
+
return toArr
|
|
1976
2251
|
}
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
systemLog,
|
|
1982
|
-
label: 'REPO_WRITE',
|
|
1983
|
-
message: `fn ${this._classname}.prototype.saveAll`,
|
|
1984
|
-
input: [{ docs: [...docs], systemLog: { ...systemLog } }]
|
|
1985
|
-
})
|
|
1986
|
-
const promise = typeof this.model.saveAll === 'function'
|
|
1987
|
-
? this.model.saveAll({ docs })
|
|
1988
|
-
: Promise.all(docs.map(async (doc) => {
|
|
1989
|
-
if (doc) {
|
|
1990
|
-
const result = await this.saveOne({ doc })
|
|
1991
|
-
isNew = result.isNew
|
|
1992
|
-
const _data = result._data || result.data
|
|
1993
|
-
return _data[0]
|
|
1994
|
-
}
|
|
1995
|
-
return null
|
|
1996
|
-
}))
|
|
1997
|
-
return promise.then((savedData) => {
|
|
1998
|
-
if (savedData.length !== 1) isNew = null
|
|
1999
|
-
const result = {
|
|
2000
|
-
data: savedData,
|
|
2001
|
-
isNew,
|
|
2002
|
-
total: savedData.length
|
|
2252
|
+
static removeByKey(arr, key) {
|
|
2253
|
+
return arr.reduce((acc, item) => {
|
|
2254
|
+
if (!this.sameKey(item, key)) {
|
|
2255
|
+
acc.push(item)
|
|
2003
2256
|
}
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
}).catch((err) => {
|
|
2007
|
-
log({ level: 'warn', output: err.toString() })
|
|
2008
|
-
throw err
|
|
2009
|
-
})
|
|
2257
|
+
return acc
|
|
2258
|
+
}, [])
|
|
2010
2259
|
}
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
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
|
|
2027
2287
|
}
|
|
2028
|
-
}
|
|
2288
|
+
}
|
|
2289
|
+
return item
|
|
2029
2290
|
})
|
|
2030
2291
|
}
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
if (
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
data: {
|
|
2042
|
-
payload: {
|
|
2043
|
-
input,
|
|
2044
|
-
output
|
|
2045
|
-
}
|
|
2046
|
-
}
|
|
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
|
|
2047
2302
|
})
|
|
2048
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 []
|
|
2049
2314
|
}
|
|
2050
|
-
}
|
|
2051
|
-
|
|
2052
2315
|
|
|
2316
|
+
// getters
|
|
2317
|
+
get isValid() {
|
|
2318
|
+
return !!this.key
|
|
2319
|
+
}
|
|
2053
2320
|
|
|
2054
|
-
|
|
2321
|
+
get toObject() {
|
|
2322
|
+
const obj = {}
|
|
2323
|
+
if (this.isValid) {
|
|
2324
|
+
obj[this.key] = this.value
|
|
2325
|
+
}
|
|
2326
|
+
return obj
|
|
2327
|
+
}
|
|
2328
|
+
}
|
|
2055
2329
|
|
|
2330
|
+
function _isSame(key1, key2) {
|
|
2331
|
+
return key1 === key2
|
|
2332
|
+
}
|
|
2056
2333
|
|
|
2057
2334
|
|
|
2058
2335
|
|
|
2059
|
-
;// ./lib/models/
|
|
2336
|
+
;// ./lib/models/keyValueObject/index.js
|
|
2060
2337
|
|
|
2061
2338
|
|
|
2062
2339
|
|
|
2063
|
-
class Service {
|
|
2064
|
-
constructor({ repo }) {
|
|
2065
|
-
this.repo = repo
|
|
2066
|
-
}
|
|
2067
2340
|
|
|
2068
|
-
|
|
2069
|
-
return 'Service'
|
|
2070
|
-
}
|
|
2071
|
-
static get _superclass() {
|
|
2072
|
-
return 'Service'
|
|
2073
|
-
}
|
|
2341
|
+
;// ./lib/models/metadata/metadata.js
|
|
2074
2342
|
|
|
2075
|
-
deleteOne({ id }) {
|
|
2076
|
-
return this.repo.deleteOne({ id })
|
|
2077
|
-
.catch(() => {
|
|
2078
|
-
throw new Error(`Not found for query: ${id}`)
|
|
2079
|
-
})
|
|
2080
|
-
}
|
|
2081
2343
|
|
|
2082
|
-
async findAll({ query = {}, systemLog } = {}) {
|
|
2083
|
-
const result = await this.repo.findAll({ query, systemLog })
|
|
2084
|
-
return makeApiResponse({
|
|
2085
|
-
repo: this.repo,
|
|
2086
|
-
result
|
|
2087
|
-
})
|
|
2088
|
-
}
|
|
2089
2344
|
|
|
2090
|
-
|
|
2091
|
-
const result = await this.repo.findOne({ query, systemLog })
|
|
2092
|
-
return makeApiResponse({
|
|
2093
|
-
repo: this.repo,
|
|
2094
|
-
result
|
|
2095
|
-
})
|
|
2096
|
-
}
|
|
2345
|
+
const DELIMITER = '_'
|
|
2097
2346
|
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
if (Array.isArray(arr)) {
|
|
2103
|
-
return arr.map((a) => this.init(a))
|
|
2347
|
+
class Metadata extends KeyValueObject {
|
|
2348
|
+
static init(options = {}) {
|
|
2349
|
+
if (options instanceof this) {
|
|
2350
|
+
return options
|
|
2104
2351
|
}
|
|
2105
|
-
|
|
2352
|
+
const instance = new this({
|
|
2353
|
+
...options,
|
|
2354
|
+
key: stringFormatter(options.key, DELIMITER),
|
|
2355
|
+
})
|
|
2356
|
+
return instance.isValid ? instance : null
|
|
2106
2357
|
}
|
|
2107
|
-
|
|
2108
|
-
return
|
|
2358
|
+
static get _classname() {
|
|
2359
|
+
return 'Metadata'
|
|
2109
2360
|
}
|
|
2110
2361
|
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
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
|
+
}
|
|
2119
2372
|
})
|
|
2373
|
+
return toArr
|
|
2120
2374
|
}
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
const copy = this.init(doc)
|
|
2124
|
-
if (copy) {
|
|
2125
|
-
const result = await this.repo.saveOne({ doc: copy, systemLog })
|
|
2126
|
-
return makeApiResponse({
|
|
2127
|
-
repo: this.repo,
|
|
2128
|
-
result
|
|
2129
|
-
})
|
|
2130
|
-
}
|
|
2131
|
-
return {
|
|
2132
|
-
isNew: null,
|
|
2133
|
-
data: [],
|
|
2134
|
-
err: new Error('doc is not a valid instance')
|
|
2135
|
-
}
|
|
2375
|
+
static sameKey(item, key) {
|
|
2376
|
+
return metadata_isSame(item.key, key)
|
|
2136
2377
|
}
|
|
2137
2378
|
}
|
|
2138
2379
|
|
|
2139
|
-
function
|
|
2140
|
-
|
|
2141
|
-
throw new Error('repo is required.')
|
|
2142
|
-
}
|
|
2143
|
-
if (repo._superclass !== Repo._superclass) {
|
|
2144
|
-
throw new Error('repo is not an instance of Repo.')
|
|
2145
|
-
}
|
|
2146
|
-
return new Service({ repo })
|
|
2380
|
+
function metadata_isSame(key1, key2) {
|
|
2381
|
+
return stringFormatter(key1, DELIMITER) === stringFormatter(key2, DELIMITER)
|
|
2147
2382
|
}
|
|
2148
2383
|
|
|
2149
2384
|
|
|
2150
2385
|
|
|
2151
|
-
;// ./lib/models/
|
|
2386
|
+
;// ./lib/models/metadata/index.js
|
|
2152
2387
|
|
|
2153
2388
|
|
|
2154
2389
|
|
|
2155
2390
|
|
|
2156
|
-
;// ./lib/models/
|
|
2391
|
+
;// ./lib/models/qMeta/qMeta.js
|
|
2157
2392
|
|
|
2158
2393
|
|
|
2159
|
-
|
|
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
|
+
|
|
2160
2406
|
static get _classname() {
|
|
2161
|
-
return '
|
|
2407
|
+
return 'QMeta'
|
|
2162
2408
|
}
|
|
2163
2409
|
static get _superclass() {
|
|
2164
|
-
return '
|
|
2410
|
+
return 'QMeta'
|
|
2165
2411
|
}
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
return _makeSetCode(fieldName, options)
|
|
2412
|
+
|
|
2413
|
+
// Class methods
|
|
2414
|
+
static init(options = {}) {
|
|
2415
|
+
if (options instanceof QMeta) {
|
|
2416
|
+
return options
|
|
2172
2417
|
}
|
|
2418
|
+
return new QMeta(options)
|
|
2173
2419
|
}
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
}, obj)
|
|
2181
|
-
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')
|
|
2182
2426
|
}
|
|
2427
|
+
this.attributes.push(kvObject)
|
|
2428
|
+
return this
|
|
2183
2429
|
}
|
|
2184
|
-
}
|
|
2185
2430
|
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
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
|
|
2194
2442
|
}
|
|
2195
2443
|
}
|
|
2196
2444
|
|
|
2197
2445
|
|
|
2198
2446
|
|
|
2199
|
-
;// ./lib/models/
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
;// ./lib/models/index.js
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2447
|
+
;// ./lib/models/qMeta/index.js
|
|
2209
2448
|
|
|
2210
2449
|
|
|
2211
2450
|
|
|
2212
2451
|
|
|
2452
|
+
;// ./lib/models/repo/index.js
|
|
2213
2453
|
|
|
2214
|
-
;// ./lib/helpers/generalPost/generalPost.js
|
|
2215
2454
|
|
|
2216
2455
|
|
|
2217
2456
|
|
|
2457
|
+
;// ./lib/models/service/index.js
|
|
2218
2458
|
|
|
2219
|
-
async function generalPost({ body = {}, GeneralModel, UniqueKeyGenerator, resourceInfo }) {
|
|
2220
|
-
const { resources, data, globalShared = {}, shared = {}, relationship = {} } = body
|
|
2221
|
-
const _resourceInfo = resourceInfo || body.resourceInfo
|
|
2222
|
-
_attachShared(data, globalShared, shared)
|
|
2223
|
-
const obj = await pReduce(resources, async (acc, resource) => {
|
|
2224
|
-
const service = _makeService(resource, _resourceInfo, UniqueKeyGenerator, GeneralModel)
|
|
2225
|
-
_createRelationship(data, relationship[resource], acc)
|
|
2226
|
-
const _data = data[resource]
|
|
2227
|
-
const result = await service.saveAll({ docs: [].concat(_data) })
|
|
2228
|
-
acc[resource] = Array.isArray(_data) ? result._data : result._data[0]
|
|
2229
|
-
return acc
|
|
2230
|
-
}, {})
|
|
2231
|
-
return obj
|
|
2232
|
-
}
|
|
2233
2459
|
|
|
2234
|
-
function _attachShared(data, globalShared = {}, shared = {}) {
|
|
2235
|
-
Object.keys(shared).forEach((key) => {
|
|
2236
|
-
const _data = data[key]
|
|
2237
|
-
data[key] = objectHelper.merge({}, _data, globalShared, shared[key] || {})
|
|
2238
|
-
})
|
|
2239
|
-
}
|
|
2240
2460
|
|
|
2241
|
-
function _createRelationship(data, relationship = {}, object) {
|
|
2242
|
-
Object.keys(relationship).forEach((key) => {
|
|
2243
|
-
const path = relationship[key]
|
|
2244
|
-
const val = objectHelper.get(object, path)
|
|
2245
|
-
objectHelper.set(data, key, val)
|
|
2246
|
-
})
|
|
2247
|
-
}
|
|
2248
2461
|
|
|
2249
|
-
|
|
2250
|
-
const { collectionName, fields } = resourceInfo[resource]
|
|
2251
|
-
const uniqueKeyGenerator = UniqueKeyGenerator.makeGenerator(fields)
|
|
2252
|
-
const model = new GeneralModel({ collectionName, uniqueKeyGenerator })
|
|
2253
|
-
return makeService({
|
|
2254
|
-
repo: new Repo({ model })
|
|
2255
|
-
})
|
|
2256
|
-
}
|
|
2462
|
+
;// ./lib/models/trackedEntity/trackedEntity.js
|
|
2257
2463
|
|
|
2258
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
|
+
}
|
|
2259
2476
|
|
|
2260
|
-
|
|
2477
|
+
if (trackFlat) {
|
|
2478
|
+
Object.assign(this, _tracking)
|
|
2479
|
+
} else {
|
|
2480
|
+
this.meta = { ..._tracking, ...options.meta }
|
|
2481
|
+
}
|
|
2482
|
+
}
|
|
2261
2483
|
|
|
2484
|
+
// Class methods
|
|
2485
|
+
static get _classname() {
|
|
2486
|
+
return 'TrackedEntity'
|
|
2487
|
+
}
|
|
2488
|
+
static get _superclass() {
|
|
2489
|
+
return 'TrackedEntity'
|
|
2490
|
+
}
|
|
2262
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
|
+
}
|
|
2263
2505
|
|
|
2506
|
+
// getters
|
|
2507
|
+
get isValid() {
|
|
2508
|
+
return !!this
|
|
2509
|
+
}
|
|
2264
2510
|
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2511
|
+
setModified() {
|
|
2512
|
+
const timestamp = Date.now()
|
|
2513
|
+
if (this.meta) {
|
|
2514
|
+
this.meta.modified = timestamp
|
|
2515
|
+
} else {
|
|
2516
|
+
this.modified = timestamp
|
|
2517
|
+
}
|
|
2270
2518
|
}
|
|
2271
|
-
return num
|
|
2272
2519
|
}
|
|
2273
2520
|
|
|
2521
|
+
;// ./lib/models/trackedEntity/index.js
|
|
2274
2522
|
|
|
2523
|
+
// Explicit named export (optional)
|
|
2275
2524
|
|
|
2276
|
-
;// ./lib/
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
;// ./lib/helpers/pReduce/index.js
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
;// ./lib/helpers/stringFormatter/index.js
|
|
2525
|
+
;// ./lib/models/tenantAwareEntity/tenantAwareEntity.js
|
|
2287
2526
|
|
|
2288
2527
|
|
|
2528
|
+
class TenantAwareEntity extends TrackedEntity {
|
|
2529
|
+
constructor(options = {}) {
|
|
2530
|
+
options = options || {}
|
|
2289
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
|
+
// }
|
|
2290
2538
|
|
|
2291
|
-
|
|
2292
|
-
function baseXEncode(num, base = 34) {
|
|
2293
|
-
const charset = getBaseCharset(base)
|
|
2294
|
-
return encode(num, charset)
|
|
2295
|
-
}
|
|
2539
|
+
super(options)
|
|
2296
2540
|
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
if (int === 0) {
|
|
2300
|
-
return byCode[0];
|
|
2541
|
+
this._tenant = options._tenant
|
|
2542
|
+
this.tenantCode = options.tenantCode // Required for multi-tenancy
|
|
2301
2543
|
}
|
|
2302
2544
|
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
res = byCode[int % max] + res;
|
|
2307
|
-
int = Math.floor(int / max);
|
|
2545
|
+
// Class methods
|
|
2546
|
+
static get _classname() {
|
|
2547
|
+
return 'TenantAwareEntity'
|
|
2308
2548
|
}
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
function getBaseCharset(base) {
|
|
2313
|
-
let charset = '9876543210ABCDEFGHJKLMNPQRSTUVWXYZ'
|
|
2314
|
-
if (base === 58) {
|
|
2315
|
-
charset = '9876543210ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz'
|
|
2549
|
+
static get _superclass() {
|
|
2550
|
+
return 'TenantAwareEntity'
|
|
2316
2551
|
}
|
|
2317
|
-
return indexCharset(charset)
|
|
2318
|
-
}
|
|
2319
2552
|
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
length = str.length,
|
|
2324
|
-
i, char;
|
|
2325
|
-
for (i = 0; i < length; i++) {
|
|
2326
|
-
char = str[i];
|
|
2327
|
-
byCode[i] = char;
|
|
2328
|
-
byChar[char] = i;
|
|
2553
|
+
// getters
|
|
2554
|
+
get isValid() {
|
|
2555
|
+
return super.isValid && !!this.tenantCode // Required for multi-tenancy
|
|
2329
2556
|
}
|
|
2330
|
-
return { byCode: byCode, byChar: byChar, length: length };
|
|
2331
2557
|
}
|
|
2332
2558
|
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
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'
|
|
2341
2569
|
}
|
|
2342
|
-
|
|
2343
|
-
|
|
2570
|
+
static get _superclass() {
|
|
2571
|
+
return 'UniqueKeyGenerator'
|
|
2344
2572
|
}
|
|
2345
|
-
|
|
2346
|
-
|
|
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
|
+
}
|
|
2347
2580
|
}
|
|
2348
|
-
|
|
2349
|
-
|
|
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
|
+
}
|
|
2350
2590
|
}
|
|
2351
|
-
const chars = [...str]
|
|
2352
|
-
return [...Array(len)].map(i => {
|
|
2353
|
-
return chars[(Math.random() * chars.length) | 0]
|
|
2354
|
-
}).join``
|
|
2355
2591
|
}
|
|
2356
2592
|
|
|
2357
|
-
function
|
|
2358
|
-
|
|
2359
|
-
|
|
2593
|
+
function _makeSetCode(fieldName, options) {
|
|
2594
|
+
return async (obj = {}) => {
|
|
2595
|
+
if (obj[fieldName]) {
|
|
2596
|
+
return {}
|
|
2597
|
+
}
|
|
2598
|
+
return {
|
|
2599
|
+
[fieldName]: stringHelper.setCode()
|
|
2600
|
+
}
|
|
2360
2601
|
}
|
|
2361
|
-
const splitString = str.split('')
|
|
2362
|
-
const reverseArray = splitString.reverse()
|
|
2363
|
-
return reverseArray.join('')
|
|
2364
|
-
}
|
|
2365
|
-
|
|
2366
|
-
function setCode(base = 34) {
|
|
2367
|
-
const now = (new Date()).valueOf()
|
|
2368
|
-
const random = randomString({
|
|
2369
|
-
len: 8,
|
|
2370
|
-
pattern: '1'
|
|
2371
|
-
})
|
|
2372
|
-
const str = reverse(`${now}${random}`)
|
|
2373
|
-
// const str = `${now}${random}`
|
|
2374
|
-
return baseXEncode(str, base)
|
|
2375
2602
|
}
|
|
2376
2603
|
|
|
2377
|
-
const stringHelper = {
|
|
2378
|
-
setCode
|
|
2379
|
-
}
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
;// ./lib/helpers/stringHelper/index.js
|
|
2383
2604
|
|
|
2384
2605
|
|
|
2606
|
+
;// ./lib/models/uniqueKeyGenerator/index.js
|
|
2385
2607
|
|
|
2386
2608
|
|
|
2387
2609
|
|
|
2388
|
-
;// ./lib/helpers/index.js
|
|
2389
2610
|
|
|
2611
|
+
;// ./lib/models/index.js
|
|
2390
2612
|
|
|
2391
2613
|
|
|
2392
2614
|
|