@tscircuit/cli 0.0.8 → 0.0.9

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/bun.lockb CHANGED
Binary file
package/dist/cli.js CHANGED
@@ -200,7 +200,6 @@ var require_dist = __commonJS((exports, module) => {
200
200
  });
201
201
 
202
202
  // lib/util/create-context-and-run-program.ts
203
- import Configstore from "configstore";
204
203
  import minimist from "minimist";
205
204
  import _ from "lodash";
206
205
  import {perfectCli} from "perfect-cli";
@@ -210,7 +209,7 @@ import {Command} from "commander";
210
209
  // package.json
211
210
  var package_default = {
212
211
  name: "@tscircuit/cli",
213
- version: "0.0.8",
212
+ version: "0.0.9",
214
213
  private: false,
215
214
  type: "module",
216
215
  description: "Command line tool for developing, publishing and installing tscircuit circuits",
@@ -242,9 +241,11 @@ var package_default = {
242
241
  chokidar: "^3.6.0",
243
242
  commander: "^12.0.0",
244
243
  configstore: "^6.0.0",
244
+ dargs: "^8.1.0",
245
245
  "dax-sh": "^0.39.2",
246
246
  delay: "^6.0.0",
247
247
  edgespec: "^0.0.69",
248
+ esbuild: "^0.20.2",
248
249
  glob: "^10.3.10",
249
250
  hono: "^4.1.0",
250
251
  ignore: "^5.3.1",
@@ -346,7 +347,10 @@ var authLogin = async (ctx, args) => {
346
347
  console.log("Ready to use!");
347
348
  };
348
349
  // lib/cmd-fns/auth-logout.ts
350
+ import kleur from "kleur";
349
351
  var authLogout = async (ctx, args) => {
352
+ ctx.profile_config.delete("session_token");
353
+ console.log(kleur.green("Logged out!"));
350
354
  };
351
355
  // lib/cmd-fns/auth-sessions-create.ts
352
356
  var authSessionsCreate = async (ctx, args) => {
@@ -421,7 +425,7 @@ var packageReleasesGet = async (ctx, args) => {
421
425
  };
422
426
  // lib/cmd-fns/package-releases-create.ts
423
427
  import {z as z7} from "zod";
424
- import kleur from "kleur";
428
+ import kleur2 from "kleur";
425
429
  var packageReleasesCreate = async (ctx, args) => {
426
430
  args.version = args.releaseVersion;
427
431
  const params = z7.object({
@@ -442,7 +446,7 @@ var packageReleasesCreate = async (ctx, args) => {
442
446
  const package_release = await ctx.axios.post("/package_releases/create", {
443
447
  package_name_with_version: packageNameWithVersion
444
448
  }).then((r) => r.data.package_release);
445
- console.log(`Package release created! ${kleur.gray(package_release.package_release_id)}`);
449
+ console.log(`Package release created! ${kleur2.gray(package_release.package_release_id)}`);
446
450
  };
447
451
  // lib/cmd-fns/package-files-list.ts
448
452
  import {z as z8} from "zod";
@@ -492,7 +496,7 @@ var packageFilesDownload = async (ctx, args) => {
492
496
  // lib/cmd-fns/package-files-create.ts
493
497
  import {z as z10} from "zod";
494
498
  import * as fs2 from "fs/promises";
495
- import kleur2 from "kleur";
499
+ import kleur3 from "kleur";
496
500
  var packageFilesCreate = async (ctx, args) => {
497
501
  const params = z10.object({
498
502
  file: z10.string(),
@@ -507,7 +511,7 @@ var packageFilesCreate = async (ctx, args) => {
507
511
  package_name_with_version: packageNameWithVersion,
508
512
  package_release_id: packageReleaseId
509
513
  }).then((r) => r.data.package_file);
510
- console.log(`Package file created ${kleur2.gray(package_file.package_file_id)}`);
514
+ console.log(`Package file created ${kleur3.gray(package_file.package_file_id)}`);
511
515
  };
512
516
  // lib/cmd-fns/package-examples-list.ts
513
517
  import {z as z11} from "zod";
@@ -606,7 +610,7 @@ var packageExamplesCreate = async (ctx, args) => {
606
610
  console.log(package_example);
607
611
  };
608
612
  // lib/cmd-fns/publish/index.ts
609
- import kleur3 from "kleur";
613
+ import kleur4 from "kleur";
610
614
  import {z as z14} from "zod";
611
615
  import * as Path2 from "path";
612
616
  import * as fs5 from "fs/promises";
@@ -678,6 +682,7 @@ var inferExportNameFromSource = (sourceContent) => {
678
682
  import $2 from "dax-sh";
679
683
  import semver from "semver";
680
684
  import {unlink as unlink2} from "fs/promises";
685
+ import esbuild from "esbuild";
681
686
  var publish = async (ctx, args) => {
682
687
  const params = z14.object({
683
688
  increment: z14.boolean().optional(),
@@ -685,26 +690,21 @@ var publish = async (ctx, args) => {
685
690
  lock: z14.boolean().optional()
686
691
  }).parse(args);
687
692
  if (typeof Bun === "undefined") {
688
- console.log(kleur3.red("\n\n----------------------------------\nBun is currently required for publishing packages to the tscircuit registry. Try installing bun:\nhhttps://bun.sh/docs/installation\n\n---------------------"));
693
+ console.log(kleur4.red("\n\n----------------------------------\nBun is currently required for publishing packages to the tscircuit registry. Try installing bun:\nhhttps://bun.sh/docs/installation\n\n---------------------"));
689
694
  process.exit(1);
690
695
  }
691
696
  const shouldIncrement = params.increment || params.patch;
692
697
  if (!await fs5.exists(Path2.join(ctx.cwd, "package.json"))) {
693
- console.log(kleur3.red("No package.json found in current directory"));
698
+ console.log(kleur4.red("No package.json found in current directory"));
694
699
  process.exit(1);
695
700
  }
696
701
  const packageJson = JSON.parse(await readFileSync(Path2.join(ctx.cwd, "package.json"), "utf-8"));
697
- await Bun.build({
698
- root: ctx.cwd,
699
- entrypoints: ["index.ts"],
700
- external: [
701
- ...Object.keys(packageJson.dependencies || {}),
702
- ...Object.keys(packageJson.devDependencies || {}),
703
- ...Object.keys(packageJson.peerDependencies || {}),
704
- ...Object.keys(packageJson.trustedDependencies || {})
705
- ],
706
- outdir: "dist",
707
- target: "node"
702
+ await esbuild.build({
703
+ entryPoints: ["index.ts"],
704
+ bundle: true,
705
+ platform: "node",
706
+ packages: "external",
707
+ outdir: "dist"
708
708
  });
709
709
  let { name, version } = packageJson;
710
710
  name = name.replace(/^@/, "");
@@ -715,7 +715,7 @@ var publish = async (ctx, args) => {
715
715
  });
716
716
  if (!existingPackage) {
717
717
  if (!packageJson.name.includes("/")) {
718
- console.log(kleur3.yellow(`Package name "${packageJson.name}" is not scoped. Scoped package names are recommended on the tscircuit registry.`));
718
+ console.log(kleur4.yellow(`Package name "${packageJson.name}" is not scoped. Scoped package names are recommended on the tscircuit registry.`));
719
719
  const myAccount = await ctx.axios.get("/accounts/get").then((r) => r.data.account);
720
720
  const newScopedName = `${myAccount.github_username}/${packageJson.name}`;
721
721
  const { confirmNameChange } = await prompts({
@@ -725,7 +725,7 @@ var publish = async (ctx, args) => {
725
725
  message: `Would you like to change the package name to the scoped name "@${newScopedName}"?`
726
726
  });
727
727
  if (confirm === undefined) {
728
- console.log(kleur3.red("Aborted."));
728
+ console.log(kleur4.red("Aborted."));
729
729
  process.exit(1);
730
730
  }
731
731
  if (confirmNameChange) {
@@ -734,7 +734,7 @@ var publish = async (ctx, args) => {
734
734
  name = newScopedName;
735
735
  }
736
736
  }
737
- console.log(kleur3.green(`Creating package "${packageJson.name}" on tscircuit registry...`));
737
+ console.log(kleur4.green(`Creating package "${packageJson.name}" on tscircuit registry...`));
738
738
  let description = packageJson.description;
739
739
  if (!description) {
740
740
  description = (await prompts({
@@ -753,14 +753,14 @@ var publish = async (ctx, args) => {
753
753
  throw e;
754
754
  });
755
755
  if (existingRelease) {
756
- console.log(kleur3.gray(`Package release already exists: ${name}@${version}`));
756
+ console.log(kleur4.gray(`Package release already exists: ${name}@${version}`));
757
757
  if (shouldIncrement) {
758
- console.log(kleur3.green(`Incrementing version from ${version} to ${semver.inc(version, "patch")}...`));
758
+ console.log(kleur4.green(`Incrementing version from ${version} to ${semver.inc(version, "patch")}...`));
759
759
  version = semver.inc(version, "patch");
760
760
  packageJson.version = version;
761
761
  await fs5.writeFile(Path2.join(ctx.cwd, "package.json"), JSON.stringify(packageJson, null, 2));
762
762
  } else {
763
- console.log(kleur3.blue(`Want to increment the version and publish a new release? Use "--increment"!`));
763
+ console.log(kleur4.blue(`Want to increment the version and publish a new release? Use "--increment"!`));
764
764
  throw new Error("Package release already exists");
765
765
  }
766
766
  }
@@ -770,7 +770,7 @@ var publish = async (ctx, args) => {
770
770
  }).then((r) => r.data.package_release);
771
771
  const filePaths = await getAllPackageFiles(ctx);
772
772
  if (!filePaths.includes("README.md")) {
773
- console.log(kleur3.yellow("No README.md found in package files. A README.md is recommended on the tscircuit registry."));
773
+ console.log(kleur4.yellow("No README.md found in package files. A README.md is recommended on the tscircuit registry."));
774
774
  const { confirmReadme } = await prompts({
775
775
  type: "confirm",
776
776
  name: "confirmReadme",
@@ -778,7 +778,7 @@ var publish = async (ctx, args) => {
778
778
  message: "Would you like to add a README.md?"
779
779
  });
780
780
  if (confirmReadme === undefined) {
781
- console.log(kleur3.red("Aborted."));
781
+ console.log(kleur4.red("Aborted."));
782
782
  process.exit(1);
783
783
  }
784
784
  if (confirmReadme) {
@@ -803,7 +803,7 @@ var publish = async (ctx, args) => {
803
803
  exportName
804
804
  }).catch((e) => e);
805
805
  if (tscircuit_soup instanceof Error) {
806
- console.log(kleur3.red(`Error soupifying ${filePath}: ${tscircuit_soup}, skipping`));
806
+ console.log(kleur4.red(`Error soupifying ${filePath}: ${tscircuit_soup}, skipping`));
807
807
  continue;
808
808
  }
809
809
  await ctx.axios.post("/package_examples/create", {
@@ -818,7 +818,7 @@ var publish = async (ctx, args) => {
818
818
  await fs5.mkdir(Path2.dirname(tmpTarballPath), { recursive: true });
819
819
  const npm_pack_outputs = await $2`cd ${ctx.cwd} && npm pack --json --pack-destination ${Path2.dirname(tmpTarballPath)}`.json();
820
820
  if (!await fs5.exists(tmpTarballPath)) {
821
- console.log(kleur3.red(`Couldn't find tarball at ${tmpTarballPath}`));
821
+ console.log(kleur4.red(`Couldn't find tarball at ${tmpTarballPath}`));
822
822
  process.exit(1);
823
823
  }
824
824
  await ctx.axios.post("/package_files/create", {
@@ -834,7 +834,7 @@ var publish = async (ctx, args) => {
834
834
  is_locked: params.lock ? true : false,
835
835
  is_latest: true
836
836
  });
837
- console.log(kleur3.green(`Published ${name}@${version}!\nhttps://registry.tscircuit.com/${name}`));
837
+ console.log(kleur4.green(`Published ${name}@${version}!\nhttps://registry.tscircuit.com/${name}`));
838
838
  };
839
839
  // lib/cmd-fns/soupify.ts
840
840
  import {z as z15} from "zod";
@@ -857,7 +857,7 @@ var soupifyCmd = async (ctx, args) => {
857
857
  };
858
858
  // lib/cmd-fns/dev/index.ts
859
859
  import {z as z18} from "zod";
860
- import kleur10 from "kleur";
860
+ import kleur11 from "kleur";
861
861
  import prompts2 from "prompts";
862
862
  import open from "open";
863
863
 
@@ -868,7 +868,7 @@ import {createWithEdgeSpec} from "edgespec";
868
868
  import {Kysely, sql, SqliteDialect} from "kysely";
869
869
  import {mkdirSync} from "fs";
870
870
  import * as Path3 from "path";
871
- import kleur4 from "kleur";
871
+ import kleur5 from "kleur";
872
872
  import"edgespec/middleware";
873
873
  import {z as z16} from "zod";
874
874
  import {NotFoundError as NotFoundError2} from "edgespec/middleware";
@@ -934,7 +934,7 @@ var withErrorResponse = async (req, ctx, next) => {
934
934
  try {
935
935
  return await next(req, ctx);
936
936
  } catch (error) {
937
- console.error(kleur4.red("Intercepted error:"), error);
937
+ console.error(kleur5.red("Intercepted error:"), error);
938
938
  if (error instanceof Response) {
939
939
  return error;
940
940
  }
@@ -1146,15 +1146,15 @@ var startDevServer = async ({
1146
1146
  };
1147
1147
 
1148
1148
  // lib/cmd-fns/dev/get-dev-server-axios.ts
1149
- import kleur5 from "kleur";
1149
+ import kleur6 from "kleur";
1150
1150
  import defaultAxios from "axios";
1151
1151
  var getDevServerAxios = ({ serverUrl }) => {
1152
1152
  const devServerAxios = defaultAxios.create({
1153
1153
  baseURL: serverUrl
1154
1154
  });
1155
1155
  devServerAxios.interceptors.response.use((res) => res, (err) => {
1156
- console.log(kleur5.red(`[ERR] ${err.response?.status} ${err.config.method?.toUpperCase()} ${err.config.url}\n\n${JSON.stringify(err.response?.data, null, " ")}`.replace(/\\n/g, "\n").replace(/\\"/g, '"')));
1157
- console.log(kleur5.yellow("[Request Body]:"), err.config.data);
1156
+ console.log(kleur6.red(`[ERR] ${err.response?.status} ${err.config.method?.toUpperCase()} ${err.config.url}\n\n${JSON.stringify(err.response?.data, null, " ")}`.replace(/\\n/g, "\n").replace(/\\"/g, '"')));
1157
+ console.log(kleur6.yellow("[Request Body]:"), err.config.data);
1158
1158
  return Promise.reject(err);
1159
1159
  });
1160
1160
  return devServerAxios;
@@ -1165,7 +1165,7 @@ import {join as joinPath2} from "path";
1165
1165
  import {readdirSync as readdirSync2} from "fs";
1166
1166
 
1167
1167
  // lib/cmd-fns/dev/soupify-and-upload-example-file.ts
1168
- import kleur6 from "kleur";
1168
+ import kleur7 from "kleur";
1169
1169
  import {join as joinPath} from "path";
1170
1170
  import {readFileSync as readFileSync2} from "fs";
1171
1171
  var soupifyAndUploadExampleFile = async ({
@@ -1177,20 +1177,20 @@ var soupifyAndUploadExampleFile = async ({
1177
1177
  const examplePath = joinPath(examplesDir, exampleFileName);
1178
1178
  const exampleContent = readFileSync2(examplePath).toString();
1179
1179
  const exportName = inferExportNameFromSource(exampleContent);
1180
- console.log(kleur6.gray(`[soupifying] ${exampleFileName}...`));
1180
+ console.log(kleur7.gray(`[soupifying] ${exampleFileName}...`));
1181
1181
  const soup = await soupify({
1182
1182
  filePath: examplePath,
1183
1183
  exportName
1184
1184
  });
1185
- console.log(kleur6.gray(`[uploading ] ${exampleFileName}...`));
1185
+ console.log(kleur7.gray(`[uploading ] ${exampleFileName}...`));
1186
1186
  await devServerAxios.post("/api/dev_package_examples/create", {
1187
1187
  tscircuit_soup: soup,
1188
1188
  file_path: examplePath,
1189
1189
  export_name: exportName
1190
1190
  });
1191
- console.log(kleur6.gray(`[ done ] ${exampleFileName}!`));
1191
+ console.log(kleur7.gray(`[ done ] ${exampleFileName}!`));
1192
1192
  } catch (e) {
1193
- console.log(kleur6.red(e.toString()));
1193
+ console.log(kleur7.red(e.toString()));
1194
1194
  }
1195
1195
  };
1196
1196
 
@@ -1220,7 +1220,7 @@ import * as Path7 from "path";
1220
1220
 
1221
1221
  // lib/cmd-fns/dev/start-watcher.ts
1222
1222
  import chokidar from "chokidar";
1223
- import kleur7 from "kleur";
1223
+ import kleur8 from "kleur";
1224
1224
  var startWatcher = async ({
1225
1225
  cwd,
1226
1226
  devServerAxios
@@ -1240,7 +1240,7 @@ var startWatcher = async ({
1240
1240
  async function uploadInBackground() {
1241
1241
  while (upload_queue_state.should_run) {
1242
1242
  if (upload_queue_state.dirty) {
1243
- console.log(kleur7.yellow("Changes detected, re-uploading examples..."));
1243
+ console.log(kleur8.yellow("Changes detected, re-uploading examples..."));
1244
1244
  upload_queue_state.dirty = false;
1245
1245
  await uploadExamplesFromDirectory({ cwd, devServerAxios });
1246
1246
  }
@@ -1259,7 +1259,7 @@ var startWatcher = async ({
1259
1259
 
1260
1260
  // lib/cmd-fns/init/create-or-modify-npmrc.ts
1261
1261
  import {existsSync, writeFileSync as writeFileSync3} from "fs";
1262
- import kleur8 from "kleur";
1262
+ import kleur9 from "kleur";
1263
1263
  import * as Path4 from "path";
1264
1264
 
1265
1265
  // lib/cmd-fns/init/get-generated-npmrc.ts
@@ -1274,7 +1274,7 @@ var createOrModifyNpmrc = async ({ quiet = true }, ctx) => {
1274
1274
  const npmrcPath = Path4.join(ctx.cwd, ".npmrc");
1275
1275
  if (existsSync(npmrcPath)) {
1276
1276
  if (!quiet) {
1277
- console.log(kleur8.yellow("npmrc already exists, not doing anything"));
1277
+ console.log(kleur9.yellow("npmrc already exists, not doing anything"));
1278
1278
  }
1279
1279
  } else {
1280
1280
  writeFileSync3(npmrcPath, getGeneratedNpmrc(ctx));
@@ -1282,18 +1282,18 @@ var createOrModifyNpmrc = async ({ quiet = true }, ctx) => {
1282
1282
  };
1283
1283
 
1284
1284
  // lib/cmd-fns/dev/check-if-initialized.ts
1285
- import kleur9 from "kleur";
1285
+ import kleur10 from "kleur";
1286
1286
  import * as Path5 from "path";
1287
1287
  import {existsSync as existsSync2, readFileSync as readFileSync4} from "fs";
1288
1288
  var checkIfInitialized = async (ctx) => {
1289
1289
  const packageJsonPath = Path5.join(ctx.cwd, "package.json");
1290
1290
  if (!existsSync2(packageJsonPath)) {
1291
- console.error(kleur9.red(`No package.json found`));
1291
+ console.error(kleur10.red(`No package.json found`));
1292
1292
  return false;
1293
1293
  }
1294
1294
  const packageJsonRaw = readFileSync4(packageJsonPath, "utf-8");
1295
1295
  if (!packageJsonRaw.includes("tscircuit")) {
1296
- console.error(kleur9.red(`No tscircuit dependencies are installed in this project.`));
1296
+ console.error(kleur10.red(`No tscircuit dependencies are installed in this project.`));
1297
1297
  return false;
1298
1298
  }
1299
1299
  return true;
@@ -1456,7 +1456,7 @@ var devCmd = async (ctx, args) => {
1456
1456
  await createOrModifyNpmrc({ quiet: false }, ctx);
1457
1457
  unlink3(Path7.join(cwd, ".tscircuit/dev-server.db")).catch(() => {
1458
1458
  });
1459
- console.log(kleur10.green(`\n--------------------------------------------\n\nStarting dev server http://localhost:${port}\n\n--------------------------------------------\n\n`));
1459
+ console.log(kleur11.green(`\n--------------------------------------------\n\nStarting dev server http://localhost:${port}\n\n--------------------------------------------\n\n`));
1460
1460
  const serverUrl = `http://localhost:${port}`;
1461
1461
  const devServerAxios = getDevServerAxios({ serverUrl });
1462
1462
  const server = await startDevServer({ port, devServerAxios });
@@ -1492,7 +1492,7 @@ var devCmd = async (ctx, args) => {
1492
1492
  }
1493
1493
  };
1494
1494
  // lib/cmd-fns/add.ts
1495
- import kleur11 from "kleur";
1495
+ import kleur12 from "kleur";
1496
1496
  import {z as z19} from "zod";
1497
1497
  import $4 from "dax-sh";
1498
1498
  var addCmd = async (ctx, args) => {
@@ -1505,11 +1505,11 @@ var addCmd = async (ctx, args) => {
1505
1505
  $4.cd(ctx.cwd);
1506
1506
  const flagsString = params.flags.dev ? "--dev" : "";
1507
1507
  const cmd = `npm add ${flagsString} ${params.packages.map((p) => `@tsci/${p.replace(/\//, ".")}`).join(" ")}`;
1508
- console.log(kleur11.gray(`> ${cmd}`));
1508
+ console.log(kleur12.gray(`> ${cmd}`));
1509
1509
  await $4`npm add ${flagsString} ${params.packages.map((p) => `@tsci/${p.replace(/\//, ".")}`).join(" ")}`;
1510
1510
  };
1511
1511
  // lib/cmd-fns/remove.ts
1512
- import kleur12 from "kleur";
1512
+ import kleur13 from "kleur";
1513
1513
  import {z as z20} from "zod";
1514
1514
  import $5 from "dax-sh";
1515
1515
  var removeCmd = async (ctx, args) => {
@@ -1522,11 +1522,11 @@ var removeCmd = async (ctx, args) => {
1522
1522
  $5.cd(ctx.cwd);
1523
1523
  const flagsString = "";
1524
1524
  const cmd = `npm remove ${flagsString} ${params.packages.map((p) => `@tsci/${p.replace(/\//, ".")}`).join(" ")}`;
1525
- console.log(kleur12.gray(`> ${cmd}`));
1525
+ console.log(kleur13.gray(`> ${cmd}`));
1526
1526
  await $5`npm remove ${flagsString} ${params.packages.map((p) => `@tsci/${p.replace(/\//, ".")}`).join(" ")}`;
1527
1527
  };
1528
1528
  // lib/cmd-fns/install.ts
1529
- import kleur13 from "kleur";
1529
+ import kleur14 from "kleur";
1530
1530
  import {z as z21} from "zod";
1531
1531
  import $6 from "dax-sh";
1532
1532
  var installCmd = async (ctx, args) => {
@@ -1539,11 +1539,11 @@ var installCmd = async (ctx, args) => {
1539
1539
  $6.cd(ctx.cwd);
1540
1540
  const flagsString = params.flags.dev ? "--dev" : "";
1541
1541
  const cmd = `npm install ${flagsString} ${params.packages.map((p) => `@tsci/${p.replace(/\//, ".")}`).join(" ")}`;
1542
- console.log(kleur13.gray(`> ${cmd}`));
1542
+ console.log(kleur14.gray(`> ${cmd}`));
1543
1543
  await $6`npm install ${flagsString} ${params.packages.map((p) => `@tsci/${p.replace(/\//, ".")}`).join(" ")}`;
1544
1544
  };
1545
1545
  // lib/cmd-fns/uninstall.ts
1546
- import kleur14 from "kleur";
1546
+ import kleur15 from "kleur";
1547
1547
  import {z as z23} from "zod";
1548
1548
  import $7 from "dax-sh";
1549
1549
  // lib/cmd-fns/dev-server-upload.ts
@@ -1562,6 +1562,22 @@ var devServerUpload = async (ctx, args) => {
1562
1562
  const watcher = await startWatcher({ cwd: params.dir, devServerAxios });
1563
1563
  }
1564
1564
  };
1565
+ // lib/cmd-fns/open.ts
1566
+ import {existsSync as existsSync4, readFileSync as readFileSync6} from "fs";
1567
+ import kleur16 from "kleur";
1568
+ import * as Path8 from "path";
1569
+ import open2 from "open";
1570
+ var openCmd = async (ctx, args) => {
1571
+ const packageJsonPath = Path8.join(ctx.cwd, "package.json");
1572
+ if (!existsSync4(packageJsonPath)) {
1573
+ console.log(kleur16.red("No package.json found in current directory"));
1574
+ process.exit(1);
1575
+ }
1576
+ const packageJson = JSON.parse(readFileSync6(packageJsonPath, "utf-8"));
1577
+ const registryUrl = `${ctx.registry_url}/${packageJson.name.replace("@", "")}`;
1578
+ console.log(`Opening ${registryUrl} in your browser...`);
1579
+ await open2(registryUrl);
1580
+ };
1565
1581
  // lib/get-program.ts
1566
1582
  var getProgram = (ctx) => {
1567
1583
  const cmd = new Command("tsci");
@@ -1610,12 +1626,13 @@ var getProgram = (ctx) => {
1610
1626
  cmd.command("uninstall").argument("<packages...>", "Packages to uninstall").action((packages, flags) => installCmd(ctx, { packages, flags }));
1611
1627
  const devServerCmd = cmd.command("dev-server");
1612
1628
  devServerCmd.command("upload").option("--dir <dir>", "Directory to upload (defaults to current directory)").option("-w, --watch", "Watch for changes").option("-p, --port", "Port dev server is running on (default: 3020)").action((args) => devServerUpload(ctx, args));
1629
+ cmd.command("open").action((args) => openCmd(ctx, args));
1613
1630
  return cmd;
1614
1631
  };
1615
1632
 
1616
1633
  // lib/util/create-context-and-run-program.ts
1617
1634
  import defaultAxios2 from "axios";
1618
- import kleur15 from "kleur";
1635
+ import kleur17 from "kleur";
1619
1636
 
1620
1637
  // lib/param-handlers/interact-for-local-directory.ts
1621
1638
  import * as fs6 from "fs/promises";
@@ -1835,15 +1852,27 @@ var PARAM_HANDLERS_BY_PARAM_NAME = {
1835
1852
  package_example_id: interactForPackageExampleId
1836
1853
  };
1837
1854
 
1838
- // lib/util/create-context-and-run-program.ts
1839
- var createContextAndRunProgram = async (process_args) => {
1840
- const args = minimist(process_args);
1855
+ // lib/create-config-manager.ts
1856
+ import Configstore from "configstore";
1857
+ var createConfigHandler = ({
1858
+ profile
1859
+ }) => {
1841
1860
  const global_config = new Configstore("tsci");
1842
- const current_profile = args.profile ?? global_config.get("current_profile") ?? "default";
1861
+ const current_profile = profile ?? global_config.get("current_profile") ?? "default";
1843
1862
  const profile_config = {
1844
1863
  get: (key) => global_config.get(`profiles.${current_profile}.${key}`),
1845
1864
  set: (key, value) => global_config.set(`profiles.${current_profile}.${key}`, value)
1846
1865
  };
1866
+ return { profile_config, global_config, current_profile };
1867
+ };
1868
+
1869
+ // lib/util/create-context-and-run-program.ts
1870
+ import dargs from "dargs";
1871
+ var createContextAndRunProgram = async (process_args) => {
1872
+ const args = minimist(process_args);
1873
+ const { global_config, profile_config, current_profile } = createConfigHandler({
1874
+ profile: args.profile
1875
+ });
1847
1876
  const registry_url = profile_config.get("registry_url") ?? "https://registry-api.tscircuit.com";
1848
1877
  args._ = args._.map((p) => p.toLowerCase().replace(/-/g, "_"));
1849
1878
  for (const key in args) {
@@ -1861,23 +1890,26 @@ var createContextAndRunProgram = async (process_args) => {
1861
1890
  if (global_config.get("log_requests")) {
1862
1891
  console.log(`Using registry_url: ${registry_url}`);
1863
1892
  axios.interceptors.request.use((req) => {
1864
- console.log(kleur15.grey(`[REQ] ${req.method?.toUpperCase()} ${req.url}`));
1893
+ console.log(kleur17.grey(`[REQ] ${req.method?.toUpperCase()} ${req.url}`));
1865
1894
  return req;
1866
1895
  });
1867
1896
  axios.interceptors.response.use((res) => {
1868
- console.log(kleur15.grey(`[RES] ${res.status} ${res.config.method?.toUpperCase()} ${res.config.url}`));
1897
+ console.log(kleur17.grey(`[RES] ${res.status} ${res.config.method?.toUpperCase()} ${res.config.url}`));
1869
1898
  return res;
1870
1899
  });
1871
1900
  }
1872
1901
  axios.interceptors.response.use((res) => res, (err) => {
1873
- console.log(kleur15.red(`[ERR] ${err.response?.status} ${err.config.method?.toUpperCase()} ${err.config.url}\n\n${JSON.stringify(err.response?.data, null, " ")}`.replace(/\\n/g, "\n").replace(/\\"/g, '"')));
1874
- console.log(kleur15.yellow("[Request Body]:"), err.config.data);
1902
+ if (err.config.data?.error?.error_code === "package_not_found" || err.config.data?.error?.error_code === "package_release_not_found") {
1903
+ return Promise.reject(err);
1904
+ }
1905
+ console.log(kleur17.red(`[ERR] ${err.response?.status} ${err.config.method?.toUpperCase()} ${err.config.url}\n\n${JSON.stringify(err.response?.data, null, " ")}`.replace(/\\n/g, "\n").replace(/\\"/g, '"')));
1906
+ console.log(kleur17.yellow("[Request Body]:"), err.config.data);
1875
1907
  return Promise.reject(err);
1876
1908
  });
1877
1909
  const ctx = {
1878
1910
  cmd: args._,
1879
1911
  cwd: args.cwd ?? process.cwd(),
1880
- profile: current_profile,
1912
+ current_profile,
1881
1913
  registry_url,
1882
1914
  axios,
1883
1915
  global_config,
@@ -1889,7 +1921,10 @@ var createContextAndRunProgram = async (process_args) => {
1889
1921
  },
1890
1922
  params: args
1891
1923
  };
1892
- await perfectCli(getProgram(ctx), process.argv, {
1924
+ delete args["cwd"];
1925
+ const { _: positional, ...flagsAndParams } = args;
1926
+ const args_without_globals = positional.concat(dargs(flagsAndParams));
1927
+ await perfectCli(getProgram(ctx), args_without_globals, {
1893
1928
  async customParamHandler({ commandPath, optionName }, { prompts: prompts3 }) {
1894
1929
  const optionNameHandler = PARAM_HANDLERS_BY_PARAM_NAME[_.snakeCase(optionName)];
1895
1930
  if (optionNameHandler) {
@@ -1,3 +1,7 @@
1
+ import kleur from "kleur"
1
2
  import { AppContext } from "../util/app-context"
2
3
 
3
- export const authLogout = async (ctx: AppContext, args: any) => {}
4
+ export const authLogout = async (ctx: AppContext, args: any) => {
5
+ ctx.profile_config.delete("session_token")
6
+ console.log(kleur.green("Logged out!"))
7
+ }
@@ -0,0 +1,5 @@
1
+ import { AppContext } from "../util/app-context"
2
+
3
+ export const configClear = async (ctx: AppContext, args: any) => {
4
+ ctx.global_config.clear()
5
+ }
@@ -31,3 +31,5 @@ export { removeCmd as remove } from "./remove"
31
31
  export { installCmd as install } from "./install"
32
32
  export { uninstallCmd as uninstall } from "./uninstall"
33
33
  export { devServerUpload } from "./dev-server-upload"
34
+ export { configClear } from "./config-clear"
35
+ export { openCmd as open } from "./open"
@@ -0,0 +1,19 @@
1
+ import { existsSync, readFileSync } from "fs"
2
+ import kleur from "kleur"
3
+ import { AppContext } from "lib/util/app-context"
4
+ import * as Path from "path"
5
+ import open from "open"
6
+
7
+ export const openCmd = async (ctx: AppContext, args: any) => {
8
+ const packageJsonPath = Path.join(ctx.cwd, "package.json")
9
+ if (!existsSync(packageJsonPath)) {
10
+ console.log(kleur.red("No package.json found in current directory"))
11
+ process.exit(1)
12
+ }
13
+ const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"))
14
+
15
+ const registryUrl = `${ctx.registry_url}/${packageJson.name.replace("@", "")}`
16
+
17
+ console.log(`Opening ${registryUrl} in your browser...`)
18
+ await open(registryUrl)
19
+ }
@@ -12,6 +12,7 @@ import { inferExportNameFromSource } from "../dev/infer-export-name-from-source"
12
12
  import $ from "dax-sh"
13
13
  import semver from "semver"
14
14
  import { unlink } from "fs/promises"
15
+ import esbuild from "esbuild"
15
16
 
16
17
  export const publish = async (ctx: AppContext, args: any) => {
17
18
  const params = z
@@ -42,24 +43,31 @@ export const publish = async (ctx: AppContext, args: any) => {
42
43
  )
43
44
 
44
45
  // TODO possibly use esbuild here, it's got stuff like packages: "external"
45
- await Bun.build({
46
- root: ctx.cwd,
47
- // TODO determine entrypoint in a more clever way e.g.
48
- // - package.json "main"
49
- entrypoints: ["index.ts"],
46
+ // await Bun.build({
47
+ // root: ctx.cwd,
48
+ // // TODO determine entrypoint in a more clever way e.g.
49
+ // // - package.json "main"
50
+ // entrypoints: ["index.ts"],
50
51
 
51
- // Everything should be external since it's a node module, esbuild has a
52
- // packages: "external" option for this
53
- external: [
54
- ...Object.keys(packageJson.dependencies || {}),
55
- ...Object.keys(packageJson.devDependencies || {}),
56
- ...Object.keys(packageJson.peerDependencies || {}),
57
- ...Object.keys(packageJson.trustedDependencies || {}),
58
- ],
52
+ // // Everything should be external since it's a node module, esbuild has a
53
+ // // packages: "external" option for this
54
+ // external: [
55
+ // ...Object.keys(packageJson.dependencies || {}),
56
+ // ...Object.keys(packageJson.devDependencies || {}),
57
+ // ...Object.keys(packageJson.peerDependencies || {}),
58
+ // ...Object.keys(packageJson.trustedDependencies || {}),
59
+ // ],
59
60
 
60
- outdir: "dist",
61
+ // outdir: "dist",
61
62
 
62
- target: "node",
63
+ // target: "node",
64
+ // })
65
+ await esbuild.build({
66
+ entryPoints: ["index.ts"], // TODO dynamically determine entrypoint
67
+ bundle: true,
68
+ platform: "node",
69
+ packages: "external",
70
+ outdir: "dist",
63
71
  })
64
72
 
65
73
  // Publish to npm??
@@ -0,0 +1,89 @@
1
+ import Configstore from "configstore"
2
+
3
+ interface ProfileConfigProps {
4
+ session_token?: string
5
+ registry_url?: string
6
+ }
7
+
8
+ interface GlobalConfigProps {
9
+ current_profile?: string
10
+ log_requests?: boolean
11
+ }
12
+
13
+ interface TypedConfigstore<T extends Record<string, any>> {
14
+ /**
15
+ * Get the path to the config file. Can be used to show the user
16
+ * where it is, or better, open it for them.
17
+ */
18
+ path: string
19
+
20
+ /**
21
+ * Get all items as an object or replace the current config with an object.
22
+ */
23
+ all: any
24
+
25
+ /**
26
+ * Get the item count
27
+ */
28
+ size: number
29
+
30
+ /**
31
+ * Get an item
32
+ * @param key The string key to get
33
+ * @return The contents of the config from key $key
34
+ */
35
+ get(key: keyof T): any
36
+
37
+ /**
38
+ * Set an item
39
+ * @param key The string key
40
+ * @param val The value to set
41
+ */
42
+ set<K extends keyof T>(key: K, val: T[K]): void
43
+
44
+ /**
45
+ * Determines if a key is present in the config
46
+ * @param key The string key to test for
47
+ * @return True if the key is present
48
+ */
49
+ has(key: keyof T): boolean
50
+
51
+ /**
52
+ * Delete an item.
53
+ * @param key The key to delete
54
+ */
55
+ delete(key: keyof T): void
56
+
57
+ /**
58
+ * Clear the config.
59
+ * Equivalent to <code>Configstore.all = {};</code>
60
+ */
61
+ clear(): void
62
+ }
63
+
64
+ export interface ContextConfigProps {
65
+ profile_config: TypedConfigstore<ProfileConfigProps>
66
+ global_config: TypedConfigstore<GlobalConfigProps>
67
+ current_profile: string
68
+ }
69
+
70
+ export const createConfigHandler = ({
71
+ profile,
72
+ }: {
73
+ profile?: string
74
+ }): ContextConfigProps => {
75
+ const global_config: TypedConfigstore<GlobalConfigProps> = new Configstore(
76
+ "tsci"
77
+ )
78
+ const current_profile =
79
+ profile ?? global_config.get("current_profile") ?? "default"
80
+
81
+ const profile_config: TypedConfigstore<ProfileConfigProps> = {
82
+ get: (key: string) =>
83
+ (global_config as any).get(`profiles.${current_profile}.${key}`),
84
+ set: (key: string, value: any) =>
85
+ (global_config as any).set(`profiles.${current_profile}.${key}`, value),
86
+ } as any
87
+
88
+ return { profile_config, global_config, current_profile }
89
+ }
@@ -241,5 +241,7 @@ export const getProgram = (ctx: AppContext) => {
241
241
  .option("-p, --port", "Port dev server is running on (default: 3020)")
242
242
  .action((args) => CMDFN.devServerUpload(ctx, args))
243
243
 
244
+ cmd.command("open").action((args) => CMDFN.open(ctx, args))
245
+
244
246
  return cmd
245
247
  }
@@ -1,5 +1,6 @@
1
1
  import { AxiosInstance } from "axios"
2
2
  import Configstore from "configstore"
3
+ import { ContextConfigProps } from "lib/create-config-manager"
3
4
 
4
5
  export type AppContext = {
5
6
  args: any
@@ -8,7 +9,5 @@ export type AppContext = {
8
9
  params: Record<string, any>
9
10
  registry_url: string
10
11
  axios: AxiosInstance
11
- profile: string
12
- profile_config: Configstore
13
- global_config: Configstore
14
- }
12
+ current_profile: string
13
+ } & ContextConfigProps
@@ -8,6 +8,8 @@ import { getProgram } from "../get-program"
8
8
  import defaultAxios from "axios"
9
9
  import kleur from "kleur"
10
10
  import { PARAM_HANDLERS_BY_PARAM_NAME } from "lib/param-handlers"
11
+ import { createConfigHandler } from "lib/create-config-manager"
12
+ import dargs from "dargs"
11
13
 
12
14
  export type CliArgs = {
13
15
  cmd: string[]
@@ -18,15 +20,10 @@ export type CliArgs = {
18
20
  export const createContextAndRunProgram = async (process_args: any) => {
19
21
  const args = minimist(process_args)
20
22
 
21
- const global_config = new Configstore("tsci")
22
- const current_profile =
23
- args.profile ?? global_config.get("current_profile") ?? "default"
24
- const profile_config: typeof global_config = {
25
- get: (key: string) =>
26
- global_config.get(`profiles.${current_profile}.${key}`),
27
- set: (key: string, value: any) =>
28
- global_config.set(`profiles.${current_profile}.${key}`, value),
29
- } as any
23
+ const { global_config, profile_config, current_profile } =
24
+ createConfigHandler({
25
+ profile: args.profile,
26
+ })
30
27
 
31
28
  // Load registry commands
32
29
  const registry_url =
@@ -71,6 +68,15 @@ export const createContextAndRunProgram = async (process_args: any) => {
71
68
  axios.interceptors.response.use(
72
69
  (res) => res,
73
70
  (err) => {
71
+ // ---- IGNORE LOGGING *_not_found --------
72
+ if (
73
+ err.config.data?.error?.error_code === "package_not_found" ||
74
+ err.config.data?.error?.error_code === "package_release_not_found"
75
+ ) {
76
+ return Promise.reject(err)
77
+ }
78
+ // end ignores ---
79
+
74
80
  console.log(
75
81
  kleur.red(
76
82
  `[ERR] ${err.response?.status} ${err.config.method?.toUpperCase()} ${
@@ -88,7 +94,7 @@ export const createContextAndRunProgram = async (process_args: any) => {
88
94
  const ctx: AppContext = {
89
95
  cmd: args._,
90
96
  cwd: args.cwd ?? process.cwd(),
91
- profile: current_profile,
97
+ current_profile,
92
98
  registry_url,
93
99
  axios,
94
100
  global_config,
@@ -101,7 +107,12 @@ export const createContextAndRunProgram = async (process_args: any) => {
101
107
  params: args,
102
108
  }
103
109
 
104
- await perfectCli(getProgram(ctx), process.argv, {
110
+ delete args["cwd"]
111
+
112
+ const { _: positional, ...flagsAndParams } = args
113
+ const args_without_globals = positional.concat(dargs(flagsAndParams))
114
+
115
+ await perfectCli(getProgram(ctx), args_without_globals, {
105
116
  async customParamHandler({ commandPath, optionName }, { prompts }) {
106
117
  const optionNameHandler =
107
118
  PARAM_HANDLERS_BY_PARAM_NAME[_.snakeCase(optionName)]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tscircuit/cli",
3
- "version": "0.0.8",
3
+ "version": "0.0.9",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Command line tool for developing, publishing and installing tscircuit circuits",
@@ -32,9 +32,11 @@
32
32
  "chokidar": "^3.6.0",
33
33
  "commander": "^12.0.0",
34
34
  "configstore": "^6.0.0",
35
+ "dargs": "^8.1.0",
35
36
  "dax-sh": "^0.39.2",
36
37
  "delay": "^6.0.0",
37
38
  "edgespec": "^0.0.69",
39
+ "esbuild": "^0.20.2",
38
40
  "glob": "^10.3.10",
39
41
  "hono": "^4.1.0",
40
42
  "ignore": "^5.3.1",
@@ -0,0 +1,9 @@
1
+ import { test, expect } from "bun:test"
2
+ import { $ } from "bun"
3
+
4
+ test("tsci open", async () => {
5
+ const result =
6
+ await $`bun cli.ts open -y --cwd ./tests/assets/example-project`.text()
7
+ expect(result).toContain("http")
8
+ expect(result).toContain("example-project")
9
+ })