diff --git a/.github/funding.yml b/.github/funding.yml deleted file mode 100644 index 0038dab..0000000 --- a/.github/funding.yml +++ /dev/null @@ -1 +0,0 @@ -github: sindresorhus diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 18531b3..d50ada6 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -10,13 +10,12 @@ jobs: fail-fast: false matrix: node-version: + - 18 + - 16 - 14 - - 12 - - 10 - - 8 steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v1 + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 with: node-version: ${{ matrix.node-version }} - run: npm install diff --git a/browser.js b/browser.js index 686a645..facfeb2 100644 --- a/browser.js +++ b/browser.js @@ -1,15 +1,14 @@ /* eslint-env browser */ -'use strict'; -const publicIp = require('public-ip'); +import publicIp from 'public-ip'; -const isOnline = async options => { +export default async function isOnline(options) { options = { timeout: 5000, ipVersion: 4, - ...options + ...options, }; - if (navigator && !navigator.onLine) { + if (!navigator?.onLine) { return false; } @@ -18,9 +17,7 @@ const isOnline = async options => { try { await publicIp[publicIpFunctionName](options); return true; - } catch (_) { + } catch { return false; } -}; - -module.exports = isOnline; +} diff --git a/index.d.ts b/index.d.ts index 9944e96..8cbb927 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,20 +1,20 @@ -declare namespace isOnline { - interface Options { - /** - Milliseconds to wait for a server to respond. +export type Options = { + /** + Milliseconds to wait for a server to respond. - @default 5000 - */ - readonly timeout?: number; + @default 5000 + */ + readonly timeout?: number; - /** - Internet Protocol version to use. This is an advanced option that is usually not necessary to be set, but it can prove useful to specifically assert IPv6 connectivity. + /** + [Internet Protocol version](https://en.wikipedia.org/wiki/Internet_Protocol#Version_history) to use. - @default 4 - */ - readonly ipVersion?: 4 | 6; - } -} + This is an advanced option that is usually not necessary to be set, but it can prove useful to specifically assert IPv6 connectivity. + + @default 4 + */ + readonly ipVersion?: 4 | 6; +}; /** Check if the internet connection is up. @@ -28,14 +28,10 @@ When any check succeeds, the returned Promise is resolved to `true`. @example ``` -import isOnline = require('is-online'); +import isOnline from 'is-online'; -(async () => { - console.log(await isOnline()); - //=> true -})(); +console.log(await isOnline()); +//=> true ``` */ -declare function isOnline(options?: isOnline.Options): Promise; - -export = isOnline; +export default function isOnline(options?: Options): Promise; diff --git a/index.js b/index.js index b8d992a..12f3e4a 100644 --- a/index.js +++ b/index.js @@ -1,20 +1,18 @@ -'use strict'; -const os = require('os'); -const got = require('got'); -const publicIp = require('public-ip'); -const pAny = require('p-any'); -const pTimeout = require('p-timeout'); - -// Use Array#flat when targeting Node.js 12 -const flat = array => [].concat(...array); +import os from 'node:os'; +import got, {CancelError} from 'got'; +import publicIp from 'public-ip'; +import pAny from 'p-any'; +import pTimeout from 'p-timeout'; const appleCheck = options => { const gotPromise = got('https://captive.apple.com/hotspot-detect.html', { - timeout: options.timeout, - dnsLookupIpVersion: options.ipVersion === 6 ? 'ipv6' : 'ipv4', + timeout: { + request: options.timeout, + }, + dnsLookupIpVersion: options.ipVersion, headers: { - 'user-agent': 'CaptiveNetworkSupport/1.0 wispr' - } + 'user-agent': 'CaptiveNetworkSupport/1.0 wispr', + }, }); const promise = (async () => { @@ -24,7 +22,7 @@ const appleCheck = options => { throw new Error('Apple check failed'); } } catch (error) { - if (!(error instanceof got.CancelError)) { + if (!(error instanceof CancelError)) { throw error; } } @@ -35,15 +33,16 @@ const appleCheck = options => { return promise; }; -const isOnline = options => { +// Note: It cannot be `async`` as then it looses the `.cancel()` method. +export default function isOnline(options) { options = { timeout: 5000, ipVersion: 4, - ...options + ...options, }; - if (flat(Object.values(os.networkInterfaces())).every(({internal}) => internal)) { - return Promise.resolve(false); + if (Object.values(os.networkInterfaces()).flat().every(({internal}) => internal)) { + return false; } if (![4, 6].includes(options.ipVersion)) { @@ -72,7 +71,7 @@ const isOnline = options => { queries.push(query); await query; return true; - })() + })(), ]); return pTimeout(promise, options.timeout).catch(() => { @@ -82,6 +81,15 @@ const isOnline = options => { return false; }); -}; -module.exports = isOnline; + // TODO: Use this instead when supporting AbortController. + // try { + // return await pTimeout(promise, options.timeout); + // } catch { + // for (const query of queries) { + // query.cancel(); + // } + + // return false; + // } +} diff --git a/index.test-d.ts b/index.test-d.ts index 660233e..3ff91b2 100644 --- a/index.test-d.ts +++ b/index.test-d.ts @@ -1,5 +1,5 @@ import {expectType} from 'tsd'; -import isOnline = require('.'); +import isOnline from './index.js'; expectType>(isOnline()); expectType>(isOnline({timeout: 10})); diff --git a/package.json b/package.json index 3396c07..ec1cf37 100644 --- a/package.json +++ b/package.json @@ -13,11 +13,17 @@ "contributors": [ "silverwind (github.com/silverwind)" ], + "type": "module", + "exports": { + "types": "./index.d.ts", + "node": "./index.js", + "default": "./browser.js" + }, "engines": { - "node": ">=10" + "node": ">=14.16" }, "scripts": { - "test": "xo && ava test.js && tsd" + "test": "xo && ava && tsd" }, "files": [ "index.js", @@ -47,20 +53,19 @@ "disconnected" ], "dependencies": { - "got": "^11.8.0", - "p-any": "^3.0.0", - "p-timeout": "^3.2.0", - "public-ip": "^4.0.4" + "got": "^12.1.0", + "p-any": "^4.0.0", + "p-timeout": "^5.1.0", + "public-ip": "^5.0.0" }, "devDependencies": { - "ava": "^2.4.0", - "tsd": "^0.13.1", - "xo": "^0.34.1" + "ava": "^4.3.0", + "tsd": "^0.20.0", + "xo": "^0.49.0" }, - "browser": "browser.js", - "xo": { - "rules": { - "unicorn/prefer-optional-catch-binding": "off" - } + "ava": { + "files": [ + "test.js" + ] } } diff --git a/readme.md b/readme.md index 8cd52a3..3cd0842 100644 --- a/readme.md +++ b/readme.md @@ -4,23 +4,21 @@ Works in Node.js and the browser *(with a bundler)*. -In the browser you have [`navigator.onLine`](https://developer.mozilla.org/en-US/docs/Web/API/NavigatorOnLine.onLine), but it's useless as it only tells you if there's a local connection, and not whether the internet is accessible. +In the browser, there is already [`navigator.onLine`](https://developer.mozilla.org/en-US/docs/Web/API/NavigatorOnLine.onLine), but it's useless as it only tells you if there's a local connection, and not whether the internet is accessible. ## Install -``` -$ npm install is-online +```sh +npm install is-online ``` ## Usage ```js -const isOnline = require('is-online'); +import isOnline from 'is-online'; -(async () => { - console.log(await isOnline()); - //=> true -})(); +console.log(await isOnline()); +//=> true ``` ## API @@ -44,7 +42,9 @@ Type: `number`\ Values: `4 | 6`\ Default: `4` -Internet Protocol version to use. This is an advanced option that is usually not necessary to be set, but it can prove useful to specifically assert IPv6 connectivity. +The [Internet Protocol version](https://en.wikipedia.org/wiki/Internet_Protocol#Version_history) to use. + +This is an advanced option that is usually not necessary to be set, but it can prove useful to specifically assert IPv6 connectivity. ## How it works diff --git a/test-browser.js b/test-browser.js index 010b9ed..4723c74 100644 --- a/test-browser.js +++ b/test-browser.js @@ -1,8 +1,5 @@ // Need to test manually in DevTools // $ browserify test-browser.js | pbcopy -'use strict'; -const isOnline = require('./browser'); +import isOnline from './browser.js'; -(async () => { - console.log('is online:', await isOnline()); -})(); +console.log('is online:', await isOnline()); diff --git a/test.js b/test.js index 0900483..6fc78fd 100644 --- a/test.js +++ b/test.js @@ -1,5 +1,6 @@ +import process from 'node:process'; import test from 'ava'; -import isOnline from '.'; +import isOnline from './index.js'; test('v4', async t => { t.true(await isOnline());