@lewishowles/lint-config 0.1.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.
Files changed (4) hide show
  1. package/README.md +109 -0
  2. package/base.json +55 -0
  3. package/package.json +47 -0
  4. package/vue.json +30 -0
package/README.md ADDED
@@ -0,0 +1,109 @@
1
+ # @lewishowles/lint-config
2
+
3
+ Shared oxlint configuration for Lewis Howles projects. One package that every repo extends, so lint setup stops being duplicated and drifting across the ecosystem.
4
+
5
+ ## Installation
6
+
7
+ ```sh
8
+ bun add -d @lewishowles/lint-config @stylistic/eslint-plugin vite-plus
9
+ ```
10
+
11
+ `@stylistic/eslint-plugin` and `vite-plus` are peer dependencies — they must be installed in the consuming project so oxlint can resolve the JS plugins from `node_modules`.
12
+
13
+ ## Usage
14
+
15
+ Create a `.oxlintrc.json` in your project root that extends the appropriate layer:
16
+
17
+ ### Base layer (all JS/TS projects)
18
+
19
+ ```json
20
+ {
21
+ "extends": ["./node_modules/@lewishowles/lint-config/base.json"],
22
+ "ignorePatterns": ["**/dist/*", ".codebase-memory/**"]
23
+ }
24
+ ```
25
+
26
+ ### Vue layer (Vue 3 projects)
27
+
28
+ ```json
29
+ {
30
+ "extends": ["./node_modules/@lewishowles/lint-config/vue.json"],
31
+ "ignorePatterns": ["**/dist/*", ".codebase-memory/**"]
32
+ }
33
+ ```
34
+
35
+ The Vue layer extends `base.json` internally — you only need to extend `vue.json`.
36
+
37
+ ## Customising
38
+
39
+ Your `.oxlintrc.json` stub can override rules, add ignore patterns, add overrides, or add plugins on top of the shared layer.
40
+
41
+ ### Overriding a rule
42
+
43
+ To change the severity or options of a rule defined in the shared layer, redeclare it in your stub — your value wins:
44
+
45
+ ```json
46
+ {
47
+ "extends": ["./node_modules/@lewishowles/lint-config/base.json"],
48
+ "rules": {
49
+ "no-unused-vars": "warn"
50
+ }
51
+ }
52
+ ```
53
+
54
+ ### Adding ignore patterns
55
+
56
+ Ignore patterns are repo-specific, so they always live in your stub:
57
+
58
+ ```json
59
+ {
60
+ "extends": ["./node_modules/@lewishowles/lint-config/base.json"],
61
+ "ignorePatterns": ["**/dist/*", ".codebase-memory/**", "support/**"]
62
+ }
63
+ ```
64
+
65
+ ### Adding overrides
66
+
67
+ Overrides are additive — shared overrides (if any) still apply, and your local ones are appended:
68
+
69
+ ```json
70
+ {
71
+ "extends": ["./node_modules/@lewishowles/lint-config/base.json"],
72
+ "overrides": [
73
+ {
74
+ "files": ["bin/**/*.js", "src/cli/**/*.js"],
75
+ "env": { "node": true }
76
+ },
77
+ {
78
+ "files": ["**/*.test.js"],
79
+ "rules": { "no-unused-vars": "off" }
80
+ }
81
+ ]
82
+ }
83
+ ```
84
+
85
+ ### Adding plugins
86
+
87
+ Plugins are additive and deduplicated — your local plugins are added to the shared ones. Note that oxlint only supports its built-in plugin names (`oxc`, `typescript`, `unicorn`, `vue`, etc.) — there is no `playwright` or `vitest` plugin. Test-file-specific behaviour is handled via `overrides`, not plugins.
88
+
89
+ ## Layers
90
+
91
+ | Layer | File | Contents |
92
+ |-------|------|----------|
93
+ | `base` | `base.json` | Correctness rules, `@stylistic` formatting rules, `vite-plus/prefer-vite-plus-imports`, `oxc` + `typescript` + `unicorn` plugins, browser env, node env for config files (`vite.config.*`, `vitest.config.*`, `playwright*.config.*`) |
94
+ | `vue` | `vue.json` | Extends `base`. Adds `vue` plugin, Vue compiler macros as globals, Vue-specific rules |
95
+
96
+ ## What stays repo-local
97
+
98
+ - `ignorePatterns` — every repo has different build output and tool directories
99
+ - `overrides` for repo-specific directories (e.g. `bin/**/*.js`, `src/cli/**/*.js`, `src/playwright/**/*.js`) — the file paths differ per repo, so they can't be generalised
100
+ - Test-file rule relaxations (e.g. turning off `vite-plus/prefer-vite-plus-imports` in `*.d.ts`)
101
+ - Additional plugins — only repos that need them
102
+
103
+ ## Merge semantics
104
+
105
+ When a consumer stub adds its own `rules` or `overrides` on top of a shared layer:
106
+
107
+ - **Rules** shallow-merge by key — the consumer's value wins for any rule defined in both
108
+ - **Overrides** are additive — both shared and local overrides apply
109
+ - **Plugins** are additive — both shared and local plugins are loaded (deduplicated)
package/base.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "plugins": ["oxc", "typescript", "unicorn"],
3
+ "jsPlugins": [
4
+ "@stylistic/eslint-plugin",
5
+ {
6
+ "name": "vite-plus",
7
+ "specifier": "vite-plus/oxlint-plugin"
8
+ }
9
+ ],
10
+ "categories": {
11
+ "correctness": "error"
12
+ },
13
+ "env": {
14
+ "builtin": true,
15
+ "browser": true
16
+ },
17
+ "rules": {
18
+ "no-case-declarations": "error",
19
+ "no-empty": "error",
20
+ "no-fallthrough": "error",
21
+ "no-prototype-builtins": "error",
22
+ "no-redeclare": "error",
23
+ "no-regex-spaces": "error",
24
+ "no-undef": "error",
25
+ "no-unexpected-multiline": "error",
26
+ "no-useless-assignment": "error",
27
+ "preserve-caught-error": "error",
28
+
29
+ "@stylistic/no-confusing-arrow": "error",
30
+ "@stylistic/padding-line-between-statements": [
31
+ "error",
32
+ { "blankLine": "always", "prev": "const", "next": "let" },
33
+ { "blankLine": "always", "prev": "let", "next": "const" },
34
+ { "blankLine": "always", "prev": "*", "next": "break" },
35
+ { "blankLine": "always", "prev": ["const", "let"], "next": "*" },
36
+ { "blankLine": "always", "prev": "*", "next": "return" },
37
+ { "blankLine": "any", "prev": "const", "next": "const" },
38
+ { "blankLine": "any", "prev": "let", "next": "let" },
39
+ { "blankLine": "always", "prev": "multiline-const", "next": "*" },
40
+ { "blankLine": "always", "prev": "*", "next": "multiline-const" }
41
+ ],
42
+
43
+ "vite-plus/prefer-vite-plus-imports": "error"
44
+ },
45
+ "overrides": [
46
+ {
47
+ "files": ["vite.config.*", "vitest.config.*", "playwright*.config.*"],
48
+ "env": { "node": true }
49
+ }
50
+ ],
51
+ "options": {
52
+ "typeAware": false,
53
+ "typeCheck": false
54
+ }
55
+ }
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "@lewishowles/lint-config",
3
+ "version": "0.1.0",
4
+ "description": "Shared oxlint configuration for Lewis Howles projects",
5
+ "keywords": [
6
+ "lint",
7
+ "oxlint",
8
+ "config",
9
+ "shared",
10
+ "eslint",
11
+ "stylistic"
12
+ ],
13
+ "homepage": "https://github.com/lewishowles/lint-config#readme",
14
+ "bugs": "https://github.com/lewishowles/lint-config/issues",
15
+ "license": "MIT",
16
+ "author": "Lewis Howles",
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "git+https://github.com/lewishowles/lint-config.git"
20
+ },
21
+ "type": "module",
22
+ "exports": {
23
+ "./base.json": "./base.json",
24
+ "./vue.json": "./vue.json"
25
+ },
26
+ "files": [
27
+ "base.json",
28
+ "vue.json",
29
+ "README.md"
30
+ ],
31
+ "peerDependencies": {
32
+ "@stylistic/eslint-plugin": "*",
33
+ "vite-plus": "*"
34
+ },
35
+ "devDependencies": {
36
+ "publint": "^0.3.21"
37
+ },
38
+ "scripts": {
39
+ "publint": "publint"
40
+ },
41
+ "publishConfig": {
42
+ "access": "public"
43
+ },
44
+ "engines": {
45
+ "node": ">=20"
46
+ }
47
+ }
package/vue.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "extends": ["./base.json"],
3
+ "plugins": ["vue"],
4
+ "globals": {
5
+ "defineEmits": "readonly",
6
+ "defineExpose": "readonly",
7
+ "defineModel": "readonly",
8
+ "defineOptions": "readonly",
9
+ "defineProps": "readonly",
10
+ "defineSlots": "readonly",
11
+ "withDefaults": "readonly"
12
+ },
13
+ "rules": {
14
+ "vue/no-arrow-functions-in-watch": "error",
15
+ "vue/no-deprecated-data-object-declaration": "error",
16
+ "vue/no-deprecated-delete-set": "error",
17
+ "vue/no-deprecated-destroyed-lifecycle": "error",
18
+ "vue/no-deprecated-events-api": "error",
19
+ "vue/no-deprecated-model-definition": "error",
20
+ "vue/no-deprecated-vue-config-keycodes": "error",
21
+ "vue/no-export-in-script-setup": "error",
22
+ "vue/no-lifecycle-after-await": "error",
23
+ "vue/prefer-import-from-vue": "error",
24
+ "vue/return-in-computed-property": "error",
25
+ "vue/valid-define-emits": "error",
26
+ "vue/valid-define-props": "error",
27
+ "vue/no-multiple-slot-args": "warn",
28
+ "vue/no-required-prop-with-default": "warn"
29
+ }
30
+ }