@shopify/address
Advanced tools
Comparing version 1.1.2 to 2.0.0
@@ -50,7 +50,7 @@ "use strict"; | ||
this.locale = locale; | ||
this.locale = locale; | ||
this.locale = locale.toUpperCase(); | ||
COUNTRIES_CACHE[this.locale] = {}; | ||
} | ||
AddressFormatter.prototype.updateLocale = function (locale) { | ||
this.locale = locale; | ||
this.locale = locale.toUpperCase(); | ||
COUNTRIES_CACHE[this.locale] = {}; | ||
@@ -71,3 +71,3 @@ }; | ||
country = _a.sent(); | ||
COUNTRIES_CACHE[this.locale][country.attributes.code] = country; | ||
COUNTRIES_CACHE[this.locale][country.code] = country; | ||
return [2 /*return*/, country]; | ||
@@ -116,3 +116,3 @@ } | ||
country = _a.sent(); | ||
layout = country.attributes.format.show || DEFAULT_SHOW_LAYOUT; | ||
layout = country.formatting.show || DEFAULT_SHOW_LAYOUT; | ||
return [2 /*return*/, layout | ||
@@ -145,5 +145,3 @@ .split(LINE_DELIMITER) | ||
country = _a.sent(); | ||
format = country | ||
? country.attributes.format.edit | ||
: DEFAULT_FORM_LAYOUT; | ||
format = country ? country.formatting.edit : DEFAULT_FORM_LAYOUT; | ||
return [2 /*return*/, format.split(LINE_DELIMITER).map(function (fields) { | ||
@@ -172,7 +170,7 @@ var result = fields.match(FIELD_REGEXP); | ||
case types_1.FieldName.Province: | ||
return [2 /*return*/, country.attributes.zoneKey]; | ||
return [2 /*return*/, country.provinceKey]; | ||
case types_1.FieldName.Zip: | ||
return [2 /*return*/, country.attributes.zipKey]; | ||
return [2 /*return*/, country.zipKey]; | ||
case types_1.FieldName.Address2: | ||
return [2 /*return*/, country.attributes.address2Key]; | ||
return [2 /*return*/, country.address2Key]; | ||
default: | ||
@@ -193,3 +191,3 @@ return [2 /*return*/, key]; | ||
return ORDERED_COUNTRIES_CACHE[this.locale].find(function (country) { | ||
return country.attributes.code === countryCode; | ||
return country.code === countryCode; | ||
}); | ||
@@ -196,0 +194,0 @@ } |
"use strict"; | ||
var __extends = (this && this.__extends) || (function () { | ||
var extendStatics = function (d, b) { | ||
extendStatics = Object.setPrototypeOf || | ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; | ||
return extendStatics(d, b); | ||
} | ||
return function (d, b) { | ||
extendStatics(d, b); | ||
function __() { this.constructor = d; } | ||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); | ||
}; | ||
})(); | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
@@ -37,25 +50,45 @@ return new (P || (P = Promise))(function (resolve, reject) { | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var API_VERSION = '1'; | ||
var API_HEADERS = { | ||
Accept: 'application/json', | ||
var graphqlQuery_1 = __importDefault(require("./graphqlQuery")); | ||
var GRAPHQL_ENDPOINT = 'https://country-service.shopifycloud.com/graphql'; | ||
var GRAPHAL_OPERATION_NAMES; | ||
(function (GRAPHAL_OPERATION_NAMES) { | ||
GRAPHAL_OPERATION_NAMES["countries"] = "countries"; | ||
GRAPHAL_OPERATION_NAMES["country"] = "country"; | ||
})(GRAPHAL_OPERATION_NAMES || (GRAPHAL_OPERATION_NAMES = {})); | ||
var HEADERS = { | ||
'Content-Type': 'application/json', | ||
'API-VERSION': API_VERSION, | ||
'Access-Control-Allow-Origin': '*', | ||
}; | ||
var COUNTRY_SERVICE_URL = 'https://country-service.shopifycloud.com'; | ||
function loadCountries(locale) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var countries, jsonResponse; | ||
var response, countries; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, fetch(COUNTRY_SERVICE_URL + "/countries?locale=" + locale, { | ||
cache: 'force-cache', | ||
headers: API_HEADERS, | ||
case 0: return [4 /*yield*/, fetch(GRAPHQL_ENDPOINT, { | ||
method: 'POST', | ||
headers: HEADERS, | ||
body: JSON.stringify({ | ||
query: graphqlQuery_1.default, | ||
operationName: GRAPHAL_OPERATION_NAMES.countries, | ||
variables: { | ||
locale: locale, | ||
}, | ||
}), | ||
})]; | ||
case 1: | ||
response = _a.sent(); | ||
return [4 /*yield*/, response.json()]; | ||
case 2: | ||
countries = _a.sent(); | ||
return [4 /*yield*/, countries.json()]; | ||
case 2: | ||
jsonResponse = _a.sent(); | ||
return [2 /*return*/, jsonResponse.data]; | ||
if ('errors' in countries) { | ||
throw new CountryLoaderError(countries); | ||
} | ||
else { | ||
return [2 /*return*/, countries.data.countries]; | ||
} | ||
return [2 /*return*/]; | ||
} | ||
@@ -68,15 +101,29 @@ }); | ||
return __awaiter(this, void 0, void 0, function () { | ||
var country, jsonResponse; | ||
var response, country; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, fetch(COUNTRY_SERVICE_URL + "/countries/" + countryCode + "?locale=" + locale, { | ||
cache: 'force-cache', | ||
headers: API_HEADERS, | ||
case 0: return [4 /*yield*/, fetch(GRAPHQL_ENDPOINT, { | ||
method: 'POST', | ||
headers: HEADERS, | ||
body: JSON.stringify({ | ||
query: graphqlQuery_1.default, | ||
operationName: GRAPHAL_OPERATION_NAMES.country, | ||
variables: { | ||
countryCode: countryCode, | ||
locale: locale, | ||
}, | ||
}), | ||
})]; | ||
case 1: | ||
response = _a.sent(); | ||
return [4 /*yield*/, response.json()]; | ||
case 2: | ||
country = _a.sent(); | ||
return [4 /*yield*/, country.json()]; | ||
case 2: | ||
jsonResponse = _a.sent(); | ||
return [2 /*return*/, jsonResponse.data]; | ||
if ('errors' in country) { | ||
throw new CountryLoaderError(country); | ||
} | ||
else { | ||
return [2 /*return*/, country.data.country]; | ||
} | ||
return [2 /*return*/]; | ||
} | ||
@@ -87,1 +134,11 @@ }); | ||
exports.loadCountry = loadCountry; | ||
var CountryLoaderError = /** @class */ (function (_super) { | ||
__extends(CountryLoaderError, _super); | ||
function CountryLoaderError(errors) { | ||
var _this = this; | ||
var errorMessage = errors.errors.map(function (error) { return error.message; }).join('; '); | ||
_this = _super.call(this, errorMessage) || this; | ||
return _this; | ||
} | ||
return CountryLoaderError; | ||
}(Error)); |
@@ -1,6 +0,6 @@ | ||
import CanadaFr from './CA_fr'; | ||
import CanadaEn from './CA_en'; | ||
import FranceFr from './FR_fr'; | ||
import JapanJa from './JP_ja'; | ||
import SingaporeEn from './SG_en'; | ||
export { CanadaFr, CanadaEn, JapanJa, SingaporeEn, FranceFr }; | ||
import countriesJa from './countries_ja'; | ||
import countriesEn from './countries_en'; | ||
import countryJpJa from './country_jp_ja'; | ||
import countryJpEn from './country_jp_en'; | ||
import countryJpFr from './country_jp_fr'; | ||
export { countriesJa, countriesEn, countryJpJa, countryJpEn, countryJpFr }; |
@@ -6,11 +6,11 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var CA_fr_1 = __importDefault(require("./CA_fr")); | ||
exports.CanadaFr = CA_fr_1.default; | ||
var CA_en_1 = __importDefault(require("./CA_en")); | ||
exports.CanadaEn = CA_en_1.default; | ||
var FR_fr_1 = __importDefault(require("./FR_fr")); | ||
exports.FranceFr = FR_fr_1.default; | ||
var JP_ja_1 = __importDefault(require("./JP_ja")); | ||
exports.JapanJa = JP_ja_1.default; | ||
var SG_en_1 = __importDefault(require("./SG_en")); | ||
exports.SingaporeEn = SG_en_1.default; | ||
var countries_ja_1 = __importDefault(require("./countries_ja")); | ||
exports.countriesJa = countries_ja_1.default; | ||
var countries_en_1 = __importDefault(require("./countries_en")); | ||
exports.countriesEn = countries_en_1.default; | ||
var country_jp_ja_1 = __importDefault(require("./country_jp_ja")); | ||
exports.countryJpJa = country_jp_ja_1.default; | ||
var country_jp_en_1 = __importDefault(require("./country_jp_en")); | ||
exports.countryJpEn = country_jp_en_1.default; | ||
var country_jp_fr_1 = __importDefault(require("./country_jp_fr")); | ||
exports.countryJpFr = country_jp_fr_1.default; |
@@ -13,2 +13,5 @@ export declare enum FieldName { | ||
} | ||
export declare type ProvinceKey = 'COUNTY' | 'EMIRATE' | 'GOVERNORATE' | 'PREFECTURE' | 'PROVINCE' | 'REGION' | 'STATE_AND_TERRITORY' | 'STATE'; | ||
export declare type ZipKey = 'POSTAL_CODE' | 'POSTCODE' | 'PINCODE' | 'ZIP_CODE'; | ||
export declare type Address2Key = 'APT_SUITE_ETC' | 'APT_UNIT_NUMBER'; | ||
export interface Address { | ||
@@ -30,18 +33,37 @@ company?: string; | ||
} | ||
export interface LoadCountriesResponse { | ||
data: { | ||
countries: Country[]; | ||
}; | ||
} | ||
export interface LoadCountryResponse { | ||
data: { | ||
country: Country; | ||
}; | ||
} | ||
export interface Country { | ||
id: string; | ||
type: string; | ||
attributes: { | ||
code: string; | ||
name: string; | ||
phoneNumberPrefix: number; | ||
format: { | ||
edit: string; | ||
show: string; | ||
}; | ||
zoneKey: string; | ||
zipKey: string; | ||
address2Key: string; | ||
provinces: Province[]; | ||
name: string; | ||
code: string; | ||
phoneNumberPrefix: number; | ||
address2Key: Address2Key; | ||
provinceKey: ProvinceKey; | ||
zipKey: ZipKey; | ||
formatting: { | ||
edit: string; | ||
show: string; | ||
}; | ||
provinces: Province[]; | ||
} | ||
export interface ResponseError { | ||
errors: { | ||
locations: { | ||
column: number; | ||
line: number; | ||
}[]; | ||
message: string; | ||
problems: { | ||
explanation: string; | ||
}[]; | ||
value: any; | ||
}[]; | ||
} |
@@ -34,7 +34,7 @@ "use strict"; | ||
case types_1.FieldName.Country: | ||
line = line.replace("{" + types_1.FieldName.Country + "}", country.attributes.name); | ||
line = line.replace("{" + types_1.FieldName.Country + "}", country.name); | ||
break; | ||
case types_1.FieldName.Province: | ||
line = line.replace("{" + types_1.FieldName.Province + "}", address.province | ||
? getProvince(country.attributes.provinces, address.province).name | ||
? getProvince(country.provinces, address.province).name | ||
: ''); | ||
@@ -41,0 +41,0 @@ break; |
{ | ||
"name": "@shopify/address", | ||
"version": "1.1.2", | ||
"version": "2.0.0", | ||
"license": "MIT", | ||
@@ -5,0 +5,0 @@ "description": "Address utilities for formatting addresses.", |
@@ -7,3 +7,2 @@ # `@shopify/address` | ||
Address utilities for loading and ordering addresses. | ||
@@ -41,5 +40,5 @@ | ||
Eg.: | ||
Eg.: | ||
``` typescript | ||
```typescript | ||
[ | ||
@@ -52,4 +51,4 @@ ['firstName', 'lastName'], | ||
['country', 'province', 'zip'], | ||
['phone'] | ||
] | ||
['phone'], | ||
]; | ||
``` | ||
@@ -61,9 +60,4 @@ | ||
``` typescript | ||
[ | ||
'Shopify', | ||
'Lindenstraße 9-14', | ||
'10969 Berlin', | ||
'Germany' | ||
] | ||
```typescript | ||
['Shopify', 'Lindenstraße 9-14', '10969 Berlin', 'Germany']; | ||
``` | ||
@@ -73,12 +67,12 @@ | ||
Get the translation key for a given field for a given country. Eg: | ||
Get the translation key for a given field for a given country. Eg: | ||
``` typescript | ||
await getTranslationKey('CA', 'province'); // => "province" | ||
await getTranslationKey('US', 'province'); // => "state" | ||
await getTranslationKey('JA', 'province'); // => "prefecture" | ||
await getTranslationKey('CA', 'zip'); // => "postalCode" | ||
await getTranslationKey('US', 'zip'); // => "zipCode" | ||
await getTranslationKey('CA', 'address2'); // => "aptUnitNumber" | ||
await getTranslationKey('JA', 'address2'); // => "aptSuiteEtc" | ||
```typescript | ||
await getTranslationKey('CA', 'province'); // => "PROVINCE" | ||
await getTranslationKey('US', 'province'); // => "STATE" | ||
await getTranslationKey('JA', 'province'); // => "PREFECTURE" | ||
await getTranslationKey('CA', 'zip'); // => "POSTAL_CODE" | ||
await getTranslationKey('US', 'zip'); // => "ZIP_CODE" | ||
await getTranslationKey('CA', 'address2'); // => "APT_UNIT_NUMBER" | ||
await getTranslationKey('JA', 'address2'); // => "APT_SUITE_ETC" | ||
``` | ||
@@ -90,24 +84,23 @@ | ||
- `zoneKey` is one of the following | ||
- `county` | ||
- `emirate` | ||
- `governorate` | ||
- `prefecture` | ||
- `province` | ||
- `region` | ||
- `stateAndTerritory` | ||
- `state` | ||
- `ProvinceKey` is one of the following | ||
- `COUNTY` | ||
- `EMIRATE` | ||
- `GOVERNORATE` | ||
- `PREFECTURE` | ||
- `PROVINCE` | ||
- `REGION` | ||
- `STATE_AND_TERRITORY` | ||
- `STATE` | ||
* `ZipKey` is one of the following | ||
- `zipKey` is one of the following | ||
- `postalCode` | ||
- `postcode` | ||
- `pincode` | ||
- `zipCode` | ||
- `POSTAL_CODE` | ||
- `POSTCODE` | ||
- `PINCODE` | ||
- `ZIP_CODE` | ||
- `address2Key` is one of the following | ||
- `aptSuiteEtc` | ||
- `aptUnitNumber` | ||
* `Address2Key` is one of the following | ||
- `APT_SUITE_ETC` | ||
- `APT_UNIT_NUMBER` | ||
#### Example Usage | ||
@@ -131,7 +124,7 @@ | ||
phone: '', | ||
} | ||
}; | ||
const addressFormatter = new AddressFormatter('ja') | ||
await addressFormatter.format(address) | ||
/* => | ||
const addressFormatter = new AddressFormatter('ja'); | ||
await addressFormatter.format(address); | ||
/* => | ||
日本 | ||
@@ -143,4 +136,4 @@ 〒100-8994東京都目黒区八重洲1-5-3 | ||
await addressFormatter.getOrderedFields('CA') | ||
/* => | ||
await addressFormatter.getOrderedFields('CA'); | ||
/* => | ||
[ | ||
@@ -147,0 +140,0 @@ ['firstName', 'lastName'], |
@@ -24,3 +24,3 @@ import {Address, FieldName, Country} from './types'; | ||
constructor(private locale: string) { | ||
this.locale = locale; | ||
this.locale = locale.toUpperCase(); | ||
COUNTRIES_CACHE[this.locale] = {}; | ||
@@ -30,3 +30,3 @@ } | ||
updateLocale(locale: string) { | ||
this.locale = locale; | ||
this.locale = locale.toUpperCase(); | ||
COUNTRIES_CACHE[this.locale] = {}; | ||
@@ -42,4 +42,3 @@ } | ||
country = await loadCountry(this.locale, countryCode); | ||
COUNTRIES_CACHE[this.locale][country.attributes.code] = country; | ||
COUNTRIES_CACHE[this.locale][country.code] = country; | ||
return country; | ||
@@ -52,3 +51,2 @@ } | ||
} | ||
const countries = await loadCountries(this.locale); | ||
@@ -74,4 +72,3 @@ ORDERED_COUNTRIES_CACHE[this.locale] = countries; | ||
const country = await this.getCountry(address.country); | ||
const layout = country.attributes.format.show || DEFAULT_SHOW_LAYOUT; | ||
const layout = country.formatting.show || DEFAULT_SHOW_LAYOUT; | ||
return layout | ||
@@ -97,5 +94,3 @@ .split(LINE_DELIMITER) | ||
const format = country | ||
? country.attributes.format.edit | ||
: DEFAULT_FORM_LAYOUT; | ||
const format = country ? country.formatting.edit : DEFAULT_FORM_LAYOUT; | ||
@@ -121,7 +116,7 @@ return format.split(LINE_DELIMITER).map(fields => { | ||
case FieldName.Province: | ||
return country.attributes.zoneKey; | ||
return country.provinceKey; | ||
case FieldName.Zip: | ||
return country.attributes.zipKey; | ||
return country.zipKey; | ||
case FieldName.Address2: | ||
return country.attributes.address2Key; | ||
return country.address2Key; | ||
default: | ||
@@ -143,3 +138,3 @@ return key; | ||
return ORDERED_COUNTRIES_CACHE[this.locale].find(country => { | ||
return country.attributes.code === countryCode; | ||
return country.code === countryCode; | ||
}); | ||
@@ -146,0 +141,0 @@ } |
@@ -1,23 +0,41 @@ | ||
import {Country} from './types'; | ||
import { | ||
Country, | ||
LoadCountriesResponse, | ||
LoadCountryResponse, | ||
ResponseError, | ||
} from './types'; | ||
import query from './graphqlQuery'; | ||
const API_VERSION = '1'; | ||
const API_HEADERS = { | ||
Accept: 'application/json', | ||
const GRAPHQL_ENDPOINT = 'https://country-service.shopifycloud.com/graphql'; | ||
enum GRAPHAL_OPERATION_NAMES { | ||
countries = 'countries', | ||
country = 'country', | ||
} | ||
const HEADERS = { | ||
'Content-Type': 'application/json', | ||
'API-VERSION': API_VERSION, | ||
'Access-Control-Allow-Origin': '*', | ||
}; | ||
const COUNTRY_SERVICE_URL = 'https://country-service.shopifycloud.com'; | ||
export async function loadCountries(locale: string): Promise<Country[]> { | ||
const countries = await fetch( | ||
`${COUNTRY_SERVICE_URL}/countries?locale=${locale}`, | ||
{ | ||
cache: 'force-cache', | ||
headers: API_HEADERS, | ||
}, | ||
); | ||
const response = await fetch(GRAPHQL_ENDPOINT, { | ||
method: 'POST', | ||
headers: HEADERS, | ||
body: JSON.stringify({ | ||
query, | ||
operationName: GRAPHAL_OPERATION_NAMES.countries, | ||
variables: { | ||
locale, | ||
}, | ||
}), | ||
}); | ||
const jsonResponse = await countries.json(); | ||
return jsonResponse.data; | ||
const countries: | ||
| LoadCountriesResponse | ||
| ResponseError = await response.json(); | ||
if ('errors' in countries) { | ||
throw new CountryLoaderError(countries); | ||
} else { | ||
return countries.data.countries; | ||
} | ||
} | ||
@@ -29,12 +47,27 @@ | ||
): Promise<Country> { | ||
const country = await fetch( | ||
`${COUNTRY_SERVICE_URL}/countries/${countryCode}?locale=${locale}`, | ||
{ | ||
cache: 'force-cache', | ||
headers: API_HEADERS, | ||
}, | ||
); | ||
const response = await fetch(GRAPHQL_ENDPOINT, { | ||
method: 'POST', | ||
headers: HEADERS, | ||
body: JSON.stringify({ | ||
query, | ||
operationName: GRAPHAL_OPERATION_NAMES.country, | ||
variables: { | ||
countryCode, | ||
locale, | ||
}, | ||
}), | ||
}); | ||
const country: LoadCountryResponse = await response.json(); | ||
if ('errors' in country) { | ||
throw new CountryLoaderError(country); | ||
} else { | ||
return country.data.country; | ||
} | ||
} | ||
const jsonResponse = await country.json(); | ||
return jsonResponse.data; | ||
class CountryLoaderError extends Error { | ||
constructor(errors: ResponseError) { | ||
const errorMessage = errors.errors.map(error => error.message).join('; '); | ||
super(errorMessage); | ||
} | ||
} |
import {fetch} from '@shopify/jest-dom-mocks'; | ||
import {Address, FieldName} from '../types'; | ||
import AddressFormatter from '..'; | ||
import {JapanJa, FranceFr, CanadaEn, CanadaFr} from './fixtures'; | ||
import { | ||
countriesJa, | ||
countriesEn, | ||
countryJpJa, | ||
countryJpEn, | ||
countryJpFr, | ||
} from './fixtures'; | ||
const countries = [JapanJa, CanadaFr, FranceFr]; | ||
const GRAPHQL_ENDPOINT = 'https://country-service.shopifycloud.com/graphql'; | ||
beforeEach(() => { | ||
fetch.mock( | ||
'https://country-service.shopifycloud.com/countries/JP?locale=ja', | ||
{data: JapanJa}, | ||
); | ||
}); | ||
afterEach(fetch.restore); | ||
const address: Address = { | ||
@@ -30,24 +27,46 @@ company: 'Shopify', | ||
afterEach(fetch.restore); | ||
function mockAPICall( | ||
operationName: string, | ||
fixture: any, | ||
locale: string = 'JA', | ||
) { | ||
fetch.mock( | ||
(url, options) => { | ||
if (url !== GRAPHQL_ENDPOINT || options.method !== 'POST') { | ||
return false; | ||
} | ||
if (typeof options.body === 'string') { | ||
const body = JSON.parse(options.body); | ||
return ( | ||
body.operationName === operationName && | ||
body.variables.locale === locale | ||
); | ||
} | ||
return false; | ||
}, | ||
fixture, | ||
{overwriteRoutes: false}, | ||
); | ||
} | ||
describe('updateLocale()', () => { | ||
beforeEach(() => { | ||
fetch.mock( | ||
'https://country-service.shopifycloud.com/countries/CA?locale=fr', | ||
{data: CanadaFr}, | ||
); | ||
fetch.mock( | ||
'https://country-service.shopifycloud.com/countries/CA?locale=en', | ||
{data: CanadaEn}, | ||
); | ||
mockAPICall('country', countryJpJa, 'JA'); | ||
mockAPICall('country', countryJpEn, 'EN'); | ||
}); | ||
it('returns the country in the correct locale', async () => { | ||
const addressFormatter = new AddressFormatter('fr'); | ||
let country = await addressFormatter.getCountry('CA'); | ||
const addressFormatter = new AddressFormatter('ja'); | ||
let country = await addressFormatter.getCountry('JP'); | ||
expect(country).toEqual(CanadaFr); | ||
expect(country).toEqual(countryJpJa.data.country); | ||
addressFormatter.updateLocale('en'); | ||
country = await addressFormatter.getCountry('CA'); | ||
expect(country).toEqual(CanadaEn); | ||
country = await addressFormatter.getCountry('JP'); | ||
expect(country).toEqual(countryJpEn.data.country); | ||
}); | ||
@@ -58,67 +77,89 @@ }); | ||
it('returns a country', async () => { | ||
const addressFormatter = new AddressFormatter('ja'); | ||
mockAPICall('country', countryJpJa); | ||
const addressFormatter = new AddressFormatter('JA'); | ||
const country = await addressFormatter.getCountry('JP'); | ||
expect(country).toEqual(JapanJa); | ||
expect(country).toEqual(countryJpJa.data.country); | ||
}); | ||
it('loads country from cache if it was preloaded', async () => { | ||
const addressFormatter = new AddressFormatter('ja'); | ||
let country = await addressFormatter.getCountry('JP'); | ||
it('should not call the API again for the same country if the locale is the same', async () => { | ||
mockAPICall('country', countryJpJa); | ||
expect(country).toEqual(JapanJa); | ||
const addressFormatter = new AddressFormatter('JA'); | ||
await addressFormatter.getCountry('JP'); | ||
await addressFormatter.getCountry('JP'); | ||
fetch.restore(); | ||
fetch.mock( | ||
'https://country-service.shopifycloud.com/countries/JP?locale=ja', | ||
{data: 'lol'}, | ||
); | ||
expect(fetch.calls()).toHaveLength(1); | ||
}); | ||
country = await addressFormatter.getCountry('JP'); | ||
expect(country).toEqual(JapanJa); | ||
it('should call the API again for the same country if the locale changes', async () => { | ||
mockAPICall('country', countryJpJa); | ||
mockAPICall('country', countryJpEn, 'EN'); | ||
const addressFormatter = new AddressFormatter('JA'); | ||
await addressFormatter.getCountry('JP'); | ||
expect(fetch.calls()).toHaveLength(1); | ||
addressFormatter.updateLocale('en'); | ||
await addressFormatter.getCountry('JP'); | ||
expect(fetch.calls()).toHaveLength(2); | ||
}); | ||
it('loads country from cache if all the countries were loaded', async () => { | ||
fetch.restore(); | ||
fetch.mock('https://country-service.shopifycloud.com/countries?locale=ja', { | ||
data: countries, | ||
}); | ||
fetch.mock( | ||
'https://country-service.shopifycloud.com/countries/JP?locale=ja', | ||
{data: 'lol'}, | ||
); | ||
it('should not call the API again for a country if all the countries have been loaded', async () => { | ||
mockAPICall('countries', countriesJa); | ||
mockAPICall('country', countryJpJa); | ||
const addressFormatter = new AddressFormatter('ja'); | ||
const addressFormatter = new AddressFormatter('JA'); | ||
await addressFormatter.getCountries(); | ||
const country = await addressFormatter.getCountry('JP'); | ||
await addressFormatter.getCountry('JP'); | ||
expect(country).toEqual(JapanJa); | ||
expect(fetch.calls()).toHaveLength(1); | ||
}); | ||
it('should call the API again for a country in another locale even if all the countries have been loaded', async () => { | ||
mockAPICall('countries', countriesEn, 'EN'); | ||
mockAPICall('country', countryJpFr, 'FR'); | ||
const addressFormatter = new AddressFormatter('EN'); | ||
await addressFormatter.getCountries(); | ||
addressFormatter.updateLocale('FR'); | ||
await addressFormatter.getCountry('JP'); | ||
expect(fetch.calls()).toHaveLength(2); | ||
}); | ||
}); | ||
describe('getCountries()', () => { | ||
beforeEach(() => { | ||
fetch.mock('https://country-service.shopifycloud.com/countries?locale=ja', { | ||
data: countries, | ||
}); | ||
}); | ||
it('returns all countries', async () => { | ||
mockAPICall('countries', countriesJa); | ||
it('returns all countries', async () => { | ||
const addressFormatter = new AddressFormatter('ja'); | ||
const addressFormatter = new AddressFormatter('JA'); | ||
const loadedCountries = await addressFormatter.getCountries(); | ||
expect(loadedCountries).toEqual(countries); | ||
expect(loadedCountries).toEqual(countriesJa.data.countries); | ||
}); | ||
it('loads countries from cache', async () => { | ||
const addressFormatter = new AddressFormatter('ja'); | ||
let loadedCountries = await addressFormatter.getCountries(); | ||
it('should not call the API again for the countries if the locale is the same.', async () => { | ||
mockAPICall('countries', countriesEn, 'YY'); | ||
expect(loadedCountries).toEqual(countries); | ||
const addressFormatter = new AddressFormatter('YY'); | ||
await addressFormatter.getCountries(); | ||
await addressFormatter.getCountries(); | ||
fetch.restore(); | ||
fetch.mock('https://country-service.shopifycloud.com/countries?locale=ja', { | ||
data: 'lol', | ||
}); | ||
expect(fetch.calls()).toHaveLength(1); | ||
}); | ||
loadedCountries = await addressFormatter.getCountries(); | ||
expect(loadedCountries).toEqual(countries); | ||
it('should call the API again for the countries if the locale has been updated.', async () => { | ||
mockAPICall('countries', countriesEn, 'ZZ'); | ||
mockAPICall('countries', countriesJa, 'XX'); | ||
const addressFormatter = new AddressFormatter('ZZ'); | ||
await addressFormatter.getCountries(); | ||
addressFormatter.updateLocale('xx'); | ||
await addressFormatter.getCountries(); | ||
expect(fetch.calls()).toHaveLength(2); | ||
}); | ||
@@ -128,5 +169,10 @@ }); | ||
describe('format()', () => { | ||
beforeEach(() => { | ||
mockAPICall('country', countryJpJa, 'JA'); | ||
}); | ||
it('returns an array of parts of the address', async () => { | ||
const addressFormatter = new AddressFormatter('ja'); | ||
const addressFormatter = new AddressFormatter('JA'); | ||
const result = await addressFormatter.format(address); | ||
expect(result).toEqual([ | ||
@@ -142,3 +188,3 @@ '日本', | ||
it('does not return {province} if the address does not have it', async () => { | ||
const addressFormatter = new AddressFormatter('ja'); | ||
const addressFormatter = new AddressFormatter('JA'); | ||
const result = await addressFormatter.format({ | ||
@@ -160,4 +206,8 @@ ...address, | ||
describe('getOrderedFields()', () => { | ||
beforeEach(() => { | ||
mockAPICall('country', countryJpJa, 'JA'); | ||
}); | ||
it('return fields ordered based on the country', async () => { | ||
const addressFormatter = new AddressFormatter('ja'); | ||
const addressFormatter = new AddressFormatter('JA'); | ||
const result = await addressFormatter.getOrderedFields('JP'); | ||
@@ -179,4 +229,8 @@ | ||
describe('getTranslationKey()', () => { | ||
beforeEach(() => { | ||
mockAPICall('country', countryJpJa, 'JA'); | ||
}); | ||
it('translates based on the country province key', async () => { | ||
const addressFormatter = new AddressFormatter('ja'); | ||
const addressFormatter = new AddressFormatter('JA'); | ||
const result = await addressFormatter.getTranslationKey( | ||
@@ -187,7 +241,7 @@ 'JP', | ||
expect(result).toBe('prefecture'); | ||
expect(result).toBe('PREFECTURE'); | ||
}); | ||
it('translates based on the country zip key', async () => { | ||
const addressFormatter = new AddressFormatter('ja'); | ||
const addressFormatter = new AddressFormatter('JA'); | ||
const result = await addressFormatter.getTranslationKey( | ||
@@ -198,7 +252,7 @@ 'JP', | ||
expect(result).toBe('postalCode'); | ||
expect(result).toBe('POSTAL_CODE'); | ||
}); | ||
it('translates based on the country address2 key', async () => { | ||
const addressFormatter = new AddressFormatter('ja'); | ||
const addressFormatter = new AddressFormatter('JA'); | ||
const result = await addressFormatter.getTranslationKey( | ||
@@ -209,7 +263,7 @@ 'JP', | ||
expect(result).toBe('aptSuiteEtc'); | ||
expect(result).toBe('APT_SUITE_ETC'); | ||
}); | ||
it('translates based on the country key', async () => { | ||
const addressFormatter = new AddressFormatter('ja'); | ||
const addressFormatter = new AddressFormatter('JA'); | ||
const result = await addressFormatter.getTranslationKey( | ||
@@ -216,0 +270,0 @@ 'JP', |
@@ -1,7 +0,7 @@ | ||
import CanadaFr from './CA_fr'; | ||
import CanadaEn from './CA_en'; | ||
import FranceFr from './FR_fr'; | ||
import JapanJa from './JP_ja'; | ||
import SingaporeEn from './SG_en'; | ||
import countriesJa from './countries_ja'; | ||
import countriesEn from './countries_en'; | ||
import countryJpJa from './country_jp_ja'; | ||
import countryJpEn from './country_jp_en'; | ||
import countryJpFr from './country_jp_fr'; | ||
export {CanadaFr, CanadaEn, JapanJa, SingaporeEn, FranceFr}; | ||
export {countriesJa, countriesEn, countryJpJa, countryJpEn, countryJpFr}; |
@@ -0,3 +1,4 @@ | ||
import {Country} from '../types'; | ||
import {renderLineTemplate} from '../utilities'; | ||
import {JapanJa} from './fixtures'; | ||
import {countryJpJa} from './fixtures'; | ||
@@ -20,5 +21,9 @@ const address = { | ||
const template = '{country} - {city} {zip} {province}'; | ||
expect(renderLineTemplate(JapanJa, template, address)).toEqual( | ||
'日本 - 目黒区 100-8994 東京都', | ||
); | ||
expect( | ||
renderLineTemplate( | ||
countryJpJa.data.country as Country, | ||
template, | ||
address, | ||
), | ||
).toEqual('日本 - 目黒区 100-8994 東京都'); | ||
}); | ||
@@ -29,3 +34,6 @@ | ||
expect( | ||
renderLineTemplate(JapanJa, template, {...address, province: 'lol'}), | ||
renderLineTemplate(countryJpJa.data.country as Country, template, { | ||
...address, | ||
province: 'lol', | ||
}), | ||
).toEqual('日本 - 目黒区 100-8994'); | ||
@@ -36,5 +44,9 @@ }); | ||
const template = '{country} - {city} {zip} {province} {what}'; | ||
expect(renderLineTemplate(JapanJa, template, address)).toEqual( | ||
'日本 - 目黒区 100-8994 東京都', | ||
); | ||
expect( | ||
renderLineTemplate( | ||
countryJpJa.data.country as Country, | ||
template, | ||
address, | ||
), | ||
).toEqual('日本 - 目黒区 100-8994 東京都'); | ||
}); | ||
@@ -44,3 +56,9 @@ | ||
const template = '{firstName} - {lastName}'; | ||
expect(renderLineTemplate(JapanJa, template, address)).toEqual(''); | ||
expect( | ||
renderLineTemplate( | ||
countryJpJa.data.country as Country, | ||
template, | ||
address, | ||
), | ||
).toEqual(''); | ||
}); | ||
@@ -50,3 +68,9 @@ | ||
const template = '[Nope]'; | ||
expect(renderLineTemplate(JapanJa, template, address)).toEqual(''); | ||
expect( | ||
renderLineTemplate( | ||
countryJpJa.data.country as Country, | ||
template, | ||
address, | ||
), | ||
).toEqual(''); | ||
}); | ||
@@ -57,5 +81,8 @@ | ||
expect( | ||
renderLineTemplate(JapanJa, template, {...address, province: 'NOPE'}), | ||
renderLineTemplate(countryJpJa.data.country as Country, template, { | ||
...address, | ||
province: 'NOPE', | ||
}), | ||
).toEqual(''); | ||
}); | ||
}); |
@@ -14,2 +14,16 @@ export enum FieldName { | ||
export type ProvinceKey = | ||
| 'COUNTY' | ||
| 'EMIRATE' | ||
| 'GOVERNORATE' | ||
| 'PREFECTURE' | ||
| 'PROVINCE' | ||
| 'REGION' | ||
| 'STATE_AND_TERRITORY' | ||
| 'STATE'; | ||
export type ZipKey = 'POSTAL_CODE' | 'POSTCODE' | 'PINCODE' | 'ZIP_CODE'; | ||
export type Address2Key = 'APT_SUITE_ETC' | 'APT_UNIT_NUMBER'; | ||
export interface Address { | ||
@@ -33,19 +47,35 @@ company?: string; | ||
} | ||
export interface LoadCountriesResponse { | ||
data: {countries: Country[]}; | ||
} | ||
export interface LoadCountryResponse { | ||
data: {country: Country}; | ||
} | ||
export interface Country { | ||
id: string; | ||
type: string; | ||
attributes: { | ||
code: string; | ||
name: string; | ||
phoneNumberPrefix: number; | ||
format: { | ||
edit: string; | ||
show: string; | ||
}; | ||
zoneKey: string; | ||
zipKey: string; | ||
address2Key: string; | ||
provinces: Province[]; | ||
name: string; | ||
code: string; | ||
phoneNumberPrefix: number; | ||
address2Key: Address2Key; | ||
provinceKey: ProvinceKey; | ||
zipKey: ZipKey; | ||
formatting: { | ||
edit: string; | ||
show: string; | ||
}; | ||
provinces: Province[]; | ||
} | ||
export interface ResponseError { | ||
errors: { | ||
locations: { | ||
column: number; | ||
line: number; | ||
}[]; | ||
message: string; | ||
problems: { | ||
explanation: string; | ||
}[]; | ||
value: any; | ||
}[]; | ||
} |
@@ -44,3 +44,3 @@ import {Address, FieldName, Country, Province} from './types'; | ||
case FieldName.Country: | ||
line = line.replace(`{${FieldName.Country}}`, country.attributes.name); | ||
line = line.replace(`{${FieldName.Country}}`, country.name); | ||
break; | ||
@@ -51,3 +51,3 @@ case FieldName.Province: | ||
address.province | ||
? getProvince(country.attributes.provinces, address.province).name | ||
? getProvince(country.provinces, address.province).name | ||
: '', | ||
@@ -54,0 +54,0 @@ ); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
991941
42
31028
142
3