@getmicdrop/venue-calendar 4.0.112 → 4.0.113

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 (99) hide show
  1. package/README.md +2 -0
  2. package/dist/CartView-DBV2yZaL.js +2466 -0
  3. package/dist/CartView-DBV2yZaL.js.map +1 -0
  4. package/dist/{Checkout-nyPWpzmE.js → Checkout-CukZs5WU.js} +5 -5
  5. package/dist/{Checkout-nyPWpzmE.js.map → Checkout-CukZs5WU.js.map} +1 -1
  6. package/dist/{Checkout-ns94gCrx.js → Checkout-DBXrhhKW.js} +54 -54
  7. package/dist/{Checkout-ns94gCrx.js.map → Checkout-DBXrhhKW.js.map} +1 -1
  8. package/dist/{CheckoutTimer-Bv4qR0Mn.js → CheckoutTimer-C7osBosg.js} +5 -5
  9. package/dist/{CheckoutTimer-Bv4qR0Mn.js.map → CheckoutTimer-C7osBosg.js.map} +1 -1
  10. package/dist/{ClockIcon-D2ib_bzt.js → ClockIcon-BeCxOp69.js} +2 -2
  11. package/dist/{ClockIcon-D2ib_bzt.js.map → ClockIcon-BeCxOp69.js.map} +1 -1
  12. package/dist/{CollectionView-G3OmVuiX.js → CollectionView-CMm-2iBY.js} +44 -45
  13. package/dist/CollectionView-CMm-2iBY.js.map +1 -0
  14. package/dist/{Event-B1syGqOf.js → Event-CGnKZ-pZ.js} +585 -581
  15. package/dist/Event-CGnKZ-pZ.js.map +1 -0
  16. package/dist/{EventPage-CqryTYfg.js → EventPage-DBGHmWGD.js} +10 -10
  17. package/dist/EventPage-DBGHmWGD.js.map +1 -0
  18. package/dist/{Heading-BM6t9w6d.js → Heading-NDMjqlhz.js} +5 -5
  19. package/dist/Heading-NDMjqlhz.js.map +1 -0
  20. package/dist/{ScarcityBadge-B7KnIEoD.js → ScarcityBadge-BqL0twaw.js} +28 -28
  21. package/dist/{ScarcityBadge-B7KnIEoD.js.map → ScarcityBadge-BqL0twaw.js.map} +1 -1
  22. package/dist/{SeriesPage-DYbBhYHy.js → SeriesPage-BggX59ED.js} +5 -5
  23. package/dist/{SeriesPage-DYbBhYHy.js.map → SeriesPage-BggX59ED.js.map} +1 -1
  24. package/dist/{Spinner-D2Ff-2jf.js → Spinner-C4aYrnjh.js} +2 -2
  25. package/dist/{Spinner-D2Ff-2jf.js.map → Spinner-C4aYrnjh.js.map} +1 -1
  26. package/dist/{Success-CPQuVaaV.js → Success-BtREZD7W.js} +8 -8
  27. package/dist/Success-BtREZD7W.js.map +1 -0
  28. package/dist/{Text-C-9C-Rav.js → Text-B0QR6Ape.js} +4 -4
  29. package/dist/{Text-C-9C-Rav.js.map → Text-B0QR6Ape.js.map} +1 -1
  30. package/dist/{VenueCalendar-Dkr4qm4p.js → VenueCalendar-DIAMhER4.js} +4143 -4091
  31. package/dist/VenueCalendar-DIAMhER4.js.map +1 -0
  32. package/dist/{ViewTicketsEmbed-B581Bukn.js → ViewTicketsEmbed-D4zF9Qgm.js} +388 -381
  33. package/dist/{ViewTicketsEmbed-B581Bukn.js.map → ViewTicketsEmbed-D4zF9Qgm.js.map} +1 -1
  34. package/dist/api/api/client.d.ts +17 -0
  35. package/dist/api/api/cta.d.ts +34 -0
  36. package/dist/api/api/events.d.ts +183 -0
  37. package/dist/api/api/gift-cards.d.ts +108 -0
  38. package/dist/api/api/index.d.ts +46 -0
  39. package/dist/api/api/orders.d.ts +149 -0
  40. package/dist/api/api/promo.d.ts +45 -0
  41. package/dist/api/api/result.d.ts +78 -0
  42. package/dist/api/api/route-manifest.d.ts +179 -0
  43. package/dist/api/api/transformers/address.d.ts +18 -0
  44. package/dist/api/api/transformers/cart.d.ts +19 -0
  45. package/dist/api/api/transformers/collection.d.ts +12 -0
  46. package/dist/api/api/transformers/event.d.ts +173 -0
  47. package/dist/api/api/transformers/giftCard.d.ts +11 -0
  48. package/dist/api/api/transformers/index.d.ts +27 -0
  49. package/dist/api/api/transformers/order.d.ts +44 -0
  50. package/dist/api/api/transformers/performer.d.ts +8 -0
  51. package/dist/api/api/transformers/series.d.ts +12 -0
  52. package/dist/api/api/transformers/venue.d.ts +39 -0
  53. package/dist/api/api/venues.d.ts +33 -0
  54. package/dist/api/api/waitlist.d.ts +49 -0
  55. package/dist/api/api.cjs +2 -0
  56. package/dist/api/api.cjs.map +1 -0
  57. package/dist/api/api.mjs +1302 -0
  58. package/dist/api/api.mjs.map +1 -0
  59. package/dist/api/types.d.ts +483 -0
  60. package/dist/{labels-DAFwZdnA.js → labels-CUDO5VqI.js} +3 -3
  61. package/dist/{labels-DAFwZdnA.js.map → labels-CUDO5VqI.js.map} +1 -1
  62. package/dist/{modalManager.svelte-BbA2uxS7.js → modalManager.svelte-CWfqhQHL.js} +2 -2
  63. package/dist/{modalManager.svelte-BbA2uxS7.js.map → modalManager.svelte-CWfqhQHL.js.map} +1 -1
  64. package/dist/navigation--gZASiSa.js.map +1 -1
  65. package/dist/{promo-BGoSmBd_.js → promo-4scuh00Y.js} +9 -9
  66. package/dist/{promo-BGoSmBd_.js.map → promo-4scuh00Y.js.map} +1 -1
  67. package/dist/seo/HostSeoController.d.ts +68 -0
  68. package/dist/seo/buildCollectionJsonLd.d.ts +8 -0
  69. package/dist/seo/buildEventJsonLd.d.ts +9 -0
  70. package/dist/seo/buildSeriesJsonLd.d.ts +6 -0
  71. package/dist/seo/helpers.d.ts +88 -0
  72. package/dist/seo/index.d.ts +10 -0
  73. package/dist/seo/seo.cjs +2 -0
  74. package/dist/seo/seo.cjs.map +1 -0
  75. package/dist/seo/seo.mjs +688 -0
  76. package/dist/seo/seo.mjs.map +1 -0
  77. package/dist/seo/types.d.ts +149 -0
  78. package/dist/{showcase-state-options-BWzGMPZ-.js → showcase-state-options-DG5Bn9mL.js} +2 -2
  79. package/dist/showcase-state-options-DG5Bn9mL.js.map +1 -0
  80. package/dist/{transform-CpjZiH34.js → transform-B1kRFSE7.js} +10 -10
  81. package/dist/{transform-CpjZiH34.js.map → transform-B1kRFSE7.js.map} +1 -1
  82. package/dist/{utm-D1uGUvk2.js → utm-CPOH8BYT.js} +2 -2
  83. package/dist/{utm-D1uGUvk2.js.map → utm-CPOH8BYT.js.map} +1 -1
  84. package/dist/venue-calendar.css +1 -1
  85. package/dist/venue-calendar.es.js +4 -4
  86. package/dist/venue-calendar.iife.js +37 -37
  87. package/dist/venue-calendar.iife.js.map +1 -1
  88. package/dist/venue-calendar.umd.js +32 -32
  89. package/dist/venue-calendar.umd.js.map +1 -1
  90. package/package.json +7 -3
  91. package/dist/CartView-H6PXIc8m.js +0 -2475
  92. package/dist/CartView-H6PXIc8m.js.map +0 -1
  93. package/dist/CollectionView-G3OmVuiX.js.map +0 -1
  94. package/dist/Event-B1syGqOf.js.map +0 -1
  95. package/dist/EventPage-CqryTYfg.js.map +0 -1
  96. package/dist/Heading-BM6t9w6d.js.map +0 -1
  97. package/dist/Success-CPQuVaaV.js.map +0 -1
  98. package/dist/VenueCalendar-Dkr4qm4p.js.map +0 -1
  99. package/dist/showcase-state-options-BWzGMPZ-.js.map +0 -1
