@bash-app/bash-common 30.408.0 → 30.413.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 (78) hide show
  1. package/dist/__tests__/partnerDealflow.test.d.ts +2 -0
  2. package/dist/__tests__/partnerDealflow.test.d.ts.map +1 -0
  3. package/dist/__tests__/partnerDealflow.test.js +51 -0
  4. package/dist/__tests__/partnerDealflow.test.js.map +1 -0
  5. package/dist/__tests__/partnerRevenueShareOptIn.test.d.ts +2 -0
  6. package/dist/__tests__/partnerRevenueShareOptIn.test.d.ts.map +1 -0
  7. package/dist/__tests__/partnerRevenueShareOptIn.test.js +55 -0
  8. package/dist/__tests__/partnerRevenueShareOptIn.test.js.map +1 -0
  9. package/dist/__tests__/reservedCustomBashEventType.test.d.ts +2 -0
  10. package/dist/__tests__/reservedCustomBashEventType.test.d.ts.map +1 -0
  11. package/dist/__tests__/reservedCustomBashEventType.test.js +19 -0
  12. package/dist/__tests__/reservedCustomBashEventType.test.js.map +1 -0
  13. package/dist/__tests__/serviceListingDealPreferences.test.d.ts +2 -0
  14. package/dist/__tests__/serviceListingDealPreferences.test.d.ts.map +1 -0
  15. package/dist/__tests__/serviceListingDealPreferences.test.js +84 -0
  16. package/dist/__tests__/serviceListingDealPreferences.test.js.map +1 -0
  17. package/dist/__tests__/statusEnums.test.js +1 -0
  18. package/dist/__tests__/statusEnums.test.js.map +1 -1
  19. package/dist/definitions.d.ts +7 -0
  20. package/dist/definitions.d.ts.map +1 -1
  21. package/dist/definitions.js +42 -0
  22. package/dist/definitions.js.map +1 -1
  23. package/dist/extendedSchemas.d.ts +101 -1
  24. package/dist/extendedSchemas.d.ts.map +1 -1
  25. package/dist/extendedSchemas.js +31 -0
  26. package/dist/extendedSchemas.js.map +1 -1
  27. package/dist/homepageSyntheticRows.d.ts +9 -0
  28. package/dist/homepageSyntheticRows.d.ts.map +1 -0
  29. package/dist/homepageSyntheticRows.js +26 -0
  30. package/dist/homepageSyntheticRows.js.map +1 -0
  31. package/dist/index.d.ts +4 -0
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/index.js +4 -0
  34. package/dist/index.js.map +1 -1
  35. package/dist/membershipDefinitions.d.ts +2 -0
  36. package/dist/membershipDefinitions.d.ts.map +1 -1
  37. package/dist/membershipDefinitions.js +2 -0
  38. package/dist/membershipDefinitions.js.map +1 -1
  39. package/dist/mirroredPrismaEnums.d.ts +1 -0
  40. package/dist/mirroredPrismaEnums.d.ts.map +1 -1
  41. package/dist/mirroredPrismaEnums.js +1 -0
  42. package/dist/mirroredPrismaEnums.js.map +1 -1
  43. package/dist/utils/__tests__/slugUtils.test.js +4 -4
  44. package/dist/utils/__tests__/slugUtils.test.js.map +1 -1
  45. package/dist/utils/service/partnerDealflow.d.ts +12 -0
  46. package/dist/utils/service/partnerDealflow.d.ts.map +1 -0
  47. package/dist/utils/service/partnerDealflow.js +33 -0
  48. package/dist/utils/service/partnerDealflow.js.map +1 -0
  49. package/dist/utils/service/partnerRevenueShareOptIn.d.ts +18 -0
  50. package/dist/utils/service/partnerRevenueShareOptIn.d.ts.map +1 -0
  51. package/dist/utils/service/partnerRevenueShareOptIn.js +46 -0
  52. package/dist/utils/service/partnerRevenueShareOptIn.js.map +1 -0
  53. package/dist/utils/service/serviceListingDealPreferences.d.ts +28 -0
  54. package/dist/utils/service/serviceListingDealPreferences.d.ts.map +1 -0
  55. package/dist/utils/service/serviceListingDealPreferences.js +126 -0
  56. package/dist/utils/service/serviceListingDealPreferences.js.map +1 -0
  57. package/dist/utils/slugUtils.d.ts +4 -1
  58. package/dist/utils/slugUtils.d.ts.map +1 -1
  59. package/dist/utils/slugUtils.js +8 -2
  60. package/dist/utils/slugUtils.js.map +1 -1
  61. package/package.json +5 -2
  62. package/prisma/schema.prisma +69 -0
  63. package/src/__tests__/partnerDealflow.test.ts +62 -0
  64. package/src/__tests__/partnerRevenueShareOptIn.test.ts +68 -0
  65. package/src/__tests__/reservedCustomBashEventType.test.ts +27 -0
  66. package/src/__tests__/serviceListingDealPreferences.test.ts +112 -0
  67. package/src/__tests__/statusEnums.test.ts +1 -0
  68. package/src/definitions.ts +53 -0
  69. package/src/extendedSchemas.ts +60 -0
  70. package/src/homepageSyntheticRows.ts +32 -0
  71. package/src/index.ts +4 -0
  72. package/src/membershipDefinitions.ts +2 -0
  73. package/src/mirroredPrismaEnums.ts +1 -0
  74. package/src/utils/__tests__/slugUtils.test.ts +4 -3
  75. package/src/utils/service/partnerDealflow.ts +47 -0
  76. package/src/utils/service/partnerRevenueShareOptIn.ts +70 -0
  77. package/src/utils/service/serviceListingDealPreferences.ts +184 -0
  78. package/src/utils/slugUtils.ts +12 -1
