@tscircuit/cli 0.0.206 → 0.0.207

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.
@@ -5,6 +5,7 @@ export const export_parameters = z.object({
5
5
  should_export_pnp_csv: z.boolean().default(false),
6
6
  should_export_bom_csv: z.boolean().default(false),
7
7
  should_export_soup_json: z.boolean().default(false),
8
+ should_export_kicad_pcb: z.boolean().default(false),
8
9
  gerbers_zip_file_name: z
9
10
  .string()
10
11
  .nullable()
@@ -13,6 +14,11 @@ export const export_parameters = z.object({
13
14
  pnp_csv_file_name: z.string().nullable().optional().default("pnp.csv"),
14
15
  bom_csv_file_name: z.string().nullable().optional().default("bom.csv"),
15
16
  soup_json_file_name: z.string().nullable().optional().default("soup.json"),
17
+ kicad_pcb_file_name: z
18
+ .string()
19
+ .nullable()
20
+ .optional()
21
+ .default("output.kicad_pcb"),
16
22
  })
17
23
 
18
24
  export type ExportParametersInput = z.input<typeof export_parameters>
package/bun.lockb CHANGED
Binary file
@@ -6,6 +6,7 @@ import { exportPnpCsvToBuffer } from "cli/lib/export-fns/export-pnp-csv"
6
6
  import { exportBomCsvToBuffer } from "cli/lib/export-fns/export-bom-csv"
7
7
  import { soupify } from "cli/lib/soupify"
8
8
  import { ExportRequest } from "api/db/schema"
9
+ import { exportKicadPcbToBuffer } from "cli/lib/export-fns/export-kicad-pcb"
9
10
 
10
11
  export const uploadBufferToExportFile = async ({
11
12
  dev_server_axios,
@@ -139,5 +140,23 @@ export const fulfillExportRequests = async (
139
140
  export_request_id: export_request.export_request_id,
140
141
  })
141
142
  }
143
+
144
+ if (export_request.export_parameters.should_export_kicad_pcb) {
145
+ console.log(kleur.gray(`\n exporting KiCad PCB...`))
146
+ const kicadPcbBuffer = await exportKicadPcbToBuffer(
147
+ {
148
+ example_file_path: export_request.example_file_path!,
149
+ export_name: export_request.export_name!,
150
+ },
151
+ ctx,
152
+ )
153
+
154
+ await uploadBufferToExportFile({
155
+ dev_server_axios,
156
+ file_buffer: kicadPcbBuffer,
157
+ file_name: export_request.export_parameters.kicad_pcb_file_name!,
158
+ export_request_id: export_request.export_request_id,
159
+ })
160
+ }
142
161
  }
143
162
  }
@@ -0,0 +1,36 @@
1
+ import { AppContext } from "../util/app-context"
2
+ import { z } from "zod"
3
+ import { soupify } from "cli/lib/soupify"
4
+ import {
5
+ convertCircuitJsonToKiCadPcb,
6
+ convertKiCadPcbToSExprString,
7
+ } from "kicad-converter"
8
+ import fs from "fs/promises"
9
+ import kleur from "kleur"
10
+
11
+ export const exportKicadPcb = async (ctx: AppContext, args: any) => {
12
+ const params = z
13
+ .object({
14
+ input: z.string(),
15
+ export: z.string().optional(),
16
+ outputfile: z.string().default("output.kicad_pcb"),
17
+ })
18
+ .parse(args)
19
+
20
+ console.log(kleur.gray("[soupifying]..."))
21
+ const soup = await soupify(
22
+ {
23
+ filePath: params.input,
24
+ exportName: params.export,
25
+ },
26
+ ctx,
27
+ )
28
+
29
+ console.log(kleur.gray("[converting to KiCad PCB]..."))
30
+ const kicadPcb = convertCircuitJsonToKiCadPcb(soup)
31
+
32
+ console.log(kleur.gray(`[writing to ${params.outputfile}]...`))
33
+ await fs.writeFile(params.outputfile, convertKiCadPcbToSExprString(kicadPcb))
34
+
35
+ console.log(kleur.green(`KiCad PCB file exported to ${params.outputfile}`))
36
+ }
@@ -38,6 +38,7 @@ export { configClear } from "./config-clear"
38
38
  export { openCmd as open } from "./open"
