@bash-app/bash-common 30.403.0 → 30.406.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.
@@ -4,7 +4,6 @@ import {
4
4
  Contact,
5
5
  DietaryOption,
6
6
  EntertainmentServiceType,
7
- IncomeRange,
8
7
  JudgingType,
9
8
  MembershipTier,
10
9
  MusicGenreType,
@@ -17,6 +16,7 @@ import {
17
16
  } from "@prisma/client";
18
17
  import type {
19
18
  AgePolicy as AgePolicyEnum,
19
+ IncomeRange,
20
20
  BashPassTier,
21
21
  BashEventDressTags,
22
22
  BashEventVibeTags,
@@ -134,6 +134,109 @@ export const AgePolicy = {
134
134
 
135
135
  export type AgePolicy = AgePolicyEnum;
136
136
 
137
+ export const INTRO_INTENT_OPTIONS = [
138
+ { id: "friends", label: "Making friends" },
139
+ { id: "professional", label: "Professional networking" },
140
+ { id: "mentorship", label: "Finding a mentor or mentee" },
141
+ ] as const;
142
+
143
+ export type IntroIntentId = (typeof INTRO_INTENT_OPTIONS)[number]["id"];
144
+
145
+ export const INTRO_INTENT_IDS: readonly IntroIntentId[] =
146
+ INTRO_INTENT_OPTIONS.map((option) => option.id);
147
+
148
+ export function isIntroIntentId(value: string): value is IntroIntentId {
149
+ return (INTRO_INTENT_IDS as readonly string[]).includes(value);
150
+ }
151
+
152
+ export const LOCUS_OF_CONTROL_OPTIONS = [
153
+ { id: "internal", label: "Internal — I shape my own outcomes" },
154
+ { id: "external", label: "External — circumstances shape outcomes" },
155
+ { id: "mixed", label: "Mixed — bit of both" },
156
+ ] as const;
157
+
158
+ export type LocusOfControlId = (typeof LOCUS_OF_CONTROL_OPTIONS)[number]["id"];
159
+
160
+ export const LOCUS_OF_CONTROL_IDS: readonly LocusOfControlId[] =
161
+ LOCUS_OF_CONTROL_OPTIONS.map((option) => option.id);
162
+
163
+ export function isLocusOfControlId(value: string): value is LocusOfControlId {
164
+ return (LOCUS_OF_CONTROL_IDS as readonly string[]).includes(value);
165
+ }
166
+
167
+ export const PERSONALITY_TYPE_MAX_LENGTH = 4;
168
+
169
+ export function normalizePersonalityType(
170
+ value: string | null | undefined
171
+ ): string | null {
172
+ if (!value) return null;
173
+ const normalized = value
174
+ .toUpperCase()
175
+ .replace(/[^A-Z]/g, "")
176
+ .slice(0, PERSONALITY_TYPE_MAX_LENGTH);
177
+ return normalized.length > 0 ? normalized : null;
178
+ }
179
+
180
+ /** True if two MBTI codes share the same second letter (S/N axis). */
181
+ export function hasSensingIntuitionOverlap(a: string, b: string): boolean {
182
+ return (
183
+ a.length >= 2 &&
184
+ b.length >= 2 &&
185
+ a[1].toUpperCase() === b[1].toUpperCase()
186
+ );
187
+ }
188
+
189
+ export function personalityOverlapHint(
190
+ a: string | null | undefined,
191
+ b: string | null | undefined
192
+ ): string | null {
193
+ if (!a || !b || !hasSensingIntuitionOverlap(a, b)) return null;
194
+ return `You both picked ${a[1].toUpperCase()} — good icebreaker.`;
195
+ }
196
+
197
+ export function sharedIntroIntentHint(
198
+ viewerIntents: readonly string[] | null | undefined,
199
+ guestIntents: readonly string[] | null | undefined
200
+ ): string | null {
201
+ if (!viewerIntents?.length || !guestIntents?.length) return null;
202
+ const guest = new Set(guestIntents);
203
+ const match = viewerIntents.find((id) => guest.has(id));
204
+ if (!match || !isIntroIntentId(match)) return null;
205
+ const label = INTRO_INTENT_OPTIONS.find((option) => option.id === match)?.label;
206
+ return label ? `You're both here for ${label.toLowerCase()}.` : null;
207
+ }
208
+
209
+ export function locusOfControlShortLabel(
210
+ id: string | null | undefined
211
+ ): string | null {
212
+ if (!id || !isLocusOfControlId(id)) return null;
213
+ if (id === "internal") return "Internal";
214
+ if (id === "external") return "External";
215
+ return "Mixed";
216
+ }
217
+
218
+ export const INTEREST_EXPRESSION_MODES = ["named", "anonymous"] as const;
219
+
220
+ export type InterestExpressionMode = (typeof INTEREST_EXPRESSION_MODES)[number];
221
+
222
+ export function isInterestExpressionMode(
223
+ value: string
224
+ ): value is InterestExpressionMode {
225
+ return (INTEREST_EXPRESSION_MODES as readonly string[]).includes(value);
226
+ }
227
+
228
+ export const INTROS_DISCLAIMER =
229
+ "Intros connects you only with people who have also explicitly opted in. Bash does not conduct background checks, verify identities beyond basic account registration, or screen users for any purpose. This feature supports platonic and professional connections only — romantic or sexual contact is a violation of our Community Guidelines. Always meet at the event, in public. Use the Report button if anyone makes you uncomfortable. By turning on Intros, you agree that Bash is not responsible for interactions between users.";
230
+
231
+ export const INTROS_DISCLAIMER_SHORT =
232
+ "Bash does not background-check users. Meet at the event, in public. Romantic or sexual contact is prohibited. Bash is not responsible for interactions between users.";
233
+
234
+ /** @deprecated Use INTROS_DISCLAIMER */
235
+ export const SCENE_INTROS_DISCLAIMER = INTROS_DISCLAIMER;
236
+
237
+ /** @deprecated Use INTROS_DISCLAIMER_SHORT */
238
+ export const SCENE_INTROS_DISCLAIMER_SHORT = INTROS_DISCLAIMER_SHORT;
239
+
137
240
  export const PASSWORD_MIN_LENGTH = 8 as const;
138
241
  export const PASSWORD_REQUIREMENTS_REGEX = new RegExp(
139
242
  String.raw`^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&^#])[A-Za-z\d@$!%*?&^#]{${PASSWORD_MIN_LENGTH},}$`
@@ -1366,6 +1469,8 @@ export interface StripeConfirmPaymentResult {
1366
1469
  ticketsSubtotalCents?: number;
1367
1470
  /** Actual amount charged to the guest (cents), including pass-through fees when applicable */
1368
1471
  totalPaidCents?: number;
1472
+ /** True when this is the buyer's first ticket purchase on Bash ever. */
1473
+ isFirstTicketPurchase?: boolean;
1369
1474
  }
1370
1475
 
1371
1476
  export interface IMediaUploadArgs {
@@ -1649,96 +1754,101 @@ export type BashEventTypeToStringType = {
1649
1754
  [key in BashEventType]: string;
1650
1755
  };
1651
1756
  export { BashEventType };
1757
+ /**
1758
+ * Keys are string literals (not `BashEventType.*`) so this module can load
1759
+ * when Jest's `@prisma/client` cache is briefly incomplete after resetModules
1760
+ * (see api/jest.setup.afterEnv.cjs). Same pattern as SERVICE_TYPE_LABELS.
1761
+ */
1652
1762
  export const BashEventTypeToString: BashEventTypeToStringType = {
1653
- [BashEventType.AfterParty]: "After-Party",
1654
- [BashEventType.AnniversaryCelebration]: "Anniversary Celebration",
1655
- [BashEventType.ArtAndCraftNight]: "Art and Craft Night",
1656
- [BashEventType.ArtExhibitOpening]: "Art Exhibit Opening",
1657
- [BashEventType.BBQCookout]: "BBQ Cookout",
1658
- [BashEventType.BabyShower]: "Baby Shower",
1659
- [BashEventType.BachelorParty]: "Bachelor Party",
1660
- [BashEventType.BacheloretteParty]: "Bachelorette Party",
1661
- [BashEventType.BeachParty]: "Beach Party",
1662
- [BashEventType.Birthday]: "Birthday",
1663
- [BashEventType.BoatParty]: "Boat Party",
1664
- [BashEventType.Bonfire]: "Bonfire",
1665
- [BashEventType.BridalShower]: "Bridal Shower",
1666
- [BashEventType.BrunchGathering]: "Brunch Gathering",
1667
- [BashEventType.CarShow]: "Car Show",
1668
- [BashEventType.Carnival]: "Carnival",
1669
- [BashEventType.CasinoNight]: "Casino Night",
1670
- [BashEventType.CasualMixer]: "Casual Mixer",
1671
- [BashEventType.CharityGala]: "Charity Gala",
1672
- [BashEventType.ChristmasParty]: "Christmas Party",
1673
- [BashEventType.ChurchEvent]: "Church Event",
1674
- [BashEventType.CitySponsored]: "City-Sponsored Event",
1675
- [BashEventType.CocktailParty]: "Cocktail Party",
1676
- [BashEventType.CollegeParty]: "College Party",
1677
- [BashEventType.ComedyShow]: "Comedy Show",
1678
- [BashEventType.Concert]: "Concert",
1679
- [BashEventType.Conference]: "Conference",
1680
- [BashEventType.Convention]: "Convention",
1681
- [BashEventType.CorporateEvent]: "Corporate Event",
1682
- [BashEventType.Cruise]: "Cruise",
1683
- [BashEventType.DanceParty]: "Dance Party",
1684
- [BashEventType.DiscoNight]: "Disco Night",
1685
- [BashEventType.EasterGathering]: "Easter Gathering",
1686
- [BashEventType.EngagementParty]: "Engagement Party",
1687
- [BashEventType.Fair]: "Fair",
1688
- [BashEventType.FarewellParty]: "Farewell Party",
1689
- [BashEventType.FashionShow]: "Fashion Show",
1690
- [BashEventType.Festival]: "Festival",
1691
- [BashEventType.FestivalFilm]: "Film Festival",
1692
- [BashEventType.FestivalFood]: "Food Festival",
1693
- [BashEventType.Fundraiser]: "Fundraiser",
1694
- [BashEventType.GameNight]: "Game Night",
1695
- [BashEventType.GamingEvent]: "Gaming Event",
1696
- [BashEventType.GardenParty]: "Garden Party",
1697
- [BashEventType.GraduationParty]: "Graduation Party",
1698
- [BashEventType.HalloweenParty]: "Halloween Party",
1699
- [BashEventType.HanukkahParty]: "Hanukkah Party",
1700
- [BashEventType.HolidayParty]: "Holiday Party",
1701
- [BashEventType.HouseParty]: "House Party",
1702
- [BashEventType.HousewarmingParty]: "Housewarming Party",
1703
- [BashEventType.KaraokeNight]: "Karaoke Night",
1704
- [BashEventType.LaunchParty]: "Launch Party",
1705
- [BashEventType.LuxuryRetreat]: "Luxury Retreat",
1706
- [BashEventType.MansionParty]: "Mansion Party",
1707
- [BashEventType.MardiGras]: "Mardi Gras",
1708
- [BashEventType.Memorial]: "Memorial",
1709
- [BashEventType.MovieNight]: "Movie Night",
1710
- [BashEventType.MoviePremiere]: "Movie Premiere",
1711
- [BashEventType.MusicFestival]: "Music Festival",
1712
- [BashEventType.NewYearsEveCelebration]: "New Year's Eve Celebration",
1713
- [BashEventType.OfficeParty]: "Office Party",
1714
- [BashEventType.OpenMicNight]: "Open Mic Night",
1715
- [BashEventType.OutdoorActivity]: "Outdoor Activity",
1716
- [BashEventType.Parade]: "Parade",
1717
- [BashEventType.Party]: "Party",
1718
- [BashEventType.PoolParty]: "Pool Party",
1719
- [BashEventType.Potluck]: "Potluck",
1720
- [BashEventType.PreParty]: "Pre-Party",
1721
- [BashEventType.ProfessionalNetworkingEvent]: "Professional Networking Event",
1722
- [BashEventType.PubCrawl]: "Pub Crawl",
1723
- [BashEventType.Rave]: "Rave",
1724
- [BashEventType.RetirementCelebration]: "Retirement Celebration",
1725
- [BashEventType.Reunion]: "Reunion",
1726
- [BashEventType.SchoolEvent]: "School Event",
1727
- [BashEventType.SocialClubEvent]: "Social Club Event",
1728
- [BashEventType.SportsWatchParty]: "Sports Watch Party",
1729
- [BashEventType.ThanksgivingDinner]: "Thanksgiving Dinner",
1730
- [BashEventType.ThemedDinnerParty]: "Themed Dinner Party",
1731
- [BashEventType.ThemedParty]: "Themed Party",
1732
- [BashEventType.ThemedPubCrawl]: "Themed Pub Crawl",
1733
- [BashEventType.Tournament]: "Tournament",
1734
- [BashEventType.TradeShow]: "Trade Show",
1735
- [BashEventType.TriviaNight]: "Trivia Night",
1736
- [BashEventType.ValentinesDayParty]: "Valentine's Day Party",
1737
- [BashEventType.WeddingReception]: "Wedding Reception",
1738
- [BashEventType.WelcomeHomeParty]: "Welcome Home Party",
1739
- [BashEventType.WineTastingEvent]: "Wine Tasting Event",
1740
- [BashEventType.Workshop]: "Workshop",
1741
- [BashEventType.Other]: "Other",
1763
+ AfterParty: "After-Party",
1764
+ AnniversaryCelebration: "Anniversary Celebration",
1765
+ ArtAndCraftNight: "Art and Craft Night",
1766
+ ArtExhibitOpening: "Art Exhibit Opening",
1767
+ BBQCookout: "BBQ Cookout",
1768
+ BabyShower: "Baby Shower",
1769
+ BachelorParty: "Bachelor Party",
1770
+ BacheloretteParty: "Bachelorette Party",
1771
+ BeachParty: "Beach Party",
1772
+ Birthday: "Birthday",
1773
+ BoatParty: "Boat Party",
1774
+ Bonfire: "Bonfire",
1775
+ BridalShower: "Bridal Shower",
1776
+ BrunchGathering: "Brunch Gathering",
1777
+ CarShow: "Car Show",
1778
+ Carnival: "Carnival",
1779
+ CasinoNight: "Casino Night",
1780
+ CasualMixer: "Casual Mixer",
1781
+ CharityGala: "Charity Gala",
1782
+ ChristmasParty: "Christmas Party",
1783
+ ChurchEvent: "Church Event",
1784
+ CitySponsored: "City-Sponsored Event",
1785
+ CocktailParty: "Cocktail Party",
1786
+ CollegeParty: "College Party",
1787
+ ComedyShow: "Comedy Show",
1788
+ Concert: "Concert",
1789
+ Conference: "Conference",
1790
+ Convention: "Convention",
1791
+ CorporateEvent: "Corporate Event",
1792
+ Cruise: "Cruise",
1793
+ DanceParty: "Dance Party",
1794
+ DiscoNight: "Disco Night",
1795
+ EasterGathering: "Easter Gathering",
1796
+ EngagementParty: "Engagement Party",
1797
+ Fair: "Fair",
1798
+ FarewellParty: "Farewell Party",
1799
+ FashionShow: "Fashion Show",
1800
+ Festival: "Festival",
1801
+ FestivalFilm: "Film Festival",
1802
+ FestivalFood: "Food Festival",
1803
+ Fundraiser: "Fundraiser",
1804
+ GameNight: "Game Night",
1805
+ GamingEvent: "Gaming Event",
1806
+ GardenParty: "Garden Party",
1807
+ GraduationParty: "Graduation Party",
1808
+ HalloweenParty: "Halloween Party",
1809
+ HanukkahParty: "Hanukkah Party",
1810
+ HolidayParty: "Holiday Party",
1811
+ HouseParty: "House Party",
1812
+ HousewarmingParty: "Housewarming Party",
1813
+ KaraokeNight: "Karaoke Night",
1814
+ LaunchParty: "Launch Party",
1815
+ LuxuryRetreat: "Luxury Retreat",
1816
+ MansionParty: "Mansion Party",
1817
+ MardiGras: "Mardi Gras",
1818
+ Memorial: "Memorial",
1819
+ MovieNight: "Movie Night",
1820
+ MoviePremiere: "Movie Premiere",
1821
+ MusicFestival: "Music Festival",
1822
+ NewYearsEveCelebration: "New Year's Eve Celebration",
1823
+ OfficeParty: "Office Party",
1824
+ OpenMicNight: "Open Mic Night",
1825
+ OutdoorActivity: "Outdoor Activity",
1826
+ Parade: "Parade",
1827
+ Party: "Party",
1828
+ PoolParty: "Pool Party",
1829
+ Potluck: "Potluck",
1830
+ PreParty: "Pre-Party",
1831
+ ProfessionalNetworkingEvent: "Professional Networking Event",
1832
+ PubCrawl: "Pub Crawl",
1833
+ Rave: "Rave",
1834
+ RetirementCelebration: "Retirement Celebration",
1835
+ Reunion: "Reunion",
1836
+ SchoolEvent: "School Event",
1837
+ SocialClubEvent: "Social Club Event",
1838
+ SportsWatchParty: "Sports Watch Party",
1839
+ ThanksgivingDinner: "Thanksgiving Dinner",
1840
+ ThemedDinnerParty: "Themed Dinner Party",
1841
+ ThemedParty: "Themed Party",
1842
+ ThemedPubCrawl: "Themed Pub Crawl",
1843
+ Tournament: "Tournament",
1844
+ TradeShow: "Trade Show",
1845
+ TriviaNight: "Trivia Night",
1846
+ ValentinesDayParty: "Valentine's Day Party",
1847
+ WeddingReception: "Wedding Reception",
1848
+ WelcomeHomeParty: "Welcome Home Party",
1849
+ WineTastingEvent: "Wine Tasting Event",
1850
+ Workshop: "Workshop",
1851
+ Other: "Other",
1742
1852
  };
1743
1853
 
1744
1854
  /**
@@ -1751,47 +1861,47 @@ export type DietaryOptionToStringType = {
1751
1861
  [key in DietaryOption]: string;
1752
1862
  };
1753
1863
  export const DietaryOptionToString: DietaryOptionToStringType = {
1754
- [DietaryOption.GlutenFreeOptions]: "Gluten-Free Options Available",
1755
- [DietaryOption.VeganOptions]: "Vegan Options Available",
1756
- [DietaryOption.VegetarianOptions]: "Vegetarian Options Available",
1757
- [DietaryOption.DairyFreeOptions]: "Dairy-Free Options Available",
1758
- [DietaryOption.NutFreeOptions]: "Nut-Free Options Available",
1759
- [DietaryOption.HalalOptions]: "Halal Options Available",
1760
- [DietaryOption.KosherOptions]: "Kosher Options Available",
1761
- [DietaryOption.SugarFreeOptions]: "Low-Sugar / Sugar-Free Options Available",
1762
- [DietaryOption.KetoOptions]: "Keto-Friendly Options Available",
1763
- [DietaryOption.PaleoOptions]: "Paleo-Friendly Options Available",
1764
- [DietaryOption.AlcoholFreeOptions]: "Non-Alcoholic Options Available",
1864
+ GlutenFreeOptions: "Gluten-Free Options Available",
1865
+ VeganOptions: "Vegan Options Available",
1866
+ VegetarianOptions: "Vegetarian Options Available",
1867
+ DairyFreeOptions: "Dairy-Free Options Available",
1868
+ NutFreeOptions: "Nut-Free Options Available",
1869
+ HalalOptions: "Halal Options Available",
1870
+ KosherOptions: "Kosher Options Available",
1871
+ SugarFreeOptions: "Low-Sugar / Sugar-Free Options Available",
1872
+ KetoOptions: "Keto-Friendly Options Available",
1873
+ PaleoOptions: "Paleo-Friendly Options Available",
1874
+ AlcoholFreeOptions: "Non-Alcoholic Options Available",
1765
1875
  };
1766
1876
 
1767
1877
  /** Short chip labels used in tight UI spots (filter modal, card pills). */
1768
1878
  export const DietaryOptionShortLabel: DietaryOptionToStringType = {
1769
- [DietaryOption.GlutenFreeOptions]: "Gluten-Free",
1770
- [DietaryOption.VeganOptions]: "Vegan",
1771
- [DietaryOption.VegetarianOptions]: "Vegetarian",
1772
- [DietaryOption.DairyFreeOptions]: "Dairy-Free",
1773
- [DietaryOption.NutFreeOptions]: "Nut-Free",
1774
- [DietaryOption.HalalOptions]: "Halal",
1775
- [DietaryOption.KosherOptions]: "Kosher",
1776
- [DietaryOption.SugarFreeOptions]: "Sugar-Free",
1777
- [DietaryOption.KetoOptions]: "Keto",
1778
- [DietaryOption.PaleoOptions]: "Paleo",
1779
- [DietaryOption.AlcoholFreeOptions]: "Non-Alcoholic",
1879
+ GlutenFreeOptions: "Gluten-Free",
1880
+ VeganOptions: "Vegan",
1881
+ VegetarianOptions: "Vegetarian",
1882
+ DairyFreeOptions: "Dairy-Free",
1883
+ NutFreeOptions: "Nut-Free",
1884
+ HalalOptions: "Halal",
1885
+ KosherOptions: "Kosher",
1886
+ SugarFreeOptions: "Sugar-Free",
1887
+ KetoOptions: "Keto",
1888
+ PaleoOptions: "Paleo",
1889
+ AlcoholFreeOptions: "Non-Alcoholic",
1780
1890
  };
1781
1891
 
1782
1892
  /** All `DietaryOption` enum values in display order (for rendering checkboxes/tags). */
1783
1893
  export const DIETARY_OPTION_VALUES: ReadonlyArray<DietaryOption> = [
1784
- DietaryOption.GlutenFreeOptions,
1785
- DietaryOption.VeganOptions,
1786
- DietaryOption.VegetarianOptions,
1787
- DietaryOption.DairyFreeOptions,
1788
- DietaryOption.NutFreeOptions,
1789
- DietaryOption.HalalOptions,
1790
- DietaryOption.KosherOptions,
1791
- DietaryOption.SugarFreeOptions,
1792
- DietaryOption.KetoOptions,
1793
- DietaryOption.PaleoOptions,
1794
- DietaryOption.AlcoholFreeOptions,
1894
+ "GlutenFreeOptions",
1895
+ "VeganOptions",
1896
+ "VegetarianOptions",
1897
+ "DairyFreeOptions",
1898
+ "NutFreeOptions",
1899
+ "HalalOptions",
1900
+ "KosherOptions",
1901
+ "SugarFreeOptions",
1902
+ "KetoOptions",
1903
+ "PaleoOptions",
1904
+ "AlcoholFreeOptions",
1795
1905
  ];
1796
1906
 
1797
1907
  /** Display labels for `IncomeRange` (wizard primary/secondary chips). */
@@ -1799,29 +1909,28 @@ export type IncomeRangeToStringType = {
1799
1909
  [key in IncomeRange]: string;
1800
1910
  };
1801
1911
  export const IncomeRangeLabel: IncomeRangeToStringType = {
1802
- [IncomeRange.NoPreference]: "Anyone",
1803
- [IncomeRange.Under40k]: "Under $40k",
1804
- [IncomeRange.From40to80k]: "$40k – $80k",
1805
- [IncomeRange.From80to150k]: "$80k – $150k",
1806
- [IncomeRange.From150to200k]: "$150k – $200k",
1807
- [IncomeRange.From200to500k]:
1808
- "$200k – $500k (common accredited-income band)",
1809
- [IncomeRange.From500kTo1M]: "$500k – $1M",
1810
- [IncomeRange.Over1M]: "$1M+",
1811
- [IncomeRange.PreferNotToSay]: "Prefer not to say",
1912
+ NoPreference: "Anyone",
1913
+ Under40k: "Under $40k",
1914
+ From40to80k: "$40k – $80k",
1915
+ From80to150k: "$80k – $150k",
1916
+ From150to200k: "$150k – $200k",
1917
+ From200to500k: "$200k – $500k (common accredited-income band)",
1918
+ From500kTo1M: "$500k – $1M",
1919
+ Over1M: "$1M+",
1920
+ PreferNotToSay: "Prefer not to say",
1812
1921
  };
1813
1922
 
1814
1923
  /** Short labels for filter modal / tight chips. */
1815
1924
  export const IncomeRangeShortLabel: IncomeRangeToStringType = {
1816
- [IncomeRange.NoPreference]: "Any income",
1817
- [IncomeRange.Under40k]: "<$40k",
1818
- [IncomeRange.From40to80k]: "$40–80k",
1819
- [IncomeRange.From80to150k]: "$80–150k",
1820
- [IncomeRange.From150to200k]: "$150–200k",
1821
- [IncomeRange.From200to500k]: "$200–500k",
1822
- [IncomeRange.From500kTo1M]: "$500k–$1M",
1823
- [IncomeRange.Over1M]: "$1M+",
1824
- [IncomeRange.PreferNotToSay]: "No answer",
1925
+ NoPreference: "Any income",
1926
+ Under40k: "<$40k",
1927
+ From40to80k: "$40–80k",
1928
+ From80to150k: "$80–150k",
1929
+ From150to200k: "$150–200k",
1930
+ From200to500k: "$200–500k",
1931
+ From500kTo1M: "$500k–$1M",
1932
+ Over1M: "$1M+",
1933
+ PreferNotToSay: "No answer",
1825
1934
  };
1826
1935
 
1827
1936
  /**
@@ -1829,15 +1938,15 @@ export const IncomeRangeShortLabel: IncomeRangeToStringType = {
1829
1938
  * Audience-targeting only — never use to gate ticket purchase or entry.
1830
1939
  */
1831
1940
  export const INCOME_RANGE_VALUES: ReadonlyArray<IncomeRange> = [
1832
- IncomeRange.Under40k,
1833
- IncomeRange.From40to80k,
1834
- IncomeRange.From80to150k,
1835
- IncomeRange.From150to200k,
1836
- IncomeRange.From200to500k,
1837
- IncomeRange.From500kTo1M,
1838
- IncomeRange.Over1M,
1839
- IncomeRange.PreferNotToSay,
1840
- IncomeRange.NoPreference,
1941
+ "Under40k",
1942
+ "From40to80k",
1943
+ "From80to150k",
1944
+ "From150to200k",
1945
+ "From200to500k",
1946
+ "From500kTo1M",
1947
+ "Over1M",
1948
+ "PreferNotToSay",
1949
+ "NoPreference",
1841
1950
  ];
1842
1951
 
1843
1952
  /** Homepage / discovery section labels for synthetic rows (not `BashEventType` enum values). */
@@ -257,7 +257,22 @@ export const PUBLIC_TEASER_USER_DATA_TO_SELECT = {
257
257
 
258
258
  export type PublicTeaserUser = Prisma.UserGetPayload<{
259
259
  select: typeof PUBLIC_TEASER_USER_DATA_TO_SELECT;
260
- }>;
260
+ }> & {
261
+ /** Only populated by Intros endpoints for eligible viewers. */
262
+ openToIntros?: boolean;
263
+ /** Only populated by Intros endpoints for eligible viewers. */
264
+ personalityType?: string | null;
265
+ /** Only populated by Intros endpoints for eligible viewers. */
266
+ locusOfControl?: string | null;
267
+ /** True when the viewer already sent an interest expression to this person. */
268
+ alreadyExpressedInterest?: boolean;
269
+ /** True when this person already sent an interest expression to the viewer. */
270
+ interestFromThem?: boolean;
271
+ /** True when both people have sent a signal. */
272
+ mutualInterest?: boolean;
273
+ /** Only populated by Intros endpoints for eligible viewers. */
274
+ introIntents?: string[];
275
+ };
261
276
 
262
277
  export const PRIVATE_USER_ACCOUNT_TO_SELECT = {
263
278
  ...FRONT_END_USER_DATA_TO_SELECT,
@@ -729,6 +744,10 @@ type BashEventExtBase = Override<
729
744
  * When true (default), signed-in visitors can message the host from the bash detail page.
730
745
  */
731
746
  allowViewerContact: boolean;
747
+ /**
748
+ * Host opt-in: guests must have a profile photo to RSVP or buy tickets.
749
+ */
750
+ requireProfilePhoto: boolean;
732
751
  };
733
752
 
734
753
  export type BashEventExt = Omit<