@bash-app/bash-common 30.50.1 → 30.52.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.
Files changed (205) hide show
  1. package/README.md +0 -0
  2. package/dist/definitions.d.ts +668 -0
  3. package/dist/definitions.d.ts.map +1 -0
  4. package/dist/definitions.js +467 -0
  5. package/dist/definitions.js.map +1 -0
  6. package/dist/extendedSchemas.d.ts +2206 -0
  7. package/dist/extendedSchemas.d.ts.map +1 -0
  8. package/dist/extendedSchemas.js +429 -0
  9. package/dist/extendedSchemas.js.map +1 -0
  10. package/dist/index.d.ts +39 -0
  11. package/dist/index.d.ts.map +1 -0
  12. package/dist/index.js +40 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/utils/addressUtils.d.ts +14 -0
  15. package/dist/utils/addressUtils.d.ts.map +1 -0
  16. package/dist/utils/addressUtils.js +177 -0
  17. package/dist/utils/addressUtils.js.map +1 -0
  18. package/dist/utils/apiUtils.d.ts +14 -0
  19. package/dist/utils/apiUtils.d.ts.map +1 -0
  20. package/dist/utils/apiUtils.js +61 -0
  21. package/dist/utils/apiUtils.js.map +1 -0
  22. package/dist/utils/arrayUtils.d.ts +2 -0
  23. package/dist/utils/arrayUtils.d.ts.map +1 -0
  24. package/dist/utils/arrayUtils.js +5 -0
  25. package/dist/utils/arrayUtils.js.map +1 -0
  26. package/dist/utils/awsS3Utils.d.ts +10 -0
  27. package/dist/utils/awsS3Utils.d.ts.map +1 -0
  28. package/dist/utils/awsS3Utils.js +89 -0
  29. package/dist/utils/awsS3Utils.js.map +1 -0
  30. package/dist/utils/badgeUtils.d.ts +33 -0
  31. package/dist/utils/badgeUtils.d.ts.map +1 -0
  32. package/dist/utils/badgeUtils.js +57 -0
  33. package/dist/utils/badgeUtils.js.map +1 -0
  34. package/dist/utils/blog/blogDbUtils.d.ts +48 -0
  35. package/dist/utils/blog/blogDbUtils.d.ts.map +1 -0
  36. package/dist/utils/blog/blogDbUtils.js +218 -0
  37. package/dist/utils/blog/blogDbUtils.js.map +1 -0
  38. package/dist/utils/blogUtils.d.ts +19 -0
  39. package/dist/utils/blogUtils.d.ts.map +1 -0
  40. package/dist/utils/blogUtils.js +118 -0
  41. package/dist/utils/blogUtils.js.map +1 -0
  42. package/dist/utils/dateTimeUtils.d.ts +38 -0
  43. package/dist/utils/dateTimeUtils.d.ts.map +1 -0
  44. package/dist/utils/dateTimeUtils.js +207 -0
  45. package/dist/utils/dateTimeUtils.js.map +1 -0
  46. package/dist/utils/entityUtils.d.ts +5 -0
  47. package/dist/utils/entityUtils.d.ts.map +1 -0
  48. package/dist/utils/entityUtils.js +5 -0
  49. package/dist/utils/entityUtils.js.map +1 -0
  50. package/dist/utils/generalDateTimeUtils.d.ts +15 -0
  51. package/dist/utils/generalDateTimeUtils.d.ts.map +1 -0
  52. package/dist/utils/generalDateTimeUtils.js +38 -0
  53. package/dist/utils/generalDateTimeUtils.js.map +1 -0
  54. package/dist/utils/luxonUtils.d.ts +95 -0
  55. package/dist/utils/luxonUtils.d.ts.map +1 -0
  56. package/dist/utils/luxonUtils.js +623 -0
  57. package/dist/utils/luxonUtils.js.map +1 -0
  58. package/dist/utils/mathUtils.d.ts +2 -0
  59. package/dist/utils/mathUtils.d.ts.map +1 -0
  60. package/dist/utils/mathUtils.js +4 -0
  61. package/dist/utils/mathUtils.js.map +1 -0
  62. package/dist/utils/objUtils.d.ts +3 -0
  63. package/dist/utils/objUtils.d.ts.map +1 -0
  64. package/dist/utils/objUtils.js +29 -0
  65. package/dist/utils/objUtils.js.map +1 -0
  66. package/dist/utils/paymentUtils.d.ts +18 -0
  67. package/dist/utils/paymentUtils.d.ts.map +1 -0
  68. package/dist/utils/paymentUtils.js +50 -0
  69. package/dist/utils/paymentUtils.js.map +1 -0
  70. package/dist/utils/promoCodesUtils.d.ts +6 -0
  71. package/dist/utils/promoCodesUtils.d.ts.map +1 -0
  72. package/dist/utils/promoCodesUtils.js +23 -0
  73. package/dist/utils/promoCodesUtils.js.map +1 -0
  74. package/dist/utils/qrCodeUtils.d.ts +4 -0
  75. package/dist/utils/qrCodeUtils.d.ts.map +1 -0
  76. package/dist/utils/qrCodeUtils.js +22 -0
  77. package/dist/utils/qrCodeUtils.js.map +1 -0
  78. package/dist/utils/recurrenceUtils.d.ts +8 -0
  79. package/dist/utils/recurrenceUtils.d.ts.map +1 -0
  80. package/dist/utils/recurrenceUtils.js +153 -0
  81. package/dist/utils/recurrenceUtils.js.map +1 -0
  82. package/dist/utils/reviewUtils.d.ts +29 -0
  83. package/dist/utils/reviewUtils.d.ts.map +1 -0
  84. package/dist/utils/reviewUtils.js +65 -0
  85. package/dist/utils/reviewUtils.js.map +1 -0
  86. package/dist/utils/service/apiServiceBookingApiUtils.d.ts +21 -0
  87. package/dist/utils/service/apiServiceBookingApiUtils.d.ts.map +1 -0
  88. package/dist/utils/service/apiServiceBookingApiUtils.js +131 -0
  89. package/dist/utils/service/apiServiceBookingApiUtils.js.map +1 -0
  90. package/dist/utils/service/attendeeOptionUtils.d.ts +11 -0
  91. package/dist/utils/service/attendeeOptionUtils.d.ts.map +1 -0
  92. package/dist/utils/service/attendeeOptionUtils.js +9 -0
  93. package/dist/utils/service/attendeeOptionUtils.js.map +1 -0
  94. package/dist/utils/service/frontendServiceBookingUtils.d.ts +53 -0
  95. package/dist/utils/service/frontendServiceBookingUtils.d.ts.map +1 -0
  96. package/dist/utils/service/frontendServiceBookingUtils.js +134 -0
  97. package/dist/utils/service/frontendServiceBookingUtils.js.map +1 -0
  98. package/dist/utils/service/regexUtils.d.ts +6 -0
  99. package/dist/utils/service/regexUtils.d.ts.map +1 -0
  100. package/dist/utils/service/regexUtils.js +16 -0
  101. package/dist/utils/service/regexUtils.js.map +1 -0
  102. package/dist/utils/service/serviceBookingStatusUtils.d.ts +21 -0
  103. package/dist/utils/service/serviceBookingStatusUtils.d.ts.map +1 -0
  104. package/dist/utils/service/serviceBookingStatusUtils.js +130 -0
  105. package/dist/utils/service/serviceBookingStatusUtils.js.map +1 -0
  106. package/dist/utils/service/serviceBookingTypes.d.ts +19 -0
  107. package/dist/utils/service/serviceBookingTypes.d.ts.map +1 -0
  108. package/dist/utils/service/serviceBookingTypes.js +2 -0
  109. package/dist/utils/service/serviceBookingTypes.js.map +1 -0
  110. package/dist/utils/service/serviceDBUtils.d.ts +5 -0
  111. package/dist/utils/service/serviceDBUtils.d.ts.map +1 -0
  112. package/dist/utils/service/serviceDBUtils.js +48 -0
  113. package/dist/utils/service/serviceDBUtils.js.map +1 -0
  114. package/dist/utils/service/serviceRateDBUtils.d.ts +1 -0
  115. package/dist/utils/service/serviceRateDBUtils.d.ts.map +1 -0
  116. package/dist/utils/service/serviceRateDBUtils.js +159 -0
  117. package/dist/utils/service/serviceRateDBUtils.js.map +1 -0
  118. package/dist/utils/service/serviceRateTypes.d.ts +9 -0
  119. package/dist/utils/service/serviceRateTypes.d.ts.map +1 -0
  120. package/dist/utils/service/serviceRateTypes.js +2 -0
  121. package/dist/utils/service/serviceRateTypes.js.map +1 -0
  122. package/dist/utils/service/serviceRateUtils.d.ts +24 -0
  123. package/dist/utils/service/serviceRateUtils.d.ts.map +1 -0
  124. package/dist/utils/service/serviceRateUtils.js +183 -0
  125. package/dist/utils/service/serviceRateUtils.js.map +1 -0
  126. package/dist/utils/service/serviceUtils.d.ts +83 -0
  127. package/dist/utils/service/serviceUtils.d.ts.map +1 -0
  128. package/dist/utils/service/serviceUtils.js +311 -0
  129. package/dist/utils/service/serviceUtils.js.map +1 -0
  130. package/dist/utils/service/venueUtils.d.ts +13 -0
  131. package/dist/utils/service/venueUtils.d.ts.map +1 -0
  132. package/dist/utils/service/venueUtils.js +18 -0
  133. package/dist/utils/service/venueUtils.js.map +1 -0
  134. package/dist/utils/slugUtils.d.ts +9 -0
  135. package/dist/utils/slugUtils.d.ts.map +1 -0
  136. package/dist/utils/slugUtils.js +47 -0
  137. package/dist/utils/slugUtils.js.map +1 -0
  138. package/dist/utils/sortUtils.d.ts +7 -0
  139. package/dist/utils/sortUtils.d.ts.map +1 -0
  140. package/dist/utils/sortUtils.js +26 -0
  141. package/dist/utils/sortUtils.js.map +1 -0
  142. package/dist/utils/stringUtils.d.ts +2 -0
  143. package/dist/utils/stringUtils.d.ts.map +1 -0
  144. package/dist/utils/stringUtils.js +6 -0
  145. package/dist/utils/stringUtils.js.map +1 -0
  146. package/dist/utils/stripeAccountUtils.d.ts +3 -0
  147. package/dist/utils/stripeAccountUtils.d.ts.map +1 -0
  148. package/dist/utils/stripeAccountUtils.js +10 -0
  149. package/dist/utils/stripeAccountUtils.js.map +1 -0
  150. package/dist/utils/ticketListUtils.d.ts +12 -0
  151. package/dist/utils/ticketListUtils.d.ts.map +1 -0
  152. package/dist/utils/ticketListUtils.js +78 -0
  153. package/dist/utils/ticketListUtils.js.map +1 -0
  154. package/dist/utils/typeUtils.d.ts +11 -0
  155. package/dist/utils/typeUtils.d.ts.map +1 -0
  156. package/dist/utils/typeUtils.js +8 -0
  157. package/dist/utils/typeUtils.js.map +1 -0
  158. package/dist/utils/urlUtils.d.ts +10 -0
  159. package/dist/utils/urlUtils.d.ts.map +1 -0
  160. package/dist/utils/urlUtils.js +66 -0
  161. package/dist/utils/urlUtils.js.map +1 -0
  162. package/dist/utils/userPromoCodeUtils.d.ts +21 -0
  163. package/dist/utils/userPromoCodeUtils.d.ts.map +1 -0
  164. package/dist/utils/userPromoCodeUtils.js +13 -0
  165. package/dist/utils/userPromoCodeUtils.js.map +1 -0
  166. package/dist/utils/userSubscriptionUtils.d.ts +36 -0
  167. package/dist/utils/userSubscriptionUtils.d.ts.map +1 -0
  168. package/dist/utils/userSubscriptionUtils.js +56 -0
  169. package/dist/utils/userSubscriptionUtils.js.map +1 -0
  170. package/dist/utils/userUtils.d.ts +2 -0
  171. package/dist/utils/userUtils.d.ts.map +1 -0
  172. package/dist/utils/userUtils.js +2 -0
  173. package/dist/utils/userUtils.js.map +1 -0
  174. package/package.json +4 -2
  175. package/prisma/schema.prisma +247 -94
  176. package/src/definitions.ts +52 -1
  177. package/src/extendedSchemas.ts +180 -13
  178. package/src/index.ts +32 -21
  179. package/src/utils/apiUtils.ts +0 -0
  180. package/src/utils/arrayUtils.ts +0 -0
  181. package/src/utils/awsS3Utils.ts +0 -0
  182. package/src/utils/blog/blogDbUtils.ts +343 -0
  183. package/src/utils/blogUtils.ts +134 -0
  184. package/src/utils/entityUtils.ts +0 -0
  185. package/src/utils/generalDateTimeUtils.ts +0 -0
  186. package/src/utils/mathUtils.ts +0 -0
  187. package/src/utils/objUtils.ts +0 -0
  188. package/src/utils/paymentUtils.ts +0 -0
  189. package/src/utils/promoCodesUtils.ts +0 -0
  190. package/src/utils/qrCodeUtils.ts +4 -2
  191. package/src/utils/service/attendeeOptionUtils.ts +0 -0
  192. package/src/utils/service/regexUtils.ts +0 -0
  193. package/src/utils/service/serviceBookingStatusUtils.ts +6 -18
  194. package/src/utils/service/serviceDBUtils.ts +0 -0
  195. package/src/utils/service/serviceRateDBUtils.ts +0 -0
  196. package/src/utils/service/serviceUtils.ts +0 -0
  197. package/src/utils/service/venueUtils.ts +0 -0
  198. package/src/utils/slugUtils.ts +60 -0
  199. package/src/utils/sortUtils.ts +0 -0
  200. package/src/utils/stringUtils.ts +0 -0
  201. package/src/utils/stripeAccountUtils.ts +0 -0
  202. package/src/utils/ticketListUtils.ts +24 -6
  203. package/src/utils/urlUtils.ts +0 -0
  204. package/src/utils/userPromoCodeUtils.ts +0 -0
  205. package/src/utils/userSubscriptionUtils.ts +0 -0
