kicadts 0.0.1 → 0.0.2

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.
Files changed (78) hide show
  1. package/.github/workflows/bun-formatcheck.yml +26 -0
  2. package/.github/workflows/bun-pver-release.yml +70 -0
  3. package/.github/workflows/bun-test.yml +32 -0
  4. package/.github/workflows/bun-typecheck.yml +26 -0
  5. package/.vscode/settings.json +1 -1
  6. package/AGENTS.md +1 -0
  7. package/LICENSE +21 -0
  8. package/README.md +101 -91
  9. package/TODO.md +46 -0
  10. package/bunfig.toml +2 -2
  11. package/lib/sexpr/classes/At.ts +15 -0
  12. package/lib/sexpr/classes/Bus.ts +23 -3
  13. package/lib/sexpr/classes/BusEntry.ts +30 -3
  14. package/lib/sexpr/classes/EmbeddedFonts.ts +1 -3
  15. package/lib/sexpr/classes/Footprint.ts +157 -27
  16. package/lib/sexpr/classes/FootprintAttr.ts +3 -1
  17. package/lib/sexpr/classes/FootprintModel.ts +1 -4
  18. package/lib/sexpr/classes/FootprintNetTiePadGroups.ts +3 -1
  19. package/lib/sexpr/classes/FootprintPad.ts +206 -54
  20. package/lib/sexpr/classes/FpArc.ts +23 -0
  21. package/lib/sexpr/classes/FpCircle.ts +24 -3
  22. package/lib/sexpr/classes/FpLine.ts +31 -3
  23. package/lib/sexpr/classes/FpPoly.ts +24 -4
  24. package/lib/sexpr/classes/FpRect.ts +24 -3
  25. package/lib/sexpr/classes/FpText.ts +43 -9
  26. package/lib/sexpr/classes/FpTextBox.ts +43 -5
  27. package/lib/sexpr/classes/GrLine.ts +20 -1
  28. package/lib/sexpr/classes/GrText.ts +38 -12
  29. package/lib/sexpr/classes/Image.ts +38 -11
  30. package/lib/sexpr/classes/Junction.ts +36 -4
  31. package/lib/sexpr/classes/KicadPcb.ts +49 -1
  32. package/lib/sexpr/classes/KicadSch.ts +119 -25
  33. package/lib/sexpr/classes/Label.ts +45 -5
  34. package/lib/sexpr/classes/NoConnect.ts +20 -3
  35. package/lib/sexpr/classes/PadLayers.ts +13 -1
  36. package/lib/sexpr/classes/PadOptions.ts +4 -5
  37. package/lib/sexpr/classes/PadPrimitiveGrArc.ts +22 -4
  38. package/lib/sexpr/classes/PadPrimitiveGrCircle.ts +23 -4
  39. package/lib/sexpr/classes/PadPrimitives.ts +3 -1
  40. package/lib/sexpr/classes/PadSize.ts +15 -0
  41. package/lib/sexpr/classes/PadTeardrops.ts +3 -1
  42. package/lib/sexpr/classes/PcbGeneral.ts +14 -7
  43. package/lib/sexpr/classes/PcbLayerDefinition.ts +5 -1
  44. package/lib/sexpr/classes/Property.ts +64 -9
  45. package/lib/sexpr/classes/Pts.ts +7 -5
  46. package/lib/sexpr/classes/SchematicText.ts +39 -9
  47. package/lib/sexpr/classes/Segment.ts +21 -0
  48. package/lib/sexpr/classes/SegmentNet.ts +3 -1
  49. package/lib/sexpr/classes/Setup/PcbPlotParams.ts +10 -50
  50. package/lib/sexpr/classes/Setup/Setup.ts +12 -11
  51. package/lib/sexpr/classes/Setup/Stackup.ts +14 -19
  52. package/lib/sexpr/classes/Setup/StackupLayerProperties.ts +3 -1
  53. package/lib/sexpr/classes/Setup/StackupProperties.ts +0 -1
  54. package/lib/sexpr/classes/Setup/base.ts +1 -3
  55. package/lib/sexpr/classes/Setup/setupMultiValueProperties.ts +0 -1
  56. package/lib/sexpr/classes/Sheet.ts +85 -3
  57. package/lib/sexpr/classes/SheetPin.ts +4 -1
  58. package/lib/sexpr/classes/Symbol.ts +176 -51
  59. package/lib/sexpr/classes/TextEffects.ts +25 -8
  60. package/lib/sexpr/classes/TitleBlock.ts +21 -4
  61. package/lib/sexpr/classes/Via.ts +38 -3
  62. package/lib/sexpr/classes/ViaNet.ts +2 -1
  63. package/lib/sexpr/classes/Wire.ts +23 -3
  64. package/lib/sexpr/classes/Xy.ts +1 -3
  65. package/lib/sexpr/classes/Zone.ts +1 -3
  66. package/lib/sexpr/parseToPrimitiveSExpr.ts +6 -1
  67. package/lib/sexpr/utils/strokeFromArgs.ts +5 -6
  68. package/lib/sexpr/utils/toStringValue.ts +2 -1
  69. package/package.json +2 -1
  70. package/scripts/download-references.ts +24 -22
  71. package/tests/fixtures/expectEqualPrimitiveSExpr.ts +6 -7
  72. package/tests/fixtures/png-matcher.ts +109 -0
  73. package/tests/fixtures/preload.ts +1 -0
  74. package/tests/sexpr/classes/FootprintPad.test.ts +8 -1
  75. package/tests/sexpr/classes/Image.test.ts +9 -1
  76. package/tests/sexpr/classes/KicadSch.test.ts +1 -3
  77. package/tests/sexpr/classes/Setup.test.ts +0 -1
  78. package/bun.lock +0 -48
@@ -6,7 +6,7 @@ import { indentLines } from "../utils/indentLines"
6
6
  import { toNumberValue } from "../utils/toNumberValue"
7
7
  import { toStringValue } from "../utils/toStringValue"
8
8
  import type { PrimitiveSExpr } from "../parseToPrimitiveSExpr"
9
- import { At } from "./At"
9
+ import { At, type AtInput } from "./At"
10
10
  import { Dnp } from "./Dnp"
11
11
  import { EmbeddedFonts } from "./EmbeddedFonts"
12
12
  import { ExcludeFromSim } from "./ExcludeFromSim"
@@ -93,8 +93,10 @@ export class SymbolPinNumbers extends SxClass {
93
93
  primitiveNodes.push(primitive)
94
94
  }
95
95
 
96
- const { propertyMap } =
97
- SxClass.parsePrimitivesToClassProperties(primitiveNodes, this.token)
96
+ const { propertyMap } = SxClass.parsePrimitivesToClassProperties(
97
+ primitiveNodes,
98
+ this.token,
99
+ )
98
100
 
99
101
  pinNumbers._sxHide = propertyMap.hide as SymbolPinNumbersHide
100
102
 
@@ -158,8 +160,10 @@ export class SymbolPinNames extends SxClass {
158
160
  primitiveSexprs: PrimitiveSExpr[],
159
161
  ): SymbolPinNames {
160
162
  const pinNames = new SymbolPinNames()
161
- const { propertyMap } =
162
- SxClass.parsePrimitivesToClassProperties(primitiveSexprs, this.token)
163
+ const { propertyMap } = SxClass.parsePrimitivesToClassProperties(
164
+ primitiveSexprs,
165
+ this.token,
166
+ )
163
167
 
164
168
  pinNames._sxOffset = propertyMap.offset as SymbolPinNamesOffset
165
169
  pinNames._sxHide = propertyMap.hide as SymbolPinNamesHide
@@ -255,7 +259,10 @@ abstract class SymbolPointBase extends SxClass {
255
259
  if (x === undefined || y === undefined) {
256
260
  throw new Error(`${this.name} expects two numeric arguments`)
257
261
  }
258
- const Ctor = this as unknown as new (x: number, y: number) => SymbolPointBase
262
+ const Ctor = this as unknown as new (
263
+ x: number,
264
+ y: number,
265
+ ) => SymbolPointBase
259
266
  return new Ctor(x, y)
260
267
  }
261
268
 
@@ -344,8 +351,10 @@ abstract class SymbolFillBase extends SxClass {
344
351
  primitiveSexprs: PrimitiveSExpr[],
345
352
  ): SymbolFillBase {
346
353
  const fill = new (this as unknown as new () => SymbolFillBase)()
347
- const { propertyMap } =
348
- SxClass.parsePrimitivesToClassProperties(primitiveSexprs, "fill")
354
+ const { propertyMap } = SxClass.parsePrimitivesToClassProperties(
355
+ primitiveSexprs,
356
+ "fill",
357
+ )
349
358
  fill._sxType = propertyMap.type as SymbolFillType
350
359
  return fill
351
360
  }
@@ -441,8 +450,10 @@ export class SymbolPolyline extends SxClass {
441
450
  primitiveSexprs: PrimitiveSExpr[],
442
451
  ): SymbolPolyline {
443
452
  const polyline = new SymbolPolyline()
444
- const { propertyMap } =
445
- SxClass.parsePrimitivesToClassProperties(primitiveSexprs, this.token)
453
+ const { propertyMap } = SxClass.parsePrimitivesToClassProperties(
454
+ primitiveSexprs,
455
+ this.token,
456
+ )
446
457
 
447
458
  polyline._sxPts = propertyMap.pts as Pts
448
459
  polyline._sxStroke = propertyMap.stroke as Stroke
@@ -499,8 +510,10 @@ export class SymbolRectangle extends SxClass {
499
510
  primitiveSexprs: PrimitiveSExpr[],
500
511
  ): SymbolRectangle {
501
512
  const rectangle = new SymbolRectangle()
502
- const { propertyMap } =
503
- SxClass.parsePrimitivesToClassProperties(primitiveSexprs, this.token)
513
+ const { propertyMap } = SxClass.parsePrimitivesToClassProperties(
514
+ primitiveSexprs,
515
+ this.token,
516
+ )
504
517
 
505
518
  rectangle._sxStart = propertyMap.start as SymbolRectangleStart
506
519
  rectangle._sxEnd = propertyMap.end as SymbolRectangleEnd
@@ -535,8 +548,10 @@ export class SymbolCircle extends SxClass {
535
548
  primitiveSexprs: PrimitiveSExpr[],
536
549
  ): SymbolCircle {
537
550
  const circle = new SymbolCircle()
538
- const { propertyMap } =
539
- SxClass.parsePrimitivesToClassProperties(primitiveSexprs, this.token)
551
+ const { propertyMap } = SxClass.parsePrimitivesToClassProperties(
552
+ primitiveSexprs,
553
+ this.token,
554
+ )
540
555
 
541
556
  circle._sxCenter = propertyMap.center as SymbolCircleCenter
542
557
  circle._sxRadius = propertyMap.radius as SymbolCircleRadius
@@ -572,8 +587,10 @@ export class SymbolArc extends SxClass {
572
587
  primitiveSexprs: PrimitiveSExpr[],
573
588
  ): SymbolArc {
574
589
  const arc = new SymbolArc()
575
- const { propertyMap } =
576
- SxClass.parsePrimitivesToClassProperties(primitiveSexprs, this.token)
590
+ const { propertyMap } = SxClass.parsePrimitivesToClassProperties(
591
+ primitiveSexprs,
592
+ this.token,
593
+ )
577
594
 
578
595
  arc._sxStart = propertyMap.start as SymbolArcStart
579
596
  arc._sxMid = propertyMap.mid as SymbolArcMid
@@ -617,8 +634,10 @@ export class SymbolText extends SxClass {
617
634
  const text = new SymbolText()
618
635
  text._value = value
619
636
 
620
- const { propertyMap } =
621
- SxClass.parsePrimitivesToClassProperties(rest, this.token)
637
+ const { propertyMap } = SxClass.parsePrimitivesToClassProperties(
638
+ rest,
639
+ this.token,
640
+ )
622
641
 
623
642
  text._sxAt = propertyMap.at as At
624
643
  text._sxEffects = propertyMap.effects as TextEffects
@@ -638,8 +657,8 @@ export class SymbolText extends SxClass {
638
657
  return this._sxAt
639
658
  }
640
659
 
641
- set at(value: At | undefined) {
642
- this._sxAt = value
660
+ set at(value: AtInput | undefined) {
661
+ this._sxAt = value !== undefined ? At.from(value) : undefined
643
662
  }
644
663
 
645
664
  get effects(): TextEffects | undefined {
@@ -687,6 +706,31 @@ export class SymbolPower extends SxClass {
687
706
  }
688
707
  SxClass.register(SymbolPower)
689
708
 
709
+ export interface SchematicSymbolConstructorParams {
710
+ libraryId?: string
711
+ at?: AtInput
712
+ unit?: number | SymbolUnit
713
+ pinNumbers?: SymbolPinNumbers
714
+ pinNames?: SymbolPinNames
715
+ excludeFromSim?: boolean
716
+ inBom?: boolean
717
+ onBoard?: boolean
718
+ dnp?: boolean
719
+ uuid?: string
720
+ duplicatePinNumbersAreJumpers?: boolean
721
+ fieldsAutoplaced?: boolean
722
+ properties?: SymbolProperty[]
723
+ pins?: SymbolPin[]
724
+ subSymbols?: SchematicSymbol[]
725
+ polylines?: SymbolPolyline[]
726
+ rectangles?: SymbolRectangle[]
727
+ circles?: SymbolCircle[]
728
+ arcs?: SymbolArc[]
729
+ texts?: SymbolText[]
730
+ embeddedFonts?: EmbeddedFonts
731
+ instances?: SymbolInstances
732
+ }
733
+
690
734
  export class SchematicSymbol extends SxClass {
691
735
  static override token = "symbol"
692
736
  token = "symbol"
@@ -716,6 +760,39 @@ export class SchematicSymbol extends SxClass {
716
760
  _sxInstances?: SymbolInstances
717
761
  private _inlineLibId?: string
718
762
 
763
+ constructor(params: SchematicSymbolConstructorParams = {}) {
764
+ super()
765
+
766
+ if (params.libraryId !== undefined) this.libraryId = params.libraryId
767
+ if (params.at !== undefined) this.at = params.at
768
+ if (params.unit !== undefined)
769
+ this.unit =
770
+ typeof params.unit === "number" ? params.unit : params.unit.value
771
+ if (params.pinNumbers !== undefined) this.pinNumbers = params.pinNumbers
772
+ if (params.pinNames !== undefined) this.pinNames = params.pinNames
773
+ if (params.excludeFromSim !== undefined)
774
+ this.excludeFromSim = params.excludeFromSim
775
+ if (params.inBom !== undefined) this.inBom = params.inBom
776
+ if (params.onBoard !== undefined) this.onBoard = params.onBoard
777
+ if (params.dnp !== undefined) this.dnp = params.dnp
778
+ if (params.uuid !== undefined) this.uuid = params.uuid
779
+ if (params.duplicatePinNumbersAreJumpers !== undefined)
780
+ this.duplicatePinNumbersAreJumpers = params.duplicatePinNumbersAreJumpers
781
+ if (params.fieldsAutoplaced !== undefined)
782
+ this.fieldsAutoplaced = params.fieldsAutoplaced
783
+ if (params.properties !== undefined) this.properties = params.properties
784
+ if (params.pins !== undefined) this.pins = params.pins
785
+ if (params.subSymbols !== undefined) this.subSymbols = params.subSymbols
786
+ if (params.polylines !== undefined) this.polylines = params.polylines
787
+ if (params.rectangles !== undefined) this.rectangles = params.rectangles
788
+ if (params.circles !== undefined) this.circles = params.circles
789
+ if (params.arcs !== undefined) this.arcs = params.arcs
790
+ if (params.texts !== undefined) this.texts = params.texts
791
+ if (params.embeddedFonts !== undefined)
792
+ this._sxEmbeddedFonts = params.embeddedFonts
793
+ if (params.instances !== undefined) this.instances = params.instances
794
+ }
795
+
719
796
  get libraryId(): string | undefined {
720
797
  return this._sxLibId?.value ?? this._inlineLibId
721
798
  }
@@ -736,8 +813,8 @@ export class SchematicSymbol extends SxClass {
736
813
  return this._sxAt
737
814
  }
738
815
 
739
- set at(value: At | undefined) {
740
- this._sxAt = value
816
+ set at(value: AtInput | undefined) {
817
+ this._sxAt = value !== undefined ? At.from(value) : undefined
741
818
  }
742
819
 
743
820
  get unit(): number | undefined {
@@ -821,7 +898,8 @@ export class SchematicSymbol extends SxClass {
821
898
  this._sxDuplicatePinNumbersAreJumpers = undefined
822
899
  return
823
900
  }
824
- this._sxDuplicatePinNumbersAreJumpers = new SymbolDuplicatePinNumbersAreJumpers(value)
901
+ this._sxDuplicatePinNumbersAreJumpers =
902
+ new SymbolDuplicatePinNumbersAreJumpers(value)
825
903
  }
826
904
 
827
905
  get instances(): SymbolInstances | undefined {
@@ -961,14 +1039,15 @@ export class SymbolProperty extends SxClass {
961
1039
  key: string
962
1040
  value: string
963
1041
  id?: number | SymbolPropertyId
964
- at?: At
1042
+ at?: AtInput
965
1043
  effects?: TextEffects
966
1044
  }) {
967
1045
  super()
968
1046
  this.key = params.key
969
1047
  this.value = params.value
970
- this._sxId = params.id !== undefined ? SymbolPropertyId.from(params.id) : undefined
971
- this._sxAt = params.at
1048
+ this._sxId =
1049
+ params.id !== undefined ? SymbolPropertyId.from(params.id) : undefined
1050
+ this._sxAt = params.at !== undefined ? At.from(params.at) : undefined
972
1051
  this._sxEffects = params.effects
973
1052
  }
974
1053
 
@@ -980,8 +1059,10 @@ export class SymbolProperty extends SxClass {
980
1059
  const key = toStringValue(inputKey) ?? ""
981
1060
  const value = toStringValue(inputValue) ?? ""
982
1061
 
983
- const { propertyMap } =
984
- SxClass.parsePrimitivesToClassProperties(rest, this.token)
1062
+ const { propertyMap } = SxClass.parsePrimitivesToClassProperties(
1063
+ rest,
1064
+ this.token,
1065
+ )
985
1066
 
986
1067
  return new SymbolProperty({
987
1068
  key,
@@ -1004,8 +1085,8 @@ export class SymbolProperty extends SxClass {
1004
1085
  return this._sxAt
1005
1086
  }
1006
1087
 
1007
- set at(value: At | undefined) {
1008
- this._sxAt = value
1088
+ set at(value: AtInput | undefined) {
1089
+ this._sxAt = value !== undefined ? At.from(value) : undefined
1009
1090
  }
1010
1091
 
1011
1092
  get effects(): TextEffects | undefined {
@@ -1070,8 +1151,31 @@ type PinGraphicStyle =
1070
1151
  | "edge_clock_high"
1071
1152
  | "non_logic"
1072
1153
 
1073
- const electricalTypeSet = new Set<PinElectricalType>(["input", "output", "bidirectional", "tri_state", "passive", "free", "unspecified", "power_in", "power_out", "open_collector", "open_emitter", "no_connect"])
1074
- const graphicStyleSet = new Set<PinGraphicStyle>(["line", "inverted", "clock", "inverted_clock", "input_low", "clock_low", "output_low", "edge_clock_high", "non_logic"])
1154
+ const electricalTypeSet = new Set<PinElectricalType>([
1155
+ "input",
1156
+ "output",
1157
+ "bidirectional",
1158
+ "tri_state",
1159
+ "passive",
1160
+ "free",
1161
+ "unspecified",
1162
+ "power_in",
1163
+ "power_out",
1164
+ "open_collector",
1165
+ "open_emitter",
1166
+ "no_connect",
1167
+ ])
1168
+ const graphicStyleSet = new Set<PinGraphicStyle>([
1169
+ "line",
1170
+ "inverted",
1171
+ "clock",
1172
+ "inverted_clock",
1173
+ "input_low",
1174
+ "clock_low",
1175
+ "output_low",
1176
+ "edge_clock_high",
1177
+ "non_logic",
1178
+ ])
1075
1179
 
1076
1180
  export class SymbolPinLength extends SxPrimitiveNumber {
1077
1181
  static override token = "length"
@@ -1099,8 +1203,10 @@ export class SymbolPinName extends SxClass {
1099
1203
  ): SymbolPinName {
1100
1204
  const [valuePrimitive, ...rest] = primitiveSexprs
1101
1205
  const value = toStringValue(valuePrimitive) ?? ""
1102
- const { propertyMap } =
1103
- SxClass.parsePrimitivesToClassProperties(rest, this.token)
1206
+ const { propertyMap } = SxClass.parsePrimitivesToClassProperties(
1207
+ rest,
1208
+ this.token,
1209
+ )
1104
1210
 
1105
1211
  return new SymbolPinName({
1106
1212
  value,
@@ -1150,8 +1256,10 @@ export class SymbolPinNumber extends SxClass {
1150
1256
  ): SymbolPinNumber {
1151
1257
  const [valuePrimitive, ...rest] = primitiveSexprs
1152
1258
  const value = toStringValue(valuePrimitive) ?? ""
1153
- const { propertyMap } =
1154
- SxClass.parsePrimitivesToClassProperties(rest, this.token)
1259
+ const { propertyMap } = SxClass.parsePrimitivesToClassProperties(
1260
+ rest,
1261
+ this.token,
1262
+ )
1155
1263
 
1156
1264
  return new SymbolPinNumber({
1157
1265
  value,
@@ -1204,12 +1312,18 @@ export class SymbolPin extends SxClass {
1204
1312
  const first = args[0]
1205
1313
  const firstString = toStringValue(first)
1206
1314
 
1207
- if (firstString && electricalTypeSet.has(firstString as PinElectricalType)) {
1315
+ if (
1316
+ firstString &&
1317
+ electricalTypeSet.has(firstString as PinElectricalType)
1318
+ ) {
1208
1319
  symbolPin.pinElectricalType = firstString as PinElectricalType
1209
1320
  index = 1
1210
1321
  const second = args[1]
1211
1322
  const secondString = toStringValue(second)
1212
- if (secondString && graphicStyleSet.has(secondString as PinGraphicStyle)) {
1323
+ if (
1324
+ secondString &&
1325
+ graphicStyleSet.has(secondString as PinGraphicStyle)
1326
+ ) {
1213
1327
  symbolPin.pinGraphicStyle = secondString as PinGraphicStyle
1214
1328
  index = 2
1215
1329
  }
@@ -1230,8 +1344,10 @@ export class SymbolPin extends SxClass {
1230
1344
  primitiveNodes.push(primitive)
1231
1345
  }
1232
1346
 
1233
- const { propertyMap } =
1234
- SxClass.parsePrimitivesToClassProperties(primitiveNodes, this.token)
1347
+ const { propertyMap } = SxClass.parsePrimitivesToClassProperties(
1348
+ primitiveNodes,
1349
+ this.token,
1350
+ )
1235
1351
 
1236
1352
  symbolPin._sxAt = propertyMap.at as At
1237
1353
  symbolPin._sxLength = propertyMap.length as SymbolPinLength
@@ -1255,8 +1371,8 @@ export class SymbolPin extends SxClass {
1255
1371
  return this._sxAt
1256
1372
  }
1257
1373
 
1258
- set at(value: At | undefined) {
1259
- this._sxAt = value
1374
+ set at(value: AtInput | undefined) {
1375
+ this._sxAt = value !== undefined ? At.from(value) : undefined
1260
1376
  }
1261
1377
 
1262
1378
  get length(): number | undefined {
@@ -1264,7 +1380,8 @@ export class SymbolPin extends SxClass {
1264
1380
  }
1265
1381
 
1266
1382
  set length(value: number | undefined) {
1267
- this._sxLength = value === undefined ? undefined : new SymbolPinLength(value)
1383
+ this._sxLength =
1384
+ value === undefined ? undefined : new SymbolPinLength(value)
1268
1385
  }
1269
1386
 
1270
1387
  get name(): string | undefined {
@@ -1356,8 +1473,10 @@ export class SymbolInstances extends SxClass {
1356
1473
  primitiveSexprs: PrimitiveSExpr[],
1357
1474
  ): SymbolInstances {
1358
1475
  const symbolInstances = new SymbolInstances()
1359
- const { arrayPropertyMap } =
1360
- SxClass.parsePrimitivesToClassProperties(primitiveSexprs, this.token)
1476
+ const { arrayPropertyMap } = SxClass.parsePrimitivesToClassProperties(
1477
+ primitiveSexprs,
1478
+ this.token,
1479
+ )
1361
1480
 
1362
1481
  symbolInstances.projects =
1363
1482
  (arrayPropertyMap.project as SymbolInstancesProject[]) ?? []
@@ -1421,8 +1540,10 @@ export class SymbolInstancesProject extends SxClass {
1421
1540
  const name = toStringValue(namePrimitive) ?? ""
1422
1541
  const project = new SymbolInstancesProject(name)
1423
1542
 
1424
- const { arrayPropertyMap } =
1425
- SxClass.parsePrimitivesToClassProperties(rest, this.token)
1543
+ const { arrayPropertyMap } = SxClass.parsePrimitivesToClassProperties(
1544
+ rest,
1545
+ this.token,
1546
+ )
1426
1547
 
1427
1548
  project.paths = (arrayPropertyMap.path as SymbolInstancePath[]) ?? []
1428
1549
 
@@ -1465,8 +1586,10 @@ export class SymbolInstancePath extends SxClass {
1465
1586
  const value = toStringValue(pathPrimitive) ?? ""
1466
1587
  const path = new SymbolInstancePath(value)
1467
1588
 
1468
- const { propertyMap } =
1469
- SxClass.parsePrimitivesToClassProperties(rest, this.token)
1589
+ const { propertyMap } = SxClass.parsePrimitivesToClassProperties(
1590
+ rest,
1591
+ this.token,
1592
+ )
1470
1593
 
1471
1594
  path._sxReference = propertyMap.reference as SymbolInstanceReference
1472
1595
  path._sxUnit = propertyMap.unit as SymbolInstanceUnit
@@ -1479,7 +1602,8 @@ export class SymbolInstancePath extends SxClass {
1479
1602
  }
1480
1603
 
1481
1604
  set reference(value: string | undefined) {
1482
- this._sxReference = value === undefined ? undefined : new SymbolInstanceReference(value)
1605
+ this._sxReference =
1606
+ value === undefined ? undefined : new SymbolInstanceReference(value)
1483
1607
  }
1484
1608
 
1485
1609
  get unit(): number | undefined {
@@ -1487,7 +1611,8 @@ export class SymbolInstancePath extends SxClass {
1487
1611
  }
1488
1612
 
1489
1613
  set unit(value: number | undefined) {
1490
- this._sxUnit = value === undefined ? undefined : new SymbolInstanceUnit(value)
1614
+ this._sxUnit =
1615
+ value === undefined ? undefined : new SymbolInstanceUnit(value)
1491
1616
  }
1492
1617
 
1493
1618
  override getChildren(): SxClass[] {
@@ -9,6 +9,12 @@ import { toStringValue } from "../utils/toStringValue"
9
9
 
10
10
  export type TextEffectsProperty = TextEffectsFont | TextEffectsJustify
11
11
 
12
+ export interface TextEffectsConstructorParams {
13
+ font?: TextEffectsFont
14
+ justify?: TextEffectsJustify
15
+ hiddenText?: boolean
16
+ }
17
+
12
18
  export class TextEffects extends SxClass {
13
19
  static override token = "effects"
14
20
  token = "effects"
@@ -17,6 +23,14 @@ export class TextEffects extends SxClass {
17
23
  _sxJustify?: TextEffectsJustify
18
24
  private _hiddenText = false
19
25
 
26
+ constructor(params: TextEffectsConstructorParams = {}) {
27
+ super()
28
+
29
+ if (params.font !== undefined) this.font = params.font
30
+ if (params.justify !== undefined) this.justify = params.justify
31
+ if (params.hiddenText !== undefined) this.hiddenText = params.hiddenText
32
+ }
33
+
20
34
  get font(): TextEffectsFont {
21
35
  if (!this._sxFont) {
22
36
  this._sxFont = new TextEffectsFont()
@@ -140,9 +154,10 @@ export class TextEffectsFont extends SxClass {
140
154
  return { height: this._sxSize.height, width: this._sxSize.width }
141
155
  }
142
156
 
143
- set size(
144
- value: TextEffectsFontSize | { height: number; width: number } | undefined,
145
- ) {
157
+ set size(value:
158
+ | TextEffectsFontSize
159
+ | { height: number; width: number }
160
+ | undefined,) {
146
161
  if (value === undefined) {
147
162
  this._sxSize = undefined
148
163
  return
@@ -357,11 +372,13 @@ export class TextEffectsJustify extends SxClass {
357
372
  private _vertical?: "top" | "bottom"
358
373
  private _mirror = false
359
374
 
360
- constructor(options: {
361
- horizontal?: "left" | "right"
362
- vertical?: "top" | "bottom"
363
- mirror?: boolean
364
- } = {}) {
375
+ constructor(
376
+ options: {
377
+ horizontal?: "left" | "right"
378
+ vertical?: "top" | "bottom"
379
+ mirror?: boolean
380
+ } = {},
381
+ ) {
365
382
  super()
366
383
  this._horizontal = options.horizontal
367
384
  this._vertical = options.vertical
@@ -14,6 +14,14 @@ function primitiveToString(value: PrimitiveSExpr | undefined): string {
14
14
  return printSExpr(value)
15
15
  }
16
16
 
17
+ export interface TitleBlockConstructorParams {
18
+ title?: string
19
+ date?: string
20
+ rev?: string
21
+ company?: string
22
+ comments?: TitleBlockComment[]
23
+ }
24
+
17
25
  export class TitleBlock extends SxClass {
18
26
  static override token = "title_block"
19
27
  token = "title_block"
@@ -24,6 +32,16 @@ export class TitleBlock extends SxClass {
24
32
  private _sxCompany?: TitleBlockCompany
25
33
  comments: TitleBlockComment[] = []
26
34
 
35
+ constructor(params: TitleBlockConstructorParams = {}) {
36
+ super()
37
+
38
+ if (params.title !== undefined) this.title = params.title
39
+ if (params.date !== undefined) this.date = params.date
40
+ if (params.rev !== undefined) this.rev = params.rev
41
+ if (params.company !== undefined) this.company = params.company
42
+ if (params.comments !== undefined) this.comments = params.comments
43
+ }
44
+
27
45
  static override fromSexprPrimitives(
28
46
  primitiveSexprs: PrimitiveSExpr[],
29
47
  ): TitleBlock {
@@ -96,7 +114,8 @@ export class TitleBlock extends SxClass {
96
114
  }
97
115
 
98
116
  set rev(value: string | undefined) {
99
- this._sxRev = value === undefined ? undefined : new TitleBlockRevision(value)
117
+ this._sxRev =
118
+ value === undefined ? undefined : new TitleBlockRevision(value)
100
119
  }
101
120
 
102
121
  get company(): string | undefined {
@@ -132,9 +151,7 @@ export class TitleBlock extends SxClass {
132
151
  if (this._sxRev) children.push(this._sxRev)
133
152
  if (this._sxCompany) children.push(this._sxCompany)
134
153
 
135
- const sortedComments = [...this.comments].sort(
136
- (a, b) => a.index - b.index,
137
- )
154
+ const sortedComments = [...this.comments].sort((a, b) => a.index - b.index)
138
155
  children.push(...sortedComments)
139
156
  return children
140
157
  }
@@ -1,7 +1,7 @@
1
1
  import { SxClass } from "../base-classes/SxClass"
2
2
  import type { PrimitiveSExpr } from "../parseToPrimitiveSExpr"
3
3
  import { quoteSExprString } from "../utils/quoteSExprString"
4
- import { At } from "./At"
4
+ import { At, type AtInput } from "./At"
5
5
  import { Layers } from "./Layers"
6
6
  import { Uuid } from "./Uuid"
7
7
  import { ViaNet } from "./ViaNet"
@@ -16,6 +16,22 @@ const BARE_FLAGS = new Set([
16
16
  "keep_end_layers",
17
17
  ])
18
18
 
19
+ export interface ViaConstructorParams {
20
+ type?: string
21
+ locked?: boolean
22
+ free?: boolean
23
+ removeUnusedLayers?: boolean
24
+ keepEndLayers?: boolean
25
+ at?: AtInput
26
+ size?: number
27
+ drill?: number
28
+ layers?: Layers | string[]
29
+ net?: ViaNet
30
+ uuid?: Uuid | string
31
+ tstamp?: string
32
+ teardrops?: PadTeardrops
33
+ }
34
+
19
35
  export class Via extends SxClass {
20
36
  static override token = "via"
21
37
  token = "via"
@@ -34,6 +50,25 @@ export class Via extends SxClass {
34
50
  private _tstamp?: string
35
51
  private _sxTeardrops?: PadTeardrops
36
52
 
53
+ constructor(params: ViaConstructorParams = {}) {
54
+ super()
55
+ if (params.type !== undefined) this.type = params.type
56
+ if (params.locked !== undefined) this.locked = params.locked
57
+ if (params.free !== undefined) this.free = params.free
58
+ if (params.removeUnusedLayers !== undefined)
59
+ this.removeUnusedLayers = params.removeUnusedLayers
60
+ if (params.keepEndLayers !== undefined)
61
+ this.keepEndLayers = params.keepEndLayers
62
+ if (params.at !== undefined) this.at = params.at
63
+ if (params.size !== undefined) this.size = params.size
64
+ if (params.drill !== undefined) this.drill = params.drill
65
+ if (params.layers !== undefined) this.layers = params.layers
66
+ if (params.net !== undefined) this.net = params.net
67
+ if (params.uuid !== undefined) this.uuid = params.uuid
68
+ if (params.tstamp !== undefined) this.tstamp = params.tstamp
69
+ if (params.teardrops !== undefined) this.teardrops = params.teardrops
70
+ }
71
+
37
72
  static override fromSexprPrimitives(primitiveSexprs: PrimitiveSExpr[]): Via {
38
73
  const via = new Via()
39
74
 
@@ -220,8 +255,8 @@ export class Via extends SxClass {
220
255
  return this._sxAt
221
256
  }
222
257
 
223
- set at(value: At | undefined) {
224
- this._sxAt = value
258
+ set at(value: AtInput | undefined) {
259
+ this._sxAt = value !== undefined ? At.from(value) : undefined
225
260
  }
226
261
 
227
262
  get size(): number | undefined {
@@ -25,7 +25,8 @@ export class ViaNet extends SxClass {
25
25
  if (id === undefined) {
26
26
  throw new Error("via net requires a numeric id")
27
27
  }
28
- const name = primitiveSexprs.length > 1 ? toStringValue(primitiveSexprs[1]) : undefined
28
+ const name =
29
+ primitiveSexprs.length > 1 ? toStringValue(primitiveSexprs[1]) : undefined
29
30
  return new ViaNet(id, name)
30
31
  }
31
32
 
@@ -6,6 +6,12 @@ import { Uuid } from "./Uuid"
6
6
 
7
7
  const SUPPORTED_TOKENS = new Set(["pts", "stroke", "uuid"])
8
8
 
9
+ export interface WireConstructorParams {
10
+ points?: Pts
11
+ stroke?: Stroke
12
+ uuid?: string | Uuid
13
+ }
14
+
9
15
  export class Wire extends SxClass {
10
16
  static override token = "wire"
11
17
  static override parentToken = "kicad_sch"
@@ -15,9 +21,23 @@ export class Wire extends SxClass {
15
21
  private _sxStroke?: Stroke
16
22
  private _sxUuid?: Uuid
17
23
 
18
- static override fromSexprPrimitives(
19
- primitiveSexprs: PrimitiveSExpr[],
20
- ): Wire {
24
+ constructor(params: WireConstructorParams = {}) {
25
+ super()
26
+
27
+ if (params.points !== undefined) {
28
+ this.points = params.points
29
+ }
30
+
31
+ if (params.stroke !== undefined) {
32
+ this.stroke = params.stroke
33
+ }
34
+
35
+ if (params.uuid !== undefined) {
36
+ this.uuid = params.uuid
37
+ }
38
+ }
39
+
40
+ static override fromSexprPrimitives(primitiveSexprs: PrimitiveSExpr[]): Wire {
21
41
  const wire = new Wire()
22
42
 
23
43
  const { propertyMap, arrayPropertyMap } =
@@ -15,9 +15,7 @@ export class Xy extends SxClass {
15
15
  this.y = y
16
16
  }
17
17
 
18
- static override fromSexprPrimitives(
19
- primitiveSexprs: PrimitiveSExpr[],
20
- ): Xy {
18
+ static override fromSexprPrimitives(primitiveSexprs: PrimitiveSExpr[]): Xy {
21
19
  const [rawX, rawY] = primitiveSexprs
22
20
  const x = toNumberValue(rawX) ?? 0
23
21
  const y = toNumberValue(rawY) ?? 0
@@ -7,9 +7,7 @@ export class Zone extends SxClass {
7
7
 
8
8
  private _rawChildren: PrimitiveSExpr[] = []
9
9
 
10
- static override fromSexprPrimitives(
11
- primitiveSexprs: PrimitiveSExpr[],
12
- ): Zone {
10
+ static override fromSexprPrimitives(primitiveSexprs: PrimitiveSExpr[]): Zone {
13
11
  const zone = new Zone()
14
12
  zone._rawChildren = [...primitiveSexprs]
15
13
  return zone