@shwfed/config 2.3.10 → 2.3.11
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 +704 -441
- package/dist/module.json +1 -1
- package/dist/preview/assets/{config-BxzDT_57.js → config-57-v4VXo.js} +1 -1
- package/dist/preview/assets/{config-2R4XkSGs.js → config-BZahzuEc.js} +1 -1
- package/dist/preview/assets/{config-KcLrpkc1.js → config-Be-2ZA2R.js} +1 -1
- package/dist/preview/assets/{config-ykJZssgx.js → config-BnZQO-Sp.js} +1 -1
- package/dist/preview/assets/{config-bxqg3yuv.js → config-Bp91DUdU.js} +1 -1
- package/dist/preview/assets/{config-CyScbxXy.js → config-DNokxY7M.js} +1 -1
- package/dist/preview/assets/{config-HdWYFZ09.js → config-_msO_f2R.js} +1 -1
- package/dist/preview/assets/{config-ja_GMXxV.js → config-_uPI8qV-.js} +1 -1
- package/dist/preview/assets/{definition.vue_vue_type_script_setup_true_lang-CWyVRSOh.js → definition.vue_vue_type_script_setup_true_lang-BtScXbs1.js} +1 -1
- package/dist/preview/assets/index-DDbl2Atj.js +1 -0
- package/dist/preview/assets/index-DGa3Oj3y.js +1075 -0
- package/dist/preview/assets/{index-BPKK3hGV.css → index-mbGtsgdv.css} +1 -1
- package/dist/preview/assets/{runtime-LBdh1D75.js → runtime-B9u14qqB.js} +1 -1
- package/dist/preview/assets/{runtime-B8aUJIpn.js → runtime-BBms4myv.js} +1 -1
- package/dist/preview/assets/{runtime-D2K1s33u.js → runtime-CfR7ZAND.js} +1 -1
- package/dist/preview/assets/{runtime-C9XnvD5A.js → runtime-D3EyeiyA.js} +1 -1
- package/dist/preview/assets/{runtime-DqZhDPHl.js → runtime-Dk9u-Ybw.js} +1 -1
- package/dist/preview/assets/{runtime-CpSiaWMP.js → runtime-XXqIAt53.js} +1 -1
- package/dist/preview/assets/{runtime-CxA8fvQP.js → runtime-cKWSGFod.js} +1 -1
- package/dist/preview/assets/{runtime-DAXQmtLg.js → runtime-w7V-p3t1.js} +1 -1
- package/dist/preview/index.html +2 -2
- package/dist/runtime/components/form/ai/fields-button.vue +3 -1
- package/dist/runtime/components/form/unit-config.vue +8 -4
- package/dist/runtime/components/form/utils/resolve.d.ts +48 -9
- package/dist/runtime/components/form/utils/resolve.js +59 -5
- package/dist/runtime/components/table/ai/columns-button.vue +1 -0
- package/dist/runtime/components/table/columns/2026-05-13/com.shwfed.table.column.switch.remote/config.d.vue.ts +10 -0
- package/dist/runtime/components/table/columns/2026-05-13/com.shwfed.table.column.switch.remote/config.vue +305 -0
- package/dist/runtime/components/table/columns/2026-05-13/com.shwfed.table.column.switch.remote/config.vue.d.ts +10 -0
- package/dist/runtime/components/table/columns/2026-05-13/com.shwfed.table.column.switch.remote/runtime.d.vue.ts +9 -0
- package/dist/runtime/components/table/columns/2026-05-13/com.shwfed.table.column.switch.remote/runtime.vue +81 -0
- package/dist/runtime/components/table/columns/2026-05-13/com.shwfed.table.column.switch.remote/runtime.vue.d.ts +9 -0
- package/dist/runtime/components/table/columns/2026-05-13/com.shwfed.table.column.switch.remote/schema.d.ts +55 -0
- package/dist/runtime/components/table/columns/2026-05-13/com.shwfed.table.column.switch.remote/schema.js +82 -0
- package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.switch.local/config.d.vue.ts +10 -0
- package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.switch.local/config.vue +310 -0
- package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.switch.local/config.vue.d.ts +10 -0
- package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.switch.local/runtime.d.vue.ts +9 -0
- package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.switch.local/runtime.vue +81 -0
- package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.switch.local/runtime.vue.d.ts +9 -0
- package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.switch.local/schema.d.ts +66 -0
- package/dist/runtime/components/table/columns/2026-05-20/com.shwfed.table.column.switch.local/schema.js +71 -0
- package/dist/runtime/components/table/config.vue +2 -1
- package/dist/runtime/components/table/utils/resolve.d.ts +53 -0
- package/dist/runtime/components/table/utils/resolve.js +66 -1
- package/package.json +1 -1
- package/dist/preview/assets/index-D3pf2RjG.js +0 -1
- package/dist/preview/assets/index-OUd02U3g.js +0 -1075
|
@@ -1 +1 @@
|
|
|
1
|
-
import{d as u,ad as l,e as i,u as p,$ as d,o as m,k as f,af as _,ag as k,aj as g,ak as w,al as x}from"./index-
|
|
1
|
+
import{d as u,ad as l,e as i,u as p,$ as d,o as m,k as f,af as _,ag as k,aj as g,ak as w,al as x}from"./index-DGa3Oj3y.js";const B=u({name:"ShwfedMarkdownItemRuntime",__name:"runtime",props:{config:{}},setup(n){const s=n,{locale:o}=l(),t=x(),c=(e,a)=>g(e,{...w(t),...a}),r=d(()=>{const e=_(s.config.content,o.value)??"";return k(e,c)});return(e,a)=>(m(),i(p(f),{"data-slot":"buttons-markdown",source:r.value,class:"prose prose-sm prose-zinc px-1"},null,8,["source"]))}});export{B as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{_ as o}from"./definition.vue_vue_type_script_setup_true_lang-
|
|
1
|
+
import{_ as o}from"./definition.vue_vue_type_script_setup_true_lang-BtScXbs1.js";import{d as n,e as a,u as c,o as f,ao as i}from"./index-DGa3Oj3y.js";const _=n({name:"ShwfedPrototypeActionRuntime",__name:"runtime",props:{buttonId:{},config:{}},setup(e){const t=i;return(r,s)=>(f(),a(o,{"action-id":e.buttonId,effect:c(t)},null,8,["action-id","effect"]))}});export{_ as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{_ as s}from"./definition.vue_vue_type_script_setup_true_lang-
|
|
1
|
+
import{_ as s}from"./definition.vue_vue_type_script_setup_true_lang-BtScXbs1.js";import{d as c,an as o,az as i,e as r,u as f,am as u,o as m}from"./index-DGa3Oj3y.js";const g=c({name:"ShwfedEventDispatchActionRuntime",__name:"runtime",props:{buttonId:{},config:{}},setup(e){const n=e,t=u(),a=o(()=>i(t,n.config.triggers));return(p,d)=>(m(),r(s,{"action-id":e.buttonId,effect:f(a)},null,8,["action-id","effect"]))}});export{g as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{d as r,an as f,ai as u,e as p,u as g,aj as m,ak as l,al as d,am as x,o as E}from"./index-
|
|
1
|
+
import{d as r,an as f,ai as u,e as p,u as g,aj as m,ak as l,al as d,am as x,o as E}from"./index-DGa3Oj3y.js";import{_}from"./definition.vue_vue_type_script_setup_true_lang-BtScXbs1.js";const k=r({name:"ShwfedHttpRequestActionRuntime",__name:"runtime",props:{buttonId:{},config:{}},setup(n){const e=n,t=d(),c=(s,o)=>m(s,{...l(t),...o}),i=x(),a=f(()=>u(e.config.expression,c,{messageExpression:e.config.messageExpression,resultExpression:e.config.resultExpression,channel:i,triggers:{success:e.config.onSuccess,warning:e.config.onWarning,error:e.config.onError,info:e.config.onInfo}}));return(s,o)=>(E(),p(_,{"action-id":n.buttonId,effect:g(a)},null,8,["action-id","effect"]))}});export{k as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{d as i,an as f,ap as r,aq as d,e as u,u as m,aj as p,ak as l,al as _,o as g}from"./index-
|
|
1
|
+
import{d as i,an as f,ap as r,aq as d,e as u,u as m,aj as p,ak as l,al as _,o as g}from"./index-DGa3Oj3y.js";import{_ as h}from"./definition.vue_vue_type_script_setup_true_lang-BtScXbs1.js";const x=i({name:"ShwfedNavigationActionRuntime",__name:"runtime",props:{buttonId:{},config:{}},setup(e){const t=e,o=_(),c=(n,a)=>p(n,{...l(o),...a}),s=f(()=>r(c(t.config.url),n=>d(()=>{window.open(n,t.config.mode)})));return(n,a)=>(g(),u(h,{"action-id":e.buttonId,effect:m(s)},null,8,["action-id","effect"]))}});export{x as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{d as s,ad as B,ar as E,ae as _,af as i,as as x,at as p,e as M,w as c,u as d,a0 as N,am as b,aq as k,o as w,f as L,au as T,g as u,av as I,aw as H,a7 as S,al as V,ax as $,ay as z}from"./index-
|
|
1
|
+
import{d as s,ad as B,ar as E,ae as _,af as i,as as x,at as p,e as M,w as c,u as d,a0 as N,am as b,aq as k,o as w,f as L,au as T,g as u,av as I,aw as H,a7 as S,al as V,ax as $,ay as z}from"./index-DGa3Oj3y.js";import{_ as A}from"./definition.vue_vue_type_script_setup_true_lang-BtScXbs1.js";const F=s({name:"ShwfedModalLayoutActionRuntime",__name:"runtime",props:{buttonId:{},config:{},buttonTitle:{}},setup(a){const n=a,{locale:l}=B(),f=e=>{},r=V(),m=b(),o=N(null),v=E(n.buttonId,{close:()=>k(()=>{o.value?.()})},m),g=s({name:"ModalBoundaryBridge",setup(e,{slots:t}){return H(r),$(z,v),()=>t.default?.()}}),h=(e,t)=>S()?.(e,t),C=_(function*(){const e=i(n.config.modalTitle,l.value)??i(n.buttonTitle,l.value)??"",{modal:t,close:y}=yield*x({title:e,width:n.config.modalWidth});o.value=()=>p(y()),yield*t,o.value=null});return(e,t)=>(w(),M(A,{"action-id":a.buttonId,effect:d(C)},{default:c(()=>[L("div",{style:T(a.config.modalMinHeight?`min-height: ${a.config.modalMinHeight}`:void 0)},[u(d(g),null,{default:c(()=>[u(I,{"slot-value":a.config.slot,configure:f,"find-entry":h},null,8,["slot-value"])]),_:1})],4)]),_:1},8,["action-id","effect"]))}});export{F as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{d as f,ad as u,ae as l,af as g,ag as d,ah as m,ai as p,e as x,u as E,aj as _,ak as h,al as k,am as w,o as C}from"./index-
|
|
1
|
+
import{d as f,ad as u,ae as l,af as g,ag as d,ah as m,ai as p,e as x,u as E,aj as _,ak as h,al as k,am as w,o as C}from"./index-DGa3Oj3y.js";import{_ as I}from"./definition.vue_vue_type_script_setup_true_lang-BtScXbs1.js";const R=f({name:"ShwfedHttpRequestConfirmActionRuntime",__name:"runtime",props:{buttonId:{},config:{}},setup(s){const n=s,{locale:c}=u(),a=k(),t=(e,o)=>_(e,{...h(a),...o}),i=w(),r=l(function*(){const e=g(n.config.markdown,c.value)??"",o=d(e,t);(yield*m({content:o,icon:n.config.icon,color:n.config.color}))||(yield*p(n.config.expression,t,{messageExpression:n.config.messageExpression,resultExpression:n.config.resultExpression,channel:i,triggers:{success:n.config.onSuccess,warning:n.config.onWarning,error:n.config.onError,info:n.config.onInfo}}))});return(e,o)=>(C(),x(I,{"action-id":s.buttonId,effect:E(r)},null,8,["action-id","effect"]))}});export{R as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{d as _,an as j,ae as B,aq as r,az as m,aA as E,aB as S,e as k,u as v,aj as x,ak as L,am as b,o as C,al as R}from"./index-
|
|
1
|
+
import{d as _,an as j,ae as B,aq as r,az as m,aA as E,aB as S,e as k,u as v,aj as x,ak as L,am as b,o as C,al as R}from"./index-DGa3Oj3y.js";import{_ as T}from"./definition.vue_vue_type_script_setup_true_lang-BtScXbs1.js";const I=_({name:"ShwfedHttpDownloadActionRuntime",__name:"runtime",props:{buttonId:{},config:{}},setup(d){const c=d,g=R(),t=(e,n)=>x(e,{...L(g),...n}),l=b(),p=new Set(["success","error","warning","info"]);function f(e){const n=URL.createObjectURL(e),o=document.createElement("a");o.href=n,o.download=e.name,document.body.appendChild(o),o.click(),o.remove(),URL.revokeObjectURL(n)}const y=j(()=>B(function*(){const{template:e,messageExpression:n,resultExpression:o}=c.config,u=yield*t(e.request);if(!e.download){const s=yield*u.file();return yield*r(()=>f(s)),yield*m(l,c.config.onSuccess)}const a={json:yield*u.json()},i=o===void 0?"success":yield*E(t(o,a),s=>p.has(s)?s:"success");if(n!==void 0){const s=yield*t(n,a);yield*r(()=>S[i](s))}if(i==="success"||i==="info"){const h=yield*(yield*t(e.download,a)).file();yield*r(()=>f(h))}const w={success:c.config.onSuccess,warning:c.config.onWarning,error:c.config.onError,info:c.config.onInfo};return yield*m(l,w[i])}));return(e,n)=>(C(),k(T,{"action-id":d.buttonId,effect:v(y)},null,8,["action-id","effect"]))}});export{I as default};
|
package/dist/preview/index.html
CHANGED
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
`--primary`, the primary button variant renders as transparent. */
|
|
11
11
|
body { --primary: #009689; }
|
|
12
12
|
</style>
|
|
13
|
-
<script type="module" crossorigin src="./assets/index-
|
|
14
|
-
<link rel="stylesheet" crossorigin href="./assets/index-
|
|
13
|
+
<script type="module" crossorigin src="./assets/index-DGa3Oj3y.js"></script>
|
|
14
|
+
<link rel="stylesheet" crossorigin href="./assets/index-mbGtsgdv.css">
|
|
15
15
|
</head>
|
|
16
16
|
<body>
|
|
17
17
|
<div id="app"></div>
|
|
@@ -177,9 +177,11 @@ function collectErrors(fields) {
|
|
|
177
177
|
return;
|
|
178
178
|
}
|
|
179
179
|
if (entry.deprecated) {
|
|
180
|
+
const sup = entry.supersededBy;
|
|
181
|
+
const replacement = sup ? sup.type === type ? `"${sup.compatibilityDate}"` : `"${sup.type}@${sup.compatibilityDate}"` : "the current alternative";
|
|
180
182
|
out.push({
|
|
181
183
|
path: `${prefix}.compatibilityDate`,
|
|
182
|
-
message: `compatibilityDate "${field.compatibilityDate}" for "${type}" is deprecated. Use
|
|
184
|
+
message: `compatibilityDate "${field.compatibilityDate}" for "${type}" is deprecated. Use ${replacement} instead.`
|
|
183
185
|
});
|
|
184
186
|
return;
|
|
185
187
|
}
|
|
@@ -90,6 +90,7 @@ function addLayout() {
|
|
|
90
90
|
const FIELD_PICKER_ENTRIES = computed(() => {
|
|
91
91
|
const byType = /* @__PURE__ */ new Map();
|
|
92
92
|
for (const f of FIELDS) {
|
|
93
|
+
if (f.deprecated) continue;
|
|
93
94
|
const prev = byType.get(f.type);
|
|
94
95
|
if (!prev || f.compatibilityDate > prev.compatibilityDate) {
|
|
95
96
|
byType.set(f.type, {
|
|
@@ -203,7 +204,7 @@ const migrationContext = { $cel: celForMigration };
|
|
|
203
204
|
const latestEntry = computed(() => {
|
|
204
205
|
const e = activeFieldEntry.value;
|
|
205
206
|
if (!e?.deprecated || !e.supersededBy) return null;
|
|
206
|
-
return findField(e.type, e.supersededBy) ?? null;
|
|
207
|
+
return findField(e.supersededBy.type, e.supersededBy.compatibilityDate) ?? null;
|
|
207
208
|
});
|
|
208
209
|
const canMigrate = computed(() => !!latestEntry.value?.migrate);
|
|
209
210
|
async function migrateActiveField() {
|
|
@@ -213,7 +214,10 @@ async function migrateActiveField() {
|
|
|
213
214
|
try {
|
|
214
215
|
const next = await Effect.runPromise(target.migrate(sel, migrationContext));
|
|
215
216
|
updateActiveField(next);
|
|
216
|
-
|
|
217
|
+
const isSameType = target.type === sel.type;
|
|
218
|
+
toast.success(
|
|
219
|
+
isSameType ? `\u5DF2\u8FC1\u79FB\u5230 ${target.compatibilityDate} \u7248\u672C` : `\u5DF2\u8FC1\u79FB\u5230 ${target.type}@${target.compatibilityDate}`
|
|
220
|
+
);
|
|
217
221
|
} catch (err) {
|
|
218
222
|
const message = err instanceof Error ? err.message : String(err);
|
|
219
223
|
toast.error("\u8FC1\u79FB\u5931\u8D25", { description: message });
|
|
@@ -466,7 +470,7 @@ function isExtraActive(id) {
|
|
|
466
470
|
v-if="activeFieldEntry"
|
|
467
471
|
>
|
|
468
472
|
<div
|
|
469
|
-
v-if="activeFieldEntry.deprecated"
|
|
473
|
+
v-if="activeFieldEntry.deprecated && activeFieldEntry.supersededBy"
|
|
470
474
|
class="mb-4 flex items-center gap-2 rounded border border-amber-200 bg-amber-50 px-3 py-2 text-xs text-amber-800"
|
|
471
475
|
role="alert"
|
|
472
476
|
>
|
|
@@ -475,7 +479,7 @@ function isExtraActive(id) {
|
|
|
475
479
|
class="size-4 shrink-0"
|
|
476
480
|
/>
|
|
477
481
|
<span class="flex-1">
|
|
478
|
-
此字段类型已弃用,建议迁移至 <span class="tabular-nums font-medium">{{ activeFieldEntry.supersededBy }}</span
|
|
482
|
+
此字段类型已弃用,建议迁移至 <span class="tabular-nums font-medium">{{ activeFieldEntry.supersededBy.type === activeFieldEntry.type ? activeFieldEntry.supersededBy.compatibilityDate : `${activeFieldEntry.supersededBy.type}@${activeFieldEntry.supersededBy.compatibilityDate}` }}</span>。
|
|
479
483
|
</span>
|
|
480
484
|
<Button
|
|
481
485
|
v-if="canMigrate"
|
|
@@ -13,12 +13,29 @@ export type MigrationContext = Readonly<{
|
|
|
13
13
|
$cel: <T>(expression: string, context?: Record<string, unknown>) => Effect.Effect<T, unknown>;
|
|
14
14
|
}>;
|
|
15
15
|
/**
|
|
16
|
-
* Migrates a value of
|
|
17
|
-
*
|
|
18
|
-
*
|
|
16
|
+
* Migrates a value of a source schema to this entry's schema. Lives on the
|
|
17
|
+
* target (newer) entry. The Effect's success channel is the migrated value;
|
|
18
|
+
* failures surface to the host as a toast — see
|
|
19
19
|
* src/runtime/components/form/config.vue's migrate handler.
|
|
20
|
+
*
|
|
21
|
+
* The target is selected by one of two rules: (a) same `type` with a strictly
|
|
22
|
+
* newer `compatibilityDate`, or (b) an explicit `migrateFrom` declaration on
|
|
23
|
+
* the target naming this source `(type, compatibilityDate)`. Either way the
|
|
24
|
+
* migrate function only sees the previous value and the host capabilities.
|
|
20
25
|
*/
|
|
21
26
|
export type MigrateFn = (prev: unknown, ctx: MigrationContext) => Effect.Effect<unknown, Error>;
|
|
27
|
+
/**
|
|
28
|
+
* Identifies an entry by `(type, compatibilityDate)`. Used for `migrateFrom`
|
|
29
|
+
* declarations on a target, and for the cross-type form of `supersededBy`
|
|
30
|
+
* exposed on a deprecated entry.
|
|
31
|
+
*
|
|
32
|
+
* Migration declarations only ever live on the *new* (target) code — old
|
|
33
|
+
* folders are never modified to announce that they have been superseded.
|
|
34
|
+
*/
|
|
35
|
+
export type MigrateSource = Readonly<{
|
|
36
|
+
type: string;
|
|
37
|
+
compatibilityDate: string;
|
|
38
|
+
}>;
|
|
22
39
|
export type FieldSizeRange = Readonly<{
|
|
23
40
|
/** Span (in step units) used when the field is first placed. */
|
|
24
41
|
initial: number;
|
|
@@ -54,16 +71,25 @@ export type FieldEntry = Readonly<{
|
|
|
54
71
|
schema: SchemaFactory;
|
|
55
72
|
config: Component;
|
|
56
73
|
runtime: Component;
|
|
57
|
-
/**
|
|
74
|
+
/**
|
|
75
|
+
* True iff this entry is shadowed by either (a) a newer-date entry sharing
|
|
76
|
+
* its `type`, or (b) another entry whose `migrateFrom` names this one.
|
|
77
|
+
*/
|
|
58
78
|
deprecated: boolean;
|
|
59
|
-
/** `compatibilityDate` of the newest entry sharing this `type`, when deprecated. */
|
|
60
|
-
supersededBy?: string;
|
|
61
79
|
/**
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
80
|
+
* Identifies the entry that supersedes this one. Same `type` for the
|
|
81
|
+
* date-versioned rule; a different `type` for declared cross-type
|
|
82
|
+
* migrations.
|
|
83
|
+
*/
|
|
84
|
+
supersededBy?: MigrateSource;
|
|
85
|
+
/**
|
|
86
|
+
* Optional migration from a recognized source schema to this entry's
|
|
87
|
+
* schema. When present, the host renders a "迁移" button on deprecated
|
|
88
|
+
* entries whose target exposes this function.
|
|
65
89
|
*/
|
|
66
90
|
migrate?: MigrateFn;
|
|
91
|
+
/** Source schemas this entry accepts migration from. See module field. */
|
|
92
|
+
migrateFrom?: ReadonlyArray<MigrateSource>;
|
|
67
93
|
/**
|
|
68
94
|
* Optional creation-time defaults. The host merges the returned partial
|
|
69
95
|
* onto the seed when the user adds a new field via the picker. Absent →
|
|
@@ -74,4 +100,17 @@ export type FieldEntry = Readonly<{
|
|
|
74
100
|
export declare const FIELDS: ReadonlyArray<FieldEntry>;
|
|
75
101
|
export declare function allFieldSchemas(configure: (env: Environment) => void): ReadonlyArray<AnySchema>;
|
|
76
102
|
export declare function findField(type: string, compatibilityDate: string): FieldEntry | undefined;
|
|
103
|
+
/**
|
|
104
|
+
* Finds the registry entry that has declared `(type, compatibilityDate)` as a
|
|
105
|
+
* migration source on its `migrateFrom`. Use when a stored value's identity
|
|
106
|
+
* no longer matches any registry entry (the old folder was renamed away) —
|
|
107
|
+
* a present return means the value is still migratable via the target's
|
|
108
|
+
* `migrate`.
|
|
109
|
+
*
|
|
110
|
+
* Note: for the date-versioned rule (same `type`, newer `compatibilityDate`)
|
|
111
|
+
* the entry itself is in the registry and tagged `deprecated`/`supersededBy`;
|
|
112
|
+
* callers reach the target through `findField(supersededBy.type, …)` rather
|
|
113
|
+
* than this function.
|
|
114
|
+
*/
|
|
115
|
+
export declare function findMigrationTarget(type: string, compatibilityDate: string): FieldEntry | undefined;
|
|
77
116
|
export {};
|
|
@@ -11,28 +11,76 @@ const runtimeModules = import.meta.glob(
|
|
|
11
11
|
"../fields/*/*/runtime.vue",
|
|
12
12
|
{ eager: true, import: "default", exhaustive: true }
|
|
13
13
|
);
|
|
14
|
+
const sourceKey = (type, compatibilityDate) => `${type}@${compatibilityDate}`;
|
|
14
15
|
const registry = defineRegistry({
|
|
15
16
|
hostName: "shwfed-form",
|
|
16
17
|
dirSegment: "fields",
|
|
17
18
|
schemaModules,
|
|
18
19
|
configModules,
|
|
19
20
|
runtimeModules,
|
|
20
|
-
// An entry is deprecated
|
|
21
|
-
//
|
|
22
|
-
//
|
|
21
|
+
// An entry is deprecated by one of two rules:
|
|
22
|
+
// (a) another entry shares its `type` with a strictly greater
|
|
23
|
+
// `compatibilityDate` — date-versioned supersession;
|
|
24
|
+
// (b) another entry declares this one in its `migrateFrom` — explicit
|
|
25
|
+
// cross-type supersession (rename, split, merge).
|
|
26
|
+
// Rule (a) wins on overlap, since the date-versioned rule is the implicit
|
|
27
|
+
// convention; an explicit `migrateFrom` against a still-current entry is
|
|
28
|
+
// almost always a mistake, but we let it slide as long as no two targets
|
|
29
|
+
// claim the same source (that collision throws below).
|
|
23
30
|
deriveEntryExtras: (drafts) => {
|
|
24
31
|
const latestByType = /* @__PURE__ */ new Map();
|
|
25
32
|
for (const d of drafts) {
|
|
26
33
|
const prev = latestByType.get(d.type);
|
|
27
34
|
if (!prev || d.compatibilityDate > prev) latestByType.set(d.type, d.compatibilityDate);
|
|
28
35
|
}
|
|
36
|
+
const migrationTargets = /* @__PURE__ */ new Map();
|
|
37
|
+
for (const d of drafts) {
|
|
38
|
+
const sources = d.module.migrateFrom;
|
|
39
|
+
if (!sources || sources.length === 0) continue;
|
|
40
|
+
for (const src of sources) {
|
|
41
|
+
const key = sourceKey(src.type, src.compatibilityDate);
|
|
42
|
+
const existing = migrationTargets.get(key);
|
|
43
|
+
if (existing) {
|
|
44
|
+
throw new Error(
|
|
45
|
+
`[shwfed-form] migrateFrom collision: source "${key}" is claimed by both "${sourceKey(existing.type, existing.compatibilityDate)}" and "${sourceKey(d.type, d.compatibilityDate)}"`
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
migrationTargets.set(key, { type: d.type, compatibilityDate: d.compatibilityDate });
|
|
49
|
+
}
|
|
50
|
+
}
|
|
29
51
|
return (draft) => {
|
|
52
|
+
const declared = migrationTargets.get(sourceKey(draft.type, draft.compatibilityDate));
|
|
53
|
+
if (declared) {
|
|
54
|
+
return { deprecated: true, supersededBy: declared };
|
|
55
|
+
}
|
|
30
56
|
const latest = latestByType.get(draft.type);
|
|
31
|
-
|
|
32
|
-
|
|
57
|
+
if (draft.compatibilityDate < latest) {
|
|
58
|
+
return {
|
|
59
|
+
deprecated: true,
|
|
60
|
+
supersededBy: { type: draft.type, compatibilityDate: latest }
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
return { deprecated: false };
|
|
33
64
|
};
|
|
34
65
|
}
|
|
35
66
|
});
|
|
67
|
+
let _migrationTargets = null;
|
|
68
|
+
function getMigrationTargets() {
|
|
69
|
+
if (_migrationTargets) return _migrationTargets;
|
|
70
|
+
const map = /* @__PURE__ */ new Map();
|
|
71
|
+
for (const entry of registry.ENTRIES) {
|
|
72
|
+
const sources = entry.module.migrateFrom;
|
|
73
|
+
if (!sources || sources.length === 0) continue;
|
|
74
|
+
for (const src of sources) {
|
|
75
|
+
map.set(sourceKey(src.type, src.compatibilityDate), {
|
|
76
|
+
type: entry.type,
|
|
77
|
+
compatibilityDate: entry.compatibilityDate
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
_migrationTargets = map;
|
|
82
|
+
return map;
|
|
83
|
+
}
|
|
36
84
|
let _fields = null;
|
|
37
85
|
function getFields() {
|
|
38
86
|
if (_fields) return _fields;
|
|
@@ -46,6 +94,7 @@ function getFields() {
|
|
|
46
94
|
deprecated: e.deprecated,
|
|
47
95
|
...e.supersededBy !== void 0 ? { supersededBy: e.supersededBy } : {},
|
|
48
96
|
migrate: e.module.migrate,
|
|
97
|
+
...e.module.migrateFrom !== void 0 ? { migrateFrom: e.module.migrateFrom } : {},
|
|
49
98
|
defaults: e.module.defaults
|
|
50
99
|
}));
|
|
51
100
|
return _fields;
|
|
@@ -72,3 +121,8 @@ export function allFieldSchemas(configure) {
|
|
|
72
121
|
export function findField(type, compatibilityDate) {
|
|
73
122
|
return getFields().find((f) => f.type === type && f.compatibilityDate === compatibilityDate);
|
|
74
123
|
}
|
|
124
|
+
export function findMigrationTarget(type, compatibilityDate) {
|
|
125
|
+
const target = getMigrationTargets().get(sourceKey(type, compatibilityDate));
|
|
126
|
+
if (!target) return void 0;
|
|
127
|
+
return findField(target.type, target.compatibilityDate);
|
|
128
|
+
}
|
|
@@ -80,6 +80,7 @@ function renderRegisterables() {
|
|
|
80
80
|
lines.push("");
|
|
81
81
|
for (const entry of COLUMNS) {
|
|
82
82
|
if (entry.type === PROHIBITED_TYPE) continue;
|
|
83
|
+
if (entry.deprecated) continue;
|
|
83
84
|
const fields = describeColumnFields(entry.type);
|
|
84
85
|
lines.push(`## \`${entry.type}\` (compatibilityDate \`${entry.compatibilityDate}\`)`);
|
|
85
86
|
lines.push("");
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
type __VLS_ModelProps = {
|
|
2
|
+
modelValue: Record<string, any>;
|
|
3
|
+
};
|
|
4
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
5
|
+
"update:modelValue": (value: Record<string, any>) => any;
|
|
6
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_ModelProps> & Readonly<{
|
|
7
|
+
"onUpdate:modelValue"?: ((value: Record<string, any>) => any) | undefined;
|
|
8
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
9
|
+
declare const _default: typeof __VLS_export;
|
|
10
|
+
export default _default;
|
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { computed } from "vue";
|
|
3
|
+
import { Icon } from "@iconify/vue";
|
|
4
|
+
import { ExpressionEditor } from "../../../../ui/expression-editor";
|
|
5
|
+
import { Switch } from "../../../../ui/switch";
|
|
6
|
+
import { Separator } from "../../../../ui/separator";
|
|
7
|
+
import { Field, FieldLabel } from "../../../../ui/field";
|
|
8
|
+
import { Locale } from "../../../../ui/locale";
|
|
9
|
+
import {
|
|
10
|
+
InputGroup,
|
|
11
|
+
InputGroupAddon,
|
|
12
|
+
InputGroupButton,
|
|
13
|
+
InputGroupNumberField
|
|
14
|
+
} from "../../../../ui/input-group";
|
|
15
|
+
import {
|
|
16
|
+
DropdownMenu,
|
|
17
|
+
DropdownMenuContent,
|
|
18
|
+
DropdownMenuItem,
|
|
19
|
+
DropdownMenuTrigger
|
|
20
|
+
} from "../../../../ui/dropdown-menu";
|
|
21
|
+
import { getStructFieldDescription, getStructFieldTitle } from "../../../utils/schema-meta";
|
|
22
|
+
import { Markdown } from "../../../../ui/markdown";
|
|
23
|
+
import TriggersField from "../../../../actions/components/triggers-field.vue";
|
|
24
|
+
import { schema } from "./schema";
|
|
25
|
+
defineOptions({ name: "ShwfedTableSwitchRendererConfig" });
|
|
26
|
+
const value = defineModel({ type: Object, ...{ required: true } });
|
|
27
|
+
const fieldSchema = schema(() => {
|
|
28
|
+
});
|
|
29
|
+
const fieldTitle = (field) => getStructFieldTitle(fieldSchema, field) ?? field;
|
|
30
|
+
const fieldDescription = (field) => getStructFieldDescription(fieldSchema, field);
|
|
31
|
+
const ALIGN_OPTIONS = [
|
|
32
|
+
{ value: "left", label: "\u5DE6\u5BF9\u9F50", icon: "fluent:text-align-left-20-regular" },
|
|
33
|
+
{ value: "center", label: "\u5C45\u4E2D", icon: "fluent:text-align-center-20-regular" },
|
|
34
|
+
{ value: "right", label: "\u53F3\u5BF9\u9F50", icon: "fluent:text-align-right-20-regular" }
|
|
35
|
+
];
|
|
36
|
+
const currentAlignIcon = computed(
|
|
37
|
+
() => (ALIGN_OPTIONS.find((o) => o.value === (value.value.align ?? "center")) ?? ALIGN_OPTIONS[1]).icon
|
|
38
|
+
);
|
|
39
|
+
const ROW_VARS = {
|
|
40
|
+
row: { type: "dyn", label: "\u5F53\u524D\u884C\u6570\u636E" },
|
|
41
|
+
index: { type: "number", label: "\u884C\u7D22\u5F15" }
|
|
42
|
+
};
|
|
43
|
+
const ROW_VALUE_VARS = {
|
|
44
|
+
...ROW_VARS,
|
|
45
|
+
value: { type: "bool", label: "\u5207\u6362\u540E\u7684\u65B0\u503C" }
|
|
46
|
+
};
|
|
47
|
+
const JSON_VARS = {
|
|
48
|
+
json: { type: "dyn", label: "HTTP \u54CD\u5E94\u4F53" }
|
|
49
|
+
};
|
|
50
|
+
const disabledModel = computed({
|
|
51
|
+
get: () => value.value.disabled ?? "",
|
|
52
|
+
set: (v) => {
|
|
53
|
+
if (v === "") delete value.value.disabled;
|
|
54
|
+
else value.value.disabled = v;
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
const onChangeModel = computed({
|
|
58
|
+
get: () => value.value.onChange ?? "",
|
|
59
|
+
set: (v) => {
|
|
60
|
+
if (v === "") delete value.value.onChange;
|
|
61
|
+
else value.value.onChange = v;
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
const successMessageModel = computed({
|
|
65
|
+
get: () => value.value.successMessage ?? "",
|
|
66
|
+
set: (v) => {
|
|
67
|
+
if (v === "") delete value.value.successMessage;
|
|
68
|
+
else value.value.successMessage = v;
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
const triggers = computed(() => value.value.triggers ?? []);
|
|
72
|
+
function updateTriggers(next) {
|
|
73
|
+
if (next.length === 0) delete value.value.triggers;
|
|
74
|
+
else value.value.triggers = next;
|
|
75
|
+
}
|
|
76
|
+
</script>
|
|
77
|
+
|
|
78
|
+
<template>
|
|
79
|
+
<div class="space-y-5">
|
|
80
|
+
<div class="grid grid-cols-2 gap-x-6 gap-y-4">
|
|
81
|
+
<Field orientation="vertical">
|
|
82
|
+
<FieldLabel class="text-xs text-zinc-500">
|
|
83
|
+
<template
|
|
84
|
+
v-if="fieldDescription('title')"
|
|
85
|
+
#tooltip
|
|
86
|
+
>
|
|
87
|
+
<Markdown
|
|
88
|
+
:source="fieldDescription('title')"
|
|
89
|
+
block
|
|
90
|
+
class="prose prose-sm prose-zinc"
|
|
91
|
+
/>
|
|
92
|
+
</template>
|
|
93
|
+
{{ fieldTitle("title") }}
|
|
94
|
+
</FieldLabel>
|
|
95
|
+
<Locale v-model="value.title" />
|
|
96
|
+
</Field>
|
|
97
|
+
<Field orientation="vertical">
|
|
98
|
+
<FieldLabel class="text-xs text-zinc-500">
|
|
99
|
+
<template
|
|
100
|
+
v-if="fieldDescription('tooltip')"
|
|
101
|
+
#tooltip
|
|
102
|
+
>
|
|
103
|
+
<Markdown
|
|
104
|
+
:source="fieldDescription('tooltip')"
|
|
105
|
+
block
|
|
106
|
+
class="prose prose-sm prose-zinc"
|
|
107
|
+
/>
|
|
108
|
+
</template>
|
|
109
|
+
{{ fieldTitle("tooltip") }}
|
|
110
|
+
</FieldLabel>
|
|
111
|
+
<Locale
|
|
112
|
+
v-model="value.tooltip"
|
|
113
|
+
markdown
|
|
114
|
+
/>
|
|
115
|
+
</Field>
|
|
116
|
+
</div>
|
|
117
|
+
<div class="grid grid-cols-2 gap-x-6 gap-y-4">
|
|
118
|
+
<Field orientation="vertical">
|
|
119
|
+
<FieldLabel class="text-xs text-zinc-500">
|
|
120
|
+
<template
|
|
121
|
+
v-if="fieldDescription('accessor')"
|
|
122
|
+
#tooltip
|
|
123
|
+
>
|
|
124
|
+
<Markdown
|
|
125
|
+
:source="fieldDescription('accessor')"
|
|
126
|
+
block
|
|
127
|
+
class="prose prose-sm prose-zinc"
|
|
128
|
+
/>
|
|
129
|
+
</template>
|
|
130
|
+
{{ fieldTitle("accessor") }}
|
|
131
|
+
</FieldLabel>
|
|
132
|
+
<ExpressionEditor
|
|
133
|
+
v-model="value.accessor"
|
|
134
|
+
placeholder="如 row.enabled"
|
|
135
|
+
result-type="bool"
|
|
136
|
+
:extra-vars="ROW_VARS"
|
|
137
|
+
/>
|
|
138
|
+
</Field>
|
|
139
|
+
<Field orientation="vertical">
|
|
140
|
+
<FieldLabel class="text-xs text-zinc-500">
|
|
141
|
+
<template
|
|
142
|
+
v-if="fieldDescription('size')"
|
|
143
|
+
#tooltip
|
|
144
|
+
>
|
|
145
|
+
<Markdown
|
|
146
|
+
:source="fieldDescription('size')"
|
|
147
|
+
block
|
|
148
|
+
class="prose prose-sm prose-zinc"
|
|
149
|
+
/>
|
|
150
|
+
</template>
|
|
151
|
+
{{ fieldTitle("size") }}
|
|
152
|
+
</FieldLabel>
|
|
153
|
+
<InputGroup>
|
|
154
|
+
<InputGroupAddon align="inline-start">
|
|
155
|
+
<DropdownMenu>
|
|
156
|
+
<DropdownMenuTrigger as-child>
|
|
157
|
+
<InputGroupButton
|
|
158
|
+
variant="ghost"
|
|
159
|
+
size="xs"
|
|
160
|
+
:title="fieldTitle('align')"
|
|
161
|
+
>
|
|
162
|
+
<Icon :icon="currentAlignIcon" />
|
|
163
|
+
</InputGroupButton>
|
|
164
|
+
</DropdownMenuTrigger>
|
|
165
|
+
<DropdownMenuContent align="start">
|
|
166
|
+
<DropdownMenuItem
|
|
167
|
+
v-for="opt in ALIGN_OPTIONS"
|
|
168
|
+
:key="opt.value"
|
|
169
|
+
@select="value.align = opt.value"
|
|
170
|
+
>
|
|
171
|
+
<Icon :icon="opt.icon" />
|
|
172
|
+
{{ opt.label }}
|
|
173
|
+
</DropdownMenuItem>
|
|
174
|
+
</DropdownMenuContent>
|
|
175
|
+
</DropdownMenu>
|
|
176
|
+
</InputGroupAddon>
|
|
177
|
+
<InputGroupNumberField
|
|
178
|
+
:model-value="value.size"
|
|
179
|
+
:disabled="value.grow"
|
|
180
|
+
:min="0"
|
|
181
|
+
@update:model-value="(v) => value.size = v"
|
|
182
|
+
/>
|
|
183
|
+
<InputGroupAddon align="inline-end">
|
|
184
|
+
<InputGroupButton
|
|
185
|
+
:variant="value.grow ? 'primary' : 'ghost'"
|
|
186
|
+
size="xs"
|
|
187
|
+
@click="value.grow = !value.grow"
|
|
188
|
+
>
|
|
189
|
+
<Icon :icon="value.grow ? 'fluent:lock-closed-20-regular' : 'fluent:arrow-autofit-width-20-regular'" />
|
|
190
|
+
{{ fieldTitle("grow") }}
|
|
191
|
+
</InputGroupButton>
|
|
192
|
+
</InputGroupAddon>
|
|
193
|
+
</InputGroup>
|
|
194
|
+
</Field>
|
|
195
|
+
<Field orientation="vertical">
|
|
196
|
+
<FieldLabel class="text-xs text-zinc-500">
|
|
197
|
+
<template
|
|
198
|
+
v-if="fieldDescription('disabled')"
|
|
199
|
+
#tooltip
|
|
200
|
+
>
|
|
201
|
+
<Markdown
|
|
202
|
+
:source="fieldDescription('disabled')"
|
|
203
|
+
block
|
|
204
|
+
class="prose prose-sm prose-zinc"
|
|
205
|
+
/>
|
|
206
|
+
</template>
|
|
207
|
+
{{ fieldTitle("disabled") }}
|
|
208
|
+
</FieldLabel>
|
|
209
|
+
<ExpressionEditor
|
|
210
|
+
v-model="disabledModel"
|
|
211
|
+
placeholder="如 row.locked"
|
|
212
|
+
result-type="bool"
|
|
213
|
+
:extra-vars="ROW_VARS"
|
|
214
|
+
/>
|
|
215
|
+
</Field>
|
|
216
|
+
<Field orientation="vertical">
|
|
217
|
+
<FieldLabel class="text-xs text-zinc-500">
|
|
218
|
+
<template
|
|
219
|
+
v-if="fieldDescription('onChange')"
|
|
220
|
+
#tooltip
|
|
221
|
+
>
|
|
222
|
+
<Markdown
|
|
223
|
+
:source="fieldDescription('onChange')"
|
|
224
|
+
block
|
|
225
|
+
class="prose prose-sm prose-zinc"
|
|
226
|
+
/>
|
|
227
|
+
</template>
|
|
228
|
+
{{ fieldTitle("onChange") }}
|
|
229
|
+
</FieldLabel>
|
|
230
|
+
<ExpressionEditor
|
|
231
|
+
v-model="onChangeModel"
|
|
232
|
+
placeholder="如 http.post('/api/items/' + row.id).body({ enabled: value })"
|
|
233
|
+
result-type="HttpRequest"
|
|
234
|
+
:extra-vars="ROW_VALUE_VARS"
|
|
235
|
+
multiline
|
|
236
|
+
/>
|
|
237
|
+
</Field>
|
|
238
|
+
<Field orientation="vertical">
|
|
239
|
+
<FieldLabel class="text-xs text-zinc-500">
|
|
240
|
+
<template
|
|
241
|
+
v-if="fieldDescription('successMessage')"
|
|
242
|
+
#tooltip
|
|
243
|
+
>
|
|
244
|
+
<Markdown
|
|
245
|
+
:source="fieldDescription('successMessage')"
|
|
246
|
+
block
|
|
247
|
+
class="prose prose-sm prose-zinc"
|
|
248
|
+
/>
|
|
249
|
+
</template>
|
|
250
|
+
{{ fieldTitle("successMessage") }}
|
|
251
|
+
</FieldLabel>
|
|
252
|
+
<ExpressionEditor
|
|
253
|
+
v-model="successMessageModel"
|
|
254
|
+
placeholder="如 '已更新'"
|
|
255
|
+
result-type="string"
|
|
256
|
+
:extra-vars="JSON_VARS"
|
|
257
|
+
/>
|
|
258
|
+
</Field>
|
|
259
|
+
<Field orientation="vertical">
|
|
260
|
+
<FieldLabel class="text-xs text-zinc-500">
|
|
261
|
+
<template
|
|
262
|
+
v-if="fieldDescription('triggers')"
|
|
263
|
+
#tooltip
|
|
264
|
+
>
|
|
265
|
+
<Markdown
|
|
266
|
+
:source="fieldDescription('triggers')"
|
|
267
|
+
block
|
|
268
|
+
class="prose prose-sm prose-zinc"
|
|
269
|
+
/>
|
|
270
|
+
</template>
|
|
271
|
+
{{ fieldTitle("triggers") }}
|
|
272
|
+
</FieldLabel>
|
|
273
|
+
<TriggersField
|
|
274
|
+
:triggers="triggers"
|
|
275
|
+
@update:triggers="updateTriggers"
|
|
276
|
+
/>
|
|
277
|
+
</Field>
|
|
278
|
+
</div>
|
|
279
|
+
<Separator />
|
|
280
|
+
<div class="flex flex-wrap gap-x-8 gap-y-3">
|
|
281
|
+
<Field
|
|
282
|
+
orientation="horizontal"
|
|
283
|
+
class="w-auto gap-2"
|
|
284
|
+
>
|
|
285
|
+
<Switch
|
|
286
|
+
:model-value="value.enableSorting ?? false"
|
|
287
|
+
@update:model-value="(v) => value.enableSorting = v"
|
|
288
|
+
/>
|
|
289
|
+
<FieldLabel class="text-sm text-zinc-600">
|
|
290
|
+
<template
|
|
291
|
+
v-if="fieldDescription('enableSorting')"
|
|
292
|
+
#tooltip
|
|
293
|
+
>
|
|
294
|
+
<Markdown
|
|
295
|
+
:source="fieldDescription('enableSorting')"
|
|
296
|
+
block
|
|
297
|
+
class="prose prose-sm prose-zinc"
|
|
298
|
+
/>
|
|
299
|
+
</template>
|
|
300
|
+
{{ fieldTitle("enableSorting") }}
|
|
301
|
+
</FieldLabel>
|
|
302
|
+
</Field>
|
|
303
|
+
</div>
|
|
304
|
+
</div>
|
|
305
|
+
</template>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
type __VLS_ModelProps = {
|
|
2
|
+
modelValue: Record<string, any>;
|
|
3
|
+
};
|
|
4
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
5
|
+
"update:modelValue": (value: Record<string, any>) => any;
|
|
6
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_ModelProps> & Readonly<{
|
|
7
|
+
"onUpdate:modelValue"?: ((value: Record<string, any>) => any) | undefined;
|
|
8
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
9
|
+
declare const _default: typeof __VLS_export;
|
|
10
|
+
export default _default;
|