diff --git a/packages/myplop/config/tsuprc/tsup.base.ts b/packages/myplop/config/tsuprc/tsup.base.ts index 794e941..344611a 100644 --- a/packages/myplop/config/tsuprc/tsup.base.ts +++ b/packages/myplop/config/tsuprc/tsup.base.ts @@ -10,7 +10,7 @@ export default defineConfig({ esbuildPlugins: [ copy({ assets: [ - { from: "./src/templates/**", to: "./configs" } + { from: "./src/templates/**", to: "./templates" } // { from: "./package.json", to: "./package.json" } ] }) diff --git a/packages/myplop/package.json b/packages/myplop/package.json index d5acfb8..605ece9 100644 --- a/packages/myplop/package.json +++ b/packages/myplop/package.json @@ -36,6 +36,7 @@ "@clack/prompts": "^0.7.0", "chalk": "^5.3.0", "commander": "^11.1.0", + "oh-my-error": "^1.0.0", "zod": "^3.23.8" }, "devDependencies": { diff --git a/packages/myplop/src/cli/init/index.ts b/packages/myplop/src/cli/init/index.ts index 08ca7d7..cc4bea7 100644 --- a/packages/myplop/src/cli/init/index.ts +++ b/packages/myplop/src/cli/init/index.ts @@ -1,13 +1,17 @@ import { program } from "commander"; import * as prompter from "@clack/prompts"; import chalk from "chalk"; +import { myErrorCatcher, myErrorWrapper } from "oh-my-error"; +import logging from "@/utils/logging"; +import { existsSync } from "fs"; program .command("init") .description("Initialize plopfile") - .option("-D, --DEBUG", "output extra debugging (default: false)", false) + .option("-D, --DEBUG", "output extra debugging", false) .action(({ DEBUG }) => { process.env.DEBUG = `${DEBUG}`.toUpperCase(); + // process.env.DEBUG = "TRUE"; prompter .group( @@ -20,20 +24,19 @@ program message: "What do you want to initialize?", initialValue: "app", options: [ - { label: "App", value: "app", hint: "Initialize app - required to work app" }, - { label: "Config", value: "config" }, - { label: "Profile", value: "profile", hint: "Initialize profile at config" }, - { label: "Component", value: "component", hint: "Initialize component" } + { label: "App", value: "app.ts", hint: "Initialize app - required to work app" }, + { label: "Config", value: "config.ts" }, + { label: "Profile", value: "profile.ts", hint: "Initialize profile at config" }, + { label: "Component", value: "component.ts", hint: "Initialize component" } ] }), - outro: () => { - prompter.outro(chalk.bgGreen("Choosed correctly!")); - }, loadModule: async ({ results }) => { - await import(/* webpackMode: "eager" */ `./options/${results.choice}`).catch(err => { - console.error("Module not found - probably file with option doesnt exist.", err); - process.exit(0); - }); + try { + await import(`./options/${results.choice}`); + } catch (err) { + logging.error("Module not found - probably file with option doesnt exist.", err); + process.exit(1); + } } }, { diff --git a/packages/myplop/src/cli/init/options/app.ts b/packages/myplop/src/cli/init/options/app.ts index 2d43fa7..f0cd721 100644 --- a/packages/myplop/src/cli/init/options/app.ts +++ b/packages/myplop/src/cli/init/options/app.ts @@ -2,84 +2,33 @@ import * as prompter from "@clack/prompts"; import chalk from "chalk"; import { resolve } from "path"; import { copyFiles, existFilePrompt } from "@/function"; -// import { spawnSync } from "child_process"; - -const installerAction = () => ({ - ConfirmProcess: async () => { - prompter.note(`Initialize app at: \n'${chalk.blue(process.env.CONFIGPATH)}'`, chalk.bgGreen(" ACTIONS ")); - const continueAction = await prompter.confirm({ message: "Do you want to continue?" }); - if (prompter.isCancel(continueAction) || !continueAction) { - prompter.cancel("Canceled."); - process.exit(0); - } - }, - // ConfirmProcess: await (async () => { - // prompter.note(`Initialize app at: \n'${chalk.blue(process.env.CONFIGPATH)}'`, chalk.bgGreen(" ACTIONS ")); - // const continueAction = await prompter.confirm({ message: "Do you want to continue?" }); - // if (prompter.isCancel(continueAction) || !continueAction) { - // prompter.cancel("Canceled."); - // process.exit(0); - // } - // })(), - Installation: async () => { - const destination = process.env.CONFIGPATH; - const templatePath = resolve(process.env.PACKAGEPATH, `./templates/app`); - - const InstallingProcess = prompter.spinner(); - InstallingProcess.start("App is installing..."); - await existFilePrompt(destination); - copyFiles(templatePath, destination, true).catch(err => { - InstallingProcess.stop(`❌ error \n${err}`, 1); - // throw new Error(`${chalk.bgRed(" ERROR ")} Something went wrong induring coping files.\n${err}`); - }); - InstallingProcess.stop("✅", 0); - } -}); - -const configAction = async () => { - const generateCurrently = () => { - copyFiles(resolve(process.env.PACKAGEPATH, `./templates/config/global`), process.env.USERPATH, true).catch(err => { - throw err; - }); - }; - const generateNewRepo = () => { - // spawnSync("git", ["init"], { cwd: process.env.USERPATH }); - }; - - prompter.note(`Global config it's place where you gonna import/export your config.`, "General CONFIG"); - - const generateType = await prompter.select({ - message: "Where do you want to generate it?", - options: [ - { label: "New Repo", value: "newRepo" }, - { label: "Currently exist repo", value: "currently" } - ] - }); - - if (generateType == "currently") generateCurrently(); - generateNewRepo(); -}; prompter .group( { - intro: () => { - prompter.intro(chalk.bgCyan(" App ")); + ConfirmProcess: async () => { + prompter.note(`Initialize app at: \n'${chalk.blue(process.env.CONFIGPATH)}'`, chalk.bgGreen(" ACTIONS ")); + const continueAction = await prompter.confirm({ message: "Do you want to continue?" }); + if (prompter.isCancel(continueAction) || !continueAction) { + prompter.cancel("Canceled."); + process.exit(0); + } }, - typeOfAction: async () => - prompter.select({ - message: "Select action ", - initialValue: "app", - options: [ - { label: "Installation", value: "installation", hint: "required to work properly" }, - { label: "General Config", value: "generalConfig", hint: "Uses github repo to store data" } - ] - }), - generation: async ({ results }) => { - if (results.typeOfAction === "installation") await installerAction(); - await configAction(); + Installation: async () => { + const destination = process.env.CONFIGPATH!; + const templatePath = resolve(process.env.PACKAGEPATH!, "./templates/app/installation/"); + + const InstallingProcess = prompter.spinner(); + InstallingProcess.start("App is installing..."); + await existFilePrompt(destination); + const [data, isError] = copyFiles(templatePath, destination, true); + if (isError) { + InstallingProcess.stop(`❌ Error: ${data.message?.user}`, 1); + process.exit(1); + } + InstallingProcess.stop("✅", 0); }, - outro: () => { + outro: async () => { prompter.outro(chalk.bgGreen(" App has been installed! ")); } }, diff --git a/packages/myplop/src/cli/init/options/config.ts b/packages/myplop/src/cli/init/options/config.ts index 504f79d..16a24f4 100644 --- a/packages/myplop/src/cli/init/options/config.ts +++ b/packages/myplop/src/cli/init/options/config.ts @@ -24,10 +24,11 @@ prompter const InstallingProcess = prompter.spinner(); InstallingProcess.start("App is installing..."); await existFilePrompt(destination); - copyFiles(templatePath, destination, true).catch(err => { - InstallingProcess.stop(`❌ error \n${err}`, 1); - // throw new Error(`${chalk.bgRed(" ERROR ")} Something went wrong induring coping files.\n${err}`); - }); + const [data, isError] = copyFiles(templatePath, destination, true); + if (isError) { + InstallingProcess.stop(`❌ Error: ${data.message?.user}`, 1); + process.exit(1); + } InstallingProcess.stop("✅", 0); }, outro: () => { diff --git a/packages/myplop/src/function/checkSystem.ts b/packages/myplop/src/function/checkSystem.ts index 3abcefa..ac97116 100644 --- a/packages/myplop/src/function/checkSystem.ts +++ b/packages/myplop/src/function/checkSystem.ts @@ -2,7 +2,7 @@ import { platform } from "os"; type System = "linux" | "mac" | "other" | "windows"; -export const checkSystem = (): System => { +export const checkSystem: System = (() => { const system = platform(); if (system == "win32") { return "windows"; @@ -14,5 +14,5 @@ export const checkSystem = (): System => { return "linux"; } return "other"; -}; +})(); export default checkSystem; diff --git a/packages/myplop/src/function/configPath.ts b/packages/myplop/src/function/configPath.ts index 732b740..421f5c1 100644 --- a/packages/myplop/src/function/configPath.ts +++ b/packages/myplop/src/function/configPath.ts @@ -2,7 +2,7 @@ import { checkSystem } from "."; import { join } from "path"; export const configPath = () => { - const userSystem = checkSystem(); + const userSystem = checkSystem; if (userSystem == "windows") { return join(process.env.APPDATA, "MyPlop"); } diff --git a/packages/myplop/src/function/dialogs.ts b/packages/myplop/src/function/dialogs.ts index 4d13bf5..b0241a1 100644 --- a/packages/myplop/src/function/dialogs.ts +++ b/packages/myplop/src/function/dialogs.ts @@ -3,15 +3,14 @@ import chalk from "chalk"; import { existsSync } from "fs"; export const existFilePrompt = async (destination: string): Promise => { - if (existsSync(destination)) { - console.log(chalk.bgBlue("Files already exists.")); - const overwrite = await prompter.confirm({ - message: "Overwrite Folders/Files?", - initialValue: false - }); - if (prompter.isCancel(overwrite) || !overwrite) { - prompter.cancel("Dont overwrite file."); - process.exit(0); - } + if (!existsSync(destination)) return; + console.log(chalk.bgBlue("Files already exists.")); + const overwrite = await prompter.confirm({ + message: "Overwrite Folders/Files?", + initialValue: false + }); + if (prompter.isCancel(overwrite) || !overwrite) { + prompter.cancel("Dont overwrite file."); + process.exit(0); } }; diff --git a/packages/myplop/src/function/fileOperations.ts b/packages/myplop/src/function/fileOperations.ts index 5333b45..47a3e32 100644 --- a/packages/myplop/src/function/fileOperations.ts +++ b/packages/myplop/src/function/fileOperations.ts @@ -1,16 +1,41 @@ import logging from "@/utils/logging"; import { copyFileSync, existsSync, mkdirSync, readdirSync } from "fs"; +import type { TFunctionReturn, TMyErrorList } from "oh-my-error"; +import { myErrorWrapper } from "oh-my-error"; import { join } from "path"; -const copyFiles = async (source: string, target: string, emptyDirs = true): Promise => - new Promise(() => { - if (!existsSync(target)) mkdirSync(target); +const MyErrorList = { + CANT_MKDIR: { + code: "CP001", + hint: {}, + message: { user: "Can't make dir" } + }, + CANT_COPY_FILE: { + code: "CP002", + hint: {}, + message: { user: "Can't Copy File" } + } +} as const satisfies TMyErrorList; + +const copyFiles = (source: string, target: string, emptyDirs = true): TFunctionReturn => { + if (!existsSync(target)) { + const [, isError] = myErrorWrapper(mkdirSync)(target); + if (isError) return [MyErrorList.CANT_MKDIR, true]; + } + + const [, isError] = myErrorWrapper(() => { readdirSync(source, { withFileTypes: true }).forEach(file => { logging.debug("File info: ", file); const curSource = join(source, file.name); if (file.isDirectory()) copyFiles(curSource, join(target, file.name), emptyDirs); else copyFileSync(curSource, join(target, file.name)); }); - }); + })(); + if (isError) return [MyErrorList.CANT_COPY_FILE, true]; + + // ERROR HANDLING DOKONCZ + + return [, false]; +}; export { copyFiles }; diff --git a/packages/myplop/src/index.ts b/packages/myplop/src/index.ts index 982de71..1e73d8b 100644 --- a/packages/myplop/src/index.ts +++ b/packages/myplop/src/index.ts @@ -5,15 +5,16 @@ import chalk from "chalk"; import { program } from "commander"; import path from "path"; -const DIRNAME = path.resolve(); +import { fileURLToPath } from "url"; +import logging from "./utils/logging"; -process.env.OS = checkSystem(); +process.env.OS = checkSystem; process.env.USERPATH = process.cwd(); -process.env.PACKAGEPATH = DIRNAME; +process.env.PACKAGEPATH = path.dirname(fileURLToPath(import.meta.url)); process.env.CONFIGPATH = configPath(); if (process.env.OS != "windows") { - console.log(chalk.bgRed(" ERROR "), "Currently Version support only Windows - Sorry"); + logging.log(chalk.bgRed(" ERROR "), "Currently Version support only Windows - Sorry"); process.exit(1); } @@ -21,7 +22,7 @@ declare global { module NodeJS { // @ts-expect-error - ProcessEnv is default defined but we want to override it export type ProcessEnv = Record & { - OS: ReturnType; + OS: typeof checkSystem; PACKAGEPATH: string; CONFIGPATH: string; USERPATH: string; @@ -29,4 +30,4 @@ declare global { } } -program.parse(); +program.parse(process.argv); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a5de396..9716e00 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -79,6 +79,12 @@ importers: chalk: specifier: ^5.3.0 version: 5.3.0 + commander: + specifier: ^11.1.0 + version: 11.1.0 + oh-my-error: + specifier: ^1.0.0 + version: 1.0.0 zod: specifier: ^3.23.8 version: 3.23.8 @@ -86,9 +92,6 @@ importers: clean-package: specifier: ^2.2.0 version: 2.2.0 - commander: - specifier: ^11.1.0 - version: 11.1.0 esbuild: specifier: ^0.21.5 version: 0.21.5 @@ -1481,7 +1484,7 @@ packages: /commander@11.1.0: resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} engines: {node: '>=16'} - dev: true + dev: false /commander@12.1.0: resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} @@ -3045,6 +3048,11 @@ packages: object-keys: 1.1.1 dev: true + /oh-my-error@1.0.0: + resolution: {integrity: sha512-TLz8M8WXDuEiCBcZls8JXvHX0+Ovxf35mD0VeBH+XHSTddfhFw8Xt0bCtbfiJdyQmJOCKDdLADzyK1dG0nQ59Q==} + engines: {node: '>=18'} + dev: false + /once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} dependencies: