From 09ab92f9c69a4ae2eb4c862c5410f5a4aa97f990 Mon Sep 17 00:00:00 2001 From: Mahdi Hazrati Date: Sat, 19 Oct 2024 11:22:06 +0330 Subject: [PATCH] feat: add [update,remove,list,version, help] command to npui CLI --- cli/README.md | 120 ++++++++++++++++++--------- cli/main.mjs | 209 ++++++++++++++++++++++++++++++++++++++--------- cli/package.json | 2 +- 3 files changed, 252 insertions(+), 79 deletions(-) diff --git a/cli/README.md b/cli/README.md index 20a0a02..cecdb2a 100644 --- a/cli/README.md +++ b/cli/README.md @@ -1,76 +1,120 @@ # 🧩 npui cli -**npui** is a CLI tool for easily adding React components from the **npui** component library to your project. It allows developers to download and install specific components from the `npui` GitHub repository directly into their app's local directory. +`npui` is a command-line interface (CLI) tool designed for easy integration of reusable UI components into your projects. Built with simplicity and flexibility in mind, `npui` allows developers to quickly add, update, remove, and list components from the NextProduction repository directly in their own projects. ## Features -- Easily download and add individual components from the **npui** component library. -- Creates a local `npui` folder in your project to organize components. -- Simple command-line interface with intuitive usage. +- **Download Components**: Fetch UI components directly from the GitHub repository. +- **Update Components**: Keep your components up to date with the latest changes. +- **Remove Components**: Easily delete components from your project. +- **List Components**: View all downloaded components at a glance. +- **Version Info**: Check the current version of `npui`. +- **Help Command**: Get usage instructions directly from the CLI. ## Installation -To use **npui**, you need to have [Node.js](https://nodejs.org/) installed on your machine. +You can install `npui` globally or use it directly with `npx` without installation. -### Step 1: Install via `npx` +### Using npx -You don't need to install the package globally. Just use it directly with `npx`: +To use `npui` directly, run the following command: ```bash -npx npui add +npx npui ``` -### Example: +### Installing Globally -To download the `Table` component from the npui component library and add it to your project: +If you prefer to install `npui` globally, you can run: + +```bash +npm install -g npui +``` + +## Usage + +Here's a breakdown of available commands: + +### `add ` + +Download a specified component to your project. ```bash npx npui add Table ``` -This will create the following structure in your project: +### `update ` + +Update an existing component to the latest version. + +```bash +npx npui update Table +``` + +### `remove ` + +Remove a specified component from your project. + +```bash +npx npui remove Table +``` + +### `list` +List all components downloaded to your project. + +```bash +npx npui list ``` -your-app/ -│ -├── npui/ -│ └── Table/ -│ └── Table.tsx + +### `version` + +Display the current version of `npui`. + +```bash +npx npui version ``` -## How It Works +### `help` -- When you run the command `npx npui add `, the CLI will: - - Create an `npui` directory (if it doesn't exist) in your project root. - - Download the specified component from the **npui** GitHub repository. - - Place the component files in the appropriate folder under the `npui` directory. +Show usage instructions for `npui`. + +```bash +npx npui help +``` -## GitHub Repository -The **npui** components are hosted on GitHub: -[NextProduction/npui](https://github.com/NextProduction/npui) +## Example -You can browse the available components and their code in the repository. +Here's a complete example of how to use `npui`: -## Commands +1. **Add a component**: + ```bash + npx npui add Button + ``` -- **Add a component:** +2. **List downloaded components**: + ```bash + npx npui list + ``` - ```bash - npx npui add - ``` +3. **Update a component**: + ```bash + npx npui update Button + ``` - Downloads the specified component from the **npui** library and places it in your project. +4. **Remove a component**: + ```bash + npx npui remove Button + ``` -## Contributing +## Contribution -We welcome contributions! If you'd like to contribute to the **npui** library, please feel free to submit a pull request on our GitHub repository. +Contributions are welcome! If you have suggestions for improvements or want to report bugs, feel free to create an issue or submit a pull request on the [GitHub repository](https://github.com/NextProduction/npui). -## License -This project is licensed under the GPL-3.0-or-later License. ---- +## Acknowledgments -**Maintained by [NextProduction](https://github.com/NextProduction)** -Created by [Mahdi Hazrati](https://github.com/mahdi-hazrati) +- Thanks to [Node.js](https://nodejs.org/) for providing a powerful platform for building command-line applications. +- Inspired by the open-source community for fostering collaboration and innovation. diff --git a/cli/main.mjs b/cli/main.mjs index 8bce2cc..2b02920 100644 --- a/cli/main.mjs +++ b/cli/main.mjs @@ -8,52 +8,181 @@ import fetch from "node-fetch"; // Importing node-fetch to make HTTP requests (u // Base URL for raw content of your GitHub repository where the components are stored. // This URL will be used to dynamically download the components. -const GITHUB_RAW_BASE_URL = 'https://raw.githubusercontent.com/NextProduction/npui/main/src/components'; +const GITHUB_RAW_BASE_URL = + "https://raw.githubusercontent.com/NextProduction/npui/main/src/components"; // Asynchronous function to download the specified component. async function downloadComponent(componentName) { - // Construct the filename and the full URL to the raw component file on GitHub. - const componentFile = `${componentName}.tsx`; - const componentUrl = `${GITHUB_RAW_BASE_URL}/${componentName}/${componentFile}`; - - try { - // Check if the 'npui' directory exists in the user's project. - // If it doesn't exist, create it to store downloaded components. - if (!fs.existsSync('npui')) { - fs.mkdirSync('npui'); // Create 'npui' directory. - } - - // Create a specific directory for the component inside the 'npui' folder (e.g., npui/Table). - const componentPath = path.join('npui', componentName); - if (!fs.existsSync(componentPath)) { - fs.mkdirSync(componentPath); // Create the component's folder if it doesn't exist. - } - - // Fetch the component file from GitHub using the constructed URL. - const response = await fetch(componentUrl); - if (!response.ok) { - throw new Error(`Failed to download component: ${componentName}`); // Throw an error if the fetch request fails. - } - const componentCode = await response.text(); // Get the file content as plain text. - - // Write the fetched component file into the user's project under the correct path (e.g., npui/Table/Table.tsx). - const filePath = path.join(componentPath, componentFile); - fs.writeFileSync(filePath, componentCode); // Save the file locally. - console.log(`Component ${componentName} downloaded successfully to ${filePath}`); // Log success message. - - } catch (error) { - // Handle errors that occur during the process (e.g., failed download or file system issues). - console.error(`Error: ${error.message}`); + // Construct the filename and the full URL to the raw component file on GitHub. + const componentFile = `${componentName}.tsx`; + const componentUrl = `${GITHUB_RAW_BASE_URL}/${componentName}/${componentFile}`; + + try { + // Check if the 'npui' directory exists in the user's project. + // If it doesn't exist, create it to store downloaded components. + if (!fs.existsSync("npui")) { + fs.mkdirSync("npui"); // Create 'npui' directory. + } + + // Create a specific directory for the component inside the 'npui' folder (e.g., npui/Table). + const componentPath = path.join("npui", componentName); + if (!fs.existsSync(componentPath)) { + fs.mkdirSync(componentPath); // Create the component's folder if it doesn't exist. + } + + // Fetch the component file from GitHub using the constructed URL. + const response = await fetch(componentUrl); + if (!response.ok) { + throw new Error(`Failed to download component: ${componentName}`); // Throw an error if the fetch request fails. + } + const componentCode = await response.text(); // Get the file content as plain text. + + // Write the fetched component file into the user's project under the correct path (e.g., npui/Table/Table.tsx). + const filePath = path.join(componentPath, componentFile); + fs.writeFileSync(filePath, componentCode); // Save the file locally. + console.log( + `Component ${componentName} downloaded successfully to ${filePath}` + ); // Log success message. + } catch (error) { + // Handle errors that occur during the process (e.g., failed download or file system issues). + console.error(`Error: ${error.message}`); + } +} + +// Function to remove the specified component. +function removeComponent(componentName) { + const componentPath = path.join("npui", componentName); + + // Check if the component's directory exists. + if (fs.existsSync(componentPath)) { + fs.rmdirSync(componentPath, { recursive: true }); // Remove the component directory recursively. + console.log(`Component ${componentName} removed successfully.`); // Log success message. + } else { + console.error(`Error: Component ${componentName} does not exist.`); // Log error if the component does not exist. + } +} + +// Function to list all downloaded components. +function listComponents() { + const npuiPath = "npui"; + + // Check if the npui directory exists. + if (fs.existsSync(npuiPath)) { + const components = fs.readdirSync(npuiPath); // Read the contents of the npui directory. + if (components.length > 0) { + console.log("Downloaded components:"); + components.forEach((component) => { + console.log(`- ${component}`); // Print each component name. + }); + } else { + console.log("No components found in the npui directory."); } + } else { + console.log("The npui directory does not exist."); + } +} + +// Function to read version and name from package.json +function readPackageInfo() { + const packageJsonPath = path.join(process.cwd(), "package.json"); // Get the path to package.json in the current directory + + try { + const packageJson = fs.readFileSync(packageJsonPath, "utf-8"); // Read the package.json file + const packageInfo = JSON.parse(packageJson); // Parse the JSON content + + return { + name: packageInfo.name || "unknown", + version: packageInfo.version || "unknown", + }; + } catch (error) { + console.error("Error reading package.json:", error.message); + return { + name: "unknown", + version: "unknown", + }; + } +} + +// Function to show a helper for how to use npui cli +function helpCommand() { + const help = ` +Usage: npx npui [options] + +Commands: + add Download and add the specified component to your project. + Example: npx npui add Table + + update Update the specified component in your project to the latest version. + Example: npx npui update Table + + remove Remove the specified component from your project. + Example: npx npui remove Table + + list List all downloaded components in the 'npui' directory. + Example: npx npui list + + version Show the current version of the npui tool. + Example: npx npui version + + help Display this help message with information about commands. + Example: npx npui help + +For more information, visit the documentation at [nextproduction.dev/npui]. + `; + console.log(help); } // Command-line arguments handler. 'process.argv' contains all arguments passed to the script. -// We slice the array to get the relevant arguments. The first argument should be 'add', and the second should be the component name. +// We slice the array to get the relevant arguments. The first argument indicates the command. const args = process.argv.slice(2); -if (args[0] === 'add' && args[1]) { - const componentName = args[1]; // Extract the component name. - downloadComponent(componentName); // Call the download function with the component name. -} else { - // If the command is incorrect or no component name is provided, display usage instructions. - console.log("Usage: npx npui add "); +const command = args[0]; +const componentName = args[1]; + +// Using switch-case for command handling. +switch (command) { + case "add": + if (componentName) { + downloadComponent(componentName); + } else { + console.error("Error: Component name is required for the add command."); + } + break; + + case "update": + if (componentName) { + console.log(`Updating component ${componentName}...`); + downloadComponent(componentName); + } else { + console.error( + "Error: Component name is required for the update command." + ); + } + break; + + case "remove": + if (componentName) { + removeComponent(componentName); + } else { + console.error( + "Error: Component name is required for the remove command." + ); + } + break; + + case "list": + listComponents(); // List available components in the npui directory. + break; + + case "version": + const { name, version } = readPackageInfo(); // Read version and name from package.json + console.log(`${name} version ${version}`); // Log the name and version + break; + + case "help": + helpCommand(); + break; + + default: + console.log("~ Hint Run : npx npui help"); + break; } diff --git a/cli/package.json b/cli/package.json index 9c8951d..1cbb80e 100644 --- a/cli/package.json +++ b/cli/package.json @@ -1,6 +1,6 @@ { "name": "npui", - "version": "2.0.1", + "version": "2.0.2", "description": "npui - open component library", "main": "main.mjs", "bin": {