From 035286826c46db6e8f45115f9f9d4f1295edb867 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Sat, 8 May 2021 01:45:41 +0700 Subject: [PATCH] Require Node.js 12.20 --- .github/funding.yml | 4 ---- .github/workflows/main.yml | 5 ++--- api.js | 10 +++++----- cli.js | 2 ++ license | 2 +- package.json | 27 ++++++++++++++------------- test.js | 17 ++++++----------- ui.js | 22 ++++++++++++---------- 8 files changed, 42 insertions(+), 47 deletions(-) delete mode 100644 .github/funding.yml diff --git a/.github/funding.yml b/.github/funding.yml deleted file mode 100644 index 15edf6e..0000000 --- a/.github/funding.yml +++ /dev/null @@ -1,4 +0,0 @@ -github: sindresorhus -open_collective: sindresorhus -patreon: sindresorhus -custom: https://sindresorhus.com/donate diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 18531b3..3b8aa86 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -10,13 +10,12 @@ jobs: fail-fast: false matrix: node-version: + - 16 - 14 - 12 - - 10 - - 8 steps: - uses: actions/checkout@v2 - - uses: actions/setup-node@v1 + - uses: actions/setup-node@v2 with: node-version: ${{ matrix.node-version }} - run: npm install diff --git a/api.js b/api.js index f8c32fc..c77d7a5 100644 --- a/api.js +++ b/api.js @@ -1,12 +1,12 @@ 'use strict'; /* eslint-env browser */ +const {isDeepStrictEqual} = require('util'); const puppeteer = require('puppeteer'); const Observable = require('zen-observable'); -const equals = require('deep-equal'); // TODO: Use `util.isDeepStrictEqual` when targeting Node.js 10 const delay = require('delay'); async function init(browser, page, observer, options) { - let prevResult; + let previousResult; /* eslint-disable no-constant-condition, no-await-in-loop */ while (true) { @@ -24,7 +24,7 @@ async function init(browser, page, observer, options) { }; }); - if (result.downloadSpeed > 0 && !equals(result, prevResult)) { + if (result.downloadSpeed > 0 && !isDeepStrictEqual(result, previousResult)) { observer.next(result); } @@ -34,7 +34,7 @@ async function init(browser, page, observer, options) { return; } - prevResult = result; + previousResult = result; await delay(100); } @@ -49,6 +49,6 @@ module.exports = options => ( const page = await browser.newPage(); await page.goto('https://fast.com'); await init(browser, page, observer, options); - })().catch(observer.error.bind(observer)); + })().catch(observer.error.bind(observer)); // eslint-disable-line promise/prefer-await-to-then }) ); diff --git a/cli.js b/cli.js index 0ba8774..96ea4ed 100755 --- a/cli.js +++ b/cli.js @@ -5,6 +5,8 @@ const importJsx = require('import-jsx'); const React = require('react'); const {render} = require('ink'); +// Note to self: This cannot be ESM until https://github.com/vadimdemedes/import-jsx/issues/15 is fixed. + const ui = importJsx('./ui'); const cli = meow(` diff --git a/license b/license index e7af2f7..fa7ceba 100644 --- a/license +++ b/license @@ -1,6 +1,6 @@ MIT License -Copyright (c) Sindre Sorhus (sindresorhus.com) +Copyright (c) Sindre Sorhus (https://sindresorhus.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/package.json b/package.json index afa8803..602b3ad 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "description": "Test your download and upload speed using fast.com", "license": "MIT", "repository": "sindresorhus/fast-cli", + "funding": "https://github.com/sponsors/sindresorhus", "author": { "name": "Sindre Sorhus", "email": "sindresorhus@gmail.com", @@ -13,7 +14,7 @@ "fast": "cli.js" }, "engines": { - "node": ">=8" + "node": ">=12.20" }, "scripts": { "test": "xo && ava" @@ -43,23 +44,23 @@ "mbps" ], "dependencies": { - "deep-equal": "^1.0.1", - "delay": "^4.1.0", + "delay": "^5.0.0", "import-jsx": "^4.0.0", "ink": "^3.0.8", - "ink-spinner": "^4.0.1", - "meow": "^5.0.0", - "puppeteer": "^1.12.1", - "react": "^17.0.1", - "zen-observable": "^0.8.13" + "ink-spinner": "^4.0.2", + "meow": "^9.0.0", + "puppeteer": "^9.1.1", + "react": "^16.8.0", + "zen-observable": "^0.8.15" }, "devDependencies": { - "ava": "^1.2.1", - "eslint-config-xo-react": "^0.23.0", - "eslint-plugin-react": "^7.21.5", + "ava": "^2.4.0", + "eslint-config-xo-react": "^0.25.0", + "eslint-plugin-react": "^7.23.2", "eslint-plugin-react-hooks": "^4.2.0", - "execa": "^1.0.0", - "xo": "^0.24.0" + "execa": "^5.0.0", + "p-event": "^4.2.0", + "xo": "^0.39.1" }, "xo": { "extends": [ diff --git a/test.js b/test.js index dc23bcd..d00d6fa 100644 --- a/test.js +++ b/test.js @@ -1,19 +1,14 @@ import childProcess from 'child_process'; import execa from 'execa'; +import pEvent from 'p-event'; import test from 'ava'; -test.cb('default', t => { - // TODO: Use `execa` here when the `spawn` API is done - const cp = childProcess.spawn('./cli.js', {stdio: 'inherit'}); - - cp.on('error', t.fail); - - cp.on('close', code => { - t.is(code, 0); - t.end(); - }); +test('default', async t => { + const subprocess = childProcess.spawn('./cli.js', {stdio: 'inherit'}); + t.is(await pEvent(subprocess, 'close'), 0); }); test('non-tty', async t => { - t.regex(await execa.stdout('./cli.js'), /^\d+(?:\.\d+)? \w+$/i); + const {stdout} = await execa('./cli.js'); + t.regex(stdout, /\d+(?:\.\d+)? \w+/i); }); diff --git a/ui.js b/ui.js index 95f95ad..438952a 100644 --- a/ui.js +++ b/ui.js @@ -1,11 +1,10 @@ 'use strict'; -const dns = require('dns'); +const {promises: dns} = require('dns'); const React = require('react'); const {useState, useEffect} = require('react'); const {Box, Text, Newline, useApp} = require('ink'); const Spinner = require('ink-spinner').default; - -const api = require('./api'); +const api = require('./api.js'); const FixedSpacer = ({size}) => ( <>{' '.repeat(size)} @@ -82,8 +81,10 @@ const Fast = ({singleLine, upload}) => { const {exit} = useApp(); useEffect(() => { - dns.lookup('fast.com', error => { - if (error) { + (async () => { + try { + await dns.lookup('fast.com'); + } catch (error) { setError(error.code === 'ENOTFOUND' ? 'Please check your internet connection' : `Something happened ${JSON.stringify(error)}` @@ -92,14 +93,15 @@ const Fast = ({singleLine, upload}) => { return; } + // eslint-disable-next-line unicorn/no-array-for-each api({measureUpload: upload}).forEach(result => { setData(result); - }).catch(error2 => { - setError(error2.message); + }).catch(error_ => { // eslint-disable-line promise/prefer-await-to-then + setError(error_.message); exit(); }); - }); - }, []); + })(); + }, [exit, upload]); useEffect(() => { if (data.isDone || (!upload && data.uploadSpeed)) { @@ -129,7 +131,7 @@ const Fast = ({singleLine, upload}) => { )} {isDone && } - {Object.keys(data).length !== 0 && } + {Object.keys(data).length > 0 && }