@santi020k/eslint-config-basic 0.1.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.
Files changed (140) hide show
  1. package/.agent/rules/context.md +78 -0
  2. package/.agent/rules/guidelines.md +124 -0
  3. package/.editorconfig +13 -0
  4. package/.env.example +8 -0
  5. package/.github/CODEOWNERS +2 -0
  6. package/.github/DISCUSSION_TEMPLATE/rfcs.yml +21 -0
  7. package/.github/DISCUSSION_TEMPLATE/technical-discussions.yml +21 -0
  8. package/.github/FUNDING.yml +2 -0
  9. package/.github/ISSUE_TEMPLATE/README.md +13 -0
  10. package/.github/ISSUE_TEMPLATE/bug_report.yml +69 -0
  11. package/.github/ISSUE_TEMPLATE/config.yml +8 -0
  12. package/.github/ISSUE_TEMPLATE/feature_request.yml +43 -0
  13. package/.github/ISSUE_TEMPLATE/question.yml +22 -0
  14. package/.github/SECURITY.md +12 -0
  15. package/.github/SPONSORSHIPS.md +27 -0
  16. package/.github/dependabot.yml +45 -0
  17. package/.github/labeler.yml +46 -0
  18. package/.github/pull_request_template.md +56 -0
  19. package/.github/workflows/assign-issues.yml +18 -0
  20. package/.github/workflows/audit.yml +22 -0
  21. package/.github/workflows/build.yml +29 -0
  22. package/.github/workflows/codeql.yml +40 -0
  23. package/.github/workflows/docs.yml +49 -0
  24. package/.github/workflows/labeler.yml +18 -0
  25. package/.github/workflows/publish.yml +24 -0
  26. package/.github/workflows/release.yml +35 -0
  27. package/.github/workflows/size-check.yml +23 -0
  28. package/.github/workflows/stale.yml +31 -0
  29. package/.nvmrc +1 -0
  30. package/.vscode/extensions.json +10 -0
  31. package/.vscode/settings.json +55 -0
  32. package/CHANGELOG.md +16 -0
  33. package/CONTRIBUTING.md +194 -0
  34. package/DEVELOPMENT.md +4 -0
  35. package/LICENSE +21 -0
  36. package/README.md +275 -0
  37. package/config/.husky/commit-msg +9 -0
  38. package/config/.husky/pre-commit +1 -0
  39. package/config/.husky/pre-push +1 -0
  40. package/config/.husky/prepare-commit-msg +1 -0
  41. package/cspell.config.yaml +2 -0
  42. package/eslint.config.js +21 -0
  43. package/llms.txt +72 -0
  44. package/package.json +61 -0
  45. package/packages/astro/README.md +13 -0
  46. package/packages/astro/package.json +45 -0
  47. package/packages/astro/src/ambient.d.ts +10 -0
  48. package/packages/astro/src/index.ts +18 -0
  49. package/packages/astro/src/rules.ts +29 -0
  50. package/packages/astro/tsconfig.json +9 -0
  51. package/packages/astro/tsup.config.ts +11 -0
  52. package/packages/basic/README.md +33 -0
  53. package/packages/basic/package.json +55 -0
  54. package/packages/basic/src/index.ts +110 -0
  55. package/packages/basic/tsconfig.json +9 -0
  56. package/packages/basic/tsup.config.ts +18 -0
  57. package/packages/core/README.md +14 -0
  58. package/packages/core/index.ts +14 -0
  59. package/packages/core/package.json +61 -0
  60. package/packages/core/src/ambient.d.ts +61 -0
  61. package/packages/core/src/index.ts +75 -0
  62. package/packages/core/src/rules.ts +157 -0
  63. package/packages/core/src/settings/gitignore.ts +10 -0
  64. package/packages/core/src/settings/index.ts +1 -0
  65. package/packages/core/src/types.ts +57 -0
  66. package/packages/core/src/utils/index.ts +28 -0
  67. package/packages/core/tsconfig.json +9 -0
  68. package/packages/core/tsup.config.ts +10 -0
  69. package/packages/expo/README.md +13 -0
  70. package/packages/expo/package.json +48 -0
  71. package/packages/expo/src/ambient.d.ts +3 -0
  72. package/packages/expo/src/index.ts +39 -0
  73. package/packages/expo/tsconfig.json +9 -0
  74. package/packages/expo/tsup.config.ts +11 -0
  75. package/packages/nest/package.json +45 -0
  76. package/packages/nest/src/ambient.d.ts +14 -0
  77. package/packages/nest/src/index.ts +20 -0
  78. package/packages/nest/src/rules.ts +15 -0
  79. package/packages/nest/tsconfig.json +9 -0
  80. package/packages/nest/tsup.config.ts +11 -0
  81. package/packages/next/README.md +13 -0
  82. package/packages/next/package.json +47 -0
  83. package/packages/next/src/index.ts +31 -0
  84. package/packages/next/src/rules.ts +16 -0
  85. package/packages/next/tsconfig.json +9 -0
  86. package/packages/next/tsup.config.ts +10 -0
  87. package/packages/optionals/README.md +18 -0
  88. package/packages/optionals/package.json +55 -0
  89. package/packages/optionals/src/ambient.d.ts +25 -0
  90. package/packages/optionals/src/cspell.ts +14 -0
  91. package/packages/optionals/src/i18next.ts +19 -0
  92. package/packages/optionals/src/index.ts +8 -0
  93. package/packages/optionals/src/markdown.ts +66 -0
  94. package/packages/optionals/src/mdx.ts +40 -0
  95. package/packages/optionals/src/stencil.ts +48 -0
  96. package/packages/optionals/src/tailwind.ts +11 -0
  97. package/packages/optionals/src/vitest.ts +61 -0
  98. package/packages/optionals/tsconfig.json +9 -0
  99. package/packages/optionals/tsup.config.ts +11 -0
  100. package/packages/playground/README.md +14 -0
  101. package/packages/playground/package.json +17 -0
  102. package/packages/playground/src/astro/eslint.config.js +4 -0
  103. package/packages/playground/src/js/eslint.config.js +4 -0
  104. package/packages/playground/src/js/index.test.js +63 -0
  105. package/packages/playground/src/mdx/eslint.config.js +4 -0
  106. package/packages/playground/src/mdx/index.mdx +115 -0
  107. package/packages/playground/src/react/eslint.config.js +4 -0
  108. package/packages/playground/src/react/index.test.jsx +130 -0
  109. package/packages/playground/src/ts/eslint.config.js +4 -0
  110. package/packages/playground/src/ts/index.test.ts +61 -0
  111. package/packages/playground/src/ts/tsconfig.json +3 -0
  112. package/packages/playground/tsconfig.json +9 -0
  113. package/packages/react/README.md +14 -0
  114. package/packages/react/index.ts +26 -0
  115. package/packages/react/package.json +49 -0
  116. package/packages/react/src/ambient.d.ts +23 -0
  117. package/packages/react/src/index.ts +52 -0
  118. package/packages/react/src/rules.ts +47 -0
  119. package/packages/react/tsconfig.json +9 -0
  120. package/packages/react/tsup.config.ts +10 -0
  121. package/packages/tests/README.md +17 -0
  122. package/packages/tests/package.json +21 -0
  123. package/packages/tests/src/__snapshots__/snapshots.test.ts.snap +654 -0
  124. package/packages/tests/src/composition.test.ts +171 -0
  125. package/packages/tests/src/configs.test.ts +118 -0
  126. package/packages/tests/src/rules.test.ts +60 -0
  127. package/packages/tests/src/snapshots.test.ts +126 -0
  128. package/packages/tests/tsconfig.json +10 -0
  129. package/packages/tests/vitest.config.ts +8 -0
  130. package/packages/typescript/README.md +14 -0
  131. package/packages/typescript/package.json +47 -0
  132. package/packages/typescript/src/index.ts +32 -0
  133. package/packages/typescript/src/rules.ts +36 -0
  134. package/packages/typescript/tsconfig.json +9 -0
  135. package/packages/typescript/tsup.config.ts +10 -0
  136. package/tsconfig.base.json +20 -0
  137. package/tsconfig.docs.json +18 -0
  138. package/turbo.json +19 -0
  139. package/typedoc.config.mjs +25 -0
  140. package/typedoc.markdown.mjs +26 -0
