Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chore(dev-deps) Bump typescript-eslint to v8 #1496

Merged
merged 1 commit into from
Aug 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
13 changes: 12 additions & 1 deletion eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,17 @@ export default tseslint.config(
},
{
files: ['**/*.mts', '**/*.ts'],
extends: [...tseslint.configs.recommended],
extends: [...tseslint.configs.recommendedTypeChecked],
languageOptions: {
parserOptions: {
projectService: {
allowDefaultProject: ['packages/*/*.test.mts'],
defaultProject: './tsconfig.test.json',
maximumDefaultProjectFileMatchCount_THIS_WILL_SLOW_DOWN_LINTING: 20,
},
tsconfigRootDir: import.meta.dirname,
},
},
},
{
files: ['**/*.cjs'],
Expand All @@ -55,6 +65,7 @@ export default tseslint.config(
{
files: ['packages/inquirer/test/**', 'packages/**/*.test.*'],
rules: {
'@typescript-eslint/unbound-method': 'off',
'n/no-extraneous-import': [
'error',
{
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
"ts-node": "^10.9.2",
"turbo": "^2.0.11",
"typescript": "^5.5.4",
"typescript-eslint": "^7.18.0",
"typescript-eslint": "^8.0.0",
"vitest": "^2.0.5"
},
"resolutions": {
Expand Down
2 changes: 1 addition & 1 deletion packages/checkbox/src/index.mts
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ export default createPrompt(
return ` ${item.separator}`;
}

const line = item.name || item.value;
const line = String(item.name || item.value);
if (item.disabled) {
const disabledLabel =
typeof item.disabled === 'string' ? item.disabled : '(disabled)';
Expand Down
5 changes: 3 additions & 2 deletions packages/core/core.test.mts
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,7 @@ describe('Error handling', () => {
it('prevent returning promises from useEffect hook', async () => {
const Prompt = (_config: object, done: (value: string) => void) => {
// @ts-expect-error: Testing an invalid behavior.
// eslint-disable-next-line @typescript-eslint/require-await
useEffect(async () => {
done('done');
}, []);
Expand All @@ -595,7 +596,7 @@ describe('Error handling', () => {
await expect(answer).rejects.toBeInstanceOf(ValidationError);
});

it('useEffect throws outside prompt', async () => {
it('useEffect throws outside prompt', () => {
expect(() => {
useEffect(() => {}, []);
}).toThrowErrorMatchingInlineSnapshot(
Expand All @@ -606,7 +607,7 @@ describe('Error handling', () => {
}).toThrow(HookError);
});

it('useKeypress throws outside prompt', async () => {
it('useKeypress throws outside prompt', () => {
expect(() => {
useKeypress(() => {});
}).toThrowErrorMatchingInlineSnapshot(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { describe, it, expect } from 'vitest';
import { lines } from './lines.mjs';
import { lines } from './src/lib/pagination/lines.mjs';

function renderResult(result: string[]) {
return `\n${result.join('\n')}\n`;
Expand Down
10 changes: 5 additions & 5 deletions packages/core/src/lib/hook-engine.mts
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,10 @@ export function readline(): InquirerReadline {
}

// Merge state updates happening within the callback function to avoid multiple renders.
export function withUpdates<T extends (...args: any) => any>(
export function withUpdates<R, T extends (...args: any[]) => R>(
fn: T,
): (...args: Parameters<T>) => ReturnType<T> {
const wrapped = (...args: any): ReturnType<T> => {
): (...args: Parameters<T>) => R {
const wrapped = (...args: Parameters<T>): R => {
const store = getStore();
let shouldUpdate = false;
const oldHandleChange = store.handleChange;
Expand Down Expand Up @@ -105,10 +105,10 @@ export function withPointer<Value, ReturnValue>(

const { index } = store;
const pointer: Pointer<Value> = {
get() {
get(): any {
return store.hooks[index];
},
set(value: any) {
set(value: unknown) {
store.hooks[index] = value;
},
initialized: index in store.hooks,
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/lib/make-theme.mts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { defaultTheme, type Theme } from './theme.mjs';
function isPlainObject(value: unknown): value is object {
if (typeof value !== 'object' || value === null) return false;

let proto = value;
let proto: unknown = value;
while (Object.getPrototypeOf(proto) !== null) {
proto = Object.getPrototypeOf(proto);
}
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/lib/use-keypress.mts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useEffect } from './use-effect.mjs';
import { withUpdates } from './hook-engine.mjs';

export function useKeypress(
userHandler: (event: KeypressEvent, rl: InquirerReadline) => void,
userHandler: (event: KeypressEvent, rl: InquirerReadline) => void | Promise<void>,
) {
const signal = useRef(userHandler);
signal.current = userHandler;
Expand All @@ -14,7 +14,7 @@ export function useKeypress(
let ignore = false;
const handler = withUpdates((_input: string, event: KeypressEvent) => {
if (ignore) return;
signal.current(event, rl);
void signal.current(event, rl);
});

rl.input.on('keypress', handler);
Expand Down
3 changes: 1 addition & 2 deletions packages/core/src/lib/use-state.mts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { withPointer, handleChange } from './hook-engine.mjs';

// eslint-disable-next-line @typescript-eslint/ban-types
type NotFunction<T> = T extends Function ? never : T;
type NotFunction<T> = T extends (...args: never) => unknown ? never : T;

export function useState<Value>(
defaultValue: NotFunction<Value> | (() => Value),
Expand Down
5 changes: 4 additions & 1 deletion packages/editor/editor.test.mts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ async function editorAction(error: undefined | Error, value?: string) {
if (!lastCall) throw new Error("editor wasn't open");

// Bugfix: The callback error value is nullable.
const editCallback = lastCall[1] as (error: undefined | Error, value: string) => void;
const editCallback = lastCall[1] as (
error: undefined | Error,
value: string,
) => void | Promise<void>;
await editCallback(error, value ?? '');
}

Expand Down
45 changes: 21 additions & 24 deletions packages/editor/src/index.mts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ type EditorConfig = {
};

export default createPrompt<string, EditorConfig>((config, done) => {
const { waitForUseInput = true, validate = () => true } = config;
const { waitForUseInput = true, postfix = '.txt', validate = () => true } = config;
const theme = makeTheme(config.theme);

const [status, setStatus] = useState<string>('pending');
Expand All @@ -34,31 +34,28 @@ export default createPrompt<string, EditorConfig>((config, done) => {

function startEditor(rl: InquirerReadline) {
rl.pause();
editAsync(
value,
// Note: The bind call isn't strictly required. But we need it for our mocks to work as expected.
AsyncResource.bind(async (error, answer) => {
rl.resume();
if (error) {
setError(error.toString());

// Note: The bind call isn't strictly required. But we need it for our mocks to work as expected.
const editCallback = AsyncResource.bind(async (error: Error, answer: string) => {
rl.resume();
if (error) {
setError(error.toString());
} else {
setStatus('loading');
const isValid = await validate(answer);
if (isValid === true) {
setError(undefined);
setStatus('done');
done(answer);
} else {
setStatus('loading');
const isValid = await validate(answer);
if (isValid === true) {
setError(undefined);
setStatus('done');
done(answer);
} else {
setValue(answer);
setError(isValid || 'You must provide a valid value');
setStatus('pending');
}
setValue(answer);
setError(isValid || 'You must provide a valid value');
setStatus('pending');
}
}),
{
postfix: config.postfix || '.txt',
},
);
}
});

editAsync(value, (error, answer) => void editCallback(error, answer), { postfix });
}

useEffect((rl) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ import tty from 'node:tty';
import { vi, expect, beforeEach, afterEach, describe, it, expectTypeOf } from 'vitest';
import { Observable } from 'rxjs';
import type { InquirerReadline } from '@inquirer/type';
import inquirer, { type QuestionMap } from '../src/index.mjs';
import type { Answers, Question } from '../src/types.mjs';
import { _ } from '../src/ui/prompt.mjs';
import inquirer, { type QuestionMap } from './src/index.mjs';
import type { Answers, Question } from './src/types.mjs';
import { _ } from './src/ui/prompt.mjs';

declare module '../src/index.mjs' {
declare module './src/index.mjs' {
interface QuestionMap {
stub: { answer?: string | boolean; message: string };
stub2: { answer?: string | boolean; message: string; default: string };
Expand Down Expand Up @@ -43,7 +43,7 @@ class StubPrompt {

class StubFailingPrompt {
run() {
return Promise.reject('This test prompt always reject');
return Promise.reject(new Error('This test prompt always reject'));
}

close() {}
Expand Down Expand Up @@ -635,13 +635,14 @@ describe('inquirer.prompt(...)', () => {

it('should not run prompt if answer exists for question', async () => {
const answers = await inquirer.prompt(
// @ts-expect-error Passing wrong type on purpose.
[
{
type: 'input',
name: 'prefilled',
when: throwFunc.bind(undefined, 'when') as any,
validate: throwFunc.bind(undefined, 'validate') as any,
transformer: throwFunc.bind(undefined, 'transformer') as any,
when: throwFunc.bind(undefined, 'when'),
validate: throwFunc.bind(undefined, 'validate'),
transformer: throwFunc.bind(undefined, 'transformer'),
message: 'message',
default: 'newValue',
},
Expand All @@ -654,13 +655,14 @@ describe('inquirer.prompt(...)', () => {

it('should not run prompt if nested answer exists for question', async () => {
const answers = await inquirer.prompt(
// @ts-expect-error Passing wrong type on purpose.
[
{
type: 'input',
name: 'prefilled.nested',
when: throwFunc.bind(undefined, 'when') as any,
validate: throwFunc.bind(undefined, 'validate') as any,
transformer: throwFunc.bind(undefined, 'transformer') as any,
when: throwFunc.bind(undefined, 'when'),
validate: throwFunc.bind(undefined, 'validate'),
transformer: throwFunc.bind(undefined, 'transformer'),
message: 'message',
default: 'newValue',
},
Expand Down Expand Up @@ -741,7 +743,7 @@ describe('inquirer.prompt(...)', () => {
});

describe('#restoreDefaultPrompts()', () => {
it('restore default prompts', async () => {
it('restore default prompts', () => {
class StubPrompt {
run = vi.fn(() => {
return Promise.resolve('bar');
Expand Down Expand Up @@ -891,6 +893,8 @@ describe('Non-TTY checks', () => {
});

describe('set utility function tests', () => {
/* eslint-disable @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-member-access */

it('Should set an objects property when provided a path and a value', () => {
const obj: any = {};
const path = 'a.b';
Expand Down Expand Up @@ -931,4 +935,6 @@ describe('set utility function tests', () => {

expect(obj.a.b).toBe('c');
});

/* eslint-enable @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-member-access */
});
9 changes: 4 additions & 5 deletions packages/inquirer/src/index.mts
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,9 @@ const defaultPrompts: PromptCollection = {
search,
};

type PromptReturnType<T> =
| (Promise<Prettify<T>> & {
ui: PromptsRunner<Prettify<T>>;
})
| never;
type PromptReturnType<T> = Promise<Prettify<T>> & {
ui: PromptsRunner<Prettify<T>>;
};

/**
* Create a new self-contained prompt module.
Expand Down Expand Up @@ -98,6 +96,7 @@ export function createPromptModule(opt?: StreamOptions) {
try {
return runner.run(questions, answers);
} catch (error) {
// eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors
const promise = Promise.reject(error);
return Object.assign(promise, { ui: runner });
}
Expand Down
12 changes: 6 additions & 6 deletions packages/inquirer/src/types.mts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import {
import type {
input,
select,
number,
Expand Down Expand Up @@ -75,13 +75,13 @@ type PromptConfigMap<A extends Answers> = {

export type Question<A extends Answers> = PromptConfigMap<A>[keyof PromptConfigMap<A>];

export type QuestionAnswerMap<A extends Answers> =
| Readonly<{ [name in KeyUnion<A>]: Omit<Question<A>, 'name'> }>
| never;
export type QuestionAnswerMap<A extends Answers> = Readonly<{
[name in KeyUnion<A>]: Omit<Question<A>, 'name'>;
}>;

export type QuestionArray<A extends Answers> = readonly Question<A>[] | never;
export type QuestionArray<A extends Answers> = readonly Question<A>[];

export type QuestionObservable<A extends Answers> = Observable<Question<A>> | never;
export type QuestionObservable<A extends Answers> = Observable<Question<A>>;

export type StreamOptions = Prettify<
Parameters<typeof input>[1] & { skipTTYChecks?: boolean }
Expand Down
Loading
Loading