@tscircuit/cli 0.0.6 → 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 +0 -0
- package/dist/cli.js +1944 -0
- package/lib/cmd-fns/auth-logout.ts +5 -1
- package/lib/cmd-fns/config-clear.ts +5 -0
- package/lib/cmd-fns/dev/index.ts +13 -6
- package/lib/cmd-fns/dev-server-upload.ts +2 -2
- package/lib/cmd-fns/index.ts +2 -0
- package/lib/cmd-fns/init/index.ts +11 -0
- package/lib/cmd-fns/open.ts +19 -0
- package/lib/cmd-fns/publish/index.ts +23 -15
- package/lib/create-config-manager.ts +89 -0
- package/lib/get-program.ts +2 -0
- package/lib/util/app-context.ts +3 -4
- package/lib/util/create-context-and-run-program.ts +22 -11
- package/package.json +3 -1
- 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/dev/index.ts
CHANGED
|
@@ -11,6 +11,7 @@ import * as Path from "path"
|
|
|
11
11
|
import { startWatcher } from "./start-watcher"
|
|
12
12
|
import { createOrModifyNpmrc } from "../init/create-or-modify-npmrc"
|
|
13
13
|
import { checkIfInitialized } from "./check-if-initialized"
|
|
14
|
+
import { initCmd } from "../init"
|
|
14
15
|
|
|
15
16
|
export const devCmd = async (ctx: AppContext, args: any) => {
|
|
16
17
|
const params = z
|
|
@@ -27,12 +28,18 @@ export const devCmd = async (ctx: AppContext, args: any) => {
|
|
|
27
28
|
const isInitialized = await checkIfInitialized(ctx)
|
|
28
29
|
|
|
29
30
|
if (!isInitialized) {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
const { confirmInitialize } = await prompts({
|
|
32
|
+
type: "confirm",
|
|
33
|
+
name: "confirmInitialize",
|
|
34
|
+
message: "Would you like to initialize this project now?",
|
|
35
|
+
initial: true,
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
if (confirmInitialize) {
|
|
39
|
+
return initCmd(ctx, {})
|
|
40
|
+
} else {
|
|
41
|
+
process.exit(1)
|
|
42
|
+
}
|
|
36
43
|
}
|
|
37
44
|
|
|
38
45
|
await createOrModifyNpmrc({ quiet: false }, ctx)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AppContext } from "../util/app-context"
|
|
2
2
|
import { z } from "zod"
|
|
3
|
-
import { getDevServerAxios } from "./get-dev-server-axios"
|
|
4
|
-
import { uploadExamplesFromDirectory } from "./upload-examples-from-directory"
|
|
3
|
+
import { getDevServerAxios } from "./dev/get-dev-server-axios"
|
|
4
|
+
import { uploadExamplesFromDirectory } from "./dev/upload-examples-from-directory"
|
|
5
5
|
import { startWatcher } from "./dev/start-watcher"
|
|
6
6
|
|
|
7
7
|
export const devServerUpload = async (ctx: AppContext, args: any) => {
|
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"
|
|
@@ -30,6 +30,17 @@ export const initCmd = async (ctx: AppContext, args: any) => {
|
|
|
30
30
|
params.dir = `.`
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
if (!params.name) {
|
|
34
|
+
try {
|
|
35
|
+
const myAccount = await ctx.axios
|
|
36
|
+
.get("/accounts/get")
|
|
37
|
+
.then((r) => r.data.account)
|
|
38
|
+
params.name = `@${myAccount.github_username}/${Path.basename(params.dir)}`
|
|
39
|
+
} catch (e) {
|
|
40
|
+
params.name = Path.basename(params.dir ?? ctx.cwd)
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
33
44
|
let runtime = params.runtime
|
|
34
45
|
if (!runtime) {
|
|
35
46
|
const bunExists = $.commandExistsSync("bun")
|
|
@@ -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
|
@@ -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
|
}
|
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,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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
+
})
|