@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
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Shared EasyEDA parsing utilities
3
+ *
4
+ * This module consolidates all EasyEDA parsing logic used by both
5
+ * the LCSC API client and EasyEDA Community API client.
6
+ */
7
+
8
+ // HTTP client
9
+ export { fetchWithCurlFallback, type FetchOptions } from './http-client.js';
10
+
11
+ // Utility functions
12
+ export { parseBool, safeParseFloat, safeParseInt } from './utils.js';
13
+
14
+ // Shape parsers - Symbol
15
+ export {
16
+ parseSymbolPin,
17
+ parseSymbolRect,
18
+ parseSymbolCircle,
19
+ parseSymbolEllipse,
20
+ parseSymbolArc,
21
+ parseSymbolPolyline,
22
+ parseSymbolPolygon,
23
+ parseSymbolPath,
24
+ parseSymbolShapes,
25
+ } from './easyeda-shapes.js';
26
+
27
+ // Shape parsers - Footprint
28
+ export {
29
+ parsePad,
30
+ parseTrack,
31
+ parseHole,
32
+ parseCircle,
33
+ parseArc,
34
+ parseRect,
35
+ parseVia,
36
+ parseText,
37
+ parseFootprintShapes,
38
+ } from './easyeda-shapes.js';
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Shared parsing utilities for EasyEDA data
3
+ */
4
+
5
+ /**
6
+ * Parse boolean from EasyEDA format
7
+ * Empty string = false, "0" = false, any other value = true
8
+ */
9
+ export function parseBool(value: string | undefined): boolean {
10
+ return value !== undefined && value !== '' && value !== '0';
11
+ }
12
+
13
+ /**
14
+ * Safely parse float with default value
15
+ */
16
+ export function safeParseFloat(value: string | undefined, defaultValue = 0): number {
17
+ if (value === undefined || value === '') return defaultValue;
18
+ const parsed = parseFloat(value);
19
+ return isNaN(parsed) ? defaultValue : parsed;
20
+ }
21
+
22
+ /**
23
+ * Safely parse int with default value
24
+ */
25
+ export function safeParseInt(value: string | undefined, defaultValue = 0): number {
26
+ if (value === undefined || value === '') return defaultValue;
27
+ const parsed = parseInt(value, 10);
28
+ return isNaN(parsed) ? defaultValue : parsed;
29
+ }
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Component Service
3
+ * High-level API for searching and fetching components
4
+ */
5
+
6
+ import type { ComponentSearchResult, EasyEDAComponentData, EasyEDACommunityComponent } from '../types/index.js';
7
+ import { jlcClient } from '../api/jlc.js';
8
+ import { easyedaClient } from '../api/easyeda.js';
9
+ import { easyedaCommunityClient } from '../api/easyeda-community.js';
10
+
11
+ export interface SearchOptions {
12
+ limit?: number;
13
+ inStock?: boolean;
14
+ basicOnly?: boolean;
15
+ source?: 'lcsc' | 'easyeda-community' | 'all';
16
+ }
17
+
18
+ export interface ComponentDetails {
19
+ lcscId: string;
20
+ name: string;
21
+ manufacturer: string;
22
+ description: string;
23
+ category: string;
24
+ package: string;
25
+ pinCount: number;
26
+ padCount: number;
27
+ has3DModel: boolean;
28
+ datasheet?: string;
29
+ }
30
+
31
+ export interface ComponentService {
32
+ search(query: string, options?: SearchOptions): Promise<ComponentSearchResult[]>;
33
+ fetch(id: string): Promise<EasyEDAComponentData | null>;
34
+ fetchCommunity(uuid: string): Promise<EasyEDACommunityComponent | null>;
35
+ getDetails(lcscId: string): Promise<ComponentDetails>;
36
+ }
37
+
38
+ /**
39
+ * Check if an ID is an LCSC part number (starts with C followed by digits)
40
+ */
41
+ function isLcscId(id: string): boolean {
42
+ return /^C\d+$/.test(id);
43
+ }
44
+
45
+ export function createComponentService(): ComponentService {
46
+ return {
47
+ async search(query: string, options: SearchOptions = {}): Promise<ComponentSearchResult[]> {
48
+ const { source = 'lcsc', limit = 20, inStock, basicOnly } = options;
49
+
50
+ if (source === 'easyeda-community') {
51
+ const results = await easyedaCommunityClient.search({
52
+ query,
53
+ limit,
54
+ });
55
+ return results.map(r => ({
56
+ lcscId: r.uuid,
57
+ name: r.title,
58
+ manufacturer: r.owner?.nickname || 'Community',
59
+ description: r.description || '',
60
+ package: r.package || '',
61
+ stock: 0,
62
+ }));
63
+ }
64
+
65
+ return jlcClient.search(query, { limit, inStock, basicOnly });
66
+ },
67
+
68
+ async fetch(id: string): Promise<EasyEDAComponentData | null> {
69
+ if (isLcscId(id)) {
70
+ return easyedaClient.getComponentData(id);
71
+ }
72
+ // For community components, caller should use fetchCommunity and adapt
73
+ return null;
74
+ },
75
+
76
+ async fetchCommunity(uuid: string): Promise<EasyEDACommunityComponent | null> {
77
+ return easyedaCommunityClient.getComponent(uuid);
78
+ },
79
+
80
+ async getDetails(lcscId: string): Promise<ComponentDetails> {
81
+ const component = await easyedaClient.getComponentData(lcscId);
82
+ if (!component) {
83
+ throw new Error(`Component ${lcscId} not found`);
84
+ }
85
+
86
+ return {
87
+ lcscId,
88
+ name: component.info.name,
89
+ manufacturer: component.info.manufacturer || '',
90
+ description: component.info.description || '',
91
+ category: component.info.category || '',
92
+ package: component.info.package || '',
93
+ pinCount: component.symbol?.pins?.length || 0,
94
+ padCount: component.footprint?.pads?.length || 0,
95
+ has3DModel: !!component.model3d,
96
+ datasheet: component.info.datasheet,
97
+ };
98
+ },
99
+ };
100
+ }
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Fix Service
3
+ * High-level API for applying pin corrections to components
4
+ */
5
+
6
+ import type { LibraryCategory } from '../converter/category-router.js';
7
+
8
+ export interface PinCorrection {
9
+ action: 'modify' | 'swap' | 'add' | 'remove';
10
+ pinNumber?: string;
11
+ newName?: string;
12
+ newType?: string;
13
+ swapWith?: string;
14
+ addPin?: {
15
+ number: string;
16
+ name: string;
17
+ type: string;
18
+ };
19
+ }
20
+
21
+ export interface FixOptions {
22
+ projectPath?: string;
23
+ force?: boolean;
24
+ }
25
+
26
+ export interface FixResult {
27
+ success: boolean;
28
+ id: string;
29
+ category: LibraryCategory;
30
+ symbolRef: string;
31
+ footprintRef: string;
32
+ correctionsApplied: number;
33
+ files: {
34
+ symbolLibrary: string;
35
+ footprint?: string;
36
+ };
37
+ }
38
+
39
+ export interface FixService {
40
+ fix(lcscId: string, corrections: { pins?: PinCorrection[] }, options?: FixOptions): Promise<FixResult>;
41
+ }
42
+
43
+ export function createFixService(): FixService {
44
+ return {
45
+ async fix(_lcscId: string, _corrections: { pins?: PinCorrection[] }, _options: FixOptions = {}): Promise<FixResult> {
46
+ // TODO: Implement by re-fetching component, applying corrections, and regenerating
47
+ throw new Error('Fix service not yet implemented');
48
+ },
49
+ };
50
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * High-level services for jlc-core
3
+ * Provides a clean API for common operations
4
+ */
5
+
6
+ // Services will be implemented after core files are validated
7
+ export { createComponentService, type ComponentService, type SearchOptions, type ComponentDetails } from './component-service.js';
8
+ export { createLibraryService, type LibraryService, type InstallOptions, type InstallResult, type InstalledComponent, type ListOptions, type LibraryStatus } from './library-service.js';
9
+ export { createFixService, type FixService, type FixOptions, type FixResult } from './fix-service.js';