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
21 changes: 11 additions & 10 deletions examples/us_street.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -15,28 +15,29 @@ const credentials = new SmartyCore.SharedCredentials(key);
// The appropriate license values to be used for your subscriptions
// can be found on the Subscription page of the account dashboard.
// https://www.smarty.com/docs/cloud/licensing
let clientBuilder = new SmartyCore.ClientBuilder(credentials).withLicenses(["us-rooftop-geocoding-cloud"]);
// .withBaseUrl("YOUR URL") // withBaseUrl() should be used if you are self-hosting the Smarty API
let clientBuilder = new SmartyCore.ClientBuilder(credentials).withLicenses([
"us-rooftop-geocoding-cloud",
]);
// .withBaseUrl("YOUR URL") // withBaseUrl() should be used if you are self-hosting the Smarty API

let client = clientBuilder.buildUsStreetApiClient();

// Documentation for input fields can be found at:
// https://www.smarty.com/docs/us-street-api#input-fields

let lookup1 = new Lookup();
lookup1.inputId = "24601"; // Optional ID from your system
lookup1.inputId = "24601"; // Optional ID from your system
lookup1.addressee = "John Doe";
lookup1.street = "330 N 100 W";
lookup1.street2 = "closet under the stairs";
lookup1.secondary = "APT 2";
lookup1.urbanization = ""; // Only applies to Puerto Rico addresses
lookup1.urbanization = ""; // Only applies to Puerto Rico addresses
lookup1.city = "Provo";
lookup1.state = "Utah";
lookup1.zipCode = "84601";
lookup1.maxCandidates = 3;
lookup1.match = "invalid"; // "invalid" is the most permissive match,
// this will always return at least one result even if the address is invalid.
// Refer to the documentation for additional MatchStrategy options.
lookup1.match = "enhanced"; // The API will return detailed output based on a more aggressive matching mechanism. It also includes a more comprehensive address dataset beyond just the postal address data. Requires a US Core license or a US Rooftop Geocoding license.
// Refer to the documentation for additional MatchStrategy options.

let lookup2 = new Lookup();
lookup2.street = "1600 Amphitheater Pkwy";
Expand All @@ -59,7 +60,7 @@ batch.add(lookup3);
await handleResponse(batch);

function handleSuccess(response) {
response.lookups.map(lookup => console.log(lookup.result));
response.lookups.map((lookup) => console.log(lookup.result));
}

function handleError(response) {
Expand All @@ -70,7 +71,7 @@ async function handleResponse(lookup) {
try {
const result = await client.send(lookup);
handleSuccess(result);
} catch(err) {
} catch (err) {
handleError(err);
}
}
}
15 changes: 8 additions & 7 deletions package-lock.json

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

64 changes: 50 additions & 14 deletions src/ClientBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const SharedCredentials = require("./SharedCredentials");
const CustomHeaderSender = require("./CustomHeaderSender");
const StatusCodeSender = require("./StatusCodeSender");
const LicenseSender = require("./LicenseSender");
const CustomQuerySender = require("@/src/CustomQuerySender");
const BadCredentialsError = require("./Errors").BadCredentialsError;
const RetrySender = require("./RetrySender");
const Sleeper = require("./util/Sleeper.ts");
Expand Down Expand Up @@ -39,7 +40,7 @@ const INTERNATIONAL_POSTAL_CODE_API_URL = "https://international-postal-code.api
*/
class ClientBuilder {
constructor(signer) {
if (noCredentialsProvided()) throw new BadCredentialsError();
if (!credentialsProvided()) throw new BadCredentialsError();

this.signer = signer;
this.httpSender = undefined;
Expand All @@ -50,15 +51,16 @@ class ClientBuilder {
this.customHeaders = {};
this.debug = undefined;
this.licenses = [];
this.customQueries = new Map();

function noCredentialsProvided() {
return (!signer) instanceof StaticCredentials || (!signer) instanceof SharedCredentials;
function credentialsProvided() {
return signer instanceof StaticCredentials || signer instanceof SharedCredentials;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed this because it was working as a false positive. I also updated it to be the positive condition for readability

}
}

/**
* @param retries The maximum number of times to retry sending the request to the API. (Default is 5)
* @return Returns <b>this</b> to accommodate method chaining.
* @return ClientBuilder <b>this</b> to accommodate method chaining.
*/
withMaxRetries(retries) {
this.maxRetries = retries;
Expand All @@ -68,7 +70,7 @@ class ClientBuilder {
/**
* @param timeout The maximum time (in milliseconds) to wait for a connection, and also to wait for <br>
* the response to be read. (Default is 10000)
* @return Returns <b>this</b> to accommodate method chaining.
* @return ClientBuilder <b>this</b> to accommodate method chaining.
*/
withMaxTimeout(timeout) {
this.maxTimeout = timeout;
Expand All @@ -77,7 +79,7 @@ class ClientBuilder {

/**
* @param sender Default is a series of nested senders. See <b>buildSender()</b>.
* @return Returns <b>this</b> to accommodate method chaining.
* @return ClientBuilder <b>this</b> to accommodate method chaining.
*/
withSender(sender) {
this.httpSender = sender;
Expand All @@ -87,7 +89,7 @@ class ClientBuilder {
/**
* This may be useful when using a local installation of the Smarty APIs.
* @param url Defaults to the URL for the API corresponding to the <b>Client</b> object being built.
* @return Returns <b>this</b> to accommodate method chaining.
* @return ClientBuilder <b>this</b> to accommodate method chaining.
*/
withBaseUrl(url) {
this.baseUrl = url;
Expand All @@ -101,7 +103,7 @@ class ClientBuilder {
* @param protocol The protocol on the proxy server to which you wish to connect. If the proxy server uses HTTPS, then you must set the protocol to 'https'.
* @param username The username to login to the proxy.
* @param password The password to login to the proxy.
* @return Returns <b>this</b> to accommodate method chaining.
* @return ClientBuilder <b>this</b> to accommodate method chaining.
*/
withProxy(host, port, protocol, username, password) {
this.proxy = {
Expand All @@ -123,35 +125,68 @@ class ClientBuilder {
/**
* Use this to add any additional headers you need.
* @param customHeaders A String to Object <b>Map</b> of header name/value pairs.
* @return Returns <b>this</b> to accommodate method chaining.
* @return ClientBuilder <b>this</b> to accommodate method chaining.
*/
withCustomHeaders(customHeaders) {
this.customHeaders = customHeaders;

return this;
}

/**
* Enables debug mode, which will print information about the HTTP request and response to console.log
* @return Returns <b>this</b> to accommodate method chaining.
* @return ClientBuilder <b>this</b> to accommodate method chaining.
*/
withDebug() {
this.debug = true;

return this;
}

/**
* Allows the caller to specify the subscription license (aka "track") they wish to use.
* @param licenses A String Array of licenses.
* @returns Returns <b>this</b> to accommodate method chaining.
* @returns ClientBuilder <b>this</b> to accommodate method chaining.
*/
withLicenses(licenses) {
this.licenses = licenses;
return this;
}

/**
* Allows the caller to specify key and value pair that is added to the request
* @param {string} key - The query parameter key
* @param {string} value - The query parameter value
* @return ClientBuilder <b>this</b> to accommodate method chaining.
*/
withCustomQuery(key, value) {
this.customQueries.set(key, value);
return this;
}

/**
* Allows the caller to specify key and value pair and appends the value associated with the key, seperated by a comma.
* @param {string} key - The query parameter key
* @param {string} value - The query parameter value
* @return ClientBuilder <b>this</b> to accommodate method chaining.
*/
withCustomCommaSeperatedQuery(key, value) {
let values = this.customQueries.get(key);
if (values === "") {
values = value;
} else {
values += "," + value;
}
this.customQueries.set(key, values);
return this;
}

/**
* Adds to the request query to use the component analysis feature.
* @return ClientBuilder <b>this</b> to accommodate method chaining.
*/
withFeatureComponentAnalysis() {
Copy link
Contributor

Choose a reason for hiding this comment

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

Here is the error I get for this:

node examples/us_street.mjs
file:///Users/mitchell/Smarty/smartystreets-javascript-sdk/examples/us_street.mjs:21
let client = clientBuilder.buildUsStreetApiClient();
^

TypeError: Cannot read properties of undefined (reading 'buildUsStreetApiClient')
at file:///Users/mitchell/Smarty/smartystreets-javascript-sdk/examples/us_street.mjs:21:28
at ModuleJob.run (node:internal/modules/esm/module_job:234:25)
at async ModuleLoader.import (node:internal/modules/esm/loader:473:24)
at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:122:5)

Node.js v20.18.1

return this.withCustomCommaSeperatedQuery("features", "component-analysis");
Copy link
Contributor

Choose a reason for hiding this comment

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

Same error with this:
`node examples/us_street.mjs
file:///Users/mitchell/Smarty/smartystreets-javascript-sdk/examples/us_street.mjs:21
let client = clientBuilder.buildUsStreetApiClient();
^

TypeError: Cannot read properties of undefined (reading 'buildUsStreetApiClient')
at file:///Users/mitchell/Smarty/smartystreets-javascript-sdk/examples/us_street.mjs:21:28
at ModuleJob.run (node:internal/modules/esm/module_job:234:25)
at async ModuleLoader.import (node:internal/modules/esm/loader:473:24)
at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:122:5)

Node.js v20.18.1`

}

buildSender() {
if (this.httpSender) return this.httpSender;

Expand All @@ -166,8 +201,9 @@ class ClientBuilder {
const customHeaderSender = new CustomHeaderSender(agentSender, this.customHeaders);
const baseUrlSender = new BaseUrlSender(customHeaderSender, this.baseUrl);
const licenseSender = new LicenseSender(baseUrlSender, this.licenses);
const customQuerySender = new CustomQuerySender(licenseSender, this.customQueries);

return licenseSender;
return customQuerySender;
}

buildClient(baseUrl, Client) {
Expand Down
20 changes: 20 additions & 0 deletions src/CustomQuerySender.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Request, Response, Sender } from "./types";

export default class CustomQuerySender {
private queries: Map<string, string>;
private sender: Sender;

constructor(innerSender: Sender, queries: Map<string, string>) {
this.queries = queries;
this.sender = innerSender;
}

send(request: Request): Promise<Response> {
this.queries.forEach((value, key) => {
const existingValue = request.parameters[key];
request.parameters[key] = existingValue ? `${existingValue},${value}` : value;
});

return this.sender.send(request);
}
}
30 changes: 27 additions & 3 deletions src/us_street/Candidate.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,7 @@ class Candidate {
this.metadata.elotSort = responseData.metadata.elot_sort;
this.metadata.latitude = responseData.metadata.latitude;
this.metadata.longitude = responseData.metadata.longitude;
switch (responseData.metadata.coordinate_license)
{
switch (responseData.metadata.coordinate_license) {
case 1:
this.metadata.coordinateLicense = "SmartyStreets Proprietary";
break;
Expand Down Expand Up @@ -82,8 +81,33 @@ class Candidate {
this.analysis.lacsLinkIndicator = responseData.analysis.lacslink_indicator;
this.analysis.isSuiteLinkMatch = responseData.analysis.suitelink_match;
this.analysis.enhancedMatch = responseData.analysis.enhanced_match;
this.analysis.components = {};
console.log("what are the analysis", responseData.analysis);
if (responseData.analysis.components !== undefined) {
this.analysis.components.primaryNumber = responseData.analysis.components.primary_number;
this.analysis.components.streetPredirection =
responseData.analysis.components.street_predirection;
this.analysis.components.streetName = responseData.analysis.components.street_name;
this.analysis.components.streetPostdirection =
responseData.analysis.components.street_postdirection;
this.analysis.components.streetSuffix = responseData.analysis.components.street_suffix;
this.analysis.components.secondaryNumber =
responseData.analysis.components.secondary_number;
this.analysis.components.secondaryDesignator =
responseData.analysis.components.secondary_designator;
this.analysis.components.extraSecondaryNumber =
responseData.analysis.components.extra_secondary_number;
this.analysis.components.extraSecondaryDesignator =
responseData.analysis.components.extra_secondary_designator;
this.analysis.components.cityName = responseData.analysis.components.city_name;
this.analysis.components.stateAbbreviation =
responseData.analysis.components.state_abbreviation;
this.analysis.components.zipCode = responseData.analysis.components.zipcode;
this.analysis.components.plus4Code = responseData.analysis.components.plus4_code;
this.analysis.components.urbanization = responseData.analysis.components.urbanization;
}
}
}
}

module.exports = Candidate;
module.exports = Candidate;
Loading