@patch-adams/core 1.3.9 → 1.4.2

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
@@ -1565,24 +1565,12 @@ function generateLrsBridgeCode(options) {
1565
1565
  // Store for document API data
1566
1566
  var documentApiData = null;
1567
1567
  var documentApiFetched = false;
1568
+ var sharedLinkApiData = null;
1568
1569
 
1569
1570
  /**
1570
- * Fetch document metadata from Bravais API to get GUIDs
1571
- * Endpoint: /api/v3/documents/{documentId}
1571
+ * Detect Bravais core URL from current page context
1572
1572
  */
1573
- function fetchDocumentMetadata(documentId, callback) {
1574
- if (!documentId) {
1575
- callback(null);
1576
- return;
1577
- }
1578
-
1579
- if (documentApiFetched) {
1580
- callback(documentApiData);
1581
- return;
1582
- }
1583
-
1584
- // Detect Bravais core URL
1585
- var coreUrl = null;
1573
+ function detectCoreUrl() {
1586
1574
  var urlsToCheck = [window.location.href, document.referrer];
1587
1575
 
1588
1576
  try {
@@ -1598,13 +1586,91 @@ function generateLrsBridgeCode(options) {
1598
1586
  } catch (e) {}
1599
1587
 
1600
1588
  for (var j = 0; j < urlsToCheck.length; j++) {
1601
- var match = urlsToCheck[j].match(/(https?:\\/\\/core-[a-zA-Z0-9_-]+\\.bravais\\.com)/);
1589
+ var match = urlsToCheck[j].match(/(https?://core-[a-zA-Z0-9_-]+.bravais.com)/);
1602
1590
  if (match) {
1603
- coreUrl = match[1];
1604
- break;
1591
+ return match[1];
1605
1592
  }
1606
1593
  }
1594
+ return null;
1595
+ }
1596
+
1597
+ /**
1598
+ * Fetch shared link data from Bravais API to get the real document ID
1599
+ * Endpoint: /api/v3/sharedLinks/token/{token}
1600
+ * Returns: { documentId, documentName, format, ... }
1601
+ */
1602
+ function fetchSharedLinkData(token, callback) {
1603
+ if (!token) {
1604
+ callback(null);
1605
+ return;
1606
+ }
1607
1607
 
1608
+ var coreUrl = detectCoreUrl();
1609
+ if (!coreUrl) {
1610
+ log('No Bravais core URL detected for shared link fetch');
1611
+ callback(null);
1612
+ return;
1613
+ }
1614
+
1615
+ var apiUrl = coreUrl + '/api/v3/sharedLinks/token/' + token;
1616
+ log('Fetching shared link data from:', apiUrl);
1617
+
1618
+ var xhr = new XMLHttpRequest();
1619
+ xhr.open('GET', apiUrl, true);
1620
+ xhr.withCredentials = true;
1621
+ xhr.setRequestHeader('Accept', 'application/json');
1622
+
1623
+ xhr.onreadystatechange = function() {
1624
+ if (xhr.readyState === 4) {
1625
+ log('Shared link API response status:', xhr.status);
1626
+ if (xhr.status >= 200 && xhr.status < 300) {
1627
+ try {
1628
+ sharedLinkApiData = JSON.parse(xhr.responseText);
1629
+ log('Shared link data received:', sharedLinkApiData);
1630
+ if (sharedLinkApiData.documentId) {
1631
+ log('Real document ID from shared link:', sharedLinkApiData.documentId);
1632
+ }
1633
+ callback(sharedLinkApiData);
1634
+ } catch (e) {
1635
+ warn('Error parsing shared link data:', e);
1636
+ callback(null);
1637
+ }
1638
+ } else {
1639
+ warn('Shared link fetch failed. Status:', xhr.status);
1640
+ callback(null);
1641
+ }
1642
+ }
1643
+ };
1644
+
1645
+ xhr.onerror = function() {
1646
+ log('Network error fetching shared link data');
1647
+ callback(null);
1648
+ };
1649
+
1650
+ try {
1651
+ xhr.send();
1652
+ } catch (e) {
1653
+ warn('Error sending shared link request:', e);
1654
+ callback(null);
1655
+ }
1656
+ }
1657
+
1658
+ /**
1659
+ * Fetch document metadata from Bravais API to get GUIDs
1660
+ * Endpoint: /api/v3/documents/{documentId}
1661
+ */
1662
+ function fetchDocumentMetadata(documentId, callback) {
1663
+ if (!documentId) {
1664
+ callback(null);
1665
+ return;
1666
+ }
1667
+
1668
+ if (documentApiFetched) {
1669
+ callback(documentApiData);
1670
+ return;
1671
+ }
1672
+
1673
+ var coreUrl = detectCoreUrl();
1608
1674
  if (!coreUrl) {
1609
1675
  log('No Bravais core URL detected for document metadata fetch');
1610
1676
  documentApiFetched = true;
@@ -1628,13 +1694,24 @@ function generateLrsBridgeCode(options) {
1628
1694
  try {
1629
1695
  documentApiData = JSON.parse(xhr.responseText);
1630
1696
  log('Document metadata received:', documentApiData);
1697
+ // Validate that we got the required fields
1698
+ if (documentApiData.guid) {
1699
+ log('Document GUID found:', documentApiData.guid);
1700
+ } else {
1701
+ warn('Document API response missing guid field!', documentApiData);
1702
+ }
1703
+ if (documentApiData.latestVersion && documentApiData.latestVersion.guid) {
1704
+ log('Version GUID found:', documentApiData.latestVersion.guid);
1705
+ } else {
1706
+ warn('Document API response missing latestVersion.guid field!', documentApiData);
1707
+ }
1631
1708
  callback(documentApiData);
1632
1709
  } catch (e) {
1633
1710
  warn('Error parsing document metadata:', e);
1634
1711
  callback(null);
1635
1712
  }
1636
1713
  } else {
1637
- log('Document metadata fetch failed. Status:', xhr.status);
1714
+ warn('Document metadata fetch failed. Status:', xhr.status, 'Response:', xhr.responseText);
1638
1715
  callback(null);
1639
1716
  }
1640
1717
  }
@@ -2018,6 +2095,14 @@ function generateLrsBridgeCode(options) {
2018
2095
  function buildCourseActivityObject() {
2019
2096
  if (!LRS.courseInfo) return null;
2020
2097
 
2098
+ // Warn if we don't have the required GUIDs for Bravais aggregation
2099
+ if (!LRS.courseInfo.guid) {
2100
+ warn('Missing document GUID - statement may fail Bravais aggregation. Using numeric ID:', LRS.courseInfo.documentId);
2101
+ }
2102
+ if (!LRS.courseInfo.versionGuid) {
2103
+ warn('Missing version GUID - statement may fail Bravais aggregation (document_version_id will be null)');
2104
+ }
2105
+
2021
2106
  var obj = {
2022
2107
  objectType: 'Activity',
2023
2108
  id: LRS.courseInfo.id,
@@ -2030,10 +2115,13 @@ function generateLrsBridgeCode(options) {
2030
2115
  // Add Xyleme-format extensions
2031
2116
  obj.definition.extensions = {};
2032
2117
 
2033
- // Version ID in Xyleme IRI format
2118
+ // Version ID in Xyleme IRI format - REQUIRED for Bravais aggregation
2034
2119
  if (LRS.courseInfo.versionGuid) {
2035
2120
  obj.definition.extensions['versionId'] =
2036
2121
  'http://xyleme.com/bravais/document.version/' + LRS.courseInfo.versionGuid;
2122
+ } else {
2123
+ // Log error - this will cause aggregation failure
2124
+ warn('versionId extension not set - this statement will fail Bravais aggregation!');
2037
2125
  }
2038
2126
 
2039
2127
  // Format (e.g., "SCORM by Rise")
@@ -2958,9 +3046,18 @@ function generateLrsBridgeCode(options) {
2958
3046
 
2959
3047
  // Fetch document metadata from API to get GUIDs (async)
2960
3048
  // Then send course launched event
3049
+ var sharedLinkToken = LRS.courseInfo ? LRS.courseInfo.sharedLinkToken : null;
2961
3050
  var documentId = LRS.courseInfo ? LRS.courseInfo.documentId : null;
2962
3051
 
2963
3052
  function sendLaunchEvents() {
3053
+ // Log the course info state before sending statements
3054
+ log('Sending launch events with course info:', {
3055
+ id: LRS.courseInfo ? LRS.courseInfo.id : null,
3056
+ guid: LRS.courseInfo ? LRS.courseInfo.guid : null,
3057
+ versionGuid: LRS.courseInfo ? LRS.courseInfo.versionGuid : null,
3058
+ documentId: LRS.courseInfo ? LRS.courseInfo.documentId : null
3059
+ });
3060
+
2964
3061
  if (TRACK_NAVIGATION) {
2965
3062
  LRS.courseLaunched();
2966
3063
  LRS.contentOpened({
@@ -2971,17 +3068,52 @@ function generateLrsBridgeCode(options) {
2971
3068
  }
2972
3069
  }
2973
3070
 
2974
- if (documentId && !LRS.courseInfo.guid) {
2975
- // Try to fetch GUIDs from API before sending statements
2976
- fetchDocumentMetadata(documentId, function(docData) {
3071
+ function fetchDocDataAndSend(docId) {
3072
+ fetchDocumentMetadata(docId, function(docData) {
2977
3073
  if (docData) {
2978
3074
  updateCourseInfoFromApi(docData);
2979
3075
  }
2980
3076
  // Send launch events after API fetch (success or failure)
2981
3077
  setTimeout(sendLaunchEvents, 100);
2982
3078
  });
3079
+ }
3080
+
3081
+ if (!LRS.courseInfo.guid) {
3082
+ // First, try to get real document ID from shared link token
3083
+ // The URL path contains a thin pack file ID, not the real document ID
3084
+ if (sharedLinkToken) {
3085
+ log('Fetching shared link data to get real document ID...');
3086
+ fetchSharedLinkData(sharedLinkToken, function(linkData) {
3087
+ if (linkData && linkData.documentId) {
3088
+ // Got the real document ID from shared link
3089
+ log('Got real document ID from shared link:', linkData.documentId);
3090
+ LRS.courseInfo.documentId = linkData.documentId;
3091
+ // Update shared link name if available
3092
+ if (linkData.documentName) {
3093
+ LRS.courseInfo.sharedLinkName = linkData.documentName;
3094
+ }
3095
+ fetchDocDataAndSend(linkData.documentId);
3096
+ } else if (documentId) {
3097
+ // Fallback to extracted document ID (may be thin pack ID)
3098
+ warn('Could not get document ID from shared link, using extracted ID:', documentId);
3099
+ fetchDocDataAndSend(documentId);
3100
+ } else {
3101
+ // No document ID available
3102
+ warn('No document ID available - statements may fail aggregation');
3103
+ setTimeout(sendLaunchEvents, 100);
3104
+ }
3105
+ });
3106
+ } else if (documentId) {
3107
+ // No shared link token, try with extracted document ID
3108
+ log('No shared link token, fetching document data with ID:', documentId);
3109
+ fetchDocDataAndSend(documentId);
3110
+ } else {
3111
+ // No identifiers available
3112
+ warn('No shared link token or document ID - statements may fail aggregation');
3113
+ setTimeout(sendLaunchEvents, 500);
3114
+ }
2983
3115
  } else {
2984
- // Already have GUID or no document ID - send after short delay
3116
+ // Already have GUID - send after short delay
2985
3117
  setTimeout(sendLaunchEvents, 500);
2986
3118
  }
2987
3119