Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions components/finerworks/actions/get-prices/get-prices.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import app from "../../finerworks.app.mjs";

export default {
key: "finerworks-get-prices",
name: "Get Prices",
description: "Get the price of a product. [See the documentation](https://v2.api.finerworks.com/Help/Api/POST-v3-get_prices)",
version: "0.0.1",
annotations: {
destructiveHint: false,
openWorldHint: true,
readOnlyHint: true,
},
type: "action",
props: {
app,
productSku: {
propDefinition: [
app,
"productSku",
],
},
productQty: {
propDefinition: [
app,
"productQty",
],
},
},
async run({ $ }) {
const response = await this.app.getPrices({
$,
data: {
products: [
{
product_qty: this.productQty,
product_sku: this.productSku,
},
],
},
});
$.export("$summary", `Successfully retrieved ${response.prices.length} ${response.prices.length > 1
? "prices"
: "price"} for product SKU ${this.productSku}`);
Comment on lines +41 to +43
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

🧩 Analysis chain

Simplify summary and verify response structure.

The inline ternary for pluralization reduces readability. Consider simplifying or extracting to a helper. Additionally, verify that the API response structure includes response.prices as an array, since this code assumes that structure without validation.

Apply this diff to simplify:

-    $.export("$summary", `Successfully retrieved ${response.prices.length} ${response.prices.length > 1
-      ? "prices"
-      : "price"} for product SKU ${this.productSku}`);
+    const count = response.prices?.length || 0;
+    const pluralized = count === 1 ? "price" : "prices";
+    $.export("$summary", `Successfully retrieved ${count} ${pluralized} for product SKU ${this.productSku}`);

Run the following script to verify the response structure from the API:


🏁 Script executed:

#!/bin/bash
# Verify that getPrices returns an object with a 'prices' array property
rg -n "prices" components/finerworks/ --type js -A 2 -B 2

Length of output: 0





---

🏁 Script executed:

```shell
#!/bin/bash
# Find and examine the get-prices.mjs file
find . -name "get-prices.mjs" -type f 2>/dev/null | head -5

Length of output: 57


🏁 Script executed:

#!/bin/bash
# List contents of finerworks actions directory to understand structure
fd --type f . components/finerworks/actions/ 2>/dev/null | head -20

Length of output: 197


🏁 Script executed:

#!/bin/bash
# Search for API response handling in finerworks component
rg -n "response\." components/finerworks/ --type js -C 2 2>/dev/null | head -50

Length of output: 0



---

🏁 Script executed:

```shell
#!/bin/bash
# Read the full get-prices.mjs file to understand the response structure
cat ./components/finerworks/actions/get-prices/get-prices.mjs

Length of output: 1046



---

🏁 Script executed:

```shell
#!/bin/bash
# Read the finerworks.app.mjs to understand getPrices return structure
cat ./components/finerworks/finerworks.app.mjs

Length of output: 3543


Simplify summary and add defensive response handling.

The inline ternary for pluralization reduces readability. Additionally, the code directly accesses response.prices.length without validating the response structure, which could fail if the API returns an unexpected format.

Consider extracting the pluralization logic and using optional chaining for defensive programming:

-    $.export("$summary", `Successfully retrieved ${response.prices.length} ${response.prices.length > 1
-      ? "prices"
-      : "price"} for product SKU ${this.productSku}`);
+    const count = response.prices?.length || 0;
+    const pluralized = count === 1 ? "price" : "prices";
+    $.export("$summary", `Successfully retrieved ${count} ${pluralized} for product SKU ${this.productSku}`);
🤖 Prompt for AI Agents
In components/finerworks/actions/get-prices/get-prices.mjs around lines 41 to
43, simplify the summary by extracting pluralization into a small variable and
make response access defensive: compute count = response?.prices?.length ?? 0,
build label = count === 1 ? "price" : "prices", then use those in the summary
string so it no longer inlines the ternary and will not throw if response or
prices is missing.

return response;
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import app from "../../finerworks.app.mjs";

export default {
key: "finerworks-get-product-details",
name: "Get Product Details",
description: "Get details of a product. [See the documentation](https://v2.api.finerworks.com/Help/Api/POST-v3-get_product_details)",
version: "0.0.1",
annotations: {
destructiveHint: false,
openWorldHint: true,
readOnlyHint: true,
},
type: "action",
props: {
app,
productSku: {
propDefinition: [
app,
"productSku",
],
},
productQty: {
propDefinition: [
app,
"productQty",
],
},
},
async run({ $ }) {
const response = await this.app.getProductDetails({
$,
data: {
products: [
{
product_sku: this.productSku,
product_qty: this.productQty,
},
],
},
});
$.export("$summary", `Successfully retrived details for product SKU ${this.productSku}`);
return response;
},
};
105 changes: 105 additions & 0 deletions components/finerworks/actions/validate-address/validate-address.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import app from "../../finerworks.app.mjs";

export default {
key: "finerworks-validate-address",
name: "Validate Address",
description: "Validate an address. [See the documentation](https://v2.api.finerworks.com/Help/Api/POST-v3-validate_recipient_address)",
version: "0.0.1",
annotations: {
destructiveHint: false,
openWorldHint: true,
readOnlyHint: true,
},
type: "action",
props: {
app,
firstName: {
propDefinition: [
app,
"firstName",
],
},
lastName: {
propDefinition: [
app,
"lastName",
],
},
companyName: {
propDefinition: [
app,
"companyName",
],
},
address: {
propDefinition: [
app,
"address",
],
},
city: {
propDefinition: [
app,
"city",
],
},
stateCode: {
propDefinition: [
app,
"stateCode",
],
},
province: {
propDefinition: [
app,
"province",
],
},
zipPostalCode: {
propDefinition: [
app,
"zipPostalCode",
],
},
countryCode: {
propDefinition: [
app,
"countryCode",
],
},
phone: {
propDefinition: [
app,
"phone",
],
},
email: {
propDefinition: [
app,
"email",
],
},
},
async run({ $ }) {
const response = await this.app.validateAddress({
$,
data: {
recipient: {
first_name: this.firstName,
last_name: this.lastName,
company_name: this.companyName,
address_1: this.address,
city: this.city,
state_code: this.stateCode,
province: this.province,
zip_postal_code: this.zipPostalCode,
country_code: this.countryCode,
phone: this.phone,
email: this.email,
},
},
});
$.export("$summary", "Successfully valid the address: " + response.status.success);
return response;
},
};
146 changes: 142 additions & 4 deletions components/finerworks/finerworks.app.mjs
Original file line number Diff line number Diff line change
@@ -1,11 +1,149 @@
import { axios } from "@pipedream/platform";

export default {
type: "app",
app: "finerworks",
propDefinitions: {},
propDefinitions: {
firstName: {
type: "string",
label: "First Name",
description: "Recipient first name",
},
lastName: {
type: "string",
label: "Last Name",
description: "Recipient last name",
},
companyName: {
type: "string",
label: "Company Name",
description: "Recipient company name",
optional: true,
},
address: {
type: "string",
label: "Address",
description: "Street address for the recipient",
},
city: {
type: "string",
label: "City",
description: "Recipient city",
optional: true,
},
stateCode: {
type: "string",
label: "State Code",
description: "Required if in U.S. A valid USPS recognized 2 digit state code, i.e.: `CA`",
optional: true,
},
province: {
type: "string",
label: "Province",
description: "Province or region name",
optional: true,
},
zipPostalCode: {
type: "string",
label: "ZIP or Postal Code",
description: "ZIP or postal code of the recipient",
},
countryCode: {
type: "string",
label: "Country Code",
description: "Two-letter ISO country code, e.g.: `US`, `CA`, `GB`",
},
phone: {
type: "string",
label: "Phone",
description: "Recipient phone number",
optional: true,
},
email: {
type: "string",
label: "Email",
description: "Recipient email address",
optional: true,
},
productQty: {
type: "integer",
label: "Product Quantity",
description: "Quantity of the product",
},
productSku: {
type: "string",
label: "Product SKU",
description: "SKU identifier of the product",
async options() {
const response = await this.getProducts();
const products = response.products;
return products.map(({
sku, name,
}) => ({
label: name,
value: sku,
}));
},
},
},
methods: {
// this.$auth contains connected account data
authKeys() {
console.log(Object.keys(this.$auth));
_baseUrl() {
return "https://v2.api.finerworks.com/v3";
},
async _makeRequest(opts = {}) {
const {
$ = this,
path,
headers,
...otherOpts
} = opts;
console.log({
...otherOpts,
url: this._baseUrl() + path,
headers: {
"web_api_key": `${this.$auth.web_api_key}`,
"app_key": `${this.$auth.app_key}`,
...headers,
},
});
Comment on lines +100 to +108
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 | 🔴 Critical

Remove debug console.log statement that logs sensitive credentials.

This console.log outputs the entire request configuration including authentication headers (web_api_key and app_key). Logging credentials in production code creates a security risk, as these logs may be exposed in log aggregation systems, CI/CD pipelines, or monitoring tools.

Apply this diff to remove the debug statement:

-      console.log({
-        ...otherOpts,
-        url: this._baseUrl() + path,
-        headers: {
-          "web_api_key": `${this.$auth.web_api_key}`,
-          "app_key": `${this.$auth.app_key}`,
-          ...headers,
-        },
-      });
       return axios($, {
📝 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
console.log({
...otherOpts,
url: this._baseUrl() + path,
headers: {
"web_api_key": `${this.$auth.web_api_key}`,
"app_key": `${this.$auth.app_key}`,
...headers,
},
});
🤖 Prompt for AI Agents
In components/finerworks/finerworks.app.mjs around lines 100 to 108, there is a
debug console.log that prints the full request config including sensitive
headers (web_api_key and app_key); remove this console.log entirely (or replace
it with a non-sensitive debug log that omits headers and credential values) so
credentials are never written to logs, and if debugging is needed, log only safe
fields (e.g., method, url, and sanitized headers) behind a guarded debug flag.

return axios($, {
...otherOpts,
url: this._baseUrl() + path,
headers: {
"web_api_key": `${this.$auth.web_api_key}`,
"app_key": `${this.$auth.app_key}`,
Comment on lines +113 to +114
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Remove unnecessary template literals.

The authentication keys are already strings and don't need template literal wrapping. This simplifies the code without changing behavior.

Apply this diff:

         headers: {
-          "web_api_key": `${this.$auth.web_api_key}`,
-          "app_key": `${this.$auth.app_key}`,
+          "web_api_key": this.$auth.web_api_key,
+          "app_key": this.$auth.app_key,
           ...headers,
         },
📝 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
"web_api_key": `${this.$auth.web_api_key}`,
"app_key": `${this.$auth.app_key}`,
headers: {
"web_api_key": this.$auth.web_api_key,
"app_key": this.$auth.app_key,
...headers,
},
🤖 Prompt for AI Agents
In components/finerworks/finerworks.app.mjs around lines 113 to 114, the code
wraps this.$auth.web_api_key and this.$auth.app_key in unnecessary template
literals; replace the template literals with direct property references (use
this.$auth.web_api_key and this.$auth.app_key as plain values) so the keys
remain strings but without the redundant interpolation.

...headers,
},
});
},
async validateAddress(args = {}) {
return this._makeRequest({
path: "/validate_recipient_address",
method: "post",
...args,
});
},
async getPrices(args = {}) {
return this._makeRequest({
path: "/get_prices",
method: "post",
...args,
});
},
async getProductDetails(args = {}) {
return this._makeRequest({
path: "/get_product_details",
method: "post",
...args,
});
},
async getProducts(args = {}) {
return this._makeRequest({
path: "/list_virtual_inventory",
method: "post",
data: {},
...args,
});
},
},
};
5 changes: 4 additions & 1 deletion components/finerworks/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@pipedream/finerworks",
"version": "0.0.1",
"version": "0.1.0",
"description": "Pipedream FinerWorks Components",
"main": "finerworks.app.mjs",
"keywords": [
Expand All @@ -11,5 +11,8 @@
"author": "Pipedream <[email protected]> (https://pipedream.com/)",
"publishConfig": {
"access": "public"
},
"dependencies": {
"@pipedream/platform": "^3.1.0"
}
}
Loading