@questwork/q-utilities 0.1.16 → 0.1.18
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/.github/workflows/publish.yml +40 -0
- package/package.json +15 -14
- package/dist/index.min.cjs +0 -3613
- package/dist/q-utilities.esm.js +0 -3521
- package/dist/q-utilities.min.js +0 -3612
package/dist/index.min.cjs
DELETED
|
@@ -1,3613 +0,0 @@
|
|
|
1
|
-
(function webpackUniversalModuleDefinition(root, factory) {
|
|
2
|
-
if(typeof exports === 'object' && typeof module === 'object')
|
|
3
|
-
module.exports = factory();
|
|
4
|
-
else if(typeof define === 'function' && define.amd)
|
|
5
|
-
define([], factory);
|
|
6
|
-
else {
|
|
7
|
-
var a = factory();
|
|
8
|
-
for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
|
|
9
|
-
}
|
|
10
|
-
})(this, () => {
|
|
11
|
-
return /******/ (() => { // webpackBootstrap
|
|
12
|
-
/******/ "use strict";
|
|
13
|
-
/******/ // The require scope
|
|
14
|
-
/******/ var __webpack_require__ = {};
|
|
15
|
-
/******/
|
|
16
|
-
/************************************************************************/
|
|
17
|
-
/******/ /* webpack/runtime/define property getters */
|
|
18
|
-
/******/ (() => {
|
|
19
|
-
/******/ // define getter functions for harmony exports
|
|
20
|
-
/******/ __webpack_require__.d = (exports, definition) => {
|
|
21
|
-
/******/ for(var key in definition) {
|
|
22
|
-
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
|
|
23
|
-
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
|
|
24
|
-
/******/ }
|
|
25
|
-
/******/ }
|
|
26
|
-
/******/ };
|
|
27
|
-
/******/ })();
|
|
28
|
-
/******/
|
|
29
|
-
/******/ /* webpack/runtime/hasOwnProperty shorthand */
|
|
30
|
-
/******/ (() => {
|
|
31
|
-
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
|
|
32
|
-
/******/ })();
|
|
33
|
-
/******/
|
|
34
|
-
/******/ /* webpack/runtime/make namespace object */
|
|
35
|
-
/******/ (() => {
|
|
36
|
-
/******/ // define __esModule on exports
|
|
37
|
-
/******/ __webpack_require__.r = (exports) => {
|
|
38
|
-
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
|
|
39
|
-
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
40
|
-
/******/ }
|
|
41
|
-
/******/ Object.defineProperty(exports, '__esModule', { value: true });
|
|
42
|
-
/******/ };
|
|
43
|
-
/******/ })();
|
|
44
|
-
/******/
|
|
45
|
-
/************************************************************************/
|
|
46
|
-
var __webpack_exports__ = {};
|
|
47
|
-
// ESM COMPAT FLAG
|
|
48
|
-
__webpack_require__.r(__webpack_exports__);
|
|
49
|
-
|
|
50
|
-
// EXPORTS
|
|
51
|
-
__webpack_require__.d(__webpack_exports__, {
|
|
52
|
-
ApiResponse: () => (/* reexport */ ApiResponse),
|
|
53
|
-
AwsStsS3Client: () => (/* reexport */ AwsStsS3Client),
|
|
54
|
-
KeyValueObject: () => (/* reexport */ KeyValueObject),
|
|
55
|
-
Metadata: () => (/* reexport */ Metadata),
|
|
56
|
-
QMeta: () => (/* reexport */ QMeta),
|
|
57
|
-
Repo: () => (/* reexport */ Repo),
|
|
58
|
-
Service: () => (/* reexport */ Service),
|
|
59
|
-
TemplateCompiler: () => (/* reexport */ TemplateCompiler),
|
|
60
|
-
TenantAwareEntity: () => (/* reexport */ TenantAwareEntity),
|
|
61
|
-
TrackedEntity: () => (/* reexport */ TrackedEntity),
|
|
62
|
-
UniqueKeyGenerator: () => (/* reexport */ UniqueKeyGenerator),
|
|
63
|
-
authorize: () => (/* reexport */ authorize),
|
|
64
|
-
changeCreatorOwner: () => (/* reexport */ changeCreatorOwner),
|
|
65
|
-
concatStringByArray: () => (/* reexport */ concatStringByArray),
|
|
66
|
-
convertString: () => (/* reexport */ convertString),
|
|
67
|
-
escapeRegex: () => (/* reexport */ escapeRegex),
|
|
68
|
-
expressHelper: () => (/* reexport */ expressHelper),
|
|
69
|
-
extractEmails: () => (/* reexport */ extractEmails),
|
|
70
|
-
formatDate: () => (/* reexport */ formatDate),
|
|
71
|
-
generalPost: () => (/* reexport */ generalPost),
|
|
72
|
-
getValidation: () => (/* reexport */ getValidation),
|
|
73
|
-
getValueByKeys: () => (/* reexport */ getValueByKeys_getValueByKeys),
|
|
74
|
-
init: () => (/* reexport */ init),
|
|
75
|
-
initFromArray: () => (/* reexport */ initFromArray),
|
|
76
|
-
initOnlyValidFromArray: () => (/* reexport */ initOnlyValidFromArray),
|
|
77
|
-
makeApiResponse: () => (/* reexport */ makeApiResponse),
|
|
78
|
-
makeService: () => (/* reexport */ makeService),
|
|
79
|
-
mergeArraysByKey: () => (/* reexport */ mergeArraysByKey),
|
|
80
|
-
objectHelper: () => (/* reexport */ objectHelper),
|
|
81
|
-
pReduce: () => (/* reexport */ pReduce),
|
|
82
|
-
padZeros: () => (/* reexport */ padZeros),
|
|
83
|
-
replacePlaceholders: () => (/* reexport */ replacePlaceholders),
|
|
84
|
-
sanitizeText: () => (/* reexport */ sanitizeText),
|
|
85
|
-
stringFormatter: () => (/* reexport */ stringFormatter),
|
|
86
|
-
stringHelper: () => (/* reexport */ stringHelper),
|
|
87
|
-
tenantPlugin: () => (/* reexport */ tenantPlugin),
|
|
88
|
-
trackingPlugin: () => (/* reexport */ trackingPlugin)
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
;// ./lib/helpers/authorize/authorize.js
|
|
92
|
-
function authorize({ allowCoordinator, allowOwner, query = {}, required, user }) {
|
|
93
|
-
if (!user) {
|
|
94
|
-
throw new Error('Require login.')
|
|
95
|
-
}
|
|
96
|
-
if (!user.permission) {
|
|
97
|
-
// throw new Error('You do not have any permission.')
|
|
98
|
-
}
|
|
99
|
-
const scopes = user.permission.getScopes(required || {}) || []
|
|
100
|
-
if (!scopes || scopes.length === 0) {
|
|
101
|
-
// throw new Error('You are not allowed in this scope.')
|
|
102
|
-
}
|
|
103
|
-
if (!scopes.includes('*')) {
|
|
104
|
-
query.tenantCode = user.tenantCode
|
|
105
|
-
}
|
|
106
|
-
if (!scopes.includes('TENANT')) {
|
|
107
|
-
query.eventShortCode = user.eventShortCode
|
|
108
|
-
}
|
|
109
|
-
// if (!scopes.includes('EVENT')) {
|
|
110
|
-
// query.eventRegistrationCode = user.eventRegistrationCode
|
|
111
|
-
// }
|
|
112
|
-
if (allowCoordinator) {
|
|
113
|
-
if (query.registrationGroupCode && user.myManagedRegistrationGroupCodes.includes(query.registrationGroupCode)) {
|
|
114
|
-
query.__ALLOW_COORDINATOR = true
|
|
115
|
-
} else {
|
|
116
|
-
if (!scopes.includes('EVENT')) {
|
|
117
|
-
query.eventRegistrationCode = user.eventRegistrationCode
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
} else {
|
|
121
|
-
if (!scopes.includes('EVENT')) {
|
|
122
|
-
query.eventRegistrationCode = user.eventRegistrationCode
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
if (allowOwner) {
|
|
126
|
-
query.__ALLOW_OWNER = true
|
|
127
|
-
}
|
|
128
|
-
// not good, just use it as example
|
|
129
|
-
if (user.hasExcludedFields) {
|
|
130
|
-
query.__EXCLUDED_FIELDS = user.getExcludedFields(required)
|
|
131
|
-
}
|
|
132
|
-
query.__LOGIN_SUBJECT_CODE = user.loginSubjectCode
|
|
133
|
-
return query
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
;// ./lib/helpers/authorize/index.js
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
;// ./lib/helpers/changeCreatorOwner/changeCreatorOwner.js
|
|
140
|
-
function changeCreatorOwner(that, { source, target }) {
|
|
141
|
-
if (that.meta) {
|
|
142
|
-
if (!that.meta.creator || that.meta.creator === source.getId()) {
|
|
143
|
-
that.meta.creator = target.getId()
|
|
144
|
-
}
|
|
145
|
-
if (!that.meta.owner || that.meta.owner === source.getId()) {
|
|
146
|
-
that.meta.owner = target.getId()
|
|
147
|
-
}
|
|
148
|
-
} else {
|
|
149
|
-
if (!that.creator || that.creator === source.getId()) {
|
|
150
|
-
that.creator = target.getId()
|
|
151
|
-
}
|
|
152
|
-
if (!that.owner || that.owner === source.getId()) {
|
|
153
|
-
that.owner = target.getId()
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
return that
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
;// ./lib/helpers/changeCreatorOwner/index.js
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
;// ./lib/helpers/getValidation/getValidation.js
|
|
163
|
-
function getValidation(rule, data, getDataByKey, KeyValueObject) {
|
|
164
|
-
if (!rule) {
|
|
165
|
-
return true
|
|
166
|
-
}
|
|
167
|
-
if (typeof getDataByKey !== 'function' || (KeyValueObject && typeof KeyValueObject !== 'function')) {
|
|
168
|
-
return false
|
|
169
|
-
}
|
|
170
|
-
const { key = '', value, placeholder, keyValuePath = '' } = rule
|
|
171
|
-
const [valueAttribute] = Object.keys(value)
|
|
172
|
-
|
|
173
|
-
if (!key && typeof placeholder === 'undefined') {
|
|
174
|
-
switch (valueAttribute) {
|
|
175
|
-
case '$and': {
|
|
176
|
-
return value['$and'].reduce((acc, item) => (acc && getValidation(item, data, getDataByKey, KeyValueObject)), true)
|
|
177
|
-
}
|
|
178
|
-
case '$or': {
|
|
179
|
-
return value['$or'].reduce((acc, item) => (acc || getValidation(item, data, getDataByKey, KeyValueObject)), false)
|
|
180
|
-
}
|
|
181
|
-
default:
|
|
182
|
-
return false
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
let rowValue = typeof placeholder === 'undefined' ? getDataByKey(key, data) : placeholder
|
|
186
|
-
|
|
187
|
-
// if KeyValue object
|
|
188
|
-
if (keyValuePath) {
|
|
189
|
-
const rowValueData = KeyValueObject.toObject(rowValue)
|
|
190
|
-
rowValue = getDataByKey(keyValuePath, rowValueData)
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
switch (valueAttribute) {
|
|
194
|
-
case '$empty': {
|
|
195
|
-
const isEmpty = rowValue === null || rowValue === undefined
|
|
196
|
-
return isEmpty === value['$empty']
|
|
197
|
-
}
|
|
198
|
-
case '$eq': {
|
|
199
|
-
return rowValue === value['$eq']
|
|
200
|
-
}
|
|
201
|
-
case '$gt': {
|
|
202
|
-
return rowValue > value['$gt']
|
|
203
|
-
}
|
|
204
|
-
case '$gte': {
|
|
205
|
-
return rowValue >= value['$gte']
|
|
206
|
-
}
|
|
207
|
-
case '$hasOverlap': {
|
|
208
|
-
return _hasOverlap(rowValue, value['$hasOverlap'])
|
|
209
|
-
}
|
|
210
|
-
case '$lt': {
|
|
211
|
-
return rowValue < value['$lt']
|
|
212
|
-
}
|
|
213
|
-
case '$lte': {
|
|
214
|
-
return rowValue <= value['$lte']
|
|
215
|
-
}
|
|
216
|
-
case '$in': {
|
|
217
|
-
if (Array.isArray(rowValue)) {
|
|
218
|
-
return !!rowValue.find((e) => (value['$in'].includes(e)))
|
|
219
|
-
}
|
|
220
|
-
if (typeof rowValue !== 'object') {
|
|
221
|
-
return !!value['$in'].includes(rowValue)
|
|
222
|
-
}
|
|
223
|
-
return false
|
|
224
|
-
}
|
|
225
|
-
case '$inValue': {
|
|
226
|
-
const result = getDataByKey(value['$inValue'], data)
|
|
227
|
-
const _value = Array.isArray(result) ? result : []
|
|
228
|
-
if (Array.isArray(rowValue)) {
|
|
229
|
-
return !!rowValue.find((e) => (_value.includes(e)))
|
|
230
|
-
}
|
|
231
|
-
if (typeof rowValue === 'string') {
|
|
232
|
-
return !!_value.includes(rowValue)
|
|
233
|
-
}
|
|
234
|
-
return false
|
|
235
|
-
}
|
|
236
|
-
case '$ne': {
|
|
237
|
-
return rowValue !== value['$ne']
|
|
238
|
-
}
|
|
239
|
-
case '$notIn': {
|
|
240
|
-
if (Array.isArray(rowValue)) {
|
|
241
|
-
return !rowValue.find((e) => (value['$notIn'].includes(e)))
|
|
242
|
-
}
|
|
243
|
-
if (typeof rowValue !== 'object') {
|
|
244
|
-
return !value['$notIn'].includes(rowValue)
|
|
245
|
-
}
|
|
246
|
-
return false
|
|
247
|
-
}
|
|
248
|
-
case '$intervalTimeGt': {
|
|
249
|
-
const now = new Date().getTime()
|
|
250
|
-
const timestamp = new Date(rowValue).getTime()
|
|
251
|
-
return (now - timestamp) > value['$intervalTimeGt']
|
|
252
|
-
}
|
|
253
|
-
case '$intervalTimeLt': {
|
|
254
|
-
const now = new Date().getTime()
|
|
255
|
-
const timestamp = new Date(rowValue).getTime()
|
|
256
|
-
return (now - timestamp) < value['$intervalTimeLt']
|
|
257
|
-
}
|
|
258
|
-
case '$isToday': {
|
|
259
|
-
const currentDate = new Date()
|
|
260
|
-
const start = currentDate.setHours(0,0,0,0)
|
|
261
|
-
const end = currentDate.setHours(23,59,59,59)
|
|
262
|
-
const dateValue = new Date(rowValue).getTime()
|
|
263
|
-
return (start <= dateValue && end >= dateValue) === value['$isToday']
|
|
264
|
-
}
|
|
265
|
-
case '$notInValue': {
|
|
266
|
-
const result = getDataByKey(value['$notInValue'], data)
|
|
267
|
-
const _value = Array.isArray(result) ? result : []
|
|
268
|
-
if (Array.isArray(rowValue)) {
|
|
269
|
-
return !rowValue.find((e) => (_value.includes(e)))
|
|
270
|
-
}
|
|
271
|
-
if (typeof rowValue !== 'object') {
|
|
272
|
-
return !_value.includes(rowValue)
|
|
273
|
-
}
|
|
274
|
-
return false
|
|
275
|
-
}
|
|
276
|
-
case '$range': {
|
|
277
|
-
const [min, max] = value['$range']
|
|
278
|
-
if (typeof min === 'number' && typeof max === 'number' && rowValue >= min && rowValue <= max) {
|
|
279
|
-
return true
|
|
280
|
-
}
|
|
281
|
-
return false
|
|
282
|
-
}
|
|
283
|
-
default:
|
|
284
|
-
return false
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
function _hasOverlap(item1, item2) {
|
|
290
|
-
let arr1 = item1
|
|
291
|
-
let arr2 = item2
|
|
292
|
-
if (typeof arr1 === 'string') {
|
|
293
|
-
arr1 = arr1.split(',')
|
|
294
|
-
}
|
|
295
|
-
if (typeof arr2 === 'string') {
|
|
296
|
-
arr2 = arr2.split(',')
|
|
297
|
-
}
|
|
298
|
-
const set1 = new Set(arr1)
|
|
299
|
-
return arr2.find((i) => (set1.has(i)))
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
/* harmony default export */ const getValidation_getValidation = ({
|
|
303
|
-
getValidation
|
|
304
|
-
});
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
;// ./lib/helpers/getValidation/index.js
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
;// ./lib/helpers/formatDate/formatDate.js
|
|
311
|
-
|
|
312
|
-
function formatDate(date, format) {
|
|
313
|
-
const _date = date && date instanceof Date ? date : new Date(date)
|
|
314
|
-
const dayMapChi = ['日','一','二','三','四','五','六']
|
|
315
|
-
const dayMapEng = ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday']
|
|
316
|
-
const dayMapEngShort = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat']
|
|
317
|
-
const _format = format || 'YYYY/MM/DD hh:mm'
|
|
318
|
-
const e = _date.getDay()
|
|
319
|
-
const ee = dayMapEngShort[e]
|
|
320
|
-
const eee = dayMapChi[e]
|
|
321
|
-
const eeee = dayMapEng[e]
|
|
322
|
-
const y = _date.getFullYear()
|
|
323
|
-
const m = _date.getMonth() + 1
|
|
324
|
-
const d = _date.getDate()
|
|
325
|
-
const h = _date.getHours()
|
|
326
|
-
const mm = _date.getMinutes()
|
|
327
|
-
const s = _date.getSeconds()
|
|
328
|
-
|
|
329
|
-
return _format.replace('YYYY', y)
|
|
330
|
-
.replace('MM', padding(m))
|
|
331
|
-
.replace('MM', padding(m))
|
|
332
|
-
.replace('DD', padding(d))
|
|
333
|
-
.replace('hh', padding(h))
|
|
334
|
-
.replace('mm', padding(mm))
|
|
335
|
-
.replace('ss', padding(s))
|
|
336
|
-
.replace('M', m)
|
|
337
|
-
.replace('D', d)
|
|
338
|
-
.replace('h', h)
|
|
339
|
-
.replace('m', mm)
|
|
340
|
-
.replace('s', s)
|
|
341
|
-
.replace('EEEE', padding(eeee))
|
|
342
|
-
.replace('EEE', padding(eee))
|
|
343
|
-
.replace('EE', padding(ee))
|
|
344
|
-
.replace('E', padding(e))
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
function padding(m) {
|
|
348
|
-
return m < 10 ? `0${m}` : m
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
/* harmony default export */ const formatDate_formatDate = ({
|
|
353
|
-
formatDate
|
|
354
|
-
});
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
;// ./lib/helpers/formatDate/index.js
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
;// ./lib/helpers/getValueByKeys/getValueByKeys.js
|
|
362
|
-
// keys can be array or object or string
|
|
363
|
-
function getValueByKeys_getValueByKeys(keys, data) {
|
|
364
|
-
let _keys = keys
|
|
365
|
-
let _data = data
|
|
366
|
-
if (typeof keys === 'string') {
|
|
367
|
-
_keys = _keys.split('.')
|
|
368
|
-
}
|
|
369
|
-
if (!Array.isArray(keys) && typeof keys === 'object') {
|
|
370
|
-
const { keys: keyArr, obj } = keys
|
|
371
|
-
_keys = keyArr
|
|
372
|
-
_data = obj
|
|
373
|
-
}
|
|
374
|
-
if (_keys.length === 0) {
|
|
375
|
-
return _data
|
|
376
|
-
}
|
|
377
|
-
const firstKey = _keys.shift()
|
|
378
|
-
if (_data && Object.prototype.hasOwnProperty.call(_data, firstKey)) {
|
|
379
|
-
return getValueByKeys_getValueByKeys(_keys, _data[firstKey])
|
|
380
|
-
}
|
|
381
|
-
if (_data && firstKey) {
|
|
382
|
-
return _data[firstKey]
|
|
383
|
-
}
|
|
384
|
-
return _data
|
|
385
|
-
|
|
386
|
-
}
|
|
387
|
-
/* harmony default export */ const getValueByKeys = ({
|
|
388
|
-
getValueByKeys: getValueByKeys_getValueByKeys
|
|
389
|
-
});
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
;// ./lib/helpers/getValueByKeys/index.js
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
;// ./lib/models/templateCompiler/templateCompilerException.js
|
|
396
|
-
const TEMPLATE_COMPILER_EXCEPTION_TYPE = {
|
|
397
|
-
argumentEmptyException: 'Argument is empty',
|
|
398
|
-
argumentFormatException: 'Incorrect number or format of argument',
|
|
399
|
-
invalidFuntionException: 'Function Name is invalid',
|
|
400
|
-
invalidRegExpException: 'Invalid regular expression',
|
|
401
|
-
isNotAFunctionException: 'Is not a function',
|
|
402
|
-
notExistException: 'Key does not exist',
|
|
403
|
-
resultEmptyException: 'Result is empty',
|
|
404
|
-
resultMoreThanOneException: 'More than one result'
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
class TemplateCompilerException extends Error {
|
|
408
|
-
constructor(message) {
|
|
409
|
-
super(message)
|
|
410
|
-
this.message = message
|
|
411
|
-
}
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
;// ./lib/models/templateCompiler/constants.js
|
|
417
|
-
const _EMPTY = '_EMPTY'
|
|
418
|
-
const _FN_NAMES = [
|
|
419
|
-
'concatIf',
|
|
420
|
-
'divide',
|
|
421
|
-
'eq',
|
|
422
|
-
'exec',
|
|
423
|
-
'filterAll',
|
|
424
|
-
'filterOne',
|
|
425
|
-
'formatDate',
|
|
426
|
-
'get',
|
|
427
|
-
'gt',
|
|
428
|
-
'gte',
|
|
429
|
-
'isEmpty',
|
|
430
|
-
'isNotEmpty',
|
|
431
|
-
'join',
|
|
432
|
-
'lt',
|
|
433
|
-
'lte',
|
|
434
|
-
'map',
|
|
435
|
-
'neq',
|
|
436
|
-
'removeHtml',
|
|
437
|
-
'toLowerCase',
|
|
438
|
-
'toUpperCase',
|
|
439
|
-
]
|
|
440
|
-
const _HIDE = '_HIDE'
|
|
441
|
-
const _NOT_EMPTY = '_NOT_EMPTY'
|
|
442
|
-
const _SELF = '_SELF'
|
|
443
|
-
const TAGS_EJS = ['<%=', '%>']
|
|
444
|
-
const TAGS_HANDLEBAR = ['{{', '}}']
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
;// ./lib/models/templateCompiler/helpers/_concatIf.js
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
function _concatIf(data, args) {
|
|
454
|
-
if (typeof data !== 'string') {
|
|
455
|
-
throw new TemplateCompilerException(`_concatIf: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: the data must be string :${data.join(', ')}`)
|
|
456
|
-
}
|
|
457
|
-
if (args.length !== 3) {
|
|
458
|
-
throw new TemplateCompilerException(`_concatIf: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: ${args.join(', ')}`)
|
|
459
|
-
}
|
|
460
|
-
if (data === null || (typeof data === 'undefined')) {
|
|
461
|
-
return null
|
|
462
|
-
}
|
|
463
|
-
const [condition, success, failover] = args
|
|
464
|
-
const validConditions = [_EMPTY, _NOT_EMPTY]
|
|
465
|
-
if (validConditions.includes(condition) || success.length !== 2) {
|
|
466
|
-
throw new TemplateCompilerException(`concatIf: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentEmptyException}: ${condition}, ${success}`)
|
|
467
|
-
}
|
|
468
|
-
if (data === '' && failover.includes(_HIDE)) {
|
|
469
|
-
return ''
|
|
470
|
-
}
|
|
471
|
-
if (data !== '' && (data !== null || data !== undefined) && failover.includes(_HIDE)) {
|
|
472
|
-
return `${success[0]}${data}${success[success.length - 1]}`
|
|
473
|
-
}
|
|
474
|
-
return failover
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
;// ./lib/models/templateCompiler/helpers/_divide.js
|
|
480
|
-
function _divide(value, divisor) {
|
|
481
|
-
try {
|
|
482
|
-
if (Number.isNaN(value)) {
|
|
483
|
-
return value
|
|
484
|
-
}
|
|
485
|
-
return (value / divisor)
|
|
486
|
-
} catch (e) {
|
|
487
|
-
throw e
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
;// ./lib/models/templateCompiler/helpers/_eq.js
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
function _eq(data, args) {
|
|
499
|
-
if (args.length !== 3) {
|
|
500
|
-
throw new TemplateCompilerException(`eq: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: ${args.join(', ')}`)
|
|
501
|
-
}
|
|
502
|
-
if (data === null || (typeof data === 'undefined')) {
|
|
503
|
-
return null
|
|
504
|
-
}
|
|
505
|
-
if (args.includes(_SELF)) {
|
|
506
|
-
args = args.map((arg) => {
|
|
507
|
-
return (arg === _SELF) ? data : arg
|
|
508
|
-
})
|
|
509
|
-
}
|
|
510
|
-
const expected = args[0]
|
|
511
|
-
return data === expected ? args[1] : args[2]
|
|
512
|
-
}
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
;// ./lib/models/templateCompiler/helpers/_exec.js
|
|
517
|
-
function _exec(data, args) {
|
|
518
|
-
try {
|
|
519
|
-
const [methodName, ..._args] = args
|
|
520
|
-
return data[methodName](..._args)
|
|
521
|
-
} catch (e) {
|
|
522
|
-
throw e
|
|
523
|
-
}
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
;// ./lib/models/templateCompiler/helpers/_filterAll.js
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
// const DELIMITER = '~~~'
|
|
533
|
-
|
|
534
|
-
function _filterAll(data, args) {
|
|
535
|
-
try {
|
|
536
|
-
if (!Array.isArray(args) || args.length === 0) {
|
|
537
|
-
throw new TemplateCompilerException(TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentEmptyException)
|
|
538
|
-
}
|
|
539
|
-
if (!Array.isArray(data) || data.length === 0) {
|
|
540
|
-
return []
|
|
541
|
-
}
|
|
542
|
-
if (typeof data[0] === 'object') {
|
|
543
|
-
return _existObject(data, args)
|
|
544
|
-
}
|
|
545
|
-
if (typeof data[0] === 'string' || typeof data[0] === 'number') {
|
|
546
|
-
return _exist(data, args)
|
|
547
|
-
}
|
|
548
|
-
return []
|
|
549
|
-
} catch (e) {
|
|
550
|
-
throw e
|
|
551
|
-
}
|
|
552
|
-
}
|
|
553
|
-
|
|
554
|
-
function _exist(data, args) {
|
|
555
|
-
const _args = args.flat()
|
|
556
|
-
return data.filter((e) => _args.some((arg) => _performOperation(arg, e)))
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
function _existObject(data, args) {
|
|
560
|
-
if (args.length === 1) {
|
|
561
|
-
const arg = args[0]
|
|
562
|
-
return data.filter((e) => {
|
|
563
|
-
if (arg.includes('.')) {
|
|
564
|
-
return getValueByKeys_getValueByKeys(arg.split('.'), e)
|
|
565
|
-
}
|
|
566
|
-
return Object.prototype.hasOwnProperty.call(e, arg)
|
|
567
|
-
})
|
|
568
|
-
}
|
|
569
|
-
|
|
570
|
-
if (args.length > 2) {
|
|
571
|
-
let res = data
|
|
572
|
-
for (let i = 0; i < args.length; i += 2) {
|
|
573
|
-
const group = [args[i], args[i + 1]]
|
|
574
|
-
res = _existObject(res, group)
|
|
575
|
-
}
|
|
576
|
-
return res
|
|
577
|
-
}
|
|
578
|
-
|
|
579
|
-
const [key, ..._argsArr] = args
|
|
580
|
-
const _args = _argsArr.flat()
|
|
581
|
-
return data.filter((e) => {
|
|
582
|
-
const value = key.includes('.') ? getValueByKeys_getValueByKeys(key.split('.'), e) : e[key]
|
|
583
|
-
return _args.some((arg) => _performOperation(arg, value))
|
|
584
|
-
})
|
|
585
|
-
}
|
|
586
|
-
|
|
587
|
-
function _performOperation(arg, value) {
|
|
588
|
-
// the arg is undefined
|
|
589
|
-
if (arg === undefined && value === undefined) return true
|
|
590
|
-
|
|
591
|
-
// the arg is null
|
|
592
|
-
if (arg === null && value === null) return true
|
|
593
|
-
|
|
594
|
-
// the arg is boolean
|
|
595
|
-
if (typeof arg === 'boolean') {
|
|
596
|
-
return arg === value
|
|
597
|
-
}
|
|
598
|
-
|
|
599
|
-
// the arg is blank or *: Blank => Empty, * => Not Empty
|
|
600
|
-
if (arg === '' || arg === '*') {
|
|
601
|
-
// null and undefined are not included in either case
|
|
602
|
-
if (value === null || value === undefined) {
|
|
603
|
-
return false
|
|
604
|
-
}
|
|
605
|
-
if (typeof value === 'string') {
|
|
606
|
-
return arg === '' ? value === '' : value !== ''
|
|
607
|
-
}
|
|
608
|
-
if (Array.isArray(value)) {
|
|
609
|
-
return arg === '' ? value.length === 0 : value.length !== 0
|
|
610
|
-
}
|
|
611
|
-
return arg !== ''
|
|
612
|
-
}
|
|
613
|
-
|
|
614
|
-
// the arg is alphabetic or number
|
|
615
|
-
if (_isPureStringOrNumber(arg)) {
|
|
616
|
-
return arg === value
|
|
617
|
-
}
|
|
618
|
-
|
|
619
|
-
// the arg is array of [] or [*]: [] => Empty, [*] => Not Empty
|
|
620
|
-
if (arg.startsWith('[') && arg.endsWith(']')) {
|
|
621
|
-
if (arg === '[]') {
|
|
622
|
-
return Array.isArray(value) && value.length === 0
|
|
623
|
-
}
|
|
624
|
-
if (arg === '[*]') {
|
|
625
|
-
return Array.isArray(value) && value.length !== 0
|
|
626
|
-
}
|
|
627
|
-
return false
|
|
628
|
-
}
|
|
629
|
-
|
|
630
|
-
// the arg is 'operator + string | number'
|
|
631
|
-
const { operator, value: argValue } = _splitOperator(arg)
|
|
632
|
-
if (!operator || (argValue !== 0 && !argValue)) {
|
|
633
|
-
return false
|
|
634
|
-
}
|
|
635
|
-
switch (operator) {
|
|
636
|
-
case '>':
|
|
637
|
-
return value > argValue
|
|
638
|
-
case '<':
|
|
639
|
-
return value < argValue
|
|
640
|
-
case '!=':
|
|
641
|
-
return value !== argValue
|
|
642
|
-
case '>=':
|
|
643
|
-
return value >= argValue
|
|
644
|
-
case '<=':
|
|
645
|
-
return value <= argValue
|
|
646
|
-
default:
|
|
647
|
-
return false
|
|
648
|
-
}
|
|
649
|
-
}
|
|
650
|
-
|
|
651
|
-
function _isPureStringOrNumber(input) {
|
|
652
|
-
if (typeof input === 'string') {
|
|
653
|
-
if (input.startsWith('[') && input.endsWith(']')) {
|
|
654
|
-
return false
|
|
655
|
-
}
|
|
656
|
-
if (/!=|>=|<=|>|</.test(input)) {
|
|
657
|
-
return false
|
|
658
|
-
}
|
|
659
|
-
return true
|
|
660
|
-
}
|
|
661
|
-
return !Number.isNaN(input)
|
|
662
|
-
}
|
|
663
|
-
|
|
664
|
-
function _splitOperator(str) {
|
|
665
|
-
const operators = ['!=', '>=', '<=', '>', '<']
|
|
666
|
-
|
|
667
|
-
const matchedOp = operators.find((op) => str.startsWith(op))
|
|
668
|
-
if (!matchedOp) return { operator: null, value: null }
|
|
669
|
-
|
|
670
|
-
const remaining = str.slice(matchedOp.length)
|
|
671
|
-
|
|
672
|
-
// '>Primary' or '<Primary' is invalid
|
|
673
|
-
if (/^[a-zA-Z]*$/.test(remaining) && matchedOp !== '!=') {
|
|
674
|
-
return { operator: null, value: null }
|
|
675
|
-
}
|
|
676
|
-
|
|
677
|
-
// if it is a number it is converted to a number
|
|
678
|
-
const value = (!Number.isNaN(parseFloat(remaining)) && !Number.isNaN(remaining)) ? Number(remaining) : remaining
|
|
679
|
-
|
|
680
|
-
return {
|
|
681
|
-
operator: matchedOp,
|
|
682
|
-
value
|
|
683
|
-
}
|
|
684
|
-
}
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
;// ./lib/models/templateCompiler/helpers/_filterOne.js
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
function _filterOne(data, args) {
|
|
693
|
-
try {
|
|
694
|
-
const list = _filterAll(data, args)
|
|
695
|
-
if (list.length === 1) {
|
|
696
|
-
return list[0]
|
|
697
|
-
}
|
|
698
|
-
if (list.length === 0) {
|
|
699
|
-
return null
|
|
700
|
-
}
|
|
701
|
-
throw new TemplateCompilerException(TEMPLATE_COMPILER_EXCEPTION_TYPE.resultMoreThanOneException)
|
|
702
|
-
} catch (e) {
|
|
703
|
-
throw e
|
|
704
|
-
}
|
|
705
|
-
}
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
;// ./lib/models/templateCompiler/helpers/_formatDate.js
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
function _formatDate(timestamp, format) {
|
|
713
|
-
if (format.length === 0) {
|
|
714
|
-
throw new TemplateCompilerException(`_formateDate: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: format parts must be not empty array`)
|
|
715
|
-
}
|
|
716
|
-
|
|
717
|
-
if (timestamp === null || timestamp === undefined) {
|
|
718
|
-
return null
|
|
719
|
-
}
|
|
720
|
-
|
|
721
|
-
const date = new Date(timestamp)
|
|
722
|
-
|
|
723
|
-
const partsMap = {
|
|
724
|
-
yyyy: String(date.getFullYear()),
|
|
725
|
-
mm: String(date.getMonth() + 1).padStart(2, '0'),
|
|
726
|
-
dd: String(date.getDate()).padStart(2, '0')
|
|
727
|
-
}
|
|
728
|
-
|
|
729
|
-
// Check for invalid format tokens
|
|
730
|
-
const validTokens = ['yyyy', 'mm', 'dd']
|
|
731
|
-
const invalidTokens = format.filter((part) => part.length > 1 && !validTokens.includes(part))
|
|
732
|
-
|
|
733
|
-
if (invalidTokens.length > 0) {
|
|
734
|
-
throw new TemplateCompilerException(
|
|
735
|
-
`_formateDate: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: the format type is not valid: ${format.join(', ')}`
|
|
736
|
-
)
|
|
737
|
-
}
|
|
738
|
-
|
|
739
|
-
// Build the formatted string using reduce
|
|
740
|
-
return format.reduce((result, part) => result + (partsMap[part] || part), '')
|
|
741
|
-
}
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
;// ./lib/models/templateCompiler/helpers/_get.js
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
function _get(data, key, failover = null) {
|
|
749
|
-
try {
|
|
750
|
-
if (key === null || (typeof key === 'undefined') || key === '') {
|
|
751
|
-
throw new TemplateCompilerException(TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentEmptyException)
|
|
752
|
-
}
|
|
753
|
-
if (data === null) {
|
|
754
|
-
return null
|
|
755
|
-
}
|
|
756
|
-
if (key.includes('.')) {
|
|
757
|
-
const parts = key.split('.')
|
|
758
|
-
if (parts.length > 1) {
|
|
759
|
-
const first = parts.shift()
|
|
760
|
-
const remainingKey = parts.join('.')
|
|
761
|
-
if (typeof data[first] !== 'undefined') {
|
|
762
|
-
return _get(data[first], remainingKey, failover)
|
|
763
|
-
}
|
|
764
|
-
return _handleFailover(key, failover)
|
|
765
|
-
}
|
|
766
|
-
}
|
|
767
|
-
if (typeof data[key] !== 'undefined') {
|
|
768
|
-
return data[key]
|
|
769
|
-
}
|
|
770
|
-
return _handleFailover(key, failover)
|
|
771
|
-
} catch (e) {
|
|
772
|
-
throw e
|
|
773
|
-
}
|
|
774
|
-
}
|
|
775
|
-
|
|
776
|
-
function _handleFailover(key, failover) {
|
|
777
|
-
if (failover !== null) {
|
|
778
|
-
return failover
|
|
779
|
-
}
|
|
780
|
-
return null
|
|
781
|
-
// throw new TemplateCompilerException(`Key "${key}" does not exist and no failover`)
|
|
782
|
-
}
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
;// ./lib/models/templateCompiler/helpers/_gt.js
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
function _gt(data, args) {
|
|
792
|
-
if (args.length !== 3) {
|
|
793
|
-
throw new TemplateCompilerException(`_gt: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: ${args.join(', ')}`)
|
|
794
|
-
}
|
|
795
|
-
if (data === null || (typeof data === 'undefined')) {
|
|
796
|
-
return null
|
|
797
|
-
}
|
|
798
|
-
if (args.includes(_SELF)) {
|
|
799
|
-
args = args.map((arg) => {
|
|
800
|
-
return (arg === _SELF) ? data : arg
|
|
801
|
-
})
|
|
802
|
-
}
|
|
803
|
-
const expected = args[0]
|
|
804
|
-
return data > expected ? args[1] : args[2]
|
|
805
|
-
}
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
;// ./lib/models/templateCompiler/helpers/_gte.js
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
function _gte(data, args) {
|
|
815
|
-
if (args.length !== 3) {
|
|
816
|
-
throw new TemplateCompilerException(`_gte: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: ${args.join(', ')}`)
|
|
817
|
-
}
|
|
818
|
-
if (data === null || (typeof data === 'undefined')) {
|
|
819
|
-
return null
|
|
820
|
-
}
|
|
821
|
-
if (args.includes(_SELF)) {
|
|
822
|
-
args = args.map((arg) => {
|
|
823
|
-
return (arg === _SELF) ? data : arg
|
|
824
|
-
})
|
|
825
|
-
}
|
|
826
|
-
const expected = args[0]
|
|
827
|
-
return data >= expected ? args[1] : args[2]
|
|
828
|
-
}
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
;// ./lib/models/templateCompiler/helpers/_isEmpty.js
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
function _isEmpty(data, args) {
|
|
838
|
-
if (args.length !== 2) {
|
|
839
|
-
throw new TemplateCompilerException(`_isEmpty: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: ${args.join(', ')}`)
|
|
840
|
-
}
|
|
841
|
-
// if (data === null || (typeof data === 'undefined')) {
|
|
842
|
-
// return null
|
|
843
|
-
// }
|
|
844
|
-
if (args.includes(_SELF)) {
|
|
845
|
-
args = args.map((arg) => {
|
|
846
|
-
return (arg === _SELF) ? data : arg
|
|
847
|
-
})
|
|
848
|
-
}
|
|
849
|
-
if (data !== null && typeof data === 'object' && Object.keys(data).length === 0) {
|
|
850
|
-
return args[0]
|
|
851
|
-
}
|
|
852
|
-
return (data === '' || data === null || data === undefined || data.length === 0) ? args[0] : args[1]
|
|
853
|
-
}
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
;// ./lib/models/templateCompiler/helpers/_isNotEmpty.js
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
function _isNotEmpty(data, args) {
|
|
863
|
-
if (args.length !== 2) {
|
|
864
|
-
throw new TemplateCompilerException(`_isNotEmpty: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: ${args.join(', ')}`)
|
|
865
|
-
}
|
|
866
|
-
// if (data === null || (typeof data === 'undefined')) {
|
|
867
|
-
// return null
|
|
868
|
-
// }
|
|
869
|
-
if (args.includes(_SELF)) {
|
|
870
|
-
args = args.map((arg) => {
|
|
871
|
-
return (arg === _SELF) ? data : arg
|
|
872
|
-
})
|
|
873
|
-
}
|
|
874
|
-
if (data !== null && typeof data === 'object' && Object.keys(data).length === 0) {
|
|
875
|
-
return args[1]
|
|
876
|
-
}
|
|
877
|
-
if (Array.isArray(data) && data.length === 0) {
|
|
878
|
-
return args[1]
|
|
879
|
-
}
|
|
880
|
-
if (typeof data === 'string' && data === '') {
|
|
881
|
-
return args[1]
|
|
882
|
-
}
|
|
883
|
-
if (data === null || data === undefined) {
|
|
884
|
-
return args[1]
|
|
885
|
-
}
|
|
886
|
-
return args[0]
|
|
887
|
-
}
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
;// ./lib/models/templateCompiler/helpers/_join.js
|
|
891
|
-
function _join(data, delimiter) {
|
|
892
|
-
try {
|
|
893
|
-
if (data.length === 0) return ''
|
|
894
|
-
if (data.length === 1) return _stringifyObject(data[0])
|
|
895
|
-
return data.map((item) => _stringifyObject(item)).join(delimiter)
|
|
896
|
-
} catch (e) {
|
|
897
|
-
throw e
|
|
898
|
-
}
|
|
899
|
-
}
|
|
900
|
-
|
|
901
|
-
function _stringifyObject(obj) {
|
|
902
|
-
return JSON.stringify(obj).replace(/"([^"]+)":/g, '$1: ').replace(/"([^"]+)"/g, '$1').replace(/,/g, ', ')
|
|
903
|
-
}
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
;// ./lib/models/templateCompiler/helpers/_lt.js
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
function _lt(data, args) {
|
|
913
|
-
if (args.length !== 3) {
|
|
914
|
-
throw new TemplateCompilerException(`_lt: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: ${args.join(', ')}`)
|
|
915
|
-
}
|
|
916
|
-
if (data === null || (typeof data === 'undefined')) {
|
|
917
|
-
return null
|
|
918
|
-
}
|
|
919
|
-
if (args.includes(_SELF)) {
|
|
920
|
-
args = args.map((arg) => {
|
|
921
|
-
return (arg === _SELF) ? data : arg
|
|
922
|
-
})
|
|
923
|
-
}
|
|
924
|
-
const expected = args[0]
|
|
925
|
-
return data < expected ? args[1] : args[2]
|
|
926
|
-
}
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
;// ./lib/models/templateCompiler/helpers/_lte.js
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
function _lte(data, args) {
|
|
936
|
-
if (args.length !== 3) {
|
|
937
|
-
throw new TemplateCompilerException(`_lte: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: ${args.join(', ')}`)
|
|
938
|
-
}
|
|
939
|
-
if (data === null || (typeof data === 'undefined')) {
|
|
940
|
-
return null
|
|
941
|
-
}
|
|
942
|
-
if (args.includes(_SELF)) {
|
|
943
|
-
args = args.map((arg) => {
|
|
944
|
-
return (arg === _SELF) ? data : arg
|
|
945
|
-
})
|
|
946
|
-
}
|
|
947
|
-
const expected = args[0]
|
|
948
|
-
return data <= expected ? args[1] : args[2]
|
|
949
|
-
}
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
;// ./lib/models/templateCompiler/helpers/_map.js
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
function _map(data, args) {
|
|
958
|
-
try {
|
|
959
|
-
if (args.length === 0) {
|
|
960
|
-
throw new TemplateCompilerException(TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentEmptyException)
|
|
961
|
-
}
|
|
962
|
-
if (data === null || (typeof data === 'undefined')) {
|
|
963
|
-
return null
|
|
964
|
-
}
|
|
965
|
-
|
|
966
|
-
const result = data.reduce((acc, item) => {
|
|
967
|
-
if (args.length === 1 && Array.isArray(args[0])) {
|
|
968
|
-
args = args[0]
|
|
969
|
-
acc.hasFormat = true
|
|
970
|
-
}
|
|
971
|
-
const list = args.map((key) => {
|
|
972
|
-
if (key.includes('.')) {
|
|
973
|
-
const parts = key.split('.')
|
|
974
|
-
const first = parts[0]
|
|
975
|
-
parts.shift()
|
|
976
|
-
const remainingKey = parts.join('.')
|
|
977
|
-
return _get(item[first], remainingKey)
|
|
978
|
-
}
|
|
979
|
-
if (typeof item[key] !== 'undefined') {
|
|
980
|
-
return item[key]
|
|
981
|
-
}
|
|
982
|
-
return null
|
|
983
|
-
})
|
|
984
|
-
if (acc.hasFormat) {
|
|
985
|
-
acc.content.push(list)
|
|
986
|
-
} else {
|
|
987
|
-
acc.content = acc.content.concat(list)
|
|
988
|
-
}
|
|
989
|
-
return acc
|
|
990
|
-
}, {
|
|
991
|
-
content: [],
|
|
992
|
-
hasFormat: false
|
|
993
|
-
})
|
|
994
|
-
return result.content
|
|
995
|
-
} catch (e) {
|
|
996
|
-
throw e
|
|
997
|
-
}
|
|
998
|
-
}
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
;// ./lib/models/templateCompiler/helpers/_neq.js
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
function _neq(data, args) {
|
|
1008
|
-
if (args.length !== 3) {
|
|
1009
|
-
throw new TemplateCompilerException(`_neq: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: ${args.join(', ')}`)
|
|
1010
|
-
}
|
|
1011
|
-
if (data === null || (typeof data === 'undefined')) {
|
|
1012
|
-
return null
|
|
1013
|
-
}
|
|
1014
|
-
if (args.includes(_SELF)) {
|
|
1015
|
-
args = args.map((arg) => {
|
|
1016
|
-
return (arg === _SELF) ? data : arg
|
|
1017
|
-
})
|
|
1018
|
-
}
|
|
1019
|
-
const expected = args[0]
|
|
1020
|
-
return data !== expected ? args[1] : args[2]
|
|
1021
|
-
}
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
;// ./lib/models/templateCompiler/helpers/_removeHtml.js
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
function _removeHtml(html, args) {
|
|
1029
|
-
if (html === null || html === undefined) {
|
|
1030
|
-
return null
|
|
1031
|
-
}
|
|
1032
|
-
if (!Array.isArray(args)) {
|
|
1033
|
-
throw new TemplateCompilerException(`_removeHtml: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: args parts must be array`)
|
|
1034
|
-
}
|
|
1035
|
-
|
|
1036
|
-
return _htmlToPlainText(html, args[0])
|
|
1037
|
-
}
|
|
1038
|
-
|
|
1039
|
-
function _htmlToPlainText(html, delimiter = '\n') {
|
|
1040
|
-
if (typeof delimiter !== 'string') {
|
|
1041
|
-
delimiter = '\n'; // Fallback to default if not a string
|
|
1042
|
-
}
|
|
1043
|
-
|
|
1044
|
-
// First decode HTML entities and normalize whitespace
|
|
1045
|
-
const decodedHtml = html
|
|
1046
|
-
.replace(/ /g, ' ')
|
|
1047
|
-
.replace(/\s+/g, ' '); // Collapse all whitespace to single spaces
|
|
1048
|
-
|
|
1049
|
-
// Process HTML tags
|
|
1050
|
-
let text = decodedHtml
|
|
1051
|
-
// Replace block tags with temporary marker (~~~)
|
|
1052
|
-
.replace(/<\/?(p|div|h[1-6]|ul|ol|li|pre|section|article|table|tr|td|th)(\s[^>]*)?>/gi, '~~~')
|
|
1053
|
-
// Replace <br> tags with temporary marker (~~~)
|
|
1054
|
-
.replace(/<br\s*\/?>/gi, '~~~')
|
|
1055
|
-
// Remove all other tags
|
|
1056
|
-
.replace(/<[^>]+>/g, '')
|
|
1057
|
-
// Convert markers to specified delimiter
|
|
1058
|
-
.replace(/~~~+/g, delimiter)
|
|
1059
|
-
// Trim and clean whitespace
|
|
1060
|
-
.trim();
|
|
1061
|
-
|
|
1062
|
-
// Special handling for empty delimiter
|
|
1063
|
-
if (delimiter === '') {
|
|
1064
|
-
// Collapse all whitespace to single space
|
|
1065
|
-
text = text.replace(/\s+/g, ' ');
|
|
1066
|
-
} else {
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
// Collapse multiple delimiters to single
|
|
1070
|
-
text = text.replace(new RegExp(`${escapeRegExp(delimiter)}+`, 'g'), delimiter);
|
|
1071
|
-
// Remove leading/trailing delimiters
|
|
1072
|
-
text = text.replace(new RegExp(`^${escapeRegExp(delimiter)}|${escapeRegExp(delimiter)}$`, 'g'), '');
|
|
1073
|
-
}
|
|
1074
|
-
|
|
1075
|
-
return text;
|
|
1076
|
-
}
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
function escapeRegExp(string) {
|
|
1080
|
-
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
1081
|
-
}
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
;// ./lib/models/templateCompiler/helpers/_toLowerCase.js
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
function _toLowerCase(data, args) {
|
|
1089
|
-
if (args !== undefined) {
|
|
1090
|
-
throw new TemplateCompilerException(`_toLowerCase: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: ${args.join(', ')}`)
|
|
1091
|
-
}
|
|
1092
|
-
if (data === null || (typeof data === 'undefined') || typeof data !== 'string') {
|
|
1093
|
-
return null
|
|
1094
|
-
}
|
|
1095
|
-
return String(data).toLowerCase()
|
|
1096
|
-
}
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
;// ./lib/models/templateCompiler/helpers/_toUpperCase.js
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
function _toUpperCase(data, args) {
|
|
1104
|
-
if (typeof data !== 'string') {
|
|
1105
|
-
throw new TemplateCompilerException(`_toUpperCase: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: the data must be string: ${data}`)
|
|
1106
|
-
}
|
|
1107
|
-
if (args !== undefined) {
|
|
1108
|
-
throw new TemplateCompilerException(`_toUpperCase: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException}: the argument must be empty: ${args.join(', ')}`)
|
|
1109
|
-
}
|
|
1110
|
-
if (data === null || (typeof data === 'undefined') || typeof data !== 'string') {
|
|
1111
|
-
return null
|
|
1112
|
-
}
|
|
1113
|
-
return String(data).toUpperCase()
|
|
1114
|
-
}
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
;// ./lib/models/templateCompiler/helpers/index.js
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
;// ./lib/models/templateCompiler/templateCompiler.js
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
class TemplateCompiler {
|
|
1148
|
-
constructor(data) {
|
|
1149
|
-
this.data = data
|
|
1150
|
-
}
|
|
1151
|
-
static init(options) {
|
|
1152
|
-
return new this(options)
|
|
1153
|
-
}
|
|
1154
|
-
static initFromArray(arr = []) {
|
|
1155
|
-
if (Array.isArray(arr)) {
|
|
1156
|
-
return arr.map((a) => this.init(a))
|
|
1157
|
-
}
|
|
1158
|
-
return []
|
|
1159
|
-
}
|
|
1160
|
-
static initOnlyValidFromArray(arr = []) {
|
|
1161
|
-
return this.initFromArray(arr).filter((i) => i)
|
|
1162
|
-
}
|
|
1163
|
-
static concatIf(data, args) {
|
|
1164
|
-
return _concatIf(data, args)
|
|
1165
|
-
}
|
|
1166
|
-
static divide(data, args) {
|
|
1167
|
-
return _divide(data, args)
|
|
1168
|
-
}
|
|
1169
|
-
static eq(data, args) {
|
|
1170
|
-
return _eq(data, args)
|
|
1171
|
-
}
|
|
1172
|
-
|
|
1173
|
-
static filterAll(data, args) {
|
|
1174
|
-
return _filterAll(data, args)
|
|
1175
|
-
}
|
|
1176
|
-
|
|
1177
|
-
static formatDate(data, args) {
|
|
1178
|
-
return _formatDate(data, args)
|
|
1179
|
-
}
|
|
1180
|
-
static get(data, key, failover = null) {
|
|
1181
|
-
return _get(data, key, failover)
|
|
1182
|
-
}
|
|
1183
|
-
static gt(data, args) {
|
|
1184
|
-
return _gt(data, args)
|
|
1185
|
-
}
|
|
1186
|
-
static gte(data, args) {
|
|
1187
|
-
return _gte(data, args)
|
|
1188
|
-
}
|
|
1189
|
-
static isEmpty(data, args) {
|
|
1190
|
-
return _isEmpty(data, args)
|
|
1191
|
-
}
|
|
1192
|
-
static isNotEmpty(data, args) {
|
|
1193
|
-
return _isNotEmpty(data, args)
|
|
1194
|
-
}
|
|
1195
|
-
static join(data, separator = '') {
|
|
1196
|
-
return _join(data, separator)
|
|
1197
|
-
}
|
|
1198
|
-
static lt(data, args) {
|
|
1199
|
-
return _lt(data, args)
|
|
1200
|
-
}
|
|
1201
|
-
static lte(data, args) {
|
|
1202
|
-
return _lte(data, args)
|
|
1203
|
-
}
|
|
1204
|
-
static map(data, args = []) {
|
|
1205
|
-
return _map(data, args)
|
|
1206
|
-
}
|
|
1207
|
-
static neq(data, args) {
|
|
1208
|
-
return _neq(data, args)
|
|
1209
|
-
}
|
|
1210
|
-
static removeHtml(data, args) {
|
|
1211
|
-
return _removeHtml(data, args)
|
|
1212
|
-
}
|
|
1213
|
-
static toLowerCase(data, args) {
|
|
1214
|
-
return _toLowerCase(data, args)
|
|
1215
|
-
}
|
|
1216
|
-
static toUpperCase(data, args) {
|
|
1217
|
-
return _toUpperCase(data, args)
|
|
1218
|
-
}
|
|
1219
|
-
static parseFunction(expression) {
|
|
1220
|
-
return _parseFunction(expression, _FN_NAMES)
|
|
1221
|
-
}
|
|
1222
|
-
static parseParams(parameters) {
|
|
1223
|
-
return _parseParams(parameters)
|
|
1224
|
-
}
|
|
1225
|
-
|
|
1226
|
-
pipe(expression = '') {
|
|
1227
|
-
this.delimiters = expression.substring(0, 2) === '{{' ? TAGS_HANDLEBAR : TAGS_EJS
|
|
1228
|
-
const regex = new RegExp(`${this.delimiters[0]}\\s(.*?)\\s${this.delimiters[1]}`)
|
|
1229
|
-
const match = expression.match(regex)
|
|
1230
|
-
if (match !== null) {
|
|
1231
|
-
try {
|
|
1232
|
-
const functionList = _parseFunction(match[1], _FN_NAMES)
|
|
1233
|
-
return functionList.reduce((acc, fn) => {
|
|
1234
|
-
return _callFunction(acc, fn.name, fn.args)
|
|
1235
|
-
}, this.data)
|
|
1236
|
-
} catch (e) {
|
|
1237
|
-
throw new TemplateCompilerException(`TemplateCompiler engine error: ${e.message}`)
|
|
1238
|
-
}
|
|
1239
|
-
}
|
|
1240
|
-
throw new TemplateCompilerException(`TemplateCompiler engine error: ${TEMPLATE_COMPILER_EXCEPTION_TYPE.invalidRegExpException}`)
|
|
1241
|
-
}
|
|
1242
|
-
}
|
|
1243
|
-
|
|
1244
|
-
function _parseFunction(expression, existFunctionNames) {
|
|
1245
|
-
const regExp = new RegExp(/(\w+)\(([^)]*)\)/)
|
|
1246
|
-
let parts
|
|
1247
|
-
if (expression.includes('|')) {
|
|
1248
|
-
parts = expression.split('|')
|
|
1249
|
-
} else {
|
|
1250
|
-
parts = [expression]
|
|
1251
|
-
}
|
|
1252
|
-
return parts.reduce((acc, part) => {
|
|
1253
|
-
const match = part.match(regExp)
|
|
1254
|
-
if (match !== null) {
|
|
1255
|
-
const functionName = match[1]
|
|
1256
|
-
const parameters = match[2]
|
|
1257
|
-
const paramList = _parseParams(parameters)
|
|
1258
|
-
if (existFunctionNames.includes(functionName)) {
|
|
1259
|
-
acc.push({
|
|
1260
|
-
name: functionName,
|
|
1261
|
-
args: paramList
|
|
1262
|
-
})
|
|
1263
|
-
} else {
|
|
1264
|
-
throw new TemplateCompilerException(`${functionName} is not a valid function`)
|
|
1265
|
-
}
|
|
1266
|
-
}
|
|
1267
|
-
return acc
|
|
1268
|
-
}, [])
|
|
1269
|
-
}
|
|
1270
|
-
|
|
1271
|
-
function _parseParams(parameters) {
|
|
1272
|
-
const _parameters = parameters.trim()
|
|
1273
|
-
const regExp = new RegExp(/^[^\w\d\s]+$/)
|
|
1274
|
-
const match = _parameters.match(regExp)
|
|
1275
|
-
if (match !== null) {
|
|
1276
|
-
return [_parameters.substring(1, _parameters.length - 1)]
|
|
1277
|
-
}
|
|
1278
|
-
if (_parameters.includes(',')) {
|
|
1279
|
-
// 用正则表达式匹配逗号,但忽略方括号中的逗号
|
|
1280
|
-
const parts = _splitIgnoringBrackets(_parameters)
|
|
1281
|
-
return parts.map((part) => _parseSinglePart(part))
|
|
1282
|
-
}
|
|
1283
|
-
return [_parseSinglePart(_parameters)]
|
|
1284
|
-
}
|
|
1285
|
-
|
|
1286
|
-
function _splitIgnoringBrackets(input) {
|
|
1287
|
-
const regExp2 = new RegExp(/^\d+(\.\d+)?$/)
|
|
1288
|
-
const regExp = new RegExp(/(?![^\[]*\])\s*,\s*/)
|
|
1289
|
-
const parts = input.split(regExp)
|
|
1290
|
-
return parts.map((part) => {
|
|
1291
|
-
const _part = part.trim()
|
|
1292
|
-
if (_part !== '' && !!_part.match(regExp2)) {
|
|
1293
|
-
// 如果是数字,转换为 num 类型
|
|
1294
|
-
return Number.isNaN(_part) ? _part : parseInt(_part, 10)
|
|
1295
|
-
}
|
|
1296
|
-
// 否则当作字符串处理
|
|
1297
|
-
return _part
|
|
1298
|
-
})
|
|
1299
|
-
}
|
|
1300
|
-
|
|
1301
|
-
function _parseSinglePart(input) {
|
|
1302
|
-
if (typeof input === 'string') {
|
|
1303
|
-
if (input.startsWith('"') && input.endsWith('"')) {
|
|
1304
|
-
// 去掉双引号,返回
|
|
1305
|
-
return input.substring(1, input.length - 1)
|
|
1306
|
-
}
|
|
1307
|
-
if (input.startsWith("'") && input.endsWith("'")) {
|
|
1308
|
-
// 去掉双引号,返回
|
|
1309
|
-
return input.substring(1, input.length - 1)
|
|
1310
|
-
}
|
|
1311
|
-
|
|
1312
|
-
const _input = _toBasicType(input)
|
|
1313
|
-
|
|
1314
|
-
if (typeof _input !== 'string') {
|
|
1315
|
-
return _input
|
|
1316
|
-
}
|
|
1317
|
-
|
|
1318
|
-
// 如果是一个列表形式(例如 ["p", "d"] 或 [p, d])
|
|
1319
|
-
if (_input.startsWith('[') && _input.endsWith(']')) {
|
|
1320
|
-
const listContent = _input.substring(1, _input.length - 1).trim()
|
|
1321
|
-
if (listContent !== '') {
|
|
1322
|
-
return listContent.split(',').map((item) => {
|
|
1323
|
-
return _toBasicType(item.trim())
|
|
1324
|
-
})
|
|
1325
|
-
}
|
|
1326
|
-
return []
|
|
1327
|
-
}
|
|
1328
|
-
return input
|
|
1329
|
-
}
|
|
1330
|
-
return input
|
|
1331
|
-
}
|
|
1332
|
-
|
|
1333
|
-
function _toBasicType(input) {
|
|
1334
|
-
if (input.startsWith('"') && input.endsWith('"')) {
|
|
1335
|
-
// 去掉双引号,返回
|
|
1336
|
-
return input.substring(1, input.length - 1)
|
|
1337
|
-
}
|
|
1338
|
-
if (input.startsWith("'") && input.endsWith("'")) {
|
|
1339
|
-
// 去掉双引号,返回
|
|
1340
|
-
return input.substring(1, input.length - 1)
|
|
1341
|
-
}
|
|
1342
|
-
if (input === 'true') {
|
|
1343
|
-
return true
|
|
1344
|
-
}
|
|
1345
|
-
if (input === 'false') {
|
|
1346
|
-
return false
|
|
1347
|
-
}
|
|
1348
|
-
if (input === 'undefined') {
|
|
1349
|
-
return undefined
|
|
1350
|
-
}
|
|
1351
|
-
if (input === 'null') {
|
|
1352
|
-
return null
|
|
1353
|
-
}
|
|
1354
|
-
if (!Number.isNaN(input) && !Number.isNaN(Number.parseFloat(input))) {
|
|
1355
|
-
return Number(input)
|
|
1356
|
-
}
|
|
1357
|
-
return input
|
|
1358
|
-
}
|
|
1359
|
-
|
|
1360
|
-
function _callFunction(data, functionName, parameters) {
|
|
1361
|
-
try {
|
|
1362
|
-
let failover
|
|
1363
|
-
switch (functionName) {
|
|
1364
|
-
case 'concatIf':
|
|
1365
|
-
return _concatIf(data, parameters)
|
|
1366
|
-
case 'divide':
|
|
1367
|
-
return _divide(data, parameters)
|
|
1368
|
-
case 'eq':
|
|
1369
|
-
return _eq(data, parameters)
|
|
1370
|
-
case 'exec':
|
|
1371
|
-
return _exec(data, parameters)
|
|
1372
|
-
case 'filterAll':
|
|
1373
|
-
return _filterAll(data, parameters)
|
|
1374
|
-
case 'filterOne':
|
|
1375
|
-
return _filterOne(data, parameters)
|
|
1376
|
-
case 'formatDate':
|
|
1377
|
-
return _formatDate(data, parameters)
|
|
1378
|
-
case 'get':
|
|
1379
|
-
if (parameters.length > 2) {
|
|
1380
|
-
throw new TemplateCompilerException(TEMPLATE_COMPILER_EXCEPTION_TYPE.argumentFormatException)
|
|
1381
|
-
}
|
|
1382
|
-
if (parameters.length === 2) {
|
|
1383
|
-
failover = parameters[parameters.length - 1]
|
|
1384
|
-
}
|
|
1385
|
-
return _get(data, parameters[0], failover)
|
|
1386
|
-
case 'gt':
|
|
1387
|
-
return _gt(data, parameters)
|
|
1388
|
-
case 'gte':
|
|
1389
|
-
return _gte(data, parameters)
|
|
1390
|
-
case 'isEmpty':
|
|
1391
|
-
return _isEmpty(data, parameters)
|
|
1392
|
-
case 'isNotEmpty':
|
|
1393
|
-
return _isNotEmpty(data, parameters)
|
|
1394
|
-
case 'join':
|
|
1395
|
-
return _join(data, parameters[0])
|
|
1396
|
-
case 'lt':
|
|
1397
|
-
return _lt(data, parameters)
|
|
1398
|
-
case 'lte':
|
|
1399
|
-
return _lte(data, parameters)
|
|
1400
|
-
case 'map':
|
|
1401
|
-
return _map(data, parameters)
|
|
1402
|
-
case 'neq':
|
|
1403
|
-
return _neq(data, parameters)
|
|
1404
|
-
case 'removeHtml':
|
|
1405
|
-
return _removeHtml(data, parameters)
|
|
1406
|
-
case 'toLowerCase':
|
|
1407
|
-
return _toLowerCase(data)
|
|
1408
|
-
case 'toUpperCase':
|
|
1409
|
-
return _toUpperCase(data)
|
|
1410
|
-
default:
|
|
1411
|
-
throw new Error(`${functionName} is not a valid function`)
|
|
1412
|
-
}
|
|
1413
|
-
} catch (e) {
|
|
1414
|
-
throw e
|
|
1415
|
-
}
|
|
1416
|
-
}
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
;// ./lib/models/templateCompiler/index.js
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
;// ./lib/helpers/concatStringByArray/concatStringByArray.js
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
function concatStringByArray(arrTemplate, data) {
|
|
1432
|
-
return arrTemplate.reduce((acc, item) => {
|
|
1433
|
-
const { type, value = '', restriction, template, format, showMinutes } = item
|
|
1434
|
-
switch (type) {
|
|
1435
|
-
case('label'): {
|
|
1436
|
-
if (getValidation(restriction, data, getValueByKeys_getValueByKeys)) {
|
|
1437
|
-
acc += (value.toString())
|
|
1438
|
-
}
|
|
1439
|
-
break
|
|
1440
|
-
}
|
|
1441
|
-
case('value'): {
|
|
1442
|
-
if (getValidation(restriction, data, getValueByKeys_getValueByKeys)) {
|
|
1443
|
-
const _value = getValueByKeys_getValueByKeys(value.split('.'), data) || ''
|
|
1444
|
-
acc += (_value.toString())
|
|
1445
|
-
}
|
|
1446
|
-
break
|
|
1447
|
-
}
|
|
1448
|
-
case('array'): {
|
|
1449
|
-
if (getValidation(restriction, data, getValueByKeys_getValueByKeys)) {
|
|
1450
|
-
const _value = getValueByKeys_getValueByKeys(value.split('.'), data) || []
|
|
1451
|
-
acc += _value.reduce((_acc, item) => {
|
|
1452
|
-
return _acc += concatStringByArray(template, item)
|
|
1453
|
-
}, '')
|
|
1454
|
-
}
|
|
1455
|
-
break
|
|
1456
|
-
}
|
|
1457
|
-
case('ellipsis'): {
|
|
1458
|
-
if (getValidation(restriction, data, getValueByKeys_getValueByKeys)) {
|
|
1459
|
-
const { maxLength } = item
|
|
1460
|
-
const _value = getValueByKeys_getValueByKeys(value.split('.'), data) || ''
|
|
1461
|
-
if (_value.length <= maxLength) {
|
|
1462
|
-
acc += (_value.toString())
|
|
1463
|
-
} else {
|
|
1464
|
-
acc += `${_value.substr(0, maxLength)}...`
|
|
1465
|
-
}
|
|
1466
|
-
}
|
|
1467
|
-
break
|
|
1468
|
-
}
|
|
1469
|
-
case ('date'): {
|
|
1470
|
-
if (getValidation(restriction, data, getValueByKeys_getValueByKeys)) {
|
|
1471
|
-
const _value = getValueByKeys_getValueByKeys(value.split('.'), data) || ''
|
|
1472
|
-
acc += (formatDate(_value, format).toString())
|
|
1473
|
-
}
|
|
1474
|
-
break
|
|
1475
|
-
}
|
|
1476
|
-
case ('templateCompiler'): {
|
|
1477
|
-
if (getValidation(restriction, data, getValueByKeys_getValueByKeys)) {
|
|
1478
|
-
const templateCompiler = new TemplateCompiler({ data })
|
|
1479
|
-
acc += templateCompiler.pipe(value)
|
|
1480
|
-
}
|
|
1481
|
-
break
|
|
1482
|
-
}
|
|
1483
|
-
}
|
|
1484
|
-
return acc
|
|
1485
|
-
}, '')
|
|
1486
|
-
}
|
|
1487
|
-
/* harmony default export */ const concatStringByArray_concatStringByArray = ({
|
|
1488
|
-
concatStringByArray
|
|
1489
|
-
});
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
;// ./lib/helpers/concatStringByArray/index.js
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
;// ./lib/helpers/convertString/convertString.js
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
function convertString(string, patternMatch = /\$\{(.+?)\}/g, value, getValueByKeys) {
|
|
1500
|
-
if (!string) {
|
|
1501
|
-
return ''
|
|
1502
|
-
}
|
|
1503
|
-
let _getValueByKeys = typeof getValueByKeys === 'function' ? getValueByKeys : getValueByKeys_getValueByKeys
|
|
1504
|
-
const reg = new RegExp(patternMatch, 'g')
|
|
1505
|
-
return string.replace(reg, (match, key) => {
|
|
1506
|
-
const result = _getValueByKeys({ keys: key.split('.'), obj: value })
|
|
1507
|
-
if (result === null || result === undefined) {
|
|
1508
|
-
return ''
|
|
1509
|
-
}
|
|
1510
|
-
return typeof result === 'object' ? JSON.stringify(result) : result
|
|
1511
|
-
})
|
|
1512
|
-
}
|
|
1513
|
-
|
|
1514
|
-
/* harmony default export */ const convertString_convertString = ({
|
|
1515
|
-
convertString
|
|
1516
|
-
});
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
;// ./lib/helpers/convertString/index.js
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
;// ./lib/helpers/escapeRegex/escapeRegex.js
|
|
1523
|
-
function escapeRegex(string) {
|
|
1524
|
-
return String(string).replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')
|
|
1525
|
-
}
|
|
1526
|
-
|
|
1527
|
-
;// ./lib/helpers/escapeRegex/index.js
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
;// ./lib/helpers/expressHelper/customHandler.js
|
|
1531
|
-
function customHandler({ responseHelper, handler, ignoreError = false }) {
|
|
1532
|
-
return async (req, res, next) => {
|
|
1533
|
-
try {
|
|
1534
|
-
await handler({ req, res })
|
|
1535
|
-
await next()
|
|
1536
|
-
} catch (err) {
|
|
1537
|
-
if (ignoreError) {
|
|
1538
|
-
await next()
|
|
1539
|
-
} else {
|
|
1540
|
-
res.status(400).json(responseHelper.standardizeResponse({ err, message: err.message || err }))
|
|
1541
|
-
}
|
|
1542
|
-
}
|
|
1543
|
-
}
|
|
1544
|
-
}
|
|
1545
|
-
|
|
1546
|
-
;// ./lib/helpers/expressHelper/findAllResult.js
|
|
1547
|
-
function findAllResult({ responseHelper, service }) {
|
|
1548
|
-
return async (req, res, next) => {
|
|
1549
|
-
try {
|
|
1550
|
-
const { query } = req
|
|
1551
|
-
const result = await service.findAll({ query })
|
|
1552
|
-
res.locals.findAllResult = result
|
|
1553
|
-
await next()
|
|
1554
|
-
} catch (err) {
|
|
1555
|
-
res.status(400).json(responseHelper.standardizeResponse({ err, message: err.message || err }))
|
|
1556
|
-
}
|
|
1557
|
-
}
|
|
1558
|
-
}
|
|
1559
|
-
|
|
1560
|
-
;// ./lib/helpers/expressHelper/findOneResult.js
|
|
1561
|
-
function findOneResult({ responseHelper, service }) {
|
|
1562
|
-
return async (req, res, next) => {
|
|
1563
|
-
try {
|
|
1564
|
-
const { params, query } = req
|
|
1565
|
-
const { id } = params
|
|
1566
|
-
const result = await service.findOne({
|
|
1567
|
-
query: {
|
|
1568
|
-
...query,
|
|
1569
|
-
id
|
|
1570
|
-
}
|
|
1571
|
-
})
|
|
1572
|
-
res.locals.findOneResult = result
|
|
1573
|
-
await next()
|
|
1574
|
-
} catch (err) {
|
|
1575
|
-
res.status(400).json(responseHelper.standardizeResponse({ err, message: err.message || err }))
|
|
1576
|
-
}
|
|
1577
|
-
}
|
|
1578
|
-
}
|
|
1579
|
-
|
|
1580
|
-
;// ./lib/helpers/expressHelper/postResult.js
|
|
1581
|
-
function postResult({ responseHelper, service }) {
|
|
1582
|
-
return async (req, res, next) => {
|
|
1583
|
-
try {
|
|
1584
|
-
const { body } = req
|
|
1585
|
-
let result
|
|
1586
|
-
if (Array.isArray(body)) {
|
|
1587
|
-
result = await service.saveAll({ docs: body })
|
|
1588
|
-
} else {
|
|
1589
|
-
result = await service.saveOne({ doc: body })
|
|
1590
|
-
}
|
|
1591
|
-
res.locals.postResult = result
|
|
1592
|
-
await next()
|
|
1593
|
-
} catch (err) {
|
|
1594
|
-
res.status(400).json(responseHelper.standardizeResponse({ err, message: err.message || err }))
|
|
1595
|
-
}
|
|
1596
|
-
}
|
|
1597
|
-
}
|
|
1598
|
-
|
|
1599
|
-
;// ./lib/helpers/expressHelper/updateOneResult.js
|
|
1600
|
-
function updateOneResult({ responseHelper, service }) {
|
|
1601
|
-
return async (req, res, next) => {
|
|
1602
|
-
try {
|
|
1603
|
-
const { body, params } = req
|
|
1604
|
-
const { id } = params
|
|
1605
|
-
if (id !== body.id) {
|
|
1606
|
-
throw new Error('id in params and body must be same')
|
|
1607
|
-
}
|
|
1608
|
-
const { data } = await service.findOne({ query: { id } })
|
|
1609
|
-
const doc = data[0]
|
|
1610
|
-
doc.update(body)
|
|
1611
|
-
const result = await service.saveOne({ doc })
|
|
1612
|
-
res.locals.updateOneResult = result
|
|
1613
|
-
await next()
|
|
1614
|
-
} catch (err) {
|
|
1615
|
-
res.status(400).json(responseHelper.standardizeResponse({ err, message: err.message || err }))
|
|
1616
|
-
}
|
|
1617
|
-
}
|
|
1618
|
-
}
|
|
1619
|
-
|
|
1620
|
-
;// ./lib/helpers/expressHelper/index.js
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
const expressHelper = {
|
|
1629
|
-
customHandler: customHandler,
|
|
1630
|
-
findAllResult: findAllResult,
|
|
1631
|
-
findOneResult: findOneResult,
|
|
1632
|
-
postResult: postResult,
|
|
1633
|
-
updateOneResult: updateOneResult,
|
|
1634
|
-
}
|
|
1635
|
-
|
|
1636
|
-
;// ./lib/helpers/extractEmails/extractEmails.js
|
|
1637
|
-
/**
|
|
1638
|
-
* Extracts and normalizes unique email addresses from an array containing messy entries
|
|
1639
|
-
* @param {Array} dirtyArray - Array that may contain emails in various formats (may include null/empty entries)
|
|
1640
|
-
* @returns {Array} Sorted array of unique, lowercase email addresses
|
|
1641
|
-
*/
|
|
1642
|
-
function extractEmails(dirtyArray) {
|
|
1643
|
-
const emailRegex = /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g
|
|
1644
|
-
const emails = new Set()
|
|
1645
|
-
|
|
1646
|
-
// Handle null/undefined input array
|
|
1647
|
-
if (!dirtyArray) return []
|
|
1648
|
-
|
|
1649
|
-
dirtyArray.forEach(entry => {
|
|
1650
|
-
// Skip null, undefined, empty, or whitespace-only entries
|
|
1651
|
-
if (!entry || typeof entry !== 'string' || !entry.trim()) return
|
|
1652
|
-
|
|
1653
|
-
try {
|
|
1654
|
-
const cleanEntry = entry
|
|
1655
|
-
.replace(/[\u200B-\u200D\uFEFF\u202A-\u202E]/g, '') // Remove hidden chars
|
|
1656
|
-
.replace(/[<>]/g, ' ') // Convert email delimiters to spaces
|
|
1657
|
-
.replace(/\s+/g, ' ') // Collapse multiple whitespace
|
|
1658
|
-
.trim()
|
|
1659
|
-
|
|
1660
|
-
// Extract all email matches
|
|
1661
|
-
const matches = cleanEntry.match(emailRegex)
|
|
1662
|
-
if (matches) {
|
|
1663
|
-
matches.forEach(email => emails.add(email.toLowerCase())) // Normalize to lowercase
|
|
1664
|
-
}
|
|
1665
|
-
} catch (e) {
|
|
1666
|
-
console.warn('Failed to process entry:', entry, e)
|
|
1667
|
-
}
|
|
1668
|
-
})
|
|
1669
|
-
|
|
1670
|
-
// Convert Set to array and sort alphabetically
|
|
1671
|
-
return Array.from(emails).sort((a, b) => a.localeCompare(b))
|
|
1672
|
-
}
|
|
1673
|
-
|
|
1674
|
-
;// ./lib/helpers/extractEmails/index.js
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
;// ./lib/helpers/objectHelper/objectHelper.js
|
|
1678
|
-
const objectHelper = {
|
|
1679
|
-
get(obj, path) {
|
|
1680
|
-
const parts = path.split('.')
|
|
1681
|
-
return parts.reduce((acc, part) => {
|
|
1682
|
-
if (part.endsWith('[]')) {
|
|
1683
|
-
// 处理数组遍历
|
|
1684
|
-
const key = part.slice(0, -2) // 去掉 '[]' 得到属性名
|
|
1685
|
-
if (Array.isArray(acc[key])) {
|
|
1686
|
-
return acc[key] // 返回整个数组
|
|
1687
|
-
}
|
|
1688
|
-
return [] // 如果不是数组,返回空数组
|
|
1689
|
-
}
|
|
1690
|
-
if (part.includes('[') && part.includes(']')) {
|
|
1691
|
-
// 处理数组索引
|
|
1692
|
-
const arrayMatch = part.match(/(\w+)\[(\d+)\]/)
|
|
1693
|
-
if (arrayMatch) {
|
|
1694
|
-
const key = arrayMatch[1]
|
|
1695
|
-
const index = arrayMatch[2]
|
|
1696
|
-
return acc && acc[key] && acc[key][index]
|
|
1697
|
-
}
|
|
1698
|
-
} else if (acc && Array.isArray(acc)) {
|
|
1699
|
-
// 如果当前值是数组,提取每个对象的指定属性
|
|
1700
|
-
return acc.map((item) => item[part])
|
|
1701
|
-
} else {
|
|
1702
|
-
// 处理普通属性
|
|
1703
|
-
return acc && acc[part]
|
|
1704
|
-
}
|
|
1705
|
-
}, obj)
|
|
1706
|
-
},
|
|
1707
|
-
merge,
|
|
1708
|
-
set(obj, path, value) {
|
|
1709
|
-
const parts = path.split('.');
|
|
1710
|
-
let current = obj;
|
|
1711
|
-
|
|
1712
|
-
// 处理所有中间部分
|
|
1713
|
-
for (let i = 0; i < parts.length - 1; i++) {
|
|
1714
|
-
const part = parts[i];
|
|
1715
|
-
let key, index;
|
|
1716
|
-
|
|
1717
|
-
// 检查是否是数组索引格式,如key[0]
|
|
1718
|
-
const arrayMatch = part.match(/^(\w+)\[(\d+)\]$/);
|
|
1719
|
-
if (arrayMatch) {
|
|
1720
|
-
key = arrayMatch[1];
|
|
1721
|
-
index = parseInt(arrayMatch[2], 10);
|
|
1722
|
-
// 确保当前层级的数组存在
|
|
1723
|
-
if (!current[key] || !Array.isArray(current[key])) {
|
|
1724
|
-
current[key] = [];
|
|
1725
|
-
}
|
|
1726
|
-
// 扩展数组到足够大
|
|
1727
|
-
while (current[key].length <= index) {
|
|
1728
|
-
current[key].push(undefined);
|
|
1729
|
-
}
|
|
1730
|
-
// 如果当前位置未定义或为null,初始化为对象
|
|
1731
|
-
if (current[key][index] == null) {
|
|
1732
|
-
current[key][index] = {};
|
|
1733
|
-
}
|
|
1734
|
-
current = current[key][index];
|
|
1735
|
-
} else {
|
|
1736
|
-
// 处理普通属性
|
|
1737
|
-
if (!current[part]) {
|
|
1738
|
-
current[part] = {};
|
|
1739
|
-
}
|
|
1740
|
-
current = current[part];
|
|
1741
|
-
}
|
|
1742
|
-
}
|
|
1743
|
-
|
|
1744
|
-
// 处理最后一部分
|
|
1745
|
-
const lastPart = parts[parts.length - 1];
|
|
1746
|
-
const arrayMatch = lastPart.match(/^(\w+)\[(\d+)\]$/);
|
|
1747
|
-
if (arrayMatch) {
|
|
1748
|
-
const key = arrayMatch[1];
|
|
1749
|
-
const index = parseInt(arrayMatch[2], 10);
|
|
1750
|
-
// 确保数组存在
|
|
1751
|
-
if (!current[key] || !Array.isArray(current[key])) {
|
|
1752
|
-
current[key] = [];
|
|
1753
|
-
}
|
|
1754
|
-
// 扩展数组到所需索引
|
|
1755
|
-
while (current[key].length <= index) {
|
|
1756
|
-
current[key].push(undefined);
|
|
1757
|
-
}
|
|
1758
|
-
current[key][index] = value;
|
|
1759
|
-
} else {
|
|
1760
|
-
current[lastPart] = value;
|
|
1761
|
-
}
|
|
1762
|
-
}
|
|
1763
|
-
}
|
|
1764
|
-
|
|
1765
|
-
function merge(target, ...sources) {
|
|
1766
|
-
if (!sources.length) return target
|
|
1767
|
-
|
|
1768
|
-
const source = sources.shift() // 取出第一个源对象
|
|
1769
|
-
|
|
1770
|
-
if (_isObject(target) && _isObject(source)) {
|
|
1771
|
-
for (const key in source) {
|
|
1772
|
-
if (_isObject(source[key])) {
|
|
1773
|
-
if (!target[key]) {
|
|
1774
|
-
// 如果目标对象没有该属性,创建一个空对象
|
|
1775
|
-
target[key] = {}
|
|
1776
|
-
}
|
|
1777
|
-
// 递归合并
|
|
1778
|
-
merge(target[key], source[key])
|
|
1779
|
-
} else {
|
|
1780
|
-
// 直接覆盖
|
|
1781
|
-
target[key] = source[key]
|
|
1782
|
-
}
|
|
1783
|
-
}
|
|
1784
|
-
}
|
|
1785
|
-
|
|
1786
|
-
// 继续合并剩余的源对象
|
|
1787
|
-
return merge(target, ...sources)
|
|
1788
|
-
}
|
|
1789
|
-
|
|
1790
|
-
function _isObject(obj) {
|
|
1791
|
-
return obj && typeof obj === 'object' && !Array.isArray(obj)
|
|
1792
|
-
}
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
;// ./lib/helpers/objectHelper/index.js
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
;// ./lib/helpers/pReduce/pReduce.js
|
|
1802
|
-
async function pReduce(iterable, reducer, initialValue) {
|
|
1803
|
-
return new Promise((resolve, reject) => {
|
|
1804
|
-
const iterator = iterable[Symbol.iterator]()
|
|
1805
|
-
let index = 0
|
|
1806
|
-
|
|
1807
|
-
const next = async total => {
|
|
1808
|
-
const element = iterator.next()
|
|
1809
|
-
|
|
1810
|
-
if (element.done) {
|
|
1811
|
-
resolve(total)
|
|
1812
|
-
return
|
|
1813
|
-
}
|
|
1814
|
-
|
|
1815
|
-
try {
|
|
1816
|
-
const [resolvedTotal, resolvedValue] = await Promise.all([total, element.value])
|
|
1817
|
-
next(reducer(resolvedTotal, resolvedValue, index++))
|
|
1818
|
-
} catch (error) {
|
|
1819
|
-
reject(error)
|
|
1820
|
-
}
|
|
1821
|
-
}
|
|
1822
|
-
|
|
1823
|
-
next(initialValue)
|
|
1824
|
-
})
|
|
1825
|
-
}
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
;// ./lib/models/repo/repo.js
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
class Repo {
|
|
1833
|
-
constructor(options) {
|
|
1834
|
-
options = options || {}
|
|
1835
|
-
this.model = options.model
|
|
1836
|
-
this._sharedOptions = options._sharedOptions // { session: this.dbTransaction }
|
|
1837
|
-
this._queryOptions = options._queryOptions
|
|
1838
|
-
this._saveOptions = options._saveOptions
|
|
1839
|
-
this._Class = options._constructor && options._constructor._Class
|
|
1840
|
-
? options._constructor._Class
|
|
1841
|
-
: null
|
|
1842
|
-
}
|
|
1843
|
-
static init(options = {}) {
|
|
1844
|
-
return init(this, options)
|
|
1845
|
-
}
|
|
1846
|
-
static get _classname() {
|
|
1847
|
-
return 'Repo'
|
|
1848
|
-
}
|
|
1849
|
-
static get _superclass() {
|
|
1850
|
-
return 'Repo'
|
|
1851
|
-
}
|
|
1852
|
-
|
|
1853
|
-
get _classname() {
|
|
1854
|
-
return 'Repo'
|
|
1855
|
-
}
|
|
1856
|
-
|
|
1857
|
-
get _superclass() {
|
|
1858
|
-
return 'Repo'
|
|
1859
|
-
}
|
|
1860
|
-
|
|
1861
|
-
get isValid() {
|
|
1862
|
-
return this.model
|
|
1863
|
-
&& (typeof this.model.deleteOne === 'function')
|
|
1864
|
-
&& (typeof this.model.findAll === 'function')
|
|
1865
|
-
&& (typeof this.model.saveOne === 'function')
|
|
1866
|
-
}
|
|
1867
|
-
|
|
1868
|
-
get queryOptions() {
|
|
1869
|
-
return {
|
|
1870
|
-
...this._sharedOptions,
|
|
1871
|
-
...this._queryOptions,
|
|
1872
|
-
}
|
|
1873
|
-
}
|
|
1874
|
-
|
|
1875
|
-
get saveOptions() {
|
|
1876
|
-
return {
|
|
1877
|
-
...this._sharedOptions,
|
|
1878
|
-
...this._saveOptions,
|
|
1879
|
-
}
|
|
1880
|
-
}
|
|
1881
|
-
|
|
1882
|
-
init(options) {
|
|
1883
|
-
if (this._Class && typeof this._Class.init === 'function') {
|
|
1884
|
-
return this._Class.init(options)
|
|
1885
|
-
}
|
|
1886
|
-
return options
|
|
1887
|
-
}
|
|
1888
|
-
|
|
1889
|
-
async deleteOne({ id }) {
|
|
1890
|
-
try {
|
|
1891
|
-
const result = await this.model.deleteOne({ _id: id })
|
|
1892
|
-
return {
|
|
1893
|
-
...result, // { message: 'ok', total }
|
|
1894
|
-
isNew: false,
|
|
1895
|
-
data: []
|
|
1896
|
-
}
|
|
1897
|
-
} catch (err) {
|
|
1898
|
-
throw err
|
|
1899
|
-
}
|
|
1900
|
-
}
|
|
1901
|
-
|
|
1902
|
-
// systemLog is optional
|
|
1903
|
-
findAll({ query, systemLog }) {
|
|
1904
|
-
const log = _makeLog({
|
|
1905
|
-
systemLog,
|
|
1906
|
-
label: 'REPO_READ',
|
|
1907
|
-
message: `fn ${this._classname}.prototype.findAll`,
|
|
1908
|
-
input: [{ query: { ...query }, systemLog: { ...systemLog } }]
|
|
1909
|
-
})
|
|
1910
|
-
return new Promise((resolve, reject) => {
|
|
1911
|
-
this.model.findAll(query, this.queryOptions, (err, data, total) => {
|
|
1912
|
-
if (err) {
|
|
1913
|
-
log({ level: 'warn', output: err.toString() })
|
|
1914
|
-
reject(err)
|
|
1915
|
-
} else {
|
|
1916
|
-
const result = {
|
|
1917
|
-
isNew: false,
|
|
1918
|
-
data,
|
|
1919
|
-
total: total || data.length
|
|
1920
|
-
}
|
|
1921
|
-
log({ level: 'info', output: { ...result } })
|
|
1922
|
-
resolve(result)
|
|
1923
|
-
}
|
|
1924
|
-
})
|
|
1925
|
-
})
|
|
1926
|
-
}
|
|
1927
|
-
|
|
1928
|
-
findOne({ query, systemLog }) {
|
|
1929
|
-
const log = _makeLog({
|
|
1930
|
-
systemLog,
|
|
1931
|
-
label: 'REPO_READ',
|
|
1932
|
-
message: `fn ${this._classname}.prototype.findOne`,
|
|
1933
|
-
input: [{ query: { ...query }, systemLog: { ...systemLog } }]
|
|
1934
|
-
})
|
|
1935
|
-
return new Promise((resolve, reject) => {
|
|
1936
|
-
this.model.findAll(query, this.queryOptions, (err, data) => {
|
|
1937
|
-
if (err) {
|
|
1938
|
-
reject(err)
|
|
1939
|
-
} else if (data.length === 1) {
|
|
1940
|
-
const result = {
|
|
1941
|
-
isNew: false,
|
|
1942
|
-
data,
|
|
1943
|
-
total: 1
|
|
1944
|
-
}
|
|
1945
|
-
log({ level: 'info', output: { ...result } })
|
|
1946
|
-
resolve(result)
|
|
1947
|
-
} else if (data.length === 0) {
|
|
1948
|
-
reject(new Error('record not found'))
|
|
1949
|
-
} else {
|
|
1950
|
-
reject(new Error('more than one is found'))
|
|
1951
|
-
}
|
|
1952
|
-
})
|
|
1953
|
-
})
|
|
1954
|
-
.catch((err) => {
|
|
1955
|
-
log({ level: 'warn', output: err.toString() })
|
|
1956
|
-
throw err
|
|
1957
|
-
})
|
|
1958
|
-
}
|
|
1959
|
-
|
|
1960
|
-
saveAll({ config = {}, docs, systemLog }) {
|
|
1961
|
-
let isNew
|
|
1962
|
-
const log = _makeLog({
|
|
1963
|
-
systemLog,
|
|
1964
|
-
label: 'REPO_WRITE',
|
|
1965
|
-
message: `fn ${this._classname}.prototype.saveAll`,
|
|
1966
|
-
input: [{ config, docs: [...docs], systemLog: { ...systemLog } }]
|
|
1967
|
-
})
|
|
1968
|
-
const promise = typeof this.model.saveAll === 'function'
|
|
1969
|
-
? this.model.saveAll({ config, docs })
|
|
1970
|
-
: Promise.all(docs.map(async (doc) => {
|
|
1971
|
-
if (doc) {
|
|
1972
|
-
const result = await this.saveOne({ config, doc })
|
|
1973
|
-
isNew = result.isNew
|
|
1974
|
-
const _data = result._data || result.data
|
|
1975
|
-
return _data[0]
|
|
1976
|
-
}
|
|
1977
|
-
return null
|
|
1978
|
-
}))
|
|
1979
|
-
return promise.then((savedData) => {
|
|
1980
|
-
if (savedData.length !== 1) isNew = null
|
|
1981
|
-
const result = {
|
|
1982
|
-
data: savedData,
|
|
1983
|
-
isNew,
|
|
1984
|
-
total: savedData.length
|
|
1985
|
-
}
|
|
1986
|
-
log({ level: 'info', output: { ...result } })
|
|
1987
|
-
return result
|
|
1988
|
-
}).catch((err) => {
|
|
1989
|
-
log({ level: 'warn', output: err.toString() })
|
|
1990
|
-
throw err
|
|
1991
|
-
})
|
|
1992
|
-
}
|
|
1993
|
-
|
|
1994
|
-
saveOne({ config = {}, doc, systemLog }) {
|
|
1995
|
-
const log = _makeLog({
|
|
1996
|
-
systemLog,
|
|
1997
|
-
label: 'REPO_WRITE',
|
|
1998
|
-
message: `fn ${this._classname}.prototype.saveOne`,
|
|
1999
|
-
input: [{ config, doc: { ...doc }, systemLog: { ...systemLog } }]
|
|
2000
|
-
})
|
|
2001
|
-
const saveOptions = {
|
|
2002
|
-
...this.saveOptions,
|
|
2003
|
-
...config,
|
|
2004
|
-
}
|
|
2005
|
-
return new Promise((resolve, reject) => {
|
|
2006
|
-
this.model.saveOne(doc, saveOptions, (err, result) => {
|
|
2007
|
-
if (err) {
|
|
2008
|
-
log({ level: 'warn', output: err.toString() })
|
|
2009
|
-
reject(err)
|
|
2010
|
-
} else {
|
|
2011
|
-
log({ level: 'info', output: { ...result } })
|
|
2012
|
-
resolve(result)
|
|
2013
|
-
}
|
|
2014
|
-
})
|
|
2015
|
-
})
|
|
2016
|
-
}
|
|
2017
|
-
}
|
|
2018
|
-
|
|
2019
|
-
function _makeLog({ systemLog, label, message: message1, input } = {}) {
|
|
2020
|
-
return ({ level, messgae: massage2, output } = {}) => {
|
|
2021
|
-
if (systemLog && systemLog.systemLogHelper) {
|
|
2022
|
-
systemLog.systemLogHelper.log({
|
|
2023
|
-
batchId: systemLog.batchId,
|
|
2024
|
-
label,
|
|
2025
|
-
level,
|
|
2026
|
-
message: massage2 || message1,
|
|
2027
|
-
data: {
|
|
2028
|
-
payload: {
|
|
2029
|
-
input,
|
|
2030
|
-
output
|
|
2031
|
-
}
|
|
2032
|
-
}
|
|
2033
|
-
})
|
|
2034
|
-
}
|
|
2035
|
-
}
|
|
2036
|
-
}
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
;// ./lib/models/repo/index.js
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
;// ./lib/models/apiResponse/apiResponse.js
|
|
2046
|
-
class ApiResponse {
|
|
2047
|
-
constructor(options = {}) {
|
|
2048
|
-
options = options || {}
|
|
2049
|
-
this._data = options.data || options._data || []
|
|
2050
|
-
this.err = options.err
|
|
2051
|
-
this.isNew = options.isNew || false
|
|
2052
|
-
this.message = options.message
|
|
2053
|
-
this.total = options.total || 0
|
|
2054
|
-
this._instanceBuilder = options._instanceBuilder
|
|
2055
|
-
}
|
|
2056
|
-
|
|
2057
|
-
static init(options = {}) {
|
|
2058
|
-
if (options instanceof this) {
|
|
2059
|
-
return options
|
|
2060
|
-
}
|
|
2061
|
-
const instance = new this(options)
|
|
2062
|
-
return instance
|
|
2063
|
-
}
|
|
2064
|
-
static get _classname() {
|
|
2065
|
-
return 'ApiResponse'
|
|
2066
|
-
}
|
|
2067
|
-
static get _superclass() {
|
|
2068
|
-
return 'ApiResponse'
|
|
2069
|
-
}
|
|
2070
|
-
|
|
2071
|
-
// getters
|
|
2072
|
-
get data() {
|
|
2073
|
-
if (this._instanceBuilder && (typeof this._instanceBuilder === 'function')) {
|
|
2074
|
-
return this._data.map(this._instanceBuilder)
|
|
2075
|
-
}
|
|
2076
|
-
return this._data
|
|
2077
|
-
}
|
|
2078
|
-
}
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
;// ./lib/models/apiResponse/makeApiResponse.js
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
function makeApiResponse({ repo, result }) {
|
|
2086
|
-
return ApiResponse.init({
|
|
2087
|
-
...result,
|
|
2088
|
-
_instanceBuilder: (i) => {
|
|
2089
|
-
return repo.init(i)
|
|
2090
|
-
}
|
|
2091
|
-
})
|
|
2092
|
-
}
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
;// ./lib/models/service/service.js
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
class Service {
|
|
2101
|
-
constructor({ repo }) {
|
|
2102
|
-
this.repo = repo
|
|
2103
|
-
}
|
|
2104
|
-
|
|
2105
|
-
static get _classname() {
|
|
2106
|
-
return 'Service'
|
|
2107
|
-
}
|
|
2108
|
-
static get _superclass() {
|
|
2109
|
-
return 'Service'
|
|
2110
|
-
}
|
|
2111
|
-
|
|
2112
|
-
deleteOne({ id }) {
|
|
2113
|
-
return this.repo.deleteOne({ id })
|
|
2114
|
-
.catch(() => {
|
|
2115
|
-
throw new Error(`Not found for query: ${id}`)
|
|
2116
|
-
})
|
|
2117
|
-
}
|
|
2118
|
-
|
|
2119
|
-
async findAll({ query = {}, systemLog } = {}) {
|
|
2120
|
-
const result = await this.repo.findAll({ query, systemLog })
|
|
2121
|
-
return makeApiResponse({
|
|
2122
|
-
repo: this.repo,
|
|
2123
|
-
result
|
|
2124
|
-
})
|
|
2125
|
-
}
|
|
2126
|
-
|
|
2127
|
-
async findOne({ query = {}, systemLog } = {}) {
|
|
2128
|
-
const result = await this.repo.findOne({ query, systemLog })
|
|
2129
|
-
return makeApiResponse({
|
|
2130
|
-
repo: this.repo,
|
|
2131
|
-
result
|
|
2132
|
-
})
|
|
2133
|
-
}
|
|
2134
|
-
|
|
2135
|
-
init(options) {
|
|
2136
|
-
return this.repo.init(options)
|
|
2137
|
-
}
|
|
2138
|
-
initFromArray(arr = []) {
|
|
2139
|
-
if (Array.isArray(arr)) {
|
|
2140
|
-
return arr.map((a) => this.init(a))
|
|
2141
|
-
}
|
|
2142
|
-
return []
|
|
2143
|
-
}
|
|
2144
|
-
initOnlyValidFromArray(arr = []) {
|
|
2145
|
-
return this.initFromArray(arr).filter((i) => i)
|
|
2146
|
-
}
|
|
2147
|
-
|
|
2148
|
-
async saveAll({ config = {}, docs = [], systemLog } = {}) {
|
|
2149
|
-
const copies = docs.map((doc) => {
|
|
2150
|
-
return config.skipInit ? doc : this.init(doc)
|
|
2151
|
-
})
|
|
2152
|
-
const result = await this.repo.saveAll({ config, docs: copies, systemLog })
|
|
2153
|
-
return makeApiResponse({
|
|
2154
|
-
repo: this.repo,
|
|
2155
|
-
result
|
|
2156
|
-
})
|
|
2157
|
-
}
|
|
2158
|
-
|
|
2159
|
-
// set skipInit to true if we want to use POST for query
|
|
2160
|
-
async saveOne({ config = {}, doc = {}, systemLog } = {}) {
|
|
2161
|
-
const copy = config.skipInit ? doc : this.init(doc)
|
|
2162
|
-
if (copy) {
|
|
2163
|
-
const result = await this.repo.saveOne({ config, doc: copy, systemLog })
|
|
2164
|
-
return makeApiResponse({
|
|
2165
|
-
repo: this.repo,
|
|
2166
|
-
result
|
|
2167
|
-
})
|
|
2168
|
-
}
|
|
2169
|
-
return {
|
|
2170
|
-
isNew: null,
|
|
2171
|
-
data: [],
|
|
2172
|
-
err: new Error('doc is not a valid instance')
|
|
2173
|
-
}
|
|
2174
|
-
}
|
|
2175
|
-
}
|
|
2176
|
-
|
|
2177
|
-
function makeService({ repo }) {
|
|
2178
|
-
if (repo === undefined) {
|
|
2179
|
-
throw new Error('repo is required.')
|
|
2180
|
-
}
|
|
2181
|
-
if (repo._superclass !== Repo._superclass) {
|
|
2182
|
-
throw new Error('repo is not an instance of Repo.')
|
|
2183
|
-
}
|
|
2184
|
-
return new Service({ repo })
|
|
2185
|
-
}
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
;// ./lib/models/service/index.js
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
;// ./lib/helpers/generalPost/generalPost.js
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
async function generalPost({ body = {}, GeneralModel, UniqueKeyGenerator, resourceInfo }) {
|
|
2201
|
-
const { resources, data, globalShared = {}, shared = {}, relationship = {} } = body
|
|
2202
|
-
const _resourceInfo = resourceInfo || body.resourceInfo
|
|
2203
|
-
_attachShared(data, globalShared, shared)
|
|
2204
|
-
const obj = await pReduce(resources, async (acc, resource) => {
|
|
2205
|
-
const service = _makeService(resource, _resourceInfo, UniqueKeyGenerator, GeneralModel)
|
|
2206
|
-
_createRelationship(data, relationship[resource], acc)
|
|
2207
|
-
const _data = data[resource]
|
|
2208
|
-
const result = await service.saveAll({ docs: [].concat(_data) })
|
|
2209
|
-
acc[resource] = Array.isArray(_data) ? result._data : result._data[0]
|
|
2210
|
-
return acc
|
|
2211
|
-
}, {})
|
|
2212
|
-
return obj
|
|
2213
|
-
}
|
|
2214
|
-
|
|
2215
|
-
function _attachShared(data, globalShared = {}, shared = {}) {
|
|
2216
|
-
Object.keys(shared).forEach((key) => {
|
|
2217
|
-
const _data = data[key]
|
|
2218
|
-
if (Array.isArray(_data)) {
|
|
2219
|
-
data[key] = _data.map((_dataItem) => {
|
|
2220
|
-
return objectHelper.merge({}, _dataItem, globalShared, shared[key] || {})
|
|
2221
|
-
})
|
|
2222
|
-
} else {
|
|
2223
|
-
data[key] = objectHelper.merge({}, _data, globalShared, shared[key] || {})
|
|
2224
|
-
}
|
|
2225
|
-
})
|
|
2226
|
-
}
|
|
2227
|
-
|
|
2228
|
-
function _createRelationship(data, relationship = {}, object) {
|
|
2229
|
-
Object.keys(relationship).forEach((key) => {
|
|
2230
|
-
const path = relationship[key]
|
|
2231
|
-
const val = objectHelper.get(object, path)
|
|
2232
|
-
objectHelper.set(data, key, val)
|
|
2233
|
-
})
|
|
2234
|
-
}
|
|
2235
|
-
|
|
2236
|
-
function _makeService(resource, resourceInfo, UniqueKeyGenerator, GeneralModel) {
|
|
2237
|
-
const { collectionName, fields } = resourceInfo[resource]
|
|
2238
|
-
const uniqueKeyGenerator = UniqueKeyGenerator.makeGenerator(fields)
|
|
2239
|
-
const model = new GeneralModel({ collectionName, uniqueKeyGenerator })
|
|
2240
|
-
return makeService({
|
|
2241
|
-
repo: new Repo({ model })
|
|
2242
|
-
})
|
|
2243
|
-
}
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
;// ./lib/helpers/generalPost/index.js
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
;// ./lib/helpers/init/init.js
|
|
2253
|
-
function init(_class, options) {
|
|
2254
|
-
if (options instanceof _class) {
|
|
2255
|
-
return options
|
|
2256
|
-
}
|
|
2257
|
-
try {
|
|
2258
|
-
const instance = new _class(options)
|
|
2259
|
-
return instance.isValid !== false ? instance : null
|
|
2260
|
-
} catch (e) {
|
|
2261
|
-
console.log(`init failed for class: ${_class._classname || 'no _classname'}`, e)
|
|
2262
|
-
return null
|
|
2263
|
-
}
|
|
2264
|
-
}
|
|
2265
|
-
|
|
2266
|
-
;// ./lib/helpers/init/index.js
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
;// ./lib/helpers/initFromArray/initFromArray.js
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
function initFromArray(_class, arr) {
|
|
2273
|
-
if (Array.isArray(arr)) {
|
|
2274
|
-
return arr.map((a) => init(_class, a))
|
|
2275
|
-
}
|
|
2276
|
-
return []
|
|
2277
|
-
}
|
|
2278
|
-
|
|
2279
|
-
;// ./lib/helpers/initFromArray/index.js
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
;// ./lib/helpers/initOnlyValidFromArray/initOnlyValidFromArray.js
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
function initOnlyValidFromArray(_class, arr) {
|
|
2286
|
-
return initFromArray(_class, arr).filter((i) => i)
|
|
2287
|
-
}
|
|
2288
|
-
|
|
2289
|
-
;// ./lib/helpers/initOnlyValidFromArray/index.js
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
;// ./lib/helpers/mergeArraysByKey/mergeArraysByKey.js
|
|
2293
|
-
function mergeArraysByKey(arr1, arr2) {
|
|
2294
|
-
// Handle undefined/null inputs by defaulting to empty arrays
|
|
2295
|
-
const safeArr1 = Array.isArray(arr1) ? arr1 : []
|
|
2296
|
-
const safeArr2 = Array.isArray(arr2) ? arr2 : []
|
|
2297
|
-
|
|
2298
|
-
const mergedMap = new Map()
|
|
2299
|
-
|
|
2300
|
-
// Helper function to merge values based on their type
|
|
2301
|
-
const mergeValues = (existingValue, newValue) => {
|
|
2302
|
-
if (existingValue === undefined) return newValue
|
|
2303
|
-
|
|
2304
|
-
// Handle arrays by concatenating
|
|
2305
|
-
if (Array.isArray(existingValue) && Array.isArray(newValue)) {
|
|
2306
|
-
return [...new Set([...existingValue, ...newValue])]
|
|
2307
|
-
}
|
|
2308
|
-
|
|
2309
|
-
// Handle objects by merging
|
|
2310
|
-
if (typeof existingValue === 'object' && typeof newValue === 'object' &&
|
|
2311
|
-
!Array.isArray(existingValue) && !Array.isArray(newValue)) {
|
|
2312
|
-
return { ...existingValue, ...newValue }
|
|
2313
|
-
}
|
|
2314
|
-
|
|
2315
|
-
// // Handle numbers by adding
|
|
2316
|
-
// if (typeof existingValue === 'number' && typeof newValue === 'number') {
|
|
2317
|
-
// return existingValue
|
|
2318
|
-
// }
|
|
2319
|
-
|
|
2320
|
-
// // Handle strings by concatenating
|
|
2321
|
-
// if (typeof existingValue === 'string' && typeof newValue === 'string') {
|
|
2322
|
-
// return existingValue
|
|
2323
|
-
// }
|
|
2324
|
-
|
|
2325
|
-
// Default: use the new value
|
|
2326
|
-
return newValue
|
|
2327
|
-
}
|
|
2328
|
-
|
|
2329
|
-
// Process first array
|
|
2330
|
-
safeArr1.forEach(item => {
|
|
2331
|
-
mergedMap.set(item.key, item.value)
|
|
2332
|
-
})
|
|
2333
|
-
|
|
2334
|
-
// Process second array and merge values
|
|
2335
|
-
safeArr2.forEach(item => {
|
|
2336
|
-
const existingValue = mergedMap.get(item.key)
|
|
2337
|
-
mergedMap.set(item.key, mergeValues(existingValue, item.value))
|
|
2338
|
-
})
|
|
2339
|
-
|
|
2340
|
-
// Convert back to array format
|
|
2341
|
-
return Array.from(mergedMap.entries()).map(([key, value]) => ({
|
|
2342
|
-
key,
|
|
2343
|
-
value
|
|
2344
|
-
}))
|
|
2345
|
-
}
|
|
2346
|
-
|
|
2347
|
-
;// ./lib/helpers/mergeArraysByKey/index.js
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
;// ./lib/helpers/padZeros/padZeros.js
|
|
2351
|
-
function padZeros(num, minLength = 6) {
|
|
2352
|
-
num = num.toString()
|
|
2353
|
-
if (num.length < minLength) {
|
|
2354
|
-
return padZeros('0' + num, minLength)
|
|
2355
|
-
}
|
|
2356
|
-
return num
|
|
2357
|
-
}
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
;// ./lib/helpers/padZeros/index.js
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
;// ./lib/helpers/pReduce/index.js
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
;// ./lib/helpers/replacePlaceholders/replacePlaceholders.js
|
|
2372
|
-
function replacePlaceholders({ content, mapping }) {
|
|
2373
|
-
let isObjectMode = false
|
|
2374
|
-
|
|
2375
|
-
if (typeof content === 'object' && content !== null) {
|
|
2376
|
-
content = JSON.stringify(content)
|
|
2377
|
-
isObjectMode = true
|
|
2378
|
-
}
|
|
2379
|
-
|
|
2380
|
-
// [[ eventRegistration.eventRegistrationCode | 0 ]]
|
|
2381
|
-
const regex = /(\[*)\[\[\s*([\w.\-_]+)(?:\s*\|\s*([^:\]\s]+))?(?:\s*:\s*([^\]\s]+))?\s*\]\](\]*)/g;
|
|
2382
|
-
|
|
2383
|
-
const result = content.replace(regex, (match, leadingBrackets, path, defaultValue, type, trailingBrackets) => {
|
|
2384
|
-
|
|
2385
|
-
// Split the path into parts
|
|
2386
|
-
const keys = path.trim().split('.')
|
|
2387
|
-
|
|
2388
|
-
// Traverse the nested object structure
|
|
2389
|
-
let value = mapping
|
|
2390
|
-
for (const key of keys) {
|
|
2391
|
-
// Handle empty keys (in case of double dots or leading/trailing dots)
|
|
2392
|
-
if (!key) continue
|
|
2393
|
-
|
|
2394
|
-
value = value?.[key]
|
|
2395
|
-
if (value === undefined) {
|
|
2396
|
-
break
|
|
2397
|
-
}
|
|
2398
|
-
}
|
|
2399
|
-
|
|
2400
|
-
// Apply default if missing
|
|
2401
|
-
if (value === undefined) value = defaultValue?.trim();
|
|
2402
|
-
if (value === undefined) return isObjectMode ? undefined : match;
|
|
2403
|
-
|
|
2404
|
-
value = value !== undefined
|
|
2405
|
-
? leadingBrackets + value + trailingBrackets
|
|
2406
|
-
: match
|
|
2407
|
-
|
|
2408
|
-
// Return replacement or original if not found
|
|
2409
|
-
return value
|
|
2410
|
-
})
|
|
2411
|
-
|
|
2412
|
-
if (isObjectMode) {
|
|
2413
|
-
return JSON.parse(result)
|
|
2414
|
-
}
|
|
2415
|
-
return result
|
|
2416
|
-
}
|
|
2417
|
-
|
|
2418
|
-
;// ./lib/helpers/replacePlaceholders/index.js
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
;// ./lib/helpers/sanitizeText/sanitizeText.js
|
|
2422
|
-
/**
|
|
2423
|
-
* Sanitizes input by removing hidden/control characters with customizable whitespace handling.
|
|
2424
|
-
* @param {string} input - The string to sanitize.
|
|
2425
|
-
* @param {Object} [options] - Configuration options.
|
|
2426
|
-
* @param {boolean} [options.normalizeWhitespace=true] - Collapse multiple spaces/tabs into one space.
|
|
2427
|
-
* @param {boolean} [options.removeNewlines=false] - If true, replaces newlines with spaces.
|
|
2428
|
-
* @param {boolean} [options.trim=true] - If true, trims leading/trailing whitespace.
|
|
2429
|
-
* @returns {string} The sanitized string.
|
|
2430
|
-
*/
|
|
2431
|
-
function sanitizeText(input, options = {}) {
|
|
2432
|
-
const {
|
|
2433
|
-
normalizeWhitespace = true,
|
|
2434
|
-
removeNewlines = false,
|
|
2435
|
-
trim = true,
|
|
2436
|
-
} = options
|
|
2437
|
-
|
|
2438
|
-
if (typeof input !== 'string') {
|
|
2439
|
-
return input
|
|
2440
|
-
}
|
|
2441
|
-
|
|
2442
|
-
let result = input
|
|
2443
|
-
|
|
2444
|
-
// Phase 1: Remove hidden/control characters
|
|
2445
|
-
result = result.replace(/[\u200B-\u200D\uFEFF\u202A-\u202E]/g, '')
|
|
2446
|
-
|
|
2447
|
-
// Phase 2: Handle whitespace transformations
|
|
2448
|
-
if (removeNewlines) {
|
|
2449
|
-
result = result.replace(/[\r\n]+/g, ' ') // Convert newlines to spaces
|
|
2450
|
-
}
|
|
2451
|
-
|
|
2452
|
-
if (normalizeWhitespace) {
|
|
2453
|
-
result = result.replace(/[ \t]+/g, ' ') // Collapse spaces/tabs to single space
|
|
2454
|
-
}
|
|
2455
|
-
|
|
2456
|
-
// Phase 3: Final trimming
|
|
2457
|
-
if (trim) {
|
|
2458
|
-
result = result.trim()
|
|
2459
|
-
}
|
|
2460
|
-
|
|
2461
|
-
return result
|
|
2462
|
-
}
|
|
2463
|
-
|
|
2464
|
-
;// ./lib/helpers/sanitizeText/index.js
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
;// ./lib/helpers/stringFormatter/stringFormatter.js
|
|
2468
|
-
function stringFormatter(str, delimiter = '_') {
|
|
2469
|
-
if (str === null || typeof str === 'undefined' || typeof str.toString === 'undefined') {
|
|
2470
|
-
return null
|
|
2471
|
-
}
|
|
2472
|
-
return str.toString()
|
|
2473
|
-
.trim()
|
|
2474
|
-
.toUpperCase()
|
|
2475
|
-
.replace('-', delimiter)
|
|
2476
|
-
.replace(' ', delimiter)
|
|
2477
|
-
}
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
;// ./lib/helpers/stringFormatter/index.js
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
;// ./lib/helpers/stringHelper/stringHelper.js
|
|
2487
|
-
function baseXEncode(num, base = 34) {
|
|
2488
|
-
const charset = getBaseCharset(base)
|
|
2489
|
-
return encode(num, charset)
|
|
2490
|
-
}
|
|
2491
|
-
|
|
2492
|
-
function encode(int, charset) {
|
|
2493
|
-
const { byCode } = charset
|
|
2494
|
-
if (int === 0) {
|
|
2495
|
-
return byCode[0]
|
|
2496
|
-
}
|
|
2497
|
-
|
|
2498
|
-
let res = ''
|
|
2499
|
-
const max = charset.length
|
|
2500
|
-
while (int > 0) {
|
|
2501
|
-
res = byCode[int % max] + res
|
|
2502
|
-
int = Math.floor(int / max)
|
|
2503
|
-
}
|
|
2504
|
-
return res
|
|
2505
|
-
}
|
|
2506
|
-
|
|
2507
|
-
function getBaseCharset(base) {
|
|
2508
|
-
let charset = '9876543210ABCDEFGHJKLMNPQRSTUVWXYZ'
|
|
2509
|
-
if (base === 58) {
|
|
2510
|
-
charset = '9876543210ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz'
|
|
2511
|
-
}
|
|
2512
|
-
return indexCharset(charset)
|
|
2513
|
-
}
|
|
2514
|
-
|
|
2515
|
-
function indexCharset(str) {
|
|
2516
|
-
const byCode = {}
|
|
2517
|
-
const byChar = {}
|
|
2518
|
-
const { length } = str
|
|
2519
|
-
let char
|
|
2520
|
-
for (let i = 0; i < length; i++) {
|
|
2521
|
-
char = str[i]
|
|
2522
|
-
byCode[i] = char
|
|
2523
|
-
byChar[char] = i;
|
|
2524
|
-
}
|
|
2525
|
-
return { byCode, byChar, length }
|
|
2526
|
-
}
|
|
2527
|
-
|
|
2528
|
-
function isSame(str1, str2) {
|
|
2529
|
-
if (typeof str1 !== 'string' || typeof str2 !== 'string') {
|
|
2530
|
-
return false
|
|
2531
|
-
}
|
|
2532
|
-
return str1.trim().toUpperCase() === str2.trim().toUpperCase()
|
|
2533
|
-
}
|
|
2534
|
-
|
|
2535
|
-
function randomString({ len = 16, pattern = 'a1' } = {}) {
|
|
2536
|
-
const A = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
|
2537
|
-
const a = 'abcdefghijklmnopqrstuvwxyz'
|
|
2538
|
-
const num = '1234567890'
|
|
2539
|
-
const mark = '~!@#$%^&*_+-='
|
|
2540
|
-
let str = ''
|
|
2541
|
-
if (pattern.includes('A')) {
|
|
2542
|
-
str += A
|
|
2543
|
-
}
|
|
2544
|
-
if (pattern.includes('a')) {
|
|
2545
|
-
str += a
|
|
2546
|
-
}
|
|
2547
|
-
if (pattern.includes('1')) {
|
|
2548
|
-
str += num
|
|
2549
|
-
}
|
|
2550
|
-
if (pattern.includes('#')) {
|
|
2551
|
-
str += mark
|
|
2552
|
-
}
|
|
2553
|
-
const chars = [...str]
|
|
2554
|
-
return [...Array(len)].map(i => {
|
|
2555
|
-
return chars[(Math.random() * chars.length) | 0]
|
|
2556
|
-
}).join``
|
|
2557
|
-
}
|
|
2558
|
-
|
|
2559
|
-
function reverse(str) {
|
|
2560
|
-
const _str = (typeof str !== 'string') ? str.toString() : str
|
|
2561
|
-
const splitString = _str.split('')
|
|
2562
|
-
const reverseArray = splitString.reverse()
|
|
2563
|
-
return reverseArray.join('')
|
|
2564
|
-
}
|
|
2565
|
-
|
|
2566
|
-
function setCode(base = 34) {
|
|
2567
|
-
const now = (new Date()).valueOf()
|
|
2568
|
-
const random = randomString({
|
|
2569
|
-
len: 8,
|
|
2570
|
-
pattern: '1'
|
|
2571
|
-
})
|
|
2572
|
-
const str = reverse(`${now}${random}`)
|
|
2573
|
-
// const str = `${now}${random}`
|
|
2574
|
-
return baseXEncode(str, base)
|
|
2575
|
-
}
|
|
2576
|
-
|
|
2577
|
-
function toCamelCase(str) {
|
|
2578
|
-
if (!str) return ''
|
|
2579
|
-
return str
|
|
2580
|
-
.trim()
|
|
2581
|
-
.split(/\s+/)
|
|
2582
|
-
.map((word, index) => {
|
|
2583
|
-
if (!word) return ''
|
|
2584
|
-
if (index === 0) {
|
|
2585
|
-
return word.toLowerCase()
|
|
2586
|
-
}
|
|
2587
|
-
return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()
|
|
2588
|
-
})
|
|
2589
|
-
.join('')
|
|
2590
|
-
}
|
|
2591
|
-
|
|
2592
|
-
function toLowerCase(str) {
|
|
2593
|
-
if (!str) return ''
|
|
2594
|
-
return str
|
|
2595
|
-
.trim()
|
|
2596
|
-
.toLowerCase()
|
|
2597
|
-
}
|
|
2598
|
-
|
|
2599
|
-
const stringHelper = {
|
|
2600
|
-
isSame,
|
|
2601
|
-
setCode,
|
|
2602
|
-
toCamelCase,
|
|
2603
|
-
toLowerCase,
|
|
2604
|
-
}
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
;// ./lib/helpers/stringHelper/index.js
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
;// ./lib/helpers/trackingPlugin/trackingPlugin.js
|
|
2614
|
-
function trackingPlugin(schema, options) {
|
|
2615
|
-
// Add meta fields
|
|
2616
|
-
schema.add({
|
|
2617
|
-
meta: {
|
|
2618
|
-
active: { type: Boolean, default: true },
|
|
2619
|
-
created: { type: Number },
|
|
2620
|
-
creator: { type: String },
|
|
2621
|
-
deleted: { type: Boolean, default: false },
|
|
2622
|
-
modified: { type: Number },
|
|
2623
|
-
owner: { type: String },
|
|
2624
|
-
}
|
|
2625
|
-
})
|
|
2626
|
-
|
|
2627
|
-
// Auto-update hook
|
|
2628
|
-
schema.pre('save', function(next) {
|
|
2629
|
-
this.meta.modified = Date.now()
|
|
2630
|
-
next()
|
|
2631
|
-
})
|
|
2632
|
-
|
|
2633
|
-
// Add core indexes
|
|
2634
|
-
schema.index({
|
|
2635
|
-
'meta.active': 1,
|
|
2636
|
-
'meta.deleted': 1
|
|
2637
|
-
}, {
|
|
2638
|
-
name: 'tracking_status_index',
|
|
2639
|
-
background: true,
|
|
2640
|
-
partialFilterExpression: {
|
|
2641
|
-
'meta.active': true,
|
|
2642
|
-
'meta.deleted': false
|
|
2643
|
-
}
|
|
2644
|
-
})
|
|
2645
|
-
|
|
2646
|
-
// Optional: Add helper methods
|
|
2647
|
-
// schema.methods.touch = function(userId) {
|
|
2648
|
-
// this.meta.updatedAt = new Date()
|
|
2649
|
-
// this.meta.updatedBy = userId
|
|
2650
|
-
// }
|
|
2651
|
-
}
|
|
2652
|
-
|
|
2653
|
-
;// ./lib/helpers/tenantPlugin/tenantPlugin.js
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
function tenantPlugin(schema, options) {
|
|
2657
|
-
// Apply tracking plugin first if not already present
|
|
2658
|
-
if (!schema.path('meta')) {
|
|
2659
|
-
trackingPlugin(schema, options)
|
|
2660
|
-
}
|
|
2661
|
-
|
|
2662
|
-
// Add tenant-specific fields
|
|
2663
|
-
schema.add({
|
|
2664
|
-
metadata: [{ type: Object }], // Instead of Schema.Types.Mixed
|
|
2665
|
-
remarks: [{ type: Object }],
|
|
2666
|
-
tenantCode: { type: String, required: true }
|
|
2667
|
-
})
|
|
2668
|
-
|
|
2669
|
-
// Add core indexes
|
|
2670
|
-
schema.index({
|
|
2671
|
-
'tenantCode': 1
|
|
2672
|
-
}, {
|
|
2673
|
-
name: 'tenant_core_index',
|
|
2674
|
-
background: true
|
|
2675
|
-
})
|
|
2676
|
-
|
|
2677
|
-
// 1. ENHANCE EXISTING TRACKING INDEXES
|
|
2678
|
-
const existingIndexes = schema.indexes()
|
|
2679
|
-
|
|
2680
|
-
// Check if tracking_status_index exists
|
|
2681
|
-
const hasTenantStatusIndex = existingIndexes.some(idx =>
|
|
2682
|
-
idx.name === 'tenant_status_index' // Check by name for reliability
|
|
2683
|
-
)
|
|
2684
|
-
|
|
2685
|
-
if (!hasTenantStatusIndex) {
|
|
2686
|
-
schema.index({
|
|
2687
|
-
'tenantCode': 1, // Unique field first
|
|
2688
|
-
_type: 1, // Low-cardinality field last
|
|
2689
|
-
}, {
|
|
2690
|
-
name: 'tenant_status_index',
|
|
2691
|
-
background: true,
|
|
2692
|
-
partialFilterExpression: {
|
|
2693
|
-
'_type': 'Tenant',
|
|
2694
|
-
'meta.active': true,
|
|
2695
|
-
'meta.deleted': false
|
|
2696
|
-
}
|
|
2697
|
-
})
|
|
2698
|
-
}
|
|
2699
|
-
}
|
|
2700
|
-
|
|
2701
|
-
;// ./lib/helpers/tenantPlugin/index.js
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
;// ./lib/helpers/trackingPlugin/index.js
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
;// ./lib/helpers/index.js
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
;// ./lib/models/apiResponse/index.js
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
;// ./lib/models/awsStsS3Client/awsStsS3Client.js
|
|
2740
|
-
class AwsStsS3Client {
|
|
2741
|
-
constructor(options) {
|
|
2742
|
-
options = options || {}
|
|
2743
|
-
|
|
2744
|
-
this.expiration = options.expiration || null
|
|
2745
|
-
this.s3Client = options.s3Client || null
|
|
2746
|
-
this.getIdToken = options.getIdToken
|
|
2747
|
-
this.region = options.region || 'ap-east-1'
|
|
2748
|
-
this.roleArn = options.roleArn
|
|
2749
|
-
this.roleSessionName = options.roleSessionName || 'web-identity-session'
|
|
2750
|
-
this.durationSession = options.durationSession || 3600
|
|
2751
|
-
this.awsClientSts = options.awsClientSts
|
|
2752
|
-
this.awsClientS3 = options.awsClientS3
|
|
2753
|
-
}
|
|
2754
|
-
|
|
2755
|
-
static dummyData() {
|
|
2756
|
-
return {
|
|
2757
|
-
getIdToken: () => 'mock-web-identity-token',
|
|
2758
|
-
roleArn: 'arn:aws:iam::846252828949:role/oidcS3Jccpa',
|
|
2759
|
-
awsClientSts: {
|
|
2760
|
-
STSClient: class {},
|
|
2761
|
-
AssumeRoleWithWebIdentityCommand: class {}
|
|
2762
|
-
},
|
|
2763
|
-
awsClientS3: {
|
|
2764
|
-
S3Client: class {},
|
|
2765
|
-
PutObjectCommand: class {},
|
|
2766
|
-
GetObjectCommand: class {},
|
|
2767
|
-
DeleteObjectCommand: class {}
|
|
2768
|
-
}
|
|
2769
|
-
}
|
|
2770
|
-
}
|
|
2771
|
-
|
|
2772
|
-
static init(options = {}) {
|
|
2773
|
-
if (options instanceof this) {
|
|
2774
|
-
return options
|
|
2775
|
-
}
|
|
2776
|
-
try {
|
|
2777
|
-
const instance = new this(options)
|
|
2778
|
-
if (!instance.isValid) {
|
|
2779
|
-
return null
|
|
2780
|
-
}
|
|
2781
|
-
return instance
|
|
2782
|
-
} catch (error) {
|
|
2783
|
-
return null
|
|
2784
|
-
}
|
|
2785
|
-
}
|
|
2786
|
-
|
|
2787
|
-
get isExpired() {
|
|
2788
|
-
if (!this.expiration) return true;
|
|
2789
|
-
const now = new Date();
|
|
2790
|
-
const bufferMs = 1 * 60 * 1000; // 一分钟缓冲
|
|
2791
|
-
return now >= new Date(this.expiration.getTime() - bufferMs);
|
|
2792
|
-
}
|
|
2793
|
-
|
|
2794
|
-
get isValid() {
|
|
2795
|
-
if (!this.getIdToken) {
|
|
2796
|
-
throw new Error('Missing required configuration: getIdToken function')
|
|
2797
|
-
}
|
|
2798
|
-
if (!this.roleArn) {
|
|
2799
|
-
throw new Error('Missing required configuration: roleArn')
|
|
2800
|
-
}
|
|
2801
|
-
if (!this.awsClientSts) {
|
|
2802
|
-
throw new Error('Missing required AWS awsClientSts client configuration')
|
|
2803
|
-
}
|
|
2804
|
-
if (!this.awsClientSts.STSClient) {
|
|
2805
|
-
throw new Error('Missing STSClient in AWS awsClientSts client configuration')
|
|
2806
|
-
}
|
|
2807
|
-
if (!this.awsClientSts.AssumeRoleWithWebIdentityCommand) {
|
|
2808
|
-
throw new Error('Missing AssumeRoleWithWebIdentityCommand in AWS awsClientSts client configuration')
|
|
2809
|
-
}
|
|
2810
|
-
if (!this.awsClientS3) {
|
|
2811
|
-
throw new Error('Missing required AWS awsClientS3 client configuration')
|
|
2812
|
-
}
|
|
2813
|
-
|
|
2814
|
-
const requiredS3Components = [
|
|
2815
|
-
'S3Client',
|
|
2816
|
-
'PutObjectCommand',
|
|
2817
|
-
'GetObjectCommand',
|
|
2818
|
-
'DeleteObjectCommand'
|
|
2819
|
-
]
|
|
2820
|
-
|
|
2821
|
-
for (const component of requiredS3Components) {
|
|
2822
|
-
if (!this.awsClientS3[component]) {
|
|
2823
|
-
throw new Error(`Missing ${component} in AWS awsClientS3 client configuration`)
|
|
2824
|
-
}
|
|
2825
|
-
}
|
|
2826
|
-
|
|
2827
|
-
return true
|
|
2828
|
-
}
|
|
2829
|
-
|
|
2830
|
-
async refreshCredentials() {
|
|
2831
|
-
try {
|
|
2832
|
-
const webIdentityToken = await this.getIdToken()
|
|
2833
|
-
if (!webIdentityToken) {
|
|
2834
|
-
throw new Error('getIdToken function returned empty or invalid token')
|
|
2835
|
-
}
|
|
2836
|
-
|
|
2837
|
-
const stsClient = new this.awsClientSts.STSClient({ region: this.region })
|
|
2838
|
-
|
|
2839
|
-
const stsResponse = await stsClient.send(
|
|
2840
|
-
new this.awsClientSts.AssumeRoleWithWebIdentityCommand({
|
|
2841
|
-
RoleArn: this.roleArn,
|
|
2842
|
-
RoleSessionName: this.roleSessionName,
|
|
2843
|
-
WebIdentityToken: await this.getIdToken(),
|
|
2844
|
-
DurationSeconds: this.durationSession,
|
|
2845
|
-
})
|
|
2846
|
-
)
|
|
2847
|
-
|
|
2848
|
-
const credentials = stsResponse.Credentials
|
|
2849
|
-
if (!credentials) {
|
|
2850
|
-
throw new Error('No credentials returned from awsClientSts')
|
|
2851
|
-
}
|
|
2852
|
-
|
|
2853
|
-
this.expiration = credentials.Expiration
|
|
2854
|
-
|
|
2855
|
-
this.s3Client = new this.awsClientS3.S3Client({
|
|
2856
|
-
region: this.region,
|
|
2857
|
-
credentials: {
|
|
2858
|
-
accessKeyId: credentials.AccessKeyId,
|
|
2859
|
-
secretAccessKey: credentials.SecretAccessKey,
|
|
2860
|
-
sessionToken: credentials.SessionToken,
|
|
2861
|
-
}
|
|
2862
|
-
})
|
|
2863
|
-
|
|
2864
|
-
return this
|
|
2865
|
-
} catch (error) {
|
|
2866
|
-
throw new Error(`Failed to refresh credentials: ${error.message}`)
|
|
2867
|
-
}
|
|
2868
|
-
}
|
|
2869
|
-
|
|
2870
|
-
async getS3Client() {
|
|
2871
|
-
if (this.isExpired || !this.s3Client) {
|
|
2872
|
-
await this.refreshCredentials()
|
|
2873
|
-
}
|
|
2874
|
-
return this.s3Client
|
|
2875
|
-
}
|
|
2876
|
-
|
|
2877
|
-
async putObject(params) {
|
|
2878
|
-
try {
|
|
2879
|
-
const client = await this.getS3Client()
|
|
2880
|
-
const command = new this.awsClientS3.PutObjectCommand(params)
|
|
2881
|
-
await client.send(command)
|
|
2882
|
-
const fileArr = params.Key.split('/')
|
|
2883
|
-
return {
|
|
2884
|
-
url: `https://s3.${this.region}.amazonaws.com/${params.Bucket}/${params.Key}`,
|
|
2885
|
-
filename: fileArr.pop(),
|
|
2886
|
-
folder: params.Bucket,
|
|
2887
|
-
subFolders: fileArr
|
|
2888
|
-
}
|
|
2889
|
-
} catch (error) {
|
|
2890
|
-
throw new Error(`Failed to put object: ${error.message}`)
|
|
2891
|
-
}
|
|
2892
|
-
}
|
|
2893
|
-
|
|
2894
|
-
async getObject(params) {
|
|
2895
|
-
try {
|
|
2896
|
-
const client = await this.getS3Client()
|
|
2897
|
-
const command = new this.awsClientS3.GetObjectCommand(params)
|
|
2898
|
-
const response = await client.send(command)
|
|
2899
|
-
return {
|
|
2900
|
-
body: response.Body,
|
|
2901
|
-
contentType: response.ContentType,
|
|
2902
|
-
lastModified: response.LastModified,
|
|
2903
|
-
contentLength: response.ContentLength,
|
|
2904
|
-
}
|
|
2905
|
-
} catch (error) {
|
|
2906
|
-
throw new Error(`Failed to get object: ${error.message}`)
|
|
2907
|
-
}
|
|
2908
|
-
}
|
|
2909
|
-
|
|
2910
|
-
async deleteObject(params) {
|
|
2911
|
-
try {
|
|
2912
|
-
const client = await this.getS3Client()
|
|
2913
|
-
const command = new this.awsClientS3.DeleteObjectCommand(params)
|
|
2914
|
-
await client.send(command)
|
|
2915
|
-
return true
|
|
2916
|
-
} catch (error) {
|
|
2917
|
-
throw new Error(`Failed to delete object: ${error.message}`)
|
|
2918
|
-
}
|
|
2919
|
-
}
|
|
2920
|
-
}
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
;// ./lib/models/awsStsS3Client/index.js
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
;// ./lib/models/keyValueObject/keyValueObject.js
|
|
2930
|
-
class KeyValueObject {
|
|
2931
|
-
constructor(options = {}) {
|
|
2932
|
-
options = options || {}
|
|
2933
|
-
this.key = options.key || null
|
|
2934
|
-
this.value = (typeof options.value !== 'undefined') ? options.value : ''
|
|
2935
|
-
}
|
|
2936
|
-
|
|
2937
|
-
// Class methods
|
|
2938
|
-
static init(options = {}) {
|
|
2939
|
-
if (options instanceof this) {
|
|
2940
|
-
return options
|
|
2941
|
-
}
|
|
2942
|
-
const instance = new this(options)
|
|
2943
|
-
return instance.isValid ? instance : null
|
|
2944
|
-
}
|
|
2945
|
-
static initFromArray(arr = []) {
|
|
2946
|
-
if (Array.isArray(arr)) {
|
|
2947
|
-
return arr.map((a) => this.init(a))
|
|
2948
|
-
}
|
|
2949
|
-
return []
|
|
2950
|
-
}
|
|
2951
|
-
static initOnlyValidFromArray(arr = []) {
|
|
2952
|
-
return this.initFromArray(arr).filter((i) => i)
|
|
2953
|
-
}
|
|
2954
|
-
static get _classname() {
|
|
2955
|
-
return 'KeyValueObject'
|
|
2956
|
-
}
|
|
2957
|
-
static get _superclass() {
|
|
2958
|
-
return 'KeyValueObject'
|
|
2959
|
-
}
|
|
2960
|
-
|
|
2961
|
-
static addItem(arr, key, value) {
|
|
2962
|
-
arr.push(this.init({ key, value }))
|
|
2963
|
-
}
|
|
2964
|
-
static addRecord(arr = [], key, value) {
|
|
2965
|
-
if (!this.hasKeyValue(arr, key, value)) {
|
|
2966
|
-
arr.push(this.init({ key, value }))
|
|
2967
|
-
}
|
|
2968
|
-
return arr
|
|
2969
|
-
}
|
|
2970
|
-
static appendRecord(arr = [], key, value) {
|
|
2971
|
-
return arr.map((item) => {
|
|
2972
|
-
if (this.sameKey(item, key)) {
|
|
2973
|
-
item.value = [...item.value, ...value]
|
|
2974
|
-
}
|
|
2975
|
-
return item
|
|
2976
|
-
})
|
|
2977
|
-
}
|
|
2978
|
-
static appendValueArray(arr = [], key, value) {
|
|
2979
|
-
return arr.map((item) => {
|
|
2980
|
-
if (this.sameKey(item, key)) {
|
|
2981
|
-
item.value = [...item.value, ...value]
|
|
2982
|
-
}
|
|
2983
|
-
return item
|
|
2984
|
-
})
|
|
2985
|
-
}
|
|
2986
|
-
static foundByKey(arr = [], key) {
|
|
2987
|
-
const found = arr.find((m) => {
|
|
2988
|
-
return this.sameKey(m, key)
|
|
2989
|
-
})
|
|
2990
|
-
return found || null
|
|
2991
|
-
}
|
|
2992
|
-
static foundValueByKey(arr = [], key) {
|
|
2993
|
-
const found = this.foundByKey(arr, key)
|
|
2994
|
-
return found ? found.value : null
|
|
2995
|
-
}
|
|
2996
|
-
static fromObject(options = {}) {
|
|
2997
|
-
return Object.keys(options).reduce((acc, key) => {
|
|
2998
|
-
acc.push(this.init({ key, value: options[key] }))
|
|
2999
|
-
return acc
|
|
3000
|
-
}, [])
|
|
3001
|
-
}
|
|
3002
|
-
static getValueByKey(arr = [], key) {
|
|
3003
|
-
return this.foundValueByKey(arr, key)
|
|
3004
|
-
}
|
|
3005
|
-
static getValueByKeyFromArray(arr = [], key) {
|
|
3006
|
-
if (arr.length === 0) {
|
|
3007
|
-
return null
|
|
3008
|
-
}
|
|
3009
|
-
const firstArr = arr.shift()
|
|
3010
|
-
const found = firstArr.find((i) => {
|
|
3011
|
-
return this.sameKey(i, key)
|
|
3012
|
-
})
|
|
3013
|
-
if (found && found.value) {
|
|
3014
|
-
return found.value
|
|
3015
|
-
}
|
|
3016
|
-
return this.getValueByKeyFromArray(arr, key)
|
|
3017
|
-
}
|
|
3018
|
-
static getValuesByKey(arr = [], key) {
|
|
3019
|
-
return arr.reduce((acc, item) => {
|
|
3020
|
-
if (this.sameKey(item, key)) {
|
|
3021
|
-
acc.push(item.value)
|
|
3022
|
-
}
|
|
3023
|
-
return acc
|
|
3024
|
-
}, [])
|
|
3025
|
-
}
|
|
3026
|
-
static hasKeyValue(arr = [], key, value) {
|
|
3027
|
-
if (typeof value === 'undefined') {
|
|
3028
|
-
return arr.filter((item) => this.sameKey(item, key)).length > 0
|
|
3029
|
-
}
|
|
3030
|
-
return arr.filter((item) => (this.sameKey(item, key) && _isSame(item.value, value))).length > 0
|
|
3031
|
-
}
|
|
3032
|
-
static insertOrUpdateRecord(arr = [], key, value) {
|
|
3033
|
-
let copy = [...arr]
|
|
3034
|
-
if (!this.hasKeyValue(arr, key)) {
|
|
3035
|
-
copy.push(this.init({ key, value }))
|
|
3036
|
-
} else {
|
|
3037
|
-
copy = this.updateRecord(arr, key, value)
|
|
3038
|
-
}
|
|
3039
|
-
return copy
|
|
3040
|
-
}
|
|
3041
|
-
static keys(arr = []) {
|
|
3042
|
-
if (Array.isArray(arr)) {
|
|
3043
|
-
return arr.reduce((acc, item) => {
|
|
3044
|
-
acc.push(item.key)
|
|
3045
|
-
return acc
|
|
3046
|
-
}, [])
|
|
3047
|
-
}
|
|
3048
|
-
return []
|
|
3049
|
-
}
|
|
3050
|
-
static merge(toArr, fromArr) {
|
|
3051
|
-
(fromArr || []).map((from) => {
|
|
3052
|
-
const found = toArr.find((to) => {
|
|
3053
|
-
return to.key === from.key
|
|
3054
|
-
})
|
|
3055
|
-
if (found) {
|
|
3056
|
-
found.value = _mergeValues(from.value, found.value)
|
|
3057
|
-
} else {
|
|
3058
|
-
toArr.push(from)
|
|
3059
|
-
}
|
|
3060
|
-
})
|
|
3061
|
-
return toArr
|
|
3062
|
-
}
|
|
3063
|
-
static removeByKey(arr, key) {
|
|
3064
|
-
return arr.reduce((acc, item) => {
|
|
3065
|
-
if (!this.sameKey(item, key)) {
|
|
3066
|
-
acc.push(item)
|
|
3067
|
-
}
|
|
3068
|
-
return acc
|
|
3069
|
-
}, [])
|
|
3070
|
-
}
|
|
3071
|
-
static sameKey(item, key) {
|
|
3072
|
-
if (item) {
|
|
3073
|
-
return _isSame(item.key, key)
|
|
3074
|
-
}
|
|
3075
|
-
return false
|
|
3076
|
-
}
|
|
3077
|
-
static toObject(arr = []) {
|
|
3078
|
-
if (Array.isArray(arr)) {
|
|
3079
|
-
return arr.reduce((acc, item) => {
|
|
3080
|
-
acc[item.key] = item.value
|
|
3081
|
-
return acc
|
|
3082
|
-
}, {})
|
|
3083
|
-
}
|
|
3084
|
-
return {}
|
|
3085
|
-
}
|
|
3086
|
-
static toString(arr = [], delimiter = '; ') {
|
|
3087
|
-
if (Array.isArray(arr)) {
|
|
3088
|
-
return arr.reduce((acc, item) => {
|
|
3089
|
-
acc.push(`${item.key}: ${item.value}`)
|
|
3090
|
-
return acc
|
|
3091
|
-
}, []).join(delimiter)
|
|
3092
|
-
}
|
|
3093
|
-
return ''
|
|
3094
|
-
}
|
|
3095
|
-
static updateRecord(arr = [], key, value) {
|
|
3096
|
-
return arr.map((item) => {
|
|
3097
|
-
if (this.sameKey(item, key)) {
|
|
3098
|
-
return {
|
|
3099
|
-
...item,
|
|
3100
|
-
value
|
|
3101
|
-
}
|
|
3102
|
-
}
|
|
3103
|
-
return item
|
|
3104
|
-
})
|
|
3105
|
-
}
|
|
3106
|
-
static updateOrInsertRecord(arr = [], key, value) {
|
|
3107
|
-
return this.insertOrUpdateRecord(arr, key, value)
|
|
3108
|
-
}
|
|
3109
|
-
static updateRecordsFromArray(arr = [], updateArr = []) {
|
|
3110
|
-
if (Array.isArray(arr) && Array.isArray(updateArr)) {
|
|
3111
|
-
const obj1 = this.toObject(arr)
|
|
3112
|
-
const obj2 = this.toObject(updateArr)
|
|
3113
|
-
return this.fromObject({
|
|
3114
|
-
...obj1,
|
|
3115
|
-
...obj2
|
|
3116
|
-
})
|
|
3117
|
-
}
|
|
3118
|
-
return []
|
|
3119
|
-
}
|
|
3120
|
-
static values(arr = []) {
|
|
3121
|
-
if (Array.isArray(arr)) {
|
|
3122
|
-
return arr.reduce((acc, item) => {
|
|
3123
|
-
acc.push(item.value)
|
|
3124
|
-
return acc
|
|
3125
|
-
}, [])
|
|
3126
|
-
}
|
|
3127
|
-
return []
|
|
3128
|
-
}
|
|
3129
|
-
|
|
3130
|
-
// getters
|
|
3131
|
-
get isValid() {
|
|
3132
|
-
return !!this.key
|
|
3133
|
-
}
|
|
3134
|
-
|
|
3135
|
-
get toObject() {
|
|
3136
|
-
const obj = {}
|
|
3137
|
-
if (this.isValid) {
|
|
3138
|
-
obj[this.key] = this.value
|
|
3139
|
-
}
|
|
3140
|
-
return obj
|
|
3141
|
-
}
|
|
3142
|
-
}
|
|
3143
|
-
|
|
3144
|
-
function _mergeValues(existingValue, newValue) {
|
|
3145
|
-
if (existingValue === undefined) return newValue
|
|
3146
|
-
|
|
3147
|
-
// Handle arrays by concatenating
|
|
3148
|
-
if (Array.isArray(existingValue) && Array.isArray(newValue)) {
|
|
3149
|
-
return [...new Set([...existingValue, ...newValue])]
|
|
3150
|
-
}
|
|
3151
|
-
|
|
3152
|
-
// Handle objects by merging
|
|
3153
|
-
if (typeof existingValue === 'object' && typeof newValue === 'object' &&
|
|
3154
|
-
!Array.isArray(existingValue) && !Array.isArray(newValue)) {
|
|
3155
|
-
return { ...existingValue, ...newValue }
|
|
3156
|
-
}
|
|
3157
|
-
|
|
3158
|
-
// // Handle numbers by adding
|
|
3159
|
-
// if (typeof existingValue === 'number' && typeof newValue === 'number') {
|
|
3160
|
-
// return existingValue
|
|
3161
|
-
// }
|
|
3162
|
-
|
|
3163
|
-
// // Handle strings by concatenating
|
|
3164
|
-
// if (typeof existingValue === 'string' && typeof newValue === 'string') {
|
|
3165
|
-
// return existingValue
|
|
3166
|
-
// }
|
|
3167
|
-
|
|
3168
|
-
// Default: use the new value
|
|
3169
|
-
return newValue
|
|
3170
|
-
}
|
|
3171
|
-
|
|
3172
|
-
function _isSame(key1, key2) {
|
|
3173
|
-
return key1 === key2
|
|
3174
|
-
}
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
-
|
|
3178
|
-
;// ./lib/models/keyValueObject/index.js
|
|
3179
|
-
|
|
3180
|
-
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
;// ./lib/models/metadata/metadata.js
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
const DELIMITER = '_'
|
|
3188
|
-
|
|
3189
|
-
class Metadata extends KeyValueObject {
|
|
3190
|
-
static init(options = {}) {
|
|
3191
|
-
if (options instanceof this) {
|
|
3192
|
-
return options
|
|
3193
|
-
}
|
|
3194
|
-
const instance = new this({
|
|
3195
|
-
...options,
|
|
3196
|
-
key: stringFormatter(options.key, DELIMITER),
|
|
3197
|
-
})
|
|
3198
|
-
return instance.isValid ? instance : null
|
|
3199
|
-
}
|
|
3200
|
-
static get _classname() {
|
|
3201
|
-
return 'Metadata'
|
|
3202
|
-
}
|
|
3203
|
-
|
|
3204
|
-
static merge(toArr, fromArr) {
|
|
3205
|
-
(fromArr || []).map((from) => {
|
|
3206
|
-
const found = toArr.find((to) => {
|
|
3207
|
-
return metadata_isSame(to.key, from.key)
|
|
3208
|
-
})
|
|
3209
|
-
if (found) {
|
|
3210
|
-
found.value = metadata_mergeValues(from.value, found.value)
|
|
3211
|
-
} else {
|
|
3212
|
-
toArr.push(from)
|
|
3213
|
-
}
|
|
3214
|
-
})
|
|
3215
|
-
return toArr
|
|
3216
|
-
}
|
|
3217
|
-
static sameKey(item, key) {
|
|
3218
|
-
return metadata_isSame(item.key, key)
|
|
3219
|
-
}
|
|
3220
|
-
}
|
|
3221
|
-
|
|
3222
|
-
function metadata_isSame(key1, key2) {
|
|
3223
|
-
return stringFormatter(key1, DELIMITER) === stringFormatter(key2, DELIMITER)
|
|
3224
|
-
}
|
|
3225
|
-
|
|
3226
|
-
function metadata_mergeValues(existingValue, newValue) {
|
|
3227
|
-
if (existingValue === undefined) return newValue
|
|
3228
|
-
|
|
3229
|
-
// Handle arrays by concatenating
|
|
3230
|
-
if (Array.isArray(existingValue) && Array.isArray(newValue)) {
|
|
3231
|
-
return [...new Set([...existingValue, ...newValue])]
|
|
3232
|
-
}
|
|
3233
|
-
|
|
3234
|
-
// Handle objects by merging
|
|
3235
|
-
if (typeof existingValue === 'object' && typeof newValue === 'object' &&
|
|
3236
|
-
!Array.isArray(existingValue) && !Array.isArray(newValue)) {
|
|
3237
|
-
return { ...existingValue, ...newValue }
|
|
3238
|
-
}
|
|
3239
|
-
|
|
3240
|
-
// // Handle numbers by adding
|
|
3241
|
-
// if (typeof existingValue === 'number' && typeof newValue === 'number') {
|
|
3242
|
-
// return existingValue
|
|
3243
|
-
// }
|
|
3244
|
-
|
|
3245
|
-
// // Handle strings by concatenating
|
|
3246
|
-
// if (typeof existingValue === 'string' && typeof newValue === 'string') {
|
|
3247
|
-
// return existingValue
|
|
3248
|
-
// }
|
|
3249
|
-
|
|
3250
|
-
// Default: use the new value
|
|
3251
|
-
return newValue
|
|
3252
|
-
}
|
|
3253
|
-
|
|
3254
|
-
|
|
3255
|
-
|
|
3256
|
-
;// ./lib/models/metadata/index.js
|
|
3257
|
-
|
|
3258
|
-
|
|
3259
|
-
|
|
3260
|
-
|
|
3261
|
-
;// ./lib/models/qMeta/qMeta.js
|
|
3262
|
-
|
|
3263
|
-
|
|
3264
|
-
const updateAllowedProps = [
|
|
3265
|
-
'attributes',
|
|
3266
|
-
'ref'
|
|
3267
|
-
]
|
|
3268
|
-
|
|
3269
|
-
class QMeta {
|
|
3270
|
-
constructor(options = {}) {
|
|
3271
|
-
options = options || {}
|
|
3272
|
-
this.attributes = KeyValueObject.initOnlyValidFromArray(options.attributes)
|
|
3273
|
-
this.ref = options.ref || {}
|
|
3274
|
-
}
|
|
3275
|
-
|
|
3276
|
-
static get _classname() {
|
|
3277
|
-
return 'QMeta'
|
|
3278
|
-
}
|
|
3279
|
-
static get _superclass() {
|
|
3280
|
-
return 'QMeta'
|
|
3281
|
-
}
|
|
3282
|
-
|
|
3283
|
-
// Class methods
|
|
3284
|
-
static init(options = {}) {
|
|
3285
|
-
if (options instanceof QMeta) {
|
|
3286
|
-
return options
|
|
3287
|
-
}
|
|
3288
|
-
return new QMeta(options)
|
|
3289
|
-
}
|
|
3290
|
-
|
|
3291
|
-
// instance methods
|
|
3292
|
-
addAttribute(obj) {
|
|
3293
|
-
const kvObject = KeyValueObject.init(obj)
|
|
3294
|
-
if (!kvObject) {
|
|
3295
|
-
throw new Error('invalid meta attribute')
|
|
3296
|
-
}
|
|
3297
|
-
this.attributes.push(kvObject)
|
|
3298
|
-
return this
|
|
3299
|
-
}
|
|
3300
|
-
|
|
3301
|
-
update(obj) {
|
|
3302
|
-
Object.keys(obj).forEach((key) => {
|
|
3303
|
-
if (updateAllowedProps.includes(key)) {
|
|
3304
|
-
if (key === 'attributes') {
|
|
3305
|
-
this[key] = KeyValueObject.initOnlyValidFromArray(obj[key])
|
|
3306
|
-
} else {
|
|
3307
|
-
this[key] = obj[key]
|
|
3308
|
-
}
|
|
3309
|
-
}
|
|
3310
|
-
})
|
|
3311
|
-
return this
|
|
3312
|
-
}
|
|
3313
|
-
}
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
;// ./lib/models/qMeta/index.js
|
|
3318
|
-
|
|
3319
|
-
|
|
3320
|
-
|
|
3321
|
-
|
|
3322
|
-
;// ./lib/models/trackedEntity/trackedEntity.js
|
|
3323
|
-
|
|
3324
|
-
|
|
3325
|
-
class TrackedEntity {
|
|
3326
|
-
constructor(options = {}) {
|
|
3327
|
-
options = options || {}
|
|
3328
|
-
const timestamp = Date.now()
|
|
3329
|
-
this.meta = {
|
|
3330
|
-
active: options.meta?.active ?? options.active ?? true,
|
|
3331
|
-
created: options.meta?.created ?? (options.created
|
|
3332
|
-
? new Date(options.created).getTime()
|
|
3333
|
-
: timestamp),
|
|
3334
|
-
creator: options.meta?.creator ?? options.creator ?? '',
|
|
3335
|
-
deleted: options.meta?.deleted ?? options.deleted ?? false,
|
|
3336
|
-
modified: options.meta?.modified ?? (options.modified
|
|
3337
|
-
? new Date(options.modified).getTime()
|
|
3338
|
-
: timestamp),
|
|
3339
|
-
owner: options.meta?.owner ?? options.owner ?? '',
|
|
3340
|
-
}
|
|
3341
|
-
|
|
3342
|
-
// if (trackFlat) {
|
|
3343
|
-
// Object.assign(this, _tracking)
|
|
3344
|
-
// } else {
|
|
3345
|
-
// this.meta = { ..._tracking, ...options.meta }
|
|
3346
|
-
// }
|
|
3347
|
-
}
|
|
3348
|
-
|
|
3349
|
-
// Class methods
|
|
3350
|
-
static get _classname() {
|
|
3351
|
-
return 'TrackedEntity'
|
|
3352
|
-
}
|
|
3353
|
-
static get _superclass() {
|
|
3354
|
-
return 'TrackedEntity'
|
|
3355
|
-
}
|
|
3356
|
-
|
|
3357
|
-
static init(options = {}) {
|
|
3358
|
-
return init(this, options)
|
|
3359
|
-
}
|
|
3360
|
-
static initFromArray(arr = []) {
|
|
3361
|
-
return initFromArray(this, arr)
|
|
3362
|
-
}
|
|
3363
|
-
static initOnlyValidFromArray(arr = []) {
|
|
3364
|
-
return initOnlyValidFromArray(this, arr)
|
|
3365
|
-
}
|
|
3366
|
-
// static nest(entity) {
|
|
3367
|
-
// const { active, created, creator, deleted, modified, owner, ...rest } = entity
|
|
3368
|
-
// return { ...rest, meta: { active, created, creator, deleted, modified, owner } }
|
|
3369
|
-
// }
|
|
3370
|
-
|
|
3371
|
-
// getters
|
|
3372
|
-
get isValid() {
|
|
3373
|
-
return !!this
|
|
3374
|
-
}
|
|
3375
|
-
get active() {
|
|
3376
|
-
return this.meta?.active ?? this.active
|
|
3377
|
-
}
|
|
3378
|
-
get created() {
|
|
3379
|
-
return this.meta?.created ?? this.created
|
|
3380
|
-
}
|
|
3381
|
-
get creator() {
|
|
3382
|
-
return this.meta?.creator ?? this.creator
|
|
3383
|
-
}
|
|
3384
|
-
get deleted() {
|
|
3385
|
-
return this.meta?.deleted ?? this.deleted
|
|
3386
|
-
}
|
|
3387
|
-
get modified() {
|
|
3388
|
-
return this.meta?.modified ?? this.modified
|
|
3389
|
-
}
|
|
3390
|
-
get owner() {
|
|
3391
|
-
return this.meta?.owner ?? this.owner
|
|
3392
|
-
}
|
|
3393
|
-
changeCreatorOwner({ source, target }) {
|
|
3394
|
-
return changeCreatorOwner(this, { source, target }).setModified()
|
|
3395
|
-
}
|
|
3396
|
-
delete() {
|
|
3397
|
-
return this.setDeleted()
|
|
3398
|
-
}
|
|
3399
|
-
setActive() {
|
|
3400
|
-
if (this.meta) {
|
|
3401
|
-
this.meta.active = true
|
|
3402
|
-
} else {
|
|
3403
|
-
this.active = true
|
|
3404
|
-
}
|
|
3405
|
-
return this
|
|
3406
|
-
}
|
|
3407
|
-
setDeleted() {
|
|
3408
|
-
if (this.meta) {
|
|
3409
|
-
this.meta.deleted = true
|
|
3410
|
-
} else {
|
|
3411
|
-
this.deleted = true
|
|
3412
|
-
}
|
|
3413
|
-
return this
|
|
3414
|
-
}
|
|
3415
|
-
setModified() {
|
|
3416
|
-
const timestamp = Date.now()
|
|
3417
|
-
if (this.meta) {
|
|
3418
|
-
this.meta.modified = timestamp
|
|
3419
|
-
} else {
|
|
3420
|
-
this.modified = timestamp
|
|
3421
|
-
}
|
|
3422
|
-
return this
|
|
3423
|
-
}
|
|
3424
|
-
setOwner(owner) {
|
|
3425
|
-
if (!owner) {
|
|
3426
|
-
return this
|
|
3427
|
-
}
|
|
3428
|
-
if (this.meta) {
|
|
3429
|
-
this.meta.owner = owner
|
|
3430
|
-
} else {
|
|
3431
|
-
this.owner = owner
|
|
3432
|
-
}
|
|
3433
|
-
return this
|
|
3434
|
-
}
|
|
3435
|
-
unsetActive() {
|
|
3436
|
-
if (this.meta) {
|
|
3437
|
-
this.meta.active = false
|
|
3438
|
-
} else {
|
|
3439
|
-
this.active = false
|
|
3440
|
-
}
|
|
3441
|
-
return this
|
|
3442
|
-
}
|
|
3443
|
-
unsetDeleted() {
|
|
3444
|
-
if (this.meta) {
|
|
3445
|
-
this.meta.deleted = false
|
|
3446
|
-
} else {
|
|
3447
|
-
this.deleted = false
|
|
3448
|
-
}
|
|
3449
|
-
return this
|
|
3450
|
-
}
|
|
3451
|
-
|
|
3452
|
-
update(update) {
|
|
3453
|
-
if (update.meta) {
|
|
3454
|
-
this.meta = { ...this.meta, ...update.meta }
|
|
3455
|
-
}
|
|
3456
|
-
return this.setModified()
|
|
3457
|
-
}
|
|
3458
|
-
}
|
|
3459
|
-
|
|
3460
|
-
;// ./lib/models/trackedEntity/index.js
|
|
3461
|
-
|
|
3462
|
-
// Explicit named export (optional)
|
|
3463
|
-
|
|
3464
|
-
;// ./lib/models/tenantAwareEntity/tenantAwareEntity.js
|
|
3465
|
-
|
|
3466
|
-
|
|
3467
|
-
|
|
3468
|
-
|
|
3469
|
-
class TenantAwareEntity extends TrackedEntity {
|
|
3470
|
-
constructor(options = {}) {
|
|
3471
|
-
options = options || {}
|
|
3472
|
-
|
|
3473
|
-
/**
|
|
3474
|
-
* instead of throw error, we choose to implement the isValid checking
|
|
3475
|
-
*/
|
|
3476
|
-
// if (!options.tenantCode) {
|
|
3477
|
-
// throw new Error('tenantCode required')
|
|
3478
|
-
// }
|
|
3479
|
-
|
|
3480
|
-
super(options)
|
|
3481
|
-
|
|
3482
|
-
this._tenant = options._tenant
|
|
3483
|
-
|
|
3484
|
-
this.metadata = Metadata.initOnlyValidFromArray(options.metadata)
|
|
3485
|
-
this.remarks = KeyValueObject.initOnlyValidFromArray(options.remarks)
|
|
3486
|
-
this.tenantCode = options.tenantCode // Required for multi-tenancy
|
|
3487
|
-
}
|
|
3488
|
-
|
|
3489
|
-
// Class methods
|
|
3490
|
-
static get _classname() {
|
|
3491
|
-
return 'TenantAwareEntity'
|
|
3492
|
-
}
|
|
3493
|
-
static get _superclass() {
|
|
3494
|
-
return 'TenantAwareEntity'
|
|
3495
|
-
}
|
|
3496
|
-
|
|
3497
|
-
// getters
|
|
3498
|
-
get isValid() {
|
|
3499
|
-
return super.isValid && !!this.tenantCode // Required for multi-tenancy
|
|
3500
|
-
}
|
|
3501
|
-
|
|
3502
|
-
// instance methods
|
|
3503
|
-
getMetadata() {
|
|
3504
|
-
return this.metadata
|
|
3505
|
-
}
|
|
3506
|
-
getMetadataByKey(key) {
|
|
3507
|
-
return Metadata.foundByKey(this.metadata, key)
|
|
3508
|
-
}
|
|
3509
|
-
getMetadataValueByKey(key) {
|
|
3510
|
-
const found = this.getMetadataByKey(key)
|
|
3511
|
-
return found ? found.value : null
|
|
3512
|
-
}
|
|
3513
|
-
getRemarks() {
|
|
3514
|
-
return this.remarks
|
|
3515
|
-
}
|
|
3516
|
-
getRemarkByKey(key) {
|
|
3517
|
-
return KeyValueObject.foundByKey(this.remarks, key)
|
|
3518
|
-
}
|
|
3519
|
-
getRemarksValueByKey(key) {
|
|
3520
|
-
const found = this.getRemarkByKey(key)
|
|
3521
|
-
return found ? found.value : null
|
|
3522
|
-
}
|
|
3523
|
-
getTenantCode() {
|
|
3524
|
-
return this.tenantCode
|
|
3525
|
-
}
|
|
3526
|
-
|
|
3527
|
-
update(update) {
|
|
3528
|
-
if (update.metadata && Array.isArray(update.metadata)) {
|
|
3529
|
-
this.metadata = Metadata.initOnlyValidFromArray(update.metadata)
|
|
3530
|
-
}
|
|
3531
|
-
if (update.remarks && Array.isArray(update.remarks)) {
|
|
3532
|
-
this.remarks = KeyValueObject.initOnlyValidFromArray(update.remarks)
|
|
3533
|
-
}
|
|
3534
|
-
return super.update(update)
|
|
3535
|
-
}
|
|
3536
|
-
}
|
|
3537
|
-
|
|
3538
|
-
;// ./lib/models/tenantAwareEntity/index.js
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
|
|
3542
|
-
;// ./lib/models/uniqueKeyGenerator/uniqueKeyGenerator.js
|
|
3543
|
-
|
|
3544
|
-
|
|
3545
|
-
class UniqueKeyGenerator {
|
|
3546
|
-
static get _classname() {
|
|
3547
|
-
return 'UniqueKeyGenerator'
|
|
3548
|
-
}
|
|
3549
|
-
static get _superclass() {
|
|
3550
|
-
return 'UniqueKeyGenerator'
|
|
3551
|
-
}
|
|
3552
|
-
static makeFormatter({ fieldName, format, options }) {
|
|
3553
|
-
switch (format) {
|
|
3554
|
-
case 'set_code':
|
|
3555
|
-
return _makeSetCode(fieldName, options)
|
|
3556
|
-
default:
|
|
3557
|
-
return _makeSetCode(fieldName, options)
|
|
3558
|
-
}
|
|
3559
|
-
}
|
|
3560
|
-
static makeGenerator(arr) {
|
|
3561
|
-
const fns = arr.map((item) => this.makeFormatter(item))
|
|
3562
|
-
return async (obj) => {
|
|
3563
|
-
const output = await pReduce(fns, async (acc, fn) => {
|
|
3564
|
-
const _obj = await fn(obj)
|
|
3565
|
-
return Object.assign(acc, _obj)
|
|
3566
|
-
}, obj)
|
|
3567
|
-
return output
|
|
3568
|
-
}
|
|
3569
|
-
}
|
|
3570
|
-
}
|
|
3571
|
-
|
|
3572
|
-
function _makeSetCode(fieldName, options) {
|
|
3573
|
-
return async (obj = {}) => {
|
|
3574
|
-
if (obj[fieldName]) {
|
|
3575
|
-
return {}
|
|
3576
|
-
}
|
|
3577
|
-
return {
|
|
3578
|
-
[fieldName]: stringHelper.setCode()
|
|
3579
|
-
}
|
|
3580
|
-
}
|
|
3581
|
-
}
|
|
3582
|
-
|
|
3583
|
-
|
|
3584
|
-
|
|
3585
|
-
;// ./lib/models/uniqueKeyGenerator/index.js
|
|
3586
|
-
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
;// ./lib/models/index.js
|
|
3591
|
-
|
|
3592
|
-
|
|
3593
|
-
|
|
3594
|
-
|
|
3595
|
-
|
|
3596
|
-
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
|
|
3600
|
-
|
|
3601
|
-
|
|
3602
|
-
|
|
3603
|
-
;// ./lib/index.js
|
|
3604
|
-
|
|
3605
|
-
|
|
3606
|
-
|
|
3607
|
-
;// ./index.js
|
|
3608
|
-
|
|
3609
|
-
|
|
3610
|
-
/******/ return __webpack_exports__;
|
|
3611
|
-
/******/ })()
|
|
3612
|
-
;
|
|
3613
|
-
});
|