@k03mad/ip2geo 6.1.0 → 7.0.1

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.
@@ -7,4 +7,4 @@ updates:
7
7
  - package-ecosystem: "github-actions"
8
8
  directory: "/"
9
9
  schedule:
10
- interval: "daily"
10
+ interval: "monthly"
@@ -7,29 +7,14 @@ on:
7
7
  pull_request:
8
8
  branches:
9
9
  - master
10
- schedule:
11
- - cron: '00 15 * * 6'
12
10
 
13
11
  jobs:
14
12
  lint:
15
- name: Lint
16
- permissions:
17
- contents: read
18
13
  runs-on: ubuntu-latest
19
14
  steps:
20
- - name: Checkout
21
- uses: actions/checkout@v4
22
-
23
- - name: Install NodeJS
24
- uses: actions/setup-node@v4
15
+ - uses: actions/checkout@v4
16
+ - uses: actions/setup-node@v4
25
17
  with:
26
18
  node-version-file: '.nvmrc'
27
-
28
- - name: Install PNPM
29
- run: npm i pnpm -g
30
-
31
- - name: Run setup
32
- run: npm run setup
33
-
34
- - name: Run lint
35
- run: npm run lint
19
+ - run: npm run setup
20
+ - run: npm run lint
@@ -0,0 +1,21 @@
1
+ name: Publish
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - master
7
+
8
+ jobs:
9
+ publish:
10
+ environment: npm
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v4
14
+ - uses: actions/setup-node@v4
15
+ with:
16
+ node-version-file: '.nvmrc'
17
+ registry-url: 'https://registry.npmjs.org'
18
+ - run: npm run setup
19
+ - run: npm publish
20
+ env:
21
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
@@ -7,29 +7,14 @@ on:
7
7
  pull_request:
8
8
  branches:
9
9
  - master
10
- schedule:
11
- - cron: '00 15 * * 6'
12
10
 
13
11
  jobs:
14
12
  test:
15
- name: Test
16
- permissions:
17
- contents: read
18
13
  runs-on: ubuntu-latest
19
14
  steps:
20
- - name: Checkout
21
- uses: actions/checkout@v4
22
-
23
- - name: Install NodeJS
24
- uses: actions/setup-node@v4
15
+ - uses: actions/checkout@v4
16
+ - uses: actions/setup-node@v4
25
17
  with:
26
18
  node-version-file: '.nvmrc'
