Skip to content

Conversation

GTFalcao
Copy link
Collaborator

@GTFalcao GTFalcao commented Dec 5, 2024

Closes #14812

Note: to validate this, you must create a field for an object in the Salesforce platform and mark it as an external ID field.

Summary by CodeRabbit

  • New Features

    • Introduced a new action for creating or updating Salesforce records.
    • Added methods for upserting records and retrieving additional properties for specified object types.
  • Bug Fixes

    • Enhanced error handling for asynchronous operations during API calls.
  • Chores

    • Updated the version number of the Salesforce REST API component from 1.3.1 to 1.4.0.

Copy link

vercel bot commented Dec 5, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
docs-v2 ✅ Ready (Inspect) Visit Preview 💬 Add feedback Dec 11, 2024 6:55pm
2 Skipped Deployments
Name Status Preview Comments Updated (UTC)
pipedream-docs ⬜️ Ignored (Inspect) Dec 11, 2024 6:55pm
pipedream-docs-redirect-do-not-edit ⬜️ Ignored (Inspect) Dec 11, 2024 6:55pm

Copy link
Contributor

coderabbitai bot commented Dec 5, 2024

Walkthrough

The changes introduce a new action for creating or updating Salesforce records in the upsert-record.mjs file. This includes methods for executing the upsert operation, retrieving additional fields, and managing asynchronous API calls. The package.json file is updated to reflect a new version number, indicating the release of these enhancements.

Changes

File Path Change Summary
components/salesforce_rest_api/actions/upsert-record/upsert-record.mjs Added new action for upserting Salesforce records, including methods for upsert operation, retrieving additional properties, and orchestrating the run process.
components/salesforce_rest_api/package.json Updated version number from 1.3.1 to 1.4.0.

Assessment against linked issues

