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.
- package/dist/commands/createProject.js +20 -2
- package/dist/index.js +19 -1
- package/package.json +1 -1
- package/src/commands/createProject.ts +25 -2
- package/src/index.ts +20 -1
- package/dist/commands/create.js +0 -65
- package/dist/installers/dependencies.js +0 -15
- package/dist/lib/setup/directory.js +0 -21
- package/dist/lib/setup/package.js +0 -17
- package/dist/lib/setup/tailwind.js +0 -22
- package/dist/lib/utils/exec.js +0 -15
- package/dist/lib/utils/paths.js +0 -6
|
@@ -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
|
-
//
|
|
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
|
-
//
|
|
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
|
|
28
|
+
await handleProjectCreation(projectName, options);
|
|
11
29
|
});
|
|
12
30
|
program.parse(process.argv);
|
package/package.json
CHANGED
|
@@ -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
|
-
//
|
|
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
|
-
//
|
|
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
|
|
31
|
+
await handleProjectCreation(projectName, options);
|
|
13
32
|
});
|
|
14
33
|
|
|
15
34
|
program.parse(process.argv);
|
package/dist/commands/create.js
DELETED
|
@@ -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
|
-
}
|
package/dist/lib/utils/exec.js
DELETED
|
@@ -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
|
-
}
|