@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/index.cjs CHANGED
@@ -39,7 +39,11 @@ var LrsBridgeConfigSchema = zod.z.object({
39
39
  /** Course homepage IRI for xAPI context */
40
40
  courseHomepage: zod.z.string().optional(),
41
41
  /** Auto-detect Bravais LRS endpoint from parent frame URL (default: true) */
42
- autoDetectLrs: zod.z.boolean().default(true)
42
+ autoDetectLrs: zod.z.boolean().default(true),
43
+ /** Basic auth credentials for LRS (Base64 encoded "username:password") - used when no cookie session exists */
44
+ lrsAuth: zod.z.string().optional(),
45
+ /** LRS proxy endpoint URL - statements are sent here instead of direct LRS, proxy handles auth server-side */
46
+ lrsProxyEndpoint: zod.z.string().optional()
43
47
  });
44
48
  var BlockingAssetConfigSchema = zod.z.object({
45
49
  /** Filename for the asset */
@@ -382,7 +386,9 @@ var DEFAULT_LRS_OPTIONS = {
382
386
  lrsWithCredentials: true,
383
387
  courseHomepage: "",
384
388
  autoDetectLrs: true,
385
- employeeApiEndpoint: ""
389
+ employeeApiEndpoint: "",
390
+ lrsAuth: "",
391
+ lrsProxyEndpoint: ""
386
392
  };
387
393
  function generateLrsBridgeCode(options) {
388
394
  if (!options.enabled) {
@@ -394,6 +400,8 @@ function generateLrsBridgeCode(options) {
394
400
  const lrsEndpoint = options.lrsEndpoint || "";
395
401
  const courseHomepage = options.courseHomepage || "";
396
402
  const employeeApiEndpoint = options.employeeApiEndpoint || "";
403
+ const lrsAuth = options.lrsAuth || "";
404
+ const lrsProxyEndpoint = options.lrsProxyEndpoint || "";
397
405
  return `
398
406
  // ==========================================================================
399
407
  // PATCH-ADAMS LRS BRIDGE v2.2.0
@@ -406,6 +414,12 @@ function generateLrsBridgeCode(options) {
406
414
  'use strict';
407
415
 
408
416
  var DEBUG = ${options.debug};
417
+ // Allow URL-based debug toggle: ?pa_debug=1 or #pa_debug
418
+ try {
419
+ if (window.location.search.indexOf('pa_debug') > -1 || window.location.hash.indexOf('pa_debug') > -1) {
420
+ DEBUG = true;
421
+ }
422
+ } catch (e) {}
409
423
  var TRACK_MEDIA = ${options.trackMedia};
410
424
  var TRACK_NAVIGATION = ${options.trackNavigation};
411
425
  var TRACK_QUIZZES = ${options.trackQuizzes};
@@ -416,6 +430,8 @@ function generateLrsBridgeCode(options) {
416
430
  var COURSE_HOMEPAGE = '${courseHomepage}';
417
431
  var AUTO_DETECT_LRS = ${options.autoDetectLrs ?? true};
418
432
  var EMPLOYEE_API_ENDPOINT = '${employeeApiEndpoint}';
433
+ var LRS_AUTH = '${lrsAuth}';
434
+ var LRS_PROXY_ENDPOINT = '${lrsProxyEndpoint}';
419
435
 
420
436
  // Bravais LRS endpoint pattern: https://lrs-{tenant}.bravais.com/XAPI/statements
421
437
  // Example: core-acme.bravais.com -> lrs-acme.bravais.com
@@ -2775,6 +2791,17 @@ function generateLrsBridgeCode(options) {
2775
2791
  function sendStatement(statement) {
2776
2792
  log('Sending statement:', statement.verb.display['en-US'] || statement.verb.id, statement);
2777
2793
 
2794
+ // Log first statement visibly (not gated by DEBUG) for production diagnostics
2795
+ if (LRS.stats.statementsSent === 0 && LRS.stats.statementsFailed === 0 && LRS.stats.statementsQueued === 0) {
2796
+ if (window.console && window.console.info) {
2797
+ var verb = statement.verb.display ? (statement.verb.display['en-US'] || statement.verb.id) : statement.verb.id;
2798
+ console.info('[PA-LRS] First statement: verb=' + verb +
2799
+ ', endpoint=' + (LRS_ENDPOINT || 'NONE') +
2800
+ ', proxy=' + (LRS_PROXY_ENDPOINT ? 'yes' : 'no') +
2801
+ ', mode=' + LRS.mode);
2802
+ }
2803
+ }
2804
+
2778
2805
  // Store in event log
2779
2806
  LRS.eventLog.push({
2780
2807
  statement: statement,
@@ -2845,24 +2872,41 @@ function generateLrsBridgeCode(options) {
2845
2872
  }
2846
2873
 
2847
2874
  function sendViaDirectLRS(statement) {
2875
+ // Use proxy endpoint if configured, otherwise direct LRS
2876
+ var useProxy = LRS_PROXY_ENDPOINT && LRS_PROXY_ENDPOINT.length > 0;
2877
+ var endpoint = useProxy ? LRS_PROXY_ENDPOINT : LRS_ENDPOINT;
2878
+
2879
+ if (!endpoint || endpoint.length === 0) {
2880
+ warn('No LRS endpoint available');
2881
+ LRS.stats.statementsFailed++;
2882
+ return Promise.reject(new Error('No LRS endpoint'));
2883
+ }
2884
+
2848
2885
  return new Promise(function(resolve, reject) {
2849
2886
  var xhr = new XMLHttpRequest();
2850
- xhr.open('POST', LRS_ENDPOINT, true);
2887
+ // POST to proxy (proxy handles PUT to LRS), POST to direct LRS
2888
+ xhr.open('POST', endpoint, true);
2851
2889
 
2852
- // xAPI required headers (Bravais LRS requires version 1.0)
2890
+ // xAPI required headers
2853
2891
  xhr.setRequestHeader('Content-Type', 'application/json');
2854
2892
  xhr.setRequestHeader('X-Experience-API-Version', '1.0');
2855
2893
 
2856
- if (LRS_WITH_CREDENTIALS) {
2894
+ if (useProxy) {
2895
+ // Proxy handles auth server-side, no auth headers needed
2896
+ log('Sending via LRS proxy:', endpoint);
2897
+ } else if (LRS_AUTH && LRS_AUTH.length > 0) {
2898
+ xhr.setRequestHeader('Authorization', 'Basic ' + LRS_AUTH);
2899
+ log('Using Basic Auth for LRS request');
2900
+ } else if (LRS_WITH_CREDENTIALS) {
2857
2901
  xhr.withCredentials = true;
2858
2902
  }
2859
2903
 
2860
2904
  xhr.onreadystatechange = function() {
2861
2905
  if (xhr.readyState === 4) {
2862
2906
  if (xhr.status >= 200 && xhr.status < 300) {
2863
- log('Statement sent successfully:', statement.verb.display['en-US']);
2907
+ log('Statement sent successfully:', statement.verb.display['en-US'], useProxy ? '(via proxy)' : '(direct)');
2864
2908
  LRS.stats.statementsSent++;
2865
- resolve({ sent: true, via: 'directLRS', status: xhr.status });
2909
+ resolve({ sent: true, via: useProxy ? 'proxy' : 'directLRS', status: xhr.status });
2866
2910
  } else {
2867
2911
  warn('Statement send failed:', xhr.status, xhr.statusText);
2868
2912
  LRS.stats.statementsFailed++;
@@ -3937,6 +3981,15 @@ function generateLrsBridgeCode(options) {
3937
3981
  LRS.mode = 'offline';
3938
3982
  }
3939
3983
 
3984
+ // Always-visible bridge summary (not gated by DEBUG)
3985
+ // This ensures diagnostics are available even in production builds
3986
+ if (window.console && window.console.info) {
3987
+ console.info('[PA-LRS] Bridge: mode=' + LRS.mode +
3988
+ ', endpoint=' + (LRS_ENDPOINT ? LRS_ENDPOINT.substring(0, 30) + '...' : 'NONE') +
3989
+ ', proxy=' + (LRS_PROXY_ENDPOINT ? 'yes' : 'no') +
3990
+ ', actor=' + (LRS.actor ? (LRS.actor.name || 'anonymous') : 'none'));
3991
+ }
3992
+
3940
3993
  // Set up event interceptors
3941
3994
  setupMediaInterceptors();
3942
3995
  setupNavigationInterceptors();
@@ -4208,7 +4261,9 @@ function buildJsBeforeOptions(config, metadata) {
4208
4261
  lrsEndpoint: lrsBridgeConfig.lrsEndpoint,
4209
4262
  lrsWithCredentials: lrsBridgeConfig.lrsWithCredentials,
4210
4263
  courseHomepage: lrsBridgeConfig.courseHomepage,
4211
- autoDetectLrs: lrsBridgeConfig.autoDetectLrs
4264
+ autoDetectLrs: lrsBridgeConfig.autoDetectLrs,
4265
+ lrsAuth: lrsBridgeConfig.lrsAuth,
4266
+ lrsProxyEndpoint: lrsBridgeConfig.lrsProxyEndpoint
4212
4267
  };
4213
4268
  return {
4214
4269
  remoteUrl: `${config.remoteDomain}/${config.localFolders.js}/${config.jsBefore.filename}`,