@patch-adams/core 1.5.23 → 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 -1
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +140 -1
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +224 -1
- 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 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -5315,7 +5315,6 @@ window.pa_patcher = window.pa_patcher || {
|
|
|
5315
5315
|
try {
|
|
5316
5316
|
var xhr = new XMLHttpRequest();
|
|
5317
5317
|
xhr.open('GET', ASSET_VERSION_URL, false);
|
|
5318
|
-
xhr.timeout = 2000;
|
|
5319
5318
|
xhr.send();
|
|
5320
5319
|
if (xhr.status === 200) {
|
|
5321
5320
|
window.__pa_v = JSON.parse(xhr.responseText).v || '1';
|
|
@@ -5697,6 +5696,139 @@ function buildSkinJsOptions(config) {
|
|
|
5697
5696
|
};
|
|
5698
5697
|
}
|
|
5699
5698
|
|
|
5699
|
+
// src/templates/class-mappings.ts
|
|
5700
|
+
function hasClassMappings(mappings) {
|
|
5701
|
+
if (!mappings) return false;
|
|
5702
|
+
if (mappings.course?.trim()) return true;
|
|
5703
|
+
if (mappings.lessons && Object.values(mappings.lessons).some((v) => v?.trim())) return true;
|
|
5704
|
+
if (mappings.blocks && Object.values(mappings.blocks).some((v) => v?.trim())) return true;
|
|
5705
|
+
return false;
|
|
5706
|
+
}
|
|
5707
|
+
function generateClassMappingsScript(mappings) {
|
|
5708
|
+
if (!hasClassMappings(mappings)) return "";
|
|
5709
|
+
const courseClasses = (mappings.course || "").trim();
|
|
5710
|
+
const blockMap = {};
|
|
5711
|
+
const lessonMap = {};
|
|
5712
|
+
if (mappings.blocks) {
|
|
5713
|
+
for (const [id, classes] of Object.entries(mappings.blocks)) {
|
|
5714
|
+
const trimmed = classes?.trim();
|
|
5715
|
+
if (trimmed) blockMap[id] = trimmed;
|
|
5716
|
+
}
|
|
5717
|
+
}
|
|
5718
|
+
if (mappings.lessons) {
|
|
5719
|
+
for (const [id, classes] of Object.entries(mappings.lessons)) {
|
|
5720
|
+
const trimmed = classes?.trim();
|
|
5721
|
+
if (trimmed) lessonMap[id] = trimmed;
|
|
5722
|
+
}
|
|
5723
|
+
}
|
|
5724
|
+
const hasBlocks = Object.keys(blockMap).length > 0;
|
|
5725
|
+
const hasLessons = Object.keys(lessonMap).length > 0;
|
|
5726
|
+
const parts = [];
|
|
5727
|
+
parts.push(`// PA-Patcher: Custom Class Mappings`);
|
|
5728
|
+
parts.push(`(function() {`);
|
|
5729
|
+
parts.push(` 'use strict';`);
|
|
5730
|
+
parts.push(``);
|
|
5731
|
+
if (courseClasses) {
|
|
5732
|
+
parts.push(` // Course-level classes (applied to <html>)`);
|
|
5733
|
+
parts.push(` var courseClasses = ${JSON.stringify(courseClasses)};`);
|
|
5734
|
+
parts.push(` courseClasses.split(' ').forEach(function(cls) {`);
|
|
5735
|
+
parts.push(` if (cls) document.documentElement.classList.add(cls);`);
|
|
5736
|
+
parts.push(` });`);
|
|
5737
|
+
parts.push(``);
|
|
5738
|
+
}
|
|
5739
|
+
if (hasBlocks) {
|
|
5740
|
+
parts.push(` // Block-level classes (applied to [data-block-id] elements)`);
|
|
5741
|
+
parts.push(` var blockMap = ${JSON.stringify(blockMap)};`);
|
|
5742
|
+
parts.push(``);
|
|
5743
|
+
parts.push(` function applyBlockClasses() {`);
|
|
5744
|
+
parts.push(` var ids = Object.keys(blockMap);`);
|
|
5745
|
+
parts.push(` for (var i = 0; i < ids.length; i++) {`);
|
|
5746
|
+
parts.push(` var el = document.querySelector('[data-block-id="' + ids[i] + '"]');`);
|
|
5747
|
+
parts.push(` if (el) {`);
|
|
5748
|
+
parts.push(` var classes = blockMap[ids[i]].split(' ');`);
|
|
5749
|
+
parts.push(` for (var j = 0; j < classes.length; j++) {`);
|
|
5750
|
+
parts.push(` if (classes[j]) el.classList.add(classes[j]);`);
|
|
5751
|
+
parts.push(` }`);
|
|
5752
|
+
parts.push(` }`);
|
|
5753
|
+
parts.push(` }`);
|
|
5754
|
+
parts.push(` }`);
|
|
5755
|
+
parts.push(``);
|
|
5756
|
+
}
|
|
5757
|
+
if (hasLessons) {
|
|
5758
|
+
parts.push(` // Lesson-level classes (toggled on <html> via hash navigation)`);
|
|
5759
|
+
parts.push(` var lessonMap = ${JSON.stringify(lessonMap)};`);
|
|
5760
|
+
parts.push(` var allLessonClasses = [];`);
|
|
5761
|
+
parts.push(` Object.keys(lessonMap).forEach(function(id) {`);
|
|
5762
|
+
parts.push(` lessonMap[id].split(' ').forEach(function(cls) {`);
|
|
5763
|
+
parts.push(` if (cls && allLessonClasses.indexOf(cls) === -1) allLessonClasses.push(cls);`);
|
|
5764
|
+
parts.push(` });`);
|
|
5765
|
+
parts.push(` });`);
|
|
5766
|
+
parts.push(``);
|
|
5767
|
+
parts.push(` var currentLessonId = null;`);
|
|
5768
|
+
parts.push(``);
|
|
5769
|
+
parts.push(` function detectCurrentLesson() {`);
|
|
5770
|
+
parts.push(` var hash = window.location.hash || '';`);
|
|
5771
|
+
parts.push(` var match = hash.match(/#\\/lessons\\/([^/]+)/);`);
|
|
5772
|
+
parts.push(` return match ? match[1] : null;`);
|
|
5773
|
+
parts.push(` }`);
|
|
5774
|
+
parts.push(``);
|
|
5775
|
+
parts.push(` function applyLessonClasses() {`);
|
|
5776
|
+
parts.push(` var lessonId = detectCurrentLesson();`);
|
|
5777
|
+
parts.push(` if (lessonId === currentLessonId) return;`);
|
|
5778
|
+
parts.push(` currentLessonId = lessonId;`);
|
|
5779
|
+
parts.push(` for (var i = 0; i < allLessonClasses.length; i++) {`);
|
|
5780
|
+
parts.push(` document.documentElement.classList.remove(allLessonClasses[i]);`);
|
|
5781
|
+
parts.push(` }`);
|
|
5782
|
+
parts.push(` if (lessonId && lessonMap[lessonId]) {`);
|
|
5783
|
+
parts.push(` var classes = lessonMap[lessonId].split(' ');`);
|
|
5784
|
+
parts.push(` for (var j = 0; j < classes.length; j++) {`);
|
|
5785
|
+
parts.push(` if (classes[j]) document.documentElement.classList.add(classes[j]);`);
|
|
5786
|
+
parts.push(` }`);
|
|
5787
|
+
parts.push(` }`);
|
|
5788
|
+
parts.push(` }`);
|
|
5789
|
+
parts.push(``);
|
|
5790
|
+
}
|
|
5791
|
+
parts.push(` // Initialization`);
|
|
5792
|
+
parts.push(` function init() {`);
|
|
5793
|
+
if (hasBlocks) {
|
|
5794
|
+
parts.push(` applyBlockClasses();`);
|
|
5795
|
+
}
|
|
5796
|
+
if (hasLessons) {
|
|
5797
|
+
parts.push(` applyLessonClasses();`);
|
|
5798
|
+
parts.push(``);
|
|
5799
|
+
parts.push(` // Watch for Rise SPA navigation`);
|
|
5800
|
+
parts.push(` window.addEventListener('hashchange', function() {`);
|
|
5801
|
+
parts.push(` applyLessonClasses();`);
|
|
5802
|
+
if (hasBlocks) {
|
|
5803
|
+
parts.push(` setTimeout(applyBlockClasses, 200);`);
|
|
5804
|
+
}
|
|
5805
|
+
parts.push(` });`);
|
|
5806
|
+
}
|
|
5807
|
+
if (hasBlocks) {
|
|
5808
|
+
parts.push(``);
|
|
5809
|
+
parts.push(` // MutationObserver for lazily-rendered Rise blocks`);
|
|
5810
|
+
parts.push(` var observer = new MutationObserver(function(mutations) {`);
|
|
5811
|
+
parts.push(` for (var i = 0; i < mutations.length; i++) {`);
|
|
5812
|
+
parts.push(` if (mutations[i].addedNodes.length > 0) {`);
|
|
5813
|
+
parts.push(` applyBlockClasses();`);
|
|
5814
|
+
parts.push(` return;`);
|
|
5815
|
+
parts.push(` }`);
|
|
5816
|
+
parts.push(` }`);
|
|
5817
|
+
parts.push(` });`);
|
|
5818
|
+
parts.push(` var container = document.querySelector('#app') || document.body;`);
|
|
5819
|
+
parts.push(` observer.observe(container, { childList: true, subtree: true });`);
|
|
5820
|
+
}
|
|
5821
|
+
parts.push(` }`);
|
|
5822
|
+
parts.push(``);
|
|
5823
|
+
parts.push(` if (document.readyState === 'loading') {`);
|
|
5824
|
+
parts.push(` document.addEventListener('DOMContentLoaded', init);`);
|
|
5825
|
+
parts.push(` } else {`);
|
|
5826
|
+
parts.push(` init();`);
|
|
5827
|
+
parts.push(` }`);
|
|
5828
|
+
parts.push(`})();`);
|
|
5829
|
+
return parts.join("\n");
|
|
5830
|
+
}
|
|
5831
|
+
|
|
5700
5832
|
// src/patcher/html-injector.ts
|
|
5701
5833
|
var HtmlInjector = class {
|
|
5702
5834
|
config;
|
|
@@ -7087,6 +7219,13 @@ var Patcher = class {
|
|
|
7087
7219
|
console.log(`[Patcher] Fetched ${fetchedCount} remote files`);
|
|
7088
7220
|
}
|
|
7089
7221
|
const pluginAssets = this.generatePluginAssets();
|
|
7222
|
+
if (hasClassMappings(options.classMappings)) {
|
|
7223
|
+
const classMappingsJs = generateClassMappingsScript(options.classMappings);
|
|
7224
|
+
if (classMappingsJs) {
|
|
7225
|
+
pluginAssets.jsAfter = classMappingsJs + (pluginAssets.jsAfter ? "\n" + pluginAssets.jsAfter : "");
|
|
7226
|
+
console.log("[Patcher] Class mappings JS will be injected inline into HTML");
|
|
7227
|
+
}
|
|
7228
|
+
}
|
|
7090
7229
|
const hasPluginAssets = pluginAssets.cssBefore || pluginAssets.cssAfter || pluginAssets.jsBefore || pluginAssets.jsAfter;
|
|
7091
7230
|
if (hasPluginAssets) {
|
|
7092
7231
|
htmlInjector.setPluginAssets(pluginAssets);
|
|
@@ -7446,6 +7585,87 @@ var Logger = class {
|
|
|
7446
7585
|
this.level = level;
|
|
7447
7586
|
}
|
|
7448
7587
|
};
|
|
7588
|
+
var DESERIALIZE_REGEX = /deserialize\s*\(\s*["']([A-Za-z0-9+/=]+)["']\s*\)/;
|
|
7589
|
+
var RISE_HTML_PATHS = [
|
|
7590
|
+
"scormcontent/index.html",
|
|
7591
|
+
"index.html"
|
|
7592
|
+
];
|
|
7593
|
+
function extractCourseStructure(zipBuffer) {
|
|
7594
|
+
try {
|
|
7595
|
+
const zip = new AdmZip__default.default(zipBuffer);
|
|
7596
|
+
let htmlContent = null;
|
|
7597
|
+
for (const path of RISE_HTML_PATHS) {
|
|
7598
|
+
const entry = zip.getEntry(path);
|
|
7599
|
+
if (entry) {
|
|
7600
|
+
htmlContent = entry.getData().toString("utf-8");
|
|
7601
|
+
if (DESERIALIZE_REGEX.test(htmlContent)) break;
|
|
7602
|
+
htmlContent = null;
|
|
7603
|
+
}
|
|
7604
|
+
}
|
|
7605
|
+
if (!htmlContent) {
|
|
7606
|
+
return null;
|
|
7607
|
+
}
|
|
7608
|
+
const match = htmlContent.match(DESERIALIZE_REGEX);
|
|
7609
|
+
if (!match || !match[1]) {
|
|
7610
|
+
return null;
|
|
7611
|
+
}
|
|
7612
|
+
const jsonStr = Buffer.from(match[1], "base64").toString("utf-8");
|
|
7613
|
+
const data = JSON.parse(jsonStr);
|
|
7614
|
+
const course = data.course;
|
|
7615
|
+
if (!course || !Array.isArray(course.lessons)) {
|
|
7616
|
+
return null;
|
|
7617
|
+
}
|
|
7618
|
+
const lessons = course.lessons.filter((lesson) => !lesson.deleted).sort((a, b) => (a.position ?? 0) - (b.position ?? 0)).map((lesson) => {
|
|
7619
|
+
const blocks = (lesson.items || []).map((block) => {
|
|
7620
|
+
const structBlock = {
|
|
7621
|
+
id: block.id,
|
|
7622
|
+
type: block.type || "unknown"
|
|
7623
|
+
};
|
|
7624
|
+
if (block.family) structBlock.family = block.family;
|
|
7625
|
+
if (block.variant) structBlock.variant = block.variant;
|
|
7626
|
+
const title = deriveBlockTitle(block);
|
|
7627
|
+
if (title) structBlock.title = title;
|
|
7628
|
+
return structBlock;
|
|
7629
|
+
});
|
|
7630
|
+
return {
|
|
7631
|
+
id: lesson.id,
|
|
7632
|
+
title: lesson.title || "Untitled Lesson",
|
|
7633
|
+
type: lesson.type || "blocks",
|
|
7634
|
+
blocks
|
|
7635
|
+
};
|
|
7636
|
+
});
|
|
7637
|
+
return {
|
|
7638
|
+
courseTitle: course.title || course.name || "Untitled Course",
|
|
7639
|
+
courseId: course.id || void 0,
|
|
7640
|
+
lessons
|
|
7641
|
+
};
|
|
7642
|
+
} catch {
|
|
7643
|
+
return null;
|
|
7644
|
+
}
|
|
7645
|
+
}
|
|
7646
|
+
function deriveBlockTitle(block) {
|
|
7647
|
+
if (block.title && typeof block.title === "string") {
|
|
7648
|
+
return stripHtml(block.title).substring(0, 80);
|
|
7649
|
+
}
|
|
7650
|
+
const items = block.items;
|
|
7651
|
+
if (!Array.isArray(items) || items.length === 0) return void 0;
|
|
7652
|
+
const firstItem = items[0];
|
|
7653
|
+
if (!firstItem) return void 0;
|
|
7654
|
+
if (firstItem.heading) {
|
|
7655
|
+
return stripHtml(firstItem.heading).substring(0, 80);
|
|
7656
|
+
}
|
|
7657
|
+
if (firstItem.title && typeof firstItem.title === "string") {
|
|
7658
|
+
return stripHtml(firstItem.title).substring(0, 80);
|
|
7659
|
+
}
|
|
7660
|
+
if (firstItem.paragraph) {
|
|
7661
|
+
const text = stripHtml(firstItem.paragraph).substring(0, 60);
|
|
7662
|
+
if (text) return text + (firstItem.paragraph.length > 60 ? "..." : "");
|
|
7663
|
+
}
|
|
7664
|
+
return void 0;
|
|
7665
|
+
}
|
|
7666
|
+
function stripHtml(html) {
|
|
7667
|
+
return html.replace(/<[^>]*>/g, "").trim();
|
|
7668
|
+
}
|
|
7449
7669
|
|
|
7450
7670
|
exports.AsyncAssetConfigSchema = AsyncAssetConfigSchema;
|
|
7451
7671
|
exports.AuthoringToolDetector = AuthoringToolDetector;
|
|
@@ -7468,12 +7688,15 @@ exports.buildJsBeforeOptions = buildJsBeforeOptions;
|
|
|
7468
7688
|
exports.defaultConfig = defaultConfig;
|
|
7469
7689
|
exports.extractCourseFingerprint = extractCourseFingerprint;
|
|
7470
7690
|
exports.extractCourseMetadata = extractCourseMetadata;
|
|
7691
|
+
exports.extractCourseStructure = extractCourseStructure;
|
|
7692
|
+
exports.generateClassMappingsScript = generateClassMappingsScript;
|
|
7471
7693
|
exports.generateConfigTemplate = generateConfigTemplate;
|
|
7472
7694
|
exports.generateCssAfterLoader = generateCssAfterLoader;
|
|
7473
7695
|
exports.generateCssBeforeLoader = generateCssBeforeLoader;
|
|
7474
7696
|
exports.generateJsAfterLoader = generateJsAfterLoader;
|
|
7475
7697
|
exports.generateJsBeforeLoader = generateJsBeforeLoader;
|
|
7476
7698
|
exports.generateLrsBridgeCode = generateLrsBridgeCode;
|
|
7699
|
+
exports.hasClassMappings = hasClassMappings;
|
|
7477
7700
|
exports.loadConfig = loadConfig;
|
|
7478
7701
|
exports.mergeWithDefaults = mergeWithDefaults;
|
|
7479
7702
|
exports.pluginRegistry = pluginRegistry;
|