revine 0.1.0 → 0.3.0

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.
@@ -0,0 +1,49 @@
1
+ import path from "path";
2
+ import { fileURLToPath } from "url";
3
+ import { updatePackageJson } from "../config/package.js";
4
+ import { updateReadme } from "../config/readme.js";
5
+ import { installDependencies } from "../installers/dependencies.js";
6
+ import { askForTailwindSetup } from "../prompts/tailwind.js";
7
+ import { setupTailwind } from "../setup/tailwind.js";
8
+ import { copyTemplate } from "../utils/file.js";
9
+ import { logError, logInfo } from "../utils/logger.js";
10
+ const __filename = fileURLToPath(import.meta.url);
11
+ const __dirname = path.dirname(__filename);
12
+ export async function createProject(projectName, options) {
13
+ // Calculate directories. This uses "../../template" for your template folder.
14
+ const templateDir = path.join(__dirname, "../../template");
15
+ const projectDir = path.resolve(projectName);
16
+ const isCurrentDir = [".", "./"].includes(projectName);
17
+ try {
18
+ logInfo(`Creating project in ${projectDir}...`);
19
+ // This copies everything, including hidden directories like .revine
20
+ await copyTemplate(templateDir, projectDir, options.force);
21
+ // Derive final project name
22
+ const finalProjectName = isCurrentDir
23
+ ? path.basename(projectDir)
24
+ : projectName;
25
+ // Update package.json (e.g., set name, set "type": "module", add Tailwind deps if chosen)
26
+ const packageJsonPath = path.join(projectDir, "package.json");
27
+ const useTailwind = await askForTailwindSetup();
28
+ await updatePackageJson(packageJsonPath, finalProjectName, { useTailwind });
29
+ // Update README with the project name
30
+ const readmePath = path.join(projectDir, "README.md");
31
+ await updateReadme(readmePath, finalProjectName);
32
+ // Install dependencies
33
+ logInfo("\nInstalling dependencies...");
34
+ await installDependencies(projectDir);
35
+ // If Tailwind is selected, set it up
36
+ if (useTailwind) {
37
+ await setupTailwind(projectDir);
38
+ }
39
+ logInfo(`\nSuccess! Created project at ${projectDir}`);
40
+ logInfo("\nStart developing with:");
41
+ if (!isCurrentDir)
42
+ console.log(` cd ${projectName}`);
43
+ console.log(" npm run dev\n");
44
+ }
45
+ catch (error) {
46
+ logError("Error during project creation:", error);
47
+ process.exit(1);
48
+ }
49
+ }
@@ -0,0 +1,14 @@
1
+ import fs from "fs-extra";
2
+ export async function updatePackageJson(filePath, projectName, options = {}) {
3
+ const packageJson = await fs.readJson(filePath);
4
+ packageJson.name = projectName;
5
+ packageJson.type = "module";
6
+ if (options.useTailwind) {
7
+ packageJson.devDependencies = {
8
+ ...packageJson.devDependencies,
9
+ tailwindcss: "^4.0.0",
10
+ "@tailwindcss/vite": "^4.0.0",
11
+ };
12
+ }
13
+ await fs.writeJson(filePath, packageJson, { spaces: 2 });
14
+ }
@@ -0,0 +1,6 @@
1
+ import fs from "fs-extra";
2
+ export async function updateReadme(filePath, projectName) {
3
+ let readmeContent = await fs.readFile(filePath, "utf-8");
4
+ readmeContent = readmeContent.replace(/%PROJECT_NAME%/g, projectName);
5
+ await fs.writeFile(filePath, readmeContent);
6
+ }
@@ -0,0 +1,9 @@
1
+ import fs from "fs-extra";
2
+ export async function updateViteConfig(filePath) {
3
+ let viteConfigContent = await fs.readFile(filePath, "utf-8");
4
+ // Insert Tailwind import after the React plugin import.
5
+ viteConfigContent = viteConfigContent.replace("import react from '@vitejs/plugin-react';", "import react from '@vitejs/plugin-react';\nimport tailwindcss from '@tailwindcss/vite';");
6
+ // Insert Tailwind plugin into the plugins array.
7
+ viteConfigContent = viteConfigContent.replace("plugins: [react()]", "plugins: [\n react(),\n tailwindcss()\n ]");
8
+ await fs.writeFile(filePath, viteConfigContent);
9
+ }
package/dist/index.js CHANGED
@@ -1,101 +1,12 @@
1
1
  #!/usr/bin/env node
