@lessonkit/lxpack 1.5.0 → 1.6.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/index.d.cts CHANGED
@@ -155,6 +155,16 @@ type SpaLessonEntry = {
155
155
  path: string;
156
156
  };
157
157
  declare function resolveSpaLessons(descriptor: LessonkitCourseDescriptor): SpaLessonEntry[];
158
+ /**
159
+ * Convert a `lessonkit.json` course descriptor to portable interchange JSON for `.lkcourse`.
160
+ *
161
+ * @example
162
+ * ```ts
163
+ * import { descriptorToInterchange } from "@lessonkit/lxpack";
164
+ *
165
+ * const interchange = descriptorToInterchange(manifest.course);
166
+ * ```
167
+ */
158
168
  declare function descriptorToInterchange(descriptor: LessonkitCourseDescriptor): LessonkitInterchangeV1;
159
169
 
160
170
  type LxpackInjectedAssessment = {
@@ -199,6 +209,18 @@ type WriteLxpackProjectResult = {
199
209
  };
200
210
  /**
201
211
  * Materialize an LXPack project tree from a LessonKit descriptor (delegates to LXPack 0.6+).
212
+ *
213
+ * @example
214
+ * ```ts
215
+ * import { writeLxpackProject } from "@lessonkit/lxpack";
216
+ *
217
+ * await writeLxpackProject({
218
+ * descriptor: courseFromLessonkitJson,
219
+ * outDir: ".lxpack/course",
220
+ * spaDistDir: "dist",
221
+ * projectRoot: process.cwd(),
222
+ * });
223
+ * ```
202
224
  */
203
225
  declare function writeLxpackProject(options: WriteLxpackProjectOptions): Promise<WriteLxpackProjectResult>;
204
226
 
@@ -260,6 +282,8 @@ type PackageLessonkitCourseOptions = WriteLxpackProjectOptions & {
260
282
  outputBaseDir?: string;
261
283
  /** Treat React parity warnings as packaging errors. */
262
284
  strictParity?: boolean;
285
+ /** Treat LXPack build warnings as packaging errors. */
286
+ strictBuild?: boolean;
263
287
  };
264
288
  type PackageLessonkitCourseResult = {
265
289
  ok: true;
@@ -288,6 +312,21 @@ declare function buildLessonkitProject(options: BuildLessonkitProjectOptions): P
288
312
  /**
289
313
  * Package a built SPA into SCORM, xAPI, cmi5, or standalone LMS artifacts.
290
314
  * Prefer `lessonkit package --target …` in course projects; call directly for custom pipelines.
315
+ *
316
+ * @example
317
+ * ```ts
318
+ * import { packageLessonkitCourse } from "@lessonkit/lxpack";
319
+ *
320
+ * const result = await packageLessonkitCourse({
321
+ * descriptor: manifest.course,
322
+ * outDir: ".lxpack/course",
323
+ * spaDistDir: "dist",
324
+ * projectRoot: process.cwd(),
325
+ * target: "scorm12",
326
+ * strictBuild: true,
327
+ * });
328
+ * if (!result.ok) console.error(result.issues);
329
+ * ```
291
330
  */
292
331
  declare function packageLessonkitCourse(options: PackageLessonkitCourseOptions): Promise<PackageLessonkitCourseResult>;
293
332
 
@@ -311,6 +350,11 @@ declare function validatePackageInputs(options: Pick<PackageLessonkitCourseOptio
311
350
  }): ValidatePackageInputsResult;
312
351
  declare function remapArtifactPaths(stagingRoot: string, outDir: string, artifactPath: string | undefined): string | undefined;
313
352
 
353
+ /**
354
+ * Reject symlinks and paths escaping dist roots before packaging LMS artifacts.
355
+ */
356
+ declare function assertSpaDistContentsSafe(spaDirs: Record<string, string>, projectRoot?: string): Promise<void>;
357
+
314
358
  type LessonkitManifestPaths = {
315
359
  spaDistDir: string;
316
360
  lxpackOutDir: string;
@@ -340,4 +384,121 @@ type ParseManifestResult = {
340
384
  declare function parseLessonkitManifest(raw: unknown, label?: string, projectRoot?: string): ParseManifestResult;
341
385
  declare function loadLessonkitManifestFromFile(readJson: () => Promise<unknown>, label?: string, projectRoot?: string): Promise<ParseManifestResult>;
342
386
 
343
- export { type AssessmentDescriptor, type BuildLessonkitProjectOptions, type BuildStagingPackageOptions, type BuildStagingPackageResult, type DescriptorValidationIssue, type DescriptorValidationResult, type FillInBlanksAssessmentDescriptor, type LessonDescriptor, type LessonkitCourseDescriptor, type LessonkitExportTarget, type LessonkitManifest, type LessonkitManifestPaths, type LxpackInjectedAssessment, type LxpackRuntimeTheme, type ManifestParseIssue, type MappedLessonkitIds, type McqAssessmentDescriptor, type PackageLessonkitCourseOptions, type PackageLessonkitCourseResult, type PackageValidationIssue, type ParseManifestResult, type ProjectPathsInput, type ReactParityIssue, type SpaLayout, type SpaLessonEntry, type TrueFalseAssessmentDescriptor, type ValidateLessonkitProjectOptions, type ValidatePackageInputsResult, type ValidationIssue, type WriteLxpackProjectOptions, type WriteLxpackProjectResult, assessmentDescriptorToLxpack, buildLessonkitProject, buildStagingPackage, descriptorToInterchange, ensureOutDirParent, escapeShellText, extractAssessments, loadLessonkitManifestFromFile, mapLessonkitIds, packageLessonkitCourse, parseLessonkitManifest, promoteStagingToOutDir, remapArtifactPaths, resolveSafePackageOutputOverride, resolveSpaLessons, themeToLxpackRuntime, validateDescriptor, validateDescriptorForTarget, validateLessonkitProject, validatePackageInputs, validateProjectPaths, validateReactManifestParity, writeLxpackProject };
387
+ type LkcourseEnvelopeV1 = {
388
+ format: "lkcourse";
389
+ schemaVersion: 1;
390
+ lessonkitVersion: string;
391
+ exportedAt: string;
392
+ sourceManifest: LessonkitManifest;
393
+ entries: string[];
394
+ };
395
+ type BlockTreeNodeV1 = {
396
+ type: string;
397
+ rawTag?: string;
398
+ courseId?: string;
399
+ lessonId?: string;
400
+ checkId?: string;
401
+ blockId?: string;
402
+ nodeId?: string;
403
+ children?: BlockTreeNodeV1[];
404
+ };
405
+ type BlockTreeV1 = {
406
+ schemaVersion: 1;
407
+ sources: string[];
408
+ blocks: BlockTreeNodeV1[];
409
+ };
410
+ type LkcourseValidationIssue = {
411
+ path: string;
412
+ message: string;
413
+ };
414
+ type ExportLkcourseOptions = {
415
+ projectRoot: string;
416
+ manifest: LessonkitManifest;
417
+ outPath?: string;
418
+ includeBlockTree?: boolean;
419
+ lessonkitVersion?: string;
420
+ };
421
+ type ExportLkcourseResult = {
422
+ ok: true;
423
+ archivePath: string;
424
+ fileCount: number;
425
+ includeBlockTree: boolean;
426
+ } | {
427
+ ok: false;
428
+ issues: LkcourseValidationIssue[];
429
+ };
430
+ type ValidateLkcourseResult = {
431
+ ok: true;
432
+ envelope: LkcourseEnvelopeV1;
433
+ interchange: LessonkitInterchangeV1;
434
+ } | {
435
+ ok: false;
436
+ issues: LkcourseValidationIssue[];
437
+ };
438
+ type ImportLkcourseOptions = {
439
+ archivePath: string;
440
+ targetDir: string;
441
+ };
442
+ type ImportLkcourseResult = {
443
+ ok: true;
444
+ targetDir: string;
445
+ manifest: LessonkitManifest;
446
+ interchange: LessonkitInterchangeV1;
447
+ fileCount: number;
448
+ } | {
449
+ ok: false;
450
+ issues: LkcourseValidationIssue[];
451
+ };
452
+ type ExtractBlockTreeOptions = {
453
+ projectRoot: string;
454
+ blockTypes?: string[];
455
+ appSources?: string[];
456
+ };
457
+
458
+ type ParseEnvelopeResult = {
459
+ ok: true;
460
+ envelope: LkcourseEnvelopeV1;
461
+ } | {
462
+ ok: false;
463
+ issues: LkcourseValidationIssue[];
464
+ };
465
+ declare function parseLkcourseEnvelope(raw: unknown, label?: string): ParseEnvelopeResult;
466
+
467
+ declare function extractBlockTree(options: ExtractBlockTreeOptions): BlockTreeV1;
468
+
469
+ /**
470
+ * Build a portable `.lkcourse` zip (manifest envelope + interchange + dist).
471
+ * Prefer `lessonkit export` in course projects.
472
+ *
473
+ * @example
474
+ * ```ts
475
+ * import { exportLkcourse } from "@lessonkit/lxpack";
476
+ *
477
+ * const result = await exportLkcourse({
478
+ * projectRoot: "/path/to/course",
479
+ * manifest: parsedLessonkitJson,
480
+ * archivePath: "handoff.lkcourse",
481
+ * });
482
+ * ```
483
+ */
484
+ declare function exportLkcourse(options: ExportLkcourseOptions): Promise<ExportLkcourseResult>;
485
+
486
+ declare function validateLkcourseArchiveEntries(entries: Map<string, Uint8Array>, _archiveLabel: string): ValidateLkcourseResult;
487
+ declare function validateLkcourse(archivePath: string): ValidateLkcourseResult;
488
+
489
+ /**
490
+ * Extract a `.lkcourse` archive into a project directory (manifest + dist tree).
491
+ *
492
+ * @example
493
+ * ```ts
494
+ * import { importLkcourse } from "@lessonkit/lxpack";
495
+ *
496
+ * const result = await importLkcourse({
497
+ * archivePath: "handoff.lkcourse",
498
+ * targetDir: "/path/to/dest",
499
+ * });
500
+ * ```
501
+ */
502
+ declare function importLkcourse(options: ImportLkcourseOptions): Promise<ImportLkcourseResult>;
503
+
504
+ export { type AssessmentDescriptor, type BlockTreeNodeV1, type BlockTreeV1, type BuildLessonkitProjectOptions, type BuildStagingPackageOptions, type BuildStagingPackageResult, type DescriptorValidationIssue, type DescriptorValidationResult, type ExportLkcourseOptions, type ExportLkcourseResult, type ExtractBlockTreeOptions, type FillInBlanksAssessmentDescriptor, type ImportLkcourseOptions, type ImportLkcourseResult, type LessonDescriptor, type LessonkitCourseDescriptor, type LessonkitExportTarget, type LessonkitManifest, type LessonkitManifestPaths, type LkcourseEnvelopeV1, type LkcourseValidationIssue, type LxpackInjectedAssessment, type LxpackRuntimeTheme, type ManifestParseIssue, type MappedLessonkitIds, type McqAssessmentDescriptor, type PackageLessonkitCourseOptions, type PackageLessonkitCourseResult, type PackageValidationIssue, type ParseManifestResult, type ProjectPathsInput, type ReactParityIssue, type SpaLayout, type SpaLessonEntry, type TrueFalseAssessmentDescriptor, type ValidateLessonkitProjectOptions, type ValidateLkcourseResult, type ValidatePackageInputsResult, type ValidationIssue, type WriteLxpackProjectOptions, type WriteLxpackProjectResult, assertSpaDistContentsSafe, assessmentDescriptorToLxpack, buildLessonkitProject, buildStagingPackage, descriptorToInterchange, ensureOutDirParent, escapeShellText, exportLkcourse, extractAssessments, extractBlockTree, importLkcourse, loadLessonkitManifestFromFile, mapLessonkitIds, packageLessonkitCourse, parseLessonkitManifest, parseLkcourseEnvelope, promoteStagingToOutDir, remapArtifactPaths, resolveSafePackageOutputOverride, resolveSpaLessons, themeToLxpackRuntime, validateDescriptor, validateDescriptorForTarget, validateLessonkitProject, validateLkcourse, validateLkcourseArchiveEntries, validatePackageInputs, validateProjectPaths, validateReactManifestParity, writeLxpackProject };
package/dist/index.d.ts CHANGED
@@ -155,6 +155,16 @@ type SpaLessonEntry = {
155
155
  path: string;
156
156
  };
157
157
  declare function resolveSpaLessons(descriptor: LessonkitCourseDescriptor): SpaLessonEntry[];
158
+ /**
159
+ * Convert a `lessonkit.json` course descriptor to portable interchange JSON for `.lkcourse`.
160
+ *
161
+ * @example
162
+ * ```ts
163
+ * import { descriptorToInterchange } from "@lessonkit/lxpack";
164
+ *
165
+ * const interchange = descriptorToInterchange(manifest.course);
166
+ * ```
167
+ */
158
168
  declare function descriptorToInterchange(descriptor: LessonkitCourseDescriptor): LessonkitInterchangeV1;
159
169
 
160
170
  type LxpackInjectedAssessment = {
@@ -199,6 +209,18 @@ type WriteLxpackProjectResult = {
199
209
  };
200
210
  /**
201
211
  * Materialize an LXPack project tree from a LessonKit descriptor (delegates to LXPack 0.6+).
212
+ *
213
+ * @example
214
+ * ```ts
215
+ * import { writeLxpackProject } from "@lessonkit/lxpack";
216
+ *
217
+ * await writeLxpackProject({
218
+ * descriptor: courseFromLessonkitJson,
219
+ * outDir: ".lxpack/course",
220
+ * spaDistDir: "dist",
221
+ * projectRoot: process.cwd(),
222
+ * });
223
+ * ```
202
224
  */
203
225
  declare function writeLxpackProject(options: WriteLxpackProjectOptions): Promise<WriteLxpackProjectResult>;
204
226
 
@@ -260,6 +282,8 @@ type PackageLessonkitCourseOptions = WriteLxpackProjectOptions & {
260
282
  outputBaseDir?: string;
261
283
  /** Treat React parity warnings as packaging errors. */
262
284
  strictParity?: boolean;
285
+ /** Treat LXPack build warnings as packaging errors. */
286
+ strictBuild?: boolean;
263
287
  };
264
288
  type PackageLessonkitCourseResult = {
265
289
  ok: true;
@@ -288,6 +312,21 @@ declare function buildLessonkitProject(options: BuildLessonkitProjectOptions): P
288
312
  /**
289
313
  * Package a built SPA into SCORM, xAPI, cmi5, or standalone LMS artifacts.
290
314
  * Prefer `lessonkit package --target …` in course projects; call directly for custom pipelines.
315
+ *
316
+ * @example
317
+ * ```ts
318
+ * import { packageLessonkitCourse } from "@lessonkit/lxpack";
319
+ *
320
+ * const result = await packageLessonkitCourse({
321
+ * descriptor: manifest.course,
322
+ * outDir: ".lxpack/course",
323
+ * spaDistDir: "dist",
324
+ * projectRoot: process.cwd(),
325
+ * target: "scorm12",
326
+ * strictBuild: true,
327
+ * });
328
+ * if (!result.ok) console.error(result.issues);
329
+ * ```
291
330
  */
292
331
  declare function packageLessonkitCourse(options: PackageLessonkitCourseOptions): Promise<PackageLessonkitCourseResult>;
293
332
 
@@ -311,6 +350,11 @@ declare function validatePackageInputs(options: Pick<PackageLessonkitCourseOptio
311
350
  }): ValidatePackageInputsResult;
312
351
  declare function remapArtifactPaths(stagingRoot: string, outDir: string, artifactPath: string | undefined): string | undefined;
313
352
 
353
+ /**
354
+ * Reject symlinks and paths escaping dist roots before packaging LMS artifacts.
355
+ */
356
+ declare function assertSpaDistContentsSafe(spaDirs: Record<string, string>, projectRoot?: string): Promise<void>;
357
+
314
358
  type LessonkitManifestPaths = {
315
359
  spaDistDir: string;
316
360
  lxpackOutDir: string;
@@ -340,4 +384,121 @@ type ParseManifestResult = {
340
384
  declare function parseLessonkitManifest(raw: unknown, label?: string, projectRoot?: string): ParseManifestResult;
341
385
  declare function loadLessonkitManifestFromFile(readJson: () => Promise<unknown>, label?: string, projectRoot?: string): Promise<ParseManifestResult>;
342
386
 
343
- export { type AssessmentDescriptor, type BuildLessonkitProjectOptions, type BuildStagingPackageOptions, type BuildStagingPackageResult, type DescriptorValidationIssue, type DescriptorValidationResult, type FillInBlanksAssessmentDescriptor, type LessonDescriptor, type LessonkitCourseDescriptor, type LessonkitExportTarget, type LessonkitManifest, type LessonkitManifestPaths, type LxpackInjectedAssessment, type LxpackRuntimeTheme, type ManifestParseIssue, type MappedLessonkitIds, type McqAssessmentDescriptor, type PackageLessonkitCourseOptions, type PackageLessonkitCourseResult, type PackageValidationIssue, type ParseManifestResult, type ProjectPathsInput, type ReactParityIssue, type SpaLayout, type SpaLessonEntry, type TrueFalseAssessmentDescriptor, type ValidateLessonkitProjectOptions, type ValidatePackageInputsResult, type ValidationIssue, type WriteLxpackProjectOptions, type WriteLxpackProjectResult, assessmentDescriptorToLxpack, buildLessonkitProject, buildStagingPackage, descriptorToInterchange, ensureOutDirParent, escapeShellText, extractAssessments, loadLessonkitManifestFromFile, mapLessonkitIds, packageLessonkitCourse, parseLessonkitManifest, promoteStagingToOutDir, remapArtifactPaths, resolveSafePackageOutputOverride, resolveSpaLessons, themeToLxpackRuntime, validateDescriptor, validateDescriptorForTarget, validateLessonkitProject, validatePackageInputs, validateProjectPaths, validateReactManifestParity, writeLxpackProject };
387
+ type LkcourseEnvelopeV1 = {
388
+ format: "lkcourse";
389
+ schemaVersion: 1;
390
+ lessonkitVersion: string;
391
+ exportedAt: string;
392
+ sourceManifest: LessonkitManifest;
393
+ entries: string[];
394
+ };
395
+ type BlockTreeNodeV1 = {
396
+ type: string;
397
+ rawTag?: string;
398
+ courseId?: string;
399
+ lessonId?: string;
400
+ checkId?: string;
401
+ blockId?: string;
402
+ nodeId?: string;
403
+ children?: BlockTreeNodeV1[];
404
+ };
405
+ type BlockTreeV1 = {
406
+ schemaVersion: 1;
407
+ sources: string[];
408
+ blocks: BlockTreeNodeV1[];
409
+ };
410
+ type LkcourseValidationIssue = {
411
+ path: string;
412
+ message: string;
413
+ };
414
+ type ExportLkcourseOptions = {
415
+ projectRoot: string;
416
+ manifest: LessonkitManifest;
417
+ outPath?: string;
418
+ includeBlockTree?: boolean;
419
+ lessonkitVersion?: string;
420
+ };
421
+ type ExportLkcourseResult = {
422
+ ok: true;
423
+ archivePath: string;
424
+ fileCount: number;
425
+ includeBlockTree: boolean;
426
+ } | {
427
+ ok: false;
428
+ issues: LkcourseValidationIssue[];
429
+ };
430
+ type ValidateLkcourseResult = {
431
+ ok: true;
432
+ envelope: LkcourseEnvelopeV1;
433
+ interchange: LessonkitInterchangeV1;
434
+ } | {
435
+ ok: false;
436
+ issues: LkcourseValidationIssue[];
437
+ };
438
+ type ImportLkcourseOptions = {
439
+ archivePath: string;
440
+ targetDir: string;
441
+ };
442
+ type ImportLkcourseResult = {
443
+ ok: true;
444
+ targetDir: string;
445
+ manifest: LessonkitManifest;
446
+ interchange: LessonkitInterchangeV1;
447
+ fileCount: number;
448
+ } | {
449
+ ok: false;
450
+ issues: LkcourseValidationIssue[];
451
+ };
452
+ type ExtractBlockTreeOptions = {
453
+ projectRoot: string;
454
+ blockTypes?: string[];
455
+ appSources?: string[];
456
+ };
457
+
458
+ type ParseEnvelopeResult = {
459
+ ok: true;
460
+ envelope: LkcourseEnvelopeV1;
461
+ } | {
462
+ ok: false;
463
+ issues: LkcourseValidationIssue[];
464
+ };
465
+ declare function parseLkcourseEnvelope(raw: unknown, label?: string): ParseEnvelopeResult;
466
+
467
+ declare function extractBlockTree(options: ExtractBlockTreeOptions): BlockTreeV1;
468
+
469
+ /**
470
+ * Build a portable `.lkcourse` zip (manifest envelope + interchange + dist).
471
+ * Prefer `lessonkit export` in course projects.
472
+ *
473
+ * @example
474
+ * ```ts
475
+ * import { exportLkcourse } from "@lessonkit/lxpack";
476
+ *
477
+ * const result = await exportLkcourse({
478
+ * projectRoot: "/path/to/course",
479
+ * manifest: parsedLessonkitJson,
480
+ * archivePath: "handoff.lkcourse",
481
+ * });
482
+ * ```
483
+ */
484
+ declare function exportLkcourse(options: ExportLkcourseOptions): Promise<ExportLkcourseResult>;
485
+
486
+ declare function validateLkcourseArchiveEntries(entries: Map<string, Uint8Array>, _archiveLabel: string): ValidateLkcourseResult;
487
+ declare function validateLkcourse(archivePath: string): ValidateLkcourseResult;
488
+
489
+ /**
490
+ * Extract a `.lkcourse` archive into a project directory (manifest + dist tree).
491
+ *
492
+ * @example
493
+ * ```ts
494
+ * import { importLkcourse } from "@lessonkit/lxpack";
495
+ *
496
+ * const result = await importLkcourse({
497
+ * archivePath: "handoff.lkcourse",
498
+ * targetDir: "/path/to/dest",
499
+ * });
500
+ * ```
501
+ */
502
+ declare function importLkcourse(options: ImportLkcourseOptions): Promise<ImportLkcourseResult>;
503
+
504
+ export { type AssessmentDescriptor, type BlockTreeNodeV1, type BlockTreeV1, type BuildLessonkitProjectOptions, type BuildStagingPackageOptions, type BuildStagingPackageResult, type DescriptorValidationIssue, type DescriptorValidationResult, type ExportLkcourseOptions, type ExportLkcourseResult, type ExtractBlockTreeOptions, type FillInBlanksAssessmentDescriptor, type ImportLkcourseOptions, type ImportLkcourseResult, type LessonDescriptor, type LessonkitCourseDescriptor, type LessonkitExportTarget, type LessonkitManifest, type LessonkitManifestPaths, type LkcourseEnvelopeV1, type LkcourseValidationIssue, type LxpackInjectedAssessment, type LxpackRuntimeTheme, type ManifestParseIssue, type MappedLessonkitIds, type McqAssessmentDescriptor, type PackageLessonkitCourseOptions, type PackageLessonkitCourseResult, type PackageValidationIssue, type ParseManifestResult, type ProjectPathsInput, type ReactParityIssue, type SpaLayout, type SpaLessonEntry, type TrueFalseAssessmentDescriptor, type ValidateLessonkitProjectOptions, type ValidateLkcourseResult, type ValidatePackageInputsResult, type ValidationIssue, type WriteLxpackProjectOptions, type WriteLxpackProjectResult, assertSpaDistContentsSafe, assessmentDescriptorToLxpack, buildLessonkitProject, buildStagingPackage, descriptorToInterchange, ensureOutDirParent, escapeShellText, exportLkcourse, extractAssessments, extractBlockTree, importLkcourse, loadLessonkitManifestFromFile, mapLessonkitIds, packageLessonkitCourse, parseLessonkitManifest, parseLkcourseEnvelope, promoteStagingToOutDir, remapArtifactPaths, resolveSafePackageOutputOverride, resolveSpaLessons, themeToLxpackRuntime, validateDescriptor, validateDescriptorForTarget, validateLessonkitProject, validateLkcourse, validateLkcourseArchiveEntries, validatePackageInputs, validateProjectPaths, validateReactManifestParity, writeLxpackProject };