@patch-adams/core 1.5.24 → 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/cli.cjs +140 -0
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +140 -0
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +224 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +88 -1
- package/dist/index.d.ts +88 -1
- package/dist/index.js +222 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -564,6 +564,53 @@ interface CourseMetadata {
|
|
|
564
564
|
*/
|
|
565
565
|
declare function extractCourseMetadata(zip: AdmZip, format: string): CourseMetadata;
|
|
566
566
|
|
|
567
|
+
/**
|
|
568
|
+
* Parsed course structure types for Rise SCORM packages.
|
|
569
|
+
* Used by the parse-structure API and the frontend tree view.
|
|
570
|
+
*/
|
|
571
|
+
/** A single block within a Rise lesson */
|
|
572
|
+
interface CourseStructureBlock {
|
|
573
|
+
/** Rise block ID (e.g. "cmk2wzn2p007q3b7hsiobz031") */
|
|
574
|
+
id: string;
|
|
575
|
+
/** Block type: "text", "image", "interactive", "knowledgeCheck", etc. */
|
|
576
|
+
type: string;
|
|
577
|
+
/** Block family: "text", "media", "interactive", etc. */
|
|
578
|
+
family?: string;
|
|
579
|
+
/** Block variant: "paragraph", "accordion", "hero", etc. */
|
|
580
|
+
variant?: string;
|
|
581
|
+
/** Human-readable title derived from block content or type label */
|
|
582
|
+
title?: string;
|
|
583
|
+
}
|
|
584
|
+
/** A lesson (section) in a Rise course */
|
|
585
|
+
interface CourseStructureLesson {
|
|
586
|
+
/** Rise lesson ID */
|
|
587
|
+
id: string;
|
|
588
|
+
/** Lesson title */
|
|
589
|
+
title: string;
|
|
590
|
+
/** Lesson type (e.g. "blocks") */
|
|
591
|
+
type: string;
|
|
592
|
+
/** Blocks within this lesson */
|
|
593
|
+
blocks: CourseStructureBlock[];
|
|
594
|
+
}
|
|
595
|
+
/** Parsed course structure returned by extractCourseStructure() */
|
|
596
|
+
interface CourseStructure {
|
|
597
|
+
/** Course title */
|
|
598
|
+
courseTitle: string;
|
|
599
|
+
/** Course identifier from manifest */
|
|
600
|
+
courseId?: string;
|
|
601
|
+
/** Lessons in the course */
|
|
602
|
+
lessons: CourseStructureLesson[];
|
|
603
|
+
}
|
|
604
|
+
/** User-assigned class mappings at course, lesson, and block levels */
|
|
605
|
+
interface CourseClassMappings {
|
|
606
|
+
/** Space-separated class names for the <html> element (course level) */
|
|
607
|
+
course?: string;
|
|
608
|
+
/** Lesson ID -> space-separated class names */
|
|
609
|
+
lessons?: Record<string, string>;
|
|
610
|
+
/** Block ID -> space-separated class names */
|
|
611
|
+
blocks?: Record<string, string>;
|
|
612
|
+
}
|
|
613
|
+
|
|
567
614
|
/**
|
|
568
615
|
* Base configuration for any plugin
|
|
569
616
|
*/
|
|
@@ -880,6 +927,8 @@ interface PatchOptions {
|
|
|
880
927
|
skin?: string;
|
|
881
928
|
/** Original package filename — baked into LRS bridge for statement searchability */
|
|
882
929
|
packageName?: string;
|
|
930
|
+
/** Custom CSS class mappings for course, lesson, and block levels */
|
|
931
|
+
classMappings?: CourseClassMappings;
|
|
883
932
|
}
|
|
884
933
|
/**
|
|
885
934
|
* Main Patcher class for patching e-learning course packages
|
|
@@ -1113,6 +1162,31 @@ declare function generateJsAfterLoader(options: JsAfterOptions): string;
|
|
|
1113
1162
|
*/
|
|
1114
1163
|
declare function buildJsAfterOptions(config: PatchAdamsConfig): JsAfterOptions;
|
|
1115
1164
|
|
|
1165
|
+
/**
|
|
1166
|
+
* Class Mappings Template
|
|
1167
|
+
*
|
|
1168
|
+
* Generates an inline JavaScript snippet that applies user-defined CSS classes
|
|
1169
|
+
* to course, lesson, and block elements at runtime.
|
|
1170
|
+
*
|
|
1171
|
+
* Timing: This script is injected inline (via plugin assets) so it executes
|
|
1172
|
+
* synchronously BEFORE the pa-loading class is removed. The user never sees
|
|
1173
|
+
* an un-styled flash — classes are applied while content is still hidden.
|
|
1174
|
+
*
|
|
1175
|
+
* - Course classes: added to <html> element immediately
|
|
1176
|
+
* - Block classes: added to [data-block-id] elements via MutationObserver
|
|
1177
|
+
* - Lesson classes: toggled on <html> via hashchange (Rise SPA routing)
|
|
1178
|
+
*/
|
|
1179
|
+
|
|
1180
|
+
/**
|
|
1181
|
+
* Check if class mappings contain any actual assignments
|
|
1182
|
+
*/
|
|
1183
|
+
declare function hasClassMappings(mappings?: CourseClassMappings): boolean;
|
|
1184
|
+
/**
|
|
1185
|
+
* Generate an inline JavaScript snippet that applies class mappings at runtime.
|
|
1186
|
+
* Returns an empty string if there are no mappings to apply.
|
|
1187
|
+
*/
|
|
1188
|
+
declare function generateClassMappingsScript(mappings: CourseClassMappings): string;
|
|
1189
|
+
|
|
1116
1190
|
type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'silent';
|
|
1117
1191
|
/**
|
|
1118
1192
|
* Simple logger utility for Patch-Adams
|
|
@@ -1129,6 +1203,19 @@ declare class Logger {
|
|
|
1129
1203
|
setLevel(level: LogLevel): void;
|
|
1130
1204
|
}
|
|
1131
1205
|
|
|
1206
|
+
/**
|
|
1207
|
+
* Rise Course Structure Parser
|
|
1208
|
+
*
|
|
1209
|
+
* Extracts the hierarchical course structure (lessons + blocks) from a
|
|
1210
|
+
* Rise SCORM ZIP package by parsing the embedded base64-encoded course JSON.
|
|
1211
|
+
*/
|
|
1212
|
+
|
|
1213
|
+
/**
|
|
1214
|
+
* Extract course structure from a Rise SCORM ZIP buffer.
|
|
1215
|
+
* Returns null if the ZIP is not a Rise package or parsing fails.
|
|
1216
|
+
*/
|
|
1217
|
+
declare function extractCourseStructure(zipBuffer: Buffer): CourseStructure | null;
|
|
1218
|
+
|
|
1132
1219
|
/**
|
|
1133
1220
|
* Plugin Registry for Patch-Adams
|
|
1134
1221
|
*
|
|
@@ -1198,4 +1285,4 @@ declare class PluginRegistry {
|
|
|
1198
1285
|
*/
|
|
1199
1286
|
declare const pluginRegistry: PluginRegistry;
|
|
1200
1287
|
|
|
1201
|
-
export { type AsyncAssetConfig, AsyncAssetConfigSchema, type AuthoringTool, AuthoringToolDetector, type AuthoringToolInfo, type BlockingAssetConfig, BlockingAssetConfigSchema, type CourseFingerprint, type CourseMetadata, type CssAfterOptions, type CssBeforeOptions, DEFAULT_LRS_OPTIONS, FormatDetector, type GeneratedPluginAssets, HtmlInjector, type JsAfterOptions, type JsBeforeOptions, type LocalFoldersConfig, LocalFoldersConfigSchema, type LogLevel, Logger, type LrsBridgeConfig, LrsBridgeConfigSchema, type LrsBridgeOptions, type ManifestPaths, ManifestUpdater, type PackageFormat, type PatchAdamsConfig, PatchAdamsConfigSchema, type PatchAdamsPlugin, type PatchOptions, type PatchResult, Patcher, type PluginAssets, type PluginConfig, PluginRegistry, type PluginsConfig, StorylineHtmlInjector, buildCssAfterOptions, buildCssBeforeOptions, buildJsAfterOptions, buildJsBeforeOptions, defaultConfig, extractCourseFingerprint, extractCourseMetadata, generateConfigTemplate, generateCssAfterLoader, generateCssBeforeLoader, generateJsAfterLoader, generateJsBeforeLoader, generateLrsBridgeCode, loadConfig, mergeWithDefaults, pluginRegistry };
|
|
1288
|
+
export { type AsyncAssetConfig, AsyncAssetConfigSchema, type AuthoringTool, AuthoringToolDetector, type AuthoringToolInfo, type BlockingAssetConfig, BlockingAssetConfigSchema, type CourseClassMappings, type CourseFingerprint, type CourseMetadata, type CourseStructure, type CourseStructureBlock, type CourseStructureLesson, type CssAfterOptions, type CssBeforeOptions, DEFAULT_LRS_OPTIONS, FormatDetector, type GeneratedPluginAssets, HtmlInjector, type JsAfterOptions, type JsBeforeOptions, type LocalFoldersConfig, LocalFoldersConfigSchema, type LogLevel, Logger, type LrsBridgeConfig, LrsBridgeConfigSchema, type LrsBridgeOptions, type ManifestPaths, ManifestUpdater, type PackageFormat, type PatchAdamsConfig, PatchAdamsConfigSchema, type PatchAdamsPlugin, type PatchOptions, type PatchResult, Patcher, type PluginAssets, type PluginConfig, PluginRegistry, type PluginsConfig, StorylineHtmlInjector, buildCssAfterOptions, buildCssBeforeOptions, buildJsAfterOptions, buildJsBeforeOptions, defaultConfig, extractCourseFingerprint, extractCourseMetadata, extractCourseStructure, generateClassMappingsScript, generateConfigTemplate, generateCssAfterLoader, generateCssBeforeLoader, generateJsAfterLoader, generateJsBeforeLoader, generateLrsBridgeCode, hasClassMappings, loadConfig, mergeWithDefaults, pluginRegistry };
|
package/dist/index.d.ts
CHANGED
|
@@ -564,6 +564,53 @@ interface CourseMetadata {
|
|
|
564
564
|
*/
|
|
565
565
|
declare function extractCourseMetadata(zip: AdmZip, format: string): CourseMetadata;
|
|
566
566
|
|
|
567
|
+
/**
|
|
568
|
+
* Parsed course structure types for Rise SCORM packages.
|
|
569
|
+
* Used by the parse-structure API and the frontend tree view.
|
|
570
|
+
*/
|
|
571
|
+
/** A single block within a Rise lesson */
|
|
572
|
+
interface CourseStructureBlock {
|
|
573
|
+
/** Rise block ID (e.g. "cmk2wzn2p007q3b7hsiobz031") */
|
|
574
|
+
id: string;
|
|
575
|
+
/** Block type: "text", "image", "interactive", "knowledgeCheck", etc. */
|
|
576
|
+
type: string;
|
|
577
|
+
/** Block family: "text", "media", "interactive", etc. */
|
|
578
|
+
family?: string;
|
|
579
|
+
/** Block variant: "paragraph", "accordion", "hero", etc. */
|
|
580
|
+
variant?: string;
|
|
581
|
+
/** Human-readable title derived from block content or type label */
|
|
582
|
+
title?: string;
|
|
583
|
+
}
|
|
584
|
+
/** A lesson (section) in a Rise course */
|
|
585
|
+
interface CourseStructureLesson {
|
|
586
|
+
/** Rise lesson ID */
|
|
587
|
+
id: string;
|
|
588
|
+
/** Lesson title */
|
|
589
|
+
title: string;
|
|
590
|
+
/** Lesson type (e.g. "blocks") */
|
|
591
|
+
type: string;
|
|
592
|
+
/** Blocks within this lesson */
|
|
593
|
+
blocks: CourseStructureBlock[];
|
|
594
|
+
}
|
|
595
|
+
/** Parsed course structure returned by extractCourseStructure() */
|
|
596
|
+
interface CourseStructure {
|
|
597
|
+
/** Course title */
|
|
598
|
+
courseTitle: string;
|
|
599
|
+
/** Course identifier from manifest */
|
|
600
|
+
courseId?: string;
|
|
601
|
+
/** Lessons in the course */
|
|
602
|
+
lessons: CourseStructureLesson[];
|
|
603
|
+
}
|
|
604
|
+
/** User-assigned class mappings at course, lesson, and block levels */
|
|
605
|
+
interface CourseClassMappings {
|
|
606
|
+
/** Space-separated class names for the <html> element (course level) */
|
|
607
|
+
course?: string;
|
|
608
|
+
/** Lesson ID -> space-separated class names */
|
|
609
|
+
lessons?: Record<string, string>;
|
|
610
|
+
/** Block ID -> space-separated class names */
|
|
611
|
+
blocks?: Record<string, string>;
|
|
612
|
+
}
|
|
613
|
+
|
|
567
614
|
/**
|
|
568
615
|
* Base configuration for any plugin
|
|
569
616
|
*/
|
|
@@ -880,6 +927,8 @@ interface PatchOptions {
|
|
|
880
927
|
skin?: string;
|
|
881
928
|
/** Original package filename — baked into LRS bridge for statement searchability */
|
|
882
929
|
packageName?: string;
|
|
930
|
+
/** Custom CSS class mappings for course, lesson, and block levels */
|
|
931
|
+
classMappings?: CourseClassMappings;
|
|
883
932
|
}
|
|
884
933
|
/**
|
|
885
934
|
* Main Patcher class for patching e-learning course packages
|
|
@@ -1113,6 +1162,31 @@ declare function generateJsAfterLoader(options: JsAfterOptions): string;
|
|
|
1113
1162
|
*/
|
|
1114
1163
|
declare function buildJsAfterOptions(config: PatchAdamsConfig): JsAfterOptions;
|
|
1115
1164
|
|
|
1165
|
+
/**
|
|
1166
|
+
* Class Mappings Template
|
|
1167
|
+
*
|
|
1168
|
+
* Generates an inline JavaScript snippet that applies user-defined CSS classes
|
|
1169
|
+
* to course, lesson, and block elements at runtime.
|
|
1170
|
+
*
|
|
1171
|
+
* Timing: This script is injected inline (via plugin assets) so it executes
|
|
1172
|
+
* synchronously BEFORE the pa-loading class is removed. The user never sees
|
|
1173
|
+
* an un-styled flash — classes are applied while content is still hidden.
|
|
1174
|
+
*
|
|
1175
|
+
* - Course classes: added to <html> element immediately
|
|
1176
|
+
* - Block classes: added to [data-block-id] elements via MutationObserver
|
|
1177
|
+
* - Lesson classes: toggled on <html> via hashchange (Rise SPA routing)
|
|
1178
|
+
*/
|
|
1179
|
+
|
|
1180
|
+
/**
|
|
1181
|
+
* Check if class mappings contain any actual assignments
|
|
1182
|
+
*/
|
|
1183
|
+
declare function hasClassMappings(mappings?: CourseClassMappings): boolean;
|
|
1184
|
+
/**
|
|
1185
|
+
* Generate an inline JavaScript snippet that applies class mappings at runtime.
|
|
1186
|
+
* Returns an empty string if there are no mappings to apply.
|
|
1187
|
+
*/
|
|
1188
|
+
declare function generateClassMappingsScript(mappings: CourseClassMappings): string;
|
|
1189
|
+
|
|
1116
1190
|
type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'silent';
|
|
1117
1191
|
/**
|
|
1118
1192
|
* Simple logger utility for Patch-Adams
|
|
@@ -1129,6 +1203,19 @@ declare class Logger {
|
|
|
1129
1203
|
setLevel(level: LogLevel): void;
|
|
1130
1204
|
}
|
|
1131
1205
|
|
|
1206
|
+
/**
|
|
1207
|
+
* Rise Course Structure Parser
|
|
1208
|
+
*
|
|
1209
|
+
* Extracts the hierarchical course structure (lessons + blocks) from a
|
|
1210
|
+
* Rise SCORM ZIP package by parsing the embedded base64-encoded course JSON.
|
|
1211
|
+
*/
|
|
1212
|
+
|
|
1213
|
+
/**
|
|
1214
|
+
* Extract course structure from a Rise SCORM ZIP buffer.
|
|
1215
|
+
* Returns null if the ZIP is not a Rise package or parsing fails.
|
|
1216
|
+
*/
|
|
1217
|
+
declare function extractCourseStructure(zipBuffer: Buffer): CourseStructure | null;
|
|
1218
|
+
|
|
1132
1219
|
/**
|
|
1133
1220
|
* Plugin Registry for Patch-Adams
|
|
1134
1221
|
*
|
|
@@ -1198,4 +1285,4 @@ declare class PluginRegistry {
|
|
|
1198
1285
|
*/
|
|
1199
1286
|
declare const pluginRegistry: PluginRegistry;
|
|
1200
1287
|
|
|
1201
|
-
export { type AsyncAssetConfig, AsyncAssetConfigSchema, type AuthoringTool, AuthoringToolDetector, type AuthoringToolInfo, type BlockingAssetConfig, BlockingAssetConfigSchema, type CourseFingerprint, type CourseMetadata, type CssAfterOptions, type CssBeforeOptions, DEFAULT_LRS_OPTIONS, FormatDetector, type GeneratedPluginAssets, HtmlInjector, type JsAfterOptions, type JsBeforeOptions, type LocalFoldersConfig, LocalFoldersConfigSchema, type LogLevel, Logger, type LrsBridgeConfig, LrsBridgeConfigSchema, type LrsBridgeOptions, type ManifestPaths, ManifestUpdater, type PackageFormat, type PatchAdamsConfig, PatchAdamsConfigSchema, type PatchAdamsPlugin, type PatchOptions, type PatchResult, Patcher, type PluginAssets, type PluginConfig, PluginRegistry, type PluginsConfig, StorylineHtmlInjector, buildCssAfterOptions, buildCssBeforeOptions, buildJsAfterOptions, buildJsBeforeOptions, defaultConfig, extractCourseFingerprint, extractCourseMetadata, generateConfigTemplate, generateCssAfterLoader, generateCssBeforeLoader, generateJsAfterLoader, generateJsBeforeLoader, generateLrsBridgeCode, loadConfig, mergeWithDefaults, pluginRegistry };
|
|
1288
|
+
export { type AsyncAssetConfig, AsyncAssetConfigSchema, type AuthoringTool, AuthoringToolDetector, type AuthoringToolInfo, type BlockingAssetConfig, BlockingAssetConfigSchema, type CourseClassMappings, type CourseFingerprint, type CourseMetadata, type CourseStructure, type CourseStructureBlock, type CourseStructureLesson, type CssAfterOptions, type CssBeforeOptions, DEFAULT_LRS_OPTIONS, FormatDetector, type GeneratedPluginAssets, HtmlInjector, type JsAfterOptions, type JsBeforeOptions, type LocalFoldersConfig, LocalFoldersConfigSchema, type LogLevel, Logger, type LrsBridgeConfig, LrsBridgeConfigSchema, type LrsBridgeOptions, type ManifestPaths, ManifestUpdater, type PackageFormat, type PatchAdamsConfig, PatchAdamsConfigSchema, type PatchAdamsPlugin, type PatchOptions, type PatchResult, Patcher, type PluginAssets, type PluginConfig, PluginRegistry, type PluginsConfig, StorylineHtmlInjector, buildCssAfterOptions, buildCssBeforeOptions, buildJsAfterOptions, buildJsBeforeOptions, defaultConfig, extractCourseFingerprint, extractCourseMetadata, extractCourseStructure, generateClassMappingsScript, generateConfigTemplate, generateCssAfterLoader, generateCssBeforeLoader, generateJsAfterLoader, generateJsBeforeLoader, generateLrsBridgeCode, hasClassMappings, loadConfig, mergeWithDefaults, pluginRegistry };
|
package/dist/index.js
CHANGED
|
@@ -5687,6 +5687,139 @@ function buildSkinJsOptions(config) {
|
|
|
5687
5687
|
};
|
|
5688
5688
|
}
|
|
5689
5689
|
|
|
5690
|
+
// src/templates/class-mappings.ts
|
|
5691
|
+
function hasClassMappings(mappings) {
|
|
5692
|
+
if (!mappings) return false;
|
|
5693
|
+
if (mappings.course?.trim()) return true;
|
|
5694
|
+
if (mappings.lessons && Object.values(mappings.lessons).some((v) => v?.trim())) return true;
|
|
5695
|
+
if (mappings.blocks && Object.values(mappings.blocks).some((v) => v?.trim())) return true;
|
|
5696
|
+
return false;
|
|
5697
|
+
}
|
|
5698
|
+
function generateClassMappingsScript(mappings) {
|
|
5699
|
+
if (!hasClassMappings(mappings)) return "";
|
|
5700
|
+
const courseClasses = (mappings.course || "").trim();
|
|
5701
|
+
const blockMap = {};
|
|
5702
|
+
const lessonMap = {};
|
|
5703
|
+
if (mappings.blocks) {
|
|
5704
|
+
for (const [id, classes] of Object.entries(mappings.blocks)) {
|
|
5705
|
+
const trimmed = classes?.trim();
|
|
5706
|
+
if (trimmed) blockMap[id] = trimmed;
|
|
5707
|
+
}
|
|
5708
|
+
}
|
|
5709
|
+
if (mappings.lessons) {
|
|
5710
|
+
for (const [id, classes] of Object.entries(mappings.lessons)) {
|
|
5711
|
+
const trimmed = classes?.trim();
|
|
5712
|
+
if (trimmed) lessonMap[id] = trimmed;
|
|
5713
|
+
}
|
|
5714
|
+
}
|
|
5715
|
+
const hasBlocks = Object.keys(blockMap).length > 0;
|
|
5716
|
+
const hasLessons = Object.keys(lessonMap).length > 0;
|
|
5717
|
+
const parts = [];
|
|
5718
|
+
parts.push(`// PA-Patcher: Custom Class Mappings`);
|
|
5719
|
+
parts.push(`(function() {`);
|
|
5720
|
+
parts.push(` 'use strict';`);
|
|
5721
|
+
parts.push(``);
|
|
5722
|
+
if (courseClasses) {
|
|
5723
|
+
parts.push(` // Course-level classes (applied to <html>)`);
|
|
5724
|
+
parts.push(` var courseClasses = ${JSON.stringify(courseClasses)};`);
|
|
5725
|
+
parts.push(` courseClasses.split(' ').forEach(function(cls) {`);
|
|
5726
|
+
parts.push(` if (cls) document.documentElement.classList.add(cls);`);
|
|
5727
|
+
parts.push(` });`);
|
|
5728
|
+
parts.push(``);
|
|
5729
|
+
}
|
|
5730
|
+
if (hasBlocks) {
|
|
5731
|
+
parts.push(` // Block-level classes (applied to [data-block-id] elements)`);
|
|
5732
|
+
parts.push(` var blockMap = ${JSON.stringify(blockMap)};`);
|
|
5733
|
+
parts.push(``);
|
|
5734
|
+
parts.push(` function applyBlockClasses() {`);
|
|
5735
|
+
parts.push(` var ids = Object.keys(blockMap);`);
|
|
5736
|
+
parts.push(` for (var i = 0; i < ids.length; i++) {`);
|
|
5737
|
+
parts.push(` var el = document.querySelector('[data-block-id="' + ids[i] + '"]');`);
|
|
5738
|
+
parts.push(` if (el) {`);
|
|
5739
|
+
parts.push(` var classes = blockMap[ids[i]].split(' ');`);
|
|
5740
|
+
parts.push(` for (var j = 0; j < classes.length; j++) {`);
|
|
5741
|
+
parts.push(` if (classes[j]) el.classList.add(classes[j]);`);
|
|
5742
|
+
parts.push(` }`);
|
|
5743
|
+
parts.push(` }`);
|
|
5744
|
+
parts.push(` }`);
|
|
5745
|
+
parts.push(` }`);
|
|
5746
|
+
parts.push(``);
|
|
5747
|
+
}
|
|
5748
|
+
if (hasLessons) {
|
|
5749
|
+
parts.push(` // Lesson-level classes (toggled on <html> via hash navigation)`);
|
|
5750
|
+
parts.push(` var lessonMap = ${JSON.stringify(lessonMap)};`);
|
|
5751
|
+
parts.push(` var allLessonClasses = [];`);
|
|
5752
|
+
parts.push(` Object.keys(lessonMap).forEach(function(id) {`);
|
|
5753
|
+
parts.push(` lessonMap[id].split(' ').forEach(function(cls) {`);
|
|
5754
|
+
parts.push(` if (cls && allLessonClasses.indexOf(cls) === -1) allLessonClasses.push(cls);`);
|
|
5755
|
+
parts.push(` });`);
|
|
5756
|
+
parts.push(` });`);
|
|
5757
|
+
parts.push(``);
|
|
5758
|
+
parts.push(` var currentLessonId = null;`);
|
|
5759
|
+
parts.push(``);
|
|
5760
|
+
parts.push(` function detectCurrentLesson() {`);
|
|
5761
|
+
parts.push(` var hash = window.location.hash || '';`);
|
|
5762
|
+
parts.push(` var match = hash.match(/#\\/lessons\\/([^/]+)/);`);
|
|
5763
|
+
parts.push(` return match ? match[1] : null;`);
|
|
5764
|
+
parts.push(` }`);
|
|
5765
|
+
parts.push(``);
|
|
5766
|
+
parts.push(` function applyLessonClasses() {`);
|
|
5767
|
+
parts.push(` var lessonId = detectCurrentLesson();`);
|
|
5768
|
+
parts.push(` if (lessonId === currentLessonId) return;`);
|
|
5769
|
+
parts.push(` currentLessonId = lessonId;`);
|
|
5770
|
+
parts.push(` for (var i = 0; i < allLessonClasses.length; i++) {`);
|
|
5771
|
+
parts.push(` document.documentElement.classList.remove(allLessonClasses[i]);`);
|
|
5772
|
+
parts.push(` }`);
|
|
5773
|
+
parts.push(` if (lessonId && lessonMap[lessonId]) {`);
|
|
5774
|
+
parts.push(` var classes = lessonMap[lessonId].split(' ');`);
|
|
5775
|
+
parts.push(` for (var j = 0; j < classes.length; j++) {`);
|
|
5776
|
+
parts.push(` if (classes[j]) document.documentElement.classList.add(classes[j]);`);
|
|
5777
|
+
parts.push(` }`);
|
|
5778
|
+
parts.push(` }`);
|
|
5779
|
+
parts.push(` }`);
|
|
5780
|
+
parts.push(``);
|
|
5781
|
+
}
|
|
5782
|
+
parts.push(` // Initialization`);
|
|
5783
|
+
parts.push(` function init() {`);
|
|
5784
|
+
if (hasBlocks) {
|
|
5785
|
+
parts.push(` applyBlockClasses();`);
|
|
5786
|
+
}
|
|
5787
|
+
if (hasLessons) {
|
|
5788
|
+
parts.push(` applyLessonClasses();`);
|
|
5789
|
+
parts.push(``);
|
|
5790
|
+
parts.push(` // Watch for Rise SPA navigation`);
|
|
5791
|
+
parts.push(` window.addEventListener('hashchange', function() {`);
|
|
5792
|
+
parts.push(` applyLessonClasses();`);
|
|
5793
|
+
if (hasBlocks) {
|
|
5794
|
+
parts.push(` setTimeout(applyBlockClasses, 200);`);
|
|
5795
|
+
}
|
|
5796
|
+
parts.push(` });`);
|
|
5797
|
+
}
|
|
5798
|
+
if (hasBlocks) {
|
|
5799
|
+
parts.push(``);
|
|
5800
|
+
parts.push(` // MutationObserver for lazily-rendered Rise blocks`);
|
|
5801
|
+
parts.push(` var observer = new MutationObserver(function(mutations) {`);
|
|
5802
|
+
parts.push(` for (var i = 0; i < mutations.length; i++) {`);
|
|
5803
|
+
parts.push(` if (mutations[i].addedNodes.length > 0) {`);
|
|
5804
|
+
parts.push(` applyBlockClasses();`);
|
|
5805
|
+
parts.push(` return;`);
|
|
5806
|
+
parts.push(` }`);
|
|
5807
|
+
parts.push(` }`);
|
|
5808
|
+
parts.push(` });`);
|
|
5809
|
+
parts.push(` var container = document.querySelector('#app') || document.body;`);
|
|
5810
|
+
parts.push(` observer.observe(container, { childList: true, subtree: true });`);
|
|
5811
|
+
}
|
|
5812
|
+
parts.push(` }`);
|
|
5813
|
+
parts.push(``);
|
|
5814
|
+
parts.push(` if (document.readyState === 'loading') {`);
|
|
5815
|
+
parts.push(` document.addEventListener('DOMContentLoaded', init);`);
|
|
5816
|
+
parts.push(` } else {`);
|
|
5817
|
+
parts.push(` init();`);
|
|
5818
|
+
parts.push(` }`);
|
|
5819
|
+
parts.push(`})();`);
|
|
5820
|
+
return parts.join("\n");
|
|
5821
|
+
}
|
|
5822
|
+
|
|
5690
5823
|
// src/patcher/html-injector.ts
|
|
5691
5824
|
var HtmlInjector = class {
|
|
5692
5825
|
config;
|
|
@@ -7077,6 +7210,13 @@ var Patcher = class {
|
|
|
7077
7210
|
console.log(`[Patcher] Fetched ${fetchedCount} remote files`);
|
|
7078
7211
|
}
|
|
7079
7212
|
const pluginAssets = this.generatePluginAssets();
|
|
7213
|
+
if (hasClassMappings(options.classMappings)) {
|
|
7214
|
+
const classMappingsJs = generateClassMappingsScript(options.classMappings);
|
|
7215
|
+
if (classMappingsJs) {
|
|
7216
|
+
pluginAssets.jsAfter = classMappingsJs + (pluginAssets.jsAfter ? "\n" + pluginAssets.jsAfter : "");
|
|
7217
|
+
console.log("[Patcher] Class mappings JS will be injected inline into HTML");
|
|
7218
|
+
}
|
|
7219
|
+
}
|
|
7080
7220
|
const hasPluginAssets = pluginAssets.cssBefore || pluginAssets.cssAfter || pluginAssets.jsBefore || pluginAssets.jsAfter;
|
|
7081
7221
|
if (hasPluginAssets) {
|
|
7082
7222
|
htmlInjector.setPluginAssets(pluginAssets);
|
|
@@ -7436,7 +7576,88 @@ var Logger = class {
|
|
|
7436
7576
|
this.level = level;
|
|
7437
7577
|
}
|
|
7438
7578
|
};
|
|
7579
|
+
var DESERIALIZE_REGEX = /deserialize\s*\(\s*["']([A-Za-z0-9+/=]+)["']\s*\)/;
|
|
7580
|
+
var RISE_HTML_PATHS = [
|
|
7581
|
+
"scormcontent/index.html",
|
|
7582
|
+
"index.html"
|
|
7583
|
+
];
|
|
7584
|
+
function extractCourseStructure(zipBuffer) {
|
|
7585
|
+
try {
|
|
7586
|
+
const zip = new AdmZip(zipBuffer);
|
|
7587
|
+
let htmlContent = null;
|
|
7588
|
+
for (const path of RISE_HTML_PATHS) {
|
|
7589
|
+
const entry = zip.getEntry(path);
|
|
7590
|
+
if (entry) {
|
|
7591
|
+
htmlContent = entry.getData().toString("utf-8");
|
|
7592
|
+
if (DESERIALIZE_REGEX.test(htmlContent)) break;
|
|
7593
|
+
htmlContent = null;
|
|
7594
|
+
}
|
|
7595
|
+
}
|
|
7596
|
+
if (!htmlContent) {
|
|
7597
|
+
return null;
|
|
7598
|
+
}
|
|
7599
|
+
const match = htmlContent.match(DESERIALIZE_REGEX);
|
|
7600
|
+
if (!match || !match[1]) {
|
|
7601
|
+
return null;
|
|
7602
|
+
}
|
|
7603
|
+
const jsonStr = Buffer.from(match[1], "base64").toString("utf-8");
|
|
7604
|
+
const data = JSON.parse(jsonStr);
|
|
7605
|
+
const course = data.course;
|
|
7606
|
+
if (!course || !Array.isArray(course.lessons)) {
|
|
7607
|
+
return null;
|
|
7608
|
+
}
|
|
7609
|
+
const lessons = course.lessons.filter((lesson) => !lesson.deleted).sort((a, b) => (a.position ?? 0) - (b.position ?? 0)).map((lesson) => {
|
|
7610
|
+
const blocks = (lesson.items || []).map((block) => {
|
|
7611
|
+
const structBlock = {
|
|
7612
|
+
id: block.id,
|
|
7613
|
+
type: block.type || "unknown"
|
|
7614
|
+
};
|
|
7615
|
+
if (block.family) structBlock.family = block.family;
|
|
7616
|
+
if (block.variant) structBlock.variant = block.variant;
|
|
7617
|
+
const title = deriveBlockTitle(block);
|
|
7618
|
+
if (title) structBlock.title = title;
|
|
7619
|
+
return structBlock;
|
|
7620
|
+
});
|
|
7621
|
+
return {
|
|
7622
|
+
id: lesson.id,
|
|
7623
|
+
title: lesson.title || "Untitled Lesson",
|
|
7624
|
+
type: lesson.type || "blocks",
|
|
7625
|
+
blocks
|
|
7626
|
+
};
|
|
7627
|
+
});
|
|
7628
|
+
return {
|
|
7629
|
+
courseTitle: course.title || course.name || "Untitled Course",
|
|
7630
|
+
courseId: course.id || void 0,
|
|
7631
|
+
lessons
|
|
7632
|
+
};
|
|
7633
|
+
} catch {
|
|
7634
|
+
return null;
|
|
7635
|
+
}
|
|
7636
|
+
}
|
|
7637
|
+
function deriveBlockTitle(block) {
|
|
7638
|
+
if (block.title && typeof block.title === "string") {
|
|
7639
|
+
return stripHtml(block.title).substring(0, 80);
|
|
7640
|
+
}
|
|
7641
|
+
const items = block.items;
|
|
7642
|
+
if (!Array.isArray(items) || items.length === 0) return void 0;
|
|
7643
|
+
const firstItem = items[0];
|
|
7644
|
+
if (!firstItem) return void 0;
|
|
7645
|
+
if (firstItem.heading) {
|
|
7646
|
+
return stripHtml(firstItem.heading).substring(0, 80);
|
|
7647
|
+
}
|
|
7648
|
+
if (firstItem.title && typeof firstItem.title === "string") {
|
|
7649
|
+
return stripHtml(firstItem.title).substring(0, 80);
|
|
7650
|
+
}
|
|
7651
|
+
if (firstItem.paragraph) {
|
|
7652
|
+
const text = stripHtml(firstItem.paragraph).substring(0, 60);
|
|
7653
|
+
if (text) return text + (firstItem.paragraph.length > 60 ? "..." : "");
|
|
7654
|
+
}
|
|
7655
|
+
return void 0;
|
|
7656
|
+
}
|
|
7657
|
+
function stripHtml(html) {
|
|
7658
|
+
return html.replace(/<[^>]*>/g, "").trim();
|
|
7659
|
+
}
|
|
7439
7660
|
|
|
7440
|
-
export { AsyncAssetConfigSchema, AuthoringToolDetector, BlockingAssetConfigSchema, DEFAULT_LRS_OPTIONS, FormatDetector, HtmlInjector, LocalFoldersConfigSchema, Logger, LrsBridgeConfigSchema, ManifestUpdater, PatchAdamsConfigSchema, Patcher, PluginRegistry, StorylineHtmlInjector, buildCssAfterOptions, buildCssBeforeOptions, buildJsAfterOptions, buildJsBeforeOptions, defaultConfig, extractCourseFingerprint, extractCourseMetadata, generateConfigTemplate, generateCssAfterLoader, generateCssBeforeLoader, generateJsAfterLoader, generateJsBeforeLoader, generateLrsBridgeCode, loadConfig, mergeWithDefaults, pluginRegistry };
|
|
7661
|
+
export { AsyncAssetConfigSchema, AuthoringToolDetector, BlockingAssetConfigSchema, DEFAULT_LRS_OPTIONS, FormatDetector, HtmlInjector, LocalFoldersConfigSchema, Logger, LrsBridgeConfigSchema, ManifestUpdater, PatchAdamsConfigSchema, Patcher, PluginRegistry, StorylineHtmlInjector, buildCssAfterOptions, buildCssBeforeOptions, buildJsAfterOptions, buildJsBeforeOptions, defaultConfig, extractCourseFingerprint, extractCourseMetadata, extractCourseStructure, generateClassMappingsScript, generateConfigTemplate, generateCssAfterLoader, generateCssBeforeLoader, generateJsAfterLoader, generateJsBeforeLoader, generateLrsBridgeCode, hasClassMappings, loadConfig, mergeWithDefaults, pluginRegistry };
|
|
7441
7662
|
//# sourceMappingURL=index.js.map
|
|
7442
7663
|
//# sourceMappingURL=index.js.map
|