lens-content-processor 0.1.0 → 0.2.1
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/cli.js +5 -1
- package/dist/cli.js.map +1 -1
- package/dist/flattener/index.js +25 -7
- package/dist/flattener/index.js.map +1 -1
- package/dist/index.js +23 -2
- package/dist/index.js.map +1 -1
- package/dist/parser/learning-outcome.js +16 -1
- package/dist/parser/learning-outcome.js.map +1 -1
- package/dist/parser/lens.js +18 -0
- package/dist/parser/lens.js.map +1 -1
- package/dist/parser/wikilink.d.ts +28 -0
- package/dist/parser/wikilink.js +154 -0
- package/dist/parser/wikilink.js.map +1 -1
- package/package.json +1 -1
- package/dist/bundler/article.test.d.ts +0 -1
- package/dist/bundler/article.test.js +0 -212
- package/dist/bundler/article.test.js.map +0 -1
- package/dist/bundler/video.test.d.ts +0 -1
- package/dist/bundler/video.test.js +0 -95
- package/dist/bundler/video.test.js.map +0 -1
- package/dist/cli.test.d.ts +0 -1
- package/dist/cli.test.js +0 -45
- package/dist/cli.test.js.map +0 -1
- package/dist/flattener/index.test.d.ts +0 -1
- package/dist/flattener/index.test.js +0 -547
- package/dist/flattener/index.test.js.map +0 -1
- package/dist/fs/read-vault.test.d.ts +0 -1
- package/dist/fs/read-vault.test.js +0 -37
- package/dist/fs/read-vault.test.js.map +0 -1
- package/dist/parser/course.test.d.ts +0 -1
- package/dist/parser/course.test.js +0 -117
- package/dist/parser/course.test.js.map +0 -1
- package/dist/parser/frontmatter.test.d.ts +0 -1
- package/dist/parser/frontmatter.test.js +0 -54
- package/dist/parser/frontmatter.test.js.map +0 -1
- package/dist/parser/learning-outcome.test.d.ts +0 -1
- package/dist/parser/learning-outcome.test.js +0 -75
- package/dist/parser/learning-outcome.test.js.map +0 -1
- package/dist/parser/lens.test.d.ts +0 -1
- package/dist/parser/lens.test.js +0 -453
- package/dist/parser/lens.test.js.map +0 -1
- package/dist/parser/module.test.d.ts +0 -1
- package/dist/parser/module.test.js +0 -99
- package/dist/parser/module.test.js.map +0 -1
- package/dist/parser/sections.test.d.ts +0 -1
- package/dist/parser/sections.test.js +0 -297
- package/dist/parser/sections.test.js.map +0 -1
- package/dist/parser/wikilink.test.d.ts +0 -1
- package/dist/parser/wikilink.test.js +0 -76
- package/dist/parser/wikilink.test.js.map +0 -1
- package/dist/validator/field-typos.test.d.ts +0 -1
- package/dist/validator/field-typos.test.js +0 -41
- package/dist/validator/field-typos.test.js.map +0 -1
- package/dist/validator/field-values.test.d.ts +0 -1
- package/dist/validator/field-values.test.js +0 -45
- package/dist/validator/field-values.test.js.map +0 -1
- package/dist/validator/segment-fields.test.d.ts +0 -1
- package/dist/validator/segment-fields.test.js +0 -73
- package/dist/validator/segment-fields.test.js.map +0 -1
- package/dist/validator/standalone.test.d.ts +0 -1
- package/dist/validator/standalone.test.js +0 -190
- package/dist/validator/standalone.test.js.map +0 -1
- package/dist/validator/uuid.test.d.ts +0 -1
- package/dist/validator/uuid.test.js +0 -229
- package/dist/validator/uuid.test.js.map +0 -1
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
// src/parser/course.test.ts
|
|
2
|
-
import { describe, it, expect } from 'vitest';
|
|
3
|
-
import { parseCourse } from './course.js';
|
|
4
|
-
describe('parseCourse', () => {
|
|
5
|
-
it('parses course with module references', () => {
|
|
6
|
-
const content = `---
|
|
7
|
-
slug: intro-course
|
|
8
|
-
title: Introduction to AI Safety
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
# Module: [[../modules/intro.md|Introduction]]
|
|
12
|
-
|
|
13
|
-
# Module: [[../modules/advanced.md|Advanced Topics]]
|
|
14
|
-
optional:: true
|
|
15
|
-
|
|
16
|
-
# Meeting: 1
|
|
17
|
-
|
|
18
|
-
# Module: [[../modules/conclusion.md|Conclusion]]
|
|
19
|
-
`;
|
|
20
|
-
const result = parseCourse(content, 'courses/intro.md');
|
|
21
|
-
expect(result.course?.slug).toBe('intro-course');
|
|
22
|
-
expect(result.course?.title).toBe('Introduction to AI Safety');
|
|
23
|
-
expect(result.course?.progression).toHaveLength(4);
|
|
24
|
-
expect(result.course?.progression[0].type).toBe('module');
|
|
25
|
-
expect(result.course?.progression[0].slug).toBe('intro');
|
|
26
|
-
expect(result.course?.progression[0].optional).toBe(false);
|
|
27
|
-
expect(result.course?.progression[1].type).toBe('module');
|
|
28
|
-
expect(result.course?.progression[1].slug).toBe('advanced');
|
|
29
|
-
expect(result.course?.progression[1].optional).toBe(true);
|
|
30
|
-
expect(result.course?.progression[2].type).toBe('meeting');
|
|
31
|
-
expect(result.course?.progression[2].number).toBe(1);
|
|
32
|
-
expect(result.course?.progression[3].type).toBe('module');
|
|
33
|
-
expect(result.course?.progression[3].slug).toBe('conclusion');
|
|
34
|
-
expect(result.errors).toHaveLength(0);
|
|
35
|
-
});
|
|
36
|
-
it('validates module references exist', () => {
|
|
37
|
-
const content = `---
|
|
38
|
-
slug: broken-course
|
|
39
|
-
title: Broken Course
|
|
40
|
-
---
|
|
41
|
-
|
|
42
|
-
# Module: [[../modules/nonexistent.md|Missing]]
|
|
43
|
-
`;
|
|
44
|
-
// Note: Reference validation happens in processContent, not parseCourse
|
|
45
|
-
// parseCourse only parses the structure, it does not validate file existence
|
|
46
|
-
const result = parseCourse(content, 'courses/broken.md');
|
|
47
|
-
expect(result.course).toBeDefined();
|
|
48
|
-
expect(result.course?.slug).toBe('broken-course');
|
|
49
|
-
expect(result.course?.progression).toHaveLength(1);
|
|
50
|
-
expect(result.course?.progression[0].type).toBe('module');
|
|
51
|
-
expect(result.course?.progression[0].slug).toBe('nonexistent');
|
|
52
|
-
// Errors about missing modules are added during processContent, not parseCourse
|
|
53
|
-
});
|
|
54
|
-
it('handles missing frontmatter', () => {
|
|
55
|
-
const content = `# Module: [[../modules/intro.md|Introduction]]`;
|
|
56
|
-
const result = parseCourse(content, 'courses/bad.md');
|
|
57
|
-
expect(result.course).toBeNull();
|
|
58
|
-
expect(result.errors.length).toBeGreaterThan(0);
|
|
59
|
-
expect(result.errors[0].message).toContain('frontmatter');
|
|
60
|
-
});
|
|
61
|
-
it('requires slug in frontmatter', () => {
|
|
62
|
-
const content = `---
|
|
63
|
-
title: Course Without Slug
|
|
64
|
-
---
|
|
65
|
-
|
|
66
|
-
# Module: [[../modules/intro.md|Introduction]]
|
|
67
|
-
`;
|
|
68
|
-
const result = parseCourse(content, 'courses/no-slug.md');
|
|
69
|
-
expect(result.course).toBeNull();
|
|
70
|
-
expect(result.errors.some(e => e.message.includes('slug'))).toBe(true);
|
|
71
|
-
});
|
|
72
|
-
it('requires title in frontmatter', () => {
|
|
73
|
-
const content = `---
|
|
74
|
-
slug: no-title-course
|
|
75
|
-
---
|
|
76
|
-
|
|
77
|
-
# Module: [[../modules/intro.md|Introduction]]
|
|
78
|
-
`;
|
|
79
|
-
const result = parseCourse(content, 'courses/no-title.md');
|
|
80
|
-
expect(result.course).toBeNull();
|
|
81
|
-
expect(result.errors.some(e => e.message.includes('title'))).toBe(true);
|
|
82
|
-
});
|
|
83
|
-
it('reports error for unknown section types', () => {
|
|
84
|
-
const content = `---
|
|
85
|
-
slug: test-course
|
|
86
|
-
title: Test Course
|
|
87
|
-
---
|
|
88
|
-
|
|
89
|
-
# Unknown: Bad Section
|
|
90
|
-
`;
|
|
91
|
-
const result = parseCourse(content, 'courses/unknown.md');
|
|
92
|
-
expect(result.errors.some(e => e.message.includes('Unknown section type'))).toBe(true);
|
|
93
|
-
});
|
|
94
|
-
it('reports error for Module section without wikilink', () => {
|
|
95
|
-
const content = `---
|
|
96
|
-
slug: test-course
|
|
97
|
-
title: Test Course
|
|
98
|
-
---
|
|
99
|
-
|
|
100
|
-
# Module: No Wikilink Here
|
|
101
|
-
`;
|
|
102
|
-
const result = parseCourse(content, 'courses/no-link.md');
|
|
103
|
-
expect(result.errors.some(e => e.message.includes('wikilink'))).toBe(true);
|
|
104
|
-
});
|
|
105
|
-
it('reports error for Meeting section without number', () => {
|
|
106
|
-
const content = `---
|
|
107
|
-
slug: test-course
|
|
108
|
-
title: Test Course
|
|
109
|
-
---
|
|
110
|
-
|
|
111
|
-
# Meeting: not a number
|
|
112
|
-
`;
|
|
113
|
-
const result = parseCourse(content, 'courses/bad-meeting.md');
|
|
114
|
-
expect(result.errors.some(e => e.message.includes('number'))).toBe(true);
|
|
115
|
-
});
|
|
116
|
-
});
|
|
117
|
-
//# sourceMappingURL=course.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"course.test.js","sourceRoot":"","sources":["../../src/parser/course.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
// src/parser/frontmatter.test.ts
|
|
2
|
-
import { describe, it, expect } from 'vitest';
|
|
3
|
-
import { parseFrontmatter } from './frontmatter';
|
|
4
|
-
describe('parseFrontmatter', () => {
|
|
5
|
-
it('extracts frontmatter fields', () => {
|
|
6
|
-
const content = `---
|
|
7
|
-
slug: my-module
|
|
8
|
-
title: My Module Title
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
# Content here`;
|
|
12
|
-
const result = parseFrontmatter(content);
|
|
13
|
-
expect(result.frontmatter).toEqual({
|
|
14
|
-
slug: 'my-module',
|
|
15
|
-
title: 'My Module Title',
|
|
16
|
-
});
|
|
17
|
-
expect(result.body).toBe('\n# Content here');
|
|
18
|
-
expect(result.bodyStartLine).toBe(5);
|
|
19
|
-
});
|
|
20
|
-
it('returns error for missing frontmatter', () => {
|
|
21
|
-
const content = '# No frontmatter here';
|
|
22
|
-
const result = parseFrontmatter(content);
|
|
23
|
-
expect(result.error).toBeDefined();
|
|
24
|
-
expect(result.error?.message).toBe('Missing frontmatter');
|
|
25
|
-
expect(result.error?.line).toBe(1);
|
|
26
|
-
});
|
|
27
|
-
it('returns error for unclosed frontmatter', () => {
|
|
28
|
-
const content = `---
|
|
29
|
-
slug: broken
|
|
30
|
-
title: Never Closed`;
|
|
31
|
-
const result = parseFrontmatter(content);
|
|
32
|
-
expect(result.error).toBeDefined();
|
|
33
|
-
expect(result.error?.message).toContain('Unclosed frontmatter');
|
|
34
|
-
});
|
|
35
|
-
it('includes file path in error when provided', () => {
|
|
36
|
-
const content = '# No frontmatter here';
|
|
37
|
-
const result = parseFrontmatter(content, 'modules/test.md');
|
|
38
|
-
expect(result.error).toBeDefined();
|
|
39
|
-
expect(result.error?.file).toBe('modules/test.md');
|
|
40
|
-
});
|
|
41
|
-
it('handles invalid YAML syntax', () => {
|
|
42
|
-
const content = `---
|
|
43
|
-
slug: test
|
|
44
|
-
title: [invalid yaml
|
|
45
|
-
---
|
|
46
|
-
|
|
47
|
-
# Content`;
|
|
48
|
-
const result = parseFrontmatter(content);
|
|
49
|
-
expect(result.error).toBeDefined();
|
|
50
|
-
expect(result.error?.message).toContain('Invalid YAML');
|
|
51
|
-
expect(result.error?.line).toBe(2);
|
|
52
|
-
});
|
|
53
|
-
});
|
|
54
|
-
//# sourceMappingURL=frontmatter.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"frontmatter.test.js","sourceRoot":"","sources":["../../src/parser/frontmatter.test.ts"],"names":[],"mappings":"AAAA,iCAAiC;AACjC,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEjD,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;QACrC,MAAM,OAAO,GAAG;;;;;eAKL,CAAC;QAEZ,MAAM,MAAM,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAEzC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC;YACjC,IAAI,EAAE,WAAW;YACjB,KAAK,EAAE,iBAAiB;SACzB,CAAC,CAAC;QACH,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QAC7C,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC/C,MAAM,OAAO,GAAG,uBAAuB,CAAC;QAExC,MAAM,MAAM,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAEzC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;QACnC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;QAC1D,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;QAChD,MAAM,OAAO,GAAG;;oBAEA,CAAC;QAEjB,MAAM,MAAM,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAEzC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;QACnC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACnD,MAAM,OAAO,GAAG,uBAAuB,CAAC;QAExC,MAAM,MAAM,GAAG,gBAAgB,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAC;QAE5D,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;QACnC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;QACrC,MAAM,OAAO,GAAG;;;;;UAKV,CAAC;QAEP,MAAM,MAAM,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAEzC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;QACnC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;QACxD,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
// src/parser/learning-outcome.test.ts
|
|
2
|
-
import { describe, it, expect } from 'vitest';
|
|
3
|
-
import { parseLearningOutcome } from './learning-outcome.js';
|
|
4
|
-
describe('parseLearningOutcome', () => {
|
|
5
|
-
it('parses LO with multiple lenses', () => {
|
|
6
|
-
const content = `---
|
|
7
|
-
id: 550e8400-e29b-41d4-a716-446655440001
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
## Lens: First Lens
|
|
11
|
-
source:: [[../Lenses/lens1.md|Lens 1]]
|
|
12
|
-
|
|
13
|
-
## Lens: Second Lens
|
|
14
|
-
source:: [[../Lenses/lens2.md|Lens 2]]
|
|
15
|
-
optional:: true
|
|
16
|
-
|
|
17
|
-
## Test: Knowledge Check
|
|
18
|
-
source:: [[../Tests/test1.md|Test]]
|
|
19
|
-
`;
|
|
20
|
-
const result = parseLearningOutcome(content, 'Learning Outcomes/lo1.md');
|
|
21
|
-
expect(result.learningOutcome?.id).toBe('550e8400-e29b-41d4-a716-446655440001');
|
|
22
|
-
expect(result.learningOutcome?.lenses).toHaveLength(2);
|
|
23
|
-
expect(result.learningOutcome?.lenses[0].source).toBe('[[../Lenses/lens1.md|Lens 1]]');
|
|
24
|
-
expect(result.learningOutcome?.lenses[0].resolvedPath).toBe('Lenses/lens1.md');
|
|
25
|
-
expect(result.learningOutcome?.lenses[0].optional).toBe(false);
|
|
26
|
-
expect(result.learningOutcome?.lenses[1].source).toBe('[[../Lenses/lens2.md|Lens 2]]');
|
|
27
|
-
expect(result.learningOutcome?.lenses[1].resolvedPath).toBe('Lenses/lens2.md');
|
|
28
|
-
expect(result.learningOutcome?.lenses[1].optional).toBe(true);
|
|
29
|
-
expect(result.learningOutcome?.test?.source).toContain('test1.md');
|
|
30
|
-
expect(result.learningOutcome?.test?.resolvedPath).toBe('Tests/test1.md');
|
|
31
|
-
expect(result.errors).toHaveLength(0);
|
|
32
|
-
});
|
|
33
|
-
it('requires id in frontmatter', () => {
|
|
34
|
-
const content = `---
|
|
35
|
-
title: Missing ID
|
|
36
|
-
---
|
|
37
|
-
|
|
38
|
-
## Lens: Test
|
|
39
|
-
source:: [[../Lenses/lens1.md|Lens]]
|
|
40
|
-
`;
|
|
41
|
-
const result = parseLearningOutcome(content, 'Learning Outcomes/bad.md');
|
|
42
|
-
expect(result.errors).toHaveLength(1);
|
|
43
|
-
expect(result.errors[0].message).toContain('id');
|
|
44
|
-
});
|
|
45
|
-
it('requires at least one lens', () => {
|
|
46
|
-
const content = `---
|
|
47
|
-
id: 550e8400-e29b-41d4-a716-446655440001
|
|
48
|
-
---
|
|
49
|
-
|
|
50
|
-
No lenses here.
|
|
51
|
-
`;
|
|
52
|
-
const result = parseLearningOutcome(content, 'Learning Outcomes/empty.md');
|
|
53
|
-
expect(result.errors.some(e => e.message.includes('Lens'))).toBe(true);
|
|
54
|
-
});
|
|
55
|
-
it('allows test section without source:: field (tests not implemented yet)', () => {
|
|
56
|
-
const content = `---
|
|
57
|
-
id: 550e8400-e29b-41d4-a716-446655440001
|
|
58
|
-
---
|
|
59
|
-
|
|
60
|
-
## Lens: Main Content
|
|
61
|
-
source:: [[../Lenses/lens1.md|Lens 1]]
|
|
62
|
-
|
|
63
|
-
## Test: Knowledge Check
|
|
64
|
-
`;
|
|
65
|
-
const result = parseLearningOutcome(content, 'Learning Outcomes/lo1.md');
|
|
66
|
-
// Should NOT produce an error for missing source:: in test section
|
|
67
|
-
expect(result.errors).toHaveLength(0);
|
|
68
|
-
// The LO should be parsed successfully
|
|
69
|
-
expect(result.learningOutcome?.id).toBe('550e8400-e29b-41d4-a716-446655440001');
|
|
70
|
-
expect(result.learningOutcome?.lenses).toHaveLength(1);
|
|
71
|
-
// Test should be undefined since no source was provided
|
|
72
|
-
expect(result.learningOutcome?.test).toBeUndefined();
|
|
73
|
-
});
|
|
74
|
-
});
|
|
75
|
-
//# sourceMappingURL=learning-outcome.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"learning-outcome.test.js","sourceRoot":"","sources":["../../src/parser/learning-outcome.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|