@dimensional-innovations/tool-config 1.4.0 → 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.
Files changed (31) hide show
  1. package/README.md +72 -18
  2. package/bin/lib/ci-setup.js +142 -0
  3. package/bin/lib/handlers/eslint.js +61 -0
  4. package/bin/lib/handlers/prettier.js +83 -0
  5. package/bin/lib/handlers/semantic-release.js +60 -0
  6. package/bin/lib/handlers/stylelint.js +85 -0
  7. package/bin/lib/handlers/typescript.js +156 -0
  8. package/bin/lib/package-manager.js +114 -0
  9. package/bin/lib/ui.js +111 -0
  10. package/bin/lib/validators.js +28 -0
  11. package/bin/setup-tool-config.js +112 -596
  12. package/package.json +16 -4
  13. package/src/detectors.js +27 -2
  14. package/src/index.js +8 -3
  15. package/src/tools/eslint/presets/frameworks/vue.js +4 -0
  16. package/src/tools/typescript/README.md +665 -0
  17. package/src/tools/typescript/checker-detection.js +113 -0
  18. package/src/tools/typescript/index.js +202 -0
  19. package/src/tools/typescript/presets/base.js +58 -0
  20. package/src/tools/typescript/presets/environments/browser.js +10 -0
  21. package/src/tools/typescript/presets/environments/node.js +11 -0
  22. package/src/tools/typescript/presets/environments/universal.js +11 -0
  23. package/src/tools/typescript/presets/frameworks/angular.js +11 -0
  24. package/src/tools/typescript/presets/frameworks/astro.js +11 -0
  25. package/src/tools/typescript/presets/frameworks/electron.js +100 -0
  26. package/src/tools/typescript/presets/frameworks/node.js +12 -0
  27. package/src/tools/typescript/presets/frameworks/react.js +10 -0
  28. package/src/tools/typescript/presets/frameworks/solid.js +11 -0
  29. package/src/tools/typescript/presets/frameworks/svelte.js +10 -0
  30. package/src/tools/typescript/presets/frameworks/vanilla.js +9 -0
  31. package/src/tools/typescript/presets/frameworks/vue.js +17 -0
package/README.md CHANGED
@@ -1,15 +1,15 @@
1
1
  # @dimensional-innovations/tool-config
2
2
 
3
- > Universal configuration package for ESLint, Prettier, Stylelint, and semantic-release with automatic framework detection.
3
+ > Universal configuration package for ESLint, Prettier, Stylelint, TypeScript, and semantic-release with automatic framework detection.
4
4
 
