lens-content-processor 0.3.0 → 0.4.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/bundler/article.d.ts +7 -2
- package/dist/bundler/article.js +19 -8
- package/dist/bundler/article.js.map +1 -1
- package/dist/content-schema.js +3 -2
- package/dist/content-schema.js.map +1 -1
- package/dist/flattener/index.d.ts +20 -1
- package/dist/flattener/index.js +476 -72
- package/dist/flattener/index.js.map +1 -1
- package/dist/flattener/test-helpers.d.ts +23 -0
- package/dist/flattener/test-helpers.js +58 -0
- package/dist/flattener/test-helpers.js.map +1 -0
- package/dist/index.d.ts +18 -2
- package/dist/index.js +53 -23
- package/dist/index.js.map +1 -1
- package/dist/parser/article.d.ts +1 -1
- package/dist/parser/article.js +8 -1
- package/dist/parser/article.js.map +1 -1
- package/dist/parser/course.js +11 -8
- package/dist/parser/course.js.map +1 -1
- package/dist/parser/learning-outcome.d.ts +7 -0
- package/dist/parser/learning-outcome.js +129 -86
- package/dist/parser/learning-outcome.js.map +1 -1
- package/dist/parser/lens.d.ts +26 -1
- package/dist/parser/lens.js +99 -10
- package/dist/parser/lens.js.map +1 -1
- package/dist/parser/module.d.ts +1 -1
- package/dist/parser/module.js +13 -8
- package/dist/parser/module.js.map +1 -1
- package/dist/parser/sections.d.ts +2 -0
- package/dist/parser/sections.js +53 -19
- package/dist/parser/sections.js.map +1 -1
- package/dist/parser/video-transcript.js +3 -0
- package/dist/parser/video-transcript.js.map +1 -1
- package/dist/validator/directives.d.ts +12 -0
- package/dist/validator/directives.js +428 -0
- package/dist/validator/directives.js.map +1 -0
- package/dist/validator/field-values.js +14 -0
- package/dist/validator/field-values.js.map +1 -1
- package/dist/validator/url-reachability.js +3 -1
- package/dist/validator/url-reachability.js.map +1 -1
- package/dist/validator/uuid.js +9 -6
- package/dist/validator/uuid.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,428 @@
|
|
|
1
|
+
import { levenshtein } from './field-typos.js';
|
|
2
|
+
const SUPPORTED_DIRECTIVES = {
|
|
3
|
+
note: { container: true, leaf: true, text: true, open: false },
|
|
4
|
+
collapse: { container: true, leaf: false, text: true, open: false },
|
|
5
|
+
footnote: { container: false, leaf: true, text: true, open: false },
|
|
6
|
+
};
|
|
7
|
+
const UNSUPPORTED_NAMES = new Set([
|
|
8
|
+
'warning', 'info', 'tip', 'caution', 'important',
|
|
9
|
+
'danger', 'details', 'summary', 'aside', 'callout', 'admonition',
|
|
10
|
+
]);
|
|
11
|
+
const ALL_DIRECTIVE_NAMES = new Set([...Object.keys(SUPPORTED_DIRECTIVES), ...UNSUPPORTED_NAMES]);
|
|
12
|
+
/**
|
|
13
|
+
* Check if a name is a near-miss typo of a supported directive name.
|
|
14
|
+
* Returns the closest match if levenshtein distance ≤ 2, else undefined.
|
|
15
|
+
*/
|
|
16
|
+
function findNearMissDirective(name) {
|
|
17
|
+
let bestMatch;
|
|
18
|
+
let bestDist = Infinity;
|
|
19
|
+
for (const supported of Object.keys(SUPPORTED_DIRECTIVES)) {
|
|
20
|
+
const dist = levenshtein(name.toLowerCase(), supported);
|
|
21
|
+
if (dist > 0 && dist <= 2 && dist < bestDist) {
|
|
22
|
+
bestDist = dist;
|
|
23
|
+
bestMatch = supported;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return bestMatch;
|
|
27
|
+
}
|
|
28
|
+
// Regex patterns
|
|
29
|
+
const CONTAINER_OPEN = /^:::([\w-]+)(?:\{([^}]*)\})?/;
|
|
30
|
+
const CONTAINER_CLOSE_BARE = /^:::\s*$/;
|
|
31
|
+
const CONTAINER_CLOSE_ATTR = /^:::\s*\{([^}]*)\}/;
|
|
32
|
+
const CODE_FENCE = /^(?:```|~~~)/;
|
|
33
|
+
const LEAF_DIRECTIVE_PRE = /^::([\w-]+)(?:\{([^}]*)\})?\[/;
|
|
34
|
+
const LEAF_DIRECTIVE_POST = /^::([\w-]+)\[[^\]]*\]\{([^}]*)\}/;
|
|
35
|
+
const TEXT_DIRECTIVE_PRE = /(?:^|[^:]):(\w[\w-]*)(?:\{([^}]*)\})?\[/;
|
|
36
|
+
const TEXT_DIRECTIVE_POST = /(?:^|[^:]):(\w[\w-]*)\[[^\]]*\]\{([^}]*)\}/;
|
|
37
|
+
// Unclosed bracket patterns — match ::name[ or :name[ without closing ]
|
|
38
|
+
const LEAF_UNCLOSED = /^::([\w-]+)(?:\{[^}]*\})?\[[^\]]*$/;
|
|
39
|
+
const TEXT_UNCLOSED = /(?:^|[^:]):([\w][\w-]*)(?:\{[^}]*\})?\[[^\]]*$/;
|
|
40
|
+
/**
|
|
41
|
+
* Check if an attribute value looks like a typo of "open".
|
|
42
|
+
*/
|
|
43
|
+
function isOpenTypo(attr) {
|
|
44
|
+
if (attr === 'open')
|
|
45
|
+
return false;
|
|
46
|
+
if (!attr)
|
|
47
|
+
return false;
|
|
48
|
+
// Case-insensitive match
|
|
49
|
+
if (attr.toLowerCase() === 'open')
|
|
50
|
+
return true;
|
|
51
|
+
// Contains = (like open=true)
|
|
52
|
+
if (attr.includes('=')) {
|
|
53
|
+
const key = attr.split('=')[0];
|
|
54
|
+
if (key.toLowerCase() === 'open')
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
// Levenshtein distance
|
|
58
|
+
if (levenshtein(attr.toLowerCase(), 'open') <= 2)
|
|
59
|
+
return true;
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Check attribute validity on a supported directive and return warnings.
|
|
64
|
+
*/
|
|
65
|
+
function checkAttribute(name, attr, file, line) {
|
|
66
|
+
const errors = [];
|
|
67
|
+
if (attr === undefined)
|
|
68
|
+
return errors;
|
|
69
|
+
const info = SUPPORTED_DIRECTIVES[name];
|
|
70
|
+
if (!info)
|
|
71
|
+
return errors;
|
|
72
|
+
if (attr === '') {
|
|
73
|
+
errors.push({
|
|
74
|
+
file,
|
|
75
|
+
line,
|
|
76
|
+
message: `Directive '${name}' has an empty attribute '{}'`,
|
|
77
|
+
suggestion: 'Remove the empty braces, or use {open} to make the directive open by default',
|
|
78
|
+
severity: 'warning',
|
|
79
|
+
});
|
|
80
|
+
return errors;
|
|
81
|
+
}
|
|
82
|
+
if (attr === 'open') {
|
|
83
|
+
// Valid attribute — but check if this directive supports it
|
|
84
|
+
if (!info.open) {
|
|
85
|
+
errors.push({
|
|
86
|
+
file,
|
|
87
|
+
line,
|
|
88
|
+
message: `Directive '${name}' does not support {open}`,
|
|
89
|
+
suggestion: `Remove {open} — '${name}' does not support the open attribute`,
|
|
90
|
+
severity: 'warning',
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
else if (isOpenTypo(attr)) {
|
|
95
|
+
errors.push({
|
|
96
|
+
file,
|
|
97
|
+
line,
|
|
98
|
+
message: `Possible attribute typo '{${attr}}' on directive '${name}'`,
|
|
99
|
+
suggestion: `Did you mean {open}?`,
|
|
100
|
+
severity: 'warning',
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
// Completely unrecognized attribute
|
|
105
|
+
errors.push({
|
|
106
|
+
file,
|
|
107
|
+
line,
|
|
108
|
+
message: `Unrecognized attribute '{${attr}}' on directive '${name}'`,
|
|
109
|
+
suggestion: info.open ? `The only supported attribute is {open}` : `'${name}' does not support any attributes`,
|
|
110
|
+
severity: 'warning',
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
return errors;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Main validator for article body content.
|
|
117
|
+
* Checks for unclosed containers, unsupported names, empty containers,
|
|
118
|
+
* attribute typos, and {open} on closing markers.
|
|
119
|
+
*/
|
|
120
|
+
export function validateDirectives(body, file, bodyStartLine) {
|
|
121
|
+
const errors = [];
|
|
122
|
+
const lines = body.split('\n');
|
|
123
|
+
const stack = [];
|
|
124
|
+
let inCodeBlock = false;
|
|
125
|
+
for (let i = 0; i < lines.length; i++) {
|
|
126
|
+
const line = lines[i];
|
|
127
|
+
const absLine = bodyStartLine + i;
|
|
128
|
+
// Toggle code block state
|
|
129
|
+
if (CODE_FENCE.test(line)) {
|
|
130
|
+
inCodeBlock = !inCodeBlock;
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
if (inCodeBlock)
|
|
134
|
+
continue;
|
|
135
|
+
// Check container close with attribute (error: {open} on closing marker)
|
|
136
|
+
const closeAttrMatch = line.match(CONTAINER_CLOSE_ATTR);
|
|
137
|
+
if (closeAttrMatch) {
|
|
138
|
+
const attrOnClose = closeAttrMatch[1];
|
|
139
|
+
const top = stack.pop();
|
|
140
|
+
if (top) {
|
|
141
|
+
errors.push({
|
|
142
|
+
file,
|
|
143
|
+
line: absLine,
|
|
144
|
+
message: `Attribute {${attrOnClose}} on closing ':::' marker has no effect`,
|
|
145
|
+
suggestion: `Move to opening marker: :::${top.name}{${attrOnClose}}`,
|
|
146
|
+
severity: 'error',
|
|
147
|
+
});
|
|
148
|
+
// Check empty container
|
|
149
|
+
if (!top.hasContent) {
|
|
150
|
+
errors.push({
|
|
151
|
+
file,
|
|
152
|
+
line: top.line,
|
|
153
|
+
message: `Empty container directive ':::${top.name}' has no content`,
|
|
154
|
+
suggestion: 'Add content between the opening and closing markers',
|
|
155
|
+
severity: 'warning',
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
// Check bare container close
|
|
162
|
+
if (CONTAINER_CLOSE_BARE.test(line)) {
|
|
163
|
+
const top = stack.pop();
|
|
164
|
+
if (top && !top.hasContent) {
|
|
165
|
+
errors.push({
|
|
166
|
+
file,
|
|
167
|
+
line: top.line,
|
|
168
|
+
message: `Empty container directive ':::${top.name}' has no content`,
|
|
169
|
+
suggestion: 'Add content between the opening and closing markers',
|
|
170
|
+
severity: 'warning',
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
// Check container open
|
|
176
|
+
const openMatch = line.match(CONTAINER_OPEN);
|
|
177
|
+
if (openMatch) {
|
|
178
|
+
const name = openMatch[1];
|
|
179
|
+
const attr = openMatch[2];
|
|
180
|
+
if (UNSUPPORTED_NAMES.has(name)) {
|
|
181
|
+
errors.push({
|
|
182
|
+
file,
|
|
183
|
+
line: absLine,
|
|
184
|
+
message: `Unsupported directive ':::${name}'`,
|
|
185
|
+
suggestion: `Supported container directives: ${Object.entries(SUPPORTED_DIRECTIVES).filter(([, v]) => v.container).map(([k]) => k).join(', ')}`,
|
|
186
|
+
severity: 'error',
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
else if (SUPPORTED_DIRECTIVES[name]) {
|
|
190
|
+
if (!SUPPORTED_DIRECTIVES[name].container) {
|
|
191
|
+
errors.push({
|
|
192
|
+
file,
|
|
193
|
+
line: absLine,
|
|
194
|
+
message: `Directive '${name}' does not support the container ':::' form`,
|
|
195
|
+
suggestion: `Use the leaf form '::${name}[text]' or inline form ':${name}[text]' instead`,
|
|
196
|
+
severity: 'error',
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
errors.push(...checkAttribute(name, attr, file, absLine));
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
const nearMiss = findNearMissDirective(name);
|
|
203
|
+
if (nearMiss) {
|
|
204
|
+
errors.push({
|
|
205
|
+
file,
|
|
206
|
+
line: absLine,
|
|
207
|
+
message: `Unknown directive ':::${name}' — did you mean ':::${nearMiss}'?`,
|
|
208
|
+
suggestion: `Supported container directives: ${Object.entries(SUPPORTED_DIRECTIVES).filter(([, v]) => v.container).map(([k]) => k).join(', ')}`,
|
|
209
|
+
severity: 'error',
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
stack.push({ name, line: absLine, hasContent: false });
|
|
214
|
+
continue;
|
|
215
|
+
}
|
|
216
|
+
// Check leaf directive (::name[...)
|
|
217
|
+
// First check for unclosed bracket: ::name[ without ]
|
|
218
|
+
const leafUnclosedMatch = line.match(LEAF_UNCLOSED);
|
|
219
|
+
if (leafUnclosedMatch) {
|
|
220
|
+
const name = leafUnclosedMatch[1];
|
|
221
|
+
if (SUPPORTED_DIRECTIVES[name] || UNSUPPORTED_NAMES.has(name) || findNearMissDirective(name)) {
|
|
222
|
+
errors.push({
|
|
223
|
+
file,
|
|
224
|
+
line: absLine,
|
|
225
|
+
message: `Unclosed bracket in leaf directive '::${name}[' — missing closing ']'`,
|
|
226
|
+
suggestion: `Add a closing bracket: ::${name}[content]`,
|
|
227
|
+
severity: 'error',
|
|
228
|
+
});
|
|
229
|
+
if (stack.length > 0) {
|
|
230
|
+
stack[stack.length - 1].hasContent = true;
|
|
231
|
+
}
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
// Try POST first to capture post-bracket attributes, fall back to PRE
|
|
236
|
+
const leafMatchPost = line.match(LEAF_DIRECTIVE_POST);
|
|
237
|
+
const leafMatchPre = line.match(LEAF_DIRECTIVE_PRE);
|
|
238
|
+
const leafMatch = leafMatchPost ?? leafMatchPre;
|
|
239
|
+
if (leafMatch) {
|
|
240
|
+
const name = leafMatch[1];
|
|
241
|
+
// Prefer post-bracket attr if available
|
|
242
|
+
const attr = leafMatchPost?.[2] ?? leafMatchPre?.[2];
|
|
243
|
+
if (UNSUPPORTED_NAMES.has(name)) {
|
|
244
|
+
errors.push({
|
|
245
|
+
file,
|
|
246
|
+
line: absLine,
|
|
247
|
+
message: `Unsupported directive '::${name}'`,
|
|
248
|
+
suggestion: `Supported leaf directives: ${Object.entries(SUPPORTED_DIRECTIVES).filter(([, v]) => v.leaf).map(([k]) => k).join(', ')}`,
|
|
249
|
+
severity: 'error',
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
else if (SUPPORTED_DIRECTIVES[name]) {
|
|
253
|
+
if (!SUPPORTED_DIRECTIVES[name].leaf) {
|
|
254
|
+
errors.push({
|
|
255
|
+
file,
|
|
256
|
+
line: absLine,
|
|
257
|
+
message: `Directive '${name}' does not support the leaf '::' form`,
|
|
258
|
+
suggestion: `Use the container form ':::${name}' or inline form ':${name}[text]' instead`,
|
|
259
|
+
severity: 'warning',
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
errors.push(...checkAttribute(name, attr, file, absLine));
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
const nearMiss = findNearMissDirective(name);
|
|
266
|
+
if (nearMiss) {
|
|
267
|
+
errors.push({
|
|
268
|
+
file,
|
|
269
|
+
line: absLine,
|
|
270
|
+
message: `Unknown directive '::${name}' — did you mean '::${nearMiss}'?`,
|
|
271
|
+
suggestion: `Supported leaf directives: ${Object.entries(SUPPORTED_DIRECTIVES).filter(([, v]) => v.leaf).map(([k]) => k).join(', ')}`,
|
|
272
|
+
severity: 'error',
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
// Mark parent container as having content
|
|
277
|
+
if (stack.length > 0) {
|
|
278
|
+
stack[stack.length - 1].hasContent = true;
|
|
279
|
+
}
|
|
280
|
+
continue;
|
|
281
|
+
}
|
|
282
|
+
// Check for unclosed text directive brackets (:name[ without ])
|
|
283
|
+
const textUnclosedMatches = line.matchAll(new RegExp(TEXT_UNCLOSED, 'g'));
|
|
284
|
+
for (const m of textUnclosedMatches) {
|
|
285
|
+
const name = m[1];
|
|
286
|
+
const matchIndex = m.index;
|
|
287
|
+
const beforeMatch = line.substring(0, matchIndex + (m[0].startsWith(':') ? 0 : 1));
|
|
288
|
+
if (/https?$|ftp$|mailto$|tel$/.test(beforeMatch))
|
|
289
|
+
continue;
|
|
290
|
+
if (SUPPORTED_DIRECTIVES[name] || UNSUPPORTED_NAMES.has(name) || findNearMissDirective(name)) {
|
|
291
|
+
errors.push({
|
|
292
|
+
file,
|
|
293
|
+
line: absLine,
|
|
294
|
+
message: `Unclosed bracket in text directive ':${name}[' — missing closing ']'`,
|
|
295
|
+
suggestion: `Add a closing bracket: :${name}[content]`,
|
|
296
|
+
severity: 'error',
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
// Check text/inline directive (:name[...)
|
|
301
|
+
// Must not be preceded by another colon (to avoid matching ::name)
|
|
302
|
+
// Check both :name{attr}[text] and :name[text]{attr} forms
|
|
303
|
+
const seenTextDirectives = new Set(); // track by match index to avoid duplicates
|
|
304
|
+
// Check POST first so :name[text]{attr} captures the attribute before PRE sees it without attr
|
|
305
|
+
for (const pattern of [TEXT_DIRECTIVE_POST, TEXT_DIRECTIVE_PRE]) {
|
|
306
|
+
const textMatches = line.matchAll(new RegExp(pattern, 'g'));
|
|
307
|
+
for (const textMatch of textMatches) {
|
|
308
|
+
const matchIndex = textMatch.index;
|
|
309
|
+
if (seenTextDirectives.has(matchIndex))
|
|
310
|
+
continue;
|
|
311
|
+
seenTextDirectives.add(matchIndex);
|
|
312
|
+
const name = textMatch[1];
|
|
313
|
+
const attr = textMatch[2];
|
|
314
|
+
// Skip URL-like patterns (http:, https:, ftp:, etc.)
|
|
315
|
+
const beforeMatch = line.substring(0, matchIndex + (textMatch[0].startsWith(':') ? 0 : 1));
|
|
316
|
+
if (/https?$|ftp$|mailto$|tel$/.test(beforeMatch))
|
|
317
|
+
continue;
|
|
318
|
+
if (UNSUPPORTED_NAMES.has(name)) {
|
|
319
|
+
errors.push({
|
|
320
|
+
file,
|
|
321
|
+
line: absLine,
|
|
322
|
+
message: `Unsupported directive ':${name}'`,
|
|
323
|
+
suggestion: `Supported text directives: ${Object.entries(SUPPORTED_DIRECTIVES).filter(([, v]) => v.text).map(([k]) => k).join(', ')}`,
|
|
324
|
+
severity: 'error',
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
else if (SUPPORTED_DIRECTIVES[name]) {
|
|
328
|
+
errors.push(...checkAttribute(name, attr, file, absLine));
|
|
329
|
+
}
|
|
330
|
+
else {
|
|
331
|
+
const nearMiss = findNearMissDirective(name);
|
|
332
|
+
if (nearMiss) {
|
|
333
|
+
errors.push({
|
|
334
|
+
file,
|
|
335
|
+
line: absLine,
|
|
336
|
+
message: `Unknown directive ':${name}' — did you mean ':${nearMiss}'?`,
|
|
337
|
+
suggestion: `Supported text directives: ${Object.entries(SUPPORTED_DIRECTIVES).filter(([, v]) => v.text).map(([k]) => k).join(', ')}`,
|
|
338
|
+
severity: 'error',
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
// Mark parent container as having content
|
|
343
|
+
if (stack.length > 0) {
|
|
344
|
+
stack[stack.length - 1].hasContent = true;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
// Mark content in parent container (non-blank, non-directive line)
|
|
349
|
+
if (stack.length > 0 && line.trim() !== '') {
|
|
350
|
+
stack[stack.length - 1].hasContent = true;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
// Report unclosed containers
|
|
354
|
+
for (const entry of stack) {
|
|
355
|
+
errors.push({
|
|
356
|
+
file,
|
|
357
|
+
line: entry.line,
|
|
358
|
+
message: `Unclosed container directive ':::${entry.name}'`,
|
|
359
|
+
suggestion: 'Add a closing ::: marker',
|
|
360
|
+
severity: 'error',
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
return errors;
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Lightweight check for directives in non-article content (e.g., lens text segments).
|
|
367
|
+
* Returns a single warning per match since directives won't render outside articles.
|
|
368
|
+
*/
|
|
369
|
+
export function detectDirectivesInNonArticle(content, file, line) {
|
|
370
|
+
const lines = content.split('\n');
|
|
371
|
+
let inCodeBlock = false;
|
|
372
|
+
for (const l of lines) {
|
|
373
|
+
if (CODE_FENCE.test(l)) {
|
|
374
|
+
inCodeBlock = !inCodeBlock;
|
|
375
|
+
continue;
|
|
376
|
+
}
|
|
377
|
+
if (inCodeBlock)
|
|
378
|
+
continue;
|
|
379
|
+
// Container directive
|
|
380
|
+
if (CONTAINER_OPEN.test(l)) {
|
|
381
|
+
const match = l.match(CONTAINER_OPEN);
|
|
382
|
+
if (ALL_DIRECTIVE_NAMES.has(match[1])) {
|
|
383
|
+
return [{
|
|
384
|
+
file,
|
|
385
|
+
line,
|
|
386
|
+
message: `Directive ':::${match[1]}' found in non-article content — directives only render in article files`,
|
|
387
|
+
suggestion: 'Move this content to an article file (articles/*.md) or remove the directive syntax',
|
|
388
|
+
severity: 'warning',
|
|
389
|
+
}];
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
// Leaf directive
|
|
393
|
+
const leafMatch = l.match(LEAF_DIRECTIVE_PRE);
|
|
394
|
+
if (leafMatch && ALL_DIRECTIVE_NAMES.has(leafMatch[1])) {
|
|
395
|
+
return [{
|
|
396
|
+
file,
|
|
397
|
+
line,
|
|
398
|
+
message: `Directive '::${leafMatch[1]}' found in non-article content — directives only render in article files`,
|
|
399
|
+
suggestion: 'Move this content to an article file (articles/*.md) or remove the directive syntax',
|
|
400
|
+
severity: 'warning',
|
|
401
|
+
}];
|
|
402
|
+
}
|
|
403
|
+
// Text/inline directive — scan for :name[ patterns (both pre and post attribute forms)
|
|
404
|
+
for (const pattern of [TEXT_DIRECTIVE_PRE, TEXT_DIRECTIVE_POST]) {
|
|
405
|
+
const textRegex = new RegExp(pattern, 'g');
|
|
406
|
+
let textMatch;
|
|
407
|
+
while ((textMatch = textRegex.exec(l)) !== null) {
|
|
408
|
+
const name = textMatch[1];
|
|
409
|
+
// Skip URL-like patterns
|
|
410
|
+
const matchIndex = textMatch.index;
|
|
411
|
+
const beforeMatch = l.substring(0, matchIndex + (textMatch[0].startsWith(':') ? 0 : 1));
|
|
412
|
+
if (/https?$|ftp$|mailto$|tel$/.test(beforeMatch))
|
|
413
|
+
continue;
|
|
414
|
+
if (ALL_DIRECTIVE_NAMES.has(name)) {
|
|
415
|
+
return [{
|
|
416
|
+
file,
|
|
417
|
+
line,
|
|
418
|
+
message: `Directive ':${name}' found in non-article content — directives only render in article files`,
|
|
419
|
+
suggestion: 'Move this content to an article file (articles/*.md) or remove the directive syntax',
|
|
420
|
+
severity: 'warning',
|
|
421
|
+
}];
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
return [];
|
|
427
|
+
}
|
|
428
|
+
//# sourceMappingURL=directives.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"directives.js","sourceRoot":"","sources":["../../src/validator/directives.ts"],"names":[],"mappings":"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"}
|
|
@@ -60,6 +60,10 @@ export function validateSlugFormat(slug, file, line) {
|
|
|
60
60
|
}
|
|
61
61
|
return null;
|
|
62
62
|
}
|
|
63
|
+
function isEmptyValue(value) {
|
|
64
|
+
const trimmed = value.trim();
|
|
65
|
+
return trimmed === '' || trimmed === '""' || trimmed === "''";
|
|
66
|
+
}
|
|
63
67
|
/**
|
|
64
68
|
* Validate field values, checking for appropriate types.
|
|
65
69
|
* Currently validates that boolean fields contain 'true' or 'false'.
|
|
@@ -72,6 +76,16 @@ export function validateSlugFormat(slug, file, line) {
|
|
|
72
76
|
export function validateFieldValues(fields, file, line) {
|
|
73
77
|
const warnings = [];
|
|
74
78
|
for (const [name, value] of Object.entries(fields)) {
|
|
79
|
+
// Check for empty 'from' field
|
|
80
|
+
if (name === 'from' && isEmptyValue(value)) {
|
|
81
|
+
warnings.push({
|
|
82
|
+
file,
|
|
83
|
+
line,
|
|
84
|
+
message: `Field 'from' is empty and can be omitted`,
|
|
85
|
+
suggestion: 'Without a from:: field, the content shows from the start',
|
|
86
|
+
severity: 'warning',
|
|
87
|
+
});
|
|
88
|
+
}
|
|
75
89
|
// Check if this is a boolean field
|
|
76
90
|
if (ALL_BOOLEAN_FIELDS.includes(name)) {
|
|
77
91
|
const normalizedValue = value.toLowerCase();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"field-values.js","sourceRoot":"","sources":["../../src/validator/field-values.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE1D;;;GAGG;AACH,MAAM,kBAAkB,GAAG,0BAA0B,CAAC;AAEtD;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,kBAAkB,CAChC,IAAY,EACZ,IAAY,EACZ,IAAY;IAEZ,4DAA4D;IAC5D,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACvB,OAAO;YACL,IAAI;YACJ,IAAI;YACJ,OAAO,EAAE,wBAAwB,IAAI,+BAA+B;YACpE,UAAU,EAAE,4BAA4B,IAAI,CAAC,WAAW,EAAE,GAAG;YAC7D,QAAQ,EAAE,OAAO;SAClB,CAAC;IACJ,CAAC;IAED,2BAA2B;IAC3B,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACzB,OAAO;YACL,IAAI;YACJ,IAAI;YACJ,OAAO,EAAE,wBAAwB,IAAI,+BAA+B;YACpE,UAAU,EAAE,2BAA2B;YACvC,QAAQ,EAAE,OAAO;SAClB,CAAC;IACJ,CAAC;IAED,4BAA4B;IAC5B,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO;YACL,IAAI;YACJ,IAAI;YACJ,OAAO,EAAE,wBAAwB,IAAI,6BAA6B;YAClE,UAAU,EAAE,4BAA4B;YACxC,QAAQ,EAAE,OAAO;SAClB,CAAC;IACJ,CAAC;IAED,2DAA2D;IAC3D,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,OAAO;YACL,IAAI;YACJ,IAAI;YACJ,OAAO,EAAE,wBAAwB,IAAI,8DAA8D;YACnG,UAAU,EAAE,oCAAoC;YAChD,QAAQ,EAAE,OAAO;SAClB,CAAC;IACJ,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,mBAAmB,CACjC,MAA8B,EAC9B,IAAY,EACZ,IAAY;IAEZ,MAAM,QAAQ,GAAmB,EAAE,CAAC;IAEpC,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QACnD,mCAAmC;QACnC,IAAI,kBAAkB,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACtC,MAAM,eAAe,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;YAC5C,IAAI,eAAe,KAAK,MAAM,IAAI,eAAe,KAAK,OAAO,EAAE,CAAC;gBAC9D,QAAQ,CAAC,IAAI,CAAC;oBACZ,IAAI;oBACJ,IAAI;oBACJ,OAAO,EAAE,UAAU,IAAI,4BAA4B,KAAK,GAAG;oBAC3D,UAAU,EAAE,4BAA4B;oBACxC,QAAQ,EAAE,SAAS;iBACpB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
1
|
+
{"version":3,"file":"field-values.js","sourceRoot":"","sources":["../../src/validator/field-values.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE1D;;;GAGG;AACH,MAAM,kBAAkB,GAAG,0BAA0B,CAAC;AAEtD;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,kBAAkB,CAChC,IAAY,EACZ,IAAY,EACZ,IAAY;IAEZ,4DAA4D;IAC5D,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACvB,OAAO;YACL,IAAI;YACJ,IAAI;YACJ,OAAO,EAAE,wBAAwB,IAAI,+BAA+B;YACpE,UAAU,EAAE,4BAA4B,IAAI,CAAC,WAAW,EAAE,GAAG;YAC7D,QAAQ,EAAE,OAAO;SAClB,CAAC;IACJ,CAAC;IAED,2BAA2B;IAC3B,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACzB,OAAO;YACL,IAAI;YACJ,IAAI;YACJ,OAAO,EAAE,wBAAwB,IAAI,+BAA+B;YACpE,UAAU,EAAE,2BAA2B;YACvC,QAAQ,EAAE,OAAO;SAClB,CAAC;IACJ,CAAC;IAED,4BAA4B;IAC5B,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO;YACL,IAAI;YACJ,IAAI;YACJ,OAAO,EAAE,wBAAwB,IAAI,6BAA6B;YAClE,UAAU,EAAE,4BAA4B;YACxC,QAAQ,EAAE,OAAO;SAClB,CAAC;IACJ,CAAC;IAED,2DAA2D;IAC3D,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,OAAO;YACL,IAAI;YACJ,IAAI;YACJ,OAAO,EAAE,wBAAwB,IAAI,8DAA8D;YACnG,UAAU,EAAE,oCAAoC;YAChD,QAAQ,EAAE,OAAO;SAClB,CAAC;IACJ,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,YAAY,CAAC,KAAa;IACjC,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,OAAO,OAAO,KAAK,EAAE,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,KAAK,IAAI,CAAC;AAChE,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,mBAAmB,CACjC,MAA8B,EAC9B,IAAY,EACZ,IAAY;IAEZ,MAAM,QAAQ,GAAmB,EAAE,CAAC;IAEpC,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QACnD,+BAA+B;QAC/B,IAAI,IAAI,KAAK,MAAM,IAAI,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3C,QAAQ,CAAC,IAAI,CAAC;gBACZ,IAAI;gBACJ,IAAI;gBACJ,OAAO,EAAE,0CAA0C;gBACnD,UAAU,EACR,0DAA0D;gBAC5D,QAAQ,EAAE,SAAS;aACpB,CAAC,CAAC;QACL,CAAC;QAED,mCAAmC;QACnC,IAAI,kBAAkB,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACtC,MAAM,eAAe,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;YAC5C,IAAI,eAAe,KAAK,MAAM,IAAI,eAAe,KAAK,OAAO,EAAE,CAAC;gBAC9D,QAAQ,CAAC,IAAI,CAAC;oBACZ,IAAI;oBACJ,IAAI;oBACJ,OAAO,EAAE,UAAU,IAAI,4BAA4B,KAAK,GAAG;oBAC3D,UAAU,EAAE,4BAA4B;oBACxC,QAAQ,EAAE,SAAS;iBACpB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -2,6 +2,8 @@ const CONCURRENCY = 10;
|
|
|
2
2
|
const TIMEOUT_MS = 15_000;
|
|
3
3
|
// Status codes that mean "server is alive" even though response.ok is false
|
|
4
4
|
const REACHABLE_STATUSES = new Set([429]);
|
|
5
|
+
// Status codes that definitively mean the resource doesn't exist
|
|
6
|
+
const NOT_FOUND_STATUSES = new Set([404, 410]);
|
|
5
7
|
async function fetchWithTimeout(url, method, signal) {
|
|
6
8
|
return fetch(url, { method, signal });
|
|
7
9
|
}
|
|
@@ -20,7 +22,7 @@ async function checkUrl(entry) {
|
|
|
20
22
|
file: entry.file,
|
|
21
23
|
line: entry.line,
|
|
22
24
|
message: `${entry.label} returned HTTP ${response.status}: ${entry.url}`,
|
|
23
|
-
severity: 'warning',
|
|
25
|
+
severity: NOT_FOUND_STATUSES.has(response.status) ? 'error' : 'warning',
|
|
24
26
|
};
|
|
25
27
|
}
|
|
26
28
|
return null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"url-reachability.js","sourceRoot":"","sources":["../../src/validator/url-reachability.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,GAAG,EAAE,CAAC;AACvB,MAAM,UAAU,GAAG,MAAM,CAAC;AAE1B,4EAA4E;AAC5E,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;AAE1C,KAAK,UAAU,gBAAgB,CAAC,GAAW,EAAE,MAAc,EAAE,MAAmB;IAC9E,OAAO,KAAK,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;AACxC,CAAC;AAED,KAAK,UAAU,QAAQ,CAAC,KAAoB;IAC1C,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,UAAU,CAAC,CAAC;QAEjE,IAAI,QAAQ,GAAG,MAAM,gBAAgB,CAAC,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;QAE5E,4CAA4C;QAC5C,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YAC5B,QAAQ,GAAG,MAAM,gBAAgB,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;QACzE,CAAC;QAED,YAAY,CAAC,OAAO,CAAC,CAAC;QAEtB,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YAC7D,OAAO;gBACL,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,OAAO,EAAE,GAAG,KAAK,CAAC,KAAK,kBAAkB,QAAQ,CAAC,MAAM,KAAK,KAAK,CAAC,GAAG,EAAE;gBACxE,QAAQ,EAAE,SAAS;
|
|
1
|
+
{"version":3,"file":"url-reachability.js","sourceRoot":"","sources":["../../src/validator/url-reachability.ts"],"names":[],"mappings":"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"}
|
package/dist/validator/uuid.js
CHANGED
|
@@ -30,12 +30,15 @@ export function validateUuids(entries) {
|
|
|
30
30
|
// Duplicate detection
|
|
31
31
|
const existing = seenUuids.get(lowerUuid);
|
|
32
32
|
if (existing) {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
33
|
+
// Allow same-file, same-field duplicates (e.g., contentId shared across submodule groups)
|
|
34
|
+
if (existing.file !== entry.file || existing.field !== entry.field) {
|
|
35
|
+
errors.push({
|
|
36
|
+
file: entry.file,
|
|
37
|
+
message: `Duplicate UUID '${entry.uuid}' - also used in ${existing.file} (${existing.field})`,
|
|
38
|
+
suggestion: 'Each UUID must be unique across the entire vault',
|
|
39
|
+
severity: 'error',
|
|
40
|
+
});
|
|
41
|
+
}
|
|
39
42
|
}
|
|
40
43
|
else {
|
|
41
44
|
seenUuids.set(lowerUuid, entry);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uuid.js","sourceRoot":"","sources":["../../src/validator/uuid.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,MAAM,UAAU,GAAG,iEAAiE,CAAC;AAErF;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,OAAO,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAChC,CAAC;AAYD;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,OAAoB;IAChD,MAAM,MAAM,GAAmB,EAAE,CAAC;IAClC,MAAM,SAAS,GAAG,IAAI,GAAG,EAAqB,CAAC,CAAC,2BAA2B;IAE3E,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;QAE3C,oBAAoB;QACpB,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7B,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,OAAO,EAAE,2BAA2B,KAAK,CAAC,KAAK,MAAM,KAAK,CAAC,IAAI,GAAG;gBAClE,UAAU,EAAE,0FAA0F;gBACtG,QAAQ,EAAE,OAAO;aAClB,CAAC,CAAC;YACH,SAAS,CAAC,yCAAyC;QACrD,CAAC;QAED,sBAAsB;QACtB,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC1C,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"uuid.js","sourceRoot":"","sources":["../../src/validator/uuid.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,MAAM,UAAU,GAAG,iEAAiE,CAAC;AAErF;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,OAAO,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAChC,CAAC;AAYD;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,OAAoB;IAChD,MAAM,MAAM,GAAmB,EAAE,CAAC;IAClC,MAAM,SAAS,GAAG,IAAI,GAAG,EAAqB,CAAC,CAAC,2BAA2B;IAE3E,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;QAE3C,oBAAoB;QACpB,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7B,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,OAAO,EAAE,2BAA2B,KAAK,CAAC,KAAK,MAAM,KAAK,CAAC,IAAI,GAAG;gBAClE,UAAU,EAAE,0FAA0F;gBACtG,QAAQ,EAAE,OAAO;aAClB,CAAC,CAAC;YACH,SAAS,CAAC,yCAAyC;QACrD,CAAC;QAED,sBAAsB;QACtB,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC1C,IAAI,QAAQ,EAAE,CAAC;YACb,0FAA0F;YAC1F,IAAI,QAAQ,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,IAAI,QAAQ,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK,EAAE,CAAC;gBACnE,MAAM,CAAC,IAAI,CAAC;oBACV,IAAI,EAAE,KAAK,CAAC,IAAI;oBAChB,OAAO,EAAE,mBAAmB,KAAK,CAAC,IAAI,oBAAoB,QAAQ,CAAC,IAAI,KAAK,QAAQ,CAAC,KAAK,GAAG;oBAC7F,UAAU,EAAE,kDAAkD;oBAC9D,QAAQ,EAAE,OAAO;iBAClB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;aAAM,CAAC;YACN,SAAS,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,CAAC;AACpB,CAAC"}
|
package/package.json
CHANGED