astrod-cli 1.0.1 → 1.0.4
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/bin/cli.js +57 -7
- package/package.json +1 -2
- package/templates/next/module/src/app/layout.tsx +22 -0
- package/templates/next/module/src/app/page.tsx +12 -0
- package/templates/next/module/src/config/index.ts +0 -0
- package/templates/next/module/src/modules/auth/components/.gitkeep +0 -0
- package/templates/next/module/src/modules/auth/index.ts +0 -0
- package/templates/next/module/src/modules/dashboard/index.ts +0 -0
- package/templates/next/module/src/styles/globals.css +0 -0
- package/templates/react-native/module/src/app/App.tsx +19 -0
- package/templates/react-native/module/src/app/index.js +0 -0
- package/templates/react-native/module/src/modules/auth/index.ts +0 -0
- package/templates/react-native/module/src/modules/dashboard/index.ts +0 -0
- package/templates/react-native/module/src/shared/navigation/AppNavigator.tsx +0 -0
- package/templates/vite/module/src/App.jsx +12 -0
- package/templates/vite/module/src/app/App.tsx +14 -0
- package/templates/vite/module/src/app/main.tsx +9 -0
- package/templates/vite/module/src/app/router.tsx +15 -0
- package/templates/vite/module/src/config/index.ts +7 -0
- package/templates/vite/module/src/modules/auth/components/.gitkeep +0 -0
- package/templates/vite/module/src/modules/auth/hooks/.gitkeep +0 -0
- package/templates/vite/module/src/modules/auth/index.ts +0 -0
- package/templates/vite/module/src/modules/auth/routes.tsx +0 -0
- package/templates/vite/module/src/modules/auth/services/.gitkeep +0 -0
- package/templates/vite/module/src/modules/auth/types/.gitkeep +0 -0
- package/templates/vite/module/src/modules/auth/utils/.gitkeep +0 -0
- package/templates/vite/module/src/modules/dashboard/components/.gitkeep +0 -0
- package/templates/vite/module/src/modules/dashboard/index.ts +0 -0
- package/templates/vite/module/src/modules/dashboard/routes.tsx +0 -0
- package/templates/vite/module/src/modules/shared/components/.gitkeep +0 -0
- package/templates/vite/module/src/modules/shared/components/Button.tsx +26 -0
- package/templates/vite/module/src/styles/global.css +29 -0
- package/templates/vite/module/src/vite-env.d.ts +0 -0
- package/templates/vite/open/src/App.jsx +12 -0
package/bin/cli.js
CHANGED
|
@@ -46,15 +46,50 @@ async function listFiles(dir, baseDir = '') {
|
|
|
46
46
|
return results;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
+
async function updateViteMainFile(targetDir) {
|
|
50
|
+
const mainFiles = ['main.jsx', 'main.tsx'];
|
|
51
|
+
for (const file of mainFiles) {
|
|
52
|
+
const filePath = path.join(targetDir, file);
|
|
53
|
+
if (fs.existsSync(filePath)) {
|
|
54
|
+
let content = await fs.readFile(filePath, 'utf8');
|
|
55
|
+
|
|
56
|
+
// Update App import to point to the new app/App location
|
|
57
|
+
content = content.replace(/import App from '\.\/App'/g, "import App from './app/App'");
|
|
58
|
+
|
|
59
|
+
// Remove old CSS imports
|
|
60
|
+
content = content.replace(/import '\.\/App\.css';?\n?/g, "");
|
|
61
|
+
content = content.replace(/import '\.\/index\.css';?\n?/g, "");
|
|
62
|
+
|
|
63
|
+
await fs.writeFile(filePath, content, 'utf8');
|
|
64
|
+
console.log(`\x1b[32mUpdated ${file} to use new module structure.\x1b[0m`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async function cleanupViteFiles(targetDir) {
|
|
70
|
+
// Common files to remove for a clean module structure
|
|
71
|
+
const filesToDelete = [
|
|
72
|
+
'App.jsx', 'App.tsx', 'App.css', 'index.css',
|
|
73
|
+
'components', 'hooks', 'utils', 'pages'
|
|
74
|
+
];
|
|
75
|
+
for (const item of filesToDelete) {
|
|
76
|
+
const itemPath = path.join(targetDir, item);
|
|
77
|
+
if (fs.existsSync(itemPath)) {
|
|
78
|
+
await fs.remove(itemPath);
|
|
79
|
+
console.log(`\x1b[33mRemoved existing ${item} for clean module initialization.\x1b[0m`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
49
84
|
program
|
|
50
|
-
.name('
|
|
85
|
+
.name('astrod')
|
|
51
86
|
.description('CLI to inject folder structures into Vite, Next, and React Native projects')
|
|
52
87
|
.version('1.0.0');
|
|
53
88
|
|
|
54
89
|
program
|
|
55
90
|
.command('init')
|
|
56
91
|
.description('Initialize the folder structure')
|
|
57
|
-
.option('-f, --force', 'Overwrite
|
|
92
|
+
.option('-f, --force', 'Overwrite conflicting files if src directory already exists')
|
|
58
93
|
.option('-d, --dry-run', 'List files that would be created without actually creating them')
|
|
59
94
|
.action(async (options) => {
|
|
60
95
|
try {
|
|
@@ -91,17 +126,32 @@ program
|
|
|
91
126
|
return;
|
|
92
127
|
}
|
|
93
128
|
|
|
94
|
-
if (fs.existsSync(targetDir)
|
|
95
|
-
console.
|
|
96
|
-
|
|
129
|
+
if (fs.existsSync(targetDir)) {
|
|
130
|
+
console.log('\x1b[33mNotice: The "src" directory already exists. Merging new structure into it...\x1b[0m');
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (framework === 'vite') {
|
|
134
|
+
await cleanupViteFiles(targetDir);
|
|
97
135
|
}
|
|
98
136
|
|
|
99
137
|
await fs.copy(templateDir, targetDir, {
|
|
100
138
|
overwrite: options.force,
|
|
101
|
-
errorOnExist:
|
|
139
|
+
errorOnExist: false
|
|
102
140
|
});
|
|
103
141
|
|
|
104
|
-
|
|
142
|
+
if (framework === 'vite') {
|
|
143
|
+
await updateViteMainFile(targetDir);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
console.log(`\n\x1b[32m✔ Successfully injected ${structureType} structure for ${framework}!\x1b[0m`);
|
|
147
|
+
|
|
148
|
+
console.log('\n\x1b[36m--- Next Steps ---\x1b[0m');
|
|
149
|
+
console.log(`1. Run \x1b[33mnpm install\x1b[0m (if you haven't already)`);
|
|
150
|
+
if (framework === 'vite' && structureType === 'module') {
|
|
151
|
+
console.log(`2. Install routing: \x1b[33mnpm install react-router-dom\x1b[0m`);
|
|
152
|
+
}
|
|
153
|
+
console.log(`3. Start developing in \x1b[33msrc/\x1b[0m`);
|
|
154
|
+
console.log('\n\x1b[35mHappy coding with ASTROD! 🚀\x1b[0m\n');
|
|
105
155
|
|
|
106
156
|
} catch (error) {
|
|
107
157
|
console.error('\x1b[31mAn error occurred:\x1b[0m', error.message);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "astrod-cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"description": "A CLI tool that injects folder structures into existing Vite, Next, and React Native projects.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./bin/cli.js",
|
|
@@ -25,7 +25,6 @@
|
|
|
25
25
|
"author": "",
|
|
26
26
|
"license": "ISC",
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"astrod-cli": "^1.0.0",
|
|
29
28
|
"commander": "^11.1.0",
|
|
30
29
|
"fs-extra": "^11.2.0",
|
|
31
30
|
"inquirer": "^9.2.12",
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Metadata } from "next";
|
|
2
|
+
import { Inter } from "next/font/google";
|
|
3
|
+
import "../styles/globals.css";
|
|
4
|
+
|
|
5
|
+
const inter = Inter({ subsets: ["latin"] });
|
|
6
|
+
|
|
7
|
+
export const metadata: Metadata = {
|
|
8
|
+
title: "ASTROD Next App",
|
|
9
|
+
description: "Built with ASTROD CLI",
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export default function RootLayout({
|
|
13
|
+
children,
|
|
14
|
+
}: Readonly<{
|
|
15
|
+
children: React.ReactNode;
|
|
16
|
+
}>) {
|
|
17
|
+
return (
|
|
18
|
+
<html lang="en">
|
|
19
|
+
<body className={inter.className}>{children}</body>
|
|
20
|
+
</html>
|
|
21
|
+
);
|
|
22
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
export default function Home() {
|
|
4
|
+
return (
|
|
5
|
+
<main className="flex min-h-screen flex-col items-center justify-between p-24">
|
|
6
|
+
<div className="z-10 w-full max-w-5xl items-center justify-between font-mono text-sm lg:flex">
|
|
7
|
+
<h1 className="text-4xl font-bold">Welcome to ASTROD Next.js Structure!</h1>
|
|
8
|
+
<p className="mt-4">Edit src/app/page.tsx to get started.</p>
|
|
9
|
+
</div>
|
|
10
|
+
</main>
|
|
11
|
+
);
|
|
12
|
+
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { SafeAreaView, StyleSheet, Text, View } from 'react-native';
|
|
3
|
+
import { AppNavigator } from '../shared/navigation/AppNavigator';
|
|
4
|
+
|
|
5
|
+
const App = () => {
|
|
6
|
+
return (
|
|
7
|
+
<SafeAreaView style={styles.container}>
|
|
8
|
+
<AppNavigator />
|
|
9
|
+
</SafeAreaView>
|
|
10
|
+
);
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const styles = StyleSheet.create({
|
|
14
|
+
container: {
|
|
15
|
+
flex: 1,
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
export default App;
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { RouterProvider } from 'react-router-dom';
|
|
3
|
+
import { router } from './router';
|
|
4
|
+
import './styles/global.css';
|
|
5
|
+
|
|
6
|
+
const App: React.FC = () => {
|
|
7
|
+
return (
|
|
8
|
+
<React.StrictMode>
|
|
9
|
+
<RouterProvider router={router} />
|
|
10
|
+
</React.StrictMode>
|
|
11
|
+
);
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export default App;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { createBrowserRouter } from 'react-router-dom';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
|
|
4
|
+
// Example module routes
|
|
5
|
+
// import { authRoutes } from '../modules/auth/routes';
|
|
6
|
+
// import { dashboardRoutes } from '../modules/dashboard/routes';
|
|
7
|
+
|
|
8
|
+
export const router = createBrowserRouter([
|
|
9
|
+
{
|
|
10
|
+
path: '/',
|
|
11
|
+
element: <div>Welcome to ASTROD CLI! Start by editing src/app/App.tsx</div>,
|
|
12
|
+
},
|
|
13
|
+
// ...authRoutes,
|
|
14
|
+
// ...dashboardRoutes,
|
|
15
|
+
]);
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
4
|
+
variant?: 'primary' | 'secondary';
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export const Button: React.FC<ButtonProps> = ({ children, variant = 'primary', ...props }) => {
|
|
8
|
+
const styles: React.CSSProperties = {
|
|
9
|
+
padding: '0.6em 1.2em',
|
|
10
|
+
fontSize: '1em',
|
|
11
|
+
fontWeight: '500',
|
|
12
|
+
fontFamily: 'inherit',
|
|
13
|
+
backgroundColor: variant === 'primary' ? '#646cff' : '#1a1a1a',
|
|
14
|
+
color: '#ffffff',
|
|
15
|
+
cursor: 'pointer',
|
|
16
|
+
border: '1px solid transparent',
|
|
17
|
+
borderRadius: '8px',
|
|
18
|
+
transition: 'border-color 0.25s',
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
return (
|
|
22
|
+
<button style={styles} {...props}>
|
|
23
|
+
{children}
|
|
24
|
+
</button>
|
|
25
|
+
);
|
|
26
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
|
|
3
|
+
line-height: 1.5;
|
|
4
|
+
font-weight: 400;
|
|
5
|
+
|
|
6
|
+
color-scheme: light dark;
|
|
7
|
+
color: rgba(255, 255, 255, 0.87);
|
|
8
|
+
background-color: #242424;
|
|
9
|
+
|
|
10
|
+
font-synthesis: none;
|
|
11
|
+
text-rendering: optimizeLegibility;
|
|
12
|
+
-webkit-font-smoothing: antialiased;
|
|
13
|
+
-moz-osx-font-smoothing: grayscale;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
body {
|
|
17
|
+
margin: 0;
|
|
18
|
+
display: flex;
|
|
19
|
+
place-items: center;
|
|
20
|
+
min-width: 320px;
|
|
21
|
+
min-height: 100vh;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
#root {
|
|
25
|
+
max-width: 1280px;
|
|
26
|
+
margin: 0 auto;
|
|
27
|
+
padding: 2rem;
|
|
28
|
+
text-align: center;
|
|
29
|
+
}
|
|
File without changes
|