mirror of
https://github.com/f/awesome-chatgpt-prompts.git
synced 2026-02-12 15:52:47 +00:00
296 lines
8.3 KiB
TypeScript
296 lines
8.3 KiB
TypeScript
import { PrismaClient, PromptType, StructuredFormat, RequiredMediaType } from "@prisma/client";
|
|
import bcrypt from "bcryptjs";
|
|
|
|
const prisma = new PrismaClient();
|
|
|
|
const PROMPTS_JSON_URL = "https://prompts.chat/prompts.json";
|
|
|
|
interface RemotePrompt {
|
|
id: string;
|
|
title: string;
|
|
slug: string;
|
|
description: string | null;
|
|
content: string;
|
|
type: string;
|
|
structuredFormat: string | null;
|
|
mediaUrl: string | null;
|
|
viewCount: number;
|
|
voteCount: number;
|
|
commentCount: number;
|
|
isFeatured: boolean;
|
|
featuredAt: string | null;
|
|
requiresMediaUpload: boolean;
|
|
requiredMediaType: string | null;
|
|
requiredMediaCount: number | null;
|
|
createdAt: string;
|
|
updatedAt: string;
|
|
category: {
|
|
id: string;
|
|
name: string;
|
|
slug: string;
|
|
icon: string | null;
|
|
} | null;
|
|
author: {
|
|
username: string;
|
|
name: string | null;
|
|
avatar: string | null;
|
|
identifier: string;
|
|
verified: boolean;
|
|
};
|
|
contributors: Array<{
|
|
username: string;
|
|
name: string | null;
|
|
avatar: string | null;
|
|
identifier: string;
|
|
verified: boolean;
|
|
}>;
|
|
tags: Array<{
|
|
id: string;
|
|
name: string;
|
|
slug: string;
|
|
color: string;
|
|
}>;
|
|
}
|
|
|
|
interface RemotePromptsResponse {
|
|
count: number;
|
|
prompts: RemotePrompt[];
|
|
}
|
|
|
|
async function fetchPrompts(): Promise<RemotePromptsResponse> {
|
|
console.log(`📡 Fetching prompts from ${PROMPTS_JSON_URL}...`);
|
|
const response = await fetch(PROMPTS_JSON_URL);
|
|
if (!response.ok) {
|
|
throw new Error(`Failed to fetch prompts: ${response.status} ${response.statusText}`);
|
|
}
|
|
const data = await response.json();
|
|
console.log(`✅ Fetched ${data.count} prompts`);
|
|
return data;
|
|
}
|
|
|
|
async function main() {
|
|
console.log("🌱 Seeding database from prompts.chat...");
|
|
|
|
// Create admin user for assigning prompts
|
|
const password = await bcrypt.hash("password123", 12);
|
|
|
|
const admin = await prisma.user.upsert({
|
|
where: { email: "admin@prompts.chat" },
|
|
update: {},
|
|
create: {
|
|
email: "admin@prompts.chat",
|
|
username: "admin",
|
|
name: "Admin User",
|
|
password: password,
|
|
role: "ADMIN",
|
|
locale: "en",
|
|
},
|
|
});
|
|
|
|
console.log("✅ Created admin user");
|
|
|
|
// Fetch prompts from remote JSON
|
|
const { prompts: remotePrompts } = await fetchPrompts();
|
|
|
|
// Extract unique categories from remote prompts
|
|
const categoryMap = new Map<string, { name: string; slug: string; icon: string | null }>();
|
|
for (const prompt of remotePrompts) {
|
|
if (prompt.category) {
|
|
categoryMap.set(prompt.category.slug, {
|
|
name: prompt.category.name,
|
|
slug: prompt.category.slug,
|
|
icon: prompt.category.icon,
|
|
});
|
|
}
|
|
}
|
|
|
|
// Create categories
|
|
console.log(`📁 Creating ${categoryMap.size} categories...`);
|
|
const categoryIdMap = new Map<string, string>();
|
|
let categoryOrder = 1;
|
|
for (const [slug, cat] of categoryMap) {
|
|
const category = await prisma.category.upsert({
|
|
where: { slug },
|
|
update: { name: cat.name, icon: cat.icon },
|
|
create: {
|
|
name: cat.name,
|
|
slug: cat.slug,
|
|
icon: cat.icon,
|
|
order: categoryOrder++,
|
|
},
|
|
});
|
|
categoryIdMap.set(slug, category.id);
|
|
}
|
|
console.log(`✅ Created ${categoryMap.size} categories`);
|
|
|
|
// Extract unique tags from remote prompts
|
|
const tagMap = new Map<string, { name: string; slug: string; color: string }>();
|
|
for (const prompt of remotePrompts) {
|
|
for (const tag of prompt.tags) {
|
|
tagMap.set(tag.slug, {
|
|
name: tag.name,
|
|
slug: tag.slug,
|
|
color: tag.color,
|
|
});
|
|
}
|
|
}
|
|
|
|
// Create tags
|
|
console.log(`🏷️ Creating ${tagMap.size} tags...`);
|
|
const tagIdMap = new Map<string, string>();
|
|
for (const [slug, tag] of tagMap) {
|
|
const createdTag = await prisma.tag.upsert({
|
|
where: { slug },
|
|
update: { name: tag.name, color: tag.color },
|
|
create: {
|
|
name: tag.name,
|
|
slug: tag.slug,
|
|
color: tag.color,
|
|
},
|
|
});
|
|
tagIdMap.set(slug, createdTag.id);
|
|
}
|
|
console.log(`✅ Created ${tagMap.size} tags`);
|
|
|
|
// Extract unique authors from remote prompts and create users
|
|
const authorMap = new Map<string, { username: string; name: string | null; avatar: string | null; verified: boolean }>();
|
|
for (const prompt of remotePrompts) {
|
|
if (!authorMap.has(prompt.author.username)) {
|
|
authorMap.set(prompt.author.username, {
|
|
username: prompt.author.username,
|
|
name: prompt.author.name,
|
|
avatar: prompt.author.avatar,
|
|
verified: prompt.author.verified,
|
|
});
|
|
}
|
|
}
|
|
|
|
// Create users for authors
|
|
console.log(`👤 Creating ${authorMap.size} users...`);
|
|
const userIdMap = new Map<string, string>();
|
|
for (const [username, author] of authorMap) {
|
|
// Skip creating if it's the admin
|
|
if (username === "admin") {
|
|
userIdMap.set(username, admin.id);
|
|
continue;
|
|
}
|
|
|
|
const user = await prisma.user.upsert({
|
|
where: { username },
|
|
update: { name: author.name, avatar: author.avatar },
|
|
create: {
|
|
email: `${username}@prompts.chat`,
|
|
username: author.username,
|
|
name: author.name,
|
|
avatar: author.avatar,
|
|
password: password,
|
|
role: "USER",
|
|
locale: "en",
|
|
},
|
|
});
|
|
userIdMap.set(username, user.id);
|
|
}
|
|
console.log(`✅ Created ${authorMap.size} users`);
|
|
|
|
// Create prompts
|
|
console.log(`📝 Creating ${remotePrompts.length} prompts...`);
|
|
let promptsCreated = 0;
|
|
let promptsSkipped = 0;
|
|
|
|
for (const remotePrompt of remotePrompts) {
|
|
const authorId = userIdMap.get(remotePrompt.author.username);
|
|
if (!authorId) {
|
|
console.warn(`⚠️ Skipping prompt "${remotePrompt.title}" - author not found`);
|
|
promptsSkipped++;
|
|
continue;
|
|
}
|
|
|
|
const categoryId = remotePrompt.category ? categoryIdMap.get(remotePrompt.category.slug) : null;
|
|
|
|
// Map prompt type
|
|
const typeMap: Record<string, PromptType> = {
|
|
TEXT: "TEXT",
|
|
IMAGE: "IMAGE",
|
|
VIDEO: "VIDEO",
|
|
AUDIO: "AUDIO",
|
|
STRUCTURED: "STRUCTURED",
|
|
SKILL: "SKILL",
|
|
};
|
|
const promptType = typeMap[remotePrompt.type] || "TEXT";
|
|
|
|
// Map structured format
|
|
const formatMap: Record<string, StructuredFormat> = {
|
|
JSON: "JSON",
|
|
YAML: "YAML",
|
|
};
|
|
const structuredFormat = remotePrompt.structuredFormat ? formatMap[remotePrompt.structuredFormat] : null;
|
|
|
|
// Check if prompt already exists
|
|
const existingPrompt = await prisma.prompt.findFirst({
|
|
where: { slug: remotePrompt.slug },
|
|
});
|
|
|
|
if (existingPrompt) {
|
|
promptsSkipped++;
|
|
continue;
|
|
}
|
|
|
|
try {
|
|
const prompt = await prisma.prompt.create({
|
|
data: {
|
|
title: remotePrompt.title,
|
|
slug: remotePrompt.slug,
|
|
description: remotePrompt.description,
|
|
content: remotePrompt.content,
|
|
type: promptType,
|
|
structuredFormat: structuredFormat,
|
|
mediaUrl: remotePrompt.mediaUrl,
|
|
viewCount: remotePrompt.viewCount,
|
|
isFeatured: remotePrompt.isFeatured,
|
|
featuredAt: remotePrompt.featuredAt ? new Date(remotePrompt.featuredAt) : null,
|
|
requiresMediaUpload: remotePrompt.requiresMediaUpload,
|
|
requiredMediaType: remotePrompt.requiredMediaType as RequiredMediaType | null,
|
|
requiredMediaCount: remotePrompt.requiredMediaCount,
|
|
authorId: authorId,
|
|
categoryId: categoryId,
|
|
tags: {
|
|
create: remotePrompt.tags
|
|
.filter(tag => tagIdMap.has(tag.slug))
|
|
.map(tag => ({ tagId: tagIdMap.get(tag.slug)! })),
|
|
},
|
|
},
|
|
});
|
|
|
|
// Create initial version
|
|
await prisma.promptVersion.create({
|
|
data: {
|
|
promptId: prompt.id,
|
|
version: 1,
|
|
content: remotePrompt.content,
|
|
changeNote: "Initial version",
|
|
createdBy: authorId,
|
|
},
|
|
});
|
|
|
|
promptsCreated++;
|
|
} catch (error) {
|
|
console.warn(`⚠️ Failed to create prompt "${remotePrompt.title}":`, error);
|
|
promptsSkipped++;
|
|
}
|
|
}
|
|
|
|
console.log(`✅ Created ${promptsCreated} prompts (${promptsSkipped} skipped)`);
|
|
console.log("\n🎉 Seeding complete!");
|
|
console.log("\n📋 Test credentials (password: password123):");
|
|
console.log(" Admin: admin@prompts.chat");
|
|
}
|
|
|
|
main()
|
|
.catch((e) => {
|
|
console.error("❌ Seeding failed:", e);
|
|
process.exit(1);
|
|
})
|
|
.finally(async () => {
|
|
await prisma.$disconnect();
|
|
});
|