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