easyeda-mcp-pro 0.4.0 → 0.5.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/README.md +68 -24
- package/dist/bom-quality/adapter.d.ts +90 -0
- package/dist/bom-quality/adapter.js +295 -0
- package/dist/bom-quality/adapter.js.map +1 -0
- package/dist/bom-quality/index.d.ts +10 -0
- package/dist/bom-quality/index.js +9 -0
- package/dist/bom-quality/index.js.map +1 -0
- package/dist/bom-quality/quality.d.ts +28 -0
- package/dist/bom-quality/quality.js +179 -0
- package/dist/bom-quality/quality.js.map +1 -0
- package/dist/bom-quality/types.d.ts +94 -0
- package/dist/bom-quality/types.js +12 -0
- package/dist/bom-quality/types.js.map +1 -0
- package/dist/bridge/manager.d.ts +41 -0
- package/dist/bridge/manager.js +333 -51
- package/dist/bridge/manager.js.map +1 -1
- package/dist/bridge/protocol.d.ts +47 -1
- package/dist/bridge/protocol.js +42 -1
- package/dist/bridge/protocol.js.map +1 -1
- package/dist/bridge/types.d.ts +6 -0
- package/dist/bridge/types.js +6 -0
- package/dist/bridge/types.js.map +1 -1
- package/dist/catalog/errors.d.ts +49 -0
- package/dist/catalog/errors.js +60 -0
- package/dist/catalog/errors.js.map +1 -0
- package/dist/catalog/index.d.ts +15 -0
- package/dist/catalog/index.js +17 -0
- package/dist/catalog/index.js.map +1 -0
- package/dist/catalog/schema.d.ts +268 -0
- package/dist/catalog/schema.js +245 -0
- package/dist/catalog/schema.js.map +1 -0
- package/dist/catalog/starter.d.ts +159 -0
- package/dist/catalog/starter.js +579 -0
- package/dist/catalog/starter.js.map +1 -0
- package/dist/catalog/validation.d.ts +48 -0
- package/dist/catalog/validation.js +263 -0
- package/dist/catalog/validation.js.map +1 -0
- package/dist/circuit/circuit-ir.d.ts +460 -0
- package/dist/circuit/circuit-ir.js +292 -0
- package/dist/circuit/circuit-ir.js.map +1 -0
- package/dist/circuit/compiler.d.ts +55 -0
- package/dist/circuit/compiler.js +197 -0
- package/dist/circuit/compiler.js.map +1 -0
- package/dist/circuit/design-intent.d.ts +94 -0
- package/dist/circuit/design-intent.js +118 -0
- package/dist/circuit/design-intent.js.map +1 -0
- package/dist/circuit/errors.d.ts +50 -0
- package/dist/circuit/errors.js +61 -0
- package/dist/circuit/errors.js.map +1 -0
- package/dist/circuit/index.d.ts +17 -0
- package/dist/circuit/index.js +18 -0
- package/dist/circuit/index.js.map +1 -0
- package/dist/circuit/types.d.ts +186 -0
- package/dist/circuit/types.js +123 -0
- package/dist/circuit/types.js.map +1 -0
- package/dist/cli/auto-setup.d.ts +1 -8
- package/dist/cli/auto-setup.js +10 -178
- package/dist/cli/auto-setup.js.map +1 -1
- package/dist/cli/client-definitions.d.ts +34 -0
- package/dist/cli/client-definitions.js +194 -0
- package/dist/cli/client-definitions.js.map +1 -0
- package/dist/cli/local-setup.js +2 -2
- package/dist/cli/local-setup.js.map +1 -1
- package/dist/config/env.d.ts +6 -1
- package/dist/config/env.js +93 -5
- package/dist/config/env.js.map +1 -1
- package/dist/config/version.d.ts +1 -1
- package/dist/config/version.js +1 -1
- package/dist/export-manifest/errors.d.ts +55 -0
- package/dist/export-manifest/errors.js +69 -0
- package/dist/export-manifest/errors.js.map +1 -0
- package/dist/export-manifest/index.d.ts +10 -0
- package/dist/export-manifest/index.js +9 -0
- package/dist/export-manifest/index.js.map +1 -0
- package/dist/export-manifest/types.d.ts +170 -0
- package/dist/export-manifest/types.js +36 -0
- package/dist/export-manifest/types.js.map +1 -0
- package/dist/export-manifest/validation.d.ts +39 -0
- package/dist/export-manifest/validation.js +298 -0
- package/dist/export-manifest/validation.js.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/net-validation/errors.d.ts +89 -0
- package/dist/net-validation/errors.js +69 -0
- package/dist/net-validation/errors.js.map +1 -0
- package/dist/net-validation/fixtures.d.ts +38 -0
- package/dist/net-validation/fixtures.js +215 -0
- package/dist/net-validation/fixtures.js.map +1 -0
- package/dist/net-validation/index.d.ts +10 -0
- package/dist/net-validation/index.js +9 -0
- package/dist/net-validation/index.js.map +1 -0
- package/dist/net-validation/schema.d.ts +118 -0
- package/dist/net-validation/schema.js +140 -0
- package/dist/net-validation/schema.js.map +1 -0
- package/dist/net-validation/validation.d.ts +45 -0
- package/dist/net-validation/validation.js +369 -0
- package/dist/net-validation/validation.js.map +1 -0
- package/dist/pcb-constraints/errors.d.ts +39 -0
- package/dist/pcb-constraints/errors.js +133 -0
- package/dist/pcb-constraints/errors.js.map +1 -0
- package/dist/pcb-constraints/index.d.ts +9 -0
- package/dist/pcb-constraints/index.js +9 -0
- package/dist/pcb-constraints/index.js.map +1 -0
- package/dist/pcb-constraints/types.d.ts +102 -0
- package/dist/pcb-constraints/types.js +7 -0
- package/dist/pcb-constraints/types.js.map +1 -0
- package/dist/pcb-constraints/validation.d.ts +70 -0
- package/dist/pcb-constraints/validation.js +309 -0
- package/dist/pcb-constraints/validation.js.map +1 -0
- package/dist/server/factory.js +2 -0
- package/dist/server/factory.js.map +1 -1
- package/dist/server/transports/http.d.ts +20 -1
- package/dist/server/transports/http.js +156 -34
- package/dist/server/transports/http.js.map +1 -1
- package/dist/storage/database.d.ts +25 -0
- package/dist/storage/database.js +126 -51
- package/dist/storage/database.js.map +1 -1
- package/dist/tools/{L0_diagnostics.d.ts → L0_diagnostics_api.d.ts} +2 -2
- package/dist/tools/L0_diagnostics_api.js +152 -0
- package/dist/tools/L0_diagnostics_api.js.map +1 -0
- package/dist/tools/L0_diagnostics_core.d.ts +6 -0
- package/dist/tools/{L0_diagnostics.js → L0_diagnostics_core.js} +50 -124
- package/dist/tools/L0_diagnostics_core.js.map +1 -0
- package/dist/tools/L1_board.js +20 -4
- package/dist/tools/L1_board.js.map +1 -1
- package/dist/tools/{L1_bom.d.ts → L1_bom_core.d.ts} +2 -2
- package/dist/tools/{L1_bom.js → L1_bom_core.js} +21 -101
- package/dist/tools/L1_bom_core.js.map +1 -0
- package/dist/tools/{L1_schematic.d.ts → L1_bom_sourcing.d.ts} +2 -2
- package/dist/tools/L1_bom_sourcing.js +265 -0
- package/dist/tools/L1_bom_sourcing.js.map +1 -0
- package/dist/tools/L1_drc_erc.js +15 -3
- package/dist/tools/L1_drc_erc.js.map +1 -1
- package/dist/tools/L1_export.js +20 -4
- package/dist/tools/L1_export.js.map +1 -1
- package/dist/tools/L1_pcb_constraints.d.ts +6 -0
- package/dist/tools/L1_pcb_constraints.js +234 -0
- package/dist/tools/L1_pcb_constraints.js.map +1 -0
- package/dist/tools/L1_pcb_write.js +26 -12
- package/dist/tools/L1_pcb_write.js.map +1 -1
- package/dist/tools/L1_schematic_read.d.ts +6 -0
- package/dist/tools/{L1_schematic.js → L1_schematic_read.js} +125 -194
- package/dist/tools/L1_schematic_read.js.map +1 -0
- package/dist/tools/L1_schematic_write.d.ts +6 -0
- package/dist/tools/L1_schematic_write.js +516 -0
- package/dist/tools/L1_schematic_write.js.map +1 -0
- package/dist/tools/register.js +15 -7
- package/dist/tools/register.js.map +1 -1
- package/dist/tools/registry.d.ts +41 -7
- package/dist/tools/registry.js +95 -25
- package/dist/tools/registry.js.map +1 -1
- package/dist/tools/types.d.ts +16 -0
- package/dist/utils/logger.d.ts +1 -1
- package/dist/utils/logger.js +1 -1
- package/dist/utils/logger.js.map +1 -1
- package/dist/vendors/base-http-client.d.ts +48 -0
- package/dist/vendors/base-http-client.js +75 -0
- package/dist/vendors/base-http-client.js.map +1 -0
- package/dist/vendors/digikey/client.js +10 -19
- package/dist/vendors/digikey/client.js.map +1 -1
- package/dist/vendors/jlcpcb/client.js +41 -70
- package/dist/vendors/jlcpcb/client.js.map +1 -1
- package/dist/vendors/lcsc/client.js +5 -18
- package/dist/vendors/lcsc/client.js.map +1 -1
- package/dist/vendors/mouser/client.js +4 -12
- package/dist/vendors/mouser/client.js.map +1 -1
- package/easyeda-bridge-extension.eext +0 -0
- package/package.json +11 -10
- package/dist/tools/L0_diagnostics.js.map +0 -1
- package/dist/tools/L1_bom.js.map +0 -1
- package/dist/tools/L1_schematic.js.map +0 -1
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BOM quality — report generation.
|
|
3
|
+
*
|
|
4
|
+
* Analyses BOM entries against supplier data to surface issues:
|
|
5
|
+
* 1. **Unavailable** — part not found or discontinued at any supplier.
|
|
6
|
+
* 2. **Single-source** — part found at exactly one supplier.
|
|
7
|
+
* 3. **Missing MPN** — no manufacturer part number.
|
|
8
|
+
* 4. **Missing footprint** — no package / footprint.
|
|
9
|
+
* 5. **Low stock** — stock below threshold at every supplier.
|
|
10
|
+
*
|
|
11
|
+
* @module
|
|
12
|
+
*/
|
|
13
|
+
import { DEFAULT_BOM_QUALITY_CONFIG } from './types.js';
|
|
14
|
+
import { availableAdapters } from './adapter.js';
|
|
15
|
+
import { getLogger } from '../utils/logger.js';
|
|
16
|
+
// ── Issue factory ──────────────────────────────────────────────────────────
|
|
17
|
+
function issue(type, severity, reference, message, details) {
|
|
18
|
+
return { type, severity, reference, message, details };
|
|
19
|
+
}
|
|
20
|
+
function unavailableIssue(ref, supplier, reason) {
|
|
21
|
+
return issue('unavailable', 'error', ref, `Part not available at ${supplier}: ${reason}`, {
|
|
22
|
+
supplier,
|
|
23
|
+
reason,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
function singleSourceIssue(ref, suppliers) {
|
|
27
|
+
return issue('single_source', 'warning', ref, `Part is single-sourced (only found at ${suppliers.join(', ')})`, { suppliers });
|
|
28
|
+
}
|
|
29
|
+
function missingMpnIssue(ref) {
|
|
30
|
+
return issue('missing_mpn', 'warning', ref, 'No manufacturer part number (MPN) specified — replaceability is limited');
|
|
31
|
+
}
|
|
32
|
+
function missingFootprintIssue(ref) {
|
|
33
|
+
return issue('missing_footprint', 'warning', ref, 'No footprint / package specified — PCB layout verification is not possible');
|
|
34
|
+
}
|
|
35
|
+
function lowStockIssue(ref, supplier, stock) {
|
|
36
|
+
return issue('low_stock', 'warning', ref, `Low stock at ${supplier}: ${stock} units`, {
|
|
37
|
+
supplier,
|
|
38
|
+
stock,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
// ── Supplier query scope ───────────────────────────────────────────────────
|
|
42
|
+
/**
|
|
43
|
+
* Determine which supplier identifiers to query based on what the entry has.
|
|
44
|
+
* - If an LCSC code is present, query LCSC.
|
|
45
|
+
* - If an MPN is present, query Mouser and DigiKey.
|
|
46
|
+
*/
|
|
47
|
+
function queryTargets(entry) {
|
|
48
|
+
const targets = [];
|
|
49
|
+
if (entry.lcsc) {
|
|
50
|
+
targets.push({ supplier: 'lcsc', identifier: { lcsc: entry.lcsc } });
|
|
51
|
+
}
|
|
52
|
+
if (entry.mpn) {
|
|
53
|
+
targets.push({ supplier: 'mouser', identifier: { mpn: entry.mpn } });
|
|
54
|
+
targets.push({ supplier: 'digikey', identifier: { mpn: entry.mpn } });
|
|
55
|
+
}
|
|
56
|
+
return targets;
|
|
57
|
+
}
|
|
58
|
+
// ── Supplier query helper ────────────────────────────────────────────────
|
|
59
|
+
async function querySuppliersForEntry(entry, adapterByKind, _logger) {
|
|
60
|
+
const targets = queryTargets(entry);
|
|
61
|
+
const supplierData = [];
|
|
62
|
+
let hasErrors = false;
|
|
63
|
+
for (const target of targets) {
|
|
64
|
+
const adapter = adapterByKind.get(target.supplier);
|
|
65
|
+
if (!adapter)
|
|
66
|
+
continue;
|
|
67
|
+
try {
|
|
68
|
+
const result = await adapter.queryPart(target.identifier);
|
|
69
|
+
if (result) {
|
|
70
|
+
supplierData.push(result);
|
|
71
|
+
if (result.confidence === 'low')
|
|
72
|
+
hasErrors = true;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
// Should not happen (adapters catch internally), but safeguard
|
|
77
|
+
hasErrors = true;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return { supplierData, hasErrors, queriedCount: targets.length };
|
|
81
|
+
}
|
|
82
|
+
// ── Main entry point ───────────────────────────────────────────────────────
|
|
83
|
+
/**
|
|
84
|
+
* Generate a BOM quality report for the given entries.
|
|
85
|
+
*
|
|
86
|
+
* For each entry the function:
|
|
87
|
+
* 1. Queries every available supplier that can handle the entry.
|
|
88
|
+
* 2. Collects supplier results (with error resilience).
|
|
89
|
+
* 3. Runs the five quality checks.
|
|
90
|
+
* 4. Returns a structured report with a summary.
|
|
91
|
+
*
|
|
92
|
+
* Supplier failures are caught gracefully — the report always succeeds
|
|
93
|
+
* (non-null), with `hasSupplierErrors` set to `true` and any affected
|
|
94
|
+
* entries marked via their issues.
|
|
95
|
+
*/
|
|
96
|
+
export async function generateBomQualityReport(bomId, entries, adapters, config = DEFAULT_BOM_QUALITY_CONFIG) {
|
|
97
|
+
const now = new Date().toISOString();
|
|
98
|
+
let hasSupplierErrors = false;
|
|
99
|
+
// Resolve available adapters once
|
|
100
|
+
const adapterList = availableAdapters(adapters);
|
|
101
|
+
const adapterByKind = new Map(adapterList.map((a) => [a.kind, a]));
|
|
102
|
+
const logger = getLogger();
|
|
103
|
+
const reportEntries = await Promise.all(entries.map(async (entry) => {
|
|
104
|
+
// ── 1. Query applicable suppliers ──────────────────────────────────
|
|
105
|
+
const { supplierData, hasErrors, queriedCount } = await querySuppliersForEntry(entry, adapterByKind, logger);
|
|
106
|
+
if (hasErrors)
|
|
107
|
+
hasSupplierErrors = true;
|
|
108
|
+
// ── 2. Run quality checks ──────────────────────────────────────────
|
|
109
|
+
const issues = [];
|
|
110
|
+
// Check: unavailable (not found or discontinued at any queried supplier)
|
|
111
|
+
const foundSuppliers = supplierData.filter((s) => s.found);
|
|
112
|
+
const discontinuedSuppliers = supplierData.filter((s) => s.found && s.lifecycle === 'discontinued');
|
|
113
|
+
if (supplierData.length > 0 && foundSuppliers.length === 0) {
|
|
114
|
+
// Queried at least one supplier, none had it
|
|
115
|
+
const queried = supplierData.map((s) => s.supplier).join(', ');
|
|
116
|
+
issues.push(unavailableIssue(entry.reference, queried, 'not found at any supplier'));
|
|
117
|
+
}
|
|
118
|
+
for (const ds of discontinuedSuppliers) {
|
|
119
|
+
issues.push(unavailableIssue(entry.reference, ds.supplier, 'discontinued / obsolete'));
|
|
120
|
+
}
|
|
121
|
+
// Check: single-source
|
|
122
|
+
const uniqueFoundSuppliers = [...new Set(foundSuppliers.map((s) => s.supplier))];
|
|
123
|
+
if (uniqueFoundSuppliers.length === 1 && queriedCount > 1) {
|
|
124
|
+
// Only flag single-source when we actually queried more than one supplier
|
|
125
|
+
// (i.e. the entry had identifiers for multiple suppliers)
|
|
126
|
+
issues.push(singleSourceIssue(entry.reference, uniqueFoundSuppliers));
|
|
127
|
+
}
|
|
128
|
+
// Check: missing MPN
|
|
129
|
+
if (config.requireMpn && !entry.mpn && !entry.manufacturer) {
|
|
130
|
+
issues.push(missingMpnIssue(entry.reference));
|
|
131
|
+
}
|
|
132
|
+
// Check: missing footprint
|
|
133
|
+
if (config.requireFootprint && !entry.footprint) {
|
|
134
|
+
issues.push(missingFootprintIssue(entry.reference));
|
|
135
|
+
}
|
|
136
|
+
// Check: low stock (at every found supplier)
|
|
137
|
+
if (foundSuppliers.length > 0) {
|
|
138
|
+
const allLow = foundSuppliers.every((s) => s.stock < config.lowStockThreshold);
|
|
139
|
+
if (allLow) {
|
|
140
|
+
for (const fs of foundSuppliers) {
|
|
141
|
+
issues.push(lowStockIssue(entry.reference, fs.supplier, fs.stock));
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return {
|
|
146
|
+
reference: entry.reference,
|
|
147
|
+
description: entry.value ?? '',
|
|
148
|
+
footprint: entry.footprint ?? '',
|
|
149
|
+
quantity: entry.quantity,
|
|
150
|
+
lcsc: entry.lcsc,
|
|
151
|
+
mpn: entry.mpn,
|
|
152
|
+
manufacturer: entry.manufacturer,
|
|
153
|
+
supplierData,
|
|
154
|
+
issues,
|
|
155
|
+
};
|
|
156
|
+
}));
|
|
157
|
+
// ── 3. Aggregate summary ────────────────────────────────────────────────
|
|
158
|
+
const allIssues = reportEntries.flatMap((e) => e.issues);
|
|
159
|
+
const summary = {
|
|
160
|
+
totalIssues: allIssues.length,
|
|
161
|
+
errors: allIssues.filter((i) => i.severity === 'error').length,
|
|
162
|
+
warnings: allIssues.filter((i) => i.severity === 'warning').length,
|
|
163
|
+
info: allIssues.filter((i) => i.severity === 'info').length,
|
|
164
|
+
unavailableCount: allIssues.filter((i) => i.type === 'unavailable').length,
|
|
165
|
+
singleSourceCount: allIssues.filter((i) => i.type === 'single_source').length,
|
|
166
|
+
missingMpnCount: allIssues.filter((i) => i.type === 'missing_mpn').length,
|
|
167
|
+
missingFootprintCount: allIssues.filter((i) => i.type === 'missing_footprint').length,
|
|
168
|
+
lowStockCount: allIssues.filter((i) => i.type === 'low_stock').length,
|
|
169
|
+
};
|
|
170
|
+
return {
|
|
171
|
+
bomId,
|
|
172
|
+
generatedAt: now,
|
|
173
|
+
totalEntries: entries.length,
|
|
174
|
+
entries: reportEntries,
|
|
175
|
+
summary,
|
|
176
|
+
hasSupplierErrors,
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
//# sourceMappingURL=quality.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quality.js","sourceRoot":"","sources":["../../src/bom-quality/quality.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BOM quality — core type definitions.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
/** Supported supplier identifiers. */
|
|
7
|
+
export type SupplierKind = 'lcsc' | 'mouser' | 'digikey' | 'jlcpcb';
|
|
8
|
+
/** Lifecycle / status of a part at a supplier. */
|
|
9
|
+
export type PartLifecycle = 'active' | 'discontinued' | 'unknown';
|
|
10
|
+
/** BOM entry as passed to quality check, extended with metadata. */
|
|
11
|
+
export interface BomEntry {
|
|
12
|
+
reference: string;
|
|
13
|
+
value?: string;
|
|
14
|
+
footprint?: string;
|
|
15
|
+
lcsc?: string;
|
|
16
|
+
mpn?: string;
|
|
17
|
+
manufacturer?: string;
|
|
18
|
+
quantity: number;
|
|
19
|
+
/** Source of this entry (e.g. 'bridge', 'manual'). */
|
|
20
|
+
source: string;
|
|
21
|
+
/** ISO-8601 timestamp when this entry was obtained. */
|
|
22
|
+
fetchedAt: string;
|
|
23
|
+
}
|
|
24
|
+
/** Normalised result from a single supplier query. */
|
|
25
|
+
export interface SupplierQueryResult {
|
|
26
|
+
supplier: SupplierKind;
|
|
27
|
+
found: boolean;
|
|
28
|
+
lcsc?: string;
|
|
29
|
+
mpn?: string;
|
|
30
|
+
manufacturer?: string;
|
|
31
|
+
description?: string;
|
|
32
|
+
lifecycle: PartLifecycle;
|
|
33
|
+
stock: number;
|
|
34
|
+
unitPrice?: number;
|
|
35
|
+
currency?: string;
|
|
36
|
+
leadTimeDays?: number;
|
|
37
|
+
/** ISO-8601 timestamp of this supplier response. */
|
|
38
|
+
queriedAt: string;
|
|
39
|
+
/** Human-readable confidence (e.g. 'high', 'medium', 'low'). */
|
|
40
|
+
confidence: 'high' | 'medium' | 'low';
|
|
41
|
+
}
|
|
42
|
+
/** Issue type identifiers for the BOM quality report. */
|
|
43
|
+
export type BomQualityIssueType = 'unavailable' | 'single_source' | 'missing_mpn' | 'missing_footprint' | 'low_stock';
|
|
44
|
+
/** A single quality issue found for a BOM entry. */
|
|
45
|
+
export interface BomQualityIssue {
|
|
46
|
+
type: BomQualityIssueType;
|
|
47
|
+
severity: 'error' | 'warning' | 'info';
|
|
48
|
+
reference: string;
|
|
49
|
+
message: string;
|
|
50
|
+
details?: Record<string, unknown>;
|
|
51
|
+
}
|
|
52
|
+
/** Complete BOM quality report. */
|
|
53
|
+
export interface BomQualityReport {
|
|
54
|
+
bomId: string;
|
|
55
|
+
generatedAt: string;
|
|
56
|
+
totalEntries: number;
|
|
57
|
+
entries: Array<{
|
|
58
|
+
reference: string;
|
|
59
|
+
description: string;
|
|
60
|
+
footprint: string;
|
|
61
|
+
quantity: number;
|
|
62
|
+
lcsc?: string;
|
|
63
|
+
mpn?: string;
|
|
64
|
+
manufacturer?: string;
|
|
65
|
+
/** Supplier-specific data collected during the check. */
|
|
66
|
+
supplierData: SupplierQueryResult[];
|
|
67
|
+
issues: BomQualityIssue[];
|
|
68
|
+
}>;
|
|
69
|
+
summary: {
|
|
70
|
+
totalIssues: number;
|
|
71
|
+
errors: number;
|
|
72
|
+
warnings: number;
|
|
73
|
+
info: number;
|
|
74
|
+
unavailableCount: number;
|
|
75
|
+
singleSourceCount: number;
|
|
76
|
+
missingMpnCount: number;
|
|
77
|
+
missingFootprintCount: number;
|
|
78
|
+
lowStockCount: number;
|
|
79
|
+
};
|
|
80
|
+
/** Whether any suppliers returned errors during the check. */
|
|
81
|
+
hasSupplierErrors: boolean;
|
|
82
|
+
}
|
|
83
|
+
/** Configuration for BOM quality checking. */
|
|
84
|
+
export interface BomQualityConfig {
|
|
85
|
+
/** Stock threshold below which a part is considered low-stock. */
|
|
86
|
+
lowStockThreshold: number;
|
|
87
|
+
/** Whether to treat a missing LCSC code as an error. */
|
|
88
|
+
requireLcsc: boolean;
|
|
89
|
+
/** Whether to treat a missing MPN as a warning. */
|
|
90
|
+
requireMpn: boolean;
|
|
91
|
+
/** Whether to treat a missing footprint as a warning. */
|
|
92
|
+
requireFootprint: boolean;
|
|
93
|
+
}
|
|
94
|
+
export declare const DEFAULT_BOM_QUALITY_CONFIG: BomQualityConfig;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/bom-quality/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAuGH,MAAM,CAAC,MAAM,0BAA0B,GAAqB;IAC1D,iBAAiB,EAAE,GAAG;IACtB,WAAW,EAAE,KAAK;IAClB,UAAU,EAAE,IAAI;IAChB,gBAAgB,EAAE,IAAI;CACvB,CAAC"}
|
package/dist/bridge/manager.d.ts
CHANGED
|
@@ -9,20 +9,44 @@ export declare class BridgeManager extends EventEmitter {
|
|
|
9
9
|
private ws;
|
|
10
10
|
private heartbeatTimer;
|
|
11
11
|
private reconnectTimer;
|
|
12
|
+
private staleSweepTimer;
|
|
12
13
|
private _activePort;
|
|
13
14
|
private _connectedAtMs;
|
|
14
15
|
private requestMap;
|
|
15
16
|
private requestIdCounter;
|
|
16
17
|
private config;
|
|
17
18
|
private _lastHeartbeatMs;
|
|
19
|
+
private reconnectAttempts;
|
|
20
|
+
private reconnectStartMs;
|
|
21
|
+
private pairingChallenges;
|
|
22
|
+
private _methodRegistryHash;
|
|
18
23
|
constructor(config: EnvConfig);
|
|
19
24
|
get lastHeartbeatMs(): number;
|
|
20
25
|
get activePort(): number;
|
|
21
26
|
get uptimeMs(): number;
|
|
22
27
|
get connected(): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Wait until the bridge is in the 'connected' state.
|
|
30
|
+
* Resolves immediately if already connected. Rejects after timeoutMs.
|
|
31
|
+
*/
|
|
32
|
+
waitForConnection(timeoutMs: number): Promise<void>;
|
|
33
|
+
get methodRegistryHash(): string;
|
|
34
|
+
private isLoopbackHost;
|
|
35
|
+
private computeMethodRegistryHash;
|
|
23
36
|
connect(): Promise<void>;
|
|
24
37
|
private tryListen;
|
|
25
38
|
private handleConnection;
|
|
39
|
+
/**
|
|
40
|
+
* Validate and accept a handshake message. Sets up the bridge session
|
|
41
|
+
* and replies with a hello containing the server's capabilities.
|
|
42
|
+
*/
|
|
43
|
+
private handleHandshake;
|
|
44
|
+
/**
|
|
45
|
+
* Validate and handle an incoming request from the extension.
|
|
46
|
+
* The server does not currently accept arbitrary extension requests,
|
|
47
|
+
* so unknown methods are rejected with a structured error response.
|
|
48
|
+
*/
|
|
49
|
+
private handleIncomingRequest;
|
|
26
50
|
call<TParams, TResult>(method: string, params?: TParams, opts?: {
|
|
27
51
|
timeoutMs?: number;
|
|
28
52
|
traceparent?: string;
|
|
@@ -32,6 +56,23 @@ export declare class BridgeManager extends EventEmitter {
|
|
|
32
56
|
private rejectPending;
|
|
33
57
|
private startHeartbeat;
|
|
34
58
|
private stopHeartbeat;
|
|
59
|
+
/**
|
|
60
|
+
* Schedule a reconnect attempt with tiered backoff. Never stops retrying.
|
|
61
|
+
* Tiers (elapsed since first disconnect):
|
|
62
|
+
* 0–30 s → 1 s interval
|
|
63
|
+
* 30–120 s → 3 s interval
|
|
64
|
+
* >120 s → 10 s interval
|
|
65
|
+
* Each delay has ±10 % jitter.
|
|
66
|
+
*/
|
|
67
|
+
private scheduleReconnect;
|
|
68
|
+
private clearReconnectTimer;
|
|
69
|
+
/**
|
|
70
|
+
* Periodically sweep the pending-request map for entries whose
|
|
71
|
+
* timeout has elapsed but whose `setTimeout` may have been leaked
|
|
72
|
+
* (defence-in-depth). Runs every 30 s while connected.
|
|
73
|
+
*/
|
|
74
|
+
private startStaleSweep;
|
|
75
|
+
private stopStaleSweep;
|
|
35
76
|
}
|
|
36
77
|
/**
|
|
37
78
|
* Parse a port scan specification string into an ordered array of ports.
|