devboot
Version:
Zero-config dev environment setup for modern web projects
26 lines • 129 kB
JavaScript
import{writeFile as je,unlink as He,readFile as Xe,mkdir as Ye}from"fs/promises";import z from"path";import M from"chalk";import qe from"ora";var Re=class{verboseMode;constructor(e=!1){this.verboseMode=e}info(e){console.log(M.blue("\u2139"),e)}success(e){console.log(M.green("\u2713"),e)}error(e){console.log(M.red("\u2717"),e)}warn(e){console.log(M.yellow("\u26A0"),e)}debug(e){this.verboseMode&&console.log(M.gray("\u25CB"),e)}log(e){console.log(e)}plain(e){console.log(e)}gray(e){console.log(M.gray(e))}cyan(e){console.log(M.cyan(e))}bold(e){console.log(M.bold(e))}yellow(e){console.log(M.yellow(e))}red(e){console.log(M.red(e))}newline(){console.log("")}spinner(e){return qe({text:e,spinner:"dots",color:"blue"})}},g=new Re;var C=class extends Error{constructor(t,i,r){super(t,{cause:r});this.context=i;this.name=this.constructor.name,Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}};var b=class extends C{get solution(){}},m=class extends b{constructor(t,i,r=!0,s,n){super(i,s);this.code=t;this.isRecoverable=r;this._solution=n}get solution(){return this._solution}};var Qe={COMMAND_NOT_FOUND:"COMMAND_NOT_FOUND",INVALID_ARGUMENT:"INVALID_ARGUMENT",MISSING_ARGUMENT:"MISSING_ARGUMENT",USER_CANCELLED:"USER_CANCELLED",PROMPT_FAILED:"PROMPT_FAILED",PERMISSION_DENIED:"PERMISSION_DENIED",NOT_IN_PROJECT:"NOT_IN_PROJECT"},f={PROJECT_NOT_FOUND:"PROJECT_NOT_FOUND",PROJECT_INVALID:"PROJECT_INVALID",PROJECT_ANALYSIS_FAILED:"PROJECT_ANALYSIS_FAILED",PKG_MANAGER_NOT_FOUND:"PKG_MANAGER_NOT_FOUND",PKG_INSTALL_FAILED:"PKG_INSTALL_FAILED",PKG_MANAGER_MISMATCH:"PKG_MANAGER_MISMATCH",CONFIG_PARSE_ERROR:"CONFIG_PARSE_ERROR",CONFIG_CONFLICT:"CONFIG_CONFLICT",CONFIG_MERGE_FAILED:"CONFIG_MERGE_FAILED",CONFIG_INVALID_FORMAT:"CONFIG_INVALID_FORMAT",CONFIG_GENERATION_FAILED:"CONFIG_GENERATION_FAILED",CONFIG_READ_ERROR:"CONFIG_READ_ERROR",CONFIG_NOT_FOUND:"CONFIG_NOT_FOUND",CONFIG_VALIDATION_ERROR:"CONFIG_VALIDATION_ERROR",PROJECT_NOT_VALID:"PROJECT_NOT_VALID",MODULE_NOT_FOUND:"MODULE_NOT_FOUND",MODULE_ALREADY_EXISTS:"MODULE_ALREADY_EXISTS",MODULE_INSTALL_FAILED:"MODULE_INSTALL_FAILED",MODULE_CONFIG_INVALID:"MODULE_CONFIG_INVALID",FILE_NOT_FOUND:"FILE_NOT_FOUND",FILE_READ_ERROR:"FILE_READ_ERROR",FILE_WRITE_ERROR:"FILE_WRITE_ERROR",FILE_ALREADY_EXISTS:"FILE_ALREADY_EXISTS",FILE_OPERATION_ERROR:"FILE_OPERATION_ERROR",FILE_PERMISSION_ERROR:"FILE_PERMISSION_ERROR",FILE_MODIFICATION_FAILED:"FILE_MODIFICATION_FAILED",PKG_UNINSTALL_FAILED:"PKG_UNINSTALL_FAILED",PKG_MANAGER_EXECUTION_ERROR:"PKG_MANAGER_EXECUTION_ERROR",INVALID_PACKAGE_MANAGER:"INVALID_PACKAGE_MANAGER",PERMISSION_DENIED:"PERMISSION_DENIED",NETWORK_ERROR:"NETWORK_ERROR",USER_CANCELLED:"USER_CANCELLED",DISK_FULL:"DISK_FULL",ROLLBACK_FAILED:"ROLLBACK_FAILED",MODULE_UNINSTALL_FAILED:"MODULE_UNINSTALL_FAILED"},wt={...Qe,...f};function T(d){return d instanceof Error&&"code"in d}function Le(d){return T(d)&&["ECONNREFUSED","ECONNRESET","ETIMEDOUT","ENETUNREACH","ENOTFOUND"].includes(d.code||"")}var Z=class extends b{code=f.FILE_OPERATION_ERROR;isRecoverable=!1;get solution(){let{operation:e,path:t,errorCode:i}=this.context||{},r=t?.split("/").pop(),s=t?.substring(0,t.lastIndexOf("/"));switch(e){case"write":case"create":return i==="ENOSPC"?"Not enough disk space. Free up some space and try again":s?`Ensure directory '${s}' exists and you have write permissions`:"Check if the parent directory exists and you have write permissions";case"read":return r?`Ensure file '${r}' exists in '${s||"current directory"}' and you have read permissions`:"Check if the file exists and you have read permissions";case"mkdir":return t?`Check if you have permission to create directory '${t}'`:"Check if you have permission to create directories";case"modify":return r?`Ensure '${r}' is not locked by another process and you have write permissions`:"Check if the file is not locked and you have write permissions";case"delete":return t?`Ensure '${t}' exists and you have delete permissions`:"Check if the file exists and you have delete permissions";default:return t?`Check permissions for '${t}'`:"Check file permissions and path"}}},A=class extends b{code=f.FILE_NOT_FOUND;isRecoverable=!1;get solution(){return"Ensure the file exists at the specified path"}},V=class extends b{code=f.FILE_PERMISSION_ERROR;isRecoverable=!1;get solution(){let{operation:e}=this.context||{};return e==="write"||e==="create"?"Try running with elevated permissions (sudo) or check directory ownership":"Check file permissions or run with elevated privileges"}};import j from"chalk";var $=class{static ERROR_PREFIX={error:j.red("\u2717"),warning:j.yellow("\u26A0"),info:j.blue("\u2139")};static logError(e,t={}){let{verbose:i=!1,prefix:r=!0,showSolution:s=!0,showContext:n=!1}=t;e instanceof C?this.logBaseError(e,{verbose:i,prefix:r,showSolution:s,showContext:n}):e instanceof Error?this.logGenericError(e,{verbose:i,prefix:r}):this.logUnknownError(e,{prefix:r})}static logBaseError(e,t){let i=t.prefix?`${this.ERROR_PREFIX.error} `:"";console.error(`${i}${e.message}`),t.showSolution&&e instanceof b&&e.solution&&console.log(j.yellow(`
\u{1F4A1} ${e.solution}`)),t.showContext&&e.context&&(t.verbose||process.env.DEBUG)&&(console.log(j.gray(`
Debug info:`)),console.log(j.gray(JSON.stringify(e.context,null,2)))),t.verbose&&e.stack&&(console.log(j.gray(`
Stack trace:`)),console.log(j.gray(e.stack)))}static logGenericError(e,t){let i=t.prefix?`${this.ERROR_PREFIX.error} `:"";console.error(`${i}${e.message}`),t.verbose&&e.stack&&(console.log(j.gray(`
Stack trace:`)),console.log(j.gray(e.stack)))}static logUnknownError(e,t){let i=t.prefix?`${this.ERROR_PREFIX.error} `:"";console.error(`${i}An unexpected error occurred`),console.error(j.gray(String(e)))}static logWarning(e){console.warn(`${this.ERROR_PREFIX.warning} ${e}`)}static logInfo(e){console.log(`${this.ERROR_PREFIX.info} ${e}`)}static logErrorSummary(e){if(e.length===0)return;let t=`${e.length} error${e.length===1?"":"s"} occurred:`;console.error(j.red(`
\u26A0\uFE0F ${t}`)),e.forEach((i,r)=>{console.error(j.red(` ${r+1}. ${i.message}`)),i instanceof b&&i.solution&&console.log(j.yellow(` \u{1F4A1} ${i.solution}`))})}static logErrorWithProgress(e,t){let i=j.gray(`[${t.current}/${t.total}] ${t.item}`);console.error(`${this.ERROR_PREFIX.error} ${i}`),this.logError(e,{prefix:!1})}};var _=class{constructor(e){this.config=e}get name(){return this.config.name}get displayName(){return this.config.displayName}get description(){return this.config.description}get version(){return this.config.version}async install(e){let t={success:!1,installedFiles:[],installedPackages:[],modifiedFiles:[],errors:[],hints:[],rollbackActions:[]};try{let i=await this.validate(e);if(!i.valid)return t.errors=i.errors.map(a=>new m(f.MODULE_CONFIG_INVALID,a,!1,{module:this.name,validationErrors:i.errors,conflictingModules:i.conflictingModules},i.conflictingModules?.length?"Use --force to override existing configurations":void 0)),i.conflictingModules?.length&&t.hints?.push("Use --force to override existing configurations"),t;if(i.warnings.length>0&&e.verbose&&i.warnings.forEach(a=>g.warn(a)),e.dryRun)return await this.previewChanges(e),t.success=!0,t.message="Dry run completed successfully",t;let r=await this.getFilesToCreate(e);for(let[a,l]of r)await this.createFile(z.join(e.projectPath,a),l,t,e);let s=await this.getFilesToModify(e);for(let[a,l]of s)await this.modifyFile(z.join(e.projectPath,a),l,t,e);let n=await this.getDependencies(e);return(n.dependencies||n.devDependencies)&&e.verbose&&g.info("Dependencies to be installed by package manager"),t.success=!0,t.message=`${this.displayName} configured successfully`,t}catch(i){if(t.rollbackActions?.length){e.verbose&&g.info("Rolling back changes...");try{await this.rollback(t.rollbackActions)}catch(r){let s=new m(f.ROLLBACK_FAILED,"Failed to rollback changes",!1,{module:this.name,originalError:i instanceof Error?i.message:String(i),rollbackError:r instanceof Error?r.message:String(r)});t.errors?.push(s)}}if(i instanceof C)t.errors?.push(i);else{let r=i instanceof Error?i.message:String(i);t.errors?.push(new m(f.MODULE_INSTALL_FAILED,`Module installation failed: ${r}`,!1,{module:this.name,originalError:r}))}return t.success=!1,t}}async previewChanges(e){g.info(`\u{1F4CB} Preview of changes:
`);let t=await this.getFilesToCreate(e);if(t.size>0){g.info("Files to create:");for(let[s]of t)g.info(` \u2728 ${s}`);g.info("")}let i=await this.getFilesToModify(e);if(i.size>0){g.info("Files to modify:");for(let[s]of i)g.info(` \u270F\uFE0F ${s}`);g.info("")}let r=await this.getDependencies(e);(r.dependencies||r.devDependencies)&&(g.info("Packages to install:"),Object.entries(r.dependencies||{}).forEach(([s,n])=>{g.info(` \u{1F4E6} ${s}@${n}`)}),Object.entries(r.devDependencies||{}).forEach(([s,n])=>{g.info(` \u{1F4E6} ${s}@${n} (dev)`)}))}async createFile(e,t,i,r){try{let s=z.dirname(e);try{await Ye(s,{recursive:!0})}catch(n){if(T(n)){let a=n;if(a.code==="EACCES"||a.code==="EPERM")throw new V(`Permission denied creating directory: ${s}`,{path:s,operation:"mkdir",errorCode:a.code})}throw n}try{await je(e,t,"utf-8")}catch(n){if(T(n)){let a=n;if(a.code==="EACCES"||a.code==="EPERM")throw new V(`Permission denied writing file: ${e}`,{path:e,operation:"write",errorCode:a.code});if(a.code==="ENOSPC")throw new m(f.DISK_FULL,"Not enough disk space",!1,{path:e})}throw n}i.installedFiles?.push(z.relative(r.projectPath,e)),r.verbose&&$.logInfo(`Created: ${z.relative(r.projectPath,e)}`),i.rollbackActions?.push(async()=>{try{await He(e)}catch{g.debug(`Rollback: File already removed: ${e}`)}})}catch(s){throw s instanceof C?s:new Z(`Failed to create file: ${e}`,{path:e,operation:"create",originalError:s instanceof Error?s.message:String(s)},s)}}async modifyFile(e,t,i,r){let s;try{try{s=await Xe(e,"utf-8")}catch(a){if(T(a)){let l=a;if(l.code==="ENOENT")throw new A(`File not found: ${e}`,{path:e,operation:"read"});if(l.code==="EACCES"||l.code==="EPERM")throw new V(`Permission denied reading file: ${e}`,{path:e,operation:"read",errorCode:l.code})}throw a}let n;try{n=await t(s)}catch(a){throw new m(f.FILE_MODIFICATION_FAILED,`Failed to modify file content: ${e}`,!1,{path:e,modifierError:a instanceof Error?a.message:String(a)})}try{await je(e,n,"utf-8")}catch(a){if(T(a)){let l=a;if(l.code==="EACCES"||l.code==="EPERM")throw new V(`Permission denied writing file: ${e}`,{path:e,operation:"write",errorCode:l.code})}throw a}i.modifiedFiles?.push(z.relative(r.projectPath,e)),r.verbose&&$.logInfo(`Modified: ${z.relative(r.projectPath,e)}`),i.rollbackActions?.push(async()=>{await je(e,s,"utf-8")})}catch(n){throw n instanceof C?n:new Z(`Failed to modify file: ${e}`,{path:e,operation:"modify",originalError:n instanceof Error?n.message:String(n)},n)}}async rollback(e){for(let t of e.reverse())try{await t()}catch(i){$.logError(i,{verbose:!1})}}checkNodeVersion(e){try{let t=process.version.slice(1).split(".").map(Number),i=e.split(".").map(Number);for(let r=0;r<Math.max(t.length,i.length);r++){let s=t[r]||0,n=i[r]||0;if(isNaN(s)||isNaN(n))return g.warn(`Invalid version number at position ${r}`),!1;if(s>n)return!0;if(s<n)return!1}return!0}catch(t){return g.error(`Version check failed: ${t}`),!1}}};import ke from"fs-extra";import Ze from"path";var pe=class extends b{code=f.PROJECT_NOT_FOUND;isRecoverable=!1;get solution(){let{suggestion:e}=this.context||{};return e?`Run '${e}' to initialize a new project.`:"Please run this command from a project root with a package.json file."}},K=class extends b{code=f.PROJECT_INVALID;isRecoverable=!1;get solution(){let{parseError:e}=this.context||{};return e?`Fix JSON syntax error: ${e}`:"Please ensure package.json is valid JSON format."}};async function Me(d){let e=Ze.join(d,"package.json");if(!await h(e))throw new pe("No package.json found in project directory",{projectPath:d,searchedPath:e,hasPackageJson:!1,suggestion:"npm init"});try{let t=await ke.readFile(e,"utf-8"),i=JSON.parse(t);if(typeof i!="object"||i===null)throw new Error("package.json must be an object");return i}catch(t){if(t instanceof SyntaxError)throw new K("Invalid package.json format",{projectPath:d,hasPackageJson:!0,parseError:t.message},t);if(T(t)){let i=t;throw new m(f.FILE_READ_ERROR,`Failed to read package.json: ${t.message}`,!1,{packageJsonPath:e,errorCode:i.code,syscall:i.syscall},"Check file permissions and try again.")}throw new m(f.FILE_READ_ERROR,t instanceof Error?`Failed to read package.json: ${t.message}`:"Failed to read package.json",!1,{packageJsonPath:e},"Check file permissions and try again.")}}async function h(d){try{return await ke.pathExists(d)}catch{return!1}}async function Ae(d){try{return await ke.readFile(d,"utf-8")}catch(e){if(T(e)){let t=e;if(t.code==="ENOENT")throw new m(f.FILE_NOT_FOUND,`File not found: ${d}`,!1,{filePath:d});if(t.code==="EACCES"||t.code==="EPERM")throw new m(f.FILE_PERMISSION_ERROR,`Permission denied reading file: ${d}`,!1,{filePath:d,errorCode:t.code},"Check file permissions")}throw new m(f.FILE_READ_ERROR,e instanceof Error?`Failed to read file: ${e.message}`:"Failed to read file",!1,{filePath:d})}}import De from"path";import{unlink as et}from"fs/promises";import*as u from"@clack/prompts";import q from"chalk";var J={charset:[{value:"utf-8",label:"UTF-8",hint:"Recommended for most projects"},{value:"latin1",label:"Latin-1",hint:"Legacy encoding"}],end_of_line:[{value:"lf",label:"LF (Unix)",hint:"Recommended for Git compatibility"},{value:"crlf",label:"CRLF (Windows)",hint:"Windows native"},{value:"cr",label:"CR (Classic Mac)",hint:"Rarely used"}],indent_style:[{value:"space",label:"Spaces",hint:"More consistent across editors"},{value:"tab",label:"Tabs",hint:"Allows personal width preference"}],indent_size:[{value:"2",label:"2",hint:"Common in JS/TS projects"},{value:"4",label:"4",hint:"Common in Python/Java"},{value:"8",label:"8",hint:"Traditional tab width"},{value:"custom",label:"Custom",hint:"Enter your own value"}],max_line_length:[{value:"80",label:"80",hint:"Traditional terminal width"},{value:"100",label:"100",hint:"Common in modern projects"},{value:"120",label:"120",hint:"Comfortable for wide screens"},{value:"off",label:"No limit",hint:"Let formatter decide"},{value:"custom",label:"Custom",hint:"Enter your own value"}]},x={charset:{utf8:{key:"charset",value:"utf-8",description:"UTF-8 encoding"},latin1:{key:"charset",value:"latin1",description:"Latin-1 encoding"}},endOfLine:{lf:{key:"end_of_line",value:"lf",description:"Unix-style (LF)"},crlf:{key:"end_of_line",value:"crlf",description:"Windows-style (CRLF)"},cr:{key:"end_of_line",value:"cr",description:"Old Mac-style (CR)"}},indentStyle:{space:{key:"indent_style",value:"space",description:"Use spaces"},tab:{key:"indent_style",value:"tab",description:"Use tabs"}},indentSize:{two:{key:"indent_size",value:2,description:"2 spaces"},four:{key:"indent_size",value:4,description:"4 spaces"},eight:{key:"indent_size",value:8,description:"8 spaces"}},trimTrailingWhitespace:{yes:{key:"trim_trailing_whitespace",value:!0,description:"Remove trailing spaces"},no:{key:"trim_trailing_whitespace",value:!1,description:"Keep trailing spaces"}},insertFinalNewline:{yes:{key:"insert_final_newline",value:!0,description:"Add newline at EOF"},no:{key:"insert_final_newline",value:!1,description:"No newline at EOF"}}},xe={javascript:{pattern:"*.{js,jsx,mjs,cjs}",description:"JavaScript files",recommendedRules:[x.indentStyle.space,x.indentSize.two],optionalRules:[{key:"max_line_length",value:100,description:"Line length limit"}]},typescript:{pattern:"*.{ts,tsx}",description:"TypeScript files",recommendedRules:[x.indentStyle.space,x.indentSize.two],optionalRules:[{key:"max_line_length",value:100,description:"Line length limit"}]},python:{pattern:"*.py",description:"Python files",recommendedRules:[x.indentStyle.space,x.indentSize.four,{key:"max_line_length",value:88,description:"Black formatter default"}],optionalRules:[]},markdown:{pattern:"*.md",description:"Markdown files",recommendedRules:[x.trimTrailingWhitespace.no],optionalRules:[{key:"max_line_length",value:80,description:"Readable line length"}]},makefile:{pattern:"Makefile",description:"Makefiles",recommendedRules:[x.indentStyle.tab],optionalRules:[]},yaml:{pattern:"*.{yml,yaml}",description:"YAML files",recommendedRules:[x.indentStyle.space,x.indentSize.two],optionalRules:[]},json:{pattern:"*.json",description:"JSON files",recommendedRules:[x.indentStyle.space,x.indentSize.two],optionalRules:[]},css:{pattern:"*.{css,scss,sass,less}",description:"Style files",recommendedRules:[x.indentStyle.space,x.indentSize.two],optionalRules:[{key:"max_line_length",value:80,description:"Line length limit"}]}};var de=class{sections=[];globalRules=[];async build(e){u.intro(q.blue("\u{1F527} EditorConfig Interactive Setup")),await this.setupGlobalRules(),await this.setupFileTypeRules(e),await this.setupCustomRules();let t=this.generatePreview();u.log.message(""),u.log.info("\u{1F4C4} Generated Configuration Preview:"),u.log.message(q.gray(t));let i=await u.confirm({message:"Apply this configuration?",initialValue:!0});if(!i||u.isCancel(i))throw u.cancel("Configuration cancelled"),new Error("Configuration cancelled");return u.outro(q.green("\u2705 EditorConfig setup complete!")),this.generate()}async setupGlobalRules(){u.log.step(q.cyan("Global Rules Configuration")),u.log.message(`These rules will apply to all files by default
`);let e=await u.select({message:"Character encoding",options:J.charset});if(u.isCancel(e))throw u.cancel("Setup cancelled"),new Error("Cancelled");this.globalRules.push({key:"charset",value:e});let t=await u.select({message:"Line ending style",options:J.end_of_line});if(u.isCancel(t))throw u.cancel("Setup cancelled"),new Error("Cancelled");this.globalRules.push({key:"end_of_line",value:t});let i=await u.select({message:"Indentation style",options:J.indent_style});if(u.isCancel(i))throw u.cancel("Setup cancelled"),new Error("Cancelled");if(this.globalRules.push({key:"indent_style",value:i}),i==="space"){let s=await u.select({message:"Indentation size",options:J.indent_size});if(u.isCancel(s))throw u.cancel("Setup cancelled"),new Error("Cancelled");if(s==="custom"){let n=await u.text({message:"Enter custom indent size (1-16)",validate:a=>{let l=parseInt(a);if(isNaN(l)||l<1||l>16)return"Please enter a number between 1 and 16"}});if(u.isCancel(n))throw u.cancel("Setup cancelled"),new Error("Cancelled");this.globalRules.push({key:"indent_size",value:parseInt(n)})}else this.globalRules.push({key:"indent_size",value:s})}let r=await u.multiselect({message:"Additional global rules",options:[{value:"trim_trailing_whitespace",label:"Trim trailing whitespace",hint:"Remove spaces at line endings"},{value:"insert_final_newline",label:"Insert final newline",hint:"Ensure files end with newline"}],initialValues:["trim_trailing_whitespace","insert_final_newline"],required:!1});if(!u.isCancel(r))for(let s of r)this.globalRules.push({key:s,value:!0});u.log.success(`Global rules configured
`)}async setupFileTypeRules(e){u.log.step(q.cyan("File Type Specific Rules"));let t=this.detectFileTypes(e);if(t.length===0){u.log.warning("No specific file types detected");return}u.log.message(`Detected file types in your project:
`);let i=await u.multiselect({message:"Select file types to configure",options:t.map(r=>({value:r.key,label:r.label,hint:r.hint})),initialValues:t.map(r=>r.key),required:!1});if(!(u.isCancel(i)||i.length===0)){for(let r of i){let s=xe[r];if(!s)continue;u.log.info(`
Configuring ${s.description}`);let n=await u.select({message:`How would you like to configure ${s.description}?`,options:[{value:"recommended",label:"Use recommended settings",hint:"Quick setup"},{value:"customize",label:"Customize settings",hint:"Fine-tune rules"},{value:"skip",label:"Skip",hint:"Use global rules only"}]});u.isCancel(n)||n==="skip"||(n==="recommended"?this.sections.push({pattern:s.pattern,rules:[...s.recommendedRules],description:s.description}):await this.customizeFileType(s))}this.sections.length>0&&u.log.success(`
File type rules configured for ${this.sections.length} patterns`)}}async customizeFileType(e){let t=[],i=await u.confirm({message:"Override global indentation settings?",initialValue:!1});if(!u.isCancel(i)&&i){let s=await u.select({message:`Indentation style for ${e.description}`,options:J.indent_style});if(!u.isCancel(s)&&(t.push({key:"indent_style",value:s}),s==="space")){let n=await u.select({message:`Indentation size for ${e.description}`,options:J.indent_size.filter(a=>a.value!=="custom")});u.isCancel(n)||t.push({key:"indent_size",value:n})}}let r=await u.confirm({message:"Set maximum line length?",initialValue:!1});if(!u.isCancel(r)&&r){let s=await u.select({message:"Maximum line length",options:J.max_line_length});if(!u.isCancel(s))if(s==="custom"){let n=await u.text({message:"Enter custom max line length",validate:a=>{let l=parseInt(a);if(isNaN(l)||l<1)return"Please enter a positive number"}});u.isCancel(n)||t.push({key:"max_line_length",value:parseInt(n)})}else s!=="off"&&t.push({key:"max_line_length",value:s})}if(e.optionalRules&&e.optionalRules.length>0){let s=await u.multiselect({message:`Additional rules for ${e.description}`,options:e.optionalRules.map(n=>({value:n.key,label:`${n.key} = ${n.value}`,hint:n.description})),required:!1});if(!u.isCancel(s))for(let n of s){let a=e.optionalRules.find(l=>l.key===n);a&&t.push(a)}}this.sections.push({pattern:e.pattern,rules:t,description:e.description})}async setupCustomRules(){let e=await u.confirm({message:`
Add custom file patterns?`,initialValue:!1});if(!e||u.isCancel(e))return;u.log.step(q.cyan("Custom Pattern Configuration"));let t=!0;for(;t;){let i=await u.text({message:"File pattern (e.g., *.{css,scss} or src/**/*.js)",placeholder:"*.{css,scss}"});if(u.isCancel(i))break;let r=[],s=await u.confirm({message:`Add specific rules for ${i}?`,initialValue:!0});if(!u.isCancel(s)&&s){let a=await u.confirm({message:"Set custom indentation?",initialValue:!1});if(!u.isCancel(a)&&a){let l=await u.text({message:"Indent size",placeholder:"2",validate:y=>{let R=parseInt(y);if(isNaN(R)||R<1||R>16)return"Please enter a number between 1 and 16"}});u.isCancel(l)||r.push({key:"indent_size",value:parseInt(l)})}}this.sections.push({pattern:i,rules:r,description:"Custom pattern"});let n=await u.confirm({message:"Add another custom pattern?",initialValue:!1});(u.isCancel(n)||!n)&&(t=!1)}}detectFileTypes(e){let t=[],i={...e.packageJson.dependencies,...e.packageJson.devDependencies},r=["json","yaml","markdown"];t.push({key:"javascript",label:"JavaScript (.js, .jsx)",hint:"Essential for Node.js projects"}),e.hasTypeScript&&t.push({key:"typescript",label:"TypeScript (.ts, .tsx)",hint:"TypeScript configuration detected"}),(i.sass||i.less||i["styled-components"]||i.emotion||e.projectType==="next"||e.projectType==="vite")&&t.push({key:"css",label:"Styles (.css, .scss, .sass, .less)",hint:"Style files detected"}),(i.python||i.django||i.flask)&&t.push({key:"python",label:"Python (.py)",hint:"Python dependencies detected"}),(i["node-gyp"]||i["cmake-js"])&&t.push({key:"makefile",label:"Makefile",hint:"Native build system detected"});for(let s of r){let n=xe[s];n&&t.push({key:s,label:n.description,hint:"Commonly used"})}return t}generatePreview(){let e=this.generate().split(`
`),t=20;return e.length<=t?e.join(`
`):e.slice(0,t).join(`
`)+`
...`}generate(){let e=["# EditorConfig is awesome: https://EditorConfig.org","","root = true",""];if(this.globalRules.length>0){e.push("[*]");for(let t of this.globalRules)e.push(`${t.key} = ${t.value}`);e.push("")}for(let t of this.sections){if(t.description&&e.push(`# ${t.description}`),e.push(`[${t.pattern}]`),t.rules.length>0)for(let i of t.rules)e.push(`${i.key} = ${i.value}`);e.push("")}for(;e[e.length-1]==="";)e.pop();return e.join(`
`)}};var ee=class extends _{generatedContent;constructor(){super({name:"editorconfig",displayName:"EditorConfig",description:"Consistent coding styles across different editors",detectFiles:[".editorconfig"],conflicts:[],version:"1.0.0"})}async isInstalled(e){try{return await h(De.join(e,".editorconfig"))}catch{return!1}}async validate(e){let t={valid:!0,errors:[],warnings:[]};try{let i=await this.isInstalled(e.projectPath);return i&&!e.force?(t.valid=!1,t.errors.push(".editorconfig already exists. Use --force to overwrite."),t):(i&&e.force&&t.warnings.push("Existing .editorconfig will be overwritten"),t)}catch(i){t.valid=!1;let r=i instanceof Error?i.message:String(i);return t.errors.push(`Validation failed: ${r}`),t}}async getDependencies(){return{}}async getFilesToCreate(e){let t=new Map;try{let i;if(!e.dryRun&&!this.generatedContent){let r=new de;try{this.generatedContent=await r.build(e),i=this.generatedContent}catch(s){throw s instanceof Error&&s.message==="Configuration cancelled"?new m(f.USER_CANCELLED,"EditorConfig setup cancelled by user",!1):s}}else this.generatedContent?i=this.generatedContent:(i=this.generateDefaultConfig(e),e.verbose&&g.info("Using default EditorConfig configuration"));return t.set(".editorconfig",i),t}catch(i){throw i instanceof C?i:new m(f.CONFIG_GENERATION_FAILED,"Failed to generate .editorconfig content",!1,{module:this.name,error:i instanceof Error?i.message:String(i)})}}async getFilesToModify(){return new Map}async uninstall(e){let t={success:!1,errors:[],hints:[]};try{let i=De.join(e.projectPath,".editorconfig");if(!await h(i))throw new A(".editorconfig file not found",{path:i,operation:"delete"});try{await et(i),t.success=!0,t.message=".editorconfig removed successfully",e.verbose&&g.success("EditorConfig configuration removed")}catch(r){throw r.code==="EACCES"?new m(f.FILE_PERMISSION_ERROR,"Permission denied while removing .editorconfig",!1,{path:i,errorCode:r.code},"Try running with elevated permissions (sudo)"):r}}catch(i){if(i instanceof C)t.errors?.push(i);else{let r=i instanceof Error?i.message:String(i);t.errors?.push(new m(f.MODULE_UNINSTALL_FAILED,`Failed to uninstall EditorConfig: ${r}`,!1,{module:this.name,originalError:r}))}}return t}generateDefaultConfig(e){let t=["# EditorConfig is awesome: https://EditorConfig.org","","root = true","","[*]","charset = utf-8","end_of_line = lf","insert_final_newline = true","trim_trailing_whitespace = true","indent_style = space","indent_size = 2",""];t.push("[*.md]","trim_trailing_whitespace = false",""),t.push("[*.{json,yml,yaml}]","indent_size = 2",""),["next","vite","react","node"].includes(e.projectType)&&(t.push("[*.{js,jsx,mjs,cjs}]","indent_size = 2",""),e.hasTypeScript&&t.push("[*.{ts,tsx}]","indent_size = 2","")),t.push("[Makefile]","indent_style = tab","");let i=e.packageJson.prettier;if(i&&typeof i=="object"){if("tabWidth"in i&&typeof i.tabWidth=="number")return t.join(`
`).replace(/indent_size = \d+/g,`indent_size = ${i.tabWidth}`);if("useTabs"in i&&i.useTabs===!0)return t.join(`
`).replace(/indent_style = space/g,"indent_style = tab")}return t.join(`
`)}};import X from"path";import*as o from"@clack/prompts";import E from"chalk";var Q={targets:[{value:"ES2022",label:"ES2022",hint:"Node 16+ and modern browsers"},{value:"ES2020",label:"ES2020",hint:"Node 14+ and 2020+ browsers"},{value:"ES2017",label:"ES2017",hint:"Wider compatibility"},{value:"ES2015",label:"ES2015",hint:"Maximum compatibility"},{value:"ESNext",label:"ESNext",hint:"Latest features (unstable)"}],modules:[{value:"NodeNext",label:"NodeNext",hint:"Modern Node.js with ESM"},{value:"ESNext",label:"ESNext",hint:"Latest ES modules"},{value:"ES2022",label:"ES2022",hint:"ES2022 modules"},{value:"CommonJS",label:"CommonJS",hint:"Traditional Node.js"},{value:"AMD",label:"AMD",hint:"Asynchronous Module Definition"},{value:"UMD",label:"UMD",hint:"Universal Module Definition"},{value:"System",label:"System",hint:"SystemJS loader"}],moduleResolution:[{value:"bundler",label:"Bundler",hint:"For modern bundlers (recommended)"},{value:"node",label:"Node",hint:"Node.js style resolution"},{value:"node16",label:"Node16",hint:"Node.js 16+ with ESM"},{value:"nodenext",label:"NodeNext",hint:"Latest Node.js resolution"},{value:"classic",label:"Classic",hint:"Legacy TypeScript resolution"}],strictness:[{value:"strict",label:"Strict",hint:"Maximum type safety (recommended)"},{value:"moderate",label:"Moderate",hint:"Balanced for migration"},{value:"loose",label:"Loose",hint:"Minimal checks"},{value:"custom",label:"Custom",hint:"Choose individual options"}],jsx:[{value:"preserve",label:"Preserve",hint:"Keep JSX for bundler"},{value:"react-jsx",label:"React 17+",hint:"New JSX transform"},{value:"react-jsxdev",label:"React Dev",hint:"Development mode"},{value:"react",label:"React Classic",hint:"React.createElement"},{value:"react-native",label:"React Native",hint:"For RN projects"}],libs:[{value:"default",label:"Default",hint:"Based on target"},{value:"dom",label:"DOM",hint:"Browser APIs"},{value:"webworker",label:"WebWorker",hint:"Worker APIs"},{value:"esnext",label:"ESNext",hint:"Latest ES features"},{value:"node",label:"Node",hint:"Node.js globals"},{value:"custom",label:"Custom",hint:"Select individually"}]},S={"next-app":{name:"Next.js App Router",description:"Next.js 13+ with App Router",config:{compilerOptions:{target:"ES2022",lib:["dom","dom.iterable","esnext"],allowJs:!0,skipLibCheck:!0,strict:!0,noEmit:!0,esModuleInterop:!0,module:"esnext",moduleResolution:"bundler",resolveJsonModule:!0,isolatedModules:!0,jsx:"preserve",incremental:!0,plugins:[{name:"next"}],paths:{"@/*":["./src/*"]}},include:["next-env.d.ts","**/*.ts","**/*.tsx",".next/types/**/*.ts"],exclude:["node_modules"]}},"next-pages":{name:"Next.js Pages Router",description:"Next.js with Pages Router",config:{compilerOptions:{target:"ES2022",lib:["dom","dom.iterable","esnext"],allowJs:!0,skipLibCheck:!0,strict:!0,forceConsistentCasingInFileNames:!0,noEmit:!0,esModuleInterop:!0,module:"esnext",moduleResolution:"node",resolveJsonModule:!0,isolatedModules:!0,jsx:"preserve",incremental:!0,paths:{"@/*":["./src/*"]}},include:["next-env.d.ts","**/*.ts","**/*.tsx"],exclude:["node_modules"]}},"vite-react":{name:"Vite + React",description:"Vite with React and HMR",config:{compilerOptions:{target:"ES2022",useDefineForClassFields:!0,lib:["ES2022","DOM","DOM.Iterable"],module:"ESNext",skipLibCheck:!0,moduleResolution:"bundler",allowImportingTsExtensions:!0,isolatedModules:!0,moduleDetection:"force",noEmit:!0,jsx:"react-jsx",strict:!0,noUnusedLocals:!0,noUnusedParameters:!0,noFallthroughCasesInSwitch:!0,paths:{"@/*":["./src/*"]}},include:["src"],references:[{path:"./tsconfig.node.json"}]},additionalFiles:{"tsconfig.node.json":JSON.stringify({compilerOptions:{target:"ES2022",lib:["ES2023"],module:"ESNext",skipLibCheck:!0,moduleResolution:"bundler",allowSyntheticDefaultImports:!0,strict:!0,types:["vite/client"]},include:["vite.config.ts"]},null,2)}},"vite-vue":{name:"Vite + Vue",description:"Vite with Vue 3",config:{compilerOptions:{target:"ES2022",module:"ESNext",moduleResolution:"bundler",lib:["ES2022","DOM","DOM.Iterable"],skipLibCheck:!0,noEmit:!0,isolatedModules:!0,moduleDetection:"force",jsx:"preserve",strict:!0,esModuleInterop:!0,allowSyntheticDefaultImports:!0,types:["vite/client","@types/node"],paths:{"@/*":["./src/*"]}},include:["src/**/*.ts","src/**/*.tsx","src/**/*.vue"],references:[{path:"./tsconfig.node.json"}]}},"node-esm":{name:"Node.js ESM",description:"Modern Node.js with ES Modules",config:{compilerOptions:{target:"ES2022",module:"NodeNext",moduleResolution:"NodeNext",lib:["ES2022"],outDir:"./dist",rootDir:"./src",strict:!0,esModuleInterop:!0,skipLibCheck:!0,forceConsistentCasingInFileNames:!0,resolveJsonModule:!0,declaration:!0,declarationMap:!0,sourceMap:!0,allowSyntheticDefaultImports:!0,types:["node"]},include:["src/**/*"],exclude:["node_modules","dist"],"ts-node":{esm:!0,experimentalSpecifierResolution:"node"}}},"node-commonjs":{name:"Node.js CommonJS",description:"Traditional Node.js with CommonJS",config:{compilerOptions:{target:"ES2022",module:"CommonJS",moduleResolution:"node",lib:["ES2022"],outDir:"./dist",rootDir:"./src",strict:!0,esModuleInterop:!0,skipLibCheck:!0,forceConsistentCasingInFileNames:!0,resolveJsonModule:!0,declaration:!0,sourceMap:!0},include:["src/**/*"],exclude:["node_modules","dist"]}},"express-api":{name:"Express API",description:"Express.js REST API server",config:{compilerOptions:{target:"ES2022",module:"CommonJS",moduleResolution:"node",lib:["ES2022"],outDir:"./dist",rootDir:"./src",strict:!0,esModuleInterop:!0,skipLibCheck:!0,forceConsistentCasingInFileNames:!0,resolveJsonModule:!0,types:["node","express"],typeRoots:["./node_modules/@types","./src/types"]},include:["src/**/*"],exclude:["node_modules","dist","**/*.spec.ts"]}},"react-library":{name:"React Component Library",description:"Publishable React component library",config:{compilerOptions:{target:"ES2020",module:"ESNext",moduleResolution:"bundler",lib:["ES2020","DOM","DOM.Iterable"],jsx:"react-jsx",declaration:!0,declarationMap:!0,outDir:"./dist",rootDir:"./src",strict:!0,esModuleInterop:!0,skipLibCheck:!0,forceConsistentCasingInFileNames:!0,resolveJsonModule:!1,isolatedModules:!0,types:["react","react-dom"]},include:["src/**/*"],exclude:["node_modules","dist","**/*.test.ts","**/*.test.tsx","**/*.stories.tsx"]}},"node-library":{name:"Node.js Library",description:"Publishable Node.js package",config:{compilerOptions:{target:"ES2020",module:"CommonJS",moduleResolution:"node",lib:["ES2020"],declaration:!0,declarationMap:!0,outDir:"./dist",rootDir:"./src",strict:!0,esModuleInterop:!0,skipLibCheck:!0,forceConsistentCasingInFileNames:!0,resolveJsonModule:!0,types:["node"]},include:["src/**/*"],exclude:["node_modules","dist","**/*.test.ts"]}},"monorepo-root":{name:"Monorepo Root",description:"Root configuration for monorepo",config:{compilerOptions:{target:"ES2022",module:"ESNext",moduleResolution:"node",composite:!0,declaration:!0,declarationMap:!0,strict:!0,esModuleInterop:!0,skipLibCheck:!0,forceConsistentCasingInFileNames:!0},files:[],references:[{path:"./packages/*/tsconfig.json"}]}},"monorepo-package":{name:"Monorepo Package",description:"Package within a monorepo",config:{extends:"../../tsconfig.json",compilerOptions:{outDir:"./dist",rootDir:"./src",composite:!0,declaration:!0,declarationMap:!0},include:["src/**/*"],exclude:["node_modules","dist"]}},"react-native":{name:"React Native",description:"React Native with TypeScript",config:{compilerOptions:{target:"ESNext",module:"CommonJS",lib:["ES2022"],jsx:"react-native",strict:!0,esModuleInterop:!0,skipLibCheck:!0,moduleResolution:"node",resolveJsonModule:!0,allowSyntheticDefaultImports:!0,types:["react-native","jest"]},exclude:["node_modules","babel.config.js","metro.config.js","jest.config.js"]}},electron:{name:"Electron",description:"Electron desktop application",config:{compilerOptions:{target:"ES2022",module:"CommonJS",lib:["ES2022","DOM"],outDir:"./dist",rootDir:"./src",strict:!0,esModuleInterop:!0,skipLibCheck:!0,moduleResolution:"node",resolveJsonModule:!0,types:["node","electron"]},include:["src/**/*"],exclude:["node_modules","dist"]}}},te={experimental:[{value:"experimentalDecorators",label:"Decorators",hint:"Enable decorators"},{value:"emitDecoratorMetadata",label:"Decorator Metadata",hint:"For reflection"},{value:"useDefineForClassFields",label:"Class Fields",hint:"Standard behavior"}],output:[{value:"declaration",label:"Type Declarations",hint:"Generate .d.ts files"},{value:"declarationMap",label:"Declaration Maps",hint:"Source maps for .d.ts"},{value:"sourceMap",label:"Source Maps",hint:"For debugging"},{value:"inlineSourceMap",label:"Inline Source Maps",hint:"Embed in output"},{value:"removeComments",label:"Remove Comments",hint:"Strip comments"},{value:"preserveConstEnums",label:"Preserve Const Enums",hint:"Keep enums"}],imports:[{value:"allowSyntheticDefaultImports",label:"Synthetic Default Imports",hint:"import React"},{value:"allowImportingTsExtensions",label:"TS Extensions",hint:"import './file.ts'"},{value:"allowArbitraryExtensions",label:"Arbitrary Extensions",hint:"Any file type"},{value:"resolvePackageJsonExports",label:"Package Exports",hint:"Use exports field"},{value:"resolvePackageJsonImports",label:"Package Imports",hint:"Use imports field"}],checks:[{value:"noUnusedLocals",label:"No Unused Locals",hint:"Error on unused vars"},{value:"noUnusedParameters",label:"No Unused Parameters",hint:"Error on unused params"},{value:"noImplicitReturns",label:"No Implicit Returns",hint:"All paths return"},{value:"noFallthroughCasesInSwitch",label:"No Fallthrough",hint:"Explicit breaks"},{value:"noUncheckedIndexedAccess",label:"Checked Index Access",hint:"Safer arrays"},{value:"noPropertyAccessFromIndexSignature",label:"No Index Access",hint:"Use bracket notation"},{value:"exactOptionalPropertyTypes",label:"Exact Optional",hint:"No undefined assignment"}]};function ie(d){let e={...d.packageJson.dependencies,...d.packageJson.devDependencies};return e.next?d.hasSrcDirectory&&d.packageJson.scripts?.dev?.includes("next dev")?"next-app":"next-pages":e.vite?e.vue?"vite-vue":(e.react,"vite-react"):e["react-native"]?"react-native":e.electron?"electron":e.express||e.fastify||e.koa?"express-api":d.packageJson.main||d.packageJson.exports?e.react?"react-library":"node-library":d.packageJson.workspaces?"monorepo-root":e.react?"react":"node-esm"}function $e(){return{typeChecking:[{value:"noImplicitAny",label:"No Implicit Any",default:!0},{value:"strictNullChecks",label:"Strict Null Checks",default:!0},{value:"strictFunctionTypes",label:"Strict Function Types",default:!0},{value:"strictBindCallApply",label:"Strict Bind/Call/Apply",default:!0},{value:"strictPropertyInitialization",label:"Strict Property Init",default:!0},{value:"noImplicitThis",label:"No Implicit This",default:!0},{value:"alwaysStrict",label:"Always Strict Mode",default:!0}],codeQuality:[{value:"noUnusedLocals",label:"No Unused Locals",default:!1},{value:"noUnusedParameters",label:"No Unused Parameters",default:!1},{value:"noImplicitReturns",label:"No Implicit Returns",default:!1},{value:"noFallthroughCasesInSwitch",label:"No Switch Fallthrough",default:!1},{value:"noUncheckedIndexedAccess",label:"Checked Array Access",default:!1}]}}import Je from"path";import tt from"path";var H=class{async analyze(e){let t={isValid:!1,config:null,errors:[],warnings:[],suggestions:[]};try{let i=await Ae(tt.join(e,"tsconfig.json"));try{t.config=JSON.parse(i),t.isValid=!0}catch{return t.errors.push("Invalid JSON format"),t}return this.analyzeCompilerOptions(t),this.analyzeIncludes(t),this.checkCommonIssues(t),t}catch(i){return t.errors.push(`Failed to read tsconfig.json: ${i}`),t}}analyzeCompilerOptions(e){let{compilerOptions:t}=e.config;if(!t){e.warnings.push("No compilerOptions found");return}t.target||e.warnings.push("No target specified, defaulting to ES3"),t.module||e.warnings.push("No module system specified"),!t.strict&&!t.strictNullChecks&&e.suggestions.push("Consider enabling strict mode for better type safety"),(t.target==="ES5"||t.target==="ES6")&&e.suggestions.push("Consider upgrading target to ES2022 for modern JavaScript features")}analyzeIncludes(e){!e.config.include&&!e.config.files&&e.warnings.push("No 'include' or 'files' specified. All TypeScript files will be included.")}checkCommonIssues(e){let{compilerOptions:t}=e.config;t?.jsx&&!t.target?.includes("ES")&&e.warnings.push("JSX requires ES target for proper support"),t?.paths&&!t.baseUrl&&e.errors.push("'paths' requires 'baseUrl' to be specified")}};var ue=class{config={};selectedPreset=null;presetKey=null;async build(e){o.intro(E.blue("\u{1F527} TypeScript Configuration Setup")),await this.checkExistingConfig(e);let t=await o.select({message:"How would you like to set it up?",options:[{value:"quick",label:"\u{1F680} Quick setup",hint:"Automatically choose an optimized preset for your project"},{value:"custom",label:"\u{1F6E0}\uFE0F Custom setup",hint:"Configure step-by-step with fine-grained options"}]});if(o.isCancel(t))throw o.cancel("Setup canceled"),new Error("Cancelled");return t==="quick"?await this.quickSetup(e):await this.customSetup(e)}async quickSetup(e){let t=ie(e);if(t){let i=S[t];if(!i)return o.log.warning("Could not find the detected preset"),await this.selectPresetManually(e);o.log.info(`
\u{1F3AF} Detected project type: ${E.cyan(i.name)}`),o.log.message(E.gray(` ${i.description}`));let r=await o.confirm({message:"Would you like to review the configuration details?",initialValue:!1});!o.isCancel(r)&&r&&(o.log.message(`
\u{1F4CB} Configuration to be applied:`),this.displayPresetDetails(i));let s=await o.confirm({message:`Apply ${i.name} configuration?`,initialValue:!0});if(o.isCancel(s))throw o.cancel("Setup canceled"),new Error("Cancelled");if(!s)return o.log.info("Please select a different preset"),await this.selectPresetManually(e);this.selectedPreset=i,this.presetKey=t,this.config=JSON.parse(JSON.stringify(i.config));let n=await o.confirm({message:"Would you like to add customizations?",initialValue:!1});!o.isCancel(n)&&n&&await this.quickCustomize(e)}else return o.log.warning("Could not automatically detect the project type"),await this.selectPresetManually(e);return this.finalizeConfiguration()}async customSetup(e){this.selectedPreset=await this.selectFramework(e),this.config=JSON.parse(JSON.stringify(this.selectedPreset.config));let t=[{name:"Target",fn:()=>this.configureTarget()},{name:"Module system",fn:()=>this.configureModuleSystem()},{name:"Type-checking strictness",fn:()=>this.configureStrictness()},{name:"Path aliases",fn:()=>this.configurePathAliases(e)},{name:"Type libraries",fn:()=>this.configureLibraries()},{name:"Additional options",fn:()=>this.configureAdditionalOptions(e)},{name:"File patterns",fn:()=>this.configureFilePatterns(e)}];o.log.info(E.cyan(`
Setup steps:`)),t.forEach((i,r)=>{o.log.message(E.gray(` ${r+1}. ${i.name}`))});for(let i of t){let r=await o.confirm({message:`Skip "${i.name}"?`,initialValue:!1});if(o.isCancel(r))throw o.cancel("Setup canceled"),new Error("Cancelled");r||await i.fn()}return this.finalizeConfiguration()}async selectPresetManually(e){let t=Object.entries(S).map(([s,n])=>({value:s,label:n.name,hint:n.description})),i=await o.select({message:"Select a preset",options:t});if(o.isCancel(i))throw o.cancel("Setup canceled"),new Error("Cancelled");this.selectedPreset=S[i],this.presetKey=i,this.config=JSON.parse(JSON.stringify(this.selectedPreset.config));let r=await o.confirm({message:"Would you like to customize the configuration?",initialValue:!1});return!o.isCancel(r)&&r&&await this.quickCustomize(e),this.finalizeConfiguration()}async quickCustomize(e){let t=await o.multiselect({message:"Select items to customize",options:[{value:"paths",label:"Path aliases (@/*, etc.)"},{value:"strict",label:"Type-checking strictness"},{value:"target",label:"Compilation target (ES2022, ES2020, etc.)"},{value:"output",label:"Output options (source maps, declarations, etc.)"}],required:!1});if(!o.isCancel(t))for(let i of t)switch(i){case"paths":await this.configurePathAliases(e);break;case"strict":await this.configureStrictness();break;case"target":await this.configureTarget();break;case"output":await this.configureOutputOptions();break}}async configureOutputOptions(){let e=await o.multiselect({message:"Choose output options",options:[{value:"sourceMap",label:"Generate source maps"},{value:"declaration",label:"Emit declaration files (.d.ts)"},{value:"declarationMap",label:"Emit declaration source maps"},{value:"removeComments",label:"Remove comments"}],initialValues:["sourceMap"]});o.isCancel(e)||e.forEach(t=>{this.config.compilerOptions[t]=!0})}displayPresetDetails(e){let{compilerOptions:t}=e.config;o.log.message(E.gray(` \u2022 Target: ${t.target}`)),o.log.message(E.gray(` \u2022 Module: ${t.module}`)),o.log.message(E.gray(` \u2022 Strict mode: ${t.strict?"Enabled":"Disabled"}`)),t.jsx&&o.log.message(E.gray(` \u2022 JSX: ${t.jsx}`)),t.paths&&o.log.message(E.gray(` \u2022 Path aliases: ${Object.keys(t.paths).join(", ")}`)),e.additionalFiles&&o.log.message(E.gray(` \u2022 Additional files: ${Object.keys(e.additionalFiles).join(", ")}`))}async finalizeConfiguration(){let e=this.generatePreview();o.log.message(""),o.log.info("\u{1F4C4} Final configuration preview:"),o.log.message(E.gray(e));let t=await o.confirm({message:"Apply this configuration?",initialValue:!0});if(!t||o.isCancel(t))throw o.cancel("Setup canceled"),new Error("Configuration cancelled");return this.selectedPreset.additionalFiles&&(o.log.info(E.yellow(`
\u{1F4DD} Additional files to be created:`)),Object.keys(this.selectedPreset.additionalFiles).forEach(i=>{o.log.message(E.gray(` \u2022 ${i}`))})),o.outro(E.green("\u2705 TypeScript configuration completed!")),{config:JSON.stringify(this.config,null,2),additionalFiles:this.selectedPreset?.additionalFiles,presetKey:this.presetKey}}async checkExistingConfig(e){let t=Je.join(e.projectPath,"tsconfig.json");if(await h(t)){let r=await new H().analyze(e.projectPath);if(r.isValid){o.log.warning("Found existing tsconfig.json"),r.warnings.length>0&&(o.log.message(E.yellow(`
\u26A0\uFE0F Issues found:`)),r.warnings.forEach(n=>{o.log.message(E.gray(` \u2022 ${n}`))}));let s=await o.select({message:"How would you like to proceed?",options:[{value:"merge",label:"Merge with existing",hint:"Keep custom settings and update defaults"},{value:"replace",label:"Replace entirely",hint:"Start with fresh configuration"},{value:"cancel",label:"Cancel",hint:"Keep existing configuration"}]});if(o.isCancel(s)||s==="cancel")throw o.cancel("Keeping existing configuration"),new Error("Cancelled");this.config._action=s}}}async selectFramework(e){let t=ie(e);if(t){let a=S[t];o.log.info(`Detected project type: ${E.cyan(a?.name)}`);let l=await o.confirm({message:`Use ${a?.name} optimized settings?"`,initialValue:!0});if(o.isCancel(l))throw o.cancel("Setup cancelled"),new Error("Cancelled");if(l)return a}let i=await o.select({message:"What type of project is this?",options:[{value:"frontend",label:"Frontend Application",hint:"React, Vue, Angular"},{value:"backend",label:"Backend Application",hint:"Node.js, Express, NestJS"},{value:"fullstack",label:"Full-stack Framework",hint:"Next.js, Remix, Nuxt"},{value:"library",label:"Library/Package",hint:"NPM package to publish"},{value:"mobile",label:"Mobile Application",hint:"React Native, Ionic"},{value:"desktop",label:"Desktop Application",hint:"Electron, Tauri"},{value:"monorepo",label:"Monorepo",hint:"Multi-package repository"},{value:"custom",label:"Custom",hint:"Configure from scratch"}]});if(o.isCancel(i))throw o.cancel("Setup cancelled"),new Error("Cancelled");let r={frontend:[{key:"vite-react",preset:S["vite-react"]},{key:"vite-vue",preset:S["vite-vue"]},{key:"react",preset:S.react}],backend:[{key:"node-esm",preset:S["node-esm"]},{key:"node-commonjs",preset:S["node-commonjs"]},{key:"express-api",preset:S["express-api"]}],fullstack:[{key:"next-app",preset:S["next-app"]},{key:"next-pages",preset:S["next-pages"]}],library:[{key:"react-library",preset:S["react-library"]},{key:"node-library",preset:S["node-library"]}],mobile:[{key:"react-native",preset:S["react-native"]}],desktop:[{key:"electron",preset:S.electron}],monorepo:[{key:"monorepo-root",preset:S["monorepo-root"]},{key:"monorepo-package",preset:S["monorepo-package"]}],custom:[]};if(i==="custom")return S["node-commonjs"];let s=r[i]||[],n=await o.select({message:"Select specific configuration",options:s.map(({key:a,preset:l})=>({value:a,label:l.name,hint:l.description}))});if(o.isCancel(n))throw o.cancel("Setup cancelled"),new Error("Cancelled");return this.presetKey=n,S[n]}async configureTarget(){let e=await o.confirm({message:"Customize the compilation target?",initialValue:!1});if(o.isCancel(e)||!e)return;o.log.step(E.cyan("\u{1F3AF} Set compilation target")),o.log.info("Target versions & typical environments:"),o.log.message(E.gray(" \u2022 ES2022: Node 16+, modern browsers (recommended)")),o.log.message(E.gray(" \u2022 ES2020: Node 14+, browsers since ~2020")),o.log.message(E.gray(" \u2022 ES2017: Broad compatibility")),o.log.message(E.gray(" \u2022 ES2015: Maximum compatibility"));let t=await o.select({message:"Choose ECMAScript target version",options:Q.targets});o.isCancel(t)||(this.config.compilerOptions.target=t,o.log.success(`Compilation target set to ${t}`))}async configureModuleSystem(){let e=await o.confirm({message:"Customize module system?",initialValue:!1});if(o.isCancel(e)||!e)return;o.log.step(E.cyan("Module System"));let t=await o.select({message:"Select module system",options:Q.modules});if(!o.isCancel(t)){this.config.compilerOptions.module=t;let i=await o.select({message:"Select module resolution strategy",options:Q.moduleResolution});o.isCancel(i)||(this.config.compilerOptions.moduleResolution=i)}}async configureStrictness(){o.log.step(E.cyan("\u{1F512} Set type-checking strictness")),o.log.info("Differences by strictness level:"),o.log.message(E.gray(" \u2022 Strict: enable all strict checks (recommended)")),o.log.message(E.gray(" \u2022 Moderate: balanced defaults for migrations")),o.log.message(E.gray(" \u2022 Loose: minimal type checks")),o.log.message(E.gray(" \u2022 Custom: pick individual options"));let e=await o.select({message:"Choose strictness level",options:Q.strictness});if(o.isCancel(e))throw o.cancel("Setup canceled"),new Error("Cancelled");if(e==="custom")await this.configureCustomStrictness();else{let i={strict:{strict:!0},moderate:{strict:!1,noImplicitAny:!0,strictNullChecks:!0,strictFunctionTypes:!0},loose:{strict:!1,noImplicitAny:!1}}[e];i&&(this.config.compilerOptions={...this.config.compilerOptions,...i})}o.log.success(`${e==="strict"?"Strict":e==="moderate"?"Moderate":e==="loose"?"Loose":"Custom"} mode selected`)}async configureCustomStrictness(){let e=$e();o.log.info("Configure individual strict options");let t=await o.multiselect({message:"Type checking options",options:e.typeChecking.map(r=>({value:r.value,label:r.label,selected:r.default}))});o.isCancel(t)||t.forEach(r=>{this.config.compilerOptions[r]=!0});let i=await o.multiselect({message:"Code qua