@salesforce/webapp-experimental 1.103.3 → 1.103.5

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.
@@ -1,4 +1,4 @@
1
- const version = "1.103.3";
1
+ const version = "1.103.5";
2
2
  export {
3
3
  version
4
4
  };
@@ -1 +1 @@
1
- {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../src/proxy/handler.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAIjE,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAG5D;;GAEG;AACH,eAAO,MAAM,yBAAyB,uBAAuB,CAAC;AAE9D;;GAEG;AACH,eAAO,MAAM,mBAAmB,8BAA8B,CAAC;AA2B/D;;GAEG;AACH,MAAM,WAAW,YAAY;IAE5B,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB,cAAc,CAAC,EAAE,CAAC,cAAc,EAAE,OAAO,KAAK,IAAI,CAAC;CACnD;AAED;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,CAC1B,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,EACnB,IAAI,CAAC,EAAE,MAAM,IAAI,KACb,OAAO,CAAC,IAAI,CAAC,CAAC;AAmkBnB;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CACjC,QAAQ,EAAE,cAAc,EACxB,OAAO,CAAC,EAAE,OAAO,EACjB,MAAM,CAAC,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,YAAY,GACpB,YAAY,CAGd;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE5D"}
1
+ {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../src/proxy/handler.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAIjE,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAG5D;;GAEG;AACH,eAAO,MAAM,yBAAyB,uBAAuB,CAAC;AAE9D;;GAEG;AACH,eAAO,MAAM,mBAAmB,8BAA8B,CAAC;AA6B/D;;GAEG;AACH,MAAM,WAAW,YAAY;IAE5B,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB,cAAc,CAAC,EAAE,CAAC,cAAc,EAAE,OAAO,KAAK,IAAI,CAAC;CACnD;AAED;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,CAC1B,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,EACnB,IAAI,CAAC,EAAE,MAAM,IAAI,KACb,OAAO,CAAC,IAAI,CAAC,CAAC;AAwlBnB;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CACjC,QAAQ,EAAE,cAAc,EACxB,OAAO,CAAC,EAAE,OAAO,EACjB,MAAM,CAAC,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,YAAY,GACpB,YAAY,CAGd;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE5D"}
@@ -7,6 +7,7 @@ const WEBAPP_HEALTH_CHECK_PARAM = "sfProxyHealthCheck";
7
7
  const WEBAPP_PROXY_HEADER = "X-Salesforce-WebApp-Proxy";
8
8
  const LIGHTNING_OUT_SINGLE_ACCESS_PATH = "/services/oauth2/singleaccess";
9
9
  const SALESFORCE_API_PREFIXES = ["/services/", "/lwr/apex/"];
10
+ const SALESFORCE_FILE_UPLOAD_PREFIX = "/chatter/handlers/file/body";
10
11
  const AUTH_FAILED_RESPONSE = {
11
12
  error: "AUTHENTICATION_FAILED",
12
13
  message: "Authentication failed. Please re-authenticate to your Salesforce org.",
@@ -75,12 +76,17 @@ class WebAppProxyHandler {
75
76
  return;
76
77
  }
77
78
  if (match.type === "file-upload") {
78
- console.log("[webapps-proxy] file-upload match found → handleFileUpload");
79
- await this.handleFileUpload(req, res, url);
79
+ if (this.options?.debug) {
80
+ console.log("[webapps-proxy] file-upload match found → handleFileUpload");
81
+ }
82
+ await this.handleFileUpload(req, res);
80
83
  return;
81
84
  }
82
85
  }
83
- if (SALESFORCE_API_PREFIXES.some((prefix) => pathname.startsWith(prefix))) {
86
+ if (pathname.startsWith(SALESFORCE_FILE_UPLOAD_PREFIX)) {
87
+ await this.handleFileUpload(req, res);
88
+ return;
89
+ } else if (SALESFORCE_API_PREFIXES.some((prefix) => pathname.startsWith(prefix))) {
84
90
  await this.handleSalesforceApi(req, res);
85
91
  return;
86
92
  }
@@ -407,14 +413,19 @@ class WebAppProxyHandler {
407
413
  * Proxy POST /chatter/handlers/file/body (XHR/file upload) to Salesforce.
408
414
  * Uses rawInstanceUrl for Chatter API. Preserves multipart/form-data from XHR.
409
415
  */
410
- async handleFileUpload(req, res, url) {
416
+ async handleFileUpload(req, res) {
411
417
  try {
412
418
  if (!this.orgInfo) {
413
419
  this.sendNoOrgError(res);
414
420
  return;
415
421
  }
416
- const pathForSalesforce = this.basePath && url.pathname.startsWith(this.basePath) ? url.pathname.slice(this.basePath.length) || "/" : url.pathname;
417
- const uploadUrl = `${this.orgInfo.rawInstanceUrl}${pathForSalesforce}${url.search}`;
422
+ const url = new URL(req.url ?? "/", `http://${req.headers.host}`);
423
+ const pathIndex = url.pathname.indexOf("/chatter/handlers/file/body");
424
+ const apiPath = url.pathname.substring(pathIndex);
425
+ const uploadUrl = `${this.orgInfo.rawInstanceUrl}${apiPath}${url.search}`;
426
+ if (this.options?.debug) {
427
+ console.log(`[webapps-proxy] Forwarding file upload to Salesforce: ${uploadUrl}`);
428
+ }
418
429
  const body = await getBody(req);
419
430
  if (!body?.length) {
420
431
  res.writeHead(400, { "Content-Type": "application/json" });
@@ -448,7 +459,23 @@ class WebAppProxyHandler {
448
459
  headers,
449
460
  body: new Uint8Array(body)
450
461
  });
451
- await this.sendResponse(res, response);
462
+ const resHeaders = {};
463
+ const skipHeaders = /* @__PURE__ */ new Set(["content-encoding", "transfer-encoding"]);
464
+ response.headers.forEach((value, key) => {
465
+ if (!skipHeaders.has(key.toLowerCase())) {
466
+ resHeaders[key] = value;
467
+ }
468
+ });
469
+ res.writeHead(response.status, resHeaders);
470
+ if (response.body) {
471
+ const reader = response.body.getReader();
472
+ while (true) {
473
+ const { done, value } = await reader.read();
474
+ if (done) break;
475
+ res.write(value);
476
+ }
477
+ }
478
+ res.end();
452
479
  } catch (error) {
453
480
  console.error("[webapps-proxy] File upload proxy failed:", error);
454
481
  res.writeHead(502, { "Content-Type": "application/json" });
@@ -220,7 +220,11 @@
220
220
  console.error("[webapps-proxy] Failed to send iframeAlive message:", e);
221
221
  }
222
222
  }
223
- if (!document.getElementById("vscode-text-selection-style")) {
223
+ if (
224
+ window.parent &&
225
+ window.parent !== window &&
226
+ !document.getElementById("vscode-text-selection-style")
227
+ ) {
224
228
  const style = document.createElement("style");
225
229
  style.id = "vscode-text-selection-style";
226
230
  style.textContent =
@@ -291,41 +295,37 @@
291
295
  }
292
296
  }
293
297
 
294
- // Listen for keyboard shortcuts (Cmd+C / Ctrl+C) - user-initiated, always send
295
- document.addEventListener(
296
- "keydown",
297
- function (e) {
298
- // Cmd+C (Mac) or Ctrl+C (Windows/Linux)
299
- if ((e.metaKey || e.ctrlKey) && (e.key === "c" || e.key === "C" || e.keyCode === 67)) {
300
- // Small delay to ensure selection is captured after VS Code processes the event
298
+ if (window.parent && window.parent !== window) {
299
+ document.addEventListener(
300
+ "keydown",
301
+ function (e) {
302
+ if ((e.metaKey || e.ctrlKey) && (e.key === "c" || e.key === "C" || e.keyCode === 67)) {
303
+ setTimeout(function () {
304
+ sendCopyMessage(true);
305
+ }, 0);
306
+ }
307
+ },
308
+ true,
309
+ );
310
+
311
+ document.addEventListener(
312
+ "copy",
313
+ function (e) {
301
314
  setTimeout(function () {
302
- sendCopyMessage(true); // forceCopy = true for user-initiated actions
315
+ sendCopyMessage(true);
303
316
  }, 0);
304
- }
305
- },
306
- true,
307
- ); // Use capture phase - highest priority
308
-
309
- // Listen for copy events as backup
310
- document.addEventListener(
311
- "copy",
312
- function (e) {
313
- // Also force send on copy event (user-initiated)
314
- setTimeout(function () {
315
- sendCopyMessage(true);
316
- }, 0);
317
- },
318
- true,
319
- ); // Use capture phase to catch before VS Code intercepts
317
+ },
318
+ true,
319
+ );
320
+ }
320
321
 
321
- document.addEventListener(
322
- "contextmenu",
323
- function (e) {
324
- // Prevent default browser context menu so our custom one shows
325
- e.preventDefault();
326
- const selection = window.getSelection();
327
- const selectedText = selection && selection.toString().trim() ? selection.toString() : "";
328
- if (window.parent && window.parent !== window) {
322
+ if (window.parent && window.parent !== window) {
323
+ document.addEventListener(
324
+ "contextmenu",
325
+ function (e) {
326
+ e.preventDefault();
327
+ const selection = window.getSelection();
328
+ const selectedText = selection && selection.toString().trim() ? selection.toString() : "";
329
329
  try {
330
330
  window.parent.postMessage(
331
331
  {
@@ -339,10 +339,10 @@
339
339
  } catch (err) {
340
340
  console.error("[webapps-proxy] Right-click: Error sending postMessage:", err);
341
341
  }
342
- }
343
- },
344
- true,
345
- );
342
+ },
343
+ true,
344
+ );
345
+ }
346
346
 
347
347
  window.addEventListener("message", function (e) {
348
348
  if (e.data && e.data.command === "getSelection") {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@salesforce/webapp-experimental",
3
3
  "description": "[experimental] Core package for Salesforce Web Applications",
4
- "version": "1.103.3",
4
+ "version": "1.103.5",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "type": "module",
7
7
  "main": "./dist/index.js",
@@ -44,7 +44,7 @@
44
44
  },
45
45
  "dependencies": {
46
46
  "@salesforce/core": "^8.23.4",
47
- "@salesforce/sdk-data": "^1.103.3",
47
+ "@salesforce/sdk-data": "^1.103.5",
48
48
  "axios": "^1.7.7",
49
49
  "micromatch": "^4.0.8",
50
50
  "path-to-regexp": "^8.3.0"