@patch-adams/core 1.5.15 → 1.5.17

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
@@ -1872,6 +1872,69 @@ function generateLrsBridgeCode(options) {
1872
1872
  }
1873
1873
  }
1874
1874
 
1875
+ /**
1876
+ * Fetch document name from our authenticated server (cdsImporter proxy).
1877
+ * Derives server base URL from LRS_PROXY_ENDPOINT.
1878
+ * Falls back gracefully if CORS blocks or server is unavailable.
1879
+ * This is the final fallback when Bravais API and PARAMS are not available.
1880
+ */
1881
+ function fetchDocumentNameFromServer(documentId, callback) {
1882
+ if (!LRS_PROXY_ENDPOINT || !documentId) {
1883
+ callback(null);
1884
+ return;
1885
+ }
1886
+
1887
+ // Derive server base from LRS proxy endpoint
1888
+ // e.g., https://api.example.com/create/statement \u2192 https://api.example.com/create/
1889
+ var serverBase = LRS_PROXY_ENDPOINT.replace(/\\/statement\\/?$/, '/');
1890
+ if (!serverBase || serverBase === LRS_PROXY_ENDPOINT) {
1891
+ log('Could not derive server base URL from LRS_PROXY_ENDPOINT');
1892
+ callback(null);
1893
+ return;
1894
+ }
1895
+
1896
+ var apiUrl = serverBase + 'cdsImporter/api/documents/' + documentId;
1897
+ log('Fetching document name from server:', apiUrl);
1898
+
1899
+ var xhr = new XMLHttpRequest();
1900
+ xhr.open('GET', apiUrl, true);
1901
+ xhr.withCredentials = true;
1902
+ xhr.setRequestHeader('Accept', 'application/json');
1903
+ xhr.timeout = 5000;
1904
+
1905
+ xhr.onreadystatechange = function() {
1906
+ if (xhr.readyState === 4) {
1907
+ if (xhr.status >= 200 && xhr.status < 300) {
1908
+ try {
1909
+ var data = JSON.parse(xhr.responseText);
1910
+ if (data.name) {
1911
+ log('Document name from server:', data.name);
1912
+ callback(data.name);
1913
+ } else {
1914
+ callback(null);
1915
+ }
1916
+ } catch (e) {
1917
+ callback(null);
1918
+ }
1919
+ } else {
1920
+ log('Server document lookup returned:', xhr.status);
1921
+ callback(null);
1922
+ }
1923
+ }
1924
+ };
1925
+
1926
+ xhr.onerror = function() {
1927
+ log('Server document lookup network error (CORS or connectivity)');
1928
+ callback(null);
1929
+ };
1930
+ xhr.ontimeout = function() {
1931
+ log('Server document lookup timed out');
1932
+ callback(null);
1933
+ };
1934
+
1935
+ try { xhr.send(); } catch (e) { callback(null); }
1936
+ }
1937
+
1875
1938
  /**
1876
1939
  * Update course info with data from document API
1877
1940
  */
@@ -1902,6 +1965,19 @@ function generateLrsBridgeCode(options) {
1902
1965
  LRS.courseInfo.resourceType = docData.resourceType;
1903
1966
  }
1904
1967
 
1968
+ // Update packageName from API document name (matches Bravais Analytics object name)
1969
+ // Only set if not already baked in at wrap time
1970
+ if (docData.name && !LRS.courseInfo.packageName) {
1971
+ LRS.courseInfo.packageName = docData.name;
1972
+ log('Updated packageName from API:', docData.name);
1973
+ }
1974
+
1975
+ // Update documentId from API if we didn't have it
1976
+ if (docData.id && !LRS.courseInfo.documentId) {
1977
+ LRS.courseInfo.documentId = String(docData.id);
1978
+ log('Updated documentId from API:', docData.id);
1979
+ }
1980
+
1905
1981
  log('Course info updated from API:', LRS.courseInfo);
1906
1982
  }
1907
1983
 
@@ -2233,7 +2309,61 @@ function generateLrsBridgeCode(options) {
2233
2309
  info.versionId = paMeta.versionId || info.versionId;
2234
2310
  }
2235
2311
 
