spaps 0.5.0 ā 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AI_TOOLS.json +114 -0
- package/README.md +204 -38
- package/bin/spaps.js +5 -312
- package/package.json +10 -6
- package/src/ai-helper.js +20 -20
- package/src/ai-tool-spec.js +298 -0
- package/src/cli-dispatcher.js +233 -0
- package/src/config.js +5 -0
- package/src/docs-html.js +3 -2
- package/src/docs-system.js +78 -129
- package/src/doctor.js +217 -0
- package/src/handlers.js +174 -0
- package/src/help-system.js +5 -3
- package/src/local-server.js +181 -16
package/bin/spaps.js
CHANGED
|
@@ -2,20 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* SPAPS CLI - Sweet Potato Authentication & Payment Service
|
|
5
|
-
*
|
|
6
|
-
* This is a minimal implementation to secure the npm package name.
|
|
7
|
-
* Full implementation coming soon!
|
|
8
5
|
*/
|
|
9
6
|
|
|
10
7
|
const chalk = require('chalk');
|
|
11
|
-
const { program } = require('commander');
|
|
12
|
-
const { spawn } = require('child_process');
|
|
13
|
-
const path = require('path');
|
|
14
8
|
const fs = require('fs');
|
|
15
|
-
const {
|
|
16
|
-
const {
|
|
17
|
-
const { showInteractiveDocs, showQuickReference, searchDocs } = require('../src/docs-system');
|
|
18
|
-
const { getQuickStartInstructions, getServerStatus, runQuickTest } = require('../src/ai-helper');
|
|
9
|
+
const { buildProgram } = require('../src/cli-dispatcher');
|
|
10
|
+
const { createHandlers } = require('../src/handlers');
|
|
19
11
|
|
|
20
12
|
const version = require('../package.json').version;
|
|
21
13
|
|
|
@@ -24,307 +16,8 @@ const logo = `
|
|
|
24
16
|
${chalk.yellow('š SPAPS')} - Sweet Potato Authentication & Payment Service
|
|
25
17
|
`;
|
|
26
18
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
.description('CLI for Sweet Potato Authentication & Payment Service')
|
|
30
|
-
.version(version)
|
|
31
|
-
.option('--json', 'Output in JSON format for machine parsing');
|
|
32
|
-
|
|
33
|
-
// Local command - Start local development server
|
|
34
|
-
program
|
|
35
|
-
.command('local')
|
|
36
|
-
.description('Start local SPAPS server (no API keys required!)')
|
|
37
|
-
.option('-p, --port <port>', 'Port to run on', '3456')
|
|
38
|
-
.option('-o, --open', 'Open browser automatically', false)
|
|
39
|
-
.option('--json', 'Output in JSON format')
|
|
40
|
-
.action(async (options, command) => {
|
|
41
|
-
const isJson = options.json || command.parent.opts().json;
|
|
42
|
-
|
|
43
|
-
if (!isJson) {
|
|
44
|
-
console.log(logo);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
try {
|
|
48
|
-
// Import and start the local server
|
|
49
|
-
const LocalServer = require('../src/local-server.js');
|
|
50
|
-
const server = new LocalServer({ port: options.port, json: isJson });
|
|
51
|
-
|
|
52
|
-
if (isJson) {
|
|
53
|
-
// For JSON output, start server and return immediately
|
|
54
|
-
await server.start();
|
|
55
|
-
console.log(JSON.stringify({
|
|
56
|
-
success: true,
|
|
57
|
-
command: 'local',
|
|
58
|
-
server: {
|
|
59
|
-
url: `http://localhost:${options.port}`,
|
|
60
|
-
docs: `http://localhost:${options.port}/docs`,
|
|
61
|
-
mode: 'local-development',
|
|
62
|
-
port: parseInt(options.port),
|
|
63
|
-
features: {
|
|
64
|
-
autoAuth: true,
|
|
65
|
-
corsEnabled: true,
|
|
66
|
-
testUsers: ['user', 'admin', 'premium'],
|
|
67
|
-
apiKeyRequired: false
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}));
|
|
71
|
-
} else {
|
|
72
|
-
await server.start();
|
|
73
|
-
|
|
74
|
-
// Open browser if requested
|
|
75
|
-
if (options.open) {
|
|
76
|
-
const { exec } = require('child_process');
|
|
77
|
-
const url = `http://localhost:${options.port}/docs`;
|
|
78
|
-
const start = process.platform === 'darwin' ? 'open' :
|
|
79
|
-
process.platform === 'win32' ? 'start' : 'xdg-open';
|
|
80
|
-
exec(`${start} ${url}`);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// Keep process running
|
|
85
|
-
process.on('SIGINT', () => {
|
|
86
|
-
if (!isJson) {
|
|
87
|
-
console.log(chalk.yellow('\nš Shutting down SPAPS local server...'));
|
|
88
|
-
}
|
|
89
|
-
process.exit(0);
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
} catch (error) {
|
|
93
|
-
handleError(error, { port: options.port, command: 'local' }, { json: isJson });
|
|
94
|
-
}
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
// Quickstart command - For AI agents
|
|
98
|
-
program
|
|
99
|
-
.command('quickstart')
|
|
100
|
-
.description('Get quick start instructions (for AI agents)')
|
|
101
|
-
.option('-p, --port <port>', 'Port to check', '3300')
|
|
102
|
-
.option('--json', 'Output in JSON format')
|
|
103
|
-
.action(async (options) => {
|
|
104
|
-
const instructions = getQuickStartInstructions(options.port);
|
|
105
|
-
|
|
106
|
-
if (options.json === true) {
|
|
107
|
-
console.log(JSON.stringify(instructions, null, 2));
|
|
108
|
-
process.exit(0);
|
|
109
|
-
} else {
|
|
110
|
-
console.log(chalk.yellow('\nš SPAPS Quick Start Instructions\n'));
|
|
111
|
-
console.log('1. Install SDK: npm install spaps-sdk');
|
|
112
|
-
console.log('2. Create test file with the code above');
|
|
113
|
-
console.log('3. Run: node test-spaps.js');
|
|
114
|
-
console.log('\nFor JSON output: npx spaps quickstart --json');
|
|
115
|
-
}
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
// Status command - Check if server is running
|
|
119
|
-
program
|
|
120
|
-
.command('status')
|
|
121
|
-
.description('Check if SPAPS server is running')
|
|
122
|
-
.option('-p, --port <port>', 'Port to check', '3300')
|
|
123
|
-
.option('--json', 'Output in JSON format')
|
|
124
|
-
.action(async (options) => {
|
|
125
|
-
const status = await getServerStatus(options.port);
|
|
126
|
-
|
|
127
|
-
if (options.json) {
|
|
128
|
-
console.log(JSON.stringify(status));
|
|
129
|
-
} else {
|
|
130
|
-
if (status.running) {
|
|
131
|
-
console.log(chalk.green(`ā
SPAPS is running on port ${options.port}`));
|
|
132
|
-
console.log(chalk.blue(` URL: ${status.url}`));
|
|
133
|
-
console.log(chalk.blue(` Docs: ${status.docs}`));
|
|
134
|
-
} else {
|
|
135
|
-
console.log(chalk.red(`ā SPAPS is not running on port ${options.port}`));
|
|
136
|
-
console.log(chalk.yellow(` Start with: ${status.start_command}`));
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
// Test command - Run quick tests
|
|
142
|
-
program
|
|
143
|
-
.command('test')
|
|
144
|
-
.description('Run quick tests to verify SPAPS is working')
|
|
145
|
-
.option('-p, --port <port>', 'Port to test', '3300')
|
|
146
|
-
.option('--json', 'Output in JSON format')
|
|
147
|
-
.action(async (options) => {
|
|
148
|
-
const results = await runQuickTest(options.port);
|
|
149
|
-
|
|
150
|
-
if (options.json) {
|
|
151
|
-
console.log(JSON.stringify(results, null, 2));
|
|
152
|
-
} else {
|
|
153
|
-
console.log(chalk.yellow('\nš§Ŗ Running SPAPS Tests...\n'));
|
|
154
|
-
|
|
155
|
-
results.results.forEach(result => {
|
|
156
|
-
const icon = result.success ? 'ā
' : 'ā';
|
|
157
|
-
console.log(`${icon} ${result.test}`);
|
|
158
|
-
if (!result.success && result.fix) {
|
|
159
|
-
console.log(chalk.yellow(` Fix: ${result.fix}`));
|
|
160
|
-
}
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
console.log();
|
|
164
|
-
console.log(results.success ?
|
|
165
|
-
chalk.green(`⨠${results.summary}`) :
|
|
166
|
-
chalk.red(`ā ļø ${results.summary}`)
|
|
167
|
-
);
|
|
168
|
-
|
|
169
|
-
if (results.next_steps) {
|
|
170
|
-
console.log('\nNext steps:');
|
|
171
|
-
results.next_steps.forEach(step => {
|
|
172
|
-
console.log(` ⢠${step}`);
|
|
173
|
-
});
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
});
|
|
177
|
-
|
|
178
|
-
// Init command - Initialize SPAPS in existing project
|
|
179
|
-
program
|
|
180
|
-
.command('init')
|
|
181
|
-
.description('Initialize SPAPS in your project')
|
|
182
|
-
.option('--json', 'Output in JSON format')
|
|
183
|
-
.action((options, command) => {
|
|
184
|
-
const isJson = options.json || command.parent.opts().json;
|
|
185
|
-
|
|
186
|
-
if (!isJson) {
|
|
187
|
-
console.log(logo);
|
|
188
|
-
console.log(chalk.green('š§ Initializing SPAPS...'));
|
|
189
|
-
console.log();
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
// Create minimal .env.local
|
|
193
|
-
const envContent = `# SPAPS Local Development Configuration
|
|
194
|
-
# No API keys needed for local development!
|
|
195
|
-
|
|
196
|
-
SPAPS_API_URL=http://localhost:3300
|
|
197
|
-
NODE_ENV=development
|
|
198
|
-
|
|
199
|
-
# When you're ready for production:
|
|
200
|
-
# SPAPS_API_KEY=your-api-key-here
|
|
201
|
-
`;
|
|
202
|
-
|
|
203
|
-
const result = {
|
|
204
|
-
success: true,
|
|
205
|
-
command: 'init',
|
|
206
|
-
files_created: [],
|
|
207
|
-
files_skipped: [],
|
|
208
|
-
next_steps: [
|
|
209
|
-
'npx spaps local',
|
|
210
|
-
'npm install @spaps/sdk',
|
|
211
|
-
'Start coding!'
|
|
212
|
-
]
|
|
213
|
-
};
|
|
214
|
-
|
|
215
|
-
if (!fs.existsSync('.env.local')) {
|
|
216
|
-
fs.writeFileSync('.env.local', envContent);
|
|
217
|
-
result.files_created.push('.env.local');
|
|
218
|
-
if (!isJson) {
|
|
219
|
-
console.log(chalk.green('ā
Created .env.local'));
|
|
220
|
-
}
|
|
221
|
-
} else {
|
|
222
|
-
result.files_skipped.push('.env.local');
|
|
223
|
-
result.message = '.env.local already exists';
|
|
224
|
-
if (!isJson) {
|
|
225
|
-
console.log(chalk.yellow('ā ļø .env.local already exists'));
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
if (isJson) {
|
|
230
|
-
console.log(JSON.stringify(result));
|
|
231
|
-
} else {
|
|
232
|
-
console.log();
|
|
233
|
-
console.log(chalk.green('⨠SPAPS initialized!'));
|
|
234
|
-
console.log();
|
|
235
|
-
console.log('Next steps:');
|
|
236
|
-
console.log(chalk.cyan(' 1. Run: npx spaps local'));
|
|
237
|
-
console.log(chalk.cyan(' 2. Install SDK: npm install @spaps/sdk'));
|
|
238
|
-
console.log(chalk.cyan(' 3. Start coding!'));
|
|
239
|
-
}
|
|
240
|
-
});
|
|
241
|
-
|
|
242
|
-
// Create command (placeholder)
|
|
243
|
-
program
|
|
244
|
-
.command('create <name>')
|
|
245
|
-
.description('Create a new project with SPAPS (coming soon)')
|
|
246
|
-
.action((name) => {
|
|
247
|
-
console.log(logo);
|
|
248
|
-
console.log(chalk.yellow(`š§ 'spaps create' coming in v0.3.0!`));
|
|
249
|
-
console.log();
|
|
250
|
-
console.log('For now, check out our examples:');
|
|
251
|
-
console.log(chalk.cyan(' https://github.com/yourusername/sweet-potato/tree/main/examples'));
|
|
252
|
-
});
|
|
253
|
-
|
|
254
|
-
// Types command (placeholder)
|
|
255
|
-
program
|
|
256
|
-
.command('types')
|
|
257
|
-
.description('Generate TypeScript types (coming soon)')
|
|
258
|
-
.action(() => {
|
|
259
|
-
console.log(logo);
|
|
260
|
-
console.log(chalk.yellow(`š§ 'spaps types' coming in v0.4.0!`));
|
|
261
|
-
});
|
|
262
|
-
|
|
263
|
-
// Help command - Interactive help system
|
|
264
|
-
program
|
|
265
|
-
.command('help')
|
|
266
|
-
.description('Show help and guides')
|
|
267
|
-
.option('-i, --interactive', 'Interactive help mode')
|
|
268
|
-
.option('-q, --quick', 'Quick reference')
|
|
269
|
-
.action(async (options) => {
|
|
270
|
-
if (options.interactive) {
|
|
271
|
-
await showInteractiveHelp();
|
|
272
|
-
} else if (options.quick) {
|
|
273
|
-
showQuickHelp();
|
|
274
|
-
} else {
|
|
275
|
-
// Default to quick help
|
|
276
|
-
showQuickHelp();
|
|
277
|
-
}
|
|
278
|
-
});
|
|
279
|
-
|
|
280
|
-
// Docs command - SDK documentation
|
|
281
|
-
program
|
|
282
|
-
.command('docs')
|
|
283
|
-
.description('Browse SDK documentation')
|
|
284
|
-
.option('-i, --interactive', 'Interactive documentation browser')
|
|
285
|
-
.option('-s, --search <query>', 'Search documentation')
|
|
286
|
-
.option('--json', 'Output in JSON format')
|
|
287
|
-
.action(async (options) => {
|
|
288
|
-
if (options.search) {
|
|
289
|
-
const results = searchDocs(options.search);
|
|
290
|
-
|
|
291
|
-
if (options.json) {
|
|
292
|
-
console.log(JSON.stringify({ results }, null, 2));
|
|
293
|
-
} else {
|
|
294
|
-
console.log(chalk.yellow(`\nš Search results for "${options.search}":\n`));
|
|
295
|
-
|
|
296
|
-
if (results.length === 0) {
|
|
297
|
-
console.log(chalk.gray(' No results found'));
|
|
298
|
-
} else {
|
|
299
|
-
results.forEach((result, i) => {
|
|
300
|
-
console.log(chalk.green(` ${i + 1}. ${result.title}`));
|
|
301
|
-
console.log(chalk.gray(` ${result.preview}`));
|
|
302
|
-
console.log();
|
|
303
|
-
});
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
console.log(chalk.blue(' Run: npx spaps docs --interactive'));
|
|
307
|
-
console.log(chalk.blue(' to browse full documentation\n'));
|
|
308
|
-
}
|
|
309
|
-
} else if (options.interactive) {
|
|
310
|
-
await showInteractiveDocs();
|
|
311
|
-
} else {
|
|
312
|
-
// Default to quick reference
|
|
313
|
-
showQuickReference();
|
|
314
|
-
}
|
|
315
|
-
});
|
|
316
|
-
|
|
317
|
-
// Help command enhancement
|
|
318
|
-
program.on('--help', () => {
|
|
319
|
-
console.log();
|
|
320
|
-
console.log('Examples:');
|
|
321
|
-
console.log();
|
|
322
|
-
console.log(' $ spaps local # Start local dev server');
|
|
323
|
-
console.log(' $ spaps init # Initialize in current project');
|
|
324
|
-
console.log(' $ spaps create my-app # Create new project (soon)');
|
|
325
|
-
console.log();
|
|
326
|
-
console.log('Learn more at https://sweetpotato.dev');
|
|
327
|
-
});
|
|
19
|
+
const handlers = createHandlers(version, logo);
|
|
20
|
+
const program = buildProgram({ handlers, dryRun: false, version, logo });
|
|
328
21
|
|
|
329
22
|
// Show help if no command provided
|
|
330
23
|
if (!process.argv.slice(2).length) {
|
|
@@ -334,4 +27,4 @@ if (!process.argv.slice(2).length) {
|
|
|
334
27
|
console.log(chalk.yellow('š” Try: npx spaps help --interactive'));
|
|
335
28
|
}
|
|
336
29
|
|
|
337
|
-
program.parse(process.argv);
|
|
30
|
+
program.parse(process.argv);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "spaps",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.2",
|
|
4
4
|
"description": "Sweet Potato Authentication & Payment Service CLI - Zero-config local development with built-in admin middleware and permission utilities",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -29,24 +29,27 @@
|
|
|
29
29
|
"ethereum"
|
|
30
30
|
],
|
|
31
31
|
"author": "buildooor",
|
|
32
|
-
"license": "
|
|
32
|
+
"license": "UNLICENSED",
|
|
33
33
|
"repository": {
|
|
34
34
|
"type": "git",
|
|
35
|
-
"url": "https://github.com/build000r
|
|
35
|
+
"url": "https://github.com/build000r"
|
|
36
36
|
},
|
|
37
37
|
"bugs": {
|
|
38
|
-
"
|
|
38
|
+
"email": "buildooor@gmail.com"
|
|
39
39
|
},
|
|
40
|
-
"homepage": "https://
|
|
40
|
+
"homepage": "https://www.buildooor.com/services",
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"axios": "^1.6.0",
|
|
43
43
|
"chalk": "^4.1.2",
|
|
44
44
|
"commander": "^11.1.0",
|
|
45
45
|
"cors": "^2.8.5",
|
|
46
46
|
"express": "^4.18.2",
|
|
47
|
+
"js-yaml": "^4.1.0",
|
|
48
|
+
"swagger-ui-dist": "^5.17.14",
|
|
47
49
|
"ora": "^5.4.1",
|
|
48
50
|
"prompts": "^2.4.2",
|
|
49
|
-
"stripe": "^18.5.0"
|
|
51
|
+
"stripe": "^18.5.0",
|
|
52
|
+
"uuid": "^8.3.2"
|
|
50
53
|
},
|
|
51
54
|
"engines": {
|
|
52
55
|
"node": ">=16.0.0"
|
|
@@ -54,6 +57,7 @@
|
|
|
54
57
|
"files": [
|
|
55
58
|
"bin",
|
|
56
59
|
"src",
|
|
60
|
+
"AI_TOOLS.json",
|
|
57
61
|
"client.js",
|
|
58
62
|
"README.md"
|
|
59
63
|
]
|
package/src/ai-helper.js
CHANGED
|
@@ -5,7 +5,9 @@
|
|
|
5
5
|
|
|
6
6
|
const chalk = require('chalk');
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
const { DEFAULT_PORT } = require('./config');
|
|
9
|
+
|
|
10
|
+
function getQuickStartInstructions(port = DEFAULT_PORT) {
|
|
9
11
|
return {
|
|
10
12
|
success: true,
|
|
11
13
|
instructions: {
|
|
@@ -17,22 +19,20 @@ function getQuickStartInstructions(port = 3300) {
|
|
|
17
19
|
step2: {
|
|
18
20
|
description: "Create test file",
|
|
19
21
|
filename: "test-spaps.js",
|
|
20
|
-
content: `const {
|
|
22
|
+
content: `const { SweetPotatoSDK } = require('spaps-sdk');
|
|
21
23
|
|
|
22
24
|
async function test() {
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
console.log('ā
Login successful:', data.user.email);
|
|
30
|
-
|
|
25
|
+
const sdk = new SweetPotatoSDK({ apiUrl: 'http://localhost:${port}' });
|
|
26
|
+
|
|
27
|
+
// Test email/password auth (local mode accepts any credentials)
|
|
28
|
+
const auth = await sdk.auth.signInWithPassword({ email: 'test@example.com', password: 'password' });
|
|
29
|
+
console.log('ā
Login successful:', auth.user.email);
|
|
30
|
+
|
|
31
31
|
// Test authenticated request
|
|
32
|
-
const user = await
|
|
33
|
-
console.log('ā
Got user:', user.
|
|
34
|
-
|
|
35
|
-
return { success: true, user
|
|
32
|
+
const user = await sdk.auth.getCurrentUser();
|
|
33
|
+
console.log('ā
Got user:', user.email);
|
|
34
|
+
|
|
35
|
+
return { success: true, user };
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
test().then(console.log).catch(console.error);`
|
|
@@ -70,9 +70,9 @@ test().then(console.log).catch(console.error);`
|
|
|
70
70
|
},
|
|
71
71
|
{
|
|
72
72
|
method: "POST",
|
|
73
|
-
path: "/api/stripe/
|
|
74
|
-
body: { price_id: "string", success_url: "string" },
|
|
75
|
-
response: {
|
|
73
|
+
path: "/api/stripe/checkout-sessions",
|
|
74
|
+
body: { price_id: "string", success_url: "string", cancel_url: "string" },
|
|
75
|
+
response: { id: "string", url: "string", status: "string" }
|
|
76
76
|
},
|
|
77
77
|
{
|
|
78
78
|
method: "GET",
|
|
@@ -84,12 +84,12 @@ test().then(console.log).catch(console.error);`
|
|
|
84
84
|
test_commands: {
|
|
85
85
|
health_check: `curl http://localhost:${port}/health`,
|
|
86
86
|
login: `curl -X POST http://localhost:${port}/api/auth/login -H "Content-Type: application/json" -d '{"email":"test@example.com","password":"password"}'`,
|
|
87
|
-
with_sdk: `node -e "const {
|
|
87
|
+
with_sdk: `node -e "const {SweetPotatoSDK}=require('spaps-sdk');const sdk=new SweetPotatoSDK({apiUrl:'http://localhost:${port}'});sdk.auth.signInWithPassword({email:'test@example.com',password:'password'}).then(r=>console.log(JSON.stringify(r.user))).catch(console.error)"`
|
|
88
88
|
}
|
|
89
89
|
};
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
-
function getServerStatus(port =
|
|
92
|
+
function getServerStatus(port = DEFAULT_PORT) {
|
|
93
93
|
const http = require('http');
|
|
94
94
|
|
|
95
95
|
return new Promise((resolve) => {
|
|
@@ -270,4 +270,4 @@ module.exports = {
|
|
|
270
270
|
getQuickStartInstructions,
|
|
271
271
|
getServerStatus,
|
|
272
272
|
runQuickTest
|
|
273
|
-
};
|
|
273
|
+
};
|