weifuwu 0.93.2 → 0.94.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/dist/client/components/ActionSheet/ActionSheet.d.ts +1 -1
- package/dist/client/components/AlertGroup/AlertGroup.d.ts +1 -1
- package/dist/client/components/Anchor/Anchor.d.ts +1 -1
- package/dist/client/components/AppShell/AppShell.d.ts +20 -3
- package/dist/client/components/AuthPage/AuthPage.d.ts +1 -1
- package/dist/client/components/AutoComplete/AutoComplete.d.ts +1 -1
- package/dist/client/components/AvatarGroup/AvatarGroup.d.ts +1 -1
- package/dist/client/components/Button/Button.d.ts +8 -2
- package/dist/client/components/Chart/Chart.d.ts +1 -1
- package/dist/client/components/Chart/chart-utils.d.ts +1 -1
- package/dist/client/components/ChatInput/ChatInput.d.ts +3 -1
- package/dist/client/components/CodeBlock/CodeBlock.d.ts +1 -1
- package/dist/client/components/CodeBlock/highlight.d.ts +1 -1
- package/dist/client/components/Confirm/Confirm.d.ts +1 -1
- package/dist/client/components/CronPicker/CronPicker.d.ts +31 -0
- package/dist/client/components/DatePicker/DatePicker.d.ts +1 -1
- package/dist/client/components/DatePicker/calendar-utils.d.ts +1 -1
- package/dist/client/components/Descriptions/Descriptions.d.ts +1 -1
- package/dist/client/components/Drawer/Drawer.d.ts +4 -1
- package/dist/client/components/DropZone/DropZone.d.ts +1 -1
- package/dist/client/components/Dropdown/Dropdown.d.ts +1 -1
- package/dist/client/components/Editor/Editor.d.ts +1 -1
- package/dist/client/components/Editor/edit-events.d.ts +1 -1
- package/dist/client/components/Editor/model/apply.d.ts +1 -1
- package/dist/client/components/Editor/model/diff.d.ts +1 -1
- package/dist/client/components/Editor/model/dom.d.ts +1 -1
- package/dist/client/components/Editor/model/history.d.ts +1 -1
- package/dist/client/components/Editor/model/html.d.ts +1 -1
- package/dist/client/components/Editor/model/inverse.d.ts +1 -1
- package/dist/client/components/Editor/model/types.d.ts +1 -1
- package/dist/client/components/Editor/tools/table.d.ts +1 -1
- package/dist/client/components/Editor/tools/toolbar.d.ts +1 -1
- package/dist/client/components/Editor/tools/types.d.ts +1 -1
- package/dist/client/components/FilePreview/FilePreview.d.ts +1 -1
- package/dist/client/components/FilePreview/markdown.d.ts +1 -1
- package/dist/client/components/FileTree/FileTree.d.ts +1 -1
- package/dist/client/components/FileUpload/FileUpload.d.ts +1 -1
- package/dist/client/components/FloatButton/FloatButton.d.ts +1 -1
- package/dist/client/components/Grid/Grid.d.ts +1 -1
- package/dist/client/components/Highlight/Highlight.d.ts +1 -1
- package/dist/client/components/HoverCard/HoverCard.d.ts +1 -1
- package/dist/client/components/Icon/Icon.d.ts +1 -1
- package/dist/client/components/Img/Img.d.ts +1 -1
- package/dist/client/components/InView/InView.d.ts +1 -1
- package/dist/client/components/Input/Input.d.ts +6 -0
- package/dist/client/components/InputNumber/InputNumber.d.ts +1 -1
- package/dist/client/components/JSONViewer/JSONViewer.d.ts +1 -1
- package/dist/client/components/Layout/Layout.d.ts +1 -1
- package/dist/client/components/Link/Link.d.ts +1 -1
- package/dist/client/components/List/List.d.ts +1 -1
- package/dist/client/components/ListScaffold/ListScaffold.d.ts +40 -0
- package/dist/client/components/LogViewer/LogViewer.d.ts +1 -1
- package/dist/client/components/Markdown/Markdown.d.ts +1 -1
- package/dist/client/components/Markdown/parser.d.ts +1 -1
- package/dist/client/components/Menu/Menu.d.ts +3 -1
- package/dist/client/components/MessageBubble/MessageBubble.d.ts +1 -1
- package/dist/client/components/Modal/Modal.d.ts +5 -1
- package/dist/client/components/NavBar/NavBar.d.ts +1 -1
- package/dist/client/components/NavMenu/NavMenu.d.ts +1 -1
- package/dist/client/components/OfficeEditor/ai/ai-bridge.d.ts +1 -1
- package/dist/client/components/OfficeEditor/model/apply.d.ts +1 -1
- package/dist/client/components/OfficeEditor/model/types.d.ts +1 -1
- package/dist/client/components/PasswordInput/PasswordInput.d.ts +1 -1
- package/dist/client/components/Popconfirm/Popconfirm.d.ts +1 -1
- package/dist/client/components/Popover/Popover.d.ts +1 -1
- package/dist/client/components/PromptTemplate/PromptTemplate.d.ts +1 -1
- package/dist/client/components/RelationGraph/RelationGraph.d.ts +1 -1
- package/dist/client/components/Result/Result.d.ts +1 -1
- package/dist/client/components/Scrollbar/Scrollbar.d.ts +1 -1
- package/dist/client/components/SheetGrid/SheetGrid.d.ts +2 -2
- package/dist/client/components/Skeleton/Skeleton.d.ts +1 -1
- package/dist/client/components/SlideCanvas/SlideCanvas.d.ts +2 -2
- package/dist/client/components/Space/Space.d.ts +1 -1
- package/dist/client/components/StatusDot/StatusDot.d.ts +25 -0
- package/dist/client/components/TabBar/TabBar.d.ts +1 -1
- package/dist/client/components/TagsInput/TagsInput.d.ts +1 -1
- package/dist/client/components/Textarea/Textarea.d.ts +6 -0
- package/dist/client/components/ThemeSwitch/ThemeSwitch.d.ts +1 -1
- package/dist/client/components/Timeline/Timeline.d.ts +1 -1
- package/dist/client/components/Tooltip/Tooltip.d.ts +1 -1
- package/dist/client/components/VirtualTable/VirtualTable.d.ts +1 -1
- package/dist/client/components/WordCloud/WordCloud.d.ts +1 -1
- package/dist/client/components/index.d.ts +9 -3
- package/dist/client/components/index.js +36 -36
- package/dist/client/components/style.css +1 -1
- package/dist/client/layout/decl.d.ts +9 -0
- package/dist/client/layout/define.d.ts +41 -0
- package/dist/client/layout/index.d.ts +20 -0
- package/dist/client/layout/index.js +17 -0
- package/dist/client/layout/weifuwu-layout.css +1 -1
- package/dist/client/vdom/context/UIContext.d.ts +1 -1
- package/dist/client/vdom/core/create-component.d.ts +42 -0
- package/dist/client/vdom/core/create-item.d.ts +52 -0
- package/dist/client/vdom/core/vnode.d.ts +8 -2
- package/dist/client/vdom/hooks/env.d.ts +12 -0
- package/dist/client/vdom/hooks/field.d.ts +54 -0
- package/dist/client/vdom/hooks/overlay.d.ts +60 -0
- package/dist/client/vdom/hooks/signal.d.ts +25 -0
- package/dist/client/vdom/index.d.ts +9 -2
- package/dist/client/vdom/index.js +3 -3
- package/dist/client/vdom/jsx-runtime.d.ts +4 -4
- package/dist/client/vdom/jsx-runtime.js +1 -1
- package/dist/client/vdom/testing.js +2 -2
- package/dist/dev/index.js +7 -6
- package/dist/server/ai/index.js +7 -0
- package/dist/server/ai/types.d.ts +1 -1
- package/dist/server/email/index.js +1 -0
- package/dist/server/index.js +235 -5
- package/dist/server/messager/index.js +1 -0
- package/dist/server/postgres/index.js +56 -0
- package/dist/server/queue/index.js +1 -0
- package/dist/server/redis/index.js +3 -0
- package/dist/server/scheduler/index.js +1 -0
- package/dist/server/ui/index.d.ts +1 -1
- package/dist/server/ui/index.js +15 -0
- package/dist/server/user/index.js +1 -0
- package/dist/server/user/token.d.ts +1 -1
- package/dist/server/workflows/index.js +24 -0
- package/dist/shared/router/index.js +2 -0
- package/docs/client.md +143 -10
- package/docs/layout.md +14 -14
- package/docs/server.md +1 -1
- package/package.json +66 -12
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
var oe=class extends Error{issues;constructor(e){super(e.map(n=>`${n.path}: ${n.message}`).join("; ")),this.name="ZodError",this.issues=e}},_=class{_meta={};get metaInfo(){return this._meta}meta(e){return this._meta={...this._meta,...e},this}parse(e){let n=this._parse(e);if(!n.ok)throw new oe([{path:n.path??"",message:n.message??"invalid"}]);return n.value}safeParse(e){let n=this._parse(e);return n.ok?{success:!0,data:n.value}:{success:!1,error:new oe([{path:n.path??"",message:n.message??"invalid"}])}}optional(){return new xe(this)}nullable(){return new be(this)}default(e){return new Se(this,e)}refine(e,n){return new ve(this,e,n)}transform(e){return new $e(this,e)}},ie=class extends _{_typeName(){return"string"}_parse(e){if(typeof e!="string")return{ok:!1,path:"",message:"expected string"};let n=e;return this._min!==void 0&&n.length<this._min?{ok:!1,path:"",message:`too small (min ${this._min})`}:this._max!==void 0&&n.length>this._max?{ok:!1,path:"",message:`too big (max ${this._max})`}:this._pattern&&!this._pattern.test(n)?{ok:!1,path:"",message:"invalid pattern"}:this._email&&!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(n)?{ok:!1,path:"",message:"invalid email"}:this._uuid&&!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(n)?{ok:!1,path:"",message:"invalid uuid"}:{ok:!0,value:n}}_min;_max;_pattern;_email=!1;_uuid=!1;min(e){return this._min=e,this}max(e){return this._max=e,this}regex(e,n){return this._pattern=e,this}email(){return this._email=!0,this}uuid(){return this._uuid=!0,this}},ce=class extends _{_typeName(){return"number"}_parse(e){if(typeof e!="number"||Number.isNaN(e))return{ok:!1,path:"",message:"expected number"};let n=e;return this._int&&!Number.isInteger(n)?{ok:!1,path:"",message:"expected integer"}:this._min!==void 0&&n<this._min?{ok:!1,path:"",message:`too small (min ${this._min})`}:this._max!==void 0&&n>this._max?{ok:!1,path:"",message:`too big (max ${this._max})`}:{ok:!0,value:n}}_int=!1;_min;_max;int(){return this._int=!0,this}min(e){return this._min=e,this}max(e){return this._max=e,this}positive(){return this._min=0,this}},le=class extends _{_typeName(){return"boolean"}_parse(e){return typeof e!="boolean"?{ok:!1,path:"",message:"expected boolean"}:{ok:!0,value:e}}},ae=class extends _{lit;constructor(e){super(),this.lit=e}get value(){return this.lit}_typeName(){return"literal"}_parse(e){return e!==this.lit?{ok:!1,path:"",message:`expected literal ${JSON.stringify(this.lit)}`}:{ok:!0,value:e}}},ue=class extends _{raw;constructor(e){super(),this.raw=e}get values(){return this.raw}_typeName(){return"enum"}_parse(e){return typeof e!="string"||!this.raw.includes(e)?{ok:!1,path:"",message:`expected one of ${this.raw.join(" | ")}`}:{ok:!0,value:e}}},de=class extends _{_typeName(){return"datetime"}_parse(e){return typeof e!="string"||Number.isNaN(Date.parse(e))?{ok:!1,path:"",message:"expected datetime string (ISO)"}:{ok:!0,value:e}}},ge=class extends _{dims;constructor(e){super(),this.dims=e}_typeName(){return"vector"}_parse(e){return typeof e!="object"||e===null||!Array.isArray(e)||!e.every(n=>typeof n=="number")?{ok:!1,path:"",message:"expected number[] vector"}:this.dims>0&&e.length!==this.dims?{ok:!1,path:"",message:`expected vector(${this.dims})\u2014\u2014got ${e.length} dims`}:{ok:!0,value:e}}},he=class extends _{_typeName(){return"json"}_parse(e){return{ok:!0,value:e}}},me=class t extends _{shape;constructor(e){super(),this.shape=e}_typeName(){return"object"}_parse(e){if(typeof e!="object"||e===null||Array.isArray(e))return{ok:!1,path:"",message:"expected object"};let n={},r=[];for(let[s,o]of Object.entries(this.shape)){let i=o._parse(e[s]);if(!i.ok){r.push({path:s,message:i.message??""});continue}n[s]=i.value}return r.length?{ok:!1,path:r[0].path,message:r[0].message}:{ok:!0,value:n}}pick(e){let n={};for(let r of e)n[r]=this.shape[r];return new t(n)}omit(e){let n={};for(let[r,s]of Object.entries(this.shape))e.includes(r)||(n[r]=s);return new t(n)}extend(e){return new t({...this.shape,...e})}},we=class extends _{inner;constructor(e){super(),this.inner=e}get itemSchema(){return this.inner}_typeName(){return"array"}_parse(e){if(!Array.isArray(e))return{ok:!1,path:"",message:"expected array"};if(this._min!==void 0&&e.length<this._min)return{ok:!1,path:"",message:`too small (min ${this._min})`};if(this._max!==void 0&&e.length>this._max)return{ok:!1,path:"",message:`too big (max ${this._max})`};let n=[];for(let r=0;r<e.length;r++){let s=this.inner._parse(e[r]);if(!s.ok)return{ok:!1,path:`${r}`,message:s.message};n.push(s.value)}return{ok:!0,value:n}}_min;_max;min(e){return this._min=e,this}max(e){return this._max=e,this}},ke=class extends _{options;constructor(e){super(),this.options=e}_typeName(){return"union"}_parse(e){let n=null;for(let r of this.options){let s=r._parse(e);if(s.ok)return{ok:!0,value:s.value};n||(n={path:s.path??"",message:s.message??""})}return{ok:!1,path:"",message:`expected union (${n?.message})`}}},ye=class extends _{disc;options;discValueOf;constructor(e,n,r){super(),this.disc=e,this.options=n,this.discValueOf=r}_typeName(){return"disUnion"}_parse(e){if(typeof e!="object"||e===null)return{ok:!1,path:"",message:"expected object"};let n=e[this.disc];for(let r of this.options)if(this.discValueOf(r.shape)===n){let s=r._parse(e);return s.ok?{ok:!0,value:s.value}:{ok:!1,path:`(${String(n)})`,message:s.message??""}}return{ok:!1,path:this.disc,message:`invalid discriminator value ${JSON.stringify(n)}`}}};function lt(t,e){let n=t[e];if(n instanceof ae)return n.lit;if(n instanceof ue)return n.values;throw new Error(`z.discriminatedUnion: \u5224\u522B\u5B57\u6BB5\u9700\u4E3A literal/enum\u2014\u2014\u5F97\u5230 ${n?._typeName?.()}`)}var xe=class extends _{inner;constructor(e){super(),this.inner=e}_typeName(){return"optional"}_parse(e){return e===void 0?{ok:!0,value:void 0}:this.inner._parse(e)}},be=class extends _{inner;constructor(e){super(),this.inner=e}_typeName(){return"nullable"}_parse(e){return e===null?{ok:!0,value:null}:this.inner._parse(e)}},Se=class extends _{inner;d;constructor(e,n){super(),this.inner=e,this.d=n}_typeName(){return"default"}_parse(e){if(e===void 0){let n=typeof this.d=="function"?this.d():this.d;return this.inner._parse(n)}return this.inner._parse(e)}},ve=class extends _{inner;fn;msg;constructor(e,n,r){super(),this.inner=e,this.fn=n,this.msg=r}_typeName(){return"effects"}_parse(e){let n=this.inner._parse(e);return n.ok?this.fn(n.value)?{ok:!0,value:n.value}:{ok:!1,path:"",message:this.msg??"refine failed"}:{ok:!1,path:n.path??"",message:n.message??""}}},$e=class extends _{inner;fn;constructor(e,n){super(),this.inner=e,this.fn=n}_typeName(){return"transform"}_parse(e){let n=this.inner._parse(e);return n.ok?{ok:!0,value:this.fn(n.value)}:{ok:!1,path:n.path??"",message:n.message??""}}},b={string:()=>new ie,number:()=>new ce,boolean:()=>new le,literal:t=>new ae(t),enum:t=>new ue(t),date:()=>new de,uuid:()=>new ie().uuid(),json:()=>new he,vector:t=>new ge(t),object:t=>new me(t),array:t=>new we(t),union:t=>new ke(t),discriminatedUnion:(t,e)=>new ye(t,e,n=>lt(n,t))};function H(t,e){return t.meta(e)}var N={pk:t=>H(t,{pk:!0,default:"random"}),req:t=>H(t,{notNull:!0}),col:(t,e)=>H(t,{column:e}),now:t=>H(t,{default:"now"}),unique:t=>H(t,{unique:!0}),dflt:(t,e)=>H(t,{default:e})};var te=class extends Error{status;constructor(e,n){super(e),this.name="HttpError",this.status=n}};function O(t,e,n){if(e.length!==n)throw new Error(`std.${t}: \u671F\u671B ${n} \u4E2A\u53C2\u6570\uFF0C\u6536\u5230 ${e.length}`)}function U(t,e,n){let r=Number(e);if(!Number.isFinite(r))throw new Error(`std.${t}: \u53C2\u6570 ${n+1} \u4E0D\u662F\u6709\u9650\u6570\u5B57\uFF08${String(e)}\uFF09`);return r}var Ze={sum:t=>{O("sum",t,1);let e=t[0];if(!Array.isArray(e))throw new Error("std.sum: \u671F\u671B\u6570\u7EC4");return e.reduce((n,r)=>n+U("sum",r,0),0)},avg:t=>{O("avg",t,1);let e=t[0];if(!Array.isArray(e))throw new Error("std.avg: \u671F\u671B\u6570\u7EC4");if(e.length===0)throw new Error("std.avg: \u7A7A\u6570\u7EC4");return e.reduce((n,r)=>n+U("avg",r,0),0)/e.length},clamp:t=>{O("clamp",t,3);let e=U("clamp",t[0],0),n=U("clamp",t[1],1),r=U("clamp",t[2],2);if(n>r)throw new Error("std.clamp: lo > hi");return Math.min(r,Math.max(n,e))}},Ve={upper:t=>{if(O("upper",t,1),typeof t[0]!="string")throw new Error(`std.upper: \u671F\u671B\u5B57\u7B26\u4E32\uFF08${String(t[0])}\uFF09`);return t[0].toUpperCase()},lower:t=>{if(O("lower",t,1),typeof t[0]!="string")throw new Error(`std.lower: \u671F\u671B\u5B57\u7B26\u4E32\uFF08${String(t[0])}\uFF09`);return t[0].toLowerCase()},join:t=>{if(O("join",t,2),!Array.isArray(t[0])||typeof t[1]!="string")throw new Error("std.join: \u671F\u671B(\u6570\u7EC4, \u5206\u9694\u7B26)");return t[0].map(e=>String(e)).join(t[1])},split:t=>{if(O("split",t,2),typeof t[0]!="string"||typeof t[1]!="string")throw new Error("std.split: \u671F\u671B(\u5B57\u7B26\u4E32, \u5206\u9694\u7B26)");return t[0].split(t[1])}},Be={count:t=>{if(O("count",t,1),Array.isArray(t[0])||typeof t[0]=="string")return t[0].length;throw new Error(`std.count: \u671F\u671B\u6570\u7EC4\u6216\u5B57\u7B26\u4E32\uFF08${String(t[0])}\uFF09`)},pick:t=>{if(O("pick",t,2),!Array.isArray(t[0]))throw new Error("std.pick: \u671F\u671B\u6570\u7EC4");let e=U("pick",t[1],1);if(!Number.isInteger(e)||e<0||e>=t[0].length)throw new Error(`std.pick: \u7D22\u5F15 ${e} \u8D8A\u754C\uFF08\u957F\u5EA6 ${t[0].length}\uFF09`);return t[0][e]}},_e={"wf://std/math":Ze,"wf://std/strings":Ve,"wf://std/collections":Be},Ee={...Ze,...Ve,...Be},Ke=Object.keys(Ee);var dt=/[A-Za-z_$][A-Za-z0-9_$]*/,gt=/[0-9]+(?:\.[0-9]+)?/,ht=["===","!=="],mt=["==","!=","&&","||","<=",">="],wt=["!","+","-","*","/","%","<",">","?"];function kt(t){let e=[],n=0,r=t.length;for(;n<r;){let s=t[n];if(s===" "||s===" "||s===`
|
|
2
|
+
`||s==="\r"){n++;continue}if(s==='"'||s==="'"){let u=s,p=n+1,f="";for(;p<r&&t[p]!==u;){if(t[p]==="\\"){let c=t[p+1];if(c==="\\"||c===u){f+=c,p+=2;continue}if(c==="n"){f+=`
|
|
3
|
+
`,p+=2;continue}if(c==="t"){f+=" ",p+=2;continue}throw new Error(`expression: invalid escape '\\${c??""}' at ${p} (in ${JSON.stringify(t)})`)}f+=t[p],p++}if(p>=r)throw new Error(`expression: unterminated string (in ${JSON.stringify(t)})`);e.push({t:"str",v:f,pos:n}),n=p+1;continue}let o=t.slice(n,n+3);if(ht.includes(o)){e.push({t:"op",v:o,pos:n}),n+=3;continue}let i=t.slice(n,n+2);if(mt.includes(i)){e.push({t:"op",v:i,pos:n}),n+=2;continue}if(wt.includes(s)){e.push({t:"op",v:s,pos:n}),n++;continue}if(s==="."||s==="["||s==="]"||s==="("||s===")"||s===","||s===":"){e.push({t:"punc",v:s,pos:n}),n++;continue}if(s>="0"&&s<="9"){let u=gt.exec(t.slice(n));if(!u)throw new Error(`expression: invalid number at ${n} (in ${JSON.stringify(t)})`);e.push({t:"num",v:Number(u[0]),pos:n}),n+=u[0].length;continue}let a=dt.exec(t.slice(n));if(a){e.push({t:"ident",v:a[0],pos:n}),n+=a[0].length;continue}throw new Error(`expression: unexpected character '${s}' at ${n} (in ${JSON.stringify(t)})`)}return e.push({t:"eof",pos:r}),e}var Re=class{i=0;tokens;src;depth=0;constructor(e,n){this.tokens=e,this.src=n}peek(){return this.tokens[this.i]}next(){return this.tokens[this.i++]}fail(e,n){throw new Error(`${e} at ${n} (in ${JSON.stringify(this.src)})`)}expectPunc(e){let n=this.next();(n.t!=="punc"||n.v!==e)&&this.fail(`expression: expected '${e}'`,n.pos)}parse(){let e=this.parseTernary(),n=this.peek();return n.t!=="eof"&&this.fail(`expression: unexpected '${String(n.v)}'`,n.pos),e}parseTernary(){++this.depth>65&&this.fail("expression: nested expression too deep (max 64 \u5C42)",this.peek().pos);try{return this.parseTernaryInner()}finally{this.depth--}}parseTernaryInner(){let e=this.parseOr(),n=this.peek();if(n.t==="op"&&n.v==="?"){this.next();let r=this.parseTernary(),s=this.next();(s.t!=="punc"||s.v!==":")&&this.fail("expression: expected ':' in ternary",s.pos);let o=this.parseTernary();return{kind:"ternary",cond:e,then:r,else:o}}return e}parseOr(){let e=this.parseAnd();for(;this.isOp("||");)this.next(),e={kind:"or",left:e,right:this.parseAnd()};return e}parseAnd(){let e=this.parseCmp();for(;this.isOp("&&");)this.next(),e={kind:"and",left:e,right:this.parseCmp()};return e}parseCmp(){let e=this.parseArith(),n=this.peek();return n.t==="op"&&["==","!=","===","!==","<","<=",">",">="].includes(n.v)?(this.next(),{kind:"compare",op:n.v,left:e,right:this.parseArith()}):e}parseArith(){let e=this.parseTerm();for(;this.isOp("+")||this.isOp("-");)e={kind:"arith",op:this.next().v,left:e,right:this.parseTerm()};return e}parseTerm(){let e=this.parseUnary();for(;this.isOp("*")||this.isOp("/")||this.isOp("%");)e={kind:"arith",op:this.next().v,left:e,right:this.parseUnary()};return e}isOp(e){let n=this.peek();return n.t==="op"&&n.v===e}parseUnary(){let e=this.peek();return e.t==="op"&&e.v==="!"?(this.next(),{kind:"not",operand:this.parseUnary()}):e.t==="op"&&e.v==="-"?(this.next(),{kind:"neg",operand:this.parseUnary()}):this.parseAtom()}parseAtom(){let e=this.peek();if(e.t==="punc"&&e.v==="("){this.next();let n=this.parseTernary();return this.expectPunc(")"),n}if(e.t==="num")return this.next(),{kind:"literal",value:e.v};if(e.t==="str")return this.next(),{kind:"literal",value:e.v};if(e.t==="ident"){let n=e.v;if(n==="null"||n==="true"||n==="false")return this.next(),{kind:"literal",value:n==="null"?null:n==="true"};let r=this.parsePath(),s=this.peek();if(r.kind==="path"&&s.t==="punc"&&s.v==="("){this.next();let o=[];if(!this.isPunc2(")"))for(;;){if(o.push(this.parseTernary()),this.isPunc2(",")){this.next();continue}break}return this.expectPunc(")"),{kind:"call",name:r.segments[0],args:o}}return r}this.fail(`expression: unexpected '${e.t==="eof"?"(end)":String(e.v)}'`,e.pos)}isPunc2(e){let n=this.peek();return n.t==="punc"&&n.v===e}parsePath(){let e=[],n=this.next();for(n.t!=="ident"&&this.fail("expression: expected path",n.pos),e.push(n.v);;){let r=this.peek();if(r.t==="punc"&&r.v==="."){this.next();let s=this.next();s.t!=="ident"&&this.fail("expression: expected property after '.'",s.pos),e.push(s.v);continue}if(r.t==="punc"&&r.v==="["){this.next();let s=this.next();if(s.t==="op"&&s.v==="*"){this.expectPunc("]"),e.push("*");continue}(s.t!=="num"||!Number.isInteger(s.v))&&this.fail("expression: expected integer index or '*' in '[]'",s.pos),this.expectPunc("]"),e.push(s.v);continue}break}return{kind:"path",segments:e}}};function I(t){return new Re(kt(t),t).parse()}function yt(t,e){function n(r,s){let o=e[s];if(o===void 0)return r;if(r==null)return;if(o==="*"){if(!Array.isArray(r))return[];let a=[];for(let u of r){let p=n(u,s+1);Array.isArray(p)?a.push(...p):p!==void 0&&a.push(p)}return a}let i;return typeof o=="number"?i=Array.isArray(r)?r[o]:void 0:o==="length"&&(Array.isArray(r)||typeof r=="string")?i=r.length:typeof r=="object"?i=r[o]:i=void 0,n(i,s+1)}return n(t,0)}function xt(t,e,n){if(typeof e!="number"||typeof n!="number")throw new Error(`expression: arithmetic '${t}' requires numbers (got ${je(e)} ${t} ${je(n)})`);let r;switch(t){case"+":r=e+n;break;case"-":r=e-n;break;case"*":r=e*n;break;case"/":r=e/n;break;case"%":r=e%n;break}if(!Number.isFinite(r))throw new Error(`expression: arithmetic '${t}' produced non-finite result`);return r}function je(t){return t===null?"null":Array.isArray(t)?"array":typeof t}function W(t,e,n){switch(t.kind){case"path":return yt(e,t.segments);case"literal":return t.value;case"neg":{let r=W(t.operand,e,n);if(typeof r!="number")throw new Error(`expression: unary '-' requires number (got ${je(r)})`);return-r}case"arith":return xt(t.op,W(t.left,e,n),W(t.right,e,n));case"ternary":return Je(t.cond,e,n)?W(t.then,e,n):W(t.else,e,n);case"call":{if(!n?.[t.name])throw new Error(`expression: \u672A\u6CE8\u518C\u51FD\u6570 '${t.name}'\uFF08std \u7EAF\u51FD\u6570\uFF1A${Ke.join("/")}\uFF09`);return n[t.name](t.args.map(r=>W(r,e,n)))}case"compare":{let r=W(t.left,e,n),s=W(t.right,e,n);switch(t.op){case"==":return r==s;case"!=":return r!=s;case"===":return r===s;case"!==":return r!==s;case"<":return r<s;case"<=":return r<=s;case">":return r>s;case">=":return r>=s}}case"not":return!M(W(t.operand,e,n));case"and":{let r=W(t.left,e,n);return M(r)?W(t.right,e,n):r}case"or":{let r=W(t.left,e,n);return M(r)?r:W(t.right,e,n)}}}function M(t){return!!t}function Je(t,e,n){return M(W(t,e,n))}function z(t,e){let n=I(t);return r=>W(n,r,e)}function bt(t){return t==null?"":typeof t=="string"?t:typeof t=="object"?JSON.stringify(t):String(t)}function C(t,e,n){if(!t.includes("{{"))return t;let r="",s=0;for(;;){let o=t.indexOf("{{",s);if(o===-1){r+=t.slice(s);break}let i=t.indexOf("}}",o+2);if(i===-1)throw new Error(`workflow/expression: interpolate: unclosed '{{' at ${o} (in ${JSON.stringify(t)})`);let a=t.slice(o+2,i).trim();if(!a)throw new Error(`workflow/expression: interpolate: empty expression (in ${JSON.stringify(t)})`);r+=t.slice(s,o),r+=bt(W(I(a),e,n)),s=i+2}return r}function E(t){switch(t.kind){case"path":return t.segments.reduce((e,n)=>e+(typeof n=="number"?`[${n}]`:n==="*"?"[*]":e===""?n:`.${n}`),"");case"literal":return t.value===null?"null":typeof t.value=="string"?`'${t.value.replace(/\\/g,"\\\\").replace(/'/g,"\\'")}'`:String(t.value);case"ternary":return`(${E(t.cond)} ? ${E(t.then)} : ${E(t.else)})`;case"call":return`${t.name}(${t.args.map(e=>E(e)).join(", ")})`;case"neg":return`-${E(t.operand)}`;case"arith":return`(${E(t.left)} ${t.op} ${E(t.right)})`;case"compare":return`(${E(t.left)} ${t.op} ${E(t.right)})`;case"not":return`!${E(t.operand)}`;case"and":return`(${E(t.left)} && ${E(t.right)})`;case"or":return`(${E(t.left)} || ${E(t.right)})`}}var St={type:"http",label:"HTTP \u8BF7\u6C42",fields:[{name:"url",label:"URL",type:"string"},{name:"method",label:"\u65B9\u6CD5",type:"string"}],required:["url"],async run(t,e,n){let r=String(t.url),s=$t(t.method),o=typeof t.timeoutMs=="number"&&t.timeoutMs>0?t.timeoutMs:1e4,i=n.fetch??globalThis.fetch;if(!i)throw new Error("http step: no fetch available");let a=t.headers??{},u=typeof t.body=="string"?t.body:void 0,p=await i(r,{method:s,headers:a,body:u,signal:AbortSignal.timeout(o)}),f=typeof t.maxBytes=="number"&&t.maxBytes>0?t.maxBytes:10*1024*1024,c=Number(p.headers.get("content-length")??0);if(c>f)throw new Error(`http step: \u54CD\u5E94 ${c} \u5B57\u8282\u8D85\u8FC7\u4E0A\u9650 ${f}`);let g;if(p.body){let R=p.body.getReader(),S=[],l=0;for(;;){let{done:w,value:d}=await R.read();if(w)break;if(l+=d.length,l>f)throw await R.cancel(),new Error(`http step: \u54CD\u5E94\u8D85\u8FC7\u4E0A\u9650 ${f} \u5B57\u8282\uFF08\u53EF\u7ECF config.maxBytes \u8C03\u6574\uFF09`);S.push(d)}g=new TextDecoder().decode(vt(S))}else g=await p.text();let $={status:p.status,text:g};try{$.json=JSON.parse(g)}catch{}return $}};function vt(t){let e=t.reduce((s,o)=>s+o.length,0),n=new Uint8Array(e),r=0;for(let s of t)n.set(s,r),r+=s.length;return n}function $t(t){let e=String(t??"GET").toUpperCase();return["GET","POST","PUT","PATCH","DELETE","HEAD"].includes(e)?e:"GET"}var _t={type:"template",label:"\u6570\u636E\u6A21\u677F",fields:[{name:"template",label:"\u6A21\u677F",type:"string"}],required:["template"],run(t,e){return{text:C(String(t.template),e)}}},Et={type:"log",label:"\u65E5\u5FD7",fields:[{name:"message",label:"\u6D88\u606F",type:"string"}],required:[],run(t,e,n){let r=C(String(t.message??""),e);return n.log?.(r),{text:r}}},Rt={type:"ai",label:"AI \u751F\u6210",fields:[{name:"prompt",label:"\u63D0\u793A\u8BCD\uFF08\u652F\u6301 {{}} \u63D2\u503C\uFF09",type:"string"},{name:"system",label:"\u7CFB\u7EDF\u6307\u4EE4",type:"string"}],required:["prompt"],effects:!0,async run(t,e,n){if(!n.ai?.chat)throw new Error("ai step: \u672A\u6CE8\u5165 ai \u9002\u914D\u5668\uFF08workflow({ ai })\uFF09");let r=t.system?C(String(t.system),e):void 0,s=C(String(t.prompt),e);return{text:(await n.ai.chat({messages:[...r?[{role:"system",content:r}]:[],{role:"user",content:s}]})).content}}},jt={type:"email",label:"\u53D1\u9001\u90AE\u4EF6",fields:[{name:"to",label:"\u6536\u4EF6\u4EBA",type:"string"},{name:"subject",label:"\u4E3B\u9898\uFF08\u652F\u6301 {{}} \u63D2\u503C\uFF09",type:"string"},{name:"body",label:"\u6B63\u6587\uFF08\u652F\u6301 {{}} \u63D2\u503C\uFF09",type:"string"}],required:["to"],effects:!0,async run(t,e,n){if(!n.email?.send)throw new Error("email step: \u672A\u6CE8\u5165 email \u9002\u914D\u5668\uFF08workflow({ email })\uFF09");let r=C(String(t.to),e),s=t.subject?C(String(t.subject),e):"workflow \u901A\u77E5",o=t.body?C(String(t.body),e):"",i=await n.email.send({to:r.split(",").map(a=>a.trim()).filter(Boolean),subject:s,body:o});if(!i.ok)throw new Error(`email step: \u53D1\u9001\u5931\u8D25${i.id?` (${i.id})`:""}`);return{id:i.id}}},Wt={type:"store",label:"KV \u5B58\u50A8",fields:[{name:"op",label:"\u64CD\u4F5C\uFF08get/set\uFF09",type:"string"},{name:"key",label:"\u952E",type:"string"},{name:"value",label:"\u503C\uFF08set \u65F6\uFF09",type:"string"}],required:["op","key"],run:async(t,e,n)=>{let r=n.store;if(!r)throw new Error("store \u6B65\u9AA4\u9700\u8981\u5B58\u50A8\u6CE8\u5165\uFF1Aworkflow({ store }) \u6216 workflow({ redis })");let s=String(t.op),o=C(String(t.key),e);if(s==="get")return await r.get(o);if(s==="set"){let i=C(String(t.value??""),e);return await r.set(o,i),i}throw new Error(`store \u672A\u77E5\u64CD\u4F5C\uFF1A'${s}'\uFF08get/set\uFF09`)}},Tt=[St,_t,Et,Rt,jt,Wt];function Le(){return Tt}async function Ue(t,e,n,r){let o=(e.mode??"live")==="dry",i=Date.now(),a={},u={status:"success",executed:[],skippedSteps:[],stepResults:a,dry:o,startedAt:i,finishedAt:0},p=e.budgetMs??6e5,f=AbortSignal.timeout(p),c=e.signal?AbortSignal.any([e.signal,f]):f,g={result:u,steps:a,dry:o,signal:c,budgetMs:p,def:t,fnDepth:0},$=await K(t.steps,{steps:a,vars:{},input:e.input},n,r,g);return u.finishedAt=Date.now(),u}async function K(t,e,n,r,s){let{result:o,steps:i}=s;for(let a of t){if(s.signal?.aborted)return o.status="error",o.error=s.signal.reason?.name==="TimeoutError"?`\u6267\u884C\u8D85\u65F6\uFF08\u9884\u7B97 ${s.budgetMs??6e5}ms\u2014\u2014\u53EF\u7ECF budgetMs \u8C03\u6574\uFF09`:`aborted before step '${a.id}'`,{k:"return"};if(a.when!==void 0){let f;try{f=M(B(a.when,e,`when of '${a.id}'`))}catch(c){return i[a.id]={ok:!1,error:`when \u8868\u8FBE\u5F0F\u9519\u8BEF\uFF1A${c.message}`},o.status="error",o.error=`step '${a.id}': ${c.message}`,{k:"return"}}if(!f){o.skippedSteps.push(a.id);continue}}switch(a.type){case"assign":{let f=a.config;try{e.vars[f.target]=B(f.value,e,`\u8D4B\u503C ${f.target}`),i[a.id]={ok:!0,data:e.vars[f.target]},o.executed.push(a.id)}catch(c){return He(s,a,c)}continue}case"if":{let f=a.config,c=await Ct(a,f,e,n,r,s);if(c.k!=="continue")return c;continue}case"try":{let f=a.config,c=await Nt(a,f,e,n,r,s);if(c.k!=="continue")return c;continue}case"while":{let f=a.config,c=await Dt(a,f,e,n,r,s);if(c.k!=="continue")return c;continue}case"for":{let f=a.config,c=await Ot(a,f,e,n,r,s);if(c.k!=="continue")return c;continue}case"return":{let f=a.config,c=f.value!==void 0?B(f.value,e,"return"):void 0;return i[a.id]={ok:!0,data:c},o.executed.push(a.id),{k:"return",value:c}}case"call":{let f=a.config,c=s.def.functions?.find(S=>S.name===f.name);if(!c)return i[a.id]={ok:!1,error:`\u672A\u77E5\u51FD\u6570\uFF1A'${f.name}'`},o.status="error",o.error=`step '${a.id}': \u672A\u77E5\u51FD\u6570 '${f.name}'`,{k:"return"};if(s.fnDepth>=64)return i[a.id]={ok:!1,error:`\u51FD\u6570\u9012\u5F52\u6DF1\u5EA6\u8D85\u8FC7 64\uFF08${f.name}\uFF09`},o.status="error",o.error=`step '${a.id}': \u51FD\u6570\u9012\u5F52\u6DF1\u5EA6\u8D85\u8FC7 64`,{k:"return"};let g={};try{for(let S=0;S<c.params.length;S++){let l=f.args?.[S]??"undefined";g[c.params[S]]=B(l,e,`\u51FD\u6570 '${f.name}' \u53C2\u6570 ${c.params[S]}`)}}catch(S){return i[a.id]={ok:!1,error:S.message},o.status="error",o.error=`step '${a.id}': ${S.message}`,{k:"return"}}let $={...e,vars:g};s.fnDepth++;let R=await K(c.step.steps,$,n,r,s);s.fnDepth--,R.k==="continue"?i[a.id]={ok:!0,data:void 0}:i[a.id]={ok:!0,data:R.value},o.executed.push(a.id);continue}}let u=r.get(a.type);if(!u)return i[a.id]={ok:!1,error:`\u672A\u6CE8\u518C\u6B65\u9AA4\u7C7B\u578B\uFF1A'${a.type}'`},o.status="error",o.error=`step '${a.id}': \u672A\u6CE8\u518C\u7C7B\u578B '${a.type}'`,{k:"return"};let p=a.config??{};try{let f;s.dry&&u.effects?(f=void 0,i[a.id]={ok:!0,dry:!0}):(f=await u.run(p,e,n),i[a.id]={ok:!0,data:f}),o.executed.push(a.id)}catch(f){return He(s,a,f)}if(s.signal?.aborted)return o.status="error",o.error=s.signal.reason?.name==="TimeoutError"?`\u6267\u884C\u8D85\u65F6\uFF08\u9884\u7B97 ${s.budgetMs??6e5}ms\u2014\u2014\u53EF\u7ECF budgetMs \u8C03\u6574\uFF09`:`aborted after step '${a.id}'`,{k:"return"}}return{k:"continue"}}async function Ct(t,e,n,r,s,o){let{result:i,steps:a}=o,u;try{u=M(B(e.when,n,`if '${t.id}' \u6761\u4EF6`))}catch(f){return a[t.id]={ok:!1,error:`if \u8868\u8FBE\u5F0F\u9519\u8BEF\uFF1A${f.message}`},i.status="error",i.error=`step '${t.id}': ${f.message}`,{k:"return"}}a[t.id]={ok:!0,data:{satisfied:u}},i.executed.push(t.id);let p=u?e.then:e.else??void 0;return p?K(p.steps,n,r,s,o):{k:"continue"}}async function Nt(t,e,n,r,s,o){let{result:i,steps:a}=o,u=i.error,p=await K(e.step.steps,n,r,s,o);if(p.k==="return"&&i.status==="error"&&i.error!==u){let f=i.error??"\u672A\u77E5\u9519\u8BEF";return a[t.id]={ok:!1,error:f},i.status="success",i.error=void 0,i.executed.push(t.id),e.catch?.steps.length?K(e.catch.steps,n,r,s,o):{k:"continue"}}return a[t.id]={ok:!0,data:{}},i.executed.push(t.id),p}async function Dt(t,e,n,r,s,o){let{result:i,steps:a}=o,u=e.maxIters??1e3;for(let p=0;;p++){if(o.signal?.aborted)return i.status="error",i.error=`aborted in while '${t.id}'`,{k:"return"};let f;try{f=M(B(e.when,n,`while '${t.id}' \u6761\u4EF6`))}catch(g){return a[t.id]={ok:!1,error:`while \u8868\u8FBE\u5F0F\u9519\u8BEF\uFF1A${g.message}`},i.status="error",i.error=`step '${t.id}': ${g.message}`,{k:"return"}}if(!f)return a[t.id]={ok:!0,data:{iterations:p}},i.executed.push(t.id),{k:"continue"};if(p>=u)return a[t.id]={ok:!1,error:`while \u8D85\u8FC7 maxIters=${u}\uFF08\u9632\u6B7B\u5FAA\u73AF\uFF09`},i.status="error",i.error=`step '${t.id}': while \u8D85\u8FC7 maxIters=${u}`,{k:"return"};let c=await K(e.step.steps,n,r,s,o);if(c.k!=="continue")return c}}async function Ot(t,e,n,r,s,o){let{result:i,steps:a}=o,u;try{u=B(e.items,n,`for '${t.id}' items`)}catch(c){return a[t.id]={ok:!1,error:`for \u8868\u8FBE\u5F0F\u9519\u8BEF\uFF1A${c.message}`},i.status="error",i.error=`step '${t.id}': ${c.message}`,{k:"return"}}if(!Array.isArray(u))return a[t.id]={ok:!1,error:`for items \u5FC5\u987B\u662F\u6570\u7EC4\uFF08\u5F97\u5230 ${String(u)}\uFF09`},i.status="error",i.error=`step '${t.id}': for items \u975E\u6570\u7EC4`,{k:"return"};let p=e.maxIters??1e3;if(u.length>p)return a[t.id]={ok:!1,error:`for \u8D85\u8FC7 maxIters=${p}\uFF08items ${u.length} \u9879\uFF09`},i.status="error",i.error=`step '${t.id}': for \u8D85\u8FC7 maxIters=${p}`,{k:"return"};let f=n.loop;for(let c=0;c<u.length;c++){if(o.signal?.aborted)return i.status="error",i.error=`aborted in for '${t.id}'`,{k:"return"};n.loop={item:u[c],index:c};let g=await K(e.step.steps,n,r,s,o);if(g.k!=="continue")return n.loop=f,g}return n.loop=f,a[t.id]={ok:!0,data:{iterations:u.length}},i.executed.push(t.id),{k:"continue"}}function He(t,e,n){return t.steps[e.id]={ok:!1,error:n.message},t.result.status="error",t.result.error=`step '${e.id}' (${e.type}): ${n.message}`,{k:"return"}}function B(t,e,n){try{return z(t,Ee)(e)}catch(r){throw new Error(`\u8868\u8FBE\u5F0F\u9519\u8BEF\uFF08${n}\uFF09\uFF1A${r.message}`)}}function ne(t){return{get:async e=>{let n=await t.command("GET",e);return n==null?null:String(n)},set:async(e,n)=>{await t.command("SET",e,n)},del:async e=>{await t.command("DEL",e)}}}var ze=["assign","if","try","while","for","return","call"];var Ge=16;function Ye(t,e){let n=[],r=t;if(!Array.isArray(r?.steps)||r.steps.length===0)return{ok:!1,errors:[{path:"steps",message:"steps \u5FC5\u987B\u4E3A\u975E\u7A7A\u6570\u7EC4"}]};let s=new Set,o=new Set,i=new Set;It(r,o,i),pe(r.steps,"steps",e,n,s,0);let a=[];At(r,a);for(let u of a){let p;try{p=I(u.expr)}catch{continue}Xe(p,o,i,u.path,n)}return{ok:n.length===0,errors:n}}function It(t,e,n){let r=s=>{for(let o of s){n.add(o.id);let i=o.config??{};o.type==="assign"&&typeof i.target=="string"&&e.add(i.target);let a=i.then;a&&Array.isArray(a.steps)&&r(a.steps);let u=i.else;u&&Array.isArray(u.steps)&&r(u.steps);let p=i.step;p&&Array.isArray(p.steps)&&r(p.steps);let f=i.catch;f&&Array.isArray(f.steps)&&r(f.steps)}};r(t.steps);for(let s of t.functions??[]){for(let o of s.params??[])e.add(o);r(s.step.steps)}}function At(t,e){let n=(i,a)=>{for(let u of i){let p=u.config??{},f=`${a}/${u.id}`;if(u.type==="assign")s(p.value,`${f}.value`);else if(u.type==="if"){s(p.when,`${f}.when`);for(let c of["then","else"]){let g=p[c];g&&Array.isArray(g.steps)&&n(g.steps,`${f}.${c}`)}}else if(u.type==="while")s(p.when,`${f}.when`);else if(u.type==="for")s(p.items,`${f}.items`);else if(u.type==="return")s(p.value,`${f}.value`);else if(u.type==="call")for(let[c,g]of(p.args??[]).entries())s(g,`${f}.args[${c}]`);else for(let[c,g]of Object.entries(p))typeof g=="string"?o(g,`${f}.${c}`):g&&typeof g=="object"&&!Array.isArray(g)&&r(g,`${f}.${c}`);typeof u.when=="string"&&s(u.when,`${f}.when`)}},r=(i,a)=>{for(let[u,p]of Object.entries(i))typeof p=="string"?o(p,`${a}.${u}`):p&&typeof p=="object"&&!Array.isArray(p)&&r(p,`${a}.${u}`)},s=(i,a)=>{typeof i=="string"&&e.push({path:a,expr:i})},o=(i,a)=>{for(let u of i.matchAll(/\{\{([\s\S]+?)\}\}/g))e.push({path:a,expr:u[1].trim()})};n(t.steps,"steps");for(let i of t.functions??[])n(i.step.steps,`functions.${i.name}`)}function Xe(t,e,n,r,s){if(!(!t||typeof t!="object")){if("segments"in t&&Array.isArray(t.segments)){let o=t.segments[0];if(o==="vars"&&t.segments[1]==="loop")return;o==="vars"&&typeof t.segments[1]=="string"&&!e.has(t.segments[1])?s.push({path:r,message:`\u672A\u58F0\u660E\u53D8\u91CF\u5F15\u7528\uFF1Avars.${t.segments[1]}\uFF08\u987B\u6709 assign target \u58F0\u660E\uFF09`}):o==="steps"&&typeof t.segments[1]=="string"&&!n.has(t.segments[1])&&s.push({path:r,message:`\u672A\u77E5\u6B65\u9AA4\u5F15\u7528\uFF1Asteps.${t.segments[1]}\uFF08\u987B\u662F\u5DF2\u5B9A\u4E49\u6B65\u9AA4 id\uFF09`});return}for(let o of Object.values(t))o&&typeof o=="object"&&Xe(o,e,n,r,s)}}function pe(t,e,n,r,s,o){if(o>Ge){r.push({path:e,message:`\u5B50\u94FE\u5D4C\u5957\u8D85\u8FC7 ${Ge} \u5C42`});return}for(let[i,a]of t.entries()){let u=`${e}[${i}]`;if(!a||typeof a!="object"){r.push({path:u,message:"step \u5FC5\u987B\u662F\u5BF9\u8C61"});continue}if(!a.id||typeof a.id!="string"?r.push({path:`${u}.id`,message:"\u5FC5\u586B\uFF1A\u552F\u4E00 id"}):s.has(a.id)?r.push({path:`${u}.id`,message:`id \u91CD\u590D\uFF1A'${a.id}'`}):s.add(a.id),!a.type||typeof a.type!="string"){r.push({path:`${u}.type`,message:"\u5FC5\u586B\uFF1A\u6B65\u9AA4\u7C7B\u578B"});continue}if(!ze.includes(a.type)&&!n.has(a.type)){r.push({path:`${u}.type`,message:`\u672A\u6CE8\u518C\u7684\u6B65\u9AA4\u7C7B\u578B\uFF1A'${a.type}'`});continue}let p=a.config??{};switch(a.type){case"assign":G(p,"target","\u76EE\u6807\u53D8\u91CF\u540D",r,`${u}.config.target`,!1),G(p,"value","\u8D4B\u503C\u8868\u8FBE\u5F0F",r,`${u}.config.value`,!1);break;case"if":{G(p,"when","\u6761\u4EF6\u8868\u8FBE\u5F0F",r,`${u}.config.when`,!1);for(let f of["then","else"]){let c=p[f];c!==void 0&&(Array.isArray(c.steps)?pe(c.steps,`${u}.config.${f}.steps`,n,r,s,o+1):r.push({path:`${u}.config.${f}.steps`,message:"\u5FC5\u987B\u662F\u6B65\u9AA4\u6570\u7EC4"}))}break}case"try":{We(p,"step",n,r,s,o,u,"steps");let f=p.catch;!f||!Array.isArray(f.steps)?r.push({path:`${u}.config.catch.steps`,message:"catch \u94FE\u5FC5\u987B\u662F\u6B65\u9AA4\u6570\u7EC4\uFF08v0 try \u5FC5\u914D catch\uFF09"}):pe(f.steps,`${u}.config.catch.steps`,n,r,s,o+1);break}case"while":{G(p,"when","\u5FAA\u73AF\u6761\u4EF6",r,`${u}.config.when`,!1),We(p,"step",n,r,s,o,u,"steps");break}case"for":{G(p,"items","\u96C6\u5408\u8868\u8FBE\u5F0F",r,`${u}.config.items`,!1),We(p,"step",n,r,s,o,u,"steps");break}case"return":{p.value!==void 0&&G(p,"value","\u8FD4\u56DE\u503C\u8868\u8FBE\u5F0F",r,`${u}.config.value`,!0);break}default:{let f=n.schema(a.type);for(let c of f?.required??[])(typeof p[c]!="string"||p[c]==="")&&r.push({path:`${u}.config.${c}`,message:`\u5FC5\u586B\uFF1A${c}`})}}if(a.when!==void 0&&typeof a.when!="string")r.push({path:`${u}.when`,message:"\u5FC5\u987B\u662F\u5B57\u7B26\u4E32\u8868\u8FBE\u5F0F"});else if(typeof a.when=="string")try{z(a.when)}catch(f){r.push({path:`${u}.when`,message:`\u8868\u8FBE\u5F0F\u9519\u8BEF\uFF1A${f.message}`})}}}function We(t,e,n,r,s,o,i,a){let u=t[e];if(!u||!Array.isArray(u.steps)){r.push({path:`${i}.config.${e}.${a}`,message:"\u5FC5\u987B\u662F\u6B65\u9AA4\u6570\u7EC4"});return}pe(u.steps,`${i}.config.${e}.${a}`,n,r,s,o+1)}function G(t,e,n,r,s,o){let i=t[e];if(typeof i!="string"||i===""){o||r.push({path:s,message:`\u5FC5\u586B\uFF1A${n}`});return}try{z(i)}catch(a){r.push({path:s,message:`\u8868\u8FBE\u5F0F\u9519\u8BEF\uFF1A${a.message}`})}}function Te(t){let e={};for(let n of t){let r={};for(let s of n.fields??[])r[s.name]={type:s.type==="number"?"number":s.type==="boolean"?"boolean":"string",title:s.label,placeholder:s.placeholder};e[n.type]={type:"object",title:n.label,properties:r,...n.required&&n.required.length?{required:n.required}:{}}}return{type:"object",title:"Workflow",properties:e}}var Pt={http:"HTTP",assign:"\u8D4B\u503C",call:"\u8C03\u7528",if:"\u6761\u4EF6",while:"\u5FAA\u73AF",for:"\u904D\u5386",return:"\u8FD4\u56DE",store:"\u5B58\u50A8",email:"\u90AE\u4EF6",ai:"AI",template:"\u6A21\u677F",log:"\u65E5\u5FD7"};function Qe(t,e,n){if(t==="if"){let r=e?.length??0,s=n?.length??0;return`then\xD7${r}${s?`/else\xD7${s}`:""}`}return t==="while"||t==="for"?`\xD7${e?.length??0} \u5B50\u6B65\u9AA4`:""}function Ce(t,e){let n=e?.labels??{},r=[],s=[],o=t.steps??[];for(let[i,a]of o.entries()){let u=a.config??{},p=`${n[a.type]??Pt[a.type]??a.type} ${a.id}`;if(a.type==="if"){let f=u.then?.steps,c=u.else?.steps,g=Qe("if",f,c);g&&(p+=`\uFF08${g}\uFF09`)}else if(a.type==="while"||a.type==="for"){let f=u.step?.steps,c=Qe(a.type,f);c&&(p+=`\uFF08${c}\uFF09`)}r.push({id:a.id,label:p}),i>0&&s.push({from:o[i-1].id,to:a.id})}return{nodes:r,edges:s}}function et(t,e,n){if(e.length===0)throw new Error("patchStepConfig: \u8DEF\u5F84\u4E0D\u80FD\u4E3A\u7A7A");let s=(a=>a&&typeof a=="object"?JSON.parse(JSON.stringify(a)):a)(t),o=s.steps,i=null;for(let a=0;a<e.length;a++){let u=e[a];if(typeof u=="number"){if(!o||!o[u])throw new Error(`patchStepConfig: \u6B65\u9AA4\u7D22\u5F15 ${u} \u8D8A\u754C`);i=o[u];let p=e[a+1];if(typeof p=="string"){let c=(i.config??{})[p];if(p==="step"&&!c?.steps)throw new Error(`patchStepConfig: \u6B65\u9AA4 ${o[u].id} \u65E0\u5B50\u94FE\uFF08step\uFF09`);if((p==="then"||p==="else")&&!c?.steps)throw new Error(`patchStepConfig: \u6B65\u9AA4 ${o[u].id} \u65E0\u5B50\u94FE\uFF08${p}\uFF09`);o=c?.steps??[],a++}else if(a!==e.length-1)throw new Error("patchStepConfig: \u94FE token\uFF08then/else/step\uFF09\u540E\u5FC5\u987B\u8DDF\u7D22\u5F15")}}if(!i)throw new Error("patchStepConfig: \u5B9A\u4F4D\u5931\u8D25");return i.config={...i.config??{},...n},s}var tt=(t,e)=>{for(let n of t){if(String(n.id)===e)return n;let r=n.config??{};for(let s of["then","else","step"]){let o=r[s];if(o?.steps){let i=tt(o.steps,e);if(i)return i}}}return null};function nt(t,e,n,r){let s=JSON.parse(JSON.stringify(t)),o;if(e===null){if(n.length>0)throw new Error("insert: \u9876\u5C42\u951A\u70B9\uFF08anchor=null\uFF09\u4E0D\u80FD\u6307\u5B9A\u5B50\u94FE\u2014\u2014\u8BF7\u7528\u6B65\u9AA4 id \u951A\u70B9");o=s.steps}else{if(n.length!==1)throw new Error("insert: v0 \u4EC5\u652F\u6301\u5355\u6BB5\u94FE\uFF08then/else/step \u4E4B\u4E00\uFF09\u2014\u2014\u591A\u6BB5\u5D4C\u5957\u94FE\u7F16\u8F91\u5668\u6682\u4E0D\u652F\u6301");let f=tt(s.steps,e);if(!f)throw new Error(`insert: \u951A\u70B9\u6B65\u9AA4 ${e} \u4E0D\u5B58\u5728`);let g=(f.config??{})[n[0]];if(!g?.steps)throw new Error(`insert: \u6B65\u9AA4 ${f.id} \u65E0\u5B50\u94FE\uFF08${n[0]}\uFF09`);o=g.steps}let i=new Set,a=f=>{for(let c of f){i.add(String(c.id));let g=c.config??{};for(let $ of["then","else","step"]){let R=g[$];R?.steps&&a(R.steps)}}};a(s.steps);let u=`_${r.type}${o.length+1}`,p=1;for(;i.has(u);)u=`_${r.type}${o.length+1+p++}`;return o.push({id:u,type:r.type,config:{...r.config}}),s}function rt(t,e){let n=JSON.parse(JSON.stringify(t));if(e.length===0)throw new Error("removeStep: \u8DEF\u5F84\u4E0D\u80FD\u4E3A\u7A7A");let r=n.steps,s=-1;for(let o=0;o<e.length;o++){let i=e[o];if(typeof i=="number"){if(!r[i])throw new Error(`removeStep: \u6B65\u9AA4\u7D22\u5F15 ${i} \u8D8A\u754C`);s=i;let a=e[o+1];if(typeof a=="string"){let p=(r[i].config??{})[a];if(!p?.steps)throw new Error(`removeStep: \u6B65\u9AA4 ${r[i].id} \u65E0\u5B50\u94FE\uFF08${a}\uFF09`);r=p.steps,o++}}}if(s<0)throw new Error("removeStep: \u5B9A\u4F4D\u5931\u8D25");return r.splice(s,1),n}var Mt=new Set(["const","let","var","if","else","while","for","of","return","function","import","export","from","as","default","await","async","once","true","false","null","try","catch","finally"]),qt=new Set(["{","}","(",")","[","]",";",",",":","."]),Ft=new Set(["+","-","*","/","%","<",">","<=",">=","==","!=","===","!==","&&","||"]),st=t=>Ft.has(t),Zt=new Set(["==","!=","<=",">=","&&","||","+=","-=","*=","/=","%=","++","--"]),Vt=new Set(["=","+","-","*","/","%","<",">","!","?"]);function Bt(t){let e=[],n=0,r=t.length;for(;n<r;){let s=t[n];if(s===" "||s===" "||s===`
|
|
4
|
+
`||s==="\r"){n++;continue}if(s==="#"||s==="/"&&t[n+1]==="/"){for(;n<r&&t[n]!==`
|
|
5
|
+
`;)n++;continue}if(s==="`"){let u=n+1,p="";for(;u<r&&t[u]!=="`";){if(t[u]==="\\"){p+=t[u]+(t[u+1]??""),u+=2;continue}p+=t[u],u++}if(u>=r)throw new Error(`wfjs: unterminated template string at ${n}`);e.push({t:"template",raw:p,v:"",pos:n,end:u+1}),n=u+1;continue}if(s==='"'||s==="'"){let u=s,p=n+1,f="";for(;p<r&&t[p]!==u;){if(t[p]==="\\"){let c=t[p+1];if(c==="n"){f+=`
|
|
6
|
+
`,p+=2;continue}if(c==="t"){f+=" ",p+=2;continue}f+=c??"",p+=2;continue}f+=t[p],p++}if(p>=r)throw new Error(`wfjs: unterminated string at ${n}`);e.push({t:"str",v:f,pos:n,end:p+1}),n=p+1;continue}let o=t.slice(n,n+3);if(o==="==="||o==="!=="){e.push({t:"op",v:o,pos:n,end:n+3}),n+=3;continue}let i=t.slice(n,n+2);if(Zt.has(i)){e.push({t:"op",v:i,pos:n,end:n+2}),n+=2;continue}if(Vt.has(s)){e.push({t:"op",v:s,pos:n,end:n+1}),n++;continue}if(qt.has(s)){e.push({t:"punc",v:s,pos:n,end:n+1}),n++;continue}if(s>="0"&&s<="9"){let u=/[0-9]+(?:\.[0-9]+)?/.exec(t.slice(n));e.push({t:"num",v:Number(u[0]),pos:n,end:n+u[0].length}),n+=u[0].length;continue}let a=/[A-Za-z_$][A-Za-z0-9_$]*/.exec(t.slice(n));if(a){e.push(Mt.has(a[0])?{t:"kw",v:a[0],pos:n,end:n+a[0].length}:{t:"ident",v:a[0],pos:n,end:n+a[0].length}),n+=a[0].length;continue}throw new Error(`wfjs: unexpected character '${s}' at ${n} (in ${JSON.stringify(t)})`)}return e.push({t:"eof",v:"",pos:r,end:r}),e}var De=class{i=0;tokens;src;constructor(e,n){this.tokens=e,this.src=n}peek(){return this.tokens[this.i]}next(){return this.tokens[this.i++]}fail(e,n){throw new Error(`${e} at ${n} (in ${JSON.stringify(this.src)})`)}expect(e){let n=this.next();return n.v!==e&&this.fail(`wfjs: expected '${e}'`,n.pos),n}isPunc(e){let n=this.peek();return n.t==="punc"&&n.v===e}isKw(e){let n=this.peek();return n.t==="kw"&&n.v===e}parseProgram(){let e=[];for(;this.peek().t!=="eof";){if(this.isPunc(";")){this.next();continue}e.push(this.parseStmt()),this.isPunc(";")&&this.next()}return e}parseStmt(){if(this.peek().t==="kw"){let e=this.peek().v;if(e==="const"||e==="let"||e==="var")return this.parseVar();if(e==="if")return this.parseIf();if(e==="try")return this.parseTry();if(e==="while")return this.parseWhile();if(e==="for")return this.parseFor();if(e==="return")return this.parseReturn();if(e==="async")return this.next(),this.parseStmt();if(e==="await")return this.next(),this.parseStmt();if(e==="import")return this.parseImport();if(e==="function")return this.parseFunction();if(e==="export")return this.parseExport()}if(this.peek().t==="ident")return this.parseAssignOrCall();this.fail(`wfjs: unexpected '${this.peek().t==="eof"?"(end)":String(this.peek().v)}'`,this.peek().pos)}parseTry(){this.expect("try"),this.expect("{");let e=this.parseBlockBody();this.isKw("catch")||this.fail("wfjs: try \u5FC5\u987B\u914D catch\uFF08v0 \u65E0 finally\uFF09\u2014\u2014\u671F\u671B catch",this.peek().pos),this.next(),this.peek().t==="punc"&&this.peek().v==="("&&this.fail("wfjs: catch \u7ED1\u5B9A\u53D8\u91CF\u6682\u4E0D\u652F\u6301\uFF08ES2019 \u53EF\u9009\u7ED1\u5B9A\u8BED\u4E49\uFF09\u2014\u2014\u9519\u8BEF\u4ECE steps.<tryId>.error \u8BFB\u53D6",this.peek().pos),this.expect("{");let n=this.parseBlockBody();return{k:"try",body:e,catchBody:n}}parseBlockBody(){let e=[];for(;!this.isPunc("}");){if(this.peek().t==="eof"&&this.fail("wfjs: unclosed block",this.peek().pos),this.isPunc(";")){this.next();continue}e.push(this.parseStmt()),this.isPunc(";")&&this.next()}return this.next(),e}parseExport(){if(this.next(),this.isKw("default")){this.next();let n=this.next();return n.t!=="ident"&&this.fail("wfjs: export default \u540E\u5FC5\u987B\u662F\u51FD\u6570\u540D",n.pos),{k:"export",named:[],default:String(n.v)}}this.expect("{");let e=[];for(;!this.isPunc("}");){let n=this.next();n.t!=="ident"&&this.fail("wfjs: export \u6210\u5458\u540D\u5FC5\u987B\u662F\u6807\u8BC6\u7B26",n.pos);let r=n.v;if(this.isKw("as")){this.next();let s=this.next();s.t!=="ident"&&this.fail("wfjs: as \u540E\u5FC5\u987B\u662F\u6807\u8BC6\u7B26",s.pos),r=s.v}if(r!==n.v?e.push({name:n.v,as:r}):e.push({name:n.v}),this.isPunc(",")){this.next();continue}}return this.next(),{k:"export",named:e,default:void 0}}parseFunction(){this.next();let e=this.next();e.t!=="ident"&&this.fail("wfjs: function \u540E\u5FC5\u987B\u662F\u51FD\u6570\u540D",e.pos),this.expect("(");let n=[];if(!this.isPunc(")"))for(;;){let s=this.next();if(s.t!=="ident"&&this.fail("wfjs: \u53C2\u6570\u5FC5\u987B\u662F\u6807\u8BC6\u7B26",s.pos),n.push(String(s.v)),this.isPunc(",")){this.next();continue}break}this.expect(")"),this.expect("{");let r=this.parseBlockBody();return{k:"function",name:String(e.v),params:n,body:r}}parseImport(){this.next(),this.isPunc("{")||this.fail("wfjs: import \u4EC5\u652F\u6301\u547D\u540D\u5BFC\u5165\uFF08{ ... }\uFF09\u2014\u2014\u9ED8\u8BA4/\u547D\u540D\u7A7A\u95F4\u5BFC\u5165 W8",this.peek().pos),this.next();let e=[];for(;!this.isPunc("}");){let r=this.next();r.t!=="ident"&&this.fail("wfjs: import \u6210\u5458\u540D\u5FC5\u987B\u662F\u6807\u8BC6\u7B26",r.pos);let s=r.v;if(this.isKw("as")){this.next();let o=this.next();o.t!=="ident"&&this.fail("wfjs: as \u540E\u5FC5\u987B\u662F\u6807\u8BC6\u7B26",o.pos),s=o.v}if(s!==r.v?e.push({name:r.v,as:s}):e.push({name:r.v}),this.isPunc(",")){this.next();continue}}this.next(),this.expect("from");let n=this.next();return n.t!=="str"&&this.fail("wfjs: import \u6765\u6E90\u5FC5\u987B\u662F\u5B57\u7B26\u4E32",n.pos),{k:"import",names:e,from:String(n.v)}}tryParseMethodCall(){let e=this.peek(),n=this.tokens[this.i+1],r=this.tokens[this.i+2],s=this.tokens[this.i+3];if(e.t!=="ident"||n?.t!=="punc"||n.v!=="."||r?.t!=="ident"||s?.t!=="punc"||s.v!=="(")return null;let o=String(e.v),i=String(r.v);this.next(),this.next(),this.next(),this.next();let a=[];if(!this.isPunc(")"))for(;;){if(a.push({key:null,value:this.parseValue()}),this.isPunc(",")){this.next();continue}break}return this.expect(")"),{name:`@${o}.${i}`,args:a}}parseVar(){let e=this.next();e.t==="kw"&&e.v==="var"&&this.fail("wfjs: 'var' \u4E0D\u652F\u6301\uFF08\u51FD\u6570\u4F5C\u7528\u57DF\u8BED\u4E49\u6613\u6DF7\u6DC6\uFF09\u2014\u2014\u8BF7\u7528 let/const",e.pos);let n=this.next();n.t!=="ident"&&this.fail(`wfjs: expected variable name after '${e.v}'`,n.pos);let r=null;return this.peek().t==="op"&&this.peek().v==="="&&(this.next(),r=this.parseValueOrCall()),{k:"var",name:n.v,init:r,isConst:e.v==="const"}}parseValueOrCall(){let e=!1;this.peek().t==="kw"&&this.peek().v==="await"&&(this.next(),e=!0);let n=this.tryParseMethodCall();if(n)return n;let r=this.peek(),s=this.tokens[this.i+1];if(e&&r.t==="ident"&&s?.t==="punc"&&s.v==="("){let o=String(this.next().v);if(this.next(),A.has(o))return{name:o,args:this.parseCallArgs()};let i=[];if(!this.isPunc(")"))for(;;){if(i.push({key:null,value:this.parseValue()}),this.isPunc(",")){this.next();continue}break}return this.expect(")"),{name:o,args:i}}if(r.t==="ident"&&s?.t==="punc"&&s.v==="("){let o=this.tokens[this.i+2];o?.t==="punc"&&o.v==="{"&&this.fail(`wfjs: \u672A\u8BC6\u522B\u8C03\u7528 '${String(r.v)}'\uFF08\u4EC5\u5185\u7F6E\u6216 std \u7EAF\u51FD\u6570\u2014\u2014\u51FD\u6570\u5B9A\u4E49 W8\uFF09`,r.pos)}return this.parseValue()}parseCallArgs(){if(this.isPunc(")"))return this.next(),[];if(this.isPunc("{")){let e=this.parseObjectArgs();return this.expect(")"),e}return this.fail("wfjs: \u5185\u7F6E\u8C03\u7528\u9700\u5BF9\u8C61\u53C2\u6570\uFF08{ key: value }\uFF09\u2014\u2014\u4F4D\u7F6E\u53C2\u6570\u4EC5\u9650 W8 \u51FD\u6570\u8C03\u7528",this.peek().pos),[]}parseObjectArgs(){this.expect("{");let e=[];for(;!this.isPunc("}");){let n=this.next();if(n.t!=="ident"&&n.t!=="str"&&this.fail("wfjs: expected argument key in object literal",n.pos),this.expect(":"),e.push({key:String(n.v),value:this.parseValue()}),this.isPunc(","))this.next();else break}return this.expect("}"),e}parseValue(){let e=this.peek();if(e.t==="template"||e.t==="str"||e.t==="num"){let n=this.tokens[this.i+1];return n&&n.t==="op"&&st(n.v)?{t:"expr",src:this.scanExpr()}:e.t==="template"?(this.next(),{t:"tpl",parts:Kt(e.raw)}):e.t==="str"?(this.next(),{t:"str",v:e.v}):(this.next(),{t:"num",v:e.v})}if(e.t==="kw"&&(e.v==="true"||e.v==="false"||e.v==="null")){let n=this.tokens[this.i+1];return n&&n.t==="op"&&st(n.v)?{t:"expr",src:this.scanExpr()}:(this.next(),{t:"expr",src:e.v})}if(e.t==="punc"&&e.v==="{"){this.next();let n=[];for(;!this.isPunc("}");){let r=this.next();if(r.t!=="ident"&&r.t!=="str"&&this.fail("wfjs: expected object key",r.pos),this.expect(":"),n.push({key:String(r.v),value:this.parseValue()}),this.isPunc(","))this.next();else break}return this.expect("}"),{t:"obj",kvs:n}}return{t:"expr",src:this.scanExpr()}}scanExpr(){let e=this.peek().pos,n="",r=0,s=-1;for(;;){let i=this.peek();if(i.t==="eof"||r===0&&(i.t==="punc"&&(i.v===","||i.v===";"||i.v===")"||i.v==="}")||i.t==="op"&&(i.v==="="||i.v==="+="||i.v==="-="||i.v==="*="||i.v==="/="||i.v==="%=")||s>=0&&this.src.slice(s,i.pos).includes(`
|
|
7
|
+
`)))break;if(i.t==="punc"&&(i.v==="("||i.v==="[")&&r++,i.t==="punc"&&(i.v===")"||i.v==="]")){if(r===0)break;r--}n+=this.src.slice(i.pos,i.end),s=i.end,this.next()}let o=n.trim();return o||this.fail("wfjs: expected expression",e),o}parseIf(){this.expect("if");let e=!1;this.isKw("once")&&(this.next(),e=!0),this.expect("(");let n=this.scanExpr();this.expect(")"),this.expect("{");let r=this.parseBlockBody(),s=null;return this.isKw("else")&&(this.next(),this.isPunc("{")?(this.next(),s=this.parseBlockBody()):s=[this.parseStmt()]),{k:"if",cond:n,then:r,else:s,once:e}}parseWhile(){this.expect("while"),this.expect("(");let e=this.scanExpr();this.expect(")"),this.expect("{");let n=this.parseBlockBody();return{k:"while",cond:e,body:n}}parseFor(){this.expect("for"),this.expect("(");let e=this.next();(e.t!=="kw"||!["const","let","var"].includes(e.v))&&this.fail("wfjs: for-of \u9700\u8981 const/let",e.pos);let n=this.next();n.t!=="ident"&&this.fail("wfjs: expected loop variable",n.pos);let r=this.next();(r.t!=="kw"||r.v!=="of")&&this.fail("wfjs: only for...of supported",r.pos);let s=this.scanExpr();this.expect(")"),this.expect("{");let o=this.parseBlockBody();return{k:"forof",varName:n.v,items:s,body:o}}parseReturn(){let e=this.next(),n=this.peek();return this.isPunc(";")||this.isPunc("}")?{k:"return",value:null}:n.t==="eof"?{k:"return",value:null}:this.src.slice(e.end,n.pos).includes(`
|
|
8
|
+
`)?{k:"return",value:null}:{k:"return",value:this.parseValue()}}parseAssignOrCall(){let e=this.tryParseMethodCall();if(e)return{k:"call",call:e};let n=this.next();n.t!=="ident"&&this.fail("wfjs: expected identifier",n.pos);let r=this.peek();if(r.t==="punc"&&r.v==="(")return this.next(),{k:"call",call:{name:n.v,args:this.parseCallArgs()}};if(r.t==="op"&&["=","+=","-=","*=","/=","%="].includes(r.v)){let s=r.v;return this.next(),{k:"assign",target:n.v,op:s,value:this.scanExpr()}}if(r.t==="op"&&(r.v==="++"||r.v==="--"))return this.next(),{k:"incdec",target:n.v,inc:r.v==="++"};this.fail(`wfjs: expected assignment or call after '${n.v}'`,r.pos)}};function Kt(t){let e=[],n=0,r="";for(;n<t.length;){if(t[n]==="$"&&t[n+1]==="{"){let s=1,o=n+2,i="";for(;o<t.length&&s>0;){if(t[o]==="\\"){i+=t[o]+(t[o+1]??""),o+=2;continue}t[o]==="{"&&s++,t[o]==="}"&&s--,s>0&&(i+=t[o]),o++}if(s!==0)throw new Error("wfjs: unclosed '${' in template");r&&(e.push(r),r=""),e.push({expr:i.trim()}),n=o;continue}r+=t[n],n++}return r&&e.push(r),e}var A=new Set(["http","email","ai","template","log","stop"]);function Oe(t,e,n){let r=t;if(!(!r||typeof r!="object")){if(r.kind==="call"){let s=r.name??"";if(Jt.has(s))throw new Error(`wfjs: \u526F\u4F5C\u7528\u51FD\u6570 '${s}()' \u4E0D\u80FD\u51FA\u73B0\u5728\u8868\u8FBE\u5F0F\u5185\uFF08in ${n}\uFF09\u2014\u2014\u9700\u8BED\u53E5\u7EA7\u8C03\u7528`);if(!e.stdFns.has(s))throw new Error(`wfjs: \u8868\u8FBE\u5F0F\u5185\u672A\u5BFC\u5165\u51FD\u6570 '${s}()'\uFF08in ${n}\uFF09\u2014\u2014std \u51FD\u6570\u9700 import \u540E\u53EF\u7528`)}for(let s of["left","right","operand","cond","then","else"])r[s]&&typeof r[s]=="object"&&Oe(r[s],e,n);if(r.args)for(let s of r.args)Oe(s,e,n)}}var Jt=new Set(["http","email","ai","template","log"]);function D(t,e,n,r){let s=I(t);return Oe(s,n,r),Y(s,o=>{let i=o.segments[0];if(typeof i!="string")return;let a=e.get(i);if(!a&&(i==="input"||i==="steps"||i==="vars"||i==="loop"))return;if(!a)throw new Error(`wfjs: \u672A\u58F0\u660E\u53D8\u91CF '${i}'\uFF08in ${r}: ${t}\uFF09`);let u=a.kind==="step"?["steps",a.id,"data"]:a.kind==="var"?["vars",a.name]:["loop","item"];o.segments=[...u,...o.segments.slice(1)]}),E(s)}function Y(t,e){let n=t;if(!(!n||typeof n!="object")){if(n.kind==="path"&&e(n),n.kind==="ternary"){Y(n.cond,e),Y(n.then,e),Y(n.else,e);return}if(n.kind==="call"){for(let r of n.args)Y(r,e);return}for(let r of[["left","right"],["operand"]])for(let s of r)n[s]&&typeof n[s]=="object"&&Y(n[s],e)}}function Ie(t,e){for(let n=1;;n++){let r=`${e}${n}`;if(!t.bindings.has(r)&&!t.steps.some(s=>s.id===r))return r}}var Ae={http:{url:"template",method:"template",body:"template",headers:"template",timeoutMs:"template"},email:{to:"template",subject:"template",body:"template"},ai:{prompt:"template",system:"template"},template:{template:"template"},log:{message:"template"},stop:{},store:{key:"expr",value:"expr"}};function fe(t,e,n,r){switch(t.t){case"str":return r==="expr"?`'${t.v.replace(/\\/g,"\\\\").replace(/'/g,"\\'")}'`:t.v;case"num":return String(t.v);case"expr":return r==="template"?`{{${D(t.src,e.bindings,e,n)}}}`:D(t.src,e.bindings,e,n);case"tpl":{if(r==="expr")throw new Error(`wfjs: \u8868\u8FBE\u5F0F\u5B57\u6BB5\u4E0D\u652F\u6301\u6A21\u677F\u4E32\uFF08in ${n}\uFF09`);let s="";for(let o of t.parts)typeof o=="string"?s+=o:s+=`{{${D(o.expr,e.bindings,e,n)}}}`;return s}case"obj":{let s={};for(let o of t.kvs)s[o.key]=fe(o.value,e,n,r);return s}}}function Ne(t,e,n){if(t.key===null){let s=t.value;if(s.t==="expr")return`{{${D(s.src,n.bindings,n,"store \u53C2\u6570")}}}`;if(s.t==="str")return s.v;if(s.t==="num")return String(s.v);throw new Error("wfjs: store \u53C2\u6570\u5FC5\u987B\u662F\u8868\u8FBE\u5F0F\u6216\u5B57\u9762\u91CF")}let r=Ae[e]?.[t.key]??"template";return fe(t.value,n,`${e}(${t.key})`,r)}function J(t,e){return{bindings:new Map(t.bindings),consts:new Set(t.consts),steps:e,imports:t.imports,stdBindings:t.stdBindings,stdFns:t.stdFns,scopes:[...t.scopes,{names:new Set}],hideCount:t.hideCount,functions:t.functions,inFunction:t.inFunction,autoPrefix:t.autoPrefix,exports:t.exports,remoteImports:t.remoteImports}}function Lt(t,e,n){let r=t.scopes[t.scopes.length-1];if(r.names.has(e))throw new Error(`wfjs: \u91CD\u590D\u58F0\u660E '${e}'\uFF08${n}\uFF09`);let s=t.scopes.slice(0,-1).some(i=>i.names.has(e)),o=e;if(s){let i=new Set;for(let a of t.bindings.values())a.kind==="var"?i.add(a.name):a.kind==="step"&&i.add(a.id);do t.hideCount++,o=`${e}$${t.hideCount}`;while(i.has(o))}return r.names.add(e),o}function Ht(t,e,n){let r=()=>Ie(e,`${e.autoPrefix}_${t.k}`);switch(t.k){case"export":{let s=e.functions,o=i=>{if(!s.some(a=>a.name===i))throw new Error(`wfjs: \u5BFC\u51FA '${i}' \u5FC5\u987B\u662F\u5DF2\u5B9A\u4E49\u51FD\u6570\uFF08v1 \u51FD\u6570\u5BFC\u51FA\u2014\u2014\u53D8\u91CF\u5BFC\u51FA v2\uFF09`)};if(t.named.forEach(i=>o(i.name)),t.default&&o(t.default),t.named.length===0&&!t.default)throw new Error("wfjs: export \u5FC5\u987B\u81F3\u5C11\u5BFC\u51FA\u4E00\u4E2A\u6210\u5458");e.exports.named.push(...t.named),t.default&&(e.exports.default=t.default);return}case"function":{if(e.inFunction)throw new Error(`wfjs: \u4E0D\u652F\u6301\u5D4C\u5957\u51FD\u6570\uFF08\u51FD\u6570 '${t.name}'\uFF09`);let s=e.functions.find(p=>p.name===t.name);if(!s)throw new Error(`wfjs: \u5185\u90E8\u9519\u8BEF\uFF1A\u51FD\u6570 '${t.name}' \u672A\u9884\u6CE8\u518C`);let o=new Map,i=new Set,a=[...e.scopes,{names:i}];for(let p of t.params){if(i.has(p))throw new Error(`wfjs: \u91CD\u590D\u53C2\u6570 '${p}'`);i.add(p),o.set(p,{kind:"var",name:p})}for(let[p,f]of e.bindings)f.kind==="var"&&!i.has(p)&&o.set(p,f);let u={bindings:o,consts:new Set,steps:[],imports:e.imports,stdBindings:e.stdBindings,stdFns:e.stdFns,scopes:a,hideCount:e.hideCount,functions:e.functions,inFunction:!0,autoPrefix:`_fn:${t.name}:`,exports:e.exports,remoteImports:e.remoteImports};q(t.body,u,!1),s.step={steps:u.steps};return}case"import":{if(t.from.startsWith("wf://std/")){let o=_e[t.from]??(t.from==="wf://std/store"?{store:null}:void 0);if(!o)throw new Error(`wfjs: std \u6A21\u5757 '${t.from}' \u672A\u6CE8\u518C\uFF08${Object.keys(_e).join(" / ")} \u4E0E wf://std/store\uFF09`);for(let{name:i,as:a}of t.names){let u=a??i;if(i==="store"&&t.from==="wf://std/store")e.stdBindings.set(u,"store");else if(o[i]!==void 0)e.stdBindings.set(u,"fn"),e.stdFns.add(u);else throw new Error(`wfjs: \u6A21\u5757 '${t.from}' \u65E0\u5BFC\u51FA '${i}'`)}e.imports.push({from:t.from,names:t.names});return}if(!t.from.startsWith("https://"))throw new Error(`wfjs: \u6A21\u5757 '${t.from}' \u4E0D\u5408\u6CD5\uFF08wf://std/* \u6216 https://\u2026\uFF09`);e.imports.push({from:t.from,names:t.names});return}case"var":{let{name:s}=t;if(A.has(s))throw new Error(`wfjs: \u53D8\u91CF\u540D '${s}' \u4E0E\u5185\u7F6E\u51FD\u6570\u51B2\u7A81`);let o=Lt(e,s,`\u58F0\u660E ${s}`);if(t.init&&Ut(t.init)){let i=t.init;if(!A.has(i.name)&&!i.name.startsWith("@")){if(e.functions.some(a=>a.name===i.name)){e.steps.push({id:o,type:"call",config:{name:i.name,args:ot(i.args,e)}}),e.bindings.set(s,{kind:"step",id:o}),t.isConst&&e.consts.add(o);return}throw new Error(`wfjs: \u672A\u8BC6\u522B\u8C03\u7528 '${i.name}'\uFF08\u5185\u7F6E\uFF1A${[...A].join("/")}\uFF1B\u51FD\u6570\u9700\u5148\u58F0\u660E\uFF09`)}if(e.inFunction)throw new Error(`wfjs: \u51FD\u6570\u4F53\u5185\u4E0D\u652F\u6301\u526F\u4F5C\u7528\u5185\u7F6E\uFF08${i.name}\uFF09\u2014\u2014\u51FD\u6570\u662F\u7EAF\u903B\u8F91\uFF08v1 \u88C1\u526A\uFF09`);it(i,o,e),e.bindings.set(s,{kind:"step",id:o})}else{let i=t.init?fe(t.init,e,`\u58F0\u660E ${s}`,"expr"):"null";e.steps.push({id:o,type:"assign",config:{target:o,value:i}}),e.bindings.set(s,{kind:"var",name:o})}t.isConst&&e.consts.add(o);return}case"assign":{let s=e.bindings.get(t.target);if(!s)throw new Error(`wfjs: \u672A\u58F0\u660E\u53D8\u91CF '${t.target}'`);let o=s.kind==="var"?s.name:s.kind==="step"?s.id:t.target;if(e.consts.has(o))throw new Error(`wfjs: \u4E0D\u80FD\u7ED9 const '${t.target}' \u8D4B\u503C`);let i=D(t.value,e.bindings,e,`\u8D4B\u503C ${t.target}`),a=t.op==="="?i:`(vars.${o} ${t.op[0]} ${i})`;e.steps.push({id:r(),type:"assign",config:{target:o,value:a}});return}case"incdec":{let s=e.bindings.get(t.target);if(!s)throw new Error(`wfjs: \u672A\u58F0\u660E\u53D8\u91CF '${t.target}'`);let o=s.kind==="var"?s.name:s.kind==="step"?s.id:t.target;if(e.consts.has(o))throw new Error(`wfjs: \u4E0D\u80FD\u7ED9 const '${t.target}' \u8D4B\u503C`);e.steps.push({id:r(),type:"assign",config:{target:o,value:`(vars.${o} ${t.inc?"+":"-"} 1)`}});return}case"if":{let s=D(t.cond,e.bindings,e,"if \u6761\u4EF6"),o=[];q(t.then,J(e,o),n);let i={when:s};if(t.once&&(i.edge=!0),o.length&&(i.then={steps:o}),t.else){let a=[];q(t.else,J(e,a),n),a.length&&(i.else={steps:a})}e.steps.push({id:r(),type:"if",config:i});return}case"try":{let s=[];q(t.body,J(e,s),n);let o=[];q(t.catchBody,J(e,o),n);let i={step:{steps:s},catch:{steps:o}};e.steps.push({id:r(),type:"try",config:i});return}case"while":{let s=D(t.cond,e.bindings,e,"while \u6761\u4EF6"),o=[];q(t.body,J(e,o),!0),e.steps.push({id:r(),type:"while",config:{when:s,step:{steps:o}}});return}case"forof":{let s=D(t.items,e.bindings,e,"for-of"),o=J(e,[]);o.bindings.set(t.varName,{kind:"loop"}),o.scopes[o.scopes.length-1].names.add(t.varName);let i=[];q(t.body,J(o,i),!0),e.steps.push({id:r(),type:"for",config:{items:s,step:{steps:i}}});return}case"return":{let s=t.value?fe(t.value,e,"return","expr"):void 0;e.steps.push({id:r(),type:"return",config:s!==void 0?{value:s}:{}});return}case"call":{if(!A.has(t.call.name)&&!t.call.name.startsWith("@")){if(!e.functions.some(s=>s.name===t.call.name))throw new Error(`wfjs: \u672A\u8BC6\u522B\u8C03\u7528 '${t.call.name}'\uFF08\u5185\u7F6E\uFF1A${[...A].join("/")}\uFF1B\u51FD\u6570\u9700\u5148\u58F0\u660E\uFF09`);e.steps.push({id:r(),type:"call",config:{name:t.call.name,args:ot(t.call.args,e)}});return}if(e.inFunction)throw new Error(`wfjs: \u51FD\u6570\u4F53\u5185\u4E0D\u652F\u6301\u526F\u4F5C\u7528\u5185\u7F6E\uFF08${t.call.name}\uFF09\u2014\u2014\u51FD\u6570\u662F\u7EAF\u903B\u8F91\uFF08v1 \u88C1\u526A\uFF09`);it(t.call,null,e);return}}}function ot(t,e){return t.map(n=>{if(n.key!==null)throw new Error("wfjs: \u51FD\u6570\u8C03\u7528\u4E0D\u652F\u6301\u547D\u540D\u53C2\u6570");let r=n.value;if(r.t==="expr")return D(r.src,e.bindings,e,"\u51FD\u6570\u53C2\u6570");if(r.t==="str")return`'${r.v.replace(/\\/g,"\\\\").replace(/'/g,"\\'")}'`;if(r.t==="num")return String(r.v);if(r.t==="tpl"){let s="`";for(let o of r.parts)typeof o=="string"?s+=o:s+="${"+D(o.expr,e.bindings,e,"\u51FD\u6570\u53C2\u6570\u6A21\u677F")+"}";return s+"`"}throw new Error("wfjs: \u51FD\u6570\u53C2\u6570\u503C\u4E0D\u5408\u6CD5")})}function Ut(t){return typeof t.name=="string"&&Array.isArray(t.args)}function q(t,e,n){for(let r of t)Ht(r,e,n)}function it(t,e,n){if(t.name==="@store.get"||t.name==="@store.set"){let o=t.name.slice(1),i=o.endsWith(".get")?"get":"set";if(!n.stdBindings.has("store")||n.stdBindings.get("store")!=="store")throw new Error("wfjs: \u4F7F\u7528 store \u524D\u9700\u5BFC\u5165\uFF1Aimport { store } from 'wf://std/store'");if(t.args.length!==(i==="get"?1:2))throw new Error(`wfjs: ${o}() \u53C2\u6570\u6570\u91CF\u9519\u8BEF\uFF08${i==="get"?"key":"key, value"}\uFF09\uFF0C\u6536\u5230 ${t.args.length}`);let a={op:i,key:Ne(t.args[0],"store",n)};i==="set"&&(a.value=Ne(t.args[1],"store",n)),n.steps.push({id:e??Ie(n,`_store${i}`),type:"store",config:a});return}if(!A.has(t.name))throw new Error(`wfjs: \u672A\u8BC6\u522B\u8C03\u7528 '${t.name}'\uFF08\u5185\u7F6E\uFF1A${[...A].join("/")}\uFF1B\u51FD\u6570\u8C03\u7528\u5728 W8 wave\uFF09`);let r=e??Ie(n,`_${t.name}`),s={};for(let o of t.args)s[o.key]=Ne(o,t.name,n);n.steps.push({id:r,type:t.name==="stop"?"return":t.name,config:s})}function zt(t,e){let n=e;if(!n||typeof n!="object"||!Array.isArray(n.functions))throw new Error(`wfjs: \u8FDC\u7A0B\u6A21\u5757 '${t}' \u683C\u5F0F\u4E0D\u5408\u6CD5\uFF08\u671F\u671B { functions: [...] }\u2014\u2014\u767D\u540D\u5355\uFF09`);for(let[r,s]of n.functions.entries()){let o=s;if(typeof o.name!="string"||!Array.isArray(o.params)||typeof o.step!="object")throw new Error(`wfjs: \u8FDC\u7A0B\u6A21\u5757 '${t}' functions[${r}] \u7F3A\u5B57\u6BB5\uFF08name/params/step\uFF09`)}return{functions:n.functions}}async function Pe(t,e){let r=new De(Bt(t),t).parseProgram(),s={bindings:new Map,consts:new Set,steps:[],imports:[],stdBindings:new Map,stdFns:new Set,scopes:[{names:new Set}],hideCount:0,functions:[],inFunction:!1,autoPrefix:"",exports:{named:[]},remoteImports:[]};for(let i of r)if(i.k==="function"){if(A.has(i.name))throw new Error(`wfjs: \u51FD\u6570\u540D '${i.name}' \u4E0E\u5185\u7F6E\u51B2\u7A81`);if(s.functions.some(a=>a.name===i.name))throw new Error(`wfjs: \u91CD\u590D\u51FD\u6570 '${i.name}'`);s.functions.push({name:i.name,params:i.params,step:{steps:[]}})}for(let i of r)i.k==="import"&&!i.from.startsWith("wf://std/")&&s.remoteImports.push({from:i.from,names:i.names});for(let i of s.remoteImports){if(!e?.remoteFetch)throw new Error(`wfjs: \u8FDC\u7A0B\u5BFC\u5165 '${i.from}' \u9700\u8981 compileWfjs({ remoteFetch })`);let a=await e.remoteFetch(i.from),u=zt(i.from,a);for(let{name:p,as:f}of i.names){let c=f??p,g=u.functions.find($=>$.name===p);if(!g)throw new Error(`wfjs: \u8FDC\u7A0B\u6A21\u5757 '${i.from}' \u65E0\u5BFC\u51FA\u51FD\u6570 '${p}'`);if(s.functions.some($=>$.name===c))throw new Error(`wfjs: \u51FD\u6570\u540D '${c}' \u51B2\u7A81\uFF08\u8FDC\u7A0B\u5BFC\u5165\uFF09`);s.functions.push({...g,name:c})}}q(r,s,!1);let o={steps:s.steps};return s.imports.length&&(o.imports=s.imports),s.functions.length&&(o.functions=s.functions),(s.exports.named.length||s.exports.default)&&(o.exports=s.exports),o}function X(t){let e=Xt(t.imports??[]),n=Yt(t.functions??[]),r=F(t.steps,{seenVars:new Set,loopNames:[],inReturn:!1}).trimEnd(),s=Gt(t.exports);return[e,n,r,s].filter(Boolean).join(`
|
|
9
|
+
|
|
10
|
+
`)}function Gt(t){if(!t)return"";let e=[];return(t.named??[]).length&&e.push(`export { ${t.named.map(n=>n.as&&n.as!==n.name?`${n.name} as ${n.as}`:n.name).join(", ")} }`),t.default&&e.push(`export default ${t.default}`),e.join(`
|
|
11
|
+
`)}function Yt(t){return t?.length?t.map(e=>{let n={seenVars:new Set,loopNames:[],inReturn:!1},r=F(e.step.steps,n);return`function ${e.name}(${e.params.join(", ")}) {
|
|
12
|
+
${L(r)}
|
|
13
|
+
}`}).join(`
|
|
14
|
+
`):""}function Xt(t){return t?.length?t.map(e=>`import { ${e.names.map(r=>r.as&&r.as!==r.name?`${r.name} as ${r.as}`:r.name).join(", ")} } from '${e.from}'`).join(`
|
|
15
|
+
`):""}function F(t,e){return t.map(n=>tn(n,e)).join(`
|
|
16
|
+
`)}function Z(t,e){return Qt(t,r=>{let[s,o,i,...a]=r;return s==="steps"&&typeof o=="string"&&(i==="data"||i==="result")&&!o.startsWith("_")?[o,...r.slice(3)]:s==="vars"&&typeof o=="string"?[o,...r.slice(2)]:s==="loop"&&o==="item"?[e.loopNames[e.loopNames.length-1]??"it",...r.slice(2)]:null})}function Qt(t,e){let n=I(t),r=s=>{let o=s;if(!(!o||typeof o!="object")){if(o.kind==="path"&&o.segments){let i=e(o.segments);i&&(o.segments=i);return}if(o.kind==="ternary"){r(o.cond),r(o.then),r(o.else);return}if(o.kind==="call"){o.args?.forEach(r);return}for(let i of["left","right","operand"])r(o[i])}};return r(n),E(n)}function Me(t,e,n){if(typeof t!="string")return JSON.stringify(t);if(e==="expr")return Z(t,n);if(!t.includes("{{"))return`'${t.replace(/\\/g,"\\\\").replace(/'/g,"\\'")}'`;let r="`",s=0;for(;;){let o=t.indexOf("{{",s);if(o===-1){r+=t.slice(s).replace(/`/g,"\\`").replace(/\\/g,"\\\\");break}r+=t.slice(s,o).replace(/`/g,"\\`").replace(/\\/g,"\\\\");let i=t.indexOf("}}",o+2);if(i===-1)break;r+="${"+Z(t.slice(o+2,i),n)+"}",s=i+2}return r+"`"}function at(t,e,n){let r=[];for(let[s,o]of Object.entries(e)){if(o===void 0)continue;let i=Ae[t]?.[s]??"template";if(o&&typeof o=="object"&&!Array.isArray(o)){r.push(`${s}: { ${at(t,o,n)} }`);continue}r.push(`${s}: ${Me(o,i,n)}`)}return r.join(", ")}function en(t,e){let n=t.config??{};if(t.type==="call"){let o=(n.args??[]).map(a=>Z(a,e)).join(", "),i=`await ${n.name}(${o})`;return t.id.startsWith("_")||t.id.includes(":")?i:`const ${t.id} = ${i}`}if(t.type==="store"){let o=Me(String(n.key),"template",e),i=n.op==="get"?"get":"set",a=n.op==="set"?`${o}, ${Me(String(n.value??""),"template",e)}`:o,u=`await store.${i}(${a})`;return t.id.startsWith("_")?u:`const ${t.id} = ${u}`}let r=at(t.type,n,e),s=`await ${t.type}({ ${r} })`;return t.id.startsWith("_")?s:`const ${t.id} = ${s}`}function tn(t,e){switch(t.type){case"assign":{let n=t.config,r=Z(n.value,e);return e.seenVars.has(n.target)?`${n.target} = ${r}`:(e.seenVars.add(n.target),`let ${n.target} = ${r}`)}case"if":{let n=t.config,o=[`if (${Z(n.when,e)}) {`];return n.then?.steps.length&&o.push(L(F(n.then.steps,re(e)))),n.else?.steps.length&&(o.push((n.then?.steps.length,"} else {")),o.push(L(F(n.else.steps,re(e))))),o.push("}"),o.join(`
|
|
17
|
+
`)}case"try":{let n=t.config,r=["try {"];return n.step?.steps.length&&r.push(L(F(n.step.steps,re(e)))),r.push("} catch {"),n.catch?.steps.length&&r.push(L(F(n.catch.steps,re(e)))),r.push("}"),r.join(`
|
|
18
|
+
`)}case"while":{let n=t.config;return`while (${Z(n.when,e)}) {
|
|
19
|
+
${L(F(n.step.steps,re(e)))}
|
|
20
|
+
}`}case"for":{let n=t.config,r=Z(n.items,e),s=`it${e.loopNames.length}`;return`for (const ${s} of ${r}) {
|
|
21
|
+
${L(F(n.step.steps,{...e,loopNames:[...e.loopNames,s]}))}
|
|
22
|
+
}`}case"return":{let n=t.config;return n.value!==void 0?`return ${Z(n.value,e)}`:"return"}default:return en(t,e)}}function re(t){return{...t,inReturn:!1}}function L(t){return t.split(`
|
|
23
|
+
`).map(e=>" "+e).join(`
|
|
24
|
+
`)}function ut(t){let e=new Map;for(let s of Le())e.set(s.type,s);let n={fetch:t?.fetch,ai:t?.ai,email:t?.email,log:t?.log,store:t?.store??(t?.redis?ne(t.redis):void 0)},r={get:s=>e.get(s),has:s=>e.has(s),schema:s=>{let o=e.get(s);if(o)return{required:o.required??[],fields:o.fields}}};return{validate:s=>Ye(s,r),execute:(s,o)=>Ue(s,o??{},n,r),registerStep:s=>{e.set(s.type,s)},stepSchemas:()=>[...e.values()].map(s=>({type:s.type,label:s.label,fields:s.fields,required:s.required??[]}))}}var nn=["\u5206\u949F(0-59)","\u5C0F\u65F6(0-23)","\u65E5(1-31)","\u6708(1-12)","\u5468(0-7, 0/7=\u5468\u65E5)"],rn=[59,23,31,12,7];function pt(t,e){let n=nn[e],r=a=>e===4?a>=0&&a<=7:a>=(e===2||e===3?1:0)&&a<=rn[e],s=a=>{if(!r(a))throw new Error(`cron \u5B57\u6BB5\u300C${n}\u300D\u503C ${a} \u8D8A\u754C`)};if(t.includes(",")){let a=t.split(",").map(p=>p.trim());if(a.some(p=>!p))throw new Error(`cron \u5B57\u6BB5\u300C${n}\u300D\u5217\u8868\u542B\u7A7A\u9879`);let u=a.map(p=>pt(p,e));return p=>u.some(f=>f(p))}let o=t.match(/^\*\/(\d+)$/);if(o){let a=Number(o[1]);if(a<1)throw new Error(`cron \u5B57\u6BB5\u300C${n}\u300D\u6B65\u957F\u5FC5\u987B \u22651`);return u=>u%a===0}let i=t.match(/^(\d+)-(\d+)$/);if(i){let a=Number(i[1]),u=Number(i[2]);if(s(a),s(u),a>u)throw new Error(`cron \u5B57\u6BB5\u300C${n}\u300D\u8303\u56F4\u8D77\u5927\u4E8E\u6B62\uFF08${a}-${u}\uFF09`);return p=>p>=a&&p<=u}if(t==="*")return()=>!0;if(/^\d+$/.test(t)){let a=Number(t);return s(a),u=>u===a}throw new Error(`cron \u5B57\u6BB5\u300C${n}\u300D\u65E0\u6CD5\u8BC6\u522B\uFF1A'${t}'\uFF08\u652F\u6301 * a/N N N-M N,M\uFF09`)}function qe(t){let e=t.trim().split(/\s+/);if(e.length!==5)throw new Error(`cron \u8868\u8FBE\u5F0F\u9700 5 \u5B57\u6BB5\uFF08\u5206 \u65F6 \u65E5 \u6708 \u5468\uFF09\u2014\u2014\u6536\u5230 ${e.length} \u4E2A\uFF1A'${t}'`);let[n,r,s,o,i]=e.map((a,u)=>pt(a,u));return a=>n(a.getMinutes())&&r(a.getHours())&&s(a.getDate())&&o(a.getMonth()+1)&&i(a.getDay())}function ft(t){let e=n=>String(n).padStart(2,"0");return`${t.getFullYear()}-${e(t.getMonth()+1)}-${e(t.getDate())}T${e(t.getHours())}:${e(t.getMinutes())}`}var V="_weifuwu_workflows",Q="_weifuwu_workflow_runs",se="_weifuwu_workflow_versions";function sn(t,e,n={}){let r=n.intervalMs??3e4,s=n.now??(()=>new Date),o=new Map,i=null,a=async()=>{let u=s(),p=ft(u);try{let f=await t.query.from(V).where({status:{eq:"active"}}).select("id","app_id","cron").run();for(let c of f){let g=String(c.cron??"");if(!g)continue;let $;try{$=qe(g)(u)}catch{continue}if(!$)continue;let R=`${p}:${String(c.id)}`;o.has(R)||(o.set(R,!0),o.size>1e4&&o.clear(),await e(String(c.app_id),String(c.id),{},"cron").catch(S=>{console.error(`[workflow-scheduler] cron \u89E6\u53D1\u6267\u884C\u5931\u8D25 (${String(c.id)}):`,S instanceof Error?S.message:S)}))}}catch(f){console.error("[workflow-scheduler] tick \u626B\u63CF\u5931\u8D25:",f instanceof Error?f.message:f)}};return{start:()=>{i||(i=setInterval(()=>{a()},r),i.unref?.(),a())},stop:()=>{i&&(clearInterval(i),i=null)}}}function Xn(t){let{orm:e,redis:n}=t,r=ut({store:n?ne(n):void 0}),s=async({wfjs:l,def:w})=>{if(typeof l=="string"){let d=await Pe(l),v=r.validate(d);if(!v.ok)throw new Error(`wfjs \u7F16\u8BD1\u901A\u8FC7\u4F46\u6821\u9A8C\u5931\u8D25\uFF1A${v.errors.map(k=>`${k.path}: ${k.message}`).join("\uFF1B")}`);return{def:d,wfjs:X(d)}}if(w){let d=r.validate(w);if(!d.ok)throw new Error(`DSL \u6821\u9A8C\u5931\u8D25\uFF1A${d.errors.map(k=>`${k.path}: ${k.message}`).join("\uFF1B")}`);let v=w;return{def:v,wfjs:X(v)}}throw new Error("\u521B\u5EFA workflow \u9700\u8981 wfjs \u6E90\u7801\u6216 DSL def")},o=async(l,w)=>{try{let d=await r.execute(l,{input:w});return{status:d.status,result:d,error:d.status==="error"?d.error??"\u6267\u884C\u5931\u8D25":null}}catch(d){return{status:"error",result:null,error:d.message}}},i="id, app_id, name, description, def_json, src_wfjs, status, cron, created_at, updated_at",a="id, app_id, workflow_id, trigger, status, args_json, result_json, error, started_at, finished_at, created_at",u=l=>typeof l=="string"?JSON.parse(l):l,p=l=>typeof l=="string"?JSON.parse(l):l,f=l=>({...l,def_json:u(l.def_json)}),c=l=>({...l,args_json:u(l.args_json),result_json:u(l.result_json)}),g={async create(l,w){let{def:d,wfjs:v}=await s(w),k=await e.query.insert(V).values({app_id:l,name:w.name,description:w.description??null,def_json:JSON.stringify(d),src_wfjs:v,cron:w.cron??null}).returning(...i.split(", ")).run(),m=f(k[0]);return await e.query.insert(se).values({app_id:l,workflow_id:m.id,def_json:JSON.stringify(d),note:"\u521D\u59CB\u7248\u672C"}).run(),m},async list(l,w){let d=w?.offset??0,v=Math.min(100,Math.max(1,w?.limit??50)),m=(await e.query.from(V).where({app_id:{eq:l}}).select(...i.split(", ")).orderBy("updated_at","desc").limit(v).offset(d).run()).map(y=>f(y));for(let y of m){let h=await e.query.from(Q).where({workflow_id:{eq:y.id},app_id:{eq:l}}).orderBy("created_at","desc").limit(1).run();y.last_run=h[0]?c(h[0]):null}return m},async get(l,w){let d=await e.query.from(V).where({app_id:{eq:l},id:{eq:w}}).select(...i.split(", ")).limit(1).run();return d[0]?f(d[0]):null},async update(l,w,d){if(!(await e.query.from(V).where({app_id:{eq:l},id:{eq:w}}).select("id").limit(1).run())[0])return!1;let k=null;if((d.wfjs!==void 0||d.def!==void 0)&&(k=await s(d)),d.cron!==void 0&&d.cron!==null&&d.cron!=="")try{qe(String(d.cron))}catch(y){throw new te(`cron \u8868\u8FBE\u5F0F\u975E\u6CD5\uFF1A${String(y?.message??y)}`,400)}let m={};return d.name!==void 0&&(m.name=d.name),d.cron!==void 0&&(m.cron=d.cron||null),k&&(m.def_json=JSON.stringify(k.def),m.src_wfjs=k.wfjs,await e.query.insert(se).values({app_id:l,workflow_id:w,def_json:JSON.stringify(k.def),note:d.note??null}).run()),m.updated_at=new Date().toISOString(),await e.query.update(V).set(m).where({app_id:{eq:l},id:{eq:w}}).run(),!0},async listVersions(l,w,d){let v=d?.offset??0,k=Math.min(100,Math.max(1,d?.limit??30));return(await e.query.from(se).where({app_id:{eq:l},workflow_id:{eq:w}}).select(..."id, app_id, workflow_id, def_json, note, created_at".split(", ")).orderBy("created_at","desc").limit(k).offset(v).run()).map(y=>{let h=y;return{...h,def_json:p(h.def_json)}})},async rollback(l,w,d){let v=await e.query.from(se).where({app_id:{eq:l},workflow_id:{eq:w},id:{eq:d}}).select(..."id, def_json".split(", ")).limit(1).run();if(!v[0]||!await g.get(l,w))return!1;let m=p(v[0].def_json);return await e.query.update(V).set({def_json:JSON.stringify(m),src_wfjs:X(m),updated_at:new Date().toISOString()}).where({app_id:{eq:l},id:{eq:w}}).run(),await e.query.insert(se).values({app_id:l,workflow_id:w,def_json:JSON.stringify(m),note:`\u56DE\u6EDA\u81EA ${d.slice(0,8)}`}).run(),!0},async remove(l,w){return await e.query.delete(V).where({app_id:{eq:l},id:{eq:w}}).run(),!0},async listRuns(l,w,d){let v=d?.offset??0,k=Math.min(100,Math.max(1,d?.limit??50));return(await e.query.from(Q).where({app_id:{eq:l},workflow_id:{eq:w}}).select(...a.split(", ")).orderBy("created_at","desc").limit(k).offset(v).run()).map(y=>c(y))},async getRun(l,w,d){let v=await e.query.from(Q).where({app_id:{eq:l},id:{eq:d},workflow_id:{eq:w}}).select(...a.split(", ")).limit(1).run();return v[0]?c(v[0]):null}},$=async(l,w,d,v="manual")=>{let k=await g.get(l,w);if(!k)throw new Error("workflow \u4E0D\u5B58\u5728");let m=new Date().toISOString(),y=await e.query.insert(Q).values({app_id:l,workflow_id:w,trigger:v,status:"running",args_json:JSON.stringify(d),result_json:null,error:null,started_at:m,finished_at:null}).returning(...a.split(", ")).run(),h=String(y[0].id);try{let x=await o(k.def_json,d),j=await e.query.update(Q).set({status:x.status,result_json:JSON.stringify(x.result),error:x.error,finished_at:new Date().toISOString()}).where({id:{eq:h}}).returning(...a.split(", ")).run();return c(j[0])}catch(x){return await e.query.update(Q).set({status:"error",error:x.message,finished_at:new Date().toISOString()}).where({id:{eq:h}}).run(),c({status:"error",error:x.message})}},R={crud:g,compileGate:s,validate:l=>r.validate(l),execute:$,executeDef:o,dag:l=>Ce(l),schema:()=>Te(r.stepSchemas()),defToWfjs:l=>X(l)},S=(async(l,w,d)=>(w.wf=R,d(l,w)));return S.wf=R,S.crud=g,S.scheduler=sn(e,$),S.__meta={injects:["wf"],depends:[]},S.routes=(l,w)=>{let d=w?.prefix??t.prefix??"/api/workflows",v=w?.appId??(y=>y.auth?.appId),k=y=>{let h=v(y);if(!h)throw new te("workflow route \u9700\u8981 appId\uFF08\u5E94\u7528\u4E0A\u4E0B\u6587\uFF09",400);return h},m=(y,h=200)=>Response.json(y,{status:h});l.get(`${d}/:id/versions`,async(y,h)=>await g.get(k(h),h.params.id)?m({versions:await g.listVersions(k(h),h.params.id)}):m({error:"workflow \u4E0D\u5B58\u5728"},404)),l.post(`${d}/:id/versions/:vid/rollback`,async(y,h)=>await g.rollback(k(h),h.params.id,h.params.vid)?m({ok:!0}):m({error:"workflow \u6216\u7248\u672C\u4E0D\u5B58\u5728"},404)),l.get(`${d}/meta`,async(y,h)=>m({schemas:R.schema()})),l.get(`${d}`,async(y,h)=>{let x=new URL(y.url),j=Math.max(0,parseInt(x.searchParams.get("offset")??"0",10)),P=Math.min(100,Math.max(1,parseInt(x.searchParams.get("limit")??"50",10)));return m({workflows:await g.list(k(h),{offset:j,limit:P})})}),l.post(`${d}`,async(y,h)=>{let x=await y.json().catch(()=>({}));if(!x?.name)return m({error:"\u5FC5\u586B\uFF1Aname"},400);try{let j=await g.create(k(h),x);return m({ok:!0,workflow:j},201)}catch(j){return m({error:j.message},400)}}),l.get(`${d}/:id`,async(y,h)=>{let x=await g.get(k(h),h.params.id);return x?m({workflow:{...x,def:x.def_json,wfjs:x.src_wfjs,dag:R.dag(x.def_json)}}):m({error:"workflow \u4E0D\u5B58\u5728"},404)}),l.put(`${d}/:id`,async(y,h)=>{let x=await y.json().catch(()=>({}));try{if(x.patch){let P=await g.get(k(h),h.params.id);if(!P)return m({error:"workflow \u4E0D\u5B58\u5728"},404);let T=x.patch,ee;if(T.op==="insert"){if(!T.step?.type)return m({error:"insert \u9700\u8981 step.type"},400);ee=nt(P.def_json,T.anchor??null,T.chain??[],T.step)}else if(T.op==="remove")ee=rt(P.def_json,T.path);else{if(!T.config)return m({error:"set \u9700\u8981 config"},400);ee=et(P.def_json,T.path,T.config)}let Fe=R.validate(ee);return Fe.ok?(await g.update(k(h),h.params.id,{def:ee}),m({ok:!0})):m({error:`patch \u6821\u9A8C\u5931\u8D25\uFF1A${Fe.errors.map(ct=>ct.message).join("\uFF1B")}`},400)}return await g.update(k(h),h.params.id,x)?m({ok:!0}):m({error:"workflow \u4E0D\u5B58\u5728"},404)}catch(j){return m({error:j.message},400)}}),l.delete(`${d}/:id`,async(y,h)=>(await g.remove(k(h),h.params.id),m({ok:!0}))),l.post(`${d}/:id/runs`,async(y,h)=>{let x=await y.json().catch(()=>({}));try{let j=await $(k(h),h.params.id,x.args??{});return m({ok:!0,run:j},201)}catch(j){return m({error:j.message},400)}}),l.get(`${d}/:id/runs`,async(y,h)=>{if(!await g.get(k(h),h.params.id))return m({error:"workflow \u4E0D\u5B58\u5728"},404);let j=new URL(y.url),P=Math.max(0,parseInt(j.searchParams.get("offset")??"0",10)),T=Math.min(100,Math.max(1,parseInt(j.searchParams.get("limit")??"50",10)));return m({runs:await g.listRuns(k(h),h.params.id,{offset:P,limit:T})})}),l.get(`${d}/:id/runs/:runId`,async(y,h)=>{let x=await g.getRun(k(h),h.params.id,h.params.runId);return x?m({run:x}):m({error:"run \u4E0D\u5B58\u5728"},404)})},S}var Qn={tables:[{name:"_weifuwu_workflows",columns:{id:N.pk(b.uuid()),app_id:N.req(b.uuid()),name:N.req(b.string()),description:b.string(),def_json:b.json().meta({notNull:!0}),src_wfjs:b.string(),status:b.string().meta({default:"active"}),cron:b.string(),created_at:b.date().meta({default:"now"}),updated_at:b.date().meta({default:"now"})},indexes:[{cols:["app_id",{col:"updated_at",desc:!0}],name:"idx_wf_workflows_app"}]},{name:"_weifuwu_workflow_runs",columns:{id:N.pk(b.uuid()),app_id:N.req(b.uuid()),workflow_id:N.req(b.uuid()).meta({references:"_weifuwu_workflows",onDelete:"cascade"}),trigger:b.string().meta({default:"manual"}),status:b.string().meta({default:"queued"}),args_json:b.json(),result_json:b.json(),error:b.string(),started_at:b.date(),finished_at:b.date(),created_at:b.date().meta({default:"now"})},indexes:[{cols:["app_id",{col:"created_at",desc:!0}],name:"idx_wf_runs_app"},{cols:["workflow_id",{col:"created_at",desc:!0}],name:"idx_wf_runs_wf"}]},{name:"_weifuwu_workflow_versions",columns:{id:N.pk(b.uuid()),app_id:N.req(b.uuid()),workflow_id:N.req(b.uuid()).meta({references:"_weifuwu_workflows",onDelete:"cascade"}),def_json:b.json().meta({notNull:!0}),note:b.string(),created_at:b.date().meta({default:"now"})},indexes:[{cols:["workflow_id",{col:"created_at",desc:!0}],name:"idx_wf_versions_wf"}]}]};export{Qn as WEIFUWU_WORKFLOW_SCHEMA,sn as createScheduler,Xn as workflowSystem};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
function x(){return{children:new Map}}function d(r,e,t,n,o="value"){if(t===e.length){let s=o==="value"?r.value:r.wildcardValue;return s!==void 0?{value:s,params:{...n},node:r}:null}let i=e[t],l=r.children.get(i);if(l){let s=d(l,e,t+1,n,o);if(s)return s}let a=r.children.get(":");if(a?.param){let s={...n,[a.param]:decodeURIComponent(i)},u=d(a,e,t+1,s,o);if(u)return u}return null}function f(r,e){let t=d(r,e,0,{});if(t){let n=t.node.wildcardValue!==void 0;return{value:t.value,params:n?{...t.params,"*":""}:t.params,wildcard:!1}}return w(r,e,e.length)}function w(r,e,t){for(let n=0;n<=t;n++){let o=d(r,e.slice(0,n),0,{},"wildcard");if(o)return{value:o.value,params:{...o.params,"*":e.slice(n).join("/")},wildcard:!0}}return null}function c(r){let e;try{e=new URL(r.url)}catch{return{ok:!1,reason:"invalid-url"}}let t=T(e);try{decodeURI(e.pathname)}catch{return{ok:!1,reason:"malformed-encoding"}}for(let n of h(e.pathname))try{decodeURIComponent(n)}catch{return{ok:!1,reason:"malformed-encoding"}}return{ok:!0,segments:h(e.pathname),pathname:e.pathname,query:t}}function h(r){return r.split("/").filter(Boolean)}function p(r){return r?{...r.params}:{}}function T(r){return Object.fromEntries(r.searchParams)}function C(r){return Response.json({error:"Bad Request",reason:r},{status:400})}async function v(r,e,t,n){let o=c(t);if(!o.ok)return C(o.reason);let i=f(r,o.segments),l=i?{value:i.value,params:p(i),wildcard:i.wildcard}:null;e.enrichCtx?.(n,l,o.pathname,o.query);try{if(!l)return await e.onNotFound(t,n,o.pathname);let a=e.resolveHandler(l,t,n);if(a.kind==="not-found")return await e.onNotFound(t,n,o.pathname);if(a.kind==="not-allowed")return e.onMethodNotAllowed?await e.onMethodNotAllowed(a.methods,t,n,o.pathname):new Response("Method Not Allowed",{status:405,headers:{Allow:a.methods.join(", ")}});let s=await a.run();return e.onRouteSuccess?.(t,n,o.pathname),s}catch(a){if(e.onError)return e.onError(a,t,n,o.pathname);throw a}}function N(){let r=new Set;return{register(e){for(let t of e)r.add(t)},check(e,t){for(let n of e)if(!r.has(n))throw new Error(`[weifuwu] Middleware at "${t}" depends on ctx.${n} but it hasn't been registered.
|
|
2
|
+
Register the provider before this middleware: app.use(${n}())`)},has(e){return r.has(e)}}}async function y(r,e,t,n){if(r.length===0)return e(t,n);let o=0,i=(l,a)=>{if(o>=r.length)return Promise.resolve(e(l,a));let s=r[o++],u=!1,g=(m,R)=>{if(u)throw new Error("[router] next() called more than once in middleware");return u=!0,i(m,R)};return Promise.resolve(s(l,a,g))};return i(t,n)}export{N as createCtxFieldRegistry,x as createTrie,v as dispatchRouter,p as freshParams,T as parseQuery,c as parseRequestTarget,y as runChain};
|
package/docs/client.md
CHANGED
|
@@ -19,19 +19,40 @@
|
|
|
19
19
|
## 1. 快速上手
|
|
20
20
|
|
|
21
21
|
```tsx
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
// 组件
|
|
22
|
+
// 服务端(默认主入口 = src/server/index.ts)
|
|
23
|
+
import { serve, Router, z } from 'weifuwu'
|
|
24
|
+
// 前端内核(src/client/vdom——h/jsx/uiServe/UIRouter/renderToStream)
|
|
25
|
+
import { uiServe, UIRouter, h } from 'weifuwu/client/vdom'
|
|
26
|
+
// 组件库(src/client/components——139 组件 + style.css 全量样式)
|
|
27
|
+
import { Button, Modal } from 'weifuwu/client/components'
|
|
28
|
+
import 'weifuwu/client/components/style.css'
|
|
27
29
|
```
|
|
28
30
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
+
**导出 = src/ 目录结构直映**(无别名):
|
|
32
|
+
|
|
33
|
+
| import | 源码(第一/二级目录直映——有 index.ts 才导出) |
|
|
34
|
+
| --- | --- |
|
|
35
|
+
| `weifuwu` / `weifuwu/server` | `src/server/index.ts`(serve/Router/z/workflow 聚合) |
|
|
36
|
+
| `weifuwu/server/workflow` | `src/server/workflow/index.ts`(声明式执行引擎) |
|
|
37
|
+
| `weifuwu/server/{ai,email,messager,postgres,queue,redis,scheduler,ui,user,workflows}` | `src/server/<子>/index.ts`——二级直映(独立 bundle) |
|
|
38
|
+
| `weifuwu/client/vdom` | `src/client/vdom/index.ts`(h/jsx/uiServe/jsx-runtime) |
|
|
39
|
+
| `weifuwu/client/components` | `src/client/components/index.ts`(139 组件) |
|
|
40
|
+
| `weifuwu/client/components/style.css` | dist 聚合样式(layout + 组件全量) |
|
|
41
|
+
| `weifuwu/client/layout` | `src/client/layout/index.ts`(模块 ——defineLayout + 装配) |
|
|
42
|
+
| `weifuwu/client/layout/weifuwu-layout.css` | 布局原语 CSS(独立面) |
|
|
43
|
+
| `weifuwu/shared/router` | `src/shared/router/index.ts`(trie/pipeline/context/chain 五件) |
|
|
44
|
+
| `weifuwu/dev` | `src/dev/index.ts`(`node --import weifuwu/dev server.ts`) |
|
|
45
|
+
|
|
46
|
+
> 颗粒度原则:**一级目录只在有天然 `index.ts` 时导出**(server/dev——src 无顶层
|
|
47
|
+
> index 人造聚合);**二级目录有 `index.ts` 即导出**(client/vdom · client/components ·
|
|
48
|
+
> server/ai · shared/router……);**更深(三级:vdom/core/field 等)不导出**(内部)。
|
|
49
|
+
|
|
50
|
+
**JSX 配置**:`tsconfig` 的 `jsxImportSource: "weifuwu/client/vdom"`(jsx-runtime
|
|
51
|
+
子路径自动解析——见仓库 tsconfig 先例)。组件 = 工厂同步 + 渲染纯同步——见 §5.1。
|
|
31
52
|
|
|
32
53
|
## 2. 组件清单
|
|
33
54
|
|
|
34
|
-
**
|
|
55
|
+
**139 个组件**——源码目录即清单:`src/client/components/<Comp>/<Comp>.ts`(每个含
|
|
35
56
|
`<Comp>.css` + 契约测试)。展示与使用示例:`apps/showcase/`(localhost:3200——
|
|
36
57
|
`/components/<id>` 每组件一页 + demo 源码即用法)。
|
|
37
58
|
|
|
@@ -40,6 +61,8 @@ app.router(Router())
|
|
|
40
61
|
| 类 | 代表组件 |
|
|
41
62
|
| --- | --- |
|
|
42
63
|
| 通用基础 | Button / Card / Badge / Avatar / Alert / EmptyState / Loading / Modal / Drawer |
|
|
64
|
+
| 列表骨架 | ListScaffold(PageHeader+工具栏+状态区+内容插槽)/ StatusDot(状态点—label 缺省只渲染点) |
|
|
65
|
+
| 常用输入 | CronPicker(cron 预设 + 自由编辑——server 解析器语义对齐) |
|
|
43
66
|
| 表单 | Input / Textarea / Select / DatePicker / Upload / Form / Checkbox / Switch / Slider |
|
|
44
67
|
| 数据展示 | Table / VirtualTable / Chart / Tree / CodeBlock / DiffView / Kanban |
|
|
45
68
|
| 导航 | NavBar / TabBar / Breadcrumb / Pagination / Menu / NavMenu / Anchor |
|
|
@@ -102,9 +125,9 @@ app.router(Router())
|
|
|
102
125
|
层叠语义的浏览器计算值读数见场景层 `e2e-layout-semantics.test.ts`。
|
|
103
126
|
|
|
104
127
|
**载荷面(W6 minify)**:dist 发布产物 `weifuwu-layout.css` **28.1K**(gzip 5.7K · brotli 5.1K)·
|
|
105
|
-
`weifuwu/components/style.css` **220.9K**(gzip 29.4K · brotli 24.3K)——esbuild minify(
|
|
128
|
+
`weifuwu/client/components/style.css` **220.9K**(gzip 29.4K · brotli 24.3K)——esbuild minify(
|
|
106
129
|
`build.mjs` 实装:`@layer`/`@property`/`@supports`/转义类名全保留,注释全剥离);
|
|
107
|
-
**无组件应用只引 `weifuwu/layout`**(28.1K / br 5.1K——独立面,零组件 CSS 成本)。
|
|
130
|
+
**无组件应用只引 `weifuwu/client/layout/weifuwu-layout.css`**(28.1K / br 5.1K——独立面,零组件 CSS 成本)。
|
|
108
131
|
按需子集(per-component 子路径 / purge)**判负**:动态类名漏删风险 + 构建期改造成本
|
|
109
132
|
+ br 后 24.3K 非瓶颈——推翻条件:真实应用首屏 CSS 成为 LCP 阻塞的实测数据。
|
|
110
133
|
|
|
@@ -228,6 +251,51 @@ style-audit 文件数基线 +1 · 覆盖哨兵跑绿(`scripts/audit-component-
|
|
|
228
251
|
R-03:类名/结构变更**反查测试选择器**(`[class*="..."]` 定位器)·
|
|
229
252
|
行为变化**必带契约测试** · 机制化优先(能进审计不靠记忆)
|
|
230
253
|
|
|
254
|
+
### 5.9 应用层组件入库路径(agent-platform 先例——2027-09)
|
|
255
|
+
|
|
256
|
+
**判别三层**(先探针甄别再动工):
|
|
257
|
+
1. **纯 UI 组件**(零 fetch/零业务类型)→ 迁库(三件套+契约+showcase+demo)
|
|
258
|
+
2. **平台业务部件**(业务元数据/枚举面——TypeBadge/TypeAva)→ 留平台
|
|
259
|
+
`ui/blocks/`(判负登记)
|
|
260
|
+
3. **业务区块**(服务端 API 绑定——Sections/MessageItem)→ `pages/blocks`
|
|
261
|
+
语义降级(判负——推翻条件:API 上抛成纯 props 展示)
|
|
262
|
+
|
|
263
|
+
**样式面**:平台组件迁库后**零自建 style**(wf- 布局组合/库 css 单源)——
|
|
264
|
+
应用层 ap-* 组件样式(壳抽屉/遮罩/徽标)随迁入改名 `wf-*`(词根登记制);
|
|
265
|
+
app.css 只留**页面布局面**(body 链/面板/消息区)。
|
|
266
|
+
|
|
267
|
+
**移动抽屉/断点**:库组件**不内建 useBreakpoint**(node 无 matchMedia 恒回
|
|
268
|
+
基档——SSR≡SPA 首帧不一致 absorb 违例——实证)——`mobile` prop 父层驱动
|
|
269
|
+
(页面级判定——库惯例「响应式交还用户」同 Layout/NavMenu)。
|
|
270
|
+
|
|
271
|
+
### 5.10 命名规范(学习成本——API 一致性红线)
|
|
272
|
+
|
|
273
|
+
**类名形态(vnode 内核 normalizeClass——2027-09)**:`class` 支持
|
|
274
|
+
**字符串 / 数组 / 对象**三形态(h/jsx 自动归一——字符串直通零成本 · 对象
|
|
275
|
+
条件真值 `{ 'wf-active': flag }` · 数组组合 `['wf-a', cond && 'wf-b']`)——
|
|
276
|
+
**新组件用对象/数组形态**(零模板拼接);旧模板字符串保留(等价——不迁移
|
|
277
|
+
(行为恒等重写风险>收益——改动自然随维护推进)
|
|
278
|
+
|
|
279
|
+
**组件命名**(用户看到的第一面):
|
|
280
|
+
- 目录/导出名:PascalCase(`CronPicker`)· registry id:**slug(无连字符小写)**——
|
|
281
|
+
`listscaffold`/`statusdot`/`togglegroup`(2027-09 曾引入连字符 id 违规实证——
|
|
282
|
+
coverage 哨兵已加 id=slug 校验防回流)
|
|
283
|
+
- 示例路径:`/components/<slug>` · 测试文件:`comp-<slug>.test.ts`
|
|
284
|
+
- **家族目录一目录多导出**(ToggleGroup 目录导出 Toggle+ToggleGroup · Typography 导出
|
|
285
|
+
Title/Text/Paragraph)——desc 首句点明全家族名 + registry 变体表挂全成员
|
|
286
|
+
|
|
287
|
+
**参数命名**(回调/文案——行业惯性对齐):
|
|
288
|
+
- 回调:**原生 DOM 事件名直映**(onClick/onKeyDown/onInput/onMouseEnter——事件名
|
|
289
|
+
即所见)· **合成语义回调**(onChange/onSelect/onOpenChange/onConfirm——等价
|
|
290
|
+
DOM 事件已在合成层映射)。表单值变化:**Input/Textarea = onInput(原生)** ·
|
|
291
|
+
Select/RadioGroup/ToggleGroup = onChange(合成)——设计自洽(DOM 名直映 + 语义
|
|
292
|
+
回调二分)——**不提供双名别名**(单源——防双面漂移)
|
|
293
|
+
- 语义色变体:success/warning/error(状态语义)· primary/secondary/ghost/danger
|
|
294
|
+
(变量语义)——行业惯例对齐(antd/shadcn 同——不跨组件统一枚举)
|
|
295
|
+
- **改名判负**(2027-09 评估):组件/参数大改名为破坏性变更(对外消费者 v0.93+);
|
|
296
|
+
现状命名已自洽(Pascal×slug×DOM 名直映)——收益<成本——**翻转条件**:下一版
|
|
297
|
+
大版本(v1.0)预发面 + 迁移脚本
|
|
298
|
+
|
|
231
299
|
---
|
|
232
300
|
|
|
233
301
|
### 6.1 认证接线范式(fullstack W4——onRefresh 时序契约)
|
|
@@ -313,5 +381,70 @@ debounce(reload)——触发读最新 q。
|
|
|
313
381
|
|
|
314
382
|
---
|
|
315
383
|
|
|
384
|
+
### 5.11 分层抽象(2027-09——三层各上浮为可生成的抽象)
|
|
385
|
+
|
|
386
|
+
> 哲学:组件 = **契约 + 默认皮**——行为正确性由契约结构性保证,皮只是样式/结构
|
|
387
|
+
> 自由面。开发者三用法(每层同构):**用现成** · **换皮** · **拓场景**。
|
|
388
|
+
|
|
389
|
+
#### ① 行为契约 hooks(vdom 层——`ctx.ui.*`)
|
|
390
|
+
|
|
391
|
+
| 契约 | 语义 | 首个消费 |
|
|
392
|
+
| --- | --- | --- |
|
|
393
|
+
| `useSignal(init)` | 局部状态原语(set 自动重渲染——getter 纪律) | 新组件 |
|
|
394
|
+
| `useOverlay(opts)` | 弹层开/关/焦点困禁/Esc/滚动锁/遮罩(sync 渲染期) | Modal |
|
|
395
|
+
| `useField(opts)` | label/error/hint/aria 连接(label for·invalid·describedby) | Input |
|
|
396
|
+
|
|
397
|
+
**换皮示例**(自绘弹层——行为全契约):
|
|
398
|
+
```ts
|
|
399
|
+
const ov = ctx.ui.useOverlay({ open, onOpenChange, role: 'dialog' })
|
|
400
|
+
const root = h('div', { class: 'my-panel', ...ov.panelProps }, [
|
|
401
|
+
h('div', { class: 'my-mask', ...ov.maskProps }),
|
|
402
|
+
h('div', { class: 'my-body' }, children),
|
|
403
|
+
])
|
|
404
|
+
ov.sync(() => root, { open, maskClosable: false }) // 渲染期同步
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
#### ② 组件抽象(components 层——`createComponent` / `createItem`)
|
|
408
|
+
|
|
409
|
+
**抽象单位判据(原语全面化 W3 判负调查定案——2027-09)**:
|
|
410
|
+
组件 = **容器 + 可交互子项**(Tabs 的 tab / Segmented 的 option)——状态类和
|
|
411
|
+
aria 布尔几乎总在**子项**(43 组件含状态面 · 12 组件同条件类+aria 双面)。
|
|
412
|
+
两种抽象按单位选:
|
|
413
|
+
|
|
414
|
+
- **`createComponent`**(组件即元素——Button 型):声明(class 词根 ·
|
|
415
|
+
enumStates 直拼/映射 · boolStates 显式 · ariaBools · role · render 皮)
|
|
416
|
+
——机械面生成,结构/内容/事件自由。首个消费:Button。全库匹配面窄(
|
|
417
|
+
多形态/子项面/单拼接/数值 aria 均判负——登记)。
|
|
418
|
+
```ts
|
|
419
|
+
const Button = createComponent({ class: 'wf-btn', enumStates: { variant: null } })
|
|
420
|
+
```
|
|
421
|
+
- **`createItem`**(交互元素 props 生成器——子项/单元素组件):声明
|
|
422
|
+
(cls/suffix/role/aria/ariaText/roving)→ `(active, extra) => props`。
|
|
423
|
+
类后缀 + aria 布尔**捆绑声明**(改一面漏一面 = a11y bug——单源回报)。
|
|
424
|
+
aria 布尔直传内核(归一 'true'/'false'——**禁手写三元**);ariaText 文本值
|
|
425
|
+
(非 active undefined 移除语义);extra.class **追加**(disabled/focus 第
|
|
426
|
+
二类面共存)。首个消费:Tabs/9 组件。
|
|
427
|
+
```ts
|
|
428
|
+
const tab = createItem({ cls: 'wf-tab', role: 'tab', aria: 'aria-selected', roving: true })
|
|
429
|
+
h('button', tab(key === active, { onClick }), label)
|
|
430
|
+
```
|
|
431
|
+
边界(诚实):单活动态(Menu current+expanded 双状态判负——多槽设计后迁);
|
|
432
|
+
aria 多值(Tree 'mixed')判负。
|
|
433
|
+
|
|
434
|
+
判据(两者):**声明比实现短且机械部分全消失**(防配置地狱)。
|
|
435
|
+
|
|
436
|
+
#### ③ 布局原语(layout 层——`defineLayout`)
|
|
437
|
+
|
|
438
|
+
声明(class/base/defaults/variants——组合缺省内建 · 零优先级默认 · 变体
|
|
439
|
+
继承基)→ 生成器 → CSS。首个迁移:row/stack/items 族(生成 = 旧手写逐
|
|
440
|
+
属性等价)。断点变体声明即有(bp 面后续波次)。
|
|
441
|
+
```ts
|
|
442
|
+
structure({ class: 'wf-row', base: { display: 'flex', 'flex-wrap': 'wrap' },
|
|
443
|
+
defaults: { gap: 'var(--wf-gap, var(--wf-gap-md))' } })
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
> **存量零改动原则**:抽象是**增量**(新组件/维护组件走契约)——存量组件
|
|
447
|
+
> 行为零回归(每波契约全量回归门)。
|
|
448
|
+
|
|
316
449
|
> **运行**:`npm run test:client`(428 契约)· `npm run test:scenario`(123 场景)·
|
|
317
450
|
> `npm run test:showcase`(324 组件测试)——全量防线见 AGENTS.md §1。
|
package/docs/layout.md
CHANGED
|
@@ -43,23 +43,23 @@
|
|
|
43
43
|
| `wf-absolute` | _position.css | position · position:absolute | — | — |
|
|
44
44
|
| `wf-app-shell` | _app-shell.css | display · grid-template-columns · height · overflow · display:grid · overflow:visible | — | — |
|
|
45
45
|
| `wf-block` | _block.css | display · display:block | — | — |
|
|
46
|
-
| `wf-center` |
|
|
46
|
+
| `wf-center` | _stack.css | align-items · display · flex-direction · justify-content · display:flex · flex-direction:column · align-items:… | — | — |
|
|
47
47
|
| `wf-cluster` | _cluster.css | align-items · display · flex-wrap · gap · justify-content · display:flex · flex-wrap:wrap · justify-content:va… | — | — |
|
|
48
48
|
| `wf-container` | _container.css | margin · max-width · padding · width | — | — |
|
|
49
|
-
| `wf-cover` |
|
|
49
|
+
| `wf-cover` | _stack.css | align-items · display · inset · justify-content · position · z-index · position:fixed · display:flex · align-i… | — | — |
|
|
50
50
|
| `wf-dim` | _hidden.css | opacity | — | — |
|
|
51
|
-
| `wf-fill` |
|
|
52
|
-
| `wf-fill-hover` |
|
|
51
|
+
| `wf-fill` | _stack.css | flex · min-height · min-width · flex:1 | — | — |
|
|
52
|
+
| `wf-fill-hover` | _stack.css | border-radius · margin · padding · transition | — | — |
|
|
53
53
|
| `wf-flex` | _flex.css | display · display:flex | @@lg @@sm | — |
|
|
54
|
-
| `wf-grid` |
|
|
54
|
+
| `wf-grid` | _stack.css | display · gap · grid-template-columns · display:grid | — | — |
|
|
55
55
|
| `wf-hidden` | _hidden.css | display · display:none | @@lg | — |
|
|
56
|
-
| `wf-items-center` |
|
|
57
|
-
| `wf-items-end` |
|
|
58
|
-
| `wf-items-start` |
|
|
59
|
-
| `wf-items-stretch` |
|
|
60
|
-
| `wf-justify-between` |
|
|
61
|
-
| `wf-justify-center` |
|
|
62
|
-
| `wf-justify-end` |
|
|
56
|
+
| `wf-items-center` | _stack.css | | — | — |
|
|
57
|
+
| `wf-items-end` | _stack.css | | — | — |
|
|
58
|
+
| `wf-items-start` | _stack.css | | — | — |
|
|
59
|
+
| `wf-items-stretch` | _stack.css | | — | — |
|
|
60
|
+
| `wf-justify-between` | _stack.css | align-items · display · gap · justify-content · display:flex · justify-content:space-between · align-items:var… | — | — |
|
|
61
|
+
| `wf-justify-center` | _stack.css | align-items · display · gap · justify-content · display:flex · justify-content:center · align-items:var(--wf-a… | — | — |
|
|
62
|
+
| `wf-justify-end` | _stack.css | align-items · display · gap · justify-content · display:flex · justify-content:flex-end · align-items:var(--wf… | — | — |
|
|
63
63
|
| `wf-layer` | _layer.css | position · z-index · position:relative | — | — |
|
|
64
64
|
| `wf-main` | _app-shell.css | background · margin-inline · max-width · min-height · min-width · overflow · overflow-y · padding · overflow:v… | — | — |
|
|
65
65
|
| `wf-min-width-0` | _shrink.css | min-width | — | — |
|
|
@@ -74,8 +74,8 @@
|
|
|
74
74
|
| `wf-overflow-x` | _overflow.css | overflow-x | — | — |
|
|
75
75
|
| `wf-pointer` | _hidden.css | cursor | — | — |
|
|
76
76
|
| `wf-relative` | _position.css | position · position:relative | — | — |
|
|
77
|
-
| `wf-row` |
|
|
78
|
-
| `wf-row-reverse` |
|
|
77
|
+
| `wf-row` | _stack.css | align-items · display · flex-wrap · gap · display:flex · flex-wrap:wrap · align-items:var(--wf-align, center) | — | — |
|
|
78
|
+
| `wf-row-reverse` | _stack.css | align-items · display · flex-direction · flex-wrap · gap · display:flex · flex-wrap:wrap · flex-direction:row-… | — | — |
|
|
79
79
|
| `wf-safe-bottom` | _safe-area.css | padding-bottom | — | — |
|
|
80
80
|
| `wf-safe-top` | _safe-area.css | padding-top | — | — |
|
|
81
81
|
| `wf-self-center` | _align-self.css | align-self | — | — |
|
package/docs/server.md
CHANGED
|
@@ -160,7 +160,7 @@ app.post('/api/notes', async (req, ctx) => {
|
|
|
160
160
|
### 1.3 段③:前端页面组件(useAsyncData 8 行——页面跑起来)
|
|
161
161
|
|
|
162
162
|
```tsx
|
|
163
|
-
import { h } from 'weifuwu/vdom'
|
|
163
|
+
import { h } from 'weifuwu/client/vdom'
|
|
164
164
|
const NotesPage: Component = (_p, ctx) => {
|
|
165
165
|
const [get] = ctx.ui.useAsyncData(fetchNotes, 'notes-page') // 唯一异步边界
|
|
166
166
|
return () => h('ul', {}, (get() ?? []).map((n) => h('li', {}, n.title)))
|
package/package.json
CHANGED
|
@@ -1,36 +1,90 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "weifuwu",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.94.0",
|
|
5
5
|
"description": "AI SaaS full-stack framework — backend HTTP + frontend VDOM + 129 components + CSS design system + SaaS foundation (auth/queue/AI). Zero-build, zero-dependency.",
|
|
6
6
|
"exports": {
|
|
7
7
|
".": {
|
|
8
8
|
"types": "./dist/server/index.d.ts",
|
|
9
9
|
"default": "./dist/server/index.js"
|
|
10
10
|
},
|
|
11
|
-
"./
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
"./server": {
|
|
12
|
+
"types": "./dist/server/index.d.ts",
|
|
13
|
+
"default": "./dist/server/index.js"
|
|
14
|
+
},
|
|
15
|
+
"./server/ai": {
|
|
16
|
+
"types": "./dist/server/ai/index.d.ts",
|
|
17
|
+
"default": "./dist/server/ai/index.js"
|
|
18
|
+
},
|
|
19
|
+
"./server/email": {
|
|
20
|
+
"types": "./dist/server/email/index.d.ts",
|
|
21
|
+
"default": "./dist/server/email/index.js"
|
|
22
|
+
},
|
|
23
|
+
"./server/messager": {
|
|
24
|
+
"types": "./dist/server/messager/index.d.ts",
|
|
25
|
+
"default": "./dist/server/messager/index.js"
|
|
26
|
+
},
|
|
27
|
+
"./server/postgres": {
|
|
28
|
+
"types": "./dist/server/postgres/index.d.ts",
|
|
29
|
+
"default": "./dist/server/postgres/index.js"
|
|
30
|
+
},
|
|
31
|
+
"./server/queue": {
|
|
32
|
+
"types": "./dist/server/queue/index.d.ts",
|
|
33
|
+
"default": "./dist/server/queue/index.js"
|
|
34
|
+
},
|
|
35
|
+
"./server/redis": {
|
|
36
|
+
"types": "./dist/server/redis/index.d.ts",
|
|
37
|
+
"default": "./dist/server/redis/index.js"
|
|
16
38
|
},
|
|
17
|
-
"./
|
|
18
|
-
|
|
19
|
-
|
|
39
|
+
"./server/scheduler": {
|
|
40
|
+
"types": "./dist/server/scheduler/index.d.ts",
|
|
41
|
+
"default": "./dist/server/scheduler/index.js"
|
|
42
|
+
},
|
|
43
|
+
"./server/ui": {
|
|
44
|
+
"types": "./dist/server/ui/index.d.ts",
|
|
45
|
+
"default": "./dist/server/ui/index.js"
|
|
46
|
+
},
|
|
47
|
+
"./server/user": {
|
|
48
|
+
"types": "./dist/server/user/index.d.ts",
|
|
49
|
+
"default": "./dist/server/user/index.js"
|
|
50
|
+
},
|
|
51
|
+
"./server/workflows": {
|
|
52
|
+
"types": "./dist/server/workflows/index.d.ts",
|
|
53
|
+
"default": "./dist/server/workflows/index.js"
|
|
54
|
+
},
|
|
55
|
+
"./server/workflow": {
|
|
20
56
|
"types": "./dist/server/workflow/index.d.ts",
|
|
21
57
|
"default": "./dist/server/workflow/index.js"
|
|
22
58
|
},
|
|
23
|
-
"./vdom": {
|
|
59
|
+
"./client/vdom": {
|
|
24
60
|
"types": "./dist/client/vdom/index.d.ts",
|
|
25
61
|
"default": "./dist/client/vdom/index.js"
|
|
26
62
|
},
|
|
27
|
-
"./vdom/jsx-runtime": {
|
|
63
|
+
"./client/vdom/jsx-runtime": {
|
|
28
64
|
"types": "./dist/client/vdom/index.d.ts",
|
|
29
65
|
"default": "./dist/client/vdom/jsx-runtime.js"
|
|
30
66
|
},
|
|
31
|
-
"./vdom/testing": {
|
|
67
|
+
"./client/vdom/testing": {
|
|
32
68
|
"types": "./dist/client/vdom/testing.d.ts",
|
|
33
69
|
"default": "./dist/client/vdom/testing.js"
|
|
70
|
+
},
|
|
71
|
+
"./client/components": {
|
|
72
|
+
"types": "./dist/client/components/index.d.ts",
|
|
73
|
+
"default": "./dist/client/components/index.js"
|
|
74
|
+
},
|
|
75
|
+
"./client/components/style.css": "./dist/client/components/style.css",
|
|
76
|
+
"./client/layout": {
|
|
77
|
+
"types": "./dist/client/layout/index.d.ts",
|
|
78
|
+
"default": "./dist/client/layout/index.js"
|
|
79
|
+
},
|
|
80
|
+
"./client/layout/weifuwu-layout.css": "./dist/client/layout/weifuwu-layout.css",
|
|
81
|
+
"./dev": {
|
|
82
|
+
"types": "./dist/dev/index.d.ts",
|
|
83
|
+
"default": "./dist/dev/index.js"
|
|
84
|
+
},
|
|
85
|
+
"./shared/router": {
|
|
86
|
+
"types": "./dist/shared/router/index.d.ts",
|
|
87
|
+
"default": "./dist/shared/router/index.js"
|
|
34
88
|
}
|
|
35
89
|
},
|
|
36
90
|
"files": [
|