revine 0.8.0 → 0.8.1

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.
@@ -1,5 +1,6 @@
1
1
  import path from "path";
2
2
  import { fileURLToPath } from "url";
3
+ import fs from "fs-extra";
3
4
  import { updatePackageJson } from "../config/package.js";
4
5
  import { updateReadme } from "../config/readme.js";
5
6
  import { askForTailwindSetup, initGit, runProject } from "../prompts/index.js";
@@ -16,18 +17,35 @@ export async function createProject(projectName, options) {
16
17
  const isCurrentDir = [".", "./"].includes(projectName);
17
18
  try {
18
19
  logInfo(`Creating project in ${projectDir}...`);
20
+ // Ensure the project directory exists
21
+ await fs.ensureDir(projectDir);
19
22
  // This copies everything, including hidden directories like .revine
20
23
  await copyTemplate(templateDir, projectDir, options.force);
21
24
  // Derive final project name
22
25
  const finalProjectName = isCurrentDir
23
26
  ? path.basename(projectDir)
24
27
  : projectName;
25
- // Update package.json (e.g., set name, set "type": "module", add Tailwind deps if chosen)
28
+ // Check if package.json exists after template copy
26
29
  const packageJsonPath = path.join(projectDir, "package.json");
30
+ // Create basic package.json if it doesn't exist
31
+ if (!await fs.pathExists(packageJsonPath)) {
32
+ const basicPackageJson = {
33
+ name: finalProjectName,
34
+ version: "0.1.0",
35
+ private: true,
36
+ type: "module"
37
+ };
38
+ await fs.writeJSON(packageJsonPath, basicPackageJson, { spaces: 2 });
39
+ }
40
+ // Update package.json with the correct details
27
41
  const useTailwind = await askForTailwindSetup();
28
42
  await updatePackageJson(packageJsonPath, finalProjectName, { useTailwind });
29
- // Update README with the project name
43
+ // Check if README exists, create it if it doesn't
30
44
  const readmePath = path.join(projectDir, "README.md");
45
+ if (!await fs.pathExists(readmePath)) {
46
+ await fs.writeFile(readmePath, `# ${finalProjectName}\n\nCreated with Revine`);
47
+ }
48
+ // Update README with the project name
31
49
  await updateReadme(readmePath, finalProjectName);
32
50
  // Install dependencies
33
51
  logInfo("\nInstalling dependencies...");
package/dist/index.js CHANGED
@@ -2,11 +2,29 @@
2
2
  import { Command } from "commander";
3
3
  import { createProject } from "./commands/createProject.js";
4
4
  const program = new Command();
5
+ // Main command handler for direct project creation
6
+ const handleProjectCreation = async (projectName, options) => {
7
+ await createProject(projectName, options);
8
+ };
9
+ // Root command (npx revine my-app)
5
10
  program
6
11
  .version("0.1.0")
12
+ .argument("[project-name]")
13
+ .option("-f, --force", "Force creation in non-empty directory")
14
+ .action(async (projectName, options) => {
15
+ if (projectName) {
16
+ await handleProjectCreation(projectName, options);
17
+ }
18
+ else {
19
+ program.help();
20
+ }
21
+ });
22
+ // Create subcommand (npx revine create my-app)
23
+ program
24
+ .command("create")
7
25
  .argument("<project-name>")
8
26
  .option("-f, --force", "Force creation in non-empty directory")
9
27
  .action(async (projectName, options) => {
10
- await createProject(projectName, options);
28
+ await handleProjectCreation(projectName, options);
11
29
  });
12
30
  program.parse(process.argv);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "revine",
3
- "version": "0.8.0",
3
+ "version": "0.8.1",
4
4
  "description": "A react framework, but better.",
5
5
  "license": "ISC",
6
6
  "author": "Rachit Bharadwaj",
@@ -1,5 +1,6 @@
1
1
  import path from "path";
2
2
  import { fileURLToPath } from "url";
3
+ import fs from "fs-extra";
3
4
  import { updatePackageJson } from "../config/package.js";
4
5
  import { updateReadme } from "../config/readme.js";
5
6
  import { askForTailwindSetup, initGit, runProject } from "../prompts/index.js";
@@ -22,6 +23,10 @@ export async function createProject(
22
23
 
23
24
  try {
24
25
  logInfo(`Creating project in ${projectDir}...`);
26
+
27
+ // Ensure the project directory exists
28
+ await fs.ensureDir(projectDir);
29
+
25
30
  // This copies everything, including hidden directories like .revine
26
31
  await copyTemplate(templateDir, projectDir, options.force);
27
32
 
@@ -30,13 +35,31 @@ export async function createProject(
30
35
  ? path.basename(projectDir)
31
36
  : projectName;
32
37
 
33
- // Update package.json (e.g., set name, set "type": "module", add Tailwind deps if chosen)
38
+ // Check if package.json exists after template copy
34
39
  const packageJsonPath = path.join(projectDir, "package.json");
40
+
41
+ // Create basic package.json if it doesn't exist
42
+ if (!await fs.pathExists(packageJsonPath)) {
43
+ const basicPackageJson = {
44
+ name: finalProjectName,
45
+ version: "0.1.0",
46
+ private: true,
47
+ type: "module"
48
+ };
49
+ await fs.writeJSON(packageJsonPath, basicPackageJson, { spaces: 2 });
50
+ }
51
+
52
+ // Update package.json with the correct details
35
53
  const useTailwind = await askForTailwindSetup();
36
54
  await updatePackageJson(packageJsonPath, finalProjectName, { useTailwind });
37
55
 
38
- // Update README with the project name
56
+ // Check if README exists, create it if it doesn't
39
57
  const readmePath = path.join(projectDir, "README.md");
58
+ if (!await fs.pathExists(readmePath)) {
59
+ await fs.writeFile(readmePath, `# ${finalProjectName}\n\nCreated with Revine`);
60
+ }
61
+
62
+ // Update README with the project name
40
63
  await updateReadme(readmePath, finalProjectName);
41
64
 
42
65
  // Install dependencies
package/src/index.ts CHANGED
@@ -4,12 +4,31 @@ import { createProject } from "./commands/createProject.js";
4
4
 
5
5
  const program = new Command();
6
6
 
7
+ // Main command handler for direct project creation
8
+ const handleProjectCreation = async (projectName: string, options: { force?: boolean }) => {
9
+ await createProject(projectName, options);
10
+ };
11
+
12
+ // Root command (npx revine my-app)
7
13
  program
8
14
  .version("0.1.0")
15
+ .argument("[project-name]")
16
+ .option("-f, --force", "Force creation in non-empty directory")
17
+ .action(async (projectName: string, options: { force?: boolean }) => {
18
+ if (projectName) {
19
+ await handleProjectCreation(projectName, options);
20
+ } else {
21
+ program.help();
22
+ }
23
+ });
24
+
25
+ // Create subcommand (npx revine create my-app)
26
+ program
27
+ .command("create")
9
28
  .argument("<project-name>")
10
29
  .option("-f, --force", "Force creation in non-empty directory")
11
30
  .action(async (projectName: string, options: { force?: boolean }) => {
12
- await createProject(projectName, options);
31
+ await handleProjectCreation(projectName, options);
13
32
  });
14
33
 
15
34
  program.parse(process.argv);
@@ -1,65 +0,0 @@
1
- import { Command } from "commander";
2
- import chalk from "chalk";
3
- import fs from "fs-extra";
4
- import path from "path";
5
- import inquirer from "inquirer";
6
- // locals
7
- import { getDirname } from "../lib/utils/paths.js";
8
- import { validateDirectory } from "../lib/setup/directory.js";
9
- import { updatePackageJson } from "../lib/setup/package.js";
10
- import { setupTailwind } from "../lib/setup/tailwind.js";
11
- import { runInstall } from "../lib/utils/exec.js";
12
- const __dirname = getDirname(import.meta.url);
13
- export function createCommand() {
14
- const command = new Command("create")
15
- .description("Create a new Revine project")
16
- .argument("<project-name>")
17
- .option("-f, --force", "Force creation in non-empty directory")
18
- .action(async (projectName, options) => {
19
- try {
20
- const templateDir = path.join(__dirname, "../../template");
21
- const projectDir = path.resolve(projectName);
22
- const isCurrentDir = [".", "./"].includes(projectName);
23
- // Validate directory
24
- validateDirectory(projectDir, isCurrentDir, options.force);
25
- // Copy template
26
- console.log(chalk.cyan(`Creating project in ${projectDir}...`));
27
- fs.copySync(templateDir, projectDir, { overwrite: options.force });
28
- // Update package.json
29
- const { useTailwind } = await inquirer.prompt([
30
- {
31
- type: "confirm",
32
- name: "useTailwind",
33
- message: "Would you like to set up Tailwind CSS?",
34
- default: true,
35
- },
36
- ]);
37
- await updatePackageJson(projectDir, isCurrentDir ? path.basename(projectDir) : projectName, useTailwind);
38
- // Update README
39
- const readmePath = path.join(projectDir, "README.md");
40
- let readmeContent = fs.readFileSync(readmePath, "utf-8");
41
- fs.writeFileSync(readmePath, readmeContent.replace(/%PROJECT_NAME%/g, projectName));
42
- // Install dependencies
43
- console.log(chalk.cyan("\nInstalling dependencies..."));
44
- runInstall(projectDir);
45
- // Setup Tailwind
46
- if (useTailwind) {
47
- setupTailwind(projectDir);
48
- }
49
- // Final message
50
- console.log(chalk.green("\nSuccess! Created project at"), chalk.yellow(projectDir));
51
- console.log(chalk.cyan("\nStart developing with:"));
52
- if (!isCurrentDir)
53
- console.log(` cd ${projectName}`);
54
- console.log(" npm run dev\n");
55
- }
56
- catch (error) {
57
- let message = "Unknown error occurred";
58
- if (error instanceof Error)
59
- message = error.message;
60
- console.log(chalk.red("Error:"), message);
61
- process.exit(1);
62
- }
63
- });
64
- return command;
65
- }
@@ -1,15 +0,0 @@
1
- import { spawnSync } from "child_process";
2
- import { logError, logInfo } from "../utils/logger.js";
3
- export async function installDependencies(projectDir) {
4
- const npmCmd = process.platform === "win32" ? "npm.cmd" : "npm";
5
- const installResult = spawnSync(npmCmd, ["install"], {
6
- stdio: "inherit",
7
- cwd: projectDir,
8
- shell: true,
9
- });
10
- if (installResult.error || installResult.status !== 0) {
11
- logError("Error installing dependencies:", installResult.error);
12
- logInfo("Try running manually: npm install");
13
- process.exit(1);
14
- }
15
- }
@@ -1,21 +0,0 @@
1
- import fs from "fs-extra";
2
- import chalk from "chalk";
3
- export function validateDirectory(projectDir, isCurrentDir, force) {
4
- if (fs.existsSync(projectDir)) {
5
- if (!isCurrentDir && !force) {
6
- console.log(chalk.red(`Error: Directory "${projectDir}" already exists.`));
7
- process.exit(1);
8
- }
9
- const existingFiles = fs
10
- .readdirSync(projectDir)
11
- .filter((file) => file !== ".git");
12
- if (existingFiles.length > 0 && !force) {
13
- console.log(chalk.red(`Error: Directory "${projectDir}" is not empty.`));
14
- console.log(chalk.yellow("Use --force to override existing files"));
15
- process.exit(1);
16
- }
17
- }
18
- else {
19
- fs.mkdirpSync(projectDir);
20
- }
21
- }
@@ -1,17 +0,0 @@
1
- import fs from "fs-extra";
2
- import path from "path";
3
- export async function updatePackageJson(projectDir, projectName, useTailwind) {
4
- const packageJsonPath = path.join(projectDir, "package.json");
5
- const packageJson = await fs.readJson(packageJsonPath);
6
- packageJson.name = projectName;
7
- packageJson.type = "module";
8
- if (useTailwind) {
9
- packageJson.devDependencies = {
10
- ...packageJson.devDependencies,
11
- tailwindcss: "^4.0.0",
12
- "@tailwindcss/vite": "^4.0.0",
13
- };
14
- }
15
- await fs.writeJson(packageJsonPath, packageJson, { spaces: 2 });
16
- return packageJson;
17
- }
@@ -1,22 +0,0 @@
1
- import fs from "fs-extra";
2
- import path from "path";
3
- import chalk from "chalk";
4
- export function setupTailwind(projectDir) {
5
- console.log(chalk.cyan("\nSetting up Tailwind CSS..."));
6
- // Update Vite config
7
- const viteConfigPath = path.join(projectDir, "vite.config.ts");
8
- let viteConfig = fs.readFileSync(viteConfigPath, "utf-8");
9
- viteConfig = viteConfig
10
- .replace("import react from '@vitejs/plugin-react';", "import react from '@vitejs/plugin-react';\nimport tailwindcss from '@tailwindcss/vite';")
11
- .replace("plugins: [react()]", "plugins: [\n react(),\n tailwindcss()\n ]");
12
- fs.writeFileSync(viteConfigPath, viteConfig);
13
- // Create styles directory
14
- const cssDir = path.join(projectDir, "src", "styles");
15
- fs.ensureDirSync(cssDir);
16
- // Create CSS file
17
- fs.writeFileSync(path.join(cssDir, "global.css"), "@import 'tailwindcss';\n");
18
- // Update main entry file
19
- const mainTsxPath = path.join(projectDir, "src", "main.tsx");
20
- const mainContent = `import './styles/global.css';\n${fs.readFileSync(mainTsxPath, "utf-8")}`;
21
- fs.writeFileSync(mainTsxPath, mainContent);
22
- }
@@ -1,15 +0,0 @@
1
- import { spawnSync } from "child_process";
2
- import { platform } from "os";
3
- export function getNpmCommand() {
4
- return platform() === "win32" ? "npm.cmd" : "npm";
5
- }
6
- export function runInstall(cwd) {
7
- const result = spawnSync(getNpmCommand(), ["install"], {
8
- stdio: "inherit",
9
- cwd,
10
- shell: true,
11
- });
12
- if (result.error || result.status !== 0) {
13
- throw new Error("Dependency installation failed");
14
- }
15
- }
@@ -1,6 +0,0 @@
1
- import { fileURLToPath } from 'url';
2
- import path from 'path';
3
- export function getDirname(metaUrl) {
4
- const __filename = fileURLToPath(metaUrl);
5
- return path.dirname(__filename);
6
- }