@shwfed/config 2.10.1 → 2.10.3

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.
Files changed (98) hide show
  1. package/dist/mcp.mjs +117 -87
  2. package/dist/module.json +1 -1
  3. package/dist/preview/assets/{FieldGroup.vue_vue_type_script_setup_true_lang-CuFusz5A.js → FieldGroup.vue_vue_type_script_setup_true_lang-sT5i_dnE.js} +1 -1
  4. package/dist/preview/assets/badge-ZFj45FMd.js +1 -0
  5. package/dist/preview/assets/config-2iinn_1E.js +1 -0
  6. package/dist/preview/assets/config-3rP_f_3o.js +1 -0
  7. package/dist/preview/assets/config-BBvebIQw.js +1 -0
  8. package/dist/preview/assets/{config-Djv6EQBY.js → config-BLesYihN.js} +1 -1
  9. package/dist/preview/assets/config-BwDPPmtn.js +1 -0
  10. package/dist/preview/assets/{config-BWC-Zw21.js → config-CEBzJOHo.js} +1 -1
  11. package/dist/preview/assets/config-CSR1JNVB.js +1 -0
  12. package/dist/preview/assets/config-CgM75jSO.js +1 -0
  13. package/dist/preview/assets/{config-urZuasV7.js → config-D1uMzMiN.js} +1 -1
  14. package/dist/preview/assets/config-DZPLqFqt.js +1 -0
  15. package/dist/preview/assets/config-DfVc2Iy9.js +1 -0
  16. package/dist/preview/assets/{config-BqSL4UAL.js → config-Rz0II9u6.js} +1 -1
  17. package/dist/preview/assets/{config-DVjZmomc.js → config-cD091sze.js} +1 -1
  18. package/dist/preview/assets/config-lskK7grq.js +1 -0
  19. package/dist/preview/assets/{definition.vue_vue_type_script_setup_true_lang-BzryfjdG.js → definition.vue_vue_type_script_setup_true_lang-Ce_NeQUa.js} +1 -1
  20. package/dist/preview/assets/index-Zc4Mcm3J.js +761 -0
  21. package/dist/preview/assets/index-_KA5_QIV.js +1 -0
  22. package/dist/preview/assets/{index-BnJ5p1Mx.css → index-pkoEF5dC.css} +1 -1
  23. package/dist/preview/assets/index-snO3CfdE.js +1 -0
  24. package/dist/preview/assets/item-CBFJ6f6b.js +1 -0
  25. package/dist/preview/assets/runtime-BIGEoc5L.js +1 -0
  26. package/dist/preview/assets/runtime-BKqyqEeD.js +1 -0
  27. package/dist/preview/assets/runtime-CIc3k_jd.js +1 -0
  28. package/dist/preview/assets/{runtime-CBBae0-H.js → runtime-Cu0RJn8g.js} +1 -1
  29. package/dist/preview/assets/{runtime-3rajYvjp.js → runtime-CvMryNNx.js} +1 -1
  30. package/dist/preview/assets/runtime-DO9HS0Rb.js +1 -0
  31. package/dist/preview/assets/{runtime-4A3oiig9.js → runtime-DQXLscBz.js} +1 -1
  32. package/dist/preview/assets/runtime-Q_isegB9.js +1 -0
  33. package/dist/preview/assets/runtime-enspc5HG.js +1 -0
  34. package/dist/preview/assets/runtime-jWibKv1T.js +1 -0
  35. package/dist/preview/assets/{schema-meta-BFzIzGiN.js → schema-meta-B5tln_XH.js} +1 -1
  36. package/dist/preview/index.html +2 -2
  37. package/dist/runtime/components/actions/buttons/2026-05-15/com.shwfed.actions.button.event.dispatch/schema.d.ts +16 -10
  38. package/dist/runtime/components/actions/buttons/2026-05-15/com.shwfed.actions.button.event.dispatch/schema.js +68 -43
  39. package/dist/runtime/components/actions/buttons/2026-05-21/com.shwfed.actions.button.http.download/schema.d.ts +1 -0
  40. package/dist/runtime/components/actions/buttons/2026-05-21/com.shwfed.actions.button.http.download/schema.js +5 -1
  41. package/dist/runtime/components/config/index.vue +5 -1
  42. package/dist/runtime/components/config/schema.d.ts +10 -0
  43. package/dist/runtime/components/config/schema.js +23 -0
  44. package/dist/runtime/components/operations/2026-06-15/com.shwfed.operation.http.download/config.d.vue.ts +31 -0
  45. package/dist/runtime/components/operations/2026-06-15/com.shwfed.operation.http.download/config.vue +103 -0
  46. package/dist/runtime/components/operations/2026-06-15/com.shwfed.operation.http.download/config.vue.d.ts +31 -0
  47. package/dist/runtime/components/operations/2026-06-15/com.shwfed.operation.http.download/runtime.d.ts +2 -0
  48. package/dist/runtime/components/operations/2026-06-15/com.shwfed.operation.http.download/runtime.js +63 -0
  49. package/dist/runtime/components/operations/2026-06-15/com.shwfed.operation.http.download/schema.d.ts +21 -0
  50. package/dist/runtime/components/operations/2026-06-15/com.shwfed.operation.http.download/schema.js +63 -0
  51. package/dist/runtime/components/operations/2026-06-15/com.shwfed.operation.navigation/config.d.vue.ts +17 -0
  52. package/dist/runtime/components/operations/2026-06-15/com.shwfed.operation.navigation/config.vue +85 -0
  53. package/dist/runtime/components/operations/2026-06-15/com.shwfed.operation.navigation/config.vue.d.ts +17 -0
  54. package/dist/runtime/components/operations/2026-06-15/com.shwfed.operation.navigation/runtime.d.ts +2 -0
  55. package/dist/runtime/components/operations/2026-06-15/com.shwfed.operation.navigation/runtime.js +36 -0
  56. package/dist/runtime/components/operations/2026-06-15/com.shwfed.operation.navigation/schema.d.ts +14 -0
  57. package/dist/runtime/components/operations/2026-06-15/com.shwfed.operation.navigation/schema.js +38 -0
  58. package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-remote/config.d.vue.ts +2 -2
  59. package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-remote/config.vue.d.ts +2 -2
  60. package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-static/config.d.vue.ts +2 -2
  61. package/dist/runtime/components/table/columns/2026-05-24/com.shwfed.table.column.combobox-single.remote.options-static/config.vue.d.ts +2 -2
  62. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-remote/config.d.vue.ts +2 -2
  63. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-remote/config.vue.d.ts +2 -2
  64. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-static/config.d.vue.ts +2 -2
  65. package/dist/runtime/components/table/columns/2026-05-25/com.shwfed.table.column.combobox-multi.remote.options-static/config.vue.d.ts +2 -2
  66. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi.remote/config.d.vue.ts +2 -2
  67. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-multi.remote/config.vue.d.ts +2 -2
  68. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single.remote/config.d.vue.ts +2 -2
  69. package/dist/runtime/components/table/columns/2026-05-26/com.shwfed.table.column.combobox-single.remote/config.vue.d.ts +2 -2
  70. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-multi/config.d.vue.ts +2 -2
  71. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-multi/config.vue.d.ts +2 -2
  72. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-single/config.d.vue.ts +2 -2
  73. package/dist/runtime/components/table/columns/2026-05-28/com.shwfed.table.column.combobox-single/config.vue.d.ts +2 -2
  74. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-multi/config.d.vue.ts +2 -2
  75. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-multi/config.vue.d.ts +2 -2
  76. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-single/config.d.vue.ts +2 -2
  77. package/dist/runtime/components/table/columns/2026-06-14/com.shwfed.table.column.combobox-single/config.vue.d.ts +2 -2
  78. package/dist/runtime/components/table/config.vue +74 -8
  79. package/package.json +1 -1
  80. package/dist/preview/assets/badge-D5FPHSix.js +0 -1
  81. package/dist/preview/assets/config-BHPiQ1lB.js +0 -1
  82. package/dist/preview/assets/config-Bg94Z7XN.js +0 -1
  83. package/dist/preview/assets/config-CeRBpZbE.js +0 -1
  84. package/dist/preview/assets/config-CfjcFb_E.js +0 -1
  85. package/dist/preview/assets/config-DNUKa3lN.js +0 -1
  86. package/dist/preview/assets/config-PNpa6ENz.js +0 -1
  87. package/dist/preview/assets/config-ucxtM3wX.js +0 -1
  88. package/dist/preview/assets/index-BE9O1XgB.js +0 -1
  89. package/dist/preview/assets/index-DCRQGu0g.js +0 -1
  90. package/dist/preview/assets/index-yvElpEK3.js +0 -743
  91. package/dist/preview/assets/item-CTkdtkvl.js +0 -1
  92. package/dist/preview/assets/runtime-BOGZFWxF.js +0 -1
  93. package/dist/preview/assets/runtime-BqroTX7H.js +0 -1
  94. package/dist/preview/assets/runtime-CBuV3vwL.js +0 -1
  95. package/dist/preview/assets/runtime-CI8yzwXd.js +0 -1
  96. package/dist/preview/assets/runtime-CcyhgOum.js +0 -1
  97. package/dist/preview/assets/runtime-CkQ-mNoH.js +0 -1
  98. package/dist/preview/assets/runtime-DmxKfudS.js +0 -1
