From 879ee6d63c4f0cdbf520e7490abac7a49b7fc887 Mon Sep 17 00:00:00 2001 From: Dmytro Chyrkin Date: Tue, 27 May 2025 02:05:21 +0300 Subject: [PATCH 01/13] fix: CA Street Directions and Street Types feat: extend IParsedAddress with streetDirection feat: fix parsing CA street directions feat: add CA street types test: extend test with CA street directions --------- Co-authored-by: K. Sokolinskyi --- .vscode/settings.json | 10 ++ data/ca-street-types.json | 120 ++++++++++++++++++++ index.d.ts | 1 + index.js | 122 +++++++++++++------- test/test.js | 229 ++++++++++++++++++++++++++------------ 5 files changed, 373 insertions(+), 109 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 data/ca-street-types.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..933440f --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,10 @@ +{ + "editor.formatOnSave": false, // disable for eslint + prettier combo + "editor.formatOnPaste": false, // disable for eslint + prettier combo + "[yaml]": { + "editor.formatOnSave": false + }, + "editor.tabSize": 4, + "editor.insertSpaces": true, + "files.trimTrailingWhitespace": true +} diff --git a/data/ca-street-types.json b/data/ca-street-types.json new file mode 100644 index 0000000..d91f686 --- /dev/null +++ b/data/ca-street-types.json @@ -0,0 +1,120 @@ +{ + "acres": "acres", + "alley": "alley", + "avenue": "avenue", + "bay": "bay", + "beach": "beach", + "bend": "bend", + "boulevard": "boulevard", + "by-pass": "by-pass", + "byway": "byway", + "campus": "campus", + "cape": "cape", + "centre": "centre", + "chase": "chase", + "circle": "circle", + "circuit": "circuit", + "close": "close", + "common": "common", + "concession": "concession", + "corners": "corners", + "court": "court", + "cove": "cove", + "crescent": "crescent", + "crossing": "crossing", + "cul-de-sac": "cul-de-sac", + "dale": "dale", + "dell": "dell", + "diversion": "diversion", + "downs": "downs", + "drive": "drive", + "end": "end", + "esplanade": "esplanade", + "estates": "estates", + "expressway": "expressway", + "extension": "extension", + "farm": "farm", + "field": "field", + "forest": "forest", + "freeway": "freeway", + "front": "front", + "gardens": "gardens", + "gate": "gate", + "glade": "glade", + "glen": "glen", + "green": "green", + "grounds": "grounds", + "grove": "grove", + "harbour": "harbour", + "heath": "heath", + "heights": "heights", + "highlands": "highlands", + "highway": "highway", + "hill": "hill", + "hollow": "hollow", + "inlet": "inlet", + "island": "island", + "key": "key", + "knoll": "knoll", + "landing": "landing", + "lane": "lane", + "limits": "limits", + "line": "line", + "link": "link", + "lookout": "lookout", + "loop": "loop", + "mall": "mall", + "manor": "manor", + "maze": "maze", + "meadow": "meadow", + "mews": "mews", + "moor": "moor", + "mount": "mount", + "mountain": "mountain", + "orchard": "orchard", + "parade": "parade", + "park": "park", + "parkway": "parkway", + "passage": "passage", + "path": "path", + "pathway": "pathway", + "pines": "pines", + "place": "place", + "plateau": "plateau", + "plaza": "plaza", + "point": "point", + "port": "port", + "private": "private", + "promenade": "promenade", + "quay": "quay", + "ramp": "ramp", + "range": "range", + "ridge": "ridge", + "rise": "rise", + "road": "road", + "route": "route", + "row": "row", + "run": "run", + "square": "square", + "street": "st", + "subdivision": "subdivision", + "terrace": "terrace", + "thicket": "thicket", + "towers": "towers", + "townline": "townline", + "trail": "trail", + "turnabout": "turnabout", + "vale": "vale", + "via": "via", + "view": "view", + "village": "village", + "villas": "villas", + "vista": "vista", + "walk": "walk", + "way": "way", + "wharf": "wharf", + "wood": "wood", + "wynd": "wynd", + "abbey": "abbey", + "st": "st" +} diff --git a/index.d.ts b/index.d.ts index 8e4e55d..ae630b6 100644 --- a/index.d.ts +++ b/index.d.ts @@ -13,6 +13,7 @@ declare module "addresser" { streetNumber: string; streetSuffix: string; streetName: string; + streetDirection: string; id: string; } diff --git a/index.js b/index.js index 1f8fa7c..93ebc10 100644 --- a/index.js +++ b/index.js @@ -1,9 +1,9 @@ -var allStates = require('./data/states.json'); -var usStreetTypes = require('./data/us-street-types.json'); -var allCities = require('./data/cities.json'); -var usStates = require('./data/us-states.json'); -var usCities = require('./data/us-cities.json'); - +const allStates = require('./data/states.json'); +const usStreetTypes = require('./data/us-street-types.json'); +const caStreetTypes = require('./data/ca-street-types.json'); +const allCities = require('./data/cities.json'); +const usStates = require('./data/us-states.json'); +const usCities = require('./data/us-cities.json'); 'use strict'; @@ -13,7 +13,7 @@ var usCities = require('./data/us-cities.json'); * @param {string} address * @return {string} **/ - + //TODO move this to utils file function getKeyByValue(object, value) { return Object.keys(object).find(key => object[key] === value); @@ -32,14 +32,45 @@ function randomProperty (obj) { }; var usStreetDirectional = { - north : "N", - northeast : "NE", - east : "E", - southeast : "SE", - south : "S", - southwest : "SW", - west : "W", - northwest : "NW", + "N": "N", + "NE": "NE", + "E": "E", + "SE": "SE", + "S": "S", + "SW": "SW", + "W": "W", + "NW": "NW" +}; + +var caStreetDirectional = { + + "N": "N", + "North": "N", + + "E": "E", + "East": "E", + + "S": "S", + "South": "S", + + "W": "W", + "West": "W", + + "NE": "NE", + "Northeast": "NE", + "North East": "NE", + + "SE": "SE", + "SouthEast": "SE", + "South East": "SE", + + "NW": "NW", + "North West": "NW", + "Northwest": "NW", + + "SW": "SW", + "Southwest" : "SW", + "South West": "SW" }; var usLine2Prefixes = { @@ -95,15 +126,22 @@ module.exports = { address = address.replace(/ +/g, ' '); // Assume comma, newline and tab is an intentional delimiter var addressParts = address.split(/,|\t|\n/); - + var result = {}; // Check if the last section contains country reference (Just supports US for now) var countrySection = addressParts[addressParts.length-1].trim(); + let streetTypes = usStreetTypes; + let streetDirectional = usStreetDirectional; if (countrySection === 'US' || countrySection === 'USA' || countrySection === 'United States' || countrySection === 'Canada') { addressParts.splice(-1,1); + + if (countrySection === 'Canada') { + streetTypes = caStreetTypes; + streetDirectional = caStreetDirectional; + } } - + // Assume the last address section contains state, zip or both var stateString = addressParts[addressParts.length-1].trim(); // Parse and remove zip or zip plus 4 from end of string @@ -158,12 +196,12 @@ module.exports = { placeString = addressParts[addressParts.length-1].trim(); } result.placeName = ""; - + allCities[result.stateAbbreviation].some(function(element) { var re = new RegExp(element + "$", "i"); if (placeString.match(re)) { placeString = placeString.replace(re,""); // Carve off the place name - + result.placeName = element; return element; // Found a winner - stop looking for cities } @@ -172,10 +210,10 @@ module.exports = { result.placeName = toTitleCase(placeString); placeString = ""; } - + // Parse the street data var streetString = ""; - var usStreetDirectionalString = Object.keys(usStreetDirectional).map(x => usStreetDirectional[x]).join('|'); + var usStreetDirectionalString = Object.keys(streetDirectional).join('|'); var usLine2String = Object.keys(usLine2Prefixes).join('|'); if (placeString.length > 0) { // Check if anything is left of last section @@ -183,7 +221,7 @@ module.exports = { } else { addressParts.splice(-1,1); } - + if (addressParts.length > 2) { throw 'Can not parse address. More than two address lines.'; } else if (addressParts.length === 2) { @@ -209,9 +247,10 @@ module.exports = { } } //Assume street address comes first and the rest is secondary address - var reStreet = new RegExp('\.\*\\b(?:' + - Object.keys(usStreetTypes).join('|') + ')\\b\\.?' + + var reStreet = new RegExp('\.\*\\b(?:' + + Object.keys(streetTypes).join('|') + ')\\b\\.?' + '( +(?:' + usStreetDirectionalString + ')\\b)?', 'i'); + var rePO = new RegExp('(P\\.?O\\.?|POST\\s+OFFICE)\\s+(BOX|DRAWER)\\s\\w+', 'i'); var reAveLetter = new RegExp('\.\*\\b(ave.?|avenue)\.\*\\b[a-zA-Z]\\b', 'i'); var reNoSuffix = new RegExp('\\b\\d+[a-z]?\\s[a-zA-Z0-9_ ]+\\b', 'i'); @@ -226,10 +265,10 @@ module.exports = { result.addressLine2 = streetString; } } - + var streetParts = result.addressLine1.split(' '); - - // Assume type is last and number is first + + // Assume type is last and number is first result.streetNumber = streetParts[0]; // Assume number is first element // Normalize to Ave @@ -254,30 +293,33 @@ module.exports = { } } var streetParts = result.addressLine1.split(' '); - + // Check if directional is last element var re = new RegExp('\.\*\\b(?:' + usStreetDirectionalString + ')$', 'i'); + if (result.addressLine1.match(re)) { - result.streetDirection = streetParts.pop().toUpperCase(); + const direction = streetParts.pop().split(""); + const [f, ...rest] = direction; + result.streetDirection = streetDirectional[f.toUpperCase() + rest.join("")]; } - - // Assume type is last and number is first + + // Assume type is last and number is first result.streetNumber = streetParts[0]; // Assume number is first element - + // If there are only 2 street parts (number and name) then its likely missing a "real" suffix and the street name just happened to match a suffix if (streetParts.length > 2) { // Remove '.' if it follows streetSuffix streetParts[streetParts.length-1] = streetParts[streetParts.length-1].replace(/\.$/, ''); - result.streetSuffix = toTitleCase(usStreetTypes[streetParts[streetParts.length-1].toLowerCase()]); + result.streetSuffix = toTitleCase(streetTypes[streetParts[streetParts.length-1].toLowerCase()]); } - + result.streetName = streetParts[1]; // Assume street name is everything in the middle for (var i = 2; i < streetParts.length-1; i++) { result.streetName = result.streetName + " " + streetParts[i]; } result.streetName = toTitleCase(result.streetName); result.addressLine1 = [result.streetNumber, result.streetName].join(" "); - + if (result.hasOwnProperty('streetSuffix')) { result.addressLine1 = result.addressLine1 + ' ' + result.streetSuffix; } @@ -294,12 +336,12 @@ module.exports = { result.addressLine2 = streetString.match(reLine2)[0].trim(); streetString = streetString.replace(reLine2,"").trim(); // Carve off the first address line } - + result.addressLine1 = streetString.match(reNoSuffix)[0]; streetString = streetString.replace(reNoSuffix,"").trim(); // Carve off the first address line var streetParts = result.addressLine1.split(' '); - - // Assume type is last and number is first + + // Assume type is last and number is first result.streetNumber = streetParts[0]; // Assume number is first element streetParts.shift(); // Remove the first element result.streetName = streetParts.join(' '); // Assume street name is everything else @@ -309,7 +351,7 @@ module.exports = { } else { throw 'Can not parse address. Invalid street address data. Input string: ' + address; } - + var addressString = result.addressLine1; if (result.hasOwnProperty('addressLine2')) { addressString += ', ' + result.addressLine2; @@ -319,7 +361,7 @@ module.exports = { result['formattedAddress'] = idString; result['id'] = encodeURI(idString.replace(/ /g, '-').replace(/\#/g, '-').replace(/\//g, '-').replace(/\./g, '-')); } - + return result; }, diff --git a/test/test.js b/test/test.js index 4a58c7d..e578472 100644 --- a/test/test.js +++ b/test/test.js @@ -372,14 +372,14 @@ describe('#parseAddress', function() { expect(result.addressLine1).to.equal("PO BOX 538"); expect(result.id).to.equal('PO-BOX-538,-Basile,-LA-70515'); }); - + it('should provide an id for a valid address with second address line', function() { var result = addresser.parseAddress("123 Main St Unit 101, Conway, SC 29526"); expect(result.addressLine1).to.equal("123 Main St"); expect(result.addressLine2).to.equal("Unit 101"); expect(result.id).to.equal('123-Main-St,-Unit-101,-Conway,-SC-29526'); }); - + it('should not provide an id if mandatory components are not present', function() { var result = addresser.parseAddress("1010 PINE, 9E-6-01\nST. LOUIS MO"); expect(result.streetNumber).to.equal("1010"); @@ -408,7 +408,7 @@ describe('#parseAddress', function() { expect(result.zipCode).to.equal("78660"); expect(result.hasOwnProperty("zipCodePlusFour")).to.equal(false); }); - + it('should parse a street address with "Ave C" style street name', function() { var result = addresser.parseAddress("826 N Ave C, Crowley, LA 70526"); expect(result.streetNumber).to.equal("826"); @@ -435,7 +435,7 @@ describe('#parseAddress', function() { expect(result.zipCode).to.equal("70526"); expect(result).to.not.have.property("zipCodePlusFour"); }); - + it('should parse a street address with "Ave. b" style street name', function() { var result = addresser.parseAddress("826 N Ave. b, Crowley, LA 70526"); expect(result.streetNumber).to.equal("826"); @@ -449,7 +449,7 @@ describe('#parseAddress', function() { expect(result.zipCode).to.equal("70526"); expect(result).to.not.have.property("zipCodePlusFour"); }); - + it('should parse a street address with "Ave. b" style street name with non delimited second address line', function() { var result = addresser.parseAddress("826 N Ave. b Unit 101, Crowley, LA 70526"); expect(result.streetNumber).to.equal("826"); @@ -463,7 +463,7 @@ describe('#parseAddress', function() { expect(result.zipCode).to.equal("70526"); expect(result).to.not.have.property("zipCodePlusFour"); }); - + it('should parse a street address without a normal suffix like 123 Texas Gold', function() { var result = addresser.parseAddress("12939 Texas Gold, San Antonio, TX 78253"); expect(result.streetNumber).to.equal("12939"); @@ -477,7 +477,7 @@ describe('#parseAddress', function() { expect(result.zipCode).to.equal('78253'); expect(result).to.not.have.property("zipCodePlusFour"); }); - + it('should parse a street address without a normal suffix and 2nd address line like 123 Texas Gold Unit 101', function() { var result = addresser.parseAddress("12939 Texas Gold Unit 101, San Antonio, TX 78253"); expect(result.streetNumber).to.equal("12939"); @@ -491,7 +491,7 @@ describe('#parseAddress', function() { expect(result.zipCode).to.equal('78253'); expect(result).to.not.have.property("zipCodePlusFour"); }); - + it('should parse an Interstate address with a # unit', function() { var result = addresser.parseAddress("10701 S Interstate 35 # 35, Austin, TX"); expect(result.streetNumber).to.equal("10701"); @@ -502,49 +502,49 @@ describe('#parseAddress', function() { expect(result.placeName).to.equal("Austin"); expect(result.stateAbbreviation).to.equal("TX"); expect(result.stateName).to.equal("Texas"); - expect(result).to.not.have.property("zipCode"); + expect(result).to.not.have.property("zipCode"); expect(result).to.not.have.property("zipCodePlusFour"); }); - + it('should parse FM number style road names', function() { var result = addresser.parseAddress("11434 W FM 471, San Antonio, TX"); expect(result.streetNumber).to.equal("11434"); expect(result.streetName).to.equal("W FM 471"); expect(result).to.not.have.property('streetSuffix') expect(result.addressLine1).to.equal("11434 W FM 471"); - expect(result).to.not.have.property("addressLine2"); + expect(result).to.not.have.property("addressLine2"); expect(result.placeName).to.equal("San Antonio"); expect(result.stateAbbreviation).to.equal("TX"); expect(result.stateName).to.equal("Texas"); - expect(result).to.not.have.property("zipCode"); + expect(result).to.not.have.property("zipCode"); expect(result).to.not.have.property("zipCodePlusFour"); }); - + it('should parse street name ending in Oak', function() { var result = addresser.parseAddress("24330 Invitation Oak, San Antonio, TX"); expect(result.streetNumber).to.equal("24330"); expect(result.streetName).to.equal("Invitation Oak"); expect(result).to.not.have.property('streetSuffix') expect(result.addressLine1).to.equal("24330 Invitation Oak"); - expect(result).to.not.have.property("addressLine2"); + expect(result).to.not.have.property("addressLine2"); expect(result.placeName).to.equal("San Antonio"); expect(result.stateAbbreviation).to.equal("TX"); expect(result.stateName).to.equal("Texas"); - expect(result).to.not.have.property("zipCode"); + expect(result).to.not.have.property("zipCode"); expect(result).to.not.have.property("zipCodePlusFour"); }); - + it('should parse street name thats just a number', function() { var result = addresser.parseAddress("506 W 1100, Chesterton, IN"); expect(result.streetNumber).to.equal("506"); expect(result.streetName).to.equal("W 1100"); expect(result).to.not.have.property('streetSuffix') expect(result.addressLine1).to.equal("506 W 1100"); - expect(result).to.not.have.property("addressLine2"); + expect(result).to.not.have.property("addressLine2"); expect(result.placeName).to.equal("Chesterton"); expect(result.stateAbbreviation).to.equal("IN"); expect(result.stateName).to.equal("Indiana"); - expect(result).to.not.have.property("zipCode"); + expect(result).to.not.have.property("zipCode"); expect(result).to.not.have.property("zipCodePlusFour"); }); @@ -554,67 +554,67 @@ describe('#parseAddress', function() { expect(result.streetName).to.equal("Longbranch Run"); expect(result).to.not.have.property('streetSuffix') expect(result.addressLine1).to.equal("25403 Longbranch Run"); - expect(result).to.not.have.property("addressLine2"); + expect(result).to.not.have.property("addressLine2"); expect(result.placeName).to.equal("San Antonio"); expect(result.stateAbbreviation).to.equal("TX"); expect(result.stateName).to.equal("Texas"); - expect(result).to.not.have.property("zipCode"); + expect(result).to.not.have.property("zipCode"); expect(result).to.not.have.property("zipCodePlusFour"); }); - + it('should parse street name that ends in Chase', function() { var result = addresser.parseAddress("22923 Cardigan Chase, San Antonio, TX"); expect(result.streetNumber).to.equal("22923"); expect(result.streetName).to.equal("Cardigan Chase"); expect(result).to.not.have.property('streetSuffix') expect(result.addressLine1).to.equal("22923 Cardigan Chase"); - expect(result).to.not.have.property("addressLine2"); + expect(result).to.not.have.property("addressLine2"); expect(result.placeName).to.equal("San Antonio"); expect(result.stateAbbreviation).to.equal("TX"); expect(result.stateName).to.equal("Texas"); - expect(result).to.not.have.property("zipCode"); + expect(result).to.not.have.property("zipCode"); expect(result).to.not.have.property("zipCodePlusFour"); }); - + it('should parse street name that ends in Chase', function() { var result = addresser.parseAddress("7114 Sunny Day, San Antonio, TX"); expect(result.streetNumber).to.equal("7114"); expect(result.streetName).to.equal("Sunny Day"); expect(result).to.not.have.property('streetSuffix') expect(result.addressLine1).to.equal("7114 Sunny Day"); - expect(result).to.not.have.property("addressLine2"); + expect(result).to.not.have.property("addressLine2"); expect(result.placeName).to.equal("San Antonio"); expect(result.stateAbbreviation).to.equal("TX"); expect(result.stateName).to.equal("Texas"); - expect(result).to.not.have.property("zipCode"); + expect(result).to.not.have.property("zipCode"); expect(result).to.not.have.property("zipCodePlusFour"); }); - + it('should parse street name that has a leading directional and is just a number', function() { var result = addresser.parseAddress("110 N 2500, Vernal, UT"); expect(result.streetNumber).to.equal("110"); expect(result.streetName).to.equal("N 2500"); expect(result).to.not.have.property('streetSuffix') expect(result.addressLine1).to.equal("110 N 2500"); - expect(result).to.not.have.property("addressLine2"); + expect(result).to.not.have.property("addressLine2"); expect(result.placeName).to.equal("Vernal"); expect(result.stateAbbreviation).to.equal("UT"); expect(result.stateName).to.equal("Utah"); - expect(result).to.not.have.property("zipCode"); + expect(result).to.not.have.property("zipCode"); expect(result).to.not.have.property("zipCodePlusFour"); }); - + it('should parse "123 Rue Dauphine style address', function() { var result = addresser.parseAddress("625 Rue Dauphine, Eunice, LA"); expect(result.streetNumber).to.equal("625"); expect(result.streetName).to.equal("Rue Dauphine"); expect(result).to.not.have.property('streetSuffix') expect(result.addressLine1).to.equal("625 Rue Dauphine"); - expect(result).to.not.have.property("addressLine2"); + expect(result).to.not.have.property("addressLine2"); expect(result.placeName).to.equal("Eunice"); expect(result.stateAbbreviation).to.equal("LA"); expect(result.stateName).to.equal("Louisiana"); - expect(result).to.not.have.property("zipCode"); + expect(result).to.not.have.property("zipCode"); expect(result).to.not.have.property("zipCodePlusFour"); }); @@ -624,11 +624,11 @@ describe('#parseAddress', function() { expect(result.streetName).to.equal("Alameda De Las Pulgas"); expect(result).to.not.have.property('streetSuffix') expect(result.addressLine1).to.equal("67A Alameda De Las Pulgas"); - expect(result).to.not.have.property("addressLine2"); + expect(result).to.not.have.property("addressLine2"); expect(result.placeName).to.equal("Redwood City"); expect(result.stateAbbreviation).to.equal("CA"); expect(result.stateName).to.equal("California"); - expect(result.zipCode).to.equal("94062"); + expect(result.zipCode).to.equal("94062"); expect(result).to.not.have.property("zipCodePlusFour"); }); @@ -638,11 +638,11 @@ describe('#parseAddress', function() { expect(result.streetName).to.equal("Pinellas Bwy S"); expect(result).to.not.have.property('streetSuffix') expect(result.addressLine1).to.equal("630A Pinellas Bwy S"); - expect(result.addressLine2).to.equal("Apt 3202"); + expect(result.addressLine2).to.equal("Apt 3202"); expect(result.placeName).to.equal("Saint Petersburg"); expect(result.stateAbbreviation).to.equal("FL"); expect(result.stateName).to.equal("Florida"); - expect(result.zipCode).to.equal("33715"); + expect(result.zipCode).to.equal("33715"); expect(result).to.not.have.property("zipCodePlusFour"); }); @@ -652,11 +652,11 @@ describe('#parseAddress', function() { expect(result.streetName).to.equal("Tupelo Sr"); expect(result).to.not.have.property('streetSuffix') expect(result.addressLine1).to.equal("24497A Tupelo Sr"); - expect(result).to.not.have.property("addressLine2"); + expect(result).to.not.have.property("addressLine2"); expect(result.placeName).to.equal("Saint Robert"); expect(result.stateAbbreviation).to.equal("MO"); expect(result.stateName).to.equal("Missouri"); - expect(result.zipCode).to.equal("65584"); + expect(result.zipCode).to.equal("65584"); expect(result).to.not.have.property("zipCodePlusFour"); }); @@ -666,11 +666,11 @@ describe('#parseAddress', function() { expect(result.streetName).to.equal("Providence Ridge"); expect(result.streetSuffix).to.equal("Turn"); expect(result.addressLine1).to.equal("1300 Providence Ridge Turn"); - expect(result).to.not.have.property("addressLine2"); + expect(result).to.not.have.property("addressLine2"); expect(result.placeName).to.equal("North Chesterfield"); expect(result.stateAbbreviation).to.equal("VA"); expect(result.stateName).to.equal("Virginia"); - expect(result.zipCode).to.equal("23236"); + expect(result.zipCode).to.equal("23236"); expect(result).to.not.have.property("zipCodePlusFour"); }); @@ -680,11 +680,11 @@ describe('#parseAddress', function() { expect(result.streetName).to.equal("Castlewood"); expect(result.streetSuffix).to.equal("Rd"); expect(result.addressLine1).to.equal("5210 Castlewood Rd"); - expect(result.addressLine2).to.equal("Apt E"); + expect(result.addressLine2).to.equal("Apt E"); expect(result.placeName).to.equal("North Chesterfield"); expect(result.stateAbbreviation).to.equal("VA"); expect(result.stateName).to.equal("Virginia"); - expect(result.zipCode).to.equal("23234"); + expect(result.zipCode).to.equal("23234"); expect(result).to.not.have.property("zipCodePlusFour"); }); @@ -694,11 +694,11 @@ describe('#parseAddress', function() { expect(result.streetName).to.equal("N Harrisburg"); expect(result.streetSuffix).to.equal("St"); expect(result.addressLine1).to.equal("186 N Harrisburg St"); - expect(result.addressLine2).to.equal("Apt 3"); + expect(result.addressLine2).to.equal("Apt 3"); expect(result.placeName).to.equal("Oberlin"); expect(result.stateAbbreviation).to.equal("PA"); expect(result.stateName).to.equal("Pennsylvania"); - expect(result.zipCode).to.equal("17113"); + expect(result.zipCode).to.equal("17113"); expect(result).to.not.have.property("zipCodePlusFour"); }); @@ -708,11 +708,11 @@ describe('#parseAddress', function() { expect(result.streetName).to.equal("Franklin"); expect(result.streetSuffix).to.equal("St"); expect(result.addressLine1).to.equal("400 Franklin St"); - expect(result.addressLine2).to.equal("Apt 205"); + expect(result.addressLine2).to.equal("Apt 205"); expect(result.placeName).to.equal("West Reading"); expect(result.stateAbbreviation).to.equal("PA"); expect(result.stateName).to.equal("Pennsylvania"); - expect(result.zipCode).to.equal("19611"); + expect(result.zipCode).to.equal("19611"); expect(result).to.not.have.property("zipCodePlusFour"); }); @@ -722,11 +722,11 @@ describe('#parseAddress', function() { expect(result.streetName).to.equal("Salem"); expect(result.streetSuffix).to.equal("St"); expect(result.addressLine1).to.equal("315 Salem St"); - expect(result.addressLine2).to.equal("Apt A"); + expect(result.addressLine2).to.equal("Apt A"); expect(result.placeName).to.equal("West Pittston"); expect(result.stateAbbreviation).to.equal("PA"); expect(result.stateName).to.equal("Pennsylvania"); - expect(result.zipCode).to.equal("18643"); + expect(result.zipCode).to.equal("18643"); expect(result).to.not.have.property("zipCodePlusFour"); }); @@ -736,11 +736,11 @@ describe('#parseAddress', function() { expect(result.streetName).to.equal("State"); expect(result.streetSuffix).to.equal("St"); expect(result.addressLine1).to.equal("485 State St"); - expect(result.addressLine2).to.equal("Apt B"); + expect(result.addressLine2).to.equal("Apt B"); expect(result.placeName).to.equal("Steelton"); expect(result.stateAbbreviation).to.equal("PA"); expect(result.stateName).to.equal("Pennsylvania"); - expect(result.zipCode).to.equal("17113"); + expect(result.zipCode).to.equal("17113"); expect(result).to.not.have.property("zipCodePlusFour"); }); @@ -750,11 +750,11 @@ describe('#parseAddress', function() { expect(result.streetName).to.equal("Bristol"); expect(result.streetSuffix).to.equal("St"); expect(result.addressLine1).to.equal("11 Bristol St"); - expect(result.addressLine2).to.equal("Apt 2"); + expect(result.addressLine2).to.equal("Apt 2"); expect(result.placeName).to.equal("East Cambridge"); expect(result.stateAbbreviation).to.equal("MA"); expect(result.stateName).to.equal("Massachusetts"); - expect(result.zipCode).to.equal("02141"); + expect(result.zipCode).to.equal("02141"); expect(result).to.not.have.property("zipCodePlusFour"); }); @@ -764,11 +764,11 @@ describe('#parseAddress', function() { expect(result.streetName).to.equal("Oakland"); expect(result.streetSuffix).to.equal("Ave"); expect(result.addressLine1).to.equal("19917 Oakland Ave"); - expect(result.addressLine2).to.equal("Unit 1"); + expect(result.addressLine2).to.equal("Unit 1"); expect(result.placeName).to.equal("South Chesterfield"); expect(result.stateAbbreviation).to.equal("VA"); expect(result.stateName).to.equal("Virginia"); - expect(result.zipCode).to.equal("23834"); + expect(result.zipCode).to.equal("23834"); expect(result).to.not.have.property("zipCodePlusFour"); }); @@ -778,30 +778,30 @@ describe('#parseAddress', function() { expect(result.streetName).to.equal("Spruce"); expect(result.streetSuffix).to.equal("St"); expect(result.addressLine1).to.equal("802 Spruce St"); - expect(result.addressLine2).to.equal("Unit A"); + expect(result.addressLine2).to.equal("Unit A"); expect(result.placeName).to.equal("East Rochester"); expect(result.stateAbbreviation).to.equal("PA"); expect(result.stateName).to.equal("Pennsylvania"); - expect(result.zipCode).to.equal("15074"); + expect(result.zipCode).to.equal("15074"); expect(result).to.not.have.property("zipCodePlusFour"); }); - - + + it('should parse a Spring Lake Park city address', function() { var result = addresser.parseAddress("8070 Central Ave NE Unit 8070-206, Spring Lake Park, MN 55432"); expect(result.streetNumber).to.equal("8070"); expect(result.streetName).to.equal("Central"); expect(result.streetSuffix).to.equal("Ave"); expect(result.addressLine1).to.equal("8070 Central Ave NE"); - expect(result.addressLine2).to.equal("Unit 8070-206"); + expect(result.addressLine2).to.equal("Unit 8070-206"); expect(result.placeName).to.equal("Spring Lake Park"); expect(result.stateAbbreviation).to.equal("MN"); expect(result.stateName).to.equal("Minnesota"); - expect(result.zipCode).to.equal("55432"); + expect(result.zipCode).to.equal("55432"); expect(result).to.not.have.property("zipCodePlusFour"); }); - - + + it('should parse street name of N Portola with unit name', function() { var result = addresser.parseAddress("47 N Portola, # 35, Laguna Beach, CA"); expect(result.streetNumber).to.equal("47"); @@ -812,10 +812,10 @@ describe('#parseAddress', function() { expect(result.placeName).to.equal("Laguna Beach"); expect(result.stateAbbreviation).to.equal("CA"); expect(result.stateName).to.equal("California"); - expect(result).to.not.have.property("zipCode"); + expect(result).to.not.have.property("zipCode"); expect(result).to.not.have.property("zipCodePlusFour"); }); - + it('should parse a street name with no suffix but the street name itself matches a suffix', function() { var result = addresser.parseAddress("1010 PINE, 9E-6-01\nST. LOUIS MO 63101"); expect(result.streetNumber).to.equal("1010"); @@ -829,7 +829,7 @@ describe('#parseAddress', function() { expect(result.zipCode).to.equal("63101"); expect(result).to.not.have.property("zipCodePlusFour"); }); - + it('should return a formattedAddress field', function() { var result = addresser.parseAddress("12939 Texas Gold, San Antonio, TX 78253"); expect(result.streetNumber).to.equal("12939"); @@ -844,7 +844,7 @@ describe('#parseAddress', function() { expect(result.zipCode).to.equal('78253'); expect(result).to.not.have.property("zipCodePlusFour"); }); - + it('should return a formattedAddress field when a second address line is provided', function() { var result = addresser.parseAddress("12939 Live Oak Street Unit 101, San Antonio, TX 78253"); expect(result.streetNumber).to.equal("12939"); @@ -859,7 +859,7 @@ describe('#parseAddress', function() { expect(result.zipCode).to.equal('78253'); expect(result).to.not.have.property("zipCodePlusFour"); }); - + it('should parse a simple Canadian Address without zip Code', function() { var result = addresser.parseAddress("123 Main St, Toronto, ON"); expect(result.streetNumber).to.equal("123"); @@ -874,7 +874,7 @@ describe('#parseAddress', function() { expect(result.hasOwnProperty("zipCode")).to.equal(false); expect(result.hasOwnProperty("zipCodePlusFour")).to.equal(false); }); - + it('should parse a simple Canadian Address with zip Code', function() { var result = addresser.parseAddress("123 Main St, Toronto, ON M3K5K9"); expect(result.streetNumber).to.equal("123"); @@ -907,7 +907,7 @@ describe('#parseAddress', function() { describe('#randomCity', function() { it('should provide a random city', function() { - for (var i = 0; i < 20; i++) { + for (var i = 0; i < 20; i++) { var result = addresser.randomCity(); expect(result.hasOwnProperty("city")).to.equal(true); expect(result['city'].length).to.be.above(1); @@ -929,3 +929,94 @@ describe('##cities', function() { expect(result['TX'].includes('ThisCityCannot143234234234234PossiblyExist')).to.be.false; }); }); + +describe('Extra canada', function() { + it('should parse a simple Canadian Address with Full word Street Direction', function() { + var result = addresser.parseAddress('310 8 Street North, Calgary, Alberta T2P 3P3, Canada'); + expect(result.streetNumber).to.equal("310"); + expect(result.streetName).to.equal("8"); + expect(result.streetSuffix).to.equal("St"); + expect(result.streetDirection).to.equal("N"); + expect(result.addressLine1).to.equal("310 8 St N"); + expect(result.hasOwnProperty("addressLine2")).to.equal(false); + expect(result.placeName).to.equal("Calgary"); + expect(result.stateAbbreviation).to.equal("AB"); + expect(result.stateName).to.equal("Alberta"); + expect(result.zipCode).to.equal("T2P 3P3"); + expect(result.hasOwnProperty("zipCodePlusFour")).to.equal(false); + }); + + it('should parse a simple Canadian Address with 2-letter Street Direction', function() { + var result = addresser.parseAddress('310 8 Street SW, Calgary, Alberta T2P 3P3, Canada'); + expect(result.streetNumber).to.equal("310"); + expect(result.streetName).to.equal("8"); + expect(result.streetSuffix).to.equal("St"); + expect(result.streetDirection).to.equal("SW"); + expect(result.addressLine1).to.equal("310 8 St SW"); + expect(result.hasOwnProperty("addressLine2")).to.equal(false); + expect(result.placeName).to.equal("Calgary"); + expect(result.stateAbbreviation).to.equal("AB"); + expect(result.stateName).to.equal("Alberta"); + expect(result.zipCode).to.equal("T2P 3P3"); + expect(result.hasOwnProperty("zipCodePlusFour")).to.equal(false); + }); + + it('should parse a simple Canadian Address with 1-letter Street Direction', function() { + var result = addresser.parseAddress('310 8 Street N, Calgary, Alberta T2P 3P3, Canada'); + expect(result.streetNumber).to.equal("310"); + expect(result.streetName).to.equal("8"); + expect(result.streetSuffix).to.equal("St"); + expect(result.streetDirection).to.equal("N"); + expect(result.addressLine1).to.equal("310 8 St N"); + expect(result.hasOwnProperty("addressLine2")).to.equal(false); + expect(result.placeName).to.equal("Calgary"); + expect(result.stateAbbreviation).to.equal("AB"); + expect(result.stateName).to.equal("Alberta"); + expect(result.zipCode).to.equal("T2P 3P3"); + expect(result.hasOwnProperty("zipCodePlusFour")).to.equal(false); + }); + + it('should parse a simple Canadian Address with Full word Street Direction', function() { + var result = addresser.parseAddress('310 8 Street North, Calgary, Alberta T2P 3P3, Canada'); + expect(result.streetNumber).to.equal("310"); + expect(result.streetName).to.equal("8"); + expect(result.streetSuffix).to.equal("St"); + expect(result.streetDirection).to.equal("N"); + expect(result.addressLine1).to.equal("310 8 St N"); + expect(result.hasOwnProperty("addressLine2")).to.equal(false); + expect(result.placeName).to.equal("Calgary"); + expect(result.stateAbbreviation).to.equal("AB"); + expect(result.stateName).to.equal("Alberta"); + expect(result.zipCode).to.equal("T2P 3P3"); + expect(result.hasOwnProperty("zipCodePlusFour")).to.equal(false); + }); + + it('should parse a simple Canadian Address with Full word Street Direction', function() { + var result = addresser.parseAddress('310 8 Street Southwest, Calgary, Alberta T2P 3P3, Canada'); + expect(result.streetNumber).to.equal("310"); + expect(result.streetName).to.equal("8"); + expect(result.streetSuffix).to.equal("St"); + expect(result.streetDirection).to.equal("SW"); + expect(result.addressLine1).to.equal("310 8 St SW"); + expect(result.hasOwnProperty("addressLine2")).to.equal(false); + expect(result.placeName).to.equal("Calgary"); + expect(result.stateAbbreviation).to.equal("AB"); + expect(result.stateName).to.equal("Alberta"); + expect(result.zipCode).to.equal("T2P 3P3"); + expect(result.hasOwnProperty("zipCodePlusFour")).to.equal(false); + }); + + it('should parse a simple Canadian Address with Full word Street Direction without ZipCode', function() { + var result = addresser.parseAddress('310 8 Street Southwest, Calgary, Alberta, Canada'); + expect(result.streetNumber).to.equal("310"); + expect(result.streetName).to.equal("8"); + expect(result.streetSuffix).to.equal("St"); + expect(result.streetDirection).to.equal("SW"); + expect(result.addressLine1).to.equal("310 8 St SW"); + expect(result.hasOwnProperty("addressLine2")).to.equal(false); + expect(result.placeName).to.equal("Calgary"); + expect(result.stateAbbreviation).to.equal("AB"); + expect(result.stateName).to.equal("Alberta"); + expect(result.hasOwnProperty("zipCodePlusFour")).to.equal(false); + }); +}); From 288e28791d424ab0e786ed6000172a4d8b10adf8 Mon Sep 17 00:00:00 2001 From: "K. Sokolinskyi" Date: Mon, 2 Jun 2025 17:51:56 -0400 Subject: [PATCH 02/13] test: add test for CA street types --- test/test.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/test/test.js b/test/test.js index e578472..76f9b0e 100644 --- a/test/test.js +++ b/test/test.js @@ -1019,4 +1019,19 @@ describe('Extra canada', function() { expect(result.stateName).to.equal("Alberta"); expect(result.hasOwnProperty("zipCodePlusFour")).to.equal(false); }); + + it('should parse a simple Canadian Address with Canadian street type', function() { + var result = addresser.parseAddress('310 Main Private, Calgary, Alberta T2P 3P3, Canada'); + expect(result.streetNumber).to.equal("310"); + expect(result.streetName).to.equal("Main"); + expect(result.streetSuffix).to.equal("Private"); + expect(result.streetDirection).to.equal(undefined); + expect(result.addressLine1).to.equal("310 Main Private"); + expect(result.hasOwnProperty("addressLine2")).to.equal(false); + expect(result.placeName).to.equal("Calgary"); + expect(result.stateAbbreviation).to.equal("AB"); + expect(result.stateName).to.equal("Alberta"); + expect(result.zipCode).to.equal("T2P 3P3"); + expect(result.hasOwnProperty("zipCodePlusFour")).to.equal(false); + }); }); From b08b3eca1ba84478ed9f7b117ed9ceeec0c8ca06 Mon Sep 17 00:00:00 2001 From: Dmytro Yashyn Date: Fri, 15 Aug 2025 17:15:57 +0200 Subject: [PATCH 03/13] Fixes Southeast correctly + adds support for Canadian "dr" street type (#2) * assure Southeast parsed correctly * formatting changes --------- Co-authored-by: K. Sokolinskyi --- .vscode/settings.json | 4 + data/ca-street-types.json | 237 +++++++++++++++++++------------------- index.js | 2 +- test/test.js | 25 ++++ 4 files changed, 149 insertions(+), 119 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 933440f..08f8d5a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -4,6 +4,10 @@ "[yaml]": { "editor.formatOnSave": false }, + "[json]": { + "editor.formatOnSave": false, + "editor.tabSize": 4 + }, "editor.tabSize": 4, "editor.insertSpaces": true, "files.trimTrailingWhitespace": true diff --git a/data/ca-street-types.json b/data/ca-street-types.json index d91f686..4f2114d 100644 --- a/data/ca-street-types.json +++ b/data/ca-street-types.json @@ -1,120 +1,121 @@ { - "acres": "acres", - "alley": "alley", - "avenue": "avenue", - "bay": "bay", - "beach": "beach", - "bend": "bend", - "boulevard": "boulevard", - "by-pass": "by-pass", - "byway": "byway", - "campus": "campus", - "cape": "cape", - "centre": "centre", - "chase": "chase", - "circle": "circle", - "circuit": "circuit", - "close": "close", - "common": "common", - "concession": "concession", - "corners": "corners", - "court": "court", - "cove": "cove", - "crescent": "crescent", - "crossing": "crossing", - "cul-de-sac": "cul-de-sac", - "dale": "dale", - "dell": "dell", - "diversion": "diversion", - "downs": "downs", - "drive": "drive", - "end": "end", - "esplanade": "esplanade", - "estates": "estates", - "expressway": "expressway", - "extension": "extension", - "farm": "farm", - "field": "field", - "forest": "forest", - "freeway": "freeway", - "front": "front", - "gardens": "gardens", - "gate": "gate", - "glade": "glade", - "glen": "glen", - "green": "green", - "grounds": "grounds", - "grove": "grove", - "harbour": "harbour", - "heath": "heath", - "heights": "heights", - "highlands": "highlands", - "highway": "highway", - "hill": "hill", - "hollow": "hollow", - "inlet": "inlet", - "island": "island", - "key": "key", - "knoll": "knoll", - "landing": "landing", - "lane": "lane", - "limits": "limits", - "line": "line", - "link": "link", - "lookout": "lookout", - "loop": "loop", - "mall": "mall", - "manor": "manor", - "maze": "maze", - "meadow": "meadow", - "mews": "mews", - "moor": "moor", - "mount": "mount", - "mountain": "mountain", - "orchard": "orchard", - "parade": "parade", - "park": "park", - "parkway": "parkway", - "passage": "passage", - "path": "path", - "pathway": "pathway", - "pines": "pines", - "place": "place", - "plateau": "plateau", - "plaza": "plaza", - "point": "point", - "port": "port", - "private": "private", - "promenade": "promenade", - "quay": "quay", - "ramp": "ramp", - "range": "range", - "ridge": "ridge", - "rise": "rise", - "road": "road", - "route": "route", - "row": "row", - "run": "run", - "square": "square", - "street": "st", - "subdivision": "subdivision", - "terrace": "terrace", - "thicket": "thicket", - "towers": "towers", - "townline": "townline", - "trail": "trail", - "turnabout": "turnabout", - "vale": "vale", - "via": "via", - "view": "view", - "village": "village", - "villas": "villas", - "vista": "vista", - "walk": "walk", - "way": "way", - "wharf": "wharf", - "wood": "wood", - "wynd": "wynd", - "abbey": "abbey", - "st": "st" + "acres": "acres", + "alley": "alley", + "avenue": "avenue", + "bay": "bay", + "beach": "beach", + "bend": "bend", + "boulevard": "boulevard", + "by-pass": "by-pass", + "byway": "byway", + "campus": "campus", + "cape": "cape", + "centre": "centre", + "chase": "chase", + "circle": "circle", + "circuit": "circuit", + "close": "close", + "common": "common", + "concession": "concession", + "corners": "corners", + "court": "court", + "cove": "cove", + "crescent": "crescent", + "crossing": "crossing", + "cul-de-sac": "cul-de-sac", + "dale": "dale", + "dell": "dell", + "diversion": "diversion", + "downs": "downs", + "drive": "drive", + "dr": "drive", + "end": "end", + "esplanade": "esplanade", + "estates": "estates", + "expressway": "expressway", + "extension": "extension", + "farm": "farm", + "field": "field", + "forest": "forest", + "freeway": "freeway", + "front": "front", + "gardens": "gardens", + "gate": "gate", + "glade": "glade", + "glen": "glen", + "green": "green", + "grounds": "grounds", + "grove": "grove", + "harbour": "harbour", + "heath": "heath", + "heights": "heights", + "highlands": "highlands", + "highway": "highway", + "hill": "hill", + "hollow": "hollow", + "inlet": "inlet", + "island": "island", + "key": "key", + "knoll": "knoll", + "landing": "landing", + "lane": "lane", + "limits": "limits", + "line": "line", + "link": "link", + "lookout": "lookout", + "loop": "loop", + "mall": "mall", + "manor": "manor", + "maze": "maze", + "meadow": "meadow", + "mews": "mews", + "moor": "moor", + "mount": "mount", + "mountain": "mountain", + "orchard": "orchard", + "parade": "parade", + "park": "park", + "parkway": "parkway", + "passage": "passage", + "path": "path", + "pathway": "pathway", + "pines": "pines", + "place": "place", + "plateau": "plateau", + "plaza": "plaza", + "point": "point", + "port": "port", + "private": "private", + "promenade": "promenade", + "quay": "quay", + "ramp": "ramp", + "range": "range", + "ridge": "ridge", + "rise": "rise", + "road": "road", + "route": "route", + "row": "row", + "run": "run", + "square": "square", + "street": "st", + "subdivision": "subdivision", + "terrace": "terrace", + "thicket": "thicket", + "towers": "towers", + "townline": "townline", + "trail": "trail", + "turnabout": "turnabout", + "vale": "vale", + "via": "via", + "view": "view", + "village": "village", + "villas": "villas", + "vista": "vista", + "walk": "walk", + "way": "way", + "wharf": "wharf", + "wood": "wood", + "wynd": "wynd", + "abbey": "abbey", + "st": "st" } diff --git a/index.js b/index.js index 93ebc10..22351f7 100644 --- a/index.js +++ b/index.js @@ -61,7 +61,7 @@ var caStreetDirectional = { "North East": "NE", "SE": "SE", - "SouthEast": "SE", + "Southeast": "SE", "South East": "SE", "NW": "NW", diff --git a/test/test.js b/test/test.js index 76f9b0e..e740aa6 100644 --- a/test/test.js +++ b/test/test.js @@ -1034,4 +1034,29 @@ describe('Extra canada', function() { expect(result.zipCode).to.equal("T2P 3P3"); expect(result.hasOwnProperty("zipCodePlusFour")).to.equal(false); }); + + it('should parse a simple Canadian Address with southeast street direction', function() { + var result = addresser.parseAddress('508 7 Avenue Southeast, Calgary, AB, Canada'); + expect(result.streetNumber).to.equal("508"); + expect(result.streetName).to.equal("7"); + expect(result.streetSuffix).to.equal("Avenue"); + expect(result.streetDirection).to.equal('SE'); + expect(result.addressLine1).to.equal("508 7 Avenue SE"); + expect(result.hasOwnProperty("addressLine2")).to.equal(false); + expect(result.placeName).to.equal("Calgary"); + expect(result.stateAbbreviation).to.equal("AB"); + }); + + // TODO: Fix code so streetDirection would be matched without case sensitivity + // it('should parse a simple Canadian Address with any-case southeast street direction', function() { + // var result = addresser.parseAddress('508 Queens dr SouthEast, Calgary, AB, Canada'); + // expect(result.streetNumber).to.equal("508"); + // expect(result.streetName).to.equal("Queens"); + // expect(result.streetSuffix).to.equal("Drive"); + // expect(result.streetDirection).to.equal('SE'); + // expect(result.addressLine1).to.equal("508 Queens Drive SE"); + // expect(result.hasOwnProperty("addressLine2")).to.equal(false); + // expect(result.placeName).to.equal("Calgary"); + // expect(result.stateAbbreviation).to.equal("AB"); + // }); }); From 0fed081b67c2fbba7a2a7e801692d693fb97cf5f Mon Sep 17 00:00:00 2001 From: "K. Sokolinskyi" Date: Mon, 18 Aug 2025 15:48:24 -0400 Subject: [PATCH 04/13] chore: extend CA street types --- data/ca-street-types.json | 68 +++++++++++++++++++++++++++++++++++++-- test/test.js | 26 +++++++++++++++ 2 files changed, 91 insertions(+), 3 deletions(-) diff --git a/data/ca-street-types.json b/data/ca-street-types.json index 4f2114d..277bde2 100644 --- a/data/ca-street-types.json +++ b/data/ca-street-types.json @@ -1,56 +1,87 @@ { + "abbey": "abbey", "acres": "acres", "alley": "alley", + "autoroute": "autoroute", + "aut": "autoroute", + "ave": "avenue", "avenue": "avenue", "bay": "bay", "beach": "beach", "bend": "bend", + "blvd": "boulevard", "boulevard": "boulevard", "by-pass": "by-pass", + "bypass": "by-pass", "byway": "byway", "campus": "campus", "cape": "cape", "centre": "centre", + "ctr": "centre", "chase": "chase", + "chemin": "chemin", + "ch": "chemin", "circle": "circle", + "cir": "circle", "circuit": "circuit", + "circt": "circuit", "close": "close", "common": "common", "concession": "concession", + "conc": "concession", "corners": "corners", + "crnrs": "corners", "court": "court", + "crt": "court", + "ct": "court", "cove": "cove", "crescent": "crescent", + "cres": "crescent", + "cr": "crescent", "crossing": "crossing", + "cross": "crossing", "cul-de-sac": "cul-de-sac", + "cds": "cul-de-sac", "dale": "dale", "dell": "dell", "diversion": "diversion", + "divers": "diversion", "downs": "downs", "drive": "drive", "dr": "drive", "end": "end", "esplanade": "esplanade", + "espl": "esplanade", "estates": "estates", + "estate": "estates", "expressway": "expressway", + "expy": "expressway", "extension": "extension", + "exten": "extension", "farm": "farm", "field": "field", "forest": "forest", "freeway": "freeway", + "fwy": "freeway", "front": "front", "gardens": "gardens", + "gdns": "gardens", "gate": "gate", "glade": "glade", "glen": "glen", "green": "green", "grounds": "grounds", + "grnds": "grounds", "grove": "grove", "harbour": "harbour", + "harbr": "harbour", "heath": "heath", "heights": "heights", + "hts": "heights", "highlands": "highlands", + "hghlds": "highlands", "highway": "highway", + "hwy": "highway", "hill": "hill", "hollow": "hollow", "inlet": "inlet", @@ -58,11 +89,15 @@ "key": "key", "knoll": "knoll", "landing": "landing", + "landng": "landing", "lane": "lane", + "ln": "lane", "limits": "limits", + "lmts": "limits", "line": "line", "link": "link", "lookout": "lookout", + "lkout": "lookout", "loop": "loop", "mall": "mall", "manor": "manor", @@ -70,52 +105,79 @@ "meadow": "meadow", "mews": "mews", "moor": "moor", + "montee": "montee", "mount": "mount", "mountain": "mountain", + "mtn": "mountain", "orchard": "orchard", + "orch": "orchard", "parade": "parade", "park": "park", + "pk": "park", "parkway": "parkway", + "pky": "parkway", "passage": "passage", + "pass": "passage", "path": "path", "pathway": "pathway", + "ptway": "pathway", "pines": "pines", "place": "place", + "pl": "place", "plateau": "plateau", + "plat": "plateau", "plaza": "plaza", "point": "point", + "pt": "point", "port": "port", "private": "private", + "pvt": "private", "promenade": "promenade", + "prom": "promenade", "quay": "quay", "ramp": "ramp", "range": "range", + "rg": "range", + "rang": "rang", "ridge": "ridge", "rise": "rise", "road": "road", + "rd": "road", "route": "route", + "rte": "route", "row": "row", + "rue": "rue", "run": "run", "square": "square", + "sq": "square", + "st": "st", "street": "st", "subdivision": "subdivision", + "subdiv": "subdivision", + "sideroad": "sideroad", + "sdrd": "sideroad", "terrace": "terrace", + "terr": "terrace", + "ter": "terrace", "thicket": "thicket", + "thick": "thicket", "towers": "towers", "townline": "townline", + "tline": "townline", "trail": "trail", + "trl": "trail", "turnabout": "turnabout", + "trnabt": "turnabout", "vale": "vale", "via": "via", "view": "view", "village": "village", + "villge": "village", "villas": "villas", "vista": "vista", "walk": "walk", "way": "way", "wharf": "wharf", "wood": "wood", - "wynd": "wynd", - "abbey": "abbey", - "st": "st" + "wynd": "wynd" } diff --git a/test/test.js b/test/test.js index e740aa6..3e634b9 100644 --- a/test/test.js +++ b/test/test.js @@ -1059,4 +1059,30 @@ describe('Extra canada', function() { // expect(result.placeName).to.equal("Calgary"); // expect(result.stateAbbreviation).to.equal("AB"); // }); + + it('should parse a simple Canadian Address with Ln and SW street direction', function() { + var result = addresser.parseAddress('15 Signal Hill Ln SW, Calgary, AB, Canada'); + expect(result.streetNumber).to.equal("15"); + expect(result.streetName).to.equal("Signal Hill"); + expect(result.streetSuffix).to.equal("Lane"); + expect(result.streetDirection).to.equal('SW'); + expect(result.addressLine1).to.equal("15 Signal Hill Lane SW"); + expect(result.hasOwnProperty("addressLine2")).to.equal(false); + expect(result.placeName).to.equal("Calgary"); + expect(result.stateAbbreviation).to.equal("AB"); + }); + + it('should parse a simple Canadian Address with Pvt and SW street direction', function() { + var result = addresser.parseAddress('15 Signal Hill Pvt SW, Calgary, AB, Canada'); + expect(result.streetNumber).to.equal("15"); + expect(result.streetName).to.equal("Signal Hill"); + expect(result.streetSuffix).to.equal("Private"); + expect(result.streetDirection).to.equal('SW'); + expect(result.addressLine1).to.equal("15 Signal Hill Private SW"); + expect(result.hasOwnProperty("addressLine2")).to.equal(false); + expect(result.placeName).to.equal("Calgary"); + expect(result.stateAbbreviation).to.equal("AB"); + }); + + }); From 9c174997a9aaaa5bd488c6c7d49093bc624beffe Mon Sep 17 00:00:00 2001 From: Dmytro Chyrkin Date: Fri, 29 Aug 2025 21:34:28 +0300 Subject: [PATCH 05/13] feat: make street direction case insensitive for long wording (#3) * feat: make street direction case insensitive for long wording * test: add failing tests * fix: fixed test * chore: fix styling, add editorconfig --------- Co-authored-by: K. Sokolinskyi --- .editorconfig | 8 ++ index.js | 389 ++++++++++++++++++++++++++------------------------ test/test.js | 59 ++++++-- 3 files changed, 256 insertions(+), 200 deletions(-) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..3274ec3 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,8 @@ +root = true + +[*] +indent_style = space +indent_size = 2 +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true \ No newline at end of file diff --git a/index.js b/index.js index 22351f7..52b6ff1 100644 --- a/index.js +++ b/index.js @@ -2,17 +2,15 @@ const allStates = require('./data/states.json'); const usStreetTypes = require('./data/us-street-types.json'); const caStreetTypes = require('./data/ca-street-types.json'); const allCities = require('./data/cities.json'); -const usStates = require('./data/us-states.json'); const usCities = require('./data/us-cities.json'); - 'use strict'; /** - * Parses a street address - * @param {string} address - * @return {string} - **/ +* Parses a street address +* @param {string} address +* @return {string} +**/ //TODO move this to utils file function getKeyByValue(object, value) { @@ -20,9 +18,9 @@ function getKeyByValue(object, value) { } function toTitleCase(str) { - return str.replace(/\w\S*/g, function(txt){ - return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase(); - }); + return str.replace(/\w\S*/g, function(txt){ + return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase(); + }); } //returns a random property of a given object @@ -32,88 +30,89 @@ function randomProperty (obj) { }; var usStreetDirectional = { - "N": "N", - "NE": "NE", - "E": "E", - "SE": "SE", - "S": "S", - "SW": "SW", - "W": "W", - "NW": "NW" + "N": "N", + "NE": "NE", + "E": "E", + "SE": "SE", + "S": "S", + "SW": "SW", + "W": "W", + "NW": "NW" }; var caStreetDirectional = { + "N": "N", + "North": "N", - "N": "N", - "North": "N", - - "E": "E", - "East": "E", + "E": "E", + "East": "E", - "S": "S", - "South": "S", + "S": "S", + "South": "S", - "W": "W", - "West": "W", + "W": "W", + "West": "W", - "NE": "NE", - "Northeast": "NE", - "North East": "NE", + "NE": "NE", + "Northeast": "NE", + "North East": "NE", - "SE": "SE", - "Southeast": "SE", - "South East": "SE", + "SE": "SE", + "Southeast": "SE", + "South East": "SE", - "NW": "NW", - "North West": "NW", - "Northwest": "NW", + "NW": "NW", + "North West": "NW", + "Northwest": "NW", - "SW": "SW", - "Southwest" : "SW", - "South West": "SW" + "SW": "SW", + "Southwest" : "SW", + "South West": "SW" }; +const caStreetSpaceDirectional = {'North East': 'Northeast', 'North West': 'NorthWest', 'South East': 'SouthEast' , 'South West': 'SouthWest'}; + var usLine2Prefixes = { - 'APARTMENT' : 'APT', - 'APT' : 'APT', - 'BASEMENT' : 'BSMT', - 'BSMT' : 'BSMT', - 'BLDG' : 'BLDG', - 'BUILDING' : 'BLDG', - 'DEPARTMENT' : 'DEPT', - 'DEPT' : 'DEPT', - 'FL' : 'FL', - 'FLOOR' : 'FL', - 'FRNT' : 'FRNT', - 'FRONT' : 'FRNT', - 'HANGAR' : 'HNGR', - 'HNGR' : 'HNGR', - 'LBBY' : 'LBBY', - 'LOBBY' : 'LBBY', - 'LOT' : 'LOT', - 'LOWER' : 'LOWR', - 'LOWR' : 'LOWER', - 'OFC' : 'OFC', - 'OFFICE' : 'OFC', - 'PENTHOUSE' : 'PH', - 'PH' : 'PH', - 'PIER' : 'PIER', - 'REAR' : 'REAR', - 'RM' : 'RM', - 'ROOM' : 'RM', - 'SIDE' : 'SIDE', - 'SLIP' : 'SLIP', - 'SPACE' : 'SPC', - 'SPC' : 'SPC', - 'STE' : 'STE', - 'STOP' : 'STOP', - 'SUITE' : 'STE', - 'TRAILER' : 'TRLR', - 'TRLR' : 'TRLR', - 'UNIT' : 'UNIT', - 'UPPER' : 'UPPR', - 'UPPR' : 'UPPR', - '#' : '#', + 'APARTMENT' : 'APT', + 'APT' : 'APT', + 'BASEMENT' : 'BSMT', + 'BSMT' : 'BSMT', + 'BLDG' : 'BLDG', + 'BUILDING' : 'BLDG', + 'DEPARTMENT' : 'DEPT', + 'DEPT' : 'DEPT', + 'FL' : 'FL', + 'FLOOR' : 'FL', + 'FRNT' : 'FRNT', + 'FRONT' : 'FRNT', + 'HANGAR' : 'HNGR', + 'HNGR' : 'HNGR', + 'LBBY' : 'LBBY', + 'LOBBY' : 'LBBY', + 'LOT' : 'LOT', + 'LOWER' : 'LOWR', + 'LOWR' : 'LOWER', + 'OFC' : 'OFC', + 'OFFICE' : 'OFC', + 'PENTHOUSE' : 'PH', + 'PH' : 'PH', + 'PIER' : 'PIER', + 'REAR' : 'REAR', + 'RM' : 'RM', + 'ROOM' : 'RM', + 'SIDE' : 'SIDE', + 'SLIP' : 'SLIP', + 'SPACE' : 'SPC', + 'SPC' : 'SPC', + 'STE' : 'STE', + 'STOP' : 'STOP', + 'SUITE' : 'STE', + 'TRAILER' : 'TRLR', + 'TRLR' : 'TRLR', + 'UNIT' : 'UNIT', + 'UPPER' : 'UPPR', + 'UPPR' : 'UPPR', + '#' : '#', } module.exports = { @@ -137,8 +136,8 @@ module.exports = { addressParts.splice(-1,1); if (countrySection === 'Canada') { - streetTypes = caStreetTypes; - streetDirectional = caStreetDirectional; + streetTypes = caStreetTypes; + streetDirectional = caStreetDirectional; } } @@ -213,7 +212,7 @@ module.exports = { // Parse the street data var streetString = ""; - var usStreetDirectionalString = Object.keys(streetDirectional).join('|'); + var streetDirectionalString = Object.keys(streetDirectional).join('|'); var usLine2String = Object.keys(usLine2Prefixes).join('|'); if (placeString.length > 0) { // Check if anything is left of last section @@ -246,134 +245,148 @@ module.exports = { streetString = streetString.replace(re,"").trim(); // Carve off the line 2 data } } + + // For street directions with spaces replace with the direction with no spaces + const caStreetSpaceDirectionalKeys = Object.keys(caStreetSpaceDirectional); + const spaceDirections = new RegExp('(' + Object.keys(caStreetSpaceDirectionalKeys).join('|') + ')', 'i'); + if (streetString.match(spaceDirections)) { + caStreetSpaceDirectionalKeys.forEach(d => { + streetString = streetString.replace(new RegExp(`(${d})`, 'i'), caStreetSpaceDirectional[d]); + }); + } + //Assume street address comes first and the rest is secondary address var reStreet = new RegExp('\.\*\\b(?:' + Object.keys(streetTypes).join('|') + ')\\b\\.?' + - '( +(?:' + usStreetDirectionalString + ')\\b)?', 'i'); - - var rePO = new RegExp('(P\\.?O\\.?|POST\\s+OFFICE)\\s+(BOX|DRAWER)\\s\\w+', 'i'); - var reAveLetter = new RegExp('\.\*\\b(ave.?|avenue)\.\*\\b[a-zA-Z]\\b', 'i'); - var reNoSuffix = new RegExp('\\b\\d+[a-z]?\\s[a-zA-Z0-9_ ]+\\b', 'i'); - if (streetString.match(reAveLetter)) { - result.addressLine1 = streetString.match(reAveLetter)[0]; - streetString = streetString.replace(reAveLetter,"").trim(); // Carve off the first address line - if (streetString && streetString.length > 0) { - // Check if line2 data was already parsed - if (result.hasOwnProperty('addressLine2') && result.addressLine2.length > 0) { - throw 'Can not parse address. Too many address lines. Input string: ' + address; - } else { - result.addressLine2 = streetString; + '( +(?:' + streetDirectionalString + ')\\b)?', 'i'); + + var rePO = new RegExp('(P\\.?O\\.?|POST\\s+OFFICE)\\s+(BOX|DRAWER)\\s\\w+', 'i'); + var reAveLetter = new RegExp('\.\*\\b(ave.?|avenue)\.\*\\b[a-zA-Z]\\b', 'i'); + var reNoSuffix = new RegExp('\\b\\d+[a-z]?\\s[a-zA-Z0-9_ ]+\\b', 'i'); + if (streetString.match(reAveLetter)) { + result.addressLine1 = streetString.match(reAveLetter)[0]; + streetString = streetString.replace(reAveLetter,"").trim(); // Carve off the first address line + if (streetString && streetString.length > 0) { + // Check if line2 data was already parsed + if (result.hasOwnProperty('addressLine2') && result.addressLine2.length > 0) { + throw 'Can not parse address. Too many address lines. Input string: ' + address; + } else { + result.addressLine2 = streetString; + } } - } - var streetParts = result.addressLine1.split(' '); + var streetParts = result.addressLine1.split(' '); - // Assume type is last and number is first - result.streetNumber = streetParts[0]; // Assume number is first element + // Assume type is last and number is first + result.streetNumber = streetParts[0]; // Assume number is first element - // Normalize to Ave - streetParts[streetParts.length-2] = streetParts[streetParts.length-2].replace(/^(ave.?|avenue)$/i, 'Ave'); + // Normalize to Ave + streetParts[streetParts.length-2] = streetParts[streetParts.length-2].replace(/^(ave.?|avenue)$/i, 'Ave'); - //result.streetSuffix = toTitleCase(usStreetTypes[streetParts[streetParts.length-1].toLowerCase()]); - result.streetName = streetParts[1]; // Assume street name is everything in the middle - for (var i = 2; i <= streetParts.length-1; i++) { - result.streetName = result.streetName + " " + streetParts[i]; - } - result.streetName = toTitleCase(result.streetName); - result.addressLine1 = [result.streetNumber, result.streetName].join(" "); - } else if (streetString.match(reStreet)) { - result.addressLine1 = streetString.match(reStreet)[0]; - streetString = streetString.replace(reStreet,"").trim(); // Carve off the first address line - if (streetString && streetString.length > 0) { - // Check if line2 data was already parsed - if (result.hasOwnProperty('addressLine2') && result.addressLine2.length > 0) { - throw 'Can not parse address. Too many address lines. Input string: ' + address; - } else { - result.addressLine2 = streetString; + //result.streetSuffix = toTitleCase(usStreetTypes[streetParts[streetParts.length-1].toLowerCase()]); + result.streetName = streetParts[1]; // Assume street name is everything in the middle + for (var i = 2; i <= streetParts.length-1; i++) { + result.streetName = result.streetName + " " + streetParts[i]; } - } - var streetParts = result.addressLine1.split(' '); + result.streetName = toTitleCase(result.streetName); + result.addressLine1 = [result.streetNumber, result.streetName].join(" "); + } else if (streetString.match(reStreet)) { + result.addressLine1 = streetString.match(reStreet)[0]; + streetString = streetString.replace(reStreet,"").trim(); // Carve off the first address line + if (streetString && streetString.length > 0) { + // Check if line2 data was already parsed + if (result.hasOwnProperty('addressLine2') && result.addressLine2.length > 0) { + throw 'Can not parse address. Too many address lines. Input string: ' + address; + } else { + result.addressLine2 = streetString; + } + } + var streetParts = result.addressLine1.split(' '); + // Check if directional is last element + var re = new RegExp('\.\*\\b(?:' + streetDirectionalString + ')$', 'i'); - // Check if directional is last element - var re = new RegExp('\.\*\\b(?:' + usStreetDirectionalString + ')$', 'i'); + if (result.addressLine1.match(re)) { + const direction = streetParts.pop().split(""); - if (result.addressLine1.match(re)) { - const direction = streetParts.pop().split(""); - const [f, ...rest] = direction; - result.streetDirection = streetDirectional[f.toUpperCase() + rest.join("")]; - } + const [f, ...rest] = direction; + // rest.length > 2 is to handle long full street directions, if it's just abbreviation like NW, SW, etc, we don't change letter case. + // But if it's full direction like Northwest, then we do. + result.streetDirection = streetDirectional[f.toUpperCase() + (rest.length > 2 ? rest.join("").toLowerCase() : rest.join(""))]; + } - // Assume type is last and number is first - result.streetNumber = streetParts[0]; // Assume number is first element + // Assume type is last and number is first + result.streetNumber = streetParts[0]; // Assume number is first element - // If there are only 2 street parts (number and name) then its likely missing a "real" suffix and the street name just happened to match a suffix - if (streetParts.length > 2) { - // Remove '.' if it follows streetSuffix - streetParts[streetParts.length-1] = streetParts[streetParts.length-1].replace(/\.$/, ''); - result.streetSuffix = toTitleCase(streetTypes[streetParts[streetParts.length-1].toLowerCase()]); - } + // If there are only 2 street parts (number and name) then its likely missing a "real" suffix and the street name just happened to match a suffix + if (streetParts.length > 2) { + // Remove '.' if it follows streetSuffix + streetParts[streetParts.length-1] = streetParts[streetParts.length-1].replace(/\.$/, ''); + result.streetSuffix = toTitleCase(streetTypes[streetParts[streetParts.length-1].toLowerCase()]); + } - result.streetName = streetParts[1]; // Assume street name is everything in the middle - for (var i = 2; i < streetParts.length-1; i++) { - result.streetName = result.streetName + " " + streetParts[i]; - } - result.streetName = toTitleCase(result.streetName); - result.addressLine1 = [result.streetNumber, result.streetName].join(" "); + result.streetName = streetParts[1]; // Assume street name is everything in the middle + for (var i = 2; i < streetParts.length-1; i++) { + result.streetName = result.streetName + " " + streetParts[i]; + } + result.streetName = toTitleCase(result.streetName); + result.addressLine1 = [result.streetNumber, result.streetName].join(" "); - if (result.hasOwnProperty('streetSuffix')) { - result.addressLine1 = result.addressLine1 + ' ' + result.streetSuffix; - } - if (result.streetDirection) { - result.addressLine1 = result.addressLine1 + ' ' + result.streetDirection; - } - } else if (streetString.match(rePO)) { - result.addressLine1 = streetString.match(rePO)[0]; - streetString = streetString.replace(rePO,"").trim(); // Carve off the first address line - } else if (streetString.match(reNoSuffix)) { - // Check for a line2 prefix followed by a single word. If found peel that off as addressLine2 - var reLine2 = new RegExp('\\s(' + usLine2String + ')\\.?\\s[a-zA-Z0-9_\-]+$','i'); - if (streetString.match(reLine2)) { - result.addressLine2 = streetString.match(reLine2)[0].trim(); - streetString = streetString.replace(reLine2,"").trim(); // Carve off the first address line - } + if (result.hasOwnProperty('streetSuffix')) { + result.addressLine1 = result.addressLine1 + ' ' + result.streetSuffix; + } + if (result.streetDirection) { + result.addressLine1 = result.addressLine1 + ' ' + result.streetDirection; + } + } else if (streetString.match(rePO)) { + result.addressLine1 = streetString.match(rePO)[0]; + streetString = streetString.replace(rePO,"").trim(); // Carve off the first address line + } else if (streetString.match(reNoSuffix)) { + // Check for a line2 prefix followed by a single word. If found peel that off as addressLine2 + var reLine2 = new RegExp('\\s(' + usLine2String + ')\\.?\\s[a-zA-Z0-9_\-]+$','i'); + if (streetString.match(reLine2)) { + result.addressLine2 = streetString.match(reLine2)[0].trim(); + streetString = streetString.replace(reLine2,"").trim(); // Carve off the first address line + } - result.addressLine1 = streetString.match(reNoSuffix)[0]; - streetString = streetString.replace(reNoSuffix,"").trim(); // Carve off the first address line - var streetParts = result.addressLine1.split(' '); + result.addressLine1 = streetString.match(reNoSuffix)[0]; + streetString = streetString.replace(reNoSuffix,"").trim(); // Carve off the first address line + var streetParts = result.addressLine1.split(' '); - // Assume type is last and number is first - result.streetNumber = streetParts[0]; // Assume number is first element - streetParts.shift(); // Remove the first element - result.streetName = streetParts.join(' '); // Assume street name is everything else + // Assume type is last and number is first + result.streetNumber = streetParts[0]; // Assume number is first element + streetParts.shift(); // Remove the first element + result.streetName = streetParts.join(' '); // Assume street name is everything else + } else { + throw 'Can not parse address. Invalid street address data. Input string: ' + address; + } } else { throw 'Can not parse address. Invalid street address data. Input string: ' + address; } - } else { - throw 'Can not parse address. Invalid street address data. Input string: ' + address; - } - var addressString = result.addressLine1; - if (result.hasOwnProperty('addressLine2')) { - addressString += ', ' + result.addressLine2; - } - if (addressString && result.hasOwnProperty("placeName") && result.hasOwnProperty("stateAbbreviation") && result.hasOwnProperty("zipCode")) { - var idString = addressString + ", " + result.placeName + ", " + result.stateAbbreviation + " " + result.zipCode; - result['formattedAddress'] = idString; - result['id'] = encodeURI(idString.replace(/ /g, '-').replace(/\#/g, '-').replace(/\//g, '-').replace(/\./g, '-')); - } - return result; - }, - randomCity: function() { - var randomState = randomProperty(usCities); - var randomStateData = usCities[randomState]; - var randomCityElementId = Math.floor(Math.random() * randomStateData.length); - var randomCity = randomStateData[randomCityElementId]; - return { city: randomCity, state: randomState}; - }, + var addressString = result.addressLine1; + if (result.hasOwnProperty('addressLine2')) { + addressString += ', ' + result.addressLine2; + } + if (addressString && result.hasOwnProperty("placeName") && result.hasOwnProperty("stateAbbreviation") && result.hasOwnProperty("zipCode")) { + var idString = addressString + ", " + result.placeName + ", " + result.stateAbbreviation + " " + result.zipCode; + result['formattedAddress'] = idString; + result['id'] = encodeURI(idString.replace(/ /g, '-').replace(/\#/g, '-').replace(/\//g, '-').replace(/\./g, '-')); + } - cities: function() { - return(usCities); - } -}; + return result; + }, + + randomCity: function() { + var randomState = randomProperty(usCities); + var randomStateData = usCities[randomState]; + var randomCityElementId = Math.floor(Math.random() * randomStateData.length); + var randomCity = randomStateData[randomCityElementId]; + return { city: randomCity, state: randomState}; + }, + + cities: function() { + return(usCities); + } + }; diff --git a/test/test.js b/test/test.js index 3e634b9..0255564 100644 --- a/test/test.js +++ b/test/test.js @@ -1047,18 +1047,53 @@ describe('Extra canada', function() { expect(result.stateAbbreviation).to.equal("AB"); }); - // TODO: Fix code so streetDirection would be matched without case sensitivity - // it('should parse a simple Canadian Address with any-case southeast street direction', function() { - // var result = addresser.parseAddress('508 Queens dr SouthEast, Calgary, AB, Canada'); - // expect(result.streetNumber).to.equal("508"); - // expect(result.streetName).to.equal("Queens"); - // expect(result.streetSuffix).to.equal("Drive"); - // expect(result.streetDirection).to.equal('SE'); - // expect(result.addressLine1).to.equal("508 Queens Drive SE"); - // expect(result.hasOwnProperty("addressLine2")).to.equal(false); - // expect(result.placeName).to.equal("Calgary"); - // expect(result.stateAbbreviation).to.equal("AB"); - // }); + it('should parse a simple Canadian Address with any-case southeast street direction', function() { + var result = addresser.parseAddress('508 Queens dr SoUthEaSt, Calgary, AB, Canada'); + expect(result.streetNumber).to.equal("508"); + expect(result.streetName).to.equal("Queens"); + expect(result.streetSuffix).to.equal("Drive"); + expect(result.streetDirection).to.equal('SE'); + expect(result.addressLine1).to.equal("508 Queens Drive SE"); + expect(result.hasOwnProperty("addressLine2")).to.equal(false); + expect(result.placeName).to.equal("Calgary"); + expect(result.stateAbbreviation).to.equal("AB"); + }); + + it('should parse a simple Canadian Address with any-case street direction - North East', function() { + var result = addresser.parseAddress('508 Queens dr North East, Calgary, AB, Canada'); + expect(result.streetNumber).to.equal("508"); + expect(result.streetName).to.equal("Queens"); + expect(result.streetSuffix).to.equal("Drive"); + expect(result.streetDirection).to.equal('NE'); + expect(result.addressLine1).to.equal("508 Queens Drive NE"); + expect(result.hasOwnProperty("addressLine2")).to.equal(false); + expect(result.placeName).to.equal("Calgary"); + expect(result.stateAbbreviation).to.equal("AB"); + }); + + it('should parse a simple Canadian Address with any-case street direction - NoRth EaSt', function() { + var result = addresser.parseAddress('508 Queens dr NoRth EaSt, Calgary, AB, Canada'); + expect(result.streetNumber).to.equal("508"); + expect(result.streetName).to.equal("Queens"); + expect(result.streetSuffix).to.equal("Drive"); + expect(result.streetDirection).to.equal('NE'); + expect(result.addressLine1).to.equal("508 Queens Drive NE"); + expect(result.hasOwnProperty("addressLine2")).to.equal(false); + expect(result.placeName).to.equal("Calgary"); + expect(result.stateAbbreviation).to.equal("AB"); + }); + + it('should parse a simple Canadian Address with any-case street direction - NE', function() { + var result = addresser.parseAddress('508 Queens dr NE, Calgary, AB, Canada'); + expect(result.streetNumber).to.equal("508"); + expect(result.streetName).to.equal("Queens"); + expect(result.streetSuffix).to.equal("Drive"); + expect(result.streetDirection).to.equal('NE'); + expect(result.addressLine1).to.equal("508 Queens Drive NE"); + expect(result.hasOwnProperty("addressLine2")).to.equal(false); + expect(result.placeName).to.equal("Calgary"); + expect(result.stateAbbreviation).to.equal("AB"); + }); it('should parse a simple Canadian Address with Ln and SW street direction', function() { var result = addresser.parseAddress('15 Signal Hill Ln SW, Calgary, AB, Canada'); From c1e0ab77480f883ac5c2e790b97b891eca2b45eb Mon Sep 17 00:00:00 2001 From: "K. Sokolinskyi" Date: Fri, 29 Aug 2025 14:43:08 -0400 Subject: [PATCH 06/13] chore: fixed settings.json to be in line with .editorconfig --- .vscode/settings.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 08f8d5a..ed52cad 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -8,7 +8,7 @@ "editor.formatOnSave": false, "editor.tabSize": 4 }, - "editor.tabSize": 4, + "editor.tabSize": 2, "editor.insertSpaces": true, "files.trimTrailingWhitespace": true } From 483f340a4f3b2095255225f544d4ee09d0c7e12e Mon Sep 17 00:00:00 2001 From: "K. Sokolinskyi" Date: Fri, 29 Aug 2025 14:47:45 -0400 Subject: [PATCH 07/13] chore: update dev dependencies (based on https://github.com/moneals/addresser/pull/39/) --- package-lock.json | 1450 ++++++++++++++++++++++++--------------------- package.json | 6 +- 2 files changed, 769 insertions(+), 687 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5d48f7c..40f0f77 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,10 +9,124 @@ "version": "1.1.19", "license": "MIT", "devDependencies": { - "chai": "^4.1.2", - "coveralls": "^3.0.2", + "chai": "^6.0.1", + "coveralls": "^3.1.1", "istanbul": "^0.4.5", - "mocha": "^10.2.0" + "mocha": "^11.7.1" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.0.tgz", + "integrity": "sha512-TKY5pyBkHyADOPYlRT9Lx6F544mPl0vS5Ew7BJ45hA08Q+t3GjbueLliBWN3sMICk6+y7HdyxSzC4bWS8baBdg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" } }, "node_modules/abbrev": { @@ -47,20 +161,12 @@ "node": ">=0.4.2" } }, - "node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -80,19 +186,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -120,15 +213,6 @@ "node": ">=0.8" } }, - "node_modules/assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true, - "engines": { - "node": "*" - } - }, "node_modules/async": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", @@ -171,37 +255,17 @@ "tweetnacl": "^0.14.3" } }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/browser-stdout": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", @@ -227,21 +291,13 @@ "dev": true }, "node_modules/chai": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.7.tgz", - "integrity": "sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/chai/-/chai-6.0.1.tgz", + "integrity": "sha512-/JOoU2//6p5vCXh00FpNgtlw0LjvhGttaWc+y7wpW9yjBm3ys0dI8tSKZxIOgNruz5J0RleccatSIC3uxEZP0g==", "dev": true, - "dependencies": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^4.1.2", - "get-func-name": "^2.0.0", - "loupe": "^2.3.1", - "pathval": "^1.1.1", - "type-detect": "^4.0.5" - }, + "license": "MIT", "engines": { - "node": ">=4" + "node": ">=18" } }, "node_modules/chalk": { @@ -281,51 +337,35 @@ "node": ">=8" } }, - "node_modules/check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", - "dev": true, - "engines": { - "node": "*" - } - }, "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], + "license": "MIT", "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" + "readdirp": "^4.0.1" }, "engines": { - "node": ">= 8.10.0" + "node": ">= 14.16.0" }, - "optionalDependencies": { - "fsevents": "~2.3.2" + "funding": { + "url": "https://paulmillr.com/funding/" } }, "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, + "license": "ISC", "dependencies": { "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", + "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" } }, "node_modules/color-convert": { @@ -389,6 +429,37 @@ "node": ">=6" } }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cross-spawn/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", @@ -402,12 +473,13 @@ } }, "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", "dev": true, + "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -418,12 +490,6 @@ } } }, - "node_modules/debug/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, "node_modules/decamelize": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", @@ -436,18 +502,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/deep-eql": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", - "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", - "dev": true, - "dependencies": { - "type-detect": "^4.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -464,14 +518,22 @@ } }, "node_modules/diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-7.0.0.tgz", + "integrity": "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" } }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, "node_modules/ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", @@ -486,13 +548,15 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -595,18 +659,6 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -632,6 +684,23 @@ "flat": "cli.js" } }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -655,44 +724,16 @@ "node": ">= 0.12" } }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true, + "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", - "dev": true, - "engines": { - "node": "*" - } - }, "node_modules/getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", @@ -718,18 +759,6 @@ "node": "*" } }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/handlebars": { "version": "4.7.7", "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", @@ -832,57 +861,16 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, "node_modules/is-plain-obj": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", @@ -948,6 +936,22 @@ "istanbul": "lib/cli.js" } }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, "node_modules/js-yaml": { "version": "3.14.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", @@ -1075,14 +1079,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/loupe": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz", - "integrity": "sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==", + "node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", "dev": true, - "dependencies": { - "get-func-name": "^2.0.0" - } + "license": "ISC" }, "node_modules/mime-db": { "version": "1.52.0", @@ -1126,6 +1128,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/mkdirp": { "version": "0.5.6", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", @@ -1139,43 +1151,39 @@ } }, "node_modules/mocha": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", - "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==", - "dev": true, - "dependencies": { - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.3", - "debug": "4.3.4", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.2.0", - "he": "1.2.0", - "js-yaml": "4.1.0", - "log-symbols": "4.1.0", - "minimatch": "5.0.1", - "ms": "2.1.3", - "nanoid": "3.3.3", - "serialize-javascript": "6.0.0", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "workerpool": "6.2.1", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" + "version": "11.7.1", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.7.1.tgz", + "integrity": "sha512-5EK+Cty6KheMS/YLPPMJC64g5V61gIR25KsRItHw6x4hEKT6Njp1n9LOlH4gpevuwMVS66SXaBBpg+RWZkza4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "browser-stdout": "^1.3.1", + "chokidar": "^4.0.1", + "debug": "^4.3.5", + "diff": "^7.0.0", + "escape-string-regexp": "^4.0.0", + "find-up": "^5.0.0", + "glob": "^10.4.5", + "he": "^1.2.0", + "js-yaml": "^4.1.0", + "log-symbols": "^4.1.0", + "minimatch": "^9.0.5", + "ms": "^2.1.3", + "picocolors": "^1.1.1", + "serialize-javascript": "^6.0.2", + "strip-json-comments": "^3.1.1", + "supports-color": "^8.1.1", + "workerpool": "^9.2.0", + "yargs": "^17.7.2", + "yargs-parser": "^21.1.1", + "yargs-unparser": "^2.0.0" }, "bin": { "_mocha": "bin/_mocha", "mocha": "bin/mocha.js" }, "engines": { - "node": ">= 14.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mochajs" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/mocha/node_modules/argparse": { @@ -1184,36 +1192,35 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, - "node_modules/mocha/node_modules/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "node_modules/mocha/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, + "license": "MIT", "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "balanced-match": "^1.0.0" } }, - "node_modules/mocha/node_modules/glob/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/mocha/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", "dev": true, + "license": "ISC", "dependencies": { - "brace-expansion": "^1.1.7" + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" }, - "engines": { - "node": "*" + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/mocha/node_modules/has-flag": { @@ -1238,24 +1245,19 @@ } }, "node_modules/mocha/node_modules/minimatch": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", - "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, "engines": { - "node": ">=10" - } - }, - "node_modules/mocha/node_modules/minimatch/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/mocha/node_modules/supports-color": { @@ -1279,18 +1281,6 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, - "node_modules/nanoid": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", - "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", - "dev": true, - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, "node_modules/neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", @@ -1309,15 +1299,6 @@ "nopt": "bin/nopt.js" } }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", @@ -1383,6 +1364,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -1401,13 +1389,31 @@ "node": ">=0.10.0" } }, - "node_modules/pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, + "license": "MIT", "engines": { - "node": "*" + "node": ">=8" + } + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/performance-now": { @@ -1416,17 +1422,12 @@ "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", "dev": true }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } + "license": "ISC" }, "node_modules/prelude-ls": { "version": "1.1.2", @@ -1466,20 +1467,23 @@ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dev": true, + "license": "MIT", "dependencies": { "safe-buffer": "^5.1.0" } }, "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, + "license": "MIT", "engines": { - "node": ">=8.10.0" + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" } }, "node_modules/request": { @@ -1519,6 +1523,7 @@ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -1556,14 +1561,51 @@ "dev": true }, "node_modules/serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "randombytes": "^2.1.0" } }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/source-map": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", @@ -1605,14 +1647,31 @@ "sshpk-verify": "bin/sshpk-verify" }, "engines": { - "node": ">=0.10.0" + "node": ">=0.10.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" } }, - "node_modules/string-width": { + "node_modules/string-width-cjs": { + "name": "string-width", "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -1627,6 +1686,21 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -1658,18 +1732,6 @@ "node": ">=0.8.0" } }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, "node_modules/tough-cookie": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", @@ -1713,15 +1775,6 @@ "node": ">= 0.8.0" } }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/uglify-js": { "version": "3.17.4", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", @@ -1781,10 +1834,11 @@ } }, "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -1796,16 +1850,37 @@ "dev": true }, "node_modules/workerpool": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", - "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", - "dev": true + "version": "9.3.3", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-9.3.3.tgz", + "integrity": "sha512-slxCaKbYjEdFT/o2rH9xS1hf4uRDch1w7Uo+apxhZ+sf/1d9e0ZVkn42kPNGP2dgjIx6YFvSevj0zHvbWe2jdw==", + "dev": true, + "license": "Apache-2.0" }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -1829,35 +1904,38 @@ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true, + "license": "ISC", "engines": { "node": ">=10" } }, "node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, + "license": "MIT", "dependencies": { - "cliui": "^7.0.2", + "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "string-width": "^4.2.0", + "string-width": "^4.2.3", "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" + "yargs-parser": "^21.1.1" }, "engines": { - "node": ">=10" + "node": ">=12" } }, "node_modules/yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true, + "license": "ISC", "engines": { - "node": ">=10" + "node": ">=12" } }, "node_modules/yargs-unparser": { @@ -1889,6 +1967,78 @@ } }, "dependencies": { + "@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "requires": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.0.tgz", + "integrity": "sha512-TKY5pyBkHyADOPYlRT9Lx6F544mPl0vS5Ew7BJ45hA08Q+t3GjbueLliBWN3sMICk6+y7HdyxSzC4bWS8baBdg==", + "dev": true + }, + "ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true + }, + "emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "requires": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + } + }, + "strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "requires": { + "ansi-regex": "^6.0.1" + } + }, + "wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "requires": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + } + } + } + }, + "@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true + }, "abbrev": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", @@ -1914,12 +2064,6 @@ "dev": true, "optional": true }, - "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true - }, "ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", @@ -1935,16 +2079,6 @@ "color-convert": "^2.0.1" } }, - "anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -1969,12 +2103,6 @@ "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", "dev": true }, - "assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true - }, "async": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", @@ -2014,31 +2142,16 @@ "tweetnacl": "^0.14.3" } }, - "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true - }, "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, "browser-stdout": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", @@ -2058,19 +2171,10 @@ "dev": true }, "chai": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.7.tgz", - "integrity": "sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==", - "dev": true, - "requires": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.2", - "deep-eql": "^4.1.2", - "get-func-name": "^2.0.0", - "loupe": "^2.3.1", - "pathval": "^1.1.1", - "type-detect": "^4.0.5" - } + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/chai/-/chai-6.0.1.tgz", + "integrity": "sha512-/JOoU2//6p5vCXh00FpNgtlw0LjvhGttaWc+y7wpW9yjBm3ys0dI8tSKZxIOgNruz5J0RleccatSIC3uxEZP0g==", + "dev": true }, "chalk": { "version": "4.1.2", @@ -2099,36 +2203,23 @@ } } }, - "check-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", - "dev": true - }, "chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", "dev": true, "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" + "readdirp": "^4.0.1" } }, "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, "requires": { "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", + "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, @@ -2181,6 +2272,28 @@ "request": "^2.88.2" } }, + "cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "dependencies": { + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, "dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", @@ -2191,20 +2304,12 @@ } }, "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", "dev": true, "requires": { - "ms": "2.1.2" - }, - "dependencies": { - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } + "ms": "^2.1.3" } }, "decamelize": { @@ -2213,15 +2318,6 @@ "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", "dev": true }, - "deep-eql": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", - "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, "deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -2235,9 +2331,15 @@ "dev": true }, "diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-7.0.0.tgz", + "integrity": "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==", + "dev": true + }, + "eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", "dev": true }, "ecc-jsbn": { @@ -2257,9 +2359,9 @@ "dev": true }, "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true }, "escape-string-regexp": { @@ -2329,15 +2431,6 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, "find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -2354,6 +2447,16 @@ "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", "dev": true }, + "foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + } + }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -2371,31 +2474,12 @@ "mime-types": "^2.1.12" } }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "optional": true - }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", - "dev": true - }, "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", @@ -2418,15 +2502,6 @@ "path-is-absolute": "^1.0.0" } }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, "handlebars": { "version": "4.7.7", "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", @@ -2503,42 +2578,12 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true - }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, "is-plain-obj": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", @@ -2591,6 +2636,16 @@ "wordwrap": "^1.0.0" } }, + "jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "requires": { + "@isaacs/cliui": "^8.0.2", + "@pkgjs/parseargs": "^0.11.0" + } + }, "js-yaml": { "version": "3.14.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", @@ -2686,14 +2741,11 @@ "is-unicode-supported": "^0.1.0" } }, - "loupe": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.6.tgz", - "integrity": "sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==", - "dev": true, - "requires": { - "get-func-name": "^2.0.0" - } + "lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true }, "mime-db": { "version": "1.52.0", @@ -2725,6 +2777,12 @@ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "dev": true }, + "minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true + }, "mkdirp": { "version": "0.5.6", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", @@ -2735,32 +2793,31 @@ } }, "mocha": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz", - "integrity": "sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==", - "dev": true, - "requires": { - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.3", - "debug": "4.3.4", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.2.0", - "he": "1.2.0", - "js-yaml": "4.1.0", - "log-symbols": "4.1.0", - "minimatch": "5.0.1", - "ms": "2.1.3", - "nanoid": "3.3.3", - "serialize-javascript": "6.0.0", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "workerpool": "6.2.1", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" + "version": "11.7.1", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.7.1.tgz", + "integrity": "sha512-5EK+Cty6KheMS/YLPPMJC64g5V61gIR25KsRItHw6x4hEKT6Njp1n9LOlH4gpevuwMVS66SXaBBpg+RWZkza4A==", + "dev": true, + "requires": { + "browser-stdout": "^1.3.1", + "chokidar": "^4.0.1", + "debug": "^4.3.5", + "diff": "^7.0.0", + "escape-string-regexp": "^4.0.0", + "find-up": "^5.0.0", + "glob": "^10.4.5", + "he": "^1.2.0", + "js-yaml": "^4.1.0", + "log-symbols": "^4.1.0", + "minimatch": "^9.0.5", + "ms": "^2.1.3", + "picocolors": "^1.1.1", + "serialize-javascript": "^6.0.2", + "strip-json-comments": "^3.1.1", + "supports-color": "^8.1.1", + "workerpool": "^9.2.0", + "yargs": "^17.7.2", + "yargs-parser": "^21.1.1", + "yargs-unparser": "^2.0.0" }, "dependencies": { "argparse": { @@ -2769,29 +2826,27 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, + "brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, "glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", "dev": true, "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "dependencies": { - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - } + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" } }, "has-flag": { @@ -2810,23 +2865,12 @@ } }, "minimatch": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz", - "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, "requires": { "brace-expansion": "^2.0.1" - }, - "dependencies": { - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - } } }, "supports-color": { @@ -2846,12 +2890,6 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, - "nanoid": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", - "integrity": "sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==", - "dev": true - }, "neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", @@ -2867,12 +2905,6 @@ "abbrev": "1" } }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, "oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", @@ -2920,6 +2952,12 @@ "p-limit": "^3.0.2" } }, + "package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true + }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -2932,22 +2970,32 @@ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true }, - "pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true }, + "path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "requires": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + } + }, "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", "dev": true }, - "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "dev": true }, "prelude-ls": { @@ -2984,13 +3032,10 @@ } }, "readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "requires": { - "picomatch": "^2.2.1" - } + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true }, "request": { "version": "2.88.2", @@ -3045,14 +3090,35 @@ "dev": true }, "serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "dev": true, "requires": { "randombytes": "^2.1.0" } }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true + }, "source-map": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", @@ -3097,6 +3163,17 @@ "strip-ansi": "^6.0.1" } }, + "string-width-cjs": { + "version": "npm:string-width@4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, "strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -3106,6 +3183,15 @@ "ansi-regex": "^5.0.1" } }, + "strip-ansi-cjs": { + "version": "npm:strip-ansi@6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, "strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -3121,15 +3207,6 @@ "has-flag": "^1.0.0" } }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, "tough-cookie": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", @@ -3164,12 +3241,6 @@ "prelude-ls": "~1.1.2" } }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, "uglify-js": { "version": "3.17.4", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", @@ -3213,9 +3284,9 @@ } }, "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true }, "wordwrap": { @@ -3225,9 +3296,9 @@ "dev": true }, "workerpool": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz", - "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==", + "version": "9.3.3", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-9.3.3.tgz", + "integrity": "sha512-slxCaKbYjEdFT/o2rH9xS1hf4uRDch1w7Uo+apxhZ+sf/1d9e0ZVkn42kPNGP2dgjIx6YFvSevj0zHvbWe2jdw==", "dev": true }, "wrap-ansi": { @@ -3241,6 +3312,17 @@ "strip-ansi": "^6.0.0" } }, + "wrap-ansi-cjs": { + "version": "npm:wrap-ansi@7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -3254,24 +3336,24 @@ "dev": true }, "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, "requires": { - "cliui": "^7.0.2", + "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "string-width": "^4.2.0", + "string-width": "^4.2.3", "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" + "yargs-parser": "^21.1.1" } }, "yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true }, "yargs-unparser": { diff --git a/package.json b/package.json index 0081367..361ec7a 100644 --- a/package.json +++ b/package.json @@ -25,9 +25,9 @@ }, "homepage": "https://github.com/moneals/addresser#readme", "devDependencies": { - "chai": "^4.1.2", - "coveralls": "^3.0.2", + "chai": "^6.0.1", + "coveralls": "^3.1.1", "istanbul": "^0.4.5", - "mocha": "^10.2.0" + "mocha": "^11.7.1" } } From 9bc675e76fa8535f12075139b1e56940acfdb509 Mon Sep 17 00:00:00 2001 From: "K. Sokolinskyi" Date: Fri, 29 Aug 2025 14:48:58 -0400 Subject: [PATCH 08/13] chore: Update geonames.org url protocol to https (based on https://github.com/moneals/addresser/pull/39) --- utils/getCities.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/getCities.js b/utils/getCities.js index f68a47a..8effe35 100644 --- a/utils/getCities.js +++ b/utils/getCities.js @@ -7,7 +7,7 @@ async function getDataForCountry(country_code){ let country_code_upper = country_code.toUpperCase(); var states = JSON.parse(fs.readFileSync("../data/"+country_code_lower+"-states.json")); - unzipper.Open.url(request,'http://download.geonames.org/export/zip/'+country_code_upper+'.zip') + unzipper.Open.url(request,'https://download.geonames.org/export/zip/'+country_code_upper+'.zip') .then(function(d) { var file = d.files.filter(function(d) { return d.path === country_code_upper+'.txt'; From 59f6e9e6cb4525f7842e71ca26dc5d53b6d659c1 Mon Sep 17 00:00:00 2001 From: "K. Sokolinskyi" Date: Fri, 29 Aug 2025 14:51:42 -0400 Subject: [PATCH 09/13] chore: Add files field to limit files installed when installed as a package (based on https://github.com/moneals/addresser/pull/34) --- package.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/package.json b/package.json index 361ec7a..d0c7fb9 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,10 @@ "type": "git", "url": "git+https://github.com/moneals/addresser.git" }, + "files": [ + "index.js", + "data" + ], "keywords": [ "address", "parser", From f56e76b7ad602afe1d749741f3c01a102a2004ce Mon Sep 17 00:00:00 2001 From: "K. Sokolinskyi" Date: Fri, 29 Aug 2025 15:49:53 -0400 Subject: [PATCH 10/13] chore: add index.d.ts to exported files --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index d0c7fb9..9d214f1 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ }, "files": [ "index.js", + "index.d.ts", "data" ], "keywords": [ From 08c766b2f41e97758bf3b6a0f67523f7ecf575e9 Mon Sep 17 00:00:00 2001 From: Kostiantyn Sokolinskyi Date: Mon, 8 Sep 2025 16:52:35 -0400 Subject: [PATCH 11/13] feat: extend ca-street-types with more shortenings (#4) --- data/ca-street-types.json | 158 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) diff --git a/data/ca-street-types.json b/data/ca-street-types.json index 277bde2..67070c8 100644 --- a/data/ca-street-types.json +++ b/data/ca-street-types.json @@ -1,32 +1,64 @@ { "abbey": "abbey", "acres": "acres", + "allee": "alley", "alley": "alley", + "ally": "alley", + "aly": "alley", "autoroute": "autoroute", "aut": "autoroute", + "av": "avenue", "ave": "avenue", + "aven": "avenue", + "avenu": "avenue", "avenue": "avenue", + "avn": "avenue", + "avnue": "avenue", "bay": "bay", "beach": "beach", + "bch": "beach", "bend": "bend", + "bnd": "bend", "blvd": "boulevard", "boulevard": "boulevard", + "boul": "boulevard", + "boulv": "boulevard", "by-pass": "by-pass", "bypass": "by-pass", + "byp": "by-pass", + "bypa": "by-pass", + "bypas": "by-pass", + "byps": "by-pass", "byway": "byway", "campus": "campus", + "camp": "campus", + "cp": "campus", "cape": "cape", + "cpe": "cape", "centre": "centre", "ctr": "centre", + "center": "centre", + "cen": "centre", + "cent": "centre", + "centr": "centre", + "cnter": "centre", + "cntr": "centre", "chase": "chase", "chemin": "chemin", "ch": "chemin", "circle": "circle", "cir": "circle", + "circ": "circle", + "circl": "circle", + "crcl": "circle", + "crcle": "circle", "circuit": "circuit", "circt": "circuit", "close": "close", + "clse": "close", + "cl": "close", "common": "common", + "cmn": "common", "concession": "concession", "conc": "concession", "corners": "corners", @@ -35,123 +67,231 @@ "crt": "court", "ct": "court", "cove": "cove", + "cv": "cove", "crescent": "crescent", "cres": "crescent", "cr": "crescent", + "crecent": "crescent", + "cresent": "crescent", + "crscnt": "crescent", + "crsent": "crescent", + "crsnt": "crescent", "crossing": "crossing", "cross": "crossing", + "xing": "crossing", + "crssing": "crossing", + "crssng": "crossing", "cul-de-sac": "cul-de-sac", "cds": "cul-de-sac", "dale": "dale", + "dl": "dale", "dell": "dell", "diversion": "diversion", "divers": "diversion", "downs": "downs", "drive": "drive", "dr": "drive", + "driv": "drive", + "drv": "drive", "end": "end", "esplanade": "esplanade", "espl": "esplanade", "estates": "estates", "estate": "estates", + "est": "estates", + "ests": "estates", "expressway": "expressway", "expy": "expressway", + "exp": "expressway", + "expr": "expressway", + "express": "expressway", + "expw": "expressway", "extension": "extension", "exten": "extension", + "ext": "extension", + "extn": "extension", + "extnsn": "extension", "farm": "farm", "field": "field", + "fld": "field", "forest": "forest", + "frst": "forest", "freeway": "freeway", "fwy": "freeway", + "freewy": "freeway", + "frway": "freeway", + "frwy": "freeway", "front": "front", "gardens": "gardens", "gdns": "gardens", + "garden": "gardens", + "gdn": "gardens", + "gardn": "gardens", + "grden": "gardens", + "grdn": "gardens", + "grdns": "gardens", "gate": "gate", + "gt": "gate", "glade": "glade", + "gld": "glade", "glen": "glen", + "gln": "glen", "green": "green", + "grn": "green", "grounds": "grounds", "grnds": "grounds", "grove": "grove", + "grv": "grove", + "grov": "grove", "harbour": "harbour", "harbr": "harbour", + "harbor": "harbour", + "harb": "harbour", + "hbr": "harbour", "heath": "heath", "heights": "heights", "hts": "heights", + "height": "heights", + "hgts": "heights", + "ht": "heights", "highlands": "highlands", "hghlds": "highlands", "highway": "highway", "hwy": "highway", + "highwy": "highway", + "hiway": "highway", + "hiwy": "highway", + "hway": "highway", "hill": "hill", + "hl": "hill", "hollow": "hollow", + "holw": "hollow", + "hllw": "hollow", "inlet": "inlet", + "inlt": "inlet", "island": "island", + "is": "island", + "islnd": "island", + "islands": "islands", + "isle": "isle", + "isles": "isles", + "islnds": "islands", "key": "key", + "ky": "key", + "keys": "keys", + "kys": "keys", "knoll": "knoll", + "knl": "knoll", + "knol": "knoll", + "knolls": "knolls", + "knls": "knolls", "landing": "landing", "landng": "landing", + "lndg": "landing", + "lndng": "landing", "lane": "lane", "ln": "lane", + "la": "lane", + "lanes": "lane", "limits": "limits", "lmts": "limits", "line": "line", "link": "link", + "lnk": "link", "lookout": "lookout", "lkout": "lookout", "loop": "loop", + "lp": "loop", "mall": "mall", + "ml": "mall", "manor": "manor", + "mnr": "manor", "maze": "maze", + "mz": "maze", "meadow": "meadow", + "mdw": "meadow", "mews": "mews", + "mws": "mews", "moor": "moor", "montee": "montee", "mount": "mount", + "mt": "mount", + "mnt": "mount", "mountain": "mountain", "mtn": "mountain", + "mntain": "mountain", + "mntn": "mountain", + "mountin": "mountain", + "mtin": "mountain", "orchard": "orchard", "orch": "orchard", + "orchrd": "orchard", "parade": "parade", + "pde": "parade", "park": "park", "pk": "park", + "prk": "park", + "parks": "park", "parkway": "parkway", "pky": "parkway", + "pkwy": "parkway", + "pkway": "parkway", + "parkwy": "parkway", + "parkways": "parkway", "passage": "passage", "pass": "passage", + "psge": "passage", "path": "path", + "paths": "path", "pathway": "pathway", "ptway": "pathway", "pines": "pines", + "pne": "pines", + "pine": "pines", "place": "place", "pl": "place", "plateau": "plateau", "plat": "plateau", "plaza": "plaza", + "plz": "plaza", + "plza": "plaza", "point": "point", "pt": "point", "port": "port", + "prt": "port", "private": "private", "pvt": "private", "promenade": "promenade", "prom": "promenade", "quay": "quay", + "qy": "quay", "ramp": "ramp", + "rmp": "ramp", "range": "range", "rg": "range", "rang": "rang", "ridge": "ridge", + "rdg": "ridge", "rise": "rise", + "rs": "rise", "road": "road", "rd": "road", + "roads": "road", "route": "route", "rte": "route", "row": "row", "rue": "rue", "run": "run", + "rn": "run", "square": "square", "sq": "square", + "sqr": "square", + "sqre": "square", + "squ": "square", "st": "st", "street": "st", + "str": "st", + "strt": "st", "subdivision": "subdivision", "subdiv": "subdivision", "sideroad": "sideroad", @@ -162,22 +302,40 @@ "thicket": "thicket", "thick": "thicket", "towers": "towers", + "twrs": "towers", "townline": "townline", "tline": "townline", "trail": "trail", "trl": "trail", + "tr": "trail", + "trails": "trail", "turnabout": "turnabout", "trnabt": "turnabout", "vale": "vale", + "vl": "vale", "via": "via", "view": "view", + "vw": "view", + "vis": "view", + "vist": "view", + "vst": "view", + "vsta": "view", "village": "village", "villge": "village", + "vlg": "village", + "vill": "village", + "villag": "village", + "villg": "village", + "villiage": "village", "villas": "villas", "vista": "vista", "walk": "walk", + "walks": "walk", "way": "way", + "wy": "way", "wharf": "wharf", + "whf": "wharf", "wood": "wood", + "wd": "wood", "wynd": "wynd" } From bb82d2bfd8f3cf12318189744c25066595b7d894 Mon Sep 17 00:00:00 2001 From: Kostiantyn Sokolinskyi Date: Tue, 9 Sep 2025 11:08:19 -0400 Subject: [PATCH 12/13] us street types mappings improvements (#5) * feat: add us street mapping into Primary Street Suffix Name; add common misspelings to the mapping * feat: extend us-street-types with common misspelings to improve robustness --- data/us-street-types-mapping-to-primary.json | 590 +++++++++++++++++++ data/us-street-types.json | 24 + 2 files changed, 614 insertions(+) create mode 100644 data/us-street-types-mapping-to-primary.json diff --git a/data/us-street-types-mapping-to-primary.json b/data/us-street-types-mapping-to-primary.json new file mode 100644 index 0000000..433d079 --- /dev/null +++ b/data/us-street-types-mapping-to-primary.json @@ -0,0 +1,590 @@ +{ + "allee": "alley", + "alley": "alley", + "ally": "alley", + "aly": "alley", + "anex": "annex", + "annex": "annex", + "annx": "annex", + "anx": "annex", + "arc": "arcade", + "arcade": "arcade", + "av": "avenue", + "ave": "avenue", + "aven": "avenue", + "avenu": "avenue", + "avenue": "avenue", + "avn": "avenue", + "avnue": "avenue", + "avene": "avenue", + "avneu": "avenue", + "bayoo": "bayou", + "bayou": "bayou", + "bch": "beach", + "beach": "beach", + "bend": "bend", + "bnd": "bend", + "bg": "burg", + "bgs": "burgs", + "blf": "bluff", + "blfs": "bluffs", + "bluf": "bluff", + "bluff": "bluff", + "bluffs": "bluffs", + "blvd": "boulevard", + "bot": "bottom", + "bottm": "bottom", + "bottom": "bottom", + "boul": "boulevard", + "boulevard": "boulevard", + "boulv": "boulevard", + "boulavard": "boulevard", + "boulevrd": "boulevard", + "boulvard": "boulevard", + "br": "branch", + "branch": "branch", + "brdge": "bridge", + "brg": "bridge", + "bridge": "bridge", + "brk": "brook", + "brks": "brooks", + "brnch": "branch", + "brook": "brook", + "brooks": "brooks", + "btm": "bottom", + "burg": "burg", + "burgs": "burgs", + "byp": "bypass", + "bypa": "bypass", + "bypas": "bypass", + "bypass": "bypass", + "byps": "bypass", + "byu": "bayou", + "camp": "camp", + "canyn": "canyon", + "canyon": "canyon", + "cape": "cape", + "causeway": "causeway", + "causway": "causeway", + "cen": "center", + "cent": "center", + "center": "center", + "centers": "centers", + "centr": "center", + "centre": "center", + "cir": "circle", + "circ": "circle", + "circl": "circle", + "circle": "circle", + "circles": "circles", + "cirs": "circles", + "cercle": "circle", + "cercl": "circle", + "ck": "creek", + "clb": "club", + "clf": "cliff", + "clfs": "cliffs", + "cliff": "cliff", + "cliffs": "cliffs", + "club": "club", + "cmn": "common", + "cmp": "camp", + "cnter": "center", + "cntr": "center", + "cnyn": "canyon", + "common": "common", + "cor": "corner", + "corner": "corner", + "corners": "corners", + "cors": "corners", + "course": "course", + "court": "court", + "courts": "courts", + "cove": "cove", + "coves": "coves", + "cp": "camp", + "cpe": "cape", + "cr": "creek", + "crcl": "circle", + "crcle": "circle", + "crecent": "crescent", + "creek": "creek", + "cres": "crescent", + "crescent": "crescent", + "cresent": "crescent", + "crest": "crest", + "crk": "creek", + "crossing": "crossing", + "crossroad": "crossroad", + "crscnt": "crescent", + "crse": "course", + "crsent": "crescent", + "crsnt": "crescent", + "crssing": "crossing", + "crssng": "crossing", + "crst": "crest", + "crt": "court", + "cswy": "causeway", + "ct": "court", + "cort": "court", + "cout": "court", + "ctr": "center", + "ctrs": "centers", + "cts": "courts", + "curv": "curve", + "curve": "curve", + "cv": "cove", + "cvs": "coves", + "cyn": "canyon", + "dale": "dale", + "dam": "dam", + "div": "divide", + "divide": "divide", + "dl": "dale", + "dm": "dam", + "dr": "drive", + "driv": "drive", + "drive": "drive", + "drives": "drives", + "drs": "drives", + "drv": "drive", + "drie": "drive", + "drve": "drive", + "dv": "divide", + "dvd": "divide", + "est": "estate", + "estate": "estate", + "estates": "estates", + "ests": "estates", + "exp": "expressway", + "expr": "expressway", + "express": "expressway", + "expressway": "expressway", + "expw": "expressway", + "expy": "expressway", + "expwy": "expressway", + "expresswy": "expressway", + "ext": "extension", + "extension": "extension", + "extensions": "extensions", + "extn": "extension", + "extnsn": "extension", + "exts": "extensions", + "fall": "fall", + "falls": "falls", + "ferry": "ferry", + "field": "field", + "fields": "fields", + "flat": "flat", + "flats": "flats", + "fld": "field", + "flds": "fields", + "fls": "falls", + "flt": "flat", + "flts": "flats", + "ford": "ford", + "fords": "fords", + "forest": "forest", + "forests": "forest", + "forg": "forge", + "forge": "forge", + "forges": "forges", + "fork": "fork", + "forks": "forks", + "fort": "fort", + "frd": "ford", + "frds": "fords", + "freeway": "freeway", + "freewy": "freeway", + "frg": "forge", + "frgs": "forges", + "frk": "fork", + "frks": "forks", + "frry": "ferry", + "frst": "forest", + "frt": "fort", + "frway": "freeway", + "frwy": "freeway", + "fry": "ferry", + "ft": "fort", + "fwy": "freeway", + "garden": "garden", + "gardens": "gardens", + "gardn": "garden", + "gateway": "gateway", + "gatewy": "gateway", + "gatway": "gateway", + "gdn": "garden", + "gdns": "gardens", + "glen": "glen", + "glens": "glens", + "gln": "glen", + "glns": "glens", + "grden": "garden", + "grdn": "garden", + "grdns": "gardens", + "green": "green", + "greens": "greens", + "grn": "green", + "grns": "greens", + "grov": "grove", + "grove": "grove", + "groves": "groves", + "grv": "grove", + "grvs": "groves", + "gtway": "gateway", + "gtwy": "gateway", + "harb": "harbor", + "harbor": "harbor", + "harbors": "harbors", + "harbr": "harbor", + "haven": "haven", + "havn": "haven", + "hbr": "harbor", + "hbrs": "harbors", + "height": "heights", + "heights": "heights", + "hgts": "heights", + "highway": "highway", + "highwy": "highway", + "hill": "hill", + "hills": "hills", + "hiway": "highway", + "hiwy": "highway", + "hl": "hill", + "hls": "hills", + "hllw": "hollow", + "hollow": "hollow", + "hollows": "hollow", + "holw": "hollow", + "holws": "hollow", + "hrbor": "harbor", + "ht": "heights", + "hts": "heights", + "hvn": "haven", + "hway": "highway", + "hwy": "highway", + "inlet": "inlet", + "inlt": "inlet", + "is": "island", + "island": "island", + "islands": "islands", + "isle": "isle", + "isles": "isle", + "islnd": "island", + "islnds": "islands", + "iss": "islands", + "jct": "junction", + "jction": "junction", + "jctn": "junction", + "jctns": "junctions", + "jcts": "junctions", + "junction": "junction", + "junctions": "junctions", + "junctn": "junction", + "juncton": "junction", + "key": "key", + "keys": "keys", + "knl": "knoll", + "knls": "knolls", + "knol": "knoll", + "knoll": "knoll", + "knolls": "knolls", + "ky": "key", + "kys": "keys", + "la": "lane", + "lake": "lake", + "lakes": "lakes", + "land": "land", + "landing": "landing", + "lane": "lane", + "lanes": "lane", + "lck": "lock", + "lcks": "locks", + "ldg": "lodge", + "ldge": "lodge", + "lf": "loaf", + "lgt": "light", + "lgts": "lights", + "light": "light", + "lights": "lights", + "lk": "lake", + "lks": "lakes", + "ln": "lane", + "lne": "lane", + "lan": "lane", + "lndg": "landing", + "lndng": "landing", + "loaf": "loaf", + "lock": "lock", + "locks": "locks", + "lodg": "lodge", + "lodge": "lodge", + "loop": "loop", + "loops": "loop", + "manor": "manor", + "manors": "manors", + "mdw": "meadow", + "mdws": "meadows", + "meadow": "meadow", + "meadows": "meadows", + "medows": "meadows", + "mews": "mews", + "mill": "mill", + "mills": "mills", + "mission": "mission", + "missn": "mission", + "ml": "mill", + "mls": "mills", + "mnr": "manor", + "mnrs": "manors", + "mnt": "mount", + "mntain": "mountain", + "mntn": "mountain", + "mntns": "mountains", + "motorway": "motorway", + "mount": "mount", + "mountain": "mountain", + "mountains": "mountains", + "mountin": "mountain", + "msn": "mission", + "mssn": "mission", + "mt": "mount", + "mtin": "mountain", + "mtn": "mountain", + "mtns": "mountains", + "mtwy": "motorway", + "nck": "neck", + "neck": "neck", + "opas": "overpass", + "orch": "orchard", + "orchard": "orchard", + "orchrd": "orchard", + "oval": "oval", + "overpass": "overpass", + "ovl": "oval", + "park": "park", + "parks": "parks", + "parkway": "parkway", + "parkways": "parkways", + "parkwy": "parkway", + "pass": "pass", + "passage": "passage", + "path": "path", + "paths": "path", + "pike": "pike", + "pikes": "pike", + "pine": "pine", + "pines": "pines", + "pk": "park", + "pak": "park", + "pkway": "parkway", + "pkwy": "parkway", + "pkwys": "parkways", + "pky": "parkway", + "pl": "place", + "place": "place", + "plain": "plain", + "plaines": "plains", + "plains": "plains", + "plaza": "plaza", + "pln": "plain", + "plns": "plains", + "plz": "plaza", + "plza": "plaza", + "plazza": "plaza", + "pne": "pine", + "pnes": "pines", + "point": "point", + "points": "points", + "port": "port", + "ports": "ports", + "pr": "prairie", + "prairie": "prairie", + "prarie": "prairie", + "prk": "park", + "prr": "prairie", + "prt": "port", + "prts": "ports", + "psge": "passage", + "pt": "point", + "pts": "points", + "rad": "radial", + "radial": "radial", + "radiel": "radial", + "radl": "radial", + "ramp": "ramp", + "ranch": "ranch", + "ranches": "ranch", + "rapid": "rapid", + "rapids": "rapids", + "rd": "road", + "raod": "road", + "rode": "road", + "rdg": "ridge", + "rdge": "ridge", + "rdgs": "ridges", + "rds": "roads", + "rest": "rest", + "ridge": "ridge", + "ridges": "ridges", + "riv": "river", + "river": "river", + "rivr": "river", + "rnch": "ranch", + "rnchs": "ranch", + "road": "road", + "roads": "roads", + "route": "route", + "rpd": "rapid", + "rpds": "rapids", + "rst": "rest", + "rte": "route", + "rue": "rue", + "run": "run", + "rvr": "river", + "row": "row", + "shl": "shoal", + "shls": "shoals", + "shoal": "shoal", + "shoals": "shoals", + "shoar": "shore", + "shoars": "shores", + "shore": "shore", + "shores": "shores", + "shr": "shore", + "shrs": "shores", + "skwy": "skyway", + "skyway": "skyway", + "smt": "summit", + "spg": "spring", + "spgs": "springs", + "spng": "spring", + "spngs": "springs", + "spring": "spring", + "springs": "springs", + "sprng": "spring", + "sprngs": "springs", + "spur": "spur", + "spurs": "spur", + "sq": "square", + "sqr": "square", + "sqre": "square", + "sqrs": "squares", + "sqs": "squares", + "squ": "square", + "square": "square", + "squares": "squares", + "st": "street", + "sta": "station", + "station": "station", + "statn": "station", + "stn": "station", + "str": "street", + "steet": "street", + "streat": "street", + "sreet": "street", + "stra": "stravenue", + "strav": "stravenue", + "strave": "stravenue", + "straven": "stravenue", + "stravenue": "stravenue", + "stravn": "stravenue", + "stream": "stream", + "street": "street", + "streets": "streets", + "streme": "stream", + "strm": "stream", + "strt": "street", + "strvn": "stravenue", + "strvnue": "stravenue", + "sts": "streets", + "sumit": "summit", + "sumitt": "summit", + "summit": "summit", + "ter": "terrace", + "terr": "terrace", + "terrace": "terrace", + "terace": "terrace", + "throughway": "throughway", + "tpk": "turnpike", + "tpke": "turnpike", + "tr": "trail", + "trace": "trace", + "traces": "trace", + "track": "track", + "tracks": "track", + "trafficway": "trafficway", + "trail": "trail", + "trailer": "trailer", + "trails": "trail", + "trak": "track", + "trce": "trace", + "trfy": "trafficway", + "trk": "track", + "trks": "track", + "trl": "trail", + "trls": "trail", + "trlr": "trailer", + "trlrs": "trailer", + "trnpk": "turnpike", + "trpk": "turnpike", + "trwy": "throughway", + "tunel": "tunnel", + "tunl": "tunnel", + "tunls": "tunnel", + "tunnel": "tunnel", + "tunnels": "tunnel", + "tunnl": "tunnel", + "turn": "turn", + "turnpike": "turnpike", + "turnpk": "turnpike", + "underpass": "underpass", + "un": "union", + "union": "union", + "unions": "unions", + "uns": "unions", + "upas": "underpass", + "valley": "valley", + "valleys": "valleys", + "vally": "valley", + "vdct": "viaduct", + "via": "viaduct", + "viadct": "viaduct", + "viaduct": "viaduct", + "view": "view", + "views": "views", + "vill": "village", + "villag": "village", + "village": "village", + "villages": "villages", + "ville": "ville", + "villg": "village", + "villiage": "village", + "vis": "vista", + "vist": "vista", + "vista": "vista", + "vl": "ville", + "vlg": "village", + "vlgs": "villages", + "vlly": "valley", + "vly": "valley", + "vlys": "valleys", + "vst": "vista", + "vsta": "vista", + "vw": "view", + "vws": "views", + "walk": "walk", + "walks": "walks", + "wall": "wall", + "way": "way", + "wa": "way", + "ways": "ways", + "well": "well", + "wells": "wells", + "wl": "well", + "wls": "wells", + "wy": "way", + "xing": "crossing", + "xrd": "crossroad" +} diff --git a/data/us-street-types.json b/data/us-street-types.json index 87cfb11..b647da5 100644 --- a/data/us-street-types.json +++ b/data/us-street-types.json @@ -16,6 +16,8 @@ "avenue" : "ave", "avn" : "ave", "avnue" : "ave", + "avene" : "ave", + "avneu" : "ave", "bayoo" : "byu", "bayou" : "byu", "bch" : "bch", @@ -36,6 +38,9 @@ "boul" : "blvd", "boulevard" : "blvd", "boulv" : "blvd", + "boulavard" : "blvd", + "boulevrd" : "blvd", + "boulvard" : "blvd", "br" : "br", "branch" : "br", "brdge" : "brg", @@ -73,6 +78,8 @@ "circle" : "cir", "circles" : "cirs", "cirs" : "cirs", + "cercle" : "cir", + "cercl" : "cir", "ck" : "crk", "clb" : "clb", "clf" : "clf", @@ -119,6 +126,8 @@ "crt" : "ct", "cswy" : "cswy", "ct" : "ct", + "cort" : "ct", + "cout" : "ct", "ctr" : "ctr", "ctrs" : "ctrs", "cts" : "cts", @@ -139,6 +148,8 @@ "drives" : "drs", "drs" : "drs", "drv" : "dr", + "drie" : "dr", + "drve" : "dr", "dv" : "dv", "dvd" : "dv", "est" : "est", @@ -151,6 +162,8 @@ "expressway" : "expy", "expw" : "expy", "expy" : "expy", + "expwy" : "expy", + "expresswy" : "expy", "ext" : "ext", "extension" : "ext", "extensions" : "exts", @@ -284,6 +297,8 @@ "landing" : "lndg", "lane" : "ln", "lanes" : "ln", + "lne" : "ln", + "lan" : "ln", "lck" : "lck", "lcks" : "lcks", "ldg" : "ldg", @@ -359,6 +374,7 @@ "pine" : "pne", "pines" : "pnes", "pk" : "park", + "pak" : "park", "pkway" : "pkwy", "pkwy" : "pkwy", "pkwys" : "pkwy", @@ -373,6 +389,7 @@ "plns" : "plns", "plz" : "plz", "plza" : "plz", + "plazza" : "plz", "pne" : "pne", "pnes" : "pnes", "point" : "pt", @@ -411,6 +428,8 @@ "rnch" : "rnch", "rnchs" : "rnch", "road" : "rd", + "raod" : "rd", + "rode" : "rd", "roads" : "rds", "route" : "rte", "rpd" : "rpd", @@ -464,6 +483,9 @@ "stravn" : "stra", "stream" : "strm", "street" : "st", + "steet" : "st", + "streat" : "st", + "sreet" : "st", "streets" : "sts", "streme" : "strm", "strm" : "strm", @@ -477,6 +499,7 @@ "ter" : "ter", "terr" : "ter", "terrace" : "ter", + "terace" : "ter", "throughway" : "trwy", "tpk" : "tpke", "tpke" : "tpke", @@ -545,6 +568,7 @@ "walk" : "walk", "walks" : "walk", "way" : "way", + "wa" : "way", "well" : "wl", "wells" : "wls", "wl" : "wl", From 0d73195e53aab3cf271305ed136cabe599846e5b Mon Sep 17 00:00:00 2001 From: Kostiantyn Sokolinskyi Date: Tue, 9 Sep 2025 14:51:54 -0400 Subject: [PATCH 13/13] fix: canadian street types mapping - all go in long form now (#6) --- data/ca-street-types.json | 8 ++++---- test/test.js | 28 ++++++++++++++-------------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/data/ca-street-types.json b/data/ca-street-types.json index 67070c8..7af0aa9 100644 --- a/data/ca-street-types.json +++ b/data/ca-street-types.json @@ -288,10 +288,10 @@ "sqr": "square", "sqre": "square", "squ": "square", - "st": "st", - "street": "st", - "str": "st", - "strt": "st", + "st": "street", + "street": "street", + "str": "street", + "strt": "street", "subdivision": "subdivision", "subdiv": "subdivision", "sideroad": "sideroad", diff --git a/test/test.js b/test/test.js index 0255564..f4f9796 100644 --- a/test/test.js +++ b/test/test.js @@ -893,9 +893,9 @@ describe('#parseAddress', function() { var result = addresser.parseAddress("123 Main St, Toronto, ON M3K5K9, Canada"); expect(result.streetNumber).to.equal("123"); expect(result.streetName).to.equal("Main"); - expect(result.streetSuffix).to.equal("St"); + expect(result.streetSuffix).to.equal("Street"); expect(result.hasOwnProperty("streetDirection")).to.equal(false); - expect(result.addressLine1).to.equal("123 Main St"); + expect(result.addressLine1).to.equal("123 Main Street"); expect(result.hasOwnProperty("addressLine2")).to.equal(false); expect(result.placeName).to.equal("Toronto"); expect(result.stateAbbreviation).to.equal("ON"); @@ -935,9 +935,9 @@ describe('Extra canada', function() { var result = addresser.parseAddress('310 8 Street North, Calgary, Alberta T2P 3P3, Canada'); expect(result.streetNumber).to.equal("310"); expect(result.streetName).to.equal("8"); - expect(result.streetSuffix).to.equal("St"); + expect(result.streetSuffix).to.equal("Street"); expect(result.streetDirection).to.equal("N"); - expect(result.addressLine1).to.equal("310 8 St N"); + expect(result.addressLine1).to.equal("310 8 Street N"); expect(result.hasOwnProperty("addressLine2")).to.equal(false); expect(result.placeName).to.equal("Calgary"); expect(result.stateAbbreviation).to.equal("AB"); @@ -950,9 +950,9 @@ describe('Extra canada', function() { var result = addresser.parseAddress('310 8 Street SW, Calgary, Alberta T2P 3P3, Canada'); expect(result.streetNumber).to.equal("310"); expect(result.streetName).to.equal("8"); - expect(result.streetSuffix).to.equal("St"); + expect(result.streetSuffix).to.equal("Street"); expect(result.streetDirection).to.equal("SW"); - expect(result.addressLine1).to.equal("310 8 St SW"); + expect(result.addressLine1).to.equal("310 8 Street SW"); expect(result.hasOwnProperty("addressLine2")).to.equal(false); expect(result.placeName).to.equal("Calgary"); expect(result.stateAbbreviation).to.equal("AB"); @@ -965,9 +965,9 @@ describe('Extra canada', function() { var result = addresser.parseAddress('310 8 Street N, Calgary, Alberta T2P 3P3, Canada'); expect(result.streetNumber).to.equal("310"); expect(result.streetName).to.equal("8"); - expect(result.streetSuffix).to.equal("St"); + expect(result.streetSuffix).to.equal("Street"); expect(result.streetDirection).to.equal("N"); - expect(result.addressLine1).to.equal("310 8 St N"); + expect(result.addressLine1).to.equal("310 8 Street N"); expect(result.hasOwnProperty("addressLine2")).to.equal(false); expect(result.placeName).to.equal("Calgary"); expect(result.stateAbbreviation).to.equal("AB"); @@ -980,9 +980,9 @@ describe('Extra canada', function() { var result = addresser.parseAddress('310 8 Street North, Calgary, Alberta T2P 3P3, Canada'); expect(result.streetNumber).to.equal("310"); expect(result.streetName).to.equal("8"); - expect(result.streetSuffix).to.equal("St"); + expect(result.streetSuffix).to.equal("Street"); expect(result.streetDirection).to.equal("N"); - expect(result.addressLine1).to.equal("310 8 St N"); + expect(result.addressLine1).to.equal("310 8 Street N"); expect(result.hasOwnProperty("addressLine2")).to.equal(false); expect(result.placeName).to.equal("Calgary"); expect(result.stateAbbreviation).to.equal("AB"); @@ -995,9 +995,9 @@ describe('Extra canada', function() { var result = addresser.parseAddress('310 8 Street Southwest, Calgary, Alberta T2P 3P3, Canada'); expect(result.streetNumber).to.equal("310"); expect(result.streetName).to.equal("8"); - expect(result.streetSuffix).to.equal("St"); + expect(result.streetSuffix).to.equal("Street"); expect(result.streetDirection).to.equal("SW"); - expect(result.addressLine1).to.equal("310 8 St SW"); + expect(result.addressLine1).to.equal("310 8 Street SW"); expect(result.hasOwnProperty("addressLine2")).to.equal(false); expect(result.placeName).to.equal("Calgary"); expect(result.stateAbbreviation).to.equal("AB"); @@ -1010,9 +1010,9 @@ describe('Extra canada', function() { var result = addresser.parseAddress('310 8 Street Southwest, Calgary, Alberta, Canada'); expect(result.streetNumber).to.equal("310"); expect(result.streetName).to.equal("8"); - expect(result.streetSuffix).to.equal("St"); + expect(result.streetSuffix).to.equal("Street"); expect(result.streetDirection).to.equal("SW"); - expect(result.addressLine1).to.equal("310 8 St SW"); + expect(result.addressLine1).to.equal("310 8 Street SW"); expect(result.hasOwnProperty("addressLine2")).to.equal(false); expect(result.placeName).to.equal("Calgary"); expect(result.stateAbbreviation).to.equal("AB");