managarten/apps/uload/scripts/seed-local-db.js
Wuesteon d36b321d9d style: auto-format codebase with Prettier
Applied formatting to 1487+ files using pnpm format:write
  - TypeScript/JavaScript files
  - Svelte components
  - Astro pages
  - JSON configs
  - Markdown docs

  13 files still need manual review (Astro JSX comments)
2025-11-27 18:33:16 +01:00

244 lines
6.7 KiB
JavaScript
Executable file

#!/usr/bin/env node
/**
* Seed Script for Local PocketBase Development
*
* This script creates test data for local development.
*
* Usage:
* 1. Make sure PocketBase is running locally (http://localhost:8090)
* 2. Run: node scripts/seed-local-db.js
*/
import PocketBase from 'pocketbase';
import { randomBytes } from 'crypto';
// Configuration
const POCKETBASE_URL = process.env.PUBLIC_POCKETBASE_URL || 'http://localhost:8090';
const ADMIN_EMAIL = process.env.POCKETBASE_ADMIN_EMAIL || 'admin@localhost';
const ADMIN_PASSWORD = process.env.POCKETBASE_ADMIN_PASSWORD || 'admin123456';
console.log('🌱 Seeding Local PocketBase Database');
console.log('=====================================\n');
console.log(`📍 PocketBase URL: ${POCKETBASE_URL}`);
const pb = new PocketBase(POCKETBASE_URL);
pb.autoCancellation(false);
// Test data
const testUsers = [
{
email: 'test@localhost',
password: 'test123456',
passwordConfirm: 'test123456',
username: 'testuser',
name: 'Test User',
emailVisibility: true,
},
{
email: 'demo@localhost',
password: 'demo123456',
passwordConfirm: 'demo123456',
username: 'demouser',
name: 'Demo User',
emailVisibility: true,
},
];
const testLinks = [
{
short_code: 'test1',
original_url: 'https://example.com',
title: 'Test Link 1',
description: 'This is a test link for development',
is_active: true,
click_limit: null,
expires_at: null,
password: null,
},
{
short_code: 'test2',
original_url: 'https://google.com',
title: 'Google Test',
description: 'Link to Google for testing',
is_active: true,
click_limit: 100,
expires_at: null,
password: null,
},
{
short_code: 'protected',
original_url: 'https://github.com',
title: 'Protected Link',
description: 'Password protected link',
is_active: true,
click_limit: null,
expires_at: null,
password: 'secret123',
},
{
short_code: 'expired',
original_url: 'https://stackoverflow.com',
title: 'Expired Link',
description: 'This link has expired',
is_active: true,
click_limit: null,
expires_at: new Date(Date.now() - 86400000).toISOString(), // Yesterday
password: null,
},
];
async function seedDatabase() {
try {
// Step 1: Try to authenticate as admin
console.log('🔐 Authenticating as admin...');
try {
await pb.admins.authWithPassword(ADMIN_EMAIL, ADMIN_PASSWORD);
console.log('✅ Admin authenticated\n');
} catch (error) {
console.log('⚠️ Admin auth failed. You may need to:');
console.log(' 1. Create admin account at http://localhost:8090/_/');
console.log(' 2. Update POCKETBASE_ADMIN_EMAIL and POCKETBASE_ADMIN_PASSWORD\n');
// Try to continue without admin auth (some operations might fail)
}
// Step 2: Create test users
console.log('👥 Creating test users...');
const createdUsers = [];
for (const userData of testUsers) {
try {
const user = await pb.collection('users').create(userData);
createdUsers.push(user);
console.log(` ✅ Created user: ${userData.email}`);
} catch (error) {
if (error.response?.data?.email?.message?.includes('already exists')) {
console.log(` ⚠️ User ${userData.email} already exists`);
// Try to get existing user
try {
const users = await pb.collection('users').getList(1, 1, {
filter: `email = "${userData.email}"`,
});
if (users.items.length > 0) {
createdUsers.push(users.items[0]);
}
} catch (e) {
console.log(` ❌ Could not fetch existing user: ${userData.email}`);
}
} else {
console.log(` ❌ Failed to create user ${userData.email}:`, error.message);
}
}
}
console.log('');
// Step 3: Create test links
console.log('🔗 Creating test links...');
// Use the first created user as the owner
const ownerId = createdUsers[0]?.id;
for (const linkData of testLinks) {
try {
// Add owner if we have one
if (ownerId) {
linkData.user_id = ownerId;
}
// Generate a random custom code if needed
if (!linkData.custom_code) {
linkData.custom_code = linkData.short_code;
}
const link = await pb.collection('links').create(linkData);
console.log(` ✅ Created link: ${linkData.short_code} -> ${linkData.original_url}`);
} catch (error) {
if (error.response?.data?.short_code?.message?.includes('already exists')) {
console.log(` ⚠️ Link ${linkData.short_code} already exists`);
} else {
console.log(` ❌ Failed to create link ${linkData.short_code}:`, error.message);
}
}
}
console.log('');
// Step 4: Create some test clicks
console.log('📊 Creating test click data...');
try {
// Get one of the links we created
const links = await pb.collection('links').getList(1, 1, {
filter: 'short_code = "test1"',
});
if (links.items.length > 0) {
const link = links.items[0];
// Create some fake clicks
const clickData = [
{
link_id: link.id,
ip_hash: '127.0.0.1',
user_agent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)',
browser: 'Chrome',
device_type: 'Desktop',
os: 'macOS',
country: 'Germany',
city: 'Munich',
clicked_at: new Date().toISOString(),
},
{
link_id: link.id,
ip_hash: '192.168.1.1',
user_agent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_0)',
browser: 'Safari',
device_type: 'Mobile',
os: 'iOS',
country: 'USA',
city: 'New York',
clicked_at: new Date(Date.now() - 3600000).toISOString(), // 1 hour ago
},
];
for (const click of clickData) {
try {
await pb.collection('clicks').create(click);
console.log(` ✅ Created test click from ${click.country}`);
} catch (error) {
console.log(` ❌ Failed to create click:`, error.message);
}
}
}
} catch (error) {
console.log(` ⚠️ Could not create click data:`, error.message);
}
console.log('');
// Summary
console.log('=====================================');
console.log('🎉 Database seeding complete!\n');
console.log('📝 Test Accounts:');
console.log(' Email: test@localhost');
console.log(' Password: test123456\n');
console.log('🔗 Test Links:');
console.log(' http://localhost:5173/test1 - Normal link');
console.log(' http://localhost:5173/test2 - Link with click limit');
console.log(' http://localhost:5173/protected - Password: secret123');
console.log(' http://localhost:5173/expired - Expired link\n');
console.log('👉 Next: Open http://localhost:5173 and test the app!');
} catch (error) {
console.error('❌ Seeding failed:', error);
process.exit(1);
}
}
// Run the seeding
seedDatabase()
.then(() => {
process.exit(0);
})
.catch((error) => {
console.error('Fatal error:', error);
process.exit(1);
});