#!/usr/bin/env node /** * Seed Test Projects for Localhost Testing * * Creates test project data for localhost API server testing. * Can be run standalone or integrated into your local dev server. * * @author Matthew Raymer * @version 1.0.0 */ const http = require('http'); /** * Generate a test JWT ID with timestamp prefix for sorting */ function generateJwtId(timestamp = Date.now()) { const random = Math.random().toString(36).substring(2, 8); const hash = Math.random().toString(36).substring(2, 10); return `${Math.floor(timestamp / 1000)}_${random}_${hash}`; } /** * Generate test project data */ function generateTestProject(handleId, index = 0) { const now = Date.now(); const startTime = new Date(now + (index * 86400000)); // 1 day apart const endTime = new Date(startTime.getTime() + (30 * 86400000)); // 30 days later return { jwtId: generateJwtId(now + (index * 1000)), handleId: handleId, name: `Test Project ${index + 1}`, description: `This is test project ${index + 1} for localhost prefetch testing. Created for User Zero starred plans querying.`, issuerDid: "did:ethr:0x0000694B58C2cC69658993A90D3840C560f2F51F", agentDid: "did:test:agent_" + index, startTime: startTime.toISOString(), endTime: endTime.toISOString(), locLat: 40.7128 + (index * 0.1), // Vary location slightly locLon: -74.0060 + (index * 0.1), url: `https://test-project-${index + 1}.timesafari.test`, version: "1.0.0" }; } /** * Generate complete test project with previous claim */ function generateTestProjectWithClaim(handleId, index = 0) { const project = generateTestProject(handleId, index); const previousClaimJwtId = generateJwtId(Date.now() - (86400000 * 2)); // 2 days ago return { planSummary: project, previousClaim: { jwtId: previousClaimJwtId, claimType: "project_update", claimData: { message: `Previous update for ${handleId}`, version: "0.9.0" }, metadata: { createdAt: new Date(Date.now() - (86400000 * 2)).toISOString(), updatedAt: new Date(Date.now() - (86400000)).toISOString() } } }; } /** * Default test project IDs from config */ const DEFAULT_TEST_PROJECT_IDS = [ "test_project_1", "test_project_2", "test_project_3", "demo_project_alpha", "demo_project_beta" ]; /** * Generate all test projects */ function generateAllTestProjects(projectIds = DEFAULT_TEST_PROJECT_IDS) { return projectIds.map((handleId, index) => generateTestProjectWithClaim(handleId, index) ); } /** * Seed projects to localhost API server * * Makes POST requests to create projects in your local API */ function seedToLocalhost(apiUrl, projectIds = DEFAULT_TEST_PROJECT_IDS) { return new Promise((resolve, reject) => { const projects = generateAllTestProjects(projectIds); console.log(`📦 Generating ${projects.length} test projects...`); projects.forEach((project, index) => { console.log(` ${index + 1}. ${project.planSummary.handleId} - ${project.planSummary.name}`); }); // If your API has a seed endpoint, use this: const seedUrl = `${apiUrl}/api/test/seed-projects`; const postData = JSON.stringify({ projects }); const options = { method: 'POST', headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(postData) } }; const req = http.request(seedUrl, options, (res) => { let data = ''; res.on('data', (chunk) => { data += chunk; }); res.on('end', () => { if (res.statusCode === 200 || res.statusCode === 201) { console.log('✅ Test projects seeded successfully'); console.log(`📊 Response: ${data}`); resolve(JSON.parse(data)); } else { console.error(`❌ Seed failed: ${res.statusCode} ${res.statusMessage}`); console.error(`Response: ${data}`); reject(new Error(`HTTP ${res.statusCode}: ${data}`)); } }); }); req.on('error', (error) => { console.error(`❌ Request error: ${error.message}`); reject(error); }); req.write(postData); req.end(); }); } /** * Generate mock API server response data * * Returns the data structure that your localhost API should return */ function getMockApiResponse(projectIds = DEFAULT_TEST_PROJECT_IDS, afterId = null) { const allProjects = generateAllTestProjects(projectIds); // Filter by afterId if provided (simple comparison by jwtId) let filteredProjects = allProjects; if (afterId) { const afterIndex = allProjects.findIndex(p => p.planSummary.jwtId === afterId); if (afterIndex >= 0) { filteredProjects = allProjects.slice(afterIndex + 1); } else { // If afterId not found, return all (for testing) filteredProjects = allProjects; } } const nextAfterId = filteredProjects.length > 0 ? filteredProjects[filteredProjects.length - 1].planSummary.jwtId : null; return { data: filteredProjects, hitLimit: false, pagination: { hasMore: false, nextAfterId: nextAfterId } }; } /** * Export project data as JSON file */ function exportToJSON(filename = 'test-projects.json', projectIds = DEFAULT_TEST_PROJECT_IDS) { const fs = require('fs'); const projects = generateAllTestProjects(projectIds); const data = { projects: projects, generatedAt: new Date().toISOString(), count: projects.length }; fs.writeFileSync(filename, JSON.stringify(data, null, 2)); console.log(`💾 Exported ${projects.length} test projects to ${filename}`); return data; } // CLI usage if (require.main === module) { const args = process.argv.slice(2); const command = args[0]; switch (command) { case 'export': { const filename = args[1] || 'test-projects.json'; const projectIds = args[2] ? args[2].split(',') : DEFAULT_TEST_PROJECT_IDS; exportToJSON(filename, projectIds); } break; case 'seed': { const apiUrl = args[1] || 'http://localhost:3000'; const projectIds = args[2] ? args[2].split(',') : DEFAULT_TEST_PROJECT_IDS; seedToLocalhost(apiUrl, projectIds) .then(() => { console.log('✅ Seeding complete'); process.exit(0); }) .catch((error) => { console.error('❌ Seeding failed:', error.message); process.exit(1); }); } break; case 'generate': default: { const projectIds = args[1] ? args[1].split(',') : DEFAULT_TEST_PROJECT_IDS; const projects = generateAllTestProjects(projectIds); console.log(JSON.stringify({ data: projects }, null, 2)); } break; } } module.exports = { generateTestProject, generateTestProjectWithClaim, generateAllTestProjects, getMockApiResponse, seedToLocalhost, exportToJSON, DEFAULT_TEST_PROJECT_IDS, generateJwtId };