@@ -0,0 +1 @@
1
+ import{be as e}from"./index-Zc4Mcm3J.js";import{bf as b,bg as r,bh as s}from"./index-Zc4Mcm3J.js";export{b as TableConfig,r as createTableConfig,e as default,s as getColumnTechnicalKey};
@@ -0,0 +1 @@
1
+ import{d as B,G as M,H as k,I as y,o as q,c as T,J as V,b as E,K as x,L as i,M as J,N as L,O as s,P,Q as U,R as W,S as z,T as A,U as G,V as g,W as H,X as b,Y as K}from"./index-Zc4Mcm3J.js";import Q from"./index-_KA5_QIV.js";const Y=B({name:"ShwfedBlockAnimatedNumberItem",__name:"item",props:{item:{}},setup(h){const n=h,j=H(),a=x(void 0),m=x(0);function u(){return G(j)}function S(e){if(typeof e=="number"&&Number.isFinite(e))return e;if(typeof e=="string"&&e.trim()!==""){const t=Number(e);return Number.isFinite(t)?t:0}return 0}const d=i(()=>a.value===void 0?g():K(a.value));function v(e){if(!e)return"";try{const t=b(s(e,{...u(),json:d.value}));return t==null?"":String(t)}catch{return""}}const w=i(()=>v(n.item.prefix)),I=i(()=>v(n.item.suffix));function N(e){if(e)try{const t=b(s(e,{...u(),json:d.value}));return t==null?void 0:typeof t=="string"||typeof t=="object"?t:String(t)}catch{return}}const _=i(()=>N(n.item.style));async function r(){const e=n.item.dataSource,t=u(),F=J(function*(){let o=g();e.request&&(o=yield*L(yield*s(e.request,t)));const O=yield*s(e.value,{...t,json:o});return{json:P(o),value:O}});try{const o=await U(W(F,z));a.value=o.json,m.value=S(o.value)}catch(o){console.warn("[shwfed-animated-number] fetch failed",o)}}const l=i(()=>(n.item.pollingInterval??0)>0),C=i(()=>Math.max(1,n.item.pollingInterval??1)*1e3),c=A(),{pause:p,resume:f}=M(()=>{r()},C,{immediate:!1});return k(()=>{r(),l.value&&c.value&&f()}),y(c,e=>{l.value&&(e?(r(),f()):p())}),y(()=>[n.item.dataSource.request??"",n.item.dataSource.value,n.item.pollingInterval??0].join("|"),()=>{r(),l.value&&c.value?f():p()}),(e,t)=>(q(),T(E(Q),{value:m.value,prefix:w.value,suffix:I.value,style:V(_.value)},null,8,["value","prefix","suffix","style"]))}});export{Y as default};
@@ -0,0 +1 @@
1
+ import{d as s,a6 as B,a_ as M,M as p,a9 as c,a$ as x,X as T,c as N,w as d,b as u,K as S,$ as k,aS as L,b0 as $,o as w,j as F,J as I,a as r,b1 as j,b2 as A,aF as H,W as K,b3 as f,a3 as m,b4 as V}from"./index-Zc4Mcm3J.js";import{_ as z}from"./definition.vue_vue_type_script_setup_true_lang-Ce_NeQUa.js";const Y=s({name:"ShwfedModalLayoutActionRuntime",__name:"runtime",props:{buttonId:{},config:{},buttonTitle:{}},setup(n){const a=n,{locale:l}=B(),v=e=>{},h=K(),i=k(f,void 0),g=L(),o=S(null),C=M(a.buttonId,{close:()=>$(()=>{o.value?.()})},g),_=s({name:"ModalBoundaryBridge",setup(e,{slots:t}){return A(h),m(V,C),i&&m(f,i),()=>t.default?.()}}),b=(e,t)=>H()?.(e,t),E=p(function*(){const e=c(a.config.modalTitle,l.value)??c(a.buttonTitle,l.value)??"",{modal:t,close:y}=yield*x({title:e,width:a.config.modalWidth});o.value=()=>T(y()),yield*t,o.value=null});return(e,t)=>(w(),N(z,{"action-id":n.buttonId,effect:u(E)},{default:d(()=>[F("div",{style:I(n.config.modalMinHeight?`min-height: ${n.config.modalMinHeight}`:void 0)},[r(u(_),null,{default:d(()=>[r(j,{"slot-value":n.config.slot,configure:v,"find-entry":b},null,8,["slot-value"])]),_:1})],4)]),_:1},8,["action-id","effect"]))}});export{Y as default};
@@ -0,0 +1 @@
1
+ import{d as l,b7 as g,aT as A,aW as y,aO as b,c as S,b as _,O as h,U as O,aS as j,b8 as k,W as C,o as B}from"./index-Zc4Mcm3J.js";import{_ as W}from"./definition.vue_vue_type_script_setup_true_lang-Ce_NeQUa.js";const F=l({name:"ShwfedStateWriteActionRuntime",__name:"runtime",props:{buttonId:{},config:{}},setup(s){const a=s,f=C(),c=(e,t)=>h(e,{...O(f),...t}),n=g(),o=n.kind==="form"&&n.parent?n.parent:n,u=j(),m=k((e,t,r)=>{if(Array.isArray(e[t])&&Array.isArray(r))return e[t]=r,!0});function i(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function p(e,t){return i(e)&&i(t)?m({...t},e):t}const d=A(()=>y(c(a.config.expression),e=>{for(const t of Object.keys(e)){const r=p(o.getAt(t),e[t]);o.setAt(t,r)}return b(u,a.config.onSuccess,c)}));return(e,t)=>(B(),S(W,{"action-id":s.buttonId,effect:_(d)},null,8,["action-id","effect"]))}});export{F as default};
@@ -0,0 +1 @@
1
+ import{d as f,a6 as u,aT as p,aU as d,aO as l,b9 as m,a9 as g,c as x,b as h,O as E,U as _,aS as b,o as B,W as k}from"./index-Zc4Mcm3J.js";import{_ as C}from"./definition.vue_vue_type_script_setup_true_lang-Ce_NeQUa.js";const w=f({name:"ShwfedHttpRequestBatchActionRuntime",__name:"runtime",props:{buttonId:{},config:{}},setup(n){const e=n,{locale:a}=u(),c=k(),s=(t,o)=>E(t,{..._(c),...o}),i=b(),r=p(()=>d(l(i,e.config.before,s),()=>m(e.config.expression,s,{messageExpression:e.config.messageExpression,resultExpression:e.config.resultExpression,continueOnError:e.config.continueOnError,markdown:g(e.config.markdown,a.value)??""})));return(t,o)=>(B(),x(C,{"action-id":n.buttonId,effect:h(r)},null,8,["action-id","effect"]))}});export{w as default};
@@ -1 +1 @@
1
- import{d as b,aR as E,C as _,aY as r,aM as m,b1 as S,b2 as j,c as v,b as x,E as B,K as C,aQ as L,M as R,o as k}from"./index-yvElpEK3.js";import{_ as T}from"./definition.vue_vue_type_script_setup_true_lang-BzryfjdG.js";const q=b({name:"ShwfedHttpDownloadActionRuntime",__name:"runtime",props:{buttonId:{},config:{}},setup(d){const c=d,g=R(),t=(e,n)=>B(e,{...C(g),...n}),l=L(),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=E(()=>_(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,t)}const a={json:yield*u.json()},i=o===void 0?"success":yield*S(t(o,a),s=>p.has(s)?s:"success");if(n!==void 0){const s=yield*t(n,a);yield*r(()=>j[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],t)}));return(e,n)=>(k(),v(T,{"action-id":d.buttonId,effect:x(y)},null,8,["action-id","effect"]))}});export{q as default};
1
+ import{d as h,aT as S,M as _,b0 as r,aO as m,b5 as E,b6 as j,c as v,b as x,O as B,U as L,aS as k,W as C,o as O}from"./index-Zc4Mcm3J.js";import{_ as R}from"./definition.vue_vue_type_script_setup_true_lang-Ce_NeQUa.js";const q=h({name:"ShwfedHttpDownloadActionRuntime",__name:"runtime",props:{buttonId:{},config:{}},setup(d){const c=d,g=C(),t=(e,n)=>B(e,{...L(g),...n}),l=k(),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=S(()=>_(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,t)}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(()=>j[i](s))}if(i==="success"||i==="info"){const b=yield*(yield*t(e.download,a)).file();yield*r(()=>f(b))}const w={success:c.config.onSuccess,warning:c.config.onWarning,error:c.config.onError,info:c.config.onInfo};return yield*m(l,w[i],t)}));return(e,n)=>(O(),v(R,{"action-id":d.buttonId,effect:x(y)},null,8,["action-id","effect"]))}});export{q as default};
@@ -1 +1 @@
1
- import{d as r,aR as f,aS as u,aM as g,aP as p,c as d,b as m,E as l,K as x,aQ as E,M as h,o as _}from"./index-yvElpEK3.js";import{_ as b}from"./definition.vue_vue_type_script_setup_true_lang-BzryfjdG.js";const B=r({name:"ShwfedHttpRequestActionRuntime",__name:"runtime",props:{buttonId:{},config:{}},setup(n){const e=n,i=h(),s=(t,c)=>l(t,{...x(i),...c}),o=E(),a=f(()=>u(g(o,e.config.before,s),()=>p(e.config.expression,s,{messageExpression:e.config.messageExpression,resultExpression:e.config.resultExpression,channel:o,triggers:{success:e.config.onSuccess,warning:e.config.onWarning,error:e.config.onError,info:e.config.onInfo}})));return(t,c)=>(_(),d(b,{"action-id":n.buttonId,effect:m(a)},null,8,["action-id","effect"]))}});export{B as default};
1
+ import{d as r,aT as f,aU as u,aO as g,aR as p,c as d,b as m,O as l,U as x,aS as h,W as E,o as _}from"./index-Zc4Mcm3J.js";import{_ as b}from"./definition.vue_vue_type_script_setup_true_lang-Ce_NeQUa.js";const B=r({name:"ShwfedHttpRequestActionRuntime",__name:"runtime",props:{buttonId:{},config:{}},setup(n){const e=n,i=E(),s=(t,c)=>l(t,{...x(i),...c}),o=h(),a=f(()=>u(g(o,e.config.before,s),()=>p(e.config.expression,s,{messageExpression:e.config.messageExpression,resultExpression:e.config.resultExpression,channel:o,triggers:{success:e.config.onSuccess,warning:e.config.onWarning,error:e.config.onError,info:e.config.onInfo}})));return(t,c)=>(_(),d(b,{"action-id":n.buttonId,effect:m(a)},null,8,["action-id","effect"]))}});export{B as default};
@@ -0,0 +1 @@
1
+ import{d as f,a6 as g,M as l,aO as u,a9 as d,aP as p,aQ as m,aR as x,c as E,b as _,O as h,U as w,aS as C,W as b,o as k}from"./index-Zc4Mcm3J.js";import{_ as I}from"./definition.vue_vue_type_script_setup_true_lang-Ce_NeQUa.js";const B=f({name:"ShwfedHttpRequestConfirmActionRuntime",__name:"runtime",props:{buttonId:{},config:{}},setup(c){const n=c,{locale:i}=g(),a=b(),s=(e,o)=>h(e,{...w(a),...o}),t=C(),r=l(function*(){yield*u(t,n.config.before,s);const e=d(n.config.markdown,i.value)??"",o=p(e,s);(yield*m({content:o,icon:n.config.icon,color:n.config.color}))||(yield*x(n.config.expression,s,{messageExpression:n.config.messageExpression,resultExpression:n.config.resultExpression,channel:t,triggers:{success:n.config.onSuccess,warning:n.config.onWarning,error:n.config.onError,info:n.config.onInfo}}))});return(e,o)=>(k(),E(I,{"action-id":c.buttonId,effect:_(r)},null,8,["action-id","effect"]))}});export{B as default};
@@ -1 +1 @@
1
- import{_ as o}from"./definition.vue_vue_type_script_setup_true_lang-BzryfjdG.js";import{d as n,c,b as a,o as f,aT as i}from"./index-yvElpEK3.js";const _=n({name:"ShwfedPrototypeActionRuntime",__name:"runtime",props:{buttonId:{},config:{}},setup(t){const e=i;return(r,s)=>(f(),c(o,{"action-id":t.buttonId,effect:a(e)},null,8,["action-id","effect"]))}});export{_ as default};
1
+ import{_ as o}from"./definition.vue_vue_type_script_setup_true_lang-Ce_NeQUa.js";import{d as n,c,b as a,o as f,aV as i}from"./index-Zc4Mcm3J.js";const _=n({name:"ShwfedPrototypeActionRuntime",__name:"runtime",props:{buttonId:{},config:{}},setup(t){const e=i;return(r,s)=>(f(),c(o,{"action-id":t.buttonId,effect:a(e)},null,8,["action-id","effect"]))}});export{_ as default};
@@ -0,0 +1 @@
1
+ import{d as u,a6 as i,c as l,b as p,L as m,o as d,h as f,a9 as _,aP as k,O as w,U as x,W as g}from"./index-Zc4Mcm3J.js";const B=u({name:"ShwfedMarkdownItemRuntime",__name:"runtime",props:{config:{}},setup(s){const o=s,{locale:a}=i(),t=g(),c=(e,n)=>w(e,{...x(t),...n}),r=m(()=>{const e=_(o.config.content,a.value)??"";return k(e,c)});return(e,n)=>(d(),l(p(f),{"data-slot":"buttons-markdown",source:r.value,class:"prose prose-sm prose-zinc px-1"},null,8,["source"]))}});export{B as default};
@@ -0,0 +1 @@
1
+ import{d as r,aT as f,aO as d,c as u,b as m,aS as p,o as l,O as g,U as h,W as _}from"./index-Zc4Mcm3J.js";import{_ as C}from"./definition.vue_vue_type_script_setup_true_lang-Ce_NeQUa.js";const B=r({name:"ShwfedEventDispatchActionRuntime",__name:"runtime",props:{buttonId:{},config:{}},setup(e){const c=e,s=_(),a=(n,t)=>g(n,{...h(s),...t}),o=p(),i=f(()=>d(o,c.config.triggers,a));return(n,t)=>(l(),u(C,{"action-id":e.buttonId,effect:m(i)},null,8,["action-id","effect"]))}});export{B as default};
@@ -0,0 +1 @@
1
+ import{d as f,aT as u,aW as d,aX as l,aY as m,c as p,b as w,aZ as _,O as g,U as h,W as b,o as x}from"./index-Zc4Mcm3J.js";import{_ as k}from"./definition.vue_vue_type_script_setup_true_lang-Ce_NeQUa.js";const C=f({name:"ShwfedNavigationActionRuntime",__name:"runtime",props:{buttonId:{},config:{}},setup(t){const o=t,a=_(),i=b(),c=(n,e)=>g(n,{...h(i),...e});function s(n){try{return new URL(n,window.location.href).origin!==window.location.origin}catch{return!1}}const r=u(()=>d(c(o.config.url),n=>l(async()=>{const e=s(n);if(o.config.mode==="_blank"){window.open(e?n:a.resolve(n).href,"_blank");return}await m(n)})));return(n,e)=>(x(),p(k,{"action-id":t.buttonId,effect:w(r)},null,8,["action-id","effect"]))}});export{C as default};
@@ -1 +1 @@
1
- import{p as o,q as l,r as p}from"./index-yvElpEK3.js";function i(n){switch(n._tag){case"TypeLiteral":return n;case"Transformation":return i(n.to);case"Refinement":return i(n.from);case"Suspend":return i(n.f());default:return null}}function d(n,t){const e=i(n.ast);return e?e.propertySignatures.find(r=>r.name===t)??null:null}function y(n){const t=n.type;if(t._tag==="Union"&&n.isOptional){const e=t.types.find(r=>r._tag!=="UndefinedKeyword");if(e)return e}return t}function c(n,t,e){const r=d(n,t);if(!r)return;const u=e(r);if(o(u))return u.value;const f=y(r),s=e(f);if(o(s))return s.value;if(f!==r.type){const a=e(r.type);if(o(a))return a.value}}function m(n,t){return c(n,t,l)}function v(n,t){return c(n,t,p)}export{v as a,m as g};
1
+ import{C as o,D as l,E as d}from"./index-Zc4Mcm3J.js";function i(n){switch(n._tag){case"TypeLiteral":return n;case"Transformation":return i(n.to);case"Refinement":return i(n.from);case"Suspend":return i(n.f());default:return null}}function p(n,t){const e=i(n.ast);return e?e.propertySignatures.find(r=>r.name===t)??null:null}function y(n){const t=n.type;if(t._tag==="Union"&&n.isOptional){const e=t.types.find(r=>r._tag!=="UndefinedKeyword");if(e)return e}return t}function c(n,t,e){const r=p(n,t);if(!r)return;const u=e(r);if(o(u))return u.value;const f=y(r),s=e(f);if(o(s))return s.value;if(f!==r.type){const a=e(r.type);if(o(a))return a.value}}function m(n,t){return c(n,t,l)}function v(n,t){return c(n,t,d)}export{v as a,m as g};
@@ -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-yvElpEK3.js"></script>
14
- <link rel="stylesheet" crossorigin href="./assets/index-BnJ5p1Mx.css">
13
+ <script type="module" crossorigin src="./assets/index-Zc4Mcm3J.js"></script>
14
+ <link rel="stylesheet" crossorigin href="./assets/index-pkoEF5dC.css">
15
15
  </head>
