@mouse_484/eslint-config 3.5.14 → 3.5.16

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 (2) hide show
  1. package/bin/cli.js +93 -46
  2. package/package.json +1 -1
package/bin/cli.js CHANGED
@@ -1,18 +1,16 @@
1
1
  #!/usr/bin/env node
2
- import { exec as _exec, spawn } from 'node:child_process'
2
+ import { execSync, spawn } from 'node:child_process'
3
3
  import fs from 'node:fs/promises'
4
4
  import path from 'node:path'
5
5
  import process from 'node:process'
6
- import { promisify } from 'node:util'
7
6
  import { resolveCommand } from 'package-manager-detector/commands'
8
7
  import { detect } from 'package-manager-detector/detect'
9
8
 
10
- const exec = promisify(_exec)
11
-
12
9
  /**
13
10
  * @typedef {object} PackageInfo
14
11
  * @property {string} name - Package name
15
12
  * @property {string} import - Import name in config
13
+ * @property {string} [version] - Package version
16
14
  */
17
15
 
18
16
  /** @type {PackageInfo} */
@@ -27,64 +25,114 @@ const TARGET = {
27
25
  import: 'mouse',
28
26
  }
29
27
 
28
+ const PACKAGE_JSON_FILE = 'package.json'
29
+ const ESLINT_CONFIG_JS_FILE = 'eslint.config.js'
30
+ const ESLINT_CONFIG_MJS_FILE = 'eslint.config.mjs'
31
+
32
+ // infinite loop prevention
33
+ const isRunningFromSourcePackage = process.argv[1].includes(SOURCE.name)
34
+
30
35
  /**
31
- *
32
- * @param {string} command
33
- * @param {string} args
34
- * @param {import('node:child_process').SpawnOptions} options
35
- * @returns {Promise} - Promise Spawn Result
36
+ * Execute command with spawn
37
+ * @param {string} command - Command to execute
38
+ * @param {string[]} args - Command arguments
39
+ * @returns {Promise<void>}
36
40
  */
37
- function spawnAsync(command, args, options = { stdio: 'inherit' }) {
41
+ function runCommand(command, args = []) {
42
+ console.info(`Running: ${command} ${args.join(' ')}`)
43
+ const spawnedProcess = spawn(command, args, { stdio: 'inherit' })
44
+
38
45
  return new Promise((resolve, reject) => {
39
- const child = spawn(command, args, options)
40
- child.on('close', resolve)
41
- child.on('error', reject)
42
- }).catch(console.error)
46
+ spawnedProcess.on('close', (code) => {
47
+ if (code === 0) {
48
+ setTimeout(() => {
49
+ resolve()
50
+ }, 300)
51
+ }
52
+ else {
53
+ reject(new Error(`Command failed with exit code ${code}`))
54
+ }
55
+ })
56
+ spawnedProcess.on('error', reject)
57
+ })
58
+ }
59
+
60
+ /**
61
+ * Update JSON file with transform function
62
+ * @param {string} filePath - JSON file path
63
+ * @param {(data: any) => any} updateFn - Transform function
64
+ */
65
+ async function updateJSONFile(filePath, updateFn) {
66
+ const content = await fs.readFile(filePath, 'utf-8')
67
+ const data = JSON.parse(content)
68
+ const updated = updateFn(data)
69
+ await fs.writeFile(filePath, JSON.stringify(updated, null, 2))
70
+ return updated
43
71
  }
44
72
 
