@questwork/q-utilities 0.1.17 → 0.1.19

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.
@@ -0,0 +1,46 @@
1
+ name: Publish to npm on Tag
2
+ on:
3
+ push:
4
+ tags:
5
+ - 'v*'
6
+ workflow_dispatch:
7
+ jobs:
8
+ publish:
9
+ runs-on: ubuntu-latest
10
+ permissions:
11
+ contents: read
12
+ packages: write
13
+ # environment: production
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+ with:
17
+ fetch-depth: 0 # Needed to get tag information
18
+
19
+ - name: Install pnpm
20
+ uses: pnpm/action-setup@v4
21
+ with:
22
+ version: 9
23
+
24
+ - uses: actions/setup-node@v4
25
+ with:
26
+ node-version: '20.x'
27
+ registry-url: https://registry.npmjs.org/
28
+ cache: 'pnpm'
29
+
30
+ - name: Install dependencies
31
+ run: pnpm install
32
+
33
+ - name: Build
34
+ run: |
35
+ BUILD_COMMAND=$(node -p "(require('./package.json').scripts || {}).build")
36
+ if [ "$BUILD_COMMAND" = "undefined" ]; then
37
+ echo "::notice::Can't find a build script in package.json, skip."
38
+ else
39
+ pnpm run build
40
+ fi
41
+
42
+ - name: Publish to npm
43
+ # if: steps.version-check.outputs.should_publish == 'true'
44
+ run: pnpm publish --no-git-checks --access public
45
+ env:
46
+ NODE_AUTH_TOKEN: ${{ secrets.QW_NPM_TOKEN }}
@@ -53,6 +53,7 @@ __webpack_require__.d(__webpack_exports__, {
53
53
  AwsStsS3Client: () => (/* reexport */ AwsStsS3Client),
54
54
  KeyValueObject: () => (/* reexport */ KeyValueObject),
55
55
  Metadata: () => (/* reexport */ Metadata),
56
+ PushEnvelope: () => (/* reexport */ PushEnvelope),
56
57
  QMeta: () => (/* reexport */ QMeta),
57
58
  Repo: () => (/* reexport */ Repo),
58
59
  Service: () => (/* reexport */ Service),
@@ -61,6 +62,7 @@ __webpack_require__.d(__webpack_exports__, {
61
62
  TrackedEntity: () => (/* reexport */ TrackedEntity),
62
63
  UniqueKeyGenerator: () => (/* reexport */ UniqueKeyGenerator),
63
64
  authorize: () => (/* reexport */ authorize),
65
+ calculateAge: () => (/* reexport */ calculateAge),
64
66
  changeCreatorOwner: () => (/* reexport */ changeCreatorOwner),
65
67
  concatStringByArray: () => (/* reexport */ concatStringByArray),
66
68
  convertString: () => (/* reexport */ convertString),
@@ -71,6 +73,7 @@ __webpack_require__.d(__webpack_exports__, {
71
73
  generalPost: () => (/* reexport */ generalPost),
72
74
  getValidation: () => (/* reexport */ getValidation),
73
75
  getValueByKeys: () => (/* reexport */ getValueByKeys_getValueByKeys),
76
+ groupArrayByKey: () => (/* reexport */ groupArrayByKey),
74
77
  init: () => (/* reexport */ init),
75
78
  initFromArray: () => (/* reexport */ initFromArray),
76
79
  initOnlyValidFromArray: () => (/* reexport */ initOnlyValidFromArray),
@@ -82,6 +85,7 @@ __webpack_require__.d(__webpack_exports__, {
82
85
  padZeros: () => (/* reexport */ padZeros),
83
86
  replacePlaceholders: () => (/* reexport */ replacePlaceholders),
84
87
  sanitizeText: () => (/* reexport */ sanitizeText),
88
+ shuffleArray: () => (/* reexport */ shuffleArray),
85
89
  stringFormatter: () => (/* reexport */ stringFormatter),
86
90
  stringHelper: () => (/* reexport */ stringHelper),
87
91
  tenantPlugin: () => (/* reexport */ tenantPlugin),
@@ -136,6 +140,36 @@ function authorize({ allowCoordinator, allowOwner, query = {}, required, user })
136
140
  ;// ./lib/helpers/authorize/index.js
137
141
 
138
142
 
143
+ ;// ./lib/helpers/calculateAge/calculateAge.js
144
+ function calculateAge(timestamp, reference) {
145
+ const birthDate = new Date(timestamp)
146
+ const refDate = reference ? new Date(reference) : new Date()
147
+ // Validate inputs
148
+ if (isNaN(birthDate.getTime())) {
149
+ return null
150
+ }
151
+ if (isNaN(refDate.getTime())) {
152
+ return null
153
+ }
154
+ if (birthDate > refDate) {
155
+ return null
156
+ }
157
+
158
+ // Calculate raw difference
159
+ let age = refDate.getFullYear() - birthDate.getFullYear();
160
+ const monthDiff = refDate.getMonth() - birthDate.getMonth();
161
+
162
+ // Adjust if birthday hasn't occurred yet this year
163
+ if (monthDiff < 0 || (monthDiff === 0 && refDate.getDate() < birthDate.getDate())) {
164
+ age--
165
+ }
166
+
167
+ return age
168
+ }
169
+
170
+ ;// ./lib/helpers/calculateAge/index.js
171
+
172
+
139
173
  ;// ./lib/helpers/changeCreatorOwner/changeCreatorOwner.js
140
174
  function changeCreatorOwner(that, { source, target }) {
141
175
  if (that.meta) {
@@ -1543,7 +1577,7 @@ function customHandler({ responseHelper, handler, ignoreError = false }) {
1543
1577
  await handler({ req, res })
1544
1578
  await next()
1545
1579
  } catch (err) {
1546
- if (ignoreError) {
1580
+ if (ignoreError || !responseHelper) {
1547
1581
  await next()
1548
1582
  } else {
1549
1583
  res.status(400).json(responseHelper.standardizeResponse({ err, message: err.message || err }))
@@ -2118,11 +2152,16 @@ class Service {
2118
2152
  return 'Service'
2119
2153
  }
2120
2154
 
2121
- deleteOne({ id }) {
2122
- return this.repo.deleteOne({ id })
2123
- .catch(() => {
2124
- throw new Error(`Not found for query: ${id}`)
2125
- })
2155
+ async deleteOne({ id }) {
2156
+ const result = await this.repo.deleteOne({ id })
2157
+ return makeApiResponse({
2158
+ repo: this.repo,
2159
+ result
2160
+ })
2161
+ // return this.repo.delete({ id })
2162
+ // .catch(() => {
2163
+ // throw new Error(`Not found for query: ${id}`)
2164
+ // })
2126
2165
  }
2127
2166
 
2128
2167
  async findAll({ query = {}, systemLog } = {}) {
@@ -2258,6 +2297,23 @@ function _makeService(resource, resourceInfo, UniqueKeyGenerator, GeneralModel)
2258
2297
 
2259
2298
 
2260
2299
 
2300
+ ;// ./lib/helpers/groupArrayByKey/groupArrayByKey.js
2301
+ function groupArrayByKey(arr, key) {
2302
+ if (!key || typeof key !== 'string') {
2303
+ return {}
2304
+ }
2305
+ return arr.reduce((acc, curr) => {
2306
+ if (!acc[curr[key]]) {
2307
+ acc[curr[key]] = 0
2308
+ }
2309
+ acc[curr[key]]++
2310
+ return acc
2311
+ }, {})
2312
+ }
2313
+
2314
+ ;// ./lib/helpers/groupArrayByKey/index.js
2315
+
2316
+
2261
2317
  ;// ./lib/helpers/init/init.js
2262
2318
  function init(_class, options) {
2263
2319
  if (options instanceof _class) {
@@ -2480,6 +2536,19 @@ function sanitizeText(input, options = {}) {
2480
2536
  ;// ./lib/helpers/sanitizeText/index.js
2481
2537
 
2482
2538
 
2539
+ ;// ./lib/helpers/shuffleArray/shuffleArray.js
2540
+ function shuffleArray(array) {
2541
+ const arr = [...array];
2542
+ for (let i = arr.length - 1; i >= 0; i--) { // Changed `i > 0` to `i >= 0`
2543
+ const j = Math.floor(Math.random() * (i + 1));
2544
+ [arr[i], arr[j]] = [arr[j], arr[i]];
2545
+ }
2546
+ return arr;
2547
+ }
2548
+
2549
+ ;// ./lib/helpers/shuffleArray/index.js
2550
+
2551
+
2483
2552
  ;// ./lib/helpers/stringFormatter/stringFormatter.js
2484
2553
  function stringFormatter(str, delimiter = '_') {
2485
2554
  if (str === null || typeof str === 'undefined' || typeof str.toString === 'undefined') {
@@ -2742,6 +2811,9 @@ function tenantPlugin(schema, options) {
2742
2811
 
2743
2812
 
2744
2813
 
2814
+
2815
+
2816
+
2745
2817
 
2746
2818
 
2747
2819
 
@@ -3274,67 +3346,6 @@ function metadata_mergeValues(existingValue, newValue) {
3274
3346
 
3275
3347
 
3276
3348
 
3277
- ;// ./lib/models/qMeta/qMeta.js
3278
-
3279
-
3280
- const updateAllowedProps = [
3281
- 'attributes',
3282
- 'ref'
3283
- ]
3284
-
3285
- class QMeta {
3286
- constructor(options = {}) {
3287
- options = options || {}
3288
- this.attributes = KeyValueObject.initOnlyValidFromArray(options.attributes)
3289
- this.ref = options.ref || {}
3290
- }
3291
-
3292
- static get _classname() {
3293
- return 'QMeta'
3294
- }
3295
- static get _superclass() {
3296
- return 'QMeta'
3297
- }
3298
-
3299
- // Class methods
3300
- static init(options = {}) {
3301
- if (options instanceof QMeta) {
3302
- return options
3303
- }
3304
- return new QMeta(options)
3305
- }
3306
-
3307
- // instance methods
3308
- addAttribute(obj) {
3309
- const kvObject = KeyValueObject.init(obj)
3310
- if (!kvObject) {
3311
- throw new Error('invalid meta attribute')
3312
- }
3313
- this.attributes.push(kvObject)
3314
- return this
3315
- }
3316
-
3317
- update(obj) {
3318
- Object.keys(obj).forEach((key) => {
3319
- if (updateAllowedProps.includes(key)) {
3320
- if (key === 'attributes') {
3321
- this[key] = KeyValueObject.initOnlyValidFromArray(obj[key])
3322
- } else {
3323
- this[key] = obj[key]
3324
- }
3325
- }
3326
- })
3327
- return this
3328
- }
3329
- }
3330
-
3331
-
3332
-
3333
- ;// ./lib/models/qMeta/index.js
3334
-
3335
-
3336
-
3337
-
3338
3349
  ;// ./lib/models/trackedEntity/trackedEntity.js
3339
3350
 
3340
3351
 
@@ -3477,6 +3488,114 @@ class TrackedEntity {
3477
3488
 
3478
3489
  // Explicit named export (optional)
3479
3490
 
3491
+ ;// ./lib/models/pushEnvelope/pushEnvelope.js
3492
+
3493
+
3494
+
3495
+
3496
+
3497
+ class PushEnvelope extends TrackedEntity {
3498
+ constructor(options) {
3499
+ options = options || {}
3500
+ super(options)
3501
+
3502
+ this.id = options.id
3503
+ this.body = options.body
3504
+ this.data = options.data
3505
+ this.dirty = options.dirty
3506
+ this.metadata = Metadata.initOnlyValidFromArray(options.metadata)
3507
+ this.remarks = KeyValueObject.initOnlyValidFromArray(options.remarks)
3508
+ this.threadID = options.threadID
3509
+ this.title = options.title
3510
+ }
3511
+ static get _classname() {
3512
+ return 'PushEnvelope'
3513
+ }
3514
+ static get _superclass() {
3515
+ return 'PushEnvelope'
3516
+ }
3517
+ static init(options = {}) {
3518
+ return init(this, options)
3519
+ }
3520
+
3521
+ get _classname() {
3522
+ return 'PushEnvelope'
3523
+ }
3524
+
3525
+ get _superclass() {
3526
+ return 'PushEnvelope'
3527
+ }
3528
+
3529
+ get isValid() {
3530
+ return super.isValid && this.data
3531
+ }
3532
+
3533
+ }
3534
+
3535
+ ;// ./lib/models/pushEnvelope/index.js
3536
+
3537
+
3538
+ ;// ./lib/models/qMeta/qMeta.js
3539
+
3540
+
3541
+ const updateAllowedProps = [
3542
+ 'attributes',
3543
+ 'ref'
3544
+ ]
3545
+
3546
+ class QMeta {
3547
+ constructor(options = {}) {
3548
+ options = options || {}
3549
+ this.attributes = KeyValueObject.initOnlyValidFromArray(options.attributes)
3550
+ this.ref = options.ref || {}
3551
+ }
3552
+
3553
+ static get _classname() {
3554
+ return 'QMeta'
3555
+ }
3556
+ static get _superclass() {
3557
+ return 'QMeta'
3558
+ }
3559
+
3560
+ // Class methods
3561
+ static init(options = {}) {
3562
+ if (options instanceof QMeta) {
3563
+ return options
3564
+ }
3565
+ return new QMeta(options)
3566
+ }
3567
+
3568
+ // instance methods
3569
+ addAttribute(obj) {
3570
+ const kvObject = KeyValueObject.init(obj)
3571
+ if (!kvObject) {
3572
+ throw new Error('invalid meta attribute')
3573
+ }
3574
+ this.attributes.push(kvObject)
3575
+ return this
3576
+ }
3577
+
3578
+ update(obj) {
3579
+ Object.keys(obj).forEach((key) => {
3580
+ if (updateAllowedProps.includes(key)) {
3581
+ if (key === 'attributes') {
3582
+ this[key] = KeyValueObject.initOnlyValidFromArray(obj[key])
3583
+ } else {
3584
+ this[key] = obj[key]
3585
+ }
3586
+ }
3587
+ })
3588
+ return this
3589
+ }
3590
+ }
3591
+
3592
+
3593
+
3594
+ ;// ./lib/models/qMeta/index.js
3595
+
3596
+
3597
+
3598
+
3480
3599
  ;// ./lib/models/tenantAwareEntity/tenantAwareEntity.js
3481
3600
 
3482
3601
 
@@ -3616,6 +3735,7 @@ function _makeSetCode(fieldName, options) {
3616
3735
 
3617
3736
 
3618
3737
 
3738
+
3619
3739
  ;// ./lib/index.js
3620
3740
 
3621
3741
 
@@ -47,6 +47,36 @@ function authorize({ allowCoordinator, allowOwner, query = {}, required, user })
47
47
  ;// ./lib/helpers/authorize/index.js
48
48
 
49
49
 
50
+ ;// ./lib/helpers/calculateAge/calculateAge.js
51
+ function calculateAge(timestamp, reference) {
52
+ const birthDate = new Date(timestamp)
53
+ const refDate = reference ? new Date(reference) : new Date()
54
+ // Validate inputs
55
+ if (isNaN(birthDate.getTime())) {
56
+ return null
57
+ }
58
+ if (isNaN(refDate.getTime())) {
59
+ return null
60
+ }
61
+ if (birthDate > refDate) {
62
+ return null
63
+ }
64
+
65
+ // Calculate raw difference
66
+ let age = refDate.getFullYear() - birthDate.getFullYear();
67
+ const monthDiff = refDate.getMonth() - birthDate.getMonth();
68
+
69
+ // Adjust if birthday hasn't occurred yet this year
70
+ if (monthDiff < 0 || (monthDiff === 0 && refDate.getDate() < birthDate.getDate())) {
71
+ age--
72
+ }
73
+
74
+ return age
75
+ }
76
+
77
+ ;// ./lib/helpers/calculateAge/index.js
78
+
79
+
50
80
  ;// ./lib/helpers/changeCreatorOwner/changeCreatorOwner.js
51
81
  function changeCreatorOwner(that, { source, target }) {
52
82
  if (that.meta) {
@@ -1454,7 +1484,7 @@ function customHandler({ responseHelper, handler, ignoreError = false }) {
1454
1484
  await handler({ req, res })
1455
1485
  await next()
1456
1486
  } catch (err) {
1457
- if (ignoreError) {
1487
+ if (ignoreError || !responseHelper) {
1458
1488
  await next()
1459
1489
  } else {
1460
1490
  res.status(400).json(responseHelper.standardizeResponse({ err, message: err.message || err }))
@@ -2029,11 +2059,16 @@ class Service {
2029
2059
  return 'Service'
2030
2060
  }
2031
2061
 
2032
- deleteOne({ id }) {
2033
- return this.repo.deleteOne({ id })
2034
- .catch(() => {
2035
- throw new Error(`Not found for query: ${id}`)
2036
- })
2062
+ async deleteOne({ id }) {
2063
+ const result = await this.repo.deleteOne({ id })
2064
+ return makeApiResponse({
2065
+ repo: this.repo,
2066
+ result
2067
+ })
2068
+ // return this.repo.delete({ id })
2069
+ // .catch(() => {
2070
+ // throw new Error(`Not found for query: ${id}`)
2071
+ // })
2037
2072
  }
2038
2073
 
2039
2074
  async findAll({ query = {}, systemLog } = {}) {
@@ -2169,6 +2204,23 @@ function _makeService(resource, resourceInfo, UniqueKeyGenerator, GeneralModel)
2169
2204
 
2170
2205
 
2171
2206
 
2207
+ ;// ./lib/helpers/groupArrayByKey/groupArrayByKey.js
2208
+ function groupArrayByKey(arr, key) {
2209
+ if (!key || typeof key !== 'string') {
2210
+ return {}
2211
+ }
2212
+ return arr.reduce((acc, curr) => {
2213
+ if (!acc[curr[key]]) {
2214
+ acc[curr[key]] = 0
2215
+ }
2216
+ acc[curr[key]]++
2217
+ return acc
2218
+ }, {})
2219
+ }
2220
+
2221
+ ;// ./lib/helpers/groupArrayByKey/index.js
2222
+
2223
+
2172
2224
  ;// ./lib/helpers/init/init.js
2173
2225
  function init(_class, options) {
2174
2226
  if (options instanceof _class) {
@@ -2391,6 +2443,19 @@ function sanitizeText(input, options = {}) {
2391
2443
  ;// ./lib/helpers/sanitizeText/index.js
2392
2444
 
2393
2445
 
2446
+ ;// ./lib/helpers/shuffleArray/shuffleArray.js
2447
+ function shuffleArray(array) {
2448
+ const arr = [...array];
2449
+ for (let i = arr.length - 1; i >= 0; i--) { // Changed `i > 0` to `i >= 0`
2450
+ const j = Math.floor(Math.random() * (i + 1));
2451
+ [arr[i], arr[j]] = [arr[j], arr[i]];
2452
+ }
2453
+ return arr;
2454
+ }
2455
+
2456
+ ;// ./lib/helpers/shuffleArray/index.js
2457
+
2458
+
2394
2459
  ;// ./lib/helpers/stringFormatter/stringFormatter.js
2395
2460
  function stringFormatter(str, delimiter = '_') {
2396
2461
  if (str === null || typeof str === 'undefined' || typeof str.toString === 'undefined') {
@@ -2653,6 +2718,9 @@ function tenantPlugin(schema, options) {
2653
2718
 
2654
2719
 
2655
2720
 
2721
+
2722
+
2723
+
2656
2724
 
2657
2725
 
2658
2726
 
@@ -3185,67 +3253,6 @@ function metadata_mergeValues(existingValue, newValue) {
3185
3253
 
3186
3254
 
3187
3255
 
3188
- ;// ./lib/models/qMeta/qMeta.js
3189
-
3190
-
3191
- const updateAllowedProps = [
3192
- 'attributes',
3193
- 'ref'
3194
- ]
3195
-
3196
- class QMeta {
3197
- constructor(options = {}) {
3198
- options = options || {}
3199
- this.attributes = KeyValueObject.initOnlyValidFromArray(options.attributes)
3200
- this.ref = options.ref || {}
3201
- }
3202
-
3203
- static get _classname() {
3204
- return 'QMeta'
3205
- }
3206
- static get _superclass() {
3207
- return 'QMeta'
3208
- }
3209
-
3210
- // Class methods
3211
- static init(options = {}) {
3212
- if (options instanceof QMeta) {
3213
- return options
3214
- }
3215
- return new QMeta(options)
3216
- }
3217
-
3218
- // instance methods
3219
- addAttribute(obj) {
3220
- const kvObject = KeyValueObject.init(obj)
3221
- if (!kvObject) {
3222
- throw new Error('invalid meta attribute')
3223
- }
3224
- this.attributes.push(kvObject)
3225
- return this
3226
- }
3227
-
3228
- update(obj) {
3229
- Object.keys(obj).forEach((key) => {
3230
- if (updateAllowedProps.includes(key)) {
3231
- if (key === 'attributes') {
3232
- this[key] = KeyValueObject.initOnlyValidFromArray(obj[key])
3233
- } else {
3234
- this[key] = obj[key]
3235
- }
3236
- }
3237
- })
3238
- return this
3239
- }
3240
- }
3241
-
3242
-
3243
-
3244
- ;// ./lib/models/qMeta/index.js
3245
-
3246
-
3247
-
3248
-
3249
3256
  ;// ./lib/models/trackedEntity/trackedEntity.js
3250
3257
 
3251
3258
 
@@ -3388,6 +3395,114 @@ class TrackedEntity {
3388
3395
 
3389
3396
  // Explicit named export (optional)
3390
3397
 
3398
+ ;// ./lib/models/pushEnvelope/pushEnvelope.js
3399
+
3400
+
3401
+
3402
+
3403
+
3404
+ class PushEnvelope extends TrackedEntity {
3405
+ constructor(options) {
3406
+ options = options || {}
3407
+ super(options)
3408
+
3409
+ this.id = options.id
3410
+ this.body = options.body
3411
+ this.data = options.data
3412
+ this.dirty = options.dirty
3413
+ this.metadata = Metadata.initOnlyValidFromArray(options.metadata)
3414
+ this.remarks = KeyValueObject.initOnlyValidFromArray(options.remarks)
3415
+ this.threadID = options.threadID
3416
+ this.title = options.title
3417
+ }
3418
+ static get _classname() {
3419
+ return 'PushEnvelope'
3420
+ }
3421
+ static get _superclass() {
3422
+ return 'PushEnvelope'
3423
+ }
3424
+ static init(options = {}) {
3425
+ return init(this, options)
3426
+ }
3427
+
3428
+ get _classname() {
3429
+ return 'PushEnvelope'
3430
+ }
3431
+
3432
+ get _superclass() {
3433
+ return 'PushEnvelope'
3434
+ }
3435
+
3436
+ get isValid() {
3437
+ return super.isValid && this.data
3438
+ }
3439
+
3440
+ }
3441
+
3442
+ ;// ./lib/models/pushEnvelope/index.js
3443
+
3444
+
3445
+ ;// ./lib/models/qMeta/qMeta.js
3446
+
3447
+
3448
+ const updateAllowedProps = [
3449
+ 'attributes',
3450
+ 'ref'
3451
+ ]
3452
+
3453
+ class QMeta {
3454
+ constructor(options = {}) {
3455
+ options = options || {}
3456
+ this.attributes = KeyValueObject.initOnlyValidFromArray(options.attributes)
3457
+ this.ref = options.ref || {}
3458
+ }
3459
+
3460
+ static get _classname() {
3461
+ return 'QMeta'
3462
+ }
3463
+ static get _superclass() {
3464
+ return 'QMeta'
3465
+ }
3466
+
3467
+ // Class methods
3468
+ static init(options = {}) {
3469
+ if (options instanceof QMeta) {
3470
+ return options
3471
+ }
3472
+ return new QMeta(options)
3473
+ }
3474
+
3475
+ // instance methods
3476
+ addAttribute(obj) {
3477
+ const kvObject = KeyValueObject.init(obj)
3478
+ if (!kvObject) {
3479
+ throw new Error('invalid meta attribute')
3480
+ }
3481
+ this.attributes.push(kvObject)
3482
+ return this
3483
+ }
3484
+
3485
+ update(obj) {
3486
+ Object.keys(obj).forEach((key) => {
3487
+ if (updateAllowedProps.includes(key)) {
3488
+ if (key === 'attributes') {
3489
+ this[key] = KeyValueObject.initOnlyValidFromArray(obj[key])
3490
+ } else {
3491
+ this[key] = obj[key]
3492
+ }
3493
+ }
3494
+ })
3495
+ return this
3496
+ }
3497
+ }
3498
+
3499
+
3500
+
3501
+ ;// ./lib/models/qMeta/index.js
3502
+
3503
+
3504
+
3505
+
3391
3506
  ;// ./lib/models/tenantAwareEntity/tenantAwareEntity.js
3392
3507
 
3393
3508
 
@@ -3527,6 +3642,7 @@ function _makeSetCode(fieldName, options) {
3527
3642
 
3528
3643
 
3529
3644
 
3645
+
3530
3646
  ;// ./lib/index.js
3531
3647
 
3532
3648
 
@@ -3534,4 +3650,4 @@ function _makeSetCode(fieldName, options) {
3534
3650
  ;// ./index.js
3535
3651
 
3536
3652
 
3537
- export { ApiResponse, AwsStsS3Client, KeyValueObject, Metadata, QMeta, Repo, Service, TemplateCompiler, TenantAwareEntity, TrackedEntity, UniqueKeyGenerator, authorize, changeCreatorOwner, concatStringByArray, convertString, escapeRegex, expressHelper, extractEmails, formatDate, generalPost, getValidation, getValueByKeys_getValueByKeys as getValueByKeys, init, initFromArray, initOnlyValidFromArray, makeApiResponse, makeService, mergeArraysByKey, objectHelper, pReduce, padZeros, replacePlaceholders, sanitizeText, stringFormatter, stringHelper, tenantPlugin, trackingPlugin };
3653
+ export { ApiResponse, AwsStsS3Client, KeyValueObject, Metadata, PushEnvelope, QMeta, Repo, Service, TemplateCompiler, TenantAwareEntity, TrackedEntity, UniqueKeyGenerator, authorize, calculateAge, changeCreatorOwner, concatStringByArray, convertString, escapeRegex, expressHelper, extractEmails, formatDate, generalPost, getValidation, getValueByKeys_getValueByKeys as getValueByKeys, groupArrayByKey, init, initFromArray, initOnlyValidFromArray, makeApiResponse, makeService, mergeArraysByKey, objectHelper, pReduce, padZeros, replacePlaceholders, sanitizeText, shuffleArray, stringFormatter, stringHelper, tenantPlugin, trackingPlugin };
@@ -52,6 +52,7 @@ __webpack_require__.d(__webpack_exports__, {
52
52
  AwsStsS3Client: () => (/* reexport */ AwsStsS3Client),
53
53
  KeyValueObject: () => (/* reexport */ KeyValueObject),
54
54
  Metadata: () => (/* reexport */ Metadata),
55
+ PushEnvelope: () => (/* reexport */ PushEnvelope),
55
56
  QMeta: () => (/* reexport */ QMeta),
56
57
  Repo: () => (/* reexport */ Repo),
57
58
  Service: () => (/* reexport */ Service),
@@ -60,6 +61,7 @@ __webpack_require__.d(__webpack_exports__, {
60
61
  TrackedEntity: () => (/* reexport */ TrackedEntity),
61
62
  UniqueKeyGenerator: () => (/* reexport */ UniqueKeyGenerator),
62
63
  authorize: () => (/* reexport */ authorize),
64
+ calculateAge: () => (/* reexport */ calculateAge),
63
65
  changeCreatorOwner: () => (/* reexport */ changeCreatorOwner),
64
66
  concatStringByArray: () => (/* reexport */ concatStringByArray),
65
67
  convertString: () => (/* reexport */ convertString),
@@ -70,6 +72,7 @@ __webpack_require__.d(__webpack_exports__, {
70
72
  generalPost: () => (/* reexport */ generalPost),
71
73
  getValidation: () => (/* reexport */ getValidation),
72
74
  getValueByKeys: () => (/* reexport */ getValueByKeys_getValueByKeys),
75
+ groupArrayByKey: () => (/* reexport */ groupArrayByKey),
73
76
  init: () => (/* reexport */ init),
74
77
  initFromArray: () => (/* reexport */ initFromArray),
75
78
  initOnlyValidFromArray: () => (/* reexport */ initOnlyValidFromArray),
@@ -81,6 +84,7 @@ __webpack_require__.d(__webpack_exports__, {
81
84
  padZeros: () => (/* reexport */ padZeros),
82
85
  replacePlaceholders: () => (/* reexport */ replacePlaceholders),
83
86
  sanitizeText: () => (/* reexport */ sanitizeText),
87
+ shuffleArray: () => (/* reexport */ shuffleArray),
84
88
  stringFormatter: () => (/* reexport */ stringFormatter),
85
89
  stringHelper: () => (/* reexport */ stringHelper),
86
90
  tenantPlugin: () => (/* reexport */ tenantPlugin),
@@ -135,6 +139,36 @@ function authorize({ allowCoordinator, allowOwner, query = {}, required, user })
135
139
  ;// ./lib/helpers/authorize/index.js
136
140
 
137
141
 
142
+ ;// ./lib/helpers/calculateAge/calculateAge.js
143
+ function calculateAge(timestamp, reference) {
144
+ const birthDate = new Date(timestamp)
145
+ const refDate = reference ? new Date(reference) : new Date()
146
+ // Validate inputs
147
+ if (isNaN(birthDate.getTime())) {
148
+ return null
149
+ }
150
+ if (isNaN(refDate.getTime())) {
151
+ return null
152
+ }
153
+ if (birthDate > refDate) {
154
+ return null
155
+ }
156
+
157
+ // Calculate raw difference
158
+ let age = refDate.getFullYear() - birthDate.getFullYear();
159
+ const monthDiff = refDate.getMonth() - birthDate.getMonth();
160
+
161
+ // Adjust if birthday hasn't occurred yet this year
162
+ if (monthDiff < 0 || (monthDiff === 0 && refDate.getDate() < birthDate.getDate())) {
163
+ age--
164
+ }
165
+
166
+ return age
167
+ }
168
+
169
+ ;// ./lib/helpers/calculateAge/index.js
170
+
171
+
138
172
  ;// ./lib/helpers/changeCreatorOwner/changeCreatorOwner.js
139
173
  function changeCreatorOwner(that, { source, target }) {
140
174
  if (that.meta) {
@@ -1542,7 +1576,7 @@ function customHandler({ responseHelper, handler, ignoreError = false }) {
1542
1576
  await handler({ req, res })
1543
1577
  await next()
1544
1578
  } catch (err) {
1545
- if (ignoreError) {
1579
+ if (ignoreError || !responseHelper) {
1546
1580
  await next()
1547
1581
  } else {
1548
1582
  res.status(400).json(responseHelper.standardizeResponse({ err, message: err.message || err }))
@@ -2117,11 +2151,16 @@ class Service {
2117
2151
  return 'Service'
2118
2152
  }
2119
2153
 
2120
- deleteOne({ id }) {
2121
- return this.repo.deleteOne({ id })
2122
- .catch(() => {
2123
- throw new Error(`Not found for query: ${id}`)
2124
- })
2154
+ async deleteOne({ id }) {
2155
+ const result = await this.repo.deleteOne({ id })
2156
+ return makeApiResponse({
2157
+ repo: this.repo,
2158
+ result
2159
+ })
2160
+ // return this.repo.delete({ id })
2161
+ // .catch(() => {
2162
+ // throw new Error(`Not found for query: ${id}`)
2163
+ // })
2125
2164
  }
2126
2165
 
2127
2166
  async findAll({ query = {}, systemLog } = {}) {
@@ -2257,6 +2296,23 @@ function _makeService(resource, resourceInfo, UniqueKeyGenerator, GeneralModel)
2257
2296
 
2258
2297
 
2259
2298
 
2299
+ ;// ./lib/helpers/groupArrayByKey/groupArrayByKey.js
2300
+ function groupArrayByKey(arr, key) {
2301
+ if (!key || typeof key !== 'string') {
2302
+ return {}
2303
+ }
2304
+ return arr.reduce((acc, curr) => {
2305
+ if (!acc[curr[key]]) {
2306
+ acc[curr[key]] = 0
2307
+ }
2308
+ acc[curr[key]]++
2309
+ return acc
2310
+ }, {})
2311
+ }
2312
+
2313
+ ;// ./lib/helpers/groupArrayByKey/index.js
2314
+
2315
+
2260
2316
  ;// ./lib/helpers/init/init.js
2261
2317
  function init(_class, options) {
2262
2318
  if (options instanceof _class) {
@@ -2479,6 +2535,19 @@ function sanitizeText(input, options = {}) {
2479
2535
  ;// ./lib/helpers/sanitizeText/index.js
2480
2536
 
2481
2537
 
2538
+ ;// ./lib/helpers/shuffleArray/shuffleArray.js
2539
+ function shuffleArray(array) {
2540
+ const arr = [...array];
2541
+ for (let i = arr.length - 1; i >= 0; i--) { // Changed `i > 0` to `i >= 0`
2542
+ const j = Math.floor(Math.random() * (i + 1));
2543
+ [arr[i], arr[j]] = [arr[j], arr[i]];
2544
+ }
2545
+ return arr;
2546
+ }
2547
+
2548
+ ;// ./lib/helpers/shuffleArray/index.js
2549
+
2550
+
2482
2551
  ;// ./lib/helpers/stringFormatter/stringFormatter.js
2483
2552
  function stringFormatter(str, delimiter = '_') {
2484
2553
  if (str === null || typeof str === 'undefined' || typeof str.toString === 'undefined') {
@@ -2741,6 +2810,9 @@ function tenantPlugin(schema, options) {
2741
2810
 
2742
2811
 
2743
2812
 
2813
+
2814
+
2815
+
2744
2816
 
2745
2817
 
2746
2818
 
@@ -3273,67 +3345,6 @@ function metadata_mergeValues(existingValue, newValue) {
3273
3345
 
3274
3346
 
3275
3347
 
3276
- ;// ./lib/models/qMeta/qMeta.js
3277
-
3278
-
3279
- const updateAllowedProps = [
3280
- 'attributes',
3281
- 'ref'
3282
- ]
3283
-
3284
- class QMeta {
3285
- constructor(options = {}) {
3286
- options = options || {}
3287
- this.attributes = KeyValueObject.initOnlyValidFromArray(options.attributes)
3288
- this.ref = options.ref || {}
3289
- }
3290
-
3291
- static get _classname() {
3292
- return 'QMeta'
3293
- }
3294
- static get _superclass() {
3295
- return 'QMeta'
3296
- }
3297
-
3298
- // Class methods
3299
- static init(options = {}) {
3300
- if (options instanceof QMeta) {
3301
- return options
3302
- }
3303
- return new QMeta(options)
3304
- }
3305
-
3306
- // instance methods
3307
- addAttribute(obj) {
3308
- const kvObject = KeyValueObject.init(obj)
3309
- if (!kvObject) {
3310
- throw new Error('invalid meta attribute')
3311
- }
3312
- this.attributes.push(kvObject)
3313
- return this
3314
- }
3315
-
3316
- update(obj) {
3317
- Object.keys(obj).forEach((key) => {
3318
- if (updateAllowedProps.includes(key)) {
3319
- if (key === 'attributes') {
3320
- this[key] = KeyValueObject.initOnlyValidFromArray(obj[key])
3321
- } else {
3322
- this[key] = obj[key]
3323
- }
3324
- }
3325
- })
3326
- return this
3327
- }
3328
- }
3329
-
3330
-
3331
-
3332
- ;// ./lib/models/qMeta/index.js
3333
-
3334
-
3335
-
3336
-
3337
3348
  ;// ./lib/models/trackedEntity/trackedEntity.js
3338
3349
 
3339
3350
 
@@ -3476,6 +3487,114 @@ class TrackedEntity {
3476
3487
 
3477
3488
  // Explicit named export (optional)
3478
3489
 
3490
+ ;// ./lib/models/pushEnvelope/pushEnvelope.js
3491
+
3492
+
3493
+
3494
+
3495
+
3496
+ class PushEnvelope extends TrackedEntity {
3497
+ constructor(options) {
3498
+ options = options || {}
3499
+ super(options)
3500
+
3501
+ this.id = options.id
3502
+ this.body = options.body
3503
+ this.data = options.data
3504
+ this.dirty = options.dirty
3505
+ this.metadata = Metadata.initOnlyValidFromArray(options.metadata)
3506
+ this.remarks = KeyValueObject.initOnlyValidFromArray(options.remarks)
3507
+ this.threadID = options.threadID
3508
+ this.title = options.title
3509
+ }
3510
+ static get _classname() {
3511
+ return 'PushEnvelope'
3512
+ }
3513
+ static get _superclass() {
3514
+ return 'PushEnvelope'
3515
+ }
3516
+ static init(options = {}) {
3517
+ return init(this, options)
3518
+ }
3519
+
3520
+ get _classname() {
3521
+ return 'PushEnvelope'
3522
+ }
3523
+
3524
+ get _superclass() {
3525
+ return 'PushEnvelope'
3526
+ }
3527
+
3528
+ get isValid() {
3529
+ return super.isValid && this.data
3530
+ }
3531
+
3532
+ }
3533
+
3534
+ ;// ./lib/models/pushEnvelope/index.js
3535
+
3536
+
3537
+ ;// ./lib/models/qMeta/qMeta.js
3538
+
3539
+
3540
+ const updateAllowedProps = [
3541
+ 'attributes',
3542
+ 'ref'
3543
+ ]
3544
+
3545
+ class QMeta {
3546
+ constructor(options = {}) {
3547
+ options = options || {}
3548
+ this.attributes = KeyValueObject.initOnlyValidFromArray(options.attributes)
3549
+ this.ref = options.ref || {}
3550
+ }
3551
+
3552
+ static get _classname() {
3553
+ return 'QMeta'
3554
+ }
3555
+ static get _superclass() {
3556
+ return 'QMeta'
3557
+ }
3558
+
3559
+ // Class methods
3560
+ static init(options = {}) {
3561
+ if (options instanceof QMeta) {
3562
+ return options
3563
+ }
3564
+ return new QMeta(options)
3565
+ }
3566
+
3567
+ // instance methods
3568
+ addAttribute(obj) {
3569
+ const kvObject = KeyValueObject.init(obj)
3570
+ if (!kvObject) {
3571
+ throw new Error('invalid meta attribute')
3572
+ }
3573
+ this.attributes.push(kvObject)
3574
+ return this
3575
+ }
3576
+
3577
+ update(obj) {
3578
+ Object.keys(obj).forEach((key) => {
3579
+ if (updateAllowedProps.includes(key)) {
3580
+ if (key === 'attributes') {
3581
+ this[key] = KeyValueObject.initOnlyValidFromArray(obj[key])
3582
+ } else {
3583
+ this[key] = obj[key]
3584
+ }
3585
+ }
3586
+ })
3587
+ return this
3588
+ }
3589
+ }
3590
+
3591
+
3592
+
3593
+ ;// ./lib/models/qMeta/index.js
3594
+
3595
+
3596
+
3597
+
3479
3598
  ;// ./lib/models/tenantAwareEntity/tenantAwareEntity.js
3480
3599
 
3481
3600
 
@@ -3615,6 +3734,7 @@ function _makeSetCode(fieldName, options) {
3615
3734
 
3616
3735
 
3617
3736
 
3737
+
3618
3738
  ;// ./lib/index.js
3619
3739
 
3620
3740
 
package/package.json CHANGED
@@ -1,7 +1,13 @@
1
1
  {
2
2
  "name": "@questwork/q-utilities",
3
- "version": "0.1.17",
3
+ "version": "0.1.19",
4
4
  "description": "Questwork QUtilities",
5
+ "author": {
6
+ "name": "Questwork Consulting Limited",
7
+ "email": "info@questwork.com",
8
+ "url": "https://questwork.com/"
9
+ },
10
+ "license": "MIT",
5
11
  "type": "module",
6
12
  "exports": {
7
13
  ".": {
@@ -10,12 +16,6 @@
10
16
  "default": "./dist/q-utilities.min.js"
11
17
  }
12
18
  },
13
- "author": {
14
- "name": "Questwork Consulting Limited",
15
- "email": "info@questwork.com",
16
- "url": "https://questwork.com/"
17
- },
18
- "license": "MIT",
19
19
  "devDependencies": {
20
20
  "@aws-sdk/client-s3": "^3.812.0",
21
21
  "@aws-sdk/client-sts": "^3.812.0",
@@ -44,6 +44,7 @@
44
44
  "build": "cross-env NODE_ENV=production minimize=false gulp",
45
45
  "build:wp": "cross-env NODE_ENV=production minimize=false gulp wp",
46
46
  "lint": "eslint .",
47
+ "test:helpers": "NODE_ENV=test mocha --exit 'lib/helpers/test.setup.js' 'lib/helpers/**/*.spec.js'",
47
48
  "test:models": "NODE_ENV=test mocha --exit 'lib/models/test.setup.js' 'lib/models/**/*.spec.js'"
48
49
  }
49
50
  }