@howells/lint 0.2.1 → 0.2.3

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/README.md CHANGED
@@ -103,11 +103,14 @@ Next.js app:
103
103
 
104
104
  Use this lane when a project wants Oxlint and Oxfmt instead of Biome. React and Next presets stack the relevant Ultracite Ox rules with [React Doctor](https://react.doctor) rules in one config.
105
105
 
106
+ React Doctor severities are passed through as published by React Doctor. Native Oxlint Next.js severities come from Oxlint's official `nextjs` plugin via Ultracite's Next preset. `@howells/lint` adds canonical Howells policy on top for file naming, barrel files, env access, and tests.
107
+
106
108
  Choose the closest preset:
107
109
 
108
110
  - `@howells/lint/oxlint/core` for Node or non-React TypeScript
109
111
  - `@howells/lint/oxlint/react` for React (Ultracite React + React Doctor recommended rules)
110
112
  - `@howells/lint/oxlint/next` for Next.js (react preset + Next.js rules)
113
+ - `@howells/lint/oxlint/boundaries` for monorepo import boundaries (`packages/**` cannot import from `apps/**`, and apps cannot import from other apps)
111
114
  - `@howells/lint/oxlint/react-doctor-rules` for composing or disabling React Doctor rules in mixed workspaces
112
115
 
113
116
  Node or non-React TypeScript:
@@ -143,6 +146,25 @@ export default defineConfig({
143
146
  });
144
147
  ```
145
148
 
149
+ Monorepo root or package boundary config:
150
+
151
+ ```ts
152
+ import { defineConfig } from "oxlint";
153
+ import {
154
+ boundaryJsPlugins,
155
+ boundaryRules,
156
+ boundarySettings,
157
+ } from "@howells/lint/oxlint/boundaries";
158
+
159
+ export default defineConfig({
160
+ jsPlugins: boundaryJsPlugins,
161
+ settings: boundarySettings,
162
+ rules: boundaryRules,
163
+ });
164
+ ```
165
+
166
+ Run boundary configs from the monorepo root so element patterns such as `apps/*/**` and `packages/*/**` match the project tree.
167
+
146
168
  Mixed monorepo with a Next.js app and Node-only packages:
147
169
 
148
170
  ```ts
@@ -0,0 +1,12 @@
1
+ import type { OxlintConfig } from "oxlint";
2
+
3
+ type OxlintRules = NonNullable<OxlintConfig["rules"]>;
4
+ type OxlintSettings = NonNullable<OxlintConfig["settings"]>;
5
+ type OxlintJsPlugins = NonNullable<OxlintConfig["jsPlugins"]>;
6
+
7
+ export const boundaryJsPlugins: OxlintJsPlugins;
8
+ export const boundarySettings: OxlintSettings;
9
+ export const boundaryRules: OxlintRules;
10
+
11
+ declare const config: OxlintConfig;
12
+ export default config;
@@ -0,0 +1,49 @@
1
+ import { defineConfig } from "oxlint";
2
+
3
+ export const boundaryJsPlugins = [
4
+ { name: "boundaries", specifier: "eslint-plugin-boundaries" },
5
+ ];
6
+
7
+ export const boundarySettings = {
8
+ "import/resolver": {
9
+ node: {
10
+ extensions: [".js", ".jsx", ".mjs", ".cjs", ".ts", ".tsx"],
11
+ },
12
+ typescript: {
13
+ alwaysTryTypes: true,
14
+ project: ["tsconfig.json", "apps/*/tsconfig.json", "packages/*/tsconfig.json"],
15
+ },
16
+ },
17
+ "boundaries/elements": [
18
+ { type: "app", pattern: "apps/*/**", mode: "full" },
19
+ { type: "package", pattern: "packages/*/**", mode: "full" },
20
+ ],
21
+ };
22
+
23
+ export const boundaryRules = {
24
+ "boundaries/dependencies": [
25
+ "error",
26
+ {
27
+ default: "allow",
28
+ checkUnknownLocals: true,
29
+ rules: [
30
+ {
31
+ from: { type: "package" },
32
+ disallow: [{ to: { type: "app" } }],
33
+ message: "Packages must not import from apps.",
34
+ },
35
+ {
36
+ from: { type: "app" },
37
+ disallow: [{ to: { type: "app" } }],
38
+ message: "Apps must not import from other apps.",
39
+ },
40
+ ],
41
+ },
42
+ ],
43
+ };
44
+
45
+ export default defineConfig({
46
+ jsPlugins: boundaryJsPlugins,
47
+ settings: boundarySettings,
48
+ rules: boundaryRules,
49
+ });
package/oxlint/core.mjs CHANGED
@@ -1 +1,44 @@
1
- export { default } from "ultracite/oxlint/core";
1
+ import { defineConfig } from "oxlint";
2
+ import ultraciteCore from "ultracite/oxlint/core";
3
+
4
+ export default defineConfig({
5
+ extends: [ultraciteCore],
6
+ plugins: [...new Set([...(ultraciteCore.plugins ?? []), "vitest"])],
7
+ rules: {
8
+ "no-restricted-properties": [
9
+ "error",
10
+ {
11
+ message:
12
+ "Use the project env schema instead of reading process.env directly. Env schema files may override this rule locally.",
13
+ object: "process",
14
+ property: "env",
15
+ },
16
+ ],
17
+ "oxc/no-barrel-file": [
18
+ "error",
19
+ {
20
+ threshold: 0,
21
+ },
22
+ ],
23
+ "unicorn/filename-case": [
24
+ "error",
25
+ {
26
+ cases: {
27
+ kebabCase: true,
28
+ },
29
+ },
30
+ ],
31
+ "vitest/hoisted-apis-on-top": "error",
32
+ "vitest/no-commented-out-tests": "error",
33
+ "vitest/no-conditional-tests": "error",
34
+ "vitest/no-disabled-tests": "error",
35
+ "vitest/no-focused-tests": "error",
36
+ "vitest/no-identical-title": "error",
37
+ "vitest/no-import-node-test": "error",
38
+ "vitest/no-mocks-import": "error",
39
+ "vitest/no-standalone-expect": "error",
40
+ "vitest/valid-describe-callback": "error",
41
+ "vitest/valid-expect": "error",
42
+ "vitest/valid-expect-in-promise": "error",
43
+ },
44
+ });
package/oxlint/react.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import { defineConfig } from "oxlint";
2
2
  import { RECOMMENDED_RULES } from "oxlint-plugin-react-doctor";
3
- import core from "ultracite/oxlint/core";
4
3
  import ultraciteReact from "ultracite/oxlint/react";
4
+ import core from "./core.mjs";
5
5
 
6
6
  export default defineConfig({
7
7
  extends: [core, ultraciteReact],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@howells/lint",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "description": "Pinned Biome, Oxlint/Oxfmt, Ultracite, and React Doctor presets for Howells projects.",
5
5
  "license": "MIT",
6
6
  "packageManager": "pnpm@10.23.0",
@@ -35,12 +35,15 @@
35
35
  "dependencies": {
36
36
  "@biomejs/biome": "2.4.15",
37
37
  "@manypkg/cli": "^0.25.1",
38
+ "eslint": "10.4.1",
39
+ "eslint-import-resolver-typescript": "4.4.4",
40
+ "eslint-plugin-boundaries": "6.0.2",
38
41
  "oxc-parser": "0.133.0",
39
42
  "oxfmt": "0.51.0",
40
43
  "oxlint": "1.66.0",
41
- "oxlint-plugin-react-doctor": "0.2.14",
44
+ "oxlint-plugin-react-doctor": "0.4.0",
42
45
  "oxlint-tsgolint": "0.23.0",
43
- "ultracite": "7.7.0"
46
+ "ultracite": "7.8.1"
44
47
  },
45
48
  "exports": {
46
49
  "./package.json": "./package.json",
@@ -63,6 +66,10 @@
63
66
  "types": "./oxlint/next.d.mts",
64
67
  "default": "./oxlint/next.mjs"
65
68
  },
69
+ "./oxlint/boundaries": {
70
+ "types": "./oxlint/boundaries.d.mts",
71
+ "default": "./oxlint/boundaries.mjs"
72
+ },
66
73
  "./oxlint/react-doctor-rules": {
67
74
  "types": "./oxlint/react-doctor-rules.d.mts",
68
75
  "default": "./oxlint/react-doctor-rules.mjs"