UNPKG

@yantra-core/yantra

Version:

Yantra.gg Serverless Physics SDK for Real-time Multiplayer Game Development

194 lines (153 loc) 5.92 kB
import inquirer from 'inquirer'; import fs from 'fs'; import path from 'path'; import { fileURLToPath } from 'url'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const init = {}; init.configureWorld = async function configureWorld(sourceDir, defaultWorldName) { inquirer.prompt.prefix = ''; // Prompt for project details const responses = await inquirer.prompt([{ type: 'input', name: 'worldName', message: 'world name:', default: defaultWorldName, prefix: '', }, { type: 'input', name: 'version', message: 'version:', default: '1.0.0', prefix: '' }, { type: 'input', name: 'description', message: 'description:', default: '', prefix: '' }]); const destDir = process.cwd(); await copyWithOverwritePrompt(sourceDir, destDir); // Update package.json with user input after copying files const packageJsonPath = path.join(destDir, 'package.json'); const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8')); packageJson.name = responses.worldName; packageJson.version = responses.version; packageJson.description = responses.description; fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2)); // Updates the config.js file with world name const configJsPath = path.join(destDir, 'config.js'); if (fs.existsSync(configJsPath)) { let configJsContent = fs.readFileSync(configJsPath, 'utf-8'); configJsContent = configJsContent.replace(/my-world/g, responses.worldName); fs.writeFileSync(configJsPath, configJsContent, 'utf-8'); console.log('Updated config.js with world name: ' + responses.worldName); } // replaces my-world with world name in boot.js const bootJsPath = path.join(destDir, 'boot.js'); if (fs.existsSync(bootJsPath)) { let bootJsContent = fs.readFileSync(bootJsPath, 'utf-8'); bootJsContent = bootJsContent.replace(/my-world/g, responses.worldName); fs.writeFileSync(bootJsPath, bootJsContent, 'utf-8'); console.log('Updated boot.js with world name: ' + responses.worldName); } console.log(responses.worldName, 'initialized successfully!'); console.log('Run `npm start` or `node boot.js` to start your world.'); console.log('Run `yantra deploy` to deploy your world to Yantra.'); console.log(''); console.log('You *must* run `npm install` in order to install Yantra SDK to this path.'); } init.scaffold = async function scaffoldInit() { const sourceDir = path.resolve(__dirname, '../node_modules/@yantra-core/examples/world'); const defaultWorldName = path.basename(process.cwd()); await init.configureWorld(sourceDir, defaultWorldName); } init.clone = async function cloneInit(worldname) { const library = ['pong', 'snake']; if (typeof worldname === 'undefined') { console.error('You must specify a world to clone.'); console.log('Available worlds:\n' + library.join('\n')); return; } if (!library.includes(worldname)) { console.error(`The world '${worldname}' does not exist in the library.`); console.log('Available worlds:', library.join(', ')); return; } const sourceDir = path.resolve(__dirname, '../node_modules/@yantra-core/examples', worldname); await init.configureWorld(sourceDir, worldname); } async function shouldOverwrite(file) { const { action } = await inquirer.prompt([{ type: 'list', name: 'action', message: `File ${file} already exists. What would you like to do?`, choices: [ { name: 'Overwrite', value: 'overwrite' }, { name: 'Always Overwrite (for all files)', value: 'always' }, { name: 'Ignore', value: 'ignore' }, { name: 'Cancel', value: 'cancel' }, ], }]); return action; } const excludes = ['.DS_Store', 'node_modules', 'package-lock.json']; async function copyWithOverwritePrompt(sourceDir, destDir) { let alwaysOverwrite = false; async function recursiveCopy(src, dest) { const entries = fs.readdirSync(src); for (let entry of entries) { const srcPath = path.join(src, entry); const destPath = path.join(dest, entry); // Check if the entry is in the excludes list if (excludes.includes(entry)) { continue; } if (fs.statSync(srcPath).isDirectory()) { // If directory doesn't exist, create it if (!fs.existsSync(destPath)) { fs.mkdirSync(destPath); } // Recursively copy the directory await recursiveCopy(srcPath, destPath); } else { if (fs.existsSync(destPath) && !alwaysOverwrite) { const action = await shouldOverwrite(entry); if (action === 'cancel') { throw new Error('Initialization cancelled.'); return; } else if (action === 'always') { alwaysOverwrite = true; } else if (action !== 'overwrite') { continue; } } fs.copyFileSync(srcPath, destPath); } } } await recursiveCopy(sourceDir, destDir); console.log(`World copied into ${destDir}`); // Remark: Show sourceDir since destDir might not have been empty originally, // and we only want to display the files that were copied displayDirectoryTree(sourceDir); } function displayDirectoryTree(basePath, level = 0) { const entries = fs.readdirSync(basePath); for (const entryName of entries) { const entryPath = path.join(basePath, entryName); // Skip over any items that match the excludes list if (excludes.includes(entryName)) { continue; } // For indentation based on directory level const prefix = ' '.repeat(level); console.log(`${prefix}${entryName}`); // If the entry is a directory, recursively print its contents if (fs.statSync(entryPath).isDirectory()) { displayDirectoryTree(entryPath, level + 1); } } } export default init;