@tscircuit/checks 0.0.182 → 0.0.184

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/README.md CHANGED
@@ -153,3 +153,10 @@ export const pcb_trace_error = z
153
153
  export type PCBTraceErrorInput = z.input<typeof pcb_trace_error>
154
154
  export type PCBTraceError = z.infer<typeof pcb_trace_error>
155
155
  ```
156
+
157
+
158
+ ### checkSameNameNetsAreConnected
159
+
160
+ Checks whether source nets with exactly the same nonblank name belong to one electrical network, including across subcircuits. Returns one `source_confusing_net_name_warning` per ambiguous name with the affected `source_net_ids`. Connectivity follows source traces, shared ports, and both forms of internal component pin connections; a shared name or scoped connectivity key alone does not connect nets.
161
+
162
+ Included in `runAllNetlistChecks` and `runAllChecks`. This checks logical source connectivity; PCB routing continuity remains a separate check.
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, PcbComponentMissingCourtyardWarning, PcbTraceTooLongWarning, PcbPadPadClearanceError, PcbPadTraceClearanceError, PcbViaTraceClearanceError, SourceComponentPinsUnderspecifiedWarning, SourceNoPowerPinDefinedWarning, SourceNoGroundPinDefinedWarning, SchematicComponentStylingWarning, PcbConnectorNotInAccessibleOrientationWarning } from 'circuit-json';
2
+ import { AnyCircuitElement, PcbPortNotConnectedError, PcbTraceError, PcbPlacementError, PcbComponentOutsideBoardError, PcbViaClearanceError, PcbTraceWarning, PcbTraceMissingError, PcbFootprintOverlapError, PcbComponentMissingCourtyardWarning, PcbTraceTooLongWarning, PcbPadPadClearanceError, PcbPadTraceClearanceError, PcbViaTraceClearanceError, SourceComponentMisconfiguredError, SourceComponentPinsUnderspecifiedWarning, SourceNoPowerPinDefinedWarning, SourceNoGroundPinDefinedWarning, SchematicComponentStylingWarning, PcbConnectorNotInAccessibleOrientationWarning, SourceConfusingNetNameWarning } from 'circuit-json';
3
3
  import { ConnectivityMap } from 'circuit-json-to-connectivity-map';
4
4
 
5
5
  declare function checkEachPcbPortConnectedToPcbTraces(circuitJson: AnyCircuitElement[]): PcbPortNotConnectedError[];
@@ -142,6 +142,8 @@ type SourcePinMustBeConnectedError = {
142
142
  */
143
143
  declare function checkPinMustBeConnected(circuitJson: AnyCircuitElement[]): SourcePinMustBeConnectedError[];
144
144
 
145
+ declare function checkTwoTerminalSwitchContactsOnDifferentNets(circuitJson: AnyCircuitElement[]): SourceComponentMisconfiguredError[];
146
+
145
147
  /**
146
148
  * Check that each component with ports has at least one pin attribute
147
149
  * specified across its ports. Returns a warning when all pins are
@@ -182,7 +184,7 @@ declare function checkSchematicComponentMissingReferenceDesignatorText(circuitJs
182
184
  declare function checkSchematicComponentPortsOutsideBody(circuitJson: AnyCircuitElement[]): SchematicComponentStylingWarning[];
183
185
 
184
186
  declare function runAllPlacementChecks(circuitJson: AnyCircuitElement[]): Promise<(circuit_json.PcbPlacementError | circuit_json.PcbComponentOutsideBoardError | circuit_json.PcbFootprintOverlapError | circuit_json.PcbComponentMissingCourtyardWarning | circuit_json.PcbPadPadClearanceError | circuit_json.PcbConnectorNotInAccessibleOrientationWarning | circuit_json.PcbCourtyardOverlapError)[]>;
185
- declare function runAllNetlistChecks(circuitJson: AnyCircuitElement[]): Promise<{
187
+ declare function runAllNetlistChecks(circuitJson: AnyCircuitElement[]): Promise<({
186
188
  type: "source_pin_must_be_connected_error";
187
189
  source_pin_must_be_connected_error_id: string;
188
190
  error_type: "source_pin_must_be_connected_error";
@@ -190,7 +192,7 @@ declare function runAllNetlistChecks(circuitJson: AnyCircuitElement[]): Promise<
190
192
  source_component_id: string;
191
193
  source_port_id: string;
192
194
  subcircuit_id?: string;
193
- }[]>;
195
+ } | circuit_json.SourceComponentMisconfiguredError | circuit_json.SourceConfusingNetNameWarning)[]>;
194
196
  declare function runAllSchematicChecks(circuitJson: AnyCircuitElement[]): Promise<circuit_json.SchematicComponentStylingWarning[]>;
195
197
  declare function runAllPinSpecificationChecks(circuitJson: AnyCircuitElement[]): Promise<(circuit_json.SourceComponentPinsUnderspecifiedWarning | circuit_json.SourceNoPowerPinDefinedWarning | circuit_json.SourceNoGroundPinDefinedWarning)[]>;
196
198
  declare function runAllRoutingChecks(circuitJson: AnyCircuitElement[]): Promise<(circuit_json.PcbPortNotConnectedError | circuit_json.PcbTraceError | circuit_json.PcbViaClearanceError | circuit_json.PcbTraceMissingError | circuit_json.PcbTraceTooLongWarning | circuit_json.PcbPadPadClearanceError | circuit_json.PcbPadTraceClearanceError | circuit_json.PcbViaTraceClearanceError)[]>;
@@ -202,7 +204,7 @@ declare function runAllChecks(circuitJson: AnyCircuitElement[]): Promise<(circui
202
204
  source_component_id: string;
203
205
  source_port_id: string;
204
206
  subcircuit_id?: string;
205
- } | circuit_json.SourceComponentPinsUnderspecifiedWarning | circuit_json.SourceNoPowerPinDefinedWarning | circuit_json.SourceNoGroundPinDefinedWarning | circuit_json.SchematicComponentStylingWarning | circuit_json.PcbConnectorNotInAccessibleOrientationWarning | circuit_json.PcbCourtyardOverlapError)[]>;
207
+ } | circuit_json.SourceComponentMisconfiguredError | circuit_json.SourceComponentPinsUnderspecifiedWarning | circuit_json.SourceNoPowerPinDefinedWarning | circuit_json.SourceNoGroundPinDefinedWarning | circuit_json.SchematicComponentStylingWarning | circuit_json.SourceConfusingNetNameWarning | circuit_json.PcbConnectorNotInAccessibleOrientationWarning | circuit_json.PcbCourtyardOverlapError)[]>;
206
208
 
207
209
  declare function checkConnectorAccessibleOrientation(circuitJson: AnyCircuitElement[]): PcbConnectorNotInAccessibleOrientationWarning[];
208
210
 
@@ -213,4 +215,7 @@ declare function checkConnectorAccessibleOrientation(circuitJson: AnyCircuitElem
213
215
  */
214
216
  declare function checkTestPointAccessibility(circuitJson: AnyCircuitElement[]): PcbPlacementError[];
215
217
 
216
- export { NetManager, checkAllPinsInComponentAreUnderspecified, checkConnectorAccessibleOrientation, checkCopperToBoardEdgeClearance, checkDifferentNetViaSpacing, checkEachPcbPortConnectedToPcbTraces, checkEachPcbTraceNonOverlapping, checkNoGroundPinDefined, checkNoPowerPinDefined, checkPadPadClearance, checkPadTraceClearance, checkPcbComponentOverCutout, checkPcbComponentOverlap, checkPcbComponentsMissingCourtyard, checkPcbComponentsOutOfBoard, checkPcbCopperOverKeepout, checkPcbTraceLengths, checkPcbTraceViaCounts, checkPcbTracesOutOfBoard, checkPinMustBeConnected, checkSameNetViaSpacing, checkSchematicComponentExcessiveVerticalPadding, checkSchematicComponentMissingReferenceDesignatorText, checkSchematicComponentPortsOutsideBody, checkSourceTracesHavePcbTraces, checkSourceTracesMatchPcbTraceThickness, checkTestPointAccessibility, checkTracesAreContiguous, checkViaPadClearance, checkViaTraceClearance, checkViasInPads, checkViasOffBoard, dedupePcbDrcErrors, runAllChecks, runAllNetlistChecks, runAllPinSpecificationChecks, runAllPlacementChecks, runAllRoutingChecks, runAllSchematicChecks };
218
+ /** Warn once per name when its source nets belong to multiple electrical islands. */
219
+ declare function checkSameNameNetsAreConnected(circuitJson: AnyCircuitElement[]): SourceConfusingNetNameWarning[];
220
+
221
+ export { NetManager, checkAllPinsInComponentAreUnderspecified, checkConnectorAccessibleOrientation, checkCopperToBoardEdgeClearance, checkDifferentNetViaSpacing, checkEachPcbPortConnectedToPcbTraces, checkEachPcbTraceNonOverlapping, checkNoGroundPinDefined, checkNoPowerPinDefined, checkPadPadClearance, checkPadTraceClearance, checkPcbComponentOverCutout, checkPcbComponentOverlap, checkPcbComponentsMissingCourtyard, checkPcbComponentsOutOfBoard, checkPcbCopperOverKeepout, checkPcbTraceLengths, checkPcbTraceViaCounts, checkPcbTracesOutOfBoard, checkPinMustBeConnected, checkSameNameNetsAreConnected, checkSameNetViaSpacing, checkSchematicComponentExcessiveVerticalPadding, checkSchematicComponentMissingReferenceDesignatorText, checkSchematicComponentPortsOutsideBody, checkSourceTracesHavePcbTraces, checkSourceTracesMatchPcbTraceThickness, checkTestPointAccessibility, checkTracesAreContiguous, checkTwoTerminalSwitchContactsOnDifferentNets, checkViaPadClearance, checkViaTraceClearance, checkViasInPads, checkViasOffBoard, dedupePcbDrcErrors, runAllChecks, runAllNetlistChecks, runAllPinSpecificationChecks, runAllPlacementChecks, runAllRoutingChecks, runAllSchematicChecks };
package/dist/index.js CHANGED
@@ -3914,6 +3914,51 @@ function checkPinMustBeConnected(circuitJson) {
3914
3914
  return errors;
3915
3915
  }
3916
3916
 
3917
+ // lib/check-two-terminal-switch-contacts-on-different-nets.ts
3918
+ import {
3919
+ source_component_misconfigured_error
3920
+ } from "circuit-json";
3921
+ function checkTwoTerminalSwitchContactsOnDifferentNets(circuitJson) {
3922
+ const switchingComponents = circuitJson.filter(
3923
+ (element) => element.type === "source_component" && (element.ftype === "simple_push_button" || element.ftype === "simple_switch")
3924
+ );
3925
+ const sourcePorts = circuitJson.filter(
3926
+ (element) => element.type === "source_port"
3927
+ );
3928
+ const schematicPorts = circuitJson.filter(
3929
+ (element) => element.type === "schematic_port"
3930
+ );
3931
+ const errors = [];
3932
+ for (const switchingComponent of switchingComponents) {
3933
+ const schematicContactSourcePorts = schematicPorts.flatMap(
3934
+ (schematicPort) => {
3935
+ const sourcePort = sourcePorts.find(
3936
+ (sourcePort2) => sourcePort2.source_port_id === schematicPort.source_port_id && sourcePort2.source_component_id === switchingComponent.source_component_id
3937
+ );
3938
+ if (!sourcePort) return [];
3939
+ return [sourcePort];
3940
+ }
3941
+ );
3942
+ if (schematicContactSourcePorts.length !== 2) continue;
3943
+ const firstContactConnectivityKey = schematicContactSourcePorts[0].subcircuit_connectivity_map_key;
3944
+ const secondContactConnectivityKey = schematicContactSourcePorts[1].subcircuit_connectivity_map_key;
3945
+ if (!firstContactConnectivityKey) continue;
3946
+ if (firstContactConnectivityKey !== secondContactConnectivityKey) continue;
3947
+ errors.push(
3948
+ source_component_misconfigured_error.parse({
3949
+ type: "source_component_misconfigured_error",
3950
+ message: `Switch ${switchingComponent.name} has both schematic contacts connected to the same net. Check internallyConnectedPins and the footprint pin mapping.`,
3951
+ source_component_ids: [switchingComponent.source_component_id],
3952
+ source_port_ids: schematicContactSourcePorts.map(
3953
+ (sourcePort) => sourcePort.source_port_id
3954
+ ),
3955
+ is_fatal: true
3956
+ })
3957
+ );
3958
+ }
3959
+ return errors;
3960
+ }
3961
+
3917
3962
  // lib/check-all-pins-in-component-are-underspecified.ts
3918
3963
  import { cju as cju7 } from "@tscircuit/circuit-json-util";
3919
3964
  var PIN_ATTRIBUTE_KEYS = [
@@ -4314,6 +4359,66 @@ function checkSchematicComponentPortsOutsideBody(circuitJson) {
4314
4359
  return warnings;
4315
4360
  }
4316
4361
 
4362
+ // lib/check-same-name-nets-are-connected.ts
4363
+ function checkSameNameNetsAreConnected(circuitJson) {
4364
+ const parents = /* @__PURE__ */ new Map();
4365
+ const find = (id) => {
4366
+ let root = id;
4367
+ while (parents.has(root) && parents.get(root) !== root) {
4368
+ root = parents.get(root);
4369
+ }
4370
+ while (parents.has(id) && parents.get(id) !== root) {
4371
+ const next = parents.get(id);
4372
+ parents.set(id, root);
4373
+ id = next;
4374
+ }
4375
+ return root;
4376
+ };
4377
+ const connect = (ids) => {
4378
+ if (ids.length < 2) return;
4379
+ const root = find(ids[0]);
4380
+ for (const id of ids.slice(1)) parents.set(find(id), root);
4381
+ };
4382
+ const netsByName = /* @__PURE__ */ new Map();
4383
+ for (const element of circuitJson) {
4384
+ if (element.type === "source_net" && element.name.trim()) {
4385
+ const nets = netsByName.get(element.name) ?? [];
4386
+ nets.push(element);
4387
+ netsByName.set(element.name, nets);
4388
+ }
4389
+ if (element.type === "source_trace") {
4390
+ connect([
4391
+ ...element.connected_source_net_ids.map((id) => `net:${id}`),
4392
+ ...element.connected_source_port_ids.map((id) => `port:${id}`)
4393
+ ]);
4394
+ }
4395
+ if (element.type === "source_component_internal_connection") {
4396
+ connect(element.source_port_ids.map((id) => `port:${id}`));
4397
+ }
4398
+ if (element.type === "source_component") {
4399
+ for (const ids of element.internally_connected_source_port_ids ?? []) {
4400
+ connect(ids.map((id) => `port:${id}`));
4401
+ }
4402
+ }
4403
+ }
4404
+ const warnings = [];
4405
+ for (const [name, nets] of netsByName) {
4406
+ const islands = new Set(nets.map((net) => find(`net:${net.source_net_id}`)));
4407
+ if (islands.size < 2) continue;
4408
+ const ids = nets.map((net) => net.source_net_id).sort();
4409
+ warnings.push({
4410
+ type: "source_confusing_net_name_warning",
4411
+ source_confusing_net_name_warning_id: `source_confusing_net_name_warning_${ids[0]}`,
4412
+ warning_type: "source_confusing_net_name_warning",
4413
+ message: `Nets named "${name}" are not all connected (${islands.size} separate electrical networks). Connect them or use distinct names to avoid confusion.`,
4414
+ source_net_ids: ids,
4415
+ net_name: name,
4416
+ ...nets.every((net) => net.subcircuit_id === nets[0].subcircuit_id) ? { subcircuit_id: nets[0].subcircuit_id } : {}
4417
+ });
4418
+ }
4419
+ return warnings;
4420
+ }
4421
+
4317
4422
  // lib/check-connector-accessible-orientation.ts
4318
4423
  import { getBoardBounds } from "@tscircuit/circuit-json-util";
4319
4424
  function getFacingDirectionFromInsertionDirection(component) {
@@ -4598,7 +4703,11 @@ async function runAllPlacementChecks(circuitJson) {
4598
4703
  ];
4599
4704
  }
4600
4705
  async function runAllNetlistChecks(circuitJson) {
4601
- return [...checkPinMustBeConnected(circuitJson)];
4706
+ return [
4707
+ ...checkPinMustBeConnected(circuitJson),
4708
+ ...checkSameNameNetsAreConnected(circuitJson),
4709
+ ...checkTwoTerminalSwitchContactsOnDifferentNets(circuitJson)
4710
+ ];
4602
4711
  }
4603
4712
  async function runAllSchematicChecks(circuitJson) {
4604
4713
  return [
@@ -4660,6 +4769,7 @@ export {
4660
4769
  checkPcbTraceViaCounts,
4661
4770
  checkPcbTracesOutOfBoard,
4662
4771
  checkPinMustBeConnected,
4772
+ checkSameNameNetsAreConnected,
4663
4773
  checkSameNetViaSpacing,
4664
4774
  checkSchematicComponentExcessiveVerticalPadding,
4665
4775
  checkSchematicComponentMissingReferenceDesignatorText,
@@ -4668,6 +4778,7 @@ export {
4668
4778
  checkSourceTracesMatchPcbTraceThickness,
4669
4779
  checkTestPointAccessibility,
4670
4780
  checkTracesAreContiguous,
4781
+ checkTwoTerminalSwitchContactsOnDifferentNets,
4671
4782
  checkViaPadClearance,
4672
4783
  checkViaTraceClearance,
4673
4784
  checkViasInPads,