@lessonkit/lxpack 0.6.0 → 0.8.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/README.md CHANGED
@@ -1,9 +1,15 @@
1
1
  # @lessonkit/lxpack
2
2
 
3
+ [![Documentation](https://readthedocs.org/projects/lessonkit/badge/?version=latest)](https://lessonkit.readthedocs.io/en/latest/)
4
+ [![npm](https://img.shields.io/npm/v/@lessonkit/lxpack.svg)](https://www.npmjs.com/package/@lessonkit/lxpack)
5
+ [![License](https://img.shields.io/github/license/eddiethedean/lessonkit)](https://github.com/eddiethedean/lessonkit/blob/main/LICENSE)
6
+
3
7
  LXPack export adapter for LessonKit — write `lessonkit.json` + `course.yaml`, copy SPA builds, and package to SCORM / standalone / xAPI / cmi5 via [`@lxpack/api`](https://www.npmjs.com/package/@lxpack/api).
4
8
 
5
9
  Requires **Node.js 20+**.
6
10
 
11
+ **Docs:** [Packaging reference](https://lessonkit.readthedocs.io/en/latest/reference/packaging.html) · [Packaging & CLI guide](https://lessonkit.readthedocs.io/en/latest/guides/react-developers/packaging-and-cli.html) · [Live examples](https://lessonkit.readthedocs.io/en/latest/examples/index.html)
12
+
7
13
  ## Install
8
14
 
9
15
  ```bash
@@ -27,7 +33,7 @@ const result = await packageLessonkitCourse({
27
33
  if (!result.ok) throw new Error("packaging failed");
28
34
  ```
29
35
 
30
- See [`docs/PACKAGING.md`](../../docs/PACKAGING.md) and [`examples/lxpack-golden`](../../examples/lxpack-golden).
36
+ See the [packaging reference](https://lessonkit.readthedocs.io/en/latest/reference/packaging.html) and the [`examples/lxpack-golden`](https://github.com/eddiethedean/lessonkit/tree/main/examples/lxpack-golden) course.
31
37
 
32
38
  ## Browser bridge
33
39
 
@@ -38,3 +44,5 @@ import { notifyLxpackLessonComplete } from "@lessonkit/lxpack/bridge";
38
44
  ```
39
45
 
40
46
  `@lessonkit/react` forwards `lesson_completed`, `course_completed`, and `quiz_completed` automatically when `window.parent.lxpackBridge.v1` is present (`config.lxpack.bridge: "off"` to disable).
47
+
48
+ For interoperability notes, see [LXPack upgrades](https://lessonkit.readthedocs.io/en/latest/reference/lxpack-upgrades.html).
package/dist/index.cjs CHANGED
@@ -57,6 +57,8 @@ function assertResolvedPathUnderRoot(root, target) {
57
57
  }
58
58
 
59
59
  // src/validateDescriptor.ts
60
+ var VALID_LAYOUTS = ["single-spa", "per-lesson-spa"];
61
+ var VALID_THEME_PRESETS = ["default", "light", "dark", "brand"];
60
62
  function normalizeDescriptor(input) {
61
63
  const course = (0, import_core.validateId)(input.courseId, "courseId");
62
64
  if (!course.ok) throw new Error("normalizeDescriptor called with invalid courseId");
@@ -99,7 +101,23 @@ function validateDescriptor(input) {
99
101
  if (!input.lessons?.length) {
100
102
  issues.push({ path: "lessons", message: "at least one lesson is required" });
101
103
  }
102
- if (input.layout === "single-spa" && (input.lessons?.length ?? 0) > 1) {
104
+ if (!input.layout) {
105
+ issues.push({ path: "layout", message: "layout is required" });
106
+ } else if (!VALID_LAYOUTS.includes(input.layout)) {
107
+ issues.push({
108
+ path: "layout",
109
+ message: `layout must be one of: ${VALID_LAYOUTS.join(", ")}`
110
+ });
111
+ }
112
+ const layout = input.layout;
113
+ const themePreset = input.theme?.preset;
114
+ if (themePreset !== void 0 && !VALID_THEME_PRESETS.includes(themePreset)) {
115
+ issues.push({
116
+ path: "theme.preset",
117
+ message: `unknown preset; use one of: ${VALID_THEME_PRESETS.join(", ")}`
118
+ });
119
+ }
120
+ if (layout === "single-spa" && (input.lessons?.length ?? 0) > 1) {
103
121
  issues.push({
104
122
  path: "lessons",
105
123
  message: "single-spa layout packages one SPA lesson; remove extra lesson entries or use per-lesson-spa"
@@ -120,7 +138,7 @@ function validateDescriptor(input) {
120
138
  if (!lesson.title?.trim()) {
121
139
  issues.push({ path: `${path}.title`, message: "lesson title is required" });
122
140
  }
123
- if (input.layout === "per-lesson-spa") {
141
+ if (layout === "per-lesson-spa") {
124
142
  const spaPath = lesson.spaPath?.trim();
125
143
  if (!spaPath) {
126
144
  issues.push({
@@ -139,7 +157,7 @@ function validateDescriptor(input) {
139
157
  }
140
158
  }
141
159
  }
142
- if (input.layout === "single-spa" && input.spaLessonId?.trim()) {
160
+ if (layout === "single-spa" && input.spaLessonId?.trim()) {
143
161
  const spaId = input.spaLessonId.trim();
144
162
  const spaResult = (0, import_core.validateId)(spaId, "spaLessonId");
145
163
  if (!spaResult.ok) {
package/dist/index.js CHANGED
@@ -21,6 +21,8 @@ function assertResolvedPathUnderRoot(root, target) {
21
21
  }
22
22
 
23
23
  // src/validateDescriptor.ts
24
+ var VALID_LAYOUTS = ["single-spa", "per-lesson-spa"];
25
+ var VALID_THEME_PRESETS = ["default", "light", "dark", "brand"];
24
26
  function normalizeDescriptor(input) {
25
27
  const course = validateId(input.courseId, "courseId");
26
28
  if (!course.ok) throw new Error("normalizeDescriptor called with invalid courseId");
@@ -63,7 +65,23 @@ function validateDescriptor(input) {
63
65
  if (!input.lessons?.length) {
64
66
  issues.push({ path: "lessons", message: "at least one lesson is required" });
65
67
  }
66
- if (input.layout === "single-spa" && (input.lessons?.length ?? 0) > 1) {
68
+ if (!input.layout) {
69
+ issues.push({ path: "layout", message: "layout is required" });
70
+ } else if (!VALID_LAYOUTS.includes(input.layout)) {
71
+ issues.push({
72
+ path: "layout",
73
+ message: `layout must be one of: ${VALID_LAYOUTS.join(", ")}`
74
+ });
75
+ }
76
+ const layout = input.layout;
77
+ const themePreset = input.theme?.preset;
78
+ if (themePreset !== void 0 && !VALID_THEME_PRESETS.includes(themePreset)) {
79
+ issues.push({
80
+ path: "theme.preset",
81
+ message: `unknown preset; use one of: ${VALID_THEME_PRESETS.join(", ")}`
82
+ });
83
+ }
84
+ if (layout === "single-spa" && (input.lessons?.length ?? 0) > 1) {
67
85
  issues.push({
68
86
  path: "lessons",
69
87
  message: "single-spa layout packages one SPA lesson; remove extra lesson entries or use per-lesson-spa"
@@ -84,7 +102,7 @@ function validateDescriptor(input) {
84
102
  if (!lesson.title?.trim()) {
85
103
  issues.push({ path: `${path}.title`, message: "lesson title is required" });
86
104
  }
87
- if (input.layout === "per-lesson-spa") {
105
+ if (layout === "per-lesson-spa") {
88
106
  const spaPath = lesson.spaPath?.trim();
89
107
  if (!spaPath) {
90
108
  issues.push({
@@ -103,7 +121,7 @@ function validateDescriptor(input) {
103
121
  }
104
122
  }
105
123
  }
106
- if (input.layout === "single-spa" && input.spaLessonId?.trim()) {
124
+ if (layout === "single-spa" && input.spaLessonId?.trim()) {
107
125
  const spaId = input.spaLessonId.trim();
108
126
  const spaResult = validateId(spaId, "spaLessonId");
109
127
  if (!spaResult.ok) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lessonkit/lxpack",
3
- "version": "0.6.0",
3
+ "version": "0.8.0",
4
4
  "private": false,
5
5
  "description": "LXPack export adapter for LessonKit courses (SCORM, standalone, xAPI, cmi5).",
6
6
  "license": "Apache-2.0",
@@ -53,8 +53,8 @@
53
53
  "lint": "echo \"(no lint configured yet)\""
54
54
  },
55
55
  "dependencies": {
56
- "@lessonkit/core": "0.6.0",
57
- "@lessonkit/themes": "0.6.0",
56
+ "@lessonkit/core": "0.8.0",
57
+ "@lessonkit/themes": "0.8.0",
58
58
  "@lxpack/api": "^0.4.0"
59
59
  },
60
60
  "devDependencies": {