New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@fragaria/address-formatter

Package Overview
Dependencies
Maintainers
5
Versions
35
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@fragaria/address-formatter - npm Package Compare versions

Comparing version 2.6.4 to 2.7.0

index.d.ts

17

package.json
{
"name": "@fragaria/address-formatter",
"version": "2.6.4",
"version": "2.7.0",
"description": "Universal international address formatting in Javascript",
"main": "dist/cjs/address-formatter.js",
"types": "index.d.ts",
"browser": "dist/umd/address-formatter.js",

@@ -37,2 +38,3 @@ "module": "dist/es/address-formatter.js",

"@babel/core": "^7.8.6",
"@babel/eslint-parser": "^7.16.3",
"@babel/plugin-proposal-class-properties": "^7.8.3",

@@ -42,12 +44,9 @@ "@babel/plugin-proposal-object-rest-spread": "^7.8.3",

"@babel/preset-env": "^7.8.6",
"babel-core": "^7.0.0-bridge.0",
"babel-eslint": "^10.0.3",
"babel-jest": "^27.0.1",
"babel-loader": "^8.0.6",
"babel-plugin-transform-builtin-extend": "^1.1.2",
"babel-jest": "^27.4.1",
"babel-loader": "^8.2.3",
"coveralls": "^3.0.9",
"eslint": "^7.2.0",
"eslint": "^8.4.0",
"eslint-config-standard": "^16.0.0",
"eslint-plugin-import": "^2.19.1",
"eslint-plugin-jest": "^24.0.0",
"eslint-plugin-jest": "^25.2.1",
"eslint-plugin-node": "^11.0.0",

@@ -67,3 +66,3 @@ "eslint-plugin-promise": "^5.1.0",

"engines": {
"node": ">=10.0.0"
"node": ">=12.0.0"
},

@@ -70,0 +69,0 @@ "jest": {

@@ -1,329 +0,15 @@

const Mustache = require('mustache');
const templates = require('./templates/templates.json');
const aliases = require('./templates/aliases.json');
const stateCodes = require('./templates/state-codes.json');
const countyCodes = require('./templates/county-codes.json');
const country2lang = require('./templates/country-to-lang.json');
const abbreviations = require('./templates/abbreviations.json');
const internal = require('./internal.js');
const countryNames = require('./templates/country-names.json');
const knownComponents = aliases.map((a) => a.alias);
const VALID_REPLACEMENT_COMPONENTS = ['state'];
const determineCountryCode = (input, fallbackCountryCode = null) => {
let countryCode = input.country_code && input.country_code.toUpperCase();
if (!templates[countryCode] && fallbackCountryCode) {
countryCode = fallbackCountryCode.toUpperCase();
}
if (!countryCode || countryCode.length !== 2) {
// TODO change this to exceptions
return input;
}
if (countryCode === 'UK') {
countryCode = 'GB';
}
if (templates[countryCode] && templates[countryCode].use_country) {
const oldCountryCode = countryCode;
countryCode = templates[countryCode].use_country.toUpperCase();
if (templates[oldCountryCode].change_country) {
let newCountry = templates[oldCountryCode].change_country;
const componentRegex = /\$(\w*)/;
const componentMatch = componentRegex.exec(newCountry);
if (componentMatch) {
if (input[componentMatch[1]]) {
newCountry = newCountry.replace(new RegExp(`\\$${componentMatch[1]}`), input[componentMatch[1]]);
} else {
newCountry = newCountry.replace(new RegExp(`\\$${componentMatch[1]}`), '');
}
}
input.country = newCountry;
}
if (templates[oldCountryCode].add_component && templates[oldCountryCode].add_component.indexOf('=') > -1) {
const splitted = templates[oldCountryCode].add_component.split('=');
if (VALID_REPLACEMENT_COMPONENTS.indexOf(splitted[0]) > -1) {
input[splitted[0]] = splitted[1];
}
}
}
if (countryCode === 'NL' && input.state) {
if (input.state === 'Curaçao') {
countryCode = 'CW';
input.country = 'Curaçao';
} else if (input.state.match(/sint maarten/i)) {
countryCode = 'SX';
input.country = 'Sint Maarten';
} else if (input.state.match(/aruba/i)) {
countryCode = 'AW';
input.country = 'Aruba';
}
}
// eslint-disable-next-line camelcase
input.country_code = countryCode;
return input;
};
const normalizeComponentKeys = (input) => {
const inputKeys = Object.keys(input);
for (let i = 0; i < inputKeys.length; i++) {
const snaked = inputKeys[i].replace(/([A-Z])/g, '_$1').toLowerCase();
if (knownComponents.indexOf(snaked) > -1 && !input[snaked]) {
if (input[inputKeys[i]]) {
input[snaked] = input[inputKeys[i]];
}
delete input[inputKeys[i]];
}
}
return input;
};
const applyAliases = (input) => {
const inputKeys = Object.keys(input);
for (let i = 0; i < inputKeys.length; i++) {
const alias = aliases.find((a) => a.alias === inputKeys[i]);
if (alias && !input[alias.name]) {
input[alias.name] = input[alias.alias];
}
}
return input;
};
const getStateCode = (state, countryCode) => {
if (!stateCodes[countryCode]) {
return;
}
// TODO what if state is actually the stateCode?
// https://github.com/OpenCageData/perl-Geo-Address-Formatter/blob/master/lib/Geo/Address/Formatter.pm#L526
const found = stateCodes[countryCode].find((e) => {
if (typeof e.name == 'string' && e.name.toUpperCase() === state.toUpperCase()) {
return e;
}
const variants = Object.values(e.name);
const foundVariant = variants.find((e) => e.toUpperCase() === state.toUpperCase());
if (foundVariant) {
return {
key: e.key,
};
}
return false;
});
return found && found.key;
};
const getCountyCode = (county, countryCode) => {
if (!countyCodes[countryCode]) {
return;
}
// TODO what if county is actually the countyCode?
const found = countyCodes[countryCode].find((e) => {
if (typeof e.name == 'string' && e.name.toUpperCase() === county.toUpperCase()) {
return e;
}
const variants = Object.values(e.name);
const foundVariant = variants.find((e) => e.toUpperCase() === county.toUpperCase());
if (foundVariant) {
return {
key: e.key,
};
}
return false;
});
return found && found.key;
};
const cleanupInput = (input, replacements = [], options = {}) => {
// If the country is a number, use the state as country
let inputKeys = Object.keys(input);
if (input.country && input.state && Number.isInteger(input.country)) {
input.country = input.state;
delete input.state;
}
if (replacements && replacements.length) {
for (let i = 0; i < inputKeys.length; i++) {
for (let j = 0; j < replacements.length; j++) {
const componentRegex = new RegExp(`^${inputKeys[i]}=`);
if (replacements[j][0].match(componentRegex)) {
const val = replacements[j][0].replace(componentRegex, '');
if (input[inputKeys[i]] === val) {
input[inputKeys[i]] = replacements[j][1];
}
} else {
input[inputKeys[i]] = `${input[inputKeys[i]]}`.replace(new RegExp(replacements[j][0]), replacements[j][1]);
}
}
}
}
if (!input.state_code && input.state) {
// eslint-disable-next-line camelcase
input.state_code = getStateCode(input.state, input.country_code);
if (input.state.match(/^washington,? d\.?c\.?/i)) {
// eslint-disable-next-line camelcase
input.state_code = 'DC';
input.state = 'District of Columbia';
input.city = 'Washington';
}
}
if (!input.county_code && input.county) {
// eslint-disable-next-line camelcase
input.county_code = getCountyCode(input.county, input.country_code);
}
const unknownComponents = [];
for (let i = 0; i < inputKeys.length; i++) {
if (knownComponents.indexOf(inputKeys[i]) === -1) {
unknownComponents.push(inputKeys[i]);
}
}
if (unknownComponents.length) {
input.attention = unknownComponents.map((c) => input[c]).join(', ');
}
if (input.postcode && options.cleanupPostcode !== false) {
// convert to string
input.postcode = `${input.postcode}`;
const multiCodeRegex = /^(\d{5}),\d{5}/;
const multiCodeMatch = multiCodeRegex.exec(input.postcode);
if (input.postcode.length > 20) {
delete input.postcode;
// OSM may use postcode ranges
} else if (input.postcode.match(/\d+;\d+/)) {
delete input.postcode;
} else if (multiCodeMatch) {
input.postcode = multiCodeMatch[1];
}
}
if (options.abbreviate && input.country_code && country2lang[input.country_code]) {
for (let i = 0; i < country2lang[input.country_code].length; i++) {
const lang = country2lang[input.country_code][i];
if (abbreviations[lang]) {
for (let j = 0; j < abbreviations[lang].length; j++) {
if (input[abbreviations[lang][j].component]) {
for (let k = 0; k < abbreviations[lang][j].replacements.length; k++) {
input[abbreviations[lang][j].component] = input[abbreviations[lang][j].component].replace(
new RegExp(`\\b${abbreviations[lang][j].replacements[k].src}\\b`),
abbreviations[lang][j].replacements[k].dest,
);
}
}
}
}
}
}
// naive url cleanup, keys might have changed along the cleanup
inputKeys = Object.keys(input);
for (let i = 0; i < inputKeys.length; i++) {
if (`${input[inputKeys[i]]}`.match(/^https?:\/\//i)) {
delete input[inputKeys[i]];
}
}
return input;
};
const findTemplate = (input) => {
return templates[input.country_code] ? templates[input.country_code] : templates.default;
};
const chooseTemplateText = (template, input) => {
let selected = template.address_template || templates.default.address_template;
const threshold = 2;
// Choose fallback only when none of these is present
const required = ['road', 'postcode'];
const missingValuesCnt = required
.map((r) => !!input[r])
.filter((s) => !s)
.length;
if (missingValuesCnt === threshold) {
selected = template.fallback_template || templates.default.fallback_template;
}
return selected;
};
const cleanupRender = (text) => {
const replacements = [
// eslint-disable-next-line no-useless-escape
{ s: /[\},\s]+$/u, d: '' },
{ s: /^[,\s]+/u, d: '' },
{ s: /^- /u, d: '' }, // line starting with dash due to a parameter missing
{ s: /,\s*,/u, d: ', ' }, // multiple commas to one
{ s: /[ \t]+,[ \t]+/u, d: ', ' }, // one horiz whitespace behind comma
{ s: /[ \t][ \t]+/u, d: ' ' }, // multiple horiz whitespace to one
{ s: /[ \t]\n/u, d: '\n' }, // horiz whitespace, newline to newline
{ s: /\n,/u, d: '\n' }, // newline comma to just newline
{ s: /,,+/u, d: ',' }, // multiple commas to one
{ s: /,\n/u, d: '\n' }, // comma newline to just newline
{ s: /\n[ \t]+/u, d: '\n' }, // newline plus space to newline
{ s: /\n\n+/u, d: '\n' }, // multiple newline to one
];
const dedupe = (inputChunks, glue, modifier = (s) => s) => {
const seen = {};
const result = [];
for (let i = 0; i < inputChunks.length; i++) {
const chunk = inputChunks[i].trim();
// Special casing New York here, no dedupe for it
if (chunk.toLowerCase() === 'new york') {
seen[chunk] = 1;
result.push(chunk);
continue;
}
if (!seen[chunk]) {
seen[chunk] = 1;
result.push(modifier(chunk));
}
}
return result.join(glue);
};
for (let i = 0; i < replacements.length; i++) {
text = text.replace(replacements[i].s, replacements[i].d);
text = dedupe(text.split('\n'), '\n', (s) => {
return dedupe(s.split(', '), ', ');
});
}
return text.trim();
};
const renderTemplate = (template, input) => {
const templateText = chooseTemplateText(template, input);
const templateInput = Object.assign({}, input, {
first: () => {
return (text, render) => {
const possibilities = render(text, input)
.split(/\s*\|\|\s*/)
.filter((b) => b.length > 0);
return possibilities.length ? possibilities[0] : '';
};
},
});
let render = cleanupRender(Mustache.render(templateText, templateInput));
if (template.postformat_replace) {
for (let i = 0; i < template.postformat_replace.length; i++) {
const replacement = template.postformat_replace[i];
render = render.replace(new RegExp(replacement[0]), replacement[1]);
}
}
render = cleanupRender(render);
if (!render.trim().length) {
render = cleanupRender(Object.keys(input)
.map((i) => input[i])
.filter((s) => !!s)
.join(', '));
}
return render + '\n';
};
module.exports = {
format: (input, options = {
countryCode: undefined,
abbreviate: false,
output: 'string',
appendCountry: false,
cleanupPostcode: true,
countryCode: undefined,
fallbackCountryCode: undefined,
output: 'string',
}) => {
let realInput = Object.assign({}, input);
realInput = normalizeComponentKeys(realInput);
realInput = internal.normalizeComponentKeys(realInput);
if (options.countryCode) {

@@ -333,10 +19,10 @@ // eslint-disable-next-line camelcase

}
realInput = determineCountryCode(realInput, options.fallbackCountryCode);
realInput = internal.determineCountryCode(realInput, options.fallbackCountryCode);
if (options.appendCountry && countryNames[realInput.country_code] && !realInput.country) {
realInput.country = countryNames[realInput.country_code];
}
realInput = applyAliases(realInput);
const template = findTemplate(realInput);
realInput = cleanupInput(realInput, template.replace, options);
const result = renderTemplate(template, realInput);
realInput = internal.applyAliases(realInput);
const template = internal.findTemplate(realInput);
realInput = internal.cleanupInput(realInput, template.replace, options);
const result = internal.renderTemplate(template, realInput);
if (options.output === 'array') {

@@ -347,12 +33,2 @@ return result.split('\n').filter((f) => !!f);

},
_determineCountryCode: determineCountryCode,
_normalizeComponentKeys: normalizeComponentKeys,
_applyAliases: applyAliases,
_getStateCode: getStateCode,
_getCountyCode: getCountyCode,
_cleanupInput: cleanupInput,
_findTemplate: findTemplate,
_chooseTemplateText: chooseTemplateText,
_cleanupRender: cleanupRender,
_renderTemplate: renderTemplate,
};

@@ -1,1 +0,1 @@

[{"alias":"street_number","name":"house_number"},{"alias":"house_number","name":"house_number"},{"alias":"building","name":"house"},{"alias":"public_building","name":"house"},{"alias":"isolated_dwelling","name":"house"},{"alias":"farmland","name":"house"},{"alias":"allotments","name":"house"},{"alias":"house","name":"house"},{"alias":"footway","name":"road"},{"alias":"street","name":"road"},{"alias":"street_name","name":"road"},{"alias":"residential","name":"road"},{"alias":"path","name":"road"},{"alias":"pedestrian","name":"road"},{"alias":"road_reference","name":"road"},{"alias":"road_reference_intl","name":"road"},{"alias":"square","name":"road"},{"alias":"place","name":"road"},{"alias":"road","name":"road"},{"alias":"locality","name":"hamlet"},{"alias":"croft","name":"hamlet"},{"alias":"hamlet","name":"hamlet"},{"alias":"village","name":"village"},{"alias":"suburb","name":"neighbourhood"},{"alias":"city_district","name":"neighbourhood"},{"alias":"district","name":"neighbourhood"},{"alias":"quarter","name":"neighbourhood"},{"alias":"borough","name":"neighbourhood"},{"alias":"city_block","name":"neighbourhood"},{"alias":"residential","name":"neighbourhood"},{"alias":"commercial","name":"neighbourhood"},{"alias":"industrial","name":"neighbourhood"},{"alias":"houses","name":"neighbourhood"},{"alias":"subdistrict","name":"neighbourhood"},{"alias":"subdivision","name":"neighbourhood"},{"alias":"ward","name":"neighbourhood"},{"alias":"neighbourhood","name":"neighbourhood"},{"alias":"postal_city","name":"postal_city"},{"alias":"town","name":"city"},{"alias":"township","name":"city"},{"alias":"city","name":"city"},{"alias":"local_administrative_area","name":"municipality"},{"alias":"subcounty","name":"municipality"},{"alias":"municipality","name":"municipality"},{"alias":"county_code","name":"county"},{"alias":"department","name":"county"},{"alias":"county","name":"county"},{"alias":"state_district","name":"state_district"},{"alias":"partial_postcode","name":"postcode"},{"alias":"postcode","name":"postcode"},{"alias":"province","name":"state"},{"alias":"state_code","name":"state"},{"alias":"state","name":"state"},{"alias":"region","name":"region"},{"alias":"island","name":"island"},{"alias":"archipelago","name":"archipelago"},{"alias":"country_name","name":"country"},{"alias":"country","name":"country"},{"alias":"country_code","name":"country_code"},{"alias":"continent","name":"continent"}]
[{"alias":"street_number","name":"house_number"},{"alias":"housenumber","name":"house_number"},{"alias":"house_number","name":"house_number"},{"alias":"building","name":"house"},{"alias":"public_building","name":"house"},{"alias":"isolated_dwelling","name":"house"},{"alias":"farmland","name":"house"},{"alias":"allotments","name":"house"},{"alias":"house","name":"house"},{"alias":"footway","name":"road"},{"alias":"street","name":"road"},{"alias":"street_name","name":"road"},{"alias":"residential","name":"road"},{"alias":"path","name":"road"},{"alias":"pedestrian","name":"road"},{"alias":"road_reference","name":"road"},{"alias":"road_reference_intl","name":"road"},{"alias":"square","name":"road"},{"alias":"place","name":"road"},{"alias":"road","name":"road"},{"alias":"locality","name":"hamlet"},{"alias":"croft","name":"hamlet"},{"alias":"hamlet","name":"hamlet"},{"alias":"village","name":"village"},{"alias":"suburb","name":"neighbourhood"},{"alias":"city_district","name":"neighbourhood"},{"alias":"district","name":"neighbourhood"},{"alias":"quarter","name":"neighbourhood"},{"alias":"borough","name":"neighbourhood"},{"alias":"city_block","name":"neighbourhood"},{"alias":"residential","name":"neighbourhood"},{"alias":"commercial","name":"neighbourhood"},{"alias":"industrial","name":"neighbourhood"},{"alias":"houses","name":"neighbourhood"},{"alias":"subdistrict","name":"neighbourhood"},{"alias":"subdivision","name":"neighbourhood"},{"alias":"ward","name":"neighbourhood"},{"alias":"neighbourhood","name":"neighbourhood"},{"alias":"postal_city","name":"postal_city"},{"alias":"town","name":"city"},{"alias":"township","name":"city"},{"alias":"city","name":"city"},{"alias":"local_administrative_area","name":"municipality"},{"alias":"subcounty","name":"municipality"},{"alias":"municipality","name":"municipality"},{"alias":"county_code","name":"county"},{"alias":"department","name":"county"},{"alias":"county","name":"county"},{"alias":"state_district","name":"state_district"},{"alias":"postal_code","name":"postcode"},{"alias":"partial_postcode","name":"postcode"},{"alias":"postcode","name":"postcode"},{"alias":"province","name":"state"},{"alias":"state_code","name":"state"},{"alias":"state","name":"state"},{"alias":"region","name":"region"},{"alias":"island","name":"island"},{"alias":"archipelago","name":"archipelago"},{"alias":"country_name","name":"country"},{"alias":"country","name":"country"},{"alias":"country_code","name":"country_code"},{"alias":"continent","name":"continent"}]

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc