@anddone/coretestautomation 1.0.1

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.
Files changed (72) hide show
  1. package/.github/workflows/npm-release.yml +102 -0
  2. package/dist/api/base.api.d.ts +32 -0
  3. package/dist/api/base.api.d.ts.map +1 -0
  4. package/dist/api/base.api.js +7 -0
  5. package/dist/api/base.api.js.map +1 -0
  6. package/dist/api/headers.d.ts +6 -0
  7. package/dist/api/headers.d.ts.map +1 -0
  8. package/dist/api/headers.js +23 -0
  9. package/dist/api/headers.js.map +1 -0
  10. package/dist/index.d.ts +13 -0
  11. package/dist/index.d.ts.map +1 -0
  12. package/dist/index.js +29 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/pages/basepage.d.ts +6 -0
  15. package/dist/pages/basepage.d.ts.map +1 -0
  16. package/dist/pages/basepage.js +10 -0
  17. package/dist/pages/basepage.js.map +1 -0
  18. package/dist/testData/api.data.json +6 -0
  19. package/dist/utils/apiUtils.d.ts +123 -0
  20. package/dist/utils/apiUtils.d.ts.map +1 -0
  21. package/dist/utils/apiUtils.js +264 -0
  22. package/dist/utils/apiUtils.js.map +1 -0
  23. package/dist/utils/assertionUtils.d.ts +223 -0
  24. package/dist/utils/assertionUtils.d.ts.map +1 -0
  25. package/dist/utils/assertionUtils.js +400 -0
  26. package/dist/utils/assertionUtils.js.map +1 -0
  27. package/dist/utils/commonUtils.d.ts +590 -0
  28. package/dist/utils/commonUtils.d.ts.map +1 -0
  29. package/dist/utils/commonUtils.js +1292 -0
  30. package/dist/utils/commonUtils.js.map +1 -0
  31. package/dist/utils/fakerStaticData.d.ts +16 -0
  32. package/dist/utils/fakerStaticData.d.ts.map +1 -0
  33. package/dist/utils/fakerStaticData.js +88 -0
  34. package/dist/utils/fakerStaticData.js.map +1 -0
  35. package/dist/utils/fileCommonUtils.d.ts +22 -0
  36. package/dist/utils/fileCommonUtils.d.ts.map +1 -0
  37. package/dist/utils/fileCommonUtils.js +243 -0
  38. package/dist/utils/fileCommonUtils.js.map +1 -0
  39. package/dist/utils/generationUtils.d.ts +424 -0
  40. package/dist/utils/generationUtils.d.ts.map +1 -0
  41. package/dist/utils/generationUtils.js +869 -0
  42. package/dist/utils/generationUtils.js.map +1 -0
  43. package/dist/utils/pageUtils.d.ts +90 -0
  44. package/dist/utils/pageUtils.d.ts.map +1 -0
  45. package/dist/utils/pageUtils.js +214 -0
  46. package/dist/utils/pageUtils.js.map +1 -0
  47. package/dist/utils/tableUtils.d.ts +304 -0
  48. package/dist/utils/tableUtils.d.ts.map +1 -0
  49. package/dist/utils/tableUtils.js +555 -0
  50. package/dist/utils/tableUtils.js.map +1 -0
  51. package/dist/utils/validationUtils.d.ts +80 -0
  52. package/dist/utils/validationUtils.d.ts.map +1 -0
  53. package/dist/utils/validationUtils.js +172 -0
  54. package/dist/utils/validationUtils.js.map +1 -0
  55. package/package.json +23 -0
  56. package/playwright.config.ts +79 -0
  57. package/src/api/base.api.ts +39 -0
  58. package/src/api/headers.ts +17 -0
  59. package/src/index.ts +12 -0
  60. package/src/pages/basepage.ts +11 -0
  61. package/src/testData/api.data.json +6 -0
  62. package/src/types/pdf-parse.d.ts +6 -0
  63. package/src/utils/apiUtils.ts +307 -0
  64. package/src/utils/assertionUtils.ts +455 -0
  65. package/src/utils/commonUtils.ts +1544 -0
  66. package/src/utils/fakerStaticData.ts +91 -0
  67. package/src/utils/fileCommonUtils.ts +239 -0
  68. package/src/utils/generationUtils.ts +929 -0
  69. package/src/utils/pageUtils.ts +224 -0
  70. package/src/utils/tableUtils.ts +715 -0
  71. package/src/utils/validationUtils.ts +179 -0
  72. package/tsconfig.json +19 -0
@@ -0,0 +1,929 @@
1
+ import { addDays, addMonths, addYears, differenceInDays, differenceInMonths, differenceInYears, format, isValid, parse } from "date-fns";
2
+ import { formatInTimeZone } from "date-fns-tz";
3
+
4
+ import {
5
+ COUNTRY_CODES, EMAIL_DOMAINS, FIRST_NAMES, INDIA_LOCATIONS,
6
+ LAST_NAMES, LOREM_WORDS, STREET_NAMES, USA_LOCATIONS
7
+ } from "./fakerStaticData";
8
+
9
+ export class GenerationUtils {
10
+ /**
11
+ * Returns a random integer between min and max (inclusive).
12
+ *
13
+ * @param min Minimum number (inclusive)
14
+ * @param max Maximum number (inclusive)
15
+ * @returns Random number between min and max
16
+ *
17
+ * Example:
18
+ * randomNumber(1, 10) → 7
19
+ */
20
+ static randomNumber(min: number, max: number): number {
21
+ try {
22
+ if (min > max) {
23
+ return 0;
24
+ }
25
+
26
+ return Math.floor(Math.random() * (max - min + 1)) + min;
27
+ } catch {
28
+ return 0;
29
+ }
30
+ }
31
+
32
+ /**
33
+ * Returns a random floating-point number between min and max.
34
+ *
35
+ * @param min Minimum number
36
+ * @param max Maximum number
37
+ * @param decimals Number of decimal places (default: 2)
38
+ * @returns Random float between min and max
39
+ *
40
+ * Example:
41
+ * randomFloat(1, 5, 2) → 3.47
42
+ */
43
+ static randomFloat(min: number, max: number, decimals: number = 2): number {
44
+ try {
45
+ if (min > max) {
46
+ return 0;
47
+ }
48
+
49
+ const value = Math.random() * (max - min) + min;
50
+ return Number(value.toFixed(decimals));
51
+ } catch {
52
+ return 0;
53
+ }
54
+ }
55
+
56
+ /**
57
+ * Returns a random boolean value.
58
+ *
59
+ * @returns true or false
60
+ *
61
+ * Example:
62
+ * randomBoolean() → true
63
+ */
64
+ static randomBoolean(): boolean {
65
+ try {
66
+ return Math.random() < 0.5;
67
+ } catch {
68
+ return false;
69
+ }
70
+ }
71
+
72
+ /**
73
+ * Returns a random element from an array.
74
+ *
75
+ * @param values Array of values
76
+ * @returns Random element or null if array is empty
77
+ *
78
+ * Example:
79
+ * randomFromArray(["A", "B", "C"]) → "B"
80
+ */
81
+ static randomFromArray<T>(values: T[]): T | null {
82
+ try {
83
+ if (!values || values.length === 0) return null;
84
+
85
+ const index = Math.floor(Math.random() * values.length);
86
+ return values[index];
87
+ } catch {
88
+ return null;
89
+ }
90
+ }
91
+
92
+ /**
93
+ * Returns a random valid index for an array.
94
+ *
95
+ * @param max Length of the array
96
+ * @returns Random index between 0 and max - 1
97
+ *
98
+ * Example:
99
+ * randomIndex(5) → 3
100
+ */
101
+ static randomIndex(max: number): number {
102
+ try {
103
+ if (max <= 0) {
104
+ return 0;
105
+ }
106
+
107
+ return Math.floor(Math.random() * max);
108
+ } catch {
109
+ return 0;
110
+ }
111
+ }
112
+
113
+ /**
114
+ * Returns a random alphabetic string (A–Z, a–z).
115
+ *
116
+ * @param length Length of the string
117
+ * @returns Random alphabetic string
118
+ *
119
+ * Example:
120
+ * randomAlphaString(5) → "aZxQe"
121
+ */
122
+ static randomAlphaString(length: number): string {
123
+ try {
124
+ const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
125
+ return this.generateRandomFromCharset(chars, length);
126
+ } catch {
127
+ return "";
128
+ }
129
+ }
130
+
131
+ /**
132
+ * Returns a random numeric string (0–9).
133
+ *
134
+ * @param length Length of the string
135
+ * @returns Random numeric string
136
+ *
137
+ * Example:
138
+ * randomNumericString(4) → "4829"
139
+ */
140
+ static randomNumericString(length: number): string {
141
+ try {
142
+ const chars = "0123456789";
143
+ return this.generateRandomFromCharset(chars, length);
144
+ } catch {
145
+ return "";
146
+ }
147
+ }
148
+
149
+ /**
150
+ * Returns a random alphanumeric string (letters + numbers).
151
+ *
152
+ * @param length Length of the string
153
+ * @returns Random alphanumeric string
154
+ *
155
+ * Example:
156
+ * randomAlphaNumericString(8) → "A9bX2Lq7"
157
+ */
158
+ static randomAlphaNumericString(length: number): string {
159
+ try {
160
+ const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
161
+ return this.generateRandomFromCharset(chars, length);
162
+ } catch {
163
+ return "";
164
+ }
165
+ }
166
+
167
+ /**
168
+ * Internal helper to generate random string from a given character set.
169
+ *
170
+ * @param chars Allowed characters
171
+ * @param length Length of string
172
+ * @returns Random string
173
+ */
174
+ private static generateRandomFromCharset(chars: string, length: number): string {
175
+ try {
176
+ if (length <= 0) return "";
177
+
178
+ let result = "";
179
+ for (let i = 0; i < length; i++) {
180
+ result += chars.charAt(Math.floor(Math.random() * chars.length));
181
+ }
182
+ return result;
183
+ } catch {
184
+ return "";
185
+ }
186
+ }
187
+
188
+ /**
189
+ * Returns a random first name.
190
+ *
191
+ * @returns Random first name
192
+ *
193
+ * Example:
194
+ * randomFirstName() → "Rahul"
195
+ */
196
+ static randomFirstName(): string {
197
+ try {
198
+ return FIRST_NAMES[
199
+ Math.floor(Math.random() * FIRST_NAMES.length)
200
+ ];
201
+ } catch {
202
+ return "";
203
+ }
204
+ }
205
+
206
+ /**
207
+ * Returns a random last name.
208
+ *
209
+ * @returns Random last name
210
+ *
211
+ * Example:
212
+ * randomLastName() → "Sharma"
213
+ */
214
+ static randomLastName(): string {
215
+ try {
216
+ return LAST_NAMES[
217
+ Math.floor(Math.random() * LAST_NAMES.length)
218
+ ];
219
+ } catch {
220
+ return "";
221
+ }
222
+ }
223
+
224
+ /**
225
+ * Returns a random full name (first name + last name).
226
+ *
227
+ * @returns Random full name
228
+ *
229
+ * Example:
230
+ * randomFullName() → "Rahul Sharma"
231
+ */
232
+ static randomFullName(): string {
233
+ try {
234
+ return `${this.randomFirstName()} ${this.randomLastName()}`;
235
+ }
236
+ catch {
237
+ return "";
238
+ }
239
+ }
240
+
241
+ /**
242
+ * Returns a random username generated from name and number.
243
+ *
244
+ * @returns Random username
245
+ *
246
+ * Example:
247
+ * randomUsername() → "rahul.sharma482"
248
+ */
249
+ static randomUsername(): string {
250
+ try {
251
+ const first = this.randomFirstName().toLowerCase();
252
+ const last = this.randomLastName().toLowerCase();
253
+ const number = Math.floor(Math.random() * 1000);
254
+
255
+ return `${first}.${last}${number}`;
256
+ } catch {
257
+ return "";
258
+ }
259
+ }
260
+
261
+ /**
262
+ * Returns a random email address.
263
+ *
264
+ * @returns Random email string
265
+ *
266
+ * Example:
267
+ * randomEmail() → "rahul.sharma482@gmail.com"
268
+ */
269
+ static randomEmail(): string {
270
+ try {
271
+ const first = this.randomFirstName().toLowerCase();
272
+ const last = this.randomLastName().toLowerCase();
273
+ const number = Math.floor(Math.random() * 1000);
274
+ const domain = EMAIL_DOMAINS[
275
+ Math.floor(Math.random() * EMAIL_DOMAINS.length)
276
+ ];
277
+
278
+ return `${first}.${last}${number}@${domain}`;
279
+ } catch {
280
+ return "";
281
+ }
282
+ }
283
+
284
+ /**
285
+ * Returns a random country calling code.
286
+ *
287
+ * @returns Country code string (e.g. "+91")
288
+ *
289
+ * Example:
290
+ * randomCountryCode() → "+91"
291
+ */
292
+ static randomCountryCode(): string {
293
+ try {
294
+ return COUNTRY_CODES[
295
+ Math.floor(Math.random() * COUNTRY_CODES.length)
296
+ ];
297
+ } catch {
298
+ return "";
299
+ }
300
+ }
301
+
302
+ /**
303
+ * Returns a random phone number with country code.
304
+ *
305
+ * @returns Phone number string
306
+ *
307
+ * Example:
308
+ * randomPhoneNumber() → "+91 9876543210"
309
+ */
310
+ static randomPhoneNumber(): string {
311
+ try {
312
+ const countryCode = this.randomCountryCode();
313
+
314
+ // Generate a 10-digit phone number
315
+ let number = "";
316
+ for (let i = 0; i < 10; i++) {
317
+ number += Math.floor(Math.random() * 10);
318
+ }
319
+
320
+ return `${countryCode} ${number}`;
321
+ } catch {
322
+ return "";
323
+ }
324
+ }
325
+
326
+ /**
327
+ * Returns a random US phone number.
328
+ *
329
+ * Format: +1 XXX-XXX-XXXX
330
+ *
331
+ * @returns US phone number string
332
+ *
333
+ * Example:
334
+ * getRandomUSPhoneNumber() → "+1 415-782-3490"
335
+ */
336
+ static getRandomUSPhoneNumber(): string {
337
+ try {
338
+ const countryCode = "+1";
339
+
340
+ // Area code (2–9 followed by 2 digits)
341
+ const areaCode =
342
+ Math.floor(Math.random() * 8 + 2).toString() +
343
+ Math.floor(Math.random() * 10) +
344
+ Math.floor(Math.random() * 10);
345
+
346
+ // Exchange code (2–9 followed by 2 digits)
347
+ const exchangeCode =
348
+ Math.floor(Math.random() * 8 + 2).toString() +
349
+ Math.floor(Math.random() * 10) +
350
+ Math.floor(Math.random() * 10);
351
+
352
+ // Line number (4 digits)
353
+ const lineNumber =
354
+ Math.floor(1000 + Math.random() * 9000);
355
+
356
+ return `${countryCode} ${areaCode}-${exchangeCode}-${lineNumber}`;
357
+ } catch {
358
+ return "";
359
+ }
360
+ }
361
+
362
+ /**
363
+ * Generates a random user object containing basic identity and contact details.
364
+ *
365
+ * @returns Generated fields include:
366
+ * - First name
367
+ * - Last name
368
+ * - Full name (first + last)
369
+ * - Username (lowercased name with numeric suffix)
370
+ * - Email address (using common email domains)
371
+ *
372
+ * - Generic phone number (with random country code)
373
+ * - US-specific phone number
374
+ */
375
+ static generateUserObject(): { firstName: string; lastName: string; fullName: string; username: string; email: string; phoneNo: string; usPhone: string; } {
376
+ try {
377
+ const firstName = this.randomFirstName();
378
+ const lastName = this.randomLastName();
379
+
380
+ const fullName = firstName + " " + lastName;
381
+ const number = Math.floor(Math.random() * 1000);
382
+ const username = `${firstName.toLowerCase()}.${lastName.toLowerCase()}${number}`;
383
+ const domain = EMAIL_DOMAINS[Math.floor(Math.random() * EMAIL_DOMAINS.length)];
384
+
385
+ const email = `${firstName}.${lastName}${number}@${domain}`;
386
+ const phoneNo = this.randomPhoneNumber();
387
+
388
+ const usPhone = this.getRandomUSPhoneNumber();
389
+ return {
390
+ firstName,
391
+ lastName,
392
+ fullName,
393
+ username,
394
+ email,
395
+ phoneNo,
396
+ usPhone,
397
+ }
398
+ } catch {
399
+ return {
400
+ firstName: "",
401
+ lastName: "",
402
+ fullName: "",
403
+ username: "",
404
+ email: "",
405
+ phoneNo: "",
406
+ usPhone: "",
407
+ };
408
+ }
409
+ }
410
+
411
+ private static generateIndiaPincode(prefix: string): string {
412
+ try {
413
+ let pincode = prefix;
414
+ for (let i = 0; i < 5; i++) {
415
+ pincode += Math.floor(Math.random() * 10);
416
+ }
417
+ return pincode;
418
+ } catch {
419
+ return "";
420
+ }
421
+ }
422
+
423
+ /**
424
+ * Returns a random India location (country, state, city).
425
+ *
426
+ * @returns Object containing country, state, and city
427
+ *
428
+ * Example:
429
+ * getRandomIndiaLocation()
430
+ * → { country: "India", state: "Karnataka", city: "Bengaluru", pincode: "560102" }
431
+ */
432
+ static getRandomIndiaLocation(): { country: string; state: string; city: string; pincode: string; } {
433
+ try {
434
+ const stateObj = INDIA_LOCATIONS[Math.floor(Math.random() * INDIA_LOCATIONS.length)];
435
+
436
+ const city = stateObj.cities[Math.floor(Math.random() * stateObj.cities.length)];
437
+ const pincode = this.generateIndiaPincode(stateObj.pincodePrefix);
438
+
439
+ return {
440
+ country: "India",
441
+ state: stateObj.state,
442
+ city,
443
+ pincode
444
+ };
445
+ } catch {
446
+ return {
447
+ country: "",
448
+ state: "",
449
+ city: "",
450
+ pincode: ""
451
+ };
452
+ }
453
+ }
454
+
455
+ private static generateUSZipCode(): string {
456
+ try {
457
+ let zip = "";
458
+ for (let i = 0; i < 5; i++) {
459
+ zip += Math.floor(Math.random() * 10);
460
+ }
461
+ return zip;
462
+ } catch {
463
+ return "";
464
+ }
465
+ }
466
+
467
+
468
+ /**
469
+ * Returns a random USA location (country, state, city).
470
+ *
471
+ * @returns Object containing country, state, and city
472
+ *
473
+ * Example:
474
+ * getRandomUSALocation()
475
+ * → { country: "United States", state: "California", city: "San Diego" }
476
+ */
477
+ static getRandomUSALocation(): { country: string; state: string; city: string; zipCode: string; } {
478
+ try {
479
+ const stateObj = USA_LOCATIONS[Math.floor(Math.random() * USA_LOCATIONS.length)];
480
+
481
+ const city = stateObj.cities[Math.floor(Math.random() * stateObj.cities.length)];
482
+
483
+ return {
484
+ country: "United States",
485
+ state: stateObj.state,
486
+ city,
487
+ zipCode: this.generateUSZipCode()
488
+ };
489
+ } catch {
490
+ return {
491
+ country: "",
492
+ state: "",
493
+ city: "",
494
+ zipCode: ""
495
+ };
496
+ }
497
+ }
498
+
499
+ /**
500
+ * Returns a random address line.
501
+ *
502
+ * @returns Random address line
503
+ *
504
+ * Example:
505
+ * randomAddressLine() → "Flat 302, MG Road"
506
+ */
507
+ static randomAddressLine(): string {
508
+ try {
509
+ const buildingNumber = Math.floor(Math.random() * 900) + 100;
510
+ const street =
511
+ STREET_NAMES[Math.floor(Math.random() * STREET_NAMES.length)];
512
+
513
+ return `Flat ${buildingNumber}, ${street}`;
514
+ } catch {
515
+ return "";
516
+ }
517
+ }
518
+
519
+ /**
520
+ * Returns a random UUID.
521
+ *
522
+ * @returns Random UUID string
523
+ *
524
+ * Example:
525
+ * randomUUID() → "f47ac10b-58cc-4372-a567-0e02b2c3d479"
526
+ */
527
+ static randomUUID(): string {
528
+ try {
529
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, char => {
530
+ const rand = Math.random() * 16 | 0;
531
+ const value = char === "x" ? rand : (rand & 0x3 | 0x8);
532
+ return value.toString(16);
533
+ });
534
+ } catch {
535
+ return "";
536
+ }
537
+ }
538
+
539
+ /**
540
+ * Returns a random lorem sentence.
541
+ *
542
+ * @param wordCount Optional number of words in the sentence
543
+ * @returns Random lorem sentence string
544
+ *
545
+ * Example:
546
+ * randomLoremSentence() → "Lorem ipsum dolor sit amet."
547
+ * randomLoremSentence(8) → "Lorem ipsum dolor sit amet consectetur elit."
548
+ */
549
+ static randomLoremSentence(wordCount: number = 8): string {
550
+ try {
551
+ if (wordCount <= 0) return "";
552
+
553
+ const words: string[] = [];
554
+
555
+ for (let i = 0; i < wordCount; i++) {
556
+ words.push(LOREM_WORDS[i % LOREM_WORDS.length]);
557
+ }
558
+
559
+ const sentence =
560
+ words.join(" ").charAt(0).toUpperCase() +
561
+ words.join(" ").slice(1) +
562
+ ".";
563
+
564
+ return sentence;
565
+ } catch {
566
+ return "";
567
+ }
568
+ }
569
+
570
+ /**
571
+ * Returns the current date formatted in the given timezone.
572
+ *
573
+ * @param timezone IANA timezone
574
+ * @param format date-fns format string
575
+ * @returns formatted date string
576
+ *
577
+ * Example:
578
+ * getCurrentDateByTimezoneFormat("Asia/Kolkata", "dd/MM/yyyy") → "07/01/2026"
579
+ */
580
+ static getCurrentDateByTimezoneFormat(timezone: string, format: string): string {
581
+ try {
582
+ const currentDate = new Date();
583
+ return formatInTimeZone(currentDate, timezone, format);
584
+ } catch {
585
+ return "";
586
+ }
587
+ }
588
+
589
+ /**
590
+ * Parses a date string using the provided format.
591
+ *
592
+ * @param dateStr input date string
593
+ * @param format date-fns format describing the input
594
+ * @returns Date object if valid, otherwise null
595
+ *
596
+ * Example:
597
+ * parseDate("02/Jan/2003", "dd/MMM/yyyy") -> 2003-01-01T18:30:00.000Z
598
+ */
599
+ static parseDate(dateStr: string, format: string): Date | null {
600
+ try {
601
+ if (!dateStr || !format) return null;
602
+
603
+ const parsedDate = parse(dateStr, format, new Date());
604
+ return isValid(parsedDate) ? parsedDate : null;
605
+ } catch {
606
+ return null;
607
+ }
608
+ }
609
+
610
+ /**
611
+ * Converts a date string from one format to another.
612
+ *
613
+ * @param dateStr input date string
614
+ * @param inputFormat format of input string
615
+ * @param outputFormat desired output format
616
+ * @returns formatted date string or null if invalid
617
+ *
618
+ * Example:
619
+ * convertDateFormat("2026-01-07", "yyyy-MM-dd", "dd/MM/yyyy") → "07/01/2026"
620
+ */
621
+ static convertDateFormat(dateStr: string, inputFormat: string, outputFormat: string) {
622
+ try {
623
+ if (!dateStr || !inputFormat || !outputFormat) return null;
624
+
625
+ const parsedDate = this.parseDate(dateStr, inputFormat);
626
+ if (parsedDate == null) return null;
627
+
628
+ return format(parsedDate, outputFormat);
629
+ } catch {
630
+ return null;
631
+ }
632
+ }
633
+
634
+ /**
635
+ * Removes the time portion from a Date and normalizes it to local midnight.
636
+ *
637
+ * @param date Date object
638
+ * @returns Date with time set to 00:00 or null if invalid
639
+ *
640
+ * Example:
641
+ * normalizeToDateOnly(new Date("2026-01-07T10:30:00")) -> 2024-01-14T18:30:00.000Z
642
+ */
643
+ static normalizeToDateOnly(date: Date): Date | null {
644
+ try {
645
+ if (!isValid(date)) return null;
646
+ return new Date(date.getFullYear(), date.getMonth(), date.getDate());
647
+ } catch {
648
+ return null;
649
+ }
650
+ }
651
+
652
+
653
+ /**
654
+ * Adjusts a date by adding or subtracting days, months, and/or years.
655
+ *
656
+ * Positive values add time, negative values subtract time.
657
+ *
658
+ * @param date Base date to adjust
659
+ * @param options Object containing days, months, and/or years
660
+ * @returns Adjusted Date or null if input date is invalid
661
+ *
662
+ * Example:
663
+ * adjustDate(new Date(), { days: 5 })
664
+ * adjustDate(new Date(), { months: -2 })
665
+ * adjustDate(new Date(), { years: 1, days: 10 })
666
+ */
667
+ static adjustDate(date: Date, options: { days?: number; months?: number; years?: number }): Date | null {
668
+ try {
669
+ if (!isValid(date)) return null;
670
+
671
+ let result = date;
672
+
673
+ if (options.years) {
674
+ result = addYears(result, options.years);
675
+ }
676
+
677
+ if (options.months) {
678
+ result = addMonths(result, options.months);
679
+ }
680
+
681
+ if (options.days) {
682
+ result = addDays(result, options.days);
683
+ }
684
+
685
+ return result;
686
+ } catch {
687
+ return null;
688
+ }
689
+ }
690
+
691
+ /**
692
+ * Adjusts the current date by adding or subtracting days, months, and/or years.
693
+ *
694
+ * Positive values add time, negative values subtract time.
695
+ *
696
+ * @param options Object containing days, months, and/or years
697
+ * @returns Adjusted Date or null if input date is invalid
698
+ *
699
+ * Example:
700
+ * adjustDate({ days: 5 })
701
+ * adjustDate({ months: -2 })
702
+ * adjustDate({ years: 1, days: 10 })
703
+ */
704
+ static adjustFromCurrentDate(options: { days?: number; months?: number; years?: number }): Date | null {
705
+ try {
706
+ const date = new Date();
707
+ if (!isValid(date)) return null;
708
+
709
+ let result = date;
710
+
711
+ if (options.years) {
712
+ result = addYears(result, options.years);
713
+ }
714
+
715
+ if (options.months) {
716
+ result = addMonths(result, options.months);
717
+ }
718
+
719
+ if (options.days) {
720
+ result = addDays(result, options.days);
721
+ }
722
+
723
+ return result;
724
+ } catch {
725
+ return null;
726
+ }
727
+ }
728
+
729
+ /**
730
+ * Extracts day, month, and year from a Date object.
731
+ *
732
+ * @param date Date object
733
+ * @returns {{ day: number; month: number; year: number } | null}
734
+ * Object containing day (1–31), month (1–12), and year
735
+ */
736
+ static getDayMonthYear(date: Date): { day: number; month: number; year: number } | null {
737
+ try {
738
+ if (!(date instanceof Date) || !isValid(date)) return null;
739
+
740
+ return {
741
+ day: date.getDate(),
742
+ month: date.getMonth() + 1,
743
+ year: date.getFullYear()
744
+ };
745
+ } catch {
746
+ return null;
747
+ }
748
+ }
749
+
750
+ /**
751
+ * Splits a string using a string or regex delimiter.
752
+ *
753
+ * @param value Input string to split
754
+ * @param delimiter String or RegExp used as delimiter
755
+ * @returns Array of split values (trimmed, non-empty)
756
+ *
757
+ * Examples:
758
+ * splitByDelimiter("A,B,C", ",") → ["A", "B", "C"]
759
+ * splitByDelimiter("A | B | C", "|") → ["A", "B", "C"]
760
+ * splitByDelimiter("A,B;C|D", /[,;|]/) → ["A", "B", "C", "D"]
761
+ */
762
+ static splitByDelimiter(value: string, delimiter: string | RegExp): string[] {
763
+ try {
764
+ if (!value || !delimiter) return [];
765
+
766
+ return value
767
+ .split(delimiter)
768
+ .map(item => item.trim())
769
+ .filter(item => item.length > 0);
770
+ } catch {
771
+ return [];
772
+ }
773
+ }
774
+
775
+ /**
776
+ * Returns the first regex match found in a string.
777
+ *
778
+ * If the regex contains capturing groups, the full match is returned.
779
+ *
780
+ * @param value Input string
781
+ * @param pattern Regular expression
782
+ * @returns First matched string or null if no match
783
+ *
784
+ * Example:
785
+ * getFirstMatch("Amount: $250", /\d+/) → "250"
786
+ */
787
+ static getFirstMatch(value: string, pattern: RegExp): string | null {
788
+ try {
789
+ if (!value || !pattern) return null;
790
+
791
+ const match = value.match(pattern);
792
+ return match ? match[0] : null;
793
+ } catch {
794
+ return null;
795
+ }
796
+ }
797
+
798
+ /**
799
+ * Returns all matches of a regex pattern found in a string.
800
+ *
801
+ * Note: For full functionality, the regex should have the global (g) flag.
802
+ *
803
+ * @param value Input string
804
+ * @param pattern Regular expression (preferably with /g)
805
+ * @returns Array of matched strings (empty array if no matches)
806
+ *
807
+ * Example:
808
+ * getAllMatches("IDs: 12, 45, 78", /\d+/g) → ["12", "45", "78"]
809
+ */
810
+ static getAllMatches(value: string, pattern: RegExp): string[] {
811
+ try {
812
+ if (!value || !pattern) return [];
813
+
814
+ const matches = value.match(pattern);
815
+ return matches ? matches : [];
816
+ } catch {
817
+ return [];
818
+ }
819
+ }
820
+
821
+ /**
822
+ * This method is to get total technology fee
823
+ * @since 13-01-2026
824
+ * @param fixedFee number
825
+ * @param percentageFee number
826
+ * @param amount number
827
+ * @returns number | null
828
+ */
829
+ static getTotalFees(
830
+ fixedFee: number,
831
+ percentageFee: number,
832
+ amount: number
833
+ ): number | null {
834
+ try {
835
+ if (
836
+ isNaN(fixedFee) ||
837
+ isNaN(percentageFee) ||
838
+ isNaN(amount)
839
+ ) {
840
+ throw new Error('Invalid number input');
841
+ }
842
+
843
+ const totalTechFees = (amount / 100) * percentageFee + fixedFee;
844
+ return totalTechFees;
845
+
846
+ } catch {
847
+ return null;
848
+ }
849
+ }
850
+
851
+ /**
852
+ * This method is get total amount as per passed fixed & percentage fee and amount
853
+ * @since 13-01-2026
854
+ * @param fixedFee number
855
+ * @param percentageFee number
856
+ * @param amount number
857
+ * @returns number | null
858
+ */
859
+ static getTotalAmount(
860
+ fixedFee: number,
861
+ percentageFee: number,
862
+ amount: number
863
+ ): number | null {
864
+ try {
865
+ const techFee = this.getTotalFees(
866
+ fixedFee,
867
+ percentageFee,
868
+ amount
869
+ );
870
+
871
+ if (techFee === null) {
872
+ throw new Error('Fee calculation failed');
873
+ }
874
+
875
+ return techFee + amount;
876
+
877
+ } catch {
878
+ return null;
879
+ }
880
+ }
881
+
882
+ /**
883
+ * Returns the difference between two dates in years.
884
+ *
885
+ * @param date1 Start date
886
+ * @param date2 End date
887
+ * @returns Difference in days or null if invalid
888
+ */
889
+ static getDifferenceInDays(date1: Date, date2: Date): number | null {
890
+ try {
891
+ if (!isValid(date1) || !isValid(date2)) return null;
892
+ return differenceInDays(date2, date1);
893
+ } catch {
894
+ return null;
895
+ }
896
+ }
897
+
898
+ /**
899
+ * Returns the difference between two dates in years.
900
+ *
901
+ * @param date1 Start date
902
+ * @param date2 End date
903
+ * @returns Difference in months or null if invalid
904
+ */
905
+ static getDifferenceInMonths(date1: Date, date2: Date): number | null {
906
+ try {
907
+ if (!isValid(date1) || !isValid(date2)) return null;
908
+ return differenceInMonths(date2, date1);
909
+ } catch {
910
+ return null;
911
+ }
912
+ }
913
+
914
+ /**
915
+ * Returns the difference between two dates in years.
916
+ *
917
+ * @param date1 Start date
918
+ * @param date2 End date
919
+ * @returns Difference in years or null if invalid
920
+ */
921
+ static getDifferenceInYears(date1: Date, date2: Date): number | null {
922
+ try {
923
+ if (!isValid(date1) || !isValid(date2)) return null;
924
+ return differenceInYears(date2, date1);
925
+ } catch {
926
+ return null;
927
+ }
928
+ }
929
+ }