@lessonkit/lxpack 0.9.0 → 0.9.2
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/index.cjs +42 -2
- package/dist/index.d.cts +4 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +42 -2
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -63,7 +63,7 @@ function isSafeRelativeSpaPath(spaPath) {
|
|
|
63
63
|
if (spaPath.startsWith("/") || spaPath.startsWith("\\")) return false;
|
|
64
64
|
if (/^[a-zA-Z]:[/\\]/.test(spaPath)) return false;
|
|
65
65
|
const segments = spaPath.split(/[/\\]/).filter((s) => s.length > 0);
|
|
66
|
-
if (segments.some((s) => s === ".."
|
|
66
|
+
if (segments.some((s) => s === "..")) return false;
|
|
67
67
|
return true;
|
|
68
68
|
}
|
|
69
69
|
function assertResolvedPathUnderRoot(root, target) {
|
|
@@ -447,6 +447,9 @@ async function writeLxpackProject(options) {
|
|
|
447
447
|
}
|
|
448
448
|
const descriptor = validation.descriptor;
|
|
449
449
|
const outDir = (0, import_node_path4.resolve)(options.outDir);
|
|
450
|
+
if (options.projectRoot) {
|
|
451
|
+
assertResolvedPathUnderRoot((0, import_node_path4.resolve)(options.projectRoot), outDir);
|
|
452
|
+
}
|
|
450
453
|
const spaDirs = await resolveSpaDirs({ ...options, descriptor });
|
|
451
454
|
const interchange = descriptorToInterchange(descriptor);
|
|
452
455
|
const materialized = await (0, import_validators.materializeLessonkitProject)({
|
|
@@ -509,7 +512,14 @@ async function promoteStagingToOutDir(stagingDir, outDir) {
|
|
|
509
512
|
await fsp.rename(tmpPromote, outDir);
|
|
510
513
|
} catch (promoteError) {
|
|
511
514
|
if (hadOutDir) {
|
|
512
|
-
|
|
515
|
+
try {
|
|
516
|
+
await fsp.rename(backup, outDir);
|
|
517
|
+
} catch (restoreError) {
|
|
518
|
+
console.warn(
|
|
519
|
+
`[lessonkit/lxpack] failed to restore ${outDir} after promote error:`,
|
|
520
|
+
restoreError instanceof Error ? restoreError.message : restoreError
|
|
521
|
+
);
|
|
522
|
+
}
|
|
513
523
|
}
|
|
514
524
|
await fsp.rm(tmpPromote, { recursive: true, force: true }).catch(() => void 0);
|
|
515
525
|
throw promoteError;
|
|
@@ -521,6 +531,36 @@ async function promoteStagingToOutDir(stagingDir, outDir) {
|
|
|
521
531
|
async function packageLessonkitCourse(options) {
|
|
522
532
|
const { target, output, dir, outputBaseDir, ...writeOpts } = options;
|
|
523
533
|
const outDir = (0, import_node_path5.resolve)(writeOpts.outDir);
|
|
534
|
+
const projectRoot = writeOpts.projectRoot ? (0, import_node_path5.resolve)(writeOpts.projectRoot) : void 0;
|
|
535
|
+
if (projectRoot) {
|
|
536
|
+
assertResolvedPathUnderRoot(projectRoot, outDir);
|
|
537
|
+
}
|
|
538
|
+
if (outputBaseDir && !isSafeRelativeSpaPath(outputBaseDir)) {
|
|
539
|
+
return {
|
|
540
|
+
ok: false,
|
|
541
|
+
courseDir: outDir,
|
|
542
|
+
target,
|
|
543
|
+
issues: [{ path: "outputBaseDir", message: `unsafe outputBaseDir: ${outputBaseDir}` }]
|
|
544
|
+
};
|
|
545
|
+
}
|
|
546
|
+
if (projectRoot && output) {
|
|
547
|
+
const resolvedOutput = (0, import_node_path5.resolve)(projectRoot, output);
|
|
548
|
+
try {
|
|
549
|
+
assertResolvedPathUnderRoot(projectRoot, resolvedOutput);
|
|
550
|
+
} catch (err) {
|
|
551
|
+
return {
|
|
552
|
+
ok: false,
|
|
553
|
+
courseDir: outDir,
|
|
554
|
+
target,
|
|
555
|
+
issues: [
|
|
556
|
+
{
|
|
557
|
+
path: "output",
|
|
558
|
+
message: err instanceof Error ? err.message : String(err)
|
|
559
|
+
}
|
|
560
|
+
]
|
|
561
|
+
};
|
|
562
|
+
}
|
|
563
|
+
}
|
|
524
564
|
const descriptorValidation = validateDescriptor(writeOpts.descriptor);
|
|
525
565
|
if (!descriptorValidation.ok) {
|
|
526
566
|
return {
|
package/dist/index.d.cts
CHANGED
|
@@ -36,6 +36,10 @@ type LessonkitCourseDescriptor = {
|
|
|
36
36
|
completion?: {
|
|
37
37
|
threshold?: number;
|
|
38
38
|
};
|
|
39
|
+
/** Required for xAPI / cmi5 export targets (`activityIri` on the course activity). */
|
|
40
|
+
xapi?: {
|
|
41
|
+
activityIri?: string;
|
|
42
|
+
};
|
|
39
43
|
};
|
|
40
44
|
/** Source Vite `dist` directory for `single-spa` (default: `dist`). */
|
|
41
45
|
spaDistDir?: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -36,6 +36,10 @@ type LessonkitCourseDescriptor = {
|
|
|
36
36
|
completion?: {
|
|
37
37
|
threshold?: number;
|
|
38
38
|
};
|
|
39
|
+
/** Required for xAPI / cmi5 export targets (`activityIri` on the course activity). */
|
|
40
|
+
xapi?: {
|
|
41
|
+
activityIri?: string;
|
|
42
|
+
};
|
|
39
43
|
};
|
|
40
44
|
/** Source Vite `dist` directory for `single-spa` (default: `dist`). */
|
|
41
45
|
spaDistDir?: string;
|
package/dist/index.js
CHANGED
|
@@ -12,7 +12,7 @@ function isSafeRelativeSpaPath(spaPath) {
|
|
|
12
12
|
if (spaPath.startsWith("/") || spaPath.startsWith("\\")) return false;
|
|
13
13
|
if (/^[a-zA-Z]:[/\\]/.test(spaPath)) return false;
|
|
14
14
|
const segments = spaPath.split(/[/\\]/).filter((s) => s.length > 0);
|
|
15
|
-
if (segments.some((s) => s === ".."
|
|
15
|
+
if (segments.some((s) => s === "..")) return false;
|
|
16
16
|
return true;
|
|
17
17
|
}
|
|
18
18
|
function assertResolvedPathUnderRoot(root, target) {
|
|
@@ -396,6 +396,9 @@ async function writeLxpackProject(options) {
|
|
|
396
396
|
}
|
|
397
397
|
const descriptor = validation.descriptor;
|
|
398
398
|
const outDir = resolve4(options.outDir);
|
|
399
|
+
if (options.projectRoot) {
|
|
400
|
+
assertResolvedPathUnderRoot(resolve4(options.projectRoot), outDir);
|
|
401
|
+
}
|
|
399
402
|
const spaDirs = await resolveSpaDirs({ ...options, descriptor });
|
|
400
403
|
const interchange = descriptorToInterchange(descriptor);
|
|
401
404
|
const materialized = await materializeLessonkitProject({
|
|
@@ -462,7 +465,14 @@ async function promoteStagingToOutDir(stagingDir, outDir) {
|
|
|
462
465
|
await fsp.rename(tmpPromote, outDir);
|
|
463
466
|
} catch (promoteError) {
|
|
464
467
|
if (hadOutDir) {
|
|
465
|
-
|
|
468
|
+
try {
|
|
469
|
+
await fsp.rename(backup, outDir);
|
|
470
|
+
} catch (restoreError) {
|
|
471
|
+
console.warn(
|
|
472
|
+
`[lessonkit/lxpack] failed to restore ${outDir} after promote error:`,
|
|
473
|
+
restoreError instanceof Error ? restoreError.message : restoreError
|
|
474
|
+
);
|
|
475
|
+
}
|
|
466
476
|
}
|
|
467
477
|
await fsp.rm(tmpPromote, { recursive: true, force: true }).catch(() => void 0);
|
|
468
478
|
throw promoteError;
|
|
@@ -474,6 +484,36 @@ async function promoteStagingToOutDir(stagingDir, outDir) {
|
|
|
474
484
|
async function packageLessonkitCourse(options) {
|
|
475
485
|
const { target, output, dir, outputBaseDir, ...writeOpts } = options;
|
|
476
486
|
const outDir = resolve5(writeOpts.outDir);
|
|
487
|
+
const projectRoot = writeOpts.projectRoot ? resolve5(writeOpts.projectRoot) : void 0;
|
|
488
|
+
if (projectRoot) {
|
|
489
|
+
assertResolvedPathUnderRoot(projectRoot, outDir);
|
|
490
|
+
}
|
|
491
|
+
if (outputBaseDir && !isSafeRelativeSpaPath(outputBaseDir)) {
|
|
492
|
+
return {
|
|
493
|
+
ok: false,
|
|
494
|
+
courseDir: outDir,
|
|
495
|
+
target,
|
|
496
|
+
issues: [{ path: "outputBaseDir", message: `unsafe outputBaseDir: ${outputBaseDir}` }]
|
|
497
|
+
};
|
|
498
|
+
}
|
|
499
|
+
if (projectRoot && output) {
|
|
500
|
+
const resolvedOutput = resolve5(projectRoot, output);
|
|
501
|
+
try {
|
|
502
|
+
assertResolvedPathUnderRoot(projectRoot, resolvedOutput);
|
|
503
|
+
} catch (err) {
|
|
504
|
+
return {
|
|
505
|
+
ok: false,
|
|
506
|
+
courseDir: outDir,
|
|
507
|
+
target,
|
|
508
|
+
issues: [
|
|
509
|
+
{
|
|
510
|
+
path: "output",
|
|
511
|
+
message: err instanceof Error ? err.message : String(err)
|
|
512
|
+
}
|
|
513
|
+
]
|
|
514
|
+
};
|
|
515
|
+
}
|
|
516
|
+
}
|
|
477
517
|
const descriptorValidation = validateDescriptor(writeOpts.descriptor);
|
|
478
518
|
if (!descriptorValidation.ok) {
|
|
479
519
|
return {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lessonkit/lxpack",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.2",
|
|
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.9.
|
|
57
|
-
"@lessonkit/themes": "0.9.
|
|
56
|
+
"@lessonkit/core": "0.9.2",
|
|
57
|
+
"@lessonkit/themes": "0.9.2",
|
|
58
58
|
"@lxpack/api": "^0.6.0",
|
|
59
59
|
"@lxpack/spa-bridge": "^0.6.0",
|
|
60
60
|
"@lxpack/tracking-schema": "^0.6.0",
|