@@ -0,0 +1,4 @@
1
+ export function roundToNearestDivisor(num, div) {
2
+ return Math.round(num * div) / div;
3
+ }
4
+ //# sourceMappingURL=mathUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mathUtils.js","sourceRoot":"","sources":["../../src/utils/mathUtils.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,qBAAqB,CAAC,GAAW,EAAE,GAAW;IAC5D,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;AACrC,CAAC"}
@@ -0,0 +1,3 @@
1
+ export declare function isObject(value: unknown): value is Record<string, unknown>;
2
+ export declare function deepMerge<T extends Record<string, any>, U extends Record<string, any>>(target: T | undefined | null, source: U | undefined | null, mergeArrays?: boolean, mergeCommon?: boolean): T;
3
+ //# sourceMappingURL=objUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"objUtils.d.ts","sourceRoot":"","sources":["../../src/utils/objUtils.ts"],"names":[],"mappings":"AAAA,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAOzE;AACD,wBAAgB,SAAS,CACvB,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC7B,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAE7B,MAAM,EAAE,CAAC,GAAG,SAAS,GAAG,IAAI,EAC5B,MAAM,EAAE,CAAC,GAAG,SAAS,GAAG,IAAI,EAC5B,WAAW,GAAE,OAAe,EAC5B,WAAW,GAAE,OAAe,GAC3B,CAAC,CA4BH"}
@@ -0,0 +1,29 @@
1
+ export function isObject(value) {
2
+ return (typeof value === "object" &&
3
+ value !== null &&
4
+ !Array.isArray(value) &&
5
+ !(value instanceof Date));
6
+ }
7
+ export function deepMerge(target, source, mergeArrays = false, mergeCommon = false) {
8
+ const output = { ...(mergeCommon ? [] : target) };
9
+ for (const key in source) {
10
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
11
+ const sourceVal = source[key];
12
+ const targetVal = target ? target[key] : undefined;
13
+ if (mergeArrays && Array.isArray(sourceVal) && Array.isArray(targetVal)) {
14
+ // Merge arrays by concatenating them.
15
+ output[key] = [...targetVal, ...sourceVal];
16
+ }
17
+ else if (isObject(sourceVal) && isObject(targetVal)) {
18
+ // When both values are objects, merge them recursively.
19
+ output[key] = deepMerge(targetVal, sourceVal);
20
+ }
21
+ else {
22
+ // Otherwise, overwrite target with source.
23
+ output[key] = sourceVal;
24
+ }
25
+ }
26
+ }
27
+ return output;
28
+ }
29
+ //# sourceMappingURL=objUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"objUtils.js","sourceRoot":"","sources":["../../src/utils/objUtils.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,QAAQ,CAAC,KAAc;IACrC,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QACrB,CAAC,CAAC,KAAK,YAAY,IAAI,CAAC,CACzB,CAAC;AACJ,CAAC;AACD,MAAM,UAAU,SAAS,CAIvB,MAA4B,EAC5B,MAA4B,EAC5B,cAAuB,KAAK,EAC5B,cAAuB,KAAK;IAE5B,MAAM,MAAM,GAAG,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,EAAW,CAAC;IAE3D,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;QACzB,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC;YACtD,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;YAC9B,MAAM,SAAS,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YAEnD,IAAI,WAAW,IAAI,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;gBACxE,sCAAsC;gBACtC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,SAAS,EAAE,GAAG,SAAS,CAGvC,CAAC;YACL,CAAC;iBAAM,IAAI,QAAQ,CAAC,SAAS,CAAC,IAAI,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;gBACtD,wDAAwD;gBACxD,MAAM,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC,SAAS,EAAE,SAAS,CAG1C,CAAC;YACL,CAAC;iBAAM,CAAC;gBACN,2CAA2C;gBAC3C,MAAM,CAAC,GAAG,CAAC,GAAG,SAA8C,CAAC;YAC/D,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,18 @@
1
+ import { BashEventPromoCode, TicketTier } from "@prisma/client";
2
+ import { NumberOfTicketsForDate } from "../definitions";
3
+ /**
4
+ * Returns the amount of discount in dollars
5
+ * @param totalInDollars
6
+ * @param promoCode
7
+ */
8
+ export declare function calculateDiscountFromPromoCode(totalInDollars: number, promoCode: BashEventPromoCode | undefined): number;
9
+ /**
10
+ * Returns the total price based on a map where the keys are the ticketTierIds
11
+ * @param ticketTiers
12
+ * @param ticketList
13
+ */
14
+ export declare function calculateTotalPriceWithoutTax(ticketTiers: TicketTier[], ticketList: Map<string, NumberOfTicketsForDate[]>): number;
15
+ export declare function convertCentsToDollars(price: number | undefined | null): number;
16
+ export declare function convertDollarsToCents(price: number | undefined | null): number;
17
+ export declare function calculateBashAppFee(total: number): number;
18
+ //# sourceMappingURL=paymentUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paymentUtils.d.ts","sourceRoot":"","sources":["../../src/utils/paymentUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAChE,OAAO,EAEL,sBAAsB,EAEvB,MAAM,gBAAgB,CAAC;AAExB;;;;GAIG;AACH,wBAAgB,8BAA8B,CAC5C,cAAc,EAAE,MAAM,EACtB,SAAS,EAAE,kBAAkB,GAAG,SAAS,GACxC,MAAM,CAeR;AAED;;;;GAIG;AACH,wBAAgB,6BAA6B,CAC3C,WAAW,EAAE,UAAU,EAAE,EACzB,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,sBAAsB,EAAE,CAAC,GAChD,MAAM,CASR;AAED,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAC/B,MAAM,CAKR;AACD,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAC/B,MAAM,CAKR;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEzD"}
@@ -0,0 +1,50 @@
1
+ import { BASH_FEE_PERCENTAGE, PRICE_DOLLARS_AND_CENTS_RATIO, } from "../definitions";
2
+ /**
3
+ * Returns the amount of discount in dollars
4
+ * @param totalInDollars
5
+ * @param promoCode
6
+ */
7
+ export function calculateDiscountFromPromoCode(totalInDollars, promoCode) {
8
+ if (promoCode) {
9
+ if (promoCode.discountAmountInCents) {
10
+ const discountInDollars = convertCentsToDollars(promoCode.discountAmountInCents);
11
+ return Math.max(0, discountInDollars); // Ensure we don't discount more than 100%
12
+ }
13
+ if (promoCode.discountAmountPercentage) {
14
+ const discountInDollars = totalInDollars * (promoCode.discountAmountPercentage / 100);
15
+ return Math.min(totalInDollars, discountInDollars); // Ensure we don't discount more than 100%
16
+ }
17
+ }
18
+ return 0;
19
+ }
20
+ /**
21
+ * Returns the total price based on a map where the keys are the ticketTierIds
22
+ * @param ticketTiers
23
+ * @param ticketList
24
+ */
25
+ export function calculateTotalPriceWithoutTax(ticketTiers, ticketList) {
26
+ let total = 0;
27
+ ticketTiers.forEach((tier) => {
28
+ const ticketListNumAndDate = ticketList.get(tier.id);
29
+ ticketListNumAndDate?.forEach((numAndDate) => {
30
+ total += tier.price * (numAndDate.numberOfTickets ?? 0);
31
+ });
32
+ });
33
+ return total;
34
+ }
35
+ export function convertCentsToDollars(price) {
36
+ if (!price) {
37
+ return 0;
38
+ }
39
+ return price / PRICE_DOLLARS_AND_CENTS_RATIO;
40
+ }
41
+ export function convertDollarsToCents(price) {
42
+ if (!price) {
43
+ return 0;
44
+ }
45
+ return price * PRICE_DOLLARS_AND_CENTS_RATIO;
46
+ }
47
+ export function calculateBashAppFee(total) {
48
+ return parseFloat((total * BASH_FEE_PERCENTAGE).toFixed(2));
49
+ }
50
+ //# sourceMappingURL=paymentUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paymentUtils.js","sourceRoot":"","sources":["../../src/utils/paymentUtils.ts"],"names":[],"mappings":"AACA,OAAO,EACL,mBAAmB,EAEnB,6BAA6B,GAC9B,MAAM,gBAAgB,CAAC;AAExB;;;;GAIG;AACH,MAAM,UAAU,8BAA8B,CAC5C,cAAsB,EACtB,SAAyC;IAEzC,IAAI,SAAS,EAAE,CAAC;QACd,IAAI,SAAS,CAAC,qBAAqB,EAAE,CAAC;YACpC,MAAM,iBAAiB,GAAG,qBAAqB,CAC7C,SAAS,CAAC,qBAAqB,CAChC,CAAC;YACF,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,iBAAiB,CAAC,CAAC,CAAC,0CAA0C;QACnF,CAAC;QACD,IAAI,SAAS,CAAC,wBAAwB,EAAE,CAAC;YACvC,MAAM,iBAAiB,GACrB,cAAc,GAAG,CAAC,SAAS,CAAC,wBAAwB,GAAG,GAAG,CAAC,CAAC;YAC9D,OAAO,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE,iBAAiB,CAAC,CAAC,CAAC,0CAA0C;QAChG,CAAC;IACH,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,6BAA6B,CAC3C,WAAyB,EACzB,UAAiD;IAEjD,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,WAAW,CAAC,OAAO,CAAC,CAAC,IAAgB,EAAE,EAAE;QACvC,MAAM,oBAAoB,GAAG,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACrD,oBAAoB,EAAE,OAAO,CAAC,CAAC,UAAkC,EAAE,EAAE;YACnE,KAAK,IAAI,IAAI,CAAC,KAAK,GAAG,CAAC,UAAU,CAAC,eAAe,IAAI,CAAC,CAAC,CAAC;QAC1D,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IACH,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,qBAAqB,CACnC,KAAgC;IAEhC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,CAAC,CAAC;IACX,CAAC;IACD,OAAO,KAAK,GAAG,6BAA6B,CAAC;AAC/C,CAAC;AACD,MAAM,UAAU,qBAAqB,CACnC,KAAgC;IAEhC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,CAAC,CAAC;IACX,CAAC;IACD,OAAO,KAAK,GAAG,6BAA6B,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,KAAa;IAC/C,OAAO,UAAU,CAAC,CAAC,KAAK,GAAG,mBAAmB,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9D,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { BashEventExt } from "../extendedSchemas";
2
+ import { BashEventPromoCode } from "@prisma/client";
3
+ export declare function findPromoCodeFromBashEvent(bashEvent: BashEventExt | undefined | null, promoCodeId: string | undefined): BashEventPromoCode | undefined;
4
+ export declare function getPromoCodesFromBashEvent(bashEvent: BashEventExt | undefined | null): BashEventPromoCode[];
5
+ export declare function updatePromoCodesOnBashEventTicketTiers(bashEvent: BashEventExt, promoCodes: BashEventPromoCode[]): void;
6
+ //# sourceMappingURL=promoCodesUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promoCodesUtils.d.ts","sourceRoot":"","sources":["../../src/utils/promoCodesUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,YAAY,EAAgB,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAC,kBAAkB,EAAC,MAAM,gBAAgB,CAAC;AAGlD,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,YAAY,GAAG,SAAS,GAAG,IAAI,EAC1C,WAAW,EAAE,MAAM,GAAG,SAAS,GAAG,kBAAkB,GAAG,SAAS,CAY1G;AAED,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,YAAY,GAAG,SAAS,GAAG,IAAI,GAAG,kBAAkB,EAAE,CAG3G;AAED,wBAAgB,sCAAsC,CAAC,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,kBAAkB,EAAE,GAAG,IAAI,CAItH"}
@@ -0,0 +1,23 @@
1
+ export function findPromoCodeFromBashEvent(bashEvent, promoCodeId) {
2
+ if (!promoCodeId) {
3
+ return;
4
+ }
5
+ if (bashEvent?.ticketTiers?.length) {
6
+ for (const tier of bashEvent?.ticketTiers) {
7
+ const foundPromoCode = tier.promoCodes.find((promoCode) => promoCode.id === promoCodeId);
8
+ if (foundPromoCode) {
9
+ return foundPromoCode;
10
+ }
11
+ }
12
+ }
13
+ }
14
+ export function getPromoCodesFromBashEvent(bashEvent) {
15
+ const ticketTiersWithPromoCode = bashEvent?.ticketTiers?.filter(ticketTier => ticketTier?.promoCodes?.length) ?? [];
16
+ return ticketTiersWithPromoCode.map(ticketTier => ticketTier.promoCodes).flat() ?? [];
17
+ }
18
+ export function updatePromoCodesOnBashEventTicketTiers(bashEvent, promoCodes) {
19
+ bashEvent.ticketTiers?.forEach((tier) => {
20
+ tier.promoCodes = promoCodes.filter((pc) => tier.id === pc.ticketTierId);
21
+ });
22
+ }
23
+ //# sourceMappingURL=promoCodesUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promoCodesUtils.js","sourceRoot":"","sources":["../../src/utils/promoCodesUtils.ts"],"names":[],"mappings":"AAIA,MAAM,UAAU,0BAA0B,CAAC,SAA0C,EAC1C,WAA+B;IACxE,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO;IACT,CAAC;IACD,IAAI,SAAS,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC;QACnC,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,WAAW,EAAE,CAAC;YAC1C,MAAM,cAAc,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,KAAK,WAAW,CAAC,CAAC;YACzF,IAAI,cAAc,EAAE,CAAC;gBACnB,OAAO,cAAc,CAAC;YACxB,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,SAA0C;IACnF,MAAM,wBAAwB,GAAoB,SAAS,EAAE,WAAW,EAAE,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,UAAU,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;IACrI,OAAO,wBAAwB,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,IAAI,EAA0B,IAAI,EAAE,CAAC;AAChH,CAAC;AAED,MAAM,UAAU,sCAAsC,CAAC,SAAuB,EAAE,UAAgC;IAC9G,SAAS,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;QACtC,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,YAAY,CAAC,CAAC;IAC3E,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,4 @@
1
+ export declare function bashEventPrismaCheckoutQrCodeUrl(bashEventId: string | undefined | null, prismaCheckoutId: string | undefined | null): string;
2
+ export declare function bashEventQrCodeUrl(bashEventId: string | undefined | null, ticketTierId?: string | undefined | null, ticketId?: string | undefined | null, slug?: string | undefined | null): string;
3
+ export declare function createQrCodeImage(qrData: string): Promise<string>;
4
+ //# sourceMappingURL=qrCodeUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qrCodeUtils.d.ts","sourceRoot":"","sources":["../../src/utils/qrCodeUtils.ts"],"names":[],"mappings":"AAIA,wBAAgB,gCAAgC,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,EAAE,gBAAgB,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,CAE5I;AAED,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,CAUnM;AAED,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAIvE"}
@@ -0,0 +1,22 @@
1
+ import QRCode from "qrcode";
2
+ import { TICKET_DETAILS } from "../definitions";
3
+ import { generateBashDetailUrl } from "./slugUtils";
4
+ export function bashEventPrismaCheckoutQrCodeUrl(bashEventId, prismaCheckoutId) {
5
+ return `${TICKET_DETAILS}/${bashEventId}/${prismaCheckoutId}`;
6
+ }
7
+ export function bashEventQrCodeUrl(bashEventId, ticketTierId, ticketId, slug) {
8
+ const baseUrl = slug ? generateBashDetailUrl(bashEventId, slug).replace('/bash/', '/ticket-details/') : `${TICKET_DETAILS}/${bashEventId}`;
9
+ if (ticketId) {
10
+ return `${baseUrl}/ticket/${ticketId}`;
11
+ }
12
+ else if (ticketTierId) {
13
+ return `${baseUrl}/ticket-tier/${ticketTierId}`;
14
+ }
15
+ return baseUrl;
16
+ }
17
+ export async function createQrCodeImage(qrData) {
18
+ return QRCode.toDataURL(qrData, {
19
+ errorCorrectionLevel: 'high',
20
+ });
21
+ }
22
+ //# sourceMappingURL=qrCodeUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qrCodeUtils.js","sourceRoot":"","sources":["../../src/utils/qrCodeUtils.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAEpD,MAAM,UAAU,gCAAgC,CAAC,WAAsC,EAAE,gBAA2C;IAClI,OAAO,GAAG,cAAc,IAAI,WAAW,IAAI,gBAAgB,EAAE,CAAC;AAChE,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,WAAsC,EAAE,YAAwC,EAAE,QAAoC,EAAE,IAAgC;IACzL,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,qBAAqB,CAAC,WAAY,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,kBAAkB,CAAC,CAAC,CAAC,CAAC,GAAG,cAAc,IAAI,WAAW,EAAE,CAAC;IAE5I,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,GAAG,OAAO,WAAW,QAAQ,EAAE,CAAC;IACzC,CAAC;SACI,IAAI,YAAY,EAAE,CAAC;QACtB,OAAO,GAAG,OAAO,gBAAgB,YAAY,EAAE,CAAC;IAClD,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,MAAc;IACpD,OAAO,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE;QAC9B,oBAAoB,EAAE,MAAM;KAC7B,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { Recurrence, RecurringFrequency } from "@prisma/client";
2
+ import { DateTime } from "luxon";
3
+ import { DateTimeArgType } from "../definitions";
4
+ export declare function getRecurringBashEventPossibleDateTimes(startDateTime: DateTimeArgType, recurrence: Recurrence | undefined | null): Date[];
5
+ export declare function getRecurringBashEventPossibleDayjsTimes(startDateTime: DateTimeArgType, recurrence: Recurrence | undefined | null): DateTime[];
6
+ export declare function freqToGrammarString(freq: RecurringFrequency, interval: number | undefined, toLowerCase?: boolean): string;
7
+ export declare function findEarliestPossibleBashEventDate(startDateTimeArg: DateTimeArgType): DateTime | undefined;
8
+ //# sourceMappingURL=recurrenceUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recurrenceUtils.d.ts","sourceRoot":"","sources":["../../src/utils/recurrenceUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,UAAU,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAC3E,OAAO,EAAE,QAAQ,EAAkB,MAAM,OAAO,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAGjD,wBAAgB,sCAAsC,CAAC,aAAa,EAAE,eAAe,EAC9B,UAAU,EAAE,UAAU,GAAG,SAAS,GAAG,IAAI,GAAG,IAAI,EAAE,CAExG;AAED,wBAAgB,uCAAuC,CAAC,aAAa,EAAE,eAAe,EAC9B,UAAU,EAAE,UAAU,GAAG,SAAS,GAAG,IAAI,GAAG,QAAQ,EAAE,CAE7G;AAqHD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,WAAW,GAAE,OAAe,GAAG,MAAM,CAqBhI;AAED,wBAAgB,iCAAiC,CAAC,gBAAgB,EAAE,eAAe,GAAG,QAAQ,GAAG,SAAS,CAEzG"}
@@ -0,0 +1,153 @@
1
+ import { DayOfWeek, RecurringFrequency } from "@prisma/client";
2
+ import { DateTime } from "luxon";
3
+ import { compareDateTime, DATETIME_FORMAT_ISO_LIKE } from "./dateTimeUtils";
4
+ export function getRecurringBashEventPossibleDateTimes(startDateTime, recurrence) {
5
+ return getRecurringBashEventPossibleDatesTimesInternal(startDateTime, recurrence, true);
6
+ }
7
+ export function getRecurringBashEventPossibleDayjsTimes(startDateTime, recurrence) {
8
+ return getRecurringBashEventPossibleDatesTimesInternal(startDateTime, recurrence, false);
9
+ }
10
+ function getRecurringBashEventPossibleDatesTimesInternal(startDateTime, recurrence, toDate) {
11
+ if (!recurrence || !recurrence.frequency || recurrence.frequency === RecurringFrequency.Never) {
12
+ return [];
13
+ }
14
+ let recurrenceDates = [];
15
+ const beginningDate = findEarliestPossibleBashEventDate(startDateTime); // Don't allow dates before the current date
16
+ switch (recurrence.frequency) {
17
+ case RecurringFrequency.Weekly:
18
+ recurrenceDates = getWeeklyRecurringDates(beginningDate, recurrence);
19
+ break;
20
+ default:
21
+ console.error(`Only weekly frequency is currently supported`);
22
+ }
23
+ return recurrenceDates.map((date) => date.toFormat(DATETIME_FORMAT_ISO_LIKE))
24
+ .sort()
25
+ .map((dateStr) => {
26
+ const luxonDate = DateTime.fromFormat(dateStr, DATETIME_FORMAT_ISO_LIKE);
27
+ if (toDate) {
28
+ return luxonDate.toJSDate();
29
+ }
30
+ else {
31
+ return luxonDate;
32
+ }
33
+ });
34
+ }
35
+ /**
36
+ * Get the weekly recurring dates
37
+ * @param beginningDateTime The beginning DateTime of the event, adjusted to be no earlier than now.
38
+ * @param recurrence
39
+ */
40
+ function getWeeklyRecurringDates(beginningDateTime, recurrence) {
41
+ if (recurrence.frequency !== RecurringFrequency.Weekly) {
42
+ throw new Error(`Cannot do a weekly recurrence if the frequency isn't weekly.`);
43
+ }
44
+ const interval = recurrence.interval ?? 1;
45
+ const recurrenceEnds = DateTime.fromJSDate(new Date(recurrence.ends || '')).endOf('day'); // Get the end of the day to not miss the last day
46
+ const numberOfDays = recurrenceEnds.diff(beginningDateTime, 'days').days;
47
+ const numberOfWeeks = Math.ceil((numberOfDays / 7) / interval); // Get the number of days and then round up so that we include the ending date
48
+ const recurrenceDates = [];
49
+ let theNextWeekOfRecurrences = beginningDateTime;
50
+ // Go week by week getting the next recurrence date
51
+ for (let i = 0; i < numberOfWeeks; i++) {
52
+ let weekday = null;
53
+ for (const dayOfWeekEnum of recurrence.repeatOnDays) {
54
+ const dayOfWeekNum = dayOfWeekEnumToDayNumber(dayOfWeekEnum);
55
+ weekday = theNextWeekOfRecurrences.set({ weekday: dayOfWeekNum });
56
+ if (weekday > recurrenceEnds || weekday < beginningDateTime) {
57
+ continue; // Continue because repeatOnDays isn't sorted by the day of the week
58
+ }
59
+ // Set the time on the date so that it matches the time when the event starts
60
+ weekday = copyTimeToDate(beginningDateTime, weekday);
61
+ recurrenceDates.push(weekday);
62
+ }
63
+ if (weekday) {
64
+ theNextWeekOfRecurrences = getBeginningOfWeekInterval(weekday, interval);
65
+ }
66
+ }
67
+ return recurrenceDates;
68
+ }
69
+ function copyTimeToDate(dateWithTimeToCopy, dateWhoseTimeToChange) {
70
+ if (dateWithTimeToCopy.second !== 0) {
71
+ console.warn(`dateWithTimeToCopy has non-zero seconds: ${dateWithTimeToCopy.toString()} \nFixing...`);
72
+ dateWithTimeToCopy = dateWithTimeToCopy.set({ second: 0 });
73
+ }
74
+ return dateWhoseTimeToChange.set({
75
+ hour: dateWithTimeToCopy.hour,
76
+ minute: dateWithTimeToCopy.minute,
77
+ second: 0
78
+ });
79
+ }
80
+ function dayOfWeekEnumToDayNumber(dayEnum) {
81
+ switch (dayEnum) {
82
+ case DayOfWeek.Sunday:
83
+ return 7; // Luxon uses 1-7 where 7 is Sunday
84
+ case DayOfWeek.Monday:
85
+ return 1;
86
+ case DayOfWeek.Tuesday:
87
+ return 2;
88
+ case DayOfWeek.Wednesday:
89
+ return 3;
90
+ case DayOfWeek.Thursday:
91
+ return 4;
92
+ case DayOfWeek.Friday:
93
+ return 5;
94
+ case DayOfWeek.Saturday:
95
+ return 6;
96
+ default:
97
+ throw new Error(`How did this happen? Invalid DayOfWeek: ${dayEnum}`); // Shouldn't happen
98
+ }
99
+ }
100
+ /**
101
+ * Get the next week determined by the interval by going to the end of the week interval and adding one day
102
+ * @param date
103
+ * @param interval
104
+ */
105
+ function getBeginningOfWeekInterval(date, interval) {
106
+ if (!interval) {
107
+ interval = 1; // Avoid 0
108
+ }
109
+ // An interval of 2 would be (2 - 1) * 7 + 1 = 8 days to add to skip a week and go into the next week
110
+ const numberOfDaysToAdd = interval > 1 ? (interval - 1) * 7 + 1 : 1;
111
+ return date.endOf('week').plus({ days: numberOfDaysToAdd });
112
+ }
113
+ export function freqToGrammarString(freq, interval, toLowerCase = false) {
114
+ if (!interval) {
115
+ return freq;
116
+ }
117
+ const isPlural = interval > 1;
118
+ let result = freq;
119
+ switch (freq) {
120
+ case RecurringFrequency.Daily:
121
+ result = isPlural ? 'Days' : 'Day';
122
+ break;
123
+ case RecurringFrequency.Weekly:
124
+ result = isPlural ? 'Weeks' : 'Week';
125
+ break;
126
+ case RecurringFrequency.Monthly:
127
+ result = isPlural ? 'Months' : 'Month';
128
+ break;
129
+ case RecurringFrequency.Yearly:
130
+ result = isPlural ? 'Years' : 'Year';
131
+ break;
132
+ }
133
+ return toLowerCase ? result.toLowerCase() : result;
134
+ }
135
+ export function findEarliestPossibleBashEventDate(startDateTimeArg) {
136
+ return findEarliestOrLatestPossibleBashEventDate(startDateTimeArg, true);
137
+ }
138
+ function findEarliestOrLatestPossibleBashEventDate(startDateTimeArg, findEarly) {
139
+ if (!startDateTimeArg) {
140
+ return;
141
+ }
142
+ // Don't allow dates before the current date
143
+ const startDateTime = DateTime.fromJSDate(new Date(startDateTimeArg));
144
+ const currentDateTime = DateTime.local();
145
+ const comparedDateTime = compareDateTime(currentDateTime.toJSDate(), startDateTimeArg);
146
+ if (findEarly) {
147
+ return comparedDateTime > 0 ? currentDateTime : startDateTime;
148
+ }
149
+ else {
150
+ return comparedDateTime < 0 ? currentDateTime : startDateTime;
151
+ }
152
+ }
153
+ //# sourceMappingURL=recurrenceUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recurrenceUtils.js","sourceRoot":"","sources":["../../src/utils/recurrenceUtils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import { Review, ReviewStats } from "../definitions";
2
+ /**
3
+ * Calculate average rating from an array of reviews
4
+ * @param reviews Array of reviews
5
+ * @returns Average rating (1-5)
6
+ */
7
+ export declare const calculateAverageRating: (reviews: Review[]) => number;
8
+ /**
9
+ * Generate review statistics from an array of reviews
10
+ * @param reviews Array of reviews
11
+ * @returns ReviewStats object with distribution and averages
12
+ */
13
+ export declare const generateReviewStats: (reviews: Review[]) => ReviewStats;
14
+ /**
15
+ * Format rating as a string with star emoji
16
+ * @param rating Numeric rating
17
+ * @returns Formatted string (e.g., "4.5 ★★★★½")
18
+ */
19
+ export declare const formatRatingWithStars: (rating: number) => string;
20
+ /**
21
+ * Check if a user is eligible to review an event
22
+ * @param userId User ID
23
+ * @param eventId Event ID
24
+ * @param alreadyReviewed Array of event IDs user has already reviewed
25
+ * @param eventsAttended Array of event IDs user has attended
26
+ * @returns Boolean indicating if user can review the event
27
+ */
28
+ export declare const isEligibleToReview: (userId: string, eventId: string, hostId: string, alreadyReviewed: string[], eventsAttended: string[]) => boolean;
29
+ //# sourceMappingURL=reviewUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reviewUtils.d.ts","sourceRoot":"","sources":["../../src/utils/reviewUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAErD;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,GAAI,SAAS,MAAM,EAAE,KAAG,MAK1D,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,GAAI,SAAS,MAAM,EAAE,KAAG,WAsBvD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,GAAI,QAAQ,MAAM,KAAG,MAQtD,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB,GAC7B,QAAQ,MAAM,EACd,SAAS,MAAM,EACf,QAAQ,MAAM,EACd,iBAAiB,MAAM,EAAE,EACzB,gBAAgB,MAAM,EAAE,KACvB,OAMF,CAAC"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Calculate average rating from an array of reviews
3
+ * @param reviews Array of reviews
4
+ * @returns Average rating (1-5)
5
+ */
6
+ export const calculateAverageRating = (reviews) => {
7
+ if (!reviews.length)
8
+ return 0;
9
+ const sum = reviews.reduce((total, review) => total + review.rating, 0);
10
+ return parseFloat((sum / reviews.length).toFixed(1));
11
+ };
12
+ /**
13
+ * Generate review statistics from an array of reviews
14
+ * @param reviews Array of reviews
15
+ * @returns ReviewStats object with distribution and averages
16
+ */
17
+ export const generateReviewStats = (reviews) => {
18
+ const ratings = {
19
+ 1: 0,
20
+ 2: 0,
21
+ 3: 0,
22
+ 4: 0,
23
+ 5: 0
24
+ };
25
+ // Count each rating level
26
+ reviews.forEach(review => {
27
+ const rating = review.rating;
28
+ if (rating >= 1 && rating <= 5) {
29
+ ratings[rating]++;
30
+ }
31
+ });
32
+ return {
33
+ averageRating: calculateAverageRating(reviews),
34
+ totalRatings: reviews.length,
35
+ ratings
36
+ };
37
+ };
38
+ /**
39
+ * Format rating as a string with star emoji
40
+ * @param rating Numeric rating
41
+ * @returns Formatted string (e.g., "4.5 ★★★★½")
42
+ */
43
+ export const formatRatingWithStars = (rating) => {
44
+ const fullStars = Math.floor(rating);
45
+ const hasHalfStar = rating % 1 >= 0.5;
46
+ let stars = '★'.repeat(fullStars);
47
+ if (hasHalfStar)
48
+ stars += '½';
49
+ return `${rating.toFixed(1)} ${stars}`;
50
+ };
51
+ /**
52
+ * Check if a user is eligible to review an event
53
+ * @param userId User ID
54
+ * @param eventId Event ID
55
+ * @param alreadyReviewed Array of event IDs user has already reviewed
56
+ * @param eventsAttended Array of event IDs user has attended
57
+ * @returns Boolean indicating if user can review the event
58
+ */
59
+ export const isEligibleToReview = (userId, eventId, hostId, alreadyReviewed, eventsAttended) => {
60
+ return (userId !== hostId && // User is not the host
61
+ eventsAttended.includes(eventId) && // User attended the event
62
+ !alreadyReviewed.includes(eventId) // User has not already reviewed the event
63
+ );
64
+ };
65
+ //# sourceMappingURL=reviewUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reviewUtils.js","sourceRoot":"","sources":["../../src/utils/reviewUtils.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,OAAiB,EAAU,EAAE;IAClE,IAAI,CAAC,OAAO,CAAC,MAAM;QAAE,OAAO,CAAC,CAAC;IAE9B,MAAM,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACxE,OAAO,UAAU,CAAC,CAAC,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;AACvD,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,OAAiB,EAAe,EAAE;IACpE,MAAM,OAAO,GAAG;QACd,CAAC,EAAE,CAAC;QACJ,CAAC,EAAE,CAAC;QACJ,CAAC,EAAE,CAAC;QACJ,CAAC,EAAE,CAAC;QACJ,CAAC,EAAE,CAAC;KACL,CAAC;IAEF,0BAA0B;IAC1B,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;QACvB,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QAC7B,IAAI,MAAM,IAAI,CAAC,IAAI,MAAM,IAAI,CAAC,EAAE,CAAC;YAC/B,OAAO,CAAC,MAA8B,CAAC,EAAE,CAAC;QAC5C,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,aAAa,EAAE,sBAAsB,CAAC,OAAO,CAAC;QAC9C,YAAY,EAAE,OAAO,CAAC,MAAM;QAC5B,OAAO;KACR,CAAC;AACJ,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,MAAc,EAAU,EAAE;IAC9D,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACrC,MAAM,WAAW,GAAG,MAAM,GAAG,CAAC,IAAI,GAAG,CAAC;IAEtC,IAAI,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAClC,IAAI,WAAW;QAAE,KAAK,IAAI,GAAG,CAAC;IAE9B,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC;AACzC,CAAC,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAChC,MAAc,EACd,OAAe,EACf,MAAc,EACd,eAAyB,EACzB,cAAwB,EACf,EAAE;IACX,OAAO,CACL,MAAM,KAAK,MAAM,IAAI,uBAAuB;QAC5C,cAAc,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,0BAA0B;QAC9D,CAAC,eAAe,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,0CAA0C;KAC9E,CAAC;AACJ,CAAC,CAAC"}
@@ -0,0 +1,21 @@
1
+ import { ApiBookingParamsLuxon, ApiServiceBookingParams, ApiServiceAddonParams, ApiServiceBookedDayParams, ApiServicePriceToBookResult } from "../../definitions";
2
+ import { ServiceAddonExt, ServiceBookingDayExt, ServiceBookingExt, ServiceExt } from "../../extendedSchemas";
3
+ import { ServiceAddonInput, FrontendServiceGetPriceToBookResult } from "./frontendServiceBookingUtils";
4
+ export type ApiServiceCantBookReason = {
5
+ type: string;
6
+ msg: string;
7
+ };
8
+ export declare const ApiServiceCantBookReasons: {
9
+ readonly notInBusinessHours: ApiServiceCantBookReason;
10
+ readonly minimumTimeBlock: ApiServiceCantBookReason;
11
+ readonly dateBlocked: ApiServiceCantBookReason;
12
+ readonly alreadyBooked: ApiServiceCantBookReason;
13
+ readonly requestDeclined: ApiServiceCantBookReason;
14
+ };
15
+ export type ApiServiceCantBookReasons = keyof typeof ApiServiceCantBookReasons;
16
+ export declare function apiTransformAddOnsToAddonInputs<AddonParams_t extends ApiServiceAddonParams>(addOnsApi: AddonParams_t[], serviceAddons: ServiceAddonExt[]): ServiceAddonInput[];
17
+ export declare function apiTransformBookedDays(priceToBook: ApiServicePriceToBookResult): Partial<ServiceBookingDayExt>[];
18
+ export declare function serviceGetPriceToBookFromBooking(service: ServiceExt, booking: ServiceBookingExt): FrontendServiceGetPriceToBookResult;
19
+ export declare function serviceBookingParamsToLuxon(params: ApiServiceBookingParams): ApiBookingParamsLuxon;
20
+ export declare function servicePriceToBookToApiDays(serviceId: string, userId: string, priceToBook: FrontendServiceGetPriceToBookResult): ApiServiceBookedDayParams[];
21
+ //# sourceMappingURL=apiServiceBookingApiUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apiServiceBookingApiUtils.d.ts","sourceRoot":"","sources":["../../../src/utils/service/apiServiceBookingApiUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,uBAAuB,EAEvB,qBAAqB,EACrB,yBAAyB,EACzB,2BAA2B,EAC5B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,eAAe,EAEf,oBAAoB,EACpB,iBAAiB,EAGjB,UAAU,EACX,MAAM,uBAAuB,CAAC;AAI/B,OAAO,EACL,iBAAiB,EACjB,mCAAmC,EAEpC,MAAM,+BAA+B,CAAC;AAEvC,MAAM,MAAM,wBAAwB,GAAG;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,eAAO,MAAM,yBAAyB;iCAG/B,wBAAwB;+BAGxB,wBAAwB;0BAGxB,wBAAwB;4BAGxB,wBAAwB;8BAGxB,wBAAwB;CACrB,CAAC;AAEX,MAAM,MAAM,yBAAyB,GAAG,MAAM,OAAO,yBAAyB,CAAC;AAE/E,wBAAgB,+BAA+B,CAC7C,aAAa,SAAS,qBAAqB,EAE3C,SAAS,EAAE,aAAa,EAAE,EAC1B,aAAa,EAAE,eAAe,EAAE,GAC/B,iBAAiB,EAAE,CAgBrB;AAED,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,2BAA2B,GACvC,OAAO,CAAC,oBAAoB,CAAC,EAAE,CAiCjC;AAED,wBAAgB,gCAAgC,CAC9C,OAAO,EAAE,UAAU,EACnB,OAAO,EAAE,iBAAiB,GACzB,mCAAmC,CA2CrC;AAED,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,uBAAuB,GAC9B,qBAAqB,CAoBvB;AAED,wBAAgB,2BAA2B,CACzC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,mCAAmC,GAC/C,yBAAyB,EAAE,CAkC7B"}