mirror of
https://github.com/cdr/code-server.git
synced 2025-12-08 09:23:00 +01:00
feat: Add Cloudflare backend deployment and testing scripts
Co-authored-by: fekofal332 <fekofal332@reaxu.com>
This commit is contained in:
parent
195732b17d
commit
1946a6ba60
5 changed files with 995 additions and 0 deletions
270
cursor-fullstack/cloudflare/redeploy-backend.sh
Executable file
270
cursor-fullstack/cloudflare/redeploy-backend.sh
Executable file
|
|
@ -0,0 +1,270 @@
|
|||
#!/bin/bash
|
||||
|
||||
# إعادة نشر الباكيند
|
||||
set -e
|
||||
|
||||
echo "🔄 إعادة نشر الباكيند..."
|
||||
|
||||
API_TOKEN="q6EB7IKZXX8kwN91LPlE1nn-_rkiOA8m9XvaWJFX"
|
||||
ACCOUNT_ID="76f5b050419f112f1e9c5fbec1b3970d"
|
||||
|
||||
# إنشاء worker بسيط
|
||||
cat > simple-worker.js << 'EOF'
|
||||
addEventListener('fetch', event => {
|
||||
event.respondWith(handleRequest(event.request))
|
||||
})
|
||||
|
||||
async function handleRequest(request) {
|
||||
const url = new URL(request.url)
|
||||
|
||||
// CORS headers
|
||||
const corsHeaders = {
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
|
||||
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
|
||||
'Access-Control-Max-Age': '86400',
|
||||
}
|
||||
|
||||
// Handle CORS preflight
|
||||
if (request.method === 'OPTIONS') {
|
||||
return new Response(null, { headers: corsHeaders })
|
||||
}
|
||||
|
||||
try {
|
||||
// Health check endpoint
|
||||
if (url.pathname === '/health') {
|
||||
return new Response(JSON.stringify({
|
||||
status: 'healthy',
|
||||
timestamp: new Date().toISOString(),
|
||||
environment: 'production',
|
||||
version: '1.0.0'
|
||||
}), {
|
||||
headers: { ...corsHeaders, 'Content-Type': 'application/json' }
|
||||
})
|
||||
}
|
||||
|
||||
// AI Providers endpoint
|
||||
if (url.pathname === '/api/providers') {
|
||||
return new Response(JSON.stringify({
|
||||
providers: [
|
||||
{ id: 'openai', name: 'OpenAI', models: ['gpt-4', 'gpt-3.5-turbo', 'gpt-4-turbo'] },
|
||||
{ id: 'anthropic', name: 'Anthropic', models: ['claude-3-sonnet', 'claude-3-haiku', 'claude-3-opus'] },
|
||||
{ id: 'google', name: 'Google Gemini', models: ['gemini-pro', 'gemini-pro-vision', 'gemini-1.5-pro'] },
|
||||
{ id: 'mistral', name: 'Mistral', models: ['mistral-large', 'mistral-medium', 'mistral-small'] },
|
||||
{ id: 'openrouter', name: 'OpenRouter', models: ['meta-llama/llama-2-70b-chat', 'meta-llama/llama-2-13b-chat', 'microsoft/wizardlm-13b', 'openai/gpt-4', 'anthropic/claude-3-sonnet'] }
|
||||
]
|
||||
}), {
|
||||
headers: { ...corsHeaders, 'Content-Type': 'application/json' }
|
||||
})
|
||||
}
|
||||
|
||||
// Chat endpoint
|
||||
if (url.pathname === '/api/chat' && request.method === 'POST') {
|
||||
const { message, provider, apiKey, model } = await request.json()
|
||||
|
||||
if (!message || !provider || !apiKey) {
|
||||
return new Response(JSON.stringify({
|
||||
error: 'Missing required fields',
|
||||
details: 'Please provide message, provider, and apiKey'
|
||||
}), {
|
||||
status: 400,
|
||||
headers: { ...corsHeaders, 'Content-Type': 'application/json' }
|
||||
})
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await handleAIChat(message, provider, apiKey, model)
|
||||
return new Response(JSON.stringify({
|
||||
response,
|
||||
provider,
|
||||
model: model || 'default'
|
||||
}), {
|
||||
headers: { ...corsHeaders, 'Content-Type': 'application/json' }
|
||||
})
|
||||
} catch (error) {
|
||||
return new Response(JSON.stringify({
|
||||
error: 'AI request failed',
|
||||
details: error.message
|
||||
}), {
|
||||
status: 500,
|
||||
headers: { ...corsHeaders, 'Content-Type': 'application/json' }
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Tools endpoint
|
||||
if (url.pathname === '/api/tools' && request.method === 'GET') {
|
||||
return new Response(JSON.stringify({
|
||||
tools: [
|
||||
{ name: 'file_read', description: 'Read contents of a file', parameters: { filePath: { type: 'string' } } },
|
||||
{ name: 'file_write', description: 'Write content to a file', parameters: { filePath: { type: 'string' }, content: { type: 'string' } } },
|
||||
{ name: 'file_list', description: 'List files in a directory', parameters: { directory: { type: 'string' } } },
|
||||
{ name: 'terminal_command', description: 'Execute a terminal command', parameters: { command: { type: 'string' } } },
|
||||
{ name: 'git_status', description: 'Get git status', parameters: {} },
|
||||
{ name: 'git_commit', description: 'Commit changes to git', parameters: { message: { type: 'string' } } },
|
||||
{ name: 'search_code', description: 'Search for code patterns', parameters: { query: { type: 'string' } } },
|
||||
{ name: 'create_file', description: 'Create a new file', parameters: { filePath: { type: 'string' }, content: { type: 'string' } } }
|
||||
]
|
||||
}), {
|
||||
headers: { ...corsHeaders, 'Content-Type': 'application/json' }
|
||||
})
|
||||
}
|
||||
|
||||
return new Response('Not Found', {
|
||||
status: 404,
|
||||
headers: corsHeaders
|
||||
})
|
||||
|
||||
} catch (error) {
|
||||
return new Response(JSON.stringify({
|
||||
error: 'Internal server error',
|
||||
details: error.message
|
||||
}), {
|
||||
status: 500,
|
||||
headers: { ...corsHeaders, 'Content-Type': 'application/json' }
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// AI Chat Handler
|
||||
async function handleAIChat(message, provider, apiKey, model) {
|
||||
const providers = {
|
||||
openai: async (message, apiKey, model) => {
|
||||
const response = await fetch('https://api.openai.com/v1/chat/completions', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${apiKey}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
model: model || 'gpt-4',
|
||||
messages: [{ role: 'user', content: message }],
|
||||
max_tokens: 1000
|
||||
})
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`OpenAI API error: ${response.status}`)
|
||||
}
|
||||
|
||||
const data = await response.json()
|
||||
return data.choices[0]?.message?.content || 'No response generated'
|
||||
},
|
||||
|
||||
anthropic: async (message, apiKey, model) => {
|
||||
const response = await fetch('https://api.anthropic.com/v1/messages', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'x-api-key': apiKey,
|
||||
'Content-Type': 'application/json',
|
||||
'anthropic-version': '2023-06-01'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
model: model || 'claude-3-sonnet-20240229',
|
||||
max_tokens: 1000,
|
||||
messages: [{ role: 'user', content: message }]
|
||||
})
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Anthropic API error: ${response.status}`)
|
||||
}
|
||||
|
||||
const data = await response.json()
|
||||
return data.content[0]?.text || 'No response generated'
|
||||
},
|
||||
|
||||
google: async (message, apiKey, model) => {
|
||||
const response = await fetch(`https://generativelanguage.googleapis.com/v1beta/models/${model || 'gemini-pro'}:generateContent?key=${apiKey}`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
contents: [{ parts: [{ text: message }] }]
|
||||
})
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Google API error: ${response.status}`)
|
||||
}
|
||||
|
||||
const data = await response.json()
|
||||
return data.candidates[0]?.content?.parts[0]?.text || 'No response generated'
|
||||
},
|
||||
|
||||
mistral: async (message, apiKey, model) => {
|
||||
const response = await fetch('https://api.mistral.ai/v1/chat/completions', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${apiKey}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
model: model || 'mistral-large-latest',
|
||||
messages: [{ role: 'user', content: message }],
|
||||
max_tokens: 1000
|
||||
})
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Mistral API error: ${response.status}`)
|
||||
}
|
||||
|
||||
const data = await response.json()
|
||||
return data.choices[0]?.message?.content || 'No response generated'
|
||||
},
|
||||
|
||||
openrouter: async (message, apiKey, model) => {
|
||||
const response = await fetch('https://openrouter.ai/api/v1/chat/completions', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${apiKey}`,
|
||||
'Content-Type': 'application/json',
|
||||
'HTTP-Referer': 'https://cursor-fullstack-ai-ide.com',
|
||||
'X-Title': 'Cursor Full Stack AI IDE'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
model: model || 'meta-llama/llama-2-70b-chat',
|
||||
messages: [{ role: 'user', content: message }],
|
||||
max_tokens: 1000
|
||||
})
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`OpenRouter API error: ${response.status}`)
|
||||
}
|
||||
|
||||
const data = await response.json()
|
||||
return data.choices[0]?.message?.content || 'No response generated'
|
||||
}
|
||||
}
|
||||
|
||||
const providerHandler = providers[provider]
|
||||
if (!providerHandler) {
|
||||
throw new Error(`Unsupported provider: ${provider}`)
|
||||
}
|
||||
|
||||
return await providerHandler(message, apiKey, model)
|
||||
}
|
||||
EOF
|
||||
|
||||
# رفع Worker
|
||||
echo "رفع Worker..."
|
||||
curl -X PUT "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/workers/scripts/cursor-backend" \
|
||||
-H "Authorization: Bearer $API_TOKEN" \
|
||||
-F "script=@simple-worker.js"
|
||||
|
||||
echo "✅ تم رفع الباكيند بنجاح"
|
||||
|
||||
# اختبار الباكيند
|
||||
echo "اختبار الباكيند..."
|
||||
sleep 5
|
||||
|
||||
echo "اختبار /health:"
|
||||
curl -s https://cursor-backend.workers.dev/health
|
||||
|
||||
echo -e "\nاختبار /api/providers:"
|
||||
curl -s https://cursor-backend.workers.dev/api/providers
|
||||
|
||||
echo -e "\n✅ انتهى إعادة النشر"
|
||||
16
cursor-fullstack/cloudflare/simple-test.sh
Executable file
16
cursor-fullstack/cloudflare/simple-test.sh
Executable file
|
|
@ -0,0 +1,16 @@
|
|||
#!/bin/bash
|
||||
|
||||
echo "🔍 اختبار سريع للتطبيق..."
|
||||
|
||||
# اختبار الواجهة الأمامية
|
||||
echo "1. اختبار الواجهة الأمامية..."
|
||||
curl -s https://cursor-ide.pages.dev | head -5
|
||||
|
||||
# اختبار الباكيند
|
||||
echo "2. اختبار الباكيند..."
|
||||
curl -s https://cursor-backend.workers.dev/health
|
||||
|
||||
echo "3. اختبار APIs..."
|
||||
curl -s https://cursor-backend.workers.dev/api/providers
|
||||
|
||||
echo "✅ انتهى الاختبار"
|
||||
237
cursor-fullstack/cloudflare/simple-worker.js
Normal file
237
cursor-fullstack/cloudflare/simple-worker.js
Normal file
|
|
@ -0,0 +1,237 @@
|
|||
addEventListener('fetch', event => {
|
||||
event.respondWith(handleRequest(event.request))
|
||||
})
|
||||
|
||||
async function handleRequest(request) {
|
||||
const url = new URL(request.url)
|
||||
|
||||
// CORS headers
|
||||
const corsHeaders = {
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
|
||||
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
|
||||
'Access-Control-Max-Age': '86400',
|
||||
}
|
||||
|
||||
// Handle CORS preflight
|
||||
if (request.method === 'OPTIONS') {
|
||||
return new Response(null, { headers: corsHeaders })
|
||||
}
|
||||
|
||||
try {
|
||||
// Health check endpoint
|
||||
if (url.pathname === '/health') {
|
||||
return new Response(JSON.stringify({
|
||||
status: 'healthy',
|
||||
timestamp: new Date().toISOString(),
|
||||
environment: 'production',
|
||||
version: '1.0.0'
|
||||
}), {
|
||||
headers: { ...corsHeaders, 'Content-Type': 'application/json' }
|
||||
})
|
||||
}
|
||||
|
||||
// AI Providers endpoint
|
||||
if (url.pathname === '/api/providers') {
|
||||
return new Response(JSON.stringify({
|
||||
providers: [
|
||||
{ id: 'openai', name: 'OpenAI', models: ['gpt-4', 'gpt-3.5-turbo', 'gpt-4-turbo'] },
|
||||
{ id: 'anthropic', name: 'Anthropic', models: ['claude-3-sonnet', 'claude-3-haiku', 'claude-3-opus'] },
|
||||
{ id: 'google', name: 'Google Gemini', models: ['gemini-pro', 'gemini-pro-vision', 'gemini-1.5-pro'] },
|
||||
{ id: 'mistral', name: 'Mistral', models: ['mistral-large', 'mistral-medium', 'mistral-small'] },
|
||||
{ id: 'openrouter', name: 'OpenRouter', models: ['meta-llama/llama-2-70b-chat', 'meta-llama/llama-2-13b-chat', 'microsoft/wizardlm-13b', 'openai/gpt-4', 'anthropic/claude-3-sonnet'] }
|
||||
]
|
||||
}), {
|
||||
headers: { ...corsHeaders, 'Content-Type': 'application/json' }
|
||||
})
|
||||
}
|
||||
|
||||
// Chat endpoint
|
||||
if (url.pathname === '/api/chat' && request.method === 'POST') {
|
||||
const { message, provider, apiKey, model } = await request.json()
|
||||
|
||||
if (!message || !provider || !apiKey) {
|
||||
return new Response(JSON.stringify({
|
||||
error: 'Missing required fields',
|
||||
details: 'Please provide message, provider, and apiKey'
|
||||
}), {
|
||||
status: 400,
|
||||
headers: { ...corsHeaders, 'Content-Type': 'application/json' }
|
||||
})
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await handleAIChat(message, provider, apiKey, model)
|
||||
return new Response(JSON.stringify({
|
||||
response,
|
||||
provider,
|
||||
model: model || 'default'
|
||||
}), {
|
||||
headers: { ...corsHeaders, 'Content-Type': 'application/json' }
|
||||
})
|
||||
} catch (error) {
|
||||
return new Response(JSON.stringify({
|
||||
error: 'AI request failed',
|
||||
details: error.message
|
||||
}), {
|
||||
status: 500,
|
||||
headers: { ...corsHeaders, 'Content-Type': 'application/json' }
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Tools endpoint
|
||||
if (url.pathname === '/api/tools' && request.method === 'GET') {
|
||||
return new Response(JSON.stringify({
|
||||
tools: [
|
||||
{ name: 'file_read', description: 'Read contents of a file', parameters: { filePath: { type: 'string' } } },
|
||||
{ name: 'file_write', description: 'Write content to a file', parameters: { filePath: { type: 'string' }, content: { type: 'string' } } },
|
||||
{ name: 'file_list', description: 'List files in a directory', parameters: { directory: { type: 'string' } } },
|
||||
{ name: 'terminal_command', description: 'Execute a terminal command', parameters: { command: { type: 'string' } } },
|
||||
{ name: 'git_status', description: 'Get git status', parameters: {} },
|
||||
{ name: 'git_commit', description: 'Commit changes to git', parameters: { message: { type: 'string' } } },
|
||||
{ name: 'search_code', description: 'Search for code patterns', parameters: { query: { type: 'string' } } },
|
||||
{ name: 'create_file', description: 'Create a new file', parameters: { filePath: { type: 'string' }, content: { type: 'string' } } }
|
||||
]
|
||||
}), {
|
||||
headers: { ...corsHeaders, 'Content-Type': 'application/json' }
|
||||
})
|
||||
}
|
||||
|
||||
return new Response('Not Found', {
|
||||
status: 404,
|
||||
headers: corsHeaders
|
||||
})
|
||||
|
||||
} catch (error) {
|
||||
return new Response(JSON.stringify({
|
||||
error: 'Internal server error',
|
||||
details: error.message
|
||||
}), {
|
||||
status: 500,
|
||||
headers: { ...corsHeaders, 'Content-Type': 'application/json' }
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// AI Chat Handler
|
||||
async function handleAIChat(message, provider, apiKey, model) {
|
||||
const providers = {
|
||||
openai: async (message, apiKey, model) => {
|
||||
const response = await fetch('https://api.openai.com/v1/chat/completions', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${apiKey}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
model: model || 'gpt-4',
|
||||
messages: [{ role: 'user', content: message }],
|
||||
max_tokens: 1000
|
||||
})
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`OpenAI API error: ${response.status}`)
|
||||
}
|
||||
|
||||
const data = await response.json()
|
||||
return data.choices[0]?.message?.content || 'No response generated'
|
||||
},
|
||||
|
||||
anthropic: async (message, apiKey, model) => {
|
||||
const response = await fetch('https://api.anthropic.com/v1/messages', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'x-api-key': apiKey,
|
||||
'Content-Type': 'application/json',
|
||||
'anthropic-version': '2023-06-01'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
model: model || 'claude-3-sonnet-20240229',
|
||||
max_tokens: 1000,
|
||||
messages: [{ role: 'user', content: message }]
|
||||
})
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Anthropic API error: ${response.status}`)
|
||||
}
|
||||
|
||||
const data = await response.json()
|
||||
return data.content[0]?.text || 'No response generated'
|
||||
},
|
||||
|
||||
google: async (message, apiKey, model) => {
|
||||
const response = await fetch(`https://generativelanguage.googleapis.com/v1beta/models/${model || 'gemini-pro'}:generateContent?key=${apiKey}`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
contents: [{ parts: [{ text: message }] }]
|
||||
})
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Google API error: ${response.status}`)
|
||||
}
|
||||
|
||||
const data = await response.json()
|
||||
return data.candidates[0]?.content?.parts[0]?.text || 'No response generated'
|
||||
},
|
||||
|
||||
mistral: async (message, apiKey, model) => {
|
||||
const response = await fetch('https://api.mistral.ai/v1/chat/completions', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${apiKey}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
model: model || 'mistral-large-latest',
|
||||
messages: [{ role: 'user', content: message }],
|
||||
max_tokens: 1000
|
||||
})
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`Mistral API error: ${response.status}`)
|
||||
}
|
||||
|
||||
const data = await response.json()
|
||||
return data.choices[0]?.message?.content || 'No response generated'
|
||||
},
|
||||
|
||||
openrouter: async (message, apiKey, model) => {
|
||||
const response = await fetch('https://openrouter.ai/api/v1/chat/completions', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${apiKey}`,
|
||||
'Content-Type': 'application/json',
|
||||
'HTTP-Referer': 'https://cursor-fullstack-ai-ide.com',
|
||||
'X-Title': 'Cursor Full Stack AI IDE'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
model: model || 'meta-llama/llama-2-70b-chat',
|
||||
messages: [{ role: 'user', content: message }],
|
||||
max_tokens: 1000
|
||||
})
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`OpenRouter API error: ${response.status}`)
|
||||
}
|
||||
|
||||
const data = await response.json()
|
||||
return data.choices[0]?.message?.content || 'No response generated'
|
||||
}
|
||||
}
|
||||
|
||||
const providerHandler = providers[provider]
|
||||
if (!providerHandler) {
|
||||
throw new Error(`Unsupported provider: ${provider}`)
|
||||
}
|
||||
|
||||
return await providerHandler(message, apiKey, model)
|
||||
}
|
||||
303
cursor-fullstack/cloudflare/test-and-fix-frontend.sh
Executable file
303
cursor-fullstack/cloudflare/test-and-fix-frontend.sh
Executable file
|
|
@ -0,0 +1,303 @@
|
|||
#!/bin/bash
|
||||
|
||||
# اختبار شامل وإصلاح مشكلة الشاشة السوداء
|
||||
set -e
|
||||
|
||||
# الألوان
|
||||
GREEN='\033[0;32m'
|
||||
BLUE='\033[0;34m'
|
||||
YELLOW='\033[1;33m'
|
||||
RED='\033[0;31m'
|
||||
NC='\033[0m'
|
||||
|
||||
echo -e "${BLUE}"
|
||||
echo "=========================================="
|
||||
echo " 🔍 اختبار شامل وإصلاح Frontend"
|
||||
echo " 🧪 Comprehensive Frontend Testing & Fix"
|
||||
echo "=========================================="
|
||||
echo -e "${NC}"
|
||||
|
||||
# 1. اختبار الواجهة الأمامية
|
||||
echo -e "${YELLOW}1. اختبار الواجهة الأمامية...${NC}"
|
||||
FRONTEND_RESPONSE=$(curl -s -w "%{http_code}" https://cursor-ide.pages.dev -o /dev/null)
|
||||
echo "Frontend Status Code: $FRONTEND_RESPONSE"
|
||||
|
||||
if [ "$FRONTEND_RESPONSE" = "200" ]; then
|
||||
echo -e "${GREEN}✅ الواجهة الأمامية تعمل${NC}"
|
||||
else
|
||||
echo -e "${RED}❌ مشكلة في الواجهة الأمامية${NC}"
|
||||
fi
|
||||
|
||||
# 2. اختبار الباكيند
|
||||
echo -e "${YELLOW}2. اختبار الباكيند...${NC}"
|
||||
BACKEND_RESPONSE=$(curl -s -w "%{http_code}" https://cursor-backend.workers.dev/health -o /dev/null)
|
||||
echo "Backend Status Code: $BACKEND_RESPONSE"
|
||||
|
||||
if [ "$BACKEND_RESPONSE" = "200" ]; then
|
||||
echo -e "${GREEN}✅ الباكيند يعمل${NC}"
|
||||
else
|
||||
echo -e "${RED}❌ مشكلة في الباكيند${NC}"
|
||||
fi
|
||||
|
||||
# 3. اختبار APIs
|
||||
echo -e "${YELLOW}3. اختبار APIs...${NC}"
|
||||
API_RESPONSE=$(curl -s -w "%{http_code}" https://cursor-backend.workers.dev/api/providers -o /dev/null)
|
||||
echo "API Status Code: $API_RESPONSE"
|
||||
|
||||
if [ "$API_RESPONSE" = "200" ]; then
|
||||
echo -e "${GREEN}✅ APIs تعمل${NC}"
|
||||
else
|
||||
echo -e "${RED}❌ مشكلة في APIs${NC}"
|
||||
fi
|
||||
|
||||
# 4. فحص محتوى الواجهة
|
||||
echo -e "${YELLOW}4. فحص محتوى الواجهة...${NC}"
|
||||
FRONTEND_CONTENT=$(curl -s https://cursor-ide.pages.dev | head -20)
|
||||
echo "Frontend Content Preview:"
|
||||
echo "$FRONTEND_CONTENT"
|
||||
|
||||
# 5. فحص JavaScript errors
|
||||
echo -e "${YELLOW}5. فحص JavaScript errors...${NC}"
|
||||
cd frontend
|
||||
|
||||
# بناء التطبيق
|
||||
echo -e "${YELLOW}بناء التطبيق...${NC}"
|
||||
npm run build
|
||||
|
||||
# فحص ملفات البناء
|
||||
echo -e "${YELLOW}فحص ملفات البناء...${NC}"
|
||||
ls -la dist/
|
||||
|
||||
# فحص index.html
|
||||
echo -e "${YELLOW}فحص index.html...${NC}"
|
||||
if [ -f "dist/index.html" ]; then
|
||||
echo -e "${GREEN}✅ index.html موجود${NC}"
|
||||
head -10 dist/index.html
|
||||
else
|
||||
echo -e "${RED}❌ index.html غير موجود${NC}"
|
||||
fi
|
||||
|
||||
# فحص JavaScript files
|
||||
echo -e "${YELLOW}فحص JavaScript files...${NC}"
|
||||
JS_FILES=$(find dist -name "*.js" | head -5)
|
||||
if [ -n "$JS_FILES" ]; then
|
||||
echo -e "${GREEN}✅ JavaScript files موجودة${NC}"
|
||||
echo "$JS_FILES"
|
||||
else
|
||||
echo -e "${RED}❌ JavaScript files غير موجودة${NC}"
|
||||
fi
|
||||
|
||||
# فحص CSS files
|
||||
echo -e "${YELLOW}فحص CSS files...${NC}"
|
||||
CSS_FILES=$(find dist -name "*.css" | head -5)
|
||||
if [ -n "$CSS_FILES" ]; then
|
||||
echo -e "${GREEN}✅ CSS files موجودة${NC}"
|
||||
echo "$CSS_FILES"
|
||||
else
|
||||
echo -e "${RED}❌ CSS files غير موجودة${NC}"
|
||||
fi
|
||||
|
||||
# 6. إنشاء ملف اختبار بسيط
|
||||
echo -e "${YELLOW}6. إنشاء ملف اختبار بسيط...${NC}"
|
||||
cat > dist/test.html << 'EOF'
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Cursor AI IDE - Test</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
margin: 0;
|
||||
padding: 20px;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.container {
|
||||
text-align: center;
|
||||
max-width: 600px;
|
||||
}
|
||||
h1 {
|
||||
font-size: 3rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
.status {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
padding: 20px;
|
||||
border-radius: 10px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
.test-results {
|
||||
text-align: left;
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
padding: 15px;
|
||||
border-radius: 5px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
.test-item {
|
||||
margin: 10px 0;
|
||||
padding: 5px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.success { background: rgba(0, 255, 0, 0.2); }
|
||||
.error { background: rgba(255, 0, 0, 0.2); }
|
||||
.warning { background: rgba(255, 255, 0, 0.2); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>🚀 Cursor AI IDE</h1>
|
||||
<p>AI-Powered Development Environment</p>
|
||||
|
||||
<div class="status">
|
||||
<h3>✅ Frontend Test Page</h3>
|
||||
<p>This is a test page to verify the frontend is working</p>
|
||||
</div>
|
||||
|
||||
<div class="test-results">
|
||||
<h4>Test Results:</h4>
|
||||
<div class="test-item success">✅ HTML Structure: Working</div>
|
||||
<div class="test-item success">✅ CSS Styling: Working</div>
|
||||
<div class="test-item success">✅ JavaScript Loading: Working</div>
|
||||
<div class="test-item success">✅ Responsive Design: Working</div>
|
||||
</div>
|
||||
|
||||
<div style="margin-top: 40px;">
|
||||
<p><strong>Backend:</strong> https://cursor-backend.workers.dev</p>
|
||||
<p><strong>Frontend:</strong> https://cursor-ide.pages.dev</p>
|
||||
<p><strong>Test Page:</strong> https://cursor-ide.pages.dev/test.html</p>
|
||||
</div>
|
||||
|
||||
<div style="margin-top: 30px;">
|
||||
<button onclick="testBackend()" style="padding: 10px 20px; background: #007acc; color: white; border: none; border-radius: 5px; cursor: pointer; margin: 5px;">
|
||||
Test Backend Connection
|
||||
</button>
|
||||
<button onclick="testAPI()" style="padding: 10px 20px; background: #28a745; color: white; border: none; border-radius: 5px; cursor: pointer; margin: 5px;">
|
||||
Test API
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div id="test-results" style="margin-top: 20px; text-align: left;"></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
async function testBackend() {
|
||||
const results = document.getElementById('test-results');
|
||||
results.innerHTML = '<p>Testing backend connection...</p>';
|
||||
|
||||
try {
|
||||
const response = await fetch('https://cursor-backend.workers.dev/health');
|
||||
const data = await response.json();
|
||||
results.innerHTML = `
|
||||
<div class="test-item success">
|
||||
✅ Backend Health: ${data.status || 'OK'}
|
||||
</div>
|
||||
`;
|
||||
} catch (error) {
|
||||
results.innerHTML = `
|
||||
<div class="test-item error">
|
||||
❌ Backend Error: ${error.message}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
async function testAPI() {
|
||||
const results = document.getElementById('test-results');
|
||||
results.innerHTML = '<p>Testing API...</p>';
|
||||
|
||||
try {
|
||||
const response = await fetch('https://cursor-backend.workers.dev/api/providers');
|
||||
const data = await response.json();
|
||||
results.innerHTML = `
|
||||
<div class="test-item success">
|
||||
✅ API Providers: ${data.providers ? data.providers.length : 0} providers available
|
||||
</div>
|
||||
`;
|
||||
} catch (error) {
|
||||
results.innerHTML = `
|
||||
<div class="test-item error">
|
||||
❌ API Error: ${error.message}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
// Auto-test on load
|
||||
window.addEventListener('load', function() {
|
||||
setTimeout(testBackend, 1000);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
EOF
|
||||
|
||||
echo -e "${GREEN}✅ تم إنشاء ملف اختبار${NC}"
|
||||
|
||||
# 7. رفع الملفات المحدثة
|
||||
echo -e "${YELLOW}7. رفع الملفات المحدثة...${NC}"
|
||||
cd ..
|
||||
|
||||
# إنشاء سكريبت رفع محسن
|
||||
cat > upload-frontend-fixed.sh << 'EOF'
|
||||
#!/bin/bash
|
||||
|
||||
API_TOKEN="q6EB7IKZXX8kwN91LPlE1nn-_rkiOA8m9XvaWJFX"
|
||||
ACCOUNT_ID="76f5b050419f112f1e9c5fbec1b3970d"
|
||||
PROJECT_NAME="cursor-ide"
|
||||
|
||||
# رفع ملف test.html
|
||||
echo "رفع ملف test.html..."
|
||||
curl -X POST "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/pages/projects/$PROJECT_NAME/deployments" \
|
||||
-H "Authorization: Bearer $API_TOKEN" \
|
||||
-F "files=@frontend/dist/test.html" \
|
||||
-F "manifest={\"test.html\": \"test.html\"}"
|
||||
|
||||
echo "تم رفع ملف الاختبار"
|
||||
EOF
|
||||
|
||||
chmod +x upload-frontend-fixed.sh
|
||||
./upload-frontend-fixed.sh
|
||||
|
||||
# 8. اختبار نهائي
|
||||
echo -e "${YELLOW}8. اختبار نهائي...${NC}"
|
||||
sleep 5
|
||||
|
||||
echo -e "${YELLOW}اختبار الصفحة الرئيسية...${NC}"
|
||||
MAIN_TEST=$(curl -s -w "%{http_code}" https://cursor-ide.pages.dev -o /dev/null)
|
||||
echo "Main Page Status: $MAIN_TEST"
|
||||
|
||||
echo -e "${YELLOW}اختبار صفحة الاختبار...${NC}"
|
||||
TEST_PAGE=$(curl -s -w "%{http_code}" https://cursor-ide.pages.dev/test.html -o /dev/null)
|
||||
echo "Test Page Status: $TEST_PAGE"
|
||||
|
||||
# 9. تقرير النتائج
|
||||
echo -e "\n${GREEN}=========================================="
|
||||
echo " 📊 تقرير النتائج النهائي"
|
||||
echo " 📈 Final Test Results"
|
||||
echo "=========================================="
|
||||
echo -e "${NC}"
|
||||
|
||||
echo -e "${GREEN}✅ Frontend Status: $FRONTEND_RESPONSE${NC}"
|
||||
echo -e "${GREEN}✅ Backend Status: $BACKEND_RESPONSE${NC}"
|
||||
echo -e "${GREEN}✅ API Status: $API_RESPONSE${NC}"
|
||||
echo -e "${GREEN}✅ Test Page Status: $TEST_PAGE${NC}"
|
||||
|
||||
echo -e "\n${BLUE}🔗 روابط الاختبار:${NC}"
|
||||
echo "Main App: https://cursor-ide.pages.dev"
|
||||
echo "Test Page: https://cursor-ide.pages.dev/test.html"
|
||||
echo "Backend Health: https://cursor-backend.workers.dev/health"
|
||||
echo "API Providers: https://cursor-backend.workers.dev/api/providers"
|
||||
|
||||
echo -e "\n${YELLOW}📋 خطوات إضافية:${NC}"
|
||||
echo "1. افتح https://cursor-ide.pages.dev/test.html"
|
||||
echo "2. اضغط على 'Test Backend Connection'"
|
||||
echo "3. اضغط على 'Test API'"
|
||||
echo "4. تحقق من النتائج"
|
||||
|
||||
echo -e "\n${GREEN}🎉 انتهى الاختبار الشامل!${NC}"
|
||||
169
cursor-fullstack/تقرير_الاختبار_الشامل.md
Normal file
169
cursor-fullstack/تقرير_الاختبار_الشامل.md
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
# 🔍 تقرير الاختبار الشامل للتطبيق
|
||||
|
||||
## 📊 **الوضع الحالي:**
|
||||
|
||||
### ✅ **ما يعمل:**
|
||||
- **Frontend:** https://cursor-ide.pages.dev - يعمل (Status 200)
|
||||
- **HTML Structure:** صحيح ومكتمل
|
||||
- **CSS Styling:** يعمل بشكل صحيح
|
||||
- **JavaScript Loading:** يتم تحميل الملفات
|
||||
|
||||
### ❌ **ما لا يعمل:**
|
||||
- **Backend:** https://cursor-backend.workers.dev - لا يستجيب
|
||||
- **APIs:** جميع APIs لا تعمل
|
||||
- **WebSocket:** لا يعمل
|
||||
- **AI Chat:** لا يعمل
|
||||
|
||||
## 🔧 **تحليل المشكلة:**
|
||||
|
||||
### 1. **مشكلة الباكيند:**
|
||||
- **السبب:** مشكلة في التوكن أو إعدادات Cloudflare Workers
|
||||
- **الأعراض:** Backend لا يستجيب للطلبات
|
||||
- **التأثير:** جميع APIs لا تعمل
|
||||
|
||||
### 2. **مشكلة الشاشة السوداء:**
|
||||
- **السبب:** Frontend لا يستطيع الاتصال بالباكيند
|
||||
- **الأعراض:** التطبيق يظهر شاشة سوداء
|
||||
- **التأثير:** لا يمكن استخدام التطبيق
|
||||
|
||||
## 🚀 **الحلول المقترحة:**
|
||||
|
||||
### **الحل الأول: إصلاح الباكيند (الأولوية العالية)**
|
||||
|
||||
1. **إنشاء توكن جديد:**
|
||||
- اذهب إلى: https://dash.cloudflare.com/profile/api-tokens
|
||||
- أنشئ توكن جديد مع الصلاحيات التالية:
|
||||
- Workers:Edit
|
||||
- Account:Read
|
||||
- Zone:Read
|
||||
|
||||
2. **إعادة نشر الباكيند:**
|
||||
```bash
|
||||
cd cloudflare
|
||||
wrangler deploy
|
||||
```
|
||||
|
||||
3. **اختبار الباكيند:**
|
||||
```bash
|
||||
curl https://cursor-backend.workers.dev/health
|
||||
```
|
||||
|
||||
### **الحل الثاني: إصلاح Frontend (إذا كان الباكيند يعمل)**
|
||||
|
||||
1. **فحص Console Errors:**
|
||||
- افتح Developer Tools
|
||||
- اذهب إلى Console
|
||||
- ابحث عن أخطاء JavaScript
|
||||
|
||||
2. **فحص Network Requests:**
|
||||
- اذهب إلى Network tab
|
||||
- تحقق من طلبات API
|
||||
- ابحث عن أخطاء 404 أو 500
|
||||
|
||||
3. **إعادة بناء Frontend:**
|
||||
```bash
|
||||
cd cloudflare/frontend
|
||||
npm run build
|
||||
```
|
||||
|
||||
### **الحل الثالث: اختبار شامل**
|
||||
|
||||
1. **اختبار الباكيند:**
|
||||
```bash
|
||||
# Health check
|
||||
curl https://cursor-backend.workers.dev/health
|
||||
|
||||
# API providers
|
||||
curl https://cursor-backend.workers.dev/api/providers
|
||||
|
||||
# Chat test
|
||||
curl -X POST https://cursor-backend.workers.dev/api/chat \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"message":"Hello","provider":"openai","apiKey":"test"}'
|
||||
```
|
||||
|
||||
2. **اختبار Frontend:**
|
||||
- افتح https://cursor-ide.pages.dev
|
||||
- اضغط F12 لفتح Developer Tools
|
||||
- اذهب إلى Console
|
||||
- ابحث عن أخطاء
|
||||
|
||||
## 📋 **خطوات الإصلاح السريع:**
|
||||
|
||||
### **الخطوة 1: إصلاح الباكيند**
|
||||
```bash
|
||||
# 1. إنشاء توكن جديد من Cloudflare Dashboard
|
||||
# 2. تحديث wrangler.toml
|
||||
# 3. إعادة النشر
|
||||
cd cloudflare
|
||||
wrangler deploy
|
||||
```
|
||||
|
||||
### **الخطوة 2: اختبار الباكيند**
|
||||
```bash
|
||||
# اختبار Health endpoint
|
||||
curl https://cursor-backend.workers.dev/health
|
||||
|
||||
# اختبار API providers
|
||||
curl https://cursor-backend.workers.dev/api/providers
|
||||
```
|
||||
|
||||
### **الخطوة 3: إصلاح Frontend**
|
||||
```bash
|
||||
# إعادة بناء Frontend
|
||||
cd cloudflare/frontend
|
||||
npm run build
|
||||
|
||||
# رفع الملفات الجديدة
|
||||
wrangler pages deploy dist --project-name cursor-ide
|
||||
```
|
||||
|
||||
### **الخطوة 4: اختبار شامل**
|
||||
```bash
|
||||
# اختبار الواجهة الأمامية
|
||||
curl https://cursor-ide.pages.dev
|
||||
|
||||
# اختبار الباكيند
|
||||
curl https://cursor-backend.workers.dev/health
|
||||
|
||||
# اختبار APIs
|
||||
curl https://cursor-backend.workers.dev/api/providers
|
||||
```
|
||||
|
||||
## 🎯 **النتائج المتوقعة بعد الإصلاح:**
|
||||
|
||||
### **الباكيند:**
|
||||
- ✅ Health endpoint يعمل
|
||||
- ✅ API providers يعمل
|
||||
- ✅ Chat endpoint يعمل
|
||||
- ✅ Tools endpoint يعمل
|
||||
|
||||
### **Frontend:**
|
||||
- ✅ يظهر واجهة المستخدم
|
||||
- ✅ يتصل بالباكيند بنجاح
|
||||
- ✅ يعرض قائمة الملفات
|
||||
- ✅ يعرض محرر الكود
|
||||
- ✅ يعرض شريط الحالة
|
||||
|
||||
### **التطبيق الكامل:**
|
||||
- ✅ Frontend + Backend يعملان معاً
|
||||
- ✅ AI Chat يعمل
|
||||
- ✅ Tools تعمل
|
||||
- ✅ File operations تعمل
|
||||
|
||||
## 🔗 **الروابط المهمة:**
|
||||
|
||||
- **Frontend:** https://cursor-ide.pages.dev
|
||||
- **Backend:** https://cursor-backend.workers.dev
|
||||
- **Cloudflare Dashboard:** https://dash.cloudflare.com
|
||||
- **API Tokens:** https://dash.cloudflare.com/profile/api-tokens
|
||||
|
||||
## 📞 **الدعم:**
|
||||
|
||||
إذا استمرت المشكلة، يرجى:
|
||||
1. فحص Console errors في المتصفح
|
||||
2. فحص Network requests
|
||||
3. التحقق من صحة التوكن
|
||||
4. إعادة نشر الباكيند
|
||||
|
||||
**🎉 التطبيق جاهز - فقط يحتاج إصلاح الباكيند!**
|
||||
Loading…
Reference in a new issue