@orakl/protocol 0.12.0 → 0.13.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.
@@ -623,12 +623,7 @@ export declare const CuratorHistoryEntryPageSchema: Schema.Struct<{
623
623
  readonly questionText?: string | undefined;
624
624
  readonly mediaUrl?: string | undefined;
625
625
  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;
626
+ readonly mediaCredit?: unknown;
632
627
  }, never>>>>;
633
628
  }>;
634
629
  presetLimit: typeof Schema.Number;
@@ -1,6 +1,6 @@
1
1
  import { Schema } from "effect";
2
2
  import { EmoteSetSchema } from "../emotes.js";
3
- import { MediaCreditSchema, MediaTypeSchema, StoredQuestionSourceSchema, } from "../question.schema.js";
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`
@@ -341,7 +341,7 @@ const QuestionRecapEntrySchema = Schema.Struct({
341
341
  questionText: Schema.optional(Schema.String),
342
342
  mediaUrl: Schema.optional(Schema.String),
343
343
  mediaType: Schema.optional(MediaTypeSchema),
344
- mediaCredit: Schema.optional(MediaCreditSchema),
344
+ mediaCredit: Schema.optional(StoredMediaCreditSchema),
345
345
  source: Schema.optional(StoredQuestionSourceSchema),
346
346
  postAnswerNote: Schema.optional(Schema.String),
347
347
  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.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
+ 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 { MediaCreditSchema, MediaTypeSchema, StoredQuestionSourceSchema, } from "../question.schema.js";
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(MediaCreditSchema),
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.filter<Schema.Struct<{
245
- licence: Schema.Literal<["cc0", "public-domain", "cc-by", "cc-by-sa", "own"]>;
246
- author: Schema.optional<Schema.filter<typeof Schema.String>>;
247
- sourceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
248
- licenceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
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.NullOr<Schema.filter<Schema.Struct<{
306
- licence: Schema.Literal<["cc0", "public-domain", "cc-by", "cc-by-sa", "own"]>;
307
- author: Schema.optional<Schema.filter<typeof Schema.String>>;
308
- sourceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
309
- licenceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
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 { MediaCreditSchema, MediaTypeSchema, StoredQuestionSourceSchema, } from "../question.schema.js";
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
- mediaCredit: Schema.optional(Schema.NullOr(MediaCreditSchema)),
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.filter<Schema.Struct<{
156
- licence: Schema.Literal<["cc0", "public-domain", "cc-by", "cc-by-sa", "own"]>;
157
- author: Schema.optional<Schema.filter<typeof Schema.String>>;
158
- sourceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
159
- licenceUrl: Schema.optional<Schema.filter<Schema.filter<typeof Schema.String>>>;
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;
@@ -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,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orakl/protocol",
3
- "version": "0.12.0",
3
+ "version": "0.13.0",
4
4
  "description": "Orakl wire contract: WebSocket frames and API response schemas.",
5
5
  "license": "AGPL-3.0-only",
6
6
  "repository": {