16
16
  <body>
17
17
  <div id="app"></div>
@@ -20,16 +20,22 @@ export declare function schema(_configure: (env: Environment) => void): Schema.S
20
20
  }>;
21
21
  export type Value = Schema.Schema.Type<ReturnType<typeof schema>>;
22
22
  /**
23
- * Adopts values stored under the standalone 「请求」 button
24
- * (`com.shwfed.actions.button.http.request.json@2026-04-18`). That button baked
25
- * the whole request lifecycle into itself fire a request, classify the
26
- * result, toast a message, then run one of four result-keyed trigger lists.
27
- * The page now exposes the request as an ambient 「发送请求」 *operation* that is
28
- * itself one step of a trigger chain, so the same behaviour is expressed as an
29
- * ordinary 「触发事件」 button whose trigger list is `before` + the request row +
30
- * the success arm, flattened in order. Migration declarations live exclusively
31
- * on this (replacement) entry; the request folder is kept so not-yet-migrated
32
- * configs keep loading, but it is never touched here.
23
+ * Adopts values from the standalone buttons whose whole behaviour the page now
24
+ * exposes as an ambient *operation* — each is rewritten into an ordinary
25
+ * 「触发事件」 button whose trigger list references that page op. Two sources, one
26
+ * per the established deprecate-standalone-button precedent:
27
+ *
28
+ * - 「请求」 (`com.shwfed.actions.button.http.request.json@2026-04-18`) baked
29
+ * the whole request lifecycle into itself fire, classify, toast, then run
30
+ * one of four result-keyed trigger lists. It maps to `before` + the request
31
+ * op row + the success arm, flattened in order (see `migrateRequest`).
32
+ * - 「导航」 (`com.shwfed.actions.button.navigation@2026-04-21`) opened a link.
33
+ * It maps to a single navigation op row carrying `{ url, mode }` (see
34
+ * `migrateNavigation`).
35
+ *
36
+ * Migration declarations live exclusively on this (replacement) entry; the
37
+ * source folders are kept so not-yet-migrated configs keep loading, but they
38
+ * are never touched here.
33
39
  */