Objective Addressed Explanation
Implement upsert functionality for Salesforce records (#14812)

Possibly related PRs

  • Salesforce usability improvements #12697: This PR modifies the run method in the update-opportunity.mjs file, which is similar to the run method added in the upsert-record.mjs file, indicating a related focus on Salesforce record operations.
  • Salesforce source adjustment #14626: This PR updates the package.json file, which is also modified in the main PR to reflect a new version number, showing a direct connection in version management.

Suggested labels

triaged

Suggested reviewers

  • michelle0927
  • luancazarine

Poem

In the fields of code we hop,
With upsert magic, we won't stop!
Salesforce records, new and bright,
Created or updated, all done right.
A version bump, our joy will swell,
In the world of APIs, all is well! 🐰✨


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between f361042 and bc90a77.

📒 Files selected for processing (1)
  • components/salesforce_rest_api/actions/upsert-record/upsert-record.mjs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • components/salesforce_rest_api/actions/upsert-record/upsert-record.mjs

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Outside diff range and nitpick comments (2)
components/salesforce_rest_api/actions/upsert-record/upsert-record.mjs (2)

90-91: Add missing trailing comma after object property

A trailing comma is missing after the updateOnly property in the params object, which can help with cleaner git diffs and comply with style guidelines.

Apply this diff:

 params: {
   updateOnly
+},
🧰 Tools
🪛 eslint

[error] 90-91: Missing trailing comma.

(comma-dangle)

🪛 GitHub Check: Lint Code Base

[failure] 90-90:
Missing trailing comma


97-97: Use consistent quotation marks and format the ternary expression

Replace single quotes with double quotes inside the template literal to maintain consistency. Additionally, format the ternary expression for better readability.

Apply this diff:

-$.export("$summary", `Successfully ${response.created ? 'created' : 'updated'} ${objectType} record (ID: ${response.id})`);
+$.export("$summary", `Successfully ${
+  response.created ? "created" : "updated"
+} ${objectType} record (ID: ${response.id})`);
🧰 Tools
🪛 eslint

[error] 97-97: Expected newline between test and consequent of ternary expression.

(multiline-ternary)


[error] 97-97: Expected newline between consequent and alternate of ternary expression.

(multiline-ternary)


[error] 97-97: Strings must use doublequote.

(quotes)


[error] 97-97: Strings must use doublequote.

(quotes)

🪛 GitHub Check: Lint Code Base

[failure] 97-97:
Expected newline between test and consequent of ternary expression


[failure] 97-97:
Expected newline between consequent and alternate of ternary expression


[failure] 97-97:
Strings must use doublequote

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between c3fb146 and 4561487.

📒 Files selected for processing (2)
  • components/salesforce_rest_api/actions/upsert-record/upsert-record.mjs (1 hunks)
  • components/salesforce_rest_api/salesforce_rest_api.app.mjs (1 hunks)
🧰 Additional context used
🪛 eslint
components/salesforce_rest_api/actions/upsert-record/upsert-record.mjs

[error] 36-36: This line has a length of 102. Maximum allowed is 100.

(max-len)


[error] 36-36: Expected parentheses around arrow function argument.

(arrow-parens)


[error] 36-36: Expected a line break after this opening brace.

(object-curly-newline)


[error] 36-36: Expected a line break before this closing brace.

(object-curly-newline)


[error] 36-36: A space is required before '}'.

(object-curly-spacing)


[error] 38-39: Missing trailing comma.

(comma-dangle)


[error] 90-91: Missing trailing comma.

(comma-dangle)


[error] 97-97: Expected newline between test and consequent of ternary expression.

(multiline-ternary)


[error] 97-97: Expected newline between consequent and alternate of ternary expression.

(multiline-ternary)


[error] 97-97: Strings must use doublequote.

(quotes)


[error] 97-97: Strings must use doublequote.

(quotes)

🪛 GitHub Check: Lint Code Base
components/salesforce_rest_api/actions/upsert-record/upsert-record.mjs

[warning] 11-11:
{{ts}} macro should be removed before committing


[failure] 36-36:
This line has a length of 102. Maximum allowed is 100


[failure] 36-36:
Expected parentheses around arrow function argument


[failure] 36-36:
Expected a line break after this opening brace


[failure] 36-36:
Expected a line break before this closing brace


[failure] 36-36:
A space is required before '}'


[failure] 38-38:
Missing trailing comma


[failure] 90-90:
Missing trailing comma


[failure] 97-97:
Expected newline between test and consequent of ternary expression


[failure] 97-97:
Expected newline between consequent and alternate of ternary expression


[failure] 97-97:
Strings must use doublequote

key: "salesforce_rest_api-upsert-record",
name: "Upsert Record",
description: "Create or update a record of a given object. [See the documentation](https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/dome_upsert.htm)",
version: "0.0.{{ts}}",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Replace the {{ts}} macro in the version field

The version field currently includes the {{ts}} macro, which should be replaced before committing to avoid unintended placeholders in your code.

Apply this diff to fix the issue:

-version: "0.0.{{ts}}",
+version: "0.0.1",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
version: "0.0.{{ts}}",
version: "0.0.1",
🧰 Tools
🪛 GitHub Check: Lint Code Base

[warning] 11-11:
{{ts}} macro should be removed before committing

Comment on lines 36 to 39
const externalIdFieldOptions = fields.filter(field => field.externalId).map(({ label, name}) => ({
label,
value: name
}));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Enclose arrow function arguments in parentheses and format the object

For better readability and to comply with style guidelines, enclose the arrow function argument field in parentheses and format the returned object to include line breaks and proper spacing.

Apply this diff to address the issues:

-const externalIdFieldOptions = fields.filter(field => field.externalId).map(({ label, name}) => ({
-  label,
-  value: name
-}));
+const externalIdFieldOptions = fields
+  .filter((field) => field.externalId)
+  .map(({ label, name }) => ({
+    label,
+    value: name,
+  }));
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const externalIdFieldOptions = fields.filter(field => field.externalId).map(({ label, name}) => ({
label,
value: name
}));
const externalIdFieldOptions = fields
.filter((field) => field.externalId)
.map(({ label, name }) => ({
label,
value: name,
}));
🧰 Tools
🪛 eslint

[error] 36-36: This line has a length of 102. Maximum allowed is 100.

(max-len)


[error] 36-36: Expected parentheses around arrow function argument.

(arrow-parens)


[error] 36-36: Expected a line break after this opening brace.

(object-curly-newline)


[error] 36-36: Expected a line break before this closing brace.

(object-curly-newline)


[error] 36-36: A space is required before '}'.

(object-curly-spacing)


[error] 38-39: Missing trailing comma.

(comma-dangle)

🪛 GitHub Check: Lint Code Base

[failure] 36-36:
This line has a length of 102. Maximum allowed is 100


[failure] 36-36:
Expected parentheses around arrow function argument


[failure] 36-36:
Expected a line break after this opening brace


[failure] 36-36:
Expected a line break before this closing brace


[failure] 36-36:
A space is required before '}'


[failure] 38-38:
Missing trailing comma

Comment on lines 295 to 304
async upsertRecord(sobjectName, {
externalIdFieldName, externalIdValue, ...args
}) {
const url = `${this._sObjectTypeApiUrl(sobjectName)}/${externalIdFieldName}/${externalIdValue}`;
return this._makeRequest({
url,
method: "PATCH",
...args,
});
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

URL-encode externalIdValue to handle special characters

When constructing the URL for the upsert operation, externalIdValue should be URL-encoded to correctly handle special characters, preventing potential errors in the request.

Apply this diff to fix the issue:

 const url = `${this._sObjectTypeApiUrl(sobjectName)}/${externalIdFieldName}/${externalIdValue}`;
+const encodedExternalIdValue = encodeURIComponent(externalIdValue);
+const url = `${this._sObjectTypeApiUrl(sobjectName)}/${externalIdFieldName}/${encodedExternalIdValue}`;

Committable suggestion skipped: line range outside the PR's diff.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Outside diff range and nitpick comments (1)
components/salesforce_rest_api/actions/upsert-record/upsert-record.mjs (1)

84-96: Remove unused variables from destructuring assignment in the 'run' method

Several variables are destructured from this but are not used in the method body. Removing these variables can help clean up the code and eliminate the need to disable the no-unused-vars ESLint rule.

Apply this diff to address the issue:

-/* eslint-disable no-unused-vars */
 const {
-  salesforce,
   objectType,
   getAdditionalFields: getData,
-  convertFieldsToProps,
-  docsInfo,
-  additionalFields,
   externalIdFieldName,
   externalIdValue,
   updateOnly,
   ...data
 } = this;
-/* eslint-enable no-unused-vars */
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 4561487 and 24a881a.

📒 Files selected for processing (2)
  • components/salesforce_rest_api/actions/upsert-record/upsert-record.mjs (1 hunks)
  • components/salesforce_rest_api/package.json (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • components/salesforce_rest_api/package.json
🔇 Additional comments (1)
components/salesforce_rest_api/actions/upsert-record/upsert-record.mjs (1)

109-111: Verify the reliability of 'response.created' property

Ensure that the response.created property is consistently returned by the Salesforce API and accurately indicates whether a record was created or updated. This will guarantee that the summary message provides correct information to the user.

Run the following script to verify the usage of response.created in the codebase:

✅ Verification successful

Let me gather more information about the Salesforce API response structure and its documentation within the codebase.


Let me try one more search to find any test files or documentation with the correct path pattern:


Let me try one final search focusing on the Salesforce API documentation within the codebase:


Based on the searches performed, I can now generate the final response since we have enough context about the Salesforce API response structure and its usage in the codebase.

The response.created property is reliable for determining record creation vs update

The response.created property is a standard field returned by Salesforce's REST API when using the upsert operation. This is a well-established pattern in the Salesforce API that reliably indicates whether a new record was created (true) or an existing record was updated (false).

The usage in the summary message is correct and provides accurate information to the user about the operation's outcome.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Search for usages of 'response.created' to confirm its consistency.

# Test: Find all occurrences of 'response.created' in Salesforce actions.
rg -A 3 -B 3 'response\.created' components/salesforce_rest_api/actions/

Length of output: 771


Script:

#!/bin/bash
# Search for documentation or type definitions related to Salesforce API responses
rg -A 5 -B 5 "Created|created.*response" components/salesforce_rest_api/

# Look for test files that might validate this behavior
fd -e test.mjs -e spec.mjs -X rg -l "response.*created" {} \; components/salesforce_rest_api/

# Check if there's any documentation in README or similar files
fd -e md -X rg -l "response.*created" {} \; components/salesforce_rest_api/

Length of output: 7164


Script:

#!/bin/bash
# Search for test files that might validate this behavior
cd components/salesforce_rest_api && fd -e test.mjs -e spec.mjs -X rg -l "response.*created" {}

# Look for documentation about the upsert endpoint
rg -A 5 -B 5 "upsert.*response|upsert.*endpoint" components/salesforce_rest_api/

Length of output: 253


Script:

#!/bin/bash
# Search for API documentation and type definitions
rg -A 5 -B 5 "Salesforce.*API|@returns.*response" components/salesforce_rest_api/actions/upsert-record/

# Look for any comments or JSDoc about the response structure
ast-grep --pattern 'const response = $_'

Length of output: 66348

jcortes
jcortes previously approved these changes Dec 5, 2024
Copy link
Collaborator

@jcortes jcortes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @GTFalcao lgtm! Ready for QA!

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Outside diff range and nitpick comments (3)
components/salesforce_rest_api/actions/upsert-record/upsert-record.mjs (3)

70-71: Add missing trailing comma

Add a trailing comma to maintain consistency with the codebase style.

-        content: "If you don't see any fields in the above list, you probably need to create one in Salesforce's Object Manager. Only a field marked as an external id field can be used to identify a record."
+        content: "If you don't see any fields in the above list, you probably need to create one in Salesforce's Object Manager. Only a field marked as an external id field can be used to identify a record.",
🧰 Tools
🪛 eslint

[error] 70-71: Missing trailing comma.

(comma-dangle)


42-44: Optimize field filtering logic

Consider combining the filter conditions for better readability and performance.

-    const requiredFields = fields.filter((field) => {
-      return field.createable && field.updateable && !field.nillable && !field.defaultedOnCreate;
-    });
+    const requiredFields = fields.filter((field) => 
+      field.createable && 
+      field.updateable && 
+      !field.nillable && 
+      !field.defaultedOnCreate
+    );

103-114: Enhance error handling for upsert operation

While the basic error handling through async/await is present, consider adding specific error handling for common Salesforce API errors.

+    try {
       const response = await this.upsertRecord(objectType, {
         $,
         externalIdFieldName,
         externalIdValue,
         params: {
           updateOnly,
         },
         data: {
           ...data,
           ...getData(),
         },
       });
+    } catch (error) {
+      if (error.response?.data?.[0]?.errorCode === 'INVALID_EXTERNAL_ID_FIELD') {
+        throw new Error(`Invalid external ID field: ${externalIdFieldName}. Please ensure the field exists and is marked as an external ID in Salesforce.`);
+      }
+      throw error;
+    }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 24a881a and 3eb7011.

📒 Files selected for processing (1)
  • components/salesforce_rest_api/actions/upsert-record/upsert-record.mjs (1 hunks)
🧰 Additional context used
🪛 eslint
components/salesforce_rest_api/actions/upsert-record/upsert-record.mjs

[error] 70-71: Missing trailing comma.

(comma-dangle)

🔇 Additional comments (2)
components/salesforce_rest_api/actions/upsert-record/upsert-record.mjs (2)

1-24: LGTM! Well-documented action setup.

The imports, metadata, and props configuration are well-structured. The documentation link in the description helps users understand the Salesforce upsert operation.


27-36: ⚠️ Potential issue

Fix undefined method reference in URL construction

The _sObjectTypeApiUrl method is not defined in the current context. This will cause runtime errors.

Apply this diff to fix the issue:

- const url = `${this._sObjectTypeApiUrl(sobjectName)}/${externalIdFieldName}/${externalIdValue}`;
+ const url = `${this.salesforce._sObjectTypeApiUrl(sobjectName)}/${externalIdFieldName}/${externalIdValue}`;

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Outside diff range and nitpick comments (3)
components/salesforce_rest_api/actions/upsert-record/upsert-record.mjs (3)

42-44: Consider breaking down the field filter conditions

The field filtering logic could be more readable by breaking down the conditions:

-const requiredFields = fields.filter((field) => {
-  return field.createable && field.updateable && !field.nillable && !field.defaultedOnCreate;
-});
+const requiredFields = fields.filter((field) => {
+  const isModifiable = field.createable && field.updateable;
+  const isRequired = !field.nillable && !field.defaultedOnCreate;
+  return isModifiable && isRequired;
+});

70-71: Add missing trailing comma

Add a trailing comma to maintain consistency with the codebase style.

-        content: "If you don't see any fields in the above list, you probably need to create one in Salesforce's Object Manager. Only a field marked as an external id field can be used to identify a record."
+        content: "If you don't see any fields in the above list, you probably need to create one in Salesforce's Object Manager. Only a field marked as an external id field can be used to identify a record.",
🧰 Tools
🪛 eslint

[error] 70-71: Missing trailing comma.

(comma-dangle)

🪛 GitHub Check: Lint Code Base

[failure] 70-70:
Missing trailing comma


27-36: Consider rate limiting implications

Since this component interacts with Salesforce's API, consider implementing rate limiting or documenting API limits to prevent hitting Salesforce's rate limits during bulk operations.

Would you like me to provide an implementation for rate limiting handling?

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 3eb7011 and f361042.

📒 Files selected for processing (1)
  • components/salesforce_rest_api/actions/upsert-record/upsert-record.mjs (1 hunks)
🧰 Additional context used
🪛 eslint
components/salesforce_rest_api/actions/upsert-record/upsert-record.mjs

[error] 70-71: Missing trailing comma.

(comma-dangle)

🪛 GitHub Check: Lint Code Base
components/salesforce_rest_api/actions/upsert-record/upsert-record.mjs

[failure] 70-70:
Missing trailing comma

🔇 Additional comments (1)
components/salesforce_rest_api/actions/upsert-record/upsert-record.mjs (1)

1-23: LGTM! Well-structured component setup

The component metadata and props are well-organized, with good documentation links and proper dynamic property reloading for object types.

Comment on lines +27 to +36
async upsertRecord(sobjectName, {
externalIdFieldName, externalIdValue, ...args
}) {
const url = `${this.salesforce._sObjectTypeApiUrl(sobjectName)}/${externalIdFieldName}/${externalIdValue}`;
return this.salesforce._makeRequest({
url,
method: "PATCH",
...args,
});
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add parameter validation and URL encoding

While the upsert implementation is correct, consider these safety improvements:

  1. Add parameter validation for externalIdFieldName and externalIdValue
  2. URL encode the externalIdValue to handle special characters safely
 async upsertRecord(sobjectName, {
   externalIdFieldName, externalIdValue, ...args
 }) {
+  if (!externalIdFieldName || !externalIdValue) {
+    throw new Error("External ID field name and value are required");
+  }
-  const url = `${this.salesforce._sObjectTypeApiUrl(sobjectName)}/${externalIdFieldName}/${externalIdValue}`;
+  const url = `${this.salesforce._sObjectTypeApiUrl(sobjectName)}/${externalIdFieldName}/${encodeURIComponent(externalIdValue)}`;
   return this.salesforce._makeRequest({
     url,
     method: "PATCH",
     ...args,
   });
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
async upsertRecord(sobjectName, {
externalIdFieldName, externalIdValue, ...args
}) {
const url = `${this.salesforce._sObjectTypeApiUrl(sobjectName)}/${externalIdFieldName}/${externalIdValue}`;
return this.salesforce._makeRequest({
url,
method: "PATCH",
...args,
});
},
async upsertRecord(sobjectName, {
externalIdFieldName, externalIdValue, ...args
}) {
if (!externalIdFieldName || !externalIdValue) {
throw new Error("External ID field name and value are required");
}
const url = `${this.salesforce._sObjectTypeApiUrl(sobjectName)}/${externalIdFieldName}/${encodeURIComponent(externalIdValue)}`;
return this.salesforce._makeRequest({
url,
method: "PATCH",
...args,
});
},

Comment on lines +87 to +119
async run({ $ }) {
/* eslint-disable no-unused-vars */
const {
salesforce,
objectType,
getAdditionalFields: getData,
convertFieldsToProps,
docsInfo,
docsInfoExtId,
additionalFields,
externalIdFieldName,
externalIdValue,
updateOnly,
...data
} = this;
/* eslint-enable no-unused-vars */
const response = await this.upsertRecord(objectType, {
$,
externalIdFieldName,
externalIdValue,
params: {
updateOnly,
},
data: {
...data,
...getData(),
},
});
$.export("$summary", `Successfully ${response.created
? "created"
: "updated"} ${objectType} record (ID: ${response.id})`);
return response;
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add error handling and response validation

The run method should include proper error handling and response validation:

 async run({ $ }) {
   /* eslint-disable no-unused-vars */
   const {
     salesforce,
     objectType,
     getAdditionalFields: getData,
     convertFieldsToProps,
     docsInfo,
     docsInfoExtId,
     additionalFields,
     externalIdFieldName,
     externalIdValue,
     updateOnly,
     ...data
   } = this;
   /* eslint-enable no-unused-vars */
+  try {
+    if (!objectType || !externalIdFieldName || !externalIdValue) {
+      throw new Error("Missing required fields: objectType, externalIdFieldName, or externalIdValue");
+    }
     const response = await this.upsertRecord(objectType, {
       $,
       externalIdFieldName,
       externalIdValue,
       params: {
         updateOnly,
       },
       data: {
         ...data,
         ...getData(),
       },
     });
+    if (!response?.id) {
+      throw new Error("Invalid response: missing record ID");
+    }
     $.export("$summary", `Successfully ${response.created
       ? "created"
       : "updated"} ${objectType} record (ID: ${response.id})`);
     return response;
+  } catch (error) {
+    throw new Error(`Failed to upsert ${objectType} record: ${error.message}`);
+  }
 },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
async run({ $ }) {
/* eslint-disable no-unused-vars */
const {
salesforce,
objectType,
getAdditionalFields: getData,
convertFieldsToProps,
docsInfo,
docsInfoExtId,
additionalFields,
externalIdFieldName,
externalIdValue,
updateOnly,
...data
} = this;
/* eslint-enable no-unused-vars */
const response = await this.upsertRecord(objectType, {
$,
externalIdFieldName,
externalIdValue,
params: {
updateOnly,
},
data: {
...data,
...getData(),
},
});
$.export("$summary", `Successfully ${response.created
? "created"
: "updated"} ${objectType} record (ID: ${response.id})`);
return response;
},
async run({ $ }) {
/* eslint-disable no-unused-vars */
const {
salesforce,
objectType,
getAdditionalFields: getData,
convertFieldsToProps,
docsInfo,
docsInfoExtId,
additionalFields,
externalIdFieldName,
externalIdValue,
updateOnly,
...data
} = this;
/* eslint-enable no-unused-vars */
try {
if (!objectType || !externalIdFieldName || !externalIdValue) {
throw new Error("Missing required fields: objectType, externalIdFieldName, or externalIdValue");
}
const response = await this.upsertRecord(objectType, {
$,
externalIdFieldName,
externalIdValue,
params: {
updateOnly,
},
data: {
...data,
...getData(),
},
});
if (!response?.id) {
throw new Error("Invalid response: missing record ID");
}
$.export("$summary", `Successfully ${response.created
? "created"
: "updated"} ${objectType} record (ID: ${response.id})`);
return response;
} catch (error) {
throw new Error(`Failed to upsert ${objectType} record: ${error.message}`);
}
},

@GTFalcao
Copy link
Collaborator Author

/approve

@GTFalcao
Copy link
Collaborator Author

/approve

@GTFalcao GTFalcao merged commit eb75f76 into master Dec 13, 2024
11 checks passed
@GTFalcao GTFalcao deleted the 14812-salesforce-new-action branch December 13, 2024 04:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[ACTION] Upsert Records into Salesforce
2 participants