@tscircuit/cli 0.0.58 → 0.0.60
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/dev-server-api/routes/api/export_files/create_or_update.ts +0 -0
- package/dev-server-api/routes/api/export_files/download.ts +0 -0
- package/dev-server-api/routes/api/export_requests/create.ts +67 -0
- package/dev-server-api/routes/api/export_requests/get.ts +0 -0
- package/dev-server-api/src/db/create-schema.ts +26 -0
- package/dev-server-api/src/db/get-db.ts +19 -0
- package/dev-server-frontend/bun.lockb +0 -0
- package/dev-server-frontend/package-lock.json +58 -321
- package/dev-server-frontend/package.json +5 -3
- package/dev-server-frontend/src/ExampleContentView.tsx +16 -11
- package/dev-server-frontend/src/HeaderMenu.tsx +203 -199
- package/dev-server-frontend/src/components/command-k.tsx +1 -1
- package/dev-server-frontend/src/components/dialogs/gerber-export-dialog.tsx +131 -0
- package/dev-server-frontend/src/components/select-example-search.tsx +4 -23
- package/dev-server-frontend/src/hooks/use-active-dev-package-example-lite.ts +39 -0
- package/dev-server-frontend/src/hooks/use-dev-package-examples.tsx +18 -0
- package/dist/cli.js +109 -44
- package/lib/cmd-fns/dev/index.ts +2 -2
- package/lib/cmd-fns/dev/{start-watcher.ts → start-fs-watcher.ts} +1 -1
- package/lib/cmd-fns/dev-server-upload.ts +36 -5
- package/lib/cmd-fns/export-gerbers.ts +5 -43
- package/lib/export-gerbers.ts +84 -0
- package/package.json +2 -3
- package/tests/assets/example-project/src/MyCircuit.tsx +1 -1
package/lib/cmd-fns/dev/index.ts
CHANGED
|
@@ -8,7 +8,7 @@ import { getDevServerAxios } from "./get-dev-server-axios"
|
|
|
8
8
|
import { uploadExamplesFromDirectory } from "./upload-examples-from-directory"
|
|
9
9
|
import { unlink } from "fs/promises"
|
|
10
10
|
import * as Path from "path"
|
|
11
|
-
import {
|
|
11
|
+
import { startFsWatcher } from "./start-fs-watcher"
|
|
12
12
|
import { createOrModifyNpmrc } from "../init/create-or-modify-npmrc"
|
|
13
13
|
import { checkIfInitialized } from "./check-if-initialized"
|
|
14
14
|
import { initCmd } from "../init"
|
|
@@ -74,7 +74,7 @@ export const devCmd = async (ctx: AppContext, args: any) => {
|
|
|
74
74
|
await uploadExamplesFromDirectory({ devServerAxios, cwd }, ctx)
|
|
75
75
|
|
|
76
76
|
// Start watcher
|
|
77
|
-
const watcher = await
|
|
77
|
+
const watcher = await startFsWatcher({ cwd, devServerAxios }, ctx)
|
|
78
78
|
|
|
79
79
|
while (true) {
|
|
80
80
|
const { action } = await prompts({
|
|
@@ -2,25 +2,56 @@ import { AppContext } from "../util/app-context"
|
|
|
2
2
|
import { z } from "zod"
|
|
3
3
|
import { getDevServerAxios } from "./dev/get-dev-server-axios"
|
|
4
4
|
import { uploadExamplesFromDirectory } from "./dev/upload-examples-from-directory"
|
|
5
|
-
import {
|
|
5
|
+
import { startFsWatcher } from "./dev/start-fs-watcher"
|
|
6
|
+
import kleur from "kleur"
|
|
7
|
+
import { AxiosInstance } from "axios"
|
|
6
8
|
|
|
7
9
|
export const devServerUpload = async (ctx: AppContext, args: any) => {
|
|
8
10
|
const params = z
|
|
9
11
|
.object({
|
|
10
12
|
dir: z.string().optional().default(ctx.cwd),
|
|
11
|
-
port: z.coerce.number().optional().default(
|
|
13
|
+
port: z.coerce.number().optional().nullable().default(null),
|
|
12
14
|
watch: z.boolean().optional().default(false),
|
|
13
15
|
})
|
|
14
16
|
.parse(args)
|
|
15
17
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
+
let serverUrl = `http://localhost:${params.port ?? 3020}`
|
|
19
|
+
let devServerAxios = getDevServerAxios({ serverUrl })
|
|
20
|
+
|
|
21
|
+
const checkHealth = () =>
|
|
22
|
+
devServerAxios
|
|
23
|
+
.get("/api/health")
|
|
24
|
+
.then(() => true)
|
|
25
|
+
.catch((e) => false)
|
|
26
|
+
|
|
27
|
+
let is_dev_server_healthy = await checkHealth()
|
|
28
|
+
|
|
29
|
+
if (!is_dev_server_healthy && !params.port) {
|
|
30
|
+
// attempt to use development-mode port, e.g. if someone ran
|
|
31
|
+
// npm run start:dev-server:dev
|
|
32
|
+
const devModeServerUrl = "http://localhost:3021"
|
|
33
|
+
devServerAxios = getDevServerAxios({ serverUrl: devModeServerUrl })
|
|
34
|
+
is_dev_server_healthy = await checkHealth()
|
|
35
|
+
if (is_dev_server_healthy) serverUrl = devModeServerUrl
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (!is_dev_server_healthy) {
|
|
39
|
+
console.log(
|
|
40
|
+
kleur.red(
|
|
41
|
+
`Dev server doesn't seem to be running at ${serverUrl}. (Could not ping health)`
|
|
42
|
+
)
|
|
43
|
+
)
|
|
44
|
+
process.exit(1)
|
|
45
|
+
}
|
|
18
46
|
|
|
19
47
|
console.log(`Loading examples...`)
|
|
20
48
|
await uploadExamplesFromDirectory({ devServerAxios, cwd: params.dir }, ctx)
|
|
21
49
|
|
|
22
50
|
if (params.watch) {
|
|
23
51
|
// Start watcher
|
|
24
|
-
const watcher = await
|
|
52
|
+
const watcher = await startFsWatcher(
|
|
53
|
+
{ cwd: params.dir, devServerAxios },
|
|
54
|
+
ctx
|
|
55
|
+
)
|
|
25
56
|
}
|
|
26
57
|
}
|
|
@@ -1,16 +1,6 @@
|
|
|
1
1
|
import { AppContext } from "../util/app-context"
|
|
2
2
|
import { z } from "zod"
|
|
3
|
-
import
|
|
4
|
-
import { unlink } from "node:fs/promises"
|
|
5
|
-
import { soupify } from "lib/soupify"
|
|
6
|
-
import * as fs from "fs"
|
|
7
|
-
import {
|
|
8
|
-
stringifyGerberCommandLayers,
|
|
9
|
-
convertSoupToGerberCommands,
|
|
10
|
-
} from "@tscircuit/builder"
|
|
11
|
-
import { zip } from "zip-a-folder"
|
|
12
|
-
import kleur from "kleur"
|
|
13
|
-
import archiver from "archiver"
|
|
3
|
+
import { exportGerbersToFile } from "lib/export-gerbers"
|
|
14
4
|
|
|
15
5
|
export const exportGerbersCmd = async (ctx: AppContext, args: any) => {
|
|
16
6
|
const params = z
|
|
@@ -21,40 +11,12 @@ export const exportGerbersCmd = async (ctx: AppContext, args: any) => {
|
|
|
21
11
|
})
|
|
22
12
|
.parse(args)
|
|
23
13
|
|
|
24
|
-
|
|
25
|
-
const soup = await soupify(
|
|
14
|
+
await exportGerbersToFile(
|
|
26
15
|
{
|
|
27
|
-
|
|
28
|
-
|
|
16
|
+
example_file_path: params.file,
|
|
17
|
+
export_name: params.export,
|
|
18
|
+
output_zip_path: params.outputfile,
|
|
29
19
|
},
|
|
30
20
|
ctx
|
|
31
21
|
)
|
|
32
|
-
|
|
33
|
-
console.log(kleur.gray("[soup to gerber json]..."))
|
|
34
|
-
const gerber_layer_cmds = convertSoupToGerberCommands(soup)
|
|
35
|
-
|
|
36
|
-
console.log(kleur.gray("[stringify gerber json]..."))
|
|
37
|
-
const gerber_file_contents = stringifyGerberCommandLayers(gerber_layer_cmds)
|
|
38
|
-
|
|
39
|
-
console.log(kleur.gray("[writing gerbers to tmp dir]..."))
|
|
40
|
-
const tempDir = Path.join(".tscircuit", "tmp-gerber-export")
|
|
41
|
-
await fs.mkdirSync(tempDir, { recursive: true })
|
|
42
|
-
for (const [fileName, fileContents] of Object.entries(gerber_file_contents)) {
|
|
43
|
-
const filePath = Path.join(tempDir, fileName)
|
|
44
|
-
await fs.writeFileSync(filePath, fileContents)
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
console.log(kleur.gray("[zipping tmp dir]..."))
|
|
48
|
-
const output = fs.createWriteStream(params.outputfile)
|
|
49
|
-
const archive = archiver("zip", {
|
|
50
|
-
zlib: { level: 9 },
|
|
51
|
-
})
|
|
52
|
-
|
|
53
|
-
archive.pipe(output)
|
|
54
|
-
archive.directory(tempDir, false)
|
|
55
|
-
|
|
56
|
-
await new Promise((resolve, reject) => {
|
|
57
|
-
output.on("close", resolve)
|
|
58
|
-
output.on("error", reject)
|
|
59
|
-
})
|
|
60
22
|
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { AppContext } from "./util/app-context"
|
|
2
|
+
import { z } from "zod"
|
|
3
|
+
import * as Path from "path"
|
|
4
|
+
import { unlink } from "node:fs/promises"
|
|
5
|
+
import { soupify } from "lib/soupify"
|
|
6
|
+
import * as fs from "fs"
|
|
7
|
+
import {
|
|
8
|
+
stringifyGerberCommandLayers,
|
|
9
|
+
convertSoupToGerberCommands,
|
|
10
|
+
} from "@tscircuit/builder"
|
|
11
|
+
import kleur from "kleur"
|
|
12
|
+
import archiver from "archiver"
|
|
13
|
+
|
|
14
|
+
export const exportGerbersToFile = async (
|
|
15
|
+
params: {
|
|
16
|
+
example_file_path: string
|
|
17
|
+
export_name?: string
|
|
18
|
+
output_zip_path: string
|
|
19
|
+
},
|
|
20
|
+
ctx: AppContext
|
|
21
|
+
) => {
|
|
22
|
+
console.log(kleur.gray("[soupifying]..."))
|
|
23
|
+
const soup = await soupify(
|
|
24
|
+
{
|
|
25
|
+
filePath: params.example_file_path,
|
|
26
|
+
exportName: params.export_name,
|
|
27
|
+
},
|
|
28
|
+
ctx
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
console.log(kleur.gray("[soup to gerber json]..."))
|
|
32
|
+
const gerber_layer_cmds = convertSoupToGerberCommands(soup)
|
|
33
|
+
|
|
34
|
+
console.log(kleur.gray("[stringify gerber json]..."))
|
|
35
|
+
const gerber_file_contents = stringifyGerberCommandLayers(gerber_layer_cmds)
|
|
36
|
+
|
|
37
|
+
console.log(kleur.gray("[writing gerbers to tmp dir]..."))
|
|
38
|
+
const tempDir = Path.join(".tscircuit", "tmp-gerber-export")
|
|
39
|
+
fs.mkdirSync(tempDir, { recursive: true })
|
|
40
|
+
for (const [fileName, fileContents] of Object.entries(gerber_file_contents)) {
|
|
41
|
+
const filePath = Path.join(tempDir, fileName)
|
|
42
|
+
await fs.writeFileSync(filePath, fileContents)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
console.log(kleur.gray("[zipping tmp dir]..."))
|
|
46
|
+
const output = fs.createWriteStream(params.output_zip_path)
|
|
47
|
+
const archive = archiver("zip", {
|
|
48
|
+
zlib: { level: 9 },
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
archive.pipe(output)
|
|
52
|
+
archive.directory(tempDir, false)
|
|
53
|
+
|
|
54
|
+
await new Promise((resolve, reject) => {
|
|
55
|
+
output.on("close", resolve)
|
|
56
|
+
output.on("error", reject)
|
|
57
|
+
})
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export const exportGerbersToZipBuffer = async (
|
|
61
|
+
params: {
|
|
62
|
+
example_file_path: string
|
|
63
|
+
export_name?: string
|
|
64
|
+
},
|
|
65
|
+
ctx: AppContext
|
|
66
|
+
) => {
|
|
67
|
+
const tempDir = Path.join(".tscircuit", "tmp-gerber-zip")
|
|
68
|
+
fs.mkdirSync(tempDir, { recursive: true })
|
|
69
|
+
|
|
70
|
+
await exportGerbersToFile(
|
|
71
|
+
{
|
|
72
|
+
example_file_path: params.example_file_path,
|
|
73
|
+
export_name: params.export_name,
|
|
74
|
+
output_zip_path: Path.join(tempDir, "gerbers.zip"),
|
|
75
|
+
},
|
|
76
|
+
ctx
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
const buffer = fs.readFileSync(Path.join(tempDir, "gerbers.zip"))
|
|
80
|
+
|
|
81
|
+
fs.rmSync(tempDir, { recursive: true })
|
|
82
|
+
|
|
83
|
+
return buffer
|
|
84
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tscircuit/cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.60",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Command line tool for developing, publishing and installing tscircuit circuits",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@edge-runtime/primitives": "^4.1.0",
|
|
37
37
|
"@hono/node-server": "^1.8.2",
|
|
38
|
-
"@tscircuit/builder": "
|
|
38
|
+
"@tscircuit/builder": "latest",
|
|
39
39
|
"@tscircuit/react-fiber": "latest",
|
|
40
40
|
"archiver": "^7.0.1",
|
|
41
41
|
"axios": "^1.6.7",
|
|
@@ -62,7 +62,6 @@
|
|
|
62
62
|
"prompts": "^2.4.2",
|
|
63
63
|
"react": "^18.2.0",
|
|
64
64
|
"semver": "^7.6.0",
|
|
65
|
-
"zip-a-folder": "^3.1.6",
|
|
66
65
|
"zod": "latest"
|
|
67
66
|
},
|
|
68
67
|
"devDependencies": {
|