45
73
  async function main() {
46
74
  console.info('Starting ESLint config setup...')
47
75
 
76
+ if (isRunningFromSourcePackage) {
77
+ console.error(
78
+ `Please run this script from the root of your project, not from ${SOURCE.name} package.`,
79
+ )
80
+ process.exitCode = 1
81
+ return
82
+ }
83
+
48
84
  const pm = await detect()
85
+ if (!pm) {
86
+ console.error(
87
+ 'Could not detect package manager. '
88
+ + 'Please ensure you are in a project with a package.json file.',
89
+ )
90
+ process.exitCode = 1
91
+ return
92
+ }
49
93
 
50
- // Install source config
51
94
  const installCmd = resolveCommand(pm.agent, 'add', ['-D', SOURCE.name])
52
- await spawnAsync(installCmd.command, installCmd.args)
95
+ await runCommand(installCmd.command, installCmd.args)
53
96
  console.info(`Installed ${SOURCE.name}`)
54
97
 
55
- // Run source config setup
56
98
  const execCmd = resolveCommand(pm.agent, 'execute', [SOURCE.name])
57
- await spawnAsync(execCmd.command, execCmd.args)
99
+ await runCommand(execCmd.command, execCmd.args)
58
100
 
59
101
  console.info(`Start replacing the config from ${SOURCE.name} to ${TARGET.name}`)
60
102
 
61
- // Update package.json
62
103
  const cwd = process.cwd()
63
- const packageJSONPath = path.join(cwd, 'package.json')
64
- const packageJSON = await fs.readFile(packageJSONPath, 'utf-8')
65
- /** @type {Record<string,unknown>} */
66
- const pkg = JSON.parse(packageJSON)
67
-
68
- // Initialize devDependencies if it doesn't exist
69
- pkg.devDependencies = pkg.devDependencies || {}
70
- delete pkg.devDependencies[SOURCE.name]
71
-
72
- // Get latest version of target package
73
- const { stdout } = await exec(`npm view ${TARGET.name} dist-tags.latest`)
74
- .catch(() => ({ stdout: 'latest' }))
75
- pkg.devDependencies[TARGET.name] = stdout.trim()
76
-
77
- // Update scripts
78
- pkg.scripts = {
79
- ...pkg.scripts,
80
- 'lint': 'eslint .',
81
- 'lint:fix': 'eslint --fix .',
82
- }
83
- await fs.writeFile(packageJSONPath, JSON.stringify(pkg, null, 2))
104
+ const packageJSONPath = path.join(cwd, PACKAGE_JSON_FILE)
105
+
106
+ const pkg = await updateJSONFile(packageJSONPath, (pkgData) => {
107
+ pkgData.devDependencies = pkgData.devDependencies || {}
108
+ delete pkgData.devDependencies[SOURCE.name]
109
+
110
+ let targetVersion
111
+ try {
112
+ targetVersion = execSync(`npm view ${TARGET.name} dist-tags.latest`).toString().trim()
113
+ }
114
+ catch (error) {
115
+ console.warn(
116
+ `Warning: Could not fetch latest version for ${TARGET.name}, using 'latest'. `
117
+ + `Error: ${error.message}`,
118
+ )
119
+ targetVersion = 'latest'
120
+ }
121
+ TARGET.version = targetVersion
122
+ pkgData.devDependencies[TARGET.name] = targetVersion
123
+
124
+ pkgData.scripts = {
125
+ ...pkgData.scripts,
126
+ 'lint': 'eslint .',
127
+ 'lint:fix': 'eslint --fix .',
128
+ }
129
+
130
+ return pkgData
131
+ })
84
132
 
85
- // Update or create ESLint config
86
133
  const configExt = pkg.type === 'module' ? 'js' : 'mjs'
87
- const configPath = path.join(cwd, `eslint.config.${configExt}`)
134
+ const eslintConfigFile = configExt === 'js' ? ESLINT_CONFIG_JS_FILE : ESLINT_CONFIG_MJS_FILE
135
+ const configPath = path.join(cwd, eslintConfigFile)
88
136
 
89
137
  let configContent = await fs.readFile(configPath, 'utf-8')
90
138
  configContent = configContent
@@ -92,12 +140,11 @@ async function main() {
92
140
  `import ${SOURCE.import} from '${SOURCE.name}'`,
93
141
  `import ${TARGET.import} from '${TARGET.name}'`,
94
142
  )
95
- .replace(SOURCE.import, TARGET.import)
143
+ .replace(new RegExp(`(?<!['"])${SOURCE.import}(?!['"])`, 'g'), TARGET.import)
96
144
  await fs.writeFile(configPath, configContent)
97
145
 
98
- // Install dependencies after all changes
99
- const finalInstallCmd = resolveCommand(pm.agent, 'install')
100
- await spawnAsync(finalInstallCmd.command, finalInstallCmd.args)
146
+ const finalInstallCmd = resolveCommand(pm.agent, 'install', [])
147
+ await runCommand(finalInstallCmd.command, finalInstallCmd.args)
101
148
 
102
149
  console.info(`Successfully replaced the config from ${SOURCE.name} to ${TARGET.name}`)
103
150
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@mouse_484/eslint-config",
3
3
  "type": "module",
4
- "version": "3.5.14",
4
+ "version": "3.5.16",
5
5
  "author": "mouse_484",
6
6
  "license": "MIT",
7
7
  "homepage": "https://github.com/mouse484/config/tree/main/packages/eslint",