@dimensional-innovations/tool-config 4.0.0 → 5.0.1

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 (83) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +7 -120
  3. package/dist/cli/index.js +1812 -0
  4. package/dist/cli/index.js.map +1 -0
  5. package/dist/index.d.ts +401 -0
  6. package/dist/index.js +2644 -0
  7. package/dist/index.js.map +1 -0
  8. package/package.json +22 -15
  9. package/bin/lib/ci-setup.js +0 -142
  10. package/bin/lib/formatting.js +0 -103
  11. package/bin/lib/handlers/eslint.js +0 -61
  12. package/bin/lib/handlers/prettier.js +0 -83
  13. package/bin/lib/handlers/semantic-release.js +0 -60
  14. package/bin/lib/handlers/stylelint.js +0 -85
  15. package/bin/lib/handlers/typescript.js +0 -156
  16. package/bin/lib/package-manager.js +0 -201
  17. package/bin/lib/ui.js +0 -239
  18. package/bin/lib/uninstall.js +0 -199
  19. package/bin/lib/validators.js +0 -28
  20. package/bin/setup-tool-config.js +0 -442
  21. package/src/detectors.js +0 -286
  22. package/src/index.js +0 -69
  23. package/src/tools/eslint/index.js +0 -282
  24. package/src/tools/eslint/presets/base.js +0 -75
  25. package/src/tools/eslint/presets/environments/browser.js +0 -16
  26. package/src/tools/eslint/presets/environments/node.js +0 -21
  27. package/src/tools/eslint/presets/environments/universal.js +0 -18
  28. package/src/tools/eslint/presets/frameworks/angular.js +0 -80
  29. package/src/tools/eslint/presets/frameworks/astro.js +0 -43
  30. package/src/tools/eslint/presets/frameworks/node.js +0 -63
  31. package/src/tools/eslint/presets/frameworks/react.js +0 -81
  32. package/src/tools/eslint/presets/frameworks/solid.js +0 -50
  33. package/src/tools/eslint/presets/frameworks/svelte.js +0 -65
  34. package/src/tools/eslint/presets/frameworks/vanilla.js +0 -22
  35. package/src/tools/eslint/presets/frameworks/vue.js +0 -159
  36. package/src/tools/eslint/presets/imports.js +0 -47
  37. package/src/tools/eslint/presets/typescript.js +0 -142
  38. package/src/tools/prettier/README.md +0 -398
  39. package/src/tools/prettier/index.js +0 -132
  40. package/src/tools/prettier/presets/base.js +0 -36
  41. package/src/tools/prettier/presets/frameworks/astro.js +0 -15
  42. package/src/tools/prettier/presets/frameworks/react.js +0 -15
  43. package/src/tools/prettier/presets/frameworks/svelte.js +0 -22
  44. package/src/tools/prettier/presets/frameworks/vanilla.js +0 -13
  45. package/src/tools/prettier/presets/frameworks/vue.js +0 -21
  46. package/src/tools/prettier/presets/prettierignore.js +0 -57
  47. package/src/tools/semantic-release/CI_SETUP.md +0 -66
  48. package/src/tools/semantic-release/README.md +0 -533
  49. package/src/tools/semantic-release/index.js +0 -130
  50. package/src/tools/semantic-release/presets/default.js +0 -37
  51. package/src/tools/semantic-release/presets/library.js +0 -58
  52. package/src/tools/semantic-release/presets/monorepo.js +0 -48
  53. package/src/tools/semantic-release/templates/.gitlab-ci.yml +0 -89
  54. package/src/tools/semantic-release/templates/bitbucket-pipelines.yml +0 -100
  55. package/src/tools/semantic-release/templates/github-workflow.yml +0 -107
  56. package/src/tools/stylelint/README.md +0 -425
  57. package/src/tools/stylelint/index.js +0 -195
  58. package/src/tools/stylelint/presets/base.js +0 -50
  59. package/src/tools/stylelint/presets/css-modules.js +0 -43
  60. package/src/tools/stylelint/presets/frameworks/react.js +0 -18
  61. package/src/tools/stylelint/presets/frameworks/svelte.js +0 -28
  62. package/src/tools/stylelint/presets/frameworks/vanilla.js +0 -14
  63. package/src/tools/stylelint/presets/frameworks/vue.js +0 -38
  64. package/src/tools/stylelint/presets/scss.js +0 -83
  65. package/src/tools/stylelint/presets/tailwind.js +0 -49
  66. package/src/tools/typescript/README.md +0 -665
  67. package/src/tools/typescript/checker-detection.js +0 -113
  68. package/src/tools/typescript/index.js +0 -202
  69. package/src/tools/typescript/presets/base.js +0 -58
  70. package/src/tools/typescript/presets/environments/browser.js +0 -10
  71. package/src/tools/typescript/presets/environments/node.js +0 -11
  72. package/src/tools/typescript/presets/environments/universal.js +0 -11
  73. package/src/tools/typescript/presets/frameworks/angular.js +0 -11
  74. package/src/tools/typescript/presets/frameworks/astro.js +0 -11
  75. package/src/tools/typescript/presets/frameworks/electron.js +0 -100
  76. package/src/tools/typescript/presets/frameworks/node.js +0 -12
  77. package/src/tools/typescript/presets/frameworks/react.js +0 -10
  78. package/src/tools/typescript/presets/frameworks/solid.js +0 -11
  79. package/src/tools/typescript/presets/frameworks/svelte.js +0 -10
  80. package/src/tools/typescript/presets/frameworks/vanilla.js +0 -9
  81. package/src/tools/typescript/presets/frameworks/vue.js +0 -17
  82. package/src/utils/ignore-patterns.js +0 -157
  83. package/src/utils/package-reader.js +0 -42
