@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.
@@ -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 */ getValueByKeys),
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 getValueByKeys(keys, data) {
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 getValueByKeys(_keys, _data[firstKey])
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 getValueByKeys_getValueByKeys = ({
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
- 'get', 'map', 'join', 'concatIf', 'exec', 'filterOne', 'filterAll', 'formatDate', 'eq', 'neq', 'gt', 'lt', 'gte', 'lte', 'isEmpty', 'isNotEmpty', 'toLowerCase', 'toUpperCase'
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 getValueByKeys(arg.split('.'), e)
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('.') ? getValueByKeys(key.split('.'), e) : e[key]
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, getValueByKeys)) {
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, getValueByKeys)) {
1229
- const _value = getValueByKeys(value.split('.'), data) || ''
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, getValueByKeys)) {
1236
- const _value = getValueByKeys(value.split('.'), data) || []
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, getValueByKeys)) {
1293
+ if (getValidation(restriction, data, getValueByKeys_getValueByKeys)) {
1245
1294
  const { maxLength } = item
1246
- const _value = getValueByKeys(value.split('.'), data) || ''
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, getValueByKeys)) {
1257
- const _value = getValueByKeys(value.split('.'), data) || ''
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, getValueByKeys)) {
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 || typeof getValueByKeys !== 'function') {
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 = getValueByKeys({ keys: key.split('.'), obj: value })
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/apiResponse/apiResponse.js
1441
- class ApiResponse {
1442
- constructor(options = {}) {
1492
+ ;// ./lib/models/repo/repo.js
1493
+ class Repo {
1494
+ constructor(options) {
1443
1495
  options = options || {}
1444
- this._data = options.data || options._data || []
1445
- this.err = options.err
1446
- this.isNew = options.isNew || false
1447
- this.message = options.message
1448
- this.total = options.total || 0
1449
- this._instanceBuilder = options._instanceBuilder
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 'ApiResponse'
1512
+ return 'Repo'
1461
1513
  }
1462
1514
  static get _superclass() {
1463
- return 'ApiResponse'
1515
+ return 'Repo'
1464
1516
  }
1465
1517
 
1466
- // getters
1467
- get data() {
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
- ;// ./lib/models/apiResponse/makeApiResponse.js
1478
-
1479
-
1480
- function makeApiResponse({ repo, result }) {
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
- // Class methods
1506
- static init(options = {}) {
1507
- if (options instanceof this) {
1508
- return options
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
- static initFromArray(arr = []) {
1514
- if (Array.isArray(arr)) {
1515
- return arr.map((a) => this.init(a))
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
- static addItem(arr, key, value) {
1530
- arr.push(this.init({ key, value }))
1531
- }
1532
- static addRecord(arr = [], key, value) {
1533
- if (!this.hasKeyValue(arr, key, value)) {
1534
- arr.push(this.init({ key, value }))
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
- static appendRecord(arr = [], key, value) {
1539
- return arr.map((item) => {
1540
- if (this.sameKey(item, key)) {
1541
- item.value = [...item.value, ...value]
1542
- }
1543
- return item
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
- static appendValueArray(arr = [], key, value) {
1547
- return arr.map((item) => {
1548
- if (this.sameKey(item, key)) {
1549
- item.value = [...item.value, ...value]
1550
- }
1551
- return item
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
- static foundByKey(arr = [], key) {
1555
- const found = arr.find((m) => {
1556
- return this.sameKey(m, key)
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 found || null
1559
- }
1560
- static foundValueByKey(arr = [], key) {
1561
- const found = this.foundByKey(arr, key)
1562
- return found ? found.value : null
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
- static fromObject(options = {}) {
1565
- return Object.keys(options).reduce((acc, key) => {
1566
- acc.push(this.init({ key, value: options[key] }))
1567
- return acc
1568
- }, [])
1569
- }
1570
- static getValueByKey(arr = [], key) {
1571
- return this.foundValueByKey(arr, key)
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
- static getValueByKeyFromArray(arr = [], key) {
1574
- if (arr.length === 0) {
1575
- return null
1576
- }
1577
- const firstArr = arr.shift()
1578
- const found = firstArr.find((i) => {
1579
- return this.sameKey(i, key)
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
- if (found && found.value) {
1582
- return found.value
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
- static getValuesByKey(arr = [], key) {
1587
- return arr.reduce((acc, item) => {
1588
- if (this.sameKey(item, key)) {
1589
- acc.push(item.value)
1590
- }
1591
- return acc
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
- static hasKeyValue(arr = [], key, value) {
1595
- if (typeof value === 'undefined') {
1596
- return arr.filter((item) => this.sameKey(item, key)).length > 0
1712
+
1713
+ static init(options = {}) {
1714
+ if (options instanceof this) {
1715
+ return options
1597
1716
  }
1598
- return arr.filter((item) => (this.sameKey(item, key) && _isSame(item.value, value))).length > 0
1717
+ const instance = new this(options)
1718
+ return instance
1599
1719
  }
1600
- static insertOrUpdateRecord(arr = [], key, value) {
1601
- let copy = [...arr]
1602
- if (!this.hasKeyValue(arr, key)) {
1603
- copy.push(this.init({ key, value }))
1604
- } else {
1605
- copy = this.updateRecord(arr, key, value)
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 copy
1732
+ return this._data
1608
1733
  }
1609
- static keys(arr = []) {
1610
- if (Array.isArray(arr)) {
1611
- return arr.reduce((acc, item) => {
1612
- acc.push(item.key)
1613
- return acc
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
- return []
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
- static merge(toArr, fromArr) {
1619
- (fromArr || []).map((from) => {
1620
- const found = toArr.find((to) => {
1621
- return to.key === from.key
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
- if (found) {
1624
- found.value = (found.value || []).concat(from.value)
1625
- } else {
1626
- toArr.push(from)
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
- static removeByKey(arr, key) {
1632
- return arr.reduce((acc, item) => {
1633
- if (!this.sameKey(item, key)) {
1634
- acc.push(item)
1635
- }
1636
- return acc
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
- static sameKey(item, key) {
1640
- return _isSame(item.key, key)
1790
+
1791
+ init(options) {
1792
+ return this.repo.init(options)
1641
1793
  }
1642
- static toObject(arr = []) {
1794
+ initFromArray(arr = []) {
1643
1795
  if (Array.isArray(arr)) {
1644
- return arr.reduce((acc, item) => {
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
- static toString(arr = [], delimiter = '; ') {
1652
- if (Array.isArray(arr)) {
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
- static updateRecord(arr = [], key, value) {
1661
- return arr.map((item) => {
1662
- if (this.sameKey(item, key)) {
1663
- return {
1664
- ...item,
1665
- value
1666
- }
1667
- }
1668
- return item
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
- static updateOrInsertRecord(arr = [], key, value) {
1672
- return this.insertOrUpdateRecord(arr, key, value)
1673
- }
1674
- static updateRecordsFromArray(arr = [], updateArr = []) {
1675
- if (Array.isArray(arr) && Array.isArray(updateArr)) {
1676
- const obj1 = this.toObject(arr)
1677
- const obj2 = this.toObject(updateArr)
1678
- return this.fromObject({
1679
- ...obj1,
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
- static values(arr = []) {
1686
- if (Array.isArray(arr)) {
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
- // getters
1696
- get isValid() {
1697
- return !!this.key
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
- get toObject() {
1701
- const obj = {}
1702
- if (this.isValid) {
1703
- obj[this.key] = this.value
1704
- }
1705
- return obj
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
- function _isSame(key1, key2) {
1710
- return key1 === key2
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/models/keyValueObject/index.js
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/models/metadata/metadata.js
1972
+ ;// ./lib/helpers/stringFormatter/index.js
1735
1973
 
1736
1974
 
1737
1975
 
1738
- const DELIMITER = '_'
1739
1976
 
1740
- class Metadata extends KeyValueObject {
1741
- static init(options = {}) {
1742
- if (options instanceof this) {
1743
- return options
1744
- }
1745
- const instance = new this({
1746
- ...options,
1747
- key: stringFormatter(options.key, DELIMITER),
1748
- })
1749
- return instance.isValid ? instance : null
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
- static get _classname() {
1752
- return 'Metadata'
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
- static merge(toArr, fromArr) {
1756
- (fromArr || []).map((from) => {
1757
- const found = toArr.find((to) => {
1758
- return metadata_isSame(to.key, from.key)
1759
- })
1760
- if (found) {
1761
- found.value = (found.value || []).concat(from.value)
1762
- } else {
1763
- toArr.push(from)
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
- return toArr
1767
- }
1768
- static sameKey(item, key) {
1769
- return metadata_isSame(item.key, key)
1770
- }
2080
+ .join('')
1771
2081
  }
1772
2082
 
1773
- function metadata_isSame(key1, key2) {
1774
- return stringFormatter(key1, DELIMITER) === stringFormatter(key2, DELIMITER)
2083
+ const stringHelper = {
2084
+ isSame,
2085
+ setCode,
2086
+ toCamelCase,
1775
2087
  }
1776
2088
 
1777
2089
 
1778
2090
 
1779
- ;// ./lib/models/metadata/index.js
2091
+ ;// ./lib/helpers/stringHelper/index.js
1780
2092
 
1781
2093
 
1782
2094
 
1783
2095
 
1784
- ;// ./lib/models/qMeta/qMeta.js
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
- ;// ./lib/models/repo/repo.js
1846
- class Repo {
1847
- constructor(options) {
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.model = options.model
1850
- this._sharedOptions = options._sharedOptions // { session: this.dbTransaction }
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 'Repo'
2144
+ return 'KeyValueObject'
1866
2145
  }
1867
2146
  static get _superclass() {
1868
- return 'Repo'
2147
+ return 'KeyValueObject'
1869
2148
  }
1870
2149
 
1871
- get _classname() {
1872
- return 'Repo'
2150
+ static addItem(arr, key, value) {
2151
+ arr.push(this.init({ key, value }))
1873
2152
  }
1874
-
1875
- get _superclass() {
1876
- return 'Repo'
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
- get isValid() {
1880
- return this.model
1881
- && (typeof this.model.deleteOne === 'function')
1882
- && (typeof this.model.findAll === 'function')
1883
- && (typeof this.model.saveOne === 'function')
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
- get queryOptions() {
1887
- return {
1888
- ...this._sharedOptions,
1889
- ...this._queryOptions,
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
- get saveOptions() {
1894
- return {
1895
- ...this._sharedOptions,
1896
- ...this._saveOptions,
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
- init(options) {
1901
- if (this._Class && typeof this._Class.init === 'function') {
1902
- return this._Class.init(options)
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
- return options
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
- async deleteOne({ id }) {
1908
- try {
1909
- const result = await this.model.deleteOne({ _id: id })
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
- } catch (err) {
1916
- throw err
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
- // systemLog is optional
1921
- findAll({ query, systemLog }) {
1922
- const log = _makeLog({
1923
- systemLog,
1924
- label: 'REPO_READ',
1925
- message: `fn ${this._classname}.prototype.findAll`,
1926
- input: [{ query: { ...query }, systemLog: { ...systemLog } }]
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
- findOne({ query, systemLog }) {
1947
- const log = _makeLog({
1948
- systemLog,
1949
- label: 'REPO_READ',
1950
- message: `fn ${this._classname}.prototype.findOne`,
1951
- input: [{ query: { ...query }, systemLog: { ...systemLog } }]
1952
- })
1953
- return new Promise((resolve, reject) => {
1954
- this.model.findAll(query, this.queryOptions, (err, data) => {
1955
- if (err) {
1956
- reject(err)
1957
- } else if (data.length === 1) {
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
- .catch((err) => {
1973
- log({ level: 'warn', output: err.toString() })
1974
- throw err
1975
- })
2250
+ return toArr
1976
2251
  }
1977
-
1978
- saveAll({ docs, systemLog }) {
1979
- let isNew
1980
- const log = _makeLog({
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
- log({ level: 'info', output: { ...result } })
2005
- return result
2006
- }).catch((err) => {
2007
- log({ level: 'warn', output: err.toString() })
2008
- throw err
2009
- })
2257
+ return acc
2258
+ }, [])
2010
2259
  }
2011
-
2012
- saveOne({ doc, systemLog }) {
2013
- const log = _makeLog({
2014
- systemLog,
2015
- label: 'REPO_WRITE',
2016
- message: `fn ${this._classname}.prototype.saveOne`,
2017
- input: [{ doc: { ...doc }, systemLog: { ...systemLog } }]
2018
- })
2019
- return new Promise((resolve, reject) => {
2020
- this.model.saveOne(doc, this.saveOptions, (err, result) => {
2021
- if (err) {
2022
- log({ level: 'warn', output: err.toString() })
2023
- reject(err)
2024
- } else {
2025
- log({ level: 'info', output: { ...result } })
2026
- resolve(result)
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
- function _makeLog({ systemLog, label, message: message1, input } = {}) {
2034
- return ({ level, messgae: massage2, output } = {}) => {
2035
- if (systemLog && systemLog.systemLogHelper) {
2036
- systemLog.systemLogHelper.log({
2037
- batchId: systemLog.batchId,
2038
- label,
2039
- level,
2040
- message: massage2 || message1,
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
- ;// ./lib/models/repo/index.js
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/service/service.js
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
- static get _classname() {
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
- async findOne({ query = {}, systemLog } = {}) {
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
- init(options) {
2099
- return this.repo.init(options)
2100
- }
2101
- initFromArray(arr = []) {
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
- return []
2352
+ const instance = new this({
2353
+ ...options,
2354
+ key: stringFormatter(options.key, DELIMITER),
2355
+ })
2356
+ return instance.isValid ? instance : null
2106
2357
  }
2107
- initOnlyValidFromArray(arr = []) {
2108
- return this.initFromArray(arr).filter((i) => i)
2358
+ static get _classname() {
2359
+ return 'Metadata'
2109
2360
  }
2110
2361
 
2111
- async saveAll({ docs = [], systemLog } = {}) {
2112
- const copies = docs.map((doc) => {
2113
- return this.init(doc)
2114
- })
2115
- const result = await this.repo.saveAll({ docs: copies, systemLog })
2116
- return makeApiResponse({
2117
- repo: this.repo,
2118
- result
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
- async saveOne({ doc = {}, systemLog } = {}) {
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 makeService({ repo }) {
2140
- if (repo === undefined) {
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/service/index.js
2386
+ ;// ./lib/models/metadata/index.js
2152
2387
 
2153
2388
 
2154
2389
 
2155
2390
 
2156
- ;// ./lib/models/uniqueKeyGenerator/uniqueKeyGenerator.js
2391
+ ;// ./lib/models/qMeta/qMeta.js
2157
2392
 
2158
2393
 
2159
- class UniqueKeyGenerator {
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 'UniqueKeyGenerator'
2407
+ return 'QMeta'
2162
2408
  }
2163
2409
  static get _superclass() {
2164
- return 'UniqueKeyGenerator'
2410
+ return 'QMeta'
2165
2411
  }
2166
- static makeFormatter({ fieldName, format, options }) {
2167
- switch (format) {
2168
- case 'set_code':
2169
- return _makeSetCode(fieldName, options)
2170
- default:
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
- static makeGenerator(arr) {
2175
- const fns = arr.map((item) => this.makeFormatter(item))
2176
- return async (obj) => {
2177
- const output = await pReduce(fns, async (acc, fn) => {
2178
- const _obj = await fn(obj)
2179
- return Object.assign(acc, _obj)
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
- function _makeSetCode(fieldName, options) {
2187
- return async (obj = {}) => {
2188
- if (obj[fieldName]) {
2189
- return {}
2190
- }
2191
- return {
2192
- [fieldName]: stringHelper.setCode()
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/uniqueKeyGenerator/index.js
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
- function _makeService(resource, resourceInfo, UniqueKeyGenerator, GeneralModel) {
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
- ;// ./lib/helpers/generalPost/index.js
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
- ;// ./lib/helpers/padZeros/padZeros.js
2266
- function padZeros(num, minLength = 6) {
2267
- num = num.toString()
2268
- if (num.length < minLength) {
2269
- return padZeros('0' + num, minLength)
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/helpers/padZeros/index.js
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
- ;// ./lib/helpers/stringHelper/stringHelper.js
2292
- function baseXEncode(num, base = 34) {
2293
- const charset = getBaseCharset(base)
2294
- return encode(num, charset)
2295
- }
2539
+ super(options)
2296
2540
 
2297
- function encode(int, charset) {
2298
- let byCode = charset.byCode;
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
- var res = "",
2304
- max = charset.length;
2305
- while (int > 0) {
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
- return res;
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
- function indexCharset(str) {
2321
- var byCode = {},
2322
- byChar = {},
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
- function randomString({ len = 16, pattern = 'a1' } = {}) {
2334
- const A = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
2335
- const a = 'abcdefghijklmnopqrstuvwxyz'
2336
- const num = '1234567890'
2337
- const mark = '~!@#$%^&*_+-='
2338
- let str = ''
2339
- if (pattern.includes('A')) {
2340
- str += A
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
- if (pattern.includes('a')) {
2343
- str += a
2570
+ static get _superclass() {
2571
+ return 'UniqueKeyGenerator'
2344
2572
  }
2345
- if (pattern.includes('1')) {
2346
- str += num
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
- if (pattern.includes('#')) {
2349
- str += mark
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 reverse(str) {
2358
- if (typeof str !== 'string') {
2359
- str = str.toString()
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