circuit-json-to-kicad 0.0.25 → 0.0.27
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/index.d.ts +5 -1
- package/dist/index.js +181 -35
- package/package.json +2 -1
package/dist/index.d.ts
CHANGED
|
@@ -13,6 +13,10 @@ interface PaperDimensions {
|
|
|
13
13
|
type SchematicPortId = string;
|
|
14
14
|
type SchematicTraceId = string;
|
|
15
15
|
type PcbPortId = string;
|
|
16
|
+
interface PcbNetInfo {
|
|
17
|
+
id: number;
|
|
18
|
+
name: string;
|
|
19
|
+
}
|
|
16
20
|
interface ConverterContext {
|
|
17
21
|
db: CircuitJsonUtilObjects;
|
|
18
22
|
circuitJson: CircuitJson;
|
|
@@ -33,7 +37,7 @@ interface ConverterContext {
|
|
|
33
37
|
x: number;
|
|
34
38
|
y: number;
|
|
35
39
|
}>;
|
|
36
|
-
pcbNetMap?: Map<string,
|
|
40
|
+
pcbNetMap?: Map<string, PcbNetInfo>;
|
|
37
41
|
}
|
|
38
42
|
declare abstract class ConverterStage<Input, Output> {
|
|
39
43
|
MAX_ITERATIONS: number;
|
package/dist/index.js
CHANGED
|
@@ -1347,27 +1347,49 @@ var AddNetsStage = class extends ConverterStage {
|
|
|
1347
1347
|
if (!kicadPcb) {
|
|
1348
1348
|
throw new Error("KicadPcb instance not initialized in context");
|
|
1349
1349
|
}
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
const
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1350
|
+
this.ctx.pcbNetMap = /* @__PURE__ */ new Map();
|
|
1351
|
+
const netNameByKey = /* @__PURE__ */ new Map();
|
|
1352
|
+
const sourceNets = this.ctx.db.source_net?.list() ?? [];
|
|
1353
|
+
for (const sourceNet of sourceNets) {
|
|
1354
|
+
const connectivityKey = sourceNet.subcircuit_connectivity_map_key || sourceNet.source_net_id;
|
|
1355
|
+
if (!connectivityKey) continue;
|
|
1356
|
+
const candidateName = sourceNet.name || sourceNet.source_net_id || "";
|
|
1357
|
+
const netName = candidateName && candidateName.trim().length > 0 ? candidateName : connectivityKey;
|
|
1358
|
+
netNameByKey.set(connectivityKey, netName);
|
|
1359
|
+
}
|
|
1360
|
+
const sourceTraces = this.ctx.db.source_trace?.list() ?? [];
|
|
1361
|
+
for (const sourceTrace of sourceTraces) {
|
|
1362
|
+
let connectivityKey = sourceTrace.subcircuit_connectivity_map_key;
|
|
1363
|
+
if (!connectivityKey && sourceTrace.connected_source_net_ids?.length) {
|
|
1364
|
+
for (const sourceNetId of sourceTrace.connected_source_net_ids) {
|
|
1365
|
+
const connectedNet = this.ctx.db.source_net?.get(sourceNetId);
|
|
1366
|
+
if (connectedNet?.subcircuit_connectivity_map_key && connectedNet.subcircuit_connectivity_map_key.length > 0) {
|
|
1367
|
+
connectivityKey = connectedNet.subcircuit_connectivity_map_key;
|
|
1368
|
+
break;
|
|
1369
|
+
}
|
|
1370
|
+
}
|
|
1371
|
+
}
|
|
1372
|
+
if (!connectivityKey) continue;
|
|
1373
|
+
if (!netNameByKey.has(connectivityKey)) {
|
|
1374
|
+
const candidateName = sourceTrace.display_name || sourceTrace.source_trace_id || "";
|
|
1375
|
+
const netName = candidateName && candidateName.trim().length > 0 ? candidateName : connectivityKey;
|
|
1376
|
+
netNameByKey.set(connectivityKey, netName);
|
|
1360
1377
|
}
|
|
1361
1378
|
}
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1379
|
+
const sortedEntries = Array.from(netNameByKey.entries()).sort(
|
|
1380
|
+
(a, b) => a[0].localeCompare(b[0])
|
|
1381
|
+
);
|
|
1382
|
+
const nets = [];
|
|
1383
|
+
nets.push(new PcbNet(0, ""));
|
|
1384
|
+
let netNumber = 1;
|
|
1385
|
+
for (const [connectivityKey, netName] of sortedEntries) {
|
|
1386
|
+
const pcbNet = new PcbNet(netNumber, netName);
|
|
1387
|
+
nets.push(pcbNet);
|
|
1388
|
+
const netInfo = { id: netNumber, name: netName };
|
|
1389
|
+
this.ctx.pcbNetMap.set(connectivityKey, netInfo);
|
|
1369
1390
|
netNumber++;
|
|
1370
1391
|
}
|
|
1392
|
+
kicadPcb.nets = nets;
|
|
1371
1393
|
this.finished = true;
|
|
1372
1394
|
}
|
|
1373
1395
|
getOutput() {
|
|
@@ -1386,7 +1408,8 @@ import {
|
|
|
1386
1408
|
PadPrimitiveGrPoly,
|
|
1387
1409
|
Pts as Pts3,
|
|
1388
1410
|
Xy as Xy3,
|
|
1389
|
-
PadOptions
|
|
1411
|
+
PadOptions,
|
|
1412
|
+
PadNet
|
|
1390
1413
|
} from "kicadts";
|
|
1391
1414
|
import {
|
|
1392
1415
|
applyToPoint as applyToPoint5,
|
|
@@ -1395,11 +1418,39 @@ import {
|
|
|
1395
1418
|
scale as scale2,
|
|
1396
1419
|
rotate
|
|
1397
1420
|
} from "transformation-matrix";
|
|
1421
|
+
|
|
1422
|
+
// lib/pcb/stages/utils/generateDeterministicUuid.ts
|
|
1423
|
+
function simpleHash(str) {
|
|
1424
|
+
let hash = 0;
|
|
1425
|
+
for (let i = 0; i < str.length; i++) {
|
|
1426
|
+
const char = str.charCodeAt(i);
|
|
1427
|
+
hash = (hash << 5) - hash + char;
|
|
1428
|
+
hash = hash & hash;
|
|
1429
|
+
}
|
|
1430
|
+
let result = "";
|
|
1431
|
+
for (let i = 0; i < 4; i++) {
|
|
1432
|
+
let h = hash;
|
|
1433
|
+
for (let j = 0; j < str.length; j++) {
|
|
1434
|
+
h = (h << 5) - h + str.charCodeAt(j) + i * 31;
|
|
1435
|
+
h = h & h;
|
|
1436
|
+
}
|
|
1437
|
+
result += Math.abs(h).toString(16).padStart(8, "0");
|
|
1438
|
+
}
|
|
1439
|
+
return result;
|
|
1440
|
+
}
|
|
1441
|
+
function generateDeterministicUuid(data) {
|
|
1442
|
+
const hash = simpleHash(data);
|
|
1443
|
+
return `${hash.slice(0, 8)}-${hash.slice(8, 12)}-${hash.slice(12, 16)}-${hash.slice(16, 20)}-${hash.slice(20, 32)}`;
|
|
1444
|
+
}
|
|
1445
|
+
|
|
1446
|
+
// lib/pcb/stages/utils/CreateSmdPadFromCircuitJson.ts
|
|
1398
1447
|
function createSmdPadFromCircuitJson({
|
|
1399
1448
|
pcbPad,
|
|
1400
1449
|
componentCenter,
|
|
1401
1450
|
padNumber,
|
|
1402
|
-
componentRotation = 0
|
|
1451
|
+
componentRotation = 0,
|
|
1452
|
+
netInfo,
|
|
1453
|
+
componentId
|
|
1403
1454
|
}) {
|
|
1404
1455
|
let padX;
|
|
1405
1456
|
let padY;
|
|
@@ -1466,6 +1517,7 @@ function createSmdPadFromCircuitJson({
|
|
|
1466
1517
|
"height" in pcbPad ? pcbPad.height : 0.5
|
|
1467
1518
|
];
|
|
1468
1519
|
}
|
|
1520
|
+
const padData = `pad:${componentId}:${padNumber}:${rotatedPos.x},${rotatedPos.y}`;
|
|
1469
1521
|
const pad = new FootprintPad({
|
|
1470
1522
|
number: String(padNumber),
|
|
1471
1523
|
padType: "smd",
|
|
@@ -1477,7 +1529,7 @@ function createSmdPadFromCircuitJson({
|
|
|
1477
1529
|
`${padLayer === "F.Cu" ? "F" : "B"}.Paste`,
|
|
1478
1530
|
`${padLayer === "F.Cu" ? "F" : "B"}.Mask`
|
|
1479
1531
|
],
|
|
1480
|
-
uuid:
|
|
1532
|
+
uuid: generateDeterministicUuid(padData)
|
|
1481
1533
|
});
|
|
1482
1534
|
if (padOptions) {
|
|
1483
1535
|
pad.options = padOptions;
|
|
@@ -1485,17 +1537,22 @@ function createSmdPadFromCircuitJson({
|
|
|
1485
1537
|
if (padPrimitives) {
|
|
1486
1538
|
pad.primitives = padPrimitives;
|
|
1487
1539
|
}
|
|
1540
|
+
if (netInfo) {
|
|
1541
|
+
pad.net = new PadNet(netInfo.id, netInfo.name);
|
|
1542
|
+
}
|
|
1488
1543
|
return pad;
|
|
1489
1544
|
}
|
|
1490
1545
|
|
|
1491
1546
|
// lib/pcb/stages/utils/CreateThruHolePadFromCircuitJson.ts
|
|
1492
|
-
import { FootprintPad as FootprintPad2, PadDrill } from "kicadts";
|
|
1547
|
+
import { FootprintPad as FootprintPad2, PadDrill, PadNet as PadNet2 } from "kicadts";
|
|
1493
1548
|
import { applyToPoint as applyToPoint6, rotate as rotate2, identity } from "transformation-matrix";
|
|
1494
1549
|
function createThruHolePadFromCircuitJson({
|
|
1495
1550
|
platedHole,
|
|
1496
1551
|
componentCenter,
|
|
1497
1552
|
padNumber,
|
|
1498
|
-
componentRotation = 0
|
|
1553
|
+
componentRotation = 0,
|
|
1554
|
+
netInfo,
|
|
1555
|
+
componentId
|
|
1499
1556
|
}) {
|
|
1500
1557
|
if (!("x" in platedHole && "y" in platedHole)) {
|
|
1501
1558
|
return null;
|
|
@@ -1585,7 +1642,8 @@ function createThruHolePadFromCircuitJson({
|
|
|
1585
1642
|
padSize = [1.6, 1.6];
|
|
1586
1643
|
drill = new PadDrill({ diameter: 0.8, offset: drillOffset });
|
|
1587
1644
|
}
|
|
1588
|
-
|
|
1645
|
+
const padData = `thruhole:${componentId}:${padNumber}:${rotatedPos.x},${rotatedPos.y}`;
|
|
1646
|
+
const pad = new FootprintPad2({
|
|
1589
1647
|
number: String(padNumber),
|
|
1590
1648
|
padType: "thru_hole",
|
|
1591
1649
|
shape: padShape,
|
|
@@ -1594,8 +1652,12 @@ function createThruHolePadFromCircuitJson({
|
|
|
1594
1652
|
drill,
|
|
1595
1653
|
layers: ["*.Cu", "*.Mask"],
|
|
1596
1654
|
removeUnusedLayers: false,
|
|
1597
|
-
uuid:
|
|
1655
|
+
uuid: generateDeterministicUuid(padData)
|
|
1598
1656
|
});
|
|
1657
|
+
if (netInfo) {
|
|
1658
|
+
pad.net = new PadNet2(netInfo.id, netInfo.name);
|
|
1659
|
+
}
|
|
1660
|
+
return pad;
|
|
1599
1661
|
}
|
|
1600
1662
|
|
|
1601
1663
|
// lib/pcb/stages/utils/CreateNpthPadFromCircuitJson.ts
|
|
@@ -1707,6 +1769,18 @@ function createFpTextFromCircuitJson({
|
|
|
1707
1769
|
var AddFootprintsStage = class extends ConverterStage {
|
|
1708
1770
|
componentsProcessed = 0;
|
|
1709
1771
|
pcbComponents = [];
|
|
1772
|
+
getNetInfoForPcbPort(pcbPortId) {
|
|
1773
|
+
if (!pcbPortId) return void 0;
|
|
1774
|
+
const pcbPort = this.ctx.db.pcb_port?.get(pcbPortId);
|
|
1775
|
+
if (!pcbPort) return void 0;
|
|
1776
|
+
const sourcePortId = pcbPort.source_port_id;
|
|
1777
|
+
if (!sourcePortId) return void 0;
|
|
1778
|
+
const sourcePort = this.ctx.db.source_port?.get(sourcePortId);
|
|
1779
|
+
if (!sourcePort) return void 0;
|
|
1780
|
+
const connectivityKey = sourcePort.subcircuit_connectivity_map_key;
|
|
1781
|
+
if (!connectivityKey) return void 0;
|
|
1782
|
+
return this.ctx.pcbNetMap?.get(connectivityKey);
|
|
1783
|
+
}
|
|
1710
1784
|
constructor(input, ctx) {
|
|
1711
1785
|
super(input, ctx);
|
|
1712
1786
|
this.pcbComponents = this.ctx.db.pcb_component.list();
|
|
@@ -1730,11 +1804,12 @@ var AddFootprintsStage = class extends ConverterStage {
|
|
|
1730
1804
|
x: component.center.x,
|
|
1731
1805
|
y: component.center.y
|
|
1732
1806
|
});
|
|
1807
|
+
const footprintData = `footprint:${component.pcb_component_id}:${transformedPos.x},${transformedPos.y}`;
|
|
1733
1808
|
const footprint = new Footprint({
|
|
1734
1809
|
libraryLink: `tscircuit:${footprintName}`,
|
|
1735
1810
|
layer: "F.Cu",
|
|
1736
1811
|
at: [transformedPos.x, transformedPos.y, component.rotation || 0],
|
|
1737
|
-
uuid:
|
|
1812
|
+
uuid: generateDeterministicUuid(footprintData)
|
|
1738
1813
|
});
|
|
1739
1814
|
const fpTexts = footprint.fpTexts;
|
|
1740
1815
|
const pcbSilkscreenTexts = this.ctx.db.pcb_silkscreen_text?.list().filter(
|
|
@@ -1757,11 +1832,14 @@ var AddFootprintsStage = class extends ConverterStage {
|
|
|
1757
1832
|
const fpPads = footprint.fpPads;
|
|
1758
1833
|
let padNumber = 1;
|
|
1759
1834
|
for (const pcbPad of pcbPads) {
|
|
1835
|
+
const netInfo = this.getNetInfoForPcbPort(pcbPad.pcb_port_id);
|
|
1760
1836
|
const pad = createSmdPadFromCircuitJson({
|
|
1761
1837
|
pcbPad,
|
|
1762
1838
|
componentCenter: component.center,
|
|
1763
1839
|
padNumber,
|
|
1764
|
-
componentRotation: component.rotation || 0
|
|
1840
|
+
componentRotation: component.rotation || 0,
|
|
1841
|
+
netInfo,
|
|
1842
|
+
componentId: component.pcb_component_id
|
|
1765
1843
|
});
|
|
1766
1844
|
fpPads.push(pad);
|
|
1767
1845
|
padNumber++;
|
|
@@ -1770,11 +1848,14 @@ var AddFootprintsStage = class extends ConverterStage {
|
|
|
1770
1848
|
(hole) => hole.pcb_component_id === component.pcb_component_id
|
|
1771
1849
|
) || [];
|
|
1772
1850
|
for (const platedHole of pcbPlatedHoles) {
|
|
1851
|
+
const netInfo = this.getNetInfoForPcbPort(platedHole.pcb_port_id);
|
|
1773
1852
|
const pad = createThruHolePadFromCircuitJson({
|
|
1774
1853
|
platedHole,
|
|
1775
1854
|
componentCenter: component.center,
|
|
1776
1855
|
padNumber,
|
|
1777
|
-
componentRotation: component.rotation || 0
|
|
1856
|
+
componentRotation: component.rotation || 0,
|
|
1857
|
+
netInfo,
|
|
1858
|
+
componentId: component.pcb_component_id
|
|
1778
1859
|
});
|
|
1779
1860
|
if (pad) {
|
|
1780
1861
|
fpPads.push(pad);
|
|
@@ -1843,22 +1924,49 @@ var AddTracesStage = class extends ConverterStage {
|
|
|
1843
1924
|
x: endPoint.x,
|
|
1844
1925
|
y: endPoint.y
|
|
1845
1926
|
});
|
|
1846
|
-
let
|
|
1927
|
+
let netInfo;
|
|
1847
1928
|
if (pcbNetMap) {
|
|
1848
|
-
|
|
1849
|
-
|
|
1929
|
+
let connectivityKey = trace.subcircuit_connectivity_map_key;
|
|
1930
|
+
if (!connectivityKey && trace.source_trace_id) {
|
|
1931
|
+
const sourceTrace = this.ctx.db.source_trace?.get(
|
|
1932
|
+
trace.source_trace_id
|
|
1933
|
+
);
|
|
1934
|
+
if (sourceTrace) {
|
|
1935
|
+
connectivityKey = sourceTrace.subcircuit_connectivity_map_key;
|
|
1936
|
+
if (!connectivityKey && sourceTrace.connected_source_net_ids?.length) {
|
|
1937
|
+
for (const sourceNetId of sourceTrace.connected_source_net_ids) {
|
|
1938
|
+
const sourceNet = this.ctx.db.source_net?.get(sourceNetId);
|
|
1939
|
+
if (sourceNet?.subcircuit_connectivity_map_key) {
|
|
1940
|
+
connectivityKey = sourceNet.subcircuit_connectivity_map_key;
|
|
1941
|
+
break;
|
|
1942
|
+
}
|
|
1943
|
+
}
|
|
1944
|
+
}
|
|
1945
|
+
}
|
|
1946
|
+
}
|
|
1947
|
+
if (!connectivityKey && typeof trace.connection_name === "string") {
|
|
1948
|
+
const sourceNet = this.ctx.db.source_net?.get(trace.connection_name);
|
|
1949
|
+
if (sourceNet?.subcircuit_connectivity_map_key) {
|
|
1950
|
+
connectivityKey = sourceNet.subcircuit_connectivity_map_key;
|
|
1951
|
+
}
|
|
1952
|
+
}
|
|
1953
|
+
if (connectivityKey) {
|
|
1954
|
+
netInfo = pcbNetMap.get(connectivityKey);
|
|
1955
|
+
}
|
|
1850
1956
|
}
|
|
1851
1957
|
const layerMap = {
|
|
1852
1958
|
top: "F.Cu",
|
|
1853
1959
|
bottom: "B.Cu"
|
|
1854
1960
|
};
|
|
1855
1961
|
const kicadLayer = layerMap[startPoint.layer] || startPoint.layer || "F.Cu";
|
|
1962
|
+
const segmentData = `segment:${transformedStart.x},${transformedStart.y}:${transformedEnd.x},${transformedEnd.y}:${kicadLayer}:${netInfo?.id ?? 0}`;
|
|
1856
1963
|
const segment = new Segment({
|
|
1857
1964
|
start: { x: transformedStart.x, y: transformedStart.y },
|
|
1858
1965
|
end: { x: transformedEnd.x, y: transformedEnd.y },
|
|
1859
1966
|
layer: kicadLayer,
|
|
1860
1967
|
width: trace.width || 0.25,
|
|
1861
|
-
net: new SegmentNet(
|
|
1968
|
+
net: new SegmentNet(netInfo?.id ?? 0),
|
|
1969
|
+
uuid: generateDeterministicUuid(segmentData)
|
|
1862
1970
|
});
|
|
1863
1971
|
const segments = kicadPcb.segments;
|
|
1864
1972
|
segments.push(segment);
|
|
@@ -1898,16 +2006,54 @@ var AddViasStage = class extends ConverterStage {
|
|
|
1898
2006
|
x: via.x,
|
|
1899
2007
|
y: via.y
|
|
1900
2008
|
});
|
|
1901
|
-
let
|
|
1902
|
-
if (pcbNetMap
|
|
1903
|
-
|
|
2009
|
+
let netInfo;
|
|
2010
|
+
if (pcbNetMap) {
|
|
2011
|
+
let connectivityKey = via.subcircuit_connectivity_map_key;
|
|
2012
|
+
if (!connectivityKey && via.pcb_trace_id) {
|
|
2013
|
+
const pcbTrace = this.ctx.db.pcb_trace?.get(via.pcb_trace_id);
|
|
2014
|
+
if (pcbTrace) {
|
|
2015
|
+
if ("subcircuit_connectivity_map_key" in pcbTrace) {
|
|
2016
|
+
connectivityKey = pcbTrace.subcircuit_connectivity_map_key;
|
|
2017
|
+
}
|
|
2018
|
+
if (!connectivityKey && pcbTrace.source_trace_id) {
|
|
2019
|
+
const sourceTrace = this.ctx.db.source_trace?.get(
|
|
2020
|
+
pcbTrace.source_trace_id
|
|
2021
|
+
);
|
|
2022
|
+
if (sourceTrace) {
|
|
2023
|
+
if ("subcircuit_connectivity_map_key" in sourceTrace) {
|
|
2024
|
+
connectivityKey = sourceTrace.subcircuit_connectivity_map_key;
|
|
2025
|
+
}
|
|
2026
|
+
if (!connectivityKey && sourceTrace.connected_source_net_ids?.length) {
|
|
2027
|
+
for (const sourceNetId of sourceTrace.connected_source_net_ids) {
|
|
2028
|
+
const sourceNet = this.ctx.db.source_net?.get(sourceNetId);
|
|
2029
|
+
if (sourceNet?.subcircuit_connectivity_map_key) {
|
|
2030
|
+
connectivityKey = sourceNet.subcircuit_connectivity_map_key;
|
|
2031
|
+
break;
|
|
2032
|
+
}
|
|
2033
|
+
}
|
|
2034
|
+
}
|
|
2035
|
+
}
|
|
2036
|
+
}
|
|
2037
|
+
}
|
|
2038
|
+
}
|
|
2039
|
+
if (!connectivityKey && via.connection_name) {
|
|
2040
|
+
const sourceNet = this.ctx.db.source_net?.get(via.connection_name);
|
|
2041
|
+
if (sourceNet?.subcircuit_connectivity_map_key) {
|
|
2042
|
+
connectivityKey = sourceNet.subcircuit_connectivity_map_key;
|
|
2043
|
+
}
|
|
2044
|
+
}
|
|
2045
|
+
if (connectivityKey) {
|
|
2046
|
+
netInfo = pcbNetMap.get(connectivityKey);
|
|
2047
|
+
}
|
|
1904
2048
|
}
|
|
2049
|
+
const viaData = `via:${transformedPos.x},${transformedPos.y}:${via.outer_diameter || 0.8}:${via.hole_diameter || 0.4}:${netInfo?.id ?? 0}`;
|
|
1905
2050
|
const kicadVia = new Via({
|
|
1906
2051
|
at: [transformedPos.x, transformedPos.y],
|
|
1907
2052
|
size: via.outer_diameter || 0.8,
|
|
1908
2053
|
drill: via.hole_diameter || 0.4,
|
|
1909
2054
|
layers: ["F.Cu", "B.Cu"],
|
|
1910
|
-
net: new ViaNet(
|
|
2055
|
+
net: new ViaNet(netInfo?.id ?? 0),
|
|
2056
|
+
uuid: generateDeterministicUuid(viaData)
|
|
1911
2057
|
});
|
|
1912
2058
|
const vias = kicadPcb.vias;
|
|
1913
2059
|
vias.push(kicadVia);
|
package/package.json
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "circuit-json-to-kicad",
|
|
3
3
|
"main": "dist/index.js",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.27",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
7
7
|
"dist"
|
|
8
8
|
],
|
|
9
9
|
"scripts": {
|
|
10
10
|
"build": "tsup-node lib/index.ts --format esm --dts",
|
|
11
|
+
"build:site": "bun build ./site/index.html --outdir site-build",
|
|
11
12
|
"download-demos": "git clone --depth 1 --filter=blob:none --sparse https://gitlab.com/kicad/code/kicad.git kicad-demos && cd kicad-demos && git sparse-checkout set demos",
|
|
12
13
|
"typecheck": "bunx tsc --noEmit",
|
|
13
14
|
"format": "biome format --write .",
|