@tscircuit/checks 0.0.145 → 0.0.147

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 CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as circuit_json from 'circuit-json';
2
- import { AnyCircuitElement, PcbPortNotConnectedError, PcbTraceError, PcbPlacementError, PcbComponentOutsideBoardError, PcbViaClearanceError, PcbTraceWarning, PcbTraceMissingError, PcbFootprintOverlapError, PcbPadPadClearanceError, PcbPadTraceClearanceError, PcbViaTraceClearanceError, SourceComponentPinsUnderspecifiedWarning, SourceNoPowerPinDefinedWarning, SourceNoGroundPinDefinedWarning, PcbConnectorNotInAccessibleOrientationWarning } from 'circuit-json';
2
+ import { AnyCircuitElement, PcbPortNotConnectedError, PcbTraceError, PcbPlacementError, PcbComponentOutsideBoardError, PcbViaClearanceError, PcbTraceWarning, PcbTraceMissingError, PcbFootprintOverlapError, PcbTraceTooLongWarning, PcbPadPadClearanceError, PcbPadTraceClearanceError, PcbViaTraceClearanceError, SourceComponentPinsUnderspecifiedWarning, SourceNoPowerPinDefinedWarning, SourceNoGroundPinDefinedWarning, PcbConnectorNotInAccessibleOrientationWarning } from 'circuit-json';
3
3
  import { ConnectivityMap } from 'circuit-json-to-connectivity-map';
4
4
 
5
5
  declare function checkEachPcbPortConnectedToPcbTraces(circuitJson: AnyCircuitElement[]): PcbPortNotConnectedError[];
