@jlcpcb/cli 0.3.2 → 0.4.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 +12 -0
- package/dist/index.js +501 -172
- package/package.json +1 -1
- package/src/app/components/ListView.tsx +1 -1
- package/src/app/components/list-view-format.test.ts +2 -0
- package/src/app/screens/InfoScreen.tsx +22 -6
- package/src/app/screens/InstalledScreen.tsx +1 -1
- package/src/app/screens/SearchScreen.tsx +11 -4
- package/src/commands/agent-json.test.ts +203 -0
- package/src/commands/easyeda.ts +63 -10
- package/src/commands/info.ts +6 -9
- package/src/commands/install.ts +39 -8
- package/src/commands/library.ts +13 -23
- package/src/commands/search.ts +35 -3
- package/src/commands/validate.ts +95 -43
- package/src/index.ts +38 -6
- package/src/utils/agent-output.ts +35 -0
- package/src/utils/search-result-output.ts +20 -0
package/dist/index.js
CHANGED
|
@@ -861,7 +861,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
861
861
|
this._exitCallback = (err) => {
|
|
862
862
|
if (err.code !== "commander.executeSubCommandAsync") {
|
|
863
863
|
throw err;
|
|
864
|
-
}
|
|
864
|
+
}
|
|
865
865
|
};
|
|
866
866
|
}
|
|
867
867
|
return this;
|
|
@@ -9687,7 +9687,7 @@ Learn more about data fetching with Hooks: https://react.dev/link/hooks-data-fet
|
|
|
9687
9687
|
offscreenSubtreeIsHidden = prevOffscreenSubtreeIsHidden;
|
|
9688
9688
|
wasHidden && !hoistableRoot && !prevOffscreenSubtreeIsHidden && !prevOffscreenSubtreeWasHidden && (finishedWork.mode & 2) !== NoMode && 0 <= componentEffectStartTime && 0 <= componentEffectEndTime && 0.05 < componentEffectEndTime - componentEffectStartTime && logComponentReappeared(finishedWork, componentEffectStartTime, componentEffectEndTime);
|
|
9689
9689
|
commitReconciliationEffects(finishedWork);
|
|
9690
|
-
if (flags & 8192 && (root = finishedWork.stateNode, root._visibility = hoistableRoot ? root._visibility & ~OffscreenVisible : root._visibility | OffscreenVisible, !hoistableRoot || current2 === null || wasHidden || offscreenSubtreeIsHidden || offscreenSubtreeWasHidden || (recursivelyTraverseDisappearLayoutEffects(finishedWork), (finishedWork.mode & 2) !== NoMode && 0 <= componentEffectStartTime && 0 <= componentEffectEndTime && 0.05 < componentEffectEndTime - componentEffectStartTime && logComponentTrigger(finishedWork, componentEffectStartTime, componentEffectEndTime, "Disconnect")), supportsMutation))
|
|
9690
|
+
if (flags & 8192 && (root = finishedWork.stateNode, root._visibility = hoistableRoot ? root._visibility & ~OffscreenVisible : root._visibility | OffscreenVisible, !hoistableRoot || current2 === null || wasHidden || offscreenSubtreeIsHidden || offscreenSubtreeWasHidden || (recursivelyTraverseDisappearLayoutEffects(finishedWork), (finishedWork.mode & 2) !== NoMode && 0 <= componentEffectStartTime && 0 <= componentEffectEndTime && 0.05 < componentEffectEndTime - componentEffectStartTime && logComponentTrigger(finishedWork, componentEffectStartTime, componentEffectEndTime, "Disconnect")), supportsMutation)) {
|
|
9691
9691
|
a:
|
|
9692
9692
|
if (current2 = null, supportsMutation)
|
|
9693
9693
|
for (root = finishedWork;; ) {
|
|
@@ -9737,6 +9737,7 @@ Learn more about data fetching with Hooks: https://react.dev/link/hooks-data-fet
|
|
|
9737
9737
|
root.sibling.return = root.return;
|
|
9738
9738
|
root = root.sibling;
|
|
9739
9739
|
}
|
|
9740
|
+
}
|
|
9740
9741
|
flags & 4 && (flags = finishedWork.updateQueue, flags !== null && (current2 = flags.retryQueue, current2 !== null && (flags.retryQueue = null, attachSuspenseRetryListeners(finishedWork, current2))));
|
|
9741
9742
|
break;
|
|
9742
9743
|
case 19:
|
|
@@ -17250,7 +17251,7 @@ var require_backend = __commonJS((exports, module) => {
|
|
|
17250
17251
|
987: (module2, __unused_webpack_exports, __webpack_require__2) => {
|
|
17251
17252
|
if (true) {
|
|
17252
17253
|
module2.exports = __webpack_require__2(786);
|
|
17253
|
-
}
|
|
17254
|
+
}
|
|
17254
17255
|
},
|
|
17255
17256
|
126: (__unused_webpack_module, exports2, __webpack_require__2) => {
|
|
17256
17257
|
var process3 = __webpack_require__2(169);
|
|
@@ -17700,7 +17701,7 @@ var require_backend = __commonJS((exports, module) => {
|
|
|
17700
17701
|
189: (module2, __unused_webpack_exports, __webpack_require__2) => {
|
|
17701
17702
|
if (true) {
|
|
17702
17703
|
module2.exports = __webpack_require__2(126);
|
|
17703
|
-
}
|
|
17704
|
+
}
|
|
17704
17705
|
},
|
|
17705
17706
|
206: function(module2, exports2, __webpack_require__2) {
|
|
17706
17707
|
var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;
|
|
@@ -17715,7 +17716,7 @@ var require_backend = __commonJS((exports, module) => {
|
|
|
17715
17716
|
(function(root, factory) {
|
|
17716
17717
|
if (true) {
|
|
17717
17718
|
__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__2(430)], __WEBPACK_AMD_DEFINE_FACTORY__ = factory, __WEBPACK_AMD_DEFINE_RESULT__ = typeof __WEBPACK_AMD_DEFINE_FACTORY__ === "function" ? __WEBPACK_AMD_DEFINE_FACTORY__.apply(exports2, __WEBPACK_AMD_DEFINE_ARRAY__) : __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module2.exports = __WEBPACK_AMD_DEFINE_RESULT__);
|
|
17718
|
-
}
|
|
17719
|
+
}
|
|
17719
17720
|
})(this, function ErrorStackParser(StackFrame) {
|
|
17720
17721
|
var FIREFOX_SAFARI_STACK_REGEXP = /(^|@)\S+:\d+/;
|
|
17721
17722
|
var CHROME_IE_STACK_REGEXP = /^\s*at .*(\S+:\d+|\(native\))/m;
|
|
@@ -18411,7 +18412,7 @@ var require_backend = __commonJS((exports, module) => {
|
|
|
18411
18412
|
(function(root, factory) {
|
|
18412
18413
|
if (true) {
|
|
18413
18414
|
__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_FACTORY__ = factory, __WEBPACK_AMD_DEFINE_RESULT__ = typeof __WEBPACK_AMD_DEFINE_FACTORY__ === "function" ? __WEBPACK_AMD_DEFINE_FACTORY__.apply(exports2, __WEBPACK_AMD_DEFINE_ARRAY__) : __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module2.exports = __WEBPACK_AMD_DEFINE_RESULT__);
|
|
18414
|
-
}
|
|
18415
|
+
}
|
|
18415
18416
|
})(this, function() {
|
|
18416
18417
|
function _isNumber(n) {
|
|
18417
18418
|
return !isNaN(parseFloat(n)) && isFinite(n);
|
|
@@ -23785,7 +23786,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
23785
23786
|
var suffix = "";
|
|
23786
23787
|
if (true) {
|
|
23787
23788
|
suffix = " (<anonymous>)";
|
|
23788
|
-
}
|
|
23789
|
+
}
|
|
23789
23790
|
return `
|
|
23790
23791
|
` + prefix + name + suffix;
|
|
23791
23792
|
}
|
|
@@ -26514,7 +26515,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
26514
26515
|
hasChanges = true;
|
|
26515
26516
|
updateMostRecentlyInspectedElementIfNecessary(devtoolsInstance.id);
|
|
26516
26517
|
}
|
|
26517
|
-
}
|
|
26518
|
+
}
|
|
26518
26519
|
}
|
|
26519
26520
|
} catch (err) {
|
|
26520
26521
|
_iterator2.e(err);
|
|
@@ -28293,7 +28294,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
28293
28294
|
if (contentFiber === null) {
|
|
28294
28295
|
throw new Error("There should always be an Offscreen Fiber child in a hydrated Suspense boundary.");
|
|
28295
28296
|
}
|
|
28296
|
-
}
|
|
28297
|
+
}
|
|
28297
28298
|
var _isTimedOut = fiber.memoizedState !== null;
|
|
28298
28299
|
if (!_isTimedOut) {
|
|
28299
28300
|
newSuspenseNode.rects = measureInstance(newInstance);
|
|
@@ -28327,7 +28328,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
28327
28328
|
if (_contentFiber === null) {
|
|
28328
28329
|
throw new Error("There should always be an Offscreen Fiber child in a hydrated Suspense boundary.");
|
|
28329
28330
|
}
|
|
28330
|
-
}
|
|
28331
|
+
}
|
|
28331
28332
|
var suspenseState = fiber.memoizedState;
|
|
28332
28333
|
var _isTimedOut3 = suspenseState !== null;
|
|
28333
28334
|
if (!_isTimedOut3) {
|
|
@@ -28427,7 +28428,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
28427
28428
|
trackThrownPromisesFromRetryCache(newSuspenseNode, fiber.stateNode);
|
|
28428
28429
|
mountSuspenseChildrenRecursively(_contentFiber2, traceNearestHostComponentUpdate, stashedSuspenseParent, stashedSuspensePrevious, stashedSuspenseRemaining);
|
|
28429
28430
|
shouldPopSuspenseNode = false;
|
|
28430
|
-
}
|
|
28431
|
+
}
|
|
28431
28432
|
} else {
|
|
28432
28433
|
if (fiber.child !== null) {
|
|
28433
28434
|
mountChildrenRecursively(fiber.child, traceNearestHostComponentUpdate);
|
|
@@ -29013,7 +29014,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
29013
29014
|
shouldPopSuspenseNode = false;
|
|
29014
29015
|
} else if (previousHydrated && !nextHydrated) {
|
|
29015
29016
|
throw new Error("Encountered a dehydrated Suspense boundary that was previously hydrated.");
|
|
29016
|
-
}
|
|
29017
|
+
}
|
|
29017
29018
|
} else {
|
|
29018
29019
|
if (nextFiber.child !== prevFiber.child) {
|
|
29019
29020
|
updateFlags |= updateChildrenRecursively(nextFiber.child, prevFiber.child, traceNearestHostComponentUpdate);
|
|
@@ -29059,8 +29060,8 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
29059
29060
|
recordResetChildren(fiberInstance);
|
|
29060
29061
|
}
|
|
29061
29062
|
updateFlags &= ~ShouldResetChildren;
|
|
29062
|
-
}
|
|
29063
|
-
}
|
|
29063
|
+
}
|
|
29064
|
+
}
|
|
29064
29065
|
if ((updateFlags & ShouldResetSuspenseChildren) !== NoUpdate) {
|
|
29065
29066
|
if (fiberInstance !== null && fiberInstance.kind === FIBER_INSTANCE) {
|
|
29066
29067
|
var _suspenseNode3 = fiberInstance.suspenseNode;
|
|
@@ -29068,7 +29069,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
29068
29069
|
recordResetSuspenseChildren(_suspenseNode3);
|
|
29069
29070
|
updateFlags &= ~ShouldResetSuspenseChildren;
|
|
29070
29071
|
}
|
|
29071
|
-
}
|
|
29072
|
+
}
|
|
29072
29073
|
}
|
|
29073
29074
|
if ((updateFlags & ShouldResetParentSuspenseChildren) !== NoUpdate) {
|
|
29074
29075
|
if (fiberInstance !== null && fiberInstance.kind === FIBER_INSTANCE) {
|
|
@@ -29077,7 +29078,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
|
|
|
29077
29078
|
updateFlags &= ~ShouldResetParentSuspenseChildren;
|
|
29078
29079
|
updateFlags |= ShouldResetSuspenseChildren;
|
|
29079
29080
|
}
|
|
29080
|
-
}
|
|
29081
|
+
}
|
|
29081
29082
|
}
|
|
29082
29083
|
return updateFlags;
|
|
29083
29084
|
} finally {
|
|
@@ -32141,7 +32142,7 @@ The error thrown in the component is:
|
|
|
32141
32142
|
rendererInterface = renderer_attach(hook, id, renderer, global2, shouldStartProfilingNow, profilingSettings);
|
|
32142
32143
|
} else if (renderer.ComponentTree) {
|
|
32143
32144
|
rendererInterface = legacy_renderer_attach(hook, id, renderer, global2);
|
|
32144
|
-
}
|
|
32145
|
+
}
|
|
32145
32146
|
}
|
|
32146
32147
|
return rendererInterface;
|
|
32147
32148
|
}
|
|
@@ -34089,6 +34090,9 @@ var {
|
|
|
34089
34090
|
Help
|
|
34090
34091
|
} = import__.default;
|
|
34091
34092
|
|
|
34093
|
+
// src/index.ts
|
|
34094
|
+
import { createRequire as createRequire2 } from "module";
|
|
34095
|
+
|
|
34092
34096
|
// ../core/dist/index.js
|
|
34093
34097
|
import { readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
|
|
34094
34098
|
import { existsSync as existsSync2 } from "fs";
|
|
@@ -34102,7 +34106,7 @@ import { join, dirname, extname, basename } from "path";
|
|
|
34102
34106
|
import { existsSync } from "fs";
|
|
34103
34107
|
import { homedir, platform } from "os";
|
|
34104
34108
|
import { join as join2 } from "path";
|
|
34105
|
-
import {
|
|
34109
|
+
import { execFileSync } from "child_process";
|
|
34106
34110
|
import { existsSync as existsSync4 } from "fs";
|
|
34107
34111
|
import { readFile as readFile4, readdir as readdir2, unlink } from "fs/promises";
|
|
34108
34112
|
import { homedir as homedir3, platform as platform3 } from "os";
|
|
@@ -39235,6 +39239,8 @@ class JLCClient {
|
|
|
39235
39239
|
const components = data.data?.componentPageInfo?.list || [];
|
|
39236
39240
|
logger3.debug(`Found ${components.length} components`);
|
|
39237
39241
|
return components.map((c) => ({
|
|
39242
|
+
id: c.componentCode,
|
|
39243
|
+
idType: "lcsc",
|
|
39238
39244
|
lcscId: c.componentCode,
|
|
39239
39245
|
name: c.componentModelEn,
|
|
39240
39246
|
manufacturer: c.componentBrandEn,
|
|
@@ -39281,6 +39287,7 @@ var jlcClient = new JLCClient;
|
|
|
39281
39287
|
var logger4 = createLogger("http-client");
|
|
39282
39288
|
async function fetchWithCurlFallback(url, options = {}) {
|
|
39283
39289
|
const method = options.method || "GET";
|
|
39290
|
+
const timeoutMs = options.timeoutMs ?? 30000;
|
|
39284
39291
|
const headers = {
|
|
39285
39292
|
Accept: "application/json",
|
|
39286
39293
|
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36"
|
|
@@ -39288,10 +39295,13 @@ async function fetchWithCurlFallback(url, options = {}) {
|
|
|
39288
39295
|
if (options.contentType) {
|
|
39289
39296
|
headers["Content-Type"] = options.contentType;
|
|
39290
39297
|
}
|
|
39298
|
+
const controller = new AbortController;
|
|
39299
|
+
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
39291
39300
|
try {
|
|
39292
39301
|
const fetchOptions = {
|
|
39293
39302
|
method,
|
|
39294
|
-
headers
|
|
39303
|
+
headers,
|
|
39304
|
+
signal: controller.signal
|
|
39295
39305
|
};
|
|
39296
39306
|
if (options.body) {
|
|
39297
39307
|
fetchOptions.body = options.body;
|
|
@@ -39305,26 +39315,28 @@ async function fetchWithCurlFallback(url, options = {}) {
|
|
|
39305
39315
|
}
|
|
39306
39316
|
} catch (error) {
|
|
39307
39317
|
logger4.debug(`Native fetch failed, falling back to curl: ${error}`);
|
|
39318
|
+
} finally {
|
|
39319
|
+
clearTimeout(timeout);
|
|
39308
39320
|
}
|
|
39309
39321
|
try {
|
|
39310
|
-
const curlArgs = ["
|
|
39322
|
+
const curlArgs = ["-sS", "--max-time", String(Math.ceil(timeoutMs / 1000))];
|
|
39311
39323
|
if (method === "POST") {
|
|
39312
39324
|
curlArgs.push("-X", "POST");
|
|
39313
39325
|
}
|
|
39314
|
-
curlArgs.push("-H",
|
|
39315
|
-
curlArgs.push("-H",
|
|
39326
|
+
curlArgs.push("-H", "Accept: application/json");
|
|
39327
|
+
curlArgs.push("-H", "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)");
|
|
39316
39328
|
if (options.contentType) {
|
|
39317
|
-
curlArgs.push("-H", `
|
|
39329
|
+
curlArgs.push("-H", `Content-Type: ${options.contentType}`);
|
|
39318
39330
|
}
|
|
39319
39331
|
if (options.body) {
|
|
39320
|
-
curlArgs.push("-d",
|
|
39332
|
+
curlArgs.push("-d", options.body);
|
|
39321
39333
|
}
|
|
39322
|
-
curlArgs.push(
|
|
39334
|
+
curlArgs.push(url);
|
|
39323
39335
|
if (options.binary) {
|
|
39324
|
-
const result2 =
|
|
39336
|
+
const result2 = execFileSync("curl", curlArgs, { maxBuffer: 50 * 1024 * 1024 });
|
|
39325
39337
|
return result2;
|
|
39326
39338
|
}
|
|
39327
|
-
const result =
|
|
39339
|
+
const result = execFileSync("curl", curlArgs, {
|
|
39328
39340
|
encoding: "utf-8",
|
|
39329
39341
|
maxBuffer: 50 * 1024 * 1024
|
|
39330
39342
|
});
|
|
@@ -39893,22 +39905,24 @@ var ENDPOINT_3D_MODEL_OBJ = "https://modules.easyeda.com/3dmodel/{uuid}";
|
|
|
39893
39905
|
class EasyEDAClient {
|
|
39894
39906
|
userAgent = "ai-eda-lcsc-mcp/1.0.0";
|
|
39895
39907
|
async getComponentData(lcscPartNumber) {
|
|
39896
|
-
const
|
|
39897
|
-
|
|
39908
|
+
const validatedLcscPartNumber = LCSCPartNumberSchema.parse(lcscPartNumber);
|
|
39909
|
+
const url = API_ENDPOINT.replace("{lcsc_id}", validatedLcscPartNumber);
|
|
39910
|
+
logger5.debug(`Fetching component data for: ${validatedLcscPartNumber}`);
|
|
39898
39911
|
try {
|
|
39899
39912
|
const responseText = await fetchWithCurlFallback(url);
|
|
39900
39913
|
const data = JSON.parse(responseText);
|
|
39901
39914
|
if (!data.result) {
|
|
39902
39915
|
return null;
|
|
39903
39916
|
}
|
|
39904
|
-
return this.parseComponentData(data.result,
|
|
39917
|
+
return this.parseComponentData(data.result, validatedLcscPartNumber);
|
|
39905
39918
|
} catch (error) {
|
|
39906
39919
|
logger5.error(`Failed to fetch component ${lcscPartNumber}:`, error);
|
|
39907
39920
|
throw error;
|
|
39908
39921
|
}
|
|
39909
39922
|
}
|
|
39910
39923
|
async get3DModel(uuid, format = "step") {
|
|
39911
|
-
const
|
|
39924
|
+
const validatedUuid = EasyEDAUuidSchema.parse(uuid);
|
|
39925
|
+
const url = format === "step" ? ENDPOINT_3D_MODEL_STEP.replace("{uuid}", validatedUuid) : ENDPOINT_3D_MODEL_OBJ.replace("{uuid}", validatedUuid);
|
|
39912
39926
|
try {
|
|
39913
39927
|
const result = await fetchWithCurlFallback(url, { binary: true });
|
|
39914
39928
|
return result;
|
|
@@ -40028,8 +40042,9 @@ class EasyEDACommunityClient {
|
|
|
40028
40042
|
}
|
|
40029
40043
|
}
|
|
40030
40044
|
async getComponent(uuid) {
|
|
40031
|
-
const
|
|
40032
|
-
|
|
40045
|
+
const validatedUuid = EasyEDAUuidSchema.parse(uuid);
|
|
40046
|
+
const url = `${API_COMPONENT_ENDPOINT}/${validatedUuid}?version=${API_VERSION}&uuid=${validatedUuid}`;
|
|
40047
|
+
logger6.debug(`Fetching component: ${validatedUuid}`);
|
|
40033
40048
|
try {
|
|
40034
40049
|
const responseText = await fetchWithCurlFallback(url);
|
|
40035
40050
|
const data = JSON.parse(responseText);
|
|
@@ -40038,12 +40053,13 @@ class EasyEDACommunityClient {
|
|
|
40038
40053
|
}
|
|
40039
40054
|
return this.parseComponent(data.result);
|
|
40040
40055
|
} catch (error) {
|
|
40041
|
-
logger6.error(`Failed to fetch component ${
|
|
40056
|
+
logger6.error(`Failed to fetch component ${validatedUuid}:`, error);
|
|
40042
40057
|
throw error;
|
|
40043
40058
|
}
|
|
40044
40059
|
}
|
|
40045
40060
|
async get3DModel(uuid, format = "step") {
|
|
40046
|
-
const
|
|
40061
|
+
const validatedUuid = EasyEDAUuidSchema.parse(uuid);
|
|
40062
|
+
const url = format === "step" ? ENDPOINT_3D_MODEL_STEP2.replace("{uuid}", validatedUuid) : ENDPOINT_3D_MODEL_OBJ2.replace("{uuid}", validatedUuid);
|
|
40047
40063
|
try {
|
|
40048
40064
|
const result = await fetchWithCurlFallback(url, { binary: true });
|
|
40049
40065
|
return result;
|
|
@@ -40178,13 +40194,37 @@ function createComponentService() {
|
|
|
40178
40194
|
return {
|
|
40179
40195
|
async search(query, options = {}) {
|
|
40180
40196
|
const { source = "lcsc", limit = 20, inStock, basicOnly } = options;
|
|
40197
|
+
if (source === "all") {
|
|
40198
|
+
const [lcscResults, communityResults] = await Promise.all([
|
|
40199
|
+
jlcClient.search(query, { limit, inStock, basicOnly }),
|
|
40200
|
+
easyedaCommunityClient.search({
|
|
40201
|
+
query,
|
|
40202
|
+
limit
|
|
40203
|
+
})
|
|
40204
|
+
]);
|
|
40205
|
+
return [
|
|
40206
|
+
...lcscResults,
|
|
40207
|
+
...communityResults.map((r) => ({
|
|
40208
|
+
id: r.uuid,
|
|
40209
|
+
idType: "easyeda_uuid",
|
|
40210
|
+
easyedaUuid: r.uuid,
|
|
40211
|
+
name: r.title,
|
|
40212
|
+
manufacturer: r.owner?.nickname || "Community",
|
|
40213
|
+
description: r.description || "",
|
|
40214
|
+
package: r.package || "",
|
|
40215
|
+
stock: 0
|
|
40216
|
+
}))
|
|
40217
|
+
].slice(0, limit);
|
|
40218
|
+
}
|
|
40181
40219
|
if (source === "community" || source === "easyeda-community") {
|
|
40182
40220
|
const results = await easyedaCommunityClient.search({
|
|
40183
40221
|
query,
|
|
40184
40222
|
limit
|
|
40185
40223
|
});
|
|
40186
40224
|
return results.map((r) => ({
|
|
40187
|
-
|
|
40225
|
+
id: r.uuid,
|
|
40226
|
+
idType: "easyeda_uuid",
|
|
40227
|
+
easyedaUuid: r.uuid,
|
|
40188
40228
|
name: r.title,
|
|
40189
40229
|
manufacturer: r.owner?.nickname || "Community",
|
|
40190
40230
|
description: r.description || "",
|
|
@@ -42890,6 +42930,40 @@ function adaptCommunityComponent(component) {
|
|
|
42890
42930
|
rawData: component.rawData
|
|
42891
42931
|
};
|
|
42892
42932
|
}
|
|
42933
|
+
function buildValidationData(component, footprintRef, footprintType, isKicadStandardFootprint) {
|
|
42934
|
+
return {
|
|
42935
|
+
component: {
|
|
42936
|
+
name: component.info.name,
|
|
42937
|
+
description: component.info.description,
|
|
42938
|
+
package: component.info.package,
|
|
42939
|
+
manufacturer: component.info.manufacturer,
|
|
42940
|
+
datasheet_url: component.info.datasheetPdf || component.info.datasheet
|
|
42941
|
+
},
|
|
42942
|
+
symbol: {
|
|
42943
|
+
pin_count: component.symbol.pins.length,
|
|
42944
|
+
pins: component.symbol.pins.map((p) => ({
|
|
42945
|
+
number: p.number,
|
|
42946
|
+
name: p.name,
|
|
42947
|
+
electrical_type: p.electricalType
|
|
42948
|
+
}))
|
|
42949
|
+
},
|
|
42950
|
+
footprint: {
|
|
42951
|
+
type: component.footprint.type,
|
|
42952
|
+
pad_count: component.footprint.pads.length,
|
|
42953
|
+
pads: footprintType === "generated" ? component.footprint.pads.map((p) => ({
|
|
42954
|
+
number: p.number,
|
|
42955
|
+
shape: p.shape
|
|
42956
|
+
})) : null,
|
|
42957
|
+
is_kicad_standard: isKicadStandardFootprint,
|
|
42958
|
+
kicad_ref: footprintRef
|
|
42959
|
+
},
|
|
42960
|
+
checks: {
|
|
42961
|
+
pin_pad_count_match: component.symbol.pins.length === component.footprint.pads.length,
|
|
42962
|
+
has_power_pins: component.symbol.pins.some((p) => p.electricalType === "power_in" || p.electricalType === "power_out"),
|
|
42963
|
+
has_ground_pins: component.symbol.pins.some((p) => p.name.toLowerCase().includes("gnd") || p.name.toLowerCase().includes("vss"))
|
|
42964
|
+
}
|
|
42965
|
+
};
|
|
42966
|
+
}
|
|
42893
42967
|
function createLibraryService() {
|
|
42894
42968
|
return {
|
|
42895
42969
|
async install(id, options = {}) {
|
|
@@ -42959,6 +43033,34 @@ function createLibraryService() {
|
|
|
42959
43033
|
await ensureDir(footprintDir);
|
|
42960
43034
|
symbolFile = join5(symbolsDir, symLibFile);
|
|
42961
43035
|
symbolName = component.info.name.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
43036
|
+
footprintPath = join5(footprintDir, `${symbolName}.kicad_mod`);
|
|
43037
|
+
footprintRef = `${libName}:${symbolName}`;
|
|
43038
|
+
symbolRef = `${libName}:${symbolName}`;
|
|
43039
|
+
component.info.package = footprintRef;
|
|
43040
|
+
if (!options.force && existsSync4(symbolFile)) {
|
|
43041
|
+
const existingContent = await readFile4(symbolFile, "utf-8");
|
|
43042
|
+
if (symbolConverter.symbolExistsInLibrary(existingContent, component.info.name)) {
|
|
43043
|
+
return {
|
|
43044
|
+
success: true,
|
|
43045
|
+
id,
|
|
43046
|
+
source: "easyeda_community",
|
|
43047
|
+
storageMode: isGlobal ? "global" : "project-local",
|
|
43048
|
+
category,
|
|
43049
|
+
symbolName,
|
|
43050
|
+
symbolRef,
|
|
43051
|
+
footprintRef,
|
|
43052
|
+
footprintType: "generated",
|
|
43053
|
+
datasheet: component.info.datasheet,
|
|
43054
|
+
files: {
|
|
43055
|
+
symbolLibrary: symbolFile,
|
|
43056
|
+
footprint: footprintPath,
|
|
43057
|
+
model3d: undefined
|
|
43058
|
+
},
|
|
43059
|
+
symbolAction: "exists",
|
|
43060
|
+
validationData: buildValidationData(component, footprintRef, "generated", false)
|
|
43061
|
+
};
|
|
43062
|
+
}
|
|
43063
|
+
}
|
|
42962
43064
|
const include3d = options.include3d ?? true;
|
|
42963
43065
|
let modelRelativePath;
|
|
42964
43066
|
if (include3d && component.model3d) {
|
|
@@ -42980,10 +43082,7 @@ function createLibraryService() {
|
|
|
42980
43082
|
include3DModel: !!modelRelativePath,
|
|
42981
43083
|
modelPath: modelRelativePath
|
|
42982
43084
|
});
|
|
42983
|
-
footprintPath = join5(footprintDir, `${symbolName}.kicad_mod`);
|
|
42984
|
-
footprintRef = `${libName}:${symbolName}`;
|
|
42985
43085
|
await writeText(footprintPath, footprint);
|
|
42986
|
-
component.info.package = footprintRef;
|
|
42987
43086
|
if (isGlobal) {
|
|
42988
43087
|
const { ensureGlobalEasyEDALibrary: ensureGlobalEasyEDALibrary2 } = await Promise.resolve().then(() => (init_global_lib_table(), exports_global_lib_table));
|
|
42989
43088
|
await ensureGlobalEasyEDALibrary2();
|
|
@@ -42991,7 +43090,6 @@ function createLibraryService() {
|
|
|
42991
43090
|
await ensureSymLibTable(options.projectPath, symbolFile, libName, libDesc);
|
|
42992
43091
|
await ensureFpLibTable(options.projectPath, footprintDir, libName, libDesc);
|
|
42993
43092
|
}
|
|
42994
|
-
symbolRef = `${libName}:${symbolName}`;
|
|
42995
43093
|
} else {
|
|
42996
43094
|
category = getLibraryCategory(component.info.prefix, component.info.category, component.info.description);
|
|
42997
43095
|
const symbolLibraryFilename = getLibraryFilename(category);
|
|
@@ -43001,6 +43099,41 @@ function createLibraryService() {
|
|
|
43001
43099
|
await ensureDir(paths.symbolsDir);
|
|
43002
43100
|
await ensureDir(paths.footprintDir);
|
|
43003
43101
|
symbolName = symbolConverter.getSymbolName(component);
|
|
43102
|
+
symbolRef = getSymbolReference(category, symbolName);
|
|
43103
|
+
if (!options.force && existsSync4(symbolFile)) {
|
|
43104
|
+
const existingContent = await readFile4(symbolFile, "utf-8");
|
|
43105
|
+
if (symbolConverter.symbolExistsInLibrary(existingContent, component.info.name)) {
|
|
43106
|
+
const existingFootprintResult = footprintConverter.getFootprint(component);
|
|
43107
|
+
if (existingFootprintResult.type === "reference") {
|
|
43108
|
+
footprintRef = existingFootprintResult.reference;
|
|
43109
|
+
footprintPath = undefined;
|
|
43110
|
+
} else {
|
|
43111
|
+
footprintPath = join5(footprintDir, `${existingFootprintResult.name}.kicad_mod`);
|
|
43112
|
+
footprintRef = getFootprintReference(existingFootprintResult.name);
|
|
43113
|
+
}
|
|
43114
|
+
component.info.package = footprintRef;
|
|
43115
|
+
const footprintType2 = existingFootprintResult.type === "reference" ? "reference" : "generated";
|
|
43116
|
+
return {
|
|
43117
|
+
success: true,
|
|
43118
|
+
id,
|
|
43119
|
+
source: "lcsc",
|
|
43120
|
+
storageMode: isGlobal ? "global" : "project-local",
|
|
43121
|
+
category,
|
|
43122
|
+
symbolName,
|
|
43123
|
+
symbolRef,
|
|
43124
|
+
footprintRef,
|
|
43125
|
+
footprintType: footprintType2,
|
|
43126
|
+
datasheet: component.info.datasheet || `https://www.lcsc.com/datasheet/lcsc_datasheet_${id}.pdf`,
|
|
43127
|
+
files: {
|
|
43128
|
+
symbolLibrary: symbolFile,
|
|
43129
|
+
footprint: footprintPath,
|
|
43130
|
+
model3d: undefined
|
|
43131
|
+
},
|
|
43132
|
+
symbolAction: "exists",
|
|
43133
|
+
validationData: buildValidationData(component, footprintRef, footprintType2, existingFootprintResult.type === "reference")
|
|
43134
|
+
};
|
|
43135
|
+
}
|
|
43136
|
+
}
|
|
43004
43137
|
const include3d = options.include3d ?? true;
|
|
43005
43138
|
let modelRelativePath;
|
|
43006
43139
|
if (include3d && component.model3d) {
|
|
@@ -43025,7 +43158,6 @@ function createLibraryService() {
|
|
|
43025
43158
|
await writeText(footprintPath, footprintResult.content);
|
|
43026
43159
|
}
|
|
43027
43160
|
component.info.package = footprintRef;
|
|
43028
|
-
symbolRef = getSymbolReference(category, symbolName);
|
|
43029
43161
|
if (!isGlobal && options.projectPath) {
|
|
43030
43162
|
await ensureSymLibTable(options.projectPath, symbolFile);
|
|
43031
43163
|
await ensureFpLibTable(options.projectPath, footprintDir);
|
|
@@ -43065,38 +43197,7 @@ function createLibraryService() {
|
|
|
43065
43197
|
}
|
|
43066
43198
|
const isKicadStandardFootprint = !isCommunityComponent && !footprintPath;
|
|
43067
43199
|
const footprintType = isKicadStandardFootprint ? "reference" : "generated";
|
|
43068
|
-
const validationData =
|
|
43069
|
-
component: {
|
|
43070
|
-
name: component.info.name,
|
|
43071
|
-
description: component.info.description,
|
|
43072
|
-
package: component.info.package,
|
|
43073
|
-
manufacturer: component.info.manufacturer,
|
|
43074
|
-
datasheet_url: component.info.datasheetPdf || component.info.datasheet
|
|
43075
|
-
},
|
|
43076
|
-
symbol: {
|
|
43077
|
-
pin_count: component.symbol.pins.length,
|
|
43078
|
-
pins: component.symbol.pins.map((p) => ({
|
|
43079
|
-
number: p.number,
|
|
43080
|
-
name: p.name,
|
|
43081
|
-
electrical_type: p.electricalType
|
|
43082
|
-
}))
|
|
43083
|
-
},
|
|
43084
|
-
footprint: {
|
|
43085
|
-
type: component.footprint.type,
|
|
43086
|
-
pad_count: component.footprint.pads.length,
|
|
43087
|
-
pads: footprintType === "generated" ? component.footprint.pads.map((p) => ({
|
|
43088
|
-
number: p.number,
|
|
43089
|
-
shape: p.shape
|
|
43090
|
-
})) : null,
|
|
43091
|
-
is_kicad_standard: isKicadStandardFootprint,
|
|
43092
|
-
kicad_ref: footprintRef
|
|
43093
|
-
},
|
|
43094
|
-
checks: {
|
|
43095
|
-
pin_pad_count_match: component.symbol.pins.length === component.footprint.pads.length,
|
|
43096
|
-
has_power_pins: component.symbol.pins.some((p) => p.electricalType === "power_in" || p.electricalType === "power_out"),
|
|
43097
|
-
has_ground_pins: component.symbol.pins.some((p) => p.name.toLowerCase().includes("gnd") || p.name.toLowerCase().includes("vss"))
|
|
43098
|
-
}
|
|
43099
|
-
};
|
|
43200
|
+
const validationData = buildValidationData(component, footprintRef, footprintType, isKicadStandardFootprint);
|
|
43100
43201
|
return {
|
|
43101
43202
|
success: true,
|
|
43102
43203
|
id,
|
|
@@ -52526,7 +52627,7 @@ function ListView({
|
|
|
52526
52627
|
]
|
|
52527
52628
|
}, undefined, true, undefined, this)
|
|
52528
52629
|
]
|
|
52529
|
-
}, r.lcscId, true, undefined, this);
|
|
52630
|
+
}, r.id ?? r.lcscId, true, undefined, this);
|
|
52530
52631
|
}),
|
|
52531
52632
|
/* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Box_default, {
|
|
52532
52633
|
marginTop: 1,
|
|
@@ -52573,10 +52674,17 @@ function SearchScreen() {
|
|
|
52573
52674
|
} else if (key.downArrow) {
|
|
52574
52675
|
setSelectedIndex(Math.min(results.length - 1, selectedIndex + 1));
|
|
52575
52676
|
} else if (key.return && results[selectedIndex]) {
|
|
52576
|
-
|
|
52577
|
-
|
|
52578
|
-
|
|
52579
|
-
|
|
52677
|
+
const selected = results[selectedIndex];
|
|
52678
|
+
if (selected.idType === "easyeda_uuid") {
|
|
52679
|
+
push("easyeda-info", {
|
|
52680
|
+
uuid: selected.easyedaUuid ?? selected.id
|
|
52681
|
+
});
|
|
52682
|
+
} else {
|
|
52683
|
+
push("info", {
|
|
52684
|
+
componentId: selected.lcscId ?? selected.id,
|
|
52685
|
+
component: selected
|
|
52686
|
+
});
|
|
52687
|
+
}
|
|
52580
52688
|
} else if (key.tab) {
|
|
52581
52689
|
setIsSearching(true);
|
|
52582
52690
|
const newFiltered = !isFiltered;
|
|
@@ -52863,7 +52971,7 @@ async function defaultBrowserId() {
|
|
|
52863
52971
|
// ../../node_modules/run-applescript/index.js
|
|
52864
52972
|
import process16 from "node:process";
|
|
52865
52973
|
import { promisify as promisify4 } from "node:util";
|
|
52866
|
-
import { execFile as execFile4, execFileSync } from "node:child_process";
|
|
52974
|
+
import { execFile as execFile4, execFileSync as execFileSync2 } from "node:child_process";
|
|
52867
52975
|
var execFileAsync2 = promisify4(execFile4);
|
|
52868
52976
|
async function runAppleScript(script, { humanReadableOutput = true, signal } = {}) {
|
|
52869
52977
|
if (process16.platform !== "darwin") {
|
|
@@ -53572,6 +53680,7 @@ function InfoScreen() {
|
|
|
53572
53680
|
fetchData();
|
|
53573
53681
|
}, [params.componentId, params.component]);
|
|
53574
53682
|
const datasheetUrl = component && ("datasheetPdf" in component ? component.datasheetPdf : ("datasheet" in component) ? component.datasheet : undefined);
|
|
53683
|
+
const componentLcscId = component?.lcscId ?? params.componentId;
|
|
53575
53684
|
const [isRegenerating, setIsRegenerating] = import_react30.useState(false);
|
|
53576
53685
|
const [isDeleting, setIsDeleting] = import_react30.useState(false);
|
|
53577
53686
|
const [regenerateMessage, setRegenerateMessage] = import_react30.useState(null);
|
|
@@ -53579,10 +53688,10 @@ function InfoScreen() {
|
|
|
53579
53688
|
if (isLoading || !component || isCheckingLibrary || isRegenerating || isDeleting)
|
|
53580
53689
|
return;
|
|
53581
53690
|
const lowerInput = input.toLowerCase();
|
|
53582
|
-
if (lowerInput === "r" && installedInfo) {
|
|
53691
|
+
if (lowerInput === "r" && installedInfo && componentLcscId) {
|
|
53583
53692
|
setIsRegenerating(true);
|
|
53584
53693
|
setRegenerateMessage("Regenerating symbol and footprint...");
|
|
53585
|
-
libraryService.install(
|
|
53694
|
+
libraryService.install(componentLcscId, { force: true }).then((result2) => {
|
|
53586
53695
|
setRegenerateMessage(`✓ Regenerated: ${result2.symbolAction}`);
|
|
53587
53696
|
setTimeout(() => setRegenerateMessage(null), 2000);
|
|
53588
53697
|
}).catch((err) => {
|
|
@@ -53609,20 +53718,25 @@ function InfoScreen() {
|
|
|
53609
53718
|
return;
|
|
53610
53719
|
}
|
|
53611
53720
|
if (key.return && !installedInfo) {
|
|
53721
|
+
if (!componentLcscId) {
|
|
53722
|
+
setRegenerateMessage("✗ Missing LCSC part number");
|
|
53723
|
+
setTimeout(() => setRegenerateMessage(null), 3000);
|
|
53724
|
+
return;
|
|
53725
|
+
}
|
|
53612
53726
|
if (checkingRef.current)
|
|
53613
53727
|
return;
|
|
53614
53728
|
checkingRef.current = true;
|
|
53615
53729
|
setIsCheckingLibrary(true);
|
|
53616
53730
|
if (libraryStatus && (!libraryStatus.installed || !libraryStatus.linked)) {
|
|
53617
53731
|
push("library-setup", {
|
|
53618
|
-
componentId:
|
|
53732
|
+
componentId: componentLcscId,
|
|
53619
53733
|
component
|
|
53620
53734
|
});
|
|
53621
53735
|
setIsCheckingLibrary(false);
|
|
53622
53736
|
checkingRef.current = false;
|
|
53623
53737
|
} else {
|
|
53624
53738
|
push("install", {
|
|
53625
|
-
componentId:
|
|
53739
|
+
componentId: componentLcscId,
|
|
53626
53740
|
component
|
|
53627
53741
|
});
|
|
53628
53742
|
setIsCheckingLibrary(false);
|
|
@@ -53670,6 +53784,21 @@ function InfoScreen() {
|
|
|
53670
53784
|
]
|
|
53671
53785
|
}, undefined, true, undefined, this);
|
|
53672
53786
|
}
|
|
53787
|
+
if (!componentLcscId) {
|
|
53788
|
+
return /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Box_default, {
|
|
53789
|
+
flexDirection: "column",
|
|
53790
|
+
children: [
|
|
53791
|
+
/* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
|
|
53792
|
+
color: "red",
|
|
53793
|
+
children: "✗ Missing LCSC part number"
|
|
53794
|
+
}, undefined, false, undefined, this),
|
|
53795
|
+
/* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
|
|
53796
|
+
dimColor: true,
|
|
53797
|
+
children: "Press Esc to go back"
|
|
53798
|
+
}, undefined, false, undefined, this)
|
|
53799
|
+
]
|
|
53800
|
+
}, undefined, true, undefined, this);
|
|
53801
|
+
}
|
|
53673
53802
|
return /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Box_default, {
|
|
53674
53803
|
flexDirection: "column",
|
|
53675
53804
|
children: [
|
|
@@ -53681,7 +53810,7 @@ function InfoScreen() {
|
|
|
53681
53810
|
"Component: ",
|
|
53682
53811
|
/* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
|
|
53683
53812
|
color: "cyan",
|
|
53684
|
-
children:
|
|
53813
|
+
children: componentLcscId
|
|
53685
53814
|
}, undefined, false, undefined, this),
|
|
53686
53815
|
" ",
|
|
53687
53816
|
/* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
|
|
@@ -53700,7 +53829,7 @@ function InfoScreen() {
|
|
|
53700
53829
|
}, undefined, true, undefined, this)
|
|
53701
53830
|
}, undefined, false, undefined, this),
|
|
53702
53831
|
/* @__PURE__ */ jsx_dev_runtime7.jsxDEV(DetailView, {
|
|
53703
|
-
component,
|
|
53832
|
+
component: { ...component, lcscId: componentLcscId },
|
|
53704
53833
|
terminalWidth,
|
|
53705
53834
|
isInstalled: !!installedInfo,
|
|
53706
53835
|
installedInfo,
|
|
@@ -53923,7 +54052,7 @@ function InstalledScreen() {
|
|
|
53923
54052
|
}, undefined, true, undefined, this)
|
|
53924
54053
|
}, undefined, false, undefined, this),
|
|
53925
54054
|
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(InstalledView, {
|
|
53926
|
-
component: params.component,
|
|
54055
|
+
component: { ...params.component, lcscId: params.componentId },
|
|
53927
54056
|
result: result2,
|
|
53928
54057
|
error: params.error || null,
|
|
53929
54058
|
terminalWidth
|
|
@@ -54972,10 +55101,53 @@ async function renderApp(initialScreen, initialParams) {
|
|
|
54972
55101
|
await instance.waitUntilExit();
|
|
54973
55102
|
}
|
|
54974
55103
|
|
|
55104
|
+
// src/utils/agent-output.ts
|
|
55105
|
+
function printJson(value) {
|
|
55106
|
+
process.stdout.write(`${JSON.stringify(value, null, 2)}
|
|
55107
|
+
`);
|
|
55108
|
+
}
|
|
55109
|
+
function printJsonError(code, message, options = {}) {
|
|
55110
|
+
const payload = {
|
|
55111
|
+
success: false,
|
|
55112
|
+
error: {
|
|
55113
|
+
code,
|
|
55114
|
+
message,
|
|
55115
|
+
retryable: options.retryable ?? false,
|
|
55116
|
+
details: options.details
|
|
55117
|
+
}
|
|
55118
|
+
};
|
|
55119
|
+
printJson(payload);
|
|
55120
|
+
}
|
|
55121
|
+
function getErrorMessage(error) {
|
|
55122
|
+
return error instanceof Error ? error.message : String(error);
|
|
55123
|
+
}
|
|
55124
|
+
|
|
55125
|
+
// src/utils/search-result-output.ts
|
|
55126
|
+
function formatSearchResultForJson(result2) {
|
|
55127
|
+
return {
|
|
55128
|
+
id: result2.id,
|
|
55129
|
+
id_type: result2.idType,
|
|
55130
|
+
lcsc_id: result2.idType === "lcsc" ? result2.lcscId : undefined,
|
|
55131
|
+
easyeda_uuid: result2.idType === "easyeda_uuid" ? result2.easyedaUuid ?? result2.id : undefined,
|
|
55132
|
+
name: result2.name,
|
|
55133
|
+
manufacturer: result2.manufacturer,
|
|
55134
|
+
description: result2.description,
|
|
55135
|
+
package: result2.package,
|
|
55136
|
+
datasheet: result2.datasheetPdf,
|
|
55137
|
+
stock: result2.stock,
|
|
55138
|
+
price: result2.price,
|
|
55139
|
+
library_type: result2.libraryType,
|
|
55140
|
+
category: result2.category,
|
|
55141
|
+
attributes: result2.attributes
|
|
55142
|
+
};
|
|
55143
|
+
}
|
|
55144
|
+
|
|
54975
55145
|
// src/commands/search.ts
|
|
54976
55146
|
var componentService5 = createComponentService();
|
|
54977
55147
|
async function searchCommand(query, options) {
|
|
54978
|
-
|
|
55148
|
+
if (!options.json) {
|
|
55149
|
+
console.log(`Searching for "${query}"...`);
|
|
55150
|
+
}
|
|
54979
55151
|
try {
|
|
54980
55152
|
let results = await componentService5.search(query, options);
|
|
54981
55153
|
if (!options.basicOnly) {
|
|
@@ -54988,17 +55160,58 @@ async function searchCommand(query, options) {
|
|
|
54988
55160
|
});
|
|
54989
55161
|
}
|
|
54990
55162
|
if (results.length === 0) {
|
|
55163
|
+
if (options.json) {
|
|
55164
|
+
printJson({
|
|
55165
|
+
success: true,
|
|
55166
|
+
query,
|
|
55167
|
+
count: 0,
|
|
55168
|
+
results: []
|
|
55169
|
+
});
|
|
55170
|
+
return;
|
|
55171
|
+
}
|
|
54991
55172
|
console.log("No components found. Try a different search term.");
|
|
54992
55173
|
return;
|
|
54993
55174
|
}
|
|
55175
|
+
if (options.json) {
|
|
55176
|
+
printJson({
|
|
55177
|
+
success: true,
|
|
55178
|
+
query,
|
|
55179
|
+
count: results.length,
|
|
55180
|
+
results: results.map(formatSearchResultForJson)
|
|
55181
|
+
});
|
|
55182
|
+
return;
|
|
55183
|
+
}
|
|
54994
55184
|
process.stdout.write("\x1B[1A\x1B[2K");
|
|
54995
55185
|
await renderApp("search", { query, results });
|
|
54996
55186
|
} catch (error) {
|
|
54997
|
-
|
|
55187
|
+
if (options.json) {
|
|
55188
|
+
printJsonError("search_failed", getErrorMessage(error), { retryable: true });
|
|
55189
|
+
} else {
|
|
55190
|
+
console.error(`Search failed: ${getErrorMessage(error)}`);
|
|
55191
|
+
}
|
|
54998
55192
|
process.exit(1);
|
|
54999
55193
|
}
|
|
55000
55194
|
}
|
|
55001
55195
|
|
|
55196
|
+
// src/commands/info.ts
|
|
55197
|
+
var componentService6 = createComponentService();
|
|
55198
|
+
async function infoCommand(id, options) {
|
|
55199
|
+
if (options.json) {
|
|
55200
|
+
try {
|
|
55201
|
+
const details = await componentService6.getDetails(id);
|
|
55202
|
+
printJson({
|
|
55203
|
+
success: true,
|
|
55204
|
+
component: details
|
|
55205
|
+
});
|
|
55206
|
+
} catch (error) {
|
|
55207
|
+
printJsonError("component_fetch_failed", getErrorMessage(error), { retryable: true });
|
|
55208
|
+
process.exit(1);
|
|
55209
|
+
}
|
|
55210
|
+
return;
|
|
55211
|
+
}
|
|
55212
|
+
await renderApp("info", { componentId: id });
|
|
55213
|
+
}
|
|
55214
|
+
|
|
55002
55215
|
// ../../node_modules/@clack/core/dist/index.mjs
|
|
55003
55216
|
var import_sisteransi = __toESM(require_src(), 1);
|
|
55004
55217
|
var import_picocolors = __toESM(require_picocolors(), 1);
|
|
@@ -55576,26 +55789,6 @@ var L2 = () => {
|
|
|
55576
55789
|
} };
|
|
55577
55790
|
};
|
|
55578
55791
|
|
|
55579
|
-
// src/commands/info.ts
|
|
55580
|
-
var componentService6 = createComponentService();
|
|
55581
|
-
async function infoCommand(id, options) {
|
|
55582
|
-
if (options.json) {
|
|
55583
|
-
const spinner = L2();
|
|
55584
|
-
spinner.start(`Fetching component ${id}...`);
|
|
55585
|
-
try {
|
|
55586
|
-
const details = await componentService6.getDetails(id);
|
|
55587
|
-
spinner.stop("Component found");
|
|
55588
|
-
console.log(JSON.stringify(details, null, 2));
|
|
55589
|
-
} catch (error) {
|
|
55590
|
-
spinner.stop("Failed to fetch component");
|
|
55591
|
-
v2.error(`Error: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
55592
|
-
process.exit(1);
|
|
55593
|
-
}
|
|
55594
|
-
return;
|
|
55595
|
-
}
|
|
55596
|
-
await renderApp("info", { componentId: id });
|
|
55597
|
-
}
|
|
55598
|
-
|
|
55599
55792
|
// src/commands/install.ts
|
|
55600
55793
|
var componentService7 = createComponentService();
|
|
55601
55794
|
var libraryService6 = createLibraryService();
|
|
@@ -55603,22 +55796,43 @@ function isLcscId(id) {
|
|
|
55603
55796
|
return /^C\d+$/i.test(id);
|
|
55604
55797
|
}
|
|
55605
55798
|
async function installCommand(id, options) {
|
|
55799
|
+
if (!id && (options.yes || options.json)) {
|
|
55800
|
+
if (options.json) {
|
|
55801
|
+
printJsonError("missing_id", "Direct install requires an LCSC part number");
|
|
55802
|
+
} else {
|
|
55803
|
+
v2.error("Direct install requires an LCSC part number.");
|
|
55804
|
+
}
|
|
55805
|
+
process.exit(1);
|
|
55806
|
+
}
|
|
55606
55807
|
if (id && !isLcscId(id)) {
|
|
55808
|
+
if (options.json) {
|
|
55809
|
+
printJsonError("invalid_lcsc_id", `"${id}" is not an LCSC part number`, {
|
|
55810
|
+
details: { hint: `Use jlc easyeda install ${id}` }
|
|
55811
|
+
});
|
|
55812
|
+
process.exit(1);
|
|
55813
|
+
}
|
|
55607
55814
|
v2.error(`"${id}" is not an LCSC part number (e.g., C2040).`);
|
|
55608
55815
|
v2.info(`For EasyEDA community components, use: ${source_default.cyan(`jlc easyeda install ${id}`)}`);
|
|
55609
55816
|
process.exit(1);
|
|
55610
55817
|
}
|
|
55611
|
-
if (id && options.
|
|
55612
|
-
const spinner = L2();
|
|
55613
|
-
spinner
|
|
55818
|
+
if (id && (options.yes || options.json)) {
|
|
55819
|
+
const spinner = options.json ? null : L2();
|
|
55820
|
+
spinner?.start(`Installing component ${id}...`);
|
|
55614
55821
|
try {
|
|
55615
55822
|
await libraryService6.ensureGlobalTables();
|
|
55616
55823
|
const result2 = await libraryService6.install(id, {
|
|
55617
55824
|
projectPath: options.projectPath,
|
|
55618
55825
|
include3d: options.include3d,
|
|
55619
|
-
force:
|
|
55826
|
+
force: options.force
|
|
55620
55827
|
});
|
|
55621
|
-
spinner
|
|
55828
|
+
spinner?.stop(source_default.green("✓ Component installed"));
|
|
55829
|
+
if (options.json) {
|
|
55830
|
+
printJson({
|
|
55831
|
+
success: true,
|
|
55832
|
+
result: result2
|
|
55833
|
+
});
|
|
55834
|
+
return;
|
|
55835
|
+
}
|
|
55622
55836
|
console.log();
|
|
55623
55837
|
console.log(source_default.cyan("Symbol: "), result2.symbolRef);
|
|
55624
55838
|
console.log(source_default.cyan("Footprint: "), result2.footprintRef);
|
|
@@ -55629,8 +55843,12 @@ async function installCommand(id, options) {
|
|
|
55629
55843
|
console.log();
|
|
55630
55844
|
console.log(source_default.dim(`Library: ${result2.files.symbolLibrary}`));
|
|
55631
55845
|
} catch (error) {
|
|
55632
|
-
spinner
|
|
55633
|
-
|
|
55846
|
+
spinner?.stop(source_default.red("✗ Installation failed"));
|
|
55847
|
+
if (options.json) {
|
|
55848
|
+
printJsonError("install_failed", getErrorMessage(error), { retryable: true });
|
|
55849
|
+
} else {
|
|
55850
|
+
v2.error(`Error: ${getErrorMessage(error)}`);
|
|
55851
|
+
}
|
|
55634
55852
|
process.exit(1);
|
|
55635
55853
|
}
|
|
55636
55854
|
return;
|
|
@@ -55682,15 +55900,13 @@ async function installCommand(id, options) {
|
|
|
55682
55900
|
var libraryService7 = createLibraryService();
|
|
55683
55901
|
async function libraryCommand(options) {
|
|
55684
55902
|
if (options.json) {
|
|
55685
|
-
const spinner = L2();
|
|
55686
|
-
spinner.start("Loading library status...");
|
|
55687
55903
|
try {
|
|
55688
55904
|
const [status, components] = await Promise.all([
|
|
55689
55905
|
libraryService7.getStatus(),
|
|
55690
55906
|
libraryService7.listInstalled({})
|
|
55691
55907
|
]);
|
|
55692
|
-
|
|
55693
|
-
|
|
55908
|
+
printJson({
|
|
55909
|
+
success: true,
|
|
55694
55910
|
status: {
|
|
55695
55911
|
installed: status.installed,
|
|
55696
55912
|
linked: status.linked,
|
|
@@ -55699,10 +55915,9 @@ async function libraryCommand(options) {
|
|
|
55699
55915
|
paths: status.paths
|
|
55700
55916
|
},
|
|
55701
55917
|
components
|
|
55702
|
-
}
|
|
55918
|
+
});
|
|
55703
55919
|
} catch (error) {
|
|
55704
|
-
|
|
55705
|
-
v2.error(`Error: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
55920
|
+
printJsonError("library_status_failed", getErrorMessage(error), { retryable: false });
|
|
55706
55921
|
process.exit(1);
|
|
55707
55922
|
}
|
|
55708
55923
|
return;
|
|
@@ -55748,6 +55963,24 @@ async function regenerateCommand(options) {
|
|
|
55748
55963
|
var componentService8 = createComponentService();
|
|
55749
55964
|
var libraryService8 = createLibraryService();
|
|
55750
55965
|
async function easyedaSearchCommand(query, options) {
|
|
55966
|
+
if (options.json) {
|
|
55967
|
+
try {
|
|
55968
|
+
const results = await componentService8.search(query, {
|
|
55969
|
+
limit: 20,
|
|
55970
|
+
source: "easyeda-community"
|
|
55971
|
+
});
|
|
55972
|
+
printJson({
|
|
55973
|
+
success: true,
|
|
55974
|
+
query,
|
|
55975
|
+
count: results.length,
|
|
55976
|
+
results: results.map(formatSearchResultForJson)
|
|
55977
|
+
});
|
|
55978
|
+
} catch (error) {
|
|
55979
|
+
printJsonError("easyeda_search_failed", getErrorMessage(error), { retryable: true });
|
|
55980
|
+
process.exit(1);
|
|
55981
|
+
}
|
|
55982
|
+
return;
|
|
55983
|
+
}
|
|
55751
55984
|
const port = options.port ?? 3847;
|
|
55752
55985
|
console.log("Starting component browser...");
|
|
55753
55986
|
startHttpServer({
|
|
@@ -55755,7 +55988,13 @@ async function easyedaSearchCommand(query, options) {
|
|
|
55755
55988
|
onReady: async (url) => {
|
|
55756
55989
|
const searchUrl = query ? `${url}?q=${encodeURIComponent(query)}` : url;
|
|
55757
55990
|
console.log(`Browser opened at ${searchUrl}`);
|
|
55758
|
-
|
|
55991
|
+
if (options.open !== false) {
|
|
55992
|
+
await open_default(searchUrl);
|
|
55993
|
+
}
|
|
55994
|
+
if (options.once) {
|
|
55995
|
+
stopHttpServer();
|
|
55996
|
+
process.exit(0);
|
|
55997
|
+
}
|
|
55759
55998
|
console.log("Press Ctrl+C to stop the server and exit");
|
|
55760
55999
|
}
|
|
55761
56000
|
});
|
|
@@ -55770,17 +56009,32 @@ Shutting down server...`);
|
|
|
55770
56009
|
});
|
|
55771
56010
|
}
|
|
55772
56011
|
async function easyedaInstallCommand(uuid, options) {
|
|
55773
|
-
if (uuid && options.
|
|
55774
|
-
|
|
55775
|
-
|
|
56012
|
+
if (!uuid && (options.yes || options.json)) {
|
|
56013
|
+
if (options.json) {
|
|
56014
|
+
printJsonError("missing_uuid", "Direct EasyEDA install requires a component UUID");
|
|
56015
|
+
} else {
|
|
56016
|
+
v2.error("Direct EasyEDA install requires a component UUID.");
|
|
56017
|
+
}
|
|
56018
|
+
process.exit(1);
|
|
56019
|
+
}
|
|
56020
|
+
if (uuid && (options.yes || options.json)) {
|
|
56021
|
+
const spinner = options.json ? null : L2();
|
|
56022
|
+
spinner?.start(`Installing EasyEDA component ${uuid}...`);
|
|
55776
56023
|
try {
|
|
55777
56024
|
await libraryService8.ensureGlobalTables();
|
|
55778
56025
|
const result2 = await libraryService8.install(uuid, {
|
|
55779
56026
|
projectPath: options.projectPath,
|
|
55780
56027
|
include3d: options.include3d,
|
|
55781
|
-
force:
|
|
56028
|
+
force: options.force
|
|
55782
56029
|
});
|
|
55783
|
-
spinner
|
|
56030
|
+
spinner?.stop(source_default.green("✓ Component installed"));
|
|
56031
|
+
if (options.json) {
|
|
56032
|
+
printJson({
|
|
56033
|
+
success: true,
|
|
56034
|
+
result: result2
|
|
56035
|
+
});
|
|
56036
|
+
return;
|
|
56037
|
+
}
|
|
55784
56038
|
console.log();
|
|
55785
56039
|
console.log(source_default.cyan("Symbol: "), result2.symbolRef);
|
|
55786
56040
|
console.log(source_default.cyan("Footprint: "), result2.footprintRef);
|
|
@@ -55791,8 +56045,12 @@ async function easyedaInstallCommand(uuid, options) {
|
|
|
55791
56045
|
console.log();
|
|
55792
56046
|
console.log(source_default.dim(`Library: ${result2.files.symbolLibrary}`));
|
|
55793
56047
|
} catch (error) {
|
|
55794
|
-
spinner
|
|
55795
|
-
|
|
56048
|
+
spinner?.stop(source_default.red("✗ Installation failed"));
|
|
56049
|
+
if (options.json) {
|
|
56050
|
+
printJsonError("easyeda_install_failed", getErrorMessage(error), { retryable: true });
|
|
56051
|
+
} else {
|
|
56052
|
+
v2.error(`Error: ${getErrorMessage(error)}`);
|
|
56053
|
+
}
|
|
55796
56054
|
process.exit(1);
|
|
55797
56055
|
}
|
|
55798
56056
|
return;
|
|
@@ -55894,33 +56152,25 @@ async function validateComponent(lcscCode, options) {
|
|
|
55894
56152
|
}
|
|
55895
56153
|
}
|
|
55896
56154
|
async function validateCommand(id, options) {
|
|
56155
|
+
if (options.footprintOnly && options.symbolOnly) {
|
|
56156
|
+
if (options.json) {
|
|
56157
|
+
printJsonError("invalid_options", "--footprint-only and --symbol-only are mutually exclusive");
|
|
56158
|
+
} else {
|
|
56159
|
+
v2.error("--footprint-only and --symbol-only are mutually exclusive");
|
|
56160
|
+
}
|
|
56161
|
+
process.exit(1);
|
|
56162
|
+
}
|
|
55897
56163
|
const validateFootprint = !options.symbolOnly;
|
|
55898
56164
|
const validateSymbol = !options.footprintOnly;
|
|
55899
56165
|
if (id && !options.category && !options.all) {
|
|
55900
|
-
const spinner = L2();
|
|
55901
|
-
spinner
|
|
56166
|
+
const spinner = options.json ? null : L2();
|
|
56167
|
+
spinner?.start(`Validating ${id}...`);
|
|
55902
56168
|
const result2 = await validateComponent(id, {
|
|
55903
56169
|
footprint: validateFootprint,
|
|
55904
56170
|
symbol: validateSymbol
|
|
55905
56171
|
});
|
|
55906
|
-
spinner
|
|
55907
|
-
|
|
55908
|
-
console.log(source_default.bold(`${result2.componentName} (${result2.lcscCode})`));
|
|
55909
|
-
console.log(source_default.dim(`Duration: ${result2.durationMs}ms`));
|
|
55910
|
-
console.log();
|
|
55911
|
-
if (result2.error) {
|
|
55912
|
-
console.log(source_default.red(`Error: ${result2.error}`));
|
|
55913
|
-
process.exit(1);
|
|
55914
|
-
}
|
|
55915
|
-
if (result2.footprint) {
|
|
55916
|
-
console.log(formatComparisonResult(result2.footprint));
|
|
55917
|
-
}
|
|
55918
|
-
if (result2.symbol) {
|
|
55919
|
-
console.log(formatSymbolComparisonResult(result2.symbol));
|
|
55920
|
-
}
|
|
55921
|
-
if (options.json) {
|
|
55922
|
-
console.log(JSON.stringify(result2, null, 2));
|
|
55923
|
-
}
|
|
56172
|
+
spinner?.stop(result2.passed ? source_default.green("✓ Validation passed") : source_default.red("✗ Validation failed"));
|
|
56173
|
+
let htmlPath2;
|
|
55924
56174
|
if (options.html) {
|
|
55925
56175
|
const reference = await fetchReferenceSVG(id);
|
|
55926
56176
|
const componentData = await easyedaClient.getComponentData(id);
|
|
@@ -55942,12 +56192,41 @@ async function validateCommand(id, options) {
|
|
|
55942
56192
|
}
|
|
55943
56193
|
const html = generateValidationReport(result2, svgs);
|
|
55944
56194
|
writeFileSync(options.html, html);
|
|
55945
|
-
|
|
56195
|
+
htmlPath2 = options.html;
|
|
56196
|
+
}
|
|
56197
|
+
if (options.json) {
|
|
56198
|
+
printJson({
|
|
56199
|
+
success: result2.passed && !result2.error,
|
|
56200
|
+
result: result2,
|
|
56201
|
+
html: htmlPath2
|
|
56202
|
+
});
|
|
56203
|
+
process.exit(result2.passed && !result2.error ? 0 : 1);
|
|
56204
|
+
}
|
|
56205
|
+
console.log();
|
|
56206
|
+
console.log(source_default.bold(`${result2.componentName} (${result2.lcscCode})`));
|
|
56207
|
+
console.log(source_default.dim(`Duration: ${result2.durationMs}ms`));
|
|
56208
|
+
console.log();
|
|
56209
|
+
if (result2.error) {
|
|
56210
|
+
console.log(source_default.red(`Error: ${result2.error}`));
|
|
56211
|
+
process.exit(1);
|
|
56212
|
+
}
|
|
56213
|
+
if (result2.footprint) {
|
|
56214
|
+
console.log(formatComparisonResult(result2.footprint));
|
|
56215
|
+
}
|
|
56216
|
+
if (result2.symbol) {
|
|
56217
|
+
console.log(formatSymbolComparisonResult(result2.symbol));
|
|
56218
|
+
}
|
|
56219
|
+
if (htmlPath2) {
|
|
56220
|
+
console.log(source_default.dim(`HTML report: ${htmlPath2}`));
|
|
55946
56221
|
}
|
|
55947
56222
|
process.exit(result2.passed ? 0 : 1);
|
|
55948
56223
|
}
|
|
55949
56224
|
let components = options.all ? getAllTestComponents() : options.category ? getTestComponentsByCategory(options.category) : [];
|
|
55950
56225
|
if (components.length === 0 && !id) {
|
|
56226
|
+
if (options.json) {
|
|
56227
|
+
printJsonError("missing_validation_target", "JSON validation requires an id, --category, or --all");
|
|
56228
|
+
process.exit(1);
|
|
56229
|
+
}
|
|
55951
56230
|
const categories = getCategoryNames();
|
|
55952
56231
|
const selected = await de({
|
|
55953
56232
|
message: "Select a category to validate:",
|
|
@@ -55964,18 +56243,30 @@ async function validateCommand(id, options) {
|
|
|
55964
56243
|
}
|
|
55965
56244
|
components = components.filter((c2) => !c2.skip);
|
|
55966
56245
|
if (components.length === 0) {
|
|
56246
|
+
if (options.json) {
|
|
56247
|
+
printJson({
|
|
56248
|
+
success: true,
|
|
56249
|
+
summary: { total: 0, passed: 0, failed: 0, errors: 0 },
|
|
56250
|
+
results: []
|
|
56251
|
+
});
|
|
56252
|
+
process.exit(0);
|
|
56253
|
+
}
|
|
55967
56254
|
v2.warn("No components to validate");
|
|
55968
56255
|
process.exit(0);
|
|
55969
56256
|
}
|
|
55970
|
-
|
|
56257
|
+
if (!options.json) {
|
|
56258
|
+
console.log(source_default.bold(`
|
|
55971
56259
|
Validating ${components.length} components...
|
|
55972
56260
|
`));
|
|
56261
|
+
}
|
|
55973
56262
|
const results = [];
|
|
55974
56263
|
let passed = 0;
|
|
55975
56264
|
let failed = 0;
|
|
55976
56265
|
let errors = 0;
|
|
55977
56266
|
for (const component of components) {
|
|
55978
|
-
|
|
56267
|
+
if (!options.json) {
|
|
56268
|
+
process.stdout.write(` ${component.lcsc.padEnd(12)} ${component.name.slice(0, 40).padEnd(42)} `);
|
|
56269
|
+
}
|
|
55979
56270
|
const result2 = await validateComponent(component.lcsc, {
|
|
55980
56271
|
footprint: validateFootprint,
|
|
55981
56272
|
symbol: validateSymbol
|
|
@@ -55983,49 +56274,79 @@ Validating ${components.length} components...
|
|
|
55983
56274
|
results.push(result2);
|
|
55984
56275
|
if (result2.error) {
|
|
55985
56276
|
errors++;
|
|
55986
|
-
|
|
56277
|
+
if (!options.json)
|
|
56278
|
+
console.log(source_default.yellow("⚠ ERROR"));
|
|
55987
56279
|
} else if (result2.passed) {
|
|
55988
56280
|
passed++;
|
|
55989
|
-
|
|
56281
|
+
if (!options.json)
|
|
56282
|
+
console.log(source_default.green("✓ PASS"));
|
|
55990
56283
|
} else {
|
|
55991
56284
|
failed++;
|
|
55992
|
-
|
|
56285
|
+
if (!options.json)
|
|
56286
|
+
console.log(source_default.red("✗ FAIL"));
|
|
55993
56287
|
}
|
|
55994
56288
|
}
|
|
56289
|
+
let htmlPath;
|
|
56290
|
+
if (options.html) {
|
|
56291
|
+
const html = generateBatchReport(results, "JLC-CLI Validation Report");
|
|
56292
|
+
writeFileSync(options.html, html);
|
|
56293
|
+
htmlPath = options.html;
|
|
56294
|
+
}
|
|
56295
|
+
if (options.json) {
|
|
56296
|
+
printJson({
|
|
56297
|
+
success: failed === 0 && errors === 0,
|
|
56298
|
+
summary: {
|
|
56299
|
+
total: results.length,
|
|
56300
|
+
passed,
|
|
56301
|
+
failed,
|
|
56302
|
+
errors
|
|
56303
|
+
},
|
|
56304
|
+
results,
|
|
56305
|
+
html: htmlPath
|
|
56306
|
+
});
|
|
56307
|
+
process.exit(failed > 0 || errors > 0 ? 1 : 0);
|
|
56308
|
+
}
|
|
55995
56309
|
console.log();
|
|
55996
56310
|
console.log(source_default.bold("Summary:"));
|
|
55997
56311
|
console.log(` ${source_default.green(`${passed} passed`)} ${source_default.red(`${failed} failed`)} ${source_default.yellow(`${errors} errors`)}`);
|
|
55998
56312
|
console.log();
|
|
55999
|
-
if (
|
|
56000
|
-
console.log(
|
|
56001
|
-
}
|
|
56002
|
-
if (options.html) {
|
|
56003
|
-
const html = generateBatchReport(results, "JLC-CLI Validation Report");
|
|
56004
|
-
writeFileSync(options.html, html);
|
|
56005
|
-
console.log(source_default.dim(`HTML report: ${options.html}`));
|
|
56313
|
+
if (htmlPath) {
|
|
56314
|
+
console.log(source_default.dim(`HTML report: ${htmlPath}`));
|
|
56006
56315
|
}
|
|
56007
56316
|
process.exit(failed > 0 || errors > 0 ? 1 : 0);
|
|
56008
56317
|
}
|
|
56009
56318
|
|
|
56010
56319
|
// src/index.ts
|
|
56320
|
+
var require2 = createRequire2(import.meta.url);
|
|
56321
|
+
var { version } = require2("../package.json");
|
|
56011
56322
|
var program2 = new Command;
|
|
56012
|
-
|
|
56013
|
-
|
|
56323
|
+
function parsePositiveInt(value) {
|
|
56324
|
+
const parsed = Number.parseInt(value, 10);
|
|
56325
|
+
if (!Number.isInteger(parsed) || parsed <= 0) {
|
|
56326
|
+
throw new Error(`Expected a positive integer, got "${value}"`);
|
|
56327
|
+
}
|
|
56328
|
+
return parsed;
|
|
56329
|
+
}
|
|
56330
|
+
program2.name("jlc").description("JLC/EasyEDA component sourcing and KiCad library management").version(version);
|
|
56331
|
+
program2.command("search <query...>").description("Search for components (basic parts sorted first)").option("-l, --limit <number>", "Maximum results", parsePositiveInt, 20).option("--in-stock", "Only show in-stock components").option("--basic-only", "Only show basic parts (no extended)").option("--community", "Search EasyEDA community library").option("--json", "Output clean JSON and do not launch the TUI").action(async (queryParts, options) => {
|
|
56014
56332
|
const query = queryParts.join(" ");
|
|
56015
56333
|
await searchCommand(query, {
|
|
56016
|
-
limit:
|
|
56334
|
+
limit: options.limit,
|
|
56017
56335
|
inStock: options.inStock,
|
|
56018
56336
|
basicOnly: options.basicOnly || false,
|
|
56019
|
-
source: options.community ? "easyeda-community" : "lcsc"
|
|
56337
|
+
source: options.community ? "easyeda-community" : "lcsc",
|
|
56338
|
+
json: options.json
|
|
56020
56339
|
});
|
|
56021
56340
|
});
|
|
56022
56341
|
program2.command("info <id>").description("Get component details").option("--json", "Output as JSON").action(async (id, options) => {
|
|
56023
56342
|
await infoCommand(id, { json: options.json });
|
|
56024
56343
|
});
|
|
56025
|
-
program2.command("install [id]").description("Install component to KiCad libraries").option("-p, --project <path>", "Install to project-local library").option("--with-3d", "Include 3D model").option("-f, --force", "Force reinstall (regenerate symbol and footprint)").action(async (id, options) => {
|
|
56344
|
+
program2.command("install [id]").description("Install component to KiCad libraries").option("-p, --project <path>", "Install to project-local library").option("--with-3d", "Include 3D model").option("-y, --yes", "Install directly without launching the TUI").option("--json", "Output clean JSON and install directly").option("-f, --force", "Force reinstall (regenerate symbol and footprint)").action(async (id, options) => {
|
|
56026
56345
|
await installCommand(id, {
|
|
56027
56346
|
projectPath: options.project,
|
|
56028
56347
|
include3d: options.with3d,
|
|
56348
|
+
yes: options.yes,
|
|
56349
|
+
json: options.json,
|
|
56029
56350
|
force: options.force
|
|
56030
56351
|
});
|
|
56031
56352
|
});
|
|
@@ -56052,17 +56373,25 @@ program2.command("validate [id]").description("Validate footprint/symbol generat
|
|
|
56052
56373
|
});
|
|
56053
56374
|
});
|
|
56054
56375
|
var easyeda = program2.command("easyeda").description("EasyEDA community component browser");
|
|
56055
|
-
easyeda.command("search <query...>").description("Open browser-based component search").option("-p, --port <number>", "HTTP server port",
|
|
56376
|
+
easyeda.command("search <query...>").description("Open browser-based component search").option("-p, --port <number>", "HTTP server port", parsePositiveInt, 3847).option("--json", "Output clean JSON search results and do not open a browser").option("--no-open", "Start the browser server without opening a browser").option("--once", "Print the browser URL and exit after the server is ready").action(async (queryParts, options) => {
|
|
56056
56377
|
const query = queryParts.join(" ");
|
|
56057
56378
|
await easyedaSearchCommand(query, {
|
|
56058
|
-
port: options.port
|
|
56379
|
+
port: options.port,
|
|
56380
|
+
json: options.json,
|
|
56381
|
+
open: options.open,
|
|
56382
|
+
once: options.once
|
|
56059
56383
|
});
|
|
56060
56384
|
});
|
|
56061
|
-
easyeda.command("install [uuid]").description("Install EasyEDA community component to KiCad libraries").option("-p, --project <path>", "Install to project-local library").option("--with-3d", "Include 3D model").option("-f, --force", "Force reinstall (regenerate symbol and footprint)").action(async (uuid, options) => {
|
|
56385
|
+
easyeda.command("install [uuid]").description("Install EasyEDA community component to KiCad libraries").option("-p, --project <path>", "Install to project-local library").option("--with-3d", "Include 3D model").option("-y, --yes", "Install directly without launching the TUI").option("--json", "Output clean JSON and install directly").option("-f, --force", "Force reinstall (regenerate symbol and footprint)").action(async (uuid, options) => {
|
|
56062
56386
|
await easyedaInstallCommand(uuid, {
|
|
56063
56387
|
projectPath: options.project,
|
|
56064
56388
|
include3d: options.with3d,
|
|
56389
|
+
yes: options.yes,
|
|
56390
|
+
json: options.json,
|
|
56065
56391
|
force: options.force
|
|
56066
56392
|
});
|
|
56067
56393
|
});
|
|
56068
|
-
program2.
|
|
56394
|
+
program2.parseAsync().catch((error) => {
|
|
56395
|
+
console.error(`Error: ${getErrorMessage(error)}`);
|
|
56396
|
+
process.exit(1);
|
|
56397
|
+
});
|