@longsightgroup/qti3-core 0.9.3 → 0.9.4
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/README.md +88 -8
- package/dist/adaptive-turn-materializer.d.ts +2 -0
- package/dist/adaptive-turn-materializer.d.ts.map +1 -1
- package/dist/adaptive-turn-materializer.js +25 -19
- package/dist/adaptive-turn-materializer.js.map +1 -1
- package/dist/adaptive-turn.d.ts +8 -1
- package/dist/adaptive-turn.d.ts.map +1 -1
- package/dist/adaptive-turn.js +15 -5
- package/dist/adaptive-turn.js.map +1 -1
- package/dist/delivery-preparation.d.ts +20 -0
- package/dist/delivery-preparation.d.ts.map +1 -0
- package/dist/delivery-preparation.js +71 -0
- package/dist/delivery-preparation.js.map +1 -0
- package/dist/delivery-redaction.d.ts +5 -0
- package/dist/delivery-redaction.d.ts.map +1 -1
- package/dist/delivery-redaction.js +26 -5
- package/dist/delivery-redaction.js.map +1 -1
- package/dist/delivery-security.js +2 -2
- package/dist/delivery-security.js.map +1 -1
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/item-scoring-expectation.d.ts +4 -0
- package/dist/item-scoring-expectation.d.ts.map +1 -0
- package/dist/item-scoring-expectation.js +6 -0
- package/dist/item-scoring-expectation.js.map +1 -0
- package/dist/item-submission-materialization.d.ts +25 -0
- package/dist/item-submission-materialization.d.ts.map +1 -0
- package/dist/item-submission-materialization.js +68 -0
- package/dist/item-submission-materialization.js.map +1 -0
- package/dist/qti-package-assets.d.ts +8 -0
- package/dist/qti-package-assets.d.ts.map +1 -0
- package/dist/qti-package-assets.js +173 -0
- package/dist/qti-package-assets.js.map +1 -0
- package/dist/qti-package-items.d.ts +14 -0
- package/dist/qti-package-items.d.ts.map +1 -0
- package/dist/qti-package-items.js +138 -0
- package/dist/qti-package-items.js.map +1 -0
- package/dist/qti-package-manifest.d.ts +13 -0
- package/dist/qti-package-manifest.d.ts.map +1 -0
- package/dist/qti-package-manifest.js +109 -0
- package/dist/qti-package-manifest.js.map +1 -0
- package/dist/qti-package-metadata.d.ts +8 -0
- package/dist/qti-package-metadata.d.ts.map +1 -0
- package/dist/qti-package-metadata.js +115 -0
- package/dist/qti-package-metadata.js.map +1 -0
- package/dist/qti-package-paths.d.ts +6 -0
- package/dist/qti-package-paths.d.ts.map +1 -0
- package/dist/qti-package-paths.js +32 -0
- package/dist/qti-package-paths.js.map +1 -0
- package/dist/qti-package-types.d.ts +98 -0
- package/dist/qti-package-types.d.ts.map +1 -0
- package/dist/qti-package-types.js +2 -0
- package/dist/qti-package-types.js.map +1 -0
- package/dist/qti-package-xml.d.ts +21 -0
- package/dist/qti-package-xml.d.ts.map +1 -0
- package/dist/qti-package-xml.js +68 -0
- package/dist/qti-package-xml.js.map +1 -0
- package/dist/qti-package-zip.d.ts +24 -0
- package/dist/qti-package-zip.d.ts.map +1 -0
- package/dist/qti-package-zip.js +185 -0
- package/dist/qti-package-zip.js.map +1 -0
- package/dist/qti-package.d.ts +7 -0
- package/dist/qti-package.d.ts.map +1 -0
- package/dist/qti-package.js +76 -0
- package/dist/qti-package.js.map +1 -0
- package/dist/response-input.d.ts +9 -0
- package/dist/response-input.d.ts.map +1 -0
- package/dist/response-input.js +9 -0
- package/dist/response-input.js.map +1 -0
- package/dist/response-validation-policy.d.ts +31 -0
- package/dist/response-validation-policy.d.ts.map +1 -0
- package/dist/response-validation-policy.js +158 -0
- package/dist/response-validation-policy.js.map +1 -0
- package/dist/response-validation.d.ts +23 -0
- package/dist/response-validation.d.ts.map +1 -0
- package/dist/response-validation.js +157 -0
- package/dist/response-validation.js.map +1 -0
- package/dist/scoring-disposition-policy.d.ts +8 -0
- package/dist/scoring-disposition-policy.d.ts.map +1 -0
- package/dist/scoring-disposition-policy.js +24 -0
- package/dist/scoring-disposition-policy.js.map +1 -0
- package/dist/template-presentation-materializer.d.ts +14 -0
- package/dist/template-presentation-materializer.d.ts.map +1 -0
- package/dist/template-presentation-materializer.js +143 -0
- package/dist/template-presentation-materializer.js.map +1 -0
- package/dist/trusted-item-session.d.ts +25 -8
- package/dist/trusted-item-session.d.ts.map +1 -1
- package/dist/trusted-item-session.js +51 -46
- package/dist/trusted-item-session.js.map +1 -1
- package/dist/trusted-session-materialization.d.ts +33 -0
- package/dist/trusted-session-materialization.d.ts.map +1 -0
- package/dist/trusted-session-materialization.js +26 -0
- package/dist/trusted-session-materialization.js.map +1 -0
- package/dist/validation-primitives.d.ts +1 -0
- package/dist/validation-primitives.d.ts.map +1 -1
- package/dist/validation-primitives.js +5 -0
- package/dist/validation-primitives.js.map +1 -1
- package/dist/variable-snapshot.d.ts +9 -0
- package/dist/variable-snapshot.d.ts.map +1 -0
- package/dist/variable-snapshot.js +9 -0
- package/dist/variable-snapshot.js.map +1 -0
- package/package.json +1 -1
- package/src/adaptive-turn-materializer.ts +29 -16
- package/src/adaptive-turn.ts +29 -6
- package/src/delivery-preparation.ts +121 -0
- package/src/delivery-redaction.ts +36 -5
- package/src/delivery-security.ts +2 -2
- package/src/index.ts +65 -0
- package/src/item-scoring-expectation.ts +9 -0
- package/src/item-submission-materialization.ts +120 -0
- package/src/qti-package-assets.ts +256 -0
- package/src/qti-package-items.ts +240 -0
- package/src/qti-package-manifest.ts +210 -0
- package/src/qti-package-metadata.ts +143 -0
- package/src/qti-package-paths.ts +56 -0
- package/src/qti-package-types.ts +117 -0
- package/src/qti-package-xml.ts +97 -0
- package/src/qti-package-zip.ts +325 -0
- package/src/qti-package.ts +176 -0
- package/src/response-input.ts +19 -0
- package/src/response-validation-policy.ts +218 -0
- package/src/response-validation.ts +282 -0
- package/src/scoring-disposition-policy.ts +37 -0
- package/src/template-presentation-materializer.ts +219 -0
- package/src/trusted-item-session.ts +80 -74
- package/src/trusted-session-materialization.ts +67 -0
- package/src/validation-primitives.ts +5 -0
- package/src/variable-snapshot.ts +20 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"trusted-item-session.js","sourceRoot":"","sources":["../src/trusted-item-session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAuB,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"trusted-item-session.js","sourceRoot":"","sources":["../src/trusted-item-session.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { type QtiItemSubmissionScoringDisposition } from "./scoring-disposition-policy.js";
|
|
2
|
+
import type { QtiAssessmentItem, QtiAttemptStateV1, QtiDiagnostic, QtiValue } from "./types.js";
|
|
3
|
+
import { type QtiVariableSnapshot } from "./variable-snapshot.js";
|
|
4
|
+
export interface QtiTrustedSessionMaterialization {
|
|
5
|
+
diagnostics: QtiDiagnostic[];
|
|
6
|
+
state: QtiAttemptStateV1;
|
|
7
|
+
responses: Record<string, QtiValue>;
|
|
8
|
+
outcomes: Record<string, QtiValue>;
|
|
9
|
+
score: number | null;
|
|
10
|
+
candidateSafeXml?: string | undefined;
|
|
11
|
+
}
|
|
12
|
+
export interface QtiItemSubmissionMaterializationSuccess {
|
|
13
|
+
ok: true;
|
|
14
|
+
diagnostics: QtiDiagnostic[];
|
|
15
|
+
state: QtiAttemptStateV1;
|
|
16
|
+
responseVariables: QtiVariableSnapshot[];
|
|
17
|
+
outcomeVariables: QtiVariableSnapshot[];
|
|
18
|
+
score: number | null;
|
|
19
|
+
scoringDisposition: Exclude<QtiItemSubmissionScoringDisposition, "invalid">;
|
|
20
|
+
candidateSafeXml?: string | undefined;
|
|
21
|
+
}
|
|
22
|
+
export interface QtiItemSubmissionMaterializationFailure {
|
|
23
|
+
ok: false;
|
|
24
|
+
diagnostics: QtiDiagnostic[];
|
|
25
|
+
state?: QtiAttemptStateV1 | undefined;
|
|
26
|
+
responseVariables: QtiVariableSnapshot[];
|
|
27
|
+
outcomeVariables: QtiVariableSnapshot[];
|
|
28
|
+
score: null;
|
|
29
|
+
scoringDisposition: "invalid";
|
|
30
|
+
}
|
|
31
|
+
export declare function buildItemSubmissionMaterializationSuccess(item: QtiAssessmentItem, result: QtiTrustedSessionMaterialization): QtiItemSubmissionMaterializationSuccess;
|
|
32
|
+
export declare function buildItemSubmissionMaterializationFailure(diagnostics: QtiDiagnostic[], state?: QtiAttemptStateV1): QtiItemSubmissionMaterializationFailure;
|
|
33
|
+
//# sourceMappingURL=trusted-session-materialization.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trusted-session-materialization.d.ts","sourceRoot":"","sources":["../src/trusted-session-materialization.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,mCAAmC,EACzC,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAChG,OAAO,EAAmC,KAAK,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAEnG,MAAM,WAAW,gCAAgC;IAC/C,WAAW,EAAE,aAAa,EAAE,CAAC;IAC7B,KAAK,EAAE,iBAAiB,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACpC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACnC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACvC;AAED,MAAM,WAAW,uCAAuC;IACtD,EAAE,EAAE,IAAI,CAAC;IACT,WAAW,EAAE,aAAa,EAAE,CAAC;IAC7B,KAAK,EAAE,iBAAiB,CAAC;IACzB,iBAAiB,EAAE,mBAAmB,EAAE,CAAC;IACzC,gBAAgB,EAAE,mBAAmB,EAAE,CAAC;IACxC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,kBAAkB,EAAE,OAAO,CAAC,mCAAmC,EAAE,SAAS,CAAC,CAAC;IAC5E,gBAAgB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACvC;AAED,MAAM,WAAW,uCAAuC;IACtD,EAAE,EAAE,KAAK,CAAC;IACV,WAAW,EAAE,aAAa,EAAE,CAAC;IAC7B,KAAK,CAAC,EAAE,iBAAiB,GAAG,SAAS,CAAC;IACtC,iBAAiB,EAAE,mBAAmB,EAAE,CAAC;IACzC,gBAAgB,EAAE,mBAAmB,EAAE,CAAC;IACxC,KAAK,EAAE,IAAI,CAAC;IACZ,kBAAkB,EAAE,SAAS,CAAC;CAC/B;AAED,wBAAgB,yCAAyC,CACvD,IAAI,EAAE,iBAAiB,EACvB,MAAM,EAAE,gCAAgC,GACvC,uCAAuC,CAWzC;AAED,wBAAgB,yCAAyC,CACvD,WAAW,EAAE,aAAa,EAAE,EAC5B,KAAK,CAAC,EAAE,iBAAiB,GACxB,uCAAuC,CAUzC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { classifyQtiItemScoringDisposition, } from "./scoring-disposition-policy.js";
|
|
2
|
+
import { snapshotQtiVariableDeclarations } from "./variable-snapshot.js";
|
|
3
|
+
export function buildItemSubmissionMaterializationSuccess(item, result) {
|
|
4
|
+
return {
|
|
5
|
+
ok: true,
|
|
6
|
+
diagnostics: result.diagnostics,
|
|
7
|
+
state: result.state,
|
|
8
|
+
responseVariables: snapshotQtiVariableDeclarations(item.responseDeclarations, result.responses),
|
|
9
|
+
outcomeVariables: snapshotQtiVariableDeclarations(item.outcomeDeclarations, result.outcomes),
|
|
10
|
+
score: result.score,
|
|
11
|
+
scoringDisposition: classifyQtiItemScoringDisposition(item, result.score),
|
|
12
|
+
candidateSafeXml: result.candidateSafeXml,
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
export function buildItemSubmissionMaterializationFailure(diagnostics, state) {
|
|
16
|
+
return {
|
|
17
|
+
ok: false,
|
|
18
|
+
diagnostics,
|
|
19
|
+
state,
|
|
20
|
+
responseVariables: [],
|
|
21
|
+
outcomeVariables: [],
|
|
22
|
+
score: null,
|
|
23
|
+
scoringDisposition: "invalid",
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=trusted-session-materialization.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trusted-session-materialization.js","sourceRoot":"","sources":["../src/trusted-session-materialization.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iCAAiC,GAElC,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EAAE,+BAA+B,EAA4B,MAAM,wBAAwB,CAAC;AAgCnG,MAAM,UAAU,yCAAyC,CACvD,IAAuB,EACvB,MAAwC;IAExC,OAAO;QACL,EAAE,EAAE,IAAI;QACR,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,iBAAiB,EAAE,+BAA+B,CAAC,IAAI,CAAC,oBAAoB,EAAE,MAAM,CAAC,SAAS,CAAC;QAC/F,gBAAgB,EAAE,+BAA+B,CAAC,IAAI,CAAC,mBAAmB,EAAE,MAAM,CAAC,QAAQ,CAAC;QAC5F,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,kBAAkB,EAAE,iCAAiC,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC;QACzE,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;KAC1C,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,yCAAyC,CACvD,WAA4B,EAC5B,KAAyB;IAEzB,OAAO;QACL,EAAE,EAAE,KAAK;QACT,WAAW;QACX,KAAK;QACL,iBAAiB,EAAE,EAAE;QACrB,gBAAgB,EAAE,EAAE;QACpB,KAAK,EAAE,IAAI;QACX,kBAAkB,EAAE,SAAS;KAC9B,CAAC;AACJ,CAAC"}
|
|
@@ -5,6 +5,7 @@ export declare function isBaseType(value: string): value is QtiBaseType;
|
|
|
5
5
|
export declare function isFiniteNumber(value: string): boolean;
|
|
6
6
|
export declare function isInteger(value: string): boolean;
|
|
7
7
|
export declare function isNonNegativeInteger(value: string): boolean;
|
|
8
|
+
export declare function parseNonNegativeInteger(value: string | undefined): number | undefined;
|
|
8
9
|
export declare function isBooleanAttribute(value: string): boolean;
|
|
9
10
|
export declare function isPoint(value: string): boolean;
|
|
10
11
|
export declare function isPair(value: string): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation-primitives.d.ts","sourceRoot":"","sources":["../src/validation-primitives.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE7E,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,WAAW,EAAE,aAAa,EAAE,EAC5B,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,GAC9B,IAAI,CASN;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,cAAc,CAEpE;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,WAAW,CAc9D;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAErD;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEhD;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAE3D;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAG9C;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAG7C"}
|
|
1
|
+
{"version":3,"file":"validation-primitives.d.ts","sourceRoot":"","sources":["../src/validation-primitives.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE7E,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,WAAW,EAAE,aAAa,EAAE,EAC5B,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,GAC9B,IAAI,CASN;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,cAAc,CAEpE;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,WAAW,CAc9D;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAErD;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEhD;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAE3D;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAGrF;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAG9C;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAG7C"}
|
|
@@ -34,6 +34,11 @@ export function isInteger(value) {
|
|
|
34
34
|
export function isNonNegativeInteger(value) {
|
|
35
35
|
return /^\d+$/.test(value);
|
|
36
36
|
}
|
|
37
|
+
export function parseNonNegativeInteger(value) {
|
|
38
|
+
if (value === undefined || !isNonNegativeInteger(value))
|
|
39
|
+
return undefined;
|
|
40
|
+
return Number(value);
|
|
41
|
+
}
|
|
37
42
|
export function isBooleanAttribute(value) {
|
|
38
43
|
return value === "true" || value === "false" || value === "1" || value === "0";
|
|
39
44
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation-primitives.js","sourceRoot":"","sources":["../src/validation-primitives.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,iBAAiB,CAC/B,OAAe,EACf,UAA8B,EAC9B,WAA4B,EAC5B,MAA+B;IAE/B,IAAI,UAAU,EAAE,IAAI,EAAE;QAAE,OAAO;IAC/B,WAAW,CAAC,IAAI,CAAC;QACf,IAAI,EAAE,qBAAqB;QAC3B,QAAQ,EAAE,OAAO;QACjB,OAAO,EAAE,GAAG,OAAO,mCAAmC;QACtD,IAAI,EAAE,MAAM,EAAE,IAAI;QAClB,MAAM;KACP,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,UAAU,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,QAAQ,CAAC;AACjG,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAa;IACtC,OAAO,CACL,KAAK,KAAK,YAAY;QACtB,KAAK,KAAK,SAAS;QACnB,KAAK,KAAK,SAAS;QACnB,KAAK,KAAK,OAAO;QACjB,KAAK,KAAK,QAAQ;QAClB,KAAK,KAAK,OAAO;QACjB,KAAK,KAAK,MAAM;QAChB,KAAK,KAAK,cAAc;QACxB,KAAK,KAAK,UAAU;QACpB,KAAK,KAAK,MAAM;QAChB,KAAK,KAAK,KAAK,CAChB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,KAAa;IAC1C,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;AACxC,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,KAAa;IACrC,OAAO,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,KAAa;IAChD,OAAO,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,KAAa;IAC9C,OAAO,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,OAAO,IAAI,KAAK,KAAK,GAAG,IAAI,KAAK,KAAK,GAAG,CAAC;AACjF,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,KAAa;IACnC,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACxC,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;AAC3D,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,KAAa;IAClC,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACxC,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACtE,CAAC"}
|
|
1
|
+
{"version":3,"file":"validation-primitives.js","sourceRoot":"","sources":["../src/validation-primitives.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,iBAAiB,CAC/B,OAAe,EACf,UAA8B,EAC9B,WAA4B,EAC5B,MAA+B;IAE/B,IAAI,UAAU,EAAE,IAAI,EAAE;QAAE,OAAO;IAC/B,WAAW,CAAC,IAAI,CAAC;QACf,IAAI,EAAE,qBAAqB;QAC3B,QAAQ,EAAE,OAAO;QACjB,OAAO,EAAE,GAAG,OAAO,mCAAmC;QACtD,IAAI,EAAE,MAAM,EAAE,IAAI;QAClB,MAAM;KACP,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,UAAU,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,QAAQ,CAAC;AACjG,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAa;IACtC,OAAO,CACL,KAAK,KAAK,YAAY;QACtB,KAAK,KAAK,SAAS;QACnB,KAAK,KAAK,SAAS;QACnB,KAAK,KAAK,OAAO;QACjB,KAAK,KAAK,QAAQ;QAClB,KAAK,KAAK,OAAO;QACjB,KAAK,KAAK,MAAM;QAChB,KAAK,KAAK,cAAc;QACxB,KAAK,KAAK,UAAU;QACpB,KAAK,KAAK,MAAM;QAChB,KAAK,KAAK,KAAK,CAChB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,KAAa;IAC1C,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;AACxC,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,KAAa;IACrC,OAAO,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,KAAa;IAChD,OAAO,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,KAAyB;IAC/D,IAAI,KAAK,KAAK,SAAS,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAC1E,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,KAAa;IAC9C,OAAO,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,OAAO,IAAI,KAAK,KAAK,GAAG,IAAI,KAAK,KAAK,GAAG,CAAC;AACjF,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,KAAa;IACnC,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACxC,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;AAC3D,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,KAAa;IAClC,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACxC,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACtE,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { QtiBaseType, QtiCardinality, QtiValue, QtiVariableDeclaration } from "./types.js";
|
|
2
|
+
export interface QtiVariableSnapshot {
|
|
3
|
+
identifier: string;
|
|
4
|
+
value: QtiValue;
|
|
5
|
+
cardinality: QtiCardinality;
|
|
6
|
+
baseType?: QtiBaseType | undefined;
|
|
7
|
+
}
|
|
8
|
+
export declare function snapshotQtiVariableDeclarations(declarations: readonly QtiVariableDeclaration[], values: Record<string, QtiValue>): QtiVariableSnapshot[];
|
|
9
|
+
//# sourceMappingURL=variable-snapshot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"variable-snapshot.d.ts","sourceRoot":"","sources":["../src/variable-snapshot.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,QAAQ,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAEhG,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,QAAQ,CAAC;IAChB,WAAW,EAAE,cAAc,CAAC;IAC5B,QAAQ,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;CACpC;AAED,wBAAgB,+BAA+B,CAC7C,YAAY,EAAE,SAAS,sBAAsB,EAAE,EAC/C,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,GAC/B,mBAAmB,EAAE,CAOvB"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export function snapshotQtiVariableDeclarations(declarations, values) {
|
|
2
|
+
return declarations.map((declaration) => ({
|
|
3
|
+
identifier: declaration.identifier,
|
|
4
|
+
value: values[declaration.identifier] ?? null,
|
|
5
|
+
cardinality: declaration.cardinality,
|
|
6
|
+
baseType: declaration.baseType,
|
|
7
|
+
}));
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=variable-snapshot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"variable-snapshot.js","sourceRoot":"","sources":["../src/variable-snapshot.ts"],"names":[],"mappings":"AASA,MAAM,UAAU,+BAA+B,CAC7C,YAA+C,EAC/C,MAAgC;IAEhC,OAAO,YAAY,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QACxC,UAAU,EAAE,WAAW,CAAC,UAAU;QAClC,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC,UAAU,CAAC,IAAI,IAAI;QAC7C,WAAW,EAAE,WAAW,CAAC,WAAW;QACpC,QAAQ,EAAE,WAAW,CAAC,QAAQ;KAC/B,CAAC,CAAC,CAAC;AACN,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,25 +1,27 @@
|
|
|
1
1
|
import {
|
|
2
2
|
FORBIDDEN_DELIVERY_SECRET_ELEMENT_NAMES,
|
|
3
|
+
analyzeDeliveryXml,
|
|
3
4
|
isDeclarationDefaultValue,
|
|
5
|
+
parseDeliveryXml,
|
|
4
6
|
redactDeliveryXml,
|
|
5
7
|
type DeliveryRedactionPolicy,
|
|
6
8
|
type QtiDeliverySecurityAnalysis,
|
|
7
9
|
type QtiDeliverySecurityFindingKind,
|
|
8
10
|
} from "./delivery-redaction.js";
|
|
11
|
+
import { materializeTemplatePresentation } from "./template-presentation-materializer.js";
|
|
9
12
|
import type { QtiDiagnostic, QtiValue } from "./types.js";
|
|
10
13
|
import { qtiValueToString } from "./value-format.js";
|
|
11
14
|
import type { XmlNode } from "./xml.js";
|
|
12
15
|
|
|
13
|
-
const
|
|
14
|
-
"template-processing",
|
|
15
|
-
"set-correct-response",
|
|
16
|
-
]);
|
|
16
|
+
const TEMPLATE_PROCESSING_ELEMENT_NAMES = new Set(["template-processing", "set-correct-response"]);
|
|
17
17
|
|
|
18
18
|
const FEEDBACK_ELEMENT_NAMES = new Set(["feedback-inline", "feedback-block", "modal-feedback"]);
|
|
19
19
|
|
|
20
20
|
export interface QtiAdaptiveCandidateMaterializationInput {
|
|
21
21
|
itemXml: string;
|
|
22
22
|
outcomes: Record<string, QtiValue>;
|
|
23
|
+
templateValues?: Record<string, QtiValue>;
|
|
24
|
+
responses?: Record<string, QtiValue>;
|
|
23
25
|
}
|
|
24
26
|
|
|
25
27
|
export interface QtiAdaptiveCandidateMaterializationResult {
|
|
@@ -32,7 +34,22 @@ export interface QtiAdaptiveCandidateMaterializationResult {
|
|
|
32
34
|
export function materializeAdaptiveCandidateView(
|
|
33
35
|
input: QtiAdaptiveCandidateMaterializationInput,
|
|
34
36
|
): QtiAdaptiveCandidateMaterializationResult {
|
|
35
|
-
|
|
37
|
+
const policy = adaptiveMaterializationPolicy(input.outcomes);
|
|
38
|
+
const templateMaterialization = materializeTemplatePresentation(input.itemXml, {
|
|
39
|
+
outcomes: input.outcomes,
|
|
40
|
+
templateValues: input.templateValues ?? {},
|
|
41
|
+
responses: input.responses,
|
|
42
|
+
});
|
|
43
|
+
if (!templateMaterialization.ok) {
|
|
44
|
+
const analysis = analyzeDeliveryXml(parseDeliveryXml(input.itemXml), policy);
|
|
45
|
+
const diagnostics = [...templateMaterialization.diagnostics, ...analysis.diagnostics];
|
|
46
|
+
return {
|
|
47
|
+
ok: false,
|
|
48
|
+
diagnostics,
|
|
49
|
+
analysis,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
return redactDeliveryXml(templateMaterialization.xml, policy);
|
|
36
53
|
}
|
|
37
54
|
|
|
38
55
|
function shouldPreserveFeedback(node: XmlNode, outcomes: Record<string, QtiValue>): boolean {
|
|
@@ -57,28 +74,24 @@ function adaptiveMaterializationPolicy(
|
|
|
57
74
|
isForbiddenElement(node, normalizedName) {
|
|
58
75
|
if (isFeedbackElement(normalizedName)) return !shouldPreserveFeedback(node, outcomes);
|
|
59
76
|
return (
|
|
77
|
+
TEMPLATE_PROCESSING_ELEMENT_NAMES.has(normalizedName) ||
|
|
60
78
|
FORBIDDEN_DELIVERY_SECRET_ELEMENT_NAMES.has(normalizedName) ||
|
|
61
79
|
isDeclarationDefaultValue(node, normalizedName)
|
|
62
80
|
);
|
|
63
81
|
},
|
|
64
|
-
unsupportedFinding(
|
|
65
|
-
|
|
66
|
-
return {
|
|
67
|
-
kind: "unsupported-secure-delivery-element",
|
|
68
|
-
qtiName: node.name,
|
|
69
|
-
localName: node.localName,
|
|
70
|
-
message: `${node.name} is not supported by adaptive candidate materialization v1.`,
|
|
71
|
-
source: node.source,
|
|
72
|
-
};
|
|
82
|
+
unsupportedFinding() {
|
|
83
|
+
return null;
|
|
73
84
|
},
|
|
74
|
-
diagnosticCodeForFinding,
|
|
85
|
+
diagnosticCodeForFinding: adaptiveMaterializationDiagnosticCodeForFinding,
|
|
75
86
|
forbiddenElementMessage(node) {
|
|
76
87
|
return `${node.name} exposes answer keys, scoring, mapping, feedback, or solution information during adaptive delivery.`;
|
|
77
88
|
},
|
|
78
89
|
};
|
|
79
90
|
}
|
|
80
91
|
|
|
81
|
-
function
|
|
92
|
+
function adaptiveMaterializationDiagnosticCodeForFinding(
|
|
93
|
+
kind: QtiDeliverySecurityFindingKind,
|
|
94
|
+
): string {
|
|
82
95
|
return kind === "unsupported-secure-delivery-element"
|
|
83
96
|
? "adaptiveTurn.materialization.unsupported"
|
|
84
97
|
: "adaptiveTurn.materialization.forbiddenElement";
|
package/src/adaptive-turn.ts
CHANGED
|
@@ -3,9 +3,12 @@ import type { QtiAttemptStateV1, QtiDiagnostic, QtiValue } from "./types.js";
|
|
|
3
3
|
import {
|
|
4
4
|
readPriorAttemptState,
|
|
5
5
|
runTrustedItemSession,
|
|
6
|
+
type QtiTrustedInputDiagnosticPrefix,
|
|
7
|
+
type QtiTrustedItemDocument,
|
|
6
8
|
type QtiTrustedItemParseOptions,
|
|
7
|
-
type QtiTrustedResponseApplication,
|
|
8
9
|
type QtiTrustedResponseInput,
|
|
10
|
+
type QtiTrustedResponseApplication,
|
|
11
|
+
type QtiTrustedSubmissionValidation,
|
|
9
12
|
} from "./trusted-item-session.js";
|
|
10
13
|
|
|
11
14
|
export type QtiAdaptiveTurnResponseInput = QtiTrustedResponseInput;
|
|
@@ -20,6 +23,13 @@ export interface QtiAdaptiveTurnInput
|
|
|
20
23
|
priorState?: unknown;
|
|
21
24
|
}
|
|
22
25
|
|
|
26
|
+
export interface TrustedAdaptiveItemTurnInput extends QtiAdaptiveTurnInput {
|
|
27
|
+
parsedItem?: QtiTrustedItemDocument | undefined;
|
|
28
|
+
diagnosticPrefix: QtiTrustedInputDiagnosticPrefix;
|
|
29
|
+
submissionValidation?: QtiTrustedSubmissionValidation | undefined;
|
|
30
|
+
allowIncompleteResponses?: boolean | undefined;
|
|
31
|
+
}
|
|
32
|
+
|
|
23
33
|
export interface QtiAdaptiveTurnResult {
|
|
24
34
|
ok: boolean;
|
|
25
35
|
diagnostics: QtiDiagnostic[];
|
|
@@ -32,14 +42,22 @@ export interface QtiAdaptiveTurnResult {
|
|
|
32
42
|
}
|
|
33
43
|
|
|
34
44
|
export function processQtiAdaptiveItemTurn(input: QtiAdaptiveTurnInput): QtiAdaptiveTurnResult {
|
|
35
|
-
|
|
45
|
+
return runTrustedAdaptiveItemTurn({ ...input, diagnosticPrefix: "adaptiveTurn" });
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function runTrustedAdaptiveItemTurn(
|
|
49
|
+
input: TrustedAdaptiveItemTurnInput,
|
|
50
|
+
): QtiAdaptiveTurnResult {
|
|
51
|
+
const diagnosticPrefix = input.diagnosticPrefix;
|
|
52
|
+
const priorStateResult = readPriorAttemptState(input.priorState, diagnosticPrefix);
|
|
36
53
|
if (priorStateResult.diagnostics.some((diagnostic) => diagnostic.severity === "error")) {
|
|
37
54
|
return failed(priorStateResult.diagnostics);
|
|
38
55
|
}
|
|
39
56
|
|
|
40
57
|
const sessionResult = runTrustedItemSession({
|
|
41
58
|
itemXml: input.itemXml,
|
|
42
|
-
|
|
59
|
+
parsedItem: input.parsedItem,
|
|
60
|
+
diagnosticPrefix,
|
|
43
61
|
allowedUndeclaredResponseIdentifiers: input.allowedUndeclaredResponseIdentifiers,
|
|
44
62
|
priorState: priorStateResult.state,
|
|
45
63
|
submission: {
|
|
@@ -48,6 +66,8 @@ export function processQtiAdaptiveItemTurn(input: QtiAdaptiveTurnInput): QtiAdap
|
|
|
48
66
|
},
|
|
49
67
|
scoring: "onSubmission",
|
|
50
68
|
requireNumericScore: true,
|
|
69
|
+
submissionValidation: input.submissionValidation,
|
|
70
|
+
allowIncompleteResponses: input.allowIncompleteResponses,
|
|
51
71
|
});
|
|
52
72
|
if (!sessionResult.ok) {
|
|
53
73
|
return failed(
|
|
@@ -61,14 +81,17 @@ export function processQtiAdaptiveItemTurn(input: QtiAdaptiveTurnInput): QtiAdap
|
|
|
61
81
|
const delivery = materializeAdaptiveCandidateView({
|
|
62
82
|
itemXml: input.itemXml,
|
|
63
83
|
outcomes: sessionResult.outcomes,
|
|
84
|
+
responses: sessionResult.responses,
|
|
85
|
+
templateValues: sessionResult.state.templateValues ?? {},
|
|
64
86
|
});
|
|
65
87
|
const deliveryDiagnostics = [...sessionResult.diagnostics, ...delivery.diagnostics];
|
|
66
|
-
|
|
88
|
+
const candidateSafeXml = delivery.xml;
|
|
89
|
+
if (!delivery.ok || !candidateSafeXml) {
|
|
67
90
|
return failed(
|
|
68
91
|
[
|
|
69
92
|
...deliveryDiagnostics,
|
|
70
93
|
{
|
|
71
|
-
code:
|
|
94
|
+
code: `${diagnosticPrefix}.delivery.materialization`,
|
|
72
95
|
severity: "error",
|
|
73
96
|
message: "Adaptive turn did not produce candidate-safe item XML.",
|
|
74
97
|
},
|
|
@@ -87,7 +110,7 @@ export function processQtiAdaptiveItemTurn(input: QtiAdaptiveTurnInput): QtiAdap
|
|
|
87
110
|
outcomes: sessionResult.outcomes,
|
|
88
111
|
score: sessionResult.score,
|
|
89
112
|
completionStatus: sessionResult.outcomes.completionStatus ?? null,
|
|
90
|
-
candidateSafeXml
|
|
113
|
+
candidateSafeXml,
|
|
91
114
|
};
|
|
92
115
|
}
|
|
93
116
|
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { materializeAdaptiveCandidateView } from "./adaptive-turn-materializer.js";
|
|
2
|
+
import type {
|
|
3
|
+
QtiDeliverySecurityAnalysis,
|
|
4
|
+
QtiDeliverySecurityFindingKind,
|
|
5
|
+
RedactedDeliveryXmlResult,
|
|
6
|
+
} from "./delivery-redaction.js";
|
|
7
|
+
import { buildQtiDeliverySafeXml } from "./delivery-security.js";
|
|
8
|
+
import type { QtiDiagnostic, QtiValue } from "./types.js";
|
|
9
|
+
|
|
10
|
+
export type QtiDeliveryPreparationMode = "static" | "server-materialized-adaptive";
|
|
11
|
+
|
|
12
|
+
export type QtiDeliveryPreparationOptions =
|
|
13
|
+
| { mode: "static" }
|
|
14
|
+
| {
|
|
15
|
+
mode: "server-materialized-adaptive";
|
|
16
|
+
outcomes: Record<string, QtiValue>;
|
|
17
|
+
templateValues?: Record<string, QtiValue>;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export interface QtiDeliveryPreparationResult {
|
|
21
|
+
ok: boolean;
|
|
22
|
+
mode: QtiDeliveryPreparationMode;
|
|
23
|
+
diagnostics: QtiDeliverySecurityAnalysis["diagnostics"];
|
|
24
|
+
analysis: QtiDeliverySecurityAnalysis;
|
|
25
|
+
candidateSafeXml?: string | undefined;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** Prepare candidate-safe XML for a supported QTI delivery mode. */
|
|
29
|
+
export function prepareQtiDeliveryXml(
|
|
30
|
+
xml: string,
|
|
31
|
+
options: QtiDeliveryPreparationOptions,
|
|
32
|
+
): QtiDeliveryPreparationResult {
|
|
33
|
+
const redaction =
|
|
34
|
+
options.mode === "static"
|
|
35
|
+
? buildQtiDeliverySafeXml(xml)
|
|
36
|
+
: materializeAdaptiveCandidateView({
|
|
37
|
+
itemXml: xml,
|
|
38
|
+
outcomes: options.outcomes,
|
|
39
|
+
...(options.templateValues === undefined
|
|
40
|
+
? {}
|
|
41
|
+
: { templateValues: options.templateValues }),
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
return {
|
|
45
|
+
ok: redaction.ok,
|
|
46
|
+
mode: options.mode,
|
|
47
|
+
diagnostics: normalizePreparationDiagnostics(redaction, options.mode),
|
|
48
|
+
analysis: redaction.analysis,
|
|
49
|
+
candidateSafeXml: redaction.xml,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function normalizePreparationDiagnostics(
|
|
54
|
+
redaction: RedactedDeliveryXmlResult,
|
|
55
|
+
mode: QtiDeliveryPreparationMode,
|
|
56
|
+
): QtiDiagnostic[] {
|
|
57
|
+
const findingCodes = redaction.analysis.findings.map((finding) =>
|
|
58
|
+
preparationDiagnosticCodeForFinding(finding.kind, mode),
|
|
59
|
+
);
|
|
60
|
+
let findingIndex = 0;
|
|
61
|
+
|
|
62
|
+
return redaction.diagnostics.map((diagnostic) => {
|
|
63
|
+
if (!isDeliveryFindingDiagnosticCode(diagnostic.code)) return diagnostic;
|
|
64
|
+
|
|
65
|
+
if (diagnostic.code === "adaptiveTurn.materialization.unsupported") {
|
|
66
|
+
return {
|
|
67
|
+
...diagnostic,
|
|
68
|
+
code: preparationDiagnosticCodeForLowerLevelCode(diagnostic.code, mode),
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const code = findingCodes[findingIndex];
|
|
73
|
+
findingIndex += 1;
|
|
74
|
+
|
|
75
|
+
return {
|
|
76
|
+
...diagnostic,
|
|
77
|
+
code: code ?? preparationDiagnosticCodeForLowerLevelCode(diagnostic.code, mode),
|
|
78
|
+
};
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function preparationDiagnosticCodeForFinding(
|
|
83
|
+
kind: QtiDeliverySecurityFindingKind,
|
|
84
|
+
mode: QtiDeliveryPreparationMode,
|
|
85
|
+
): string {
|
|
86
|
+
if (kind === "forbidden-delivery-element") return "delivery.preparation.forbiddenElement";
|
|
87
|
+
if (kind === "unsupported-adaptive-response-processing") {
|
|
88
|
+
return "delivery.preparation.unsupportedAdaptiveResponseProcessing";
|
|
89
|
+
}
|
|
90
|
+
return mode === "server-materialized-adaptive"
|
|
91
|
+
? "delivery.preparation.unsupportedMaterialization"
|
|
92
|
+
: "delivery.preparation.unsupportedSecureDelivery";
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function isDeliveryFindingDiagnosticCode(code: string): boolean {
|
|
96
|
+
return (
|
|
97
|
+
code === "delivery.forbiddenElement" ||
|
|
98
|
+
code === "delivery.unsupportedSecureDelivery" ||
|
|
99
|
+
code === "delivery.unsupportedAdaptiveResponseProcessing" ||
|
|
100
|
+
code === "adaptiveTurn.materialization.forbiddenElement" ||
|
|
101
|
+
code === "adaptiveTurn.materialization.unsupported"
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function preparationDiagnosticCodeForLowerLevelCode(
|
|
106
|
+
code: string,
|
|
107
|
+
mode: QtiDeliveryPreparationMode,
|
|
108
|
+
): string {
|
|
109
|
+
if (
|
|
110
|
+
code === "delivery.forbiddenElement" ||
|
|
111
|
+
code === "adaptiveTurn.materialization.forbiddenElement"
|
|
112
|
+
) {
|
|
113
|
+
return "delivery.preparation.forbiddenElement";
|
|
114
|
+
}
|
|
115
|
+
if (code === "delivery.unsupportedAdaptiveResponseProcessing") {
|
|
116
|
+
return "delivery.preparation.unsupportedAdaptiveResponseProcessing";
|
|
117
|
+
}
|
|
118
|
+
return mode === "server-materialized-adaptive"
|
|
119
|
+
? "delivery.preparation.unsupportedMaterialization"
|
|
120
|
+
: "delivery.preparation.unsupportedSecureDelivery";
|
|
121
|
+
}
|
|
@@ -167,7 +167,13 @@ export function redactDeliveryXml(
|
|
|
167
167
|
[parsed.root, ...descendants(parsed.root, () => true)],
|
|
168
168
|
(node, normalizedName) => policy.isForbiddenElement(node, normalizedName),
|
|
169
169
|
);
|
|
170
|
-
const redactedXml =
|
|
170
|
+
const redactedXml = applySourceRangeEdits(
|
|
171
|
+
xml,
|
|
172
|
+
redactionRanges.map((range) => ({
|
|
173
|
+
startOffset: range.startOffset,
|
|
174
|
+
endOffset: range.endOffset,
|
|
175
|
+
})),
|
|
176
|
+
);
|
|
171
177
|
const redactedAnalysis = analyzeDeliveryXml(parseDeliveryXml(redactedXml), policy);
|
|
172
178
|
if (!redactedAnalysis.deliverySafe || !redactedAnalysis.secureDeliverySupported) {
|
|
173
179
|
return {
|
|
@@ -203,16 +209,36 @@ export function sourceRangeFor(node: XmlNode): RedactionRange[] {
|
|
|
203
209
|
return [{ startOffset: node.sourceRange.startOffset, endOffset }];
|
|
204
210
|
}
|
|
205
211
|
|
|
206
|
-
export function
|
|
212
|
+
export function applySourceRangeEdits(xml: string, edits: readonly SourceRangeEdit[]): string {
|
|
213
|
+
if (edits.length === 0) return xml;
|
|
214
|
+
const sorted = edits.toSorted((left, right) => left.startOffset - right.startOffset);
|
|
215
|
+
assertNonOverlappingSourceRangeEdits(sorted);
|
|
207
216
|
let output = "";
|
|
208
217
|
let cursor = 0;
|
|
209
|
-
for (const
|
|
210
|
-
output += xml.slice(cursor,
|
|
211
|
-
|
|
218
|
+
for (const edit of sorted) {
|
|
219
|
+
output += xml.slice(cursor, edit.startOffset);
|
|
220
|
+
if (edit.text !== undefined) output += edit.text;
|
|
221
|
+
cursor = edit.endOffset;
|
|
212
222
|
}
|
|
213
223
|
return output + xml.slice(cursor);
|
|
214
224
|
}
|
|
215
225
|
|
|
226
|
+
function assertNonOverlappingSourceRangeEdits(edits: readonly SourceRangeEdit[]): void {
|
|
227
|
+
for (let index = 1; index < edits.length; index += 1) {
|
|
228
|
+
const previous = edits[index - 1];
|
|
229
|
+
const current = edits[index];
|
|
230
|
+
if (!previous || !current || current.startOffset >= previous.endOffset) continue;
|
|
231
|
+
throw new Error("Source range edits must not overlap.");
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
export function removeSourceRanges(xml: string, ranges: readonly RedactionRange[]): string {
|
|
236
|
+
return applySourceRangeEdits(
|
|
237
|
+
xml,
|
|
238
|
+
ranges.map((range) => ({ startOffset: range.startOffset, endOffset: range.endOffset })),
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
|
|
216
242
|
export function normalizedQtiElementName(localName: string): string {
|
|
217
243
|
const lower = localName.toLowerCase();
|
|
218
244
|
return lower.startsWith("qti-") ? lower.slice("qti-".length) : lower;
|
|
@@ -240,6 +266,11 @@ export interface RedactionRange {
|
|
|
240
266
|
endOffset: number;
|
|
241
267
|
}
|
|
242
268
|
|
|
269
|
+
export interface SourceRangeEdit extends RedactionRange {
|
|
270
|
+
/** When omitted, the source range is removed. When set, the range is replaced with this text. */
|
|
271
|
+
text?: string | undefined;
|
|
272
|
+
}
|
|
273
|
+
|
|
243
274
|
function mergeSourceRanges(ranges: readonly RedactionRange[]): RedactionRange[] {
|
|
244
275
|
const sorted = ranges.toSorted((left, right) => left.startOffset - right.startOffset);
|
|
245
276
|
const merged: RedactionRange[] = [];
|
package/src/delivery-security.ts
CHANGED
|
@@ -82,13 +82,13 @@ const staticDeliveryPolicy: DeliveryRedactionPolicy = {
|
|
|
82
82
|
|
|
83
83
|
return null;
|
|
84
84
|
},
|
|
85
|
-
diagnosticCodeForFinding,
|
|
85
|
+
diagnosticCodeForFinding: staticDiagnosticCodeForFinding,
|
|
86
86
|
forbiddenElementMessage(node: XmlNode) {
|
|
87
87
|
return `${node.name} exposes answer keys, scoring, mapping, feedback, or solution information during delivery.`;
|
|
88
88
|
},
|
|
89
89
|
};
|
|
90
90
|
|
|
91
|
-
function
|
|
91
|
+
function staticDiagnosticCodeForFinding(kind: QtiDeliverySecurityFindingKind): string {
|
|
92
92
|
if (kind === "forbidden-delivery-element") return "delivery.forbiddenElement";
|
|
93
93
|
if (kind === "unsupported-adaptive-response-processing") {
|
|
94
94
|
return "delivery.unsupportedAdaptiveResponseProcessing";
|