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
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ Each API follows the same structure in `src/<api_name>/`:
- `Client.ts` - Request/response handling
- `Candidate.ts`, `Result.ts`, or `Suggestion.ts` - Response data structures

Supported APIs: `us_street`, `us_zipcode`, `us_autocomplete_pro`, `us_extract`, `us_enrichment`, `us_reverse_geo`, `international_street`, `international_address_autocomplete`, `international_postal_code`
Supported APIs: `us_street`, `us_zipcode`, `us_autocomplete`, `us_autocomplete_pro`, `us_extract`, `us_enrichment`, `us_reverse_geo`, `international_street`, `international_address_autocomplete`, `international_postal_code`

### us_enrichment specifics

Expand Down
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ examples-ts: build
@npx tsx examples/us_street_match_strategy.ts || true
@npx tsx examples/us_zipcode.ts || true
@npx tsx examples/us_autocomplete_pro.ts || true
@npx tsx examples/us_autocomplete.ts || true
@npx tsx examples/us_extract.ts || true
@npx tsx examples/us_reverse_geo.ts || true
@npx tsx examples/us_enrichment.ts || true
Expand All @@ -47,6 +48,7 @@ examples-js: build
@node examples/us_street_match_strategy.mjs || true
@node examples/us_zipcode.mjs || true
@node examples/us_autocomplete_pro.mjs || true
@node examples/us_autocomplete.mjs || true
@node examples/us_extract.mjs || true
@node examples/us_reverse_geo.mjs || true
@node examples/us_enrichment.mjs || true
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ console.log(response.result); // Array of address suggestions
| [US Street](https://www.smarty.com/docs/cloud/us-street-api) | `usStreet` | `buildUsStreetApiClient()` | [example](examples/us_street.mjs) |
| [US Zipcode](https://www.smarty.com/docs/cloud/us-zipcode-api) | `usZipcode` | `buildUsZipcodeClient()` | [example](examples/us_zipcode.mjs) |
| [US Autocomplete Pro](https://www.smarty.com/docs/cloud/us-autocomplete-pro-api) | `usAutocompletePro` | `buildUsAutocompleteProClient()` | [example](examples/us_autocomplete_pro.mjs) |
| [US Autocomplete](https://www.smarty.com/docs/apis/us-autocomplete-v2) | `usAutocomplete` | `buildUsAutocompleteClient()` | [example](examples/us_autocomplete.mjs) |
| [US Extract](https://www.smarty.com/docs/cloud/us-extract-api) | `usExtract` | `buildUsExtractClient()` | [example](examples/us_extract.mjs) |
| [US Enrichment](https://www.smarty.com/docs/cloud/us-address-enrichment-api) | `usEnrichment` | `buildUsEnrichmentClient()` | [example](examples/us_enrichment.mjs) |
| [US Reverse Geocoding](https://www.smarty.com/docs/cloud/us-reverse-geo-api) | `usReverseGeo` | `buildUsReverseGeoClient()` | [example](examples/us_reverse_geo.mjs) |
Expand Down
72 changes: 72 additions & 0 deletions examples/us_autocomplete.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import SmartySDK from "smartystreets-javascript-sdk";

// This example is for US Autocomplete (V2). It has the same name as a previous product
// which has been deprecated since 2022, which we refer to as US Autocomplete Basic.
// If you are still using US Autocomplete Basic, this SDK will not work.

const SmartyCore = SmartySDK.core;
const Lookup = SmartySDK.usAutocomplete.Lookup;

// for client-side requests (browser/mobile), use this code:
// let key = process.env.SMARTY_EMBEDDED_KEY;
// const credentials = new SmartyCore.SharedCredentials(key);

// for Server-to-server requests, use this code:
let authId = process.env.SMARTY_AUTH_ID;
let authToken = process.env.SMARTY_AUTH_TOKEN;
const credentials = new SmartyCore.BasicAuthCredentials(authId, authToken);

// 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);
// .withBaseUrl("YOUR URL") // withBaseUrl() should be used if you are self-hosting the Smarty API

let client = clientBuilder.buildUsAutocompleteClient();

// Documentation for input fields can be found at:
// https://www.smarty.com/docs/apis/us-autocomplete-v2/reference#http-request-input-fields

// *** Simple Lookup ***
let lookup = new Lookup("4770 Lincoln");
// uncomment the following line to add a custom parameter
// lookup.addCustomParameter("max_results", 3);

await handleRequest(lookup, "Simple Lookup");

// *** Using Filter and Prefer ***
lookup = new Lookup("4770 Lincoln");

lookup.maxResults = 10;
lookup.includeOnlyCities = ["Chicago,La Grange,IL", "Blaine,WA"];
lookup.preferStates = ["IL"];
lookup.preferRatio = 33;
lookup.source = "all";

await handleRequest(lookup, "Using Filter and Prefer");

// *** Using 'selected' to Expand Secondaries ***
// Take an entry_id from a previous result that has secondaries and pass it back as the selected address.
const entryId = lookup.result.find((suggestion) => suggestion.entryId)?.entryId;
if (entryId) {
lookup = new Lookup("4770 Lincoln");
lookup.selected = entryId;
await handleRequest(lookup, "Using 'selected' to Expand Secondaries");
}

// ************************************************

function logSuggestions(response, message) {
console.log(message);
console.log(response.result);
console.log("*********************");
}

async function handleRequest(lookup, lookupType) {
try {
const results = await client.send(lookup);
logSuggestions(results, lookupType);
} catch (err) {
console.log(err);
}
}
78 changes: 78 additions & 0 deletions examples/us_autocomplete.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import {
ClientBuilder,
BasicAuthCredentials,
LookupUSAutocomplete,
} from "smartystreets-javascript-sdk";

// This example is for US Autocomplete (V2). It has the same name as a previous product
// which has been deprecated since 2022, which we refer to as US Autocomplete Basic.
// If you are still using US Autocomplete Basic, this SDK will not work.

// for client-side requests (browser/mobile), use this code:
// import { SharedCredentials } from "smartystreets-javascript-sdk";
// const key: string = process.env.SMARTY_EMBEDDED_KEY!;
// const credentials = new SharedCredentials(key);

// for Server-to-server requests, use this code:
const authId = process.env.SMARTY_AUTH_ID!;
const authToken = process.env.SMARTY_AUTH_TOKEN!;
const credentials = new BasicAuthCredentials(authId, authToken);

// 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
const clientBuilder = new ClientBuilder(credentials);
// .withBaseUrl("YOUR URL") // withBaseUrl() should be used if you are self-hosting the Smarty API

const client = clientBuilder.buildUsAutocompleteClient();

// Documentation for input fields can be found at:
// https://www.smarty.com/docs/apis/us-autocomplete-v2/reference#http-request-input-fields

// ************************************************

function logSuggestions(response: LookupUSAutocomplete, message: string): void {
console.log(message);
console.log(response.result);
console.log("*********************");
}

async function handleRequest(lookup: LookupUSAutocomplete, lookupType: string): Promise<void> {
try {
const results = await client.send(lookup);
logSuggestions(results, lookupType);
} catch (err: unknown) {
console.error(err);
}
}

async function main(): Promise<void> {
// *** Simple Lookup ***
let lookup = new LookupUSAutocomplete("4770 Lincoln");
// uncomment the following line to add a custom parameter
// lookup.addCustomParameter("max_results", "3");

await handleRequest(lookup, "Simple Lookup");

// *** Using Filter and Prefer ***
lookup = new LookupUSAutocomplete("4770 Lincoln");

lookup.maxResults = 10;
lookup.includeOnlyCities = ["Chicago,La Grange,IL", "Blaine,WA"];
lookup.preferStates = ["IL"];
lookup.preferRatio = 33;
lookup.source = "all";

await handleRequest(lookup, "Using Filter and Prefer");

// *** Using 'selected' to Expand Secondaries ***
// Take an entry_id from a previous result that has secondaries and pass it back as the selected address.
const entryId = lookup.result.find((suggestion) => suggestion.entryId)?.entryId;
if (entryId) {
lookup = new LookupUSAutocomplete("4770 Lincoln");
lookup.selected = entryId;
await handleRequest(lookup, "Using 'selected' to Expand Secondaries");
}
}

main();
14 changes: 13 additions & 1 deletion index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ import ResultUSZipcode from "./src/us_zipcode/Result.js";
import LookupUSAutocompletePro from "./src/us_autocomplete_pro/Lookup.js";
import SuggestionUSAutocompletePro from "./src/us_autocomplete_pro/Suggestion.js";

import LookupUSAutocomplete from "./src/us_autocomplete/Lookup.js";
import SuggestionUSAutocomplete from "./src/us_autocomplete/Suggestion.js";

import LookupUSExtract from "./src/us_extract/Lookup.js";
import ResultUSExtract from "./src/us_extract/Result.js";

Expand Down Expand Up @@ -53,7 +56,8 @@ export type { Request, Response, Sender, Sleeper, Signer } from "./src/types.js"
export { SmartyError, NotModifiedError } from "./src/Errors.js";
export type { MatchStrategy, OutputFormat, CountySource } from "./src/us_street/Lookup.js";
export type { CoordinateLicense, MatchInfo } from "./src/us_street/Candidate.js";
export type { Geolocation, AutocompleteSource } from "./src/us_autocomplete_pro/Lookup.js";
export type { Geolocation } from "./src/us_autocomplete_pro/Lookup.js";
export type { AutocompleteSource } from "./src/us_autocomplete/Lookup.js";
export type { ReverseGeoSource } from "./src/us_reverse_geo/Lookup.js";
export type { Language, Geocode } from "./src/international_street/Lookup.js";

Expand All @@ -71,6 +75,8 @@ export {
ResultUSZipcode,
LookupUSAutocompletePro,
SuggestionUSAutocompletePro,
LookupUSAutocomplete,
SuggestionUSAutocomplete,
LookupUSExtract,
ResultUSExtract,
LookupInternationalStreet,
Expand Down Expand Up @@ -120,6 +126,11 @@ export const usAutocompletePro = {
Suggestion: SuggestionUSAutocompletePro,
};

export const usAutocomplete = {
Lookup: LookupUSAutocomplete,
Suggestion: SuggestionUSAutocomplete,
};

export const usExtract = {
Lookup: LookupUSExtract,
Result: ResultUSExtract,
Expand Down Expand Up @@ -165,6 +176,7 @@ export default {
usStreet,
usZipcode,
usAutocompletePro,
usAutocomplete,
usExtract,
internationalStreet,
usReverseGeo,
Expand Down
6 changes: 6 additions & 0 deletions src/ClientBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import Sleeper from "./util/Sleeper.js";
import UsStreetClient from "./us_street/Client.js";
import UsZipcodeClient from "./us_zipcode/Client.js";
import UsAutocompleteProClient from "./us_autocomplete_pro/Client.js";
import UsAutocompleteClient from "./us_autocomplete/Client.js";
import UsExtractClient from "./us_extract/Client.js";
import InternationalStreetClient from "./international_street/Client.js";
import UsReverseGeoClient from "./us_reverse_geo/Client.js";
Expand All @@ -26,6 +27,7 @@ import { Sender } from "./types.js";

const INTERNATIONAL_STREET_API_URI = "https://international-street.api.smarty.com/verify";
const US_AUTOCOMPLETE_PRO_API_URL = "https://us-autocomplete-pro.api.smarty.com/lookup";
const US_AUTOCOMPLETE_API_URL = "https://us-autocomplete.api.smarty.com/v2/lookup";
const US_EXTRACT_API_URL = "https://us-extract.api.smarty.com/";
const US_STREET_API_URL = "https://us-street.api.smarty.com/street-address";
const US_ZIP_CODE_API_URL = "https://us-zipcode.api.smarty.com/lookup";
Expand Down Expand Up @@ -242,6 +244,10 @@ export default class ClientBuilder {
return this.buildClient(US_AUTOCOMPLETE_PRO_API_URL, UsAutocompleteProClient);
}

buildUsAutocompleteClient(): UsAutocompleteClient {
return this.buildClient(US_AUTOCOMPLETE_API_URL, UsAutocompleteClient);
}

buildUsExtractClient(): UsExtractClient {
return this.buildClient(US_EXTRACT_API_URL, UsExtractClient);
}
Expand Down
42 changes: 42 additions & 0 deletions src/us_autocomplete/Client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { UndefinedLookupError } from "../Errors.js";
import Request from "../Request.js";
import Suggestion, { RawUsAutocompleteSuggestion } from "./Suggestion.js";
import buildInputData from "../util/buildInputData.js";
import apiToSDKKeyMap from "../util/apiToSDKKeyMap.js";
import { Sender } from "../types.js";
import Lookup from "./Lookup.js";

const keyTranslationFormat = apiToSDKKeyMap.usAutocomplete;

export default class Client {
private sender: Sender;

constructor(sender: Sender) {
this.sender = sender;
}

send(lookup: Lookup): Promise<Lookup> {
if (typeof lookup === "undefined") throw new UndefinedLookupError();

const request = new Request();
request.parameters = buildInputData(lookup, keyTranslationFormat);

return new Promise((resolve, reject) => {
this.sender
.send(request)
.then((response) => {
if (response.error) return reject(response.error);

const payload = response.payload as {
suggestions: RawUsAutocompleteSuggestion[] | null;
};
lookup.result =
payload.suggestions === null
? []
: payload.suggestions.map((suggestion) => new Suggestion(suggestion));
resolve(lookup);
})
.catch(reject);
});
}
}
47 changes: 47 additions & 0 deletions src/us_autocomplete/Lookup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import Suggestion from "./Suggestion.js";

export type Geolocation = "city" | "none" | (string & {});
export type AutocompleteSource = "all" | "postal" | (string & {});

export default class Lookup {
result: Suggestion[];
search: string | undefined;
selected: string | undefined;
exclude: string | undefined;
maxResults: number | undefined;
includeOnlyCities: string[];
includeOnlyStates: string[];
includeOnlyZIPCodes: string[];
excludeStates: string[];
preferCities: string[];
preferStates: string[];
preferZIPCodes: string[];
preferRatio: number | undefined;
preferGeolocation: Geolocation | undefined;
source: AutocompleteSource | undefined;
customParameters: Record<string, string>;

constructor(search?: string) {
this.result = [];

this.search = search;
this.selected = undefined;
this.exclude = undefined;
this.maxResults = undefined;
this.includeOnlyCities = [];
this.includeOnlyStates = [];
this.includeOnlyZIPCodes = [];
this.excludeStates = [];
this.preferCities = [];
this.preferStates = [];
this.preferZIPCodes = [];
this.preferRatio = undefined;
this.preferGeolocation = undefined;
this.source = undefined;
this.customParameters = {};
}

addCustomParameter(key: string, value: string): void {
this.customParameters[key] = value;
}
}
35 changes: 35 additions & 0 deletions src/us_autocomplete/Suggestion.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
export interface RawUsAutocompleteSuggestion {
smarty_key?: string;
entry_id?: string;
street_line?: string;
secondary?: string;
city?: string;
state?: string;
zipcode?: string;
entries?: number;
source?: string;
}

export default class Suggestion {
smartyKey: string;
entryId: string;
streetLine: string;
secondary: string;
city: string;
state: string;
zipcode: string;
entries: number;
source: string;

constructor(responseData: RawUsAutocompleteSuggestion) {
this.smartyKey = responseData.smarty_key ?? "";
this.entryId = responseData.entry_id ?? "";
this.streetLine = responseData.street_line ?? "";
this.secondary = responseData.secondary ?? "";
this.city = responseData.city ?? "";
this.state = responseData.state ?? "";
this.zipcode = responseData.zipcode ?? "";
this.entries = responseData.entries ?? 0;
this.source = responseData.source ?? "";
}
}
Loading