2
- import chalk from "chalk";
3
- import { spawnSync } from "child_process";
4
2
  import { Command } from "commander";
5
- import fs from "fs-extra";
6
- import inquirer from "inquirer";
7
- import path from "path";
8
- import { fileURLToPath } from "url";
9
- // Get directory paths in ESM
10
- const __filename = fileURLToPath(import.meta.url);
11
- const __dirname = path.dirname(__filename);
3
+ import { createProject } from "./commands/createProject.js";
12
4
  const program = new Command();
13
5
  program
14
6
  .version("0.1.0")
15
7
  .argument("<project-name>")
16
8
  .option("-f, --force", "Force creation in non-empty directory")
17
9
  .action(async (projectName, options) => {
18
- const templateDir = path.join(__dirname, "../template");
19
- const projectDir = path.resolve(projectName);
20
- const isCurrentDir = [".", "./"].includes(projectName);
21
- // ... [keep existing directory checks the same] ...
22
- try {
23
- console.log(chalk.cyan(`Creating project in ${projectDir}...`));
24
- fs.copySync(templateDir, projectDir, { overwrite: options.force });
25
- // Update package.json with ESM configuration
26
- const packageJsonPath = path.join(projectDir, "package.json");
27
- const packageJson = await fs.readJson(packageJsonPath);
28
- const finalProjectName = isCurrentDir
29
- ? path.basename(projectDir)
30
- : projectName;
31
- packageJson.name = finalProjectName;
32
- packageJson.type = "module"; // Add ESM type declaration
33
- const npmCmd = process.platform === "win32" ? "npm.cmd" : "npm";
34
- // Add Tailwind prompt
35
- const { useTailwind } = await inquirer.prompt([
36
- {
37
- type: "confirm",
38
- name: "useTailwind",
39
- message: "Would you like to set up Tailwind CSS?",
40
- default: true,
41
- },
42
- ]);
43
- // Add Tailwind v4 dependencies if selected
44
- if (useTailwind) {
45
- packageJson.devDependencies = {
46
- ...packageJson.devDependencies,
47
- tailwindcss: "^4.0.0",
48
- "@tailwindcss/vite": "^4.0.0",
49
- };
50
- }
51
- await fs.writeJson(packageJsonPath, packageJson, { spaces: 2 });
52
- // Update README
53
- const readmePath = path.join(projectDir, "README.md");
54
- let readmeContent = fs.readFileSync(readmePath, "utf-8");
55
- readmeContent = readmeContent.replace(/%PROJECT_NAME%/g, finalProjectName);
56
- fs.writeFileSync(readmePath, readmeContent);
57
- // Install dependencies with error handling
58
- console.log(chalk.cyan("\nInstalling dependencies..."));
59
- const installResult = spawnSync(npmCmd, ["install"], {
60
- stdio: "inherit",
61
- cwd: projectDir,
62
- shell: true,
63
- });
64
- if (installResult.error || installResult.status !== 0) {
65
- console.log(chalk.red("\nError installing dependencies!", installResult.error));
66
- console.log(chalk.yellow("Try running manually: npm install"));
67
- process.exit(1);
68
- }
69
- // Setup Tailwind after dependencies are installed
70
- if (useTailwind) {
71
- console.log(chalk.cyan("\nSetting up Tailwind CSS v4..."));
72
- // Update Vite config to add Tailwind plugin
73
- const viteConfigPath = path.join(projectDir, "vite.config.ts");
74
- let viteConfigContent = fs.readFileSync(viteConfigPath, "utf-8");
75
- // Add Tailwind import
76
- viteConfigContent = viteConfigContent.replace("import react from '@vitejs/plugin-react';", "import react from '@vitejs/plugin-react';\nimport tailwindcss from '@tailwindcss/vite';");
77
- // Add Tailwind plugin to existing config
78
- viteConfigContent = viteConfigContent.replace("plugins: [react()]", "plugins: [\n react(),\n tailwindcss()\n ]");
79
- fs.writeFileSync(viteConfigPath, viteConfigContent);
80
- fs.writeFileSync(viteConfigPath, viteConfigContent);
81
- // Create CSS file with import
82
- const cssDir = path.join(projectDir, "src", "styles");
83
- fs.ensureDirSync(cssDir);
84
- fs.writeFileSync(path.join(cssDir, "global.css"), "@import 'tailwindcss';\n");
85
- // Add CSS import to main.tsx
86
- const mainTsxPath = path.join(projectDir, "src", "main.tsx");
87
- const mainContent = `import './styles/global.css';\n${fs.readFileSync(mainTsxPath, "utf-8")}`;
88
- fs.writeFileSync(mainTsxPath, mainContent);
89
- }
90
- console.log(chalk.green("\nSuccess! Created project at"), chalk.yellow(projectDir));
91
- console.log(chalk.cyan("\nStart developing with:"));
92
- if (!isCurrentDir)
93
- console.log(` cd ${projectName}`);
94
- console.log(" npm run dev\n");
95
- }
96
- catch (error) {
97
- console.log(chalk.red("Error:"), error);
98
- process.exit(1);
99
- }
10
+ await createProject(projectName, options);
100
11
  });
