@tscircuit/parts-engine 0.0.16 → 0.0.18

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.
@@ -1,502 +0,0 @@
1
- import { describe, test, expect, beforeEach } from "bun:test"
2
- import { jlcPartsEngine, cache } from "../lib/jlc-parts-engine"
3
- import type { AnySourceComponent } from "circuit-json"
4
- describe("jlcPartsEngine", () => {
5
- beforeEach(() => {
6
- cache.clear()
7
- // Reset fetch fake between tests
8
- globalThis.fetch = (async (url: string) => {
9
- if (url.includes("/resistors/")) {
10
- return {
11
- json: async () => ({
12
- resistors: [{ lcsc: "1234" }, { lcsc: "5678" }, { lcsc: "9012" }],
13
- }),
14
- } as Response
15
- }
16
- if (url.includes("/capacitors/")) {
17
- return {
18
- json: async () => ({
19
- capacitors: [{ lcsc: "2345" }, { lcsc: "6789" }, { lcsc: "0123" }],
20
- }),
21
- } as Response
22
- }
23
- if (url.includes("/potentiometers/")) {
24
- return {
25
- json: async () => ({
26
- potentiometers: [
27
- { lcsc: "1234" },
28
- { lcsc: "5678" },
29
- { lcsc: "9012" },
30
- ],
31
- }),
32
- } as Response
33
- }
34
- if (url.includes("/headers/")) {
35
- return {
36
- json: async () => ({
37
- headers: [{ lcsc: "3456" }, { lcsc: "7890" }, { lcsc: "1234" }],
38
- }),
39
- } as Response
40
- }
41
- if (url.includes("/diodes/")) {
42
- return {
43
- json: async () => ({
44
- diodes: [{ lcsc: "4567" }, { lcsc: "8901" }, { lcsc: "2345" }],
45
- }),
46
- } as Response
47
- }
48
- if (url.includes("/chips/")) {
49
- return {
50
- json: async () => ({
51
- chips: [{ lcsc: "5678" }, { lcsc: "9012" }, { lcsc: "3456" }],
52
- }),
53
- } as Response
54
- }
55
- if (url.includes("/transistors/")) {
56
- return {
57
- json: async () => ({
58
- transistors: [{ lcsc: "6789" }, { lcsc: "0123" }, { lcsc: "4567" }],
59
- }),
60
- } as Response
61
- }
62
- if (url.includes("/power_sources/")) {
63
- return {
64
- json: async () => ({
65
- power_sources: [
66
- { lcsc: "7890" },
67
- { lcsc: "1234" },
68
- { lcsc: "5678" },
69
- ],
70
- }),
71
- } as Response
72
- }
73
- if (url.includes("/inductors/")) {
74
- return {
75
- json: async () => ({
76
- inductors: [{ lcsc: "8901" }, { lcsc: "2345" }, { lcsc: "6789" }],
77
- }),
78
- } as Response
79
- }
80
- if (url.includes("/crystals/")) {
81
- return {
82
- json: async () => ({
83
- crystals: [{ lcsc: "9012" }, { lcsc: "3456" }, { lcsc: "7890" }],
84
- }),
85
- } as Response
86
- }
87
- if (url.includes("/mosfets/")) {
88
- return {
89
- json: async () => ({
90
- mosfets: [{ lcsc: "0123" }, { lcsc: "4567" }, { lcsc: "8901" }],
91
- }),
92
- } as Response
93
- }
94
- if (url.includes("/resonators/")) {
95
- return {
96
- json: async () => ({
97
- resonators: [{ lcsc: "1234" }, { lcsc: "5678" }, { lcsc: "9012" }],
98
- }),
99
- } as Response
100
- }
101
- if (url.includes("/switches/")) {
102
- return {
103
- json: async () => ({
104
- switches: [{ lcsc: "2345" }, { lcsc: "6789" }, { lcsc: "0123" }],
105
- }),
106
- } as Response
107
- }
108
- if (url.includes("/usb_c_connectors/")) {
109
- return {
110
- json: async () => ({
111
- usb_c_connectors: [
112
- { lcsc: "165948" },
113
- { lcsc: "165949" },
114
- { lcsc: "165950" },
115
- ],
116
- }),
117
- } as Response
118
- }
119
- return {} as Response
120
- }) as unknown as typeof fetch
121
- })
122
-
123
- test("should find resistor parts", async () => {
124
- const resistor: AnySourceComponent = {
125
- type: "source_component",
126
- ftype: "simple_resistor",
127
- resistance: 10000,
128
- source_component_id: "source_component_0",
129
- name: "R1",
130
- }
131
-
132
- const result = await jlcPartsEngine.findPart({
133
- sourceComponent: resistor,
134
- footprinterString: "0603",
135
- })
136
-
137
- expect(result).toEqual({
138
- jlcpcb: ["C1234", "C5678", "C9012"],
139
- })
140
- })
141
-
142
- test("should find resistor parts with kicad footprint", async () => {
143
- const resistor: AnySourceComponent = {
144
- type: "source_component",
145
- ftype: "simple_resistor",
146
- resistance: 10000,
147
- source_component_id: "source_component_0",
148
- name: "R1",
149
- }
150
-
151
- const result = await jlcPartsEngine.findPart({
152
- sourceComponent: resistor,
153
- footprinterString: "kicad:Resistor_SMD:R_0603_1608Metric",
154
- })
155
-
156
- expect(result).toEqual({
157
- jlcpcb: ["C1234", "C5678", "C9012"],
158
- })
159
- })
160
-
161
- test("should find capacitor parts", async () => {
162
- const capacitor: AnySourceComponent = {
163
- type: "source_component",
164
- ftype: "simple_capacitor",
165
- capacitance: 100000,
166
- source_component_id: "source_component_0",
167
- name: "C1",
168
- }
169
-
170
- const result = await jlcPartsEngine.findPart({
171
- sourceComponent: capacitor,
172
- footprinterString: "cap0603",
173
- })
174
-
175
- expect(result).toEqual({
176
- jlcpcb: ["C2345", "C6789", "C0123"],
177
- })
178
- })
179
-
180
- test("should find pin header parts", async () => {
181
- const header: AnySourceComponent = {
182
- type: "source_component",
183
- ftype: "simple_pin_header",
184
- pin_count: 8,
185
- gender: "male",
186
- source_component_id: "source_component_0",
187
- name: "J1",
188
- }
189
-
190
- const result = await jlcPartsEngine.findPart({
191
- sourceComponent: header,
192
- footprinterString: "2x4_p2.54",
193
- })
194
-
195
- expect(result).toEqual({
196
- jlcpcb: ["C3456", "C7890", "C1234"],
197
- })
198
- })
199
-
200
- // potentiometers
201
- test("should find potentiometers", async () => {
202
- const potentiometer: AnySourceComponent = {
203
- type: "source_component",
204
- ftype: "simple_potentiometer",
205
- source_component_id: "source_component_0",
206
- name: "P1",
207
- max_resistance: 10000,
208
- }
209
-
210
- const result = await jlcPartsEngine.findPart({
211
- sourceComponent: potentiometer,
212
- footprinterString: "10k",
213
- })
214
-
215
- expect(result).toEqual({
216
- jlcpcb: ["C1234", "C5678", "C9012"],
217
- })
218
- })
219
-
220
- test("should find diode parts", async () => {
221
- const diode: AnySourceComponent = {
222
- type: "source_component",
223
- ftype: "simple_diode",
224
- source_component_id: "source_component_0",
225
- name: "D1",
226
- }
227
-
228
- const result = await jlcPartsEngine.findPart({
229
- sourceComponent: diode,
230
- footprinterString: "SOD-123",
231
- })
232
-
233
- expect(result).toEqual({
234
- jlcpcb: ["C4567", "C8901", "C2345"],
235
- })
236
- })
237
-
238
- test("should find chip parts", async () => {
239
- const chip: AnySourceComponent = {
240
- type: "source_component",
241
- ftype: "simple_chip",
242
- source_component_id: "source_component_0",
243
- name: "U1",
244
- }
245
-
246
- const result = await jlcPartsEngine.findPart({
247
- sourceComponent: chip,
248
- footprinterString: "SOIC-8",
249
- })
250
-
251
- expect(result).toEqual({
252
- jlcpcb: ["C5678", "C9012", "C3456"],
253
- })
254
- })
255
-
256
- test("should find chip parts with kicad footprint", async () => {
257
- const chip: AnySourceComponent = {
258
- type: "source_component",
259
- ftype: "simple_chip",
260
- source_component_id: "source_component_0",
261
- name: "U1",
262
- }
263
-
264
- const result = await jlcPartsEngine.findPart({
265
- sourceComponent: chip,
266
- footprinterString: "kicad:Package_SO:SOIC-8_3.9x4.9mm_P1.27mm",
267
- })
268
-
269
- expect(result).toEqual({
270
- jlcpcb: ["C5678", "C9012", "C3456"],
271
- })
272
- })
273
-
274
- test("should find transistor parts", async () => {
275
- const transistor: AnySourceComponent = {
276
- type: "source_component",
277
- ftype: "simple_transistor",
278
- transistor_type: "npn",
279
- source_component_id: "source_component_0",
280
- name: "Q1",
281
- }
282
-
283
- const result = await jlcPartsEngine.findPart({
284
- sourceComponent: transistor,
285
- footprinterString: "SOT-23",
286
- })
287
-
288
- expect(result).toEqual({
289
- jlcpcb: ["C6789", "C0123", "C4567"],
290
- })
291
- })
292
-
293
- test("should find power source parts", async () => {
294
- const powerSource: AnySourceComponent = {
295
- type: "source_component",
296
- ftype: "simple_power_source",
297
- voltage: 5,
298
- source_component_id: "source_component_0",
299
- name: "V1",
300
- }
301
-
302
- const result = await jlcPartsEngine.findPart({
303
- sourceComponent: powerSource,
304
- footprinterString: "SOT-223",
305
- })
306
-
307
- expect(result).toEqual({
308
- jlcpcb: ["C7890", "C1234", "C5678"],
309
- })
310
- })
311
-
312
- test("should find inductor parts", async () => {
313
- const inductor: AnySourceComponent = {
314
- type: "source_component",
315
- ftype: "simple_inductor",
316
- inductance: 100,
317
- source_component_id: "source_component_0",
318
- name: "L1",
319
- }
320
-
321
- const result = await jlcPartsEngine.findPart({
322
- sourceComponent: inductor,
323
- footprinterString: "0603",
324
- })
325
-
326
- expect(result).toEqual({
327
- jlcpcb: ["C8901", "C2345", "C6789"],
328
- })
329
- })
330
-
331
- test("should find crystal parts", async () => {
332
- const crystal: AnySourceComponent = {
333
- type: "source_component",
334
- ftype: "simple_crystal",
335
- frequency: 16000000,
336
- load_capacitance: 20,
337
- source_component_id: "source_component_0",
338
- name: "X1",
339
- }
340
-
341
- const result = await jlcPartsEngine.findPart({
342
- sourceComponent: crystal,
343
- footprinterString: "HC-49S",
344
- })
345
-
346
- expect(result).toEqual({
347
- jlcpcb: ["C9012", "C3456", "C7890"],
348
- })
349
- })
350
-
351
- test("should find MOSFET parts", async () => {
352
- const mosfet: AnySourceComponent = {
353
- type: "source_component",
354
- ftype: "simple_mosfet",
355
- mosfet_mode: "enhancement",
356
- channel_type: "n",
357
- source_component_id: "source_component_0",
358
- name: "M1",
359
- }
360
-
361
- const result = await jlcPartsEngine.findPart({
362
- sourceComponent: mosfet,
363
- footprinterString: "SOT-23",
364
- })
365
-
366
- expect(result).toEqual({
367
- jlcpcb: ["C0123", "C4567", "C8901"],
368
- })
369
- })
370
-
371
- test("should find resonator parts", async () => {
372
- const resonator: AnySourceComponent = {
373
- type: "source_component",
374
- ftype: "simple_resonator",
375
- frequency: 16000000,
376
- load_capacitance: 20,
377
- source_component_id: "source_component_0",
378
- name: "Y1",
379
- }
380
-
381
- const result = await jlcPartsEngine.findPart({
382
- sourceComponent: resonator,
383
- footprinterString: "SMD",
384
- })
385
-
386
- expect(result).toEqual({
387
- jlcpcb: ["C1234", "C5678", "C9012"],
388
- })
389
- })
390
-
391
- test("should find switch parts", async () => {
392
- const switch_: AnySourceComponent = {
393
- type: "source_component",
394
- ftype: "simple_switch",
395
- source_component_id: "source_component_0",
396
- name: "SW1",
397
- }
398
-
399
- const result = await jlcPartsEngine.findPart({
400
- sourceComponent: switch_,
401
- footprinterString: "SMD",
402
- })
403
-
404
- expect(result).toEqual({
405
- jlcpcb: ["C2345", "C6789", "C0123"],
406
- })
407
- })
408
-
409
- test("should find usb_c connector parts", async () => {
410
- const connector = {
411
- type: "source_component",
412
- ftype: "simple_connector",
413
- standard: "usb_c",
414
- source_component_id: "source_component_0",
415
- name: "J1",
416
- } as AnySourceComponent
417
-
418
- const result = await jlcPartsEngine.findPart({
419
- sourceComponent: connector,
420
- })
421
-
422
- expect(result).toEqual({
423
- jlcpcb: ["C165948", "C165949", "C165950"],
424
- })
425
- })
426
-
427
- test("should return empty object for unknown component types", async () => {
428
- const unknown: AnySourceComponent = {
429
- type: "source_component",
430
- ftype: "random" as any,
431
- source_component_id: "source_component_0",
432
- name: "U1",
433
- resistance: 10000,
434
- }
435
-
436
- const result = await jlcPartsEngine.findPart({
437
- sourceComponent: unknown,
438
- footprinterString: "",
439
- })
440
-
441
- expect(result).toEqual({})
442
- })
443
-
444
- test("should handle missing API data", async () => {
445
- globalThis.fetch = (async () => ({
446
- json: async () => ({}),
447
- })) as unknown as typeof fetch
448
-
449
- const resistor: AnySourceComponent = {
450
- type: "source_component",
451
- ftype: "simple_resistor",
452
- resistance: 1000,
453
- source_component_id: "source_component_0",
454
- name: "R2",
455
- }
456
-
457
- const result = await jlcPartsEngine.findPart({
458
- sourceComponent: resistor,
459
- footprinterString: "0603",
460
- })
461
-
462
- expect(result).toEqual({ jlcpcb: [] })
463
- })
464
-
465
- test("should prefer basic parts when available", async () => {
466
- // Override the global fetch mock for this specific test
467
- globalThis.fetch = (async (url: string) => {
468
- if (url.includes("/resistors/")) {
469
- return {
470
- json: async () => ({
471
- resistors: [
472
- { lcsc: "1111" }, // is_basic is undefined, treated as false
473
- { lcsc: "2222", is_basic: true },
474
- { lcsc: "3333", is_basic: false },
475
- { lcsc: "4444", is_basic: true },
476
- { lcsc: "5555" },
477
- ],
478
- }),
479
- } as Response
480
- }
481
- return {} as Response
482
- }) as unknown as typeof fetch
483
-
484
- const resistor: AnySourceComponent = {
485
- type: "source_component",
486
- ftype: "simple_resistor",
487
- resistance: 10000,
488
- source_component_id: "source_component_0",
489
- name: "R1",
490
- }
491
-
492
- const result = await jlcPartsEngine.findPart({
493
- sourceComponent: resistor,
494
- footprinterString: "0603",
495
- })
496
-
497
- // Expecting basic parts to be prioritized
498
- expect(result).toEqual({
499
- jlcpcb: ["C2222", "C4444", "C1111"],
500
- })
501
- })
502
- })
package/tsconfig.json DELETED
@@ -1,28 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- // Environment setup & latest features
4
- "lib": ["ESNext"],
5
- "target": "ESNext",
6
- "module": "ESNext",
7
- "moduleDetection": "force",
8
- "jsx": "react-jsx",
9
- "allowJs": true,
10
-
11
- // Bundler mode
12
- "moduleResolution": "bundler",
13
- "allowImportingTsExtensions": true,
14
- "verbatimModuleSyntax": true,
15
- "noEmit": true,
16
-
17
- // Best practices
18
- "strict": true,
19
- "skipLibCheck": true,
20
- "noFallthroughCasesInSwitch": true,
21
- "noUncheckedIndexedAccess": true,
22
-
23
- // Some stricter flags (disabled by default)
24
- "noUnusedLocals": false,
25
- "noUnusedParameters": false,
26
- "noPropertyAccessFromIndexSignature": false
27
- }
28
- }