@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.
- package/README.md +2 -0
- package/dist/CartView-DBV2yZaL.js +2466 -0
- package/dist/CartView-DBV2yZaL.js.map +1 -0
- package/dist/{Checkout-nyPWpzmE.js → Checkout-CukZs5WU.js} +5 -5
- package/dist/{Checkout-nyPWpzmE.js.map → Checkout-CukZs5WU.js.map} +1 -1
- package/dist/{Checkout-ns94gCrx.js → Checkout-DBXrhhKW.js} +54 -54
- package/dist/{Checkout-ns94gCrx.js.map → Checkout-DBXrhhKW.js.map} +1 -1
- package/dist/{CheckoutTimer-Bv4qR0Mn.js → CheckoutTimer-C7osBosg.js} +5 -5
- package/dist/{CheckoutTimer-Bv4qR0Mn.js.map → CheckoutTimer-C7osBosg.js.map} +1 -1
- package/dist/{ClockIcon-D2ib_bzt.js → ClockIcon-BeCxOp69.js} +2 -2
- package/dist/{ClockIcon-D2ib_bzt.js.map → ClockIcon-BeCxOp69.js.map} +1 -1
- package/dist/{CollectionView-G3OmVuiX.js → CollectionView-CMm-2iBY.js} +44 -45
- package/dist/CollectionView-CMm-2iBY.js.map +1 -0
- package/dist/{Event-B1syGqOf.js → Event-CGnKZ-pZ.js} +585 -581
- package/dist/Event-CGnKZ-pZ.js.map +1 -0
- package/dist/{EventPage-CqryTYfg.js → EventPage-DBGHmWGD.js} +10 -10
- package/dist/EventPage-DBGHmWGD.js.map +1 -0
- package/dist/{Heading-BM6t9w6d.js → Heading-NDMjqlhz.js} +5 -5
- package/dist/Heading-NDMjqlhz.js.map +1 -0
- package/dist/{ScarcityBadge-B7KnIEoD.js → ScarcityBadge-BqL0twaw.js} +28 -28
- package/dist/{ScarcityBadge-B7KnIEoD.js.map → ScarcityBadge-BqL0twaw.js.map} +1 -1
- package/dist/{SeriesPage-DYbBhYHy.js → SeriesPage-BggX59ED.js} +5 -5
- package/dist/{SeriesPage-DYbBhYHy.js.map → SeriesPage-BggX59ED.js.map} +1 -1
- package/dist/{Spinner-D2Ff-2jf.js → Spinner-C4aYrnjh.js} +2 -2
- package/dist/{Spinner-D2Ff-2jf.js.map → Spinner-C4aYrnjh.js.map} +1 -1
- package/dist/{Success-CPQuVaaV.js → Success-BtREZD7W.js} +8 -8
- package/dist/Success-BtREZD7W.js.map +1 -0
- package/dist/{Text-C-9C-Rav.js → Text-B0QR6Ape.js} +4 -4
- package/dist/{Text-C-9C-Rav.js.map → Text-B0QR6Ape.js.map} +1 -1
- package/dist/{VenueCalendar-Dkr4qm4p.js → VenueCalendar-DIAMhER4.js} +4143 -4091
- package/dist/VenueCalendar-DIAMhER4.js.map +1 -0
- package/dist/{ViewTicketsEmbed-B581Bukn.js → ViewTicketsEmbed-D4zF9Qgm.js} +388 -381
- package/dist/{ViewTicketsEmbed-B581Bukn.js.map → ViewTicketsEmbed-D4zF9Qgm.js.map} +1 -1
- package/dist/api/api/client.d.ts +17 -0
- package/dist/api/api/cta.d.ts +34 -0
- package/dist/api/api/events.d.ts +183 -0
- package/dist/api/api/gift-cards.d.ts +108 -0
- package/dist/api/api/index.d.ts +46 -0
- package/dist/api/api/orders.d.ts +149 -0
- package/dist/api/api/promo.d.ts +45 -0
- package/dist/api/api/result.d.ts +78 -0
- package/dist/api/api/route-manifest.d.ts +179 -0
- package/dist/api/api/transformers/address.d.ts +18 -0
- package/dist/api/api/transformers/cart.d.ts +19 -0
- package/dist/api/api/transformers/collection.d.ts +12 -0
- package/dist/api/api/transformers/event.d.ts +173 -0
- package/dist/api/api/transformers/giftCard.d.ts +11 -0
- package/dist/api/api/transformers/index.d.ts +27 -0
- package/dist/api/api/transformers/order.d.ts +44 -0
- package/dist/api/api/transformers/performer.d.ts +8 -0
- package/dist/api/api/transformers/series.d.ts +12 -0
- package/dist/api/api/transformers/venue.d.ts +39 -0
- package/dist/api/api/venues.d.ts +33 -0
- package/dist/api/api/waitlist.d.ts +49 -0
- package/dist/api/api.cjs +2 -0
- package/dist/api/api.cjs.map +1 -0
- package/dist/api/api.mjs +1302 -0
- package/dist/api/api.mjs.map +1 -0
- package/dist/api/types.d.ts +483 -0
- package/dist/{labels-DAFwZdnA.js → labels-CUDO5VqI.js} +3 -3
- package/dist/{labels-DAFwZdnA.js.map → labels-CUDO5VqI.js.map} +1 -1
- package/dist/{modalManager.svelte-BbA2uxS7.js → modalManager.svelte-CWfqhQHL.js} +2 -2
- package/dist/{modalManager.svelte-BbA2uxS7.js.map → modalManager.svelte-CWfqhQHL.js.map} +1 -1
- package/dist/navigation--gZASiSa.js.map +1 -1
- package/dist/{promo-BGoSmBd_.js → promo-4scuh00Y.js} +9 -9
- package/dist/{promo-BGoSmBd_.js.map → promo-4scuh00Y.js.map} +1 -1
- package/dist/seo/HostSeoController.d.ts +68 -0
- package/dist/seo/buildCollectionJsonLd.d.ts +8 -0
- package/dist/seo/buildEventJsonLd.d.ts +9 -0
- package/dist/seo/buildSeriesJsonLd.d.ts +6 -0
- package/dist/seo/helpers.d.ts +88 -0
- package/dist/seo/index.d.ts +10 -0
- package/dist/seo/seo.cjs +2 -0
- package/dist/seo/seo.cjs.map +1 -0
- package/dist/seo/seo.mjs +688 -0
- package/dist/seo/seo.mjs.map +1 -0
- package/dist/seo/types.d.ts +149 -0
- package/dist/{showcase-state-options-BWzGMPZ-.js → showcase-state-options-DG5Bn9mL.js} +2 -2
- package/dist/showcase-state-options-DG5Bn9mL.js.map +1 -0
- package/dist/{transform-CpjZiH34.js → transform-B1kRFSE7.js} +10 -10
- package/dist/{transform-CpjZiH34.js.map → transform-B1kRFSE7.js.map} +1 -1
- package/dist/{utm-D1uGUvk2.js → utm-CPOH8BYT.js} +2 -2
- package/dist/{utm-D1uGUvk2.js.map → utm-CPOH8BYT.js.map} +1 -1
- package/dist/venue-calendar.css +1 -1
- package/dist/venue-calendar.es.js +4 -4
- package/dist/venue-calendar.iife.js +37 -37
- package/dist/venue-calendar.iife.js.map +1 -1
- package/dist/venue-calendar.umd.js +32 -32
- package/dist/venue-calendar.umd.js.map +1 -1
- package/package.json +7 -3
- package/dist/CartView-H6PXIc8m.js +0 -2475
- package/dist/CartView-H6PXIc8m.js.map +0 -1
- package/dist/CollectionView-G3OmVuiX.js.map +0 -1
- package/dist/Event-B1syGqOf.js.map +0 -1
- package/dist/EventPage-CqryTYfg.js.map +0 -1
- package/dist/Heading-BM6t9w6d.js.map +0 -1
- package/dist/Success-CPQuVaaV.js.map +0 -1
- package/dist/VenueCalendar-Dkr4qm4p.js.map +0 -1
- 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>;
|