From e694b0907a2570535a0688f11d1b7ef375fa7aac Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 1 Mar 2025 02:35:27 +0000 Subject: [PATCH 01/11] chore(deps): update dependency @changesets/changelog-github to ^0.5.1 (#365) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 19 +++++++++++++------ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 758c4c91..539a1ddb 100644 --- a/package.json +++ b/package.json @@ -90,7 +90,7 @@ "devDependencies": { "@1stg/eslint-config": "7.0.1", "@1stg/lib-config": "^12.0.1", - "@changesets/changelog-github": "^0.5.0", + "@changesets/changelog-github": "^0.5.1", "@changesets/cli": "^2.27.12", "@commitlint/cli": "^17.8.1", "@mozilla/glean": "^3.0.0", diff --git a/yarn.lock b/yarn.lock index 420dcfa3..455faae6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2076,14 +2076,14 @@ __metadata: languageName: node linkType: hard -"@changesets/changelog-github@npm:^0.5.0": - version: 0.5.0 - resolution: "@changesets/changelog-github@npm:0.5.0" +"@changesets/changelog-github@npm:^0.5.1": + version: 0.5.1 + resolution: "@changesets/changelog-github@npm:0.5.1" dependencies: "@changesets/get-github-info": "npm:^0.6.0" - "@changesets/types": "npm:^6.0.0" + "@changesets/types": "npm:^6.1.0" dotenv: "npm:^8.1.0" - checksum: a9c01d918f67c3d5dd38a505da29261518bed932c67fe3eb85cc15a485d32c1d11549cd276f121b4e169f26fb20923b435e931e6a5e83e213623dd8c3733cde9 + checksum: 1284e7dc067652edfa14792196e6036849455d121afabe63e8d1a7dc0e8fb0310edb58d1130f2a5944819ae4011eeecc7e0c44c1cda43e6a581a3add187c3447 languageName: node linkType: hard @@ -2275,6 +2275,13 @@ __metadata: languageName: node linkType: hard +"@changesets/types@npm:^6.1.0": + version: 6.1.0 + resolution: "@changesets/types@npm:6.1.0" + checksum: 2dcd00712cb85d0c53afdd8d0e856b4bf9c0ce8dc36c838c918d44799aacd9ba8659b9ff610ff92b94fc03c8fd2b52c5b05418fcf8a1bd138cd9182414ede373 + languageName: node + linkType: hard + "@changesets/write@npm:^0.3.2": version: 0.3.2 resolution: "@changesets/write@npm:0.3.2" @@ -6144,7 +6151,7 @@ __metadata: dependencies: "@1stg/eslint-config": "npm:7.0.1" "@1stg/lib-config": "npm:^12.0.1" - "@changesets/changelog-github": "npm:^0.5.0" + "@changesets/changelog-github": "npm:^0.5.1" "@changesets/cli": "npm:^2.27.12" "@commitlint/cli": "npm:^17.8.1" "@mozilla/glean": "npm:^3.0.0" From ece9efd2aa4d3f9499871dd3196e9229d43cbd57 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 1 Mar 2025 02:35:39 +0000 Subject: [PATCH 02/11] chore(deps): update dependency @types/node to ^18.19.78 (#366) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 13 +++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 539a1ddb..e3aabd3b 100644 --- a/package.json +++ b/package.json @@ -96,7 +96,7 @@ "@mozilla/glean": "^3.0.0", "@pkgr/rollup": "^4.1.3", "@types/debug": "^4.1.12", - "@types/node": "^18.19.74", + "@types/node": "^18.19.78", "@types/unist": "^2.0.11", "dummy.js": "link:dummy.js", "eslint": "^8.57.1", diff --git a/yarn.lock b/yarn.lock index 455faae6..56478d01 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3731,7 +3731,7 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:^18.0.0, @types/node@npm:^18.19.74": +"@types/node@npm:^18.0.0": version: 18.19.74 resolution: "@types/node@npm:18.19.74" dependencies: @@ -3740,6 +3740,15 @@ __metadata: languageName: node linkType: hard +"@types/node@npm:^18.19.78": + version: 18.19.78 + resolution: "@types/node@npm:18.19.78" + dependencies: + undici-types: "npm:~5.26.4" + checksum: c9b285b965c054d4ffd511fd31c18b3d1512dfdf2af0f0340b19a225716aedc2a26d87dadc2dd27b33e2fa6cbcdacff2bb8bf70f91978b2ef3b18dfa327afdfb + languageName: node + linkType: hard + "@types/normalize-package-data@npm:^2.4.0": version: 2.4.4 resolution: "@types/normalize-package-data@npm:2.4.4" @@ -6158,7 +6167,7 @@ __metadata: "@nolyfill/is-core-module": "npm:1.0.39" "@pkgr/rollup": "npm:^4.1.3" "@types/debug": "npm:^4.1.12" - "@types/node": "npm:^18.19.74" + "@types/node": "npm:^18.19.78" "@types/unist": "npm:^2.0.11" debug: "npm:^4.3.7" dummy.js: "link:dummy.js" From c4c99b4fef9c0b5793836ecb0b8e5a26a3785873 Mon Sep 17 00:00:00 2001 From: JounQin Date: Tue, 11 Mar 2025 00:43:10 +0800 Subject: [PATCH 03/11] ci: allow release on v3.x (#369) --- .github/workflows/ci.yml | 14 +++++++++----- .github/workflows/codeql.yml | 12 +++++++++--- .github/workflows/release.yml | 5 +++++ .github/workflows/size-limit.yml | 5 +++++ 4 files changed, 28 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3f7ed8c0..11e2b6f3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,19 +4,28 @@ on: - push - pull_request +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: default: + name: Lint and Test with Node.js ${{ matrix.node }} on ${{ matrix.os }} strategy: matrix: node: - 16 - 18 - 20 + - 22 os: - ubuntu-latest - windows-latest - macos-latest + fail-fast: false runs-on: ${{ matrix.os }} + env: + YARN_IGNORE_NODE: 1 steps: - uses: actions/checkout@v4 @@ -33,17 +42,12 @@ jobs: with: node-version: ${{ matrix.node }} cache: yarn - env: - YARN_IGNORE_NODE: 1 - name: Install Dependencies run: yarn --immutable - env: - YARN_IGNORE_NODE: 1 - name: Build, Lint and Test run: yarn run-s build lint test typecov env: EFF_NO_LINK_RULES: true PARSER_NO_WATCH: true - YARN_IGNORE_NODE: 1 diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 17a1049f..925e4126 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -4,12 +4,18 @@ on: push: branches: - master + - v3.x pull_request: branches: - master + - v3.x schedule: - cron: '16 11 * * 2' +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: analyze: name: Analyze @@ -30,15 +36,15 @@ jobs: uses: actions/checkout@v4 - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} queries: +security-and-quality - name: Autobuild - uses: github/codeql-action/autobuild@v2 + uses: github/codeql-action/autobuild@v3 - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 with: category: '/language:${{ matrix.language }}' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1b54dd01..92ab801f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -4,6 +4,11 @@ on: push: branches: - master + - v3.x + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true jobs: release: diff --git a/.github/workflows/size-limit.yml b/.github/workflows/size-limit.yml index d09c4940..44884f4c 100644 --- a/.github/workflows/size-limit.yml +++ b/.github/workflows/size-limit.yml @@ -4,11 +4,16 @@ on: pull_request: branches: - master + - v3.x permissions: contents: read pull-requests: write +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: size-limit: runs-on: ubuntu-latest From c94078504cfb6fd17b775c53d268962a56a2d118 Mon Sep 17 00:00:00 2001 From: JounQin Date: Tue, 11 Mar 2025 03:32:48 +0800 Subject: [PATCH 04/11] test: test `import-x` and flat config support correctly (#370) * test: test import-x/flat config support correctly * fix: support multiple matching ts paths --- .changeset/beige-gorillas-hunt.md | 5 ++ .eslintrc | 3 +- .nvmrc | 2 +- package.json | 5 +- src/index.ts | 67 ++++++++++++++---------- tests/importXResolverV3/eslint.config.js | 37 ++++++++----- yarn.lock | 57 +++++++++++++------- 7 files changed, 110 insertions(+), 66 deletions(-) create mode 100644 .changeset/beige-gorillas-hunt.md diff --git a/.changeset/beige-gorillas-hunt.md b/.changeset/beige-gorillas-hunt.md new file mode 100644 index 00000000..e896184a --- /dev/null +++ b/.changeset/beige-gorillas-hunt.md @@ -0,0 +1,5 @@ +--- +"eslint-import-resolver-typescript": patch +--- + +fix: support multiple matching ts paths diff --git a/.eslintrc b/.eslintrc index 19106e5b..95a3175d 100644 --- a/.eslintrc +++ b/.eslintrc @@ -4,7 +4,8 @@ "node": true }, "parserOptions": { - "ecmaVersion": "latest" + "ecmaVersion": "latest", + "sourceType": "module" }, "extends": [ "plugin:prettier/recommended", diff --git a/.nvmrc b/.nvmrc index 1fc51668..9be0c705 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -18.20.6 +18.20.7 diff --git a/package.json b/package.json index e3aabd3b..54b36b0c 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "test:dotInclude": "eslint --ext ts,tsx tests/dotInclude --ignore-pattern \"!.dot\"", "test:dotPaths": "eslint --ext ts,tsx tests/dotPaths --ignore-pattern \"!.dot\"", "test:dotProject": "eslint --ext ts,tsx tests/dotProject --ignore-pattern \"!.dot\"", - "test:importXResolverV3": "eslint --config=tests/importXResolverV3/eslint.config.js tests/importXResolverV3", + "test:importXResolverV3": "cross-env ESLINT_USE_FLAT_CONFIG=true eslint --config=tests/importXResolverV3/eslint.config.js tests/importXResolverV3", "test:multipleEslintrcs": "eslint --ext ts,tsx tests/multipleEslintrcs", "test:multipleTsconfigs": "eslint --ext ts,tsx tests/multipleTsconfigs", "test:withJsExtension": "node tests/withJsExtension/test.js && eslint --ext ts,tsx tests/withJsExtension", @@ -98,6 +98,7 @@ "@types/debug": "^4.1.12", "@types/node": "^18.19.78", "@types/unist": "^2.0.11", + "cross-env": "^7.0.3", "dummy.js": "link:dummy.js", "eslint": "^8.57.1", "eslint-import-resolver-typescript": "link:.", @@ -111,7 +112,7 @@ "size-limit": "^11.0.0", "size-limit-preset-node-lib": "^0.3.0", "type-coverage": "^2.27.0", - "typescript": "^5.3.2" + "typescript": "~5.1.0" }, "resolutions": { "eslint-import-resolver-typescript": "link:.", diff --git a/src/index.ts b/src/index.ts index bc92c25d..1287aefe 100644 --- a/src/index.ts +++ b/src/index.ts @@ -181,22 +181,30 @@ export function resolve( initMappers(cachedOptions) - const mappedPath = getMappedPath(source, file, cachedOptions.extensions, true) - if (mappedPath) { - log('matched ts path:', mappedPath) + let mappedPaths = getMappedPaths(source, file, cachedOptions.extensions, true) + + if (mappedPaths.length > 0) { + log('matched ts path:', ...mappedPaths) + } else { + mappedPaths = [source] } // note that even if we map the path, we still need to do a final resolve - let foundNodePath: string | null - try { - foundNodePath = - resolver.resolveSync( + let foundNodePath: string | undefined + for (const mappedPath of mappedPaths) { + try { + const resolved = resolver.resolveSync( {}, path.dirname(path.resolve(file)), - mappedPath ?? source, - ) || null - } catch { - foundNodePath = null + mappedPath, + ) + if (resolved) { + foundNodePath = resolved + break + } + } catch { + log('failed to resolve with', mappedPath) + } } // naive attempt at `@types/*` resolution, @@ -286,16 +294,16 @@ const isModule = (modulePath?: string | undefined): modulePath is string => { * @returns The mapped path of the module or undefined */ // eslint-disable-next-line sonarjs/cognitive-complexity -function getMappedPath( +function getMappedPaths( source: string, file: string, extensions: string[] = defaultExtensions, retry?: boolean, -): string | undefined { +): string[] { const originalExtensions = extensions extensions = ['', ...extensions] - let paths: Array | undefined = [] + let paths: string[] = [] if (RELATIVE_PATH_PATTERN.test(source)) { const resolved = path.resolve(path.dirname(file), source) @@ -341,34 +349,35 @@ function getMappedPath( const tsExt = jsExt.replace('js', 'ts') const basename = source.replace(JS_EXT_PATTERN, '') - const resolved = - getMappedPath(basename + tsExt, file) || - getMappedPath( - basename + '.d' + (tsExt === '.tsx' ? '.ts' : tsExt), - file, - ) + const mappedPaths = getMappedPaths(basename + tsExt, file) - if (resolved) { + const resolved = + mappedPaths.length > 0 + ? mappedPaths + : getMappedPaths( + basename + '.d' + (tsExt === '.tsx' ? '.ts' : tsExt), + file, + ) + + if (resolved.length > 0) { return resolved } } for (const ext of extensions) { + const mappedPaths = isJs ? [] : getMappedPaths(source + ext, file) const resolved = - (isJs ? null : getMappedPath(source + ext, file)) || - getMappedPath(source + `/index${ext}`, file) + mappedPaths.length > 0 + ? mappedPaths + : getMappedPaths(source + `/index${ext}`, file) - if (resolved) { + if (resolved.length > 0) { return resolved } } } - if (paths.length > 1) { - log('found multiple matching ts paths:', paths) - } - - return paths[0] + return paths } // eslint-disable-next-line sonarjs/cognitive-complexity diff --git a/tests/importXResolverV3/eslint.config.js b/tests/importXResolverV3/eslint.config.js index 70a0e565..4fe2fdd4 100644 --- a/tests/importXResolverV3/eslint.config.js +++ b/tests/importXResolverV3/eslint.config.js @@ -1,20 +1,31 @@ const path = require('path') -const { createTypeScriptImportResolver } = require('../../lib/index.cjs') +const importX = require('eslint-plugin-import-x') + +const { createTypeScriptImportResolver } = require('../..') const globPattern = './packages/*/tsconfig.json' // in normal cases this is not needed because the __dirname would be the root const absoluteGlobPath = path.join(__dirname, globPattern) -module.exports = { - ...require('eslint-plugin-import-x').flatConfigs.typescript, - settings: { - ...require('eslint-plugin-import-x').flatConfigs.typescript.settings, - 'import-x/resolver-next': [ - createTypeScriptImportResolver({ - project: absoluteGlobPath, - alwaysTryTypes: true, - }), - ], - }, -} +const base = require('../baseEslintConfig.cjs')() + +module.exports = + // don't run on node 16 because lacking of `structuredClone` + +process.versions.node.split('.')[0] <= 16 + ? {} + : { + files: ['**/*.ts', '**/*.tsx'], + plugins: { + import: importX, + }, + settings: { + ...importX.flatConfigs.typescript.settings, + 'import-x/resolver-next': [ + createTypeScriptImportResolver({ + project: absoluteGlobPath, + }), + ], + }, + rules: base.rules, + } diff --git a/yarn.lock b/yarn.lock index 56478d01..841bba11 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2268,14 +2268,7 @@ __metadata: languageName: node linkType: hard -"@changesets/types@npm:^6.0.0": - version: 6.0.0 - resolution: "@changesets/types@npm:6.0.0" - checksum: 214c58ff3e3da019c578b94815ec6748729a38b665d950acddf53f3a23073ac7a57dce45812c4bec0cbcd6902c84a482c804457d4c903602005b2399de8a4021 - languageName: node - linkType: hard - -"@changesets/types@npm:^6.1.0": +"@changesets/types@npm:^6.0.0, @changesets/types@npm:^6.1.0": version: 6.1.0 resolution: "@changesets/types@npm:6.1.0" checksum: 2dcd00712cb85d0c53afdd8d0e856b4bf9c0ce8dc36c838c918d44799aacd9ba8659b9ff610ff92b94fc03c8fd2b52c5b05418fcf8a1bd138cd9182414ede373 @@ -3731,16 +3724,7 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:^18.0.0": - version: 18.19.74 - resolution: "@types/node@npm:18.19.74" - dependencies: - undici-types: "npm:~5.26.4" - checksum: 2306bd0b41cdd528b890b210b96f287a5b5035c128f62636057d6616bd612b3f53d32d77f7e76ef41a9f130ea691e6980e6d5942dd625df05d3a641764fddb78 - languageName: node - linkType: hard - -"@types/node@npm:^18.19.78": +"@types/node@npm:^18.0.0, @types/node@npm:^18.19.78": version: 18.19.78 resolution: "@types/node@npm:18.19.78" dependencies: @@ -5373,6 +5357,18 @@ __metadata: languageName: node linkType: hard +"cross-env@npm:^7.0.3": + version: 7.0.3 + resolution: "cross-env@npm:7.0.3" + dependencies: + cross-spawn: "npm:^7.0.1" + bin: + cross-env: src/bin/cross-env.js + cross-env-shell: src/bin/cross-env-shell.js + checksum: e99911f0d31c20e990fd92d6fd001f4b01668a303221227cc5cb42ed155f086351b1b3bd2699b200e527ab13011b032801f8ce638e6f09f854bdf744095e604c + languageName: node + linkType: hard + "cross-spawn@npm:^6.0.5": version: 6.0.5 resolution: "cross-spawn@npm:6.0.5" @@ -5386,7 +5382,7 @@ __metadata: languageName: node linkType: hard -"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.3, cross-spawn@npm:^7.0.5": +"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.1, cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.3, cross-spawn@npm:^7.0.5": version: 7.0.6 resolution: "cross-spawn@npm:7.0.6" dependencies: @@ -6169,6 +6165,7 @@ __metadata: "@types/debug": "npm:^4.1.12" "@types/node": "npm:^18.19.78" "@types/unist": "npm:^2.0.11" + cross-env: "npm:^7.0.3" debug: "npm:^4.3.7" dummy.js: "link:dummy.js" enhanced-resolve: "npm:^5.15.0" @@ -6188,7 +6185,7 @@ __metadata: stable-hash: "npm:^0.0.4" tinyglobby: "npm:^0.2.12" type-coverage: "npm:^2.27.0" - typescript: "npm:^5.3.2" + typescript: "npm:~5.1.0" peerDependencies: eslint: "*" eslint-plugin-import: "*" @@ -13873,6 +13870,16 @@ __metadata: languageName: node linkType: hard +"typescript@npm:~5.1.0": + version: 5.1.6 + resolution: "typescript@npm:5.1.6" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: f347cde665cf43dc4c1c7d9821c7d9bbec3c3914f4bdd82ee490e9fb9f6d99036ed8666463b6a192dd005eeef333c5087d5931bdd51ec853436ff9a670a7417e + languageName: node + linkType: hard + "typescript@patch:typescript@npm%3A^4.6.4 || ^5.2.2#optional!builtin, typescript@patch:typescript@npm%3A^5.3.2#optional!builtin": version: 5.3.2 resolution: "typescript@patch:typescript@npm%3A5.3.2#optional!builtin::version=5.3.2&hash=e012d7" @@ -13883,6 +13890,16 @@ __metadata: languageName: node linkType: hard +"typescript@patch:typescript@npm%3A~5.1.0#optional!builtin": + version: 5.1.6 + resolution: "typescript@patch:typescript@npm%3A5.1.6#optional!builtin::version=5.1.6&hash=5da071" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: f5481fa3ba0eee8970f46708d13c05650a865ad093b586fc9573f425c64c57ca97e3308e110bb528deb3ccebe83f6fd7b5a8ac90018038da96326a9ccdf8e77c + languageName: node + linkType: hard + "unassert@npm:^2.0.0, unassert@npm:^2.0.2": version: 2.0.2 resolution: "unassert@npm:2.0.2" From b813788dde5c2e2b39a28bdab216d574ab32a760 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 10 Mar 2025 19:35:24 +0000 Subject: [PATCH 05/11] chore: release eslint-import-resolver-typescript (#371) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .changeset/beige-gorillas-hunt.md | 5 ----- CHANGELOG.md | 6 ++++++ package.json | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) delete mode 100644 .changeset/beige-gorillas-hunt.md diff --git a/.changeset/beige-gorillas-hunt.md b/.changeset/beige-gorillas-hunt.md deleted file mode 100644 index e896184a..00000000 --- a/.changeset/beige-gorillas-hunt.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"eslint-import-resolver-typescript": patch ---- - -fix: support multiple matching ts paths diff --git a/CHANGELOG.md b/CHANGELOG.md index 1dd6496f..70319074 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 3.8.4 + +### Patch Changes + +- [#370](https://github.com/import-js/eslint-import-resolver-typescript/pull/370) [`c940785`](https://github.com/import-js/eslint-import-resolver-typescript/commit/c94078504cfb6fd17b775c53d268962a56a2d118) Thanks [@JounQin](https://github.com/JounQin)! - fix: support multiple matching ts paths + ## 3.8.3 ### Patch Changes diff --git a/package.json b/package.json index 54b36b0c..c35a251a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "eslint-import-resolver-typescript", - "version": "3.8.3", + "version": "3.8.4", "type": "module", "description": "This plugin adds `TypeScript` support to `eslint-plugin-import`", "repository": "git+https://github.com/import-js/eslint-import-resolver-typescript", From 366eeaf8ba87adf7c2e165b0a73406292c002ad9 Mon Sep 17 00:00:00 2001 From: Carlo Corradini Date: Tue, 11 Mar 2025 23:25:56 +0100 Subject: [PATCH 06/11] =?UTF-8?q?fix:=20if=20file=20has=20no=20correspondi?= =?UTF-8?q?ng=20mapper=20function,=20apply=20all=20of=20them=E2=80=A6=20(#?= =?UTF-8?q?372)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .changeset/long-insects-tan.md | 5 ++ .size-limit.json | 2 +- package.json | 1 + src/index.ts | 91 +++++++++++++++------ tests/nearestTsconfig/.eslintrc.cjs | 10 +++ tests/nearestTsconfig/a/app/app.ts | 2 + tests/nearestTsconfig/a/b/app/app.ts | 2 + tests/nearestTsconfig/a/b/c/app/app.ts | 2 + tests/nearestTsconfig/a/b/c/components/c.ts | 1 + tests/nearestTsconfig/a/b/c/tsconfig.json | 9 ++ tests/nearestTsconfig/a/b/components/b.ts | 1 + tests/nearestTsconfig/a/b/tsconfig.json | 9 ++ tests/nearestTsconfig/a/components/a.ts | 1 + tests/nearestTsconfig/a/tsconfig.json | 9 ++ tests/nearestTsconfig/app/app.ts | 1 + tests/nearestTsconfig/components/root.ts | 1 + tests/nearestTsconfig/tsconfig.json | 9 ++ 17 files changed, 128 insertions(+), 28 deletions(-) create mode 100644 .changeset/long-insects-tan.md create mode 100644 tests/nearestTsconfig/.eslintrc.cjs create mode 100644 tests/nearestTsconfig/a/app/app.ts create mode 100644 tests/nearestTsconfig/a/b/app/app.ts create mode 100644 tests/nearestTsconfig/a/b/c/app/app.ts create mode 100644 tests/nearestTsconfig/a/b/c/components/c.ts create mode 100644 tests/nearestTsconfig/a/b/c/tsconfig.json create mode 100644 tests/nearestTsconfig/a/b/components/b.ts create mode 100644 tests/nearestTsconfig/a/b/tsconfig.json create mode 100644 tests/nearestTsconfig/a/components/a.ts create mode 100644 tests/nearestTsconfig/a/tsconfig.json create mode 100644 tests/nearestTsconfig/app/app.ts create mode 100644 tests/nearestTsconfig/components/root.ts create mode 100644 tests/nearestTsconfig/tsconfig.json diff --git a/.changeset/long-insects-tan.md b/.changeset/long-insects-tan.md new file mode 100644 index 00000000..4f341cdb --- /dev/null +++ b/.changeset/long-insects-tan.md @@ -0,0 +1,5 @@ +--- +'eslint-import-resolver-typescript': patch +--- + +fix: if file has no corresponding mapper function, apply all of them, starting with the nearest one. diff --git a/.size-limit.json b/.size-limit.json index 0c0657ad..648747e9 100644 --- a/.size-limit.json +++ b/.size-limit.json @@ -1,6 +1,6 @@ [ { "path": "./lib/index.js", - "limit": "3kB" + "limit": "3.1kB" } ] diff --git a/package.json b/package.json index c35a251a..cf2511e1 100644 --- a/package.json +++ b/package.json @@ -57,6 +57,7 @@ "test:importXResolverV3": "cross-env ESLINT_USE_FLAT_CONFIG=true eslint --config=tests/importXResolverV3/eslint.config.js tests/importXResolverV3", "test:multipleEslintrcs": "eslint --ext ts,tsx tests/multipleEslintrcs", "test:multipleTsconfigs": "eslint --ext ts,tsx tests/multipleTsconfigs", + "test:nearestTsconfig": "eslint --ext ts,tsx tests/nearestTsconfig", "test:withJsExtension": "node tests/withJsExtension/test.js && eslint --ext ts,tsx tests/withJsExtension", "test:withJsconfig": "eslint --ext js tests/withJsconfig", "test:withPaths": "eslint --ext ts,tsx tests/withPaths", diff --git a/src/index.ts b/src/index.ts index 1287aefe..b774b3ce 100644 --- a/src/index.ts +++ b/src/index.ts @@ -112,6 +112,7 @@ let prevCwd: string let mappersCachedOptions: InternalResolverOptions let mappers: Array<{ + path: string files: Set mapperFn: NonNullable> }> = [] @@ -311,35 +312,50 @@ function getMappedPaths( paths = [resolved] } } else { - paths = [ - ...new Set( - mappers - .filter(({ files }) => files.has(file)) - .map(({ mapperFn }) => - mapperFn(source).map(item => [ - ...extensions.map(ext => `${item}${ext}`), - ...originalExtensions.map(ext => `${item}/index${ext}`), - ]), - ) - .flat(2) - .map(toNativePathSeparator), - ), - ].filter(mappedPath => { - try { - const stat = fs.statSync(mappedPath, { throwIfNoEntry: false }) - if (stat === undefined) return false - if (stat.isFile()) return true - - // Maybe this is a module dir? - if (stat.isDirectory()) { - return isModule(mappedPath) + // Filter mapper functions associated with file + let mapperFns: Array>> = + mappers + .filter(({ files }) => files.has(file)) + .map(({ mapperFn }) => mapperFn) + if (mapperFns.length === 0) { + // If empty, try all mapper functions, starting with the nearest one + mapperFns = mappers + .map(mapper => ({ + mapperFn: mapper.mapperFn, + counter: equalChars(path.dirname(file), path.dirname(mapper.path)), + })) + .sort( + (a, b) => + // Sort in descending order where the nearest one has the longest counter + b.counter - a.counter, + ) + .map(({ mapperFn }) => mapperFn) + } + paths = mapperFns + .map(mapperFn => + mapperFn(source).map(item => [ + ...extensions.map(ext => `${item}${ext}`), + ...originalExtensions.map(ext => `${item}/index${ext}`), + ]), + ) + .flat(2) + .map(toNativePathSeparator) + .filter(mappedPath => { + try { + const stat = fs.statSync(mappedPath, { throwIfNoEntry: false }) + if (stat === undefined) return false + if (stat.isFile()) return true + + // Maybe this is a module dir? + if (stat.isDirectory()) { + return isModule(mappedPath) + } + } catch { + return false } - } catch { - return false - } - return false - }) + return false + }) } if (retry && paths.length === 0) { @@ -487,6 +503,7 @@ function initMappers(options: InternalResolverOptions) { } return { + path: toNativePathSeparator(tsconfigResult.path), files: new Set(files.map(toNativePathSeparator)), mapperFn, } @@ -551,3 +568,23 @@ function toNativePathSeparator(p: string) { function isDefined(value: T | null | undefined): value is T { return value !== null && value !== undefined } + +/** + * Counts how many characters in strings `a` and `b` are exactly the same and in the same position. + * + * @param {string} a First string + * @param {string} b Second string + * @returns Number of matching characters + */ +function equalChars(a: string, b: string): number { + if (a.length === 0 || b.length === 0) { + return 0 + } + + let i = 0 + const length = Math.min(a.length, b.length) + while (i < length && a.charAt(i) === b.charAt(i)) { + i += 1 + } + return i +} diff --git a/tests/nearestTsconfig/.eslintrc.cjs b/tests/nearestTsconfig/.eslintrc.cjs new file mode 100644 index 00000000..285ee8d6 --- /dev/null +++ b/tests/nearestTsconfig/.eslintrc.cjs @@ -0,0 +1,10 @@ +const path = require('node:path') + +const project = [ + 'tsconfig.json', + 'a/tsconfig.json', + 'a/b/tsconfig.json', + 'a/b/c/tsconfig.json', +].map(tsconfig => path.resolve(__dirname, tsconfig)) + +module.exports = require('../baseEslintConfig.cjs')(project) diff --git a/tests/nearestTsconfig/a/app/app.ts b/tests/nearestTsconfig/a/app/app.ts new file mode 100644 index 00000000..9597f5bf --- /dev/null +++ b/tests/nearestTsconfig/a/app/app.ts @@ -0,0 +1,2 @@ +import 'components/a' +import 'components/root' diff --git a/tests/nearestTsconfig/a/b/app/app.ts b/tests/nearestTsconfig/a/b/app/app.ts new file mode 100644 index 00000000..61b335ec --- /dev/null +++ b/tests/nearestTsconfig/a/b/app/app.ts @@ -0,0 +1,2 @@ +import 'components/b' +import 'components/root' diff --git a/tests/nearestTsconfig/a/b/c/app/app.ts b/tests/nearestTsconfig/a/b/c/app/app.ts new file mode 100644 index 00000000..e49cf01e --- /dev/null +++ b/tests/nearestTsconfig/a/b/c/app/app.ts @@ -0,0 +1,2 @@ +import 'components/c' +import 'components/root' diff --git a/tests/nearestTsconfig/a/b/c/components/c.ts b/tests/nearestTsconfig/a/b/c/components/c.ts new file mode 100644 index 00000000..da4b0eda --- /dev/null +++ b/tests/nearestTsconfig/a/b/c/components/c.ts @@ -0,0 +1 @@ +export default 'c' diff --git a/tests/nearestTsconfig/a/b/c/tsconfig.json b/tests/nearestTsconfig/a/b/c/tsconfig.json new file mode 100644 index 00000000..6f4b6a28 --- /dev/null +++ b/tests/nearestTsconfig/a/b/c/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "paths": { + "components/*": ["../../../components/*", "./components/*"] + } + }, + "files": ["components/c.ts"] +} diff --git a/tests/nearestTsconfig/a/b/components/b.ts b/tests/nearestTsconfig/a/b/components/b.ts new file mode 100644 index 00000000..a3bb4904 --- /dev/null +++ b/tests/nearestTsconfig/a/b/components/b.ts @@ -0,0 +1 @@ +export default 'b' diff --git a/tests/nearestTsconfig/a/b/tsconfig.json b/tests/nearestTsconfig/a/b/tsconfig.json new file mode 100644 index 00000000..fedccddb --- /dev/null +++ b/tests/nearestTsconfig/a/b/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "paths": { + "components/*": ["../../components/*", "./components/*"] + } + }, + "files": ["components/b.ts"] +} diff --git a/tests/nearestTsconfig/a/components/a.ts b/tests/nearestTsconfig/a/components/a.ts new file mode 100644 index 00000000..90bd54cd --- /dev/null +++ b/tests/nearestTsconfig/a/components/a.ts @@ -0,0 +1 @@ +export default 'a' diff --git a/tests/nearestTsconfig/a/tsconfig.json b/tests/nearestTsconfig/a/tsconfig.json new file mode 100644 index 00000000..c01728fe --- /dev/null +++ b/tests/nearestTsconfig/a/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "paths": { + "components/*": ["../components/*", "./components/*"] + } + }, + "files": ["components/a.ts"] +} diff --git a/tests/nearestTsconfig/app/app.ts b/tests/nearestTsconfig/app/app.ts new file mode 100644 index 00000000..60f1cde9 --- /dev/null +++ b/tests/nearestTsconfig/app/app.ts @@ -0,0 +1 @@ +import 'components/root' diff --git a/tests/nearestTsconfig/components/root.ts b/tests/nearestTsconfig/components/root.ts new file mode 100644 index 00000000..8c841b31 --- /dev/null +++ b/tests/nearestTsconfig/components/root.ts @@ -0,0 +1 @@ +export default 'root' diff --git a/tests/nearestTsconfig/tsconfig.json b/tests/nearestTsconfig/tsconfig.json new file mode 100644 index 00000000..21cf5788 --- /dev/null +++ b/tests/nearestTsconfig/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "paths": { + "components/*": ["./components/*"] + } + }, + "files": ["components/root.ts"] +} From 7d63ec77eb508529e65767ed5e22282c3d8a51ba Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 11 Mar 2025 22:54:58 +0000 Subject: [PATCH 07/11] chore: release eslint-import-resolver-typescript (#373) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .changeset/long-insects-tan.md | 5 ----- CHANGELOG.md | 6 ++++++ package.json | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) delete mode 100644 .changeset/long-insects-tan.md diff --git a/.changeset/long-insects-tan.md b/.changeset/long-insects-tan.md deleted file mode 100644 index 4f341cdb..00000000 --- a/.changeset/long-insects-tan.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'eslint-import-resolver-typescript': patch ---- - -fix: if file has no corresponding mapper function, apply all of them, starting with the nearest one. diff --git a/CHANGELOG.md b/CHANGELOG.md index 70319074..f2183de8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 3.8.5 + +### Patch Changes + +- [#372](https://github.com/import-js/eslint-import-resolver-typescript/pull/372) [`366eeaf`](https://github.com/import-js/eslint-import-resolver-typescript/commit/366eeaf8ba87adf7c2e165b0a73406292c002ad9) Thanks [@carlocorradini](https://github.com/carlocorradini)! - fix: if file has no corresponding mapper function, apply all of them, starting with the nearest one. + ## 3.8.4 ### Patch Changes diff --git a/package.json b/package.json index cf2511e1..86e53743 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "eslint-import-resolver-typescript", - "version": "3.8.4", + "version": "3.8.5", "type": "module", "description": "This plugin adds `TypeScript` support to `eslint-plugin-import`", "repository": "git+https://github.com/import-js/eslint-import-resolver-typescript", From c9d5ab0fa963bd891b6f2ae312ae3ec10a397b7c Mon Sep 17 00:00:00 2001 From: JounQin Date: Thu, 13 Mar 2025 02:22:09 +0800 Subject: [PATCH 08/11] fix: add support for importing with .js extension as tsx importee (#374) Co-authored-by: David Ensinger --- .changeset/loud-avocados-bake.md | 5 +++++ .size-limit.json | 2 +- src/index.ts | 23 +++++++++++++++-------- tests/withPaths/index.ts | 4 ++++ 4 files changed, 25 insertions(+), 9 deletions(-) create mode 100644 .changeset/loud-avocados-bake.md diff --git a/.changeset/loud-avocados-bake.md b/.changeset/loud-avocados-bake.md new file mode 100644 index 00000000..fdbe2ff2 --- /dev/null +++ b/.changeset/loud-avocados-bake.md @@ -0,0 +1,5 @@ +--- +"eslint-import-resolver-typescript": patch +--- + +fix: add support for importing with .js extension as tsx importee diff --git a/.size-limit.json b/.size-limit.json index 648747e9..bdf75734 100644 --- a/.size-limit.json +++ b/.size-limit.json @@ -1,6 +1,6 @@ [ { "path": "./lib/index.js", - "limit": "3.1kB" + "limit": "3.2kB" } ] diff --git a/src/index.ts b/src/index.ts index b774b3ce..c5a8822d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -362,18 +362,25 @@ function getMappedPaths( const isJs = JS_EXT_PATTERN.test(source) if (isJs) { const jsExt = path.extname(source) + // cjs -> cts, js -> ts, jsx -> tsx, mjs -> mts const tsExt = jsExt.replace('js', 'ts') + const basename = source.replace(JS_EXT_PATTERN, '') - const mappedPaths = getMappedPaths(basename + tsExt, file) + let resolved = getMappedPaths(basename + tsExt, file) - const resolved = - mappedPaths.length > 0 - ? mappedPaths - : getMappedPaths( - basename + '.d' + (tsExt === '.tsx' ? '.ts' : tsExt), - file, - ) + if (resolved.length === 0 && jsExt === '.js') { + // js -> tsx + const tsxExt = jsExt.replace('js', 'tsx') + resolved = getMappedPaths(basename + tsxExt, file) + } + + if (resolved.length === 0) { + resolved = getMappedPaths( + basename + '.d' + (tsExt === '.tsx' ? '.ts' : tsExt), + file, + ) + } if (resolved.length > 0) { return resolved diff --git a/tests/withPaths/index.ts b/tests/withPaths/index.ts index 594e79d4..696bf409 100644 --- a/tests/withPaths/index.ts +++ b/tests/withPaths/index.ts @@ -6,9 +6,13 @@ import './subfolder/tsxImportee' // import using tsconfig.json path mapping import 'folder/tsImportee' +import 'folder/tsImportee.js' import 'folder/tsxImportee' +import 'folder/tsxImportee.js' import 'folder/subfolder/tsImportee' +import 'folder/subfolder/tsImportee.js' import 'folder/subfolder/tsxImportee' +import 'folder/subfolder/tsxImportee.js' // import module with typings set in package.json import 'folder/module' From 7fdfd8055872559a4c31186f9bfee5a51ca3e5c8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 12 Mar 2025 18:28:26 +0000 Subject: [PATCH 09/11] chore: release eslint-import-resolver-typescript (#375) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .changeset/loud-avocados-bake.md | 5 ----- CHANGELOG.md | 6 ++++++ package.json | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) delete mode 100644 .changeset/loud-avocados-bake.md diff --git a/.changeset/loud-avocados-bake.md b/.changeset/loud-avocados-bake.md deleted file mode 100644 index fdbe2ff2..00000000 --- a/.changeset/loud-avocados-bake.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"eslint-import-resolver-typescript": patch ---- - -fix: add support for importing with .js extension as tsx importee diff --git a/CHANGELOG.md b/CHANGELOG.md index f2183de8..9c060040 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 3.8.6 + +### Patch Changes + +- [#374](https://github.com/import-js/eslint-import-resolver-typescript/pull/374) [`c9d5ab0`](https://github.com/import-js/eslint-import-resolver-typescript/commit/c9d5ab0fa963bd891b6f2ae312ae3ec10a397b7c) Thanks [@JounQin](https://github.com/JounQin)! - fix: add support for importing with .js extension as tsx importee + ## 3.8.5 ### Patch Changes diff --git a/package.json b/package.json index 86e53743..8d601b85 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "eslint-import-resolver-typescript", - "version": "3.8.5", + "version": "3.8.6", "type": "module", "description": "This plugin adds `TypeScript` support to `eslint-plugin-import`", "repository": "git+https://github.com/import-js/eslint-import-resolver-typescript", From a14fdd95011c4c09b74f71854410f684c0f04bc5 Mon Sep 17 00:00:00 2001 From: Carlo Corradini Date: Thu, 13 Mar 2025 18:03:50 +0100 Subject: [PATCH 10/11] fix: include mapper with no files and force non-dynamic projects to use absolute paths (#377) --- .changeset/new-peas-fry.md | 5 +++++ src/index.ts | 9 +++------ 2 files changed, 8 insertions(+), 6 deletions(-) create mode 100644 .changeset/new-peas-fry.md diff --git a/.changeset/new-peas-fry.md b/.changeset/new-peas-fry.md new file mode 100644 index 00000000..c0204887 --- /dev/null +++ b/.changeset/new-peas-fry.md @@ -0,0 +1,5 @@ +--- +'eslint-import-resolver-typescript': patch +--- + +fix: include mapper with no files and force non-dynamic projects to use absolute paths diff --git a/src/index.ts b/src/index.ts index c5a8822d..46ba89f9 100644 --- a/src/index.ts +++ b/src/index.ts @@ -430,7 +430,9 @@ function initMappers(options: InternalResolverOptions) { // Turn glob patterns into paths const projectPaths = [ ...new Set([ - ...configPaths.filter(path => !isDynamicPattern(path)), + ...configPaths + .filter(p => !isDynamicPattern(p)) + .map(p => path.resolve(process.cwd(), p)), ...globSync( configPaths.filter(path => isDynamicPattern(path)), { @@ -504,11 +506,6 @@ function initMappers(options: InternalResolverOptions) { : []), ] - if (files.length === 0) { - // eslint-disable-next-line unicorn/no-useless-undefined - return undefined - } - return { path: toNativePathSeparator(tsconfigResult.path), files: new Set(files.map(toNativePathSeparator)), From 904356bd14469f532feddaa07cda2a02169c1c01 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 13 Mar 2025 17:29:05 +0000 Subject: [PATCH 11/11] chore: release eslint-import-resolver-typescript (#378) --- .changeset/new-peas-fry.md | 5 ----- CHANGELOG.md | 6 ++++++ package.json | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) delete mode 100644 .changeset/new-peas-fry.md diff --git a/.changeset/new-peas-fry.md b/.changeset/new-peas-fry.md deleted file mode 100644 index c0204887..00000000 --- a/.changeset/new-peas-fry.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'eslint-import-resolver-typescript': patch ---- - -fix: include mapper with no files and force non-dynamic projects to use absolute paths diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c060040..dc7202b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 3.8.7 + +### Patch Changes + +- [#377](https://github.com/import-js/eslint-import-resolver-typescript/pull/377) [`a14fdd9`](https://github.com/import-js/eslint-import-resolver-typescript/commit/a14fdd95011c4c09b74f71854410f684c0f04bc5) Thanks [@carlocorradini](https://github.com/carlocorradini)! - fix: include mapper with no files and force non-dynamic projects to use absolute paths + ## 3.8.6 ### Patch Changes diff --git a/package.json b/package.json index 8d601b85..128f7b89 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "eslint-import-resolver-typescript", - "version": "3.8.6", + "version": "3.8.7", "type": "module", "description": "This plugin adds `TypeScript` support to `eslint-plugin-import`", "repository": "git+https://github.com/import-js/eslint-import-resolver-typescript",