Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/typescript/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Fixed

- **BREAKING:** Restrict usage of `with`, `in`, and sequence expressions, which should have been inherited from the base config but were mistakenly overridden ([#436](https://github.com/MetaMask/eslint-config/pull/436))
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We shouldn't have been overriding these rules, but it's been a while since we made a new eslint-config release, so even though I don't like that we have to mark this change as breaking, I figure it's probably better to do so than not.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could also wait to merge this if there are any non-breaking changes we'd like to release first.


## [15.0.0]

### Changed
Expand Down
12 changes: 12 additions & 0 deletions packages/typescript/rules-snapshot.json
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,18 @@
"no-redeclare": "off",
"no-restricted-syntax": [
"error",
{
"selector": "WithStatement",
"message": "With statements are not allowed"
},
{
"selector": "BinaryExpression[operator='in']",
"message": "The \"in\" operator is not allowed"
},
{
"selector": "SequenceExpression",
"message": "Sequence expressions are not allowed"
},
{
"selector": "PropertyDefinition[accessibility='private'], MethodDefinition[accessibility='private'], TSParameterProperty[accessibility='private']",
"message": "Use a hash name instead."
Expand Down
34 changes: 33 additions & 1 deletion packages/typescript/src/index.mjs
Original file line number Diff line number Diff line change
@@ -1,11 +1,42 @@
import { createConfig } from '@metamask/eslint-config';
import base, { createConfig } from '@metamask/eslint-config';
import * as resolver from 'eslint-import-resolver-typescript';
import importX from 'eslint-plugin-import-x';
import jsdoc from 'eslint-plugin-jsdoc';
// TODO: Look into why this doesn't resolve.
// eslint-disable-next-line import-x/no-unresolved
import typescript from 'typescript-eslint';

/**
* Collects all options for a given array-valued rule across one or more flat
* config arrays, excluding the leading severity element.
*
* ESLint flat config does not merge array-valued rules across config objects —
* a later config silently replaces earlier ones. This helper makes it possible
* to extend an upstream rule configuration rather than copy-pasting its options.
*
* @param {string} ruleName - The rule to collect options for.
* @param {import('eslint').Linter.Config[][]} configs - Flat config arrays to
* collect options from.
* @returns {unknown[]} The options from all matching rule entries, with the
* leading severity element omitted.
*/
function collectExistingRuleOptions(ruleName, configs) {
return configs.flat().flatMap((config) => {
const rule = config.rules?.[ruleName];
if (!Array.isArray(rule)) {
return [];
}
// Rule entries are ['error' | 'warn' | number, ...options].
// Skip the first element (severity) and collect the rest.
return rule.slice(1);
});
}

const baseNoRestrictedSyntaxOptions = collectExistingRuleOptions(
'no-restricted-syntax',
base,
);

const config = createConfig({
name: '@metamask/eslint-config-typescript',

Expand Down Expand Up @@ -234,6 +265,7 @@ const config = createConfig({
// Prefer hash names over TypeScript's `private` modifier.
'no-restricted-syntax': [
'error',
...baseNoRestrictedSyntaxOptions,
{
selector:
"PropertyDefinition[accessibility='private'], MethodDefinition[accessibility='private'], TSParameterProperty[accessibility='private']",
Expand Down
Loading