@patch-adams/core 1.5.24 → 1.6.1
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 +229 -0
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +229 -0
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +313 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +103 -1
- package/dist/index.d.ts +103 -1
- package/dist/index.js +311 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -5696,6 +5696,228 @@ function buildSkinJsOptions(config) {
|
|
|
5696
5696
|
};
|
|
5697
5697
|
}
|
|
5698
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
|
+
if (mappings.blockGroups && mappings.blockGroups.length > 0) return true;
|
|
5706
|
+
return false;
|
|
5707
|
+
}
|
|
5708
|
+
function generateClassMappingsScript(mappings) {
|
|
5709
|
+
if (!hasClassMappings(mappings)) return "";
|
|
5710
|
+
const courseClasses = (mappings.course || "").trim();
|
|
5711
|
+
const blockMap = {};
|
|
5712
|
+
const lessonMap = {};
|
|
5713
|
+
if (mappings.blocks) {
|
|
5714
|
+
for (const [id, classes] of Object.entries(mappings.blocks)) {
|
|
5715
|
+
const trimmed = classes?.trim();
|
|
5716
|
+
if (trimmed) blockMap[id] = trimmed;
|
|
5717
|
+
}
|
|
5718
|
+
}
|
|
5719
|
+
if (mappings.lessons) {
|
|
5720
|
+
for (const [id, classes] of Object.entries(mappings.lessons)) {
|
|
5721
|
+
const trimmed = classes?.trim();
|
|
5722
|
+
if (trimmed) lessonMap[id] = trimmed;
|
|
5723
|
+
}
|
|
5724
|
+
}
|
|
5725
|
+
const hasBlocks = Object.keys(blockMap).length > 0;
|
|
5726
|
+
const hasLessons = Object.keys(lessonMap).length > 0;
|
|
5727
|
+
const blockGroups = (mappings.blockGroups || []).filter(
|
|
5728
|
+
(g) => g.blockIds.length >= 2 && g.className.trim() && g.lessonId
|
|
5729
|
+
);
|
|
5730
|
+
const hasGroups = blockGroups.length > 0;
|
|
5731
|
+
const parts = [];
|
|
5732
|
+
parts.push(`// PA-Patcher: Custom Class Mappings`);
|
|
5733
|
+
parts.push(`(function() {`);
|
|
5734
|
+
parts.push(` 'use strict';`);
|
|
5735
|
+
parts.push(``);
|
|
5736
|
+
if (courseClasses) {
|
|
5737
|
+
parts.push(` // Course-level classes (applied to <html>)`);
|
|
5738
|
+
parts.push(` var courseClasses = ${JSON.stringify(courseClasses)};`);
|
|
5739
|
+
parts.push(` courseClasses.split(' ').forEach(function(cls) {`);
|
|
5740
|
+
parts.push(` if (cls) document.documentElement.classList.add(cls);`);
|
|
5741
|
+
parts.push(` });`);
|
|
5742
|
+
parts.push(``);
|
|
5743
|
+
}
|
|
5744
|
+
if (hasBlocks) {
|
|
5745
|
+
parts.push(` // Block-level classes (applied to [data-block-id] elements)`);
|
|
5746
|
+
parts.push(` var blockMap = ${JSON.stringify(blockMap)};`);
|
|
5747
|
+
parts.push(``);
|
|
5748
|
+
parts.push(` function applyBlockClasses() {`);
|
|
5749
|
+
parts.push(` var ids = Object.keys(blockMap);`);
|
|
5750
|
+
parts.push(` for (var i = 0; i < ids.length; i++) {`);
|
|
5751
|
+
parts.push(` var el = document.querySelector('[data-block-id="' + ids[i] + '"]');`);
|
|
5752
|
+
parts.push(` if (el) {`);
|
|
5753
|
+
parts.push(` var classes = blockMap[ids[i]].split(' ');`);
|
|
5754
|
+
parts.push(` for (var j = 0; j < classes.length; j++) {`);
|
|
5755
|
+
parts.push(` if (classes[j]) el.classList.add(classes[j]);`);
|
|
5756
|
+
parts.push(` }`);
|
|
5757
|
+
parts.push(` }`);
|
|
5758
|
+
parts.push(` }`);
|
|
5759
|
+
parts.push(` }`);
|
|
5760
|
+
parts.push(``);
|
|
5761
|
+
}
|
|
5762
|
+
if (hasLessons) {
|
|
5763
|
+
parts.push(` // Lesson-level classes (toggled on <html> via hash navigation)`);
|
|
5764
|
+
parts.push(` var lessonMap = ${JSON.stringify(lessonMap)};`);
|
|
5765
|
+
parts.push(` var allLessonClasses = [];`);
|
|
5766
|
+
parts.push(` Object.keys(lessonMap).forEach(function(id) {`);
|
|
5767
|
+
parts.push(` lessonMap[id].split(' ').forEach(function(cls) {`);
|
|
5768
|
+
parts.push(` if (cls && allLessonClasses.indexOf(cls) === -1) allLessonClasses.push(cls);`);
|
|
5769
|
+
parts.push(` });`);
|
|
5770
|
+
parts.push(` });`);
|
|
5771
|
+
parts.push(``);
|
|
5772
|
+
parts.push(` var currentLessonId = null;`);
|
|
5773
|
+
parts.push(``);
|
|
5774
|
+
parts.push(` function detectCurrentLesson() {`);
|
|
5775
|
+
parts.push(` var hash = window.location.hash || '';`);
|
|
5776
|
+
parts.push(` var match = hash.match(/#\\/lessons\\/([^/]+)/);`);
|
|
5777
|
+
parts.push(` return match ? match[1] : null;`);
|
|
5778
|
+
parts.push(` }`);
|
|
5779
|
+
parts.push(``);
|
|
5780
|
+
parts.push(` function applyLessonClasses() {`);
|
|
5781
|
+
parts.push(` var lessonId = detectCurrentLesson();`);
|
|
5782
|
+
parts.push(` if (lessonId === currentLessonId) return;`);
|
|
5783
|
+
parts.push(` currentLessonId = lessonId;`);
|
|
5784
|
+
parts.push(` for (var i = 0; i < allLessonClasses.length; i++) {`);
|
|
5785
|
+
parts.push(` document.documentElement.classList.remove(allLessonClasses[i]);`);
|
|
5786
|
+
parts.push(` }`);
|
|
5787
|
+
parts.push(` if (lessonId && lessonMap[lessonId]) {`);
|
|
5788
|
+
parts.push(` var classes = lessonMap[lessonId].split(' ');`);
|
|
5789
|
+
parts.push(` for (var j = 0; j < classes.length; j++) {`);
|
|
5790
|
+
parts.push(` if (classes[j]) document.documentElement.classList.add(classes[j]);`);
|
|
5791
|
+
parts.push(` }`);
|
|
5792
|
+
parts.push(` }`);
|
|
5793
|
+
parts.push(` }`);
|
|
5794
|
+
parts.push(``);
|
|
5795
|
+
}
|
|
5796
|
+
if (hasGroups) {
|
|
5797
|
+
const groupData = blockGroups.map((g) => ({
|
|
5798
|
+
id: g.id,
|
|
5799
|
+
lessonId: g.lessonId,
|
|
5800
|
+
blockIds: g.blockIds,
|
|
5801
|
+
className: g.className.trim()
|
|
5802
|
+
}));
|
|
5803
|
+
parts.push(` // Block groups (adjacent blocks wrapped in container divs)`);
|
|
5804
|
+
parts.push(` var groupMap = ${JSON.stringify(groupData)};`);
|
|
5805
|
+
parts.push(``);
|
|
5806
|
+
parts.push(` function applyBlockGroups() {`);
|
|
5807
|
+
parts.push(` var hash = window.location.hash || '';`);
|
|
5808
|
+
parts.push(` var match = hash.match(/#\\/lessons\\/([^/]+)/);`);
|
|
5809
|
+
parts.push(` var currentLesson = match ? match[1] : null;`);
|
|
5810
|
+
parts.push(` for (var g = 0; g < groupMap.length; g++) {`);
|
|
5811
|
+
parts.push(` var group = groupMap[g];`);
|
|
5812
|
+
parts.push(` if (group.lessonId !== currentLesson) continue;`);
|
|
5813
|
+
parts.push(` if (document.querySelector('[data-pa-group-id="' + group.id + '"]')) continue;`);
|
|
5814
|
+
parts.push(` var blocks = [];`);
|
|
5815
|
+
parts.push(` var allPresent = true;`);
|
|
5816
|
+
parts.push(` for (var b = 0; b < group.blockIds.length; b++) {`);
|
|
5817
|
+
parts.push(` var el = document.querySelector('[data-block-id="' + group.blockIds[b] + '"]');`);
|
|
5818
|
+
parts.push(` if (!el) { allPresent = false; break; }`);
|
|
5819
|
+
parts.push(` blocks.push(el);`);
|
|
5820
|
+
parts.push(` }`);
|
|
5821
|
+
parts.push(` if (!allPresent) continue;`);
|
|
5822
|
+
parts.push(` var parent = blocks[0].parentNode;`);
|
|
5823
|
+
parts.push(` var sameParent = true;`);
|
|
5824
|
+
parts.push(` for (var s = 1; s < blocks.length; s++) {`);
|
|
5825
|
+
parts.push(` if (blocks[s].parentNode !== parent) { sameParent = false; break; }`);
|
|
5826
|
+
parts.push(` }`);
|
|
5827
|
+
parts.push(` if (!sameParent) continue;`);
|
|
5828
|
+
parts.push(` var wrapper = document.createElement('div');`);
|
|
5829
|
+
parts.push(` wrapper.setAttribute('data-pa-group-id', group.id);`);
|
|
5830
|
+
parts.push(` var cls = group.className.split(' ');`);
|
|
5831
|
+
parts.push(` for (var c = 0; c < cls.length; c++) {`);
|
|
5832
|
+
parts.push(` if (cls[c]) wrapper.classList.add(cls[c]);`);
|
|
5833
|
+
parts.push(` }`);
|
|
5834
|
+
parts.push(` parent.insertBefore(wrapper, blocks[0]);`);
|
|
5835
|
+
parts.push(` for (var m = 0; m < blocks.length; m++) {`);
|
|
5836
|
+
parts.push(` wrapper.appendChild(blocks[m]);`);
|
|
5837
|
+
parts.push(` }`);
|
|
5838
|
+
parts.push(` }`);
|
|
5839
|
+
parts.push(` }`);
|
|
5840
|
+
parts.push(``);
|
|
5841
|
+
parts.push(` function teardownBlockGroups() {`);
|
|
5842
|
+
parts.push(` var wrappers = document.querySelectorAll('[data-pa-group-id]');`);
|
|
5843
|
+
parts.push(` for (var w = 0; w < wrappers.length; w++) {`);
|
|
5844
|
+
parts.push(` var wr = wrappers[w];`);
|
|
5845
|
+
parts.push(` var par = wr.parentNode;`);
|
|
5846
|
+
parts.push(` while (wr.firstChild) {`);
|
|
5847
|
+
parts.push(` par.insertBefore(wr.firstChild, wr);`);
|
|
5848
|
+
parts.push(` }`);
|
|
5849
|
+
parts.push(` par.removeChild(wr);`);
|
|
5850
|
+
parts.push(` }`);
|
|
5851
|
+
parts.push(` }`);
|
|
5852
|
+
parts.push(``);
|
|
5853
|
+
}
|
|
5854
|
+
parts.push(` // Initialization`);
|
|
5855
|
+
parts.push(` function init() {`);
|
|
5856
|
+
if (hasBlocks) {
|
|
5857
|
+
parts.push(` applyBlockClasses();`);
|
|
5858
|
+
}
|
|
5859
|
+
if (hasGroups) {
|
|
5860
|
+
parts.push(` applyBlockGroups();`);
|
|
5861
|
+
}
|
|
5862
|
+
if (hasLessons) {
|
|
5863
|
+
parts.push(` applyLessonClasses();`);
|
|
5864
|
+
}
|
|
5865
|
+
if (hasLessons || hasGroups) {
|
|
5866
|
+
parts.push(``);
|
|
5867
|
+
parts.push(` // Watch for Rise SPA navigation`);
|
|
5868
|
+
parts.push(` window.addEventListener('hashchange', function() {`);
|
|
5869
|
+
if (hasGroups) {
|
|
5870
|
+
parts.push(` teardownBlockGroups();`);
|
|
5871
|
+
}
|
|
5872
|
+
if (hasLessons) {
|
|
5873
|
+
parts.push(` applyLessonClasses();`);
|
|
5874
|
+
}
|
|
5875
|
+
if (hasBlocks) {
|
|
5876
|
+
parts.push(` setTimeout(applyBlockClasses, 200);`);
|
|
5877
|
+
}
|
|
5878
|
+
if (hasGroups) {
|
|
5879
|
+
parts.push(` setTimeout(applyBlockGroups, 300);`);
|
|
5880
|
+
}
|
|
5881
|
+
parts.push(` });`);
|
|
5882
|
+
}
|
|
5883
|
+
if (hasBlocks || hasGroups) {
|
|
5884
|
+
parts.push(``);
|
|
5885
|
+
parts.push(` // MutationObserver for lazily-rendered Rise blocks`);
|
|
5886
|
+
if (hasGroups) {
|
|
5887
|
+
parts.push(` var debounceTimer = null;`);
|
|
5888
|
+
parts.push(` var observer = new MutationObserver(function() {`);
|
|
5889
|
+
parts.push(` if (debounceTimer) clearTimeout(debounceTimer);`);
|
|
5890
|
+
parts.push(` debounceTimer = setTimeout(function() {`);
|
|
5891
|
+
if (hasBlocks) {
|
|
5892
|
+
parts.push(` applyBlockClasses();`);
|
|
5893
|
+
}
|
|
5894
|
+
parts.push(` applyBlockGroups();`);
|
|
5895
|
+
parts.push(` }, 100);`);
|
|
5896
|
+
parts.push(` });`);
|
|
5897
|
+
} else {
|
|
5898
|
+
parts.push(` var observer = new MutationObserver(function(mutations) {`);
|
|
5899
|
+
parts.push(` for (var i = 0; i < mutations.length; i++) {`);
|
|
5900
|
+
parts.push(` if (mutations[i].addedNodes.length > 0) {`);
|
|
5901
|
+
parts.push(` applyBlockClasses();`);
|
|
5902
|
+
parts.push(` return;`);
|
|
5903
|
+
parts.push(` }`);
|
|
5904
|
+
parts.push(` }`);
|
|
5905
|
+
parts.push(` });`);
|
|
5906
|
+
}
|
|
5907
|
+
parts.push(` var container = document.querySelector('#app') || document.body;`);
|
|
5908
|
+
parts.push(` observer.observe(container, { childList: true, subtree: true });`);
|
|
5909
|
+
}
|
|
5910
|
+
parts.push(` }`);
|
|
5911
|
+
parts.push(``);
|
|
5912
|
+
parts.push(` if (document.readyState === 'loading') {`);
|
|
5913
|
+
parts.push(` document.addEventListener('DOMContentLoaded', init);`);
|
|
5914
|
+
parts.push(` } else {`);
|
|
5915
|
+
parts.push(` init();`);
|
|
5916
|
+
parts.push(` }`);
|
|
5917
|
+
parts.push(`})();`);
|
|
5918
|
+
return parts.join("\n");
|
|
5919
|
+
}
|
|
5920
|
+
|
|
5699
5921
|
// src/patcher/html-injector.ts
|
|
5700
5922
|
var HtmlInjector = class {
|
|
5701
5923
|
config;
|
|
@@ -7086,6 +7308,13 @@ var Patcher = class {
|
|
|
7086
7308
|
console.log(`[Patcher] Fetched ${fetchedCount} remote files`);
|
|
7087
7309
|
}
|
|
7088
7310
|
const pluginAssets = this.generatePluginAssets();
|
|
7311
|
+
if (hasClassMappings(options.classMappings)) {
|
|
7312
|
+
const classMappingsJs = generateClassMappingsScript(options.classMappings);
|
|
7313
|
+
if (classMappingsJs) {
|
|
7314
|
+
pluginAssets.jsAfter = classMappingsJs + (pluginAssets.jsAfter ? "\n" + pluginAssets.jsAfter : "");
|
|
7315
|
+
console.log("[Patcher] Class mappings JS will be injected inline into HTML");
|
|
7316
|
+
}
|
|
7317
|
+
}
|
|
7089
7318
|
const hasPluginAssets = pluginAssets.cssBefore || pluginAssets.cssAfter || pluginAssets.jsBefore || pluginAssets.jsAfter;
|
|
7090
7319
|
if (hasPluginAssets) {
|
|
7091
7320
|
htmlInjector.setPluginAssets(pluginAssets);
|
|
@@ -7445,6 +7674,87 @@ var Logger = class {
|
|
|
7445
7674
|
this.level = level;
|
|
7446
7675
|
}
|
|
7447
7676
|
};
|
|
7677
|
+
var DESERIALIZE_REGEX = /deserialize\s*\(\s*["']([A-Za-z0-9+/=]+)["']\s*\)/;
|
|
7678
|
+
var RISE_HTML_PATHS = [
|
|
7679
|
+
"scormcontent/index.html",
|
|
7680
|
+
"index.html"
|
|
7681
|
+
];
|
|
7682
|
+
function extractCourseStructure(zipBuffer) {
|
|
7683
|
+
try {
|
|
7684
|
+
const zip = new AdmZip__default.default(zipBuffer);
|
|
7685
|
+
let htmlContent = null;
|
|
7686
|
+
for (const path of RISE_HTML_PATHS) {
|
|
7687
|
+
const entry = zip.getEntry(path);
|
|
7688
|
+
if (entry) {
|
|
7689
|
+
htmlContent = entry.getData().toString("utf-8");
|
|
7690
|
+
if (DESERIALIZE_REGEX.test(htmlContent)) break;
|
|
7691
|
+
htmlContent = null;
|
|
7692
|
+
}
|
|
7693
|
+
}
|
|
7694
|
+
if (!htmlContent) {
|
|
7695
|
+
return null;
|
|
7696
|
+
}
|
|
7697
|
+
const match = htmlContent.match(DESERIALIZE_REGEX);
|
|
7698
|
+
if (!match || !match[1]) {
|
|
7699
|
+
return null;
|
|
7700
|
+
}
|
|
7701
|
+
const jsonStr = Buffer.from(match[1], "base64").toString("utf-8");
|
|
7702
|
+
const data = JSON.parse(jsonStr);
|
|
7703
|
+
const course = data.course;
|
|
7704
|
+
if (!course || !Array.isArray(course.lessons)) {
|
|
7705
|
+
return null;
|
|
7706
|
+
}
|
|
7707
|
+
const lessons = course.lessons.filter((lesson) => !lesson.deleted).sort((a, b) => (a.position ?? 0) - (b.position ?? 0)).map((lesson) => {
|
|
7708
|
+
const blocks = (lesson.items || []).map((block) => {
|
|
7709
|
+
const structBlock = {
|
|
7710
|
+
id: block.id,
|
|
7711
|
+
type: block.type || "unknown"
|
|
7712
|
+
};
|
|
7713
|
+
if (block.family) structBlock.family = block.family;
|
|
7714
|
+
if (block.variant) structBlock.variant = block.variant;
|
|
7715
|
+
const title = deriveBlockTitle(block);
|
|
7716
|
+
if (title) structBlock.title = title;
|
|
7717
|
+
return structBlock;
|
|
7718
|
+
});
|
|
7719
|
+
return {
|
|
7720
|
+
id: lesson.id,
|
|
7721
|
+
title: lesson.title || "Untitled Lesson",
|
|
7722
|
+
type: lesson.type || "blocks",
|
|
7723
|
+
blocks
|
|
7724
|
+
};
|
|
7725
|
+
});
|
|
7726
|
+
return {
|
|
7727
|
+
courseTitle: course.title || course.name || "Untitled Course",
|
|
7728
|
+
courseId: course.id || void 0,
|
|
7729
|
+
lessons
|
|
7730
|
+
};
|
|
7731
|
+
} catch {
|
|
7732
|
+
return null;
|
|
7733
|
+
}
|
|
7734
|
+
}
|
|
7735
|
+
function deriveBlockTitle(block) {
|
|
7736
|
+
if (block.title && typeof block.title === "string") {
|
|
7737
|
+
return stripHtml(block.title).substring(0, 80);
|
|
7738
|
+
}
|
|
7739
|
+
const items = block.items;
|
|
7740
|
+
if (!Array.isArray(items) || items.length === 0) return void 0;
|
|
7741
|
+
const firstItem = items[0];
|
|
7742
|
+
if (!firstItem) return void 0;
|
|
7743
|
+
if (firstItem.heading) {
|
|
7744
|
+
return stripHtml(firstItem.heading).substring(0, 80);
|
|
7745
|
+
}
|
|
7746
|
+
if (firstItem.title && typeof firstItem.title === "string") {
|
|
7747
|
+
return stripHtml(firstItem.title).substring(0, 80);
|
|
7748
|
+
}
|
|
7749
|
+
if (firstItem.paragraph) {
|
|
7750
|
+
const text = stripHtml(firstItem.paragraph).substring(0, 60);
|
|
7751
|
+
if (text) return text + (firstItem.paragraph.length > 60 ? "..." : "");
|
|
7752
|
+
}
|
|
7753
|
+
return void 0;
|
|
7754
|
+
}
|
|
7755
|
+
function stripHtml(html) {
|
|
7756
|
+
return html.replace(/<[^>]*>/g, "").trim();
|
|
7757
|
+
}
|
|
7448
7758
|
|
|
7449
7759
|
exports.AsyncAssetConfigSchema = AsyncAssetConfigSchema;
|
|
7450
7760
|
exports.AuthoringToolDetector = AuthoringToolDetector;
|
|
@@ -7467,12 +7777,15 @@ exports.buildJsBeforeOptions = buildJsBeforeOptions;
|
|
|
7467
7777
|
exports.defaultConfig = defaultConfig;
|
|
7468
7778
|
exports.extractCourseFingerprint = extractCourseFingerprint;
|
|
7469
7779
|
exports.extractCourseMetadata = extractCourseMetadata;
|
|
7780
|
+
exports.extractCourseStructure = extractCourseStructure;
|
|
7781
|
+
exports.generateClassMappingsScript = generateClassMappingsScript;
|
|
7470
7782
|
exports.generateConfigTemplate = generateConfigTemplate;
|
|
7471
7783
|
exports.generateCssAfterLoader = generateCssAfterLoader;
|
|
7472
7784
|
exports.generateCssBeforeLoader = generateCssBeforeLoader;
|
|
7473
7785
|
exports.generateJsAfterLoader = generateJsAfterLoader;
|
|
7474
7786
|
exports.generateJsBeforeLoader = generateJsBeforeLoader;
|
|
7475
7787
|
exports.generateLrsBridgeCode = generateLrsBridgeCode;
|
|
7788
|
+
exports.hasClassMappings = hasClassMappings;
|
|
7476
7789
|
exports.loadConfig = loadConfig;
|
|
7477
7790
|
exports.mergeWithDefaults = mergeWithDefaults;
|
|
7478
7791
|
exports.pluginRegistry = pluginRegistry;
|