lens-content-processor 0.33.0 → 0.34.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/authoring-markup.d.ts +0 -11
- package/dist/authoring-markup.js +0 -52
- package/dist/authoring-markup.js.map +1 -1
- package/dist/cli.d.ts +0 -1
- package/dist/cli.js +2 -6
- package/dist/cli.js.map +1 -1
- package/dist/content-schema.d.ts +3 -1
- package/dist/content-schema.js +46 -12
- package/dist/content-schema.js.map +1 -1
- package/dist/dedupe-errors.js +1 -7
- package/dist/dedupe-errors.js.map +1 -1
- package/dist/flattener/index.d.ts +23 -0
- package/dist/flattener/index.js +39 -51
- package/dist/flattener/index.js.map +1 -1
- package/dist/index.d.ts +24 -3
- package/dist/index.js +85 -28
- package/dist/index.js.map +1 -1
- package/dist/parser/article.js +32 -34
- package/dist/parser/article.js.map +1 -1
- package/dist/parser/course.d.ts +10 -0
- package/dist/parser/course.js +14 -16
- package/dist/parser/course.js.map +1 -1
- package/dist/parser/learning-outcome.d.ts +0 -1
- package/dist/parser/learning-outcome.js +50 -29
- package/dist/parser/learning-outcome.js.map +1 -1
- package/dist/parser/lens.d.ts +12 -2
- package/dist/parser/lens.js +27 -67
- package/dist/parser/lens.js.map +1 -1
- package/dist/parser/module.js +17 -24
- package/dist/parser/module.js.map +1 -1
- package/dist/parser/response-segments.d.ts +54 -0
- package/dist/parser/response-segments.js +499 -0
- package/dist/parser/response-segments.js.map +1 -0
- package/dist/parser/sections.d.ts +1 -2
- package/dist/parser/sections.js +3 -5
- package/dist/parser/sections.js.map +1 -1
- package/dist/parser/survey.js +51 -25
- package/dist/parser/survey.js.map +1 -1
- package/dist/validator/directives.js +0 -42
- package/dist/validator/directives.js.map +1 -1
- package/dist/validator/emphasis.js +2 -126
- package/dist/validator/emphasis.js.map +1 -1
- package/dist/validator/html-tags.js +111 -103
- package/dist/validator/html-tags.js.map +1 -1
- package/dist/validator/math.js +9 -66
- package/dist/validator/math.js.map +1 -1
- package/dist/validator/output-integrity.d.ts +1 -1
- package/dist/validator/output-integrity.js +8 -14
- package/dist/validator/output-integrity.js.map +1 -1
- package/dist/validator/segment-fields.d.ts +4 -2
- package/dist/validator/segment-fields.js +27 -5
- package/dist/validator/segment-fields.js.map +1 -1
- package/dist/validator/test-segments.d.ts +11 -0
- package/dist/validator/test-segments.js +45 -0
- package/dist/validator/test-segments.js.map +1 -1
- package/dist/validator/uuid.d.ts +1 -2
- package/dist/validator/uuid.js +4 -6
- package/dist/validator/uuid.js.map +1 -1
- package/package.json +1 -9
- package/dist/source-location.d.ts +0 -2
- package/dist/source-location.js +0 -12
- package/dist/source-location.js.map +0 -1
- package/dist/validator/article-review-provenance.d.ts +0 -5
- package/dist/validator/article-review-provenance.js +0 -57
- package/dist/validator/article-review-provenance.js.map +0 -1
- package/dist/validator/article-structure.d.ts +0 -8
- package/dist/validator/article-structure.js +0 -674
- package/dist/validator/article-structure.js.map +0 -1
- package/dist/validator/same-lens-links.d.ts +0 -4
- package/dist/validator/same-lens-links.js +0 -297
- package/dist/validator/same-lens-links.js.map +0 -1
- package/dist/validator/suppressions.d.ts +0 -42
- package/dist/validator/suppressions.js +0 -97
- package/dist/validator/suppressions.js.map +0 -1
|
@@ -3,11 +3,6 @@
|
|
|
3
3
|
* Handles both inline (%% ... %% on same line) and block (multiline) comments.
|
|
4
4
|
*/
|
|
5
5
|
export declare function stripObsidianComments(content: string): string;
|
|
6
|
-
/**
|
|
7
|
-
* Reject authoring markup while preserving source line numbers for validators.
|
|
8
|
-
* Publishing deliberately uses stripAuthoringMarkup() instead.
|
|
9
|
-
*/
|
|
10
|
-
export declare function stripAuthoringMarkupForValidation(content: string): string;
|
|
11
6
|
/**
|
|
12
7
|
* Strip CriticMarkup from content using reject-all-changes behavior. Each
|
|
13
8
|
* form's regex and publish replacement are defined once in CRITIC_MARKUP_FORMS
|
|
@@ -19,9 +14,3 @@ export declare function stripCriticMarkup(content: string): string;
|
|
|
19
14
|
* Call before parsing or publishing learner-facing content.
|
|
20
15
|
*/
|
|
21
16
|
export declare function stripAuthoringMarkup(content: string): string;
|
|
22
|
-
/**
|
|
23
|
-
* Copy learner-facing strings from a publishing parse onto the equivalent
|
|
24
|
-
* validation parse. Objects (and their non-enumerable source provenance) stay
|
|
25
|
-
* intact, as do validation-derived line numbers and other scalar metadata.
|
|
26
|
-
*/
|
|
27
|
-
export declare function usePublishedStrings<T>(validationValue: T, publishedValue: T): T;
|
package/dist/authoring-markup.js
CHANGED
|
@@ -6,28 +6,6 @@ import { CRITIC_MARKUP_FORMS } from "./criticmarkup-forms.js";
|
|
|
6
6
|
export function stripObsidianComments(content) {
|
|
7
7
|
return content.replace(/%%.*?%%/gs, "");
|
|
8
8
|
}
|
|
9
|
-
function preserveNewlines(match, replacement) {
|
|
10
|
-
const missing = (match.match(/\n/g)?.length ?? 0) - (replacement.match(/\n/g)?.length ?? 0);
|
|
11
|
-
return replacement + "\n".repeat(Math.max(0, missing));
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* Reject authoring markup while preserving source line numbers for validators.
|
|
15
|
-
* Publishing deliberately uses stripAuthoringMarkup() instead.
|
|
16
|
-
*/
|
|
17
|
-
export function stripAuthoringMarkupForValidation(content) {
|
|
18
|
-
let result = content.replace(/%%.*?%%/gs, (match) => match.replace(/[^\n]/g, " "));
|
|
19
|
-
for (const form of CRITIC_MARKUP_FORMS) {
|
|
20
|
-
result = result.replace(form.re, (...args) => {
|
|
21
|
-
const match = String(args[0]);
|
|
22
|
-
const kept = form.rejected === "$1" ? String(args[1] ?? "") : "";
|
|
23
|
-
return preserveNewlines(match, kept);
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
return result
|
|
27
|
-
.split("\n")
|
|
28
|
-
.map((line) => line.trimEnd())
|
|
29
|
-
.join("\n");
|
|
30
|
-
}
|
|
31
9
|
/**
|
|
32
10
|
* Strip CriticMarkup from content using reject-all-changes behavior. Each
|
|
33
11
|
* form's regex and publish replacement are defined once in CRITIC_MARKUP_FORMS
|
|
@@ -48,34 +26,4 @@ export function stripAuthoringMarkup(content) {
|
|
|
48
26
|
.map((line) => line.trimEnd())
|
|
49
27
|
.join("\n");
|
|
50
28
|
}
|
|
51
|
-
/**
|
|
52
|
-
* Copy learner-facing strings from a publishing parse onto the equivalent
|
|
53
|
-
* validation parse. Objects (and their non-enumerable source provenance) stay
|
|
54
|
-
* intact, as do validation-derived line numbers and other scalar metadata.
|
|
55
|
-
*/
|
|
56
|
-
export function usePublishedStrings(validationValue, publishedValue) {
|
|
57
|
-
if (typeof validationValue === "string")
|
|
58
|
-
return publishedValue;
|
|
59
|
-
if (validationValue === null ||
|
|
60
|
-
publishedValue === null ||
|
|
61
|
-
typeof validationValue !== "object" ||
|
|
62
|
-
typeof publishedValue !== "object") {
|
|
63
|
-
return validationValue;
|
|
64
|
-
}
|
|
65
|
-
if (Array.isArray(validationValue) && Array.isArray(publishedValue)) {
|
|
66
|
-
const count = Math.min(validationValue.length, publishedValue.length);
|
|
67
|
-
for (let index = 0; index < count; index += 1) {
|
|
68
|
-
validationValue[index] = usePublishedStrings(validationValue[index], publishedValue[index]);
|
|
69
|
-
}
|
|
70
|
-
return validationValue;
|
|
71
|
-
}
|
|
72
|
-
const validationRecord = validationValue;
|
|
73
|
-
const publishedRecord = publishedValue;
|
|
74
|
-
for (const key of Object.keys(validationRecord)) {
|
|
75
|
-
if (key in publishedRecord) {
|
|
76
|
-
validationRecord[key] = usePublishedStrings(validationRecord[key], publishedRecord[key]);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
return validationValue;
|
|
80
|
-
}
|
|
81
29
|
//# sourceMappingURL=authoring-markup.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authoring-markup.js","sourceRoot":"","sources":["../src/authoring-markup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAE9D;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,OAAe;IACnD,OAAO,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;AAC1C,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"authoring-markup.js","sourceRoot":"","sources":["../src/authoring-markup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAE9D;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,OAAe;IACnD,OAAO,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;AAC1C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAe;IAC/C,OAAO,mBAAmB,CAAC,MAAM,CAC/B,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,QAAQ,CAAC,EACpD,OAAO,CACR,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAAe;IAClD,MAAM,QAAQ,GAAG,qBAAqB,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,CAAC;IACnE,0DAA0D;IAC1D,OAAO,QAAQ;SACZ,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;SAC7B,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC"}
|
package/dist/cli.d.ts
CHANGED
package/dist/cli.js
CHANGED
|
@@ -14,7 +14,6 @@ export function parseArgs(argv) {
|
|
|
14
14
|
let stdin = false;
|
|
15
15
|
let deferUrls = false;
|
|
16
16
|
let checkUrlsOnly = false;
|
|
17
|
-
let skipUrls = false;
|
|
18
17
|
for (let i = 0; i < args.length; i++) {
|
|
19
18
|
if (args[i] === "--output" || args[i] === "-o") {
|
|
20
19
|
outputPath = args[i + 1] || null;
|
|
@@ -29,14 +28,11 @@ export function parseArgs(argv) {
|
|
|
29
28
|
else if (args[i] === "--check-urls-only") {
|
|
30
29
|
checkUrlsOnly = true;
|
|
31
30
|
}
|
|
32
|
-
else if (args[i] === "--skip-urls") {
|
|
33
|
-
skipUrls = true;
|
|
34
|
-
}
|
|
35
31
|
else if (!args[i].startsWith("-")) {
|
|
36
32
|
vaultPath = args[i];
|
|
37
33
|
}
|
|
38
34
|
}
|
|
39
|
-
return { vaultPath, outputPath, stdin, deferUrls, checkUrlsOnly
|
|
35
|
+
return { vaultPath, outputPath, stdin, deferUrls, checkUrlsOnly };
|
|
40
36
|
}
|
|
41
37
|
async function readStdin() {
|
|
42
38
|
const chunks = [];
|
|
@@ -125,7 +121,7 @@ async function main() {
|
|
|
125
121
|
staleUrlCount: cache.staleCount(result.urlsToValidate),
|
|
126
122
|
};
|
|
127
123
|
}
|
|
128
|
-
else if (
|
|
124
|
+
else if (result.urlsToValidate.length > 0) {
|
|
129
125
|
const urlWarnings = await validateUrls(result.urlsToValidate, UrlCache.load());
|
|
130
126
|
// Re-dedupe: urlWarnings are appended after processContent already
|
|
131
127
|
// deduped, and can themselves repeat (same unreachable URL twice).
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,aAAa;AACb,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EACL,cAAc,GAIf,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,YAAY,EACZ,mBAAmB,GACpB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/content-schema.d.ts
CHANGED
|
@@ -26,8 +26,10 @@ export declare const CONTENT_SCHEMAS: Record<string, ContentTypeSchema>;
|
|
|
26
26
|
*/
|
|
27
27
|
export declare const SURVEY_SEGMENT_SCHEMAS: Record<string, SegmentTypeSchema>;
|
|
28
28
|
export declare const SEGMENT_SCHEMAS: Record<string, SegmentTypeSchema>;
|
|
29
|
+
export declare const QUESTION_SUBTYPE_SCHEMAS: Record<string, SegmentTypeSchema>;
|
|
29
30
|
/**
|
|
30
|
-
* Valid fields per segment type, derived from SEGMENT_SCHEMAS
|
|
31
|
+
* Valid fields per segment type, derived from SEGMENT_SCHEMAS (plus the
|
|
32
|
+
* "question:<subtype>" response schemas).
|
|
31
33
|
* Used by segment-fields.ts to check for misplaced fields.
|
|
32
34
|
*/
|
|
33
35
|
export declare const VALID_FIELDS_BY_SEGMENT_TYPE: Record<string, Set<string>>;
|
package/dist/content-schema.js
CHANGED
|
@@ -43,13 +43,6 @@ export const CONTENT_SCHEMAS = {
|
|
|
43
43
|
"url",
|
|
44
44
|
"allowAuthorInTitle",
|
|
45
45
|
"allowUnreachableUrl",
|
|
46
|
-
"llm_reviewed",
|
|
47
|
-
"llm_review_version",
|
|
48
|
-
"llm_review_model",
|
|
49
|
-
"llm_review_digest",
|
|
50
|
-
"llm_review_source_digest",
|
|
51
|
-
"llm_review_source_fetched",
|
|
52
|
-
"llm_review_source_kind",
|
|
53
46
|
]),
|
|
54
47
|
"video-transcript": contentSchema(["title", "channel", "url"],
|
|
55
48
|
// from/to: default excerpt range applied when an embedding lens omits
|
|
@@ -116,13 +109,46 @@ export const SEGMENT_SCHEMAS = {
|
|
|
116
109
|
], ["optional"]),
|
|
117
110
|
};
|
|
118
111
|
/**
|
|
119
|
-
*
|
|
112
|
+
* Response (subtyped) question segment schemas, keyed "question:<subtype>".
|
|
113
|
+
* `#### Question: Open` etc. — the same segment family in lenses, LO tests,
|
|
114
|
+
* and surveys. Kept out of SEGMENT_SCHEMAS because a bare `#### Question`
|
|
115
|
+
* stays the legacy schema there; responseSegmentSchemaKey (parser) resolves
|
|
116
|
+
* a titled question header to one of these keys for field validation.
|
|
117
|
+
*/
|
|
118
|
+
const RESPONSE_REQUIRED = ["id", "content"];
|
|
119
|
+
const RESPONSE_OPTIONAL = ["optional", "feedback-instructions"];
|
|
120
|
+
export const QUESTION_SUBTYPE_SCHEMAS = {
|
|
121
|
+
"question:open": segmentSchema(RESPONSE_REQUIRED, [
|
|
122
|
+
...RESPONSE_OPTIONAL,
|
|
123
|
+
"assessment-instructions",
|
|
124
|
+
"max-chars",
|
|
125
|
+
"max-time",
|
|
126
|
+
"placeholder",
|
|
127
|
+
"enforce-voice",
|
|
128
|
+
], ["optional", "enforce-voice"]),
|
|
129
|
+
// assessment-instructions is listed so the only message an author gets is
|
|
130
|
+
// the parser's targeted "ratings are never graded" error, not a generic
|
|
131
|
+
// unknown-field warning on top of it.
|
|
132
|
+
"question:rating": segmentSchema(RESPONSE_REQUIRED, [
|
|
133
|
+
...RESPONSE_OPTIONAL,
|
|
134
|
+
"assessment-instructions",
|
|
135
|
+
"scale",
|
|
136
|
+
"low-label",
|
|
137
|
+
"high-label",
|
|
138
|
+
], ["optional"]),
|
|
139
|
+
"question:choice": segmentSchema([...RESPONSE_REQUIRED, "options"], [...RESPONSE_OPTIONAL, "multi", "shuffle"], ["optional", "multi", "shuffle"]),
|
|
140
|
+
"question:fillblank": segmentSchema(RESPONSE_REQUIRED, [...RESPONSE_OPTIONAL, "assessment-instructions"], ["optional"]),
|
|
141
|
+
"question:ranking": segmentSchema([...RESPONSE_REQUIRED, "items"], [...RESPONSE_OPTIONAL, "assessment-instructions"], ["optional"]),
|
|
142
|
+
};
|
|
143
|
+
/**
|
|
144
|
+
* Valid fields per segment type, derived from SEGMENT_SCHEMAS (plus the
|
|
145
|
+
* "question:<subtype>" response schemas).
|
|
120
146
|
* Used by segment-fields.ts to check for misplaced fields.
|
|
121
147
|
*/
|
|
122
|
-
export const VALID_FIELDS_BY_SEGMENT_TYPE = Object.fromEntries(
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
]));
|
|
148
|
+
export const VALID_FIELDS_BY_SEGMENT_TYPE = Object.fromEntries([
|
|
149
|
+
...Object.entries(SEGMENT_SCHEMAS),
|
|
150
|
+
...Object.entries(QUESTION_SUBTYPE_SCHEMAS),
|
|
151
|
+
].map(([type, schema]) => [type, new Set(schema.allFields)]));
|
|
126
152
|
/**
|
|
127
153
|
* Section-level fields used in body sections (not frontmatter, not segments).
|
|
128
154
|
* These are fields like source:: and learningOutcomeId:: used in LO/lens sections.
|
|
@@ -150,6 +176,10 @@ export const ALL_KNOWN_FIELDS = (() => {
|
|
|
150
176
|
for (const field of schema.allFields)
|
|
151
177
|
fields.add(field);
|
|
152
178
|
}
|
|
179
|
+
for (const schema of Object.values(QUESTION_SUBTYPE_SCHEMAS)) {
|
|
180
|
+
for (const field of schema.allFields)
|
|
181
|
+
fields.add(field);
|
|
182
|
+
}
|
|
153
183
|
for (const schema of Object.values(SURVEY_SEGMENT_SCHEMAS)) {
|
|
154
184
|
for (const field of schema.allFields)
|
|
155
185
|
fields.add(field);
|
|
@@ -167,6 +197,10 @@ export const ALL_BOOLEAN_FIELDS = (() => {
|
|
|
167
197
|
for (const field of schema.booleanFields)
|
|
168
198
|
fields.add(field);
|
|
169
199
|
}
|
|
200
|
+
for (const schema of Object.values(QUESTION_SUBTYPE_SCHEMAS)) {
|
|
201
|
+
for (const field of schema.booleanFields)
|
|
202
|
+
fields.add(field);
|
|
203
|
+
}
|
|
170
204
|
for (const schema of Object.values(SURVEY_SEGMENT_SCHEMAS)) {
|
|
171
205
|
for (const field of schema.booleanFields)
|
|
172
206
|
fields.add(field);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"content-schema.js","sourceRoot":"","sources":["../src/content-schema.ts"],"names":[],"mappings":"AAAA,kGAAkG;AAsBlG,SAAS,aAAa,CACpB,QAAkB,EAClB,QAAkB;IAElB,OAAO;QACL,cAAc,EAAE,QAAQ;QACxB,cAAc,EAAE,QAAQ;QACxB,SAAS,EAAE,CAAC,GAAG,QAAQ,EAAE,GAAG,QAAQ,CAAC;KACtC,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CACpB,QAAkB,EAClB,QAAkB,EAClB,aAAuB;IAEvB,OAAO;QACL,cAAc,EAAE,QAAQ;QACxB,cAAc,EAAE,QAAQ;QACxB,SAAS,EAAE,CAAC,GAAG,QAAQ,EAAE,GAAG,QAAQ,CAAC;QACrC,aAAa;KACd,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,eAAe,GAAsC;IAChE,MAAM,EAAE,aAAa,CACnB,CAAC,MAAM,EAAE,OAAO,CAAC,EACjB,CAAC,WAAW,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,CAAC,CAC1C;IACD,MAAM,EAAE,aAAa,CACnB,CAAC,MAAM,EAAE,OAAO,CAAC,EACjB;QACE,IAAI;QACJ,cAAc;QACd,MAAM;QACN,cAAc;QACd,cAAc;QACd,oBAAoB;QACpB,aAAa;KACd,CACF;IACD,IAAI,EAAE,aAAa,CACjB,CAAC,IAAI,CAAC,EACN;QACE,OAAO;QACP,MAAM;QACN,mBAAmB;QACnB,MAAM;QACN,mBAAmB;QACnB,kBAAkB;QAClB,iBAAiB;QACjB,eAAe;KAChB,CACF;IACD,kBAAkB,EAAE,aAAa,CAC/B,CAAC,IAAI,CAAC,EACN,CAAC,YAAY,EAAE,kBAAkB,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,CAAC,CAC1E;IACD,OAAO,EAAE,aAAa,CACpB,CAAC,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,WAAW,CAAC,EAC9C;QACE,SAAS;QACT,aAAa;QACb,MAAM;QACN,KAAK;QACL,oBAAoB;QACpB,qBAAqB;
|
|
1
|
+
{"version":3,"file":"content-schema.js","sourceRoot":"","sources":["../src/content-schema.ts"],"names":[],"mappings":"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"}
|
package/dist/dedupe-errors.js
CHANGED
|
@@ -14,12 +14,6 @@ export function dedupeErrors(errors) {
|
|
|
14
14
|
const seen = new Set();
|
|
15
15
|
const deduped = [];
|
|
16
16
|
for (const error of errors) {
|
|
17
|
-
// Output-integrity validation can see the same flattened segment with a
|
|
18
|
-
// resolved section title in the standalone pass and an empty title in an
|
|
19
|
-
// embedding module pass. The title is presentation context, not problem
|
|
20
|
-
// identity; retain the segment kind and ordinal so distinct segments are
|
|
21
|
-
// still reported independently.
|
|
22
|
-
const messageKey = error.message.replace(/^(Empty (?:text|article) segment|Empty video transcript) in ".*" (\(segment \d+\))$/, "$1 $2");
|
|
23
17
|
// \x1f (unit separator) joins the fields: file paths and messages can
|
|
24
18
|
// themselves contain spaces, so a printable separator could let two
|
|
25
19
|
// distinct errors collapse to the same key.
|
|
@@ -27,7 +21,7 @@ export function dedupeErrors(errors) {
|
|
|
27
21
|
error.file,
|
|
28
22
|
error.line ?? "",
|
|
29
23
|
error.severity,
|
|
30
|
-
|
|
24
|
+
error.message,
|
|
31
25
|
].join("\x1f");
|
|
32
26
|
if (seen.has(key))
|
|
33
27
|
continue;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dedupe-errors.js","sourceRoot":"","sources":["../src/dedupe-errors.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,YAAY,CAAC,MAAsB;IACjD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,OAAO,GAAmB,EAAE,CAAC;IAEnC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,
|
|
1
|
+
{"version":3,"file":"dedupe-errors.js","sourceRoot":"","sources":["../src/dedupe-errors.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,YAAY,CAAC,MAAsB;IACjD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,OAAO,GAAmB,EAAE,CAAC;IAEnC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,sEAAsE;QACtE,oEAAoE;QACpE,4CAA4C;QAC5C,MAAM,GAAG,GAAG;YACV,KAAK,CAAC,IAAI;YACV,KAAK,CAAC,IAAI,IAAI,EAAE;YAChB,KAAK,CAAC,QAAQ;YACd,KAAK,CAAC,OAAO;SACd,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACf,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,SAAS;QAC5B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACd,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -29,6 +29,29 @@ export declare function splitAtBoundaries(items: FlatItem[], parentSlug: string,
|
|
|
29
29
|
* Flatten a module by resolving all references to Learning Outcomes, Lenses, and content.
|
|
30
30
|
*/
|
|
31
31
|
export declare function flattenModule(modulePath: string, files: Map<string, string>, visitedPaths?: Set<string>, tierMap?: Map<string, ContentTier>): FlattenModuleResult;
|
|
32
|
+
interface ExpandPromptImportsResult {
|
|
33
|
+
/** The field value with prompt imports inlined, or null when an import failed. */
|
|
34
|
+
value: string | null;
|
|
35
|
+
errors: ContentError[];
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Expand prompt imports in a prompt-capable field (chat instructions::,
|
|
39
|
+
* roleplay ai-instructions::, question/roleplay assessment-instructions::).
|
|
40
|
+
* Two forms:
|
|
41
|
+
*
|
|
42
|
+
* - Sole wikilink (the whole field is one wikilink): strict import — it must
|
|
43
|
+
* resolve to a valid prompts/ file. This is the original prompt-import
|
|
44
|
+
* form and behaves exactly as before.
|
|
45
|
+
* - Mixed text: each wikilink whose target resolves into a prompts/
|
|
46
|
+
* directory is replaced with that prompt file's body; the surrounding /
|
|
47
|
+
* interleaved text is preserved verbatim (no separators added — authors
|
|
48
|
+
* control spacing around the wikilink, and prompt bodies are trimmed).
|
|
49
|
+
* Targeting prompts/ is the import signal: other wikilinks stay literal
|
|
50
|
+
* text. A wikilink that looks like a prompts/ target but is malformed or
|
|
51
|
+
* doesn't resolve is an error, and the segment is dropped like a failed
|
|
52
|
+
* sole import.
|
|
53
|
+
*/
|
|
54
|
+
export declare function expandPromptImports(value: string, fieldName: string, lensPath: string, files: Map<string, string>, tierMap?: Map<string, ContentTier>): ExpandPromptImportsResult;
|
|
32
55
|
/**
|
|
33
56
|
* Flatten a single Lens file into a FlattenedModule.
|
|
34
57
|
*/
|
package/dist/flattener/index.js
CHANGED
|
@@ -5,11 +5,11 @@ import { parseLearningOutcome, } from "../parser/learning-outcome.js";
|
|
|
5
5
|
import { parseLens, } from "../parser/lens.js";
|
|
6
6
|
import { parseWikilink, resolveWikilinkPath, findFileWithExtension, findSimilarFiles, formatSuggestion, isSoleWikilink, findWikilinks, findBrokenPromptImports, } from "../parser/wikilink.js";
|
|
7
7
|
import { parsePrompt, isPromptPath } from "../parser/prompt.js";
|
|
8
|
+
import { toFlattenedResponseSegment } from "../parser/response-segments.js";
|
|
8
9
|
import { parseFrontmatter } from "../parser/frontmatter.js";
|
|
9
10
|
import { fileNameToSlug } from "../utils/slug.js";
|
|
10
11
|
import { extractArticleExcerpt, bundleArticleWithCollapsed, } from "../bundler/article.js";
|
|
11
12
|
import { extractVideoExcerpt, resolveVideoRange, } from "../bundler/video.js";
|
|
12
|
-
import { attachSourceLine, getSourceLine } from "../source-location.js";
|
|
13
13
|
function countWords(text) {
|
|
14
14
|
return text.trim().split(/\s+/).filter(Boolean).length;
|
|
15
15
|
}
|
|
@@ -684,14 +684,14 @@ function flattenLensSection(section, modulePath, files, visitedPaths, tierMap, i
|
|
|
684
684
|
const hideConflict = checkHideOptionalConflict(effectiveOptional, effectiveHide, modulePath, section.line);
|
|
685
685
|
if (hideConflict)
|
|
686
686
|
errors.push(hideConflict);
|
|
687
|
-
const resultSection =
|
|
687
|
+
const resultSection = {
|
|
688
688
|
type: "lens",
|
|
689
689
|
meta: { title: inlineLens.title || section.title },
|
|
690
690
|
sourcePath: modulePath,
|
|
691
691
|
optional: effectiveOptional,
|
|
692
692
|
...(effectiveHide && { hide: true }),
|
|
693
693
|
...lensSectionFields(inlineLens, segments, modulePath, section.line, errors),
|
|
694
|
-
}
|
|
694
|
+
};
|
|
695
695
|
sections.push(resultSection);
|
|
696
696
|
return { sections, errors };
|
|
697
697
|
}
|
|
@@ -775,14 +775,14 @@ function flattenLensSection(section, modulePath, files, visitedPaths, tierMap, i
|
|
|
775
775
|
const hideConflict = checkHideOptionalConflict(effectiveOptional, effectiveHide, modulePath, section.line);
|
|
776
776
|
if (hideConflict)
|
|
777
777
|
errors.push(hideConflict);
|
|
778
|
-
const resultSection =
|
|
778
|
+
const resultSection = {
|
|
779
779
|
type: "lens",
|
|
780
780
|
meta: { title: lens.title || section.title },
|
|
781
781
|
sourcePath: lensPath,
|
|
782
782
|
optional: effectiveOptional,
|
|
783
783
|
...(effectiveHide && { hide: true }),
|
|
784
784
|
...lensSectionFields(lens, segments, lensPath, section.line, errors),
|
|
785
|
-
}
|
|
785
|
+
};
|
|
786
786
|
sections.push(resultSection);
|
|
787
787
|
return { sections, errors };
|
|
788
788
|
}
|
|
@@ -938,7 +938,7 @@ function resolvePromptImport(value, fieldName, lensPath, files, tierMap) {
|
|
|
938
938
|
* doesn't resolve is an error, and the segment is dropped like a failed
|
|
939
939
|
* sole import.
|
|
940
940
|
*/
|
|
941
|
-
function expandPromptImports(value, fieldName, lensPath, files, tierMap) {
|
|
941
|
+
export function expandPromptImports(value, fieldName, lensPath, files, tierMap) {
|
|
942
942
|
// Sole wikilink — the whole field is the import (including recognizably
|
|
943
943
|
// malformed single wikilinks, which must fail loudly).
|
|
944
944
|
if (isSoleWikilink(value)) {
|
|
@@ -1009,10 +1009,7 @@ function convertSegment(parsedSegment, lensPath, files, visitedPaths, tierMap) {
|
|
|
1009
1009
|
if (parsedSegment.optional) {
|
|
1010
1010
|
segment.optional = true;
|
|
1011
1011
|
}
|
|
1012
|
-
return {
|
|
1013
|
-
segment: attachSourceLine(segment, getSourceLine(parsedSegment)),
|
|
1014
|
-
errors,
|
|
1015
|
-
};
|
|
1012
|
+
return { segment, errors };
|
|
1016
1013
|
}
|
|
1017
1014
|
case "chat": {
|
|
1018
1015
|
let instructions = parsedSegment.instructions;
|
|
@@ -1036,10 +1033,7 @@ function convertSegment(parsedSegment, lensPath, files, visitedPaths, tierMap) {
|
|
|
1036
1033
|
if (parsedSegment.hidePreviousContentFromTutor) {
|
|
1037
1034
|
segment.hidePreviousContentFromTutor = true;
|
|
1038
1035
|
}
|
|
1039
|
-
return {
|
|
1040
|
-
segment: attachSourceLine(segment, getSourceLine(parsedSegment)),
|
|
1041
|
-
errors,
|
|
1042
|
-
};
|
|
1036
|
+
return { segment, errors };
|
|
1043
1037
|
}
|
|
1044
1038
|
case "article": {
|
|
1045
1039
|
// Source comes from the parsed segment (set via inheritance in parseLens)
|
|
@@ -1105,11 +1099,7 @@ function convertSegment(parsedSegment, lensPath, files, visitedPaths, tierMap) {
|
|
|
1105
1099
|
// Extract the excerpt
|
|
1106
1100
|
const excerptResult = extractArticleExcerpt(articleContent, parsedSegment.fromAnchor, parsedSegment.toAnchor, articlePath);
|
|
1107
1101
|
if (excerptResult.error) {
|
|
1108
|
-
errors.push({
|
|
1109
|
-
...excerptResult.error,
|
|
1110
|
-
file: lensPath,
|
|
1111
|
-
line: getSourceLine(parsedSegment),
|
|
1112
|
-
});
|
|
1102
|
+
errors.push({ ...excerptResult.error, file: lensPath });
|
|
1113
1103
|
return { segment: null, errors };
|
|
1114
1104
|
}
|
|
1115
1105
|
const segment = {
|
|
@@ -1131,10 +1121,7 @@ function convertSegment(parsedSegment, lensPath, files, visitedPaths, tierMap) {
|
|
|
1131
1121
|
if (parsedSegment.optional) {
|
|
1132
1122
|
segment.optional = true;
|
|
1133
1123
|
}
|
|
1134
|
-
return {
|
|
1135
|
-
segment: attachSourceLine(segment, getSourceLine(parsedSegment)),
|
|
1136
|
-
errors,
|
|
1137
|
-
};
|
|
1124
|
+
return { segment, errors };
|
|
1138
1125
|
}
|
|
1139
1126
|
case "video": {
|
|
1140
1127
|
// Source comes from the parsed segment (set via inheritance in parseLens)
|
|
@@ -1213,11 +1200,7 @@ function convertSegment(parsedSegment, lensPath, files, visitedPaths, tierMap) {
|
|
|
1213
1200
|
const { fromTime, toTime } = resolveVideoRange(parsedSegment.fromTimeStr, parsedSegment.toTimeStr, vfm);
|
|
1214
1201
|
const excerptResult = extractVideoExcerpt(transcriptContent, fromTime, toTime, videoPath, timestamps);
|
|
1215
1202
|
if (excerptResult.error) {
|
|
1216
|
-
errors.push({
|
|
1217
|
-
...excerptResult.error,
|
|
1218
|
-
file: lensPath,
|
|
1219
|
-
line: getSourceLine(parsedSegment),
|
|
1220
|
-
});
|
|
1203
|
+
errors.push({ ...excerptResult.error, file: lensPath });
|
|
1221
1204
|
return { segment: null, errors };
|
|
1222
1205
|
}
|
|
1223
1206
|
const segment = {
|
|
@@ -1242,10 +1225,7 @@ function convertSegment(parsedSegment, lensPath, files, visitedPaths, tierMap) {
|
|
|
1242
1225
|
if (parsedSegment.optional) {
|
|
1243
1226
|
segment.optional = true;
|
|
1244
1227
|
}
|
|
1245
|
-
return {
|
|
1246
|
-
segment: attachSourceLine(segment, getSourceLine(parsedSegment)),
|
|
1247
|
-
errors,
|
|
1248
|
-
};
|
|
1228
|
+
return { segment, errors };
|
|
1249
1229
|
}
|
|
1250
1230
|
case "question": {
|
|
1251
1231
|
let assessmentInstructions = parsedSegment.assessmentInstructions;
|
|
@@ -1257,6 +1237,27 @@ function convertSegment(parsedSegment, lensPath, files, visitedPaths, tierMap) {
|
|
|
1257
1237
|
}
|
|
1258
1238
|
assessmentInstructions = resolved.value;
|
|
1259
1239
|
}
|
|
1240
|
+
// New-style response segment (`#### Question: <Subtype>`): pass the
|
|
1241
|
+
// parsed shape through, with prompt imports expanded in both
|
|
1242
|
+
// instruction fields. Answers (correctOptions, blank expectations)
|
|
1243
|
+
// stay in the cache JSON — the web API strips them before serving.
|
|
1244
|
+
if ("questionType" in parsedSegment) {
|
|
1245
|
+
let feedbackInstructions = parsedSegment.feedbackInstructions;
|
|
1246
|
+
if (feedbackInstructions) {
|
|
1247
|
+
const resolved = expandPromptImports(feedbackInstructions, "feedback-instructions", lensPath, files, tierMap);
|
|
1248
|
+
errors.push(...resolved.errors);
|
|
1249
|
+
if (resolved.value === null) {
|
|
1250
|
+
return { segment: null, errors };
|
|
1251
|
+
}
|
|
1252
|
+
feedbackInstructions = resolved.value;
|
|
1253
|
+
}
|
|
1254
|
+
const segment = toFlattenedResponseSegment(parsedSegment);
|
|
1255
|
+
if (assessmentInstructions)
|
|
1256
|
+
segment.assessmentInstructions = assessmentInstructions;
|
|
1257
|
+
if (feedbackInstructions)
|
|
1258
|
+
segment.feedbackInstructions = feedbackInstructions;
|
|
1259
|
+
return { segment, errors };
|
|
1260
|
+
}
|
|
1260
1261
|
const segment = {
|
|
1261
1262
|
type: "question",
|
|
1262
1263
|
content: parsedSegment.content,
|
|
@@ -1275,10 +1276,7 @@ function convertSegment(parsedSegment, lensPath, files, visitedPaths, tierMap) {
|
|
|
1275
1276
|
segment.feedback = parsedSegment.feedback;
|
|
1276
1277
|
if (parsedSegment.optional)
|
|
1277
1278
|
segment.optional = true;
|
|
1278
|
-
return {
|
|
1279
|
-
segment: attachSourceLine(segment, getSourceLine(parsedSegment)),
|
|
1280
|
-
errors,
|
|
1281
|
-
};
|
|
1279
|
+
return { segment, errors };
|
|
1282
1280
|
}
|
|
1283
1281
|
case "roleplay": {
|
|
1284
1282
|
let aiInstructions = parsedSegment.aiInstructions;
|
|
@@ -1315,10 +1313,7 @@ function convertSegment(parsedSegment, lensPath, files, visitedPaths, tierMap) {
|
|
|
1315
1313
|
segment.optional = true;
|
|
1316
1314
|
if (parsedSegment.feedback)
|
|
1317
1315
|
segment.feedback = true;
|
|
1318
|
-
return {
|
|
1319
|
-
segment: attachSourceLine(segment, getSourceLine(parsedSegment)),
|
|
1320
|
-
errors,
|
|
1321
|
-
};
|
|
1316
|
+
return { segment, errors };
|
|
1322
1317
|
}
|
|
1323
1318
|
case "embed": {
|
|
1324
1319
|
if (!parsedSegment.source) {
|
|
@@ -1389,11 +1384,7 @@ function convertSegment(parsedSegment, lensPath, files, visitedPaths, tierMap) {
|
|
|
1389
1384
|
}
|
|
1390
1385
|
const excerptResult = extractArticleExcerpt(articleContent, parsedSegment.fromAnchor, parsedSegment.toAnchor, articlePath);
|
|
1391
1386
|
if (excerptResult.error) {
|
|
1392
|
-
errors.push({
|
|
1393
|
-
...excerptResult.error,
|
|
1394
|
-
file: lensPath,
|
|
1395
|
-
line: getSourceLine(parsedSegment),
|
|
1396
|
-
});
|
|
1387
|
+
errors.push({ ...excerptResult.error, file: lensPath });
|
|
1397
1388
|
return { segment: null, errors };
|
|
1398
1389
|
}
|
|
1399
1390
|
const segment = {
|
|
@@ -1421,10 +1412,7 @@ function convertSegment(parsedSegment, lensPath, files, visitedPaths, tierMap) {
|
|
|
1421
1412
|
segment.sandbox = parsedSegment.sandbox;
|
|
1422
1413
|
if (parsedSegment.optional)
|
|
1423
1414
|
segment.optional = true;
|
|
1424
|
-
return {
|
|
1425
|
-
segment: attachSourceLine(segment, getSourceLine(parsedSegment)),
|
|
1426
|
-
errors,
|
|
1427
|
-
};
|
|
1415
|
+
return { segment, errors };
|
|
1428
1416
|
}
|
|
1429
1417
|
default:
|
|
1430
1418
|
return { segment: null, errors };
|
|
@@ -1484,13 +1472,13 @@ export function flattenLens(lensPath, files, tierMap, preParsedLens) {
|
|
|
1484
1472
|
.replace(/\b\w/g, (c) => c.toUpperCase());
|
|
1485
1473
|
}
|
|
1486
1474
|
}
|
|
1487
|
-
const section =
|
|
1475
|
+
const section = {
|
|
1488
1476
|
type: "lens",
|
|
1489
1477
|
meta,
|
|
1490
1478
|
sourcePath: lensPath,
|
|
1491
1479
|
optional: false,
|
|
1492
1480
|
...lensSectionFields(lens, segments, lensPath, 1, errors),
|
|
1493
|
-
}
|
|
1481
|
+
};
|
|
1494
1482
|
const flattenedModule = {
|
|
1495
1483
|
slug: "lens/" + fileNameToSlug(lensPath),
|
|
1496
1484
|
title: meta.title ?? fileNameToSlug(lensPath),
|