@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.
- package/CHANGELOG.md +10 -0
- package/README.md +474 -0
- package/package.json +48 -0
- package/src/api/easyeda-community.ts +259 -0
- package/src/api/easyeda.ts +153 -0
- package/src/api/index.ts +7 -0
- package/src/api/jlc.ts +185 -0
- package/src/constants/design-rules.ts +119 -0
- package/src/constants/footprints.ts +68 -0
- package/src/constants/index.ts +7 -0
- package/src/constants/kicad.ts +147 -0
- package/src/converter/category-router.ts +638 -0
- package/src/converter/footprint-mapper.ts +236 -0
- package/src/converter/footprint.ts +949 -0
- package/src/converter/global-lib-table.ts +394 -0
- package/src/converter/index.ts +46 -0
- package/src/converter/lib-table.ts +181 -0
- package/src/converter/svg-arc.ts +179 -0
- package/src/converter/symbol-templates.ts +214 -0
- package/src/converter/symbol.ts +1682 -0
- package/src/converter/value-normalizer.ts +262 -0
- package/src/index.ts +25 -0
- package/src/parsers/easyeda-shapes.ts +628 -0
- package/src/parsers/http-client.ts +96 -0
- package/src/parsers/index.ts +38 -0
- package/src/parsers/utils.ts +29 -0
- package/src/services/component-service.ts +100 -0
- package/src/services/fix-service.ts +50 -0
- package/src/services/index.ts +9 -0
- package/src/services/library-service.ts +696 -0
- package/src/types/component.ts +61 -0
- package/src/types/easyeda-community.ts +78 -0
- package/src/types/easyeda.ts +356 -0
- package/src/types/index.ts +12 -0
- package/src/types/jlc.ts +84 -0
- package/src/types/kicad.ts +136 -0
- package/src/types/mcp.ts +77 -0
- package/src/types/project.ts +60 -0
- package/src/utils/conversion.ts +104 -0
- package/src/utils/file-system.ts +143 -0
- package/src/utils/index.ts +8 -0
- package/src/utils/logger.ts +96 -0
- package/src/utils/validation.ts +110 -0
- package/tsconfig.json +9 -0
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Component Value Normalizer
|
|
3
|
+
* Extracts and normalizes component values from descriptions
|
|
4
|
+
* "16k Ohm ±1% 0.1W" → "16k"
|
|
5
|
+
* "100nF 50V X7R" → "100n/50V"
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export type ComponentType = 'resistor' | 'capacitor' | 'inductor' | 'diode' | 'transistor' | 'ic' | 'other';
|
|
9
|
+
|
|
10
|
+
export interface NormalizedValue {
|
|
11
|
+
displayValue: string; // For symbol Value property
|
|
12
|
+
originalValue: string; // Keep for Description
|
|
13
|
+
params?: {
|
|
14
|
+
value?: string; // Core value (e.g., "16k", "100n")
|
|
15
|
+
tolerance?: string; // e.g., "1%"
|
|
16
|
+
voltage?: string; // e.g., "50V"
|
|
17
|
+
power?: string; // e.g., "0.25W"
|
|
18
|
+
current?: string; // e.g., "2A"
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Regex patterns for value extraction
|
|
23
|
+
const PATTERNS = {
|
|
24
|
+
// Resistors: Match value with optional multiplier and unit
|
|
25
|
+
// "16k", "16kOhm", "16K OHM", "16000", "4.7k", "0R1" (0.1 ohm)
|
|
26
|
+
resistor: /(\d+(?:\.\d+)?)\s*([kKmMgGrR]?)\s*(?:ohm|Ohm|OHM|Ω|R)?/i,
|
|
27
|
+
|
|
28
|
+
// Capacitors: Match value with unit and optional voltage
|
|
29
|
+
// "100nF 50V", "10uF", "100pF", "1000uF/16V"
|
|
30
|
+
capacitor: /(\d+(?:\.\d+)?)\s*([pnuμmM]?)[Ff]?\s*(?:[\/\s]*(\d+)\s*[Vv])?/i,
|
|
31
|
+
|
|
32
|
+
// Inductors: Match value with unit and optional current
|
|
33
|
+
// "10uH 2A", "100nH", "4.7mH"
|
|
34
|
+
inductor: /(\d+(?:\.\d+)?)\s*([nμumM]?)[Hh]\s*(?:[\/\s]*(\d+(?:\.\d+)?)\s*[Aa])?/i,
|
|
35
|
+
|
|
36
|
+
// Voltage rating extraction
|
|
37
|
+
voltage: /(\d+(?:\.\d+)?)\s*[Vv]/,
|
|
38
|
+
|
|
39
|
+
// Tolerance extraction
|
|
40
|
+
tolerance: /[±]?\s*(\d+(?:\.\d+)?)\s*%/,
|
|
41
|
+
|
|
42
|
+
// Power rating extraction
|
|
43
|
+
power: /(\d+(?:\.\d+)?)\s*[Ww]/,
|
|
44
|
+
|
|
45
|
+
// Current rating extraction
|
|
46
|
+
current: /(\d+(?:\.\d+)?)\s*[Aa]/,
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
// Multiplier normalization
|
|
50
|
+
const MULTIPLIER_MAP: Record<string, string> = {
|
|
51
|
+
'': '',
|
|
52
|
+
'r': '', // 0R1 style (0.1 ohm)
|
|
53
|
+
'R': '',
|
|
54
|
+
'k': 'k',
|
|
55
|
+
'K': 'k',
|
|
56
|
+
'm': 'm', // milli for caps/inductors, mega for resistors (context dependent)
|
|
57
|
+
'M': 'M',
|
|
58
|
+
'g': 'G',
|
|
59
|
+
'G': 'G',
|
|
60
|
+
'p': 'p',
|
|
61
|
+
'n': 'n',
|
|
62
|
+
'u': 'u',
|
|
63
|
+
'μ': 'u',
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Detect component type from prefix and category
|
|
68
|
+
*/
|
|
69
|
+
export function detectComponentType(prefix: string, category?: string): ComponentType {
|
|
70
|
+
const p = prefix.toUpperCase();
|
|
71
|
+
|
|
72
|
+
switch (p) {
|
|
73
|
+
case 'R':
|
|
74
|
+
return 'resistor';
|
|
75
|
+
case 'C':
|
|
76
|
+
return 'capacitor';
|
|
77
|
+
case 'L':
|
|
78
|
+
return 'inductor';
|
|
79
|
+
case 'D':
|
|
80
|
+
return 'diode';
|
|
81
|
+
case 'Q':
|
|
82
|
+
return 'transistor';
|
|
83
|
+
case 'U':
|
|
84
|
+
return 'ic';
|
|
85
|
+
default:
|
|
86
|
+
// Fallback to category-based detection
|
|
87
|
+
if (category) {
|
|
88
|
+
const cat = category.toLowerCase();
|
|
89
|
+
if (cat.includes('resistor')) return 'resistor';
|
|
90
|
+
if (cat.includes('capacitor')) return 'capacitor';
|
|
91
|
+
if (cat.includes('inductor')) return 'inductor';
|
|
92
|
+
if (cat.includes('diode')) return 'diode';
|
|
93
|
+
if (cat.includes('transistor')) return 'transistor';
|
|
94
|
+
if (cat.includes('ic') || cat.includes('microcontroller')) return 'ic';
|
|
95
|
+
}
|
|
96
|
+
return 'other';
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Normalize resistor value
|
|
102
|
+
*/
|
|
103
|
+
function normalizeResistor(description: string): NormalizedValue {
|
|
104
|
+
const match = description.match(PATTERNS.resistor);
|
|
105
|
+
|
|
106
|
+
if (!match) {
|
|
107
|
+
return { displayValue: description, originalValue: description };
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const [, value, multiplier] = match;
|
|
111
|
+
const normalizedMultiplier = MULTIPLIER_MAP[multiplier] || '';
|
|
112
|
+
|
|
113
|
+
// Handle "0R1" style notation (0.1 ohm)
|
|
114
|
+
if (multiplier.toLowerCase() === 'r') {
|
|
115
|
+
const numValue = parseFloat(value);
|
|
116
|
+
if (numValue === 0) {
|
|
117
|
+
// "0R1" = 0.1 ohm - extract the digit after R from original
|
|
118
|
+
const zeroRMatch = description.match(/0[rR](\d)/);
|
|
119
|
+
if (zeroRMatch) {
|
|
120
|
+
return {
|
|
121
|
+
displayValue: `0.${zeroRMatch[1]}`,
|
|
122
|
+
originalValue: description,
|
|
123
|
+
params: { value: `0.${zeroRMatch[1]}` },
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const displayValue = `${value}${normalizedMultiplier}`;
|
|
130
|
+
|
|
131
|
+
// Extract additional params
|
|
132
|
+
const toleranceMatch = description.match(PATTERNS.tolerance);
|
|
133
|
+
const powerMatch = description.match(PATTERNS.power);
|
|
134
|
+
|
|
135
|
+
return {
|
|
136
|
+
displayValue,
|
|
137
|
+
originalValue: description,
|
|
138
|
+
params: {
|
|
139
|
+
value: displayValue,
|
|
140
|
+
tolerance: toleranceMatch ? `${toleranceMatch[1]}%` : undefined,
|
|
141
|
+
power: powerMatch ? `${powerMatch[1]}W` : undefined,
|
|
142
|
+
},
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Normalize capacitor value
|
|
148
|
+
*/
|
|
149
|
+
function normalizeCapacitor(description: string): NormalizedValue {
|
|
150
|
+
const match = description.match(PATTERNS.capacitor);
|
|
151
|
+
|
|
152
|
+
if (!match) {
|
|
153
|
+
return { displayValue: description, originalValue: description };
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const [, value, unit, voltage] = match;
|
|
157
|
+
const normalizedUnit = MULTIPLIER_MAP[unit] || unit;
|
|
158
|
+
|
|
159
|
+
let displayValue = `${value}${normalizedUnit}`;
|
|
160
|
+
|
|
161
|
+
// Add voltage if present
|
|
162
|
+
if (voltage) {
|
|
163
|
+
displayValue += `/${voltage}V`;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return {
|
|
167
|
+
displayValue,
|
|
168
|
+
originalValue: description,
|
|
169
|
+
params: {
|
|
170
|
+
value: `${value}${normalizedUnit}`,
|
|
171
|
+
voltage: voltage ? `${voltage}V` : undefined,
|
|
172
|
+
},
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Normalize inductor value
|
|
178
|
+
*/
|
|
179
|
+
function normalizeInductor(description: string): NormalizedValue {
|
|
180
|
+
const match = description.match(PATTERNS.inductor);
|
|
181
|
+
|
|
182
|
+
if (!match) {
|
|
183
|
+
return { displayValue: description, originalValue: description };
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
const [, value, unit, current] = match;
|
|
187
|
+
const normalizedUnit = MULTIPLIER_MAP[unit] || unit;
|
|
188
|
+
|
|
189
|
+
let displayValue = `${value}${normalizedUnit}H`;
|
|
190
|
+
|
|
191
|
+
// Add current if present
|
|
192
|
+
if (current) {
|
|
193
|
+
displayValue += `/${current}A`;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
return {
|
|
197
|
+
displayValue,
|
|
198
|
+
originalValue: description,
|
|
199
|
+
params: {
|
|
200
|
+
value: `${value}${normalizedUnit}H`,
|
|
201
|
+
current: current ? `${current}A` : undefined,
|
|
202
|
+
},
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Main normalization function
|
|
208
|
+
* Returns normalized value based on component type
|
|
209
|
+
*/
|
|
210
|
+
export function normalizeValue(
|
|
211
|
+
description: string,
|
|
212
|
+
type: ComponentType
|
|
213
|
+
): NormalizedValue {
|
|
214
|
+
// Clean input
|
|
215
|
+
const cleaned = description.trim();
|
|
216
|
+
|
|
217
|
+
// Skip normalization for ICs and complex parts - keep original name
|
|
218
|
+
if (type === 'ic' || type === 'other') {
|
|
219
|
+
return { displayValue: cleaned, originalValue: cleaned };
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
switch (type) {
|
|
223
|
+
case 'resistor':
|
|
224
|
+
return normalizeResistor(cleaned);
|
|
225
|
+
case 'capacitor':
|
|
226
|
+
return normalizeCapacitor(cleaned);
|
|
227
|
+
case 'inductor':
|
|
228
|
+
return normalizeInductor(cleaned);
|
|
229
|
+
case 'diode':
|
|
230
|
+
case 'transistor':
|
|
231
|
+
// For diodes and transistors, keep the part number but clean it up
|
|
232
|
+
// Remove common prefixes/suffixes that aren't part of the name
|
|
233
|
+
return { displayValue: cleaned, originalValue: cleaned };
|
|
234
|
+
default:
|
|
235
|
+
return { displayValue: cleaned, originalValue: cleaned };
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Extract value from component name or description
|
|
241
|
+
* Tries multiple strategies to find a meaningful value
|
|
242
|
+
*/
|
|
243
|
+
export function extractDisplayValue(
|
|
244
|
+
name: string,
|
|
245
|
+
description: string | undefined,
|
|
246
|
+
prefix: string,
|
|
247
|
+
category?: string
|
|
248
|
+
): string {
|
|
249
|
+
const type = detectComponentType(prefix, category);
|
|
250
|
+
|
|
251
|
+
// For passives, prefer to extract from description which has more detail
|
|
252
|
+
if (description && (type === 'resistor' || type === 'capacitor' || type === 'inductor')) {
|
|
253
|
+
const normalized = normalizeValue(description, type);
|
|
254
|
+
if (normalized.displayValue !== description) {
|
|
255
|
+
return normalized.displayValue;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// Fallback to name
|
|
260
|
+
const normalized = normalizeValue(name, type);
|
|
261
|
+
return normalized.displayValue;
|
|
262
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* jlc-core
|
|
3
|
+
* Core library for JLC/EasyEDA component sourcing and KiCad conversion
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// Services (high-level API)
|
|
7
|
+
export * from './services/index.js';
|
|
8
|
+
|
|
9
|
+
// API clients (low-level)
|
|
10
|
+
export * from './api/index.js';
|
|
11
|
+
|
|
12
|
+
// Converters (low-level)
|
|
13
|
+
export * from './converter/index.js';
|
|
14
|
+
|
|
15
|
+
// Types
|
|
16
|
+
export * from './types/index.js';
|
|
17
|
+
|
|
18
|
+
// Utils
|
|
19
|
+
export * from './utils/index.js';
|
|
20
|
+
|
|
21
|
+
// Constants
|
|
22
|
+
export * from './constants/index.js';
|
|
23
|
+
|
|
24
|
+
// Parsers
|
|
25
|
+
export * from './parsers/index.js';
|