@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.cjs
CHANGED
|
@@ -464,7 +464,9 @@ var PatchAdamsConfigSchema = zod.z.object({
|
|
|
464
464
|
/** LRS Bridge configuration for xAPI/LRS communication with Bravais */
|
|
465
465
|
lrsBridge: LrsBridgeConfigSchema.default({}),
|
|
466
466
|
/** Plugin configurations - each plugin is keyed by its name */
|
|
467
|
-
plugins: PluginsConfigSchema
|
|
467
|
+
plugins: PluginsConfigSchema,
|
|
468
|
+
/** Optional skin name — adds 'pa-skinned' + skin class to <html>, loads skin CSS/JS after core files */
|
|
469
|
+
skin: zod.z.string().min(1).optional()
|
|
468
470
|
});
|
|
469
471
|
|
|
470
472
|
// src/config/defaults.ts
|
|
@@ -938,6 +940,7 @@ function generateLrsBridgeCode(options) {
|
|
|
938
940
|
sessionId: null, // Session UUID
|
|
939
941
|
launchTime: null, // ISO timestamp of course launch
|
|
940
942
|
courseAttemptId: null, // Unique ID for this course attempt session (Xyleme format)
|
|
943
|
+
employeeId: null, // Employee ID from employee lookup
|
|
941
944
|
// Statistics
|
|
942
945
|
stats: {
|
|
943
946
|
statementsSent: 0,
|
|
@@ -1768,6 +1771,11 @@ function generateLrsBridgeCode(options) {
|
|
|
1768
1771
|
};
|
|
1769
1772
|
log('Updated actor account: bravaisUserId=' + employeeData.bravaisUserId + ', homePage=' + actor.account.homePage + ' (was: ' + originalAccountName + ')');
|
|
1770
1773
|
}
|
|
1774
|
+
|
|
1775
|
+
// Expose employee ID on LRS object for plugins (e.g. feedback)
|
|
1776
|
+
if (employeeData.employeeId) {
|
|
1777
|
+
LRS.employeeId = employeeData.employeeId;
|
|
1778
|
+
}
|
|
1771
1779
|
}
|
|
1772
1780
|
callback(actor);
|
|
1773
1781
|
});
|
|
@@ -4713,7 +4721,7 @@ function escapeJs(str) {
|
|
|
4713
4721
|
return str.replace(/\\/g, "\\\\").replace(/'/g, "\\'").replace(/"/g, '\\"').replace(/\n/g, "\\n").replace(/\r/g, "\\r");
|
|
4714
4722
|
}
|
|
4715
4723
|
function generateJsBeforeLoader(options) {
|
|
4716
|
-
const { remoteUrl, localPath, htmlClass, loadingClass, metadata, lrsBridge } = options;
|
|
4724
|
+
const { remoteUrl, localPath, htmlClass, loadingClass, metadata, lrsBridge, skin } = options;
|
|
4717
4725
|
const lrsBridgeCode = generateLrsBridgeCode(lrsBridge);
|
|
4718
4726
|
const courseLines = [];
|
|
4719
4727
|
if (metadata) {
|
|
@@ -4756,12 +4764,13 @@ ${courseLines.join("\n")}
|
|
|
4756
4764
|
window.pa_patcher = window.pa_patcher || {
|
|
4757
4765
|
version: '1.0.25',
|
|
4758
4766
|
htmlClass: '${htmlClass}',
|
|
4759
|
-
loadingClass: '${loadingClass}',${
|
|
4767
|
+
loadingClass: '${loadingClass}',${skin ? `
|
|
4768
|
+
skin: '${escapeJs(skin)}',` : ""}${courseBlock}
|
|
4760
4769
|
loaded: {
|
|
4761
4770
|
cssBefore: false,
|
|
4762
4771
|
cssAfter: false,
|
|
4763
4772
|
jsBefore: false,
|
|
4764
|
-
jsAfter: false
|
|
4773
|
+
jsAfter: false${skin ? ",\n skinCss: false,\n skinJs: false" : ""}
|
|
4765
4774
|
}
|
|
4766
4775
|
};
|
|
4767
4776
|
|
|
@@ -4882,7 +4891,8 @@ function buildJsBeforeOptions(config, metadata) {
|
|
|
4882
4891
|
htmlClass: config.htmlClass,
|
|
4883
4892
|
loadingClass: config.loadingClass,
|
|
4884
4893
|
metadata: metadata ?? null,
|
|
4885
|
-
lrsBridge
|
|
4894
|
+
lrsBridge,
|
|
4895
|
+
skin: config.skin
|
|
4886
4896
|
};
|
|
4887
4897
|
}
|
|
4888
4898
|
|
|
@@ -5005,6 +5015,196 @@ function buildJsAfterOptions(config) {
|
|
|
5005
5015
|
};
|
|
5006
5016
|
}
|
|
5007
5017
|
|
|
5018
|
+
// src/templates/skin-css.ts
|
|
5019
|
+
function generateSkinCssLoader(options) {
|
|
5020
|
+
const { remoteUrl, localPath, timeout } = options;
|
|
5021
|
+
return `<!-- === PATCH-ADAMS: SKIN CSS (async with fallback) === -->
|
|
5022
|
+
<script data-pa="skin-css-loader">
|
|
5023
|
+
(function() {
|
|
5024
|
+
'use strict';
|
|
5025
|
+
var REMOTE_URL = "${remoteUrl}";
|
|
5026
|
+
var LOCAL_PATH = "${localPath}";
|
|
5027
|
+
var TIMEOUT = ${timeout};
|
|
5028
|
+
|
|
5029
|
+
function loadCSS(url, onSuccess, onError) {
|
|
5030
|
+
var link = document.createElement('link');
|
|
5031
|
+
link.rel = 'stylesheet';
|
|
5032
|
+
link.href = url;
|
|
5033
|
+
link.setAttribute('data-pa', 'skin-css');
|
|
5034
|
+
|
|
5035
|
+
link.onload = function() {
|
|
5036
|
+
if (onSuccess) onSuccess();
|
|
5037
|
+
};
|
|
5038
|
+
|
|
5039
|
+
link.onerror = function() {
|
|
5040
|
+
if (onError) onError();
|
|
5041
|
+
};
|
|
5042
|
+
|
|
5043
|
+
document.head.appendChild(link);
|
|
5044
|
+
return link;
|
|
5045
|
+
}
|
|
5046
|
+
|
|
5047
|
+
function loadCSSWithFallback() {
|
|
5048
|
+
var loaded = false;
|
|
5049
|
+
var timeoutId;
|
|
5050
|
+
|
|
5051
|
+
// Try remote first
|
|
5052
|
+
var remoteLink = loadCSS(
|
|
5053
|
+
REMOTE_URL,
|
|
5054
|
+
function() {
|
|
5055
|
+
if (loaded) return;
|
|
5056
|
+
loaded = true;
|
|
5057
|
+
clearTimeout(timeoutId);
|
|
5058
|
+
console.log('[PA-Patcher] Skin CSS loaded from remote:', REMOTE_URL);
|
|
5059
|
+
},
|
|
5060
|
+
function() {
|
|
5061
|
+
if (loaded) return;
|
|
5062
|
+
loaded = true;
|
|
5063
|
+
clearTimeout(timeoutId);
|
|
5064
|
+
loadLocalFallback();
|
|
5065
|
+
}
|
|
5066
|
+
);
|
|
5067
|
+
|
|
5068
|
+
// Timeout fallback
|
|
5069
|
+
timeoutId = setTimeout(function() {
|
|
5070
|
+
if (loaded) return;
|
|
5071
|
+
loaded = true;
|
|
5072
|
+
console.warn('[PA-Patcher] Skin CSS timed out, using local fallback');
|
|
5073
|
+
if (remoteLink.parentNode) {
|
|
5074
|
+
document.head.removeChild(remoteLink);
|
|
5075
|
+
}
|
|
5076
|
+
loadLocalFallback();
|
|
5077
|
+
}, TIMEOUT);
|
|
5078
|
+
}
|
|
5079
|
+
|
|
5080
|
+
function loadLocalFallback() {
|
|
5081
|
+
loadCSS(
|
|
5082
|
+
LOCAL_PATH,
|
|
5083
|
+
function() {
|
|
5084
|
+
console.log('[PA-Patcher] Skin CSS loaded from local fallback:', LOCAL_PATH);
|
|
5085
|
+
},
|
|
5086
|
+
function() {
|
|
5087
|
+
console.error('[PA-Patcher] Skin CSS failed to load from both remote and local');
|
|
5088
|
+
}
|
|
5089
|
+
);
|
|
5090
|
+
}
|
|
5091
|
+
|
|
5092
|
+
// Execute immediately
|
|
5093
|
+
loadCSSWithFallback();
|
|
5094
|
+
})();
|
|
5095
|
+
</script>`;
|
|
5096
|
+
}
|
|
5097
|
+
function buildSkinCssOptions(config) {
|
|
5098
|
+
if (!config.skin) return null;
|
|
5099
|
+
return {
|
|
5100
|
+
remoteUrl: `${config.remoteDomain}/skin/${config.skin}.css`,
|
|
5101
|
+
localPath: `skin/${config.skin}.css`,
|
|
5102
|
+
timeout: config.cssAfter.timeout
|
|
5103
|
+
// reuse cssAfter timeout
|
|
5104
|
+
};
|
|
5105
|
+
}
|
|
5106
|
+
|
|
5107
|
+
// src/templates/skin-js.ts
|
|
5108
|
+
function generateSkinJsLoader(options) {
|
|
5109
|
+
const { remoteUrl, localPath, timeout } = options;
|
|
5110
|
+
return `<!-- === PATCH-ADAMS: SKIN JS (async with fallback) === -->
|
|
5111
|
+
<script data-pa="skin-js-loader">
|
|
5112
|
+
(function() {
|
|
5113
|
+
'use strict';
|
|
5114
|
+
var REMOTE_URL = "${remoteUrl}";
|
|
5115
|
+
var LOCAL_PATH = "${localPath}";
|
|
5116
|
+
var TIMEOUT = ${timeout};
|
|
5117
|
+
|
|
5118
|
+
function loadJS(url, onSuccess, onError) {
|
|
5119
|
+
var script = document.createElement('script');
|
|
5120
|
+
script.src = url;
|
|
5121
|
+
script.async = true;
|
|
5122
|
+
script.setAttribute('data-pa', 'skin-js');
|
|
5123
|
+
|
|
5124
|
+
script.onload = function() {
|
|
5125
|
+
if (onSuccess) onSuccess();
|
|
5126
|
+
};
|
|
5127
|
+
|
|
5128
|
+
script.onerror = function() {
|
|
5129
|
+
if (onError) onError();
|
|
5130
|
+
};
|
|
5131
|
+
|
|
5132
|
+
document.body.appendChild(script);
|
|
5133
|
+
return script;
|
|
5134
|
+
}
|
|
5135
|
+
|
|
5136
|
+
function loadJSWithFallback() {
|
|
5137
|
+
var loaded = false;
|
|
5138
|
+
var timeoutId;
|
|
5139
|
+
|
|
5140
|
+
// Try remote first
|
|
5141
|
+
var remoteScript = loadJS(
|
|
5142
|
+
REMOTE_URL,
|
|
5143
|
+
function() {
|
|
5144
|
+
if (loaded) return;
|
|
5145
|
+
loaded = true;
|
|
5146
|
+
clearTimeout(timeoutId);
|
|
5147
|
+
console.log('[PA-Patcher] Skin JS loaded from remote:', REMOTE_URL);
|
|
5148
|
+
if (window.pa_patcher && window.pa_patcher.loaded) {
|
|
5149
|
+
window.pa_patcher.loaded.skinJs = true;
|
|
5150
|
+
}
|
|
5151
|
+
},
|
|
5152
|
+
function() {
|
|
5153
|
+
if (loaded) return;
|
|
5154
|
+
loaded = true;
|
|
5155
|
+
clearTimeout(timeoutId);
|
|
5156
|
+
loadLocalFallback();
|
|
5157
|
+
}
|
|
5158
|
+
);
|
|
5159
|
+
|
|
5160
|
+
// Timeout fallback
|
|
5161
|
+
timeoutId = setTimeout(function() {
|
|
5162
|
+
if (loaded) return;
|
|
5163
|
+
loaded = true;
|
|
5164
|
+
console.warn('[PA-Patcher] Skin JS timed out, using local fallback');
|
|
5165
|
+
if (remoteScript.parentNode) {
|
|
5166
|
+
document.body.removeChild(remoteScript);
|
|
5167
|
+
}
|
|
5168
|
+
loadLocalFallback();
|
|
5169
|
+
}, TIMEOUT);
|
|
5170
|
+
}
|
|
5171
|
+
|
|
5172
|
+
function loadLocalFallback() {
|
|
5173
|
+
loadJS(
|
|
5174
|
+
LOCAL_PATH,
|
|
5175
|
+
function() {
|
|
5176
|
+
console.log('[PA-Patcher] Skin JS loaded from local fallback:', LOCAL_PATH);
|
|
5177
|
+
if (window.pa_patcher && window.pa_patcher.loaded) {
|
|
5178
|
+
window.pa_patcher.loaded.skinJs = true;
|
|
5179
|
+
}
|
|
5180
|
+
},
|
|
5181
|
+
function() {
|
|
5182
|
+
console.error('[PA-Patcher] Skin JS failed to load from both remote and local');
|
|
5183
|
+
}
|
|
5184
|
+
);
|
|
5185
|
+
}
|
|
5186
|
+
|
|
5187
|
+
// Execute after DOM is ready
|
|
5188
|
+
if (document.readyState === 'loading') {
|
|
5189
|
+
document.addEventListener('DOMContentLoaded', function() {
|
|
5190
|
+
setTimeout(loadJSWithFallback, 150);
|
|
5191
|
+
});
|
|
5192
|
+
} else {
|
|
5193
|
+
setTimeout(loadJSWithFallback, 150);
|
|
5194
|
+
}
|
|
5195
|
+
})();
|
|
5196
|
+
</script>`;
|
|
5197
|
+
}
|
|
5198
|
+
function buildSkinJsOptions(config) {
|
|
5199
|
+
if (!config.skin) return null;
|
|
5200
|
+
return {
|
|
5201
|
+
remoteUrl: `${config.remoteDomain}/skin/${config.skin}.js`,
|
|
5202
|
+
localPath: `skin/${config.skin}.js`,
|
|
5203
|
+
timeout: config.jsAfter.timeout
|
|
5204
|
+
// reuse jsAfter timeout
|
|
5205
|
+
};
|
|
5206
|
+
}
|
|
5207
|
+
|
|
5008
5208
|
// src/patcher/html-injector.ts
|
|
5009
5209
|
var HtmlInjector = class {
|
|
5010
5210
|
config;
|
|
@@ -5068,6 +5268,10 @@ var HtmlInjector = class {
|
|
|
5068
5268
|
if (this.config.jsAfter.enabled) {
|
|
5069
5269
|
result = this.injectJsAfter(result);
|
|
5070
5270
|
}
|
|
5271
|
+
if (this.config.skin) {
|
|
5272
|
+
result = this.injectSkinCss(result);
|
|
5273
|
+
result = this.injectSkinJs(result);
|
|
5274
|
+
}
|
|
5071
5275
|
if (this.pluginAssets) {
|
|
5072
5276
|
result = this.injectPluginAssets(result);
|
|
5073
5277
|
}
|
|
@@ -5114,8 +5318,8 @@ ${pluginJs}
|
|
|
5114
5318
|
* Also adds data attributes for course metadata
|
|
5115
5319
|
*/
|
|
5116
5320
|
addHtmlAttributes(html) {
|
|
5117
|
-
const { htmlClass, loadingClass } = this.config;
|
|
5118
|
-
const classes = `${htmlClass} ${loadingClass}`;
|
|
5321
|
+
const { htmlClass, loadingClass, skin } = this.config;
|
|
5322
|
+
const classes = `${htmlClass} ${loadingClass}${skin ? ` pa-skinned ${skin}` : ""}`;
|
|
5119
5323
|
const dataAttrs = [];
|
|
5120
5324
|
if (this.metadata) {
|
|
5121
5325
|
dataAttrs.push(`data-pa-course-id="${this.escapeAttr(this.metadata.courseId)}"`);
|
|
@@ -5124,6 +5328,9 @@ ${pluginJs}
|
|
|
5124
5328
|
dataAttrs.push(`data-pa-title="${this.escapeAttr(this.metadata.title)}"`);
|
|
5125
5329
|
}
|
|
5126
5330
|
}
|
|
5331
|
+
if (skin) {
|
|
5332
|
+
dataAttrs.push(`data-pa-skin="${this.escapeAttr(skin)}"`);
|
|
5333
|
+
}
|
|
5127
5334
|
const dataAttrString = dataAttrs.length > 0 ? " " + dataAttrs.join(" ") : "";
|
|
5128
5335
|
const htmlTagPattern = /<html([^>]*)>/i;
|
|
5129
5336
|
const match = html.match(htmlTagPattern);
|
|
@@ -5202,6 +5409,26 @@ ${loader}`);
|
|
|
5202
5409
|
${loader}`);
|
|
5203
5410
|
}
|
|
5204
5411
|
return html.replace(/<\/body>/i, `${loader}
|
|
5412
|
+
</body>`);
|
|
5413
|
+
}
|
|
5414
|
+
/**
|
|
5415
|
+
* Inject Skin CSS loader after CSS After (before </head>)
|
|
5416
|
+
*/
|
|
5417
|
+
injectSkinCss(html) {
|
|
5418
|
+
const options = buildSkinCssOptions(this.config);
|
|
5419
|
+
if (!options) return html;
|
|
5420
|
+
const loader = generateSkinCssLoader(options);
|
|
5421
|
+
return html.replace(/<\/head>/i, `${loader}
|
|
5422
|
+
</head>`);
|
|
5423
|
+
}
|
|
5424
|
+
/**
|
|
5425
|
+
* Inject Skin JS loader after JS After (before </body>)
|
|
5426
|
+
*/
|
|
5427
|
+
injectSkinJs(html) {
|
|
5428
|
+
const options = buildSkinJsOptions(this.config);
|
|
5429
|
+
if (!options) return html;
|
|
5430
|
+
const loader = generateSkinJsLoader(options);
|
|
5431
|
+
return html.replace(/<\/body>/i, `${loader}
|
|
5205
5432
|
</body>`);
|
|
5206
5433
|
}
|
|
5207
5434
|
};
|
|
@@ -5245,6 +5472,10 @@ var StorylineHtmlInjector = class {
|
|
|
5245
5472
|
if (this.config.jsAfter.enabled) {
|
|
5246
5473
|
result = this.injectJsAfter(result);
|
|
5247
5474
|
}
|
|
5475
|
+
if (this.config.skin) {
|
|
5476
|
+
result = this.injectSkinCss(result);
|
|
5477
|
+
result = this.injectSkinJs(result);
|
|
5478
|
+
}
|
|
5248
5479
|
if (this.pluginAssets) {
|
|
5249
5480
|
result = this.injectPluginAssets(result);
|
|
5250
5481
|
}
|
|
@@ -5289,8 +5520,8 @@ ${pluginJs}
|
|
|
5289
5520
|
* Also adds data attributes for course metadata
|
|
5290
5521
|
*/
|
|
5291
5522
|
addHtmlAttributes(html) {
|
|
5292
|
-
const { htmlClass, loadingClass } = this.config;
|
|
5293
|
-
const classes = `${htmlClass} ${loadingClass}`;
|
|
5523
|
+
const { htmlClass, loadingClass, skin } = this.config;
|
|
5524
|
+
const classes = `${htmlClass} ${loadingClass}${skin ? ` pa-skinned ${skin}` : ""}`;
|
|
5294
5525
|
const dataAttrs = [];
|
|
5295
5526
|
if (this.metadata) {
|
|
5296
5527
|
dataAttrs.push(`data-pa-course-id="${this.escapeAttr(this.metadata.courseId)}"`);
|
|
@@ -5300,6 +5531,9 @@ ${pluginJs}
|
|
|
5300
5531
|
dataAttrs.push(`data-pa-title="${this.escapeAttr(this.metadata.title)}"`);
|
|
5301
5532
|
}
|
|
5302
5533
|
}
|
|
5534
|
+
if (skin) {
|
|
5535
|
+
dataAttrs.push(`data-pa-skin="${this.escapeAttr(skin)}"`);
|
|
5536
|
+
}
|
|
5303
5537
|
const dataAttrString = dataAttrs.length > 0 ? " " + dataAttrs.join(" ") : "";
|
|
5304
5538
|
const htmlTagPattern = /<html([^>]*)>/i;
|
|
5305
5539
|
const match = html.match(htmlTagPattern);
|
|
@@ -5377,6 +5611,26 @@ ${loader}`);
|
|
|
5377
5611
|
const options = buildJsAfterOptions(this.config);
|
|
5378
5612
|
const loader = generateJsAfterLoader(options);
|
|
5379
5613
|
return html.replace(/<\/body>/i, `${loader}
|
|
5614
|
+
</body>`);
|
|
5615
|
+
}
|
|
5616
|
+
/**
|
|
5617
|
+
* Inject Skin CSS loader after CSS After (before </head>)
|
|
5618
|
+
*/
|
|
5619
|
+
injectSkinCss(html) {
|
|
5620
|
+
const options = buildSkinCssOptions(this.config);
|
|
5621
|
+
if (!options) return html;
|
|
5622
|
+
const loader = generateSkinCssLoader(options);
|
|
5623
|
+
return html.replace(/<\/head>/i, `${loader}
|
|
5624
|
+
</head>`);
|
|
5625
|
+
}
|
|
5626
|
+
/**
|
|
5627
|
+
* Inject Skin JS loader after JS After (before </body>)
|
|
5628
|
+
*/
|
|
5629
|
+
injectSkinJs(html) {
|
|
5630
|
+
const options = buildSkinJsOptions(this.config);
|
|
5631
|
+
if (!options) return html;
|
|
5632
|
+
const loader = generateSkinJsLoader(options);
|
|
5633
|
+
return html.replace(/<\/body>/i, `${loader}
|
|
5380
5634
|
</body>`);
|
|
5381
5635
|
}
|
|
5382
5636
|
};
|
|
@@ -5427,7 +5681,9 @@ var ManifestUpdater = class {
|
|
|
5427
5681
|
paths.cssBefore,
|
|
5428
5682
|
paths.cssAfter,
|
|
5429
5683
|
paths.jsBefore,
|
|
5430
|
-
paths.jsAfter
|
|
5684
|
+
paths.jsAfter,
|
|
5685
|
+
paths.skinCss,
|
|
5686
|
+
paths.skinJs
|
|
5431
5687
|
].filter(Boolean);
|
|
5432
5688
|
if (filesToAdd.length === 0) {
|
|
5433
5689
|
return [];
|
|
@@ -5907,6 +6163,20 @@ var Patcher = class {
|
|
|
5907
6163
|
})
|
|
5908
6164
|
);
|
|
5909
6165
|
}
|
|
6166
|
+
if (this.config.skin) {
|
|
6167
|
+
const skinCssUrl = `${remoteDomain}/skin/${this.config.skin}.css`;
|
|
6168
|
+
fetchPromises.push(
|
|
6169
|
+
this.fetchFile(skinCssUrl).then((content) => {
|
|
6170
|
+
fetched.skinCss = content;
|
|
6171
|
+
})
|
|
6172
|
+
);
|
|
6173
|
+
const skinJsUrl = `${remoteDomain}/skin/${this.config.skin}.js`;
|
|
6174
|
+
fetchPromises.push(
|
|
6175
|
+
this.fetchFile(skinJsUrl).then((content) => {
|
|
6176
|
+
fetched.skinJs = content;
|
|
6177
|
+
})
|
|
6178
|
+
);
|
|
6179
|
+
}
|
|
5910
6180
|
await Promise.all(fetchPromises);
|
|
5911
6181
|
return fetched;
|
|
5912
6182
|
}
|
|
@@ -5990,6 +6260,16 @@ var Patcher = class {
|
|
|
5990
6260
|
console.log(`[Patcher] Wrote generated UUID to manifest identifier`);
|
|
5991
6261
|
}
|
|
5992
6262
|
}
|
|
6263
|
+
const effectiveSkin = options.skin || this.config.skin;
|
|
6264
|
+
if (options.skin && options.skin !== this.config.skin) {
|
|
6265
|
+
this.config.skin = options.skin;
|
|
6266
|
+
this.riseHtmlInjector = new HtmlInjector(this.config);
|
|
6267
|
+
this.storylineHtmlInjector = new StorylineHtmlInjector(this.config);
|
|
6268
|
+
console.log(`[Patcher] Using per-call skin override: ${options.skin}`);
|
|
6269
|
+
}
|
|
6270
|
+
if (effectiveSkin) {
|
|
6271
|
+
console.log(`[Patcher] Skin: ${effectiveSkin}`);
|
|
6272
|
+
}
|
|
5993
6273
|
const htmlInjector = this.getHtmlInjector(toolInfo.tool);
|
|
5994
6274
|
htmlInjector.setMetadata(metadata);
|
|
5995
6275
|
let fetchedFallbacks = {};
|
|
@@ -6118,7 +6398,11 @@ var Patcher = class {
|
|
|
6118
6398
|
buildManifestPaths(addedFiles) {
|
|
6119
6399
|
const paths = {};
|
|
6120
6400
|
for (const filePath of addedFiles) {
|
|
6121
|
-
if (filePath.endsWith(this.config.
|
|
6401
|
+
if (this.config.skin && filePath.endsWith(`skin/${this.config.skin}.css`)) {
|
|
6402
|
+
paths.skinCss = filePath;
|
|
6403
|
+
} else if (this.config.skin && filePath.endsWith(`skin/${this.config.skin}.js`)) {
|
|
6404
|
+
paths.skinJs = filePath;
|
|
6405
|
+
} else if (filePath.endsWith(this.config.cssBefore.filename)) {
|
|
6122
6406
|
paths.cssBefore = filePath;
|
|
6123
6407
|
} else if (filePath.endsWith(this.config.cssAfter.filename)) {
|
|
6124
6408
|
paths.cssAfter = filePath;
|
|
@@ -6202,6 +6486,22 @@ var Patcher = class {
|
|
|
6202
6486
|
added.push(path);
|
|
6203
6487
|
if (fetched.jsAfter) console.log(`[Patcher] Using fetched content for ${path}`);
|
|
6204
6488
|
}
|
|
6489
|
+
if (this.config.skin) {
|
|
6490
|
+
const skinCssPath = `${basePath}skin/${this.config.skin}.css`;
|
|
6491
|
+
const skinCssContent = fetched.skinCss ?? `/* PA-Patcher: Skin CSS (${this.config.skin}) */
|
|
6492
|
+
`;
|
|
6493
|
+
zip.addFile(skinCssPath, Buffer.from(skinCssContent, "utf-8"));
|
|
6494
|
+
added.push(skinCssPath);
|
|
6495
|
+
if (fetched.skinCss) console.log(`[Patcher] Using fetched skin CSS for ${skinCssPath}`);
|
|
6496
|
+
else console.log(`[Patcher] Added placeholder skin CSS: ${skinCssPath}`);
|
|
6497
|
+
const skinJsPath = `${basePath}skin/${this.config.skin}.js`;
|
|
6498
|
+
const skinJsContent = fetched.skinJs ?? `// PA-Patcher: Skin JS (${this.config.skin})
|
|
6499
|
+
`;
|
|
6500
|
+
zip.addFile(skinJsPath, Buffer.from(skinJsContent, "utf-8"));
|
|
6501
|
+
added.push(skinJsPath);
|
|
6502
|
+
if (fetched.skinJs) console.log(`[Patcher] Using fetched skin JS for ${skinJsPath}`);
|
|
6503
|
+
else console.log(`[Patcher] Added placeholder skin JS: ${skinJsPath}`);
|
|
6504
|
+
}
|
|
6205
6505
|
return added;
|
|
6206
6506
|
}
|
|
6207
6507
|
/**
|
|
@@ -6216,9 +6516,9 @@ var Patcher = class {
|
|
|
6216
6516
|
* @param buffer - Input ZIP file as Buffer
|
|
6217
6517
|
* @returns Patched ZIP file as Buffer
|
|
6218
6518
|
*/
|
|
6219
|
-
async patchBuffer(buffer) {
|
|
6519
|
+
async patchBuffer(buffer, options) {
|
|
6220
6520
|
console.log(`[Patcher] patchBuffer called with ${buffer.length} bytes`);
|
|
6221
|
-
const { buffer: patchedBuffer, result } = await this.patch(buffer);
|
|
6521
|
+
const { buffer: patchedBuffer, result } = await this.patch(buffer, options);
|
|
6222
6522
|
console.log(`[Patcher] Patch result:`, JSON.stringify(result, null, 2));
|
|
6223
6523
|
console.log(`[Patcher] Returning ${patchedBuffer.length} bytes`);
|
|
6224
6524
|
return patchedBuffer;
|