|  | import ignore from 'ignore'; | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | export const IGNORE_PATTERNS = [ | 
					
						
						|  | 'node_modules/**', | 
					
						
						|  | '.git/**', | 
					
						
						|  | 'dist/**', | 
					
						
						|  | 'build/**', | 
					
						
						|  | '.next/**', | 
					
						
						|  | 'coverage/**', | 
					
						
						|  | '.cache/**', | 
					
						
						|  | '.vscode/**', | 
					
						
						|  | '.idea/**', | 
					
						
						|  | '**/*.log', | 
					
						
						|  | '**/.DS_Store', | 
					
						
						|  | '**/npm-debug.log*', | 
					
						
						|  | '**/yarn-debug.log*', | 
					
						
						|  | '**/yarn-error.log*', | 
					
						
						|  | ]; | 
					
						
						|  |  | 
					
						
						|  | export const MAX_FILES = 1000; | 
					
						
						|  | export const ig = ignore().add(IGNORE_PATTERNS); | 
					
						
						|  |  | 
					
						
						|  | export const generateId = () => Math.random().toString(36).substring(2, 15); | 
					
						
						|  |  | 
					
						
						|  | export const isBinaryFile = async (file: File): Promise<boolean> => { | 
					
						
						|  | const chunkSize = 1024; | 
					
						
						|  | const buffer = new Uint8Array(await file.slice(0, chunkSize).arrayBuffer()); | 
					
						
						|  |  | 
					
						
						|  | for (let i = 0; i < buffer.length; i++) { | 
					
						
						|  | const byte = buffer[i]; | 
					
						
						|  |  | 
					
						
						|  | if (byte === 0 || (byte < 32 && byte !== 9 && byte !== 10 && byte !== 13)) { | 
					
						
						|  | return true; | 
					
						
						|  | } | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | return false; | 
					
						
						|  | }; | 
					
						
						|  |  | 
					
						
						|  | export const shouldIncludeFile = (path: string): boolean => { | 
					
						
						|  | return !ig.ignores(path); | 
					
						
						|  | }; | 
					
						
						|  |  | 
					
						
						|  | const readPackageJson = async (files: File[]): Promise<{ scripts?: Record<string, string> } | null> => { | 
					
						
						|  | const packageJsonFile = files.find((f) => f.webkitRelativePath.endsWith('package.json')); | 
					
						
						|  |  | 
					
						
						|  | if (!packageJsonFile) { | 
					
						
						|  | return null; | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | try { | 
					
						
						|  | const content = await new Promise<string>((resolve, reject) => { | 
					
						
						|  | const reader = new FileReader(); | 
					
						
						|  | reader.onload = () => resolve(reader.result as string); | 
					
						
						|  | reader.onerror = reject; | 
					
						
						|  | reader.readAsText(packageJsonFile); | 
					
						
						|  | }); | 
					
						
						|  |  | 
					
						
						|  | return JSON.parse(content); | 
					
						
						|  | } catch (error) { | 
					
						
						|  | console.error('Error reading package.json:', error); | 
					
						
						|  | return null; | 
					
						
						|  | } | 
					
						
						|  | }; | 
					
						
						|  |  | 
					
						
						|  | export const detectProjectType = async ( | 
					
						
						|  | files: File[], | 
					
						
						|  | ): Promise<{ type: string; setupCommand: string; followupMessage: string }> => { | 
					
						
						|  | const hasFile = (name: string) => files.some((f) => f.webkitRelativePath.endsWith(name)); | 
					
						
						|  |  | 
					
						
						|  | if (hasFile('package.json')) { | 
					
						
						|  | const packageJson = await readPackageJson(files); | 
					
						
						|  | const scripts = packageJson?.scripts || {}; | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | const preferredCommands = ['dev', 'start', 'preview']; | 
					
						
						|  | const availableCommand = preferredCommands.find((cmd) => scripts[cmd]); | 
					
						
						|  |  | 
					
						
						|  | if (availableCommand) { | 
					
						
						|  | return { | 
					
						
						|  | type: 'Node.js', | 
					
						
						|  | setupCommand: `npm install && npm run ${availableCommand}`, | 
					
						
						|  | followupMessage: `Found "${availableCommand}" script in package.json. Running "npm run ${availableCommand}" after installation.`, | 
					
						
						|  | }; | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | return { | 
					
						
						|  | type: 'Node.js', | 
					
						
						|  | setupCommand: 'npm install', | 
					
						
						|  | followupMessage: | 
					
						
						|  | 'Would you like me to inspect package.json to determine the available scripts for running this project?', | 
					
						
						|  | }; | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | if (hasFile('index.html')) { | 
					
						
						|  | return { | 
					
						
						|  | type: 'Static', | 
					
						
						|  | setupCommand: 'npx --yes serve', | 
					
						
						|  | followupMessage: '', | 
					
						
						|  | }; | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  | return { type: '', setupCommand: '', followupMessage: '' }; | 
					
						
						|  | }; | 
					
						
						|  |  |