27
-
28
- - name: Install PNPM
29
- run: npm i pnpm -g
30
-
31
- - name: Run setup
32
- run: npm run setup
33
-
34
- - name: Run test
35
- run: npm run test
19
+ - run: npm run setup
20
+ - run: npm run test
@@ -29,7 +29,9 @@ export const collectOutputData = dataArr => {
29
29
  const outputData = {};
30
30
 
31
31
  outputKeys.forEach((key, i) => {
32
- outputData[key] = dataArr[i];
32
+ outputData[key] = key === 'connectionAsn' && dataArr[i]
33
+ ? Number(dataArr[i])
34
+ : dataArr[i];
33
35
  });
34
36
 
35
37
  return outputData;
@@ -94,11 +96,10 @@ export const readFromFsCache = async (ip, cacheDir, cacheFileName, cacheFileSepa
94
96
  */
95
97
  export const writeToFsCache = async (ip, data, cacheDir, cacheFileName, cacheFileSeparator, cacheFileNewline) => {
96
98
  const cacheFileFull = getCacheFileFullPath(ip, cacheDir, cacheFileName);
99
+ debug('set to fs cache: %o %o', cacheFileFull, data);
97
100
 
98
101
  await fs.mkdir(cacheDir, {recursive: true});
99
102
  await fs.appendFile(cacheFileFull, Object.values(data).join(cacheFileSeparator) + cacheFileNewline);
100
-
101
- debug('set to fs cache: %o %o', cacheFileFull, data);
102
103
  };
103
104
 
104
105
  /**
@@ -109,38 +110,25 @@ export const writeToFsCache = async (ip, data, cacheDir, cacheFileName, cacheFil
109
110
  */
110
111
  export const readFromMapCache = (ip, cacheMap, cacheMapMaxEntries) => {
111
112
  if (cacheMapMaxEntries > 0) {
112
- const mapCache = cacheMap.get(ip);
113
+ const value = cacheMap.get(ip);
113
114
 
114
- if (mapCache) {
115
- debug('get from map cache: %o', mapCache);
116
- return mapCache;
115
+ if (value) {
116
+ debug('get from map cache: %o', value);
117
+ return value;
117
118
  }
118
119
  }
119
120
  };
120
121
 
121
- /**
122
- * @param {object} body
123
- * @param {string} body.ip
124
- * @param {Map} cacheMap
125
- * @param {number} cacheMapMaxEntries
126
- */
127
- export const writeToMapCache = (body, cacheMap, cacheMapMaxEntries) => {
128
- if (cacheMapMaxEntries > 0) {
129
- cacheMap.set(body.ip, body);
130
- debug('set to map cache: %o', body);
131
- }
132
- };
133
-
134
122
  /**
135
123
  * @param {Map} cacheMap
136
124
  * @param {number} cacheMapMaxEntries
137
125
  */
138
126
  export const removeFromMapCacheIfLimit = (cacheMap, cacheMapMaxEntries) => {
139
127
  if (cacheMap.size > cacheMapMaxEntries) {
140
- debug('remove from map cache by limit: size %o, limit: %o', cacheMap.size, cacheMapMaxEntries);
128
+ debug('remove from map cache by limit: %o > %o', cacheMap.size, cacheMapMaxEntries);
141
129
 
142
130
  for (const [key] of cacheMap) {
143
- debug('remove from map cache by limit: key %o', key);
131
+ debug('remove from map cache by limit: %o', key);
144
132
  cacheMap.delete(key);
145
133
 
146
134
  if (cacheMap.size <= cacheMapMaxEntries) {
@@ -149,3 +137,18 @@ export const removeFromMapCacheIfLimit = (cacheMap, cacheMapMaxEntries) => {
149
137
  }
150
138
  }
151
139
  };
140
+
141
+ /**
142
+ * @param {object} body
143
+ * @param {string} body.ip
144
+ * @param {Map} cacheMap
145
+ * @param {number} cacheMapMaxEntries
146
+ */
147
+ export const writeToMapCache = (body, cacheMap, cacheMapMaxEntries) => {
148
+ if (cacheMapMaxEntries > 0) {
149
+ debug('set to map cache: %o', body);
150
+ cacheMap.set(body.ip, body);
151
+
152
+ removeFromMapCacheIfLimit(cacheMap, cacheMapMaxEntries);
153
+ }
154
+ };
package/app/lib/ip2geo.js CHANGED
@@ -8,7 +8,6 @@ import {
8
8
  collectOutputData,
9
9
  readFromFsCache,
10
10
  readFromMapCache,
11
- removeFromMapCacheIfLimit,
12
11
  writeToFsCache,
13
12
  writeToMapCache,
14
13
  } from '../helpers/cache.js';
@@ -75,7 +74,11 @@ export const ip2geo = async ({
75
74
  return mapCache;
76
75
  }
77
76
 
78
- const fsCache = await readFromFsCache(ip, cacheDir, cacheFileName);
77
+ const fsCache = await readFromFsCache(
78
+ ip,
79
+ cacheDir, cacheFileName,
80
+ cacheFileSeparator, cacheFileNewline,
81
+ );
79
82
 
80
83
  if (fsCache) {
81
84
  writeToMapCache(fsCache, cacheMap, cacheMapMaxEntries);
@@ -87,7 +90,11 @@ export const ip2geo = async ({
87
90
  const {body} = await request(reqUrl, {}, {rps});
88
91
 
89
92
  if (!body?.ip) {
90
- logErrorExit(['API error', `request: ${reqUrl}`, `response body: ${body}`]);
93
+ logErrorExit([
94
+ 'API error',
95
+ `request: ${reqUrl}`,
96
+ `response body: ${body}`,
97
+ ]);
91
98
  }
92
99
 
93
100
  const outputData = collectOutputData([
@@ -107,11 +114,11 @@ export const ip2geo = async ({
107
114
  ]);
108
115
 
109
116
  writeToMapCache(outputData, cacheMap, cacheMapMaxEntries);
110
- removeFromMapCacheIfLimit(cacheMap, cacheMapMaxEntries);
111
117
 
112
118
  await writeToFsCache(
113
119
  body.ip, outputData,
114
- cacheDir, cacheFileName, cacheFileSeparator, cacheFileNewline,
120
+ cacheDir, cacheFileName,
121
+ cacheFileSeparator, cacheFileNewline,
115
122
  );
116
123
 
117
124
  return outputData;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@k03mad/ip2geo",
3
- "version": "6.1.0",
3
+ "version": "7.0.1",
4
4
  "description": "GeoIP library",
5
5
  "maintainers": [
6
6
  "Kirill Molchanov <k03.mad@gmail.com"
@@ -19,25 +19,25 @@
19
19
  "node": ">=20"
20
20
  },
21
21
  "dependencies": {
22
- "@k03mad/request": "5.6.0",
23
- "@k03mad/simple-log": "2.1.0",
22
+ "@k03mad/request": "5.6.1",
23
+ "@k03mad/simple-log": "2.1.1",
24
24
  "chalk": "5.3.0",
25
25
  "debug": "4.3.4"
26
26
  },
27
27
  "devDependencies": {
28
- "@k03mad/eslint-config": "20.2.0",
28
+ "@k03mad/eslint-config": "20.3.0",
29
29
  "eslint": "8.56.0",
30
- "husky": "9.0.7",
31
- "mocha": "10.2.0"
30
+ "husky": "9.0.11",
31
+ "mocha": "10.3.0"
32
32
  },
33
33
  "scripts": {
34
34
  "lint": "npm run lint:eslint",
35
35
  "lint:eslint": "eslint ./ --cache",
36
- "test": "mocha tests",
36
+ "test": "rm -rfv ./.geoip && mocha tests",
37
37
  "clean": "npm run clean:modules && npm run clean:eslint:cache",
38
38
  "clean:modules": "rm -rf ./node_modules || true",
39
39
  "clean:eslint:cache": "rm -rf .eslintcache || true",
40
- "setup": "npm run clean && pnpm i",
40
+ "setup": "npm run clean && npm i pnpm -g && pnpm i",
41
41
  "prepare": "husky || true"
42
42
  }
43
43
  }
@@ -0,0 +1,36 @@
1
+ import assert from 'node:assert/strict';
2
+
3
+ import {describe, it} from 'mocha';
4
+
5
+ import {ip2geo} from '../app/index.js';
6
+
7
+ import {getCurrentFilename, getTestFolder} from './helpers/path.js';
8
+ import {REQUEST_IPV4} from './shared/consts.js';
9
+ import {checkCacheFile, removeCacheFolder} from './shared/fs.js';
10
+
11
+ const testName = getCurrentFilename(import.meta.url);
12
+
13
+ describe(testName, () => {
14
+ const opts = {
15
+ cacheDir: getTestFolder(testName),
16
+ cacheMap: new Map(),
17
+ cacheMapMaxEntries: 0,
18
+ tries: 5,
19
+ };
20
+
21
+ it('should remove fs cache dir if exist', () => removeCacheFolder(opts.cacheDir));
22
+
23
+ Array.from({length: opts.tries}, (_, i) => i + 1).forEach(num => {
24
+ describe(`Try: ${num}`, () => {
25
+ it(`should return correct response for IP: "${REQUEST_IPV4.ip}"`, async () => {
26
+ const data = await ip2geo({ip: REQUEST_IPV4.ip, ...opts});
27
+ assert.deepEqual(data, REQUEST_IPV4);
28
+ });
29
+
30
+ it('should have cache file', () => checkCacheFile({
31
+ ...opts,
32
+ response: REQUEST_IPV4,
33
+ }));
34
+ });
35
+ });
36
+ });
@@ -4,8 +4,8 @@ import {describe, it} from 'mocha';
4
4
 
5
5
  import {ip2geo} from '../app/index.js';
6
6
 
7
- import {REQUEST_IPV4} from './helpers/consts.js';
8
7
  import {getCurrentFilename, getTestFolder} from './helpers/path.js';
8
+ import {REQUEST_IPV4} from './shared/consts.js';
9
9
  import {checkCacheFile, removeCacheFolder} from './shared/fs.js';
10
10
 
11
11
  const testName = getCurrentFilename(import.meta.url);
@@ -5,8 +5,8 @@ import {describe, it} from 'mocha';
5
5
 
6
6
  import {ip2geo} from '../app/index.js';
7
7
 
8
- import {REQUEST_IPV4} from './helpers/consts.js';
9
8
  import {getCurrentFilename, getTestFolder} from './helpers/path.js';
9
+ import {REQUEST_IPV4} from './shared/consts.js';
10
10
  import {checkCacheFile, removeCacheFolder} from './shared/fs.js';
11
11
 
12
12
  const testName = getCurrentFilename(import.meta.url);
@@ -4,8 +4,8 @@ import {describe, it} from 'mocha';
4
4
 
5
5
  import {ip2geo} from '../app/index.js';
6
6
 
7
- import {REQUEST_IPV4, REQUEST_IPV6} from './helpers/consts.js';
8
7
  import {getCurrentFilename, getTestFolder} from './helpers/path.js';
8
+ import {REQUEST_IPV4, REQUEST_IPV6} from './shared/consts.js';
9
9
  import {removeCacheFolder} from './shared/fs.js';
10
10
 
11
11
  const testName = getCurrentFilename(import.meta.url);
@@ -4,8 +4,8 @@ import {describe, it} from 'mocha';
4
4
 
5
5
  import {cacheStorage, ip2geo} from '../app/index.js';
6
6
 
7
- import {REQUEST_IPV4_MAP_OFF_ONLY} from './helpers/consts.js';
8
7
  import {getCurrentFilename, getTestFolder} from './helpers/path.js';
8
+ import {REQUEST_IPV4_MAP_OFF_ONLY} from './shared/consts.js';
9
9
  import {checkCacheFile, removeCacheFolder} from './shared/fs.js';
10
10
 
11
11
  const testName = getCurrentFilename(import.meta.url);
package/tests/default.js CHANGED
@@ -4,8 +4,8 @@ import {describe, it} from 'mocha';
4
4
 
5
5
  import {cacheStorage, ip2geo} from '../app/index.js';
6
6
 
7
- import {REQUEST_IPV4} from './helpers/consts.js';
8
7
  import {getCurrentFilename} from './helpers/path.js';
8
+ import {REQUEST_IPV4} from './shared/consts.js';
9
9
  import {checkCacheFile, removeCacheFolder} from './shared/fs.js';
10
10
 
11
11
  const testName = getCurrentFilename(import.meta.url);
@@ -4,8 +4,8 @@ import {describe, it} from 'mocha';
4
4
 
5
5
  import {ip2geo} from '../app/index.js';
6
6
 
7
- import {REQUEST_IPV4} from './helpers/consts.js';
8
7
  import {getCurrentFilename, getTestFolder} from './helpers/path.js';
8
+ import {REQUEST_IPV4} from './shared/consts.js';
9
9
  import {checkCacheFile, removeCacheFolder} from './shared/fs.js';
10
10
 
11
11
  const testName = getCurrentFilename(import.meta.url);
@@ -4,8 +4,8 @@ import {describe, it} from 'mocha';
4
4
 
5
5
  import {ip2geo} from '../app/index.js';
6
6
 
7
- import {REQUEST_IPV4} from './helpers/consts.js';
8
7
  import {getCurrentFilename, getTestFolder} from './helpers/path.js';
8
+ import {REQUEST_IPV4} from './shared/consts.js';
9
9
  import {removeCacheFolder} from './shared/fs.js';
10
10
 
11
11
  const testName = getCurrentFilename(import.meta.url);
package/tests/ip-v6.js CHANGED
@@ -4,8 +4,8 @@ import {describe, it} from 'mocha';
4
4
 
5
5
  import {ip2geo} from '../app/index.js';
6
6
 
7
- import {REQUEST_IPV6} from './helpers/consts.js';
8
7
  import {getCurrentFilename, getTestFolder} from './helpers/path.js';
8
+ import {REQUEST_IPV6} from './shared/consts.js';
9
9
  import {checkCacheFile, removeCacheFolder} from './shared/fs.js';
10
10
 
11
11
  const testName = getCurrentFilename(import.meta.url);
@@ -21,9 +21,9 @@ export const REQUEST_IPV4_MAP_OFF_ONLY = {
21
21
  country: 'United States',
22
22
  countryCode: 'US',
23
23
  countryEmoji: '🇺🇸',
24
- region: 'District of Columbia',
25
- regionCode: 'DC',
26
- city: 'Washington',
24
+ region: 'California',
25
+ regionCode: 'CA',
26
+ city: 'San Jose',
27
27
  connectionAsn: 13_335,
28
28
  connectionOrg: 'APNIC and Cloudflare DNS Resolver project',
29
29
  connectionIsp: 'Cloudflare, Inc.',