@terpjs/eslint-boundaries 0.5.9 → 0.6.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@terpjs/eslint-boundaries",
3
- "version": "0.5.9",
3
+ "version": "0.6.0",
4
4
  "type": "module",
5
5
  "description": "Terp frontend boundary rules (as data) + the ESLint adapter: no cross-module imports, no package internals, design-token-only styling (no style/className/module stylesheets), token-styled components for raw HTML tags, router-only in-app links, generated-client-only, and browser XSS/navigation sink bans. Strict-only (no modes); governed opt-outs via terp-allow markers + the escape-hatch budget ratchet (terp-boundaries-budget).",
6
6
  "main": "./src/index.js",
@@ -25,7 +25,7 @@
25
25
  "typescript-eslint": "^8.20.0"
26
26
  },
27
27
  "devDependencies": {
28
- "@terpjs/spec": "0.22.0",
28
+ "@terpjs/spec": "0.23.0",
29
29
  "eslint": "^10.8.0",
30
30
  "vitest": "^4.1.9"
31
31
  },
package/src/layouts.js CHANGED
@@ -12,6 +12,10 @@
12
12
  * Both halves phrase the SAME agent-directive message (see {@link slotViolationMessage}),
13
13
  * so a failing check *tells the author how to build the screen*, wherever it fires.
14
14
  *
15
+ * Both halves govern the slot's DIRECT children only: an allowed container's own
16
+ * subtree (a Card's body, a Stack's rows) is the app's to compose — nesting content
17
+ * inside an allowed component is sanctioned composition, not an escape hatch.
18
+ *
15
19
  * Contracts are opt-in and backwards compatible: no checked-in `layout-contract.json`
16
20
  * (and no `layoutContract` option at runtime) means today's behavior. The react-core
17
21
  * runtime carries a TypeScript mirror of this table (src/layoutContract.ts); a parity
@@ -32,8 +36,9 @@ export const LAYOUT_CONTRACTS = {
32
36
  "The standard three-level shape: hub bodies are card grids (HubCard only), " +
33
37
  "overview bodies are data collections (DataView / ResourceList + framework " +
34
38
  "states), detail bodies are record sections (DetailList / Stack / Tabs + " +
35
- "framework states). A bespoke screen composes the plain Page, which the " +
36
- "contract deliberately leaves unconstrained.",
39
+ "framework states); Card is allowed in overview and detail bodies as the " +
40
+ "sanctioned visual separation between sections. A bespoke screen composes " +
41
+ "the plain Page, which the contract deliberately leaves unconstrained.",
37
42
  slots: {
38
43
  HubPage: {
39
44
  components: { HubCard: "hubcard" },
@@ -44,6 +49,7 @@ export const LAYOUT_CONTRACTS = {
44
49
  ResourceList: "resource-list",
45
50
  ModuleNav: "module-nav",
46
51
  Stack: "stack",
52
+ Card: "card",
47
53
  EmptyState: "empty-state",
48
54
  ErrorState: "error-state",
49
55
  LoadingState: "loading-state",
@@ -58,6 +64,7 @@ export const LAYOUT_CONTRACTS = {
58
64
  Tabs: "tabs",
59
65
  ModuleNav: "module-nav",
60
66
  DataView: "dataview",
67
+ Card: "card",
61
68
  EmptyState: "empty-state",
62
69
  ErrorState: "error-state",
63
70
  LoadingState: "loading-state",
@@ -50,10 +50,10 @@ describe("terp/layout-contract", () => {
50
50
 
51
51
  it("passes a conforming hub / overview / detail composition", async () => {
52
52
  const code = [
53
- 'import { DataView, DetailList, HubCard, HubPage, OverviewPage, DetailPage, Stack } from "@terpjs/react-core";',
53
+ 'import { Card, DataView, DetailList, HubCard, HubPage, OverviewPage, DetailPage, Stack } from "@terpjs/react-core";',
54
54
  "export const H = () => <HubPage title='x'><HubCard to='/a' title='a' /></HubPage>;",
55
- "export const O = () => <OverviewPage title='x'><DataView /></OverviewPage>;",
56
- "export const D = () => <DetailPage title='x' parents={[]}><Stack><DetailList items={[]} /></Stack></DetailPage>;",
55
+ "export const O = () => <OverviewPage title='x'><Card title='open'><DataView /></Card></OverviewPage>;",
56
+ "export const D = () => <DetailPage title='x' parents={[]}><Card title='a section'>body</Card><Stack><DetailList items={[]} /></Stack></DetailPage>;",
57
57
  ].join("\n");
58
58
  expect((await lint(code, configWithContract("standard"))).map((m) => m.ruleId)).toEqual([]);
59
59
  });
package/src/spec.js CHANGED
@@ -15,7 +15,7 @@
15
15
  * NOT by this package's own suite, which certification runs against candidate spec releases
16
16
  * whose version is allowed to be newer).
17
17
  */
18
- export const SPEC_VERSION = "0.22.0";
18
+ export const SPEC_VERSION = "0.23.0";
19
19
 
20
20
  export const BOUNDARY_SPEC = {
21
21
  /** App module files the boundary + frontend security defaults apply to. */