geodata-kit-postal 0.0.0-stage → 0.1.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/LICENSE +24 -0
- package/NOTICE +91 -0
- package/README.md +30 -2
- package/data/AD.json.gz +0 -0
- package/data/AE.json.gz +0 -0
- package/data/AI.json.gz +0 -0
- package/data/AL.json.gz +0 -0
- package/data/AM.json.gz +0 -0
- package/data/AR.json.gz +0 -0
- package/data/AS.json.gz +0 -0
- package/data/AT.json.gz +0 -0
- package/data/AU.json.gz +0 -0
- package/data/AX.json.gz +0 -0
- package/data/AZ.json.gz +0 -0
- package/data/BD.json.gz +0 -0
- package/data/BE.json.gz +0 -0
- package/data/BG.json.gz +0 -0
- package/data/BM.json.gz +0 -0
- package/data/BR.json.gz +0 -0
- package/data/BY.json.gz +0 -0
- package/data/CA.json.gz +0 -0
- package/data/CC.json.gz +0 -0
- package/data/CH.json.gz +0 -0
- package/data/CL.json.gz +0 -0
- package/data/CN.json.gz +0 -0
- package/data/CO.json.gz +0 -0
- package/data/CR.json.gz +0 -0
- package/data/CX.json.gz +0 -0
- package/data/CY.json.gz +0 -0
- package/data/CZ.json.gz +0 -0
- package/data/DE.json.gz +0 -0
- package/data/DK.json.gz +0 -0
- package/data/DO.json.gz +0 -0
- package/data/DZ.json.gz +0 -0
- package/data/EC.json.gz +0 -0
- package/data/EE.json.gz +0 -0
- package/data/ES.json.gz +0 -0
- package/data/FI.json.gz +0 -0
- package/data/FK.json.gz +0 -0
- package/data/FM.json.gz +0 -0
- package/data/FO.json.gz +0 -0
- package/data/FR.json.gz +0 -0
- package/data/GB.json.gz +0 -0
- package/data/GF.json.gz +0 -0
- package/data/GG.json.gz +0 -0
- package/data/GI.json.gz +0 -0
- package/data/GL.json.gz +0 -0
- package/data/GP.json.gz +0 -0
- package/data/GS.json.gz +0 -0
- package/data/GT.json.gz +0 -0
- package/data/GU.json.gz +0 -0
- package/data/HK.json.gz +0 -0
- package/data/HM.json.gz +0 -0
- package/data/HN.json.gz +0 -0
- package/data/HR.json.gz +0 -0
- package/data/HT.json.gz +0 -0
- package/data/HU.json.gz +0 -0
- package/data/ID.json.gz +0 -0
- package/data/IE.json.gz +0 -0
- package/data/IM.json.gz +0 -0
- package/data/IN.json.gz +0 -0
- package/data/IO.json.gz +0 -0
- package/data/IS.json.gz +0 -0
- package/data/IT.json.gz +0 -0
- package/data/JE.json.gz +0 -0
- package/data/JP.json.gz +0 -0
- package/data/KE.json.gz +0 -0
- package/data/KR.json.gz +0 -0
- package/data/LI.json.gz +0 -0
- package/data/LK.json.gz +0 -0
- package/data/LT.json.gz +0 -0
- package/data/LU.json.gz +0 -0
- package/data/LV.json.gz +0 -0
- package/data/MA.json.gz +0 -0
- package/data/MC.json.gz +0 -0
- package/data/MD.json.gz +0 -0
- package/data/MH.json.gz +0 -0
- package/data/MK.json.gz +0 -0
- package/data/MN.json.gz +0 -0
- package/data/MO.json.gz +0 -0
- package/data/MP.json.gz +0 -0
- package/data/MQ.json.gz +0 -0
- package/data/MT.json.gz +0 -0
- package/data/MW.json.gz +0 -0
- package/data/MX.json.gz +0 -0
- package/data/MY.json.gz +0 -0
- package/data/NC.json.gz +0 -0
- package/data/NF.json.gz +0 -0
- package/data/NL.json.gz +0 -0
- package/data/NO.json.gz +0 -0
- package/data/NR.json.gz +0 -0
- package/data/NU.json.gz +0 -0
- package/data/NZ.json.gz +0 -0
- package/data/PA.json.gz +0 -0
- package/data/PE.json.gz +0 -0
- package/data/PF.json.gz +0 -0
- package/data/PH.json.gz +0 -0
- package/data/PK.json.gz +0 -0
- package/data/PL.json.gz +0 -0
- package/data/PM.json.gz +0 -0
- package/data/PN.json.gz +0 -0
- package/data/PR.json.gz +0 -0
- package/data/PT.json.gz +0 -0
- package/data/PW.json.gz +0 -0
- package/data/PY.json.gz +0 -0
- package/data/RE.json.gz +0 -0
- package/data/RO.json.gz +0 -0
- package/data/RS.json.gz +0 -0
- package/data/RU.json.gz +0 -0
- package/data/SE.json.gz +0 -0
- package/data/SG.json.gz +0 -0
- package/data/SI.json.gz +0 -0
- package/data/SJ.json.gz +0 -0
- package/data/SK.json.gz +0 -0
- package/data/SM.json.gz +0 -0
- package/data/TC.json.gz +0 -0
- package/data/TH.json.gz +0 -0
- package/data/TR.json.gz +0 -0
- package/data/UA.json.gz +0 -0
- package/data/US.json.gz +0 -0
- package/data/UY.json.gz +0 -0
- package/data/VA.json.gz +0 -0
- package/data/VI.json.gz +0 -0
- package/data/WF.json.gz +0 -0
- package/data/WS.json.gz +0 -0
- package/data/YT.json.gz +0 -0
- package/data/ZA.json.gz +0 -0
- package/dist/index.cjs +123 -0
- package/dist/index.d.cts +32 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.js +88 -0
- package/package.json +51 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 geodata-kit contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
|
23
|
+
The code is MIT-licensed. The bundled data keeps the licences of its sources;
|
|
24
|
+
see NOTICE.
|
package/NOTICE
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
geodata-kit — third-party data notices
|
|
2
|
+
======================================
|
|
3
|
+
|
|
4
|
+
The code of geodata-kit is MIT-licensed (see LICENSE). The data shipped in
|
|
5
|
+
the packages was generated from the sources below and keeps their licences.
|
|
6
|
+
Every source, its download URL, size, SHA-256 and download date is listed in
|
|
7
|
+
data/meta.json of the repository.
|
|
8
|
+
|
|
9
|
+
GeoNames
|
|
10
|
+
Countries, subdivisions, cities, localities, alternate names, airports,
|
|
11
|
+
timezones per place and postal codes. Data from GeoNames (https://www.geonames.org),
|
|
12
|
+
licensed under Creative Commons Attribution 4.0 (CC BY 4.0,
|
|
13
|
+
https://creativecommons.org/licenses/by/4.0/). Modified: filtered,
|
|
14
|
+
re-keyed and combined with the other sources listed here.
|
|
15
|
+
|
|
16
|
+
Unicode CLDR
|
|
17
|
+
Country, language and subdivision names, currencies with dates, retired
|
|
18
|
+
codes, UN M49 regions, languages per country, likely locales, week and
|
|
19
|
+
measurement data. Copyright © 1991-2025 Unicode, Inc. Licensed under the
|
|
20
|
+
Unicode License v3 (https://www.unicode.org/license.txt):
|
|
21
|
+
|
|
22
|
+
UNICODE LICENSE V3
|
|
23
|
+
COPYRIGHT AND PERMISSION NOTICE
|
|
24
|
+
Copyright © 1991-2025 Unicode, Inc.
|
|
25
|
+
NOTICE TO USER: Carefully read the following legal agreement. BY
|
|
26
|
+
DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING DATA FILES, AND/OR
|
|
27
|
+
SOFTWARE, YOU UNEQUIVOCALLY ACCEPT, AND AGREE TO BE BOUND BY, ALL OF THE
|
|
28
|
+
TERMS AND CONDITIONS OF THIS AGREEMENT. IF YOU DO NOT AGREE, DO NOT
|
|
29
|
+
DOWNLOAD, INSTALL, COPY, DISTRIBUTE OR USE THE DATA FILES OR SOFTWARE.
|
|
30
|
+
Permission is hereby granted, free of charge, to any person obtaining a
|
|
31
|
+
copy of data files and any associated documentation (the "Data Files") or
|
|
32
|
+
software and any associated documentation (the "Software") to deal in the
|
|
33
|
+
Data Files or Software without restriction, including without limitation
|
|
34
|
+
the rights to use, copy, modify, merge, publish, distribute, and/or sell
|
|
35
|
+
copies of the Data Files or Software, and to permit persons to whom the
|
|
36
|
+
Data Files or Software are furnished to do so, provided that either (a)
|
|
37
|
+
this copyright and permission notice appear with all copies of the Data
|
|
38
|
+
Files or Software, or (b) this copyright and permission notice appear in
|
|
39
|
+
associated Documentation.
|
|
40
|
+
THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
|
41
|
+
KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
42
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
|
|
43
|
+
THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
|
|
44
|
+
INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
|
|
45
|
+
OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
|
46
|
+
USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
47
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
48
|
+
PERFORMANCE OF THE DATA FILES OR SOFTWARE.
|
|
49
|
+
Except as contained in this notice, the name of a copyright holder shall
|
|
50
|
+
not be used in advertising or otherwise to promote the sale, use or other
|
|
51
|
+
dealings in these Data Files or Software without prior written
|
|
52
|
+
authorization of the copyright holder.
|
|
53
|
+
|
|
54
|
+
IANA Time Zone Database
|
|
55
|
+
Timezone names, zones per country and legacy aliases, from the IANA Time
|
|
56
|
+
Zone Database (https://www.iana.org/time-zones), which is in the public domain.
|
|
57
|
+
|
|
58
|
+
Wikidata
|
|
59
|
+
Subdivision ISO 3166-2 ↔ GeoNames mapping, official languages of countries
|
|
60
|
+
and subdivisions, demonyms, calling codes, driving side. From Wikidata
|
|
61
|
+
(https://www.wikidata.org), dedicated to the public domain under CC0 1.0.
|
|
62
|
+
|
|
63
|
+
Natural Earth
|
|
64
|
+
Country and first-level subdivision polygons. Made with Natural Earth.
|
|
65
|
+
Free vector and raster map data @ naturalearthdata.com (public domain).
|
|
66
|
+
|
|
67
|
+
libphonenumber
|
|
68
|
+
Phone-number metadata, converted from PhoneNumberMetadata.xml.
|
|
69
|
+
Copyright (C) The Libphonenumber Authors. Licensed under the Apache
|
|
70
|
+
License, Version 2.0 (https://www.apache.org/licenses/LICENSE-2.0).
|
|
71
|
+
You may not use this data except in compliance with that License. Unless
|
|
72
|
+
required by applicable law or agreed to in writing, it is distributed on
|
|
73
|
+
an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND.
|
|
74
|
+
|
|
75
|
+
Google address metadata (libaddressinput)
|
|
76
|
+
Address formats, required fields, postal-code patterns and region lists.
|
|
77
|
+
Data from Google's libaddressinput project
|
|
78
|
+
(https://github.com/google/libaddressinput), licensed under CC BY 4.0.
|
|
79
|
+
Modified: merged with GeoNames postal formats.
|
|
80
|
+
|
|
81
|
+
European Union / EFTA
|
|
82
|
+
EU, Eurozone, Schengen, EEA and EFTA membership dates, compiled from
|
|
83
|
+
europa.eu (© European Union, CC BY 4.0) and efta.int. Modified.
|
|
84
|
+
|
|
85
|
+
geodata-kit-tz only
|
|
86
|
+
Timezone polygons from timezone-boundary-builder
|
|
87
|
+
(https://github.com/evansiroky/timezone-boundary-builder), based on data
|
|
88
|
+
© OpenStreetMap contributors, licensed under the Open Database License
|
|
89
|
+
(ODbL) 1.0 (https://opendatacommons.org/licenses/odbl/1-0/). The ODbL
|
|
90
|
+
applies to that data, not to the rest of geodata-kit. See LICENSE-DATA in
|
|
91
|
+
that package.
|
package/README.md
CHANGED
|
@@ -1,3 +1,31 @@
|
|
|
1
|
-
#
|
|
1
|
+
# geodata-kit-postal
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Postal code → place, and place → postal codes, for 124 countries. Node.js only.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npm install geodata-kit-postal
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import { findPlacesByPostalCode, findPostalCodes } from 'geodata-kit-postal';
|
|
11
|
+
|
|
12
|
+
await findPlacesByPostalCode('80331', 'DE'); // [{ name: 'München', … }]
|
|
13
|
+
await findPostalCodes({ city: 'Unterhaching', country: 'DE' }); // ['82008']
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Installed next to [geodata-kit](https://www.npmjs.com/package/geodata-kit), it
|
|
17
|
+
also lets `parseAddress` check the city against the postal code and fix typos.
|
|
18
|
+
For the UK, Canada and the Netherlands only the first part of the code is
|
|
19
|
+
known ("SW1A", "K1A", "1234").
|
|
20
|
+
|
|
21
|
+
## API
|
|
22
|
+
|
|
23
|
+
| Function | Returns |
|
|
24
|
+
|---|---|
|
|
25
|
+
| `findPlacesByPostalCode(code, country)` | async; places `{ postalCode, name, subdivisionName, subdivisionCode, subdivision2Name, subdivision3Name, lat, lng }`. Prefixes such as `D-` and spacing are ignored |
|
|
26
|
+
| `findPostalCodes({ city, country, subdivision? })` | async; postal codes of a place |
|
|
27
|
+
| `isKnownPostalCode(code, country)` | async; `true` / `false` |
|
|
28
|
+
| `listPostalCountries()` | the 124 countries with data |
|
|
29
|
+
| `foldName(text)` | the name folding used for matching |
|
|
30
|
+
|
|
31
|
+
MIT. Data from GeoNames (CC BY 4.0); see `NOTICE`.
|
package/data/AD.json.gz
ADDED
|
Binary file
|
package/data/AE.json.gz
ADDED
|
Binary file
|
package/data/AI.json.gz
ADDED
|
Binary file
|
package/data/AL.json.gz
ADDED
|
Binary file
|
package/data/AM.json.gz
ADDED
|
Binary file
|
package/data/AR.json.gz
ADDED
|
Binary file
|
package/data/AS.json.gz
ADDED
|
Binary file
|
package/data/AT.json.gz
ADDED
|
Binary file
|
package/data/AU.json.gz
ADDED
|
Binary file
|
package/data/AX.json.gz
ADDED
|
Binary file
|
package/data/AZ.json.gz
ADDED
|
Binary file
|
package/data/BD.json.gz
ADDED
|
Binary file
|
package/data/BE.json.gz
ADDED
|
Binary file
|
package/data/BG.json.gz
ADDED
|
Binary file
|
package/data/BM.json.gz
ADDED
|
Binary file
|
package/data/BR.json.gz
ADDED
|
Binary file
|
package/data/BY.json.gz
ADDED
|
Binary file
|
package/data/CA.json.gz
ADDED
|
Binary file
|
package/data/CC.json.gz
ADDED
|
Binary file
|
package/data/CH.json.gz
ADDED
|
Binary file
|
package/data/CL.json.gz
ADDED
|
Binary file
|
package/data/CN.json.gz
ADDED
|
Binary file
|
package/data/CO.json.gz
ADDED
|
Binary file
|
package/data/CR.json.gz
ADDED
|
Binary file
|
package/data/CX.json.gz
ADDED
|
Binary file
|
package/data/CY.json.gz
ADDED
|
Binary file
|
package/data/CZ.json.gz
ADDED
|
Binary file
|
package/data/DE.json.gz
ADDED
|
Binary file
|
package/data/DK.json.gz
ADDED
|
Binary file
|
package/data/DO.json.gz
ADDED
|
Binary file
|
package/data/DZ.json.gz
ADDED
|
Binary file
|
package/data/EC.json.gz
ADDED
|
Binary file
|
package/data/EE.json.gz
ADDED
|
Binary file
|
package/data/ES.json.gz
ADDED
|
Binary file
|
package/data/FI.json.gz
ADDED
|
Binary file
|
package/data/FK.json.gz
ADDED
|
Binary file
|
package/data/FM.json.gz
ADDED
|
Binary file
|
package/data/FO.json.gz
ADDED
|
Binary file
|
package/data/FR.json.gz
ADDED
|
Binary file
|
package/data/GB.json.gz
ADDED
|
Binary file
|
package/data/GF.json.gz
ADDED
|
Binary file
|
package/data/GG.json.gz
ADDED
|
Binary file
|
package/data/GI.json.gz
ADDED
|
Binary file
|
package/data/GL.json.gz
ADDED
|
Binary file
|
package/data/GP.json.gz
ADDED
|
Binary file
|
package/data/GS.json.gz
ADDED
|
Binary file
|
package/data/GT.json.gz
ADDED
|
Binary file
|
package/data/GU.json.gz
ADDED
|
Binary file
|
package/data/HK.json.gz
ADDED
|
Binary file
|
package/data/HM.json.gz
ADDED
|
Binary file
|
package/data/HN.json.gz
ADDED
|
Binary file
|
package/data/HR.json.gz
ADDED
|
Binary file
|
package/data/HT.json.gz
ADDED
|
Binary file
|
package/data/HU.json.gz
ADDED
|
Binary file
|
package/data/ID.json.gz
ADDED
|
Binary file
|
package/data/IE.json.gz
ADDED
|
Binary file
|
package/data/IM.json.gz
ADDED
|
Binary file
|
package/data/IN.json.gz
ADDED
|
Binary file
|
package/data/IO.json.gz
ADDED
|
Binary file
|
package/data/IS.json.gz
ADDED
|
Binary file
|
package/data/IT.json.gz
ADDED
|
Binary file
|
package/data/JE.json.gz
ADDED
|
Binary file
|
package/data/JP.json.gz
ADDED
|
Binary file
|
package/data/KE.json.gz
ADDED
|
Binary file
|
package/data/KR.json.gz
ADDED
|
Binary file
|
package/data/LI.json.gz
ADDED
|
Binary file
|
package/data/LK.json.gz
ADDED
|
Binary file
|
package/data/LT.json.gz
ADDED
|
Binary file
|
package/data/LU.json.gz
ADDED
|
Binary file
|
package/data/LV.json.gz
ADDED
|
Binary file
|
package/data/MA.json.gz
ADDED
|
Binary file
|
package/data/MC.json.gz
ADDED
|
Binary file
|
package/data/MD.json.gz
ADDED
|
Binary file
|
package/data/MH.json.gz
ADDED
|
Binary file
|
package/data/MK.json.gz
ADDED
|
Binary file
|
package/data/MN.json.gz
ADDED
|
Binary file
|
package/data/MO.json.gz
ADDED
|
Binary file
|
package/data/MP.json.gz
ADDED
|
Binary file
|
package/data/MQ.json.gz
ADDED
|
Binary file
|
package/data/MT.json.gz
ADDED
|
Binary file
|
package/data/MW.json.gz
ADDED
|
Binary file
|
package/data/MX.json.gz
ADDED
|
Binary file
|
package/data/MY.json.gz
ADDED
|
Binary file
|
package/data/NC.json.gz
ADDED
|
Binary file
|
package/data/NF.json.gz
ADDED
|
Binary file
|
package/data/NL.json.gz
ADDED
|
Binary file
|
package/data/NO.json.gz
ADDED
|
Binary file
|
package/data/NR.json.gz
ADDED
|
Binary file
|
package/data/NU.json.gz
ADDED
|
Binary file
|
package/data/NZ.json.gz
ADDED
|
Binary file
|
package/data/PA.json.gz
ADDED
|
Binary file
|
package/data/PE.json.gz
ADDED
|
Binary file
|
package/data/PF.json.gz
ADDED
|
Binary file
|
package/data/PH.json.gz
ADDED
|
Binary file
|
package/data/PK.json.gz
ADDED
|
Binary file
|
package/data/PL.json.gz
ADDED
|
Binary file
|
package/data/PM.json.gz
ADDED
|
Binary file
|
package/data/PN.json.gz
ADDED
|
Binary file
|
package/data/PR.json.gz
ADDED
|
Binary file
|
package/data/PT.json.gz
ADDED
|
Binary file
|
package/data/PW.json.gz
ADDED
|
Binary file
|
package/data/PY.json.gz
ADDED
|
Binary file
|
package/data/RE.json.gz
ADDED
|
Binary file
|
package/data/RO.json.gz
ADDED
|
Binary file
|
package/data/RS.json.gz
ADDED
|
Binary file
|
package/data/RU.json.gz
ADDED
|
Binary file
|
package/data/SE.json.gz
ADDED
|
Binary file
|
package/data/SG.json.gz
ADDED
|
Binary file
|
package/data/SI.json.gz
ADDED
|
Binary file
|
package/data/SJ.json.gz
ADDED
|
Binary file
|
package/data/SK.json.gz
ADDED
|
Binary file
|
package/data/SM.json.gz
ADDED
|
Binary file
|
package/data/TC.json.gz
ADDED
|
Binary file
|
package/data/TH.json.gz
ADDED
|
Binary file
|
package/data/TR.json.gz
ADDED
|
Binary file
|
package/data/UA.json.gz
ADDED
|
Binary file
|
package/data/US.json.gz
ADDED
|
Binary file
|
package/data/UY.json.gz
ADDED
|
Binary file
|
package/data/VA.json.gz
ADDED
|
Binary file
|
package/data/VI.json.gz
ADDED
|
Binary file
|
package/data/WF.json.gz
ADDED
|
Binary file
|
package/data/WS.json.gz
ADDED
|
Binary file
|
package/data/YT.json.gz
ADDED
|
Binary file
|
package/data/ZA.json.gz
ADDED
|
Binary file
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var src_exports = {};
|
|
22
|
+
__export(src_exports, {
|
|
23
|
+
findPlacesByPostalCode: () => findPlacesByPostalCode,
|
|
24
|
+
findPostalCodes: () => findPostalCodes,
|
|
25
|
+
foldName: () => foldName,
|
|
26
|
+
isKnownPostalCode: () => isKnownPostalCode,
|
|
27
|
+
listPostalCountries: () => listPostalCountries
|
|
28
|
+
});
|
|
29
|
+
module.exports = __toCommonJS(src_exports);
|
|
30
|
+
|
|
31
|
+
// ../../node_modules/tsup/assets/cjs_shims.js
|
|
32
|
+
var getImportMetaUrl = () => typeof document === "undefined" ? new URL(`file:${__filename}`).href : document.currentScript && document.currentScript.tagName.toUpperCase() === "SCRIPT" ? document.currentScript.src : new URL("main.js", document.baseURI).href;
|
|
33
|
+
var importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
|
|
34
|
+
|
|
35
|
+
// src/index.ts
|
|
36
|
+
var import_node_fs = require("fs");
|
|
37
|
+
var import_promises = require("fs/promises");
|
|
38
|
+
var import_node_zlib = require("zlib");
|
|
39
|
+
var DATA_DIR = new URL("../data/", importMetaUrl);
|
|
40
|
+
var cache = /* @__PURE__ */ new Map();
|
|
41
|
+
var compact = (code) => code.toUpperCase().replace(/[\s-]/g, "");
|
|
42
|
+
function foldName(text) {
|
|
43
|
+
const special = { "\xDF": "ss", "\u0142": "l", "\u0111": "d", "\xF0": "d", "\xF8": "o", "\xE6": "ae", "\u0153": "oe", "\xFE": "th", "\u0131": "i" };
|
|
44
|
+
let plain = "";
|
|
45
|
+
for (const character of text.replace(/['’ʻʼ`´]/g, "").normalize("NFKD").replace(/\p{M}/gu, "").toLowerCase()) {
|
|
46
|
+
plain += special[character] ?? character;
|
|
47
|
+
}
|
|
48
|
+
return plain.replace(/[^\p{L}\p{N}]+/gu, " ").trim().split(" ").filter(Boolean).map((word) => word === "saint" ? "st" : word === "sainte" ? "ste" : word).join(" ");
|
|
49
|
+
}
|
|
50
|
+
function load(country) {
|
|
51
|
+
const code = country.trim().toUpperCase();
|
|
52
|
+
let promise = cache.get(code);
|
|
53
|
+
if (!promise) {
|
|
54
|
+
promise = (async () => {
|
|
55
|
+
const file = new URL(`${code}.json.gz`, DATA_DIR);
|
|
56
|
+
if (!/^[A-Z]{2}$/.test(code) || !(0, import_node_fs.existsSync)(file)) return null;
|
|
57
|
+
const data = JSON.parse((0, import_node_zlib.gunzipSync)(await (0, import_promises.readFile)(file)).toString("utf8"));
|
|
58
|
+
const places = data.rows.map((row) => ({
|
|
59
|
+
postalCode: row[0],
|
|
60
|
+
name: row[1],
|
|
61
|
+
subdivisionName: row[2],
|
|
62
|
+
subdivisionCode: row[3],
|
|
63
|
+
subdivision2Name: row[4],
|
|
64
|
+
subdivision3Name: row[5],
|
|
65
|
+
lat: row[6],
|
|
66
|
+
lng: row[7]
|
|
67
|
+
}));
|
|
68
|
+
const byCode = /* @__PURE__ */ new Map();
|
|
69
|
+
for (const place of places) {
|
|
70
|
+
const key = compact(place.postalCode);
|
|
71
|
+
const list = byCode.get(key);
|
|
72
|
+
if (list) list.push(place);
|
|
73
|
+
else byCode.set(key, [place]);
|
|
74
|
+
}
|
|
75
|
+
return { places, byCode, codeLengths: [...new Set([...byCode.keys()].map((key) => key.length))].sort((a, b) => b - a) };
|
|
76
|
+
})();
|
|
77
|
+
cache.set(code, promise);
|
|
78
|
+
}
|
|
79
|
+
return promise;
|
|
80
|
+
}
|
|
81
|
+
function lookup(data, code) {
|
|
82
|
+
const key = compact(code.trim().replace(/^[A-Z]{1,3}-(?=\d)/i, "").replace(/^〒/, ""));
|
|
83
|
+
const exact = data.byCode.get(key);
|
|
84
|
+
if (exact) return exact;
|
|
85
|
+
for (const length of data.codeLengths) {
|
|
86
|
+
if (length >= key.length) continue;
|
|
87
|
+
const partial = data.byCode.get(key.slice(0, length));
|
|
88
|
+
if (partial) return partial;
|
|
89
|
+
}
|
|
90
|
+
return [];
|
|
91
|
+
}
|
|
92
|
+
async function findPlacesByPostalCode(code, country) {
|
|
93
|
+
const data = await load(country);
|
|
94
|
+
return data ? lookup(data, code).map((place) => ({ ...place })) : [];
|
|
95
|
+
}
|
|
96
|
+
async function isKnownPostalCode(code, country) {
|
|
97
|
+
return (await findPlacesByPostalCode(code, country)).length > 0;
|
|
98
|
+
}
|
|
99
|
+
async function findPostalCodes(options) {
|
|
100
|
+
const data = await load(options.country);
|
|
101
|
+
if (!data) return [];
|
|
102
|
+
const key = foldName(options.city);
|
|
103
|
+
const subdivision = options.subdivision ? foldName(options.subdivision) : null;
|
|
104
|
+
const codes = /* @__PURE__ */ new Set();
|
|
105
|
+
for (const place of data.places) {
|
|
106
|
+
if (foldName(place.name) !== key) continue;
|
|
107
|
+
if (subdivision && foldName(place.subdivisionName) !== subdivision && foldName(place.subdivisionCode) !== subdivision) continue;
|
|
108
|
+
codes.add(place.postalCode);
|
|
109
|
+
}
|
|
110
|
+
return [...codes].sort();
|
|
111
|
+
}
|
|
112
|
+
function listPostalCountries() {
|
|
113
|
+
if (!(0, import_node_fs.existsSync)(DATA_DIR)) return [];
|
|
114
|
+
return (0, import_node_fs.readdirSync)(DATA_DIR).filter((file) => file.endsWith(".json.gz")).map((file) => file.slice(0, 2)).sort();
|
|
115
|
+
}
|
|
116
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
117
|
+
0 && (module.exports = {
|
|
118
|
+
findPlacesByPostalCode,
|
|
119
|
+
findPostalCodes,
|
|
120
|
+
foldName,
|
|
121
|
+
isKnownPostalCode,
|
|
122
|
+
listPostalCountries
|
|
123
|
+
});
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
interface PostalPlace {
|
|
2
|
+
postalCode: string;
|
|
3
|
+
/** Place name as published by the postal service. */
|
|
4
|
+
name: string;
|
|
5
|
+
/** First-level subdivision name and code as used by the postal data (the code may differ from ISO 3166-2). */
|
|
6
|
+
subdivisionName: string;
|
|
7
|
+
subdivisionCode: string;
|
|
8
|
+
/** County / district names, where given. */
|
|
9
|
+
subdivision2Name: string;
|
|
10
|
+
subdivision3Name: string;
|
|
11
|
+
lat: number;
|
|
12
|
+
lng: number;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Same folding as geodata-kit's fold() (kept identical; a test checks it):
|
|
16
|
+
* lower case, no accents, no punctuation, "saint" → "st".
|
|
17
|
+
*/
|
|
18
|
+
declare function foldName(text: string): string;
|
|
19
|
+
/** Places with this postal code: ("80331", "DE") → München. Prefixes and spacing are ignored. */
|
|
20
|
+
declare function findPlacesByPostalCode(code: string, country: string): Promise<PostalPlace[]>;
|
|
21
|
+
/** True if the postal code exists in the country's data. */
|
|
22
|
+
declare function isKnownPostalCode(code: string, country: string): Promise<boolean>;
|
|
23
|
+
/** Postal codes of a place: ({ city: 'Unterhaching', country: 'DE' }) → ["82008"]. */
|
|
24
|
+
declare function findPostalCodes(options: {
|
|
25
|
+
city: string;
|
|
26
|
+
country: string;
|
|
27
|
+
subdivision?: string;
|
|
28
|
+
}): Promise<string[]>;
|
|
29
|
+
/** Countries with postal data. */
|
|
30
|
+
declare function listPostalCountries(): string[];
|
|
31
|
+
|
|
32
|
+
export { type PostalPlace, findPlacesByPostalCode, findPostalCodes, foldName, isKnownPostalCode, listPostalCountries };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
interface PostalPlace {
|
|
2
|
+
postalCode: string;
|
|
3
|
+
/** Place name as published by the postal service. */
|
|
4
|
+
name: string;
|
|
5
|
+
/** First-level subdivision name and code as used by the postal data (the code may differ from ISO 3166-2). */
|
|
6
|
+
subdivisionName: string;
|
|
7
|
+
subdivisionCode: string;
|
|
8
|
+
/** County / district names, where given. */
|
|
9
|
+
subdivision2Name: string;
|
|
10
|
+
subdivision3Name: string;
|
|
11
|
+
lat: number;
|
|
12
|
+
lng: number;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Same folding as geodata-kit's fold() (kept identical; a test checks it):
|
|
16
|
+
* lower case, no accents, no punctuation, "saint" → "st".
|
|
17
|
+
*/
|
|
18
|
+
declare function foldName(text: string): string;
|
|
19
|
+
/** Places with this postal code: ("80331", "DE") → München. Prefixes and spacing are ignored. */
|
|
20
|
+
declare function findPlacesByPostalCode(code: string, country: string): Promise<PostalPlace[]>;
|
|
21
|
+
/** True if the postal code exists in the country's data. */
|
|
22
|
+
declare function isKnownPostalCode(code: string, country: string): Promise<boolean>;
|
|
23
|
+
/** Postal codes of a place: ({ city: 'Unterhaching', country: 'DE' }) → ["82008"]. */
|
|
24
|
+
declare function findPostalCodes(options: {
|
|
25
|
+
city: string;
|
|
26
|
+
country: string;
|
|
27
|
+
subdivision?: string;
|
|
28
|
+
}): Promise<string[]>;
|
|
29
|
+
/** Countries with postal data. */
|
|
30
|
+
declare function listPostalCountries(): string[];
|
|
31
|
+
|
|
32
|
+
export { type PostalPlace, findPlacesByPostalCode, findPostalCodes, foldName, isKnownPostalCode, listPostalCountries };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import { existsSync, readdirSync } from "fs";
|
|
3
|
+
import { readFile } from "fs/promises";
|
|
4
|
+
import { gunzipSync } from "zlib";
|
|
5
|
+
var DATA_DIR = new URL("../data/", import.meta.url);
|
|
6
|
+
var cache = /* @__PURE__ */ new Map();
|
|
7
|
+
var compact = (code) => code.toUpperCase().replace(/[\s-]/g, "");
|
|
8
|
+
function foldName(text) {
|
|
9
|
+
const special = { "\xDF": "ss", "\u0142": "l", "\u0111": "d", "\xF0": "d", "\xF8": "o", "\xE6": "ae", "\u0153": "oe", "\xFE": "th", "\u0131": "i" };
|
|
10
|
+
let plain = "";
|
|
11
|
+
for (const character of text.replace(/['’ʻʼ`´]/g, "").normalize("NFKD").replace(/\p{M}/gu, "").toLowerCase()) {
|
|
12
|
+
plain += special[character] ?? character;
|
|
13
|
+
}
|
|
14
|
+
return plain.replace(/[^\p{L}\p{N}]+/gu, " ").trim().split(" ").filter(Boolean).map((word) => word === "saint" ? "st" : word === "sainte" ? "ste" : word).join(" ");
|
|
15
|
+
}
|
|
16
|
+
function load(country) {
|
|
17
|
+
const code = country.trim().toUpperCase();
|
|
18
|
+
let promise = cache.get(code);
|
|
19
|
+
if (!promise) {
|
|
20
|
+
promise = (async () => {
|
|
21
|
+
const file = new URL(`${code}.json.gz`, DATA_DIR);
|
|
22
|
+
if (!/^[A-Z]{2}$/.test(code) || !existsSync(file)) return null;
|
|
23
|
+
const data = JSON.parse(gunzipSync(await readFile(file)).toString("utf8"));
|
|
24
|
+
const places = data.rows.map((row) => ({
|
|
25
|
+
postalCode: row[0],
|
|
26
|
+
name: row[1],
|
|
27
|
+
subdivisionName: row[2],
|
|
28
|
+
subdivisionCode: row[3],
|
|
29
|
+
subdivision2Name: row[4],
|
|
30
|
+
subdivision3Name: row[5],
|
|
31
|
+
lat: row[6],
|
|
32
|
+
lng: row[7]
|
|
33
|
+
}));
|
|
34
|
+
const byCode = /* @__PURE__ */ new Map();
|
|
35
|
+
for (const place of places) {
|
|
36
|
+
const key = compact(place.postalCode);
|
|
37
|
+
const list = byCode.get(key);
|
|
38
|
+
if (list) list.push(place);
|
|
39
|
+
else byCode.set(key, [place]);
|
|
40
|
+
}
|
|
41
|
+
return { places, byCode, codeLengths: [...new Set([...byCode.keys()].map((key) => key.length))].sort((a, b) => b - a) };
|
|
42
|
+
})();
|
|
43
|
+
cache.set(code, promise);
|
|
44
|
+
}
|
|
45
|
+
return promise;
|
|
46
|
+
}
|
|
47
|
+
function lookup(data, code) {
|
|
48
|
+
const key = compact(code.trim().replace(/^[A-Z]{1,3}-(?=\d)/i, "").replace(/^〒/, ""));
|
|
49
|
+
const exact = data.byCode.get(key);
|
|
50
|
+
if (exact) return exact;
|
|
51
|
+
for (const length of data.codeLengths) {
|
|
52
|
+
if (length >= key.length) continue;
|
|
53
|
+
const partial = data.byCode.get(key.slice(0, length));
|
|
54
|
+
if (partial) return partial;
|
|
55
|
+
}
|
|
56
|
+
return [];
|
|
57
|
+
}
|
|
58
|
+
async function findPlacesByPostalCode(code, country) {
|
|
59
|
+
const data = await load(country);
|
|
60
|
+
return data ? lookup(data, code).map((place) => ({ ...place })) : [];
|
|
61
|
+
}
|
|
62
|
+
async function isKnownPostalCode(code, country) {
|
|
63
|
+
return (await findPlacesByPostalCode(code, country)).length > 0;
|
|
64
|
+
}
|
|
65
|
+
async function findPostalCodes(options) {
|
|
66
|
+
const data = await load(options.country);
|
|
67
|
+
if (!data) return [];
|
|
68
|
+
const key = foldName(options.city);
|
|
69
|
+
const subdivision = options.subdivision ? foldName(options.subdivision) : null;
|
|
70
|
+
const codes = /* @__PURE__ */ new Set();
|
|
71
|
+
for (const place of data.places) {
|
|
72
|
+
if (foldName(place.name) !== key) continue;
|
|
73
|
+
if (subdivision && foldName(place.subdivisionName) !== subdivision && foldName(place.subdivisionCode) !== subdivision) continue;
|
|
74
|
+
codes.add(place.postalCode);
|
|
75
|
+
}
|
|
76
|
+
return [...codes].sort();
|
|
77
|
+
}
|
|
78
|
+
function listPostalCountries() {
|
|
79
|
+
if (!existsSync(DATA_DIR)) return [];
|
|
80
|
+
return readdirSync(DATA_DIR).filter((file) => file.endsWith(".json.gz")).map((file) => file.slice(0, 2)).sort();
|
|
81
|
+
}
|
|
82
|
+
export {
|
|
83
|
+
findPlacesByPostalCode,
|
|
84
|
+
findPostalCodes,
|
|
85
|
+
foldName,
|
|
86
|
+
isKnownPostalCode,
|
|
87
|
+
listPostalCountries
|
|
88
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,53 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "geodata-kit-postal",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Optional data for geodata-kit: postal code \u2192 place and place \u2192 postal codes for 124 countries (GeoNames, 1.8 million codes). Node.js only.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"postal-code",
|
|
7
|
+
"zip-code",
|
|
8
|
+
"postcode",
|
|
9
|
+
"geonames",
|
|
10
|
+
"geodata-kit"
|
|
11
|
+
],
|
|
12
|
+
"license": "MIT",
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "git+https://github.com/greta-devhub/geodata-kit.git",
|
|
16
|
+
"directory": "packages/geodata-kit-postal"
|
|
17
|
+
},
|
|
18
|
+
"homepage": "https://github.com/greta-devhub/geodata-kit/tree/main/packages/geodata-kit-postal#readme",
|
|
19
|
+
"bugs": {
|
|
20
|
+
"url": "https://github.com/greta-devhub/geodata-kit/issues"
|
|
21
|
+
},
|
|
22
|
+
"type": "module",
|
|
23
|
+
"sideEffects": false,
|
|
24
|
+
"engines": {
|
|
25
|
+
"node": ">=20"
|
|
26
|
+
},
|
|
27
|
+
"main": "./dist/index.cjs",
|
|
28
|
+
"module": "./dist/index.js",
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
30
|
+
"exports": {
|
|
31
|
+
".": {
|
|
32
|
+
"import": {
|
|
33
|
+
"types": "./dist/index.d.ts",
|
|
34
|
+
"default": "./dist/index.js"
|
|
35
|
+
},
|
|
36
|
+
"require": {
|
|
37
|
+
"types": "./dist/index.d.cts",
|
|
38
|
+
"default": "./dist/index.cjs"
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"./package.json": "./package.json"
|
|
42
|
+
},
|
|
43
|
+
"files": [
|
|
44
|
+
"dist",
|
|
45
|
+
"data",
|
|
46
|
+
"NOTICE",
|
|
47
|
+
"LICENSE",
|
|
48
|
+
"README.md"
|
|
49
|
+
],
|
|
50
|
+
"scripts": {
|
|
51
|
+
"build": "tsup"
|
|
52
|
+
}
|
|
53
|
+
}
|