Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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;
}
}
38 changes: 38 additions & 0 deletions src/us_autocomplete/Suggestion.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
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 | undefined;

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;

if (responseData.source) {
this.source = responseData.source;
}
Comment thread
mae-smarty marked this conversation as resolved.
Outdated
}
}
Loading