Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,11 @@ const options = {
}

// Set custom parameters for the email validation request.
api.email
api.email()
.setCustomId("CustomRequestID") // Sets a custom request ID.
.setClientIP("127.0.0.1") // Sets the client IP address.
.setClientCountry("CZ") // Sets the client country code.
.includeRequestDetails(true) // Returns the request in API response
.setOptions(options)
.validate(query) // Sends request to Foxentry API and performs email validation.
.then((res: Response): void => {
Expand All @@ -72,7 +73,6 @@ It offers the following methods:
|-----------------------|------------------|----------------------------------------------|
| setAuth | `API key` | Sets API key, that will be used in requests |
| setApiVersion | `version number` | Sets specific API version, that will be used |
| includeRequestDetails | `true/false` | Includes request details with every request |

To access various resources from this class, simply provide the resource name, and you will be able to access the resource's methods, e.g., `api.email.search(query)`, `api.company.get(query)`, etc.

Expand Down Expand Up @@ -117,4 +117,4 @@ Response class is returned with every request providing methods below:

## Testing

The library includes unit tests to ensure its functionality and provide examples of how the library can be used. You can run the tests using Jest. Don't forget to set your API key for these tests, located in the \test\config.ts file.
The library includes unit tests to ensure its functionality and provide examples of how the library can be used. You can run the tests using Jest. Don't forget to set your API key for these tests, located in the \test\config.ts file.
23 changes: 17 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@foxentry/js-sdk",
"version": "1.0.3",
"version": "1.1.0",
"main": "dist/index.js",
"module": "dist/index.m.js",
"unpkg": "dist/index.umd.js",
Expand Down Expand Up @@ -41,6 +41,7 @@
"ts-jest": "^29.1.2"
},
"dependencies": {
"axios": "^1.6.8"
"axios": "^1.7.5",
"ipaddr.js": "^2.2.0"
}
}
85 changes: 37 additions & 48 deletions src/ApiClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,91 +11,80 @@ import Phone from './Resource/Phone';
*/
export default class ApiClient {
/**
* Email resource.
* Api key
*/
public email: Email;
private apiKey: string | null = null;

/**
* Location resource.
* Api version
*/
public location: Location;
private apiVersion: string = '2.0';

/**
* Company resource.
* ApiClient constructor.
* @param apiKey The API key for authentication
*/
public company: Company;
constructor(apiKey: string | null = null) {
this.apiKey = apiKey;
}

/**
* Name resource.
* Email resource.
*/
public name: Name;
public email(): Email {
const request = new Request(this.apiVersion, this.apiKey);
return new Email(request);
}

/**
* Phone resource.
* Location resource.
*/
public phone: Phone;
public location(): Location {
const request = new Request(this.apiVersion, this.apiKey);
return new Location(request);
}

/**
* Request object for making API requests.
* Company resource.
*/
private request: Request;
public company(): Company {
const request = new Request(this.apiVersion, this.apiKey);
return new Company(request);
}

/**
* ApiClient constructor.
* @param apiKey The API key for authentication
* Name resource.
*/
constructor(apiKey: string | null = null) {
this.request = new Request();

if (apiKey) {
this.request.setAuth(apiKey);
}

this.company = new Company(this.request);
this.email = new Email(this.request);
this.location = new Location(this.request);
this.name = new Name(this.request);
this.phone = new Phone(this.request);
public name(): Name {
const request = new Request(this.apiVersion, this.apiKey);
return new Name(request);
}

/**
* Sets the base URL for API requests.
*
* @param {string} url - The base URL to set.
* @return {ApiClient}
* Phone resource.
*/
public setBaseURL(url: string): ApiClient {
this.request.setBaseURL(url);
return this;
public phone(): Phone {
const request = new Request(this.apiVersion, this.apiKey);
return new Phone(request);
}

/**
* Set API key for authentication.
* @param apiKey The API key to set
* @return {ApiClient}
* @return {ApiClient}
*/
public setAuth(apiKey: string): ApiClient {
this.request.setAuth(apiKey);
this.apiKey = apiKey;
return this;
}

/**
* Set the API version for requests.
* @param version The API version to set
* @return {ApiClient}
* @return {ApiClient}
*/
public setApiVersion(version: string): ApiClient {
this.request.setHeader("Api-Version", version);
return this;
}

/**
* Include request details in API responses.
* @param value Whether to include request details (default: true)
* @return {ApiClient}
*/
public includeRequestDetails(value: boolean = true): ApiClient {
this.request.setHeader("Foxentry-Include-Request-Details", value);
this.apiVersion = version;
return this;
}
}
}
30 changes: 15 additions & 15 deletions src/Request.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ExceptionBuilder } from './Exception/ExceptionBuilder';
import axios, { Axios, AxiosResponse } from "axios";
import { ExceptionBuilder } from './Exception/ExceptionBuilder'
import axios, { Axios, AxiosResponse } from 'axios'
import * as ipaddr from 'ipaddr.js';

