@tscircuit/parts-engine 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.
- package/bun.lock +2 -2
- package/lib/jlc-parts-engine.ts +112 -2
- package/package.json +2 -2
- package/tests/jlc-parts-engine.test.ts +261 -0
package/bun.lock
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"@biomejs/biome": "^1.9.4",
|
|
8
8
|
"@tscircuit/props": "^0.0.172",
|
|
9
9
|
"@types/bun": "latest",
|
|
10
|
-
"circuit-json": "^0.0.
|
|
10
|
+
"circuit-json": "^0.0.180",
|
|
11
11
|
"tsup": "^8.4.0",
|
|
12
12
|
},
|
|
13
13
|
"peerDependencies": {
|
|
@@ -172,7 +172,7 @@
|
|
|
172
172
|
|
|
173
173
|
"chokidar": ["chokidar@4.0.3", "", { "dependencies": { "readdirp": "^4.0.1" } }, "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA=="],
|
|
174
174
|
|
|
175
|
-
"circuit-json": ["circuit-json@0.0.
|
|
175
|
+
"circuit-json": ["circuit-json@0.0.180", "", { "dependencies": { "nanoid": "^5.0.7", "zod": "^3.23.6" } }, "sha512-kKaMOWbrymFyg3NoSCadaAdwBBE20p0xNdO9AISLkEytWgvAQCP2Mfb4n99nTYxVIhdD8inPpf5Hzw4xQfSRtA=="],
|
|
176
176
|
|
|
177
177
|
"color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="],
|
|
178
178
|
|
package/lib/jlc-parts-engine.ts
CHANGED
|
@@ -54,9 +54,9 @@ export const jlcPartsEngine: PartsEngine = {
|
|
|
54
54
|
sourceComponent.type === "source_component" &&
|
|
55
55
|
sourceComponent.ftype === "simple_pin_header"
|
|
56
56
|
) {
|
|
57
|
-
let pitch
|
|
57
|
+
let pitch: number | undefined
|
|
58
58
|
if (footprinterString?.includes("_p")) {
|
|
59
|
-
pitch = footprinterString.split("_p")[1]
|
|
59
|
+
pitch = Number(footprinterString.split("_p")[1])
|
|
60
60
|
}
|
|
61
61
|
const { headers } = await getJlcPartsCached(
|
|
62
62
|
"headers",
|
|
@@ -74,6 +74,116 @@ export const jlcPartsEngine: PartsEngine = {
|
|
|
74
74
|
return {
|
|
75
75
|
jlcpcb: headers.map((h: any) => `C${h.lcsc}`).slice(0, 3),
|
|
76
76
|
}
|
|
77
|
+
} else if (
|
|
78
|
+
sourceComponent.type === "source_component" &&
|
|
79
|
+
sourceComponent.ftype === "simple_potentiometer"
|
|
80
|
+
) {
|
|
81
|
+
const { potentiometers } = await getJlcPartsCached("potentiometers", {
|
|
82
|
+
resistance: sourceComponent.max_resistance,
|
|
83
|
+
package: footprinterString,
|
|
84
|
+
})
|
|
85
|
+
return {
|
|
86
|
+
jlcpcb: potentiometers.map((p: any) => `C${p.lcsc}`).slice(0, 3),
|
|
87
|
+
}
|
|
88
|
+
} else if (
|
|
89
|
+
sourceComponent.type === "source_component" &&
|
|
90
|
+
sourceComponent.ftype === "simple_diode"
|
|
91
|
+
) {
|
|
92
|
+
const { diodes } = await getJlcPartsCached("diodes", {
|
|
93
|
+
package: footprinterString,
|
|
94
|
+
})
|
|
95
|
+
return {
|
|
96
|
+
jlcpcb: diodes.map((d: any) => `C${d.lcsc}`).slice(0, 3),
|
|
97
|
+
}
|
|
98
|
+
} else if (
|
|
99
|
+
sourceComponent.type === "source_component" &&
|
|
100
|
+
sourceComponent.ftype === "simple_chip"
|
|
101
|
+
) {
|
|
102
|
+
const { chips } = await getJlcPartsCached("chips", {
|
|
103
|
+
package: footprinterString,
|
|
104
|
+
})
|
|
105
|
+
return {
|
|
106
|
+
jlcpcb: chips.map((c: any) => `C${c.lcsc}`).slice(0, 3),
|
|
107
|
+
}
|
|
108
|
+
} else if (
|
|
109
|
+
sourceComponent.type === "source_component" &&
|
|
110
|
+
sourceComponent.ftype === "simple_transistor"
|
|
111
|
+
) {
|
|
112
|
+
const { transistors } = await getJlcPartsCached("transistors", {
|
|
113
|
+
package: footprinterString,
|
|
114
|
+
transistor_type: sourceComponent.transistor_type,
|
|
115
|
+
})
|
|
116
|
+
return {
|
|
117
|
+
jlcpcb: transistors.map((t: any) => `C${t.lcsc}`).slice(0, 3),
|
|
118
|
+
}
|
|
119
|
+
} else if (
|
|
120
|
+
sourceComponent.type === "source_component" &&
|
|
121
|
+
sourceComponent.ftype === "simple_power_source"
|
|
122
|
+
) {
|
|
123
|
+
const { power_sources } = await getJlcPartsCached("power_sources", {
|
|
124
|
+
voltage: sourceComponent.voltage,
|
|
125
|
+
package: footprinterString,
|
|
126
|
+
})
|
|
127
|
+
return {
|
|
128
|
+
jlcpcb: power_sources.map((p: any) => `C${p.lcsc}`).slice(0, 3),
|
|
129
|
+
}
|
|
130
|
+
} else if (
|
|
131
|
+
sourceComponent.type === "source_component" &&
|
|
132
|
+
sourceComponent.ftype === "simple_inductor"
|
|
133
|
+
) {
|
|
134
|
+
const { inductors } = await getJlcPartsCached("inductors", {
|
|
135
|
+
inductance: sourceComponent.inductance,
|
|
136
|
+
package: footprinterString,
|
|
137
|
+
})
|
|
138
|
+
return {
|
|
139
|
+
jlcpcb: inductors.map((i: any) => `C${i.lcsc}`).slice(0, 3),
|
|
140
|
+
}
|
|
141
|
+
} else if (
|
|
142
|
+
sourceComponent.type === "source_component" &&
|
|
143
|
+
sourceComponent.ftype === "simple_crystal"
|
|
144
|
+
) {
|
|
145
|
+
const { crystals } = await getJlcPartsCached("crystals", {
|
|
146
|
+
frequency: sourceComponent.frequency,
|
|
147
|
+
load_capacitance: sourceComponent.load_capacitance,
|
|
148
|
+
package: footprinterString,
|
|
149
|
+
})
|
|
150
|
+
return {
|
|
151
|
+
jlcpcb: crystals.map((c: any) => `C${c.lcsc}`).slice(0, 3),
|
|
152
|
+
}
|
|
153
|
+
} else if (
|
|
154
|
+
sourceComponent.type === "source_component" &&
|
|
155
|
+
sourceComponent.ftype === "simple_mosfet"
|
|
156
|
+
) {
|
|
157
|
+
const { mosfets } = await getJlcPartsCached("mosfets", {
|
|
158
|
+
package: footprinterString,
|
|
159
|
+
mosfet_mode: sourceComponent.mosfet_mode,
|
|
160
|
+
channel_type: sourceComponent.channel_type,
|
|
161
|
+
})
|
|
162
|
+
return {
|
|
163
|
+
jlcpcb: mosfets.map((m: any) => `C${m.lcsc}`).slice(0, 3),
|
|
164
|
+
}
|
|
165
|
+
} else if (
|
|
166
|
+
sourceComponent.type === "source_component" &&
|
|
167
|
+
sourceComponent.ftype === "simple_resonator"
|
|
168
|
+
) {
|
|
169
|
+
const { resonators } = await getJlcPartsCached("resonators", {
|
|
170
|
+
frequency: sourceComponent.frequency,
|
|
171
|
+
package: footprinterString,
|
|
172
|
+
})
|
|
173
|
+
return {
|
|
174
|
+
jlcpcb: resonators.map((r: any) => `C${r.lcsc}`).slice(0, 3),
|
|
175
|
+
}
|
|
176
|
+
} else if (
|
|
177
|
+
sourceComponent.type === "source_component" &&
|
|
178
|
+
sourceComponent.ftype === "simple_switch"
|
|
179
|
+
) {
|
|
180
|
+
const { switches } = await getJlcPartsCached("switches", {
|
|
181
|
+
switch_type: sourceComponent.type,
|
|
182
|
+
package: footprinterString,
|
|
183
|
+
})
|
|
184
|
+
return {
|
|
185
|
+
jlcpcb: switches.map((s: any) => `C${s.lcsc}`).slice(0, 3),
|
|
186
|
+
}
|
|
77
187
|
}
|
|
78
188
|
return {}
|
|
79
189
|
},
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tscircuit/parts-engine",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"devDependencies": {
|
|
7
7
|
"@biomejs/biome": "^1.9.4",
|
|
8
8
|
"@tscircuit/props": "^0.0.172",
|
|
9
9
|
"@types/bun": "latest",
|
|
10
|
-
"circuit-json": "^0.0.
|
|
10
|
+
"circuit-json": "^0.0.180",
|
|
11
11
|
"tsup": "^8.4.0"
|
|
12
12
|
},
|
|
13
13
|
"scripts": {
|
|
@@ -19,6 +19,13 @@ describe("jlcPartsEngine", () => {
|
|
|
19
19
|
}),
|
|
20
20
|
} as Response
|
|
21
21
|
}
|
|
22
|
+
if (url.includes("/potentiometers/")) {
|
|
23
|
+
return {
|
|
24
|
+
json: async () => ({
|
|
25
|
+
potentiometers: [{ lcsc: "1234" }, { lcsc: "5678" }, { lcsc: "9012" }],
|
|
26
|
+
}),
|
|
27
|
+
} as Response
|
|
28
|
+
}
|
|
22
29
|
if (url.includes("/headers/")) {
|
|
23
30
|
return {
|
|
24
31
|
json: async () => ({
|
|
@@ -26,6 +33,69 @@ describe("jlcPartsEngine", () => {
|
|
|
26
33
|
}),
|
|
27
34
|
} as Response
|
|
28
35
|
}
|
|
36
|
+
if (url.includes("/diodes/")) {
|
|
37
|
+
return {
|
|
38
|
+
json: async () => ({
|
|
39
|
+
diodes: [{ lcsc: "4567" }, { lcsc: "8901" }, { lcsc: "2345" }],
|
|
40
|
+
}),
|
|
41
|
+
} as Response
|
|
42
|
+
}
|
|
43
|
+
if (url.includes("/chips/")) {
|
|
44
|
+
return {
|
|
45
|
+
json: async () => ({
|
|
46
|
+
chips: [{ lcsc: "5678" }, { lcsc: "9012" }, { lcsc: "3456" }],
|
|
47
|
+
}),
|
|
48
|
+
} as Response
|
|
49
|
+
}
|
|
50
|
+
if (url.includes("/transistors/")) {
|
|
51
|
+
return {
|
|
52
|
+
json: async () => ({
|
|
53
|
+
transistors: [{ lcsc: "6789" }, { lcsc: "0123" }, { lcsc: "4567" }],
|
|
54
|
+
}),
|
|
55
|
+
} as Response
|
|
56
|
+
}
|
|
57
|
+
if (url.includes("/power_sources/")) {
|
|
58
|
+
return {
|
|
59
|
+
json: async () => ({
|
|
60
|
+
power_sources: [{ lcsc: "7890" }, { lcsc: "1234" }, { lcsc: "5678" }],
|
|
61
|
+
}),
|
|
62
|
+
} as Response
|
|
63
|
+
}
|
|
64
|
+
if (url.includes("/inductors/")) {
|
|
65
|
+
return {
|
|
66
|
+
json: async () => ({
|
|
67
|
+
inductors: [{ lcsc: "8901" }, { lcsc: "2345" }, { lcsc: "6789" }],
|
|
68
|
+
}),
|
|
69
|
+
} as Response
|
|
70
|
+
}
|
|
71
|
+
if (url.includes("/crystals/")) {
|
|
72
|
+
return {
|
|
73
|
+
json: async () => ({
|
|
74
|
+
crystals: [{ lcsc: "9012" }, { lcsc: "3456" }, { lcsc: "7890" }],
|
|
75
|
+
}),
|
|
76
|
+
} as Response
|
|
77
|
+
}
|
|
78
|
+
if (url.includes("/mosfets/")) {
|
|
79
|
+
return {
|
|
80
|
+
json: async () => ({
|
|
81
|
+
mosfets: [{ lcsc: "0123" }, { lcsc: "4567" }, { lcsc: "8901" }],
|
|
82
|
+
}),
|
|
83
|
+
} as Response
|
|
84
|
+
}
|
|
85
|
+
if (url.includes("/resonators/")) {
|
|
86
|
+
return {
|
|
87
|
+
json: async () => ({
|
|
88
|
+
resonators: [{ lcsc: "1234" }, { lcsc: "5678" }, { lcsc: "9012" }],
|
|
89
|
+
}),
|
|
90
|
+
} as Response
|
|
91
|
+
}
|
|
92
|
+
if (url.includes("/switches/")) {
|
|
93
|
+
return {
|
|
94
|
+
json: async () => ({
|
|
95
|
+
switches: [{ lcsc: "2345" }, { lcsc: "6789" }, { lcsc: "0123" }],
|
|
96
|
+
}),
|
|
97
|
+
} as Response
|
|
98
|
+
}
|
|
29
99
|
return {} as Response
|
|
30
100
|
}) as unknown as typeof fetch
|
|
31
101
|
})
|
|
@@ -88,6 +158,197 @@ describe("jlcPartsEngine", () => {
|
|
|
88
158
|
})
|
|
89
159
|
})
|
|
90
160
|
|
|
161
|
+
// potentiometers
|
|
162
|
+
test("should find potentiometers", async () => {
|
|
163
|
+
const potentiometer: AnySourceComponent = {
|
|
164
|
+
type: "source_component",
|
|
165
|
+
ftype: "simple_potentiometer",
|
|
166
|
+
source_component_id: "source_component_0",
|
|
167
|
+
name: "P1",
|
|
168
|
+
max_resistance: 10000,
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const result = await jlcPartsEngine.findPart({
|
|
172
|
+
sourceComponent: potentiometer,
|
|
173
|
+
footprinterString: "10k",
|
|
174
|
+
})
|
|
175
|
+
|
|
176
|
+
expect(result).toEqual({
|
|
177
|
+
jlcpcb: ["C1234", "C5678", "C9012"],
|
|
178
|
+
})
|
|
179
|
+
})
|
|
180
|
+
|
|
181
|
+
test("should find diode parts", async () => {
|
|
182
|
+
const diode: AnySourceComponent = {
|
|
183
|
+
type: "source_component",
|
|
184
|
+
ftype: "simple_diode",
|
|
185
|
+
source_component_id: "source_component_0",
|
|
186
|
+
name: "D1",
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const result = await jlcPartsEngine.findPart({
|
|
190
|
+
sourceComponent: diode,
|
|
191
|
+
footprinterString: "SOD-123",
|
|
192
|
+
})
|
|
193
|
+
|
|
194
|
+
expect(result).toEqual({
|
|
195
|
+
jlcpcb: ["C4567", "C8901", "C2345"],
|
|
196
|
+
})
|
|
197
|
+
})
|
|
198
|
+
|
|
199
|
+
test("should find chip parts", async () => {
|
|
200
|
+
const chip: AnySourceComponent = {
|
|
201
|
+
type: "source_component",
|
|
202
|
+
ftype: "simple_chip",
|
|
203
|
+
source_component_id: "source_component_0",
|
|
204
|
+
name: "U1",
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
const result = await jlcPartsEngine.findPart({
|
|
208
|
+
sourceComponent: chip,
|
|
209
|
+
footprinterString: "SOIC-8",
|
|
210
|
+
})
|
|
211
|
+
|
|
212
|
+
expect(result).toEqual({
|
|
213
|
+
jlcpcb: ["C5678", "C9012", "C3456"],
|
|
214
|
+
})
|
|
215
|
+
})
|
|
216
|
+
|
|
217
|
+
test("should find transistor parts", async () => {
|
|
218
|
+
const transistor: AnySourceComponent = {
|
|
219
|
+
type: "source_component",
|
|
220
|
+
ftype: "simple_transistor",
|
|
221
|
+
transistor_type: "npn",
|
|
222
|
+
source_component_id: "source_component_0",
|
|
223
|
+
name: "Q1",
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
const result = await jlcPartsEngine.findPart({
|
|
227
|
+
sourceComponent: transistor,
|
|
228
|
+
footprinterString: "SOT-23",
|
|
229
|
+
})
|
|
230
|
+
|
|
231
|
+
expect(result).toEqual({
|
|
232
|
+
jlcpcb: ["C6789", "C0123", "C4567"],
|
|
233
|
+
})
|
|
234
|
+
})
|
|
235
|
+
|
|
236
|
+
test("should find power source parts", async () => {
|
|
237
|
+
const powerSource: AnySourceComponent = {
|
|
238
|
+
type: "source_component",
|
|
239
|
+
ftype: "simple_power_source",
|
|
240
|
+
voltage: 5,
|
|
241
|
+
source_component_id: "source_component_0",
|
|
242
|
+
name: "V1",
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
const result = await jlcPartsEngine.findPart({
|
|
246
|
+
sourceComponent: powerSource,
|
|
247
|
+
footprinterString: "SOT-223",
|
|
248
|
+
})
|
|
249
|
+
|
|
250
|
+
expect(result).toEqual({
|
|
251
|
+
jlcpcb: ["C7890", "C1234", "C5678"],
|
|
252
|
+
})
|
|
253
|
+
})
|
|
254
|
+
|
|
255
|
+
test("should find inductor parts", async () => {
|
|
256
|
+
const inductor: AnySourceComponent = {
|
|
257
|
+
type: "source_component",
|
|
258
|
+
ftype: "simple_inductor",
|
|
259
|
+
inductance: 100,
|
|
260
|
+
source_component_id: "source_component_0",
|
|
261
|
+
name: "L1",
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
const result = await jlcPartsEngine.findPart({
|
|
265
|
+
sourceComponent: inductor,
|
|
266
|
+
footprinterString: "0603",
|
|
267
|
+
})
|
|
268
|
+
|
|
269
|
+
expect(result).toEqual({
|
|
270
|
+
jlcpcb: ["C8901", "C2345", "C6789"],
|
|
271
|
+
})
|
|
272
|
+
})
|
|
273
|
+
|
|
274
|
+
test("should find crystal parts", async () => {
|
|
275
|
+
const crystal: AnySourceComponent = {
|
|
276
|
+
type: "source_component",
|
|
277
|
+
ftype: "simple_crystal",
|
|
278
|
+
frequency: 16000000,
|
|
279
|
+
load_capacitance: 20,
|
|
280
|
+
source_component_id: "source_component_0",
|
|
281
|
+
name: "X1",
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
const result = await jlcPartsEngine.findPart({
|
|
285
|
+
sourceComponent: crystal,
|
|
286
|
+
footprinterString: "HC-49S",
|
|
287
|
+
})
|
|
288
|
+
|
|
289
|
+
expect(result).toEqual({
|
|
290
|
+
jlcpcb: ["C9012", "C3456", "C7890"],
|
|
291
|
+
})
|
|
292
|
+
})
|
|
293
|
+
|
|
294
|
+
test("should find MOSFET parts", async () => {
|
|
295
|
+
const mosfet: AnySourceComponent = {
|
|
296
|
+
type: "source_component",
|
|
297
|
+
ftype: "simple_mosfet",
|
|
298
|
+
mosfet_mode: "enhancement",
|
|
299
|
+
channel_type: "n",
|
|
300
|
+
source_component_id: "source_component_0",
|
|
301
|
+
name: "M1",
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
const result = await jlcPartsEngine.findPart({
|
|
305
|
+
sourceComponent: mosfet,
|
|
306
|
+
footprinterString: "SOT-23",
|
|
307
|
+
})
|
|
308
|
+
|
|
309
|
+
expect(result).toEqual({
|
|
310
|
+
jlcpcb: ["C0123", "C4567", "C8901"],
|
|
311
|
+
})
|
|
312
|
+
})
|
|
313
|
+
|
|
314
|
+
test("should find resonator parts", async () => {
|
|
315
|
+
const resonator: AnySourceComponent = {
|
|
316
|
+
type: "source_component",
|
|
317
|
+
ftype: "simple_resonator",
|
|
318
|
+
frequency: 16000000,
|
|
319
|
+
load_capacitance: 20,
|
|
320
|
+
source_component_id: "source_component_0",
|
|
321
|
+
name: "Y1",
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
const result = await jlcPartsEngine.findPart({
|
|
325
|
+
sourceComponent: resonator,
|
|
326
|
+
footprinterString: "SMD",
|
|
327
|
+
})
|
|
328
|
+
|
|
329
|
+
expect(result).toEqual({
|
|
330
|
+
jlcpcb: ["C1234", "C5678", "C9012"],
|
|
331
|
+
})
|
|
332
|
+
})
|
|
333
|
+
|
|
334
|
+
test("should find switch parts", async () => {
|
|
335
|
+
const switch_: AnySourceComponent = {
|
|
336
|
+
type: "source_component",
|
|
337
|
+
ftype: "simple_switch",
|
|
338
|
+
source_component_id: "source_component_0",
|
|
339
|
+
name: "SW1",
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
const result = await jlcPartsEngine.findPart({
|
|
343
|
+
sourceComponent: switch_,
|
|
344
|
+
footprinterString: "SMD",
|
|
345
|
+
})
|
|
346
|
+
|
|
347
|
+
expect(result).toEqual({
|
|
348
|
+
jlcpcb: ["C2345", "C6789", "C0123"],
|
|
349
|
+
})
|
|
350
|
+
})
|
|
351
|
+
|
|
91
352
|
test("should return empty object for unknown component types", async () => {
|
|
92
353
|
const unknown: AnySourceComponent = {
|
|
93
354
|
type: "source_component",
|