185 lines
5.6 KiB
TypeScript
185 lines
5.6 KiB
TypeScript
import { NextRequest, NextResponse } from 'next/server'
|
|
import { prisma } from '@/lib/prisma'
|
|
|
|
interface ImportPrompt {
|
|
id: string
|
|
name: string
|
|
content: string
|
|
description?: string | null
|
|
permissions?: string
|
|
visibility?: string | null
|
|
tags?: Array<{ name: string; color?: string }>
|
|
album?: { name: string; description?: string | null } | null
|
|
versions?: Array<{
|
|
version: number
|
|
content: string
|
|
changelog?: string | null
|
|
createdAt: string
|
|
}>
|
|
createdAt?: string
|
|
updatedAt?: string
|
|
}
|
|
|
|
interface ImportData {
|
|
exportVersion?: string
|
|
exportDate?: string
|
|
userId?: string
|
|
totalPrompts?: number
|
|
prompts: ImportPrompt[]
|
|
}
|
|
|
|
export async function POST(req: NextRequest) {
|
|
try {
|
|
const formData = await req.formData()
|
|
const file = formData.get('file') as File
|
|
const userId = formData.get('userId') as string
|
|
|
|
if (!file || !userId) {
|
|
return NextResponse.json({ error: 'Missing file or userId' }, { status: 400 })
|
|
}
|
|
|
|
// Read and parse the file content
|
|
const fileContent = await file.text()
|
|
let importData: ImportData
|
|
|
|
try {
|
|
importData = JSON.parse(fileContent)
|
|
} catch {
|
|
return NextResponse.json({ error: 'Invalid JSON file' }, { status: 400 })
|
|
}
|
|
|
|
if (!importData.prompts || !Array.isArray(importData.prompts)) {
|
|
return NextResponse.json({ error: 'Invalid file format: missing prompts array' }, { status: 400 })
|
|
}
|
|
|
|
const results = {
|
|
imported: 0,
|
|
skipped: 0,
|
|
errors: 0,
|
|
messages: [] as string[]
|
|
}
|
|
|
|
// Process each prompt
|
|
for (const promptData of importData.prompts) {
|
|
try {
|
|
// Check if prompt with this ID already exists for this user
|
|
const existingPrompt = await prisma.prompt.findUnique({
|
|
where: { id: promptData.id }
|
|
})
|
|
|
|
if (existingPrompt) {
|
|
results.skipped++
|
|
results.messages.push(`Skipped prompt "${promptData.name}" (ID: ${promptData.id}) - already exists`)
|
|
continue
|
|
}
|
|
|
|
// Handle tags - create if they don't exist
|
|
const tagIds: string[] = []
|
|
if (promptData.tags && promptData.tags.length > 0) {
|
|
for (const tagData of promptData.tags) {
|
|
const existingTag = await prisma.promptTag.findUnique({
|
|
where: { name: tagData.name }
|
|
})
|
|
|
|
if (existingTag) {
|
|
tagIds.push(existingTag.id)
|
|
} else {
|
|
const newTag = await prisma.promptTag.create({
|
|
data: {
|
|
name: tagData.name,
|
|
color: tagData.color || '#3B82F6'
|
|
}
|
|
})
|
|
tagIds.push(newTag.id)
|
|
}
|
|
}
|
|
}
|
|
|
|
// Handle album - create if it doesn't exist
|
|
let albumId: string | null = null
|
|
if (promptData.album) {
|
|
const existingAlbum = await prisma.promptAlbum.findFirst({
|
|
where: { name: promptData.album.name }
|
|
})
|
|
|
|
if (existingAlbum) {
|
|
albumId = existingAlbum.id
|
|
} else {
|
|
const newAlbum = await prisma.promptAlbum.create({
|
|
data: {
|
|
name: promptData.album.name,
|
|
description: promptData.album.description
|
|
}
|
|
})
|
|
albumId = newAlbum.id
|
|
}
|
|
}
|
|
|
|
// Create the prompt with the original ID
|
|
const newPrompt = await prisma.prompt.create({
|
|
data: {
|
|
id: promptData.id,
|
|
name: promptData.name,
|
|
content: promptData.content,
|
|
description: promptData.description,
|
|
permissions: promptData.permissions || 'private',
|
|
visibility: promptData.visibility,
|
|
userId,
|
|
albumId,
|
|
createdAt: promptData.createdAt ? new Date(promptData.createdAt) : undefined,
|
|
updatedAt: promptData.updatedAt ? new Date(promptData.updatedAt) : undefined,
|
|
tags: {
|
|
connect: tagIds.map(id => ({ id }))
|
|
}
|
|
}
|
|
})
|
|
|
|
// Import versions if available
|
|
if (promptData.versions && promptData.versions.length > 0) {
|
|
for (const versionData of promptData.versions) {
|
|
await prisma.promptVersion.create({
|
|
data: {
|
|
promptId: newPrompt.id,
|
|
version: versionData.version,
|
|
content: versionData.content,
|
|
changelog: versionData.changelog,
|
|
createdAt: new Date(versionData.createdAt)
|
|
}
|
|
})
|
|
}
|
|
} else {
|
|
// If no versions are provided, create version 1 with the prompt content
|
|
await prisma.promptVersion.create({
|
|
data: {
|
|
promptId: newPrompt.id,
|
|
version: 1,
|
|
content: promptData.content,
|
|
changelog: 'Initial version'
|
|
}
|
|
})
|
|
}
|
|
|
|
results.imported++
|
|
results.messages.push(`Imported prompt "${promptData.name}" successfully`)
|
|
|
|
} catch (error) {
|
|
results.errors++
|
|
results.messages.push(`Error importing prompt "${promptData.name}": ${error instanceof Error ? error.message : 'Unknown error'}`)
|
|
console.error('Import error for prompt:', promptData.name, error)
|
|
}
|
|
}
|
|
|
|
return NextResponse.json({
|
|
success: true,
|
|
results,
|
|
message: `Import completed: ${results.imported} imported, ${results.skipped} skipped, ${results.errors} errors`
|
|
})
|
|
|
|
} catch (error) {
|
|
console.error('Import error:', error)
|
|
return NextResponse.json({
|
|
error: 'Import failed',
|
|
details: error instanceof Error ? error.message : 'Unknown error'
|
|
}, { status: 500 })
|
|
}
|
|
} |