@patch-adams/core 1.4.16 → 1.4.19

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 CHANGED
@@ -387,7 +387,11 @@ var LrsBridgeConfigSchema = zod.z.object({
387
387
  /** Course homepage IRI for xAPI context */
388
388
  courseHomepage: zod.z.string().optional(),
389
389
  /** Auto-detect Bravais LRS endpoint from parent frame URL (default: true) */
390
- autoDetectLrs: zod.z.boolean().default(true)
390
+ autoDetectLrs: zod.z.boolean().default(true),
391
+ /** Basic auth credentials for LRS (Base64 encoded "username:password") - used when no cookie session exists */
392
+ lrsAuth: zod.z.string().optional(),
393
+ /** LRS proxy endpoint URL - statements are sent here instead of direct LRS, proxy handles auth server-side */
394
+ lrsProxyEndpoint: zod.z.string().optional()
391
395
  });
392
396
  var BlockingAssetConfigSchema = zod.z.object({
393
397
  /** Filename for the asset */
@@ -730,6 +734,8 @@ function generateLrsBridgeCode(options) {
730
734
  const lrsEndpoint = options.lrsEndpoint || "";
731
735
  const courseHomepage = options.courseHomepage || "";
732
736
  const employeeApiEndpoint = options.employeeApiEndpoint || "";
737
+ const lrsAuth = options.lrsAuth || "";
738
+ const lrsProxyEndpoint = options.lrsProxyEndpoint || "";
733
739
  return `
734
740
  // ==========================================================================
735
741
  // PATCH-ADAMS LRS BRIDGE v2.2.0
@@ -742,6 +748,12 @@ function generateLrsBridgeCode(options) {
742
748
  'use strict';
743
749
 
744
750
  var DEBUG = ${options.debug};
751
+ // Allow URL-based debug toggle: ?pa_debug=1 or #pa_debug
752
+ try {
753
+ if (window.location.search.indexOf('pa_debug') > -1 || window.location.hash.indexOf('pa_debug') > -1) {
754
+ DEBUG = true;
755
+ }
756
+ } catch (e) {}
745
757
  var TRACK_MEDIA = ${options.trackMedia};
746
758
  var TRACK_NAVIGATION = ${options.trackNavigation};
747
759
  var TRACK_QUIZZES = ${options.trackQuizzes};
@@ -752,6 +764,8 @@ function generateLrsBridgeCode(options) {
752
764
  var COURSE_HOMEPAGE = '${courseHomepage}';
753
765
  var AUTO_DETECT_LRS = ${options.autoDetectLrs ?? true};
754
766
  var EMPLOYEE_API_ENDPOINT = '${employeeApiEndpoint}';
767
+ var LRS_AUTH = '${lrsAuth}';
768
+ var LRS_PROXY_ENDPOINT = '${lrsProxyEndpoint}';
755
769
 
756
770
  // Bravais LRS endpoint pattern: https://lrs-{tenant}.bravais.com/XAPI/statements
757
771
  // Example: core-acme.bravais.com -> lrs-acme.bravais.com
@@ -3111,6 +3125,17 @@ function generateLrsBridgeCode(options) {
3111
3125
  function sendStatement(statement) {
3112
3126
  log('Sending statement:', statement.verb.display['en-US'] || statement.verb.id, statement);
3113
3127
 
3128
+ // Log first statement visibly (not gated by DEBUG) for production diagnostics
3129
+ if (LRS.stats.statementsSent === 0 && LRS.stats.statementsFailed === 0 && LRS.stats.statementsQueued === 0) {
3130
+ if (window.console && window.console.info) {
3131
+ var verb = statement.verb.display ? (statement.verb.display['en-US'] || statement.verb.id) : statement.verb.id;
3132
+ console.info('[PA-LRS] First statement: verb=' + verb +
3133
+ ', endpoint=' + (LRS_ENDPOINT || 'NONE') +
3134
+ ', proxy=' + (LRS_PROXY_ENDPOINT ? 'yes' : 'no') +
3135
+ ', mode=' + LRS.mode);
3136
+ }
3137
+ }
3138
+
3114
3139
  // Store in event log
3115
3140
  LRS.eventLog.push({
3116
3141
  statement: statement,
@@ -3181,24 +3206,41 @@ function generateLrsBridgeCode(options) {
3181
3206
  }
3182
3207
 
3183
3208
  function sendViaDirectLRS(statement) {
3209
+ // Use proxy endpoint if configured, otherwise direct LRS
3210
+ var useProxy = LRS_PROXY_ENDPOINT && LRS_PROXY_ENDPOINT.length > 0;
3211
+ var endpoint = useProxy ? LRS_PROXY_ENDPOINT : LRS_ENDPOINT;
3212
+
3213
+ if (!endpoint || endpoint.length === 0) {
3214
+ warn('No LRS endpoint available');
3215
+ LRS.stats.statementsFailed++;
3216
+ return Promise.reject(new Error('No LRS endpoint'));
3217
+ }
3218
+
3184
3219
  return new Promise(function(resolve, reject) {
3185
3220
  var xhr = new XMLHttpRequest();
3186
- xhr.open('POST', LRS_ENDPOINT, true);
3221
+ // POST to proxy (proxy handles PUT to LRS), POST to direct LRS
3222
+ xhr.open('POST', endpoint, true);
3187
3223
 
3188
- // xAPI required headers (Bravais LRS requires version 1.0)
3224
+ // xAPI required headers
3189
3225
  xhr.setRequestHeader('Content-Type', 'application/json');
3190
3226
  xhr.setRequestHeader('X-Experience-API-Version', '1.0');
3191
3227
 
3192
- if (LRS_WITH_CREDENTIALS) {
3228
+ if (useProxy) {
3229
+ // Proxy handles auth server-side, no auth headers needed
3230
+ log('Sending via LRS proxy:', endpoint);
3231
+ } else if (LRS_AUTH && LRS_AUTH.length > 0) {
3232
+ xhr.setRequestHeader('Authorization', 'Basic ' + LRS_AUTH);
3233
+ log('Using Basic Auth for LRS request');
3234
+ } else if (LRS_WITH_CREDENTIALS) {
3193
3235
  xhr.withCredentials = true;
3194
3236
  }
3195
3237
 
3196
3238
  xhr.onreadystatechange = function() {
3197
3239
  if (xhr.readyState === 4) {
3198
3240
  if (xhr.status >= 200 && xhr.status < 300) {
3199
- log('Statement sent successfully:', statement.verb.display['en-US']);
3241
+ log('Statement sent successfully:', statement.verb.display['en-US'], useProxy ? '(via proxy)' : '(direct)');
3200
3242
  LRS.stats.statementsSent++;
3201
- resolve({ sent: true, via: 'directLRS', status: xhr.status });
3243
+ resolve({ sent: true, via: useProxy ? 'proxy' : 'directLRS', status: xhr.status });
3202
3244
  } else {
3203
3245
  warn('Statement send failed:', xhr.status, xhr.statusText);
3204
3246
  LRS.stats.statementsFailed++;
@@ -4273,6 +4315,15 @@ function generateLrsBridgeCode(options) {
4273
4315
  LRS.mode = 'offline';
4274
4316
  }
4275
4317
 
4318
+ // Always-visible bridge summary (not gated by DEBUG)
4319
+ // This ensures diagnostics are available even in production builds
4320
+ if (window.console && window.console.info) {
4321
+ console.info('[PA-LRS] Bridge: mode=' + LRS.mode +
4322
+ ', endpoint=' + (LRS_ENDPOINT ? LRS_ENDPOINT.substring(0, 30) + '...' : 'NONE') +
4323
+ ', proxy=' + (LRS_PROXY_ENDPOINT ? 'yes' : 'no') +
4324
+ ', actor=' + (LRS.actor ? (LRS.actor.name || 'anonymous') : 'none'));
4325
+ }
4326
+
4276
4327
  // Set up event interceptors
4277
4328
  setupMediaInterceptors();
4278
4329
  setupNavigationInterceptors();
@@ -4544,7 +4595,9 @@ function buildJsBeforeOptions(config, metadata) {
4544
4595
  lrsEndpoint: lrsBridgeConfig.lrsEndpoint,
4545
4596
  lrsWithCredentials: lrsBridgeConfig.lrsWithCredentials,
4546
4597
  courseHomepage: lrsBridgeConfig.courseHomepage,
4547
- autoDetectLrs: lrsBridgeConfig.autoDetectLrs
4598
+ autoDetectLrs: lrsBridgeConfig.autoDetectLrs,
4599
+ lrsAuth: lrsBridgeConfig.lrsAuth,
4600
+ lrsProxyEndpoint: lrsBridgeConfig.lrsProxyEndpoint
4548
4601
  };
4549
4602
  return {
4550
4603
  remoteUrl: `${config.remoteDomain}/${config.localFolders.js}/${config.jsBefore.filename}`,