@tscircuit/cli 0.0.64 → 0.0.65
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/src/lib/zod/export_parameters.ts +7 -0
- package/dev-server-api/src/lib/zod/export_request.ts +2 -0
- package/dev-server-frontend/bun.lockb +0 -0
- package/dev-server-frontend/src/HeaderMenu.tsx +26 -6
- package/dev-server-frontend/src/components/dialogs/generic-export-dialog.tsx +188 -0
- package/dev-server-frontend/tsconfig.json +3 -0
- package/dist/cli.js +132 -55
- package/lib/cmd-fns/dev/fulfill-export-requests.ts +90 -26
- package/lib/cmd-fns/export-gerbers.ts +1 -1
- package/lib/export-fns/export-bom-csv.ts +30 -0
- package/lib/{export-gerbers.ts → export-fns/export-gerbers.ts} +1 -1
- package/lib/export-fns/export-pnp-csv.ts +35 -0
- package/package.json +3 -3
- package/tests/assets/example-project/package-lock.json +28 -9
- package/tests/assets/example-project/package.json +2 -2
- package/tests/assets/example-project/src/MyCircuit.tsx +8 -1
- package/tsconfig.json +3 -1
|
@@ -1,7 +1,37 @@
|
|
|
1
1
|
import { AppContext } from "../../util/app-context"
|
|
2
2
|
import kleur from "kleur"
|
|
3
|
-
import { exportGerbersToZipBuffer } from "lib/export-gerbers"
|
|
3
|
+
import { exportGerbersToZipBuffer } from "lib/export-fns/export-gerbers"
|
|
4
4
|
import { AxiosInstance } from "axios"
|
|
5
|
+
import { ExportRequest } from "@server/lib/zod/export_request"
|
|
6
|
+
import { exportPnpCsvToBuffer } from "lib/export-fns/export-pnp-csv"
|
|
7
|
+
import { exportBomCsvToBuffer } from "lib/export-fns/export-bom-csv"
|
|
8
|
+
|
|
9
|
+
export const uploadBufferToExportFile = async ({
|
|
10
|
+
dev_server_axios,
|
|
11
|
+
file_buffer,
|
|
12
|
+
file_name,
|
|
13
|
+
export_request_id,
|
|
14
|
+
}: {
|
|
15
|
+
dev_server_axios: AxiosInstance
|
|
16
|
+
file_buffer: Buffer
|
|
17
|
+
file_name: string
|
|
18
|
+
export_request_id: number
|
|
19
|
+
}) => {
|
|
20
|
+
await dev_server_axios.post("/api/export_files/create", {
|
|
21
|
+
file_content_base64: file_buffer.toString("base64"),
|
|
22
|
+
file_name: file_name,
|
|
23
|
+
export_request_id: export_request_id,
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
console.log(kleur.gray(` marking export request as complete...`))
|
|
27
|
+
|
|
28
|
+
await dev_server_axios.post("/api/export_requests/update", {
|
|
29
|
+
export_request_id: export_request_id,
|
|
30
|
+
is_complete: true,
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
console.log(kleur.green(` done`))
|
|
34
|
+
}
|
|
5
35
|
|
|
6
36
|
export const fulfillExportRequests = async (
|
|
7
37
|
{
|
|
@@ -11,46 +41,80 @@ export const fulfillExportRequests = async (
|
|
|
11
41
|
},
|
|
12
42
|
ctx: AppContext
|
|
13
43
|
) => {
|
|
14
|
-
const export_requests = await dev_server_axios
|
|
44
|
+
const export_requests: ExportRequest[] = await dev_server_axios
|
|
15
45
|
.post("/api/export_requests/list", {
|
|
16
46
|
is_complete: false,
|
|
17
47
|
})
|
|
18
48
|
.then((r) => r.data.export_requests)
|
|
19
49
|
|
|
20
50
|
for (const export_request of export_requests) {
|
|
21
|
-
console.log(
|
|
51
|
+
console.log(
|
|
52
|
+
kleur.gray(
|
|
53
|
+
`Fulfilling export request ${export_request.export_request_id}`
|
|
54
|
+
)
|
|
55
|
+
)
|
|
22
56
|
console.log(
|
|
23
57
|
kleur.gray(` example_file_path: ${export_request.example_file_path}`)
|
|
24
58
|
)
|
|
25
59
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
60
|
+
if (export_request.export_parameters.should_export_gerber_zip) {
|
|
61
|
+
console.log(kleur.gray(`\n exporting gerbers...`))
|
|
62
|
+
const zip_buffer = await exportGerbersToZipBuffer(
|
|
63
|
+
{
|
|
64
|
+
example_file_path: export_request.example_file_path,
|
|
65
|
+
export_name: export_request.export_name,
|
|
66
|
+
},
|
|
67
|
+
ctx
|
|
68
|
+
)
|
|
34
69
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
70
|
+
console.log(
|
|
71
|
+
kleur.gray(
|
|
72
|
+
` uploading zip "${export_request.export_parameters.gerbers_zip_file_name}" to dev server...`
|
|
73
|
+
)
|
|
38
74
|
)
|
|
39
|
-
)
|
|
40
75
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
76
|
+
await uploadBufferToExportFile({
|
|
77
|
+
dev_server_axios,
|
|
78
|
+
file_buffer: zip_buffer,
|
|
79
|
+
file_name: export_request.export_parameters.gerbers_zip_file_name!,
|
|
80
|
+
export_request_id: export_request.export_request_id,
|
|
81
|
+
})
|
|
82
|
+
}
|
|
46
83
|
|
|
47
|
-
|
|
84
|
+
if (export_request.export_parameters.should_export_pnp_csv) {
|
|
85
|
+
console.log(kleur.gray(`\n exporting pick'n'place...`))
|
|
86
|
+
const csv_buffer = await exportPnpCsvToBuffer(
|
|
87
|
+
{
|
|
88
|
+
example_file_path: export_request.example_file_path,
|
|
89
|
+
export_name: export_request.export_name,
|
|
90
|
+
},
|
|
91
|
+
ctx
|
|
92
|
+
)
|
|
48
93
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
94
|
+
await uploadBufferToExportFile({
|
|
95
|
+
dev_server_axios,
|
|
96
|
+
file_buffer: csv_buffer,
|
|
97
|
+
file_name: export_request.export_parameters.pnp_csv_file_name!,
|
|
98
|
+
export_request_id: export_request.export_request_id,
|
|
99
|
+
})
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (export_request.export_parameters.should_export_bom_csv) {
|
|
103
|
+
console.log(kleur.gray(`\n exporting bill of materials...`))
|
|
104
|
+
const csv_buffer = await exportBomCsvToBuffer(
|
|
105
|
+
{
|
|
106
|
+
example_file_path: export_request.example_file_path,
|
|
107
|
+
export_name: export_request.export_name,
|
|
108
|
+
},
|
|
109
|
+
ctx
|
|
110
|
+
)
|
|
53
111
|
|
|
54
|
-
|
|
112
|
+
await uploadBufferToExportFile({
|
|
113
|
+
dev_server_axios,
|
|
114
|
+
file_buffer: csv_buffer,
|
|
115
|
+
file_name: export_request.export_parameters.bom_csv_file_name!,
|
|
116
|
+
export_request_id: export_request.export_request_id,
|
|
117
|
+
})
|
|
118
|
+
}
|
|
55
119
|
}
|
|
56
120
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AppContext } from "../util/app-context"
|
|
2
2
|
import { z } from "zod"
|
|
3
|
-
import { exportGerbersToFile } from "lib/export-gerbers"
|
|
3
|
+
import { exportGerbersToFile } from "lib/export-fns/export-gerbers"
|
|
4
4
|
|
|
5
5
|
export const exportGerbersCmd = async (ctx: AppContext, args: any) => {
|
|
6
6
|
const params = z
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { AppContext } from "../util/app-context"
|
|
2
|
+
import { soupify } from "lib/soupify"
|
|
3
|
+
import { convertSoupToBomRows, convertBomRowsToCsv } from "@tscircuit/builder"
|
|
4
|
+
import kleur from "kleur"
|
|
5
|
+
|
|
6
|
+
export const exportBomCsvToBuffer = async (
|
|
7
|
+
params: {
|
|
8
|
+
example_file_path: string
|
|
9
|
+
export_name?: string
|
|
10
|
+
},
|
|
11
|
+
ctx: AppContext
|
|
12
|
+
) => {
|
|
13
|
+
console.log(kleur.gray("[soupifying]..."))
|
|
14
|
+
const soup = await soupify(
|
|
15
|
+
{
|
|
16
|
+
filePath: params.example_file_path,
|
|
17
|
+
exportName: params.export_name,
|
|
18
|
+
},
|
|
19
|
+
ctx
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
console.log(kleur.gray("[soup to bom rows]..."))
|
|
23
|
+
// @ts-ignore
|
|
24
|
+
const bom_rows = await convertSoupToBomRows({ soup })
|
|
25
|
+
|
|
26
|
+
console.log(kleur.gray("[bom rows to csv]..."))
|
|
27
|
+
const bom_csv = await convertBomRowsToCsv(bom_rows)
|
|
28
|
+
|
|
29
|
+
return Buffer.from(bom_csv, "utf-8")
|
|
30
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
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
|
+
convertSoupToPickAndPlaceCsv,
|
|
11
|
+
} from "@tscircuit/builder"
|
|
12
|
+
import kleur from "kleur"
|
|
13
|
+
import archiver from "archiver"
|
|
14
|
+
|
|
15
|
+
export const exportPnpCsvToBuffer = async (
|
|
16
|
+
params: {
|
|
17
|
+
example_file_path: string
|
|
18
|
+
export_name?: 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 pnp csv string]..."))
|
|
32
|
+
const pnp_csv = await convertSoupToPickAndPlaceCsv(soup)
|
|
33
|
+
|
|
34
|
+
return Buffer.from(pnp_csv, "utf-8")
|
|
35
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tscircuit/cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.65",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Command line tool for developing, publishing and installing tscircuit circuits",
|
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@edge-runtime/primitives": "^4.1.0",
|
|
37
37
|
"@hono/node-server": "^1.8.2",
|
|
38
|
-
"@tscircuit/builder": "^1.5.
|
|
39
|
-
"@tscircuit/react-fiber": "^1.0.
|
|
38
|
+
"@tscircuit/builder": "^1.5.60",
|
|
39
|
+
"@tscircuit/react-fiber": "^1.0.34",
|
|
40
40
|
"archiver": "^7.0.1",
|
|
41
41
|
"axios": "^1.6.7",
|
|
42
42
|
"better-sqlite3": "^9.4.3",
|
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
"name": "example-project",
|
|
9
9
|
"version": "1.2.26",
|
|
10
10
|
"dependencies": {
|
|
11
|
-
"@tscircuit/builder": "^1.5.
|
|
12
|
-
"@tscircuit/react-fiber": "^1.0.
|
|
11
|
+
"@tscircuit/builder": "^1.5.61",
|
|
12
|
+
"@tscircuit/react-fiber": "^1.0.34"
|
|
13
13
|
}
|
|
14
14
|
},
|
|
15
15
|
"node_modules/@babel/runtime": {
|
|
@@ -29,17 +29,18 @@
|
|
|
29
29
|
"integrity": "sha512-iB+oaYyaVK1hQ0cODubnoSDg4gGYL9cp/4ad7G1b9Z0/IqehPztp5qE3KP2mV9Ns0UYmzwvtkEhTCmKUuhorbg=="
|
|
30
30
|
},
|
|
31
31
|
"node_modules/@tscircuit/builder": {
|
|
32
|
-
"version": "1.5.
|
|
33
|
-
"resolved": "https://registry.npmjs.org/@tscircuit/builder/-/builder-1.5.
|
|
34
|
-
"integrity": "sha512-
|
|
32
|
+
"version": "1.5.61",
|
|
33
|
+
"resolved": "https://registry.npmjs.org/@tscircuit/builder/-/builder-1.5.61.tgz",
|
|
34
|
+
"integrity": "sha512-pkaIte2C6Kksp3B79eQIG5f0/9KO2x0fdkHe/a0757lMYVUbcSvqjanL7RmJJ983C2wnEMo2au5ycgXvZseMUQ==",
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@lume/kiwi": "^0.1.0",
|
|
37
|
-
"@tscircuit/builder": "^1.5.55",
|
|
38
37
|
"@tscircuit/footprints": "^0.0.14",
|
|
39
38
|
"@tscircuit/routing": "^1.3.1",
|
|
40
39
|
"@tscircuit/sparkfun-packages": "^1.2.0",
|
|
41
40
|
"convert-units": "^2.3.4",
|
|
42
41
|
"fast-json-stable-stringify": "^2.1.0",
|
|
42
|
+
"format-si-prefix": "^0.3.2",
|
|
43
|
+
"papaparse": "^5.4.1",
|
|
43
44
|
"rectilinear-router": "^1.0.1",
|
|
44
45
|
"svg-path-bounds": "^1.0.2",
|
|
45
46
|
"transformation-matrix": "^2.12.0"
|
|
@@ -68,9 +69,9 @@
|
|
|
68
69
|
}
|
|
69
70
|
},
|
|
70
71
|
"node_modules/@tscircuit/react-fiber": {
|
|
71
|
-
"version": "1.0.
|
|
72
|
-
"resolved": "https://registry.npmjs.org/@tscircuit/react-fiber/-/react-fiber-1.0.
|
|
73
|
-
"integrity": "sha512-
|
|
72
|
+
"version": "1.0.34",
|
|
73
|
+
"resolved": "https://registry.npmjs.org/@tscircuit/react-fiber/-/react-fiber-1.0.34.tgz",
|
|
74
|
+
"integrity": "sha512-kI5oOe/dbJGbeWlInx239hXNWPIRMRTgD8pO9IXvAvZ4YOldR6CJanx9DuT5vgTcZTjoswaXJzRJZZB1Ib2jmw==",
|
|
74
75
|
"dependencies": {
|
|
75
76
|
"react-reconciler": "^0.29.0"
|
|
76
77
|
},
|
|
@@ -120,6 +121,14 @@
|
|
|
120
121
|
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
|
|
121
122
|
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
|
|
122
123
|
},
|
|
124
|
+
"node_modules/format-si-prefix": {
|
|
125
|
+
"version": "0.3.2",
|
|
126
|
+
"resolved": "https://registry.npmjs.org/format-si-prefix/-/format-si-prefix-0.3.2.tgz",
|
|
127
|
+
"integrity": "sha512-gtCZh4RpmlmEZtyzyvs+FXXWOmdfpQQ0M7mjc81zpAYm5QpsoUDPKhAK+Lj7fJCtZSJpE5xbpCYgspCBxahObQ==",
|
|
128
|
+
"dependencies": {
|
|
129
|
+
"parseunit": "^0"
|
|
130
|
+
}
|
|
131
|
+
},
|
|
123
132
|
"node_modules/glpk.js": {
|
|
124
133
|
"version": "4.0.2",
|
|
125
134
|
"resolved": "https://registry.npmjs.org/glpk.js/-/glpk.js-4.0.2.tgz",
|
|
@@ -326,11 +335,21 @@
|
|
|
326
335
|
"resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz",
|
|
327
336
|
"integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug=="
|
|
328
337
|
},
|
|
338
|
+
"node_modules/papaparse": {
|
|
339
|
+
"version": "5.4.1",
|
|
340
|
+
"resolved": "https://registry.npmjs.org/papaparse/-/papaparse-5.4.1.tgz",
|
|
341
|
+
"integrity": "sha512-HipMsgJkZu8br23pW15uvo6sib6wne/4woLZPlFf3rpDyMe9ywEXUsuD7+6K9PRkJlVT51j/sCOYDKGGS3ZJrw=="
|
|
342
|
+
},
|
|
329
343
|
"node_modules/parse-svg-path": {
|
|
330
344
|
"version": "0.1.2",
|
|
331
345
|
"resolved": "https://registry.npmjs.org/parse-svg-path/-/parse-svg-path-0.1.2.tgz",
|
|
332
346
|
"integrity": "sha512-JyPSBnkTJ0AI8GGJLfMXvKq42cj5c006fnLz6fXy6zfoVjJizi8BNTpu8on8ziI1cKy9d9DGNuY17Ce7wuejpQ=="
|
|
333
347
|
},
|
|
348
|
+
"node_modules/parseunit": {
|
|
349
|
+
"version": "0.3.1",
|
|
350
|
+
"resolved": "https://registry.npmjs.org/parseunit/-/parseunit-0.3.1.tgz",
|
|
351
|
+
"integrity": "sha512-kKtTgCJDsktOHsnvRR/B5DhWi3a/RZ5M9XjVQZGbOatcam+/tk4sMOCQ1WM9Rswfr78zWGBgHNbWTyJvfR0ejg=="
|
|
352
|
+
},
|
|
334
353
|
"node_modules/pathfinding": {
|
|
335
354
|
"version": "0.4.18",
|
|
336
355
|
"resolved": "https://registry.npmjs.org/pathfinding/-/pathfinding-0.4.18.tgz",
|
|
@@ -2,6 +2,13 @@ import "@tscircuit/react-fiber"
|
|
|
2
2
|
|
|
3
3
|
export const MyCircuit = () => (
|
|
4
4
|
<board width="40mm" height="40mm" center_x={0} center_y={0}>
|
|
5
|
-
<resistor
|
|
5
|
+
<resistor
|
|
6
|
+
name="R1"
|
|
7
|
+
resistance="20kohm"
|
|
8
|
+
footprint="0805"
|
|
9
|
+
supplier_part_numbers={{
|
|
10
|
+
jlcpcb: "C2759650",
|
|
11
|
+
}}
|
|
12
|
+
/>
|
|
6
13
|
</board>
|
|
7
14
|
)
|
package/tsconfig.json
CHANGED
|
@@ -29,7 +29,9 @@
|
|
|
29
29
|
// "rootDir": "./", /* Specify the root folder within your source files. */
|
|
30
30
|
"moduleResolution": "Bundler", /* Specify how TypeScript looks up a file from a given module specifier. */
|
|
31
31
|
"baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
|
|
32
|
-
"paths": {
|
|
32
|
+
"paths": {
|
|
33
|
+
"@server/*": ["./dev-server-api/src/*"]
|
|
34
|
+
}, /* Specify a set of entries that re-map imports to additional lookup locations. */
|
|
33
35
|
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
|
|
34
36
|
// "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
|
|
35
37
|
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
|