Skip to content

build: lint for WebKit 15.4 with eslint-plugin-compat - #8212

Merged
ashishjain0512 merged 3 commits into
release/12.0.0from
build/add-eslint-plugin-compat
Sep 4, 2026
Merged

ashishjain0512 merged 3 commits into
release/12.0.0from
build/add-eslint-plugin-compat

Conversation

@aloisklink

Copy link
Copy Markdown
Member

📑 Summary

Note

This PR targets the release/12.0.0 branch since that has already branched off of develop.

Lint the code that ships in the bundles (packages/*/src), with compat/compat.

📏 Design Decisions

Safari 15.4 is the floor that we're not officially supporting in Mermaid v11 (hence why it's not documented anywhere), but is one we're trying to support as a rough guideline.

📋 Tasks

Make sure you

  • 📖 have read the contribution guidelines
  • 💻 have added necessary unit/e2e tests.
  • 📓 have added documentation. Make sure MERMAID_RELEASE_VERSION is used for all new features.
  • 🦋 If your PR makes a change that should be noted in one or more packages' changelogs, generate a changeset by running pnpm changeset and following the prompts. Changesets that add features should be minor and those that fix bugs should be patch. Please prefix changeset messages with feat:, fix:, or chore:.

Lint the code that ships in the bundles (`packages/*/src`), with `compat/compat`.

Safari 15.4 is the floor that we're not officially supporting in Mermaid
v11, but is one we're trying to support as a rough guideline.
@changeset-bot

changeset-bot Bot commented Sep 4, 2026 •

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: b0ccaf8

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai

coderabbitai Bot commented Sep 4, 2026 •

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Team

Run ID: f76a21d4-d758-4a0f-b2f4-d583eb8264f0

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Sep 4, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 80.16%. Comparing base (fe0e237) to head (b0ccaf8).
⚠️ Report is 13 commits behind head on release/12.0.0.

Additional details and impacted files

Impacted file tree graph

@@                Coverage Diff                 @@
##           release/12.0.0    #8212      +/-   ##
==================================================
+ Coverage           80.13%   80.16%   +0.02%     
==================================================
  Files                 624      624              
  Lines               85311    85411     +100     
  Branches            16183    16103      -80     
==================================================
+ Hits                68366    68471     +105     
+ Misses              15909    15906       -3     
+ Partials             1036     1034       -2     
Flag Coverage Δ
e2e 73.69% <ø> (-0.21%) ⬇️
unit 77.93% <ø> (+0.03%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.
see 18 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

…slint-plugin-compat

Fixes the failing unit tests.
@argos-ci

argos-ci Bot commented Sep 4, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Argos notifications ↗︎

Build Status Details Updated (UTC)
default (Inspect) 👍 Approved by Ashish Jain 5 changed, 171 ignored Sep 4, 2026, 2:05 PM

@ashishjain0512 ashishjain0512 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[sisyphus-bot]

Nice, tightly-scoped change — a machine-checked support floor beats a tribal-knowledge one, and it's a good sign that zero source changes were needed to land it at safari >= 15.4.

I checked out the PR head (4cd8a1d), installed from the lockfile, and verified the mechanism rather than just reading the diff. Notes below.

What's working well

🎉 The target genuinely resolves. The one thing I wanted to disprove was a silent fallback to browserslist defaults, since packages/mermaid/package.json has no browserslist field of its own and eslint-plugin-compat resolves from the linted file's path (browserslistDir = context.filename, then browserslist(undefined, { path })). findConfig() walks straight past the package-level package.json and lands on the root one:

findConfig(packages/mermaid/src/mermaid.ts) -> {"defaults":["safari >= 15.4"]}
floor of resolved targets                   -> safari 15.4

And end to end, on a scratch file under packages/mermaid/src:

error  Array.toSorted() is not supported in Safari 15.4  compat/compat

with structuredClone() (Safari 15.4) correctly not flagged. So the rule is live and calibrated to the right floor.

🎉 The files/ignores scoping does what the comment says. Via eslint --print-config:

file compat/compat
packages/mermaid/src/mermaid.ts on
packages/mermaid/src/diagrams/class/styles.js on
packages/mermaid/src/diagrams/treemap/utils.spec.ts off
packages/mermaid/src/docs/.vitepress/canonical-config.ts off

🎉 Generated code is already out of scope — the global ignores block (eslint.config.js:19-29) covers **/generated/ and packages/mermaid/src/config.type.ts, so the Langium output can't start failing a rule whose fix would have to live in a generator.

🎉 lintAllEsApis: true won't be silently undone. v7 computes it as settings.lintAllEsApis === true || (!polyfills.includes('es:all') && !isUsingTranspiler(file)), and isUsingTranspiler find-ups for a babel config / babel key — of which there are none here. The explicit true short-circuits it either way. Good call setting it, since lintAllEsApis is the half that catches toSorted at all.

🎉 Clean dependency footprint — devDependencies only, nothing under packages/*/src imports it, none of the four new packages has a pre/post-install script, and the lockfile diff is +42/−0 with no existing resolution touched (so dompurify and friends are provably unchanged).

Things to address

🟡 [important] The rule's API knowledge is ~2 years stale, so green lint isn't a guarantee. From the same scratch file, these were not flagged:

Object.groupBy([1, 2, 3], (n) => String(n % 2)); // Safari 17.4
Promise.withResolvers();                          // Safari 17.4

while toSorted (Safari 16.4) was. The cause looks like the dependency split visible in the lockfile: the plugin ships @mdn/browser-compat-data@6.1.5, but ast-metadata-inferer@0.8.1 — which generates the AST metadata that decides what the rule can even recognise — pins @mdn/browser-compat-data@5.7.6. Anything added to BCD after 5.7.6 is invisible to compat/compat.

Worth noting explicitly (in the PR body, or as a line in the eslint.config.js comment) that this is a best-effort net rather than a gate — otherwise the next person reads a passing lint as proof. Related: the weekly Update Browserslist workflow refreshes caniuse-lite, which affects how safari >= 15.4 expands but not what APIs the rule knows about; keeping that current means bumping the plugin.

🟢 [nit] **/*.test.ts isn't ignored — eslint.config.js:169 ignores **/*.spec.{ts,js} only, so five files that never ship are now linted against the browser floor:

  • packages/mermaid-layout-tidy-tree/src/layout.test.ts
  • packages/mermaid/src/diagrams/mindmap/mindmapDb.getData.test.ts
  • packages/mermaid/src/diagrams/treemap/utils.test.ts
  • packages/mermaid/src/rendering-util/layout-algorithms/cose-bilkent/cytoscape-setup.test.ts
  • packages/mermaid/src/rendering-util/layout-algorithms/cose-bilkent/layout.test.ts

Harmless today (nothing in them trips the rule), but it's a latent false positive for whoever reaches for toSorted in a Vitest-only file. '**/*.{spec,test}.{ts,js}' covers both. The rest of the config has the same *.spec.*-only assumption (:250, :257), so this is a pre-existing habit rather than something you introduced — it just bites harder here, where the rule is specifically about shipped code.

🟢 [nit] Two of the four ignore entries are inert. **/vitepress/** doesn't match the directory, which is .vitepress (a literal path segment has to match exactly — the leading dot matters), and **/scripts/** only ever had packages/mermaid/src/docs/.vitepress/scripts/ to match, which **/docs/** already covers. Confirmed by the print-config table above: .vitepress/canonical-config.ts is excluded by **/docs/**, not by the pattern that looks like it's doing the work. ignores: ['**/*.{spec,test}.{ts,js}', '**/docs/**'] is the honest version.

Suggestions / questions

💡 The syntax half of the floor is still unenforced. compat/compat checks API availability; nothing checks emitted syntax. .esbuild/util.ts sets no target, so the shipped bundles are built at esbuild's default (esnext) — meanwhile the dev server hardcodes target: 'es2020' (.esbuild/server.ts:240) and the docs build already pins target: 'modules' with a comment about Vite 7 moving its default (packages/mermaid/src/docs/vite.config.ts:21-22). Three different notions of "old enough", now with a fourth (browserslist) that only lint reads. Deriving the esbuild target from the same browserslist field would make the floor mean one thing. Also out of reach either way: bundled dependencies (d3, dagre, …) aren't linted, so their API use isn't held to 15.4. Both feel like follow-ups rather than this PR's job — happy for this to land as-is.

💡 Since this targets release/12.0.0, is the plan to pick this up on develop via the eventual forward-merge, or would a matching PR there be worth it so the rule doesn't quietly vanish from v12+ development in the meantime?

Security

No XSS or injection issues identified. No source files are touched, so there's no DOM sink, SVG emission, or DOMPurify call site in scope. I did check the one plausible indirect path — a new root browserslist field silently retargeting a transpiler and changing shipped output — and it's a non-issue: there is no autoprefixer, postcss, @babel/preset-env, or @vitejs/plugin-legacy anywhere in the repo, no .browserslistrc, and no package-level browserslist, so the field is read by eslint-plugin-compat at lint time and nothing else. Bundled output is unchanged.

Verdict: comment only, nothing blocking. The two nits are one-liners in eslint.config.js:169; the 🟡 is a documentation ask, not a code change.

`**/vitepress/**` and `**/scripts/**` are unnecessary, since the only
thing they affect are in `packages/mermaid/src/docs`, which `**/docs/**`
already handles.

I've also ignored `**/__mocks__/**` since that is currently included,
but is only needed for vitest.
@aloisklink

Copy link
Copy Markdown
Member Author

🟡 [important] The rule's API knowledge is ~2 years stale, so green lint isn't a guarantee.

These are caught by TypeScript on .ts files. And I have another PR open that will check these for .js files: #7426, so I think we can ignore this for this PR.

🟢 [nit] **/*.test.ts isn't ignored

I think it's better to fix this in a separate PR by renaming all these test files to .spec., since we have other globs that rely on all tests being called .spec.

🟢 [nit] Two of the four ignore entries are inert.

Fixed in b0ccaf8

💡 The syntax half of the floor is still unenforced.

TypeScript enforces most of this. #8213 will update ESBuild. And I'm working on a PR that will add a Safari 17.4 E2E test.

💡 Since this targets release/12.0.0, is the plan to pick this up on develop via the eventual forward-merge, or would a matching PR there be worth it so the rule doesn't quietly vanish from v12+ development in the meantime?

I'll leave this up to @ashishjain0512 to decide, but we'll probably merge release/12.0.0 to master then to develop soon.

@ashishjain0512
ashishjain0512 merged commit 92876e3 into release/12.0.0 Sep 4, 2026
26 of 27 checks passed
@ashishjain0512
ashishjain0512 deleted the build/add-eslint-plugin-compat branch September 4, 2026 14:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants