@tioelvis/next-ui 1.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,3 @@
1
+ # Interactive CLI UI Project Generator
2
+
3
+ This project is a command-line tool to scaffold a modern Next.js + Typescript + TailwindCSS project
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "@tioelvis/next-ui",
3
+ "version": "1.0.10",
4
+ "description": "Interactive CLI to scaffold a Next.js project with customizable presets and configurations.",
5
+ "type": "module",
6
+ "bin": {
7
+ "next-ui": "./src/main.js"
8
+ },
9
+ "keywords": [
10
+ "cli",
11
+ "nextjs",
12
+ "ui",
13
+ "scaffolding"
14
+ ],
15
+ "author": {
16
+ "name": "TioElvis",
17
+ "email": "elvis.veramijares@gmail.com"
18
+ },
19
+ "license": "MIT",
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "https://github.com/TioElvis/next-ui"
23
+ },
24
+ "dependencies": {
25
+ "chalk": "^5.6.2",
26
+ "ora": "^9.0.0",
27
+ "prompts": "^2.4.2"
28
+ },
29
+ "devDependencies": {
30
+ "@tailwindcss/postcss": "^4.1.18",
31
+ "@tanstack/react-query": "^5.90.12",
32
+ "@types/node": "^25.0.3",
33
+ "@types/prompts": "^2.4.9",
34
+ "@types/react": "^19.2.7",
35
+ "@types/react-dom": "^19.2.3",
36
+ "eslint": "^9.39.2",
37
+ "eslint-config-next": "^16.1.0",
38
+ "next": "^16.1.0",
39
+ "react": "^19.2.3",
40
+ "react-dom": "^19.2.3",
41
+ "tailwindcss": "^4.1.18",
42
+ "typescript": "^5.9.3"
43
+ }
44
+ }
@@ -0,0 +1,32 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+
4
+ import chalk from "chalk";
5
+
6
+ import { context } from "../main.js";
7
+ import { Exception } from "../lib/exception.js";
8
+
9
+ export function configurePackageJson() {
10
+ console.log(chalk.white("\nConfiguring package.json..."));
11
+
12
+ const packageJSON = {
13
+ name: context.projectName,
14
+ version: "1.0.0",
15
+ private: true,
16
+ scripts: {
17
+ dev: "next dev",
18
+ build: "next build",
19
+ start: "next start",
20
+ lint: "next lint",
21
+ },
22
+ };
23
+
24
+ const packageJsonPath = path.join(context.dest, "package.json");
25
+
26
+ try {
27
+ fs.writeFileSync(packageJsonPath, JSON.stringify(packageJSON, null, 2));
28
+ console.log(chalk.green("package.json configured successfully."));
29
+ } catch (error) {
30
+ throw new Exception("Failed to configure package.json. Please try again.");
31
+ }
32
+ }
@@ -0,0 +1,18 @@
1
+ import fs from "node:fs";
2
+
3
+ import chalk from "chalk";
4
+
5
+ import { context } from "../main.js";
6
+ import { Exception } from "../lib/exception.js";
7
+ import { TEMPLATE_FOLDER_PATH } from "../constants.js";
8
+
9
+ export function copyingTemplateFiles() {
10
+ console.log(chalk.white(`Copying template files...`));
11
+
12
+ try {
13
+ fs.cpSync(TEMPLATE_FOLDER_PATH, context.dest, { recursive: true });
14
+ console.log(chalk.green("Template files copied successfully."));
15
+ } catch (error) {
16
+ throw new Exception(`Could not copy template files: ${error.message}`);
17
+ }
18
+ }
@@ -0,0 +1,23 @@
1
+ import fs from "node:fs";
2
+
3
+ import chalk from "chalk";
4
+
5
+ import { context } from "../main.js";
6
+ import { Exception } from "../lib/exception.js";
7
+
8
+ export function creatingProject() {
9
+ console.log(chalk.white(`Creating project "${context.projectName}"...`));
10
+
11
+ if (fs.existsSync(context.dest)) {
12
+ throw new Exception(
13
+ `Directory ${context.projectName} already exists. Choose a different project name.`,
14
+ );
15
+ }
16
+
17
+ try {
18
+ fs.mkdirSync(context.dest, { recursive: true });
19
+ console.log(chalk.green(`Created "${context.projectName}" folder.`));
20
+ } catch (error) {
21
+ throw new Exception(`Could not create project folder: ${error.message}`);
22
+ }
23
+ }
@@ -0,0 +1,22 @@
1
+ import ora from "ora";
2
+
3
+ import { context } from "../main.js";
4
+ import { runCommand } from "../lib/utils.js";
5
+ import { Exception } from "../lib/exception.js";
6
+ import { MAIN_DEPENDENCIES, MAIN_DEV_DEPENDENCIES } from "../constants.js";
7
+
8
+ export async function installAllDependencies() {
9
+ const spinner = ora("Installing main packages...").start();
10
+
11
+ const { packageManager: pm, dest } = context;
12
+
13
+ try {
14
+ await runCommand(pm, ["install", ...MAIN_DEPENDENCIES], dest);
15
+ await runCommand(pm, ["install", "-D", ...MAIN_DEV_DEPENDENCIES], dest);
16
+
17
+ spinner.succeed("Main packages installed successfully.");
18
+ } catch (error) {
19
+ spinner.fail("Failed to install main packages.");
20
+ throw new Exception(`Failed to install main packages: ${error.message}`);
21
+ }
22
+ }
@@ -0,0 +1,26 @@
1
+ import path from "node:path";
2
+ import { fileURLToPath } from "node:url";
3
+
4
+ export const __filename = fileURLToPath(import.meta.url);
5
+ export const __dirname = path.dirname(__filename);
6
+
7
+ export const CWD = path.resolve(process.cwd());
8
+
9
+ export const TEMPLATE_FOLDER_PATH = path.join(__dirname, "template");
10
+
11
+ export const MAIN_DEPENDENCIES = [
12
+ "next@latest",
13
+ "react@latest",
14
+ "react-dom@latest",
15
+ ];
16
+
17
+ export const MAIN_DEV_DEPENDENCIES = [
18
+ "@tailwindcss/postcss@latest",
19
+ "@types/node@latest",
20
+ "@types/react@latest",
21
+ "@types/react-dom@latest",
22
+ "eslint@latest",
23
+ "eslint-config-next@latest",
24
+ "tailwindcss@latest",
25
+ "typescript@latest",
26
+ ];
@@ -0,0 +1,6 @@
1
+ export class Exception extends Error {
2
+ constructor(message) {
3
+ super(message);
4
+ this.name = "Exception";
5
+ }
6
+ }
@@ -0,0 +1,21 @@
1
+ import { promisify } from "node:util";
2
+ import { exec } from "node:child_process";
3
+
4
+ import chalk from "chalk";
5
+
6
+ import { Exception } from "./exception.js";
7
+
8
+ const execPromise = promisify(exec);
9
+
10
+ export function onCancel() {
11
+ console.log(chalk.red("\nOperation cancelled."));
12
+ process.exit(0);
13
+ }
14
+
15
+ export async function runCommand(command, args = [], cwd = process.cwd()) {
16
+ try {
17
+ await execPromise(`${command} ${args.join(" ")}`, { cwd });
18
+ } catch (error) {
19
+ throw new Exception(`Failed to run command: ${error.message}`);
20
+ }
21
+ }
package/src/main.js ADDED
@@ -0,0 +1,111 @@
1
+ #!/usr/bin/env node
2
+
3
+ import fs from "node:fs";
4
+ import path from "node:path";
5
+
6
+ import chalk from "chalk";
7
+ import prompts from "prompts";
8
+
9
+ import { CWD } from "./constants.js";
10
+ import { onCancel } from "./lib/utils.js";
11
+ import { Exception } from "./lib/exception.js";
12
+ import { creatingProject } from "./actions/creating-project.js";
13
+ import { copyingTemplateFiles } from "./actions/copying-template-files.js";
14
+ import { configurePackageJson } from "./actions/configure-package-json.js";
15
+ import { installAllDependencies } from "./actions/install-all-dependencies.js";
16
+
17
+ export const context = {
18
+ dest: "",
19
+ projectName: null,
20
+ packageManager: null,
21
+ isNewProject: true,
22
+ };
23
+
24
+ process.on("SIGINT", () => onCancel());
25
+
26
+ async function bootstrap() {
27
+ if (fs.existsSync(path.join(CWD, "next.config.ts"))) {
28
+ context.isNewProject = false;
29
+ }
30
+
31
+ console.log(chalk.green("\nWelcome to @tioelvis/next-ui!"));
32
+ console.log(
33
+ chalk.white(
34
+ "Interactive CLI to scaffold a Next.js project with customizable presets and configurations.\n",
35
+ ),
36
+ );
37
+
38
+ if (context.isNewProject === true) {
39
+ console.log(
40
+ chalk.blue("Creating a new project with the following features:"),
41
+ );
42
+ console.log(chalk.white("- Latest version of Next.js"));
43
+ console.log(chalk.white("- TypeScript enabled"));
44
+ console.log(chalk.white("- Latest version of Tailwind CSS"));
45
+ console.log(chalk.white("- Project structure inside the `src/` directory"));
46
+ console.log(chalk.white("- '@/' alias configured to import from `src`\n"));
47
+
48
+ try {
49
+ const responses = await prompts(
50
+ [
51
+ {
52
+ type: "text",
53
+ name: "projectName",
54
+ message: "What is the name of your Next.js project?",
55
+ initial: "my-app",
56
+ },
57
+ {
58
+ type: "confirm",
59
+ name: "installDependencies",
60
+ message: "Do you want to install dependencies now?",
61
+ initial: true,
62
+ },
63
+ {
64
+ type: (prev) => (prev ? "select" : null),
65
+ name: "packageManager",
66
+ message: "Which package manager do you want to use?",
67
+ choices: [
68
+ { title: "npm", value: "npm" },
69
+ { title: "yarn", value: "yarn" },
70
+ { title: "pnpm", value: "pnpm" },
71
+ ],
72
+ initial: 0,
73
+ },
74
+ ],
75
+ { onCancel },
76
+ );
77
+
78
+ const { projectName, installDependencies, packageManager } = responses;
79
+
80
+ context.projectName = projectName;
81
+ context.dest = path.join(CWD, context.projectName);
82
+ context.packageManager = packageManager;
83
+
84
+ creatingProject();
85
+ copyingTemplateFiles();
86
+ configurePackageJson();
87
+ if (installDependencies) {
88
+ await installAllDependencies();
89
+ }
90
+ // Install shadcn if user wants to use it
91
+ // Init theme color
92
+
93
+ console.log(chalk.green("\nProject setup complete!"));
94
+ } catch (error) {
95
+ if (error instanceof Exception) {
96
+ console.log(chalk.red(error.message));
97
+ } else {
98
+ console.log(chalk.red("An unexpected error occurred."));
99
+ console.error(error);
100
+ }
101
+ process.exit(1);
102
+ }
103
+ } else {
104
+ console.log(
105
+ chalk.yellow("Sorry but this package only supports new projects.\n"),
106
+ );
107
+ process.exit(0);
108
+ }
109
+ }
110
+
111
+ bootstrap();
@@ -0,0 +1,18 @@
1
+ import { defineConfig, globalIgnores } from "eslint/config";
2
+ import nextVitals from "eslint-config-next/core-web-vitals";
3
+ import nextTs from "eslint-config-next/typescript";
4
+
5
+ const eslintConfig = defineConfig([
6
+ ...nextVitals,
7
+ ...nextTs,
8
+ // Override default ignores of eslint-config-next.
9
+ globalIgnores([
10
+ // Default ignores of eslint-config-next:
11
+ ".next/**",
12
+ "out/**",
13
+ "build/**",
14
+ "next-env.d.ts",
15
+ ]),
16
+ ]);
17
+
18
+ export default eslintConfig;
@@ -0,0 +1,8 @@
1
+ import type { NextConfig } from "next";
2
+
3
+ const nextConfig: NextConfig = {
4
+ /* config options here */
5
+ reactCompiler: true,
6
+ };
7
+
8
+ export default nextConfig;
@@ -0,0 +1,7 @@
1
+ const config = {
2
+ plugins: {
3
+ "@tailwindcss/postcss": {},
4
+ },
5
+ };
6
+
7
+ export default config;
Binary file
@@ -0,0 +1,28 @@
1
+ import "./globals.css";
2
+ import type { Metadata } from "next";
3
+ import { Inter } from "next/font/google";
4
+
5
+ const inter = Inter({
6
+ subsets: ["latin"],
7
+ weight: ["400", "500", "600", "700"],
8
+ variable: "--font-inter",
9
+ });
10
+
11
+ export const metadata: Metadata = {
12
+ title: "Untitled",
13
+ icons: {
14
+ icon: "/favicon.ico",
15
+ },
16
+ };
17
+
18
+ interface Props {
19
+ children: React.ReactNode;
20
+ }
21
+
22
+ export default function Layout({ children }: Readonly<Props>) {
23
+ return (
24
+ <html lang="en">
25
+ <body className={inter.variable}>{children}</body>
26
+ </html>
27
+ );
28
+ }
@@ -0,0 +1,9 @@
1
+ import { Fragment } from "react/jsx-runtime";
2
+
3
+ export default function Page() {
4
+ return (
5
+ <Fragment>
6
+ <h1 className="text-primary">Hello, THERE!</h1>
7
+ </Fragment>
8
+ );
9
+ }
@@ -0,0 +1,34 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2017",
4
+ "lib": ["dom", "dom.iterable", "esnext"],
5
+ "allowJs": true,
6
+ "skipLibCheck": true,
7
+ "strict": true,
8
+ "noEmit": true,
9
+ "esModuleInterop": true,
10
+ "module": "esnext",
11
+ "moduleResolution": "bundler",
12
+ "resolveJsonModule": true,
13
+ "isolatedModules": true,
14
+ "jsx": "react-jsx",
15
+ "incremental": true,
16
+ "plugins": [
17
+ {
18
+ "name": "next"
19
+ }
20
+ ],
21
+ "paths": {
22
+ "@/*": ["./src/*"]
23
+ }
24
+ },
25
+ "include": [
26
+ "next-env.d.ts",
27
+ "**/*.ts",
28
+ "**/*.tsx",
29
+ ".next/types/**/*.ts",
30
+ ".next/dev/types/**/*.ts",
31
+ "**/*.mts"
32
+ ],
33
+ "exclude": ["node_modules"]
34
+ }