UNPKG

@react-gnome/core

Version:

## Getting Started

200 lines (198 loc) 7.15 kB
var __defProp = Object.defineProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); // src/programs/init-program.ts import { exec } from "child_process"; import { defineOption } from "clify.js"; import fsbase from "fs"; import fs from "fs/promises"; import path from "path"; import { html, Output } from "termx-markup"; import { getJsProjectConfigFile } from "../init-project/config-file-js.mjs"; import { getTsProjectConfigFile } from "../init-project/config-file-ts.mjs"; import { getJsEntryFile } from "../init-project/entry-file-js.mjs"; import { getTsEntryFile } from "../init-project/entry-file-ts.mjs"; import { getTsConfig } from "../init-project/tsconfig-file.mjs"; var ForceTypescriptArg = defineOption({ char: "t", name: "typescript", description: "Initiate project with typescript. By default this will be enabled automatically if a tsconfig.json file is detected.", type: "boolean" }); var InitProgram = class { constructor(init) { __publicField(this, "type", "init"); __publicField(this, "forceTypescript"); __publicField(this, "packageManager"); __publicField(this, "projectDir", process.cwd()); this.forceTypescript = init.option(ForceTypescriptArg); } detectPackageManager(projectFiles) { if (this.packageManager) { return this.packageManager; } if (projectFiles == null) { projectFiles = fsbase.readdirSync(this.projectDir); } if (projectFiles.includes("yarn.lock")) { this.packageManager = "yarn"; } else if (projectFiles.includes("package-lock.json")) { this.packageManager = "npm"; } else if (projectFiles.includes("pnpm-lock.yaml")) { this.packageManager = "pnpm"; } else if (projectFiles.includes("bun.lockb")) { this.packageManager = "bun"; } else { this.packageManager = "npm"; } return this.packageManager; } async createFiles(projectDir, useTypescript) { const srcDir = path.resolve(projectDir, "src"); if (!fsbase.existsSync(srcDir)) { await fs.mkdir(srcDir); } const entryFilePath = path.resolve( projectDir, "src", useTypescript ? "start.tsx" : "start.jsx" ); if (!fsbase.existsSync(entryFilePath)) { const entryFileContent = useTypescript ? getTsEntryFile() : getJsEntryFile(); Output.print( html`<span> Creating entrypoint file: <span color="white"> ./${path.relative(projectDir, entryFilePath)} </span> </span>` ); await fs.writeFile(entryFilePath, entryFileContent); } const configFilePath = path.resolve( projectDir, useTypescript ? "react-gtk.config.ts" : "react-gtk.config.mjs" ); if (!fsbase.existsSync(configFilePath)) { const configFileContent = useTypescript ? getTsProjectConfigFile() : getJsProjectConfigFile(); Output.print( html`<span> Creating config file: <span color="white"> ./${path.relative(projectDir, configFilePath)} </span> </span>` ); await fs.writeFile(configFilePath, configFileContent); } if (useTypescript) { const tsconfigPath = path.resolve(projectDir, "tsconfig.json"); if (!fsbase.existsSync(tsconfigPath)) { const fileContent = getTsConfig(); Output.print( html`<span> Creating tsconfig file: <span color="white"> ./${path.relative(projectDir, tsconfigPath)} </span> </span>` ); await fs.writeFile(tsconfigPath, fileContent); } } } async updatePackageJson(packageJson, filepath) { Output.print( html`<span> Updating scripts in: <span color="white">./package.json</span> </span>` ); const scripts = packageJson.scripts ?? {}; scripts.build = `react-gtk build`; scripts.bundle = `react-gtk bundle`; scripts.start = `react-gtk start -m development -w`; scripts["install-pkg"] = "meson install -C ./dist/.build/_build"; packageJson.type = "module"; packageJson.scripts = scripts; await fs.writeFile(filepath, JSON.stringify(packageJson, null, 2)); } async installDependencies(packageJson, useTypescript) { const hasDep = (dep) => { return packageJson.dependencies && !!packageJson.dependencies[dep] || packageJson.devDependencies && !!packageJson.devDependencies[dep]; }; Output.print(html`<span>Installing dependencies...</span>`); const neededDeps = { dev: [], prod: [] }; if (!hasDep("react")) { neededDeps.prod.push("react"); } if (!hasDep("@reactgjs/renderer")) { neededDeps.prod.push("@reactgjs/renderer"); } if (useTypescript) { if (!hasDep("typescript")) { neededDeps.dev.push("typescript"); } if (!hasDep("@types/react")) { neededDeps.dev.push("@types/react"); } if (!hasDep("ts-node")) { neededDeps.dev.push("ts-node"); } if (!hasDep("gjs-esm-types")) { neededDeps.dev.push("gjs-esm-types"); } } switch (this.detectPackageManager()) { case "yarn": await execute(`yarn add -D ${neededDeps.dev.join(" ")}`); await execute(`yarn add ${neededDeps.prod.join(" ")}`); break; case "pnpm": await execute(`pnpm add -D ${neededDeps.dev.join(" ")}`); await execute(`pnpm add ${neededDeps.prod.join(" ")}`); break; case "bun": await execute(`bun add -D ${neededDeps.dev.join(" ")}`); await execute(`bun add ${neededDeps.prod.join(" ")}`); break; case "npm": await execute(`npm install --save-dev ${neededDeps.dev.join(" ")}`); await execute(`npm install --save ${neededDeps.prod.join(" ")}`); break; } } async run() { Output.print(html` <span color="green">Initializing new project.</span> `); const projectDir = process.cwd(); const projectFiles = await fs.readdir(projectDir); const useTypescript = this.forceTypescript.value ?? projectFiles.includes("tsconfig.json"); this.detectPackageManager(projectFiles); await this.createFiles(projectDir, useTypescript); const packageJsonPath = path.resolve(projectDir, "package.json"); let packageJson = {}; if (fsbase.existsSync(packageJsonPath)) { packageJson = JSON.parse(await fs.readFile(packageJsonPath, "utf-8")); } await this.updatePackageJson(packageJson, packageJsonPath); await this.installDependencies(packageJson, useTypescript); Output.print(html` <span color="green">Done.</span> `); } }; function execute(command) { return new Promise((resolve) => { exec(command, (err, stdout, stderr) => { if (err) { resolve({ stdout, stderr, code: err.code ?? null }); } else { resolve({ stdout, stderr, code: 0 }); } }); }); } export { InitProgram };