@conform-ed/contracts 0.0.13 → 0.0.15
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/.turbo/turbo-format.log +1 -1
- package/.turbo/turbo-lint.log +1 -1
- package/.turbo/turbo-test.log +182 -182
- package/package.json +4 -4
- package/src/adapter.ts +1 -1
- package/src/caliper/v1_2/caliper_v1p2_bootcamp_schema.ts +6 -6
- package/src/caliper/v1_2/shared.ts +2 -2
- package/src/case/v1_1/case_v1p1_openapi3_restbinding_schema.ts +1 -0
- package/src/case/v1_1/index.ts +41 -41
- package/src/cat/v1_0/index.ts +39 -39
- package/src/cat/v1_0/shared.ts +1 -1
- package/src/clr/v2_0/shared.ts +19 -17
- package/src/cmi5/v1_0/index.ts +19 -19
- package/src/common-cartridge/v1_3/ccv1p3_imscp_v1p2_v1p0.ts +3 -3
- package/src/common-cartridge/v1_3/ccv1p3_lomccltilink_v1p0.ts +2 -1
- package/src/common-cartridge/v1_3/ccv1p3_lommanifest_v1p0.ts +2 -1
- package/src/common-cartridge/v1_3/ccv1p3_lomresource_v1p0.ts +2 -1
- package/src/common-cartridge/v1_3/ccv1p3_qtiasiv1p2p1_v1p0.ts +16 -13
- package/src/common-cartridge/v1_3/index.ts +3 -3
- package/src/common-cartridge/v1_3/lom-internal.ts +19 -19
- package/src/common-cartridge/v1_3/shared.ts +1 -1
- package/src/common-cartridge/v1_4/core/ccv1p4_imscp_v1p2_v1p0.ts +6 -6
- package/src/common-cartridge/v1_4/core/ccv1p4_lommanifest_v1p0.ts +2 -1
- package/src/common-cartridge/v1_4/core/ccv1p4_lomresource_v1p0.ts +2 -1
- package/src/common-cartridge/v1_4/extension/ccv1p4_cpextensionv1p2_v1p0.ts +1 -0
- package/src/common-cartridge/v1_4/index.ts +5 -5
- package/src/common-cartridge/v1_4/k12/ccv1p4_lommanifest_v1p0.ts +2 -1
- package/src/common-cartridge/v1_4/k12/ccv1p4_lomresource_v1p0.ts +2 -1
- package/src/common-cartridge/v1_4/lom-internal.ts +30 -27
- package/src/common-cartridge/v1_4/shared/ccv1p4_lomccltilink_v1p0.ts +2 -1
- package/src/common-cartridge/v1_4/shared/ccv1p4_qtiasiv1p2p1_v1p0.ts +16 -13
- package/src/common-cartridge/v1_4/shared.ts +1 -1
- package/src/common-cartridge/v1_4/thin/ccv1p4_imscp_v1p2_v1p0.ts +5 -5
- package/src/common-cartridge/v1_4/thin/ccv1p4_lommanifest_v1p0.ts +2 -1
- package/src/common-cartridge/v1_4/thin/ccv1p4_lomresource_v1p0.ts +2 -1
- package/src/common-cartridge/v1_4/vdex/imsmd_loose_v1p3p2.ts +2 -1
- package/src/common-cartridge/v1_4/vdex/imsvdex_v1p0.ts +1 -1
- package/src/config.ts +3 -3
- package/src/h5p/v1/content.ts +1 -0
- package/src/h5p/v1/h5p-json.ts +4 -3
- package/src/h5p/v1/index.ts +21 -21
- package/src/h5p/v1/library-json.ts +2 -1
- package/src/lti/ags/v2_0/index.ts +12 -12
- package/src/lti/deep-linking/v2_0/index.ts +10 -10
- package/src/lti/index.ts +2 -2
- package/src/lti/nrps/v2_0/index.ts +10 -10
- package/src/lti/proctoring/v1_0/index.ts +11 -11
- package/src/lti/v1_3/index.ts +17 -17
- package/src/oneroster/v1_2/index.ts +45 -45
- package/src/oneroster/v1_2/or_v1p2_gradebook_restbinding_schema.ts +3 -3
- package/src/oneroster/v1_2/or_v1p2_resource_restbinding_schema.ts +1 -1
- package/src/oneroster/v1_2/or_v1p2_rostering_restbinding_schema.ts +1 -1
- package/src/oneroster/v1_2/or_v1p2_rostering_service_schema.ts +1 -1
- package/src/open-badges/v3_0/shared.ts +31 -29
- package/src/qti/v2-internal.ts +12 -11
- package/src/qti/v3_0_1/assessment-internal.ts +198 -178
- package/src/qti/v3_0_1/imsqti_asiv3p0p1_v1p0.ts +4 -4
- package/src/qti/v3_0_1/imsqti_itemv3p0p1_v1p0.ts +1 -1
- package/src/qti/v3_0_1/imsqti_metadatav3p0_v1p0.ts +1 -1
- package/src/qti/v3_0_1/imsqti_responseprocessingv3p0p1_v1p0.ts +1 -1
- package/src/qti/v3_0_1/imsqti_resultv3p0_v1p0.ts +4 -3
- package/src/qti/v3_0_1/imsqti_sectionv3p0p1_v1p0.ts +1 -1
- package/src/qti/v3_0_1/imsqti_stimulusv3p0p1_v1p0.ts +1 -1
- package/src/qti/v3_0_1/imsqti_testv3p0p1_v1p0.ts +2 -2
- package/src/qti/v3_0_1/imsqti_usagedatav3p0_v1p0.ts +1 -1
- package/src/qti/v3_0_1/processing-internal.ts +33 -33
- package/src/qti/v3_0_1/shared.ts +2 -2
- package/src/vc-data-model/v2_0/shared.ts +4 -4
- package/src/xapi/shared.ts +11 -14
- package/src/xapi/v1_0_3/index.ts +54 -54
- package/src/xapi/v2_0/index.ts +56 -56
- package/test/caliper-v1_2.test.ts +1 -1
- package/test/cat-v1_0.test.ts +1 -0
- package/test/cmi5-v1_0.test.ts +33 -31
- package/test/contracts.test.ts +1 -0
- package/test/h5p-v1.test.ts +1 -0
- package/test/lti.test.ts +1 -0
- package/test/qti-v3_0_1.test.ts +1 -0
- package/test/schema-examples.test.ts +1 -0
- package/test/xapi.test.ts +1 -0
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
|
|
3
|
+
import {
|
|
4
|
+
QtiBranchRuleSchema,
|
|
5
|
+
QtiIncludeSchema,
|
|
6
|
+
QtiOutcomeProcessingSchema,
|
|
7
|
+
QtiPreConditionSchema,
|
|
8
|
+
QtiResponseProcessingSchema,
|
|
9
|
+
QtiTemplateDefaultSchema,
|
|
10
|
+
QtiTemplateProcessingSchema,
|
|
11
|
+
} from "./processing-internal";
|
|
3
12
|
import {
|
|
4
13
|
QtiDirectionSchema,
|
|
5
14
|
QtiIdentifierListSchema,
|
|
@@ -31,15 +40,6 @@ import {
|
|
|
31
40
|
QtiVariableMappingSchema,
|
|
32
41
|
QtiWeightSchema,
|
|
33
42
|
} from "./variables-internal";
|
|
34
|
-
import {
|
|
35
|
-
QtiBranchRuleSchema,
|
|
36
|
-
QtiIncludeSchema,
|
|
37
|
-
QtiOutcomeProcessingSchema,
|
|
38
|
-
QtiPreConditionSchema,
|
|
39
|
-
QtiResponseProcessingSchema,
|
|
40
|
-
QtiTemplateDefaultSchema,
|
|
41
|
-
QtiTemplateProcessingSchema,
|
|
42
|
-
} from "./processing-internal";
|
|
43
43
|
|
|
44
44
|
const QtiCommonNodeShape = {
|
|
45
45
|
id: QtiIdentifierSchema.optional(),
|
|
@@ -84,9 +84,9 @@ const interactionKinds = new Set<string>([
|
|
|
84
84
|
"endAttemptInteraction",
|
|
85
85
|
]);
|
|
86
86
|
|
|
87
|
-
export const QtiXmlContentNodeSchema: z.
|
|
87
|
+
export const QtiXmlContentNodeSchema: z.ZodType = z.lazy(() => createXmlNodeSchema(QtiContentFragmentSchema));
|
|
88
88
|
|
|
89
|
-
export const QtiPromptSchema: z.
|
|
89
|
+
export const QtiPromptSchema: z.ZodType = z.lazy(() =>
|
|
90
90
|
strictObject({
|
|
91
91
|
kind: z.literal("prompt"),
|
|
92
92
|
...QtiCommonNodeShape,
|
|
@@ -94,7 +94,7 @@ export const QtiPromptSchema: z.ZodTypeAny = z.lazy(() =>
|
|
|
94
94
|
}),
|
|
95
95
|
);
|
|
96
96
|
|
|
97
|
-
export const QtiLabelElementSchema: z.
|
|
97
|
+
export const QtiLabelElementSchema: z.ZodType = z.lazy(() =>
|
|
98
98
|
strictObject({
|
|
99
99
|
kind: z.literal("labelElement"),
|
|
100
100
|
...QtiCommonNodeShape,
|
|
@@ -133,14 +133,14 @@ export const QtiInteractionModulesSchema = strictObject({
|
|
|
133
133
|
modules: z.array(QtiInteractionModuleSchema).min(1),
|
|
134
134
|
});
|
|
135
135
|
|
|
136
|
-
export const QtiInteractionMarkupSchema: z.
|
|
136
|
+
export const QtiInteractionMarkupSchema: z.ZodType = z.lazy(() =>
|
|
137
137
|
strictObject({
|
|
138
138
|
kind: z.literal("interactionMarkup"),
|
|
139
139
|
content: z.array(QtiContentFragmentSchema).optional(),
|
|
140
140
|
}),
|
|
141
141
|
);
|
|
142
142
|
|
|
143
|
-
export const QtiFeedbackInlineSchema: z.
|
|
143
|
+
export const QtiFeedbackInlineSchema: z.ZodType = z.lazy(() =>
|
|
144
144
|
strictObject({
|
|
145
145
|
kind: z.literal("feedbackInline"),
|
|
146
146
|
...QtiCommonNodeShape,
|
|
@@ -151,7 +151,7 @@ export const QtiFeedbackInlineSchema: z.ZodTypeAny = z.lazy(() =>
|
|
|
151
151
|
}),
|
|
152
152
|
);
|
|
153
153
|
|
|
154
|
-
export const QtiFeedbackBlockSchema: z.
|
|
154
|
+
export const QtiFeedbackBlockSchema: z.ZodType = z.lazy(() =>
|
|
155
155
|
strictObject({
|
|
156
156
|
kind: z.literal("feedbackBlock"),
|
|
157
157
|
...QtiCommonNodeShape,
|
|
@@ -164,7 +164,7 @@ export const QtiFeedbackBlockSchema: z.ZodTypeAny = z.lazy(() =>
|
|
|
164
164
|
}),
|
|
165
165
|
);
|
|
166
166
|
|
|
167
|
-
export const QtiTemplateInlineSchema: z.
|
|
167
|
+
export const QtiTemplateInlineSchema: z.ZodType = z.lazy(() =>
|
|
168
168
|
strictObject({
|
|
169
169
|
kind: z.literal("templateInline"),
|
|
170
170
|
...QtiCommonNodeShape,
|
|
@@ -175,7 +175,7 @@ export const QtiTemplateInlineSchema: z.ZodTypeAny = z.lazy(() =>
|
|
|
175
175
|
}),
|
|
176
176
|
);
|
|
177
177
|
|
|
178
|
-
export const QtiTemplateBlockFeedbackBlockSchema: z.
|
|
178
|
+
export const QtiTemplateBlockFeedbackBlockSchema: z.ZodType = z.lazy(() =>
|
|
179
179
|
strictObject({
|
|
180
180
|
kind: z.literal("templateBlockFeedbackBlock"),
|
|
181
181
|
...QtiCommonNodeShape,
|
|
@@ -188,7 +188,7 @@ export const QtiTemplateBlockFeedbackBlockSchema: z.ZodTypeAny = z.lazy(() =>
|
|
|
188
188
|
}),
|
|
189
189
|
);
|
|
190
190
|
|
|
191
|
-
export const QtiTemplateBlockSchema: z.
|
|
191
|
+
export const QtiTemplateBlockSchema: z.ZodType = z.lazy(() =>
|
|
192
192
|
strictObject({
|
|
193
193
|
kind: z.literal("templateBlock"),
|
|
194
194
|
...QtiCommonNodeShape,
|
|
@@ -201,7 +201,7 @@ export const QtiTemplateBlockSchema: z.ZodTypeAny = z.lazy(() =>
|
|
|
201
201
|
}),
|
|
202
202
|
);
|
|
203
203
|
|
|
204
|
-
export const QtiRubricBlockSchema: z.
|
|
204
|
+
export const QtiRubricBlockSchema: z.ZodType = z.lazy(() =>
|
|
205
205
|
strictObject({
|
|
206
206
|
kind: z.literal("rubricBlock"),
|
|
207
207
|
...QtiCommonNodeShape,
|
|
@@ -213,7 +213,7 @@ export const QtiRubricBlockSchema: z.ZodTypeAny = z.lazy(() =>
|
|
|
213
213
|
}),
|
|
214
214
|
);
|
|
215
215
|
|
|
216
|
-
export const QtiTestRubricBlockSchema: z.
|
|
216
|
+
export const QtiTestRubricBlockSchema: z.ZodType = z.lazy(() =>
|
|
217
217
|
strictObject({
|
|
218
218
|
kind: z.literal("testRubricBlock"),
|
|
219
219
|
...QtiCommonNodeShape,
|
|
@@ -226,7 +226,7 @@ export const QtiTestRubricBlockSchema: z.ZodTypeAny = z.lazy(() =>
|
|
|
226
226
|
}),
|
|
227
227
|
);
|
|
228
228
|
|
|
229
|
-
export const QtiModalFeedbackSchema: z.
|
|
229
|
+
export const QtiModalFeedbackSchema: z.ZodType = z.lazy(() =>
|
|
230
230
|
strictObject({
|
|
231
231
|
kind: z.literal("modalFeedback"),
|
|
232
232
|
outcomeIdentifier: QtiIdentifierSchema,
|
|
@@ -240,7 +240,7 @@ export const QtiModalFeedbackSchema: z.ZodTypeAny = z.lazy(() =>
|
|
|
240
240
|
}),
|
|
241
241
|
);
|
|
242
242
|
|
|
243
|
-
export const QtiTestFeedbackSchema: z.
|
|
243
|
+
export const QtiTestFeedbackSchema: z.ZodType = z.lazy(() =>
|
|
244
244
|
strictObject({
|
|
245
245
|
kind: z.literal("testFeedback"),
|
|
246
246
|
access: z.enum(["atEnd", "during"]),
|
|
@@ -265,7 +265,7 @@ export const QtiGapSchema = strictObject({
|
|
|
265
265
|
required: z.boolean().optional(),
|
|
266
266
|
});
|
|
267
267
|
|
|
268
|
-
export const QtiGapTextSchema: z.
|
|
268
|
+
export const QtiGapTextSchema: z.ZodType = z.lazy(() =>
|
|
269
269
|
strictObject({
|
|
270
270
|
kind: z.literal("gapText"),
|
|
271
271
|
...QtiCommonNodeShape,
|
|
@@ -279,7 +279,7 @@ export const QtiGapTextSchema: z.ZodTypeAny = z.lazy(() =>
|
|
|
279
279
|
}),
|
|
280
280
|
);
|
|
281
281
|
|
|
282
|
-
export const QtiGapImgSchema: z.
|
|
282
|
+
export const QtiGapImgSchema: z.ZodType = z.lazy(() =>
|
|
283
283
|
strictObject({
|
|
284
284
|
kind: z.literal("gapImg"),
|
|
285
285
|
...QtiCommonNodeShape,
|
|
@@ -296,7 +296,7 @@ export const QtiGapImgSchema: z.ZodTypeAny = z.lazy(() =>
|
|
|
296
296
|
}),
|
|
297
297
|
);
|
|
298
298
|
|
|
299
|
-
export const QtiHotTextSchema: z.
|
|
299
|
+
export const QtiHotTextSchema: z.ZodType = z.lazy(() =>
|
|
300
300
|
strictObject({
|
|
301
301
|
kind: z.literal("hotText"),
|
|
302
302
|
...QtiCommonNodeShape,
|
|
@@ -331,7 +331,7 @@ export const QtiAssociableHotspotSchema = strictObject({
|
|
|
331
331
|
hotspotLabel: z.string().optional(),
|
|
332
332
|
});
|
|
333
333
|
|
|
334
|
-
export const QtiSimpleChoiceSchema: z.
|
|
334
|
+
export const QtiSimpleChoiceSchema: z.ZodType = z.lazy(() =>
|
|
335
335
|
strictObject({
|
|
336
336
|
kind: z.literal("simpleChoice"),
|
|
337
337
|
...QtiCommonNodeShape,
|
|
@@ -343,7 +343,7 @@ export const QtiSimpleChoiceSchema: z.ZodTypeAny = z.lazy(() =>
|
|
|
343
343
|
}),
|
|
344
344
|
);
|
|
345
345
|
|
|
346
|
-
export const QtiSimpleAssociableChoiceSchema: z.
|
|
346
|
+
export const QtiSimpleAssociableChoiceSchema: z.ZodType = z.lazy(() =>
|
|
347
347
|
strictObject({
|
|
348
348
|
kind: z.literal("simpleAssociableChoice"),
|
|
349
349
|
...QtiCommonNodeShape,
|
|
@@ -358,7 +358,7 @@ export const QtiSimpleAssociableChoiceSchema: z.ZodTypeAny = z.lazy(() =>
|
|
|
358
358
|
}),
|
|
359
359
|
);
|
|
360
360
|
|
|
361
|
-
export const QtiInlineChoiceSchema: z.
|
|
361
|
+
export const QtiInlineChoiceSchema: z.ZodType = z.lazy(() =>
|
|
362
362
|
strictObject({
|
|
363
363
|
kind: z.literal("inlineChoice"),
|
|
364
364
|
...QtiCommonNodeShape,
|
|
@@ -372,7 +372,7 @@ export const QtiInlineChoiceSchema: z.ZodTypeAny = z.lazy(() =>
|
|
|
372
372
|
|
|
373
373
|
const QtiRenderableNodeSchema = z.union([QtiXmlContentNodeSchema, QtiIncludeSchema]);
|
|
374
374
|
|
|
375
|
-
export const QtiChoiceInteractionSchema: z.
|
|
375
|
+
export const QtiChoiceInteractionSchema: z.ZodType = z.lazy(() =>
|
|
376
376
|
strictObject({
|
|
377
377
|
kind: z.literal("choiceInteraction"),
|
|
378
378
|
...QtiCommonNodeShape,
|
|
@@ -388,7 +388,7 @@ export const QtiChoiceInteractionSchema: z.ZodTypeAny = z.lazy(() =>
|
|
|
388
388
|
}),
|
|
389
389
|
);
|
|
390
390
|
|
|
391
|
-
export const QtiInlineChoiceInteractionSchema: z.
|
|
391
|
+
export const QtiInlineChoiceInteractionSchema: z.ZodType = z.lazy(() =>
|
|
392
392
|
strictObject({
|
|
393
393
|
kind: z.literal("inlineChoiceInteraction"),
|
|
394
394
|
...QtiCommonNodeShape,
|
|
@@ -416,7 +416,7 @@ export const QtiTextEntryInteractionSchema = strictObject({
|
|
|
416
416
|
dataPatternmaskMessage: z.string().optional(),
|
|
417
417
|
});
|
|
418
418
|
|
|
419
|
-
export const QtiExtendedTextInteractionSchema: z.
|
|
419
|
+
export const QtiExtendedTextInteractionSchema: z.ZodType = z.lazy(() =>
|
|
420
420
|
strictObject({
|
|
421
421
|
kind: z.literal("extendedTextInteraction"),
|
|
422
422
|
...QtiCommonNodeShape,
|
|
@@ -435,7 +435,7 @@ export const QtiExtendedTextInteractionSchema: z.ZodTypeAny = z.lazy(() =>
|
|
|
435
435
|
}),
|
|
436
436
|
);
|
|
437
437
|
|
|
438
|
-
export const QtiSimpleMatchSetSchema: z.
|
|
438
|
+
export const QtiSimpleMatchSetSchema: z.ZodType = z.lazy(() =>
|
|
439
439
|
strictObject({
|
|
440
440
|
kind: z.literal("simpleMatchSet"),
|
|
441
441
|
id: QtiIdentifierSchema.optional(),
|
|
@@ -444,7 +444,7 @@ export const QtiSimpleMatchSetSchema: z.ZodTypeAny = z.lazy(() =>
|
|
|
444
444
|
}),
|
|
445
445
|
);
|
|
446
446
|
|
|
447
|
-
export const QtiMatchInteractionSchema: z.
|
|
447
|
+
export const QtiMatchInteractionSchema: z.ZodType = z.lazy(() =>
|
|
448
448
|
strictObject({
|
|
449
449
|
kind: z.literal("matchInteraction"),
|
|
450
450
|
...QtiCommonNodeShape,
|
|
@@ -462,7 +462,7 @@ export const QtiMatchInteractionSchema: z.ZodTypeAny = z.lazy(() =>
|
|
|
462
462
|
|
|
463
463
|
export const QtiGapChoiceSchema = z.union([QtiGapTextSchema, QtiGapImgSchema]);
|
|
464
464
|
|
|
465
|
-
export const QtiGapMatchInteractionSchema: z.
|
|
465
|
+
export const QtiGapMatchInteractionSchema: z.ZodType = z.lazy(() =>
|
|
466
466
|
strictObject({
|
|
467
467
|
kind: z.literal("gapMatchInteraction"),
|
|
468
468
|
...QtiCommonNodeShape,
|
|
@@ -479,7 +479,7 @@ export const QtiGapMatchInteractionSchema: z.ZodTypeAny = z.lazy(() =>
|
|
|
479
479
|
}),
|
|
480
480
|
);
|
|
481
481
|
|
|
482
|
-
export const QtiMediaInteractionSchema: z.
|
|
482
|
+
export const QtiMediaInteractionSchema: z.ZodType = z.lazy(() =>
|
|
483
483
|
strictObject({
|
|
484
484
|
kind: z.literal("mediaInteraction"),
|
|
485
485
|
...QtiCommonNodeShape,
|
|
@@ -494,7 +494,7 @@ export const QtiMediaInteractionSchema: z.ZodTypeAny = z.lazy(() =>
|
|
|
494
494
|
}),
|
|
495
495
|
);
|
|
496
496
|
|
|
497
|
-
export const QtiUploadInteractionSchema: z.
|
|
497
|
+
export const QtiUploadInteractionSchema: z.ZodType = z.lazy(() =>
|
|
498
498
|
strictObject({
|
|
499
499
|
kind: z.literal("uploadInteraction"),
|
|
500
500
|
...QtiCommonNodeShape,
|
|
@@ -504,7 +504,7 @@ export const QtiUploadInteractionSchema: z.ZodTypeAny = z.lazy(() =>
|
|
|
504
504
|
}),
|
|
505
505
|
);
|
|
506
506
|
|
|
507
|
-
export const QtiOrderInteractionSchema: z.
|
|
507
|
+
export const QtiOrderInteractionSchema: z.ZodType = z.lazy(() =>
|
|
508
508
|
strictObject({
|
|
509
509
|
kind: z.literal("orderInteraction"),
|
|
510
510
|
...QtiCommonNodeShape,
|
|
@@ -521,7 +521,7 @@ export const QtiOrderInteractionSchema: z.ZodTypeAny = z.lazy(() =>
|
|
|
521
521
|
}),
|
|
522
522
|
);
|
|
523
523
|
|
|
524
|
-
export const QtiHotTextInteractionSchema: z.
|
|
524
|
+
export const QtiHotTextInteractionSchema: z.ZodType = z.lazy(() =>
|
|
525
525
|
strictObject({
|
|
526
526
|
kind: z.literal("hotTextInteraction"),
|
|
527
527
|
...QtiCommonNodeShape,
|
|
@@ -535,7 +535,7 @@ export const QtiHotTextInteractionSchema: z.ZodTypeAny = z.lazy(() =>
|
|
|
535
535
|
}),
|
|
536
536
|
);
|
|
537
537
|
|
|
538
|
-
export const QtiHotspotInteractionSchema: z.
|
|
538
|
+
export const QtiHotspotInteractionSchema: z.ZodType = z.lazy(() =>
|
|
539
539
|
strictObject({
|
|
540
540
|
kind: z.literal("hotspotInteraction"),
|
|
541
541
|
...QtiCommonNodeShape,
|
|
@@ -550,7 +550,7 @@ export const QtiHotspotInteractionSchema: z.ZodTypeAny = z.lazy(() =>
|
|
|
550
550
|
}),
|
|
551
551
|
);
|
|
552
552
|
|
|
553
|
-
export const QtiAssociateInteractionSchema: z.
|
|
553
|
+
export const QtiAssociateInteractionSchema: z.ZodType = z.lazy(() =>
|
|
554
554
|
strictObject({
|
|
555
555
|
kind: z.literal("associateInteraction"),
|
|
556
556
|
...QtiCommonNodeShape,
|
|
@@ -563,7 +563,7 @@ export const QtiAssociateInteractionSchema: z.ZodTypeAny = z.lazy(() =>
|
|
|
563
563
|
}),
|
|
564
564
|
);
|
|
565
565
|
|
|
566
|
-
export const QtiGraphicAssociateInteractionSchema: z.
|
|
566
|
+
export const QtiGraphicAssociateInteractionSchema: z.ZodType = z.lazy(() =>
|
|
567
567
|
strictObject({
|
|
568
568
|
kind: z.literal("graphicAssociateInteraction"),
|
|
569
569
|
...QtiCommonNodeShape,
|
|
@@ -576,7 +576,7 @@ export const QtiGraphicAssociateInteractionSchema: z.ZodTypeAny = z.lazy(() =>
|
|
|
576
576
|
}),
|
|
577
577
|
);
|
|
578
578
|
|
|
579
|
-
export const QtiGraphicGapMatchInteractionSchema: z.
|
|
579
|
+
export const QtiGraphicGapMatchInteractionSchema: z.ZodType = z.lazy(() =>
|
|
580
580
|
strictObject({
|
|
581
581
|
kind: z.literal("graphicGapMatchInteraction"),
|
|
582
582
|
...QtiCommonNodeShape,
|
|
@@ -593,7 +593,7 @@ export const QtiGraphicGapMatchInteractionSchema: z.ZodTypeAny = z.lazy(() =>
|
|
|
593
593
|
}),
|
|
594
594
|
);
|
|
595
595
|
|
|
596
|
-
export const QtiGraphicOrderInteractionSchema: z.
|
|
596
|
+
export const QtiGraphicOrderInteractionSchema: z.ZodType = z.lazy(() =>
|
|
597
597
|
strictObject({
|
|
598
598
|
kind: z.literal("graphicOrderInteraction"),
|
|
599
599
|
...QtiCommonNodeShape,
|
|
@@ -606,7 +606,7 @@ export const QtiGraphicOrderInteractionSchema: z.ZodTypeAny = z.lazy(() =>
|
|
|
606
606
|
}),
|
|
607
607
|
);
|
|
608
608
|
|
|
609
|
-
export const QtiSelectPointInteractionSchema: z.
|
|
609
|
+
export const QtiSelectPointInteractionSchema: z.ZodType = z.lazy(() =>
|
|
610
610
|
strictObject({
|
|
611
611
|
kind: z.literal("selectPointInteraction"),
|
|
612
612
|
...QtiCommonNodeShape,
|
|
@@ -618,7 +618,7 @@ export const QtiSelectPointInteractionSchema: z.ZodTypeAny = z.lazy(() =>
|
|
|
618
618
|
}),
|
|
619
619
|
);
|
|
620
620
|
|
|
621
|
-
export const QtiSliderInteractionSchema: z.
|
|
621
|
+
export const QtiSliderInteractionSchema: z.ZodType = z.lazy(() =>
|
|
622
622
|
strictObject({
|
|
623
623
|
kind: z.literal("sliderInteraction"),
|
|
624
624
|
...QtiCommonNodeShape,
|
|
@@ -633,7 +633,7 @@ export const QtiSliderInteractionSchema: z.ZodTypeAny = z.lazy(() =>
|
|
|
633
633
|
}),
|
|
634
634
|
);
|
|
635
635
|
|
|
636
|
-
export const QtiPositionObjectInteractionSchema: z.
|
|
636
|
+
export const QtiPositionObjectInteractionSchema: z.ZodType = z.lazy(() =>
|
|
637
637
|
strictObject({
|
|
638
638
|
kind: z.literal("positionObjectInteraction"),
|
|
639
639
|
...QtiCommonNodeShape,
|
|
@@ -645,7 +645,7 @@ export const QtiPositionObjectInteractionSchema: z.ZodTypeAny = z.lazy(() =>
|
|
|
645
645
|
}),
|
|
646
646
|
);
|
|
647
647
|
|
|
648
|
-
export const QtiPortableCustomInteractionSchema: z.
|
|
648
|
+
export const QtiPortableCustomInteractionSchema: z.ZodType = z.lazy(() =>
|
|
649
649
|
strictObject({
|
|
650
650
|
kind: z.literal("portableCustomInteraction"),
|
|
651
651
|
...QtiCommonNodeShape,
|
|
@@ -664,7 +664,7 @@ export const QtiPortableCustomInteractionSchema: z.ZodTypeAny = z.lazy(() =>
|
|
|
664
664
|
}),
|
|
665
665
|
);
|
|
666
666
|
|
|
667
|
-
export const QtiCustomInteractionSchema: z.
|
|
667
|
+
export const QtiCustomInteractionSchema: z.ZodType = z.lazy(() =>
|
|
668
668
|
strictObject({
|
|
669
669
|
kind: z.literal("customInteraction"),
|
|
670
670
|
...QtiCommonNodeShape,
|
|
@@ -674,7 +674,7 @@ export const QtiCustomInteractionSchema: z.ZodTypeAny = z.lazy(() =>
|
|
|
674
674
|
}),
|
|
675
675
|
);
|
|
676
676
|
|
|
677
|
-
export const QtiDrawingInteractionSchema: z.
|
|
677
|
+
export const QtiDrawingInteractionSchema: z.ZodType = z.lazy(() =>
|
|
678
678
|
strictObject({
|
|
679
679
|
kind: z.literal("drawingInteraction"),
|
|
680
680
|
...QtiCommonNodeShape,
|
|
@@ -685,7 +685,7 @@ export const QtiDrawingInteractionSchema: z.ZodTypeAny = z.lazy(() =>
|
|
|
685
685
|
}),
|
|
686
686
|
);
|
|
687
687
|
|
|
688
|
-
export const QtiEndAttemptInteractionSchema: z.
|
|
688
|
+
export const QtiEndAttemptInteractionSchema: z.ZodType = z.lazy(() =>
|
|
689
689
|
strictObject({
|
|
690
690
|
kind: z.literal("endAttemptInteraction"),
|
|
691
691
|
...QtiCommonNodeShape,
|
|
@@ -697,7 +697,7 @@ export const QtiEndAttemptInteractionSchema: z.ZodTypeAny = z.lazy(() =>
|
|
|
697
697
|
}),
|
|
698
698
|
);
|
|
699
699
|
|
|
700
|
-
export const QtiPositionObjectStageSchema: z.
|
|
700
|
+
export const QtiPositionObjectStageSchema: z.ZodType = z.lazy(() =>
|
|
701
701
|
strictObject({
|
|
702
702
|
kind: z.literal("positionObjectStage"),
|
|
703
703
|
id: QtiIdentifierSchema.optional(),
|
|
@@ -707,7 +707,7 @@ export const QtiPositionObjectStageSchema: z.ZodTypeAny = z.lazy(() =>
|
|
|
707
707
|
}),
|
|
708
708
|
);
|
|
709
709
|
|
|
710
|
-
export const QtiContentFragmentSchema: z.
|
|
710
|
+
export const QtiContentFragmentSchema: z.ZodType = z.lazy(() =>
|
|
711
711
|
z.union([
|
|
712
712
|
z.string(),
|
|
713
713
|
QtiXmlContentNodeSchema,
|
|
@@ -753,13 +753,13 @@ export const QtiContentFragmentSchema: z.ZodTypeAny = z.lazy(() =>
|
|
|
753
753
|
]),
|
|
754
754
|
);
|
|
755
755
|
|
|
756
|
-
export const QtiItemBodySchema: z.
|
|
756
|
+
export const QtiItemBodySchema: z.ZodType = z.lazy(() =>
|
|
757
757
|
strictObject({
|
|
758
758
|
content: z.array(QtiContentFragmentSchema).min(1),
|
|
759
759
|
}),
|
|
760
760
|
);
|
|
761
761
|
|
|
762
|
-
export const QtiStimulusBodySchema: z.
|
|
762
|
+
export const QtiStimulusBodySchema: z.ZodType = z.lazy(() =>
|
|
763
763
|
strictObject({
|
|
764
764
|
...QtiCommonNodeShape,
|
|
765
765
|
content: z.array(QtiContentFragmentSchema).min(1),
|
|
@@ -831,7 +831,35 @@ export const QtiAssessmentStimulusRefSchema = strictObject({
|
|
|
831
831
|
foreignAttributes: XmlForeignAttributesSchema.optional(),
|
|
832
832
|
});
|
|
833
833
|
|
|
834
|
-
|
|
834
|
+
/**
|
|
835
|
+
* The ASI node fields the cross-validators read. Nodes arrive pre-validation
|
|
836
|
+
* (these refinements run during parsing), so every field stays `unknown` until
|
|
837
|
+
* narrowed; the declared names are the QTI vocabulary the checks are defined
|
|
838
|
+
* over -- anything else on a node flows through the index signature.
|
|
839
|
+
*/
|
|
840
|
+
type AsiNodeView = {
|
|
841
|
+
kind?: unknown;
|
|
842
|
+
identifier?: unknown;
|
|
843
|
+
responseIdentifier?: unknown;
|
|
844
|
+
content?: unknown;
|
|
845
|
+
simpleChoices?: unknown;
|
|
846
|
+
inlineChoices?: unknown;
|
|
847
|
+
gapChoices?: unknown;
|
|
848
|
+
hotspotChoices?: unknown;
|
|
849
|
+
minChoices?: unknown;
|
|
850
|
+
maxChoices?: unknown;
|
|
851
|
+
minStrings?: unknown;
|
|
852
|
+
maxStrings?: unknown;
|
|
853
|
+
minAssociations?: unknown;
|
|
854
|
+
maxAssociations?: unknown;
|
|
855
|
+
minPlays?: unknown;
|
|
856
|
+
maxPlays?: unknown;
|
|
857
|
+
lowerBound?: unknown;
|
|
858
|
+
upperBound?: unknown;
|
|
859
|
+
[key: string]: unknown;
|
|
860
|
+
};
|
|
861
|
+
|
|
862
|
+
function walkUnknown(value: unknown, visit: (node: AsiNodeView) => void) {
|
|
835
863
|
if (Array.isArray(value)) {
|
|
836
864
|
for (const entry of value) {
|
|
837
865
|
walkUnknown(entry, visit);
|
|
@@ -843,7 +871,7 @@ function walkUnknown(value: unknown, visit: (node: Record<string, unknown>) => v
|
|
|
843
871
|
return;
|
|
844
872
|
}
|
|
845
873
|
|
|
846
|
-
const node = value as
|
|
874
|
+
const node = value as AsiNodeView;
|
|
847
875
|
visit(node);
|
|
848
876
|
|
|
849
877
|
for (const [key, child] of Object.entries(node)) {
|
|
@@ -867,8 +895,8 @@ function containsInteraction(value: unknown): boolean {
|
|
|
867
895
|
return found;
|
|
868
896
|
}
|
|
869
897
|
|
|
870
|
-
function collectInteractionNodes(value: unknown):
|
|
871
|
-
const interactions:
|
|
898
|
+
function collectInteractionNodes(value: unknown): AsiNodeView[] {
|
|
899
|
+
const interactions: AsiNodeView[] = [];
|
|
872
900
|
|
|
873
901
|
walkUnknown(value, (node) => {
|
|
874
902
|
const kind = typeof node.kind === "string" ? node.kind : null;
|
|
@@ -880,8 +908,8 @@ function collectInteractionNodes(value: unknown): Array<Record<string, unknown>>
|
|
|
880
908
|
return interactions;
|
|
881
909
|
}
|
|
882
910
|
|
|
883
|
-
function collectNodesByKind(value: unknown, kinds: readonly string[]):
|
|
884
|
-
const matches:
|
|
911
|
+
function collectNodesByKind(value: unknown, kinds: readonly string[]): AsiNodeView[] {
|
|
912
|
+
const matches: AsiNodeView[] = [];
|
|
885
913
|
const kindSet = new Set(kinds);
|
|
886
914
|
|
|
887
915
|
walkUnknown(value, (node) => {
|
|
@@ -977,7 +1005,7 @@ function addDuplicateSummaryIssue(
|
|
|
977
1005
|
}
|
|
978
1006
|
|
|
979
1007
|
function validateResponseBinding(
|
|
980
|
-
interaction:
|
|
1008
|
+
interaction: AsiNodeView,
|
|
981
1009
|
responsesById: Map<string, z.infer<typeof QtiResponseDeclarationSchema>>,
|
|
982
1010
|
context: z.RefinementCtx,
|
|
983
1011
|
path: Array<string | number>,
|
|
@@ -1249,7 +1277,7 @@ function validateTemplateAndResponseReferences(
|
|
|
1249
1277
|
}
|
|
1250
1278
|
}
|
|
1251
1279
|
|
|
1252
|
-
export const QtiAssessmentSectionRawSchema: z.
|
|
1280
|
+
export const QtiAssessmentSectionRawSchema: z.ZodType = z.lazy(() =>
|
|
1253
1281
|
strictObject({
|
|
1254
1282
|
identifier: QtiIdentifierSchema,
|
|
1255
1283
|
required: z.boolean().optional(),
|
|
@@ -1280,7 +1308,7 @@ export const QtiAssessmentSectionRawSchema: z.ZodTypeAny = z.lazy(() =>
|
|
|
1280
1308
|
}),
|
|
1281
1309
|
);
|
|
1282
1310
|
|
|
1283
|
-
export const QtiAssessmentSectionSchema: z.
|
|
1311
|
+
export const QtiAssessmentSectionSchema: z.ZodType = QtiAssessmentSectionRawSchema.superRefine(
|
|
1284
1312
|
(value: unknown, context) => {
|
|
1285
1313
|
const section = value as QtiSectionValidationValue;
|
|
1286
1314
|
|
|
@@ -1309,7 +1337,7 @@ export const QtiAssessmentSectionSchema: z.ZodTypeAny = QtiAssessmentSectionRawS
|
|
|
1309
1337
|
},
|
|
1310
1338
|
);
|
|
1311
1339
|
|
|
1312
|
-
export const QtiTestPartSchema: z.
|
|
1340
|
+
export const QtiTestPartSchema: z.ZodType = z.lazy(() =>
|
|
1313
1341
|
strictObject({
|
|
1314
1342
|
identifier: QtiIdentifierSchema,
|
|
1315
1343
|
title: z.string().optional(),
|
|
@@ -1327,7 +1355,7 @@ export const QtiTestPartSchema: z.ZodTypeAny = z.lazy(() =>
|
|
|
1327
1355
|
}),
|
|
1328
1356
|
);
|
|
1329
1357
|
|
|
1330
|
-
export const QtiAssessmentStimulusSchema: z.
|
|
1358
|
+
export const QtiAssessmentStimulusSchema: z.ZodType = z.lazy(() =>
|
|
1331
1359
|
strictObject({
|
|
1332
1360
|
identifier: QtiIdentifierSchema,
|
|
1333
1361
|
title: z.string(),
|
|
@@ -1341,7 +1369,7 @@ export const QtiAssessmentStimulusSchema: z.ZodTypeAny = z.lazy(() =>
|
|
|
1341
1369
|
}),
|
|
1342
1370
|
);
|
|
1343
1371
|
|
|
1344
|
-
export const QtiAssessmentItemRawSchema: z.
|
|
1372
|
+
export const QtiAssessmentItemRawSchema: z.ZodType = z.lazy(() =>
|
|
1345
1373
|
strictObject({
|
|
1346
1374
|
identifier: QtiIdentifierSchema,
|
|
1347
1375
|
title: z.string(),
|
|
@@ -1367,92 +1395,86 @@ export const QtiAssessmentItemRawSchema: z.ZodTypeAny = z.lazy(() =>
|
|
|
1367
1395
|
}),
|
|
1368
1396
|
);
|
|
1369
1397
|
|
|
1370
|
-
export const QtiAssessmentItemSchema: z.
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1398
|
+
export const QtiAssessmentItemSchema: z.ZodType = QtiAssessmentItemRawSchema.superRefine((value: unknown, context) => {
|
|
1399
|
+
const item = value as QtiItemValidationValue;
|
|
1400
|
+
const contextDeclarations = asArray(item.contextDeclarations);
|
|
1401
|
+
const responseDeclarationsList = asArray(item.responseDeclarations);
|
|
1402
|
+
const outcomeDeclarationsList = asArray(item.outcomeDeclarations);
|
|
1403
|
+
const templateDeclarationsList = asArray(item.templateDeclarations);
|
|
1404
|
+
const modalFeedbacks = asArray(item.modalFeedbacks);
|
|
1405
|
+
|
|
1406
|
+
const variableDeclarations = [
|
|
1407
|
+
...contextDeclarations,
|
|
1408
|
+
...responseDeclarationsList,
|
|
1409
|
+
...outcomeDeclarationsList,
|
|
1410
|
+
...templateDeclarationsList,
|
|
1411
|
+
];
|
|
1412
|
+
|
|
1413
|
+
addDuplicateSummaryIssue(
|
|
1414
|
+
context,
|
|
1415
|
+
[],
|
|
1416
|
+
"assessment item variable declaration identifiers",
|
|
1417
|
+
variableDeclarations.map((declaration) => declaration.identifier),
|
|
1418
|
+
);
|
|
1419
|
+
|
|
1420
|
+
validateOutcomeDeclarationConventions(outcomeDeclarationsList, context, ["outcomeDeclarations"]);
|
|
1421
|
+
|
|
1422
|
+
const responseDeclarations = new Map(
|
|
1423
|
+
responseDeclarationsList.map((declaration) => [declaration.identifier, declaration]),
|
|
1424
|
+
);
|
|
1425
|
+
const outcomeDeclarations = new Map(
|
|
1426
|
+
outcomeDeclarationsList.map((declaration) => [declaration.identifier, declaration]),
|
|
1427
|
+
);
|
|
1428
|
+
const templateDeclarations = new Map(
|
|
1429
|
+
templateDeclarationsList.map((declaration) => [declaration.identifier, declaration]),
|
|
1430
|
+
);
|
|
1431
|
+
|
|
1432
|
+
const interactions = collectInteractionNodes(item.itemBody?.content);
|
|
1433
|
+
const responseBindings = new Map<string, string[]>();
|
|
1434
|
+
|
|
1435
|
+
for (const interaction of interactions) {
|
|
1436
|
+
const responseIdentifier =
|
|
1437
|
+
typeof interaction.responseIdentifier === "string" ? interaction.responseIdentifier : undefined;
|
|
1438
|
+
if (responseIdentifier) {
|
|
1439
|
+
const boundKinds = responseBindings.get(responseIdentifier) ?? [];
|
|
1440
|
+
boundKinds.push(String(interaction.kind));
|
|
1441
|
+
responseBindings.set(responseIdentifier, boundKinds);
|
|
1442
|
+
}
|
|
1407
1443
|
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
typeof interaction.responseIdentifier === "string" ? interaction.responseIdentifier : undefined;
|
|
1411
|
-
if (responseIdentifier) {
|
|
1412
|
-
const boundKinds = responseBindings.get(responseIdentifier) ?? [];
|
|
1413
|
-
boundKinds.push(String(interaction.kind));
|
|
1414
|
-
responseBindings.set(responseIdentifier, boundKinds);
|
|
1415
|
-
}
|
|
1444
|
+
validateResponseBinding(interaction, responseDeclarations, context, ["itemBody"]);
|
|
1445
|
+
}
|
|
1416
1446
|
|
|
1417
|
-
|
|
1447
|
+
for (const [identifier, kinds] of responseBindings) {
|
|
1448
|
+
if (kinds.length > 1) {
|
|
1449
|
+
addIssue(
|
|
1450
|
+
context,
|
|
1451
|
+
["itemBody"],
|
|
1452
|
+
`Response identifier '${identifier}' is bound by multiple interactions: ${kinds.join(", ")}.`,
|
|
1453
|
+
);
|
|
1418
1454
|
}
|
|
1455
|
+
}
|
|
1419
1456
|
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
}
|
|
1457
|
+
for (const [index, feedback] of modalFeedbacks.entries()) {
|
|
1458
|
+
if (!outcomeDeclarations.has(feedback.outcomeIdentifier)) {
|
|
1459
|
+
addIssue(
|
|
1460
|
+
context,
|
|
1461
|
+
["modalFeedbacks", index, "outcomeIdentifier"],
|
|
1462
|
+
`modalFeedback references undeclared outcome identifier '${feedback.outcomeIdentifier}'.`,
|
|
1463
|
+
);
|
|
1428
1464
|
}
|
|
1429
1465
|
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
addIssue(
|
|
1433
|
-
context,
|
|
1434
|
-
["modalFeedbacks", index, "outcomeIdentifier"],
|
|
1435
|
-
`modalFeedback references undeclared outcome identifier '${feedback.outcomeIdentifier}'.`,
|
|
1436
|
-
);
|
|
1437
|
-
}
|
|
1438
|
-
|
|
1439
|
-
if (containsInteraction(feedback.content)) {
|
|
1440
|
-
addIssue(context, ["modalFeedbacks", index, "content"], "modalFeedback content must not contain interactions.");
|
|
1441
|
-
}
|
|
1466
|
+
if (containsInteraction(feedback.content)) {
|
|
1467
|
+
addIssue(context, ["modalFeedbacks", index, "content"], "modalFeedback content must not contain interactions.");
|
|
1442
1468
|
}
|
|
1469
|
+
}
|
|
1443
1470
|
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
context,
|
|
1450
|
-
["templateProcessing"],
|
|
1451
|
-
);
|
|
1452
|
-
},
|
|
1453
|
-
);
|
|
1471
|
+
validateOutcomeReferences(item.responseProcessing, outcomeDeclarations, context, ["responseProcessing"]);
|
|
1472
|
+
validateTemplateAndResponseReferences(item.templateProcessing, templateDeclarations, responseDeclarations, context, [
|
|
1473
|
+
"templateProcessing",
|
|
1474
|
+
]);
|
|
1475
|
+
});
|
|
1454
1476
|
|
|
1455
|
-
export const QtiAssessmentTestRawSchema: z.
|
|
1477
|
+
export const QtiAssessmentTestRawSchema: z.ZodType = z.lazy(() =>
|
|
1456
1478
|
strictObject({
|
|
1457
1479
|
identifier: QtiIdentifierSchema,
|
|
1458
1480
|
title: z.string(),
|
|
@@ -1471,47 +1493,45 @@ export const QtiAssessmentTestRawSchema: z.ZodTypeAny = z.lazy(() =>
|
|
|
1471
1493
|
}),
|
|
1472
1494
|
);
|
|
1473
1495
|
|
|
1474
|
-
export const QtiAssessmentTestSchema: z.
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
const testFeedbacks = asArray(testValue.testFeedbacks);
|
|
1481
|
-
|
|
1482
|
-
addDuplicateSummaryIssue(context, [], "assessment test variable declaration identifiers", [
|
|
1483
|
-
...contextDeclarations.map((declaration) => declaration.identifier),
|
|
1484
|
-
...outcomeDeclarationsList.map((declaration) => declaration.identifier),
|
|
1485
|
-
]);
|
|
1486
|
-
|
|
1487
|
-
addDuplicateSummaryIssue(
|
|
1488
|
-
context,
|
|
1489
|
-
["testParts"],
|
|
1490
|
-
"test part identifiers",
|
|
1491
|
-
testParts.map((testPart) => testPart.identifier),
|
|
1492
|
-
);
|
|
1496
|
+
export const QtiAssessmentTestSchema: z.ZodType = QtiAssessmentTestRawSchema.superRefine((value: unknown, context) => {
|
|
1497
|
+
const testValue = value as QtiTestValidationValue;
|
|
1498
|
+
const contextDeclarations = asArray(testValue.contextDeclarations);
|
|
1499
|
+
const outcomeDeclarationsList = asArray(testValue.outcomeDeclarations);
|
|
1500
|
+
const testParts = asArray(testValue.testParts);
|
|
1501
|
+
const testFeedbacks = asArray(testValue.testFeedbacks);
|
|
1493
1502
|
|
|
1494
|
-
|
|
1503
|
+
addDuplicateSummaryIssue(context, [], "assessment test variable declaration identifiers", [
|
|
1504
|
+
...contextDeclarations.map((declaration) => declaration.identifier),
|
|
1505
|
+
...outcomeDeclarationsList.map((declaration) => declaration.identifier),
|
|
1506
|
+
]);
|
|
1495
1507
|
|
|
1496
|
-
|
|
1508
|
+
addDuplicateSummaryIssue(
|
|
1509
|
+
context,
|
|
1510
|
+
["testParts"],
|
|
1511
|
+
"test part identifiers",
|
|
1512
|
+
testParts.map((testPart) => testPart.identifier),
|
|
1513
|
+
);
|
|
1497
1514
|
|
|
1498
|
-
|
|
1499
|
-
if (!outcomes.has(feedback.outcomeIdentifier)) {
|
|
1500
|
-
addIssue(
|
|
1501
|
-
context,
|
|
1502
|
-
["testFeedbacks", index, "outcomeIdentifier"],
|
|
1503
|
-
`testFeedback references undeclared outcome identifier '${feedback.outcomeIdentifier}'.`,
|
|
1504
|
-
);
|
|
1505
|
-
}
|
|
1515
|
+
validateOutcomeDeclarationConventions(outcomeDeclarationsList, context, ["outcomeDeclarations"]);
|
|
1506
1516
|
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1517
|
+
const outcomes = new Map(outcomeDeclarationsList.map((declaration) => [declaration.identifier, declaration]));
|
|
1518
|
+
|
|
1519
|
+
for (const [index, feedback] of testFeedbacks.entries()) {
|
|
1520
|
+
if (!outcomes.has(feedback.outcomeIdentifier)) {
|
|
1521
|
+
addIssue(
|
|
1522
|
+
context,
|
|
1523
|
+
["testFeedbacks", index, "outcomeIdentifier"],
|
|
1524
|
+
`testFeedback references undeclared outcome identifier '${feedback.outcomeIdentifier}'.`,
|
|
1525
|
+
);
|
|
1510
1526
|
}
|
|
1511
1527
|
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1528
|
+
if (containsInteraction(feedback.content)) {
|
|
1529
|
+
addIssue(context, ["testFeedbacks", index, "content"], "testFeedback content must not contain interactions.");
|
|
1530
|
+
}
|
|
1531
|
+
}
|
|
1532
|
+
|
|
1533
|
+
validateOutcomeReferences(testValue.outcomeProcessing, outcomes, context, ["outcomeProcessing"]);
|
|
1534
|
+
});
|
|
1515
1535
|
// Inferred types from exported Zod validators.
|
|
1516
1536
|
export type QtiPrintedVariable = z.infer<typeof QtiPrintedVariableSchema>;
|
|
1517
1537
|
export type QtiInteractionModule = z.infer<typeof QtiInteractionModuleSchema>;
|