@@ -0,0 +1,184 @@
1
+ import type { ServiceExt } from "../../extendedSchemas";
2
+ import {
3
+ readPartnerDealflowFields,
4
+ serviceListingOpenToInKindDeal,
5
+ } from "./partnerDealflow.js";
6
+ import {
7
+ readPartnerRevenueShareFields,
8
+ REVENUE_SHARE_WITH_HOST_BASIS_LABEL,
9
+ serviceListingOpenToRevenueShare,
10
+ type RevenueShareWithHostBasis,
11
+ } from "./partnerRevenueShareOptIn.js";
12
+
13
+ export type ServiceListingDealBadge = {
14
+ id: string;
15
+ label: string;
16
+ };
17
+
18
+ export type ServiceListingDealDetailRow = {
19
+ label: string;
20
+ value: string;
21
+ };
22
+
23
+ function formatUsdFromCents(cents: number): string {
24
+ const dollars = cents / 100;
25
+ return dollars % 1 === 0 ? `$${dollars.toFixed(0)}` : `$${dollars.toFixed(2)}`;
26
+ }
27
+
28
+ function minimumCashLabel(deal: ReturnType<typeof readPartnerDealflowFields>): string | null {
29
+ if (deal?.dealRequiresMinimumCash !== true) return null;
30
+ if (typeof deal.dealMinimumCashCents !== "number" || deal.dealMinimumCashCents <= 0) {
31
+ return null;
32
+ }
33
+ return `${formatUsdFromCents(deal.dealMinimumCashCents)} min cash`;
34
+ }
35
+
36
+ function truncateOffer(text: string, maxLen: number): string {
37
+ const t = text.trim();
38
+ if (t.length <= maxLen) return t;
39
+ return `${t.slice(0, maxLen - 1).trim()}…`;
40
+ }
41
+
42
+ /** Compact chips for cards and list rows. */
43
+ export function getServiceListingDealBadges(
44
+ service: ServiceExt
45
+ ): ServiceListingDealBadge[] {
46
+ const badges: ServiceListingDealBadge[] = [];
47
+ const deal = readPartnerDealflowFields(service);
48
+
49
+ if (serviceListingOpenToRevenueShare(service)) {
50
+ badges.push({ id: "rev-share", label: "Rev share" });
51
+ }
52
+ if (serviceListingOpenToInKindDeal(service)) {
53
+ badges.push({ id: "in-kind", label: "In-kind" });
54
+ }
55
+
56
+ const minCash = minimumCashLabel(deal);
57
+ if (minCash) {
58
+ badges.push({ id: "min-cash", label: minCash });
59
+ }
60
+
61
+ const hostBidOpen =
62
+ service.vendor?.preferences?.openToHostBids === true ||
63
+ service.exhibitor?.openToHostBids === true ||
64
+ service.sponsor?.openToHostBids === true;
65
+ if (hostBidOpen) {
66
+ badges.push({ id: "host-bids", label: "Host bids" });
67
+ }
68
+
69
+ return badges;
70
+ }
71
+
72
+ /** Longer copy for public detail pages. */
73
+ export function getServiceListingDealDetailRows(
74
+ service: ServiceExt
75
+ ): ServiceListingDealDetailRow[] {
76
+ const rows: ServiceListingDealDetailRow[] = [];
77
+ const deal = readPartnerDealflowFields(service);
78
+ const rev = readPartnerRevenueShareFields(service);
79
+ const venue = service.venue;
80
+
81
+ if (venue?.revenueShareEnabled === true && venue.revenueShareHostPercentage != null) {
82
+ rows.push({
83
+ label: "Venue revenue share",
84
+ value: `Host keeps ${venue.revenueShareHostPercentage}% of agreed ticket or bar revenue.`,
85
+ });
86
+ } else if (rev?.openToRevenueShareWithHost === true) {
87
+ const pct = rev.revenueShareWithHostPercentage;
88
+ const basis = rev.revenueShareWithHostBasis as RevenueShareWithHostBasis | null;
89
+ const basisLabel =
90
+ basis && basis in REVENUE_SHARE_WITH_HOST_BASIS_LABEL
91
+ ? REVENUE_SHARE_WITH_HOST_BASIS_LABEL[basis]
92
+ : null;
93
+ rows.push({
94
+ label: "Revenue share with host",
95
+ value:
96
+ typeof pct === "number"
97
+ ? `Shares ${pct}% with the host${basisLabel ? ` (${basisLabel.toLowerCase()})` : ""}.`
98
+ : "Open to sharing revenue with the host (percentage not set).",
99
+ });
100
+ }
101
+
102
+ if (serviceListingOpenToInKindDeal(service) && deal?.inKindDealOfferText) {
103
+ const est =
104
+ typeof deal.inKindEstimatedValueCents === "number" &&
105
+ deal.inKindEstimatedValueCents > 0
106
+ ? ` Approx. value ${formatUsdFromCents(deal.inKindEstimatedValueCents)}.`
107
+ : "";
108
+ rows.push({
109
+ label: "In-kind / trade offer",
110
+ value: `${deal.inKindDealOfferText.trim()}${est}`,
111
+ });
112
+ }
113
+
114
+ const minCash = minimumCashLabel(deal);
115
+ if (minCash) {
116
+ rows.push({
117
+ label: "Minimum cash on hybrid deals",
118
+ value: `Requires ${minCash.replace(" min cash", "")} minimum cash alongside rev-share or in-kind terms so hosts know you're serious.`,
119
+ });
120
+ }
121
+
122
+ return rows;
123
+ }
124
+
125
+ /** Card preview line for in-kind (truncated). */
126
+ export function getServiceListingInKindPreview(
127
+ service: ServiceExt,
128
+ maxLen = 80
129
+ ): string | null {
130
+ const deal = readPartnerDealflowFields(service);
131
+ if (!serviceListingOpenToInKindDeal(service) || !deal?.inKindDealOfferText) {
132
+ return null;
133
+ }
134
+ return truncateOffer(deal.inKindDealOfferText, maxLen);
135
+ }
136
+
137
+ export type PartnerDealflowBookingSnapshot = {
138
+ openToRevenueShareWithHostSnapshot?: boolean;
139
+ revenueShareWithHostPercentageSnapshot?: number | null;
140
+ revenueShareWithHostBasisSnapshot?: string | null;
141
+ openToInKindDealsSnapshot?: boolean;
142
+ inKindDealOfferTextSnapshot?: string | null;
143
+ inKindEstimatedValueCentsSnapshot?: number | null;
144
+ dealRequiresMinimumCashSnapshot?: boolean;
145
+ dealMinimumCashCentsSnapshot?: number | null;
146
+ };
147
+
148
+ /** Copy live listing deal prefs onto a booking at confirmation time. */
149
+ export function buildPartnerDealflowBookingSnapshot(
150
+ service: ServiceExt
151
+ ): PartnerDealflowBookingSnapshot {
152
+ const rev = readPartnerRevenueShareFields(service);
153
+ const deal = readPartnerDealflowFields(service);
154
+ const venue = service.venue;
155
+
156
+ const snap: PartnerDealflowBookingSnapshot = {};
157
+
158
+ if (venue?.revenueShareEnabled === true) {
159
+ snap.openToRevenueShareWithHostSnapshot = true;
160
+ snap.revenueShareWithHostPercentageSnapshot =
161
+ venue.revenueShareHostPercentage ?? null;
162
+ snap.revenueShareWithHostBasisSnapshot = venue.revenueShareBasis ?? null;
163
+ } else if (rev?.openToRevenueShareWithHost === true) {
164
+ snap.openToRevenueShareWithHostSnapshot = true;
165
+ snap.revenueShareWithHostPercentageSnapshot =
166
+ rev.revenueShareWithHostPercentage ?? null;
167
+ snap.revenueShareWithHostBasisSnapshot =
168
+ rev.revenueShareWithHostBasis ?? null;
169
+ }
170
+
171
+ if (deal?.openToInKindDeals === true) {
172
+ snap.openToInKindDealsSnapshot = true;
173
+ snap.inKindDealOfferTextSnapshot = deal.inKindDealOfferText?.trim() ?? null;
174
+ snap.inKindEstimatedValueCentsSnapshot =
175
+ deal.inKindEstimatedValueCents ?? null;
176
+ }
177
+
178
+ if (deal?.dealRequiresMinimumCash === true) {
179
+ snap.dealRequiresMinimumCashSnapshot = true;
180
+ snap.dealMinimumCashCentsSnapshot = deal.dealMinimumCashCents ?? null;
181
+ }
182
+
183
+ return snap;
184
+ }
@@ -1,6 +1,7 @@
1
1
  import * as slugifyImport from "slugify";
