@mailwoman/codex 8.0.0 → 8.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/address-system-conventions.ts +7 -1
- package/au/delivery-service.ts +34 -12
- package/au/level-designator.ts +38 -14
- package/au/postcode.ts +9 -3
- package/au/state.ts +9 -3
- package/ca/postal-code.ts +10 -3
- package/ca/province.ts +23 -9
- package/ca/street-type.ts +9 -5
- package/country/country.ts +14 -8
- package/country/official-languages.ts +12 -4
- package/country/reference-data.ts +7 -3
- package/country/reference.ts +1 -1
- package/country/subdivision.ts +19 -8
- package/de/bundesland.ts +19 -6
- package/de/postleitzahl.ts +21 -7
- package/de/street-type.ts +14 -3
- package/fr/cedex.ts +15 -5
- package/fr/code-postal.ts +17 -4
- package/fr/departement.ts +18 -6
- package/fr/region.ts +23 -9
- package/fr/voie.ts +8 -4
- package/gb/country.ts +25 -9
- package/gb/postcode-area.ts +6 -2
- package/gb/postcode.ts +10 -3
- package/gb/street-type.ts +4 -2
- package/index.ts +1 -0
- package/jp/address-unit.ts +8 -4
- package/jp/postal-code.ts +7 -3
- package/jp/prefecture.ts +27 -10
- package/level-semantics.ts +55 -19
- package/nz/delivery-service.ts +43 -15
- package/nz/postcode.ts +9 -3
- package/out/address-system-conventions.d.ts +7 -1
- package/out/address-system-conventions.d.ts.map +1 -1
- package/out/address-system-conventions.js +7 -1
- package/out/address-system-conventions.js.map +1 -1
- package/out/au/delivery-service.d.ts +30 -10
- package/out/au/delivery-service.d.ts.map +1 -1
- package/out/au/delivery-service.js +7 -3
- package/out/au/delivery-service.js.map +1 -1
- package/out/au/level-designator.d.ts +27 -9
- package/out/au/level-designator.d.ts.map +1 -1
- package/out/au/level-designator.js +10 -6
- package/out/au/level-designator.js.map +1 -1
- package/out/au/postcode.d.ts +9 -3
- package/out/au/postcode.d.ts.map +1 -1
- package/out/au/postcode.js +9 -3
- package/out/au/postcode.js.map +1 -1
- package/out/au/state.d.ts +9 -3
- package/out/au/state.d.ts.map +1 -1
- package/out/au/state.js +6 -2
- package/out/au/state.js.map +1 -1
- package/out/ca/postal-code.d.ts +3 -1
- package/out/ca/postal-code.d.ts.map +1 -1
- package/out/ca/postal-code.js +9 -3
- package/out/ca/postal-code.js.map +1 -1
- package/out/ca/province.d.ts +18 -6
- package/out/ca/province.d.ts.map +1 -1
- package/out/ca/province.js +8 -4
- package/out/ca/province.js.map +1 -1
- package/out/ca/street-type.d.ts.map +1 -1
- package/out/ca/street-type.js +9 -5
- package/out/ca/street-type.js.map +1 -1
- package/out/country/country.d.ts +11 -7
- package/out/country/country.d.ts.map +1 -1
- package/out/country/country.js +7 -4
- package/out/country/country.js.map +1 -1
- package/out/country/official-languages.d.ts +12 -4
- package/out/country/official-languages.d.ts.map +1 -1
- package/out/country/official-languages.js +3 -1
- package/out/country/official-languages.js.map +1 -1
- package/out/country/reference-data.d.ts +6 -2
- package/out/country/reference-data.d.ts.map +1 -1
- package/out/country/reference-data.js +4 -2
- package/out/country/reference-data.js.map +1 -1
- package/out/country/reference.js +1 -1
- package/out/country/reference.js.map +1 -1
- package/out/country/subdivision.d.ts +12 -4
- package/out/country/subdivision.d.ts.map +1 -1
- package/out/country/subdivision.js +6 -4
- package/out/country/subdivision.js.map +1 -1
- package/out/de/bundesland.d.ts +18 -6
- package/out/de/bundesland.d.ts.map +1 -1
- package/out/de/bundesland.js +3 -1
- package/out/de/bundesland.js.map +1 -1
- package/out/de/postleitzahl.d.ts +21 -7
- package/out/de/postleitzahl.d.ts.map +1 -1
- package/out/de/postleitzahl.js +9 -3
- package/out/de/postleitzahl.js.map +1 -1
- package/out/de/street-type.d.ts +5 -4
- package/out/de/street-type.d.ts.map +1 -1
- package/out/de/street-type.js +10 -2
- package/out/de/street-type.js.map +1 -1
- package/out/fr/cedex.d.ts +15 -5
- package/out/fr/cedex.d.ts.map +1 -1
- package/out/fr/cedex.js +6 -2
- package/out/fr/cedex.js.map +1 -1
- package/out/fr/code-postal.d.ts +8 -11
- package/out/fr/code-postal.d.ts.map +1 -1
- package/out/fr/code-postal.js +24 -4
- package/out/fr/code-postal.js.map +1 -1
- package/out/fr/departement.d.ts +18 -6
- package/out/fr/departement.d.ts.map +1 -1
- package/out/fr/departement.js +3 -1
- package/out/fr/departement.js.map +1 -1
- package/out/fr/region.d.ts +18 -6
- package/out/fr/region.d.ts.map +1 -1
- package/out/fr/region.js +11 -5
- package/out/fr/region.js.map +1 -1
- package/out/fr/voie.d.ts +3 -1
- package/out/fr/voie.d.ts.map +1 -1
- package/out/fr/voie.js +3 -3
- package/out/fr/voie.js.map +1 -1
- package/out/gb/country.d.ts +18 -6
- package/out/gb/country.d.ts.map +1 -1
- package/out/gb/country.js +13 -5
- package/out/gb/country.js.map +1 -1
- package/out/gb/postcode-area.d.ts.map +1 -1
- package/out/gb/postcode-area.js +6 -2
- package/out/gb/postcode-area.js.map +1 -1
- package/out/gb/postcode.d.ts +3 -11
- package/out/gb/postcode.d.ts.map +1 -1
- package/out/gb/postcode.js +19 -3
- package/out/gb/postcode.js.map +1 -1
- package/out/gb/street-type.d.ts +3 -1
- package/out/gb/street-type.d.ts.map +1 -1
- package/out/gb/street-type.js +1 -1
- package/out/gb/street-type.js.map +1 -1
- package/out/index.d.ts.map +1 -1
- package/out/index.js.map +1 -1
- package/out/jp/address-unit.d.ts +6 -2
- package/out/jp/address-unit.d.ts.map +1 -1
- package/out/jp/address-unit.js +2 -2
- package/out/jp/address-unit.js.map +1 -1
- package/out/jp/postal-code.d.ts +6 -2
- package/out/jp/postal-code.d.ts.map +1 -1
- package/out/jp/postal-code.js +7 -3
- package/out/jp/postal-code.js.map +1 -1
- package/out/jp/prefecture.d.ts +24 -8
- package/out/jp/prefecture.d.ts.map +1 -1
- package/out/jp/prefecture.js +5 -3
- package/out/jp/prefecture.js.map +1 -1
- package/out/level-semantics.d.ts +48 -16
- package/out/level-semantics.d.ts.map +1 -1
- package/out/level-semantics.js +34 -12
- package/out/level-semantics.js.map +1 -1
- package/out/nz/delivery-service.d.ts +39 -13
- package/out/nz/delivery-service.d.ts.map +1 -1
- package/out/nz/delivery-service.js +16 -6
- package/out/nz/delivery-service.js.map +1 -1
- package/out/nz/postcode.d.ts +9 -3
- package/out/nz/postcode.d.ts.map +1 -1
- package/out/nz/postcode.js +9 -3
- package/out/nz/postcode.js.map +1 -1
- package/out/postcode-systems.d.ts +3 -1
- package/out/postcode-systems.d.ts.map +1 -1
- package/out/postcode-systems.js +1 -1
- package/out/postcode-systems.js.map +1 -1
- package/out/tools/build-country-surface-lexicon.js +26 -12
- package/out/tools/build-country-surface-lexicon.js.map +1 -1
- package/out/tools/export-country-surfaces.js.map +1 -1
- package/out/tools/generate-country-reference.d.ts +12 -4
- package/out/tools/generate-country-reference.d.ts.map +1 -1
- package/out/tools/generate-country-reference.js +10 -8
- package/out/tools/generate-country-reference.js.map +1 -1
- package/out/tools/generate-official-languages.d.ts +18 -6
- package/out/tools/generate-official-languages.d.ts.map +1 -1
- package/out/tools/generate-official-languages.js +9 -7
- package/out/tools/generate-official-languages.js.map +1 -1
- package/out/us/floor-designator.d.ts +15 -5
- package/out/us/floor-designator.d.ts.map +1 -1
- package/out/us/floor-designator.js +3 -1
- package/out/us/floor-designator.js.map +1 -1
- package/out/us/military-address.d.ts +36 -12
- package/out/us/military-address.d.ts.map +1 -1
- package/out/us/military-address.js +26 -15
- package/out/us/military-address.js.map +1 -1
- package/out/us/po-box.d.ts +9 -3
- package/out/us/po-box.d.ts.map +1 -1
- package/out/us/po-box.js +4 -2
- package/out/us/po-box.js.map +1 -1
- package/out/us/state.d.ts +6 -2
- package/out/us/state.d.ts.map +1 -1
- package/out/us/state.js +3 -1
- package/out/us/state.js.map +1 -1
- package/out/us/street-directional.d.ts +12 -3
- package/out/us/street-directional.d.ts.map +1 -1
- package/out/us/street-directional.js +8 -3
- package/out/us/street-directional.js.map +1 -1
- package/out/us/street-suffix.d.ts +24 -8
- package/out/us/street-suffix.d.ts.map +1 -1
- package/out/us/street-suffix.js +7 -3
- package/out/us/street-suffix.js.map +1 -1
- package/out/us/unit-designator.d.ts +24 -8
- package/out/us/unit-designator.d.ts.map +1 -1
- package/out/us/unit-designator.js +3 -1
- package/out/us/unit-designator.js.map +1 -1
- package/package.json +2 -2
- package/postcode-systems.ts +4 -2
- package/tools/build-country-surface-lexicon.ts +30 -12
- package/tools/export-country-surfaces.ts +2 -0
- package/tools/generate-country-reference.ts +27 -13
- package/tools/generate-official-languages.ts +27 -12
- package/us/floor-designator.ts +15 -5
- package/us/military-address.ts +53 -24
- package/us/po-box.ts +13 -5
- package/us/state.ts +6 -2
- package/us/street-directional.ts +14 -5
- package/us/street-suffix.ts +27 -9
- package/us/unit-designator.ts +25 -8
package/us/military-address.ts
CHANGED
|
@@ -33,16 +33,22 @@
|
|
|
33
33
|
* @see {@link https://pe.usps.com/text/pub28/28apb_001.htm USPS Pub 28 Appendix B — Armed Forces Addresses}
|
|
34
34
|
*/
|
|
35
35
|
|
|
36
|
-
/**
|
|
36
|
+
/**
|
|
37
|
+
* USPS military / diplomatic post-office location codes (the "city" substitute on the city line).
|
|
38
|
+
*/
|
|
37
39
|
export const US_MILITARY_POST_OFFICE_CODES = [
|
|
38
40
|
/**
|
|
39
41
|
* Army Post Office — domestic USPS gateway for Army and Air Force overseas mail; also used for some diplomatic
|
|
40
42
|
* addresses (DPO is preferred for State Dept posts since 2011).
|
|
41
43
|
*/
|
|
42
44
|
{ code: "APO", name: "Army Post Office", armedForces: true },
|
|
43
|
-
/**
|
|
45
|
+
/**
|
|
46
|
+
* Fleet Post Office — Navy ships and shore installations.
|
|
47
|
+
*/
|
|
44
48
|
{ code: "FPO", name: "Fleet Post Office", armedForces: true },
|
|
45
|
-
/**
|
|
49
|
+
/**
|
|
50
|
+
* Diplomatic Post Office — US embassies and missions (added 2011).
|
|
51
|
+
*/
|
|
46
52
|
{ code: "DPO", name: "Diplomatic Post Office", armedForces: false },
|
|
47
53
|
] as const
|
|
48
54
|
|
|
@@ -96,20 +102,32 @@ export const US_MILITARY_UNIT_DESIGNATORS = [
|
|
|
96
102
|
|
|
97
103
|
export type USMilitaryUnitDesignatorCode = (typeof US_MILITARY_UNIT_DESIGNATORS)[number]["code"]
|
|
98
104
|
|
|
99
|
-
/**
|
|
105
|
+
/**
|
|
106
|
+
* Result of a military address line parse (the unit line: PSC/CMR/UNIT).
|
|
107
|
+
*/
|
|
100
108
|
export interface USMilitaryUnitMatch {
|
|
101
|
-
/**
|
|
109
|
+
/**
|
|
110
|
+
* The designator as it appeared ("PSC", "CMR", "Unit").
|
|
111
|
+
*/
|
|
102
112
|
matched: string
|
|
103
|
-
/**
|
|
113
|
+
/**
|
|
114
|
+
* The canonical designator code ("PSC", "CMR", "UNIT").
|
|
115
|
+
*/
|
|
104
116
|
code: USMilitaryUnitDesignatorCode
|
|
105
|
-
/**
|
|
117
|
+
/**
|
|
118
|
+
* The installation identifier ("1520", "453").
|
|
119
|
+
*/
|
|
106
120
|
id: string
|
|
107
|
-
/**
|
|
121
|
+
/**
|
|
122
|
+
* The box number when present ("4620", "1234A").
|
|
123
|
+
*/
|
|
108
124
|
box?: string
|
|
109
125
|
}
|
|
110
126
|
|
|
111
|
-
|
|
112
|
-
|
|
127
|
+
/**
|
|
128
|
+
* Unit-line regex: PSC/CMR/UNIT <id> [BOX <box>] Identifiers are numeric; box numbers are alphanumeric. UNIT may stand
|
|
129
|
+
* without BOX.
|
|
130
|
+
*/
|
|
113
131
|
const UNIT_LINE_RE = /^\s*(psc|cmr|unit)\s+(\d+)(?:\s+box\s+([\dA-Za-z]+))?\s*$/i
|
|
114
132
|
|
|
115
133
|
/**
|
|
@@ -137,7 +155,9 @@ export function matchMilitaryUnitLine(input: unknown): USMilitaryUnitMatch | nul
|
|
|
137
155
|
return { matched: m[1]!, code, id, ...(box ? { box } : {}) }
|
|
138
156
|
}
|
|
139
157
|
|
|
140
|
-
/**
|
|
158
|
+
/**
|
|
159
|
+
* Type-predicate: does the input look like a USPS military unit line (PSC/CMR/UNIT)?
|
|
160
|
+
*/
|
|
141
161
|
export function isMilitaryUnitLine(input: unknown): boolean {
|
|
142
162
|
try {
|
|
143
163
|
return matchMilitaryUnitLine(input) !== null
|
|
@@ -146,13 +166,21 @@ export function isMilitaryUnitLine(input: unknown): boolean {
|
|
|
146
166
|
}
|
|
147
167
|
}
|
|
148
168
|
|
|
149
|
-
/**
|
|
169
|
+
/**
|
|
170
|
+
* Result of a military city-line parse (APO/FPO/DPO + region code + ZIP).
|
|
171
|
+
*/
|
|
150
172
|
export interface USMilitaryCityMatch {
|
|
151
|
-
/**
|
|
173
|
+
/**
|
|
174
|
+
* The post-office code as it appeared ("APO", "FPO", "DPO").
|
|
175
|
+
*/
|
|
152
176
|
matched: string
|
|
153
|
-
/**
|
|
177
|
+
/**
|
|
178
|
+
* The canonical post-office code.
|
|
179
|
+
*/
|
|
154
180
|
code: USMilitaryPostOfficeCode
|
|
155
|
-
/**
|
|
181
|
+
/**
|
|
182
|
+
* The Armed Forces region code ("AA", "AE", "AP").
|
|
183
|
+
*/
|
|
156
184
|
region: USArmedForcesRegionCode
|
|
157
185
|
/**
|
|
158
186
|
* The 5-digit or 9-digit ZIP code. Typical ranges per Pub 28: 09xxx (AE), 34xxx (AA), 96xxx (AP) — range validation
|
|
@@ -161,14 +189,13 @@ export interface USMilitaryCityMatch {
|
|
|
161
189
|
zip: string
|
|
162
190
|
}
|
|
163
191
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
// co-validation is operational policy, not structural syntax).
|
|
192
|
+
/**
|
|
193
|
+
* City-line regex: APO/FPO/DPO <region> <zip> USPS military ZIP assignment per Pub 28 and the Armed Forces zip code
|
|
194
|
+
* list: - AA (Americas): 340xx range - AE (Europe/ME/Africa/Canada): 09xxx range - AP (Pacific): 962xx-966xx range The
|
|
195
|
+
* regex accepts any 5-digit or 9-digit ZIP code in combination with a valid region code — validating the specific
|
|
196
|
+
* numeric range for each region is left to the caller (region+ZIP co-validation is operational policy, not structural
|
|
197
|
+
* syntax).
|
|
198
|
+
*/
|
|
172
199
|
const CITY_LINE_RE = /^\s*(apo|fpo|dpo)\s+(aa|ae|ap)\s+(\d{5}(?:-\d{4})?)\s*$/i
|
|
173
200
|
|
|
174
201
|
/**
|
|
@@ -193,7 +220,9 @@ export function matchMilitaryCityLine(input: unknown): USMilitaryCityMatch | nul
|
|
|
193
220
|
}
|
|
194
221
|
}
|
|
195
222
|
|
|
196
|
-
/**
|
|
223
|
+
/**
|
|
224
|
+
* Type-predicate: does the input look like a USPS military city line (APO/FPO/DPO + region + ZIP)?
|
|
225
|
+
*/
|
|
197
226
|
export function isMilitaryCityLine(input: unknown): boolean {
|
|
198
227
|
return matchMilitaryCityLine(input) !== null
|
|
199
228
|
}
|
package/us/po-box.ts
CHANGED
|
@@ -30,8 +30,10 @@ export const US_PO_BOX_DESIGNATORS = [
|
|
|
30
30
|
|
|
31
31
|
export type USPoBoxDesignator = (typeof US_PO_BOX_DESIGNATORS)[number]
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
/**
|
|
34
|
+
* Matches a leading PO-box designator + its identifier. Allows "P.O. Box", "PO BOX", "Post Office Box", "Box 12-A",
|
|
35
|
+
* etc. The id is alphanumeric with optional dashes (USPS caller/firm ids exist).
|
|
36
|
+
*/
|
|
35
37
|
const PO_BOX_RE =
|
|
36
38
|
/^\s*(?:(p\.?\s*o\.?\s*box)|(post\s+office\s+box)|(firm\s+caller)|(caller)|(drawer)|(lockbox)|(box))\s*#?\s*([\dA-Za-z][\dA-Za-z-]*)\s*$/i
|
|
37
39
|
|
|
@@ -44,11 +46,17 @@ export function isPOBox(input: unknown): boolean {
|
|
|
44
46
|
return typeof input === "string" && PO_BOX_RE.test(input)
|
|
45
47
|
}
|
|
46
48
|
|
|
47
|
-
/**
|
|
49
|
+
/**
|
|
50
|
+
* Result of a PO-box parse: the matched designator phrase and the box identifier.
|
|
51
|
+
*/
|
|
48
52
|
export interface PoBoxMatch {
|
|
49
|
-
/**
|
|
53
|
+
/**
|
|
54
|
+
* The designator phrase as it appeared, e.g. "P.O. Box", "Post Office Box".
|
|
55
|
+
*/
|
|
50
56
|
matched: string
|
|
51
|
-
/**
|
|
57
|
+
/**
|
|
58
|
+
* The box identifier, e.g. "123", "12-A".
|
|
59
|
+
*/
|
|
52
60
|
id: string
|
|
53
61
|
}
|
|
54
62
|
|
package/us/state.ts
CHANGED
|
@@ -75,7 +75,9 @@ export const US_STATE_ABBREVIATIONS = [
|
|
|
75
75
|
"AS",
|
|
76
76
|
] as const satisfies readonly string[]
|
|
77
77
|
|
|
78
|
-
/**
|
|
78
|
+
/**
|
|
79
|
+
* A USPS two-letter state-or-territory abbreviation.
|
|
80
|
+
*/
|
|
79
81
|
export type USStateAbbreviation = (typeof US_STATE_ABBREVIATIONS)[number]
|
|
80
82
|
|
|
81
83
|
const STATE_ABBREVIATION_SET: ReadonlySet<string> = new Set(US_STATE_ABBREVIATIONS)
|
|
@@ -152,5 +154,7 @@ export const US_STATE_BY_ABBREVIATION = {
|
|
|
152
154
|
AS: "American Samoa",
|
|
153
155
|
} as const satisfies Record<USStateAbbreviation, string>
|
|
154
156
|
|
|
155
|
-
/**
|
|
157
|
+
/**
|
|
158
|
+
* The full state/territory names, derived from {@link US_STATE_BY_ABBREVIATION}.
|
|
159
|
+
*/
|
|
156
160
|
export const US_STATE_NAMES: readonly string[] = Object.values(US_STATE_BY_ABBREVIATION)
|
package/us/street-directional.ts
CHANGED
|
@@ -29,7 +29,9 @@ export const DirectionalAbbreviation = {
|
|
|
29
29
|
|
|
30
30
|
export type DirectionalAbbreviation = (typeof DirectionalAbbreviation)[keyof typeof DirectionalAbbreviation]
|
|
31
31
|
|
|
32
|
-
/**
|
|
32
|
+
/**
|
|
33
|
+
* The 8 directional names accepted by the USPS (intercardinals spaced, per the publication).
|
|
34
|
+
*/
|
|
33
35
|
export const DirectionalNames = [
|
|
34
36
|
"NORTH",
|
|
35
37
|
"EAST",
|
|
@@ -43,6 +45,9 @@ export const DirectionalNames = [
|
|
|
43
45
|
|
|
44
46
|
export type DirectionalName = (typeof DirectionalNames)[number]
|
|
45
47
|
|
|
48
|
+
/**
|
|
49
|
+
* Surface forms a US directional can take (`N`, `N.`, `North`), for both parsing and formatting.
|
|
50
|
+
*/
|
|
46
51
|
export const DirectionalNameVariations = [
|
|
47
52
|
...DirectionalNames,
|
|
48
53
|
// Without spaces (the common US street form: "Northeast Main St")…
|
|
@@ -143,7 +148,7 @@ export function lookupDirectionalAbbreviation(input: unknown): DirectionalAbbrev
|
|
|
143
148
|
|
|
144
149
|
return (
|
|
145
150
|
DirectionalToAbbreviationMap.get(input) ||
|
|
146
|
-
DirectionalToAbbreviationMap.get(input.trim().toUpperCase().
|
|
151
|
+
DirectionalToAbbreviationMap.get(input.trim().toUpperCase().replaceAll(/\s+/g, " ")) ||
|
|
147
152
|
null
|
|
148
153
|
)
|
|
149
154
|
}
|
|
@@ -152,9 +157,13 @@ export function lookupDirectionalAbbreviation(input: unknown): DirectionalAbbrev
|
|
|
152
157
|
* Result of a directional lookup: the canonical full name + its preferred abbreviation.
|
|
153
158
|
*/
|
|
154
159
|
export interface DirectionalMatch {
|
|
155
|
-
/**
|
|
160
|
+
/**
|
|
161
|
+
* The matched directional name, e.g. "NORTH", "NORTH EAST".
|
|
162
|
+
*/
|
|
156
163
|
directional: DirectionalName
|
|
157
|
-
/**
|
|
164
|
+
/**
|
|
165
|
+
* The corresponding USPS abbreviation, e.g. "N", "NE".
|
|
166
|
+
*/
|
|
158
167
|
abbreviation: DirectionalAbbreviation
|
|
159
168
|
}
|
|
160
169
|
|
|
@@ -207,7 +216,7 @@ export function renderDirectional(
|
|
|
207
216
|
form: "abbr" | "full",
|
|
208
217
|
reference: string
|
|
209
218
|
): string {
|
|
210
|
-
const target = form === "abbr" ? match.abbreviation : match.canonical.
|
|
219
|
+
const target = form === "abbr" ? match.abbreviation : match.canonical.replaceAll(/\s+/g, "")
|
|
211
220
|
|
|
212
221
|
return matchCase(target, reference)
|
|
213
222
|
}
|
package/us/street-suffix.ts
CHANGED
|
@@ -228,7 +228,9 @@ export const US_STREET_SUFFIX_VARIANTS = {
|
|
|
228
228
|
WELLS: ["WLS"],
|
|
229
229
|
} as const satisfies Record<string, readonly string[]>
|
|
230
230
|
|
|
231
|
-
/**
|
|
231
|
+
/**
|
|
232
|
+
* Canonical USPS suffix (full word, uppercase per the publication).
|
|
233
|
+
*/
|
|
232
234
|
export type USStreetSuffix = keyof typeof US_STREET_SUFFIX_VARIANTS
|
|
233
235
|
|
|
234
236
|
/**
|
|
@@ -254,7 +256,9 @@ export const US_STREET_SUFFIX_LOOKUP: ReadonlyMap<string, USStreetSuffix> = (()
|
|
|
254
256
|
return out
|
|
255
257
|
})()
|
|
256
258
|
|
|
257
|
-
/**
|
|
259
|
+
/**
|
|
260
|
+
* Preferred USPS abbreviation per canonical (`AVENUE → "AVE"`, `STREET → "ST"`).
|
|
261
|
+
*/
|
|
258
262
|
export const US_STREET_SUFFIX_PREFERRED_ABBR: Readonly<Record<USStreetSuffix, string>> = Object.fromEntries(
|
|
259
263
|
(Object.keys(US_STREET_SUFFIX_VARIANTS) as USStreetSuffix[]).map((k) => [k, US_STREET_SUFFIX_VARIANTS[k][0]])
|
|
260
264
|
) as Readonly<Record<USStreetSuffix, string>>
|
|
@@ -285,7 +289,7 @@ export function matchTrailingSuffix(street: string): { canonical: USStreetSuffix
|
|
|
285
289
|
|
|
286
290
|
if (!trimmed) return null
|
|
287
291
|
const parts = trimmed.split(/\s+/)
|
|
288
|
-
const last = parts
|
|
292
|
+
const last = parts.at(-1)!
|
|
289
293
|
const canonical = US_STREET_SUFFIX_LOOKUP.get(last.toLowerCase())
|
|
290
294
|
|
|
291
295
|
if (!canonical) return null
|
|
@@ -297,6 +301,7 @@ export function matchTrailingSuffix(street: string): { canonical: USStreetSuffix
|
|
|
297
301
|
* The USPS suffix record, under its original isp-nexus name. Aliases {@link US_STREET_SUFFIX_VARIANTS}.
|
|
298
302
|
*/
|
|
299
303
|
export const StreetSuffixAbbreviationRecord = US_STREET_SUFFIX_VARIANTS
|
|
304
|
+
|
|
300
305
|
export type StreetSuffixAbbreviationRecord = typeof US_STREET_SUFFIX_VARIANTS
|
|
301
306
|
|
|
302
307
|
/**
|
|
@@ -304,17 +309,27 @@ export type StreetSuffixAbbreviationRecord = typeof US_STREET_SUFFIX_VARIANTS
|
|
|
304
309
|
*/
|
|
305
310
|
export type StreetSuffix = USStreetSuffix
|
|
306
311
|
|
|
307
|
-
/**
|
|
312
|
+
/**
|
|
313
|
+
* A standardized USPS street suffix abbreviation (the preferred form), i.e. "ST", "AVE", "BLVD".
|
|
314
|
+
*/
|
|
308
315
|
export type USPSStandardSuffixAbbreviation = StreetSuffixAbbreviationRecord[StreetSuffix][0]
|
|
309
316
|
|
|
310
|
-
/**
|
|
317
|
+
/**
|
|
318
|
+
* Any USPS-recognized suffix variant or abbreviation.
|
|
319
|
+
*/
|
|
311
320
|
export type StreetSuffixAbbreviation = StreetSuffixAbbreviationRecord[StreetSuffix][number]
|
|
312
321
|
|
|
313
|
-
/**
|
|
322
|
+
/**
|
|
323
|
+
* Result of a successful USPS street suffix lookup.
|
|
324
|
+
*/
|
|
314
325
|
export interface StreetSuffixMatch<S extends StreetSuffix = StreetSuffix> {
|
|
315
|
-
/**
|
|
326
|
+
/**
|
|
327
|
+
* The matched canonical USPS street suffix, i.e. "STREET", "AVENUE".
|
|
328
|
+
*/
|
|
316
329
|
suffix: S
|
|
317
|
-
/**
|
|
330
|
+
/**
|
|
331
|
+
* The preferred USPS street suffix abbreviation, i.e. "ST", "AVE".
|
|
332
|
+
*/
|
|
318
333
|
abbreviation: StreetSuffixAbbreviationRecord[S][0]
|
|
319
334
|
}
|
|
320
335
|
|
|
@@ -323,6 +338,7 @@ export interface StreetSuffixMatch<S extends StreetSuffix = StreetSuffix> {
|
|
|
323
338
|
*/
|
|
324
339
|
export function lookupStreetSuffix<S extends StreetSuffix>(suffix: S): StreetSuffixMatch<S>
|
|
325
340
|
export function lookupStreetSuffix(input: string | null | undefined): StreetSuffixMatch | null
|
|
341
|
+
|
|
326
342
|
export function lookupStreetSuffix(input: string | null | undefined): StreetSuffixMatch | null {
|
|
327
343
|
if (!input || typeof input !== "string") return null
|
|
328
344
|
const suffix = US_STREET_SUFFIX_LOOKUP.get(input.trim().toLowerCase())
|
|
@@ -332,7 +348,9 @@ export function lookupStreetSuffix(input: string | null | undefined): StreetSuff
|
|
|
332
348
|
return { suffix, abbreviation: US_STREET_SUFFIX_VARIANTS[suffix][0] }
|
|
333
349
|
}
|
|
334
350
|
|
|
335
|
-
/**
|
|
351
|
+
/**
|
|
352
|
+
* Type-predicate: is the input a canonical USPS street suffix (uppercase full word, e.g. "STREET")?
|
|
353
|
+
*/
|
|
336
354
|
export function isStreetSuffix(input: unknown): input is StreetSuffix {
|
|
337
355
|
return typeof input === "string" && Object.hasOwn(US_STREET_SUFFIX_VARIANTS, input)
|
|
338
356
|
}
|
package/us/unit-designator.ts
CHANGED
|
@@ -62,7 +62,9 @@ export const US_UNIT_DESIGNATOR_VARIANTS = {
|
|
|
62
62
|
UPPER: ["UPPR"],
|
|
63
63
|
} as const satisfies Record<string, readonly string[]>
|
|
64
64
|
|
|
65
|
-
/**
|
|
65
|
+
/**
|
|
66
|
+
* Canonical USPS secondary unit designator (full word, uppercase per the publication).
|
|
67
|
+
*/
|
|
66
68
|
export type USUnitDesignator = keyof typeof US_UNIT_DESIGNATOR_VARIANTS
|
|
67
69
|
|
|
68
70
|
/**
|
|
@@ -86,7 +88,9 @@ export const US_UNIT_DESIGNATOR_LOOKUP: ReadonlyMap<string, USUnitDesignator> =
|
|
|
86
88
|
return out
|
|
87
89
|
})()
|
|
88
90
|
|
|
89
|
-
/**
|
|
91
|
+
/**
|
|
92
|
+
* Approved USPS abbreviation per canonical (`APARTMENT → "APT"`, `SUITE → "STE"`).
|
|
93
|
+
*/
|
|
90
94
|
export const US_UNIT_DESIGNATOR_PREFERRED_ABBR: Readonly<Record<USUnitDesignator, string>> = Object.fromEntries(
|
|
91
95
|
(Object.keys(US_UNIT_DESIGNATOR_VARIANTS) as USUnitDesignator[]).map((k) => [k, US_UNIT_DESIGNATOR_VARIANTS[k][0]])
|
|
92
96
|
) as Readonly<Record<USUnitDesignator, string>>
|
|
@@ -141,11 +145,17 @@ export function matchLeadingDesignator(unit: string): { canonical: USUnitDesigna
|
|
|
141
145
|
return { canonical, matched: first }
|
|
142
146
|
}
|
|
143
147
|
|
|
144
|
-
/**
|
|
148
|
+
/**
|
|
149
|
+
* Result of {@link matchLeadingDesignatorWithRange}: the leading designator plus its optional secondary range.
|
|
150
|
+
*/
|
|
145
151
|
export interface UnitDesignatorRangeMatch {
|
|
146
|
-
/**
|
|
152
|
+
/**
|
|
153
|
+
* The matched canonical designator, i.e. "APARTMENT", "SUITE".
|
|
154
|
+
*/
|
|
147
155
|
canonical: USUnitDesignator
|
|
148
|
-
/**
|
|
156
|
+
/**
|
|
157
|
+
* The designator's own matched surface form, i.e. "Apt".
|
|
158
|
+
*/
|
|
149
159
|
matched: string
|
|
150
160
|
/**
|
|
151
161
|
* The secondary range/identifier token immediately following the designator, i.e. "4B" in "Apt 4B". Undefined when
|
|
@@ -183,11 +193,17 @@ export function matchLeadingDesignatorWithRange(unit: string): UnitDesignatorRan
|
|
|
183
193
|
}
|
|
184
194
|
}
|
|
185
195
|
|
|
186
|
-
/**
|
|
196
|
+
/**
|
|
197
|
+
* Result of a successful USPS secondary-unit designator lookup.
|
|
198
|
+
*/
|
|
187
199
|
export interface UnitDesignatorMatch<D extends USUnitDesignator = USUnitDesignator> {
|
|
188
|
-
/**
|
|
200
|
+
/**
|
|
201
|
+
* The matched canonical designator, i.e. "APARTMENT", "SUITE".
|
|
202
|
+
*/
|
|
189
203
|
designator: D
|
|
190
|
-
/**
|
|
204
|
+
/**
|
|
205
|
+
* The approved USPS abbreviation, i.e. "APT", "STE".
|
|
206
|
+
*/
|
|
191
207
|
abbreviation: (typeof US_UNIT_DESIGNATOR_VARIANTS)[D][0]
|
|
192
208
|
}
|
|
193
209
|
|
|
@@ -197,6 +213,7 @@ export interface UnitDesignatorMatch<D extends USUnitDesignator = USUnitDesignat
|
|
|
197
213
|
*/
|
|
198
214
|
export function lookupUnitDesignator<D extends USUnitDesignator>(designator: D): UnitDesignatorMatch<D>
|
|
199
215
|
export function lookupUnitDesignator(input: string | null | undefined): UnitDesignatorMatch | null
|
|
216
|
+
|
|
200
217
|
export function lookupUnitDesignator(input: string | null | undefined): UnitDesignatorMatch | null {
|
|
201
218
|
if (!input || typeof input !== "string") return null
|
|
202
219
|
const designator = US_UNIT_DESIGNATOR_LOOKUP.get(input.trim().toLowerCase())
|