@tscircuit/cli 0.0.8 → 0.0.14

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.
@@ -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,6 @@
1
+ import { AppContext } from "lib/util/app-context"
2
+ import packageJson from "./../../package.json"
3
+
4
+ export const versionCmd = async (ctx: AppContext, args: any) => {
5
+ console.log(`tsci v${packageJson.version}`)
6
+ }
@@ -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
+ }
@@ -166,9 +166,7 @@ export const getProgram = (ctx: AppContext) => {
166
166
  .option("--lock", "Lock the release after publishing to prevent changes")
167
167
  .action((args) => CMDFN.publish(ctx, args))
168
168
 
169
- cmd
170
- .command("version")
171
- .action(() => console.log(`tsci v${packageJson.version}`))
169
+ cmd.command("version").action(() => CMDFN.version(ctx, args))
172
170
 
173
171
  cmd.command("login").action((args) => CMDFN.authLogin(ctx, args))
174
172
  cmd.command("logout").action((args) => CMDFN.authLogout(ctx, args))
@@ -241,5 +239,7 @@ export const getProgram = (ctx: AppContext) => {
241
239
  .option("-p, --port", "Port dev server is running on (default: 3020)")
242
240
  .action((args) => CMDFN.devServerUpload(ctx, args))
243
241
 
242
+ cmd.command("open").action((args) => CMDFN.open(ctx, args))
243
+
244
244
  return cmd
245
245
  }
@@ -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,9 @@ 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"
13
+ import { versionCmd } from "lib/cmd-fns/version"
11
14
 
12
15
  export type CliArgs = {
13
16
  cmd: string[]
@@ -18,15 +21,10 @@ export type CliArgs = {
18
21
  export const createContextAndRunProgram = async (process_args: any) => {
19
22
  const args = minimist(process_args)
20
23
 
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
24
+ const { global_config, profile_config, current_profile } =
25
+ createConfigHandler({
26
+ profile: args.profile,
27
+ })
30
28
 
31
29
  // Load registry commands
32
30
  const registry_url =
@@ -71,6 +69,15 @@ export const createContextAndRunProgram = async (process_args: any) => {
71
69
  axios.interceptors.response.use(
72
70
  (res) => res,
73
71
  (err) => {
72
+ // ---- IGNORE LOGGING *_not_found --------
73
+ if (
74
+ err.config.data?.error?.error_code === "package_not_found" ||
75
+ err.config.data?.error?.error_code === "package_release_not_found"
76
+ ) {
77
+ return Promise.reject(err)
78
+ }
79
+ // end ignores ---
80
+
74
81
  console.log(
75
82
  kleur.red(
76
83
  `[ERR] ${err.response?.status} ${err.config.method?.toUpperCase()} ${
@@ -88,7 +95,7 @@ export const createContextAndRunProgram = async (process_args: any) => {
88
95
  const ctx: AppContext = {
89
96
  cmd: args._,
90
97
  cwd: args.cwd ?? process.cwd(),
91
- profile: current_profile,
98
+ current_profile,
92
99
  registry_url,
93
100
  axios,
94
101
  global_config,
@@ -101,7 +108,17 @@ export const createContextAndRunProgram = async (process_args: any) => {
101
108
  params: args,
102
109
  }
103
110
 
104
- await perfectCli(getProgram(ctx), process.argv, {
111
+ delete args["cwd"]
112
+
113
+ const { _: positional, ...flagsAndParams } = args
114
+ const args_without_globals = positional.concat(dargs(flagsAndParams))
115
+
116
+ if (args["version"] && args._.length === 2) {
117
+ await versionCmd(ctx, {})
118
+ process.exit(0)
119
+ }
120
+
121
+ await perfectCli(getProgram(ctx), args_without_globals, {
105
122
  async customParamHandler({ commandPath, optionName }, { prompts }) {
106
123
  const optionNameHandler =
107
124
  PARAM_HANDLERS_BY_PARAM_NAME[_.snakeCase(optionName)]
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@tscircuit/cli",
3
- "version": "0.0.8",
3
+ "version": "0.0.14",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Command line tool for developing, publishing and installing tscircuit circuits",
7
7
  "main": "./dist/cli.js",
8
8
  "scripts": {
9
- "bootstrap": "bun i && cd dev-server-api && bun i && cd ../dev-server-frontend && bun i",
9
+ "bootstrap": "bun i --frozen-lockfile && cd dev-server-api && bun i --frozen-lockfile && cd ../dev-server-frontend && bun i --frozen-lockfile",
10
10
  "start": "bun cli.ts",
11
11
  "start:dev-server:dev": "TSCI_DEV_SERVER_DB=$(pwd)/.tscircuit/dev-server.db concurrently 'cd dev-server-api && bun start' 'cd dev-server-frontend && bun start'",
12
12
  "start:dev-server": "bun build:dev-server && bun cli.ts dev -y --cwd ./tests/assets/example-project",
@@ -19,7 +19,13 @@
19
19
  "tscircuit": "./dist/cli.js",
20
20
  "tsci": "./dist/cli.js"
21
21
  },
22
- "keywords": [],
22
+ "keywords": [
23
+ "circuit",
24
+ "react",
25
+ "electronics",
26
+ "pcb",
27
+ "schematic"
28
+ ],
23
29
  "author": "",
24
30
  "license": "ISC",
25
31
  "dependencies": {
@@ -32,9 +38,11 @@
32
38
  "chokidar": "^3.6.0",
33
39
  "commander": "^12.0.0",
34
40
  "configstore": "^6.0.0",
41
+ "dargs": "^8.1.0",
35
42
  "dax-sh": "^0.39.2",
36
43
  "delay": "^6.0.0",
37
44
  "edgespec": "^0.0.69",
45
+ "esbuild": "^0.20.2",
38
46
  "glob": "^10.3.10",
39
47
  "hono": "^4.1.0",
40
48
  "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
+ })