Skip to content
This repository was archived by the owner on Jan 13, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
351 changes: 341 additions & 10 deletions packages/editor/package-lock.json

Large diffs are not rendered by default.

6 changes: 4 additions & 2 deletions packages/editor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,15 @@
"lint": "next lint"
},
"dependencies": {
"@anthropic-ai/sdk": "^0.17.1",
"@dnd-kit/core": "^6.1.0",
"@dnd-kit/sortable": "^8.0.0",
"@dnd-kit/utilities": "^3.2.2",
"@google/generative-ai": "^0.2.1",
"@radix-ui/react-accordion": "^1.2.1",
"@radix-ui/react-checkbox": "^1.1.2",
"@radix-ui/react-collapsible": "^1.1.1",
"@radix-ui/react-context-menu": "^2.2.3",
"@radix-ui/react-dialog": "^1.1.2",
"@radix-ui/react-dropdown-menu": "^2.1.2",
"@radix-ui/react-label": "^2.1.0",
Expand All @@ -34,11 +37,10 @@
"next": "15.0.3",
"next-themes": "^0.4.3",
"openai": "^4.73.1",
"@anthropic-ai/sdk": "^0.17.1",
"@google/generative-ai": "^0.2.1",
"react": "^18.3.1",
"react-dom": "^18.2.0",
"react-error-boundary": "^4.1.2",
"react-resizable-panels": "^2.1.7",
"react-syntax-highlighter": "^15.6.1",
"sonner": "^1.7.0",
"tailwind-merge": "^2.5.4",
Expand Down
121 changes: 62 additions & 59 deletions packages/editor/src/app/api/files/route.ts
Original file line number Diff line number Diff line change
@@ -1,122 +1,125 @@
import { writeFile, mkdir, rm, unlink, readFile } from 'fs/promises'
import { NextResponse } from 'next/server'
import path from 'path'
import { writeFile, mkdir, rm, unlink, readFile } from "fs/promises";
import { NextResponse } from "next/server";
import path from "path";

function getBasePath() {
return path.join(process.cwd(), '..', 'compiled')
return path.join(process.cwd(), "..", "compiled");
}

export async function POST(request: Request) {
try {
const { path: filePath, content } = await request.json()
const fullPath = path.join(getBasePath(), filePath)
const { path: filePath, content, isDirectory } = await request.json();
const fullPath = path.join(getBasePath(), filePath);

// Ensure the directory exists
await mkdir(path.dirname(fullPath), { recursive: true })

// Write the file
await writeFile(fullPath, JSON.stringify(content, null, 2))
return NextResponse.json({ success: true })
await mkdir(path.dirname(fullPath), { recursive: true });

if (isDirectory) {
// If it's a directory, just create it
await mkdir(fullPath, { recursive: true });
} else {
// If it's a file, write the content
await writeFile(fullPath, JSON.stringify(content, null, 2));
}

return NextResponse.json({ success: true });
} catch (error) {
console.error('Error creating file:', error)
console.error("Error creating file:", error);
return NextResponse.json(
{ error: 'Failed to create file' },
{ error: "Failed to create file" },
{ status: 500 }
)
);
}
}

export async function DELETE(request: Request) {
try {
const { path: itemPath, type } = await request.json()
const fullPath = path.join(getBasePath(), itemPath)
const { path: itemPath, type } = await request.json();
const fullPath = path.join(getBasePath(), itemPath);

if (type === 'folder') {
await rm(fullPath, { recursive: true, force: true })
if (type === "folder") {
await rm(fullPath, { recursive: true, force: true });
} else {
await unlink(fullPath)
await unlink(fullPath);
}

return NextResponse.json({ success: true })
return NextResponse.json({ success: true });
} catch (error) {
console.error('Error deleting item:', error)
console.error("Error deleting item:", error);
return NextResponse.json(
{ error: 'Failed to delete item' },
{ error: "Failed to delete item" },
{ status: 500 }
)
);
}
}

export async function GET(request: Request) {
try {
const { searchParams } = new URL(request.url)
const filePath = searchParams.get('path')
const { searchParams } = new URL(request.url);
const filePath = searchParams.get("path");

if (!filePath) {
return NextResponse.json(
{ error: 'No file path provided' },
{ error: "No file path provided" },
{ status: 400 }
)
);
}

const fullPath = path.join(getBasePath(), filePath)
const fileContent = await readFile(fullPath, 'utf-8')
const parsedContent = JSON.parse(fileContent)
return NextResponse.json(parsedContent)
const fullPath = path.join(getBasePath(), filePath);
const fileContent = await readFile(fullPath, "utf-8");
const parsedContent = JSON.parse(fileContent);

return NextResponse.json(parsedContent);
} catch (error) {
console.error('Error reading file:', error)
return NextResponse.json(
{ error: 'Failed to read file' },
{ status: 500 }
)
console.error("Error reading file:", error);
return NextResponse.json({ error: "Failed to read file" }, { status: 500 });
}
}

export async function PUT(request: Request) {
try {
const { path: filePath, content } = await request.json()
const { path: filePath, content } = await request.json();

if (!filePath) {
return NextResponse.json(
{ error: 'No file path provided' },
{ error: "No file path provided" },
{ status: 400 }
)
);
}

// Validate content
if (!content) {
return NextResponse.json(
{ error: 'No content provided' },
{ error: "No content provided" },
{ status: 400 }
)
);
}

const fullPath = path.join(getBasePath(), filePath)
const fullPath = path.join(getBasePath(), filePath);

// Check if directory exists, if not create it
await mkdir(path.dirname(fullPath), { recursive: true })
await mkdir(path.dirname(fullPath), { recursive: true });

// Add retry logic
const maxRetries = 3;
for (let i = 0; i < maxRetries; i++) {
try {
const jsonContent = JSON.stringify(content, null, 2)
await writeFile(fullPath, jsonContent, 'utf-8')
return NextResponse.json({ success: true })
const jsonContent = JSON.stringify(content, null, 2);
await writeFile(fullPath, jsonContent, "utf-8");
return NextResponse.json({ success: true });
} catch (writeError) {
if (i === maxRetries - 1) throw writeError;
await new Promise(resolve => setTimeout(resolve, 1000)); // Wait 1s before retry
await new Promise((resolve) => setTimeout(resolve, 1000)); // Wait 1s before retry
}
}
} catch (error) {
console.error('Error writing file:', error)
console.error("Error writing file:", error);
return NextResponse.json(
{
error: 'Failed to write file',
details: error instanceof Error ? error.message : 'Unknown error'
{
error: "Failed to write file",
details: error instanceof Error ? error.message : "Unknown error",
},
{ status: 500 }
)
);
}
}
}
Loading
Loading