diff --git a/.changeset/violet-peaches-juggle.md b/.changeset/violet-peaches-juggle.md new file mode 100644 index 0000000..8e147b3 --- /dev/null +++ b/.changeset/violet-peaches-juggle.md @@ -0,0 +1,5 @@ +--- +"typescript-eslint-parser-for-extra-files": minor +--- + +feat: support for boolean project option diff --git a/src/index.ts b/src/index.ts index c808d4f..e3b06b8 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,6 +2,7 @@ import type { ParserOptions } from "@typescript-eslint/parser"; import type { ProgramOptions } from "./ts"; import { TSServiceManager } from "./ts"; import * as tsEslintParser from "@typescript-eslint/parser"; +import { getProjectConfigFiles } from "./utils/get-project-config-files"; const DEFAULT_EXTRA_FILE_EXTENSIONS = [".vue", ".svelte", ".astro"]; const tsServiceManager = new TSServiceManager(); @@ -47,9 +48,7 @@ function* iterateOptions(options: ParserOptions): Iterable { "Specify `parserOptions.project`. Otherwise there is no point in using this parser." ); } - for (const project of Array.isArray(options.project) - ? options.project - : [options.project]) { + for (const project of getProjectConfigFiles(options)) { yield { project, filePath: options.filePath, diff --git a/src/utils/get-project-config-files.ts b/src/utils/get-project-config-files.ts new file mode 100644 index 0000000..632e2d7 --- /dev/null +++ b/src/utils/get-project-config-files.ts @@ -0,0 +1,32 @@ +import type { ParserOptions } from "@typescript-eslint/parser"; +import fs from "fs"; +import path from "path"; + +export function getProjectConfigFiles(options: ParserOptions): string[] { + const tsconfigRootDir = + typeof options.tsconfigRootDir === "string" + ? options.tsconfigRootDir + : process.cwd(); + if (options.project !== true) { + return Array.isArray(options.project) + ? options.project + : [options.project!]; + } + + let directory = path.dirname(options.filePath!); + const checkedDirectories = [directory]; + + do { + const tsconfigPath = path.join(directory, "tsconfig.json"); + if (fs.existsSync(tsconfigPath)) { + return [tsconfigPath]; + } + + directory = path.dirname(directory); + checkedDirectories.push(directory); + } while (directory.length > 1 && directory.length >= tsconfigRootDir.length); + + throw new Error( + `project was set to \`true\` but couldn't find any tsconfig.json relative to '${options.filePath}' within '${tsconfigRootDir}'.` + ); +} diff --git a/tests/fixtures/types/vue/vue-script-setup01/types.vue b/tests/fixtures/types/vue/vue-script-setup01/types.vue index be1a729..6b74a09 100644 --- a/tests/fixtures/types/vue/vue-script-setup01/types.vue +++ b/tests/fixtures/types/vue/vue-script-setup01/types.vue @@ -10,7 +10,7 @@ import { TypeFoo } from "../vue-script-setup02/source.vue"; // TypeFoo: any, Typ import { numberValue } from "./number"; // numberValue: 1, numberValue: 1 let a: TypeFoo = $ref(1); // a: string, $ref(1): any let b: TypeFoo; // b: string -defineProps<{ foo: string }>(); // defineProps<{ foo: string }>(): Readonly<{ foo: string; }> +defineProps<{ foo: string }>(); // defineProps<{ foo: string }>(): Readonly & {}> console.log(numberValue); // console.log(numberValue): void