@questwork/q-utilities 0.1.10 → 0.1.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.min.js CHANGED
@@ -32,11 +32,12 @@ __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),
38
39
  G8: () => (/* reexport */ getValidation),
39
- pY: () => (/* reexport */ getValueByKeys),
40
+ pY: () => (/* reexport */ getValueByKeys_getValueByKeys),
40
41
  su: () => (/* reexport */ makeApiResponse),
41
42
  Q6: () => (/* reexport */ makeService),
42
43
  UI: () => (/* reexport */ objectHelper),
@@ -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
253
- function getValueByKeys(keys, data) {
237
+ // keys can be array or object or string
238
+ function getValueByKeys_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
@@ -263,7 +251,7 @@ function getValueByKeys(keys, data) {
263
251
  }
264
252
  const firstKey = _keys.shift()
265
253
  if (_data && Object.prototype.hasOwnProperty.call(_data, firstKey)) {
266
- return getValueByKeys(_keys, _data[firstKey])
254
+ return getValueByKeys_getValueByKeys(_keys, _data[firstKey])
267
255
  }
268
256
  if (_data && firstKey) {
269
257
  return _data[firstKey]
@@ -271,8 +259,8 @@ function getValueByKeys(keys, data) {
271
259
  return _data
272
260
 
273
261
  }
274
- /* harmony default export */ const getValueByKeys_getValueByKeys = ({
275
- getValueByKeys
262
+ /* harmony default export */ const getValueByKeys = ({
263
+ getValueByKeys: getValueByKeys_getValueByKeys
276
264
  });
277
265
 
278
266
 
@@ -280,950 +268,909 @@ 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_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_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
515
- }
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
- })
467
+ if (arg === '[*]') {
468
+ return Array.isArray(value) && value.length !== 0
469
+ }
470
+ return false
523
471
  }
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
- })
472
+
473
+ // the arg is 'operator + string | number'
474
+ const { operator, value: argValue } = _splitOperator(arg)
475
+ if (!operator || (argValue !== 0 && !argValue)) {
476
+ return false
531
477
  }
532
- static foundByKey(arr = [], key) {
533
- const found = arr.find((m) => {
534
- return this.sameKey(m, key)
535
- })
536
- return found || null
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
537
491
  }
538
- static foundValueByKey(arr = [], key) {
539
- const found = this.foundByKey(arr, key)
540
- return found ? found.value : null
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
541
503
  }
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)
504
+ return !Number.isNaN(input)
505
+ }
506
+
507
+ function _splitOperator(str) {
508
+ const operators = ['!=', '>=', '<=', '>', '<']
509
+
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 }
563
518
  }
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
- }, [])
519
+
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
522
+
523
+ return {
524
+ operator: matchedOp,
525
+ value
571
526
  }
