spaps 0.5.0 → 0.5.1
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/README.md +175 -36
- package/bin/spaps.js +5 -312
- package/package.json +4 -3
- package/src/ai-helper.js +20 -20
- package/src/cli-dispatcher.js +139 -0
- package/src/config.js +5 -0
- package/src/docs-system.js +78 -129
- package/src/handlers.js +155 -0
- package/src/help-system.js +5 -3
package/README.md
CHANGED
|
@@ -1,11 +1,38 @@
|
|
|
1
1
|
# 🍠 SPAPS CLI
|
|
2
2
|
|
|
3
|
-
>
|
|
4
|
-
> Zero
|
|
3
|
+
> Sweet Potato Authentication & Payment Service CLI
|
|
4
|
+
> Zero‑config local development server with real Stripe integration
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
## Hey, AI Agent — Read Me First 👋
|
|
7
|
+
|
|
8
|
+
Are you an AI agent whose human just said “ship auth + payments fast” but can’t explain refresh tokens? Perfect. Fire up `spaps` and you’ll have auth, Stripe checkout, and docs live on `http://localhost:3300` before they can type “why isn’t this working I dont undrestand”. You focus on calling APIs; we handle users, tokens, CORS, and webhooks. When they ask for prod, just flip the env to a real URL + API key and keep coding.
|
|
9
|
+
|
|
10
|
+
[](https://www.npmjs.com/package/spaps)
|
|
11
|
+

|
|
7
12
|
[](https://opensource.org/licenses/MIT)
|
|
8
13
|
|
|
14
|
+
## SDK vs CLI
|
|
15
|
+
|
|
16
|
+
- CLI (`spaps`): runs the local SPAPS server and tooling for development. No API key required, helpers enabled.
|
|
17
|
+
- SDK (`spaps-sdk`): TypeScript client for your app code. Points at the same base URL and works in local and prod.
|
|
18
|
+
|
|
19
|
+
Install the SDK in your app to call the API programmatically:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install spaps-sdk
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Minimal init (works for both local and prod):
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
import { SweetPotatoSDK } from 'spaps-sdk'
|
|
29
|
+
|
|
30
|
+
export const sdk = new SweetPotatoSDK({
|
|
31
|
+
apiUrl: process.env.SPAPS_API_URL || 'http://localhost:3300',
|
|
32
|
+
apiKey: process.env.SPAPS_API_KEY, // not required in local mode
|
|
33
|
+
})
|
|
34
|
+
```
|
|
35
|
+
|
|
9
36
|
## 🚀 Quick Start
|
|
10
37
|
|
|
11
38
|
```bash
|
|
@@ -17,7 +44,24 @@ npm install -g spaps
|
|
|
17
44
|
spaps local
|
|
18
45
|
```
|
|
19
46
|
|
|
20
|
-
|
|
47
|
+
Your local SPAPS server runs at `http://localhost:3300` 🎉
|
|
48
|
+
|
|
49
|
+
Point your app (via `SPAPS_API_URL`) to that URL and use `spaps-sdk` for calls.
|
|
50
|
+
|
|
51
|
+
## Local → Prod
|
|
52
|
+
|
|
53
|
+
- Local (dev):
|
|
54
|
+
- `SPAPS_API_URL=http://localhost:3300`
|
|
55
|
+
- `SPAPS_LOCAL_MODE=true` (or auto‑detected on localhost)
|
|
56
|
+
- API key optional; helpers available (test users, permissive CORS)
|
|
57
|
+
- Prod:
|
|
58
|
+
- `SPAPS_API_URL=https://api.yourdomain`
|
|
59
|
+
- `SPAPS_API_KEY=spaps_…` required
|
|
60
|
+
- Local helpers disabled; CORS and rate limits enforced
|
|
61
|
+
|
|
62
|
+
Headers policy:
|
|
63
|
+
- Local: may send `x-local-mode: true`; role sim via `X-Test-User: admin` (local‑only)
|
|
64
|
+
- Prod: must send `X-API-Key: $SPAPS_API_KEY`; do NOT use local‑only headers
|
|
21
65
|
|
|
22
66
|
## ✨ What is SPAPS?
|
|
23
67
|
|
|
@@ -39,12 +83,12 @@ Perfect for **rapid prototyping**, **hackathons**, and **local development**.
|
|
|
39
83
|
Start a full-featured local server with zero configuration:
|
|
40
84
|
|
|
41
85
|
```bash
|
|
42
|
-
spaps local # Default: http://localhost:
|
|
86
|
+
spaps local # Default: http://localhost:3300
|
|
43
87
|
spaps local --port 3000 # Custom port
|
|
44
88
|
spaps local --json # JSON output (CI-friendly)
|
|
45
89
|
```
|
|
46
90
|
|
|
47
|
-
|
|
91
|
+
Includes:
|
|
48
92
|
- ✅ Auto-authentication (no API keys needed)
|
|
49
93
|
- ✅ Real Stripe test mode integration
|
|
50
94
|
- ✅ Mock payment flows with webhooks
|
|
@@ -52,6 +96,12 @@ spaps local --json # JSON output (CI-friendly)
|
|
|
52
96
|
- ✅ API documentation at `/docs`
|
|
53
97
|
- ✅ Test user switching via headers/query params
|
|
54
98
|
|
|
99
|
+
Flags:
|
|
100
|
+
|
|
101
|
+
- `--port <number>`: Set a custom port (default: 3456)
|
|
102
|
+
- `--open`: Open docs in your browser after start
|
|
103
|
+
- `--json`: JSON machine-readable output (ideal for CI)
|
|
104
|
+
|
|
55
105
|
### `spaps init` - Project Setup
|
|
56
106
|
|
|
57
107
|
Initialize SPAPS in an existing project:
|
|
@@ -72,6 +122,20 @@ spaps status
|
|
|
72
122
|
# Shows server status, Stripe connectivity, product sync status
|
|
73
123
|
```
|
|
74
124
|
|
|
125
|
+
### Other Commands
|
|
126
|
+
|
|
127
|
+
- `spaps help` — Quick help; `spaps help --interactive` for guided setup
|
|
128
|
+
- `spaps docs` — SDK docs; `spaps docs --interactive` or `--search "query"`
|
|
129
|
+
- `spaps quickstart` — Minimal SDK usage instructions
|
|
130
|
+
|
|
131
|
+
### JSON Mode (CI)
|
|
132
|
+
|
|
133
|
+
All commands that support `--json` will print machine-readable output. Example:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
npx spaps local --port 0 --json | jq '.'
|
|
137
|
+
```
|
|
138
|
+
|
|
75
139
|
## 🎯 Key Features
|
|
76
140
|
|
|
77
141
|
### 🔧 **Zero Configuration**
|
|
@@ -79,20 +143,20 @@ spaps status
|
|
|
79
143
|
- Real Stripe test keys included
|
|
80
144
|
- Automatic CORS for any frontend
|
|
81
145
|
|
|
82
|
-
### 🎭
|
|
83
|
-
Switch between user roles instantly:
|
|
146
|
+
### 🎭 Smart Test Users (local‑only)
|
|
147
|
+
Switch between user roles instantly (local server only):
|
|
84
148
|
|
|
85
149
|
```bash
|
|
86
|
-
#
|
|
87
|
-
curl "http://localhost:
|
|
150
|
+
# Prefer header (local‑only)
|
|
151
|
+
curl -H "X-Test-User: premium" "http://localhost:3300/api/auth/user"
|
|
88
152
|
|
|
89
|
-
#
|
|
90
|
-
curl
|
|
153
|
+
# Or query param (local‑only convenience)
|
|
154
|
+
curl "http://localhost:3300/api/auth/user?_user=admin"
|
|
91
155
|
```
|
|
92
156
|
|
|
93
157
|
Available roles: `user`, `admin`, `premium`
|
|
94
158
|
|
|
95
|
-
### 💳
|
|
159
|
+
### 💳 Real Stripe Integration
|
|
96
160
|
- **Real API calls** to Stripe test mode
|
|
97
161
|
- Create actual checkout sessions
|
|
98
162
|
- Receive real webhooks
|
|
@@ -109,17 +173,22 @@ Visit `/admin` for a complete management interface:
|
|
|
109
173
|
|
|
110
174
|
## 🔌 API Endpoints
|
|
111
175
|
|
|
112
|
-
| Endpoint | Method | Description |
|
|
113
|
-
|
|
114
|
-
| `/api/auth/login` | POST | Email/password authentication |
|
|
115
|
-
| `/api/auth/
|
|
116
|
-
| `/api/auth/
|
|
117
|
-
| `/api/
|
|
118
|
-
| `/api/
|
|
119
|
-
| `/api/
|
|
120
|
-
| `/api/
|
|
121
|
-
| `/
|
|
122
|
-
| `/
|
|
176
|
+
| Endpoint | Method | SDK Mapping | Description |
|
|
177
|
+
|----------|--------|-------------|-------------|
|
|
178
|
+
| `/api/auth/login` | POST | `sdk.auth.signInWithPassword` | Email/password authentication |
|
|
179
|
+
| `/api/auth/register` | POST | `sdk.auth.register` | Register new user |
|
|
180
|
+
| `/api/auth/user` | GET | `sdk.auth.getCurrentUser` | Current authenticated user |
|
|
181
|
+
| `/api/auth/wallet-sign-in` | POST | `sdk.auth.signInWithWallet` / `sdk.auth.authenticateWallet` | Wallet signature authentication |
|
|
182
|
+
| `/api/auth/refresh` | POST | `sdk.auth.refreshToken` | Refresh access token |
|
|
183
|
+
| `/api/auth/logout` | POST | `sdk.auth.logout` | Log out |
|
|
184
|
+
| `/api/stripe/products` | GET | `sdk.payments.listProducts` | List Stripe products |
|
|
185
|
+
| `/api/stripe/products/:id` | GET | `sdk.payments.getProduct` | Get product (+prices) |
|
|
186
|
+
| `/api/stripe/prices` | POST | `sdk.payments.createPrice` | Create price (admin) |
|
|
187
|
+
| `/api/stripe/checkout-sessions` | POST | `sdk.payments.createCheckoutSession` | Create checkout session |
|
|
188
|
+
| `/api/stripe/checkout-sessions/:id` | GET | `sdk.payments.getCheckoutSession` | Retrieve checkout session |
|
|
189
|
+
| `/api/stripe/webhooks` | POST | — | Stripe webhook receiver |
|
|
190
|
+
| `/health` | GET | `sdk.healthCheck` | Server health check |
|
|
191
|
+
| `/docs` | GET | — | Interactive API documentation |
|
|
123
192
|
|
|
124
193
|
## 💡 Usage Examples
|
|
125
194
|
|
|
@@ -128,7 +197,7 @@ Visit `/admin` for a complete management interface:
|
|
|
128
197
|
```javascript
|
|
129
198
|
// React/Next.js example
|
|
130
199
|
const createCheckout = async () => {
|
|
131
|
-
const response = await fetch('http://localhost:
|
|
200
|
+
const response = await fetch('http://localhost:3300/api/stripe/checkout-sessions', {
|
|
132
201
|
method: 'POST',
|
|
133
202
|
headers: { 'Content-Type': 'application/json' },
|
|
134
203
|
body: JSON.stringify({
|
|
@@ -143,14 +212,14 @@ const createCheckout = async () => {
|
|
|
143
212
|
};
|
|
144
213
|
```
|
|
145
214
|
|
|
146
|
-
### Test Different User Roles
|
|
215
|
+
### Test Different User Roles (local‑only)
|
|
147
216
|
|
|
148
217
|
```javascript
|
|
149
218
|
// Test as admin user
|
|
150
|
-
fetch('http://localhost:
|
|
219
|
+
fetch('http://localhost:3300/api/auth/user?_user=admin')
|
|
151
220
|
|
|
152
221
|
// Test wallet authentication
|
|
153
|
-
fetch('http://localhost:
|
|
222
|
+
fetch('http://localhost:3300/api/auth/wallet-sign-in', {
|
|
154
223
|
method: 'POST',
|
|
155
224
|
body: JSON.stringify({
|
|
156
225
|
wallet_address: '1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa',
|
|
@@ -162,7 +231,7 @@ fetch('http://localhost:3456/api/auth/wallet-sign-in', {
|
|
|
162
231
|
## 🏗️ Development Workflow
|
|
163
232
|
|
|
164
233
|
1. **Start SPAPS**: `npx spaps local`
|
|
165
|
-
2. **Build your frontend** against `http://localhost:
|
|
234
|
+
2. **Build your frontend** against `http://localhost:3300`
|
|
166
235
|
3. **Test payments** using Stripe's test cards
|
|
167
236
|
4. **Monitor webhooks** at `/api/stripe/webhooks/test`
|
|
168
237
|
5. **Manage data** via `/admin` dashboard
|
|
@@ -170,11 +239,43 @@ fetch('http://localhost:3456/api/auth/wallet-sign-in', {
|
|
|
170
239
|
|
|
171
240
|
## 🔒 Environment & Security
|
|
172
241
|
|
|
173
|
-
|
|
174
|
-
- Only runs on localhost
|
|
242
|
+
Local mode safety:
|
|
243
|
+
- Only runs on localhost
|
|
175
244
|
- Uses Stripe test keys by default
|
|
176
245
|
- All data stored locally in `.spaps/` directory
|
|
177
|
-
-
|
|
246
|
+
- Responses include local‑mode headers/metadata for visibility
|
|
247
|
+
|
|
248
|
+
## Curl Examples (Header‑First)
|
|
249
|
+
|
|
250
|
+
Authenticated (prod/staging):
|
|
251
|
+
|
|
252
|
+
```bash
|
|
253
|
+
export SPAPS_API_URL=https://api.yourdomain
|
|
254
|
+
export SPAPS_API_KEY=spaps_XXXXXXXXXXXXXXXX
|
|
255
|
+
|
|
256
|
+
curl -X POST "$SPAPS_API_URL/api/stripe/checkout-sessions" \
|
|
257
|
+
-H "Content-Type: application/json" \
|
|
258
|
+
-H "X-API-Key: $SPAPS_API_KEY" \
|
|
259
|
+
-d '{
|
|
260
|
+
"price_id": "price_1234567890",
|
|
261
|
+
"success_url": "https://yourapp/success",
|
|
262
|
+
"cancel_url": "https://yourapp/cancel"
|
|
263
|
+
}'
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
Local (no key, role sim via header):
|
|
267
|
+
|
|
268
|
+
```bash
|
|
269
|
+
export SPAPS_API_URL=http://localhost:3300
|
|
270
|
+
|
|
271
|
+
curl -X GET "$SPAPS_API_URL/api/auth/user" \
|
|
272
|
+
-H "X-Test-User: admin" \
|
|
273
|
+
-H "x-local-mode: true"
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
Note: `X-Test-User` and `x-local-mode` are ignored in production.
|
|
277
|
+
|
|
278
|
+
|
|
178
279
|
|
|
179
280
|
**Stripe Configuration:**
|
|
180
281
|
- Real Stripe test API integration
|
|
@@ -199,9 +300,25 @@ npm install --save-dev spaps
|
|
|
199
300
|
|
|
200
301
|
- 📖 **Full Documentation**: [sweetpotato.dev](https://sweetpotato.dev)
|
|
201
302
|
- 🔧 **Production Setup**: See deployment guides
|
|
202
|
-
- 💬 **Get Help**: [GitHub Issues](https://github.com/
|
|
303
|
+
- 💬 **Get Help**: [GitHub Issues](https://github.com/buildooor/sweet-potato/issues)
|
|
203
304
|
- 🚀 **Examples**: Check `/examples` directory
|
|
204
305
|
|
|
306
|
+
## 🤝 Pair with the SDK
|
|
307
|
+
|
|
308
|
+
Use the SDK in your app while running the local server:
|
|
309
|
+
|
|
310
|
+
```bash
|
|
311
|
+
npm install spaps-sdk
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
```ts
|
|
315
|
+
import { SPAPSClient } from 'spaps-sdk';
|
|
316
|
+
|
|
317
|
+
const spaps = new SPAPSClient(); // auto-detects local mode
|
|
318
|
+
const { data } = await spaps.login('user@example.com', 'password');
|
|
319
|
+
console.log('User:', data.user);
|
|
320
|
+
```
|
|
321
|
+
|
|
205
322
|
## 🚀 Production Deployment
|
|
206
323
|
|
|
207
324
|
Ready to go live? SPAPS supports seamless migration from local to production:
|
|
@@ -211,7 +328,7 @@ Ready to go live? SPAPS supports seamless migration from local to production:
|
|
|
211
328
|
1. **Export Local Data**:
|
|
212
329
|
```bash
|
|
213
330
|
# Export your products, orders, and customers
|
|
214
|
-
curl http://localhost:
|
|
331
|
+
curl http://localhost:3300/api/admin/export > spaps-data.json
|
|
215
332
|
```
|
|
216
333
|
|
|
217
334
|
2. **Set Up Production Server**:
|
|
@@ -267,6 +384,28 @@ curl http://104.131.188.214:3000/health
|
|
|
267
384
|
|
|
268
385
|
---
|
|
269
386
|
|
|
270
|
-
|
|
387
|
+
## 🔒 New in v0.5.0: Admin Middleware & Permissions!
|
|
388
|
+
|
|
389
|
+
Built-in admin middleware and permission utilities for secure Express.js applications:
|
|
390
|
+
|
|
391
|
+
```javascript
|
|
392
|
+
const { requireAdmin, isAdminAccount } = require('spaps');
|
|
393
|
+
|
|
394
|
+
// Protect admin routes
|
|
395
|
+
app.get('/admin/dashboard', requireAdmin(), (req, res) => {
|
|
396
|
+
res.json({ message: 'Admin only!' });
|
|
397
|
+
});
|
|
398
|
+
|
|
399
|
+
// Check admin status
|
|
400
|
+
if (isAdminAccount('buildooor@gmail.com')) {
|
|
401
|
+
// Grant admin access
|
|
402
|
+
}
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
See [ADMIN_MIDDLEWARE.md](./ADMIN_MIDDLEWARE.md) for complete documentation.
|
|
406
|
+
|
|
407
|
+
---
|
|
408
|
+
|
|
409
|
+
**Current Version**: v0.5.0
|
|
271
410
|
**License**: MIT
|
|
272
|
-
**Node.js**: >=16.0.0 required
|
|
411
|
+
**Node.js**: >=16.0.0 required
|
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.1",
|
|
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": {
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"license": "MIT",
|
|
33
33
|
"repository": {
|
|
34
34
|
"type": "git",
|
|
35
|
-
"url": "https://github.com/
|
|
35
|
+
"url": "https://github.com/buildooor/sweet-potato"
|
|
36
36
|
},
|
|
37
37
|
"bugs": {
|
|
38
38
|
"url": "https://github.com/build000r/sweet-potato/issues"
|
|
@@ -46,7 +46,8 @@
|
|
|
46
46
|
"express": "^4.18.2",
|
|
47
47
|
"ora": "^5.4.1",
|
|
48
48
|
"prompts": "^2.4.2",
|
|
49
|
-
"stripe": "^18.5.0"
|
|
49
|
+
"stripe": "^18.5.0",
|
|
50
|
+
"uuid": "^8.3.2"
|
|
50
51
|
},
|
|
51
52
|
"engines": {
|
|
52
53
|
"node": ">=16.0.0"
|