spaps
Version:
Sweet Potato Authentication & Payment Service CLI - Zero-config local development with built-in admin middleware and permission utilities
175 lines (172 loc) ⢠7.26 kB
JavaScript
const chalk = require('chalk');
const fs = require('fs');
const { DEFAULT_PORT } = require('./config');
const { handleError } = require('./error-handler');
const { showInteractiveHelp, showQuickHelp } = require('./help-system');
const { showInteractiveDocs, showQuickReference, searchDocs } = require('./docs-system');
const { getQuickStartInstructions, getServerStatus, runQuickTest } = require('./ai-helper');
const { buildToolSpec } = require('./ai-tool-spec');
const { runDoctor } = require('./doctor');
function createHandlers(version, logo) {
return {
local: async ({ options }) => {
const isJson = options.json;
if (!isJson) console.log(logo);
try {
const LocalServer = require('./local-server.js');
const server = new LocalServer({ port: options.port, json: isJson, stripeMode: options.stripe, seedMode: options.seed });
if (isJson) {
await server.start();
console.log(JSON.stringify({
success: true,
command: 'local',
server: {
url: `http://localhost:${options.port}`,
docs: `http://localhost:${options.port}/docs`,
mode: 'local-development',
port: Number(options.port),
features: { autoAuth: true, corsEnabled: true, testUsers: ['user', 'admin', 'premium'], apiKeyRequired: false, stripeMode: options.stripe, seeded: options.seed }
}
}));
} else {
await server.start();
if (options.open) {
const { exec } = require('child_process');
const url = `http://localhost:${options.port}/docs`;
const start = process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'start' : 'xdg-open';
exec(`${start} ${url}`);
}
}
process.on('SIGINT', () => {
if (!isJson) console.log(chalk.yellow('\nš Shutting down SPAPS local server...'));
process.exit(0);
});
} catch (error) {
handleError(error, { port: options.port, command: 'local' }, { json: isJson });
}
},
quickstart: async ({ options }) => {
const instructions = getQuickStartInstructions(options.port);
if (options.json) {
console.log(JSON.stringify(instructions, null, 2));
} else {
console.log(chalk.yellow('\nš SPAPS Quick Start Instructions\n'));
console.log('1. Install SDK: npm install spaps-sdk');
console.log('2. Create test file with the code above');
console.log('3. Run: node test-spaps.js');
console.log('\nFor JSON output: npx spaps quickstart --json');
}
},
status: async ({ options }) => {
const status = await getServerStatus(options.port);
if (options.json) {
console.log(JSON.stringify(status));
} else {
if (!status.running) {
console.log(chalk.red('\nā SPAPS server is not running'));
console.log('Start it with:');
console.log(chalk.cyan(` npx spaps local --port ${options.port}`));
console.log();
} else {
console.log(chalk.green('\nā
SPAPS server is running!\n'));
console.log(' URL:', chalk.cyan(status.url));
console.log(' Docs:', chalk.cyan(status.docs));
console.log();
}
}
},
test: async ({ options }) => {
const result = await runQuickTest(options.port);
console.log(JSON.stringify(result, null, 2));
},
init: async ({ options }) => {
const isJson = options.json;
const envContent = `# SPAPS Local Development\nSPAPS_API_URL=http://localhost:${DEFAULT_PORT}\n# SPAPS_API_KEY=your-api-key-here\n`;
const result = { success: true, command: 'init', files_created: [], files_skipped: [], next_steps: ['npx spaps local', 'npm install @spaps/sdk', 'Start coding!'] };
if (!fs.existsSync('.env.local')) {
fs.writeFileSync('.env.local', envContent);
result.files_created.push('.env.local');
if (!isJson) console.log(chalk.green('ā
Created .env.local'));
} else {
result.files_skipped.push('.env.local');
result.message = '.env.local already exists';
if (!isJson) console.log(chalk.yellow('ā ļø .env.local already exists'));
}
if (isJson) {
console.log(JSON.stringify(result));
} else {
console.log();
console.log(chalk.green('⨠SPAPS initialized!'));
console.log();
console.log('Next steps:');
console.log(chalk.cyan(' 1. Run: npx spaps local'));
console.log(chalk.cyan(' 2. Install SDK: npm install @spaps/sdk'));
console.log(chalk.cyan(' 3. Start coding!'));
}
},
create: () => {
console.log(chalk.yellow('š SPAPS'));
console.log(chalk.yellow(`š§ 'spaps create' coming in v0.3.0!`));
console.log();
console.log('For now, check out our examples:');
console.log(chalk.cyan(' https://github.com/yourusername/sweet-potato/tree/main/examples'));
},
types: () => {
console.log(chalk.yellow('š SPAPS'));
console.log(chalk.yellow(`š§ 'spaps types' coming in v0.4.0!`));
},
help: async ({ options }) => {
if (options.interactive) {
await showInteractiveHelp();
} else if (options.quick) {
showQuickHelp();
} else {
showQuickHelp();
}
},
docs: async ({ options }) => {
if (options.search) {
const results = searchDocs(options.search);
if (options.json) {
console.log(JSON.stringify({ results }, null, 2));
} else {
console.log(chalk.yellow(`\nš Search results for "${options.search}":\n`));
if (results.length === 0) {
console.log(chalk.gray(' No results found'));
} else {
results.forEach((result, i) => {
console.log(chalk.green(` ${i + 1}. ${result.title}`));
console.log(chalk.gray(` ${result.preview}`));
console.log();
});
}
console.log(chalk.blue(' Run: npx spaps docs --interactive'));
console.log(chalk.blue(' to browse full documentation\n'));
}
} else if (options.interactive) {
await showInteractiveDocs();
} else {
showQuickReference();
}
},
tools: async ({ options }) => {
const spec = buildToolSpec({ format: options.format || 'openai', port: options.port });
if (options.json) {
console.log(JSON.stringify(spec, null, 2));
} else {
console.log(chalk.yellow('\nš SPAPS AI Tool Spec (OpenAI-style)\n'));
console.log('Base URL:', spec.base_url);
console.log('Tools:');
spec.tools.forEach((t, i) => {
console.log(chalk.green(` ${i + 1}. ${t.name}`), '-', t.description);
console.log(chalk.gray(` ${t.method} ${t.path}`));
});
console.log('\nTip: npx spaps tools --json > spaps-tools.json');
}
},
doctor: async ({ options }) => {
await runDoctor({ port: options.port || DEFAULT_PORT, stripe: options.stripe || null, json: options.json });
}
};
}
module.exports = { createHandlers };