@@ -63,6 +63,8 @@ declare function checkPcbTracesOutOfBoard(circuitJson: AnyCircuitElement[], conf
63
63
  */
64
64
  declare function checkPcbComponentOverlap(circuitJson: AnyCircuitElement[]): PcbFootprintOverlapError[];
65
65
 
66
+ declare const checkPcbTraceLengths: (circuitJson: AnyCircuitElement[]) => PcbTraceTooLongWarning[];
67
+
66
68
  declare function checkPadPadClearance(circuitJson: AnyCircuitElement[], { connMap, minClearance, }?: {
67
69
  connMap?: ConnectivityMap;
68
70
  minClearance?: number;
@@ -137,8 +139,8 @@ declare function runAllNetlistChecks(circuitJson: AnyCircuitElement[]): Promise<
137
139
  subcircuit_id?: string;
138
140
  }[]>;
139
141
  declare function runAllPinSpecificationChecks(circuitJson: AnyCircuitElement[]): Promise<(circuit_json.SourceComponentPinsUnderspecifiedWarning | circuit_json.SourceNoPowerPinDefinedWarning | circuit_json.SourceNoGroundPinDefinedWarning)[]>;
140
- declare function runAllRoutingChecks(circuitJson: AnyCircuitElement[]): Promise<(circuit_json.PcbPortNotConnectedError | circuit_json.PcbTraceError | circuit_json.PcbViaClearanceError | circuit_json.PcbTraceMissingError | circuit_json.PcbPadTraceClearanceError | circuit_json.PcbViaTraceClearanceError)[]>;
141
- declare function runAllChecks(circuitJson: AnyCircuitElement[]): Promise<(circuit_json.PcbPortNotConnectedError | circuit_json.PcbTraceError | circuit_json.PcbPlacementError | circuit_json.PcbComponentOutsideBoardError | circuit_json.PcbViaClearanceError | circuit_json.PcbTraceMissingError | circuit_json.PcbFootprintOverlapError | circuit_json.PcbPadPadClearanceError | circuit_json.PcbPadTraceClearanceError | circuit_json.PcbViaTraceClearanceError | {
142
+ declare function runAllRoutingChecks(circuitJson: AnyCircuitElement[]): Promise<(circuit_json.PcbPortNotConnectedError | circuit_json.PcbTraceError | circuit_json.PcbViaClearanceError | circuit_json.PcbTraceMissingError | circuit_json.PcbTraceTooLongWarning | circuit_json.PcbPadTraceClearanceError | circuit_json.PcbViaTraceClearanceError)[]>;
143
+ declare function runAllChecks(circuitJson: AnyCircuitElement[]): Promise<(circuit_json.PcbPortNotConnectedError | circuit_json.PcbTraceError | circuit_json.PcbPlacementError | circuit_json.PcbComponentOutsideBoardError | circuit_json.PcbViaClearanceError | circuit_json.PcbTraceMissingError | circuit_json.PcbFootprintOverlapError | circuit_json.PcbTraceTooLongWarning | circuit_json.PcbPadPadClearanceError | circuit_json.PcbPadTraceClearanceError | circuit_json.PcbViaTraceClearanceError | {
142
144
  type: "source_pin_must_be_connected_error";
143
145
  source_pin_must_be_connected_error_id: string;
144
146
  error_type: "source_pin_must_be_connected_error";
@@ -150,4 +152,4 @@ declare function runAllChecks(circuitJson: AnyCircuitElement[]): Promise<(circui
150
152
 
151
153
  declare function checkConnectorAccessibleOrientation(circuitJson: AnyCircuitElement[]): PcbConnectorNotInAccessibleOrientationWarning[];
152
154
 
153
- export { NetManager, checkAllPinsInComponentAreUnderspecified, checkConnectorAccessibleOrientation, checkDifferentNetViaSpacing, checkEachPcbPortConnectedToPcbTraces, checkEachPcbTraceNonOverlapping, checkNoGroundPinDefined, checkNoPowerPinDefined, checkPadPadClearance, checkPadTraceClearance, checkPcbComponentOverlap, checkPcbComponentsOutOfBoard, checkPcbTracesOutOfBoard, checkPinMustBeConnected, checkSameNetViaSpacing, checkSourceTracesHavePcbTraces, checkSourceTracesMatchPcbTraceThickness, checkTracesAreContiguous, checkViaTraceClearance, checkViasOffBoard, dedupePcbDrcErrors, runAllChecks, runAllNetlistChecks, runAllPinSpecificationChecks, runAllPlacementChecks, runAllRoutingChecks };
155
+ export { NetManager, checkAllPinsInComponentAreUnderspecified, checkConnectorAccessibleOrientation, checkDifferentNetViaSpacing, checkEachPcbPortConnectedToPcbTraces, checkEachPcbTraceNonOverlapping, checkNoGroundPinDefined, checkNoPowerPinDefined, checkPadPadClearance, checkPadTraceClearance, checkPcbComponentOverlap, checkPcbComponentsOutOfBoard, checkPcbTraceLengths, checkPcbTracesOutOfBoard, checkPinMustBeConnected, checkSameNetViaSpacing, checkSourceTracesHavePcbTraces, checkSourceTracesMatchPcbTraceThickness, checkTracesAreContiguous, checkViaTraceClearance, checkViasOffBoard, dedupePcbDrcErrors, runAllChecks, runAllNetlistChecks, runAllPinSpecificationChecks, runAllPlacementChecks, runAllRoutingChecks };
package/dist/index.js CHANGED
@@ -1232,6 +1232,11 @@ var getRadiusOfCircuitJsonElement = (obj) => {
1232
1232
  };
1233
1233
 
1234
1234
  // lib/check-each-pcb-trace-non-overlapping/check-each-pcb-trace-non-overlapping.ts
1235
+ var getPcbComponentConnectionElementId = (element) => {
1236
+ if (element.type === "pcb_port") return element.pcb_port_id;
1237
+ if (element.type === "pcb_smtpad") return element.pcb_smtpad_id;
1238
+ return element.pcb_plated_hole_id;
1239
+ };
1235
1240
  function checkEachPcbTraceNonOverlapping(circuitJson, {
1236
1241
  connMap,
1237
1242
  minClearance
@@ -1266,9 +1271,28 @@ function checkEachPcbTraceNonOverlapping(circuitJson, {
1266
1271
  });
1267
1272
  const pcbSmtPads = cju2(circuitJson).pcb_smtpad.list();
1268
1273
  const pcbPlatedHoles = cju2(circuitJson).pcb_plated_hole.list();
1274
+ const pcbPorts = cju2(circuitJson).pcb_port.list();
1269
1275
  const pcbHoles = cju2(circuitJson).pcb_hole.list();
1270
1276
  const pcbVias = cju2(circuitJson).pcb_via.list();
1271
1277
  const pcbKeepouts = cju2(circuitJson).pcb_keepout.list();
1278
+ const pcbComponentConnectionElements = [
1279
+ ...pcbPorts,
1280
+ ...pcbSmtPads,
1281
+ ...pcbPlatedHoles
1282
+ ];
1283
+ const excludedConnectionIdsByKeepoutId = /* @__PURE__ */ new Map();
1284
+ for (const keepout of pcbKeepouts) {
1285
+ const excludedPcbComponentIds = new Set(
1286
+ keepout.excluded_pcb_component_ids ?? []
1287
+ );
1288
+ if (excludedPcbComponentIds.size === 0) continue;
1289
+ excludedConnectionIdsByKeepoutId.set(
1290
+ keepout.pcb_keepout_id,
1291
+ pcbComponentConnectionElements.filter(
1292
+ (element) => element.pcb_component_id && excludedPcbComponentIds.has(element.pcb_component_id)
1293
+ ).map(getPcbComponentConnectionElementId)
1294
+ );
1295
+ }
1272
1296
  const allObjects = [
1273
1297
  ...pcbTraceSegments,
1274
1298
  ...pcbSmtPads,
@@ -1301,6 +1325,11 @@ function checkEachPcbTraceNonOverlapping(circuitJson, {
1301
1325
  if (!getLayersOfPcbElement(obj).includes(segmentA.layer)) {
1302
1326
  continue;
1303
1327
  }
1328
+ if (obj.type === "pcb_keepout" && (excludedConnectionIdsByKeepoutId.get(obj.pcb_keepout_id) ?? []).some(
1329
+ (connectionId) => connMap.areIdsConnected(segmentA.pcb_trace_id, connectionId)
1330
+ )) {
1331
+ continue;
1332
+ }
1304
1333
  if (obj.type === "pcb_trace_segment") {
1305
1334
  const segmentB = obj;
1306
1335
  if (segmentA.layer !== segmentB.layer) continue;
@@ -2491,6 +2520,68 @@ function checkPcbComponentOverlap(circuitJson) {
2491
2520
  return errors;
2492
2521
  }
2493
2522
 
2523
+ // lib/check-pcb-trace-lengths.ts
2524
+ var DEFAULT_VIA_LENGTH_MM = 1.6;
2525
+ var getRoutePointPosition = (routePoint) => routePoint.route_type === "through_pad" ? routePoint.start : { x: routePoint.x, y: routePoint.y };
2526
+ var getPcbTraceLength = (pcbTrace) => {
2527
+ if (pcbTrace.trace_length !== void 0) return pcbTrace.trace_length;
2528
+ let traceLength = 0;
2529
+ for (let routePointIndex = 0; routePointIndex < pcbTrace.route.length; routePointIndex++) {
2530
+ const routePoint = pcbTrace.route[routePointIndex];
2531
+ if (!routePoint) continue;
2532
+ if (routePoint.route_type === "via") {
2533
+ traceLength += DEFAULT_VIA_LENGTH_MM;
2534
+ continue;
2535
+ }
2536
+ const nextRoutePoint = pcbTrace.route[routePointIndex + 1];
2537
+ if (!nextRoutePoint) continue;
2538
+ const routePointPosition = getRoutePointPosition(routePoint);
2539
+ const nextRoutePointPosition = getRoutePointPosition(nextRoutePoint);
2540
+ traceLength += Math.hypot(
2541
+ nextRoutePointPosition.x - routePointPosition.x,
2542
+ nextRoutePointPosition.y - routePointPosition.y
2543
+ );
2544
+ }
2545
+ return traceLength;
2546
+ };
2547
+ var checkPcbTraceLengths = (circuitJson) => {
2548
+ const sourceTraces = circuitJson.filter(
2549
+ (element) => element.type === "source_trace"
2550
+ );
2551
+ const pcbTraces = circuitJson.filter(
2552
+ (element) => element.type === "pcb_trace"
2553
+ );
2554
+ const sourceTracesById = new Map(
2555
+ sourceTraces.map((sourceTrace) => [
2556
+ sourceTrace.source_trace_id,
2557
+ sourceTrace
2558
+ ])
2559
+ );
2560
+ const warnings = [];
2561
+ for (const pcbTrace of pcbTraces) {
2562
+ if (!pcbTrace.source_trace_id) continue;
2563
+ const sourceTrace = sourceTracesById.get(pcbTrace.source_trace_id);
2564
+ if (!sourceTrace) continue;
2565
+ const maximumTraceLength = sourceTrace.max_length;
2566
+ if (typeof maximumTraceLength !== "number") continue;
2567
+ const actualTraceLength = getPcbTraceLength(pcbTrace);
2568
+ if (actualTraceLength <= maximumTraceLength) continue;
2569
+ warnings.push({
2570
+ type: "pcb_trace_too_long_warning",
2571
+ pcb_trace_too_long_warning_id: `pcb_trace_too_long_warning_${pcbTrace.pcb_trace_id}`,
2572
+ warning_type: "pcb_trace_too_long_warning",
2573
+ message: `PCB trace is ${actualTraceLength.toFixed(2)}mm long, exceeding the ${maximumTraceLength}mm maximum`,
2574
+ pcb_trace_id: pcbTrace.pcb_trace_id,
2575
+ source_trace_id: sourceTrace.source_trace_id,
2576
+ source_net_id: sourceTrace.connected_source_net_ids[0],
2577
+ actual_trace_length: actualTraceLength,
2578
+ maximum_trace_length: maximumTraceLength,
2579
+ subcircuit_id: pcbTrace.subcircuit_id ?? sourceTrace.subcircuit_id
2580
+ });
2581
+ }
2582
+ return warnings;
2583
+ };
2584
+
2494
2585
  // lib/check-pad-pad-clearance.ts
2495
2586
  import {
2496
2587
  getPrimaryId as getPrimaryId3,
@@ -3113,6 +3204,7 @@ async function runAllRoutingChecks(circuitJson) {
3113
3204
  return [
3114
3205
  ...checkEachPcbPortConnectedToPcbTraces(circuitJson),
3115
3206
  ...checkSourceTracesHavePcbTraces(circuitJson),
3207
+ ...checkPcbTraceLengths(circuitJson),
3116
3208
  ...checkEachPcbTraceNonOverlapping(circuitJson),
3117
3209
  ...checkPadTraceClearance(circuitJson),
3118
3210
  ...checkViaTraceClearance(circuitJson),
@@ -3143,6 +3235,7 @@ export {
3143
3235
  checkPadTraceClearance,
3144
3236
  checkPcbComponentOverlap,
3145
3237
  checkPcbComponentsOutOfBoard,
3238
+ checkPcbTraceLengths,
3146
3239
  checkPcbTracesOutOfBoard,
3147
3240
  checkPinMustBeConnected,
3148
3241
  checkSameNetViaSpacing,