/**
* Request class for handling API requests.
Expand All @@ -11,7 +12,7 @@ export default class Request {
"Foxentry-Include-Request-Details": false,
"Content-Type": "application/json",
"Accept": "application/json",
"User-Agent": "sdk/javascript"
"User-Agent": "FoxentrySdk (JS/1.1.0; ApiReference/2.0)"
};
private body: object | null = null;
private customId: string | null = null;
Expand All @@ -22,7 +23,13 @@ export default class Request {
private apiKey: string = "";
private client: Record<string, any> | null = null;

constructor() {
constructor(apiVersion: string, apiKey?: string|null) {
this.setHeader("Api-Version", apiVersion);

if (apiKey){
this.setAuth(apiKey);
}

this.httpClient = axios.create({
baseURL: this.baseUri
});
Expand All @@ -49,17 +56,12 @@ export default class Request {
this.options = options;
}

public setBaseURL(url: string): void {
this.baseUri = url;
this.httpClient.defaults.baseURL = this.baseUri;
}

public setEndpoint(endpoint: string): void {
this.endpoint = endpoint;
}

public setClientIP(ip: string): void {
if (!ip.match(/\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b/)) {
if (!ipaddr.isValid(ip)) {
throw new Error("The specified IP address is not valid.");
}

Expand All @@ -86,14 +88,12 @@ export default class Request {
this.buildBody();
this.validate();

const response = await this.httpClient.request({
return await this.httpClient.request({
method: this.method,
url: this.endpoint,
headers: this.headers,
data: JSON.stringify(this.body)
})

return response;
});
} catch (error: any) {
if (error?.isAxiosError)
throw ExceptionBuilder.fromRequestException(error);
Expand Down Expand Up @@ -131,4 +131,4 @@ export default class Request {
throw new Error("Request body is empty.");
}
}
}
}
14 changes: 12 additions & 2 deletions src/Resource/BaseResource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@ export default abstract class BaseResource {
this.request = request;
}

/**
* Include request details in API responses.
* @param value Whether to include request details (default: true)
* @return {ApiClient}
*/
public includeRequestDetails(value: boolean = true): this {
this.request.setHeader("Foxentry-Include-Request-Details", value);
return this;
}

/**
* Sets a custom ID for the resource.
*
Expand Down Expand Up @@ -89,11 +99,11 @@ export default abstract class BaseResource {
/**
* Sends a request to the specified endpoint with the given query parameters.
*
* @param {Record<string, any>} query - The query parameters to send with the request.
* @param {string} endpoint - The endpoint to call e.g. "email/validate".
* @param {Record<string, any>} query - The query parameters to send with the request.
* @return {Promise<Response>} A promise that resolves to the response from the request.
*/
protected async send(query: Record<string, any>, endpoint: Endpoint): Promise<Response> {
protected async send(endpoint: Endpoint, query: Record<string, any>): Promise<Response> {
this.request.setEndpoint(endpoint);
this.request.setQuery(query);
const r = await this.request.send()
Expand Down
6 changes: 3 additions & 3 deletions src/Resource/Company.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export default class Company extends BaseResource {
* @returns A promise resolving to the response from the validation request
*/
public validate(query: Record<string, any>): Promise<Response> {
return super.send(query, Endpoint.CompanyValidate);
return super.send(Endpoint.CompanyValidate, query);
}

/**
Expand All @@ -24,7 +24,7 @@ export default class Company extends BaseResource {
* @returns A promise resolving to the response from the API
*/
public search(query: Record<string, any>): Promise<Response> {
return super.send(query, Endpoint.CompanySearch);
return super.send(Endpoint.CompanySearch, query);
}

/**
Expand All @@ -35,6 +35,6 @@ export default class Company extends BaseResource {
* @returns A promise resolving to the response from the API
*/
public get(query: Record<string, any>): Promise<Response> {
return super.send(query, Endpoint.CompanyGet);
return super.send(Endpoint.CompanyGet, query);
}
}
6 changes: 3 additions & 3 deletions src/Resource/Email.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export default class Email extends BaseResource {
*/
public validate(query: string | Record<string, any>): Promise<Response> {
const emailQuery = typeof query === 'string' ? { email: query } : query;
return super.send(emailQuery, Endpoint.EmailValidate);
return super.send(Endpoint.EmailValidate, emailQuery);
}


Expand All @@ -26,6 +26,6 @@ export default class Email extends BaseResource {
*/
public search(query: string | Record<string, any>): Promise<Response> {
const searchQuery = typeof query === 'string' ? { value: query } : query;
return super.send(searchQuery, Endpoint.EmailSearch);
return super.send(Endpoint.EmailSearch, searchQuery);
}
}
}
Loading