Skip to content
Open
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import ip2location from "../../ip2location_io.app.mjs";

export default {
key: "ip2location_io-lookup-hosted-domain",
name: "Lookup Hosted Domain",
description: "Retrieve the list of hosted domains on an IP Address. [See the docs here](https://www.ip2location.io/ip2whois-domains-documentation)",
version: "0.0.1",
type: "action",
props: {
ip2location,
ip: {
type: "string",
label: "IP Address",
description: "IP address (IPv4 or IPv6) to lookup",
},
format: {
propDefinition: [
ip2location,
"format",
],
},
page: {
type: "integer",
label: "Page",
description: "Pagination result returns of the hosted domains. If unspecified, 1st page will be used.",
optional: true,
},
},
async run({ $ }) {
try {
const response = await this.ip2location.lookupHostedDomain({
params: {
ip: this.ip,
format: this.format,
page: this.page,
},
});
if (response && response.total_domains) {
$.export(
"$summary",
`Successfully retrieved hosted domain information about IP ${this.ip}.`

Check failure on line 41 in components/ip2location_io/actions/lookup-hosted-domain/lookup-hosted-domain.mjs

View workflow job for this annotation

GitHub Actions / Lint Code Base

Missing trailing comma
);
}
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

Fix linting errors and improve response checking

Two issues need to be addressed in this section:

  1. There's a missing trailing comma at the end of line 41 causing a build failure
  2. The response check should use optional chaining for better safety

Also, consider improving the summary message to include the count of domains found.

-      if (response && response.total_domains) {
+      if (response?.total_domains) {
        $.export(
          "$summary",
-          `Successfully retrieved hosted domain information about IP ${this.ip}.`
+          `Successfully retrieved ${response.total_domains} hosted domains for IP ${this.ip}.`,
        );
      }
📝 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
if (response && response.total_domains) {
$.export(
"$summary",
`Successfully retrieved hosted domain information about IP ${this.ip}.`
);
}
if (response?.total_domains) {
$.export(
"$summary",
`Successfully retrieved ${response.total_domains} hosted domains for IP ${this.ip}.`,
);
}
🧰 Tools
🪛 Biome (1.9.4)

[error] 38-38: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

🪛 GitHub Check: Lint Code Base

[failure] 41-41:
Missing trailing comma

🪛 GitHub Actions: Pull Request Checks

[error] 41-41: ESLint: Missing trailing comma (comma-dangle)

return response;
} catch (error) {
throw new Error(`Error retrieving hosted domains: ${error.message}`);
}
},
};
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Verify API behavior with pagination

The action supports a page parameter for pagination, but there's no validation or handling for cases where there are no results for the requested page.

Could you test the API behavior when:

  1. The requested page is beyond available results
  2. The IP address has no hosted domains

🏁 Script executed:

#!/bin/bash
# Check the API documentation for pagination behavior
curl -s "https://www.ip2location.io/ip2whois-domains-documentation" | grep -A 10 -i pagination

# Check if there are any example implementation files in the repository
fd -t f -e js -e mjs | xargs grep -l "page.*pagination" | head -5

Length of output: 2345


Handle empty results and enforce page bounds in pagination

Add explicit checks after calling the API to cover edge cases:

  • If response.total_domains === 0, export a summary like
    "No hosted domains found for IP ${this.ip}." and return immediately.
  • If this.page is provided and exceeds response.total_pages, throw an error indicating the page is out of range.

See the API Pagination docs for guidance:
https://www.ip2location.io/ip2whois-domains-documentation#apipage

Affected file:

  • components/ip2location_io/actions/lookup-hosted-domain/lookup-hosted-domain.mjs

Proposed diff:

   async run({ $ }) {
     try {
       const response = await this.ip2location.lookupHostedDomain({
         params: {
           ip: this.ip,
           format: this.format,
           page: this.page,
         },
       });
+      // No hosted domains found
+      if (response && response.total_domains === 0) {
+        $.export(
+          "$summary",
+          `No hosted domains found for IP ${this.ip}.`
+        );
+        return response;
+      }
+      // Requested page is beyond available pages
+      if (this.page && response.total_pages && this.page > response.total_pages) {
+        throw new Error(
+          `Requested page ${this.page} exceeds total pages ${response.total_pages}.`
+        );
+      }
       // Successful lookup
       if (response && response.total_domains) {
         $.export(
           "$summary",
           `Successfully retrieved hosted domain information about IP ${this.ip}.`
         );
       }
       return response;
     } catch (error) {
       throw new Error(`Error retrieving hosted domains: ${error.message}`);
     }
   },

Please implement these checks and verify the behavior for:

  1. An IP address with no hosted domains.
  2. A page number beyond the available pages.
📝 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
import ip2location from "../../ip2location_io.app.mjs";
export default {
key: "ip2location_io-lookup-hosted-domain",
name: "Lookup Hosted Domain",
description: "Retrieve the list of hosted domains on an IP Address. [See the docs here](https://www.ip2location.io/ip2whois-domains-documentation)",
version: "0.0.1",
type: "action",
props: {
ip2location,
ip: {
type: "string",
label: "IP Address",
description: "IP address (IPv4 or IPv6) to lookup",
},
format: {
propDefinition: [
ip2location,
"format",
],
},
page: {
type: "integer",
label: "Page",
description: "Pagination result returns of the hosted domains. If unspecified, 1st page will be used.",
optional: true,
},
},
async run({ $ }) {
try {
const response = await this.ip2location.lookupHostedDomain({
params: {
ip: this.ip,
format: this.format,
page: this.page,
},
});
if (response && response.total_domains) {
$.export(
"$summary",
`Successfully retrieved hosted domain information about IP ${this.ip}.`
);
}
return response;
} catch (error) {
throw new Error(`Error retrieving hosted domains: ${error.message}`);
}
},
};
async run({ $ }) {
try {
const response = await this.ip2location.lookupHostedDomain({
params: {
ip: this.ip,
format: this.format,
page: this.page,
},
});
// No hosted domains found
if (response && response.total_domains === 0) {
$.export(
"$summary",
`No hosted domains found for IP ${this.ip}.`
);
return response;
}
// Requested page is beyond available pages
if (this.page && response.total_pages && this.page > response.total_pages) {
throw new Error(
`Requested page ${this.page} exceeds total pages ${response.total_pages}.`
);
}
// Successful lookup
if (response && response.total_domains) {
$.export(
"$summary",
`Successfully retrieved hosted domain information about IP ${this.ip}.`
);
}
return response;
} catch (error) {
throw new Error(`Error retrieving hosted domains: ${error.message}`);
}
},
🧰 Tools
🪛 Biome (1.9.4)

[error] 38-38: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

🪛 GitHub Check: Lint Code Base

[failure] 41-41:
Missing trailing comma

🪛 GitHub Actions: Pull Request Checks

[error] 41-41: ESLint: Missing trailing comma (comma-dangle)

Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export default {
key: "ip2location_io-lookup-ip-address",
name: "Lookup IP Address",
description: "Retrieve geolocation data about an IP Address. [See the docs here](https://www.ip2location.io/ip2location-documentation)",
version: "0.0.1",
version: "0.0.2",
type: "action",
props: {
ip2location,
Expand Down
29 changes: 28 additions & 1 deletion components/ip2location_io/ip2location_io.app.mjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { axios } from "@pipedream/platform";

const BASE_URL = "https://api.ip2location.io";
const DOMAINS_URL = "https://domains.ip2whois.com/domains";

export default {
type: "app",
app: "ip2location_io",
Expand Down Expand Up @@ -34,9 +37,33 @@
...args,
});
},
/**
* Lookup geolocation information for an IP address
* @param {Object} args - The arguments for the request
* @param {Object} [args.params] - The query parameters
* @param {string} [args.params.ip] - The IP address to lookup (IPv4 or IPv6)
* @param {string} [args.params.format] - Response format (json or xml)
* @param {string} [args.params.lang] - Translation information(ISO639-1) for continent, country, region and city name

Check failure on line 46 in components/ip2location_io/ip2location_io.app.mjs

View workflow job for this annotation

GitHub Actions / Lint Code Base

This line has a length of 122. Maximum allowed is 100
* @returns {Promise<Object>} The hosted domain information
*/
lookupIpAddress(args = {}) {
return this._makeRequest({
url: "https://api.ip2location.io",
url: BASE_URL,
...args,
});
},
/**
* Lookup hosted domains for an IP address
* @param {Object} args - The arguments for the request
* @param {Object} [args.params] - The query parameters
* @param {string} [args.params.ip] - The IP address to lookup (IPv4 or IPv6)
* @param {string} [args.params.format] - Response format (json or xml)
* @param {number} [args.params.page] - Page number for pagination
* @returns {Promise<Object>} The hosted domain information
*/
lookupHostedDomain(args = {}) {
return this._makeRequest({
url: DOMAINS_URL,
...args,
});
},
Expand Down
2 changes: 1 addition & 1 deletion components/ip2location_io/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@pipedream/ip2location_io",
"version": "0.1.0",
"version": "0.2.0",
"description": "Pipedream IP2Location.io Components",
"main": "ip2location_io.app.mjs",
"keywords": [
Expand Down
Loading