@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.
- package/.github/workflows/release.yml +35 -0
- package/bun.lockb +0 -0
- package/dist/cli.js +214 -168
- package/lib/cmd-fns/auth-logout.ts +5 -1
- package/lib/cmd-fns/config-clear.ts +5 -0
- package/lib/cmd-fns/index.ts +2 -0
- package/lib/cmd-fns/open.ts +19 -0
- package/lib/cmd-fns/publish/index.ts +23 -15
- package/lib/cmd-fns/version.ts +6 -0
- package/lib/create-config-manager.ts +89 -0
- package/lib/get-program.ts +3 -3
- package/lib/util/app-context.ts +3 -4
- package/lib/util/create-context-and-run-program.ts +28 -11
- package/package.json +11 -3
- package/tests/open.test.ts +9 -0
|
@@ -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
|
+
}
|
package/lib/cmd-fns/index.ts
CHANGED
|
@@ -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
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
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
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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
|
-
|
|
61
|
+
// outdir: "dist",
|
|
61
62
|
|
|
62
|
-
|
|
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
|
+
}
|
package/lib/get-program.ts
CHANGED
|
@@ -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
|
}
|
package/lib/util/app-context.ts
CHANGED
|
@@ -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
|
-
|
|
12
|
-
|
|
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
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
+
})
|