@jlcpcb/core 0.1.0

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 (44) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/README.md +474 -0
  3. package/package.json +48 -0
  4. package/src/api/easyeda-community.ts +259 -0
  5. package/src/api/easyeda.ts +153 -0
  6. package/src/api/index.ts +7 -0
  7. package/src/api/jlc.ts +185 -0
  8. package/src/constants/design-rules.ts +119 -0
  9. package/src/constants/footprints.ts +68 -0
  10. package/src/constants/index.ts +7 -0
  11. package/src/constants/kicad.ts +147 -0
  12. package/src/converter/category-router.ts +638 -0
  13. package/src/converter/footprint-mapper.ts +236 -0
  14. package/src/converter/footprint.ts +949 -0
  15. package/src/converter/global-lib-table.ts +394 -0
  16. package/src/converter/index.ts +46 -0
  17. package/src/converter/lib-table.ts +181 -0
  18. package/src/converter/svg-arc.ts +179 -0
  19. package/src/converter/symbol-templates.ts +214 -0
  20. package/src/converter/symbol.ts +1682 -0
  21. package/src/converter/value-normalizer.ts +262 -0
  22. package/src/index.ts +25 -0
  23. package/src/parsers/easyeda-shapes.ts +628 -0
  24. package/src/parsers/http-client.ts +96 -0
  25. package/src/parsers/index.ts +38 -0
  26. package/src/parsers/utils.ts +29 -0
  27. package/src/services/component-service.ts +100 -0
  28. package/src/services/fix-service.ts +50 -0
  29. package/src/services/index.ts +9 -0
  30. package/src/services/library-service.ts +696 -0
  31. package/src/types/component.ts +61 -0
  32. package/src/types/easyeda-community.ts +78 -0
  33. package/src/types/easyeda.ts +356 -0
  34. package/src/types/index.ts +12 -0
  35. package/src/types/jlc.ts +84 -0
  36. package/src/types/kicad.ts +136 -0
  37. package/src/types/mcp.ts +77 -0
  38. package/src/types/project.ts +60 -0
  39. package/src/utils/conversion.ts +104 -0
  40. package/src/utils/file-system.ts +143 -0
  41. package/src/utils/index.ts +8 -0
  42. package/src/utils/logger.ts +96 -0
  43. package/src/utils/validation.ts +110 -0
  44. package/tsconfig.json +9 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,10 @@