2
2
  import {
3
3
  BASH_DETAIL_URL,
4
+ BASH_EVENT_WIZARD_GENERATE_SUBSTEP,
4
5
  BASH_EVENT_WIZARD_HOW_MAJOR_STEP,
5
6
  BASH_EVENT_WIZARD_HOW_SUBSTEP_PAYOUT,
6
7
  BASH_EVENT_WIZARD_MAJOR,
@@ -114,8 +115,18 @@ export function getBashEventWizardPayoutStepPath(bashEventId: string): string {
114
115
  );
115
116
  }
116
117
 
117
- /** Create / resume at Getting Started (Templates). Defaults to the `new` draft. */
118
+ /**
119
+ * New drafts open on Generate (flyer upload + AI).
120
+ * An existing event id still opens Quick bash so resume does not dump hosts into the composer.
121
+ */
118
122
  export function getBashEventWizardStartPath(bashEventId = "new"): string {
123
+ if (bashEventId === "new") {
124
+ return getBashEventWizardStepPath(
125
+ bashEventId,
126
+ BASH_EVENT_WIZARD_MAJOR.GENERATE,
127
+ BASH_EVENT_WIZARD_GENERATE_SUBSTEP.START
128
+ );
129
+ }
119
130
  return getBashEventWizardStepPath(
120
131
  bashEventId,
121
132
  BASH_EVENT_WIZARD_MAJOR.TEMPLATES,