@fragments-sdk/mcp 0.7.1 → 0.8.1
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/dist/bin.js +1 -1
- package/dist/{chunk-HGGAXLRO.js → chunk-6JMX4AMO.js} +397 -13
- package/dist/chunk-6JMX4AMO.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/server.js +1 -1
- package/package.json +5 -5
- package/dist/chunk-HGGAXLRO.js.map +0 -1
package/dist/bin.js
CHANGED
|
@@ -2462,6 +2462,205 @@ var governHandler = async (args, ctx) => {
|
|
|
2462
2462
|
}
|
|
2463
2463
|
};
|
|
2464
2464
|
|
|
2465
|
+
// src/tools/validate-and-fix.ts
|
|
2466
|
+
import {
|
|
2467
|
+
formatVerdict as formatVerdict2,
|
|
2468
|
+
fragments as fragmentsPreset2,
|
|
2469
|
+
handleGovernTool as handleGovernTool2,
|
|
2470
|
+
universal as universal2
|
|
2471
|
+
} from "@fragments-sdk/govern";
|
|
2472
|
+
function classifyComponent(component) {
|
|
2473
|
+
if (component.status === "deprecated") return "discouraged";
|
|
2474
|
+
if (component.isCanonical && component.tier === "core") return "preferred";
|
|
2475
|
+
return "allowed";
|
|
2476
|
+
}
|
|
2477
|
+
function buildEffectiveComponents(ctx) {
|
|
2478
|
+
const selectionByKey = new Map(
|
|
2479
|
+
(ctx.data.validateFixContext?.components ?? []).map((component) => [
|
|
2480
|
+
component.componentKey,
|
|
2481
|
+
component.selection
|
|
2482
|
+
])
|
|
2483
|
+
);
|
|
2484
|
+
return Object.entries(ctx.data.components).map(([componentKey, component]) => ({
|
|
2485
|
+
component,
|
|
2486
|
+
selection: selectionByKey.get(componentKey) ?? classifyComponent(component)
|
|
2487
|
+
}));
|
|
2488
|
+
}
|
|
2489
|
+
function cloneSpec(spec) {
|
|
2490
|
+
return structuredClone(spec);
|
|
2491
|
+
}
|
|
2492
|
+
function getSelectionNames(effectiveComponents, selection) {
|
|
2493
|
+
const selections = Array.isArray(selection) ? selection : [selection];
|
|
2494
|
+
return Array.from(
|
|
2495
|
+
new Set(
|
|
2496
|
+
effectiveComponents.filter((entry) => selections.includes(entry.selection)).map((entry) => entry.component.name)
|
|
2497
|
+
)
|
|
2498
|
+
);
|
|
2499
|
+
}
|
|
2500
|
+
function buildBasePolicy(ctx) {
|
|
2501
|
+
const tokenPrefix = ctx.data.tokens?.prefix;
|
|
2502
|
+
const basePolicy = tokenPrefix === "fui-" ? { rules: fragmentsPreset2().rules } : { rules: universal2().rules };
|
|
2503
|
+
const allowedComponents = buildEffectiveComponents(ctx).filter(({ selection }) => selection === "preferred" || selection === "allowed").map(({ component }) => component.name);
|
|
2504
|
+
basePolicy.rules["components/allow"] = {
|
|
2505
|
+
enabled: true,
|
|
2506
|
+
severity: "serious",
|
|
2507
|
+
options: {
|
|
2508
|
+
components: allowedComponents
|
|
2509
|
+
}
|
|
2510
|
+
};
|
|
2511
|
+
return basePolicy;
|
|
2512
|
+
}
|
|
2513
|
+
async function runGovern(spec, ctx, policyOverrides) {
|
|
2514
|
+
const input = {
|
|
2515
|
+
spec,
|
|
2516
|
+
policy: policyOverrides,
|
|
2517
|
+
format: "json"
|
|
2518
|
+
};
|
|
2519
|
+
const engineOptions = ctx.data.tokens ? { tokenData: ctx.data.tokens } : void 0;
|
|
2520
|
+
return handleGovernTool2(input, buildBasePolicy(ctx), engineOptions);
|
|
2521
|
+
}
|
|
2522
|
+
function applyDeterministicReplacements(spec, ctx) {
|
|
2523
|
+
const effectiveComponents = buildEffectiveComponents(ctx);
|
|
2524
|
+
const byName = /* @__PURE__ */ new Map();
|
|
2525
|
+
const preferredByCategory = /* @__PURE__ */ new Map();
|
|
2526
|
+
for (const entry of effectiveComponents) {
|
|
2527
|
+
const list = byName.get(entry.component.name) ?? [];
|
|
2528
|
+
list.push(entry);
|
|
2529
|
+
byName.set(entry.component.name, list);
|
|
2530
|
+
if (entry.selection !== "preferred") continue;
|
|
2531
|
+
const category = entry.component.category ?? "uncategorized";
|
|
2532
|
+
const names = preferredByCategory.get(category) ?? [];
|
|
2533
|
+
if (!names.includes(entry.component.name)) {
|
|
2534
|
+
names.push(entry.component.name);
|
|
2535
|
+
}
|
|
2536
|
+
preferredByCategory.set(category, names);
|
|
2537
|
+
}
|
|
2538
|
+
const fixedSpec = cloneSpec(spec);
|
|
2539
|
+
const nodes = Array.isArray(fixedSpec.nodes) ? fixedSpec.nodes : [];
|
|
2540
|
+
const replacements = [];
|
|
2541
|
+
for (const node of nodes) {
|
|
2542
|
+
if (!node.type) continue;
|
|
2543
|
+
const componentEntries = byName.get(node.type) ?? [];
|
|
2544
|
+
const component = componentEntries[0];
|
|
2545
|
+
if (!component || component.selection !== "discouraged" && component.selection !== "forbidden") {
|
|
2546
|
+
continue;
|
|
2547
|
+
}
|
|
2548
|
+
const candidates = (preferredByCategory.get(component.component.category ?? "uncategorized") ?? []).filter((candidate) => candidate !== component.component.name);
|
|
2549
|
+
if (candidates.length !== 1) continue;
|
|
2550
|
+
const replacement = candidates[0];
|
|
2551
|
+
replacements.push({
|
|
2552
|
+
nodeId: node.id ?? node.type,
|
|
2553
|
+
from: component.component.name,
|
|
2554
|
+
to: replacement,
|
|
2555
|
+
reason: "deprecated_component"
|
|
2556
|
+
});
|
|
2557
|
+
node.type = replacement;
|
|
2558
|
+
}
|
|
2559
|
+
return {
|
|
2560
|
+
fixedSpec,
|
|
2561
|
+
replacements
|
|
2562
|
+
};
|
|
2563
|
+
}
|
|
2564
|
+
function buildSummary(args) {
|
|
2565
|
+
const lines = [
|
|
2566
|
+
`status: ${args.status}`,
|
|
2567
|
+
`original: ${formatVerdict2(args.originalVerdict, "summary")}`
|
|
2568
|
+
];
|
|
2569
|
+
if (args.replacements.length > 0) {
|
|
2570
|
+
lines.push(
|
|
2571
|
+
`replacements: ${args.replacements.map((item) => `${item.from} -> ${item.to}`).join(", ")}`
|
|
2572
|
+
);
|
|
2573
|
+
lines.push(`final: ${formatVerdict2(args.finalVerdict, "summary")}`);
|
|
2574
|
+
}
|
|
2575
|
+
return lines.join("\n");
|
|
2576
|
+
}
|
|
2577
|
+
var validateAndFixHandler = async (args, ctx) => {
|
|
2578
|
+
const spec = args?.spec;
|
|
2579
|
+
if (!spec || typeof spec !== "object") {
|
|
2580
|
+
return {
|
|
2581
|
+
content: [
|
|
2582
|
+
{
|
|
2583
|
+
type: "text",
|
|
2584
|
+
text: JSON.stringify({
|
|
2585
|
+
error: "spec is required and must be an object with { nodes: [{ id, type, props, children }] }"
|
|
2586
|
+
})
|
|
2587
|
+
}
|
|
2588
|
+
],
|
|
2589
|
+
isError: true
|
|
2590
|
+
};
|
|
2591
|
+
}
|
|
2592
|
+
const policyOverrides = args?.policy;
|
|
2593
|
+
const applyFixes = args?.applyFixes !== false;
|
|
2594
|
+
const format = args?.format ?? "json";
|
|
2595
|
+
try {
|
|
2596
|
+
const effectiveComponents = buildEffectiveComponents(ctx);
|
|
2597
|
+
const originalVerdict = await runGovern(spec, ctx, policyOverrides);
|
|
2598
|
+
let finalVerdict = originalVerdict;
|
|
2599
|
+
let fixedSpec;
|
|
2600
|
+
let replacements = [];
|
|
2601
|
+
if (!originalVerdict.passed && applyFixes) {
|
|
2602
|
+
const result = applyDeterministicReplacements(
|
|
2603
|
+
spec,
|
|
2604
|
+
ctx
|
|
2605
|
+
);
|
|
2606
|
+
replacements = result.replacements;
|
|
2607
|
+
fixedSpec = result.fixedSpec;
|
|
2608
|
+
if (replacements.length > 0) {
|
|
2609
|
+
finalVerdict = await runGovern(fixedSpec, ctx, policyOverrides);
|
|
2610
|
+
}
|
|
2611
|
+
}
|
|
2612
|
+
const status = originalVerdict.passed ? "pass" : replacements.length > 0 ? "fixed" : "fail";
|
|
2613
|
+
const payload = {
|
|
2614
|
+
status,
|
|
2615
|
+
applyFixes,
|
|
2616
|
+
replacements,
|
|
2617
|
+
originalVerdict,
|
|
2618
|
+
finalVerdict,
|
|
2619
|
+
...fixedSpec ? { fixedSpec } : {},
|
|
2620
|
+
preferredComponents: getSelectionNames(
|
|
2621
|
+
effectiveComponents,
|
|
2622
|
+
"preferred"
|
|
2623
|
+
),
|
|
2624
|
+
discouragedComponents: getSelectionNames(effectiveComponents, [
|
|
2625
|
+
"discouraged",
|
|
2626
|
+
"forbidden"
|
|
2627
|
+
])
|
|
2628
|
+
};
|
|
2629
|
+
return {
|
|
2630
|
+
content: [
|
|
2631
|
+
{
|
|
2632
|
+
type: "text",
|
|
2633
|
+
text: format === "summary" ? buildSummary({
|
|
2634
|
+
status,
|
|
2635
|
+
originalVerdict,
|
|
2636
|
+
finalVerdict,
|
|
2637
|
+
replacements
|
|
2638
|
+
}) : JSON.stringify(payload)
|
|
2639
|
+
}
|
|
2640
|
+
],
|
|
2641
|
+
_meta: {
|
|
2642
|
+
status,
|
|
2643
|
+
replacementCount: replacements.length,
|
|
2644
|
+
passed: finalVerdict.passed
|
|
2645
|
+
}
|
|
2646
|
+
};
|
|
2647
|
+
} catch (error) {
|
|
2648
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2649
|
+
const isSpecError = message.includes("Expected") || message.includes("Required");
|
|
2650
|
+
return {
|
|
2651
|
+
content: [
|
|
2652
|
+
{
|
|
2653
|
+
type: "text",
|
|
2654
|
+
text: JSON.stringify({
|
|
2655
|
+
error: isSpecError ? `Invalid spec format: ${message}. Expected: { nodes: [{ id: string, type: string, props: object, children?: string[] }] }` : message
|
|
2656
|
+
})
|
|
2657
|
+
}
|
|
2658
|
+
],
|
|
2659
|
+
isError: true
|
|
2660
|
+
};
|
|
2661
|
+
}
|
|
2662
|
+
};
|
|
2663
|
+
|
|
2465
2664
|
// src/tools/generate-ui.ts
|
|
2466
2665
|
var generateUiHandler = async (args, ctx) => {
|
|
2467
2666
|
const prompt = args?.prompt;
|
|
@@ -2491,6 +2690,142 @@ var generateUiHandler = async (args, ctx) => {
|
|
|
2491
2690
|
};
|
|
2492
2691
|
};
|
|
2493
2692
|
|
|
2693
|
+
// src/findings-service.ts
|
|
2694
|
+
var DEFAULT_CLOUD_URL = "https://app.usefragments.com";
|
|
2695
|
+
function normalizeCloudUrl(url) {
|
|
2696
|
+
if (!url) return DEFAULT_CLOUD_URL;
|
|
2697
|
+
return url.replace(/\/+$/, "");
|
|
2698
|
+
}
|
|
2699
|
+
async function fetchFindings(apiKey, params, cloudUrl) {
|
|
2700
|
+
const base = normalizeCloudUrl(cloudUrl);
|
|
2701
|
+
const url = new URL(`${base}/api/findings`);
|
|
2702
|
+
if (params.status) url.searchParams.set("status", params.status);
|
|
2703
|
+
if (params.severity) url.searchParams.set("severity", params.severity);
|
|
2704
|
+
if (params.category) url.searchParams.set("category", params.category);
|
|
2705
|
+
if (params.ruleId) url.searchParams.set("ruleId", params.ruleId);
|
|
2706
|
+
if (params.filePath) url.searchParams.set("filePath", params.filePath);
|
|
2707
|
+
if (params.limit != null) url.searchParams.set("limit", String(params.limit));
|
|
2708
|
+
const response = await fetch(url.toString(), {
|
|
2709
|
+
headers: { "X-API-Key": apiKey }
|
|
2710
|
+
});
|
|
2711
|
+
if (!response.ok) {
|
|
2712
|
+
const body = await response.text();
|
|
2713
|
+
let message;
|
|
2714
|
+
try {
|
|
2715
|
+
const parsed = JSON.parse(body);
|
|
2716
|
+
message = parsed.error ?? body;
|
|
2717
|
+
} catch {
|
|
2718
|
+
message = body;
|
|
2719
|
+
}
|
|
2720
|
+
throw new Error(
|
|
2721
|
+
`Cloud findings API error (${response.status}): ${message}`
|
|
2722
|
+
);
|
|
2723
|
+
}
|
|
2724
|
+
return await response.json();
|
|
2725
|
+
}
|
|
2726
|
+
async function fetchFindingsForFile(apiKey, filePath, cloudUrl) {
|
|
2727
|
+
return fetchFindings(
|
|
2728
|
+
apiKey,
|
|
2729
|
+
{ status: "open", filePath, limit: 200 },
|
|
2730
|
+
cloudUrl
|
|
2731
|
+
);
|
|
2732
|
+
}
|
|
2733
|
+
|
|
2734
|
+
// src/tools/findings.ts
|
|
2735
|
+
function resolveCloudApiKey(ctx) {
|
|
2736
|
+
return ctx.config.cloudApiKey ?? ctx.config.fileConfig?.cloud?.apiKey ?? process.env.FRAGMENTS_API_KEY;
|
|
2737
|
+
}
|
|
2738
|
+
function resolveCloudUrl(ctx) {
|
|
2739
|
+
return ctx.config.fileConfig?.cloud?.url ?? process.env.FRAGMENTS_CLOUD_URL;
|
|
2740
|
+
}
|
|
2741
|
+
function missingKeyError() {
|
|
2742
|
+
return {
|
|
2743
|
+
content: [
|
|
2744
|
+
{
|
|
2745
|
+
type: "text",
|
|
2746
|
+
text: JSON.stringify({
|
|
2747
|
+
error: "Cloud API key required. Set FRAGMENTS_API_KEY env var, pass --cloud-api-key, or configure cloud.apiKey in ds-mcp.config.json."
|
|
2748
|
+
})
|
|
2749
|
+
}
|
|
2750
|
+
],
|
|
2751
|
+
isError: true
|
|
2752
|
+
};
|
|
2753
|
+
}
|
|
2754
|
+
var findingsListHandler = async (args, ctx) => {
|
|
2755
|
+
const apiKey = resolveCloudApiKey(ctx);
|
|
2756
|
+
if (!apiKey) return missingKeyError();
|
|
2757
|
+
const cloudUrl = resolveCloudUrl(ctx);
|
|
2758
|
+
const params = {};
|
|
2759
|
+
if (args.status) params.status = args.status;
|
|
2760
|
+
if (args.severity)
|
|
2761
|
+
params.severity = args.severity;
|
|
2762
|
+
if (args.category) params.category = String(args.category);
|
|
2763
|
+
if (args.ruleId) params.ruleId = String(args.ruleId);
|
|
2764
|
+
if (args.filePath) params.filePath = String(args.filePath);
|
|
2765
|
+
if (args.limit != null) params.limit = Number(args.limit);
|
|
2766
|
+
try {
|
|
2767
|
+
const result = await fetchFindings(apiKey, params, cloudUrl);
|
|
2768
|
+
return {
|
|
2769
|
+
content: [{ type: "text", text: JSON.stringify(result) }],
|
|
2770
|
+
_meta: { count: result.findings.length }
|
|
2771
|
+
};
|
|
2772
|
+
} catch (error) {
|
|
2773
|
+
return {
|
|
2774
|
+
content: [
|
|
2775
|
+
{
|
|
2776
|
+
type: "text",
|
|
2777
|
+
text: JSON.stringify({
|
|
2778
|
+
error: error instanceof Error ? error.message : String(error)
|
|
2779
|
+
})
|
|
2780
|
+
}
|
|
2781
|
+
],
|
|
2782
|
+
isError: true
|
|
2783
|
+
};
|
|
2784
|
+
}
|
|
2785
|
+
};
|
|
2786
|
+
var findingsForFileHandler = async (args, ctx) => {
|
|
2787
|
+
const apiKey = resolveCloudApiKey(ctx);
|
|
2788
|
+
if (!apiKey) return missingKeyError();
|
|
2789
|
+
const filePath = args.filePath;
|
|
2790
|
+
if (!filePath || typeof filePath !== "string") {
|
|
2791
|
+
return {
|
|
2792
|
+
content: [
|
|
2793
|
+
{
|
|
2794
|
+
type: "text",
|
|
2795
|
+
text: JSON.stringify({ error: "filePath is required." })
|
|
2796
|
+
}
|
|
2797
|
+
],
|
|
2798
|
+
isError: true
|
|
2799
|
+
};
|
|
2800
|
+
}
|
|
2801
|
+
const cloudUrl = resolveCloudUrl(ctx);
|
|
2802
|
+
try {
|
|
2803
|
+
const result = await fetchFindingsForFile(apiKey, filePath, cloudUrl);
|
|
2804
|
+
const findings = result.findings.filter((f) => f.filePath === filePath);
|
|
2805
|
+
return {
|
|
2806
|
+
content: [
|
|
2807
|
+
{
|
|
2808
|
+
type: "text",
|
|
2809
|
+
text: JSON.stringify({ findings, filePath })
|
|
2810
|
+
}
|
|
2811
|
+
],
|
|
2812
|
+
_meta: { count: findings.length, filePath }
|
|
2813
|
+
};
|
|
2814
|
+
} catch (error) {
|
|
2815
|
+
return {
|
|
2816
|
+
content: [
|
|
2817
|
+
{
|
|
2818
|
+
type: "text",
|
|
2819
|
+
text: JSON.stringify({
|
|
2820
|
+
error: error instanceof Error ? error.message : String(error)
|
|
2821
|
+
})
|
|
2822
|
+
}
|
|
2823
|
+
],
|
|
2824
|
+
isError: true
|
|
2825
|
+
};
|
|
2826
|
+
}
|
|
2827
|
+
};
|
|
2828
|
+
|
|
2494
2829
|
// src/tools/index.ts
|
|
2495
2830
|
var CORE_TOOLS = {
|
|
2496
2831
|
discover: discoverHandler,
|
|
@@ -2499,7 +2834,10 @@ var CORE_TOOLS = {
|
|
|
2499
2834
|
tokens: tokensHandler,
|
|
2500
2835
|
graph: graphHandler,
|
|
2501
2836
|
perf: perfHandler,
|
|
2502
|
-
govern: governHandler
|
|
2837
|
+
govern: governHandler,
|
|
2838
|
+
validate_and_fix: validateAndFixHandler,
|
|
2839
|
+
findings_list: findingsListHandler,
|
|
2840
|
+
findings_for_file: findingsForFileHandler
|
|
2503
2841
|
};
|
|
2504
2842
|
var VIEWER_TOOLS = {
|
|
2505
2843
|
render: renderHandler,
|
|
@@ -2521,6 +2859,7 @@ var TOOL_CAPABILITIES = {
|
|
|
2521
2859
|
tokens: ["tokens"],
|
|
2522
2860
|
graph: ["graph"],
|
|
2523
2861
|
perf: ["performance"],
|
|
2862
|
+
validate_and_fix: ["components"],
|
|
2524
2863
|
render: ["components"],
|
|
2525
2864
|
fix: ["components"],
|
|
2526
2865
|
a11y: ["components"]
|
|
@@ -3782,7 +4121,7 @@ function readPackageName(projectRoot) {
|
|
|
3782
4121
|
}
|
|
3783
4122
|
|
|
3784
4123
|
// src/adapters/cloud-catalog.ts
|
|
3785
|
-
var
|
|
4124
|
+
var DEFAULT_CLOUD_URL2 = "https://app.usefragments.com/api/catalog";
|
|
3786
4125
|
var TOKEN_CATEGORY_ALIASES2 = {
|
|
3787
4126
|
color: ["color", "colors", "accent", "background", "foreground", "danger", "brand"],
|
|
3788
4127
|
spacing: ["spacing", "space", "padding", "margin", "gap", "inset"],
|
|
@@ -3795,10 +4134,14 @@ var TOKEN_CATEGORY_ALIASES2 = {
|
|
|
3795
4134
|
surface: ["surface", "surfaces", "canvas", "card", "background"]
|
|
3796
4135
|
};
|
|
3797
4136
|
function normalizeCatalogUrl(url) {
|
|
3798
|
-
if (!url) return
|
|
4137
|
+
if (!url) return DEFAULT_CLOUD_URL2;
|
|
3799
4138
|
if (url.endsWith("/api/catalog")) return url;
|
|
3800
4139
|
return `${url.replace(/\/+$/, "")}/api/catalog`;
|
|
3801
4140
|
}
|
|
4141
|
+
function normalizeValidateFixUrl(url) {
|
|
4142
|
+
const base = normalizeCatalogUrl(url).replace(/\/api\/catalog$/, "");
|
|
4143
|
+
return `${base}/api/context?target=validate-fix`;
|
|
4144
|
+
}
|
|
3802
4145
|
function normalizeValue(value) {
|
|
3803
4146
|
return value?.toLowerCase().replace(/[^a-z0-9]+/g, " ").trim() ?? "";
|
|
3804
4147
|
}
|
|
@@ -3917,17 +4260,54 @@ function mapComponent(component, designSystem) {
|
|
|
3917
4260
|
}
|
|
3918
4261
|
};
|
|
3919
4262
|
}
|
|
4263
|
+
function normalizeValidateFixContext(raw) {
|
|
4264
|
+
const content = raw.content;
|
|
4265
|
+
if (!content || !Array.isArray(content.components)) {
|
|
4266
|
+
return void 0;
|
|
4267
|
+
}
|
|
4268
|
+
const components = content.components.filter(
|
|
4269
|
+
(component) => Boolean(component?.componentKey) && Boolean(component?.publicRef) && Boolean(component?.name) && Boolean(component?.selection)
|
|
4270
|
+
).map((component) => ({
|
|
4271
|
+
componentKey: component.componentKey,
|
|
4272
|
+
publicRef: component.publicRef,
|
|
4273
|
+
name: component.name,
|
|
4274
|
+
category: component.category ?? "uncategorized",
|
|
4275
|
+
status: component.status ?? "stable",
|
|
4276
|
+
tier: component.tier ?? "composition",
|
|
4277
|
+
isCanonical: component.isCanonical ?? false,
|
|
4278
|
+
isActive: component.isActive ?? true,
|
|
4279
|
+
selection: component.selection ?? "allowed",
|
|
4280
|
+
reasons: component.reasons ?? [],
|
|
4281
|
+
usageGuidance: component.usageGuidance,
|
|
4282
|
+
dos: component.dos ?? [],
|
|
4283
|
+
donts: component.donts ?? []
|
|
4284
|
+
}));
|
|
4285
|
+
return {
|
|
4286
|
+
version: 1,
|
|
4287
|
+
catalogRevision: content.catalogRevision,
|
|
4288
|
+
updatedAt: content.updatedAt,
|
|
4289
|
+
policy: {
|
|
4290
|
+
mode: "cloud",
|
|
4291
|
+
endpoint: content.policy?.endpoint ?? "/api/govern/policy"
|
|
4292
|
+
},
|
|
4293
|
+
components
|
|
4294
|
+
};
|
|
4295
|
+
}
|
|
3920
4296
|
var CloudCatalogAdapter = class {
|
|
3921
4297
|
constructor(options) {
|
|
3922
4298
|
this.options = options;
|
|
3923
4299
|
}
|
|
3924
4300
|
name = "cloud";
|
|
3925
4301
|
async load(_projectRoot) {
|
|
3926
|
-
const
|
|
3927
|
-
|
|
3928
|
-
|
|
3929
|
-
|
|
3930
|
-
|
|
4302
|
+
const headers = {
|
|
4303
|
+
"X-API-Key": this.options.apiKey
|
|
4304
|
+
};
|
|
4305
|
+
const [response, validateFixResponse] = await Promise.all([
|
|
4306
|
+
fetch(normalizeCatalogUrl(this.options.url), { headers }),
|
|
4307
|
+
fetch(normalizeValidateFixUrl(this.options.url), { headers }).catch(
|
|
4308
|
+
() => null
|
|
4309
|
+
)
|
|
4310
|
+
]);
|
|
3931
4311
|
if (!response.ok) {
|
|
3932
4312
|
throw new Error(
|
|
3933
4313
|
`Failed to load Cloud catalog (${response.status} ${response.statusText}).`
|
|
@@ -3969,6 +4349,9 @@ var CloudCatalogAdapter = class {
|
|
|
3969
4349
|
packageMap,
|
|
3970
4350
|
defaultPackageName: packageName
|
|
3971
4351
|
});
|
|
4352
|
+
const validateFixContext = validateFixResponse && validateFixResponse.ok ? normalizeValidateFixContext(
|
|
4353
|
+
await validateFixResponse.json()
|
|
4354
|
+
) : void 0;
|
|
3972
4355
|
const hydratedComponents = Object.fromEntries(
|
|
3973
4356
|
Object.entries(snapshot.components).map(([componentId, component]) => [
|
|
3974
4357
|
componentId,
|
|
@@ -3990,6 +4373,7 @@ var CloudCatalogAdapter = class {
|
|
|
3990
4373
|
performanceSummary: void 0,
|
|
3991
4374
|
packageMap: snapshot.packageMap,
|
|
3992
4375
|
defaultPackageName: snapshot.defaultPackageName,
|
|
4376
|
+
validateFixContext,
|
|
3993
4377
|
capabilities: new Set(snapshot.capabilities)
|
|
3994
4378
|
};
|
|
3995
4379
|
}
|
|
@@ -4224,10 +4608,10 @@ var BundleAdapter = class {
|
|
|
4224
4608
|
};
|
|
4225
4609
|
|
|
4226
4610
|
// src/source-selection.ts
|
|
4227
|
-
function
|
|
4611
|
+
function resolveCloudApiKey2(config, fileConfig) {
|
|
4228
4612
|
return config.cloudApiKey ?? fileConfig?.cloud?.apiKey ?? process.env.FRAGMENTS_API_KEY;
|
|
4229
4613
|
}
|
|
4230
|
-
function
|
|
4614
|
+
function resolveCloudUrl2(fileConfig) {
|
|
4231
4615
|
return fileConfig?.cloud?.url ?? process.env.FRAGMENTS_CLOUD_URL;
|
|
4232
4616
|
}
|
|
4233
4617
|
function hasTsProject(projectRoot) {
|
|
@@ -4237,8 +4621,8 @@ function resolveDataAdapter(config, fileConfig) {
|
|
|
4237
4621
|
const source = config.source ?? fileConfig?.source ?? "auto";
|
|
4238
4622
|
const fragmentsJsonPaths = findFragmentsJson(config.projectRoot);
|
|
4239
4623
|
const bundleManifestPaths = findBundleManifest(config.projectRoot);
|
|
4240
|
-
const cloudApiKey =
|
|
4241
|
-
const cloudUrl =
|
|
4624
|
+
const cloudApiKey = resolveCloudApiKey2(config, fileConfig);
|
|
4625
|
+
const cloudUrl = resolveCloudUrl2(fileConfig);
|
|
4242
4626
|
switch (source) {
|
|
4243
4627
|
case "fragments-json":
|
|
4244
4628
|
return { adapter: new FragmentsJsonAdapter(), mode: "fragments-json" };
|
|
@@ -4498,4 +4882,4 @@ export {
|
|
|
4498
4882
|
startMcpServer,
|
|
4499
4883
|
createSandboxServer
|
|
4500
4884
|
};
|
|
4501
|
-
//# sourceMappingURL=chunk-
|
|
4885
|
+
//# sourceMappingURL=chunk-6JMX4AMO.js.map
|