From 3ec8cbd4987f7c9ba3adb56c1dedcc92e6c40dc6 Mon Sep 17 00:00:00 2001 From: Nishant Arora <1895906+whizzzkid@users.noreply.github.com> Date: Wed, 19 Oct 2022 17:34:58 -0600 Subject: [PATCH 01/14] sanity --- .editorconfig | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..8ac209c --- /dev/null +++ b/.editorconfig @@ -0,0 +1,8 @@ +root=true + +[*] +end_of_line = lf +insert_final_newline = true +charset = utf-8 +indent_style = space +indent_size = 2 From 8ce619cb2de1169a71390e93aae3bc89a31b7c90 Mon Sep 17 00:00:00 2001 From: Nishant Arora <1895906+whizzzkid@users.noreply.github.com> Date: Wed, 19 Oct 2022 17:35:18 -0600 Subject: [PATCH 02/14] not a module yet --- package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/package.json b/package.json index 225e6df..c3a2cb8 100644 --- a/package.json +++ b/package.json @@ -16,8 +16,7 @@ "src", "dist" ], - "type": "module", - "main": "src/index.js", + "main": "dist/index.min.js", "repository": { "type": "git", "url": "https://github.com/ipfs-shipyard/ipfs-geoip" From 11b64c232a909cf5162fa3a521f4148176f33417 Mon Sep 17 00:00:00 2001 From: Nishant Arora <1895906+whizzzkid@users.noreply.github.com> Date: Wed, 19 Oct 2022 17:36:24 -0600 Subject: [PATCH 03/14] unnecessary --- example/lookup.js | 1 - 1 file changed, 1 deletion(-) diff --git a/example/lookup.js b/example/lookup.js index b288ee8..db7bbc4 100644 --- a/example/lookup.js +++ b/example/lookup.js @@ -1,5 +1,4 @@ import * as geoip from '../src/index.js' -import { create } from 'ipfs-http-client' const ipfsGw = process?.env?.IPFS_GATEWAY || 'https://ipfs.io' From 6584eaf0811fa136fb219bdf7c668ab5cc7ef640 Mon Sep 17 00:00:00 2001 From: Nishant Arora <1895906+whizzzkid@users.noreply.github.com> Date: Wed, 19 Oct 2022 20:23:19 -0600 Subject: [PATCH 04/14] Building esm --- package-lock.json | 37 +++++++++++++++++++++++++++++++++++++ package.json | 14 +++++++++++++- 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index a6f2865..095da1b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,6 +24,7 @@ "chai": "^4.3.6", "chai-as-promised": "^7.1.1", "csv-parse": "^5.3.0", + "esmock": "^2.0.6", "gauge": "^4.0.4", "ipfs-http-client": "^58.0.1", "multihashes": "^4.0.3", @@ -8033,6 +8034,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/esmock": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/esmock/-/esmock-2.0.6.tgz", + "integrity": "sha512-2EY6isqPxZ9xm/nPz7DE5u/M5Nt3Xq4WUTOT5Dv9sfaqim6HZ6hitpEEfrSKAryA1JsnF/YljSRo2MZCtx0LTw==", + "dev": true, + "dependencies": { + "resolvewithplus": "^1.0.2" + }, + "engines": { + "node": ">=14.16.0" + } + }, "node_modules/espree": { "version": "9.4.0", "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", @@ -19000,6 +19013,15 @@ "node": ">=4" } }, + "node_modules/resolvewithplus": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/resolvewithplus/-/resolvewithplus-1.0.2.tgz", + "integrity": "sha512-UNvTSqWpe1lhKvXb+Qo97Q/dFUtA0kDuUG/gO7S+P9H/xYZ+A9pwlAbY6Dqp2tgAeQNdHmQG5MdNL6d9/FWo6Q==", + "dev": true, + "engines": { + "node": ">=12.16.0" + } + }, "node_modules/responselike": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", @@ -27706,6 +27728,15 @@ "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", "dev": true }, + "esmock": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/esmock/-/esmock-2.0.6.tgz", + "integrity": "sha512-2EY6isqPxZ9xm/nPz7DE5u/M5Nt3Xq4WUTOT5Dv9sfaqim6HZ6hitpEEfrSKAryA1JsnF/YljSRo2MZCtx0LTw==", + "dev": true, + "requires": { + "resolvewithplus": "^1.0.2" + } + }, "espree": { "version": "9.4.0", "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", @@ -35476,6 +35507,12 @@ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, + "resolvewithplus": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/resolvewithplus/-/resolvewithplus-1.0.2.tgz", + "integrity": "sha512-UNvTSqWpe1lhKvXb+Qo97Q/dFUtA0kDuUG/gO7S+P9H/xYZ+A9pwlAbY6Dqp2tgAeQNdHmQG5MdNL6d9/FWo6Q==", + "dev": true + }, "responselike": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", diff --git a/package.json b/package.json index c3a2cb8..50df096 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "src", "dist" ], + "type": "module", "main": "dist/index.min.js", "repository": { "type": "git", @@ -64,7 +65,18 @@ "npm": ">=8.0.0" }, "aegir": { - "tsRepo": false + "tsRepo": false, + "build": { + "config": { + "format": "esm", + "banner": { + "js": "" + }, + "footer": { + "js": "" + } + } + } }, "pre-commit": [ "lint" From e84e307432cafc6dda2a35cc8401940bd7341204 Mon Sep 17 00:00:00 2001 From: Nishant Arora <1895906+whizzzkid@users.noreply.github.com> Date: Wed, 19 Oct 2022 20:23:32 -0600 Subject: [PATCH 05/14] Adding example --- README.md | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0879e38..b93f970 100644 --- a/README.md +++ b/README.md @@ -44,13 +44,44 @@ npm install --save ipfs-geoip Instead of a local installation (and browserification) you may request a [remote copy from jsDelivr](https://www.jsdelivr.com/package/npm/ipfs-geoip): +** - + ``` When using prebuilt bundle from CDN, `ipfs-geoip` will be exposed under `window.IpfsGeoip` +**>=v9** + +```html + + + + +``` + +The response in the console looks like: +```js +{ + "country_name": "USA", + "country_code": "US", + "region_code": "VA", + "city": "Ashburn", + "postal_code": "20149", + "latitude": 39.0469, + "longitude": -77.4903, + "planet": "Earth" +} +``` ## Usage From 4c8594418f3156cd694a2ad03b0f54ad8bb74def Mon Sep 17 00:00:00 2001 From: Nishant Arora <1895906+whizzzkid@users.noreply.github.com> Date: Wed, 19 Oct 2022 23:18:35 -0600 Subject: [PATCH 06/14] Adding aegir options --- .aegir.js | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 .aegir.js diff --git a/.aegir.js b/.aegir.js new file mode 100644 index 0000000..2fe78d7 --- /dev/null +++ b/.aegir.js @@ -0,0 +1,26 @@ +export default { + tsRepo: false, + build: { + config: { + external: ['fs'], + format: 'esm', + banner: { + js: '' + }, + footer: { + js: '' + } + } + }, + test: { + before: (...args) => { + if (args[0].runner === 'node') { + return { + env: { + NODE_OPTIONS: '--loader=esmock' + } + } + } + } + } +} From 767a66794d61c0ff3aadd1f7481ae633108bb379 Mon Sep 17 00:00:00 2001 From: Nishant Arora <1895906+whizzzkid@users.noreply.github.com> Date: Wed, 19 Oct 2022 23:19:23 -0600 Subject: [PATCH 07/14] Adding retrying mechanism --- src/constants.js | 1 + src/lookup.js | 27 ++++++++++++++++++++--- test/lookupMultiple.node.spec.js | 37 ++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 3 deletions(-) create mode 100644 src/constants.js create mode 100644 test/lookupMultiple.node.spec.js diff --git a/src/constants.js b/src/constants.js new file mode 100644 index 0000000..5a796f9 --- /dev/null +++ b/src/constants.js @@ -0,0 +1 @@ +export const MAX_LOOKUP_RETRIES = 3 diff --git a/src/lookup.js b/src/lookup.js index 72563cc..5bf001b 100644 --- a/src/lookup.js +++ b/src/lookup.js @@ -1,9 +1,10 @@ import { default as memoize } from 'p-memoize' import ip from 'ip' -import * as dagCbor from '@ipld/dag-cbor' +import { decode as dagCborDecode } from '@ipld/dag-cbor' import { CID } from 'multiformats/cid' import fetch from 'cross-fetch' import { formatData } from './format.js' +import { MAX_LOOKUP_RETRIES } from './constants.js' export const GEOIP_ROOT = CID.parse('bafyreihnpl7ami7esahkfdnemm6idx4r2n6u3apmtcrxlqwuapgjsciihy') // b-tree version of GeoLite2-City-CSV_20221018 @@ -45,6 +46,27 @@ async function getRawBlock (ipfs, cid) { } } +/** + * Gets Obj and Block after retrying multiple times. + * + * @param {object|string} ipfs + * @param {CID} cid + * @param {number} numTry - this will be 1 for the first try and recurse till MAX_LOOKUP_RETRIES is reached. + * @returns {Promise<{obj, block}>} + */ +async function getObjAndBlockWithRetries (ipfs, cid, numTry = 1) { + try { + const block = await getRawBlock(ipfs, cid) + const obj = await dagCborDecode(block) + return { obj, block } + } catch (e) { + if (numTry < MAX_LOOKUP_RETRIES) { + return await getObjAndBlockWithRetries(ipfs, cid, numTry + 1) + } + throw e + } +} + /** * @param {object|string} ipfs * @param {CID} cid @@ -54,8 +76,7 @@ async function getRawBlock (ipfs, cid) { async function _lookup (ipfs, cid, lookfor) { let obj, block try { - block = await getRawBlock(ipfs, cid) - obj = await dagCbor.decode(block) + ({ obj, block } = await getObjAndBlockWithRetries(ipfs, cid)) } catch (e) { if (process?.env?.DEBUG || process?.env?.TEST) { if (!block) { diff --git a/test/lookupMultiple.node.spec.js b/test/lookupMultiple.node.spec.js new file mode 100644 index 0000000..3ff93c1 --- /dev/null +++ b/test/lookupMultiple.node.spec.js @@ -0,0 +1,37 @@ +import { decode as dagCborDecode } from '@ipld/dag-cbor' +import esmock from 'esmock' +import { expect } from 'chai' + +describe('[Runner Node]: lookup via HTTP Gateway supporting application/vnd.ipld.raw responses', function () { + const ipfsGW = process?.env?.IPFS_GATEWAY || 'https://ipfs.io' + + it('looks up multiple times before failing', async () => { + let decodeCallCount = 0 + const rewiredGeoIp = await esmock('../src/index.js', {}, { + '@ipld/dag-cbor': { + decode: (...args) => { + decodeCallCount += 1 + if (decodeCallCount === 1) { + throw new Error('Decode Failed') + } + return dagCborDecode(...args) + } + } + }) + + const result = await rewiredGeoIp.lookup(ipfsGW, '66.6.44.4') + expect(decodeCallCount).to.be.greaterThan(1) + expect( + result + ).to.be.eql({ + country_name: 'USA', + country_code: 'US', + region_code: 'VA', + city: 'Ashburn', + postal_code: '20149', + latitude: 39.0469, + longitude: -77.4903, + planet: 'Earth' + }) + }) +}) From d0ade12075c29090cb85b8f3a4b79b2b3632d1a7 Mon Sep 17 00:00:00 2001 From: Nishant Arora <1895906+whizzzkid@users.noreply.github.com> Date: Wed, 19 Oct 2022 23:19:50 -0600 Subject: [PATCH 08/14] Renaming browser test format --- test/{format.spec.js => format.browser.spec.js} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/{format.spec.js => format.browser.spec.js} (100%) diff --git a/test/format.spec.js b/test/format.browser.spec.js similarity index 100% rename from test/format.spec.js rename to test/format.browser.spec.js From 54123fa463a54f5ce4dfc0d45f9e18483eb3aaa5 Mon Sep 17 00:00:00 2001 From: Nishant Arora <1895906+whizzzkid@users.noreply.github.com> Date: Wed, 19 Oct 2022 23:20:33 -0600 Subject: [PATCH 09/14] Renaming browser test generate --- test/{generate.spec.js => generate.browser.spec.js} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/{generate.spec.js => generate.browser.spec.js} (100%) diff --git a/test/generate.spec.js b/test/generate.browser.spec.js similarity index 100% rename from test/generate.spec.js rename to test/generate.browser.spec.js From fe810e38e587470628fe949ea6e6b2e42ddab458 Mon Sep 17 00:00:00 2001 From: Nishant Arora <1895906+whizzzkid@users.noreply.github.com> Date: Wed, 19 Oct 2022 23:20:46 -0600 Subject: [PATCH 10/14] Renaming browser test lookup --- test/{lookup.spec.js => lookup.browser.spec.js} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/{lookup.spec.js => lookup.browser.spec.js} (100%) diff --git a/test/lookup.spec.js b/test/lookup.browser.spec.js similarity index 100% rename from test/lookup.spec.js rename to test/lookup.browser.spec.js From 7894d78a8fcb66ba8842d56af41095f8dbed9956 Mon Sep 17 00:00:00 2001 From: Nishant Arora <1895906+whizzzkid@users.noreply.github.com> Date: Wed, 19 Oct 2022 23:20:56 -0600 Subject: [PATCH 11/14] fixing package.json --- package.json | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/package.json b/package.json index 50df096..4eaf31e 100644 --- a/package.json +++ b/package.json @@ -26,9 +26,9 @@ "lint": "aegir lint", "release": "aegir release", "build": "aegir build", - "test": "aegir test", + "test": "npm run test:node && npm run test:browser", "test:node": "aegir test --target node", - "test:browser": "aegir test --target browser", + "test:browser": "aegir test --target browser --files test/**/*.browser.spec.{js,cjs,mjs}", "generate": "node bin/generate.js" }, "dependencies": { @@ -47,6 +47,7 @@ "chai": "^4.3.6", "chai-as-promised": "^7.1.1", "csv-parse": "^5.3.0", + "esmock": "^2.0.6", "gauge": "^4.0.4", "ipfs-http-client": "^58.0.1", "multihashes": "^4.0.3", @@ -64,20 +65,6 @@ "node": ">=16.0.0", "npm": ">=8.0.0" }, - "aegir": { - "tsRepo": false, - "build": { - "config": { - "format": "esm", - "banner": { - "js": "" - }, - "footer": { - "js": "" - } - } - } - }, "pre-commit": [ "lint" ], From 2b9ed8c98ee598e8daf107babdc824955771ca8f Mon Sep 17 00:00:00 2001 From: Nishant Arora <1895906+whizzzkid@users.noreply.github.com> Date: Wed, 19 Oct 2022 23:34:08 -0600 Subject: [PATCH 12/14] not needed --- .aegir.js | 1 - 1 file changed, 1 deletion(-) diff --git a/.aegir.js b/.aegir.js index 2fe78d7..05b296b 100644 --- a/.aegir.js +++ b/.aegir.js @@ -2,7 +2,6 @@ export default { tsRepo: false, build: { config: { - external: ['fs'], format: 'esm', banner: { js: '' From 4423251d0356423fcb7d885a37278b2124405fbf Mon Sep 17 00:00:00 2001 From: Nishant Arora <1895906+whizzzkid@users.noreply.github.com> Date: Wed, 19 Oct 2022 23:46:16 -0600 Subject: [PATCH 13/14] Adding file patterns for CI --- .github/workflows/main.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d28495b..f4be23a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -44,8 +44,8 @@ jobs: - uses: actions/checkout@v2 - uses: microsoft/playwright-github-action@v1 - run: npm install - - run: npx aegir test -t browser --bail --cov - - run: npx aegir test -t webworker --bail + - run: npx aegir test -t browser --bail --cov --files test/**/*.browser.spec.{js,cjs,mjs} + - run: npx aegir test -t webworker --bail --files test/**/*.browser.spec.{js,cjs,mjs} - uses: codecov/codecov-action@v1 test-firefox: needs: check @@ -54,7 +54,7 @@ jobs: - uses: actions/checkout@v2 - uses: microsoft/playwright-github-action@v1 - run: npm install - - run: npx aegir test -t browser -t webworker --bail -- --browser firefox + - run: npx aegir test -t browser -t webworker --bail --files test/**/*.browser.spec.{js,cjs,mjs} -- --browser firefox test-webkit: needs: check runs-on: ubuntu-latest @@ -62,11 +62,11 @@ jobs: - uses: actions/checkout@v2 - uses: microsoft/playwright-github-action@v1 - run: npm install - - run: npx aegir test -t browser -t webworker --bail -- --browser webkit + - run: npx aegir test -t browser -t webworker --bail --files test/**/*.browser.spec.{js,cjs,mjs} -- --browser webkit test-electron-main: needs: check runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - run: npm install - - run: npx xvfb-maybe aegir test -t electron-main --bail + - run: npx xvfb-maybe aegir test -t electron-main --bail --files test/**/*.browser.spec.{js,cjs,mjs} From c953962e8e64206078978ffa494b9aad6b567444 Mon Sep 17 00:00:00 2001 From: Marcin Rataj Date: Fri, 21 Oct 2022 15:39:14 +0200 Subject: [PATCH 14/14] docs: version-agnostic README Also, simplified default example to use gateway API, and not RPC --- README.md | 38 +++++++++++--------------------------- 1 file changed, 11 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index b93f970..e8fbc8d 100644 --- a/README.md +++ b/README.md @@ -42,34 +42,18 @@ npm install --save ipfs-geoip ### CDN -Instead of a local installation (and browserification) you may request a [remote copy from jsDelivr](https://www.jsdelivr.com/package/npm/ipfs-geoip): +Instead of a local installation (and browserification) you may request a specific +version `N.N.N` as a [remote copy from jsDelivr](https://www.jsdelivr.com/package/npm/ipfs-geoip): -** - -``` - -When using prebuilt bundle from CDN, `ipfs-geoip` will be exposed under `window.IpfsGeoip` - -**>=v9** - -```html - - - ``` -The response in the console looks like: +The response in the console should look similar to: ```js { "country_name": "USA", @@ -87,25 +71,25 @@ The response in the console looks like: ### With public gateways (default) -If `ipfs` is a string or array of strings with public gateway URLs, it will be used for +If `gateways` is a string or array of strings with public gateway URLs, it will be used for fetching IPFS blocks as [`application/vnd.ipld.raw`](https://www.iana.org/assignments/media-types/application/vnd.ipld.raw) -and parsing them as DAG-CBOR locally: +and parsing them as DAG-CBOR locally via [@ipld/dag-cbor](https://www.npmjs.com/package/@ipld/dag-cbor): ```js const geoip = require('ipfs-geoip') const exampleIp = '66.6.44.4' -const ipfsGw = ['https://ipfs.io', 'https://dweb.link'] +const gateways = ['https://ipfs.io', 'https://dweb.link'] try { - const result = await geoip.lookup(ipfsGw, exampleIp) + const result = await geoip.lookup(gateways, exampleIp) console.log('Result: ', result) } catch (err) { console.log('Error: ' + err) } try { - const result = await geoip.lookupPretty(ipfsGw, '/ip4/' + exampleIp) + const result = await geoip.lookupPretty(gateways, '/ip4/' + exampleIp) console.log('Pretty result: %s', result.formatted) } catch (err) { console.log('Error: ' + err)