@@ -0,0 +1,171 @@
1
+ import { describe, expect, it } from 'vitest'
2
+
3
+ import { ConfigOption, eslintConfig, OptionalOption, SettingOption } from '@santi020k/eslint-config-basic'
4
+
5
+ describe('eslintConfig Function', () => {
6
+ it('should return an array when called with minimal options', () => {
7
+ const config = eslintConfig({ config: [] })
8
+
9
+ expect(Array.isArray(config)).toBe(true)
10
+ })
11
+
12
+ it('should return config with TypeScript when Ts option is specified', () => {
13
+ const config = eslintConfig({ config: [ConfigOption.Ts] })
14
+
15
+ expect(Array.isArray(config)).toBe(true)
16
+
17
+ expect(config.length).toBeGreaterThan(0)
18
+ })
19
+
20
+ it('should return config with React when React option is specified', () => {
21
+ const config = eslintConfig({ config: [ConfigOption.React] })
22
+
23
+ expect(Array.isArray(config)).toBe(true)
24
+
25
+ expect(config.length).toBeGreaterThan(0)
26
+ })
27
+
28
+ it('should return config with Next when Next option is specified', () => {
29
+ const config = eslintConfig({ config: [ConfigOption.Next] })
30
+
31
+ expect(Array.isArray(config)).toBe(true)
32
+
33
+ expect(config.length).toBeGreaterThan(0)
34
+ })
35
+
36
+ it('should return config with Nest when Nest option is specified', () => {
37
+ const config = eslintConfig({ config: [ConfigOption.Nest] })
38
+
39
+ expect(Array.isArray(config)).toBe(true)
40
+
41
+ expect(config.length).toBeGreaterThan(0)
42
+ })
43
+
44
+ it('should include gitignore when setting is specified', () => {
45
+ const config = eslintConfig({
46
+ config: [],
47
+ settings: [SettingOption.Gitignore]
48
+ })
49
+
50
+ expect(Array.isArray(config)).toBe(true)
51
+ })
52
+
53
+ it('should handle multiple framework configs', () => {
54
+ const config = eslintConfig({
55
+ config: [ConfigOption.Ts, ConfigOption.React]
56
+ })
57
+
58
+ expect(Array.isArray(config)).toBe(true)
59
+
60
+ expect(config.length).toBeGreaterThan(0)
61
+ })
62
+
63
+ it('should handle optionals', () => {
64
+ const config = eslintConfig({
65
+ config: [ConfigOption.Ts],
66
+ optionals: [OptionalOption.Tailwind]
67
+ })
68
+
69
+ expect(Array.isArray(config)).toBe(true)
70
+ })
71
+
72
+ it('should return a valid config when called with no arguments', () => {
73
+ const config = eslintConfig()
74
+
75
+ expect(Array.isArray(config)).toBe(true)
76
+
77
+ expect(config.length).toBeGreaterThan(0)
78
+ })
79
+
80
+ it('should handle all framework configs combined', () => {
81
+ const config = eslintConfig({
82
+ config: [
83
+ ConfigOption.Ts,
84
+ ConfigOption.React,
85
+ ConfigOption.Next,
86
+ ConfigOption.Astro,
87
+ ConfigOption.Expo,
88
+ ConfigOption.Nest
89
+ ]
90
+ })
91
+
92
+ expect(Array.isArray(config)).toBe(true)
93
+
94
+ expect(config.length).toBeGreaterThan(0)
95
+ })
96
+
97
+ it('should handle all optionals combined', () => {
98
+ const config = eslintConfig({
99
+ config: [ConfigOption.Ts],
100
+ optionals: [
101
+ OptionalOption.Cspell,
102
+ OptionalOption.Tailwind,
103
+ OptionalOption.Vitest,
104
+ OptionalOption.I18next,
105
+ OptionalOption.Mdx,
106
+ OptionalOption.Markdown,
107
+ OptionalOption.Stencil
108
+ ]
109
+ })
110
+
111
+ expect(Array.isArray(config)).toBe(true)
112
+
113
+ expect(config.length).toBeGreaterThan(0)
114
+ })
115
+
116
+ it('should handle duplicate config entries without crashing', () => {
117
+ const config = eslintConfig({
118
+ config: [ConfigOption.Ts, ConfigOption.Ts, ConfigOption.React, ConfigOption.React]
119
+ })
120
+
121
+ expect(Array.isArray(config)).toBe(true)
122
+
123
+ expect(config.length).toBeGreaterThan(0)
124
+ })
125
+
126
+ it('should not crash with unknown enum values', () => {
127
+ const config = eslintConfig({
128
+ config: ['unknown-config' as ConfigOption]
129
+ })
130
+
131
+ expect(Array.isArray(config)).toBe(true)
132
+ })
133
+
134
+ it('should handle full kitchen-sink configuration', () => {
135
+ const config = eslintConfig({
136
+ config: [ConfigOption.Ts, ConfigOption.React, ConfigOption.Next],
137
+ optionals: [OptionalOption.Tailwind, OptionalOption.Vitest, OptionalOption.Cspell],
138
+ settings: [SettingOption.Gitignore]
139
+ })
140
+
141
+ expect(Array.isArray(config)).toBe(true)
142
+
143
+ expect(config.length).toBeGreaterThan(0)
144
+ })
145
+ })
146
+
147
+ describe('Type Exports', () => {
148
+ it('should have all ConfigOption values', () => {
149
+ const options = Object.values(ConfigOption)
150
+
151
+ expect(options).toContain('ts')
152
+
153
+ expect(options).toContain('react')
154
+
155
+ expect(options).toContain('next')
156
+ })
157
+
158
+ it('should have all OptionalOption values', () => {
159
+ const options = Object.values(OptionalOption)
160
+
161
+ expect(options).toContain('tailwind')
162
+
163
+ expect(options).toContain('vitest')
164
+ })
165
+
166
+ it('should have all SettingOption values', () => {
167
+ const options = Object.values(SettingOption)
168
+
169
+ expect(options).toContain('gitignore')
170
+ })
171
+ })
@@ -0,0 +1,118 @@
1
+ import { describe, expect, it } from 'vitest'
2
+
3
+ import { astroConfig } from '@santi020k/eslint-config-astro'
4
+ import {
5
+ ConfigOption,
6
+ coreConfig,
7
+ OptionalOption,
8
+ SettingOption
9
+ } from '@santi020k/eslint-config-core'
10
+ import { expoConfig } from '@santi020k/eslint-config-expo'
11
+ import { nestConfig } from '@santi020k/eslint-config-nest'
12
+ import { nextConfig } from '@santi020k/eslint-config-next'
13
+ import { reactConfig } from '@santi020k/eslint-config-react'
14
+ import { typescriptConfig } from '@santi020k/eslint-config-typescript'
15
+
16
+ describe('Core Config', () => {
17
+ it('should export coreConfig as an array', () => {
18
+ expect(Array.isArray(coreConfig)).toBe(true)
19
+ })
20
+
21
+ it('should have at least one config entry', () => {
22
+ expect(coreConfig.length).toBeGreaterThan(0)
23
+ })
24
+
25
+ it('should have named config entries', () => {
26
+ const hasNames = coreConfig.every(config => typeof config.name === 'string')
27
+
28
+ expect(hasNames).toBe(true)
29
+ })
30
+ })
31
+
32
+ describe('TypeScript Config', () => {
33
+ it('should export typescriptConfig as an array', () => {
34
+ expect(Array.isArray(typescriptConfig)).toBe(true)
35
+ })
36
+
37
+ it('should have at least one config entry', () => {
38
+ expect(typescriptConfig.length).toBeGreaterThan(0)
39
+ })
40
+ })
41
+
42
+ describe('React Config', () => {
43
+ it('should export reactConfig as an array', () => {
44
+ expect(Array.isArray(reactConfig)).toBe(true)
45
+ })
46
+
47
+ it('should have at least one config entry', () => {
48
+ expect(reactConfig.length).toBeGreaterThan(0)
49
+ })
50
+ })
51
+
52
+ describe('Next.js Config', () => {
53
+ it('should export nextConfig as an array', () => {
54
+ expect(Array.isArray(nextConfig)).toBe(true)
55
+ })
56
+
57
+ it('should have at least one config entry', () => {
58
+ expect(nextConfig.length).toBeGreaterThan(0)
59
+ })
60
+ })
61
+
62
+ describe('Astro Config', () => {
63
+ it('should export astroConfig as an array', () => {
64
+ expect(Array.isArray(astroConfig)).toBe(true)
65
+ })
66
+
67
+ it('should have at least one config entry', () => {
68
+ expect(astroConfig.length).toBeGreaterThan(0)
69
+ })
70
+ })
71
+
72
+ describe('Expo Config', () => {
73
+ it('should export expoConfig as an array', () => {
74
+ expect(Array.isArray(expoConfig)).toBe(true)
75
+ })
76
+
77
+ it('should have at least one config entry', () => {
78
+ expect(expoConfig.length).toBeGreaterThan(0)
79
+ })
80
+ })
81
+
82
+ describe('NestJS Config', () => {
83
+ it('should export nestConfig as an array', () => {
84
+ expect(Array.isArray(nestConfig)).toBe(true)
85
+ })
86
+
87
+ it('should have at least one config entry', () => {
88
+ expect(nestConfig.length).toBeGreaterThan(0)
89
+ })
90
+ })
91
+
92
+ describe('Config Enums', () => {
93
+ it('should export ConfigOption enum with expected values', () => {
94
+ expect(ConfigOption.Ts).toBeDefined()
95
+
96
+ expect(ConfigOption.React).toBeDefined()
97
+
98
+ expect(ConfigOption.Next).toBeDefined()
99
+
100
+ expect(ConfigOption.Astro).toBeDefined()
101
+
102
+ expect(ConfigOption.Expo).toBeDefined()
103
+
104
+ expect(ConfigOption.Nest).toBeDefined()
105
+ })
106
+
107
+ it('should export OptionalOption enum with expected values', () => {
108
+ expect(OptionalOption.Tailwind).toBeDefined()
109
+
110
+ expect(OptionalOption.Vitest).toBeDefined()
111
+
112
+ expect(OptionalOption.Cspell).toBeDefined()
113
+ })
114
+
115
+ it('should export SettingOption enum with expected values', () => {
116
+ expect(SettingOption.Gitignore).toBeDefined()
117
+ })
118
+ })
@@ -0,0 +1,60 @@
1
+ import { describe, expect, it } from 'vitest'
2
+
3
+ import { coreConfig, rules } from '@santi020k/eslint-config-core'
4
+ import { reactConfig } from '@santi020k/eslint-config-react'
5
+ import { typescriptConfig } from '@santi020k/eslint-config-typescript'
6
+
7
+ describe('Core Rules', () => {
8
+ it('should export rules object', () => {
9
+ expect(typeof rules).toBe('object')
10
+ })
11
+
12
+ it('should include expected core rules', () => {
13
+ // Check for actual rules exported from the core package
14
+ expect(rules['@stylistic/indent']).toBeDefined()
15
+
16
+ expect(rules['@stylistic/quotes']).toBeDefined()
17
+ })
18
+
19
+ it('should have config with stylistic rules', () => {
20
+ const stylisticConfig = coreConfig.find(c => c.name === 'eslint-config/stylistic')
21
+
22
+ expect(stylisticConfig).toBeDefined()
23
+ })
24
+
25
+ it('should have config with plugins', () => {
26
+ const pluginsConfig = coreConfig.find(c => c.name === 'eslint-config/plugins')
27
+
28
+ expect(pluginsConfig).toBeDefined()
29
+
30
+ expect(pluginsConfig?.plugins).toBeDefined()
31
+ })
32
+ })
33
+
34
+ describe('TypeScript Rules', () => {
35
+ it('should include TypeScript parser configuration', () => {
36
+ const tsConfig = typescriptConfig.find(c => c.languageOptions?.parser)
37
+
38
+ expect(tsConfig).toBeDefined()
39
+ })
40
+
41
+ it('should target TypeScript files', () => {
42
+ const hasTypeScriptFiles = typescriptConfig.some(c => c.files?.some(pattern => typeof pattern === 'string' && pattern.includes('.ts')))
43
+
44
+ expect(hasTypeScriptFiles).toBe(true)
45
+ })
46
+ })
47
+
48
+ describe('React Rules', () => {
49
+ it('should include React plugin configuration', () => {
50
+ const hasReactPlugin = reactConfig.some(c => c.plugins && ('react' in c.plugins || 'react-hooks' in c.plugins))
51
+
52
+ expect(hasReactPlugin).toBe(true)
53
+ })
54
+
55
+ it('should have React version detection setting', () => {
56
+ const hasReactSettings = reactConfig.some(c => (c.settings?.react as { version?: string } | undefined)?.version === 'detect')
57
+
58
+ expect(hasReactSettings).toBe(true)
59
+ })
60
+ })
@@ -0,0 +1,126 @@
1
+ import { describe, expect, it } from 'vitest'
2
+
3
+ import { astroConfig } from '@santi020k/eslint-config-astro'
4
+ import { coreConfig } from '@santi020k/eslint-config-core'
5
+ import { expoConfig } from '@santi020k/eslint-config-expo'
6
+ import { nestConfig } from '@santi020k/eslint-config-nest'
7
+ import { nextConfig } from '@santi020k/eslint-config-next'
8
+ import { reactConfig } from '@santi020k/eslint-config-react'
9
+ import { typescriptConfig } from '@santi020k/eslint-config-typescript'
10
+
11
+ /**
12
+ * Extract rule names from a config array for snapshot comparison.
13
+ * This captures the "shape" of each config — when plugin updates
14
+ * add or remove rules, these snapshots will catch it.
15
+ */
16
+ const extractRuleNames = (config: Record<string, unknown>[]): string[] => {
17
+ const ruleNames = new Set<string>()
18
+
19
+ for (const entry of config) {
20
+ const rules = entry.rules as Record<string, unknown> | undefined
21
+
22
+ if (rules) {
23
+ for (const ruleName of Object.keys(rules)) {
24
+ ruleNames.add(ruleName)
25
+ }
26
+ }
27
+ }
28
+
29
+ return [...ruleNames].sort()
30
+ }
31
+
32
+ /**
33
+ * Extract config entry names from a config array.
34
+ */
35
+ const extractConfigNames = (config: Record<string, unknown>[]): string[] => config
36
+ .map(entry => entry.name as string | undefined)
37
+ .filter((name): name is string => typeof name === 'string')
38
+ .sort()
39
+
40
+ describe('Config Snapshots — Rule Names', () => {
41
+ it('core config rules should match snapshot', () => {
42
+ const rules = extractRuleNames(coreConfig as Record<string, unknown>[])
43
+
44
+ expect(rules).toMatchSnapshot()
45
+ })
46
+
47
+ it('typescript config rules should match snapshot', () => {
48
+ const rules = extractRuleNames(typescriptConfig as Record<string, unknown>[])
49
+
50
+ expect(rules).toMatchSnapshot()
51
+ })
52
+
53
+ it('react config rules should match snapshot', () => {
54
+ const rules = extractRuleNames(reactConfig as Record<string, unknown>[])
55
+
56
+ expect(rules).toMatchSnapshot()
57
+ })
58
+
59
+ it('next config rules should match snapshot', () => {
60
+ const rules = extractRuleNames(nextConfig as Record<string, unknown>[])
61
+
62
+ expect(rules).toMatchSnapshot()
63
+ })
64
+
65
+ it('astro config rules should match snapshot', () => {
66
+ const rules = extractRuleNames(astroConfig as Record<string, unknown>[])
67
+
68
+ expect(rules).toMatchSnapshot()
69
+ })
70
+
71
+ it('expo config rules should match snapshot', () => {
72
+ const rules = extractRuleNames(expoConfig as Record<string, unknown>[])
73
+
74
+ expect(rules).toMatchSnapshot()
75
+ })
76
+
77
+ it('nest config rules should match snapshot', () => {
78
+ const rules = extractRuleNames(nestConfig as Record<string, unknown>[])
79
+
80
+ expect(rules).toMatchSnapshot()
81
+ })
82
+ })
83
+
84
+ describe('Config Snapshots — Entry Names', () => {
85
+ it('core config entries should match snapshot', () => {
86
+ const names = extractConfigNames(coreConfig as Record<string, unknown>[])
87
+
88
+ expect(names).toMatchSnapshot()
89
+ })
90
+
91
+ it('typescript config entries should match snapshot', () => {
92
+ const names = extractConfigNames(typescriptConfig as Record<string, unknown>[])
93
+
94
+ expect(names).toMatchSnapshot()
95
+ })
96
+
97
+ it('react config entries should match snapshot', () => {
98
+ const names = extractConfigNames(reactConfig as Record<string, unknown>[])
99
+
100
+ expect(names).toMatchSnapshot()
101
+ })
102
+
103
+ it('next config entries should match snapshot', () => {
104
+ const names = extractConfigNames(nextConfig as Record<string, unknown>[])
105
+
106
+ expect(names).toMatchSnapshot()
107
+ })
108
+
109
+ it('astro config entries should match snapshot', () => {
110
+ const names = extractConfigNames(astroConfig as Record<string, unknown>[])
111
+
112
+ expect(names).toMatchSnapshot()
113
+ })
114
+
115
+ it('expo config entries should match snapshot', () => {
116
+ const names = extractConfigNames(expoConfig as Record<string, unknown>[])
117
+
118
+ expect(names).toMatchSnapshot()
119
+ })
120
+
121
+ it('nest config entries should match snapshot', () => {
122
+ const names = extractConfigNames(nestConfig as Record<string, unknown>[])
123
+
124
+ expect(names).toMatchSnapshot()
125
+ })
126
+ })
@@ -0,0 +1,10 @@
1
+ {
2
+ "extends": "../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "outDir": "./dist",
5
+ "rootDir": "./src",
6
+ "types": ["vitest/globals"]
7
+ },
8
+ "include": ["src/**/*.ts"],
9
+ "exclude": ["node_modules", "dist"]
10
+ }
@@ -0,0 +1,8 @@
1
+ import { defineConfig } from 'vitest/config'
2
+
3
+ export default defineConfig({
4
+ test: {
5
+ globals: true,
6
+ environment: 'node'
7
+ }
8
+ })
@@ -0,0 +1,14 @@
1
+ # @santi020k/eslint-config-typescript
2
+
3
+ TypeScript specific ESLint rules and configurations.
4
+
5
+ ## Description
6
+
7
+ This package provides:
8
+ - TypeScript parser configuration.
9
+ - `@typescript-eslint` recommended rules.
10
+ - Proper file globbing for `.ts` and `.tsx` files.
11
+
12
+ ## Usage
13
+
14
+ This package is used automatically when `ConfigOption.Ts` is selected in the main configuration.
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "@santi020k/eslint-config-typescript",
3
+ "version": "0.0.0",
4
+ "description": "TypeScript ESLint configuration",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": "./dist/index.js",
12
+ "types": "./dist/index.d.ts"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "scripts": {
19
+ "build": "tsup",
20
+ "dev": "tsup --watch",
21
+ "clean": "rm -rf dist"
22
+ },
23
+ "peerDependencies": {
24
+ "eslint": "^9.0.0",
25
+ "typescript": "^5.0.0"
26
+ },
27
+ "dependencies": {
28
+ "@santi020k/eslint-config-core": "*",
29
+ "@typescript-eslint/eslint-plugin": "^8.54.0",
30
+ "@typescript-eslint/parser": "^8.54.0",
31
+ "typescript-eslint": "^8.54.0"
32
+ },
33
+ "devDependencies": {
34
+ "@typescript-eslint/utils": "^8.54.0",
35
+ "tsup": "^8.5.1"
36
+ },
37
+ "publishConfig": {
38
+ "access": "public"
39
+ },
40
+ "license": "MIT",
41
+ "author": "santi020k",
42
+ "repository": {
43
+ "type": "git",
44
+ "url": "git+https://github.com/santi020k/eslint-config.git",
45
+ "directory": "packages/typescript"
46
+ }
47
+ }
@@ -0,0 +1,32 @@
1
+ import tsEslint from 'typescript-eslint'
2
+
3
+ import { rules } from './rules.js'
4
+
5
+ import tsParser from '@typescript-eslint/parser'
6
+ import type { TSESLint } from '@typescript-eslint/utils'
7
+
8
+ /**
9
+ * TypeScript ESLint configuration
10
+ * Extends typescript-eslint stylistic config with custom rules
11
+ */
12
+ export const typescriptConfig: TSESLint.FlatConfig.ConfigArray = [
13
+ ...tsEslint.configs.stylistic as TSESLint.FlatConfig.ConfigArray,
14
+ {
15
+ name: 'eslint-config-typescript/rules',
16
+ files: ['**/*.{ts,tsx,mts,cts}'],
17
+ rules,
18
+ languageOptions: {
19
+ parser: tsParser,
20
+ parserOptions: {
21
+ project: true
22
+ },
23
+ ecmaVersion: 'latest'
24
+ }
25
+ }
26
+ ]
27
+
28
+ // Legacy export for backwards compatibility
29
+ export { typescriptConfig as tsConfig }
30
+
31
+ // Re-export rules for direct access
32
+ export { rules }
@@ -0,0 +1,36 @@
1
+ import { rules as coreRules } from '@santi020k/eslint-config-core'
2
+ import type { TSESLint } from '@typescript-eslint/utils'
3
+
4
+ export const rules: TSESLint.Linter.RulesRecord = {
5
+ // Include core JS rules for TS files
6
+ ...coreRules,
7
+ // Disable conflicting rules
8
+ semi: 'off',
9
+ 'no-unused-vars': 'off',
10
+ '@typescript-eslint/indent': 'off',
11
+ // TypeScript-specific rules
12
+ '@typescript-eslint/no-unused-vars': [
13
+ 'warn',
14
+ {
15
+ vars: 'all',
16
+ varsIgnorePattern: '^_',
17
+ args: 'after-used',
18
+ argsIgnorePattern: '^_',
19
+ destructuredArrayIgnorePattern: '^_',
20
+ ignoreRestSiblings: true
21
+ }
22
+ ],
23
+ '@typescript-eslint/no-explicit-any': 'warn',
24
+ '@typescript-eslint/no-empty-function': 'warn',
25
+ '@typescript-eslint/no-empty-object-type': 'warn',
26
+ '@typescript-eslint/no-unsafe-function-type': 'warn',
27
+ '@typescript-eslint/no-wrapper-object-types': 'warn',
28
+ '@typescript-eslint/no-var-requires': 'warn',
29
+ '@typescript-eslint/ban-ts-comment': 'warn',
30
+ '@typescript-eslint/no-non-null-assertion': 'warn',
31
+ '@typescript-eslint/no-invalid-void-type': 'warn',
32
+ '@typescript-eslint/no-dynamic-delete': 'warn',
33
+ '@typescript-eslint/no-useless-constructor': 'warn',
34
+ '@typescript-eslint/prefer-for-of': 'warn',
35
+ '@typescript-eslint/no-duplicate-enum-values': 'warn'
36
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "extends": "../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "outDir": "./dist",
5
+ "rootDir": "./src"
6
+ },
7
+ "include": ["src/**/*.ts"],
8
+ "exclude": ["node_modules", "dist"]
9
+ }
@@ -0,0 +1,10 @@
1
+ import { defineConfig } from 'tsup'
2
+
3
+ export default defineConfig({
4
+ entry: ['src/index.ts'],
5
+ format: ['esm'],
6
+ dts: true,
7
+ clean: true,
8
+ splitting: false,
9
+ sourcemap: true
10
+ })
@@ -0,0 +1,20 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "Node16",
5
+ "lib": ["ES2023"],
6
+ "declaration": true,
7
+ "declarationMap": true,
8
+ "moduleResolution": "Node16",
9
+ "esModuleInterop": false,
10
+ "skipLibCheck": true,
11
+ "forceConsistentCasingInFileNames": true,
12
+ "strict": true,
13
+ "allowSyntheticDefaultImports": true,
14
+ "isolatedModules": true,
15
+ "resolveJsonModule": true,
16
+ "noEmit": true,
17
+ "allowImportingTsExtensions": true
18
+ },
19
+ "exclude": ["node_modules", "dist"]
20
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "extends": "./tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "noEmit": true
5
+ },
6
+ "include": [
7
+ "packages/core/src/**/*.ts",
8
+ "packages/typescript/src/**/*.ts",
9
+ "packages/react/src/**/*.ts",
10
+ "packages/next/src/**/*.ts",
11
+ "packages/astro/src/**/*.ts",
12
+ "packages/expo/src/**/*.ts",
13
+ "packages/nest/src/**/*.ts",
14
+ "packages/optionals/src/**/*.ts",
15
+ "packages/basic/src/**/*.ts"
16
+ ],
17
+ "exclude": ["node_modules", "dist", "**/*.test.ts"]
18
+ }