@intellectif/lk-core 0.2.0 → 0.3.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 (61) hide show
  1. package/README.md +70 -0
  2. package/dist/activity-zdcAMtFB.d.cts +626 -0
  3. package/dist/activity-zdcAMtFB.d.ts +626 -0
  4. package/dist/chunk-3YAVDV5F.js +47 -0
  5. package/dist/chunk-3YAVDV5F.js.map +1 -0
  6. package/dist/chunk-55O4M45K.js +57 -0
  7. package/dist/chunk-55O4M45K.js.map +1 -0
  8. package/dist/chunk-5GJJHGY5.js +576 -0
  9. package/dist/chunk-5GJJHGY5.js.map +1 -0
  10. package/dist/{chunk-ZHOX6TO4.js → chunk-HS7BYCGE.js} +65 -7
  11. package/dist/chunk-HS7BYCGE.js.map +1 -0
  12. package/dist/chunk-PIMX4B4D.cjs +47 -0
  13. package/dist/chunk-PIMX4B4D.cjs.map +1 -0
  14. package/dist/chunk-QOAORTA4.cjs +576 -0
  15. package/dist/chunk-QOAORTA4.cjs.map +1 -0
  16. package/dist/chunk-QSVBYTNM.js +94 -0
  17. package/dist/chunk-QSVBYTNM.js.map +1 -0
  18. package/dist/{chunk-PJFDAP54.cjs → chunk-RUGIOQZY.cjs} +66 -8
  19. package/dist/chunk-RUGIOQZY.cjs.map +1 -0
  20. package/dist/chunk-THSZMZND.cjs +94 -0
  21. package/dist/chunk-THSZMZND.cjs.map +1 -0
  22. package/dist/chunk-YNTYWHZI.cjs +57 -0
  23. package/dist/chunk-YNTYWHZI.cjs.map +1 -0
  24. package/dist/index.cjs +185 -6
  25. package/dist/index.cjs.map +1 -1
  26. package/dist/index.d.cts +253 -7
  27. package/dist/index.d.ts +253 -7
  28. package/dist/index.js +188 -9
  29. package/dist/index.js.map +1 -1
  30. package/dist/schemas.cjs +29 -2
  31. package/dist/schemas.cjs.map +1 -1
  32. package/dist/schemas.d.cts +312 -31
  33. package/dist/schemas.d.ts +312 -31
  34. package/dist/schemas.js +32 -5
  35. package/dist/scoring.cjs +13 -3
  36. package/dist/scoring.cjs.map +1 -1
  37. package/dist/scoring.d.cts +29 -5
  38. package/dist/scoring.d.ts +29 -5
  39. package/dist/scoring.js +12 -2
  40. package/dist/xapi.cjs +3 -3
  41. package/dist/xapi.cjs.map +1 -1
  42. package/dist/xapi.d.cts +40 -2
  43. package/dist/xapi.d.ts +40 -2
  44. package/dist/xapi.js +2 -2
  45. package/package.json +12 -2
  46. package/dist/activity-D5tqgx8A.d.cts +0 -330
  47. package/dist/activity-D5tqgx8A.d.ts +0 -330
  48. package/dist/chunk-2T3IL7VL.js +0 -147
  49. package/dist/chunk-2T3IL7VL.js.map +0 -1
  50. package/dist/chunk-3JMLUUFS.cjs +0 -124
  51. package/dist/chunk-3JMLUUFS.cjs.map +0 -1
  52. package/dist/chunk-6VOCV4EX.js +0 -25
  53. package/dist/chunk-6VOCV4EX.js.map +0 -1
  54. package/dist/chunk-DCDOTQNH.cjs +0 -147
  55. package/dist/chunk-DCDOTQNH.cjs.map +0 -1
  56. package/dist/chunk-DV466SBJ.cjs +0 -25
  57. package/dist/chunk-DV466SBJ.cjs.map +0 -1
  58. package/dist/chunk-GZ73G2TS.js +0 -124
  59. package/dist/chunk-GZ73G2TS.js.map +0 -1
  60. package/dist/chunk-PJFDAP54.cjs.map +0 -1
  61. package/dist/chunk-ZHOX6TO4.js.map +0 -1
