-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.js
More file actions
156 lines (136 loc) · 3.66 KB
/
Copy pathindex.js
File metadata and controls
156 lines (136 loc) · 3.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#!/usr/bin/env bun
// package.json'da "type": "module" olmalı
// Gerekli paketler:
// bun add @google/genai mime prompts chalk dotenv
// bun add -D @types/node
import fs from "fs";
import path from "path";
import prompts from "prompts";
import chalk from "chalk";
import * as dotenv from "dotenv";
import { GoogleGenAI } from "@google/genai";
// Ortam değişkenlerini yükle
dotenv.config();
async function loadLogo() {
try {
const logoPath = path.resolve(process.cwd(), "logo.txt");
const ascii = fs.readFileSync(logoPath, "utf8");
console.log(chalk.hex("#f05123")(ascii));
} catch {
console.log(chalk.red("Logo yüklenemedi."));
}
}
async function getApiKey() {
if (!process.env.GEMINI_API_KEY) {
const { apiKey } = await prompts({
type: "password",
name: "apiKey",
message: "Gemini API anahtarınızı girin:",
});
if (!apiKey) {
console.error(chalk.red("API anahtarı gerekli!"));
process.exit(1);
}
fs.appendFileSync(".env", `\nGEMINI_API_KEY=${apiKey}`);
process.env.GEMINI_API_KEY = apiKey;
console.log(chalk.green("API anahtarı kaydedildi."));
}
}
async function askQuestions() {
const answers = await prompts([
{
type: "text",
name: "componentName",
message: "Ne componenti istiyorsunuz?",
},
{
type: "text",
name: "examplePath",
message: "Projede örnek bir component dosyası yolu:",
},
{
type: "text",
name: "targetFolder",
message: "Component hangi klasöre kaydedilsin?",
initial: "src/components",
},
{
type: "toggle",
name: "useHooks",
message: "React hook kullanılsın mı?",
initial: true,
active: "Evet",
inactive: "Hayır",
},
]);
return answers;
}
async function generateComponent(promptText) {
const ai = new GoogleGenAI({
apiKey: process.env.GEMINI_API_KEY,
});
const config = {
thinkingConfig: {
thinkingBudget: -1,
},
systemInstruction: [
{
text: "Sen bir profesyonel React component generator'sun. Kullanıcının verdiği bilgiler doğrultusunda TypeScript/React component üret.",
},
],
};
const model = "gemini-2.5-pro";
const contents = [
{
role: "user",
parts: [
{
text: promptText,
},
],
},
];
const response = await ai.models.generateContentStream({
model,
config,
contents,
});
let output = "";
for await (const chunk of response) {
process.stdout.write(chunk.text || "");
output += chunk.text || "";
}
return output;
}
async function main() {
await loadLogo();
await getApiKey();
const { componentName, examplePath, targetFolder, useHooks } =
await askQuestions();
let exampleCode = "";
try {
exampleCode = fs.readFileSync(examplePath, "utf8");
} catch {
console.warn(chalk.yellow("Örnek component okunamadı, boş geçiliyor."));
}
const promptText = `
React TypeScript ile "${componentName}" isimli bir component üret.
Component yapısı şu örneğe benzesin:
${exampleCode}
Kayıt klasörü: ${targetFolder}
Hook kullanımı: ${useHooks ? "Evet" : "Hayır"}
Kodun tam ve çalışır olsun.
`;
console.log(chalk.blue("\nGemini AI ile component üretiliyor...\n"));
const code = await generateComponent(promptText);
const fileName = `${componentName
.replace(/\s+/g, "")
.replace(/[^a-zA-Z0-9]/g, "")}.tsx`;
const filePath = path.join(targetFolder, fileName);
fs.mkdirSync(targetFolder, { recursive: true });
fs.writeFileSync(filePath, code);
console.log(chalk.green(`\n✅ Component kaydedildi: ${filePath}`));
}
main().catch((err) => {
console.error(chalk.red(err));
});