5
5
  [![npm version](https://img.shields.io/npm/v/@dimensional-innovations/tool-config.svg)](https://www.npmjs.com/package/@dimensional-innovations/tool-config)
6
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
7
  [![Node Version](https://img.shields.io/badge/node-%3E%3D22.12.0-brightgreen.svg)](https://nodejs.org/)
8
8
  [![Test Coverage](https://img.shields.io/badge/coverage-100%25-brightgreen.svg)](./tests/)
9
9
 
10
- **One package. Four tools. Zero configuration.**
10
+ **One package. Five tools. Zero configuration.**
11
11
 
12
- Stop juggling multiple config packages. This single package provides battle-tested configurations for ESLint, Prettier, Stylelint, and semantic-release that automatically detect your project's framework, environment, and TypeScript setup.
12
+ Stop juggling multiple config packages. This single package provides battle-tested configurations for ESLint, Prettier, Stylelint, TypeScript, and semantic-release that automatically detect your project's framework, environment, and TypeScript setup.
13
13
 
14
14
  ## Why This Package?
15
15
 
@@ -34,12 +34,12 @@ npm install --save-dev @dimensional-innovations/tool-config
34
34
  ## Features
35
35
 
36
36
  - 🎯 **Zero Configuration** - Auto-detects your framework, environment, and TypeScript
37
- - 🧰 **Multi-Tool Support** - ESLint, Prettier, Stylelint, semantic-release in one package
37
+ - 🧰 **Multi-Tool Support** - ESLint, Prettier, Stylelint, TypeScript, semantic-release in one package
38
38
  - ⚛️ **8+ Frameworks** - React, Vue, Svelte, Solid, Astro, Angular, Vanilla JS, Node.js
39
39
  - 📦 **All-In-One** - All plugins and parsers included as dependencies
40
40
  - 🔧 **Customizable** - Override any setting while keeping smart defaults
41
- - 🚀 **Modern** - ESLint 9+ flat config, latest tooling versions
42
- - ✅ **Battle-Tested** - 369 tests with 100% coverage
41
+ - 🚀 **Modern** - ESLint 9+ flat config, TypeScript with tsgo support (10x faster)
42
+ - ✅ **Battle-Tested** - 535 tests with 100% coverage
43
43
 
44
44
  ## Quick Start
45
45
 
@@ -83,6 +83,22 @@ import { createConfig } from '@dimensional-innovations/tool-config'
83
83
  export default createConfig('stylelint')
84
84
  ```
85
85
 
86
+ **TypeScript** (`tsconfig.json`):
87
+
88
+ ```json
89
+ {
90
+ "$schema": "https://json.schemastore.org/tsconfig",
91
+ "compilerOptions": {
92
+ "strict": true,
93
+ "skipLibCheck": true
94
+ },
95
+ "include": ["src/**/*"],
96
+ "exclude": ["node_modules"]
97
+ }
98
+ ```
99
+
100
+ Or use the factory function to generate framework-specific TypeScript configs programmatically.
101
+
86
102
  **semantic-release** (`release.config.js`):
87
103
 
88
104
  ```javascript
@@ -103,23 +119,25 @@ That's it! The configs will automatically detect your framework and TypeScript s
103
119
  "prettier": "prettier --check .",
104
120
  "prettier:fix": "prettier --write .",
105
121
  "style": "stylelint '**/*.css'",
106
- "style:fix": "stylelint '**/*.css' --fix"
122
+ "style:fix": "stylelint '**/*.css' --fix",
123
+ "typecheck": "tsc --noEmit",
124
+ "typecheck:watch": "tsc --noEmit --watch"
107
125
  }
108
126
  }
109
127
  ```
110
128
 
111
129
  ## Supported Frameworks
112
130
 
113
- | Framework | ESLint | Prettier | Stylelint | Auto-Detect |
114
- | --------- | ------ | -------- | ------------------- | ----------- |
115
- | React | ✅ | ✅ | ✅ CSS Modules | ✅ |
116
- | Vue | ✅ | ✅ | ✅ Scoped Styles | ✅ |
117
- | Svelte | ✅ | ✅ | ✅ Component Styles | ✅ |
118
- | Solid | ✅ | ✅ | ✅ CSS Modules | ✅ |
119
- | Astro | ✅ | ✅ | ✅ | ✅ |
120
- | Angular | ✅ | ✅ | ✅ | ✅ |
121
- | Vanilla | ✅ | ✅ | ✅ | ✅ |
122
- | Node.js | ✅ | ✅ | N/A | ✅ |
131
+ | Framework | ESLint | Prettier | Stylelint | TypeScript | Auto-Detect |
132
+ | --------- | ------ | -------- | ------------------- | --------------- | ----------- |
133
+ | React | ✅ | ✅ | ✅ CSS Modules | ✅ react-jsx | ✅ |
134
+ | Vue | ✅ | ✅ | ✅ Scoped Styles | ✅ vue-tsc | ✅ |
135
+ | Svelte | ✅ | ✅ | ✅ Component Styles | ✅ svelte types | ✅ |
136
+ | Solid | ✅ | ✅ | ✅ CSS Modules | ✅ solid-js | ✅ |
137
+ | Astro | ✅ | ✅ | ✅ | ✅ astro/client | ✅ |
138
+ | Angular | ✅ | ✅ | ✅ | ✅ decorators | ✅ |
139
+ | Vanilla | ✅ | ✅ | ✅ | ✅ browser | ✅ |
140
+ | Node.js | ✅ | ✅ | N/A | ✅ NodeNext | ✅ |
123
141
 
124
142
  **Meta-frameworks**: Next.js (→ React), Nuxt (→ Vue), SvelteKit (→ Svelte)
125
143
 
@@ -131,7 +149,7 @@ The main factory function that creates configurations for any supported tool.
131
149
 
132
150
  **Parameters:**
133
151
 
134
- - `tool` (string, required): Tool name - `'eslint'`, `'prettier'`, `'stylelint'`, or `'semantic-release'`
152
+ - `tool` (string, required): Tool name - `'eslint'`, `'prettier'`, `'stylelint'`, `'typescript'`, or `'semantic-release'`
135
153
  - `options` (object, optional): Configuration options
136
154
 
137
155
  **Common Options:**
@@ -219,6 +237,42 @@ export default createConfig('stylelint', {
219
237
  })
220
238
  ```
221
239
 
240
+ ### TypeScript Options
241
+
242
+ ```javascript
243
+ await createConfig('typescript', {
244
+ framework: 'auto', // Auto-detect or specify framework
245
+ environment: 'auto', // 'auto' | 'browser' | 'node' | 'universal'
246
+ checker: 'auto', // 'auto' | 'modern' (tsgo) | 'legacy' (tsc/vue-tsc)
247
+ strict: true, // Enable strict type checking
248
+ compilerOptions: {} // Custom TypeScript compiler options
249
+ })
250
+ ```
251
+
252
+ **Example - React with Custom Options:**
253
+
254
+ ```javascript
255
+ export default await createConfig('typescript', {
256
+ framework: 'react',
257
+ compilerOptions: {
258
+ baseUrl: '.',
259
+ paths: {
260
+ '@/*': ['src/*']
261
+ }
262
+ }
263
+ })
264
+ ```
265
+
266
+ **Example - Use tsgo for 10x Faster Type Checking:**
267
+
268
+ ```javascript
269
+ export default await createConfig('typescript', {
270
+ checker: 'modern' // Forces tsgo when installed
271
+ })
272
+ ```
273
+
274
+ **tsgo Support:** Install `@typescript/native-preview` for 10x faster type checking. The package automatically detects and uses tsgo when available.
275
+
222
276
  ### semantic-release Options
223
277
 
224
278
  ```javascript
@@ -0,0 +1,142 @@
1
+ /**
2
+ * CI/CD setup utilities for setup-tool-config CLI
3
+ * Handles CI template copying and configuration
4
+ */
5
+
6
+ import { copyFileSync, existsSync, mkdirSync } from 'fs'
7
+ import { dirname, join } from 'path'
8
+ import { fileURLToPath } from 'url'
9
+
10
+ // eslint-disable-next-line @typescript-eslint/naming-convention
11
+ const __filename = fileURLToPath(import.meta.url)
12
+ // eslint-disable-next-line @typescript-eslint/naming-convention
13
+ const __dirname = dirname(__filename)
14
+
15
+ /**
16
+ * Get CI filename and path for a git provider
17
+ */
18
+ function getCIFileInfo(provider) {
19
+ const ciFiles = {
20
+ gitlab: {
21
+ filename: '.gitlab-ci.yml',
22
+ destination: '.gitlab-ci.yml',
23
+ template: '.gitlab-ci.yml'
24
+ },
25
+ github: {
26
+ filename: 'ci.yml',
27
+ destination: '.github/workflows/ci.yml',
28
+ template: 'github-workflow.yml',
29
+ needsDir: true
30
+ },
31
+ bitbucket: {
32
+ filename: 'bitbucket-pipelines.yml',
33
+ destination: 'bitbucket-pipelines.yml',
34
+ template: 'bitbucket-pipelines.yml'
35
+ }
36
+ }
37
+
38
+ return ciFiles[provider] || null
39
+ }
40
+
41
+ /**
42
+ * Get environment variable instructions for a git provider
43
+ */
44
+ function getCIInstructions(provider) {
45
+ const instructions = {
46
+ gitlab: `
47
+ ⚠️ Configuration Required:
48
+ Add these CI/CD variables in GitLab Settings > CI/CD > Variables:
49
+ - GL_TOKEN: GitLab Personal Access Token (with api scope)
50
+ - NPM_TOKEN: npm authentication token
51
+
52
+ Then push to main branch to trigger automated releases.`,
53
+ github: `
54
+ ⚠️ Configuration Required:
55
+ Add these secrets in GitHub Settings > Secrets and variables > Actions:
56
+ - GITHUB_TOKEN: Automatically provided by GitHub Actions
57
+ - NPM_TOKEN: npm authentication token
58
+
59
+ Then push to main branch to trigger automated releases.`,
60
+ bitbucket: `
61
+ ⚠️ Configuration Required:
62
+ Add this repository variable in Bitbucket Settings > Pipelines > Repository variables:
63
+ - NPM_TOKEN: npm authentication token
64
+
65
+ Then push to main branch to trigger automated releases.`
66
+ }
67
+
68
+ return instructions[provider] || ''
69
+ }
70
+
71
+ /**
72
+ * Copy CI/CD template
73
+ */
74
+ export function copyCITemplate(provider, cwd, dryRun = false) {
75
+ if (!provider || provider === 'unknown') {
76
+ console.log(' ⚠️ Could not detect git provider - skipping CI setup')
77
+ console.log(' 💡 You can manually copy templates from:')
78
+ console.log(
79
+ ' node_modules/@dimensional-innovations/tool-config/src/tools/semantic-release/templates/'
80
+ )
81
+ return false
82
+ }
83
+
84
+ const ciInfo = getCIFileInfo(provider)
85
+
86
+ if (!ciInfo) {
87
+ console.log(` ⚠️ Unsupported git provider: ${provider}`)
88
+ return false
89
+ }
90
+
91
+ const destPath = join(cwd, ciInfo.destination)
92
+ const destDir = dirname(destPath)
93
+
94
+ // Check if CI file already exists
95
+ if (existsSync(destPath)) {
96
+ console.log(` ⚠️ ${ciInfo.destination} already exists - skipping`)
97
+ return false
98
+ }
99
+
100
+ if (dryRun) {
101
+ console.log(` 📄 Would create: ${ciInfo.destination}`)
102
+ if (ciInfo.needsDir && !existsSync(destDir)) {
103
+ console.log(` 📁 Would create directory: ${dirname(ciInfo.destination)}`)
104
+ }
105
+ return true
106
+ }
107
+
108
+ try {
109
+ // Create directory if needed
110
+ if (ciInfo.needsDir && !existsSync(destDir)) {
111
+ mkdirSync(destDir, { recursive: true })
112
+ console.log(` ✅ Created directory: ${dirname(ciInfo.destination)}`)
113
+ }
114
+
115
+ // Copy template
116
+ const templatePath = join(
117
+ __dirname,
118
+ '..',
119
+ '..',
120
+ 'src',
121
+ 'tools',
122
+ 'semantic-release',
123
+ 'templates',
124
+ ciInfo.template
125
+ )
126
+ copyFileSync(templatePath, destPath)
127
+ console.log(` ✅ Created: ${ciInfo.destination}`)
128
+
129
+ // Show configuration instructions
130
+ console.log(getCIInstructions(provider))
131
+
132
+ console.log('\n 📖 For more details, see:')
133
+ console.log(
134
+ ' node_modules/@dimensional-innovations/tool-config/src/tools/semantic-release/CI_SETUP.md'
135
+ )
136
+
137
+ return true
138
+ } catch (error) {
139
+ console.error(` ❌ Failed to copy CI template:`, error.message)
140
+ return false
141
+ }
142
+ }
@@ -0,0 +1,61 @@
1
+ /**
2
+ * ESLint handler for setup-tool-config CLI
3
+ */
4
+
5
+ import { existsSync, writeFileSync } from 'fs'
6
+ import { join } from 'path'
7
+
8
+ /**
9
+ * Get config filename
10
+ */
11
+ export function getConfigFilename() {
12
+ return 'eslint.config.js'
13
+ }
14
+
15
+ /**
16
+ * Generate config file content
17
+ */
18
+ export function generateConfigContent() {
19
+ return `import { createConfig } from '@dimensional-innovations/tool-config'
20
+
21
+ export default await createConfig('eslint')
22
+ `
23
+ }
24
+
25
+ /**
26
+ * Get npm scripts
27
+ */
28
+ export function getScripts() {
29
+ return {
30
+ lint: 'eslint .',
31
+ 'lint:fix': 'eslint --fix .'
32
+ }
33
+ }
34
+
35
+ /**
36
+ * Write config file
37
+ */
38
+ export function writeConfig(cwd, _detected, dryRun = false) {
39
+ const filename = getConfigFilename()
40
+ const filepath = join(cwd, filename)
41
+ const content = generateConfigContent()
42
+
43
+ if (existsSync(filepath)) {
44
+ console.log(` ⚠️ ${filename} already exists - skipping`)
45
+ return false
46
+ }
47
+
48
+ if (dryRun) {
49
+ console.log(` 📄 Would create: ${filename}`)
50
+ return true
51
+ }
52
+
53
+ try {
54
+ writeFileSync(filepath, content, 'utf8')
55
+ console.log(` ✅ Created: ${filename}`)
56
+ return true
57
+ } catch (error) {
58
+ console.error(` ❌ Failed to create ${filename}:`, error.message)
59
+ return false
60
+ }
61
+ }
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Prettier handler for setup-tool-config CLI
3
+ */
4
+
5
+ import { existsSync, writeFileSync } from 'fs'
6
+ import { join } from 'path'
7
+
8
+ import { prettierIgnoreContent } from '../../../src/tools/prettier/index.js'
9
+
10
+ /**
11
+ * Get config filename
12
+ */
13
+ export function getConfigFilename() {
14
+ return 'prettier.config.js'
15
+ }
16
+
17
+ /**
18
+ * Generate config file content
19
+ */
20
+ export function generateConfigContent() {
21
+ return `import { createConfig } from '@dimensional-innovations/tool-config'
22
+
23
+ export default createConfig('prettier')
24
+ `
25
+ }
26
+
27
+ /**
28
+ * Get npm scripts
29
+ */
30
+ export function getScripts() {
31
+ return {
32
+ 'prettier:fix': 'prettier --write .',
33
+ prettier: 'prettier --check .'
34
+ }
35
+ }
36
+
37
+ /**
38
+ * Write config file
39
+ */
40
+ export function writeConfig(cwd, _detected, dryRun = false) {
41
+ const filename = getConfigFilename()
42
+ const filepath = join(cwd, filename)
43
+ const content = generateConfigContent()
44
+
45
+ if (existsSync(filepath)) {
46
+ console.log(` ⚠️ ${filename} already exists - skipping`)
47
+ return false
48
+ }
49
+
50
+ if (dryRun) {
51
+ console.log(` 📄 Would create: ${filename}`)
52
+
53
+ // Prettier also creates .prettierignore
54
+ const ignoreFile = '.prettierignore'
55
+ const ignoreExists = existsSync(join(cwd, ignoreFile))
56
+ if (!ignoreExists) {
57
+ console.log(` 📄 Would create: ${ignoreFile}`)
58
+ }
59
+
60
+ return true
61
+ }
62
+
63
+ try {
64
+ writeFileSync(filepath, content, 'utf8')
65
+ console.log(` ✅ Created: ${filename}`)
66
+
67
+ // Prettier also creates .prettierignore
68
+ const ignoreFile = '.prettierignore'
69
+ const ignorePath = join(cwd, ignoreFile)
70
+
71
+ if (!existsSync(ignorePath)) {
72
+ writeFileSync(ignorePath, prettierIgnoreContent, 'utf8')
73
+ console.log(` ✅ Created: ${ignoreFile}`)
74
+ } else {
75
+ console.log(` ⚠️ ${ignoreFile} already exists - skipping`)
76
+ }
77
+
78
+ return true
79
+ } catch (error) {
80
+ console.error(` ❌ Failed to create ${filename}:`, error.message)
81
+ return false
82
+ }
83
+ }
@@ -0,0 +1,60 @@
1
+ /**
2
+ * semantic-release handler for setup-tool-config CLI
3
+ */
4
+
5
+ import { existsSync, writeFileSync } from 'fs'
6
+ import { join } from 'path'
7
+
8
+ /**
9
+ * Get config filename
10
+ */
11
+ export function getConfigFilename() {
12
+ return 'release.config.js'
13
+ }
14
+
15
+ /**
16
+ * Generate config file content
17
+ */
18
+ export function generateConfigContent() {
19
+ return `import { createConfig } from '@dimensional-innovations/tool-config'
20
+
21
+ export default createConfig('semantic-release')
22
+ `
23
+ }
24
+
25
+ /**
26
+ * Get npm scripts
27
+ */
28
+ export function getScripts() {
29
+ return {
30
+ release: 'semantic-release'
31
+ }
32
+ }
33
+
34
+ /**
35
+ * Write config file
36
+ */
37
+ export function writeConfig(cwd, _detected, dryRun = false) {
38
+ const filename = getConfigFilename()
39
+ const filepath = join(cwd, filename)
40
+ const content = generateConfigContent()
41
+
42
+ if (existsSync(filepath)) {
43
+ console.log(` ⚠️ ${filename} already exists - skipping`)
44
+ return false
45
+ }
46
+
47
+ if (dryRun) {
48
+ console.log(` 📄 Would create: ${filename}`)
49
+ return true
50
+ }
51
+
52
+ try {
53
+ writeFileSync(filepath, content, 'utf8')
54
+ console.log(` ✅ Created: ${filename}`)
55
+ return true
56
+ } catch (error) {
57
+ console.error(` ❌ Failed to create ${filename}:`, error.message)
58
+ return false
59
+ }
60
+ }
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Stylelint handler for setup-tool-config CLI
3
+ */
4
+
5
+ import { existsSync, writeFileSync } from 'fs'
6
+ import { join } from 'path'
7
+
8
+ /**
9
+ * Get config filename
10
+ */
11
+ export function getConfigFilename() {
12
+ return 'stylelint.config.js'
13
+ }
14
+
15
+ /**
16
+ * Generate config file content
17
+ */
18
+ export function generateConfigContent() {
19
+ return `import { createConfig } from '@dimensional-innovations/tool-config'
20
+
21
+ export default createConfig('stylelint')
22
+ `
23
+ }
24
+
25
+ /**
26
+ * Get file extensions for Stylelint based on framework and CSS type
27
+ */
28
+ function getStylelintExtensions(framework, cssType) {
29
+ const extensions = ['css']
30
+
31
+ // Add preprocessor extensions
32
+ if (cssType.preprocessor === 'scss') {
33
+ extensions.push('scss')
34
+ } else if (cssType.preprocessor === 'less') {
35
+ extensions.push('less')
36
+ }
37
+
38
+ // Add framework-specific extensions
39
+ if (framework === 'vue') extensions.push('vue')
40
+ if (framework === 'svelte') extensions.push('svelte')
41
+
42
+ return extensions
43
+ }
44
+
45
+ /**
46
+ * Get npm scripts based on detected framework and CSS type
47
+ */
48
+ export function getScripts(detected) {
49
+ const extensions = getStylelintExtensions(detected.framework, detected.cssType)
50
+ const pattern =
51
+ extensions.length === 1 ? `**/*.${extensions[0]}` : `**/*.{${extensions.join(',')}}`
52
+
53
+ return {
54
+ style: `stylelint "${pattern}"`,
55
+ 'style:fix': `stylelint "${pattern}" --fix`
56
+ }
57
+ }
58
+
59
+ /**
60
+ * Write config file
61
+ */
62
+ export function writeConfig(cwd, _detected, dryRun = false) {
63
+ const filename = getConfigFilename()
64
+ const filepath = join(cwd, filename)
65
+ const content = generateConfigContent()
66
+
67
+ if (existsSync(filepath)) {
68
+ console.log(` ⚠️ ${filename} already exists - skipping`)
69
+ return false
70
+ }
71
+
72
+ if (dryRun) {
73
+ console.log(` 📄 Would create: ${filename}`)
74
+ return true
75
+ }
76
+
77
+ try {
78
+ writeFileSync(filepath, content, 'utf8')
79
+ console.log(` ✅ Created: ${filename}`)
80
+ return true
81
+ } catch (error) {
82
+ console.error(` ❌ Failed to create ${filename}:`, error.message)
83
+ return false
84
+ }
85
+ }