diff --git a/package.json b/package.json index 4bf6446..5b6cc7a 100644 --- a/package.json +++ b/package.json @@ -94,7 +94,7 @@ "dependencies": { "eslint-config-prettier": "^10.1.8", "eslint-import-resolver-typescript": "^4.4.5", - "eslint-plugin-import-x": "^4.17.1", + "eslint-plugin-import-x": "^4.18.1", "globals": "^17.13.0", "jsonc-parser": "^3.3.1", "yaml": "^2.9.1" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 876e9bc..4fca052 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -187,6 +187,10 @@ settings: autoInstallPeers: true excludeLinksFromLockfile: false +overrides: + minimatch@<11.0.1: ^11.0.1 + zod@<4.6.6: ^4.6.6 + importers: .: @@ -196,10 +200,10 @@ importers: version: 10.1.8(eslint@10.14.0(jiti@2.7.0)(supports-color@7.2.0)) eslint-import-resolver-typescript: specifier: ^4.4.5 - version: 4.4.5(eslint-plugin-import-x@4.17.1(@typescript-eslint/utils@8.71.1(eslint@10.14.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3))(eslint@10.14.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0))(eslint@10.14.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0) + version: 4.4.5(eslint-plugin-import-x@4.18.1(@typescript-eslint/utils@8.71.1(eslint@10.14.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3))(eslint@10.14.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0))(eslint@10.14.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0) eslint-plugin-import-x: - specifier: ^4.17.1 - version: 4.17.1(@typescript-eslint/utils@8.71.1(eslint@10.14.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3))(eslint@10.14.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0) + specifier: ^4.18.1 + version: 4.18.1(@typescript-eslint/utils@8.71.1(eslint@10.14.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3))(eslint@10.14.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0) globals: specifier: ^17.13.0 version: 17.14.0 @@ -561,6 +565,9 @@ packages: resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} engines: {node: '>=18.18'} + '@isaacs/nonrecursive-glob-match@1.1.0': + resolution: {integrity: sha512-GPm/Dbvk5RLmhRnxXIa7nTpK0xtl4E0wj0MslsuNiJ1FIROU+2+9lgUC/dgF7Ey4QCWhfEsgxilMRMCdHPfDfw==} + '@jridgewell/gen-mapping@0.4.0-beta.0': resolution: {integrity: sha512-JdGNkbE4GlNPYQhM0L95fBQr7ctLZJ276QXQLTad4t1oSdnnCI3fDq9DW3BqYAWv8Wc3+HS+4Gsii1oPMCfz1w==} @@ -1372,6 +1379,9 @@ packages: cjs-module-lexer@1.4.3: resolution: {integrity: sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==} + cjs-module-lexer@2.3.0: + resolution: {integrity: sha512-lmNyBzi6iYiqyrExTctfmjd8tInx+dHu9PBomTfH5RXS53c27JMFJgzNv5TyAnm3PgGf+MLy0+Ws41/HlVxdKQ==} + cli-cursor@5.0.0: resolution: {integrity: sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==} engines: {node: '>=18'} @@ -1460,6 +1470,9 @@ packages: es-module-lexer@2.3.2: resolution: {integrity: sha512-poHGpORABojJJucnV9KbOavETW8lBVnphkW77ER5/BQ5Fz7oXSoCNek7IH3vR5nRjdsEz926ibFYX8KtLQmdyw==} + es-module-lexer@3.0.4: + resolution: {integrity: sha512-BldNY5mwkVu+cQ5Ymn3e6hB9Sx8XHx4ZevWbiUyZbfKxJxYO27Hf0wfzkxIaD5CAJMaGl3YspKELj0ff/7nCMA==} + escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} @@ -1496,8 +1509,8 @@ packages: eslint-plugin-import-x: optional: true - eslint-plugin-import-x@4.17.1: - resolution: {integrity: sha512-4cdstYkKCyjumM2Q9NSI03K8D2a9F4Ssz33K2lv2hQa4KmR9jPLwk3uWGtNvclfqBrPGfGuMBwsGMbe6dMRbfg==} + eslint-plugin-import-x@4.18.1: + resolution: {integrity: sha512-D1h++38NS2Z40zf8jbd2OHqDrnIFRKpdp8sL0jP4xSDGZj6MNwEQua8F+r3tOWjcHrsWuhHOJ7wASWioJ31tfg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: '@typescript-eslint/utils': ^8.56.0 @@ -1844,9 +1857,9 @@ packages: resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==} engines: {node: '>=18'} - minimatch@10.2.6: - resolution: {integrity: sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==} - engines: {node: 18 || 20 || >=22} + minimatch@11.0.5: + resolution: {integrity: sha512-snPlVppFcYWfLLFQGhDxUyBcHNtMlWmn3jtj7pEaO+DP8pqL0IvAzXhMYmn1z9ASNtgmwLBdFxSf4tMUB0OTKA==} + engines: {node: 20 || >=22} mri@1.2.0: resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} @@ -2312,8 +2325,8 @@ packages: resolution: {integrity: sha512-xYqdZFUK/VYazNl/oCDYN+3WloWQwMfZxBoiNt6qNyk+xfOdi598muWE42rNZFp1kNOiqW936q5RhUdnpqElSg==} engines: {node: '>=18'} - zod@4.6.5: - resolution: {integrity: sha512-v5l/aFXZQeai4awLbOpSoHecE9UiMrnfx75tEXLjNonXVARxQ5mOeipTjROUchszUNCqnE+hqAMujRsRHsut2Q==} + zod@4.6.7: + resolution: {integrity: sha512-g8W2D2kU6a8untc053fX1uVBKzM7yqAxW/3zwk83+6RyF2+SKOuV+c0wBDhUwzV1PaGapmZH+rmcUzPf+3CGwg==} snapshots: @@ -2449,7 +2462,7 @@ snapshots: '@standard-schema/spec': 1.1.0 rxjs: 7.8.2 tslib: 2.9.1 - zod: 4.6.5 + zod: 4.6.7 '@angular/platform-browser@22.2.4(@angular/common@22.2.4(@angular/core@22.2.4(@angular/compiler@22.2.4)(rxjs@7.8.2))(rxjs@7.8.2))(@angular/core@22.2.4(@angular/compiler@22.2.4)(rxjs@7.8.2))': dependencies: @@ -2634,7 +2647,7 @@ snapshots: dependencies: '@eslint/object-schema': 3.0.5 debug: 4.4.3(supports-color@7.2.0) - minimatch: 10.2.6 + minimatch: 11.0.5 transitivePeerDependencies: - supports-color @@ -2669,6 +2682,8 @@ snapshots: '@humanwhocodes/retry@0.4.3': {} + '@isaacs/nonrecursive-glob-match@1.1.0': {} + '@jridgewell/gen-mapping@0.4.0-beta.0': dependencies: '@jridgewell/sourcemap-codec': 1.6.0 @@ -3019,7 +3034,7 @@ snapshots: '@typescript-eslint/types': 8.71.1 '@typescript-eslint/visitor-keys': 8.71.1 debug: 4.4.3(supports-color@7.2.0) - minimatch: 10.2.6 + minimatch: 11.0.5 semver: 7.8.5 tinyglobby: 0.2.17 ts-api-utils: 2.5.0(typescript@6.0.3) @@ -3034,7 +3049,7 @@ snapshots: '@typescript-eslint/types': 8.71.2 '@typescript-eslint/visitor-keys': 8.71.2 debug: 4.4.3(supports-color@7.2.0) - minimatch: 10.2.6 + minimatch: 11.0.5 semver: 7.8.5 tinyglobby: 0.2.17 ts-api-utils: 2.5.0(typescript@6.0.3) @@ -3049,7 +3064,7 @@ snapshots: '@typescript-eslint/types': 8.72.1 '@typescript-eslint/visitor-keys': 8.72.1 debug: 4.4.3(supports-color@7.2.0) - minimatch: 10.2.6 + minimatch: 11.0.5 semver: 7.8.5 tinyglobby: 0.2.17 ts-api-utils: 2.5.0(typescript@6.0.3) @@ -3329,6 +3344,8 @@ snapshots: cjs-module-lexer@1.4.3: {} + cjs-module-lexer@2.3.0: {} + cli-cursor@5.0.0: dependencies: restore-cursor: 5.1.0 @@ -3406,6 +3423,8 @@ snapshots: es-module-lexer@2.3.2: {} + es-module-lexer@3.0.4: {} + escalade@3.2.0: {} escape-string-regexp@4.0.0: {} @@ -3421,7 +3440,7 @@ snapshots: optionalDependencies: unrs-resolver: 1.12.2 - eslint-import-resolver-typescript@4.4.5(eslint-plugin-import-x@4.17.1(@typescript-eslint/utils@8.71.1(eslint@10.14.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3))(eslint@10.14.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0))(eslint@10.14.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0): + eslint-import-resolver-typescript@4.4.5(eslint-plugin-import-x@4.18.1(@typescript-eslint/utils@8.71.1(eslint@10.14.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3))(eslint@10.14.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0))(eslint@10.14.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0): dependencies: debug: 4.4.3(supports-color@7.2.0) eslint: 10.14.0(jiti@2.7.0)(supports-color@7.2.0) @@ -3432,19 +3451,21 @@ snapshots: tinyglobby: 0.2.17 unrs-resolver: 1.12.2 optionalDependencies: - eslint-plugin-import-x: 4.17.1(@typescript-eslint/utils@8.71.1(eslint@10.14.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3))(eslint@10.14.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0) + eslint-plugin-import-x: 4.18.1(@typescript-eslint/utils@8.71.1(eslint@10.14.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3))(eslint@10.14.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0) transitivePeerDependencies: - supports-color - eslint-plugin-import-x@4.17.1(@typescript-eslint/utils@8.71.1(eslint@10.14.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3))(eslint@10.14.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0): + eslint-plugin-import-x@4.18.1(@typescript-eslint/utils@8.71.1(eslint@10.14.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.3))(eslint@10.14.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0): dependencies: - '@typescript-eslint/types': 8.71.1 + '@typescript-eslint/types': 8.72.1 + cjs-module-lexer: 2.3.0 comment-parser: 1.4.9 debug: 4.4.3(supports-color@7.2.0) + es-module-lexer: 3.0.4 eslint: 10.14.0(jiti@2.7.0)(supports-color@7.2.0) eslint-import-context: 0.1.9(unrs-resolver@1.12.2) is-glob: 4.0.3 - minimatch: 10.2.6 + minimatch: 11.0.5 semver: 7.8.5 stable-hash-x: 0.2.0 unrs-resolver: 1.12.2 @@ -3493,7 +3514,7 @@ snapshots: imurmurhash: 0.1.4 is-glob: 4.0.3 json-stable-stringify-without-jsonify: 1.0.1 - minimatch: 10.2.6 + minimatch: 11.0.5 natural-compare: 1.4.0 optionator: 0.9.4 optionalDependencies: @@ -3657,7 +3678,7 @@ snapshots: tinyglobby: 0.2.17 unbash: 6.0.1 yaml: 2.9.1 - zod: 4.6.5 + zod: 4.6.7 levn@0.4.1: dependencies: @@ -3753,8 +3774,9 @@ snapshots: mimic-function@5.0.1: {} - minimatch@10.2.6: + minimatch@11.0.5: dependencies: + '@isaacs/nonrecursive-glob-match': 1.1.0 brace-expansion: 5.0.12 mri@1.2.0: {} @@ -4194,4 +4216,4 @@ snapshots: yoctocolors@2.2.0: {} - zod@4.6.5: {} + zod@4.6.7: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 30d1c6d..f57baff 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,2 +1,8 @@ allowBuilds: unrs-resolver: false +overrides: + # GHSA-g3hv-75wg-m249 (minimatch < 11.0.1): eslint and typescript-eslint still ask for ^10, which has no fix. + # Drop this once they allow 11. + 'minimatch@<11.0.1': ^11.0.1 + # GHSA-mrhx-c7xc-m3w5 (zod < 4.6.6), through knip and @angular/forms; their ranges allow the fix + 'zod@<4.6.6': ^4.6.6 diff --git a/scripts/rules-add.mjs b/scripts/rules-add.mjs index 5c613a6..06e8aaf 100644 --- a/scripts/rules-add.mjs +++ b/scripts/rules-add.mjs @@ -12,7 +12,7 @@ import path from 'node:path'; import process from 'node:process'; import { fileURLToPath } from 'node:url'; -import * as prettier from 'prettier'; +import { format, resolveConfig } from 'prettier'; import { gaps, inventories } from './rule-inventory.mjs'; @@ -70,8 +70,8 @@ async function main() { remove, add: undecided.map((rule) => [rule, inventory.initial(rule)]), }); - const options = await prettier.resolveConfig(file); - writeFileSync(file, await prettier.format(updated, { ...options, filepath: file })); + const options = await resolveConfig(file); + writeFileSync(file, await format(updated, { ...options, filepath: file })); changed += undecided.length + remove.length; for (const rule of undecided) { console.log(`${inventory.file}: added ${rule}: ${JSON.stringify(inventory.initial(rule))}`); diff --git a/src/eslint/index.mjs b/src/eslint/index.mjs index 2c6a44c..858aed5 100644 --- a/src/eslint/index.mjs +++ b/src/eslint/index.mjs @@ -7,8 +7,6 @@ import { typescript } from './layers/typescript.mjs'; import { vitest } from './layers/vitest.mjs'; import { normalizeOptions, OPTIONS_SETTING } from './options.mjs'; -export { angular, ignores, imports, javascript, normalizeOptions, prettier, typescript, vitest }; - /** @typedef {import('./options.mjs').Options} Options */ /** @typedef {import('eslint').Linter.Config} Config */ diff --git a/src/eslint/rules/angular-template.mjs b/src/eslint/rules/angular-template.mjs index 45dc8ab..06b9359 100644 --- a/src/eslint/rules/angular-template.mjs +++ b/src/eslint/rules/angular-template.mjs @@ -1,7 +1,7 @@ /* * @angular-eslint/template rules. Every plugin rule is listed; effective configuration. */ -export default /** @type {import('eslint').Linter.RulesRecord} */ ({ +const rules = /** @type {import('eslint').Linter.RulesRecord} */ ({ '@angular-eslint/template/alt-text': 'error', '@angular-eslint/template/attributes-order': 'error', '@angular-eslint/template/banana-in-box': 'error', @@ -56,3 +56,5 @@ export default /** @type {import('eslint').Linter.RulesRecord} */ ({ '@angular-eslint/template/require-switch-default': 'error', '@angular-eslint/template/prefer-style-binding': 'error', }); + +export default rules; diff --git a/src/eslint/rules/angular.mjs b/src/eslint/rules/angular.mjs index 4aa1740..6fcdec8 100644 --- a/src/eslint/rules/angular.mjs +++ b/src/eslint/rules/angular.mjs @@ -1,7 +1,7 @@ /* * @angular-eslint rules for TypeScript. Every plugin rule is listed; effective configuration. */ -export default /** @type {import('eslint').Linter.RulesRecord} */ ({ +const rules = /** @type {import('eslint').Linter.RulesRecord} */ ({ // prefix comes from createConfig({ angular: { prefix } }); the angular layer sets the options '@angular-eslint/directive-selector': 'error', '@angular-eslint/component-selector': 'error', @@ -62,3 +62,5 @@ export default /** @type {import('eslint').Linter.RulesRecord} */ ({ // previously crashed on Signal Forms destructuring; verified fixed by test/lint.test.mjs '@angular-eslint/reactive-context-must-read-signal': 'error', }); + +export default rules; diff --git a/src/eslint/rules/imports.mjs b/src/eslint/rules/imports.mjs index 8eb98db..90e19f1 100644 --- a/src/eslint/rules/imports.mjs +++ b/src/eslint/rules/imports.mjs @@ -4,7 +4,7 @@ * Resolution-based rules are off except no-cycle: TypeScript already reports unresolved modules * and missing named exports. The imports layer configures the TypeScript resolver for no-cycle. */ -export default /** @type {import('eslint').Linter.RulesRecord} */ ({ +const rules = /** @type {import('eslint').Linter.RulesRecord} */ ({ // -- ordering and layout -- // groups and internal patterns are set by the imports layer 'import-x/order': 'error', @@ -68,4 +68,14 @@ export default /** @type {import('eslint').Linter.RulesRecord} */ ({ 'import-x/no-dynamic-require': 'error', // Node built-ins are expected in Node projects; browser builds fail without polyfills anyway 'import-x/no-nodejs-modules': 'off', + // -- barrel files: a module that mostly re-exports others makes every importer load all of them -- + 'import-x/avoid-barrel-files': 'error', + // also through dependencies: import the module itself (lodash-es/debounce), not the package's barrel + 'import-x/avoid-importing-barrel-files': 'error', + // `import * as x` hides which exports are used and defeats tree-shaking; import them by name + 'import-x/avoid-namespace-import': 'error', + // `export * from` makes the API whatever the other module exports; name the exports + 'import-x/avoid-re-export-all': 'error', }); + +export default rules; diff --git a/src/eslint/rules/javascript.mjs b/src/eslint/rules/javascript.mjs index 3479c2f..d9d9b53 100644 --- a/src/eslint/rules/javascript.mjs +++ b/src/eslint/rules/javascript.mjs @@ -2,7 +2,7 @@ * Core ESLint rules. Every non-deprecated core rule is listed; this table is the effective * configuration (see docs/specs). Formatting is owned by Prettier. */ -export default /** @type {import('eslint').Linter.RulesRecord} */ ({ +const rules = /** @type {import('eslint').Linter.RulesRecord} */ ({ // possible logic errors 'array-callback-return': 'error', 'constructor-super': 'error', @@ -242,3 +242,5 @@ export default /** @type {import('eslint').Linter.RulesRecord} */ ({ yoda: 'error', 'unicode-bom': 'error', }); + +export default rules; diff --git a/src/eslint/rules/typescript.mjs b/src/eslint/rules/typescript.mjs index 989bf73..4a323ca 100644 --- a/src/eslint/rules/typescript.mjs +++ b/src/eslint/rules/typescript.mjs @@ -3,7 +3,7 @@ * Every rule in typescript-eslint's `all` config is listed; this table is the effective * configuration for TS files. */ -export default /** @type {import('eslint').Linter.RulesRecord} */ ({ +const rules = /** @type {import('eslint').Linter.RulesRecord} */ ({ '@typescript-eslint/adjacent-overload-signatures': 'error', '@typescript-eslint/array-type': 'error', '@typescript-eslint/await-thenable': 'error', @@ -231,3 +231,5 @@ export default /** @type {import('eslint').Linter.RulesRecord} */ ({ '@typescript-eslint/no-unnecessary-type-conversion': 'error', '@typescript-eslint/no-generated-empty-object-type': 'error', }); + +export default rules; diff --git a/src/eslint/rules/vitest.mjs b/src/eslint/rules/vitest.mjs index eb446ce..7e75173 100644 --- a/src/eslint/rules/vitest.mjs +++ b/src/eslint/rules/vitest.mjs @@ -1,7 +1,7 @@ /* * @vitest/eslint-plugin rules. Every non-deprecated plugin rule is listed; effective configuration. */ -export default /** @type {import('eslint').Linter.RulesRecord} */ ({ +const rules = /** @type {import('eslint').Linter.RulesRecord} */ ({ // -- Assertions -- // helpers named expect* (e.g. expectValid(...)) count as assertions 'vitest/expect-expect': ['error', { assertFunctionNames: ['expect', 'expect*'] }], @@ -121,3 +121,5 @@ export default /** @type {import('eslint').Linter.RulesRecord} */ ({ 'vitest/padding-around-expect-groups': 'off', 'vitest/padding-around-test-blocks': 'off', }); + +export default rules; diff --git a/test/__snapshots__/effective-config.test.mjs.snap b/test/__snapshots__/effective-config.test.mjs.snap index c436a33..5322bba 100644 --- a/test/__snapshots__/effective-config.test.mjs.snap +++ b/test/__snapshots__/effective-config.test.mjs.snap @@ -859,6 +859,10 @@ exports[`effective config > Angular TS 1`] = ` }, ], "implicit-arrow-linebreak": 0, + "import-x/avoid-barrel-files": 2, + "import-x/avoid-importing-barrel-files": 2, + "import-x/avoid-namespace-import": 2, + "import-x/avoid-re-export-all": 2, "import-x/consistent-type-specifier-style": 0, "import-x/default": 0, "import-x/dynamic-import-chunkname": 0, @@ -2900,6 +2904,10 @@ exports[`effective config > Node TS 1`] = ` }, ], "implicit-arrow-linebreak": 0, + "import-x/avoid-barrel-files": 2, + "import-x/avoid-importing-barrel-files": 2, + "import-x/avoid-namespace-import": 2, + "import-x/avoid-re-export-all": 2, "import-x/consistent-type-specifier-style": 0, "import-x/default": 0, "import-x/dynamic-import-chunkname": 0, @@ -4356,6 +4364,10 @@ exports[`effective config > TS spec 1`] = ` }, ], "implicit-arrow-linebreak": 0, + "import-x/avoid-barrel-files": 2, + "import-x/avoid-importing-barrel-files": 2, + "import-x/avoid-namespace-import": 2, + "import-x/avoid-re-export-all": 2, "import-x/consistent-type-specifier-style": 0, "import-x/default": 0, "import-x/dynamic-import-chunkname": 0, @@ -5745,6 +5757,10 @@ exports[`effective config > plain JS 1`] = ` }, ], "implicit-arrow-linebreak": 0, + "import-x/avoid-barrel-files": 2, + "import-x/avoid-importing-barrel-files": 2, + "import-x/avoid-namespace-import": 2, + "import-x/avoid-re-export-all": 2, "import-x/consistent-type-specifier-style": 0, "import-x/default": 0, "import-x/dynamic-import-chunkname": 0, @@ -7200,6 +7216,10 @@ exports[`effective config > root config file 1`] = ` }, ], "implicit-arrow-linebreak": 0, + "import-x/avoid-barrel-files": 2, + "import-x/avoid-importing-barrel-files": 2, + "import-x/avoid-namespace-import": 2, + "import-x/avoid-re-export-all": 2, "import-x/consistent-type-specifier-style": 0, "import-x/default": 0, "import-x/dynamic-import-chunkname": 0, diff --git a/test/fixtures/plain-js/nested/leaf.js b/test/fixtures/plain-js/nested/leaf.js new file mode 100644 index 0000000..51e8599 --- /dev/null +++ b/test/fixtures/plain-js/nested/leaf.js @@ -0,0 +1 @@ +export const leaf = 'leaf'; diff --git a/test/fixtures/plain-js/nested/parent-first.js b/test/fixtures/plain-js/nested/parent-first.js new file mode 100644 index 0000000..e7a41ac --- /dev/null +++ b/test/fixtures/plain-js/nested/parent-first.js @@ -0,0 +1,4 @@ +import { greet } from '../clean.js'; +import { leaf } from './leaf.js'; + +export { greet, leaf }; diff --git a/test/fixtures/plain-js/nested/sibling-first.js b/test/fixtures/plain-js/nested/sibling-first.js new file mode 100644 index 0000000..9e61e20 --- /dev/null +++ b/test/fixtures/plain-js/nested/sibling-first.js @@ -0,0 +1,4 @@ +import { leaf } from './leaf.js'; +import { greet } from '../clean.js'; + +export { greet, leaf }; diff --git a/test/lint.test.mjs b/test/lint.test.mjs index 713910b..4e333e2 100644 --- a/test/lint.test.mjs +++ b/test/lint.test.mjs @@ -40,6 +40,13 @@ describe('plain-js fixture', () => { it('clean file reports nothing', () => expect(report['clean.js']).toEqual([])); it('reports undefined identifiers in JS', () => expect(report['undef.js']).toEqual(['no-undef'])); it('orders imports', () => expect(report['order.js']).toEqual(['import-x/order'])); + // parent and sibling imports share a group: parents first (import-x 4.18's transitive comparator; the old one + // depended on the Node version's sort) + it('orders parent imports before sibling ones', () => { + expect(report['nested/parent-first.js']).toEqual([]); + expect(report['nested/sibling-first.js']).toEqual(['import-x/order']); + expect(report['nested/leaf.js']).toEqual([]); + }); }); describe('node-ts fixture', () => { diff --git a/test/options.test.mjs b/test/options.test.mjs index bac9e84..e4ea372 100644 --- a/test/options.test.mjs +++ b/test/options.test.mjs @@ -1,12 +1,10 @@ import { describe, expect, it } from 'vitest'; -import { - angular, - createConfig, - normalizeOptions, - typescript, - vitest, -} from '../src/eslint/index.mjs'; +import { createConfig } from '../src/eslint/index.mjs'; +import { angular } from '../src/eslint/layers/angular.mjs'; +import { typescript } from '../src/eslint/layers/typescript.mjs'; +import { vitest } from '../src/eslint/layers/vitest.mjs'; +import { normalizeOptions } from '../src/eslint/options.mjs'; import { importPeer } from '../src/eslint/peer.mjs'; /** A dynamic import that fails as if `specifier` were not installed. */