From e7cfbf11fa426e224d28103e0da6aac0bc931b5d Mon Sep 17 00:00:00 2001 From: ocavue Date: Sat, 12 Oct 2024 11:05:34 +1100 Subject: [PATCH 01/14] [Fix] correct generated type declaration --- index.js | 53 ++++++++++++++------------ lib/rules/forbid-prop-types.js | 1 + lib/rules/forward-ref-uses-ref.js | 1 + lib/rules/index.js | 4 +- lib/rules/jsx-fragments.js | 2 +- lib/rules/jsx-no-literals.js | 5 ++- lib/rules/jsx-props-no-spread-multi.js | 1 + lib/rules/no-deprecated.js | 2 +- package.json | 2 +- 9 files changed, 40 insertions(+), 31 deletions(-) diff --git a/index.js b/index.js index 8426993e5b..7cd1fcb21a 100644 --- a/index.js +++ b/index.js @@ -11,7 +11,7 @@ function filterRules(rules, predicate) { /** * @param {object} rules - rules object mapping rule name to rule module - * @returns {Record} + * @returns {Record} */ function configureAsError(rules) { return fromEntries(Object.keys(rules).map((key) => [`react/${key}`, 2])); @@ -31,6 +31,9 @@ const plugins = [ 'react', ]; +const SEVERITY_ERROR = /** @type {2} */ (2); +const SEVERITY_OFF = /** @type {0} */ (0); + const configs = { recommended: { plugins, @@ -40,28 +43,28 @@ const configs = { }, }, rules: { - 'react/display-name': 2, - 'react/jsx-key': 2, - 'react/jsx-no-comment-textnodes': 2, - 'react/jsx-no-duplicate-props': 2, - 'react/jsx-no-target-blank': 2, - 'react/jsx-no-undef': 2, - 'react/jsx-uses-react': 2, - 'react/jsx-uses-vars': 2, - 'react/no-children-prop': 2, - 'react/no-danger-with-children': 2, - 'react/no-deprecated': 2, - 'react/no-direct-mutation-state': 2, - 'react/no-find-dom-node': 2, - 'react/no-is-mounted': 2, - 'react/no-render-return-value': 2, - 'react/no-string-refs': 2, - 'react/no-unescaped-entities': 2, - 'react/no-unknown-property': 2, - 'react/no-unsafe': 0, - 'react/prop-types': 2, - 'react/react-in-jsx-scope': 2, - 'react/require-render-return': 2, + 'react/display-name': SEVERITY_ERROR, + 'react/jsx-key': SEVERITY_ERROR, + 'react/jsx-no-comment-textnodes': SEVERITY_ERROR, + 'react/jsx-no-duplicate-props': SEVERITY_ERROR, + 'react/jsx-no-target-blank': SEVERITY_ERROR, + 'react/jsx-no-undef': SEVERITY_ERROR, + 'react/jsx-uses-react': SEVERITY_ERROR, + 'react/jsx-uses-vars': SEVERITY_ERROR, + 'react/no-children-prop': SEVERITY_ERROR, + 'react/no-danger-with-children': SEVERITY_ERROR, + 'react/no-deprecated': SEVERITY_ERROR, + 'react/no-direct-mutation-state': SEVERITY_ERROR, + 'react/no-find-dom-node': SEVERITY_ERROR, + 'react/no-is-mounted': SEVERITY_ERROR, + 'react/no-render-return-value': SEVERITY_ERROR, + 'react/no-string-refs': SEVERITY_ERROR, + 'react/no-unescaped-entities': SEVERITY_ERROR, + 'react/no-unknown-property': SEVERITY_ERROR, + 'react/no-unsafe': SEVERITY_OFF, + 'react/prop-types': SEVERITY_ERROR, + 'react/react-in-jsx-scope': SEVERITY_ERROR, + 'react/require-render-return': SEVERITY_ERROR, }, }, all: { @@ -82,8 +85,8 @@ const configs = { jsxPragma: null, // for @typescript/eslint-parser }, rules: { - 'react/react-in-jsx-scope': 0, - 'react/jsx-uses-react': 0, + 'react/react-in-jsx-scope': SEVERITY_OFF, + 'react/jsx-uses-react': SEVERITY_OFF, }, }, }; diff --git a/lib/rules/forbid-prop-types.js b/lib/rules/forbid-prop-types.js index df40706d00..44de1fa023 100644 --- a/lib/rules/forbid-prop-types.js +++ b/lib/rules/forbid-prop-types.js @@ -195,6 +195,7 @@ module.exports = { const propTypesSpecifier = node.specifiers.find((specifier) => ( 'imported' in specifier && specifier.imported + && 'name' in specifier.imported && specifier.imported.name === 'PropTypes' )); if (propTypesSpecifier) { diff --git a/lib/rules/forward-ref-uses-ref.js b/lib/rules/forward-ref-uses-ref.js index aeedeb82df..3a0b7de4c9 100644 --- a/lib/rules/forward-ref-uses-ref.js +++ b/lib/rules/forward-ref-uses-ref.js @@ -41,6 +41,7 @@ const messages = { removeForwardRef: 'Remove forwardRef wrapper', }; +/** @type {import('eslint').Rule.RuleModule} */ module.exports = { meta: { docs: { diff --git a/lib/rules/index.js b/lib/rules/index.js index 1e010b677b..0e73ab1a3f 100644 --- a/lib/rules/index.js +++ b/lib/rules/index.js @@ -3,7 +3,7 @@ /* eslint global-require: 0 */ /** @satisfies {Record} */ -module.exports = { +const rules = { 'boolean-prop-naming': require('./boolean-prop-naming'), 'button-has-type': require('./button-has-type'), 'checked-requires-onchange-or-readonly': require('./checked-requires-onchange-or-readonly'), @@ -108,3 +108,5 @@ module.exports = { 'style-prop-object': require('./style-prop-object'), 'void-dom-elements-no-children': require('./void-dom-elements-no-children'), }; + +module.exports = rules; diff --git a/lib/rules/jsx-fragments.js b/lib/rules/jsx-fragments.js index 6835331025..e6787c8af5 100644 --- a/lib/rules/jsx-fragments.js +++ b/lib/rules/jsx-fragments.js @@ -170,7 +170,7 @@ module.exports = { ImportDeclaration(node) { if (node.source && node.source.value === 'react') { node.specifiers.forEach((spec) => { - if ('imported' in spec && spec.imported && spec.imported.name === fragmentPragma) { + if ('imported' in spec && spec.imported && 'name' in spec.imported && spec.imported.name === fragmentPragma) { if (spec.local) { fragmentNames.add(spec.local.name); } diff --git a/lib/rules/jsx-no-literals.js b/lib/rules/jsx-no-literals.js index 230d33a18d..5b092dcdfe 100644 --- a/lib/rules/jsx-no-literals.js +++ b/lib/rules/jsx-no-literals.js @@ -45,7 +45,7 @@ const messages = { literalNotInJSXExpressionInElement: 'Missing JSX expression container around literal string: "{{text}}" in {{element}}', }; -/** @type {Exclude['properties']} */ +/** @type {Exclude['properties']} */ const commonPropertiesSchema = { noStrings: { type: 'boolean', @@ -182,6 +182,7 @@ const elementOverrides = { }, }; +/** @type {import('eslint').Rule.RuleModule} */ module.exports = { meta: /** @type {import('eslint').Rule.RuleModule["meta"]} */ ({ docs: { @@ -485,7 +486,7 @@ module.exports = { }); }); }, - } : false, { + } : {}, { Literal(node) { const resolvedConfig = getOverrideConfig(node) || config; diff --git a/lib/rules/jsx-props-no-spread-multi.js b/lib/rules/jsx-props-no-spread-multi.js index 2eeed0be49..3103be86da 100644 --- a/lib/rules/jsx-props-no-spread-multi.js +++ b/lib/rules/jsx-props-no-spread-multi.js @@ -16,6 +16,7 @@ const messages = { noMultiSpreading: 'Spreading the same expression multiple times is forbidden', }; +/** @type {import('eslint').Rule.RuleModule} */ module.exports = { meta: { docs: { diff --git a/lib/rules/no-deprecated.js b/lib/rules/no-deprecated.js index 9f5ddf7082..0c5931345f 100644 --- a/lib/rules/no-deprecated.js +++ b/lib/rules/no-deprecated.js @@ -229,7 +229,7 @@ module.exports = { } node.specifiers.filter(((s) => 'imported' in s && s.imported)).forEach((specifier) => { // TODO, semver-major: remove `in` check as part of jsdoc->tsdoc migration - checkDeprecation(node, 'imported' in specifier && `${MODULES[node.source.value][0]}.${specifier.imported.name}`, specifier); + checkDeprecation(node, 'imported' in specifier && 'name' in specifier.imported && `${MODULES[node.source.value][0]}.${specifier.imported.name}`, specifier); }); }, diff --git a/package.json b/package.json index 5122692c22..23afa5b598 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,7 @@ "@types/node": "^4.9.5", "@typescript-eslint/parser": "^2.34.0 || ^3.10.1 || ^4 || ^5 || ^6.20 || ^7.14.1 || ^8.4", "babel-eslint": "^8 || ^9 || ^10.1.0", - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7", + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.10", "eslint-config-airbnb-base": "^15.0.0", "eslint-doc-generator": "^1.7.1", "eslint-plugin-eslint-plugin": "^2.3.0 || ^3.5.3 || ^4.0.1 || ^5.0.5", From 27d8b6e5bf41f28ea4b377c872ad1d0b963eaa67 Mon Sep 17 00:00:00 2001 From: ocavue Date: Sat, 12 Oct 2024 11:17:44 +1100 Subject: [PATCH 02/14] Try remove `@ts-expect-error` --- lib/rules/forbid-foreign-prop-types.js | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/rules/forbid-foreign-prop-types.js b/lib/rules/forbid-foreign-prop-types.js index 7724049af4..ce82028395 100644 --- a/lib/rules/forbid-foreign-prop-types.js +++ b/lib/rules/forbid-foreign-prop-types.js @@ -109,7 +109,6 @@ module.exports = { && !ast.isAssignmentLHS(node) && !isAllowedAssignment(node) )) || ( - // @ts-expect-error The JSXText type is not present in the estree type definitions (node.property.type === 'Literal' || node.property.type === 'JSXText') && 'value' in node.property && node.property.value === 'propTypes' From d7cc41f90143da7afe4c421562c6e757013c7d87 Mon Sep 17 00:00:00 2001 From: ocavue Date: Sat, 12 Oct 2024 11:35:17 +1100 Subject: [PATCH 03/14] change back eslint devDependencies version range --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 23afa5b598..5122692c22 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,7 @@ "@types/node": "^4.9.5", "@typescript-eslint/parser": "^2.34.0 || ^3.10.1 || ^4 || ^5 || ^6.20 || ^7.14.1 || ^8.4", "babel-eslint": "^8 || ^9 || ^10.1.0", - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.10", + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7", "eslint-config-airbnb-base": "^15.0.0", "eslint-doc-generator": "^1.7.1", "eslint-plugin-eslint-plugin": "^2.3.0 || ^3.5.3 || ^4.0.1 || ^5.0.5", From f33003c4195d50b8621ddb29bc4b643f56ec2292 Mon Sep 17 00:00:00 2001 From: ocavue Date: Sat, 12 Oct 2024 11:43:14 +1100 Subject: [PATCH 04/14] Update lib/rules/jsx-fragments.js Co-authored-by: Jordan Harband --- lib/rules/jsx-fragments.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/rules/jsx-fragments.js b/lib/rules/jsx-fragments.js index e6787c8af5..b4a545846e 100644 --- a/lib/rules/jsx-fragments.js +++ b/lib/rules/jsx-fragments.js @@ -170,7 +170,12 @@ module.exports = { ImportDeclaration(node) { if (node.source && node.source.value === 'react') { node.specifiers.forEach((spec) => { - if ('imported' in spec && spec.imported && 'name' in spec.imported && spec.imported.name === fragmentPragma) { + if ( + 'imported' in spec + && spec.imported + && 'name' in spec.imported + && spec.imported.name === fragmentPragma + ) { if (spec.local) { fragmentNames.add(spec.local.name); } From 9e7d3b4dab004cbd129e813bddfe5c3fa51fbb5d Mon Sep 17 00:00:00 2001 From: ocavue Date: Sat, 12 Oct 2024 12:15:12 +1100 Subject: [PATCH 05/14] Add types/rules/jsx-no-literals.d.ts to avoid error TS2309: An export assignment cannot be used in a module with other exported elements. --- lib/rules/jsx-no-literals.js | 64 +++++++------------------------- tsconfig.json | 2 +- types/rules/jsx-no-literals.d.ts | 50 +++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 52 deletions(-) create mode 100644 types/rules/jsx-no-literals.d.ts diff --git a/lib/rules/jsx-no-literals.js b/lib/rules/jsx-no-literals.js index 5b092dcdfe..e7811646fc 100644 --- a/lib/rules/jsx-no-literals.js +++ b/lib/rules/jsx-no-literals.js @@ -66,51 +66,13 @@ const commonPropertiesSchema = { }; /** - * @typedef RawElementConfigProperties - * @property {boolean} [noStrings] - * @property {string[]} [allowedStrings] - * @property {boolean} [ignoreProps] - * @property {boolean} [noAttributeStrings] - * - * @typedef RawOverrideConfigProperties - * @property {boolean} [allowElement] - * @property {boolean} [applyToNestedElements=true] - * - * @typedef {RawElementConfigProperties} RawElementConfig - * @typedef {RawElementConfigProperties & RawElementConfigProperties} RawOverrideConfig - * - * @typedef RawElementOverrides - * @property {Record} [elementOverrides] - * - * @typedef {RawElementConfig & RawElementOverrides} RawConfig - * - * ---------------------------------------------------------------------- - * - * @typedef ElementConfigType - * @property {'element'} type - * - * @typedef ElementConfigProperties - * @property {boolean} noStrings - * @property {Set} allowedStrings - * @property {boolean} ignoreProps - * @property {boolean} noAttributeStrings - * - * @typedef OverrideConfigProperties - * @property {'override'} type - * @property {string} name - * @property {boolean} allowElement - * @property {boolean} applyToNestedElements - * - * @typedef {ElementConfigType & ElementConfigProperties} ElementConfig - * @typedef {OverrideConfigProperties & ElementConfigProperties} OverrideConfig - * - * @typedef ElementOverrides - * @property {Record} elementOverrides - * - * @typedef {ElementConfig & ElementOverrides} Config - * @typedef {Config | OverrideConfig} ResolvedConfig + * @typedef {import("../../types/rules/jsx-no-literals").RawConfig} RawConfig + * @typedef {import("../../types/rules/jsx-no-literals").ElementConfig} ElementConfig + * @typedef {import("../../types/rules/jsx-no-literals").OverrideConfig} OverrideConfig + * @typedef {import("../../types/rules/jsx-no-literals").Config} Config + * @typedef {import("../../types/rules/jsx-no-literals").ResolvedConfig} ResolvedConfig */ - + /** * Normalizes the element portion of the config * @param {RawConfig} config @@ -131,10 +93,10 @@ function normalizeElementConfig(config) { /** * Normalizes the config and applies default values to all config options * @param {RawConfig} config - * @returns {Config} + * @returns {import('./jsx-no-literals').Config} */ function normalizeConfig(config) { - /** @type {Config} */ + /** @type {import('./jsx-no-literals').Config} */ const normalizedConfig = Object.assign(normalizeElementConfig(config), { elementOverrides: {}, }); @@ -344,7 +306,7 @@ module.exports = { * Determines whether a given node's value and its immediate parent are * viable text nodes that can/should be reported on * @param {ASTNode} node - * @param {ResolvedConfig} resolvedConfig + * @param {import('./jsx-no-literals').ResolvedConfig} resolvedConfig * @returns {boolean} */ function isViableTextNode(node, resolvedConfig) { @@ -376,7 +338,7 @@ module.exports = { * need to traverse the ancestor tree to determine if an ancestor's config * will also apply to the current node. * @param {ASTNode} node - * @returns {OverrideConfig | undefined} + * @returns {import('./jsx-no-literals').OverrideConfig | undefined} */ function getOverrideConfig(node) { if (!hasElementOverrides) { @@ -410,7 +372,7 @@ module.exports = { } /** - * @param {ResolvedConfig} resolvedConfig + * @param {import('./jsx-no-literals').ResolvedConfig} resolvedConfig * @returns {boolean} */ function shouldAllowElement(resolvedConfig) { @@ -419,7 +381,7 @@ module.exports = { /** * @param {boolean} ancestorIsJSXElement - * @param {ResolvedConfig} resolvedConfig + * @param {import('./jsx-no-literals').ResolvedConfig} resolvedConfig * @returns {string} */ function defaultMessageId(ancestorIsJSXElement, resolvedConfig) { @@ -437,7 +399,7 @@ module.exports = { /** * @param {ASTNode} node * @param {string} messageId - * @param {ResolvedConfig} resolvedConfig + * @param {import('./jsx-no-literals').ResolvedConfig} resolvedConfig */ function reportLiteralNode(node, messageId, resolvedConfig) { report(context, messages[messageId], messageId, { diff --git a/tsconfig.json b/tsconfig.json index 39187b7f32..8772fab53d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -19,5 +19,5 @@ "alwaysStrict": false, /* Parse in strict mode and emit "use strict" for each source file. */ "resolveJsonModule": true }, - "include": ["lib"], + "include": ["lib", "types"], } diff --git a/types/rules/jsx-no-literals.d.ts b/types/rules/jsx-no-literals.d.ts new file mode 100644 index 0000000000..c1b9638958 --- /dev/null +++ b/types/rules/jsx-no-literals.d.ts @@ -0,0 +1,50 @@ +type RawElementConfig = { + noStrings?: boolean; + allowedStrings?: string[]; + ignoreProps?: boolean; + noAttributeStrings?: boolean; +}; + +type RawOverrideConfig = { + allowElement?: boolean; + applyToNestedElements?: boolean; +}; + +interface RawElementOverrides { + elementOverrides?: Record; +} + +export type RawConfig = RawElementConfig & RawElementOverrides; + +interface ElementConfigType { + type: 'element'; +} + +interface ElementConfigProperties { + noStrings: boolean; + allowedStrings: Set; + ignoreProps: boolean; + noAttributeStrings: boolean; +} + +interface OverrideConfigProperties { + type: 'override'; + name: string; + allowElement: boolean; + applyToNestedElements: boolean; +} + +export type ElementConfig = { + type: 'element'; +} & ElementConfigProperties; + +export type OverrideConfig = OverrideConfigProperties & ElementConfigProperties; + +interface ElementOverrides { + elementOverrides: Record; +} + +export type Config = ElementConfig & ElementOverrides; + +export type ResolvedConfig = Config | OverrideConfig; + From 9483b34014d9ed43e4f95160183deeb209f0e483 Mon Sep 17 00:00:00 2001 From: ocavue Date: Sat, 12 Oct 2024 12:20:58 +1100 Subject: [PATCH 06/14] Fix types for string.prototype.repeat --- types/string.prototype.repeat/index.d.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/types/string.prototype.repeat/index.d.ts b/types/string.prototype.repeat/index.d.ts index f240d9301f..b2e5992712 100644 --- a/types/string.prototype.repeat/index.d.ts +++ b/types/string.prototype.repeat/index.d.ts @@ -1,3 +1,4 @@ declare module 'string.prototype.repeat' { - export = typeof Function.call.bind(String.prototype.repeat); + function repeat(text: string, count: number): string; + export = repeat; } From 5cb28d81c9df204b548612e6206386893d7c658f Mon Sep 17 00:00:00 2001 From: ocavue Date: Sat, 12 Oct 2024 12:27:05 +1100 Subject: [PATCH 07/14] Avoid `@typedef` --- lib/rules/jsx-no-literals.js | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/lib/rules/jsx-no-literals.js b/lib/rules/jsx-no-literals.js index e7811646fc..6eb1c401fd 100644 --- a/lib/rules/jsx-no-literals.js +++ b/lib/rules/jsx-no-literals.js @@ -65,18 +65,10 @@ const commonPropertiesSchema = { }, }; -/** - * @typedef {import("../../types/rules/jsx-no-literals").RawConfig} RawConfig - * @typedef {import("../../types/rules/jsx-no-literals").ElementConfig} ElementConfig - * @typedef {import("../../types/rules/jsx-no-literals").OverrideConfig} OverrideConfig - * @typedef {import("../../types/rules/jsx-no-literals").Config} Config - * @typedef {import("../../types/rules/jsx-no-literals").ResolvedConfig} ResolvedConfig - */ - /** * Normalizes the element portion of the config - * @param {RawConfig} config - * @returns {ElementConfig} + * @param {import("../../types/rules/jsx-no-literals").RawConfig} config + * @returns {import("../../types/rules/jsx-no-literals").ElementConfig} */ function normalizeElementConfig(config) { return { @@ -92,11 +84,11 @@ function normalizeElementConfig(config) { /** * Normalizes the config and applies default values to all config options - * @param {RawConfig} config - * @returns {import('./jsx-no-literals').Config} + * @param {import("../../types/rules/jsx-no-literals").RawConfig} config + * @returns {import("../../types/rules/jsx-no-literals").Config} */ function normalizeConfig(config) { - /** @type {import('./jsx-no-literals').Config} */ + /** @type {import("../../types/rules/jsx-no-literals").Config} */ const normalizedConfig = Object.assign(normalizeElementConfig(config), { elementOverrides: {}, }); @@ -167,7 +159,7 @@ module.exports = { }), create(context) { - /** @type {RawConfig} */ + /** @type {import("../../types/rules/jsx-no-literals").RawConfig} */ const rawConfig = (context.options.length && context.options[0]) || {}; const config = normalizeConfig(rawConfig); @@ -306,7 +298,7 @@ module.exports = { * Determines whether a given node's value and its immediate parent are * viable text nodes that can/should be reported on * @param {ASTNode} node - * @param {import('./jsx-no-literals').ResolvedConfig} resolvedConfig + * @param {import("../../types/rules/jsx-no-literals").ResolvedConfig} resolvedConfig * @returns {boolean} */ function isViableTextNode(node, resolvedConfig) { @@ -338,7 +330,7 @@ module.exports = { * need to traverse the ancestor tree to determine if an ancestor's config * will also apply to the current node. * @param {ASTNode} node - * @returns {import('./jsx-no-literals').OverrideConfig | undefined} + * @returns {import("../../types/rules/jsx-no-literals").OverrideConfig | undefined} */ function getOverrideConfig(node) { if (!hasElementOverrides) { @@ -372,7 +364,7 @@ module.exports = { } /** - * @param {import('./jsx-no-literals').ResolvedConfig} resolvedConfig + * @param {import("../../types/rules/jsx-no-literals").ResolvedConfig} resolvedConfig * @returns {boolean} */ function shouldAllowElement(resolvedConfig) { @@ -381,7 +373,7 @@ module.exports = { /** * @param {boolean} ancestorIsJSXElement - * @param {import('./jsx-no-literals').ResolvedConfig} resolvedConfig + * @param {import("../../types/rules/jsx-no-literals").ResolvedConfig} resolvedConfig * @returns {string} */ function defaultMessageId(ancestorIsJSXElement, resolvedConfig) { @@ -399,7 +391,7 @@ module.exports = { /** * @param {ASTNode} node * @param {string} messageId - * @param {import('./jsx-no-literals').ResolvedConfig} resolvedConfig + * @param {import("../../types/rules/jsx-no-literals").ResolvedConfig} resolvedConfig */ function reportLiteralNode(node, messageId, resolvedConfig) { report(context, messages[messageId], messageId, { From 7db2a9d008bea4fa7f223bbf40db3286ccd21a05 Mon Sep 17 00:00:00 2001 From: ocavue Date: Sat, 12 Oct 2024 13:04:19 +1100 Subject: [PATCH 08/14] Add eslint-disable-next-line valid-jsdoc --- lib/rules/jsx-no-literals.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/rules/jsx-no-literals.js b/lib/rules/jsx-no-literals.js index 6eb1c401fd..d782433b0c 100644 --- a/lib/rules/jsx-no-literals.js +++ b/lib/rules/jsx-no-literals.js @@ -65,6 +65,7 @@ const commonPropertiesSchema = { }, }; +// eslint-disable-next-line valid-jsdoc /** * Normalizes the element portion of the config * @param {import("../../types/rules/jsx-no-literals").RawConfig} config @@ -82,6 +83,7 @@ function normalizeElementConfig(config) { }; } +// eslint-disable-next-line valid-jsdoc /** * Normalizes the config and applies default values to all config options * @param {import("../../types/rules/jsx-no-literals").RawConfig} config @@ -294,6 +296,7 @@ module.exports = { return some(iterFrom([ancestors.parent, ancestors.grandParent]), (parent) => jsxElementTypes.has(parent.type)); } + // eslint-disable-next-line valid-jsdoc /** * Determines whether a given node's value and its immediate parent are * viable text nodes that can/should be reported on @@ -325,6 +328,7 @@ module.exports = { return isStandardJSXNode && parent.type !== 'JSXExpressionContainer'; } + // eslint-disable-next-line valid-jsdoc /** * Gets an override config for a given node. For any given node, we also * need to traverse the ancestor tree to determine if an ancestor's config @@ -363,6 +367,7 @@ module.exports = { } } + // eslint-disable-next-line valid-jsdoc /** * @param {import("../../types/rules/jsx-no-literals").ResolvedConfig} resolvedConfig * @returns {boolean} @@ -371,6 +376,7 @@ module.exports = { return resolvedConfig.type === 'override' && 'allowElement' in resolvedConfig && !!resolvedConfig.allowElement; } + // eslint-disable-next-line valid-jsdoc /** * @param {boolean} ancestorIsJSXElement * @param {import("../../types/rules/jsx-no-literals").ResolvedConfig} resolvedConfig @@ -388,6 +394,7 @@ module.exports = { return resolvedConfig.type === 'override' ? 'literalNotInJSXExpressionInElement' : 'literalNotInJSXExpression'; } + // eslint-disable-next-line valid-jsdoc /** * @param {ASTNode} node * @param {string} messageId From 3c96ffbaac18c680c030d47ffd2067f12c4b60bb Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Wed, 16 Oct 2024 15:03:47 -0700 Subject: [PATCH 09/14] fixup: add TODO comment --- index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/index.js b/index.js index 7cd1fcb21a..365f17446c 100644 --- a/index.js +++ b/index.js @@ -31,6 +31,7 @@ const plugins = [ 'react', ]; +// TODO: with TS 4.5+, inline this const SEVERITY_ERROR = /** @type {2} */ (2); const SEVERITY_OFF = /** @type {0} */ (0); From 6ffce62de9ef7e51e539b4f30e8c85fb96a45697 Mon Sep 17 00:00:00 2001 From: ocavue Date: Thu, 17 Oct 2024 15:35:17 +1100 Subject: [PATCH 10/14] Add back `// @ts-expect-error` --- lib/rules/forbid-foreign-prop-types.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/rules/forbid-foreign-prop-types.js b/lib/rules/forbid-foreign-prop-types.js index ce82028395..982119af1c 100644 --- a/lib/rules/forbid-foreign-prop-types.js +++ b/lib/rules/forbid-foreign-prop-types.js @@ -109,6 +109,7 @@ module.exports = { && !ast.isAssignmentLHS(node) && !isAllowedAssignment(node) )) || ( + // @ts-expect-error: Literal is not a valid type (node.property.type === 'Literal' || node.property.type === 'JSXText') && 'value' in node.property && node.property.value === 'propTypes' From f2db629848a6abbc613b76c46c3665ebd16381e2 Mon Sep 17 00:00:00 2001 From: ocavue Date: Thu, 17 Oct 2024 15:35:46 +1100 Subject: [PATCH 11/14] Revert the change in Object.assign --- lib/rules/jsx-no-literals.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/rules/jsx-no-literals.js b/lib/rules/jsx-no-literals.js index d782433b0c..44f134ba56 100644 --- a/lib/rules/jsx-no-literals.js +++ b/lib/rules/jsx-no-literals.js @@ -447,7 +447,7 @@ module.exports = { }); }); }, - } : {}, { + } : false, { Literal(node) { const resolvedConfig = getOverrideConfig(node) || config; From 0de698d1f77069c33de5e45ebfec933e952d2fac Mon Sep 17 00:00:00 2001 From: ocavue Date: Thu, 17 Oct 2024 16:20:35 +1100 Subject: [PATCH 12/14] Fix CI test-published-types --- .github/workflows/type-check.yml | 16 ++++++++++++++++ test-published-types/index.js | 4 +++- test-published-types/package.json | 3 +-- test-published-types/tsconfig.json | 3 ++- 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/.github/workflows/type-check.yml b/.github/workflows/type-check.yml index c0e6b4d033..36a9311ada 100644 --- a/.github/workflows/type-check.yml +++ b/.github/workflows/type-check.yml @@ -44,10 +44,26 @@ jobs: - name: build types run: npm run build-types + # Pack the lib into a tarball so that when we install the lib later in the + # test-published-types directory, it's only install `dependencies` of the + # lib. + - name: pack the lib + run: npm run pack --pack-destination /tmp/ + + - name: find the packed lib + run: echo "ESLINT_PLUGIN_REACT_PATH=$(ls /tmp/eslint-plugin-react*.tgz | tail -n 1)" >> $GITHUB_ENV + + - name: show the path to the packed lib + run: echo "$ESLINT_PLUGIN_REACT_PATH" + - name: npm install working directory run: npm install working-directory: test-published-types + - name: install packed lib + run: npm install --no-save "$ESLINT_PLUGIN_REACT_PATH" + working-directory: test-published-types + - name: install typescript version ${{ matrix.ts_version }} run: npm install --no-save typescript@${{ matrix.ts_version }} working-directory: test-published-types diff --git a/test-published-types/index.js b/test-published-types/index.js index 31e6005985..010d658041 100644 --- a/test-published-types/index.js +++ b/test-published-types/index.js @@ -3,10 +3,12 @@ const react = require('eslint-plugin-react'); /** @type {import('eslint').Linter.Config[]} */ -module.exports = [ +const config = [ { plugins: { react, }, }, ]; + +module.exports = config; diff --git a/test-published-types/package.json b/test-published-types/package.json index ab8a7160c6..80953c53ab 100644 --- a/test-published-types/package.json +++ b/test-published-types/package.json @@ -3,7 +3,6 @@ "private": true, "version": "0.0.0", "dependencies": { - "eslint": "^9.11.1", - "eslint-plugin-react": "file:.." + "eslint": "^9.11.1" } } diff --git a/test-published-types/tsconfig.json b/test-published-types/tsconfig.json index 7fc1500df3..2ce0bd816e 100644 --- a/test-published-types/tsconfig.json +++ b/test-published-types/tsconfig.json @@ -7,6 +7,7 @@ "compilerOptions": { "lib": ["esnext"], - "types": ["node"] + "types": ["node"], + "skipLibCheck": true } } From e5b553f4ef4a30649c2fceebc62d95b59da82934 Mon Sep 17 00:00:00 2001 From: ocavue Date: Thu, 17 Oct 2024 16:22:09 +1100 Subject: [PATCH 13/14] Fix CI test-published-types --- .github/workflows/type-check.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/type-check.yml b/.github/workflows/type-check.yml index 36a9311ada..ce9286237f 100644 --- a/.github/workflows/type-check.yml +++ b/.github/workflows/type-check.yml @@ -48,7 +48,7 @@ jobs: # test-published-types directory, it's only install `dependencies` of the # lib. - name: pack the lib - run: npm run pack --pack-destination /tmp/ + run: npm pack --pack-destination /tmp/ - name: find the packed lib run: echo "ESLINT_PLUGIN_REACT_PATH=$(ls /tmp/eslint-plugin-react*.tgz | tail -n 1)" >> $GITHUB_ENV From bab6a750b70b63ab981778ceb2331f0f9886e490 Mon Sep 17 00:00:00 2001 From: ocavue Date: Thu, 17 Oct 2024 16:57:18 +1100 Subject: [PATCH 14/14] Fix install script in type-check.yml --- .github/workflows/type-check.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/type-check.yml b/.github/workflows/type-check.yml index ce9286237f..d6fcb91218 100644 --- a/.github/workflows/type-check.yml +++ b/.github/workflows/type-check.yml @@ -60,18 +60,18 @@ jobs: run: npm install working-directory: test-published-types - - name: install packed lib - run: npm install --no-save "$ESLINT_PLUGIN_REACT_PATH" - working-directory: test-published-types - - - name: install typescript version ${{ matrix.ts_version }} - run: npm install --no-save typescript@${{ matrix.ts_version }} + - name: install eslint-plugin-react and typescript version ${{ matrix.ts_version }} + run: npm install --no-save "$ESLINT_PLUGIN_REACT_PATH" typescript@${{ matrix.ts_version }} working-directory: test-published-types - name: show installed typescript version run: npm list typescript --depth=0 working-directory: test-published-types + - name: show installed eslint-plugin-react version + run: npm list eslint-plugin-react --depth=0 + working-directory: test-published-types + - name: check types with lib "${{ matrix.ts_lib }}" run: npx tsc --lib ${{ matrix.ts_lib }} working-directory: test-published-types