@@ -0,0 +1,179 @@
1
+ /**
2
+ * The wire contract: every backend route this repo names.
3
+ *
4
+ * A test that asserts a route NAME proves nothing unless it proves the name
5
+ * RESOLVES. `expect(fetch).toHaveBeenCalledWith('/api/…')` passes happily
6
+ * against a route the router 404s — that is how 4.0.96 shipped a POST against a
7
+ * route the backend did not serve and locked every buyer out of every
8
+ * password-protected event.
9
+ *
10
+ * This module is the single source of truth two gates read:
11
+ *
12
+ * route-answers-contract.test.ts (every PR, offline)
13
+ * every API call site in src/ must name a route listed here, with a verb
14
+ * and body shape that match.
15
+ *
16
+ * route-answers-probe.test.ts (CI job, hits the deployed backend)
17
+ * every route listed here must be ANSWERED by the router. That is what
18
+ * keeps this file from being fiction.
19
+ *
20
+ * ROUTER-404 vs RESOURCE-404 — the whole diagnosis. The backend replies to an
21
+ * unrouted request with 404 + `{"error":{"code":"NOT_FOUND","message":"Route
22
+ * not found: POST /api/…"}}`. A route that EXISTS but whose resource does not
23
+ * replies 400 "Invalid event ID", or 404 "Order not found", or 401, or 200.
24
+ * Only the "Route not found:" prefix means the name resolved to nothing.
25
+ * `isRouterNotFound()` below is the one place that distinction is made.
26
+ *
27
+ * PROBE SAFETY. The probe test asks PRODUCTION. A probe recipe is only correct if
28
+ * it CANNOT MUTATE — and that claim is worthless unless something checks it. It
29
+ * is load-bearing, not decorative: `POST /orders/create` with an EMPTY body
30
+ * answers 200 and creates a real order.
31
+ *
32
+ * So every mutating row (POST/PUT/DELETE) must declare `probe.safety`, and
33
+ * route-answers-probe.test.ts asserts the declaration against what production
34
+ * actually answers. That holds for EVERY mutating row in BOTH lists — an UNSERVED
35
+ * row is not exempt. "It is a router-404, so no handler runs" is circular: it is
36
+ * true until the day the row's whole purpose is fulfilled and the backend ships the
37
+ * route. The probe sends the request BEFORE it can know whether the name resolved,
38
+ * so on that day the POST lands on a live handler, and the safety claim is the only
39
+ * thing asserting it bounced. Two shapes are legal, and only two:
40
+ *
41
+ * refused — the handler REJECTS the recipe (400 invalid id, 401, 404, 422) and
42
+ * never reaches its write. Assert the status is one it declared.
43
+ *
44
+ * inert — the handler ACCEPTS the recipe but it targets a resource that
45
+ * cannot exist, so it changes nothing, and the response SAYS SO.
46
+ * `POST /orders/complete/:uuid` is a bulk update keyed on the UUID:
47
+ * it answers 200 "Completed 0 reservations" for every UUID, refusing
48
+ * nothing — there is no rejecting recipe to write. Assert the row
49
+ * count in the body: the response itself proves zero rows moved.
50
+ *
51
+ * A row that cannot honestly claim either shape must not be probed at all.
52
+ */
53
+ /** Host prefixes. `client.ts` prefixes any endpoint not starting with `http`
54
+ * with PUBLIC — a bare `/orders/create` means `${PUBLIC}/orders/create`. */
55
+ export declare const PUBLIC = "/api/v2/public";
56
+ export declare const ORDERS_V2 = "/api/orders/v2/public";
57
+ export declare const ORDERS_V2_ROOT = "/api/orders/v2";
58
+ /**
59
+ * The verbs this contract knows — runtime, not just a type. The source scanner in
60
+ * route-answers-contract.test.ts checks a call site's `method:` against THIS list
61
+ * and goes red on anything else. When the scanner carried its own regex
62
+ * alternation instead, a `method: 'PATCH'` matched nothing, fell through to the
63
+ * `'GET'` default and was checked against the GET row: green, silently, at a route
64
+ * that serves no PATCH. One list, read by both.
65
+ */
66
+ export declare const HTTP_METHODS: readonly ["GET", "HEAD", "POST", "PUT", "DELETE"];
67
+ export type HttpMethod = (typeof HTTP_METHODS)[number];
68
+ /** Whether a verb written at a call site is one this contract can reason about. */
69
+ export declare function isHttpMethod(verb: string): verb is HttpMethod;
70
+ /**
71
+ * Why a probe cannot mutate production — see PROBE SAFETY above. Required on
72
+ * every POST/PUT/DELETE row and asserted live; the offline gate fails a mutating
73
+ * row that omits it, so the safety claim can never again be author discipline.
74
+ */
75
+ export type ProbeSafety = {
76
+ kind: 'refused';
77
+ /** Statuses the handler answers when it refuses this recipe. Never 2xx. */
78
+ statuses: readonly number[];
79
+ } | {
80
+ kind: 'inert';
81
+ /** The status the handler answers when it accepts this recipe. */
82
+ status: number;
83
+ /** Must match the response body, and must prove nothing was written. */
84
+ proof: RegExp;
85
+ /** Why accepting it changes nothing. */
86
+ why: string;
87
+ };
88
+ export interface Probe {
89
+ path: string;
90
+ body?: unknown;
91
+ headers?: Record<string, string>;
92
+ /** Required on POST/PUT/DELETE. Reads cannot mutate, so GET/HEAD omit it. */
93
+ safety?: ProbeSafety;
94
+ }
95
+ export interface BackendRoute {
96
+ method: HttpMethod;
97
+ /** Full path from the host root. Path params are written `:name`. */
98
+ path: string;
99
+ /** Whether the route takes a request body. */
100
+ body: 'required' | 'none';
101
+ /** A request that reaches the router and cannot change anything behind it. */
102
+ probe: Probe;
103
+ }
104
+ /** The verbs that can write. These are the probes that need a safety claim. */
105
+ export declare function isMutating(method: HttpMethod): boolean;
106
+ /** Turn a manifest pattern into a matcher: `:name` matches any single segment. */
107
+ export declare function patternMatches(pattern: string, concrete: string): boolean;
108
+ /**
109
+ * A path param value that is syntactically valid and cannot exist.
110
+ *
111
+ * Exported because production code needs it too: `testNetworkConnection()` asks a
112
+ * SERVED route about this id to find out whether the router answers at all. Same
113
+ * id, same reason, one definition — an id-that-cannot-exist written out twice is
114
+ * two ids that can drift.
115
+ */
116
+ export declare const NONEXISTENT_ID = "00000000-0000-0000-0000-000000000000";
117
+ /**
118
+ * Routes the deployed backend ANSWERS. Verified by route-answers-probe.test.ts.
119
+ * Adding a row here without the probe agreeing is exactly the lie this gate exists
120
+ * to catch — the probe will fail the row.
121
+ */
122
+ export declare const SERVED_ROUTES: BackendRoute[];
123
+ export interface UnservedRoute extends Omit<BackendRoute, 'body'> {
124
+ /** Where the dead name is spoken. */
125
+ callSites: string[];
126
+ /** What the buyer sees because the name resolves to nothing. */
127
+ impact: string;
128
+ issue: string;
129
+ }
130
+ /**
131
+ * Routes this repo NAMES that the router does not serve — verified router-404.
132
+ *
133
+ * This is a debt ledger, not a sanctioned end-state. It exists so the gate can
134
+ * land red-free while every dead name stays visible and non-regressible: the
135
+ * contract test fails if a NEW call site names a route in neither list, and the
136
+ * probe fails if a route listed here starts answering (fix the call site, then
137
+ * move the row into SERVED_ROUTES). The list may only ever shrink.
138
+ */
139
+ export declare const UNSERVED_ROUTES: UnservedRoute[];
140
+ export interface RetiredRoute {
141
+ method: HttpMethod;
142
+ /** The dead name, exactly as the ledger row used to spell it. */
143
+ path: string;
144
+ /** Who used to speak it, and what happened to them. */
145
+ wasNamedBy: string;
146
+ issue: string;
147
+ }
148
+ /**
149
+ * Dead names this repo has STOPPED speaking. The ledger's graveyard.
150
+ *
151
+ * UNSERVED_ROUTES says "may only ever shrink" — and until now nothing enforced
152
+ * that. Two ways to put a dead name back were wide open: re-add the row, or write
153
+ * a fresh call site and baseline it. Either one turns the debt ledger into a
154
+ * silencer, and a silencer is how the 4.0.96 password outage shipped in the first
155
+ * place.
156
+ *
157
+ * So a retired route is retired in both directions, asserted in
158
+ * route-answers-contract.test.ts:
159
+ *
160
+ * - nothing in src/ may NAME it again (a new call site goes red, not baselined);
161
+ * - it may not reappear in UNSERVED_ROUTES (you cannot re-open the debt);
162
+ * - it may not appear in SERVED_ROUTES either — if the backend genuinely ships
163
+ * the route one day, DELETE the row here in the same commit that adds the
164
+ * served one with a probe recipe proving the router answers it. That is a
165
+ * deliberate two-place edit, which is the whole point: coming back from the
166
+ * dead should cost more than adding a line.
167
+ */
168
+ export declare const RETIRED_ROUTES: RetiredRoute[];
169
+ /**
170
+ * The router-404 discriminator — the one place the distinction is made.
171
+ *
172
+ * TRUE = the name resolved to nothing (the bug).
173
+ * FALSE = the router answered; whatever the handler then said (400 invalid id,
174
+ * 404 "Order not found", 401, 501, 200) is a RESOURCE-level answer and
175
+ * is none of this gate's business.
176
+ */
177
+ export declare function isRouterNotFound(status: number, bodyText: string): boolean;
178
+ /** HEAD is answered by the GET route — Express routes the two together. */
179
+ export declare function effectiveMethod(method: HttpMethod): HttpMethod;
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Address helpers — shared between the event, series and collection page
3
+ * transformers.
4
+ *
5
+ * Lifted verbatim from public-calendar-flow/transform.ts so the series and
6
+ * collection canonicals (and the in-place transformApiEvent) read a single
7
+ * source instead of each carrying a private copy. Behavior is byte-identical
8
+ * to the previous module-private versions.
9
+ */
10
+ /**
11
+ * Parse a single-line address string into display lines.
12
+ * E.g. "123 Main St, Los Angeles, CA 90012" -> ["123 Main St", "Los Angeles, CA 90012"]
13
+ */
14
+ export declare function parseAddress(addressStr: string): string[];
15
+ /**
16
+ * Build a Google Maps search URL from an address string.
17
+ */
18
+ export declare function buildGoogleMapsUrl(address: string): string;
@@ -0,0 +1,19 @@
1
+ import { CartView, CartReservationView } from '../orders.js';
2
+ /**
3
+ * Parse a single raw reservation row into the normalized CartReservationView.
4
+ *
5
+ * Wire shape is contained here. Uses `??` (PascalCase first, camelCase
6
+ * fallback) so a real `0` quantity / price is preserved. Numeric coercion via
7
+ * Number(), status via String() -- byte-identical to the inline `.map` in
8
+ * getCartByUUID.
9
+ */
10
+ export declare function parseCartReservation(raw: unknown): CartReservationView;
11
+ /**
12
+ * Parse a raw cart payload into the normalized CartView domain shape.
13
+ *
14
+ * Wire shape (RawCart) is contained inside this module and never escapes it.
15
+ * Reconciles PascalCase and camelCase JSON tags via `??`. Reservations are
16
+ * normalized through parseCartReservation. Byte-identical to the inline
17
+ * normalization previously embedded in getCartByUUID.
18
+ */
19
+ export declare function parseCart(raw: unknown): CartView;
@@ -0,0 +1,12 @@
1
+ import { PublicCollectionData } from '../types.js';
2
+ import { EventData } from '../../public-calendar-flow/types';
3
+ /**
4
+ * Transform PublicCollectionData (from the collection API) into our clean EventData interface.
5
+ * Sets collectionId so EventExperience renders in full-width collection mode.
6
+ */
7
+ export declare function parseCollection(collection: PublicCollectionData): EventData;
8
+ /**
9
+ * Back-compat alias — the public-calendar-flow shaper name. Existing call
10
+ * sites importing transformCollectionData continue to work unchanged.
11
+ */
12
+ export declare const transformCollectionData: typeof parseCollection;
@@ -0,0 +1,173 @@
1
+ import { Event, AvailableTicket } from '../types.js';
2
+ interface ApiEvent {
3
+ eventID?: number;
4
+ id?: number;
5
+ ID?: number;
6
+ name?: string;
7
+ title?: string;
8
+ slug?: string;
9
+ description?: string;
10
+ date?: string;
11
+ startDateTime?: string;
12
+ start_date_time?: string;
13
+ endDateTime?: string;
14
+ end_date_time?: string;
15
+ doorsOpenTime?: string;
16
+ doors_open_time?: string;
17
+ timezone?: string;
18
+ time_zone?: string;
19
+ venueId?: number;
20
+ venue_id?: number;
21
+ venueName?: string;
22
+ venue_name?: string;
23
+ venueAddress?: string;
24
+ venue_address?: string;
25
+ location?: string;
26
+ imageUrl?: string;
27
+ imageURL?: string;
28
+ image_url?: string;
29
+ image?: string;
30
+ status?: string;
31
+ isPublished?: boolean;
32
+ is_published?: boolean;
33
+ isCancelled?: boolean;
34
+ is_cancelled?: boolean;
35
+ availableTickets?: any[];
36
+ available_tickets?: any[];
37
+ tickets?: any[];
38
+ ticketsAvailable?: number;
39
+ tickets_available?: number;
40
+ ticketsSold?: number;
41
+ tickets_sold?: number;
42
+ minPrice?: number;
43
+ min_price?: number;
44
+ maxPrice?: number;
45
+ max_price?: number;
46
+ ctaText?: string;
47
+ cta_text?: string;
48
+ ctaState?: string;
49
+ cta_state?: string;
50
+ showPerformers?: boolean;
51
+ show_performers?: boolean;
52
+ eventSeriesId?: number;
53
+ event_series_id?: number;
54
+ seriesInstanceNumber?: number;
55
+ series_instance_number?: number;
56
+ timeZone?: string;
57
+ eventSummary?: string;
58
+ password?: string;
59
+ hasPassword?: boolean;
60
+ disclaimer?: string;
61
+ ticketType?: number;
62
+ eventTicketingType?: number;
63
+ ageRestriction?: number;
64
+ displayAgeRestriction?: boolean;
65
+ displayStartTime?: boolean;
66
+ displayEndTime?: boolean;
67
+ displayDoorsTime?: boolean;
68
+ collectionId?: number;
69
+ collection_id?: number;
70
+ ticketsRemaining?: number;
71
+ ticketsTotal?: number;
72
+ hasHiddenTickets?: boolean;
73
+ stage?: {
74
+ name?: string;
75
+ } | null;
76
+ stageName?: string;
77
+ stageId?: number;
78
+ eventCategoryTypes?: number[] | null;
79
+ publicPerformers?: Array<{
80
+ id?: number;
81
+ displayName?: string;
82
+ image?: string;
83
+ }> | null;
84
+ collectionIds?: number[] | null;
85
+ venue?: Record<string, any>;
86
+ performers?: Record<string, any>[];
87
+ faqs?: Record<string, any>[];
88
+ showtimes?: Record<string, any>[];
89
+ purchasedTickets?: Record<string, any>[];
90
+ }
91
+ /**
92
+ * Get CDN image URL.
93
+ *
94
+ * Delegates the host-join to SC's canonical `resolveImageUrl` (one path-join,
95
+ * one host constant). `{ cdn: true }` picks the Cloudflare-fronted CDN base
96
+ * (`moxy.sfo3.cdn`), the correct, edge-cached host for public buyer surfaces.
97
+ *
98
+ * This replaced VC's local `micdrop-images.sfo3` bucket, which 404s for real
99
+ * event/venue keys (CDN census 2026-07-05, ledger vc-getcdnimageurl-wrong-
100
+ * bucket-404). SC additionally passes `data:`/`blob:` URLs through untouched
101
+ * and normalizes a missing leading slash — a strict superset of the old body.
102
+ */
103
+ export declare function getCDNImageUrl(path: string | undefined): string;
104
+ /**
105
+ * Extract image URL from event with fallbacks.
106
+ *
107
+ * DIVERGENCE (no-shadowed-helper rename-keep): the HOST-JOIN is now the SC
108
+ * canonical (via `getCDNImageUrl` above); only the FIELD PRECEDENCE stays local
109
+ * and deliberately differs -- this transformer reads
110
+ * `imageUrl -> imageURL -> image_url -> image` (incl. the camelCase `imageURL`,
111
+ * asserted by event.test.ts), whereas SC reads
112
+ * `image -> coverImage -> imageUrl -> image_url`. The VC chain is what this
113
+ * wire boundary trusts; changing it would repoint which field wins for the same
114
+ * event, so it is preserved. Declared under a non-shadowing name and
115
+ * re-exported below as `getEventImageUrl` so call sites keep their existing
116
+ * import -- satisfies `micdrop/no-shadowed-helper` without suppression.
117
+ */
118
+ declare function getEventImageUrlByFieldPrecedence(apiEvent: ApiEvent): string;
119
+ export { getEventImageUrlByFieldPrecedence as getEventImageUrl };
120
+ /**
121
+ * Calculate CTA state based on ticket availability
122
+ */
123
+ /**
124
+ * VC's 4-state CTA derivation (available/sold_out/coming_soon/ended) for parsed events.
125
+ * Distinct from SC's `calculateCtaState` (richer wire-level canonical) — renamed to
126
+ * avoid shadowing the SC export; this variant reads the parsed/raw event shape parseEvent consumes.
127
+ */
128
+ type CtaState = 'available' | 'sold_out' | 'coming_soon' | 'ended';
129
+ export declare function deriveEventCtaState(apiEvent: ApiEvent): CtaState;
130
+ /**
131
+ * Parse a raw ticket payload into the normalized AvailableTicket domain shape.
132
+ *
133
+ * Wire shape is contained inside this module. Uses `||` chains matching the
134
+ * old transformer exactly -- 0/false values fall through to the next variant
135
+ * or default, byte-identical to previous behavior.
136
+ */
137
+ export declare function parseTicket(raw: unknown): AvailableTicket;
138
+ /**
139
+ * Parse a raw event payload into the normalized Event domain shape.
140
+ *
141
+ * Wire shape (ApiEvent) is contained inside this module and never escapes it.
142
+ * Uses `||` chains matching the old transformer exactly -- 0/false values fall
143
+ * through to the next variant, byte-identical to previous behavior. Throw
144
+ * behavior preserved from old mapper: null/undefined input (property access on a nullish value) or a non-array
145
+ * tickets field throws exactly as the old code did. Callers always pass real
146
+ * wire objects.
147
+ *
148
+ * COMPOSITION NOTE — passthrough seams (events convergence):
149
+ * The trailing block of fields below is carried VERBATIM from the wire (no
150
+ * fallback chains, no normalization) so that the view-shape projections —
151
+ * `utils/event-transform.js` (DETAIL/BROWSE) and
152
+ * `public-calendar-flow/transform.ts` (EventData) — can compose parseEvent
153
+ * for every event-level scalar instead of reading the wire themselves.
154
+ * `venue`/`performers`/`faqs`/`showtimes`/`purchasedTickets` stay raw objects
155
+ * by contract: their consumers (and #260's performer canonical) own that
156
+ * variance; normalizing them here would change rendered output.
157
+ */
158
+ export declare function parseEvent(raw: unknown): Event;
159
+ /**
160
+ * Back-compat alias -- existing call sites using transformTicket continue
161
+ * to work unchanged.
162
+ */
163
+ export declare const transformTicket: typeof parseTicket;
164
+ /**
165
+ * Back-compat alias -- existing call sites using transformEvent(apiEvent)
166
+ * continue to work unchanged.
167
+ */
168
+ export declare const transformEvent: typeof parseEvent;
169
+ /**
170
+ * Legacy transformer name for backwards compatibility.
171
+ */
172
+ export declare const transformEventData: typeof parseEvent;
173
+ export declare function parseEventList(raws: unknown[]): Event[];
@@ -0,0 +1,11 @@
1
+ import { ApplyGiftCardResult } from '../gift-cards.js';
2
+ /**
3
+ * Parse a successful apply-gift-card backend payload into ApplyGiftCardResult.
4
+ *
5
+ * Maps the real backend contract to what the Checkout component expects:
6
+ * - appliedAmount (cents) -> giftCardAmount (dollars)
7
+ * - remainingTotal (dollars) -> stripeAmount (dollars, residual to charge)
8
+ * - fullyCoveredByCard -> paymentType 'gift_card_only' | 'split' + requiresStripe
9
+ * Byte-identical to the inline success-path mapping previously in applyGiftCard.
10
+ */
11
+ export declare function parseGiftCardApplication(raw: unknown): ApplyGiftCardResult;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Transformers Index
3
+ *
4
+ * Re-exports all transformer functions for convenient importing.
5
+ *
6
+ * Canonical parse<Entity> functions (preferred for new code):
7
+ * parseEvent, parseVenue, parseOrder, parsePurchasedTicket, parseTicket,
8
+ * parseSeries, parseCollection
9
+ *
10
+ * Back-compat aliases (old names, call the same function):
11
+ * transformEvent, transformEventData, transformVenue, transformOrder,
12
+ * transformTicket, transformSeriesPageData, transformCollectionData
13
+ */
14
+ export { parseOrder, parsePurchasedTicket, transformOrder, // back-compat alias
15
+ transformTicket, // back-compat alias
16
+ transformOrderForDisplay, } from './order.js';
17
+ export { parseEvent, parseEventList, parseTicket, transformEvent, // back-compat alias
18
+ transformEventData, // legacy alias
19
+ transformTicket as transformAvailableTicket, // back-compat alias
20
+ getCDNImageUrl, getEventImageUrl, deriveEventCtaState, deriveEventCtaState as calculateCtaState, } from './event.js';
21
+ export { parseVenue, transformVenue, // back-compat alias
22
+ extractVenueFees, formatVenueAddress, } from './venue.js';
23
+ export { parseSeries, transformSeriesPageData, } from './series.js';
24
+ export { parseCollection, transformCollectionData, } from './collection.js';
25
+ export { parseCart, parseCartReservation } from './cart.js';
26
+ export { parseGiftCardApplication } from './giftCard.js';
27
+ export { parseEventPerformers } from './performer.js';
@@ -0,0 +1,44 @@
1
+ import { Order, PurchasedTicket } from '../types.js';
2
+ /**
3
+ * Parse a raw purchased-ticket payload into the normalized PurchasedTicket domain shape.
4
+ *
5
+ * Wire shape (ApiTicket) is contained inside this module. Uses `||` chains matching
6
+ * the old transformer exactly -- byte-identical to previous behavior. Throw behavior
7
+ * preserved from old mapper: null/undefined input (property access on a nullish value) throws as the old code did.
8
+ */
9
+ export declare function parsePurchasedTicket(raw: unknown): PurchasedTicket;
10
+ /**
11
+ * Parse a raw order payload into the normalized Order domain shape.
12
+ *
13
+ * Wire shape (ApiOrder) is contained inside this module and never escapes it.
14
+ * Uses `||` chains matching the old transformer exactly (all money fields use `||`,
15
+ * not `??` -- 0-valued amounts fall through to next variant, same as old) --
16
+ * byte-identical to previous behavior. Throw behavior preserved from old mapper:
17
+ * null/undefined input (property access on a nullish value) or a non-array tickets field throws as the old code did.
18
+ */
19
+ export declare function parseOrder(raw: unknown): Order;
20
+ /**
21
+ * Back-compat alias -- existing call sites using transformTicket continue
22
+ * to work unchanged.
23
+ */
24
+ export declare const transformTicket: typeof parsePurchasedTicket;
25
+ /**
26
+ * Back-compat alias -- existing call sites using transformOrder(apiOrder)
27
+ * continue to work unchanged.
28
+ */
29
+ export declare const transformOrder: typeof parseOrder;
30
+ /**
31
+ * Transform order for display on success page.
32
+ *
33
+ * Returns a simplified object with display-ready values.
34
+ */
35
+ export declare function transformOrderForDisplay(raw: unknown): {
36
+ orderId: string;
37
+ displayOrderId: string;
38
+ email: string;
39
+ customerName: string;
40
+ total: number;
41
+ formattedTotal: string;
42
+ ticketCount: number;
43
+ status: string;
44
+ };
@@ -0,0 +1,8 @@
1
+ import { EventPerformersResponse } from '../types.js';
2
+ /**
3
+ * Parse a raw performers payload into the normalized EventPerformersResponse.
4
+ *
5
+ * `performers` is coerced to an array (Array.isArray gate), `showPerformers`
6
+ * to a strict boolean (`=== true`) -- matching fetchEventPerformers exactly.
7
+ */
8
+ export declare function parseEventPerformers(raw: unknown): EventPerformersResponse;
@@ -0,0 +1,12 @@
1
+ import { SeriesPageData } from '../types.js';
2
+ import { EventData } from '../../public-calendar-flow/types';
3
+ /**
4
+ * Transform SeriesPageData (from the series API) into our clean EventData interface.
5
+ * Sets eventSeriesId so EventExperience renders in full-width series mode.
6
+ */
7
+ export declare function parseSeries(series: SeriesPageData): EventData;
8
+ /**
9
+ * Back-compat alias — the public-calendar-flow shaper name. Existing call
10
+ * sites importing transformSeriesPageData continue to work unchanged.
11
+ */
12
+ export declare const transformSeriesPageData: typeof parseSeries;
@@ -0,0 +1,39 @@
1
+ import { Venue } from '../types.js';
2
+ /**
3
+ * Parse a raw venue payload into the normalized Venue domain shape.
4
+ *
5
+ * Wire shape (ApiVenue) is contained inside this module and never escapes it.
6
+ * Uses `||` / `??` chains matching the old transformer exactly -- byte-identical
7
+ * to previous behavior. Throw behavior preserved from old mapper: null/undefined
8
+ * input throws exactly as the old code did. Callers always pass real wire objects.
9
+ */
10
+ declare function vcParseVenue(raw: unknown): Venue;
11
+ /**
12
+ * Public re-export under the canonical name + back-compat alias. Existing call
13
+ * sites using either parseVenue(apiVenue) or transformVenue(apiVenue) continue
14
+ * to work unchanged; re-exports don't redeclare the identifier so the
15
+ * no-shadowed-helper rule is satisfied without a suppression.
16
+ */
17
+ export { vcParseVenue as parseVenue };
18
+ export declare const transformVenue: typeof vcParseVenue;
19
+ /**
20
+ * Extract fee configuration from a raw venue payload.
21
+ *
22
+ * Uses `??` (not `||`) so 0-valued fees are preserved correctly.
23
+ */
24
+ declare function vcExtractVenueFees(raw: unknown): {
25
+ serviceFeePercentage: number;
26
+ serviceFeeCents: number;
27
+ taxPercentage: number;
28
+ };
29
+ /**
30
+ * Get formatted venue address.
31
+ *
32
+ * Compare-first vs SC canonical formatVenueAddress(venue: Pick<ParsedVenue,
33
+ * 'address'|'city'|'state'|...>): GENUINELY DIVERGED — VC takes its own `Venue`
34
+ * domain type (the resolved shape `vcParseVenue` emits), not SC's `ParsedVenue`
35
+ * pick. Kept local under a non-shadowing name and re-exported below; no
36
+ * eslint-disable.
37
+ */
38
+ declare function vcFormatVenueAddress(venue: Venue): string;
39
+ export { vcExtractVenueFees as extractVenueFees, vcFormatVenueAddress as formatVenueAddress, };
@@ -0,0 +1,33 @@
1
+ import { Venue } from './types.js';
2
+ /**
3
+ * Get venue details (public, no auth required)
4
+ *
5
+ * Fetches venue information including service fees and taxes
6
+ * needed for checkout calculations.
7
+ *
8
+ * @param venueId - The venue ID
9
+ * @returns Venue details or null on error
10
+ */
11
+ export declare function getVenue(venueId: string | number): Promise<Venue | null>;
12
+ /**
13
+ * Get venue service fee configuration
14
+ *
15
+ * Returns just the fee-related fields for checkout calculations.
16
+ *
17
+ * @param venueId - The venue ID
18
+ * @returns Fee configuration or null on error
19
+ */
20
+ export declare function getVenueFees(venueId: string | number): Promise<{
21
+ serviceFeePercentage: number;
22
+ serviceFeeCents: number;
23
+ taxPercentage: number;
24
+ } | null>;
25
+ /**
26
+ * Get venue by slug
27
+ *
28
+ * Fetches venue using its URL-friendly slug.
29
+ *
30
+ * @param slug - The venue slug
31
+ * @returns Venue details or null on error
32
+ */
33
+ export declare function getVenueBySlug(slug: string): Promise<Venue | null>;
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Waitlist API
3
+ *
4
+ * Endpoints for the sold-out-event waitlist flow.
5
+ */
6
+ export interface JoinWaitlistResult {
7
+ success: boolean;
8
+ updated?: boolean;
9
+ error?: string;
10
+ }
11
+ /**
12
+ * Join the waitlist for a sold-out event.
13
+ */
14
+ export declare function joinWaitlist(eventId: string | number, email: string, phone?: string | null, smsOptIn?: boolean): Promise<JoinWaitlistResult>;
15
+ export interface ValidateWaitlistTokenResult {
16
+ valid: boolean;
17
+ eventId: number;
18
+ /**
19
+ * Present only when `valid` is false. One of the server's failure enums:
20
+ * invalid_token | token_expired | token_used | email_mismatch |
21
+ * inventory_exhausted. Callers map it to friendly copy.
22
+ */
23
+ errorCode?: string;
24
+ }
25
+ /**
26
+ * Validate a tokenized waitlist unlock link (decisions #3/#22/#36).
27
+ *
28
+ * A waitlister receives an email link carrying an opaque token bound to their
29
+ * email. Presenting a valid (token, email) pair unlocks the normal Buy Tickets
30
+ * flow on an otherwise-gated sold-out event, routing freed inventory to the
31
+ * notified buyer. Failures are surfaced (not thrown) so the page can show a
32
+ * non-blocking notice while keeping the event in its gated waitlist state.
33
+ */
34
+ export declare function validateWaitlistToken(token: string, email: string): Promise<ValidateWaitlistTokenResult>;
35
+ export interface WaitlistStatusResult {
36
+ waitlistEnabled: boolean;
37
+ soldOut: boolean;
38
+ /**
39
+ * When gated, the public event page should present "Sold Out — join the
40
+ * waitlist" to non-members even if tickets are technically available, and only
41
+ * a valid tokenized link unlocks checkout (reconciled decision #3).
42
+ */
43
+ gated: boolean;
44
+ }
45
+ /**
46
+ * Fetch an event's waitlist gating status. Returns a non-gated default if the
47
+ * request fails so the page degrades to normal behavior.
48
+ */
49
+ export declare function getWaitlistStatus(eventId: string | number): Promise<WaitlistStatusResult>;