@tscircuit/cli 0.0.64 → 0.0.66

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.
@@ -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(kleur.gray(`Fulfilling export request ${export_request.id}`))
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
- console.log(kleur.gray(`\n exporting gerbers...`))
27
- const zip_buffer = await exportGerbersToZipBuffer(
28
- {
29
- example_file_path: export_request.example_file_path,
30
- export_name: export_request.export_name,
31
- },
32
- ctx
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
- console.log(
36
- kleur.gray(
37
- ` uploading zip "${export_request.export_parameters.gerbers_zip_file_name}" to dev server...`
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
- await dev_server_axios.post("/api/export_files/create", {
42
- file_content_base64: zip_buffer.toString("base64"),
43
- file_name: export_request.export_parameters.gerbers_zip_file_name,
44
- export_request_id: export_request.export_request_id,
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
- console.log(kleur.gray(` marking export request as complete...`))
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
- await dev_server_axios.post("/api/export_requests/update", {
50
- export_request_id: export_request.export_request_id,
51
- is_complete: true,
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
- console.log(kleur.green(` done`))
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
+ }
@@ -1,4 +1,4 @@
1
- import { AppContext } from "./util/app-context"
1
+ import { AppContext } from "../util/app-context"
2
2
  import { z } from "zod"
3
3
  import * as Path from "path"
4
4
  import { unlink } from "node:fs/promises"
@@ -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/lib/soupify.ts CHANGED
@@ -6,6 +6,9 @@ import { unlink } from "node:fs/promises"
6
6
  import kleur from "kleur"
7
7
  import { writeFileSync } from "fs"
8
8
  import { readFile } from "fs/promises"
9
+ import Debug from "debug"
10
+
11
+ const debug = Debug("tscircuit:soupify")
9
12
 
10
13
  export const soupify = async (
11
14
  {
@@ -17,6 +20,7 @@ export const soupify = async (
17
20
  },
18
21
  ctx: { runtime: "node" | "bun" }
19
22
  ) => {
23
+ debug(`reading ${filePath}`)
20
24
  const targetFileContent = await readFile(filePath, "utf-8")
21
25
 
22
26
  if (!exportName) {
@@ -43,6 +47,7 @@ export const soupify = async (
43
47
  Path.basename(filePath).replace(/\.[^\.]+$/, "") + ".__tmp_entrypoint.tsx"
44
48
  )
45
49
 
50
+ debug(`writing to ${tmpFilePath}`)
46
51
  writeFileSync(
47
52
  tmpFilePath,
48
53
  `
@@ -69,20 +74,24 @@ console.log(JSON.stringify(elements))
69
74
  `.trim()
70
75
  )
71
76
 
77
+ debug(`using runtime ${ctx.runtime}`)
72
78
  const processCmdPart1 =
73
79
  ctx.runtime === "node" ? $`npx tsx ${tmpFilePath}` : $`bun ${tmpFilePath}`
74
80
 
81
+ debug(`starting process....`)
75
82
  const processResult = await processCmdPart1
76
- .stdout("piped")
77
- .stderr("piped")
83
+ .stdout("inheritPiped")
84
+ .stderr("inheritPiped")
78
85
  .noThrow()
79
86
 
80
87
  const rawSoup = processResult.stdout
81
88
  const errText = processResult.stderr
82
89
 
90
+ debug(`deleting ${tmpFilePath}`)
83
91
  await unlink(tmpFilePath)
84
92
 
85
93
  try {
94
+ debug(`parsing result of soupify...`)
86
95
  const soup = JSON.parse(rawSoup)
87
96
 
88
97
  if (soup.COMPILE_ERROR) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tscircuit/cli",
3
- "version": "0.0.64",
3
+ "version": "0.0.66",
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.53",
39
- "@tscircuit/react-fiber": "^1.0.22",
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",
@@ -45,6 +45,7 @@
45
45
  "configstore": "^6.0.0",
46
46
  "dargs": "^8.1.0",
47
47
  "dax-sh": "^0.39.2",
48
+ "debug": "^4.3.4",
48
49
  "delay": "^6.0.0",
49
50
  "edgespec": "^0.0.69",
50
51
  "esbuild": "^0.20.2",
@@ -69,6 +70,7 @@
69
70
  "@types/bun": "^1.0.8",
70
71
  "@types/chokidar": "^2.1.3",
71
72
  "@types/configstore": "^6.0.2",
73
+ "@types/debug": "^4.1.12",
72
74
  "@types/lodash": "^4.14.202",
73
75
  "@types/mime-types": "^2.1.4",
74
76
  "@types/minimist": "^1.2.5",
@@ -8,8 +8,8 @@
8
8
  "name": "example-project",
9
9
  "version": "1.2.26",
10
10
  "dependencies": {
11
- "@tscircuit/builder": "^1.5.56",
12
- "@tscircuit/react-fiber": "^1.0.33"
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.56",
33
- "resolved": "https://registry.npmjs.org/@tscircuit/builder/-/builder-1.5.56.tgz",
34
- "integrity": "sha512-Kx1lg9zc0qqlsp1Udnz4QbtZUgmaXUsS4SY6x4I9bg1SIPLaQnMXe7X6cxWEn5ByenP8jkAs3qmfMxFxYzSPmA==",
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.33",
72
- "resolved": "https://registry.npmjs.org/@tscircuit/react-fiber/-/react-fiber-1.0.33.tgz",
73
- "integrity": "sha512-9+WL0+sI4vs21s7AVNHRckaCSYw2/61/TEnJTZCYM9SkBXGLj1LbaIJNgxCVmUH3Mtn/JcNo3LVApDGvsyOhRw==",
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",
@@ -4,7 +4,7 @@
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "dependencies": {
7
- "@tscircuit/builder": "^1.5.56",
8
- "@tscircuit/react-fiber": "^1.0.33"
7
+ "@tscircuit/builder": "^1.5.61",
8
+ "@tscircuit/react-fiber": "^1.0.34"
9
9
  }
10
10
  }
@@ -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 name="R1" resistance="20kohm" footprint="1210" />
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": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
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. */