@orakl/protocol 0.12.0 → 0.14.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/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/pages/app.schema.d.ts +42 -6
- package/dist/pages/app.schema.js +25 -2
- package/dist/pages/common.schema.d.ts +11 -6
- package/dist/pages/common.schema.js +2 -2
- package/dist/pages/history.schema.d.ts +22 -12
- package/dist/pages/history.schema.js +3 -2
- package/dist/pages/quiz.schema.d.ts +11 -6
- package/dist/question.schema.d.ts +22 -0
- package/dist/question.schema.js +23 -6
- package/package.json +1 -1
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 { 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";
|
|
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, POST_ANSWER_NOTE_MAX_LEN, PostAnswerNoteSchema, type Question, QuestionSchema, type QuestionSource, QuestionSourceSchema, type QuestionType, QuestionTypeSchema, SOURCE_LABEL_MAX_LEN, SOURCE_URL_MAX_LEN, 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 { ATTRIBUTION_LICENCES, CREDIT_LICENCE_LABEL, CREDIT_LICENCES, CreditLicenceSchema, DISTRIBUTABLE_LICENCES, DifficultySchema, isHttpsUrl, MediaCreditSchema, 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, POST_ANSWER_NOTE_MAX_LEN, PostAnswerNoteSchema, QuestionSchema, QuestionSourceSchema, QuestionTypeSchema, SOURCE_LABEL_MAX_LEN, SOURCE_URL_MAX_LEN, 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";
|
|
@@ -288,6 +288,47 @@ export declare const ManageQuestionRatingsPageSchema: Schema.Struct<{
|
|
|
288
288
|
initialHasMore: typeof Schema.Boolean;
|
|
289
289
|
page: typeof Schema.Number;
|
|
290
290
|
}>;
|
|
291
|
+
declare const BankQuestionRowSchema: Schema.Struct<{
|
|
292
|
+
id: typeof Schema.String;
|
|
293
|
+
excerpt: typeof Schema.String;
|
|
294
|
+
source: Schema.Literal<["built-in", "promoted"]>;
|
|
295
|
+
category: typeof Schema.String;
|
|
296
|
+
/** The stored question type, e.g. `text_choice`. */
|
|
297
|
+
type: typeof Schema.String;
|
|
298
|
+
difficulty: Schema.NullOr<Schema.Literal<["easy", "medium", "hard"]>>;
|
|
299
|
+
/** At least one revision exists. */
|
|
300
|
+
edited: typeof Schema.Boolean;
|
|
301
|
+
}>;
|
|
302
|
+
/** One question an operator may edit on the question bank page: built-in or promoted. */
|
|
303
|
+
export type BankQuestionRow = typeof BankQuestionRowSchema.Type;
|
|
304
|
+
/** Body of `GET /api/pages/manage/bank`. */
|
|
305
|
+
export declare const ManageBankPageSchema: Schema.Struct<{
|
|
306
|
+
initial: Schema.mutable<Schema.Array$<Schema.Schema<{
|
|
307
|
+
readonly type: string;
|
|
308
|
+
readonly source: "built-in" | "promoted";
|
|
309
|
+
readonly id: string;
|
|
310
|
+
readonly category: string;
|
|
311
|
+
readonly difficulty: "medium" | "easy" | "hard" | null;
|
|
312
|
+
readonly excerpt: string;
|
|
313
|
+
readonly edited: boolean;
|
|
314
|
+
}, {
|
|
315
|
+
readonly type: string;
|
|
316
|
+
readonly source: "built-in" | "promoted";
|
|
317
|
+
readonly id: string;
|
|
318
|
+
readonly category: string;
|
|
319
|
+
readonly difficulty: "medium" | "easy" | "hard" | null;
|
|
320
|
+
readonly excerpt: string;
|
|
321
|
+
readonly edited: boolean;
|
|
322
|
+
}, never>>>;
|
|
323
|
+
initialHasMore: typeof Schema.Boolean;
|
|
324
|
+
page: typeof Schema.Number;
|
|
325
|
+
/** The search term the page was loaded with; empty for none. */
|
|
326
|
+
q: typeof Schema.String;
|
|
327
|
+
/** The category name the page was filtered to; empty for all. */
|
|
328
|
+
category: typeof Schema.String;
|
|
329
|
+
/** Category names offered by the filter, A to Z. */
|
|
330
|
+
categories: Schema.mutable<Schema.Array$<Schema.Schema<string, string, never>>>;
|
|
331
|
+
}>;
|
|
291
332
|
declare const AuthoredQuestionRowSchema: Schema.Struct<{
|
|
292
333
|
id: typeof Schema.String;
|
|
293
334
|
category: typeof Schema.String;
|
|
@@ -623,12 +664,7 @@ export declare const CuratorHistoryEntryPageSchema: Schema.Struct<{
|
|
|
623
664
|
readonly questionText?: string | undefined;
|
|
624
665
|
readonly mediaUrl?: string | undefined;
|
|
625
666
|
readonly mediaType?: "audio" | "video" | "image" | undefined;
|
|
626
|
-
readonly mediaCredit?:
|
|
627
|
-
readonly licence: "cc0" | "public-domain" | "cc-by" | "cc-by-sa" | "own";
|
|
628
|
-
readonly author?: string | undefined;
|
|
629
|
-
readonly sourceUrl?: string | undefined;
|
|
630
|
-
readonly licenceUrl?: string | undefined;
|
|
631
|
-
} | undefined;
|
|
667
|
+
readonly mediaCredit?: unknown;
|
|
632
668
|
}, never>>>>;
|
|
633
669
|
}>;
|
|
634
670
|
presetLimit: typeof Schema.Number;
|
package/dist/pages/app.schema.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Schema } from "effect";
|
|
2
2
|
import { EmoteSetSchema } from "../emotes.js";
|
|
3
|
-
import {
|
|
3
|
+
import { MediaTypeSchema, StoredMediaCreditSchema, StoredQuestionSourceSchema, } from "../question.schema.js";
|
|
4
4
|
import { ThemeModeSchema, UserPowerSchema, UserRoleSchema, } from "./common.schema.js";
|
|
5
5
|
/** Page-load response bodies for `src/api/routes/pages.ts`. */
|
|
6
6
|
/** A JSON array, decoded mutable — Effect's `Schema.Array` types its `.Type`
|
|
@@ -196,6 +196,29 @@ export const ManageQuestionRatingsPageSchema = Schema.Struct({
|
|
|
196
196
|
initialHasMore: Schema.Boolean,
|
|
197
197
|
page: Schema.Number,
|
|
198
198
|
});
|
|
199
|
+
const BankQuestionRowSchema = Schema.Struct({
|
|
200
|
+
id: Schema.String,
|
|
201
|
+
excerpt: Schema.String,
|
|
202
|
+
source: Schema.Literal("built-in", "promoted"),
|
|
203
|
+
category: Schema.String,
|
|
204
|
+
/** The stored question type, e.g. `text_choice`. */
|
|
205
|
+
type: Schema.String,
|
|
206
|
+
difficulty: Schema.NullOr(Schema.Literal("easy", "medium", "hard")),
|
|
207
|
+
/** At least one revision exists. */
|
|
208
|
+
edited: Schema.Boolean,
|
|
209
|
+
});
|
|
210
|
+
/** Body of `GET /api/pages/manage/bank`. */
|
|
211
|
+
export const ManageBankPageSchema = Schema.Struct({
|
|
212
|
+
initial: Arr(BankQuestionRowSchema),
|
|
213
|
+
initialHasMore: Schema.Boolean,
|
|
214
|
+
page: Schema.Number,
|
|
215
|
+
/** The search term the page was loaded with; empty for none. */
|
|
216
|
+
q: Schema.String,
|
|
217
|
+
/** The category name the page was filtered to; empty for all. */
|
|
218
|
+
category: Schema.String,
|
|
219
|
+
/** Category names offered by the filter, A to Z. */
|
|
220
|
+
categories: Arr(Schema.String),
|
|
221
|
+
});
|
|
199
222
|
const AuthoredQuestionRowSchema = Schema.Struct({
|
|
200
223
|
id: Schema.String,
|
|
201
224
|
category: Schema.String,
|
|
@@ -341,7 +364,7 @@ const QuestionRecapEntrySchema = Schema.Struct({
|
|
|
341
364
|
questionText: Schema.optional(Schema.String),
|
|
342
365
|
mediaUrl: Schema.optional(Schema.String),
|
|
343
366
|
mediaType: Schema.optional(MediaTypeSchema),
|
|
344
|
-
mediaCredit: Schema.optional(
|
|
367
|
+
mediaCredit: Schema.optional(StoredMediaCreditSchema),
|
|
345
368
|
source: Schema.optional(StoredQuestionSourceSchema),
|
|
346
369
|
postAnswerNote: Schema.optional(Schema.String),
|
|
347
370
|
answered: Schema.Number,
|
|
@@ -19,12 +19,17 @@ 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.
|
|
23
|
-
licence:
|
|
24
|
-
author
|
|
25
|
-
sourceUrl
|
|
26
|
-
licenceUrl
|
|
27
|
-
}
|
|
22
|
+
mediaCredit: Schema.optional<Schema.transform<typeof Schema.Unknown, Schema.UndefinedOr<Schema.SchemaClass<{
|
|
23
|
+
readonly licence: "cc0" | "public-domain" | "cc-by" | "cc-by-sa" | "own";
|
|
24
|
+
readonly author?: string | undefined;
|
|
25
|
+
readonly sourceUrl?: string | undefined;
|
|
26
|
+
readonly licenceUrl?: string | undefined;
|
|
27
|
+
}, {
|
|
28
|
+
readonly licence: "cc0" | "public-domain" | "cc-by" | "cc-by-sa" | "own";
|
|
29
|
+
readonly author?: string | undefined;
|
|
30
|
+
readonly sourceUrl?: string | undefined;
|
|
31
|
+
readonly licenceUrl?: string | undefined;
|
|
32
|
+
}, never>>>>;
|
|
28
33
|
source: Schema.optional<Schema.transform<typeof Schema.Unknown, Schema.UndefinedOr<Schema.SchemaClass<{
|
|
29
34
|
readonly url: string;
|
|
30
35
|
readonly label?: string | undefined;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Schema } from "effect";
|
|
2
|
-
import {
|
|
2
|
+
import { MediaTypeSchema, StoredMediaCreditSchema, 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,7 +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(
|
|
23
|
+
mediaCredit: Schema.optional(StoredMediaCreditSchema),
|
|
24
24
|
source: Schema.optional(StoredQuestionSourceSchema),
|
|
25
25
|
postAnswerNote: Schema.optional(Schema.String),
|
|
26
26
|
});
|
|
@@ -241,12 +241,17 @@ export declare const GameReviewPageSchema: Schema.Struct<{
|
|
|
241
241
|
correctAnswerText: Schema.optional<typeof Schema.String>;
|
|
242
242
|
mediaUrl: Schema.optional<typeof Schema.String>;
|
|
243
243
|
mediaType: Schema.optional<Schema.Literal<["image", "audio", "video"]>>;
|
|
244
|
-
mediaCredit: Schema.optional<Schema.
|
|
245
|
-
licence:
|
|
246
|
-
author
|
|
247
|
-
sourceUrl
|
|
248
|
-
licenceUrl
|
|
249
|
-
}
|
|
244
|
+
mediaCredit: Schema.optional<Schema.transform<typeof Schema.Unknown, Schema.UndefinedOr<Schema.SchemaClass<{
|
|
245
|
+
readonly licence: "cc0" | "public-domain" | "cc-by" | "cc-by-sa" | "own";
|
|
246
|
+
readonly author?: string | undefined;
|
|
247
|
+
readonly sourceUrl?: string | undefined;
|
|
248
|
+
readonly licenceUrl?: string | undefined;
|
|
249
|
+
}, {
|
|
250
|
+
readonly licence: "cc0" | "public-domain" | "cc-by" | "cc-by-sa" | "own";
|
|
251
|
+
readonly author?: string | undefined;
|
|
252
|
+
readonly sourceUrl?: string | undefined;
|
|
253
|
+
readonly licenceUrl?: string | undefined;
|
|
254
|
+
}, never>>>>;
|
|
250
255
|
source: Schema.optional<Schema.transform<typeof Schema.Unknown, Schema.UndefinedOr<Schema.SchemaClass<{
|
|
251
256
|
readonly url: string;
|
|
252
257
|
readonly label?: string | undefined;
|
|
@@ -302,12 +307,17 @@ export declare const SoloReviewPageSchema: Schema.Struct<{
|
|
|
302
307
|
questionId: Schema.NullOr<typeof Schema.String>;
|
|
303
308
|
mediaUrl: Schema.NullOr<typeof Schema.String>;
|
|
304
309
|
mediaType: Schema.NullOr<Schema.Literal<["image", "audio", "video"]>>;
|
|
305
|
-
mediaCredit: Schema.optional<Schema.
|
|
306
|
-
licence:
|
|
307
|
-
author
|
|
308
|
-
sourceUrl
|
|
309
|
-
licenceUrl
|
|
310
|
-
}
|
|
310
|
+
mediaCredit: Schema.optional<Schema.Union<[typeof Schema.Null, Schema.transform<typeof Schema.Unknown, Schema.UndefinedOr<Schema.SchemaClass<{
|
|
311
|
+
readonly licence: "cc0" | "public-domain" | "cc-by" | "cc-by-sa" | "own";
|
|
312
|
+
readonly author?: string | undefined;
|
|
313
|
+
readonly sourceUrl?: string | undefined;
|
|
314
|
+
readonly licenceUrl?: string | undefined;
|
|
315
|
+
}, {
|
|
316
|
+
readonly licence: "cc0" | "public-domain" | "cc-by" | "cc-by-sa" | "own";
|
|
317
|
+
readonly author?: string | undefined;
|
|
318
|
+
readonly sourceUrl?: string | undefined;
|
|
319
|
+
readonly licenceUrl?: string | undefined;
|
|
320
|
+
}, never>>>]>>;
|
|
311
321
|
source: Schema.Union<[typeof Schema.Null, Schema.transform<typeof Schema.Unknown, Schema.UndefinedOr<Schema.SchemaClass<{
|
|
312
322
|
readonly url: string;
|
|
313
323
|
readonly label?: string | undefined;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Schema } from "effect";
|
|
2
|
-
import {
|
|
2
|
+
import { MediaTypeSchema, StoredMediaCreditSchema, 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`). */
|
|
@@ -208,7 +208,8 @@ const SoloRunReviewEntrySchema = Schema.Struct({
|
|
|
208
208
|
mediaUrl: Schema.NullOr(Schema.String),
|
|
209
209
|
mediaType: Schema.NullOr(MediaTypeSchema),
|
|
210
210
|
// Optional: a review served before credits existed has no key.
|
|
211
|
-
|
|
211
|
+
// Null first: the stored-credit transform accepts any value, null included.
|
|
212
|
+
mediaCredit: Schema.optional(Schema.Union(Schema.Null, StoredMediaCreditSchema)),
|
|
212
213
|
// Null first: the stored-source transform accepts any value, null included.
|
|
213
214
|
source: Schema.Union(Schema.Null, StoredQuestionSourceSchema),
|
|
214
215
|
postAnswerNote: Schema.NullOr(Schema.String),
|
|
@@ -152,12 +152,17 @@ export declare const QuizResultsPageSchema: Schema.Struct<{
|
|
|
152
152
|
correctAnswerText: Schema.optional<typeof Schema.String>;
|
|
153
153
|
mediaUrl: Schema.optional<typeof Schema.String>;
|
|
154
154
|
mediaType: Schema.optional<Schema.Literal<["image", "audio", "video"]>>;
|
|
155
|
-
mediaCredit: Schema.optional<Schema.
|
|
156
|
-
licence:
|
|
157
|
-
author
|
|
158
|
-
sourceUrl
|
|
159
|
-
licenceUrl
|
|
160
|
-
}
|
|
155
|
+
mediaCredit: Schema.optional<Schema.transform<typeof Schema.Unknown, Schema.UndefinedOr<Schema.SchemaClass<{
|
|
156
|
+
readonly licence: "cc0" | "public-domain" | "cc-by" | "cc-by-sa" | "own";
|
|
157
|
+
readonly author?: string | undefined;
|
|
158
|
+
readonly sourceUrl?: string | undefined;
|
|
159
|
+
readonly licenceUrl?: string | undefined;
|
|
160
|
+
}, {
|
|
161
|
+
readonly licence: "cc0" | "public-domain" | "cc-by" | "cc-by-sa" | "own";
|
|
162
|
+
readonly author?: string | undefined;
|
|
163
|
+
readonly sourceUrl?: string | undefined;
|
|
164
|
+
readonly licenceUrl?: string | undefined;
|
|
165
|
+
}, never>>>>;
|
|
161
166
|
source: Schema.optional<Schema.transform<typeof Schema.Unknown, Schema.UndefinedOr<Schema.SchemaClass<{
|
|
162
167
|
readonly url: string;
|
|
163
168
|
readonly label?: string | undefined;
|
|
@@ -24,6 +24,22 @@ export declare const MediaCreditSchema: Schema.filter<Schema.Struct<{
|
|
|
24
24
|
licenceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
|
|
25
25
|
}>>;
|
|
26
26
|
export type MediaCredit = typeof MediaCreditSchema.Type;
|
|
27
|
+
/**
|
|
28
|
+
* Read-side credit: a stored value that fails `MediaCreditSchema` (a rule
|
|
29
|
+
* tightened after it was written, a wrong shape) decodes to undefined, so one
|
|
30
|
+
* bad credit never fails a whole page.
|
|
31
|
+
*/
|
|
32
|
+
export declare const StoredMediaCreditSchema: Schema.transform<typeof Schema.Unknown, Schema.UndefinedOr<Schema.SchemaClass<{
|
|
33
|
+
readonly licence: "cc0" | "public-domain" | "cc-by" | "cc-by-sa" | "own";
|
|
34
|
+
readonly author?: string | undefined;
|
|
35
|
+
readonly sourceUrl?: string | undefined;
|
|
36
|
+
readonly licenceUrl?: string | undefined;
|
|
37
|
+
}, {
|
|
38
|
+
readonly licence: "cc0" | "public-domain" | "cc-by" | "cc-by-sa" | "own";
|
|
39
|
+
readonly author?: string | undefined;
|
|
40
|
+
readonly sourceUrl?: string | undefined;
|
|
41
|
+
readonly licenceUrl?: string | undefined;
|
|
42
|
+
}, never>>>;
|
|
27
43
|
export declare const MediaSchema: Schema.Struct<{
|
|
28
44
|
type: Schema.Literal<["image", "audio", "video"]>;
|
|
29
45
|
url: typeof Schema.String;
|
|
@@ -37,6 +53,12 @@ export declare const MediaSchema: Schema.Struct<{
|
|
|
37
53
|
licenceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
|
|
38
54
|
}>>>;
|
|
39
55
|
}>;
|
|
56
|
+
/** Max characters in a question source URL. */
|
|
57
|
+
export declare const SOURCE_URL_MAX_LEN = 2048;
|
|
58
|
+
/** Max characters in a question source label. */
|
|
59
|
+
export declare const SOURCE_LABEL_MAX_LEN = 200;
|
|
60
|
+
/** Max characters in a post-answer note. */
|
|
61
|
+
export declare const POST_ANSWER_NOTE_MAX_LEN = 160;
|
|
40
62
|
export declare const QuestionSourceSchema: Schema.Struct<{
|
|
41
63
|
url: Schema.filter<Schema.filter<typeof Schema.String>>;
|
|
42
64
|
label: Schema.optional<Schema.filter<typeof Schema.String>>;
|
package/dist/question.schema.js
CHANGED
|
@@ -57,6 +57,17 @@ export const MediaCreditSchema = Schema.Struct({
|
|
|
57
57
|
}).pipe(Schema.filter((c) => !ATTRIBUTION_LICENCES.includes(c.licence) ||
|
|
58
58
|
Boolean(c.author?.trim()) ||
|
|
59
59
|
"Author is required for CC BY and CC BY-SA"));
|
|
60
|
+
const isMediaCredit = Schema.is(MediaCreditSchema);
|
|
61
|
+
/**
|
|
62
|
+
* Read-side credit: a stored value that fails `MediaCreditSchema` (a rule
|
|
63
|
+
* tightened after it was written, a wrong shape) decodes to undefined, so one
|
|
64
|
+
* bad credit never fails a whole page.
|
|
65
|
+
*/
|
|
66
|
+
export const StoredMediaCreditSchema = Schema.transform(Schema.Unknown, Schema.UndefinedOr(Schema.typeSchema(MediaCreditSchema)), {
|
|
67
|
+
strict: true,
|
|
68
|
+
decode: (credit) => (isMediaCredit(credit) ? credit : undefined),
|
|
69
|
+
encode: (credit) => credit,
|
|
70
|
+
});
|
|
60
71
|
export const MediaSchema = Schema.Struct({
|
|
61
72
|
type: MediaTypeSchema,
|
|
62
73
|
url: Schema.String,
|
|
@@ -66,13 +77,19 @@ export const MediaSchema = Schema.Struct({
|
|
|
66
77
|
// Security: source.url is stored in the DB and read back on results/history
|
|
67
78
|
// pages; cap to match imageUrl's bound (curator.schema.ts) since both are
|
|
68
79
|
// URLs of the same practical size.
|
|
69
|
-
|
|
70
|
-
|
|
80
|
+
/** Max characters in a question source URL. */
|
|
81
|
+
export const SOURCE_URL_MAX_LEN = 2048;
|
|
82
|
+
/** Max characters in a question source label. */
|
|
83
|
+
export const SOURCE_LABEL_MAX_LEN = 200;
|
|
84
|
+
/** Max characters in a post-answer note. */
|
|
85
|
+
export const POST_ANSWER_NOTE_MAX_LEN = 160;
|
|
86
|
+
const HttpsUrlSchema = Schema.String.pipe(Schema.maxLength(SOURCE_URL_MAX_LEN, {
|
|
87
|
+
message: () => `Source URL must be ${SOURCE_URL_MAX_LEN} characters or fewer`,
|
|
71
88
|
}), Schema.filter(isHttpsUrl, { message: () => "Source URL must be https" }));
|
|
72
89
|
export const QuestionSourceSchema = Schema.Struct({
|
|
73
90
|
url: HttpsUrlSchema,
|
|
74
|
-
label: Schema.optional(Schema.String.pipe(Schema.maxLength(
|
|
75
|
-
message: () =>
|
|
91
|
+
label: Schema.optional(Schema.String.pipe(Schema.maxLength(SOURCE_LABEL_MAX_LEN, {
|
|
92
|
+
message: () => `Source label must be ${SOURCE_LABEL_MAX_LEN} characters or fewer`,
|
|
76
93
|
}))),
|
|
77
94
|
});
|
|
78
95
|
const isQuestionSource = Schema.is(QuestionSourceSchema);
|
|
@@ -86,8 +103,8 @@ export const StoredQuestionSourceSchema = Schema.transform(Schema.Unknown, Schem
|
|
|
86
103
|
decode: (source) => (isQuestionSource(source) ? source : undefined),
|
|
87
104
|
encode: (source) => source,
|
|
88
105
|
});
|
|
89
|
-
export const PostAnswerNoteSchema = Schema.String.pipe(Schema.maxLength(
|
|
90
|
-
message: () =>
|
|
106
|
+
export const PostAnswerNoteSchema = Schema.String.pipe(Schema.maxLength(POST_ANSWER_NOTE_MAX_LEN, {
|
|
107
|
+
message: () => `Post-answer note must be ${POST_ANSWER_NOTE_MAX_LEN} characters or fewer`,
|
|
91
108
|
}));
|
|
92
109
|
const MetadataSchema = Schema.Struct({
|
|
93
110
|
source: SourceSchema,
|