@in-ch/setup
Version:
A tool for quick setup and configuration of essential project files.
1 lines ⢠78 kB
Source Map (JSON)
{"version":3,"sources":["../src/index.ts","../commands/commitlint.ts","../commands/husky.ts","../lib/husky-config.ts","../const/packagesMng.ts","../lib/detect-package-manger.ts","../lib/version-update.ts","../commands/pkgmng.ts","../lib/check-latest-pkg-version.ts","../lib/get-package-info.ts","../lib/commit-lint-config.ts","../commands/eslint.ts","../lib/eslint-config.ts","../lib/get-global-package-path.ts","../lib/get-setting-file-path.ts","../commands/gitmessage.ts","../lib/gitmessage-config.ts","../commands/prettier.ts","../lib/prettier-config.ts","../commands/typescript.ts","../lib/typescript-config.ts","../const/commands.ts","../commands/edit.ts","../lib/get-open-command.ts","../commands/init.ts","../commands/latest.ts","../commands/lighthouse.ts","../lib/lighthouse-config.ts","../commands/list.ts","../lib/color-map.ts","../lib/convert-from-objects.ts","../lib/table-message.ts","../commands/update.ts","../commands/vscode-autoprefix.ts","../lib/update-vscode-setting.ts","../lib/check-vscode-extension-installed.ts","../lib/install-vscode-extension.ts","../lib/init-pkg.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { commitlintCli } from 'commands/commitlint.ts';\nimport { editCli } from 'commands/edit.ts';\nimport { eslintCli } from 'commands/eslint.ts';\nimport { gitmessageCli } from 'commands/gitmessage.ts';\nimport { huskyCli } from 'commands/husky.ts';\nimport { initCli } from 'commands/init.ts';\nimport { latestCli } from 'commands/latest.ts';\nimport { lighthouseCli } from 'commands/lighthouse.ts';\nimport { listCli } from 'commands/list.ts';\nimport { pkgmngCli } from 'commands/pkgmng.ts';\nimport { prettierCli } from 'commands/prettier.ts';\nimport { typescriptCli } from 'commands/typescript.ts';\nimport { updateCli } from 'commands/update.ts';\nimport { vsCodeAutoPrefixCli } from 'commands/vscode-autoprefix.ts';\nimport { getPackageInfo } from 'lib/get-package-info.ts';\nimport { initPackagePkg } from 'lib/init-pkg.ts';\n\nprocess.on('SIGINT', () => process.exit(0));\nprocess.on('SIGTERM', () => process.exit(0));\n\nasync function main() {\n await initPackagePkg();\n const packageInfo = await getPackageInfo();\n const program = new Command()\n .name('@in-ch/setup')\n .description('Quick config: Download and apply settings in seconds.')\n .version(`@in-ch/setup v${packageInfo.version || '1.0.0'}`, '-v, --version', 'display the version number');\n program.addCommand(listCli);\n program.addCommand(initCli);\n program.addCommand(eslintCli);\n program.addCommand(prettierCli);\n program.addCommand(editCli);\n program.addCommand(typescriptCli);\n program.addCommand(gitmessageCli);\n program.addCommand(huskyCli);\n program.addCommand(commitlintCli);\n program.addCommand(pkgmngCli);\n program.addCommand(lighthouseCli);\n program.addCommand(vsCodeAutoPrefixCli);\n program.addCommand(latestCli);\n program.addCommand(updateCli);\n program.parse();\n}\n\nmain();\n","#!/usr/bin/env node\nimport { Command } from 'commander';\nimport { husky } from 'commands/husky.ts';\nimport { existsSync } from 'fs';\nimport { createConfigFiles, installDependencies } from 'lib/commit-lint-config.ts';\nimport versionCheckAndUpdate from 'lib/version-update.ts';\nimport { confirm } from '@inquirer/prompts';\n\nexport const commitlintCli = new Command()\n .command('commitlint')\n .description('Setup commit lint')\n .action(async () => commitLint());\nexport const commitLint = async () => {\n await versionCheckAndUpdate();\n\n const isInitHusky = existsSync('.husky');\n if (!isInitHusky) {\n const isInitHusky = await confirm({\n message: 'Husky is not initialized. Would you like to initialize it?',\n });\n if (!isInitHusky) {\n console.log('canceled!');\n return;\n }\n await husky();\n }\n installDependencies();\n createConfigFiles();\n};\n","#!/usr/bin/env node\nimport { Command } from 'commander';\nimport { existsSync } from 'fs';\nimport { createConfigHusky, installDependencies, updatePackageJson } from 'lib/husky-config.ts';\nimport versionCheckAndUpdate from 'lib/version-update.ts';\nimport { confirm } from '@inquirer/prompts';\n\nexport const huskyCli = new Command()\n .command('husky')\n .description('Setup husky')\n .action(async () => husky());\n\nexport const husky = async () => {\n await versionCheckAndUpdate();\n\n const huskyConfigFiles = ['.husky'];\n const existingConfigs = huskyConfigFiles.filter(file => existsSync(file));\n if (existingConfigs.length > 0) {\n const overwrite = await confirm({\n message: 'Husky settings are already configured. Do you still want to proceed with the setup?',\n });\n if (!overwrite) {\n console.log('canceled!');\n return;\n }\n }\n await installDependencies();\n await createConfigHusky();\n await updatePackageJson();\n};\n","import { execSync } from 'child_process';\nimport { packageManagerInstallChoices } from 'const/packagesMng.ts';\nimport detectPackageManager from 'lib/detect-package-manger.ts';\nimport path from 'path';\nimport { select } from '@inquirer/prompts';\n\nconst installDependencies = async (): Promise<void> => {\n console.log('\\nInstalling husky dependencies...\\n');\n\n try {\n const dependencies = `husky -D`;\n let packageMng = detectPackageManager();\n if (packageMng === 'default') {\n console.log(\n 'The package manager could not be detected. \\n\\n1. If this is not the project root, please run the command from the root directory. \\n2. If you have not installed the packages beforehand, please install them first and then try again.\\n\\n'\n );\n if (packageMng === 'default') {\n const answer = await select({\n message: 'Which package manager would you like to use for installation? \\n',\n choices: packageManagerInstallChoices,\n });\n if (answer === 'cancel') {\n return;\n }\n packageMng = answer;\n }\n }\n const installCommand = `${packageMng} ${dependencies}`;\n execSync(`${installCommand} -D`, { stdio: 'inherit' });\n } catch (error) {\n console.error('š„² š„² š„² Failed to install dependencies...');\n process.exit(1);\n }\n};\n\nconst createConfigHusky = async (): Promise<void> => {\n execSync(`npx husky init`, { stdio: 'inherit' });\n};\n\nconst updatePackageJson = async (): Promise<void> => {\n const packageJsonPath = path.resolve(process.cwd(), 'package.json');\n const fs = await import('fs-extra');\n try {\n await fs.access(packageJsonPath);\n } catch (error) {\n console.error('Could not find the package.json file.');\n return;\n }\n\n try {\n const data = await fs.readFile(packageJsonPath, 'utf-8');\n const packageJson = JSON.parse(data);\n\n if (!packageJson.scripts) {\n packageJson.scripts = {};\n }\n\n packageJson.scripts.test = 'echo \"Error: no test specified\" && exit 1';\n\n await fs.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2), 'utf-8');\n console.log('package.json file updated successfully.');\n } catch (error) {\n console.error('An error occurred while reading or modifying the package.json file:', error);\n }\n};\n\nexport { createConfigHusky, installDependencies, updatePackageJson };\n","const PACKAGE_MANAGER = {\n NPM: 'npm',\n PNPM: 'pnpm',\n YARN: 'yarn',\n};\nconst PACKAGE_MANAGER_VALUE = {\n NPM: 'npm',\n PNPM: 'pnpm',\n YARN: 'yarn',\n};\nconst PACKAGE_MANAGER_VALUE_INSTALL = {\n NPM: 'npm install',\n PNPM: 'pnpm add',\n YARN: 'yarn add',\n};\ntype PackageManagerTypes = (typeof PACKAGE_MANAGER)[keyof typeof PACKAGE_MANAGER];\n\nconst packageManagerChoices = [\n { name: PACKAGE_MANAGER.NPM, value: PACKAGE_MANAGER_VALUE.NPM },\n { name: PACKAGE_MANAGER.PNPM, value: PACKAGE_MANAGER_VALUE.PNPM },\n { name: PACKAGE_MANAGER.YARN, value: PACKAGE_MANAGER_VALUE.YARN },\n { name: 'cancel', value: 'cancel' },\n];\n\nconst packageManagerInstallChoices = [\n { name: PACKAGE_MANAGER.NPM, value: PACKAGE_MANAGER_VALUE_INSTALL.NPM },\n { name: PACKAGE_MANAGER.PNPM, value: PACKAGE_MANAGER_VALUE_INSTALL.PNPM },\n { name: PACKAGE_MANAGER.YARN, value: PACKAGE_MANAGER_VALUE_INSTALL.YARN },\n { name: 'cancel', value: 'cancel' },\n];\n\nexport { PACKAGE_MANAGER, packageManagerChoices, packageManagerInstallChoices };\nexport type { PackageManagerTypes };\n","import fs from 'fs';\n\n/**\n * After identifying the package manager being used in the project, return the appropriate installation command.\n * If the package manager cannot be found, it indicates either an unsupported environment or that the location\n * is not the project root.\n * @returns {string} Return install command\n */\nconst detectPackageManager = (): string => {\n const files = fs.readdirSync(process.cwd());\n if (files.includes('yarn.lock')) {\n return 'yarn add';\n }\n if (files.includes('pnpm-lock.yaml')) {\n return 'pnpm add';\n }\n if (files.includes('package-lock.json')) {\n return 'npm install';\n }\n return 'default';\n};\n\nexport default detectPackageManager;\n","import { execSync } from 'child_process';\nimport { pkgmng } from 'commands/pkgmng.ts';\nimport { confirm } from '@inquirer/prompts';\nimport checkLatestPkgVersion from './check-latest-pkg-version.ts';\nimport { getPackageInfo } from './get-package-info.ts';\n\nexport function initializePackageManager() {\n try {\n execSync('npm --version', { stdio: 'ignore' });\n } catch {\n pkgmng();\n }\n}\n\nexport default async function versionCheckAndUpdate() {\n initializePackageManager();\n\n const latestVersion = await checkLatestPkgVersion('@in-ch/setup');\n const currentVersion = await getPackageInfo().version;\n\n if (currentVersion !== latestVersion) {\n const isUpdateLatestVersion = await confirm({\n message: `The latest version is ${latestVersion}, but the current version is ${currentVersion}. An update is needed. Would you like to update?`,\n });\n if (isUpdateLatestVersion) {\n execSync('npm install @in-ch/setup@latest -g', { stdio: 'inherit' });\n console.log('Update completed successfully.');\n }\n }\n}\n","#!/usr/bin/env node\nimport { execSync } from 'child_process';\nimport { Command } from 'commander';\nimport { packageManagerChoices } from 'const/packagesMng.ts';\nimport { select } from '@inquirer/prompts';\n\nexport const pkgmngCli = new Command()\n .command('pm')\n .description('Initialize package manager')\n .action(async () => pkgmng());\nexport const pkgmng = async () => {\n try {\n const answer = await select({\n message: 'Which package manager would you like to use? \\n',\n choices: packageManagerChoices,\n });\n if (answer === 'cancel') {\n return;\n }\n execSync(`${answer} init`, { stdio: 'inherit' });\n } catch (error) {\n console.error('š„² š„² š„² Failed to init package manager... to\\n', error);\n process.exit(1);\n }\n};\n","import { exec } from 'child_process';\n\n/**\n * @param {string} packageName package name\n * @returns {Promise<string>} latest version of the package\n */\nexport default function checkLatestPkgVersion(packageName: string): Promise<string> {\n return new Promise((resolve, reject) => {\n exec(`npm show ${packageName} version`, (error, stdout, stderr) => {\n if (error) {\n reject(`Error fetching latest version: ${error.message}`);\n return;\n }\n if (stderr) {\n reject(`Error: ${stderr}`);\n return;\n }\n resolve(stdout.trim());\n });\n });\n}\n","import { execSync } from 'child_process';\nimport fs from 'fs-extra';\nimport path from 'path';\n\nexport function getPackageInfo(packageName = '@in-ch/setup') {\n try {\n const globalRoot = execSync('npm root -g', { encoding: 'utf-8' }).trim();\n const packageJsonPath = path.join(globalRoot, packageName, 'package.json');\n if (fs.existsSync(packageJsonPath)) {\n return JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));\n } else {\n throw new Error('package.json not found');\n }\n } catch (error) {\n console.error('Error fetching global package.json:', error);\n return null;\n }\n}\n","import { execSync } from 'child_process';\nimport { COMMANDS } from 'const/commands.ts';\nimport { packageManagerInstallChoices } from 'const/packagesMng.ts';\nimport fs from 'fs';\nimport detectPackageManager from 'lib/detect-package-manger.ts';\nimport getSettingFilePath from 'lib/get-setting-file-path.ts';\nimport path from 'path';\nimport { select } from '@inquirer/prompts';\n\n/**\n * install dependencies\n * @returns {Promise<void>}\n */\nconst installDependencies = async (): Promise<void> => {\n console.log('\\nInstalling eslint dependencies...\\n');\n try {\n const dependencies = ['@commitlint/config-conventional', '@commitlint/cli', 'lint-staged'];\n let packageMng = detectPackageManager();\n if (packageMng === 'default') {\n console.log(\n 'The package manager could not be detected. \\n\\n1. If this is not the project root, please run the command from the root directory. \\n2. If you have not installed the packages beforehand, please install them first and then try again.\\n\\n'\n );\n if (packageMng === 'default') {\n const answer = await select({\n message: 'Which package manager would you like to use for installation? \\n',\n choices: packageManagerInstallChoices,\n });\n if (answer === 'cancel') {\n return;\n }\n packageMng = answer;\n }\n }\n const installCommand = `${packageMng} ${dependencies.join(' ')}`;\n execSync(`${installCommand} -D`, { stdio: 'inherit' });\n } catch (error) {\n console.error(\"š„² š„² š„² Failed to install commitlint's dependencies...\");\n process.exit(1);\n }\n};\n\nconst createConfigFiles = (): void => {\n const rootDir = process.cwd();\n const commitlintrcConfig = fs.readFileSync(getSettingFilePath(COMMANDS.COMMIT_LINT), 'utf-8');\n const lintStagedConfig = fs.readFileSync(getSettingFilePath(COMMANDS.LINT_STAGE), 'utf-8');\n try {\n fs.writeFileSync(path.join(rootDir, '.commitlintrc.json'), commitlintrcConfig, 'utf-8');\n fs.writeFileSync(path.join(rootDir, '.lintstagedrc.json'), lintStagedConfig, 'utf-8');\n\n console.log('\\nš Successfully created the Commitlint configuration file.');\n } catch (error) {\n console.error('š„² š„² š„² Failed to setup commit lint... to\\n', error);\n process.exit(1);\n }\n};\n\nexport { installDependencies, createConfigFiles };\n","#!/usr/bin/env node\nimport { Command } from 'commander';\nimport { COMMANDS, eslintConfigTypeChoices, eslintConfigTypeChoicesValue } from 'const/commands.ts';\nimport { existsSync } from 'fs';\nimport {\n createConfigFiles,\n installAirbnbDependencies,\n installGoogleDependencies,\n installImportSortDependencies,\n installXODependencies,\n} from 'lib/eslint-config.ts';\nimport versionCheckAndUpdate from 'lib/version-update.ts';\nimport { confirm, select } from '@inquirer/prompts';\n\nexport const eslintCli = new Command()\n .command('eslint')\n .description('Setup eslint file')\n .action(async () => eslint());\nexport const eslint = async () => {\n await versionCheckAndUpdate();\n\n const eslintConfigFiles = [\n '.eslintrc.js',\n '.eslintrc.json',\n '.eslintrc.yaml',\n '.eslintrc.yml',\n '.eslintrc.config.mjs',\n '.eslintrc',\n ];\n const existingConfigs = eslintConfigFiles.filter(file => existsSync(file));\n if (existingConfigs.length > 0) {\n const overwrite = await confirm({\n message: 'At least one ESLint file exists. Do you still want to proceed with the setup?',\n });\n if (!overwrite) {\n console.log('canceled!');\n return;\n }\n }\n const eslintConfigType = await select({\n message: 'Choose an ESLint configuration type:',\n choices: eslintConfigTypeChoices,\n });\n\n if (eslintConfigType === eslintConfigTypeChoicesValue.airbnb) {\n console.log('Setting up Airbnb ESLint configuration...');\n installAirbnbDependencies();\n createConfigFiles(COMMANDS.AIRBNB);\n } else if (eslintConfigType === eslintConfigTypeChoicesValue.google) {\n console.log('Setting up Google ESLint configuration...');\n installGoogleDependencies();\n createConfigFiles(COMMANDS.GOOGLE);\n } else if (eslintConfigType === eslintConfigTypeChoicesValue.xo) {\n console.log('Setting up XO ESLint configuration...');\n installXODependencies();\n createConfigFiles(COMMANDS.XO);\n } else {\n console.log('Setting up Import Sort ESLint configuration...');\n installImportSortDependencies();\n createConfigFiles(COMMANDS.ESLINT);\n }\n};\n","import { execSync } from 'child_process';\nimport { packageManagerInstallChoices } from 'const/packagesMng.ts';\nimport fs from 'fs';\nimport detectPackageManager from 'lib/detect-package-manger.ts';\nimport getSettingFilePath from 'lib/get-setting-file-path.ts';\nimport path from 'path';\nimport { select } from '@inquirer/prompts';\n\n/**\n * eslint import sort install dependencies\n * @returns {Promise<void>}\n */\nconst installImportSortDependencies = async (): Promise<void> => {\n console.log('\\nInstalling eslint dependencies...\\n');\n try {\n const dependencies =\n 'eslint @types/eslint eslint-plugin-jsdoc eslint-plugin-no-for-of-array eslint-plugin-vue @eslint/js typescript-eslint globals';\n let packageMng = detectPackageManager();\n if (packageMng === 'default') {\n console.log(\n 'The package manager could not be detected. \\n\\n1. If this is not the project root, please run the command from the root directory. \\n2. If you have not installed the packages beforehand, please install them first and then try again.\\n\\n'\n );\n if (packageMng === 'default') {\n const answer = await select({\n message: 'Which package manager would you like to use for installation? \\n',\n choices: packageManagerInstallChoices,\n });\n if (answer === 'cancel') {\n return;\n }\n packageMng = answer;\n }\n }\n const installCommand = `${packageMng} ${dependencies}`;\n execSync(`${installCommand} -D`, { stdio: 'inherit' });\n } catch (error) {\n console.error('š„² š„² š„² Failed to install dependencies...');\n process.exit(1);\n }\n};\n\n/**\n * eslint airbnb install dependencies\n * @returns {Promise<void>}\n */\nconst installAirbnbDependencies = async (): Promise<void> => {\n console.log('\\nInstalling eslint dependencies...\\n');\n try {\n const dependencies =\n 'eslint eslint-config-airbnb-base eslint-plugin-import @typescript-eslint/parser @typescript-eslint/eslint-plugin';\n let packageMng = detectPackageManager();\n if (packageMng === 'default') {\n console.log(\n 'The package manager could not be detected. \\n\\n1. If this is not the project root, please run the command from the root directory. \\n2. If you have not installed the packages beforehand, please install them first and then try again.\\n\\n'\n );\n if (packageMng === 'default') {\n const answer = await select({\n message: 'Which package manager would you like to use for installation? \\n',\n choices: packageManagerInstallChoices,\n });\n if (answer === 'cancel') {\n return;\n }\n packageMng = answer;\n }\n }\n const installCommand = `${packageMng} ${dependencies}`;\n execSync(`${installCommand} -D`, { stdio: 'inherit' });\n } catch (error) {\n console.error('š„² š„² š„² Failed to install dependencies...');\n process.exit(1);\n }\n};\n\n/**\n * eslint google install dependencies\n * @returns {Promise<void>}\n */\nconst installGoogleDependencies = async (): Promise<void> => {\n console.log('\\nInstalling eslint dependencies...\\n');\n try {\n const dependencies = 'eslint eslint-config-google';\n let packageMng = detectPackageManager();\n if (packageMng === 'default') {\n console.log(\n 'The package manager could not be detected. \\n\\n1. If this is not the project root, please run the command from the root directory. \\n2. If you have not installed the packages beforehand, please install them first and then try again.\\n\\n'\n );\n if (packageMng === 'default') {\n const answer = await select({\n message: 'Which package manager would you like to use for installation? \\n',\n choices: packageManagerInstallChoices,\n });\n if (answer === 'cancel') {\n return;\n }\n packageMng = answer;\n }\n }\n const installCommand = `${packageMng} ${dependencies}`;\n execSync(`${installCommand} -D`, { stdio: 'inherit' });\n } catch (error) {\n console.error('š„² š„² š„² Failed to install dependencies...');\n process.exit(1);\n }\n};\n\n/**\n * eslint xo install dependencies\n * @returns {Promise<void>}\n */\nconst installXODependencies = async (): Promise<void> => {\n console.log('\\nInstalling eslint dependencies...\\n');\n try {\n const dependencies = 'eslint eslint-config-xo';\n let packageMng = detectPackageManager();\n if (packageMng === 'default') {\n console.log(\n 'The package manager could not be detected. \\n\\n1. If this is not the project root, please run the command from the root directory. \\n2. If you have not installed the packages beforehand, please install them first and then try again.\\n\\n'\n );\n if (packageMng === 'default') {\n const answer = await select({\n message: 'Which package manager would you like to use for installation? \\n',\n choices: packageManagerInstallChoices,\n });\n if (answer === 'cancel') {\n return;\n }\n packageMng = answer;\n }\n }\n const installCommand = `${packageMng} ${dependencies}`;\n execSync(`${installCommand} -D`, { stdio: 'inherit' });\n } catch (error) {\n console.error('š„² š„² š„² Failed to install dependencies...');\n process.exit(1);\n }\n};\n\nconst createConfigFiles = (command: string): void => {\n const rootDir = process.cwd();\n const eslintConfig = fs.readFileSync(getSettingFilePath(command), 'utf-8');\n try {\n fs.writeFileSync(path.join(rootDir, 'eslint.config.mjs'), eslintConfig, 'utf-8');\n console.log('\\nš Successfully created the ESLint configuration file.');\n } catch (error) {\n console.error('š„² š„² š„² Failed to setup eslint... to\\n', error);\n process.exit(1);\n }\n};\n\nexport {\n installImportSortDependencies,\n createConfigFiles,\n installAirbnbDependencies,\n installGoogleDependencies,\n installXODependencies,\n};\n","import { execSync } from 'child_process';\nimport path from 'path';\n\n/**\n * Get the global path of a given npm package\n * @param {string} packageName Name of the package\n * @returns {string | null} Path to the global package, or null if not found\n */\nexport default function getGlobalPackagePath(packageName: string): string | null {\n try {\n const globalNpmRoot = execSync('npm root -g', { encoding: 'utf8' }).trim();\n const packagePath = path.resolve(globalNpmRoot, packageName);\n return packagePath;\n } catch (error) {\n console.error('Error resolving global package path:', error);\n return null;\n }\n}\n","import { extension } from 'const/commands.ts';\nimport getGlobalPackagePath from 'lib/get-global-package-path.ts';\nimport path from 'path';\n\n/**\n * @param {string} file Config file name\n * @description Get config file's path\n * @returns {string} Full path to the config file\n */\nexport default function getSettingFilePath(file: string): string {\n if (!file) {\n throw new Error('File name is required');\n }\n\n const isDevMode = process.env.NODE_ENV === 'development';\n if (isDevMode) {\n return path.resolve(process.cwd(), 'const/config', file) + extension[file];\n } else {\n const globalPath = getGlobalPackagePath('@in-ch/setup');\n if (!globalPath) {\n throw new Error('Could not resolve global path for @in-ch/setup');\n }\n return path.resolve(globalPath, 'const/config', file) + extension[file];\n }\n}\n","#!/usr/bin/env node\nimport { Command } from 'commander';\nimport { existsSync } from 'fs';\nimport { createConfigFiles, initializeGit } from 'lib/gitmessage-config.ts';\nimport versionCheckAndUpdate from 'lib/version-update.ts';\nimport { confirm } from '@inquirer/prompts';\n\nexport const gitmessageCli = new Command()\n .command('gitmessage')\n .description('Setup git message file')\n .action(async () => gitmessage());\nexport const gitmessage = async () => {\n await versionCheckAndUpdate();\n\n const isInitGit = existsSync('.git');\n if (!isInitGit) {\n const isOkInitGit = await confirm({\n message: 'Git is not initialized. Would you like to initialize it?',\n });\n if (!isOkInitGit) {\n console.log('canceled!');\n return;\n }\n await initializeGit();\n }\n createConfigFiles();\n};\n","import { execSync } from 'child_process';\nimport { COMMANDS } from 'const/commands.ts';\nimport fs from 'fs';\nimport getSettingFilePath from 'lib/get-setting-file-path.ts';\nimport path from 'path';\n\n/**\n * initialize git\n * @returns {Promise<void>}\n */\nconst initializeGit = async (): Promise<void> => {\n execSync(`git init`, { stdio: 'inherit' });\n};\n\nconst createConfigFiles = (): void => {\n const rootDir = process.cwd();\n const config = fs.readFileSync(getSettingFilePath(COMMANDS.GITMESSAGE), 'utf-8');\n try {\n fs.writeFileSync(path.join(rootDir, '.gitmessage'), config, 'utf-8');\n execSync('git config commit.template .gitmessage');\n execSync('git config init.defaultBranch main');\n console.log('š Successfully created the git message configuration file. š');\n console.log(\n 'You can now write commits following the template using the commit button in your IDE tool or the `git commit` command in the terminal.'\n );\n } catch (error) {\n console.error('š„² š„² š„² Failed to setup git message... to \\n', error);\n process.exit(1);\n }\n};\n\nexport { initializeGit, createConfigFiles };\n","#!/usr/bin/env node\nimport { Command } from 'commander';\nimport { existsSync } from 'fs';\nimport { createConfigFiles, installDependencies } from 'lib/prettier-config.ts';\nimport versionCheckAndUpdate from 'lib/version-update.ts';\nimport { confirm } from '@inquirer/prompts';\n\nexport const prettierCli = new Command()\n .command('prettier')\n .description('Setup prettier file')\n .action(async () => prettier());\nexport const prettier = async () => {\n await versionCheckAndUpdate();\n\n const prettierConfigFiles = [\n '.prettierrc',\n '.prettierrc.json',\n '.prettierrc.yml',\n '.prettierrc.yaml',\n '.prettierrc.js',\n '.prettierrc.cjs',\n 'prettier.config.js',\n 'prettier.config.cjs',\n ];\n const existingConfigs = prettierConfigFiles.filter(file => existsSync(file));\n if (existingConfigs.length > 0) {\n const overwrite = await confirm({\n message: 'At least one Prettier file exists. Do you still want to proceed with the setup?',\n });\n if (!overwrite) {\n console.log('canceled!');\n return;\n }\n }\n installDependencies();\n createConfigFiles();\n};\n","import { execSync } from 'child_process';\nimport { COMMANDS } from 'const/commands.ts';\nimport { packageManagerInstallChoices } from 'const/packagesMng.ts';\nimport fs from 'fs';\nimport detectPackageManager from 'lib/detect-package-manger.ts';\nimport getSettingFilePath from 'lib/get-setting-file-path.ts';\nimport path from 'path';\nimport { select } from '@inquirer/prompts';\n\nconst installDependencies = async (): Promise<void> => {\n console.log('\\nInstalling prettier dependencies...\\n');\n try {\n const dependencies = 'prettier prettier-plugin-sort-re-exports @trivago/prettier-plugin-sort-imports';\n let packageMng = detectPackageManager();\n if (packageMng === 'default') {\n console.log(\n 'The package manager could not be detected. \\n\\n1. If this is not the project root, please run the command from the root directory. \\n2. If you have not installed the packages beforehand, please install them first and then try again.\\n\\n'\n );\n if (packageMng === 'default') {\n const answer = await select({\n message: 'Which package manager would you like to use for installation? \\n',\n choices: packageManagerInstallChoices,\n });\n if (answer === 'cancel') {\n return;\n }\n packageMng = answer;\n }\n }\n const installCommand = `${packageMng} ${dependencies}`;\n execSync(`${installCommand} -D`, { stdio: 'inherit' });\n } catch (error) {\n console.error('š„² Fail to install prettier dependencies.... to \\n' + error);\n process.exit(1);\n }\n};\n\nconst createConfigFiles = () => {\n const rootDir = process.cwd();\n const prettierConfig = fs.readFileSync(getSettingFilePath(COMMANDS.PRETTIER), 'utf-8');\n const prettierIgnore = `node_modules/\ndist/\nbuild/\ncoverage/\n*.min.js\n*.bundle.js\n*.config.js\n*.cjs\nlogs/\n*.log\n.vscode/\n.DS_Store\n.env\n.env.*\npackage-lock.json\nyarn.lock\npnpm-lock.yaml`;\n\n try {\n fs.writeFileSync(path.join(rootDir, '.prettierrc.cjs'), prettierConfig, 'utf-8');\n fs.writeFileSync(path.join(rootDir, '.prettierignore'), prettierIgnore, 'utf-8');\n console.log('š Prettier configuration file has been created.');\n } catch (error) {\n console.error('š„² Failed to setup prettier... to \\n', error);\n process.exit(1);\n }\n};\n\nexport { installDependencies, createConfigFiles };\n","#!/usr/bin/env node\nimport { Command } from 'commander';\nimport { existsSync } from 'fs';\nimport { createConfigFiles, installDependencies } from 'lib/typescript-config.ts';\nimport versionCheckAndUpdate from 'lib/version-update.ts';\n\nexport const typescriptCli = new Command()\n .command('typescript')\n .description('Setup typescript file')\n .action(async () => typescript());\nexport const typescript = async () => {\n await versionCheckAndUpdate();\n\n const typescriptConfigFiles = ['.tsconfig.json'];\n const existingConfigs = typescriptConfigFiles.filter(file => existsSync(file));\n if (existingConfigs.length > 0) {\n console.error('At least one Typescript file exists.');\n return;\n }\n installDependencies();\n createConfigFiles();\n};\n","import { execSync } from 'child_process';\nimport { packageManagerInstallChoices } from 'const/packagesMng.ts';\nimport detectPackageManager from 'lib/detect-package-manger.ts';\nimport { select } from '@inquirer/prompts';\n\n/**\n * install dependencies\n * @returns {Promise<void>}\n */\nconst installDependencies = async (): Promise<void> => {\n console.log('\\nInstalling typescript dependencies...\\n');\n try {\n const dependencies = 'typescript @types/node @types/react';\n let packageMng = detectPackageManager();\n if (packageMng === 'default') {\n console.log(\n 'The package manager could not be detected. \\n\\n1. If this is not the project root, please run the command from the root directory. \\n2. If you have not installed the packages beforehand, please install them first and then try again.\\n\\n'\n );\n if (packageMng === 'default') {\n const answer = await select({\n message: 'Which package manager would you like to use for installation? \\n',\n choices: packageManagerInstallChoices,\n });\n if (answer === 'cancel') {\n return;\n }\n packageMng = answer;\n }\n }\n const installCommand = `${packageMng} ${dependencies}`;\n execSync(`${installCommand} -D`, { stdio: 'inherit' });\n } catch (error) {\n console.error('š„² š„² š„² Failed to install dependencies...');\n process.exit(1);\n }\n};\n\n/**\n * Setup typescript file\n * @returns {void}\n */\nconst createConfigFiles = (): void => {\n console.log('Configure Typescript');\n execSync(`npx tsc --init`);\n};\n\nexport { installDependencies, createConfigFiles };\n","import { commitLint } from 'commands/commitlint.ts';\nimport { eslint } from 'commands/eslint.ts';\nimport { gitmessage } from 'commands/gitmessage.ts';\nimport { husky } from 'commands/husky.ts';\nimport { prettier } from 'commands/prettier.ts';\nimport { typescript } from 'commands/typescript.ts';\n\nconst COMMANDS = {\n ESLINT: 'eslint',\n PRETTIER: 'prettier',\n TYPESCRIPT: 'typescript',\n GITMESSAGE: 'gitmessage',\n HUSKY: 'husky',\n COMMIT_LINT: 'commitlint',\n LINT_STAGE: 'lintstage',\n AIRBNB: 'airbnb',\n GOOGLE: 'google',\n XO: 'xo',\n};\n\nconst filteredCommands = Object.entries(COMMANDS)\n .filter(([key]) => ![COMMANDS.AIRBNB, COMMANDS.GOOGLE, COMMANDS.XO].includes(key))\n .map(([key, value]) => ({ name: key, value }));\nconst filteredCommandChoices = filteredCommands.map(command => command.value);\n\ntype CommandsTypes = (typeof COMMANDS)[keyof typeof COMMANDS];\nconst commandFuc = {\n [COMMANDS.ESLINT]: () => eslint(),\n [COMMANDS.PRETTIER]: () => prettier(),\n [COMMANDS.TYPESCRIPT]: () => typescript(),\n [COMMANDS.GITMESSAGE]: () => gitmessage(),\n [COMMANDS.HUSKY]: () => husky(),\n [COMMANDS.COMMIT_LINT]: () => commitLint(),\n};\nconst extension = {\n [COMMANDS.ESLINT]: '.js',\n [COMMANDS.PRETTIER]: '.js',\n [COMMANDS.TYPESCRIPT]: '.json',\n [COMMANDS.GITMESSAGE]: '.txt',\n [COMMANDS.COMMIT_LINT]: '.json',\n [COMMANDS.LINT_STAGE]: '.json',\n [COMMANDS.AIRBNB]: '.js',\n [COMMANDS.GOOGLE]: '.js',\n [COMMANDS.XO]: '.js',\n};\nconst commandChoices = [\n { name: COMMANDS.ESLINT, value: COMMANDS.ESLINT },\n { name: COMMANDS.PRETTIER, value: COMMANDS.PRETTIER },\n { name: COMMANDS.TYPESCRIPT, value: COMMANDS.TYPESCRIPT },\n { name: COMMANDS.GITMESSAGE, value: COMMANDS.GITMESSAGE },\n { name: COMMANDS.HUSKY, value: COMMANDS.HUSKY },\n { name: COMMANDS.COMMIT_LINT, value: COMMANDS.COMMIT_LINT },\n];\nconst eslintConfigTypeChoices = [\n { name: 'Import Sort', value: 'import-sort' },\n { name: 'Airbnb', value: 'airbnb' },\n { name: 'Google', value: 'google' },\n { name: 'XO', value: 'xo' },\n];\n\nconst eslintConfigTypeChoicesValue = eslintConfigTypeChoices.reduce(\n (acc, choice) => {\n acc[choice.value] = choice.value;\n return acc;\n },\n {} as Record<string, string>\n);\n\nexport {\n COMMANDS,\n commandFuc,\n commandChoices,\n extension,\n eslintConfigTypeChoices,\n eslintConfigTypeChoicesValue,\n filteredCommands,\n filteredCommandChoices,\n};\nexport type { CommandsTypes };\n","import { exec } from 'child_process';\nimport { Command } from 'commander';\nimport { commandChoices, CommandsTypes } from 'const/commands.ts';\nimport getOpenCommand from 'lib/get-open-command.ts';\nimport getSettingFilePath from 'lib/get-setting-file-path.ts';\nimport versionCheckAndUpdate from 'lib/version-update.ts';\nimport { select } from '@inquirer/prompts';\n\nexport const editCli = new Command()\n .command('edit')\n .description('edit config file')\n .action(async () => {\n await versionCheckAndUpdate();\n\n const file: CommandsTypes = await select({\n message: 'What do you want to edit config file.',\n choices: commandChoices,\n });\n const path = getSettingFilePath(file);\n const command = getOpenCommand(path);\n exec(command, err => {\n if (err) {\n console.error('Failed to open file or folder:', err);\n } else {\n console.log(`Opened: ${path}`);\n }\n });\n });\n","import { execSync } from 'child_process';\nimport os from 'os';\n\n/**\n * @param {string} program program name\n *\n * @description Checks if the program specified as a parameter is installed.\n * @returns {boolean} Returns true if the specified program is installed, false otherwise.\n */\nconst isProgramAvailable = (program: string): boolean => {\n try {\n execSync(`which ${program}`, { stdio: 'ignore' });\n return true;\n } catch {\n return false;\n }\n};\n\n/**\n * @param {string} filepath File path\n * @description Get a command to open a file in VS Code or the default text editor, depending on the OS and availability\n * @returns {string} Command to open the file\n */\nexport default function getOpenCommand(filepath: string): string {\n const platform = os.platform();\n let command;\n\n if (platform === 'win32') {\n command = `start \"\" \"notepad\" \"${filepath}\"`;\n } else if (platform === 'darwin') {\n if (isProgramAvailable('code')) {\n command = `open -a \"Visual Studio Code\" \"${filepath}\"`;\n } else {\n command = `open -a \"TextEdit\" \"${filepath}\"`;\n }\n } else if (platform === 'linux') {\n if (isProgramAvailable('code')) {\n command = `code \"${filepath}\"`;\n } else {\n command = `xdg-open \"${filepath}\"`;\n }\n } else {\n console.error('Unsupported platform');\n return '';\n }\n return command;\n}\n","import { Command } from 'commander';\nimport { commandFuc, CommandsTypes, filteredCommandChoices } from 'const/commands.ts';\nimport versionCheckAndUpdate from 'lib/version-update.ts';\nimport { checkbox } from '@inquirer/prompts';\n\nexport const initCli = new Command()\n .command('init')\n .description('Easy Setup various configs')\n .action(async () => {\n await versionCheckAndUpdate();\n\n const results: CommandsTypes[] = await checkbox({\n message: 'Which files do you want to install?\\n',\n choices: filteredCommandChoices,\n });\n for (const result of results) {\n if (commandFuc[result] !== undefined) {\n await commandFuc[result]();\n }\n }\n });\n","import { Command } from 'commander';\nimport checkLatestPkgVersion from 'lib/check-latest-pkg-version.ts';\nimport versionCheckAndUpdate from 'lib/version-update.ts';\n\nexport const latestCli = new Command()\n .command('latest')\n .description('Check latest version of @in-ch/cli package')\n .action(() => latest());\nexport const latest = async () => {\n await versionCheckAndUpdate();\n const latestVersion = await checkLatestPkgVersion('@in-ch/setup');\n console.log(`The latest version of @in-ch/setup is v${latestVersion}`);\n};\n","import { Command } from 'commander';\nimport { doAnalysis, installDependencies } from 'lib/lighthouse-config.ts';\nimport versionCheckAndUpdate from 'lib/version-update.ts';\n\nexport const lighthouseCli = new Command()\n .command('lg')\n .description('Run a Lighthouse test')\n .option('--headless', 'Run Lighthouse in headless mode')\n .action(async cmd => lighthouse(cmd.headless));\n\nexport const lighthouse = async (headless = false) => {\n await versionCheckAndUpdate();\n await installDependencies();\n await doAnalysis(headless);\n};\n","import { execSync } from 'child_process';\nimport { confirm, input } from '@inquirer/prompts';\n\n/**\n * install dependencies\n * @returns {Promise<void>}\n */\nconst installDependencies = async (): Promise<void> => {\n console.log('\\nChecking Lighthouse dependencies...\\n');\n\n try {\n const result = execSync('lighthouse --version', { encoding: 'utf-8' });\n console.log('Lighouse version: ', result.trim() + '\\n');\n } catch (error) {\n const isOkInstall = await confirm({\n message: 'Lighthouse is not installed. Would you like to install it?',\n });\n if (isOkInstall) {\n execSync(`npm i lighthouse -g`, { stdio: 'inherit' });\n }\n }\n};\n\nconst doAnalysis = async (headless = false): Promise<void> => {\n const webAddress = await input({\n message: 'Enter the web address:',\n default: 'http://localhost:3000',\n });\n let isValidUrl = false;\n try {\n const url = new URL(webAddress);\n isValidUrl = url.protocol === 'http:' || url.protocol === 'https:';\n } catch (e) {\n isValidUrl = false;\n }\n if (!isValidUrl) {\n console.error('Invalid web address. Please enter a valid URL.');\n return;\n }\n\n execSync(`lighthouse ${webAddress} ${headless ? '--chrome-flags=\"--headless\"' : ' --output=html --view'} `, {\n stdio: 'inherit',\n });\n};\n\nexport { installDependencies, doAnalysis };\n","#!/usr/bin/env node\nimport { Command } from 'commander';\nimport fs from 'fs';\nimport colorMap from 'lib/color-map.ts';\nimport tableMessage from 'lib/table-message.ts';\nimport versionCheckAndUpdate from 'lib/version-update.ts';\nimport { fileURLToPath } from 'url';\n\n/**\n * @description This command will list all the tasks.\n */\nexport const listCli = new Command()\n .command('list')\n .description('list all commands')\n .action(async () => {\n await versionCheckAndUpdate();\n\n const isESM = typeof import.meta !== 'undefined';\n const filePath = isESM ? fileURLToPath(import.meta.url) : __filename;\n const fileContent = fs.readFileSync(filePath, 'utf-8');\n const commandDescriptionPattern = /command\\(\"(.+?)\"\\)\\.description\\(\"(.+?)\"\\)/g;\n let match;\n const results: Array<{ command: string; description: string }> = [];\n while ((match = commandDescriptionPattern.exec(fileContent)) !== null) {\n const command = match[1] as string;\n const description = match[2] as string;\n results.push({ command, description });\n }\n console.log(\n `${colorMap.orange}@in-ch/setup${colorMap.white}'s commands \\n\\n${tableMessage({\n data: results,\n borderColor: 'lightBlack',\n textColor: 'default',\n headerColor: 'orange',\n })}\\n\\n`\n );\n });\n","/**\n * @description Color map for console.log\n */\nconst colorMap: { [key: string]: string } = {\n black: '\\x1b[30m',\n red: '\\x1b[31m',\n green: '\\x1b[32m',\n yellow: '\\x1b[33m',\n blue: '\\x1b[34m',\n magenta: '\\x1b[35m',\n cyan: '\\x1b[36m',\n orange: '\\x1b[38;5;214m',\n white: '\\x1b[37m',\n\n lightBlack: '\\x1b[90m',\n lightRed: '\\x1b[91m',\n lightGreen: '\\x1b[92m',\n lightYellow: '\\x1b[93m',\n lightBlue: '\\x1b[94m',\n lightMagenta: '\\x1b[95m',\n lightCyan: '\\x1b[96m',\n lightWhite: '\\x1b[97m',\n\n bgBlack: '\\x1b[40m',\n bgRed: '\\x1b[41m',\n bgGreen: '\\x1b[42m',\n bgYellow: '\\x1b[43m',\n bgBlue: '\\x1b[44m',\n bgMagenta: '\\x1b[45m',\n bgCyan: '\\x1b[46m',\n bgWhite: '\\x1b[47m',\n\n bgLightBlack: '\\x1b[100m',\n bgLightRed: '\\x1b[101m',\n bgLightGreen: '\\x1b[102m',\n bgLightYellow: '\\x1b[103m',\n bgLightBlue: '\\x1b[104m',\n bgLightMagenta: '\\x1b[105m',\n bgLightCyan: '\\x1b[106m',\n bgLightWhite: '\\x1b[107m',\n\n default: '\\x1b[0m',\n};\n\ntype Color = keyof typeof colorMap;\n\nexport default colorMap;\nexport type { Color };\n","export interface Row {\n [key: string]: string;\n}\n\ninterface ConvertedData {\n column: string[];\n rows: string[][];\n}\n\n/**\n * @param {Row[]} data The data to be converted\n * @description Convert data from objects to arrays\n * @returns {ConvertedData} Return the converted data with structured rows and columns.\n */\nexport default function convertFromObjects(data: Row[]): ConvertedData {\n if (data.length === 0 || data[0] === undefined) {\n return { column: [], rows: [] };\n }\n const column = Object.keys(data.reduce((acc, row) => ({ ...acc, ...row }), {}));\n const rows = data.map(row => column.map(key => row[key] || ''));\n return { column, rows };\n}\n","import colorMap from 'lib/color-map.ts';\nimport convertFromObjects, { Row } from 'lib/convert-from-objects.ts';\n\ninterface BoxedMessageProps {\n data: Row[];\n textColor?: keyof typeof colorMap;\n headerColor?: keyof typeof colorMap;\n borderColor?: keyof typeof colorMap;\n}\n\n/**\n * @template Color - keyof typeof colorMap\n * @param {Row[]} data table data\n * @param {Color} [textColor] text color\n * @param {Color} [headerColor] header color\n * @param {Color} [borderColor] border color\n * @description This function will draw a table with the given data\n * @returns {string} the table as a string\n */\nexport default function tableMessage({\n data,\n textColor = colorMap.default,\n headerColor = colorMap.default,\n borderColor = colorMap.default,\n}: BoxedMessageProps): string {\n const { rows, column } = convertFromObjects(data);\n const borderColorCode = colorMap[borderColor ?? 'default'];\n const headerColorCode = colorMap[headerColor ?? 'default'];\n const textColorCode = colorMap[textColor ?? 'default'];\n\n const initialLength = column.map(message => message.length + 2);\n const boxWidths = initialLength.map((col, index) => {\n return rows.reduce((length, row) => Math.max(row[index]!.length + 2, length), col);\n });\n const padIndex = (str: string, index: number) => `${textColorCode}${str.padEnd(boxWidths[index]!)}`;\n const padHeaderIndex = (str: string, index: number) => `${headerColorCode}${str.padEnd(boxWidths[index]!)}`;\n const drawHeaderTopBoder = () =>\n `${borderColorCode}ā${column.map((_, index) => ''.padEnd(boxWidths[index]! + 1, `ā`)).join('ā¬')}ā`;\n const drawHeaderBottomBoder = () =>\n `${borderColorCode}ā${column.map((_, index) => ''.padEnd(boxWidths[index]! + 1, `ā`)).join('ā¼')}ā¤`;\n const drawFooterBottomBoder = () =>\n `${borderColorCode}ā${column.map((_, index) => ''.padEnd(boxWidths[index]! + 1, `ā`)).join('ā“')}ā`;\n\n let table = '';\n // Draw the top border\n table += drawHeaderTopBoder() + '\\n';\n table += `${borderColorCode}ā ${column.map(padHeaderIndex).join(`${borderColorCode}ā `)}${borderColorCode}ā\\n`;\n table += drawHeaderBottomBoder() + '\\n';\n rows.forEach(row => {\n table += `${borderColorCode}ā ${row.map(padIndex).join(`${borderColorCode}ā `)}ā\\n`;\n });\n // Draw the bottom border\n table += `${drawFooterBottomBoder()}${colorMap['default']}\\n`;\n\n return table;\n}\n","#!/usr/bin/env node\nimport { execSync } from 'child_process';\nimport { Command } from 'commander';\nimport checkLatestPkgVersion from 'lib/check-latest-pkg-version.ts';\nimport { getPackageInfo } from 'lib/get-package-info.ts';\nimport { initializePackageManager } from 'lib/version-update.ts';\n\nexport const updateCli = new Command()\n .command('update')\n .description('Update package version')\n .action(async () => update());\nexport const update = async () => {\n await initializePackageManager();\n\n const latestVersion = await checkLatestPkgVersion('@in-ch/setup');\n const currentVersion = await getPackageInfo().version;\n\n if (currentVersion !== latestVersion) {\n execSync('npm install @in-ch/setup@latest -g', { stdio: 'inherit' });\n } else {\n console.log('@in-ch/setup package is already up to date.');\n }\n};\n","import { Command } from 'commander';\nimport updateVscodeSetting from 'lib/update-vscode-setting.ts';\nimport versionCheckAndUpdate from 'lib/version-update.ts';\n\nexport const vsCodeAutoPrefixCli = new Command()\n .command('autoPrefix')\n .description('Update VSCode Auto Prefix Settings')\n .action(async () => {\n await versionCheckAndUpdate();\n updateVscodeSetting();\n });\n","import fs from 'fs';\nimport os from 'os';\nimport path from 'path';\nimport checkVsCodeExtensionInstalled from './check-vscode-extension-installed.ts';\nimport installVscodeExtension from './install-vscode-extension.ts';\n\nconst vscodeSettingsPath = (() => {\n const platform = os.platform();\n if (platform === 'win32') {\n return path.join(\n process.env.APPDATA || path.join(process.env.HOME!, 'AppData', 'Roaming'),\n 'Code',\n 'User',\n 'settings.json'\n );\n } else if (platform === 'darwin') {\n return path.join(process.env.HOME!, 'Library', 'Application Support', 'Code', 'User', 'settings.json');\n } else {\n return path.join(process.env.HOME!, '.config', 'Code', 'User', 'settings.json');\n }\n})();\n\nconst newSettings = {\n '[javascript]': {\n 'editor.defaultFormatter': 'esbenp.prettier-vscode',\n 'editor.formatOnSave': true,\n },\n '[typescript]': {\n 'editor.defaultFormatter': 'esbenp.prettier-vscode',\n 'editor.formatOnSave': true,\n },\n '[javascriptreact]': {\n 'editor.defaultFormatter': 'esbenp.prettier-vscode',\n 'editor.formatOnSave': true,\n },\n '[typescriptreact]': {\n 'editor.defaultFormatter': 'esbenp.prettier-vscode',\n 'editor.formatOnSave': true,\n },\n};\n\n/**\n * update vscode setting\n * @returns {void}\n */\nexport default function updateVscodeSetting(): void {\n fs.readFile(vscodeSettingsPath, 'utf8', async (err, data) => {\n if (err && err.code !== 'ENOENT') {\n console.error('Error reading VSCode settings.json:', err);\n return;\n }\n const installed = await checkVsCodeExtensionInstalled('esbenp.prettier-vscode');\n if (!installed) {\n await installVscodeExtension('esbenp.prettier-vscode');\n }\n\n let settings = {};\n if (data) {\n try {\n settings = JSON.parse(data);\n } catch (parseErr) {\n console.error('Error parsing settings.json:', parseErr);\n return;\n }\n }\n const updatedSettings = { ...settings, ...newSettings };\n fs.writeFile(vscodeSettingsPath, JSON.stringify(updatedSettings, null, 2), 'utf8', writeErr => {\n if (writeErr) {\n console.error('Error writing to settings.json:', writeErr);\n } else {\n console.log('VSCode settings.json updated successfully!');\n }\n });\n });\n}\n","#!/usr/bin/env node\nimport { execSync } from 'child_process';\n\n/**\n * Checks if a specific VSCode extension is installed.\n *\n * @param {string} extensionId - The ID of the VSCode extension to check (e.g., \"esbenp.prettier-vscode\").\n * @returns {Promise<boolean>} return whether the extension is installed\n */\nexport default async function checkVsCodeExtensionInstalled(extensionId: string): Promise<boolean | undefined> {\n try {\n const list = execSync('code --list-extensions', { stdio: 'pipe' }).toString();\n\n if (!list) {\n console.error('No extensions found or error e