@@ -1,142 +0,0 @@
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
- }
@@ -1,103 +0,0 @@
1
- /**
2
- * Formatting utilities for CLI output
3
- * Standardized box drawing with consistent width
4
- */
5
-
6
- import pc from 'picocolors'
7
-
8
- const BOX_WIDTH = 70 // Standard width for all boxes
9
-
10
- export const BOX = {
11
- topLeft: '┌',
12
- topRight: '┐',
13
- bottomLeft: '└',
14
- bottomRight: '┘',
15
- vertical: '│',
16
- horizontal: '─',
17
- separator: '━',
18
- width: BOX_WIDTH
19
- }
20
-
21
- /**
22
- * Create a box with standard width (70 chars)
23
- * @param {string[]} lines - Array of content lines
24
- * @param {string} title - Optional title for top border
25
- * @returns {string} Formatted box
26
- */
27
- export function createBox(lines, title = '') {
28
- const width = BOX.width
29
- const contentWidth = width - 4 // Remove: │ + space + space + │
30
-
31
- // Create top border
32
- let top
33
- if (title) {
34
- const titlePart = `─ ${title} `
35
- const remaining = width - 2 - titlePart.length // -2 for corners
36
- top = BOX.topLeft + titlePart + BOX.horizontal.repeat(remaining) + BOX.topRight
37
- } else {
38
- top = BOX.topLeft + BOX.horizontal.repeat(width - 2) + BOX.topRight
39
- }
40
-
41
- // Create content lines - pad each to exact width
42
- const content = lines.map(line => {
43
- const padded = line.slice(0, contentWidth).padEnd(contentWidth)
44
- return `${BOX.vertical} ${padded} ${BOX.vertical}`
45
- })
46
-
47
- // Create bottom border
48
- const bottom = BOX.bottomLeft + BOX.horizontal.repeat(width - 2) + BOX.bottomRight
49
-
50
- return [top, ...content, bottom].join('\n')
51
- }
52
-
53
- /**
54
- * Create a separator line
55
- * @returns {string} Separator line
56
- */
57
- export function createSeparator() {
58
- return BOX.separator.repeat(BOX.width)
59
- }
60
-
61
- /**
62
- * Create a simple indented list
63
- * @param {string[]} items - Array of items
64
- * @param {string} bullet - Bullet character (default: '•')
65
- * @returns {string} Formatted list
66
- */
67
- export function createList(items, bullet = '•') {
68
- return items.map(item => ` ${bullet} ${item}`).join('\n')
69
- }
70
-
71
- /**
72
- * Create a progress indicator
73
- * @param {number} current - Current step
74
- * @param {number} total - Total steps
75
- * @param {string} label - Label for this step
76
- * @returns {string} Progress line
77
- */
78
- export function createProgress(current, total, label) {
79
- return ` [${current}/${total}] ${label}`
80
- }
81
-
82
- /**
83
- * Color symbols for CLI output
84
- */
85
- export const SYMBOLS = {
86
- success: pc.green('✓'),
87
- warning: pc.yellow('⚠'),
88
- error: pc.red('✗'),
89
- info: pc.blue('ℹ')
90
- }
91
-
92
- /**
93
- * Color helper functions
94
- */
95
- export const colors = {
96
- success: pc.green,
97
- warning: pc.yellow,
98
- error: pc.red,
99
- info: pc.blue,
100
- dim: pc.dim,
101
- bold: pc.bold,
102
- cyan: pc.cyan
103
- }
@@ -1,61 +0,0 @@
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
- }
@@ -1,83 +0,0 @@
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
- }
@@ -1,60 +0,0 @@
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
- }
@@ -1,85 +0,0 @@
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}" --allow-empty-input`,
55
- 'style:fix': `stylelint "${pattern}" --fix --allow-empty-input`
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
- }
@@ -1,156 +0,0 @@
1
- /**
2
- * TypeScript handler for setup-tool-config CLI
3
- */
4
-
5
- import { existsSync, writeFileSync } from 'fs'
6
- import { join } from 'path'
7
-
8
- import {
9
- detectTypeChecker,
10
- getTypeCheckCommand
11
- } from '../../../src/tools/typescript/checker-detection.js'
12
-
13
- /**
14
- * Get config filename
15
- */
16
- export function getConfigFilename() {
17
- return 'tsconfig.json'
18
- }
19
-
20
- /**
21
- * Generate config file content for standard (non-Electron) projects
22
- */
23
- export function generateConfigContent() {
24
- return JSON.stringify(
25
- {
26
- $schema: 'https://json.schemastore.org/tsconfig',
27
- compilerOptions: {
28
- target: 'ES2022',
29
- lib: ['ES2022'],
30
- module: 'ESNext',
31
- moduleResolution: 'Bundler',
32
- strict: true,
33
- esModuleInterop: true,
34
- skipLibCheck: true,
35
- forceConsistentCasingInFileNames: true,
36
- resolveJsonModule: true
37
- },
38
- include: ['src/**/*'],
39
- exclude: ['node_modules', 'dist', 'build', 'out', 'coverage']
40
- },
41
- null,
42
- 2
43
- )
44
- }
45
-
46
- /**
47
- * Get npm scripts based on detected framework and type checker
48
- */
49
- export function getScripts(detected) {
50
- // Electron uses tsc --build for project references
51
- if (detected.electron) {
52
- return {
53
- typecheck: 'tsc --build',
54
- 'typecheck:watch': 'tsc --build --watch'
55
- }
56
- }
57
-
58
- // Standard single-config
59
- const checker = detectTypeChecker(detected.framework, 'auto')
60
- const cmd = getTypeCheckCommand(checker)
61
- const watchCmd = getTypeCheckCommand(checker, { watch: true })
62
-
63
- return {
64
- typecheck: cmd,
65
- 'typecheck:watch': watchCmd
66
- }
67
- }
68
-
69
- /**
70
- * Write Electron multi-config TypeScript files
71
- */
72
- async function writeElectronConfigs(detected, cwd, dryRun = false) {
73
- const files = [
74
- { name: 'tsconfig.json', key: 'root', desc: 'root orchestrator' },
75
- { name: 'tsconfig.node.json', key: 'node', desc: 'main process' },
76
- { name: 'tsconfig.web.json', key: 'web', desc: 'renderer process' },
77
- { name: 'tsconfig.tests.json', key: 'tests', desc: 'test environment' }
78
- ]
79
-
80
- if (dryRun) {
81
- for (const file of files) {
82
- console.log(` 📄 Would create: ${file.name} (${file.desc})`)
83
- }
84
- return true
85
- }
86
-
87
- try {
88
- // Import the factory and generate configs
89
- const { createTypescriptConfig } = await import('../../../src/tools/typescript/index.js')
90
- const configs = await createTypescriptConfig({
91
- electron: true,
92
- renderer: detected.framework,
93
- cwd
94
- })
95
-
96
- // Write all 4 files
97
- let created = 0
98
- for (const file of files) {
99
- const filepath = join(cwd, file.name)
100
-
101
- if (existsSync(filepath)) {
102
- console.log(` ⚠️ ${file.name} already exists - skipping`)
103
- continue
104
- }
105
-
106
- const content = JSON.stringify(configs[file.key], null, 2)
107
- writeFileSync(filepath, `${content}\n`, 'utf8')
108
- console.log(` ✅ Created: ${file.name} (${file.desc})`)
109
- created++
110
- }
111
-
112
- return created > 0
113
- } catch (error) {
114
- console.error(' ❌ Failed to create Electron configs:', error.message)
115
- return false
116
- }
117
- }
118
-
119
- /**
120
- * Write config file
121
- */
122
- export function writeConfig(cwd, detected, dryRun = false) {
123
- // TypeScript tool requires TypeScript to be detected
124
- if (!detected.typescript) {
125
- console.log(' ⚠️ TypeScript not detected - skipping tsconfig generation')
126
- return false
127
- }
128
-
129
- // Special handling for TypeScript with Electron
130
- if (detected.electron) {
131
- return writeElectronConfigs(detected, cwd, dryRun)
132
- }
133
-
134
- const filename = getConfigFilename()
135
- const filepath = join(cwd, filename)
136
- const content = generateConfigContent()
137
-
138
- if (existsSync(filepath)) {
139
- console.log(` ⚠️ ${filename} already exists - skipping`)
140
- return false
141
- }
142
-
143
- if (dryRun) {
144
- console.log(` 📄 Would create: ${filename}`)
145
- return true
146
- }
147
-
148
- try {
149
- writeFileSync(filepath, content, 'utf8')
150
- console.log(` ✅ Created: ${filename}`)
151
- return true
152
- } catch (error) {
153
- console.error(` ❌ Failed to create ${filename}:`, error.message)
154
- return false
155
- }
156
- }