@patch-adams/core 1.4.25 → 1.4.27
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 +82 -39
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +82 -39
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +82 -39
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +82 -39
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -969,7 +969,7 @@ declare function generateCssAfterLoader(options: CssAfterOptions): string;
|
|
|
969
969
|
declare function buildCssAfterOptions(config: PatchAdamsConfig): CssAfterOptions;
|
|
970
970
|
|
|
971
971
|
/**
|
|
972
|
-
* LRS Bridge Template for
|
|
972
|
+
* LRS Bridge Template for PA-Patcher
|
|
973
973
|
*
|
|
974
974
|
* Generates JavaScript code that bridges Rise courses to an LRS endpoint.
|
|
975
975
|
* Supports direct xAPI statement posting when PlayerIntegration is unavailable.
|
package/dist/index.d.ts
CHANGED
|
@@ -969,7 +969,7 @@ declare function generateCssAfterLoader(options: CssAfterOptions): string;
|
|
|
969
969
|
declare function buildCssAfterOptions(config: PatchAdamsConfig): CssAfterOptions;
|
|
970
970
|
|
|
971
971
|
/**
|
|
972
|
-
* LRS Bridge Template for
|
|
972
|
+
* LRS Bridge Template for PA-Patcher
|
|
973
973
|
*
|
|
974
974
|
* Generates JavaScript code that bridges Rise courses to an LRS endpoint.
|
|
975
975
|
* Supports direct xAPI statement posting when PlayerIntegration is unavailable.
|
package/dist/index.js
CHANGED
|
@@ -264,13 +264,13 @@ html.${htmlClass}.${loadingClass} body {
|
|
|
264
264
|
var link = loadCSSSync(REMOTE_URL);
|
|
265
265
|
|
|
266
266
|
link.onerror = function() {
|
|
267
|
-
console.warn('[
|
|
267
|
+
console.warn('[PA-Patcher] CSS before failed to load from remote, using local fallback');
|
|
268
268
|
document.head.removeChild(link);
|
|
269
269
|
loadCSSSync(LOCAL_PATH);
|
|
270
270
|
};
|
|
271
271
|
|
|
272
272
|
link.onload = function() {
|
|
273
|
-
console.log('[
|
|
273
|
+
console.log('[PA-Patcher] CSS before loaded from remote:', REMOTE_URL);
|
|
274
274
|
};
|
|
275
275
|
})();
|
|
276
276
|
</script>`;
|
|
@@ -324,7 +324,7 @@ function generateCssAfterLoader(options) {
|
|
|
324
324
|
if (loaded) return;
|
|
325
325
|
loaded = true;
|
|
326
326
|
clearTimeout(timeoutId);
|
|
327
|
-
console.log('[
|
|
327
|
+
console.log('[PA-Patcher] CSS after loaded from remote:', REMOTE_URL);
|
|
328
328
|
},
|
|
329
329
|
function() {
|
|
330
330
|
if (loaded) return;
|
|
@@ -338,7 +338,7 @@ function generateCssAfterLoader(options) {
|
|
|
338
338
|
timeoutId = setTimeout(function() {
|
|
339
339
|
if (loaded) return;
|
|
340
340
|
loaded = true;
|
|
341
|
-
console.warn('[
|
|
341
|
+
console.warn('[PA-Patcher] CSS after timed out, using local fallback');
|
|
342
342
|
if (remoteLink.parentNode) {
|
|
343
343
|
document.head.removeChild(remoteLink);
|
|
344
344
|
}
|
|
@@ -350,10 +350,10 @@ function generateCssAfterLoader(options) {
|
|
|
350
350
|
loadCSS(
|
|
351
351
|
LOCAL_PATH,
|
|
352
352
|
function() {
|
|
353
|
-
console.log('[
|
|
353
|
+
console.log('[PA-Patcher] CSS after loaded from local fallback:', LOCAL_PATH);
|
|
354
354
|
},
|
|
355
355
|
function() {
|
|
356
|
-
console.error('[
|
|
356
|
+
console.error('[PA-Patcher] CSS after failed to load from both remote and local');
|
|
357
357
|
}
|
|
358
358
|
);
|
|
359
359
|
}
|
|
@@ -1336,7 +1336,9 @@ function generateLrsBridgeCode(options) {
|
|
|
1336
1336
|
((employee.fname || employee.firstName || '') + ' ' + (employee.lname || employee.lastName || '')).trim(),
|
|
1337
1337
|
firstName: employee.fname || employee.firstName || employee.first_name,
|
|
1338
1338
|
lastName: employee.lname || employee.lastName || employee.last_name,
|
|
1339
|
-
employeeId: employee.emp_id || employee.employeeId || employee.employee_id || employeeId
|
|
1339
|
+
employeeId: employee.emp_id || employee.employeeId || employee.employee_id || employeeId,
|
|
1340
|
+
bravaisUserId: employee.bravaisUserId || null,
|
|
1341
|
+
tenantUrl: employee.tenantUrl || null
|
|
1340
1342
|
};
|
|
1341
1343
|
log('Parsed employee data:', employeeLookupData);
|
|
1342
1344
|
// Persist to localStorage for cross-session caching
|
|
@@ -1410,6 +1412,16 @@ function generateLrsBridgeCode(options) {
|
|
|
1410
1412
|
if (employeeData.name && (!actor.name || actor.name === 'Unknown Learner')) {
|
|
1411
1413
|
actor.name = employeeData.name;
|
|
1412
1414
|
}
|
|
1415
|
+
|
|
1416
|
+
// Update account with Bravais user ID and tenant URL if available
|
|
1417
|
+
if (employeeData.bravaisUserId) {
|
|
1418
|
+
var originalAccountName = actor.account ? actor.account.name : null;
|
|
1419
|
+
actor.account = {
|
|
1420
|
+
name: employeeData.bravaisUserId,
|
|
1421
|
+
homePage: employeeData.tenantUrl || (actor.account && actor.account.homePage) || window.location.origin
|
|
1422
|
+
};
|
|
1423
|
+
log('Updated actor account: bravaisUserId=' + employeeData.bravaisUserId + ', homePage=' + actor.account.homePage + ' (was: ' + originalAccountName + ')');
|
|
1424
|
+
}
|
|
1413
1425
|
}
|
|
1414
1426
|
callback(actor);
|
|
1415
1427
|
});
|
|
@@ -2074,7 +2086,7 @@ function generateLrsBridgeCode(options) {
|
|
|
2074
2086
|
tenantHomepage: null // https://{tenant}.bravais.com format
|
|
2075
2087
|
};
|
|
2076
2088
|
|
|
2077
|
-
// 0. Use baked-in GUIDs from
|
|
2089
|
+
// 0. Use baked-in GUIDs from PA-Patcher config (highest priority - set at wrap time)
|
|
2078
2090
|
if (DOCUMENT_GUID) {
|
|
2079
2091
|
info.guid = DOCUMENT_GUID;
|
|
2080
2092
|
info.id = 'http://xyleme.com/bravais/document/' + DOCUMENT_GUID;
|
|
@@ -2583,6 +2595,11 @@ function generateLrsBridgeCode(options) {
|
|
|
2583
2595
|
// Publish index (default to 1)
|
|
2584
2596
|
ctx.extensions['publishIndex'] = (LRS.courseInfo && LRS.courseInfo.publishIndex) ? LRS.courseInfo.publishIndex : 1;
|
|
2585
2597
|
|
|
2598
|
+
// Employee ID from employee lookup (if available)
|
|
2599
|
+
if (employeeLookupData && employeeLookupData.employeeId) {
|
|
2600
|
+
ctx.extensions['employeeId'] = employeeLookupData.employeeId;
|
|
2601
|
+
}
|
|
2602
|
+
|
|
2586
2603
|
// Xyleme schema version and PII flag
|
|
2587
2604
|
ctx.extensions['http://xyleme.com/bravais/extensions/statement-schema'] = 'xyleme_10';
|
|
2588
2605
|
ctx.extensions['http://xyleme.com/bravais/extensions/protect_pii'] = false;
|
|
@@ -4065,6 +4082,19 @@ function generateLrsBridgeCode(options) {
|
|
|
4065
4082
|
// Setup connection
|
|
4066
4083
|
var bridgeReady = setupBridge();
|
|
4067
4084
|
|
|
4085
|
+
// Track async readiness: both actor and doc metadata must resolve before sending statements
|
|
4086
|
+
var actorReady = false;
|
|
4087
|
+
var docReady = false;
|
|
4088
|
+
var launchEventsSent = false;
|
|
4089
|
+
|
|
4090
|
+
function tryLaunchEvents() {
|
|
4091
|
+
if (launchEventsSent) return;
|
|
4092
|
+
if (!actorReady || !docReady) return;
|
|
4093
|
+
launchEventsSent = true;
|
|
4094
|
+
log('Both actor and doc metadata ready, sending launch events');
|
|
4095
|
+
setTimeout(sendLaunchEvents, 50);
|
|
4096
|
+
}
|
|
4097
|
+
|
|
4068
4098
|
if (bridgeReady) {
|
|
4069
4099
|
LRS.initialized = true;
|
|
4070
4100
|
|
|
@@ -4075,14 +4105,23 @@ function generateLrsBridgeCode(options) {
|
|
|
4075
4105
|
log('Actor:', LRS.actor);
|
|
4076
4106
|
log('Course:', LRS.courseInfo);
|
|
4077
4107
|
|
|
4078
|
-
// Then try async actor extraction
|
|
4079
|
-
//
|
|
4108
|
+
// Then try async actor extraction (employee lookup, Bravais session)
|
|
4109
|
+
// Launch events will NOT be sent until this completes
|
|
4080
4110
|
extractActorAsync(function(actor) {
|
|
4081
4111
|
log('Actor updated after async fetch:', actor);
|
|
4112
|
+
actorReady = true;
|
|
4113
|
+
// Log final actor state for diagnostics
|
|
4114
|
+
if (window.console && window.console.info) {
|
|
4115
|
+
console.info('[PA-LRS] Actor resolved: name=' + (actor ? actor.name : 'none') +
|
|
4116
|
+
', mbox=' + (actor ? actor.mbox : 'none') +
|
|
4117
|
+
', account=' + (actor && actor.account ? actor.account.name : 'none'));
|
|
4118
|
+
}
|
|
4119
|
+
tryLaunchEvents();
|
|
4082
4120
|
});
|
|
4083
4121
|
} else {
|
|
4084
4122
|
warn('Bridge setup failed - operating in offline mode');
|
|
4085
4123
|
LRS.mode = 'offline';
|
|
4124
|
+
actorReady = true; // No actor to wait for in offline mode
|
|
4086
4125
|
}
|
|
4087
4126
|
|
|
4088
4127
|
// Always-visible bridge summary (not gated by DEBUG)
|
|
@@ -4127,13 +4166,17 @@ function generateLrsBridgeCode(options) {
|
|
|
4127
4166
|
}
|
|
4128
4167
|
}
|
|
4129
4168
|
|
|
4130
|
-
function
|
|
4169
|
+
function onDocReady() {
|
|
4170
|
+
docReady = true;
|
|
4171
|
+
tryLaunchEvents();
|
|
4172
|
+
}
|
|
4173
|
+
|
|
4174
|
+
function fetchDocDataAndReady(docId) {
|
|
4131
4175
|
fetchDocumentMetadata(docId, function(docData) {
|
|
4132
4176
|
if (docData) {
|
|
4133
4177
|
updateCourseInfoFromApi(docData);
|
|
4134
4178
|
}
|
|
4135
|
-
|
|
4136
|
-
setTimeout(sendLaunchEvents, 100);
|
|
4179
|
+
onDocReady();
|
|
4137
4180
|
});
|
|
4138
4181
|
}
|
|
4139
4182
|
|
|
@@ -4153,20 +4196,20 @@ function generateLrsBridgeCode(options) {
|
|
|
4153
4196
|
} else {
|
|
4154
4197
|
warn('Could not fetch document data from shared API - statements may fail aggregation');
|
|
4155
4198
|
}
|
|
4156
|
-
|
|
4199
|
+
onDocReady();
|
|
4157
4200
|
});
|
|
4158
4201
|
} else if (documentId) {
|
|
4159
4202
|
// No shared link token, try with extracted document ID (requires auth)
|
|
4160
4203
|
log('No shared link token, fetching document data with ID:', documentId);
|
|
4161
|
-
|
|
4204
|
+
fetchDocDataAndReady(documentId);
|
|
4162
4205
|
} else {
|
|
4163
4206
|
// No identifiers available
|
|
4164
4207
|
warn('No shared link token or document ID - statements may fail aggregation');
|
|
4165
|
-
|
|
4208
|
+
onDocReady();
|
|
4166
4209
|
}
|
|
4167
4210
|
} else {
|
|
4168
|
-
// Already have GUID
|
|
4169
|
-
|
|
4211
|
+
// Already have GUID
|
|
4212
|
+
onDocReady();
|
|
4170
4213
|
}
|
|
4171
4214
|
|
|
4172
4215
|
// Setup beforeunload to send terminated
|
|
@@ -4251,7 +4294,7 @@ ${courseLines.join("\n")}
|
|
|
4251
4294
|
},` : "";
|
|
4252
4295
|
return `<!-- === PATCH-ADAMS: JS BEFORE (blocking) === -->
|
|
4253
4296
|
<script data-pa="js-before-loader">
|
|
4254
|
-
// Initialize
|
|
4297
|
+
// Initialize PA-Patcher global namespace IMMEDIATELY (before IIFE)
|
|
4255
4298
|
window.pa_patcher = window.pa_patcher || {
|
|
4256
4299
|
version: '1.0.25',
|
|
4257
4300
|
htmlClass: '${htmlClass}',
|
|
@@ -4296,7 +4339,7 @@ window.pa_patcher = window.pa_patcher || {
|
|
|
4296
4339
|
if (isExtensionError(event.reason)) {
|
|
4297
4340
|
event.preventDefault();
|
|
4298
4341
|
event.stopImmediatePropagation();
|
|
4299
|
-
console.debug('[
|
|
4342
|
+
console.debug('[PA-Patcher] Suppressed browser extension error:', event.reason);
|
|
4300
4343
|
return false;
|
|
4301
4344
|
}
|
|
4302
4345
|
}, true);
|
|
@@ -4306,7 +4349,7 @@ window.pa_patcher = window.pa_patcher || {
|
|
|
4306
4349
|
if (isExtensionError(event.error || event.message)) {
|
|
4307
4350
|
event.preventDefault();
|
|
4308
4351
|
event.stopImmediatePropagation();
|
|
4309
|
-
console.debug('[
|
|
4352
|
+
console.debug('[PA-Patcher] Suppressed browser extension error:', event.message);
|
|
4310
4353
|
return false;
|
|
4311
4354
|
}
|
|
4312
4355
|
}, true);
|
|
@@ -4331,17 +4374,17 @@ window.pa_patcher = window.pa_patcher || {
|
|
|
4331
4374
|
var script = loadJSSync(REMOTE_URL);
|
|
4332
4375
|
|
|
4333
4376
|
script.onerror = function() {
|
|
4334
|
-
console.warn('[
|
|
4377
|
+
console.warn('[PA-Patcher] JS before failed to load from remote, using local fallback');
|
|
4335
4378
|
document.head.removeChild(script);
|
|
4336
4379
|
var fallback = loadJSSync(LOCAL_PATH);
|
|
4337
4380
|
fallback.onload = function() {
|
|
4338
4381
|
if (window.pa_patcher && window.pa_patcher.loaded) {
|
|
4339
4382
|
window.pa_patcher.loaded.jsBefore = true;
|
|
4340
4383
|
}
|
|
4341
|
-
console.log('[
|
|
4384
|
+
console.log('[PA-Patcher] JS before loaded from local fallback:', LOCAL_PATH);
|
|
4342
4385
|
};
|
|
4343
4386
|
fallback.onerror = function() {
|
|
4344
|
-
console.error('[
|
|
4387
|
+
console.error('[PA-Patcher] JS before failed to load from both remote and local');
|
|
4345
4388
|
};
|
|
4346
4389
|
};
|
|
4347
4390
|
|
|
@@ -4349,7 +4392,7 @@ window.pa_patcher = window.pa_patcher || {
|
|
|
4349
4392
|
if (window.pa_patcher && window.pa_patcher.loaded) {
|
|
4350
4393
|
window.pa_patcher.loaded.jsBefore = true;
|
|
4351
4394
|
}
|
|
4352
|
-
console.log('[
|
|
4395
|
+
console.log('[PA-Patcher] JS before loaded from remote:', REMOTE_URL);
|
|
4353
4396
|
};
|
|
4354
4397
|
})();
|
|
4355
4398
|
${lrsBridgeCode}
|
|
@@ -4420,14 +4463,14 @@ function generateJsAfterLoader(options) {
|
|
|
4420
4463
|
if (window.pa_patcher && window.pa_patcher.loaded) {
|
|
4421
4464
|
window.pa_patcher.loaded.jsAfter = true;
|
|
4422
4465
|
}
|
|
4423
|
-
console.log('[
|
|
4466
|
+
console.log('[PA-Patcher] Loading complete, content revealed');
|
|
4424
4467
|
|
|
4425
4468
|
// Add visual badge to indicate patching is active
|
|
4426
4469
|
var badge = document.createElement('div');
|
|
4427
4470
|
badge.setAttribute('data-pa', 'badge');
|
|
4428
4471
|
badge.style.cssText = 'position:fixed;bottom:10px;right:10px;background:#4CAF50;color:white;padding:4px 8px;border-radius:4px;font-size:11px;font-family:sans-serif;z-index:999999;opacity:0.8;cursor:pointer;';
|
|
4429
4472
|
badge.textContent = 'PA';
|
|
4430
|
-
badge.title = '
|
|
4473
|
+
badge.title = 'PA-Patcher Active';
|
|
4431
4474
|
badge.onclick = function() { badge.style.display = 'none'; };
|
|
4432
4475
|
document.body.appendChild(badge);
|
|
4433
4476
|
}
|
|
@@ -4443,7 +4486,7 @@ function generateJsAfterLoader(options) {
|
|
|
4443
4486
|
if (loaded) return;
|
|
4444
4487
|
loaded = true;
|
|
4445
4488
|
clearTimeout(timeoutId);
|
|
4446
|
-
console.log('[
|
|
4489
|
+
console.log('[PA-Patcher] JS after loaded from remote:', REMOTE_URL);
|
|
4447
4490
|
// Give the script a moment to execute, then remove loading class
|
|
4448
4491
|
setTimeout(removeLoadingClass, 50);
|
|
4449
4492
|
},
|
|
@@ -4459,7 +4502,7 @@ function generateJsAfterLoader(options) {
|
|
|
4459
4502
|
timeoutId = setTimeout(function() {
|
|
4460
4503
|
if (loaded) return;
|
|
4461
4504
|
loaded = true;
|
|
4462
|
-
console.warn('[
|
|
4505
|
+
console.warn('[PA-Patcher] JS after timed out, using local fallback');
|
|
4463
4506
|
if (remoteScript.parentNode) {
|
|
4464
4507
|
document.body.removeChild(remoteScript);
|
|
4465
4508
|
}
|
|
@@ -4471,11 +4514,11 @@ function generateJsAfterLoader(options) {
|
|
|
4471
4514
|
loadJS(
|
|
4472
4515
|
LOCAL_PATH,
|
|
4473
4516
|
function() {
|
|
4474
|
-
console.log('[
|
|
4517
|
+
console.log('[PA-Patcher] JS after loaded from local fallback:', LOCAL_PATH);
|
|
4475
4518
|
setTimeout(removeLoadingClass, 50);
|
|
4476
4519
|
},
|
|
4477
4520
|
function() {
|
|
4478
|
-
console.error('[
|
|
4521
|
+
console.error('[PA-Patcher] JS after failed to load from both remote and local');
|
|
4479
4522
|
// Still remove loading class so content is visible even if JS fails
|
|
4480
4523
|
removeLoadingClass();
|
|
4481
4524
|
}
|
|
@@ -4935,7 +4978,7 @@ var ManifestUpdater = class {
|
|
|
4935
4978
|
const resourceClosePattern = /(\s*)<\/resource>/i;
|
|
4936
4979
|
const match = xmlContent.match(resourceClosePattern);
|
|
4937
4980
|
if (!match) {
|
|
4938
|
-
console.warn("[
|
|
4981
|
+
console.warn("[PA-Patcher] Could not find </resource> tag in imsmanifest.xml");
|
|
4939
4982
|
return [];
|
|
4940
4983
|
}
|
|
4941
4984
|
const updatedXml = xmlContent.replace(
|
|
@@ -4947,7 +4990,7 @@ $1</resource>`
|
|
|
4947
4990
|
zip.updateFile("imsmanifest.xml", Buffer.from(updatedXml, "utf-8"));
|
|
4948
4991
|
return ["imsmanifest.xml"];
|
|
4949
4992
|
} catch (error) {
|
|
4950
|
-
console.error("[
|
|
4993
|
+
console.error("[PA-Patcher] Failed to update imsmanifest.xml:", error);
|
|
4951
4994
|
return [];
|
|
4952
4995
|
}
|
|
4953
4996
|
}
|
|
@@ -5579,7 +5622,7 @@ ${js.after}
|
|
|
5579
5622
|
var pluginRegistry = new PluginRegistry();
|
|
5580
5623
|
|
|
5581
5624
|
// src/patcher/index.ts
|
|
5582
|
-
var DEFAULT_CSS_BEFORE = `/*
|
|
5625
|
+
var DEFAULT_CSS_BEFORE = `/* PA-Patcher: CSS Before (blocking)
|
|
5583
5626
|
* This file loads at the start of <head> and blocks rendering.
|
|
5584
5627
|
* Use it to hide content and prevent flash of unstyled content.
|
|
5585
5628
|
*
|
|
@@ -5589,7 +5632,7 @@ var DEFAULT_CSS_BEFORE = `/* Patch-Adams: CSS Before (blocking)
|
|
|
5589
5632
|
* }
|
|
5590
5633
|
*/
|
|
5591
5634
|
`;
|
|
5592
|
-
var DEFAULT_CSS_AFTER = `/*
|
|
5635
|
+
var DEFAULT_CSS_AFTER = `/* PA-Patcher: CSS After (async)
|
|
5593
5636
|
* This file loads at the end of <head> with remote fallback.
|
|
5594
5637
|
* Use it for style overrides that take precedence over Rise styles.
|
|
5595
5638
|
*
|
|
@@ -5599,7 +5642,7 @@ var DEFAULT_CSS_AFTER = `/* Patch-Adams: CSS After (async)
|
|
|
5599
5642
|
* }
|
|
5600
5643
|
*/
|
|
5601
5644
|
`;
|
|
5602
|
-
var DEFAULT_JS_BEFORE = `//
|
|
5645
|
+
var DEFAULT_JS_BEFORE = `// PA-Patcher: JS Before (blocking)
|
|
5603
5646
|
// This file loads at the start of <head> and blocks rendering.
|
|
5604
5647
|
// Use it for setup, API interception, and preparing globals.
|
|
5605
5648
|
//
|
|
@@ -5609,9 +5652,9 @@ var DEFAULT_JS_BEFORE = `// Patch-Adams: JS Before (blocking)
|
|
|
5609
5652
|
// analytics: true
|
|
5610
5653
|
// };
|
|
5611
5654
|
|
|
5612
|
-
console.log('[
|
|
5655
|
+
console.log('[PA-Patcher] JS Before loaded');
|
|
5613
5656
|
`;
|
|
5614
|
-
var DEFAULT_JS_AFTER = `//
|
|
5657
|
+
var DEFAULT_JS_AFTER = `// PA-Patcher: JS After (async)
|
|
5615
5658
|
// This file loads at the end of <body> with remote fallback.
|
|
5616
5659
|
// Use it for DOM manipulation after Rise has initialized.
|
|
5617
5660
|
//
|
|
@@ -5623,7 +5666,7 @@ var DEFAULT_JS_AFTER = `// Patch-Adams: JS After (async)
|
|
|
5623
5666
|
// // Your modifications here
|
|
5624
5667
|
// });
|
|
5625
5668
|
|
|
5626
|
-
console.log('[
|
|
5669
|
+
console.log('[PA-Patcher] JS After loaded');
|
|
5627
5670
|
`;
|
|
5628
5671
|
var Patcher = class {
|
|
5629
5672
|
config;
|