572
- static hasKeyValue(arr = [], key, value) {
573
- if (typeof value === 'undefined') {
574
- return arr.filter((item) => this.sameKey(item, key)).length > 0
527
+ }
528
+
529
+
530
+
531
+ ;// ./lib/models/templateCompiler/helpers/_filterOne.js
532
+
533
+
534
+
535
+ function _filterOne(data, args) {
536
+ try {
537
+ const list = _filterAll(data, args)
538
+ if (list.length === 1) {
539
+ return list[0]
575
540
  }
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)
541
+ if (list.length === 0) {
542
+ return null
584
543
  }
585
- return copy
544
+ throw new TemplateCompilerException(TEMPLATE_COMPILER_EXCEPTION_TYPE.resultMoreThanOneException)
545
+ } catch (e) {
546
+ throw e
586
547
  }
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 []
548
+ }
549
+
550
+
551
+
552
+ ;// ./lib/models/templateCompiler/helpers/_formatDate.js
553
+
554
+
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`)
595
558
  }
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
559
+
560
+ if (timestamp === null || timestamp === undefined) {
561
+ return null
608
562
  }
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
- }, [])
563
+
564
+ const date = new Date(timestamp)
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')
616
570
  }
617
- static sameKey(item, key) {
618
- return _isSame(item.key, key)
571
+
572
+ // Check for invalid format tokens
573
+ const validTokens = ['yyyy', 'mm', 'dd']
574
+ const invalidTokens = format.filter((part) => part.length > 1 && !validTokens.includes(part))
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
+ )
619
580
  }
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
- }, {})
581
+
582
+ // Build the formatted string using reduce
583
+ return format.reduce((result, part) => result + (partsMap[part] || part), '')
584
+ }
585
+
586
+
587
+
588
+ ;// ./lib/models/templateCompiler/helpers/_get.js
589
+
590
+
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)
626
595
  }
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)
596
+ if (data === null) {
597
+ return null
635
598
  }
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
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)
644
606
  }
607
+ return _handleFailover(key, failover)
645
608
  }
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
609
  }
670
- return []
671
- }
672
-
673
- // getters
674
- get isValid() {
675
- return !!this.key
676
- }
677
-
678
- get toObject() {
679
- const obj = {}
680
- if (this.isValid) {
681
- obj[this.key] = this.value
610
+ if (typeof data[key] !== 'undefined') {
611
+ return data[key]
682
612
  }
683
- return obj
613
+ return _handleFailover(key, failover)
614
+ } catch (e) {
615
+ throw e
684
616
  }
685
617
  }
686
618
 
687
- function _isSame(key1, key2) {
688
- return key1 === key2
619
+ function _handleFailover(key, failover) {
620
+ if (failover !== null) {
621
+ return failover
622
+ }
623
+ return null
624
+ // throw new TemplateCompilerException(`Key "${key}" does not exist and no failover`)
689
625
  }
690
626
 
691
627
 
692
628
 
693
- ;// ./lib/models/keyValueObject/index.js
629
+ ;// ./lib/models/templateCompiler/helpers/_gt.js
694
630
 
695
631
 
696
632
 
697
633
 
698
- ;// ./lib/helpers/stringFormatter/stringFormatter.js
699
- function stringFormatter(str, delimiter = '_') {
700
- if (str === null || typeof str === 'undefined' || typeof str.toString === 'undefined') {
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')) {
701
639
  return null
702
640
  }
703
- return str.toString()
704
- .trim()
705
- .toUpperCase()
706
- .replace('-', delimiter)
707
- .replace(' ', delimiter)
641
+ if (args.includes(_SELF)) {
642
+ args = args.map((arg) => {
643
+ return (arg === _SELF) ? data : arg
644
+ })
645
+ }
646
+ const expected = args[0]
647
+ return data > expected ? args[1] : args[2]
708
648
  }
709
649
 
710
650
 
711
651
 
712
- ;// ./lib/models/metadata/metadata.js
652
+ ;// ./lib/models/templateCompiler/helpers/_gte.js
713
653
 
714
654
 
715
655
 
716
- const DELIMITER = '_'
717
656
 
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
657
+ function _gte(data, args) {
658
+ if (args.length !== 3) {
659
+ throw new TemplateCompilerException(`_gte: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: ${args.join(', ')}`)
728
660
  }
729
- static get _classname() {
730
- return 'Metadata'
661
+ if (data === null || (typeof data === 'undefined')) {
662
+ return null
731
663
  }
732
-
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
- }
664
+ if (args.includes(_SELF)) {
665
+ args = args.map((arg) => {
666
+ return (arg === _SELF) ? data : arg
743
667
  })
744
- return toArr
745
- }
746
- static sameKey(item, key) {
747
- return metadata_isSame(item.key, key)
748
668
  }
669
+ const expected = args[0]
670
+ return data >= expected ? args[1] : args[2]
749
671
  }
750
672
 
751
- function metadata_isSame(key1, key2) {
752
- return stringFormatter(key1, DELIMITER) === stringFormatter(key2, DELIMITER)
753
- }
754
673
 
755
674
 
675
+ ;// ./lib/models/templateCompiler/helpers/_isEmpty.js
756
676
 
757
- ;// ./lib/models/metadata/index.js
758
677
 
759
678
 
760
679
 
680
+ function _isEmpty(data, args) {
681
+ if (args.length !== 2) {
682
+ throw new TemplateCompilerException(`_isEmpty: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: ${args.join(', ')}`)
683
+ }
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
690
+ })
691
+ }
692
+ if (data !== null && typeof data === 'object' && Object.keys(data).length === 0) {
693
+ return args[0]
694
+ }
695
+ return (data === '' || data === null || data === undefined || data.length === 0) ? args[0] : args[1]
696
+ }
761
697
 
762
- ;// ./lib/models/qMeta/qMeta.js
763
698
 
764
699
 
765
- const updateAllowedProps = [
766
- 'attributes',
767
- 'ref'
768
- ]
700
+ ;// ./lib/models/templateCompiler/helpers/_isNotEmpty.js
769
701
 
770
- class QMeta {
771
- constructor(options = {}) {
772
- options = options || {}
773
- this.attributes = KeyValueObject.initOnlyValidFromArray(options.attributes)
774
- this.ref = options.ref || {}
775
- }
776
702
 
777
- static get _classname() {
778
- return 'QMeta'
703
+
704
+
705
+ function _isNotEmpty(data, args) {
706
+ if (args.length !== 2) {
707
+ throw new TemplateCompilerException(`_isNotEmpty: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: ${args.join(', ')}`)
779
708
  }
780
- static get _superclass() {
781
- return 'QMeta'
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
715
+ })
782
716
  }
783
-
784
- // Class methods
785
- static init(options = {}) {
786
- if (options instanceof QMeta) {
787
- return options
788
- }
789
- return new QMeta(options)
717
+ if (data !== null && typeof data === 'object' && Object.keys(data).length === 0) {
718
+ return args[1]
790
719
  }
791
-
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
720
+ if (Array.isArray(data) && data.length === 0) {
721
+ return args[1]
722
+ }
723
+ if (typeof data === 'string' && data === '') {
724
+ return args[1]
725
+ }
726
+ if (data === null || data === undefined) {
727
+ return args[1]
800
728
  }
729
+ return args[0]
730
+ }
801
731
 
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
- }
811
- })
812
- return this
732
+
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
813
741
  }
814
742
  }
815
743
 
744
+ function _stringifyObject(obj) {
745
+ return JSON.stringify(obj).replace(/"([^"]+)":/g, '$1: ').replace(/"([^"]+)"/g, '$1').replace(/,/g, ', ')
746
+ }
816
747
 
817
748
 
818
- ;// ./lib/models/qMeta/index.js
819
749
 
750
+ ;// ./lib/models/templateCompiler/helpers/_lt.js
820
751
 
821
752
 
822
753
 
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
754
+
755
+ function _lt(data, args) {
756
+ if (args.length !== 3) {
757
+ throw new TemplateCompilerException(`_lt: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: ${args.join(', ')}`)
841
758
  }
842
- static get _classname() {
843
- return 'Repo'
759
+ if (data === null || (typeof data === 'undefined')) {
760
+ return null
844
761
  }
845
- static get _superclass() {
846
- return 'Repo'
762
+ if (args.includes(_SELF)) {
763
+ args = args.map((arg) => {
764
+ return (arg === _SELF) ? data : arg
765
+ })
847
766
  }
767
+ const expected = args[0]
768
+ return data < expected ? args[1] : args[2]
769
+ }
848
770
 
849
- get _classname() {
850
- return 'Repo'
851
- }
852
771
 
853
- get _superclass() {
854
- return 'Repo'
855
- }
856
772
 
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
- }
773
+ ;// ./lib/models/templateCompiler/helpers/_lte.js
863
774
 
864
- get queryOptions() {
865
- return {
866
- ...this._sharedOptions,
867
- ...this._queryOptions,
868
- }
869
- }
870
775
 
871
- get saveOptions() {
872
- return {
873
- ...this._sharedOptions,
874
- ...this._saveOptions,
875
- }
876
- }
877
776
 
878
- init(options) {
879
- if (this._Class && typeof this._Class.init === 'function') {
880
- return this._Class.init(options)
881
- }
882
- return options
883
- }
884
777
 
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
- }
778
+ function _lte(data, args) {
779
+ if (args.length !== 3) {
780
+ throw new TemplateCompilerException(`_lte: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: ${args.join(', ')}`)
896
781
  }
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
- })
782
+ if (data === null || (typeof data === 'undefined')) {
783
+ return null
784
+ }
785
+ if (args.includes(_SELF)) {
786
+ args = args.map((arg) => {
787
+ return (arg === _SELF) ? data : arg
921
788
  })
922
789
  }
790
+ const expected = args[0]
791
+ return data <= expected ? args[1] : args[2]
792
+ }
923
793
 
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
- })
954
- }
955
794
 
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 } }]
963
- })
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]
795
+
796
+ ;// ./lib/models/templateCompiler/helpers/_map.js
797
+
798
+
799
+
800
+ function _map(data, args) {
801
+ try {
802
+ if (args.length === 0) {
803
+ throw new TemplateCompilerException(TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentEmptyException)
804
+ }
805
+ if (data === null || (typeof data === 'undefined')) {
806
+ return null
807
+ }
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]
972
824
  }
973
825
  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
826
+ })
827
+ if (acc.hasFormat) {
828
+ acc.content.push(list)
829
+ } else {
830
+ acc.content = acc.content.concat(list)
981
831
  }
982
- log({ level: 'info', output: { ...result } })
983
- return result
984
- }).catch((err) => {
985
- log({ level: 'warn', output: err.toString() })
986
- throw err
832
+ return acc
833
+ }, {
834
+ content: [],
835
+ hasFormat: false
987
836
  })
837
+ return result.content
838
+ } catch (e) {
839
+ throw e
988
840
  }
841
+ }
989
842
 
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
- })
843
+
844
+
845
+ ;// ./lib/models/templateCompiler/helpers/_neq.js
846
+
847
+
848
+
849
+
850
+ function _neq(data, args) {
851
+ if (args.length !== 3) {
852
+ throw new TemplateCompilerException(`_neq: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: ${args.join(', ')}`)
853
+ }
854
+ if (data === null || (typeof data === 'undefined')) {
855
+ return null
856
+ }
857
+ if (args.includes(_SELF)) {
858
+ args = args.map((arg) => {
859
+ return (arg === _SELF) ? data : arg
1007
860
  })
1008
861
  }
862
+ const expected = args[0]
863
+ return data !== expected ? args[1] : args[2]
1009
864
  }
1010
865
 
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
- }
866
+
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(', ')}`)
874
+ }
875
+ if (data === null || (typeof data === 'undefined') || typeof data !== 'string') {
876
+ return null
1027
877
  }
878
+ return String(data).toLowerCase()
1028
879
  }
1029
880
 
1030
881
 
1031
882
 
1032
- ;// ./lib/models/repo/index.js
883
+ ;// ./lib/models/templateCompiler/helpers/_toUpperCase.js
1033
884
 
