@patch-adams/core 1.4.6 → 1.4.8

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
@@ -1995,7 +1995,12 @@ function generateLrsBridgeCode(options) {
1995
1995
  callback(null);
1996
1996
  }
1997
1997
  } else {
1998
- warn('Shared link fetch failed. Status:', xhr.status);
1998
+ // 401/403 is expected - API requires auth that may not be available from iframe
1999
+ if (xhr.status === 401 || xhr.status === 403) {
2000
+ log('Shared link API requires auth (expected), will use fallback');
2001
+ } else {
2002
+ log('Shared link fetch failed. Status:', xhr.status);
2003
+ }
1999
2004
  callback(null);
2000
2005
  }
2001
2006
  }
@@ -2015,15 +2020,11 @@ function generateLrsBridgeCode(options) {
2015
2020
  }
2016
2021
 
2017
2022
  /**
2018
- * Fetch document metadata from Bravais API to get GUIDs
2019
- * Endpoint: /api/v3/documents/{documentId}
2023
+ * Fetch document metadata from Bravais shared API to get GUIDs
2024
+ * PRIMARY endpoint: /api/shared/{token}/documents (does NOT require auth)
2025
+ * FALLBACK endpoint: /api/v3/documents/{documentId} (requires auth)
2020
2026
  */
