@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/index.js CHANGED
@@ -1651,7 +1651,12 @@ function generateLrsBridgeCode(options) {
1651
1651
  callback(null);
1652
1652
  }
1653
1653
  } else {
1654
- warn('Shared link fetch failed. Status:', xhr.status);
1654
+ // 401/403 is expected - API requires auth that may not be available from iframe
1655
+ if (xhr.status === 401 || xhr.status === 403) {
1656
+ log('Shared link API requires auth (expected), will use fallback');
1657
+ } else {
1658
+ log('Shared link fetch failed. Status:', xhr.status);
1659
+ }
1655
1660
  callback(null);
1656
1661
  }
1657
1662
  }
@@ -1671,15 +1676,11 @@ function generateLrsBridgeCode(options) {
1671
1676
  }
1672
1677
 
1673
1678
  /**
1674
- * Fetch document metadata from Bravais API to get GUIDs
1675
- * Endpoint: /api/v3/documents/{documentId}
1679
+ * Fetch document metadata from Bravais shared API to get GUIDs
1680
+ * PRIMARY endpoint: /api/shared/{token}/documents (does NOT require auth)
1681
+ * FALLBACK endpoint: /api/v3/documents/{documentId} (requires auth)
1676
1682
  */
1677
- function fetchDocumentMetadata(documentId, callback) {
1678
- if (!documentId) {
1679
- callback(null);
1680
- return;
1681
- }
1682
-
1683
+ function fetchDocumentMetadata(documentIdOrToken, callback) {
1683
1684
  if (documentApiFetched) {
1684
1685
  callback(documentApiData);
1685
1686
  return;
@@ -1693,8 +1694,24 @@ function generateLrsBridgeCode(options) {
1693
1694
  return;
1694
1695
  }
1695
1696
 
1696
- var apiUrl = coreUrl + '/api/v3/documents/' + documentId;
1697
- log('Fetching document metadata from:', apiUrl);
1697
+ // Determine which endpoint to use
1698
+ // If we have a shared link token, use /api/shared/{token}/documents (no auth required)
1699
+ // This is the same endpoint Xyleme Cloud Player uses
1700
+ var sharedToken = LRS.courseInfo ? LRS.courseInfo.sharedLinkToken : null;
1701
+ var apiUrl;
1702
+
1703
+ if (sharedToken) {
1704
+ apiUrl = coreUrl + '/api/shared/' + sharedToken + '/documents';
1705
+ log('Fetching document via shared API (no auth required):', apiUrl);
1706
+ } else if (documentIdOrToken) {
1707
+ apiUrl = coreUrl + '/api/v3/documents/' + documentIdOrToken;
1708
+ log('Fetching document via v3 API (requires auth):', apiUrl);
1709
+ } else {
1710
+ log('No shared token or document ID available for metadata fetch');
1711
+ documentApiFetched = true;
1712
+ callback(null);
1713
+ return;
1714
+ }
1698
1715
 
1699
1716
  var xhr = new XMLHttpRequest();
1700
1717
  xhr.open('GET', apiUrl, true);
@@ -1726,7 +1743,12 @@ function generateLrsBridgeCode(options) {
1726
1743
  callback(null);
1727
1744
  }
1728
1745
  } else {
1729
- warn('Document metadata fetch failed. Status:', xhr.status, 'Response:', xhr.responseText);
1746
+ // 401/403 is expected - API requires auth that may not be available from iframe
1747
+ if (xhr.status === 401 || xhr.status === 403) {
1748
+ log('Document API requires auth (expected), will use fallback');
1749
+ } else {
1750
+ log('Document metadata fetch failed. Status:', xhr.status);
1751
+ }
1730
1752
  callback(null);
1731
1753
  }
1732
1754
  }
@@ -1889,6 +1911,95 @@ function generateLrsBridgeCode(options) {
1889
1911
  return null;
1890
1912
  }
1891
1913
 
1914
+ /**
1915
+ * Try to extract document data from Xyleme Cloud Player's internal state
1916
+ * The Cloud Player stores this after fetching /api/shared/{token}/documents
1917
+ */
1918
+ function extractFromXylemeCloudPlayer() {
1919
+ try {
1920
+ var win = window;
1921
+ for (var level = 0; level < 10; level++) {
1922
+ try {
1923
+ // Check for Xyleme Cloud Player's document data in various locations
1924
+ // The player stores data in multiple places depending on version
1925
+
1926
+ // Check for CdsDataService data
1927
+ if (win._cdsDataService && win._cdsDataService.documentData) {
1928
+ var docData = win._cdsDataService.documentData;
1929
+ log('Found document data in _cdsDataService at level', level);
1930
+ return extractGuidsFromDocumentData(docData);
1931
+ }
1932
+
1933
+ // Check for window.documentData
1934
+ if (win.documentData && win.documentData.guid) {
1935
+ log('Found document data in window.documentData at level', level);
1936
+ return extractGuidsFromDocumentData(win.documentData);
1937
+ }
1938
+
1939
+ // Check for PlayerIntegration's internal data
1940
+ if (win.playerIntegration && win.playerIntegration._documentData) {
1941
+ log('Found document data in playerIntegration at level', level);
1942
+ return extractGuidsFromDocumentData(win.playerIntegration._documentData);
1943
+ }
1944
+
1945
+ // Check for __xyleme_data
1946
+ if (win.__xyleme_data && win.__xyleme_data.document) {
1947
+ log('Found document data in __xyleme_data at level', level);
1948
+ return extractGuidsFromDocumentData(win.__xyleme_data.document);
1949
+ }
1950
+
1951
+ // Check for documentVersionData which has the versionGuid
1952
+ if (win.documentVersionData) {
1953
+ log('Found documentVersionData at level', level);
1954
+ return {
1955
+ versionGuid: win.documentVersionData.guid || win.documentVersionData.versionGuid,
1956
+ documentId: win.documentVersionData.documentId
1957
+ };
1958
+ }
1959
+
1960
+ } catch (e) {}
1961
+
1962
+ if (win.parent && win.parent !== win) {
1963
+ win = win.parent;
1964
+ } else {
1965
+ break;
1966
+ }
1967
+ }
1968
+ } catch (e) {}
1969
+ return null;
1970
+ }
1971
+
1972
+ function extractGuidsFromDocumentData(data) {
1973
+ if (!data) return null;
1974
+
1975
+ var result = {};
1976
+
1977
+ // Document GUID
1978
+ if (data.guid) result.guid = data.guid;
1979
+ if (data.documentGuid) result.guid = data.documentGuid;
1980
+
1981
+ // Version GUID - usually in latestVersion or currentVersion
1982
+ if (data.latestVersion && data.latestVersion.guid) {
1983
+ result.versionGuid = data.latestVersion.guid;
1984
+ }
1985
+ if (data.currentVersion && data.currentVersion.guid) {
1986
+ result.versionGuid = data.currentVersion.guid;
1987
+ }
1988
+ if (data.versionGuid) result.versionGuid = data.versionGuid;
1989
+
1990
+ // Numeric IDs
1991
+ if (data.id) result.documentId = data.id;
1992
+ if (data.documentId) result.documentId = data.documentId;
1993
+ if (data.cdsId) result.documentId = data.cdsId;
1994
+
1995
+ // Title
1996
+ if (data.name) result.title = data.name;
1997
+ if (data.title) result.title = data.title;
1998
+
1999
+ log('Extracted GUIDs from Cloud Player:', result);
2000
+ return Object.keys(result).length > 0 ? result : null;
2001
+ }
2002
+
1892
2003
  function extractCourseInfo() {
1893
2004
  var info = {
1894
2005
  // Xyleme IRI format: http://xyleme.com/bravais/document/{guid}
@@ -1944,6 +2055,23 @@ function generateLrsBridgeCode(options) {
1944
2055
  info.sharedLinkName = launchInfo.sharedLinkName || info.sharedLinkName;
1945
2056
  }
1946
2057
 
2058
+ // 3b. Try to extract GUIDs from Xyleme Cloud Player's internal data
2059
+ // This is more reliable than API calls which may fail with 401
2060
+ if (!info.guid || !info.versionGuid) {
2061
+ var cloudPlayerData = extractFromXylemeCloudPlayer();
2062
+ if (cloudPlayerData) {
2063
+ info.guid = cloudPlayerData.guid || info.guid;
2064
+ info.versionGuid = cloudPlayerData.versionGuid || info.versionGuid;
2065
+ info.documentId = cloudPlayerData.documentId || info.documentId;
2066
+ info.title = cloudPlayerData.title || info.title;
2067
+ log('Updated course info from Cloud Player:', {
2068
+ guid: info.guid,
2069
+ versionGuid: info.versionGuid,
2070
+ documentId: info.documentId
2071
+ });
2072
+ }
2073
+ }
2074
+
1947
2075
  // 4. Try getCourseTitle() from preloadIntegrity.js
1948
2076
  var preloadTitle = extractCourseTitleFromPreload();
1949
2077
  if (preloadTitle) {
@@ -3449,7 +3577,7 @@ function generateLrsBridgeCode(options) {
3449
3577
  // ========================================================================
3450
3578
 
3451
3579
  function init() {
3452
- log('Initializing LRS bridge v2.5.1...');
3580
+ log('Initializing LRS bridge v2.6.0...');
3453
3581
 
3454
3582
  // Extract course info early
3455
3583
  extractCourseInfo();
@@ -3518,32 +3646,25 @@ function generateLrsBridgeCode(options) {
3518
3646
  }
3519
3647
 
3520
3648
  if (!LRS.courseInfo.guid) {
3521
- // First, try to get real document ID from shared link token
3522
- // The URL path contains a thin pack file ID, not the real document ID
3649
+ // When we have a shared link token, use /api/shared/{token}/documents directly
3650
+ // This endpoint does NOT require authentication and returns both document GUID and version GUID
3523
3651
  if (sharedLinkToken) {
3524
- log('Fetching shared link data to get real document ID...');
3525
- fetchSharedLinkData(sharedLinkToken, function(linkData) {
3526
- if (linkData && linkData.documentId) {
3527
- // Got the real document ID from shared link
3528
- log('Got real document ID from shared link:', linkData.documentId);
3529
- LRS.courseInfo.documentId = linkData.documentId;
3530
- // Update shared link name if available
3531
- if (linkData.documentName) {
3532
- LRS.courseInfo.sharedLinkName = linkData.documentName;
3652
+ log('Have shared link token, fetching document data via shared API...');
3653
+ // fetchDocumentMetadata will use /api/shared/{token}/documents when sharedLinkToken is present
3654
+ fetchDocumentMetadata(null, function(docData) {
3655
+ if (docData) {
3656
+ updateCourseInfoFromApi(docData);
3657
+ // Also update document name if available
3658
+ if (docData.name) {
3659
+ LRS.courseInfo.sharedLinkName = docData.name;
3533
3660
  }
3534
- fetchDocDataAndSend(linkData.documentId);
3535
- } else if (documentId) {
3536
- // Fallback to extracted document ID (may be thin pack ID)
3537
- warn('Could not get document ID from shared link, using extracted ID:', documentId);
3538
- fetchDocDataAndSend(documentId);
3539
3661
  } else {
3540
- // No document ID available
3541
- warn('No document ID available - statements may fail aggregation');
3542
- setTimeout(sendLaunchEvents, 100);
3662
+ warn('Could not fetch document data from shared API - statements may fail aggregation');
3543
3663
  }
3664
+ setTimeout(sendLaunchEvents, 100);
3544
3665
  });
3545
3666
  } else if (documentId) {
3546
- // No shared link token, try with extracted document ID
3667
+ // No shared link token, try with extracted document ID (requires auth)
3547
3668
  log('No shared link token, fetching document data with ID:', documentId);
3548
3669
  fetchDocDataAndSend(documentId);
3549
3670
  } else {