spaps 0.2.0 → 0.2.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/bin/spaps.js CHANGED
@@ -23,7 +23,8 @@ ${chalk.yellow('šŸ  SPAPS')} - Sweet Potato Authentication & Payment Service
23
23
  program
24
24
  .name('spaps')
25
25
  .description('CLI for Sweet Potato Authentication & Payment Service')
26
- .version(version);
26
+ .version(version)
27
+ .option('--json', 'Output in JSON format for machine parsing');
27
28
 
28
29
  // Local command - Start local development server
29
30
  program
@@ -31,45 +32,87 @@ program
31
32
  .description('Start local SPAPS server (no API keys required!)')
32
33
  .option('-p, --port <port>', 'Port to run on', '3300')
33
34
  .option('-o, --open', 'Open browser automatically', false)
34
- .action(async (options) => {
35
- console.log(logo);
35
+ .option('--json', 'Output in JSON format')
36
+ .action(async (options, command) => {
37
+ const isJson = options.json || command.parent.opts().json;
38
+
39
+ if (!isJson) {
40
+ console.log(logo);
41
+ }
36
42
 
37
43
  try {
38
44
  // Import and start the local server
39
45
  const LocalServer = require('../src/local-server.js');
40
- const server = new LocalServer({ port: options.port });
46
+ const server = new LocalServer({ port: options.port, json: isJson });
41
47
 
42
- await server.start();
43
-
44
- // Open browser if requested
45
- if (options.open) {
46
- const { exec } = require('child_process');
47
- const url = `http://localhost:${options.port}/docs`;
48
- const start = process.platform === 'darwin' ? 'open' :
49
- process.platform === 'win32' ? 'start' : 'xdg-open';
50
- exec(`${start} ${url}`);
48
+ if (isJson) {
49
+ // For JSON output, start server and return immediately
50
+ await server.start();
51
+ console.log(JSON.stringify({
52
+ success: true,
53
+ command: 'local',
54
+ server: {
55
+ url: `http://localhost:${options.port}`,
56
+ docs: `http://localhost:${options.port}/docs`,
57
+ mode: 'local-development',
58
+ port: parseInt(options.port),
59
+ features: {
60
+ autoAuth: true,
61
+ corsEnabled: true,
62
+ testUsers: ['user', 'admin', 'premium'],
63
+ apiKeyRequired: false
64
+ }
65
+ }
66
+ }));
67
+ } else {
68
+ await server.start();
69
+
70
+ // Open browser if requested
71
+ if (options.open) {
72
+ const { exec } = require('child_process');
73
+ const url = `http://localhost:${options.port}/docs`;
74
+ const start = process.platform === 'darwin' ? 'open' :
75
+ process.platform === 'win32' ? 'start' : 'xdg-open';
76
+ exec(`${start} ${url}`);
77
+ }
51
78
  }
52
79
 
53
80
  // Keep process running
54
81
  process.on('SIGINT', () => {
55
- console.log(chalk.yellow('\nšŸ‘‹ Shutting down SPAPS local server...'));
82
+ if (!isJson) {
83
+ console.log(chalk.yellow('\nšŸ‘‹ Shutting down SPAPS local server...'));
84
+ }
56
85
  process.exit(0);
57
86
  });
58
87
 
59
88
  } catch (error) {
60
- console.error(chalk.red('āŒ Failed to start server:'), error.message);
61
-
62
- if (error.code === 'MODULE_NOT_FOUND') {
63
- console.log(chalk.yellow('\nšŸ’” Installing dependencies...'));
64
- const { execSync } = require('child_process');
65
- try {
66
- execSync('npm install express cors', {
67
- cwd: path.join(__dirname, '..'),
68
- stdio: 'inherit'
69
- });
70
- console.log(chalk.green('āœ… Dependencies installed! Please run the command again.'));
71
- } catch (installError) {
72
- console.error(chalk.red('Failed to install dependencies. Please run: npm install express cors'));
89
+ if (isJson) {
90
+ console.log(JSON.stringify({
91
+ success: false,
92
+ command: 'local',
93
+ error: {
94
+ message: error.message,
95
+ code: error.code,
96
+ suggestion: error.code === 'EADDRINUSE' ?
97
+ 'Try a different port with --port option' :
98
+ 'Check error message for details'
99
+ }
100
+ }));
101
+ } else {
102
+ console.error(chalk.red('āŒ Failed to start server:'), error.message);
103
+
104
+ if (error.code === 'MODULE_NOT_FOUND') {
105
+ console.log(chalk.yellow('\nšŸ’” Installing dependencies...'));
106
+ const { execSync } = require('child_process');
107
+ try {
108
+ execSync('npm install express cors', {
109
+ cwd: path.join(__dirname, '..'),
110
+ stdio: 'inherit'
111
+ });
112
+ console.log(chalk.green('āœ… Dependencies installed! Please run the command again.'));
113
+ } catch (installError) {
114
+ console.error(chalk.red('Failed to install dependencies. Please run: npm install express cors'));
115
+ }
73
116
  }
74
117
  }
75
118
 
@@ -81,10 +124,15 @@ program
81
124
  program
82
125
  .command('init')
83
126
  .description('Initialize SPAPS in your project')
84
- .action(() => {
85
- console.log(logo);
86
- console.log(chalk.green('šŸ”§ Initializing SPAPS...'));
87
- console.log();
127
+ .option('--json', 'Output in JSON format')
128
+ .action((options, command) => {
129
+ const isJson = options.json || command.parent.opts().json;
130
+
131
+ if (!isJson) {
132
+ console.log(logo);
133
+ console.log(chalk.green('šŸ”§ Initializing SPAPS...'));
134
+ console.log();
135
+ }
88
136
 
89
137
  // Create minimal .env.local
90
138
  const envContent = `# SPAPS Local Development Configuration
@@ -97,20 +145,43 @@ NODE_ENV=development
97
145
  # SPAPS_API_KEY=your-api-key-here
98
146
  `;
99
147
 
148
+ const result = {
149
+ success: true,
150
+ command: 'init',
151
+ files_created: [],
152
+ files_skipped: [],
153
+ next_steps: [
154
+ 'npx spaps local',
155
+ 'npm install @spaps/sdk',
156
+ 'Start coding!'
157
+ ]
158
+ };
159
+
100
160
  if (!fs.existsSync('.env.local')) {
101
161
  fs.writeFileSync('.env.local', envContent);
102
- console.log(chalk.green('āœ… Created .env.local'));
162
+ result.files_created.push('.env.local');
163
+ if (!isJson) {
164
+ console.log(chalk.green('āœ… Created .env.local'));
165
+ }
103
166
  } else {
104
- console.log(chalk.yellow('āš ļø .env.local already exists'));
167
+ result.files_skipped.push('.env.local');
168
+ result.message = '.env.local already exists';
169
+ if (!isJson) {
170
+ console.log(chalk.yellow('āš ļø .env.local already exists'));
171
+ }
105
172
  }
106
173
 
107
- console.log();
108
- console.log(chalk.green('✨ SPAPS initialized!'));
109
- console.log();
110
- console.log('Next steps:');
111
- console.log(chalk.cyan(' 1. Run: npx spaps local'));
112
- console.log(chalk.cyan(' 2. Install SDK: npm install @spaps/sdk'));
113
- console.log(chalk.cyan(' 3. Start coding!'));
174
+ if (isJson) {
175
+ console.log(JSON.stringify(result));
176
+ } else {
177
+ console.log();
178
+ console.log(chalk.green('✨ SPAPS initialized!'));
179
+ console.log();
180
+ console.log('Next steps:');
181
+ console.log(chalk.cyan(' 1. Run: npx spaps local'));
182
+ console.log(chalk.cyan(' 2. Install SDK: npm install @spaps/sdk'));
183
+ console.log(chalk.cyan(' 3. Start coding!'));
184
+ }
114
185
  });
115
186
 
116
187
  // Create command (placeholder)
package/client.js ADDED
@@ -0,0 +1,102 @@
1
+ /**
2
+ * SPAPS Client - Re-export from spaps-sdk
3
+ * This allows users to import from 'spaps/client'
4
+ */
5
+
6
+ try {
7
+ // Try to load spaps-sdk if it's installed
8
+ module.exports = require('spaps-sdk');
9
+ } catch (error) {
10
+ // Fallback to a simple client implementation for local development
11
+ const axios = require('axios');
12
+
13
+ class SPAPSClient {
14
+ constructor(config = {}) {
15
+ const apiUrl = config.apiUrl || process.env.SPAPS_API_URL || 'http://localhost:3300';
16
+ this.isLocalMode = apiUrl.includes('localhost') || apiUrl.includes('127.0.0.1');
17
+
18
+ this.client = axios.create({
19
+ baseURL: apiUrl,
20
+ timeout: config.timeout || 10000,
21
+ headers: {
22
+ 'Content-Type': 'application/json',
23
+ ...(config.apiKey && { 'X-API-Key': config.apiKey })
24
+ }
25
+ });
26
+
27
+ this.accessToken = null;
28
+ this.refreshToken = null;
29
+ }
30
+
31
+ async login(email, password) {
32
+ const response = await this.client.post('/api/auth/login', { email, password });
33
+ this.accessToken = response.data.access_token;
34
+ this.refreshToken = response.data.refresh_token;
35
+ return response;
36
+ }
37
+
38
+ async register(email, password) {
39
+ const response = await this.client.post('/api/auth/register', { email, password });
40
+ this.accessToken = response.data.access_token;
41
+ this.refreshToken = response.data.refresh_token;
42
+ return response;
43
+ }
44
+
45
+ async walletSignIn(walletAddress, signature, message, chainType = 'solana') {
46
+ const response = await this.client.post('/api/auth/wallet-sign-in', {
47
+ wallet_address: walletAddress,
48
+ signature,
49
+ message,
50
+ chain_type: chainType
51
+ });
52
+ this.accessToken = response.data.access_token;
53
+ this.refreshToken = response.data.refresh_token;
54
+ return response;
55
+ }
56
+
57
+ async getUser() {
58
+ return this.client.get('/api/auth/user', {
59
+ headers: { Authorization: `Bearer ${this.accessToken}` }
60
+ });
61
+ }
62
+
63
+ async createCheckoutSession(priceId, successUrl, cancelUrl) {
64
+ return this.client.post('/api/stripe/create-checkout-session',
65
+ { price_id: priceId, success_url: successUrl, cancel_url: cancelUrl },
66
+ { headers: { Authorization: `Bearer ${this.accessToken}` } }
67
+ );
68
+ }
69
+
70
+ async getSubscription() {
71
+ return this.client.get('/api/stripe/subscription', {
72
+ headers: { Authorization: `Bearer ${this.accessToken}` }
73
+ });
74
+ }
75
+
76
+ async getUsageBalance() {
77
+ return this.client.get('/api/usage/balance', {
78
+ headers: { Authorization: `Bearer ${this.accessToken}` }
79
+ });
80
+ }
81
+
82
+ isAuthenticated() {
83
+ return !!this.accessToken;
84
+ }
85
+
86
+ getAccessToken() {
87
+ return this.accessToken;
88
+ }
89
+
90
+ setAccessToken(token) {
91
+ this.accessToken = token;
92
+ }
93
+
94
+ isLocalMode() {
95
+ return this.isLocalMode;
96
+ }
97
+ }
98
+
99
+ module.exports = SPAPSClient;
100
+ module.exports.SPAPSClient = SPAPSClient;
101
+ module.exports.default = SPAPSClient;
102
+ }
package/package.json CHANGED
@@ -1,11 +1,15 @@
1
1
  {
2
2
  "name": "spaps",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "Sweet Potato Authentication & Payment Service CLI - Zero-config local development and project scaffolding",
5
5
  "main": "bin/spaps.js",
6
6
  "bin": {
7
7
  "spaps": "./bin/spaps.js"
8
8
  },
9
+ "exports": {
10
+ ".": "./bin/spaps.js",
11
+ "./client": "./client.js"
12
+ },
9
13
  "scripts": {
10
14
  "test": "echo \"No tests yet\""
11
15
  },
@@ -47,6 +51,7 @@
47
51
  "files": [
48
52
  "bin",
49
53
  "src",
54
+ "client.js",
50
55
  "README.md"
51
56
  ]
52
57
  }
@@ -12,6 +12,7 @@ const chalk = require('chalk');
12
12
  class LocalServer {
13
13
  constructor(options = {}) {
14
14
  this.port = options.port || process.env.PORT || 3300;
15
+ this.json = options.json || false;
15
16
  this.app = express();
16
17
  this.setupMiddleware();
17
18
  this.setupRoutes();
@@ -44,8 +45,10 @@ class LocalServer {
44
45
  };
45
46
  }
46
47
 
47
- // Log requests
48
- console.log(chalk.dim(`${req.method} ${req.path}`));
48
+ // Log requests (unless in JSON mode)
49
+ if (!this.json) {
50
+ console.log(chalk.dim(`${req.method} ${req.path}`));
51
+ }
49
52
  next();
50
53
  });
51
54
  }
@@ -276,25 +279,29 @@ CORS: Enabled (all origins)
276
279
  if (err) {
277
280
  reject(err);
278
281
  } else {
279
- console.log();
280
- console.log(chalk.yellow('šŸ  SPAPS Local Development Server'));
281
- console.log(chalk.green(`✨ Running at: http://localhost:${this.port}`));
282
- console.log(chalk.blue(`šŸ“ Documentation: http://localhost:${this.port}/docs`));
283
- console.log(chalk.dim(' Press Ctrl+C to stop'));
284
- console.log();
282
+ if (!this.json) {
283
+ console.log();
284
+ console.log(chalk.yellow('šŸ  SPAPS Local Development Server'));
285
+ console.log(chalk.green(`✨ Running at: http://localhost:${this.port}`));
286
+ console.log(chalk.blue(`šŸ“ Documentation: http://localhost:${this.port}/docs`));
287
+ console.log(chalk.dim(' Press Ctrl+C to stop'));
288
+ console.log();
289
+ }
285
290
  resolve(server);
286
291
  }
287
292
  });
288
293
 
289
294
  // Handle errors
290
295
  server.on('error', (err) => {
291
- if (err.code === 'EADDRINUSE') {
292
- console.error(chalk.red(`āŒ Port ${this.port} is already in use`));
293
- console.log(chalk.yellow('šŸ’” Try: spaps local --port 3301'));
294
- } else {
295
- console.error(chalk.red('āŒ Server error:'), err.message);
296
+ if (!this.json) {
297
+ if (err.code === 'EADDRINUSE') {
298
+ console.error(chalk.red(`āŒ Port ${this.port} is already in use`));
299
+ console.log(chalk.yellow('šŸ’” Try: spaps local --port 3301'));
300
+ } else {
301
+ console.error(chalk.red('āŒ Server error:'), err.message);
302
+ }
296
303
  }
297
- process.exit(1);
304
+ reject(err);
298
305
  });
299
306
  });
300
307
  }