circuit-json-to-tscircuit 0.0.29 → 0.0.30
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/dist/{chunk-O2XG7HJL.js → chunk-Y7MQ2KXU.js} +47 -25
- package/dist/cli/main.js +2 -2
- package/dist/lib/index.js +1 -1
- package/lib/generate-footprint-tsx/convert-keepouts.ts +24 -0
- package/lib/generate-footprint-tsx.tsx +2 -0
- package/package.json +1 -1
- package/tests/__snapshots__/test17-support-pcb-keepouts-pcb.snap.svg +1 -0
- package/tests/test17-support-pcb-keepouts.test.tsx +82 -0
|
@@ -251,14 +251,35 @@ var convertHoles = (circuitJson) => {
|
|
|
251
251
|
return elementStrings;
|
|
252
252
|
};
|
|
253
253
|
|
|
254
|
-
// lib/generate-footprint-tsx/convert-
|
|
254
|
+
// lib/generate-footprint-tsx/convert-keepouts.ts
|
|
255
255
|
import { su as su6 } from "@tscircuit/soup-util";
|
|
256
|
+
var convertKeepouts = (circuitJson) => {
|
|
257
|
+
const pcbKeepouts = su6(circuitJson).pcb_keepout.list();
|
|
258
|
+
const elementStrings = [];
|
|
259
|
+
for (const keepout of pcbKeepouts) {
|
|
260
|
+
if (keepout.shape === "rect") {
|
|
261
|
+
elementStrings.push(
|
|
262
|
+
`<keepout shape="rect" pcbX="${formatMm(keepout.center.x)}" pcbY="${formatMm(keepout.center.y)}" width="${formatMm(keepout.width)}" height="${formatMm(keepout.height)}" />`
|
|
263
|
+
);
|
|
264
|
+
} else if (keepout.shape === "circle") {
|
|
265
|
+
elementStrings.push(
|
|
266
|
+
`<keepout shape="circle" pcbX="${formatMm(keepout.center.x)}" pcbY="${formatMm(keepout.center.y)}" radius="${formatMm(keepout.radius)}" />`
|
|
267
|
+
);
|
|
268
|
+
} else {
|
|
269
|
+
console.warn(`Unhandled pcb_keepout shape: ${keepout.shape}`);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
return elementStrings;
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
// lib/generate-footprint-tsx/convert-notes.ts
|
|
276
|
+
import { su as su7 } from "@tscircuit/soup-util";
|
|
256
277
|
var convertNotes = (circuitJson) => {
|
|
257
|
-
const noteTexts =
|
|
258
|
-
const noteRects =
|
|
259
|
-
const notePaths =
|
|
260
|
-
const noteLines =
|
|
261
|
-
const noteDimensions =
|
|
278
|
+
const noteTexts = su7(circuitJson).pcb_note_text.list();
|
|
279
|
+
const noteRects = su7(circuitJson).pcb_note_rect.list();
|
|
280
|
+
const notePaths = su7(circuitJson).pcb_note_path.list();
|
|
281
|
+
const noteLines = su7(circuitJson).pcb_note_line.list();
|
|
282
|
+
const noteDimensions = su7(circuitJson).pcb_note_dimension.list();
|
|
262
283
|
const elementStrings = [];
|
|
263
284
|
for (const noteText of noteTexts) {
|
|
264
285
|
const anchorPosition = noteText.anchor_position ?? { x: 0, y: 0 };
|
|
@@ -348,14 +369,14 @@ var convertNotes = (circuitJson) => {
|
|
|
348
369
|
};
|
|
349
370
|
|
|
350
371
|
// lib/generate-footprint-tsx/convert-plated-holes.ts
|
|
351
|
-
import { su as
|
|
372
|
+
import { su as su8 } from "@tscircuit/soup-util";
|
|
352
373
|
import { mmStr as mmStr3 } from "@tscircuit/mm";
|
|
353
374
|
var formatOptionalMmAttr = (attrName, value) => {
|
|
354
375
|
if (value === void 0) return "";
|
|
355
376
|
return ` ${attrName}="${mmStr3(value)}"`;
|
|
356
377
|
};
|
|
357
378
|
var convertPlatedHoles = (circuitJson) => {
|
|
358
|
-
const platedHoles =
|
|
379
|
+
const platedHoles = su8(circuitJson).pcb_plated_hole.list();
|
|
359
380
|
const elementStrings = [];
|
|
360
381
|
for (const platedHole of platedHoles) {
|
|
361
382
|
if (platedHole.shape === "oval" || platedHole.shape === "pill") {
|
|
@@ -385,12 +406,12 @@ var convertPlatedHoles = (circuitJson) => {
|
|
|
385
406
|
};
|
|
386
407
|
|
|
387
408
|
// lib/generate-footprint-tsx/convert-silkscreen.ts
|
|
388
|
-
import { su as
|
|
409
|
+
import { su as su9 } from "@tscircuit/soup-util";
|
|
389
410
|
var convertSilkscreen = (circuitJson) => {
|
|
390
|
-
const silkscreenLines =
|
|
391
|
-
const silkscreenPaths =
|
|
392
|
-
const silkscreenRects =
|
|
393
|
-
const silkscreenCircles =
|
|
411
|
+
const silkscreenLines = su9(circuitJson).pcb_silkscreen_line.list();
|
|
412
|
+
const silkscreenPaths = su9(circuitJson).pcb_silkscreen_path.list();
|
|
413
|
+
const silkscreenRects = su9(circuitJson).pcb_silkscreen_rect.list();
|
|
414
|
+
const silkscreenCircles = su9(circuitJson).pcb_silkscreen_circle.list();
|
|
394
415
|
const elementStrings = [];
|
|
395
416
|
for (const silkscreenPath of silkscreenPaths) {
|
|
396
417
|
elementStrings.push(
|
|
@@ -452,9 +473,9 @@ var convertSilkscreen = (circuitJson) => {
|
|
|
452
473
|
};
|
|
453
474
|
|
|
454
475
|
// lib/generate-footprint-tsx/convert-silkscreen-text.ts
|
|
455
|
-
import { su as
|
|
476
|
+
import { su as su10 } from "@tscircuit/soup-util";
|
|
456
477
|
var convertSilkscreenText = (circuitJson) => {
|
|
457
|
-
const silkscreenTexts =
|
|
478
|
+
const silkscreenTexts = su10(circuitJson).pcb_silkscreen_text.list();
|
|
458
479
|
const elementStrings = [];
|
|
459
480
|
for (const silkscreenText of silkscreenTexts) {
|
|
460
481
|
const pcbX = silkscreenText.anchor_position?.x ?? 0;
|
|
@@ -467,10 +488,10 @@ var convertSilkscreenText = (circuitJson) => {
|
|
|
467
488
|
};
|
|
468
489
|
|
|
469
490
|
// lib/generate-footprint-tsx/convert-smt-pads.ts
|
|
470
|
-
import { su as
|
|
491
|
+
import { su as su11 } from "@tscircuit/soup-util";
|
|
471
492
|
import { mmStr as mmStr4 } from "@tscircuit/mm";
|
|
472
493
|
var convertSmtPads = (circuitJson) => {
|
|
473
|
-
const smtPads =
|
|
494
|
+
const smtPads = su11(circuitJson).pcb_smtpad.list();
|
|
474
495
|
const elementStrings = [];
|
|
475
496
|
for (const smtPad of smtPads) {
|
|
476
497
|
if (smtPad.shape === "circle") {
|
|
@@ -508,6 +529,7 @@ var generateFootprintTsx = (circuitJson) => {
|
|
|
508
529
|
convertFabrication,
|
|
509
530
|
convertSilkscreenText,
|
|
510
531
|
convertCopperText,
|
|
532
|
+
convertKeepouts,
|
|
511
533
|
convertCutouts,
|
|
512
534
|
convertNotes,
|
|
513
535
|
convertCourtyard
|
|
@@ -524,15 +546,15 @@ var generateFootprintTsx = (circuitJson) => {
|
|
|
524
546
|
};
|
|
525
547
|
|
|
526
548
|
// lib/generate-symbol-tsx.ts
|
|
527
|
-
import { su as
|
|
549
|
+
import { su as su12 } from "@tscircuit/soup-util";
|
|
528
550
|
var generateSymbolTsx = (circuitJson) => {
|
|
529
|
-
const schematicArcs =
|
|
530
|
-
const schematicLines =
|
|
531
|
-
const schematicPaths =
|
|
532
|
-
const schematicTexts =
|
|
533
|
-
const schematicCircles =
|
|
534
|
-
const schematicBoxes =
|
|
535
|
-
const schematicRects =
|
|
551
|
+
const schematicArcs = su12(circuitJson).schematic_arc.list();
|
|
552
|
+
const schematicLines = su12(circuitJson).schematic_line.list();
|
|
553
|
+
const schematicPaths = su12(circuitJson).schematic_path.list();
|
|
554
|
+
const schematicTexts = su12(circuitJson).schematic_text.list();
|
|
555
|
+
const schematicCircles = su12(circuitJson).schematic_circle.list();
|
|
556
|
+
const schematicBoxes = su12(circuitJson).schematic_box.list();
|
|
557
|
+
const schematicRects = su12(circuitJson).schematic_rect.list();
|
|
536
558
|
const elementStrings = [];
|
|
537
559
|
for (const arc of schematicArcs) {
|
|
538
560
|
const center = arc.center ?? { x: 0, y: 0 };
|
package/dist/cli/main.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
convertCircuitJsonToTscircuit
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-Y7MQ2KXU.js";
|
|
5
5
|
|
|
6
6
|
// cli/main.ts
|
|
7
7
|
import { Command } from "commander";
|
|
@@ -16,7 +16,7 @@ var package_default = {
|
|
|
16
16
|
"./cli": "./dist/cli/main.js"
|
|
17
17
|
},
|
|
18
18
|
type: "module",
|
|
19
|
-
version: "0.0.
|
|
19
|
+
version: "0.0.29",
|
|
20
20
|
scripts: {
|
|
21
21
|
build: "tsup-node lib/index.ts cli/main.ts --format esm --dts",
|
|
22
22
|
test: "bun test",
|
package/dist/lib/index.js
CHANGED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { su } from "@tscircuit/soup-util"
|
|
2
|
+
import type { FootprintElementConverter } from "./converter-types"
|
|
3
|
+
import { formatMm } from "./helpers"
|
|
4
|
+
|
|
5
|
+
export const convertKeepouts: FootprintElementConverter = (circuitJson) => {
|
|
6
|
+
const pcbKeepouts = su(circuitJson).pcb_keepout.list()
|
|
7
|
+
const elementStrings: string[] = []
|
|
8
|
+
|
|
9
|
+
for (const keepout of pcbKeepouts) {
|
|
10
|
+
if (keepout.shape === "rect") {
|
|
11
|
+
elementStrings.push(
|
|
12
|
+
`<keepout shape="rect" pcbX="${formatMm(keepout.center.x)}" pcbY="${formatMm(keepout.center.y)}" width="${formatMm(keepout.width)}" height="${formatMm(keepout.height)}" />`,
|
|
13
|
+
)
|
|
14
|
+
} else if (keepout.shape === "circle") {
|
|
15
|
+
elementStrings.push(
|
|
16
|
+
`<keepout shape="circle" pcbX="${formatMm(keepout.center.x)}" pcbY="${formatMm(keepout.center.y)}" radius="${formatMm(keepout.radius)}" />`,
|
|
17
|
+
)
|
|
18
|
+
} else {
|
|
19
|
+
console.warn(`Unhandled pcb_keepout shape: ${(keepout as any).shape}`)
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return elementStrings
|
|
24
|
+
}
|
|
@@ -5,6 +5,7 @@ import { convertCourtyard } from "./generate-footprint-tsx/convert-courtyard"
|
|
|
5
5
|
import { convertCutouts } from "./generate-footprint-tsx/convert-cutouts"
|
|
6
6
|
import { convertFabrication } from "./generate-footprint-tsx/convert-fabrication"
|
|
7
7
|
import { convertHoles } from "./generate-footprint-tsx/convert-holes"
|
|
8
|
+
import { convertKeepouts } from "./generate-footprint-tsx/convert-keepouts"
|
|
8
9
|
import { convertNotes } from "./generate-footprint-tsx/convert-notes"
|
|
9
10
|
import { convertPlatedHoles } from "./generate-footprint-tsx/convert-plated-holes"
|
|
10
11
|
import { convertSilkscreen } from "./generate-footprint-tsx/convert-silkscreen"
|
|
@@ -22,6 +23,7 @@ export const generateFootprintTsx = (
|
|
|
22
23
|
convertFabrication,
|
|
23
24
|
convertSilkscreenText,
|
|
24
25
|
convertCopperText,
|
|
26
|
+
convertKeepouts,
|
|
25
27
|
convertCutouts,
|
|
26
28
|
convertNotes,
|
|
27
29
|
convertCourtyard,
|
package/package.json
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="800" height="600" data-software-used-string="@tscircuit/core@0.0.1090"><style></style><defs><pattern id="pcb-keepout-pattern" width="20" height="20" patternUnits="userSpaceOnUse"><line x1="-20" y1="0" x2="0" y2="20" stroke="#FF6B6B" stroke-width="1"/><line x1="-15" y1="0" x2="5" y2="20" stroke="#FF6B6B" stroke-width="1"/><line x1="-10" y1="0" x2="10" y2="20" stroke="#FF6B6B" stroke-width="1"/><line x1="-5" y1="0" x2="15" y2="20" stroke="#FF6B6B" stroke-width="1"/><line x1="0" y1="0" x2="20" y2="20" stroke="#FF6B6B" stroke-width="1"/><line x1="5" y1="0" x2="25" y2="20" stroke="#FF6B6B" stroke-width="1"/><line x1="10" y1="0" x2="30" y2="20" stroke="#FF6B6B" stroke-width="1"/><line x1="15" y1="0" x2="35" y2="20" stroke="#FF6B6B" stroke-width="1"/><line x1="20" y1="0" x2="40" y2="20" stroke="#FF6B6B" stroke-width="1"/></pattern></defs><rect class="boundary" x="0" y="0" fill="#000" width="800" height="600" data-type="pcb_background" data-pcb-layer="global"/><rect class="pcb-boundary" fill="none" stroke="#fff" stroke-width="0.3" x="127.27272727272725" y="27.272727272727252" width="545.4545454545455" height="545.4545454545455" data-type="pcb_boundary" data-pcb-layer="global"/><path class="pcb-board" d="M 127.27272727272725 572.7272727272727 L 672.7272727272727 572.7272727272727 L 672.7272727272727 27.272727272727252 L 127.27272727272725 27.272727272727252 Z" fill="none" stroke="rgba(255, 255, 255, 0.5)" stroke-width="2.7272727272727275" data-type="pcb_board" data-pcb-layer="board"/><rect class="pcb-keepout pcb-keepout-rect pcb-keepout-background" data-type="pcb_keepout" data-pcb-layer="top" data-pcb-keepout-id="pcb_keepout_0" stroke="none" x="-43.63636363636364" y="-19.09090909090909" width="87.27272727272728" height="38.18181818181818" fill="rgba(255, 107, 107, 0.2)" transform="matrix(1,0,0,1,359.0909090909091,245.45454545454544)"/><rect class="pcb-keepout pcb-keepout-rect pcb-keepout-pattern" fill="url(#pcb-keepout-pattern)" data-type="pcb_keepout" data-pcb-layer="top" data-pcb-keepout-id="pcb_keepout_0" stroke="none" x="-43.63636363636364" y="-19.09090909090909" width="87.27272727272728" height="38.18181818181818" transform="matrix(1,0,0,1,359.0909090909091,245.45454545454544)"/><circle class="pcb-keepout pcb-keepout-circle pcb-keepout-background" data-type="pcb_keepout" data-pcb-layer="top" data-pcb-keepout-id="pcb_keepout_1" stroke="none" cx="468.1818181818182" cy="327.27272727272725" r="24.545454545454547" fill="rgba(255, 107, 107, 0.2)"/><circle class="pcb-keepout pcb-keepout-circle pcb-keepout-pattern" fill="url(#pcb-keepout-pattern)" data-type="pcb_keepout" data-pcb-layer="top" data-pcb-keepout-id="pcb_keepout_1" stroke="none" cx="468.1818181818182" cy="327.27272727272725" r="24.545454545454547"/><rect class="pcb-keepout pcb-keepout-rect pcb-keepout-background" data-type="pcb_keepout" data-pcb-layer="top" data-pcb-keepout-id="pcb_keepout_2" stroke="none" x="-43.63636363636364" y="-19.09090909090909" width="87.27272727272728" height="38.18181818181818" fill="rgba(255, 107, 107, 0.2)" transform="matrix(1,0,0,1,359.0909090909091,245.45454545454544)"/><rect class="pcb-keepout pcb-keepout-rect pcb-keepout-pattern" fill="url(#pcb-keepout-pattern)" data-type="pcb_keepout" data-pcb-layer="top" data-pcb-keepout-id="pcb_keepout_2" stroke="none" x="-43.63636363636364" y="-19.09090909090909" width="87.27272727272728" height="38.18181818181818" transform="matrix(1,0,0,1,359.0909090909091,245.45454545454544)"/><circle class="pcb-keepout pcb-keepout-circle pcb-keepout-background" data-type="pcb_keepout" data-pcb-layer="top" data-pcb-keepout-id="pcb_keepout_3" stroke="none" cx="468.1818181818182" cy="327.27272727272725" r="24.545454545454547" fill="rgba(255, 107, 107, 0.2)"/><circle class="pcb-keepout pcb-keepout-circle pcb-keepout-pattern" fill="url(#pcb-keepout-pattern)" data-type="pcb_keepout" data-pcb-layer="top" data-pcb-keepout-id="pcb_keepout_3" stroke="none" cx="468.1818181818182" cy="327.27272727272725" r="24.545454545454547"/></svg>
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { expect, test } from "bun:test"
|
|
2
|
+
import { convertCircuitJsonToPcbSvg } from "circuit-to-svg"
|
|
3
|
+
import type { AnyCircuitElement } from "circuit-json"
|
|
4
|
+
import { convertCircuitJsonToTscircuit } from "lib"
|
|
5
|
+
import { runTscircuitCode } from "tscircuit"
|
|
6
|
+
|
|
7
|
+
test("test17 support pcb keepouts", async () => {
|
|
8
|
+
const tscircuit = convertCircuitJsonToTscircuit(circuitJson, {
|
|
9
|
+
componentName: "Test17Component",
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
expect(tscircuit).toMatchInlineSnapshot(`
|
|
13
|
+
"import { type ChipProps } from "tscircuit"
|
|
14
|
+
export const Test17Component = (props: ChipProps) => (
|
|
15
|
+
<chip
|
|
16
|
+
footprint={<footprint>
|
|
17
|
+
<keepout shape="rect" pcbX="-1.5mm" pcbY="2mm" width="3.2mm" height="1.4mm" />
|
|
18
|
+
<keepout shape="circle" pcbX="2.5mm" pcbY="-1mm" radius="0.9mm" />
|
|
19
|
+
</footprint>}
|
|
20
|
+
{...props}
|
|
21
|
+
/>
|
|
22
|
+
)"
|
|
23
|
+
`)
|
|
24
|
+
|
|
25
|
+
const renderedCircuitJson = (await runTscircuitCode(`
|
|
26
|
+
${tscircuit}
|
|
27
|
+
|
|
28
|
+
circuit.add(
|
|
29
|
+
<board width="20mm" height="20mm">
|
|
30
|
+
<Test17Component />
|
|
31
|
+
</board>,
|
|
32
|
+
)
|
|
33
|
+
`)) as AnyCircuitElement[]
|
|
34
|
+
|
|
35
|
+
const renderedKeepouts = renderedCircuitJson.filter(
|
|
36
|
+
(elm) => elm.type === "pcb_keepout",
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
expect(renderedKeepouts.length).toBeGreaterThanOrEqual(2)
|
|
40
|
+
expect(renderedKeepouts).toEqual(
|
|
41
|
+
expect.arrayContaining([
|
|
42
|
+
expect.objectContaining({
|
|
43
|
+
type: "pcb_keepout",
|
|
44
|
+
layers: ["top"],
|
|
45
|
+
shape: "rect",
|
|
46
|
+
width: 3.2,
|
|
47
|
+
height: 1.4,
|
|
48
|
+
center: { x: -1.5, y: 2 },
|
|
49
|
+
}),
|
|
50
|
+
expect.objectContaining({
|
|
51
|
+
type: "pcb_keepout",
|
|
52
|
+
layers: ["top"],
|
|
53
|
+
shape: "circle",
|
|
54
|
+
radius: 0.9,
|
|
55
|
+
center: { x: 2.5, y: -1 },
|
|
56
|
+
}),
|
|
57
|
+
]),
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
const pcbSvg = convertCircuitJsonToPcbSvg(renderedCircuitJson)
|
|
61
|
+
await expect(pcbSvg).toMatchSvgSnapshot(import.meta.path, "pcb")
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
const circuitJson: AnyCircuitElement[] = [
|
|
65
|
+
{
|
|
66
|
+
type: "pcb_keepout",
|
|
67
|
+
pcb_keepout_id: "keepout_rect",
|
|
68
|
+
shape: "rect",
|
|
69
|
+
center: { x: -1.5, y: 2 },
|
|
70
|
+
width: 3.2,
|
|
71
|
+
height: 1.4,
|
|
72
|
+
layers: ["top"],
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
type: "pcb_keepout",
|
|
76
|
+
pcb_keepout_id: "keepout_circle",
|
|
77
|
+
shape: "circle",
|
|
78
|
+
center: { x: 2.5, y: -1 },
|
|
79
|
+
radius: 0.9,
|
|
80
|
+
layers: ["top"],
|
|
81
|
+
},
|
|
82
|
+
]
|