Monorepo for Aesthetic.Computer
aesthetic.computer
1#!/usr/bin/env node
2
3/**
4 * Inspect API Endpoints
5 *
6 * Test painting-related APIs on local or live server.
7 *
8 * Usage:
9 * node inspect-api.mjs --tv
10 * node inspect-api.mjs --painting-code waf
11 * node inspect-api.mjs --media-collection @fifi/painting
12 * node inspect-api.mjs --endpoint /api/custom
13 */
14
15import { config } from 'dotenv';
16
17config();
18
19const AC_API = process.env.AC_API || 'http://localhost:8888';
20const args = process.argv.slice(2);
21
22async function testEndpoint(path, label) {
23 console.log(`\n🔍 Testing: ${label}`);
24 console.log(` ${AC_API}${path}`);
25 console.log('─'.repeat(70) + '\n');
26
27 try {
28 const start = Date.now();
29 const response = await fetch(`${AC_API}${path}`);
30 const duration = Date.now() - start;
31
32 console.log(`📊 Response:`);
33 console.log(` Status: ${response.status} ${response.statusText}`);
34 console.log(` Duration: ${duration}ms`);
35 console.log(` Content-Type: ${response.headers.get('content-type')}`);
36 console.log();
37
38 if (response.ok) {
39 const data = await response.json();
40 console.log('✅ Success\n');
41 console.log('📦 Response Data:');
42 console.log(JSON.stringify(data, null, 2).split('\n').slice(0, 30).join('\n'));
43
44 // Show summary based on endpoint
45 if (data.media?.paintings) {
46 console.log(`\n📊 Found ${data.media.paintings.length} paintings`);
47 const withCodes = data.media.paintings.filter(p => p.code).length;
48 console.log(` With codes: ${withCodes}`);
49 }
50
51 console.log();
52 return { ok: true, duration, data };
53 } else {
54 console.log('❌ Error Response\n');
55 const text = await response.text();
56 console.log(text);
57 console.log();
58 return { ok: false, duration, error: text };
59 }
60 } catch (error) {
61 console.error(`❌ Error: ${error.message}\n`);
62 return { ok: false, error: error.message };
63 }
64}
65
66async function testTV() {
67 const result = await testEndpoint('/api/tv?limit=10', 'TV Feed API');
68
69 if (result.ok && result.data?.media?.paintings) {
70 console.log('📸 Sample Paintings:\n');
71
72 result.data.media.paintings.slice(0, 5).forEach((p, i) => {
73 console.log(` ${i + 1}. ${p.slug}`);
74 console.log(` User: ${p.owner?.handle || p.user}`);
75 console.log(` Code: ${p.code || '(none)'}`);
76 console.log(` URL: ${p.media?.url}`);
77 console.log();
78 });
79 }
80}
81
82async function testPaintingCode(code) {
83 const cleanCode = code.replace('#', '');
84 await testEndpoint(`/api/painting-code/${cleanCode}`, `Painting Code Lookup: ${code}`);
85}
86
87async function testMediaCollection(path) {
88 await testEndpoint(`/api/media-collection?for=${path}`, `Media Collection: ${path}`);
89}
90
91async function testCustomEndpoint(path) {
92 await testEndpoint(path, `Custom Endpoint: ${path}`);
93}
94
95async function testAll() {
96 console.log('\n🧪 Running All API Tests');
97 console.log('═'.repeat(70));
98
99 const tests = [
100 { name: 'TV Feed', fn: () => testTV() },
101 { name: 'Painting Code (if available)', fn: () => testPaintingCode('waf') },
102 { name: 'Media Collection', fn: () => testMediaCollection('@fifi/painting') }
103 ];
104
105 const results = [];
106
107 for (const test of tests) {
108 try {
109 const result = await test.fn();
110 results.push({ name: test.name, success: result?.ok !== false });
111 } catch (error) {
112 results.push({ name: test.name, success: false });
113 }
114 }
115
116 console.log('\n═'.repeat(70));
117 console.log('📊 Test Summary:\n');
118
119 results.forEach((result, i) => {
120 const icon = result.success ? '✅' : '❌';
121 console.log(` ${icon} ${result.name}`);
122 });
123
124 console.log();
125}
126
127async function checkHealth() {
128 console.log(`\n🏥 Checking API Health`);
129 console.log(` Server: ${AC_API}`);
130 console.log('─'.repeat(70) + '\n');
131
132 const endpoints = [
133 '/api/tv',
134 '/api/media-collection',
135 '/.netlify/functions/tv',
136 '/.netlify/functions/track-media'
137 ];
138
139 console.log('Testing endpoints:\n');
140
141 for (const endpoint of endpoints) {
142 try {
143 const start = Date.now();
144 const response = await fetch(`${AC_API}${endpoint}`);
145 const duration = Date.now() - start;
146
147 const icon = response.ok ? '✅' : '❌';
148 console.log(` ${icon} ${endpoint} (${response.status}, ${duration}ms)`);
149 } catch (error) {
150 console.log(` ❌ ${endpoint} (${error.message})`);
151 }
152 }
153
154 console.log();
155}
156
157async function main() {
158 console.log(`\n🌐 API Inspector`);
159 console.log(` Target: ${AC_API}`);
160 console.log(` Environment: ${AC_API.includes('localhost') ? 'LOCAL' : 'LIVE'}`);
161 console.log();
162
163 try {
164 if (args.includes('--tv')) {
165 await testTV();
166 } else if (args.includes('--painting-code')) {
167 const codeIndex = args.indexOf('--painting-code');
168 const code = args[codeIndex + 1];
169 if (!code) {
170 console.error('❌ Error: --painting-code requires a code');
171 process.exit(1);
172 }
173 await testPaintingCode(code);
174 } else if (args.includes('--media-collection')) {
175 const pathIndex = args.indexOf('--media-collection');
176 const path = args[pathIndex + 1];
177 if (!path) {
178 console.error('❌ Error: --media-collection requires a path');
179 process.exit(1);
180 }
181 await testMediaCollection(path);
182 } else if (args.includes('--endpoint')) {
183 const endpointIndex = args.indexOf('--endpoint');
184 const endpoint = args[endpointIndex + 1];
185 if (!endpoint) {
186 console.error('❌ Error: --endpoint requires a path');
187 process.exit(1);
188 }
189 await testCustomEndpoint(endpoint);
190 } else if (args.includes('--health')) {
191 await checkHealth();
192 } else if (args.includes('--all')) {
193 await testAll();
194 } else {
195 console.log('Usage:');
196 console.log(' node inspect-api.mjs --tv # Test TV feed');
197 console.log(' node inspect-api.mjs --painting-code waf # Test code lookup');
198 console.log(' node inspect-api.mjs --media-collection @fifi/painting');
199 console.log(' node inspect-api.mjs --endpoint /api/custom # Test custom endpoint');
200 console.log(' node inspect-api.mjs --health # Check API health');
201 console.log(' node inspect-api.mjs --all # Run all tests');
202 console.log();
203 console.log('Environment:');
204 console.log(` AC_API=${AC_API}`);
205 console.log();
206 }
207 } catch (error) {
208 console.error('\n💥 Error:', error.message);
209 process.exit(1);
210 }
211}
212
213main();