@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.cjs CHANGED
@@ -1659,7 +1659,12 @@ function generateLrsBridgeCode(options) {
1659
1659
  callback(null);
1660
1660
  }
1661
1661
  } else {
1662
- warn('Shared link fetch failed. Status:', xhr.status);
1662
+ // 401/403 is expected - API requires auth that may not be available from iframe
1663
+ if (xhr.status === 401 || xhr.status === 403) {
1664
+ log('Shared link API requires auth (expected), will use fallback');
1665
+ } else {
1666
+ log('Shared link fetch failed. Status:', xhr.status);
1667
+ }
1663
1668
  callback(null);
1664
1669
  }
1665
1670
  }
@@ -1679,15 +1684,11 @@ function generateLrsBridgeCode(options) {
1679
1684
  }
1680
1685
 
1681
1686
  /**
1682
- * Fetch document metadata from Bravais API to get GUIDs
1683
- * Endpoint: /api/v3/documents/{documentId}
1687
+ * Fetch document metadata from Bravais shared API to get GUIDs
1688
+ * PRIMARY endpoint: /api/shared/{token}/documents (does NOT require auth)
1689
+ * FALLBACK endpoint: /api/v3/documents/{documentId} (requires auth)
1684
1690
  */
1685
- function fetchDocumentMetadata(documentId, callback) {
1686
- if (!documentId) {
1687
- callback(null);
1688
- return;
1689
- }
1690
-
1691
+ function fetchDocumentMetadata(documentIdOrToken, callback) {
1691
1692
  if (documentApiFetched) {
1692
1693
  callback(documentApiData);
1693
1694
  return;
@@ -1701,8 +1702,24 @@ function generateLrsBridgeCode(options) {
1701
1702
  return;
1702
1703
  }
1703
1704
 
1704
- var apiUrl = coreUrl + '/api/v3/documents/' + documentId;
1705
- log('Fetching document metadata from:', apiUrl);
1705
+ // Determine which endpoint to use
1706
+ // If we have a shared link token, use /api/shared/{token}/documents (no auth required)
1707
+ // This is the same endpoint Xyleme Cloud Player uses
1708
+ var sharedToken = LRS.courseInfo ? LRS.courseInfo.sharedLinkToken : null;
1709
+ var apiUrl;
1710
+
1711
+ if (sharedToken) {
1712
+ apiUrl = coreUrl + '/api/shared/' + sharedToken + '/documents';
1713
+ log('Fetching document via shared API (no auth required):', apiUrl);
1714
+ } else if (documentIdOrToken) {
1715
+ apiUrl = coreUrl + '/api/v3/documents/' + documentIdOrToken;
1716
+ log('Fetching document via v3 API (requires auth):', apiUrl);
1717
+ } else {
1718
+ log('No shared token or document ID available for metadata fetch');
1719
+ documentApiFetched = true;
1720
+ callback(null);
1721
+ return;
1722
+ }
1706
1723
 
1707
1724
  var xhr = new XMLHttpRequest();
1708
1725
  xhr.open('GET', apiUrl, true);
@@ -1734,7 +1751,12 @@ function generateLrsBridgeCode(options) {
1734
1751
  callback(null);
1735
1752
  }
1736
1753
  } else {
1737
- warn('Document metadata fetch failed. Status:', xhr.status, 'Response:', xhr.responseText);
1754
+ // 401/403 is expected - API requires auth that may not be available from iframe
1755
+ if (xhr.status === 401 || xhr.status === 403) {
1756
+ log('Document API requires auth (expected), will use fallback');
1757
+ } else {
1758
+ log('Document metadata fetch failed. Status:', xhr.status);
1759
+ }
1738
1760
  callback(null);
1739
1761
  }
1740
1762
  }
@@ -1897,6 +1919,95 @@ function generateLrsBridgeCode(options) {
1897
1919
  return null;
1898
1920
  }
1899
1921
 
1922
+ /**
1923
+ * Try to extract document data from Xyleme Cloud Player's internal state
1924
+ * The Cloud Player stores this after fetching /api/shared/{token}/documents
1925
+ */
1926
+ function extractFromXylemeCloudPlayer() {
1927
+ try {
1928
+ var win = window;
1929
+ for (var level = 0; level < 10; level++) {
1930
+ try {
1931
+ // Check for Xyleme Cloud Player's document data in various locations
1932
+ // The player stores data in multiple places depending on version
1933
+
1934
+ // Check for CdsDataService data
1935
+ if (win._cdsDataService && win._cdsDataService.documentData) {
1936
+ var docData = win._cdsDataService.documentData;
1937
+ log('Found document data in _cdsDataService at level', level);
1938
+ return extractGuidsFromDocumentData(docData);
1939
+ }
1940
+
1941
+ // Check for window.documentData
1942
+ if (win.documentData && win.documentData.guid) {
1943
+ log('Found document data in window.documentData at level', level);
1944
+ return extractGuidsFromDocumentData(win.documentData);
1945
+ }
1946
+
1947
+ // Check for PlayerIntegration's internal data
1948
+ if (win.playerIntegration && win.playerIntegration._documentData) {
1949
+ log('Found document data in playerIntegration at level', level);
1950
+ return extractGuidsFromDocumentData(win.playerIntegration._documentData);
1951
+ }
1952
+
1953
+ // Check for __xyleme_data
1954
+ if (win.__xyleme_data && win.__xyleme_data.document) {
1955
+ log('Found document data in __xyleme_data at level', level);
1956
+ return extractGuidsFromDocumentData(win.__xyleme_data.document);
1957
+ }
1958
+
1959
+ // Check for documentVersionData which has the versionGuid
1960
+ if (win.documentVersionData) {
1961
+ log('Found documentVersionData at level', level);
1962
+ return {
1963
+ versionGuid: win.documentVersionData.guid || win.documentVersionData.versionGuid,
1964
+ documentId: win.documentVersionData.documentId
1965
+ };
1966
+ }
1967
+
1968
+ } catch (e) {}
1969
+
1970
+ if (win.parent && win.parent !== win) {
1971
+ win = win.parent;
1972
+ } else {
1973
+ break;
1974
+ }
1975
+ }
1976
+ } catch (e) {}
1977
+ return null;
1978
+ }
1979
+
1980
+ function extractGuidsFromDocumentData(data) {
1981
+ if (!data) return null;
1982
+
1983
+ var result = {};
1984
+
1985
+ // Document GUID
1986
+ if (data.guid) result.guid = data.guid;
1987
+ if (data.documentGuid) result.guid = data.documentGuid;
1988
+
1989
+ // Version GUID - usually in latestVersion or currentVersion
1990
+ if (data.latestVersion && data.latestVersion.guid) {
1991
+ result.versionGuid = data.latestVersion.guid;
1992
+ }
1993
+ if (data.currentVersion && data.currentVersion.guid) {
1994
+ result.versionGuid = data.currentVersion.guid;
1995
+ }
1996
+ if (data.versionGuid) result.versionGuid = data.versionGuid;
1997
+
1998
+ // Numeric IDs
1999
+ if (data.id) result.documentId = data.id;
2000
+ if (data.documentId) result.documentId = data.documentId;
2001
+ if (data.cdsId) result.documentId = data.cdsId;
2002
+
2003
+ // Title
2004
+ if (data.name) result.title = data.name;
2005
+ if (data.title) result.title = data.title;
2006
+
2007
+ log('Extracted GUIDs from Cloud Player:', result);
2008
+ return Object.keys(result).length > 0 ? result : null;
2009
+ }
2010
+
1900
2011
  function extractCourseInfo() {
1901
2012
  var info = {
1902
2013
  // Xyleme IRI format: http://xyleme.com/bravais/document/{guid}
@@ -1952,6 +2063,23 @@ function generateLrsBridgeCode(options) {
1952
2063
  info.sharedLinkName = launchInfo.sharedLinkName || info.sharedLinkName;
1953
2064
  }
1954
2065
 
2066
+ // 3b. Try to extract GUIDs from Xyleme Cloud Player's internal data
2067
+ // This is more reliable than API calls which may fail with 401
2068
+ if (!info.guid || !info.versionGuid) {
2069
+ var cloudPlayerData = extractFromXylemeCloudPlayer();
2070
+ if (cloudPlayerData) {
2071
+ info.guid = cloudPlayerData.guid || info.guid;
2072
+ info.versionGuid = cloudPlayerData.versionGuid || info.versionGuid;
2073
+ info.documentId = cloudPlayerData.documentId || info.documentId;
2074
+ info.title = cloudPlayerData.title || info.title;
2075
+ log('Updated course info from Cloud Player:', {
2076
+ guid: info.guid,
2077
+ versionGuid: info.versionGuid,
2078
+ documentId: info.documentId
2079
+ });
2080
+ }
2081
+ }
2082
+
1955
2083
  // 4. Try getCourseTitle() from preloadIntegrity.js
1956
2084
  var preloadTitle = extractCourseTitleFromPreload();
1957
2085
  if (preloadTitle) {
@@ -3457,7 +3585,7 @@ function generateLrsBridgeCode(options) {
3457
3585
  // ========================================================================
3458
3586
 
3459
3587
  function init() {
3460
- log('Initializing LRS bridge v2.5.1...');
3588
+ log('Initializing LRS bridge v2.6.0...');
3461
3589
 
3462
3590
  // Extract course info early
3463
3591
  extractCourseInfo();
@@ -3526,32 +3654,25 @@ function generateLrsBridgeCode(options) {
3526
3654
  }
3527
3655
 
3528
3656
  if (!LRS.courseInfo.guid) {
3529
- // First, try to get real document ID from shared link token
3530
- // The URL path contains a thin pack file ID, not the real document ID
3657
+ // When we have a shared link token, use /api/shared/{token}/documents directly
3658
+ // This endpoint does NOT require authentication and returns both document GUID and version GUID
3531
3659
  if (sharedLinkToken) {
3532
- log('Fetching shared link data to get real document ID...');
3533
- fetchSharedLinkData(sharedLinkToken, function(linkData) {
3534
- if (linkData && linkData.documentId) {
3535
- // Got the real document ID from shared link
3536
- log('Got real document ID from shared link:', linkData.documentId);
3537
- LRS.courseInfo.documentId = linkData.documentId;
3538
- // Update shared link name if available
3539
- if (linkData.documentName) {
3540
- LRS.courseInfo.sharedLinkName = linkData.documentName;
3660
+ log('Have shared link token, fetching document data via shared API...');
3661
+ // fetchDocumentMetadata will use /api/shared/{token}/documents when sharedLinkToken is present
3662
+ fetchDocumentMetadata(null, function(docData) {
3663
+ if (docData) {
3664
+ updateCourseInfoFromApi(docData);
3665
+ // Also update document name if available
3666
+ if (docData.name) {
3667
+ LRS.courseInfo.sharedLinkName = docData.name;
3541
3668
  }
3542
- fetchDocDataAndSend(linkData.documentId);
3543
- } else if (documentId) {
3544
- // Fallback to extracted document ID (may be thin pack ID)
3545
- warn('Could not get document ID from shared link, using extracted ID:', documentId);
3546
- fetchDocDataAndSend(documentId);
3547
3669
  } else {
3548
- // No document ID available
3549
- warn('No document ID available - statements may fail aggregation');
3550
- setTimeout(sendLaunchEvents, 100);
3670
+ warn('Could not fetch document data from shared API - statements may fail aggregation');
3551
3671
  }
3672
+ setTimeout(sendLaunchEvents, 100);
3552
3673
  });
3553
3674
  } else if (documentId) {
3554
- // No shared link token, try with extracted document ID
3675
+ // No shared link token, try with extracted document ID (requires auth)
3555
3676
  log('No shared link token, fetching document data with ID:', documentId);
3556
3677
  fetchDocDataAndSend(documentId);
3557
3678
  } else {