1
+ # @jlcpcb/core
2
+
3
+ ## 0.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`cc44735`](https://github.com/l3wi/jlc-cli/commit/cc44735cc56191533f1a088101dfe2b368929048) Thanks [@l3wi](https://github.com/l3wi)! - Initial release of @jlcpcb packages for JLC/EasyEDA component sourcing and KiCad integration.
8
+ - **@jlcpcb/core**: Core library with API clients, converters, and services
9
+ - **@jlcpcb/cli**: Interactive terminal UI for component search and library management
10
+ - **@jlcpcb/mcp**: MCP server for Claude Desktop/Code integration
package/README.md ADDED
@@ -0,0 +1,474 @@
1
+ # @jlcpcb/core
2
+
3
+ > **Unofficial package** - This is a community-maintained tool and is not affiliated with, endorsed by, or officially connected to JLCPCB, LCSC, or EasyEDA.
4
+
5
+ Core library for JLC/EasyEDA component sourcing and KiCad conversion. Provides API clients, symbol/footprint converters, and library management services.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ npm install @jlcpcb/core
11
+ # or
12
+ bun add @jlcpcb/core
13
+ ```
14
+
15
+ ## Quick Start
16
+
17
+ ```typescript
18
+ import {
19
+ createComponentService,
20
+ createLibraryService
21
+ } from '@jlcpcb/core';
22
+
23
+ // Search for components
24
+ const componentService = createComponentService();
25
+ const results = await componentService.search('STM32F103', {
26
+ limit: 10,
27
+ inStock: true,
28
+ basicOnly: true,
29
+ });
30
+
31
+ // Install to KiCad library
32
+ const libraryService = createLibraryService();
33
+ const result = await libraryService.install('C8734', {
34
+ include3d: true,
35
+ });
36
+
37
+ console.log(result.symbolRef); // "JLC-MCP-ICs:STM32F103C8T6"
38
+ console.log(result.footprintRef); // "Package_QFP:LQFP-48_7x7mm_P0.5mm"
39
+ ```
40
+
41
+ ## API Reference
42
+
43
+ ### Services
44
+
45
+ High-level APIs for common operations.
46
+
47
+ #### ComponentService
48
+
49
+ Search and fetch component data from LCSC/EasyEDA.
50
+
51
+ ```typescript
52
+ import { createComponentService } from '@jlcpcb/core';
53
+
54
+ const service = createComponentService();
55
+
56
+ // Search LCSC catalog
57
+ const results = await service.search('100nF 0402', {
58
+ limit: 20,
59
+ inStock: true,
60
+ basicOnly: true, // Only JLCPCB basic parts
61
+ source: 'lcsc', // 'lcsc' | 'easyeda-community' | 'all'
62
+ });
63
+
64
+ // Fetch full component data
65
+ const component = await service.fetch('C2040');
66
+
67
+ // Get component details with pin/pad counts
68
+ const details = await service.getDetails('C2040');
69
+
70
+ // Fetch from EasyEDA community library
71
+ const communityComponent = await service.fetchCommunity('uuid-here');
72
+ ```
73
+
74
+ **SearchOptions:**
75
+
76
+ | Option | Type | Default | Description |
77
+ |--------|------|---------|-------------|
78
+ | `limit` | `number` | `20` | Maximum results |
79
+ | `inStock` | `boolean` | `false` | Only in-stock parts |
80
+ | `basicOnly` | `boolean` | `false` | Only JLCPCB basic parts |
81
+ | `source` | `string` | `'lcsc'` | Search source |
82
+
83
+ #### LibraryService
84
+
85
+ Install components to KiCad libraries.
86
+
87
+ ```typescript
88
+ import { createLibraryService } from '@jlcpcb/core';
89
+
90
+ const lib = createLibraryService();
91
+
92
+ // Install component to global library
93
+ const result = await lib.install('C2040', {
94
+ include3d: true,
95
+ });
96
+
97
+ // Install to project-local library
98
+ const result = await lib.install('C2040', {
99
+ projectPath: '/path/to/kicad/project',
100
+ include3d: true,
101
+ });
102
+
103
+ // List installed components
104
+ const installed = await lib.listInstalled();
105
+
106
+ // Check library status
107
+ const status = await lib.getStatus();
108
+ // { installed: true, linked: true, kicadVersion: '9.0', path: '...' }
109
+
110
+ // Initialize/register global library tables
111
+ await lib.ensureGlobalTables();
112
+ ```
113
+
114
+ **InstallOptions:**
115
+
116
+ | Option | Type | Default | Description |
117
+ |--------|------|---------|-------------|
118
+ | `projectPath` | `string` | - | Project path for local install |
119
+ | `include3d` | `boolean` | `false` | Download 3D model |
120
+ | `force` | `boolean` | `false` | Regenerate if exists |
121
+
122
+ **InstallResult:**
123
+
124
+ ```typescript
125
+ interface InstallResult {
126
+ symbolRef: string; // "JLC-MCP-ICs:STM32F103C8T6"
127
+ footprintRef: string; // "Package_QFP:LQFP-48..."
128
+ symbolPath: string; // Absolute path to .kicad_sym
129
+ footprintPath?: string; // Path to .kicad_mod (if custom)
130
+ modelPath?: string; // Path to .step (if included)
131
+ symbolAction: 'created' | 'appended' | 'exists' | 'replaced';
132
+ footprintType: 'builtin' | 'custom';
133
+ validationData: {
134
+ pinCount: number;
135
+ padCount: number;
136
+ pinPadCountMatch: boolean;
137
+ hasPowerPins: boolean;
138
+ hasGroundPins: boolean;
139
+ };
140
+ }
141
+ ```
142
+
143
+ ### API Clients
144
+
145
+ Low-level clients for direct API access.
146
+
147
+ #### JLCClient
148
+
149
+ Search JLCPCB/LCSC catalog.
150
+
151
+ ```typescript
152
+ import { jlcClient } from '@jlcpcb/core';
153
+
154
+ // Search components
155
+ const results = await jlcClient.search('STM32F103', {
156
+ limit: 10,
157
+ page: 1,
158
+ inStock: true,
159
+ basicOnly: true,
160
+ });
161
+
162
+ // Get current stock and pricing
163
+ const stock = await jlcClient.getStock('C2040');
164
+ // { stock: 50000, priceTiers: [{ qty: 1, price: 0.15 }, ...] }
165
+
166
+ // Get detailed component info with attributes
167
+ const details = await jlcClient.getComponentDetails('C2040');
168
+ ```
169
+
170
+ #### EasyEDAClient
171
+
172
+ Fetch symbol/footprint data from EasyEDA.
173
+
174
+ ```typescript
175
+ import { easyedaClient } from '@jlcpcb/core';
176
+
177
+ // Get complete component data
178
+ const data = await easyedaClient.getComponentData('C2040');
179
+ // Returns: { info, symbol, footprint, model3d }
180
+
181
+ // Download 3D model
182
+ const modelBuffer = await easyedaClient.get3DModel('uuid', 'step');
183
+ // Returns: Buffer containing STEP file
184
+ ```
185
+
186
+ **EasyEDAComponentData:**
187
+
188
+ ```typescript
189
+ interface EasyEDAComponentData {
190
+ info: {
191
+ lcsc: string;
192
+ manufacturer: string;
193
+ mfrPart: string;
194
+ package: string;
195
+ datasheet: string;
196
+ description: string;
197
+ category: string;
198
+ };
199
+ symbol: {
200
+ pins: EasyEDAPin[];
201
+ rectangles: EasyEDASymbolRect[];
202
+ circles: EasyEDASymbolCircle[];
203
+ arcs: EasyEDASymbolArc[];
204
+ polylines: EasyEDASymbolPolyline[];
205
+ paths: EasyEDASymbolPath[];
206
+ };
207
+ footprint: {
208
+ pads: EasyEDAPad[];
209
+ tracks: EasyEDATrack[];
210
+ holes: EasyEDAHole[];
211
+ circles: EasyEDACircle[];
212
+ vias: EasyEDAVia[];
213
+ solidRegions: EasyEDASolidRegion[];
214
+ };
215
+ model3d?: EasyEDA3DModel;
216
+ }
217
+ ```
218
+
219
+ #### EasyEDACommunityClient
220
+
221
+ Search user-contributed components.
222
+
223
+ ```typescript
224
+ import { easyedaCommunityClient } from '@jlcpcb/core';
225
+
226
+ // Search community library
227
+ const results = await easyedaCommunityClient.search({
228
+ query: 'XIAO RP2040',
229
+ limit: 10,
230
+ });
231
+
232
+ // Get full component by UUID
233
+ const component = await easyedaCommunityClient.getComponent('uuid');
234
+
235
+ // Download 3D model
236
+ const model = await easyedaCommunityClient.get3DModel('uuid', 'step');
237
+ ```
238
+
239
+ ### Converters
240
+
241
+ Convert EasyEDA format to KiCad S-expression format.
242
+
243
+ #### SymbolConverter
244
+
245
+ ```typescript
246
+ import { symbolConverter } from '@jlcpcb/core';
247
+
248
+ // Generate complete KiCad symbol library
249
+ const kicadSym = symbolConverter.convert(componentData, {
250
+ libraryName: 'MyLibrary',
251
+ includeDatasheet: true,
252
+ });
253
+
254
+ // Generate symbol entry only (for appending)
255
+ const entry = symbolConverter.convertToSymbolEntry(componentData);
256
+
257
+ // Append to existing library
258
+ const updated = symbolConverter.appendToLibrary(existingContent, componentData);
259
+
260
+ // Replace symbol in library
261
+ const replaced = symbolConverter.replaceInLibrary(existingContent, componentData);
262
+
263
+ // Check if symbol exists
264
+ const exists = symbolConverter.symbolExistsInLibrary(content, 'STM32F103C8T6');
265
+
266
+ // Get symbol name from component
267
+ const name = symbolConverter.getSymbolName(componentData);
268
+ ```
269
+
270
+ #### FootprintConverter
271
+
272
+ ```typescript
273
+ import { footprintConverter } from '@jlcpcb/core';
274
+
275
+ // Generate KiCad footprint file
276
+ const kicadMod = footprintConverter.convert(componentData, {
277
+ footprintName: 'LQFP-48_Custom',
278
+ include3dModel: true,
279
+ modelPath: '${KICAD9_3RD_PARTY}/jlc_mcp/3dmodels/...',
280
+ });
281
+
282
+ // Get footprint (returns reference for built-in or generates custom)
283
+ const result = footprintConverter.getFootprint(componentData);
284
+ // { type: 'builtin', ref: 'Package_QFP:LQFP-48_7x7mm_P0.5mm' }
285
+ // or
286
+ // { type: 'custom', content: '(footprint ...)' }
287
+ ```
288
+
289
+ ### Utilities
290
+
291
+ #### CategoryRouter
292
+
293
+ Route components to category-based libraries.
294
+
295
+ ```typescript
296
+ import { categoryRouter } from '@jlcpcb/core';
297
+
298
+ // Determine library category from component
299
+ const category = categoryRouter.getLibraryCategory('R', 'Resistors', '100k 0603');
300
+ // 'Resistors'
301
+
302
+ // Get library filename
303
+ const filename = categoryRouter.getLibraryFilename('Resistors');
304
+ // 'JLC-MCP-Resistors.kicad_sym'
305
+
306
+ // Get full symbol reference
307
+ const ref = categoryRouter.getSymbolReference('ICs', 'STM32F103C8T6');
308
+ // 'JLC-MCP-ICs:STM32F103C8T6'
309
+
310
+ // Get footprint reference
311
+ const fpRef = categoryRouter.getFootprintReference('LQFP-48_Custom');
312
+ // 'JLC-MCP:LQFP-48_Custom'
313
+
314
+ // List all categories
315
+ const categories = categoryRouter.getAllCategories();
316
+ // ['Resistors', 'Capacitors', 'Inductors', 'Diodes', 'Transistors', ...]
317
+ ```
318
+
319
+ **Categories:** Resistors, Capacitors, Inductors, Diodes, Crystals, Transistors, MCUs, Memory, Sensors, Interface, Power, Optocouplers, Connectors, ICs, Misc
320
+
321
+ #### FootprintMapper
322
+
323
+ Map package names to KiCad built-in footprints.
324
+
325
+ ```typescript
326
+ import { footprintMapper } from '@jlcpcb/core';
327
+
328
+ // Map package to KiCad footprint
329
+ const fp = footprintMapper.mapToKicadFootprint('0603');
330
+ // 'Resistor_SMD:R_0603_1608Metric'
331
+
332
+ const fp2 = footprintMapper.mapToKicadFootprint('SOIC-8');
333
+ // 'Package_SO:SOIC-8_3.9x4.9mm_P1.27mm'
334
+
335
+ // Check if standard passive
336
+ const isStandard = footprintMapper.isStandardPassive('0805');
337
+ // true
338
+
339
+ // Get reference with category context
340
+ const ref = footprintMapper.getKicadFootprintRef('SOT-23', 'Transistors');
341
+ // 'Package_TO_SOT_SMD:SOT-23'
342
+ ```
343
+
344
+ **Supported Packages:**
345
+ - SMD sizes: 0201, 0402, 0603, 0805, 1206, 1210, 1812, 2010, 2512
346
+ - SOIC: 8, 14, 16, 16W, 20, 24, 28-pin
347
+ - TSSOP: 8, 14, 16, 20, 24, 28-pin
348
+ - SOT: SOT-23, SOT-89, SOT-223
349
+ - SOD: SOD-123, SOD-123F
350
+ - QFP/LQFP: 32, 48, 64, 100-pin
351
+ - BGA: Various pitch/ball counts
352
+
353
+ #### ValueNormalizer
354
+
355
+ Extract and normalize component values.
356
+
357
+ ```typescript
358
+ import { valueNormalizer } from '@jlcpcb/core';
359
+
360
+ // Normalize component value
361
+ const value = valueNormalizer.normalizeValue('100nF 10% 50V X7R');
362
+ // '100nF'
363
+
364
+ // Detect component type
365
+ const type = valueNormalizer.detectComponentType('10k 0603 1%');
366
+ // 'resistor'
367
+
368
+ // Extract display value
369
+ const display = valueNormalizer.extractDisplayValue('100uF 16V Electrolytic');
370
+ // '100uF 16V'
371
+ ```
372
+
373
+ ## Types
374
+
375
+ Key TypeScript types exported from `@jlcpcb/core/types`:
376
+
377
+ ```typescript
378
+ import type {
379
+ // Component types
380
+ Component,
381
+ ComponentSearchResult,
382
+ ComponentDetails,
383
+ PriceTier,
384
+
385
+ // EasyEDA types
386
+ EasyEDAComponentData,
387
+ EasyEDAPin,
388
+ EasyEDAPad,
389
+ EasyEDASymbolRect,
390
+ EasyEDASymbolCircle,
391
+ EasyEDASymbolArc,
392
+
393
+ // Installation types
394
+ InstallResult,
395
+ InstallOptions,
396
+ LibraryStatus,
397
+
398
+ // Search types
399
+ SearchOptions,
400
+ SearchResult,
401
+ } from '@jlcpcb/core/types';
402
+ ```
403
+
404
+ ## Architecture
405
+
406
+ ### Data Flow
407
+
408
+ ```
409
+ LCSC Part Number (e.g., C2040)
410
+
411
+
412
+ ┌───────────────────────────────────┐
413
+ │ JLCClient / EasyEDAClient │ Fetch component data
414
+ └───────────────────────────────────┘
415
+
416
+
417
+ ┌───────────────────────────────────┐
418
+ │ SymbolConverter │ Convert to KiCad S-expression
419
+ └───────────────────────────────────┘
420
+
421
+
422
+ ┌───────────────────────────────────┐
423
+ │ FootprintMapper / Converter │ Map to built-in or generate
424
+ └───────────────────────────────────┘
425
+
426
+
427
+ ┌───────────────────────────────────┐
428
+ │ CategoryRouter │ Route to category library
429
+ └───────────────────────────────────┘
430
+
431
+
432
+ ┌───────────────────────────────────┐
433
+ │ LibraryService │ Write files, update tables
434
+ └───────────────────────────────────┘
435
+ ```
436
+
437
+ ### Library Organization
438
+
439
+ Components are organized into category-based symbol libraries:
440
+
441
+ ```
442
+ ~/Documents/KiCad/9.0/3rdparty/jlc_mcp/
443
+ ├── symbols/
444
+ │ ├── JLC-MCP-Resistors.kicad_sym
445
+ │ ├── JLC-MCP-Capacitors.kicad_sym
446
+ │ ├── JLC-MCP-ICs.kicad_sym
447
+ │ └── ...
448
+ ├── footprints/
449
+ │ └── JLC-MCP.pretty/
450
+ │ └── [custom footprints]
451
+ └── 3dmodels/
452
+ └── JLC-MCP.3dshapes/
453
+ └── [STEP files]
454
+ ```
455
+
456
+ ### Hybrid Footprint Strategy
457
+
458
+ - **Standard packages** (0603, SOIC-8, etc.) use KiCad's built-in footprint library
459
+ - **Non-standard packages** get custom footprints generated in `JLC-MCP.pretty/`
460
+
461
+ This keeps library size small while ensuring full compatibility.
462
+
463
+ ## Development
464
+
465
+ ```bash
466
+ bun run dev # Watch mode
467
+ bun run build # Build to ./dist
468
+ bun run test # Run tests
469
+ bun run typecheck # Type checking
470
+ ```
471
+
472
+ ## License
473
+
474
+ MIT
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@jlcpcb/core",
3
+ "version": "0.1.0",
4
+ "private": false,
5
+ "type": "module",
6
+ "description": "Core library for JLC/EasyEDA component sourcing and KiCad conversion",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/l3wi/jlc-cli.git",
10
+ "directory": "packages/jlc-core"
11
+ },
12
+ "publishConfig": {
13
+ "access": "public"
14
+ },
15
+ "main": "./dist/index.js",
16
+ "types": "./dist/index.d.ts",
17
+ "exports": {
18
+ ".": "./dist/index.js",
19
+ "./services": "./dist/services/index.js",
20
+ "./api": "./dist/api/index.js",
21
+ "./converter": "./dist/converter/index.js",
22
+ "./types": "./dist/types/index.js"
23
+ },
24
+ "scripts": {
25
+ "build": "tsc && bun build ./src/index.ts --outdir ./dist --target node",
26
+ "dev": "bun --watch build",
27
+ "typecheck": "tsc --noEmit",
28
+ "test": "bun test",
29
+ "clean": "rm -rf dist"
30
+ },
31
+ "keywords": [
32
+ "jlcpcb",
33
+ "jlc",
34
+ "easyeda",
35
+ "kicad",
36
+ "electronics",
37
+ "components",
38
+ "pcb"
39
+ ],
40
+ "author": "",
41
+ "license": "MIT",
42
+ "dependencies": {
43
+ "zod": "^3.22.0"
44
+ },
45
+ "devDependencies": {
46
+ "@types/node": "^20.0.0"
47
+ }
48
+ }