39
39
  export { versionCmd as version } from "./version"
40
40
  export { exportGerbersCmd as exportGerbers } from "./export-gerbers"
41
+ export { exportKicadPcb } from "./export-kicad-pcb"
41
42
  export { devServerFulfillExportRequests } from "./dev-server-fulfill-export-requests"
42
43
  export { lintCmd as lint } from "./lint"
43
44
  export { renderCmd as render } from "./render"
@@ -0,0 +1,32 @@
1
+ import { AppContext } from "../util/app-context"
2
+ import { soupify } from "cli/lib/soupify"
3
+ import {
4
+ convertCircuitJsonToKiCadPcb,
5
+ convertKiCadPcbToSExprString,
6
+ } from "kicad-converter"
7
+ import kleur from "kleur"
8
+
9
+ export const exportKicadPcbToBuffer = async (
10
+ params: {
11
+ example_file_path: string
12
+ export_name?: string
13
+ },
14
+ ctx: AppContext,
15
+ ) => {
16
+ console.log(kleur.gray("[soupifying]..."))
17
+ const soup = await soupify(
18
+ {
19
+ filePath: params.example_file_path,
20
+ exportName: params.export_name,
21
+ },
22
+ ctx,
23
+ )
24
+
25
+ console.log(kleur.gray("[converting to KiCad PCB]..."))
26
+ const kicadPcb = convertCircuitJsonToKiCadPcb(soup)
27
+
28
+ console.log(kleur.gray("[converting to S-expression string]..."))
29
+ const kicadPcbString = convertKiCadPcbToSExprString(kicadPcb)
30
+
31
+ return Buffer.from(kicadPcbString, "utf-8")
32
+ }
@@ -293,6 +293,17 @@ export const getProgram = (ctx: AppContext) => {
293
293
  .option("--outputfile <outputfile>", "Output file name", "gerbers.zip")
294
294
  .action((args) => CMDFN.exportGerbers(ctx, args))
295
295
 
296
+ exportCmd
297
+ .command("kicad_pcb")
298
+ .description("Export KiCad PCB file from an example file")
299
+ .option("--input <input>", "Input example file")
300
+ .option(
301
+ "--export <export_name>",
302
+ "Name of export to soupify, if not specified, soupify the default/only export",
303
+ )
304
+ .option("--outputfile <outputfile>", "Output file name", "output.kicad_pcb")
305
+ .action((args) => CMDFN.exportKicadPcb(ctx, args))
306
+
296
307
  cmd
297
308
  .command("soupify")
298
309
  .description("Convert an example file to tscircuit soup")
@@ -0,0 +1,23 @@
1
+ import { test, expect, describe } from "bun:test"
2
+ import { $ } from "bun"
3
+ import { temporaryDirectory } from "tempy"
4
+ import { join } from "path"
5
+ import { existsSync, readFileSync } from "fs"
6
+
7
+ test("tsci export kicad_pcb --input example-project/examples/macrokeypad.tsx", async () => {
8
+ const tempDir = temporaryDirectory()
9
+ const kicadPcbPath = join(tempDir, "output.kicad_pcb")
10
+ const { stdout, stderr } =
11
+ await $`bun cli/cli.ts export kicad_pcb --input example-project/examples/macrokeypad.tsx --outputfile ${kicadPcbPath} --no-color`
12
+
13
+ expect(stderr.toString()).toBe("")
14
+ expect(stdout.toString()).toContain("output.kicad_pcb")
15
+
16
+ expect(existsSync(kicadPcbPath)).toBe(true)
17
+
18
+ const kicadPcbContent = readFileSync(kicadPcbPath, "utf-8")
19
+ expect(kicadPcbContent).toContain("(kicad_pcb")
20
+ expect(kicadPcbContent).toContain("(version")
21
+ expect(kicadPcbContent).toContain("(footprint")
22
+ expect(kicadPcbContent).toContain("(layer")
23
+ })