From 965754e7462c0b799105e4c9c3fc80e13aaa5b66 Mon Sep 17 00:00:00 2001 From: akulsr0 Date: Wed, 8 May 2024 12:24:28 +0530 Subject: [PATCH 1/9] fix: allow glob patterns for `restrictedNamedExports` in `no-restricted-exports` --- lib/rules/no-restricted-exports.js | 6 ++++- tests/lib/rules/no-restricted-exports.js | 33 ++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/lib/rules/no-restricted-exports.js b/lib/rules/no-restricted-exports.js index a1d54b085fd..e944bc11201 100644 --- a/lib/rules/no-restricted-exports.js +++ b/lib/rules/no-restricted-exports.js @@ -5,6 +5,8 @@ "use strict"; +const minimatch = require("minimatch"); + //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ @@ -109,7 +111,9 @@ module.exports = { function checkExportedName(node) { const name = astUtils.getModuleExportName(node); - if (restrictedNames.has(name)) { + const hasRestrictedName = [...restrictedNames].some(restrictedName => name === restrictedName || (name && minimatch(name, restrictedName))); + + if (hasRestrictedName) { context.report({ node, messageId: "restrictedNamed", diff --git a/tests/lib/rules/no-restricted-exports.js b/tests/lib/rules/no-restricted-exports.js index cea7c046694..7c5453c3af4 100644 --- a/tests/lib/rules/no-restricted-exports.js +++ b/tests/lib/rules/no-restricted-exports.js @@ -91,6 +91,10 @@ ruleTester.run("no-restricted-exports", rule, { { code: "import a from 'foo';", options: [{ restrictedNamedExports: ["a"] }] }, { code: "import { a } from 'foo';", options: [{ restrictedNamedExports: ["a"] }] }, { code: "import { b as a } from 'foo';", options: [{ restrictedNamedExports: ["a"] }] }, + { + code: "var setSomething; export { setSomething };", + options: [{ restrictedNamedExports: ["get*"] }] + }, // does not check re-export all declarations { code: "export * from 'foo';", options: [{ restrictedNamedExports: ["a"] }] }, @@ -532,6 +536,35 @@ ruleTester.run("no-restricted-exports", rule, { { messageId: "restrictedNamed", data: { name: "f" }, type: "Identifier" } ] }, + { + code: "var getSomething; export { getSomething };", + options: [{ restrictedNamedExports: ["get*"] }], + errors: [ + { messageId: "restrictedNamed", data: { name: "getSomething" }, type: "Identifier" } + ] + }, + { + code: "var getSomethingFromUser; export { getSomethingFromUser };", + options: [{ restrictedNamedExports: ["*User"] }], + errors: [ + { messageId: "restrictedNamed", data: { name: "getSomethingFromUser" }, type: "Identifier" } + ] + }, + { + code: "var foo, ab, xy; export { foo, ab, xy };", + options: [{ restrictedNamedExports: ["*+(b|y)"] }], + errors: [ + { messageId: "restrictedNamed", data: { name: "ab" }, type: "Identifier" }, + { messageId: "restrictedNamed", data: { name: "xy" }, type: "Identifier" } + ] + }, + { + code: "var foo; export { foo as ab };", + options: [{ restrictedNamedExports: ["*+(b|y)"] }], + errors: [ + { messageId: "restrictedNamed", data: { name: "ab" }, type: "Identifier" } + ] + }, // reports "default" in named export declarations (when configured) { From aa547b99b445384e71967121100512c662f1f647 Mon Sep 17 00:00:00 2001 From: akulsr0 Date: Wed, 8 May 2024 15:34:34 +0530 Subject: [PATCH 2/9] chore: update option name --- lib/rules/no-restricted-exports.js | 18 ++++++++++++++++-- tests/lib/rules/no-restricted-exports.js | 12 +++++++----- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/lib/rules/no-restricted-exports.js b/lib/rules/no-restricted-exports.js index e944bc11201..c086fabbedc 100644 --- a/lib/rules/no-restricted-exports.js +++ b/lib/rules/no-restricted-exports.js @@ -43,6 +43,19 @@ module.exports = { }, additionalProperties: false }, + { + type: "object", + properties: { + restrictedNamedExportsPattern: { + type: "array", + items: { + type: "string" + }, + uniqueItems: true + } + }, + additionalProperties: false + }, { type: "object", properties: { @@ -100,6 +113,7 @@ module.exports = { create(context) { const restrictedNames = new Set(context.options[0] && context.options[0].restrictedNamedExports); + const restrictedNamePatterns = context.options[0] && context.options[0].restrictedNamedExportsPattern || []; const restrictDefaultExports = context.options[0] && context.options[0].restrictDefaultExports; const sourceCode = context.sourceCode; @@ -111,9 +125,9 @@ module.exports = { function checkExportedName(node) { const name = astUtils.getModuleExportName(node); - const hasRestrictedName = [...restrictedNames].some(restrictedName => name === restrictedName || (name && minimatch(name, restrictedName))); + const hasRestrictedNamePattern = restrictedNamePatterns.some(pattern => name && minimatch(name, pattern)); - if (hasRestrictedName) { + if (hasRestrictedNamePattern || restrictedNames.has(name)) { context.report({ node, messageId: "restrictedNamed", diff --git a/tests/lib/rules/no-restricted-exports.js b/tests/lib/rules/no-restricted-exports.js index 7c5453c3af4..7b0f6ffed2f 100644 --- a/tests/lib/rules/no-restricted-exports.js +++ b/tests/lib/rules/no-restricted-exports.js @@ -93,7 +93,7 @@ ruleTester.run("no-restricted-exports", rule, { { code: "import { b as a } from 'foo';", options: [{ restrictedNamedExports: ["a"] }] }, { code: "var setSomething; export { setSomething };", - options: [{ restrictedNamedExports: ["get*"] }] + options: [{ restrictedNamedExportsPattern: ["get*"] }] }, // does not check re-export all declarations @@ -536,23 +536,25 @@ ruleTester.run("no-restricted-exports", rule, { { messageId: "restrictedNamed", data: { name: "f" }, type: "Identifier" } ] }, + + // restrictedNamedExportsPattern { code: "var getSomething; export { getSomething };", - options: [{ restrictedNamedExports: ["get*"] }], + options: [{ restrictedNamedExportsPattern: ["get*"] }], errors: [ { messageId: "restrictedNamed", data: { name: "getSomething" }, type: "Identifier" } ] }, { code: "var getSomethingFromUser; export { getSomethingFromUser };", - options: [{ restrictedNamedExports: ["*User"] }], + options: [{ restrictedNamedExportsPattern: ["*User"] }], errors: [ { messageId: "restrictedNamed", data: { name: "getSomethingFromUser" }, type: "Identifier" } ] }, { code: "var foo, ab, xy; export { foo, ab, xy };", - options: [{ restrictedNamedExports: ["*+(b|y)"] }], + options: [{ restrictedNamedExportsPattern: ["*+(b|y)"] }], errors: [ { messageId: "restrictedNamed", data: { name: "ab" }, type: "Identifier" }, { messageId: "restrictedNamed", data: { name: "xy" }, type: "Identifier" } @@ -560,7 +562,7 @@ ruleTester.run("no-restricted-exports", rule, { }, { code: "var foo; export { foo as ab };", - options: [{ restrictedNamedExports: ["*+(b|y)"] }], + options: [{ restrictedNamedExportsPattern: ["*+(b|y)"] }], errors: [ { messageId: "restrictedNamed", data: { name: "ab" }, type: "Identifier" } ] From 0e66cc8fcf5abc387cf2e5aa8bf74d4fc77c6a0d Mon Sep 17 00:00:00 2001 From: akulsr0 Date: Wed, 8 May 2024 16:37:54 +0530 Subject: [PATCH 3/9] chore: use regex instead of glob patterns --- lib/rules/no-restricted-exports.js | 15 ++++++++++++--- tests/lib/rules/no-restricted-exports.js | 8 ++++---- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/lib/rules/no-restricted-exports.js b/lib/rules/no-restricted-exports.js index c086fabbedc..8c5ecddd9cb 100644 --- a/lib/rules/no-restricted-exports.js +++ b/lib/rules/no-restricted-exports.js @@ -5,8 +5,6 @@ "use strict"; -const minimatch = require("minimatch"); - //------------------------------------------------------------------------------ // Requirements //------------------------------------------------------------------------------ @@ -46,6 +44,13 @@ module.exports = { { type: "object", properties: { + restrictedNamedExports: { + type: "array", + items: { + type: "string" + }, + uniqueItems: true + }, restrictedNamedExportsPattern: { type: "array", items: { @@ -125,7 +130,11 @@ module.exports = { function checkExportedName(node) { const name = astUtils.getModuleExportName(node); - const hasRestrictedNamePattern = restrictedNamePatterns.some(pattern => name && minimatch(name, pattern)); + const hasRestrictedNamePattern = restrictedNamePatterns.some(pattern => { + const patternRegex = new RegExp(pattern, "u"); + + return name && patternRegex.test(name); + }); if (hasRestrictedNamePattern || restrictedNames.has(name)) { context.report({ diff --git a/tests/lib/rules/no-restricted-exports.js b/tests/lib/rules/no-restricted-exports.js index 7b0f6ffed2f..2488925699c 100644 --- a/tests/lib/rules/no-restricted-exports.js +++ b/tests/lib/rules/no-restricted-exports.js @@ -93,7 +93,7 @@ ruleTester.run("no-restricted-exports", rule, { { code: "import { b as a } from 'foo';", options: [{ restrictedNamedExports: ["a"] }] }, { code: "var setSomething; export { setSomething };", - options: [{ restrictedNamedExportsPattern: ["get*"] }] + options: [{ restrictedNamedExportsPattern: ["^get"] }] }, // does not check re-export all declarations @@ -547,14 +547,14 @@ ruleTester.run("no-restricted-exports", rule, { }, { code: "var getSomethingFromUser; export { getSomethingFromUser };", - options: [{ restrictedNamedExportsPattern: ["*User"] }], + options: [{ restrictedNamedExportsPattern: ["User$"] }], errors: [ { messageId: "restrictedNamed", data: { name: "getSomethingFromUser" }, type: "Identifier" } ] }, { code: "var foo, ab, xy; export { foo, ab, xy };", - options: [{ restrictedNamedExportsPattern: ["*+(b|y)"] }], + options: [{ restrictedNamedExportsPattern: ["(b|y)$"] }], errors: [ { messageId: "restrictedNamed", data: { name: "ab" }, type: "Identifier" }, { messageId: "restrictedNamed", data: { name: "xy" }, type: "Identifier" } @@ -562,7 +562,7 @@ ruleTester.run("no-restricted-exports", rule, { }, { code: "var foo; export { foo as ab };", - options: [{ restrictedNamedExportsPattern: ["*+(b|y)"] }], + options: [{ restrictedNamedExportsPattern: ["(b|y)$"] }], errors: [ { messageId: "restrictedNamed", data: { name: "ab" }, type: "Identifier" } ] From 2c4163f24a6f176e4864d1fcb0dc4a2e7b85222a Mon Sep 17 00:00:00 2001 From: akulsr0 Date: Wed, 8 May 2024 21:46:26 +0530 Subject: [PATCH 4/9] chore: add docs and use set for given regex strings --- docs/src/rules/no-restricted-exports.md | 15 +++++++++++++++ lib/rules/no-restricted-exports.js | 4 ++-- tests/lib/rules/no-restricted-exports.js | 7 +++++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/docs/src/rules/no-restricted-exports.md b/docs/src/rules/no-restricted-exports.md index 44672021a10..5825bde1042 100644 --- a/docs/src/rules/no-restricted-exports.md +++ b/docs/src/rules/no-restricted-exports.md @@ -17,6 +17,7 @@ By default, this rule doesn't disallow any names. Only the names you specify in This rule has an object option: * `"restrictedNamedExports"` is an array of strings, where each string is a name to be restricted. +* `"restrictedNamedExportsPattern"` is an array of regex strings, where each string regex pattern would be restricted. * `"restrictDefaultExports"` is an object option with boolean properties to restrict certain default export declarations. The option works only if the `restrictedNamedExports` option does not contain the `"default"` value. The following properties are allowed: * `direct`: restricts `export default` declarations. * `named`: restricts `export { foo as default };` declarations. @@ -130,6 +131,20 @@ export default function foo() {} ::: +### restrictedNamedExportsPattern + +This option allows you to restrict regex patterns for named exports. + +```js +/*eslint no-restricted-exports: ["error", { + "restrictedNamedExports": [], + "restrictedNamedExportsPattern": ["^privateUser"] +}]*/ + +var privateUserEmail = '...'; +export { privateUserEmail }; +``` + ### restrictDefaultExports This option allows you to restrict certain `default` declarations. The option works only if the `restrictedNamedExports` option does not contain the `"default"` value. This option accepts the following properties: diff --git a/lib/rules/no-restricted-exports.js b/lib/rules/no-restricted-exports.js index 8c5ecddd9cb..78fd8709c92 100644 --- a/lib/rules/no-restricted-exports.js +++ b/lib/rules/no-restricted-exports.js @@ -118,7 +118,7 @@ module.exports = { create(context) { const restrictedNames = new Set(context.options[0] && context.options[0].restrictedNamedExports); - const restrictedNamePatterns = context.options[0] && context.options[0].restrictedNamedExportsPattern || []; + const restrictedNamePatterns = new Set(context.options[0] && context.options[0].restrictedNamedExportsPattern || []); const restrictDefaultExports = context.options[0] && context.options[0].restrictDefaultExports; const sourceCode = context.sourceCode; @@ -130,7 +130,7 @@ module.exports = { function checkExportedName(node) { const name = astUtils.getModuleExportName(node); - const hasRestrictedNamePattern = restrictedNamePatterns.some(pattern => { + const hasRestrictedNamePattern = [...restrictedNamePatterns].some(pattern => { const patternRegex = new RegExp(pattern, "u"); return name && patternRegex.test(name); diff --git a/tests/lib/rules/no-restricted-exports.js b/tests/lib/rules/no-restricted-exports.js index 2488925699c..f0e807ceed7 100644 --- a/tests/lib/rules/no-restricted-exports.js +++ b/tests/lib/rules/no-restricted-exports.js @@ -567,6 +567,13 @@ ruleTester.run("no-restricted-exports", rule, { { messageId: "restrictedNamed", data: { name: "ab" }, type: "Identifier" } ] }, + { + code: "var privateUserEmail; export { privateUserEmail };", + options: [{ restrictedNamedExportsPattern: ["^privateUser"] }], + errors: [ + { messageId: "restrictedNamed", data: { name: "privateUserEmail" }, type: "Identifier" } + ] + }, // reports "default" in named export declarations (when configured) { From c881975f1324b05b4aba008b74723ffe6a7764be Mon Sep 17 00:00:00 2001 From: akulsr0 Date: Thu, 9 May 2024 21:25:22 +0530 Subject: [PATCH 5/9] chore: review changes --- docs/src/rules/no-restricted-exports.md | 6 ++--- lib/rules/no-restricted-exports.js | 34 +++++++----------------- tests/lib/rules/no-restricted-exports.js | 12 ++++----- 3 files changed, 18 insertions(+), 34 deletions(-) diff --git a/docs/src/rules/no-restricted-exports.md b/docs/src/rules/no-restricted-exports.md index 5825bde1042..5ed8fddcf25 100644 --- a/docs/src/rules/no-restricted-exports.md +++ b/docs/src/rules/no-restricted-exports.md @@ -17,7 +17,7 @@ By default, this rule doesn't disallow any names. Only the names you specify in This rule has an object option: * `"restrictedNamedExports"` is an array of strings, where each string is a name to be restricted. -* `"restrictedNamedExportsPattern"` is an array of regex strings, where each string regex pattern would be restricted. +* `"restrictedNamedExportsPattern"` is a regex string, and any named export matching that pattern would be restricted. * `"restrictDefaultExports"` is an object option with boolean properties to restrict certain default export declarations. The option works only if the `restrictedNamedExports` option does not contain the `"default"` value. The following properties are allowed: * `direct`: restricts `export default` declarations. * `named`: restricts `export { foo as default };` declarations. @@ -133,12 +133,12 @@ export default function foo() {} ### restrictedNamedExportsPattern -This option allows you to restrict regex patterns for named exports. +This option allows you to restrict regex pattern for named exports. ```js /*eslint no-restricted-exports: ["error", { "restrictedNamedExports": [], - "restrictedNamedExportsPattern": ["^privateUser"] + "restrictedNamedExportsPattern": "^privateUser" }]*/ var privateUserEmail = '...'; diff --git a/lib/rules/no-restricted-exports.js b/lib/rules/no-restricted-exports.js index 78fd8709c92..821c1b57e17 100644 --- a/lib/rules/no-restricted-exports.js +++ b/lib/rules/no-restricted-exports.js @@ -28,19 +28,6 @@ module.exports = { schema: [{ anyOf: [ - { - type: "object", - properties: { - restrictedNamedExports: { - type: "array", - items: { - type: "string" - }, - uniqueItems: true - } - }, - additionalProperties: false - }, { type: "object", properties: { @@ -51,13 +38,7 @@ module.exports = { }, uniqueItems: true }, - restrictedNamedExportsPattern: { - type: "array", - items: { - type: "string" - }, - uniqueItems: true - } + restrictedNamedExportsPattern: { type: "string" } }, additionalProperties: false }, @@ -72,6 +53,7 @@ module.exports = { }, uniqueItems: true }, + restrictedNamedExportsPattern: { type: "string" }, restrictDefaultExports: { type: "object", properties: { @@ -118,7 +100,7 @@ module.exports = { create(context) { const restrictedNames = new Set(context.options[0] && context.options[0].restrictedNamedExports); - const restrictedNamePatterns = new Set(context.options[0] && context.options[0].restrictedNamedExportsPattern || []); + const restrictedNamePattern = context.options[0] && context.options[0].restrictedNamedExportsPattern; const restrictDefaultExports = context.options[0] && context.options[0].restrictDefaultExports; const sourceCode = context.sourceCode; @@ -130,11 +112,13 @@ module.exports = { function checkExportedName(node) { const name = astUtils.getModuleExportName(node); - const hasRestrictedNamePattern = [...restrictedNamePatterns].some(pattern => { - const patternRegex = new RegExp(pattern, "u"); + let hasRestrictedNamePattern = false; - return name && patternRegex.test(name); - }); + if (restrictedNamePattern) { + const patternRegex = new RegExp(restrictedNamePattern, "u"); + + hasRestrictedNamePattern = name && patternRegex.test(name); + } if (hasRestrictedNamePattern || restrictedNames.has(name)) { context.report({ diff --git a/tests/lib/rules/no-restricted-exports.js b/tests/lib/rules/no-restricted-exports.js index f0e807ceed7..ca325342225 100644 --- a/tests/lib/rules/no-restricted-exports.js +++ b/tests/lib/rules/no-restricted-exports.js @@ -93,7 +93,7 @@ ruleTester.run("no-restricted-exports", rule, { { code: "import { b as a } from 'foo';", options: [{ restrictedNamedExports: ["a"] }] }, { code: "var setSomething; export { setSomething };", - options: [{ restrictedNamedExportsPattern: ["^get"] }] + options: [{ restrictedNamedExportsPattern: "^get" }] }, // does not check re-export all declarations @@ -540,21 +540,21 @@ ruleTester.run("no-restricted-exports", rule, { // restrictedNamedExportsPattern { code: "var getSomething; export { getSomething };", - options: [{ restrictedNamedExportsPattern: ["get*"] }], + options: [{ restrictedNamedExportsPattern: "get*" }], errors: [ { messageId: "restrictedNamed", data: { name: "getSomething" }, type: "Identifier" } ] }, { code: "var getSomethingFromUser; export { getSomethingFromUser };", - options: [{ restrictedNamedExportsPattern: ["User$"] }], + options: [{ restrictedNamedExportsPattern: "User$" }], errors: [ { messageId: "restrictedNamed", data: { name: "getSomethingFromUser" }, type: "Identifier" } ] }, { code: "var foo, ab, xy; export { foo, ab, xy };", - options: [{ restrictedNamedExportsPattern: ["(b|y)$"] }], + options: [{ restrictedNamedExportsPattern: "(b|y)$" }], errors: [ { messageId: "restrictedNamed", data: { name: "ab" }, type: "Identifier" }, { messageId: "restrictedNamed", data: { name: "xy" }, type: "Identifier" } @@ -562,14 +562,14 @@ ruleTester.run("no-restricted-exports", rule, { }, { code: "var foo; export { foo as ab };", - options: [{ restrictedNamedExportsPattern: ["(b|y)$"] }], + options: [{ restrictedNamedExportsPattern: "(b|y)$" }], errors: [ { messageId: "restrictedNamed", data: { name: "ab" }, type: "Identifier" } ] }, { code: "var privateUserEmail; export { privateUserEmail };", - options: [{ restrictedNamedExportsPattern: ["^privateUser"] }], + options: [{ restrictedNamedExportsPattern: "^privateUser" }], errors: [ { messageId: "restrictedNamed", data: { name: "privateUserEmail" }, type: "Identifier" } ] From ac7356f38f285c8d4590e042b2a212c2954a0cfa Mon Sep 17 00:00:00 2001 From: akulsr0 Date: Sat, 11 May 2024 11:08:13 +0530 Subject: [PATCH 6/9] chore: add correct/incorrect example doc --- docs/src/rules/no-restricted-exports.md | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/docs/src/rules/no-restricted-exports.md b/docs/src/rules/no-restricted-exports.md index 5ed8fddcf25..be32d4dc5f7 100644 --- a/docs/src/rules/no-restricted-exports.md +++ b/docs/src/rules/no-restricted-exports.md @@ -133,16 +133,28 @@ export default function foo() {} ### restrictedNamedExportsPattern -This option allows you to restrict regex pattern for named exports. +Example of **incorrect** code for the `"restrictedNamedExportsPattern"` option: + +::: incorrect + +```js +/*eslint no-restricted-exports: ["error", { + "restrictedNamedExportsPattern": "bar$" +}]*/ + +export const foobar = 1; +``` + +Example of **correct** code for the `"restrictedNamedExportsPattern"` option: + +::: correct ```js /*eslint no-restricted-exports: ["error", { - "restrictedNamedExports": [], - "restrictedNamedExportsPattern": "^privateUser" + "restrictedNamedExportsPattern": "bar$" }]*/ -var privateUserEmail = '...'; -export { privateUserEmail }; +export const abc = 1; ``` ### restrictDefaultExports From 43f0a4676d9107f6c3469b05d3e62341a9bb4db6 Mon Sep 17 00:00:00 2001 From: akulsr0 Date: Sun, 12 May 2024 19:48:24 +0530 Subject: [PATCH 7/9] chore: review changes --- docs/src/rules/no-restricted-exports.md | 4 ++++ lib/rules/no-restricted-exports.js | 6 +++--- tests/lib/rules/no-restricted-exports.js | 11 +++++++++++ 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/docs/src/rules/no-restricted-exports.md b/docs/src/rules/no-restricted-exports.md index be32d4dc5f7..2893753fb1b 100644 --- a/docs/src/rules/no-restricted-exports.md +++ b/docs/src/rules/no-restricted-exports.md @@ -145,6 +145,8 @@ Example of **incorrect** code for the `"restrictedNamedExportsPattern"` option: export const foobar = 1; ``` +::: + Example of **correct** code for the `"restrictedNamedExportsPattern"` option: ::: correct @@ -157,6 +159,8 @@ Example of **correct** code for the `"restrictedNamedExportsPattern"` option: export const abc = 1; ``` +::: + ### restrictDefaultExports This option allows you to restrict certain `default` declarations. The option works only if the `restrictedNamedExports` option does not contain the `"default"` value. This option accepts the following properties: diff --git a/lib/rules/no-restricted-exports.js b/lib/rules/no-restricted-exports.js index 821c1b57e17..4b946f29c4a 100644 --- a/lib/rules/no-restricted-exports.js +++ b/lib/rules/no-restricted-exports.js @@ -112,15 +112,15 @@ module.exports = { function checkExportedName(node) { const name = astUtils.getModuleExportName(node); - let hasRestrictedNamePattern = false; + let matchesRestrictedNamePattern = false; if (restrictedNamePattern) { const patternRegex = new RegExp(restrictedNamePattern, "u"); - hasRestrictedNamePattern = name && patternRegex.test(name); + matchesRestrictedNamePattern = patternRegex.test(name); } - if (hasRestrictedNamePattern || restrictedNames.has(name)) { + if (matchesRestrictedNamePattern || restrictedNames.has(name)) { context.report({ node, messageId: "restrictedNamed", diff --git a/tests/lib/rules/no-restricted-exports.js b/tests/lib/rules/no-restricted-exports.js index ca325342225..2c61726e813 100644 --- a/tests/lib/rules/no-restricted-exports.js +++ b/tests/lib/rules/no-restricted-exports.js @@ -95,6 +95,10 @@ ruleTester.run("no-restricted-exports", rule, { code: "var setSomething; export { setSomething };", options: [{ restrictedNamedExportsPattern: "^get" }] }, + { + code: "var foo, bar; export { foo, bar };", + options: [{ restrictedNamedExportsPattern: "^(?!foo)(?!bar).+$" }] + }, // does not check re-export all declarations { code: "export * from 'foo';", options: [{ restrictedNamedExports: ["a"] }] }, @@ -574,6 +578,13 @@ ruleTester.run("no-restricted-exports", rule, { { messageId: "restrictedNamed", data: { name: "privateUserEmail" }, type: "Identifier" } ] }, + { + code: "export const a = 1;", + options: [{ restrictedNamedExportsPattern: "^(?!foo)(?!bar).+$" }], + errors: [ + { messageId: "restrictedNamed", data: { name: "a" }, type: "Identifier" } + ] + }, // reports "default" in named export declarations (when configured) { From 2984afdca2f2d02726e80ab2960d064c6562e724 Mon Sep 17 00:00:00 2001 From: akulsr0 Date: Mon, 13 May 2024 10:31:43 +0530 Subject: [PATCH 8/9] chore: review changes --- docs/src/rules/no-restricted-exports.md | 4 +++- lib/rules/no-restricted-exports.js | 2 +- tests/lib/rules/no-restricted-exports.js | 4 ++++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/docs/src/rules/no-restricted-exports.md b/docs/src/rules/no-restricted-exports.md index 2893753fb1b..446c4fbc337 100644 --- a/docs/src/rules/no-restricted-exports.md +++ b/docs/src/rules/no-restricted-exports.md @@ -17,7 +17,7 @@ By default, this rule doesn't disallow any names. Only the names you specify in This rule has an object option: * `"restrictedNamedExports"` is an array of strings, where each string is a name to be restricted. -* `"restrictedNamedExportsPattern"` is a regex string, and any named export matching that pattern would be restricted. +* `"restrictedNamedExportsPattern"` is a string representing a regular expression pattern. Named exports matching this pattern will be restricted. This option does not apply to `default` named exports. * `"restrictDefaultExports"` is an object option with boolean properties to restrict certain default export declarations. The option works only if the `restrictedNamedExports` option does not contain the `"default"` value. The following properties are allowed: * `direct`: restricts `export default` declarations. * `named`: restricts `export { foo as default };` declarations. @@ -161,6 +161,8 @@ export const abc = 1; ::: +Note that this option does not apply to `export default` or any `default` named exports. If you want to also restrict `default` exports, use the `restrictDefaultExports` option. + ### restrictDefaultExports This option allows you to restrict certain `default` declarations. The option works only if the `restrictedNamedExports` option does not contain the `"default"` value. This option accepts the following properties: diff --git a/lib/rules/no-restricted-exports.js b/lib/rules/no-restricted-exports.js index 4b946f29c4a..8da2f2dfe01 100644 --- a/lib/rules/no-restricted-exports.js +++ b/lib/rules/no-restricted-exports.js @@ -114,7 +114,7 @@ module.exports = { let matchesRestrictedNamePattern = false; - if (restrictedNamePattern) { + if (restrictedNamePattern && name !== "default") { const patternRegex = new RegExp(restrictedNamePattern, "u"); matchesRestrictedNamePattern = patternRegex.test(name); diff --git a/tests/lib/rules/no-restricted-exports.js b/tests/lib/rules/no-restricted-exports.js index 2c61726e813..c215ef8c42a 100644 --- a/tests/lib/rules/no-restricted-exports.js +++ b/tests/lib/rules/no-restricted-exports.js @@ -99,6 +99,10 @@ ruleTester.run("no-restricted-exports", rule, { code: "var foo, bar; export { foo, bar };", options: [{ restrictedNamedExportsPattern: "^(?!foo)(?!bar).+$" }] }, + { + code: "var foobar; export default foobar;", + options: [{ restrictedNamedExportsPattern: "bar$" }] + }, // does not check re-export all declarations { code: "export * from 'foo';", options: [{ restrictedNamedExports: ["a"] }] }, From 9e068821483c3824a7289ea4d6300b0c8bad8762 Mon Sep 17 00:00:00 2001 From: akulsr0 Date: Mon, 13 May 2024 18:36:18 +0530 Subject: [PATCH 9/9] chore: add default test cases --- tests/lib/rules/no-restricted-exports.js | 32 ++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/tests/lib/rules/no-restricted-exports.js b/tests/lib/rules/no-restricted-exports.js index c215ef8c42a..aab1043fc70 100644 --- a/tests/lib/rules/no-restricted-exports.js +++ b/tests/lib/rules/no-restricted-exports.js @@ -103,6 +103,38 @@ ruleTester.run("no-restricted-exports", rule, { code: "var foobar; export default foobar;", options: [{ restrictedNamedExportsPattern: "bar$" }] }, + { + code: "var foobar; export default foobar;", + options: [{ restrictedNamedExportsPattern: "default" }] + }, + { + code: "export default 'default';", + options: [{ restrictedNamedExportsPattern: "default" }] + }, + { + code: "var foobar; export { foobar as default };", + options: [{ restrictedNamedExportsPattern: "default" }] + }, + { + code: "var foobar; export { foobar as 'default' };", + options: [{ restrictedNamedExportsPattern: "default" }] + }, + { + code: "export { default } from 'mod';", + options: [{ restrictedNamedExportsPattern: "default" }] + }, + { + code: "export { default as default } from 'mod';", + options: [{ restrictedNamedExportsPattern: "default" }] + }, + { + code: "export { foobar as default } from 'mod';", + options: [{ restrictedNamedExportsPattern: "default" }] + }, + { + code: "export * as default from 'mod';", + options: [{ restrictedNamedExportsPattern: "default" }] + }, // does not check re-export all declarations { code: "export * from 'foo';", options: [{ restrictedNamedExports: ["a"] }] },