@discourse/lint-configs 1.4.2 → 2.0.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.
@@ -0,0 +1,14 @@
1
+ import DiscourseBaseConfig from "./eslint.mjs";
2
+
3
+ export default [
4
+ ...DiscourseBaseConfig,
5
+ {
6
+ languageOptions: {
7
+ globals: {
8
+ settings: "readonly",
9
+ themePrefix: "readonly",
10
+ },
11
+ },
12
+ ignores: ["javascripts/vendor/*"],
13
+ },
14
+ ];
@@ -0,0 +1,2 @@
1
+ import DiscourseRecommended from "./eslint.mjs";
2
+ export default DiscourseRecommended;
package/eslint.mjs ADDED
@@ -0,0 +1,260 @@
1
+ import BabelParser from "@babel/eslint-parser";
2
+ import js from "@eslint/js";
3
+ import EmberESLintParser from "ember-eslint-parser";
4
+ import DecoratorPosition from "eslint-plugin-decorator-position";
5
+ import EmberPlugin from "eslint-plugin-ember";
6
+ import EmberRecommended from "eslint-plugin-ember/configs/recommended";
7
+ import QUnitPlugin from "eslint-plugin-qunit";
8
+ import QUnitRecommended from "eslint-plugin-qunit/configs/recommended";
9
+ import SimpleImportSort from "eslint-plugin-simple-import-sort";
10
+ import SortClassMembers from "eslint-plugin-sort-class-members";
11
+ import globals from "globals";
12
+
13
+ // Copied from "ember-template-imports/lib/utils"
14
+ const TEMPLATE_TAG_PLACEHOLDER = "__GLIMMER_TEMPLATE";
15
+
16
+ export default [
17
+ js.configs.recommended,
18
+ QUnitRecommended,
19
+ ...EmberRecommended,
20
+ {
21
+ languageOptions: {
22
+ ecmaVersion: 2018,
23
+ sourceType: "module",
24
+ parser: BabelParser,
25
+ parserOptions: {
26
+ requireConfigFile: false,
27
+ babelOptions: {
28
+ plugins: [["@babel/plugin-proposal-decorators", { legacy: true }]],
29
+ },
30
+ },
31
+
32
+ globals: {
33
+ ...globals.browser,
34
+ ...globals.node,
35
+ _: "off",
36
+ $: "readonly", // covered by ember/no-global-jquery
37
+ acceptance: "off",
38
+ asyncRender: "off",
39
+ Blob: "readonly",
40
+ bootbox: "off",
41
+ click: "off",
42
+ count: "off",
43
+ currentPath: "off",
44
+ currentRouteName: "off",
45
+ currentURL: "off",
46
+ currentUser: "off",
47
+ define: "readonly",
48
+ Discourse: "off",
49
+ Ember: "off",
50
+ exists: "off",
51
+ File: "readonly",
52
+ fillIn: "off",
53
+ find: "off",
54
+ getSettledState: "off",
55
+ globalThis: "readonly",
56
+ hasModule: "off",
57
+ invisible: "off",
58
+ jQuery: "readonly", // covered by ember/no-global-jquery
59
+ keyboardHelper: "off",
60
+ keyEvent: "off",
61
+ moduleFor: "off",
62
+ moment: "readonly",
63
+ pauseTest: "off",
64
+ Pretender: "off",
65
+ Promise: "readonly",
66
+ query: "off",
67
+ queryAll: "off",
68
+ QUnit: "off",
69
+ require: "readonly",
70
+ requirejs: "readonly",
71
+ sandbox: "off",
72
+ sinon: "off",
73
+ test: "off",
74
+ testDone: "off",
75
+ testStart: "off",
76
+ triggerEvent: "off",
77
+ visible: "off",
78
+ visit: "off",
79
+ waitUntil: "off",
80
+ },
81
+ },
82
+ plugins: {
83
+ ember: EmberPlugin,
84
+ "sort-class-members": SortClassMembers,
85
+ "decorator-position": DecoratorPosition,
86
+ "simple-import-sort": SimpleImportSort,
87
+ qunit: QUnitPlugin,
88
+ },
89
+ rules: {
90
+ "block-scoped-var": "error",
91
+ eqeqeq: ["error", "allow-null"],
92
+ "getter-return": "off",
93
+ "guard-for-in": "error",
94
+ "no-alert": "error",
95
+ "no-bitwise": "error",
96
+ "no-caller": "error",
97
+ "no-case-declarations": "off",
98
+ "no-cond-assign": "off",
99
+ "no-console": "error",
100
+ "no-constant-condition": "off",
101
+ "no-control-regex": "off",
102
+ "no-debugger": "error",
103
+ "no-empty": ["error", { allowEmptyCatch: true }],
104
+ "no-eval": "error",
105
+ "no-extend-native": "error",
106
+ "no-inner-declarations": "error",
107
+ "no-irregular-whitespace": "error",
108
+ "no-iterator": "error",
109
+ "no-loop-func": "error",
110
+ "no-misleading-character-class": "off",
111
+ "no-mixed-spaces-and-tabs": "error",
112
+ "no-multi-str": "error",
113
+ "no-new": "error",
114
+ "no-proto": "error",
115
+ "no-prototype-builtins": "off",
116
+ "no-regex-spaces": "off",
117
+ "no-script-url": "error",
118
+ "no-sequences": "error",
119
+ "no-shadow": "error",
120
+ "no-this-before-super": "error",
121
+ "no-trailing-spaces": "error",
122
+ "no-undef": "error",
123
+ "no-unexpected-multiline": "off",
124
+ "no-unused-vars": "error",
125
+ "no-useless-escape": "off",
126
+ "no-var": "error",
127
+ "no-with": "error",
128
+ radix: "error",
129
+ semi: "error",
130
+ "valid-typeof": "error",
131
+ "wrap-iife": ["error", "inside"],
132
+ curly: "error",
133
+ "no-duplicate-imports": "error",
134
+ "object-shorthand": ["error", "properties"],
135
+ "no-dupe-class-members": "error",
136
+ "ember/no-classic-components": "off",
137
+ "ember/no-component-lifecycle-hooks": "off",
138
+ "ember/require-tagless-components": "off",
139
+ "ember/no-assignment-of-untracked-properties-used-in-tracking-contexts":
140
+ "off",
141
+ "ember/no-computed-properties-in-native-classes": "off",
142
+ "ember/no-side-effects": "off",
143
+ "ember/require-computed-property-dependencies": "off",
144
+ "ember/require-return-from-computed": "off",
145
+ "ember/use-brace-expansion": "off", // we no longer recommend using @computed
146
+ "ember/no-deprecated-router-transition-methods": "off", // this rule is broken
147
+ "ember/avoid-leaking-state-in-ember-objects": "off",
148
+ "ember/no-get": "off",
149
+ "ember/no-observers": "off",
150
+ "ember/no-mixins": "off",
151
+ "ember/no-new-mixins": "off",
152
+ "ember/no-implicit-injections": "off", // this rule is broken
153
+ "ember/no-array-prototype-extensions": "off",
154
+ "ember/no-at-ember-render-modifiers": "off",
155
+ "ember/classic-decorator-hooks": "off",
156
+ "ember/classic-decorator-no-classic-methods": "off",
157
+ "ember/no-actions-hash": "off",
158
+ "ember/no-classic-classes": "off",
159
+ "ember/no-tracked-properties-from-args": "off",
160
+ "ember/no-jquery": "off",
161
+ "ember/no-runloop": "off",
162
+ "ember/no-capital-letters-in-routes": "off",
163
+ "ember/no-controller-access-in-routes": "off",
164
+ "ember/no-shadow-route-definition": "off",
165
+ "ember/no-unnecessary-index-route": "off",
166
+ "ember/no-unnecessary-service-injection-argument": "error",
167
+ "ember/route-path-style": "off",
168
+ "ember/routes-segments-snake-case": "off",
169
+ "ember/no-replace-test-comments": "error",
170
+ "qunit/no-assert-equal-boolean": "off",
171
+ "qunit/no-assert-equal": "off",
172
+ "qunit/no-conditional-assertions": "off",
173
+ "qunit/no-identical-names": "off",
174
+ "qunit/no-loose-assertions": "off",
175
+ "qunit/no-negated-ok": "off",
176
+ "qunit/no-ok-equality": "off",
177
+ "sort-class-members/sort-class-members": [
178
+ "error",
179
+ {
180
+ order: [
181
+ "[static-properties]",
182
+ "[static-methods]",
183
+ "[injected-services]",
184
+ "[injected-controllers]",
185
+ "[tracked-properties]",
186
+ "[properties]",
187
+ "[private-properties]",
188
+ "constructor",
189
+ "[everything-else]",
190
+ "[template-tag]",
191
+ ],
192
+ groups: {
193
+ // https://github.com/ember-cli/eslint-plugin-ember/issues/1896
194
+ // This only sort of works: in addition to the issues mentioned
195
+ // above, it doesn't seem to reliably enforce the order, e.g.
196
+ // [injected-services] -> <template> -> [injected-services]
197
+ // doesn't seem to trigger the error. That being said, it does
198
+ // work sometimes and this is needed to avoid emitting errors
199
+ // in the limited cases where it does work.
200
+ "template-tag": [
201
+ { type: "property", name: `/${TEMPLATE_TAG_PLACEHOLDER}/` },
202
+ ],
203
+ "injected-services": [
204
+ { groupByDecorator: "service", type: "property" },
205
+ { groupByDecorator: "optionalService", type: "property" },
206
+ ],
207
+ "injected-controllers": [
208
+ { groupByDecorator: "controller", type: "property" },
209
+ ],
210
+ "tracked-properties": [
211
+ { groupByDecorator: "tracked", type: "property" },
212
+ ],
213
+ "private-properties": [
214
+ { type: "property", private: true },
215
+ { type: "property", name: "/_.+/" },
216
+ ],
217
+ },
218
+ accessorPairPositioning: "getThenSet",
219
+ stopAfterFirstProblem: false,
220
+ },
221
+ ],
222
+ "decorator-position/decorator-position": ["error", { printWidth: 80 }],
223
+ "simple-import-sort/imports": [
224
+ "error",
225
+ {
226
+ groups: [
227
+ [
228
+ // Ember/glimmer
229
+ "^@glimmer/",
230
+ "^@ember/",
231
+ // Any other packages ('longest match wins')
232
+ "",
233
+ // Internal
234
+ "^discourse/",
235
+ "^discourse-common/",
236
+ "^discourse-.+",
237
+ "^admin/",
238
+ "^wizard/",
239
+ "^I18n$",
240
+ "^select-kit/",
241
+ "^float-kit/",
242
+ "^truth-helpers/",
243
+ // Plugins
244
+ "^discourse/plugins/",
245
+ // Relative
246
+ "^\\.\\./",
247
+ "^\\./",
248
+ ],
249
+ ],
250
+ },
251
+ ],
252
+ },
253
+ },
254
+ {
255
+ files: ["**/*.gjs", "**/*.gts"],
256
+ languageOptions: {
257
+ parser: EmberESLintParser,
258
+ },
259
+ },
260
+ ];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@discourse/lint-configs",
3
- "version": "1.4.2",
3
+ "version": "2.0.0",
4
4
  "description": "Shareable lint configs for Discourse core, plugins, and themes",
