@questwork/q-utilities 0.1.19 → 0.1.20
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 +6 -6
- package/dist/index.min.cjs +513 -211
- package/dist/q-utilities.esm.js +510 -212
- package/dist/q-utilities.min.js +513 -211
- package/eslint.config.js +3 -0
- package/package.json +3 -2
package/dist/q-utilities.min.js
CHANGED
|
@@ -48,6 +48,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
48
48
|
|
|
49
49
|
// EXPORTS
|
|
50
50
|
__webpack_require__.d(__webpack_exports__, {
|
|
51
|
+
ActionRecord: () => (/* reexport */ ActionRecord),
|
|
51
52
|
ApiResponse: () => (/* reexport */ ApiResponse),
|
|
52
53
|
AwsStsS3Client: () => (/* reexport */ AwsStsS3Client),
|
|
53
54
|
KeyValueObject: () => (/* reexport */ KeyValueObject),
|
|
@@ -56,6 +57,8 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
56
57
|
QMeta: () => (/* reexport */ QMeta),
|
|
57
58
|
Repo: () => (/* reexport */ Repo),
|
|
58
59
|
Service: () => (/* reexport */ Service),
|
|
60
|
+
Status: () => (/* reexport */ Status),
|
|
61
|
+
StatusDocument: () => (/* reexport */ StatusDocument),
|
|
59
62
|
TemplateCompiler: () => (/* reexport */ TemplateCompiler),
|
|
60
63
|
TenantAwareEntity: () => (/* reexport */ TenantAwareEntity),
|
|
61
64
|
TrackedEntity: () => (/* reexport */ TrackedEntity),
|
|
@@ -76,6 +79,7 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
76
79
|
init: () => (/* reexport */ init),
|
|
77
80
|
initFromArray: () => (/* reexport */ initFromArray),
|
|
78
81
|
initOnlyValidFromArray: () => (/* reexport */ initOnlyValidFromArray),
|
|
82
|
+
isConvertibleToNumber: () => (/* reexport */ isConvertibleToNumber),
|
|
79
83
|
makeApiResponse: () => (/* reexport */ makeApiResponse),
|
|
80
84
|
makeService: () => (/* reexport */ makeService),
|
|
81
85
|
mergeArraysByKey: () => (/* reexport */ mergeArraysByKey),
|
|
@@ -116,14 +120,14 @@ function authorize({ allowCoordinator, allowOwner, query = {}, required, user })
|
|
|
116
120
|
if (query.registrationGroupCode && user.myManagedRegistrationGroupCodes.includes(query.registrationGroupCode)) {
|
|
117
121
|
query.__ALLOW_COORDINATOR = true
|
|
118
122
|
} else {
|
|
119
|
-
if (!scopes.includes('EVENT')) {
|
|
120
|
-
query.eventRegistrationCode = user.eventRegistrationCode
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
} else {
|
|
124
123
|
if (!scopes.includes('EVENT')) {
|
|
125
124
|
query.eventRegistrationCode = user.eventRegistrationCode
|
|
126
125
|
}
|
|
126
|
+
}
|
|
127
|
+
} else {
|
|
128
|
+
if (!scopes.includes('EVENT')) {
|
|
129
|
+
query.eventRegistrationCode = user.eventRegistrationCode
|
|
130
|
+
}
|
|
127
131
|
}
|
|
128
132
|
if (allowOwner) {
|
|
129
133
|
query.__ALLOW_OWNER = true
|
|
@@ -155,14 +159,14 @@ function calculateAge(timestamp, reference) {
|
|
|
155
159
|
}
|
|
156
160
|
|
|
157
161
|
// Calculate raw difference
|
|
158
|
-
let age = refDate.getFullYear() - birthDate.getFullYear()
|
|
159
|
-
const monthDiff = refDate.getMonth() - birthDate.getMonth()
|
|
160
|
-
|
|
162
|
+
let age = refDate.getFullYear() - birthDate.getFullYear()
|
|
163
|
+
const monthDiff = refDate.getMonth() - birthDate.getMonth()
|
|
164
|
+
|
|
161
165
|
// Adjust if birthday hasn't occurred yet this year
|
|
162
166
|
if (monthDiff < 0 || (monthDiff === 0 && refDate.getDate() < birthDate.getDate())) {
|
|
163
167
|
age--
|
|
164
168
|
}
|
|
165
|
-
|
|
169
|
+
|
|
166
170
|
return age
|
|
167
171
|
}
|
|
168
172
|
|
|
@@ -192,7 +196,18 @@ function changeCreatorOwner(that, { source, target }) {
|
|
|
192
196
|
;// ./lib/helpers/changeCreatorOwner/index.js
|
|
193
197
|
|
|
194
198
|
|
|
199
|
+
;// ./lib/helpers/isConvertibleToNumber/isConvertibleToNumber.js
|
|
200
|
+
function isConvertibleToNumber(value) {
|
|
201
|
+
return value !== null
|
|
202
|
+
&& value !== undefined
|
|
203
|
+
&& typeof value !== 'boolean'
|
|
204
|
+
&& String(value).trim() !== ''
|
|
205
|
+
&& !isNaN(Number(value))
|
|
206
|
+
}
|
|
207
|
+
|
|
195
208
|
;// ./lib/helpers/getValidation/getValidation.js
|
|
209
|
+
|
|
210
|
+
|
|
196
211
|
function getValidation(rule, data, getDataByKey, KeyValueObject) {
|
|
197
212
|
if (!rule) {
|
|
198
213
|
return true
|
|
@@ -206,10 +221,10 @@ function getValidation(rule, data, getDataByKey, KeyValueObject) {
|
|
|
206
221
|
if (!key && typeof placeholder === 'undefined') {
|
|
207
222
|
switch (valueAttribute) {
|
|
208
223
|
case '$and': {
|
|
209
|
-
return value
|
|
224
|
+
return value.$and.reduce((acc, item) => (acc && getValidation(item, data, getDataByKey, KeyValueObject)), true)
|
|
210
225
|
}
|
|
211
226
|
case '$or': {
|
|
212
|
-
return value
|
|
227
|
+
return value.$or.reduce((acc, item) => (acc || getValidation(item, data, getDataByKey, KeyValueObject)), false)
|
|
213
228
|
}
|
|
214
229
|
default:
|
|
215
230
|
return false
|
|
@@ -224,39 +239,53 @@ function getValidation(rule, data, getDataByKey, KeyValueObject) {
|
|
|
224
239
|
}
|
|
225
240
|
|
|
226
241
|
switch (valueAttribute) {
|
|
242
|
+
case '$after': {
|
|
243
|
+
if (isConvertibleToNumber(value?.$after)) {
|
|
244
|
+
const _value = Number(String(value?.$after))
|
|
245
|
+
return Date.now() > _value
|
|
246
|
+
}
|
|
247
|
+
return false
|
|
248
|
+
}
|
|
249
|
+
case '$before': {
|
|
250
|
+
if (isConvertibleToNumber(value?.$before)) {
|
|
251
|
+
const _value = Number(String(value?.$before))
|
|
252
|
+
return Date.now() < _value
|
|
253
|
+
}
|
|
254
|
+
return false
|
|
255
|
+
}
|
|
227
256
|
case '$empty': {
|
|
228
257
|
const isEmpty = rowValue === null || rowValue === undefined
|
|
229
|
-
return isEmpty === value
|
|
258
|
+
return isEmpty === value.$empty
|
|
230
259
|
}
|
|
231
260
|
case '$eq': {
|
|
232
|
-
return rowValue === value
|
|
261
|
+
return rowValue === value.$eq
|
|
233
262
|
}
|
|
234
263
|
case '$gt': {
|
|
235
|
-
return rowValue > value
|
|
264
|
+
return rowValue > value.$gt
|
|
236
265
|
}
|
|
237
266
|
case '$gte': {
|
|
238
|
-
return rowValue >= value
|
|
267
|
+
return rowValue >= value.$gte
|
|
239
268
|
}
|
|
240
269
|
case '$hasOverlap': {
|
|
241
|
-
return _hasOverlap(rowValue, value
|
|
270
|
+
return _hasOverlap(rowValue, value.$hasOverlap)
|
|
242
271
|
}
|
|
243
272
|
case '$lt': {
|
|
244
|
-
return rowValue < value
|
|
273
|
+
return rowValue < value.$lt
|
|
245
274
|
}
|
|
246
275
|
case '$lte': {
|
|
247
|
-
return rowValue <= value
|
|
276
|
+
return rowValue <= value.$lte
|
|
248
277
|
}
|
|
249
278
|
case '$in': {
|
|
250
279
|
if (Array.isArray(rowValue)) {
|
|
251
|
-
return !!rowValue.find((e) => (value
|
|
280
|
+
return !!rowValue.find((e) => (value.$in.includes(e)))
|
|
252
281
|
}
|
|
253
282
|
if (typeof rowValue !== 'object') {
|
|
254
|
-
return !!value
|
|
283
|
+
return !!value.$in.includes(rowValue)
|
|
255
284
|
}
|
|
256
285
|
return false
|
|
257
286
|
}
|
|
258
287
|
case '$inValue': {
|
|
259
|
-
const result = getDataByKey(value
|
|
288
|
+
const result = getDataByKey(value.$inValue, data)
|
|
260
289
|
const _value = Array.isArray(result) ? result : []
|
|
261
290
|
if (Array.isArray(rowValue)) {
|
|
262
291
|
return !!rowValue.find((e) => (_value.includes(e)))
|
|
@@ -267,36 +296,36 @@ function getValidation(rule, data, getDataByKey, KeyValueObject) {
|
|
|
267
296
|
return false
|
|
268
297
|
}
|
|
269
298
|
case '$ne': {
|
|
270
|
-
return rowValue !== value
|
|
299
|
+
return rowValue !== value.$ne
|
|
271
300
|
}
|
|
272
301
|
case '$notIn': {
|
|
273
302
|
if (Array.isArray(rowValue)) {
|
|
274
|
-
return !rowValue.find((e) => (value
|
|
303
|
+
return !rowValue.find((e) => (value.$notIn.includes(e)))
|
|
275
304
|
}
|
|
276
305
|
if (typeof rowValue !== 'object') {
|
|
277
|
-
return !value
|
|
306
|
+
return !value.$notIn.includes(rowValue)
|
|
278
307
|
}
|
|
279
308
|
return false
|
|
280
309
|
}
|
|
281
310
|
case '$intervalTimeGt': {
|
|
282
311
|
const now = new Date().getTime()
|
|
283
312
|
const timestamp = new Date(rowValue).getTime()
|
|
284
|
-
return (now - timestamp) > value
|
|
313
|
+
return (now - timestamp) > value.$intervalTimeGt
|
|
285
314
|
}
|
|
286
315
|
case '$intervalTimeLt': {
|
|
287
316
|
const now = new Date().getTime()
|
|
288
317
|
const timestamp = new Date(rowValue).getTime()
|
|
289
|
-
return (now - timestamp) < value
|
|
318
|
+
return (now - timestamp) < value.$intervalTimeLt
|
|
290
319
|
}
|
|
291
320
|
case '$isToday': {
|
|
292
321
|
const currentDate = new Date()
|
|
293
|
-
const start = currentDate.setHours(0,0,0,0)
|
|
294
|
-
const end = currentDate.setHours(23,59,59,59)
|
|
322
|
+
const start = currentDate.setHours(0, 0, 0, 0)
|
|
323
|
+
const end = currentDate.setHours(23, 59, 59, 59)
|
|
295
324
|
const dateValue = new Date(rowValue).getTime()
|
|
296
|
-
return (start <= dateValue && end >= dateValue) === value
|
|
325
|
+
return (start <= dateValue && end >= dateValue) === value.$isToday
|
|
297
326
|
}
|
|
298
327
|
case '$notInValue': {
|
|
299
|
-
const result = getDataByKey(value
|
|
328
|
+
const result = getDataByKey(value.$notInValue, data)
|
|
300
329
|
const _value = Array.isArray(result) ? result : []
|
|
301
330
|
if (Array.isArray(rowValue)) {
|
|
302
331
|
return !rowValue.find((e) => (_value.includes(e)))
|
|
@@ -307,7 +336,7 @@ function getValidation(rule, data, getDataByKey, KeyValueObject) {
|
|
|
307
336
|
return false
|
|
308
337
|
}
|
|
309
338
|
case '$range': {
|
|
310
|
-
const [min, max] = value
|
|
339
|
+
const [min, max] = value.$range
|
|
311
340
|
if (typeof min === 'number' && typeof max === 'number' && rowValue >= min && rowValue <= max) {
|
|
312
341
|
return true
|
|
313
342
|
}
|
|
@@ -316,7 +345,6 @@ function getValidation(rule, data, getDataByKey, KeyValueObject) {
|
|
|
316
345
|
default:
|
|
317
346
|
return false
|
|
318
347
|
}
|
|
319
|
-
|
|
320
348
|
}
|
|
321
349
|
|
|
322
350
|
function _hasOverlap(item1, item2) {
|
|
@@ -341,12 +369,11 @@ function _hasOverlap(item1, item2) {
|
|
|
341
369
|
|
|
342
370
|
|
|
343
371
|
;// ./lib/helpers/formatDate/formatDate.js
|
|
344
|
-
|
|
345
372
|
function formatDate(date, format) {
|
|
346
373
|
const _date = date && date instanceof Date ? date : new Date(date)
|
|
347
|
-
const dayMapChi = ['日','一','二','三','四','五','六']
|
|
348
|
-
const dayMapEng = ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday']
|
|
349
|
-
const dayMapEngShort = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat']
|
|
374
|
+
const dayMapChi = ['日', '一', '二', '三', '四', '五', '六']
|
|
375
|
+
const dayMapEng = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']
|
|
376
|
+
const dayMapEngShort = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
|
|
350
377
|
const _format = format || 'YYYY/MM/DD hh:mm'
|
|
351
378
|
const e = _date.getDay()
|
|
352
379
|
const ee = dayMapEngShort[e]
|
|
@@ -381,13 +408,11 @@ function padding(m) {
|
|
|
381
408
|
return m < 10 ? `0${m}` : m
|
|
382
409
|
}
|
|
383
410
|
|
|
384
|
-
|
|
385
411
|
/* harmony default export */ const formatDate_formatDate = ({
|
|
386
412
|
formatDate
|
|
387
413
|
});
|
|
388
414
|
|
|
389
415
|
|
|
390
|
-
|
|
391
416
|
;// ./lib/helpers/formatDate/index.js
|
|
392
417
|
|
|
393
418
|
|
|
@@ -418,7 +443,6 @@ function getValueByKeys_getValueByKeys(keys, data) {
|
|
|
418
443
|
return _data[firstKey]
|
|
419
444
|
}
|
|
420
445
|
return _data
|
|
421
|
-
|
|
422
446
|
}
|
|
423
447
|
/* harmony default export */ const getValueByKeys = ({
|
|
424
448
|
getValueByKeys: getValueByKeys_getValueByKeys
|
|
@@ -470,6 +494,7 @@ const _FN_NAMES = [
|
|
|
470
494
|
'map',
|
|
471
495
|
'neq',
|
|
472
496
|
'removeHtml',
|
|
497
|
+
'sum',
|
|
473
498
|
'toLowerCase',
|
|
474
499
|
'toUpperCase',
|
|
475
500
|
]
|
|
@@ -622,10 +647,12 @@ function _existObject(data, args) {
|
|
|
622
647
|
|
|
623
648
|
function _performOperation(arg, value) {
|
|
624
649
|
// the arg is undefined
|
|
625
|
-
if (arg === undefined && value === undefined)
|
|
650
|
+
if (arg === undefined && value === undefined)
|
|
651
|
+
return true
|
|
626
652
|
|
|
627
653
|
// the arg is null
|
|
628
|
-
if (arg === null && value === null)
|
|
654
|
+
if (arg === null && value === null)
|
|
655
|
+
return true
|
|
629
656
|
|
|
630
657
|
// the arg is boolean
|
|
631
658
|
if (typeof arg === 'boolean') {
|
|
@@ -701,17 +728,18 @@ function _splitOperator(str) {
|
|
|
701
728
|
const operators = ['!=', '>=', '<=', '>', '<']
|
|
702
729
|
|
|
703
730
|
const matchedOp = operators.find((op) => str.startsWith(op))
|
|
704
|
-
if (!matchedOp)
|
|
731
|
+
if (!matchedOp)
|
|
732
|
+
return { operator: null, value: null }
|
|
705
733
|
|
|
706
734
|
const remaining = str.slice(matchedOp.length)
|
|
707
735
|
|
|
708
736
|
// '>Primary' or '<Primary' is invalid
|
|
709
|
-
if (/^[a-
|
|
737
|
+
if (/^[a-z]*$/i.test(remaining) && matchedOp !== '!=') {
|
|
710
738
|
return { operator: null, value: null }
|
|
711
739
|
}
|
|
712
740
|
|
|
713
741
|
// if it is a number it is converted to a number
|
|
714
|
-
const value = (!Number.isNaN(parseFloat(remaining)) && !Number.isNaN(remaining)) ? Number(remaining) : remaining
|
|
742
|
+
const value = (!Number.isNaN(Number.parseFloat(remaining)) && !Number.isNaN(remaining)) ? Number(remaining) : remaining
|
|
715
743
|
|
|
716
744
|
return {
|
|
717
745
|
operator: matchedOp,
|
|
@@ -923,11 +951,14 @@ function _isNotEmpty(data, args) {
|
|
|
923
951
|
}
|
|
924
952
|
|
|
925
953
|
|
|
954
|
+
|
|
926
955
|
;// ./lib/models/templateCompiler/helpers/_join.js
|
|
927
956
|
function _join(data, delimiter) {
|
|
928
957
|
try {
|
|
929
|
-
if (data.length === 0)
|
|
930
|
-
|
|
958
|
+
if (data.length === 0)
|
|
959
|
+
return ''
|
|
960
|
+
if (data.length === 1)
|
|
961
|
+
return _stringifyObject(data[0])
|
|
931
962
|
return data.map((item) => _stringifyObject(item)).join(delimiter)
|
|
932
963
|
} catch (e) {
|
|
933
964
|
throw e
|
|
@@ -1074,13 +1105,13 @@ function _removeHtml(html, args) {
|
|
|
1074
1105
|
|
|
1075
1106
|
function _htmlToPlainText(html, delimiter = '\n') {
|
|
1076
1107
|
if (typeof delimiter !== 'string') {
|
|
1077
|
-
delimiter = '\n'
|
|
1108
|
+
delimiter = '\n' // Fallback to default if not a string
|
|
1078
1109
|
}
|
|
1079
1110
|
|
|
1080
1111
|
// First decode HTML entities and normalize whitespace
|
|
1081
1112
|
const decodedHtml = html
|
|
1082
1113
|
.replace(/ /g, ' ')
|
|
1083
|
-
.replace(/\s+/g, ' ')
|
|
1114
|
+
.replace(/\s+/g, ' ') // Collapse all whitespace to single spaces
|
|
1084
1115
|
|
|
1085
1116
|
// Process HTML tags
|
|
1086
1117
|
let text = decodedHtml
|
|
@@ -1091,29 +1122,36 @@ function _htmlToPlainText(html, delimiter = '\n') {
|
|
|
1091
1122
|
// Remove all other tags
|
|
1092
1123
|
.replace(/<[^>]+>/g, '')
|
|
1093
1124
|
// Convert markers to specified delimiter
|
|
1094
|
-
.replace(
|
|
1125
|
+
.replace(/~{3,}/g, delimiter)
|
|
1095
1126
|
// Trim and clean whitespace
|
|
1096
|
-
.trim()
|
|
1127
|
+
.trim()
|
|
1097
1128
|
|
|
1098
1129
|
// Special handling for empty delimiter
|
|
1099
1130
|
if (delimiter === '') {
|
|
1100
1131
|
// Collapse all whitespace to single space
|
|
1101
|
-
text = text.replace(/\s+/g, ' ')
|
|
1132
|
+
text = text.replace(/\s+/g, ' ')
|
|
1102
1133
|
} else {
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
1134
|
// Collapse multiple delimiters to single
|
|
1106
|
-
text = text.replace(new RegExp(`${escapeRegExp(delimiter)}+`, 'g'), delimiter)
|
|
1135
|
+
text = text.replace(new RegExp(`${escapeRegExp(delimiter)}+`, 'g'), delimiter)
|
|
1107
1136
|
// Remove leading/trailing delimiters
|
|
1108
|
-
text = text.replace(new RegExp(`^${escapeRegExp(delimiter)}|${escapeRegExp(delimiter)}$`, 'g'), '')
|
|
1137
|
+
text = text.replace(new RegExp(`^${escapeRegExp(delimiter)}|${escapeRegExp(delimiter)}$`, 'g'), '')
|
|
1109
1138
|
}
|
|
1110
1139
|
|
|
1111
|
-
return text
|
|
1140
|
+
return text
|
|
1112
1141
|
}
|
|
1113
1142
|
|
|
1114
|
-
|
|
1115
1143
|
function escapeRegExp(string) {
|
|
1116
|
-
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
|
|
1144
|
+
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
|
|
1145
|
+
}
|
|
1146
|
+
|
|
1147
|
+
|
|
1148
|
+
|
|
1149
|
+
;// ./lib/models/templateCompiler/helpers/_sum.js
|
|
1150
|
+
function _sum(data, args) {
|
|
1151
|
+
if (Number.isNaN(data) || data === null || (typeof data === 'undefined') || data === '') {
|
|
1152
|
+
return data
|
|
1153
|
+
}
|
|
1154
|
+
return args.reduce((acc, e) => (acc + e), data)
|
|
1117
1155
|
}
|
|
1118
1156
|
|
|
1119
1157
|
|
|
@@ -1173,6 +1211,7 @@ function _toUpperCase(data, args) {
|
|
|
1173
1211
|
|
|
1174
1212
|
|
|
1175
1213
|
|
|
1214
|
+
|
|
1176
1215
|
|
|
1177
1216
|
|
|
1178
1217
|
;// ./lib/models/templateCompiler/templateCompiler.js
|
|
@@ -1246,6 +1285,9 @@ class TemplateCompiler {
|
|
|
1246
1285
|
static removeHtml(data, args) {
|
|
1247
1286
|
return _removeHtml(data, args)
|
|
1248
1287
|
}
|
|
1288
|
+
static sum(data, args) {
|
|
1289
|
+
return _sum(data, args)
|
|
1290
|
+
}
|
|
1249
1291
|
static toLowerCase(data, args) {
|
|
1250
1292
|
return _toLowerCase(data, args)
|
|
1251
1293
|
}
|
|
@@ -1306,7 +1348,7 @@ function _parseFunction(expression, existFunctionNames) {
|
|
|
1306
1348
|
|
|
1307
1349
|
function _parseParams(parameters) {
|
|
1308
1350
|
const _parameters = parameters.trim()
|
|
1309
|
-
const regExp = new RegExp(/^[^\w\
|
|
1351
|
+
const regExp = new RegExp(/^[^\w\s]+$/)
|
|
1310
1352
|
const match = _parameters.match(regExp)
|
|
1311
1353
|
if (match !== null) {
|
|
1312
1354
|
return [_parameters.substring(1, _parameters.length - 1)]
|
|
@@ -1321,13 +1363,13 @@ function _parseParams(parameters) {
|
|
|
1321
1363
|
|
|
1322
1364
|
function _splitIgnoringBrackets(input) {
|
|
1323
1365
|
const regExp2 = new RegExp(/^\d+(\.\d+)?$/)
|
|
1324
|
-
const regExp = new RegExp(/(?![
|
|
1366
|
+
const regExp = new RegExp(/(?![^[]*\])\s*,\s*/)
|
|
1325
1367
|
const parts = input.split(regExp)
|
|
1326
1368
|
return parts.map((part) => {
|
|
1327
1369
|
const _part = part.trim()
|
|
1328
1370
|
if (_part !== '' && !!_part.match(regExp2)) {
|
|
1329
1371
|
// 如果是数字,转换为 num 类型
|
|
1330
|
-
return Number.isNaN(_part) ? _part : parseInt(_part, 10)
|
|
1372
|
+
return Number.isNaN(_part) ? _part : Number.parseInt(_part, 10)
|
|
1331
1373
|
}
|
|
1332
1374
|
// 否则当作字符串处理
|
|
1333
1375
|
return _part
|
|
@@ -1340,7 +1382,7 @@ function _parseSinglePart(input) {
|
|
|
1340
1382
|
// 去掉双引号,返回
|
|
1341
1383
|
return input.substring(1, input.length - 1)
|
|
1342
1384
|
}
|
|
1343
|
-
if (input.startsWith(
|
|
1385
|
+
if (input.startsWith('\'') && input.endsWith('\'')) {
|
|
1344
1386
|
// 去掉双引号,返回
|
|
1345
1387
|
return input.substring(1, input.length - 1)
|
|
1346
1388
|
}
|
|
@@ -1371,7 +1413,7 @@ function _toBasicType(input) {
|
|
|
1371
1413
|
// 去掉双引号,返回
|
|
1372
1414
|
return input.substring(1, input.length - 1)
|
|
1373
1415
|
}
|
|
1374
|
-
if (input.startsWith(
|
|
1416
|
+
if (input.startsWith('\'') && input.endsWith('\'')) {
|
|
1375
1417
|
// 去掉双引号,返回
|
|
1376
1418
|
return input.substring(1, input.length - 1)
|
|
1377
1419
|
}
|
|
@@ -1439,6 +1481,8 @@ function _callFunction(data, functionName, parameters) {
|
|
|
1439
1481
|
return _neq(data, parameters)
|
|
1440
1482
|
case 'removeHtml':
|
|
1441
1483
|
return _removeHtml(data, parameters)
|
|
1484
|
+
case 'sum':
|
|
1485
|
+
return _sum(data, parameters)
|
|
1442
1486
|
case 'toLowerCase':
|
|
1443
1487
|
return _toLowerCase(data)
|
|
1444
1488
|
case 'toUpperCase':
|
|
@@ -1468,14 +1512,14 @@ function concatStringByArray(arrTemplate, data) {
|
|
|
1468
1512
|
return arrTemplate.reduce((acc, item) => {
|
|
1469
1513
|
const { type, value = '', restriction, template, format, showMinutes } = item
|
|
1470
1514
|
switch (type) {
|
|
1471
|
-
case('array'): {
|
|
1515
|
+
case ('array'): {
|
|
1472
1516
|
if (getValidation(restriction, data, getValueByKeys_getValueByKeys)) {
|
|
1473
1517
|
const _value = getValueByKeys_getValueByKeys(value.split('.'), data) || []
|
|
1474
1518
|
acc += _value.reduce((_acc, item) => {
|
|
1475
1519
|
return _acc += concatStringByArray(template, item)
|
|
1476
1520
|
}, '')
|
|
1477
1521
|
}
|
|
1478
|
-
break
|
|
1522
|
+
break
|
|
1479
1523
|
}
|
|
1480
1524
|
case ('date'): {
|
|
1481
1525
|
if (getValidation(restriction, data, getValueByKeys_getValueByKeys)) {
|
|
@@ -1484,7 +1528,7 @@ function concatStringByArray(arrTemplate, data) {
|
|
|
1484
1528
|
}
|
|
1485
1529
|
break
|
|
1486
1530
|
}
|
|
1487
|
-
case('ellipsis'): {
|
|
1531
|
+
case ('ellipsis'): {
|
|
1488
1532
|
if (getValidation(restriction, data, getValueByKeys_getValueByKeys)) {
|
|
1489
1533
|
const { maxLength } = item
|
|
1490
1534
|
const _value = getValueByKeys_getValueByKeys(value.split('.'), data) || ''
|
|
@@ -1494,15 +1538,15 @@ function concatStringByArray(arrTemplate, data) {
|
|
|
1494
1538
|
acc += `${_value.substr(0, maxLength)}...`
|
|
1495
1539
|
}
|
|
1496
1540
|
}
|
|
1497
|
-
break
|
|
1541
|
+
break
|
|
1498
1542
|
}
|
|
1499
|
-
case('group'): {
|
|
1543
|
+
case ('group'): {
|
|
1500
1544
|
if (getValidation(restriction, data, getValueByKeys_getValueByKeys)) {
|
|
1501
1545
|
return concatStringByArray(value, data)
|
|
1502
1546
|
}
|
|
1503
1547
|
break
|
|
1504
1548
|
}
|
|
1505
|
-
case('label'): {
|
|
1549
|
+
case ('label'): {
|
|
1506
1550
|
if (getValidation(restriction, data, getValueByKeys_getValueByKeys)) {
|
|
1507
1551
|
acc += (value.toString())
|
|
1508
1552
|
}
|
|
@@ -1515,12 +1559,12 @@ function concatStringByArray(arrTemplate, data) {
|
|
|
1515
1559
|
}
|
|
1516
1560
|
break
|
|
1517
1561
|
}
|
|
1518
|
-
case('value'): {
|
|
1562
|
+
case ('value'): {
|
|
1519
1563
|
if (getValidation(restriction, data, getValueByKeys_getValueByKeys)) {
|
|
1520
1564
|
const _value = getValueByKeys_getValueByKeys(value.split('.'), data) || ''
|
|
1521
1565
|
acc += (_value.toString())
|
|
1522
1566
|
}
|
|
1523
|
-
break
|
|
1567
|
+
break
|
|
1524
1568
|
}
|
|
1525
1569
|
}
|
|
1526
1570
|
return acc
|
|
@@ -1531,7 +1575,6 @@ function concatStringByArray(arrTemplate, data) {
|
|
|
1531
1575
|
});
|
|
1532
1576
|
|
|
1533
1577
|
|
|
1534
|
-
|
|
1535
1578
|
;// ./lib/helpers/concatStringByArray/index.js
|
|
1536
1579
|
|
|
1537
1580
|
|
|
@@ -1542,7 +1585,7 @@ function convertString(string, patternMatch = /\$\{(.+?)\}/g, value, getValueByK
|
|
|
1542
1585
|
if (!string) {
|
|
1543
1586
|
return ''
|
|
1544
1587
|
}
|
|
1545
|
-
|
|
1588
|
+
const _getValueByKeys = typeof getValueByKeys === 'function' ? getValueByKeys : getValueByKeys_getValueByKeys
|
|
1546
1589
|
const reg = new RegExp(patternMatch, 'g')
|
|
1547
1590
|
return string.replace(reg, (match, key) => {
|
|
1548
1591
|
const result = _getValueByKeys({ keys: key.split('.'), obj: value })
|
|
@@ -1563,7 +1606,7 @@ function convertString(string, patternMatch = /\$\{(.+?)\}/g, value, getValueByK
|
|
|
1563
1606
|
|
|
1564
1607
|
;// ./lib/helpers/escapeRegex/escapeRegex.js
|
|
1565
1608
|
function escapeRegex(string) {
|
|
1566
|
-
return String(string).replace(/[
|
|
1609
|
+
return String(string).replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&')
|
|
1567
1610
|
}
|
|
1568
1611
|
|
|
1569
1612
|
;// ./lib/helpers/escapeRegex/index.js
|
|
@@ -1666,7 +1709,6 @@ function updateOneResult({ responseHelper, service }) {
|
|
|
1666
1709
|
|
|
1667
1710
|
|
|
1668
1711
|
|
|
1669
|
-
|
|
1670
1712
|
const expressHelper = {
|
|
1671
1713
|
customHandler: customHandler,
|
|
1672
1714
|
findAllResult: findAllResult,
|
|
@@ -1682,27 +1724,29 @@ const expressHelper = {
|
|
|
1682
1724
|
* @returns {Array} Sorted array of unique, lowercase email addresses
|
|
1683
1725
|
*/
|
|
1684
1726
|
function extractEmails(dirtyArray) {
|
|
1685
|
-
const emailRegex = /[
|
|
1727
|
+
const emailRegex = /[\w.%+-]+@[a-z0-9.-]+\.[a-z]{2,}/gi
|
|
1686
1728
|
const emails = new Set()
|
|
1687
1729
|
|
|
1688
1730
|
// Handle null/undefined input array
|
|
1689
|
-
if (!dirtyArray)
|
|
1731
|
+
if (!dirtyArray)
|
|
1732
|
+
return []
|
|
1690
1733
|
|
|
1691
|
-
dirtyArray.forEach(entry => {
|
|
1734
|
+
dirtyArray.forEach((entry) => {
|
|
1692
1735
|
// Skip null, undefined, empty, or whitespace-only entries
|
|
1693
|
-
if (!entry || typeof entry !== 'string' || !entry.trim())
|
|
1736
|
+
if (!entry || typeof entry !== 'string' || !entry.trim())
|
|
1737
|
+
return
|
|
1694
1738
|
|
|
1695
1739
|
try {
|
|
1696
1740
|
const cleanEntry = entry
|
|
1697
1741
|
.replace(/[\u200B-\u200D\uFEFF\u202A-\u202E]/g, '') // Remove hidden chars
|
|
1698
|
-
.replace(/[<>]/g, ' ')
|
|
1699
|
-
.replace(/\s+/g, ' ')
|
|
1742
|
+
.replace(/[<>]/g, ' ') // Convert email delimiters to spaces
|
|
1743
|
+
.replace(/\s+/g, ' ') // Collapse multiple whitespace
|
|
1700
1744
|
.trim()
|
|
1701
1745
|
|
|
1702
1746
|
// Extract all email matches
|
|
1703
1747
|
const matches = cleanEntry.match(emailRegex)
|
|
1704
1748
|
if (matches) {
|
|
1705
|
-
matches.forEach(email => emails.add(email.toLowerCase())) // Normalize to lowercase
|
|
1749
|
+
matches.forEach((email) => emails.add(email.toLowerCase())) // Normalize to lowercase
|
|
1706
1750
|
}
|
|
1707
1751
|
} catch (e) {
|
|
1708
1752
|
console.warn('Failed to process entry:', entry, e)
|
|
@@ -1748,64 +1792,65 @@ const objectHelper = {
|
|
|
1748
1792
|
},
|
|
1749
1793
|
merge,
|
|
1750
1794
|
set(obj, path, value) {
|
|
1751
|
-
const parts = path.split('.')
|
|
1752
|
-
let current = obj
|
|
1795
|
+
const parts = path.split('.')
|
|
1796
|
+
let current = obj
|
|
1753
1797
|
|
|
1754
1798
|
// 处理所有中间部分
|
|
1755
1799
|
for (let i = 0; i < parts.length - 1; i++) {
|
|
1756
|
-
const part = parts[i]
|
|
1757
|
-
let key, index
|
|
1800
|
+
const part = parts[i]
|
|
1801
|
+
let key, index
|
|
1758
1802
|
|
|
1759
1803
|
// 检查是否是数组索引格式,如key[0]
|
|
1760
|
-
const arrayMatch = part.match(/^(\w+)\[(\d+)\]$/)
|
|
1804
|
+
const arrayMatch = part.match(/^(\w+)\[(\d+)\]$/)
|
|
1761
1805
|
if (arrayMatch) {
|
|
1762
|
-
key = arrayMatch[1]
|
|
1763
|
-
index = parseInt(arrayMatch[2], 10)
|
|
1806
|
+
key = arrayMatch[1]
|
|
1807
|
+
index = Number.parseInt(arrayMatch[2], 10)
|
|
1764
1808
|
// 确保当前层级的数组存在
|
|
1765
1809
|
if (!current[key] || !Array.isArray(current[key])) {
|
|
1766
|
-
current[key] = []
|
|
1810
|
+
current[key] = []
|
|
1767
1811
|
}
|
|
1768
1812
|
// 扩展数组到足够大
|
|
1769
1813
|
while (current[key].length <= index) {
|
|
1770
|
-
current[key].push(undefined)
|
|
1814
|
+
current[key].push(undefined)
|
|
1771
1815
|
}
|
|
1772
1816
|
// 如果当前位置未定义或为null,初始化为对象
|
|
1773
1817
|
if (current[key][index] == null) {
|
|
1774
|
-
current[key][index] = {}
|
|
1818
|
+
current[key][index] = {}
|
|
1775
1819
|
}
|
|
1776
|
-
current = current[key][index]
|
|
1820
|
+
current = current[key][index]
|
|
1777
1821
|
} else {
|
|
1778
1822
|
// 处理普通属性
|
|
1779
1823
|
if (!current[part]) {
|
|
1780
|
-
current[part] = {}
|
|
1824
|
+
current[part] = {}
|
|
1781
1825
|
}
|
|
1782
|
-
current = current[part]
|
|
1826
|
+
current = current[part]
|
|
1783
1827
|
}
|
|
1784
1828
|
}
|
|
1785
1829
|
|
|
1786
1830
|
// 处理最后一部分
|
|
1787
|
-
const lastPart = parts[parts.length - 1]
|
|
1788
|
-
const arrayMatch = lastPart.match(/^(\w+)\[(\d+)\]$/)
|
|
1831
|
+
const lastPart = parts[parts.length - 1]
|
|
1832
|
+
const arrayMatch = lastPart.match(/^(\w+)\[(\d+)\]$/)
|
|
1789
1833
|
if (arrayMatch) {
|
|
1790
|
-
const key = arrayMatch[1]
|
|
1791
|
-
const index = parseInt(arrayMatch[2], 10)
|
|
1834
|
+
const key = arrayMatch[1]
|
|
1835
|
+
const index = Number.parseInt(arrayMatch[2], 10)
|
|
1792
1836
|
// 确保数组存在
|
|
1793
1837
|
if (!current[key] || !Array.isArray(current[key])) {
|
|
1794
|
-
current[key] = []
|
|
1838
|
+
current[key] = []
|
|
1795
1839
|
}
|
|
1796
1840
|
// 扩展数组到所需索引
|
|
1797
1841
|
while (current[key].length <= index) {
|
|
1798
|
-
current[key].push(undefined)
|
|
1842
|
+
current[key].push(undefined)
|
|
1799
1843
|
}
|
|
1800
|
-
current[key][index] = value
|
|
1844
|
+
current[key][index] = value
|
|
1801
1845
|
} else {
|
|
1802
|
-
current[lastPart] = value
|
|
1846
|
+
current[lastPart] = value
|
|
1803
1847
|
}
|
|
1804
1848
|
}
|
|
1805
1849
|
}
|
|
1806
1850
|
|
|
1807
1851
|
function merge(target, ...sources) {
|
|
1808
|
-
if (!sources.length)
|
|
1852
|
+
if (!sources.length)
|
|
1853
|
+
return target
|
|
1809
1854
|
|
|
1810
1855
|
const source = sources.shift() // 取出第一个源对象
|
|
1811
1856
|
|
|
@@ -1842,28 +1887,28 @@ function _isObject(obj) {
|
|
|
1842
1887
|
|
|
1843
1888
|
;// ./lib/helpers/pReduce/pReduce.js
|
|
1844
1889
|
async function pReduce(iterable, reducer, initialValue) {
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1890
|
+
return new Promise((resolve, reject) => {
|
|
1891
|
+
const iterator = iterable[Symbol.iterator]()
|
|
1892
|
+
let index = 0
|
|
1848
1893
|
|
|
1849
|
-
|
|
1850
|
-
|
|
1894
|
+
const next = async (total) => {
|
|
1895
|
+
const element = iterator.next()
|
|
1851
1896
|
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1897
|
+
if (element.done) {
|
|
1898
|
+
resolve(total)
|
|
1899
|
+
return
|
|
1900
|
+
}
|
|
1856
1901
|
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1902
|
+
try {
|
|
1903
|
+
const [resolvedTotal, resolvedValue] = await Promise.all([total, element.value])
|
|
1904
|
+
next(reducer(resolvedTotal, resolvedValue, index++))
|
|
1905
|
+
} catch (error) {
|
|
1906
|
+
reject(error)
|
|
1907
|
+
}
|
|
1908
|
+
}
|
|
1864
1909
|
|
|
1865
|
-
|
|
1866
|
-
|
|
1910
|
+
next(initialValue)
|
|
1911
|
+
})
|
|
1867
1912
|
}
|
|
1868
1913
|
|
|
1869
1914
|
|
|
@@ -2010,16 +2055,17 @@ class Repo {
|
|
|
2010
2055
|
const promise = typeof this.model.saveAll === 'function'
|
|
2011
2056
|
? this.model.saveAll({ config, docs })
|
|
2012
2057
|
: Promise.all(docs.map(async (doc) => {
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2058
|
+
if (doc) {
|
|
2059
|
+
const result = await this.saveOne({ config, doc })
|
|
2060
|
+
isNew = result.isNew
|
|
2061
|
+
const _data = result._data || result.data
|
|
2062
|
+
return _data[0]
|
|
2063
|
+
}
|
|
2064
|
+
return null
|
|
2065
|
+
}))
|
|
2021
2066
|
return promise.then((savedData) => {
|
|
2022
|
-
if (savedData.length !== 1)
|
|
2067
|
+
if (savedData.length !== 1)
|
|
2068
|
+
isNew = null
|
|
2023
2069
|
const result = {
|
|
2024
2070
|
data: savedData,
|
|
2025
2071
|
isNew,
|
|
@@ -2353,6 +2399,9 @@ function initOnlyValidFromArray(_class, arr) {
|
|
|
2353
2399
|
;// ./lib/helpers/initOnlyValidFromArray/index.js
|
|
2354
2400
|
|
|
2355
2401
|
|
|
2402
|
+
;// ./lib/helpers/isConvertibleToNumber/index.js
|
|
2403
|
+
|
|
2404
|
+
|
|
2356
2405
|
;// ./lib/helpers/mergeArraysByKey/mergeArraysByKey.js
|
|
2357
2406
|
function mergeArraysByKey(arr1, arr2) {
|
|
2358
2407
|
// Handle undefined/null inputs by defaulting to empty arrays
|
|
@@ -2363,40 +2412,41 @@ function mergeArraysByKey(arr1, arr2) {
|
|
|
2363
2412
|
|
|
2364
2413
|
// Helper function to merge values based on their type
|
|
2365
2414
|
const mergeValues = (existingValue, newValue) => {
|
|
2366
|
-
if (existingValue === undefined)
|
|
2367
|
-
|
|
2415
|
+
if (existingValue === undefined)
|
|
2416
|
+
return newValue
|
|
2417
|
+
|
|
2368
2418
|
// Handle arrays by concatenating
|
|
2369
2419
|
if (Array.isArray(existingValue) && Array.isArray(newValue)) {
|
|
2370
2420
|
return [...new Set([...existingValue, ...newValue])]
|
|
2371
2421
|
}
|
|
2372
|
-
|
|
2422
|
+
|
|
2373
2423
|
// Handle objects by merging
|
|
2374
|
-
if (typeof existingValue === 'object' && typeof newValue === 'object'
|
|
2375
|
-
|
|
2424
|
+
if (typeof existingValue === 'object' && typeof newValue === 'object'
|
|
2425
|
+
&& !Array.isArray(existingValue) && !Array.isArray(newValue)) {
|
|
2376
2426
|
return { ...existingValue, ...newValue }
|
|
2377
2427
|
}
|
|
2378
|
-
|
|
2428
|
+
|
|
2379
2429
|
// // Handle numbers by adding
|
|
2380
2430
|
// if (typeof existingValue === 'number' && typeof newValue === 'number') {
|
|
2381
2431
|
// return existingValue
|
|
2382
2432
|
// }
|
|
2383
|
-
|
|
2433
|
+
|
|
2384
2434
|
// // Handle strings by concatenating
|
|
2385
2435
|
// if (typeof existingValue === 'string' && typeof newValue === 'string') {
|
|
2386
2436
|
// return existingValue
|
|
2387
2437
|
// }
|
|
2388
|
-
|
|
2438
|
+
|
|
2389
2439
|
// Default: use the new value
|
|
2390
2440
|
return newValue
|
|
2391
2441
|
}
|
|
2392
2442
|
|
|
2393
2443
|
// Process first array
|
|
2394
|
-
safeArr1.forEach(item => {
|
|
2444
|
+
safeArr1.forEach((item) => {
|
|
2395
2445
|
mergedMap.set(item.key, item.value)
|
|
2396
2446
|
})
|
|
2397
2447
|
|
|
2398
2448
|
// Process second array and merge values
|
|
2399
|
-
safeArr2.forEach(item => {
|
|
2449
|
+
safeArr2.forEach((item) => {
|
|
2400
2450
|
const existingValue = mergedMap.get(item.key)
|
|
2401
2451
|
mergedMap.set(item.key, mergeValues(existingValue, item.value))
|
|
2402
2452
|
})
|
|
@@ -2415,7 +2465,7 @@ function mergeArraysByKey(arr1, arr2) {
|
|
|
2415
2465
|
function padZeros(num, minLength = 6) {
|
|
2416
2466
|
num = num.toString()
|
|
2417
2467
|
if (num.length < minLength) {
|
|
2418
|
-
return padZeros(
|
|
2468
|
+
return padZeros(`0${num}`, minLength)
|
|
2419
2469
|
}
|
|
2420
2470
|
return num
|
|
2421
2471
|
}
|
|
@@ -2435,26 +2485,26 @@ function padZeros(num, minLength = 6) {
|
|
|
2435
2485
|
;// ./lib/helpers/replacePlaceholders/replacePlaceholders.js
|
|
2436
2486
|
function replacePlaceholders({ content, mapping }) {
|
|
2437
2487
|
let isObjectMode = false
|
|
2438
|
-
|
|
2488
|
+
|
|
2439
2489
|
if (typeof content === 'object' && content !== null) {
|
|
2440
2490
|
content = JSON.stringify(content)
|
|
2441
2491
|
isObjectMode = true
|
|
2442
2492
|
}
|
|
2443
2493
|
|
|
2444
2494
|
// [[ eventRegistration.eventRegistrationCode | 0 ]]
|
|
2445
|
-
const regex = /(\[*)\[\[\s*([\w.\-
|
|
2495
|
+
const regex = /(\[*)\[\[\s*([\w.\-]+)(?:\s*\|\s*([^:\]\s]+))?(?:\s*:\s*([^\]\s]+))?\s*\]\](\]*)/g
|
|
2446
2496
|
|
|
2447
2497
|
const result = content.replace(regex, (match, leadingBrackets, path, defaultValue, type, trailingBrackets) => {
|
|
2448
|
-
|
|
2449
2498
|
// Split the path into parts
|
|
2450
2499
|
const keys = path.trim().split('.')
|
|
2451
|
-
|
|
2500
|
+
|
|
2452
2501
|
// Traverse the nested object structure
|
|
2453
2502
|
let value = mapping
|
|
2454
2503
|
for (const key of keys) {
|
|
2455
2504
|
// Handle empty keys (in case of double dots or leading/trailing dots)
|
|
2456
|
-
if (!key)
|
|
2457
|
-
|
|
2505
|
+
if (!key)
|
|
2506
|
+
continue
|
|
2507
|
+
|
|
2458
2508
|
value = value?.[key]
|
|
2459
2509
|
if (value === undefined) {
|
|
2460
2510
|
break
|
|
@@ -2462,10 +2512,12 @@ function replacePlaceholders({ content, mapping }) {
|
|
|
2462
2512
|
}
|
|
2463
2513
|
|
|
2464
2514
|
// Apply default if missing
|
|
2465
|
-
if (value === undefined)
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2515
|
+
if (value === undefined)
|
|
2516
|
+
value = defaultValue?.trim()
|
|
2517
|
+
if (value === undefined)
|
|
2518
|
+
return isObjectMode ? undefined : match
|
|
2519
|
+
|
|
2520
|
+
value = value !== undefined
|
|
2469
2521
|
? leadingBrackets + value + trailingBrackets
|
|
2470
2522
|
: match
|
|
2471
2523
|
|
|
@@ -2486,10 +2538,11 @@ function replacePlaceholders({ content, mapping }) {
|
|
|
2486
2538
|
/**
|
|
2487
2539
|
* Sanitizes input by removing hidden/control characters with customizable whitespace handling.
|
|
2488
2540
|
* @param {string} input - The string to sanitize.
|
|
2489
|
-
* @param {
|
|
2490
|
-
* @param {boolean} [options.normalizeWhitespace
|
|
2491
|
-
* @param {boolean} [options.removeNewlines
|
|
2492
|
-
* @param {boolean} [options.trim
|
|
2541
|
+
* @param {object} [options] - Configuration options.
|
|
2542
|
+
* @param {boolean} [options.normalizeWhitespace] - Collapse multiple spaces/tabs into one space.
|
|
2543
|
+
* @param {boolean} [options.removeNewlines] - If true, replaces newlines with spaces.
|
|
2544
|
+
* @param {boolean} [options.trim] - If true, trims leading/trailing whitespace.
|
|
2545
|
+
* @param {boolean} [options.debug] - If true, logs debug information about removed characters.
|
|
2493
2546
|
* @returns {string} The sanitized string.
|
|
2494
2547
|
*/
|
|
2495
2548
|
function sanitizeText(input, options = {}) {
|
|
@@ -2497,7 +2550,8 @@ function sanitizeText(input, options = {}) {
|
|
|
2497
2550
|
normalizeWhitespace = true,
|
|
2498
2551
|
removeNewlines = false,
|
|
2499
2552
|
trim = true,
|
|
2500
|
-
preserveBasicWhitespace = true,
|
|
2553
|
+
preserveBasicWhitespace = true,
|
|
2554
|
+
debug = false, // new option for debugging
|
|
2501
2555
|
} = options
|
|
2502
2556
|
|
|
2503
2557
|
if (typeof input !== 'string') {
|
|
@@ -2506,27 +2560,106 @@ function sanitizeText(input, options = {}) {
|
|
|
2506
2560
|
|
|
2507
2561
|
let result = input
|
|
2508
2562
|
|
|
2563
|
+
if (debug) {
|
|
2564
|
+
console.log('Original input:', JSON.stringify(input))
|
|
2565
|
+
console.log('Options:', { normalizeWhitespace, removeNewlines, trim, preserveBasicWhitespace })
|
|
2566
|
+
}
|
|
2567
|
+
|
|
2509
2568
|
// Phase 1: Remove all control characters except basic whitespace if requested
|
|
2510
2569
|
if (preserveBasicWhitespace && !removeNewlines) {
|
|
2511
|
-
|
|
2512
|
-
|
|
2570
|
+
if (debug) {
|
|
2571
|
+
const before = result
|
|
2572
|
+
const matches = []
|
|
2573
|
+
// Use a replacer function to capture what's being removed
|
|
2574
|
+
result = result.replace(/[\x00-\x08\v\f\x0E-\x1F\x7F-\x9F\u200B-\u200D\uFEFF\u202A-\u202E]/g, (match) => {
|
|
2575
|
+
matches.push({
|
|
2576
|
+
char: match,
|
|
2577
|
+
code: match.charCodeAt(0),
|
|
2578
|
+
hex: `0x${match.charCodeAt(0).toString(16).toUpperCase().padStart(4, '0')}`
|
|
2579
|
+
})
|
|
2580
|
+
return ''
|
|
2581
|
+
})
|
|
2582
|
+
if (matches.length > 0) {
|
|
2583
|
+
console.log('Phase 1 (preserve mode) - Removed characters:')
|
|
2584
|
+
matches.forEach((m) => {
|
|
2585
|
+
console.log(` - Character: ${JSON.stringify(m.char)}, Code: ${m.code}, Hex: ${m.hex}`)
|
|
2586
|
+
})
|
|
2587
|
+
console.log(`Removed ${matches.length} control character(s)`)
|
|
2588
|
+
} else {
|
|
2589
|
+
console.log('Phase 1 (preserve mode) - No control characters found')
|
|
2590
|
+
}
|
|
2591
|
+
} else {
|
|
2592
|
+
result = result.replace(/[\x00-\x08\v\f\x0E-\x1F\x7F-\x9F\u200B-\u200D\uFEFF\u202A-\u202E]/g, '')
|
|
2593
|
+
}
|
|
2513
2594
|
} else {
|
|
2514
|
-
|
|
2515
|
-
|
|
2595
|
+
if (debug) {
|
|
2596
|
+
const before = result
|
|
2597
|
+
const matches = []
|
|
2598
|
+
result = result.replace(/[\x00-\x1F\x7F-\x9F\u200B-\u200D\uFEFF\u202A-\u202E]/g, (match) => {
|
|
2599
|
+
matches.push({
|
|
2600
|
+
char: match,
|
|
2601
|
+
code: match.charCodeAt(0),
|
|
2602
|
+
hex: `0x${match.charCodeAt(0).toString(16).toUpperCase().padStart(4, '0')}`
|
|
2603
|
+
})
|
|
2604
|
+
return ''
|
|
2605
|
+
})
|
|
2606
|
+
if (matches.length > 0) {
|
|
2607
|
+
console.log('Phase 1 (full removal mode) - Removed characters:')
|
|
2608
|
+
matches.forEach((m) => {
|
|
2609
|
+
console.log(` - Character: ${JSON.stringify(m.char)}, Code: ${m.code}, Hex: ${m.hex}`)
|
|
2610
|
+
})
|
|
2611
|
+
console.log(`Removed ${matches.length} control character(s)`)
|
|
2612
|
+
} else {
|
|
2613
|
+
console.log('Phase 1 (full removal mode) - No control characters found')
|
|
2614
|
+
}
|
|
2615
|
+
} else {
|
|
2616
|
+
result = result.replace(/[\x00-\x1F\x7F-\x9F\u200B-\u200D\uFEFF\u202A-\u202E]/g, '')
|
|
2617
|
+
}
|
|
2618
|
+
}
|
|
2619
|
+
|
|
2620
|
+
if (debug) {
|
|
2621
|
+
console.log('After Phase 1:', JSON.stringify(result))
|
|
2516
2622
|
}
|
|
2517
2623
|
|
|
2518
2624
|
// Phase 2: Handle whitespace transformations
|
|
2519
2625
|
if (removeNewlines) {
|
|
2520
|
-
|
|
2626
|
+
if (debug) {
|
|
2627
|
+
const before = result
|
|
2628
|
+
result = result.replace(/[\r\n]+/g, ' ')
|
|
2629
|
+
console.log('Phase 2 - Converted newlines to spaces')
|
|
2630
|
+
} else {
|
|
2631
|
+
result = result.replace(/[\r\n]+/g, ' ')
|
|
2632
|
+
}
|
|
2521
2633
|
}
|
|
2522
2634
|
|
|
2523
2635
|
if (normalizeWhitespace) {
|
|
2524
|
-
|
|
2636
|
+
if (debug) {
|
|
2637
|
+
const before = result
|
|
2638
|
+
result = result.replace(/[ \t]+/g, ' ')
|
|
2639
|
+
console.log('Phase 2 - Normalized whitespace')
|
|
2640
|
+
} else {
|
|
2641
|
+
result = result.replace(/[ \t]+/g, ' ')
|
|
2642
|
+
}
|
|
2643
|
+
}
|
|
2644
|
+
|
|
2645
|
+
if (debug) {
|
|
2646
|
+
console.log('After Phase 2:', JSON.stringify(result))
|
|
2525
2647
|
}
|
|
2526
2648
|
|
|
2527
2649
|
// Phase 3: Final trimming
|
|
2528
2650
|
if (trim) {
|
|
2529
|
-
|
|
2651
|
+
if (debug) {
|
|
2652
|
+
const before = result
|
|
2653
|
+
result = result.trim()
|
|
2654
|
+
console.log('Phase 3 - Trimmed leading/trailing whitespace')
|
|
2655
|
+
} else {
|
|
2656
|
+
result = result.trim()
|
|
2657
|
+
}
|
|
2658
|
+
}
|
|
2659
|
+
|
|
2660
|
+
if (debug) {
|
|
2661
|
+
console.log('Final result:', JSON.stringify(result))
|
|
2662
|
+
console.log('--- Sanitization complete ---')
|
|
2530
2663
|
}
|
|
2531
2664
|
|
|
2532
2665
|
return result
|
|
@@ -2537,12 +2670,12 @@ function sanitizeText(input, options = {}) {
|
|
|
2537
2670
|
|
|
2538
2671
|
;// ./lib/helpers/shuffleArray/shuffleArray.js
|
|
2539
2672
|
function shuffleArray(array) {
|
|
2540
|
-
const arr = [...array]
|
|
2541
|
-
for (let i = arr.length - 1; i >= 0; i--) {
|
|
2673
|
+
const arr = [...array]
|
|
2674
|
+
for (let i = arr.length - 1; i >= 0; i--) { // Changed `i > 0` to `i >= 0`
|
|
2542
2675
|
const j = Math.floor(Math.random() * (i + 1));
|
|
2543
|
-
[arr[i], arr[j]] = [arr[j], arr[i]]
|
|
2676
|
+
[arr[i], arr[j]] = [arr[j], arr[i]]
|
|
2544
2677
|
}
|
|
2545
|
-
return arr
|
|
2678
|
+
return arr
|
|
2546
2679
|
}
|
|
2547
2680
|
|
|
2548
2681
|
;// ./lib/helpers/shuffleArray/index.js
|
|
@@ -2604,7 +2737,7 @@ function indexCharset(str) {
|
|
|
2604
2737
|
for (let i = 0; i < length; i++) {
|
|
2605
2738
|
char = str[i]
|
|
2606
2739
|
byCode[i] = char
|
|
2607
|
-
byChar[char] = i
|
|
2740
|
+
byChar[char] = i
|
|
2608
2741
|
}
|
|
2609
2742
|
return { byCode, byChar, length }
|
|
2610
2743
|
}
|
|
@@ -2635,7 +2768,7 @@ function randomString({ len = 16, pattern = 'a1' } = {}) {
|
|
|
2635
2768
|
str += mark
|
|
2636
2769
|
}
|
|
2637
2770
|
const chars = [...str]
|
|
2638
|
-
return [...Array(len)].map(i => {
|
|
2771
|
+
return [...new Array(len)].map((i) => {
|
|
2639
2772
|
return chars[(Math.random() * chars.length) | 0]
|
|
2640
2773
|
}).join``
|
|
2641
2774
|
}
|
|
@@ -2659,12 +2792,14 @@ function setCode(base = 34) {
|
|
|
2659
2792
|
}
|
|
2660
2793
|
|
|
2661
2794
|
function toCamelCase(str) {
|
|
2662
|
-
if (!str)
|
|
2795
|
+
if (!str)
|
|
2796
|
+
return ''
|
|
2663
2797
|
return str
|
|
2664
2798
|
.trim()
|
|
2665
2799
|
.split(/\s+/)
|
|
2666
2800
|
.map((word, index) => {
|
|
2667
|
-
if (!word)
|
|
2801
|
+
if (!word)
|
|
2802
|
+
return ''
|
|
2668
2803
|
if (index === 0) {
|
|
2669
2804
|
return word.toLowerCase()
|
|
2670
2805
|
}
|
|
@@ -2674,7 +2809,8 @@ function toCamelCase(str) {
|
|
|
2674
2809
|
}
|
|
2675
2810
|
|
|
2676
2811
|
function toLowerCase(str) {
|
|
2677
|
-
if (!str)
|
|
2812
|
+
if (!str)
|
|
2813
|
+
return ''
|
|
2678
2814
|
return str
|
|
2679
2815
|
.trim()
|
|
2680
2816
|
.toLowerCase()
|
|
@@ -2709,7 +2845,7 @@ function trackingPlugin(schema, options) {
|
|
|
2709
2845
|
})
|
|
2710
2846
|
|
|
2711
2847
|
// Auto-update hook
|
|
2712
|
-
schema.pre('save', function(next) {
|
|
2848
|
+
schema.pre('save', function (next) {
|
|
2713
2849
|
this.meta.modified = Date.now()
|
|
2714
2850
|
next()
|
|
2715
2851
|
})
|
|
@@ -2721,9 +2857,9 @@ function trackingPlugin(schema, options) {
|
|
|
2721
2857
|
}, {
|
|
2722
2858
|
name: 'tracking_status_index',
|
|
2723
2859
|
background: true,
|
|
2724
|
-
partialFilterExpression: {
|
|
2860
|
+
partialFilterExpression: {
|
|
2725
2861
|
'meta.active': true,
|
|
2726
|
-
'meta.deleted': false
|
|
2862
|
+
'meta.deleted': false
|
|
2727
2863
|
}
|
|
2728
2864
|
})
|
|
2729
2865
|
|
|
@@ -2752,7 +2888,7 @@ function tenantPlugin(schema, options) {
|
|
|
2752
2888
|
|
|
2753
2889
|
// Add core indexes
|
|
2754
2890
|
schema.index({
|
|
2755
|
-
|
|
2891
|
+
tenantCode: 1
|
|
2756
2892
|
}, {
|
|
2757
2893
|
name: 'tenant_core_index',
|
|
2758
2894
|
background: true
|
|
@@ -2760,15 +2896,15 @@ function tenantPlugin(schema, options) {
|
|
|
2760
2896
|
|
|
2761
2897
|
// 1. ENHANCE EXISTING TRACKING INDEXES
|
|
2762
2898
|
const existingIndexes = schema.indexes()
|
|
2763
|
-
|
|
2899
|
+
|
|
2764
2900
|
// Check if tracking_status_index exists
|
|
2765
|
-
const hasTenantStatusIndex = existingIndexes.some(idx =>
|
|
2901
|
+
const hasTenantStatusIndex = existingIndexes.some((idx) =>
|
|
2766
2902
|
idx.name === 'tenant_status_index' // Check by name for reliability
|
|
2767
2903
|
)
|
|
2768
2904
|
|
|
2769
2905
|
if (!hasTenantStatusIndex) {
|
|
2770
2906
|
schema.index({
|
|
2771
|
-
|
|
2907
|
+
tenantCode: 1, // Unique field first
|
|
2772
2908
|
_type: 1, // Low-cardinality field last
|
|
2773
2909
|
}, {
|
|
2774
2910
|
name: 'tenant_status_index',
|
|
@@ -2776,7 +2912,7 @@ function tenantPlugin(schema, options) {
|
|
|
2776
2912
|
partialFilterExpression: {
|
|
2777
2913
|
'_type': 'Tenant',
|
|
2778
2914
|
'meta.active': true,
|
|
2779
|
-
'meta.deleted': false
|
|
2915
|
+
'meta.deleted': false
|
|
2780
2916
|
}
|
|
2781
2917
|
})
|
|
2782
2918
|
}
|
|
@@ -2815,6 +2951,7 @@ function tenantPlugin(schema, options) {
|
|
|
2815
2951
|
|
|
2816
2952
|
|
|
2817
2953
|
|
|
2954
|
+
|
|
2818
2955
|
|
|
2819
2956
|
|
|
2820
2957
|
;// ./lib/models/apiResponse/index.js
|
|
@@ -2872,10 +3009,11 @@ class AwsStsS3Client {
|
|
|
2872
3009
|
}
|
|
2873
3010
|
|
|
2874
3011
|
get isExpired() {
|
|
2875
|
-
if (!this.expiration)
|
|
2876
|
-
|
|
2877
|
-
const
|
|
2878
|
-
|
|
3012
|
+
if (!this.expiration)
|
|
3013
|
+
return true
|
|
3014
|
+
const now = new Date()
|
|
3015
|
+
const bufferMs = 1 * 60 * 1000 // 一分钟缓冲
|
|
3016
|
+
return now >= new Date(this.expiration.getTime() - bufferMs)
|
|
2879
3017
|
}
|
|
2880
3018
|
|
|
2881
3019
|
get isValid() {
|
|
@@ -2910,7 +3048,7 @@ class AwsStsS3Client {
|
|
|
2910
3048
|
throw new Error(`Missing ${component} in AWS awsClientS3 client configuration`)
|
|
2911
3049
|
}
|
|
2912
3050
|
}
|
|
2913
|
-
|
|
3051
|
+
|
|
2914
3052
|
return true
|
|
2915
3053
|
}
|
|
2916
3054
|
|
|
@@ -2920,9 +3058,9 @@ class AwsStsS3Client {
|
|
|
2920
3058
|
if (!webIdentityToken) {
|
|
2921
3059
|
throw new Error('getIdToken function returned empty or invalid token')
|
|
2922
3060
|
}
|
|
2923
|
-
|
|
3061
|
+
|
|
2924
3062
|
const stsClient = new this.awsClientSts.STSClient({ region: this.region })
|
|
2925
|
-
|
|
3063
|
+
|
|
2926
3064
|
const stsResponse = await stsClient.send(
|
|
2927
3065
|
new this.awsClientSts.AssumeRoleWithWebIdentityCommand({
|
|
2928
3066
|
RoleArn: this.roleArn,
|
|
@@ -3229,29 +3367,30 @@ class KeyValueObject {
|
|
|
3229
3367
|
}
|
|
3230
3368
|
|
|
3231
3369
|
function _mergeValues(existingValue, newValue) {
|
|
3232
|
-
if (existingValue === undefined)
|
|
3233
|
-
|
|
3370
|
+
if (existingValue === undefined)
|
|
3371
|
+
return newValue
|
|
3372
|
+
|
|
3234
3373
|
// Handle arrays by concatenating
|
|
3235
3374
|
if (Array.isArray(existingValue) && Array.isArray(newValue)) {
|
|
3236
3375
|
return [...new Set([...existingValue, ...newValue])]
|
|
3237
3376
|
}
|
|
3238
|
-
|
|
3377
|
+
|
|
3239
3378
|
// Handle objects by merging
|
|
3240
|
-
if (typeof existingValue === 'object' && typeof newValue === 'object'
|
|
3241
|
-
|
|
3379
|
+
if (typeof existingValue === 'object' && typeof newValue === 'object'
|
|
3380
|
+
&& !Array.isArray(existingValue) && !Array.isArray(newValue)) {
|
|
3242
3381
|
return { ...existingValue, ...newValue }
|
|
3243
3382
|
}
|
|
3244
|
-
|
|
3383
|
+
|
|
3245
3384
|
// // Handle numbers by adding
|
|
3246
3385
|
// if (typeof existingValue === 'number' && typeof newValue === 'number') {
|
|
3247
3386
|
// return existingValue
|
|
3248
3387
|
// }
|
|
3249
|
-
|
|
3388
|
+
|
|
3250
3389
|
// // Handle strings by concatenating
|
|
3251
3390
|
// if (typeof existingValue === 'string' && typeof newValue === 'string') {
|
|
3252
3391
|
// return existingValue
|
|
3253
3392
|
// }
|
|
3254
|
-
|
|
3393
|
+
|
|
3255
3394
|
// Default: use the new value
|
|
3256
3395
|
return newValue
|
|
3257
3396
|
}
|
|
@@ -3311,29 +3450,30 @@ function metadata_isSame(key1, key2) {
|
|
|
3311
3450
|
}
|
|
3312
3451
|
|
|
3313
3452
|
function metadata_mergeValues(existingValue, newValue) {
|
|
3314
|
-
if (existingValue === undefined)
|
|
3315
|
-
|
|
3453
|
+
if (existingValue === undefined)
|
|
3454
|
+
return newValue
|
|
3455
|
+
|
|
3316
3456
|
// Handle arrays by concatenating
|
|
3317
3457
|
if (Array.isArray(existingValue) && Array.isArray(newValue)) {
|
|
3318
3458
|
return [...new Set([...existingValue, ...newValue])]
|
|
3319
3459
|
}
|
|
3320
|
-
|
|
3460
|
+
|
|
3321
3461
|
// Handle objects by merging
|
|
3322
|
-
if (typeof existingValue === 'object' && typeof newValue === 'object'
|
|
3323
|
-
|
|
3462
|
+
if (typeof existingValue === 'object' && typeof newValue === 'object'
|
|
3463
|
+
&& !Array.isArray(existingValue) && !Array.isArray(newValue)) {
|
|
3324
3464
|
return { ...existingValue, ...newValue }
|
|
3325
3465
|
}
|
|
3326
|
-
|
|
3466
|
+
|
|
3327
3467
|
// // Handle numbers by adding
|
|
3328
3468
|
// if (typeof existingValue === 'number' && typeof newValue === 'number') {
|
|
3329
3469
|
// return existingValue
|
|
3330
3470
|
// }
|
|
3331
|
-
|
|
3471
|
+
|
|
3332
3472
|
// // Handle strings by concatenating
|
|
3333
3473
|
// if (typeof existingValue === 'string' && typeof newValue === 'string') {
|
|
3334
3474
|
// return existingValue
|
|
3335
3475
|
// }
|
|
3336
|
-
|
|
3476
|
+
|
|
3337
3477
|
// Default: use the new value
|
|
3338
3478
|
return newValue
|
|
3339
3479
|
}
|
|
@@ -3354,14 +3494,14 @@ class TrackedEntity {
|
|
|
3354
3494
|
const timestamp = Date.now()
|
|
3355
3495
|
this.meta = {
|
|
3356
3496
|
active: options.meta?.active ?? options.active ?? true,
|
|
3357
|
-
created: options.meta?.created ?? (options.created
|
|
3358
|
-
|
|
3359
|
-
|
|
3497
|
+
created: options.meta?.created ?? (options.created
|
|
3498
|
+
? new Date(options.created).getTime()
|
|
3499
|
+
: timestamp),
|
|
3360
3500
|
creator: options.meta?.creator ?? options.creator ?? '',
|
|
3361
3501
|
deleted: options.meta?.deleted ?? options.deleted ?? false,
|
|
3362
|
-
modified: options.meta?.modified ?? (options.modified
|
|
3363
|
-
|
|
3364
|
-
|
|
3502
|
+
modified: options.meta?.modified ?? (options.modified
|
|
3503
|
+
? new Date(options.modified).getTime()
|
|
3504
|
+
: timestamp),
|
|
3365
3505
|
owner: options.meta?.owner ?? options.owner ?? '',
|
|
3366
3506
|
}
|
|
3367
3507
|
|
|
@@ -3528,7 +3668,6 @@ class PushEnvelope extends TrackedEntity {
|
|
|
3528
3668
|
get isValid() {
|
|
3529
3669
|
return super.isValid && this.data
|
|
3530
3670
|
}
|
|
3531
|
-
|
|
3532
3671
|
}
|
|
3533
3672
|
|
|
3534
3673
|
;// ./lib/models/pushEnvelope/index.js
|
|
@@ -3595,6 +3734,168 @@ class QMeta {
|
|
|
3595
3734
|
|
|
3596
3735
|
|
|
3597
3736
|
|
|
3737
|
+
;// ./lib/models/status/actionRecord.js
|
|
3738
|
+
|
|
3739
|
+
|
|
3740
|
+
class ActionRecord {
|
|
3741
|
+
constructor(options) {
|
|
3742
|
+
options = options || {}
|
|
3743
|
+
|
|
3744
|
+
const { _Actor } = options._constructor || {}
|
|
3745
|
+
this._Actor = _Actor
|
|
3746
|
+
|
|
3747
|
+
this._actor = options._actor
|
|
3748
|
+
|
|
3749
|
+
this.actorCode = typeof options === 'number' ? null : (options.actorCode || null)
|
|
3750
|
+
this.timestamp = typeof options === 'number' ? options : (options.timestamp || null)
|
|
3751
|
+
}
|
|
3752
|
+
|
|
3753
|
+
static get _classname() {
|
|
3754
|
+
return 'ActionRecord'
|
|
3755
|
+
}
|
|
3756
|
+
static get _superclass() {
|
|
3757
|
+
return 'ActionRecord'
|
|
3758
|
+
}
|
|
3759
|
+
static dummyData() {
|
|
3760
|
+
return {
|
|
3761
|
+
timestamp: (new Date()).valueOf(),
|
|
3762
|
+
}
|
|
3763
|
+
}
|
|
3764
|
+
static init(options = {}) {
|
|
3765
|
+
return init(this, options)
|
|
3766
|
+
}
|
|
3767
|
+
|
|
3768
|
+
get _classname() {
|
|
3769
|
+
return 'ActionRecord'
|
|
3770
|
+
}
|
|
3771
|
+
|
|
3772
|
+
get _superclass() {
|
|
3773
|
+
return 'ActionRecord'
|
|
3774
|
+
}
|
|
3775
|
+
|
|
3776
|
+
get actor() {
|
|
3777
|
+
return this._Actor && typeof this._Actor.init === 'function' ? this._Actor.init(this._actor) : this._actor
|
|
3778
|
+
}
|
|
3779
|
+
|
|
3780
|
+
get isValid() {
|
|
3781
|
+
return !!this.timestamp
|
|
3782
|
+
}
|
|
3783
|
+
|
|
3784
|
+
update(update) {
|
|
3785
|
+
if (typeof update === 'number') {
|
|
3786
|
+
this.timestamp = update
|
|
3787
|
+
return this
|
|
3788
|
+
}
|
|
3789
|
+
Object.keys(update).forEach((key) => {
|
|
3790
|
+
this[key] = update[key]
|
|
3791
|
+
})
|
|
3792
|
+
return this
|
|
3793
|
+
}
|
|
3794
|
+
}
|
|
3795
|
+
|
|
3796
|
+
;// ./lib/models/status/status.js
|
|
3797
|
+
|
|
3798
|
+
|
|
3799
|
+
|
|
3800
|
+
const notUpdateAllowedProps = [
|
|
3801
|
+
'created',
|
|
3802
|
+
// 'statusType'
|
|
3803
|
+
]
|
|
3804
|
+
|
|
3805
|
+
class Status {
|
|
3806
|
+
constructor(options) {
|
|
3807
|
+
options = options || {}
|
|
3808
|
+
|
|
3809
|
+
const { _ActionRecord } = options._constructor || {}
|
|
3810
|
+
this._ActionRecord = _ActionRecord && (_ActionRecord._superclass === ActionRecord._superclass) ? _ActionRecord : ActionRecord
|
|
3811
|
+
|
|
3812
|
+
this.created = this._ActionRecord.init(options.created || { timestamp: (new Date()).valueOf() })
|
|
3813
|
+
// this.statusType = options.statusType || 'Status'
|
|
3814
|
+
}
|
|
3815
|
+
|
|
3816
|
+
static get _classname() {
|
|
3817
|
+
return 'Status'
|
|
3818
|
+
}
|
|
3819
|
+
static get _superclass() {
|
|
3820
|
+
return 'Status'
|
|
3821
|
+
}
|
|
3822
|
+
static dummyData() {
|
|
3823
|
+
return {}
|
|
3824
|
+
}
|
|
3825
|
+
static init(options = {}) {
|
|
3826
|
+
return init(this, options)
|
|
3827
|
+
}
|
|
3828
|
+
static initFromArray(arr = []) {
|
|
3829
|
+
return initFromArray(this, arr)
|
|
3830
|
+
}
|
|
3831
|
+
static initOnlyValidFromArray(arr = []) {
|
|
3832
|
+
return initOnlyValidFromArray(this, arr)
|
|
3833
|
+
}
|
|
3834
|
+
|
|
3835
|
+
get _classname() {
|
|
3836
|
+
return 'Status'
|
|
3837
|
+
}
|
|
3838
|
+
get _superclass() {
|
|
3839
|
+
return 'Status'
|
|
3840
|
+
}
|
|
3841
|
+
get isCreated() {
|
|
3842
|
+
return this.created?.timestamp !== null
|
|
3843
|
+
}
|
|
3844
|
+
get isValid() {
|
|
3845
|
+
return !!this
|
|
3846
|
+
}
|
|
3847
|
+
|
|
3848
|
+
setValue(t, actorCode, key) {
|
|
3849
|
+
const timestamp = t || Date.now()
|
|
3850
|
+
this[key] = this[key] instanceof this._ActionRecord ? this[key].update({ actorCode, timestamp }) : this._ActionRecord.init({ actorCode, timestamp })
|
|
3851
|
+
return this
|
|
3852
|
+
}
|
|
3853
|
+
|
|
3854
|
+
update(update) {
|
|
3855
|
+
Object.keys(update).forEach((key) => {
|
|
3856
|
+
if (!notUpdateAllowedProps.includes(key)) {
|
|
3857
|
+
this[key] = this[key] instanceof this._ActionRecord ? this[key].update(update[key]) : this._ActionRecord.init(update[key])
|
|
3858
|
+
}
|
|
3859
|
+
})
|
|
3860
|
+
return this
|
|
3861
|
+
}
|
|
3862
|
+
}
|
|
3863
|
+
|
|
3864
|
+
;// ./lib/models/status/statusDocument.js
|
|
3865
|
+
|
|
3866
|
+
|
|
3867
|
+
class StatusDocument extends Status {
|
|
3868
|
+
constructor(options) {
|
|
3869
|
+
options = options || {}
|
|
3870
|
+
super(options)
|
|
3871
|
+
|
|
3872
|
+
this.archived = this._ActionRecord.init(options.archived)
|
|
3873
|
+
this.completed = this._ActionRecord.init(options.completed)
|
|
3874
|
+
this.drafted = this._ActionRecord.init(options.drafted)
|
|
3875
|
+
this.discarded = this._ActionRecord.init(options.discarded)
|
|
3876
|
+
// this.statusType = 'StatusDocument'
|
|
3877
|
+
}
|
|
3878
|
+
|
|
3879
|
+
get isValid() {
|
|
3880
|
+
return super.isValid
|
|
3881
|
+
}
|
|
3882
|
+
|
|
3883
|
+
static get _classname() {
|
|
3884
|
+
return 'StatusDocument'
|
|
3885
|
+
}
|
|
3886
|
+
setArchived(value, actorCode) {
|
|
3887
|
+
// const timestamp = value || Date.now()
|
|
3888
|
+
// this.archived = this.archived instanceof this._ActionRecord ? this.archived.update({ actorCode, timestamp }) : this._ActionRecord.init({ actorCode, timestamp })
|
|
3889
|
+
// return this
|
|
3890
|
+
return this.setValue(value, actorCode, 'archived')
|
|
3891
|
+
}
|
|
3892
|
+
}
|
|
3893
|
+
|
|
3894
|
+
;// ./lib/models/status/index.js
|
|
3895
|
+
|
|
3896
|
+
|
|
3897
|
+
|
|
3898
|
+
|
|
3598
3899
|
;// ./lib/models/tenantAwareEntity/tenantAwareEntity.js
|
|
3599
3900
|
|
|
3600
3901
|
|
|
@@ -3735,6 +4036,7 @@ function _makeSetCode(fieldName, options) {
|
|
|
3735
4036
|
|
|
3736
4037
|
|
|
3737
4038
|
|
|
4039
|
+
|
|
3738
4040
|
;// ./lib/index.js
|
|
3739
4041
|
|
|
3740
4042
|
|