@questwork/q-utilities 0.1.10 → 0.1.11

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.
Files changed (3) hide show
  1. package/dist/index.min.cjs +1591 -1508
  2. package/dist/index.min.js +1593 -1509
  3. package/package.json +1 -1
package/dist/index.min.js CHANGED
@@ -32,6 +32,7 @@ __webpack_require__.d(__webpack_exports__, {
32
32
  kl: () => (/* reexport */ Service),
33
33
  Mg: () => (/* reexport */ TemplateCompiler),
34
34
  _x: () => (/* reexport */ UniqueKeyGenerator),
35
+ yl: () => (/* reexport */ concatStringByArray),
35
36
  l0: () => (/* reexport */ convertString),
36
37
  Yq: () => (/* reexport */ formatDate),
37
38
  zn: () => (/* reexport */ generalPost),
@@ -46,86 +47,12 @@ __webpack_require__.d(__webpack_exports__, {
46
47
  yO: () => (/* reexport */ stringHelper)
47
48
  });
48
49
 
49
- ;// ./lib/helpers/convertString/convertString.js
50
- function convertString(string, patternMatch = /\$\{(.+?)\}/g, value, getValueByKeys) {
51
- if (!string || typeof getValueByKeys !== 'function') {
52
- return ''
53
- }
54
- const reg = new RegExp(patternMatch, 'g')
55
- return string.replace(reg, (match, key) => {
56
- const result = getValueByKeys({ keys: key.split('.'), obj: value })
57
- if (result === null || result === undefined) {
58
- return ''
59
- }
60
- return typeof result === 'object' ? JSON.stringify(result) : result
61
- })
62
- }
63
-
64
- /* harmony default export */ const convertString_convertString = ({
65
- convertString
66
- });
67
-
68
-
69
- ;// ./lib/helpers/convertString/index.js
70
-
71
-
72
- ;// ./lib/helpers/formatDate/formatDate.js
73
-
74
- function formatDate(date, format) {
75
- const _date = date && date instanceof Date ? date : new Date(date)
76
- const dayMapChi = ['日','一','二','三','四','五','六']
77
- const dayMapEng = ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday']
78
- const dayMapEngShort = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat']
79
- const _format = format || 'YYYY/MM/DD hh:mm'
80
- const e = _date.getDay()
81
- const ee = dayMapEngShort[e]
82
- const eee = dayMapChi[e]
83
- const eeee = dayMapEng[e]
84
- const y = _date.getFullYear()
85
- const m = _date.getMonth() + 1
86
- const d = _date.getDate()
87
- const h = _date.getHours()
88
- const mm = _date.getMinutes()
89
- const s = _date.getSeconds()
90
-
91
- return _format.replace('YYYY', y)
92
- .replace('MM', padding(m))
93
- .replace('MM', padding(m))
94
- .replace('DD', padding(d))
95
- .replace('hh', padding(h))
96
- .replace('mm', padding(mm))
97
- .replace('ss', padding(s))
98
- .replace('M', m)
99
- .replace('D', d)
100
- .replace('h', h)
101
- .replace('m', mm)
102
- .replace('s', s)
103
- .replace('EEEE', padding(eeee))
104
- .replace('EEE', padding(eee))
105
- .replace('EE', padding(ee))
106
- .replace('E', padding(e))
107
- }
108
-
109
- function padding(m) {
110
- return m < 10 ? `0${m}` : m
111
- }
112
-
113
-
114
- /* harmony default export */ const formatDate_formatDate = ({
115
- formatDate
116
- });
117
-
118
-
119
-
120
- ;// ./lib/helpers/formatDate/index.js
121
-
122
-
123
50
  ;// ./lib/helpers/getValidation/getValidation.js
124
51
  function getValidation(rule, data, getDataByKey, KeyValueObject) {
125
52
  if (!rule) {
126
53
  return true
127
54
  }
128
- if (typeof getDataByKey !== 'function' || typeof KeyValueObject !== 'function') {
55
+ if (typeof getDataByKey !== 'function' || (KeyValueObject && typeof KeyValueObject !== 'function')) {
129
56
  return false
130
57
  }
131
58
  const { key = '', value, keyValuePath = '' } = rule
@@ -217,6 +144,13 @@ function getValidation(rule, data, getDataByKey, KeyValueObject) {
217
144
  const timestamp = new Date(rowValue).getTime()
218
145
  return (now - timestamp) < value['$intervalTimeLt']
219
146
  }
147
+ case '$isToday': {
148
+ const currentDate = new Date()
149
+ const start = currentDate.setHours(0,0,0,0)
150
+ const end = currentDate.setHours(23,59,59,59)
151
+ const dateValue = new Date(rowValue).getTime()
152
+ return (start <= dateValue && end >= dateValue) === value['$isToday']
153
+ }
220
154
  case '$notInValue': {
221
155
  const result = getDataByKey(value['$notInValue'], data)
222
156
  const _value = Array.isArray(result) ? result : []
@@ -248,12 +182,66 @@ function getValidation(rule, data, getDataByKey, KeyValueObject) {
248
182
  ;// ./lib/helpers/getValidation/index.js
249
183
 
250
184
 
185
+ ;// ./lib/helpers/formatDate/formatDate.js
186
+
187
+ function formatDate(date, format) {
188
+ const _date = date && date instanceof Date ? date : new Date(date)
189
+ const dayMapChi = ['日','一','二','三','四','五','六']
190
+ const dayMapEng = ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday']
191
+ const dayMapEngShort = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat']
192
+ const _format = format || 'YYYY/MM/DD hh:mm'
193
+ const e = _date.getDay()
194
+ const ee = dayMapEngShort[e]
195
+ const eee = dayMapChi[e]
196
+ const eeee = dayMapEng[e]
197
+ const y = _date.getFullYear()
198
+ const m = _date.getMonth() + 1
199
+ const d = _date.getDate()
200
+ const h = _date.getHours()
201
+ const mm = _date.getMinutes()
202
+ const s = _date.getSeconds()
203
+
204
+ return _format.replace('YYYY', y)
205
+ .replace('MM', padding(m))
206
+ .replace('MM', padding(m))
207
+ .replace('DD', padding(d))
208
+ .replace('hh', padding(h))
209
+ .replace('mm', padding(mm))
210
+ .replace('ss', padding(s))
211
+ .replace('M', m)
212
+ .replace('D', d)
213
+ .replace('h', h)
214
+ .replace('m', mm)
215
+ .replace('s', s)
216
+ .replace('EEEE', padding(eeee))
217
+ .replace('EEE', padding(eee))
218
+ .replace('EE', padding(ee))
219
+ .replace('E', padding(e))
220
+ }
221
+
222
+ function padding(m) {
223
+ return m < 10 ? `0${m}` : m
224
+ }
225
+
226
+
227
+ /* harmony default export */ const formatDate_formatDate = ({
228
+ formatDate
229
+ });
230
+
231
+
232
+
233
+ ;// ./lib/helpers/formatDate/index.js
234
+
235
+
251
236
  ;// ./lib/helpers/getValueByKeys/getValueByKeys.js
252
- // keys can be array or string
237
+ // keys can be array or object or string
253
238
  function getValueByKeys(keys, data) {
254
239
  let _keys = keys
255
240
  let _data = data
256
- if (!Array.isArray(keys)) {
241
+ if (typeof keys === 'string') {
242
+ _keys = _keys.split('.')
243
+ }
244
+ if (!Array.isArray(keys) && typeof keys === 'object') {
257
245
  const { keys: keyArr, obj } = keys
258
246
  _keys = keyArr
259
247
  _data = obj
@@ -280,930 +268,516 @@ function getValueByKeys(keys, data) {
280
268
  ;// ./lib/helpers/getValueByKeys/index.js
281
269
 
282
270
 
283
- ;// ./lib/helpers/objectHelper/objectHelper.js
284
- const objectHelper = {
285
- get(obj, path) {
286
- const parts = path.split('.')
287
- return parts.reduce((acc, part) => {
288
- if (part.endsWith('[]')) {
289
- // 处理数组遍历
290
- const key = part.slice(0, -2) // 去掉 '[]' 得到属性名
291
- if (Array.isArray(acc[key])) {
292
- return acc[key] // 返回整个数组
293
- }
294
- return [] // 如果不是数组,返回空数组
295
- }
296
- if (part.includes('[') && part.includes(']')) {
297
- // 处理数组索引
298
- const arrayMatch = part.match(/(\w+)\[(\d+)\]/)
299
- if (arrayMatch) {
300
- const key = arrayMatch[1]
301
- const index = arrayMatch[2]
302
- return acc && acc[key] && acc[key][index]
303
- }
304
- } else if (acc && Array.isArray(acc)) {
305
- // 如果当前值是数组,提取每个对象的指定属性
306
- return acc.map((item) => item[part])
307
- } else {
308
- // 处理普通属性
309
- return acc && acc[part]
310
- }
311
- }, obj)
312
- },
313
- merge,
314
- set(obj, path, value) {
315
- const parts = path.split('.')
316
- let current = obj
317
- for (let i = 0; i < parts.length - 1; i++) {
318
- const part = parts[i]
319
- if (part.endsWith('[]')) {
320
- // 处理数组遍历
321
- const key = part.slice(0, -2) // 去掉 '[]' 得到属性名
322
- if (Array.isArray(current[key])) {
323
- current[key].forEach((item) => set(item, parts.slice(i + 1).join('.'), value))
324
- }
325
- return // 处理完数组后直接返回
326
- }
327
- if (part.includes('[') && part.includes(']')) {
328
- // 处理数组索引
329
- const arrayMatch = part.match(/(\w+)\[(\d+)\]/)
330
- if (arrayMatch) {
331
- const key = arrayMatch[1]
332
- const index = arrayMatch[2]
333
- if (Array.isArray(current[key]) && current[key][index]) {
334
- current = current[key][index]
335
- } else {
336
- return // 如果数组或索引不存在,直接返回
337
- }
338
- }
339
- } else {
340
- // 处理普通属性
341
- if (!current[part]) {
342
- current[part] = {} // 如果属性不存在,创建一个空对象
343
- }
344
- current = current[part]
345
- }
346
- }
347
-
348
- // 设置最终属性值
349
- const lastPart = parts[parts.length - 1]
350
- current[lastPart] = value
351
- }
271
+ ;// ./lib/models/templateCompiler/templateCompilerException.js
272
+ const TEMPLATE_COMPILER_EXCEPTION_TYPE = {
273
+ argumentEmptyException: 'Argument is empty',
274
+ argumentFormatException: 'Incorrect number or format of argument',
275
+ invalidFuntionException: 'Function Name is invalid',
276
+ invalidRegExpException: 'Invalid regular expression',
277
+ isNotAFunctionException: 'Is not a function',
278
+ notExistException: 'Key does not exist',
279
+ resultEmptyException: 'Result is empty',
280
+ resultMoreThanOneException: 'More than one result'
352
281
  }
353
282
 
354
- function merge(target, ...sources) {
355
- if (!sources.length) return target
356
-
357
- const source = sources.shift() // 取出第一个源对象
358
-
359
- if (_isObject(target) && _isObject(source)) {
360
- for (const key in source) {
361
- if (_isObject(source[key])) {
362
- if (!target[key]) {
363
- // 如果目标对象没有该属性,创建一个空对象
364
- target[key] = {}
365
- }
366
- // 递归合并
367
- merge(target[key], source[key])
368
- } else {
369
- // 直接覆盖
370
- target[key] = source[key]
371
- }
372
- }
283
+ class TemplateCompilerException extends Error {
284
+ constructor(message) {
285
+ super(message)
286
+ this.message = message
373
287
  }
374
-
375
- // 继续合并剩余的源对象
376
- return merge(target, ...sources)
377
288
  }
378
289
 
379
- function _isObject(obj) {
380
- return obj && typeof obj === 'object' && !Array.isArray(obj)
381
- }
382
290
 
383
291
 
292
+ ;// ./lib/models/templateCompiler/constants.js
293
+ const _EMPTY = '_EMPTY'
294
+ const _FN_NAMES = [
295
+ 'get', 'map', 'join', 'concatIf', 'exec', 'filterOne', 'filterAll', 'formatDate', 'eq', 'neq', 'gt', 'lt', 'gte', 'lte', 'isEmpty', 'isNotEmpty', 'toLowerCase', 'toUpperCase'
296
+ ]
297
+ const _HIDE = '_HIDE'
298
+ const _NOT_EMPTY = '_NOT_EMPTY'
299
+ const _SELF = '_SELF'
300
+ const TAGS_EJS = ['<%=', '%>']
301
+ const TAGS_HANDLEBAR = ['{{', '}}']
384
302
 
385
- ;// ./lib/helpers/objectHelper/index.js
386
303
 
387
304
 
305
+ ;// ./lib/models/templateCompiler/helpers/_concatIf.js
388
306
 
389
307
 
390
- ;// ./lib/helpers/pReduce/pReduce.js
391
- async function pReduce(iterable, reducer, initialValue) {
392
- return new Promise((resolve, reject) => {
393
- const iterator = iterable[Symbol.iterator]()
394
- let index = 0
395
308
 
396
- const next = async total => {
397
- const element = iterator.next()
398
309
 
399
- if (element.done) {
400
- resolve(total)
401
- return
402
- }
310
+ function _concatIf(data, args) {
311
+ if (typeof data !== 'string') {
312
+ throw new TemplateCompilerException(`_concatIf: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: the data must be string :${data.join(', ')}`)
313
+ }
314
+ if (args.length !== 3) {
315
+ throw new TemplateCompilerException(`_concatIf: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: ${args.join(', ')}`)
316
+ }
317
+ if (data === null || (typeof data === 'undefined')) {
318
+ return null
319
+ }
320
+ const [condition, success, failover] = args
321
+ const validConditions = [_EMPTY, _NOT_EMPTY]
322
+ if (validConditions.includes(condition) || success.length !== 2) {
323
+ throw new TemplateCompilerException(`concatIf: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentEmptyException}: ${condition}, ${success}`)
324
+ }
325
+ if (data === '' && failover.includes(_HIDE)) {
326
+ return ''
327
+ }
328
+ if (data !== '' && (data !== null || data !== undefined) && failover.includes(_HIDE)) {
329
+ return `${success[0]}${data}${success[success.length - 1]}`
330
+ }
331
+ return failover
332
+ }
403
333
 
404
- try {
405
- const [resolvedTotal, resolvedValue] = await Promise.all([total, element.value])
406
- next(reducer(resolvedTotal, resolvedValue, index++))
407
- } catch (error) {
408
- reject(error)
409
- }
410
- }
411
334
 
412
- next(initialValue)
413
- })
414
- }
415
335
 
336
+ ;// ./lib/models/templateCompiler/helpers/_eq.js
416
337
 
417
338
 
418
- ;// ./lib/models/apiResponse/apiResponse.js
419
- class ApiResponse {
420
- constructor(options = {}) {
421
- options = options || {}
422
- this._data = options.data || options._data || []
423
- this.err = options.err
424
- this.isNew = options.isNew || false
425
- this.message = options.message
426
- this.total = options.total || 0
427
- this._instanceBuilder = options._instanceBuilder
428
- }
429
339
 
430
- static init(options = {}) {
431
- if (options instanceof this) {
432
- return options
433
- }
434
- const instance = new this(options)
435
- return instance
340
+
341
+ function _eq(data, args) {
342
+ if (args.length !== 3) {
343
+ throw new TemplateCompilerException(`eq: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: ${args.join(', ')}`)
436
344
  }
437
- static get _classname() {
438
- return 'ApiResponse'
345
+ if (data === null || (typeof data === 'undefined')) {
346
+ return null
439
347
  }
440
- static get _superclass() {
441
- return 'ApiResponse'
348
+ if (args.includes(_SELF)) {
349
+ args = args.map((arg) => {
350
+ return (arg === _SELF) ? data : arg
351
+ })
442
352
  }
353
+ const expected = args[0]
354
+ return data === expected ? args[1] : args[2]
355
+ }
443
356
 
444
- // getters
445
- get data() {
446
- if (this._instanceBuilder && (typeof this._instanceBuilder === 'function')) {
447
- return this._data.map(this._instanceBuilder)
448
- }
449
- return this._data
357
+
358
+
359
+ ;// ./lib/models/templateCompiler/helpers/_exec.js
360
+ function _exec(data, args) {
361
+ try {
362
+ const [methodName, ..._args] = args
363
+ return data[methodName](..._args)
364
+ } catch (e) {
365
+ throw e
450
366
  }
451
367
  }
452
368
 
453
369
 
454
370
 
455
- ;// ./lib/models/apiResponse/makeApiResponse.js
371
+ ;// ./lib/models/templateCompiler/helpers/_filterAll.js
456
372
 
457
373
 
458
- function makeApiResponse({ repo, result }) {
459
- return ApiResponse.init({
460
- ...result,
461
- _instanceBuilder: (i) => {
462
- return repo.init(i)
374
+
375
+ // const DELIMITER = '~~~'
376
+
377
+ function _filterAll(data, args) {
378
+ try {
379
+ if (!Array.isArray(args) || args.length === 0) {
380
+ throw new TemplateCompilerException(TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentEmptyException)
463
381
  }
464
- })
382
+ if (!Array.isArray(data) || data.length === 0) {
383
+ return []
384
+ }
385
+ if (typeof data[0] === 'object') {
386
+ return _existObject(data, args)
387
+ }
388
+ if (typeof data[0] === 'string' || typeof data[0] === 'number') {
389
+ return _exist(data, args)
390
+ }
391
+ return []
392
+ } catch (e) {
393
+ throw e
394
+ }
465
395
  }
466
396
 
397
+ function _exist(data, args) {
398
+ const _args = args.flat()
399
+ return data.filter((e) => _args.some((arg) => _performOperation(arg, e)))
400
+ }
467
401
 
402
+ function _existObject(data, args) {
403
+ if (args.length === 1) {
404
+ const arg = args[0]
405
+ return data.filter((e) => {
406
+ if (arg.includes('.')) {
407
+ return getValueByKeys(arg.split('.'), e)
408
+ }
409
+ return Object.prototype.hasOwnProperty.call(e, arg)
410
+ })
411
+ }
468
412
 
469
- ;// ./lib/models/apiResponse/index.js
470
-
413
+ if (args.length > 2) {
414
+ let res = data
415
+ for (let i = 0; i < args.length; i += 2) {
416
+ const group = [args[i], args[i + 1]]
417
+ res = _existObject(res, group)
418
+ }
419
+ return res
420
+ }
471
421
 
422
+ const [key, ..._argsArr] = args
423
+ const _args = _argsArr.flat()
424
+ return data.filter((e) => {
425
+ const value = key.includes('.') ? getValueByKeys(key.split('.'), e) : e[key]
426
+ return _args.some((arg) => _performOperation(arg, value))
427
+ })
428
+ }
472
429
 
430
+ function _performOperation(arg, value) {
431
+ // the arg is undefined
432
+ if (arg === undefined && value === undefined) return true
473
433
 
434
+ // the arg is null
435
+ if (arg === null && value === null) return true
474
436
 
475
- ;// ./lib/models/keyValueObject/keyValueObject.js
476
- class KeyValueObject {
477
- constructor(options = {}) {
478
- options = options || {}
479
- this.key = options.key || null
480
- this.value = (typeof options.value !== 'undefined') ? options.value : ''
437
+ // the arg is boolean
438
+ if (typeof arg === 'boolean') {
439
+ return arg === value
481
440
  }
482
441
 
483
- // Class methods
484
- static init(options = {}) {
485
- if (options instanceof this) {
486
- return options
442
+ // the arg is blank or *: Blank => Empty, * => Not Empty
443
+ if (arg === '' || arg === '*') {
444
+ // null and undefined are not included in either case
445
+ if (value === null || value === undefined) {
446
+ return false
487
447
  }
488
- const instance = new this(options)
489
- return instance.isValid ? instance : null
490
- }
491
- static initFromArray(arr = []) {
492
- if (Array.isArray(arr)) {
493
- return arr.map((a) => this.init(a))
448
+ if (typeof value === 'string') {
449
+ return arg === '' ? value === '' : value !== ''
494
450
  }
495
- return []
496
- }
497
- static initOnlyValidFromArray(arr = []) {
498
- return this.initFromArray(arr).filter((i) => i)
499
- }
500
- static get _classname() {
501
- return 'KeyValueObject'
502
- }
503
- static get _superclass() {
504
- return 'KeyValueObject'
451
+ if (Array.isArray(value)) {
452
+ return arg === '' ? value.length === 0 : value.length !== 0
453
+ }
454
+ return arg !== ''
505
455
  }
506
456
 
507
- static addItem(arr, key, value) {
508
- arr.push(this.init({ key, value }))
457
+ // the arg is alphabetic or number
458
+ if (_isPureStringOrNumber(arg)) {
459
+ return arg === value
509
460
  }
510
- static addRecord(arr = [], key, value) {
511
- if (!this.hasKeyValue(arr, key, value)) {
512
- arr.push(this.init({ key, value }))
461
+
462
+ // the arg is array of [] or [*]: [] => Empty, [*] => Not Empty
463
+ if (arg.startsWith('[') && arg.endsWith(']')) {
464
+ if (arg === '[]') {
465
+ return Array.isArray(value) && value.length === 0
513
466
  }
514
- return arr
467
+ if (arg === '[*]') {
468
+ return Array.isArray(value) && value.length !== 0
469
+ }
470
+ return false
515
471
  }
516
- static appendRecord(arr = [], key, value) {
517
- return arr.map((item) => {
518
- if (this.sameKey(item, key)) {
519
- item.value = [...item.value, ...value]
520
- }
521
- return item
522
- })
472
+
473
+ // the arg is 'operator + string | number'
474
+ const { operator, value: argValue } = _splitOperator(arg)
475
+ if (!operator || (argValue !== 0 && !argValue)) {
476
+ return false
523
477
  }
524
- static appendValueArray(arr = [], key, value) {
525
- return arr.map((item) => {
526
- if (this.sameKey(item, key)) {
527
- item.value = [...item.value, ...value]
528
- }
529
- return item
530
- })
478
+ switch (operator) {
479
+ case '>':
480
+ return value > argValue
481
+ case '<':
482
+ return value < argValue
483
+ case '!=':
484
+ return value !== argValue
485
+ case '>=':
486
+ return value >= argValue
487
+ case '<=':
488
+ return value <= argValue
489
+ default:
490
+ return false
531
491
  }
532
- static foundByKey(arr = [], key) {
533
- const found = arr.find((m) => {
534
- return this.sameKey(m, key)
535
- })
536
- return found || null
537
- }
538
- static foundValueByKey(arr = [], key) {
539
- const found = this.foundByKey(arr, key)
540
- return found ? found.value : null
541
- }
542
- static fromObject(options = {}) {
543
- return Object.keys(options).reduce((acc, key) => {
544
- acc.push(this.init({ key, value: options[key] }))
545
- return acc
546
- }, [])
547
- }
548
- static getValueByKey(arr = [], key) {
549
- return this.foundValueByKey(arr, key)
550
- }
551
- static getValueByKeyFromArray(arr = [], key) {
552
- if (arr.length === 0) {
553
- return null
554
- }
555
- const firstArr = arr.shift()
556
- const found = firstArr.find((i) => {
557
- return this.sameKey(i, key)
558
- })
559
- if (found && found.value) {
560
- return found.value
561
- }
562
- return this.getValueByKeyFromArray(arr, key)
563
- }
564
- static getValuesByKey(arr = [], key) {
565
- return arr.reduce((acc, item) => {
566
- if (this.sameKey(item, key)) {
567
- acc.push(item.value)
568
- }
569
- return acc
570
- }, [])
571
- }
572
- static hasKeyValue(arr = [], key, value) {
573
- if (typeof value === 'undefined') {
574
- return arr.filter((item) => this.sameKey(item, key)).length > 0
575
- }
576
- return arr.filter((item) => (this.sameKey(item, key) && _isSame(item.value, value))).length > 0
577
- }
578
- static insertOrUpdateRecord(arr = [], key, value) {
579
- let copy = [...arr]
580
- if (!this.hasKeyValue(arr, key)) {
581
- copy.push(this.init({ key, value }))
582
- } else {
583
- copy = this.updateRecord(arr, key, value)
584
- }
585
- return copy
586
- }
587
- static keys(arr = []) {
588
- if (Array.isArray(arr)) {
589
- return arr.reduce((acc, item) => {
590
- acc.push(item.key)
591
- return acc
592
- }, [])
593
- }
594
- return []
595
- }
596
- static merge(toArr, fromArr) {
597
- (fromArr || []).map((from) => {
598
- const found = toArr.find((to) => {
599
- return to.key === from.key
600
- })
601
- if (found) {
602
- found.value = (found.value || []).concat(from.value)
603
- } else {
604
- toArr.push(from)
605
- }
606
- })
607
- return toArr
608
- }
609
- static removeByKey(arr, key) {
610
- return arr.reduce((acc, item) => {
611
- if (!this.sameKey(item, key)) {
612
- acc.push(item)
613
- }
614
- return acc
615
- }, [])
616
- }
617
- static sameKey(item, key) {
618
- return _isSame(item.key, key)
619
- }
620
- static toObject(arr = []) {
621
- if (Array.isArray(arr)) {
622
- return arr.reduce((acc, item) => {
623
- acc[item.key] = item.value
624
- return acc
625
- }, {})
626
- }
627
- return {}
628
- }
629
- static toString(arr = [], delimiter = '; ') {
630
- if (Array.isArray(arr)) {
631
- return arr.reduce((acc, item) => {
632
- acc.push(`${item.key}: ${item.value}`)
633
- return acc
634
- }, []).join(delimiter)
635
- }
636
- return ''
637
- }
638
- static updateRecord(arr = [], key, value) {
639
- return arr.map((item) => {
640
- if (this.sameKey(item, key)) {
641
- return {
642
- ...item,
643
- value
644
- }
645
- }
646
- return item
647
- })
648
- }
649
- static updateOrInsertRecord(arr = [], key, value) {
650
- return this.insertOrUpdateRecord(arr, key, value)
651
- }
652
- static updateRecordsFromArray(arr = [], updateArr = []) {
653
- if (Array.isArray(arr) && Array.isArray(updateArr)) {
654
- const obj1 = this.toObject(arr)
655
- const obj2 = this.toObject(updateArr)
656
- return this.fromObject({
657
- ...obj1,
658
- ...obj2
659
- })
660
- }
661
- return []
662
- }
663
- static values(arr = []) {
664
- if (Array.isArray(arr)) {
665
- return arr.reduce((acc, item) => {
666
- acc.push(item.value)
667
- return acc
668
- }, [])
669
- }
670
- return []
492
+ }
493
+
494
+ function _isPureStringOrNumber(input) {
495
+ if (typeof input === 'string') {
496
+ if (input.startsWith('[') && input.endsWith(']')) {
497
+ return false
498
+ }
499
+ if (/!=|>=|<=|>|</.test(input)) {
500
+ return false
501
+ }
502
+ return true
671
503
  }
504
+ return !Number.isNaN(input)
505
+ }
672
506
 
673
- // getters
674
- get isValid() {
675
- return !!this.key
676
- }
507
+ function _splitOperator(str) {
508
+ const operators = ['!=', '>=', '<=', '>', '<']
677
509
 
678
- get toObject() {
679
- const obj = {}
680
- if (this.isValid) {
681
- obj[this.key] = this.value
682
- }
683
- return obj
510
+ const matchedOp = operators.find((op) => str.startsWith(op))
511
+ if (!matchedOp) return { operator: null, value: null }
512
+
513
+ const remaining = str.slice(matchedOp.length)
514
+
515
+ // '>Primary' or '<Primary' is invalid
516
+ if (/^[a-zA-Z]*$/.test(remaining) && matchedOp !== '!=') {
517
+ return { operator: null, value: null }
684
518
  }
685
- }
686
519
 
687
- function _isSame(key1, key2) {
688
- return key1 === key2
689
- }
520
+ // if it is a number it is converted to a number
521
+ const value = (!Number.isNaN(parseFloat(remaining)) && !Number.isNaN(remaining)) ? Number(remaining) : remaining
690
522
 
523
+ return {
524
+ operator: matchedOp,
525
+ value
526
+ }
527
+ }
691
528
 
692
529
 
693
- ;// ./lib/models/keyValueObject/index.js
694
530
 
531
+ ;// ./lib/models/templateCompiler/helpers/_filterOne.js
695
532
 
696
533
 
697
534
 
698
- ;// ./lib/helpers/stringFormatter/stringFormatter.js
699
- function stringFormatter(str, delimiter = '_') {
700
- if (str === null || typeof str === 'undefined' || typeof str.toString === 'undefined') {
701
- return null
535
+ function _filterOne(data, args) {
536
+ try {
537
+ const list = _filterAll(data, args)
538
+ if (list.length === 1) {
539
+ return list[0]
540
+ }
541
+ if (list.length === 0) {
542
+ return null
543
+ }
544
+ throw new TemplateCompilerException(TEMPLATE_COMPILER_EXCEPTION_TYPE.resultMoreThanOneException)
545
+ } catch (e) {
546
+ throw e
702
547
  }
703
- return str.toString()
704
- .trim()
705
- .toUpperCase()
706
- .replace('-', delimiter)
707
- .replace(' ', delimiter)
708
548
  }
709
549
 
710
550
 
711
551
 
712
- ;// ./lib/models/metadata/metadata.js
713
-
714
-
552
+ ;// ./lib/models/templateCompiler/helpers/_formatDate.js
715
553
 
716
- const DELIMITER = '_'
717
554
 
718
- class Metadata extends KeyValueObject {
719
- static init(options = {}) {
720
- if (options instanceof this) {
721
- return options
722
- }
723
- const instance = new this({
724
- ...options,
725
- key: stringFormatter(options.key, DELIMITER),
726
- })
727
- return instance.isValid ? instance : null
728
- }
729
- static get _classname() {
730
- return 'Metadata'
555
+ function _formatDate(timestamp, format) {
556
+ if (format.length === 0) {
557
+ throw new TemplateCompilerException(`_formateDate: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: format parts must be not empty array`)
731
558
  }
732
559
 
733
- static merge(toArr, fromArr) {
734
- (fromArr || []).map((from) => {
735
- const found = toArr.find((to) => {
736
- return metadata_isSame(to.key, from.key)
737
- })
738
- if (found) {
739
- found.value = (found.value || []).concat(from.value)
740
- } else {
741
- toArr.push(from)
742
- }
743
- })
744
- return toArr
745
- }
746
- static sameKey(item, key) {
747
- return metadata_isSame(item.key, key)
560
+ if (timestamp === null || timestamp === undefined) {
561
+ return null
748
562
  }
749
- }
750
-
751
- function metadata_isSame(key1, key2) {
752
- return stringFormatter(key1, DELIMITER) === stringFormatter(key2, DELIMITER)
753
- }
754
563
 
564
+ const date = new Date(timestamp)
755
565
 
566
+ const partsMap = {
567
+ yyyy: String(date.getFullYear()),
568
+ mm: String(date.getMonth() + 1).padStart(2, '0'),
569
+ dd: String(date.getDate()).padStart(2, '0')
570
+ }
756
571
 
757
- ;// ./lib/models/metadata/index.js
572
+ // Check for invalid format tokens
573
+ const validTokens = ['yyyy', 'mm', 'dd']
574
+ const invalidTokens = format.filter((part) => part.length > 1 && !validTokens.includes(part))
758
575
 
576
+ if (invalidTokens.length > 0) {
577
+ throw new TemplateCompilerException(
578
+ `_formateDate: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: the format type is not valid: ${format.join(', ')}`
579
+ )
580
+ }
759
581
 
582
+ // Build the formatted string using reduce
583
+ return format.reduce((result, part) => result + (partsMap[part] || part), '')
584
+ }
760
585
 
761
586
 
762
- ;// ./lib/models/qMeta/qMeta.js
763
587
 
588
+ ;// ./lib/models/templateCompiler/helpers/_get.js
764
589
 
765
- const updateAllowedProps = [
766
- 'attributes',
767
- 'ref'
768
- ]
769
590
 
770
- class QMeta {
771
- constructor(options = {}) {
772
- options = options || {}
773
- this.attributes = KeyValueObject.initOnlyValidFromArray(options.attributes)
774
- this.ref = options.ref || {}
591
+ function _get(data, key, failover = null) {
592
+ try {
593
+ if (key === null || (typeof key === 'undefined') || key === '') {
594
+ throw new TemplateCompilerException(TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentEmptyException)
595
+ }
596
+ if (data === null) {
597
+ return null
598
+ }
599
+ if (key.includes('.')) {
600
+ const parts = key.split('.')
601
+ if (parts.length > 1) {
602
+ const first = parts.shift()
603
+ const remainingKey = parts.join('.')
604
+ if (typeof data[first] !== 'undefined') {
605
+ return _get(data[first], remainingKey, failover)
606
+ }
607
+ return _handleFailover(key, failover)
608
+ }
609
+ }
610
+ if (typeof data[key] !== 'undefined') {
611
+ return data[key]
612
+ }
613
+ return _handleFailover(key, failover)
614
+ } catch (e) {
615
+ throw e
775
616
  }
617
+ }
776
618
 
777
- static get _classname() {
778
- return 'QMeta'
779
- }
780
- static get _superclass() {
781
- return 'QMeta'
619
+ function _handleFailover(key, failover) {
620
+ if (failover !== null) {
621
+ return failover
782
622
  }
623
+ return null
624
+ // throw new TemplateCompilerException(`Key "${key}" does not exist and no failover`)
625
+ }
783
626
 
784
- // Class methods
785
- static init(options = {}) {
786
- if (options instanceof QMeta) {
787
- return options
788
- }
789
- return new QMeta(options)
790
- }
791
627
 
792
- // instance methods
793
- addAttribute(obj) {
794
- const kvObject = KeyValueObject.init(obj)
795
- if (!kvObject) {
796
- throw new Error('invalid meta attribute')
797
- }
798
- this.attributes.push(kvObject)
799
- return this
800
- }
801
628
 
802
- update(obj) {
803
- Object.keys(obj).forEach((key) => {
804
- if (updateAllowedProps.includes(key)) {
805
- if (key === 'attributes') {
806
- this[key] = KeyValueObject.initOnlyValidFromArray(obj[key])
807
- } else {
808
- this[key] = obj[key]
809
- }
810
- }
629
+ ;// ./lib/models/templateCompiler/helpers/_gt.js
630
+
631
+
632
+
633
+
634
+ function _gt(data, args) {
635
+ if (args.length !== 3) {
636
+ throw new TemplateCompilerException(`_gt: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: ${args.join(', ')}`)
637
+ }
638
+ if (data === null || (typeof data === 'undefined')) {
639
+ return null
640
+ }
641
+ if (args.includes(_SELF)) {
642
+ args = args.map((arg) => {
643
+ return (arg === _SELF) ? data : arg
811
644
  })
812
- return this
813
645
  }
646
+ const expected = args[0]
647
+ return data > expected ? args[1] : args[2]
814
648
  }
815
649
 
816
650
 
817
651
 
818
- ;// ./lib/models/qMeta/index.js
652
+ ;// ./lib/models/templateCompiler/helpers/_gte.js
819
653
 
820
654
 
821
655
 
822
656
 
823
- ;// ./lib/models/repo/repo.js
824
- class Repo {
825
- constructor(options) {
826
- options = options || {}
827
- this.model = options.model
828
- this._sharedOptions = options._sharedOptions // { session: this.dbTransaction }
829
- this._queryOptions = options._queryOptions
830
- this._saveOptions = options._saveOptions
831
- this._Class = options._constructor && options._constructor._Class
832
- ? options._constructor._Class
833
- : null
834
- }
835
- static init(options = {}) {
836
- if (options instanceof this) {
837
- return options
838
- }
839
- const instance = new this(options)
840
- return instance.isValid ? instance : null
657
+ function _gte(data, args) {
658
+ if (args.length !== 3) {
659
+ throw new TemplateCompilerException(`_gte: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: ${args.join(', ')}`)
841
660
  }
842
- static get _classname() {
843
- return 'Repo'
661
+ if (data === null || (typeof data === 'undefined')) {
662
+ return null
844
663
  }
845
- static get _superclass() {
846
- return 'Repo'
664
+ if (args.includes(_SELF)) {
665
+ args = args.map((arg) => {
666
+ return (arg === _SELF) ? data : arg
667
+ })
847
668
  }
669
+ const expected = args[0]
670
+ return data >= expected ? args[1] : args[2]
671
+ }
848
672
 
849
- get _classname() {
850
- return 'Repo'
851
- }
852
673
 
853
- get _superclass() {
854
- return 'Repo'
855
- }
856
674
 
857
- get isValid() {
858
- return this.model
859
- && (typeof this.model.deleteOne === 'function')
860
- && (typeof this.model.findAll === 'function')
861
- && (typeof this.model.saveOne === 'function')
862
- }
675
+ ;// ./lib/models/templateCompiler/helpers/_isEmpty.js
863
676
 
864
- get queryOptions() {
865
- return {
866
- ...this._sharedOptions,
867
- ...this._queryOptions,
868
- }
869
- }
870
677
 
871
- get saveOptions() {
872
- return {
873
- ...this._sharedOptions,
874
- ...this._saveOptions,
875
- }
876
- }
877
678
 
878
- init(options) {
879
- if (this._Class && typeof this._Class.init === 'function') {
880
- return this._Class.init(options)
881
- }
882
- return options
883
- }
884
679
 
885
- async deleteOne({ id }) {
886
- try {
887
- const result = await this.model.deleteOne({ _id: id })
888
- return {
889
- ...result, // { message: 'ok', total }
890
- isNew: false,
891
- data: []
892
- }
893
- } catch (err) {
894
- throw err
895
- }
680
+ function _isEmpty(data, args) {
681
+ if (args.length !== 2) {
682
+ throw new TemplateCompilerException(`_isEmpty: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: ${args.join(', ')}`)
896
683
  }
897
-
898
- // systemLog is optional
899
- findAll({ query, systemLog }) {
900
- const log = _makeLog({
901
- systemLog,
902
- label: 'REPO_READ',
903
- message: `fn ${this._classname}.prototype.findAll`,
904
- input: [{ query: { ...query }, systemLog: { ...systemLog } }]
905
- })
906
- return new Promise((resolve, reject) => {
907
- this.model.findAll(query, this.queryOptions, (err, data, total) => {
908
- if (err) {
909
- log({ level: 'warn', output: err.toString() })
910
- reject(err)
911
- } else {
912
- const result = {
913
- isNew: false,
914
- data,
915
- total: total || data.length
916
- }
917
- log({ level: 'info', output: { ...result } })
918
- resolve(result)
919
- }
920
- })
684
+ // if (data === null || (typeof data === 'undefined')) {
685
+ // return null
686
+ // }
687
+ if (args.includes(_SELF)) {
688
+ args = args.map((arg) => {
689
+ return (arg === _SELF) ? data : arg
921
690
  })
922
691
  }
923
-
924
- findOne({ query, systemLog }) {
925
- const log = _makeLog({
926
- systemLog,
927
- label: 'REPO_READ',
928
- message: `fn ${this._classname}.prototype.findOne`,
929
- input: [{ query: { ...query }, systemLog: { ...systemLog } }]
930
- })
931
- return new Promise((resolve, reject) => {
932
- this.model.findAll(query, this.queryOptions, (err, data) => {
933
- if (err) {
934
- reject(err)
935
- } else if (data.length === 1) {
936
- const result = {
937
- isNew: false,
938
- data,
939
- total: 1
940
- }
941
- log({ level: 'info', output: { ...result } })
942
- resolve(result)
943
- } else if (data.length === 0) {
944
- reject(new Error('record not found'))
945
- } else {
946
- reject(new Error('more than one is found'))
947
- }
948
- })
949
- })
950
- .catch((err) => {
951
- log({ level: 'warn', output: err.toString() })
952
- throw err
953
- })
692
+ if (data !== null && typeof data === 'object' && Object.keys(data).length === 0) {
693
+ return args[0]
954
694
  }
695
+ return (data === '' || data === null || data === undefined || data.length === 0) ? args[0] : args[1]
696
+ }
955
697
 
956
- saveAll({ docs, systemLog }) {
957
- let isNew
958
- const log = _makeLog({
959
- systemLog,
960
- label: 'REPO_WRITE',
961
- message: `fn ${this._classname}.prototype.saveAll`,
962
- input: [{ docs: [...docs], systemLog: { ...systemLog } }]
698
+
699
+
700
+ ;// ./lib/models/templateCompiler/helpers/_isNotEmpty.js
701
+
702
+
703
+
704
+
705
+ function _isNotEmpty(data, args) {
706
+ if (args.length !== 2) {
707
+ throw new TemplateCompilerException(`_isNotEmpty: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: ${args.join(', ')}`)
708
+ }
709
+ // if (data === null || (typeof data === 'undefined')) {
710
+ // return null
711
+ // }
712
+ if (args.includes(_SELF)) {
713
+ args = args.map((arg) => {
714
+ return (arg === _SELF) ? data : arg
963
715
  })
964
- const promise = typeof this.model.saveAll === 'function'
965
- ? this.model.saveAll({ docs })
966
- : Promise.all(docs.map(async (doc) => {
967
- if (doc) {
968
- const result = await this.saveOne({ doc })
969
- isNew = result.isNew
970
- const _data = result._data || result.data
971
- return _data[0]
972
- }
973
- return null
974
- }))
975
- return promise.then((savedData) => {
976
- if (savedData.length !== 1) isNew = null
977
- const result = {
978
- data: savedData,
979
- isNew,
980
- total: savedData.length
981
- }
982
- log({ level: 'info', output: { ...result } })
983
- return result
984
- }).catch((err) => {
985
- log({ level: 'warn', output: err.toString() })
986
- throw err
987
- })
988
- }
989
-
990
- saveOne({ doc, systemLog }) {
991
- const log = _makeLog({
992
- systemLog,
993
- label: 'REPO_WRITE',
994
- message: `fn ${this._classname}.prototype.saveOne`,
995
- input: [{ doc: { ...doc }, systemLog: { ...systemLog } }]
996
- })
997
- return new Promise((resolve, reject) => {
998
- this.model.saveOne(doc, this.saveOptions, (err, result) => {
999
- if (err) {
1000
- log({ level: 'warn', output: err.toString() })
1001
- reject(err)
1002
- } else {
1003
- log({ level: 'info', output: { ...result } })
1004
- resolve(result)
1005
- }
1006
- })
1007
- })
1008
- }
1009
- }
1010
-
1011
- function _makeLog({ systemLog, label, message: message1, input } = {}) {
1012
- return ({ level, messgae: massage2, output } = {}) => {
1013
- if (systemLog && systemLog.systemLogHelper) {
1014
- systemLog.systemLogHelper.log({
1015
- batchId: systemLog.batchId,
1016
- label,
1017
- level,
1018
- message: massage2 || message1,
1019
- data: {
1020
- payload: {
1021
- input,
1022
- output
1023
- }
1024
- }
1025
- })
1026
- }
1027
- }
1028
- }
1029
-
1030
-
1031
-
1032
- ;// ./lib/models/repo/index.js
1033
-
1034
-
1035
-
1036
-
1037
- ;// ./lib/models/service/service.js
1038
-
1039
-
1040
-
1041
- class Service {
1042
- constructor({ repo }) {
1043
- this.repo = repo
1044
- }
1045
-
1046
- static get _classname() {
1047
- return 'Service'
1048
- }
1049
- static get _superclass() {
1050
- return 'Service'
1051
- }
1052
-
1053
- deleteOne({ id }) {
1054
- return this.repo.deleteOne({ id })
1055
- .catch(() => {
1056
- throw new Error(`Not found for query: ${id}`)
1057
- })
1058
- }
1059
-
1060
- async findAll({ query = {}, systemLog } = {}) {
1061
- const result = await this.repo.findAll({ query, systemLog })
1062
- return makeApiResponse({
1063
- repo: this.repo,
1064
- result
1065
- })
1066
- }
1067
-
1068
- async findOne({ query = {}, systemLog } = {}) {
1069
- const result = await this.repo.findOne({ query, systemLog })
1070
- return makeApiResponse({
1071
- repo: this.repo,
1072
- result
1073
- })
1074
- }
1075
-
1076
- init(options) {
1077
- return this.repo.init(options)
1078
- }
1079
- initFromArray(arr = []) {
1080
- if (Array.isArray(arr)) {
1081
- return arr.map((a) => this.init(a))
1082
- }
1083
- return []
1084
- }
1085
- initOnlyValidFromArray(arr = []) {
1086
- return this.initFromArray(arr).filter((i) => i)
1087
716
  }
1088
-
1089
- async saveAll({ docs = [], systemLog } = {}) {
1090
- const copies = docs.map((doc) => {
1091
- return this.init(doc)
1092
- })
1093
- const result = await this.repo.saveAll({ docs: copies, systemLog })
1094
- return makeApiResponse({
1095
- repo: this.repo,
1096
- result
1097
- })
717
+ if (data !== null && typeof data === 'object' && Object.keys(data).length === 0) {
718
+ return args[1]
1098
719
  }
1099
-
1100
- async saveOne({ doc = {}, systemLog } = {}) {
1101
- const copy = this.init(doc)
1102
- if (copy) {
1103
- const result = await this.repo.saveOne({ doc: copy, systemLog })
1104
- return makeApiResponse({
1105
- repo: this.repo,
1106
- result
1107
- })
1108
- }
1109
- return {
1110
- isNew: null,
1111
- data: [],
1112
- err: new Error('doc is not a valid instance')
1113
- }
720
+ if (Array.isArray(data) && data.length === 0) {
721
+ return args[1]
1114
722
  }
1115
- }
1116
-
1117
- function makeService({ repo }) {
1118
- if (repo === undefined) {
1119
- throw new Error('repo is required.')
723
+ if (typeof data === 'string' && data === '') {
724
+ return args[1]
1120
725
  }
1121
- if (repo._superclass !== Repo._superclass) {
1122
- throw new Error('repo is not an instance of Repo.')
726
+ if (data === null || data === undefined) {
727
+ return args[1]
1123
728
  }
1124
- return new Service({ repo })
729
+ return args[0]
1125
730
  }
1126
731
 
1127
732
 
1128
-
1129
- ;// ./lib/models/service/index.js
1130
-
1131
-
1132
-
1133
-
1134
- ;// ./lib/models/templateCompiler/templateCompilerException.js
1135
- const TEMPLATE_COMPILER_EXCEPTION_TYPE = {
1136
- argumentEmptyException: 'Argument is empty',
1137
- argumentFormatException: 'Incorrect number or format of argument',
1138
- invalidFuntionException: 'Function Name is invalid',
1139
- invalidRegExpException: 'Invalid regular expression',
1140
- isNotAFunctionException: 'Is not a function',
1141
- notExistException: 'Key does not exist',
1142
- resultEmptyException: 'Result is empty',
1143
- resultMoreThanOneException: 'More than one result'
1144
- }
1145
-
1146
- class TemplateCompilerException extends Error {
1147
- constructor(message) {
1148
- super(message)
1149
- this.message = message
733
+ ;// ./lib/models/templateCompiler/helpers/_join.js
734
+ function _join(data, delimiter) {
735
+ try {
736
+ if (data.length === 0) return ''
737
+ if (data.length === 1) return _stringifyObject(data[0])
738
+ return data.map((item) => _stringifyObject(item)).join(delimiter)
739
+ } catch (e) {
740
+ throw e
1150
741
  }
1151
742
  }
1152
743
 
1153
-
1154
-
1155
- ;// ./lib/models/templateCompiler/constants.js
1156
- const _EMPTY = '_EMPTY'
1157
- const _FN_NAMES = [
1158
- 'get', 'map', 'join', 'concatIf', 'exec', 'filterOne', 'filterAll', 'formatDate', 'eq', 'neq', 'gt', 'lt', 'gte', 'lte', 'isEmpty', 'isNotEmpty', 'toLowerCase', 'toUpperCase'
1159
- ]
1160
- const _HIDE = '_HIDE'
1161
- const _NOT_EMPTY = '_NOT_EMPTY'
1162
- const _SELF = '_SELF'
1163
- const TAGS_EJS = ['<%=', '%>']
1164
- const TAGS_HANDLEBAR = ['{{', '}}']
744
+ function _stringifyObject(obj) {
745
+ return JSON.stringify(obj).replace(/"([^"]+)":/g, '$1: ').replace(/"([^"]+)"/g, '$1').replace(/,/g, ', ')
746
+ }
1165
747
 
1166
748
 
1167
749
 
1168
- ;// ./lib/models/templateCompiler/helpers/_concatIf.js
750
+ ;// ./lib/models/templateCompiler/helpers/_lt.js
1169
751
 
1170
752
 
1171
753
 
1172
754
 
1173
- function _concatIf(data, args) {
1174
- if (typeof data !== 'string') {
1175
- throw new TemplateCompilerException(`_concatIf: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: the data must be string :${data.join(', ')}`)
1176
- }
755
+ function _lt(data, args) {
1177
756
  if (args.length !== 3) {
1178
- throw new TemplateCompilerException(`_concatIf: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: ${args.join(', ')}`)
757
+ throw new TemplateCompilerException(`_lt: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: ${args.join(', ')}`)
1179
758
  }
1180
759
  if (data === null || (typeof data === 'undefined')) {
1181
760
  return null
1182
761
  }
1183
- const [condition, success, failover] = args
1184
- const validConditions = [_EMPTY, _NOT_EMPTY]
1185
- if (validConditions.includes(condition) || success.length !== 2) {
1186
- throw new TemplateCompilerException(`concatIf: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentEmptyException}: ${condition}, ${success}`)
1187
- }
1188
- if (data === '' && failover.includes(_HIDE)) {
1189
- return ''
1190
- }
1191
- if (data !== '' && (data !== null || data !== undefined) && failover.includes(_HIDE)) {
1192
- return `${success[0]}${data}${success[success.length - 1]}`
762
+ if (args.includes(_SELF)) {
763
+ args = args.map((arg) => {
764
+ return (arg === _SELF) ? data : arg
765
+ })
1193
766
  }
1194
- return failover
767
+ const expected = args[0]
768
+ return data < expected ? args[1] : args[2]
1195
769
  }
1196
770
 
1197
771
 
1198
772
 
1199
- ;// ./lib/models/templateCompiler/helpers/_eq.js
773
+ ;// ./lib/models/templateCompiler/helpers/_lte.js
1200
774
 
1201
775
 
1202
776
 
1203
777
 
1204
- function _eq(data, args) {
778
+ function _lte(data, args) {
1205
779
  if (args.length !== 3) {
1206
- throw new TemplateCompilerException(`eq: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: ${args.join(', ')}`)
780
+ throw new TemplateCompilerException(`_lte: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: ${args.join(', ')}`)
1207
781
  }
1208
782
  if (data === null || (typeof data === 'undefined')) {
1209
783
  return null
@@ -1214,490 +788,389 @@ function _eq(data, args) {
1214
788
  })
1215
789
  }
1216
790
  const expected = args[0]
1217
- return data === expected ? args[1] : args[2]
791
+ return data <= expected ? args[1] : args[2]
1218
792
  }
1219
793
 
1220
794
 
1221
795
 
1222
- ;// ./lib/models/templateCompiler/helpers/_exec.js
1223
- function _exec(data, args) {
1224
- try {
1225
- const [methodName, ..._args] = args
1226
- return data[methodName](..._args)
1227
- } catch (e) {
1228
- throw e
1229
- }
1230
- }
1231
-
1232
-
796
+ ;// ./lib/models/templateCompiler/helpers/_map.js
1233
797
 
1234
- ;// ./lib/models/templateCompiler/helpers/_filterAll.js
1235
798
 
1236
799
 
1237
-
1238
- // const DELIMITER = '~~~'
1239
-
1240
- function _filterAll(data, args) {
800
+ function _map(data, args) {
1241
801
  try {
1242
- if (!Array.isArray(args) || args.length === 0) {
802
+ if (args.length === 0) {
1243
803
  throw new TemplateCompilerException(TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentEmptyException)
1244
804
  }
1245
- if (!Array.isArray(data) || data.length === 0) {
1246
- return []
1247
- }
1248
- if (typeof data[0] === 'object') {
1249
- return _existObject(data, args)
1250
- }
1251
- if (typeof data[0] === 'string' || typeof data[0] === 'number') {
1252
- return _exist(data, args)
805
+ if (data === null || (typeof data === 'undefined')) {
806
+ return null
1253
807
  }
1254
- return []
808
+
809
+ const result = data.reduce((acc, item) => {
810
+ if (args.length === 1 && Array.isArray(args[0])) {
811
+ args = args[0]
812
+ acc.hasFormat = true
813
+ }
814
+ const list = args.map((key) => {
815
+ if (key.includes('.')) {
816
+ const parts = key.split('.')
817
+ const first = parts[0]
818
+ parts.shift()
819
+ const remainingKey = parts.join('.')
820
+ return _get(item[first], remainingKey)
821
+ }
822
+ if (typeof item[key] !== 'undefined') {
823
+ return item[key]
824
+ }
825
+ return null
826
+ })
827
+ if (acc.hasFormat) {
828
+ acc.content.push(list)
829
+ } else {
830
+ acc.content = acc.content.concat(list)
831
+ }
832
+ return acc
833
+ }, {
834
+ content: [],
835
+ hasFormat: false
836
+ })
837
+ return result.content
1255
838
  } catch (e) {
1256
839
  throw e
1257
840
  }
1258
841
  }
1259
842
 
1260
- function _exist(data, args) {
1261
- const _args = args.flat()
1262
- return data.filter((e) => _args.some((arg) => _performOperation(arg, e)))
1263
- }
1264
843
 
1265
- function _existObject(data, args) {
1266
- if (args.length === 1) {
1267
- const arg = args[0]
1268
- return data.filter((e) => {
1269
- if (arg.includes('.')) {
1270
- return getValueByKeys(arg.split('.'), e)
1271
- }
1272
- return Object.prototype.hasOwnProperty.call(e, arg)
1273
- })
1274
- }
1275
844
 
1276
- if (args.length > 2) {
1277
- let res = data
1278
- for (let i = 0; i < args.length; i += 2) {
1279
- const group = [args[i], args[i + 1]]
1280
- res = _existObject(res, group)
1281
- }
1282
- return res
1283
- }
845
+ ;// ./lib/models/templateCompiler/helpers/_neq.js
1284
846
 
1285
- const [key, ..._argsArr] = args
1286
- const _args = _argsArr.flat()
1287
- return data.filter((e) => {
1288
- const value = key.includes('.') ? getValueByKeys(key.split('.'), e) : e[key]
1289
- return _args.some((arg) => _performOperation(arg, value))
1290
- })
1291
- }
1292
847
 
1293
- function _performOperation(arg, value) {
1294
- // the arg is undefined
1295
- if (arg === undefined && value === undefined) return true
1296
848
 
1297
- // the arg is null
1298
- if (arg === null && value === null) return true
1299
849
 
1300
- // the arg is boolean
1301
- if (typeof arg === 'boolean') {
1302
- return arg === value
850
+ function _neq(data, args) {
851
+ if (args.length !== 3) {
852
+ throw new TemplateCompilerException(`_neq: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: ${args.join(', ')}`)
1303
853
  }
1304
-
1305
- // the arg is blank or *: Blank => Empty, * => Not Empty
1306
- if (arg === '' || arg === '*') {
1307
- // null and undefined are not included in either case
1308
- if (value === null || value === undefined) {
1309
- return false
1310
- }
1311
- if (typeof value === 'string') {
1312
- return arg === '' ? value === '' : value !== ''
1313
- }
1314
- if (Array.isArray(value)) {
1315
- return arg === '' ? value.length === 0 : value.length !== 0
1316
- }
1317
- return arg !== ''
854
+ if (data === null || (typeof data === 'undefined')) {
855
+ return null
1318
856
  }
1319
-
1320
- // the arg is alphabetic or number
1321
- if (_isPureStringOrNumber(arg)) {
1322
- return arg === value
857
+ if (args.includes(_SELF)) {
858
+ args = args.map((arg) => {
859
+ return (arg === _SELF) ? data : arg
860
+ })
1323
861
  }
862
+ const expected = args[0]
863
+ return data !== expected ? args[1] : args[2]
864
+ }
1324
865
 
1325
- // the arg is array of [] or [*]: [] => Empty, [*] => Not Empty
1326
- if (arg.startsWith('[') && arg.endsWith(']')) {
1327
- if (arg === '[]') {
1328
- return Array.isArray(value) && value.length === 0
1329
- }
1330
- if (arg === '[*]') {
1331
- return Array.isArray(value) && value.length !== 0
1332
- }
1333
- return false
1334
- }
1335
866
 
1336
- // the arg is 'operator + string | number'
1337
- const { operator, value: argValue } = _splitOperator(arg)
1338
- if (!operator || (argValue !== 0 && !argValue)) {
1339
- return false
867
+
868
+ ;// ./lib/models/templateCompiler/helpers/_toLowerCase.js
869
+
870
+
871
+ function _toLowerCase(data, args) {
872
+ if (args !== undefined) {
873
+ throw new TemplateCompilerException(`_toLowerCase: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: ${args.join(', ')}`)
1340
874
  }
1341
- switch (operator) {
1342
- case '>':
1343
- return value > argValue
1344
- case '<':
1345
- return value < argValue
1346
- case '!=':
1347
- return value !== argValue
1348
- case '>=':
1349
- return value >= argValue
1350
- case '<=':
1351
- return value <= argValue
1352
- default:
1353
- return false
875
+ if (data === null || (typeof data === 'undefined') || typeof data !== 'string') {
876
+ return null
1354
877
  }
878
+ return String(data).toLowerCase()
1355
879
  }
1356
880
 
1357
- function _isPureStringOrNumber(input) {
1358
- if (typeof input === 'string') {
1359
- if (input.startsWith('[') && input.endsWith(']')) {
1360
- return false
1361
- }
1362
- if (/!=|>=|<=|>|</.test(input)) {
1363
- return false
1364
- }
1365
- return true
881
+
882
+
883
+ ;// ./lib/models/templateCompiler/helpers/_toUpperCase.js
884
+
885
+
886
+ function _toUpperCase(data, args) {
887
+ if (typeof data !== 'string') {
888
+ throw new TemplateCompilerException(`_toUpperCase: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: the data must be string: ${data}`)
1366
889
  }
1367
- return !Number.isNaN(input)
890
+ if (args !== undefined) {
891
+ throw new TemplateCompilerException(`_toUpperCase: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: the argument must be empty: ${args.join(', ')}`)
892
+ }
893
+ if (data === null || (typeof data === 'undefined') || typeof data !== 'string') {
894
+ return null
895
+ }
896
+ return String(data).toUpperCase()
1368
897
  }
1369
898
 
1370
- function _splitOperator(str) {
1371
- const operators = ['!=', '>=', '<=', '>', '<']
1372
899
 
1373
- const matchedOp = operators.find((op) => str.startsWith(op))
1374
- if (!matchedOp) return { operator: null, value: null }
1375
900
 
1376
- const remaining = str.slice(matchedOp.length)
901
+ ;// ./lib/models/templateCompiler/helpers/index.js
1377
902
 
1378
- // '>Primary' or '<Primary' is invalid
1379
- if (/^[a-zA-Z]*$/.test(remaining) && matchedOp !== '!=') {
1380
- return { operator: null, value: null }
1381
- }
1382
903
 
1383
- // if it is a number it is converted to a number
1384
- const value = (!Number.isNaN(parseFloat(remaining)) && !Number.isNaN(remaining)) ? Number(remaining) : remaining
1385
904
 
1386
- return {
1387
- operator: matchedOp,
1388
- value
1389
- }
1390
- }
1391
905
 
1392
906
 
1393
907
 
1394
- ;// ./lib/models/templateCompiler/helpers/_filterOne.js
1395
908
 
1396
909
 
1397
910
 
1398
- function _filterOne(data, args) {
1399
- try {
1400
- const list = _filterAll(data, args)
1401
- if (list.length === 1) {
1402
- return list[0]
1403
- }
1404
- if (list.length === 0) {
1405
- return null
1406
- }
1407
- throw new TemplateCompilerException(TEMPLATE_COMPILER_EXCEPTION_TYPE.resultMoreThanOneException)
1408
- } catch (e) {
1409
- throw e
1410
- }
1411
- }
1412
911
 
1413
912
 
1414
913
 
1415
- ;// ./lib/models/templateCompiler/helpers/_formatDate.js
1416
914
 
1417
915
 
1418
- function _formatDate(timestamp, format) {
1419
- if (format.length === 0) {
1420
- throw new TemplateCompilerException(`_formateDate: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: format parts must be not empty array`)
1421
- }
1422
916
 
1423
- if (timestamp === null || timestamp === undefined) {
1424
- return null
1425
- }
1426
917
 
1427
- const date = new Date(timestamp)
1428
918
 
1429
- const partsMap = {
1430
- yyyy: String(date.getFullYear()),
1431
- mm: String(date.getMonth() + 1).padStart(2, '0'),
1432
- dd: String(date.getDate()).padStart(2, '0')
1433
- }
1434
919
 
1435
- // Check for invalid format tokens
1436
- const validTokens = ['yyyy', 'mm', 'dd']
1437
- const invalidTokens = format.filter((part) => part.length > 1 && !validTokens.includes(part))
1438
920
 
1439
- if (invalidTokens.length > 0) {
1440
- throw new TemplateCompilerException(
1441
- `_formateDate: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: the format type is not valid: ${format.join(', ')}`
1442
- )
1443
- }
1444
921
 
1445
- // Build the formatted string using reduce
1446
- return format.reduce((result, part) => result + (partsMap[part] || part), '')
1447
- }
1448
922
 
923
+ ;// ./lib/models/templateCompiler/templateCompiler.js
1449
924
 
1450
925
 
1451
- ;// ./lib/models/templateCompiler/helpers/_get.js
1452
926
 
1453
927
 
1454
- function _get(data, key, failover = null) {
1455
- try {
1456
- if (key === null || (typeof key === 'undefined') || key === '') {
1457
- throw new TemplateCompilerException(TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentEmptyException)
1458
- }
1459
- if (data === null) {
1460
- return null
928
+ class TemplateCompiler {
929
+ constructor(data) {
930
+ this.data = data
931
+ }
932
+ static init(options) {
933
+ return new this(options)
934
+ }
935
+ static initFromArray(arr = []) {
936
+ if (Array.isArray(arr)) {
937
+ return arr.map((a) => this.init(a))
1461
938
  }
1462
- if (key.includes('.')) {
1463
- const parts = key.split('.')
1464
- if (parts.length > 1) {
1465
- const first = parts.shift()
1466
- const remainingKey = parts.join('.')
1467
- if (typeof data[first] !== 'undefined') {
1468
- return _get(data[first], remainingKey, failover)
1469
- }
1470
- return _handleFailover(key, failover)
1471
- }
1472
- }
1473
- if (typeof data[key] !== 'undefined') {
1474
- return data[key]
1475
- }
1476
- return _handleFailover(key, failover)
1477
- } catch (e) {
1478
- throw e
1479
- }
1480
- }
1481
-
1482
- function _handleFailover(key, failover) {
1483
- if (failover !== null) {
1484
- return failover
939
+ return []
1485
940
  }
1486
- return null
1487
- // throw new TemplateCompilerException(`Key "${key}" does not exist and no failover`)
1488
- }
1489
-
1490
-
1491
-
1492
- ;// ./lib/models/templateCompiler/helpers/_gt.js
1493
-
1494
-
1495
-
1496
-
1497
- function _gt(data, args) {
1498
- if (args.length !== 3) {
1499
- throw new TemplateCompilerException(`_gt: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: ${args.join(', ')}`)
941
+ static initOnlyValidFromArray(arr = []) {
942
+ return this.initFromArray(arr).filter((i) => i)
1500
943
  }
1501
- if (data === null || (typeof data === 'undefined')) {
1502
- return null
944
+ static concatIf(data, args) {
945
+ return _concatIf(data, args)
1503
946
  }
1504
- if (args.includes(_SELF)) {
1505
- args = args.map((arg) => {
1506
- return (arg === _SELF) ? data : arg
1507
- })
947
+ static eq(data, args) {
948
+ return _eq(data, args)
1508
949
  }
1509
- const expected = args[0]
1510
- return data > expected ? args[1] : args[2]
1511
- }
1512
-
1513
-
1514
-
1515
- ;// ./lib/models/templateCompiler/helpers/_gte.js
1516
-
1517
-
1518
950
 
951
+ static filterAll(data, args) {
952
+ return _filterAll(data, args)
953
+ }
1519
954
 
1520
- function _gte(data, args) {
1521
- if (args.length !== 3) {
1522
- throw new TemplateCompilerException(`_gte: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: ${args.join(', ')}`)
955
+ static formatDate(data, args) {
956
+ return _formatDate(data, args)
1523
957
  }
1524
- if (data === null || (typeof data === 'undefined')) {
1525
- return null
958
+
959
+ static get(data, key, failover = null) {
960
+ return _get(data, key, failover)
1526
961
  }
1527
- if (args.includes(_SELF)) {
1528
- args = args.map((arg) => {
1529
- return (arg === _SELF) ? data : arg
1530
- })
962
+ static gt(data, args) {
963
+ return _gt(data, args)
1531
964
  }
1532
- const expected = args[0]
1533
- return data >= expected ? args[1] : args[2]
1534
- }
1535
-
1536
-
1537
-
1538
- ;// ./lib/models/templateCompiler/helpers/_isEmpty.js
1539
-
1540
-
1541
-
1542
-
1543
- function _isEmpty(data, args) {
1544
- if (args.length !== 2) {
1545
- throw new TemplateCompilerException(`_isEmpty: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: ${args.join(', ')}`)
965
+ static gte(data, args) {
966
+ return _gte(data, args)
1546
967
  }
1547
- // if (data === null || (typeof data === 'undefined')) {
1548
- // return null
1549
- // }
1550
- if (args.includes(_SELF)) {
1551
- args = args.map((arg) => {
1552
- return (arg === _SELF) ? data : arg
1553
- })
968
+ static isEmpty(data, args) {
969
+ return _isEmpty(data, args)
1554
970
  }
1555
- if (data !== null && typeof data === 'object' && Object.keys(data).length === 0) {
1556
- return args[0]
971
+ static isNotEmpty(data, args) {
972
+ return _isNotEmpty(data, args)
1557
973
  }
1558
- return (data === '' || data === null || data === undefined || data.length === 0) ? args[0] : args[1]
1559
- }
1560
-
1561
-
1562
-
1563
- ;// ./lib/models/templateCompiler/helpers/_isNotEmpty.js
1564
-
1565
-
1566
-
1567
-
1568
- function _isNotEmpty(data, args) {
1569
- if (args.length !== 2) {
1570
- throw new TemplateCompilerException(`_isNotEmpty: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: ${args.join(', ')}`)
974
+ static join(data, separator = '') {
975
+ return _join(data, separator)
1571
976
  }
1572
- // if (data === null || (typeof data === 'undefined')) {
1573
- // return null
1574
- // }
1575
- if (args.includes(_SELF)) {
1576
- args = args.map((arg) => {
1577
- return (arg === _SELF) ? data : arg
1578
- })
977
+ static lt(data, args) {
978
+ return _lt(data, args)
1579
979
  }
1580
- if (data !== null && typeof data === 'object' && Object.keys(data).length === 0) {
1581
- return args[1]
980
+ static lte(data, args) {
981
+ return _lte(data, args)
1582
982
  }
1583
- if (Array.isArray(data) && data.length === 0) {
1584
- return args[1]
983
+ static map(data, args = []) {
984
+ return _map(data, args)
1585
985
  }
1586
- if (typeof data === 'string' && data === '') {
1587
- return args[1]
986
+ static neq(data, args) {
987
+ return _neq(data, args)
1588
988
  }
1589
- if (data === null || data === undefined) {
1590
- return args[1]
989
+ static toLowerCase(data, args) {
990
+ return _toLowerCase(data, args)
991
+ }
992
+ static toUpperCase(data, args) {
993
+ return _toUpperCase(data, args)
994
+ }
995
+ static parseFunction(expression) {
996
+ return _parseFunction(expression, _FN_NAMES)
1591
997
  }
1592
- return args[0]
1593
- }
1594
-
1595
998
 
1596
- ;// ./lib/models/templateCompiler/helpers/_join.js
1597
- function _join(data, delimiter) {
1598
- try {
1599
- if (data.length === 0) return ''
1600
- if (data.length === 1) return _stringifyObject(data[0])
1601
- return data.map((item) => _stringifyObject(item)).join(delimiter)
1602
- } catch (e) {
1603
- throw e
999
+ pipe(expression = '') {
1000
+ this.delimiters = expression.substring(0, 2) === '{{' ? TAGS_HANDLEBAR : TAGS_EJS
1001
+ const regex = new RegExp(`${this.delimiters[0]}\\s(.*?)\\s${this.delimiters[1]}`)
1002
+ const match = expression.match(regex)
1003
+ if (match !== null) {
1004
+ try {
1005
+ const functionList = _parseFunction(match[1], _FN_NAMES)
1006
+ return functionList.reduce((acc, fn) => {
1007
+ return _callFunction(acc, fn.name, fn.args)
1008
+ }, this.data)
1009
+ } catch (e) {
1010
+ throw new TemplateCompilerException(`TemplateCompiler engine error: ${e.message}`)
1011
+ }
1012
+ }
1013
+ throw new TemplateCompilerException(`TemplateCompiler engine error: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.invalidRegExpException}`)
1604
1014
  }
1605
1015
  }
1606
1016
 
1607
- function _stringifyObject(obj) {
1608
- return JSON.stringify(obj).replace(/"([^"]+)":/g, '$1: ').replace(/"([^"]+)"/g, '$1').replace(/,/g, ', ')
1017
+ function _parseFunction(expression, existFunctionNames) {
1018
+ const regExp = new RegExp(/(\w+)\(([^)]*)\)/)
1019
+ let parts
1020
+ if (expression.includes('|')) {
1021
+ parts = expression.split('|')
1022
+ } else {
1023
+ parts = [expression]
1024
+ }
1025
+ return parts.reduce((acc, part) => {
1026
+ const match = part.match(regExp)
1027
+ if (match !== null) {
1028
+ const functionName = match[1]
1029
+ const parameters = match[2]
1030
+ const paramList = _parseParams(parameters)
1031
+ if (existFunctionNames.includes(functionName)) {
1032
+ acc.push({
1033
+ name: functionName,
1034
+ args: paramList
1035
+ })
1036
+ } else {
1037
+ throw new TemplateCompilerException(`${functionName} is not a valid function`)
1038
+ }
1039
+ }
1040
+ return acc
1041
+ }, [])
1609
1042
  }
1610
1043
 
1611
-
1612
-
1613
- ;// ./lib/models/templateCompiler/helpers/_lt.js
1614
-
1615
-
1616
-
1617
-
1618
- function _lt(data, args) {
1619
- if (args.length !== 3) {
1620
- throw new TemplateCompilerException(`_lt: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: ${args.join(', ')}`)
1621
- }
1622
- if (data === null || (typeof data === 'undefined')) {
1623
- return null
1044
+ function _parseParams(parameters) {
1045
+ const _parameters = parameters.trim()
1046
+ const regExp = new RegExp(/^[^\w\d\s]+$/)
1047
+ const match = _parameters.match(regExp)
1048
+ if (match !== null) {
1049
+ return [_parameters.substring(1, _parameters.length - 1)]
1624
1050
  }
1625
- if (args.includes(_SELF)) {
1626
- args = args.map((arg) => {
1627
- return (arg === _SELF) ? data : arg
1628
- })
1051
+ if (_parameters.includes(',')) {
1052
+ // 用正则表达式匹配逗号,但忽略方括号中的逗号
1053
+ const parts = _splitIgnoringBrackets(_parameters)
1054
+ return parts.map((part) => _parseSinglePart(part))
1629
1055
  }
1630
- const expected = args[0]
1631
- return data < expected ? args[1] : args[2]
1056
+ return [_parseSinglePart(_parameters)]
1632
1057
  }
1633
1058
 
1059
+ function _splitIgnoringBrackets(input) {
1060
+ const regExp2 = new RegExp(/^\d+(\.\d+)?$/)
1061
+ const regExp = new RegExp(/(?![^\[]*\])\s*,\s*/)
1062
+ const parts = input.split(regExp)
1063
+ return parts.map((part) => {
1064
+ const _part = part.trim()
1065
+ if (_part !== '' && !!_part.match(regExp2)) {
1066
+ // 如果是数字,转换为 num 类型
1067
+ return Number.isNaN(_part) ? _part : parseInt(_part, 10)
1068
+ }
1069
+ // 否则当作字符串处理
1070
+ return _part
1071
+ })
1072
+ }
1634
1073
 
1074
+ function _parseSinglePart(input) {
1075
+ if (typeof input === 'string') {
1076
+ if (input.startsWith('"') && input.endsWith('"')) {
1077
+ // 去掉双引号,返回
1078
+ return input.substring(1, input.length - 1)
1079
+ }
1635
1080
 
1636
- ;// ./lib/models/templateCompiler/helpers/_lte.js
1637
-
1081
+ const _input = _toBasicType(input)
1638
1082
 
1083
+ if (typeof _input !== 'string') {
1084
+ return _input
1085
+ }
1639
1086
 
1087
+ // 如果是一个列表形式(例如 ["p", "d"] 或 [p, d])
1088
+ if (_input.startsWith('[') && _input.endsWith(']')) {
1089
+ const listContent = _input.substring(1, _input.length - 1).trim()
1090
+ if (listContent !== '') {
1091
+ return listContent.split(',').map((item) => {
1092
+ return _toBasicType(item.trim())
1093
+ })
1094
+ }
1095
+ return []
1096
+ }
1097
+ return input
1098
+ }
1099
+ return input
1100
+ }
1640
1101
 
1641
- function _lte(data, args) {
1642
- if (args.length !== 3) {
1643
- throw new TemplateCompilerException(`_lte: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: ${args.join(', ')}`)
1102
+ function _toBasicType(input) {
1103
+ if (input.startsWith('"') && input.endsWith('"')) {
1104
+ // 去掉双引号,返回
1105
+ return input.substring(1, input.length - 1)
1644
1106
  }
1645
- if (data === null || (typeof data === 'undefined')) {
1107
+ if (input === 'true') {
1108
+ return true
1109
+ }
1110
+ if (input === 'false') {
1111
+ return false
1112
+ }
1113
+ if (input === 'undefined') {
1114
+ return undefined
1115
+ }
1116
+ if (input === 'null') {
1646
1117
  return null
1647
1118
  }
1648
- if (args.includes(_SELF)) {
1649
- args = args.map((arg) => {
1650
- return (arg === _SELF) ? data : arg
1651
- })
1119
+ if (!Number.isNaN(input) && !Number.isNaN(Number.parseFloat(input))) {
1120
+ return Number(input)
1652
1121
  }
1653
- const expected = args[0]
1654
- return data <= expected ? args[1] : args[2]
1122
+ return input
1655
1123
  }
1656
1124
 
1657
-
1658
-
1659
- ;// ./lib/models/templateCompiler/helpers/_map.js
1660
-
1661
-
1662
-
1663
- function _map(data, args) {
1125
+ function _callFunction(data, functionName, parameters) {
1664
1126
  try {
1665
- if (args.length === 0) {
1666
- throw new TemplateCompilerException(TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentEmptyException)
1667
- }
1668
- if (data === null || (typeof data === 'undefined')) {
1669
- return null
1670
- }
1671
-
1672
- const result = data.reduce((acc, item) => {
1673
- if (args.length === 1 && Array.isArray(args[0])) {
1674
- args = args[0]
1675
- acc.hasFormat = true
1676
- }
1677
- const list = args.map((key) => {
1678
- if (key.includes('.')) {
1679
- const parts = key.split('.')
1680
- const first = parts[0]
1681
- parts.shift()
1682
- const remainingKey = parts.join('.')
1683
- return _get(item[first], remainingKey)
1127
+ let failover
1128
+ switch (functionName) {
1129
+ case 'exec':
1130
+ return _exec(data, parameters)
1131
+ case 'get':
1132
+ if (parameters.length > 2) {
1133
+ throw new TemplateCompilerException(TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException)
1684
1134
  }
1685
- if (typeof item[key] !== 'undefined') {
1686
- return item[key]
1135
+ if (parameters.length === 2) {
1136
+ failover = parameters[parameters.length - 1]
1687
1137
  }
1688
- return null
1689
- })
1690
- if (acc.hasFormat) {
1691
- acc.content.push(list)
1692
- } else {
1693
- acc.content = acc.content.concat(list)
1694
- }
1695
- return acc
1696
- }, {
1697
- content: [],
1698
- hasFormat: false
1699
- })
1700
- return result.content
1138
+ return _get(data, parameters[0], failover)
1139
+ case 'join':
1140
+ return _join(data, parameters[0])
1141
+ case 'map':
1142
+ return _map(data, parameters)
1143
+ case 'concatIf':
1144
+ return _concatIf(data, parameters)
1145
+ case 'filterOne':
1146
+ return _filterOne(data, parameters)
1147
+ case 'filterAll':
1148
+ return _filterAll(data, parameters)
1149
+ case 'formatDate':
1150
+ return _formatDate(data, parameters)
1151
+ case 'eq':
1152
+ return _eq(data, parameters)
1153
+ case 'neq':
1154
+ return _neq(data, parameters)
1155
+ case 'gt':
1156
+ return _gt(data, parameters)
1157
+ case 'gte':
1158
+ return _gte(data, parameters)
1159
+ case 'lt':
1160
+ return _lt(data, parameters)
1161
+ case 'lte':
1162
+ return _lte(data, parameters)
1163
+ case 'isEmpty':
1164
+ return _isEmpty(data, parameters)
1165
+ case 'isNotEmpty':
1166
+ return _isNotEmpty(data, parameters)
1167
+ case 'toLowerCase':
1168
+ return _toLowerCase(data)
1169
+ case 'toUpperCase':
1170
+ return _toUpperCase(data)
1171
+ default:
1172
+ throw new Error(`${functionName} is not a valid function`)
1173
+ }
1701
1174
  } catch (e) {
1702
1175
  throw e
1703
1176
  }
@@ -1705,343 +1178,952 @@ function _map(data, args) {
1705
1178
 
1706
1179
 
1707
1180
 
1708
- ;// ./lib/models/templateCompiler/helpers/_neq.js
1181
+ ;// ./lib/models/templateCompiler/index.js
1709
1182
 
1710
1183
 
1711
1184
 
1712
1185
 
1713
- function _neq(data, args) {
1714
- if (args.length !== 3) {
1715
- throw new TemplateCompilerException(`_neq: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: ${args.join(', ')}`)
1716
- }
1717
- if (data === null || (typeof data === 'undefined')) {
1718
- return null
1719
- }
1720
- if (args.includes(_SELF)) {
1721
- args = args.map((arg) => {
1722
- return (arg === _SELF) ? data : arg
1723
- })
1724
- }
1725
- const expected = args[0]
1726
- return data !== expected ? args[1] : args[2]
1727
- }
1186
+ ;// ./lib/helpers/concatStringByArray/concatStringByArray.js
1728
1187
 
1729
1188
 
1730
1189
 
1731
- ;// ./lib/models/templateCompiler/helpers/_toLowerCase.js
1732
1190
 
1733
1191
 
1734
- function _toLowerCase(data, args) {
1735
- if (args !== undefined) {
1736
- throw new TemplateCompilerException(`_toLowerCase: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: ${args.join(', ')}`)
1737
- }
1738
- if (data === null || (typeof data === 'undefined') || typeof data !== 'string') {
1739
- return null
1740
- }
1741
- return String(data).toLowerCase()
1192
+ function concatStringByArray(arrTemplate, data) {
1193
+ return arrTemplate.reduce((acc, item) => {
1194
+ const { type, value = '', restriction, template, format, showMinutes } = item
1195
+ switch (type) {
1196
+ case('label'): {
1197
+ if (getValidation(restriction, data, getValueByKeys)) {
1198
+ acc += (value.toString())
1199
+ }
1200
+ break
1201
+ }
1202
+ case('value'): {
1203
+ if (getValidation(restriction, data, getValueByKeys)) {
1204
+ const _value = getValueByKeys(value.split('.'), data) || ''
1205
+ acc += (_value.toString())
1206
+ }
1207
+ break
1208
+ }
1209
+ case('array'): {
1210
+ if (getValidation(restriction, data, getValueByKeys)) {
1211
+ const _value = getValueByKeys(value.split('.'), data) || []
1212
+ acc += _value.reduce((_acc, item) => {
1213
+ return _acc += concatStringByArray(template, item)
1214
+ }, '')
1215
+ }
1216
+ break
1217
+ }
1218
+ case('ellipsis'): {
1219
+ if (getValidation(restriction, data, getValueByKeys)) {
1220
+ const { maxLength } = item
1221
+ const _value = getValueByKeys(value.split('.'), data) || ''
1222
+ if (_value.length <= maxLength) {
1223
+ acc += (_value.toString())
1224
+ } else {
1225
+ acc += `${_value.substr(0, maxLength)}...`
1226
+ }
1227
+ }
1228
+ break
1229
+ }
1230
+ case ('date'): {
1231
+ if (getValidation(restriction, data, getValueByKeys)) {
1232
+ const _value = getValueByKeys(value.split('.'), data) || ''
1233
+ acc += (formatDate(_value, format).toString())
1234
+ }
1235
+ break
1236
+ }
1237
+ case ('templateCompiler'): {
1238
+ if (getValidation(restriction, data, getValueByKeys)) {
1239
+ const templateCompiler = new TemplateCompiler({ data })
1240
+ acc += templateCompiler.pipe(value)
1241
+ }
1242
+ break
1243
+ }
1244
+ }
1245
+ return acc
1246
+ }, '')
1742
1247
  }
1248
+ /* harmony default export */ const concatStringByArray_concatStringByArray = ({
1249
+ concatStringByArray
1250
+ });
1743
1251
 
1744
1252
 
1745
1253
 
1746
- ;// ./lib/models/templateCompiler/helpers/_toUpperCase.js
1254
+ ;// ./lib/helpers/concatStringByArray/index.js
1747
1255
 
1748
1256
 
1749
- function _toUpperCase(data, args) {
1750
- if (typeof data !== 'string') {
1751
- throw new TemplateCompilerException(`_toUpperCase: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: the data must be string: ${data}`)
1752
- }
1753
- if (args !== undefined) {
1754
- throw new TemplateCompilerException(`_toUpperCase: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: the argument must be empty: ${args.join(', ')}`)
1755
- }
1756
- if (data === null || (typeof data === 'undefined') || typeof data !== 'string') {
1757
- return null
1257
+ ;// ./lib/helpers/convertString/convertString.js
1258
+ function convertString(string, patternMatch = /\$\{(.+?)\}/g, value, getValueByKeys) {
1259
+ if (!string || typeof getValueByKeys !== 'function') {
1260
+ return ''
1758
1261
  }
1759
- return String(data).toUpperCase()
1262
+ const reg = new RegExp(patternMatch, 'g')
1263
+ return string.replace(reg, (match, key) => {
1264
+ const result = getValueByKeys({ keys: key.split('.'), obj: value })
1265
+ if (result === null || result === undefined) {
1266
+ return ''
1267
+ }
1268
+ return typeof result === 'object' ? JSON.stringify(result) : result
1269
+ })
1760
1270
  }
1761
1271
 
1272
+ /* harmony default export */ const convertString_convertString = ({
1273
+ convertString
1274
+ });
1762
1275
 
1763
1276
 
1764
- ;// ./lib/models/templateCompiler/helpers/index.js
1765
-
1766
-
1767
-
1768
-
1769
-
1770
-
1771
-
1772
-
1773
-
1774
-
1775
-
1776
-
1777
-
1778
-
1779
-
1780
-
1781
-
1782
-
1783
-
1784
-
1785
-
1786
- ;// ./lib/models/templateCompiler/templateCompiler.js
1787
-
1788
-
1789
-
1790
-
1791
- class TemplateCompiler {
1792
- constructor(data) {
1793
- this.data = data
1794
- }
1795
- static init(options) {
1796
- return new this(options)
1797
- }
1798
- static initFromArray(arr = []) {
1799
- if (Array.isArray(arr)) {
1800
- return arr.map((a) => this.init(a))
1801
- }
1802
- return []
1803
- }
1804
- static initOnlyValidFromArray(arr = []) {
1805
- return this.initFromArray(arr).filter((i) => i)
1806
- }
1807
- static concatIf(data, args) {
1808
- return _concatIf(data, args)
1809
- }
1810
- static eq(data, args) {
1811
- return _eq(data, args)
1812
- }
1277
+ ;// ./lib/helpers/convertString/index.js
1813
1278
 
1814
- static filterAll(data, args) {
1815
- return _filterAll(data, args)
1816
- }
1817
1279
 
1818
- static formatDate(data, args) {
1819
- return _formatDate(data, args)
1280
+ ;// ./lib/helpers/objectHelper/objectHelper.js
1281
+ const objectHelper = {
1282
+ get(obj, path) {
1283
+ const parts = path.split('.')
1284
+ return parts.reduce((acc, part) => {
1285
+ if (part.endsWith('[]')) {
1286
+ // 处理数组遍历
1287
+ const key = part.slice(0, -2) // 去掉 '[]' 得到属性名
1288
+ if (Array.isArray(acc[key])) {
1289
+ return acc[key] // 返回整个数组
1290
+ }
1291
+ return [] // 如果不是数组,返回空数组
1292
+ }
1293
+ if (part.includes('[') && part.includes(']')) {
1294
+ // 处理数组索引
1295
+ const arrayMatch = part.match(/(\w+)\[(\d+)\]/)
1296
+ if (arrayMatch) {
1297
+ const key = arrayMatch[1]
1298
+ const index = arrayMatch[2]
1299
+ return acc && acc[key] && acc[key][index]
1300
+ }
1301
+ } else if (acc && Array.isArray(acc)) {
1302
+ // 如果当前值是数组,提取每个对象的指定属性
1303
+ return acc.map((item) => item[part])
1304
+ } else {
1305
+ // 处理普通属性
1306
+ return acc && acc[part]
1307
+ }
1308
+ }, obj)
1309
+ },
1310
+ merge,
1311
+ set(obj, path, value) {
1312
+ const parts = path.split('.')
1313
+ let current = obj
1314
+ for (let i = 0; i < parts.length - 1; i++) {
1315
+ const part = parts[i]
1316
+ if (part.endsWith('[]')) {
1317
+ // 处理数组遍历
1318
+ const key = part.slice(0, -2) // 去掉 '[]' 得到属性名
1319
+ if (Array.isArray(current[key])) {
1320
+ current[key].forEach((item) => set(item, parts.slice(i + 1).join('.'), value))
1321
+ }
1322
+ return // 处理完数组后直接返回
1323
+ }
1324
+ if (part.includes('[') && part.includes(']')) {
1325
+ // 处理数组索引
1326
+ const arrayMatch = part.match(/(\w+)\[(\d+)\]/)
1327
+ if (arrayMatch) {
1328
+ const key = arrayMatch[1]
1329
+ const index = arrayMatch[2]
1330
+ if (Array.isArray(current[key]) && current[key][index]) {
1331
+ current = current[key][index]
1332
+ } else {
1333
+ return // 如果数组或索引不存在,直接返回
1334
+ }
1335
+ }
1336
+ } else {
1337
+ // 处理普通属性
1338
+ if (!current[part]) {
1339
+ current[part] = {} // 如果属性不存在,创建一个空对象
1340
+ }
1341
+ current = current[part]
1342
+ }
1343
+ }
1344
+
1345
+ // 设置最终属性值
1346
+ const lastPart = parts[parts.length - 1]
1347
+ current[lastPart] = value
1348
+ }
1349
+ }
1350
+
1351
+ function merge(target, ...sources) {
1352
+ if (!sources.length) return target
1353
+
1354
+ const source = sources.shift() // 取出第一个源对象
1355
+
1356
+ if (_isObject(target) && _isObject(source)) {
1357
+ for (const key in source) {
1358
+ if (_isObject(source[key])) {
1359
+ if (!target[key]) {
1360
+ // 如果目标对象没有该属性,创建一个空对象
1361
+ target[key] = {}
1362
+ }
1363
+ // 递归合并
1364
+ merge(target[key], source[key])
1365
+ } else {
1366
+ // 直接覆盖
1367
+ target[key] = source[key]
1368
+ }
1369
+ }
1370
+ }
1371
+
1372
+ // 继续合并剩余的源对象
1373
+ return merge(target, ...sources)
1374
+ }
1375
+
1376
+ function _isObject(obj) {
1377
+ return obj && typeof obj === 'object' && !Array.isArray(obj)
1378
+ }
1379
+
1380
+
1381
+
1382
+ ;// ./lib/helpers/objectHelper/index.js
1383
+
1384
+
1385
+
1386
+
1387
+ ;// ./lib/helpers/pReduce/pReduce.js
1388
+ async function pReduce(iterable, reducer, initialValue) {
1389
+ return new Promise((resolve, reject) => {
1390
+ const iterator = iterable[Symbol.iterator]()
1391
+ let index = 0
1392
+
1393
+ const next = async total => {
1394
+ const element = iterator.next()
1395
+
1396
+ if (element.done) {
1397
+ resolve(total)
1398
+ return
1399
+ }
1400
+
1401
+ try {
1402
+ const [resolvedTotal, resolvedValue] = await Promise.all([total, element.value])
1403
+ next(reducer(resolvedTotal, resolvedValue, index++))
1404
+ } catch (error) {
1405
+ reject(error)
1406
+ }
1407
+ }
1408
+
1409
+ next(initialValue)
1410
+ })
1411
+ }
1412
+
1413
+
1414
+
1415
+ ;// ./lib/models/apiResponse/apiResponse.js
1416
+ class ApiResponse {
1417
+ constructor(options = {}) {
1418
+ options = options || {}
1419
+ this._data = options.data || options._data || []
1420
+ this.err = options.err
1421
+ this.isNew = options.isNew || false
1422
+ this.message = options.message
1423
+ this.total = options.total || 0
1424
+ this._instanceBuilder = options._instanceBuilder
1425
+ }
1426
+
1427
+ static init(options = {}) {
1428
+ if (options instanceof this) {
1429
+ return options
1430
+ }
1431
+ const instance = new this(options)
1432
+ return instance
1433
+ }
1434
+ static get _classname() {
1435
+ return 'ApiResponse'
1436
+ }
1437
+ static get _superclass() {
1438
+ return 'ApiResponse'
1439
+ }
1440
+
1441
+ // getters
1442
+ get data() {
1443
+ if (this._instanceBuilder && (typeof this._instanceBuilder === 'function')) {
1444
+ return this._data.map(this._instanceBuilder)
1445
+ }
1446
+ return this._data
1447
+ }
1448
+ }
1449
+
1450
+
1451
+
1452
+ ;// ./lib/models/apiResponse/makeApiResponse.js
1453
+
1454
+
1455
+ function makeApiResponse({ repo, result }) {
1456
+ return ApiResponse.init({
1457
+ ...result,
1458
+ _instanceBuilder: (i) => {
1459
+ return repo.init(i)
1460
+ }
1461
+ })
1462
+ }
1463
+
1464
+
1465
+
1466
+ ;// ./lib/models/apiResponse/index.js
1467
+
1468
+
1469
+
1470
+
1471
+
1472
+ ;// ./lib/models/keyValueObject/keyValueObject.js
1473
+ class KeyValueObject {
1474
+ constructor(options = {}) {
1475
+ options = options || {}
1476
+ this.key = options.key || null
1477
+ this.value = (typeof options.value !== 'undefined') ? options.value : ''
1478
+ }
1479
+
1480
+ // Class methods
1481
+ static init(options = {}) {
1482
+ if (options instanceof this) {
1483
+ return options
1484
+ }
1485
+ const instance = new this(options)
1486
+ return instance.isValid ? instance : null
1487
+ }
1488
+ static initFromArray(arr = []) {
1489
+ if (Array.isArray(arr)) {
1490
+ return arr.map((a) => this.init(a))
1491
+ }
1492
+ return []
1493
+ }
1494
+ static initOnlyValidFromArray(arr = []) {
1495
+ return this.initFromArray(arr).filter((i) => i)
1496
+ }
1497
+ static get _classname() {
1498
+ return 'KeyValueObject'
1499
+ }
1500
+ static get _superclass() {
1501
+ return 'KeyValueObject'
1502
+ }
1503
+
1504
+ static addItem(arr, key, value) {
1505
+ arr.push(this.init({ key, value }))
1506
+ }
1507
+ static addRecord(arr = [], key, value) {
1508
+ if (!this.hasKeyValue(arr, key, value)) {
1509
+ arr.push(this.init({ key, value }))
1510
+ }
1511
+ return arr
1512
+ }
1513
+ static appendRecord(arr = [], key, value) {
1514
+ return arr.map((item) => {
1515
+ if (this.sameKey(item, key)) {
1516
+ item.value = [...item.value, ...value]
1517
+ }
1518
+ return item
1519
+ })
1520
+ }
1521
+ static appendValueArray(arr = [], key, value) {
1522
+ return arr.map((item) => {
1523
+ if (this.sameKey(item, key)) {
1524
+ item.value = [...item.value, ...value]
1525
+ }
1526
+ return item
1527
+ })
1528
+ }
1529
+ static foundByKey(arr = [], key) {
1530
+ const found = arr.find((m) => {
1531
+ return this.sameKey(m, key)
1532
+ })
1533
+ return found || null
1534
+ }
1535
+ static foundValueByKey(arr = [], key) {
1536
+ const found = this.foundByKey(arr, key)
1537
+ return found ? found.value : null
1538
+ }
1539
+ static fromObject(options = {}) {
1540
+ return Object.keys(options).reduce((acc, key) => {
1541
+ acc.push(this.init({ key, value: options[key] }))
1542
+ return acc
1543
+ }, [])
1544
+ }
1545
+ static getValueByKey(arr = [], key) {
1546
+ return this.foundValueByKey(arr, key)
1547
+ }
1548
+ static getValueByKeyFromArray(arr = [], key) {
1549
+ if (arr.length === 0) {
1550
+ return null
1551
+ }
1552
+ const firstArr = arr.shift()
1553
+ const found = firstArr.find((i) => {
1554
+ return this.sameKey(i, key)
1555
+ })
1556
+ if (found && found.value) {
1557
+ return found.value
1558
+ }
1559
+ return this.getValueByKeyFromArray(arr, key)
1560
+ }
1561
+ static getValuesByKey(arr = [], key) {
1562
+ return arr.reduce((acc, item) => {
1563
+ if (this.sameKey(item, key)) {
1564
+ acc.push(item.value)
1565
+ }
1566
+ return acc
1567
+ }, [])
1568
+ }
1569
+ static hasKeyValue(arr = [], key, value) {
1570
+ if (typeof value === 'undefined') {
1571
+ return arr.filter((item) => this.sameKey(item, key)).length > 0
1572
+ }
1573
+ return arr.filter((item) => (this.sameKey(item, key) && _isSame(item.value, value))).length > 0
1574
+ }
1575
+ static insertOrUpdateRecord(arr = [], key, value) {
1576
+ let copy = [...arr]
1577
+ if (!this.hasKeyValue(arr, key)) {
1578
+ copy.push(this.init({ key, value }))
1579
+ } else {
1580
+ copy = this.updateRecord(arr, key, value)
1581
+ }
1582
+ return copy
1583
+ }
1584
+ static keys(arr = []) {
1585
+ if (Array.isArray(arr)) {
1586
+ return arr.reduce((acc, item) => {
1587
+ acc.push(item.key)
1588
+ return acc
1589
+ }, [])
1590
+ }
1591
+ return []
1592
+ }
1593
+ static merge(toArr, fromArr) {
1594
+ (fromArr || []).map((from) => {
1595
+ const found = toArr.find((to) => {
1596
+ return to.key === from.key
1597
+ })
1598
+ if (found) {
1599
+ found.value = (found.value || []).concat(from.value)
1600
+ } else {
1601
+ toArr.push(from)
1602
+ }
1603
+ })
1604
+ return toArr
1605
+ }
1606
+ static removeByKey(arr, key) {
1607
+ return arr.reduce((acc, item) => {
1608
+ if (!this.sameKey(item, key)) {
1609
+ acc.push(item)
1610
+ }
1611
+ return acc
1612
+ }, [])
1613
+ }
1614
+ static sameKey(item, key) {
1615
+ return _isSame(item.key, key)
1616
+ }
1617
+ static toObject(arr = []) {
1618
+ if (Array.isArray(arr)) {
1619
+ return arr.reduce((acc, item) => {
1620
+ acc[item.key] = item.value
1621
+ return acc
1622
+ }, {})
1623
+ }
1624
+ return {}
1625
+ }
1626
+ static toString(arr = [], delimiter = '; ') {
1627
+ if (Array.isArray(arr)) {
1628
+ return arr.reduce((acc, item) => {
1629
+ acc.push(`${item.key}: ${item.value}`)
1630
+ return acc
1631
+ }, []).join(delimiter)
1632
+ }
1633
+ return ''
1634
+ }
1635
+ static updateRecord(arr = [], key, value) {
1636
+ return arr.map((item) => {
1637
+ if (this.sameKey(item, key)) {
1638
+ return {
1639
+ ...item,
1640
+ value
1641
+ }
1642
+ }
1643
+ return item
1644
+ })
1645
+ }
1646
+ static updateOrInsertRecord(arr = [], key, value) {
1647
+ return this.insertOrUpdateRecord(arr, key, value)
1648
+ }
1649
+ static updateRecordsFromArray(arr = [], updateArr = []) {
1650
+ if (Array.isArray(arr) && Array.isArray(updateArr)) {
1651
+ const obj1 = this.toObject(arr)
1652
+ const obj2 = this.toObject(updateArr)
1653
+ return this.fromObject({
1654
+ ...obj1,
1655
+ ...obj2
1656
+ })
1657
+ }
1658
+ return []
1659
+ }
1660
+ static values(arr = []) {
1661
+ if (Array.isArray(arr)) {
1662
+ return arr.reduce((acc, item) => {
1663
+ acc.push(item.value)
1664
+ return acc
1665
+ }, [])
1666
+ }
1667
+ return []
1668
+ }
1669
+
1670
+ // getters
1671
+ get isValid() {
1672
+ return !!this.key
1673
+ }
1674
+
1675
+ get toObject() {
1676
+ const obj = {}
1677
+ if (this.isValid) {
1678
+ obj[this.key] = this.value
1679
+ }
1680
+ return obj
1681
+ }
1682
+ }
1683
+
1684
+ function _isSame(key1, key2) {
1685
+ return key1 === key2
1686
+ }
1687
+
1688
+
1689
+
1690
+ ;// ./lib/models/keyValueObject/index.js
1691
+
1692
+
1693
+
1694
+
1695
+ ;// ./lib/helpers/stringFormatter/stringFormatter.js
1696
+ function stringFormatter(str, delimiter = '_') {
1697
+ if (str === null || typeof str === 'undefined' || typeof str.toString === 'undefined') {
1698
+ return null
1699
+ }
1700
+ return str.toString()
1701
+ .trim()
1702
+ .toUpperCase()
1703
+ .replace('-', delimiter)
1704
+ .replace(' ', delimiter)
1705
+ }
1706
+
1707
+
1708
+
1709
+ ;// ./lib/models/metadata/metadata.js
1710
+
1711
+
1712
+
1713
+ const DELIMITER = '_'
1714
+
1715
+ class Metadata extends KeyValueObject {
1716
+ static init(options = {}) {
1717
+ if (options instanceof this) {
1718
+ return options
1719
+ }
1720
+ const instance = new this({
1721
+ ...options,
1722
+ key: stringFormatter(options.key, DELIMITER),
1723
+ })
1724
+ return instance.isValid ? instance : null
1725
+ }
1726
+ static get _classname() {
1727
+ return 'Metadata'
1728
+ }
1729
+
1730
+ static merge(toArr, fromArr) {
1731
+ (fromArr || []).map((from) => {
1732
+ const found = toArr.find((to) => {
1733
+ return metadata_isSame(to.key, from.key)
1734
+ })
1735
+ if (found) {
1736
+ found.value = (found.value || []).concat(from.value)
1737
+ } else {
1738
+ toArr.push(from)
1739
+ }
1740
+ })
1741
+ return toArr
1742
+ }
1743
+ static sameKey(item, key) {
1744
+ return metadata_isSame(item.key, key)
1745
+ }
1746
+ }
1747
+
1748
+ function metadata_isSame(key1, key2) {
1749
+ return stringFormatter(key1, DELIMITER) === stringFormatter(key2, DELIMITER)
1750
+ }
1751
+
1752
+
1753
+
1754
+ ;// ./lib/models/metadata/index.js
1755
+
1756
+
1757
+
1758
+
1759
+ ;// ./lib/models/qMeta/qMeta.js
1760
+
1761
+
1762
+ const updateAllowedProps = [
1763
+ 'attributes',
1764
+ 'ref'
1765
+ ]
1766
+
1767
+ class QMeta {
1768
+ constructor(options = {}) {
1769
+ options = options || {}
1770
+ this.attributes = KeyValueObject.initOnlyValidFromArray(options.attributes)
1771
+ this.ref = options.ref || {}
1820
1772
  }
1821
-
1822
- static get(data, key, failover = null) {
1823
- return _get(data, key, failover)
1773
+
1774
+ static get _classname() {
1775
+ return 'QMeta'
1824
1776
  }
1825
- static gt(data, args) {
1826
- return _gt(data, args)
1777
+ static get _superclass() {
1778
+ return 'QMeta'
1827
1779
  }
1828
- static gte(data, args) {
1829
- return _gte(data, args)
1780
+
1781
+ // Class methods
1782
+ static init(options = {}) {
1783
+ if (options instanceof QMeta) {
1784
+ return options
1785
+ }
1786
+ return new QMeta(options)
1830
1787
  }
1831
- static isEmpty(data, args) {
1832
- return _isEmpty(data, args)
1788
+
1789
+ // instance methods
1790
+ addAttribute(obj) {
1791
+ const kvObject = KeyValueObject.init(obj)
1792
+ if (!kvObject) {
1793
+ throw new Error('invalid meta attribute')
1794
+ }
1795
+ this.attributes.push(kvObject)
1796
+ return this
1833
1797
  }
1834
- static isNotEmpty(data, args) {
1835
- return _isNotEmpty(data, args)
1798
+
1799
+ update(obj) {
1800
+ Object.keys(obj).forEach((key) => {
1801
+ if (updateAllowedProps.includes(key)) {
1802
+ if (key === 'attributes') {
1803
+ this[key] = KeyValueObject.initOnlyValidFromArray(obj[key])
1804
+ } else {
1805
+ this[key] = obj[key]
1806
+ }
1807
+ }
1808
+ })
1809
+ return this
1836
1810
  }
1837
- static join(data, separator = '') {
1838
- return _join(data, separator)
1811
+ }
1812
+
1813
+
1814
+
1815
+ ;// ./lib/models/qMeta/index.js
1816
+
1817
+
1818
+
1819
+
1820
+ ;// ./lib/models/repo/repo.js
1821
+ class Repo {
1822
+ constructor(options) {
1823
+ options = options || {}
1824
+ this.model = options.model
1825
+ this._sharedOptions = options._sharedOptions // { session: this.dbTransaction }
1826
+ this._queryOptions = options._queryOptions
1827
+ this._saveOptions = options._saveOptions
1828
+ this._Class = options._constructor && options._constructor._Class
1829
+ ? options._constructor._Class
1830
+ : null
1839
1831
  }
1840
- static lt(data, args) {
1841
- return _lt(data, args)
1832
+ static init(options = {}) {
1833
+ if (options instanceof this) {
1834
+ return options
1835
+ }
1836
+ const instance = new this(options)
1837
+ return instance.isValid ? instance : null
1842
1838
  }
1843
- static lte(data, args) {
1844
- return _lte(data, args)
1839
+ static get _classname() {
1840
+ return 'Repo'
1845
1841
  }
1846
- static map(data, args = []) {
1847
- return _map(data, args)
1842
+ static get _superclass() {
1843
+ return 'Repo'
1848
1844
  }
1849
- static neq(data, args) {
1850
- return _neq(data, args)
1845
+
1846
+ get _classname() {
1847
+ return 'Repo'
1851
1848
  }
1852
- static toLowerCase(data, args) {
1853
- return _toLowerCase(data, args)
1849
+
1850
+ get _superclass() {
1851
+ return 'Repo'
1854
1852
  }
1855
- static toUpperCase(data, args) {
1856
- return _toUpperCase(data, args)
1853
+
1854
+ get isValid() {
1855
+ return this.model
1856
+ && (typeof this.model.deleteOne === 'function')
1857
+ && (typeof this.model.findAll === 'function')
1858
+ && (typeof this.model.saveOne === 'function')
1857
1859
  }
1858
- static parseFunction(expression) {
1859
- return _parseFunction(expression, _FN_NAMES)
1860
+
1861
+ get queryOptions() {
1862
+ return {
1863
+ ...this._sharedOptions,
1864
+ ...this._queryOptions,
1865
+ }
1866
+ }
1867
+
1868
+ get saveOptions() {
1869
+ return {
1870
+ ...this._sharedOptions,
1871
+ ...this._saveOptions,
1872
+ }
1873
+ }
1874
+
1875
+ init(options) {
1876
+ if (this._Class && typeof this._Class.init === 'function') {
1877
+ return this._Class.init(options)
1878
+ }
1879
+ return options
1880
+ }
1881
+
1882
+ async deleteOne({ id }) {
1883
+ try {
1884
+ const result = await this.model.deleteOne({ _id: id })
1885
+ return {
1886
+ ...result, // { message: 'ok', total }
1887
+ isNew: false,
1888
+ data: []
1889
+ }
1890
+ } catch (err) {
1891
+ throw err
1892
+ }
1893
+ }
1894
+
1895
+ // systemLog is optional
1896
+ findAll({ query, systemLog }) {
1897
+ const log = _makeLog({
1898
+ systemLog,
1899
+ label: 'REPO_READ',
1900
+ message: `fn ${this._classname}.prototype.findAll`,
1901
+ input: [{ query: { ...query }, systemLog: { ...systemLog } }]
1902
+ })
1903
+ return new Promise((resolve, reject) => {
1904
+ this.model.findAll(query, this.queryOptions, (err, data, total) => {
1905
+ if (err) {
1906
+ log({ level: 'warn', output: err.toString() })
1907
+ reject(err)
1908
+ } else {
1909
+ const result = {
1910
+ isNew: false,
1911
+ data,
1912
+ total: total || data.length
1913
+ }
1914
+ log({ level: 'info', output: { ...result } })
1915
+ resolve(result)
1916
+ }
1917
+ })
1918
+ })
1919
+ }
1920
+
1921
+ findOne({ query, systemLog }) {
1922
+ const log = _makeLog({
1923
+ systemLog,
1924
+ label: 'REPO_READ',
1925
+ message: `fn ${this._classname}.prototype.findOne`,
1926
+ input: [{ query: { ...query }, systemLog: { ...systemLog } }]
1927
+ })
1928
+ return new Promise((resolve, reject) => {
1929
+ this.model.findAll(query, this.queryOptions, (err, data) => {
1930
+ if (err) {
1931
+ reject(err)
1932
+ } else if (data.length === 1) {
1933
+ const result = {
1934
+ isNew: false,
1935
+ data,
1936
+ total: 1
1937
+ }
1938
+ log({ level: 'info', output: { ...result } })
1939
+ resolve(result)
1940
+ } else if (data.length === 0) {
1941
+ reject(new Error('record not found'))
1942
+ } else {
1943
+ reject(new Error('more than one is found'))
1944
+ }
1945
+ })
1946
+ })
1947
+ .catch((err) => {
1948
+ log({ level: 'warn', output: err.toString() })
1949
+ throw err
1950
+ })
1951
+ }
1952
+
1953
+ saveAll({ docs, systemLog }) {
1954
+ let isNew
1955
+ const log = _makeLog({
1956
+ systemLog,
1957
+ label: 'REPO_WRITE',
1958
+ message: `fn ${this._classname}.prototype.saveAll`,
1959
+ input: [{ docs: [...docs], systemLog: { ...systemLog } }]
1960
+ })
1961
+ const promise = typeof this.model.saveAll === 'function'
1962
+ ? this.model.saveAll({ docs })
1963
+ : Promise.all(docs.map(async (doc) => {
1964
+ if (doc) {
1965
+ const result = await this.saveOne({ doc })
1966
+ isNew = result.isNew
1967
+ const _data = result._data || result.data
1968
+ return _data[0]
1969
+ }
1970
+ return null
1971
+ }))
1972
+ return promise.then((savedData) => {
1973
+ if (savedData.length !== 1) isNew = null
1974
+ const result = {
1975
+ data: savedData,
1976
+ isNew,
1977
+ total: savedData.length
1978
+ }
1979
+ log({ level: 'info', output: { ...result } })
1980
+ return result
1981
+ }).catch((err) => {
1982
+ log({ level: 'warn', output: err.toString() })
1983
+ throw err
1984
+ })
1985
+ }
1986
+
1987
+ saveOne({ doc, systemLog }) {
1988
+ const log = _makeLog({
1989
+ systemLog,
1990
+ label: 'REPO_WRITE',
1991
+ message: `fn ${this._classname}.prototype.saveOne`,
1992
+ input: [{ doc: { ...doc }, systemLog: { ...systemLog } }]
1993
+ })
1994
+ return new Promise((resolve, reject) => {
1995
+ this.model.saveOne(doc, this.saveOptions, (err, result) => {
1996
+ if (err) {
1997
+ log({ level: 'warn', output: err.toString() })
1998
+ reject(err)
1999
+ } else {
2000
+ log({ level: 'info', output: { ...result } })
2001
+ resolve(result)
2002
+ }
2003
+ })
2004
+ })
1860
2005
  }
2006
+ }
1861
2007
 
1862
- pipe(expression = '') {
1863
- this.delimiters = expression.substring(0, 2) === '{{' ? TAGS_HANDLEBAR : TAGS_EJS
1864
- const regex = new RegExp(`${this.delimiters[0]}\\s(.*?)\\s${this.delimiters[1]}`)
1865
- const match = expression.match(regex)
1866
- if (match !== null) {
1867
- try {
1868
- const functionList = _parseFunction(match[1], _FN_NAMES)
1869
- return functionList.reduce((acc, fn) => {
1870
- return _callFunction(acc, fn.name, fn.args)
1871
- }, this.data)
1872
- } catch (e) {
1873
- throw new TemplateCompilerException(`TemplateCompiler engine error: ${e.message}`)
1874
- }
2008
+ function _makeLog({ systemLog, label, message: message1, input } = {}) {
2009
+ return ({ level, messgae: massage2, output } = {}) => {
2010
+ if (systemLog && systemLog.systemLogHelper) {
2011
+ systemLog.systemLogHelper.log({
2012
+ batchId: systemLog.batchId,
2013
+ label,
2014
+ level,
2015
+ message: massage2 || message1,
2016
+ data: {
2017
+ payload: {
2018
+ input,
2019
+ output
2020
+ }
2021
+ }
2022
+ })
1875
2023
  }
1876
- throw new TemplateCompilerException(`TemplateCompiler engine error: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.invalidRegExpException}`)
1877
2024
  }
1878
2025
  }
1879
2026
 
1880
- function _parseFunction(expression, existFunctionNames) {
1881
- const regExp = new RegExp(/(\w+)\(([^)]*)\)/)
1882
- let parts
1883
- if (expression.includes('|')) {
1884
- parts = expression.split('|')
1885
- } else {
1886
- parts = [expression]
1887
- }
1888
- return parts.reduce((acc, part) => {
1889
- const match = part.match(regExp)
1890
- if (match !== null) {
1891
- const functionName = match[1]
1892
- const parameters = match[2]
1893
- const paramList = _parseParams(parameters)
1894
- if (existFunctionNames.includes(functionName)) {
1895
- acc.push({
1896
- name: functionName,
1897
- args: paramList
1898
- })
1899
- } else {
1900
- throw new TemplateCompilerException(`${functionName} is not a valid function`)
1901
- }
1902
- }
1903
- return acc
1904
- }, [])
1905
- }
1906
2027
 
1907
- function _parseParams(parameters) {
1908
- const _parameters = parameters.trim()
1909
- const regExp = new RegExp(/^[^\w\d\s]+$/)
1910
- const match = _parameters.match(regExp)
1911
- if (match !== null) {
1912
- return [_parameters.substring(1, _parameters.length - 1)]
1913
- }
1914
- if (_parameters.includes(',')) {
1915
- // 用正则表达式匹配逗号,但忽略方括号中的逗号
1916
- const parts = _splitIgnoringBrackets(_parameters)
1917
- return parts.map((part) => _parseSinglePart(part))
1918
- }
1919
- return [_parseSinglePart(_parameters)]
1920
- }
1921
2028
 
1922
- function _splitIgnoringBrackets(input) {
1923
- const regExp2 = new RegExp(/^\d+(\.\d+)?$/)
1924
- const regExp = new RegExp(/(?![^\[]*\])\s*,\s*/)
1925
- const parts = input.split(regExp)
1926
- return parts.map((part) => {
1927
- const _part = part.trim()
1928
- if (_part !== '' && !!_part.match(regExp2)) {
1929
- // 如果是数字,转换为 num 类型
1930
- return Number.isNaN(_part) ? _part : parseInt(_part, 10)
1931
- }
1932
- // 否则当作字符串处理
1933
- return _part
1934
- })
1935
- }
2029
+ ;// ./lib/models/repo/index.js
1936
2030
 
1937
- function _parseSinglePart(input) {
1938
- if (typeof input === 'string') {
1939
- if (input.startsWith('"') && input.endsWith('"')) {
1940
- // 去掉双引号,返回
1941
- return input.substring(1, input.length - 1)
1942
- }
1943
2031
 
1944
- const _input = _toBasicType(input)
1945
2032
 
1946
- if (typeof _input !== 'string') {
1947
- return _input
1948
- }
1949
2033
 
1950
- // 如果是一个列表形式(例如 ["p", "d"] 或 [p, d])
1951
- if (_input.startsWith('[') && _input.endsWith(']')) {
1952
- const listContent = _input.substring(1, _input.length - 1).trim()
1953
- if (listContent !== '') {
1954
- return listContent.split(',').map((item) => {
1955
- return _toBasicType(item.trim())
1956
- })
1957
- }
1958
- return []
1959
- }
1960
- return input
2034
+ ;// ./lib/models/service/service.js
2035
+
2036
+
2037
+
2038
+ class Service {
2039
+ constructor({ repo }) {
2040
+ this.repo = repo
1961
2041
  }
1962
- return input
1963
- }
1964
2042
 
1965
- function _toBasicType(input) {
1966
- if (input.startsWith('"') && input.endsWith('"')) {
1967
- // 去掉双引号,返回
1968
- return input.substring(1, input.length - 1)
2043
+ static get _classname() {
2044
+ return 'Service'
1969
2045
  }
1970
- if (input === 'true') {
1971
- return true
2046
+ static get _superclass() {
2047
+ return 'Service'
1972
2048
  }
1973
- if (input === 'false') {
1974
- return false
2049
+
2050
+ deleteOne({ id }) {
2051
+ return this.repo.deleteOne({ id })
2052
+ .catch(() => {
2053
+ throw new Error(`Not found for query: ${id}`)
2054
+ })
1975
2055
  }
1976
- if (input === 'undefined') {
1977
- return undefined
2056
+
2057
+ async findAll({ query = {}, systemLog } = {}) {
2058
+ const result = await this.repo.findAll({ query, systemLog })
2059
+ return makeApiResponse({
2060
+ repo: this.repo,
2061
+ result
2062
+ })
1978
2063
  }
1979
- if (input === 'null') {
1980
- return null
2064
+
2065
+ async findOne({ query = {}, systemLog } = {}) {
2066
+ const result = await this.repo.findOne({ query, systemLog })
2067
+ return makeApiResponse({
2068
+ repo: this.repo,
2069
+ result
2070
+ })
1981
2071
  }
1982
- if (!Number.isNaN(input) && !Number.isNaN(Number.parseFloat(input))) {
1983
- return Number(input)
2072
+
2073
+ init(options) {
2074
+ return this.repo.init(options)
2075
+ }
2076
+ initFromArray(arr = []) {
2077
+ if (Array.isArray(arr)) {
2078
+ return arr.map((a) => this.init(a))
2079
+ }
2080
+ return []
2081
+ }
2082
+ initOnlyValidFromArray(arr = []) {
2083
+ return this.initFromArray(arr).filter((i) => i)
1984
2084
  }
1985
- return input
1986
- }
1987
2085
 
1988
- function _callFunction(data, functionName, parameters) {
1989
- try {
1990
- let failover
1991
- switch (functionName) {
1992
- case 'exec':
1993
- return _exec(data, parameters)
1994
- case 'get':
1995
- if (parameters.length > 2) {
1996
- throw new TemplateCompilerException(TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException)
1997
- }
1998
- if (parameters.length === 2) {
1999
- failover = parameters[parameters.length - 1]
2000
- }
2001
- return _get(data, parameters[0], failover)
2002
- case 'join':
2003
- return _join(data, parameters[0])
2004
- case 'map':
2005
- return _map(data, parameters)
2006
- case 'concatIf':
2007
- return _concatIf(data, parameters)
2008
- case 'filterOne':
2009
- return _filterOne(data, parameters)
2010
- case 'filterAll':
2011
- return _filterAll(data, parameters)
2012
- case 'formatDate':
2013
- return _formatDate(data, parameters)
2014
- case 'eq':
2015
- return _eq(data, parameters)
2016
- case 'neq':
2017
- return _neq(data, parameters)
2018
- case 'gt':
2019
- return _gt(data, parameters)
2020
- case 'gte':
2021
- return _gte(data, parameters)
2022
- case 'lt':
2023
- return _lt(data, parameters)
2024
- case 'lte':
2025
- return _lte(data, parameters)
2026
- case 'isEmpty':
2027
- return _isEmpty(data, parameters)
2028
- case 'isNotEmpty':
2029
- return _isNotEmpty(data, parameters)
2030
- case 'toLowerCase':
2031
- return _toLowerCase(data)
2032
- case 'toUpperCase':
2033
- return _toUpperCase(data)
2034
- default:
2035
- throw new Error(`${functionName} is not a valid function`)
2086
+ async saveAll({ docs = [], systemLog } = {}) {
2087
+ const copies = docs.map((doc) => {
2088
+ return this.init(doc)
2089
+ })
2090
+ const result = await this.repo.saveAll({ docs: copies, systemLog })
2091
+ return makeApiResponse({
2092
+ repo: this.repo,
2093
+ result
2094
+ })
2095
+ }
2096
+
2097
+ async saveOne({ doc = {}, systemLog } = {}) {
2098
+ const copy = this.init(doc)
2099
+ if (copy) {
2100
+ const result = await this.repo.saveOne({ doc: copy, systemLog })
2101
+ return makeApiResponse({
2102
+ repo: this.repo,
2103
+ result
2104
+ })
2036
2105
  }
2037
- } catch (e) {
2038
- throw e
2106
+ return {
2107
+ isNew: null,
2108
+ data: [],
2109
+ err: new Error('doc is not a valid instance')
2110
+ }
2111
+ }
2112
+ }
2113
+
2114
+ function makeService({ repo }) {
2115
+ if (repo === undefined) {
2116
+ throw new Error('repo is required.')
2117
+ }
2118
+ if (repo._superclass !== Repo._superclass) {
2119
+ throw new Error('repo is not an instance of Repo.')
2039
2120
  }
2121
+ return new Service({ repo })
2040
2122
  }
2041
2123
 
2042
2124
 
2043
2125
 
2044
- ;// ./lib/models/templateCompiler/index.js
2126
+ ;// ./lib/models/service/index.js
2045
2127
 
2046
2128
 
2047
2129
 
@@ -2290,6 +2372,7 @@ const stringHelper = {
2290
2372
 
2291
2373
 
2292
2374
 
2375
+
2293
2376
  ;// ./lib/index.js
2294
2377
 
2295
2378
 
@@ -2305,6 +2388,7 @@ var __webpack_exports__Repo = __webpack_exports__.lc;
2305
2388
  var __webpack_exports__Service = __webpack_exports__.kl;
2306
2389
  var __webpack_exports__TemplateCompiler = __webpack_exports__.Mg;
2307
2390
  var __webpack_exports__UniqueKeyGenerator = __webpack_exports__._x;
2391
+ var __webpack_exports__concatStringByArray = __webpack_exports__.yl;
2308
2392
  var __webpack_exports__convertString = __webpack_exports__.l0;
2309
2393
  var __webpack_exports__formatDate = __webpack_exports__.Yq;
2310
2394
  var __webpack_exports__generalPost = __webpack_exports__.zn;
@@ -2317,4 +2401,4 @@ var __webpack_exports__pReduce = __webpack_exports__.d;
2317
2401
  var __webpack_exports__padZeros = __webpack_exports__.Lv;
2318
2402
  var __webpack_exports__stringFormatter = __webpack_exports__.Qy;
2319
2403
  var __webpack_exports__stringHelper = __webpack_exports__.yO;
2320
- export { __webpack_exports__ApiResponse as ApiResponse, __webpack_exports__KeyValueObject as KeyValueObject, __webpack_exports__Metadata as Metadata, __webpack_exports__QMeta as QMeta, __webpack_exports__Repo as Repo, __webpack_exports__Service as Service, __webpack_exports__TemplateCompiler as TemplateCompiler, __webpack_exports__UniqueKeyGenerator as UniqueKeyGenerator, __webpack_exports__convertString as convertString, __webpack_exports__formatDate as formatDate, __webpack_exports__generalPost as generalPost, __webpack_exports__getValidation as getValidation, __webpack_exports__getValueByKeys as getValueByKeys, __webpack_exports__makeApiResponse as makeApiResponse, __webpack_exports__makeService as makeService, __webpack_exports__objectHelper as objectHelper, __webpack_exports__pReduce as pReduce, __webpack_exports__padZeros as padZeros, __webpack_exports__stringFormatter as stringFormatter, __webpack_exports__stringHelper as stringHelper };
2404
+ export { __webpack_exports__ApiResponse as ApiResponse, __webpack_exports__KeyValueObject as KeyValueObject, __webpack_exports__Metadata as Metadata, __webpack_exports__QMeta as QMeta, __webpack_exports__Repo as Repo, __webpack_exports__Service as Service, __webpack_exports__TemplateCompiler as TemplateCompiler, __webpack_exports__UniqueKeyGenerator as UniqueKeyGenerator, __webpack_exports__concatStringByArray as concatStringByArray, __webpack_exports__convertString as convertString, __webpack_exports__formatDate as formatDate, __webpack_exports__generalPost as generalPost, __webpack_exports__getValidation as getValidation, __webpack_exports__getValueByKeys as getValueByKeys, __webpack_exports__makeApiResponse as makeApiResponse, __webpack_exports__makeService as makeService, __webpack_exports__objectHelper as objectHelper, __webpack_exports__pReduce as pReduce, __webpack_exports__padZeros as padZeros, __webpack_exports__stringFormatter as stringFormatter, __webpack_exports__stringHelper as stringHelper };