@lxpack/scorm 0.1.1 → 0.2.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
@@ -5,15 +5,16 @@
5
5
  [![License](https://img.shields.io/github/license/eddiethedean/lxpack)](https://github.com/eddiethedean/lxpack/blob/main/LICENSE)
6
6
  [![Node.js](https://img.shields.io/badge/node-%3E%3D20-brightgreen)](https://nodejs.org/)
7
7
 
8
- SCORM 1.2 and standalone HTML export for LXPack courses.
8
+ SCORM 1.2, SCORM 2004 (multi-SCO), and standalone HTML export for LXPack courses.
9
9
 
10
- Part of [LXPack](https://github.com/eddiethedean/lxpack) — an AI-native learning experience compiler and runtime.
10
+ Part of [LXPack](https://github.com/eddiethedean/lxpack) — an AI-native learning experience compiler and runtime (**v0.2.0**).
11
11
 
12
12
  | Related | Package |
13
13
  |---------|---------|
14
14
  | CLI | [`@lxpack/cli`](../cli/README.md) |
15
15
  | Manifest validation | [`@lxpack/validators`](../validators/README.md) |
16
16
  | Embedded client | [`@lxpack/runtime`](../runtime/README.md) |
17
+ | Components bundle | [`@lxpack/components`](../components/README.md) |
17
18
 
18
19
  ## Install
19
20
 
@@ -25,6 +26,8 @@ Requires Node.js 20+.
25
26
 
26
27
  ## Usage
27
28
 
29
+ ### SCORM 1.2 or standalone ZIP
30
+
28
31
  ```ts
29
32
  import { readFile } from "node:fs/promises";
30
33
  import type { CourseManifest } from "@lxpack/validators";
@@ -44,6 +47,7 @@ const assessmentBundle = await buildRuntimeAssessmentBundle(courseDir, manifest)
44
47
 
45
48
  const runtimeClientJs = await readFile("path/to/client.js", "utf8");
46
49
  const runtimeCss = await readFile("path/to/styles.css", "utf8");
50
+ const componentsJs = await readFile("path/to/bundle.js", "utf8"); // optional
47
51
 
48
52
  await packageCourse({
49
53
  courseDir,
@@ -52,10 +56,31 @@ await packageCourse({
52
56
  outputPath: "/path/to/output/course-scorm12.zip",
53
57
  runtimeClientJs,
54
58
  runtimeCss,
59
+ componentsJs,
60
+ assessmentBundle,
61
+ });
62
+ ```
63
+
64
+ ### SCORM 2004 multi-SCO
65
+
66
+ ```ts
67
+ import { packageScorm2004, buildScoIndexHtml, listCourseActivities } from "@lxpack/scorm";
68
+
69
+ const activities = listCourseActivities(manifest);
70
+
71
+ await packageScorm2004({
72
+ courseDir,
73
+ manifest,
74
+ outputPath: "/path/to/output/course-scorm2004.zip",
75
+ runtimeClientJs,
76
+ runtimeCss,
77
+ componentsJs,
55
78
  assessmentBundle,
56
79
  });
57
80
  ```
58
81
 
82
+ Each activity gets `sco/<activityId>/index.html` (via `buildScoIndexHtml`). Shared assets include `lxpack-runtime.js` and `lxpack-components.js`. `generateScorm2004Manifest` emits `imsmanifest.xml` with IMS Simple Sequencing metadata.
83
+
59
84
  ### Standalone directory
60
85
 
61
86
  ```ts
@@ -66,6 +91,7 @@ await packageStandaloneDir({
66
91
  outputDir: "/path/to/output/standalone",
67
92
  runtimeClientJs,
68
93
  runtimeCss,
94
+ componentsJs,
69
95
  assessmentBundle,
70
96
  });
71
97
  ```
@@ -77,16 +103,21 @@ Most users should use `lxpack build` from [`@lxpack/cli`](../cli/README.md) inst
77
103
  | Export | Description |
78
104
  |--------|-------------|
79
105
  | `packageCourse(options)` | Build a SCORM 1.2 or standalone ZIP |
80
- | `packageStandaloneDir(options)` | Write an unpacked directory (ZIP or SCORM layout) |
106
+ | `packageScorm2004(options)` | Build a SCORM 2004 multi-SCO ZIP |
107
+ | `packageStandaloneDir(options)` | Write an unpacked directory |
108
+ | `listCourseActivities(manifest)` | Ordered activities for multi-SCO layout |
81
109
  | `generateImsManifest(manifest, files)` | SCORM 1.2 `imsmanifest.xml` |
82
- | `buildIndexHtml(options)` | Course shell HTML with embedded config |
110
+ | `generateScorm2004Manifest(...)` | SCORM 2004 manifest with sequencing |
111
+ | `buildIndexHtml(options)` | Single-SCO course shell HTML |
112
+ | `buildScoIndexHtml(options)` | Per-activity launch HTML for SCORM 2004 |
113
+ | `scoLaunchPath(activityId)` | Relative launch path (`sco/<id>/index.html`) |
83
114
  | `buildRuntimeConfig(options)` | Config object passed to `safeJsonForHtml` |
84
115
  | `collectFiles(courseDir, baseDir)` | Course assets for packaging (respects skip rules) |
85
116
  | `shouldSkipCourseFile(rel)` | Whether a relative path is omitted from exports |
86
117
  | `buildManifestFileList(courseFiles)` | File list for `imsmanifest.xml` |
87
118
  | `safeJsonForHtml(value)` | JSON safe for `<script type="application/json">` blocks |
88
119
  | `courseSlug(manifest)` | Stable slug for ZIP names and manifest identifiers |
89
- | `ExportTarget` | `"scorm12"` \| `"standalone"` |
120
+ | `ExportTarget` | `"scorm12"` \| `"scorm2004"` \| `"standalone"` |
90
121
 
91
122
  ### `PackageOptions`
92
123
 
@@ -94,28 +125,30 @@ Most users should use `lxpack build` from [`@lxpack/cli`](../cli/README.md) inst
94
125
  |-------|-------------|
95
126
  | `courseDir` | Course root directory |
96
127
  | `manifest` | Parsed `course.yaml` |
97
- | `outputPath` | Destination ZIP path (`packageCourse`) |
98
- | `target` | `scorm12` or `standalone` |
128
+ | `outputPath` | Destination ZIP path |
129
+ | `target` | `scorm12`, `scorm2004`, or `standalone` |
99
130
  | `runtimeClientJs` | Contents of `@lxpack/runtime/client` bundle |
100
131
  | `runtimeCss` | Runtime stylesheet |
101
- | `assessmentBundle` | Optional; from `buildRuntimeAssessmentBundle()` |
132
+ | `componentsJs` | Optional `@lxpack/components/bundle` for component lessons |
133
+ | `assessmentBundle` | From `buildRuntimeAssessmentBundle()` (assessments, keys, configs, feedback) |
102
134
 
103
135
  ## What gets packaged
104
136
 
105
137
  **Included**
106
138
 
107
- - Lessons, interactions, and assets referenced by the manifest
108
- - `index.html` — shell with embedded manifest + assessment config
139
+ - Lessons, interactions, assets, and component overrides referenced by the manifest
109
140
  - `lxpack-runtime.js` — browser client bundle
110
- - `imsmanifest.xml` — SCORM 1.2 target only
141
+ - `lxpack-components.js` — when component lessons are used
142
+ - **SCORM 1.2 / standalone:** root `index.html` with embedded config
143
+ - **SCORM 2004:** `sco/<activityId>/index.html` per activity + `imsmanifest.xml`
111
144
 
112
145
  **Excluded** (`shouldSkipCourseFile`)
113
146
 
114
147
  - `course.yaml`, `lxpack.config.json`, `.lxpack/`
115
148
  - `assessments/**` — author YAML; assessments are embedded in config instead
116
- - Root `index.html` if present (packager generates the entry page)
149
+ - Root `index.html` if present (packager generates entry pages)
117
150
 
118
- Answer keys are only present inside the JSON config block (with `<` escaped via `safeJsonForHtml`), not as downloadable files.
151
+ Answer keys and feedback text are only present inside the JSON config block (with `<` escaped via `safeJsonForHtml`), not as downloadable files.
119
152
 
120
153
  ## Development
121
154
 
@@ -130,6 +163,8 @@ pnpm --filter @lxpack/scorm typecheck
130
163
  ## Links
131
164
 
132
165
  - [LXPack repository](https://github.com/eddiethedean/lxpack)
166
+ - [Documentation index](https://github.com/eddiethedean/lxpack/blob/main/docs/README.md)
167
+ - [Roadmap & phases](https://github.com/eddiethedean/lxpack/blob/main/docs/ROADMAP.md)
133
168
  - [Changelog](https://github.com/eddiethedean/lxpack/blob/main/CHANGELOG.md)
134
169
 
135
170
  ## License
package/dist/index.d.ts CHANGED
@@ -6,19 +6,18 @@ declare function generateImsManifest(manifest: CourseManifest, files: string[],
6
6
  interface BuildHtmlOptions {
7
7
  manifest: CourseManifest;
8
8
  runtimeCss: string;
9
- mode: "standalone" | "scorm12";
9
+ mode: "standalone" | "scorm12" | "scorm2004";
10
+ activityId?: string;
10
11
  assessmentBundle?: RuntimeAssessmentBundle;
12
+ componentsScript?: string;
11
13
  }
12
- declare function buildRuntimeConfig(options: BuildHtmlOptions): {
13
- manifest: CourseManifest;
14
- baseUrl: string;
15
- mode: BuildHtmlOptions["mode"];
16
- assessments?: RuntimeAssessmentBundle["assessments"];
17
- answerKeys?: RuntimeAssessmentBundle["answerKeys"];
18
- };
14
+ declare function buildRuntimeConfig(options: BuildHtmlOptions): Record<string, unknown>;
15
+ declare function buildScoIndexHtml(options: BuildHtmlOptions & {
16
+ activityId: string;
17
+ }): string;
19
18
  declare function buildIndexHtml(options: BuildHtmlOptions): string;
20
19
 
21
- type ExportTarget = "scorm12" | "standalone";
20
+ type ExportTarget = "scorm12" | "scorm2004" | "standalone";
22
21
  interface PackageOptions {
23
22
  courseDir: string;
24
23
  manifest: CourseManifest;
@@ -26,6 +25,7 @@ interface PackageOptions {
26
25
  target: ExportTarget;
27
26
  runtimeClientJs: string;
28
27
  runtimeCss: string;
28
+ componentsBundleJs?: string;
29
29
  assessmentBundle?: RuntimeAssessmentBundle;
30
30
  }
31
31
  declare function shouldSkipCourseFile(rel: string): boolean;
@@ -36,6 +36,10 @@ declare function collectFiles(dir: string, baseDir: string): Promise<Array<{
36
36
  declare function buildManifestFileList(courseFiles: Array<{
37
37
  path: string;
38
38
  }>): string[];
39
+ declare function packageScorm2004(options: PackageOptions): Promise<{
40
+ outputPath: string;
41
+ fileCount: number;
42
+ }>;
39
43
  declare function packageCourse(options: PackageOptions): Promise<{
40
44
  outputPath: string;
41
45
  fileCount: number;
@@ -53,4 +57,15 @@ declare function safeJsonForHtml(value: unknown): string;
53
57
  /** Stable slug for ZIP filenames and SCORM identifiers. */
54
58
  declare function courseSlug(manifest: CourseManifest): string;
55
59
 
56
- export { type BuildHtmlOptions, type ExportTarget, type PackageOptions, buildIndexHtml, buildManifestFileList, buildRuntimeConfig, collectFiles, courseSlug, generateImsManifest, manifestIdentifier, packageCourse, packageStandaloneDir, safeJsonForHtml, shouldSkipCourseFile };
60
+ interface CourseActivity {
61
+ id: string;
62
+ title: string;
63
+ kind: "lesson" | "assessment";
64
+ }
65
+ declare function listCourseActivities(manifest: CourseManifest): CourseActivity[];
66
+
67
+ declare function scoLaunchPath(activityId: string): string;
68
+ declare function buildScorm2004ManifestFiles(manifest: CourseManifest, courseFiles: string[]): string[];
69
+ declare function generateScorm2004Manifest(manifest: CourseManifest, courseFiles: string[]): string;
70
+
71
+ export { type BuildHtmlOptions, type CourseActivity, type ExportTarget, type PackageOptions, buildIndexHtml, buildManifestFileList, buildRuntimeConfig, buildScoIndexHtml, buildScorm2004ManifestFiles, collectFiles, courseSlug, generateImsManifest, generateScorm2004Manifest, listCourseActivities, manifestIdentifier, packageCourse, packageScorm2004, packageStandaloneDir, safeJsonForHtml, scoLaunchPath, shouldSkipCourseFile };
package/dist/index.js CHANGED
@@ -59,20 +59,47 @@ function safeJsonForHtml(value) {
59
59
 
60
60
  // src/build-html.ts
61
61
  function buildRuntimeConfig(options) {
62
- const { manifest, mode, assessmentBundle } = options;
62
+ const { manifest, mode, assessmentBundle, activityId } = options;
63
63
  return {
64
64
  manifest,
65
65
  baseUrl: ".",
66
66
  mode,
67
+ ...activityId ? { activityId } : {},
67
68
  ...assessmentBundle ? {
68
69
  assessments: assessmentBundle.assessments,
69
- answerKeys: assessmentBundle.answerKeys
70
+ answerKeys: assessmentBundle.answerKeys,
71
+ assessmentConfigs: assessmentBundle.configs,
72
+ assessmentFeedback: assessmentBundle.feedback
70
73
  } : {}
71
74
  };
72
75
  }
76
+ function buildScoIndexHtml(options) {
77
+ const { manifest, runtimeCss, activityId, componentsScript } = options;
78
+ const config = safeJsonForHtml(buildRuntimeConfig({ ...options, activityId }));
79
+ const componentsTag = componentsScript ? `<script type="module" src="${escapeHtml(componentsScript)}"></script>` : "";
80
+ return `<!DOCTYPE html>
81
+ <html lang="en">
82
+ <head>
83
+ <meta charset="UTF-8">
84
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
85
+ <title>${escapeHtml(manifest.title)} \u2014 ${escapeHtml(activityId)}</title>
86
+ <style>${runtimeCss}</style>
87
+ </head>
88
+ <body>
89
+ <div id="lxpack-app"></div>
90
+ <script type="application/json" id="lxpack-config">${config}</script>
91
+ <script>
92
+ window.__LXPACK_CONFIG__ = JSON.parse(document.getElementById('lxpack-config').textContent);
93
+ </script>
94
+ ${componentsTag}
95
+ <script type="module" src="../../lxpack-runtime.js"></script>
96
+ </body>
97
+ </html>`;
98
+ }
73
99
  function buildIndexHtml(options) {
74
- const { manifest, runtimeCss } = options;
100
+ const { manifest, runtimeCss, componentsScript } = options;
75
101
  const config = safeJsonForHtml(buildRuntimeConfig(options));
102
+ const componentsTag = componentsScript ? `<script type="module" src="${escapeHtml(componentsScript)}"></script>` : "";
76
103
  return `<!DOCTYPE html>
77
104
  <html lang="en">
78
105
  <head>
@@ -87,6 +114,7 @@ function buildIndexHtml(options) {
87
114
  <script>
88
115
  window.__LXPACK_CONFIG__ = JSON.parse(document.getElementById('lxpack-config').textContent);
89
116
  </script>
117
+ ${componentsTag}
90
118
  <script type="module" src="./lxpack-runtime.js"></script>
91
119
  </body>
92
120
  </html>`;
@@ -100,6 +128,103 @@ import { readFile, readdir, writeFile, mkdir, cp } from "fs/promises";
100
128
  import { existsSync } from "fs";
101
129
  import { dirname, join, relative } from "path";
102
130
  import JSZip from "jszip";
131
+
132
+ // src/activities.ts
133
+ function listCourseActivities(manifest) {
134
+ const activities = manifest.lessons.map((lesson) => ({
135
+ id: lesson.id,
136
+ title: lesson.title ?? lesson.id,
137
+ kind: "lesson"
138
+ }));
139
+ for (const ref of manifest.assessments ?? []) {
140
+ activities.push({
141
+ id: ref.id,
142
+ title: ref.id.replace(/_/g, " "),
143
+ kind: "assessment"
144
+ });
145
+ }
146
+ return activities;
147
+ }
148
+
149
+ // src/scorm2004-manifest.ts
150
+ function escapeXml2(text) {
151
+ return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
152
+ }
153
+ function scoLaunchPath(activityId) {
154
+ return `sco/${activityId}/index.html`;
155
+ }
156
+ function buildScorm2004ManifestFiles(manifest, courseFiles) {
157
+ const activities = listCourseActivities(manifest);
158
+ const scoFiles = activities.map((a) => scoLaunchPath(a.id));
159
+ return [
160
+ "lxpack-runtime.js",
161
+ "lxpack-components.js",
162
+ ...scoFiles,
163
+ ...courseFiles
164
+ ];
165
+ }
166
+ function generateScorm2004Manifest(manifest, courseFiles) {
167
+ const identifier = manifestIdentifier(manifest);
168
+ const orgId = `${identifier}-org`;
169
+ const activities = listCourseActivities(manifest);
170
+ const itemEntries = activities.map((activity) => {
171
+ const itemId = `item_${activity.id}`;
172
+ const resourceId = `res_${activity.id}`;
173
+ const sequencing = activity.kind === "assessment" ? `
174
+ <imsss:sequencing>
175
+ <imsss:deliveryControls tracked="true" completionSetByContent="true" objectiveSetByContent="true"/>
176
+ </imsss:sequencing>` : `
177
+ <imsss:sequencing>
178
+ <imsss:deliveryControls tracked="true" completionSetByContent="true"/>
179
+ </imsss:sequencing>`;
180
+ return ` <item identifier="${escapeXml2(itemId)}" identifierref="${escapeXml2(resourceId)}">
181
+ <title>${escapeXml2(activity.title)}</title>${sequencing}
182
+ </item>`;
183
+ }).join("\n");
184
+ const resources = activities.map((activity) => {
185
+ const resourceId = `res_${activity.id}`;
186
+ const href = scoLaunchPath(activity.id);
187
+ return ` <resource identifier="${escapeXml2(resourceId)}" type="webcontent" adlcp:scormType="sco" href="${escapeXml2(href)}">
188
+ <file href="${escapeXml2(href)}"/>
189
+ <file href="lxpack-runtime.js"/>
190
+ <file href="lxpack-components.js"/>
191
+ </resource>`;
192
+ }).join("\n");
193
+ const orgSequencing = `
194
+ <imsss:sequencing>
195
+ <imsss:controlMode choice="true" flow="true"/>
196
+ </imsss:sequencing>`;
197
+ const uniqueCourseFiles = [...new Set(courseFiles)].filter((f) => !f.startsWith("sco/")).map(
198
+ (href) => ` <file href="${escapeXml2(href)}"/>`
199
+ ).join("\n");
200
+ return `<?xml version="1.0" encoding="UTF-8"?>
201
+ <manifest identifier="${escapeXml2(identifier)}" version="${escapeXml2(manifest.version)}"
202
+ xmlns="http://www.imsglobal.org/xsd/imscp_v1p1"
203
+ xmlns:adlcp="http://www.adlnet.org/xsd/adlcp_v1p3"
204
+ xmlns:adlseq="http://www.adlnet.org/xsd/adlseq_v1p3"
205
+ xmlns:imsss="http://www.imsglobal.org/xsd/imsss"
206
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
207
+ <metadata>
208
+ <schema>ADL SCORM</schema>
209
+ <schemaversion>2004 4th Edition</schemaversion>
210
+ </metadata>
211
+ <organizations default="${escapeXml2(orgId)}">
212
+ <organization identifier="${escapeXml2(orgId)}">${orgSequencing}
213
+ ${itemEntries}
214
+ </organization>
215
+ </organizations>
216
+ <resources>
217
+ ${resources}
218
+ <resource identifier="shared_assets" type="webcontent" adlcp:scormType="asset">
219
+ ${uniqueCourseFiles}
220
+ <file href="lxpack-runtime.js"/>
221
+ <file href="lxpack-components.js"/>
222
+ </resource>
223
+ </resources>
224
+ </manifest>`;
225
+ }
226
+
227
+ // src/package.ts
103
228
  var SKIP_FILES = /* @__PURE__ */ new Set([
104
229
  "course.yaml",
105
230
  "lxpack.config.ts",
@@ -140,7 +265,57 @@ async function collectFiles(dir, baseDir) {
140
265
  function buildManifestFileList(courseFiles) {
141
266
  return ["index.html", "lxpack-runtime.js", ...courseFiles.map((f) => f.path)];
142
267
  }
268
+ async function packageScorm2004(options) {
269
+ const {
270
+ courseDir,
271
+ manifest,
272
+ outputPath,
273
+ runtimeClientJs,
274
+ runtimeCss,
275
+ componentsBundleJs,
276
+ assessmentBundle
277
+ } = options;
278
+ const zip = new JSZip();
279
+ const courseFiles = await collectFiles(courseDir, courseDir);
280
+ for (const file of courseFiles) {
281
+ const content = await readFile(file.fullPath);
282
+ zip.file(file.path, content);
283
+ }
284
+ zip.file("lxpack-runtime.js", runtimeClientJs);
285
+ if (componentsBundleJs) {
286
+ zip.file("lxpack-components.js", componentsBundleJs);
287
+ }
288
+ const activities = listCourseActivities(manifest);
289
+ for (const activity of activities) {
290
+ const html = buildScoIndexHtml({
291
+ manifest,
292
+ runtimeCss,
293
+ mode: "scorm2004",
294
+ activityId: activity.id,
295
+ assessmentBundle,
296
+ componentsScript: componentsBundleJs ? "../../lxpack-components.js" : void 0
297
+ });
298
+ zip.file(`sco/${activity.id}/index.html`, html);
299
+ }
300
+ const manifestFiles = buildScorm2004ManifestFiles(
301
+ manifest,
302
+ courseFiles.map((f) => f.path)
303
+ );
304
+ zip.file("imsmanifest.xml", generateScorm2004Manifest(manifest, manifestFiles));
305
+ const buffer = await zip.generateAsync({
306
+ type: "nodebuffer",
307
+ compression: "DEFLATE"
308
+ });
309
+ await writeFile(outputPath, buffer);
310
+ return {
311
+ outputPath,
312
+ fileCount: Object.keys(zip.files).length
313
+ };
314
+ }
143
315
  async function packageCourse(options) {
316
+ if (options.target === "scorm2004") {
317
+ return packageScorm2004(options);
318
+ }
144
319
  const {
145
320
  courseDir,
146
321
  manifest,
@@ -148,7 +323,8 @@ async function packageCourse(options) {
148
323
  target,
149
324
  runtimeClientJs,
150
325
  runtimeCss,
151
- assessmentBundle
326
+ assessmentBundle,
327
+ componentsBundleJs
152
328
  } = options;
153
329
  const zip = new JSZip();
154
330
  const mode = target === "scorm12" ? "scorm12" : "standalone";
@@ -161,10 +337,14 @@ async function packageCourse(options) {
161
337
  manifest,
162
338
  runtimeCss,
163
339
  mode,
164
- assessmentBundle
340
+ assessmentBundle,
341
+ componentsScript: componentsBundleJs ? "./lxpack-components.js" : void 0
165
342
  });
166
343
  zip.file("index.html", indexHtml);
167
344
  zip.file("lxpack-runtime.js", runtimeClientJs);
345
+ if (componentsBundleJs) {
346
+ zip.file("lxpack-components.js", componentsBundleJs);
347
+ }
168
348
  if (target === "scorm12") {
169
349
  const manifestFiles = buildManifestFileList(courseFiles);
170
350
  zip.file(
@@ -228,12 +408,18 @@ export {
228
408
  buildIndexHtml,
229
409
  buildManifestFileList,
230
410
  buildRuntimeConfig,
411
+ buildScoIndexHtml,
412
+ buildScorm2004ManifestFiles,
231
413
  collectFiles,
232
414
  courseSlug,
233
415
  generateImsManifest,
416
+ generateScorm2004Manifest,
417
+ listCourseActivities,
234
418
  manifestIdentifier,
235
419
  packageCourse,
420
+ packageScorm2004,
236
421
  packageStandaloneDir,
237
422
  safeJsonForHtml,
423
+ scoLaunchPath,
238
424
  shouldSkipCourseFile
239
425
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lxpack/scorm",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "SCORM and standalone HTML export for LXPack",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -39,7 +39,7 @@
39
39
  ],
40
40
  "dependencies": {
41
41
  "jszip": "^3.10.1",
42
- "@lxpack/validators": "0.1.1"
42
+ "@lxpack/validators": "0.2.0"
43
43
  },
44
44
  "devDependencies": {
45
45
  "@types/node": "^22.13.10",