@patch-adams/core 1.4.36 → 1.5.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 +313 -13
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +313 -13
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +313 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +27 -1
- package/dist/index.d.ts +27 -1
- package/dist/index.js +313 -13
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -115,7 +115,9 @@ var PatchAdamsConfigSchema = zod.z.object({
|
|
|
115
115
|
/** LRS Bridge configuration for xAPI/LRS communication with Bravais */
|
|
116
116
|
lrsBridge: LrsBridgeConfigSchema.default({}),
|
|
117
117
|
/** Plugin configurations - each plugin is keyed by its name */
|
|
118
|
-
plugins: PluginsConfigSchema
|
|
118
|
+
plugins: PluginsConfigSchema,
|
|
119
|
+
/** Optional skin name — adds 'pa-skinned' + skin class to <html>, loads skin CSS/JS after core files */
|
|
120
|
+
skin: zod.z.string().min(1).optional()
|
|
119
121
|
});
|
|
120
122
|
|
|
121
123
|
// src/config/defaults.ts
|
|
@@ -605,6 +607,7 @@ function generateLrsBridgeCode(options) {
|
|
|
605
607
|
sessionId: null, // Session UUID
|
|
606
608
|
launchTime: null, // ISO timestamp of course launch
|
|
607
609
|
courseAttemptId: null, // Unique ID for this course attempt session (Xyleme format)
|
|
610
|
+
employeeId: null, // Employee ID from employee lookup
|
|
608
611
|
// Statistics
|
|
609
612
|
stats: {
|
|
610
613
|
statementsSent: 0,
|
|
@@ -1435,6 +1438,11 @@ function generateLrsBridgeCode(options) {
|
|
|
1435
1438
|
};
|
|
1436
1439
|
log('Updated actor account: bravaisUserId=' + employeeData.bravaisUserId + ', homePage=' + actor.account.homePage + ' (was: ' + originalAccountName + ')');
|
|
1437
1440
|
}
|
|
1441
|
+
|
|
1442
|
+
// Expose employee ID on LRS object for plugins (e.g. feedback)
|
|
1443
|
+
if (employeeData.employeeId) {
|
|
1444
|
+
LRS.employeeId = employeeData.employeeId;
|
|
1445
|
+
}
|
|
1438
1446
|
}
|
|
1439
1447
|
callback(actor);
|
|
1440
1448
|
});
|
|
@@ -4380,7 +4388,7 @@ function escapeJs(str) {
|
|
|
4380
4388
|
return str.replace(/\\/g, "\\\\").replace(/'/g, "\\'").replace(/"/g, '\\"').replace(/\n/g, "\\n").replace(/\r/g, "\\r");
|
|
4381
4389
|
}
|
|
4382
4390
|
function generateJsBeforeLoader(options) {
|
|
4383
|
-
const { remoteUrl, localPath, htmlClass, loadingClass, metadata, lrsBridge } = options;
|
|
4391
|
+
const { remoteUrl, localPath, htmlClass, loadingClass, metadata, lrsBridge, skin } = options;
|
|
4384
4392
|
const lrsBridgeCode = generateLrsBridgeCode(lrsBridge);
|
|
4385
4393
|
const courseLines = [];
|
|
4386
4394
|
if (metadata) {
|
|
@@ -4423,12 +4431,13 @@ ${courseLines.join("\n")}
|
|
|
4423
4431
|
window.pa_patcher = window.pa_patcher || {
|
|
4424
4432
|
version: '1.0.25',
|
|
4425
4433
|
htmlClass: '${htmlClass}',
|
|
4426
|
-
loadingClass: '${loadingClass}',${
|
|
4434
|
+
loadingClass: '${loadingClass}',${skin ? `
|
|
4435
|
+
skin: '${escapeJs(skin)}',` : ""}${courseBlock}
|
|
4427
4436
|
loaded: {
|
|
4428
4437
|
cssBefore: false,
|
|
4429
4438
|
cssAfter: false,
|
|
4430
4439
|
jsBefore: false,
|
|
4431
|
-
jsAfter: false
|
|
4440
|
+
jsAfter: false${skin ? ",\n skinCss: false,\n skinJs: false" : ""}
|
|
4432
4441
|
}
|
|
4433
4442
|
};
|
|
4434
4443
|
|
|
@@ -4549,7 +4558,8 @@ function buildJsBeforeOptions(config, metadata) {
|
|
|
4549
4558
|
htmlClass: config.htmlClass,
|
|
4550
4559
|
loadingClass: config.loadingClass,
|
|
4551
4560
|
metadata: metadata ?? null,
|
|
4552
|
-
lrsBridge
|
|
4561
|
+
lrsBridge,
|
|
4562
|
+
skin: config.skin
|
|
4553
4563
|
};
|
|
4554
4564
|
}
|
|
4555
4565
|
|
|
@@ -4672,6 +4682,196 @@ function buildJsAfterOptions(config) {
|
|
|
4672
4682
|
};
|
|
4673
4683
|
}
|
|
4674
4684
|
|
|
4685
|
+
// src/templates/skin-css.ts
|
|
4686
|
+
function generateSkinCssLoader(options) {
|
|
4687
|
+
const { remoteUrl, localPath, timeout } = options;
|
|
4688
|
+
return `<!-- === PATCH-ADAMS: SKIN CSS (async with fallback) === -->
|
|
4689
|
+
<script data-pa="skin-css-loader">
|
|
4690
|
+
(function() {
|
|
4691
|
+
'use strict';
|
|
4692
|
+
var REMOTE_URL = "${remoteUrl}";
|
|
4693
|
+
var LOCAL_PATH = "${localPath}";
|
|
4694
|
+
var TIMEOUT = ${timeout};
|
|
4695
|
+
|
|
4696
|
+
function loadCSS(url, onSuccess, onError) {
|
|
4697
|
+
var link = document.createElement('link');
|
|
4698
|
+
link.rel = 'stylesheet';
|
|
4699
|
+
link.href = url;
|
|
4700
|
+
link.setAttribute('data-pa', 'skin-css');
|
|
4701
|
+
|
|
4702
|
+
link.onload = function() {
|
|
4703
|
+
if (onSuccess) onSuccess();
|
|
4704
|
+
};
|
|
4705
|
+
|
|
4706
|
+
link.onerror = function() {
|
|
4707
|
+
if (onError) onError();
|
|
4708
|
+
};
|
|
4709
|
+
|
|
4710
|
+
document.head.appendChild(link);
|
|
4711
|
+
return link;
|
|
4712
|
+
}
|
|
4713
|
+
|
|
4714
|
+
function loadCSSWithFallback() {
|
|
4715
|
+
var loaded = false;
|
|
4716
|
+
var timeoutId;
|
|
4717
|
+
|
|
4718
|
+
// Try remote first
|
|
4719
|
+
var remoteLink = loadCSS(
|
|
4720
|
+
REMOTE_URL,
|
|
4721
|
+
function() {
|
|
4722
|
+
if (loaded) return;
|
|
4723
|
+
loaded = true;
|
|
4724
|
+
clearTimeout(timeoutId);
|
|
4725
|
+
console.log('[PA-Patcher] Skin CSS loaded from remote:', REMOTE_URL);
|
|
4726
|
+
},
|
|
4727
|
+
function() {
|
|
4728
|
+
if (loaded) return;
|
|
4729
|
+
loaded = true;
|
|
4730
|
+
clearTimeout(timeoutId);
|
|
4731
|
+
loadLocalFallback();
|
|
4732
|
+
}
|
|
4733
|
+
);
|
|
4734
|
+
|
|
4735
|
+
// Timeout fallback
|
|
4736
|
+
timeoutId = setTimeout(function() {
|
|
4737
|
+
if (loaded) return;
|
|
4738
|
+
loaded = true;
|
|
4739
|
+
console.warn('[PA-Patcher] Skin CSS timed out, using local fallback');
|
|
4740
|
+
if (remoteLink.parentNode) {
|
|
4741
|
+
document.head.removeChild(remoteLink);
|
|
4742
|
+
}
|
|
4743
|
+
loadLocalFallback();
|
|
4744
|
+
}, TIMEOUT);
|
|
4745
|
+
}
|
|
4746
|
+
|
|
4747
|
+
function loadLocalFallback() {
|
|
4748
|
+
loadCSS(
|
|
4749
|
+
LOCAL_PATH,
|
|
4750
|
+
function() {
|
|
4751
|
+
console.log('[PA-Patcher] Skin CSS loaded from local fallback:', LOCAL_PATH);
|
|
4752
|
+
},
|
|
4753
|
+
function() {
|
|
4754
|
+
console.error('[PA-Patcher] Skin CSS failed to load from both remote and local');
|
|
4755
|
+
}
|
|
4756
|
+
);
|
|
4757
|
+
}
|
|
4758
|
+
|
|
4759
|
+
// Execute immediately
|
|
4760
|
+
loadCSSWithFallback();
|
|
4761
|
+
})();
|
|
4762
|
+
</script>`;
|
|
4763
|
+
}
|
|
4764
|
+
function buildSkinCssOptions(config) {
|
|
4765
|
+
if (!config.skin) return null;
|
|
4766
|
+
return {
|
|
4767
|
+
remoteUrl: `${config.remoteDomain}/skin/${config.skin}.css`,
|
|
4768
|
+
localPath: `skin/${config.skin}.css`,
|
|
4769
|
+
timeout: config.cssAfter.timeout
|
|
4770
|
+
// reuse cssAfter timeout
|
|
4771
|
+
};
|
|
4772
|
+
}
|
|
4773
|
+
|
|
4774
|
+
// src/templates/skin-js.ts
|
|
4775
|
+
function generateSkinJsLoader(options) {
|
|
4776
|
+
const { remoteUrl, localPath, timeout } = options;
|
|
4777
|
+
return `<!-- === PATCH-ADAMS: SKIN JS (async with fallback) === -->
|
|
4778
|
+
<script data-pa="skin-js-loader">
|
|
4779
|
+
(function() {
|
|
4780
|
+
'use strict';
|
|
4781
|
+
var REMOTE_URL = "${remoteUrl}";
|
|
4782
|
+
var LOCAL_PATH = "${localPath}";
|
|
4783
|
+
var TIMEOUT = ${timeout};
|
|
4784
|
+
|
|
4785
|
+
function loadJS(url, onSuccess, onError) {
|
|
4786
|
+
var script = document.createElement('script');
|
|
4787
|
+
script.src = url;
|
|
4788
|
+
script.async = true;
|
|
4789
|
+
script.setAttribute('data-pa', 'skin-js');
|
|
4790
|
+
|
|
4791
|
+
script.onload = function() {
|
|
4792
|
+
if (onSuccess) onSuccess();
|
|
4793
|
+
};
|
|
4794
|
+
|
|
4795
|
+
script.onerror = function() {
|
|
4796
|
+
if (onError) onError();
|
|
4797
|
+
};
|
|
4798
|
+
|
|
4799
|
+
document.body.appendChild(script);
|
|
4800
|
+
return script;
|
|
4801
|
+
}
|
|
4802
|
+
|
|
4803
|
+
function loadJSWithFallback() {
|
|
4804
|
+
var loaded = false;
|
|
4805
|
+
var timeoutId;
|
|
4806
|
+
|
|
4807
|
+
// Try remote first
|
|
4808
|
+
var remoteScript = loadJS(
|
|
4809
|
+
REMOTE_URL,
|
|
4810
|
+
function() {
|
|
4811
|
+
if (loaded) return;
|
|
4812
|
+
loaded = true;
|
|
4813
|
+
clearTimeout(timeoutId);
|
|
4814
|
+
console.log('[PA-Patcher] Skin JS loaded from remote:', REMOTE_URL);
|
|
4815
|
+
if (window.pa_patcher && window.pa_patcher.loaded) {
|
|
4816
|
+
window.pa_patcher.loaded.skinJs = true;
|
|
4817
|
+
}
|
|
4818
|
+
},
|
|
4819
|
+
function() {
|
|
4820
|
+
if (loaded) return;
|
|
4821
|
+
loaded = true;
|
|
4822
|
+
clearTimeout(timeoutId);
|
|
4823
|
+
loadLocalFallback();
|
|
4824
|
+
}
|
|
4825
|
+
);
|
|
4826
|
+
|
|
4827
|
+
// Timeout fallback
|
|
4828
|
+
timeoutId = setTimeout(function() {
|
|
4829
|
+
if (loaded) return;
|
|
4830
|
+
loaded = true;
|
|
4831
|
+
console.warn('[PA-Patcher] Skin JS timed out, using local fallback');
|
|
4832
|
+
if (remoteScript.parentNode) {
|
|
4833
|
+
document.body.removeChild(remoteScript);
|
|
4834
|
+
}
|
|
4835
|
+
loadLocalFallback();
|
|
4836
|
+
}, TIMEOUT);
|
|
4837
|
+
}
|
|
4838
|
+
|
|
4839
|
+
function loadLocalFallback() {
|
|
4840
|
+
loadJS(
|
|
4841
|
+
LOCAL_PATH,
|
|
4842
|
+
function() {
|
|
4843
|
+
console.log('[PA-Patcher] Skin JS loaded from local fallback:', LOCAL_PATH);
|
|
4844
|
+
if (window.pa_patcher && window.pa_patcher.loaded) {
|
|
4845
|
+
window.pa_patcher.loaded.skinJs = true;
|
|
4846
|
+
}
|
|
4847
|
+
},
|
|
4848
|
+
function() {
|
|
4849
|
+
console.error('[PA-Patcher] Skin JS failed to load from both remote and local');
|
|
4850
|
+
}
|
|
4851
|
+
);
|
|
4852
|
+
}
|
|
4853
|
+
|
|
4854
|
+
// Execute after DOM is ready
|
|
4855
|
+
if (document.readyState === 'loading') {
|
|
4856
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
4857
|
+
setTimeout(loadJSWithFallback, 150);
|
|
4858
|
+
});
|
|
4859
|
+
} else {
|
|
4860
|
+
setTimeout(loadJSWithFallback, 150);
|
|
4861
|
+
}
|
|
4862
|
+
})();
|
|
4863
|
+
</script>`;
|
|
4864
|
+
}
|
|
4865
|
+
function buildSkinJsOptions(config) {
|
|
4866
|
+
if (!config.skin) return null;
|
|
4867
|
+
return {
|
|
4868
|
+
remoteUrl: `${config.remoteDomain}/skin/${config.skin}.js`,
|
|
4869
|
+
localPath: `skin/${config.skin}.js`,
|
|
4870
|
+
timeout: config.jsAfter.timeout
|
|
4871
|
+
// reuse jsAfter timeout
|
|
4872
|
+
};
|
|
4873
|
+
}
|
|
4874
|
+
|
|
4675
4875
|
// src/patcher/html-injector.ts
|
|
4676
4876
|
var HtmlInjector = class {
|
|
4677
4877
|
config;
|
|
@@ -4735,6 +4935,10 @@ var HtmlInjector = class {
|
|
|
4735
4935
|
if (this.config.jsAfter.enabled) {
|
|
4736
4936
|
result = this.injectJsAfter(result);
|
|
4737
4937
|
}
|
|
4938
|
+
if (this.config.skin) {
|
|
4939
|
+
result = this.injectSkinCss(result);
|
|
4940
|
+
result = this.injectSkinJs(result);
|
|
4941
|
+
}
|
|
4738
4942
|
if (this.pluginAssets) {
|
|
4739
4943
|
result = this.injectPluginAssets(result);
|
|
4740
4944
|
}
|
|
@@ -4781,8 +4985,8 @@ ${pluginJs}
|
|
|
4781
4985
|
* Also adds data attributes for course metadata
|
|
4782
4986
|
*/
|
|
4783
4987
|
addHtmlAttributes(html) {
|
|
4784
|
-
const { htmlClass, loadingClass } = this.config;
|
|
4785
|
-
const classes = `${htmlClass} ${loadingClass}`;
|
|
4988
|
+
const { htmlClass, loadingClass, skin } = this.config;
|
|
4989
|
+
const classes = `${htmlClass} ${loadingClass}${skin ? ` pa-skinned ${skin}` : ""}`;
|
|
4786
4990
|
const dataAttrs = [];
|
|
4787
4991
|
if (this.metadata) {
|
|
4788
4992
|
dataAttrs.push(`data-pa-course-id="${this.escapeAttr(this.metadata.courseId)}"`);
|
|
@@ -4791,6 +4995,9 @@ ${pluginJs}
|
|
|
4791
4995
|
dataAttrs.push(`data-pa-title="${this.escapeAttr(this.metadata.title)}"`);
|
|
4792
4996
|
}
|
|
4793
4997
|
}
|
|
4998
|
+
if (skin) {
|
|
4999
|
+
dataAttrs.push(`data-pa-skin="${this.escapeAttr(skin)}"`);
|
|
5000
|
+
}
|
|
4794
5001
|
const dataAttrString = dataAttrs.length > 0 ? " " + dataAttrs.join(" ") : "";
|
|
4795
5002
|
const htmlTagPattern = /<html([^>]*)>/i;
|
|
4796
5003
|
const match = html.match(htmlTagPattern);
|
|
@@ -4869,6 +5076,26 @@ ${loader}`);
|
|
|
4869
5076
|
${loader}`);
|
|
4870
5077
|
}
|
|
4871
5078
|
return html.replace(/<\/body>/i, `${loader}
|
|
5079
|
+
</body>`);
|
|
5080
|
+
}
|
|
5081
|
+
/**
|
|
5082
|
+
* Inject Skin CSS loader after CSS After (before </head>)
|
|
5083
|
+
*/
|
|
5084
|
+
injectSkinCss(html) {
|
|
5085
|
+
const options = buildSkinCssOptions(this.config);
|
|
5086
|
+
if (!options) return html;
|
|
5087
|
+
const loader = generateSkinCssLoader(options);
|
|
5088
|
+
return html.replace(/<\/head>/i, `${loader}
|
|
5089
|
+
</head>`);
|
|
5090
|
+
}
|
|
5091
|
+
/**
|
|
5092
|
+
* Inject Skin JS loader after JS After (before </body>)
|
|
5093
|
+
*/
|
|
5094
|
+
injectSkinJs(html) {
|
|
5095
|
+
const options = buildSkinJsOptions(this.config);
|
|
5096
|
+
if (!options) return html;
|
|
5097
|
+
const loader = generateSkinJsLoader(options);
|
|
5098
|
+
return html.replace(/<\/body>/i, `${loader}
|
|
4872
5099
|
</body>`);
|
|
4873
5100
|
}
|
|
4874
5101
|
};
|
|
@@ -4912,6 +5139,10 @@ var StorylineHtmlInjector = class {
|
|
|
4912
5139
|
if (this.config.jsAfter.enabled) {
|
|
4913
5140
|
result = this.injectJsAfter(result);
|
|
4914
5141
|
}
|
|
5142
|
+
if (this.config.skin) {
|
|
5143
|
+
result = this.injectSkinCss(result);
|
|
5144
|
+
result = this.injectSkinJs(result);
|
|
5145
|
+
}
|
|
4915
5146
|
if (this.pluginAssets) {
|
|
4916
5147
|
result = this.injectPluginAssets(result);
|
|
4917
5148
|
}
|
|
@@ -4956,8 +5187,8 @@ ${pluginJs}
|
|
|
4956
5187
|
* Also adds data attributes for course metadata
|
|
4957
5188
|
*/
|
|
4958
5189
|
addHtmlAttributes(html) {
|
|
4959
|
-
const { htmlClass, loadingClass } = this.config;
|
|
4960
|
-
const classes = `${htmlClass} ${loadingClass}`;
|
|
5190
|
+
const { htmlClass, loadingClass, skin } = this.config;
|
|
5191
|
+
const classes = `${htmlClass} ${loadingClass}${skin ? ` pa-skinned ${skin}` : ""}`;
|
|
4961
5192
|
const dataAttrs = [];
|
|
4962
5193
|
if (this.metadata) {
|
|
4963
5194
|
dataAttrs.push(`data-pa-course-id="${this.escapeAttr(this.metadata.courseId)}"`);
|
|
@@ -4967,6 +5198,9 @@ ${pluginJs}
|
|
|
4967
5198
|
dataAttrs.push(`data-pa-title="${this.escapeAttr(this.metadata.title)}"`);
|
|
4968
5199
|
}
|
|
4969
5200
|
}
|
|
5201
|
+
if (skin) {
|
|
5202
|
+
dataAttrs.push(`data-pa-skin="${this.escapeAttr(skin)}"`);
|
|
5203
|
+
}
|
|
4970
5204
|
const dataAttrString = dataAttrs.length > 0 ? " " + dataAttrs.join(" ") : "";
|
|
4971
5205
|
const htmlTagPattern = /<html([^>]*)>/i;
|
|
4972
5206
|
const match = html.match(htmlTagPattern);
|
|
@@ -5044,6 +5278,26 @@ ${loader}`);
|
|
|
5044
5278
|
const options = buildJsAfterOptions(this.config);
|
|
5045
5279
|
const loader = generateJsAfterLoader(options);
|
|
5046
5280
|
return html.replace(/<\/body>/i, `${loader}
|
|
5281
|
+
</body>`);
|
|
5282
|
+
}
|
|
5283
|
+
/**
|
|
5284
|
+
* Inject Skin CSS loader after CSS After (before </head>)
|
|
5285
|
+
*/
|
|
5286
|
+
injectSkinCss(html) {
|
|
5287
|
+
const options = buildSkinCssOptions(this.config);
|
|
5288
|
+
if (!options) return html;
|
|
5289
|
+
const loader = generateSkinCssLoader(options);
|
|
5290
|
+
return html.replace(/<\/head>/i, `${loader}
|
|
5291
|
+
</head>`);
|
|
5292
|
+
}
|
|
5293
|
+
/**
|
|
5294
|
+
* Inject Skin JS loader after JS After (before </body>)
|
|
5295
|
+
*/
|
|
5296
|
+
injectSkinJs(html) {
|
|
5297
|
+
const options = buildSkinJsOptions(this.config);
|
|
5298
|
+
if (!options) return html;
|
|
5299
|
+
const loader = generateSkinJsLoader(options);
|
|
5300
|
+
return html.replace(/<\/body>/i, `${loader}
|
|
5047
5301
|
</body>`);
|
|
5048
5302
|
}
|
|
5049
5303
|
};
|
|
@@ -5094,7 +5348,9 @@ var ManifestUpdater = class {
|
|
|
5094
5348
|
paths.cssBefore,
|
|
5095
5349
|
paths.cssAfter,
|
|
5096
5350
|
paths.jsBefore,
|
|
5097
|
-
paths.jsAfter
|
|
5351
|
+
paths.jsAfter,
|
|
5352
|
+
paths.skinCss,
|
|
5353
|
+
paths.skinJs
|
|
5098
5354
|
].filter(Boolean);
|
|
5099
5355
|
if (filesToAdd.length === 0) {
|
|
5100
5356
|
return [];
|
|
@@ -5884,6 +6140,20 @@ var Patcher = class {
|
|
|
5884
6140
|
})
|
|
5885
6141
|
);
|
|
5886
6142
|
}
|
|
6143
|
+
if (this.config.skin) {
|
|
6144
|
+
const skinCssUrl = `${remoteDomain}/skin/${this.config.skin}.css`;
|
|
6145
|
+
fetchPromises.push(
|
|
6146
|
+
this.fetchFile(skinCssUrl).then((content) => {
|
|
6147
|
+
fetched.skinCss = content;
|
|
6148
|
+
})
|
|
6149
|
+
);
|
|
6150
|
+
const skinJsUrl = `${remoteDomain}/skin/${this.config.skin}.js`;
|
|
6151
|
+
fetchPromises.push(
|
|
6152
|
+
this.fetchFile(skinJsUrl).then((content) => {
|
|
6153
|
+
fetched.skinJs = content;
|
|
6154
|
+
})
|
|
6155
|
+
);
|
|
6156
|
+
}
|
|
5887
6157
|
await Promise.all(fetchPromises);
|
|
5888
6158
|
return fetched;
|
|
5889
6159
|
}
|
|
@@ -5967,6 +6237,16 @@ var Patcher = class {
|
|
|
5967
6237
|
console.log(`[Patcher] Wrote generated UUID to manifest identifier`);
|
|
5968
6238
|
}
|
|
5969
6239
|
}
|
|
6240
|
+
const effectiveSkin = options.skin || this.config.skin;
|
|
6241
|
+
if (options.skin && options.skin !== this.config.skin) {
|
|
6242
|
+
this.config.skin = options.skin;
|
|
6243
|
+
this.riseHtmlInjector = new HtmlInjector(this.config);
|
|
6244
|
+
this.storylineHtmlInjector = new StorylineHtmlInjector(this.config);
|
|
6245
|
+
console.log(`[Patcher] Using per-call skin override: ${options.skin}`);
|
|
6246
|
+
}
|
|
6247
|
+
if (effectiveSkin) {
|
|
6248
|
+
console.log(`[Patcher] Skin: ${effectiveSkin}`);
|
|
6249
|
+
}
|
|
5970
6250
|
const htmlInjector = this.getHtmlInjector(toolInfo.tool);
|
|
5971
6251
|
htmlInjector.setMetadata(metadata);
|
|
5972
6252
|
let fetchedFallbacks = {};
|
|
@@ -6095,7 +6375,11 @@ var Patcher = class {
|
|
|
6095
6375
|
buildManifestPaths(addedFiles) {
|
|
6096
6376
|
const paths = {};
|
|
6097
6377
|
for (const filePath of addedFiles) {
|
|
6098
|
-
if (filePath.endsWith(this.config.
|
|
6378
|
+
if (this.config.skin && filePath.endsWith(`skin/${this.config.skin}.css`)) {
|
|
6379
|
+
paths.skinCss = filePath;
|
|
6380
|
+
} else if (this.config.skin && filePath.endsWith(`skin/${this.config.skin}.js`)) {
|
|
6381
|
+
paths.skinJs = filePath;
|
|
6382
|
+
} else if (filePath.endsWith(this.config.cssBefore.filename)) {
|
|
6099
6383
|
paths.cssBefore = filePath;
|
|
6100
6384
|
} else if (filePath.endsWith(this.config.cssAfter.filename)) {
|
|
6101
6385
|
paths.cssAfter = filePath;
|
|
@@ -6179,6 +6463,22 @@ var Patcher = class {
|
|
|
6179
6463
|
added.push(path);
|
|
6180
6464
|
if (fetched.jsAfter) console.log(`[Patcher] Using fetched content for ${path}`);
|
|
6181
6465
|
}
|
|
6466
|
+
if (this.config.skin) {
|
|
6467
|
+
const skinCssPath = `${basePath}skin/${this.config.skin}.css`;
|
|
6468
|
+
const skinCssContent = fetched.skinCss ?? `/* PA-Patcher: Skin CSS (${this.config.skin}) */
|
|
6469
|
+
`;
|
|
6470
|
+
zip.addFile(skinCssPath, Buffer.from(skinCssContent, "utf-8"));
|
|
6471
|
+
added.push(skinCssPath);
|
|
6472
|
+
if (fetched.skinCss) console.log(`[Patcher] Using fetched skin CSS for ${skinCssPath}`);
|
|
6473
|
+
else console.log(`[Patcher] Added placeholder skin CSS: ${skinCssPath}`);
|
|
6474
|
+
const skinJsPath = `${basePath}skin/${this.config.skin}.js`;
|
|
6475
|
+
const skinJsContent = fetched.skinJs ?? `// PA-Patcher: Skin JS (${this.config.skin})
|
|
6476
|
+
`;
|
|
6477
|
+
zip.addFile(skinJsPath, Buffer.from(skinJsContent, "utf-8"));
|
|
6478
|
+
added.push(skinJsPath);
|
|
6479
|
+
if (fetched.skinJs) console.log(`[Patcher] Using fetched skin JS for ${skinJsPath}`);
|
|
6480
|
+
else console.log(`[Patcher] Added placeholder skin JS: ${skinJsPath}`);
|
|
6481
|
+
}
|
|
6182
6482
|
return added;
|
|
6183
6483
|
}
|
|
6184
6484
|
/**
|
|
@@ -6193,9 +6493,9 @@ var Patcher = class {
|
|
|
6193
6493
|
* @param buffer - Input ZIP file as Buffer
|
|
6194
6494
|
* @returns Patched ZIP file as Buffer
|
|
6195
6495
|
*/
|
|
6196
|
-
async patchBuffer(buffer) {
|
|
6496
|
+
async patchBuffer(buffer, options) {
|
|
6197
6497
|
console.log(`[Patcher] patchBuffer called with ${buffer.length} bytes`);
|
|
6198
|
-
const { buffer: patchedBuffer, result } = await this.patch(buffer);
|
|
6498
|
+
const { buffer: patchedBuffer, result } = await this.patch(buffer, options);
|
|
6199
6499
|
console.log(`[Patcher] Patch result:`, JSON.stringify(result, null, 2));
|
|
6200
6500
|
console.log(`[Patcher] Returning ${patchedBuffer.length} bytes`);
|
|
6201
6501
|
return patchedBuffer;
|