@insforge/cli 0.1.18 → 0.1.20

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/dist/index.js CHANGED
@@ -5,7 +5,7 @@ import { readFileSync as readFileSync6 } from "fs";
5
5
  import { join as join6, dirname } from "path";
6
6
  import { fileURLToPath } from "url";
7
7
  import { Command } from "commander";
8
- import * as clack13 from "@clack/prompts";
8
+ import * as clack14 from "@clack/prompts";
9
9
 
10
10
  // src/lib/config.ts
11
11
  import { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync } from "fs";
@@ -694,6 +694,21 @@ ${missing.join("\n")}
694
694
  `;
695
695
  appendFileSync(gitignorePath, block);
696
696
  }
697
+ async function installCliGlobally(json) {
698
+ try {
699
+ const { stdout } = await execAsync("npm ls -g @insforge/cli --json", { timeout: 1e4 });
700
+ const parsed = JSON.parse(stdout);
701
+ if (parsed?.dependencies?.["@insforge/cli"]) return;
702
+ } catch {
703
+ }
704
+ try {
705
+ if (!json) clack5.log.info("Installing InsForge CLI globally...");
706
+ await execAsync("npm install -g @insforge/cli", { timeout: 6e4 });
707
+ if (!json) clack5.log.success("InsForge CLI installed. You can now run `insforge` directly.");
708
+ } catch {
709
+ if (!json) clack5.log.warn("Failed to install CLI globally. You can run manually: npm install -g @insforge/cli");
710
+ }
711
+ }
697
712
  async function installSkills(json) {
698
713
  try {
699
714
  if (!json) clack5.log.info("Installing InsForge agent skills...");
@@ -818,6 +833,7 @@ function registerProjectLinkCommand(program2) {
818
833
  } else {
819
834
  outputSuccess(`Linked to project "${project.name}" (${project.appkey}.${project.region})`);
820
835
  }
836
+ await installCliGlobally(json);
821
837
  await installSkills(json);
822
838
  await reportCliUsage("cli.link", true, 6);
823
839
  } catch (err) {
@@ -1383,23 +1399,42 @@ Specify --file <path> or create ${join3("insforge", "functions", slug, "index.ts
1383
1399
  } catch {
1384
1400
  exists = false;
1385
1401
  }
1402
+ let res;
1386
1403
  if (exists) {
1387
- await ossFetch(`/api/functions/${encodeURIComponent(slug)}`, {
1404
+ res = await ossFetch(`/api/functions/${encodeURIComponent(slug)}`, {
1388
1405
  method: "PUT",
1389
1406
  body: JSON.stringify({ name, description, code })
1390
1407
  });
1391
1408
  } else {
1392
- await ossFetch("/api/functions", {
1409
+ res = await ossFetch("/api/functions", {
1393
1410
  method: "POST",
1394
1411
  body: JSON.stringify({ slug, name, description, code })
1395
1412
  });
1396
1413
  }
1414
+ const result = await res.json();
1415
+ const deployFailed = result.deployment?.status === "failed";
1397
1416
  if (json) {
1398
- outputJson({ success: true, slug, action: exists ? "updated" : "created" });
1417
+ outputJson(result);
1399
1418
  } else {
1400
- outputSuccess(`Function "${slug}" ${exists ? "updated" : "created"} successfully.`);
1419
+ const action = exists ? "updation" : "creation";
1420
+ const resultStatus = result.success ? "success" : "failed";
1421
+ outputSuccess(`Function "${result.function.slug}" ${action} ${resultStatus}.`);
1422
+ if (result.deployment) {
1423
+ if (result.deployment.status === "success") {
1424
+ console.log(` Deployment: ${result.deployment.status}${result.deployment.url ? ` \u2192 ${result.deployment.url}` : ""}`);
1425
+ } else {
1426
+ console.log(` Deployment: ${result.deployment.status}`);
1427
+ if (result.deployment.buildLogs?.length) {
1428
+ console.log(" Build logs:");
1429
+ for (const line of result.deployment.buildLogs) {
1430
+ console.log(` ${line}`);
1431
+ }
1432
+ }
1433
+ }
1434
+ }
1401
1435
  }
1402
- await reportCliUsage("cli.functions.deploy", true);
1436
+ await reportCliUsage("cli.functions.deploy", !deployFailed);
1437
+ if (deployFailed) process.exit(1);
1403
1438
  } catch (err) {
1404
1439
  await reportCliUsage("cli.functions.deploy", false);
1405
1440
  handleError(err, json);
@@ -1480,6 +1515,43 @@ function registerFunctionsCodeCommand(functionsCmd2) {
1480
1515
  });
1481
1516
  }
1482
1517
 
1518
+ // src/commands/functions/delete.ts
1519
+ import * as clack7 from "@clack/prompts";
1520
+ function registerFunctionsDeleteCommand(functionsCmd2) {
1521
+ functionsCmd2.command("delete <slug>").description("Delete an edge function").action(async (slug, _opts, cmd) => {
1522
+ const { json, yes } = getRootOpts(cmd);
1523
+ try {
1524
+ await requireAuth();
1525
+ if (!yes && !json) {
1526
+ const confirmed = await clack7.confirm({
1527
+ message: `Delete function "${slug}"? This cannot be undone.`
1528
+ });
1529
+ if (clack7.isCancel(confirmed) || !confirmed) {
1530
+ clack7.log.info("Cancelled.");
1531
+ return;
1532
+ }
1533
+ }
1534
+ const res = await ossFetch(`/api/functions/${encodeURIComponent(slug)}`, {
1535
+ method: "DELETE"
1536
+ });
1537
+ const result = await res.json();
1538
+ if (json) {
1539
+ outputJson(result);
1540
+ } else {
1541
+ if (result.success) {
1542
+ outputSuccess(`Function "${slug}" deleted successfully.`);
1543
+ } else {
1544
+ outputSuccess(`Failed to delete function "${slug}".`);
1545
+ }
1546
+ }
1547
+ await reportCliUsage("cli.functions.delete", true);
1548
+ } catch (err) {
1549
+ await reportCliUsage("cli.functions.delete", false);
1550
+ handleError(err, json);
1551
+ }
1552
+ });
1553
+ }
1554
+
1483
1555
  // src/commands/storage/buckets.ts
1484
1556
  function registerStorageBucketsCommand(storageCmd2) {
1485
1557
  storageCmd2.command("buckets").description("List all storage buckets").action(async (_opts, cmd) => {
@@ -1613,17 +1685,17 @@ function registerStorageCreateBucketCommand(storageCmd2) {
1613
1685
  }
1614
1686
 
1615
1687
  // src/commands/storage/delete-bucket.ts
1616
- import * as clack7 from "@clack/prompts";
1688
+ import * as clack8 from "@clack/prompts";
1617
1689
  function registerStorageDeleteBucketCommand(storageCmd2) {
1618
1690
  storageCmd2.command("delete-bucket <name>").description("Delete a storage bucket and all its objects").action(async (name, _opts, cmd) => {
1619
1691
  const { json, yes } = getRootOpts(cmd);
1620
1692
  try {
1621
1693
  await requireAuth();
1622
1694
  if (!yes && !json) {
1623
- const confirm7 = await clack7.confirm({
1695
+ const confirm8 = await clack8.confirm({
1624
1696
  message: `Delete bucket "${name}" and all its objects? This cannot be undone.`
1625
1697
  });
1626
- if (!confirm7 || clack7.isCancel(confirm7)) {
1698
+ if (!confirm8 || clack8.isCancel(confirm8)) {
1627
1699
  process.exit(0);
1628
1700
  }
1629
1701
  }
@@ -1705,12 +1777,12 @@ import { tmpdir } from "os";
1705
1777
  import { promisify as promisify2 } from "util";
1706
1778
  import * as fs2 from "fs/promises";
1707
1779
  import * as path2 from "path";
1708
- import * as clack9 from "@clack/prompts";
1780
+ import * as clack10 from "@clack/prompts";
1709
1781
 
1710
1782
  // src/commands/deployments/deploy.ts
1711
1783
  import * as path from "path";
1712
1784
  import * as fs from "fs/promises";
1713
- import * as clack8 from "@clack/prompts";
1785
+ import * as clack9 from "@clack/prompts";
1714
1786
  import archiver from "archiver";
1715
1787
  var POLL_INTERVAL_MS = 5e3;
1716
1788
  var POLL_TIMEOUT_MS = 12e4;
@@ -1814,7 +1886,7 @@ function registerDeploymentsDeployCommand(deploymentsCmd2) {
1814
1886
  if (!stats?.isDirectory()) {
1815
1887
  throw new CLIError(`"${sourceDir}" is not a valid directory.`);
1816
1888
  }
1817
- const s = !json ? clack8.spinner() : null;
1889
+ const s = !json ? clack9.spinner() : null;
1818
1890
  const startBody = {};
1819
1891
  if (opts.env) {
1820
1892
  try {
@@ -1842,18 +1914,18 @@ function registerDeploymentsDeployCommand(deploymentsCmd2) {
1842
1914
  outputJson(result.deployment);
1843
1915
  } else {
1844
1916
  if (result.liveUrl) {
1845
- clack8.log.success(`Live at: ${result.liveUrl}`);
1917
+ clack9.log.success(`Live at: ${result.liveUrl}`);
1846
1918
  }
1847
- clack8.log.info(`Deployment ID: ${result.deploymentId}`);
1919
+ clack9.log.info(`Deployment ID: ${result.deploymentId}`);
1848
1920
  }
1849
1921
  } else {
1850
1922
  s?.stop("Deployment is still building");
1851
1923
  if (json) {
1852
1924
  outputJson({ id: result.deploymentId, status: result.deployment?.status ?? "building", timedOut: true });
1853
1925
  } else {
1854
- clack8.log.info(`Deployment ID: ${result.deploymentId}`);
1855
- clack8.log.warn("Deployment did not finish within 2 minutes.");
1856
- clack8.log.info(`Check status with: insforge deployments status ${result.deploymentId}`);
1926
+ clack9.log.info(`Deployment ID: ${result.deploymentId}`);
1927
+ clack9.log.warn("Deployment did not finish within 2 minutes.");
1928
+ clack9.log.info(`Check status with: insforge deployments status ${result.deploymentId}`);
1857
1929
  }
1858
1930
  }
1859
1931
  await reportCliUsage("cli.deployments.deploy", true);
@@ -1897,7 +1969,7 @@ function registerCreateCommand(program2) {
1897
1969
  try {
1898
1970
  await requireAuth(apiUrl);
1899
1971
  if (!json) {
1900
- clack9.intro("Create a new InsForge project");
1972
+ clack10.intro("Create a new InsForge project");
1901
1973
  }
1902
1974
  let orgId = opts.orgId;
1903
1975
  if (!orgId) {
@@ -1908,14 +1980,14 @@ function registerCreateCommand(program2) {
1908
1980
  if (json) {
1909
1981
  throw new CLIError("Specify --org-id in JSON mode.");
1910
1982
  }
1911
- const selected = await clack9.select({
1983
+ const selected = await clack10.select({
1912
1984
  message: "Select an organization:",
1913
1985
  options: orgs.map((o) => ({
1914
1986
  value: o.id,
1915
1987
  label: o.name
1916
1988
  }))
1917
1989
  });
1918
- if (clack9.isCancel(selected)) process.exit(0);
1990
+ if (clack10.isCancel(selected)) process.exit(0);
1919
1991
  orgId = selected;
1920
1992
  }
1921
1993
  const globalConfig = getGlobalConfig();
@@ -1924,11 +1996,11 @@ function registerCreateCommand(program2) {
1924
1996
  let projectName = opts.name;
1925
1997
  if (!projectName) {
1926
1998
  if (json) throw new CLIError("--name is required in JSON mode.");
1927
- const name = await clack9.text({
1999
+ const name = await clack10.text({
1928
2000
  message: "Project name:",
1929
2001
  validate: (v) => v.length >= 2 ? void 0 : "Name must be at least 2 characters"
1930
2002
  });
1931
- if (clack9.isCancel(name)) process.exit(0);
2003
+ if (clack10.isCancel(name)) process.exit(0);
1932
2004
  projectName = name;
1933
2005
  }
1934
2006
  let template = opts.template;
@@ -1936,7 +2008,7 @@ function registerCreateCommand(program2) {
1936
2008
  if (json) {
1937
2009
  template = "empty";
1938
2010
  } else {
1939
- const selected = await clack9.select({
2011
+ const selected = await clack10.select({
1940
2012
  message: "Choose a starter template:",
1941
2013
  options: [
1942
2014
  { value: "react", label: "Web app template with React" },
@@ -1944,11 +2016,11 @@ function registerCreateCommand(program2) {
1944
2016
  { value: "empty", label: "Empty project" }
1945
2017
  ]
1946
2018
  });
1947
- if (clack9.isCancel(selected)) process.exit(0);
2019
+ if (clack10.isCancel(selected)) process.exit(0);
1948
2020
  template = selected;
1949
2021
  }
1950
2022
  }
1951
- const s = !json ? clack9.spinner() : null;
2023
+ const s = !json ? clack10.spinner() : null;
1952
2024
  s?.start("Creating project...");
1953
2025
  const project = await createProject(orgId, projectName, opts.region, apiUrl);
1954
2026
  s?.message("Waiting for project to become active...");
@@ -1969,10 +2041,11 @@ function registerCreateCommand(program2) {
1969
2041
  if (hasTemplate) {
1970
2042
  await downloadTemplate(template, projectConfig, projectName, json, apiUrl);
1971
2043
  }
2044
+ await installCliGlobally(json);
1972
2045
  await installSkills(json);
1973
2046
  await reportCliUsage("cli.create", true, 6);
1974
2047
  if (hasTemplate) {
1975
- const installSpinner = !json ? clack9.spinner() : null;
2048
+ const installSpinner = !json ? clack10.spinner() : null;
1976
2049
  installSpinner?.start("Installing dependencies...");
1977
2050
  try {
1978
2051
  await execAsync2("npm install", { cwd: process.cwd(), maxBuffer: 10 * 1024 * 1024 });
@@ -1980,19 +2053,19 @@ function registerCreateCommand(program2) {
1980
2053
  } catch (err) {
1981
2054
  installSpinner?.stop("Failed to install dependencies");
1982
2055
  if (!json) {
1983
- clack9.log.warn(`npm install failed: ${err.message}`);
1984
- clack9.log.info("Run `npm install` manually to install dependencies.");
2056
+ clack10.log.warn(`npm install failed: ${err.message}`);
2057
+ clack10.log.info("Run `npm install` manually to install dependencies.");
1985
2058
  }
1986
2059
  }
1987
2060
  }
1988
2061
  let liveUrl = null;
1989
2062
  if (hasTemplate && !json) {
1990
- const shouldDeploy = await clack9.confirm({
2063
+ const shouldDeploy = await clack10.confirm({
1991
2064
  message: "Would you like to deploy now?"
1992
2065
  });
1993
- if (!clack9.isCancel(shouldDeploy) && shouldDeploy) {
2066
+ if (!clack10.isCancel(shouldDeploy) && shouldDeploy) {
1994
2067
  try {
1995
- const deploySpinner = clack9.spinner();
2068
+ const deploySpinner = clack10.spinner();
1996
2069
  const result = await deployProject({
1997
2070
  sourceDir: process.cwd(),
1998
2071
  spinner: deploySpinner
@@ -2002,12 +2075,12 @@ function registerCreateCommand(program2) {
2002
2075
  liveUrl = result.liveUrl;
2003
2076
  } else {
2004
2077
  deploySpinner.stop("Deployment is still building");
2005
- clack9.log.info(`Deployment ID: ${result.deploymentId}`);
2006
- clack9.log.warn("Deployment did not finish within 2 minutes.");
2007
- clack9.log.info(`Check status with: insforge deployments status ${result.deploymentId}`);
2078
+ clack10.log.info(`Deployment ID: ${result.deploymentId}`);
2079
+ clack10.log.warn("Deployment did not finish within 2 minutes.");
2080
+ clack10.log.info(`Check status with: insforge deployments status ${result.deploymentId}`);
2008
2081
  }
2009
2082
  } catch (err) {
2010
- clack9.log.warn(`Deploy failed: ${err.message}`);
2083
+ clack10.log.warn(`Deploy failed: ${err.message}`);
2011
2084
  }
2012
2085
  }
2013
2086
  }
@@ -2023,11 +2096,11 @@ function registerCreateCommand(program2) {
2023
2096
  }
2024
2097
  });
2025
2098
  } else {
2026
- clack9.log.step(`Dashboard: ${dashboardUrl}`);
2099
+ clack10.log.step(`Dashboard: ${dashboardUrl}`);
2027
2100
  if (liveUrl) {
2028
- clack9.log.success(`Live site: ${liveUrl}`);
2101
+ clack10.log.success(`Live site: ${liveUrl}`);
2029
2102
  }
2030
- clack9.outro("Done!");
2103
+ clack10.outro("Done!");
2031
2104
  }
2032
2105
  } catch (err) {
2033
2106
  handleError(err, json);
@@ -2035,7 +2108,7 @@ function registerCreateCommand(program2) {
2035
2108
  });
2036
2109
  }
2037
2110
  async function downloadTemplate(framework, projectConfig, projectName, json, _apiUrl) {
2038
- const s = !json ? clack9.spinner() : null;
2111
+ const s = !json ? clack10.spinner() : null;
2039
2112
  s?.start("Downloading template...");
2040
2113
  try {
2041
2114
  const anonKey = await getAnonKey();
@@ -2066,8 +2139,8 @@ async function downloadTemplate(framework, projectConfig, projectName, json, _ap
2066
2139
  } catch (err) {
2067
2140
  s?.stop("Template download failed");
2068
2141
  if (!json) {
2069
- clack9.log.warn(`Failed to download template: ${err.message}`);
2070
- clack9.log.info("You can manually set up the template later.");
2142
+ clack10.log.warn(`Failed to download template: ${err.message}`);
2143
+ clack10.log.info("You can manually set up the template later.");
2071
2144
  }
2072
2145
  }
2073
2146
  }
@@ -2250,7 +2323,7 @@ function registerDeploymentsStatusCommand(deploymentsCmd2) {
2250
2323
  }
2251
2324
 
2252
2325
  // src/commands/deployments/cancel.ts
2253
- import * as clack10 from "@clack/prompts";
2326
+ import * as clack11 from "@clack/prompts";
2254
2327
  function registerDeploymentsCancelCommand(deploymentsCmd2) {
2255
2328
  deploymentsCmd2.command("cancel <id>").description("Cancel a deployment").action(async (id, _opts, cmd) => {
2256
2329
  const { json, yes } = getRootOpts(cmd);
@@ -2258,10 +2331,10 @@ function registerDeploymentsCancelCommand(deploymentsCmd2) {
2258
2331
  await requireAuth();
2259
2332
  if (!getProjectConfig()) throw new ProjectNotLinkedError();
2260
2333
  if (!yes && !json) {
2261
- const confirmed = await clack10.confirm({
2334
+ const confirmed = await clack11.confirm({
2262
2335
  message: `Cancel deployment ${id}?`
2263
2336
  });
2264
- if (clack10.isCancel(confirmed) || !confirmed) process.exit(0);
2337
+ if (clack11.isCancel(confirmed) || !confirmed) process.exit(0);
2265
2338
  }
2266
2339
  const res = await ossFetch(`/api/deployments/${id}/cancel`, { method: "POST" });
2267
2340
  const result = await res.json();
@@ -2464,17 +2537,17 @@ function registerSecretsUpdateCommand(secretsCmd2) {
2464
2537
  }
2465
2538
 
2466
2539
  // src/commands/secrets/delete.ts
2467
- import * as clack11 from "@clack/prompts";
2540
+ import * as clack12 from "@clack/prompts";
2468
2541
  function registerSecretsDeleteCommand(secretsCmd2) {
2469
2542
  secretsCmd2.command("delete <key>").description("Delete a secret").action(async (key, _opts, cmd) => {
2470
2543
  const { json, yes } = getRootOpts(cmd);
2471
2544
  try {
2472
2545
  await requireAuth();
2473
2546
  if (!yes && !json) {
2474
- const confirm7 = await clack11.confirm({
2547
+ const confirm8 = await clack12.confirm({
2475
2548
  message: `Delete secret "${key}"? This cannot be undone.`
2476
2549
  });
2477
- if (!confirm7 || clack11.isCancel(confirm7)) {
2550
+ if (!confirm8 || clack12.isCancel(confirm8)) {
2478
2551
  process.exit(0);
2479
2552
  }
2480
2553
  }
@@ -2650,17 +2723,17 @@ function registerSchedulesUpdateCommand(schedulesCmd2) {
2650
2723
  }
2651
2724
 
2652
2725
  // src/commands/schedules/delete.ts
2653
- import * as clack12 from "@clack/prompts";
2726
+ import * as clack13 from "@clack/prompts";
2654
2727
  function registerSchedulesDeleteCommand(schedulesCmd2) {
2655
2728
  schedulesCmd2.command("delete <id>").description("Delete a schedule").action(async (id, _opts, cmd) => {
2656
2729
  const { json, yes } = getRootOpts(cmd);
2657
2730
  try {
2658
2731
  await requireAuth();
2659
2732
  if (!yes && !json) {
2660
- const confirm7 = await clack12.confirm({
2733
+ const confirm8 = await clack13.confirm({
2661
2734
  message: `Delete schedule "${id}"? This cannot be undone.`
2662
2735
  });
2663
- if (!confirm7 || clack12.isCancel(confirm7)) {
2736
+ if (!confirm8 || clack13.isCancel(confirm8)) {
2664
2737
  process.exit(0);
2665
2738
  }
2666
2739
  }
@@ -2889,6 +2962,7 @@ registerFunctionsCommands(functionsCmd);
2889
2962
  registerFunctionsCodeCommand(functionsCmd);
2890
2963
  registerFunctionsDeployCommand(functionsCmd);
2891
2964
  registerFunctionsInvokeCommand(functionsCmd);
2965
+ registerFunctionsDeleteCommand(functionsCmd);
2892
2966
  var storageCmd = program.command("storage").description("Manage storage");
2893
2967
  registerStorageBucketsCommand(storageCmd);
2894
2968
  registerStorageCreateBucketCommand(storageCmd);
@@ -2933,7 +3007,7 @@ async function showInteractiveMenu() {
2933
3007
  } catch {
2934
3008
  }
2935
3009
  console.log(INSFORGE_LOGO);
2936
- clack13.intro(`InsForge CLI v${pkg.version}`);
3010
+ clack14.intro(`InsForge CLI v${pkg.version}`);
2937
3011
  const options = [];
2938
3012
  if (!isLoggedIn) {
2939
3013
  options.push({ value: "login", label: "Log in to InsForge" });
@@ -2949,12 +3023,12 @@ async function showInteractiveMenu() {
2949
3023
  { value: "docs", label: "View documentation" },
2950
3024
  { value: "help", label: "Show all commands" }
2951
3025
  );
2952
- const action = await clack13.select({
3026
+ const action = await clack14.select({
2953
3027
  message: "What would you like to do?",
2954
3028
  options
2955
3029
  });
2956
- if (clack13.isCancel(action)) {
2957
- clack13.cancel("Bye!");
3030
+ if (clack14.isCancel(action)) {
3031
+ clack14.cancel("Bye!");
2958
3032
  process.exit(0);
2959
3033
  }
2960
3034
  switch (action) {