34
40
  export declare const migrateFrom: ReadonlyArray<MigrateSource>;
35
41
  export declare const migrate: MigrateFn;
@@ -2,6 +2,7 @@ import { Effect, Schema } from "effect";
2
2
  import { Triggers } from "../../../../../share/event-bus.js";
3
3
  import { PAGE_TARGET_ID } from "../../../../../share/page-target.js";
4
4
  import * as httpRequestOp from "../../../../operations/2026-06-11/com.shwfed.operation.http.request.json/schema.js";
5
+ import * as navigationOp from "../../../../operations/2026-06-15/com.shwfed.operation.navigation/schema.js";
5
6
  export const type = "com.shwfed.actions.button.event.dispatch";
6
7
  export const compatibilityDate = "2026-05-15";
7
8
  export const metadata = {
@@ -21,56 +22,80 @@ export function schema(_configure) {
21
22
  });
22
23
  }
23
24
  export const migrateFrom = [
24
- { type: "com.shwfed.actions.button.http.request.json", compatibilityDate: "2026-04-18" }
25
+ { type: "com.shwfed.actions.button.http.request.json", compatibilityDate: "2026-04-18" },
26
+ { type: "com.shwfed.actions.button.navigation", compatibilityDate: "2026-04-21" }
25
27
  ];