5
5
  "author": "Discourse",
6
6
  "license": "MIT",
@@ -14,12 +14,8 @@
14
14
  "homepage": "https://github.com/discourse/lint-configs#readme",
15
15
  "type": "module",
16
16
  "exports": {
17
- "./eslint": {
18
- "require": "./eslintrc.cjs"
19
- },
20
- "./eslint-theme": {
21
- "require": "./eslint-theme.cjs"
22
- },
17
+ "./eslint": "./eslint.mjs",
18
+ "./eslint-theme": "./eslint-theme.mjs",
23
19
  "./prettier": {
24
20
  "require": "./.prettierrc.cjs"
25
21
  },
@@ -28,7 +24,7 @@
28
24
  }
29
25
  },
30
26
  "scripts": {
31
- "lint": "eslint --no-error-on-unmatched-pattern **/*.cjs **/*.js && pnpm prettier --check .",
27
+ "lint": "eslint --no-error-on-unmatched-pattern **/*.cjs */**.mjs **/*.js && pnpm prettier --check .",
32
28
  "test": "cd ../test && node test.js"
33
29
  },
34
30
  "dependencies": {
@@ -36,9 +32,9 @@
36
32
  "@babel/eslint-parser": "^7.25.8",
37
33
  "@babel/plugin-proposal-decorators": "^7.25.7",
38
34
  "ember-template-lint": "^6.0.0",
39
- "eslint": "8.57.1",
35
+ "eslint": "^9.14.0",
40
36
  "eslint-plugin-decorator-position": "^5.0.2",
41
- "eslint-plugin-ember": "^12.2.1",
37
+ "eslint-plugin-ember": "^12.3.1",
42
38
  "eslint-plugin-qunit": "^8.1.2",
43
39
  "eslint-plugin-simple-import-sort": "^12.1.1",
44
40
  "eslint-plugin-sort-class-members": "^1.20.0",
@@ -49,7 +45,7 @@
49
45
  },
