wedance-shared 1.0.158 → 1.0.161
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/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.js +1 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/poll.d.ts +102 -0
- package/dist/types/poll.js +2 -0
- package/dist/types/poll.js.map +1 -0
- package/dist/types/ticket.d.ts +87 -6
- package/dist/utils/ticket.d.ts +32 -0
- package/dist/utils/ticket.js +28 -0
- package/dist/utils/ticket.js.map +1 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC"}
|
package/dist/types/index.d.ts
CHANGED
package/dist/types/index.js
CHANGED
|
@@ -12,6 +12,7 @@ export * from "./support.js";
|
|
|
12
12
|
export * from "./coupons.js";
|
|
13
13
|
export * from "./checkin.js";
|
|
14
14
|
export * from "./pass.js";
|
|
15
|
+
export * from "./poll.js";
|
|
15
16
|
// Re-export from subdirectories
|
|
16
17
|
export * from "./festivals/index.js";
|
|
17
18
|
//# sourceMappingURL=index.js.map
|
package/dist/types/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,4CAA4C;AAC5C,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAE1B,gCAAgC;AAChC,cAAc,sBAAsB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,4CAA4C;AAC5C,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAE1B,gCAAgC;AAChC,cAAc,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { LanguageCode } from "./other.js";
|
|
2
|
+
/**
|
|
3
|
+
* Mirrors the `{ fi, en }` shape already used by `Organizer.description`.
|
|
4
|
+
*/
|
|
5
|
+
export type LocalizedText = {
|
|
6
|
+
en: string;
|
|
7
|
+
fi: string;
|
|
8
|
+
};
|
|
9
|
+
export type PollQuestionType = "single_choice" | "multi_choice" | "text";
|
|
10
|
+
export type PollQuestionOption = {
|
|
11
|
+
/** Stable human-readable slug, e.g. "weekly". Never renamed after publish. */
|
|
12
|
+
id: string;
|
|
13
|
+
label: LocalizedText;
|
|
14
|
+
};
|
|
15
|
+
export type PollQuestion = {
|
|
16
|
+
/** Stable slug, unique within the poll, e.g. "q1". */
|
|
17
|
+
id: string;
|
|
18
|
+
type: PollQuestionType;
|
|
19
|
+
body: LocalizedText;
|
|
20
|
+
/** Present for "single" and "multi". Omitted for "text". */
|
|
21
|
+
options?: PollQuestionOption[];
|
|
22
|
+
/** "multi" only. Omit for no limit. */
|
|
23
|
+
maxSelections?: number;
|
|
24
|
+
isRequired: boolean;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Row shape for `public.polls`.
|
|
28
|
+
*/
|
|
29
|
+
export type Poll = {
|
|
30
|
+
id: string;
|
|
31
|
+
title: LocalizedText;
|
|
32
|
+
description: LocalizedText | null;
|
|
33
|
+
questions: PollQuestion[];
|
|
34
|
+
startsAt: string;
|
|
35
|
+
endsAt: string;
|
|
36
|
+
createdAt: string;
|
|
37
|
+
updatedAt: string;
|
|
38
|
+
status: "draft" | "published" | "archived";
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Answer value per question type:
|
|
42
|
+
* - "single" → option id
|
|
43
|
+
* - "multi" → option ids
|
|
44
|
+
* - "text" → the raw text
|
|
45
|
+
*/
|
|
46
|
+
export type PollAnswerValue = string | string[];
|
|
47
|
+
export type PollAnswers = Record<string, PollAnswerValue>;
|
|
48
|
+
/**
|
|
49
|
+
* Row shape for `public.poll_responses`.
|
|
50
|
+
*/
|
|
51
|
+
export type PollResponse = {
|
|
52
|
+
id: string;
|
|
53
|
+
pollId: string;
|
|
54
|
+
userId: string;
|
|
55
|
+
answers: PollAnswers;
|
|
56
|
+
/** Snapshot of the user's city at submit time. */
|
|
57
|
+
city: string | null;
|
|
58
|
+
/** Language the app was in when answering. */
|
|
59
|
+
language: LanguageCode | null;
|
|
60
|
+
createdAt: string;
|
|
61
|
+
};
|
|
62
|
+
/** `GET /polls/active` — null when no poll is running. */
|
|
63
|
+
export type ActivePollResponse = {
|
|
64
|
+
poll: Poll;
|
|
65
|
+
hasAnswered: boolean;
|
|
66
|
+
} | null;
|
|
67
|
+
/** `POST /polls/:id/responses` */
|
|
68
|
+
export type SubmitPollResponseInput = {
|
|
69
|
+
answers: PollAnswers;
|
|
70
|
+
language?: LanguageCode;
|
|
71
|
+
};
|
|
72
|
+
export type PollOptionTally = {
|
|
73
|
+
optionId: string;
|
|
74
|
+
count: number;
|
|
75
|
+
/** 0–100, rounded to one decimal. */
|
|
76
|
+
percentage: number;
|
|
77
|
+
};
|
|
78
|
+
export type PollQuestionResults = {
|
|
79
|
+
questionId: string;
|
|
80
|
+
type: PollQuestionType;
|
|
81
|
+
/** Choice questions only. */
|
|
82
|
+
tallies?: PollOptionTally[];
|
|
83
|
+
/** Text questions only — admin-visible, for manual quote selection. */
|
|
84
|
+
textAnswers?: {
|
|
85
|
+
text: string;
|
|
86
|
+
city: string | null;
|
|
87
|
+
language: LanguageCode | null;
|
|
88
|
+
}[];
|
|
89
|
+
/** Responses that answered this question. */
|
|
90
|
+
answeredCount: number;
|
|
91
|
+
};
|
|
92
|
+
/** `GET /polls/:id/results` — admin only. */
|
|
93
|
+
export type PollResults = {
|
|
94
|
+
pollId: string;
|
|
95
|
+
totalResponses: number;
|
|
96
|
+
/** Response counts per city, descending. */
|
|
97
|
+
byCity: {
|
|
98
|
+
city: string;
|
|
99
|
+
count: number;
|
|
100
|
+
}[];
|
|
101
|
+
questions: PollQuestionResults[];
|
|
102
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"poll.js","sourceRoot":"","sources":["../../src/types/poll.ts"],"names":[],"mappings":""}
|
package/dist/types/ticket.d.ts
CHANGED
|
@@ -78,7 +78,12 @@ export type TicketTransfer = {
|
|
|
78
78
|
toUserId: string;
|
|
79
79
|
timestamp: Timestamp;
|
|
80
80
|
};
|
|
81
|
-
|
|
81
|
+
/**
|
|
82
|
+
* Fields shared by every product sold through the `ticket_types` table, regardless
|
|
83
|
+
* of `productType`. Exported so consumers can type "any ticket" for forms and table
|
|
84
|
+
* rows without narrowing; use {@link TicketType} when the variant matters.
|
|
85
|
+
*/
|
|
86
|
+
export type TicketTypeBase = {
|
|
82
87
|
id: string;
|
|
83
88
|
/**
|
|
84
89
|
* ID from firebase firestore
|
|
@@ -89,7 +94,6 @@ export type EventTicket = {
|
|
|
89
94
|
*/
|
|
90
95
|
externalEventTicketId: string | null | undefined;
|
|
91
96
|
price_details: MonetaryAmount;
|
|
92
|
-
eventId: string;
|
|
93
97
|
quantity: number;
|
|
94
98
|
showQuantity: boolean;
|
|
95
99
|
/**
|
|
@@ -117,6 +121,20 @@ export type EventTicket = {
|
|
|
117
121
|
* Promotional period for the ticket
|
|
118
122
|
*/
|
|
119
123
|
promotionalPeriod: PromotionalPeriod | null;
|
|
124
|
+
organizerId: string;
|
|
125
|
+
};
|
|
126
|
+
/**
|
|
127
|
+
* A ticket sold for one specific event. The only variant currently written in
|
|
128
|
+
* production — the server hardcodes `product_type = 'event'` on insert.
|
|
129
|
+
*/
|
|
130
|
+
export type EventTicketType = TicketTypeBase & {
|
|
131
|
+
productType: "event";
|
|
132
|
+
eventId: string;
|
|
133
|
+
credits?: never;
|
|
134
|
+
validityDays?: never;
|
|
135
|
+
validFrom?: never;
|
|
136
|
+
validUntil?: never;
|
|
137
|
+
seriesId?: never;
|
|
120
138
|
/**
|
|
121
139
|
* @deprecated Replaced by name
|
|
122
140
|
*/
|
|
@@ -125,14 +143,77 @@ export type EventTicket = {
|
|
|
125
143
|
* @deprecated Replaced by price_details
|
|
126
144
|
*/
|
|
127
145
|
price?: number;
|
|
128
|
-
|
|
129
|
-
|
|
146
|
+
};
|
|
147
|
+
/**
|
|
148
|
+
* Single-class drop-in. May be attached to a specific event, or sold standalone
|
|
149
|
+
* and redeemed against any qualifying class.
|
|
150
|
+
*/
|
|
151
|
+
export type DropInTicketType = TicketTypeBase & {
|
|
152
|
+
productType: "drop_in";
|
|
153
|
+
eventId: string | null;
|
|
154
|
+
credits?: never;
|
|
155
|
+
seriesId?: never;
|
|
156
|
+
validityDays?: never;
|
|
157
|
+
validFrom?: never;
|
|
158
|
+
validUntil?: never;
|
|
159
|
+
};
|
|
160
|
+
/**
|
|
161
|
+
* A bundle of N classes. Not tied to any event.
|
|
162
|
+
*/
|
|
163
|
+
export type PassTicketType = TicketTypeBase & {
|
|
164
|
+
productType: "pass";
|
|
165
|
+
eventId: null;
|
|
166
|
+
/**
|
|
167
|
+
* Number of classes the pass is worth. Required and non-nullable: a pass with
|
|
168
|
+
* no credit count is a misconfiguration, not a meaningful state. Encoding this
|
|
169
|
+
* in the type prevents the `credits ?? 1` fallback that silently turned a
|
|
170
|
+
* 10-class pass into a 1-credit pass.
|
|
171
|
+
*/
|
|
172
|
+
credits: number;
|
|
130
173
|
validityDays: number | null;
|
|
131
174
|
validFrom: string | null;
|
|
132
175
|
validUntil: string | null;
|
|
133
|
-
|
|
134
|
-
|
|
176
|
+
seriesId?: never;
|
|
177
|
+
};
|
|
178
|
+
/**
|
|
179
|
+
* Unlimited access for a period. Deliberately has **no** `credits` field —
|
|
180
|
+
* "unlimited" is expressed structurally by the field's absence rather than by a
|
|
181
|
+
* `null` that would be indistinguishable from a misconfigured pass.
|
|
182
|
+
*/
|
|
183
|
+
export type MembershipTicketType = TicketTypeBase & {
|
|
184
|
+
productType: "membership";
|
|
185
|
+
eventId: null;
|
|
186
|
+
credits?: never;
|
|
187
|
+
validityDays: number | null;
|
|
188
|
+
validFrom: string | null;
|
|
189
|
+
validUntil: string | null;
|
|
190
|
+
seriesId?: never;
|
|
191
|
+
};
|
|
192
|
+
/**
|
|
193
|
+
* Enrollment in a course series. Always belongs to a series; `credits` is
|
|
194
|
+
* nullable here because a course may grant a fixed number of sessions or cover
|
|
195
|
+
* the whole series.
|
|
196
|
+
*/
|
|
197
|
+
export type CourseTicketType = TicketTypeBase & {
|
|
198
|
+
productType: "course";
|
|
199
|
+
eventId: null;
|
|
200
|
+
seriesId: string;
|
|
201
|
+
credits: number | null;
|
|
202
|
+
validityDays?: never;
|
|
203
|
+
validFrom?: never;
|
|
204
|
+
validUntil?: never;
|
|
135
205
|
};
|
|
206
|
+
/**
|
|
207
|
+
* Anything sellable from the `ticket_types` table, discriminated on
|
|
208
|
+
* `productType`. Narrow with a `switch (t.productType)` or with the
|
|
209
|
+
* `is*TicketType` guards before reading variant-specific fields.
|
|
210
|
+
*/
|
|
211
|
+
export type TicketType = EventTicketType | DropInTicketType | PassTicketType | MembershipTicketType | CourseTicketType;
|
|
212
|
+
/**
|
|
213
|
+
* @deprecated Prefer the explicit {@link EventTicketType}, or {@link TicketType}
|
|
214
|
+
* when the product may not be an event. Retained for backward compatibility.
|
|
215
|
+
*/
|
|
216
|
+
export type EventTicket = EventTicketType;
|
|
136
217
|
export type ProductType = "event" | "drop_in" | "pass" | "membership" | "course";
|
|
137
218
|
export type EventTicketStatus = "published" | "draft" | "sold-out" | "unavailable";
|
|
138
219
|
export type PromotionalPeriod = {
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Narrowing helpers for the {@link TicketType} discriminated union.
|
|
3
|
+
*
|
|
4
|
+
* At an API boundary the value arrives as `unknown` (parsed JSON), so narrow in
|
|
5
|
+
* two steps:
|
|
6
|
+
*
|
|
7
|
+
* ```ts
|
|
8
|
+
* const json: unknown = await res.json();
|
|
9
|
+
* if (!isTicketType(json)) throw new Error("not a ticket type");
|
|
10
|
+
* // json is TicketType here
|
|
11
|
+
* if (isPassTicketType(json)) {
|
|
12
|
+
* json.credits; // number — required and non-nullable on a pass
|
|
13
|
+
* }
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
* Inside code that already holds a `TicketType`, prefer an exhaustive
|
|
17
|
+
* `switch (t.productType)` over chained guards — the compiler will then flag any
|
|
18
|
+
* variant added later.
|
|
19
|
+
*/
|
|
20
|
+
import type { CourseTicketType, DropInTicketType, EventTicketType, MembershipTicketType, PassTicketType, TicketType } from "../types/ticket.js";
|
|
21
|
+
/**
|
|
22
|
+
* Shallow structural check for use at API boundaries where the value is
|
|
23
|
+
* `unknown`. Verifies the discriminant and the fields common to every variant —
|
|
24
|
+
* it does not validate variant-specific fields, so it is a gate against
|
|
25
|
+
* malformed payloads rather than a full schema validation.
|
|
26
|
+
*/
|
|
27
|
+
export declare const isTicketType: (value: unknown) => value is TicketType;
|
|
28
|
+
export declare const isEventTicketType: (t: TicketType) => t is EventTicketType;
|
|
29
|
+
export declare const isDropInTicketType: (t: TicketType) => t is DropInTicketType;
|
|
30
|
+
export declare const isPassTicketType: (t: TicketType) => t is PassTicketType;
|
|
31
|
+
export declare const isMembershipTicketType: (t: TicketType) => t is MembershipTicketType;
|
|
32
|
+
export declare const isCourseTicketType: (t: TicketType) => t is CourseTicketType;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
const PRODUCT_TYPES = [
|
|
2
|
+
"event",
|
|
3
|
+
"drop_in",
|
|
4
|
+
"pass",
|
|
5
|
+
"membership",
|
|
6
|
+
"course"
|
|
7
|
+
];
|
|
8
|
+
/**
|
|
9
|
+
* Shallow structural check for use at API boundaries where the value is
|
|
10
|
+
* `unknown`. Verifies the discriminant and the fields common to every variant —
|
|
11
|
+
* it does not validate variant-specific fields, so it is a gate against
|
|
12
|
+
* malformed payloads rather than a full schema validation.
|
|
13
|
+
*/
|
|
14
|
+
export const isTicketType = (value) => {
|
|
15
|
+
if (typeof value !== "object" || value === null)
|
|
16
|
+
return false;
|
|
17
|
+
const candidate = value;
|
|
18
|
+
return (typeof candidate.id === "string" &&
|
|
19
|
+
typeof candidate.name === "string" &&
|
|
20
|
+
typeof candidate.productType === "string" &&
|
|
21
|
+
PRODUCT_TYPES.includes(candidate.productType));
|
|
22
|
+
};
|
|
23
|
+
export const isEventTicketType = (t) => t.productType === "event";
|
|
24
|
+
export const isDropInTicketType = (t) => t.productType === "drop_in";
|
|
25
|
+
export const isPassTicketType = (t) => t.productType === "pass";
|
|
26
|
+
export const isMembershipTicketType = (t) => t.productType === "membership";
|
|
27
|
+
export const isCourseTicketType = (t) => t.productType === "course";
|
|
28
|
+
//# sourceMappingURL=ticket.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ticket.js","sourceRoot":"","sources":["../../src/utils/ticket.ts"],"names":[],"mappings":"AA6BA,MAAM,aAAa,GAA2B;IAC5C,OAAO;IACP,SAAS;IACT,MAAM;IACN,YAAY;IACZ,QAAQ;CACT,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,KAAc,EAAuB,EAAE;IAClE,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC9D,MAAM,SAAS,GAAG,KAAgC,CAAC;IACnD,OAAO,CACL,OAAO,SAAS,CAAC,EAAE,KAAK,QAAQ;QAChC,OAAO,SAAS,CAAC,IAAI,KAAK,QAAQ;QAClC,OAAO,SAAS,CAAC,WAAW,KAAK,QAAQ;QACzC,aAAa,CAAC,QAAQ,CAAC,SAAS,CAAC,WAA0B,CAAC,CAC7D,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAa,EAAwB,EAAE,CACvE,CAAC,CAAC,WAAW,KAAK,OAAO,CAAC;AAE5B,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAa,EAAyB,EAAE,CACzE,CAAC,CAAC,WAAW,KAAK,SAAS,CAAC;AAE9B,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAa,EAAuB,EAAE,CACrE,CAAC,CAAC,WAAW,KAAK,MAAM,CAAC;AAE3B,MAAM,CAAC,MAAM,sBAAsB,GAAG,CACpC,CAAa,EACc,EAAE,CAAC,CAAC,CAAC,WAAW,KAAK,YAAY,CAAC;AAE/D,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAa,EAAyB,EAAE,CACzE,CAAC,CAAC,WAAW,KAAK,QAAQ,CAAC"}
|
package/package.json
CHANGED