Skip to content

Commit

Permalink
Require Node.js 18 (#635)
Browse files Browse the repository at this point in the history
  • Loading branch information
sindresorhus committed Nov 3, 2023
1 parent 801efff commit d73468a
Show file tree
Hide file tree
Showing 20 changed files with 83 additions and 94 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/test.yml
Expand Up @@ -7,12 +7,12 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node_version: [14, 16, 18]
node_version: [18, 20]

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Use Node.js ${{ matrix.node_version }}
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node_version }}
- run: npm install
Expand Down
8 changes: 4 additions & 4 deletions examples/jest/summary.tsx
Expand Up @@ -2,10 +2,10 @@ import React from 'react';
import {Box, Text} from '../../src/index.js';

type Props = {
isFinished: boolean;
passed: number;
failed: number;
time: string;
readonly isFinished: boolean;
readonly passed: number;
readonly failed: number;
readonly time: string;
};

function Summary({isFinished, passed, failed, time}: Props) {
Expand Down
4 changes: 2 additions & 2 deletions examples/jest/test.tsx
Expand Up @@ -22,8 +22,8 @@ const getBackgroundForStatus = (status: string): string | undefined => {
};

type Props = {
status: string;
path: string;
readonly status: string;
readonly path: string;
};

function Test({status, path}: Props) {
Expand Down
4 changes: 2 additions & 2 deletions examples/use-focus-with-id/use-focus-with-id.tsx
Expand Up @@ -41,8 +41,8 @@ function Focus() {
}

type ItemProps = {
id: number;
label: string;
readonly id: number;
readonly label: string;
};

function Item({label, id}: ItemProps) {
Expand Down
43 changes: 20 additions & 23 deletions package.json
Expand Up @@ -15,7 +15,7 @@
"default": "./build/index.js"
},
"engines": {
"node": ">=14.16"
"node": ">=18"
},
"scripts": {
"dev": "tsc --watch",
Expand Down Expand Up @@ -45,33 +45,32 @@
"dependencies": {
"@alcalzone/ansi-tokenize": "^0.1.3",
"ansi-escapes": "^6.0.0",
"ansi-styles": "^6.2.1",
"auto-bind": "^5.0.1",
"chalk": "^5.2.0",
"chalk": "^5.3.0",
"cli-boxes": "^3.0.0",
"cli-cursor": "^4.0.0",
"cli-truncate": "^3.1.0",
"cli-truncate": "^4.0.0",
"code-excerpt": "^4.0.0",
"indent-string": "^5.0.0",
"is-ci": "^3.0.1",
"is-lower-case": "^2.0.2",
"is-upper-case": "^2.0.2",
"lodash": "^4.17.21",
"patch-console": "^2.0.0",
"react-reconciler": "^0.29.0",
"scheduler": "^0.23.0",
"signal-exit": "^3.0.7",
"slice-ansi": "^6.0.0",
"slice-ansi": "^7.1.0",
"stack-utils": "^2.0.6",
"string-width": "^5.1.2",
"type-fest": "^0.12.0",
"widest-line": "^4.0.1",
"wrap-ansi": "^8.1.0",
"string-width": "^7.0.0",
"type-fest": "^4.6.0",
"widest-line": "^5.0.0",
"wrap-ansi": "^9.0.0",
"ws": "^8.12.0",
"yoga-wasm-web": "~0.3.3"
},
"devDependencies": {
"@faker-js/faker": "^7.6.0",
"@sindresorhus/tsconfig": "3.0.1",
"@faker-js/faker": "^8.2.0",
"@sindresorhus/tsconfig": "^5.0.0",
"@types/benchmark": "^2.1.2",
"@types/is-ci": "^2.0.0",
"@types/lodash": "^4.14.191",
Expand All @@ -81,29 +80,27 @@
"@types/react-reconciler": "^0.28.2",
"@types/scheduler": "^0.16.2",
"@types/signal-exit": "^3.0.0",
"@types/sinon": "^9.0.4",
"@types/slice-ansi": "^4.0.0",
"@types/stack-utils": "^1.0.1",
"@types/wrap-ansi": "^3.0.0",
"@types/sinon": "^10.0.20",
"@types/stack-utils": "^2.0.2",
"@types/ws": "^8.5.4",
"@vdemedes/prettier-config": "^1.0.1",
"ava": "^5.1.1",
"boxen": "^7.0.1",
"delay": "^5.0.0",
"delay": "^6.0.0",
"eslint-config-xo-react": "0.27.0",
"eslint-plugin-react": "7.32.2",
"eslint-plugin-react": "^7.33.2",
"eslint-plugin-react-hooks": "4.6.0",
"ms": "^2.1.3",
"node-pty": "0.10.1",
"node-pty": "^1.0.0",
"p-queue": "^7.3.4",
"prettier": "^2.0.4",
"react": "^18.0.0",
"react-devtools-core": "^4.19.1",
"sinon": "^12.0.1",
"strip-ansi": "^6.0.0",
"sinon": "^17.0.0",
"strip-ansi": "^7.1.0",
"ts-node": "10.9.1",
"typescript": "^4.9.4",
"xo": "0.54.2"
"typescript": "^5.2.2",
"xo": "^0.56.0"
},
"peerDependencies": {
"@types/react": ">=18.0.0",
Expand Down
3 changes: 1 addition & 2 deletions src/components/App.tsx
Expand Up @@ -261,8 +261,7 @@ export default class App extends PureComponent<Props, State> {

focusPrevious = (): void => {
this.setState(previousState => {
const lastFocusableId =
previousState.focusables[previousState.focusables.length - 1]?.id;
const lastFocusableId = previousState.focusables.at(-1)?.id;

const previousFocusableId = this.findPreviousFocusable(previousState);

Expand Down
3 changes: 1 addition & 2 deletions src/hooks/use-input.ts
@@ -1,5 +1,4 @@
import {useEffect} from 'react';
import {isUpperCase} from 'is-upper-case';
import parseKeypress, {nonAlphanumericKeys} from '../parse-keypress.js';
import reconciler from '../reconciler.js';
import useStdin from './use-stdin.js';
Expand Down Expand Up @@ -176,7 +175,7 @@ const useInput = (inputHandler: Handler, options: Options = {}) => {
if (
input.length === 1 &&
typeof input[0] === 'string' &&
isUpperCase(input[0])
input[0].toUpperCase() === input[0]
) {
key.shift = true;
}
Expand Down
2 changes: 1 addition & 1 deletion src/output.ts
Expand Up @@ -131,7 +131,7 @@ export default class Output {
let {x, y} = operation;
let lines = text.split('\n');

const clip = clips[clips.length - 1];
const clip = clips.at(-1);

if (clip) {
const clipHorizontally =
Expand Down
2 changes: 1 addition & 1 deletion src/styles.ts
@@ -1,7 +1,7 @@
/* eslint-disable @typescript-eslint/prefer-nullish-coalescing */
import {type Boxes, type BoxStyle} from 'cli-boxes';
import {type LiteralUnion} from 'type-fest';
import {type ForegroundColorName} from 'chalk';
import {type ForegroundColorName} from 'ansi-styles'; // Note: We import directly from `ansi-styles` to avoid a bug in TypeScript.
// eslint-disable-next-line n/file-extension-in-import
import Yoga, {type Node as YogaNode} from 'yoga-wasm-web/auto';

Expand Down
2 changes: 1 addition & 1 deletion test/borders.tsx
Expand Up @@ -415,7 +415,7 @@ test('nested boxes - fit-content box with emojis on flex-direction column', t =>
test('render border after update', t => {
const stdout = createStdout();

function Test({borderColor}: {borderColor?: string}) {
function Test({borderColor}: {readonly borderColor?: string}) {
return (
<Box borderStyle="round" borderColor={borderColor}>
<Text>Hello World</Text>
Expand Down
16 changes: 8 additions & 8 deletions test/components.tsx
Expand Up @@ -375,7 +375,7 @@ test('static output', t => {
test('skip previous output when rendering new static output', t => {
const stdout = createStdout();

function Dynamic({items}: {items: string[]}) {
function Dynamic({items}: {readonly items: string[]}) {
return (
<Static items={items}>{item => <Text key={item}>{item}</Text>}</Static>
);
Expand All @@ -395,7 +395,7 @@ test('skip previous output when rendering new static output', t => {
test('render only new items in static output on final render', t => {
const stdout = createStdout();

function Dynamic({items}: {items: string[]}) {
function Dynamic({items}: {readonly items: string[]}) {
return (
<Static items={items}>{item => <Text key={item}>{item}</Text>}</Static>
);
Expand Down Expand Up @@ -426,7 +426,7 @@ test('ensure wrap-ansi doesn’t trim leading whitespace', t => {
test('replace child node with text', t => {
const stdout = createStdout();

function Dynamic({replace}: {replace?: boolean}) {
function Dynamic({replace}: {readonly replace?: boolean}) {
return <Text>{replace ? 'x' : <Text color="green">test</Text>}</Text>;
}

Expand Down Expand Up @@ -476,8 +476,8 @@ test('disable raw mode when all input components are unmounted', t => {
renderFirstInput,
renderSecondInput
}: {
renderFirstInput?: boolean;
renderSecondInput?: boolean;
readonly renderFirstInput?: boolean;
readonly renderSecondInput?: boolean;
}) {
const {setRawMode} = useStdin();

Expand Down Expand Up @@ -597,8 +597,8 @@ test('render different component based on whether stdin is a TTY or not', t => {
renderFirstInput,
renderSecondInput
}: {
renderFirstInput?: boolean;
renderSecondInput?: boolean;
readonly renderFirstInput?: boolean;
readonly renderSecondInput?: boolean;
}) {
const {isRawModeSupported, setRawMode} = useStdin();

Expand Down Expand Up @@ -660,7 +660,7 @@ test('render all frames if CI environment variable equals false', async t => {
test('reset prop when it’s removed from the element', t => {
const stdout = createStdout();

function Dynamic({remove}: {remove?: boolean}) {
function Dynamic({remove}: {readonly remove?: boolean}) {
return (
<Box
flexDirection="column"
Expand Down
6 changes: 3 additions & 3 deletions test/exit.tsx
Expand Up @@ -81,7 +81,7 @@ test.serial('don’t exit while raw mode is active', async t => {

let output = '';

term.on('data', (data: string) => {
term.onData(data => {
if (data === 's') {
setTimeout(() => {
t.false(isExited);
Expand All @@ -100,10 +100,10 @@ test.serial('don’t exit while raw mode is active', async t => {

let isExited = false;

term.on('exit', (code: any) => {
term.onExit(({exitCode}) => {
isExited = true;

if (code === 0) {
if (exitCode === 0) {
t.true(output.includes('exited'));
t.pass();
resolve();
Expand Down
2 changes: 1 addition & 1 deletion test/fixtures/use-input.tsx
Expand Up @@ -2,7 +2,7 @@ import process from 'node:process';
import React from 'react';
import {render, useInput, useApp} from '../../src/index.js';

function UserInput({test}: {test: string | undefined}) {
function UserInput({test}: {readonly test: string | undefined}) {
const {exit} = useApp();

useInput((input, key) => {
Expand Down
20 changes: 10 additions & 10 deletions test/focus.tsx
Expand Up @@ -27,13 +27,13 @@ const emitReadable = (stdin: NodeJS.WriteStream, chunk: string) => {
};

type TestProps = {
showFirst?: boolean;
disableSecond?: boolean;
autoFocus?: boolean;
disabled?: boolean;
focusNext?: boolean;
focusPrevious?: boolean;
unmountChildren?: boolean;
readonly showFirst?: boolean;
readonly disableSecond?: boolean;
readonly autoFocus?: boolean;
readonly disabled?: boolean;
readonly focusNext?: boolean;
readonly focusPrevious?: boolean;
readonly unmountChildren?: boolean;
};

function Test({
Expand Down Expand Up @@ -81,9 +81,9 @@ function Test({
}

type ItemProps = {
label: string;
autoFocus: boolean;
disabled?: boolean;
readonly label: string;
readonly autoFocus: boolean;
readonly disabled?: boolean;
};

function Item({label, autoFocus, disabled = false}: ItemProps) {
Expand Down
8 changes: 4 additions & 4 deletions test/helpers/run.ts
Expand Up @@ -42,17 +42,17 @@ export const run: Run = async (fixture, props) => {

let output = '';

term.on('data', (data: string) => {
term.onData(data => {
output += data;
});

term.on('exit', (code: number) => {
if (code === 0) {
term.onExit(({exitCode}) => {
if (exitCode === 0) {
resolve(output);
return;
}

reject(new Error(`Process exited with a non-zero code: ${output}`));
reject(new Error(`Process exited with a non-zero code: ${exitCode}`));
});
});
};
17 changes: 6 additions & 11 deletions test/hooks.tsx
@@ -1,14 +1,9 @@
import process from 'node:process';
import {createRequire} from 'node:module';
import url from 'node:url';
import * as path from 'node:path';
import path from 'node:path';
import test, {type ExecutionContext} from 'ava';
import stripAnsi from 'strip-ansi';

const require = createRequire(import.meta.url);

// eslint-disable-next-line @typescript-eslint/consistent-type-imports
const {spawn} = require('node-pty') as typeof import('node-pty');
import {spawn} from 'node-pty';

const __dirname = url.fileURLToPath(new URL('.', import.meta.url));

Expand Down Expand Up @@ -56,17 +51,17 @@ const term = (fixture: string, args: string[] = []) => {
waitForExit: async () => exitPromise
};

ps.on('data', (data: string) => {
ps.onData(data => {
result.output += data;
});

ps.on('exit', (code: number) => {
if (code === 0) {
ps.onExit(({exitCode}) => {
if (exitCode === 0) {
resolve();
return;
}

reject(new Error(`Process exited with non-zero exit code: ${code}`));
reject(new Error(`Process exited with non-zero exit code: ${exitCode}`));
});

return result;
Expand Down

0 comments on commit d73468a

Please sign in to comment.