@memizy/oqse 1.0.0-rc.6 → 1.0.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/CHANGELOG.md +22 -0
- package/README.md +1 -1
- package/dist/checkAnswer.cjs +1 -1
- package/dist/checkAnswer.js +79 -76
- package/dist/compatibility.cjs +1 -1
- package/dist/compatibility.js +26 -24
- package/dist/fileValidation.cjs +2 -2
- package/dist/fileValidation.js +301 -122
- package/dist/headerValidation.cjs +1 -1
- package/dist/headerValidation.js +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +21 -19
- package/dist/knownProperties.generated.cjs +1 -0
- package/dist/knownProperties.generated.js +218 -0
- package/dist/manifestValidation.cjs +1 -1
- package/dist/manifestValidation.js +42 -52
- package/dist/mustUnderstand.cjs +1 -0
- package/dist/mustUnderstand.js +11 -0
- package/dist/oqse.cjs +1 -1
- package/dist/oqse.js +59 -29
- package/dist/oqseValidation.cjs +1 -1
- package/dist/oqseValidation.js +321 -362
- package/dist/progressValidation.cjs +1 -1
- package/dist/progressValidation.js +23 -14
- package/dist/src/fileValidation.d.ts +35 -5
- package/dist/src/index.d.ts +2 -0
- package/dist/src/knownProperties.generated.d.ts +2 -0
- package/dist/src/knownPropertiesSource.d.ts +10 -0
- package/dist/src/manifest.d.ts +9 -9
- package/dist/src/manifestValidation.d.ts +13 -28
- package/dist/src/mustUnderstand.d.ts +15 -0
- package/dist/src/oqse.d.ts +53 -22
- package/dist/src/oqseValidation.d.ts +656 -2335
- package/dist/src/progress.d.ts +4 -0
- package/dist/src/progressValidation.d.ts +2 -0
- package/dist/src/propertyPaths.d.ts +14 -0
- package/dist/src/utils.d.ts +8 -0
- package/dist/utils.cjs +1 -1
- package/dist/utils.js +7 -6
- package/oqse-header.md +1 -0
- package/oqse-manifest.md +10 -7
- package/oqse-progress.md +8 -4
- package/oqse.md +85 -41
- package/package.json +2 -2
- package/schemas/oqse-header-v1.0.json +4 -5
- package/schemas/oqse-manifest-v1.0.json +7 -14
- package/schemas/oqse-progress-v1.0.json +15 -11
- package/schemas/oqse-v1.0.json +494 -733
package/dist/fileValidation.js
CHANGED
|
@@ -1,187 +1,366 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { formatPath as
|
|
3
|
-
import { OQSEMetaSchema as
|
|
4
|
-
import { OFFICIAL_FEATURE_KEYS as
|
|
5
|
-
import { findHeadings as
|
|
6
|
-
import { findAssetKeys as
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
1
|
+
import { BLOOM_LEVELS as e, COGNITIVE_LOADS as t, MEDIA_TYPES as n, OFFICIAL_ITEM_TYPES as r, SOURCE_KINDS as i, SUBTITLE_KINDS as a } from "./oqse.js";
|
|
2
|
+
import { MAX_ITEMS as o, formatPath as s, validateJsonDepth as c } from "./utils.js";
|
|
3
|
+
import { OQSEMetaSchema as l, SourceMaterialSchema as u, UnknownTypeItemSchema as d, getItemSchema as f } from "./oqseValidation.js";
|
|
4
|
+
import { OFFICIAL_FEATURE_KEYS as p, OFFICIAL_ITEM_PROPERTIES as m, OFFICIAL_META_PROPERTIES as h } from "./manifest.js";
|
|
5
|
+
import { findHeadings as g, splitLines as _ } from "./markdownUtils.js";
|
|
6
|
+
import { findAssetKeys as v, findRawHtml as y } from "./richTextProcessor.js";
|
|
7
|
+
import { missingMustUnderstand as b } from "./mustUnderstand.js";
|
|
8
|
+
import { resolveAsset as x } from "./assets.js";
|
|
9
|
+
import { itemRichText as S, metaRichText as C } from "./richTextFields.js";
|
|
10
|
+
import { detectFeatures as w, looksLikeLatex as T } from "./features.js";
|
|
10
11
|
//#region src/fileValidation.ts
|
|
11
|
-
var
|
|
12
|
+
var E = class extends Error {
|
|
12
13
|
errors;
|
|
13
14
|
warnings;
|
|
14
15
|
constructor(e, t) {
|
|
15
|
-
super(`Invalid OQSE file:\n${
|
|
16
|
+
super(`Invalid OQSE file:\n${D(e).join("\n")}`), this.name = "OQSEValidationError", this.errors = e, this.warnings = t;
|
|
16
17
|
}
|
|
17
18
|
};
|
|
18
|
-
function
|
|
19
|
+
function D(e) {
|
|
19
20
|
return e.map((e) => e.path ? `${e.path}: ${e.message}` : e.message);
|
|
20
21
|
}
|
|
21
|
-
var
|
|
22
|
-
function
|
|
23
|
-
return
|
|
22
|
+
var O = 1, k = "1.0";
|
|
23
|
+
function A(e, t = {}) {
|
|
24
|
+
return I(e, "load", t);
|
|
24
25
|
}
|
|
25
|
-
function
|
|
26
|
-
let
|
|
26
|
+
function j(e, t = {}) {
|
|
27
|
+
let n = I(e, "strict", t), r = n.success && n.errors.length === 0;
|
|
27
28
|
return {
|
|
28
|
-
success:
|
|
29
|
-
data:
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
success: r,
|
|
30
|
+
data: r ? n.data : void 0,
|
|
31
|
+
unsupportedItems: n.unsupportedItems,
|
|
32
|
+
errors: n.errors,
|
|
33
|
+
warnings: n.warnings
|
|
32
34
|
};
|
|
33
35
|
}
|
|
34
|
-
function
|
|
35
|
-
let
|
|
36
|
-
|
|
37
|
-
return
|
|
36
|
+
function M(e, t) {
|
|
37
|
+
let n = [...e.items];
|
|
38
|
+
for (let { index: e, item: r } of [...t].sort((e, t) => e.index - t.index)) n.splice(Math.min(e, n.length), 0, structuredClone(r));
|
|
39
|
+
return {
|
|
40
|
+
...e,
|
|
41
|
+
items: n
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
function N(e, t = {}) {
|
|
45
|
+
let n = j(e, t);
|
|
46
|
+
if (!n.success) throw new E(n.errors, n.warnings);
|
|
47
|
+
return n.data;
|
|
38
48
|
}
|
|
39
|
-
var
|
|
49
|
+
var P = new Set(r), F = class {
|
|
40
50
|
errors = [];
|
|
41
51
|
warnings = [];
|
|
42
|
-
add(e, n, r, i
|
|
43
|
-
let
|
|
52
|
+
add(e, t, n, r, i) {
|
|
53
|
+
let a = {
|
|
44
54
|
severity: e,
|
|
45
|
-
code:
|
|
46
|
-
message:
|
|
47
|
-
path:
|
|
55
|
+
code: t,
|
|
56
|
+
message: n,
|
|
57
|
+
path: s(r)
|
|
48
58
|
};
|
|
49
|
-
|
|
59
|
+
i && (a.itemId = i), (e === "error" ? this.errors : this.warnings).push(a);
|
|
50
60
|
}
|
|
51
61
|
addZod(e, t, n, r) {
|
|
52
62
|
for (let i of e.issues) this.add("error", t, i.message, [...n, ...i.path], r);
|
|
53
63
|
}
|
|
54
64
|
};
|
|
55
|
-
function
|
|
56
|
-
let
|
|
65
|
+
function I(e, t, n) {
|
|
66
|
+
let r = new F(), i = [], a = () => ({
|
|
57
67
|
success: !1,
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
68
|
+
unsupportedItems: i,
|
|
69
|
+
errors: r.errors,
|
|
70
|
+
warnings: r.warnings
|
|
71
|
+
}), s = t === "strict" ? "error" : "warning";
|
|
61
72
|
try {
|
|
62
|
-
|
|
73
|
+
c(e, 32);
|
|
63
74
|
} catch (e) {
|
|
64
|
-
return
|
|
65
|
-
}
|
|
66
|
-
if (!
|
|
67
|
-
let
|
|
68
|
-
if (
|
|
69
|
-
if (typeof
|
|
70
|
-
let
|
|
71
|
-
if (
|
|
72
|
-
if (
|
|
73
|
-
if (t === "load"
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
75
|
+
return r.add("error", "SECURITY_LIMIT", e.message, []), a();
|
|
76
|
+
}
|
|
77
|
+
if (!X(e) || !X(e.meta) || !Array.isArray(e.items)) return r.add("error", "INVALID_ROOT", "An OQSE file must be an object with \"version\", \"meta\" and \"items\" (array).", []), a();
|
|
78
|
+
let l = structuredClone(e);
|
|
79
|
+
if (l.$schema !== void 0 && typeof l.$schema != "string") return r.add("error", "INVALID_ROOT", "\"$schema\" must be a string URL.", ["$schema"]), a();
|
|
80
|
+
if (typeof l.version != "string" || !/^\d+\.\d+$/.test(l.version)) return r.add("error", "INVALID_VERSION", "Version must be in MAJOR.MINOR format (e.g. \"1.0\").", ["version"]), a();
|
|
81
|
+
let u = Number(l.version.split(".")[0]);
|
|
82
|
+
if (u === 0) return r.add("error", "UNSUPPORTED_VERSION", `OQSE ${l.version} is a pre-release version; this library reads OQSE 1.x (convert the set to 1.0).`, ["version"]), a();
|
|
83
|
+
if (u !== 1 && r.add("warning", "UNSUPPORTED_VERSION", `Unsupported MAJOR version ${l.version}; loading in best-effort mode.`, ["version"]), l.items.length > 5e4) return r.add("error", "TOO_MANY_ITEMS", `Maximum ${o} items per set.`, ["items"]), a();
|
|
84
|
+
if (t === "load") {
|
|
85
|
+
if (!Y(l.meta, ["meta", "assets"], r)) return a();
|
|
86
|
+
U(l.meta, "language", ["meta", "language"], r), l.items.forEach((e, t) => X(e) && U(e, "lang", [
|
|
87
|
+
"items",
|
|
88
|
+
t,
|
|
89
|
+
"lang"
|
|
90
|
+
], r, typeof e.id == "string" ? e.id : void 0));
|
|
91
|
+
}
|
|
92
|
+
L(l.meta, r, t);
|
|
93
|
+
let g = H(l.meta, r);
|
|
94
|
+
if (!g) return a();
|
|
95
|
+
let _ = {
|
|
96
|
+
features: p,
|
|
97
|
+
itemProperties: m,
|
|
98
|
+
metaProperties: h
|
|
80
99
|
};
|
|
81
|
-
for (let [e, t] of Object.entries(
|
|
100
|
+
for (let [e, t] of Object.entries(_)) for (let n of g.requirements?.[e] ?? []) !n.startsWith("x-") && !t.includes(n) && r.add("warning", "UNKNOWN_FEATURE", `Unknown ${e === "features" ? "feature" : "property"} "${n}" in requirements.${e} (ignored).`, [
|
|
82
101
|
"meta",
|
|
83
102
|
"requirements",
|
|
84
103
|
e
|
|
85
104
|
]);
|
|
86
|
-
let
|
|
87
|
-
|
|
88
|
-
for (let [e, n] of
|
|
89
|
-
let
|
|
90
|
-
|
|
91
|
-
}
|
|
92
|
-
let
|
|
93
|
-
|
|
94
|
-
let
|
|
95
|
-
if (typeof
|
|
96
|
-
|
|
105
|
+
let v = new Set(g.requirements?.features ?? []), x = v.has("html"), E = v.has("latex");
|
|
106
|
+
K(g.assets, ["meta", "assets"], r, t), g.thumbnail && !g.assets?.[g.thumbnail] && (r.add(s, "MISSING_THUMBNAIL_ASSET", `Thumbnail references non-existent asset "${g.thumbnail}".`, ["meta", "thumbnail"]), t === "load" && delete g.thumbnail);
|
|
107
|
+
for (let [e, n] of C(g)) {
|
|
108
|
+
let i = x ? null : y(n, { latex: E });
|
|
109
|
+
i && (r.add(s, "RAW_HTML_NOT_ALLOWED", Z(i), e), t === "load" && Q(g, e.slice(1)));
|
|
110
|
+
}
|
|
111
|
+
let D = /* @__PURE__ */ new Set([g.id]), O = [];
|
|
112
|
+
l.items.forEach((e, a) => {
|
|
113
|
+
let o = ["items", a], c = X(e) && typeof e.id == "string" ? e.id : void 0, l = X(e) ? e.type : void 0;
|
|
114
|
+
if (typeof l == "string" && !l.startsWith("x-") && !P.has(l)) {
|
|
115
|
+
let t = d.safeParse(e);
|
|
116
|
+
if (!t.success) {
|
|
117
|
+
r.addZod(t.error, "INVALID_ITEM", o, c);
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
if (D.has(t.data.id)) {
|
|
121
|
+
r.add("error", "DUPLICATE_ID", `Duplicate ID "${t.data.id}" (IDs must be unique within the set, including meta.id).`, [...o, "id"], t.data.id);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
D.add(t.data.id), r.add("warning", "UNKNOWN_ITEM_TYPE", `Unknown item type "${l}" (a newer OQSE version, or a typo; custom types use the "x-" prefix). The item is kept but not shown.`, [...o, "type"], c), i.push({
|
|
125
|
+
index: a,
|
|
126
|
+
item: structuredClone(e)
|
|
127
|
+
});
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
if (t === "load" && X(e) && !Y(e, [...o, "assets"], r, c)) return;
|
|
131
|
+
let u = f(e).safeParse(e);
|
|
132
|
+
if (!u.success) {
|
|
133
|
+
r.addZod(u.error, "INVALID_ITEM", o, c);
|
|
97
134
|
return;
|
|
98
135
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
c.addZod(s.error, "INVALID_ITEM", r, a);
|
|
136
|
+
let p = u.data;
|
|
137
|
+
if (D.has(p.id)) {
|
|
138
|
+
r.add("error", "DUPLICATE_ID", `Duplicate ID "${p.id}" (IDs must be unique within the set, including meta.id).`, [...o, "id"], p.id);
|
|
103
139
|
return;
|
|
104
140
|
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
141
|
+
D.add(p.id);
|
|
142
|
+
for (let [e, t] of z(p)) R.test(t) && r.add("warning", "REVEALING_CHOICE_ID", `Choice ID "${t}" gives the answer away (learners can see IDs); use an ID from the text or a random one.`, [...o, ...e], p.id);
|
|
143
|
+
let m = b(p, n.understood);
|
|
144
|
+
if (m.length > 0) {
|
|
145
|
+
r.add("warning", "MUST_UNDERSTAND", `The item needs properties this application does not support (${m.join(", ")}); it is kept but not shown.`, [...o, "mustUnderstand"], p.id), i.push({
|
|
146
|
+
index: a,
|
|
147
|
+
item: structuredClone(e)
|
|
148
|
+
});
|
|
108
149
|
return;
|
|
109
150
|
}
|
|
110
|
-
|
|
111
|
-
item:
|
|
112
|
-
index:
|
|
151
|
+
K(p.assets, [...o, "assets"], r, t, p.id), G(p, o, g, x, E, r, s) && O.push({
|
|
152
|
+
item: p,
|
|
153
|
+
index: a
|
|
113
154
|
});
|
|
114
155
|
});
|
|
115
|
-
let
|
|
116
|
-
for (let { item: e
|
|
117
|
-
|
|
156
|
+
let k = O.map((e) => e.item), A = new Set(k.map((e) => e.id));
|
|
157
|
+
for (let { item: e } of i) A.add(e.id);
|
|
158
|
+
let j = new Set((g.sourceMaterials ?? []).map((e) => e.id)), M = new Set((g.sourceMaterials ?? []).filter((e) => e.set === g.id).map((e) => e.id));
|
|
159
|
+
for (let { item: e, index: n } of O) {
|
|
160
|
+
let i = ["items", n];
|
|
118
161
|
for (let n of ["relatedItems", "dependencyItems"]) {
|
|
119
|
-
let
|
|
120
|
-
if (!
|
|
121
|
-
let
|
|
122
|
-
|
|
162
|
+
let a = e[n];
|
|
163
|
+
if (!a) continue;
|
|
164
|
+
let o = a.filter((t) => t !== e.id && A.has(t));
|
|
165
|
+
o.length !== a.length && (r.add(s, "DANGLING_REFERENCE", `${n} contains IDs that do not exist in the set or reference the item itself.`, [...i, n], e.id), t === "load" && (e[n] = o));
|
|
123
166
|
}
|
|
124
167
|
if (e.sources) {
|
|
125
|
-
let n = e.sources.filter((e) =>
|
|
126
|
-
n.length !== e.sources.length && (
|
|
168
|
+
let n = e.sources.filter((e) => j.has(e.id));
|
|
169
|
+
n.length !== e.sources.length && (r.add(s, "DANGLING_REFERENCE", "sources reference source materials that do not exist in meta.sourceMaterials.", [...i, "sources"], e.id), t === "load" && (e.sources = n)), e.sources.forEach((n, a) => {
|
|
170
|
+
n.itemId !== void 0 && M.has(n.id) && !A.has(n.itemId) && (r.add(s, "DANGLING_REFERENCE", `sources[${a}].itemId "${n.itemId}" does not exist in this set.`, [
|
|
171
|
+
...i,
|
|
172
|
+
"sources",
|
|
173
|
+
a,
|
|
174
|
+
"itemId"
|
|
175
|
+
], e.id), t === "load" && delete n.itemId);
|
|
176
|
+
});
|
|
127
177
|
}
|
|
128
178
|
}
|
|
129
|
-
for (let e of
|
|
130
|
-
meta:
|
|
131
|
-
items:
|
|
132
|
-
})) e !== "html" && !
|
|
179
|
+
for (let e of w({
|
|
180
|
+
meta: g,
|
|
181
|
+
items: k
|
|
182
|
+
})) e !== "html" && !v.has(e) && r.add("warning", "UNDECLARED_FEATURE", `The content uses "${e}", but meta.requirements.features does not declare it.`, [
|
|
133
183
|
"meta",
|
|
134
184
|
"requirements",
|
|
135
185
|
"features"
|
|
136
186
|
]);
|
|
137
|
-
if (!
|
|
138
|
-
let n =
|
|
139
|
-
n &&
|
|
187
|
+
if (!E) for (let { item: e, index: t } of O) {
|
|
188
|
+
let n = S(e).find(([, e]) => T(e));
|
|
189
|
+
n && r.add("warning", "LOOKS_LIKE_LATEX", "The text looks like a LaTeX formula; if it is one, declare the \"latex\" feature (otherwise $ is an ordinary character).", [
|
|
140
190
|
"items",
|
|
141
191
|
t,
|
|
142
192
|
...n[0]
|
|
143
193
|
], e.id);
|
|
144
194
|
}
|
|
145
|
-
return {
|
|
195
|
+
return W(g, O, r), {
|
|
146
196
|
success: !0,
|
|
147
197
|
data: {
|
|
148
|
-
...
|
|
149
|
-
meta:
|
|
150
|
-
items:
|
|
198
|
+
...l,
|
|
199
|
+
meta: g,
|
|
200
|
+
items: k
|
|
151
201
|
},
|
|
152
|
-
|
|
153
|
-
|
|
202
|
+
unsupportedItems: i,
|
|
203
|
+
errors: r.errors,
|
|
204
|
+
warnings: r.warnings
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
function L(e, t, n) {
|
|
208
|
+
if (!Array.isArray(e.sourceMaterials)) return;
|
|
209
|
+
let r = [];
|
|
210
|
+
e.sourceMaterials.forEach((e, i) => {
|
|
211
|
+
let a = [
|
|
212
|
+
"meta",
|
|
213
|
+
"sourceMaterials",
|
|
214
|
+
i
|
|
215
|
+
], o = u.safeParse(e);
|
|
216
|
+
if (!o.success) {
|
|
217
|
+
t.addZod(o.error, "INVALID_SOURCE", a), n === "strict" && r.push(e);
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
let s = o.data;
|
|
221
|
+
s.url === void 0 && s.doi === void 0 && s.isbn === void 0 && s.set === void 0 && t.add("warning", "SOURCE_WITHOUT_LOCATOR", `Source "${s.id}" has none of url, doi, isbn, set: it can be cited only by its title.`, a), r.push(e);
|
|
222
|
+
}), n === "load" && (e.sourceMaterials = r);
|
|
223
|
+
}
|
|
224
|
+
var R = /(^|[^a-z])(correct|incorrect|right|wrong|answer|solution)([^a-z]|$)/i;
|
|
225
|
+
function z(e) {
|
|
226
|
+
let t = [], n = e;
|
|
227
|
+
for (let e of [
|
|
228
|
+
"options",
|
|
229
|
+
"items",
|
|
230
|
+
"prompts",
|
|
231
|
+
"matches",
|
|
232
|
+
"categories",
|
|
233
|
+
"rows",
|
|
234
|
+
"columns",
|
|
235
|
+
"labels",
|
|
236
|
+
"events",
|
|
237
|
+
"zones"
|
|
238
|
+
]) {
|
|
239
|
+
let r = n[e];
|
|
240
|
+
Array.isArray(r) && r.forEach((n, r) => X(n) && typeof n.id == "string" && t.push([[
|
|
241
|
+
e,
|
|
242
|
+
r,
|
|
243
|
+
"id"
|
|
244
|
+
], n.id]));
|
|
245
|
+
}
|
|
246
|
+
if (e.type === "fill-in-select" && X(n.blanks)) for (let [e, r] of Object.entries(n.blanks)) X(r) && Array.isArray(r.options) && r.options.forEach((n, r) => X(n) && typeof n.id == "string" && t.push([[
|
|
247
|
+
"blanks",
|
|
248
|
+
e,
|
|
249
|
+
"options",
|
|
250
|
+
r,
|
|
251
|
+
"id"
|
|
252
|
+
], n.id]));
|
|
253
|
+
return t;
|
|
254
|
+
}
|
|
255
|
+
var B = /* @__PURE__ */ new Set([
|
|
256
|
+
"id",
|
|
257
|
+
"title",
|
|
258
|
+
"language",
|
|
259
|
+
"createdAt",
|
|
260
|
+
"updatedAt"
|
|
261
|
+
]), V = /* @__PURE__ */ new Set([
|
|
262
|
+
"assets",
|
|
263
|
+
"tagDefinitions",
|
|
264
|
+
"translations",
|
|
265
|
+
"prerequisites",
|
|
266
|
+
"relatedSets",
|
|
267
|
+
"contributors",
|
|
268
|
+
"sourceMaterials"
|
|
269
|
+
]);
|
|
270
|
+
function H(e, t) {
|
|
271
|
+
let n = structuredClone(e);
|
|
272
|
+
for (let e = 0; e < 50; e++) {
|
|
273
|
+
let e = l.safeParse(n);
|
|
274
|
+
if (e.success) return e.data;
|
|
275
|
+
let r = [];
|
|
276
|
+
for (let n of e.error.issues) {
|
|
277
|
+
let [e, i] = n.path;
|
|
278
|
+
if (e === void 0 || B.has(String(e))) return t.add("error", "INVALID_META", n.message, ["meta", ...n.path]), null;
|
|
279
|
+
t.add("error", "INVALID_META_FIELD", `${n.message} (removed)`, ["meta", ...n.path]), r.push(V.has(String(e)) && i !== void 0 ? [e, i] : [e]);
|
|
280
|
+
}
|
|
281
|
+
r.sort((e, t) => Number(t[1] ?? 0) - Number(e[1] ?? 0));
|
|
282
|
+
let i = /* @__PURE__ */ new Set();
|
|
283
|
+
for (let e of r) {
|
|
284
|
+
let t = e.join(".");
|
|
285
|
+
if (i.has(t)) continue;
|
|
286
|
+
i.add(t);
|
|
287
|
+
let [r, a] = e, o = n[r];
|
|
288
|
+
a === void 0 ? delete n[r] : Array.isArray(o) ? o.splice(Number(a), 1) : X(o) && delete o[a];
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
return null;
|
|
292
|
+
}
|
|
293
|
+
function U(e, t, n, r, i) {
|
|
294
|
+
let a = e[t];
|
|
295
|
+
typeof a == "string" && a.includes("_") && (e[t] = a.replace(/_/g, "-"), r.add("warning", "LANGUAGE_NORMALIZED", `Language tag "${a}" written as "${e[t]}" (BCP 47 uses hyphens).`, n, i));
|
|
296
|
+
}
|
|
297
|
+
function W(r, o, s) {
|
|
298
|
+
let c = (e, t, n, r, i) => {
|
|
299
|
+
typeof e == "string" && !t.includes(e) && s.add("warning", "UNKNOWN_VALUE", `Unknown value "${e}" (a newer OQSE version, or a typo): ${r}.`, n, i);
|
|
300
|
+
}, l = (e, t, r) => {
|
|
301
|
+
for (let [i, o] of Object.entries(e ?? {})) c(o.type, n, [
|
|
302
|
+
...t,
|
|
303
|
+
i,
|
|
304
|
+
"type"
|
|
305
|
+
], "shown as a link", r), o.subtitles?.forEach((e, n) => c(e.kind, a, [
|
|
306
|
+
...t,
|
|
307
|
+
i,
|
|
308
|
+
"subtitles",
|
|
309
|
+
n,
|
|
310
|
+
"kind"
|
|
311
|
+
], "the track is not offered", r));
|
|
154
312
|
};
|
|
313
|
+
l(r.assets, ["meta", "assets"]), r.sourceMaterials?.forEach((e, t) => c(e.kind, i, [
|
|
314
|
+
"meta",
|
|
315
|
+
"sourceMaterials",
|
|
316
|
+
t,
|
|
317
|
+
"kind"
|
|
318
|
+
], "treated as \"other\""));
|
|
319
|
+
for (let { item: n, index: r } of o) l(n.assets, [
|
|
320
|
+
"items",
|
|
321
|
+
r,
|
|
322
|
+
"assets"
|
|
323
|
+
], n.id), c(n.pedagogy?.bloomLevel, e, [
|
|
324
|
+
"items",
|
|
325
|
+
r,
|
|
326
|
+
"pedagogy",
|
|
327
|
+
"bloomLevel"
|
|
328
|
+
], "ignored", n.id), c(n.pedagogy?.cognitiveLoad, t, [
|
|
329
|
+
"items",
|
|
330
|
+
r,
|
|
331
|
+
"pedagogy",
|
|
332
|
+
"cognitiveLoad"
|
|
333
|
+
], "ignored", n.id);
|
|
155
334
|
}
|
|
156
|
-
function
|
|
335
|
+
function G(e, t, n, r, i, a, o) {
|
|
157
336
|
let s = !0;
|
|
158
|
-
if (!r) for (let [n, r] of
|
|
159
|
-
let o =
|
|
160
|
-
o && (a.add("error", "RAW_HTML_NOT_ALLOWED",
|
|
337
|
+
if (!r) for (let [n, r] of S(e)) {
|
|
338
|
+
let o = y(r, { latex: i });
|
|
339
|
+
o && (a.add("error", "RAW_HTML_NOT_ALLOWED", Z(o), [...t, ...n], e.id), s = !1);
|
|
161
340
|
}
|
|
162
341
|
if ("targetAsset" in e && typeof e.targetAsset == "string" && !e.type.startsWith("x-")) {
|
|
163
|
-
let r =
|
|
342
|
+
let r = x(e.targetAsset, e, n), i = e.type === "pin-on-model" ? "model" : "image";
|
|
164
343
|
r ? r.type !== i && (a.add("error", "INVALID_TARGET_ASSET", `targetAsset "${e.targetAsset}" must be of type "${i}".`, [...t, "targetAsset"], e.id), s = !1) : (a.add("error", "MISSING_TARGET_ASSET", `targetAsset "${e.targetAsset}" does not exist in item.assets or meta.assets.`, [...t, "targetAsset"], e.id), s = !1);
|
|
165
344
|
}
|
|
166
|
-
let
|
|
167
|
-
if (
|
|
168
|
-
let n =
|
|
345
|
+
let c = e.type === "timeline" ? e.events : e.type === "categorize" ? e.items : void 0;
|
|
346
|
+
if (c) {
|
|
347
|
+
let n = c.map((e) => e.id);
|
|
169
348
|
new Set(n).size !== n.length && (a.add("error", "DUPLICATE_ID", "Internal IDs must be unique within the item.", [...t, e.type === "timeline" ? "events" : "items"], e.id), s = !1);
|
|
170
349
|
}
|
|
171
350
|
if (e.type === "chess-puzzle" && e.correctAnswers.some((e) => e.length % 2 == 0) && a.add("warning", "CHESS_SEQUENCE_LENGTH", "Each move sequence should end with the learner's move (an odd number of moves; the application plays the replies).", [...t, "correctAnswers"], e.id), e.type === "note") for (let n of ["content", "hiddenContent"]) {
|
|
172
351
|
let r = e[n];
|
|
173
|
-
r &&
|
|
352
|
+
r && g(_(r)).some((e) => e.level === 1) && a.add("warning", "NOTE_HEADING_LEVEL", "Headings inside a note should start at level 2 (##); the note title is level 1.", [...t, n], e.id);
|
|
174
353
|
}
|
|
175
|
-
let
|
|
176
|
-
for (let [n, r] of
|
|
177
|
-
for (let i of
|
|
354
|
+
let l = e.type === "fill-in-blanks" || e.type === "fill-in-select";
|
|
355
|
+
for (let [n, r] of S(e)) {
|
|
356
|
+
for (let i of q(r)) {
|
|
178
357
|
if (/^https:\/\//i.test(i)) continue;
|
|
179
358
|
let r = /^http:\/\//i.test(i);
|
|
180
359
|
a.add(r ? "warning" : o, "INVALID_IMAGE_URL", r ? `Image "${i}" uses http:// (prefer https://).` : `Image "${i}" needs an absolute https:// URL (use <asset:key /> for other media).`, [...t, ...n], e.id);
|
|
181
360
|
}
|
|
182
|
-
!(
|
|
361
|
+
!(l && n.length === 1 && n[0] === "text") && /<blank:[a-zA-Z0-9_-]+\s*\/>/i.test(r) && a.add("warning", "BLANK_OUTSIDE_TEXT", "Blank tags belong only in the text of fill-in-blanks and fill-in-select (shown here as an empty line).", [...t, ...n], e.id);
|
|
183
362
|
}
|
|
184
|
-
for (let [r, i] of
|
|
363
|
+
for (let [r, i] of S(e)) for (let o of v(i)) x(o, e, n) || a.add("warning", "MISSING_ASSET", `<asset:${o} /> does not exist in item.assets or meta.assets.`, [...t, ...r], e.id);
|
|
185
364
|
for (let r of Object.keys(e.assets ?? {})) n.assets?.[r] && a.add("warning", "ASSET_SHADOWED", `Item asset "${r}" shadows a global asset with the same key; use unique keys.`, [
|
|
186
365
|
...t,
|
|
187
366
|
"assets",
|
|
@@ -189,22 +368,22 @@ function D(e, t, n, r, i, a, o) {
|
|
|
189
368
|
], e.id);
|
|
190
369
|
return s;
|
|
191
370
|
}
|
|
192
|
-
function
|
|
371
|
+
function K(e, t, n, r, i) {
|
|
193
372
|
for (let [a, o] of Object.entries(e ?? {})) o.type !== "image" || o.altText?.trim() || (n.add(r === "strict" ? "error" : "warning", "MISSING_ALT_TEXT", `Image "${a}" has no altText (alternative text for screen readers).`, [
|
|
194
373
|
...t,
|
|
195
374
|
a,
|
|
196
375
|
"altText"
|
|
197
|
-
], i), r === "load" && (o.altText =
|
|
376
|
+
], i), r === "load" && (o.altText = J(o.value) || a));
|
|
198
377
|
}
|
|
199
|
-
function
|
|
378
|
+
function q(e) {
|
|
200
379
|
return [...e.replace(/^ {0,3}(`{3,}|~{3,})[^\n]*\n[\s\S]*?(?:^ {0,3}\1[`~]*[ \t]*$|(?![\s\S]))/gm, "").replace(/`[^`\n]+`/g, "").matchAll(/!\[[^\]\n]*\]\(\s*<?([^)\s>]+)/g)].map((e) => e[1]);
|
|
201
380
|
}
|
|
202
|
-
function
|
|
381
|
+
function J(e) {
|
|
203
382
|
return (e.split(/[?#]/)[0].split("/").pop() ?? "").replace(/\.[a-z0-9]+$/i, "").replace(/[-_]+/g, " ").trim();
|
|
204
383
|
}
|
|
205
|
-
function
|
|
384
|
+
function Y(e, t, n, r) {
|
|
206
385
|
let i = e.assets;
|
|
207
|
-
if (!
|
|
386
|
+
if (!X(i)) return !0;
|
|
208
387
|
let a = {};
|
|
209
388
|
for (let [e, o] of Object.entries(i)) {
|
|
210
389
|
let i = e.toLowerCase();
|
|
@@ -215,16 +394,16 @@ function j(e, t, n, r) {
|
|
|
215
394
|
for (let t of ["thumbnail", "targetAsset"]) typeof e[t] == "string" && (e[t] = e[t].toLowerCase());
|
|
216
395
|
return !0;
|
|
217
396
|
}
|
|
218
|
-
function
|
|
397
|
+
function X(e) {
|
|
219
398
|
return typeof e == "object" && !!e && !Array.isArray(e);
|
|
220
399
|
}
|
|
221
|
-
function
|
|
400
|
+
function Z(e) {
|
|
222
401
|
return `Raw HTML ${e} is not allowed unless the set declares the "html" feature (use Markdown instead).`;
|
|
223
402
|
}
|
|
224
|
-
function
|
|
403
|
+
function Q(e, t) {
|
|
225
404
|
let n = e;
|
|
226
405
|
for (let e of t.slice(0, -1)) n = n[e];
|
|
227
406
|
delete n[t[t.length - 1]];
|
|
228
407
|
}
|
|
229
408
|
//#endregion
|
|
230
|
-
export {
|
|
409
|
+
export { E as OQSEValidationError, k as OQSE_VERSION, O as SUPPORTED_OQSE_MAJOR_VERSION, D as formatOQSEIssues, A as loadOQSEFile, j as safeValidateOQSEFile, N as validateOQSEFile, M as withUnsupportedItems };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const e=require("./oqseValidation.cjs");let t=require("zod");var n=t.z.
|
|
1
|
+
const e=require("./oqseValidation.cjs");let t=require("zod");var n=t.z.looseObject(e.OQSEMetaSchema.shape).pick({id:!0,title:!0,language:!0,updatedAt:!0,description:!0,author:!0,subject:!0,tags:!0,createdAt:!0,estimatedTime:!0,requirements:!0}).partial({createdAt:!0}).extend({url:e.AbsoluteURLSchema,$schema:t.z.string().url().optional()});function r(e){return n.parse(e)}function i(e){return n.safeParse(e)}exports.OQSEHeaderSchema=n,exports.safeValidateOQSEHeader=i,exports.validateOQSEHeader=r;
|
package/dist/headerValidation.js
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./oqse.cjs"),t=require("./utils.cjs"),n=require("./answers.cjs"),r=require("./oqseValidation.cjs"),i=require("./manifest.cjs"),a=require("./manifestValidation.cjs"),o=require("./progressValidation.cjs"),s=require("./headerValidation.cjs"),c=require("./markdownUtils.cjs"),l=require("./richTextProcessor.cjs"),u=require("./
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./oqse.cjs"),t=require("./utils.cjs"),n=require("./answers.cjs"),r=require("./oqseValidation.cjs"),i=require("./manifest.cjs"),a=require("./manifestValidation.cjs"),o=require("./progressValidation.cjs"),s=require("./headerValidation.cjs"),c=require("./markdownUtils.cjs"),l=require("./richTextProcessor.cjs"),u=require("./knownProperties.generated.cjs"),d=require("./mustUnderstand.cjs"),f=require("./assets.cjs"),p=require("./richTextFields.cjs"),m=require("./features.cjs"),h=require("./fileValidation.cjs"),g=require("./markdownSet.cjs"),_=require("./checkAnswer.cjs"),v=require("./plainText.cjs"),y=require("./compatibility.cjs");exports.AbsoluteURLSchema=r.AbsoluteURLSchema,exports.AnyOQSEItemSchema=r.AnyOQSEItemSchema,exports.AssetDictionarySchema=r.AssetDictionarySchema,exports.AssetKeySchema=r.AssetKeySchema,exports.AudioMimeTypeSchema=a.AudioMimeTypeSchema,exports.BLOOM_LEVELS=e.BLOOM_LEVELS,exports.BaseItemSchema=r.BaseItemSchema,exports.BlankTokenSchema=r.BlankTokenSchema,exports.BloomLevelSchema=r.BloomLevelSchema,exports.COGNITIVE_LOADS=e.COGNITIVE_LOADS,exports.CORE_ITEM_TYPES=e.CORE_ITEM_TYPES,exports.CameraSetupSchema=r.CameraSetupSchema,exports.CategorizeEntrySchema=r.CategorizeEntrySchema,exports.CategorizeItemSchema=r.CategorizeItemSchema,exports.ChessPuzzleItemSchema=r.ChessPuzzleItemSchema,exports.ChoiceIdSchema=r.ChoiceIdSchema,exports.ChoiceSchema=r.ChoiceSchema,exports.CircleHotspotSchema=r.CircleHotspotSchema,exports.CognitiveLoadSchema=r.CognitiveLoadSchema,exports.CustomItemSchema=r.CustomItemSchema,exports.CustomItemTypeSchema=r.CustomItemTypeSchema,exports.DEFAULT_NOTE_HEADING_LEVEL=g.DEFAULT_NOTE_HEADING_LEVEL,exports.DiagramLabelItemSchema=r.DiagramLabelItemSchema,exports.DiagramZoneSchema=r.DiagramZoneSchema,exports.FeatureFlagSchema=a.FeatureFlagSchema,exports.FeatureKeySchema=r.FeatureKeySchema,exports.FeatureProfileSchema=r.FeatureProfileSchema,exports.FillInBlanksItemSchema=r.FillInBlanksItemSchema,exports.FillInSelectItemSchema=r.FillInSelectItemSchema,exports.FlashcardItemSchema=r.FlashcardItemSchema,exports.HIDDEN_CALLOUT_MARKER=g.HIDDEN_CALLOUT_MARKER,exports.Hotspot2DSchema=r.Hotspot2DSchema,exports.HotspotObjectSchema=r.HotspotObjectSchema,exports.ISO8601DateTimeSchema=r.ISO8601DateTimeSchema,exports.ImageMimeTypeSchema=a.ImageMimeTypeSchema,exports.ItemPropertyKeySchema=a.ItemPropertyKeySchema,exports.KNOWN_ITEM_PROPERTIES=u.KNOWN_ITEM_PROPERTIES,exports.LanguageCodeSchema=r.LanguageCodeSchema,exports.LastAnswerObjectSchema=o.LastAnswerObjectSchema,exports.LinkedSetObjectSchema=r.LinkedSetObjectSchema,exports.MAX_ITEMS=t.MAX_ITEMS,exports.MAX_JSON_DEPTH=t.MAX_JSON_DEPTH,exports.MAX_LAST_ANSWER_BYTES=o.MAX_LAST_ANSWER_BYTES,exports.MCQMultiItemSchema=r.MCQMultiItemSchema,exports.MCQSingleItemSchema=r.MCQSingleItemSchema,exports.MEDIA_TYPES=e.MEDIA_TYPES,exports.ManifestAssetsSchema=a.ManifestAssetsSchema,exports.ManifestCapabilitiesSchema=a.ManifestCapabilitiesSchema,exports.MarkdownSetError=g.MarkdownSetError,exports.MatchComplexItemSchema=r.MatchComplexItemSchema,exports.MatchPairsItemSchema=r.MatchPairsItemSchema,exports.MathInputItemSchema=r.MathInputItemSchema,exports.MatrixItemSchema=r.MatrixItemSchema,exports.MediaObjectSchema=r.MediaObjectSchema,exports.MeshHotspotSchema=r.MeshHotspotSchema,exports.MetaPropertyKeySchema=a.MetaPropertyKeySchema,exports.ModelMimeTypeSchema=a.ModelMimeTypeSchema,exports.NoteItemSchema=r.NoteItemSchema,exports.NumericInputItemSchema=r.NumericInputItemSchema,exports.OFFICIAL_ACTIONS=i.OFFICIAL_ACTIONS,exports.OFFICIAL_FEATURE_KEYS=i.OFFICIAL_FEATURE_KEYS,exports.OFFICIAL_ITEM_PROPERTIES=i.OFFICIAL_ITEM_PROPERTIES,exports.OFFICIAL_ITEM_TYPES=e.OFFICIAL_ITEM_TYPES,exports.OFFICIAL_META_PROPERTIES=i.OFFICIAL_META_PROPERTIES,exports.OQSEActionSchema=a.OQSEActionSchema,exports.OQSEFileSchema=r.OQSEFileSchema,exports.OQSEHeaderSchema=s.OQSEHeaderSchema,exports.OQSEItemSchema=r.OQSEItemSchema,exports.OQSEManifestSchema=a.OQSEManifestSchema,exports.OQSEMetaSchema=r.OQSEMetaSchema,exports.OQSEProgressSchema=o.OQSEProgressSchema,exports.OQSEQuestionDensitySchema=a.OQSEQuestionDensitySchema,exports.OQSEStudyModeSchema=a.OQSEStudyModeSchema,exports.OQSEValidationError=h.OQSEValidationError,exports.OQSE_TAG_PATTERN=l.OQSE_TAG_PATTERN,exports.OQSE_VERSION=h.OQSE_VERSION,exports.OpenEndedItemSchema=r.OpenEndedItemSchema,exports.OpenValueSchema=r.OpenValueSchema,exports.OptionalRichContentSchema=r.OptionalRichContentSchema,exports.PedagogySchema=r.PedagogySchema,exports.PersonObjectSchema=r.PersonObjectSchema,exports.PinOnImageItemSchema=r.PinOnImageItemSchema,exports.PinOnModelItemSchema=r.PinOnModelItemSchema,exports.PlainTextSchema=r.PlainTextSchema,exports.PolygonHotspotSchema=r.PolygonHotspotSchema,exports.ProgressMetaSchema=o.ProgressMetaSchema,exports.ProgressRecordSchema=o.ProgressRecordSchema,exports.PropertyKeySchema=r.PropertyKeySchema,exports.RTL_LANGUAGES=m.RTL_LANGUAGES,exports.RawLatexSchema=r.RawLatexSchema,exports.RectHotspotSchema=r.RectHotspotSchema,exports.RichContentSchema=r.RichContentSchema,exports.RubricCriterionSchema=r.RubricCriterionSchema,exports.RubricSchema=r.RubricSchema,exports.SOURCE_KINDS=e.SOURCE_KINDS,exports.SPDXLicenseSchema=r.SPDXLicenseSchema,exports.SUBTITLE_KINDS=e.SUBTITLE_KINDS,exports.SUPPORTED_OQSE_MAJOR_VERSION=h.SUPPORTED_OQSE_MAJOR_VERSION,exports.SelectBlankObjectSchema=r.SelectBlankObjectSchema,exports.ShortAnswerItemSchema=r.ShortAnswerItemSchema,exports.SkillIdSchema=r.SkillIdSchema,exports.SliderItemSchema=r.SliderItemSchema,exports.SortItemsItemSchema=r.SortItemsItemSchema,exports.SourceMaterialSchema=r.SourceMaterialSchema,exports.SourceReferenceSchema=r.SourceReferenceSchema,exports.StatsObjectSchema=o.StatsObjectSchema,exports.SubtitleTrackSchema=r.SubtitleTrackSchema,exports.TagDefinitionDictionarySchema=r.TagDefinitionDictionarySchema,exports.TagDefinitionSchema=r.TagDefinitionSchema,exports.TimelineDateSchema=r.TimelineDateSchema,exports.TimelineEventSchema=r.TimelineEventSchema,exports.TimelineItemSchema=r.TimelineItemSchema,exports.TimelinePrecisionSchema=r.TimelinePrecisionSchema,exports.TranslationObjectSchema=r.TranslationObjectSchema,exports.TrueFalseItemSchema=r.TrueFalseItemSchema,exports.UUIDSchema=r.UUIDSchema,exports.UnknownTypeItemSchema=r.UnknownTypeItemSchema,exports.Vector3Schema=r.Vector3Schema,exports.VideoMimeTypeSchema=a.VideoMimeTypeSchema,exports.allowedTypos=n.allowedTypos,exports.assertNoRawHtml=l.assertNoRawHtml,exports.checkAnswer=_.checkAnswer,exports.checkCompatibility=y.checkCompatibility,exports.choiceList=r.choiceList,exports.compareManifestVersions=i.compareManifestVersions,exports.compareTimelineEvents=n.compareTimelineEvents,exports.detectFeatures=m.detectFeatures,exports.detokenizeOqseTags=l.detokenizeOqseTags,exports.editDistance=n.editDistance,exports.effectiveFeatures=m.effectiveFeatures,exports.findAssetKeys=l.findAssetKeys,exports.findRawHtml=l.findRawHtml,exports.formatOQSEErrors=t.formatOQSEErrors,exports.formatOQSEIssues=h.formatOQSEIssues,exports.formatPath=t.formatPath,exports.generateUUID=t.generateUUID,exports.getItemSchema=r.getItemSchema,exports.isCategorize=e.isCategorize,exports.isChessPuzzle=e.isChessPuzzle,exports.isCoreItem=e.isCoreItem,exports.isCustomItem=e.isCustomItem,exports.isDiagramLabel=e.isDiagramLabel,exports.isExtendedItem=e.isExtendedItem,exports.isFillInBlanks=e.isFillInBlanks,exports.isFillInSelect=e.isFillInSelect,exports.isFlashcard=e.isFlashcard,exports.isMCQMulti=e.isMCQMulti,exports.isMCQSingle=e.isMCQSingle,exports.isMatchComplex=e.isMatchComplex,exports.isMatchPairs=e.isMatchPairs,exports.isMathInput=e.isMathInput,exports.isMatrix=e.isMatrix,exports.isNote=e.isNote,exports.isNumericInput=e.isNumericInput,exports.isOQSEManifest=i.isOQSEManifest,exports.isOpenEnded=e.isOpenEnded,exports.isPinOnImage=e.isPinOnImage,exports.isPinOnModel=e.isPinOnModel,exports.isShortAnswer=e.isShortAnswer,exports.isSlider=e.isSlider,exports.isSortItems=e.isSortItems,exports.isTimeline=e.isTimeline,exports.isTimelineDate=n.isTimelineDate,exports.isTimelineOrderCorrect=n.isTimelineOrderCorrect,exports.isTrueFalse=e.isTrueFalse,exports.isValidManifestVersion=i.isValidManifestVersion,exports.isValidOQSEManifest=a.isValidOQSEManifest,exports.isValidSemVer=i.isValidSemVer,exports.isValidUUID=t.isValidUUID,exports.isVersionCompatible=i.isVersionCompatible,exports.itemRichText=p.itemRichText,exports.loadOQSEFile=h.loadOQSEFile,exports.looksLikeLatex=m.looksLikeLatex,exports.metaRichText=p.metaRichText,exports.missingMustUnderstand=d.missingMustUnderstand,exports.normalizeAnswerText=n.normalizeAnswerText,exports.parseMarkdownSet=g.parseMarkdownSet,exports.prepareRichTextForDisplay=l.prepareRichTextForDisplay,exports.resolveAsset=f.resolveAsset,exports.safeParseMarkdownSet=g.safeParseMarkdownSet,exports.safeValidateOQSEFile=h.safeValidateOQSEFile,exports.safeValidateOQSEHeader=s.safeValidateOQSEHeader,exports.safeValidateOQSEItem=r.safeValidateOQSEItem,exports.safeValidateOQSEManifest=a.safeValidateOQSEManifest,exports.safeValidateOQSEProgress=o.safeValidateOQSEProgress,exports.serializeMarkdownSet=g.serializeMarkdownSet,exports.shiftHeadings=c.shiftHeadings,exports.textAnswerMatches=n.textAnswerMatches,exports.toPlainText=v.toPlainText,exports.tokenizeOqseTags=l.tokenizeOqseTags,exports.validateJsonDepth=t.validateJsonDepth,exports.validateOQSEFile=h.validateOQSEFile,exports.validateOQSEHeader=s.validateOQSEHeader,exports.validateOQSEItem=r.validateOQSEItem,exports.validateOQSEManifest=a.validateOQSEManifest,exports.validateOQSEProgress=o.validateOQSEProgress,exports.withManifestDefaults=i.withManifestDefaults,exports.withUnsupportedItems=h.withUnsupportedItems;
|
package/dist/index.d.ts
CHANGED
|
@@ -18,3 +18,5 @@ export * from './src/checkAnswer.js';
|
|
|
18
18
|
export * from './src/plainText.js';
|
|
19
19
|
export * from './src/features.js';
|
|
20
20
|
export * from './src/compatibility.js';
|
|
21
|
+
export { missingMustUnderstand } from './src/mustUnderstand.js';
|
|
22
|
+
export { KNOWN_ITEM_PROPERTIES } from './src/knownProperties.generated.js';
|