101
12
  program.parse(process.argv);
@@ -0,0 +1,15 @@
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
+ }
@@ -0,0 +1,12 @@
1
+ import inquirer from "inquirer";
2
+ export async function askForTailwindSetup() {
3
+ const { useTailwind } = await inquirer.prompt([
4
+ {
5
+ type: "confirm",
6
+ name: "useTailwind",
7
+ message: "Would you like to set up Tailwind CSS?",
8
+ default: true,
9
+ },
10
+ ]);
11
+ return useTailwind;
12
+ }
@@ -0,0 +1,20 @@
1
+ import path from "path";
2
+ import fs from "fs-extra";
3
+ import { updateViteConfig } from "../config/vite.js";
4
+ import { logInfo } from "../utils/logger.js";
5
+ export async function setupTailwind(projectDir) {
6
+ logInfo("\nSetting up Tailwind CSS v4...");
7
+ // Point to the hidden Vite config
8
+ const viteConfigPath = path.join(projectDir, ".revine", "bundler", "vite.config.ts");
9
+ // Now use existing updateViteConfig logic on this new path
10
+ await updateViteConfig(viteConfigPath);
11
+ // Creating the CSS directory and file that imports Tailwind
12
+ const cssDir = path.join(projectDir, "src", "styles");
13
+ await fs.ensureDir(cssDir);
14
+ await fs.writeFile(path.join(cssDir, "global.css"), "@import 'tailwindcss';\n");
15
+ // Prepend the CSS import to src/main.tsx
16
+ const mainTsxPath = path.join(projectDir, "src", "main.tsx");
17
+ const mainContent = `import './styles/global.css';\n` +
18
+ (await fs.readFile(mainTsxPath, "utf-8"));
19
+ await fs.writeFile(mainTsxPath, mainContent);
20
+ }
@@ -0,0 +1,4 @@
1
+ import fs from "fs-extra";
2
+ export async function copyTemplate(templateDir, destinationDir, force) {
3
+ await fs.copy(templateDir, destinationDir, { overwrite: force });
4
+ }
@@ -0,0 +1,7 @@
1
+ import chalk from "chalk";
2
+ export function logInfo(message) {
3
+ console.log(chalk.cyan(message));
4
+ }
5
+ export function logError(message, error) {
6
+ console.error(chalk.red(message), error || "");
7
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "revine",
3
- "version": "0.1.0",
3
+ "version": "0.3.0",
4
4
  "description": "A react framework, but better.",
5
5
  "license": "ISC",
6
6
  "author": "Rachit Bharadwaj",
@@ -0,0 +1,59 @@
1
+ import path from "path";
2
+ import { fileURLToPath } from "url";
3
+ import { updatePackageJson } from "../config/package.js";
4
+ import { updateReadme } from "../config/readme.js";
5
+ import { installDependencies } from "../installers/dependencies.js";
6
+ import { askForTailwindSetup } from "../prompts/tailwind.js";
7
+ import { setupTailwind } from "../setup/tailwind.js";
8
+ import { copyTemplate } from "../utils/file.js";
9
+ import { logError, logInfo } from "../utils/logger.js";
10
+
11
+ const __filename = fileURLToPath(import.meta.url);
12
+ const __dirname = path.dirname(__filename);
13
+
14
+ export async function createProject(
15
+ projectName: string,
16
+ options: { force?: boolean }
17
+ ) {
18
+ // Calculate directories. This uses "../../template" for your template folder.
19
+ const templateDir = path.join(__dirname, "../../template");
20
+ const projectDir = path.resolve(projectName);
21
+ const isCurrentDir = [".", "./"].includes(projectName);
22
+
23
+ try {
24
+ logInfo(`Creating project in ${projectDir}...`);
25
+ // This copies everything, including hidden directories like .revine
26
+ await copyTemplate(templateDir, projectDir, options.force);
27
+
28
+ // Derive final project name
29
+ const finalProjectName = isCurrentDir
30
+ ? path.basename(projectDir)
31
+ : projectName;
32
+
33
+ // Update package.json (e.g., set name, set "type": "module", add Tailwind deps if chosen)
34
+ const packageJsonPath = path.join(projectDir, "package.json");
35
+ const useTailwind = await askForTailwindSetup();
36
+ await updatePackageJson(packageJsonPath, finalProjectName, { useTailwind });
37
+
38
+ // Update README with the project name
39
+ const readmePath = path.join(projectDir, "README.md");
40
+ await updateReadme(readmePath, finalProjectName);
41
+
42
+ // Install dependencies
43
+ logInfo("\nInstalling dependencies...");
44
+ await installDependencies(projectDir);
45
+
46
+ // If Tailwind is selected, set it up
47
+ if (useTailwind) {
48
+ await setupTailwind(projectDir);
49
+ }
50
+
51
+ logInfo(`\nSuccess! Created project at ${projectDir}`);
52
+ logInfo("\nStart developing with:");
53
+ if (!isCurrentDir) console.log(` cd ${projectName}`);
54
+ console.log(" npm run dev\n");
55
+ } catch (error) {
56
+ logError("Error during project creation:", error);
57
+ process.exit(1);
58
+ }
59
+ }
@@ -0,0 +1,23 @@
1
+ import fs from "fs-extra";
2
+
3
+ interface UpdatePackageOptions {
4
+ useTailwind?: boolean;
5
+ }
6
+
7
+ export async function updatePackageJson(
8
+ filePath: string,
9
+ projectName: string,
10
+ options: UpdatePackageOptions = {}
11
+ ) {
12
+ const packageJson = await fs.readJson(filePath);
13
+ packageJson.name = projectName;
14
+ packageJson.type = "module";
15
+ if (options.useTailwind) {
16
+ packageJson.devDependencies = {
17
+ ...packageJson.devDependencies,
18
+ tailwindcss: "^4.0.0",
19
+ "@tailwindcss/vite": "^4.0.0",
20
+ };
21
+ }
22
+ await fs.writeJson(filePath, packageJson, { spaces: 2 });
23
+ }
@@ -0,0 +1,7 @@
1
+ import fs from "fs-extra";
2
+
3
+ export async function updateReadme(filePath: string, projectName: string) {
4
+ let readmeContent = await fs.readFile(filePath, "utf-8");
5
+ readmeContent = readmeContent.replace(/%PROJECT_NAME%/g, projectName);
6
+ await fs.writeFile(filePath, readmeContent);
7
+ }
@@ -0,0 +1,19 @@
1
+ import fs from "fs-extra";
2
+
3
+ export async function updateViteConfig(filePath: string) {
4
+ let viteConfigContent = await fs.readFile(filePath, "utf-8");
5
+
6
+ // Insert Tailwind import after the React plugin import.
7
+ viteConfigContent = viteConfigContent.replace(
8
+ "import react from '@vitejs/plugin-react';",
9
+ "import react from '@vitejs/plugin-react';\nimport tailwindcss from '@tailwindcss/vite';"
10
+ );
11
+
12
+ // Insert Tailwind plugin into the plugins array.
13
+ viteConfigContent = viteConfigContent.replace(
14
+ "plugins: [react()]",
15
+ "plugins: [\n react(),\n tailwindcss()\n ]"
16
+ );
17
+
18
+ await fs.writeFile(filePath, viteConfigContent);
19
+ }
package/src/index.ts CHANGED
@@ -1,16 +1,6 @@
1
1
  #!/usr/bin/env node
2
-
3
- import chalk from "chalk";
4
- import { spawnSync } from "child_process";
5
2
  import { Command } from "commander";
6
- import fs from "fs-extra";
7
- import inquirer from "inquirer";
8
- import path from "path";
9
- import { fileURLToPath } from "url";
10
-
11
- // Get directory paths in ESM
12
- const __filename = fileURLToPath(import.meta.url);
13
- const __dirname = path.dirname(__filename);
3
+ import { createProject } from "./commands/createProject.js";
14
4
 
15
5
  const program = new Command();
16
6
 
@@ -19,125 +9,7 @@ program
19
9
  .argument("<project-name>")
20
10
  .option("-f, --force", "Force creation in non-empty directory")
21
11
  .action(async (projectName: string, options: { force?: boolean }) => {
22
- const templateDir = path.join(__dirname, "../template");
23
- const projectDir = path.resolve(projectName);
24
- const isCurrentDir = [".", "./"].includes(projectName);
25
-
26
- // ... [keep existing directory checks the same] ...
27
-
28
- try {
29
- console.log(chalk.cyan(`Creating project in ${projectDir}...`));
30
- fs.copySync(templateDir, projectDir, { overwrite: options.force });
31
-
32
- // Update package.json with ESM configuration
33
- const packageJsonPath = path.join(projectDir, "package.json");
34
- const packageJson = await fs.readJson(packageJsonPath);
35
- const finalProjectName = isCurrentDir
36
- ? path.basename(projectDir)
37
- : projectName;
38
-
39
- packageJson.name = finalProjectName;
40
- packageJson.type = "module"; // Add ESM type declaration
41
-
42
- const npmCmd = process.platform === "win32" ? "npm.cmd" : "npm";
43
-
44
- // Add Tailwind prompt
45
- const { useTailwind } = await inquirer.prompt([
46
- {
47
- type: "confirm",
48
- name: "useTailwind",
49
- message: "Would you like to set up Tailwind CSS?",
50
- default: true,
51
- },
52
- ]);
53
-
54
- // Add Tailwind v4 dependencies if selected
55
- if (useTailwind) {
56
- packageJson.devDependencies = {
57
- ...packageJson.devDependencies,
58
- tailwindcss: "^4.0.0",
59
- "@tailwindcss/vite": "^4.0.0",
60
- };
61
- }
62
-
63
- await fs.writeJson(packageJsonPath, packageJson, { spaces: 2 });
64
-
65
- // Update README
66
- const readmePath = path.join(projectDir, "README.md");
67
- let readmeContent = fs.readFileSync(readmePath, "utf-8");
68
- readmeContent = readmeContent.replace(
69
- /%PROJECT_NAME%/g,
70
- finalProjectName
71
- );
72
- fs.writeFileSync(readmePath, readmeContent);
73
-
74
- // Install dependencies with error handling
75
- console.log(chalk.cyan("\nInstalling dependencies..."));
76
- const installResult = spawnSync(npmCmd, ["install"], {
77
- stdio: "inherit",
78
- cwd: projectDir,
79
- shell: true,
80
- });
81
-
82
- if (installResult.error || installResult.status !== 0) {
83
- console.log(
84
- chalk.red("\nError installing dependencies!", installResult.error)
85
- );
86
- console.log(chalk.yellow("Try running manually: npm install"));
87
- process.exit(1);
88
- }
89
-
90
- // Setup Tailwind after dependencies are installed
91
- if (useTailwind) {
92
- console.log(chalk.cyan("\nSetting up Tailwind CSS v4..."));
93
-
94
- // Update Vite config to add Tailwind plugin
95
- const viteConfigPath = path.join(projectDir, "vite.config.ts");
96
- let viteConfigContent = fs.readFileSync(viteConfigPath, "utf-8");
97
-
98
- // Add Tailwind import
99
- viteConfigContent = viteConfigContent.replace(
100
- "import react from '@vitejs/plugin-react';",
101
- "import react from '@vitejs/plugin-react';\nimport tailwindcss from '@tailwindcss/vite';"
102
- );
103
-
104
- // Add Tailwind plugin to existing config
105
- viteConfigContent = viteConfigContent.replace(
106
- "plugins: [react()]",
107
- "plugins: [\n react(),\n tailwindcss()\n ]"
108
- );
109
-
110
- fs.writeFileSync(viteConfigPath, viteConfigContent);
111
- fs.writeFileSync(viteConfigPath, viteConfigContent);
112
-
113
- // Create CSS file with import
114
- const cssDir = path.join(projectDir, "src", "styles");
115
- fs.ensureDirSync(cssDir);
116
- fs.writeFileSync(
117
- path.join(cssDir, "global.css"),
118
- "@import 'tailwindcss';\n"
119
- );
120
-
121
- // Add CSS import to main.tsx
122
- const mainTsxPath = path.join(projectDir, "src", "main.tsx");
123
- const mainContent = `import './styles/global.css';\n${fs.readFileSync(
124
- mainTsxPath,
125
- "utf-8"
126
- )}`;
127
- fs.writeFileSync(mainTsxPath, mainContent);
128
- }
129
-
130
- console.log(
131
- chalk.green("\nSuccess! Created project at"),
132
- chalk.yellow(projectDir)
133
- );
134
- console.log(chalk.cyan("\nStart developing with:"));
135
- if (!isCurrentDir) console.log(` cd ${projectName}`);
136
- console.log(" npm run dev\n");
137
- } catch (error) {
138
- console.log(chalk.red("Error:"), error);
139
- process.exit(1);
140
- }
12
+ await createProject(projectName, options);
141
13
  });
142
14
 
143
15
  program.parse(process.argv);
@@ -0,0 +1,16 @@
1
+ import { spawnSync } from "child_process";
2
+ import { logError, logInfo } from "../utils/logger.js";
3
+
4
+ export async function installDependencies(projectDir: string): Promise<void> {
5
+ const npmCmd = process.platform === "win32" ? "npm.cmd" : "npm";
6
+ const installResult = spawnSync(npmCmd, ["install"], {
7
+ stdio: "inherit",
8
+ cwd: projectDir,
9
+ shell: true,
10
+ });
11
+ if (installResult.error || installResult.status !== 0) {
12
+ logError("Error installing dependencies:", installResult.error);
13
+ logInfo("Try running manually: npm install");
14
+ process.exit(1);
15
+ }
16
+ }
@@ -0,0 +1,13 @@
1
+ import inquirer from "inquirer";
2
+
3
+ export async function askForTailwindSetup(): Promise<boolean> {
4
+ const { useTailwind } = await inquirer.prompt([
5
+ {
6
+ type: "confirm",
7
+ name: "useTailwind",
8
+ message: "Would you like to set up Tailwind CSS?",
9
+ default: true,
10
+ },
11
+ ]);
12
+ return useTailwind;
13
+ }
@@ -0,0 +1,34 @@
1
+ import path from "path";
2
+ import fs from "fs-extra";
3
+ import { updateViteConfig } from "../config/vite.js";
4
+ import { logInfo } from "../utils/logger.js";
5
+
6
+ export async function setupTailwind(projectDir: string) {
7
+ logInfo("\nSetting up Tailwind CSS v4...");
8
+
9
+ // Point to the hidden Vite config
10
+ const viteConfigPath = path.join(
11
+ projectDir,
12
+ ".revine",
13
+ "bundler",
14
+ "vite.config.ts"
15
+ );
16
+
17
+ // Now use existing updateViteConfig logic on this new path
18
+ await updateViteConfig(viteConfigPath);
19
+
20
+ // Creating the CSS directory and file that imports Tailwind
21
+ const cssDir = path.join(projectDir, "src", "styles");
22
+ await fs.ensureDir(cssDir);
23
+ await fs.writeFile(
24
+ path.join(cssDir, "global.css"),
25
+ "@import 'tailwindcss';\n"
26
+ );
27
+
28
+ // Prepend the CSS import to src/main.tsx
29
+ const mainTsxPath = path.join(projectDir, "src", "main.tsx");
30
+ const mainContent =
31
+ `import './styles/global.css';\n` +
32
+ (await fs.readFile(mainTsxPath, "utf-8"));
33
+ await fs.writeFile(mainTsxPath, mainContent);
34
+ }
@@ -0,0 +1,9 @@
1
+ import fs from "fs-extra";
2
+
3
+ export async function copyTemplate(
4
+ templateDir: string,
5
+ destinationDir: string,
6
+ force?: boolean
7
+ ): Promise<void> {
8
+ await fs.copy(templateDir, destinationDir, { overwrite: force });
9
+ }
@@ -0,0 +1,9 @@
1
+ import chalk from "chalk";
2
+
3
+ export function logInfo(message: string) {
4
+ console.log(chalk.cyan(message));
5
+ }
6
+
7
+ export function logError(message: string, error?: any) {
8
+ console.error(chalk.red(message), error || "");
9
+ }
@@ -0,0 +1,14 @@
1
+ import react from "@vitejs/plugin-react";
2
+
3
+ export const defaultViteConfig = {
4
+ plugins: [react()],
5
+ server: {
6
+ open: true,
7
+ port: 3000,
8
+ host: true,
9
+ },
10
+ build: {
11
+ outDir: "build",
12
+ emptyOutDir: true,
13
+ },
14
+ };
@@ -0,0 +1,18 @@
1
+ // .revine/bundler/generateConfig.ts
2
+ import { merge } from 'lodash-es';
3
+ import { defaultViteConfig } from './defaults/vite.js';
4
+ import { loadUserConfig } from './utils/loadUserConfig.js';
5
+ import tailwindcss from '@tailwindcss/vite'; // For direct plugin usage
6
+
7
+ export async function generateRevineViteConfig() {
8
+ // Load the user's revine.config.ts
9
+ const userConfig = await loadUserConfig();
10
+
11
+ // Merge user "vite" overrides with your default config
12
+ const finalConfig = merge({}, defaultViteConfig, userConfig.vite || {});
13
+
14
+ // Insert the Tailwind plugin, if desired, automatically or conditionally:
15
+ // finalConfig.plugins.push(tailwindcss());
16
+
17
+ return finalConfig;
18
+ }
@@ -0,0 +1,13 @@
1
+ export async function loadUserConfig() {
2
+ try {
3
+ // relative path to the user's revine.config.ts
4
+ const configModule = await import("../../../revine.config.ts");
5
+ return configModule.default || {};
6
+ } catch (error) {
7
+ console.error(
8
+ "[Revine] Could not load revine.config.ts, using defaults.",
9
+ error
10
+ );
11
+ return {};
12
+ }
13
+ }
@@ -0,0 +1,8 @@
1
+ import { defineConfig } from "vite";
2
+ import { generateRevineViteConfig } from "./generateConfig.js";
3
+
4
+ // Vite supports async config. We can do:
5
+ export default defineConfig(async () => {
6
+ // Merge defaults + user overrides
7
+ return await generateRevineViteConfig();
8
+ });
@@ -1,21 +1,23 @@
1
1
  {
2
- "name": "{{project-name}}",
3
- "version": "0.1.0",
4
- "scripts": {
5
- "dev": "vite",
6
- "build": "vite build",
7
- "preview": "vite preview"
8
- },
9
- "dependencies": {
10
- "react": "^18.2.0",
11
- "react-dom": "^18.2.0",
12
- "react-router-dom": "^6.22.3"
13
- },
14
- "devDependencies": {
15
- "@types/react": "^18.2.45",
16
- "@types/react-dom": "^18.2.18",
17
- "typescript": "^5.3.3",
18
- "vite": "^5.0.12",
19
- "@vitejs/plugin-react": "^4.2.1"
20
- }
21
- }
2
+ "name": "{{project-name}}",
3
+ "version": "0.1.0",
4
+ "scripts": {
5
+ "dev": "vite --config .revine/bundler/vite.config.ts",
6
+ "build": "vite build --config .revine/bundler/vite.config.ts",
7
+ "preview": "vite preview --config .revine/bundler/vite.config.ts"
8
+ },
9
+ "dependencies": {
10
+ "react": "^18.2.0",
11
+ "react-dom": "^18.2.0",
12
+ "react-router-dom": "^6.22.3"
13
+ },
14
+ "devDependencies": {
15
+ "@types/react": "^18.2.45",
16
+ "@types/react-dom": "^18.2.18",
17
+ "typescript": "^5.3.3",
18
+ "vite": "^5.0.12",
19
+ "@vitejs/plugin-react": "^4.2.1",
20
+ "lodash-es": "^4.17.21",
21
+ "@tailwindcss/vite": "^4.0.0"
22
+ }
23
+ }
@@ -0,0 +1,13 @@
1
+ export default {
2
+ vite: {
3
+ server: {
4
+ open: true,
5
+ port: 3000,
6
+ host: true,
7
+ },
8
+ build: {
9
+ outDir: "build",
10
+ emptyOutDir: true,
11
+ },
12
+ },
13
+ };
@@ -16,5 +16,5 @@
16
16
  "noFallthroughCasesInSwitch": true,
17
17
  "types": ["vite/client"]
18
18
  },
19
- "include": ["src"]
19
+ "include": ["src", ".revine/bundler/types/**/*"]
20
20
  }
@@ -1,15 +0,0 @@
1
- import { defineConfig } from 'vite';
2
- import react from '@vitejs/plugin-react';
3
-
4
- export default defineConfig({
5
- plugins: [react()],
6
- server: {
7
- open: true,
8
- port: 3000,
9
- host: true
10
- },
11
- build: {
12
- outDir: 'dist',
13
- emptyOutDir: true,
14
- }
15
- });