@starci/eslint-canon-fe 6.0.1 → 6.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## 6.0.2 - 2026-09-30
4
+
5
+ - **Fix: `use-client-only-at-boundary` refused the providers wrapper.** The route tree's `providers.tsx` (root or `[locale]`,
6
+ role `providers` of `fe.route` in the slot manifest) is the client component a server layout renders around its children to host
7
+ context providers; the directive is accepted there. A providers wrapper kept elsewhere (a layout feature, a module) is still a
8
+ finding, and the message names `providers.tsx` as its home.
9
+
3
10
  ## 6.0.1 - 2026-09-30
4
11
 
5
12
  - **Fix: `no-hand-rolled-polling` refused a shared clock.** A timer is polling only when what it runs reads data - a call whose
@@ -20,7 +20,8 @@ import { classifyImport, fileOf, isProductSource, isSpecFile, kindOfFile, roleOf
20
20
  import { typed } from "./lib/types.mjs"
21
21
 
22
22
  /** The route roles that are client-only by the framework's own rule: `error` and `global-error`. */
23
- const FRAMEWORK_CLIENT_ROLES = new Set(["error", "global-error"])
23
+ /** Route-tree roles that are client components by construction: the error boundaries, and the providers wrapper a layout renders. */
24
+ const FRAMEWORK_CLIENT_ROLES = new Set(["error", "global-error", "providers"])
24
25
 
25
26
  /** True when the program opens with the `"use client"` directive. */
26
27
  const clientDirective = (program) =>
@@ -58,9 +59,9 @@ export const useClientOnlyAtBoundary = {
58
59
  schema: [],
59
60
  messages: {
60
61
  slot:
61
- "`\"use client\"` on a {{slot}}. Routes, pages and layouts are server components: making one a client component ships its whole subtree, including the message catalog, to every reader and stops it reading data on the server. Move the interaction into a block below it and put the directive on that block's `index.tsx`.",
62
+ "`\"use client\"` on a {{slot}}. Routes, pages and layouts are server components: making one a client component ships its whole subtree, including the message catalog, to every reader and stops it reading data on the server. Move the interaction into a block below it and put the directive on that block's `index.tsx`; context providers go in the route tree's `providers.tsx`.",
62
63
  elsewhere:
63
- "`\"use client\"` here is not at an interaction boundary. The directive belongs on the `index.tsx` of the interactive block (or overlay), on a leaf whose interaction is intrinsic, or on `error.tsx`/`global-error.tsx`. Below a client block the file is already client; above one it must stay a server component.",
64
+ "`\"use client\"` here is not at an interaction boundary. The directive belongs on the `index.tsx` of the interactive block (or overlay), on a leaf whose interaction is intrinsic, on `error.tsx`/`global-error.tsx`, or on the route tree's `providers.tsx` (the context providers a layout renders around its children). Below a client block the file is already client; above one it must stay a server component.",
64
65
  },
65
66
  },
66
67
  create(context) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@starci/eslint-canon-fe",
3
- "version": "6.0.1",
3
+ "version": "6.0.2",
4
4
  "description": "The StarCi front-end lint canon: every rule its laws publish, gathered as one flat-config plugin and attached by one factory.",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",
@@ -662,7 +662,7 @@ slots:
662
662
  presence: optional
663
663
  tracked: tracked
664
664
  tier: inherit
665
- requires: [connection.ts] # CONNECTION = <CONN>_CONNECTION of an hfs.json connection, and the capability's <c>Entities / <c>Migrations arrays (the owner index re-exports the two arrays by name)
665
+ requires: [connection.ts] # the capability's <c>Entities / <c>Migrations arrays (the owner index re-exports the two arrays by name); no CONNECTION alias: the connection is the one the apps register the arrays on
666
666
  allows: ["entities/<table>.entity.ts", "migrations/<epochMs13>-<kebab-name>.ts", "<name>.sql.ts", "<name>.rows.ts", connection.ts, "*.spec.ts"]
667
667
  forbids: [index.ts, "<name>.repository.ts"]
668
668
  tests: unit-beside
@@ -838,7 +838,8 @@ slots:
838
838
  not-found.tsx, layout.tsx, # next-intl: a request outside every locale renders the root not-found inside a root layout
839
839
  "health/{live,ready}/route.ts", "api/**/route.ts", "_*/**", providers.tsx, globals.css,
840
840
  "{icon,favicon,apple-icon,opengraph-image,twitter-image}.*", robots.ts, sitemap.ts, manifest.ts, "**/*.spec.ts", "**/*.spec.tsx"]
841
- roles: {page: page.tsx, layout: layout.tsx, template: template.tsx, loading: loading.tsx, error: error.tsx, not-found: not-found.tsx, default: default.tsx, route: route.ts, global-error: global-error.tsx}
841
+ # providers.tsx (root or [locale]) is the client wrapper the server layout renders around its children to host context providers.
842
+ roles: {page: page.tsx, layout: layout.tsx, template: template.tsx, loading: loading.tsx, error: error.tsx, not-found: not-found.tsx, default: default.tsx, route: route.ts, global-error: global-error.tsx, providers: providers.tsx}
842
843
  tests: none
843
844
  rules: [FE_ROUTE_FILES_THIN, FE_CLIENT_BOUNDARY, FE_OWNER_REACHABLE]
844
845
  - id: fe.source-root-pinned