Skip to content

Commit

Permalink
feat: add [update,remove,list,version, help] command to npui CLI
Browse files Browse the repository at this point in the history
  • Loading branch information
Mahdi-Hazrati committed Oct 19, 2024
1 parent 181424d commit 09ab92f
Show file tree
Hide file tree
Showing 3 changed files with 252 additions and 79 deletions.
120 changes: 82 additions & 38 deletions cli/README.md
Original file line number Diff line number Diff line change
@@ -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 <ComponentName>
npx npui <command> <ComponentName>
```

### 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 <ComponentName>`

Download a specified component to your project.

```bash
npx npui add Table
```

This will create the following structure in your project:
### `update <ComponentName>`

Update an existing component to the latest version.

```bash
npx npui update Table
```

### `remove <ComponentName>`

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 <ComponentName>`, 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 <ComponentName>
```
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.
209 changes: 169 additions & 40 deletions cli/main.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -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 <command> [options]
Commands:
add <ComponentName> Download and add the specified component to your project.
Example: npx npui add Table
update <ComponentName> Update the specified component in your project to the latest version.
Example: npx npui update Table
remove <ComponentName> 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 <ComponentName>");
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;
}
2 changes: 1 addition & 1 deletion cli/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "npui",
"version": "2.0.1",
"version": "2.0.2",
"description": "npui - open component library",
"main": "main.mjs",
"bin": {
Expand Down

0 comments on commit 09ab92f

Please sign in to comment.