@orakl/protocol 0.7.0 → 0.8.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.
- package/dist/game-answer-record.d.ts +2 -1
- package/dist/game.d.ts +3 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/pages/app.schema.d.ts +12 -0
- package/dist/pages/app.schema.js +2 -1
- package/dist/pages/common.schema.d.ts +6 -0
- package/dist/pages/common.schema.js +2 -1
- package/dist/pages/history.schema.d.ts +12 -0
- package/dist/pages/history.schema.js +3 -1
- package/dist/pages/quiz.schema.d.ts +6 -0
- package/dist/question.schema.d.ts +149 -2
- package/dist/question.schema.js +50 -5
- package/dist/solo-ws.d.ts +2 -1
- package/dist/wire/question-bank.d.ts +2 -2
- package/dist/ws-game.schema.d.ts +12 -0
- package/dist/ws-game.schema.js +2 -1
- package/dist/ws.d.ts +2 -1
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { MediaType, QuestionSource } from "./question.schema.ts";
|
|
1
|
+
import type { MediaCredit, MediaType, QuestionSource } from "./question.schema.ts";
|
|
2
2
|
/**
|
|
3
3
|
* One round in a player's multiplayer answer log. Misses recorded during the
|
|
4
4
|
* player's hero tenure (timeout, disconnect, quit) appear with isCorrect=false
|
|
@@ -26,6 +26,7 @@ export interface GameAnswerRecord {
|
|
|
26
26
|
* game is reviewed, so a reader re-signs it (see `resignBreakdown`). */
|
|
27
27
|
mediaUrl?: string;
|
|
28
28
|
mediaType?: MediaType;
|
|
29
|
+
mediaCredit?: MediaCredit;
|
|
29
30
|
source?: QuestionSource;
|
|
30
31
|
postAnswerNote?: string;
|
|
31
32
|
}
|
package/dist/game.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AdvanceMode, Difficulty, TimerDuration } from "./game.settings.ts";
|
|
2
|
-
import type { MediaType, QuestionSource, QuestionType } from "./question.schema.ts";
|
|
2
|
+
import type { MediaCredit, MediaType, QuestionSource, QuestionType } from "./question.schema.ts";
|
|
3
3
|
export type { AdvanceMode, Difficulty, TimerDuration, } from "./game.settings.ts";
|
|
4
4
|
export type PlayerRole = "player" | "observer";
|
|
5
5
|
export type PlayerStatus = "pending" | "active" | "disconnected";
|
|
@@ -54,6 +54,8 @@ interface BaseQuizQuestion {
|
|
|
54
54
|
answers: QuizAnswer[];
|
|
55
55
|
mediaUrl?: string;
|
|
56
56
|
mediaType?: MediaType;
|
|
57
|
+
/** Author and licence of the image; absent when the image has no credit. */
|
|
58
|
+
mediaCredit?: MediaCredit;
|
|
57
59
|
/** Carried only so `toPlayerSafeQuestion` can strip it — never sent on the
|
|
58
60
|
* wire during a game (map #912, decision 2). */
|
|
59
61
|
source?: QuestionSource;
|
package/dist/index.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ export * from "./pages/common.schema.ts";
|
|
|
10
10
|
export * from "./pages/history.schema.ts";
|
|
11
11
|
export * from "./pages/quiz.schema.ts";
|
|
12
12
|
export type { PlayerSafeQuestion } from "./player-safe-question.ts";
|
|
13
|
-
export { DifficultySchema, type ImageChoiceQuestion, type ImageMatchingQuestion, isHttpsUrl, type Media, MediaSchema, type MediaType, MediaTypeSchema, PostAnswerNoteSchema, type Question, QuestionSchema, type QuestionSource, QuestionSourceSchema, type QuestionType, QuestionTypeSchema, type Source, SourceSchema, type TextChoiceQuestion, type TrueFalseQuestion, } from "./question.schema.ts";
|
|
13
|
+
export { ATTRIBUTION_LICENCES, CREDIT_LICENCE_LABEL, CREDIT_LICENCES, type CreditLicence, CreditLicenceSchema, DISTRIBUTABLE_LICENCES, DifficultySchema, type ImageChoiceQuestion, type ImageMatchingQuestion, isHttpsUrl, type Media, type MediaCredit, MediaCreditSchema, MediaSchema, type MediaType, MediaTypeSchema, PostAnswerNoteSchema, type Question, QuestionSchema, type QuestionSource, QuestionSourceSchema, type QuestionType, QuestionTypeSchema, type Source, SourceSchema, type TextChoiceQuestion, type TrueFalseQuestion, } from "./question.schema.ts";
|
|
14
14
|
export { hasMedia, isImageMatching, isTextChoice, isTrueFalse, } from "./question.ts";
|
|
15
15
|
export type { QuestionRating } from "./question-rating.ts";
|
|
16
16
|
export { OptionalScoringModeSchema, ScoringModeSchema, } from "./scoring.schema.ts";
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ export * from "./pages/auth.schema.js";
|
|
|
5
5
|
export * from "./pages/common.schema.js";
|
|
6
6
|
export * from "./pages/history.schema.js";
|
|
7
7
|
export * from "./pages/quiz.schema.js";
|
|
8
|
-
export { DifficultySchema, isHttpsUrl, MediaSchema, MediaTypeSchema, PostAnswerNoteSchema, QuestionSchema, QuestionSourceSchema, QuestionTypeSchema, SourceSchema, } from "./question.schema.js";
|
|
8
|
+
export { ATTRIBUTION_LICENCES, CREDIT_LICENCE_LABEL, CREDIT_LICENCES, CreditLicenceSchema, DISTRIBUTABLE_LICENCES, DifficultySchema, isHttpsUrl, MediaCreditSchema, MediaSchema, MediaTypeSchema, PostAnswerNoteSchema, QuestionSchema, QuestionSourceSchema, QuestionTypeSchema, SourceSchema, } from "./question.schema.js";
|
|
9
9
|
export { hasMedia, isImageMatching, isTextChoice, isTrueFalse, } from "./question.js";
|
|
10
10
|
export { OptionalScoringModeSchema, ScoringModeSchema, } from "./scoring.schema.js";
|
|
11
11
|
export { soloError, } from "./solo-ws.js";
|
|
@@ -590,6 +590,12 @@ export declare const CuratorHistoryEntryPageSchema: Schema.Struct<{
|
|
|
590
590
|
readonly questionText?: string | undefined;
|
|
591
591
|
readonly mediaUrl?: string | undefined;
|
|
592
592
|
readonly mediaType?: "audio" | "video" | "image" | undefined;
|
|
593
|
+
readonly mediaCredit?: {
|
|
594
|
+
readonly licence: "cc0" | "public-domain" | "cc-by" | "cc-by-sa" | "own";
|
|
595
|
+
readonly author?: string | undefined;
|
|
596
|
+
readonly sourceUrl?: string | undefined;
|
|
597
|
+
readonly licenceUrl?: string | undefined;
|
|
598
|
+
} | undefined;
|
|
593
599
|
readonly correct: number;
|
|
594
600
|
readonly answered: number;
|
|
595
601
|
readonly spread: {
|
|
@@ -615,6 +621,12 @@ export declare const CuratorHistoryEntryPageSchema: Schema.Struct<{
|
|
|
615
621
|
readonly questionText?: string | undefined;
|
|
616
622
|
readonly mediaUrl?: string | undefined;
|
|
617
623
|
readonly mediaType?: "audio" | "video" | "image" | undefined;
|
|
624
|
+
readonly mediaCredit?: {
|
|
625
|
+
readonly licence: "cc0" | "public-domain" | "cc-by" | "cc-by-sa" | "own";
|
|
626
|
+
readonly author?: string | undefined;
|
|
627
|
+
readonly sourceUrl?: string | undefined;
|
|
628
|
+
readonly licenceUrl?: string | undefined;
|
|
629
|
+
} | undefined;
|
|
618
630
|
}, never>>>>;
|
|
619
631
|
}>;
|
|
620
632
|
presetLimit: typeof Schema.Number;
|
package/dist/pages/app.schema.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Schema } from "effect";
|
|
2
|
-
import { MediaTypeSchema, StoredQuestionSourceSchema, } from "../question.schema.js";
|
|
2
|
+
import { MediaCreditSchema, MediaTypeSchema, StoredQuestionSourceSchema, } from "../question.schema.js";
|
|
3
3
|
import { ThemeModeSchema, UserPowerSchema, UserRoleSchema, } from "./common.schema.js";
|
|
4
4
|
/** Page-load response bodies for `src/api/routes/pages.ts`. */
|
|
5
5
|
/** A JSON array, decoded mutable — Effect's `Schema.Array` types its `.Type`
|
|
@@ -338,6 +338,7 @@ const QuestionRecapEntrySchema = Schema.Struct({
|
|
|
338
338
|
questionText: Schema.optional(Schema.String),
|
|
339
339
|
mediaUrl: Schema.optional(Schema.String),
|
|
340
340
|
mediaType: Schema.optional(MediaTypeSchema),
|
|
341
|
+
mediaCredit: Schema.optional(MediaCreditSchema),
|
|
341
342
|
source: Schema.optional(StoredQuestionSourceSchema),
|
|
342
343
|
postAnswerNote: Schema.optional(Schema.String),
|
|
343
344
|
answered: Schema.Number,
|
|
@@ -19,6 +19,12 @@ export declare const GameAnswerRecordSchema: Schema.Struct<{
|
|
|
19
19
|
correctAnswerText: Schema.optional<typeof Schema.String>;
|
|
20
20
|
mediaUrl: Schema.optional<typeof Schema.String>;
|
|
21
21
|
mediaType: Schema.optional<Schema.Literal<["image", "audio", "video"]>>;
|
|
22
|
+
mediaCredit: Schema.optional<Schema.filter<Schema.Struct<{
|
|
23
|
+
licence: Schema.Literal<["cc0", "public-domain", "cc-by", "cc-by-sa", "own"]>;
|
|
24
|
+
author: Schema.optional<Schema.filter<typeof Schema.String>>;
|
|
25
|
+
sourceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
|
|
26
|
+
licenceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
|
|
27
|
+
}>>>;
|
|
22
28
|
source: Schema.optional<Schema.transform<typeof Schema.Unknown, Schema.UndefinedOr<Schema.SchemaClass<{
|
|
23
29
|
readonly url: string;
|
|
24
30
|
readonly label?: string | undefined;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Schema } from "effect";
|
|
2
|
-
import { MediaTypeSchema, StoredQuestionSourceSchema, } from "../question.schema.js";
|
|
2
|
+
import { MediaCreditSchema, MediaTypeSchema, StoredQuestionSourceSchema, } from "../question.schema.js";
|
|
3
3
|
/** Schemas shared by more than one page-load body. */
|
|
4
4
|
export const UserRoleSchema = Schema.Literal("anonymous", "display", "member", "curator", "admin");
|
|
5
5
|
export const UserPowerSchema = Schema.Literal("can-access-mimic", "can-send-feedback", "can-import-quizzes", "can-manage-features", "can-add-questions", "can-manage-categories", "can-moderate-questions", "can-publish-questions", "is-power-user", "can-manage-avatars", "can-apply-for-curation", "can-1v1");
|
|
@@ -20,6 +20,7 @@ export const GameAnswerRecordSchema = Schema.Struct({
|
|
|
20
20
|
correctAnswerText: Schema.optional(Schema.String),
|
|
21
21
|
mediaUrl: Schema.optional(Schema.String),
|
|
22
22
|
mediaType: Schema.optional(MediaTypeSchema),
|
|
23
|
+
mediaCredit: Schema.optional(MediaCreditSchema),
|
|
23
24
|
source: Schema.optional(StoredQuestionSourceSchema),
|
|
24
25
|
postAnswerNote: Schema.optional(Schema.String),
|
|
25
26
|
});
|
|
@@ -213,6 +213,12 @@ export declare const GameReviewPageSchema: Schema.Struct<{
|
|
|
213
213
|
correctAnswerText: Schema.optional<typeof Schema.String>;
|
|
214
214
|
mediaUrl: Schema.optional<typeof Schema.String>;
|
|
215
215
|
mediaType: Schema.optional<Schema.Literal<["image", "audio", "video"]>>;
|
|
216
|
+
mediaCredit: Schema.optional<Schema.filter<Schema.Struct<{
|
|
217
|
+
licence: Schema.Literal<["cc0", "public-domain", "cc-by", "cc-by-sa", "own"]>;
|
|
218
|
+
author: Schema.optional<Schema.filter<typeof Schema.String>>;
|
|
219
|
+
sourceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
|
|
220
|
+
licenceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
|
|
221
|
+
}>>>;
|
|
216
222
|
source: Schema.optional<Schema.transform<typeof Schema.Unknown, Schema.UndefinedOr<Schema.SchemaClass<{
|
|
217
223
|
readonly url: string;
|
|
218
224
|
readonly label?: string | undefined;
|
|
@@ -268,6 +274,12 @@ export declare const SoloReviewPageSchema: Schema.Struct<{
|
|
|
268
274
|
questionId: Schema.NullOr<typeof Schema.String>;
|
|
269
275
|
mediaUrl: Schema.NullOr<typeof Schema.String>;
|
|
270
276
|
mediaType: Schema.NullOr<Schema.Literal<["image", "audio", "video"]>>;
|
|
277
|
+
mediaCredit: Schema.optional<Schema.NullOr<Schema.filter<Schema.Struct<{
|
|
278
|
+
licence: Schema.Literal<["cc0", "public-domain", "cc-by", "cc-by-sa", "own"]>;
|
|
279
|
+
author: Schema.optional<Schema.filter<typeof Schema.String>>;
|
|
280
|
+
sourceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
|
|
281
|
+
licenceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
|
|
282
|
+
}>>>>;
|
|
271
283
|
source: Schema.Union<[typeof Schema.Null, Schema.transform<typeof Schema.Unknown, Schema.UndefinedOr<Schema.SchemaClass<{
|
|
272
284
|
readonly url: string;
|
|
273
285
|
readonly label?: string | undefined;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Schema } from "effect";
|
|
2
|
-
import { MediaTypeSchema, StoredQuestionSourceSchema, } from "../question.schema.js";
|
|
2
|
+
import { MediaCreditSchema, MediaTypeSchema, StoredQuestionSourceSchema, } from "../question.schema.js";
|
|
3
3
|
import { GameAnswerRecordSchema, PlayerRoleSchema, UserPowerSchema, UserRoleSchema, } from "./common.schema.js";
|
|
4
4
|
/** Page-load response bodies for `src/api/routes/pages-history.ts and admin-feature-flags.ts`. */
|
|
5
5
|
/** Achievement badge id (mirrors `BadgeId` in `src/lib/badges.ts`). */
|
|
@@ -179,6 +179,8 @@ const SoloRunReviewEntrySchema = Schema.Struct({
|
|
|
179
179
|
questionId: Schema.NullOr(Schema.String),
|
|
180
180
|
mediaUrl: Schema.NullOr(Schema.String),
|
|
181
181
|
mediaType: Schema.NullOr(MediaTypeSchema),
|
|
182
|
+
// Optional: a review served before credits existed has no key.
|
|
183
|
+
mediaCredit: Schema.optional(Schema.NullOr(MediaCreditSchema)),
|
|
182
184
|
// Null first: the stored-source transform accepts any value, null included.
|
|
183
185
|
source: Schema.Union(Schema.Null, StoredQuestionSourceSchema),
|
|
184
186
|
postAnswerNote: Schema.NullOr(Schema.String),
|
|
@@ -135,6 +135,12 @@ export declare const QuizResultsPageSchema: Schema.Struct<{
|
|
|
135
135
|
correctAnswerText: Schema.optional<typeof Schema.String>;
|
|
136
136
|
mediaUrl: Schema.optional<typeof Schema.String>;
|
|
137
137
|
mediaType: Schema.optional<Schema.Literal<["image", "audio", "video"]>>;
|
|
138
|
+
mediaCredit: Schema.optional<Schema.filter<Schema.Struct<{
|
|
139
|
+
licence: Schema.Literal<["cc0", "public-domain", "cc-by", "cc-by-sa", "own"]>;
|
|
140
|
+
author: Schema.optional<Schema.filter<typeof Schema.String>>;
|
|
141
|
+
sourceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
|
|
142
|
+
licenceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
|
|
143
|
+
}>>>;
|
|
138
144
|
source: Schema.optional<Schema.transform<typeof Schema.Unknown, Schema.UndefinedOr<Schema.SchemaClass<{
|
|
139
145
|
readonly url: string;
|
|
140
146
|
readonly label?: string | undefined;
|
|
@@ -3,13 +3,40 @@ export declare const DifficultySchema: Schema.Literal<["easy", "medium", "hard"]
|
|
|
3
3
|
export declare const MediaTypeSchema: Schema.Literal<["image", "audio", "video"]>;
|
|
4
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
5
|
export declare const SourceSchema: Schema.Literal<["opentdb", "custom", "the-trivia-api"]>;
|
|
6
|
+
/** True for an https URL WHATWG-parses; false for anything else (including unparsable strings). */
|
|
7
|
+
export declare function isHttpsUrl(url: string): boolean;
|
|
8
|
+
/** Every licence an image credit may name. */
|
|
9
|
+
export declare const CREDIT_LICENCES: readonly ["cc0", "public-domain", "cc-by", "cc-by-sa", "own"];
|
|
10
|
+
export declare const CreditLicenceSchema: Schema.Literal<["cc0", "public-domain", "cc-by", "cc-by-sa", "own"]>;
|
|
11
|
+
export type CreditLicence = typeof CreditLicenceSchema.Type;
|
|
12
|
+
/** Licences Orakl may distribute: a promoted or imported image must carry one. */
|
|
13
|
+
export declare const DISTRIBUTABLE_LICENCES: readonly CreditLicence[];
|
|
14
|
+
/** Licences whose terms require the author's name beside the image. */
|
|
15
|
+
export declare const ATTRIBUTION_LICENCES: readonly CreditLicence[];
|
|
16
|
+
export declare const CREDIT_LICENCE_LABEL: Record<CreditLicence, string>;
|
|
17
|
+
/** Who made an image and under which licence it is used (map #1570, decision 9). */
|
|
18
|
+
export declare const MediaCreditSchema: Schema.filter<Schema.Struct<{
|
|
19
|
+
licence: Schema.Literal<["cc0", "public-domain", "cc-by", "cc-by-sa", "own"]>;
|
|
20
|
+
author: Schema.optional<Schema.filter<typeof Schema.String>>;
|
|
21
|
+
/** The page the image was taken from, e.g. its Commons file page. */
|
|
22
|
+
sourceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
|
|
23
|
+
/** The licence deed, version included. */
|
|
24
|
+
licenceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
|
|
25
|
+
}>>;
|
|
26
|
+
export type MediaCredit = typeof MediaCreditSchema.Type;
|
|
6
27
|
export declare const MediaSchema: Schema.Struct<{
|
|
7
28
|
type: Schema.Literal<["image", "audio", "video"]>;
|
|
8
29
|
url: typeof Schema.String;
|
|
9
30
|
thumbnail: Schema.optional<typeof Schema.String>;
|
|
31
|
+
credit: Schema.optional<Schema.filter<Schema.Struct<{
|
|
32
|
+
licence: Schema.Literal<["cc0", "public-domain", "cc-by", "cc-by-sa", "own"]>;
|
|
33
|
+
author: Schema.optional<Schema.filter<typeof Schema.String>>;
|
|
34
|
+
/** The page the image was taken from, e.g. its Commons file page. */
|
|
35
|
+
sourceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
|
|
36
|
+
/** The licence deed, version included. */
|
|
37
|
+
licenceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
|
|
38
|
+
}>>>;
|
|
10
39
|
}>;
|
|
11
|
-
/** True for an https URL WHATWG-parses; false for anything else (including unparsable strings). */
|
|
12
|
-
export declare function isHttpsUrl(url: string): boolean;
|
|
13
40
|
export declare const QuestionSourceSchema: Schema.Struct<{
|
|
14
41
|
url: Schema.filter<Schema.filter<typeof Schema.String>>;
|
|
15
42
|
label: Schema.optional<Schema.filter<typeof Schema.String>>;
|
|
@@ -38,6 +65,14 @@ declare const TextChoiceSchema: Schema.Struct<{
|
|
|
38
65
|
type: Schema.Literal<["image", "audio", "video"]>;
|
|
39
66
|
url: typeof Schema.String;
|
|
40
67
|
thumbnail: Schema.optional<typeof Schema.String>;
|
|
68
|
+
credit: Schema.optional<Schema.filter<Schema.Struct<{
|
|
69
|
+
licence: Schema.Literal<["cc0", "public-domain", "cc-by", "cc-by-sa", "own"]>;
|
|
70
|
+
author: Schema.optional<Schema.filter<typeof Schema.String>>;
|
|
71
|
+
/** The page the image was taken from, e.g. its Commons file page. */
|
|
72
|
+
sourceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
|
|
73
|
+
/** The licence deed, version included. */
|
|
74
|
+
licenceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
|
|
75
|
+
}>>>;
|
|
41
76
|
}>>;
|
|
42
77
|
}>;
|
|
43
78
|
correctAnswer: typeof Schema.String;
|
|
@@ -66,6 +101,14 @@ declare const ImageChoiceSchema: Schema.Struct<{
|
|
|
66
101
|
type: Schema.Literal<["image", "audio", "video"]>;
|
|
67
102
|
url: typeof Schema.String;
|
|
68
103
|
thumbnail: Schema.optional<typeof Schema.String>;
|
|
104
|
+
credit: Schema.optional<Schema.filter<Schema.Struct<{
|
|
105
|
+
licence: Schema.Literal<["cc0", "public-domain", "cc-by", "cc-by-sa", "own"]>;
|
|
106
|
+
author: Schema.optional<Schema.filter<typeof Schema.String>>;
|
|
107
|
+
/** The page the image was taken from, e.g. its Commons file page. */
|
|
108
|
+
sourceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
|
|
109
|
+
/** The licence deed, version included. */
|
|
110
|
+
licenceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
|
|
111
|
+
}>>>;
|
|
69
112
|
}>;
|
|
70
113
|
}>;
|
|
71
114
|
id: typeof Schema.String;
|
|
@@ -102,6 +145,14 @@ declare const TrueFalseSchema: Schema.Struct<{
|
|
|
102
145
|
type: Schema.Literal<["image", "audio", "video"]>;
|
|
103
146
|
url: typeof Schema.String;
|
|
104
147
|
thumbnail: Schema.optional<typeof Schema.String>;
|
|
148
|
+
credit: Schema.optional<Schema.filter<Schema.Struct<{
|
|
149
|
+
licence: Schema.Literal<["cc0", "public-domain", "cc-by", "cc-by-sa", "own"]>;
|
|
150
|
+
author: Schema.optional<Schema.filter<typeof Schema.String>>;
|
|
151
|
+
/** The page the image was taken from, e.g. its Commons file page. */
|
|
152
|
+
sourceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
|
|
153
|
+
/** The licence deed, version included. */
|
|
154
|
+
licenceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
|
|
155
|
+
}>>>;
|
|
105
156
|
}>>;
|
|
106
157
|
}>;
|
|
107
158
|
question_fingerprint: Schema.optional<typeof Schema.String>;
|
|
@@ -128,6 +179,14 @@ declare const ImageMatchingSchema: Schema.Struct<{
|
|
|
128
179
|
type: Schema.Literal<["image", "audio", "video"]>;
|
|
129
180
|
url: typeof Schema.String;
|
|
130
181
|
thumbnail: Schema.optional<typeof Schema.String>;
|
|
182
|
+
credit: Schema.optional<Schema.filter<Schema.Struct<{
|
|
183
|
+
licence: Schema.Literal<["cc0", "public-domain", "cc-by", "cc-by-sa", "own"]>;
|
|
184
|
+
author: Schema.optional<Schema.filter<typeof Schema.String>>;
|
|
185
|
+
/** The page the image was taken from, e.g. its Commons file page. */
|
|
186
|
+
sourceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
|
|
187
|
+
/** The licence deed, version included. */
|
|
188
|
+
licenceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
|
|
189
|
+
}>>>;
|
|
131
190
|
}>;
|
|
132
191
|
}>;
|
|
133
192
|
correctAnswer: typeof Schema.String;
|
|
@@ -166,6 +225,14 @@ export declare const QuestionSchema: Schema.Union<[Schema.Struct<{
|
|
|
166
225
|
type: Schema.Literal<["image", "audio", "video"]>;
|
|
167
226
|
url: typeof Schema.String;
|
|
168
227
|
thumbnail: Schema.optional<typeof Schema.String>;
|
|
228
|
+
credit: Schema.optional<Schema.filter<Schema.Struct<{
|
|
229
|
+
licence: Schema.Literal<["cc0", "public-domain", "cc-by", "cc-by-sa", "own"]>;
|
|
230
|
+
author: Schema.optional<Schema.filter<typeof Schema.String>>;
|
|
231
|
+
/** The page the image was taken from, e.g. its Commons file page. */
|
|
232
|
+
sourceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
|
|
233
|
+
/** The licence deed, version included. */
|
|
234
|
+
licenceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
|
|
235
|
+
}>>>;
|
|
169
236
|
}>>;
|
|
170
237
|
}>;
|
|
171
238
|
correctAnswer: typeof Schema.String;
|
|
@@ -193,6 +260,14 @@ export declare const QuestionSchema: Schema.Union<[Schema.Struct<{
|
|
|
193
260
|
type: Schema.Literal<["image", "audio", "video"]>;
|
|
194
261
|
url: typeof Schema.String;
|
|
195
262
|
thumbnail: Schema.optional<typeof Schema.String>;
|
|
263
|
+
credit: Schema.optional<Schema.filter<Schema.Struct<{
|
|
264
|
+
licence: Schema.Literal<["cc0", "public-domain", "cc-by", "cc-by-sa", "own"]>;
|
|
265
|
+
author: Schema.optional<Schema.filter<typeof Schema.String>>;
|
|
266
|
+
/** The page the image was taken from, e.g. its Commons file page. */
|
|
267
|
+
sourceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
|
|
268
|
+
/** The licence deed, version included. */
|
|
269
|
+
licenceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
|
|
270
|
+
}>>>;
|
|
196
271
|
}>;
|
|
197
272
|
}>;
|
|
198
273
|
id: typeof Schema.String;
|
|
@@ -228,6 +303,14 @@ export declare const QuestionSchema: Schema.Union<[Schema.Struct<{
|
|
|
228
303
|
type: Schema.Literal<["image", "audio", "video"]>;
|
|
229
304
|
url: typeof Schema.String;
|
|
230
305
|
thumbnail: Schema.optional<typeof Schema.String>;
|
|
306
|
+
credit: Schema.optional<Schema.filter<Schema.Struct<{
|
|
307
|
+
licence: Schema.Literal<["cc0", "public-domain", "cc-by", "cc-by-sa", "own"]>;
|
|
308
|
+
author: Schema.optional<Schema.filter<typeof Schema.String>>;
|
|
309
|
+
/** The page the image was taken from, e.g. its Commons file page. */
|
|
310
|
+
sourceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
|
|
311
|
+
/** The licence deed, version included. */
|
|
312
|
+
licenceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
|
|
313
|
+
}>>>;
|
|
231
314
|
}>>;
|
|
232
315
|
}>;
|
|
233
316
|
question_fingerprint: Schema.optional<typeof Schema.String>;
|
|
@@ -253,6 +336,14 @@ export declare const QuestionSchema: Schema.Union<[Schema.Struct<{
|
|
|
253
336
|
type: Schema.Literal<["image", "audio", "video"]>;
|
|
254
337
|
url: typeof Schema.String;
|
|
255
338
|
thumbnail: Schema.optional<typeof Schema.String>;
|
|
339
|
+
credit: Schema.optional<Schema.filter<Schema.Struct<{
|
|
340
|
+
licence: Schema.Literal<["cc0", "public-domain", "cc-by", "cc-by-sa", "own"]>;
|
|
341
|
+
author: Schema.optional<Schema.filter<typeof Schema.String>>;
|
|
342
|
+
/** The page the image was taken from, e.g. its Commons file page. */
|
|
343
|
+
sourceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
|
|
344
|
+
/** The licence deed, version included. */
|
|
345
|
+
licenceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
|
|
346
|
+
}>>>;
|
|
256
347
|
}>;
|
|
257
348
|
}>;
|
|
258
349
|
id: typeof Schema.String;
|
|
@@ -283,6 +374,14 @@ export declare const QuestionSchema: Schema.Union<[Schema.Struct<{
|
|
|
283
374
|
type: Schema.Literal<["image", "audio", "video"]>;
|
|
284
375
|
url: typeof Schema.String;
|
|
285
376
|
thumbnail: Schema.optional<typeof Schema.String>;
|
|
377
|
+
credit: Schema.optional<Schema.filter<Schema.Struct<{
|
|
378
|
+
licence: Schema.Literal<["cc0", "public-domain", "cc-by", "cc-by-sa", "own"]>;
|
|
379
|
+
author: Schema.optional<Schema.filter<typeof Schema.String>>;
|
|
380
|
+
/** The page the image was taken from, e.g. its Commons file page. */
|
|
381
|
+
sourceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
|
|
382
|
+
/** The licence deed, version included. */
|
|
383
|
+
licenceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
|
|
384
|
+
}>>>;
|
|
286
385
|
}>;
|
|
287
386
|
}>;
|
|
288
387
|
id: typeof Schema.String;
|
|
@@ -316,6 +415,14 @@ export declare const QuestionSchema: Schema.Union<[Schema.Struct<{
|
|
|
316
415
|
type: Schema.Literal<["image", "audio", "video"]>;
|
|
317
416
|
url: typeof Schema.String;
|
|
318
417
|
thumbnail: Schema.optional<typeof Schema.String>;
|
|
418
|
+
credit: Schema.optional<Schema.filter<Schema.Struct<{
|
|
419
|
+
licence: Schema.Literal<["cc0", "public-domain", "cc-by", "cc-by-sa", "own"]>;
|
|
420
|
+
author: Schema.optional<Schema.filter<typeof Schema.String>>;
|
|
421
|
+
/** The page the image was taken from, e.g. its Commons file page. */
|
|
422
|
+
sourceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
|
|
423
|
+
/** The licence deed, version included. */
|
|
424
|
+
licenceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
|
|
425
|
+
}>>>;
|
|
319
426
|
}>>;
|
|
320
427
|
}>;
|
|
321
428
|
correctAnswer: typeof Schema.String;
|
|
@@ -355,6 +462,14 @@ export declare const QuestionSchema: Schema.Union<[Schema.Struct<{
|
|
|
355
462
|
type: Schema.Literal<["image", "audio", "video"]>;
|
|
356
463
|
url: typeof Schema.String;
|
|
357
464
|
thumbnail: Schema.optional<typeof Schema.String>;
|
|
465
|
+
credit: Schema.optional<Schema.filter<Schema.Struct<{
|
|
466
|
+
licence: Schema.Literal<["cc0", "public-domain", "cc-by", "cc-by-sa", "own"]>;
|
|
467
|
+
author: Schema.optional<Schema.filter<typeof Schema.String>>;
|
|
468
|
+
/** The page the image was taken from, e.g. its Commons file page. */
|
|
469
|
+
sourceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
|
|
470
|
+
/** The licence deed, version included. */
|
|
471
|
+
licenceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
|
|
472
|
+
}>>>;
|
|
358
473
|
}>>;
|
|
359
474
|
}>;
|
|
360
475
|
correctAnswer: typeof Schema.String;
|
|
@@ -377,6 +492,14 @@ export declare const QuestionSchema: Schema.Union<[Schema.Struct<{
|
|
|
377
492
|
type: Schema.Literal<["image", "audio", "video"]>;
|
|
378
493
|
url: typeof Schema.String;
|
|
379
494
|
thumbnail: Schema.optional<typeof Schema.String>;
|
|
495
|
+
credit: Schema.optional<Schema.filter<Schema.Struct<{
|
|
496
|
+
licence: Schema.Literal<["cc0", "public-domain", "cc-by", "cc-by-sa", "own"]>;
|
|
497
|
+
author: Schema.optional<Schema.filter<typeof Schema.String>>;
|
|
498
|
+
/** The page the image was taken from, e.g. its Commons file page. */
|
|
499
|
+
sourceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
|
|
500
|
+
/** The licence deed, version included. */
|
|
501
|
+
licenceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
|
|
502
|
+
}>>>;
|
|
380
503
|
}>>;
|
|
381
504
|
}>;
|
|
382
505
|
correctAnswer: typeof Schema.String;
|
|
@@ -407,6 +530,14 @@ export declare const QuestionSchema: Schema.Union<[Schema.Struct<{
|
|
|
407
530
|
type: Schema.Literal<["image", "audio", "video"]>;
|
|
408
531
|
url: typeof Schema.String;
|
|
409
532
|
thumbnail: Schema.optional<typeof Schema.String>;
|
|
533
|
+
credit: Schema.optional<Schema.filter<Schema.Struct<{
|
|
534
|
+
licence: Schema.Literal<["cc0", "public-domain", "cc-by", "cc-by-sa", "own"]>;
|
|
535
|
+
author: Schema.optional<Schema.filter<typeof Schema.String>>;
|
|
536
|
+
/** The page the image was taken from, e.g. its Commons file page. */
|
|
537
|
+
sourceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
|
|
538
|
+
/** The licence deed, version included. */
|
|
539
|
+
licenceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
|
|
540
|
+
}>>>;
|
|
410
541
|
}>>;
|
|
411
542
|
}>;
|
|
412
543
|
correctAnswer: typeof Schema.String;
|
|
@@ -434,6 +565,14 @@ export declare const QuestionSchema: Schema.Union<[Schema.Struct<{
|
|
|
434
565
|
type: Schema.Literal<["image", "audio", "video"]>;
|
|
435
566
|
url: typeof Schema.String;
|
|
436
567
|
thumbnail: Schema.optional<typeof Schema.String>;
|
|
568
|
+
credit: Schema.optional<Schema.filter<Schema.Struct<{
|
|
569
|
+
licence: Schema.Literal<["cc0", "public-domain", "cc-by", "cc-by-sa", "own"]>;
|
|
570
|
+
author: Schema.optional<Schema.filter<typeof Schema.String>>;
|
|
571
|
+
/** The page the image was taken from, e.g. its Commons file page. */
|
|
572
|
+
sourceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
|
|
573
|
+
/** The licence deed, version included. */
|
|
574
|
+
licenceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
|
|
575
|
+
}>>>;
|
|
437
576
|
}>;
|
|
438
577
|
}>;
|
|
439
578
|
metadata: Schema.Struct<{
|
|
@@ -465,6 +604,14 @@ export declare const QuestionSchema: Schema.Union<[Schema.Struct<{
|
|
|
465
604
|
type: Schema.Literal<["image", "audio", "video"]>;
|
|
466
605
|
url: typeof Schema.String;
|
|
467
606
|
thumbnail: Schema.optional<typeof Schema.String>;
|
|
607
|
+
credit: Schema.optional<Schema.filter<Schema.Struct<{
|
|
608
|
+
licence: Schema.Literal<["cc0", "public-domain", "cc-by", "cc-by-sa", "own"]>;
|
|
609
|
+
author: Schema.optional<Schema.filter<typeof Schema.String>>;
|
|
610
|
+
/** The page the image was taken from, e.g. its Commons file page. */
|
|
611
|
+
sourceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
|
|
612
|
+
/** The licence deed, version included. */
|
|
613
|
+
licenceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
|
|
614
|
+
}>>>;
|
|
468
615
|
}>;
|
|
469
616
|
}>;
|
|
470
617
|
correctAnswer: typeof Schema.String;
|
package/dist/question.schema.js
CHANGED
|
@@ -4,11 +4,6 @@ export const DifficultySchema = Schema.Literal(...GAME.roundConfig.difficulties)
|
|
|
4
4
|
export const MediaTypeSchema = Schema.Literal("image", "audio", "video");
|
|
5
5
|
export 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");
|
|
6
6
|
export const SourceSchema = Schema.Literal(...GAME.question.sources);
|
|
7
|
-
export const MediaSchema = Schema.Struct({
|
|
8
|
-
type: MediaTypeSchema,
|
|
9
|
-
url: Schema.String,
|
|
10
|
-
thumbnail: Schema.optional(Schema.String),
|
|
11
|
-
});
|
|
12
7
|
/** True for an https URL WHATWG-parses; false for anything else (including unparsable strings). */
|
|
13
8
|
export function isHttpsUrl(url) {
|
|
14
9
|
try {
|
|
@@ -18,6 +13,56 @@ export function isHttpsUrl(url) {
|
|
|
18
13
|
return false;
|
|
19
14
|
}
|
|
20
15
|
}
|
|
16
|
+
/** Every licence an image credit may name. */
|
|
17
|
+
export const CREDIT_LICENCES = [
|
|
18
|
+
"cc0",
|
|
19
|
+
"public-domain",
|
|
20
|
+
"cc-by",
|
|
21
|
+
"cc-by-sa",
|
|
22
|
+
"own",
|
|
23
|
+
];
|
|
24
|
+
export const CreditLicenceSchema = Schema.Literal(...CREDIT_LICENCES);
|
|
25
|
+
/** Licences Orakl may distribute: a promoted or imported image must carry one. */
|
|
26
|
+
export const DISTRIBUTABLE_LICENCES = [
|
|
27
|
+
"cc0",
|
|
28
|
+
"public-domain",
|
|
29
|
+
"cc-by",
|
|
30
|
+
"cc-by-sa",
|
|
31
|
+
];
|
|
32
|
+
/** Licences whose terms require the author's name beside the image. */
|
|
33
|
+
export const ATTRIBUTION_LICENCES = [
|
|
34
|
+
"cc-by",
|
|
35
|
+
"cc-by-sa",
|
|
36
|
+
];
|
|
37
|
+
export const CREDIT_LICENCE_LABEL = {
|
|
38
|
+
cc0: "CC0",
|
|
39
|
+
"public-domain": "Public domain",
|
|
40
|
+
"cc-by": "CC BY",
|
|
41
|
+
"cc-by-sa": "CC BY-SA",
|
|
42
|
+
own: "Uploader's own / rights confirmed",
|
|
43
|
+
};
|
|
44
|
+
const CreditUrlSchema = Schema.String.pipe(Schema.maxLength(2048, {
|
|
45
|
+
message: () => "Credit link must be 2048 characters or fewer",
|
|
46
|
+
}), Schema.filter(isHttpsUrl, { message: () => "Credit link must be https" }));
|
|
47
|
+
/** Who made an image and under which licence it is used (map #1570, decision 9). */
|
|
48
|
+
export const MediaCreditSchema = Schema.Struct({
|
|
49
|
+
licence: CreditLicenceSchema,
|
|
50
|
+
author: Schema.optional(Schema.String.pipe(Schema.maxLength(200, {
|
|
51
|
+
message: () => "Author must be 200 characters or fewer",
|
|
52
|
+
}))),
|
|
53
|
+
/** The page the image was taken from, e.g. its Commons file page. */
|
|
54
|
+
sourceUrl: Schema.optional(CreditUrlSchema),
|
|
55
|
+
/** The licence deed, version included. */
|
|
56
|
+
licenceUrl: Schema.optional(CreditUrlSchema),
|
|
57
|
+
}).pipe(Schema.filter((c) => !ATTRIBUTION_LICENCES.includes(c.licence) ||
|
|
58
|
+
Boolean(c.author?.trim()) ||
|
|
59
|
+
"Author is required for CC BY and CC BY-SA"));
|
|
60
|
+
export const MediaSchema = Schema.Struct({
|
|
61
|
+
type: MediaTypeSchema,
|
|
62
|
+
url: Schema.String,
|
|
63
|
+
thumbnail: Schema.optional(Schema.String),
|
|
64
|
+
credit: Schema.optional(MediaCreditSchema),
|
|
65
|
+
});
|
|
21
66
|
// Security: source.url is stored in the DB and read back on results/history
|
|
22
67
|
// pages; cap to match imageUrl's bound (curator.schema.ts) since both are
|
|
23
68
|
// URLs of the same practical size.
|
package/dist/solo-ws.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { BadgeAward } from "./badges.ts";
|
|
2
2
|
import type { PlayerSafeQuestion } from "./player-safe-question.ts";
|
|
3
|
-
import type { MediaType, QuestionSource } from "./question.ts";
|
|
3
|
+
import type { MediaCredit, MediaType, QuestionSource } from "./question.schema.ts";
|
|
4
4
|
import type { QuestionRating } from "./question-rating.ts";
|
|
5
5
|
import type { RateAckReason } from "./ws.ts";
|
|
6
6
|
export type SoloAuthMessage = {
|
|
@@ -189,6 +189,7 @@ export type SoloFinalMessage = {
|
|
|
189
189
|
* question's image, source and note. Absent when the question has none. */
|
|
190
190
|
mediaUrl?: string;
|
|
191
191
|
mediaType?: MediaType;
|
|
192
|
+
mediaCredit?: MediaCredit;
|
|
192
193
|
source?: QuestionSource;
|
|
193
194
|
postAnswerNote?: string;
|
|
194
195
|
/** From the same batched precheck as `solo:question`'s `alreadyFlagged`
|
|
@@ -14,10 +14,10 @@ export type OperatorQuestionRevision = QuestionRevision & {
|
|
|
14
14
|
} | null;
|
|
15
15
|
};
|
|
16
16
|
/** One outcome of a bulk publish — an id that promoted, was already shared,
|
|
17
|
-
* is flagged, or wasn't found. */
|
|
17
|
+
* is flagged, has an image without a distributable licence, or wasn't found. */
|
|
18
18
|
export type PublishManyResult = {
|
|
19
19
|
id: string;
|
|
20
|
-
outcome: "promoted" | "already" | "flagged" | "not_found";
|
|
20
|
+
outcome: "promoted" | "already" | "flagged" | "unlicensed" | "not_found";
|
|
21
21
|
published_at?: string;
|
|
22
22
|
published_by?: string;
|
|
23
23
|
};
|
package/dist/ws-game.schema.d.ts
CHANGED
|
@@ -42,6 +42,12 @@ export declare const ClientMessageSchema: Schema.Union<[Schema.Struct<{
|
|
|
42
42
|
}>>>>;
|
|
43
43
|
mediaUrl: Schema.optional<Schema.filter<typeof Schema.String>>;
|
|
44
44
|
mediaType: Schema.optional<Schema.Literal<["image", "audio", "video"]>>;
|
|
45
|
+
mediaCredit: Schema.optional<Schema.filter<Schema.Struct<{
|
|
46
|
+
licence: Schema.Literal<["cc0", "public-domain", "cc-by", "cc-by-sa", "own"]>;
|
|
47
|
+
author: Schema.optional<Schema.filter<typeof Schema.String>>;
|
|
48
|
+
sourceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
|
|
49
|
+
licenceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
|
|
50
|
+
}>>>;
|
|
45
51
|
}>, Schema.Struct<{
|
|
46
52
|
type: Schema.Literal<["image_matching"]>;
|
|
47
53
|
matchItems: Schema.Struct<{
|
|
@@ -59,6 +65,12 @@ export declare const ClientMessageSchema: Schema.Union<[Schema.Struct<{
|
|
|
59
65
|
}>>>>;
|
|
60
66
|
mediaUrl: Schema.optional<Schema.filter<typeof Schema.String>>;
|
|
61
67
|
mediaType: Schema.optional<Schema.Literal<["image", "audio", "video"]>>;
|
|
68
|
+
mediaCredit: Schema.optional<Schema.filter<Schema.Struct<{
|
|
69
|
+
licence: Schema.Literal<["cc0", "public-domain", "cc-by", "cc-by-sa", "own"]>;
|
|
70
|
+
author: Schema.optional<Schema.filter<typeof Schema.String>>;
|
|
71
|
+
sourceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
|
|
72
|
+
licenceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
|
|
73
|
+
}>>>;
|
|
62
74
|
}>]>>>>;
|
|
63
75
|
}>, Schema.Struct<{
|
|
64
76
|
type: Schema.Literal<["curator:advance"]>;
|
package/dist/ws-game.schema.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Schema } from "effect";
|
|
2
2
|
import { SELECTABLE_EMOTE_IDS } from "./emotes.js";
|
|
3
3
|
import { GAME } from "./game.settings.js";
|
|
4
|
-
import { DifficultySchema, MediaTypeSchema } from "./question.schema.js";
|
|
4
|
+
import { DifficultySchema, MediaCreditSchema, MediaTypeSchema, } from "./question.schema.js";
|
|
5
5
|
import { OptionalScoringModeSchema } from "./scoring.schema.js";
|
|
6
6
|
/**
|
|
7
7
|
* Frame-level validation for the multiplayer game WebSocket (issue #734 hardening).
|
|
@@ -76,6 +76,7 @@ const BaseQuizQuestionFields = {
|
|
|
76
76
|
answers: Schema.Array(QuizAnswerSchema).pipe(Schema.minItems(1), Schema.maxItems(8)),
|
|
77
77
|
mediaUrl: Schema.optional(Schema.String.pipe(Schema.maxLength(2048))),
|
|
78
78
|
mediaType: Schema.optional(MediaTypeSchema),
|
|
79
|
+
mediaCredit: Schema.optional(MediaCreditSchema),
|
|
79
80
|
};
|
|
80
81
|
const StandardPreloadedQuestionSchema = Schema.Struct({
|
|
81
82
|
...BaseQuizQuestionFields,
|
package/dist/ws.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { ErrorCode } from "./error-codes.ts";
|
|
|
3
3
|
import type { AdvanceMode, Difficulty, DifficultyFilter, ScoringMode, TimerDuration } from "./game.settings.ts";
|
|
4
4
|
import type { Player, PlayerRole, QuizQuestion } from "./game.ts";
|
|
5
5
|
import type { GameAnswerRecord } from "./game-answer-record.ts";
|
|
6
|
-
import type { MediaType, QuestionType } from "./question.schema.ts";
|
|
6
|
+
import type { MediaCredit, MediaType, QuestionType } from "./question.schema.ts";
|
|
7
7
|
import type { QuestionRating } from "./question-rating.ts";
|
|
8
8
|
import type { StreakFlourish } from "./streak-flourish.ts";
|
|
9
9
|
export type ClientMessage = WsAuthMessage | PlayerAnswerMessage | PlayerEmoteMessage | PlayerRoleMessage | PlayerLeaveMessage | PlayerRateMessage | CuratorStartMessage | CuratorAdvanceMessage | CuratorStartRoleSelectionMessage | CuratorIntermissionMessage | CuratorPlayerActionMessage | CuratorStopMessage | CuratorResetMessage | WsPongMessage;
|
|
@@ -165,6 +165,7 @@ export interface GameQuestionMessage {
|
|
|
165
165
|
};
|
|
166
166
|
mediaUrl?: string;
|
|
167
167
|
mediaType?: MediaType;
|
|
168
|
+
mediaCredit?: MediaCredit;
|
|
168
169
|
timeRemaining: number;
|
|
169
170
|
serverTs: number;
|
|
170
171
|
/** This recipient's own already-submitted answer, if any — set only on a
|