1034
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}`)
889
+ }
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()
897
+ }
1035
898
 
1036
899
 
1037
- ;// ./lib/models/service/service.js
1038
900
 
901
+ ;// ./lib/models/templateCompiler/helpers/index.js
1039
902
 
1040
903
 
1041
- class Service {
1042
- constructor({ repo }) {
1043
- this.repo = repo
1044
- }
1045
904
 
1046
- static get _classname() {
1047
- return 'Service'
1048
- }
1049
- static get _superclass() {
1050
- return 'Service'
1051
- }
1052
905
 
1053
- deleteOne({ id }) {
1054
- return this.repo.deleteOne({ id })
1055
- .catch(() => {
1056
- throw new Error(`Not found for query: ${id}`)
1057
- })
1058
- }
1059
906
 
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
907
 
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
908
 
1076
- init(options) {
1077
- return this.repo.init(options)
909
+
910
+
911
+
912
+
913
+
914
+
915
+
916
+
917
+
918
+
919
+
920
+
921
+
922
+
923
+ ;// ./lib/models/templateCompiler/templateCompiler.js
924
+
925
+
926
+
927
+
928
+ class TemplateCompiler {
929
+ constructor(data) {
930
+ this.data = data
1078
931
  }
1079
- initFromArray(arr = []) {
932
+ static init(options) {
933
+ return new this(options)
934
+ }
935
+ static initFromArray(arr = []) {
1080
936
  if (Array.isArray(arr)) {
1081
937
  return arr.map((a) => this.init(a))
1082
938
  }
1083
939
  return []
1084
940
  }
1085
- initOnlyValidFromArray(arr = []) {
941
+ static initOnlyValidFromArray(arr = []) {
1086
942
  return this.initFromArray(arr).filter((i) => i)
1087
943
  }
944
+ static concatIf(data, args) {
945
+ return _concatIf(data, args)
946
+ }
947
+ static eq(data, args) {
948
+ return _eq(data, args)
949
+ }
1088
950
 
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
- })
951
+ static filterAll(data, args) {
952
+ return _filterAll(data, args)
1098
953
  }
1099
954
 
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
- }
955
+ static formatDate(data, args) {
956
+ return _formatDate(data, args)
1114
957
  }
1115
- }
1116
-
1117
- function makeService({ repo }) {
1118
- if (repo === undefined) {
1119
- throw new Error('repo is required.')
958
+
959
+ static get(data, key, failover = null) {
960
+ return _get(data, key, failover)
1120
961
  }
1121
- if (repo._superclass !== Repo._superclass) {
1122
- throw new Error('repo is not an instance of Repo.')
962
+ static gt(data, args) {
963
+ return _gt(data, args)
1123
964
  }
1124
- return new Service({ repo })
1125
- }
1126
-
1127
-
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
965
+ static gte(data, args) {
966
+ return _gte(data, args)
1150
967
  }
1151
- }
1152
-
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 = ['{{', '}}']
1165
-
1166
-
1167
-
1168
- ;// ./lib/models/templateCompiler/helpers/_concatIf.js
1169
-
1170
-
1171
-
1172
-
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(', ')}`)
968
+ static isEmpty(data, args) {
969
+ return _isEmpty(data, args)
1176
970
  }
1177
- if (args.length !== 3) {
1178
- throw new TemplateCompilerException(`_concatIf: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: ${args.join(', ')}`)
971
+ static isNotEmpty(data, args) {
972
+ return _isNotEmpty(data, args)
1179
973
  }
1180
- if (data === null || (typeof data === 'undefined')) {
1181
- return null
974
+ static join(data, separator = '') {
975
+ return _join(data, separator)
1182
976
  }
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}`)
977
+ static lt(data, args) {
978
+ return _lt(data, args)
1187
979
  }
1188
- if (data === '' && failover.includes(_HIDE)) {
1189
- return ''
980
+ static lte(data, args) {
981
+ return _lte(data, args)
1190
982
  }
1191
- if (data !== '' && (data !== null || data !== undefined) && failover.includes(_HIDE)) {
1192
- return `${success[0]}${data}${success[success.length - 1]}`
983
+ static map(data, args = []) {
984
+ return _map(data, args)
985
+ }
986
+ static neq(data, args) {
987
+ return _neq(data, args)
988
+ }
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)
997
+ }
998
+
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}`)
1193
1014
  }
1194
- return failover
1195
1015
  }
1196
1016
 
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
+ }, [])
1042
+ }
1197
1043
 
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)]
1050
+ }
1051
+ if (_parameters.includes(',')) {
1052
+ // 用正则表达式匹配逗号,但忽略方括号中的逗号
1053
+ const parts = _splitIgnoringBrackets(_parameters)
1054
+ return parts.map((part) => _parseSinglePart(part))
1055
+ }
1056
+ return [_parseSinglePart(_parameters)]
1057
+ }
1198
1058
 
1199
- ;// ./lib/models/templateCompiler/helpers/_eq.js
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
+ }
1200
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
+ }
1201
1080
 
1081
+ const _input = _toBasicType(input)
1202
1082
 
1083
+ if (typeof _input !== 'string') {
1084
+ return _input
1085
+ }
1203
1086
 
1204
- function _eq(data, args) {
1205
- if (args.length !== 3) {
1206
- throw new TemplateCompilerException(`eq: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: ${args.join(', ')}`)
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
1207
1098
  }
1208
- if (data === null || (typeof data === 'undefined')) {
1099
+ return input
1100
+ }
1101
+
1102
+ function _toBasicType(input) {
1103
+ if (input.startsWith('"') && input.endsWith('"')) {
1104
+ // 去掉双引号,返回
1105
+ return input.substring(1, input.length - 1)
1106
+ }
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') {
1209
1117
  return null
1210
1118
  }
1211
- if (args.includes(_SELF)) {
1212
- args = args.map((arg) => {
1213
- return (arg === _SELF) ? data : arg
1214
- })
1119
+ if (!Number.isNaN(input) && !Number.isNaN(Number.parseFloat(input))) {
1120
+ return Number(input)
1215
1121
  }
1216
- const expected = args[0]
1217
- return data === expected ? args[1] : args[2]
1122
+ return input
1218
1123
  }
1219
1124
 
1220
-
1221
-
1222
- ;// ./lib/models/templateCompiler/helpers/_exec.js
1223
- function _exec(data, args) {
1125
+ function _callFunction(data, functionName, parameters) {
1224
1126
  try {
1225
- const [methodName, ..._args] = args
1226
- return data[methodName](..._args)
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)
1134
+ }
1135
+ if (parameters.length === 2) {
1136
+ failover = parameters[parameters.length - 1]
1137
+ }
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
+ }
1227
1174
  } catch (e) {
1228
1175
  throw e
1229
1176
  }
@@ -1231,817 +1178,955 @@ function _exec(data, args) {
1231
1178
 
1232
1179
 
1233
1180
 
1234
- ;// ./lib/models/templateCompiler/helpers/_filterAll.js
1181
+ ;// ./lib/models/templateCompiler/index.js
1235
1182
 
1236
1183
 
1237
1184
 
1238
- // const DELIMITER = '~~~'
1239
1185
 
1240
- function _filterAll(data, args) {
1241
- try {
1242
- if (!Array.isArray(args) || args.length === 0) {
1243
- throw new TemplateCompilerException(TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentEmptyException)
1244
- }
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)
1253
- }
1254
- return []
1255
- } catch (e) {
1256
- throw e
1257
- }
1258
- }
1186
+ ;// ./lib/helpers/concatStringByArray/concatStringByArray.js
1259
1187
 
1260
- function _exist(data, args) {
1261
- const _args = args.flat()
1262
- return data.filter((e) => _args.some((arg) => _performOperation(arg, e)))
1263
- }
1264
1188
 
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
1189
 
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
- }
1284
1190
 
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
- })
1191
+
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_getValueByKeys)) {
1198
+ acc += (value.toString())
1199
+ }
1200
+ break
1201
+ }
1202
+ case('value'): {
1203
+ if (getValidation(restriction, data, getValueByKeys_getValueByKeys)) {
1204
+ const _value = getValueByKeys_getValueByKeys(value.split('.'), data) || ''
1205
+ acc += (_value.toString())
1206
+ }
1207
+ break
1208
+ }
1209
+ case('array'): {
1210
+ if (getValidation(restriction, data, getValueByKeys_getValueByKeys)) {
1211
+ const _value = getValueByKeys_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_getValueByKeys)) {
1220
+ const { maxLength } = item
1221
+ const _value = getValueByKeys_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_getValueByKeys)) {
1232
+ const _value = getValueByKeys_getValueByKeys(value.split('.'), data) || ''
1233
+ acc += (formatDate(_value, format).toString())
1234
+ }
1235
+ break
1236
+ }
1237
+ case ('templateCompiler'): {
1238
+ if (getValidation(restriction, data, getValueByKeys_getValueByKeys)) {
1239
+ const templateCompiler = new TemplateCompiler({ data })
1240
+ acc += templateCompiler.pipe(value)
1241
+ }
1242
+ break
1243
+ }
1244
+ }
1245
+ return acc
1246
+ }, '')
1291
1247
  }
1248
+ /* harmony default export */ const concatStringByArray_concatStringByArray = ({
1249
+ concatStringByArray
1250
+ });
1292
1251
 
1293
- function _performOperation(arg, value) {
1294
- // the arg is undefined
1295
- if (arg === undefined && value === undefined) return true
1296
1252
 
1297
- // the arg is null
1298
- if (arg === null && value === null) return true
1299
1253
 
1300
- // the arg is boolean
1301
- if (typeof arg === 'boolean') {
1302
- return arg === value
1303
- }
1254
+ ;// ./lib/helpers/concatStringByArray/index.js
1304
1255
 
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 !== ''
1318
- }
1319
1256
 
