UNPKG

rune

Version:

CLI to upload your games to Rune

138 lines (137 loc) 6.88 kB
import { spawn } from "child_process"; import fs from "fs"; import { Box, Text } from "ink"; import { UncontrolledTextInput } from "ink-text-input"; import React, { useCallback, useEffect } from "react"; import { Choose } from "../components/Choose.js"; import { Select } from "../components/Select.js"; import { Step } from "../components/Step.js"; import { createGameFromTemplate, templates } from "../lib/create.js"; import { formatTargetDir } from "../lib/files.js"; import { installDependenciesForProject } from "../lib/install.js"; var Steps; (function (Steps) { Steps[Steps["Target"] = 0] = "Target"; Steps[Steps["Overwrite"] = 1] = "Overwrite"; Steps[Steps["CancelOverwrite"] = 2] = "CancelOverwrite"; Steps[Steps["SelectTemplate"] = 3] = "SelectTemplate"; Steps[Steps["Creating"] = 4] = "Creating"; Steps[Steps["PromptInstall"] = 5] = "PromptInstall"; Steps[Steps["SkipInstall"] = 6] = "SkipInstall"; Steps[Steps["Installing"] = 7] = "Installing"; Steps[Steps["InstallError"] = 8] = "InstallError"; Steps[Steps["PostInstall"] = 9] = "PostInstall"; })(Steps || (Steps = {})); const defaultProjectName = "rune-game"; const pkgManager = process.env.npm_config_user_agent?.split("/")[0] || "npm"; function formatRunCommand(command) { return `${pkgManager}${pkgManager === "yarn" ? "" : " run"} ${command}`; } export function Create({ args }) { const [targetDir, setTargetDir] = React.useState(""); const [step, setStep] = React.useState(Steps.Target); const [exists, setExists] = React.useState(false); const [selectedTemplate, setSelectedTemplate] = React.useState("javascript"); const [overwrite, setOverwrite] = React.useState(false); const onSubmitTarget = useCallback((value) => { const targetDir = formatTargetDir(value || defaultProjectName); const exists = fs.existsSync(targetDir); setTargetDir(targetDir); setExists(exists); setStep(exists ? Steps.Overwrite : Steps.SelectTemplate); }, [setTargetDir, setStep]); const onCreate = useCallback(() => { createGameFromTemplate({ overwrite, targetDir, template: selectedTemplate || "javascript", }).then(() => { setStep(Steps.PromptInstall); }); }, [targetDir, overwrite, selectedTemplate, setStep]); const onInstall = useCallback(() => { installDependenciesForProject({ pathToProject: targetDir }) .then(() => { setStep(Steps.PostInstall); }) .catch(() => { setStep(Steps.InstallError); }); }, [targetDir]); const onPostInstall = useCallback(() => { process.chdir(targetDir); spawn(pkgManager, ["run", "dev", "--clearScreen=false"], { stdio: "inherit", //Fixes issue when running on windows https://stackoverflow.com/a/54515183 shell: process.platform === "win32", }); }, [targetDir]); useEffect(() => { if (args[0]) { onSubmitTarget(args[0]); } }, [args, onSubmitTarget]); useEffect(() => { if (step === Steps.Creating) { onCreate(); } if (step === Steps.Installing) { onInstall(); } if (step === Steps.PostInstall) { onPostInstall(); } }, [step, onCreate, onInstall, onPostInstall]); return (React.createElement(Box, { flexDirection: "column" }, React.createElement(Step, { status: step > Steps.Target ? "success" : "userInput", label: step > Steps.Target ? `Will create a game in "${targetDir}"` : "Game directory name", view: step <= Steps.Target && (React.createElement(UncontrolledTextInput, { placeholder: defaultProjectName, onSubmit: onSubmitTarget })) }), step === Steps.CancelOverwrite ? (React.createElement(Text, { color: "red" }, "Operation cancelled")) : (exists && (React.createElement(Step, { status: step > Steps.Overwrite ? "success" : "userInput", label: step > Steps.Overwrite ? `Will overwrite existing directory` : `Target directory "${targetDir}" is not empty. Remove existing files and continue?`, view: step <= Steps.Overwrite && !overwrite && (React.createElement(Choose, { options: ["No", "Yes"], onSubmit: (response) => { const overwrite = response === "Yes"; if (overwrite) { setOverwrite(true); setStep(Steps.SelectTemplate); } else { setStep(Steps.CancelOverwrite); } } })) }))), step >= Steps.SelectTemplate && (React.createElement(Step, { status: step > Steps.SelectTemplate ? "success" : "userInput", label: step > Steps.SelectTemplate ? `Selected ${selectedTemplate} template` : "Select a template", view: step === Steps.SelectTemplate && (React.createElement(Select, { items: templates, value: selectedTemplate, onChange: setSelectedTemplate, onSubmit: () => setStep(Steps.Creating) })) })), step >= Steps.Creating && (React.createElement(Step, { status: step > Steps.Creating ? "success" : "waiting", label: step > Steps.Overwrite ? `Game directory created!` : `Creating game directory...` })), step === Steps.PromptInstall && (React.createElement(Step, { status: step > Steps.PromptInstall ? "success" : "userInput", label: `Install using ${pkgManager} + open Dev UI?`, view: step <= Steps.PromptInstall && (React.createElement(Choose, { options: ["Yes", "No"], onSubmit: (response) => { const install = response === "Yes"; if (install) { setStep(Steps.Installing); } else { setStep(Steps.SkipInstall); } } })) })), step >= Steps.Installing && (React.createElement(Step, { status: step > Steps.InstallError ? "success" : step === Steps.InstallError ? "error" : "waiting", label: step > Steps.InstallError ? `Dependencies installed successfully!` : step === Steps.InstallError ? `Failed to install dependencies` : `Installing dependencies...` })), (step === Steps.SkipInstall || step === Steps.InstallError) && (React.createElement(Text, null, ` To start the project, run: cd ${targetDir} ${pkgManager} install ${formatRunCommand("dev")} `)), step === Steps.PostInstall && (React.createElement(Text, null, ` To start the project next time, run: cd ${targetDir} ${formatRunCommand("dev")} `)))); }