openkbs 0.0.63 → 0.0.65

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/src/actions.js CHANGED
@@ -1935,7 +1935,7 @@ async function siteDeployAction(kbToken, kbId, siteDir, args) {
1935
1935
  }
1936
1936
 
1937
1937
  console.green(`\nUpload complete! ${uploaded}/${files.length} files uploaded.`);
1938
- console.log(`Files accessible at: https://files.openkbs.com/${kbId}/`);
1938
+ // console.log(`Files accessible at: https://files.openkbs.com/${kbId}/`);
1939
1939
 
1940
1940
  } catch (error) {
1941
1941
  console.red('Upload failed:', error.message);
@@ -2184,9 +2184,12 @@ async function elasticDeployAction() {
2184
2184
  if (elasticRes.error) {
2185
2185
  console.red('Elastic deploy error:', elasticRes.error);
2186
2186
  } else {
2187
- if (elasticRes.pulse?.enabled) console.green(' ✓ Pulse enabled');
2188
- if (elasticRes.postgres?.enabled) console.green(' Postgres enabled');
2189
- if (elasticRes.storage?.enabled) console.green(' ✓ Storage enabled');
2187
+ if (elasticRes.pulse?.enabled || elasticRes.pulse?.alreadyEnabled) console.green(' ✓ Pulse enabled');
2188
+ if (elasticRes.pulse?.error) console.yellow(' Pulse:', elasticRes.pulse.error);
2189
+ if (elasticRes.postgres?.enabled || elasticRes.postgres?.alreadyEnabled || elasticRes.postgres?.host) console.green(' ✓ Postgres enabled');
2190
+ if (elasticRes.postgres?.error) console.yellow(' ⚠ Postgres:', elasticRes.postgres.error);
2191
+ if (elasticRes.storage?.enabled || elasticRes.storage?.alreadyEnabled || elasticRes.storage?.bucket) console.green(' ✓ Storage enabled');
2192
+ if (elasticRes.storage?.error) console.yellow(' ⚠ Storage:', elasticRes.storage.error);
2190
2193
  if (elasticRes.storage?.cloudfront) console.green(' ✓ CloudFront configured');
2191
2194
  }
2192
2195
  }
@@ -2219,6 +2222,257 @@ async function elasticDeployAction() {
2219
2222
  console.green('\nDeploy complete!');
2220
2223
  }
2221
2224
 
2225
+ /**
2226
+ * Destroy all resources defined in openkbs.json
2227
+ */
2228
+ async function elasticDestroyAction() {
2229
+ // Find openkbs.json
2230
+ const configPaths = [
2231
+ path.join(process.cwd(), 'openkbs.json'),
2232
+ path.join(process.cwd(), '..', 'openkbs.json')
2233
+ ];
2234
+
2235
+ let configPath = null;
2236
+ for (const p of configPaths) {
2237
+ if (fs.existsSync(p)) {
2238
+ configPath = p;
2239
+ break;
2240
+ }
2241
+ }
2242
+
2243
+ if (!configPath) {
2244
+ return console.red('openkbs.json not found.');
2245
+ }
2246
+
2247
+ const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
2248
+
2249
+ console.log(`Destroying ${config.name || 'project'} resources...`);
2250
+ console.yellow('Warning: This will permanently delete all resources!\n');
2251
+
2252
+ // Get KB token
2253
+ const settings = findSettings();
2254
+ if (!settings?.kbId) {
2255
+ return console.red('No kbId found. Run from a directory with settings.json');
2256
+ }
2257
+
2258
+ const res = await fetchKBJWT(settings.kbId);
2259
+ if (!res?.kbToken) {
2260
+ return console.red(`KB ${settings.kbId} not found`);
2261
+ }
2262
+ const kbToken = res.kbToken;
2263
+
2264
+ // Delete functions
2265
+ if (config.functions && config.functions.length > 0) {
2266
+ console.log('Deleting functions...');
2267
+ for (const fnName of config.functions) {
2268
+ const name = typeof fnName === 'object' ? fnName.name : fnName;
2269
+ try {
2270
+ await fnDeleteAction(kbToken, name);
2271
+ console.green(` ✓ Deleted ${name}`);
2272
+ } catch (e) {
2273
+ console.yellow(` ⚠ ${name}: ${e.message}`);
2274
+ }
2275
+ }
2276
+ }
2277
+
2278
+ // Disable elastic services
2279
+ if (config.elastic) {
2280
+ console.log('\nDisabling Elastic services...');
2281
+
2282
+ if (config.elastic.storage) {
2283
+ // First remove CloudFront behavior/origin if configured
2284
+ const cloudfrontPath = typeof config.elastic.storage === 'object'
2285
+ ? config.elastic.storage.cloudfront
2286
+ : null;
2287
+
2288
+ if (cloudfrontPath) {
2289
+ try {
2290
+ await makePostRequest(KB_API_URL, {
2291
+ token: kbToken,
2292
+ action: 'setStorageCloudFront',
2293
+ pathPrefix: cloudfrontPath,
2294
+ enable: false
2295
+ });
2296
+ console.green(` ✓ CloudFront behavior removed (/${cloudfrontPath}/*)`);
2297
+ } catch (e) {
2298
+ console.yellow(` ⚠ CloudFront: ${e.message}`);
2299
+ }
2300
+ }
2301
+
2302
+ // Then delete storage bucket
2303
+ try {
2304
+ const storageRes = await makePostRequest(KB_API_URL, {
2305
+ token: kbToken,
2306
+ action: 'deleteElasticStorage',
2307
+ force: true
2308
+ });
2309
+ if (storageRes.error) {
2310
+ console.yellow(` ⚠ Storage: ${storageRes.error}`);
2311
+ } else {
2312
+ console.green(' ✓ Storage disabled');
2313
+ }
2314
+ } catch (e) {
2315
+ console.yellow(` ⚠ Storage: ${e.message}`);
2316
+ }
2317
+ }
2318
+
2319
+ if (config.elastic.postgres) {
2320
+ try {
2321
+ await makePostRequest(KB_API_URL, {
2322
+ token: kbToken,
2323
+ action: 'deleteElasticPostgres'
2324
+ });
2325
+ console.green(' ✓ Postgres disabled');
2326
+ } catch (e) {
2327
+ console.yellow(` ⚠ Postgres: ${e.message}`);
2328
+ }
2329
+ }
2330
+
2331
+ if (config.elastic.pulse) {
2332
+ try {
2333
+ await makePostRequest(KB_API_URL, {
2334
+ token: kbToken,
2335
+ action: 'disableElasticPulse'
2336
+ });
2337
+ console.green(' ✓ Pulse disabled');
2338
+ } catch (e) {
2339
+ console.yellow(` ⚠ Pulse: ${e.message}`);
2340
+ }
2341
+ }
2342
+ }
2343
+
2344
+ console.green('\nDestroy complete!');
2345
+ }
2346
+
2347
+ /**
2348
+ * Show status of all resources defined in openkbs.json
2349
+ */
2350
+ async function elasticStatusAction() {
2351
+ // Find openkbs.json
2352
+ const configPaths = [
2353
+ path.join(process.cwd(), 'openkbs.json'),
2354
+ path.join(process.cwd(), '..', 'openkbs.json')
2355
+ ];
2356
+
2357
+ let configPath = null;
2358
+ for (const p of configPaths) {
2359
+ if (fs.existsSync(p)) {
2360
+ configPath = p;
2361
+ break;
2362
+ }
2363
+ }
2364
+
2365
+ if (!configPath) {
2366
+ return console.red('openkbs.json not found.');
2367
+ }
2368
+
2369
+ const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
2370
+
2371
+ console.log(`Stack: ${config.name || 'unnamed'}`);
2372
+ console.log(`Region: ${config.region || 'us-east-1'}\n`);
2373
+
2374
+ // Get KB token
2375
+ const settings = findSettings();
2376
+ if (!settings?.kbId) {
2377
+ return console.red('No kbId found. Run from a directory with settings.json');
2378
+ }
2379
+
2380
+ const res = await fetchKBJWT(settings.kbId);
2381
+ if (!res?.kbToken) {
2382
+ return console.red(`KB ${settings.kbId} not found`);
2383
+ }
2384
+ const kbToken = res.kbToken;
2385
+
2386
+ // Check functions
2387
+ if (config.functions && config.functions.length > 0) {
2388
+ console.log('Functions:');
2389
+ const listRes = await makePostRequest(KB_API_URL, {
2390
+ token: kbToken,
2391
+ action: 'listElasticFunctions'
2392
+ });
2393
+ const deployed = listRes.functions?.map(f => f.functionName) || [];
2394
+
2395
+ for (const fnName of config.functions) {
2396
+ const name = typeof fnName === 'object' ? fnName.name : fnName;
2397
+ if (deployed.includes(name)) {
2398
+ const fn = listRes.functions.find(f => f.functionName === name);
2399
+ console.green(` ✓ ${name} (${fn.customUrl || fn.functionUrl})`);
2400
+ } else {
2401
+ console.yellow(` ○ ${name} (not deployed)`);
2402
+ }
2403
+ }
2404
+ console.log('');
2405
+ }
2406
+
2407
+ // Check elastic services
2408
+ if (config.elastic) {
2409
+ console.log('Elastic Services:');
2410
+
2411
+ if (config.elastic.storage) {
2412
+ const storageRes = await makePostRequest(KB_API_URL, {
2413
+ token: kbToken,
2414
+ action: 'getElasticStorage'
2415
+ });
2416
+ if (storageRes.enabled) {
2417
+ console.green(` ✓ Storage (${storageRes.bucket})`);
2418
+ } else {
2419
+ console.yellow(' ○ Storage (not enabled)');
2420
+ }
2421
+ }
2422
+
2423
+ if (config.elastic.postgres) {
2424
+ const pgRes = await makePostRequest(KB_API_URL, {
2425
+ token: kbToken,
2426
+ action: 'getElasticPostgres'
2427
+ });
2428
+ if (pgRes.enabled) {
2429
+ console.green(` ✓ Postgres (${pgRes.host})`);
2430
+ } else {
2431
+ console.yellow(' ○ Postgres (not enabled)');
2432
+ }
2433
+ }
2434
+
2435
+ if (config.elastic.pulse) {
2436
+ const pulseRes = await makePostRequest(KB_API_URL, {
2437
+ token: kbToken,
2438
+ action: 'getElasticPulse'
2439
+ });
2440
+ if (pulseRes.enabled) {
2441
+ console.green(` ✓ Pulse (${pulseRes.endpoint})`);
2442
+ } else {
2443
+ console.yellow(' ○ Pulse (not enabled)');
2444
+ }
2445
+ }
2446
+ }
2447
+
2448
+ // Site info
2449
+ if (config.site) {
2450
+ console.log('');
2451
+ console.log(`Site: https://files.openkbs.com/${settings.kbId}/`);
2452
+ }
2453
+ }
2454
+
2455
+ /**
2456
+ * Stack command handler
2457
+ */
2458
+ async function stackAction(subCommand, args = []) {
2459
+ switch (subCommand) {
2460
+ case 'deploy':
2461
+ return await elasticDeployAction();
2462
+ case 'destroy':
2463
+ return await elasticDestroyAction();
2464
+ case 'status':
2465
+ return await elasticStatusAction();
2466
+ default:
2467
+ console.log('Usage: openkbs stack <command>');
2468
+ console.log('');
2469
+ console.log('Commands:');
2470
+ console.log(' deploy Deploy all resources from openkbs.json');
2471
+ console.log(' destroy Delete all resources (DANGEROUS)');
2472
+ console.log(' status Show status of all resources');
2473
+ }
2474
+ }
2475
+
2222
2476
  module.exports = {
2223
2477
  signAction,
2224
2478
  loginAction,
@@ -2245,5 +2499,7 @@ module.exports = {
2245
2499
  storageAction,
2246
2500
  postgresAction,
2247
2501
  pulseAction,
2248
- elasticDeployAction
2502
+ stackAction,
2503
+ elasticDeployAction,
2504
+ elasticDestroyAction
2249
2505
  };
package/src/index.js CHANGED
@@ -19,7 +19,9 @@ const {
19
19
  storageAction,
20
20
  postgresAction,
21
21
  pulseAction,
22
- elasticDeployAction
22
+ stackAction,
23
+ elasticDeployAction,
24
+ elasticDestroyAction
23
25
  } = require('./actions');
24
26
 
25
27
 
@@ -127,6 +129,35 @@ Reads openkbs.json and deploys:
127
129
  - Site
128
130
  `);
129
131
 
132
+ program
133
+ .command('destroy')
134
+ .description('Destroy all resources from openkbs.json (DANGEROUS)')
135
+ .action(elasticDestroyAction)
136
+ .addHelpText('after', `
137
+ Examples:
138
+ $ openkbs destroy
139
+
140
+ Reads openkbs.json and deletes:
141
+ - Functions
142
+ - Elastic services (storage, postgres, pulse)
143
+ `);
144
+
145
+ program
146
+ .command('stack <subcommand>')
147
+ .description('Manage stack resources (deploy, destroy, status)')
148
+ .action((subCommand) => stackAction(subCommand))
149
+ .addHelpText('after', `
150
+ Commands:
151
+ deploy Deploy all resources from openkbs.json
152
+ destroy Delete all resources (DANGEROUS)
153
+ status Show status of all resources
154
+
155
+ Examples:
156
+ $ openkbs stack deploy
157
+ $ openkbs stack status
158
+ $ openkbs stack destroy
159
+ `);
160
+
130
161
  // program
131
162
  // .command('sign')
132
163
  // .description('Signs a transaction to request OpenKBS service')
package/src/utils.js CHANGED
@@ -166,14 +166,18 @@ function makePostRequest(url, data) {
166
166
  try {
167
167
  const parsed = JSON.parse(body);
168
168
  if (parsed.error) {
169
- console.red(parsed.error);
169
+ console.red(`Error: ${parsed.error}`);
170
170
  } else if (parsed.message) {
171
- console.red(parsed.message);
171
+ console.red(`Error: ${parsed.message}`);
172
172
  } else {
173
- console.red(`Invalid Request`);
173
+ // Show the full response body if no error/message field
174
+ console.red(`Request failed (HTTP ${res.statusCode}):`);
175
+ console.red(JSON.stringify(parsed, null, 2));
174
176
  }
175
177
  } catch (e) {
176
- console.red(`Invalid Request`);
178
+ // Could not parse JSON, show raw body
179
+ console.red(`Request failed (HTTP ${res.statusCode}):`);
180
+ console.red(body || 'No response body');
177
181
  }
178
182
 
179
183
  process.exit(1);
package/version.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.0.61",
3
- "releaseDate": "2025-12-30",
4
- "releaseNotes": "OpenKBS CLI version 0.0.61"
2
+ "version": "0.0.65",
3
+ "releaseDate": "2026-01-02",
4
+ "releaseNotes": "OpenKBS CLI version 0.0.65"
5
5
  }