28
+ function pageOpRow(operation, opCompatibilityDate, params) {
29
+ return {
30
+ id: crypto.randomUUID(),
31
+ target: PAGE_TARGET_ID,
32
+ operation,
33
+ compatibilityDate: opCompatibilityDate,
34
+ params
35
+ };
36
+ }
37
+ function migrateRequest(prev) {
38
+ const {
39
+ type: _t,
40
+ compatibilityDate: _c,
41
+ expression,
42
+ before,
43
+ messageExpression,
44
+ resultExpression,
45
+ onSuccess,
46
+ onWarning,
47
+ onError,
48
+ onInfo,
49
+ ...rest
50
+ } = prev;
51
+ const nonEmpty = (arm) => Array.isArray(arm) && arm.length > 0;
52
+ if (nonEmpty(onWarning) || nonEmpty(onError) || nonEmpty(onInfo)) {
53
+ throw new Error("\u8BE5\u300C\u8BF7\u6C42\u300D\u6309\u94AE\u914D\u7F6E\u4E86\u300C\u8B66\u544A\u300D\u300C\u9519\u8BEF\u300D\u6216\u300C\u4FE1\u606F\u300D\u5206\u652F\uFF0C\u65E0\u6CD5\u81EA\u52A8\u8FC1\u79FB\u4E3A\u89E6\u53D1\u94FE\uFF0C\u8BF7\u624B\u52A8\u6539\u5199");
54
+ }
55
+ const onCompleted = typeof messageExpression === "string" && messageExpression.length > 0 ? `(${messageExpression})` : "''";
56
+ const titleExpression = `json == null ? '\u8BF7\u6C42\u5931\u8D25' : ${onCompleted}`;
57
+ const params = {
58
+ expression: typeof expression === "string" ? expression : "",
59
+ titleExpression
60
+ };
61
+ if (typeof resultExpression === "string" && resultExpression.length > 0) {
62
+ params.resultExpression = resultExpression;
63
+ }
64
+ const requestRow = pageOpRow(httpRequestOp.type, httpRequestOp.compatibilityDate, params);
65
+ const beforeRows = Array.isArray(before) ? before : [];
66
+ const successRows = Array.isArray(onSuccess) ? onSuccess : [];
67
+ return {
68
+ ...rest,
69
+ type,
70
+ compatibilityDate,
71
+ triggers: [...beforeRows, requestRow, ...successRows]
72
+ };
73
+ }
74
+ function migrateNavigation(prev) {
75
+ const { type: _t, compatibilityDate: _c, url, mode, ...rest } = prev;
76
+ const params = { url, mode };
77
+ const row = pageOpRow(navigationOp.type, navigationOp.compatibilityDate, params);
78
+ return {
79
+ ...rest,
80
+ type,
81
+ compatibilityDate,
82
+ triggers: [row]
83
+ };
84
+ }
26
85
  export const migrate = (prev) => Effect.try({
27
86
  try: () => {
28
87
  if (!prev || typeof prev !== "object") {
29
88
  throw new Error("\u89E6\u53D1\u4E8B\u4EF6\u8FC1\u79FB\u5931\u8D25\uFF1A\u539F\u503C\u4E0D\u662F\u5BF9\u8C61");
30
89
  }
31
- const {
32
- type: _t,
33
- compatibilityDate: _c,
34
- expression,
35
- before,
36
- messageExpression,
37
- resultExpression,
38
- onSuccess,
39
- onWarning,
40
- onError,
41
- onInfo,
42
- ...rest
43
- } = prev;
44
- const nonEmpty = (arm) => Array.isArray(arm) && arm.length > 0;
45
- if (nonEmpty(onWarning) || nonEmpty(onError) || nonEmpty(onInfo)) {
46
- throw new Error("\u8BE5\u300C\u8BF7\u6C42\u300D\u6309\u94AE\u914D\u7F6E\u4E86\u300C\u8B66\u544A\u300D\u300C\u9519\u8BEF\u300D\u6216\u300C\u4FE1\u606F\u300D\u5206\u652F\uFF0C\u65E0\u6CD5\u81EA\u52A8\u8FC1\u79FB\u4E3A\u89E6\u53D1\u94FE\uFF0C\u8BF7\u624B\u52A8\u6539\u5199");
47
- }
48
- const onCompleted = typeof messageExpression === "string" && messageExpression.length > 0 ? `(${messageExpression})` : "''";
49
- const titleExpression = `json == null ? '\u8BF7\u6C42\u5931\u8D25' : ${onCompleted}`;
50
- const params = {
51
- expression: typeof expression === "string" ? expression : "",
52
- titleExpression
53
- };
54
- if (typeof resultExpression === "string" && resultExpression.length > 0) {
55
- params.resultExpression = resultExpression;
90
+ const record = prev;
91
+ switch (record.type) {
92
+ case "com.shwfed.actions.button.http.request.json":
93
+ return migrateRequest(record);
94
+ case "com.shwfed.actions.button.navigation":
95
+ return migrateNavigation(record);
96
+ default:
97
+ throw new Error(`\u89E6\u53D1\u4E8B\u4EF6\u8FC1\u79FB\u5931\u8D25\uFF1A\u65E0\u6CD5\u8BC6\u522B\u7684\u6765\u6E90\u7C7B\u578B ${String(record.type)}`);
56
98
  }
57
- const requestRow = {
58
- // The row id is the address later steps reference outputs under; mint a
59
- // stable one so it survives reorders (see the Trigger schema).
60
- id: crypto.randomUUID(),
61
- target: PAGE_TARGET_ID,
62
- operation: httpRequestOp.type,
63
- compatibilityDate: httpRequestOp.compatibilityDate,
64
- params
65
- };
66
- const beforeRows = Array.isArray(before) ? before : [];
67
- const successRows = Array.isArray(onSuccess) ? onSuccess : [];
68
- return {
69
- ...rest,
70
- type,
71
- compatibilityDate,
72
- triggers: [...beforeRows, requestRow, ...successRows]
73
- };
74
99
  },
75
100
  catch: (e) => e instanceof Error ? e : new Error(String(e))
76
101
  });
@@ -5,6 +5,7 @@ export declare const compatibilityDate: "2026-05-21";
5
5
  export declare const metadata: {
6
6
  readonly name: "下载文件";
7
7
  readonly icon: "fluent:arrow-download-20-regular";
8
+ readonly deprecated: "本按钮已废弃:改用「触发事件」按钮,其触发列表串联页面的「下载文件」操作;原两步式(先取凭据再下载)现为一个「发送请求」行后接一个引用 `steps[\"<步骤标识>\"]` 的「下载文件」行。";
8
9
  };
9
10
  export declare const JSON_VAR: {
10
11
  readonly type: "dyn";
@@ -6,7 +6,11 @@ export const type = "com.shwfed.actions.button.http.download";
6
6
  export const compatibilityDate = "2026-05-21";
7
7
  export const metadata = {
8
8
  name: "\u4E0B\u8F7D\u6587\u4EF6",
9
- icon: "fluent:arrow-download-20-regular"
9
+ icon: "fluent:arrow-download-20-regular",
10
+ // No structured migrate target — designers rebuild downloads by hand. Use a
11
+ // 触发事件 按钮,其触发列表串联页面的「下载文件」操作即可替代本按钮;原来的两步式
12
+ // (先取凭据再下载)现为一个「发送请求」行后接一个引用 `steps["<步骤标识>"]` 的「下载文件」行。
13
+ deprecated: '\u672C\u6309\u94AE\u5DF2\u5E9F\u5F03\uFF1A\u6539\u7528\u300C\u89E6\u53D1\u4E8B\u4EF6\u300D\u6309\u94AE\uFF0C\u5176\u89E6\u53D1\u5217\u8868\u4E32\u8054\u9875\u9762\u7684\u300C\u4E0B\u8F7D\u6587\u4EF6\u300D\u64CD\u4F5C\uFF1B\u539F\u4E24\u6B65\u5F0F\uFF08\u5148\u53D6\u51ED\u636E\u518D\u4E0B\u8F7D\uFF09\u73B0\u4E3A\u4E00\u4E2A\u300C\u53D1\u9001\u8BF7\u6C42\u300D\u884C\u540E\u63A5\u4E00\u4E2A\u5F15\u7528 `steps["<\u6B65\u9AA4\u6807\u8BC6>"]` \u7684\u300C\u4E0B\u8F7D\u6587\u4EF6\u300D\u884C\u3002'
10
14
  };
11
15
  export const JSON_VAR = {
12
16
  type: "dyn",
@@ -15,7 +15,9 @@ import EditorFooter from "./footer.vue";
15
15
  import { provideEventTarget } from "../../share/event-bus";
16
16
  import { operationHandlers } from "../operations/utils/resolve";
17
17
  import * as alertOperation from "../operations/2026-06-09/com.shwfed.operation.alert/schema";
18
+ import * as httpDownloadOperation from "../operations/2026-06-15/com.shwfed.operation.http.download/schema";
18
19
  import * as httpRequestOperation from "../operations/2026-06-11/com.shwfed.operation.http.request.json/schema";
20
+ import * as navigationOperation from "../operations/2026-06-15/com.shwfed.operation.navigation/schema";
19
21
  import { PAGE_TARGET_ID, createPageConfig } from "./schema";
20
22
  import { useConfigEditor } from "./use-editor";
21
23
  import { findBlock } from "./utils/resolve";
@@ -55,7 +57,9 @@ provideEventTarget(PAGE_TARGET_ID, {
55
57
  ...operationHandlers(
56
58
  [
57
59
  { type: alertOperation.type, compatibilityDate: alertOperation.compatibilityDate },
58
- { type: httpRequestOperation.type, compatibilityDate: httpRequestOperation.compatibilityDate }
60
+ { type: httpRequestOperation.type, compatibilityDate: httpRequestOperation.compatibilityDate },
61
+ { type: navigationOperation.type, compatibilityDate: navigationOperation.compatibilityDate },
62
+ { type: httpDownloadOperation.type, compatibilityDate: httpDownloadOperation.compatibilityDate }
59
63
  ],
60
64
  { cel: $cel, locale: () => locale.value }
61
65
  )
@@ -27,6 +27,16 @@ export declare const metadata: {
27
27
  readonly compatibilityDate: "2026-06-11";
28
28
  readonly name: "发送请求";
29
29
  readonly icon: "fluent:cloud-arrow-up-20-regular";
30
+ }, {
31
+ readonly id: "com.shwfed.operation.navigation";
32
+ readonly compatibilityDate: "2026-06-15";
33
+ readonly name: "导航";
34
+ readonly icon: "fluent:link-20-regular";
35
+ }, {
36
+ readonly id: "com.shwfed.operation.http.download";
37
+ readonly compatibilityDate: "2026-06-15";
38
+ readonly name: "下载文件";
39
+ readonly icon: "fluent:arrow-download-20-regular";
30
40
  }];
31
41
  };
32
42
  export declare function PageConfig(configure: (env: Environment) => void): Schema.Struct<{
@@ -2,7 +2,9 @@ import { Schema } from "effect";
2
2
  import { Expression, Slot, defaultSlot } from "../../share/layout.js";
3
3
  import { Locale } from "../../share/locale.js";
4
4
  import * as alertOperation from "../operations/2026-06-09/com.shwfed.operation.alert/schema.js";
5
+ import * as httpDownloadOperation from "../operations/2026-06-15/com.shwfed.operation.http.download/schema.js";
5
6
  import * as httpRequestOperation from "../operations/2026-06-11/com.shwfed.operation.http.request.json/schema.js";
7
+ import * as navigationOperation from "../operations/2026-06-15/com.shwfed.operation.navigation/schema.js";
6
8
  import { blockRef } from "./utils/resolve.js";
7
9
  export { getStructFieldDescription, getStructFieldTitle } from "../table/utils/schema-meta.js";
8
10
  const KIND = "shwfed.component.page";
@@ -29,6 +31,27 @@ export const metadata = {
29
31
  compatibilityDate: httpRequestOperation.compatibilityDate,
30
32
  name: httpRequestOperation.metadata.name,
31
33
  icon: httpRequestOperation.metadata.icon
34
+ },
35
+ // Navigation as an op (replaces the standalone navigation *button*): its URL
36
+ // expression can reference `steps["<id>"]`, so a chain can navigate using an
37
+ // earlier request's response. The page hosts it for the same reason as the
38
+ // request op — navigation acts on nothing instance-specific.
39
+ {
40
+ id: navigationOperation.type,
41
+ compatibilityDate: navigationOperation.compatibilityDate,
42
+ name: navigationOperation.metadata.name,
43
+ icon: navigationOperation.metadata.icon
44
+ },
45
+ // Download as an op (replaces the standalone download *button*): its request
46
+ // expression can reference `steps["<id>"]`, so the old two-step「先取凭据再下载」
47
+ // becomes a 发送请求 row followed by this download row. The page hosts it for
48
+ // the same reason as the request op — the download acts on nothing
49
+ // instance-specific.
50
+ {
51
+ id: httpDownloadOperation.type,
52
+ compatibilityDate: httpDownloadOperation.compatibilityDate,
53
+ name: httpDownloadOperation.metadata.name,
54
+ icon: httpDownloadOperation.metadata.icon
32
55
  }
33
56
  ]
34
57
  };
@@ -0,0 +1,31 @@
1
+ import { type Value } from './schema.js';
2
+ type __VLS_ModelProps = {
3
+ modelValue: Value;
4
+ };
5
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
6
+ "update:modelValue": (value: {
7
+ readonly description?: readonly [{
8
+ readonly locale: "zh";
9
+ readonly message: string;
10
+ }, ...{
11
+ readonly locale: "en" | "ja" | "ko";
12
+ readonly message: string;
13
+ }[]] | undefined;
14
+ readonly expression: string;
15
+ readonly titleExpression?: string | undefined;
16
+ }) => any;
17
+ }, string, import("vue").PublicProps, Readonly<__VLS_ModelProps> & Readonly<{
18
+ "onUpdate:modelValue"?: ((value: {
19
+ readonly description?: readonly [{
20
+ readonly locale: "zh";
21
+ readonly message: string;
22
+ }, ...{
23
+ readonly locale: "en" | "ja" | "ko";
24
+ readonly message: string;
25
+ }[]] | undefined;
26
+ readonly expression: string;
27
+ readonly titleExpression?: string | undefined;
28
+ }) => any) | undefined;
29
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
30
+ declare const _default: typeof __VLS_export;
31
+ export default _default;
@@ -0,0 +1,103 @@
1
+ <script setup>
2
+ import { ExpressionEditor } from "../../../ui/expression-editor";
3
+ import { Field, FieldGroup, FieldLabel } from "../../../ui/field";
4
+ import { Locale as LocaleField } from "../../../ui/locale";
5
+ import { Markdown } from "../../../ui/markdown";
6
+ import { getStructFieldDescription, getStructFieldTitle } from "../../../../share/schema-meta";
7
+ import { schema } from "./schema";
8
+ defineOptions({ name: "ShwfedHttpDownloadOperationConfig" });
9
+ const value = defineModel({ type: null, ...{ required: true } });
10
+ const opSchema = schema(() => {
11
+ });
12
+ const fieldTitle = (f) => getStructFieldTitle(opSchema, f) ?? f;
13
+ const fieldDescription = (f) => getStructFieldDescription(opSchema, f);
14
+ const OUTCOME_VARS = {
15
+ result: { type: "string", label: "\u6267\u884C\u7ED3\u679C" }
16
+ };
17
+ function patch(patchValue) {
18
+ const next = { ...value.value, ...patchValue };
19
+ for (const [k, v] of Object.entries(patchValue)) {
20
+ if (v === void 0) Reflect.deleteProperty(next, k);
21
+ }
22
+ value.value = next;
23
+ }
24
+ function patchOptionalExpression(key, v) {
25
+ patch({ [key]: v.length === 0 ? void 0 : v });
26
+ }
27
+ function patchDescription(v) {
28
+ const blank = v.every((entry) => entry.message.trim().length === 0);
29
+ patch({ description: blank ? void 0 : v });
30
+ }
31
+ </script>
32
+
33
+ <template>
34
+ <FieldGroup>
35
+ <Field orientation="vertical">
36
+ <FieldLabel class="text-xs text-zinc-500">
37
+ <template
38
+ v-if="fieldDescription('expression')"
39
+ #tooltip
40
+ >
41
+ <Markdown
42
+ :source="fieldDescription('expression')"
43
+ block
44
+ class="prose prose-sm prose-zinc"
45
+ />
46
+ </template>
47
+ {{ fieldTitle("expression") }}
48
+ </FieldLabel>
49
+ <ExpressionEditor
50
+ :model-value="value.expression"
51
+ multiline
52
+ placeholder="例:http.get('/api/export').body({ id: row.id })"
53
+ result-type="HttpRequest"
54
+ class="min-h-16"
55
+ @update:model-value="(v) => patch({ expression: v })"
56
+ />
57
+ </Field>
58
+
59
+ <Field orientation="vertical">
60
+ <FieldLabel class="text-xs text-zinc-500">
61
+ <template
62
+ v-if="fieldDescription('titleExpression')"
63
+ #tooltip
64
+ >
65
+ <Markdown
66
+ :source="fieldDescription('titleExpression')"
67
+ block
68
+ class="prose prose-sm prose-zinc"
69
+ />
70
+ </template>
71
+ {{ fieldTitle("titleExpression") }}
72
+ </FieldLabel>
73
+ <ExpressionEditor
74
+ :model-value="value.titleExpression ?? ''"
75
+ placeholder="例:result == 'error' ? '下载失败' : '下载成功'"
76
+ result-type="string"
77
+ :extra-vars="OUTCOME_VARS"
78
+ @update:model-value="(v) => patchOptionalExpression('titleExpression', v)"
79
+ />
80
+ </Field>
81
+
82
+ <Field orientation="vertical">
83
+ <FieldLabel class="text-xs text-zinc-500">
84
+ <template
85
+ v-if="fieldDescription('description')"
86
+ #tooltip
87
+ >
88
+ <Markdown
89
+ :source="fieldDescription('description')"
90
+ block
91
+ class="prose prose-sm prose-zinc"
92
+ />
93
+ </template>
94
+ {{ fieldTitle("description") }}
95
+ </FieldLabel>
96
+ <LocaleField
97
+ markdown
98
+ :model-value="value.description"
99
+ @update:model-value="(v) => patchDescription(v)"
100
+ />
101
+ </Field>
102
+ </FieldGroup>
103
+ </template>
@@ -0,0 +1,31 @@
1
+ import { type Value } from './schema.js';
2
+ type __VLS_ModelProps = {
3
+ modelValue: Value;
4
+ };
5
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
6
+ "update:modelValue": (value: {
7
+ readonly description?: readonly [{
8
+ readonly locale: "zh";
9
+ readonly message: string;
10
+ }, ...{
11
+ readonly locale: "en" | "ja" | "ko";
12
+ readonly message: string;
13
+ }[]] | undefined;
14
+ readonly expression: string;
15
+ readonly titleExpression?: string | undefined;
16
+ }) => any;
17
+ }, string, import("vue").PublicProps, Readonly<__VLS_ModelProps> & Readonly<{
18
+ "onUpdate:modelValue"?: ((value: {
19
+ readonly description?: readonly [{
20
+ readonly locale: "zh";
21
+ readonly message: string;
22
+ }, ...{
23
+ readonly locale: "en" | "ja" | "ko";
24
+ readonly message: string;
25
+ }[]] | undefined;
26
+ readonly expression: string;
27
+ readonly titleExpression?: string | undefined;
28
+ }) => any) | undefined;
29
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
30
+ declare const _default: typeof __VLS_export;
31
+ export default _default;
@@ -0,0 +1,2 @@
1
+ import type { OperationHandler } from '../../utils/resolve.js';
2
+ export declare const handler: OperationHandler;
@@ -0,0 +1,63 @@
1
+ import { Effect, Either, Option } from "effect";
2
+ import { Fetch } from "fx-fetch";
3
+ import { toast } from "vue-sonner";
4
+ import { asRequest } from "../../../../share/request.js";
5
+ import { getLocalizedText } from "../../../../share/locale.js";
6
+ import { interpolateMarkdown } from "../../../../share/interpolate.js";
7
+ class HttpRequestHalted {
8
+ constructor(reason) {
9
+ this.reason = reason;
10
+ }
11
+ _tag = "HttpRequestHalted";
12
+ }
13
+ function saveFile(file) {
14
+ const url = URL.createObjectURL(file);
15
+ const a = document.createElement("a");
16
+ a.href = url;
17
+ a.download = file.name;
18
+ document.body.appendChild(a);
19
+ a.click();
20
+ a.remove();
21
+ URL.revokeObjectURL(url);
22
+ }
23
+ export const handler = (params, ctx) => {
24
+ const { expression, titleExpression, description } = params ?? {};
25
+ if (!expression || expression.trim().length === 0) return Effect.void;
26
+ const program = Effect.gen(function* () {
27
+ const steps = ctx.step?.outputs() ?? {};
28
+ const evaluated = yield* ctx.cel(expression, { steps });
29
+ const request = asRequest(evaluated);
30
+ if (Option.isNone(request)) return;
31
+ const outcome = yield* Effect.either(request.value.file());
32
+ const result = Either.isLeft(outcome) ? "error" : "success";
33
+ if (titleExpression !== void 0) {
34
+ const title = yield* ctx.cel(titleExpression, { result, steps });
35
+ if (title.length > 0) {
36
+ const raw = getLocalizedText(description, ctx.locale()) ?? "";
37
+ const body = raw.length === 0 ? void 0 : interpolateMarkdown(raw, ctx.cel, { result, steps });
38
+ toast[result === "error" ? "error" : "success"](title, body === void 0 ? void 0 : { description: body });
39
+ }
40
+ }
41
+ if (Either.isLeft(outcome)) {
42
+ if (import.meta.dev) console.warn("[shwfed-operations] http download failed", outcome.left);
43
+ return yield* Effect.die(new HttpRequestHalted(outcome.left));
44
+ }
45
+ yield* Effect.sync(() => saveFile(outcome.right));
46
+ });
47
+ return program.pipe(
48
+ // The bus's handler contract has no requirements channel, so the host can't
49
+ // thread a Fetch layer through — the op provides its own, same layer the
50
+ // button runner uses.
51
+ Effect.provide(Fetch.layer),
52
+ // What remains on the error channel is CEL evaluation failure (request /
53
+ // title expression) — a config bug, not a runtime outcome. Mirror the
54
+ // request op: silent in prod, console in dev; the chain still halts so later
55
+ // operations don't fire off a broken step.
56
+ Effect.catchAll((error) => Effect.zipRight(
57
+ Effect.sync(() => {
58
+ if (import.meta.dev) console.warn("[shwfed-operations] http download op failed", error);
59
+ }),
60
+ Effect.die(new HttpRequestHalted(error))
61
+ ))
62
+ );
63
+ };
@@ -0,0 +1,21 @@
1
+ import { Schema } from 'effect';
2
+ import type { Environment } from '../../../../vendor/cel-js/lib/index.js';
3
+ export declare const type: "com.shwfed.operation.http.download";
4
+ export declare const compatibilityDate: "2026-06-15";
5
+ export declare const metadata: {
6
+ readonly name: "下载文件";
7
+ readonly icon: "fluent:arrow-download-20-regular";
8
+ };
9
+ export declare function schema(configure: (env: Environment) => void): Schema.Struct<{
10
+ expression: Schema.Schema<string, string, never>;
11
+ titleExpression: Schema.optional<Schema.Schema<string, string, never>>;
12
+ description: Schema.optional<Schema.TupleType<readonly [Schema.Struct<{
13
+ locale: Schema.Literal<["zh"]>;
14
+ message: Schema.SchemaClass<string, string, never>;
15
+ }>], [Schema.Struct<{
16
+ locale: Schema.Literal<["ja", "en", "ko"]>;
17
+ message: Schema.SchemaClass<string, string, never>;
18
+ }>]>>;
19
+ }>;
20
+ export type Value = Schema.Schema.Type<ReturnType<typeof schema>>;
21
+ export declare function defaults(): Partial<Value>;