@orakl/protocol 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/LICENSE +662 -0
  2. package/dist/badges.d.ts +19 -0
  3. package/dist/badges.js +1 -0
  4. package/dist/emotes.d.ts +5 -0
  5. package/dist/emotes.js +62 -0
  6. package/dist/error-codes.d.ts +1 -0
  7. package/dist/error-codes.js +1 -0
  8. package/dist/game-answer-record.d.ts +31 -0
  9. package/dist/game-answer-record.js +1 -0
  10. package/dist/game.d.ts +83 -0
  11. package/dist/game.js +1 -0
  12. package/dist/game.settings.d.ts +91 -0
  13. package/dist/game.settings.js +61 -0
  14. package/dist/index.d.ts +23 -0
  15. package/dist/index.js +13 -0
  16. package/dist/pages/app.schema.d.ts +544 -0
  17. package/dist/pages/app.schema.js +336 -0
  18. package/dist/pages/auth.schema.d.ts +25 -0
  19. package/dist/pages/auth.schema.js +23 -0
  20. package/dist/pages/common.schema.d.ts +27 -0
  21. package/dist/pages/common.schema.js +28 -0
  22. package/dist/pages/history.schema.d.ts +273 -0
  23. package/dist/pages/history.schema.js +210 -0
  24. package/dist/pages/quiz.schema.d.ts +150 -0
  25. package/dist/pages/quiz.schema.js +132 -0
  26. package/dist/player-safe-question.d.ts +13 -0
  27. package/dist/player-safe-question.js +1 -0
  28. package/dist/question.d.ts +6 -0
  29. package/dist/question.js +12 -0
  30. package/dist/question.schema.d.ts +494 -0
  31. package/dist/question.schema.js +132 -0
  32. package/dist/scoring.schema.d.ts +7 -0
  33. package/dist/scoring.schema.js +8 -0
  34. package/dist/solo-ws.d.ts +202 -0
  35. package/dist/solo-ws.js +4 -0
  36. package/dist/streak-flourish.d.ts +6 -0
  37. package/dist/streak-flourish.js +1 -0
  38. package/dist/wire/leaderboard.d.ts +6 -0
  39. package/dist/wire/leaderboard.js +1 -0
  40. package/dist/wire/question-bank.d.ts +23 -0
  41. package/dist/wire/question-bank.js +1 -0
  42. package/dist/wire/question-flags.d.ts +40 -0
  43. package/dist/wire/question-flags.js +1 -0
  44. package/dist/ws-game.schema.d.ts +75 -0
  45. package/dist/ws-game.schema.js +131 -0
  46. package/dist/ws-solo.schema.d.ts +31 -0
  47. package/dist/ws-solo.schema.js +57 -0
  48. package/dist/ws.d.ts +281 -0
  49. package/dist/ws.js +1 -0
  50. package/package.json +39 -0
@@ -0,0 +1,132 @@
1
+ import { Schema } from "effect";
2
+ import { GAME } from "../game.settings.js";
3
+ import { GameAnswerRecordSchema, PlayerRoleSchema, SkyPhaseSchema, ThemeModeSchema, UserPowerSchema, UserRoleSchema, } from "./common.schema.js";
4
+ /** Page-load response bodies for `src/api/routes/layout.ts and quiz.ts`. */
5
+ // ---- auth (RootLayoutData's `user`, stripped of email/sid) ----
6
+ const LayoutUserSchema = Schema.Struct({
7
+ id: Schema.String,
8
+ nickname: Schema.NullOr(Schema.String),
9
+ avatar: Schema.NullOr(Schema.String),
10
+ role: UserRoleSchema,
11
+ powers: Schema.mutable(Schema.Array(UserPowerSchema)),
12
+ lobbyCode: Schema.NullOr(Schema.String),
13
+ lobbyRole: Schema.optional(Schema.Literal("curator")),
14
+ accountRole: Schema.optional(UserRoleSchema),
15
+ emailVerified: Schema.Boolean,
16
+ accountUserId: Schema.optional(Schema.String),
17
+ });
18
+ // ---- theme ----
19
+ const ResolvedThemeSchema = Schema.Struct({
20
+ mode: ThemeModeSchema,
21
+ effective: Schema.Literal("dark", "light"),
22
+ phase: SkyPhaseSchema,
23
+ showStars: Schema.Boolean,
24
+ showSky: Schema.Boolean,
25
+ showBirds: Schema.Boolean,
26
+ skyTimeOfDay: Schema.Literal("dawn", "morning", "noon", "evening", "sunset", "dusk"),
27
+ renderBoth: Schema.Boolean,
28
+ });
29
+ // ---- analytics ----
30
+ const AnalyticsStateSchema = Schema.Struct({
31
+ enabled: Schema.Boolean,
32
+ browserSignal: Schema.Boolean,
33
+ });
34
+ // ---- uiFlags: every flag the client may need resolved, all optional ----
35
+ const UiFlagsSchema = Schema.partial(Schema.Struct({
36
+ FEEDBACK_WIDGET: Schema.Boolean,
37
+ ENABLE_IMPORTS: Schema.Boolean,
38
+ PLAYER_HISTORY: Schema.Boolean,
39
+ CURATOR_HISTORY: Schema.Boolean,
40
+ SOLO_LEADERBOARDS: Schema.Boolean,
41
+ QUIZ_SCORING_MODES: Schema.Boolean,
42
+ QUIZ_ACCESS_MODES: Schema.Boolean,
43
+ QUIZ_MAX_PLAYERS: Schema.Boolean,
44
+ QUIZ_PRESETS: Schema.Boolean,
45
+ IMAGE_QUIZ_CATEGORY: Schema.Boolean,
46
+ BADGE_DISPLAY: Schema.Boolean,
47
+ ROLE_SELECTION: Schema.Boolean,
48
+ }));
49
+ /** Body of `GET /api/layout`. */
50
+ export const LayoutPageSchema = Schema.Struct({
51
+ user: LayoutUserSchema,
52
+ theme: ResolvedThemeSchema,
53
+ analytics: AnalyticsStateSchema,
54
+ feedbackWidgetEnabled: Schema.Boolean,
55
+ uiFlags: UiFlagsSchema,
56
+ });
57
+ // ---- journey (ADR 0004) ----
58
+ const MembershipSchema = Schema.Literal("none", "pending", "active");
59
+ const ServerPhaseSchema = Schema.Literal("lobby", "playing", "round_results", "final_scores", "role_selection", "intermission");
60
+ const JourneyStateSchema = Schema.Literal("code-entry", "setup", "pending", "lobby", "playing", "role_selection", "final_scores");
61
+ const PlayerJourneySchema = Schema.Struct({
62
+ membership: MembershipSchema,
63
+ phase: Schema.NullOr(ServerPhaseSchema),
64
+ state: JourneyStateSchema,
65
+ route: Schema.String,
66
+ });
67
+ /** Body of `GET /api/quiz/journey`: a `PlayerJourney` plus the registry-miss diagnosis. */
68
+ export const QuizJourneyPageSchema = Schema.Struct({
69
+ ...PlayerJourneySchema.fields,
70
+ miss: Schema.NullOr(Schema.Literal("lobby_lost")),
71
+ });
72
+ // ---- quiz context (the `/quiz/*` layout's session seed) ----
73
+ const DifficultyFilterSchema = Schema.Literal(...GAME.roundConfig.difficultyOptions);
74
+ const PlayerStatusSchema = Schema.Literal("pending", "active", "disconnected");
75
+ const AccessModeSchema = Schema.Literal("open", "invite-only");
76
+ const AvatarSchema = Schema.Struct({
77
+ id: Schema.String,
78
+ title: Schema.String,
79
+ description: Schema.String,
80
+ category: Schema.String,
81
+ src: Schema.String,
82
+ });
83
+ const LobbySchema = Schema.Struct({
84
+ quizName: Schema.String,
85
+ description: Schema.String,
86
+ categories: Schema.mutable(Schema.Array(Schema.String)),
87
+ difficulty: Schema.NullOr(DifficultyFilterSchema),
88
+ accessMode: AccessModeSchema,
89
+ maxPlayers: Schema.NullOr(Schema.Number),
90
+ players: Schema.mutable(Schema.Array(Schema.Struct({
91
+ id: Schema.String,
92
+ nickname: Schema.String,
93
+ avatar: Schema.String,
94
+ score: Schema.Number,
95
+ status: PlayerStatusSchema,
96
+ role: PlayerRoleSchema,
97
+ }))),
98
+ });
99
+ /** Body of `GET /api/quiz/context`. */
100
+ export const QuizContextPageSchema = Schema.Struct({
101
+ membership: MembershipSchema,
102
+ phase: Schema.NullOr(ServerPhaseSchema),
103
+ playerId: Schema.NullOr(Schema.String),
104
+ isCurator: Schema.Boolean,
105
+ curatorNickname: Schema.String,
106
+ curatorAvatarId: Schema.String,
107
+ isLoggedIn: Schema.Boolean,
108
+ profileAvatarId: Schema.String,
109
+ avatars: Schema.mutable(Schema.Array(AvatarSchema)),
110
+ emotesEnabled: Schema.Boolean,
111
+ lobby: Schema.NullOr(LobbySchema),
112
+ // Replayed game WS frames, opaque here — applyStateMessages reads their
113
+ // fields by message `type` on the client, so decoding preserves every key
114
+ // rather than pinning it to one member of the ServerMessage union.
115
+ stateMessages: Schema.mutable(Schema.Array(Schema.Unknown)),
116
+ journey: PlayerJourneySchema,
117
+ });
118
+ // ---- quiz results ----
119
+ /** Body of `GET /api/quiz/results`. */
120
+ export const QuizResultsPageSchema = Schema.Struct({
121
+ isAnonymousPlayer: Schema.Boolean,
122
+ claimed: Schema.Boolean,
123
+ breakdown: Schema.NullOr(Schema.mutable(Schema.Array(GameAnswerRecordSchema))),
124
+ canFlag: Schema.Boolean,
125
+ alreadyFlaggedIds: Schema.mutable(Schema.Array(Schema.String)),
126
+ hostAllowance: Schema.NullOr(Schema.Struct({
127
+ counted: Schema.Boolean,
128
+ used: Schema.Number,
129
+ limit: Schema.Number,
130
+ left: Schema.Number,
131
+ })),
132
+ });
@@ -0,0 +1,13 @@
1
+ import type { QuizQuestion } from "./game.ts";
2
+ import type { PlayerQuestionAnswer } from "./ws.ts";
3
+ /**
4
+ * The question shape safe to put on the wire — answers carry only id + text,
5
+ * never `isCorrect`. `Omit<QuizQuestion, "answers">` collapses the discriminated
6
+ * union to its common keys, so `matchItems` (image_matching only) isn't
7
+ * statically visible here; callers that need it should narrow the *original*
8
+ * `QuizQuestion` (its `type` field) — see `src/lib/question-mapper.ts`'s
9
+ * `toPlayerSafeQuestion`.
10
+ */
11
+ export interface PlayerSafeQuestion extends Omit<QuizQuestion, "answers" | "source" | "postAnswerNote"> {
12
+ answers: PlayerQuestionAnswer[];
13
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,6 @@
1
+ export type { Difficulty, ImageChoiceQuestion, ImageMatchingQuestion, Media, MediaType, Question, QuestionSource, QuestionType, Source, TextChoiceQuestion, TrueFalseQuestion, } from "./question.schema.ts";
2
+ import type { ImageMatchingQuestion, Question, TextChoiceQuestion, TrueFalseQuestion } from "./question.schema.ts";
3
+ export declare function isTextChoice(q: Question): q is TextChoiceQuestion;
4
+ export declare function isTrueFalse(q: Question): q is TrueFalseQuestion;
5
+ export declare function isImageMatching(q: Question): q is ImageMatchingQuestion;
6
+ export declare function hasMedia(q: Question): boolean;
@@ -0,0 +1,12 @@
1
+ export function isTextChoice(q) {
2
+ return q.type === "text_choice";
3
+ }
4
+ export function isTrueFalse(q) {
5
+ return q.type === "true_false";
6
+ }
7
+ export function isImageMatching(q) {
8
+ return q.type === "image_matching";
9
+ }
10
+ export function hasMedia(q) {
11
+ return "media" in q.question && q.question.media !== undefined;
12
+ }
@@ -0,0 +1,494 @@
1
+ import { Schema } from "effect";
2
+ export declare const DifficultySchema: Schema.Literal<["easy", "medium", "hard"]>;
3
+ export declare const MediaTypeSchema: Schema.Literal<["image", "audio", "video"]>;
4
+ export declare const QuestionTypeSchema: Schema.Literal<["text_choice", "image_choice", "true_false", "finish_line", "audio_identify", "sequence_order", "estimate_range", "fill_blank", "matching_pairs", "progressive_reveal", "image_matching"]>;
5
+ export declare const SourceSchema: Schema.Literal<["opentdb", "custom", "the-trivia-api"]>;
6
+ export declare const MediaSchema: Schema.Struct<{
7
+ type: Schema.Literal<["image", "audio", "video"]>;
8
+ url: typeof Schema.String;
9
+ thumbnail: Schema.optional<typeof Schema.String>;
10
+ }>;
11
+ /** True for an https URL WHATWG-parses; false for anything else (including unparsable strings). */
12
+ export declare function isHttpsUrl(url: string): boolean;
13
+ export declare const QuestionSourceSchema: Schema.Struct<{
14
+ url: Schema.filter<Schema.filter<typeof Schema.String>>;
15
+ label: Schema.optional<Schema.filter<typeof Schema.String>>;
16
+ }>;
17
+ export declare const PostAnswerNoteSchema: Schema.filter<typeof Schema.String>;
18
+ declare const TextChoiceSchema: Schema.Struct<{
19
+ type: Schema.Literal<["text_choice"]>;
20
+ id: typeof Schema.String;
21
+ category: typeof Schema.String;
22
+ difficulty: Schema.Literal<["easy", "medium", "hard"]>;
23
+ question: Schema.Struct<{
24
+ text: typeof Schema.String;
25
+ media: Schema.optional<Schema.Struct<{
26
+ type: Schema.Literal<["image", "audio", "video"]>;
27
+ url: typeof Schema.String;
28
+ thumbnail: Schema.optional<typeof Schema.String>;
29
+ }>>;
30
+ }>;
31
+ correctAnswer: typeof Schema.String;
32
+ incorrectAnswers: Schema.Array$<typeof Schema.String>;
33
+ question_fingerprint: Schema.optional<typeof Schema.String>;
34
+ metadata: Schema.Struct<{
35
+ source: Schema.Literal<["opentdb", "custom", "the-trivia-api"]>;
36
+ tags: Schema.optional<Schema.Array$<typeof Schema.String>>;
37
+ region: Schema.optional<Schema.Array$<typeof Schema.String>>;
38
+ isNiche: Schema.optional<typeof Schema.Boolean>;
39
+ timeLimit: Schema.optional<typeof Schema.Number>;
40
+ points: Schema.optional<typeof Schema.Number>;
41
+ }>;
42
+ createdAt: typeof Schema.String;
43
+ source: Schema.optional<Schema.Struct<{
44
+ url: Schema.filter<Schema.filter<typeof Schema.String>>;
45
+ label: Schema.optional<Schema.filter<typeof Schema.String>>;
46
+ }>>;
47
+ postAnswerNote: Schema.optional<Schema.filter<typeof Schema.String>>;
48
+ }>;
49
+ declare const ImageChoiceSchema: Schema.Struct<{
50
+ type: Schema.Literal<["image_choice"]>;
51
+ question: Schema.Struct<{
52
+ text: typeof Schema.String;
53
+ media: Schema.Struct<{
54
+ type: Schema.Literal<["image", "audio", "video"]>;
55
+ url: typeof Schema.String;
56
+ thumbnail: Schema.optional<typeof Schema.String>;
57
+ }>;
58
+ }>;
59
+ id: typeof Schema.String;
60
+ category: typeof Schema.String;
61
+ difficulty: Schema.Literal<["easy", "medium", "hard"]>;
62
+ correctAnswer: typeof Schema.String;
63
+ incorrectAnswers: Schema.Array$<typeof Schema.String>;
64
+ question_fingerprint: Schema.optional<typeof Schema.String>;
65
+ metadata: Schema.Struct<{
66
+ source: Schema.Literal<["opentdb", "custom", "the-trivia-api"]>;
67
+ tags: Schema.optional<Schema.Array$<typeof Schema.String>>;
68
+ region: Schema.optional<Schema.Array$<typeof Schema.String>>;
69
+ isNiche: Schema.optional<typeof Schema.Boolean>;
70
+ timeLimit: Schema.optional<typeof Schema.Number>;
71
+ points: Schema.optional<typeof Schema.Number>;
72
+ }>;
73
+ createdAt: typeof Schema.String;
74
+ source: Schema.optional<Schema.Struct<{
75
+ url: Schema.filter<Schema.filter<typeof Schema.String>>;
76
+ label: Schema.optional<Schema.filter<typeof Schema.String>>;
77
+ }>>;
78
+ postAnswerNote: Schema.optional<Schema.filter<typeof Schema.String>>;
79
+ }>;
80
+ declare const TrueFalseSchema: Schema.Struct<{
81
+ type: Schema.Literal<["true_false"]>;
82
+ correctAnswer: Schema.Literal<["true", "false"]>;
83
+ incorrectAnswers: Schema.Tuple<[Schema.Literal<["true", "false"]>]>;
84
+ id: typeof Schema.String;
85
+ category: typeof Schema.String;
86
+ difficulty: Schema.Literal<["easy", "medium", "hard"]>;
87
+ question: Schema.Struct<{
88
+ text: typeof Schema.String;
89
+ media: Schema.optional<Schema.Struct<{
90
+ type: Schema.Literal<["image", "audio", "video"]>;
91
+ url: typeof Schema.String;
92
+ thumbnail: Schema.optional<typeof Schema.String>;
93
+ }>>;
94
+ }>;
95
+ question_fingerprint: Schema.optional<typeof Schema.String>;
96
+ metadata: Schema.Struct<{
97
+ source: Schema.Literal<["opentdb", "custom", "the-trivia-api"]>;
98
+ tags: Schema.optional<Schema.Array$<typeof Schema.String>>;
99
+ region: Schema.optional<Schema.Array$<typeof Schema.String>>;
100
+ isNiche: Schema.optional<typeof Schema.Boolean>;
101
+ timeLimit: Schema.optional<typeof Schema.Number>;
102
+ points: Schema.optional<typeof Schema.Number>;
103
+ }>;
104
+ createdAt: typeof Schema.String;
105
+ source: Schema.optional<Schema.Struct<{
106
+ url: Schema.filter<Schema.filter<typeof Schema.String>>;
107
+ label: Schema.optional<Schema.filter<typeof Schema.String>>;
108
+ }>>;
109
+ postAnswerNote: Schema.optional<Schema.filter<typeof Schema.String>>;
110
+ }>;
111
+ declare const ImageMatchingSchema: Schema.Struct<{
112
+ type: Schema.Literal<["image_matching"]>;
113
+ question: Schema.Struct<{
114
+ text: typeof Schema.String;
115
+ media: Schema.Struct<{
116
+ type: Schema.Literal<["image", "audio", "video"]>;
117
+ url: typeof Schema.String;
118
+ thumbnail: Schema.optional<typeof Schema.String>;
119
+ }>;
120
+ }>;
121
+ correctAnswer: typeof Schema.String;
122
+ incorrectAnswers: Schema.Array$<typeof Schema.String>;
123
+ matchItems: Schema.Struct<{
124
+ left: Schema.Tuple<[typeof Schema.String, typeof Schema.String, typeof Schema.String, typeof Schema.String]>;
125
+ right: Schema.Tuple<[typeof Schema.String, typeof Schema.String, typeof Schema.String, typeof Schema.String]>;
126
+ }>;
127
+ id: typeof Schema.String;
128
+ category: typeof Schema.String;
129
+ difficulty: Schema.Literal<["easy", "medium", "hard"]>;
130
+ question_fingerprint: Schema.optional<typeof Schema.String>;
131
+ metadata: Schema.Struct<{
132
+ source: Schema.Literal<["opentdb", "custom", "the-trivia-api"]>;
133
+ tags: Schema.optional<Schema.Array$<typeof Schema.String>>;
134
+ region: Schema.optional<Schema.Array$<typeof Schema.String>>;
135
+ isNiche: Schema.optional<typeof Schema.Boolean>;
136
+ timeLimit: Schema.optional<typeof Schema.Number>;
137
+ points: Schema.optional<typeof Schema.Number>;
138
+ }>;
139
+ createdAt: typeof Schema.String;
140
+ source: Schema.optional<Schema.Struct<{
141
+ url: Schema.filter<Schema.filter<typeof Schema.String>>;
142
+ label: Schema.optional<Schema.filter<typeof Schema.String>>;
143
+ }>>;
144
+ postAnswerNote: Schema.optional<Schema.filter<typeof Schema.String>>;
145
+ }>;
146
+ export declare const QuestionSchema: Schema.Union<[Schema.Struct<{
147
+ type: Schema.Literal<["text_choice"]>;
148
+ id: typeof Schema.String;
149
+ category: typeof Schema.String;
150
+ difficulty: Schema.Literal<["easy", "medium", "hard"]>;
151
+ question: Schema.Struct<{
152
+ text: typeof Schema.String;
153
+ media: Schema.optional<Schema.Struct<{
154
+ type: Schema.Literal<["image", "audio", "video"]>;
155
+ url: typeof Schema.String;
156
+ thumbnail: Schema.optional<typeof Schema.String>;
157
+ }>>;
158
+ }>;
159
+ correctAnswer: typeof Schema.String;
160
+ incorrectAnswers: Schema.Array$<typeof Schema.String>;
161
+ question_fingerprint: Schema.optional<typeof Schema.String>;
162
+ metadata: Schema.Struct<{
163
+ source: Schema.Literal<["opentdb", "custom", "the-trivia-api"]>;
164
+ tags: Schema.optional<Schema.Array$<typeof Schema.String>>;
165
+ region: Schema.optional<Schema.Array$<typeof Schema.String>>;
166
+ isNiche: Schema.optional<typeof Schema.Boolean>;
167
+ timeLimit: Schema.optional<typeof Schema.Number>;
168
+ points: Schema.optional<typeof Schema.Number>;
169
+ }>;
170
+ createdAt: typeof Schema.String;
171
+ source: Schema.optional<Schema.Struct<{
172
+ url: Schema.filter<Schema.filter<typeof Schema.String>>;
173
+ label: Schema.optional<Schema.filter<typeof Schema.String>>;
174
+ }>>;
175
+ postAnswerNote: Schema.optional<Schema.filter<typeof Schema.String>>;
176
+ }>, Schema.Struct<{
177
+ type: Schema.Literal<["image_choice"]>;
178
+ question: Schema.Struct<{
179
+ text: typeof Schema.String;
180
+ media: Schema.Struct<{
181
+ type: Schema.Literal<["image", "audio", "video"]>;
182
+ url: typeof Schema.String;
183
+ thumbnail: Schema.optional<typeof Schema.String>;
184
+ }>;
185
+ }>;
186
+ id: typeof Schema.String;
187
+ category: typeof Schema.String;
188
+ difficulty: Schema.Literal<["easy", "medium", "hard"]>;
189
+ correctAnswer: typeof Schema.String;
190
+ incorrectAnswers: Schema.Array$<typeof Schema.String>;
191
+ question_fingerprint: Schema.optional<typeof Schema.String>;
192
+ metadata: Schema.Struct<{
193
+ source: Schema.Literal<["opentdb", "custom", "the-trivia-api"]>;
194
+ tags: Schema.optional<Schema.Array$<typeof Schema.String>>;
195
+ region: Schema.optional<Schema.Array$<typeof Schema.String>>;
196
+ isNiche: Schema.optional<typeof Schema.Boolean>;
197
+ timeLimit: Schema.optional<typeof Schema.Number>;
198
+ points: Schema.optional<typeof Schema.Number>;
199
+ }>;
200
+ createdAt: typeof Schema.String;
201
+ source: Schema.optional<Schema.Struct<{
202
+ url: Schema.filter<Schema.filter<typeof Schema.String>>;
203
+ label: Schema.optional<Schema.filter<typeof Schema.String>>;
204
+ }>>;
205
+ postAnswerNote: Schema.optional<Schema.filter<typeof Schema.String>>;
206
+ }>, Schema.Struct<{
207
+ type: Schema.Literal<["true_false"]>;
208
+ correctAnswer: Schema.Literal<["true", "false"]>;
209
+ incorrectAnswers: Schema.Tuple<[Schema.Literal<["true", "false"]>]>;
210
+ id: typeof Schema.String;
211
+ category: typeof Schema.String;
212
+ difficulty: Schema.Literal<["easy", "medium", "hard"]>;
213
+ question: Schema.Struct<{
214
+ text: typeof Schema.String;
215
+ media: Schema.optional<Schema.Struct<{
216
+ type: Schema.Literal<["image", "audio", "video"]>;
217
+ url: typeof Schema.String;
218
+ thumbnail: Schema.optional<typeof Schema.String>;
219
+ }>>;
220
+ }>;
221
+ question_fingerprint: Schema.optional<typeof Schema.String>;
222
+ metadata: Schema.Struct<{
223
+ source: Schema.Literal<["opentdb", "custom", "the-trivia-api"]>;
224
+ tags: Schema.optional<Schema.Array$<typeof Schema.String>>;
225
+ region: Schema.optional<Schema.Array$<typeof Schema.String>>;
226
+ isNiche: Schema.optional<typeof Schema.Boolean>;
227
+ timeLimit: Schema.optional<typeof Schema.Number>;
228
+ points: Schema.optional<typeof Schema.Number>;
229
+ }>;
230
+ createdAt: typeof Schema.String;
231
+ source: Schema.optional<Schema.Struct<{
232
+ url: Schema.filter<Schema.filter<typeof Schema.String>>;
233
+ label: Schema.optional<Schema.filter<typeof Schema.String>>;
234
+ }>>;
235
+ postAnswerNote: Schema.optional<Schema.filter<typeof Schema.String>>;
236
+ }>, Schema.Struct<{
237
+ type: Schema.Literal<["finish_line"]>;
238
+ question: Schema.Struct<{
239
+ text: typeof Schema.String;
240
+ media: Schema.Struct<{
241
+ type: Schema.Literal<["image", "audio", "video"]>;
242
+ url: typeof Schema.String;
243
+ thumbnail: Schema.optional<typeof Schema.String>;
244
+ }>;
245
+ }>;
246
+ id: typeof Schema.String;
247
+ category: typeof Schema.String;
248
+ difficulty: Schema.Literal<["easy", "medium", "hard"]>;
249
+ correctAnswer: typeof Schema.String;
250
+ incorrectAnswers: Schema.Array$<typeof Schema.String>;
251
+ question_fingerprint: Schema.optional<typeof Schema.String>;
252
+ metadata: Schema.Struct<{
253
+ source: Schema.Literal<["opentdb", "custom", "the-trivia-api"]>;
254
+ tags: Schema.optional<Schema.Array$<typeof Schema.String>>;
255
+ region: Schema.optional<Schema.Array$<typeof Schema.String>>;
256
+ isNiche: Schema.optional<typeof Schema.Boolean>;
257
+ timeLimit: Schema.optional<typeof Schema.Number>;
258
+ points: Schema.optional<typeof Schema.Number>;
259
+ }>;
260
+ createdAt: typeof Schema.String;
261
+ source: Schema.optional<Schema.Struct<{
262
+ url: Schema.filter<Schema.filter<typeof Schema.String>>;
263
+ label: Schema.optional<Schema.filter<typeof Schema.String>>;
264
+ }>>;
265
+ postAnswerNote: Schema.optional<Schema.filter<typeof Schema.String>>;
266
+ }>, Schema.Struct<{
267
+ type: Schema.Literal<["audio_identify"]>;
268
+ question: Schema.Struct<{
269
+ text: typeof Schema.String;
270
+ media: Schema.Struct<{
271
+ type: Schema.Literal<["image", "audio", "video"]>;
272
+ url: typeof Schema.String;
273
+ thumbnail: Schema.optional<typeof Schema.String>;
274
+ }>;
275
+ }>;
276
+ id: typeof Schema.String;
277
+ category: typeof Schema.String;
278
+ difficulty: Schema.Literal<["easy", "medium", "hard"]>;
279
+ correctAnswer: typeof Schema.String;
280
+ incorrectAnswers: Schema.Array$<typeof Schema.String>;
281
+ question_fingerprint: Schema.optional<typeof Schema.String>;
282
+ metadata: Schema.Struct<{
283
+ source: Schema.Literal<["opentdb", "custom", "the-trivia-api"]>;
284
+ tags: Schema.optional<Schema.Array$<typeof Schema.String>>;
285
+ region: Schema.optional<Schema.Array$<typeof Schema.String>>;
286
+ isNiche: Schema.optional<typeof Schema.Boolean>;
287
+ timeLimit: Schema.optional<typeof Schema.Number>;
288
+ points: Schema.optional<typeof Schema.Number>;
289
+ }>;
290
+ createdAt: typeof Schema.String;
291
+ source: Schema.optional<Schema.Struct<{
292
+ url: Schema.filter<Schema.filter<typeof Schema.String>>;
293
+ label: Schema.optional<Schema.filter<typeof Schema.String>>;
294
+ }>>;
295
+ postAnswerNote: Schema.optional<Schema.filter<typeof Schema.String>>;
296
+ }>, Schema.Struct<{
297
+ type: Schema.Literal<["sequence_order"]>;
298
+ id: typeof Schema.String;
299
+ category: typeof Schema.String;
300
+ difficulty: Schema.Literal<["easy", "medium", "hard"]>;
301
+ question: Schema.Struct<{
302
+ text: typeof Schema.String;
303
+ media: Schema.optional<Schema.Struct<{
304
+ type: Schema.Literal<["image", "audio", "video"]>;
305
+ url: typeof Schema.String;
306
+ thumbnail: Schema.optional<typeof Schema.String>;
307
+ }>>;
308
+ }>;
309
+ correctAnswer: typeof Schema.String;
310
+ incorrectAnswers: Schema.Array$<typeof Schema.String>;
311
+ question_fingerprint: Schema.optional<typeof Schema.String>;
312
+ metadata: Schema.Struct<{
313
+ source: Schema.Literal<["opentdb", "custom", "the-trivia-api"]>;
314
+ tags: Schema.optional<Schema.Array$<typeof Schema.String>>;
315
+ region: Schema.optional<Schema.Array$<typeof Schema.String>>;
316
+ isNiche: Schema.optional<typeof Schema.Boolean>;
317
+ timeLimit: Schema.optional<typeof Schema.Number>;
318
+ points: Schema.optional<typeof Schema.Number>;
319
+ }>;
320
+ createdAt: typeof Schema.String;
321
+ source: Schema.optional<Schema.Struct<{
322
+ url: Schema.filter<Schema.filter<typeof Schema.String>>;
323
+ label: Schema.optional<Schema.filter<typeof Schema.String>>;
324
+ }>>;
325
+ postAnswerNote: Schema.optional<Schema.filter<typeof Schema.String>>;
326
+ }>, Schema.Struct<{
327
+ type: Schema.Literal<["estimate_range"]>;
328
+ metadata: Schema.Struct<{
329
+ acceptableRange: typeof Schema.Number;
330
+ source: Schema.Literal<["opentdb", "custom", "the-trivia-api"]>;
331
+ tags: Schema.optional<Schema.Array$<typeof Schema.String>>;
332
+ region: Schema.optional<Schema.Array$<typeof Schema.String>>;
333
+ isNiche: Schema.optional<typeof Schema.Boolean>;
334
+ timeLimit: Schema.optional<typeof Schema.Number>;
335
+ points: Schema.optional<typeof Schema.Number>;
336
+ }>;
337
+ id: typeof Schema.String;
338
+ category: typeof Schema.String;
339
+ difficulty: Schema.Literal<["easy", "medium", "hard"]>;
340
+ question: Schema.Struct<{
341
+ text: typeof Schema.String;
342
+ media: Schema.optional<Schema.Struct<{
343
+ type: Schema.Literal<["image", "audio", "video"]>;
344
+ url: typeof Schema.String;
345
+ thumbnail: Schema.optional<typeof Schema.String>;
346
+ }>>;
347
+ }>;
348
+ correctAnswer: typeof Schema.String;
349
+ incorrectAnswers: Schema.Array$<typeof Schema.String>;
350
+ question_fingerprint: Schema.optional<typeof Schema.String>;
351
+ createdAt: typeof Schema.String;
352
+ source: Schema.optional<Schema.Struct<{
353
+ url: Schema.filter<Schema.filter<typeof Schema.String>>;
354
+ label: Schema.optional<Schema.filter<typeof Schema.String>>;
355
+ }>>;
356
+ postAnswerNote: Schema.optional<Schema.filter<typeof Schema.String>>;
357
+ }>, Schema.Struct<{
358
+ type: Schema.Literal<["fill_blank"]>;
359
+ id: typeof Schema.String;
360
+ category: typeof Schema.String;
361
+ difficulty: Schema.Literal<["easy", "medium", "hard"]>;
362
+ question: Schema.Struct<{
363
+ text: typeof Schema.String;
364
+ media: Schema.optional<Schema.Struct<{
365
+ type: Schema.Literal<["image", "audio", "video"]>;
366
+ url: typeof Schema.String;
367
+ thumbnail: Schema.optional<typeof Schema.String>;
368
+ }>>;
369
+ }>;
370
+ correctAnswer: typeof Schema.String;
371
+ incorrectAnswers: Schema.Array$<typeof Schema.String>;
372
+ question_fingerprint: Schema.optional<typeof Schema.String>;
373
+ metadata: Schema.Struct<{
374
+ source: Schema.Literal<["opentdb", "custom", "the-trivia-api"]>;
375
+ tags: Schema.optional<Schema.Array$<typeof Schema.String>>;
376
+ region: Schema.optional<Schema.Array$<typeof Schema.String>>;
377
+ isNiche: Schema.optional<typeof Schema.Boolean>;
378
+ timeLimit: Schema.optional<typeof Schema.Number>;
379
+ points: Schema.optional<typeof Schema.Number>;
380
+ }>;
381
+ createdAt: typeof Schema.String;
382
+ source: Schema.optional<Schema.Struct<{
383
+ url: Schema.filter<Schema.filter<typeof Schema.String>>;
384
+ label: Schema.optional<Schema.filter<typeof Schema.String>>;
385
+ }>>;
386
+ postAnswerNote: Schema.optional<Schema.filter<typeof Schema.String>>;
387
+ }>, Schema.Struct<{
388
+ type: Schema.Literal<["matching_pairs"]>;
389
+ id: typeof Schema.String;
390
+ category: typeof Schema.String;
391
+ difficulty: Schema.Literal<["easy", "medium", "hard"]>;
392
+ question: Schema.Struct<{
393
+ text: typeof Schema.String;
394
+ media: Schema.optional<Schema.Struct<{
395
+ type: Schema.Literal<["image", "audio", "video"]>;
396
+ url: typeof Schema.String;
397
+ thumbnail: Schema.optional<typeof Schema.String>;
398
+ }>>;
399
+ }>;
400
+ correctAnswer: typeof Schema.String;
401
+ incorrectAnswers: Schema.Array$<typeof Schema.String>;
402
+ question_fingerprint: Schema.optional<typeof Schema.String>;
403
+ metadata: Schema.Struct<{
404
+ source: Schema.Literal<["opentdb", "custom", "the-trivia-api"]>;
405
+ tags: Schema.optional<Schema.Array$<typeof Schema.String>>;
406
+ region: Schema.optional<Schema.Array$<typeof Schema.String>>;
407
+ isNiche: Schema.optional<typeof Schema.Boolean>;
408
+ timeLimit: Schema.optional<typeof Schema.Number>;
409
+ points: Schema.optional<typeof Schema.Number>;
410
+ }>;
411
+ createdAt: typeof Schema.String;
412
+ source: Schema.optional<Schema.Struct<{
413
+ url: Schema.filter<Schema.filter<typeof Schema.String>>;
414
+ label: Schema.optional<Schema.filter<typeof Schema.String>>;
415
+ }>>;
416
+ postAnswerNote: Schema.optional<Schema.filter<typeof Schema.String>>;
417
+ }>, Schema.Struct<{
418
+ type: Schema.Literal<["progressive_reveal"]>;
419
+ question: Schema.Struct<{
420
+ text: typeof Schema.String;
421
+ media: Schema.Struct<{
422
+ type: Schema.Literal<["image", "audio", "video"]>;
423
+ url: typeof Schema.String;
424
+ thumbnail: Schema.optional<typeof Schema.String>;
425
+ }>;
426
+ }>;
427
+ metadata: Schema.Struct<{
428
+ revealSteps: typeof Schema.Number;
429
+ source: Schema.Literal<["opentdb", "custom", "the-trivia-api"]>;
430
+ tags: Schema.optional<Schema.Array$<typeof Schema.String>>;
431
+ region: Schema.optional<Schema.Array$<typeof Schema.String>>;
432
+ isNiche: Schema.optional<typeof Schema.Boolean>;
433
+ timeLimit: Schema.optional<typeof Schema.Number>;
434
+ points: Schema.optional<typeof Schema.Number>;
435
+ }>;
436
+ id: typeof Schema.String;
437
+ category: typeof Schema.String;
438
+ difficulty: Schema.Literal<["easy", "medium", "hard"]>;
439
+ correctAnswer: typeof Schema.String;
440
+ incorrectAnswers: Schema.Array$<typeof Schema.String>;
441
+ question_fingerprint: Schema.optional<typeof Schema.String>;
442
+ createdAt: typeof Schema.String;
443
+ source: Schema.optional<Schema.Struct<{
444
+ url: Schema.filter<Schema.filter<typeof Schema.String>>;
445
+ label: Schema.optional<Schema.filter<typeof Schema.String>>;
446
+ }>>;
447
+ postAnswerNote: Schema.optional<Schema.filter<typeof Schema.String>>;
448
+ }>, Schema.Struct<{
449
+ type: Schema.Literal<["image_matching"]>;
450
+ question: Schema.Struct<{
451
+ text: typeof Schema.String;
452
+ media: Schema.Struct<{
453
+ type: Schema.Literal<["image", "audio", "video"]>;
454
+ url: typeof Schema.String;
455
+ thumbnail: Schema.optional<typeof Schema.String>;
456
+ }>;
457
+ }>;
458
+ correctAnswer: typeof Schema.String;
459
+ incorrectAnswers: Schema.Array$<typeof Schema.String>;
460
+ matchItems: Schema.Struct<{
461
+ left: Schema.Tuple<[typeof Schema.String, typeof Schema.String, typeof Schema.String, typeof Schema.String]>;
462
+ right: Schema.Tuple<[typeof Schema.String, typeof Schema.String, typeof Schema.String, typeof Schema.String]>;
463
+ }>;
464
+ id: typeof Schema.String;
465
+ category: typeof Schema.String;
466
+ difficulty: Schema.Literal<["easy", "medium", "hard"]>;
467
+ question_fingerprint: Schema.optional<typeof Schema.String>;
468
+ metadata: Schema.Struct<{
469
+ source: Schema.Literal<["opentdb", "custom", "the-trivia-api"]>;
470
+ tags: Schema.optional<Schema.Array$<typeof Schema.String>>;
471
+ region: Schema.optional<Schema.Array$<typeof Schema.String>>;
472
+ isNiche: Schema.optional<typeof Schema.Boolean>;
473
+ timeLimit: Schema.optional<typeof Schema.Number>;
474
+ points: Schema.optional<typeof Schema.Number>;
475
+ }>;
476
+ createdAt: typeof Schema.String;
477
+ source: Schema.optional<Schema.Struct<{
478
+ url: Schema.filter<Schema.filter<typeof Schema.String>>;
479
+ label: Schema.optional<Schema.filter<typeof Schema.String>>;
480
+ }>>;
481
+ postAnswerNote: Schema.optional<Schema.filter<typeof Schema.String>>;
482
+ }>]>;
483
+ export type Difficulty = typeof DifficultySchema.Type;
484
+ export type MediaType = typeof MediaTypeSchema.Type;
485
+ export type QuestionType = typeof QuestionTypeSchema.Type;
486
+ export type Source = typeof SourceSchema.Type;
487
+ export type Media = typeof MediaSchema.Type;
488
+ export type QuestionSource = typeof QuestionSourceSchema.Type;
489
+ export type Question = typeof QuestionSchema.Type;
490
+ export type TextChoiceQuestion = typeof TextChoiceSchema.Type;
491
+ export type TrueFalseQuestion = typeof TrueFalseSchema.Type;
492
+ export type ImageMatchingQuestion = typeof ImageMatchingSchema.Type;
493
+ export type ImageChoiceQuestion = typeof ImageChoiceSchema.Type;
494
+ export {};