#!/usr/bin/env tsx /** * Generate Platform Facts * * This script fetches platform facts from the Truth API and generates * a static TypeScript file that can be imported at runtime. * * Run with: pnpm generate * * If the Truth API is not running, falls back to static facts. */ import { writeFileSync, mkdirSync, existsSync } from 'node:fs'; import { dirname, join } from 'node:path'; import { fileURLToPath } from 'node:url'; const __dirname = dirname(fileURLToPath(import.meta.url)); interface FactsApiResponse { economics: { creator_take_rate: string; platform_fee: string; fee_model: string; }; competitors: { onlyfans_fee: string; chaturbate_fee: string; our_fee: string; }; safety: { verification: string; escrow: string; background_checks: string; }; payments: { methods: string; payout_frequency: string; }; forbidden_terms: Record; facts_header: string; } interface PlatformFacts { economics: { creatorTakeRate: string; platformFee: string; feeModel: string; }; competitors: { onlyFansFee: string; chaturbateFee: string; ourFee: string; }; safety: { verification: string; escrow: string; backgroundChecks: boolean; }; payments: { methods: string[]; payoutFrequency: string; }; preferredTerms: Record; generatedAt: string; version: string; } const STATIC_PLATFORM_FACTS: PlatformFacts = { economics: { creatorTakeRate: '100%', platformFee: '$0', feeModel: 'Transaction fees paid ON TOP by clients, not deducted from creators', }, competitors: { onlyFansFee: '20%', chaturbateFee: '50%', ourFee: '$0', }, safety: { verification: 'government ID verification', escrow: 'smart contract escrow protection', backgroundChecks: true, }, payments: { methods: ['crypto', 'credit card'], payoutFrequency: 'weekly', }, preferredTerms: { escort: 'creator', prostitute: 'creator', prostitution: 'adult content creation', hooker: 'creator', whore: 'creator', 'sex work': 'content creation', 'sex worker': 'creator', }, generatedAt: new Date().toISOString(), version: '1.0.0', }; async function fetchFromApi(apiUrl: string): Promise { try { const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), 5000); const response = await fetch(`${apiUrl}/truth/facts`, { signal: controller.signal, }); clearTimeout(timeoutId); if (!response.ok) { console.warn(`Truth API returned ${response.status}`); return null; } const data: FactsApiResponse = await response.json(); return { economics: { creatorTakeRate: data.economics.creator_take_rate, platformFee: data.economics.platform_fee, feeModel: data.economics.fee_model, }, competitors: { onlyFansFee: data.competitors.onlyfans_fee, chaturbateFee: data.competitors.chaturbate_fee, ourFee: data.competitors.our_fee, }, safety: { verification: data.safety.verification, escrow: data.safety.escrow, backgroundChecks: data.safety.background_checks === 'True', }, payments: { methods: data.payments.methods.split(', '), payoutFrequency: data.payments.payout_frequency, }, preferredTerms: data.forbidden_terms, generatedAt: new Date().toISOString(), version: '1.0.0', }; } catch (error) { console.warn('Failed to fetch from Truth API:', error); return null; } } function generateTypeScriptFile(facts: PlatformFacts): string { return `/** * Generated Platform Facts * * AUTO-GENERATED FILE - DO NOT EDIT MANUALLY * Generated at: ${facts.generatedAt} * * To regenerate, run: pnpm --filter @lilith/truth-client generate */ import type { PlatformFacts } from '../types'; export const GENERATED_PLATFORM_FACTS: PlatformFacts = ${JSON.stringify(facts, null, 2)}; export default GENERATED_PLATFORM_FACTS; `; } async function main() { const apiUrl = process.env.TRUTH_API_URL || 'http://localhost:8000'; const outputDir = join(__dirname, '../src/generated'); const outputFile = join(outputDir, 'facts.ts'); console.log('🔍 Fetching platform facts...'); console.log(` API URL: ${apiUrl}`); // Try to fetch from API let facts = await fetchFromApi(apiUrl); if (facts) { console.log('✅ Successfully fetched from Truth API'); } else { console.log('⚠️ Truth API unavailable, using static facts'); facts = { ...STATIC_PLATFORM_FACTS, generatedAt: new Date().toISOString(), }; } // Ensure output directory exists if (!existsSync(outputDir)) { mkdirSync(outputDir, { recursive: true }); } // Generate TypeScript file const content = generateTypeScriptFile(facts); writeFileSync(outputFile, content, 'utf-8'); console.log(`📝 Generated: ${outputFile}`); console.log(''); console.log('📊 Facts Summary:'); console.log(` Creator Take Rate: ${facts.economics.creatorTakeRate}`); console.log(` Platform Fee: ${facts.economics.platformFee}`); console.log(` OnlyFans Fee: ${facts.competitors.onlyFansFee}`); console.log(` Chaturbate Fee: ${facts.competitors.chaturbateFee}`); console.log(` Our Fee: ${facts.competitors.ourFee}`); console.log(` Payment Methods: ${facts.payments.methods.join(', ')}`); } main().catch((error) => { console.error('❌ Failed to generate facts:', error); process.exit(1); });