2021
- function fetchDocumentMetadata(documentId, callback) {
2022
- if (!documentId) {
2023
- callback(null);
2024
- return;
2025
- }
2026
-
2027
+ function fetchDocumentMetadata(documentIdOrToken, callback) {
2027
2028
  if (documentApiFetched) {
2028
2029
  callback(documentApiData);
2029
2030
  return;
@@ -2037,8 +2038,24 @@ function generateLrsBridgeCode(options) {
2037
2038
  return;
2038
2039
  }
2039
2040
 
2040
- var apiUrl = coreUrl + '/api/v3/documents/' + documentId;
2041
- log('Fetching document metadata from:', apiUrl);
2041
+ // Determine which endpoint to use
2042
+ // If we have a shared link token, use /api/shared/{token}/documents (no auth required)
2043
+ // This is the same endpoint Xyleme Cloud Player uses
2044
+ var sharedToken = LRS.courseInfo ? LRS.courseInfo.sharedLinkToken : null;
2045
+ var apiUrl;
2046
+
2047
+ if (sharedToken) {
2048
+ apiUrl = coreUrl + '/api/shared/' + sharedToken + '/documents';
2049
+ log('Fetching document via shared API (no auth required):', apiUrl);
2050
+ } else if (documentIdOrToken) {
2051
+ apiUrl = coreUrl + '/api/v3/documents/' + documentIdOrToken;
2052
+ log('Fetching document via v3 API (requires auth):', apiUrl);
2053
+ } else {
2054
+ log('No shared token or document ID available for metadata fetch');
2055
+ documentApiFetched = true;
2056
+ callback(null);
2057
+ return;
2058
+ }
2042
2059
 
2043
2060
  var xhr = new XMLHttpRequest();
2044
2061
  xhr.open('GET', apiUrl, true);
@@ -2070,7 +2087,12 @@ function generateLrsBridgeCode(options) {
2070
2087
  callback(null);
2071
2088
  }
2072
2089
  } else {
2073
- warn('Document metadata fetch failed. Status:', xhr.status, 'Response:', xhr.responseText);
2090
+ // 401/403 is expected - API requires auth that may not be available from iframe
2091
+ if (xhr.status === 401 || xhr.status === 403) {
2092
+ log('Document API requires auth (expected), will use fallback');
2093
+ } else {
2094
+ log('Document metadata fetch failed. Status:', xhr.status);
2095
+ }
2074
2096
  callback(null);
2075
2097
  }
2076
2098
  }
@@ -2233,6 +2255,95 @@ function generateLrsBridgeCode(options) {
2233
2255
  return null;
2234
2256
  }
2235
2257
 
2258
+ /**
2259
+ * Try to extract document data from Xyleme Cloud Player's internal state
2260
+ * The Cloud Player stores this after fetching /api/shared/{token}/documents
2261
+ */
2262
+ function extractFromXylemeCloudPlayer() {
2263
+ try {
2264
+ var win = window;
2265
+ for (var level = 0; level < 10; level++) {
2266
+ try {
2267
+ // Check for Xyleme Cloud Player's document data in various locations
2268
+ // The player stores data in multiple places depending on version
2269
+
2270
+ // Check for CdsDataService data
2271
+ if (win._cdsDataService && win._cdsDataService.documentData) {
2272
+ var docData = win._cdsDataService.documentData;
2273
+ log('Found document data in _cdsDataService at level', level);
2274
+ return extractGuidsFromDocumentData(docData);
2275
+ }
2276
+
2277
+ // Check for window.documentData
2278
+ if (win.documentData && win.documentData.guid) {
2279
+ log('Found document data in window.documentData at level', level);
2280
+ return extractGuidsFromDocumentData(win.documentData);
2281
+ }
2282
+
2283
+ // Check for PlayerIntegration's internal data
2284
+ if (win.playerIntegration && win.playerIntegration._documentData) {
2285
+ log('Found document data in playerIntegration at level', level);
2286
+ return extractGuidsFromDocumentData(win.playerIntegration._documentData);
2287
+ }
2288
+
2289
+ // Check for __xyleme_data
2290
+ if (win.__xyleme_data && win.__xyleme_data.document) {
2291
+ log('Found document data in __xyleme_data at level', level);
2292
+ return extractGuidsFromDocumentData(win.__xyleme_data.document);
2293
+ }
2294
+
2295
+ // Check for documentVersionData which has the versionGuid
2296
+ if (win.documentVersionData) {
2297
+ log('Found documentVersionData at level', level);
2298
+ return {
2299
+ versionGuid: win.documentVersionData.guid || win.documentVersionData.versionGuid,
2300
+ documentId: win.documentVersionData.documentId
2301
+ };
2302
+ }
2303
+
2304
+ } catch (e) {}
2305
+
2306
+ if (win.parent && win.parent !== win) {
2307
+ win = win.parent;
2308
+ } else {
2309
+ break;
2310
+ }
2311
+ }
2312
+ } catch (e) {}
2313
+ return null;
2314
+ }
2315
+
2316
+ function extractGuidsFromDocumentData(data) {
2317
+ if (!data) return null;
2318
+
2319
+ var result = {};
2320
+
2321
+ // Document GUID
2322
+ if (data.guid) result.guid = data.guid;
2323
+ if (data.documentGuid) result.guid = data.documentGuid;
2324
+
2325
+ // Version GUID - usually in latestVersion or currentVersion
2326
+ if (data.latestVersion && data.latestVersion.guid) {
2327
+ result.versionGuid = data.latestVersion.guid;
2328
+ }
2329
+ if (data.currentVersion && data.currentVersion.guid) {
2330
+ result.versionGuid = data.currentVersion.guid;
2331
+ }
2332
+ if (data.versionGuid) result.versionGuid = data.versionGuid;
2333
+
2334
+ // Numeric IDs
2335
+ if (data.id) result.documentId = data.id;
2336
+ if (data.documentId) result.documentId = data.documentId;
2337
+ if (data.cdsId) result.documentId = data.cdsId;
2338
+
2339
+ // Title
2340
+ if (data.name) result.title = data.name;
2341
+ if (data.title) result.title = data.title;
2342
+
2343
+ log('Extracted GUIDs from Cloud Player:', result);
2344
+ return Object.keys(result).length > 0 ? result : null;
2345
+ }
2346
+
2236
2347
  function extractCourseInfo() {
2237
2348
  var info = {
2238
2349
  // Xyleme IRI format: http://xyleme.com/bravais/document/{guid}
@@ -2288,6 +2399,23 @@ function generateLrsBridgeCode(options) {
2288
2399
  info.sharedLinkName = launchInfo.sharedLinkName || info.sharedLinkName;
2289
2400
  }
2290
2401
 
2402
+ // 3b. Try to extract GUIDs from Xyleme Cloud Player's internal data
2403
+ // This is more reliable than API calls which may fail with 401
2404
+ if (!info.guid || !info.versionGuid) {
2405
+ var cloudPlayerData = extractFromXylemeCloudPlayer();
2406
+ if (cloudPlayerData) {
2407
+ info.guid = cloudPlayerData.guid || info.guid;
2408
+ info.versionGuid = cloudPlayerData.versionGuid || info.versionGuid;
2409
+ info.documentId = cloudPlayerData.documentId || info.documentId;
2410
+ info.title = cloudPlayerData.title || info.title;
2411
+ log('Updated course info from Cloud Player:', {
2412
+ guid: info.guid,
2413
+ versionGuid: info.versionGuid,
2414
+ documentId: info.documentId
2415
+ });
2416
+ }
2417
+ }
2418
+
2291
2419
  // 4. Try getCourseTitle() from preloadIntegrity.js
2292
2420
  var preloadTitle = extractCourseTitleFromPreload();
2293
2421
  if (preloadTitle) {
@@ -3793,7 +3921,7 @@ function generateLrsBridgeCode(options) {
3793
3921
  // ========================================================================
3794
3922
 
3795
3923
  function init() {
3796
- log('Initializing LRS bridge v2.5.1...');
3924
+ log('Initializing LRS bridge v2.6.0...');
3797
3925
 
3798
3926
  // Extract course info early
3799
3927
  extractCourseInfo();
@@ -3862,32 +3990,25 @@ function generateLrsBridgeCode(options) {
3862
3990
  }
3863
3991
 
3864
3992
  if (!LRS.courseInfo.guid) {
3865
- // First, try to get real document ID from shared link token
3866
- // The URL path contains a thin pack file ID, not the real document ID
3993
+ // When we have a shared link token, use /api/shared/{token}/documents directly
3994
+ // This endpoint does NOT require authentication and returns both document GUID and version GUID
3867
3995
  if (sharedLinkToken) {
3868
- log('Fetching shared link data to get real document ID...');
3869
- fetchSharedLinkData(sharedLinkToken, function(linkData) {
3870
- if (linkData && linkData.documentId) {
3871
- // Got the real document ID from shared link
3872
- log('Got real document ID from shared link:', linkData.documentId);
3873
- LRS.courseInfo.documentId = linkData.documentId;
3874
- // Update shared link name if available
3875
- if (linkData.documentName) {
3876
- LRS.courseInfo.sharedLinkName = linkData.documentName;
3996
+ log('Have shared link token, fetching document data via shared API...');
3997
+ // fetchDocumentMetadata will use /api/shared/{token}/documents when sharedLinkToken is present
3998
+ fetchDocumentMetadata(null, function(docData) {
3999
+ if (docData) {
4000
+ updateCourseInfoFromApi(docData);
4001
+ // Also update document name if available
4002
+ if (docData.name) {
4003
+ LRS.courseInfo.sharedLinkName = docData.name;
3877
4004
  }
3878
- fetchDocDataAndSend(linkData.documentId);
3879
- } else if (documentId) {
3880
- // Fallback to extracted document ID (may be thin pack ID)
3881
- warn('Could not get document ID from shared link, using extracted ID:', documentId);
3882
- fetchDocDataAndSend(documentId);
3883
4005
  } else {
3884
- // No document ID available
3885
- warn('No document ID available - statements may fail aggregation');
3886
- setTimeout(sendLaunchEvents, 100);
4006
+ warn('Could not fetch document data from shared API - statements may fail aggregation');
3887
4007
  }
4008
+ setTimeout(sendLaunchEvents, 100);
3888
4009
  });
3889
4010
  } else if (documentId) {
3890
- // No shared link token, try with extracted document ID
4011
+ // No shared link token, try with extracted document ID (requires auth)
3891
4012
  log('No shared link token, fetching document data with ID:', documentId);
3892
4013
  fetchDocDataAndSend(documentId);
3893
4014
  } else {