@longsightgroup/qti3-core 0.9.9 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/attempt-state.d.ts.map +1 -1
- package/dist/attempt-state.js +8 -2
- package/dist/attempt-state.js.map +1 -1
- package/dist/delivery-redaction.d.ts +0 -1
- package/dist/delivery-redaction.d.ts.map +1 -1
- package/dist/delivery-redaction.js +0 -10
- package/dist/delivery-redaction.js.map +1 -1
- package/dist/delivery-security.d.ts.map +1 -1
- package/dist/delivery-security.js +2 -1
- package/dist/delivery-security.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/parser-declarations.d.ts.map +1 -1
- package/dist/parser-declarations.js +2 -2
- package/dist/parser-declarations.js.map +1 -1
- package/dist/parser-item-metadata.d.ts.map +1 -1
- package/dist/parser-item-metadata.js +2 -1
- package/dist/parser-item-metadata.js.map +1 -1
- package/dist/parser-processing.d.ts.map +1 -1
- package/dist/parser-processing.js +8 -4
- package/dist/parser-processing.js.map +1 -1
- package/dist/parser-values.d.ts.map +1 -1
- package/dist/parser-values.js +9 -6
- package/dist/parser-values.js.map +1 -1
- package/dist/processing-expression-collection.d.ts +4 -0
- package/dist/processing-expression-collection.d.ts.map +1 -0
- package/dist/processing-expression-collection.js +44 -0
- package/dist/processing-expression-collection.js.map +1 -0
- package/dist/qti-package-assets.d.ts +3 -1
- package/dist/qti-package-assets.d.ts.map +1 -1
- package/dist/qti-package-assets.js +22 -0
- package/dist/qti-package-assets.js.map +1 -1
- package/dist/qti-package-items.d.ts +2 -1
- package/dist/qti-package-items.d.ts.map +1 -1
- package/dist/qti-package-items.js +96 -18
- package/dist/qti-package-items.js.map +1 -1
- package/dist/qti-package-manifest.d.ts.map +1 -1
- package/dist/qti-package-manifest.js +2 -0
- package/dist/qti-package-manifest.js.map +1 -1
- package/dist/qti-package-metadata.d.ts +5 -2
- package/dist/qti-package-metadata.d.ts.map +1 -1
- package/dist/qti-package-metadata.js +116 -8
- package/dist/qti-package-metadata.js.map +1 -1
- package/dist/qti-package-types.d.ts +62 -0
- package/dist/qti-package-types.d.ts.map +1 -1
- package/dist/qti-package-xml.d.ts.map +1 -1
- package/dist/qti-package-xml.js +1 -1
- package/dist/qti-package-xml.js.map +1 -1
- package/dist/qti-package.d.ts +2 -1
- package/dist/qti-package.d.ts.map +1 -1
- package/dist/qti-package.js +2 -0
- package/dist/qti-package.js.map +1 -1
- package/dist/response-validation-policy.d.ts.map +1 -1
- package/dist/response-validation-policy.js +2 -1
- package/dist/response-validation-policy.js.map +1 -1
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/validation-primitives.d.ts.map +1 -1
- package/dist/validation-primitives.js +2 -1
- package/dist/validation-primitives.js.map +1 -1
- package/dist/validation-processing.d.ts.map +1 -1
- package/dist/validation-processing.js +2 -2
- package/dist/validation-processing.js.map +1 -1
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +18 -6
- package/dist/validation.js.map +1 -1
- package/package.json +1 -1
- package/src/attempt-state.ts +6 -2
- package/src/delivery-redaction.ts +0 -8
- package/src/delivery-security.ts +1 -1
- package/src/index.ts +10 -1
- package/src/parser-declarations.ts +2 -1
- package/src/parser-item-metadata.ts +2 -1
- package/src/parser-processing.ts +8 -4
- package/src/parser-values.ts +7 -4
- package/src/processing-expression-collection.ts +57 -0
- package/src/qti-package-assets.ts +30 -0
- package/src/qti-package-items.ts +190 -29
- package/src/qti-package-manifest.ts +2 -0
- package/src/qti-package-metadata.ts +174 -7
- package/src/qti-package-types.ts +69 -0
- package/src/qti-package-xml.ts +2 -1
- package/src/qti-package.ts +9 -0
- package/src/response-validation-policy.ts +2 -1
- package/src/types.ts +2 -0
- package/src/validation-primitives.ts +2 -1
- package/src/validation-processing.ts +7 -2
- package/src/validation.ts +22 -6
package/src/qti-package.ts
CHANGED
|
@@ -36,22 +36,30 @@ import {
|
|
|
36
36
|
import type { QtiDiagnostic } from "./types.js";
|
|
37
37
|
|
|
38
38
|
export { decodeUtf8, readQtiPackageZipEntries };
|
|
39
|
+
export { discoverQtiPackageContentAssets } from "./qti-package-assets.js";
|
|
39
40
|
export { normalizePackagePath } from "./qti-package-paths.js";
|
|
40
41
|
export { QTI_ITEM_RESOURCE_TYPE, QTI_PACKAGE_MANIFEST_PATH } from "./qti-package-manifest.js";
|
|
41
42
|
export type { QtiPackageEntry };
|
|
42
43
|
|
|
43
44
|
export type {
|
|
45
|
+
QtiAssessmentSectionPackageModel,
|
|
44
46
|
QtiAssessmentTestItemRef,
|
|
45
47
|
QtiAssessmentTestPackageModel,
|
|
46
48
|
QtiManifestFile,
|
|
47
49
|
QtiManifestResource,
|
|
48
50
|
QtiPackageAsset,
|
|
51
|
+
QtiPackageContentAssetDiscovery,
|
|
49
52
|
QtiPackageAssetSource,
|
|
50
53
|
QtiPackageItem,
|
|
51
54
|
QtiPackageItemSource,
|
|
52
55
|
QtiPackageParseResult,
|
|
53
56
|
QtiPackageShape,
|
|
57
|
+
QtiItemSessionControl,
|
|
54
58
|
QtiStandardAlignment,
|
|
59
|
+
QtiTestPartNavigationMode,
|
|
60
|
+
QtiTestPartPackageModel,
|
|
61
|
+
QtiTestPartSubmissionMode,
|
|
62
|
+
QtiTimeLimits,
|
|
55
63
|
QtiTimingMetadata,
|
|
56
64
|
} from "./qti-package-types.js";
|
|
57
65
|
|
|
@@ -159,6 +167,7 @@ function parseQtiPackageEntries(
|
|
|
159
167
|
return {
|
|
160
168
|
ok: diagnostics.every((diagnostic) => diagnostic.severity !== "error"),
|
|
161
169
|
title,
|
|
170
|
+
entries,
|
|
162
171
|
packageShape,
|
|
163
172
|
items,
|
|
164
173
|
assets,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { QtiChoice, QtiDiagnostic, QtiInteraction, QtiValue } from "./types.js";
|
|
2
|
+
import { parseXmlBoolean } from "./parser-values.js";
|
|
2
3
|
import { parseNonNegativeInteger } from "./validation-primitives.js";
|
|
3
4
|
import { qtiValueToIdentifierList } from "./value-format.js";
|
|
4
5
|
|
|
@@ -36,7 +37,7 @@ export function responseLimitAttribute(
|
|
|
36
37
|
}
|
|
37
38
|
|
|
38
39
|
function interactionRequiresResponse(interaction: QtiInteraction): boolean {
|
|
39
|
-
return interaction.attributes.required ===
|
|
40
|
+
return parseXmlBoolean(interaction.attributes.required) === true;
|
|
40
41
|
}
|
|
41
42
|
|
|
42
43
|
export function minimumRequiredResponses(interaction: QtiInteraction | undefined): number {
|
package/src/types.ts
CHANGED
|
@@ -494,6 +494,8 @@ export interface QtiResponseProcessing {
|
|
|
494
494
|
template?: string | undefined;
|
|
495
495
|
rules: QtiResponseRule[];
|
|
496
496
|
conditions: QtiResponseCondition[];
|
|
497
|
+
/** Direct processing expressions retained even when they are not wrapped in a response rule. */
|
|
498
|
+
expressions?: QtiProcessingExpression[] | undefined;
|
|
497
499
|
}
|
|
498
500
|
|
|
499
501
|
export interface QtiResponseCondition {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { QtiBaseType, QtiCardinality, QtiDiagnostic } from "./types.js";
|
|
2
|
+
import { parseXmlBoolean } from "./parser-values.js";
|
|
2
3
|
|
|
3
4
|
export function requireIdentifier(
|
|
4
5
|
qtiName: string,
|
|
@@ -54,7 +55,7 @@ export function parseNonNegativeInteger(value: string | undefined): number | und
|
|
|
54
55
|
}
|
|
55
56
|
|
|
56
57
|
export function isBooleanAttribute(value: string): boolean {
|
|
57
|
-
return value
|
|
58
|
+
return parseXmlBoolean(value) !== undefined;
|
|
58
59
|
}
|
|
59
60
|
|
|
60
61
|
export function isPoint(value: string): boolean {
|
|
@@ -13,7 +13,12 @@ import {
|
|
|
13
13
|
responseProcessingTemplateKind,
|
|
14
14
|
type ResponseProcessingTemplateKind,
|
|
15
15
|
} from "./processing-templates.js";
|
|
16
|
-
import {
|
|
16
|
+
import {
|
|
17
|
+
isBaseType,
|
|
18
|
+
isBooleanAttribute,
|
|
19
|
+
isFiniteNumber,
|
|
20
|
+
isInteger,
|
|
21
|
+
} from "./validation-primitives.js";
|
|
17
22
|
import { COMPLETION_STATUS } from "./attempt-state-constants.js";
|
|
18
23
|
|
|
19
24
|
export function validateResponseProcessingTemplate(
|
|
@@ -640,7 +645,7 @@ function validateBaseValueExpression(
|
|
|
640
645
|
source: expression.source,
|
|
641
646
|
});
|
|
642
647
|
}
|
|
643
|
-
if (expression.baseType === "boolean" && value
|
|
648
|
+
if (expression.baseType === "boolean" && !isBooleanAttribute(value)) {
|
|
644
649
|
diagnostics.push({
|
|
645
650
|
code: "processing.baseValue.boolean",
|
|
646
651
|
severity: "error",
|
package/src/validation.ts
CHANGED
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
} from "./validation-geometry.js";
|
|
24
24
|
import {
|
|
25
25
|
isBaseType,
|
|
26
|
+
isBooleanAttribute,
|
|
26
27
|
isCardinality,
|
|
27
28
|
isFiniteNumber,
|
|
28
29
|
isInteger,
|
|
@@ -82,7 +83,7 @@ function validateAssessmentItemRoot(item: QtiAssessmentItem, diagnostics: QtiDia
|
|
|
82
83
|
path: item.source?.path,
|
|
83
84
|
source: item.source,
|
|
84
85
|
});
|
|
85
|
-
} else if (!
|
|
86
|
+
} else if (!isBooleanAttribute(timeDependent)) {
|
|
86
87
|
diagnostics.push({
|
|
87
88
|
code: "assessmentItem.timeDependent.boolean",
|
|
88
89
|
severity: "error",
|
|
@@ -93,10 +94,6 @@ function validateAssessmentItemRoot(item: QtiAssessmentItem, diagnostics: QtiDia
|
|
|
93
94
|
}
|
|
94
95
|
}
|
|
95
96
|
|
|
96
|
-
function isXmlBoolean(value: string): boolean {
|
|
97
|
-
return value === "true" || value === "false" || value === "1" || value === "0";
|
|
98
|
-
}
|
|
99
|
-
|
|
100
97
|
function validateItemBody(item: QtiAssessmentItem, diagnostics: QtiDiagnostic[]): void {
|
|
101
98
|
if (item.itemBodySource) return;
|
|
102
99
|
diagnostics.push({
|
|
@@ -219,7 +216,7 @@ function isValidDeclarationBaseValue(value: string, baseType: QtiBaseType): bool
|
|
|
219
216
|
case "float":
|
|
220
217
|
return isFiniteNumber(value);
|
|
221
218
|
case "boolean":
|
|
222
|
-
return value
|
|
219
|
+
return isBooleanAttribute(value);
|
|
223
220
|
case "point":
|
|
224
221
|
return isPoint(value);
|
|
225
222
|
case "pair":
|
|
@@ -669,6 +666,19 @@ function validateCatalogCard(
|
|
|
669
666
|
});
|
|
670
667
|
}
|
|
671
668
|
|
|
669
|
+
if (isCatalogCardEntry(card)) {
|
|
670
|
+
const defaultAttribute = card.attributes.default;
|
|
671
|
+
if (defaultAttribute !== undefined && !isBooleanAttribute(defaultAttribute)) {
|
|
672
|
+
diagnostics.push({
|
|
673
|
+
code: "catalog.cardEntry.default.boolean",
|
|
674
|
+
severity: "error",
|
|
675
|
+
message: `qti-card-entry default must be an XML boolean, found ${defaultAttribute}.`,
|
|
676
|
+
path: card.source?.path,
|
|
677
|
+
source: card.source,
|
|
678
|
+
});
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
|
|
672
682
|
const defaultEntries = entries.filter((entry) => entry.default);
|
|
673
683
|
if (defaultEntries.length > 1) {
|
|
674
684
|
diagnostics.push({
|
|
@@ -698,6 +708,12 @@ function validateCatalogCard(
|
|
|
698
708
|
}
|
|
699
709
|
}
|
|
700
710
|
|
|
711
|
+
function isCatalogCardEntry(
|
|
712
|
+
card: QtiCatalogCard | QtiCatalogCardEntry,
|
|
713
|
+
): card is QtiCatalogCardEntry {
|
|
714
|
+
return !("entries" in card);
|
|
715
|
+
}
|
|
716
|
+
|
|
701
717
|
function validateCatalogHtmlContent(nodes: QtiContentNode[], diagnostics: QtiDiagnostic[]): void {
|
|
702
718
|
for (const node of nodes) {
|
|
703
719
|
if (node.kind === "element") {
|