@storm-software/eslint 0.100.0 → 0.107.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/dist/preset.js ADDED
@@ -0,0 +1,375 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
+ import eslint from "@eslint/js";
4
+ import next from "@next/eslint-plugin-next";
5
+ import nxPlugin from "@nx/eslint-plugin/nx.js";
6
+ import { formatLogMessage, writeDebug, writeError, writeFatal, writeInfo } from "@storm-software/config-tools";
7
+ import { defu } from "defu";
8
+ import json from "eslint-plugin-json";
9
+ import markdown from "eslint-plugin-markdown";
10
+ import prettierConfig from "eslint-plugin-prettier/recommended";
11
+ import reactPlugin from "eslint-plugin-react";
12
+ import reactCompiler from "eslint-plugin-react-compiler";
13
+ import reactHooks from "eslint-plugin-react-hooks";
14
+ import tsdoc from "eslint-plugin-tsdoc";
15
+ import unicorn from "eslint-plugin-unicorn";
16
+ import yml from "eslint-plugin-yml";
17
+ import globalsObj from "globals";
18
+ import tsEslint from "typescript-eslint";
19
+ import { getStormRulesConfig } from "./rules/storm";
20
+ import tsdocRules from "./rules/ts-docs";
21
+ import banner from "./utils/banner-plugin";
22
+ import { CODE_BLOCK, TS_FILE } from "./utils/constants";
23
+ import { formatConfig } from "./utils/format-config";
24
+ import { ignores } from "./utils/ignores";
25
+ function getStormConfig(options = {
26
+ rules: {},
27
+ ignores: [],
28
+ globals: {},
29
+ useUnicorn: true,
30
+ markdown: {},
31
+ react: {},
32
+ nx: {},
33
+ useReactCompiler: false,
34
+ logLevel: "info",
35
+ cspellConfigFile: ".vscode/cspell.json"
36
+ }, ...userConfigs) {
37
+ const tsconfig = options.tsconfig;
38
+ const parserOptions = options.parserOptions;
39
+ const typescriptEslintConfigType = options.typescriptEslintConfigType || "eslintRecommended";
40
+ const useUnicorn = options.useUnicorn ?? true;
41
+ const react = options.react ?? {};
42
+ const nx = options.nx ?? {};
43
+ const useReactCompiler = options.useReactCompiler ?? false;
44
+ const logLevel = options.logLevel ?? "info";
45
+ const globals = options.globals ?? {};
46
+ const cspellConfigFile = options.cspellConfigFile || ".vscode/cspell.json";
47
+ try {
48
+ const configs = [
49
+ // Prettier
50
+ prettierConfig,
51
+ // Import
52
+ // https://www.npmjs.com/package/eslint-plugin-import
53
+ // { plugins: { import: importEslint } },
54
+ // {
55
+ // files: [CODE_FILE],
56
+ // rules: importRules
57
+ // },
58
+ // Json
59
+ // https://www.npmjs.com/package/eslint-plugin-json
60
+ {
61
+ files: [
62
+ "**/*.json"
63
+ ],
64
+ ...json.configs["recommended"],
65
+ rules: {
66
+ "json/json": [
67
+ "warn",
68
+ {
69
+ "allowComments": true
70
+ }
71
+ ]
72
+ }
73
+ },
74
+ {
75
+ files: [
76
+ "**/executors/**/schema.json",
77
+ "**/generators/**/schema.json"
78
+ ],
79
+ rules: nx !== false ? {
80
+ "@nx/workspace/valid-schema-description": "error"
81
+ } : {}
82
+ },
83
+ {
84
+ files: [
85
+ "**/package.json"
86
+ ],
87
+ rules: nx !== false ? {
88
+ "@nx/dependency-checks": [
89
+ "error",
90
+ {
91
+ buildTargets: [
92
+ "build"
93
+ ],
94
+ ignoredDependencies: [
95
+ "typescript"
96
+ ],
97
+ ignoredFiles: options.ignores,
98
+ checkMissingDependencies: true,
99
+ checkObsoleteDependencies: true,
100
+ checkVersionMismatches: false,
101
+ includeTransitiveDependencies: true,
102
+ useLocalPathsForWorkspaceDependencies: true
103
+ }
104
+ ]
105
+ } : {}
106
+ },
107
+ // YML
108
+ // https://www.npmjs.com/package/eslint-plugin-yml
109
+ ...yml.configs["flat/recommended"],
110
+ ...yml.configs["flat/prettier"],
111
+ // CSpell
112
+ {
113
+ ...json.configs["recommended"],
114
+ rules: {
115
+ ...json.configs["recommended"].rules,
116
+ "@cspell/spellchecker": [
117
+ "warn",
118
+ {
119
+ configFile: new URL(cspellConfigFile, import.meta.url).toString(),
120
+ autoFix: true
121
+ }
122
+ ]
123
+ }
124
+ },
125
+ // User overrides
126
+ ...userConfigs
127
+ ].filter(Boolean);
128
+ if (nx) {
129
+ configs.push({
130
+ plugins: {
131
+ "@nx": nxPlugin
132
+ }
133
+ });
134
+ }
135
+ configs.push(eslint.configs.recommended);
136
+ if (typescriptEslintConfigType !== "none") {
137
+ if (!(typescriptEslintConfigType in tsEslint.configs)) {
138
+ console.warn("Invalid TypeScript ESLint configuration type:", typescriptEslintConfigType);
139
+ } else {
140
+ configs.push(...Array.isArray(tsEslint.configs[typescriptEslintConfigType]) ? tsEslint.configs[typescriptEslintConfigType] : [
141
+ tsEslint.configs[typescriptEslintConfigType]
142
+ ]);
143
+ }
144
+ }
145
+ if (useUnicorn) {
146
+ configs.push({
147
+ files: [
148
+ TS_FILE
149
+ ],
150
+ plugins: {
151
+ unicorn
152
+ },
153
+ rules: {
154
+ ...unicorn.configs["flat/recommended"].rules
155
+ }
156
+ });
157
+ }
158
+ configs.push({
159
+ files: [
160
+ TS_FILE
161
+ ],
162
+ plugins: {
163
+ tsdoc
164
+ },
165
+ rules: tsdocRules
166
+ });
167
+ configs.push({
168
+ // ...banner.configs!["recommended"],
169
+ name: "banner",
170
+ plugins: {
171
+ banner
172
+ },
173
+ files: [
174
+ TS_FILE
175
+ ],
176
+ rules: {
177
+ "banner/banner": [
178
+ "error",
179
+ {
180
+ commentType: "block",
181
+ numNewlines: 2,
182
+ repositoryName: options.name
183
+ }
184
+ ]
185
+ }
186
+ });
187
+ if (react) {
188
+ const reactConfigs = [
189
+ {
190
+ ...reactPlugin.configs?.recommended,
191
+ plugins: {
192
+ "react": reactPlugin
193
+ },
194
+ files: [
195
+ "**/*.tsx"
196
+ ],
197
+ ignores: [
198
+ ...ignores,
199
+ ...options.ignores || []
200
+ ],
201
+ ...react
202
+ },
203
+ {
204
+ ...reactHooks.configs?.recommended,
205
+ plugins: {
206
+ "react-hooks": reactHooks
207
+ },
208
+ files: [
209
+ TS_FILE
210
+ ],
211
+ ignores: [
212
+ ...ignores,
213
+ ...options.ignores || []
214
+ ]
215
+ }
216
+ ];
217
+ if (useReactCompiler) {
218
+ reactConfigs.push({
219
+ files: [
220
+ "**/*.tsx"
221
+ ],
222
+ ignores: [
223
+ ...ignores,
224
+ ...options.ignores || []
225
+ ],
226
+ plugins: {
227
+ "react-compiler": reactCompiler
228
+ },
229
+ rules: {
230
+ "react-compiler/react-compiler": "error"
231
+ }
232
+ });
233
+ }
234
+ configs.push(...reactConfigs);
235
+ }
236
+ if (options.nextFiles && options.nextFiles.length > 0) {
237
+ configs.push({
238
+ ...next.configs["core-web-vitals"],
239
+ ignores: [
240
+ ...options.ignores || []
241
+ ],
242
+ files: options.nextFiles
243
+ });
244
+ }
245
+ const typescriptConfig = {
246
+ files: [
247
+ TS_FILE
248
+ ],
249
+ languageOptions: {
250
+ globals: {
251
+ ...Object.fromEntries(Object.keys(globalsObj).flatMap((group) => Object.keys(globalsObj[group]).map((key) => [
252
+ key,
253
+ "readonly"
254
+ ]))),
255
+ ...globalsObj.browser,
256
+ ...globalsObj.node,
257
+ ...globals,
258
+ "window": "readonly"
259
+ },
260
+ parserOptions: {
261
+ projectService: true,
262
+ ecmaFeatures: {
263
+ jsx: react !== false
264
+ }
265
+ }
266
+ },
267
+ rules: {
268
+ ...getStormRulesConfig({
269
+ ...options,
270
+ typescriptEslintConfigType,
271
+ useUnicorn,
272
+ useNx: nx !== false
273
+ }),
274
+ ...Object.keys(options.rules ?? {}).filter((ruleId) => !useUnicorn || !ruleId.startsWith("unicorn/") || !react || !ruleId.startsWith("react/") && !ruleId.startsWith("react-hooks/")).reduce((ret, ruleId) => {
275
+ ret[ruleId] = options.rules[ruleId];
276
+ return ret;
277
+ }, {})
278
+ },
279
+ ignores: [
280
+ ...ignores,
281
+ ...options.ignores || []
282
+ ]
283
+ };
284
+ if (parserOptions) {
285
+ typescriptConfig.languageOptions ??= {};
286
+ typescriptConfig.languageOptions.parserOptions = parserOptions;
287
+ }
288
+ if (tsconfig) {
289
+ typescriptConfig.languageOptions ??= {};
290
+ typescriptConfig.languageOptions.parserOptions ??= {};
291
+ typescriptConfig.languageOptions.parserOptions.project = tsconfig;
292
+ }
293
+ configs.push(typescriptConfig);
294
+ if (options.markdown) {
295
+ configs.push(...markdown.configs.recommended);
296
+ configs.push({
297
+ files: [
298
+ CODE_BLOCK
299
+ ],
300
+ processor: "markdown/markdown",
301
+ rules: {
302
+ "unicorn/filename-case": "off",
303
+ "no-undef": "off",
304
+ "no-unused-expressions": "off",
305
+ "padded-blocks": "off",
306
+ "no-empty-pattern": "off",
307
+ "no-redeclare": "off",
308
+ "no-import-assign": "off",
309
+ ...options.markdown
310
+ }
311
+ });
312
+ configs.push({
313
+ files: [
314
+ "**/*.md/*.js",
315
+ "**/*.md/*.ts"
316
+ ],
317
+ rules: {
318
+ "unicorn/filename-case": "off",
319
+ "no-undef": "off",
320
+ "no-unused-expressions": "off",
321
+ "padded-blocks": "off",
322
+ "no-empty-pattern": "off",
323
+ "no-redeclare": "off",
324
+ "no-import-assign": "off",
325
+ ...options.markdown
326
+ }
327
+ });
328
+ }
329
+ const result = formatConfig("Preset", configs.reduce((ret, config) => {
330
+ delete config.parserOptions;
331
+ const existingIndex = ret.findIndex((existing) => areFilesEqual(existing.files, config.files));
332
+ if (existingIndex >= 0) {
333
+ ret[existingIndex] = defu(ret[existingIndex], config);
334
+ } else {
335
+ ret.push(config);
336
+ }
337
+ return ret;
338
+ }, []));
339
+ writeInfo("\u2699\uFE0F Completed generated Storm ESLint configuration objects", {
340
+ logLevel
341
+ });
342
+ writeDebug(formatLogMessage(result, {
343
+ skip: [
344
+ "globals"
345
+ ]
346
+ }), {
347
+ logLevel
348
+ });
349
+ return result;
350
+ } catch (error) {
351
+ writeFatal("Error generating Storm ESLint configuration objects", {
352
+ logLevel
353
+ });
354
+ writeError(error, {
355
+ logLevel
356
+ });
357
+ throw error;
358
+ }
359
+ }
360
+ __name(getStormConfig, "getStormConfig");
361
+ const areFilesEqual = /* @__PURE__ */ __name((files1, files2) => {
362
+ if (files1 === files2) {
363
+ return true;
364
+ } else if (!files1 || !files2) {
365
+ return false;
366
+ } else if (typeof files1 === "string" && typeof files2 !== "string" || typeof files1 !== "string" && typeof files2 === "string" || Array.isArray(files1) && !Array.isArray(files2) || !Array.isArray(files1) && Array.isArray(files2)) {
367
+ return false;
368
+ } else if (files1.length !== files2.length) {
369
+ return false;
370
+ }
371
+ return files1.every((file, index) => Array.isArray(file) && Array.isArray(files2?.[index]) ? areFilesEqual(file, files2?.[index]) : !Array.isArray(file) && !Array.isArray(files2?.[index]) ? file?.toLowerCase() === files2?.[index]?.toLowerCase() : file === files2);
372
+ }, "areFilesEqual");
373
+ export {
374
+ getStormConfig
375
+ };
package/package.json CHANGED
@@ -1,121 +1 @@
1
- {
2
- "name": "@storm-software/eslint",
3
- "version": "0.100.0",
4
- "type": "module",
5
- "description": "⚡ A package containing the base ESLint configuration used by Storm Software across many projects.",
6
- "repository": {
7
- "type": "github",
8
- "url": "https://github.com/storm-software/storm-ops",
9
- "directory": "packages/eslint"
10
- },
11
- "homepage": "https://stormsoftware.com",
12
- "bugs": {
13
- "url": "https://github.com/storm-software/storm-ops/issues",
14
- "email": "support@stormsoftware.com"
15
- },
16
- "author": {
17
- "name": "Storm Software",
18
- "email": "contact@stormsoftware.com",
19
- "url": "https://stormsoftware.com"
20
- },
21
- "maintainers": [
22
- {
23
- "name": "Storm Software",
24
- "email": "contact@stormsoftware.com",
25
- "url": "https://stormsoftware.com"
26
- },
27
- {
28
- "name": "Pat Sullivan",
29
- "email": "admin@stormsoftware.com",
30
- "url": "https://patsullivan.org"
31
- }
32
- ],
33
- "license": "Apache-2.0",
34
- "private": false,
35
- "exports": {
36
- ".": {
37
- "types": "./dist/preset.d.ts",
38
- "import": "./dist/preset.mjs"
39
- }
40
- },
41
- "files": [
42
- "dist"
43
- ],
44
- "keywords": [
45
- "storm",
46
- "storm-ops",
47
- "sullivanpj",
48
- "eslint",
49
- "eslintconfig",
50
- "eslint-config",
51
- "monorepo"
52
- ],
53
- "peerDependencies": {
54
- "@nx/eslint": "^20.2.2",
55
- "@nx/eslint-plugin": "^20.2.2",
56
- "eslint": "9.5.0",
57
- "graphql": ">=16.9.0"
58
- },
59
- "peerDependenciesMeta": {
60
- "@nx/eslint": {
61
- "optional": true
62
- },
63
- "@nx/eslint-plugin": {
64
- "optional": true
65
- },
66
- "eslint": {
67
- "optional": false
68
- },
69
- "graphql": {
70
- "optional": true
71
- }
72
- },
73
- "dependencies": {
74
- "@cspell/eslint-plugin": "8.13.1",
75
- "@graphql-eslint/eslint-plugin": "3.20.1",
76
- "@next/eslint-plugin-next": "14.2.4",
77
- "defu": "6.1.4",
78
- "eslint-plugin-es-x": "7.6.0",
79
- "eslint-plugin-import": "^2.29.1",
80
- "eslint-plugin-json": "4.0.0",
81
- "eslint-plugin-jsonc": "2.16.0",
82
- "eslint-plugin-jsx-a11y": "^6.8.0",
83
- "eslint-plugin-markdown": "^5.1.0",
84
- "eslint-plugin-markdownlint": "0.6.0",
85
- "eslint-plugin-mdx": "3.1.5",
86
- "eslint-plugin-n": "17.8.1",
87
- "eslint-plugin-prettier": "^5.0.0",
88
- "eslint-plugin-promise": "6.2.0",
89
- "eslint-plugin-react": "^7.34.3",
90
- "eslint-plugin-react-compiler": "0.0.0-experimental-b6997ec-20240909",
91
- "eslint-plugin-react-hooks": "^4.6.2",
92
- "eslint-plugin-relay": "1.8.3",
93
- "eslint-plugin-sonarjs": "1.0.3",
94
- "eslint-plugin-storybook": "0.10.1",
95
- "eslint-plugin-tsdoc": "0.3.0",
96
- "eslint-plugin-unicorn": "54.0.0",
97
- "eslint-plugin-yml": "1.14.0",
98
- "globals": "^15.8.0",
99
- "jsonc-eslint-parser": "2.4.0",
100
- "synckit": "0.9.0",
101
- "typescript-eslint": "8.10.0",
102
- "ws": "8.17.1",
103
- "yaml-eslint-parser": "1.2.3"
104
- },
105
- "devDependencies": {
106
- "@eslint/config-inspector": "^0.5.1",
107
- "@nx/eslint": "^20.2.2",
108
- "@nx/eslint-plugin": "^20.2.2",
109
- "@types/eslint": "^8.56.10",
110
- "@types/eslint__js": "^8.42.3",
111
- "@types/node": "^22.4.0",
112
- "eslint": "9.5.0",
113
- "eslint-typegen": "^0.2.4",
114
- "graphql": ">=16.9.0",
115
- "typescript": ">=5.5.3",
116
- "unbuild": "^2.0.0"
117
- },
118
- "publishConfig": {
119
- "access": "public"
120
- }
121
- }
1
+ {"name":"@storm-software/eslint","version":"0.107.0","type":"module","description":"⚡ A package containing the base ESLint configuration used by Storm Software across many projects.","repository":{"type":"github","url":"https://github.com/storm-software/storm-ops","directory":"packages/eslint"},"homepage":"https://stormsoftware.com","bugs":"https://github.com/storm-software/storm-ops/issues","author":{"name":"Storm Software","email":"contact@stormsoftware.com","url":"https://stormsoftware.com"},"maintainers":[{"name":"Storm Software","email":"contact@stormsoftware.com","url":"https://stormsoftware.com"},{"name":"Pat Sullivan","email":"admin@stormsoftware.com","url":"https://patsullivan.org"}],"license":"Apache-2.0","private":false,"exports":{".":{"types":"./dist/preset.d.ts","import":"./dist/preset.mjs"}},"files":["dist"],"keywords":["eslint","eslint-config","eslintconfig","monorepo","storm","storm-ops","sullivanpj"],"peerDependencies":{"@nx/eslint":"^20.3.1","@nx/eslint-plugin":"^20.3.1","eslint":"^9.12.0","graphql":">=16.9.0"},"peerDependenciesMeta":{"@nx/eslint":{"optional":true},"@nx/eslint-plugin":{"optional":true},"eslint":{"optional":false},"graphql":{"optional":true}},"dependencies":{"@cspell/eslint-plugin":"8.13.1","@graphql-eslint/eslint-plugin":"3.20.1","@next/eslint-plugin-next":"14.2.4","defu":"6.1.4","eslint-plugin-es-x":"7.6.0","eslint-plugin-import":"^2.29.1","eslint-plugin-json":"4.0.0","eslint-plugin-jsonc":"2.16.0","eslint-plugin-jsx-a11y":"^6.8.0","eslint-plugin-markdown":"^5.1.0","eslint-plugin-markdownlint":"0.6.0","eslint-plugin-mdx":"3.1.5","eslint-plugin-n":"17.8.1","eslint-plugin-prettier":"^5.0.0","eslint-plugin-promise":"6.2.0","eslint-plugin-react":"^7.34.3","eslint-plugin-react-compiler":"0.0.0-experimental-b6997ec-20240909","eslint-plugin-react-hooks":"^5.1.0","eslint-plugin-relay":"1.8.3","eslint-plugin-sonarjs":"1.0.3","eslint-plugin-storybook":"0.11.0","eslint-plugin-tsdoc":"0.4.0","eslint-plugin-unicorn":"56.0.0","eslint-plugin-yml":"1.14.0","globals":"^15.8.0","jsonc-eslint-parser":"2.4.0","synckit":"0.9.0","typescript-eslint":"^8.13.0","ws":"8.17.1","yaml-eslint-parser":"1.2.3"},"devDependencies":{"@eslint/config-inspector":"^0.5.1","@nx/eslint":"^20.3.1","@nx/eslint-plugin":"^20.3.1","@types/eslint":"^9.6.1","@types/eslint__js":"^8.42.3","@types/node":"^22.10.2","eslint":"^9.12.0","eslint-typegen":"^1.0.0","graphql":">=16.9.0","tsup":"8.3.5","typescript":"^5.7.2"},"publishConfig":{"access":"public"}}