@patch-adams/core 1.4.0 → 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/cli.js CHANGED
@@ -1900,24 +1900,12 @@ function generateLrsBridgeCode(options) {
1900
1900
  // Store for document API data
1901
1901
  var documentApiData = null;
1902
1902
  var documentApiFetched = false;
1903
+ var sharedLinkApiData = null;
1903
1904
 
1904
1905
  /**
1905
- * Fetch document metadata from Bravais API to get GUIDs
1906
- * Endpoint: /api/v3/documents/{documentId}
1906
+ * Detect Bravais core URL from current page context
1907
1907
  */
1908
- function fetchDocumentMetadata(documentId, callback) {
1909
- if (!documentId) {
1910
- callback(null);
1911
- return;
1912
- }
1913
-
1914
- if (documentApiFetched) {
1915
- callback(documentApiData);
1916
- return;
1917
- }
1918
-
1919
- // Detect Bravais core URL
1920
- var coreUrl = null;
1908
+ function detectCoreUrl() {
1921
1909
  var urlsToCheck = [window.location.href, document.referrer];
1922
1910
 
1923
1911
  try {
@@ -1933,13 +1921,91 @@ function generateLrsBridgeCode(options) {
1933
1921
  } catch (e) {}
1934
1922
 
1935
1923
  for (var j = 0; j < urlsToCheck.length; j++) {
1936
- var match = urlsToCheck[j].match(/(https?:\\/\\/core-[a-zA-Z0-9_-]+\\.bravais\\.com)/);
1924
+ var match = urlsToCheck[j].match(/(https?://core-[a-zA-Z0-9_-]+.bravais.com)/);
1937
1925
  if (match) {
1938
- coreUrl = match[1];
1939
- break;
1926
+ return match[1];
1940
1927
  }
1941
1928
  }
1929
+ return null;
1930
+ }
1931
+
1932
+ /**
1933
+ * Fetch shared link data from Bravais API to get the real document ID
1934
+ * Endpoint: /api/v3/sharedLinks/token/{token}
1935
+ * Returns: { documentId, documentName, format, ... }
1936
+ */
1937
+ function fetchSharedLinkData(token, callback) {
1938
+ if (!token) {
1939
+ callback(null);
1940
+ return;
1941
+ }
1942
1942
 
1943
+ var coreUrl = detectCoreUrl();
1944
+ if (!coreUrl) {
1945
+ log('No Bravais core URL detected for shared link fetch');
1946
+ callback(null);
1947
+ return;
1948
+ }
1949
+
1950
+ var apiUrl = coreUrl + '/api/v3/sharedLinks/token/' + token;
1951
+ log('Fetching shared link data from:', apiUrl);
1952
+
1953
+ var xhr = new XMLHttpRequest();
1954
+ xhr.open('GET', apiUrl, true);
1955
+ xhr.withCredentials = true;
1956
+ xhr.setRequestHeader('Accept', 'application/json');
1957
+
1958
+ xhr.onreadystatechange = function() {
1959
+ if (xhr.readyState === 4) {
1960
+ log('Shared link API response status:', xhr.status);
1961
+ if (xhr.status >= 200 && xhr.status < 300) {
1962
+ try {
1963
+ sharedLinkApiData = JSON.parse(xhr.responseText);
1964
+ log('Shared link data received:', sharedLinkApiData);
1965
+ if (sharedLinkApiData.documentId) {
1966
+ log('Real document ID from shared link:', sharedLinkApiData.documentId);
1967
+ }
1968
+ callback(sharedLinkApiData);
1969
+ } catch (e) {
1970
+ warn('Error parsing shared link data:', e);
1971
+ callback(null);
1972
+ }
1973
+ } else {
1974
+ warn('Shared link fetch failed. Status:', xhr.status);
1975
+ callback(null);
1976
+ }
1977
+ }
1978
+ };
1979
+
1980
+ xhr.onerror = function() {
1981
+ log('Network error fetching shared link data');
1982
+ callback(null);
1983
+ };
1984
+
1985
+ try {
1986
+ xhr.send();
1987
+ } catch (e) {
1988
+ warn('Error sending shared link request:', e);
1989
+ callback(null);
1990
+ }
1991
+ }
1992
+
1993
+ /**
1994
+ * Fetch document metadata from Bravais API to get GUIDs
1995
+ * Endpoint: /api/v3/documents/{documentId}
1996
+ */
1997
+ function fetchDocumentMetadata(documentId, callback) {
1998
+ if (!documentId) {
1999
+ callback(null);
2000
+ return;
2001
+ }
2002
+
2003
+ if (documentApiFetched) {
2004
+ callback(documentApiData);
2005
+ return;
2006
+ }
2007
+
2008
+ var coreUrl = detectCoreUrl();
1943
2009
  if (!coreUrl) {
1944
2010
  log('No Bravais core URL detected for document metadata fetch');
1945
2011
  documentApiFetched = true;
@@ -1963,13 +2029,24 @@ function generateLrsBridgeCode(options) {
1963
2029
  try {
1964
2030
  documentApiData = JSON.parse(xhr.responseText);
1965
2031
  log('Document metadata received:', documentApiData);
2032
+ // Validate that we got the required fields
2033
+ if (documentApiData.guid) {
2034
+ log('Document GUID found:', documentApiData.guid);
2035
+ } else {
2036
+ warn('Document API response missing guid field!', documentApiData);
2037
+ }
2038
+ if (documentApiData.latestVersion && documentApiData.latestVersion.guid) {
2039
+ log('Version GUID found:', documentApiData.latestVersion.guid);
2040
+ } else {
2041
+ warn('Document API response missing latestVersion.guid field!', documentApiData);
2042
+ }
1966
2043
  callback(documentApiData);
1967
2044
  } catch (e) {
1968
2045
  warn('Error parsing document metadata:', e);
1969
2046
  callback(null);
1970
2047
  }
1971
2048
  } else {
1972
- log('Document metadata fetch failed. Status:', xhr.status);
2049
+ warn('Document metadata fetch failed. Status:', xhr.status, 'Response:', xhr.responseText);
1973
2050
  callback(null);
1974
2051
  }
1975
2052
  }
@@ -2353,6 +2430,14 @@ function generateLrsBridgeCode(options) {
2353
2430
  function buildCourseActivityObject() {
2354
2431
  if (!LRS.courseInfo) return null;
2355
2432
 
2433
+ // Warn if we don't have the required GUIDs for Bravais aggregation
2434
+ if (!LRS.courseInfo.guid) {
2435
+ warn('Missing document GUID - statement may fail Bravais aggregation. Using numeric ID:', LRS.courseInfo.documentId);
2436
+ }
2437
+ if (!LRS.courseInfo.versionGuid) {
2438
+ warn('Missing version GUID - statement may fail Bravais aggregation (document_version_id will be null)');
2439
+ }
2440
+
2356
2441
  var obj = {
2357
2442
  objectType: 'Activity',
2358
2443
  id: LRS.courseInfo.id,
@@ -2365,10 +2450,13 @@ function generateLrsBridgeCode(options) {
2365
2450
  // Add Xyleme-format extensions
2366
2451
  obj.definition.extensions = {};
2367
2452
 
2368
- // Version ID in Xyleme IRI format
2453
+ // Version ID in Xyleme IRI format - REQUIRED for Bravais aggregation
2369
2454
  if (LRS.courseInfo.versionGuid) {
2370
2455
  obj.definition.extensions['versionId'] =
2371
2456
  'http://xyleme.com/bravais/document.version/' + LRS.courseInfo.versionGuid;
2457
+ } else {
2458
+ // Log error - this will cause aggregation failure
2459
+ warn('versionId extension not set - this statement will fail Bravais aggregation!');
2372
2460
  }
2373
2461
 
2374
2462
  // Format (e.g., "SCORM by Rise")
@@ -3293,9 +3381,18 @@ function generateLrsBridgeCode(options) {
3293
3381
 
3294
3382
  // Fetch document metadata from API to get GUIDs (async)
3295
3383
  // Then send course launched event
3384
+ var sharedLinkToken = LRS.courseInfo ? LRS.courseInfo.sharedLinkToken : null;
3296
3385
  var documentId = LRS.courseInfo ? LRS.courseInfo.documentId : null;
3297
3386
 
3298
3387
  function sendLaunchEvents() {
3388
+ // Log the course info state before sending statements
3389
+ log('Sending launch events with course info:', {
3390
+ id: LRS.courseInfo ? LRS.courseInfo.id : null,
3391
+ guid: LRS.courseInfo ? LRS.courseInfo.guid : null,
3392
+ versionGuid: LRS.courseInfo ? LRS.courseInfo.versionGuid : null,
3393
+ documentId: LRS.courseInfo ? LRS.courseInfo.documentId : null
3394
+ });
3395
+
3299
3396
  if (TRACK_NAVIGATION) {
3300
3397
  LRS.courseLaunched();
3301
3398
  LRS.contentOpened({
@@ -3306,17 +3403,52 @@ function generateLrsBridgeCode(options) {
3306
3403
  }
3307
3404
  }
3308
3405
 
3309
- if (documentId && !LRS.courseInfo.guid) {
3310
- // Try to fetch GUIDs from API before sending statements
3311
- fetchDocumentMetadata(documentId, function(docData) {
3406
+ function fetchDocDataAndSend(docId) {
3407
+ fetchDocumentMetadata(docId, function(docData) {
3312
3408
  if (docData) {
3313
3409
  updateCourseInfoFromApi(docData);
3314
3410
  }
3315
3411
  // Send launch events after API fetch (success or failure)
3316
3412
  setTimeout(sendLaunchEvents, 100);
3317
3413
  });
3414
+ }
3415
+
3416
+ if (!LRS.courseInfo.guid) {
3417
+ // First, try to get real document ID from shared link token
3418
+ // The URL path contains a thin pack file ID, not the real document ID
3419
+ if (sharedLinkToken) {
3420
+ log('Fetching shared link data to get real document ID...');
3421
+ fetchSharedLinkData(sharedLinkToken, function(linkData) {
3422
+ if (linkData && linkData.documentId) {
3423
+ // Got the real document ID from shared link
3424
+ log('Got real document ID from shared link:', linkData.documentId);
3425
+ LRS.courseInfo.documentId = linkData.documentId;
3426
+ // Update shared link name if available
3427
+ if (linkData.documentName) {
3428
+ LRS.courseInfo.sharedLinkName = linkData.documentName;
3429
+ }
3430
+ fetchDocDataAndSend(linkData.documentId);
3431
+ } else if (documentId) {
3432
+ // Fallback to extracted document ID (may be thin pack ID)
3433
+ warn('Could not get document ID from shared link, using extracted ID:', documentId);
3434
+ fetchDocDataAndSend(documentId);
3435
+ } else {
3436
+ // No document ID available
3437
+ warn('No document ID available - statements may fail aggregation');
3438
+ setTimeout(sendLaunchEvents, 100);
3439
+ }
3440
+ });
3441
+ } else if (documentId) {
3442
+ // No shared link token, try with extracted document ID
3443
+ log('No shared link token, fetching document data with ID:', documentId);
3444
+ fetchDocDataAndSend(documentId);
3445
+ } else {
3446
+ // No identifiers available
3447
+ warn('No shared link token or document ID - statements may fail aggregation');
3448
+ setTimeout(sendLaunchEvents, 500);
3449
+ }
3318
3450
  } else {
3319
- // Already have GUID or no document ID - send after short delay
3451
+ // Already have GUID - send after short delay
3320
3452
  setTimeout(sendLaunchEvents, 500);
3321
3453
  }
3322
3454