@lewishowles/lint-config 0.1.0 → 0.1.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.
Files changed (3) hide show
  1. package/README.md +34 -6
  2. package/base.json +51 -51
  3. package/package.json +15 -15
package/README.md CHANGED
@@ -88,10 +88,10 @@ Plugins are additive and deduplicated — your local plugins are added to the sh
88
88
 
89
89
  ## Layers
90
90
 
91
- | Layer | File | Contents |
92
- |-------|------|----------|
91
+ | Layer | File | Contents |
92
+ | ------ | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
93
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 |
94
+ | `vue` | `vue.json` | Extends `base`. Adds `vue` plugin, Vue compiler macros as globals, Vue-specific rules |
95
95
 
96
96
  ## What stays repo-local
97
97
 
@@ -102,8 +102,36 @@ Plugins are additive and deduplicated — your local plugins are added to the sh
102
102
 
103
103
  ## Merge semantics
104
104
 
105
- When a consumer stub adds its own `rules` or `overrides` on top of a shared layer:
105
+ When a consumer stub extends a shared layer:
106
106
 
107
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)
108
+ - **Overrides** are additive — both shared and local `overrides` entries apply, including any `env` declared inside an override block
109
+ - **Plugins** are additive — both shared and local `plugins`/`jsPlugins` are loaded (deduplicated)
110
+
111
+ ### Known oxlint limitation: top-level `env`, `globals`, and `ignorePatterns` don't merge through `extends`
112
+
113
+ oxlint currently drops top-level `env`, `globals`, and `ignorePatterns` from an extended config file entirely — they only take effect if declared directly in the file oxlint is invoked with. This is an open upstream bug: [oxc-project/oxc#20087](https://github.com/oxc-project/oxc/issues/20087) (open as of oxlint 1.72.0).
114
+
115
+ In practice this means:
116
+
117
+ - `base.json`'s `env` (`builtin`, `browser`) and `vue.json`'s Vue macro `globals` (`defineProps`, `defineEmits`, etc.) will **not** reach a consumer that only does `{ "extends": ["./node_modules/@lewishowles/lint-config/vue.json"] }` — every global from the shared layer will be flagged by `no-undef`.
118
+ - Any `ignorePatterns` this package might declare would be silently dropped the same way, so it deliberately ships none — see "What stays repo-local" below.
119
+
120
+ Until this is fixed upstream, redeclare the `env`/`globals` you need directly in your project's `.oxlintrc.json`, even though `base.json`/`vue.json` already declare them:
121
+
122
+ ```json
123
+ {
124
+ "extends": ["./node_modules/@lewishowles/lint-config/vue.json"],
125
+ "env": { "builtin": true, "browser": true },
126
+ "globals": {
127
+ "defineEmits": "readonly",
128
+ "defineExpose": "readonly",
129
+ "defineModel": "readonly",
130
+ "defineOptions": "readonly",
131
+ "defineProps": "readonly",
132
+ "defineSlots": "readonly",
133
+ "withDefaults": "readonly"
134
+ },
135
+ "ignorePatterns": ["**/dist/*", ".codebase-memory/**"]
136
+ }
137
+ ```
package/base.json CHANGED
@@ -1,55 +1,55 @@
1
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",
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
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
- ],
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
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
- }
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
55
  }
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@lewishowles/lint-config",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Shared oxlint configuration for Lewis Howles projects",
5
5
  "keywords": [
6
+ "config",
7
+ "eslint",
6
8
  "lint",
7
9
  "oxlint",
8
- "config",
9
10
  "shared",
10
- "eslint",
11
11
  "stylistic"
12
12
  ],
13
13
  "homepage": "https://github.com/lewishowles/lint-config#readme",
@@ -18,28 +18,28 @@
18
18
  "type": "git",
19
19
  "url": "git+https://github.com/lewishowles/lint-config.git"
20
20
  },
21
- "type": "module",
22
- "exports": {
23
- "./base.json": "./base.json",
24
- "./vue.json": "./vue.json"
25
- },
26
21
  "files": [
27
22
  "base.json",
28
23
  "vue.json",
29
24
  "README.md"
30
25
  ],
31
- "peerDependencies": {
32
- "@stylistic/eslint-plugin": "*",
33
- "vite-plus": "*"
26
+ "type": "module",
27
+ "exports": {
28
+ "./base.json": "./base.json",
29
+ "./vue.json": "./vue.json"
34
30
  },
35
- "devDependencies": {
36
- "publint": "^0.3.21"
31
+ "publishConfig": {
32
+ "access": "public"
37
33
  },
38
34
  "scripts": {
39
35
  "publint": "publint"
40
36
  },
41
- "publishConfig": {
42
- "access": "public"
37
+ "devDependencies": {
38
+ "publint": "^0.3.21"
39
+ },
40
+ "peerDependencies": {
41
+ "@stylistic/eslint-plugin": "*",
42
+ "vite-plus": "*"
43
43
  },
44
44
  "engines": {
45
45
  "node": ">=20"