@jlcpcb/cli 0.1.0 → 0.1.1

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/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # @jlcpcb/cli
2
2
 
3
+ ## 0.1.1
4
+
5
+ ### Patch Changes
6
+
7
+ - **@jlcpcb/core:**
8
+ - Fix: Restrict built-in footprints to 2-pad passives only — prevents pin-flip issues on multi-pin components
9
+
10
+ **@jlcpcb/cli & @jlcpcb/mcp:**
11
+ - Updated dependencies
12
+
13
+ - Updated dependencies []:
14
+ - @jlcpcb/core@0.1.1
15
+
3
16
  ## 0.1.0
4
17
 
5
18
  ### Minor Changes
package/README.md CHANGED
@@ -4,6 +4,8 @@
4
4
 
5
5
  Interactive terminal UI for JLCPCB component search and KiCad library management. Built with React and Ink for a rich terminal experience.
6
6
 
7
+ <video src="https://github.com/user-attachments/assets/7be693d3-0d82-473d-9fec-0d65fd994ca6" controls></video>
8
+
7
9
  ## Installation
8
10
 
9
11
  ```bash
package/dist/index.js CHANGED
@@ -2693,7 +2693,7 @@ See https://react.dev/link/invalid-hook-call for tips about how to debug and fix
2693
2693
 
2694
2694
  // ../../node_modules/react/index.js
2695
2695
  var require_react = __commonJS((exports, module) => {
2696
- var react_development = __toESM(require_react_development(), 1);
2696
+ var react_development = __toESM(require_react_development());
2697
2697
  if (false) {} else {
2698
2698
  module.exports = react_development;
2699
2699
  }
@@ -3145,7 +3145,7 @@ var require_scheduler_development = __commonJS((exports) => {
3145
3145
 
3146
3146
  // ../../node_modules/scheduler/index.js
3147
3147
  var require_scheduler = __commonJS((exports, module) => {
3148
- var scheduler_development = __toESM(require_scheduler_development(), 1);
3148
+ var scheduler_development = __toESM(require_scheduler_development());
3149
3149
  if (false) {} else {
3150
3150
  module.exports = scheduler_development;
3151
3151
  }
@@ -3153,8 +3153,8 @@ var require_scheduler = __commonJS((exports, module) => {
3153
3153
 
3154
3154
  // ../../node_modules/react-reconciler/cjs/react-reconciler.development.js
3155
3155
  var require_react_reconciler_development = __commonJS((exports, module) => {
3156
- var React = __toESM(require_react(), 1);
3157
- var Scheduler = __toESM(require_scheduler(), 1);
3156
+ var React = __toESM(require_react());
3157
+ var Scheduler = __toESM(require_scheduler());
3158
3158
  module.exports = function($$$config) {
3159
3159
  function findHook(fiber, id) {
3160
3160
  for (fiber = fiber.memoizedState;fiber !== null && 0 < id; )
@@ -33706,7 +33706,7 @@ var require_stack_utils = __commonJS((exports, module) => {
33706
33706
 
33707
33707
  // ../../node_modules/react/cjs/react-jsx-dev-runtime.development.js
33708
33708
  var require_react_jsx_dev_runtime_development = __commonJS((exports) => {
33709
- var React10 = __toESM(require_react(), 1);
33709
+ var React10 = __toESM(require_react());
33710
33710
  (function() {
33711
33711
  function getComponentNameFromType(type) {
33712
33712
  if (type == null)
@@ -33921,7 +33921,7 @@ React keys must be passed directly to JSX without using spread:
33921
33921
 
33922
33922
  // ../../node_modules/react/jsx-dev-runtime.js
33923
33923
  var require_jsx_dev_runtime = __commonJS((exports, module) => {
33924
- var react_jsx_dev_runtime_development = __toESM(require_react_jsx_dev_runtime_development(), 1);
33924
+ var react_jsx_dev_runtime_development = __toESM(require_react_jsx_dev_runtime_development());
33925
33925
  if (false) {} else {
33926
33926
  module.exports = react_jsx_dev_runtime_development;
33927
33927
  }
@@ -41644,7 +41644,6 @@ ${template.bodyGraphics}
41644
41644
  }
41645
41645
  }
41646
41646
  var symbolConverter = new SymbolConverter;
41647
- init_category_router();
41648
41647
  var SMD_SIZES = {
41649
41648
  "0201": { metric: "0603", imperialMm: "0.6x0.3" },
41650
41649
  "0402": { metric: "1005", imperialMm: "1.0x0.5" },
@@ -41661,57 +41660,7 @@ var PASSIVE_LIBRARIES = {
41661
41660
  C: "Capacitor_SMD",
41662
41661
  L: "Inductor_SMD"
41663
41662
  };
41664
- var LED_LIBRARY = "LED_SMD";
41665
- var DIODE_LIBRARY = "Diode_SMD";
41666
- var CATEGORY_TO_PREFIX2 = {
41667
- Resistors: "R",
41668
- Capacitors: "C",
41669
- Inductors: "L",
41670
- Diodes: "D"
41671
- };
41672
- var SOIC_MAPPINGS = {
41673
- "SOIC-8": "SOIC-8_3.9x4.9mm_P1.27mm",
41674
- "SOP-8": "SOIC-8_3.9x4.9mm_P1.27mm",
41675
- "SOIC-14": "SOIC-14_3.9x8.7mm_P1.27mm",
41676
- "SOIC-16": "SOIC-16_3.9x9.9mm_P1.27mm",
41677
- "SOIC-16W": "SOIC-16W_7.5x10.3mm_P1.27mm",
41678
- "SOIC-20": "SOIC-20W_7.5x12.8mm_P1.27mm",
41679
- "SOIC-24": "SOIC-24W_7.5x15.4mm_P1.27mm",
41680
- "SOIC-28": "SOIC-28W_7.5x17.9mm_P1.27mm"
41681
- };
41682
- var TSSOP_MAPPINGS = {
41683
- "TSSOP-8": "TSSOP-8_3x3mm_P0.65mm",
41684
- "TSSOP-14": "TSSOP-14_4.4x5mm_P0.65mm",
41685
- "TSSOP-16": "TSSOP-16_4.4x5mm_P0.65mm",
41686
- "TSSOP-20": "TSSOP-20_4.4x6.5mm_P0.65mm",
41687
- "TSSOP-24": "TSSOP-24_4.4x7.8mm_P0.65mm",
41688
- "TSSOP-28": "TSSOP-28_4.4x9.7mm_P0.65mm"
41689
- };
41690
- var SOT_MAPPINGS = {
41691
- "SOT-23": { library: "Package_TO_SOT_SMD", footprint: "SOT-23" },
41692
- "SOT-23-3": { library: "Package_TO_SOT_SMD", footprint: "SOT-23" },
41693
- "SOT-23-5": { library: "Package_TO_SOT_SMD", footprint: "SOT-23-5" },
41694
- "SOT-23-6": { library: "Package_TO_SOT_SMD", footprint: "SOT-23-6" },
41695
- "SOT-89": { library: "Package_TO_SOT_SMD", footprint: "SOT-89-3" },
41696
- "SOT-223": { library: "Package_TO_SOT_SMD", footprint: "SOT-223-3_TabPin2" }
41697
- };
41698
- var SOD_MAPPINGS = {
41699
- "SOD-123": { library: "Diode_SMD", footprint: "D_SOD-123" },
41700
- "SOD-123F": { library: "Diode_SMD", footprint: "D_SOD-123F" },
41701
- "SOD-323": { library: "Diode_SMD", footprint: "D_SOD-323" },
41702
- "SOD-523": { library: "Diode_SMD", footprint: "D_SOD-523" },
41703
- "SOD-923": { library: "Diode_SMD", footprint: "D_SOD-923" },
41704
- "SOD-128": { library: "Diode_SMD", footprint: "D_SOD-128" },
41705
- "SOD-80": { library: "Diode_SMD", footprint: "D_SOD-80" }
41706
- };
41707
- var DIODE_PACKAGE_MAPPINGS = {
41708
- SMA: { library: "Diode_SMD", footprint: "D_SMA" },
41709
- SMB: { library: "Diode_SMD", footprint: "D_SMB" },
41710
- SMC: { library: "Diode_SMD", footprint: "D_SMC" },
41711
- MELF: { library: "Diode_SMD", footprint: "D_MELF" },
41712
- MINIMELF: { library: "Diode_SMD", footprint: "D_MiniMELF" },
41713
- MICROMELF: { library: "Diode_SMD", footprint: "D_MicroMELF" }
41714
- };
41663
+ var PASSIVE_PAD_COUNT = 2;
41715
41664
  function normalizePackageName(name) {
41716
41665
  return name.toUpperCase().replace(/[_\s-]+/g, "-").replace(/\(.*?\)/g, "").trim();
41717
41666
  }
@@ -41726,58 +41675,23 @@ function extractSmdSize(packageName) {
41726
41675
  const match = normalized.match(sizePattern);
41727
41676
  return match ? match[1] : null;
41728
41677
  }
41729
- function mapToKicadFootprint(packageName, componentPrefix, category, description) {
41730
- const normalized = normalizePackageName(packageName);
41731
- let prefix = componentPrefix.toUpperCase();
41732
- const isKnownPrefix = PASSIVE_LIBRARIES[prefix] || prefix === "D" || prefix === "LED";
41733
- if (!isKnownPrefix && (category || description)) {
41734
- const detectedCategory = getLibraryCategory(prefix, category, description);
41735
- const categoryPrefix = CATEGORY_TO_PREFIX2[detectedCategory];
41736
- if (categoryPrefix) {
41737
- prefix = categoryPrefix;
41738
- }
41678
+ function mapToKicadFootprint(packageName, componentPrefix, _category, _description) {
41679
+ const prefix = componentPrefix.toUpperCase();
41680
+ if (!PASSIVE_LIBRARIES[prefix]) {
41681
+ return null;
41739
41682
  }
41740
41683
  const smdSize = extractSmdSize(packageName);
41741
- if (smdSize && PASSIVE_LIBRARIES[prefix]) {
41684
+ if (smdSize) {
41742
41685
  const sizeInfo = SMD_SIZES[smdSize];
41743
41686
  const library = PASSIVE_LIBRARIES[prefix];
41744
41687
  const footprint = `${prefix}_${smdSize}_${sizeInfo.metric}Metric`;
41745
41688
  return { library, footprint };
41746
41689
  }
41747
- if (smdSize && prefix === "LED") {
41748
- const sizeInfo = SMD_SIZES[smdSize];
41749
- const footprint = `LED_${smdSize}_${sizeInfo.metric}Metric`;
41750
- return { library: LED_LIBRARY, footprint };
41751
- }
41752
- if (smdSize && prefix === "D") {
41753
- const sizeInfo = SMD_SIZES[smdSize];
41754
- const footprint = `D_${smdSize}_${sizeInfo.metric}Metric`;
41755
- return { library: DIODE_LIBRARY, footprint };
41756
- }
41757
- for (const [pattern, mapping] of Object.entries(SOD_MAPPINGS)) {
41758
- if (normalized.includes(pattern) || normalized.startsWith(pattern.replace(/-/g, ""))) {
41759
- return mapping;
41760
- }
41761
- }
41762
- for (const [pattern, mapping] of Object.entries(DIODE_PACKAGE_MAPPINGS)) {
41763
- if (normalized === pattern || normalized.startsWith(pattern + "-") || normalized.startsWith(pattern + "_")) {
41764
- return mapping;
41765
- }
41766
- }
41767
- for (const [pattern, footprint] of Object.entries(SOIC_MAPPINGS)) {
41768
- if (normalized.includes(pattern) || normalized.startsWith(pattern.replace(/-/g, ""))) {
41769
- return { library: "Package_SO", footprint };
41770
- }
41771
- }
41772
- for (const [pattern, footprint] of Object.entries(TSSOP_MAPPINGS)) {
41773
- if (normalized.includes(pattern) || normalized.startsWith(pattern.replace(/-/g, ""))) {
41774
- return { library: "Package_SO", footprint };
41775
- }
41776
- }
41777
- for (const [pattern, mapping] of Object.entries(SOT_MAPPINGS)) {
41778
- if (normalized.includes(pattern) || normalized === pattern.replace(/-/g, "")) {
41779
- return mapping;
41780
- }
41690
+ return null;
41691
+ }
41692
+ function getExpectedPadCount(mapping) {
41693
+ if (mapping.library === "Resistor_SMD" || mapping.library === "Capacitor_SMD" || mapping.library === "Inductor_SMD") {
41694
+ return PASSIVE_PAD_COUNT;
41781
41695
  }
41782
41696
  return null;
41783
41697
  }
@@ -41955,13 +41869,19 @@ class FootprintConverter {
41955
41869
  const { info, footprint } = component;
41956
41870
  const packageName = footprint.name;
41957
41871
  const prefix = info.prefix;
41872
+ const actualPadCount = footprint.pads.length;
41958
41873
  const mapping = mapToKicadFootprint(packageName, prefix, info.category, info.description);
41959
41874
  if (mapping) {
41960
- return {
41961
- type: "reference",
41962
- reference: getKicadFootprintRef(mapping),
41963
- name: mapping.footprint
41964
- };
41875
+ const expectedPadCount = getExpectedPadCount(mapping);
41876
+ if (expectedPadCount !== null && expectedPadCount !== actualPadCount) {
41877
+ console.warn(`[footprint] Pad count mismatch for ${packageName}: expected ${expectedPadCount}, got ${actualPadCount}. Generating custom footprint.`);
41878
+ } else {
41879
+ return {
41880
+ type: "reference",
41881
+ reference: getKicadFootprintRef(mapping),
41882
+ name: mapping.footprint
41883
+ };
41884
+ }
41965
41885
  }
41966
41886
  const content = this.convert(component, options);
41967
41887
  const name = this.sanitizeName(footprint.name);
@@ -51099,7 +51019,7 @@ var r = { modifier: { reset: [0, 0], bold: [1, 22], dim: [2, 22], italic: [3, 23
51099
51019
  Object.keys(r.modifier);
51100
51020
  var tD = Object.keys(r.color);
51101
51021
  var eD = Object.keys(r.bgColor);
51102
- [...tD];
51022
+ [...tD, ...eD];
51103
51023
  function sD() {
51104
51024
  const t = new Map;
51105
51025
  for (const [u, F] of Object.entries(r)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jlcpcb/cli",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "CLI for JLC/EasyEDA component sourcing and KiCad library management",