Skip to content

Commit 8367a45

Browse files
committed
wip: recode
1 parent f89b138 commit 8367a45

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+6709
-256
lines changed

.gitattributes

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* text eol=lf

.gitignore

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
dist
2+
indexes
3+
.DS_Store
4+
coverage
5+
*.lcov
6+
node_modules/
7+
*.tsbuildinfo
8+
.npm
9+
.eslintcache
10+
*.tgz
11+
.env

.vscode/settings.json

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
{
2+
// Disable the default formatter, use eslint instead
3+
"prettier.enable": false,
4+
"editor.formatOnSave": false,
5+
6+
// Auto fix
7+
"editor.codeActionsOnSave": {
8+
"source.fixAll.eslint": "explicit",
9+
"source.organizeImports": "never"
10+
},
11+
12+
// Silent the stylistic rules in you IDE, but still auto fix them
13+
"eslint.rules.customizations": [
14+
{ "rule": "style/*", "severity": "off", "fixable": true },
15+
{ "rule": "format/*", "severity": "off", "fixable": true },
16+
{ "rule": "*-indent", "severity": "off", "fixable": true },
17+
{ "rule": "*-spacing", "severity": "off", "fixable": true },
18+
{ "rule": "*-spaces", "severity": "off", "fixable": true },
19+
{ "rule": "*-order", "severity": "off", "fixable": true },
20+
{ "rule": "*-dangle", "severity": "off", "fixable": true },
21+
{ "rule": "*-newline", "severity": "off", "fixable": true },
22+
{ "rule": "*quotes", "severity": "off", "fixable": true },
23+
{ "rule": "*semi", "severity": "off", "fixable": true }
24+
],
25+
26+
// Enable eslint for all supported languages
27+
"eslint.validate": [
28+
"javascript",
29+
"javascriptreact",
30+
"typescript",
31+
"typescriptreact",
32+
"vue",
33+
"html",
34+
"markdown",
35+
"json",
36+
"jsonc",
37+
"yaml",
38+
"toml",
39+
"xml",
40+
"gql",
41+
"graphql",
42+
"astro",
43+
"css",
44+
"less",
45+
"scss",
46+
"pcss",
47+
"postcss"
48+
]
49+
}

README.md