2236
- // 8. Build the course ID in Xyleme IRI format
2312
+ // 8. Extract Bravais document name from launch environment (runtime)
2313
+ // This is the name shown in Bravais Analytics and used for search.
2314
+ // Overrides packageName so the statement object name matches the Bravais document.
2315
+ if (!info.packageName) {
2316
+ var bravaisDocName = null;
2317
+
2318
+ // Strategy 1: Walk parent frames for PARAMS.documentName and PARAMS.did
2319
+ try {
2320
+ var win = window;
2321
+ for (var i = 0; i < 10; i++) {
2322
+ try {
2323
+ if (win.PARAMS) {
2324
+ if (win.PARAMS.documentName && !bravaisDocName) {
2325
+ bravaisDocName = win.PARAMS.documentName;
2326
+ log('Bravais document name from PARAMS:', bravaisDocName);
2327
+ }
2328
+ if (win.PARAMS.did && !info.documentId) {
2329
+ info.documentId = String(win.PARAMS.did);
2330
+ log('Bravais document ID from PARAMS.did:', info.documentId);
2331
+ }
2332
+ }
2333
+ } catch (e) {}
2334
+ if (win === win.parent) break;
2335
+ win = win.parent;
2336
+ }
2337
+ } catch (e) {}
2338
+
2339
+ // Strategy 2: Walk parent frames checking window.name
2340
+ // Bravais sets the iframe name attribute to the document name
2341
+ if (!bravaisDocName) {
2342
+ try {
2343
+ var win = window;
2344
+ for (var i = 0; i < 10; i++) {
2345
+ try {
2346
+ var frameName = win.name;
2347
+ // Document names have hyphens and are long; skip generic frame names
2348
+ if (frameName && frameName.length > 20 && frameName.indexOf('-') > -1 &&
2349
+ frameName.indexOf('scorm') === -1 && frameName.indexOf('API') === -1) {
2350
+ bravaisDocName = frameName;
2351
+ log('Bravais document name from frame name:', bravaisDocName);
2352
+ break;
2353
+ }
2354
+ } catch (e) {}
2355
+ if (win === win.parent) break;
2356
+ win = win.parent;
2357
+ }
2358
+ } catch (e) {}
2359
+ }
2360
+
2361
+ if (bravaisDocName) {
2362
+ info.packageName = bravaisDocName;
2363
+ }
2364
+ }
2365
+
2366
+ // 9. Build the course ID in Xyleme IRI format
2237
2367
  // Native format: http://xyleme.com/bravais/document/{guid}
2238
2368
  if (info.guid) {
2239
2369
  info.id = 'http://xyleme.com/bravais/document/' + info.guid;
@@ -4806,12 +4936,30 @@ function generateLrsBridgeCode(options) {
4806
4936
  tryLaunchEvents();
4807
4937
  }
4808
4938
 
4939
+ // After Bravais API metadata resolves, try our authenticated server as a
4940
+ // final fallback to get the document name for packageName.
4941
+ // This handles cases where PARAMS is cross-origin blocked and no baked name exists.
4942
+ function maybeEnrichAndReady() {
4943
+ if (LRS.courseInfo.packageName || !LRS.courseInfo.documentId || !LRS_PROXY_ENDPOINT) {
4944
+ onDocReady();
4945
+ return;
4946
+ }
4947
+ log('No packageName yet, trying server-side document lookup for ID:', LRS.courseInfo.documentId);
4948
+ fetchDocumentNameFromServer(LRS.courseInfo.documentId, function(name) {
4949
+ if (name) {
4950
+ LRS.courseInfo.packageName = name;
4951
+ log('Set packageName from server lookup:', name);
4952
+ }
4953
+ onDocReady();
4954
+ });
4955
+ }
4956
+
4809
4957
  function fetchDocDataAndReady(docId) {
4810
4958
  fetchDocumentMetadata(docId, function(docData) {
4811
4959
  if (docData) {
4812
4960
  updateCourseInfoFromApi(docData);
4813
4961
  }
4814
- onDocReady();
4962
+ maybeEnrichAndReady();
4815
4963
  });
4816
4964
  }
4817
4965
 
@@ -4831,7 +4979,7 @@ function generateLrsBridgeCode(options) {
4831
4979
  } else {
4832
4980
  warn('Could not fetch document data from shared API - statements may fail aggregation');
4833
4981
  }
4834
- onDocReady();
4982
+ maybeEnrichAndReady();
4835
4983
  });
4836
4984
  } else if (documentId) {
4837
4985
  // No shared link token, try with extracted document ID (requires auth)
@@ -4840,11 +4988,11 @@ function generateLrsBridgeCode(options) {
4840
4988
  } else {
4841
4989
  // No identifiers available
4842
4990
  warn('No shared link token or document ID - statements may fail aggregation');
4843
- onDocReady();
4991
+ maybeEnrichAndReady();
4844
4992
  }
4845
4993
  } else {
4846
- // Already have GUID
4847
- onDocReady();
4994
+ // Already have GUID \u2014 still try to enrich packageName if missing
4995
+ maybeEnrichAndReady();
4848
4996
  }
4849
4997
 
4850
4998
  // Setup beforeunload to send terminated