@ntnyq/eslint-config 3.10.2 → 3.10.4

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/README.md CHANGED
@@ -9,11 +9,12 @@
9
9
 
10
10
  ## Features
11
11
 
12
- - Opinionable: single quotes, no semi, trailing comma, etc.
12
+ - Opinionable: single quotes, no semi, trailing comma, etc
13
13
  - Designed to work alongside with [Prettier](https://prettier.io)
14
14
  - Respect `.gitignore` via [eslint-config-flat-gitignore](https://github.com/antfu/eslint-config-flat-gitignore)
15
- - Out-of-box support for TypeScript, Vue, JSON, Markdown, YAML, TOML etc.
15
+ - Out-of-box support for TypeScript, Vue, JSON, Markdown, YAML, TOML, SVG and etc
16
16
  - Strict but provides useful rules to guard your codebase
17
+ - Custom ESLint commands for [eslint-plugin-command](https://github.com/antfu/eslint-plugin-command)
17
18
  - [ESLint flat config](https://eslint.org/docs/latest/use/configure/configuration-files) for ESLint v9.5.0+
18
19
 
19
20
  ## Install
@@ -27,23 +28,57 @@ pnpm add eslint prettier typescript @ntnyq/eslint-config @ntnyq/prettier-config
27
28
  Highly recommended using **`eslint.config.mjs`** as the config file :
28
29
 
29
30
  ```js
31
+ // @ts-check
32
+
30
33
  import { defineESLintConfig } from '@ntnyq/eslint-config'
31
34
 
32
35
  export default defineESLintConfig()
33
36
  ```
34
37
 
35
- Add scripts `lint` in `package.json` and config prettier:
38
+ Add scripts `lint` in `package.json`:
36
39
 
37
40
  ```json
38
41
  {
39
42
  "scripts": {
40
43
  "lint": "eslint .",
41
44
  "lint:fix": "eslint . --fix"
42
- },
43
- "prettier": "@ntnyq/prettier-config"
45
+ }
44
46
  }
45
47
  ```
46
48
 
49
+ <details>
50
+ <summary>💼 Intergrated with Prettier, VSCode, husky and nano-staged</summary>
51
+
52
+ <br>
53
+
54
+ ## Prettier config
55
+
56
+ ```js
57
+ // @ts-check
58
+
59
+ import { config, defineConfig } from '@ntnyq/prettier-config'
60
+
61
+ export default defineConfig({
62
+ ...config,
63
+
64
+ // overrides if needed
65
+ overrides: [
66
+ {
67
+ files: ['**/*.html'],
68
+ options: {
69
+ singleAttributePerLine: false,
70
+ },
71
+ },
72
+ {
73
+ files: ['**/*.{css,scss,less}'],
74
+ options: {
75
+ singleQuote: false,
76
+ },
77
+ },
78
+ ],
79
+ })
80
+ ```
81
+
47
82
  ## VSCode Config
48
83
 
49
84
  ```json
@@ -99,6 +134,8 @@ pnpm add husky nano-staged -D
99
134
  echo "nano-staged" > .husky/pre-commit
100
135
  ```
101
136
 
137
+ </details>
138
+
102
139
  ## Advanced config
103
140
 
104
141
  Check for detail in:
package/dist/index.cjs CHANGED
@@ -1133,20 +1133,24 @@ var test = (options = {}) => [
1133
1133
  }
1134
1134
  }
1135
1135
  ];
1136
- var vitest = (options = {}) => [
1137
- {
1138
- name: "ntnyq/vitest",
1139
- plugins: {
1140
- vitest: import_eslint_plugin2.default
1141
- },
1142
- files: [...GLOB_TEST],
1143
- rules: {
1144
- ...import_eslint_plugin2.default.configs.recommended.rules,
1145
- // Overrides rules
1146
- ...options.overridesVitestRules
1136
+ var vitest = (options = {}) => {
1137
+ if (!import_eslint_plugin2.default.configs?.recommended) return [];
1138
+ const vitestConfigs = import_eslint_plugin2.default.configs;
1139
+ return [
1140
+ {
1141
+ name: "ntnyq/vitest",
1142
+ plugins: {
1143
+ vitest: import_eslint_plugin2.default
1144
+ },
1145
+ files: [...GLOB_TEST],
1146
+ rules: {
1147
+ ...vitestConfigs.recommended.rules,
1148
+ // Overrides rules
1149
+ ...options.overridesVitestRules
1150
+ }
1147
1151
  }
1148
- }
1149
- ];
1152
+ ];
1153
+ };
1150
1154
 
1151
1155
  // src/configs/svgo.ts
1152
1156
  var import_eslint_plugin_svgo2 = require("eslint-plugin-svgo");
@@ -1791,7 +1795,7 @@ var import_config = __toESM(require("eslint-plugin-command/config"), 1);
1791
1795
  var import_commands = require("eslint-plugin-command/commands");
1792
1796
  var regexper = (0, import_commands.defineCommand)({
1793
1797
  name: "regexper",
1794
- // @regexper https://regexper.com/#(%5Cb%7C%5Cs%7C%5E)(%40regexper)(%5Cs%5CS%2B)%3F(%5Cb%7C%5Cs%7C%24)
1798
+ // @regexper https://regexper.com/#%2F(%5Cb%7C%5Cs%7C%5E)(%40regexper)(%5Cs%5CS%2B)%3F(%5Cb%7C%5Cs%7C%24)%2F
1795
1799
  match: /(\b|\s|^)(@regexper)(\s\S+)?(\b|\s|$)/,
1796
1800
  action(ctx) {
1797
1801
  const literal = ctx.findNodeBelow((node2) => {
@@ -1800,8 +1804,16 @@ var regexper = (0, import_commands.defineCommand)({
1800
1804
  if (!literal) {
1801
1805
  return ctx.reportError("Unable to find a regexp literal to generate");
1802
1806
  }
1803
- const [_fullStr = "", spaceBefore = "", commandStr = "", existingUrl = "", _spaceAfter = ""] = ctx.matches;
1804
- const url = `https://regexper.com/#${encodeURIComponent(literal.regex.pattern)}`;
1807
+ const [
1808
+ // non-use
1809
+ _fullStr = "",
1810
+ spaceBefore = "",
1811
+ commandStr = "",
1812
+ existingUrl = "",
1813
+ // non-use
1814
+ _spaceAfter = ""
1815
+ ] = ctx.matches;
1816
+ const url = `https://regexper.com/#${encodeURIComponent(literal.raw)}`;
1805
1817
  if (existingUrl.trim() === url.trim()) {
1806
1818
  return;
1807
1819
  }
@@ -2076,12 +2088,27 @@ var comments = (options = {}) => [
2076
2088
  // src/configs/markdown.ts
2077
2089
  var markdown = (options = {}) => {
2078
2090
  if (!Array.isArray(import_markdown.default.configs?.processor)) return [];
2079
- const { files = [`${GLOB_MARKDOWN}/${GLOB_SRC}`], extensions = [] } = options;
2091
+ const {
2092
+ /**
2093
+ * code block files
2094
+ */
2095
+ files = [`${GLOB_MARKDOWN}/${GLOB_SRC}`],
2096
+ /**
2097
+ * other extensions
2098
+ */
2099
+ extensions = []
2100
+ } = options;
2080
2101
  return [
2102
+ /**
2103
+ * extracting code blocks to be linted individually
2104
+ */
2081
2105
  ...import_markdown.default.configs.processor.map((config) => ({
2082
2106
  ...config,
2083
2107
  name: `ntnyq/${config.name}`
2084
2108
  })),
2109
+ /**
2110
+ * enhance `markdown/recommended/processor`
2111
+ */
2085
2112
  {
2086
2113
  name: "ntnyq/markdown/processor",
2087
2114
  files,
@@ -2567,8 +2594,10 @@ var typescript = (options = {}) => {
2567
2594
  ...recommendedRules,
2568
2595
  // Disabled in favor of ts rules
2569
2596
  "no-redeclare": "off",
2570
- "no-use-before-define": "off",
2571
2597
  "no-unused-vars": "off",
2598
+ "no-use-before-define": "off",
2599
+ "no-useless-constructor": "off",
2600
+ "@typescript-eslint/no-useless-constructor": "error",
2572
2601
  "@typescript-eslint/no-redeclare": [
2573
2602
  "error",
2574
2603
  {
package/dist/index.d.cts CHANGED
@@ -5099,6 +5099,11 @@ interface RuleOptions {
5099
5099
  * @deprecated
5100
5100
  */
5101
5101
  'nonblock-statement-body-position'?: Linter.RuleEntry<NonblockStatementBodyPosition>;
5102
+ /**
5103
+ * disallow duplicate exports statement
5104
+ * @see https://eslint-plugin.ntnyq.com/rules/no-duplicate-exports.html
5105
+ */
5106
+ 'ntnyq/no-duplicate-exports'?: Linter.RuleEntry<NtnyqNoDuplicateExports>;
5102
5107
  /**
5103
5108
  * disallow usage of typescript member accessibility
5104
5109
  * @see https://eslint-plugin.ntnyq.com/rules/no-member-accessibility.html
@@ -9800,7 +9805,7 @@ type TypescriptEslintConsistentTypeAssertions = [] | [
9800
9805
  ({
9801
9806
  assertionStyle: "never";
9802
9807
  } | {
9803
- assertionStyle: ("as" | "angle-bracket");
9808
+ assertionStyle?: ("as" | "angle-bracket");
9804
9809
  objectLiteralTypeAssertions?: ("allow" | "allow-as-parameter" | "never");
9805
9810
  })
9806
9811
  ];
@@ -14157,6 +14162,11 @@ type NonblockStatementBodyPosition = [] | [("beside" | "below" | "any")] | [
14157
14162
  };
14158
14163
  }
14159
14164
  ];
14165
+ type NtnyqNoDuplicateExports = [] | [
14166
+ {
14167
+ style?: ("inline" | "separate");
14168
+ }
14169
+ ];
14160
14170
  type ObjectCurlyNewline = [] | [
14161
14171
  ((("always" | "never") | {
14162
14172
  multiline?: boolean;
package/dist/index.d.ts CHANGED
@@ -5099,6 +5099,11 @@ interface RuleOptions {
5099
5099
  * @deprecated
5100
5100
  */
5101
5101
  'nonblock-statement-body-position'?: Linter.RuleEntry<NonblockStatementBodyPosition>;
5102
+ /**
5103
+ * disallow duplicate exports statement
5104
+ * @see https://eslint-plugin.ntnyq.com/rules/no-duplicate-exports.html
5105
+ */
5106
+ 'ntnyq/no-duplicate-exports'?: Linter.RuleEntry<NtnyqNoDuplicateExports>;
5102
5107
  /**
5103
5108
  * disallow usage of typescript member accessibility
5104
5109
  * @see https://eslint-plugin.ntnyq.com/rules/no-member-accessibility.html
@@ -9800,7 +9805,7 @@ type TypescriptEslintConsistentTypeAssertions = [] | [
9800
9805
  ({
9801
9806
  assertionStyle: "never";
9802
9807
  } | {
9803
- assertionStyle: ("as" | "angle-bracket");
9808
+ assertionStyle?: ("as" | "angle-bracket");
9804
9809
  objectLiteralTypeAssertions?: ("allow" | "allow-as-parameter" | "never");
9805
9810
  })
9806
9811
  ];
@@ -14157,6 +14162,11 @@ type NonblockStatementBodyPosition = [] | [("beside" | "below" | "any")] | [
14157
14162
  };
14158
14163
  }
14159
14164
  ];
14165
+ type NtnyqNoDuplicateExports = [] | [
14166
+ {
14167
+ style?: ("inline" | "separate");
14168
+ }
14169
+ ];
14160
14170
  type ObjectCurlyNewline = [] | [
14161
14171
  ((("always" | "never") | {
14162
14172
  multiline?: boolean;
package/dist/index.js CHANGED
@@ -977,20 +977,24 @@ var test = (options = {}) => [
977
977
  }
978
978
  }
979
979
  ];
980
- var vitest = (options = {}) => [
981
- {
982
- name: "ntnyq/vitest",
983
- plugins: {
984
- vitest: default16
985
- },
986
- files: [...GLOB_TEST],
987
- rules: {
988
- ...default16.configs.recommended.rules,
989
- // Overrides rules
990
- ...options.overridesVitestRules
980
+ var vitest = (options = {}) => {
981
+ if (!default16.configs?.recommended) return [];
982
+ const vitestConfigs = default16.configs;
983
+ return [
984
+ {
985
+ name: "ntnyq/vitest",
986
+ plugins: {
987
+ vitest: default16
988
+ },
989
+ files: [...GLOB_TEST],
990
+ rules: {
991
+ ...vitestConfigs.recommended.rules,
992
+ // Overrides rules
993
+ ...options.overridesVitestRules
994
+ }
991
995
  }
992
- }
993
- ];
996
+ ];
997
+ };
994
998
 
995
999
  // src/configs/svgo.ts
996
1000
  import { config as createSVGOConfig } from "eslint-plugin-svgo";
@@ -1635,7 +1639,7 @@ import createCommandConfig from "eslint-plugin-command/config";
1635
1639
  import { defineCommand } from "eslint-plugin-command/commands";
1636
1640
  var regexper = defineCommand({
1637
1641
  name: "regexper",
1638
- // @regexper https://regexper.com/#(%5Cb%7C%5Cs%7C%5E)(%40regexper)(%5Cs%5CS%2B)%3F(%5Cb%7C%5Cs%7C%24)
1642
+ // @regexper https://regexper.com/#%2F(%5Cb%7C%5Cs%7C%5E)(%40regexper)(%5Cs%5CS%2B)%3F(%5Cb%7C%5Cs%7C%24)%2F
1639
1643
  match: /(\b|\s|^)(@regexper)(\s\S+)?(\b|\s|$)/,
1640
1644
  action(ctx) {
1641
1645
  const literal = ctx.findNodeBelow((node2) => {
@@ -1644,8 +1648,16 @@ var regexper = defineCommand({
1644
1648
  if (!literal) {
1645
1649
  return ctx.reportError("Unable to find a regexp literal to generate");
1646
1650
  }
1647
- const [_fullStr = "", spaceBefore = "", commandStr = "", existingUrl = "", _spaceAfter = ""] = ctx.matches;
1648
- const url = `https://regexper.com/#${encodeURIComponent(literal.regex.pattern)}`;
1651
+ const [
1652
+ // non-use
1653
+ _fullStr = "",
1654
+ spaceBefore = "",
1655
+ commandStr = "",
1656
+ existingUrl = "",
1657
+ // non-use
1658
+ _spaceAfter = ""
1659
+ ] = ctx.matches;
1660
+ const url = `https://regexper.com/#${encodeURIComponent(literal.raw)}`;
1649
1661
  if (existingUrl.trim() === url.trim()) {
1650
1662
  return;
1651
1663
  }
@@ -1920,12 +1932,27 @@ var comments = (options = {}) => [
1920
1932
  // src/configs/markdown.ts
1921
1933
  var markdown = (options = {}) => {
1922
1934
  if (!Array.isArray(default10.configs?.processor)) return [];
1923
- const { files = [`${GLOB_MARKDOWN}/${GLOB_SRC}`], extensions = [] } = options;
1935
+ const {
1936
+ /**
1937
+ * code block files
1938
+ */
1939
+ files = [`${GLOB_MARKDOWN}/${GLOB_SRC}`],
1940
+ /**
1941
+ * other extensions
1942
+ */
1943
+ extensions = []
1944
+ } = options;
1924
1945
  return [
1946
+ /**
1947
+ * extracting code blocks to be linted individually
1948
+ */
1925
1949
  ...default10.configs.processor.map((config) => ({
1926
1950
  ...config,
1927
1951
  name: `ntnyq/${config.name}`
1928
1952
  })),
1953
+ /**
1954
+ * enhance `markdown/recommended/processor`
1955
+ */
1929
1956
  {
1930
1957
  name: "ntnyq/markdown/processor",
1931
1958
  files,
@@ -2411,8 +2438,10 @@ var typescript = (options = {}) => {
2411
2438
  ...recommendedRules,
2412
2439
  // Disabled in favor of ts rules
2413
2440
  "no-redeclare": "off",
2414
- "no-use-before-define": "off",
2415
2441
  "no-unused-vars": "off",
2442
+ "no-use-before-define": "off",
2443
+ "no-useless-constructor": "off",
2444
+ "@typescript-eslint/no-useless-constructor": "error",
2416
2445
  "@typescript-eslint/no-redeclare": [
2417
2446
  "error",
2418
2447
  {
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@ntnyq/eslint-config",
3
3
  "type": "module",
4
- "version": "3.10.2",
5
- "packageManager": "pnpm@9.15.1",
4
+ "version": "3.10.4",
5
+ "packageManager": "pnpm@9.15.2",
6
6
  "description": "An opinionated ESLint config preset of ntnyq",
7
7
  "keywords": [
8
8
  "eslint",
@@ -59,8 +59,8 @@
59
59
  "@eslint/js": "^9.17.0",
60
60
  "@eslint/markdown": "^6.2.1",
61
61
  "@stylistic/eslint-plugin": "^2.12.1",
62
- "@unocss/eslint-plugin": "^0.65.2",
63
- "@vitest/eslint-plugin": "^1.1.20",
62
+ "@unocss/eslint-plugin": "^0.65.3",
63
+ "@vitest/eslint-plugin": "^1.1.21",
64
64
  "eslint-config-flat-gitignore": "^0.3.0",
65
65
  "eslint-flat-config-utils": "^0.4.0",
66
66
  "eslint-import-resolver-typescript": "^3.7.0",
@@ -75,12 +75,12 @@
75
75
  "eslint-plugin-jsdoc": "^50.6.1",
76
76
  "eslint-plugin-jsonc": "^2.18.2",
77
77
  "eslint-plugin-n": "^17.15.1",
78
- "eslint-plugin-ntnyq": "^0.7.1",
78
+ "eslint-plugin-ntnyq": "^0.8.2",
79
79
  "eslint-plugin-perfectionist": "^4.4.0",
80
80
  "eslint-plugin-pinia": "^0.4.1",
81
81
  "eslint-plugin-prettier": "^5.2.1",
82
82
  "eslint-plugin-regexp": "^2.7.0",
83
- "eslint-plugin-svgo": "^0.2.0",
83
+ "eslint-plugin-svgo": "^0.3.1",
84
84
  "eslint-plugin-toml": "^0.12.0",
85
85
  "eslint-plugin-unicorn": "^56.0.1",
86
86
  "eslint-plugin-unused-imports": "^4.1.4",
@@ -92,7 +92,7 @@
92
92
  "local-pkg": "^0.5.1",
93
93
  "prettier": "^3.4.2",
94
94
  "toml-eslint-parser": "^0.10.0",
95
- "typescript-eslint": "^8.18.1",
95
+ "typescript-eslint": "^8.18.2",
96
96
  "vue-eslint-parser": "^9.4.3",
97
97
  "yaml-eslint-parser": "^1.2.3"
98
98
  },
@@ -110,7 +110,7 @@
110
110
  "tsx": "^4.19.2",
111
111
  "typescript": "^5.7.2",
112
112
  "vitest": "^3.0.0-beta.3",
113
- "zx": "^8.2.4"
113
+ "zx": "^8.3.0"
114
114
  },
115
115
  "engines": {
116
116
  "node": ">=18.18.0"