@k03mad/ip2geo 3.1.0 β†’ 4.0.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/README.md CHANGED
@@ -7,6 +7,7 @@
7
7
 
8
8
  ```bash
9
9
  npm i @k03mad/ip2geo -g
10
+ ip2geo --help
10
11
 
11
12
  ip2geo 1.1.1.1
12
13
  # {
@@ -21,8 +22,8 @@ ip2geo 1.1.1.1
21
22
  # ispDomain: 'cloudflare.com'
22
23
  # }
23
24
 
24
- ip2geo 1.1.1.1 --json
25
- # {"ip":"1.1.1.1","emoji":"πŸ‡ΊπŸ‡Έ","country":"United States","countryA2":"US","region":"District of Columbia","city":"Washington","org":"APNIC and Cloudflare DNS Resolver project","isp":"Cloudflare, Inc.","ispDomain":"cloudflare.com"}
25
+ ip2geo 1.1.1.1 8.8.8.8 --json
26
+ # [{"ip":"1.1.1.1","emoji":"πŸ‡ΊπŸ‡Έ","country":"United States","countryA2":"US","region":"District of Columbia","city":"Washington","org":"APNIC and Cloudflare DNS Resolver project","isp":"Cloudflare, Inc.","ispDomain":"cloudflare.com"},{"ip":"8.8.8.8","emoji":"πŸ‡ΊπŸ‡Έ","country":"United States","countryA2":"US","region":"California","city":"Mountain View","org":"Google LLC","isp":"Google LLC","ispDomain":"google.com"}]
26
27
  ```
27
28
 
28
29
  ## API
@@ -40,6 +41,8 @@ const info = await ip2geo('1.1.1.1', {
40
41
  cacheFileName: 'ips.log',
41
42
  cacheFileSeparator: ';;',
42
43
  cacheFileNewline: '\n',
44
+ cacheMap: new Map(),
45
+ rps: 5, // useful in Promise.all with big IPs array
43
46
  });
44
47
 
45
48
  // info {
package/app/cli.js CHANGED
@@ -1,40 +1,39 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import {log, logErrorExit} from '@k03mad/simple-log';
3
+ import {log} from '@k03mad/simple-log';
4
4
 
5
- import {codeText, errorText, nameText} from './helpers/colors.js';
5
+ import {codeText, nameText} from './helpers/colors.js';
6
6
 
7
7
  import {ip2geo} from './index.js';
8
8
 
9
- const jsonParam = '--json';
9
+ const args = process.argv.slice(2);
10
10
 