@@ -1,330 +0,0 @@
1
- /**
2
- * An xAPI Activity object — the thing a statement is about.
3
- * This SDK only builds Activity-type objects (xAPI 1.0.3 §4.1.4.1).
4
- */
5
- interface XAPIObject {
6
- objectType: 'Activity';
7
- /** IRI uniquely identifying the activity. */
8
- id: string;
9
- definition?: {
10
- /** Language-map of human-readable names for the activity. */
11
- name?: Record<string, string>;
12
- /** Language-map of human-readable descriptions. */
13
- description?: Record<string, string>;
14
- /** IRI identifying the activity type. */
15
- type?: string;
16
- extensions?: Record<string, unknown>;
17
- };
18
- }
19
- /**
20
- * An xAPI Agent (person or system) that performed the statement's verb.
21
- * Exactly one of `mbox` or `account` must be present.
22
- */
23
- interface XAPIActor {
24
- objectType: 'Agent';
25
- /** Display name for the actor. */
26
- name?: string;
27
- /** Mailto IRI uniquely identifying the actor (e.g. `mailto:user@example.com`). */
28
- mbox?: string;
29
- /** Account-based actor identifier. */
30
- account?: {
31
- /** IRI of the home page of the account's service provider. */
32
- homePage: string;
33
- /** The actor's unique name on that service. */
34
- name: string;
35
- };
36
- }
37
- /** An xAPI Verb — the action performed in the statement. */
38
- interface XAPIVerbObject {
39
- /** IRI uniquely identifying this verb (e.g. from adlnet.gov/expapi/verbs). */
40
- id: string;
41
- /** Language-map of human-readable verb labels. */
42
- display: Record<string, string>;
43
- }
44
- /** Score sub-object within an xAPI Result. */
45
- interface XAPIScore {
46
- /** Normalized score in the range [0, 1]. */
47
- scaled: number;
48
- /** Raw score in the instrument's native scale. */
49
- raw?: number;
50
- /** Minimum possible raw score. */
51
- min?: number;
52
- /** Maximum possible raw score. */
53
- max?: number;
54
- }
55
- /** Result information attached to an xAPI Statement. */
56
- interface XAPIResult {
57
- score?: XAPIScore;
58
- /** Whether the actor's performance was successful. */
59
- success?: boolean;
60
- /** Whether the activity was completed. */
61
- completion?: boolean;
62
- /** ISO 8601 duration string representing time spent (e.g. `PT5M30S`). */
63
- duration?: string;
64
- /** A string representation of the learner's response. */
65
- response?: string;
66
- extensions?: Record<string, unknown>;
67
- }
68
- /** Context information attached to an xAPI Statement. */
69
- interface XAPIContext {
70
- /** Name of the software used to record the statement. */
71
- platform?: string;
72
- /** BCP 47 language tag for the activity content. */
73
- language?: string;
74
- extensions?: Record<string, unknown>;
75
- }
76
- /** A complete xAPI 1.0.3 Statement. */
77
- interface XAPIStatement {
78
- /** UUID v4 uniquely identifying this statement. */
79
- id: string;
80
- actor: XAPIActor;
81
- verb: XAPIVerbObject;
82
- object: XAPIObject;
83
- result?: XAPIResult;
84
- context?: XAPIContext;
85
- /** ISO 8601 timestamp of when the statement occurred. */
86
- timestamp: string;
87
- version: '1.0.3';
88
- }
89
- /**
90
- * Configuration passed to `useXAPI` to connect to an LRS endpoint.
91
- * The `auth` field supports both HTTP Basic and Bearer token authentication.
92
- */
93
- interface XAPIConfig {
94
- /** Full URL of the LRS statements endpoint. */
95
- endpoint: string;
96
- /** Authentication credentials for the LRS. */
97
- auth: {
98
- type: 'basic';
99
- username: string;
100
- password: string;
101
- } | {
102
- type: 'bearer';
103
- token: string;
104
- };
105
- /** IRI identifying the activity in all statements sent by this hook instance. */
106
- activityId: string;
107
- actor: XAPIActor;
108
- /** Called after all retry attempts are exhausted. */
109
- onError?: (err: XAPIError) => void;
110
- }
111
- /** Error payload delivered to `XAPIConfig.onError` after retries are exhausted. */
112
- interface XAPIError {
113
- /** The statement that failed to send. */
114
- statement: XAPIStatement;
115
- /** The 1-based attempt number on which the final failure occurred. */
116
- attempt: number;
117
- /** HTTP status code from the LRS, if a response was received. */
118
- statusCode?: number;
119
- /** Human-readable error description. */
120
- message: string;
121
- }
122
-
123
- /** The set of activity types supported by learning-kit. */
124
- type ActivityType = 'multiple-choice' | 'fill-in-the-blanks';
125
- /** Maps each ActivityType string to its corresponding data shape. */
126
- interface ActivityDataMap {
127
- 'multiple-choice': MultipleChoiceData;
128
- 'fill-in-the-blanks': FillInTheBlanksData;
129
- }
130
- /** Union of all valid activity data shapes. */
131
- type ActivityData = MultipleChoiceData | FillInTheBlanksData;
132
- /**
133
- * Optional media (image/audio/video) shown above a question or passage.
134
- * URL-only: hosting/delivery is the consuming application's responsibility.
135
- */
136
- interface ActivityMedia {
137
- /** The kind of media; selects the rendered element. `embed` → sandboxed iframe. */
138
- type: 'image' | 'audio' | 'video' | 'embed';
139
- /**
140
- * Source URL. For `embed` this MUST be the provider's embeddable URL
141
- * (e.g. `https://www.youtube.com/embed/<id>`), not the watch page.
142
- */
143
- url: string;
144
- /** Alternative text. Required for `image` and `embed`; optional label for audio/video. */
145
- alt?: string;
146
- /** Optional WebVTT captions track URL for `audio`/`video`. */
147
- captionsUrl?: string;
148
- }
149
- /**
150
- * Optional authored "overall feedback" shown after submission, chosen by
151
- * whether the learner passed (h5p-style overall feedback). Distinct from
152
- * per-option feedback; either field may be omitted.
153
- */
154
- interface ActivityFeedback {
155
- /** Shown when the learner passes (score ≥ pass threshold). */
156
- correct?: string;
157
- /** Shown when the learner does not pass. */
158
- incorrect?: string;
159
- }
160
- /** A single selectable option within a Multiple Choice activity. */
161
- interface MultipleChoiceOption {
162
- /** Unique identifier for this option within the activity. */
163
- id: string;
164
- /** Display text shown to the learner. */
165
- text: string;
166
- /** Whether this option is part of the correct answer. */
167
- isCorrect: boolean;
168
- /** Optional per-option feedback shown after submission. */
169
- feedback?: string;
170
- }
171
- /** Data contract for a Multiple Choice activity. */
172
- interface MultipleChoiceData {
173
- schemaVersion: '1.0';
174
- type: 'multiple-choice';
175
- /** Unique identifier for this activity. */
176
- id: string;
177
- /** Human-readable title used in xAPI statements and error boundaries. */
178
- title: string;
179
- /** The question stem presented to the learner. */
180
- question: string;
181
- /** `single` allows one selection; `multi` allows multiple. */
182
- mode: 'single' | 'multi';
183
- /** Ordered list of answer options. */
184
- options: MultipleChoiceOption[];
185
- /** Scoring algorithm applied when the learner submits. */
186
- scoringStrategy: 'all-or-nothing' | 'partial';
187
- /** Optional media shown above the question. */
188
- media?: ActivityMedia;
189
- /** Optional authored overall feedback shown after submission. */
190
- feedback?: ActivityFeedback;
191
- /** Minimum scaled score [0–1] required to pass. Defaults to 0.6 when absent. */
192
- passThreshold?: number;
193
- /** When true, options are shuffled deterministically per session. */
194
- shuffle?: boolean;
195
- /** BCP 47 language tag for the activity content. */
196
- locale?: string;
197
- /** IRI references to learning objectives addressed by this activity. */
198
- learningObjectives?: string[];
199
- /** Subjective difficulty on a 1–5 scale. */
200
- difficultyLevel?: 1 | 2 | 3 | 4 | 5;
201
- }
202
- /** Configuration for a single fill-in-the-blank slot. */
203
- interface BlankConfig {
204
- /** Unique identifier matching the `{{blank_id}}` placeholder in the passage. */
205
- id: string;
206
- /** List of strings accepted as correct answers for this blank. */
207
- acceptedAnswers: string[];
208
- /** Whether answer matching is case-sensitive. Defaults to false. */
209
- caseSensitive?: boolean;
210
- /** Whether leading/trailing whitespace is stripped before matching. Defaults to true. */
211
- trimWhitespace?: boolean;
212
- /** Optional hint text revealed on learner request. */
213
- hint?: string;
214
- /** Optional feedback shown inline next to this blank after submission. */
215
- feedback?: string;
216
- }
217
- /** Data contract for a Fill-in-the-Blanks activity. */
218
- interface FillInTheBlanksData {
219
- schemaVersion: '1.0';
220
- type: 'fill-in-the-blanks';
221
- /** Unique identifier for this activity. */
222
- id: string;
223
- /** Human-readable title used in xAPI statements and error boundaries. */
224
- title: string;
225
- /** Passage text containing `{{blank_id}}` placeholders. */
226
- passage: string;
227
- /** Configuration for each blank in the passage. */
228
- blanks: BlankConfig[];
229
- /** Scoring algorithm applied when the learner submits. */
230
- scoringStrategy: 'all-or-nothing' | 'partial';
231
- /** Optional media shown above the passage. */
232
- media?: ActivityMedia;
233
- /** Optional authored overall feedback shown after submission. */
234
- feedback?: ActivityFeedback;
235
- /** Minimum scaled score [0–1] required to pass. Defaults to 0.6 when absent. */
236
- passThreshold?: number;
237
- /** BCP 47 language tag for the activity content. */
238
- locale?: string;
239
- /** IRI references to learning objectives addressed by this activity. */
240
- learningObjectives?: string[];
241
- /** Subjective difficulty on a 1–5 scale. */
242
- difficultyLevel?: 1 | 2 | 3 | 4 | 5;
243
- }
244
- /** Union of all learner response shapes. */
245
- type LearnerResponse = MultipleChoiceLearnerResponse | FillInTheBlanksLearnerResponse;
246
- /** Learner response for a Multiple Choice activity. */
247
- interface MultipleChoiceLearnerResponse {
248
- type: 'multiple-choice';
249
- /** IDs of the options the learner selected. */
250
- selectedOptionIds: string[];
251
- }
252
- /** Learner response for a Fill-in-the-Blanks activity. */
253
- interface FillInTheBlanksLearnerResponse {
254
- type: 'fill-in-the-blanks';
255
- /** Map of blank ID to the learner's typed answer. */
256
- answers: Record<string, string>;
257
- }
258
- /** Per-item scoring breakdown returned by the scoring engine. */
259
- interface ScoringDetail {
260
- /** ID of the option or blank this detail refers to. */
261
- itemId: string;
262
- /** Whether the learner's response for this item was correct. */
263
- correct: boolean;
264
- /** The learner's actual response for this item. */
265
- learnerResponse: string | string[];
266
- /** The expected correct response(s) for this item. */
267
- correctResponse: string | string[];
268
- /** Optional weight applied to this item's contribution to the overall score. */
269
- weight?: number;
270
- }
271
- /** Full scoring result returned by the scoring engine. */
272
- interface ScoringResult {
273
- /** Scaled score in the range [0, 1]. */
274
- score: number;
275
- /** Maximum possible scaled score (always 1). */
276
- maxScore: number;
277
- /** Whether the score meets or exceeds the activity's pass threshold. */
278
- passed: boolean;
279
- /** Optional top-level feedback message, or null when absent. */
280
- feedback: string | null;
281
- /** Per-item scoring breakdown. */
282
- details: ScoringDetail[];
283
- }
284
- /** A single validation error produced by `validateActivity`. */
285
- interface ValidationError {
286
- /** JSON-path-style location of the invalid field. */
287
- path: string[];
288
- /** Human-readable description of the validation failure. */
289
- message: string;
290
- /** Machine-readable error code. */
291
- code: string;
292
- }
293
- /**
294
- * Result of a `validateActivity` call.
295
- * On success, `data` is the validated and typed activity data.
296
- * On failure, `errors` contains one entry per violated constraint.
297
- */
298
- type ValidationResult<T> = {
299
- success: true;
300
- data: T;
301
- } | {
302
- success: false;
303
- errors: ValidationError[];
304
- };
305
- /** The payload delivered to an activity's `onComplete` callback. */
306
- interface ActivityResult {
307
- /** Scaled score in the range [0, 1]. */
308
- score: number;
309
- /** Maximum possible scaled score (always 1). */
310
- maxScore: number;
311
- /** Whether the learner passed based on the activity's pass threshold. */
312
- passed: boolean;
313
- /** Time in milliseconds from first interaction to submission. */
314
- timeSpent: number;
315
- /** The xAPI statement built and (optionally) sent for this attempt. */
316
- xapiStatement: XAPIStatement;
317
- }
318
- /** Fired by activity components on every discrete learner interaction. */
319
- interface InteractionEvent {
320
- /** The kind of interaction that occurred. */
321
- type: 'option-selected' | 'option-deselected' | 'blank-filled' | 'hint-requested' | 'submitted';
322
- /** ID of the activity that produced the event. */
323
- activityId: string;
324
- /** Unix timestamp (ms) of when the interaction occurred. */
325
- timestamp: number;
326
- /** Additional event-specific data. */
327
- payload: Record<string, unknown>;
328
- }
329
-
330
- export type { ActivityData as A, BlankConfig as B, FillInTheBlanksData as F, InteractionEvent as I, LearnerResponse as L, MultipleChoiceData as M, ScoringDetail as S, ValidationError as V, XAPIActor as X, ActivityDataMap as a, ActivityFeedback as b, ActivityMedia as c, ActivityResult as d, ActivityType as e, FillInTheBlanksLearnerResponse as f, MultipleChoiceLearnerResponse as g, MultipleChoiceOption as h, ScoringResult as i, ValidationResult as j, XAPIConfig as k, XAPIContext as l, XAPIError as m, XAPIObject as n, XAPIResult as o, XAPIScore as p, XAPIStatement as q, XAPIVerbObject as r };
@@ -1,147 +0,0 @@
1
- // src/schemas/fill-in-the-blanks.ts
2
- import { z as z3 } from "zod/v4";
3
-
4
- // src/schemas/feedback.ts
5
- import { z } from "zod/v4";
6
- var FeedbackSchema = z.object({
7
- correct: z.string().min(1).optional(),
8
- incorrect: z.string().min(1).optional()
9
- });
10
-
11
- // src/schemas/media.ts
12
- import { z as z2 } from "zod/v4";
13
- var MediaSchema = z2.object({
14
- type: z2.enum(["image", "audio", "video", "embed"]),
15
- url: z2.url(),
16
- alt: z2.string().min(1).optional(),
17
- captionsUrl: z2.url().optional()
18
- }).refine(
19
- (m) => m.type !== "image" && m.type !== "embed" || typeof m.alt === "string" && m.alt.length > 0,
20
- {
21
- error: "image and embed media require non-empty alt text (WCAG 1.1.1 / 4.1.2).",
22
- path: ["alt"]
23
- }
24
- );
25
-
26
- // src/schemas/fill-in-the-blanks.ts
27
- var PLACEHOLDER_RE = /\{\{\s*([^{}]+?)\s*\}\}/g;
28
- var BlankConfigSchema = z3.object({
29
- id: z3.string().min(1),
30
- acceptedAnswers: z3.array(z3.string().min(1)).min(1),
31
- caseSensitive: z3.boolean().optional(),
32
- trimWhitespace: z3.boolean().optional(),
33
- hint: z3.string().optional(),
34
- feedback: z3.string().optional()
35
- });
36
- var FillInTheBlanksDataSchema = z3.object({
37
- schemaVersion: z3.literal("1.0"),
38
- type: z3.literal("fill-in-the-blanks"),
39
- id: z3.string().min(1),
40
- title: z3.string().min(1),
41
- passage: z3.string().min(1),
42
- blanks: z3.array(BlankConfigSchema).min(1),
43
- scoringStrategy: z3.enum(["all-or-nothing", "partial"]),
44
- media: MediaSchema.optional(),
45
- feedback: FeedbackSchema.optional(),
46
- passThreshold: z3.number().min(0).max(1).optional(),
47
- locale: z3.string().optional(),
48
- learningObjectives: z3.array(z3.string()).optional(),
49
- difficultyLevel: z3.literal([1, 2, 3, 4, 5]).optional()
50
- }).refine(
51
- (data) => {
52
- const placeholderIds = new Set(
53
- [...data.passage.matchAll(PLACEHOLDER_RE)].map((match) => match[1])
54
- );
55
- const blankIds = new Set(data.blanks.map((blank) => blank.id));
56
- if (placeholderIds.size !== blankIds.size) {
57
- return false;
58
- }
59
- for (const id of blankIds) {
60
- if (!placeholderIds.has(id)) {
61
- return false;
62
- }
63
- }
64
- return true;
65
- },
66
- {
67
- error: "Each blank id must have exactly one matching {{id}} placeholder in the passage, and vice versa.",
68
- path: ["passage"]
69
- }
70
- );
71
-
72
- // src/schemas/multiple-choice.ts
73
- import { z as z4 } from "zod/v4";
74
- var MultipleChoiceOptionSchema = z4.object({
75
- id: z4.string().min(1),
76
- text: z4.string().min(1),
77
- isCorrect: z4.boolean(),
78
- feedback: z4.string().optional()
79
- });
80
- var MultipleChoiceDataSchema = z4.object({
81
- schemaVersion: z4.literal("1.0"),
82
- type: z4.literal("multiple-choice"),
83
- id: z4.string().min(1),
84
- title: z4.string().min(1),
85
- question: z4.string().min(1),
86
- mode: z4.enum(["single", "multi"]),
87
- options: z4.array(MultipleChoiceOptionSchema).min(2).max(10),
88
- scoringStrategy: z4.enum(["all-or-nothing", "partial"]),
89
- media: MediaSchema.optional(),
90
- feedback: FeedbackSchema.optional(),
91
- passThreshold: z4.number().min(0).max(1).optional(),
92
- shuffle: z4.boolean().optional(),
93
- locale: z4.string().optional(),
94
- learningObjectives: z4.array(z4.string()).optional(),
95
- difficultyLevel: z4.literal([1, 2, 3, 4, 5]).optional()
96
- }).refine((data) => data.options.some((option) => option.isCorrect), {
97
- error: "At least one option must be marked correct.",
98
- path: ["options"]
99
- }).refine(
100
- (data) => data.mode !== "single" || data.options.filter((option) => option.isCorrect).length === 1,
101
- {
102
- error: 'Single-select activities (mode: "single") must have exactly one correct option.',
103
- path: ["options"]
104
- }
105
- );
106
-
107
- // src/schemas/json-schema.ts
108
- import { z as z5 } from "zod/v4";
109
- var multipleChoiceJsonSchema = z5.toJSONSchema(MultipleChoiceDataSchema, {
110
- target: "draft-7"
111
- });
112
- var fillInTheBlanksJsonSchema = z5.toJSONSchema(FillInTheBlanksDataSchema, {
113
- target: "draft-7"
114
- });
115
-
116
- // src/schemas/index.ts
117
- var schemaMap = {
118
- "multiple-choice": MultipleChoiceDataSchema,
119
- "fill-in-the-blanks": FillInTheBlanksDataSchema
120
- };
121
- function validateActivity(type, data) {
122
- const result = schemaMap[type].safeParse(data);
123
- if (result.success) {
124
- return { success: true, data: result.data };
125
- }
126
- return {
127
- success: false,
128
- errors: result.error.issues.map((issue) => ({
129
- path: issue.path.map(String),
130
- message: issue.message,
131
- code: issue.code
132
- }))
133
- };
134
- }
135
-
136
- export {
137
- FeedbackSchema,
138
- MediaSchema,
139
- BlankConfigSchema,
140
- FillInTheBlanksDataSchema,
141
- MultipleChoiceOptionSchema,
142
- MultipleChoiceDataSchema,
143
- multipleChoiceJsonSchema,
144
- fillInTheBlanksJsonSchema,
145
- validateActivity
146
- };
147
- //# sourceMappingURL=chunk-2T3IL7VL.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/schemas/fill-in-the-blanks.ts","../src/schemas/feedback.ts","../src/schemas/media.ts","../src/schemas/multiple-choice.ts","../src/schemas/json-schema.ts","../src/schemas/index.ts"],"sourcesContent":["import { z } from 'zod/v4';\nimport { FeedbackSchema } from './feedback.js';\nimport { MediaSchema } from './media.js';\n\n/** Matches `{{ blank_id }}` placeholders in a passage, capturing the trimmed id. */\nconst PLACEHOLDER_RE = /\\{\\{\\s*([^{}]+?)\\s*\\}\\}/g;\n\n/** Zod schema for a single fill-in-the-blank slot configuration. */\nexport const BlankConfigSchema = z.object({\n id: z.string().min(1),\n acceptedAnswers: z.array(z.string().min(1)).min(1),\n caseSensitive: z.boolean().optional(),\n trimWhitespace: z.boolean().optional(),\n hint: z.string().optional(),\n feedback: z.string().optional(),\n});\n\n/**\n * Zod schema validating the full Fill-in-the-Blanks activity data contract.\n *\n * The refinement enforces a bijection between `{{id}}` placeholders in the\n * passage and `blanks[].id`; otherwise a blank could never be rendered, or a\n * placeholder could have no scoring config, yielding undefined behaviour.\n */\nexport const FillInTheBlanksDataSchema = z\n .object({\n schemaVersion: z.literal('1.0'),\n type: z.literal('fill-in-the-blanks'),\n id: z.string().min(1),\n title: z.string().min(1),\n passage: z.string().min(1),\n blanks: z.array(BlankConfigSchema).min(1),\n scoringStrategy: z.enum(['all-or-nothing', 'partial']),\n media: MediaSchema.optional(),\n feedback: FeedbackSchema.optional(),\n passThreshold: z.number().min(0).max(1).optional(),\n locale: z.string().optional(),\n learningObjectives: z.array(z.string()).optional(),\n difficultyLevel: z.literal([1, 2, 3, 4, 5]).optional(),\n })\n .refine(\n (data) => {\n const placeholderIds = new Set(\n [...data.passage.matchAll(PLACEHOLDER_RE)].map((match) => match[1]),\n );\n const blankIds = new Set(data.blanks.map((blank) => blank.id));\n if (placeholderIds.size !== blankIds.size) {\n return false;\n }\n for (const id of blankIds) {\n if (!placeholderIds.has(id)) {\n return false;\n }\n }\n return true;\n },\n {\n error:\n 'Each blank id must have exactly one matching {{id}} placeholder in the passage, and vice versa.',\n path: ['passage'],\n },\n );\n","import { z } from 'zod/v4';\n\n/**\n * Optional authored \"overall feedback\" shown after submission, selected by\n * whether the learner passed (h5p-style overall feedback). Both fields are\n * optional; non-empty when present.\n */\nexport const FeedbackSchema = z.object({\n correct: z.string().min(1).optional(),\n incorrect: z.string().min(1).optional(),\n});\n","import { z } from 'zod/v4';\n\n/**\n * Optional media attached to an activity, rendered above the question or\n * passage — e.g. a recording to listen to, or an embedded video to watch\n * before answering. URL-only by design: hosting/delivery (S3/CDN, or the\n * provider's own embed for `embed`) is the consuming app's responsibility\n * (see requirements \"Non-Goals and Shared Responsibility\").\n *\n * - `image`: rendered as `<img>` — `alt` is REQUIRED (WCAG 1.1.1 / Req 14.5).\n * - `audio` / `video`: rendered with native controls; `alt` is an optional\n * accessible label; `captionsUrl` points at a WebVTT `<track>`. `url` must\n * be a direct media file (NOT a YouTube/Vimeo page — use `embed` for those).\n * - `embed`: rendered as a sandboxed `<iframe>` for provider players\n * (YouTube/Vimeo/etc.). `url` MUST be the provider's *embeddable* URL\n * (e.g. `https://www.youtube.com/embed/<id>`). `alt` is REQUIRED and used\n * as the iframe's accessible `title` (WCAG 4.1.2 / 2.4.1).\n */\nexport const MediaSchema = z\n .object({\n type: z.enum(['image', 'audio', 'video', 'embed']),\n url: z.url(),\n alt: z.string().min(1).optional(),\n captionsUrl: z.url().optional(),\n })\n .refine(\n (m) =>\n (m.type !== 'image' && m.type !== 'embed') || (typeof m.alt === 'string' && m.alt.length > 0),\n {\n error: 'image and embed media require non-empty alt text (WCAG 1.1.1 / 4.1.2).',\n path: ['alt'],\n },\n );\n","import { z } from 'zod/v4';\nimport { FeedbackSchema } from './feedback.js';\nimport { MediaSchema } from './media.js';\n\n/** Zod schema for a single Multiple Choice option. */\nexport const MultipleChoiceOptionSchema = z.object({\n id: z.string().min(1),\n text: z.string().min(1),\n isCorrect: z.boolean(),\n feedback: z.string().optional(),\n});\n\n/**\n * Zod schema validating the full Multiple Choice activity data contract.\n *\n * Two semantic guards: (1) at least one option must be correct, otherwise the\n * activity can never be answered correctly; (2) `mode: 'single'` must have\n * exactly one correct option — multiple correct options under single-select\n * make `showCorrectAnswers` and the xAPI correct-response ambiguous and mask\n * authoring errors. Both are unrepresentable in JSON Schema and are dropped\n * from `toJSONSchema` output by design.\n */\nexport const MultipleChoiceDataSchema = z\n .object({\n schemaVersion: z.literal('1.0'),\n type: z.literal('multiple-choice'),\n id: z.string().min(1),\n title: z.string().min(1),\n question: z.string().min(1),\n mode: z.enum(['single', 'multi']),\n options: z.array(MultipleChoiceOptionSchema).min(2).max(10),\n scoringStrategy: z.enum(['all-or-nothing', 'partial']),\n media: MediaSchema.optional(),\n feedback: FeedbackSchema.optional(),\n passThreshold: z.number().min(0).max(1).optional(),\n shuffle: z.boolean().optional(),\n locale: z.string().optional(),\n learningObjectives: z.array(z.string()).optional(),\n difficultyLevel: z.literal([1, 2, 3, 4, 5]).optional(),\n })\n .refine((data) => data.options.some((option) => option.isCorrect), {\n error: 'At least one option must be marked correct.',\n path: ['options'],\n })\n .refine(\n (data) =>\n data.mode !== 'single' || data.options.filter((option) => option.isCorrect).length === 1,\n {\n error: 'Single-select activities (mode: \"single\") must have exactly one correct option.',\n path: ['options'],\n },\n );\n","import { z } from 'zod/v4';\nimport { FillInTheBlanksDataSchema } from './fill-in-the-blanks.js';\nimport { MultipleChoiceDataSchema } from './multiple-choice.js';\n\n/**\n * JSON Schema (Draft 7) representation of the Multiple Choice activity data\n * contract, generated natively by Zod 4. Draft 7 is mandated by Requirement\n * 2.2 for the widest AI-prompt / OpenAPI tooling compatibility. The semantic\n * `.refine()` guards are not representable in JSON Schema and are\n * intentionally omitted — the export captures the *structural* contract only.\n */\nexport const multipleChoiceJsonSchema = z.toJSONSchema(MultipleChoiceDataSchema, {\n target: 'draft-7',\n});\n\n/**\n * JSON Schema (Draft 7) representation of the Fill-in-the-Blanks activity data\n * contract, generated natively by Zod 4. Structural contract only (semantic\n * `.refine()` guards are Zod-only and not representable in JSON Schema).\n */\nexport const fillInTheBlanksJsonSchema = z.toJSONSchema(FillInTheBlanksDataSchema, {\n target: 'draft-7',\n});\n","import type { ActivityDataMap, ActivityType, ValidationResult } from '../types/activity.js';\nimport { FillInTheBlanksDataSchema } from './fill-in-the-blanks.js';\nimport { MultipleChoiceDataSchema } from './multiple-choice.js';\n\nexport { FeedbackSchema } from './feedback.js';\nexport { BlankConfigSchema, FillInTheBlanksDataSchema } from './fill-in-the-blanks.js';\nexport { fillInTheBlanksJsonSchema, multipleChoiceJsonSchema } from './json-schema.js';\nexport { MediaSchema } from './media.js';\nexport { MultipleChoiceDataSchema, MultipleChoiceOptionSchema } from './multiple-choice.js';\n\n/** Maps each activity type to the Zod schema that validates its data. */\nconst schemaMap = {\n 'multiple-choice': MultipleChoiceDataSchema,\n 'fill-in-the-blanks': FillInTheBlanksDataSchema,\n} as const;\n\n/**\n * Validates raw activity data against the schema for the given activity type.\n *\n * @returns `{ success: true, data }` with the typed, validated data, or\n * `{ success: false, errors }` with one entry per failed constraint.\n */\nexport function validateActivity<T extends ActivityType>(\n type: T,\n data: unknown,\n): ValidationResult<ActivityDataMap[T]> {\n const result = schemaMap[type].safeParse(data);\n\n if (result.success) {\n return { success: true, data: result.data as ActivityDataMap[T] };\n }\n\n return {\n success: false,\n errors: result.error.issues.map((issue) => ({\n path: issue.path.map(String),\n message: issue.message,\n code: issue.code,\n })),\n };\n}\n"],"mappings":";AAAA,SAAS,KAAAA,UAAS;;;ACAlB,SAAS,SAAS;AAOX,IAAM,iBAAiB,EAAE,OAAO;AAAA,EACrC,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA,EACpC,WAAW,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS;AACxC,CAAC;;;ACVD,SAAS,KAAAC,UAAS;AAkBX,IAAM,cAAcA,GACxB,OAAO;AAAA,EACN,MAAMA,GAAE,KAAK,CAAC,SAAS,SAAS,SAAS,OAAO,CAAC;AAAA,EACjD,KAAKA,GAAE,IAAI;AAAA,EACX,KAAKA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA,EAChC,aAAaA,GAAE,IAAI,EAAE,SAAS;AAChC,CAAC,EACA;AAAA,EACC,CAAC,MACE,EAAE,SAAS,WAAW,EAAE,SAAS,WAAa,OAAO,EAAE,QAAQ,YAAY,EAAE,IAAI,SAAS;AAAA,EAC7F;AAAA,IACE,OAAO;AAAA,IACP,MAAM,CAAC,KAAK;AAAA,EACd;AACF;;;AF3BF,IAAM,iBAAiB;AAGhB,IAAM,oBAAoBC,GAAE,OAAO;AAAA,EACxC,IAAIA,GAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACpB,iBAAiBA,GAAE,MAAMA,GAAE,OAAO,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC;AAAA,EACjD,eAAeA,GAAE,QAAQ,EAAE,SAAS;AAAA,EACpC,gBAAgBA,GAAE,QAAQ,EAAE,SAAS;AAAA,EACrC,MAAMA,GAAE,OAAO,EAAE,SAAS;AAAA,EAC1B,UAAUA,GAAE,OAAO,EAAE,SAAS;AAChC,CAAC;AASM,IAAM,4BAA4BA,GACtC,OAAO;AAAA,EACN,eAAeA,GAAE,QAAQ,KAAK;AAAA,EAC9B,MAAMA,GAAE,QAAQ,oBAAoB;AAAA,EACpC,IAAIA,GAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACpB,OAAOA,GAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACvB,SAASA,GAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACzB,QAAQA,GAAE,MAAM,iBAAiB,EAAE,IAAI,CAAC;AAAA,EACxC,iBAAiBA,GAAE,KAAK,CAAC,kBAAkB,SAAS,CAAC;AAAA,EACrD,OAAO,YAAY,SAAS;AAAA,EAC5B,UAAU,eAAe,SAAS;AAAA,EAClC,eAAeA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA,EACjD,QAAQA,GAAE,OAAO,EAAE,SAAS;AAAA,EAC5B,oBAAoBA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EACjD,iBAAiBA,GAAE,QAAQ,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC,EAAE,SAAS;AACvD,CAAC,EACA;AAAA,EACC,CAAC,SAAS;AACR,UAAM,iBAAiB,IAAI;AAAA,MACzB,CAAC,GAAG,KAAK,QAAQ,SAAS,cAAc,CAAC,EAAE,IAAI,CAAC,UAAU,MAAM,CAAC,CAAC;AAAA,IACpE;AACA,UAAM,WAAW,IAAI,IAAI,KAAK,OAAO,IAAI,CAAC,UAAU,MAAM,EAAE,CAAC;AAC7D,QAAI,eAAe,SAAS,SAAS,MAAM;AACzC,aAAO;AAAA,IACT;AACA,eAAW,MAAM,UAAU;AACzB,UAAI,CAAC,eAAe,IAAI,EAAE,GAAG;AAC3B,eAAO;AAAA,MACT;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,OACE;AAAA,IACF,MAAM,CAAC,SAAS;AAAA,EAClB;AACF;;;AG7DF,SAAS,KAAAC,UAAS;AAKX,IAAM,6BAA6BC,GAAE,OAAO;AAAA,EACjD,IAAIA,GAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACpB,MAAMA,GAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACtB,WAAWA,GAAE,QAAQ;AAAA,EACrB,UAAUA,GAAE,OAAO,EAAE,SAAS;AAChC,CAAC;AAYM,IAAM,2BAA2BA,GACrC,OAAO;AAAA,EACN,eAAeA,GAAE,QAAQ,KAAK;AAAA,EAC9B,MAAMA,GAAE,QAAQ,iBAAiB;AAAA,EACjC,IAAIA,GAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACpB,OAAOA,GAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACvB,UAAUA,GAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC1B,MAAMA,GAAE,KAAK,CAAC,UAAU,OAAO,CAAC;AAAA,EAChC,SAASA,GAAE,MAAM,0BAA0B,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE;AAAA,EAC1D,iBAAiBA,GAAE,KAAK,CAAC,kBAAkB,SAAS,CAAC;AAAA,EACrD,OAAO,YAAY,SAAS;AAAA,EAC5B,UAAU,eAAe,SAAS;AAAA,EAClC,eAAeA,GAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA,EACjD,SAASA,GAAE,QAAQ,EAAE,SAAS;AAAA,EAC9B,QAAQA,GAAE,OAAO,EAAE,SAAS;AAAA,EAC5B,oBAAoBA,GAAE,MAAMA,GAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EACjD,iBAAiBA,GAAE,QAAQ,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC,EAAE,SAAS;AACvD,CAAC,EACA,OAAO,CAAC,SAAS,KAAK,QAAQ,KAAK,CAAC,WAAW,OAAO,SAAS,GAAG;AAAA,EACjE,OAAO;AAAA,EACP,MAAM,CAAC,SAAS;AAClB,CAAC,EACA;AAAA,EACC,CAAC,SACC,KAAK,SAAS,YAAY,KAAK,QAAQ,OAAO,CAAC,WAAW,OAAO,SAAS,EAAE,WAAW;AAAA,EACzF;AAAA,IACE,OAAO;AAAA,IACP,MAAM,CAAC,SAAS;AAAA,EAClB;AACF;;;ACnDF,SAAS,KAAAC,UAAS;AAWX,IAAM,2BAA2BC,GAAE,aAAa,0BAA0B;AAAA,EAC/E,QAAQ;AACV,CAAC;AAOM,IAAM,4BAA4BA,GAAE,aAAa,2BAA2B;AAAA,EACjF,QAAQ;AACV,CAAC;;;ACXD,IAAM,YAAY;AAAA,EAChB,mBAAmB;AAAA,EACnB,sBAAsB;AACxB;AAQO,SAAS,iBACd,MACA,MACsC;AACtC,QAAM,SAAS,UAAU,IAAI,EAAE,UAAU,IAAI;AAE7C,MAAI,OAAO,SAAS;AAClB,WAAO,EAAE,SAAS,MAAM,MAAM,OAAO,KAA2B;AAAA,EAClE;AAEA,SAAO;AAAA,IACL,SAAS;AAAA,IACT,QAAQ,OAAO,MAAM,OAAO,IAAI,CAAC,WAAW;AAAA,MAC1C,MAAM,MAAM,KAAK,IAAI,MAAM;AAAA,MAC3B,SAAS,MAAM;AAAA,MACf,MAAM,MAAM;AAAA,IACd,EAAE;AAAA,EACJ;AACF;","names":["z","z","z","z","z","z","z"]}
@@ -1,124 +0,0 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
2
-
3
- var _chunkDV466SBJcjs = require('./chunk-DV466SBJ.cjs');
4
-
5
- // src/scoring/strategies/all-or-nothing.ts
6
- function allOrNothingStrategy(correctItems) {
7
- return correctItems.every((isCorrect) => isCorrect) ? 1 : 0;
8
- }
9
-
10
- // src/scoring/strategies/partial.ts
11
- function partialStrategy(correctSelected, incorrectSelected, totalCorrect, totalIncorrect) {
12
- const reward = correctSelected / totalCorrect;
13
- const penalty = totalIncorrect === 0 ? 0 : incorrectSelected / totalIncorrect;
14
- return Math.max(0, reward - penalty);
15
- }
16
- function partialBlankStrategy(correctBlanks, totalBlanks) {
17
- return correctBlanks / totalBlanks;
18
- }
19
-
20
- // src/scoring/activity-scorers/fill-in-the-blanks.ts
21
- function normalize(value, blank) {
22
- let result = value;
23
- if (blank.trimWhitespace !== false) {
24
- result = result.trim();
25
- }
26
- if (blank.caseSensitive !== true) {
27
- result = result.toLowerCase();
28
- }
29
- return result;
30
- }
31
- function scoreFillInTheBlanks(data, response) {
32
- const details = [];
33
- const perBlankCorrect = [];
34
- for (const blank of data.blanks) {
35
- const rawInput = response.answers[blank.id];
36
- const input = typeof rawInput === "string" ? rawInput : "";
37
- const normalizedInput = normalize(input, blank);
38
- const matched = blank.acceptedAnswers.some(
39
- (accepted) => normalize(accepted, blank) === normalizedInput
40
- );
41
- perBlankCorrect.push(matched);
42
- details.push({
43
- itemId: blank.id,
44
- correct: matched,
45
- learnerResponse: [input],
46
- correctResponse: [...blank.acceptedAnswers]
47
- });
48
- }
49
- const correctBlanks = perBlankCorrect.filter(Boolean).length;
50
- const scoreValue = data.scoringStrategy === "all-or-nothing" ? allOrNothingStrategy(perBlankCorrect) : partialBlankStrategy(correctBlanks, data.blanks.length);
51
- return { score: scoreValue, maxScore: 1, feedback: null, details };
52
- }
53
-
54
- // src/scoring/activity-scorers/multiple-choice.ts
55
- function scoreMultipleChoice(data, response) {
56
- const optionById = new Map(data.options.map((option) => [option.id, option]));
57
- const selected = new Set(response.selectedOptionIds);
58
- const totalCorrect = data.options.filter((option) => option.isCorrect).length;
59
- const totalIncorrect = data.options.length - totalCorrect;
60
- let scoreValue;
61
- if (data.scoringStrategy === "all-or-nothing") {
62
- if (data.mode === "single") {
63
- scoreValue = response.selectedOptionIds.length === 1 && _optionalChain([optionById, 'access', _ => _.get, 'call', _2 => _2(response.selectedOptionIds[0]), 'optionalAccess', _3 => _3.isCorrect]) === true ? 1 : 0;
64
- } else {
65
- const correctIds = data.options.filter((o) => o.isCorrect).map((o) => o.id);
66
- const allCorrectSelected = correctIds.every((id) => selected.has(id));
67
- scoreValue = selected.size === correctIds.length && allCorrectSelected ? 1 : 0;
68
- }
69
- } else {
70
- let correctSelected = 0;
71
- let incorrectSelected = 0;
72
- for (const id of selected) {
73
- const option = optionById.get(id);
74
- if (_optionalChain([option, 'optionalAccess', _4 => _4.isCorrect])) {
75
- correctSelected += 1;
76
- } else {
77
- incorrectSelected += 1;
78
- }
79
- }
80
- scoreValue = partialStrategy(correctSelected, incorrectSelected, totalCorrect, totalIncorrect);
81
- }
82
- const details = data.options.map((option) => {
83
- const wasSelected = selected.has(option.id);
84
- return {
85
- itemId: option.id,
86
- correct: wasSelected === option.isCorrect,
87
- learnerResponse: [wasSelected ? "selected" : "not-selected"],
88
- correctResponse: [option.isCorrect ? "selected" : "not-selected"]
89
- };
90
- });
91
- return { score: scoreValue, maxScore: 1, feedback: null, details };
92
- }
93
-
94
- // src/scoring/index.ts
95
- var DEFAULT_PASS_THRESHOLD = 0.7;
96
- function computePassThreshold(activityData, score2) {
97
- return score2 >= (_nullishCoalesce(activityData.passThreshold, () => ( DEFAULT_PASS_THRESHOLD)));
98
- }
99
- function score(activityType, activityData, learnerResponse) {
100
- let result;
101
- switch (activityType) {
102
- case "multiple-choice":
103
- result = scoreMultipleChoice(
104
- activityData,
105
- learnerResponse
106
- );
107
- break;
108
- case "fill-in-the-blanks":
109
- result = scoreFillInTheBlanks(
110
- activityData,
111
- learnerResponse
112
- );
113
- break;
114
- default:
115
- throw new (0, _chunkDV466SBJcjs.UnknownActivityTypeError)(String(activityType));
116
- }
117
- return { ...result, passed: computePassThreshold(activityData, result.score) };
118
- }
119
-
120
-
121
-
122
-
123
- exports.computePassThreshold = computePassThreshold; exports.score = score;
124
- //# sourceMappingURL=chunk-3JMLUUFS.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["c:\\Users\\onecu\\Documents\\Intellectif\\IT-for-Intellectif\\learning-kit\\packages\\lk-core\\dist\\chunk-3JMLUUFS.cjs"],"names":[],"mappings":"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","file":"C:\\Users\\onecu\\Documents\\Intellectif\\IT-for-Intellectif\\learning-kit\\packages\\lk-core\\dist\\chunk-3JMLUUFS.cjs","sourcesContent":[null]}
@@ -1,25 +0,0 @@
1
- // src/errors.ts
2
- var ActivitySchemaError = class extends Error {
3
- constructor(activityType, errors) {
4
- super(`Invalid activity data for type "${activityType}"`);
5
- this.activityType = activityType;
6
- this.errors = errors;
7
- this.name = "ActivitySchemaError";
8
- }
9
- activityType;
10
- errors;
11
- };
12
- var UnknownActivityTypeError = class extends Error {
13
- constructor(activityType) {
14
- super(`Activity type "${activityType}" is not registered`);
15
- this.activityType = activityType;
16
- this.name = "UnknownActivityTypeError";
17
- }
18
- activityType;
19
- };
20
-
21
- export {
22
- ActivitySchemaError,
23
- UnknownActivityTypeError
24
- };
25
- //# sourceMappingURL=chunk-6VOCV4EX.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/errors.ts"],"sourcesContent":["import type { ValidationError } from './types/activity.js';\n\n/** Thrown when activity data fails schema validation at a component boundary. */\nexport class ActivitySchemaError extends Error {\n constructor(\n public readonly activityType: string,\n public readonly errors: ValidationError[],\n ) {\n super(`Invalid activity data for type \"${activityType}\"`);\n this.name = 'ActivitySchemaError';\n }\n}\n\n/** Thrown when an unrecognised activity type is passed to the scoring engine. */\nexport class UnknownActivityTypeError extends Error {\n constructor(public readonly activityType: string) {\n super(`Activity type \"${activityType}\" is not registered`);\n this.name = 'UnknownActivityTypeError';\n }\n}\n"],"mappings":";AAGO,IAAM,sBAAN,cAAkC,MAAM;AAAA,EAC7C,YACkB,cACA,QAChB;AACA,UAAM,mCAAmC,YAAY,GAAG;AAHxC;AACA;AAGhB,SAAK,OAAO;AAAA,EACd;AAAA,EALkB;AAAA,EACA;AAKpB;AAGO,IAAM,2BAAN,cAAuC,MAAM;AAAA,EAClD,YAA4B,cAAsB;AAChD,UAAM,kBAAkB,YAAY,qBAAqB;AAD/B;AAE1B,SAAK,OAAO;AAAA,EACd;AAAA,EAH4B;AAI9B;","names":[]}