@insforge/cli 0.1.3 → 0.1.5

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 CHANGED
@@ -473,6 +473,22 @@ npm link # makes `insforge` available globally
473
473
  npm run dev # watch mode for development
474
474
  ```
475
475
 
476
+ ## Releasing
477
+
478
+ Bump the version, push the tag, and create a GitHub Release — the CI will publish to npm automatically.
479
+
480
+ ```bash
481
+ # Bump version (creates commit + tag)
482
+ npm version patch # 0.1.3 → 0.1.4
483
+ # or
484
+ npm version minor # 0.1.3 → 0.2.0
485
+
486
+ # Push commit and tag
487
+ git push && git push --tags
488
+ ```
489
+
490
+ Then go to GitHub → Releases → **Draft a new release**, select the tag (e.g. `v0.1.4`), and publish. The [publish workflow](.github/workflows/publish.yml) will run `npm publish` automatically.
491
+
476
492
  ## License
477
493
 
478
494
  Apache-2.0
package/dist/index.js CHANGED
@@ -48,6 +48,11 @@ function clearCredentials() {
48
48
  if (existsSync(CREDENTIALS_FILE)) {
49
49
  unlinkSync(CREDENTIALS_FILE);
50
50
  }
51
+ const config = getGlobalConfig();
52
+ if (config.default_org_id) {
53
+ delete config.default_org_id;
54
+ saveGlobalConfig(config);
55
+ }
51
56
  }
52
57
  function getLocalConfigDir() {
53
58
  return join(process.cwd(), ".insforge");
@@ -1589,10 +1594,10 @@ function registerStorageDeleteBucketCommand(storageCmd2) {
1589
1594
  try {
1590
1595
  requireAuth();
1591
1596
  if (!yes && !json) {
1592
- const confirm4 = await clack5.confirm({
1597
+ const confirm5 = await clack5.confirm({
1593
1598
  message: `Delete bucket "${name}" and all its objects? This cannot be undone.`
1594
1599
  });
1595
- if (!confirm4 || clack5.isCancel(confirm4)) {
1600
+ if (!confirm5 || clack5.isCancel(confirm5)) {
1596
1601
  process.exit(0);
1597
1602
  }
1598
1603
  }
@@ -1851,9 +1856,9 @@ function registerContextCommand(program2) {
1851
1856
  } else {
1852
1857
  console.log(" User: (not logged in)");
1853
1858
  }
1854
- if (globalConfig.default_org_id) {
1859
+ if (creds && globalConfig.default_org_id) {
1855
1860
  console.log(` Default Org: ${globalConfig.default_org_id}`);
1856
- } else {
1861
+ } else if (creds) {
1857
1862
  console.log(" Default Org: (none)");
1858
1863
  }
1859
1864
  if (projectConfig) {
@@ -1863,7 +1868,7 @@ function registerContextCommand(program2) {
1863
1868
  console.log(` Region: ${projectConfig.region}`);
1864
1869
  console.log(` OSS Host: ${projectConfig.oss_host}`);
1865
1870
  } else {
1866
- console.log("\n Project: (not linked \u2014 run `insforge projects link`)");
1871
+ console.log("\n Project: (not linked \u2014 run `insforge link`)");
1867
1872
  }
1868
1873
  console.log("");
1869
1874
  } catch (err) {
@@ -2376,10 +2381,10 @@ function registerSecretsDeleteCommand(secretsCmd2) {
2376
2381
  try {
2377
2382
  requireAuth();
2378
2383
  if (!yes && !json) {
2379
- const confirm4 = await clack9.confirm({
2384
+ const confirm5 = await clack9.confirm({
2380
2385
  message: `Delete secret "${key}"? This cannot be undone.`
2381
2386
  });
2382
- if (!confirm4 || clack9.isCancel(confirm4)) {
2387
+ if (!confirm5 || clack9.isCancel(confirm5)) {
2383
2388
  process.exit(0);
2384
2389
  }
2385
2390
  }
@@ -2398,6 +2403,267 @@ function registerSecretsDeleteCommand(secretsCmd2) {
2398
2403
  });
2399
2404
  }
2400
2405
 
2406
+ // src/commands/schedules/list.ts
2407
+ function registerSchedulesListCommand(schedulesCmd2) {
2408
+ schedulesCmd2.command("list").description("List all schedules").action(async (_opts, cmd) => {
2409
+ const { json } = getRootOpts(cmd);
2410
+ try {
2411
+ requireAuth();
2412
+ const res = await ossFetch("/api/schedules");
2413
+ const data = await res.json();
2414
+ const schedules = Array.isArray(data) ? data : data.schedules ?? [];
2415
+ if (json) {
2416
+ outputJson(schedules);
2417
+ } else {
2418
+ if (!schedules.length) {
2419
+ console.log("No schedules found.");
2420
+ return;
2421
+ }
2422
+ outputTable(
2423
+ ["ID", "Name", "Cron", "URL", "Method", "Active", "Next Run"],
2424
+ schedules.map((s) => [
2425
+ String(s.id ?? "-"),
2426
+ String(s.name ?? "-"),
2427
+ String(s.cronSchedule ?? "-"),
2428
+ String(s.functionUrl ?? "-"),
2429
+ String(s.httpMethod ?? "-"),
2430
+ s.isActive === false ? "No" : "Yes",
2431
+ s.nextRun ? new Date(String(s.nextRun)).toLocaleString() : "-"
2432
+ ])
2433
+ );
2434
+ }
2435
+ } catch (err) {
2436
+ handleError(err, json);
2437
+ }
2438
+ });
2439
+ }
2440
+
2441
+ // src/commands/schedules/get.ts
2442
+ function registerSchedulesGetCommand(schedulesCmd2) {
2443
+ schedulesCmd2.command("get <id>").description("Get schedule details").action(async (id, _opts, cmd) => {
2444
+ const { json } = getRootOpts(cmd);
2445
+ try {
2446
+ requireAuth();
2447
+ const res = await ossFetch(`/api/schedules/${encodeURIComponent(id)}`);
2448
+ const data = await res.json();
2449
+ if (json) {
2450
+ outputJson(data);
2451
+ } else {
2452
+ console.log(`
2453
+ Name: ${data.name ?? "-"}`);
2454
+ console.log(` ID: ${data.id ?? "-"}`);
2455
+ console.log(` Cron: ${data.cronSchedule ?? "-"}`);
2456
+ console.log(` URL: ${data.functionUrl ?? "-"}`);
2457
+ console.log(` Method: ${data.httpMethod ?? "-"}`);
2458
+ console.log(` Active: ${data.isActive === false ? "No" : "Yes"}`);
2459
+ if (data.headers) console.log(` Headers: ${JSON.stringify(data.headers)}`);
2460
+ if (data.body) console.log(` Body: ${JSON.stringify(data.body)}`);
2461
+ console.log(` Next Run: ${data.nextRun ? new Date(String(data.nextRun)).toLocaleString() : "-"}`);
2462
+ console.log(` Created: ${data.createdAt ? new Date(String(data.createdAt)).toLocaleString() : "-"}`);
2463
+ console.log("");
2464
+ }
2465
+ } catch (err) {
2466
+ handleError(err, json);
2467
+ }
2468
+ });
2469
+ }
2470
+
2471
+ // src/commands/schedules/create.ts
2472
+ function registerSchedulesCreateCommand(schedulesCmd2) {
2473
+ schedulesCmd2.command("create").description("Create a new schedule").requiredOption("--name <name>", "Schedule name").requiredOption("--cron <expression>", "Cron expression (5-field format)").requiredOption("--url <url>", "URL to invoke").requiredOption("--method <method>", "HTTP method (GET, POST, PUT, PATCH, DELETE)").option("--headers <json>", "HTTP headers as JSON").option("--body <json>", "Request body as JSON").action(async (opts, cmd) => {
2474
+ const { json } = getRootOpts(cmd);
2475
+ try {
2476
+ requireAuth();
2477
+ const body = {
2478
+ name: opts.name,
2479
+ cronSchedule: opts.cron,
2480
+ functionUrl: opts.url,
2481
+ httpMethod: opts.method.toUpperCase()
2482
+ };
2483
+ if (opts.headers) {
2484
+ try {
2485
+ body.headers = JSON.parse(opts.headers);
2486
+ } catch {
2487
+ throw new CLIError("Invalid JSON for --headers");
2488
+ }
2489
+ }
2490
+ if (opts.body) {
2491
+ try {
2492
+ body.body = JSON.parse(opts.body);
2493
+ } catch {
2494
+ throw new CLIError("Invalid JSON for --body");
2495
+ }
2496
+ }
2497
+ const res = await ossFetch("/api/schedules", {
2498
+ method: "POST",
2499
+ body: JSON.stringify(body)
2500
+ });
2501
+ const data = await res.json();
2502
+ if (json) {
2503
+ outputJson(data);
2504
+ } else {
2505
+ outputSuccess(`Schedule "${opts.name}" created (ID: ${data.id ?? "unknown"}).`);
2506
+ }
2507
+ } catch (err) {
2508
+ handleError(err, json);
2509
+ }
2510
+ });
2511
+ }
2512
+
2513
+ // src/commands/schedules/update.ts
2514
+ function registerSchedulesUpdateCommand(schedulesCmd2) {
2515
+ schedulesCmd2.command("update <id>").description("Update a schedule").option("--name <name>", "New schedule name").option("--cron <expression>", "New cron expression").option("--url <url>", "New URL to invoke").option("--method <method>", "New HTTP method").option("--headers <json>", "New HTTP headers as JSON").option("--body <json>", "New request body as JSON").option("--active <bool>", "Enable/disable schedule (true/false)").action(async (id, opts, cmd) => {
2516
+ const { json } = getRootOpts(cmd);
2517
+ try {
2518
+ requireAuth();
2519
+ const body = {};
2520
+ if (opts.name !== void 0) body.name = opts.name;
2521
+ if (opts.cron !== void 0) body.cronSchedule = opts.cron;
2522
+ if (opts.url !== void 0) body.functionUrl = opts.url;
2523
+ if (opts.method !== void 0) body.httpMethod = opts.method.toUpperCase();
2524
+ if (opts.active !== void 0) body.isActive = opts.active === "true";
2525
+ if (opts.headers !== void 0) {
2526
+ try {
2527
+ body.headers = JSON.parse(opts.headers);
2528
+ } catch {
2529
+ throw new CLIError("Invalid JSON for --headers");
2530
+ }
2531
+ }
2532
+ if (opts.body !== void 0) {
2533
+ try {
2534
+ body.body = JSON.parse(opts.body);
2535
+ } catch {
2536
+ throw new CLIError("Invalid JSON for --body");
2537
+ }
2538
+ }
2539
+ if (Object.keys(body).length === 0) {
2540
+ throw new CLIError("Provide at least one option to update (--name, --cron, --url, --method, --headers, --body, --active).");
2541
+ }
2542
+ const res = await ossFetch(`/api/schedules/${encodeURIComponent(id)}`, {
2543
+ method: "PATCH",
2544
+ body: JSON.stringify(body)
2545
+ });
2546
+ const data = await res.json();
2547
+ if (json) {
2548
+ outputJson(data);
2549
+ } else {
2550
+ outputSuccess(data.message ?? "Schedule updated.");
2551
+ }
2552
+ } catch (err) {
2553
+ handleError(err, json);
2554
+ }
2555
+ });
2556
+ }
2557
+
2558
+ // src/commands/schedules/delete.ts
2559
+ import * as clack10 from "@clack/prompts";
2560
+ function registerSchedulesDeleteCommand(schedulesCmd2) {
2561
+ schedulesCmd2.command("delete <id>").description("Delete a schedule").action(async (id, _opts, cmd) => {
2562
+ const { json, yes } = getRootOpts(cmd);
2563
+ try {
2564
+ requireAuth();
2565
+ if (!yes && !json) {
2566
+ const confirm5 = await clack10.confirm({
2567
+ message: `Delete schedule "${id}"? This cannot be undone.`
2568
+ });
2569
+ if (!confirm5 || clack10.isCancel(confirm5)) {
2570
+ process.exit(0);
2571
+ }
2572
+ }
2573
+ const res = await ossFetch(`/api/schedules/${encodeURIComponent(id)}`, {
2574
+ method: "DELETE"
2575
+ });
2576
+ const data = await res.json();
2577
+ if (json) {
2578
+ outputJson(data);
2579
+ } else {
2580
+ outputSuccess(data.message ?? "Schedule deleted.");
2581
+ }
2582
+ } catch (err) {
2583
+ handleError(err, json);
2584
+ }
2585
+ });
2586
+ }
2587
+
2588
+ // src/commands/schedules/logs.ts
2589
+ function registerSchedulesLogsCommand(schedulesCmd2) {
2590
+ schedulesCmd2.command("logs <id>").description("Get execution logs for a schedule").option("--limit <n>", "Max logs to return (default: 50, max: 100)", "50").option("--offset <n>", "Pagination offset", "0").action(async (id, opts, cmd) => {
2591
+ const { json } = getRootOpts(cmd);
2592
+ try {
2593
+ requireAuth();
2594
+ const limit = parseInt(opts.limit, 10) || 50;
2595
+ const offset = parseInt(opts.offset, 10) || 0;
2596
+ const res = await ossFetch(`/api/schedules/${encodeURIComponent(id)}/logs?limit=${limit}&offset=${offset}`);
2597
+ const data = await res.json();
2598
+ const logs = data.logs ?? [];
2599
+ if (json) {
2600
+ outputJson(data);
2601
+ } else {
2602
+ if (!logs.length) {
2603
+ console.log("No execution logs found.");
2604
+ return;
2605
+ }
2606
+ outputTable(
2607
+ ["Executed At", "Status", "Success", "Duration (ms)"],
2608
+ logs.map((l) => [
2609
+ l.executedAt ? new Date(String(l.executedAt)).toLocaleString() : "-",
2610
+ String(l.statusCode ?? "-"),
2611
+ l.success ? "Yes" : "No",
2612
+ String(l.durationMs ?? "-")
2613
+ ])
2614
+ );
2615
+ if (data.totalCount > offset + logs.length) {
2616
+ console.log(`
2617
+ Showing ${offset + 1}-${offset + logs.length} of ${data.totalCount}. Use --offset to paginate.`);
2618
+ }
2619
+ }
2620
+ } catch (err) {
2621
+ handleError(err, json);
2622
+ }
2623
+ });
2624
+ }
2625
+
2626
+ // src/commands/logs.ts
2627
+ var VALID_SOURCES = ["insforge.logs", "postgREST.logs", "postgres.logs", "function.logs"];
2628
+ var SOURCE_LOOKUP = new Map(VALID_SOURCES.map((s) => [s.toLowerCase(), s]));
2629
+ function registerLogsCommand(program2) {
2630
+ program2.command("logs <source>").description("Fetch backend container logs (insforge.logs | postgREST.logs | postgres.logs | function.logs)").option("--limit <n>", "Number of log entries to return", "20").action(async (source, opts, cmd) => {
2631
+ const { json } = getRootOpts(cmd);
2632
+ try {
2633
+ requireAuth();
2634
+ const resolved = SOURCE_LOOKUP.get(source.toLowerCase());
2635
+ if (!resolved) {
2636
+ console.error(`Invalid log source "${source}". Valid sources: ${VALID_SOURCES.join(", ")}`);
2637
+ process.exit(1);
2638
+ }
2639
+ const limit = parseInt(opts.limit, 10) || 20;
2640
+ const res = await ossFetch(`/api/logs/${encodeURIComponent(resolved)}?limit=${limit}`);
2641
+ const data = await res.json();
2642
+ if (json) {
2643
+ outputJson(data);
2644
+ } else {
2645
+ const logs = Array.isArray(data) ? data : data.logs;
2646
+ if (!Array.isArray(logs) || !logs.length) {
2647
+ console.log("No logs found.");
2648
+ return;
2649
+ }
2650
+ for (const entry of logs) {
2651
+ if (typeof entry === "string") {
2652
+ console.log(entry);
2653
+ } else {
2654
+ const e = entry;
2655
+ const ts = e.timestamp ?? e.time ?? "";
2656
+ const msg = e.message ?? e.msg ?? e.log ?? JSON.stringify(e);
2657
+ console.log(`${ts} ${msg}`);
2658
+ }
2659
+ }
2660
+ }
2661
+ } catch (err) {
2662
+ handleError(err, json);
2663
+ }
2664
+ });
2665
+ }
2666
+
2401
2667
  // src/index.ts
2402
2668
  var __dirname = dirname(fileURLToPath(import.meta.url));
2403
2669
  var pkg = JSON.parse(readFileSync5(join5(__dirname, "../package.json"), "utf-8"));
@@ -2471,5 +2737,13 @@ registerSecretsGetCommand(secretsCmd);
2471
2737
  registerSecretsAddCommand(secretsCmd);
2472
2738
  registerSecretsUpdateCommand(secretsCmd);
2473
2739
  registerSecretsDeleteCommand(secretsCmd);
2740
+ registerLogsCommand(program);
2741
+ var schedulesCmd = program.command("schedules").description("Manage scheduled tasks (cron jobs)");
2742
+ registerSchedulesListCommand(schedulesCmd);
2743
+ registerSchedulesGetCommand(schedulesCmd);
2744
+ registerSchedulesCreateCommand(schedulesCmd);
2745
+ registerSchedulesUpdateCommand(schedulesCmd);
2746
+ registerSchedulesDeleteCommand(schedulesCmd);
2747
+ registerSchedulesLogsCommand(schedulesCmd);
2474
2748
  program.parse();
2475
2749
  //# sourceMappingURL=index.js.map