Skip to content

Add @cratis/eslint-plugin-arc#2273

Merged
einari merged 5 commits into
mainfrom
feature/shareable-eslint
Jun 4, 2026
Merged

Add @cratis/eslint-plugin-arc#2273
einari merged 5 commits into
mainfrom
feature/shareable-eslint

Conversation

@woksin

@woksin woksin commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Added

  • @cratis/eslint-plugin-arc: ESLint rules for projects that consume Cratis Arc, designed to compose on top of @cratis/eslint-config.
    • skip-generated-proxies (processor) — skips Arc-generated proxy files wholesale. They carry a // @generated by Cratis header (and a **DO NOT EDIT** banner), cannot be edited, and are regenerated by the build, so any lint finding on them is un-actionable. Keyed on the header because generated proxies sit intermixed with hand-written .ts under the same folders, with no path distinction. The pass-through preserves filenames (import resolution is unaffected) and keeps --fix working on hand-written files.
    • no-hooks-in-view-model (rule) — forbids React hook calls inside MVVM view models (classes named *ViewModel). A view model must be a plain, React-free class; inject Cratis abstractions instead of calling hooks. Only bare-identifier hook calls are flagged, so view-model methods that merely start with use are not false positives. The class suffix and hook pattern are configurable.

Notes

  • Named per the ESLint scoped-plugin convention (@scope/eslint-plugin-*). The plugin namespace is @cratis/arc, so rule IDs read @cratis/arc/no-hooks-in-view-model.
  • Ships as raw ESM (no build step), declares only eslint as a peer dependency, and exposes meta.version plus per-rule docs URLs. It owns these rules because Arc owns the proxy generator and @cratis/arc.react.mvvm.

🤖 Generated with Claude Code

Introduce @cratis/arc.eslint, ESLint rules for projects that consume Cratis Arc,
to compose on top of @cratis/eslint-config:

- skip-generated-proxies: a processor that skips Arc-generated proxy files
  wholesale. Keyed on the `// @generated by Cratis` header (with the DO NOT EDIT
  banner as a fallback) because proxies sit intermixed with hand-written .ts.
- no-hooks-in-view-model: forbids React hook calls inside MVVM view models
  (classes named *ViewModel), which must stay plain, React-free classes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@woksin woksin added the minor label Jun 4, 2026
@github-actions

github-actions Bot commented Jun 4, 2026

Copy link
Copy Markdown

NuGet packages for this PR, e.g. Cratis.Arc:
https://github.com/cratis/arc/packages/1655206?version=20.33.13

Expose name + version on the plugin meta (cache keys, --print-config) and a
docs URL on no-hooks-in-view-model so IDEs render a clickable link.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jun 4, 2026

Copy link
Copy Markdown

NuGet packages for this PR, e.g. Cratis.Arc:
https://github.com/cratis/arc/packages/1655206?version=20.33.14

Follow the ESLint scoped-plugin naming convention (@scope/eslint-plugin-*) so
the package reads as an ESLint plugin to consumers. The plugin namespace stays
@cratis/arc, so rule IDs (@cratis/arc/no-hooks-in-view-model) are unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@woksin woksin changed the title Add @cratis/arc.eslint Add @cratis/eslint-plugin-arc Jun 4, 2026
@github-actions

github-actions Bot commented Jun 4, 2026

Copy link
Copy Markdown

NuGet packages for this PR, e.g. Cratis.Arc:
https://github.com/cratis/arc/packages/1655206?version=20.33.15

@woksin woksin requested a review from einari June 4, 2026 13:38
woksin and others added 2 commits June 4, 2026 15:44
Make the default export the plugin object itself (meta + rules + processors +
self-referencing configs), per the ESLint flat-config plugin convention, so
consumers get arc.meta/arc.rules/arc.configs directly. Name every config block.
Fold recommended.js into index.js.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Previously the first failed 'npm publish' called process.exit(1), aborting the
release and stranding every workspace after it. A brand-new package whose npm
trusted publisher isn't configured yet would therefore also block the existing
packages from releasing. Collect publish failures, keep publishing the rest, and
exit non-zero at the end with a summary. Build/test tasks stay fail-fast.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@woksin

woksin commented Jun 4, 2026

Copy link
Copy Markdown
Contributor Author

⚠️ One-time first-publish bootstrap (before this releases cleanly)

This PR adds a brand-new npm package@cratis/eslint-plugin-arc. The Publish workflow uses npm trusted publishing (OIDC) (it strips the auth token), which requires a trusted-publisher relationship that must already exist on the package. That can't be configured before the package exists, so the package's first publish over OIDC will fail.

One-time bootstrap (do before merge, or after — the companion resilience commit means an un-bootstrapped package no longer blocks the others):

  • Initial token-based publish to create the package, authenticated to npm with publish rights to @cratis:
    cd Source/JavaScript/Arc.ESLint
    npm publish --access public
    (or run with a granular NODE_AUTH_TOKEN). publishConfig.access: public is already set.
  • Configure the trusted publisher: npmjs.com → @cratis/eslint-plugin-arcSettings → Trusted Publisher → repository Cratis/Arc, workflow .github/workflows/publish.yml.
  • Verify the next Publish run publishes over OIDC with no token.

Heads-up — co-versioning: publish-version sets every workspace to the repo release version, so on the first automated release this package jumps to ~20.x (matching @cratis/arc), not 0.x/1.0.0. Starting it independently would need a release-pipeline change.

🤖 Generated with Claude Code

@woksin

woksin commented Jun 4, 2026

Copy link
Copy Markdown
Contributor Author

@einari — two one-time steps before merging this. This is 1 of 3 coordinated PRs: Fundamentals Cratis/Fundamentals#1072, Arc #2273, Components Cratis/Components#95.

1. Bootstrap @cratis/eslint-plugin-arc on npm (one-time)

The Publish workflow uses OIDC trusted publishing, which can't create a package that doesn't exist yet — so the first publish has to be done by hand. From a checkout of this branch, authenticated to npm with publish rights to @cratis:

cd Source/JavaScript/Arc.ESLint
npm publish --access public

Then on npmjs.com → @cratis/eslint-plugin-arcSettings → Trusted Publisher: repository Cratis/Arc, workflow .github/workflows/publish.yml. (publishConfig.access: public is already set; the throwaway 0.0.0 gets superseded by the real version on the first automated release.)

2. Merge with the minor label (already applied)

Merging triggers the Publish workflow, which co-versions and releases every workspace over OIDC — including the now-bootstrapped package.

Order: bootstrap → merge for a fully-green first release. Merging before bootstrapping is safe too — the resilience commit means this new package failing to publish no longer blocks @cratis/arc or the other workspaces; it just won't publish until bootstrapped.

Versioning note: co-versioning makes this plugin debut at ~20.x (the repo version), not 1.0.0. Say the word if you want it versioned independently and we'll adjust the pipeline first.

🤖 Generated with Claude Code

@github-actions

github-actions Bot commented Jun 4, 2026

Copy link
Copy Markdown

NuGet packages for this PR, e.g. Cratis.Arc:
https://github.com/cratis/arc/packages/1655206?version=20.33.19

@einari einari merged commit 571235c into main Jun 4, 2026
10 checks passed
@einari einari deleted the feature/shareable-eslint branch June 4, 2026 17:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants