@bash-app/bash-common 10.7.0 → 10.9.0
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/README.md +8 -8
- package/package.json +45 -45
- package/prisma/schema.prisma +982 -983
- package/src/definitions.ts +443 -443
- package/src/extendedSchemas.ts +244 -244
- package/src/index.ts +10 -10
- package/src/utils/addressUtils.ts +173 -173
- package/src/utils/awsS3Utils.ts +100 -100
- package/src/utils/dateTimeUtils.ts +186 -186
- package/src/utils/paymentUtils.ts +56 -56
- package/src/utils/qrCodeUtils.ts +23 -23
- package/src/utils/recurrenceUtils.ts +175 -175
- package/src/utils/sortUtils.ts +28 -28
- package/src/utils/ticketListUtils.ts +71 -71
- package/tsconfig.json +19 -19
|
@@ -1,175 +1,175 @@
|
|
|
1
|
-
import {DayOfWeek, Recurrence, RecurringFrequency} from "@prisma/client";
|
|
2
|
-
import dayjs, {Dayjs} from "dayjs";
|
|
3
|
-
import dayjsWeekDay from "dayjs/plugin/weekday";
|
|
4
|
-
import {DateTimeArgType} from "../definitions";
|
|
5
|
-
import {compareDateTime, DATETIME_FORMAT_ISO_LIKE} from "./dateTimeUtils";
|
|
6
|
-
|
|
7
|
-
dayjs.extend(dayjsWeekDay);
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
export function getRecurringBashEventPossibleDateTimes(startDateTime: DateTimeArgType,
|
|
11
|
-
recurrence: Recurrence | undefined | null): Date[] {
|
|
12
|
-
return getRecurringBashEventPossibleDatesTimesInternal(startDateTime, recurrence, true) as Date[];
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export function getRecurringBashEventPossibleDayjsTimes(startDateTime: DateTimeArgType,
|
|
16
|
-
recurrence: Recurrence | undefined | null): Dayjs[] {
|
|
17
|
-
return getRecurringBashEventPossibleDatesTimesInternal(startDateTime, recurrence, false) as Dayjs[];
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
function getRecurringBashEventPossibleDatesTimesInternal(startDateTime: DateTimeArgType,
|
|
22
|
-
recurrence: Recurrence | undefined | null,
|
|
23
|
-
toDate: boolean): (Dayjs | Date)[] {
|
|
24
|
-
if (!recurrence || !recurrence.frequency || recurrence.frequency === RecurringFrequency.Never) {
|
|
25
|
-
return [];
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
let recurrenceDates: Dayjs[] = [];
|
|
29
|
-
const beginningDate = findEarliestPossibleBashEventDate(startDateTime) as Dayjs; // Don't allow dates before the current date
|
|
30
|
-
|
|
31
|
-
switch (recurrence.frequency) {
|
|
32
|
-
case RecurringFrequency.Weekly:
|
|
33
|
-
recurrenceDates = getWeeklyRecurringDates(beginningDate, recurrence);
|
|
34
|
-
break;
|
|
35
|
-
default:
|
|
36
|
-
console.error(`Only weekly frequency is currently supported`);
|
|
37
|
-
}
|
|
38
|
-
return recurrenceDates.map((date: Dayjs): string => date.format(DATETIME_FORMAT_ISO_LIKE))
|
|
39
|
-
.sort()
|
|
40
|
-
.map((dateStr: string): Dayjs | Date => {
|
|
41
|
-
if (toDate) {
|
|
42
|
-
return dayjs(dateStr).toDate();
|
|
43
|
-
}
|
|
44
|
-
else {
|
|
45
|
-
return dayjs(dateStr);
|
|
46
|
-
}
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Get the weekly recurring dates
|
|
52
|
-
* @param beginningDateTime The beginning DateTime of the event, adjusted to be no earlier than now.
|
|
53
|
-
* @param recurrence
|
|
54
|
-
*/
|
|
55
|
-
function getWeeklyRecurringDates(beginningDateTime: Dayjs, recurrence: Recurrence): Dayjs[] {
|
|
56
|
-
if (recurrence.frequency !== RecurringFrequency.Weekly) {
|
|
57
|
-
throw new Error(`Cannot do a weekly recurrence if the frequency isn't weekly.`);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
const interval = recurrence.interval ?? 1;
|
|
61
|
-
const recurrenceEnds = dayjs(recurrence.ends).endOf('day'); // Get the end of the day to not miss the last day
|
|
62
|
-
const numberOfDays = recurrenceEnds.diff(beginningDateTime, 'days');
|
|
63
|
-
const numberOfWeeks = Math.ceil((numberOfDays / 7) / interval); // Get the number of days and then round up so that we include the ending date
|
|
64
|
-
|
|
65
|
-
const recurrenceDates: Dayjs[] = [];
|
|
66
|
-
let theNextWeekOfRecurrences = beginningDateTime;
|
|
67
|
-
|
|
68
|
-
// Go week by week getting the next recurrence date
|
|
69
|
-
for (let i = 0; i < numberOfWeeks; i++) {
|
|
70
|
-
let weekday: Dayjs | null = null;
|
|
71
|
-
for (const dayOfWeekEnum of recurrence.repeatOnDays) {
|
|
72
|
-
const dayOfWeekNum = dayOfWeekEnumToDayNumber(dayOfWeekEnum);
|
|
73
|
-
weekday = theNextWeekOfRecurrences.weekday(dayOfWeekNum);
|
|
74
|
-
if (weekday > recurrenceEnds || weekday < beginningDateTime) {
|
|
75
|
-
continue; // Continue because repeatOnDays isn't sorted by the day of the week
|
|
76
|
-
}
|
|
77
|
-
// Set the time on the date so that it matches the time when the event starts
|
|
78
|
-
weekday = copyTimeToDate(beginningDateTime, weekday);
|
|
79
|
-
recurrenceDates.push(weekday);
|
|
80
|
-
}
|
|
81
|
-
if (weekday) {
|
|
82
|
-
theNextWeekOfRecurrences = getBeginningOfWeekInterval(weekday, interval);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
return recurrenceDates;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
function copyTimeToDate(dateWithTimeToCopy: Dayjs, dateWhoseTimeToChange: Dayjs): Dayjs {
|
|
89
|
-
if (dateWithTimeToCopy.second() !== 0) {
|
|
90
|
-
console.warn(`dateWithTimeToCopy has non-zero seconds: ${dateWithTimeToCopy.toString()} \nFixing...`);
|
|
91
|
-
dateWithTimeToCopy = dateWithTimeToCopy.set('seconds', 0);
|
|
92
|
-
}
|
|
93
|
-
dateWhoseTimeToChange = dateWhoseTimeToChange.set('hours', dateWithTimeToCopy.hour());
|
|
94
|
-
dateWhoseTimeToChange = dateWhoseTimeToChange.set('minutes', dateWithTimeToCopy.minute());
|
|
95
|
-
dateWhoseTimeToChange = dateWhoseTimeToChange.set('seconds', 0); // Should be 0
|
|
96
|
-
return dateWhoseTimeToChange;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
function dayOfWeekEnumToDayNumber(dayEnum: DayOfWeek): number {
|
|
100
|
-
switch (dayEnum) {
|
|
101
|
-
case DayOfWeek.Sunday:
|
|
102
|
-
return 0;
|
|
103
|
-
case DayOfWeek.Monday:
|
|
104
|
-
return 1;
|
|
105
|
-
case DayOfWeek.Tuesday:
|
|
106
|
-
return 2;
|
|
107
|
-
case DayOfWeek.Wednesday:
|
|
108
|
-
return 3;
|
|
109
|
-
case DayOfWeek.Thursday:
|
|
110
|
-
return 4;
|
|
111
|
-
case DayOfWeek.Friday:
|
|
112
|
-
return 5;
|
|
113
|
-
case DayOfWeek.Saturday:
|
|
114
|
-
return 6;
|
|
115
|
-
default:
|
|
116
|
-
throw new Error(`How did this happen? Invalid DayOfWeek: ${dayEnum}`); // Shouldn't happen
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* Get the next week determined by the interval by going to the end of the week interval and adding one day
|
|
122
|
-
* @param date
|
|
123
|
-
* @param interval
|
|
124
|
-
*/
|
|
125
|
-
function getBeginningOfWeekInterval(date: Dayjs, interval: number): Dayjs {
|
|
126
|
-
if (!interval) {
|
|
127
|
-
interval = 1; // Avoid 0
|
|
128
|
-
}
|
|
129
|
-
// An interval of 2 would be (2 - 1) * 7 + 1 = 8 days to add to skip a week and go into the next week
|
|
130
|
-
const numberOfDaysToAdd = interval > 1 ? (interval - 1) * 7 + 1 : 1;
|
|
131
|
-
return date.endOf('week').add(numberOfDaysToAdd, 'day');
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
export function freqToGrammarString(freq: RecurringFrequency, interval: number | undefined, toLowerCase: boolean = false): string {
|
|
135
|
-
if (!interval) {
|
|
136
|
-
return freq;
|
|
137
|
-
}
|
|
138
|
-
const isPlural = interval > 1;
|
|
139
|
-
let result: string = freq;
|
|
140
|
-
switch (freq) {
|
|
141
|
-
case RecurringFrequency.Daily:
|
|
142
|
-
result = isPlural ? 'Days' : 'Day';
|
|
143
|
-
break;
|
|
144
|
-
case RecurringFrequency.Weekly:
|
|
145
|
-
result = isPlural ? 'Weeks' : 'Week';
|
|
146
|
-
break;
|
|
147
|
-
case RecurringFrequency.Monthly:
|
|
148
|
-
result = isPlural ? 'Months' : 'Month';
|
|
149
|
-
break;
|
|
150
|
-
case RecurringFrequency.Yearly:
|
|
151
|
-
result = isPlural ? 'Years' : 'Year';
|
|
152
|
-
break;
|
|
153
|
-
}
|
|
154
|
-
return toLowerCase ? result.toLowerCase() : result;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
export function findEarliestPossibleBashEventDate(startDateTimeArg: DateTimeArgType): Dayjs | undefined {
|
|
158
|
-
return findEarliestOrLatestPossibleBashEventDate(startDateTimeArg, true);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
function findEarliestOrLatestPossibleBashEventDate(startDateTimeArg: DateTimeArgType, findEarly: boolean): Dayjs | undefined {
|
|
162
|
-
if (!startDateTimeArg) {
|
|
163
|
-
return;
|
|
164
|
-
}
|
|
165
|
-
// Don't allow dates before the current date
|
|
166
|
-
const startDateTime = dayjs(startDateTimeArg);
|
|
167
|
-
const currentDateTime = dayjs();
|
|
168
|
-
const comparedDateTime = compareDateTime(currentDateTime.toDate(), startDateTimeArg);
|
|
169
|
-
if (findEarly) {
|
|
170
|
-
return comparedDateTime > 0 ? currentDateTime : startDateTime;
|
|
171
|
-
}
|
|
172
|
-
else {
|
|
173
|
-
return comparedDateTime < 0 ? currentDateTime : startDateTime;
|
|
174
|
-
}
|
|
175
|
-
}
|
|
1
|
+
import {DayOfWeek, Recurrence, RecurringFrequency} from "@prisma/client";
|
|
2
|
+
import dayjs, {Dayjs} from "dayjs";
|
|
3
|
+
import dayjsWeekDay from "dayjs/plugin/weekday";
|
|
4
|
+
import {DateTimeArgType} from "../definitions";
|
|
5
|
+
import {compareDateTime, DATETIME_FORMAT_ISO_LIKE} from "./dateTimeUtils";
|
|
6
|
+
|
|
7
|
+
dayjs.extend(dayjsWeekDay);
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
export function getRecurringBashEventPossibleDateTimes(startDateTime: DateTimeArgType,
|
|
11
|
+
recurrence: Recurrence | undefined | null): Date[] {
|
|
12
|
+
return getRecurringBashEventPossibleDatesTimesInternal(startDateTime, recurrence, true) as Date[];
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function getRecurringBashEventPossibleDayjsTimes(startDateTime: DateTimeArgType,
|
|
16
|
+
recurrence: Recurrence | undefined | null): Dayjs[] {
|
|
17
|
+
return getRecurringBashEventPossibleDatesTimesInternal(startDateTime, recurrence, false) as Dayjs[];
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
function getRecurringBashEventPossibleDatesTimesInternal(startDateTime: DateTimeArgType,
|
|
22
|
+
recurrence: Recurrence | undefined | null,
|
|
23
|
+
toDate: boolean): (Dayjs | Date)[] {
|
|
24
|
+
if (!recurrence || !recurrence.frequency || recurrence.frequency === RecurringFrequency.Never) {
|
|
25
|
+
return [];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
let recurrenceDates: Dayjs[] = [];
|
|
29
|
+
const beginningDate = findEarliestPossibleBashEventDate(startDateTime) as Dayjs; // Don't allow dates before the current date
|
|
30
|
+
|
|
31
|
+
switch (recurrence.frequency) {
|
|
32
|
+
case RecurringFrequency.Weekly:
|
|
33
|
+
recurrenceDates = getWeeklyRecurringDates(beginningDate, recurrence);
|
|
34
|
+
break;
|
|
35
|
+
default:
|
|
36
|
+
console.error(`Only weekly frequency is currently supported`);
|
|
37
|
+
}
|
|
38
|
+
return recurrenceDates.map((date: Dayjs): string => date.format(DATETIME_FORMAT_ISO_LIKE))
|
|
39
|
+
.sort()
|
|
40
|
+
.map((dateStr: string): Dayjs | Date => {
|
|
41
|
+
if (toDate) {
|
|
42
|
+
return dayjs(dateStr).toDate();
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
return dayjs(dateStr);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Get the weekly recurring dates
|
|
52
|
+
* @param beginningDateTime The beginning DateTime of the event, adjusted to be no earlier than now.
|
|
53
|
+
* @param recurrence
|
|
54
|
+
*/
|
|
55
|
+
function getWeeklyRecurringDates(beginningDateTime: Dayjs, recurrence: Recurrence): Dayjs[] {
|
|
56
|
+
if (recurrence.frequency !== RecurringFrequency.Weekly) {
|
|
57
|
+
throw new Error(`Cannot do a weekly recurrence if the frequency isn't weekly.`);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const interval = recurrence.interval ?? 1;
|
|
61
|
+
const recurrenceEnds = dayjs(recurrence.ends).endOf('day'); // Get the end of the day to not miss the last day
|
|
62
|
+
const numberOfDays = recurrenceEnds.diff(beginningDateTime, 'days');
|
|
63
|
+
const numberOfWeeks = Math.ceil((numberOfDays / 7) / interval); // Get the number of days and then round up so that we include the ending date
|
|
64
|
+
|
|
65
|
+
const recurrenceDates: Dayjs[] = [];
|
|
66
|
+
let theNextWeekOfRecurrences = beginningDateTime;
|
|
67
|
+
|
|
68
|
+
// Go week by week getting the next recurrence date
|
|
69
|
+
for (let i = 0; i < numberOfWeeks; i++) {
|
|
70
|
+
let weekday: Dayjs | null = null;
|
|
71
|
+
for (const dayOfWeekEnum of recurrence.repeatOnDays) {
|
|
72
|
+
const dayOfWeekNum = dayOfWeekEnumToDayNumber(dayOfWeekEnum);
|
|
73
|
+
weekday = theNextWeekOfRecurrences.weekday(dayOfWeekNum);
|
|
74
|
+
if (weekday > recurrenceEnds || weekday < beginningDateTime) {
|
|
75
|
+
continue; // Continue because repeatOnDays isn't sorted by the day of the week
|
|
76
|
+
}
|
|
77
|
+
// Set the time on the date so that it matches the time when the event starts
|
|
78
|
+
weekday = copyTimeToDate(beginningDateTime, weekday);
|
|
79
|
+
recurrenceDates.push(weekday);
|
|
80
|
+
}
|
|
81
|
+
if (weekday) {
|
|
82
|
+
theNextWeekOfRecurrences = getBeginningOfWeekInterval(weekday, interval);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return recurrenceDates;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function copyTimeToDate(dateWithTimeToCopy: Dayjs, dateWhoseTimeToChange: Dayjs): Dayjs {
|
|
89
|
+
if (dateWithTimeToCopy.second() !== 0) {
|
|
90
|
+
console.warn(`dateWithTimeToCopy has non-zero seconds: ${dateWithTimeToCopy.toString()} \nFixing...`);
|
|
91
|
+
dateWithTimeToCopy = dateWithTimeToCopy.set('seconds', 0);
|
|
92
|
+
}
|
|
93
|
+
dateWhoseTimeToChange = dateWhoseTimeToChange.set('hours', dateWithTimeToCopy.hour());
|
|
94
|
+
dateWhoseTimeToChange = dateWhoseTimeToChange.set('minutes', dateWithTimeToCopy.minute());
|
|
95
|
+
dateWhoseTimeToChange = dateWhoseTimeToChange.set('seconds', 0); // Should be 0
|
|
96
|
+
return dateWhoseTimeToChange;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function dayOfWeekEnumToDayNumber(dayEnum: DayOfWeek): number {
|
|
100
|
+
switch (dayEnum) {
|
|
101
|
+
case DayOfWeek.Sunday:
|
|
102
|
+
return 0;
|
|
103
|
+
case DayOfWeek.Monday:
|
|
104
|
+
return 1;
|
|
105
|
+
case DayOfWeek.Tuesday:
|
|
106
|
+
return 2;
|
|
107
|
+
case DayOfWeek.Wednesday:
|
|
108
|
+
return 3;
|
|
109
|
+
case DayOfWeek.Thursday:
|
|
110
|
+
return 4;
|
|
111
|
+
case DayOfWeek.Friday:
|
|
112
|
+
return 5;
|
|
113
|
+
case DayOfWeek.Saturday:
|
|
114
|
+
return 6;
|
|
115
|
+
default:
|
|
116
|
+
throw new Error(`How did this happen? Invalid DayOfWeek: ${dayEnum}`); // Shouldn't happen
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Get the next week determined by the interval by going to the end of the week interval and adding one day
|
|
122
|
+
* @param date
|
|
123
|
+
* @param interval
|
|
124
|
+
*/
|
|
125
|
+
function getBeginningOfWeekInterval(date: Dayjs, interval: number): Dayjs {
|
|
126
|
+
if (!interval) {
|
|
127
|
+
interval = 1; // Avoid 0
|
|
128
|
+
}
|
|
129
|
+
// An interval of 2 would be (2 - 1) * 7 + 1 = 8 days to add to skip a week and go into the next week
|
|
130
|
+
const numberOfDaysToAdd = interval > 1 ? (interval - 1) * 7 + 1 : 1;
|
|
131
|
+
return date.endOf('week').add(numberOfDaysToAdd, 'day');
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export function freqToGrammarString(freq: RecurringFrequency, interval: number | undefined, toLowerCase: boolean = false): string {
|
|
135
|
+
if (!interval) {
|
|
136
|
+
return freq;
|
|
137
|
+
}
|
|
138
|
+
const isPlural = interval > 1;
|
|
139
|
+
let result: string = freq;
|
|
140
|
+
switch (freq) {
|
|
141
|
+
case RecurringFrequency.Daily:
|
|
142
|
+
result = isPlural ? 'Days' : 'Day';
|
|
143
|
+
break;
|
|
144
|
+
case RecurringFrequency.Weekly:
|
|
145
|
+
result = isPlural ? 'Weeks' : 'Week';
|
|
146
|
+
break;
|
|
147
|
+
case RecurringFrequency.Monthly:
|
|
148
|
+
result = isPlural ? 'Months' : 'Month';
|
|
149
|
+
break;
|
|
150
|
+
case RecurringFrequency.Yearly:
|
|
151
|
+
result = isPlural ? 'Years' : 'Year';
|
|
152
|
+
break;
|
|
153
|
+
}
|
|
154
|
+
return toLowerCase ? result.toLowerCase() : result;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export function findEarliestPossibleBashEventDate(startDateTimeArg: DateTimeArgType): Dayjs | undefined {
|
|
158
|
+
return findEarliestOrLatestPossibleBashEventDate(startDateTimeArg, true);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function findEarliestOrLatestPossibleBashEventDate(startDateTimeArg: DateTimeArgType, findEarly: boolean): Dayjs | undefined {
|
|
162
|
+
if (!startDateTimeArg) {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
// Don't allow dates before the current date
|
|
166
|
+
const startDateTime = dayjs(startDateTimeArg);
|
|
167
|
+
const currentDateTime = dayjs();
|
|
168
|
+
const comparedDateTime = compareDateTime(currentDateTime.toDate(), startDateTimeArg);
|
|
169
|
+
if (findEarly) {
|
|
170
|
+
return comparedDateTime > 0 ? currentDateTime : startDateTime;
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
return comparedDateTime < 0 ? currentDateTime : startDateTime;
|
|
174
|
+
}
|
|
175
|
+
}
|
package/src/utils/sortUtils.ts
CHANGED
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
type SortTierFields = Partial<{sortOrder: number | undefined | null, price: number | string | undefined | null}>;
|
|
2
|
-
|
|
3
|
-
export function sortTiers(a: SortTierFields, b: SortTierFields): number {
|
|
4
|
-
const aValueToCompare = getTierValueToCompare(a);
|
|
5
|
-
const bValueToCompare = getTierValueToCompare(b);
|
|
6
|
-
if (aValueToCompare === bValueToCompare) {
|
|
7
|
-
return 0;
|
|
8
|
-
}
|
|
9
|
-
else if (!aValueToCompare && bValueToCompare) {
|
|
10
|
-
return -1;
|
|
11
|
-
}
|
|
12
|
-
else if (aValueToCompare && !bValueToCompare) {
|
|
13
|
-
return 1;
|
|
14
|
-
}
|
|
15
|
-
else if (!aValueToCompare || !bValueToCompare) {
|
|
16
|
-
return 0;
|
|
17
|
-
}
|
|
18
|
-
else if (aValueToCompare > bValueToCompare) {
|
|
19
|
-
return 1;
|
|
20
|
-
}
|
|
21
|
-
else {
|
|
22
|
-
return -1;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
function getTierValueToCompare(tier: SortTierFields): string | undefined {
|
|
27
|
-
return tier.sortOrder?.toString() ?? tier.price?.toString();
|
|
28
|
-
}
|
|
1
|
+
type SortTierFields = Partial<{sortOrder: number | undefined | null, price: number | string | undefined | null}>;
|
|
2
|
+
|
|
3
|
+
export function sortTiers(a: SortTierFields, b: SortTierFields): number {
|
|
4
|
+
const aValueToCompare = getTierValueToCompare(a);
|
|
5
|
+
const bValueToCompare = getTierValueToCompare(b);
|
|
6
|
+
if (aValueToCompare === bValueToCompare) {
|
|
7
|
+
return 0;
|
|
8
|
+
}
|
|
9
|
+
else if (!aValueToCompare && bValueToCompare) {
|
|
10
|
+
return -1;
|
|
11
|
+
}
|
|
12
|
+
else if (aValueToCompare && !bValueToCompare) {
|
|
13
|
+
return 1;
|
|
14
|
+
}
|
|
15
|
+
else if (!aValueToCompare || !bValueToCompare) {
|
|
16
|
+
return 0;
|
|
17
|
+
}
|
|
18
|
+
else if (aValueToCompare > bValueToCompare) {
|
|
19
|
+
return 1;
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
return -1;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function getTierValueToCompare(tier: SortTierFields): string | undefined {
|
|
27
|
+
return tier.sortOrder?.toString() ?? tier.price?.toString();
|
|
28
|
+
}
|
|
@@ -1,71 +1,71 @@
|
|
|
1
|
-
import dayjs from "dayjs";
|
|
2
|
-
import {
|
|
3
|
-
NumberOfTicketsForDate,
|
|
4
|
-
URL_PARAMS_NUMBER_OF_TICKETS_TICKETS_DATE_DELIM,
|
|
5
|
-
URL_PARAMS_TICKET_TIER_ID_NUMBER_OF_TICKETS_DATE_DELIM,
|
|
6
|
-
URL_PARAMS_TICKET_LIST_DELIM,
|
|
7
|
-
URL_PARAMS_TICKETS_DATE_DELIM
|
|
8
|
-
} from "../definitions";
|
|
9
|
-
import { DATETIME_FORMAT_ISO_LIKE } from "./dateTimeUtils";
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Returns A string structured like: [ticketTierId]__[numberOfTickets];;[date]~~[numberOfTickets];;[date]~~,...
|
|
14
|
-
* @param ticketList A map where the key is the ticketTierId
|
|
15
|
-
*/
|
|
16
|
-
export function ticketListToString(ticketList: Map<string, NumberOfTicketsForDate[]>): string {
|
|
17
|
-
const ticketListArr: string[] = [];
|
|
18
|
-
|
|
19
|
-
for (const [ticketTierId, ticketListArgs] of ticketList.entries()) {
|
|
20
|
-
const ticketArgs: string[] = [`${ticketTierId}${URL_PARAMS_TICKET_TIER_ID_NUMBER_OF_TICKETS_DATE_DELIM}`];
|
|
21
|
-
for (const ticketNumAndDates of ticketListArgs) {
|
|
22
|
-
if (ticketNumAndDates.numberOfTickets > 0) {
|
|
23
|
-
ticketArgs.push(
|
|
24
|
-
`${ticketNumAndDates.numberOfTickets}${URL_PARAMS_TICKETS_DATE_DELIM}${ticketNumAndDates.ticketDateTime}`);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
ticketListArr.push(ticketArgs.join(URL_PARAMS_NUMBER_OF_TICKETS_TICKETS_DATE_DELIM));
|
|
28
|
-
}
|
|
29
|
-
return ticketListArr.join(URL_PARAMS_TICKET_LIST_DELIM);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Returns map where the key is the ticketTierId
|
|
34
|
-
* @param ticketListStr A string structured like: [ticketTierId]__[numberOfTickets];;[date]~~[numberOfTickets];;[date]~~...,...
|
|
35
|
-
*/
|
|
36
|
-
export function ticketListStrToTicketList(ticketListStr: string): Map<string, NumberOfTicketsForDate[]> {
|
|
37
|
-
const ticketList: Map<string, NumberOfTicketsForDate[]> = new Map();
|
|
38
|
-
|
|
39
|
-
// [ticketTierId]__~~[numberOfTickets];;[date]~~[numberOfTickets];;[date]~~...,...
|
|
40
|
-
const ticketListArgs = ticketListStr.split(URL_PARAMS_TICKET_LIST_DELIM);
|
|
41
|
-
|
|
42
|
-
ticketListArgs.forEach((tierIdAndTicketNumbersAndDates: string): void => {
|
|
43
|
-
const ticketNumAndDatesArr: NumberOfTicketsForDate[] = [];
|
|
44
|
-
// [ticketTierId]__~~[numberOfTickets];;[date]~~[numberOfTickets];;[date]~~...
|
|
45
|
-
const [ticketTierId, ticketNumAndDatesStr] = tierIdAndTicketNumbersAndDates.split(URL_PARAMS_TICKET_TIER_ID_NUMBER_OF_TICKETS_DATE_DELIM);
|
|
46
|
-
if (!ticketNumAndDatesArr) {
|
|
47
|
-
throw new Error(`Could not parse ticketListStr. Maybe it is just an amount?`);
|
|
48
|
-
}
|
|
49
|
-
// ~~[numberOfTickets];;[date]~~[numberOfTickets];;[date]~~...
|
|
50
|
-
const ticketNumAndDates = ticketNumAndDatesStr.split(URL_PARAMS_NUMBER_OF_TICKETS_TICKETS_DATE_DELIM)
|
|
51
|
-
.filter((ticketNumAndDateStr): boolean => !!ticketNumAndDateStr);
|
|
52
|
-
|
|
53
|
-
for (const ticketNumAndDateStr of ticketNumAndDates) {
|
|
54
|
-
// [numberOfTickets];;[date]
|
|
55
|
-
const [numberOfTickets, ticketDateTimeStr] = ticketNumAndDateStr.split(URL_PARAMS_TICKETS_DATE_DELIM);
|
|
56
|
-
const ticketDateTime = dayjs(ticketDateTimeStr);
|
|
57
|
-
let ticketDateTimeFormattedStr: string | undefined = undefined;
|
|
58
|
-
|
|
59
|
-
if (ticketDateTime.isValid()) {
|
|
60
|
-
ticketDateTimeFormattedStr = ticketDateTime.format(DATETIME_FORMAT_ISO_LIKE);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
ticketNumAndDatesArr.push({
|
|
64
|
-
numberOfTickets: parseInt(numberOfTickets),
|
|
65
|
-
ticketDateTime: ticketDateTimeFormattedStr,
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
ticketList.set(ticketTierId, ticketNumAndDatesArr);
|
|
69
|
-
});
|
|
70
|
-
return ticketList;
|
|
71
|
-
}
|
|
1
|
+
import dayjs from "dayjs";
|
|
2
|
+
import {
|
|
3
|
+
NumberOfTicketsForDate,
|
|
4
|
+
URL_PARAMS_NUMBER_OF_TICKETS_TICKETS_DATE_DELIM,
|
|
5
|
+
URL_PARAMS_TICKET_TIER_ID_NUMBER_OF_TICKETS_DATE_DELIM,
|
|
6
|
+
URL_PARAMS_TICKET_LIST_DELIM,
|
|
7
|
+
URL_PARAMS_TICKETS_DATE_DELIM
|
|
8
|
+
} from "../definitions";
|
|
9
|
+
import { DATETIME_FORMAT_ISO_LIKE } from "./dateTimeUtils";
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Returns A string structured like: [ticketTierId]__[numberOfTickets];;[date]~~[numberOfTickets];;[date]~~,...
|
|
14
|
+
* @param ticketList A map where the key is the ticketTierId
|
|
15
|
+
*/
|
|
16
|
+
export function ticketListToString(ticketList: Map<string, NumberOfTicketsForDate[]>): string {
|
|
17
|
+
const ticketListArr: string[] = [];
|
|
18
|
+
|
|
19
|
+
for (const [ticketTierId, ticketListArgs] of ticketList.entries()) {
|
|
20
|
+
const ticketArgs: string[] = [`${ticketTierId}${URL_PARAMS_TICKET_TIER_ID_NUMBER_OF_TICKETS_DATE_DELIM}`];
|
|
21
|
+
for (const ticketNumAndDates of ticketListArgs) {
|
|
22
|
+
if (ticketNumAndDates.numberOfTickets > 0) {
|
|
23
|
+
ticketArgs.push(
|
|
24
|
+
`${ticketNumAndDates.numberOfTickets}${URL_PARAMS_TICKETS_DATE_DELIM}${ticketNumAndDates.ticketDateTime}`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
ticketListArr.push(ticketArgs.join(URL_PARAMS_NUMBER_OF_TICKETS_TICKETS_DATE_DELIM));
|
|
28
|
+
}
|
|
29
|
+
return ticketListArr.join(URL_PARAMS_TICKET_LIST_DELIM);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Returns map where the key is the ticketTierId
|
|
34
|
+
* @param ticketListStr A string structured like: [ticketTierId]__[numberOfTickets];;[date]~~[numberOfTickets];;[date]~~...,...
|
|
35
|
+
*/
|
|
36
|
+
export function ticketListStrToTicketList(ticketListStr: string): Map<string, NumberOfTicketsForDate[]> {
|
|
37
|
+
const ticketList: Map<string, NumberOfTicketsForDate[]> = new Map();
|
|
38
|
+
|
|
39
|
+
// [ticketTierId]__~~[numberOfTickets];;[date]~~[numberOfTickets];;[date]~~...,...
|
|
40
|
+
const ticketListArgs = ticketListStr.split(URL_PARAMS_TICKET_LIST_DELIM);
|
|
41
|
+
|
|
42
|
+
ticketListArgs.forEach((tierIdAndTicketNumbersAndDates: string): void => {
|
|
43
|
+
const ticketNumAndDatesArr: NumberOfTicketsForDate[] = [];
|
|
44
|
+
// [ticketTierId]__~~[numberOfTickets];;[date]~~[numberOfTickets];;[date]~~...
|
|
45
|
+
const [ticketTierId, ticketNumAndDatesStr] = tierIdAndTicketNumbersAndDates.split(URL_PARAMS_TICKET_TIER_ID_NUMBER_OF_TICKETS_DATE_DELIM);
|
|
46
|
+
if (!ticketNumAndDatesArr) {
|
|
47
|
+
throw new Error(`Could not parse ticketListStr. Maybe it is just an amount?`);
|
|
48
|
+
}
|
|
49
|
+
// ~~[numberOfTickets];;[date]~~[numberOfTickets];;[date]~~...
|
|
50
|
+
const ticketNumAndDates = ticketNumAndDatesStr.split(URL_PARAMS_NUMBER_OF_TICKETS_TICKETS_DATE_DELIM)
|
|
51
|
+
.filter((ticketNumAndDateStr): boolean => !!ticketNumAndDateStr);
|
|
52
|
+
|
|
53
|
+
for (const ticketNumAndDateStr of ticketNumAndDates) {
|
|
54
|
+
// [numberOfTickets];;[date]
|
|
55
|
+
const [numberOfTickets, ticketDateTimeStr] = ticketNumAndDateStr.split(URL_PARAMS_TICKETS_DATE_DELIM);
|
|
56
|
+
const ticketDateTime = dayjs(ticketDateTimeStr);
|
|
57
|
+
let ticketDateTimeFormattedStr: string | undefined = undefined;
|
|
58
|
+
|
|
59
|
+
if (ticketDateTime.isValid()) {
|
|
60
|
+
ticketDateTimeFormattedStr = ticketDateTime.format(DATETIME_FORMAT_ISO_LIKE);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
ticketNumAndDatesArr.push({
|
|
64
|
+
numberOfTickets: parseInt(numberOfTickets),
|
|
65
|
+
ticketDateTime: ticketDateTimeFormattedStr,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
ticketList.set(ticketTierId, ticketNumAndDatesArr);
|
|
69
|
+
});
|
|
70
|
+
return ticketList;
|
|
71
|
+
}
|
package/tsconfig.json
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "es2022",
|
|
4
|
-
"module": "esnext",
|
|
5
|
-
"moduleResolution": "node",
|
|
6
|
-
"esModuleInterop": true,
|
|
7
|
-
"noEmit": true,
|
|
8
|
-
"outDir": "./dist",
|
|
9
|
-
"rootDir": "./src",
|
|
10
|
-
"strict": true,
|
|
11
|
-
"skipLibCheck": true,
|
|
12
|
-
"forceConsistentCasingInFileNames": true,
|
|
13
|
-
"jsx": "react-jsx",
|
|
14
|
-
"noImplicitAny": true,
|
|
15
|
-
"sourceMap": true,
|
|
16
|
-
},
|
|
17
|
-
"include": ["src/**/*.ts", "src/**/*.tsx"],
|
|
18
|
-
"exclude": ["node_modules"]
|
|
19
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "es2022",
|
|
4
|
+
"module": "esnext",
|
|
5
|
+
"moduleResolution": "node",
|
|
6
|
+
"esModuleInterop": true,
|
|
7
|
+
"noEmit": true,
|
|
8
|
+
"outDir": "./dist",
|
|
9
|
+
"rootDir": "./src",
|
|
10
|
+
"strict": true,
|
|
11
|
+
"skipLibCheck": true,
|
|
12
|
+
"forceConsistentCasingInFileNames": true,
|
|
13
|
+
"jsx": "react-jsx",
|
|
14
|
+
"noImplicitAny": true,
|
|
15
|
+
"sourceMap": true,
|
|
16
|
+
},
|
|
17
|
+
"include": ["src/**/*.ts", "src/**/*.tsx"],
|
|
18
|
+
"exclude": ["node_modules"]
|
|
19
|
+
}
|