tambahan
This commit is contained in:
160
bin/src/app-create.ts
Normal file
160
bin/src/app-create.ts
Normal file
@@ -0,0 +1,160 @@
|
||||
import ora from "ora"
|
||||
|
||||
const appRoutesTemplate = `
|
||||
import { BrowserRouter, Routes, Route } from "react-router-dom";
|
||||
import Home from "./pages/Home";
|
||||
import NotFound from "./pages/NotFound";
|
||||
|
||||
export default function AppRoutes() {
|
||||
return (
|
||||
<BrowserRouter>
|
||||
<Routes>
|
||||
<Route path="/" element={<Home />} />
|
||||
<Route path="*" element={<NotFound />} />
|
||||
</Routes>
|
||||
</BrowserRouter>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
`
|
||||
|
||||
const postCssTemplate = `
|
||||
module.exports = {
|
||||
plugins: {
|
||||
'postcss-preset-mantine': {},
|
||||
'postcss-simple-vars': {
|
||||
variables: {
|
||||
'mantine-breakpoint-xs': '36em',
|
||||
'mantine-breakpoint-sm': '48em',
|
||||
'mantine-breakpoint-md': '62em',
|
||||
'mantine-breakpoint-lg': '75em',
|
||||
'mantine-breakpoint-xl': '88em',
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
`
|
||||
|
||||
const appTemplate = `
|
||||
import '@mantine/core/styles.css';
|
||||
|
||||
import { MantineProvider } from '@mantine/core';
|
||||
import AppRoutes from './AppRoutes';
|
||||
|
||||
export function App() {
|
||||
return <MantineProvider>
|
||||
<AppRoutes />
|
||||
</MantineProvider>;
|
||||
}
|
||||
`
|
||||
|
||||
const homeTemplate = `
|
||||
export default function Home() {
|
||||
return (
|
||||
<div>
|
||||
<h1>Home</h1>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
`
|
||||
|
||||
const serverTemplate = `
|
||||
import Elysia from "elysia";
|
||||
import Swagger from "@elysiajs/swagger";
|
||||
import html from "./index.html"
|
||||
|
||||
const Docs = new Elysia({})
|
||||
.use(Swagger({
|
||||
path: "/docs",
|
||||
}))
|
||||
|
||||
|
||||
const Api = new Elysia({
|
||||
prefix: "/api",
|
||||
})
|
||||
.use(Docs)
|
||||
.post("/hello", () => "Hello, world!")
|
||||
|
||||
|
||||
const app = new Elysia()
|
||||
.use(Api)
|
||||
.get("/*", html)
|
||||
.listen(3000, () => {
|
||||
console.log("Server running at http://localhost:3000");
|
||||
});
|
||||
|
||||
|
||||
export type Server = typeof app;
|
||||
`
|
||||
|
||||
const notFoundTemplate = `
|
||||
export default function NotFound() {
|
||||
return (
|
||||
<div>
|
||||
<h1>404 Not Found</h1>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
`
|
||||
|
||||
|
||||
|
||||
const cmd = (appName: string) => `
|
||||
bun init --react ${appName}
|
||||
echo "init react"
|
||||
cd ${appName}
|
||||
echo "cd ${appName}"
|
||||
bun add react-router-dom
|
||||
echo "add react-router-dom"
|
||||
bun add @mantine/core @mantine/hooks
|
||||
echo "add @mantine/core @mantine/hooks"
|
||||
bun add --dev postcss postcss-preset-mantine postcss-simple-vars
|
||||
echo "add --dev postcss postcss-preset-mantine postcss-simple-vars"
|
||||
bun add elysia @elysiajs/cors @elysiajs/swagger @elysiajs/eden
|
||||
echo "add elysia @elysiajs/cors @elysiajs/swagger @elysiajs/eden"
|
||||
cat <<EOF > postcss.config.js
|
||||
${postCssTemplate}
|
||||
EOF
|
||||
echo "postcss.config.js"
|
||||
cat <<EOF > src/App.tsx
|
||||
${appTemplate}
|
||||
EOF
|
||||
echo "src/App.tsx"
|
||||
|
||||
cat <<EOF > src/AppRoutes.tsx
|
||||
${appRoutesTemplate}
|
||||
EOF
|
||||
echo "src/AppRoutes.tsx"
|
||||
|
||||
mkdir src/pages
|
||||
echo "mkdir src/pages"
|
||||
cat <<EOF > src/pages/Home.tsx
|
||||
${homeTemplate}
|
||||
EOF
|
||||
echo "src/pages/Home.tsx"
|
||||
|
||||
cat <<EOF > src/index.tsx
|
||||
${serverTemplate}
|
||||
EOF
|
||||
echo "src/index.tsx"
|
||||
|
||||
cat <<EOF > src/pages/NotFound.tsx
|
||||
${notFoundTemplate}
|
||||
EOF
|
||||
echo "src/pages/NotFound.tsx"
|
||||
|
||||
rm src/APITester.tsx
|
||||
|
||||
ls
|
||||
|
||||
echo "✅ done"
|
||||
`
|
||||
|
||||
|
||||
export default async function appCreate({ appName }: { appName: string }) {
|
||||
const spinner = ora(`Creating app ${appName}...`).start();
|
||||
const { stdout } = Bun.spawnSync(["bash", "-c", cmd(appName)]);
|
||||
spinner.stop();
|
||||
console.log(stdout.toString());
|
||||
}
|
||||
41
bin/src/code.ts
Normal file
41
bin/src/code.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import path from "path";
|
||||
import ora from "ora";
|
||||
|
||||
async function query({ question }: { question: string }) {
|
||||
const spinner = ora("Processing...").start();
|
||||
const response = await fetch(
|
||||
"https://cloud-aiflow.wibudev.com/api/v1/prediction/4da85628-c638-43d3-9491-4cd0a7e6b1b8",
|
||||
{
|
||||
headers: {
|
||||
Authorization: "Bearer v3WdPjn61bNDsEYCO5_LYPRs16ICKjpQE6lF60DjpNo",
|
||||
"Content-Type": "application/json"
|
||||
},
|
||||
method: "POST",
|
||||
body: JSON.stringify({ question })
|
||||
}
|
||||
);
|
||||
const result: { text: string } = await response.json() as { text: string };
|
||||
spinner.stop();
|
||||
return result.text;
|
||||
}
|
||||
|
||||
|
||||
async function code({ sourcePath }: { sourcePath: string }) {
|
||||
const file = Bun.file(sourcePath);
|
||||
const content = await file.text();
|
||||
const result = await query({
|
||||
question: content
|
||||
});
|
||||
|
||||
const output = `${path.dirname(sourcePath)}/${path.basename(sourcePath, path.extname(sourcePath))}.md`;
|
||||
|
||||
Bun.write(output, result);
|
||||
console.log(`✅ Code generated at ${output}`);
|
||||
|
||||
}
|
||||
|
||||
if (import.meta.main) {
|
||||
code({ sourcePath: "bin/g3n.ts" });
|
||||
}
|
||||
|
||||
export default code;
|
||||
@@ -3,7 +3,7 @@ import { promises as fs } from "fs";
|
||||
import * as os from "os";
|
||||
import * as path from "path";
|
||||
|
||||
const CONFIG_FILE = path.join(os.homedir(), ".frpdev.conf");
|
||||
const CONFIG_FILE = path.join(os.homedir(), ".g3n.conf");
|
||||
|
||||
interface FrpConfig {
|
||||
FRP_HOST: string;
|
||||
|
||||
48
bin/src/generate/env.generate.ts
Normal file
48
bin/src/generate/env.generate.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import * as fs from "fs";
|
||||
import * as path from "path";
|
||||
import * as dotenv from "dotenv";
|
||||
|
||||
interface GenerateEnvTypesOptions {
|
||||
envFilePath?: string;
|
||||
outputDir?: string;
|
||||
outputFileName?: string;
|
||||
}
|
||||
|
||||
export function generateEnvTypes(options: GenerateEnvTypesOptions = {}) {
|
||||
const {
|
||||
envFilePath = path.resolve(process.cwd(), ".env"),
|
||||
outputDir = path.resolve(process.cwd(), "types"),
|
||||
outputFileName = "env.d.ts",
|
||||
} = options;
|
||||
|
||||
const outputFile = path.join(outputDir, outputFileName);
|
||||
|
||||
// 1. Baca .env
|
||||
if (!fs.existsSync(envFilePath)) {
|
||||
console.warn(`⚠️ .env file not found at: ${envFilePath}`);
|
||||
return;
|
||||
}
|
||||
|
||||
const envContent = fs.readFileSync(envFilePath, "utf-8");
|
||||
const parsed = dotenv.parse(envContent);
|
||||
|
||||
// 2. Generate TypeScript declare
|
||||
const lines = Object.keys(parsed).map((key) => ` ${key}?: string;`);
|
||||
|
||||
const fileContent = `declare namespace NodeJS {
|
||||
interface ProcessEnv {
|
||||
${lines.join("\n")}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
// 3. Buat folder kalau belum ada
|
||||
if (!fs.existsSync(outputDir)) {
|
||||
fs.mkdirSync(outputDir, { recursive: true });
|
||||
}
|
||||
|
||||
// 4. Tulis file
|
||||
fs.writeFileSync(outputFile, fileContent, "utf-8");
|
||||
|
||||
console.log(`✅ Env types generated at: ${outputFile}`);
|
||||
}
|
||||
Reference in New Issue
Block a user