1320
- // the arg is alphabetic or number
1321
- if (_isPureStringOrNumber(arg)) {
1322
- return arg === value
1323
- }
1257
+ ;// ./lib/helpers/convertString/convertString.js
1324
1258
 
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
1259
 
1336
- // the arg is 'operator + string | number'
1337
- const { operator, value: argValue } = _splitOperator(arg)
1338
- if (!operator || (argValue !== 0 && !argValue)) {
1339
- return false
1340
- }
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
1260
+ function convertString(string, patternMatch = /\$\{(.+?)\}/g, value, getValueByKeys) {
1261
+ if (!string) {
1262
+ return ''
1354
1263
  }
1264
+ let _getValueByKeys = typeof getValueByKeys !== 'function' ? getValueByKeys : getValueByKeys_getValueByKeys
1265
+ const reg = new RegExp(patternMatch, 'g')
1266
+ return string.replace(reg, (match, key) => {
1267
+ const result = _getValueByKeys({ keys: key.split('.'), obj: value })
1268
+ if (result === null || result === undefined) {
1269
+ return ''
1270
+ }
1271
+ return typeof result === 'object' ? JSON.stringify(result) : result
1272
+ })
1355
1273
  }
1356
1274
 
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
1275
+ /* harmony default export */ const convertString_convertString = ({
1276
+ convertString
1277
+ });
1278
+
1279
+
1280
+ ;// ./lib/helpers/convertString/index.js
1281
+
1282
+
1283
+ ;// ./lib/helpers/objectHelper/objectHelper.js
1284
+ const objectHelper = {
1285
+ get(obj, path) {
1286
+ const parts = path.split('.')
1287
+ return parts.reduce((acc, part) => {
1288
+ if (part.endsWith('[]')) {
1289
+ // 处理数组遍历
1290
+ const key = part.slice(0, -2) // 去掉 '[]' 得到属性名
1291
+ if (Array.isArray(acc[key])) {
1292
+ return acc[key] // 返回整个数组
1293
+ }
1294
+ return [] // 如果不是数组,返回空数组
1295
+ }
1296
+ if (part.includes('[') && part.includes(']')) {
1297
+ // 处理数组索引
1298
+ const arrayMatch = part.match(/(\w+)\[(\d+)\]/)
1299
+ if (arrayMatch) {
1300
+ const key = arrayMatch[1]
1301
+ const index = arrayMatch[2]
1302
+ return acc && acc[key] && acc[key][index]
1303
+ }
1304
+ } else if (acc && Array.isArray(acc)) {
1305
+ // 如果当前值是数组,提取每个对象的指定属性
1306
+ return acc.map((item) => item[part])
1307
+ } else {
1308
+ // 处理普通属性
1309
+ return acc && acc[part]
1310
+ }
1311
+ }, obj)
1312
+ },
1313
+ merge,
1314
+ set(obj, path, value) {
1315
+ const parts = path.split('.')
1316
+ let current = obj
1317
+ for (let i = 0; i < parts.length - 1; i++) {
1318
+ const part = parts[i]
1319
+ if (part.endsWith('[]')) {
1320
+ // 处理数组遍历
1321
+ const key = part.slice(0, -2) // 去掉 '[]' 得到属性名
1322
+ if (Array.isArray(current[key])) {
1323
+ current[key].forEach((item) => set(item, parts.slice(i + 1).join('.'), value))
1324
+ }
1325
+ return // 处理完数组后直接返回
1326
+ }
1327
+ if (part.includes('[') && part.includes(']')) {
1328
+ // 处理数组索引
1329
+ const arrayMatch = part.match(/(\w+)\[(\d+)\]/)
1330
+ if (arrayMatch) {
1331
+ const key = arrayMatch[1]
1332
+ const index = arrayMatch[2]
1333
+ if (Array.isArray(current[key]) && current[key][index]) {
1334
+ current = current[key][index]
1335
+ } else {
1336
+ return // 如果数组或索引不存在,直接返回
1337
+ }
1338
+ }
1339
+ } else {
1340
+ // 处理普通属性
1341
+ if (!current[part]) {
1342
+ current[part] = {} // 如果属性不存在,创建一个空对象
1343
+ }
1344
+ current = current[part]
1345
+ }
1364
1346
  }
1365
- return true
1347
+
1348
+ // 设置最终属性值
1349
+ const lastPart = parts[parts.length - 1]
1350
+ current[lastPart] = value
1366
1351
  }
1367
- return !Number.isNaN(input)
1368
1352
  }
1369
1353
 
1370
- function _splitOperator(str) {
1371
- const operators = ['!=', '>=', '<=', '>', '<']
1372
-
1373
- const matchedOp = operators.find((op) => str.startsWith(op))
1374
- if (!matchedOp) return { operator: null, value: null }
1354
+ function merge(target, ...sources) {
1355
+ if (!sources.length) return target
1375
1356
 
1376
- const remaining = str.slice(matchedOp.length)
1357
+ const source = sources.shift() // 取出第一个源对象
1377
1358
 
1378
- // '>Primary' or '<Primary' is invalid
1379
- if (/^[a-zA-Z]*$/.test(remaining) && matchedOp !== '!=') {
1380
- return { operator: null, value: null }
1359
+ if (_isObject(target) && _isObject(source)) {
1360
+ for (const key in source) {
1361
+ if (_isObject(source[key])) {
1362
+ if (!target[key]) {
1363
+ // 如果目标对象没有该属性,创建一个空对象
1364
+ target[key] = {}
1365
+ }
1366
+ // 递归合并
1367
+ merge(target[key], source[key])
1368
+ } else {
1369
+ // 直接覆盖
1370
+ target[key] = source[key]
1371
+ }
1372
+ }
1381
1373
  }
1382
1374
 
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
1375
+ // 继续合并剩余的源对象
1376
+ return merge(target, ...sources)
1377
+ }
1385
1378
 
1386
- return {
1387
- operator: matchedOp,
1388
- value
1389
- }
1379
+ function _isObject(obj) {
1380
+ return obj && typeof obj === 'object' && !Array.isArray(obj)
1390
1381
  }
1391
1382
 
1392
1383
 
1393
1384
 
1394
- ;// ./lib/models/templateCompiler/helpers/_filterOne.js
1385
+ ;// ./lib/helpers/objectHelper/index.js
1395
1386
 
1396
1387
 
1397
1388
 
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
1389
 
1390
+ ;// ./lib/helpers/pReduce/pReduce.js
1391
+ async function pReduce(iterable, reducer, initialValue) {
1392
+ return new Promise((resolve, reject) => {
1393
+ const iterator = iterable[Symbol.iterator]()
1394
+ let index = 0
1413
1395
 
1396
+ const next = async total => {
1397
+ const element = iterator.next()
1414
1398
 
1415
- ;// ./lib/models/templateCompiler/helpers/_formatDate.js
1399
+ if (element.done) {
1400
+ resolve(total)
1401
+ return
1402
+ }
1416
1403
 
1404
+ try {
1405
+ const [resolvedTotal, resolvedValue] = await Promise.all([total, element.value])
1406
+ next(reducer(resolvedTotal, resolvedValue, index++))
1407
+ } catch (error) {
1408
+ reject(error)
1409
+ }
1410
+ }
1417
1411
 
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
- }
1412
+ next(initialValue)
1413
+ })
1414
+ }
1422
1415
 
1423
- if (timestamp === null || timestamp === undefined) {
1424
- return null
1425
- }
1426
1416
 
1427
- const date = new Date(timestamp)
1428
1417
 
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')
1418
+ ;// ./lib/models/apiResponse/apiResponse.js
1419
+ class ApiResponse {
1420
+ constructor(options = {}) {
1421
+ options = options || {}
1422
+ this._data = options.data || options._data || []
1423
+ this.err = options.err
1424
+ this.isNew = options.isNew || false
1425
+ this.message = options.message
1426
+ this.total = options.total || 0
1427
+ this._instanceBuilder = options._instanceBuilder
1433
1428
  }
1434
1429
 
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
-
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
- )
1430
+ static init(options = {}) {
1431
+ if (options instanceof this) {
1432
+ return options
1433
+ }
1434
+ const instance = new this(options)
1435
+ return instance
1436
+ }
1437
+ static get _classname() {
1438
+ return 'ApiResponse'
1439
+ }
1440
+ static get _superclass() {
1441
+ return 'ApiResponse'
1443
1442
  }
1444
1443
 
1445
- // Build the formatted string using reduce
1446
- return format.reduce((result, part) => result + (partsMap[part] || part), '')
1444
+ // getters
1445
+ get data() {
1446
+ if (this._instanceBuilder && (typeof this._instanceBuilder === 'function')) {
1447
+ return this._data.map(this._instanceBuilder)
1448
+ }
1449
+ return this._data
1450
+ }
1447
1451
  }
