Skip to content

Commit 56ead32

Browse files
authored
refactor: add eslint rules and refactor based on that (#91)
1 parent 5832a09 commit 56ead32

File tree

9 files changed

+73
-60
lines changed

9 files changed

+73
-60
lines changed

bin/package-manager-completion.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import {
44
} from 'child_process';
55
import { RootCommand } from '../src/t.js';
66

7+
const noop = () => {};
8+
79
function debugLog(...args: unknown[]) {
810
if (process.env.DEBUG) {
911
console.error('[DEBUG]', ...args);
@@ -47,7 +49,9 @@ async function checkCliHasCompletions(
4749
try {
4850
const result = runCompletionCommand(cliName, [], []);
4951
if (result) return true;
50-
} catch {}
52+
} catch {
53+
noop();
54+
}
5155

5256
try {
5357
const result = runCompletionCommand(packageManager, [cliName], []);
@@ -67,7 +71,9 @@ async function getCliCompletions(
6771
if (result) {
6872
return result.split('\n').filter(Boolean);
6973
}
70-
} catch {}
74+
} catch {
75+
noop();
76+
}
7177

7278
try {
7379
const result = runCompletionCommand(packageManager, [cliName], args);

eslint.config.js

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,47 @@ import { configs as tseslintConfigs } from 'typescript-eslint';
33
import prettierConfig from 'eslint-config-prettier';
44

55
const { configs: eslintConfigs } = eslintjs;
6+
const completionFileGlobs = [
7+
'src/**/*.ts',
8+
'bin/**/*.ts',
9+
'benchmarks/**/*.ts',
10+
'*.ts',
11+
];
612

713
export default [
14+
{
15+
ignores: ['dist/**'],
16+
},
817
{
918
...eslintConfigs.recommended,
10-
files: ['src/**/*.ts'],
19+
files: completionFileGlobs,
1120
},
1221
...tseslintConfigs.strict,
1322
{
23+
files: completionFileGlobs,
1424
rules: {
15-
'@typescript-eslint/no-unused-vars': 'off',
25+
'@typescript-eslint/no-unused-vars': [
26+
'error',
27+
{
28+
argsIgnorePattern: '^_',
29+
varsIgnorePattern: '^_',
30+
caughtErrorsIgnorePattern: '^ignore',
31+
ignoreRestSiblings: true,
32+
},
33+
],
34+
'@typescript-eslint/consistent-type-imports': [
35+
'warn',
36+
{
37+
prefer: 'type-imports',
38+
fixStyle: 'separate-type-imports',
39+
},
40+
],
41+
'@typescript-eslint/consistent-type-definitions': ['error', 'interface'],
42+
'default-case-last': 'error',
43+
eqeqeq: ['error', 'smart'],
44+
'no-fallthrough': ['error', { allowEmptyCase: true }],
45+
'prefer-template': 'error',
46+
'no-console': 'off',
1647
},
1748
},
1849
prettierConfig,

src/cac.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import * as fish from './fish';
44
import * as powershell from './powershell';
55
import type { CAC } from 'cac';
66
import { assertDoubleDashes } from './shared';
7-
import { CompletionConfig } from './shared';
8-
import t, { RootCommand } from './t';
7+
import type { CompletionConfig } from './shared';
8+
import t, { type RootCommand } from './t';
99

1010
const execPath = process.execPath;
1111
const processArgs = process.argv.slice(1);

src/citty.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { ArgDef, defineCommand } from 'citty';
1+
import { defineCommand } from 'citty';
2+
import type { ArgDef } from 'citty';
23
import * as zsh from './zsh';
34
import * as bash from './bash';
45
import * as fish from './fish';
@@ -10,8 +11,9 @@ import type {
1011
SubCommandsDef,
1112
} from 'citty';
1213
import { generateFigSpec } from './fig';
13-
import { CompletionConfig, assertDoubleDashes } from './shared';
14-
import t, { RootCommand } from './t';
14+
import { assertDoubleDashes } from './shared';
15+
import type { CompletionConfig } from './shared';
16+
import t, { type RootCommand } from './t';
1517

1618
function quoteIfNeeded(path: string) {
1719
return path.includes(' ') ? `'${path}'` : path;

src/commander.ts

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import * as bash from './bash';
33
import * as fish from './fish';
44
import * as powershell from './powershell';
55
import type { Command as CommanderCommand, ParseOptions } from 'commander';
6-
import t, { RootCommand } from './t';
6+
import t, { type RootCommand } from './t';
77
import { assertDoubleDashes } from './shared';
88

99
const execPath = process.execPath;
@@ -22,10 +22,10 @@ export default function tab(instance: CommanderCommand): RootCommand {
2222
const programName = instance.name();
2323

2424
// Process the root command
25-
processRootCommand(instance, programName);
25+
processRootCommand(instance);
2626

2727
// Process all subcommands
28-
processSubcommands(instance, programName);
28+
processSubcommands(instance);
2929

3030
// Add the complete command for normal shell script generation
3131
instance
@@ -101,10 +101,7 @@ export default function tab(instance: CommanderCommand): RootCommand {
101101
return t;
102102
}
103103

104-
function processRootCommand(
105-
command: CommanderCommand,
106-
programName: string
107-
): void {
104+
function processRootCommand(command: CommanderCommand): void {
108105
// Add root command options to the root t instance
109106
for (const option of command.options) {
110107
// Extract short flag from the name if it exists (e.g., "-c, --config" -> "c")
@@ -122,10 +119,7 @@ function processRootCommand(
122119
}
123120
}
124121

125-
function processSubcommands(
126-
rootCommand: CommanderCommand,
127-
programName: string
128-
): void {
122+
function processSubcommands(rootCommand: CommanderCommand): void {
129123
// Build a map of command paths
130124
const commandMap = new Map<string, CommanderCommand>();
131125

src/fig.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,40 @@
11
import type { CommandDef, ArgsDef, PositionalArgDef, CommandMeta } from 'citty';
22

3-
type FigSpec = {
3+
interface FigSpec {
44
name: string;
55
description: string;
66
options?: FigOption[];
77
subcommands?: FigSubcommand[];
88
args?: FigArg[];
9-
};
9+
}
1010

11-
type FigOption = {
11+
interface FigOption {
1212
name: string;
1313
description: string;
1414
args?: FigArg[];
1515
isRequired?: boolean;
16-
};
16+
}
1717

18-
type FigSubcommand = {
18+
interface FigSubcommand {
1919
name: string;
2020
description: string;
2121
options?: FigOption[];
2222
subcommands?: FigSubcommand[];
2323
args?: FigArg[];
24-
};
24+
}
2525

26-
type FigArg = {
26+
interface FigArg {
2727
name: string;
2828
description?: string;
2929
isOptional?: boolean;
3030
isVariadic?: boolean;
3131
suggestions?: FigSuggestion[];
32-
};
32+
}
3333

34-
type FigSuggestion = {
34+
interface FigSuggestion {
3535
name: string;
3636
description?: string;
37-
};
37+
}
3838

3939
async function processArgs<T extends ArgsDef>(
4040
args: T

src/powershell.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,7 @@ import { ShellCompDirective } from './t';
22

33
// TODO: issue with -- -- completions
44

5-
export function generate(
6-
name: string,
7-
exec: string,
8-
includeDesc = false
9-
): string {
5+
export function generate(name: string, exec: string): string {
106
// Replace '-' and ':' with '_' for variable names
117
const nameForVar = name.replace(/[-:]/g, '_');
128

src/shared.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { OptionHandler, ArgumentHandler } from './t';
1+
import type { OptionHandler, ArgumentHandler } from './t';
22

33
export const noopHandler: OptionHandler = function () {
44
// No-op handler for options

src/t.ts

Lines changed: 8 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ export type OptionHandler = (
2020
options: OptionsMap
2121
) => void;
2222

23-
export type Completion = {
23+
export interface Completion {
2424
description?: string;
2525
value: string;
26-
};
26+
}
2727

2828
export type ArgumentHandler = (
2929
this: Argument,
@@ -214,8 +214,7 @@ export class RootCommand extends Command {
214214

215215
private shouldCompleteFlags(
216216
lastPrevArg: string | undefined,
217-
toComplete: string,
218-
endsWithSpace: boolean
217+
toComplete: string
219218
): boolean {
220219
if (toComplete.startsWith('-')) {
221220
return true;
@@ -244,10 +243,7 @@ export class RootCommand extends Command {
244243
return false;
245244
}
246245

247-
private shouldCompleteCommands(
248-
toComplete: string,
249-
endsWithSpace: boolean
250-
): boolean {
246+
private shouldCompleteCommands(toComplete: string): boolean {
251247
return !toComplete.startsWith('-');
252248
}
253249

@@ -256,7 +252,6 @@ export class RootCommand extends Command {
256252
command: Command,
257253
previousArgs: string[],
258254
toComplete: string,
259-
endsWithSpace: boolean,
260255
lastPrevArg: string | undefined
261256
) {
262257
// Handle flag value completion
@@ -350,12 +345,7 @@ export class RootCommand extends Command {
350345
}
351346

352347
// positional argument completion
353-
private handlePositionalCompletion(
354-
command: Command,
355-
previousArgs: string[],
356-
toComplete: string,
357-
endsWithSpace: boolean
358-
) {
348+
private handlePositionalCompletion(command: Command, previousArgs: string[]) {
359349
// current argument position (subtract command name)
360350
const commandParts = command.value.split(' ').length;
361351
const currentArgIndex = Math.max(0, previousArgs.length - commandParts);
@@ -437,12 +427,11 @@ export class RootCommand extends Command {
437427
const [matchedCommand] = this.matchCommand(previousArgs);
438428
const lastPrevArg = previousArgs[previousArgs.length - 1];
439429

440-
if (this.shouldCompleteFlags(lastPrevArg, toComplete, endsWithSpace)) {
430+
if (this.shouldCompleteFlags(lastPrevArg, toComplete)) {
441431
this.handleFlagCompletion(
442432
matchedCommand,
443433
previousArgs,
444434
toComplete,
445-
endsWithSpace,
446435
lastPrevArg
447436
);
448437
} else {
@@ -461,16 +450,11 @@ export class RootCommand extends Command {
461450
}
462451
}
463452

464-
if (this.shouldCompleteCommands(toComplete, endsWithSpace)) {
453+
if (this.shouldCompleteCommands(toComplete)) {
465454
this.handleCommandCompletion(previousArgs, toComplete);
466455
}
467456
if (matchedCommand && matchedCommand.arguments.size > 0) {
468-
this.handlePositionalCompletion(
469-
matchedCommand,
470-
previousArgs,
471-
toComplete,
472-
endsWithSpace
473-
);
457+
this.handlePositionalCompletion(matchedCommand, previousArgs);
474458
}
475459
}
476460

0 commit comments

Comments
 (0)