11
- let args = process.argv.slice(2);
12
-
13
- if (args.length === 0) {
11
+ if (args.includes('-h') || args.includes('--help')) {
14
12
  const prefix = codeText('$');
15
13
  const name = nameText('ip2geo');
14
+ const json = codeText('// json output for parse');
15
+ const multi = codeText('// multi IPs');
16
16
 
17
- logErrorExit([
18
- errorText('IP(s) should be passed as args'),
17
+ log([
19
18
  '',
19
+ `${prefix} ${name}`,
20
20
  `${prefix} ${name} 1.1.1.1`,
21
- `${prefix} ${name} 1.1.1.1 8.8.8.8`,
21
+ `${prefix} ${name} 1.1.1.1 -j ${json}`,
22
+ `${prefix} ${name} 1.1.1.1 --json ${json}`,
23
+ `${prefix} ${name} 1.1.1.1 8.8.8.8 ${multi}`,
24
+ `${prefix} ${name} 1.1.1.1,8.8.8.8 ${multi}`,
25
+ '',
22
26
  ]);
23
27
  }
24
28
 
25
- let json;
26
-
27
- if (args.includes(jsonParam)) {
28
- json = true;
29
- args = args.filter(elem => elem !== jsonParam);
30
- }
31
-
32
- await Promise.all(args.map(async arg => {
33
- const output = await ip2geo(arg);
29
+ const output = await Promise.all(args
30
+ .filter(arg => !arg.startsWith('-'))
31
+ .map(arg => Promise.all(arg.split(',').map(elem => ip2geo(elem)))));
34
32
 
35
- if (json) {
36
- return log(JSON.stringify(output));
37
- }
33
+ const flatten = output.flat();
38
34
 
39
- log(output);
40
- }));
35
+ if (args.includes('--json') || args.includes('-j')) {
36
+ log(JSON.stringify(flatten.length > 1 ? flatten : flatten[0]));
37
+ } else {
38
+ log(flatten);
39
+ }
@@ -1,6 +1,5 @@
1
1
  import chalk from 'chalk';
2
2
 
3
- export const errorText = chalk.red.bold.bgGray;
4
3
  export const codeText = chalk.gray;
5
4
  export const numText = chalk.blue;
6
5
  export const nameText = chalk.magenta;
package/app/index.js CHANGED
@@ -1 +1 @@
1
- export {default as ip2geo} from './lib/ip2geo.js';
1
+ export * from './lib/ip2geo.js';
package/app/lib/ip2geo.js CHANGED
@@ -26,8 +26,9 @@ const DEFAULT_CACHE_FILE_DIR = path.join(os.tmpdir(), '.ip2geo');
26
26
  const DEFAULT_CACHE_FILE_NAME = 'ips.log';
27
27
  const DEFAULT_CACHE_FILE_SEPARATOR = ';;';
28
28
  const DEFAULT_CACHE_FILE_NEWLINE = '\n';
29
+ const DEFAULT_RPS = 5;
29
30
 
30
- const cacheMap = new Map();
31
+ export const cacheStorage = new Map();
31
32
 
32
33
  const outputKeys = [
33
34
  'ip',
@@ -110,13 +111,17 @@ const writeToFsCache = async (ip, data, cacheDir, cacheFileName, cacheFileSepara
110
111
  * @param {string} [opts.cacheFileName]
111
112
  * @param {string} [opts.cacheFileSeparator]
112
113
  * @param {string} [opts.cacheFileNewline]
114
+ * @param {Map} [opts.cacheMap]
115
+ * @param {number} opts.rps
113
116
  * @returns {Promise<GeoIpOutput>}
114
117
  */
115
- export default async (ip = '', {
118
+ export const ip2geo = async (ip = '', {
116
119
  cacheDir = DEFAULT_CACHE_FILE_DIR,
117
120
  cacheFileName = DEFAULT_CACHE_FILE_NAME,
118
121
  cacheFileSeparator = DEFAULT_CACHE_FILE_SEPARATOR,
119
122
  cacheFileNewline = DEFAULT_CACHE_FILE_NEWLINE,
123
+ cacheMap = cacheStorage,
124
+ rps = DEFAULT_RPS,
120
125
  } = {}) => {
121
126
  if (ip) {
122
127
  const ipData = cacheMap.get(ip);
@@ -145,7 +150,7 @@ export default async (ip = '', {
145
150
  }
146
151
  }
147
152
 
148
- const {body} = await request(API + ip);
153
+ const {body} = await request(API + ip, {}, {rps});
149
154
 
150
155
  if (!body?.ip) {
151
156
  throw new Error(`API error:\n${body}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@k03mad/ip2geo",
3
- "version": "3.1.0",
3
+ "version": "4.0.0",
4
4
  "description": "GeoIP library",
5
5
  "maintainers": [
6
6
  "Kirill Molchanov <k03.mad@gmail.com"
@@ -19,13 +19,13 @@
19
19
  "node": ">=20"
20
20
  },
21
21
  "dependencies": {
22
- "@k03mad/request": "5.4.1",
23
- "@k03mad/simple-log": "2.0.0",
22
+ "@k03mad/request": "5.5.0",
23
+ "@k03mad/simple-log": "2.1.0",
24
24
  "chalk": "5.3.0",
25
25
  "debug": "4.3.4"
26
26
  },
27
27
  "devDependencies": {
28
- "@k03mad/eslint-config": "19.3.0",
28
+ "@k03mad/eslint-config": "19.4.0",
29
29
  "eslint": "8.56.0",
30
30
  "husky": "8.0.3",
31
31
  "mocha": "10.2.0"
@@ -0,0 +1,33 @@
1
+ import os from 'node:os';
2
+ import path from 'node:path';
3
+
4
+ export const DEFAULT_OPTS = {
5
+ cacheDir: path.join(os.tmpdir(), '.ip2geo'),
6
+ cacheFileName: 'ips.log',
7
+ cacheFileSeparator: ';;',
8
+ cacheFileNewline: '\n',
9
+ };
10
+
11
+ export const REQUEST_IPV4 = {
12
+ ip: '8.8.8.8',
13
+ emoji: 'πŸ‡ΊπŸ‡Έ',
14
+ country: 'United States',
15
+ countryA2: 'US',
16
+ region: 'California',
17
+ city: 'Mountain View',
18
+ org: 'Google LLC',
19
+ isp: 'Google LLC',
20
+ ispDomain: 'google.com',
21
+ };
22
+
23
+ export const REQUEST_IPV6 = {
24
+ ip: '2a00:dd80:40:100::',
25
+ emoji: 'πŸ‡³πŸ‡±',
26
+ country: 'Netherlands',
27
+ countryA2: 'NL',
28
+ region: 'North Holland',
29
+ city: 'Amsterdam',
30
+ org: '',
31
+ isp: 'NetActuate Inc',
32
+ ispDomain: '',
33
+ };
@@ -0,0 +1,33 @@
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 {REQUEST_IPV4} from './helpers/consts.js';
8
+ import {getCurrentFilename, getTestFolder} from './helpers/path.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
+ cacheFileName: 'ips.md',
17
+ cacheFileSeparator: '-_-',
18
+ cacheFileNewline: '%%%',
19
+ cacheMap: new Map(),
20
+ };
21
+
22
+ it('should remove fs cache dir if exist', () => removeCacheFolder(opts.cacheDir));
23
+
24
+ it(`should return correct response for IP: "${REQUEST_IPV4.ip}"`, async () => {
25
+ const data = await ip2geo(REQUEST_IPV4.ip, opts);
26
+ assert.deepEqual(data, REQUEST_IPV4);
27
+ });
28
+
29
+ it('should have cache file', () => checkCacheFile({
30
+ ...opts,
31
+ response: REQUEST_IPV4,
32
+ }));
33
+ });
@@ -0,0 +1,43 @@
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 {REQUEST_IPV4, REQUEST_IPV6} from './helpers/consts.js';
8
+ import {getCurrentFilename, getTestFolder} from './helpers/path.js';
9
+ import {removeCacheFolder} from './shared/fs.js';
10
+
11
+ const testName = getCurrentFilename(import.meta.url);
12
+
13
+ describe(testName, () => {
14
+ const cacheMap = new Map();
15
+
16
+ const opts = {
17
+ cacheDir: getTestFolder(testName),
18
+ cacheMap,
19
+ };
20
+
21
+ it('should remove fs cache dir if exist', () => removeCacheFolder(opts.cacheDir));
22
+
23
+ it(`should return correct response for IP: "${REQUEST_IPV4.ip}"`, async () => {
24
+ const data = await ip2geo(REQUEST_IPV4.ip, opts);
25
+ assert.deepEqual(data, REQUEST_IPV4);
26
+ });
27
+
28
+ it('should have 1 correct cache entry', () => {
29
+ assert.equal(cacheMap.size, 1);
30
+ assert.deepEqual(cacheMap.get(REQUEST_IPV4.ip), REQUEST_IPV4);
31
+ });
32
+
33
+ it(`should return correct response for IP: "${REQUEST_IPV6.ip}"`, async () => {
34
+ const data = await ip2geo(REQUEST_IPV6.ip, opts);
35
+ assert.deepEqual(data, REQUEST_IPV6);
36
+ });
37
+
38
+ it('should have 2 correct cache entries', () => {
39
+ assert.equal(cacheMap.size, 2);
40
+ assert.deepEqual(cacheMap.get(REQUEST_IPV4.ip), REQUEST_IPV4);
41
+ assert.deepEqual(cacheMap.get(REQUEST_IPV6.ip), REQUEST_IPV6);
42
+ });
43
+ });
@@ -4,48 +4,28 @@ 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';
7
8
  import {getCurrentFilename, getTestFolder} from './helpers/path.js';
8
9
  import {checkCacheFile, removeCacheFolder} from './shared/fs.js';
9
10
 
10
11
  const testName = getCurrentFilename(import.meta.url);
11
12
 
12
13
  describe(testName, () => {
13
- const CACHE_FILE_DIR = getTestFolder(testName);
14
- const CACHE_FILE_NAME = 'ips.log';
15
- const CACHE_FILE_SEPARATOR = ';;';
16
- const CACHE_FILE_NEWLINE = '\n';
17
-
18
- const REQUEST_IP = '2a00:dd80:40:100::';
19
-
20
- const cacheFile = `${REQUEST_IP.split(/\.|:/)[0]}_${CACHE_FILE_NAME}`;
21
-
22
- const response = {
23
- ip: REQUEST_IP,
24
- emoji: 'πŸ‡³πŸ‡±',
25
- country: 'Netherlands',
26
- countryA2: 'NL',
27
- region: 'North Holland',
28
- city: 'Amsterdam',
29
- org: '',
30
- isp: 'NetActuate Inc',
31
- ispDomain: '',
14
+ const opts = {
15
+ cacheDir: getTestFolder(testName),
16
+ cacheMap: new Map(),
32
17
  };
33
18
 
34
- it('should remove fs cache dir if exist', () => removeCacheFolder(CACHE_FILE_DIR));
19
+ it('should remove fs cache dir if exist', () => removeCacheFolder(opts.cacheDir));
35
20
 
36
- it(`should return correct response for IP: "${REQUEST_IP}"`, async () => {
37
- const data = await ip2geo(REQUEST_IP, {
38
- cacheDir: CACHE_FILE_DIR,
39
- });
21
+ it(`should return correct response for IP: "${REQUEST_IPV6.ip}"`, async () => {
22
+ const data = await ip2geo(REQUEST_IPV6.ip, opts);
40
23
 
41
- assert.deepEqual(data, response);
24
+ assert.deepEqual(data, REQUEST_IPV6);
42
25
  });
43
26
 
44
- it('should have cache file', () => checkCacheFile(
45
- CACHE_FILE_DIR,
46
- cacheFile,
47
- CACHE_FILE_SEPARATOR,
48
- CACHE_FILE_NEWLINE,
49
- response,
50
- ));
27
+ it('should have cache file', () => checkCacheFile({
28
+ ...opts,
29
+ response: REQUEST_IPV6,
30
+ }));
51
31
  });
@@ -0,0 +1,33 @@
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 {REQUEST_IPV4} from './helpers/consts.js';
8
+ import {getCurrentFilename, getTestFolder} from './helpers/path.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
+ requestsCount: 5,
18
+ };
19
+
20
+ it('should remove fs cache dir if exist', () => removeCacheFolder(opts.cacheDir));
21
+
22
+ Array.from({length: opts.requestsCount}).forEach(() => {
23
+ it(`should return correct response for IP: "${REQUEST_IPV4.ip}"`, async () => {
24
+ const data = await ip2geo(REQUEST_IPV4.ip, opts);
25
+ assert.deepEqual(data, REQUEST_IPV4);
26
+ });
27
+ });
28
+
29
+ it('should have cache file', () => checkCacheFile({
30
+ ...opts,
31
+ response: REQUEST_IPV4,
32
+ }));
33
+ });
@@ -0,0 +1,33 @@
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 {REQUEST_IPV4} from './helpers/consts.js';
8
+ import {getCurrentFilename, getTestFolder} from './helpers/path.js';
9
+ import {removeCacheFolder} from './shared/fs.js';
10
+
11
+ const testName = getCurrentFilename(import.meta.url);
12
+
13
+ describe(testName, () => {
14
+ const response = {ip: '10.10.10.10'};
15
+
16
+ Object.keys(REQUEST_IPV4).forEach(elem => {
17
+ if (elem !== 'ip') {
18
+ response[elem] = undefined;
19
+ }
20
+ });
21
+
22
+ const opts = {
23
+ cacheDir: getTestFolder(testName),
24
+ cacheMap: new Map(),
25
+ };
26
+
27
+ it('should remove fs cache dir if exist', () => removeCacheFolder(opts.cacheDir));
28
+
29
+ it(`should return empty response for IP: "${response.ip}"`, async () => {
30
+ const data = await ip2geo(response.ip, opts);
31
+ assert.deepEqual(data, response);
32
+ });
33
+ });
@@ -5,54 +5,33 @@ 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';
8
9
  import {getCurrentFilename, getTestFolder} from './helpers/path.js';
9
10
  import {checkCacheFile, removeCacheFolder} from './shared/fs.js';
10
11
 
11
12
  const testName = getCurrentFilename(import.meta.url);
12
- const SUBFOLDERS = 5;
13
13
 
14
14
  describe(testName, () => {
15
- const CACHE_FILE_DIR = getTestFolder(
16
- path.join(
17
- ...Array.from({length: SUBFOLDERS}, () => testName),
15
+ const SUBFOLDERS = 5;
16
+
17
+ const opts = {
18
+ cacheDir: getTestFolder(
19
+ path.join(
20
+ ...Array.from({length: SUBFOLDERS}, () => testName),
21
+ ),
18
22
  ),
19
- );
20
-
21
- const CACHE_FILE_NAME = 'ips.log';
22
- const CACHE_FILE_SEPARATOR = ';;';
23
- const CACHE_FILE_NEWLINE = '\n';
24
-
25
- const REQUEST_IP = '9.9.9.9';
26
-
27
- const cacheFile = `${REQUEST_IP.split(/\.|:/)[0]}_${CACHE_FILE_NAME}`;
28
-
29
- const response = {
30
- ip: REQUEST_IP,
31
- emoji: 'πŸ‡¨πŸ‡­',
32
- country: 'Switzerland',
33
- countryA2: 'CH',
34
- region: 'Zurich',
35
- city: 'ZΓΌrich',
36
- org: 'Quad9',
37
- isp: 'Quad9',
38
- ispDomain: 'quad9.net',
23
+ cacheMap: new Map(),
39
24
  };
40
25
 
41
- it('should remove fs cache dir if exist', () => removeCacheFolder(CACHE_FILE_DIR));
42
-
43
- it(`should return correct response for IP: "${REQUEST_IP}"`, async () => {
44
- const data = await ip2geo(REQUEST_IP, {
45
- cacheDir: CACHE_FILE_DIR,
46
- });
26
+ it('should remove fs cache dir if exist', () => removeCacheFolder(opts.cacheDir));
47
27
 
48
- assert.deepEqual(data, response);
28
+ it(`should return correct response for IP: "${REQUEST_IPV4.ip}"`, async () => {
29
+ const data = await ip2geo(REQUEST_IPV4.ip, opts);
30
+ assert.deepEqual(data, REQUEST_IPV4);
49
31
  });
50
32
 
51
- it('should have cache file', () => checkCacheFile(
52
- CACHE_FILE_DIR,
53
- cacheFile,
54
- CACHE_FILE_SEPARATOR,
55
- CACHE_FILE_NEWLINE,
56
- response,
57
- ));
33
+ it('should have cache file', () => checkCacheFile({
34
+ ...opts,
35
+ response: REQUEST_IPV4,
36
+ }));
58
37
  });
@@ -1,63 +1,32 @@
1
1
  import assert from 'node:assert/strict';
2
- import os from 'node:os';
3
- import path from 'node:path';
4
2
 
5
3
  import {describe, it} from 'mocha';
6
4
 
7
- import {ip2geo} from '../app/index.js';
5
+ import {cacheStorage, ip2geo} from '../app/index.js';
8
6
 
7
+ import {REQUEST_IPV4} from './helpers/consts.js';
8
+ import {getCurrentFilename} from './helpers/path.js';
9
9
  import {checkCacheFile, removeCacheFolder} from './shared/fs.js';
10
10
 
11
- describe('opts-default', () => {
12
- const CACHE_FILE_DIR = path.join(os.tmpdir(), '.ip2geo');
13
- const CACHE_FILE_NAME = 'ips.log';
14
- const CACHE_FILE_SEPARATOR = ';;';
15
- const CACHE_FILE_NEWLINE = '\n';
11
+ const testName = getCurrentFilename(import.meta.url);
16
12
 
17
- const REQUEST_IP = '1.1.1.1';
18
-
19
- const cacheFile = `${REQUEST_IP.split(/\.|:/)[0]}_${CACHE_FILE_NAME}`;
20
-
21
- const response = {
22
- ip: REQUEST_IP,
23
- emoji: 'πŸ‡ΊπŸ‡Έ',
24
- country: 'United States',
25
- countryA2: 'US',
26
- region: 'District of Columbia',
27
- city: 'Washington',
28
- org: 'APNIC and Cloudflare DNS Resolver project',
29
- isp: 'Cloudflare, Inc.',
30
- ispDomain: 'cloudflare.com',
31
- };
32
-
33
- const outputKeys = [
34
- 'ip',
35
- 'emoji',
36
- 'country',
37
- 'countryA2',
38
- 'region',
39
- 'city',
40
- 'org',
41
- 'isp',
42
- 'ispDomain',
43
- ];
44
-
45
- removeCacheFolder(CACHE_FILE_DIR);
13
+ describe(testName, () => {
14
+ it('should remove fs cache dir if exist', () => removeCacheFolder());
46
15
 
47
16
  describe('with ip arg', () => {
48
- it(`should return correct response for IP: "${REQUEST_IP}"`, async () => {
49
- const data = await ip2geo(REQUEST_IP);
50
-
51
- assert.deepEqual(data, response);
17
+ it(`should return correct response for IP: "${REQUEST_IPV4.ip}"`, async () => {
18
+ const data = await ip2geo(REQUEST_IPV4.ip);
19
+ assert.deepEqual(data, REQUEST_IPV4);
52
20
  });
53
21
 
54
- it('should have cache file', () => checkCacheFile(
55
- CACHE_FILE_DIR,
56
- cacheFile,
57
- CACHE_FILE_SEPARATOR,
58
- CACHE_FILE_NEWLINE,
59
- response,
60
- ));
22
+ it('should have cache file', () => checkCacheFile({
23
+ response: REQUEST_IPV4,
24
+ }));
25
+
26
+ it('should have 1 correct cache entry', () => {
27
+ assert.equal(cacheStorage.size, 1);
28
+ assert.deepEqual(cacheStorage.get(REQUEST_IPV4.ip), REQUEST_IPV4);
29
+ });
61
30
  });
62
31
 
63
32
  describe('without ip arg', () => {
@@ -67,14 +36,19 @@ describe('opts-default', () => {
67
36
  data = await ip2geo();
68
37
  });
69
38
 
70
- outputKeys.forEach(key => {
39
+ Object.keys(REQUEST_IPV4).forEach(key => {
71
40
  it(`should have "${key}" in request response`, () => {
72
41
  assert.ok(data[key]);
73
42
  });
74
43
  });
75
44
 
76
45
  it('should not have extra keys in request response', () => {
77
- assert.deepEqual(Object.keys(data), outputKeys);
46
+ assert.deepEqual(Object.keys(data), Object.keys(REQUEST_IPV4));
47
+ });
48
+
49
+ it('should have 2 cache entries', () => {
50
+ assert.equal(cacheStorage.size, 2);
51
+ assert.deepEqual(cacheStorage.get(REQUEST_IPV4.ip), REQUEST_IPV4);
78
52
  });
79
53
  });
80
54
  });
@@ -2,10 +2,12 @@ import assert from 'node:assert/strict';
2
2
  import fs from 'node:fs/promises';
3
3
  import path from 'node:path';
4
4
 
5
+ import {DEFAULT_OPTS} from '../helpers/consts.js';
6
+
5
7
  /**
6
8
  * @param {string} cacheDir
7
9
  */
8
- export const removeCacheFolder = async cacheDir => {
10
+ export const removeCacheFolder = async (cacheDir = DEFAULT_OPTS.cacheDir) => {
9
11
  try {
10
12
  await fs.rm(cacheDir, {recursive: true, force: true});
11
13
  } catch (err) {
@@ -16,14 +18,22 @@ export const removeCacheFolder = async cacheDir => {
16
18
  };
17
19
 
18
20
  /**
19
- * @param {string} cacheDir
20
- * @param {string} cacheFileName
21
- * @param {string} cacheFileSeparator
22
- * @param {string} cacheFileNewline
23
- * @param {object} response
21
+ * @param {object} opts
22
+ * @param {string} opts.cacheDir
23
+ * @param {string} opts.cacheFileName
24
+ * @param {string} opts.cacheFileSeparator
25
+ * @param {string} opts.cacheFileNewline
26
+ * @param {object} opts.response
24
27
  */
25
- export const checkCacheFile = async (cacheDir, cacheFileName, cacheFileSeparator, cacheFileNewline, response) => {
26
- const data = await fs.readFile(path.join(cacheDir, cacheFileName), {encoding: 'utf8'});
28
+ export const checkCacheFile = async ({
29
+ cacheDir = DEFAULT_OPTS.cacheDir,
30
+ cacheFileName = DEFAULT_OPTS.cacheFileName,
31
+ cacheFileSeparator = DEFAULT_OPTS.cacheFileSeparator,
32
+ cacheFileNewline = DEFAULT_OPTS.cacheFileNewline,
33
+ response,
34
+ }) => {
35
+ const cacheFile = `${response.ip.split(/\.|:/)[0]}_${cacheFileName}`;
36
+ const data = await fs.readFile(path.join(cacheDir, cacheFile), {encoding: 'utf8'});
27
37
 
28
38
  assert.equal(data, Object.values(response).join(cacheFileSeparator) + cacheFileNewline);
29
39
  };
@@ -1,54 +0,0 @@
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 {checkCacheFile, removeCacheFolder} from './shared/fs.js';
9
-
10
- const testName = getCurrentFilename(import.meta.url);
11
-
12
- describe(testName, () => {
13
- const CACHE_FILE_DIR = getTestFolder(testName);
14
- const CACHE_FILE_NAME = 'ips.md';
15
- const CACHE_FILE_SEPARATOR = '-_-';
16
- const CACHE_FILE_NEWLINE = '%%%';
17
-
18
- const REQUEST_IP = '8.8.8.8';
19
-
20
- const cacheFile = `${REQUEST_IP.split(/\.|:/)[0]}_${CACHE_FILE_NAME}`;
21
-
22
- const response = {
23
- ip: REQUEST_IP,
24
- emoji: 'πŸ‡ΊπŸ‡Έ',
25
- country: 'United States',
26
- countryA2: 'US',
27
- region: 'California',
28
- city: 'Mountain View',
29
- org: 'Google LLC',
30
- isp: 'Google LLC',
31
- ispDomain: 'google.com',
32
- };
33
-
34
- it('should remove fs cache dir if exist', () => removeCacheFolder(CACHE_FILE_DIR));
35
-
36
- it(`should return correct response for IP: "${REQUEST_IP}"`, async () => {
37
- const data = await ip2geo(REQUEST_IP, {
38
- cacheDir: CACHE_FILE_DIR,
39
- cacheFileName: CACHE_FILE_NAME,
40
- cacheFileSeparator: CACHE_FILE_SEPARATOR,
41
- cacheFileNewline: CACHE_FILE_NEWLINE,
42
- });
43
-
44
- assert.deepEqual(data, response);
45
- });
46
-
47
- it('should have cache file', () => checkCacheFile(
48
- CACHE_FILE_DIR,
49
- cacheFile,
50
- CACHE_FILE_SEPARATOR,
51
- CACHE_FILE_NEWLINE,
52
- response,
53
- ));
54
- });