@shwfed/config 2.3.12 → 2.3.13
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/mcp.mjs +493 -208
- package/dist/module.json +1 -1
- package/dist/preview/assets/{config-QUQ71Eo6.js → config-0UIjgMSM.js} +1 -1
- package/dist/preview/assets/{config-zCMkbPQt.js → config-9eu0BvKT.js} +1 -1
- package/dist/preview/assets/{config-oO93sSer.js → config-B1jKkIYg.js} +1 -1
- package/dist/preview/assets/{config-B-1L3Ra-.js → config-BpTg08Vv.js} +1 -1
- package/dist/preview/assets/{config-Cf5kO84H.js → config-CDjs2Ohl.js} +1 -1
- package/dist/preview/assets/{config-DqxN0Byp.js → config-CVS1PW6h.js} +1 -1
- package/dist/preview/assets/{config-sJ5XKUJy.js → config-DoQjG5TI.js} +1 -1
- package/dist/preview/assets/{config-DTQkLHVw.js → config-f56G9OU7.js} +1 -1
- package/dist/preview/assets/{definition.vue_vue_type_script_setup_true_lang-D-OVRv68.js → definition.vue_vue_type_script_setup_true_lang-DbnaeqGK.js} +1 -1
- package/dist/preview/assets/{index-D8QyOVfp.js → index-DDthcoXk.js} +5 -5
- package/dist/preview/assets/index-DhkKZ2ii.js +1 -0
- package/dist/preview/assets/{runtime-Cv2doZNu.js → runtime-BICQC6bF.js} +1 -1
- package/dist/preview/assets/{runtime-DcYhXvSk.js → runtime-BkZp9k_z.js} +1 -1
- package/dist/preview/assets/{runtime-CzDUrqSa.js → runtime-BqFFtMNw.js} +1 -1
- package/dist/preview/assets/{runtime-10_7L7Gz.js → runtime-COMOofol.js} +1 -1
- package/dist/preview/assets/{runtime-cmkN6aik.js → runtime-CPPOlC0F.js} +1 -1
- package/dist/preview/assets/{runtime-B2EP6060.js → runtime-DejxoCBP.js} +1 -1
- package/dist/preview/assets/{runtime-DlDhRVII.js → runtime-YYdaCEw3.js} +1 -1
- package/dist/preview/assets/{runtime-BxlgShjU.js → runtime-hKRNY9F6.js} +1 -1
- package/dist/preview/index.html +1 -1
- package/dist/runtime/components/actions/utils/resolve.js +6 -2
- package/dist/runtime/components/config/utils/resolve.js +3 -1
- package/dist/runtime/components/form/utils/resolve.js +3 -1
- package/dist/runtime/components/table/utils/resolve.js +3 -1
- package/package.json +1 -1
- package/dist/preview/assets/index-b_t8yWJJ.js +0 -1
package/dist/mcp.mjs
CHANGED
|
@@ -45510,133 +45510,6 @@ function LocaleMarkdown(options) {
|
|
|
45510
45510
|
)
|
|
45511
45511
|
);
|
|
45512
45512
|
}
|
|
45513
|
-
const TrackCount = Number$.pipe(int(), positive());
|
|
45514
|
-
const GridCoord = Number$.pipe(int(), positive());
|
|
45515
|
-
const Corner = Tuple(GridCoord, GridCoord).annotations({
|
|
45516
|
-
title: "Corner",
|
|
45517
|
-
description: "[x, y] 网格线号(1 基)"
|
|
45518
|
-
});
|
|
45519
|
-
const Area = Tuple(Corner, Corner).pipe(filter((a) => {
|
|
45520
|
-
if (a[1][0] <= a[0][0]) return "右下列线必须大于左上列线";
|
|
45521
|
-
if (a[1][1] <= a[0][1]) return "右下行线必须大于左上行线";
|
|
45522
|
-
return true;
|
|
45523
|
-
})).annotations({
|
|
45524
|
-
title: "Area",
|
|
45525
|
-
description: "矩形区域:`[[x1, y1], [x2, y2]]`,左上 + 右下对角(终止线不含)"
|
|
45526
|
-
});
|
|
45527
|
-
const Align$1 = Literal2("start", "center", "end", "stretch").annotations({
|
|
45528
|
-
title: "Align",
|
|
45529
|
-
description: "网格项在单轴上的对齐方式;缺省等同于 stretch"
|
|
45530
|
-
});
|
|
45531
|
-
const Placement = Struct({
|
|
45532
|
-
area: Area,
|
|
45533
|
-
h: optional(Align$1.annotations({ title: "水平对齐", description: "水平轴对齐(justify-self)" })),
|
|
45534
|
-
v: optional(Align$1.annotations({ title: "垂直对齐", description: "垂直轴对齐(align-self)" }))
|
|
45535
|
-
}).annotations({
|
|
45536
|
-
title: "Placement",
|
|
45537
|
-
description: "块在某一布局中的位置与对齐"
|
|
45538
|
-
});
|
|
45539
|
-
const Layout = Struct({
|
|
45540
|
-
columns: TrackCount.annotations({
|
|
45541
|
-
title: "列数",
|
|
45542
|
-
description: "总列数。每列等宽,渲染时展开为 `repeat(N, minmax(0, 1fr))` — 列会收缩以适配容器宽度"
|
|
45543
|
-
}),
|
|
45544
|
-
rows: optional(TrackCount.annotations({
|
|
45545
|
-
title: "行数",
|
|
45546
|
-
description: "总行数。每行等权,渲染时展开为 `repeat(N, minmax(0, 1fr))` — 在自然高度容器内等同于 `auto`"
|
|
45547
|
-
})),
|
|
45548
|
-
gap: optional(Number$.pipe(int(), nonNegative()).annotations({
|
|
45549
|
-
title: "网格间距",
|
|
45550
|
-
description: "非负整数;实际 CSS gap 为 `calc(n * 0.25rem)`。显式 `0` 表示无间距,未设置则取默认间距 4(即 `1rem`)"
|
|
45551
|
-
})),
|
|
45552
|
-
style: optional(String$.annotations({
|
|
45553
|
-
title: "容器样式",
|
|
45554
|
-
description: "容器的内联样式字符串"
|
|
45555
|
-
})),
|
|
45556
|
-
placements: Record({
|
|
45557
|
-
key: String$,
|
|
45558
|
-
value: Placement
|
|
45559
|
-
}).annotations({
|
|
45560
|
-
title: "位置",
|
|
45561
|
-
description: "以块 `id` 为键的位置映射;未映射的块在该布局中不渲染"
|
|
45562
|
-
})
|
|
45563
|
-
}).annotations({
|
|
45564
|
-
title: "Layout",
|
|
45565
|
-
description: "一套完整的网格布局"
|
|
45566
|
-
});
|
|
45567
|
-
function configureMedia(configure) {
|
|
45568
|
-
return (env) => {
|
|
45569
|
-
env.registerFunction(
|
|
45570
|
-
"media(string): bool",
|
|
45571
|
-
(_self, q) => typeof window !== "undefined" && window.matchMedia(q).matches,
|
|
45572
|
-
{ description: "匹配 CSS 媒体查询,等价于 `window.matchMedia(q).matches`;SSR 上下文返回 `false`" }
|
|
45573
|
-
);
|
|
45574
|
-
configure(env);
|
|
45575
|
-
};
|
|
45576
|
-
}
|
|
45577
|
-
function LayoutSet(configure) {
|
|
45578
|
-
return Struct({
|
|
45579
|
-
name: String$.annotations({
|
|
45580
|
-
title: "名称",
|
|
45581
|
-
description: "编辑器中区分不同布局的内部名称"
|
|
45582
|
-
}),
|
|
45583
|
-
media: optional(Expression({
|
|
45584
|
-
configure: configureMedia(configure),
|
|
45585
|
-
resultType: "bool"
|
|
45586
|
-
}).annotations({
|
|
45587
|
-
title: "匹配条件",
|
|
45588
|
-
description: "返回 `bool` 的 CEL 表达式,挂载时一次性求值;空表示无条件匹配。可用 `media('(min-width: 1024px)')` 包装 CSS 媒体查询。"
|
|
45589
|
-
})),
|
|
45590
|
-
layout: Layout
|
|
45591
|
-
}).annotations({
|
|
45592
|
-
title: "LayoutSet",
|
|
45593
|
-
description: "带匹配条件的布局集合项"
|
|
45594
|
-
});
|
|
45595
|
-
}
|
|
45596
|
-
function validatePlacements(items2, layouts, label) {
|
|
45597
|
-
const ids2 = new Set(items2.map((it) => it.id));
|
|
45598
|
-
for (const [i, set3] of layouts.entries()) {
|
|
45599
|
-
const nCols = set3.layout.columns;
|
|
45600
|
-
const nRows = set3.layout.rows;
|
|
45601
|
-
for (const [id2, placement] of Object.entries(set3.layout.placements)) {
|
|
45602
|
-
if (!ids2.has(id2)) {
|
|
45603
|
-
return `布局 #${i} (${set3.name}) 引用了不存在的${label} id: ${id2}`;
|
|
45604
|
-
}
|
|
45605
|
-
const [, [x2, y2]] = placement.area;
|
|
45606
|
-
if (x2 > nCols + 1) {
|
|
45607
|
-
return `布局 #${i} (${set3.name}) ${label} ${id2} 的列区域超出列定义(共 ${nCols} 列)`;
|
|
45608
|
-
}
|
|
45609
|
-
if (nRows !== void 0 && y2 > nRows + 1) {
|
|
45610
|
-
return `布局 #${i} (${set3.name}) ${label} ${id2} 的行区域超出行定义(共 ${nRows} 行)`;
|
|
45611
|
-
}
|
|
45612
|
-
}
|
|
45613
|
-
}
|
|
45614
|
-
return true;
|
|
45615
|
-
}
|
|
45616
|
-
function Slot(BlockSchemaUnion, configure) {
|
|
45617
|
-
return Struct({
|
|
45618
|
-
blocks: Array$(BlockSchemaUnion).annotations({
|
|
45619
|
-
title: "块",
|
|
45620
|
-
description: "块列表;未绑定到任何布局的块不会被渲染"
|
|
45621
|
-
}),
|
|
45622
|
-
layouts: Array$(LayoutSet(configure)).pipe(minItems(1)).annotations({
|
|
45623
|
-
title: "布局",
|
|
45624
|
-
description: "按顺序排列的布局集合;挂载时按序求值各项 `media` CEL 表达式,使用第一个为 `true` 的布局(全部不匹配时回退到最后一项)"
|
|
45625
|
-
})
|
|
45626
|
-
}).pipe(filter((slot) => {
|
|
45627
|
-
const items2 = slot.blocks.map((b) => ({ id: b.id }));
|
|
45628
|
-
return validatePlacements(items2, slot.layouts, "块");
|
|
45629
|
-
})).annotations({
|
|
45630
|
-
title: "Slot",
|
|
45631
|
-
description: "块与布局的组合:定义一组块以及它们在不同布局下的位置"
|
|
45632
|
-
});
|
|
45633
|
-
}
|
|
45634
|
-
function defaultSlot() {
|
|
45635
|
-
return {
|
|
45636
|
-
blocks: [],
|
|
45637
|
-
layouts: [{ name: "默认", layout: { columns: 1, placements: {} } }]
|
|
45638
|
-
};
|
|
45639
|
-
}
|
|
45640
45513
|
var vue = { exports: {} };
|
|
45641
45514
|
var vue_cjs_prod = {};
|
|
45642
45515
|
var compilerDom_cjs_prod = {};
|
|
@@ -57245,12 +57118,12 @@ function requireLib() {
|
|
|
57245
57118
|
}
|
|
57246
57119
|
}
|
|
57247
57120
|
finishPlaceholder(node, expectedNode) {
|
|
57248
|
-
let
|
|
57249
|
-
if (!
|
|
57250
|
-
|
|
57121
|
+
let placeholder2 = node;
|
|
57122
|
+
if (!placeholder2.expectedNode || !placeholder2.type) {
|
|
57123
|
+
placeholder2 = this.finishNode(placeholder2, "Placeholder");
|
|
57251
57124
|
}
|
|
57252
|
-
|
|
57253
|
-
return
|
|
57125
|
+
placeholder2.expectedNode = expectedNode;
|
|
57126
|
+
return placeholder2;
|
|
57254
57127
|
}
|
|
57255
57128
|
getTokenFromCode(code3) {
|
|
57256
57129
|
if (code3 === 37 && this.input.charCodeAt(this.state.pos + 1) === 37) {
|
|
@@ -57338,13 +57211,13 @@ function requireLib() {
|
|
|
57338
57211
|
const type2 = isStatement ? "ClassDeclaration" : "ClassExpression";
|
|
57339
57212
|
this.next();
|
|
57340
57213
|
const oldStrict = this.state.strict;
|
|
57341
|
-
const
|
|
57342
|
-
if (
|
|
57214
|
+
const placeholder2 = this.parsePlaceholder("Identifier");
|
|
57215
|
+
if (placeholder2) {
|
|
57343
57216
|
if (this.match(81) || this.match(133) || this.match(5)) {
|
|
57344
|
-
node.id =
|
|
57217
|
+
node.id = placeholder2;
|
|
57345
57218
|
} else if (optionalId || !isStatement) {
|
|
57346
57219
|
node.id = null;
|
|
57347
|
-
node.body = this.finishPlaceholder(
|
|
57220
|
+
node.body = this.finishPlaceholder(placeholder2, "ClassBody");
|
|
57348
57221
|
return this.finishNode(node, type2);
|
|
57349
57222
|
} else {
|
|
57350
57223
|
throw this.raise(PlaceholderErrors.ClassNameIsRequired, this.state.startLoc);
|
|
@@ -57357,18 +57230,18 @@ function requireLib() {
|
|
|
57357
57230
|
return this.finishNode(node, type2);
|
|
57358
57231
|
}
|
|
57359
57232
|
parseExport(node, decorators) {
|
|
57360
|
-
const
|
|
57361
|
-
if (!
|
|
57233
|
+
const placeholder2 = this.parsePlaceholder("Identifier");
|
|
57234
|
+
if (!placeholder2) return super.parseExport(node, decorators);
|
|
57362
57235
|
const node2 = node;
|
|
57363
57236
|
if (!this.isContextual(98) && !this.match(12)) {
|
|
57364
57237
|
node2.specifiers = [];
|
|
57365
57238
|
node2.source = null;
|
|
57366
|
-
node2.declaration = this.finishPlaceholder(
|
|
57239
|
+
node2.declaration = this.finishPlaceholder(placeholder2, "Declaration");
|
|
57367
57240
|
return this.finishNode(node2, "ExportNamedDeclaration");
|
|
57368
57241
|
}
|
|
57369
57242
|
this.expectPlugin("exportDefaultFrom");
|
|
57370
57243
|
const specifier = this.startNode();
|
|
57371
|
-
specifier.exported =
|
|
57244
|
+
specifier.exported = placeholder2;
|
|
57372
57245
|
node2.specifiers = [this.finishNode(specifier, "ExportDefaultSpecifier")];
|
|
57373
57246
|
return super.parseExport(node2, decorators);
|
|
57374
57247
|
}
|
|
@@ -57401,16 +57274,16 @@ function requireLib() {
|
|
|
57401
57274
|
node.specifiers = specifiers;
|
|
57402
57275
|
}
|
|
57403
57276
|
parseImport(node) {
|
|
57404
|
-
const
|
|
57405
|
-
if (!
|
|
57277
|
+
const placeholder2 = this.parsePlaceholder("Identifier");
|
|
57278
|
+
if (!placeholder2) return super.parseImport(node);
|
|
57406
57279
|
node.specifiers = [];
|
|
57407
57280
|
if (!this.isContextual(98) && !this.match(12)) {
|
|
57408
|
-
node.source = this.finishPlaceholder(
|
|
57281
|
+
node.source = this.finishPlaceholder(placeholder2, "StringLiteral");
|
|
57409
57282
|
this.semicolon();
|
|
57410
57283
|
return this.finishNode(node, "ImportDeclaration");
|
|
57411
57284
|
}
|
|
57412
|
-
const specifier = this.startNodeAtNode(
|
|
57413
|
-
specifier.local =
|
|
57285
|
+
const specifier = this.startNodeAtNode(placeholder2);
|
|
57286
|
+
specifier.local = placeholder2;
|
|
57414
57287
|
node.specifiers.push(this.finishNode(specifier, "ImportDefaultSpecifier"));
|
|
57415
57288
|
if (this.eat(12)) {
|
|
57416
57289
|
const hasStarImport = this.maybeParseStarImportSpecifier(node);
|
|
@@ -73378,9 +73251,9 @@ function requireRuntimeCore_cjs_prod() {
|
|
|
73378
73251
|
queuePostRenderEffect(mountJob, parentSuspense);
|
|
73379
73252
|
};
|
|
73380
73253
|
if (n1 == null) {
|
|
73381
|
-
const
|
|
73254
|
+
const placeholder2 = n2.el = createText("");
|
|
73382
73255
|
const mainAnchor = n2.anchor = createText("");
|
|
73383
|
-
insert(
|
|
73256
|
+
insert(placeholder2, container, anchor);
|
|
73384
73257
|
insert(mainAnchor, container, anchor);
|
|
73385
73258
|
if (isTeleportDeferred(n2.props) || parentSuspense && parentSuspense.pendingBranch) {
|
|
73386
73259
|
queuePendingMount(n2);
|
|
@@ -77380,9 +77253,9 @@ function requireRuntimeCore_cjs_prod() {
|
|
|
77380
77253
|
if (instance.asyncDep) {
|
|
77381
77254
|
parentSuspense && parentSuspense.registerDep(instance, setupRenderEffect, optimized);
|
|
77382
77255
|
if (!initialVNode.el) {
|
|
77383
|
-
const
|
|
77384
|
-
processCommentNode(null,
|
|
77385
|
-
initialVNode.placeholder =
|
|
77256
|
+
const placeholder2 = instance.subTree = createVNode(Comment);
|
|
77257
|
+
processCommentNode(null, placeholder2, container, anchor);
|
|
77258
|
+
initialVNode.placeholder = placeholder2.el;
|
|
77386
77259
|
}
|
|
77387
77260
|
} else {
|
|
77388
77261
|
setupRenderEffect(
|
|
@@ -78664,7 +78537,7 @@ function requireRuntimeCore_cjs_prod() {
|
|
|
78664
78537
|
if (hydratedEl) {
|
|
78665
78538
|
vnode2.el = hydratedEl;
|
|
78666
78539
|
}
|
|
78667
|
-
const
|
|
78540
|
+
const placeholder2 = !hydratedEl && instance.subTree.el;
|
|
78668
78541
|
setupRenderEffect(
|
|
78669
78542
|
instance,
|
|
78670
78543
|
vnode2,
|
|
@@ -78679,9 +78552,9 @@ function requireRuntimeCore_cjs_prod() {
|
|
|
78679
78552
|
namespace,
|
|
78680
78553
|
optimized2
|
|
78681
78554
|
);
|
|
78682
|
-
if (
|
|
78555
|
+
if (placeholder2) {
|
|
78683
78556
|
vnode2.placeholder = null;
|
|
78684
|
-
remove2(
|
|
78557
|
+
remove2(placeholder2);
|
|
78685
78558
|
}
|
|
78686
78559
|
updateHOCHostEl(instance, vnode2.el);
|
|
78687
78560
|
if (isInPendingSuspense && --suspense.deps === 0) {
|
|
@@ -81823,6 +81696,133 @@ const __vite_glob_0_3$3 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.d
|
|
|
81823
81696
|
schema: schema$M,
|
|
81824
81697
|
type: type$M
|
|
81825
81698
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
81699
|
+
const TrackCount = Number$.pipe(int(), positive());
|
|
81700
|
+
const GridCoord = Number$.pipe(int(), positive());
|
|
81701
|
+
const Corner = Tuple(GridCoord, GridCoord).annotations({
|
|
81702
|
+
title: "Corner",
|
|
81703
|
+
description: "[x, y] 网格线号(1 基)"
|
|
81704
|
+
});
|
|
81705
|
+
const Area = Tuple(Corner, Corner).pipe(filter((a) => {
|
|
81706
|
+
if (a[1][0] <= a[0][0]) return "右下列线必须大于左上列线";
|
|
81707
|
+
if (a[1][1] <= a[0][1]) return "右下行线必须大于左上行线";
|
|
81708
|
+
return true;
|
|
81709
|
+
})).annotations({
|
|
81710
|
+
title: "Area",
|
|
81711
|
+
description: "矩形区域:`[[x1, y1], [x2, y2]]`,左上 + 右下对角(终止线不含)"
|
|
81712
|
+
});
|
|
81713
|
+
const Align$1 = Literal2("start", "center", "end", "stretch").annotations({
|
|
81714
|
+
title: "Align",
|
|
81715
|
+
description: "网格项在单轴上的对齐方式;缺省等同于 stretch"
|
|
81716
|
+
});
|
|
81717
|
+
const Placement = Struct({
|
|
81718
|
+
area: Area,
|
|
81719
|
+
h: optional(Align$1.annotations({ title: "水平对齐", description: "水平轴对齐(justify-self)" })),
|
|
81720
|
+
v: optional(Align$1.annotations({ title: "垂直对齐", description: "垂直轴对齐(align-self)" }))
|
|
81721
|
+
}).annotations({
|
|
81722
|
+
title: "Placement",
|
|
81723
|
+
description: "块在某一布局中的位置与对齐"
|
|
81724
|
+
});
|
|
81725
|
+
const Layout = Struct({
|
|
81726
|
+
columns: TrackCount.annotations({
|
|
81727
|
+
title: "列数",
|
|
81728
|
+
description: "总列数。每列等宽,渲染时展开为 `repeat(N, minmax(0, 1fr))` — 列会收缩以适配容器宽度"
|
|
81729
|
+
}),
|
|
81730
|
+
rows: optional(TrackCount.annotations({
|
|
81731
|
+
title: "行数",
|
|
81732
|
+
description: "总行数。每行等权,渲染时展开为 `repeat(N, minmax(0, 1fr))` — 在自然高度容器内等同于 `auto`"
|
|
81733
|
+
})),
|
|
81734
|
+
gap: optional(Number$.pipe(int(), nonNegative()).annotations({
|
|
81735
|
+
title: "网格间距",
|
|
81736
|
+
description: "非负整数;实际 CSS gap 为 `calc(n * 0.25rem)`。显式 `0` 表示无间距,未设置则取默认间距 4(即 `1rem`)"
|
|
81737
|
+
})),
|
|
81738
|
+
style: optional(String$.annotations({
|
|
81739
|
+
title: "容器样式",
|
|
81740
|
+
description: "容器的内联样式字符串"
|
|
81741
|
+
})),
|
|
81742
|
+
placements: Record({
|
|
81743
|
+
key: String$,
|
|
81744
|
+
value: Placement
|
|
81745
|
+
}).annotations({
|
|
81746
|
+
title: "位置",
|
|
81747
|
+
description: "以块 `id` 为键的位置映射;未映射的块在该布局中不渲染"
|
|
81748
|
+
})
|
|
81749
|
+
}).annotations({
|
|
81750
|
+
title: "Layout",
|
|
81751
|
+
description: "一套完整的网格布局"
|
|
81752
|
+
});
|
|
81753
|
+
function configureMedia(configure) {
|
|
81754
|
+
return (env) => {
|
|
81755
|
+
env.registerFunction(
|
|
81756
|
+
"media(string): bool",
|
|
81757
|
+
(_self, q) => typeof window !== "undefined" && window.matchMedia(q).matches,
|
|
81758
|
+
{ description: "匹配 CSS 媒体查询,等价于 `window.matchMedia(q).matches`;SSR 上下文返回 `false`" }
|
|
81759
|
+
);
|
|
81760
|
+
configure(env);
|
|
81761
|
+
};
|
|
81762
|
+
}
|
|
81763
|
+
function LayoutSet(configure) {
|
|
81764
|
+
return Struct({
|
|
81765
|
+
name: String$.annotations({
|
|
81766
|
+
title: "名称",
|
|
81767
|
+
description: "编辑器中区分不同布局的内部名称"
|
|
81768
|
+
}),
|
|
81769
|
+
media: optional(Expression({
|
|
81770
|
+
configure: configureMedia(configure),
|
|
81771
|
+
resultType: "bool"
|
|
81772
|
+
}).annotations({
|
|
81773
|
+
title: "匹配条件",
|
|
81774
|
+
description: "返回 `bool` 的 CEL 表达式,挂载时一次性求值;空表示无条件匹配。可用 `media('(min-width: 1024px)')` 包装 CSS 媒体查询。"
|
|
81775
|
+
})),
|
|
81776
|
+
layout: Layout
|
|
81777
|
+
}).annotations({
|
|
81778
|
+
title: "LayoutSet",
|
|
81779
|
+
description: "带匹配条件的布局集合项"
|
|
81780
|
+
});
|
|
81781
|
+
}
|
|
81782
|
+
function validatePlacements(items2, layouts, label) {
|
|
81783
|
+
const ids2 = new Set(items2.map((it) => it.id));
|
|
81784
|
+
for (const [i, set3] of layouts.entries()) {
|
|
81785
|
+
const nCols = set3.layout.columns;
|
|
81786
|
+
const nRows = set3.layout.rows;
|
|
81787
|
+
for (const [id2, placement] of Object.entries(set3.layout.placements)) {
|
|
81788
|
+
if (!ids2.has(id2)) {
|
|
81789
|
+
return `布局 #${i} (${set3.name}) 引用了不存在的${label} id: ${id2}`;
|
|
81790
|
+
}
|
|
81791
|
+
const [, [x2, y2]] = placement.area;
|
|
81792
|
+
if (x2 > nCols + 1) {
|
|
81793
|
+
return `布局 #${i} (${set3.name}) ${label} ${id2} 的列区域超出列定义(共 ${nCols} 列)`;
|
|
81794
|
+
}
|
|
81795
|
+
if (nRows !== void 0 && y2 > nRows + 1) {
|
|
81796
|
+
return `布局 #${i} (${set3.name}) ${label} ${id2} 的行区域超出行定义(共 ${nRows} 行)`;
|
|
81797
|
+
}
|
|
81798
|
+
}
|
|
81799
|
+
}
|
|
81800
|
+
return true;
|
|
81801
|
+
}
|
|
81802
|
+
function Slot(BlockSchemaUnion, configure) {
|
|
81803
|
+
return Struct({
|
|
81804
|
+
blocks: Array$(BlockSchemaUnion).annotations({
|
|
81805
|
+
title: "块",
|
|
81806
|
+
description: "块列表;未绑定到任何布局的块不会被渲染"
|
|
81807
|
+
}),
|
|
81808
|
+
layouts: Array$(LayoutSet(configure)).pipe(minItems(1)).annotations({
|
|
81809
|
+
title: "布局",
|
|
81810
|
+
description: "按顺序排列的布局集合;挂载时按序求值各项 `media` CEL 表达式,使用第一个为 `true` 的布局(全部不匹配时回退到最后一项)"
|
|
81811
|
+
})
|
|
81812
|
+
}).pipe(filter((slot) => {
|
|
81813
|
+
const items2 = slot.blocks.map((b) => ({ id: b.id }));
|
|
81814
|
+
return validatePlacements(items2, slot.layouts, "块");
|
|
81815
|
+
})).annotations({
|
|
81816
|
+
title: "Slot",
|
|
81817
|
+
description: "块与布局的组合:定义一组块以及它们在不同布局下的位置"
|
|
81818
|
+
});
|
|
81819
|
+
}
|
|
81820
|
+
function defaultSlot() {
|
|
81821
|
+
return {
|
|
81822
|
+
blocks: [],
|
|
81823
|
+
layouts: [{ name: "默认", layout: { columns: 1, placements: {} } }]
|
|
81824
|
+
};
|
|
81825
|
+
}
|
|
81826
81826
|
const blockRefCache = /* @__PURE__ */ new WeakMap();
|
|
81827
81827
|
function registerBlockRef(configure, ref2) {
|
|
81828
81828
|
blockRefCache.set(configure, ref2);
|
|
@@ -82175,7 +82175,9 @@ const BUTTONS = registry$3.ENTRIES.map((e) => ({
|
|
|
82175
82175
|
...e.deprecationNote !== void 0 ? { deprecationNote: e.deprecationNote } : {}
|
|
82176
82176
|
}));
|
|
82177
82177
|
function allButtonSchemas(configure) {
|
|
82178
|
-
return BUTTONS.map((entry) => entry.schema(configure)
|
|
82178
|
+
return BUTTONS.map((entry) => entry.schema(configure).annotations({
|
|
82179
|
+
identifier: `${entry.type}@${entry.compatibilityDate}`
|
|
82180
|
+
}));
|
|
82179
82181
|
}
|
|
82180
82182
|
const itemSchemaModules = /* @__PURE__ */ Object.assign({
|
|
82181
82183
|
"../items/2026-05-21/com.shwfed.actions.item.markdown/schema.ts": __vite_glob_3_0
|
|
@@ -82214,7 +82216,9 @@ const ITEMS = itemRegistry.ENTRIES.map((e) => ({
|
|
|
82214
82216
|
runtime: e.runtime
|
|
82215
82217
|
}));
|
|
82216
82218
|
function allItemSchemas(configure) {
|
|
82217
|
-
return ITEMS.map((entry) => entry.schema(configure)
|
|
82219
|
+
return ITEMS.map((entry) => entry.schema(configure).annotations({
|
|
82220
|
+
identifier: `${entry.type}@${entry.compatibilityDate}`
|
|
82221
|
+
}));
|
|
82218
82222
|
}
|
|
82219
82223
|
const KIND$3 = "shwfed.component.action";
|
|
82220
82224
|
const Variant = Literal2("default", "primary", "destructive", "ghost", "link").annotations({
|
|
@@ -92156,7 +92160,9 @@ const COLUMNS = registry$2.ENTRIES.map((e) => ({
|
|
|
92156
92160
|
return map2;
|
|
92157
92161
|
})();
|
|
92158
92162
|
function allColumnSchemas(configure) {
|
|
92159
|
-
return COLUMNS.map((entry) => entry.schema(configure)
|
|
92163
|
+
return COLUMNS.map((entry) => entry.schema(configure).annotations({
|
|
92164
|
+
identifier: `${entry.type}@${entry.compatibilityDate}`
|
|
92165
|
+
}));
|
|
92160
92166
|
}
|
|
92161
92167
|
function getTypeLiteral(ast) {
|
|
92162
92168
|
switch (ast._tag) {
|
|
@@ -92862,7 +92868,7 @@ function getFields() {
|
|
|
92862
92868
|
}));
|
|
92863
92869
|
return _fields;
|
|
92864
92870
|
}
|
|
92865
|
-
new Proxy([], {
|
|
92871
|
+
const FIELDS = new Proxy([], {
|
|
92866
92872
|
get(_, prop) {
|
|
92867
92873
|
const list2 = getFields();
|
|
92868
92874
|
const v = list2[prop];
|
|
@@ -92879,7 +92885,9 @@ new Proxy([], {
|
|
|
92879
92885
|
}
|
|
92880
92886
|
});
|
|
92881
92887
|
function allFieldSchemas(configure) {
|
|
92882
|
-
return getFields().map((entry) => entry.schema(configure)
|
|
92888
|
+
return getFields().map((entry) => entry.schema(configure).annotations({
|
|
92889
|
+
identifier: `${entry.type}@${entry.compatibilityDate}`
|
|
92890
|
+
}));
|
|
92883
92891
|
}
|
|
92884
92892
|
const KIND$1 = "shwfed.component.form";
|
|
92885
92893
|
function unitFields(configure) {
|
|
@@ -93442,7 +93450,9 @@ function getOrBuildUnion(configure) {
|
|
|
93442
93450
|
}).annotations({ identifier: "PageBlock" });
|
|
93443
93451
|
unionCache.set(configure, entry);
|
|
93444
93452
|
registerBlockRef(configure, entry.blockRef);
|
|
93445
|
-
entry.members = BLOCKS.map((b) => b.schema(configure, entry.blockRef)
|
|
93453
|
+
entry.members = BLOCKS.map((b) => b.schema(configure, entry.blockRef).annotations({
|
|
93454
|
+
identifier: `${b.type}@${b.compatibilityDate}`
|
|
93455
|
+
}));
|
|
93446
93456
|
entry.union = entry.members.length === 1 ? entry.members[0] : Union2(...entry.members);
|
|
93447
93457
|
return entry;
|
|
93448
93458
|
}
|
|
@@ -93464,31 +93474,11 @@ function PageConfig(configure) {
|
|
|
93464
93474
|
description: "页面组件完整配置"
|
|
93465
93475
|
});
|
|
93466
93476
|
}
|
|
93467
|
-
const pageSchema = PageConfig(() => {
|
|
93468
|
-
});
|
|
93469
|
-
function validateConfig(input) {
|
|
93470
|
-
const result = decodeUnknownEither(pageSchema, { errors: "all" })(input);
|
|
93471
|
-
if (isRight(result)) return { valid: true };
|
|
93472
|
-
const error2 = result.left;
|
|
93473
|
-
const issues = ArrayFormatter.formatErrorSync(error2).map((i) => ({
|
|
93474
|
-
path: i.path,
|
|
93475
|
-
message: i.message,
|
|
93476
|
-
tag: i._tag
|
|
93477
|
-
}));
|
|
93478
|
-
return {
|
|
93479
|
-
valid: false,
|
|
93480
|
-
message: TreeFormatter.formatErrorSync(error2),
|
|
93481
|
-
issues
|
|
93482
|
-
};
|
|
93483
|
-
}
|
|
93484
|
-
function getSchema() {
|
|
93485
|
-
return make$2(pageSchema);
|
|
93486
|
-
}
|
|
93487
93477
|
const isObject = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
93488
|
-
const branchesOf = (node) => {
|
|
93478
|
+
const branchesOf = (node, root) => {
|
|
93489
93479
|
const list2 = node.anyOf ?? node.oneOf;
|
|
93490
93480
|
if (!Array.isArray(list2)) return void 0;
|
|
93491
|
-
return list2.filter(isObject);
|
|
93481
|
+
return list2.filter(isObject).map((b) => resolveRef(b, root)).filter(isObject);
|
|
93492
93482
|
};
|
|
93493
93483
|
const typeEnumOf = (branch) => {
|
|
93494
93484
|
const props = isObject(branch.properties) ? branch.properties : void 0;
|
|
@@ -93524,8 +93514,8 @@ const parseSegment = (raw) => {
|
|
|
93524
93514
|
if (at >= 0) return { name: s.slice(0, at), pin: s.slice(at + 1), array: array2 };
|
|
93525
93515
|
return { name: s, array: array2 };
|
|
93526
93516
|
};
|
|
93527
|
-
const describeOptions = (node) => {
|
|
93528
|
-
const branches = branchesOf(node);
|
|
93517
|
+
const describeOptions = (node, root) => {
|
|
93518
|
+
const branches = branchesOf(node, root);
|
|
93529
93519
|
if (branches) {
|
|
93530
93520
|
const grouped = /* @__PURE__ */ new Map();
|
|
93531
93521
|
for (const b of branches) {
|
|
@@ -93561,7 +93551,7 @@ function narrowSchema(root, path) {
|
|
|
93561
93551
|
};
|
|
93562
93552
|
}
|
|
93563
93553
|
const { name, pin, array: array2 } = parseSegment(raw);
|
|
93564
|
-
const branches = branchesOf(node);
|
|
93554
|
+
const branches = branchesOf(node, root);
|
|
93565
93555
|
if (branches) {
|
|
93566
93556
|
const matches = branches.filter((b) => typeEnumOf(b).includes(name));
|
|
93567
93557
|
if (matches.length === 0) {
|
|
@@ -93569,7 +93559,7 @@ function narrowSchema(root, path) {
|
|
|
93569
93559
|
ok: false,
|
|
93570
93560
|
error: `no '${name}' branch at '${walked.join("/") || "<root>"}'`,
|
|
93571
93561
|
atPath: walked.join("/"),
|
|
93572
|
-
options: describeOptions(node)
|
|
93562
|
+
options: describeOptions(node, root)
|
|
93573
93563
|
};
|
|
93574
93564
|
}
|
|
93575
93565
|
let picked;
|
|
@@ -93603,7 +93593,7 @@ function narrowSchema(root, path) {
|
|
|
93603
93593
|
ok: false,
|
|
93604
93594
|
error: `can't resolve '${name}' at '${walked.join("/") || "<root>"}'`,
|
|
93605
93595
|
atPath: walked.join("/"),
|
|
93606
|
-
options: describeOptions(node)
|
|
93596
|
+
options: describeOptions(node, root)
|
|
93607
93597
|
};
|
|
93608
93598
|
}
|
|
93609
93599
|
if (array2) {
|
|
@@ -93623,17 +93613,290 @@ function narrowSchema(root, path) {
|
|
|
93623
93613
|
node = resolveRef(node, root);
|
|
93624
93614
|
return { ok: true, schema: node, resolvedPath: walked.join("/") };
|
|
93625
93615
|
}
|
|
93616
|
+
const pageSchema = PageConfig(() => {
|
|
93617
|
+
});
|
|
93618
|
+
function validateConfig(input) {
|
|
93619
|
+
const result = decodeUnknownEither(pageSchema, { errors: "all" })(input);
|
|
93620
|
+
if (isRight(result)) return { valid: true };
|
|
93621
|
+
const error2 = result.left;
|
|
93622
|
+
const issues = ArrayFormatter.formatErrorSync(error2).map((i) => ({
|
|
93623
|
+
path: i.path,
|
|
93624
|
+
message: i.message,
|
|
93625
|
+
tag: i._tag
|
|
93626
|
+
}));
|
|
93627
|
+
return {
|
|
93628
|
+
valid: false,
|
|
93629
|
+
message: TreeFormatter.formatErrorSync(error2),
|
|
93630
|
+
issues
|
|
93631
|
+
};
|
|
93632
|
+
}
|
|
93633
|
+
const KIND_NAMESPACES = [
|
|
93634
|
+
["com.shwfed.block.", "block"],
|
|
93635
|
+
["com.shwfed.form.field.", "field"],
|
|
93636
|
+
["com.shwfed.table.column.", "column"],
|
|
93637
|
+
["com.shwfed.actions.button.", "button"],
|
|
93638
|
+
["com.shwfed.actions.item.", "item"]
|
|
93639
|
+
];
|
|
93640
|
+
function kindOfType(t) {
|
|
93641
|
+
for (const [prefix, kind] of KIND_NAMESPACES) {
|
|
93642
|
+
if (t.startsWith(prefix)) return kind;
|
|
93643
|
+
}
|
|
93644
|
+
return void 0;
|
|
93645
|
+
}
|
|
93646
|
+
const isObj = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
93647
|
+
function refId(node) {
|
|
93648
|
+
if (!isObj(node) || typeof node.$ref !== "string") return void 0;
|
|
93649
|
+
if (!node.$ref.startsWith("#/$defs/")) return void 0;
|
|
93650
|
+
return node.$ref.slice("#/$defs/".length);
|
|
93651
|
+
}
|
|
93652
|
+
function classifyDefs(defs) {
|
|
93653
|
+
const leafIds = /* @__PURE__ */ new Map();
|
|
93654
|
+
for (const [id2, def] of Object.entries(defs)) {
|
|
93655
|
+
if (!isObj(def)) continue;
|
|
93656
|
+
const props = isObj(def.properties) ? def.properties : void 0;
|
|
93657
|
+
const typeProp = props && isObj(props.type) ? props.type : void 0;
|
|
93658
|
+
const typeEnum = typeProp?.enum;
|
|
93659
|
+
if (!Array.isArray(typeEnum) || typeof typeEnum[0] !== "string") continue;
|
|
93660
|
+
const cdProp = props && isObj(props.compatibilityDate) ? props.compatibilityDate : void 0;
|
|
93661
|
+
const cdEnum = cdProp?.enum;
|
|
93662
|
+
if (!Array.isArray(cdEnum) || cdEnum.length !== 1) continue;
|
|
93663
|
+
const kind = kindOfType(typeEnum[0]);
|
|
93664
|
+
if (kind) leafIds.set(id2, kind);
|
|
93665
|
+
}
|
|
93666
|
+
const containerIds = /* @__PURE__ */ new Map();
|
|
93667
|
+
for (const [id2, def] of Object.entries(defs)) {
|
|
93668
|
+
if (!isObj(def)) continue;
|
|
93669
|
+
const arr = def.anyOf ?? def.oneOf;
|
|
93670
|
+
if (!Array.isArray(arr) || arr.length === 0) continue;
|
|
93671
|
+
const kinds = /* @__PURE__ */ new Set();
|
|
93672
|
+
let allLeaf = true;
|
|
93673
|
+
for (const branch of arr) {
|
|
93674
|
+
const bid = refId(branch);
|
|
93675
|
+
const kind = bid !== void 0 ? leafIds.get(bid) : void 0;
|
|
93676
|
+
if (!kind) {
|
|
93677
|
+
allLeaf = false;
|
|
93678
|
+
break;
|
|
93679
|
+
}
|
|
93680
|
+
kinds.add(kind);
|
|
93681
|
+
}
|
|
93682
|
+
if (allLeaf && kinds.size === 1) containerIds.set(id2, [...kinds][0]);
|
|
93683
|
+
}
|
|
93684
|
+
return { leafIds, containerIds };
|
|
93685
|
+
}
|
|
93686
|
+
function placeholder(kind) {
|
|
93687
|
+
return {
|
|
93688
|
+
"x-shwfed-slot": kind,
|
|
93689
|
+
"description": `可注册的 ${kind} 槽位。先调用 search_metadata(kind='${kind}') 列出可选 (type, compatibilityDate);再调用 get_schema(path='<type>') 获取该项的详细 schema。`
|
|
93690
|
+
};
|
|
93691
|
+
}
|
|
93692
|
+
function rewriteNode(node, leafIds, containerIds) {
|
|
93693
|
+
if (Array.isArray(node)) return node.map((n) => rewriteNode(n, leafIds, containerIds));
|
|
93694
|
+
if (!isObj(node)) return node;
|
|
93695
|
+
const arr = node.anyOf ?? node.oneOf;
|
|
93696
|
+
if (Array.isArray(arr) && arr.length > 0) {
|
|
93697
|
+
const kinds = /* @__PURE__ */ new Set();
|
|
93698
|
+
let allLeaf = true;
|
|
93699
|
+
for (const branch of arr) {
|
|
93700
|
+
const bid = refId(branch);
|
|
93701
|
+
const kind = bid !== void 0 ? leafIds.get(bid) : void 0;
|
|
93702
|
+
if (!kind) {
|
|
93703
|
+
allLeaf = false;
|
|
93704
|
+
break;
|
|
93705
|
+
}
|
|
93706
|
+
kinds.add(kind);
|
|
93707
|
+
}
|
|
93708
|
+
if (allLeaf && kinds.size === 1) return placeholder([...kinds][0]);
|
|
93709
|
+
}
|
|
93710
|
+
const id2 = refId(node);
|
|
93711
|
+
if (id2 !== void 0) {
|
|
93712
|
+
const cKind = containerIds.get(id2);
|
|
93713
|
+
if (cKind) return placeholder(cKind);
|
|
93714
|
+
const lKind = leafIds.get(id2);
|
|
93715
|
+
if (lKind) return placeholder(lKind);
|
|
93716
|
+
}
|
|
93717
|
+
const out = {};
|
|
93718
|
+
for (const [k, v] of Object.entries(node)) out[k] = rewriteNode(v, leafIds, containerIds);
|
|
93719
|
+
return out;
|
|
93720
|
+
}
|
|
93721
|
+
function collectRefs(node, sink) {
|
|
93722
|
+
if (Array.isArray(node)) {
|
|
93723
|
+
for (const n of node) collectRefs(n, sink);
|
|
93724
|
+
return;
|
|
93725
|
+
}
|
|
93726
|
+
if (!isObj(node)) return;
|
|
93727
|
+
const id2 = refId(node);
|
|
93728
|
+
if (id2 !== void 0) sink.add(id2);
|
|
93729
|
+
for (const v of Object.values(node)) collectRefs(v, sink);
|
|
93730
|
+
}
|
|
93731
|
+
function postProcessSchema(node, root) {
|
|
93732
|
+
if (!isObj(root)) return node;
|
|
93733
|
+
const defs = root.$defs ?? {};
|
|
93734
|
+
const { leafIds, containerIds } = classifyDefs(defs);
|
|
93735
|
+
const inputForRewrite = isObj(node) && node.$defs !== void 0 ? Object.fromEntries(Object.entries(node).filter(([k]) => k !== "$defs")) : node;
|
|
93736
|
+
const rewritten = rewriteNode(inputForRewrite, leafIds, containerIds);
|
|
93737
|
+
const queue = [];
|
|
93738
|
+
const seen = /* @__PURE__ */ new Set();
|
|
93739
|
+
const initial = /* @__PURE__ */ new Set();
|
|
93740
|
+
collectRefs(rewritten, initial);
|
|
93741
|
+
for (const id2 of initial) {
|
|
93742
|
+
if (!seen.has(id2)) {
|
|
93743
|
+
seen.add(id2);
|
|
93744
|
+
queue.push(id2);
|
|
93745
|
+
}
|
|
93746
|
+
}
|
|
93747
|
+
const keptDefs = {};
|
|
93748
|
+
while (queue.length > 0) {
|
|
93749
|
+
const id2 = queue.shift();
|
|
93750
|
+
if (leafIds.has(id2) || containerIds.has(id2)) continue;
|
|
93751
|
+
const def = defs[id2];
|
|
93752
|
+
if (def === void 0) continue;
|
|
93753
|
+
const rewrittenDef = rewriteNode(def, leafIds, containerIds);
|
|
93754
|
+
keptDefs[id2] = rewrittenDef;
|
|
93755
|
+
const sub = /* @__PURE__ */ new Set();
|
|
93756
|
+
collectRefs(rewrittenDef, sub);
|
|
93757
|
+
for (const s of sub) {
|
|
93758
|
+
if (!seen.has(s)) {
|
|
93759
|
+
seen.add(s);
|
|
93760
|
+
queue.push(s);
|
|
93761
|
+
}
|
|
93762
|
+
}
|
|
93763
|
+
}
|
|
93764
|
+
if (!isObj(rewritten)) return rewritten;
|
|
93765
|
+
const { $defs: _omit, ...rest } = rewritten;
|
|
93766
|
+
if (Object.keys(keptDefs).length === 0) return rest;
|
|
93767
|
+
return { ...rest, $defs: keptDefs };
|
|
93768
|
+
}
|
|
93769
|
+
function getSchema() {
|
|
93770
|
+
return make$2(pageSchema);
|
|
93771
|
+
}
|
|
93772
|
+
function lookupLeafByType(defs, type2, date2) {
|
|
93773
|
+
if (date2) {
|
|
93774
|
+
const id22 = `${type2}@${date2}`;
|
|
93775
|
+
const def = defs[id22];
|
|
93776
|
+
if (def !== void 0) return { id: id22, def };
|
|
93777
|
+
return void 0;
|
|
93778
|
+
}
|
|
93779
|
+
const candidates = Object.keys(defs).filter((k) => k.startsWith(`${type2}@`));
|
|
93780
|
+
if (candidates.length === 0) return void 0;
|
|
93781
|
+
candidates.sort();
|
|
93782
|
+
const id2 = candidates[candidates.length - 1];
|
|
93783
|
+
return { id: id2, def: defs[id2] };
|
|
93784
|
+
}
|
|
93785
|
+
function getSchemaAtPath(path) {
|
|
93786
|
+
const root = getSchema();
|
|
93787
|
+
if (!path || !path.trim()) {
|
|
93788
|
+
return { ok: true, path: "", schema: postProcessSchema(root, root) };
|
|
93789
|
+
}
|
|
93790
|
+
const trimmed = path.trim();
|
|
93791
|
+
if (!trimmed.includes("/")) {
|
|
93792
|
+
if (!isObj(root)) {
|
|
93793
|
+
return { ok: false, error: "schema root is not an object" };
|
|
93794
|
+
}
|
|
93795
|
+
const defs = root.$defs ?? {};
|
|
93796
|
+
const atIdx = trimmed.indexOf("@");
|
|
93797
|
+
const type2 = atIdx >= 0 ? trimmed.slice(0, atIdx) : trimmed;
|
|
93798
|
+
const date2 = atIdx >= 0 ? trimmed.slice(atIdx + 1) : void 0;
|
|
93799
|
+
const found = lookupLeafByType(defs, type2, date2);
|
|
93800
|
+
if (!found) {
|
|
93801
|
+
return {
|
|
93802
|
+
ok: false,
|
|
93803
|
+
error: date2 ? `no leaf '${type2}@${date2}'` : `no leaf with type '${type2}'`,
|
|
93804
|
+
options: "call search_metadata to discover available (type, compatibilityDate) values"
|
|
93805
|
+
};
|
|
93806
|
+
}
|
|
93807
|
+
return {
|
|
93808
|
+
ok: true,
|
|
93809
|
+
path: found.id,
|
|
93810
|
+
schema: postProcessSchema(found.def, root)
|
|
93811
|
+
};
|
|
93812
|
+
}
|
|
93813
|
+
const r = narrowSchema(root, trimmed);
|
|
93814
|
+
if (!r.ok) {
|
|
93815
|
+
return { ok: false, error: r.error, atPath: r.atPath, options: r.options };
|
|
93816
|
+
}
|
|
93817
|
+
return {
|
|
93818
|
+
ok: true,
|
|
93819
|
+
path: r.resolvedPath,
|
|
93820
|
+
schema: postProcessSchema(r.schema, root)
|
|
93821
|
+
};
|
|
93822
|
+
}
|
|
93823
|
+
function listMetadata(opts = {}) {
|
|
93824
|
+
const items2 = [];
|
|
93825
|
+
for (const e of BLOCKS) {
|
|
93826
|
+
items2.push({
|
|
93827
|
+
kind: "block",
|
|
93828
|
+
type: e.type,
|
|
93829
|
+
compatibilityDate: e.compatibilityDate,
|
|
93830
|
+
name: e.metadata.name,
|
|
93831
|
+
icon: e.metadata.icon
|
|
93832
|
+
});
|
|
93833
|
+
}
|
|
93834
|
+
for (const e of FIELDS) {
|
|
93835
|
+
const m = {
|
|
93836
|
+
kind: "field",
|
|
93837
|
+
type: e.type,
|
|
93838
|
+
compatibilityDate: e.compatibilityDate,
|
|
93839
|
+
name: e.metadata.name,
|
|
93840
|
+
icon: e.metadata.icon
|
|
93841
|
+
};
|
|
93842
|
+
if (e.deprecated) m.deprecated = true;
|
|
93843
|
+
if (e.supersededBy) m.supersededBy = { type: e.supersededBy.type, compatibilityDate: e.supersededBy.compatibilityDate };
|
|
93844
|
+
items2.push(m);
|
|
93845
|
+
}
|
|
93846
|
+
for (const e of COLUMNS) {
|
|
93847
|
+
const m = {
|
|
93848
|
+
kind: "column",
|
|
93849
|
+
type: e.type,
|
|
93850
|
+
compatibilityDate: e.compatibilityDate,
|
|
93851
|
+
name: e.metadata.name,
|
|
93852
|
+
icon: e.metadata.icon
|
|
93853
|
+
};
|
|
93854
|
+
if (e.deprecated) m.deprecated = true;
|
|
93855
|
+
if (e.supersededBy) m.supersededBy = { type: e.supersededBy.type, compatibilityDate: e.supersededBy.compatibilityDate };
|
|
93856
|
+
items2.push(m);
|
|
93857
|
+
}
|
|
93858
|
+
for (const e of BUTTONS) {
|
|
93859
|
+
const m = {
|
|
93860
|
+
kind: "button",
|
|
93861
|
+
type: e.type,
|
|
93862
|
+
compatibilityDate: e.compatibilityDate,
|
|
93863
|
+
name: e.metadata.name,
|
|
93864
|
+
icon: e.metadata.icon
|
|
93865
|
+
};
|
|
93866
|
+
if (e.deprecated) m.deprecated = true;
|
|
93867
|
+
items2.push(m);
|
|
93868
|
+
}
|
|
93869
|
+
for (const e of ITEMS) {
|
|
93870
|
+
items2.push({
|
|
93871
|
+
kind: "item",
|
|
93872
|
+
type: e.type,
|
|
93873
|
+
compatibilityDate: e.compatibilityDate,
|
|
93874
|
+
name: e.metadata.name,
|
|
93875
|
+
icon: e.metadata.icon
|
|
93876
|
+
});
|
|
93877
|
+
}
|
|
93878
|
+
const q = opts.query?.trim().toLowerCase();
|
|
93879
|
+
return items2.filter((m) => {
|
|
93880
|
+
if (opts.kind && m.kind !== opts.kind) return false;
|
|
93881
|
+
if (q && !m.type.toLowerCase().includes(q) && !m.name.toLowerCase().includes(q)) return false;
|
|
93882
|
+
return true;
|
|
93883
|
+
});
|
|
93884
|
+
}
|
|
93626
93885
|
const server = new McpServer({
|
|
93627
93886
|
name: "@shwfed/config",
|
|
93628
93887
|
version: "0.1.0"
|
|
93629
93888
|
}, {
|
|
93630
93889
|
instructions: [
|
|
93631
|
-
"Tools for authoring ShwfedConfig JSON.
|
|
93890
|
+
"Tools for authoring ShwfedConfig JSON. The schema is organized so the agent never pulls every registerable at once — it discovers them via `search_metadata` and fetches each one with `get_schema(path='<type>')` on demand.",
|
|
93891
|
+
"",
|
|
93892
|
+
"Typical workflow:",
|
|
93893
|
+
"1. `get_schema()` with no path — returns the page skeleton. Union slots (`blocks[]`, `columns[]`, `fields[]`, `buttons[]`, `items[]`) appear as thin placeholders carrying `x-shwfed-slot: <kind>`. They do NOT enumerate the available types.",
|
|
93894
|
+
"2. `search_metadata(kind=<slot kind>)` — lists every registerable for that kind: `(type, compatibilityDate, name, icon)` plus deprecation info. Optional `query` filters by substring against `type` and `name`.",
|
|
93895
|
+
"3. `get_schema(path='<type>')` — fetches the chosen leaf's schema, with its own inner union slots also replaced by placeholders. Use `<type>@<compatibilityDate>` to pin a version; bare `<type>` picks the latest. Slash-separated paths still work for stepping through the tree (e.g. `slot/blocks[]/com.shwfed.block.form/form`).",
|
|
93896
|
+
"4. `validate_config` — validates a draft. Iterate until it returns `{ valid: true }`. CEL expressions are accepted as strings without evaluation.",
|
|
93897
|
+
"5. (Optional) `preview_config` / `stop_preview` — render the result in a localhost browser tab.",
|
|
93632
93898
|
"",
|
|
93633
|
-
"
|
|
93634
|
-
"1. When creating a new entry, ALWAYS pick the LATEST `compatibilityDate` available for that `type` in the schema. Do not select an older one because it looks simpler or familiar.",
|
|
93635
|
-
"2. When editing an existing config that uses an older `compatibilityDate`, prefer migrating it to the latest version (translate its fields into the newer contract) and tell the user you did so, instead of preserving the old version silently.",
|
|
93636
|
-
"3. Never mix versions of the same `type` across a single config when the latest covers the use case."
|
|
93899
|
+
"Versioning rules: the same `type` may appear at multiple `compatibilityDate`s with DIFFERENT contracts — they are not interchangeable. Always pick the LATEST `compatibilityDate` for new entries (this is the default when you pass bare `<type>`). When editing an existing config that uses an older `compatibilityDate`, prefer migrating it to the latest version and tell the user you did so, instead of preserving the old version silently."
|
|
93637
93900
|
].join("\n")
|
|
93638
93901
|
});
|
|
93639
93902
|
server.registerTool("validate_config", {
|
|
@@ -93653,27 +93916,23 @@ server.registerTool("validate_config", {
|
|
|
93653
93916
|
server.registerTool("get_schema", {
|
|
93654
93917
|
title: "Get ShwfedConfig JSON Schema",
|
|
93655
93918
|
description: [
|
|
93656
|
-
"Returns
|
|
93919
|
+
"Returns a JSON Schema (draft-07) fragment for a portion of the ShwfedConfig.",
|
|
93920
|
+
"",
|
|
93921
|
+
"Without `path`, returns the page-level skeleton. Union slots collapse into thin placeholders with `x-shwfed-slot: <kind>` and a hint to call `search_metadata` and then `get_schema(path='<type>')` — the leaves themselves are not enumerated.",
|
|
93657
93922
|
"",
|
|
93658
|
-
"
|
|
93659
|
-
" - `
|
|
93660
|
-
" - `
|
|
93661
|
-
"
|
|
93662
|
-
"
|
|
93663
|
-
"
|
|
93923
|
+
"With `path`, two syntaxes are accepted:",
|
|
93924
|
+
" - `<type>` or `<type>@<compatibilityDate>` (no slash) — direct leaf lookup. Bare `<type>` picks the latest `compatibilityDate`; pin with `@<date>` for an older version. Example: `com.shwfed.form.field.text`, `com.shwfed.block.table@2026-05-06`.",
|
|
93925
|
+
" - `<segment>/<segment>/…` — step through the tree by property name, with `[]` to enter an array's `items` and `<type>` (optionally `@<date>`) to pick a union branch. Example: `slot/blocks[]/com.shwfed.block.table/columns[]/com.shwfed.table.column.text`.",
|
|
93926
|
+
"",
|
|
93927
|
+
"Inner union slots in the returned schema are also collapsed to placeholders, so a leaf fetch is bounded in size. To explore an inner slot, fetch that slot's leaf separately with another `get_schema(path='<type>')` call.",
|
|
93928
|
+
"",
|
|
93929
|
+
"Versioning: the same `type` may be published at multiple `compatibilityDate`s with incompatible contracts. For new entries, prefer the latest. For existing configs on older dates, prefer migrating to the latest and report the migration."
|
|
93664
93930
|
].join("\n"),
|
|
93665
93931
|
inputSchema: {
|
|
93666
|
-
path: string$1().optional().describe("Optional
|
|
93932
|
+
path: string$1().optional().describe("Optional path or leaf shortcut. See description for syntax.")
|
|
93667
93933
|
}
|
|
93668
93934
|
}, async ({ path }) => {
|
|
93669
|
-
const
|
|
93670
|
-
if (!path) {
|
|
93671
|
-
return {
|
|
93672
|
-
content: [{ type: "text", text: JSON.stringify(schema2, null, 2) }],
|
|
93673
|
-
structuredContent: schema2
|
|
93674
|
-
};
|
|
93675
|
-
}
|
|
93676
|
-
const result = narrowSchema(schema2, path);
|
|
93935
|
+
const result = getSchemaAtPath(path);
|
|
93677
93936
|
if (!result.ok) {
|
|
93678
93937
|
const payload2 = { error: result.error, atPath: result.atPath, options: result.options };
|
|
93679
93938
|
return {
|
|
@@ -93682,7 +93941,33 @@ server.registerTool("get_schema", {
|
|
|
93682
93941
|
isError: true
|
|
93683
93942
|
};
|
|
93684
93943
|
}
|
|
93685
|
-
const payload = { path: result.
|
|
93944
|
+
const payload = { path: result.path, schema: result.schema };
|
|
93945
|
+
return {
|
|
93946
|
+
content: [{ type: "text", text: JSON.stringify(payload, null, 2) }],
|
|
93947
|
+
structuredContent: payload
|
|
93948
|
+
};
|
|
93949
|
+
});
|
|
93950
|
+
server.registerTool("search_metadata", {
|
|
93951
|
+
title: "List or search registerable items",
|
|
93952
|
+
description: [
|
|
93953
|
+
"Returns metadata for every registerable item (block, field, column, button, item). Use this to discover what `(type, compatibilityDate)` values are valid at a given slot before calling `get_schema(path='<type>')` to fetch the chosen leaf's detailed schema.",
|
|
93954
|
+
"",
|
|
93955
|
+
"Each result carries:",
|
|
93956
|
+
" - `kind`: which slot the entry plugs into (`block` | `field` | `column` | `button` | `item`).",
|
|
93957
|
+
" - `type`, `compatibilityDate`: identity. The same `type` may appear at multiple dates with incompatible contracts.",
|
|
93958
|
+
" - `name`, `icon`: human-readable label and icon name (Iconify slug).",
|
|
93959
|
+
" - `deprecated`: present and `true` when the entry is superseded.",
|
|
93960
|
+
" - `supersededBy`: when known, the `(type, compatibilityDate)` to migrate to.",
|
|
93961
|
+
"",
|
|
93962
|
+
"Filter with `kind` (single kind) and/or `query` (case-insensitive substring against `type` and `name`). Omit both to dump everything."
|
|
93963
|
+
].join("\n"),
|
|
93964
|
+
inputSchema: {
|
|
93965
|
+
kind: _enum$1(["block", "field", "column", "button", "item"]).optional().describe("Restrict results to one slot kind."),
|
|
93966
|
+
query: string$1().optional().describe("Case-insensitive substring matched against `type` and `name`.")
|
|
93967
|
+
}
|
|
93968
|
+
}, async ({ kind, query }) => {
|
|
93969
|
+
const items2 = listMetadata({ kind, query });
|
|
93970
|
+
const payload = { count: items2.length, items: items2 };
|
|
93686
93971
|
return {
|
|
93687
93972
|
content: [{ type: "text", text: JSON.stringify(payload, null, 2) }],
|
|
93688
93973
|
structuredContent: payload
|