Skip to content

Commit 7d7e8ef

Browse files
authored
fix: .dts generation + better types (#538)
closes #537 <details> <summary>`dist/index.dts`</summary> ``` declare const _default: { configs: { readonly 'flat/pedantic': import('./config-helper.js').SplittedFlatConfig<{ readonly name: "oxlint/pedantic"; readonly rules: Record<string, "off">; }>; readonly 'flat/style': import('./config-helper.js').SplittedFlatConfig<{ readonly name: "oxlint/style"; readonly rules: Record<string, "off">; }>; readonly 'flat/suspicious': import('./config-helper.js').SplittedFlatConfig<{ readonly name: "oxlint/suspicious"; readonly rules: Record<string, "off">; }>; readonly 'flat/restriction': import('./config-helper.js').SplittedFlatConfig<{ readonly name: "oxlint/restriction"; readonly rules: Record<string, "off">; }>; readonly 'flat/correctness': import('./config-helper.js').SplittedFlatConfig<{ readonly name: "oxlint/correctness"; readonly rules: Record<string, "off">; }>; readonly 'flat/perf': import('./config-helper.js').SplittedFlatConfig<{ readonly name: "oxlint/perf"; readonly rules: Record<string, "off">; }>; readonly 'flat/eslint': import('./config-helper.js').SplittedFlatConfig<{ readonly name: "oxlint/eslint"; readonly rules: Record<string, "off">; }>; readonly 'flat/import': import('./config-helper.js').SplittedFlatConfig<{ readonly name: "oxlint/import"; readonly rules: Record<string, "off">; }>; readonly 'flat/jest': import('./config-helper.js').SplittedFlatConfig<{ readonly name: "oxlint/jest"; readonly rules: Record<string, "off">; }>; readonly 'flat/jsdoc': import('./config-helper.js').SplittedFlatConfig<{ readonly name: "oxlint/jsdoc"; readonly rules: Record<string, "off">; }>; readonly 'flat/jsx-a11y': import('./config-helper.js').SplittedFlatConfig<{ readonly name: "oxlint/jsx-a11y"; readonly rules: Record<string, "off">; }>; readonly 'flat/nextjs': import('./config-helper.js').SplittedFlatConfig<{ readonly name: "oxlint/nextjs"; readonly rules: Record<string, "off">; }>; readonly 'flat/node': import('./config-helper.js').SplittedFlatConfig<{ readonly name: "oxlint/node"; readonly rules: Record<string, "off">; }>; readonly 'flat/promise': import('./config-helper.js').SplittedFlatConfig<{ readonly name: "oxlint/promise"; readonly rules: Record<string, "off">; }>; readonly 'flat/react': import('./config-helper.js').SplittedFlatConfig<{ readonly name: "oxlint/react"; readonly rules: Record<string, "off">; }>; readonly 'flat/react-hooks': import('./config-helper.js').SplittedFlatConfig<{ readonly name: "oxlint/react-hooks"; readonly rules: Record<string, "off">; }>; readonly 'flat/react-perf': import('./config-helper.js').SplittedFlatConfig<{ readonly name: "oxlint/react-perf"; readonly rules: Record<string, "off">; }>; readonly 'flat/typescript': import('./config-helper.js').SplittedFlatConfig<{ readonly name: "oxlint/typescript"; readonly rules: Record<string, "off">; }>; readonly 'flat/unicorn': import('./config-helper.js').SplittedFlatConfig<{ readonly name: "oxlint/unicorn"; readonly rules: Record<string, "off">; }>; readonly 'flat/vitest': import('./config-helper.js').SplittedFlatConfig<{ readonly name: "oxlint/vitest"; readonly rules: Record<string, "off">; }>; readonly 'flat/vue': import('./config-helper.js').SplittedFlatConfig<{ readonly name: "oxlint/vue"; readonly rules: Record<string, "off">; }>; readonly recommended: { plugins: string[]; rules: Record<string, "off">; }; readonly all: { plugins: string[]; rules: Record<string, "off">; }; readonly 'flat/all': import('./config-helper.js').SplittedFlatConfig<{ name: string; rules: Record<string, "off">; }>; readonly 'flat/recommended': import('./config-helper.js').SplittedFlatConfig<{ name: string; rules: Record<string, "off">; }>; }; buildFromOxlintConfig: (config: import('./build-from-oxlint-config/types.js').OxlintConfig) => import('./build-from-oxlint-config/types.js').EslintPluginOxlintConfig[]; buildFromOxlintConfigFile: (oxlintConfigFile: string) => import('./build-from-oxlint-config/types.js').EslintPluginOxlintConfig[]; }; export default _default; ``` </details>
1 parent 40ae1de commit 7d7e8ef

File tree

5 files changed

+65
-42
lines changed

5 files changed

+65
-42
lines changed

scripts/config-generator.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ export class ConfigGenerator {
5959

6060
code += ` name: 'oxlint/${kebabCase(grouping)}',\n`;
6161
code += ` rules: rules.${camelCase(grouping)}Rules,`;
62-
code += '\n};\n\n';
62+
code += '\n} as const;\n\n';
6363
}
6464

6565
code += `const configBy${exportName} = {\n`;

src/config-helper.ts

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,27 @@
11
import { rulesDisabledForVueAndSvelteFiles } from './constants.js';
2-
import type { Linter } from 'eslint';
2+
3+
// Some type helpers for better type inference
4+
type LegacyConfig = {
5+
rules?: Record<string, 'off'>;
6+
overrides?: {
7+
files: string[];
8+
excludedFiles?: string[];
9+
rules?: Record<string, 'off'>;
10+
}[];
11+
};
12+
13+
type FlatConfig = {
14+
name?: string;
15+
rules?: Record<string, 'off'>;
16+
ignores?: string[];
17+
};
318

419
// for eslint legacy configuration
5-
export const overrideDisabledRulesForVueAndSvelteFiles = (
6-
config: Linter.LegacyConfig<Record<string, 'off'>>
7-
): Linter.LegacyConfig<Record<string, 'off'>> => {
20+
export const overrideDisabledRulesForVueAndSvelteFiles = <
21+
C extends LegacyConfig,
22+
>(
23+
config: C
24+
): C => {
825
const foundRules = Object.keys(config.rules!).filter((rule) =>
926
rulesDisabledForVueAndSvelteFiles.includes(rule)
1027
);
@@ -32,10 +49,12 @@ export const overrideDisabledRulesForVueAndSvelteFiles = (
3249
return newConfig;
3350
};
3451

52+
export type SplittedFlatConfig<C extends FlatConfig> = [C] | [C, FlatConfig];
53+
3554
// for eslint flat configuration
36-
export const splitDisabledRulesForVueAndSvelteFiles = (
37-
config: Linter.Config
38-
): Linter.Config[] => {
55+
export const splitDisabledRulesForVueAndSvelteFiles = <C extends FlatConfig>(
56+
config: C
57+
): SplittedFlatConfig<C> => {
3958
const foundRules = Object.keys(config.rules!).filter((rule) =>
4059
rulesDisabledForVueAndSvelteFiles.includes(rule)
4160
);
@@ -46,7 +65,7 @@ export const splitDisabledRulesForVueAndSvelteFiles = (
4665

4766
const oldConfig = structuredClone(config);
4867

49-
const newConfig: Linter.Config = {
68+
const newConfig: FlatConfig = {
5069
// flat configs use minimatch syntax
5170
name: 'oxlint/vue-svelte-exceptions',
5271
ignores: ['**/*.vue', '**/*.svelte'],
@@ -60,3 +79,17 @@ export const splitDisabledRulesForVueAndSvelteFiles = (
6079

6180
return [oldConfig, newConfig];
6281
};
82+
83+
export const splitDisabledRulesForVueAndSvelteFilesDeep = <
84+
T extends Record<string, FlatConfig>,
85+
>(
86+
config: T
87+
): { [K in keyof T]: SplittedFlatConfig<T[K]> } => {
88+
const result = {} as { [K in keyof T]: SplittedFlatConfig<T[K]> };
89+
90+
for (const name in config) {
91+
result[name] = splitDisabledRulesForVueAndSvelteFiles(config[name]);
92+
}
93+
94+
return result;
95+
};

src/configs.ts

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ import configByCategory from './generated/configs-by-category.js';
55
import {
66
overrideDisabledRulesForVueAndSvelteFiles,
77
splitDisabledRulesForVueAndSvelteFiles,
8+
splitDisabledRulesForVueAndSvelteFilesDeep,
89
} from './config-helper.js';
9-
import type { Linter } from 'eslint';
1010

1111
type UnionToIntersection<U> = (
1212
U extends unknown ? (x: U) => void : never
@@ -22,16 +22,6 @@ const allRules: UnionToIntersection<AllRules> = Object.assign(
2222
...Object.values(ruleMapsByScope)
2323
);
2424

25-
const splitDisabledRulesForVueAndSvelteFilesDeep = <T extends string>(
26-
config: Record<T, Linter.Config>
27-
): Record<T, Linter.Config[]> => {
28-
const entries = Object.entries<Linter.Config>(config).map(
29-
([name, config]) => [name, splitDisabledRulesForVueAndSvelteFiles(config)]
30-
);
31-
32-
return Object.fromEntries(entries);
33-
};
34-
3525
export default {
3626
recommended: overrideDisabledRulesForVueAndSvelteFiles({
3727
plugins: ['oxlint'],
@@ -51,4 +41,4 @@ export default {
5141
}),
5242
...splitDisabledRulesForVueAndSvelteFilesDeep(configByScope),
5343
...splitDisabledRulesForVueAndSvelteFilesDeep(configByCategory),
54-
};
44+
} as const;

src/generated/configs-by-category.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,32 +5,32 @@ import * as rules from './rules-by-category.js';
55
const pedanticConfig = {
66
name: 'oxlint/pedantic',
77
rules: rules.pedanticRules,
8-
};
8+
} as const;
99

1010
const styleConfig = {
1111
name: 'oxlint/style',
1212
rules: rules.styleRules,
13-
};
13+
} as const;
1414

1515
const suspiciousConfig = {
1616
name: 'oxlint/suspicious',
1717
rules: rules.suspiciousRules,
18-
};
18+
} as const;
1919

2020
const restrictionConfig = {
2121
name: 'oxlint/restriction',
2222
rules: rules.restrictionRules,
23-
};
23+
} as const;
2424

2525
const correctnessConfig = {
2626
name: 'oxlint/correctness',
2727
rules: rules.correctnessRules,
28-
};
28+
} as const;
2929

3030
const perfConfig = {
3131
name: 'oxlint/perf',
3232
rules: rules.perfRules,
33-
};
33+
} as const;
3434

3535
const configByCategory = {
3636
'flat/pedantic': pedanticConfig,

src/generated/configs-by-scope.ts

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,77 +5,77 @@ import * as rules from './rules-by-scope.js';
55
const eslintConfig = {
66
name: 'oxlint/eslint',
77
rules: rules.eslintRules,
8-
};
8+
} as const;
99

1010
const importConfig = {
1111
name: 'oxlint/import',
1212
rules: rules.importRules,
13-
};
13+
} as const;
1414

1515
const jestConfig = {
1616
name: 'oxlint/jest',
1717
rules: rules.jestRules,
18-
};
18+
} as const;
1919

2020
const jsdocConfig = {
2121
name: 'oxlint/jsdoc',
2222
rules: rules.jsdocRules,
23-
};
23+
} as const;
2424

