@tscircuit/cli 0.0.4 → 0.0.6
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/README.md +31 -22
- package/bun.lockb +0 -0
- package/dev-server-frontend/bun.lockb +0 -0
- package/lib/cmd-fns/add.ts +34 -0
- package/lib/cmd-fns/config-reveal-location.ts +1 -1
- package/lib/cmd-fns/dev/check-if-initialized.ts +22 -0
- package/lib/cmd-fns/dev/dev-server-request-handler.ts +54 -0
- package/lib/cmd-fns/dev/get-dev-server-axios.ts +25 -0
- package/lib/cmd-fns/dev/index.ts +33 -156
- package/lib/cmd-fns/dev/infer-export-name-from-source.ts +17 -0
- package/lib/cmd-fns/dev/soupify-and-upload-example-file.ts +38 -0
- package/lib/cmd-fns/dev/start-dev-server.ts +34 -0
- package/lib/cmd-fns/dev/start-watcher.ts +48 -0
- package/lib/cmd-fns/dev/upload-examples-from-directory.ts +26 -0
- package/lib/cmd-fns/dev-server-upload.ts +26 -0
- package/lib/cmd-fns/index.ts +5 -0
- package/lib/cmd-fns/init/create-or-modify-npmrc.ts +21 -0
- package/lib/cmd-fns/init/get-generated-npmrc.ts +8 -0
- package/lib/cmd-fns/init/get-generated-readme.ts +34 -0
- package/lib/cmd-fns/init/get-generated-tsconfig.ts +34 -0
- package/lib/cmd-fns/{init.ts → init/index.ts} +19 -64
- package/lib/cmd-fns/install.ts +34 -0
- package/lib/cmd-fns/publish/index.ts +296 -0
- package/lib/cmd-fns/remove.ts +31 -0
- package/lib/cmd-fns/uninstall.ts +31 -0
- package/lib/get-program.ts +48 -7
- package/lib/util/create-context-and-run-program.ts +1 -1
- package/lib/util/get-all-package-files.ts +35 -0
- package/package.json +13 -6
- package/tests/assets/example-project/README.md +18 -0
- package/tests/assets/example-project/index.ts +1 -0
- package/tests/assets/example-project/package.json +2 -1
- package/tests/assets/example-project/src/MyCircuit.tsx +1 -1
- package/tests/init.test.ts +1 -1
- package/dist/cli.js +0 -1465
- package/lib/cmd-fns/publish.ts +0 -3
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { existsSync, writeFileSync } from "fs"
|
|
2
|
+
import kleur from "kleur"
|
|
3
|
+
import * as Path from "path"
|
|
4
|
+
import { getGeneratedNpmrc } from "./get-generated-npmrc"
|
|
5
|
+
import { AppContext } from "lib/util/app-context"
|
|
6
|
+
|
|
7
|
+
export const createOrModifyNpmrc = async (
|
|
8
|
+
{ quiet = true }: { quiet?: boolean },
|
|
9
|
+
ctx: AppContext
|
|
10
|
+
) => {
|
|
11
|
+
const npmrcPath = Path.join(ctx.cwd, ".npmrc")
|
|
12
|
+
|
|
13
|
+
if (existsSync(npmrcPath)) {
|
|
14
|
+
// TODO check that @tsci registry is correctly set
|
|
15
|
+
if (!quiet) {
|
|
16
|
+
console.log(kleur.yellow("npmrc already exists, not doing anything"))
|
|
17
|
+
}
|
|
18
|
+
} else {
|
|
19
|
+
writeFileSync(npmrcPath, getGeneratedNpmrc(ctx))
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export const getGeneratedReadme = ({
|
|
2
|
+
name,
|
|
3
|
+
shouldHaveProjectGeneratedNotice = false,
|
|
4
|
+
}: {
|
|
5
|
+
name: string
|
|
6
|
+
shouldHaveProjectGeneratedNotice?: boolean
|
|
7
|
+
}) => {
|
|
8
|
+
return `
|
|
9
|
+
# ${name}
|
|
10
|
+
${
|
|
11
|
+
shouldHaveProjectGeneratedNotice
|
|
12
|
+
? `\n\n> This project was generated using [tsci](https://github.com/tscircuit/tscircuit)\n`
|
|
13
|
+
: ""
|
|
14
|
+
}
|
|
15
|
+
To develop and view the examples, run \`tsci dev\` and open [http://localhost:3020](http://localhost:3020) in your browser.
|
|
16
|
+
|
|
17
|
+
## Developing
|
|
18
|
+
|
|
19
|
+
You should install an editor like [VS Code](https://code.visualstudio.com/) with a typescript extension. Many web developers already have this.
|
|
20
|
+
|
|
21
|
+
Usually, you'll want to develop some named circuits inside of the \`lib\` directory,
|
|
22
|
+
export them in the \`index.ts\` file, then show how to use them in the \`examples\` directory.
|
|
23
|
+
|
|
24
|
+
Any file in \`examples\` will be automatically loaded and appear in the browser preview when you run \`tsci dev\`. It auto-reloads when you make changes, no need to reload the page or re-run the command.
|
|
25
|
+
|
|
26
|
+
> [!TIP] Make sure to replace this README with some details about your project and how to use it.
|
|
27
|
+
|
|
28
|
+
## Publishing
|
|
29
|
+
|
|
30
|
+
After you're satisfied with your project, publish it on the [tscircuit registry](https://registry.tscircuit.com) with \`tsci publish\`
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
`.trim()
|
|
34
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export const getGeneratedTsconfig = () =>
|
|
2
|
+
`
|
|
3
|
+
|
|
4
|
+
{
|
|
5
|
+
"compilerOptions": {
|
|
6
|
+
// Enable latest features
|
|
7
|
+
"lib": ["ESNext"],
|
|
8
|
+
"target": "ESNext",
|
|
9
|
+
"module": "ESNext",
|
|
10
|
+
"moduleDetection": "force",
|
|
11
|
+
"jsx": "react-jsx",
|
|
12
|
+
"allowJs": true,
|
|
13
|
+
"types": ["@tscircuit/react-fiber"],
|
|
14
|
+
"baseUrl": ".",
|
|
15
|
+
|
|
16
|
+
// Bundler mode
|
|
17
|
+
"moduleResolution": "bundler",
|
|
18
|
+
"allowImportingTsExtensions": true,
|
|
19
|
+
"verbatimModuleSyntax": true,
|
|
20
|
+
"noEmit": true,
|
|
21
|
+
|
|
22
|
+
// Best practices
|
|
23
|
+
"strict": true,
|
|
24
|
+
"skipLibCheck": true,
|
|
25
|
+
"noFallthroughCasesInSwitch": true,
|
|
26
|
+
|
|
27
|
+
// Some stricter flags (disabled by default)
|
|
28
|
+
"noUnusedLocals": false,
|
|
29
|
+
"noUnusedParameters": false,
|
|
30
|
+
"noPropertyAccessFromIndexSignature": false
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
`.trim()
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AppContext } from "
|
|
1
|
+
import { AppContext } from "../../util/app-context"
|
|
2
2
|
import { z } from "zod"
|
|
3
3
|
import {
|
|
4
4
|
readFileSync,
|
|
@@ -10,6 +10,10 @@ import {
|
|
|
10
10
|
} from "fs"
|
|
11
11
|
import * as Path from "node:path"
|
|
12
12
|
import $ from "dax-sh"
|
|
13
|
+
import { getGeneratedReadme } from "./get-generated-readme"
|
|
14
|
+
import { getGeneratedTsconfig } from "./get-generated-tsconfig"
|
|
15
|
+
import { getGeneratedNpmrc } from "./get-generated-npmrc"
|
|
16
|
+
import { createOrModifyNpmrc } from "./create-or-modify-npmrc"
|
|
13
17
|
|
|
14
18
|
export const initCmd = async (ctx: AppContext, args: any) => {
|
|
15
19
|
const params = z
|
|
@@ -59,6 +63,9 @@ export const initCmd = async (ctx: AppContext, args: any) => {
|
|
|
59
63
|
await $`${pkm} add -D typescript tsx`
|
|
60
64
|
}
|
|
61
65
|
|
|
66
|
+
// TODO just allow adding "tscircuit" in the future
|
|
67
|
+
await $`${pkm} add -D @tscircuit/react-fiber @tscircuit/builder`
|
|
68
|
+
|
|
62
69
|
console.log("Changing package name...")
|
|
63
70
|
// Change package.json "name" to params.name
|
|
64
71
|
const packageJson = JSON.parse(readFileSync("package.json", "utf-8"))
|
|
@@ -66,11 +73,14 @@ export const initCmd = async (ctx: AppContext, args: any) => {
|
|
|
66
73
|
writeFileSync("package.json", JSON.stringify(packageJson, null, 2))
|
|
67
74
|
|
|
68
75
|
console.log(`Adding ".tscircuit" to .gitignore`)
|
|
69
|
-
appendFileSync(".gitignore", "\n.tscircuit", {
|
|
76
|
+
appendFileSync(".gitignore", "\n.tscircuit\n*.__tmp_entrypoint.tsx\ndist", {
|
|
70
77
|
encoding: "utf-8",
|
|
71
|
-
flag: "
|
|
78
|
+
flag: "a+",
|
|
72
79
|
})
|
|
73
80
|
|
|
81
|
+
console.log("Add .npmrc with tscircuit registry...")
|
|
82
|
+
await createOrModifyNpmrc({ quiet: false }, ctx)
|
|
83
|
+
|
|
74
84
|
console.log("Creating lib and examples directories...")
|
|
75
85
|
mkdirSync("examples", { recursive: true })
|
|
76
86
|
mkdirSync("lib", { recursive: true })
|
|
@@ -104,69 +114,14 @@ export const MyExample = () => (
|
|
|
104
114
|
// Override the README file
|
|
105
115
|
writeFileSync(
|
|
106
116
|
"README.md",
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
To develop and view the examples, run \`tsck dev\` and open [http://localhost:3020](http://localhost:3020) in your browser.
|
|
113
|
-
|
|
114
|
-
## Developing
|
|
115
|
-
|
|
116
|
-
You should install an editor like [VS Code](https://code.visualstudio.com/) with a typescript extension. Many web developers already have this.
|
|
117
|
-
|
|
118
|
-
Usually, you'll want to develop some named circuits inside of the \`lib\` directory,
|
|
119
|
-
export them in the \`index.ts\` file, then show how to use them in the \`examples\` directory.
|
|
120
|
-
|
|
121
|
-
Any file in \`examples\` will be automatically loaded and appear in the browser preview when you run \`tsck dev\`. It auto-reloads when you make changes, no need to reload the page or re-run the command.
|
|
122
|
-
|
|
123
|
-
> [!TIP] Make sure to replace this README with some details about your project and how to use it.
|
|
124
|
-
|
|
125
|
-
## Publishing
|
|
126
|
-
|
|
127
|
-
After you're satisfied with your project, publish it on the [tscircuit registry](https://registry.tscircuit.com) with \`tsck publish\`
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
`.trim()
|
|
117
|
+
getGeneratedReadme({
|
|
118
|
+
name: params.name!,
|
|
119
|
+
shouldHaveProjectGeneratedNotice: true,
|
|
120
|
+
})
|
|
132
121
|
)
|
|
133
122
|
|
|
134
123
|
// Open tsconfig.json and modify it to import the tscircuit types
|
|
135
|
-
writeFileSync(
|
|
136
|
-
"tsconfig.json",
|
|
137
|
-
`
|
|
138
|
-
{
|
|
139
|
-
"compilerOptions": {
|
|
140
|
-
// Enable latest features
|
|
141
|
-
"lib": ["ESNext"],
|
|
142
|
-
"target": "ESNext",
|
|
143
|
-
"module": "ESNext",
|
|
144
|
-
"moduleDetection": "force",
|
|
145
|
-
"jsx": "react-jsx",
|
|
146
|
-
"allowJs": true,
|
|
147
|
-
"types": ["@tscircuit/react-fiber"],
|
|
148
|
-
"baseUrl": ".",
|
|
149
|
-
|
|
150
|
-
// Bundler mode
|
|
151
|
-
"moduleResolution": "bundler",
|
|
152
|
-
"allowImportingTsExtensions": true,
|
|
153
|
-
"verbatimModuleSyntax": true,
|
|
154
|
-
"noEmit": true,
|
|
155
|
-
|
|
156
|
-
// Best practices
|
|
157
|
-
"strict": true,
|
|
158
|
-
"skipLibCheck": true,
|
|
159
|
-
"noFallthroughCasesInSwitch": true,
|
|
160
|
-
|
|
161
|
-
// Some stricter flags (disabled by default)
|
|
162
|
-
"noUnusedLocals": false,
|
|
163
|
-
"noUnusedParameters": false,
|
|
164
|
-
"noPropertyAccessFromIndexSignature": false
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
`.trim()
|
|
169
|
-
)
|
|
124
|
+
writeFileSync("tsconfig.json", getGeneratedTsconfig())
|
|
170
125
|
|
|
171
|
-
console.log("Done! Run `
|
|
126
|
+
console.log("Done! Run `tsci dev` to start developing!")
|
|
172
127
|
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import kleur from "kleur"
|
|
2
|
+
import { AppContext } from "lib/util/app-context"
|
|
3
|
+
import { z } from "zod"
|
|
4
|
+
import { createOrModifyNpmrc } from "./init/create-or-modify-npmrc"
|
|
5
|
+
import $ from "dax-sh"
|
|
6
|
+
|
|
7
|
+
export const installCmd = async (ctx: AppContext, args: any) => {
|
|
8
|
+
const params = z
|
|
9
|
+
.object({
|
|
10
|
+
packages: z.array(z.string()),
|
|
11
|
+
flags: z
|
|
12
|
+
.object({ dev: z.boolean().optional().default(false) })
|
|
13
|
+
.optional()
|
|
14
|
+
.default({}),
|
|
15
|
+
})
|
|
16
|
+
.parse(args)
|
|
17
|
+
|
|
18
|
+
params.packages = params.packages.map((p) => p.replace(/^@/, ""))
|
|
19
|
+
|
|
20
|
+
await createOrModifyNpmrc({ quiet: true }, ctx)
|
|
21
|
+
|
|
22
|
+
$.cd(ctx.cwd)
|
|
23
|
+
|
|
24
|
+
const flagsString = params.flags.dev ? "--dev" : ""
|
|
25
|
+
|
|
26
|
+
const cmd = `npm install ${flagsString} ${params.packages
|
|
27
|
+
.map((p) => `@tsci/${p.replace(/\//, ".")}`)
|
|
28
|
+
.join(" ")}`
|
|
29
|
+
console.log(kleur.gray(`> ${cmd}`))
|
|
30
|
+
|
|
31
|
+
await $`npm install ${flagsString} ${params.packages
|
|
32
|
+
.map((p) => `@tsci/${p.replace(/\//, ".")}`)
|
|
33
|
+
.join(" ")}`
|
|
34
|
+
}
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
import kleur from "kleur"
|
|
2
|
+
import { z } from "zod"
|
|
3
|
+
import { AppContext } from "../../util/app-context"
|
|
4
|
+
import * as Path from "path"
|
|
5
|
+
import * as fs from "fs/promises"
|
|
6
|
+
import { readFileSync } from "fs"
|
|
7
|
+
import { getAllPackageFiles } from "lib/util/get-all-package-files"
|
|
8
|
+
import prompts from "prompts"
|
|
9
|
+
import { getGeneratedReadme } from "../init/get-generated-readme"
|
|
10
|
+
import { soupify } from "../../soupify"
|
|
11
|
+
import { inferExportNameFromSource } from "../dev/infer-export-name-from-source"
|
|
12
|
+
import $ from "dax-sh"
|
|
13
|
+
import semver from "semver"
|
|
14
|
+
import { unlink } from "fs/promises"
|
|
15
|
+
|
|
16
|
+
export const publish = async (ctx: AppContext, args: any) => {
|
|
17
|
+
const params = z
|
|
18
|
+
.object({
|
|
19
|
+
increment: z.boolean().optional(),
|
|
20
|
+
patch: z.boolean().optional(),
|
|
21
|
+
lock: z.boolean().optional(),
|
|
22
|
+
})
|
|
23
|
+
.parse(args)
|
|
24
|
+
if (typeof Bun === "undefined") {
|
|
25
|
+
console.log(
|
|
26
|
+
kleur.red(
|
|
27
|
+
"\n\n----------------------------------\nBun is currently required for publishing packages to the tscircuit registry. Try installing bun:\nhhttps://bun.sh/docs/installation\n\n---------------------"
|
|
28
|
+
)
|
|
29
|
+
)
|
|
30
|
+
process.exit(1)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const shouldIncrement = params.increment || params.patch
|
|
34
|
+
|
|
35
|
+
if (!(await fs.exists(Path.join(ctx.cwd, "package.json")))) {
|
|
36
|
+
console.log(kleur.red("No package.json found in current directory"))
|
|
37
|
+
process.exit(1)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const packageJson = JSON.parse(
|
|
41
|
+
await readFileSync(Path.join(ctx.cwd, "package.json"), "utf-8")
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
// 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"],
|
|
50
|
+
|
|
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
|
+
],
|
|
59
|
+
|
|
60
|
+
outdir: "dist",
|
|
61
|
+
|
|
62
|
+
target: "node",
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
// Publish to npm??
|
|
66
|
+
|
|
67
|
+
// Upload to tscircuit registry
|
|
68
|
+
// 1. Get the package name and version from package.json
|
|
69
|
+
let { name, version } = packageJson
|
|
70
|
+
name = name.replace(/^@/, "") // remove leading @ if it exists
|
|
71
|
+
// 2.1 Check if package already exists, if it doesn't, create it
|
|
72
|
+
const existingPackage = await ctx.axios
|
|
73
|
+
.post("/packages/get", { name })
|
|
74
|
+
.then((r) => r.data.package)
|
|
75
|
+
.catch((e) => {
|
|
76
|
+
if (e.response?.data?.error?.error_code === "package_not_found")
|
|
77
|
+
return null
|
|
78
|
+
throw e
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
if (!existingPackage) {
|
|
82
|
+
if (!packageJson.name.includes("/")) {
|
|
83
|
+
console.log(
|
|
84
|
+
kleur.yellow(
|
|
85
|
+
`Package name "${packageJson.name}" is not scoped. Scoped package names are recommended on the tscircuit registry.`
|
|
86
|
+
)
|
|
87
|
+
)
|
|
88
|
+
const myAccount = await ctx.axios
|
|
89
|
+
.get("/accounts/get")
|
|
90
|
+
.then((r) => r.data.account)
|
|
91
|
+
const newScopedName = `${myAccount.github_username}/${packageJson.name}`
|
|
92
|
+
|
|
93
|
+
const { confirmNameChange } = await prompts({
|
|
94
|
+
type: "confirm",
|
|
95
|
+
name: "confirmNameChange",
|
|
96
|
+
initial: true,
|
|
97
|
+
message: `Would you like to change the package name to the scoped name "@${newScopedName}"?`,
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
if (confirm === undefined) {
|
|
101
|
+
console.log(kleur.red("Aborted."))
|
|
102
|
+
process.exit(1)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (confirmNameChange) {
|
|
106
|
+
packageJson.name = `@${newScopedName}`
|
|
107
|
+
await fs.writeFile(
|
|
108
|
+
Path.join(ctx.cwd, "package.json"),
|
|
109
|
+
JSON.stringify(packageJson, null, 2)
|
|
110
|
+
)
|
|
111
|
+
name = newScopedName
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
console.log(
|
|
116
|
+
kleur.green(
|
|
117
|
+
`Creating package "${packageJson.name}" on tscircuit registry...`
|
|
118
|
+
)
|
|
119
|
+
)
|
|
120
|
+
let description = packageJson.description
|
|
121
|
+
if (!description) {
|
|
122
|
+
description = (
|
|
123
|
+
await prompts({
|
|
124
|
+
type: "text",
|
|
125
|
+
name: "description",
|
|
126
|
+
message: "Enter a description for the package",
|
|
127
|
+
})
|
|
128
|
+
).description
|
|
129
|
+
}
|
|
130
|
+
await ctx.axios
|
|
131
|
+
.post("/packages/create", { name, description })
|
|
132
|
+
.then((r) => r.data.package)
|
|
133
|
+
}
|
|
134
|
+
// 2.2 Check if package release already exists
|
|
135
|
+
const existingRelease = await ctx.axios
|
|
136
|
+
.post("/package_releases/get", {
|
|
137
|
+
package_name_with_version: `${name}@${version}`,
|
|
138
|
+
})
|
|
139
|
+
.then((r) => r.data.package_release)
|
|
140
|
+
.catch((e) => {
|
|
141
|
+
if (e.response?.data?.error?.error_code === "package_release_not_found")
|
|
142
|
+
return null
|
|
143
|
+
throw e
|
|
144
|
+
})
|
|
145
|
+
// 3. If it does, ask to increment the version or update the existing release, if increment is specified, increment the version automatically
|
|
146
|
+
if (existingRelease) {
|
|
147
|
+
console.log(
|
|
148
|
+
kleur.gray(`Package release already exists: ${name}@${version}`)
|
|
149
|
+
)
|
|
150
|
+
if (shouldIncrement) {
|
|
151
|
+
console.log(
|
|
152
|
+
kleur.green(
|
|
153
|
+
`Incrementing version from ${version} to ${semver.inc(
|
|
154
|
+
version,
|
|
155
|
+
"patch"
|
|
156
|
+
)}...`
|
|
157
|
+
)
|
|
158
|
+
)
|
|
159
|
+
version = semver.inc(version, "patch")
|
|
160
|
+
packageJson.version = version
|
|
161
|
+
await fs.writeFile(
|
|
162
|
+
Path.join(ctx.cwd, "package.json"),
|
|
163
|
+
JSON.stringify(packageJson, null, 2)
|
|
164
|
+
)
|
|
165
|
+
} else {
|
|
166
|
+
console.log(
|
|
167
|
+
kleur.blue(
|
|
168
|
+
`Want to increment the version and publish a new release? Use "--increment"!`
|
|
169
|
+
)
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
throw new Error("Package release already exists")
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
// 4. Create new package_release
|
|
176
|
+
const newRelease = await ctx.axios
|
|
177
|
+
.post("/package_releases/create", {
|
|
178
|
+
package_name_with_version: `${name}@${version}`,
|
|
179
|
+
is_latest: false, // only make it latest when locking
|
|
180
|
+
})
|
|
181
|
+
.then((r) => r.data.package_release)
|
|
182
|
+
// 5. Upload package_files
|
|
183
|
+
const filePaths = await getAllPackageFiles(ctx)
|
|
184
|
+
if (!filePaths.includes("README.md")) {
|
|
185
|
+
console.log(
|
|
186
|
+
kleur.yellow(
|
|
187
|
+
"No README.md found in package files. A README.md is recommended on the tscircuit registry."
|
|
188
|
+
)
|
|
189
|
+
)
|
|
190
|
+
const { confirmReadme } = await prompts({
|
|
191
|
+
type: "confirm",
|
|
192
|
+
name: "confirmReadme",
|
|
193
|
+
initial: true,
|
|
194
|
+
message: "Would you like to add a README.md?",
|
|
195
|
+
})
|
|
196
|
+
|
|
197
|
+
if (confirmReadme === undefined) {
|
|
198
|
+
console.log(kleur.red("Aborted."))
|
|
199
|
+
process.exit(1)
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
if (confirmReadme) {
|
|
203
|
+
await fs.writeFile(
|
|
204
|
+
Path.join(ctx.cwd, "README.md"),
|
|
205
|
+
getGeneratedReadme({ name })
|
|
206
|
+
)
|
|
207
|
+
filePaths.push("README.md")
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
for (const filePath of filePaths) {
|
|
212
|
+
const fileContent = await fs.readFile(Path.join(ctx.cwd, filePath))
|
|
213
|
+
|
|
214
|
+
await ctx.axios
|
|
215
|
+
.post("/package_files/create", {
|
|
216
|
+
file_path: filePath,
|
|
217
|
+
content_text: fileContent.toString(),
|
|
218
|
+
package_name_with_version: `${name}@${version}`,
|
|
219
|
+
})
|
|
220
|
+
.then((r) => r.data.package_file)
|
|
221
|
+
}
|
|
222
|
+
// 6. Upload package_examples
|
|
223
|
+
const exampleFilePaths = filePaths.filter((fp) => fp.startsWith("examples/"))
|
|
224
|
+
for (const filePath of exampleFilePaths) {
|
|
225
|
+
const fileContent = (
|
|
226
|
+
await fs.readFile(Path.join(ctx.cwd, filePath))
|
|
227
|
+
).toString()
|
|
228
|
+
|
|
229
|
+
const exportName = inferExportNameFromSource(fileContent)
|
|
230
|
+
|
|
231
|
+
const tscircuit_soup = await soupify({
|
|
232
|
+
filePath,
|
|
233
|
+
exportName,
|
|
234
|
+
}).catch((e) => e)
|
|
235
|
+
|
|
236
|
+
if (tscircuit_soup instanceof Error) {
|
|
237
|
+
console.log(
|
|
238
|
+
kleur.red(`Error soupifying ${filePath}: ${tscircuit_soup}, skipping`)
|
|
239
|
+
)
|
|
240
|
+
continue
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
await ctx.axios
|
|
244
|
+
.post("/package_examples/create", {
|
|
245
|
+
file_path: filePath,
|
|
246
|
+
package_name_with_version: `${name}@${version}`,
|
|
247
|
+
export_name: exportName,
|
|
248
|
+
source_content: fileContent,
|
|
249
|
+
tscircuit_soup,
|
|
250
|
+
})
|
|
251
|
+
.then((r) => r.data.package_example)
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// 7. Create tarball and upload
|
|
255
|
+
const tmpTarballPath = Path.join(
|
|
256
|
+
ctx.cwd,
|
|
257
|
+
".tscircuit/tmp",
|
|
258
|
+
`${name.replace(/\//g, "-")}-${version}.tgz`
|
|
259
|
+
)
|
|
260
|
+
await fs.mkdir(Path.dirname(tmpTarballPath), { recursive: true })
|
|
261
|
+
const npm_pack_outputs = await $`cd ${
|
|
262
|
+
ctx.cwd
|
|
263
|
+
} && npm pack --json --pack-destination ${Path.dirname(
|
|
264
|
+
tmpTarballPath
|
|
265
|
+
)}`.json()
|
|
266
|
+
|
|
267
|
+
if (!(await fs.exists(tmpTarballPath))) {
|
|
268
|
+
console.log(kleur.red(`Couldn't find tarball at ${tmpTarballPath}`))
|
|
269
|
+
process.exit(1)
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// Upload tarball
|
|
273
|
+
await ctx.axios.post("/package_files/create", {
|
|
274
|
+
file_path: `.tscircuit-internal/tarball.tgz`,
|
|
275
|
+
content_base64: (await fs.readFile(tmpTarballPath)).toString("base64"),
|
|
276
|
+
package_name_with_version: `${name}@${version}`,
|
|
277
|
+
is_release_tarball: true,
|
|
278
|
+
npm_pack_output: npm_pack_outputs?.[0],
|
|
279
|
+
})
|
|
280
|
+
|
|
281
|
+
// Clean up .tscircuit/tmp
|
|
282
|
+
await unlink(tmpTarballPath)
|
|
283
|
+
|
|
284
|
+
// 8. Lock/set release to latest version
|
|
285
|
+
await ctx.axios.post("/package_releases/update", {
|
|
286
|
+
package_name_with_version: `${name}@${version}`,
|
|
287
|
+
is_locked: params.lock ? true : false,
|
|
288
|
+
is_latest: true,
|
|
289
|
+
})
|
|
290
|
+
|
|
291
|
+
console.log(
|
|
292
|
+
kleur.green(
|
|
293
|
+
`Published ${name}@${version}!\nhttps://registry.tscircuit.com/${name}`
|
|
294
|
+
)
|
|
295
|
+
)
|
|
296
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import kleur from "kleur"
|
|
2
|
+
import { AppContext } from "lib/util/app-context"
|
|
3
|
+
import { z } from "zod"
|
|
4
|
+
import { createOrModifyNpmrc } from "./init/create-or-modify-npmrc"
|
|
5
|
+
import $ from "dax-sh"
|
|
6
|
+
|
|
7
|
+
export const removeCmd = async (ctx: AppContext, args: any) => {
|
|
8
|
+
const params = z
|
|
9
|
+
.object({
|
|
10
|
+
packages: z.array(z.string()),
|
|
11
|
+
flags: z.object({}).optional().default({}),
|
|
12
|
+
})
|
|
13
|
+
.parse(args)
|
|
14
|
+
|
|
15
|
+
params.packages = params.packages.map((p) => p.replace(/^@/, ""))
|
|
16
|
+
|
|
17
|
+
await createOrModifyNpmrc({ quiet: true }, ctx)
|
|
18
|
+
|
|
19
|
+
$.cd(ctx.cwd)
|
|
20
|
+
|
|
21
|
+
const flagsString = ""
|
|
22
|
+
|
|
23
|
+
const cmd = `npm remove ${flagsString} ${params.packages
|
|
24
|
+
.map((p) => `@tsci/${p.replace(/\//, ".")}`)
|
|
25
|
+
.join(" ")}`
|
|
26
|
+
console.log(kleur.gray(`> ${cmd}`))
|
|
27
|
+
|
|
28
|
+
await $`npm remove ${flagsString} ${params.packages
|
|
29
|
+
.map((p) => `@tsci/${p.replace(/\//, ".")}`)
|
|
30
|
+
.join(" ")}`
|
|
31
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import kleur from "kleur"
|
|
2
|
+
import { AppContext } from "lib/util/app-context"
|
|
3
|
+
import { z } from "zod"
|
|
4
|
+
import { createOrModifyNpmrc } from "./init/create-or-modify-npmrc"
|
|
5
|
+
import $ from "dax-sh"
|
|
6
|
+
|
|
7
|
+
export const uninstallCmd = async (ctx: AppContext, args: any) => {
|
|
8
|
+
const params = z
|
|
9
|
+
.object({
|
|
10
|
+
packages: z.array(z.string()),
|
|
11
|
+
flags: z.object({}).optional().default({}),
|
|
12
|
+
})
|
|
13
|
+
.parse(args)
|
|
14
|
+
|
|
15
|
+
params.packages = params.packages.map((p) => p.replace(/^@/, ""))
|
|
16
|
+
|
|
17
|
+
await createOrModifyNpmrc({ quiet: true }, ctx)
|
|
18
|
+
|
|
19
|
+
$.cd(ctx.cwd)
|
|
20
|
+
|
|
21
|
+
const flagsString = ""
|
|
22
|
+
|
|
23
|
+
const cmd = `npm uninstall ${flagsString} ${params.packages
|
|
24
|
+
.map((p) => `@tsci/${p.replace(/\//, ".")}`)
|
|
25
|
+
.join(" ")}`
|
|
26
|
+
console.log(kleur.gray(`> ${cmd}`))
|
|
27
|
+
|
|
28
|
+
await $`npm uninstall ${flagsString} ${params.packages
|
|
29
|
+
.map((p) => `@tsci/${p.replace(/\//, ".")}`)
|
|
30
|
+
.join(" ")}`
|
|
31
|
+
}
|