50
46
  "peerDependencies": {
51
47
  "ember-template-lint": "6.0.0",
52
- "eslint": "8.57.1",
48
+ "eslint": "^9.14.0",
53
49
  "prettier": "2.8.8"
54
50
  }
55
51
  }
package/.eslintrc.cjs DELETED
@@ -1 +0,0 @@
1
- module.exports = require("./eslintrc.cjs");
package/eslint-theme.cjs DELETED
@@ -1,13 +0,0 @@
1
- const eslint = require("./eslintrc.cjs");
2
-
3
- const config = { ...eslint };
4
- config.ignorePatterns = ["javascripts/vendor/*"];
5
- config.overrides.push({
6
- files: ["*.js", "*.gjs"],
7
- globals: {
8
- settings: "readonly",
9
- themePrefix: "readonly",
10
- },
11
- });
12
-
13
- module.exports = config;
package/eslintrc.cjs DELETED
@@ -1,262 +0,0 @@
1
- "use strict";
2
-
3
- /* eslint-env node */
4
-
5
- // Copied from "ember-template-imports/lib/utils"
6
- const TEMPLATE_TAG_PLACEHOLDER = "__GLIMMER_TEMPLATE";
7
-
8
- module.exports = {
9
- root: true,
10
- extends: [
11
- "eslint:recommended",
12
- "plugin:qunit/recommended",
13
- "plugin:ember/recommended",
14
- ],
15
- parser: "@babel/eslint-parser",
16
- env: {
17
- browser: true,
18
- builtin: true,
19
- es6: true,
20
- node: true,
21
- },
22
- parserOptions: {
23
- ecmaVersion: 2018,
24
- sourceType: "module",
25
- requireConfigFile: false,
26
- babelOptions: {
27
- plugins: [["@babel/plugin-proposal-decorators", { legacy: true }]],
28
- },
29
- },
30
- plugins: [
31
- "ember",
32
- "sort-class-members",
33
- "decorator-position",
34
- "simple-import-sort",
35
- "qunit",
36
- ],
37
- globals: {
38
- _: "off",
39
- $: "readonly", // covered by ember/no-global-jquery
40
- acceptance: "off",
41
- asyncRender: "off",
42
- Blob: "readonly",
43
- bootbox: "off",
44
- click: "off",
45
- count: "off",
46
- currentPath: "off",
47
- currentRouteName: "off",
48
- currentURL: "off",
49
- currentUser: "off",
50
- define: "readonly",
51
- Discourse: "off",
52
- Ember: "off",
53
- exists: "off",
54
- File: "readonly",
55
- fillIn: "off",
56
- find: "off",
57
- getSettledState: "off",
58
- globalThis: "readonly",
59
- hasModule: "off",
60
- invisible: "off",
61
- jQuery: "readonly", // covered by ember/no-global-jquery
62
- keyboardHelper: "off",
63
- keyEvent: "off",
64
- moduleFor: "off",
65
- moment: "readonly",
66
- pauseTest: "off",
67
- Pretender: "off",
68
- Promise: "readonly",
69
- query: "off",
70
- queryAll: "off",
71
- QUnit: "off",
72
- require: "readonly",
73
- requirejs: "readonly",
74
- sandbox: "off",
75
- sinon: "off",
76
- test: "off",
77
- testDone: "off",
78
- testStart: "off",
79
- triggerEvent: "off",
80
- visible: "off",
81
- visit: "off",
82
- waitUntil: "off",
83
- },
84
- rules: {
85
- "block-scoped-var": "error",
86
- eqeqeq: ["error", "allow-null"],
87
- "getter-return": "off",
88
- "guard-for-in": "error",
89
- "no-alert": "error",
90
- "no-bitwise": "error",
91
- "no-caller": "error",
92
- "no-case-declarations": "off",
93
- "no-cond-assign": "off",
94
- "no-console": "error",
95
- "no-constant-condition": "off",
96
- "no-control-regex": "off",
97
- "no-debugger": "error",
98
- "no-empty": ["error", { allowEmptyCatch: true }],
99
- "no-eval": "error",
100
- "no-extend-native": "error",
101
- "no-inner-declarations": "error",
102
- "no-irregular-whitespace": "error",
103
- "no-iterator": "error",
104
- "no-loop-func": "error",
105
- "no-misleading-character-class": "off",
106
- "no-mixed-spaces-and-tabs": "error",
107
- "no-multi-str": "error",
108
- "no-new": "error",
109
- "no-proto": "error",
110
- "no-prototype-builtins": "off",
111
- "no-regex-spaces": "off",
112
- "no-script-url": "error",
113
- "no-sequences": "error",
114
- "no-shadow": "error",
115
- "no-this-before-super": "error",
116
- "no-trailing-spaces": "error",
117
- "no-undef": "error",
118
- "no-unexpected-multiline": "off",
119
- "no-unused-vars": "error",
120
- "no-useless-escape": "off",
121
- "no-var": "error",
122
- "no-with": "error",
123
- radix: "error",
124
- semi: "error",
125
- "valid-typeof": "error",
126
- "wrap-iife": ["error", "inside"],
127
- curly: "error",
128
- "no-duplicate-imports": "error",
129
- "object-shorthand": ["error", "properties"],
130
- "no-dupe-class-members": "error",
131
-
132
- "ember/no-classic-components": "off",
133
- "ember/no-component-lifecycle-hooks": "off",
134
- "ember/require-tagless-components": "off",
135
- "ember/no-assignment-of-untracked-properties-used-in-tracking-contexts":
136
- "off",
137
- "ember/no-computed-properties-in-native-classes": "off",
138
- "ember/no-side-effects": "off",
139
- "ember/require-computed-property-dependencies": "off",
140
- "ember/require-return-from-computed": "off",
141
- "ember/use-brace-expansion": "off", // we no longer recommend using @computed
142
- "ember/no-deprecated-router-transition-methods": "off", // this rule is broken
143
- "ember/avoid-leaking-state-in-ember-objects": "off",
144
- "ember/no-get": "off",
145
- "ember/no-observers": "off",
146
- "ember/no-mixins": "off",
147
- "ember/no-new-mixins": "off",
148
- "ember/no-implicit-injections": "off", // this rule is broken
149
- "ember/no-array-prototype-extensions": "off",
150
- "ember/no-at-ember-render-modifiers": "off",
151
- "ember/classic-decorator-hooks": "off",
152
- "ember/classic-decorator-no-classic-methods": "off",
153
- "ember/no-actions-hash": "off",
154
- "ember/no-classic-classes": "off",
155
- "ember/no-tracked-properties-from-args": "off",
156
- "ember/no-jquery": "off",
157
- "ember/no-runloop": "off",
158
- "ember/no-capital-letters-in-routes": "off",
159
- "ember/no-controller-access-in-routes": "off",
160
- "ember/no-shadow-route-definition": "off",
161
- "ember/no-unnecessary-index-route": "off",
162
- "ember/no-unnecessary-service-injection-argument": "error",
163
- "ember/route-path-style": "off",
164
- "ember/routes-segments-snake-case": "off",
165
- "ember/no-replace-test-comments": "error",
166
-
167
- "qunit/no-assert-equal-boolean": "off",
168
- "qunit/no-assert-equal": "off",
169
- "qunit/no-conditional-assertions": "off",
170
- "qunit/no-identical-names": "off",
171
- "qunit/no-loose-assertions": "off",
172
- "qunit/no-negated-ok": "off",
173
- "qunit/no-ok-equality": "off",
174
-
175
- "sort-class-members/sort-class-members": [
176
- "error",
177
- {
178
- order: [
179
- "[static-properties]",
180
- "[static-methods]",
181
- "[injected-services]",
182
- "[injected-controllers]",
183
- "[tracked-properties]",
184
- "[properties]",
185
- "[private-properties]",
186
- "constructor",
187
- "[everything-else]",
188
- "[template-tag]",
189
- ],
190
- groups: {
191
- // https://github.com/ember-cli/eslint-plugin-ember/issues/1896
192
- // This only sort of works: in addition to the issues mentioned
193
- // above, it doesn't seem to reliably enforce the order, e.g.
194
- // [injected-services] -> <template> -> [injected-services]
195
- // doesn't seem to trigger the error. That being said, it does
196
- // work sometimes and this is needed to avoid emitting errors
197
- // in the limited cases where it does work.
198
- "template-tag": [
199
- { type: "property", name: `/${TEMPLATE_TAG_PLACEHOLDER}/` },
200
- ],
201
- "injected-services": [
202
- { groupByDecorator: "service", type: "property" },
203
- { groupByDecorator: "optionalService", type: "property" },
204
- ],
205
- "injected-controllers": [
206
- { groupByDecorator: "controller", type: "property" },
207
- ],
208
- "tracked-properties": [
209
- { groupByDecorator: "tracked", type: "property" },
210
- ],
211
- "private-properties": [
212
- { type: "property", private: true },
213
- { type: "property", name: "/_.+/" },
214
- ],
215
- },
216
- accessorPairPositioning: "getThenSet",
217
- stopAfterFirstProblem: false,
218
- },
219
- ],
220
- "decorator-position/decorator-position": ["error", { printWidth: 80 }],
221
- "simple-import-sort/imports": [
222
- "error",
223
- {
224
- groups: [
225
- [
226
- // Ember/glimmer
227
- "^@glimmer/",
228
- "^@ember/",
229
- // Any other packages ('longest match wins')
230
- "",
231
- // Internal
232
- "^discourse/",
233
- "^discourse-common/",
234
- "^discourse-.+",
235
- "^admin/",
236
- "^wizard/",
237
- "^I18n$",
238
- "^select-kit/",
239
- "^float-kit/",
240
- "^truth-helpers/",
241
- // Plugins
242
- "^discourse/plugins/",
243
- // Relative
244
- "^\\.\\./",
245
- "^\\./",
246
- ],
247
- ],
248
- },
249
- ],
250
- },
251
-
252
- overrides: [
253
- {
254
- files: ["**/*.gjs"],
255
- parser: "ember-eslint-parser",
256
- extends: ["plugin:ember/recommended-gjs"],
257
- rules: {
258
- "ember/template-no-let-reference": "off", // we have valid cases of using let variables in templates
259
- },
260
- },
261
- ],
262
- };