@bash-app/bash-common 29.44.3 → 29.45.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 +47 -47
- package/prisma/schema.prisma +1623 -1622
- package/src/definitions.ts +610 -610
- package/src/extendedSchemas.ts +554 -554
- package/src/index.ts +16 -16
- package/src/utils/addressUtils.ts +173 -173
- package/src/utils/apiUtils.ts +76 -76
- package/src/utils/awsS3Utils.ts +99 -99
- package/src/utils/dateTimeUtils.ts +234 -234
- package/src/utils/paymentUtils.ts +56 -56
- package/src/utils/promoCodesUtils.ts +29 -29
- package/src/utils/qrCodeUtils.ts +23 -23
- package/src/utils/recurrenceUtils.ts +175 -175
- package/src/utils/service/serviceUtils.ts +121 -121
- package/src/utils/service/venueUtils.ts +45 -45
- package/src/utils/sortUtils.ts +28 -28
- package/src/utils/stripeAccountUtils.ts +11 -11
- package/src/utils/ticketListUtils.ts +78 -78
- package/src/utils/urlUtils.ts +29 -29
- package/tsconfig.json +19 -19
|
@@ -1,122 +1,122 @@
|
|
|
1
|
-
import { ServiceCancelationPolicy as ServiceCancelationPolicyOption } from "@prisma/client";
|
|
2
|
-
|
|
3
|
-
export type ServiceCancelationRefundPolicy = {
|
|
4
|
-
days?: number;
|
|
5
|
-
hours?: number;
|
|
6
|
-
refundPercentage: number
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export type ServiceCancelationPolicyData = {
|
|
10
|
-
name: string,
|
|
11
|
-
description?: string,
|
|
12
|
-
refundPolicy: ServiceCancelationRefundPolicy[],
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
export type ServiceCancelationPolicyMap = {
|
|
16
|
-
[key in ServiceCancelationPolicyOption]: ServiceCancelationPolicyData;
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
export const ServiceCancelationPolicyData: ServiceCancelationPolicyMap = {
|
|
20
|
-
[ServiceCancelationPolicyOption.None]: {
|
|
21
|
-
name: "None",
|
|
22
|
-
refundPolicy: [],
|
|
23
|
-
description: "No cancellation policy."
|
|
24
|
-
},
|
|
25
|
-
[ServiceCancelationPolicyOption.VeryFlexible]: {
|
|
26
|
-
name: "Very Flexible",
|
|
27
|
-
refundPolicy: [
|
|
28
|
-
{
|
|
29
|
-
hours: 24,
|
|
30
|
-
refundPercentage: 100
|
|
31
|
-
}
|
|
32
|
-
]
|
|
33
|
-
},
|
|
34
|
-
[ServiceCancelationPolicyOption.Flexible]: {
|
|
35
|
-
name: "Flexible",
|
|
36
|
-
refundPolicy: [
|
|
37
|
-
{
|
|
38
|
-
days: 7,
|
|
39
|
-
refundPercentage: 100
|
|
40
|
-
},
|
|
41
|
-
{
|
|
42
|
-
hours: 24,
|
|
43
|
-
refundPercentage: 50
|
|
44
|
-
}
|
|
45
|
-
]
|
|
46
|
-
},
|
|
47
|
-
[ServiceCancelationPolicyOption.Standard30Day]: {
|
|
48
|
-
name: "Standard 30 Day",
|
|
49
|
-
refundPolicy: [
|
|
50
|
-
{
|
|
51
|
-
days: 30,
|
|
52
|
-
refundPercentage: 100
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
days: 7,
|
|
56
|
-
refundPercentage: 50
|
|
57
|
-
}
|
|
58
|
-
]
|
|
59
|
-
},
|
|
60
|
-
[ServiceCancelationPolicyOption.Standard90Day]: {
|
|
61
|
-
name: "Very Flexible",
|
|
62
|
-
refundPolicy: [
|
|
63
|
-
{
|
|
64
|
-
days: 90,
|
|
65
|
-
refundPercentage: 100
|
|
66
|
-
},
|
|
67
|
-
{
|
|
68
|
-
days: 14,
|
|
69
|
-
refundPercentage: 50
|
|
70
|
-
}
|
|
71
|
-
]
|
|
72
|
-
}
|
|
73
|
-
} as const;
|
|
74
|
-
|
|
75
|
-
function generateDescription(refundPolicy: ServiceCancelationRefundPolicy[]): string {
|
|
76
|
-
const descriptions = refundPolicy.map((policy, index) => {
|
|
77
|
-
const unit = policy.days ? 'days' : 'hours';
|
|
78
|
-
const timeValue = policy.days ?? policy.hours;
|
|
79
|
-
|
|
80
|
-
const refundText = policy.refundPercentage === 100
|
|
81
|
-
? "a full refund (including all Fees)"
|
|
82
|
-
: `${policy.refundPercentage}% refund (excluding Fees)`;
|
|
83
|
-
|
|
84
|
-
if (index === 0) {
|
|
85
|
-
return `Guests may cancel their Booking until ${timeValue} ${unit} before the event start time and will receive ${refundText} of their Booking Price.`;
|
|
86
|
-
} else {
|
|
87
|
-
const previousTime = refundPolicy[index - 1].days ?? refundPolicy[index - 1].hours;
|
|
88
|
-
return `Guests may cancel their Booking between ${timeValue} ${unit} and ${previousTime} ${unit} before the event start time and receive ${refundText} of their Booking Price.`;
|
|
89
|
-
}
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
const lastTime = refundPolicy[refundPolicy.length - 1].days ?? refundPolicy[refundPolicy.length - 1].hours;
|
|
93
|
-
descriptions.push(`Cancellations submitted less than ${lastTime} ${refundPolicy[refundPolicy.length - 1].days ? 'days' : 'hours'} before the Event start time are not refundable.`);
|
|
94
|
-
|
|
95
|
-
return descriptions.join(" ");
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
Object.keys(ServiceCancelationPolicyData).filter((policyKey) => policyKey as ServiceCancelationPolicyOption != ServiceCancelationPolicyOption.None).forEach((policyKey) => {
|
|
99
|
-
const policy = ServiceCancelationPolicyData[policyKey as ServiceCancelationPolicyOption];
|
|
100
|
-
policy.description = generateDescription(policy.refundPolicy);
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
export type ServicePromoCodeType = "PerUser" | "PerService";
|
|
104
|
-
|
|
105
|
-
export type ServicePromoCodeDuration = {
|
|
106
|
-
days?: number;
|
|
107
|
-
};
|
|
108
|
-
|
|
109
|
-
export type ServicePromoCode = {
|
|
110
|
-
code?: string;
|
|
111
|
-
maxRedemptions?: number;
|
|
112
|
-
isTrial?: boolean;
|
|
113
|
-
discountPercentageFee?: number;
|
|
114
|
-
discountMonthlyFee?: number;
|
|
115
|
-
duration: ServicePromoCodeDuration,
|
|
116
|
-
type: ServicePromoCodeType;
|
|
117
|
-
automaticallyApplied: boolean;
|
|
118
|
-
};
|
|
119
|
-
|
|
120
|
-
export type ServicePromoCodeMap = {
|
|
121
|
-
[key: string]: ServicePromoCode;
|
|
1
|
+
import { ServiceCancelationPolicy as ServiceCancelationPolicyOption } from "@prisma/client";
|
|
2
|
+
|
|
3
|
+
export type ServiceCancelationRefundPolicy = {
|
|
4
|
+
days?: number;
|
|
5
|
+
hours?: number;
|
|
6
|
+
refundPercentage: number
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export type ServiceCancelationPolicyData = {
|
|
10
|
+
name: string,
|
|
11
|
+
description?: string,
|
|
12
|
+
refundPolicy: ServiceCancelationRefundPolicy[],
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export type ServiceCancelationPolicyMap = {
|
|
16
|
+
[key in ServiceCancelationPolicyOption]: ServiceCancelationPolicyData;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export const ServiceCancelationPolicyData: ServiceCancelationPolicyMap = {
|
|
20
|
+
[ServiceCancelationPolicyOption.None]: {
|
|
21
|
+
name: "None",
|
|
22
|
+
refundPolicy: [],
|
|
23
|
+
description: "No cancellation policy."
|
|
24
|
+
},
|
|
25
|
+
[ServiceCancelationPolicyOption.VeryFlexible]: {
|
|
26
|
+
name: "Very Flexible",
|
|
27
|
+
refundPolicy: [
|
|
28
|
+
{
|
|
29
|
+
hours: 24,
|
|
30
|
+
refundPercentage: 100
|
|
31
|
+
}
|
|
32
|
+
]
|
|
33
|
+
},
|
|
34
|
+
[ServiceCancelationPolicyOption.Flexible]: {
|
|
35
|
+
name: "Flexible",
|
|
36
|
+
refundPolicy: [
|
|
37
|
+
{
|
|
38
|
+
days: 7,
|
|
39
|
+
refundPercentage: 100
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
hours: 24,
|
|
43
|
+
refundPercentage: 50
|
|
44
|
+
}
|
|
45
|
+
]
|
|
46
|
+
},
|
|
47
|
+
[ServiceCancelationPolicyOption.Standard30Day]: {
|
|
48
|
+
name: "Standard 30 Day",
|
|
49
|
+
refundPolicy: [
|
|
50
|
+
{
|
|
51
|
+
days: 30,
|
|
52
|
+
refundPercentage: 100
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
days: 7,
|
|
56
|
+
refundPercentage: 50
|
|
57
|
+
}
|
|
58
|
+
]
|
|
59
|
+
},
|
|
60
|
+
[ServiceCancelationPolicyOption.Standard90Day]: {
|
|
61
|
+
name: "Very Flexible",
|
|
62
|
+
refundPolicy: [
|
|
63
|
+
{
|
|
64
|
+
days: 90,
|
|
65
|
+
refundPercentage: 100
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
days: 14,
|
|
69
|
+
refundPercentage: 50
|
|
70
|
+
}
|
|
71
|
+
]
|
|
72
|
+
}
|
|
73
|
+
} as const;
|
|
74
|
+
|
|
75
|
+
function generateDescription(refundPolicy: ServiceCancelationRefundPolicy[]): string {
|
|
76
|
+
const descriptions = refundPolicy.map((policy, index) => {
|
|
77
|
+
const unit = policy.days ? 'days' : 'hours';
|
|
78
|
+
const timeValue = policy.days ?? policy.hours;
|
|
79
|
+
|
|
80
|
+
const refundText = policy.refundPercentage === 100
|
|
81
|
+
? "a full refund (including all Fees)"
|
|
82
|
+
: `${policy.refundPercentage}% refund (excluding Fees)`;
|
|
83
|
+
|
|
84
|
+
if (index === 0) {
|
|
85
|
+
return `Guests may cancel their Booking until ${timeValue} ${unit} before the event start time and will receive ${refundText} of their Booking Price.`;
|
|
86
|
+
} else {
|
|
87
|
+
const previousTime = refundPolicy[index - 1].days ?? refundPolicy[index - 1].hours;
|
|
88
|
+
return `Guests may cancel their Booking between ${timeValue} ${unit} and ${previousTime} ${unit} before the event start time and receive ${refundText} of their Booking Price.`;
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
const lastTime = refundPolicy[refundPolicy.length - 1].days ?? refundPolicy[refundPolicy.length - 1].hours;
|
|
93
|
+
descriptions.push(`Cancellations submitted less than ${lastTime} ${refundPolicy[refundPolicy.length - 1].days ? 'days' : 'hours'} before the Event start time are not refundable.`);
|
|
94
|
+
|
|
95
|
+
return descriptions.join(" ");
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
Object.keys(ServiceCancelationPolicyData).filter((policyKey) => policyKey as ServiceCancelationPolicyOption != ServiceCancelationPolicyOption.None).forEach((policyKey) => {
|
|
99
|
+
const policy = ServiceCancelationPolicyData[policyKey as ServiceCancelationPolicyOption];
|
|
100
|
+
policy.description = generateDescription(policy.refundPolicy);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
export type ServicePromoCodeType = "PerUser" | "PerService";
|
|
104
|
+
|
|
105
|
+
export type ServicePromoCodeDuration = {
|
|
106
|
+
days?: number;
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
export type ServicePromoCode = {
|
|
110
|
+
code?: string;
|
|
111
|
+
maxRedemptions?: number;
|
|
112
|
+
isTrial?: boolean;
|
|
113
|
+
discountPercentageFee?: number;
|
|
114
|
+
discountMonthlyFee?: number;
|
|
115
|
+
duration: ServicePromoCodeDuration,
|
|
116
|
+
type: ServicePromoCodeType;
|
|
117
|
+
automaticallyApplied: boolean;
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
export type ServicePromoCodeMap = {
|
|
121
|
+
[key: string]: ServicePromoCode;
|
|
122
122
|
};
|
|
@@ -1,46 +1,46 @@
|
|
|
1
|
-
import { VenuePricingPlan as VenuePricingPlanOption } from "@prisma/client";
|
|
2
|
-
import { ServicePromoCodeMap } from "./serviceUtils";
|
|
3
|
-
|
|
4
|
-
export type VenuePricingPlanData = {
|
|
5
|
-
name: string,
|
|
6
|
-
description: string,
|
|
7
|
-
percentageFee: number;
|
|
8
|
-
monthlyFee: number;
|
|
9
|
-
flatFee: number;
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
export type VenuePricingPlanMap = {
|
|
13
|
-
[key in VenuePricingPlanOption]: VenuePricingPlanData;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
export const VenuePricingPlanData: VenuePricingPlanMap = {
|
|
17
|
-
[VenuePricingPlanOption.Percentage]: {
|
|
18
|
-
name: "Pay per booking",
|
|
19
|
-
description: "15% of each booking goes to Bash.",
|
|
20
|
-
percentageFee: 0.15,
|
|
21
|
-
monthlyFee: 0.0,
|
|
22
|
-
flatFee: 0.0
|
|
23
|
-
},
|
|
24
|
-
[VenuePricingPlanOption.Subscription]: {
|
|
25
|
-
name: "Monthly subscription",
|
|
26
|
-
description: "Pay $100/month and keep 100% of each booking.",
|
|
27
|
-
percentageFee: 0.0,
|
|
28
|
-
monthlyFee: 100.0,
|
|
29
|
-
flatFee: 0.0
|
|
30
|
-
}
|
|
31
|
-
} as const;
|
|
32
|
-
|
|
33
|
-
export const VenuePromoCodes: ServicePromoCodeMap = {
|
|
34
|
-
"Venue0001": {
|
|
35
|
-
isTrial: true,
|
|
36
|
-
duration: {
|
|
37
|
-
days: 90
|
|
38
|
-
},
|
|
39
|
-
type: "PerUser",
|
|
40
|
-
automaticallyApplied: true
|
|
41
|
-
}
|
|
42
|
-
} as const;
|
|
43
|
-
|
|
44
|
-
Object.entries(VenuePromoCodes).forEach(promoCode => promoCode[1].code = promoCode[0]);
|
|
45
|
-
|
|
1
|
+
import { VenuePricingPlan as VenuePricingPlanOption } from "@prisma/client";
|
|
2
|
+
import { ServicePromoCodeMap } from "./serviceUtils";
|
|
3
|
+
|
|
4
|
+
export type VenuePricingPlanData = {
|
|
5
|
+
name: string,
|
|
6
|
+
description: string,
|
|
7
|
+
percentageFee: number;
|
|
8
|
+
monthlyFee: number;
|
|
9
|
+
flatFee: number;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export type VenuePricingPlanMap = {
|
|
13
|
+
[key in VenuePricingPlanOption]: VenuePricingPlanData;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export const VenuePricingPlanData: VenuePricingPlanMap = {
|
|
17
|
+
[VenuePricingPlanOption.Percentage]: {
|
|
18
|
+
name: "Pay per booking",
|
|
19
|
+
description: "15% of each booking goes to Bash.",
|
|
20
|
+
percentageFee: 0.15,
|
|
21
|
+
monthlyFee: 0.0,
|
|
22
|
+
flatFee: 0.0
|
|
23
|
+
},
|
|
24
|
+
[VenuePricingPlanOption.Subscription]: {
|
|
25
|
+
name: "Monthly subscription",
|
|
26
|
+
description: "Pay $100/month and keep 100% of each booking.",
|
|
27
|
+
percentageFee: 0.0,
|
|
28
|
+
monthlyFee: 100.0,
|
|
29
|
+
flatFee: 0.0
|
|
30
|
+
}
|
|
31
|
+
} as const;
|
|
32
|
+
|
|
33
|
+
export const VenuePromoCodes: ServicePromoCodeMap = {
|
|
34
|
+
"Venue0001": {
|
|
35
|
+
isTrial: true,
|
|
36
|
+
duration: {
|
|
37
|
+
days: 90
|
|
38
|
+
},
|
|
39
|
+
type: "PerUser",
|
|
40
|
+
automaticallyApplied: true
|
|
41
|
+
}
|
|
42
|
+
} as const;
|
|
43
|
+
|
|
44
|
+
Object.entries(VenuePromoCodes).forEach(promoCode => promoCode[1].code = promoCode[0]);
|
|
45
|
+
|
|
46
46
|
export const VenueFreeTrialPromoCode = "Venue0001";
|
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,11 +1,11 @@
|
|
|
1
|
-
import { StripeLinkingStatus } from "../definitions";
|
|
2
|
-
import { isProduction } from "./apiUtils";
|
|
3
|
-
|
|
4
|
-
export const stripeAccountFullyLinked = (linkingStatus: StripeLinkingStatus): boolean => {
|
|
5
|
-
return (
|
|
6
|
-
!linkingStatus.hasOutstandingRequirements &&
|
|
7
|
-
linkingStatus.isOnboarded &&
|
|
8
|
-
linkingStatus.paymentsEnabled &&
|
|
9
|
-
(!isProduction() || linkingStatus.taxMonitoringEnabled)
|
|
10
|
-
);
|
|
11
|
-
}
|
|
1
|
+
import { StripeLinkingStatus } from "../definitions";
|
|
2
|
+
import { isProduction } from "./apiUtils";
|
|
3
|
+
|
|
4
|
+
export const stripeAccountFullyLinked = (linkingStatus: StripeLinkingStatus): boolean => {
|
|
5
|
+
return (
|
|
6
|
+
!linkingStatus.hasOutstandingRequirements &&
|
|
7
|
+
linkingStatus.isOnboarded &&
|
|
8
|
+
linkingStatus.paymentsEnabled &&
|
|
9
|
+
(!isProduction() || linkingStatus.taxMonitoringEnabled)
|
|
10
|
+
);
|
|
11
|
+
}
|
|
@@ -1,78 +1,78 @@
|
|
|
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
|
-
let ticketsExist = true;
|
|
21
|
-
const ticketArgs: string[] = [`${ticketTierId}${URL_PARAMS_TICKET_TIER_ID_NUMBER_OF_TICKETS_DATE_DELIM}`];
|
|
22
|
-
for (const ticketNumAndDates of ticketListArgs) {
|
|
23
|
-
if (ticketNumAndDates.numberOfTickets > 0) {
|
|
24
|
-
ticketsExist = true;
|
|
25
|
-
ticketArgs.push(
|
|
26
|
-
`${ticketNumAndDates.numberOfTickets}${URL_PARAMS_TICKETS_DATE_DELIM}${ticketNumAndDates.ticketDateTime}`);
|
|
27
|
-
}
|
|
28
|
-
else {
|
|
29
|
-
ticketsExist = false;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
if (ticketsExist) {
|
|
33
|
-
ticketListArr.push(ticketArgs.join(URL_PARAMS_NUMBER_OF_TICKETS_TICKETS_DATE_DELIM));
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
return ticketListArr.join(URL_PARAMS_TICKET_LIST_DELIM);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Returns map where the key is the ticketTierId
|
|
41
|
-
* @param ticketListStr A string structured like: [ticketTierId]__[numberOfTickets];;[date]~~[numberOfTickets];;[date]~~...,...
|
|
42
|
-
*/
|
|
43
|
-
export function ticketListStrToTicketList(ticketListStr: string): Map<string, NumberOfTicketsForDate[]> {
|
|
44
|
-
const ticketList: Map<string, NumberOfTicketsForDate[]> = new Map();
|
|
45
|
-
|
|
46
|
-
// [ticketTierId]__~~[numberOfTickets];;[date]~~[numberOfTickets];;[date]~~...,...
|
|
47
|
-
const ticketListArgs = ticketListStr.split(URL_PARAMS_TICKET_LIST_DELIM);
|
|
48
|
-
|
|
49
|
-
ticketListArgs.forEach((tierIdAndTicketNumbersAndDates: string): void => {
|
|
50
|
-
const ticketNumAndDatesArr: NumberOfTicketsForDate[] = [];
|
|
51
|
-
// [ticketTierId]__~~[numberOfTickets];;[date]~~[numberOfTickets];;[date]~~...
|
|
52
|
-
const [ticketTierId, ticketNumAndDatesStr] = tierIdAndTicketNumbersAndDates.split(URL_PARAMS_TICKET_TIER_ID_NUMBER_OF_TICKETS_DATE_DELIM);
|
|
53
|
-
if (!ticketNumAndDatesArr) {
|
|
54
|
-
throw new Error(`Could not parse ticketListStr. Maybe it is just an amount?`);
|
|
55
|
-
}
|
|
56
|
-
// ~~[numberOfTickets];;[date]~~[numberOfTickets];;[date]~~...
|
|
57
|
-
const ticketNumAndDates = ticketNumAndDatesStr.split(URL_PARAMS_NUMBER_OF_TICKETS_TICKETS_DATE_DELIM)
|
|
58
|
-
.filter((ticketNumAndDateStr): boolean => !!ticketNumAndDateStr);
|
|
59
|
-
|
|
60
|
-
for (const ticketNumAndDateStr of ticketNumAndDates) {
|
|
61
|
-
// [numberOfTickets];;[date]
|
|
62
|
-
const [numberOfTickets, ticketDateTimeStr] = ticketNumAndDateStr.split(URL_PARAMS_TICKETS_DATE_DELIM);
|
|
63
|
-
const ticketDateTime = dayjs(ticketDateTimeStr);
|
|
64
|
-
let ticketDateTimeFormattedStr: string | undefined = undefined;
|
|
65
|
-
|
|
66
|
-
if (ticketDateTime.isValid()) {
|
|
67
|
-
ticketDateTimeFormattedStr = ticketDateTime.format(DATETIME_FORMAT_ISO_LIKE);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
ticketNumAndDatesArr.push({
|
|
71
|
-
numberOfTickets: parseInt(numberOfTickets),
|
|
72
|
-
ticketDateTime: ticketDateTimeFormattedStr,
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
ticketList.set(ticketTierId, ticketNumAndDatesArr);
|
|
76
|
-
});
|
|
77
|
-
return ticketList;
|
|
78
|
-
}
|
|
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
|
+
let ticketsExist = true;
|
|
21
|
+
const ticketArgs: string[] = [`${ticketTierId}${URL_PARAMS_TICKET_TIER_ID_NUMBER_OF_TICKETS_DATE_DELIM}`];
|
|
22
|
+
for (const ticketNumAndDates of ticketListArgs) {
|
|
23
|
+
if (ticketNumAndDates.numberOfTickets > 0) {
|
|
24
|
+
ticketsExist = true;
|
|
25
|
+
ticketArgs.push(
|
|
26
|
+
`${ticketNumAndDates.numberOfTickets}${URL_PARAMS_TICKETS_DATE_DELIM}${ticketNumAndDates.ticketDateTime}`);
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
ticketsExist = false;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
if (ticketsExist) {
|
|
33
|
+
ticketListArr.push(ticketArgs.join(URL_PARAMS_NUMBER_OF_TICKETS_TICKETS_DATE_DELIM));
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return ticketListArr.join(URL_PARAMS_TICKET_LIST_DELIM);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Returns map where the key is the ticketTierId
|
|
41
|
+
* @param ticketListStr A string structured like: [ticketTierId]__[numberOfTickets];;[date]~~[numberOfTickets];;[date]~~...,...
|
|
42
|
+
*/
|
|
43
|
+
export function ticketListStrToTicketList(ticketListStr: string): Map<string, NumberOfTicketsForDate[]> {
|
|
44
|
+
const ticketList: Map<string, NumberOfTicketsForDate[]> = new Map();
|
|
45
|
+
|
|
46
|
+
// [ticketTierId]__~~[numberOfTickets];;[date]~~[numberOfTickets];;[date]~~...,...
|
|
47
|
+
const ticketListArgs = ticketListStr.split(URL_PARAMS_TICKET_LIST_DELIM);
|
|
48
|
+
|
|
49
|
+
ticketListArgs.forEach((tierIdAndTicketNumbersAndDates: string): void => {
|
|
50
|
+
const ticketNumAndDatesArr: NumberOfTicketsForDate[] = [];
|
|
51
|
+
// [ticketTierId]__~~[numberOfTickets];;[date]~~[numberOfTickets];;[date]~~...
|
|
52
|
+
const [ticketTierId, ticketNumAndDatesStr] = tierIdAndTicketNumbersAndDates.split(URL_PARAMS_TICKET_TIER_ID_NUMBER_OF_TICKETS_DATE_DELIM);
|
|
53
|
+
if (!ticketNumAndDatesArr) {
|
|
54
|
+
throw new Error(`Could not parse ticketListStr. Maybe it is just an amount?`);
|
|
55
|
+
}
|
|
56
|
+
// ~~[numberOfTickets];;[date]~~[numberOfTickets];;[date]~~...
|
|
57
|
+
const ticketNumAndDates = ticketNumAndDatesStr.split(URL_PARAMS_NUMBER_OF_TICKETS_TICKETS_DATE_DELIM)
|
|
58
|
+
.filter((ticketNumAndDateStr): boolean => !!ticketNumAndDateStr);
|
|
59
|
+
|
|
60
|
+
for (const ticketNumAndDateStr of ticketNumAndDates) {
|
|
61
|
+
// [numberOfTickets];;[date]
|
|
62
|
+
const [numberOfTickets, ticketDateTimeStr] = ticketNumAndDateStr.split(URL_PARAMS_TICKETS_DATE_DELIM);
|
|
63
|
+
const ticketDateTime = dayjs(ticketDateTimeStr);
|
|
64
|
+
let ticketDateTimeFormattedStr: string | undefined = undefined;
|
|
65
|
+
|
|
66
|
+
if (ticketDateTime.isValid()) {
|
|
67
|
+
ticketDateTimeFormattedStr = ticketDateTime.format(DATETIME_FORMAT_ISO_LIKE);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
ticketNumAndDatesArr.push({
|
|
71
|
+
numberOfTickets: parseInt(numberOfTickets),
|
|
72
|
+
ticketDateTime: ticketDateTimeFormattedStr,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
ticketList.set(ticketTierId, ticketNumAndDatesArr);
|
|
76
|
+
});
|
|
77
|
+
return ticketList;
|
|
78
|
+
}
|
package/src/utils/urlUtils.ts
CHANGED
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
import {isProduction} from "./apiUtils";
|
|
2
|
-
import {BASH_DETAIL_URL} from "../definitions";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const API_HOST = process.env.REACT_APP_API ?? "http://localhost:3500";
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
export function getFrontendHost(): string {
|
|
9
|
-
const host = isProduction()
|
|
10
|
-
? `${window.location.protocol}//${window.location.host}`
|
|
11
|
-
: `${window.location.protocol}//${window.location.hostname}:3000`;
|
|
12
|
-
return host;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export function getBackendHost(): string {
|
|
16
|
-
const host = isProduction()
|
|
17
|
-
? API_HOST
|
|
18
|
-
: `${window.location.protocol}//${window.location.hostname}:3500`;
|
|
19
|
-
return host;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export function getSsrBashDetailUrl(bashEventId: string | undefined): string {
|
|
23
|
-
if (bashEventId) {
|
|
24
|
-
const url = `/api/ssr${BASH_DETAIL_URL}/${bashEventId}`;
|
|
25
|
-
return url;
|
|
26
|
-
}
|
|
27
|
-
console.error(`BashEventId was not specified for the ssr bash detail url`);
|
|
28
|
-
return '';
|
|
29
|
-
}
|
|
1
|
+
import {isProduction} from "./apiUtils";
|
|
2
|
+
import {BASH_DETAIL_URL} from "../definitions";
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
const API_HOST = process.env.REACT_APP_API ?? "http://localhost:3500";
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
export function getFrontendHost(): string {
|
|
9
|
+
const host = isProduction()
|
|
10
|
+
? `${window.location.protocol}//${window.location.host}`
|
|
11
|
+
: `${window.location.protocol}//${window.location.hostname}:3000`;
|
|
12
|
+
return host;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function getBackendHost(): string {
|
|
16
|
+
const host = isProduction()
|
|
17
|
+
? API_HOST
|
|
18
|
+
: `${window.location.protocol}//${window.location.hostname}:3500`;
|
|
19
|
+
return host;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function getSsrBashDetailUrl(bashEventId: string | undefined): string {
|
|
23
|
+
if (bashEventId) {
|
|
24
|
+
const url = `/api/ssr${BASH_DETAIL_URL}/${bashEventId}`;
|
|
25
|
+
return url;
|
|
26
|
+
}
|
|
27
|
+
console.error(`BashEventId was not specified for the ssr bash detail url`);
|
|
28
|
+
return '';
|
|
29
|
+
}
|