2525
const jsxA11yConfig = {
2626
name: 'oxlint/jsx-a11y',
2727
rules: rules.jsxA11yRules,
28-
};
28+
} as const;
2929

3030
const nextjsConfig = {
3131
name: 'oxlint/nextjs',
3232
rules: rules.nextjsRules,
33-
};
33+
} as const;
3434

3535
const nodeConfig = {
3636
name: 'oxlint/node',
3737
rules: rules.nodeRules,
38-
};
38+
} as const;
3939

4040
const promiseConfig = {
4141
name: 'oxlint/promise',
4242
rules: rules.promiseRules,
43-
};
43+
} as const;
4444

4545
const reactConfig = {
4646
name: 'oxlint/react',
4747
rules: rules.reactRules,
48-
};
48+
} as const;
4949

5050
const reactHooksConfig = {
5151
name: 'oxlint/react-hooks',
5252
rules: rules.reactHooksRules,
53-
};
53+
} as const;
5454

5555
const reactPerfConfig = {
5656
name: 'oxlint/react-perf',
5757
rules: rules.reactPerfRules,
58-
};
58+
} as const;
5959

6060
const typescriptConfig = {
6161
name: 'oxlint/typescript',
6262
rules: rules.typescriptRules,
63-
};
63+
} as const;
6464

6565
const unicornConfig = {
6666
name: 'oxlint/unicorn',
6767
rules: rules.unicornRules,
68-
};
68+
} as const;
6969

7070
const vitestConfig = {
7171
name: 'oxlint/vitest',
7272
rules: rules.vitestRules,
73-
};
73+
} as const;
7474

7575
const vueConfig = {
7676
name: 'oxlint/vue',
7777
rules: rules.vueRules,
78-
};
78+
} as const;
7979

8080
const configByScope = {
8181
'flat/eslint': eslintConfig,

0 commit comments

Comments
 (0)