1448
1452
 
1449
1453
 
1450
1454
 
1451
- ;// ./lib/models/templateCompiler/helpers/_get.js
1455
+ ;// ./lib/models/apiResponse/makeApiResponse.js
1452
1456
 
1453
1457
 
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
1461
- }
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]
1458
+ function makeApiResponse({ repo, result }) {
1459
+ return ApiResponse.init({
1460
+ ...result,
1461
+ _instanceBuilder: (i) => {
1462
+ return repo.init(i)
1475
1463
  }
1476
- return _handleFailover(key, failover)
1477
- } catch (e) {
1478
- throw e
1479
- }
1464
+ })
1480
1465
  }
1481
1466
 
1482
- function _handleFailover(key, failover) {
1483
- if (failover !== null) {
1484
- return failover
1485
- }
1486
- return null
1487
- // throw new TemplateCompilerException(`Key "${key}" does not exist and no failover`)
1488
- }
1489
1467
 
1490
1468
 
1469
+ ;// ./lib/models/apiResponse/index.js
1491
1470
 
1492
- ;// ./lib/models/templateCompiler/helpers/_gt.js
1493
1471
 
1494
1472
 
1495
1473
 
1496
1474
 
1497
- function _gt(data, args) {
1498
- if (args.length !== 3) {
1499
- throw new TemplateCompilerException(`_gt: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: ${args.join(', ')}`)
1475
+ ;// ./lib/models/keyValueObject/keyValueObject.js
1476
+ class KeyValueObject {
1477
+ constructor(options = {}) {
1478
+ options = options || {}
1479
+ this.key = options.key || null
1480
+ this.value = (typeof options.value !== 'undefined') ? options.value : ''
1500
1481
  }
1501
- if (data === null || (typeof data === 'undefined')) {
1502
- return null
1482
+
1483
+ // Class methods
1484
+ static init(options = {}) {
1485
+ if (options instanceof this) {
1486
+ return options
1487
+ }
1488
+ const instance = new this(options)
1489
+ return instance.isValid ? instance : null
1503
1490
  }
1504
- if (args.includes(_SELF)) {
1505
- args = args.map((arg) => {
1506
- return (arg === _SELF) ? data : arg
1507
- })
1491
+ static initFromArray(arr = []) {
1492
+ if (Array.isArray(arr)) {
1493
+ return arr.map((a) => this.init(a))
1494
+ }
1495
+ return []
1496
+ }
1497
+ static initOnlyValidFromArray(arr = []) {
1498
+ return this.initFromArray(arr).filter((i) => i)
1499
+ }
1500
+ static get _classname() {
1501
+ return 'KeyValueObject'
1502
+ }
1503
+ static get _superclass() {
1504
+ return 'KeyValueObject'
1508
1505
  }
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
-
1519
1506
 
1520
- function _gte(data, args) {
1521
- if (args.length !== 3) {
1522
- throw new TemplateCompilerException(`_gte: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: ${args.join(', ')}`)
1507
+ static addItem(arr, key, value) {
1508
+ arr.push(this.init({ key, value }))
1523
1509
  }
1524
- if (data === null || (typeof data === 'undefined')) {
1525
- return null
1510
+ static addRecord(arr = [], key, value) {
1511
+ if (!this.hasKeyValue(arr, key, value)) {
1512
+ arr.push(this.init({ key, value }))
1513
+ }
1514
+ return arr
1526
1515
  }
1527
- if (args.includes(_SELF)) {
1528
- args = args.map((arg) => {
1529
- return (arg === _SELF) ? data : arg
1516
+ static appendRecord(arr = [], key, value) {
1517
+ return arr.map((item) => {
1518
+ if (this.sameKey(item, key)) {
1519
+ item.value = [...item.value, ...value]
1520
+ }
1521
+ return item
1530
1522
  })
1531
1523
  }
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(', ')}`)
1524
+ static appendValueArray(arr = [], key, value) {
1525
+ return arr.map((item) => {
1526
+ if (this.sameKey(item, key)) {
1527
+ item.value = [...item.value, ...value]
1528
+ }
1529
+ return item
1530
+ })
1546
1531
  }
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
1532
+ static foundByKey(arr = [], key) {
1533
+ const found = arr.find((m) => {
1534
+ return this.sameKey(m, key)
1553
1535
  })
1536
+ return found || null
1554
1537
  }
1555
- if (data !== null && typeof data === 'object' && Object.keys(data).length === 0) {
1556
- return args[0]
1538
+ static foundValueByKey(arr = [], key) {
1539
+ const found = this.foundByKey(arr, key)
1540
+ return found ? found.value : null
1557
1541
  }
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(', ')}`)
1542
+ static fromObject(options = {}) {
1543
+ return Object.keys(options).reduce((acc, key) => {
1544
+ acc.push(this.init({ key, value: options[key] }))
1545
+ return acc
1546
+ }, [])
1547
+ }
1548
+ static getValueByKey(arr = [], key) {
1549
+ return this.foundValueByKey(arr, key)
1550
+ }
1551
+ static getValueByKeyFromArray(arr = [], key) {
1552
+ if (arr.length === 0) {
1553
+ return null
1554
+ }
1555
+ const firstArr = arr.shift()
1556
+ const found = firstArr.find((i) => {
1557
+ return this.sameKey(i, key)
1558
+ })
1559
+ if (found && found.value) {
1560
+ return found.value
1561
+ }
1562
+ return this.getValueByKeyFromArray(arr, key)
1563
+ }
1564
+ static getValuesByKey(arr = [], key) {
1565
+ return arr.reduce((acc, item) => {
1566
+ if (this.sameKey(item, key)) {
1567
+ acc.push(item.value)
1568
+ }
1569
+ return acc
1570
+ }, [])
1571
+ }
1572
+ static hasKeyValue(arr = [], key, value) {
1573
+ if (typeof value === 'undefined') {
1574
+ return arr.filter((item) => this.sameKey(item, key)).length > 0
1575
+ }
1576
+ return arr.filter((item) => (this.sameKey(item, key) && _isSame(item.value, value))).length > 0
1577
+ }
1578
+ static insertOrUpdateRecord(arr = [], key, value) {
1579
+ let copy = [...arr]
1580
+ if (!this.hasKeyValue(arr, key)) {
1581
+ copy.push(this.init({ key, value }))
1582
+ } else {
1583
+ copy = this.updateRecord(arr, key, value)
1584
+ }
1585
+ return copy
1586
+ }
1587
+ static keys(arr = []) {
1588
+ if (Array.isArray(arr)) {
1589
+ return arr.reduce((acc, item) => {
1590
+ acc.push(item.key)
1591
+ return acc
1592
+ }, [])
1593
+ }
1594
+ return []
1595
+ }
1596
+ static merge(toArr, fromArr) {
1597
+ (fromArr || []).map((from) => {
1598
+ const found = toArr.find((to) => {
1599
+ return to.key === from.key
1600
+ })
1601
+ if (found) {
1602
+ found.value = (found.value || []).concat(from.value)
1603
+ } else {
1604
+ toArr.push(from)
1605
+ }
1606
+ })
1607
+ return toArr
1608
+ }
1609
+ static removeByKey(arr, key) {
1610
+ return arr.reduce((acc, item) => {
1611
+ if (!this.sameKey(item, key)) {
1612
+ acc.push(item)
1613
+ }
1614
+ return acc
1615
+ }, [])
1616
+ }
1617
+ static sameKey(item, key) {
1618
+ return _isSame(item.key, key)
1619
+ }
1620
+ static toObject(arr = []) {
1621
+ if (Array.isArray(arr)) {
1622
+ return arr.reduce((acc, item) => {
1623
+ acc[item.key] = item.value
1624
+ return acc
1625
+ }, {})
1626
+ }
1627
+ return {}
1571
1628
  }
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
- })
1629
+ static toString(arr = [], delimiter = '; ') {
1630
+ if (Array.isArray(arr)) {
1631
+ return arr.reduce((acc, item) => {
1632
+ acc.push(`${item.key}: ${item.value}`)
1633
+ return acc
1634
+ }, []).join(delimiter)
1635
+ }
1636
+ return ''
1579
1637
  }
1580
- if (data !== null && typeof data === 'object' && Object.keys(data).length === 0) {
1581
- return args[1]
1638
+ static updateRecord(arr = [], key, value) {
1639
+ return arr.map((item) => {
1640
+ if (this.sameKey(item, key)) {
1641
+ return {
1642
+ ...item,
1643
+ value
1644
+ }
1645
+ }
1646
+ return item
1647
+ })
1582
1648
  }
1583
- if (Array.isArray(data) && data.length === 0) {
1584
- return args[1]
1649
+ static updateOrInsertRecord(arr = [], key, value) {
1650
+ return this.insertOrUpdateRecord(arr, key, value)
1585
1651
  }
1586
- if (typeof data === 'string' && data === '') {
1587
- return args[1]
1652
+ static updateRecordsFromArray(arr = [], updateArr = []) {
1653
+ if (Array.isArray(arr) && Array.isArray(updateArr)) {
1654
+ const obj1 = this.toObject(arr)
1655
+ const obj2 = this.toObject(updateArr)
1656
+ return this.fromObject({
1657
+ ...obj1,
1658
+ ...obj2
1659
+ })
1660
+ }
1661
+ return []
1588
1662
  }
1589
- if (data === null || data === undefined) {
1590
- return args[1]
1663
+ static values(arr = []) {
1664
+ if (Array.isArray(arr)) {
1665
+ return arr.reduce((acc, item) => {
1666
+ acc.push(item.value)
1667
+ return acc
1668
+ }, [])
1669
+ }
1670
+ return []
1591
1671
  }
1592
- return args[0]
1593
- }
1594
1672
 
1673
+ // getters
1674
+ get isValid() {
1675
+ return !!this.key
1676
+ }
1595
1677
 
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
1678
+ get toObject() {
1679
+ const obj = {}
1680
+ if (this.isValid) {
1681
+ obj[this.key] = this.value
1682
+ }
1683
+ return obj
1604
1684
  }
1605
1685
  }
1606
1686
 
1607
- function _stringifyObject(obj) {
1608
- return JSON.stringify(obj).replace(/"([^"]+)":/g, '$1: ').replace(/"([^"]+)"/g, '$1').replace(/,/g, ', ')
1687
+ function _isSame(key1, key2) {
1688
+ return key1 === key2
1609
1689
  }
1610
1690
 
1611
1691
 
1612
1692
 
1613
- ;// ./lib/models/templateCompiler/helpers/_lt.js
1693
+ ;// ./lib/models/keyValueObject/index.js
1614
1694
 
1615
1695
 
1616
1696
 
1617
1697
 
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')) {
1698
+ ;// ./lib/helpers/stringFormatter/stringFormatter.js
1699
+ function stringFormatter(str, delimiter = '_') {
1700
+ if (str === null || typeof str === 'undefined' || typeof str.toString === 'undefined') {
1623
1701
  return null
1624
1702
  }
1625
- if (args.includes(_SELF)) {
1626
- args = args.map((arg) => {
1627
- return (arg === _SELF) ? data : arg
1628
- })
1629
- }
1630
- const expected = args[0]
1631
- return data < expected ? args[1] : args[2]
1703
+ return str.toString()
1704
+ .trim()
1705
+ .toUpperCase()
1706
+ .replace('-', delimiter)
1707
+ .replace(' ', delimiter)
1632
1708
  }
1633
1709
 
1634
1710
 
1635
1711
 
1636
- ;// ./lib/models/templateCompiler/helpers/_lte.js
1712
+ ;// ./lib/models/metadata/metadata.js
1637
1713
 
1638
1714
 
1639
1715
 
1716
+ const DELIMITER = '_'
1640
1717
 
1641
- function _lte(data, args) {
1642
- if (args.length !== 3) {
1643
- throw new TemplateCompilerException(`_lte: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: ${args.join(', ')}`)
1644
- }
1645
- if (data === null || (typeof data === 'undefined')) {
1646
- return null
1647
- }
1648
- if (args.includes(_SELF)) {
1649
- args = args.map((arg) => {
1650
- return (arg === _SELF) ? data : arg
1718
+ class Metadata extends KeyValueObject {
1719
+ static init(options = {}) {
1720
+ if (options instanceof this) {
1721
+ return options
1722
+ }
1723
+ const instance = new this({
1724
+ ...options,
1725
+ key: stringFormatter(options.key, DELIMITER),
1651
1726
  })
1727
+ return instance.isValid ? instance : null
1728
+ }
1729
+ static get _classname() {
1730
+ return 'Metadata'
1652
1731
  }
1653
- const expected = args[0]
1654
- return data <= expected ? args[1] : args[2]
1655
- }
1656
-
1657
-
1658
-
1659
- ;// ./lib/models/templateCompiler/helpers/_map.js
1660
-
1661
-
1662
-
1663
- function _map(data, args) {
1664
- 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
1732
 
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)
1684
- }
1685
- if (typeof item[key] !== 'undefined') {
1686
- return item[key]
1687
- }
1688
- return null
1733
+ static merge(toArr, fromArr) {
1734
+ (fromArr || []).map((from) => {
1735
+ const found = toArr.find((to) => {
1736
+ return metadata_isSame(to.key, from.key)
1689
1737
  })
1690
- if (acc.hasFormat) {
1691
- acc.content.push(list)
1738
+ if (found) {
1739
+ found.value = (found.value || []).concat(from.value)
1692
1740
  } else {
1693
- acc.content = acc.content.concat(list)
1741
+ toArr.push(from)
1694
1742
  }
1695
- return acc
1696
- }, {
1697
- content: [],
1698
- hasFormat: false
1699
- })
1700
- return result.content
1701
- } catch (e) {
1702
- throw e
1703
- }
1704
- }
1705
-
1706
-
1707
-
1708
- ;// ./lib/models/templateCompiler/helpers/_neq.js
1709
-
1710
-
1711
-
1712
-
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
1743
  })
1744
+ return toArr
1724
1745
  }
1725
- const expected = args[0]
1726
- return data !== expected ? args[1] : args[2]
1727
- }
1728
-
1729
-
1730
-
1731
- ;// ./lib/models/templateCompiler/helpers/_toLowerCase.js
1732
-
1733
-
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
1746
+ static sameKey(item, key) {
1747
+ return metadata_isSame(item.key, key)
1740
1748
  }
1741
- return String(data).toLowerCase()
1742
1749
  }
1743
1750
 
1744
-
1745
-
1746
- ;// ./lib/models/templateCompiler/helpers/_toUpperCase.js
1747
-
1748
-
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
1758
- }
1759
- return String(data).toUpperCase()
1751
+ function metadata_isSame(key1, key2) {
1752
+ return stringFormatter(key1, DELIMITER) === stringFormatter(key2, DELIMITER)
1760
1753
  }
1761
1754
 
1762
1755
 
1763
1756
 
1764
- ;// ./lib/models/templateCompiler/helpers/index.js
1765
-
1766
-
1767
-
1768
-
1769
-
1770
-
1771
-
1757
+ ;// ./lib/models/metadata/index.js
1772
1758
 
1773
1759
 
1774
1760
 
1775
1761
 
1762
+ ;// ./lib/models/qMeta/qMeta.js
1776
1763
 
1777
1764
 
1765
+ const updateAllowedProps = [
1766
+ 'attributes',
1767
+ 'ref'
1768
+ ]
1778
1769
 
1770
+ class QMeta {
1771
+ constructor(options = {}) {
1772
+ options = options || {}
1773
+ this.attributes = KeyValueObject.initOnlyValidFromArray(options.attributes)
1774
+ this.ref = options.ref || {}
1775
+ }
1779
1776
 
1777
+ static get _classname() {
1778
+ return 'QMeta'
1779
+ }
1780
+ static get _superclass() {
1781
+ return 'QMeta'
1782
+ }
1780
1783
 
1784
+ // Class methods
1785
+ static init(options = {}) {
1786
+ if (options instanceof QMeta) {
1787
+ return options
1788
+ }
1789
+ return new QMeta(options)
1790
+ }
1781
1791
 
1792
+ // instance methods
1793
+ addAttribute(obj) {
1794
+ const kvObject = KeyValueObject.init(obj)
1795
+ if (!kvObject) {
1796
+ throw new Error('invalid meta attribute')
1797
+ }
1798
+ this.attributes.push(kvObject)
1799
+ return this
1800
+ }
1782
1801
 
1802
+ update(obj) {
1803
+ Object.keys(obj).forEach((key) => {
1804
+ if (updateAllowedProps.includes(key)) {
1805
+ if (key === 'attributes') {
1806
+ this[key] = KeyValueObject.initOnlyValidFromArray(obj[key])
1807
+ } else {
1808
+ this[key] = obj[key]
1809
+ }
1810
+ }
1811
+ })
1812
+ return this
1813
+ }
1814
+ }
1783
1815
 
1784
1816
 
1785
1817
 
1786
- ;// ./lib/models/templateCompiler/templateCompiler.js
1818
+ ;// ./lib/models/qMeta/index.js
1787
1819
 
1788
1820
 
1789
1821
 
1790
1822
 
1791
- class TemplateCompiler {
1792
- constructor(data) {
1793
- this.data = data
1794
- }
1795
- static init(options) {
1796
- return new this(options)
1823
+ ;// ./lib/models/repo/repo.js
1824
+ class Repo {
1825
+ constructor(options) {
1826
+ options = options || {}
1827
+ this.model = options.model
1828
+ this._sharedOptions = options._sharedOptions // { session: this.dbTransaction }
1829
+ this._queryOptions = options._queryOptions
1830
+ this._saveOptions = options._saveOptions
1831
+ this._Class = options._constructor && options._constructor._Class
1832
+ ? options._constructor._Class
1833
+ : null
1797
1834
  }
1798
- static initFromArray(arr = []) {
1799
- if (Array.isArray(arr)) {
1800
- return arr.map((a) => this.init(a))
1835
+ static init(options = {}) {
1836
+ if (options instanceof this) {
1837
+ return options
1801
1838
  }
1802
- return []
1803
- }
1804
- static initOnlyValidFromArray(arr = []) {
1805
- return this.initFromArray(arr).filter((i) => i)
1839
+ const instance = new this(options)
1840
+ return instance.isValid ? instance : null
1806
1841
  }
1807
- static concatIf(data, args) {
1808
- return _concatIf(data, args)
1842
+ static get _classname() {
1843
+ return 'Repo'
1809
1844
  }
1810
- static eq(data, args) {
1811
- return _eq(data, args)
1845
+ static get _superclass() {
1846
+ return 'Repo'
1812
1847
  }
1813
1848
 
1814
- static filterAll(data, args) {
1815
- return _filterAll(data, args)
1849
+ get _classname() {
1850
+ return 'Repo'
1816
1851
  }
1817
1852
 
1818
- static formatDate(data, args) {
1819
- return _formatDate(data, args)
1820
- }
1821
-
1822
- static get(data, key, failover = null) {
1823
- return _get(data, key, failover)
1824
- }
1825
- static gt(data, args) {
1826
- return _gt(data, args)
1827
- }
1828
- static gte(data, args) {
1829
- return _gte(data, args)
1830
- }
1831
- static isEmpty(data, args) {
1832
- return _isEmpty(data, args)
1853
+ get _superclass() {
1854
+ return 'Repo'
1833
1855
  }
1834
- static isNotEmpty(data, args) {
1835
- return _isNotEmpty(data, args)
1856
+
1857
+ get isValid() {
1858
+ return this.model
1859
+ && (typeof this.model.deleteOne === 'function')
1860
+ && (typeof this.model.findAll === 'function')
1861
+ && (typeof this.model.saveOne === 'function')
1836
1862
  }
1837
- static join(data, separator = '') {
1838
- return _join(data, separator)
1863
+
1864
+ get queryOptions() {
1865
+ return {
1866
+ ...this._sharedOptions,
1867
+ ...this._queryOptions,
1868
+ }
1839
1869
  }
1840
- static lt(data, args) {
1841
- return _lt(data, args)
1870
+
1871
+ get saveOptions() {
1872
+ return {
1873
+ ...this._sharedOptions,
1874
+ ...this._saveOptions,
1875
+ }
1842
1876
  }
1843
- static lte(data, args) {
1844
- return _lte(data, args)
1877
+
1878
+ init(options) {
1879
+ if (this._Class && typeof this._Class.init === 'function') {
1880
+ return this._Class.init(options)
1881
+ }
1882
+ return options
1845
1883
  }
1846
- static map(data, args = []) {
1847
- return _map(data, args)
1884
+
1885
+ async deleteOne({ id }) {
1886
+ try {
1887
+ const result = await this.model.deleteOne({ _id: id })
1888
+ return {
1889
+ ...result, // { message: 'ok', total }
1890
+ isNew: false,
1891
+ data: []
1892
+ }
1893
+ } catch (err) {
1894
+ throw err
1895
+ }
1848
1896
  }
1849
- static neq(data, args) {
1850
- return _neq(data, args)
1897
+
1898
+ // systemLog is optional
1899
+ findAll({ query, systemLog }) {
1900
+ const log = _makeLog({
1901
+ systemLog,
1902
+ label: 'REPO_READ',
1903
+ message: `fn ${this._classname}.prototype.findAll`,
1904
+ input: [{ query: { ...query }, systemLog: { ...systemLog } }]
1905
+ })
1906
+ return new Promise((resolve, reject) => {
1907
+ this.model.findAll(query, this.queryOptions, (err, data, total) => {
1908
+ if (err) {
1909
+ log({ level: 'warn', output: err.toString() })
1910
+ reject(err)
1911
+ } else {
1912
+ const result = {
1913
+ isNew: false,
1914
+ data,
1915
+ total: total || data.length
1916
+ }
1917
+ log({ level: 'info', output: { ...result } })
1918
+ resolve(result)
1919
+ }
1920
+ })
1921
+ })
1851
1922
  }
1852
- static toLowerCase(data, args) {
1853
- return _toLowerCase(data, args)
1923
+
1924
+ findOne({ query, systemLog }) {
1925
+ const log = _makeLog({
1926
+ systemLog,
1927
+ label: 'REPO_READ',
1928
+ message: `fn ${this._classname}.prototype.findOne`,
1929
+ input: [{ query: { ...query }, systemLog: { ...systemLog } }]
1930
+ })
1931
+ return new Promise((resolve, reject) => {
1932
+ this.model.findAll(query, this.queryOptions, (err, data) => {
1933
+ if (err) {
1934
+ reject(err)
1935
+ } else if (data.length === 1) {
1936
+ const result = {
1937
+ isNew: false,
1938
+ data,
1939
+ total: 1
1940
+ }
1941
+ log({ level: 'info', output: { ...result } })
1942
+ resolve(result)
1943
+ } else if (data.length === 0) {
1944
+ reject(new Error('record not found'))
1945
+ } else {
1946
+ reject(new Error('more than one is found'))
1947
+ }
1948
+ })
1949
+ })
1950
+ .catch((err) => {
1951
+ log({ level: 'warn', output: err.toString() })
1952
+ throw err
1953
+ })
1854
1954
  }
1855
- static toUpperCase(data, args) {
1856
- return _toUpperCase(data, args)
1955
+
1956
+ saveAll({ docs, systemLog }) {
1957
+ let isNew
1958
+ const log = _makeLog({
1959
+ systemLog,
1960
+ label: 'REPO_WRITE',
1961
+ message: `fn ${this._classname}.prototype.saveAll`,
1962
+ input: [{ docs: [...docs], systemLog: { ...systemLog } }]
1963
+ })
1964
+ const promise = typeof this.model.saveAll === 'function'
1965
+ ? this.model.saveAll({ docs })
1966
+ : Promise.all(docs.map(async (doc) => {
1967
+ if (doc) {
1968
+ const result = await this.saveOne({ doc })
1969
+ isNew = result.isNew
1970
+ const _data = result._data || result.data
1971
+ return _data[0]
1972
+ }
1973
+ return null
1974
+ }))
1975
+ return promise.then((savedData) => {
1976
+ if (savedData.length !== 1) isNew = null
1977
+ const result = {
1978
+ data: savedData,
1979
+ isNew,
1980
+ total: savedData.length
1981
+ }
1982
+ log({ level: 'info', output: { ...result } })
1983
+ return result
1984
+ }).catch((err) => {
1985
+ log({ level: 'warn', output: err.toString() })
1986
+ throw err
1987
+ })
1857
1988
  }
1858
- static parseFunction(expression) {
1859
- return _parseFunction(expression, _FN_NAMES)
1989
+
1990
+ saveOne({ doc, systemLog }) {
1991
+ const log = _makeLog({
1992
+ systemLog,
1993
+ label: 'REPO_WRITE',
1994
+ message: `fn ${this._classname}.prototype.saveOne`,
1995
+ input: [{ doc: { ...doc }, systemLog: { ...systemLog } }]
1996
+ })
1997
+ return new Promise((resolve, reject) => {
1998
+ this.model.saveOne(doc, this.saveOptions, (err, result) => {
1999
+ if (err) {
2000
+ log({ level: 'warn', output: err.toString() })
2001
+ reject(err)
2002
+ } else {
2003
+ log({ level: 'info', output: { ...result } })
2004
+ resolve(result)
2005
+ }
2006
+ })
2007
+ })
1860
2008
  }
2009
+ }
1861
2010
 
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
- }
2011
+ function _makeLog({ systemLog, label, message: message1, input } = {}) {
2012
+ return ({ level, messgae: massage2, output } = {}) => {
2013
+ if (systemLog && systemLog.systemLogHelper) {
2014
+ systemLog.systemLogHelper.log({
2015
+ batchId: systemLog.batchId,
2016
+ label,
2017
+ level,
2018
+ message: massage2 || message1,
2019
+ data: {
2020
+ payload: {
2021
+ input,
2022
+ output
2023
+ }
2024
+ }
2025
+ })
1875
2026
  }
1876
- throw new TemplateCompilerException(`TemplateCompiler engine error: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.invalidRegExpException}`)
1877
2027
  }
1878
2028
  }
1879
2029
 
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
2030
 
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
2031
 
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
- }
2032
+ ;// ./lib/models/repo/index.js
1936
2033
 
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
2034
 
1944
- const _input = _toBasicType(input)
1945
2035
 
1946
- if (typeof _input !== 'string') {
1947
- return _input
1948
- }
1949
2036
 
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
2037
+ ;// ./lib/models/service/service.js
2038
+
2039
+
2040
+
2041
+ class Service {
2042
+ constructor({ repo }) {
2043
+ this.repo = repo
1961
2044
  }
1962
- return input
1963
- }
1964
2045
 
1965
- function _toBasicType(input) {
1966
- if (input.startsWith('"') && input.endsWith('"')) {
1967
- // 去掉双引号,返回
1968
- return input.substring(1, input.length - 1)
2046
+ static get _classname() {
2047
+ return 'Service'
1969
2048
  }
1970
- if (input === 'true') {
1971
- return true
2049
+ static get _superclass() {
2050
+ return 'Service'
1972
2051
  }
1973
- if (input === 'false') {
1974
- return false
2052
+
2053
+ deleteOne({ id }) {
2054
+ return this.repo.deleteOne({ id })
2055
+ .catch(() => {
2056
+ throw new Error(`Not found for query: ${id}`)
2057
+ })
1975
2058
  }
1976
- if (input === 'undefined') {
1977
- return undefined
2059
+
2060
+ async findAll({ query = {}, systemLog } = {}) {
2061
+ const result = await this.repo.findAll({ query, systemLog })
2062
+ return makeApiResponse({
2063
+ repo: this.repo,
2064
+ result
2065
+ })
1978
2066
  }
1979
- if (input === 'null') {
1980
- return null
2067
+
2068
+ async findOne({ query = {}, systemLog } = {}) {
2069
+ const result = await this.repo.findOne({ query, systemLog })
2070
+ return makeApiResponse({
2071
+ repo: this.repo,
2072
+ result
2073
+ })
1981
2074
  }
1982
- if (!Number.isNaN(input) && !Number.isNaN(Number.parseFloat(input))) {
1983
- return Number(input)
2075
+
2076
+ init(options) {
2077
+ return this.repo.init(options)
2078
+ }
2079
+ initFromArray(arr = []) {
2080
+ if (Array.isArray(arr)) {
2081
+ return arr.map((a) => this.init(a))
2082
+ }
2083
+ return []
2084
+ }
2085
+ initOnlyValidFromArray(arr = []) {
2086
+ return this.initFromArray(arr).filter((i) => i)
1984
2087
  }
1985
- return input
1986
- }
1987
2088
 
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`)
2089
+ async saveAll({ docs = [], systemLog } = {}) {
2090
+ const copies = docs.map((doc) => {
2091
+ return this.init(doc)
2092
+ })
2093
+ const result = await this.repo.saveAll({ docs: copies, systemLog })
2094
+ return makeApiResponse({
2095
+ repo: this.repo,
2096
+ result
2097
+ })
2098
+ }
2099
+
2100
+ async saveOne({ doc = {}, systemLog } = {}) {
2101
+ const copy = this.init(doc)
2102
+ if (copy) {
2103
+ const result = await this.repo.saveOne({ doc: copy, systemLog })
2104
+ return makeApiResponse({
2105
+ repo: this.repo,
2106
+ result
2107
+ })
2036
2108
  }
2037
- } catch (e) {
2038
- throw e
2109
+ return {
2110
+ isNew: null,
2111
+ data: [],
2112
+ err: new Error('doc is not a valid instance')
2113
+ }
2114
+ }
2115
+ }
2116
+
2117
+ function makeService({ repo }) {
2118
+ if (repo === undefined) {
2119
+ throw new Error('repo is required.')
2120
+ }
2121
+ if (repo._superclass !== Repo._superclass) {
2122
+ throw new Error('repo is not an instance of Repo.')
2039
2123
  }
2124
+ return new Service({ repo })
2040
2125
  }
2041
2126
 
2042
2127
 
2043
2128
 
2044
- ;// ./lib/models/templateCompiler/index.js
2129
+ ;// ./lib/models/service/index.js
2045
2130
 
2046
2131
 
2047
2132
 
@@ -2290,6 +2375,7 @@ const stringHelper = {
2290
2375
 
2291
2376
 
2292
2377
 
2378
+
2293
2379
  ;// ./lib/index.js
2294
2380
 
2295
2381
 
@@ -2305,6 +2391,7 @@ var __webpack_exports__Repo = __webpack_exports__.lc;
2305
2391
  var __webpack_exports__Service = __webpack_exports__.kl;
2306
2392
  var __webpack_exports__TemplateCompiler = __webpack_exports__.Mg;
2307
2393
  var __webpack_exports__UniqueKeyGenerator = __webpack_exports__._x;
2394
+ var __webpack_exports__concatStringByArray = __webpack_exports__.yl;
2308
2395
  var __webpack_exports__convertString = __webpack_exports__.l0;
2309
2396
  var __webpack_exports__formatDate = __webpack_exports__.Yq;
2310
2397
  var __webpack_exports__generalPost = __webpack_exports__.zn;
@@ -2317,4 +2404,4 @@ var __webpack_exports__pReduce = __webpack_exports__.d;
2317
2404
  var __webpack_exports__padZeros = __webpack_exports__.Lv;
2318
2405
  var __webpack_exports__stringFormatter = __webpack_exports__.Qy;
2319
2406
  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 };
2407
+ 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 };