From bc6839919c31870ee99d34882b391722c2bb3a2a Mon Sep 17 00:00:00 2001 From: cawcenter Date: Sun, 14 Dec 2025 14:54:09 -0500 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=B1=20GOD=20MODE=20CLI:=20Persistent?= =?UTF-8?q?=20API=20access=20with=20no=20connection=20limits?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Features: - Keep-alive connections (no random disconnects) - Zero timeout (never cuts off) - Auto-retry with exponential backoff (5 attempts) - Works as CLI and Node.js module Commands: - health: Check API status - collections: List all collections - schema: Export full schema - read : Query collection - count : Count items - insert : Create item from stdin No yaml edits - pure JS utility --- scripts/god-mode.js | 316 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 316 insertions(+) create mode 100644 scripts/god-mode.js diff --git a/scripts/god-mode.js b/scripts/god-mode.js new file mode 100644 index 0000000..55677cd --- /dev/null +++ b/scripts/god-mode.js @@ -0,0 +1,316 @@ +#!/usr/bin/env node +/** + * SPARK GOD MODE CLI + * ================== + * Direct API access to Spark Platform with no connection limits. + * + * Usage: + * node scripts/god-mode.js [options] + * + * Commands: + * health - Check API health + * collections - List all collections + * schema - Export schema snapshot + * query - Query a collection + * insert - Insert into collection (reads JSON from stdin) + * update - Update items (requires --filter and --data) + * sql - Execute raw SQL (admin only) + * + * Environment: + * DIRECTUS_URL - Directus API URL (default: https://spark.jumpstartscaling.com) + * GOD_MODE_TOKEN - God Mode authentication token + * ADMIN_TOKEN - Directus Admin Token (for standard ops) + */ + +const https = require('https'); +const http = require('http'); + +// ============================================================================ +// CONFIGURATION +// ============================================================================ + +const CONFIG = { + // Primary URL (can be overridden by env) + DIRECTUS_URL: process.env.DIRECTUS_URL || 'https://spark.jumpstartscaling.com', + + // Authentication + GOD_MODE_TOKEN: process.env.GOD_MODE_TOKEN || '', + ADMIN_TOKEN: process.env.DIRECTUS_ADMIN_TOKEN || process.env.ADMIN_TOKEN || '', + + // Connection settings - NO LIMITS + TIMEOUT: 0, // No timeout + MAX_RETRIES: 5, + RETRY_DELAY: 1000, + KEEP_ALIVE: true +}; + +// Keep-alive agent for persistent connections +const httpAgent = new http.Agent({ keepAlive: true, maxSockets: 10 }); +const httpsAgent = new https.Agent({ keepAlive: true, maxSockets: 10 }); + +// ============================================================================ +// HTTP CLIENT (No external dependencies) +// ============================================================================ + +function request(method, path, data = null, useGodMode = false) { + return new Promise((resolve, reject) => { + const url = new URL(path.startsWith('http') ? path : `${CONFIG.DIRECTUS_URL}${path}`); + const isHttps = url.protocol === 'https:'; + const client = isHttps ? https : http; + + const headers = { + 'Content-Type': 'application/json', + 'Accept': 'application/json', + 'User-Agent': 'SparkGodMode/1.0' + }; + + // Authentication + if (useGodMode && CONFIG.GOD_MODE_TOKEN) { + headers['X-God-Token'] = CONFIG.GOD_MODE_TOKEN; + } else if (CONFIG.ADMIN_TOKEN) { + headers['Authorization'] = `Bearer ${CONFIG.ADMIN_TOKEN}`; + } + + const options = { + hostname: url.hostname, + port: url.port || (isHttps ? 443 : 80), + path: url.pathname + url.search, + method: method, + headers: headers, + agent: isHttps ? httpsAgent : httpAgent, + timeout: CONFIG.TIMEOUT + }; + + const req = client.request(options, (res) => { + let body = ''; + res.on('data', chunk => body += chunk); + res.on('end', () => { + try { + const json = JSON.parse(body); + if (res.statusCode >= 400) { + reject({ status: res.statusCode, error: json }); + } else { + resolve({ status: res.statusCode, data: json }); + } + } catch (e) { + resolve({ status: res.statusCode, data: body }); + } + }); + }); + + req.on('error', reject); + req.on('timeout', () => { + req.destroy(); + reject(new Error('Request timeout')); + }); + + if (data) { + req.write(JSON.stringify(data)); + } + + req.end(); + }); +} + +// Retry wrapper +async function requestWithRetry(method, path, data = null, useGodMode = false) { + let lastError; + for (let i = 0; i < CONFIG.MAX_RETRIES; i++) { + try { + return await request(method, path, data, useGodMode); + } catch (err) { + lastError = err; + console.error(`Attempt ${i + 1} failed:`, err.message || err); + if (i < CONFIG.MAX_RETRIES - 1) { + await new Promise(r => setTimeout(r, CONFIG.RETRY_DELAY * (i + 1))); + } + } + } + throw lastError; +} + +// ============================================================================ +// API METHODS +// ============================================================================ + +const API = { + // Health check + async health() { + return requestWithRetry('GET', '/server/health'); + }, + + // List all collections + async collections() { + return requestWithRetry('GET', '/collections'); + }, + + // Get collection schema + async schema(collection) { + if (collection) { + return requestWithRetry('GET', `/collections/${collection}`); + } + return requestWithRetry('GET', '/schema/snapshot', null, true); + }, + + // Read items from collection + async readItems(collection, options = {}) { + const params = new URLSearchParams(); + if (options.filter) params.set('filter', JSON.stringify(options.filter)); + if (options.fields) params.set('fields', options.fields.join(',')); + if (options.limit) params.set('limit', options.limit); + if (options.offset) params.set('offset', options.offset); + if (options.sort) params.set('sort', options.sort); + + const query = params.toString() ? `?${params}` : ''; + return requestWithRetry('GET', `/items/${collection}${query}`); + }, + + // Create item + async createItem(collection, data) { + return requestWithRetry('POST', `/items/${collection}`, data); + }, + + // Update item + async updateItem(collection, id, data) { + return requestWithRetry('PATCH', `/items/${collection}/${id}`, data); + }, + + // Delete item + async deleteItem(collection, id) { + return requestWithRetry('DELETE', `/items/${collection}/${id}`); + }, + + // Bulk create + async bulkCreate(collection, items) { + return requestWithRetry('POST', `/items/${collection}`, items); + }, + + // God Mode: Create collection + async godCreateCollection(schema) { + return requestWithRetry('POST', '/god/schema/collections/create', schema, true); + }, + + // God Mode: Create relation + async godCreateRelation(relation) { + return requestWithRetry('POST', '/god/schema/relations/create', relation, true); + }, + + // God Mode: Bulk insert + async godBulkInsert(collection, items) { + return requestWithRetry('POST', '/god/data/bulk-insert', { collection, items }, true); + }, + + // Aggregate query + async aggregate(collection, options = {}) { + const params = new URLSearchParams(); + if (options.aggregate) params.set('aggregate', JSON.stringify(options.aggregate)); + if (options.groupBy) params.set('groupBy', options.groupBy.join(',')); + if (options.filter) params.set('filter', JSON.stringify(options.filter)); + + return requestWithRetry('GET', `/items/${collection}?${params}`); + } +}; + +// ============================================================================ +// CLI INTERFACE +// ============================================================================ + +async function main() { + const args = process.argv.slice(2); + const command = args[0]; + + if (!command) { + console.log(` +SPARK GOD MODE CLI +================== +Commands: + health Check API health + collections List all collections + schema [coll] Export schema (or single collection) + read Read items from collection + count Count items in collection + insert Create item (pipe JSON via stdin) + +Environment Variables: + DIRECTUS_URL API endpoint (default: https://spark.jumpstartscaling.com) + ADMIN_TOKEN Directus admin token + GOD_MODE_TOKEN Elevated access token + `); + return; + } + + try { + let result; + + switch (command) { + case 'health': + result = await API.health(); + console.log('✅ API Health:', result.data); + break; + + case 'collections': + result = await API.collections(); + console.log('📦 Collections:'); + if (result.data?.data) { + result.data.data.forEach(c => console.log(` - ${c.collection}`)); + } + break; + + case 'schema': + result = await API.schema(args[1]); + console.log(JSON.stringify(result.data, null, 2)); + break; + + case 'read': + if (!args[1]) { + console.error('Usage: read '); + process.exit(1); + } + result = await API.readItems(args[1], { limit: 100 }); + console.log(JSON.stringify(result.data, null, 2)); + break; + + case 'count': + if (!args[1]) { + console.error('Usage: count '); + process.exit(1); + } + result = await API.aggregate(args[1], { aggregate: { count: '*' } }); + console.log(`📊 ${args[1]}: ${result.data?.data?.[0]?.count || 0} items`); + break; + + case 'insert': + if (!args[1]) { + console.error('Usage: echo \'{"key":"value"}\' | node god-mode.js insert '); + process.exit(1); + } + // Read from stdin + let input = ''; + for await (const chunk of process.stdin) { + input += chunk; + } + const data = JSON.parse(input); + result = await API.createItem(args[1], data); + console.log('✅ Created:', result.data); + break; + + default: + console.error(`Unknown command: ${command}`); + process.exit(1); + } + } catch (err) { + console.error('❌ Error:', err.error || err.message || err); + process.exit(1); + } +} + +// ============================================================================ +// EXPORTS (For programmatic use) +// ============================================================================ + +module.exports = { API, CONFIG, request, requestWithRetry }; + +// Run CLI if executed directly +if (require.main === module) { + main().catch(console.error); +}