Lines changed: 8 additions & 256 deletions
Original file line numberDiff line numberDiff line change
@@ -1,256 +1,8 @@
1-
# ip-location-api [![npm version](https://img.shields.io/npm/v/ip-location-api?color=success&style=flat-square&label=npm)](https://www.npmjs.com/package/ip-location-api)
2-
3-
Fast and customizable nodejs api to get geolocation information from ip address.
4-
`ip-location-api` make a fast lookup by using in-memory database.
5-
6-
This api is created for server-side javascript like Node.js.
7-
If you need client-side javascript which works in **BROWSER**, please try to use [@iplookup/country](https://github.com/sapics/ip-location-api/tree/main/browser/country) or [@iplookup/geocode](https://github.com/sapics/ip-location-api/tree/main/browser/geocode).
8-
9-
10-
## Synopsis
11-
12-
```javascript
13-
import { lookup } from 'ip-location-api'
14-
// or CJS format
15-
// const { lookup } = require('ip-location-api')
16-
17-
var ip = "207.97.227.239"
18-
var location = lookup(ip)
19-
// If you use Asynchronouns version which is configured with smallMemory=true,
20-
// var location = await lookup(ip)
21-
22-
console.log(location)
23-
{
24-
country: 'FR',
25-
region1: 'NOR',
26-
region1_name: 'Normandy',
27-
region2: '27',
28-
region2_name: 'Eure',
29-
city: 'Heudicourt',
30-
// metro: Defined only in US (Aug.2024)
31-
timezone: 'Europe/Paris',
32-
eu: 1,
33-
latitude: 49.3335,
34-
longitude: 1.6566,
35-
area: 5,
36-
postcode: 27860,
37-
country_name: 'France',
38-
country_native: 'France',
39-
phone: [ 33 ],
40-
continent: 'EU',
41-
capital: 'Paris',
42-
currency: [ 'EUR' ],
43-
languages: [ 'fr' ],
44-
continent_name: 'Europe'
45-
}
46-
```
47-
48-
## Benchmark
49-
50-
I make a benchmark for making comparison with intel 12700 (2.1GHz), SSD, nodejs v20.
51-
You can change the memory usage or lookup time, by customizing location information.
52-
53-
| benchmark | type | in-memory db | startup | lookup ipv4 | lookup ipv6 |
54-
| ---- | ---- | ---- | ---- | ---- | ---- |
55-
| ip-location-api<br>(default) | country | 6.9 MB | 3 ms | 0.362 μs/ip | 0.708 μs/ip |
56-
| ip-location-api<br>(async) | country | 2.9 MB | 2 ms | 243 μs/ip | 255 μs/ip |
57-
| ip-location-api | city | 62.9 MB | 14 ms | 0.751 μs/ip | 1.064 μs/ip |
58-
| ip-location-api<br>(async) | city | 15.6 MB | 5 ms | 267 μs/ip | 271 μs/ip |
59-
| [geoip-lite](https://github.com/geoip-lite/node-geoip) | city | 136 MB | 54 ms | 1.616 μs/ip | 3.890 μs/ip |
60-
| [fast-geoip](https://github.com/Doc999tor/fast-geoip)<br>(async) | city | 0MB | 4 ms | 1714 μs/ip | cannot lookup |
61-
62-
63-
## Installation
64-
65-
```bash
66-
$ npm i ip-location-api
67-
```
68-
69-
70-
## API
71-
72-
ip-location-api has two modes which are synchronous and asynchronous.
73-
Synchronouns one load all data in-memory at startup time, thus it makes fast lookup.
74-
Asynchronouns one load smaller data in-memory at startup time, and the other data is loaded from the hard drive for each lookup.
75-
76-
| type | memory usage | startup | lookup |
77-
| ---- | ---- | ---- | ---- |
78-
| Synchronouns | Large | Slow | Fast |
79-
| Asynchronouns | Small | Fast | Slow |
80-
81-
If you have a enough memory, I recommend to use synchronouns one because lookup is over 300 times faster than asynchronouns one.
82-
83-
84-
## Field description
85-
86-
Note that as far as possible, the same field names as in `geoip-lite` are used, but some different field names are used.
87-
88-
| `ip-location-api` | `geoip-lite` | database |description |
89-
| ---- | ---- | ---- | ---- |
90-
| country | country | MaxMind | "2 letter" country code defined at [ISO-3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1) |
91-
| region1 | region | MaxMind | region code which is short code for region1_name [ISO 3166-2](https://en.wikipedia.org/wiki/ISO_3166-2) |
92-
| region1_name | ❌️ | MaxMind | first sub division name (multi language) |
93-
| region2 | ❌️ | MaxMind | region code which is short code for region2_name [ISO 3166-2](https://en.wikipedia.org/wiki/ISO_3166-2) |
94-
| region2_name | ❌️ | MaxMind | second sub division name (multi language) |
95-
| city | city |MaxMind | city name (multi language) |
96-
| metro | metro |MaxMind | Geolocation target code from Google |
97-
| eu | eu | MaxMind | true: the member state of the European Union, undefined: for the other countries. This needs "country" field. |
98-
| timezone | timezone | MaxMind | time zone associated with location |
99-
| latitude | ll[0] | MaxMind | approximate [WGS84](https://en.wikipedia.org/wiki/World_Geodetic_System) latitude |
100-
| longitude | ll[1] | MaxMind | approximate [WGS84](https://en.wikipedia.org/wiki/World_Geodetic_System) longitude |
101-
| area | area | MaxMind | The radius in kilometers around the specified location where the IP address is likely to be. [maxmind blog](https://blog.maxmind.com/2022/06/using-maxminds-accuracy-radius/) |
102-
| postcode | ❌️ | MaxMind | region-specific postal code near the IP address |
103-
| ❌️ | range | MaxMind | We removes range information for optimization |
104-
| country_name | ❌️ | Countries| country name|
105-
| country_native | ❌️ | Countries| country name in native language|
106-
| continent | ❌️ | Countries| continent short code|
107-
| continent_name | ❌️ | Countries| continent name|
108-
| capital | ❌️ | Countries | capital name |
109-
| phone | ❌️ | Countries| international country calling codes |
110-
| currency | ❌️ | Countries | list of commonly used currencies |
111-
| languages | ❌️ | Countries | list of commonly used languages |
112-
113-
114-
## Setup the configuration
115-
116-
You can configure the api by 3 way.
117-
- CLI parameters: `ILA_FIELDS=latitude,longitude`
118-
- Environment variables: `ILA_FIELDS=latitude,longitude`
119-
- Javascript: `await reload({fields: 'latitude,longitude'})` .
120-
121-
The name of CLI prameter and environment variables are same.
122-
123-
124-
Conf key in `reload(conf)` is named with "LOWER CAMEL", CLI or ENV parameter is named with "SNAKE" with adding "ILA_" (come from Ip-Location-Api).
125-
126-
| `reload(conf)` | CLI or ENV | default | description |
127-
| ---- | ---- | ---- | ---- |
128-
| fields | ILA_FIELDS | country | You can change the fields to be retrived from [MaxMind](https://www.maxmind.com/). When you set "all", all fields are displayed. |
129-
| addCountryInfo | ILA_ADD_COUNTRY_INFO | false | "true" make to add the country information from [Countries](https://github.com/annexare/Countries). This needs "country" field. |
130-
| dataDir | ILA_DATA_DIR | ../data | Directory for database file |
131-
| tmpDataDir | ILA_TMP_DATA_DIR | ../tmp | Directory for temporary file |
132-
| smallMemory | ILA_SMALL_MEMORY | false | false: synchronouns, ture: asynchronouns |
133-
| smallMemoryFileSize | ILA_SMALL_MEMORY_FILE_SIZE | 4096 | Max file size for asynchronouns data (no change is recommended) |
134-
| licenseKey | ILA_LICENSE_KEY | redist | By setting [MaxMind](https://www.maxmind.com/) License key, you can download latest version of database from [MaxMind](https://www.maxmind.com/) server. By setting to "redist", you can download the database from [node-geolite2-redist](https://github.com/sapics/node-geolite2-redist) repository which re-distribute the GeoLite2 database. |
135-
| ipLocationDb | ILA_IP_LOCATION_DB | | When you need only "country" field, you can use [ip-location-db](https://github.com/sapics/ip-location-db) data |
136-
| downloadType | ILA_DOWNLOAD_TYPE | reuse | By setting to "false", "tmpDataDir" directory is deleted every update. "reuse" dose not delete "tmpDataDir" and re-use "tmpDataDir"'s database if the database file dose not update. |
137-
| autoUpdate | ILA_AUTO_UPDATE | default | By setting to "false", it dose not update automatically. "default" updates twice weekly. You can set CRON PATTERN FORMAT which is provided by [cron](https://github.com/kelektiv/node-cron) with UTC timezone (For example, ILA_AUTO_UPDATE="0 1 * * *" for daily update). |
138-
| multiDbDir | ILA_MULTI_DB_DIR | false | If you use multiple "dataDir", please make this value to "true" |
139-
| series | ILA_SERIES | GeoLite2 | By setting to "GeoIP2", you can use premium database "GeoIP2" |
140-
| language | ILA_LANGUAGE | en | You can choose "de", "en", "es", "fr", "ja", "pt-BR", "ru", "zh-CN". By changing, the language of "region1_name", "region2_name", "city" fields are changed |
141-
| silent | ILA_SILENT | false | true: deactivate unnecessary console.log |
142-
143-
144-
## Update database
145-
146-
```bash
147-
npm run updatedb
148-
```
149-
150-
or
151-
152-
```javascript
153-
import { updateDb } from 'ip-location-api'
154-
await updateDb(setting)
155-
```
156-
157-
158-
There are three database update way.
159-
- ILA_LICENSE_KEY=redist
160-
- ILA_LICENSE_KEY=YOUR_GEOLITE2_LICENSE_KEY
161-
- ILA_IP_LOCATION_DB=YOUR_CHOOSEN_DATABSE
162-
163-
When you set "ILA_LICENSE_KEY=redist" which is the dafault setting, it downloads GeoLite2 database from the redistribution repository [node-geolite2-redist](https://github.com/sapics/node-geolite2-redist).
164-
165-
When you set "ILA_LICENSE_KEY=YOUR_GEOLITE2_LICENSE_KEY", it downloads GeoLite2 dastabase from the MaxMind provided server.
166-
`YOUR_GEOLITE2_LICENSE_KEY` should be replaced by a valid GeoLite2 license key. Please [follow instructions](https://dev.maxmind.com/geoip/geoip2/geolite2/) provided by MaxMind to obtain a license key.
167-
168-
When you set "ILA_IP_LOCATION_DB=YOUR_CHOOSEN_DATABSE", it downloads from the [ip-location-db](https://github.com/sapics/ip-location-db) (country type only).
169-
You can "YOUR_CHOOSEN_DATABSE" from [ip-location-db](https://github.com/sapics/ip-location-db) with country type. For example, "geolite2-geo-whois-asn" is wider IP range country database which is equivalent to GeoLite2 database result for GeoLite2 country covered IP range and geo-whois-asn-country for the other IP range.
170-
The other example, "geo-whois-asn" is [CC0 licensed database](https://github.com/sapics/ip-location-db/tree/main/geo-asn-country), if you are unable to apply the GeoLite2 License.
171-
172-
173-
After v2.0, the database is created automatically at initial startup, and updated automatically by setting `ILA_AUTO_UPDATE` which updates twice weekly with default setting.
174-
175-
176-
## How to use with an example
177-
178-
When you need only geographic coordinates, please set "ILA_FIELDS=latitude,longitude".
179-
You need to create a database for each configuration.
180-
After v2.0.0, the database is created at initial running (which takes some seconds), and auto update with `ILA_AUTO_UPDATE` which update twice weekly with default setting.
181-
The database is created by following CLI
182-
183-
```bash
184-
$ npm run updatedb ILA_FIELDS=latitude,longitude
185-
```
186-
187-
or
188-
189-
```bash
190-
$ ILA_FIELDS=latitude,longitude # set environment variable
191-
$ npm run updatedb
192-
```
193-
194-
or you can create database with 'create.js' which includes the following.
195-
196-
```javascript
197-
await updateDb({fields:['latitude', 'longitude']})
198-
```
199-
200-
201-
The CLI command for using `app.js` which uses `ip-location-api` is necessary to start with following CLI parameter
202-
203-
```bash
204-
$ node app.js ILA_FIELDS=latitude,longitude
205-
```
206-
207-
or environment variable
208-
209-
```bash
210-
$ ILA_FIELDS=latitude,longitude # set environment variable
211-
$ node app.js
212-
```
213-
214-
or you can write down configuration in `reload` function of app.js as
215-
216-
```javascript
217-
await reload({fields:['latitude', 'longitude']})
218-
// or await reload({fields:'latitude,longitude'})
219-
```
220-
221-
222-
If you need all the data in above field table, setting "ILA_FIELDS=all" and "ILA_ADD_COUNTRY_INFO=true" is the one.
223-
224-
225-
| benchmark | in-memory db | startup | lookup ipv4 | lookup ipv6 |
226-
| ---- | ---- | ---- | ---- | ---- |
227-
| longitude,latitude | 46.5 MB | 10 ms | 0.428 μs/ip | 0.776 μs/ip |
228-
| all | 76.4 MB | 18 ms | 1.054 μs/ip | 1.348 μs/ip |
229-
230-
231-
232-
## Node.js version
233-
234-
This library supports Node.js >= 14 for ESM and CJS.
235-
236-
237-
## License and EULA
238-
239-
There are multiple licenses in this library, one for the software library, and the others for the datadata.
240-
Please read the LICENSE and EULA files for details.
241-
242-
243-
The license for the software itself is published under MIT License by [sapics](https://github.com/sapics).
244-
245-
246-
The GeoLite2 database comes with certain restrictions and obligations, most notably:
247-
- You cannot prevent the library from updating the databases.
248-
- You cannot use the GeoLite2 data:
249-
- for FCRA purposes,
250-
- to identify specific households or individuals.
251-
252-
You can read [the latest version of GeoLite2 EULA](https://www.maxmind.com/en/geolite2/eula).
253-
GeoLite2 database is provided under [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/) by [MaxMind](https://www.maxmind.com/), so, you need to create attribusion to [MaxMind](https://www.maxmind.com/) for using GeoLite2 database.
254-
255-
256-
The database of [Countries](https://github.com/annexare/Countries) is published under MIT license by [Annexare Studio](https://annexare.com/).
1+
## 💻 Development
2+
3+
- Clone this repository
4+
- Enable [Corepack](https://github.com/nodejs/corepack) using `corepack enable` (use `npm i -g corepack` for Node.js < 16.10)
5+
- Install dependencies using `pnpm install`
6+
- Run interactive tests using `pnpm test:ui`
7+
- Build packages using `pnpm build`
8+
- Build packages in watch mode using `pnpm build:watch` (will watch for changes and rebuild)

eslint.config.mjs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import antfu from '@antfu/eslint-config'
2+
3+
export default antfu(
4+
{
5+
formatters: true,
6+
typescript: true,
7+
},
8+
)

package.json

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
{
2+
"type": "module",
3+
"private": true,
4+
"packageManager": "pnpm@9.11.0",
5+
"engines": {
6+
"node": ">=14.8.0",
7+
"pnpm": ">=9.11.0"
8+
},
9+
"scripts": {
10+
"lint": "eslint .",
11+
"lint:fix": "eslint . --fix",
12+
"build": "pnpm -r build",
13+
"build:watch": "concurrently \"npm:build:watch:*\" --kill-others",
14+
"build:watch:country": "cd packages/country && pnpm build:watch",
15+
"build:watch:country-extra": "cd packages/country-extra && pnpm build:watch",
16+
"build:watch:geocode": "cd packages/geocode && pnpm build:watch",
17+
"build:watch:geocode-extra": "cd packages/geocode-extra && pnpm build:watch",
18+
"build:watch:ip-location-api": "cd packages/ip-location-api && pnpm build:watch",
19+
"build:watch:util": "cd packages/util && pnpm build:watch",
20+
"test:ui": "vitest --ui --coverage",
21+
"test": "vitest --run --coverage"
22+
},
23+
"devDependencies": {
24+
"@antfu/eslint-config": "^3.7.3",
25+
"@rollup/plugin-replace": "^6.0.1",
26+
"@total-typescript/tsconfig": "^1.0.4",
27+
"@types/node": "^22.7.4",
28+
"@unocss/eslint-plugin": "^0.63.0",
29+
"@vitest/coverage-v8": "^2.1.1",
30+
"@vitest/ui": "^2.1.1",
31+
"concurrently": "^9.0.1",
32+
"eslint": "^9.11.1",
33+
"eslint-plugin-format": "^0.1.2",
34+
"typescript": "^5.6.2",
35+
"vite": "^5.4.8",
36+
"vite-plugin-checker": "^0.8.0",
37+
"vite-plugin-dts": "^4.2.2",
38+
"vitest": "^2.1.1"
39+
}
40+
}

0 commit comments

Comments
 (0)