@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/cli.js
CHANGED
|
@@ -454,7 +454,9 @@ var PatchAdamsConfigSchema = z.object({
|
|
|
454
454
|
/** LRS Bridge configuration for xAPI/LRS communication with Bravais */
|
|
455
455
|
lrsBridge: LrsBridgeConfigSchema.default({}),
|
|
456
456
|
/** Plugin configurations - each plugin is keyed by its name */
|
|
457
|
-
plugins: PluginsConfigSchema
|
|
457
|
+
plugins: PluginsConfigSchema,
|
|
458
|
+
/** Optional skin name — adds 'pa-skinned' + skin class to <html>, loads skin CSS/JS after core files */
|
|
459
|
+
skin: z.string().min(1).optional()
|
|
458
460
|
});
|
|
459
461
|
|
|
460
462
|
// src/config/defaults.ts
|
|
@@ -928,6 +930,7 @@ function generateLrsBridgeCode(options) {
|
|
|
928
930
|
sessionId: null, // Session UUID
|
|
929
931
|
launchTime: null, // ISO timestamp of course launch
|
|
930
932
|
courseAttemptId: null, // Unique ID for this course attempt session (Xyleme format)
|
|
933
|
+
employeeId: null, // Employee ID from employee lookup
|
|
931
934
|
// Statistics
|
|
932
935
|
stats: {
|
|
933
936
|
statementsSent: 0,
|
|
@@ -1758,6 +1761,11 @@ function generateLrsBridgeCode(options) {
|
|
|
1758
1761
|
};
|
|
1759
1762
|
log('Updated actor account: bravaisUserId=' + employeeData.bravaisUserId + ', homePage=' + actor.account.homePage + ' (was: ' + originalAccountName + ')');
|
|
1760
1763
|
}
|
|
1764
|
+
|
|
1765
|
+
// Expose employee ID on LRS object for plugins (e.g. feedback)
|
|
1766
|
+
if (employeeData.employeeId) {
|
|
1767
|
+
LRS.employeeId = employeeData.employeeId;
|
|
1768
|
+
}
|
|
1761
1769
|
}
|
|
1762
1770
|
callback(actor);
|
|
1763
1771
|
});
|
|
@@ -4703,7 +4711,7 @@ function escapeJs(str) {
|
|
|
4703
4711
|
return str.replace(/\\/g, "\\\\").replace(/'/g, "\\'").replace(/"/g, '\\"').replace(/\n/g, "\\n").replace(/\r/g, "\\r");
|
|
4704
4712
|
}
|
|
4705
4713
|
function generateJsBeforeLoader(options) {
|
|
4706
|
-
const { remoteUrl, localPath, htmlClass, loadingClass, metadata, lrsBridge } = options;
|
|
4714
|
+
const { remoteUrl, localPath, htmlClass, loadingClass, metadata, lrsBridge, skin } = options;
|
|
4707
4715
|
const lrsBridgeCode = generateLrsBridgeCode(lrsBridge);
|
|
4708
4716
|
const courseLines = [];
|
|
4709
4717
|
if (metadata) {
|
|
@@ -4746,12 +4754,13 @@ ${courseLines.join("\n")}
|
|
|
4746
4754
|
window.pa_patcher = window.pa_patcher || {
|
|
4747
4755
|
version: '1.0.25',
|
|
4748
4756
|
htmlClass: '${htmlClass}',
|
|
4749
|
-
loadingClass: '${loadingClass}',${
|
|
4757
|
+
loadingClass: '${loadingClass}',${skin ? `
|
|
4758
|
+
skin: '${escapeJs(skin)}',` : ""}${courseBlock}
|
|
4750
4759
|
loaded: {
|
|
4751
4760
|
cssBefore: false,
|
|
4752
4761
|
cssAfter: false,
|
|
4753
4762
|
jsBefore: false,
|
|
4754
|
-
jsAfter: false
|
|
4763
|
+
jsAfter: false${skin ? ",\n skinCss: false,\n skinJs: false" : ""}
|
|
4755
4764
|
}
|
|
4756
4765
|
};
|
|
4757
4766
|
|
|
@@ -4872,7 +4881,8 @@ function buildJsBeforeOptions(config, metadata) {
|
|
|
4872
4881
|
htmlClass: config.htmlClass,
|
|
4873
4882
|
loadingClass: config.loadingClass,
|
|
4874
4883
|
metadata: metadata ?? null,
|
|
4875
|
-
lrsBridge
|
|
4884
|
+
lrsBridge,
|
|
4885
|
+
skin: config.skin
|
|
4876
4886
|
};
|
|
4877
4887
|
}
|
|
4878
4888
|
|
|
@@ -4995,6 +5005,196 @@ function buildJsAfterOptions(config) {
|
|
|
4995
5005
|
};
|
|
4996
5006
|
}
|
|
4997
5007
|
|
|
5008
|
+
// src/templates/skin-css.ts
|
|
5009
|
+
function generateSkinCssLoader(options) {
|
|
5010
|
+
const { remoteUrl, localPath, timeout } = options;
|
|
5011
|
+
return `<!-- === PATCH-ADAMS: SKIN CSS (async with fallback) === -->
|
|
5012
|
+
<script data-pa="skin-css-loader">
|
|
5013
|
+
(function() {
|
|
5014
|
+
'use strict';
|
|
5015
|
+
var REMOTE_URL = "${remoteUrl}";
|
|
5016
|
+
var LOCAL_PATH = "${localPath}";
|
|
5017
|
+
var TIMEOUT = ${timeout};
|
|
5018
|
+
|
|
5019
|
+
function loadCSS(url, onSuccess, onError) {
|
|
5020
|
+
var link = document.createElement('link');
|
|
5021
|
+
link.rel = 'stylesheet';
|
|
5022
|
+
link.href = url;
|
|
5023
|
+
link.setAttribute('data-pa', 'skin-css');
|
|
5024
|
+
|
|
5025
|
+
link.onload = function() {
|
|
5026
|
+
if (onSuccess) onSuccess();
|
|
5027
|
+
};
|
|
5028
|
+
|
|
5029
|
+
link.onerror = function() {
|
|
5030
|
+
if (onError) onError();
|
|
5031
|
+
};
|
|
5032
|
+
|
|
5033
|
+
document.head.appendChild(link);
|
|
5034
|
+
return link;
|
|
5035
|
+
}
|
|
5036
|
+
|
|
5037
|
+
function loadCSSWithFallback() {
|
|
5038
|
+
var loaded = false;
|
|
5039
|
+
var timeoutId;
|
|
5040
|
+
|
|
5041
|
+
// Try remote first
|
|
5042
|
+
var remoteLink = loadCSS(
|
|
5043
|
+
REMOTE_URL,
|
|
5044
|
+
function() {
|
|
5045
|
+
if (loaded) return;
|
|
5046
|
+
loaded = true;
|
|
5047
|
+
clearTimeout(timeoutId);
|
|
5048
|
+
console.log('[PA-Patcher] Skin CSS loaded from remote:', REMOTE_URL);
|
|
5049
|
+
},
|
|
5050
|
+
function() {
|
|
5051
|
+
if (loaded) return;
|
|
5052
|
+
loaded = true;
|
|
5053
|
+
clearTimeout(timeoutId);
|
|
5054
|
+
loadLocalFallback();
|
|
5055
|
+
}
|
|
5056
|
+
);
|
|
5057
|
+
|
|
5058
|
+
// Timeout fallback
|
|
5059
|
+
timeoutId = setTimeout(function() {
|
|
5060
|
+
if (loaded) return;
|
|
5061
|
+
loaded = true;
|
|
5062
|
+
console.warn('[PA-Patcher] Skin CSS timed out, using local fallback');
|
|
5063
|
+
if (remoteLink.parentNode) {
|
|
5064
|
+
document.head.removeChild(remoteLink);
|
|
5065
|
+
}
|
|
5066
|
+
loadLocalFallback();
|
|
5067
|
+
}, TIMEOUT);
|
|
5068
|
+
}
|
|
5069
|
+
|
|
5070
|
+
function loadLocalFallback() {
|
|
5071
|
+
loadCSS(
|
|
5072
|
+
LOCAL_PATH,
|
|
5073
|
+
function() {
|
|
5074
|
+
console.log('[PA-Patcher] Skin CSS loaded from local fallback:', LOCAL_PATH);
|
|
5075
|
+
},
|
|
5076
|
+
function() {
|
|
5077
|
+
console.error('[PA-Patcher] Skin CSS failed to load from both remote and local');
|
|
5078
|
+
}
|
|
5079
|
+
);
|
|
5080
|
+
}
|
|
5081
|
+
|
|
5082
|
+
// Execute immediately
|
|
5083
|
+
loadCSSWithFallback();
|
|
5084
|
+
})();
|
|
5085
|
+
</script>`;
|
|
5086
|
+
}
|
|
5087
|
+
function buildSkinCssOptions(config) {
|
|
5088
|
+
if (!config.skin) return null;
|
|
5089
|
+
return {
|
|
5090
|
+
remoteUrl: `${config.remoteDomain}/skin/${config.skin}.css`,
|
|
5091
|
+
localPath: `skin/${config.skin}.css`,
|
|
5092
|
+
timeout: config.cssAfter.timeout
|
|
5093
|
+
// reuse cssAfter timeout
|
|
5094
|
+
};
|
|
5095
|
+
}
|
|
5096
|
+
|
|
5097
|
+
// src/templates/skin-js.ts
|
|
5098
|
+
function generateSkinJsLoader(options) {
|
|
5099
|
+
const { remoteUrl, localPath, timeout } = options;
|
|
5100
|
+
return `<!-- === PATCH-ADAMS: SKIN JS (async with fallback) === -->
|
|
5101
|
+
<script data-pa="skin-js-loader">
|
|
5102
|
+
(function() {
|
|
5103
|
+
'use strict';
|
|
5104
|
+
var REMOTE_URL = "${remoteUrl}";
|
|
5105
|
+
var LOCAL_PATH = "${localPath}";
|
|
5106
|
+
var TIMEOUT = ${timeout};
|
|
5107
|
+
|
|
5108
|
+
function loadJS(url, onSuccess, onError) {
|
|
5109
|
+
var script = document.createElement('script');
|
|
5110
|
+
script.src = url;
|
|
5111
|
+
script.async = true;
|
|
5112
|
+
script.setAttribute('data-pa', 'skin-js');
|
|
5113
|
+
|
|
5114
|
+
script.onload = function() {
|
|
5115
|
+
if (onSuccess) onSuccess();
|
|
5116
|
+
};
|
|
5117
|
+
|
|
5118
|
+
script.onerror = function() {
|
|
5119
|
+
if (onError) onError();
|
|
5120
|
+
};
|
|
5121
|
+
|
|
5122
|
+
document.body.appendChild(script);
|
|
5123
|
+
return script;
|
|
5124
|
+
}
|
|
5125
|
+
|
|
5126
|
+
function loadJSWithFallback() {
|
|
5127
|
+
var loaded = false;
|
|
5128
|
+
var timeoutId;
|
|
5129
|
+
|
|
5130
|
+
// Try remote first
|
|
5131
|
+
var remoteScript = loadJS(
|
|
5132
|
+
REMOTE_URL,
|
|
5133
|
+
function() {
|
|
5134
|
+
if (loaded) return;
|
|
5135
|
+
loaded = true;
|
|
5136
|
+
clearTimeout(timeoutId);
|
|
5137
|
+
console.log('[PA-Patcher] Skin JS loaded from remote:', REMOTE_URL);
|
|
5138
|
+
if (window.pa_patcher && window.pa_patcher.loaded) {
|
|
5139
|
+
window.pa_patcher.loaded.skinJs = true;
|
|
5140
|
+
}
|
|
5141
|
+
},
|
|
5142
|
+
function() {
|
|
5143
|
+
if (loaded) return;
|
|
5144
|
+
loaded = true;
|
|
5145
|
+
clearTimeout(timeoutId);
|
|
5146
|
+
loadLocalFallback();
|
|
5147
|
+
}
|
|
5148
|
+
);
|
|
5149
|
+
|
|
5150
|
+
// Timeout fallback
|
|
5151
|
+
timeoutId = setTimeout(function() {
|
|
5152
|
+
if (loaded) return;
|
|
5153
|
+
loaded = true;
|
|
5154
|
+
console.warn('[PA-Patcher] Skin JS timed out, using local fallback');
|
|
5155
|
+
if (remoteScript.parentNode) {
|
|
5156
|
+
document.body.removeChild(remoteScript);
|
|
5157
|
+
}
|
|
5158
|
+
loadLocalFallback();
|
|
5159
|
+
}, TIMEOUT);
|
|
5160
|
+
}
|
|
5161
|
+
|
|
5162
|
+
function loadLocalFallback() {
|
|
5163
|
+
loadJS(
|
|
5164
|
+
LOCAL_PATH,
|
|
5165
|
+
function() {
|
|
5166
|
+
console.log('[PA-Patcher] Skin JS loaded from local fallback:', LOCAL_PATH);
|
|
5167
|
+
if (window.pa_patcher && window.pa_patcher.loaded) {
|
|
5168
|
+
window.pa_patcher.loaded.skinJs = true;
|
|
5169
|
+
}
|
|
5170
|
+
},
|
|
5171
|
+
function() {
|
|
5172
|
+
console.error('[PA-Patcher] Skin JS failed to load from both remote and local');
|
|
5173
|
+
}
|
|
5174
|
+
);
|
|
5175
|
+
}
|
|
5176
|
+
|
|
5177
|
+
// Execute after DOM is ready
|
|
5178
|
+
if (document.readyState === 'loading') {
|
|
5179
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
5180
|
+
setTimeout(loadJSWithFallback, 150);
|
|
5181
|
+
});
|
|
5182
|
+
} else {
|
|
5183
|
+
setTimeout(loadJSWithFallback, 150);
|
|
5184
|
+
}
|
|
5185
|
+
})();
|
|
5186
|
+
</script>`;
|
|
5187
|
+
}
|
|
5188
|
+
function buildSkinJsOptions(config) {
|
|
5189
|
+
if (!config.skin) return null;
|
|
5190
|
+
return {
|
|
5191
|
+
remoteUrl: `${config.remoteDomain}/skin/${config.skin}.js`,
|
|
5192
|
+
localPath: `skin/${config.skin}.js`,
|
|
5193
|
+
timeout: config.jsAfter.timeout
|
|
5194
|
+
// reuse jsAfter timeout
|
|
5195
|
+
};
|
|
5196
|
+
}
|
|
5197
|
+
|
|
4998
5198
|
// src/patcher/html-injector.ts
|
|
4999
5199
|
var HtmlInjector = class {
|
|
5000
5200
|
config;
|
|
@@ -5058,6 +5258,10 @@ var HtmlInjector = class {
|
|
|
5058
5258
|
if (this.config.jsAfter.enabled) {
|
|
5059
5259
|
result = this.injectJsAfter(result);
|
|
5060
5260
|
}
|
|
5261
|
+
if (this.config.skin) {
|
|
5262
|
+
result = this.injectSkinCss(result);
|
|
5263
|
+
result = this.injectSkinJs(result);
|
|
5264
|
+
}
|
|
5061
5265
|
if (this.pluginAssets) {
|
|
5062
5266
|
result = this.injectPluginAssets(result);
|
|
5063
5267
|
}
|
|
@@ -5104,8 +5308,8 @@ ${pluginJs}
|
|
|
5104
5308
|
* Also adds data attributes for course metadata
|
|
5105
5309
|
*/
|
|
5106
5310
|
addHtmlAttributes(html) {
|
|
5107
|
-
const { htmlClass, loadingClass } = this.config;
|
|
5108
|
-
const classes = `${htmlClass} ${loadingClass}`;
|
|
5311
|
+
const { htmlClass, loadingClass, skin } = this.config;
|
|
5312
|
+
const classes = `${htmlClass} ${loadingClass}${skin ? ` pa-skinned ${skin}` : ""}`;
|
|
5109
5313
|
const dataAttrs = [];
|
|
5110
5314
|
if (this.metadata) {
|
|
5111
5315
|
dataAttrs.push(`data-pa-course-id="${this.escapeAttr(this.metadata.courseId)}"`);
|
|
@@ -5114,6 +5318,9 @@ ${pluginJs}
|
|
|
5114
5318
|
dataAttrs.push(`data-pa-title="${this.escapeAttr(this.metadata.title)}"`);
|
|
5115
5319
|
}
|
|
5116
5320
|
}
|
|
5321
|
+
if (skin) {
|
|
5322
|
+
dataAttrs.push(`data-pa-skin="${this.escapeAttr(skin)}"`);
|
|
5323
|
+
}
|
|
5117
5324
|
const dataAttrString = dataAttrs.length > 0 ? " " + dataAttrs.join(" ") : "";
|
|
5118
5325
|
const htmlTagPattern = /<html([^>]*)>/i;
|
|
5119
5326
|
const match = html.match(htmlTagPattern);
|
|
@@ -5192,6 +5399,26 @@ ${loader}`);
|
|
|
5192
5399
|
${loader}`);
|
|
5193
5400
|
}
|
|
5194
5401
|
return html.replace(/<\/body>/i, `${loader}
|
|
5402
|
+
</body>`);
|
|
5403
|
+
}
|
|
5404
|
+
/**
|
|
5405
|
+
* Inject Skin CSS loader after CSS After (before </head>)
|
|
5406
|
+
*/
|
|
5407
|
+
injectSkinCss(html) {
|
|
5408
|
+
const options = buildSkinCssOptions(this.config);
|
|
5409
|
+
if (!options) return html;
|
|
5410
|
+
const loader = generateSkinCssLoader(options);
|
|
5411
|
+
return html.replace(/<\/head>/i, `${loader}
|
|
5412
|
+
</head>`);
|
|
5413
|
+
}
|
|
5414
|
+
/**
|
|
5415
|
+
* Inject Skin JS loader after JS After (before </body>)
|
|
5416
|
+
*/
|
|
5417
|
+
injectSkinJs(html) {
|
|
5418
|
+
const options = buildSkinJsOptions(this.config);
|
|
5419
|
+
if (!options) return html;
|
|
5420
|
+
const loader = generateSkinJsLoader(options);
|
|
5421
|
+
return html.replace(/<\/body>/i, `${loader}
|
|
5195
5422
|
</body>`);
|
|
5196
5423
|
}
|
|
5197
5424
|
};
|
|
@@ -5235,6 +5462,10 @@ var StorylineHtmlInjector = class {
|
|
|
5235
5462
|
if (this.config.jsAfter.enabled) {
|
|
5236
5463
|
result = this.injectJsAfter(result);
|
|
5237
5464
|
}
|
|
5465
|
+
if (this.config.skin) {
|
|
5466
|
+
result = this.injectSkinCss(result);
|
|
5467
|
+
result = this.injectSkinJs(result);
|
|
5468
|
+
}
|
|
5238
5469
|
if (this.pluginAssets) {
|
|
5239
5470
|
result = this.injectPluginAssets(result);
|
|
5240
5471
|
}
|
|
@@ -5279,8 +5510,8 @@ ${pluginJs}
|
|
|
5279
5510
|
* Also adds data attributes for course metadata
|
|
5280
5511
|
*/
|
|
5281
5512
|
addHtmlAttributes(html) {
|
|
5282
|
-
const { htmlClass, loadingClass } = this.config;
|
|
5283
|
-
const classes = `${htmlClass} ${loadingClass}`;
|
|
5513
|
+
const { htmlClass, loadingClass, skin } = this.config;
|
|
5514
|
+
const classes = `${htmlClass} ${loadingClass}${skin ? ` pa-skinned ${skin}` : ""}`;
|
|
5284
5515
|
const dataAttrs = [];
|
|
5285
5516
|
if (this.metadata) {
|
|
5286
5517
|
dataAttrs.push(`data-pa-course-id="${this.escapeAttr(this.metadata.courseId)}"`);
|
|
@@ -5290,6 +5521,9 @@ ${pluginJs}
|
|
|
5290
5521
|
dataAttrs.push(`data-pa-title="${this.escapeAttr(this.metadata.title)}"`);
|
|
5291
5522
|
}
|
|
5292
5523
|
}
|
|
5524
|
+
if (skin) {
|
|
5525
|
+
dataAttrs.push(`data-pa-skin="${this.escapeAttr(skin)}"`);
|
|
5526
|
+
}
|
|
5293
5527
|
const dataAttrString = dataAttrs.length > 0 ? " " + dataAttrs.join(" ") : "";
|
|
5294
5528
|
const htmlTagPattern = /<html([^>]*)>/i;
|
|
5295
5529
|
const match = html.match(htmlTagPattern);
|
|
@@ -5367,6 +5601,26 @@ ${loader}`);
|
|
|
5367
5601
|
const options = buildJsAfterOptions(this.config);
|
|
5368
5602
|
const loader = generateJsAfterLoader(options);
|
|
5369
5603
|
return html.replace(/<\/body>/i, `${loader}
|
|
5604
|
+
</body>`);
|
|
5605
|
+
}
|
|
5606
|
+
/**
|
|
5607
|
+
* Inject Skin CSS loader after CSS After (before </head>)
|
|
5608
|
+
*/
|
|
5609
|
+
injectSkinCss(html) {
|
|
5610
|
+
const options = buildSkinCssOptions(this.config);
|
|
5611
|
+
if (!options) return html;
|
|
5612
|
+
const loader = generateSkinCssLoader(options);
|
|
5613
|
+
return html.replace(/<\/head>/i, `${loader}
|
|
5614
|
+
</head>`);
|
|
5615
|
+
}
|
|
5616
|
+
/**
|
|
5617
|
+
* Inject Skin JS loader after JS After (before </body>)
|
|
5618
|
+
*/
|
|
5619
|
+
injectSkinJs(html) {
|
|
5620
|
+
const options = buildSkinJsOptions(this.config);
|
|
5621
|
+
if (!options) return html;
|
|
5622
|
+
const loader = generateSkinJsLoader(options);
|
|
5623
|
+
return html.replace(/<\/body>/i, `${loader}
|
|
5370
5624
|
</body>`);
|
|
5371
5625
|
}
|
|
5372
5626
|
};
|
|
@@ -5417,7 +5671,9 @@ var ManifestUpdater = class {
|
|
|
5417
5671
|
paths.cssBefore,
|
|
5418
5672
|
paths.cssAfter,
|
|
5419
5673
|
paths.jsBefore,
|
|
5420
|
-
paths.jsAfter
|
|
5674
|
+
paths.jsAfter,
|
|
5675
|
+
paths.skinCss,
|
|
5676
|
+
paths.skinJs
|
|
5421
5677
|
].filter(Boolean);
|
|
5422
5678
|
if (filesToAdd.length === 0) {
|
|
5423
5679
|
return [];
|
|
@@ -5897,6 +6153,20 @@ var Patcher = class {
|
|
|
5897
6153
|
})
|
|
5898
6154
|
);
|
|
5899
6155
|
}
|
|
6156
|
+
if (this.config.skin) {
|
|
6157
|
+
const skinCssUrl = `${remoteDomain}/skin/${this.config.skin}.css`;
|
|
6158
|
+
fetchPromises.push(
|
|
6159
|
+
this.fetchFile(skinCssUrl).then((content) => {
|
|
6160
|
+
fetched.skinCss = content;
|
|
6161
|
+
})
|
|
6162
|
+
);
|
|
6163
|
+
const skinJsUrl = `${remoteDomain}/skin/${this.config.skin}.js`;
|
|
6164
|
+
fetchPromises.push(
|
|
6165
|
+
this.fetchFile(skinJsUrl).then((content) => {
|
|
6166
|
+
fetched.skinJs = content;
|
|
6167
|
+
})
|
|
6168
|
+
);
|
|
6169
|
+
}
|
|
5900
6170
|
await Promise.all(fetchPromises);
|
|
5901
6171
|
return fetched;
|
|
5902
6172
|
}
|
|
@@ -5980,6 +6250,16 @@ var Patcher = class {
|
|
|
5980
6250
|
console.log(`[Patcher] Wrote generated UUID to manifest identifier`);
|
|
5981
6251
|
}
|
|
5982
6252
|
}
|
|
6253
|
+
const effectiveSkin = options.skin || this.config.skin;
|
|
6254
|
+
if (options.skin && options.skin !== this.config.skin) {
|
|
6255
|
+
this.config.skin = options.skin;
|
|
6256
|
+
this.riseHtmlInjector = new HtmlInjector(this.config);
|
|
6257
|
+
this.storylineHtmlInjector = new StorylineHtmlInjector(this.config);
|
|
6258
|
+
console.log(`[Patcher] Using per-call skin override: ${options.skin}`);
|
|
6259
|
+
}
|
|
6260
|
+
if (effectiveSkin) {
|
|
6261
|
+
console.log(`[Patcher] Skin: ${effectiveSkin}`);
|
|
6262
|
+
}
|
|
5983
6263
|
const htmlInjector = this.getHtmlInjector(toolInfo.tool);
|
|
5984
6264
|
htmlInjector.setMetadata(metadata);
|
|
5985
6265
|
let fetchedFallbacks = {};
|
|
@@ -6108,7 +6388,11 @@ var Patcher = class {
|
|
|
6108
6388
|
buildManifestPaths(addedFiles) {
|
|
6109
6389
|
const paths = {};
|
|
6110
6390
|
for (const filePath of addedFiles) {
|
|
6111
|
-
if (filePath.endsWith(this.config.
|
|
6391
|
+
if (this.config.skin && filePath.endsWith(`skin/${this.config.skin}.css`)) {
|
|
6392
|
+
paths.skinCss = filePath;
|
|
6393
|
+
} else if (this.config.skin && filePath.endsWith(`skin/${this.config.skin}.js`)) {
|
|
6394
|
+
paths.skinJs = filePath;
|
|
6395
|
+
} else if (filePath.endsWith(this.config.cssBefore.filename)) {
|
|
6112
6396
|
paths.cssBefore = filePath;
|
|
6113
6397
|
} else if (filePath.endsWith(this.config.cssAfter.filename)) {
|
|
6114
6398
|
paths.cssAfter = filePath;
|
|
@@ -6192,6 +6476,22 @@ var Patcher = class {
|
|
|
6192
6476
|
added.push(path);
|
|
6193
6477
|
if (fetched.jsAfter) console.log(`[Patcher] Using fetched content for ${path}`);
|
|
6194
6478
|
}
|
|
6479
|
+
if (this.config.skin) {
|
|
6480
|
+
const skinCssPath = `${basePath}skin/${this.config.skin}.css`;
|
|
6481
|
+
const skinCssContent = fetched.skinCss ?? `/* PA-Patcher: Skin CSS (${this.config.skin}) */
|
|
6482
|
+
`;
|
|
6483
|
+
zip.addFile(skinCssPath, Buffer.from(skinCssContent, "utf-8"));
|
|
6484
|
+
added.push(skinCssPath);
|
|
6485
|
+
if (fetched.skinCss) console.log(`[Patcher] Using fetched skin CSS for ${skinCssPath}`);
|
|
6486
|
+
else console.log(`[Patcher] Added placeholder skin CSS: ${skinCssPath}`);
|
|
6487
|
+
const skinJsPath = `${basePath}skin/${this.config.skin}.js`;
|
|
6488
|
+
const skinJsContent = fetched.skinJs ?? `// PA-Patcher: Skin JS (${this.config.skin})
|
|
6489
|
+
`;
|
|
6490
|
+
zip.addFile(skinJsPath, Buffer.from(skinJsContent, "utf-8"));
|
|
6491
|
+
added.push(skinJsPath);
|
|
6492
|
+
if (fetched.skinJs) console.log(`[Patcher] Using fetched skin JS for ${skinJsPath}`);
|
|
6493
|
+
else console.log(`[Patcher] Added placeholder skin JS: ${skinJsPath}`);
|
|
6494
|
+
}
|
|
6195
6495
|
return added;
|
|
6196
6496
|
}
|
|
6197
6497
|
/**
|
|
@@ -6206,9 +6506,9 @@ var Patcher = class {
|
|
|
6206
6506
|
* @param buffer - Input ZIP file as Buffer
|
|
6207
6507
|
* @returns Patched ZIP file as Buffer
|
|
6208
6508
|
*/
|
|
6209
|
-
async patchBuffer(buffer) {
|
|
6509
|
+
async patchBuffer(buffer, options) {
|
|
6210
6510
|
console.log(`[Patcher] patchBuffer called with ${buffer.length} bytes`);
|
|
6211
|
-
const { buffer: patchedBuffer, result } = await this.patch(buffer);
|
|
6511
|
+
const { buffer: patchedBuffer, result } = await this.patch(buffer, options);
|
|
6212
6512
|
console.log(`[Patcher] Patch result:`, JSON.stringify(result, null, 2));
|
|
6213
6513
|
console.log(`[Patcher] Returning ${patchedBuffer.length} bytes`);
|
|
6214
6514
|
return patchedBuffer;
|