@heyq02/rslint-config 0.0.1 → 0.0.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.
package/dist/index.mjs DELETED
@@ -1,522 +0,0 @@
1
- import { createRequire } from "node:module";
2
- import { globalIgnores, globals, importPlugin, jestPlugin, js, jsxA11yPlugin, nodePlugin, promisePlugin, reactHooksPlugin, reactPlugin, rstestPlugin, ts, unicornPlugin } from "@rslint/core";
3
- import process from "node:process";
4
- //#region src/globs.ts
5
- const GLOB_SRC_EXT = "?([cm])[jt]s?(x)";
6
- const GLOB_SRC = `**/*.${GLOB_SRC_EXT}`;
7
- const GLOB_JS = "**/*.?([cm])js";
8
- const GLOB_JSX = "**/*.jsx";
9
- const GLOB_TS = "**/*.?([cm])ts";
10
- const GLOB_TSX = "**/*.tsx";
11
- const GLOB_TESTS = [
12
- `**/__tests__/**/*.${GLOB_SRC_EXT}`,
13
- `**/*.spec.${GLOB_SRC_EXT}`,
14
- `**/*.test.${GLOB_SRC_EXT}`,
15
- `**/*.bench.${GLOB_SRC_EXT}`,
16
- `**/*.benchmark.${GLOB_SRC_EXT}`
17
- ];
18
- const GLOB_NODE_MODULES = "**/node_modules";
19
- const GLOB_DIST = "**/dist";
20
- const GLOB_LOCKFILE = [
21
- "**/package-lock.json",
22
- "**/yarn.lock",
23
- "**/pnpm-lock.yaml",
24
- "**/bun.lock",
25
- "**/bun.lockb"
26
- ];
27
- const GLOB_EXCLUDE = [
28
- GLOB_NODE_MODULES,
29
- GLOB_DIST,
30
- ...GLOB_LOCKFILE,
31
- "**/coverage",
32
- "**/temp",
33
- "**/tmp",
34
- "**/fixtures",
35
- "**/output",
36
- "**/.vitepress/cache",
37
- "**/.nuxt",
38
- "**/.next",
39
- "**/.vercel",
40
- "**/.changeset",
41
- "**/.idea",
42
- "**/.output",
43
- "**/.vite-inspect",
44
- "**/.nitro",
45
- "**/.turbo",
46
- "**/CHANGELOG*.md",
47
- "**/*.min.*",
48
- "**/LICENSE*",
49
- "**/__snapshots__",
50
- "**/auto-import?(s).d.ts",
51
- "**/components.d.ts"
52
- ];
53
- //#endregion
54
- //#region src/configs/ignores.ts
55
- const ignores = (extra = []) => [{
56
- ...globalIgnores([...GLOB_EXCLUDE, ...extra]),
57
- name: "heyq02/global-ignores"
58
- }];
59
- //#endregion
60
- //#region src/configs/imports.ts
61
- const imports = (options = {}) => [{
62
- ...importPlugin.configs.recommended,
63
- files: [GLOB_SRC],
64
- name: "heyq02/imports/recommended"
65
- }, {
66
- files: [GLOB_SRC],
67
- name: "heyq02/imports",
68
- rules: {
69
- "import/first": "error",
70
- "import/no-default-export": "error",
71
- "import/no-duplicates": ["error", { "prefer-inline": true }],
72
- "import/no-mutable-exports": "error",
73
- "import/no-named-default": "error",
74
- ...options.typescript ? {
75
- "import/default": "off",
76
- "import/named": "off",
77
- "import/namespace": "off",
78
- "import/no-unresolved": "off"
79
- } : {}
80
- }
81
- }];
82
- //#endregion
83
- //#region src/configs/javascript.ts
84
- const restrictedSyntaxJs = ["ForInStatement", "LabeledStatement"];
85
- const javascript = () => [{
86
- ...js.configs.recommended,
87
- name: "heyq02/js/recommended"
88
- }, {
89
- files: [GLOB_SRC],
90
- languageOptions: {
91
- ecmaVersion: "latest",
92
- globals: {
93
- ...globals.browser,
94
- ...globals.es2026,
95
- ...globals.nodeBuiltin
96
- },
97
- sourceType: "module"
98
- },
99
- name: "heyq02/js",
100
- rules: {
101
- "array-callback-return": "error",
102
- "block-scoped-var": "error",
103
- "dot-notation": "warn",
104
- eqeqeq: ["error", "smart"],
105
- "no-alert": "warn",
106
- "no-console": ["warn", { allow: [
107
- "warn",
108
- "error",
109
- "info",
110
- "clear"
111
- ] }],
112
- "no-debugger": "warn",
113
- "no-duplicate-imports": "error",
114
- "no-empty": ["error", { allowEmptyCatch: true }],
115
- "no-fallthrough": ["warn", { commentPattern: String.raw`break[\s\w]*omitted` }],
116
- "no-inner-declarations": "error",
117
- "no-lonely-if": "error",
118
- "no-multi-str": "error",
119
- "no-restricted-syntax": ["error", ...restrictedSyntaxJs],
120
- "no-unused-expressions": ["error", {
121
- allowShortCircuit: true,
122
- allowTaggedTemplates: true,
123
- allowTernary: true
124
- }],
125
- "no-unused-vars": ["error", {
126
- args: "after-used",
127
- argsIgnorePattern: "^_",
128
- ignoreRestSiblings: true,
129
- varsIgnorePattern: "^_"
130
- }],
131
- "no-useless-call": "error",
132
- "no-useless-computed-key": "error",
133
- "no-useless-constructor": "error",
134
- "no-useless-rename": "error",
135
- "no-var": "error",
136
- "no-void": "error",
137
- "object-shorthand": [
138
- "error",
139
- "always",
140
- {
141
- avoidQuotes: true,
142
- ignoreConstructors: false
143
- }
144
- ],
145
- "one-var": ["error", { initialized: "never" }],
146
- "prefer-arrow-callback": ["error", {
147
- allowNamedFunctions: false,
148
- allowUnboundThis: true
149
- }],
150
- "prefer-const": ["warn", {
151
- destructuring: "all",
152
- ignoreReadBeforeAssign: true
153
- }],
154
- "prefer-exponentiation-operator": "error",
155
- "prefer-regex-literals": ["error", { disallowRedundantWrapping: true }],
156
- "prefer-rest-params": "error",
157
- "prefer-spread": "error",
158
- "prefer-template": "error",
159
- "require-await": "error",
160
- "unicode-bom": ["error", "never"],
161
- "use-isnan": ["error", {
162
- enforceForIndexOf: true,
163
- enforceForSwitchCase: true
164
- }],
165
- "valid-typeof": ["error", { requireStringLiterals: true }],
166
- "vars-on-top": "error"
167
- }
168
- }];
169
- //#endregion
170
- //#region src/configs/jest.ts
171
- const jest = () => [{
172
- ...jestPlugin.configs.recommended,
173
- files: [...GLOB_TESTS],
174
- name: "heyq02/jest/recommended"
175
- }, {
176
- ...jestPlugin.configs.style,
177
- files: [...GLOB_TESTS],
178
- name: "heyq02/jest/style"
179
- }];
180
- //#endregion
181
- //#region src/configs/node.ts
182
- const node = (preset = "module") => {
183
- if (preset === "mixed") return nodePlugin.configs.recommended.map((entry, index) => ({
184
- ...entry,
185
- name: entry.name ?? `heyq02/node/recommended-${index}`
186
- }));
187
- if (preset === "script") return [{
188
- ...nodePlugin.configs.recommendedScript,
189
- files: [GLOB_SRC],
190
- name: "heyq02/node/recommended-script"
191
- }];
192
- return [{
193
- ...nodePlugin.configs.recommendedModule,
194
- files: [GLOB_SRC],
195
- name: "heyq02/node/recommended-module"
196
- }, {
197
- files: [GLOB_SRC],
198
- name: "heyq02/node",
199
- plugins: ["node"],
200
- rules: {
201
- "node/handle-callback-err": ["error", "^(err|error)$"],
202
- "node/no-deprecated-api": "error",
203
- "node/no-exports-assign": "error",
204
- "node/no-new-require": "error",
205
- "node/no-path-concat": "error",
206
- "node/prefer-global/buffer": ["error", "never"],
207
- "node/prefer-global/process": ["error", "never"],
208
- "node/process-exit-as-throw": "error"
209
- }
210
- }];
211
- };
212
- //#endregion
213
- //#region src/configs/promise.ts
214
- const promise = () => [{
215
- ...promisePlugin.configs.recommended,
216
- files: [GLOB_SRC],
217
- name: "heyq02/promise/recommended"
218
- }, {
219
- files: [GLOB_SRC],
220
- name: "heyq02/promise",
221
- rules: {
222
- "promise/always-return": "off",
223
- "promise/catch-or-return": "off",
224
- "promise/no-nesting": "off"
225
- }
226
- }];
227
- //#endregion
228
- //#region src/configs/react.ts
229
- const reactFiles = [
230
- GLOB_JSX,
231
- GLOB_TSX,
232
- "**/*.{jsx,tsx}"
233
- ];
234
- const jsxA11y = () => [{
235
- ...jsxA11yPlugin.configs.recommended,
236
- files: reactFiles,
237
- name: "heyq02/jsx-a11y/recommended"
238
- }];
239
- const react = (options = {}) => {
240
- const configs = [{
241
- ...reactPlugin.configs.recommended,
242
- files: reactFiles,
243
- name: "heyq02/react/recommended"
244
- }, {
245
- ...reactHooksPlugin.configs.recommended,
246
- files: reactFiles,
247
- name: "heyq02/react-hooks/recommended"
248
- }];
249
- if (options.jsxA11y !== false) configs.push(...jsxA11y());
250
- return configs;
251
- };
252
- //#endregion
253
- //#region src/configs/rstest.ts
254
- const rstest = () => [{
255
- ...rstestPlugin.configs.recommended,
256
- files: [...GLOB_TESTS],
257
- name: "heyq02/rstest/recommended"
258
- }];
259
- //#endregion
260
- //#region src/configs/special-cases.ts
261
- const specialCases = () => [
262
- {
263
- files: [
264
- "**/scripts/*",
265
- "**/cli.*",
266
- "**/bin/**"
267
- ],
268
- name: "heyq02/special/cli",
269
- rules: { "no-console": "off" }
270
- },
271
- {
272
- files: [`**/*.{test,spec}.${GLOB_SRC_EXT}`],
273
- name: "heyq02/special/tests",
274
- rules: {
275
- "no-unused-expressions": "off",
276
- "@typescript-eslint/no-unused-expressions": "off"
277
- }
278
- },
279
- {
280
- files: [
281
- `**/*config*.${GLOB_SRC_EXT}`,
282
- `**/{views,pages,routes,middleware,plugins,api,modules}/${GLOB_SRC}`,
283
- `**/{index,vite,esbuild,rollup,rolldown,webpack,rspack,farm,unloader,nuxt,rslint}.${GLOB_SRC_EXT}`,
284
- "**/*.d.ts",
285
- "**/.prettierrc*"
286
- ],
287
- name: "heyq02/special/allow-default-export",
288
- rules: { "import/no-default-export": "off" }
289
- },
290
- {
291
- files: ["**/ISSUE_TEMPLATE/**"],
292
- name: "heyq02/special/github",
293
- rules: { "unicorn/filename-case": "off" }
294
- },
295
- {
296
- files: [GLOB_JSX, GLOB_TSX],
297
- name: "heyq02/special/components",
298
- rules: {
299
- "unicorn/no-anonymous-default-export": "off",
300
- "import/no-default-export": "off"
301
- }
302
- }
303
- ];
304
- //#endregion
305
- //#region src/configs/typescript.ts
306
- function resolveTypeScriptOptions(options) {
307
- if (options === true) return {
308
- typeChecked: false,
309
- strict: false,
310
- stylistic: true
311
- };
312
- return {
313
- typeChecked: options.typeChecked ?? false,
314
- strict: options.strict ?? false,
315
- stylistic: options.stylistic ?? true,
316
- projectService: options.projectService
317
- };
318
- }
319
- const typescript = (options = true) => {
320
- const opts = resolveTypeScriptOptions(options);
321
- const baseline = opts.strict && opts.typeChecked ? ts.configs.strictTypeChecked : opts.strict ? ts.configs.strict : opts.typeChecked ? ts.configs.recommendedTypeChecked : ts.configs.recommended;
322
- const stylistic = opts.stylistic ? opts.typeChecked ? ts.configs.stylisticTypeChecked : ts.configs.stylistic : [];
323
- const enableProjectService = opts.projectService ?? (opts.typeChecked ? true : void 0);
324
- return [
325
- ...baseline,
326
- ...stylistic,
327
- {
328
- files: [GLOB_TS, GLOB_TSX],
329
- name: "heyq02/typescript",
330
- ...enableProjectService === void 0 ? {} : { languageOptions: { parserOptions: { projectService: enableProjectService } } },
331
- rules: {
332
- "@typescript-eslint/ban-ts-comment": "off",
333
- "@typescript-eslint/consistent-type-assertions": ["error", {
334
- assertionStyle: "as",
335
- objectLiteralTypeAssertions: "allow-as-parameter"
336
- }],
337
- "@typescript-eslint/consistent-type-imports": ["error", {
338
- disallowTypeAnnotations: false,
339
- fixStyle: "inline-type-imports"
340
- }],
341
- "@typescript-eslint/method-signature-style": ["error", "property"],
342
- "@typescript-eslint/no-empty-object-type": "off",
343
- "@typescript-eslint/no-explicit-any": "off",
344
- "@typescript-eslint/no-import-type-side-effects": "error",
345
- "@typescript-eslint/no-non-null-assertion": "off",
346
- "@typescript-eslint/no-redeclare": "error",
347
- "@typescript-eslint/no-unused-expressions": ["error", {
348
- allowShortCircuit: true,
349
- allowTaggedTemplates: true,
350
- allowTernary: true
351
- }],
352
- "@typescript-eslint/no-unused-vars": ["error", {
353
- args: "after-used",
354
- argsIgnorePattern: "^_",
355
- ignoreRestSiblings: true,
356
- varsIgnorePattern: "^_"
357
- }],
358
- "@typescript-eslint/no-useless-constructor": "error",
359
- "@typescript-eslint/prefer-as-const": "warn",
360
- "@typescript-eslint/prefer-literal-enum-member": ["error", { allowBitwiseExpressions: true }],
361
- "no-restricted-syntax": [
362
- "error",
363
- ...restrictedSyntaxJs,
364
- "TSEnumDeclaration[const=true]"
365
- ],
366
- "no-unused-vars": "off"
367
- }
368
- },
369
- {
370
- files: ["**/*.d.ts"],
371
- name: "heyq02/typescript/dts-rules",
372
- rules: {
373
- "import/no-duplicates": "off",
374
- "no-restricted-syntax": "off"
375
- }
376
- },
377
- {
378
- files: [GLOB_JS, "**/*.cjs"],
379
- name: "heyq02/typescript/cjs-rules",
380
- rules: { "@typescript-eslint/no-require-imports": "off" }
381
- }
382
- ];
383
- };
384
- //#endregion
385
- //#region src/configs/unicorn.ts
386
- const unicorn = () => [{
387
- ...unicornPlugin.configs.recommended,
388
- files: [GLOB_SRC],
389
- name: "heyq02/unicorn/recommended"
390
- }, {
391
- files: [GLOB_SRC],
392
- name: "heyq02/unicorn",
393
- rules: {
394
- "unicorn/filename-case": ["error", {
395
- cases: {
396
- kebabCase: true,
397
- pascalCase: true
398
- },
399
- ignore: [
400
- String.raw`^[A-Z]+\..*$`,
401
- String.raw`^[a-z]{2}-[A-Z]{2}$`,
402
- String.raw`import_map\.json`
403
- ]
404
- }],
405
- "unicorn/no-null": "off",
406
- "unicorn/no-this-assignment": "off",
407
- "unicorn/prefer-ternary": "off",
408
- "unicorn/no-process-exit": "off"
409
- }
410
- }];
411
- //#endregion
412
- //#region src/env.ts
413
- const require = createRequire(import.meta.url);
414
- const cwd = process.cwd();
415
- function isPackageExists(name) {
416
- try {
417
- require.resolve(name, { paths: [cwd] });
418
- return true;
419
- } catch {
420
- return false;
421
- }
422
- }
423
- const hasTypeScript = () => isPackageExists("typescript");
424
- const hasReact = () => isPackageExists("react") || isPackageExists("react-dom") || isPackageExists("next") || isPackageExists("preact") || isPackageExists("@remix-run/react");
425
- const hasJest = () => isPackageExists("jest") || isPackageExists("@jest/globals");
426
- const hasRstest = () => isPackageExists("rstest") || isPackageExists("@rstest/core") || isPackageExists("@rstest/adapter");
427
- function isInEditorEnv() {
428
- if (process.env.CI) return false;
429
- if (isInGitHooksOrLintStaged()) return false;
430
- return !!(process.env.VSCODE_PID || process.env.VSCODE_CWD || process.env.JETBRAINS_IDE || process.env.VIM || process.env.NVIM);
431
- }
432
- function isInGitHooksOrLintStaged() {
433
- return !!(process.env.GIT_PARAMS || process.env.VSCODE_GIT_COMMAND || process.env.npm_lifecycle_script?.startsWith("lint-staged"));
434
- }
435
- //#endregion
436
- //#region src/utils.ts
437
- /** Flatten nested config values into a single entry list. */
438
- function flattenConfigs(...configs) {
439
- const result = [];
440
- for (const config of configs) {
441
- if (!config) continue;
442
- if (Array.isArray(config)) {
443
- result.push(...flattenConfigs(...config));
444
- continue;
445
- }
446
- result.push(config);
447
- }
448
- return result;
449
- }
450
- function toArray(value) {
451
- return Array.isArray(value) ? value : [value];
452
- }
453
- //#endregion
454
- //#region src/presets.ts
455
- /** Ignore common files and include JavaScript support. */
456
- const presetJavaScript = () => [
457
- ...ignores(),
458
- ...javascript(),
459
- ...imports({ typescript: false }),
460
- ...unicorn(),
461
- ...node(),
462
- ...promise()
463
- ];
464
- /** Includes `presetJavaScript` and TypeScript support. */
465
- const presetBasic = (typescriptOptions = true) => [
466
- ...ignores(),
467
- ...javascript(),
468
- ...typescript(typescriptOptions),
469
- ...imports({ typescript: true }),
470
- ...unicorn(),
471
- ...node(),
472
- ...promise()
473
- ];
474
- /**
475
- * Full opinionated preset:
476
- * - JS + TS
477
- * - Unicorn / import / node / promise
478
- * - React / Jest / Rstest when detected
479
- * - Special-case overrides
480
- */
481
- const presetAll = () => heyq02({
482
- typescript: true,
483
- react: true,
484
- jest: true,
485
- rstest: true,
486
- jsxA11y: true
487
- });
488
- /**
489
- * `@heyq02`'s opinionated Rslint config preset.
490
- *
491
- * @example
492
- * ```ts
493
- * // rslint.config.ts
494
- * import { heyq02 } from '@heyq02/rslint-config'
495
- *
496
- * export default heyq02({
497
- * typescript: { typeChecked: true, strict: true },
498
- * react: true,
499
- * })
500
- * ```
501
- */
502
- function heyq02(options = {}, ...userConfigs) {
503
- const { ignores: extraIgnores = [], javascript: enableJavaScript = true, typescript: enableTypeScript = hasTypeScript(), unicorn: enableUnicorn = true, imports: enableImports = true, node: enableNode = true, promise: enablePromise = true, react: enableReact = hasReact(), jsxA11y: enableJsxA11y, jest: enableJest = hasJest(), rstest: enableRstest = hasRstest() } = options;
504
- const configs = [...ignores(extraIgnores)];
505
- if (enableJavaScript) configs.push(...javascript());
506
- if (enableTypeScript) configs.push(...typescript(enableTypeScript === true ? true : enableTypeScript));
507
- if (enableImports) configs.push(...imports({ typescript: Boolean(enableTypeScript) }));
508
- if (enableUnicorn) configs.push(...unicorn());
509
- if (enableNode) configs.push(...node(enableNode === true ? "module" : enableNode));
510
- if (enablePromise) configs.push(...promise());
511
- if (enableReact) configs.push(...react({ jsxA11y: enableJsxA11y ?? true }));
512
- else if (enableJsxA11y) configs.push(...jsxA11y());
513
- if (enableJest) configs.push(...jest());
514
- if (enableRstest) configs.push(...rstest());
515
- configs.push(...specialCases());
516
- configs.push(...flattenConfigs(...userConfigs));
517
- return configs;
518
- }
519
- /** Alias of {@link heyq02}. */
520
- const rslintConfig = heyq02;
521
- //#endregion
522
- export { GLOB_DIST, GLOB_EXCLUDE, GLOB_JS, GLOB_JSX, GLOB_LOCKFILE, GLOB_NODE_MODULES, GLOB_SRC, GLOB_SRC_EXT, GLOB_TESTS, GLOB_TS, GLOB_TSX, flattenConfigs, hasJest, hasReact, hasRstest, hasTypeScript, heyq02, ignores, imports, isInEditorEnv, isInGitHooksOrLintStaged, javascript, jest, jsxA11y, node, presetAll, presetBasic, presetJavaScript, promise, react, restrictedSyntaxJs, rslintConfig, rstest, specialCases, toArray, typescript, unicorn };