equinor / equinor/fusion-framework

Support extension-alternation syntax in lint rule basename patterns (e.g. *.stories.{ts,tsx})

Open
#5,183 0 comments 0 reactions 0 assignees View on GitHub
✨ improvement 🤷 question
Dominant language
TypeScript
Stars
10
Forks
10
Avg merge
19h 40m
Merged PRs (30d)
150

Description

**Is your feature request related to a problem? Please describe.**

`matchesBasenamePattern` (used for rule `excludePattern`/`includePattern` config, e.g.
`single-export-per-file`, `filename-convention`) only supports a single `*` wildcard in
basename patterns. There's no way to match a set of related extensions/suffixes without
listing every variant out.

Example: excluding Storybook story files from `single-export-per-file` requires:

```yaml
rules:
single-export-per-file:
excludePattern:
- "*.stories.ts"
- "*.stories.tsx"
```

This gets noisy fast for rules with many suffix variants (see fusion-framework's own
`fusion-lint.config.json`, which lists 14 separate `excludePattern` entries for
`single-export-per-file` and 20 for `filename-convention`, several of which are just
`.ts`/`.tsx` pairs of the same basename).

**Describe the solution you'd like**

Support a standard extension-alternation glob syntax in basename patterns, e.g. one of:

- Brace expansion: `*.stories.{ts,tsx}`
- POSIX-style bracket alternation: `*.stories.[t][s][x]?` (less preferred, harder to read)
- Regex-lite suffix optionality: `*.stories.ts?(x)`

Brace expansion (`{a,b}`) is the most broadly recognized convention (shell globbing,
`fast-glob`, etc.) and would let a single entry replace `.ts`/`.tsx` (and `.js`/`.jsx`) pairs
throughout existing configs.

**Describe alternatives you've considered**

- Listing every extension variant explicitly (current behavior) — works, but is repetitive
and easy to miss a variant when adding a new file extension convention later.
- A full glob/regex engine — more powerful than needed and adds parsing complexity/surface
area for a config value that's currently a simple, fast basename check.

**Additional context**

Relevant source: `packages/linting/core/src/create-matcher.ts` /
`packages/linting/core/src/matches-basename-pattern.ts`. Docs for `MatcherFn`/`createMatcher`
explicitly call out "only `*` is supported" today.

Contributor guide

Open the contributing guide

Research direction

Start with packages/linting/core/src/matches-basename-pattern.ts and packages/linting/core/src/create-matcher.ts, then read the MatcherFn/createMatcher documentation that says only `*` is supported. Trace the existing basename matching behavior and decide how the requested brace syntax should be handled alongside current patterns. Done means extension alternation works for examples such as `*.stories.{ts,tsx}` without breaking existing matching behavior, with relevant tests and documentation updated.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
tooling
Issue type
Feature
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
64/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.