koishi-plugin-filter-pro 1.0.14 → 1.0.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{icons as e,message as t,send as n}from"@koishijs/client";import{Fragment as r,Teleport as i,computed as a,createBlock as o,createCommentVNode as s,createElementBlock as c,createElementVNode as l,createTextVNode as u,createVNode as d,defineComponent as f,normalizeClass as p,normalizeStyle as m,onBeforeUnmount as h,onMounted as g,openBlock as _,ref as v,renderList as y,resolveComponent as b,toDisplayString as x,vModelText as S,watch as C,withCtx as w,withDirectives as T}from"vue";const E=[`disabled`],D={class:`label`},O=[`onClick`];var k=f({__name:`fp-select`,props:{modelValue:{type:String,required:!0},options:{type:Array,required:!0},placeholder:{type:String,required:!1},disabled:{type:Boolean,required:!1}},emits:[`update:modelValue`],setup(e,{emit:t}){let n=e,u=t,d=v(null),f=v(!1),b=v({left:0,top:0,width:0}),S=a(()=>n.options.find(e=>e.value===n.modelValue)?.label||``);function w(){n.disabled||(f.value=!f.value,f.value&&A())}function T(e){u(`update:modelValue`,e),f.value=!1}function k(e){let t=e.target;!d.value||!t||d.value.contains(t)||(f.value=!1)}function A(){if(!d.value)return;let e=d.value.getBoundingClientRect(),t=window.innerHeight-e.bottom-6,n=e.top-6,r=t<180&&n>t,i=Math.min(240,r?n:t);b.value={left:e.left,width:e.width,top:r?Math.max(8,e.top-Math.max(120,i)-6):e.bottom+6}}function j(){f.value&&A()}return C(f,e=>{e&&A()}),g(()=>{document.addEventListener(`click`,k),window.addEventListener(`resize`,j),window.addEventListener(`scroll`,j,!0)}),h(()=>{document.removeEventListener(`click`,k),window.removeEventListener(`resize`,j),window.removeEventListener(`scroll`,j,!0)}),(t,n)=>(_(),c(r,null,[l(`div`,{class:`fp-select`,ref_key:`root`,ref:d},[l(`button`,{type:`button`,class:p([`trigger`,{disabled:e.disabled}]),onClick:w,disabled:e.disabled},[l(`span`,D,x(S.value||e.placeholder),1),n[0]||=l(`span`,{class:`arrow`},`▾`,-1)],10,E)],512),(_(),o(i,{to:`body`},[f.value?(_(),c(`div`,{key:0,class:`menu`,style:m({left:`${b.value.left}px`,top:`${b.value.top}px`,width:`${b.value.width}px`})},[(_(!0),c(r,null,y(e.options,t=>(_(),c(`button`,{key:t.value,type:`button`,class:p([`item`,{active:t.value===e.modelValue}]),onClick:e=>T(t.value)},x(t.label),11,O))),128))],4)):s(`v-if`,!0)]))],64))}}),A=(e,t)=>{let n=e.__vccOpts||e;for(let[e,r]of t)n[e]=r;return n},j=A(k,[[`__scopeId`,`data-v-4a262c3e`]]);const M={class:`cf-editor`},N={class:`rows-section`},P={key:0,class:`connector-sep`},F=[`title`,`onClick`],I={class:`cf-row`},L=[`onUpdate:modelValue`],R={key:1,class:`bool-toggle`},z=[`checked`,`onChange`],ee={class:`bool-label`},B=[`onUpdate:modelValue`,`onInput`],te=[`disabled`,`onClick`],ne={class:`add-section`},re={class:`preview-section`},ie={class:`preview-code`};var V=A(f({name:`ExprEditor`,__name:`expr-editor`,props:{modelValue:{type:Object,required:!0}},emits:[`update:modelValue`],setup(e,{emit:t}){let n=0,i=()=>String(++n),f=[{value:`guildId`,label:`群组 ID(guildId)`},{value:`channelId`,label:`频道 ID(channelId)`},{value:`userId`,label:`用户 ID(userId)`},{value:`platform`,label:`平台(platform)`},{value:`content`,label:`消息内容(content)`},{value:`isDirect`,label:`私聊(isDirect)`},{value:`type`,label:`消息类型(type)`}],m=[...f,{value:`__custom__`,label:`自定义字段...`}],h=[{value:`eq`,label:`等于`},{value:`ne`,label:`不等于`},{value:`includes`,label:`包含`},{value:`regex`,label:`正则匹配`},{value:`gt`,label:`大于`},{value:`gte`,label:`大于等于`},{value:`lt`,label:`小于`},{value:`lte`,label:`小于等于`},{value:`exists`,label:`存在`}],g=[{value:`eq`,label:`等于`},{value:`ne`,label:`不等于`},{value:`exists`,label:`存在`}],E={eq:`eq`,ne:`ne`,includes:`contains`,regex:`matches`,gt:`gt`,gte:`gte`,lt:`lt`,lte:`lte`,exists:`exists`},D=e,O=t,k=v(U(D.modelValue)),A=JSON.stringify(D.modelValue);C(()=>D.modelValue,e=>{let t=JSON.stringify(e);t!==A&&(A=t,k.value=U(e))},{deep:!0});function V(e,t=`guildId`){let n=t===`isDirect`;return{id:i(),field:t,customField:``,operator:`eq`,valueText:n?`false`:``,value:n?!1:``,connector:e}}function H(e,t){let n=f.some(t=>t.value===e.field),r=n?e.field:`__custom__`,a=r===`isDirect`?!1:``,o=e.value??a;return{id:i(),field:r,customField:n?``:e.field,operator:e.operator,valueText:o==null?``:String(o),value:o,connector:t}}function U(e){if(!e)return[V(null)];if(e.type===`compare`)return[H(e,null)];if(e.type===`group`){if(e.children.every(e=>e.type===`compare`))return e.children.map((t,n)=>H(t,n===0?null:e.operator));if(e.operator===`or`){let t=[],n=!0;for(let r of e.children)r.type===`compare`?(t.push(H(r,n?null:`or`)),n=!1):r.type===`group`&&r.operator===`and`&&r.children.forEach((e,r)=>{e.type===`compare`&&(t.push(H(e,n?null:r===0?`or`:`and`)),n=!1)});if(t.length>0)return t}}return[V(null)]}function W(e){return{type:`compare`,field:e.field===`__custom__`?(e.customField||``).trim()||`guildId`:e.field,operator:e.operator,value:e.operator===`exists`?void 0:e.value}}function G(e){if(e.length===0)return{type:`compare`,field:`guildId`,operator:`eq`,value:``};if(e.length===1)return W(e[0]);let t=[],n=[e[0]];for(let r=1;r<e.length;r++)e[r].connector===`or`?(t.push(n),n=[e[r]]):n.push(e[r]);t.push(n);let r=t.map(e=>e.length===1?W(e[0]):{type:`group`,operator:`and`,children:e.map(W)});return r.length===1?r[0]:{type:`group`,operator:`or`,children:r}}function K(e){if(e.type===`compare`){let t=E[e.operator]||e.operator,n=e.value===void 0?``:JSON.stringify(e.value);return`(${e.field} ${t} ${n})`}if(e.type===`group`){let t=e.operator===`and`?` AND `:` OR `;return e.children.map(K).join(t)}return e.type===`not`?`NOT (${K(e.child)})`:``}let q=a(()=>K(G(k.value)));function J(){let e=G(k.value);A=JSON.stringify(e),O(`update:modelValue`,e)}function Y(e){k.value.push(V(e??`and`)),J()}function X(e){k.value.length<=1||(k.value.splice(e,1),e===0&&(k.value[0].connector=null),J())}function Z(e){e<=0||(k.value[e].connector=k.value[e].connector===`or`?`and`:`or`,J())}function Q(e){let t=e.trim();if(!t)return``;if(t===`true`)return!0;if(t===`false`)return!1;if(t===`null`)return null;let n=Number(t);return Number.isFinite(n)?n:e}return(e,t)=>{let n=b(`k-button`);return _(),c(`div`,M,[s(` 条件行 `),l(`div`,N,[(_(!0),c(r,null,y(k.value,(e,t)=>(_(),c(r,{key:e.id},[s(` 连接符(第一行之后显示) `),t>0?(_(),c(`div`,P,[l(`button`,{class:p([`connector-toggle`,`conn-`+e.connector]),title:`点击切换为`+(e.connector===`or`?`且(AND)`:`或(OR)`),onClick:e=>Z(t)},x(e.connector===`or`?`或(OR)`:`且(AND)`),11,F)])):s(`v-if`,!0),s(` 条件行 `),l(`div`,I,[d(j,{"model-value":e.field,options:m,class:`sel-field`,"onUpdate:modelValue":t=>{let n=e.field===`isDirect`;e.field=t,t===`isDirect`?(e.value=!1,e.valueText=`false`,[`eq`,`ne`,`exists`].includes(e.operator)||(e.operator=`eq`)):n&&(e.value=``,e.valueText=``),J()}},null,8,[`model-value`,`onUpdate:modelValue`]),e.field===`__custom__`?T((_(),c(`input`,{key:0,class:`input custom-input`,"onUpdate:modelValue":t=>e.customField=t,onInput:J,placeholder:`字段路径,如 author.name`},null,40,L)),[[S,e.customField]]):s(`v-if`,!0),d(j,{"model-value":e.operator,options:e.field===`isDirect`?g:h,class:`sel-op`,"onUpdate:modelValue":t=>{e.operator=t,J()}},null,8,[`model-value`,`options`,`onUpdate:modelValue`]),s(` isDirect:开关 `),e.field===`isDirect`&&e.operator!==`exists`?(_(),c(`label`,R,[l(`input`,{type:`checkbox`,checked:e.value===!0,onChange:t=>{e.value=t.target.checked,e.valueText=String(e.value),J()}},null,40,z),l(`span`,ee,x(e.value===!0?`是(true)`:`否(false)`),1)])):e.field!==`isDirect`&&e.operator!==`exists`?(_(),c(r,{key:2},[s(` 普通文本输入 `),T(l(`input`,{class:`input val-input`,"onUpdate:modelValue":t=>e.valueText=t,onInput:()=>{e.value=Q(e.valueText),J()},placeholder:`比较值`},null,40,B),[[S,e.valueText]])],2112)):s(`v-if`,!0),l(`button`,{class:`del-btn`,disabled:k.value.length<=1,onClick:e=>X(t),title:`删除此条件`},`✕`,8,te)])],64))),128))]),s(` 添加条件 `),l(`div`,ne,[k.value.length===0?(_(),o(n,{key:0,onClick:t[0]||=e=>Y(null)},{default:w(()=>[...t[3]||=[u(`+ 添加条件`,-1)]]),_:1})):(_(),c(r,{key:1},[d(n,{onClick:t[1]||=e=>Y(`and`)},{default:w(()=>[...t[4]||=[u(`且(AND)`,-1)]]),_:1}),d(n,{onClick:t[2]||=e=>Y(`or`)},{default:w(()=>[...t[5]||=[u(`或(OR)`,-1)]]),_:1})],64))]),s(` 表达式预览 `),l(`div`,re,[t[6]||=l(`div`,{class:`preview-title`},`表达式预览`,-1),l(`code`,ie,x(q.value||`(空)`),1)])])}}}),[[`__scopeId`,`data-v-40533e84`]]);const H={class:`fp-layout`},U={class:`fp-main`},W={class:`editor-header`},G={class:`rule-list`},K=[`onClick`],q={class:`top`},J={class:`name`},Y={class:`meta`},X={class:`editor-header`},Z={class:`actions`},Q={class:`editor-body`},ae={class:`editor-grid`},oe={class:`field`},se={class:`field`},ce={key:0,class:`field`},le={class:`field`},ue={class:`field`},de={class:`field switch`},fe={class:`expr-wrap`},pe={class:`footer-actions`};var $=A(f({__name:`page`,setup(e){let i=n,f={bypass:`放行`,block:`拦截`},m=[{label:`全局`,value:`global`},{label:`插件`,value:`plugin`}],h=[{label:`放行(bypass)`,value:`bypass`},{label:`拦截(block)`,value:`block`}],g=a(()=>[{label:`请选择插件实例`,value:``},...E.value.map(e=>({label:e.label,value:e.key}))]),C=v([]),E=v([]),D=v(``),O=a(()=>[...C.value].sort((e,t)=>e.priority-t.priority||e.id.localeCompare(t.id))),k=a(()=>O.value.find(e=>e.id===D.value));function A(){return{type:`group`,operator:`and`,children:[{type:`compare`,field:`guildId`,operator:`eq`,value:``}]}}async function M(){let[e,n]=await Promise.all([i(`filter-pro/list`),i(`filter-pro/targets`)]);E.value=n,C.value=e,(!D.value||!C.value.some(e=>e.id===D.value))&&(D.value=O.value[0]?.id||``),t.success(`刷新成功`)}async function N(){await i(`filter-pro/create`,{name:`new-rule`,enabled:!0,priority:(O.value.at(-1)?.priority??-1)+1,action:`block`,target:{type:`global`,value:``},condition:A(),response:``}),await M(),D.value=O.value.at(-1)?.id||D.value,t.success(`创建成功`)}function P(e){let t=e.target,n=Number(t.value);(n<1||!Number.isInteger(n))&&(t.value=String(Math.max(1,Math.floor(Math.abs(n))||1)),k.value&&(k.value.priority=Number(t.value)))}async function F(e){e.enabled=!e.enabled,await i(`filter-pro/toggle`,{id:e.id,enabled:e.enabled})}async function I(e){let n=e.target.type===`global`?{type:`global`,value:``}:{type:`plugin`,value:e.target.value||``};await i(`filter-pro/update`,{id:e.id,name:e.name,enabled:e.enabled,priority:e.priority,action:e.action,target:n,condition:e.condition,response:e.response||``}),await M(),t.success(`保存成功`)}async function L(){k.value&&confirm(`确定要删除这条规则吗?`)&&await R(k.value.id)}async function R(e){await i(`filter-pro/delete`,e),await M(),t.success(`删除成功`)}async function z(e,t){let n=O.value,r=n.findIndex(t=>t.id===e);if(r<0)return;let a=r+t;if(a<0||a>=n.length)return;let o=[...n];[o[r],o[a]]=[o[a],o[r]],await i(`filter-pro/reorder`,o.map(e=>e.id)),await M()}return M(),(e,t)=>{let n=b(`k-button`),i=b(`k-card`),a=b(`k-layout`);return _(),o(a,null,{default:w(()=>[l(`div`,H,[l(`div`,U,[d(i,{class:`panel list`},{header:w(()=>[l(`div`,W,[t[11]||=l(`div`,{class:`panel-title`},`规则列表`,-1),d(n,{onClick:N},{default:w(()=>[...t[10]||=[u(`新建规则`,-1)]]),_:1})])]),default:w(()=>[l(`div`,G,[(_(!0),c(r,null,y(O.value,e=>(_(),c(`button`,{key:e.id,class:p([`rule-item`,{active:D.value===e.id}]),onClick:t=>D.value=e.id},[l(`div`,q,[l(`span`,J,x(e.name||`未命名规则`),1),l(`span`,{class:p([`badge`,e.action])},x(f[e.action]),3)]),l(`div`,Y,[l(`span`,null,`#`+x(e.priority),1),l(`span`,null,x(e.target.type===`global`?`全局`:e.target.value||`未指定插件`),1),l(`span`,null,x(e.enabled?`启用`:`停用`),1)])],10,K))),128))])]),_:1}),k.value?(_(),o(i,{key:0,class:`panel editor`},{header:w(()=>[l(`div`,X,[t[15]||=l(`div`,{class:`panel-title`},`规则编辑`,-1),l(`div`,Z,[d(n,{onClick:t[0]||=e=>k.value&&I(k.value),disabled:!k.value},{default:w(()=>[...t[12]||=[u(`保存`,-1)]]),_:1},8,[`disabled`]),d(n,{onClick:L,disabled:!k.value},{default:w(()=>[...t[13]||=[u(`删除`,-1)]]),_:1},8,[`disabled`]),d(n,{onClick:M},{default:w(()=>[...t[14]||=[u(`刷新`,-1)]]),_:1})])])]),default:w(()=>[l(`div`,Q,[l(`div`,ae,[l(`label`,oe,[t[16]||=l(`span`,null,`规则名`,-1),T(l(`input`,{class:`input`,"onUpdate:modelValue":t[1]||=e=>k.value.name=e,placeholder:`输入规则名`},null,512),[[S,k.value.name]])]),l(`label`,se,[t[17]||=l(`span`,null,`目标`,-1),d(j,{modelValue:k.value.target.type,"onUpdate:modelValue":t[2]||=e=>k.value.target.type=e,options:m},null,8,[`modelValue`])]),k.value.target.type===`plugin`?(_(),c(`label`,ce,[t[18]||=l(`span`,null,`插件实例`,-1),d(j,{"model-value":k.value.target.value??``,options:g.value,"onUpdate:modelValue":t[3]||=e=>k.value.target.value=e},null,8,[`model-value`,`options`])])):s(`v-if`,!0),l(`label`,le,[t[19]||=l(`span`,null,`动作`,-1),d(j,{modelValue:k.value.action,"onUpdate:modelValue":t[4]||=e=>k.value.action=e,options:h},null,8,[`modelValue`])]),l(`label`,ue,[t[20]||=l(`span`,null,`优先级`,-1),T(l(`input`,{class:`input`,type:`number`,min:`1`,step:`1`,"onUpdate:modelValue":t[5]||=e=>k.value.priority=e,onInput:P},null,544),[[S,k.value.priority,void 0,{number:!0}]])]),l(`label`,de,[t[22]||=l(`span`,null,`启用状态`,-1),l(`div`,{class:p([`toggle-switch`,{active:k.value.enabled}]),onClick:t[6]||=e=>F(k.value)},[...t[21]||=[l(`div`,{class:`toggle-thumb`},null,-1)]],2)])]),l(`div`,fe,[t[23]||=l(`div`,{class:`panel-title small`},`条件表达式`,-1),d(V,{modelValue:k.value.condition,"onUpdate:modelValue":t[7]||=e=>k.value.condition=e},null,8,[`modelValue`])]),l(`div`,pe,[d(n,{onClick:t[8]||=e=>z(k.value.id,-1)},{default:w(()=>[...t[24]||=[u(`上移`,-1)]]),_:1}),d(n,{onClick:t[9]||=e=>z(k.value.id,1)},{default:w(()=>[...t[25]||=[u(`下移`,-1)]]),_:1})])])]),_:1})):s(`v-if`,!0)])])]),_:1})}}}),[[`__scopeId`,`data-v-0e916acc`]]);const me={},he={class:`k-icon`,viewBox:`0 0 512 512`,xmlns:`http://www.w3.org/2000/svg`};function ge(e,t){return _(),c(`svg`,he,[s(` 漏斗主体 `),t[0]||=l(`path`,{fill:`none`,stroke:`currentColor`,"stroke-width":`32`,"stroke-linejoin":`round`,d:`M487.976 0H24.028C2.71 0-8.047 25.866 7.058 40.971L192 225.941V432c0 7.831 3.821 15.17 10.237 19.662l80 55.98C298.02 518.69 320 507.493 320 487.98V225.941l184.947-184.97C520.021 25.896 509.338 0 487.976 0z`},null,-1)])}var _e=A(me,[[`render`,ge]]),ve=t=>{e.register(`activity:filter-pro`,_e),t.page({name:`规则集`,path:`/filter-pro`,icon:`activity:filter-pro`,order:320,component:$})};export{ve as default};
1
+ import{icons as e,message as t,send as n}from"@koishijs/client";import{Fragment as r,Teleport as i,computed as a,createBlock as o,createCommentVNode as s,createElementBlock as c,createElementVNode as l,createTextVNode as u,createVNode as d,defineComponent as f,normalizeClass as p,normalizeStyle as m,onBeforeUnmount as h,onMounted as g,openBlock as _,ref as v,renderList as y,resolveComponent as b,toDisplayString as x,vModelText as S,watch as C,withCtx as w,withDirectives as T,withKeys as E,withModifiers as D}from"vue";const O=[`disabled`],k={class:`label`},A=[`onClick`];var j=f({__name:`fp-select`,props:{modelValue:{type:String,required:!0},options:{type:Array,required:!0},placeholder:{type:String,required:!1},disabled:{type:Boolean,required:!1}},emits:[`update:modelValue`],setup(e,{emit:t}){let n=e,u=t,d=v(null),f=v(!1),b=v({left:0,top:0,width:0}),S=a(()=>n.options.find(e=>e.value===n.modelValue)?.label||``);function w(){n.disabled||(f.value=!f.value,f.value&&D())}function T(e){u(`update:modelValue`,e),f.value=!1}function E(e){let t=e.target;!d.value||!t||d.value.contains(t)||(f.value=!1)}function D(){if(!d.value)return;let e=d.value.getBoundingClientRect(),t=window.innerHeight-e.bottom-6,n=e.top-6,r=t<180&&n>t,i=Math.min(240,r?n:t);b.value={left:e.left,width:e.width,top:r?Math.max(8,e.top-Math.max(120,i)-6):e.bottom+6}}function j(){f.value&&D()}return C(f,e=>{e&&D()}),g(()=>{document.addEventListener(`click`,E),window.addEventListener(`resize`,j),window.addEventListener(`scroll`,j,!0)}),h(()=>{document.removeEventListener(`click`,E),window.removeEventListener(`resize`,j),window.removeEventListener(`scroll`,j,!0)}),(t,n)=>(_(),c(r,null,[l(`div`,{class:`fp-select`,ref_key:`root`,ref:d},[l(`button`,{type:`button`,class:p([`trigger`,{disabled:e.disabled}]),onClick:w,disabled:e.disabled},[l(`span`,k,x(S.value||e.placeholder),1),n[0]||=l(`span`,{class:`arrow`},`▾`,-1)],10,O)],512),(_(),o(i,{to:`body`},[f.value?(_(),c(`div`,{key:0,class:`menu`,style:m({left:`${b.value.left}px`,top:`${b.value.top}px`,width:`${b.value.width}px`})},[(_(!0),c(r,null,y(e.options,t=>(_(),c(`button`,{key:t.value,type:`button`,class:p([`item`,{active:t.value===e.modelValue}]),onClick:e=>T(t.value)},x(t.label),11,A))),128))],4)):s(`v-if`,!0)]))],64))}}),M=(e,t)=>{let n=e.__vccOpts||e;for(let[e,r]of t)n[e]=r;return n},N=M(j,[[`__scopeId`,`data-v-4a262c3e`]]);const P={class:`chip-text`},F=[`onClick`],I=[`placeholder`,`onKeydown`];var L=M(f({name:`TagInput`,__name:`tag-input`,props:{modelValue:{type:Array,required:!0},placeholder:{type:String,required:!1}},emits:[`update:modelValue`],setup(e,{emit:t}){let n=e,i=t,a=v(null),o=v(``),u=v(!1);function d(){a.value?.focus()}function f(){let e=o.value.trim();e&&(n.modelValue.includes(e)||i(`update:modelValue`,[...n.modelValue,e]),o.value=``)}function m(e){let t=[...n.modelValue];t.splice(e,1),i(`update:modelValue`,t)}function h(){i(`update:modelValue`,[]),o.value=``}function g(){o.value===``&&n.modelValue.length>0&&m(n.modelValue.length-1)}function b(){let e=o.value.trim();e&&!n.modelValue.includes(e)&&i(`update:modelValue`,[...n.modelValue,e]),o.value=``,u.value=!1}return(t,n)=>(_(),c(`div`,{class:p([`tag-input-wrap`,{"is-focused":u.value}]),onClick:d},[(_(!0),c(r,null,y(e.modelValue,(e,t)=>(_(),c(`span`,{key:t,class:`tag-chip`},[l(`span`,P,x(e),1),l(`button`,{class:`chip-del`,onClick:D(e=>m(t),[`stop`]),tabindex:`-1`,title:`移除`},`×`,8,F)]))),128)),T(l(`input`,{ref_key:`inputEl`,ref:a,class:`tag-text-input`,"onUpdate:modelValue":n[0]||=e=>o.value=e,placeholder:e.modelValue.length===0?e.placeholder??``:``,onKeydown:[E(D(f,[`prevent`]),[`enter`]),E(g,[`backspace`])],onFocus:n[1]||=e=>u.value=!0,onBlur:b},null,40,I),[[S,o.value]]),e.modelValue.length>0?(_(),c(`button`,{key:0,class:`tag-clear-btn`,onClick:D(h,[`stop`]),tabindex:`-1`,title:`清空`},`×`)):s(`v-if`,!0)],2))}}),[[`__scopeId`,`data-v-8e9ea736`]]);const R={class:`cf-editor`},z={class:`rows-section`},B={key:0,class:`conn-and-wrap`},V={class:`cf-row`},H=[`onUpdate:modelValue`],U={key:1,class:`bool-toggle`},W=[`checked`,`onChange`],G={class:`bool-label`},ee=[`onUpdate:modelValue`,`onInput`,`placeholder`],te={class:`row-btns`},ne=[`disabled`,`onClick`],re={key:0,class:`add-section`},ie={class:`preview-section`},ae={class:`preview-code`};var K=M(f({name:`ExprEditor`,__name:`expr-editor`,props:{modelValue:{type:Object,required:!0}},emits:[`update:modelValue`],setup(e,{emit:t}){let n=0,i=()=>String(++n),f=[{value:`guildId`,label:`群组 ID(guildId)`},{value:`channelId`,label:`频道 ID(channelId)`},{value:`userId`,label:`用户 ID(userId)`},{value:`platform`,label:`平台(platform)`},{value:`content`,label:`消息内容(content)`},{value:`isDirect`,label:`私聊(isDirect)`},{value:`type`,label:`消息类型(type)`}],m=[...f,{value:`__custom__`,label:`自定义字段...`}],h=[{value:`eq`,label:`等于`},{value:`ne`,label:`不等于`},{value:`in`,label:`等于以下各项`},{value:`nin`,label:`不等于以下各项`},{value:`includes`,label:`包含以下各项`},{value:`notincludes`,label:`不包含以下各项`},{value:`regex`,label:`正则匹配`},{value:`gt`,label:`大于`},{value:`gte`,label:`大于等于`},{value:`lt`,label:`小于`},{value:`lte`,label:`小于等于`},{value:`exists`,label:`存在`}],g=[{value:`eq`,label:`等于`},{value:`ne`,label:`不等于`},{value:`exists`,label:`存在`}],E={eq:`eq`,ne:`ne`,in:`in`,nin:`nin`,includes:`contains`,notincludes:`not-contains`,regex:`matches`,gt:`gt`,gte:`gte`,lt:`lt`,lte:`lte`,exists:`exists`},D=e,O=t,k=v(P(D.modelValue)),A=JSON.stringify(D.modelValue);C(()=>D.modelValue,e=>{let t=JSON.stringify(e);t!==A&&(A=t,k.value=P(e))},{deep:!0});function j(e,t=`guildId`){let n=t===`isDirect`;return{id:i(),field:t,customField:``,operator:`eq`,valueText:n?`false`:``,value:n?!1:``,connector:e}}function M(e,t){let n=f.some(t=>t.value===e.field),r=n?e.field:`__custom__`,a=Q(e.operator),o=r===`isDirect`?!1:a?[]:``,s=e.value??o;return a&&(typeof s==`string`?s=s?s.split(/[,,]/).map(e=>e.trim()).filter(Boolean):[]:Array.isArray(s)||(s=[])),{id:i(),field:r,customField:n?``:e.field,operator:e.operator,valueText:Array.isArray(s)||s==null?``:String(s),value:s,connector:t}}function P(e){if(!e)return[j(null)];if(e.type===`compare`)return[M(e,null)];if(e.type===`group`){if(e.children.every(e=>e.type===`compare`))return e.children.map((t,n)=>M(t,n===0?null:e.operator));if(e.operator===`or`){let t=[],n=!0;for(let r of e.children)r.type===`compare`?(t.push(M(r,n?null:`or`)),n=!1):r.type===`group`&&r.operator===`and`&&r.children.forEach((e,r)=>{e.type===`compare`&&(t.push(M(e,n?null:r===0?`or`:`and`)),n=!1)});if(t.length>0)return t}}return[j(null)]}function F(e){return{type:`compare`,field:e.field===`__custom__`?(e.customField||``).trim()||`guildId`:e.field,operator:e.operator,value:e.operator===`exists`?void 0:e.value}}function I(e){if(e.length===0)return{type:`compare`,field:`guildId`,operator:`eq`,value:``};if(e.length===1)return F(e[0]);let t=[],n=[e[0]];for(let r=1;r<e.length;r++)e[r].connector===`or`?(t.push(n),n=[e[r]]):n.push(e[r]);t.push(n);let r=t.map(e=>e.length===1?F(e[0]):{type:`group`,operator:`and`,children:e.map(F)});return r.length===1?r[0]:{type:`group`,operator:`or`,children:r}}function K(e){if(e.type===`compare`){let t=E[e.operator]||e.operator,n;return n=e.value===void 0?``:Array.isArray(e.value)?`{${e.value.map(e=>JSON.stringify(e)).join(` `)}}`:JSON.stringify(e.value),`(${e.field} ${t} ${n})`}if(e.type===`group`){let t=e.operator===`and`?` AND `:` OR `;return e.children.map(K).join(t)}return e.type===`not`?`NOT (${K(e.child)})`:``}let q=a(()=>K(I(k.value)));function J(){let e=I(k.value);A=JSON.stringify(e),O(`update:modelValue`,e)}function Y(e){k.value.push(j(e??`and`)),J()}function X(e,t){k.value.splice(e+1,0,j(t)),J()}function oe(e){k.value.length<=1||(k.value.splice(e,1),e===0&&(k.value[0].connector=null),J())}function Z(e){e<=0||(k.value[e].connector=k.value[e].connector===`or`?`and`:`or`,J())}function se(e){let t=e.trim();if(!t)return``;if(t===`true`)return!0;if(t===`false`)return!1;if(t===`null`)return null;let n=Number(t);return Number.isFinite(n)?n:e}function Q(e){return[`in`,`nin`,`includes`,`notincludes`].includes(e)}function $(e){return Q(e)?`输入后按 Enter 添加`:`比较值`}return(e,t)=>{let n=b(`k-button`);return _(),c(`div`,R,[s(` 条件行 `),l(`div`,z,[(_(!0),c(r,null,y(k.value,(e,i)=>(_(),c(r,{key:e.id},[s(` 连接符(第一行之后显示) `),i>0?(_(),c(`div`,{key:0,class:p([`connector-sep`,`conn-`+e.connector])},[s(` AND:细线 + 按钮 + 细线 `),e.connector===`and`?(_(),c(`div`,B,[t[2]||=l(`div`,{class:`conn-vline`},null,-1),d(n,{title:`点击切换为或(OR)`,onClick:e=>Z(i)},{default:w(()=>[...t[1]||=[u(`且(AND)`,-1)]]),_:1},8,[`onClick`]),t[3]||=l(`div`,{class:`conn-vline`},null,-1)])):(_(),c(r,{key:1},[s(` OR:仅按钮 `),d(n,{title:`点击切换为且(AND)`,onClick:e=>Z(i)},{default:w(()=>[...t[4]||=[u(`或(OR)`,-1)]]),_:1},8,[`onClick`])],2112))],2)):s(`v-if`,!0),s(` 条件行 `),l(`div`,V,[d(N,{"model-value":e.field,options:m,class:`sel-field`,"onUpdate:modelValue":t=>{let n=e.field===`isDirect`;e.field=t,t===`isDirect`?(e.value=!1,e.valueText=`false`,[`eq`,`ne`,`exists`].includes(e.operator)||(e.operator=`eq`)):n&&(e.value=Q(e.operator)?[]:``,e.valueText=``),J()}},null,8,[`model-value`,`onUpdate:modelValue`]),e.field===`__custom__`?T((_(),c(`input`,{key:0,class:`input custom-input`,"onUpdate:modelValue":t=>e.customField=t,onInput:J,placeholder:`字段路径,如 author.name`},null,40,H)),[[S,e.customField]]):s(`v-if`,!0),d(N,{"model-value":e.operator,options:e.field===`isDirect`?g:h,class:`sel-op`,"onUpdate:modelValue":t=>{let n=Q(e.operator),r=Q(t);e.operator=t,r&&!n?(e.value=[],e.valueText=``):!r&&n&&(e.value=``,e.valueText=``),J()}},null,8,[`model-value`,`options`,`onUpdate:modelValue`]),s(` isDirect:开关 `),e.field===`isDirect`&&e.operator!==`exists`?(_(),c(`label`,U,[l(`input`,{type:`checkbox`,checked:e.value===!0,onChange:t=>{e.value=t.target.checked,e.valueText=String(e.value),J()}},null,40,W),l(`span`,G,x(e.value===!0?`是(true)`:`否(false)`),1)])):e.field!==`isDirect`&&e.operator!==`exists`&&Q(e.operator)?(_(),c(r,{key:2},[s(` 数组操作符:Tag 输入 `),d(L,{"model-value":Array.isArray(e.value)?e.value:[],placeholder:$(e.operator),"onUpdate:modelValue":t=>{e.value=t,J()}},null,8,[`model-value`,`placeholder`,`onUpdate:modelValue`])],2112)):e.field!==`isDirect`&&e.operator!==`exists`?(_(),c(r,{key:3},[s(` 普通文本输入 `),T(l(`input`,{class:`input val-input`,"onUpdate:modelValue":t=>e.valueText=t,onInput:()=>{e.value=se(e.valueText),J()},placeholder:$(e.operator)},null,40,ee),[[S,e.valueText]])],2112)):s(`v-if`,!0),l(`div`,te,[d(n,{onClick:e=>X(i,`and`)},{default:w(()=>[...t[5]||=[u(`且(AND)`,-1)]]),_:1},8,[`onClick`]),i===k.value.length-1?(_(),o(n,{key:0,onClick:e=>X(i,`or`)},{default:w(()=>[...t[6]||=[u(`或(OR)`,-1)]]),_:1},8,[`onClick`])):s(`v-if`,!0)]),l(`button`,{class:`del-btn`,disabled:k.value.length<=1,onClick:e=>oe(i),title:`删除此条件`},` ✕ `,8,ne)])],64))),128))]),s(` 添加条件(仅空状态) `),k.value.length===0?(_(),c(`div`,re,[d(n,{onClick:t[0]||=e=>Y(null)},{default:w(()=>[...t[7]||=[u(`+ 添加条件`,-1)]]),_:1})])):s(`v-if`,!0),s(` 表达式预览 `),l(`div`,ie,[t[8]||=l(`div`,{class:`preview-title`},`表达式预览`,-1),l(`code`,ae,x(q.value||`(空)`),1)])])}}}),[[`__scopeId`,`data-v-40533e84`]]);const q={class:`plugin-selector`},J={class:`label`},Y={class:`dialog-header`},X={class:`dialog-body`},oe={class:`toolbar`},Z={class:`checkbox-item select-all`},se=[`checked`],Q=[`placeholder`],$={class:`plugin-list`},ce=[`value`,`checked`,`onChange`],le={key:0,class:`empty-state`};var ue=M(f({__name:`plugin-selector`,props:{modelValue:{type:Array,required:!0},options:{type:Array,required:!0},mode:{type:String,required:!1}},emits:[`update:modelValue`],setup(e,{emit:t}){let n=e,u=t,d=v(!1),f=v(``),p=v([...n.modelValue]),m=a(()=>n.mode===`command`),h=a(()=>m.value?`选择指令`:`选择插件实例`),g=a(()=>m.value?`搜索指令...`:`搜索插件...`),b=a(()=>m.value?`没有找到匹配的指令`:`没有找到匹配的插件`),w=a(()=>{let e=m.value?`指令`:`插件`,t=m.value?`请选择指令`:`请选择插件实例`;return p.value.length===0?t:p.value.length===1?n.options.find(e=>e.key===p.value[0])?.label||`已选择 1 个${e}`:`已选择 ${p.value.length} 个${e}`}),E=a(()=>{if(!f.value)return n.options;let e=f.value.toLowerCase();return n.options.filter(t=>t.label.toLowerCase().includes(e))}),O=a(()=>E.value.length>0&&E.value.every(e=>p.value.includes(e.key)));function k(e){let t=p.value.indexOf(e);t>-1?p.value.splice(t,1):p.value.push(e)}function A(e){if(e.target.checked)for(let e of E.value)p.value.includes(e.key)||p.value.push(e.key);else p.value=p.value.filter(e=>!E.value.some(t=>t.key===e))}function j(){u(`update:modelValue`,[...p.value]),d.value=!1}function M(){p.value=[...n.modelValue],d.value=!1}return C(()=>n.modelValue,e=>{p.value=[...e]}),C(d,e=>{e&&(f.value=``)}),(e,t)=>(_(),c(`div`,q,[s(` 触发按钮 `),l(`button`,{type:`button`,class:`trigger-btn`,onClick:t[0]||=e=>d.value=!0},[l(`span`,J,x(w.value),1),t[5]||=l(`span`,{class:`arrow`},`▾`,-1)]),s(` 多选对话框 `),(_(),o(i,{to:`body`},[d.value?(_(),c(`div`,{key:0,class:`dialog-overlay`,onClick:t[4]||=e=>d.value=!1},[l(`div`,{class:`dialog-content`,onClick:t[3]||=D(()=>{},[`stop`])},[l(`div`,Y,[l(`h3`,null,x(h.value),1),l(`button`,{class:`close-btn`,onClick:t[1]||=e=>d.value=!1},`✕`)]),l(`div`,X,[s(` 搜索和全选 `),l(`div`,oe,[l(`label`,Z,[l(`input`,{type:`checkbox`,checked:O.value,onChange:A},null,40,se),t[6]||=l(`span`,null,`全选`,-1)]),T(l(`input`,{"onUpdate:modelValue":t[2]||=e=>f.value=e,class:`search-input`,placeholder:g.value},null,8,Q),[[S,f.value]])]),s(` 插件/指令列表 `),l(`div`,$,[(_(!0),c(r,null,y(E.value,e=>(_(),c(`label`,{key:e.key,class:`checkbox-item`},[l(`input`,{type:`checkbox`,value:e.key,checked:p.value.includes(e.key),onChange:t=>k(e.key)},null,40,ce),l(`span`,null,x(e.label),1)]))),128)),E.value.length===0?(_(),c(`div`,le,x(b.value),1)):s(`v-if`,!0)])]),l(`div`,{class:`dialog-footer`},[l(`button`,{class:`btn btn-cancel`,onClick:M},`取消`),l(`button`,{class:`btn btn-confirm`,onClick:j},`确定`)])])])):s(`v-if`,!0)]))]))}}),[[`__scopeId`,`data-v-6b39c823`]]);const de={class:`fp-layout`},fe={class:`fp-main`},pe={class:`editor-header`},me={class:`rule-list`},he=[`onClick`],ge={class:`top`},_e={class:`name`},ve={class:`meta`},ye={class:`editor-header`},be={class:`actions`},xe={class:`editor-body`},Se={class:`editor-grid`},Ce={class:`field`},we={class:`field`},Te={key:0,class:`field`},Ee={key:1,class:`field`},De={class:`field`},Oe={class:`field`},ke={class:`field switch`},Ae={class:`expr-wrap`},je={class:`footer-actions`},Me={class:`confirm-dialog`},Ne={class:`confirm-actions`};var Pe=M(f({__name:`page`,setup(e){let f=n,m={bypass:`放行`,block:`拦截`},h=[{label:`全局`,value:`global`},{label:`插件`,value:`plugin`},{label:`指令`,value:`command`}],g=[{label:`放行(bypass)`,value:`bypass`},{label:`拦截(block)`,value:`block`}];a(()=>[{label:`请选择插件实例`,value:``},...O.value.map(e=>({label:e.label,value:e.key}))]);let E=v([]),O=v([]),k=v([]),A=v(``),j=v(!1),M=a(()=>[...E.value].sort((e,t)=>e.priority-t.priority||e.id.localeCompare(t.id))),P=a(()=>M.value.find(e=>e.id===A.value));function F(e){return e.type===`global`?`全局`:e.type===`plugin`?Array.isArray(e.value)?e.value.length>0?`插件 (${e.value.length})`:`未指定插件`:e.value||`未指定插件`:e.type===`command`?Array.isArray(e.value)?e.value.length>0?`指令 (${e.value.length})`:`未指定指令`:e.value||`未指定指令`:`未知`}C(()=>P.value?.target.type,(e,t)=>{e&&t&&e!==t&&P.value&&(P.value.target.value=e===`global`?``:[])});function I(){return{type:`group`,operator:`and`,children:[{type:`compare`,field:`guildId`,operator:`eq`,value:``}]}}async function L(){let[e,n,r]=await Promise.all([f(`filter-pro/list`),f(`filter-pro/targets`),f(`filter-pro/commands`)]);O.value=n,k.value=r,E.value=e,(!A.value||!E.value.some(e=>e.id===A.value))&&(A.value=M.value[0]?.id||``),t.success(`刷新成功`)}async function R(){await f(`filter-pro/create`,{name:`new-rule`,enabled:!0,priority:(M.value.at(-1)?.priority??-1)+1,action:`block`,target:{type:`global`,value:``},condition:I(),response:``}),await L(),A.value=M.value.at(-1)?.id||A.value,t.success(`创建成功`)}function z(e){let t=e.target,n=Number(t.value);(n<1||!Number.isInteger(n))&&(t.value=String(Math.max(1,Math.floor(Math.abs(n))||1)),P.value&&(P.value.priority=Number(t.value)))}async function B(e){e.enabled=!e.enabled,await f(`filter-pro/toggle`,{id:e.id,enabled:e.enabled})}async function V(e){let n;n=e.target.type===`global`?{type:`global`,value:``}:e.target.type===`plugin`?{type:`plugin`,value:e.target.value||[]}:{type:`command`,value:e.target.value||[]},await f(`filter-pro/update`,{id:e.id,name:e.name,enabled:e.enabled,priority:e.priority,action:e.action,target:n,condition:e.condition,response:e.response||``}),await L(),t.success(`保存成功`)}async function H(){P.value&&(j.value=!0)}async function U(){j.value=!1,P.value&&await W(P.value.id)}async function W(e){await f(`filter-pro/delete`,e),await L(),t.success(`删除成功`)}async function G(e,t){let n=M.value,r=n.findIndex(t=>t.id===e);if(r<0)return;let i=r+t;if(i<0||i>=n.length)return;let a=[...n];[a[r],a[i]]=[a[i],a[r]],await f(`filter-pro/reorder`,a.map(e=>e.id)),await L()}return L(),(e,t)=>{let n=b(`k-button`),a=b(`k-card`),f=b(`k-layout`);return _(),c(r,null,[d(f,null,{default:w(()=>[l(`div`,de,[l(`div`,fe,[d(a,{class:`panel list`},{header:w(()=>[l(`div`,pe,[t[14]||=l(`div`,{class:`panel-title`},`规则列表`,-1),d(n,{onClick:R},{default:w(()=>[...t[13]||=[u(`新建规则`,-1)]]),_:1})])]),default:w(()=>[l(`div`,me,[(_(!0),c(r,null,y(M.value,e=>(_(),c(`button`,{key:e.id,class:p([`rule-item`,{active:A.value===e.id}]),onClick:t=>A.value=e.id},[l(`div`,ge,[l(`span`,_e,x(e.name||`未命名规则`),1),l(`span`,{class:p([`badge`,e.action])},x(m[e.action]),3)]),l(`div`,ve,[l(`span`,null,`#`+x(e.priority),1),l(`span`,null,x(F(e.target)),1),l(`span`,null,x(e.enabled?`启用`:`停用`),1)])],10,he))),128))])]),_:1}),P.value?(_(),o(a,{key:0,class:`panel editor`},{header:w(()=>[l(`div`,ye,[t[18]||=l(`div`,{class:`panel-title`},`规则编辑`,-1),l(`div`,be,[d(n,{onClick:t[0]||=e=>P.value&&V(P.value),disabled:!P.value},{default:w(()=>[...t[15]||=[u(`保存`,-1)]]),_:1},8,[`disabled`]),d(n,{onClick:H,disabled:!P.value},{default:w(()=>[...t[16]||=[u(`删除`,-1)]]),_:1},8,[`disabled`]),d(n,{onClick:L},{default:w(()=>[...t[17]||=[u(`刷新`,-1)]]),_:1})])])]),default:w(()=>[l(`div`,xe,[l(`div`,Se,[l(`label`,Ce,[t[19]||=l(`span`,null,`规则名`,-1),T(l(`input`,{class:`input`,"onUpdate:modelValue":t[1]||=e=>P.value.name=e,placeholder:`输入规则名`},null,512),[[S,P.value.name]])]),l(`label`,we,[t[20]||=l(`span`,null,`目标`,-1),d(N,{modelValue:P.value.target.type,"onUpdate:modelValue":t[2]||=e=>P.value.target.type=e,options:h},null,8,[`modelValue`])]),s(` 插件多选 `),P.value.target.type===`plugin`?(_(),c(`label`,Te,[t[21]||=l(`span`,null,`插件实例`,-1),d(ue,{mode:`plugin`,"model-value":Array.isArray(P.value.target.value)?P.value.target.value:P.value.target.value?[P.value.target.value]:[],options:O.value,"onUpdate:modelValue":t[3]||=e=>P.value.target.value=e},null,8,[`model-value`,`options`])])):s(`v-if`,!0),s(` 指令多选 `),P.value.target.type===`command`?(_(),c(`label`,Ee,[t[22]||=l(`span`,null,`作用指令`,-1),d(ue,{mode:`command`,"model-value":Array.isArray(P.value.target.value)?P.value.target.value:P.value.target.value?[P.value.target.value]:[],options:k.value.map(e=>({key:e.name,name:e.name,ident:``,label:e.label})),"onUpdate:modelValue":t[4]||=e=>P.value.target.value=e},null,8,[`model-value`,`options`])])):s(`v-if`,!0),l(`label`,De,[t[23]||=l(`span`,null,`动作`,-1),d(N,{modelValue:P.value.action,"onUpdate:modelValue":t[5]||=e=>P.value.action=e,options:g},null,8,[`modelValue`])]),l(`label`,Oe,[t[24]||=l(`span`,null,`优先级`,-1),T(l(`input`,{class:`input`,type:`number`,min:`1`,step:`1`,"onUpdate:modelValue":t[6]||=e=>P.value.priority=e,onInput:z},null,544),[[S,P.value.priority,void 0,{number:!0}]])]),l(`label`,ke,[t[26]||=l(`span`,null,`启用状态`,-1),l(`div`,{class:p([`toggle-switch`,{active:P.value.enabled}]),onClick:t[7]||=e=>B(P.value)},[...t[25]||=[l(`div`,{class:`toggle-thumb`},null,-1)]],2)])]),l(`div`,Ae,[t[27]||=l(`div`,{class:`panel-title small`},`条件表达式`,-1),d(K,{modelValue:P.value.condition,"onUpdate:modelValue":t[8]||=e=>P.value.condition=e},null,8,[`modelValue`])]),l(`div`,je,[d(n,{onClick:t[9]||=e=>G(P.value.id,-1)},{default:w(()=>[...t[28]||=[u(`上移`,-1)]]),_:1}),d(n,{onClick:t[10]||=e=>G(P.value.id,1)},{default:w(()=>[...t[29]||=[u(`下移`,-1)]]),_:1})])])]),_:1})):s(`v-if`,!0)])])]),_:1}),s(` 删除确认弹窗 `),(_(),o(i,{to:`body`},[j.value?(_(),c(`div`,{key:0,class:`confirm-overlay`,onClick:t[12]||=D(e=>j.value=!1,[`self`])},[l(`div`,Me,[t[31]||=l(`div`,{class:`confirm-title`},`删除规则`,-1),t[32]||=l(`div`,{class:`confirm-body`},`确定要删除这条规则吗?此操作不可撤销。`,-1),l(`div`,Ne,[d(n,{onClick:t[11]||=e=>j.value=!1},{default:w(()=>[...t[30]||=[u(`取消`,-1)]]),_:1}),l(`button`,{class:`confirm-danger-btn`,onClick:U},`确认删除`)])])])):s(`v-if`,!0)]))],64)}}}),[[`__scopeId`,`data-v-0e916acc`]]);const Fe={},Ie={class:`k-icon`,viewBox:`0 0 512 512`,xmlns:`http://www.w3.org/2000/svg`};function Le(e,t){return _(),c(`svg`,Ie,[s(` 漏斗主体 `),t[0]||=l(`path`,{fill:`none`,stroke:`currentColor`,"stroke-width":`32`,"stroke-linejoin":`round`,d:`M487.976 0H24.028C2.71 0-8.047 25.866 7.058 40.971L192 225.941V432c0 7.831 3.821 15.17 10.237 19.662l80 55.98C298.02 518.69 320 507.493 320 487.98V225.941l184.947-184.97C520.021 25.896 509.338 0 487.976 0z`},null,-1)])}var Re=M(Fe,[[`render`,Le]]),ze=t=>{e.register(`activity:filter-pro`,Re),t.page({name:`规则集`,path:`/filter-pro`,icon:`activity:filter-pro`,order:320,component:Pe})};export{ze as default};
package/dist/style.css CHANGED
@@ -5,6 +5,8 @@
5
5
  }
6
6
  .trigger[data-v-4a262c3e] {
7
7
  width: 100%;
8
+ height: 35px;
9
+ box-sizing: border-box;
8
10
  display: flex;
9
11
  align-items: center;
10
12
  justify-content: space-between;
@@ -51,6 +53,96 @@
51
53
  }
52
54
 
53
55
 
56
+ .tag-input-wrap[data-v-8e9ea736] {
57
+ display: flex;
58
+ flex-wrap: wrap;
59
+ align-items: center;
60
+ gap: 4px;
61
+ flex: 1;
62
+ min-width: 160px;
63
+ min-height: 35px;
64
+ box-sizing: border-box;
65
+ padding: 4px 8px;
66
+ background: var(--k-input-bg, transparent);
67
+ border: 1px solid var(--k-card-border, rgba(127, 127, 127, 0.35));
68
+ border-radius: 6px;
69
+ cursor: text;
70
+ transition: border-color 0.15s;
71
+ }
72
+ .tag-input-wrap.is-focused[data-v-8e9ea736] {
73
+ border-color: var(--k-color-primary, #4f7cff);
74
+ }
75
+ .tag-chip[data-v-8e9ea736] {
76
+ display: inline-flex;
77
+ align-items: center;
78
+ gap: 2px;
79
+ background: color-mix(in srgb, var(--k-color-primary, #4f7cff) 15%, transparent);
80
+ border: 1px solid color-mix(in srgb, var(--k-color-primary, #4f7cff) 50%, transparent);
81
+ border-radius: 4px;
82
+ padding: 1px 4px 1px 8px;
83
+ font-size: 13px;
84
+ color: var(--k-text-normal, inherit);
85
+ white-space: nowrap;
86
+ line-height: 1.6;
87
+ }
88
+ .chip-text[data-v-8e9ea736] {
89
+ line-height: 1.4;
90
+ }
91
+ .chip-del[data-v-8e9ea736] {
92
+ display: inline-flex;
93
+ align-items: center;
94
+ justify-content: center;
95
+ width: 16px;
96
+ height: 16px;
97
+ border: none;
98
+ background: none;
99
+ color: var(--k-text-secondary, #888);
100
+ cursor: pointer;
101
+ padding: 0;
102
+ font-size: 15px;
103
+ border-radius: 3px;
104
+ line-height: 1;
105
+ flex-shrink: 0;
106
+ }
107
+ .chip-del[data-v-8e9ea736]:hover {
108
+ background: color-mix(in srgb, #e74c3c 20%, transparent);
109
+ color: #e74c3c;
110
+ }
111
+ .tag-text-input[data-v-8e9ea736] {
112
+ flex: 1;
113
+ min-width: 80px;
114
+ border: none;
115
+ outline: none;
116
+ background: transparent;
117
+ color: var(--k-text-normal, inherit);
118
+ font-size: 14px;
119
+ padding: 0;
120
+ height: 22px;
121
+ }
122
+ .tag-text-input[data-v-8e9ea736]::placeholder {
123
+ color: var(--k-text-secondary, rgba(127, 127, 127, 0.6));
124
+ }
125
+ .tag-clear-btn[data-v-8e9ea736] {
126
+ display: inline-flex;
127
+ align-items: center;
128
+ justify-content: center;
129
+ width: 18px;
130
+ height: 18px;
131
+ border: none;
132
+ background: none;
133
+ color: var(--k-text-secondary, #888);
134
+ cursor: pointer;
135
+ padding: 0;
136
+ font-size: 16px;
137
+ border-radius: 50%;
138
+ margin-left: 2px;
139
+ flex-shrink: 0;
140
+ }
141
+ .tag-clear-btn[data-v-8e9ea736]:hover {
142
+ background: color-mix(in srgb, currentColor 15%, transparent);
143
+ }
144
+
145
+
54
146
  .cf-editor[data-v-40533e84] {
55
147
  display: flex;
56
148
  flex-direction: column;
@@ -61,29 +153,30 @@
61
153
  .connector-sep[data-v-40533e84] {
62
154
  display: flex;
63
155
  align-items: center;
64
- padding: 2px 0;
65
156
  }
66
- .connector-toggle[data-v-40533e84] {
67
- font-size: 12px;
68
- font-weight: 700;
69
- padding: 2px 12px;
70
- border-radius: 4px;
71
- border: 1px solid var(--k-card-border, rgba(127, 127, 127, 0.4));
72
- cursor: pointer;
73
- background: var(--k-input-bg, transparent);
74
- color: var(--k-text-normal, inherit);
75
- letter-spacing: 0.04em;
76
- transition: opacity 0.15s;
157
+
158
+ /* OR:按钮 + 上下内廝 */
159
+ .connector-sep.conn-or[data-v-40533e84] {
160
+ padding: 16px 0;
77
161
  }
78
- .connector-toggle[data-v-40533e84]:hover { opacity: 0.75;
162
+
163
+ /* AND:无额外内廝,由线提供等高间距 */
164
+ .connector-sep.conn-and[data-v-40533e84] {
165
+ padding: 0;
79
166
  }
80
- .connector-toggle.conn-and[data-v-40533e84] {
81
- border-color: var(--k-color-primary, #4f7cff);
82
- color: var(--k-color-primary, #4f7cff);
167
+
168
+ /* AND 内部:线 + 按钮 + 线,列居中 */
169
+ .conn-and-wrap[data-v-40533e84] {
170
+ display: inline-flex;
171
+ flex-direction: column;
172
+ align-items: center;
83
173
  }
84
- .connector-toggle.conn-or[data-v-40533e84] {
85
- border-color: #e67e22;
86
- color: #e67e22;
174
+
175
+ /* 上下细线,高度与 OR 内廝相同,颜色和边框一致 */
176
+ .conn-vline[data-v-40533e84] {
177
+ width: 1px;
178
+ height: 12px;
179
+ background: var(--k-card-border, rgba(127, 127, 127, 0.35));
87
180
  }
88
181
 
89
182
  /* ── 条件行 ── */
@@ -92,19 +185,19 @@
92
185
  align-items: center;
93
186
  gap: 8px;
94
187
  flex-wrap: wrap;
95
- padding: 8px 10px;
96
- border: 1px solid var(--k-card-border, rgba(127, 127, 127, 0.35));
97
- border-radius: 8px;
98
- background: color-mix(in srgb, var(--k-card-bg, #1a1a1a) 60%, transparent);
99
188
  }
100
- .sel-field[data-v-40533e84] { min-width: 168px;
189
+ .sel-field[data-v-40533e84] {
190
+ min-width: 168px;
101
191
  }
102
- .sel-op[data-v-40533e84] { min-width: 110px;
192
+ .sel-op[data-v-40533e84] {
193
+ min-width: 110px;
103
194
  }
104
195
  .val-input[data-v-40533e84],
105
196
  .custom-input[data-v-40533e84] {
106
197
  flex: 1;
107
198
  min-width: 120px;
199
+ height: 35px;
200
+ box-sizing: border-box;
108
201
  color: var(--k-text-normal, inherit);
109
202
  background: var(--k-input-bg, transparent);
110
203
  border: 1px solid var(--k-card-border, rgba(127, 127, 127, 0.35));
@@ -122,20 +215,20 @@
122
215
  flex: 1;
123
216
  min-width: 120px;
124
217
  }
125
- .bool-toggle input[type='checkbox'][data-v-40533e84] {
218
+ .bool-toggle input[type="checkbox"][data-v-40533e84] {
126
219
  appearance: none;
127
220
  -webkit-appearance: none;
128
221
  width: 36px;
129
222
  height: 20px;
130
223
  border-radius: 999px;
131
- background: var(--k-card-border, rgba(127,127,127,0.4));
224
+ background: var(--k-card-border, rgba(127, 127, 127, 0.4));
132
225
  position: relative;
133
226
  cursor: pointer;
134
227
  transition: background 0.2s;
135
228
  flex-shrink: 0;
136
229
  }
137
- .bool-toggle input[type='checkbox'][data-v-40533e84]::after {
138
- content: '';
230
+ .bool-toggle input[type="checkbox"][data-v-40533e84]::after {
231
+ content: "";
139
232
  position: absolute;
140
233
  width: 14px;
141
234
  height: 14px;
@@ -145,10 +238,10 @@
145
238
  left: 3px;
146
239
  transition: left 0.2s;
147
240
  }
148
- .bool-toggle input[type='checkbox'][data-v-40533e84]:checked {
241
+ .bool-toggle input[type="checkbox"][data-v-40533e84]:checked {
149
242
  background: var(--k-color-primary, #4f7cff);
150
243
  }
151
- .bool-toggle input[type='checkbox'][data-v-40533e84]:checked::after {
244
+ .bool-toggle input[type="checkbox"][data-v-40533e84]:checked::after {
152
245
  left: 19px;
153
246
  }
154
247
  .bool-label[data-v-40533e84] {
@@ -156,10 +249,19 @@
156
249
  color: var(--k-text-normal, inherit);
157
250
  user-select: none;
158
251
  }
252
+
253
+ /* ── 行内操作按钮(And / Or) ── */
254
+ .row-btns[data-v-40533e84] {
255
+ display: flex;
256
+ gap: 4px;
257
+ flex-shrink: 0;
258
+ margin-left: auto;
259
+ }
159
260
  .del-btn[data-v-40533e84] {
160
261
  flex-shrink: 0;
161
- width: 28px;
162
- height: 28px;
262
+ width: 35px;
263
+ height: 35px;
264
+ box-sizing: border-box;
163
265
  display: flex;
164
266
  align-items: center;
165
267
  justify-content: center;
@@ -169,8 +271,9 @@
169
271
  color: var(--k-text-secondary, #888);
170
272
  cursor: pointer;
171
273
  font-size: 14px;
172
- margin-left: auto;
173
- transition: color 0.15s, background 0.15s;
274
+ transition:
275
+ color 0.15s,
276
+ background 0.15s;
174
277
  }
175
278
  .del-btn[data-v-40533e84]:hover {
176
279
  color: #e74c3c;
@@ -204,7 +307,7 @@
204
307
  }
205
308
  .preview-code[data-v-40533e84] {
206
309
  display: block;
207
- font-family: 'Consolas', 'Monaco', 'Fira Code', monospace;
310
+ font-family: "Consolas", "Monaco", "Fira Code", monospace;
208
311
  font-size: 13px;
209
312
  background: color-mix(in srgb, #000 35%, transparent);
210
313
  padding: 10px 14px;
@@ -216,6 +319,187 @@
216
319
  }
217
320
 
218
321
 
322
+ .plugin-selector[data-v-6b39c823] {
323
+ position: relative;
324
+ min-width: 140px;
325
+ }
326
+ .trigger-btn[data-v-6b39c823] {
327
+ width: 100%;
328
+ display: flex;
329
+ align-items: center;
330
+ justify-content: space-between;
331
+ gap: 8px;
332
+ color: var(--k-text-normal, inherit);
333
+ background: var(--k-input-bg, transparent);
334
+ border: 1px solid var(--k-card-border, rgba(127, 127, 127, 0.35));
335
+ border-radius: 6px;
336
+ padding: 6px 10px;
337
+ cursor: pointer;
338
+ transition: border-color 0.2s;
339
+ }
340
+ .trigger-btn[data-v-6b39c823]:hover {
341
+ border-color: var(--k-color-primary, #4f7cff);
342
+ }
343
+ .label[data-v-6b39c823] {
344
+ overflow: hidden;
345
+ text-overflow: ellipsis;
346
+ white-space: nowrap;
347
+ flex: 1;
348
+ text-align: left;
349
+ }
350
+ .arrow[data-v-6b39c823] {
351
+ flex-shrink: 0;
352
+ }
353
+
354
+ /* 对话框 */
355
+ .dialog-overlay[data-v-6b39c823] {
356
+ position: fixed;
357
+ top: 0;
358
+ left: 0;
359
+ right: 0;
360
+ bottom: 0;
361
+ background: rgba(0, 0, 0, 0.5);
362
+ display: flex;
363
+ align-items: center;
364
+ justify-content: center;
365
+ z-index: 10000;
366
+ }
367
+ .dialog-content[data-v-6b39c823] {
368
+ background: var(--k-card-bg, #1e1e1e);
369
+ border: 1px solid var(--k-card-border, rgba(127, 127, 127, 0.35));
370
+ border-radius: 12px;
371
+ width: 90%;
372
+ max-width: 500px;
373
+ max-height: 80vh;
374
+ display: flex;
375
+ flex-direction: column;
376
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
377
+ }
378
+ .dialog-header[data-v-6b39c823] {
379
+ display: flex;
380
+ align-items: center;
381
+ justify-content: space-between;
382
+ padding: 16px 20px;
383
+ border-bottom: 1px solid var(--k-card-border, rgba(127, 127, 127, 0.2));
384
+ }
385
+ .dialog-header h3[data-v-6b39c823] {
386
+ margin: 0;
387
+ font-size: 16px;
388
+ font-weight: 600;
389
+ color: var(--k-text-normal, inherit);
390
+ }
391
+ .close-btn[data-v-6b39c823] {
392
+ width: 28px;
393
+ height: 28px;
394
+ display: flex;
395
+ align-items: center;
396
+ justify-content: center;
397
+ border: none;
398
+ border-radius: 6px;
399
+ background: transparent;
400
+ color: var(--k-text-secondary, #888);
401
+ cursor: pointer;
402
+ font-size: 18px;
403
+ transition: color 0.15s, background 0.15s;
404
+ }
405
+ .close-btn[data-v-6b39c823]:hover {
406
+ color: var(--k-text-normal, inherit);
407
+ background: color-mix(in srgb, var(--k-card-border, #888) 20%, transparent);
408
+ }
409
+ .dialog-body[data-v-6b39c823] {
410
+ flex: 1;
411
+ min-height: 0;
412
+ display: flex;
413
+ flex-direction: column;
414
+ padding: 16px 20px;
415
+ overflow: hidden;
416
+ }
417
+ .toolbar[data-v-6b39c823] {
418
+ display: flex;
419
+ align-items: center;
420
+ gap: 12px;
421
+ margin-bottom: 12px;
422
+ }
423
+ .select-all[data-v-6b39c823] {
424
+ flex-shrink: 0;
425
+ font-weight: 600;
426
+ }
427
+ .search-input[data-v-6b39c823] {
428
+ flex: 1;
429
+ min-width: 0;
430
+ color: var(--k-text-normal, inherit);
431
+ background: var(--k-input-bg, transparent);
432
+ border: 1px solid var(--k-card-border, rgba(127, 127, 127, 0.35));
433
+ border-radius: 6px;
434
+ padding: 6px 10px;
435
+ font-size: 14px;
436
+ }
437
+ .plugin-list[data-v-6b39c823] {
438
+ flex: 1;
439
+ min-height: 0;
440
+ overflow-y: auto;
441
+ display: flex;
442
+ flex-direction: column;
443
+ gap: 8px;
444
+ }
445
+ .checkbox-item[data-v-6b39c823] {
446
+ display: flex;
447
+ align-items: center;
448
+ gap: 8px;
449
+ padding: 8px;
450
+ border-radius: 6px;
451
+ cursor: pointer;
452
+ transition: background 0.15s;
453
+ user-select: none;
454
+ }
455
+ .checkbox-item[data-v-6b39c823]:hover {
456
+ background: color-mix(in srgb, var(--k-card-border, #888) 15%, transparent);
457
+ }
458
+ .checkbox-item input[type='checkbox'][data-v-6b39c823] {
459
+ width: 16px;
460
+ height: 16px;
461
+ cursor: pointer;
462
+ flex-shrink: 0;
463
+ }
464
+ .checkbox-item span[data-v-6b39c823] {
465
+ color: var(--k-text-normal, inherit);
466
+ font-size: 14px;
467
+ }
468
+ .empty-state[data-v-6b39c823] {
469
+ padding: 40px 20px;
470
+ text-align: center;
471
+ color: var(--k-text-secondary, #888);
472
+ }
473
+ .dialog-footer[data-v-6b39c823] {
474
+ display: flex;
475
+ align-items: center;
476
+ justify-content: flex-end;
477
+ gap: 8px;
478
+ padding: 16px 20px;
479
+ border-top: 1px solid var(--k-card-border, rgba(127, 127, 127, 0.2));
480
+ }
481
+ .btn[data-v-6b39c823] {
482
+ padding: 6px 16px;
483
+ border-radius: 6px;
484
+ border: none;
485
+ cursor: pointer;
486
+ font-size: 14px;
487
+ transition: opacity 0.15s;
488
+ }
489
+ .btn[data-v-6b39c823]:hover {
490
+ opacity: 0.85;
491
+ }
492
+ .btn-cancel[data-v-6b39c823] {
493
+ background: transparent;
494
+ color: var(--k-text-normal, inherit);
495
+ border: 1px solid var(--k-card-border, rgba(127, 127, 127, 0.35));
496
+ }
497
+ .btn-confirm[data-v-6b39c823] {
498
+ background: var(--k-color-primary, #4f7cff);
499
+ color: #fff;
500
+ }
501
+
502
+
219
503
  .fp-layout[data-v-0e916acc] {
220
504
  position: absolute;
221
505
  top: 0;
@@ -368,6 +652,7 @@
368
652
  .input[data-v-0e916acc] {
369
653
  width: 100%;
370
654
  min-width: 0;
655
+ height: 35px;
371
656
  box-sizing: border-box;
372
657
  color: var(--k-text-normal, inherit);
373
658
  background: var(--k-input-bg, transparent);
@@ -383,6 +668,61 @@
383
668
  gap: 8px;
384
669
  flex-wrap: wrap;
385
670
  }
671
+
672
+ /* ── 删除确认框 ── */
673
+ .confirm-overlay[data-v-0e916acc] {
674
+ position: fixed;
675
+ inset: 0;
676
+ z-index: 10000;
677
+ background: rgba(0, 0, 0, 0.55);
678
+ display: flex;
679
+ align-items: center;
680
+ justify-content: center;
681
+ }
682
+ .confirm-dialog[data-v-0e916acc] {
683
+ background: var(--k-card-bg, #1e1e1e);
684
+ border: 1px solid var(--k-card-border, rgba(127, 127, 127, 0.35));
685
+ border-radius: 12px;
686
+ padding: 24px 28px;
687
+ min-width: 320px;
688
+ max-width: 480px;
689
+ display: flex;
690
+ flex-direction: column;
691
+ gap: 12px;
692
+ box-shadow: 0 16px 48px rgba(0, 0, 0, 0.4);
693
+ }
694
+ .confirm-title[data-v-0e916acc] {
695
+ font-size: 16px;
696
+ font-weight: 700;
697
+ color: var(--k-text-normal, inherit);
698
+ }
699
+ .confirm-body[data-v-0e916acc] {
700
+ font-size: 14px;
701
+ color: var(--k-text-secondary, #aaa);
702
+ line-height: 1.6;
703
+ }
704
+ .confirm-actions[data-v-0e916acc] {
705
+ display: flex;
706
+ justify-content: flex-end;
707
+ gap: 8px;
708
+ margin-top: 4px;
709
+ }
710
+ .confirm-danger-btn[data-v-0e916acc] {
711
+ height: 35px;
712
+ box-sizing: border-box;
713
+ padding: 0 16px;
714
+ border-radius: 6px;
715
+ border: none;
716
+ background: #e74c3c;
717
+ color: #fff;
718
+ font-size: 14px;
719
+ font-weight: 600;
720
+ cursor: pointer;
721
+ transition: opacity 0.15s;
722
+ }
723
+ .confirm-danger-btn[data-v-0e916acc]:hover {
724
+ opacity: 0.85;
725
+ }
386
726
  @media (max-width: 980px) {
387
727
  .fp-main[data-v-0e916acc] {
388
728
  grid-template-columns: 1fr;
@@ -392,3 +732,9 @@
392
732
  }
393
733
  }
394
734
 
735
+
736
+ .k-button {
737
+ height: 35px !important;
738
+ box-sizing: border-box !important;
739
+ }
740
+
package/lib/index.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require(`koishi`),t=require(`@koishijs/plugin-console`),n=require(`node:path`),r=require(`node:fs/promises`);const i=e.Schema.object({filename:e.Schema.string().default(`rules.json`).description(`持久化文件名(位于 data/filterpro/ 下)。`),debug:e.Schema.boolean().default(!1).description(`输出规则匹配调试日志。`)}),a=Symbol.for(`koishi.loader.record`);var o=class extends t.DataService{constructor(e,t){super(e,`filter-pro`),this.state=t}async get(){return u(this.state.rules).map(c)}};function s(){return{type:`group`,operator:`and`,children:[{type:`compare`,field:`guildId`,operator:`eq`,value:``}]}}function c(e){return{id:e.id,name:e.name,enabled:e.enabled,priority:e.priority,action:e.action,target:{...e.target},condition:l(e.condition),response:e.response}}function l(e){return e.type===`group`?{type:`group`,operator:e.operator,children:e.children.map(l)}:e.type===`not`?{type:`not`,child:l(e.child)}:{type:`compare`,field:e.field,operator:e.operator,value:e.value}}function u(e){return[...e].sort((e,t)=>e.priority-t.priority||e.id.localeCompare(t.id))}function d(e){if(!e||typeof e!=`object`)return s();let t=e;if(t.type===`group`)return{type:`group`,operator:t.operator===`or`?`or`:`and`,children:Array.isArray(t.children)?t.children.map(d):[]};if(t.type===`not`)return{type:`not`,child:d(t.child)};let n=[`eq`,`ne`,`includes`,`regex`,`gt`,`gte`,`lt`,`lte`,`exists`].includes(t.operator)?t.operator:`eq`;return{type:`compare`,field:typeof t.field==`string`?t.field:`content`,operator:n,value:t.value}}function f(t){let n=t.target||{type:`global`},r=typeof n.value==`string`?n.value.trim():``,i=n.type===`plugin`?r:``,a={type:n.type===`plugin`?`plugin`:`global`,value:i};return{id:t.id||e.Random.id(8),name:t.name||`new-rule`,enabled:t.enabled??!0,priority:t.priority??0,action:t.action||`block`,target:a,condition:d(t.condition),response:t.response??``}}function p(e,t){if(!e||e.type===`global`)return!0;let n=typeof t.pluginKey==`string`?t.pluginKey:``,r=e.value?.trim();return r?n===r:!1}function m(e){let t=[],n=new Set,r=new Set,i=e=>{let o=e?.scope?.[a];if(!(!o||r.has(o))){r.add(o);for(let[e,r]of Object.entries(o)){let a=String(e).replace(/^~/,``),[o,s=``]=a.split(`:`,2);r?.runtime?.plugin?.filter!==!1&&(o&&o!==`group`&&!n.has(a)&&(n.add(a),t.push({key:a,name:o,ident:s,label:s?`${o}:${s}`:o})),i(r?.ctx))}}};return i(e.root),t.sort((e,t)=>e.key.localeCompare(t.key))}function h(e){let t=new Map,n=new Set,r=e=>{let i=e?.scope?.[a];if(!(!i||n.has(i))){n.add(i);for(let[e,n]of Object.entries(i)){let i=String(e).replace(/^~/,``);t.set(i,n),r(n?.ctx)}}};return r(e.root),t}function g(e,t){let n=[],r=new Map,i=new Map,o=new WeakMap,s=t=>{if(!t)return;let n=r.get(t);if(n)return n;let a=e.loader;if(a?.paths){let e=a.paths(t);for(let t of e||[]){let e=String(t).replace(/^~/,``),n=i.get(e);if(n)return n}}};return{rebuild:()=>{n=m(e),r.clear(),i.clear();for(let e of n)i.set(e.key,e);t?.(`resolver:rebuild:start`,{targetCount:n.length,sample:n.slice(0,10).map(e=>e.key)});let o=new Set,s=e=>{let t=e?.scope?.[a];if(!(!t||o.has(t))){o.add(t);for(let[e,n]of Object.entries(t)){let t=String(e).replace(/^~/,``),a=i.get(t);a&&n?.ctx?.scope&&r.set(n.ctx.scope,a),s(n?.ctx)}}};s(e.root),t?.(`resolver:rebuild:done`,{targetCount:n.length,scopeBindings:r.size})},list:()=>n,resolveByCommand:e=>{let n=String(e?.name??``),r=o.get(e);if(r)return t?.(`resolver:resolve:cache-hit`,{command:n,pluginKey:r.key}),r;let i=s(e?.caller?.scope);return i?(o.set(e,i),t?.(`resolver:resolve:resolved`,{command:n,pluginKey:i.key,pluginName:i.name})):t?.(`resolver:resolve:miss`,{command:n}),i},bindCommand:e=>{let n=s(e?.caller?.scope);n?(o.set(e,n),t?.(`resolver:bind:ok`,{command:String(e?.name??``),pluginKey:n.key,pluginName:n.name})):t?.(`resolver:bind:miss`,{command:String(e?.name??``)})}}}function _(e,t){if(!t)return;let n=t.split(`.`),r=e;for(let e of n){if(!r||typeof r!=`object`)return;r=r[e]}return r}function v(e){if(typeof e==`number`)return Number.isFinite(e)?e:null;if(typeof e==`string`&&e.trim()){let t=Number(e);return Number.isFinite(t)?t:null}return null}function y(e){return e==null||typeof e==`object`?e:String(e)}function b(e,t){if(t.operator===`exists`)return e!=null;let n=t.value,r=y(e),i=y(n);if(t.operator===`eq`)return r===i;if(t.operator===`ne`)return r!==i;if(t.operator===`includes`)return typeof r==`string`?r.includes(String(i??``)):Array.isArray(e)?e.map(e=>y(e)).includes(i):!1;if(t.operator===`regex`){if(typeof r!=`string`)return!1;try{return new RegExp(String(i??``)).test(r)}catch{return!1}}let a=v(e),o=v(n);return a===null||o===null?!1:t.operator===`gt`?a>o:t.operator===`gte`?a>=o:t.operator===`lt`?a<o:t.operator===`lte`?a<=o:!1}function x(e,t){return e.type===`group`?e.children.length?e.operator===`and`?e.children.every(e=>x(e,t)):e.children.some(e=>x(e,t)):!0:e.type===`not`?!x(e.child,t):b(_(t,e.field),e)}async function S(e){try{let t=await(0,r.readFile)(e,`utf8`),n=JSON.parse(t);return Array.isArray(n)?n.map(e=>f(e)):[]}catch{return null}}function C(e){let t=Promise.resolve();return async n=>{t=t.catch(()=>{}).then(async()=>{await(0,r.writeFile)(e,JSON.stringify(n.map(c),null,2),`utf8`)}),await t}}function w(e,t={}){let i=(0,n.join)(e.baseDir||process.cwd(),`data`,`filterpro`),a=(0,n.join)(i,t.filename||`rules.json`),s={rules:[]},l=C(a),d=e.logger(`filter-pro`),m=!!t.debug,_=(e,t)=>{m&&e===`native-filter:evaluate`&&t?.matched&&d.info(`[trace:%s] %s`,e,JSON.stringify(t))},v=g(e,_),y=new Map,b=new Map,w=(e,t={})=>({platform:String(e.platform??``),selfId:String(e.selfId??``),userId:String(e.userId??``),channelId:String(e.channelId??``),guildId:String(e.guildId??``),isDirect:e.isDirect,content:String(e.content??``),type:String(e.type??``),event:e.event,author:e.author,quote:e.quote,...t}),T=(e,t)=>{let n=w(t,{pluginKey:e});for(let t of u(s.rules)){if(!t.enabled||t.target.type!==`plugin`||(t.target.value||``).trim()!==e)continue;let r=x(t.condition,n);if(_(`native-filter:evaluate`,{pluginKey:e,ruleId:t.id,ruleName:t.name,action:t.action,matched:r}),r)return t.action===`bypass`}return!0},E=(async()=>{await(0,r.mkdir)(i,{recursive:!0});let e=await S(a);if(e){s.rules=e;return}s.rules=[],await l(s.rules)})().catch(t=>{e.logger(`filter-pro`).warn(`failed to initialize persistent rules: %s`,String(t)),s.rules=[]}),D=async()=>{await E,v.rebuild();let t=e?.$commander?._commandList;if(Array.isArray(t)){_(`resolver:bind-existing:start`,{commandCount:t.length});for(let e of t)v.bindCommand(e);_(`resolver:bind-existing:done`,{commandCount:t.length})}else _(`resolver:bind-existing:skip`,{reason:`$commander not available`})},O=async()=>{await D();for(let[e,t]of b.entries()){if(e?.filter!==t)continue;let n=y.get(e);n&&(e.filter=n)}b.clear();let t=h(e),n=new Set(s.rules.filter(e=>e.enabled&&e.target.type===`plugin`&&!!e.target.value).map(e=>(e.target.value||``).trim()));_(`native-filter:sync:start`,{activeTargetCount:n.size,discoveredForks:t.size});for(let[e,r]of t.entries()){let t=r?.parent;if(!t||typeof t.filter!=`function`)continue;y.has(t),y.set(t,t.filter);let i=y.get(t);if(!n.has(e)){t.filter=i;continue}let a=t=>i(t)?T(e,t):!1;t.filter=a,b.set(t,a)}_(`native-filter:sync:done`,{activeTargetCount:n.size})};D(),O(),e.on(`ready`,O),e.on(`internal/fork`,O),e.on(`internal/before-update`,O),e.on(`internal/update`,O),e.on(`internal/runtime`,O),e.on(`dispose`,()=>{for(let[e,t]of b.entries()){if(e?.filter!==t)continue;let n=y.get(e);n&&(e.filter=n)}b.clear()}),e.on(`command-added`,e=>{v.bindCommand(e),_(`command:added`,{command:String(e?.name??``)})}),e.middleware(async(e,t)=>{await E;let n=w(e);_(`message:incoming`,{platform:n.platform,userId:n.userId,channelId:n.channelId,guildId:n.guildId,isDirect:n.isDirect,content:n.content,ruleCount:s.rules.length});for(let e of u(s.rules)){if(!e.enabled||e.target.type!==`global`)continue;if(!p(e.target,n)){_(`message:skip-target`,{ruleId:e.id,ruleName:e.name,target:e.target,pluginKey:n.pluginKey});continue}let r=x(e.condition,n);if(_(`message:evaluate`,{ruleId:e.id,ruleName:e.name,action:e.action,matched:r,expr:e.condition}),r)return e.action===`bypass`?(_(`message:action`,{ruleId:e.id,action:`bypass`}),t()):e.response?(_(`message:action`,{ruleId:e.id,action:`block`,response:e.response}),e.response):(_(`message:action`,{ruleId:e.id,action:`block`,response:``}),``)}return _(`message:pass`,{reason:`no-rule-matched`}),t()},!0),e.before(`command/execute`,async e=>{await E;let t=v.resolveByCommand(e.command),n=w(e.session,{commandName:String(e.command.name??``),pluginKey:t?.key,pluginName:t?.name});_(`command:incoming`,{command:n.commandName,pluginKey:n.pluginKey,pluginName:n.pluginName,isDirect:n.isDirect,guildId:n.guildId,content:n.content,ruleCount:s.rules.length}),_(`command:pass`,{reason:`native-filter-mode`})}),e.inject([`console`],e=>{e.console.addEntry({dev:(0,n.resolve)(__dirname,`../client/index.ts`),prod:(0,n.resolve)(__dirname,`../dist`)});let t=new o(e,s),r=e.console.addListener.bind(e.console),i=async()=>{await l(s.rules),await O(),t.refresh()};r(`filter-pro/list`,async()=>(await E,t.get()),{authority:3}),r(`filter-pro/targets`,async()=>(await D(),v.list()),{authority:3}),r(`filter-pro/create`,async e=>{await E;let t=f(e||{});return s.rules.push(t),await i(),c(t)},{authority:3}),r(`filter-pro/update`,async e=>{if(await E,!e?.id)return null;let t=s.rules.findIndex(t=>t.id===e.id);if(t<0)return null;let n=s.rules[t];return s.rules[t]=f({...n,...e,id:n.id}),await i(),c(s.rules[t])},{authority:3}),r(`filter-pro/delete`,async e=>{await E;let t=s.rules.findIndex(t=>t.id===e);return t<0?!1:(s.rules.splice(t,1),await i(),!0)},{authority:3}),r(`filter-pro/reorder`,async e=>{if(await E,!Array.isArray(e))return t.get();let n=new Map(e.map((e,t)=>[e,t]));s.rules.sort((e,t)=>(n.has(e.id)?n.get(e.id):2**53-1)-(n.has(t.id)?n.get(t.id):2**53-1));for(let e=0;e<s.rules.length;e++)s.rules[e].priority=e;return await i(),t.get()},{authority:3}),r(`filter-pro/toggle`,async e=>{if(await E,!e?.id)return null;let t=s.rules.find(t=>t.id===e.id);return t?(t.enabled=!!e.enabled,await i(),c(t)):null},{authority:3})})}exports.Config=i,exports.apply=w,exports.filter=!1,exports.name=`filter-pro`,exports.reusable=!0;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require(`koishi`),t=require(`@koishijs/plugin-console`),n=require(`node:path`),r=require(`node:fs/promises`);const i=e.Schema.object({filename:e.Schema.string().default(`rules.json`).description(`持久化文件名(位于 data/filterpro/ 下)。`),debug:e.Schema.boolean().default(!1).description(`输出规则匹配调试日志。`)}),a=Symbol.for(`koishi.loader.record`);var o=class extends t.DataService{constructor(e,t){super(e,`filter-pro`),this.state=t}async get(){return u(this.state.rules).map(c)}};function s(){return{type:`group`,operator:`and`,children:[{type:`compare`,field:`guildId`,operator:`eq`,value:``}]}}function c(e){return{id:e.id,name:e.name,enabled:e.enabled,priority:e.priority,action:e.action,target:{...e.target},condition:l(e.condition),response:e.response}}function l(e){return e.type===`group`?{type:`group`,operator:e.operator,children:e.children.map(l)}:e.type===`not`?{type:`not`,child:l(e.child)}:{type:`compare`,field:e.field,operator:e.operator,value:e.value}}function u(e){return[...e].sort((e,t)=>e.priority-t.priority||e.id.localeCompare(t.id))}function d(e){if(!e||typeof e!=`object`)return s();let t=e;if(t.type===`group`)return{type:`group`,operator:t.operator===`or`?`or`:`and`,children:Array.isArray(t.children)?t.children.map(d):[]};if(t.type===`not`)return{type:`not`,child:d(t.child)};let n=[`eq`,`ne`,`in`,`nin`,`includes`,`notincludes`,`regex`,`gt`,`gte`,`lt`,`lte`,`exists`].includes(t.operator)?t.operator:`eq`;return{type:`compare`,field:typeof t.field==`string`?t.field:`content`,operator:n,value:t.value}}function f(t){let n=t.target||{type:`global`},r;n.type===`global`?r=``:(n.type===`plugin`||n.type===`command`)&&(r=Array.isArray(n.value)?n.value.filter(e=>typeof e==`string`&&e.trim()).map(e=>e.trim()):typeof n.value==`string`&&n.value.trim()?[n.value.trim()]:[]);let i={type:n.type===`command`?`command`:n.type===`plugin`?`plugin`:`global`,value:r};return{id:t.id||e.Random.id(8),name:t.name||`new-rule`,enabled:t.enabled??!0,priority:t.priority??0,action:t.action||`block`,target:i,condition:d(t.condition),response:t.response??``}}function p(e,t){if(!e||e.type===`global`)return!0;if(e.type===`plugin`){let n=typeof t.pluginKey==`string`?t.pluginKey:``;if(!n)return!1;if(Array.isArray(e.value))return e.value.length>0&&e.value.includes(n);let r=typeof e.value==`string`?e.value.trim():``;return r&&n===r}if(e.type===`command`){let n=typeof t.commandName==`string`?t.commandName:``;if(!n)return!1;if(Array.isArray(e.value))return e.value.length>0&&e.value.includes(n);let r=typeof e.value==`string`?e.value.trim():``;return r&&n===r}return!1}function m(e){let t=[],n=new Set,r=new Set,i=e=>{let o=e?.scope?.[a];if(!(!o||r.has(o))){r.add(o);for(let[e,r]of Object.entries(o)){let a=String(e).replace(/^~/,``),[o,s=``]=a.split(`:`,2);r?.runtime?.plugin?.filter!==!1&&(o&&o!==`group`&&!n.has(a)&&(n.add(a),t.push({key:a,name:o,ident:s,label:s?`${o}:${s}`:o})),i(r?.ctx))}}};return i(e.root),t.sort((e,t)=>e.key.localeCompare(t.key))}function h(e){let t=new Map,n=new Set,r=e=>{let i=e?.scope?.[a];if(!(!i||n.has(i))){n.add(i);for(let[e,n]of Object.entries(i)){let i=String(e).replace(/^~/,``);t.set(i,n),r(n?.ctx)}}};return r(e.root),t}function g(e,t){let n=[],r=new Map,i=new Map,o=new WeakMap,s=t=>{if(!t)return;let n=r.get(t);if(n)return n;let a=e.loader;if(a?.paths){let e=a.paths(t);for(let t of e||[]){let e=String(t).replace(/^~/,``),n=i.get(e);if(n)return n}}};return{rebuild:()=>{n=m(e),r.clear(),i.clear();for(let e of n)i.set(e.key,e);t?.(`resolver:rebuild:start`,{targetCount:n.length,sample:n.slice(0,10).map(e=>e.key)});let o=new Set,s=e=>{let t=e?.scope?.[a];if(!(!t||o.has(t))){o.add(t);for(let[e,n]of Object.entries(t)){let t=String(e).replace(/^~/,``),a=i.get(t);a&&n?.ctx?.scope&&r.set(n.ctx.scope,a),s(n?.ctx)}}};s(e.root),t?.(`resolver:rebuild:done`,{targetCount:n.length,scopeBindings:r.size})},list:()=>n,resolveByCommand:e=>{let n=String(e?.name??``),r=o.get(e);if(r)return t?.(`resolver:resolve:cache-hit`,{command:n,pluginKey:r.key}),r;let i=s(e?.caller?.scope);return i?(o.set(e,i),t?.(`resolver:resolve:resolved`,{command:n,pluginKey:i.key,pluginName:i.name})):t?.(`resolver:resolve:miss`,{command:n}),i},bindCommand:e=>{let n=s(e?.caller?.scope);n?(o.set(e,n),t?.(`resolver:bind:ok`,{command:String(e?.name??``),pluginKey:n.key,pluginName:n.name})):t?.(`resolver:bind:miss`,{command:String(e?.name??``)})}}}function _(e,t){if(!t)return;let n=t.split(`.`),r=e;for(let e of n){if(!r||typeof r!=`object`)return;r=r[e]}return r}function v(e){if(typeof e==`number`)return Number.isFinite(e)?e:null;if(typeof e==`string`&&e.trim()){let t=Number(e);return Number.isFinite(t)?t:null}return null}function y(e){return e==null||typeof e==`object`?e:String(e)}function b(e){if(Array.isArray(e))return e;if(typeof e!=`string`)return[e];let t=e.split(/[,,]/).map(e=>e.trim()).filter(e=>e);return t.length>1?t:[e]}function x(e,t){if(t.operator===`exists`)return e!=null;let n=t.value,r=y(e),i=y(n);if(t.operator===`eq`)return r===i;if(t.operator===`ne`)return r!==i;let a=b(n);if(t.operator===`in`)return a.some(e=>r===y(e));if(t.operator===`nin`)return a.every(e=>r!==y(e));if(t.operator===`includes`){if(typeof r==`string`)return a.some(e=>r.includes(String(y(e)??``)));if(Array.isArray(e)){let t=e.map(e=>y(e));return a.some(e=>t.includes(y(e)))}return!1}if(t.operator===`notincludes`){if(typeof r==`string`)return a.every(e=>!r.includes(String(y(e)??``)));if(Array.isArray(e)){let t=e.map(e=>y(e));return a.every(e=>!t.includes(y(e)))}return!1}if(t.operator===`regex`){if(typeof r!=`string`)return!1;try{return new RegExp(String(y(a[0])??``)).test(r)}catch{return!1}}let o=y(a[0]),s=v(e),c=v(o);return s===null||c===null?!1:t.operator===`gt`?s>c:t.operator===`gte`?s>=c:t.operator===`lt`?s<c:t.operator===`lte`?s<=c:!1}function S(e,t){return e.type===`group`?e.children.length?e.operator===`and`?e.children.every(e=>S(e,t)):e.children.some(e=>S(e,t)):!0:e.type===`not`?!S(e.child,t):x(_(t,e.field),e)}async function C(e){try{let t=await(0,r.readFile)(e,`utf8`),n=JSON.parse(t);return Array.isArray(n)?n.map(e=>f(e)):[]}catch{return null}}function w(e){let t=Promise.resolve();return async n=>{t=t.catch(()=>{}).then(async()=>{await(0,r.writeFile)(e,JSON.stringify(n.map(c),null,2),`utf8`)}),await t}}function T(e,t={}){let i=(0,n.join)(e.baseDir||process.cwd(),`data`,`filterpro`),a=(0,n.join)(i,t.filename||`rules.json`),s={rules:[]},l=w(a),d=e.logger(`filter-pro`),m=!!t.debug,_=(e,t)=>{m&&e===`native-filter:evaluate`&&t?.matched&&d.info(`[trace:%s] %s`,e,JSON.stringify(t))},v=g(e,_),y=new Map,b=new Map,x=(e,t={})=>({platform:String(e.platform??``),selfId:String(e.selfId??``),userId:String(e.userId??``),channelId:String(e.channelId??``),guildId:String(e.guildId??``),isDirect:e.isDirect,content:String(e.content??``),type:String(e.type??``),event:e.event,author:e.author,quote:e.quote,...t}),T=(e,t)=>{let n=x(t,{pluginKey:e});for(let t of u(s.rules)){if(!t.enabled||t.target.type!==`plugin`)continue;let r=!1;if(Array.isArray(t.target.value)?r=t.target.value.includes(e):typeof t.target.value==`string`&&(r=t.target.value.trim()===e),!r)continue;let i=S(t.condition,n);if(_(`native-filter:evaluate`,{pluginKey:e,ruleId:t.id,ruleName:t.name,action:t.action,matched:i}),i)return t.action===`bypass`}return!0},E=(async()=>{await(0,r.mkdir)(i,{recursive:!0});let e=await C(a);if(e){s.rules=e;return}s.rules=[],await l(s.rules)})().catch(t=>{e.logger(`filter-pro`).warn(`failed to initialize persistent rules: %s`,String(t)),s.rules=[]}),D=async()=>{await E,v.rebuild();let t=e?.$commander?._commandList;if(Array.isArray(t)){_(`resolver:bind-existing:start`,{commandCount:t.length});for(let e of t)v.bindCommand(e);_(`resolver:bind-existing:done`,{commandCount:t.length})}else _(`resolver:bind-existing:skip`,{reason:`$commander not available`})},O=async()=>{await D();for(let[e,t]of b.entries()){if(e?.filter!==t)continue;let n=y.get(e);n&&(e.filter=n)}b.clear();let t=h(e),n=new Set;for(let e of s.rules)if(!(!e.enabled||e.target.type!==`plugin`||!e.target.value)){if(Array.isArray(e.target.value))for(let t of e.target.value)n.add(t);else if(typeof e.target.value==`string`){let t=e.target.value.trim();t&&n.add(t)}}_(`native-filter:sync:start`,{activeTargetCount:n.size,discoveredForks:t.size});for(let[e,r]of t.entries()){let t=r?.parent;if(!t||typeof t.filter!=`function`)continue;y.has(t),y.set(t,t.filter);let i=y.get(t);if(!n.has(e)){t.filter=i;continue}let a=t=>i(t)?T(e,t):!1;t.filter=a,b.set(t,a)}_(`native-filter:sync:done`,{activeTargetCount:n.size})};D(),O(),e.on(`ready`,O),e.on(`internal/fork`,O),e.on(`internal/before-update`,O),e.on(`internal/update`,O),e.on(`internal/runtime`,O),e.on(`dispose`,()=>{for(let[e,t]of b.entries()){if(e?.filter!==t)continue;let n=y.get(e);n&&(e.filter=n)}b.clear()}),e.on(`command-added`,e=>{v.bindCommand(e),_(`command:added`,{command:String(e?.name??``)})}),e.middleware(async(e,t)=>{await E;let n=x(e);_(`message:incoming`,{platform:n.platform,userId:n.userId,channelId:n.channelId,guildId:n.guildId,isDirect:n.isDirect,content:n.content,ruleCount:s.rules.length});for(let e of u(s.rules)){if(!e.enabled||e.target.type!==`global`)continue;if(!p(e.target,n)){_(`message:skip-target`,{ruleId:e.id,ruleName:e.name,target:e.target,pluginKey:n.pluginKey});continue}let r=S(e.condition,n);if(_(`message:evaluate`,{ruleId:e.id,ruleName:e.name,action:e.action,matched:r,expr:e.condition}),r)return e.action===`bypass`?(_(`message:action`,{ruleId:e.id,action:`bypass`}),t()):e.response?(_(`message:action`,{ruleId:e.id,action:`block`,response:e.response}),e.response):(_(`message:action`,{ruleId:e.id,action:`block`,response:``}),``)}return _(`message:pass`,{reason:`no-rule-matched`}),t()},!0),e.before(`command/execute`,async e=>{await E;let t=v.resolveByCommand(e.command),n=String(e.command.name??``),r=x(e.session,{commandName:n,pluginKey:t?.key,pluginName:t?.name});_(`command:incoming`,{command:r.commandName,pluginKey:r.pluginKey,pluginName:r.pluginName,isDirect:r.isDirect,guildId:r.guildId,content:r.content,ruleCount:s.rules.length});for(let t of u(s.rules)){if(!t.enabled||t.target.type!==`command`||!p(t.target,r))continue;let i=S(t.condition,r);if(_(`command:evaluate`,{ruleId:t.id,ruleName:t.name,action:t.action,matched:i,commandName:n}),i){if(t.action===`bypass`){_(`command:action`,{ruleId:t.id,action:`bypass`});return}return _(`command:action`,{ruleId:t.id,action:`block`,response:t.response||``}),t.response&&await e.session.send(t.response),``}}_(`command:pass`,{reason:`no-command-rule-matched`})}),e.inject([`console`],e=>{e.console.addEntry({dev:(0,n.resolve)(__dirname,`../client/index.ts`),prod:(0,n.resolve)(__dirname,`../dist`)});let t=new o(e,s),r=e.console.addListener.bind(e.console),i=async()=>{await l(s.rules),await O(),t.refresh()};r(`filter-pro/list`,async()=>(await E,t.get()),{authority:3}),r(`filter-pro/targets`,async()=>(await D(),v.list()),{authority:3}),r(`filter-pro/commands`,async()=>(e?.$commander?._commandList||[]).map(e=>({name:String(e.name??``),label:String(e.name??``)})),{authority:3}),r(`filter-pro/create`,async e=>{await E;let t=f(e||{});return s.rules.push(t),await i(),c(t)},{authority:3}),r(`filter-pro/update`,async e=>{if(await E,!e?.id)return null;let t=s.rules.findIndex(t=>t.id===e.id);if(t<0)return null;let n=s.rules[t];return s.rules[t]=f({...n,...e,id:n.id}),await i(),c(s.rules[t])},{authority:3}),r(`filter-pro/delete`,async e=>{await E;let t=s.rules.findIndex(t=>t.id===e);return t<0?!1:(s.rules.splice(t,1),await i(),!0)},{authority:3}),r(`filter-pro/reorder`,async e=>{if(await E,!Array.isArray(e))return t.get();let n=new Map(e.map((e,t)=>[e,t]));s.rules.sort((e,t)=>(n.has(e.id)?n.get(e.id):2**53-1)-(n.has(t.id)?n.get(t.id):2**53-1));for(let e=0;e<s.rules.length;e++)s.rules[e].priority=e;return await i(),t.get()},{authority:3}),r(`filter-pro/toggle`,async e=>{if(await E,!e?.id)return null;let t=s.rules.find(t=>t.id===e.id);return t?(t.enabled=!!e.enabled,await i(),c(t)):null},{authority:3})})}exports.Config=i,exports.apply=T,exports.filter=!1,exports.name=`filter-pro`,exports.reusable=!0;
package/lib/index.d.ts CHANGED
@@ -7,11 +7,11 @@ declare const reusable = true;
7
7
  declare const filter = false;
8
8
  type RuleAction = 'bypass' | 'block';
9
9
  type GroupOperator = 'and' | 'or';
10
- type CompareOperator = 'eq' | 'ne' | 'includes' | 'regex' | 'gt' | 'gte' | 'lt' | 'lte' | 'exists';
11
- type TargetType = 'global' | 'plugin';
10
+ type CompareOperator = 'eq' | 'ne' | 'in' | 'nin' | 'includes' | 'notincludes' | 'regex' | 'gt' | 'gte' | 'lt' | 'lte' | 'exists';
11
+ type TargetType = 'global' | 'plugin' | 'command';
12
12
  interface RuleTarget {
13
13
  type: TargetType;
14
- value?: string;
14
+ value?: string | string[];
15
15
  }
16
16
  interface GroupExpr {
17
17
  type: 'group';
@@ -63,6 +63,10 @@ interface PluginTargetOption {
63
63
  ident: string;
64
64
  label: string;
65
65
  }
66
+ interface CommandOption {
67
+ name: string;
68
+ label: string;
69
+ }
66
70
  declare module '@koishijs/plugin-console' {
67
71
  namespace Console {
68
72
  interface Services {
@@ -71,6 +75,7 @@ declare module '@koishijs/plugin-console' {
71
75
  interface Events {
72
76
  'filter-pro/list': () => Awaitable<RuleItem[]>;
73
77
  'filter-pro/targets': () => Awaitable<PluginTargetOption[]>;
78
+ 'filter-pro/commands': () => Awaitable<CommandOption[]>;
74
79
  'filter-pro/create': (input: RuleInput) => Awaitable<RuleItem>;
75
80
  'filter-pro/update': (input: RuleInput) => Awaitable<RuleItem | null>;
76
81
  'filter-pro/delete': (id: string) => Awaitable<boolean>;
package/lib/index.mjs CHANGED
@@ -1 +1 @@
1
- import{Random as e,Schema as t}from"koishi";import{DataService as n}from"@koishijs/plugin-console";import{join as r,resolve as i}from"node:path";import{mkdir as a,readFile as o,writeFile as s}from"node:fs/promises";const c=`filter-pro`,l=!0,u=!1,d=t.object({filename:t.string().default(`rules.json`).description(`持久化文件名(位于 data/filterpro/ 下)。`),debug:t.boolean().default(!1).description(`输出规则匹配调试日志。`)}),f=Symbol.for(`koishi.loader.record`);var p=class extends n{constructor(e,t){super(e,`filter-pro`),this.state=t}async get(){return _(this.state.rules).map(h)}};function m(){return{type:`group`,operator:`and`,children:[{type:`compare`,field:`guildId`,operator:`eq`,value:``}]}}function h(e){return{id:e.id,name:e.name,enabled:e.enabled,priority:e.priority,action:e.action,target:{...e.target},condition:g(e.condition),response:e.response}}function g(e){return e.type===`group`?{type:`group`,operator:e.operator,children:e.children.map(g)}:e.type===`not`?{type:`not`,child:g(e.child)}:{type:`compare`,field:e.field,operator:e.operator,value:e.value}}function _(e){return[...e].sort((e,t)=>e.priority-t.priority||e.id.localeCompare(t.id))}function v(e){if(!e||typeof e!=`object`)return m();let t=e;if(t.type===`group`)return{type:`group`,operator:t.operator===`or`?`or`:`and`,children:Array.isArray(t.children)?t.children.map(v):[]};if(t.type===`not`)return{type:`not`,child:v(t.child)};let n=[`eq`,`ne`,`includes`,`regex`,`gt`,`gte`,`lt`,`lte`,`exists`].includes(t.operator)?t.operator:`eq`;return{type:`compare`,field:typeof t.field==`string`?t.field:`content`,operator:n,value:t.value}}function y(t){let n=t.target||{type:`global`},r=typeof n.value==`string`?n.value.trim():``,i=n.type===`plugin`?r:``,a={type:n.type===`plugin`?`plugin`:`global`,value:i};return{id:t.id||e.id(8),name:t.name||`new-rule`,enabled:t.enabled??!0,priority:t.priority??0,action:t.action||`block`,target:a,condition:v(t.condition),response:t.response??``}}function b(e,t){if(!e||e.type===`global`)return!0;let n=typeof t.pluginKey==`string`?t.pluginKey:``,r=e.value?.trim();return r?n===r:!1}function x(e){let t=[],n=new Set,r=new Set,i=e=>{let a=e?.scope?.[f];if(!(!a||r.has(a))){r.add(a);for(let[e,r]of Object.entries(a)){let a=String(e).replace(/^~/,``),[o,s=``]=a.split(`:`,2);r?.runtime?.plugin?.filter!==!1&&(o&&o!==`group`&&!n.has(a)&&(n.add(a),t.push({key:a,name:o,ident:s,label:s?`${o}:${s}`:o})),i(r?.ctx))}}};return i(e.root),t.sort((e,t)=>e.key.localeCompare(t.key))}function S(e){let t=new Map,n=new Set,r=e=>{let i=e?.scope?.[f];if(!(!i||n.has(i))){n.add(i);for(let[e,n]of Object.entries(i)){let i=String(e).replace(/^~/,``);t.set(i,n),r(n?.ctx)}}};return r(e.root),t}function C(e,t){let n=[],r=new Map,i=new Map,a=new WeakMap,o=t=>{if(!t)return;let n=r.get(t);if(n)return n;let a=e.loader;if(a?.paths){let e=a.paths(t);for(let t of e||[]){let e=String(t).replace(/^~/,``),n=i.get(e);if(n)return n}}};return{rebuild:()=>{n=x(e),r.clear(),i.clear();for(let e of n)i.set(e.key,e);t?.(`resolver:rebuild:start`,{targetCount:n.length,sample:n.slice(0,10).map(e=>e.key)});let a=new Set,o=e=>{let t=e?.scope?.[f];if(!(!t||a.has(t))){a.add(t);for(let[e,n]of Object.entries(t)){let t=String(e).replace(/^~/,``),a=i.get(t);a&&n?.ctx?.scope&&r.set(n.ctx.scope,a),o(n?.ctx)}}};o(e.root),t?.(`resolver:rebuild:done`,{targetCount:n.length,scopeBindings:r.size})},list:()=>n,resolveByCommand:e=>{let n=String(e?.name??``),r=a.get(e);if(r)return t?.(`resolver:resolve:cache-hit`,{command:n,pluginKey:r.key}),r;let i=o(e?.caller?.scope);return i?(a.set(e,i),t?.(`resolver:resolve:resolved`,{command:n,pluginKey:i.key,pluginName:i.name})):t?.(`resolver:resolve:miss`,{command:n}),i},bindCommand:e=>{let n=o(e?.caller?.scope);n?(a.set(e,n),t?.(`resolver:bind:ok`,{command:String(e?.name??``),pluginKey:n.key,pluginName:n.name})):t?.(`resolver:bind:miss`,{command:String(e?.name??``)})}}}function w(e,t){if(!t)return;let n=t.split(`.`),r=e;for(let e of n){if(!r||typeof r!=`object`)return;r=r[e]}return r}function T(e){if(typeof e==`number`)return Number.isFinite(e)?e:null;if(typeof e==`string`&&e.trim()){let t=Number(e);return Number.isFinite(t)?t:null}return null}function E(e){return e==null||typeof e==`object`?e:String(e)}function D(e,t){if(t.operator===`exists`)return e!=null;let n=t.value,r=E(e),i=E(n);if(t.operator===`eq`)return r===i;if(t.operator===`ne`)return r!==i;if(t.operator===`includes`)return typeof r==`string`?r.includes(String(i??``)):Array.isArray(e)?e.map(e=>E(e)).includes(i):!1;if(t.operator===`regex`){if(typeof r!=`string`)return!1;try{return new RegExp(String(i??``)).test(r)}catch{return!1}}let a=T(e),o=T(n);return a===null||o===null?!1:t.operator===`gt`?a>o:t.operator===`gte`?a>=o:t.operator===`lt`?a<o:t.operator===`lte`?a<=o:!1}function O(e,t){return e.type===`group`?e.children.length?e.operator===`and`?e.children.every(e=>O(e,t)):e.children.some(e=>O(e,t)):!0:e.type===`not`?!O(e.child,t):D(w(t,e.field),e)}async function k(e){try{let t=await o(e,`utf8`),n=JSON.parse(t);return Array.isArray(n)?n.map(e=>y(e)):[]}catch{return null}}function A(e){let t=Promise.resolve();return async n=>{t=t.catch(()=>{}).then(async()=>{await s(e,JSON.stringify(n.map(h),null,2),`utf8`)}),await t}}function j(e,t={}){let n=r(e.baseDir||process.cwd(),`data`,`filterpro`),o=r(n,t.filename||`rules.json`),s={rules:[]},c=A(o),l=e.logger(`filter-pro`),u=!!t.debug,d=(e,t)=>{u&&e===`native-filter:evaluate`&&t?.matched&&l.info(`[trace:%s] %s`,e,JSON.stringify(t))},f=C(e,d),m=new Map,g=new Map,v=(e,t={})=>({platform:String(e.platform??``),selfId:String(e.selfId??``),userId:String(e.userId??``),channelId:String(e.channelId??``),guildId:String(e.guildId??``),isDirect:e.isDirect,content:String(e.content??``),type:String(e.type??``),event:e.event,author:e.author,quote:e.quote,...t}),x=(e,t)=>{let n=v(t,{pluginKey:e});for(let t of _(s.rules)){if(!t.enabled||t.target.type!==`plugin`||(t.target.value||``).trim()!==e)continue;let r=O(t.condition,n);if(d(`native-filter:evaluate`,{pluginKey:e,ruleId:t.id,ruleName:t.name,action:t.action,matched:r}),r)return t.action===`bypass`}return!0},w=(async()=>{await a(n,{recursive:!0});let e=await k(o);if(e){s.rules=e;return}s.rules=[],await c(s.rules)})().catch(t=>{e.logger(`filter-pro`).warn(`failed to initialize persistent rules: %s`,String(t)),s.rules=[]}),T=async()=>{await w,f.rebuild();let t=e?.$commander?._commandList;if(Array.isArray(t)){d(`resolver:bind-existing:start`,{commandCount:t.length});for(let e of t)f.bindCommand(e);d(`resolver:bind-existing:done`,{commandCount:t.length})}else d(`resolver:bind-existing:skip`,{reason:`$commander not available`})},E=async()=>{await T();for(let[e,t]of g.entries()){if(e?.filter!==t)continue;let n=m.get(e);n&&(e.filter=n)}g.clear();let t=S(e),n=new Set(s.rules.filter(e=>e.enabled&&e.target.type===`plugin`&&!!e.target.value).map(e=>(e.target.value||``).trim()));d(`native-filter:sync:start`,{activeTargetCount:n.size,discoveredForks:t.size});for(let[e,r]of t.entries()){let t=r?.parent;if(!t||typeof t.filter!=`function`)continue;m.has(t),m.set(t,t.filter);let i=m.get(t);if(!n.has(e)){t.filter=i;continue}let a=t=>i(t)?x(e,t):!1;t.filter=a,g.set(t,a)}d(`native-filter:sync:done`,{activeTargetCount:n.size})};T(),E(),e.on(`ready`,E),e.on(`internal/fork`,E),e.on(`internal/before-update`,E),e.on(`internal/update`,E),e.on(`internal/runtime`,E),e.on(`dispose`,()=>{for(let[e,t]of g.entries()){if(e?.filter!==t)continue;let n=m.get(e);n&&(e.filter=n)}g.clear()}),e.on(`command-added`,e=>{f.bindCommand(e),d(`command:added`,{command:String(e?.name??``)})}),e.middleware(async(e,t)=>{await w;let n=v(e);d(`message:incoming`,{platform:n.platform,userId:n.userId,channelId:n.channelId,guildId:n.guildId,isDirect:n.isDirect,content:n.content,ruleCount:s.rules.length});for(let e of _(s.rules)){if(!e.enabled||e.target.type!==`global`)continue;if(!b(e.target,n)){d(`message:skip-target`,{ruleId:e.id,ruleName:e.name,target:e.target,pluginKey:n.pluginKey});continue}let r=O(e.condition,n);if(d(`message:evaluate`,{ruleId:e.id,ruleName:e.name,action:e.action,matched:r,expr:e.condition}),r)return e.action===`bypass`?(d(`message:action`,{ruleId:e.id,action:`bypass`}),t()):e.response?(d(`message:action`,{ruleId:e.id,action:`block`,response:e.response}),e.response):(d(`message:action`,{ruleId:e.id,action:`block`,response:``}),``)}return d(`message:pass`,{reason:`no-rule-matched`}),t()},!0),e.before(`command/execute`,async e=>{await w;let t=f.resolveByCommand(e.command),n=v(e.session,{commandName:String(e.command.name??``),pluginKey:t?.key,pluginName:t?.name});d(`command:incoming`,{command:n.commandName,pluginKey:n.pluginKey,pluginName:n.pluginName,isDirect:n.isDirect,guildId:n.guildId,content:n.content,ruleCount:s.rules.length}),d(`command:pass`,{reason:`native-filter-mode`})}),e.inject([`console`],e=>{e.console.addEntry({dev:i(__dirname,`../client/index.ts`),prod:i(__dirname,`../dist`)});let t=new p(e,s),n=e.console.addListener.bind(e.console),r=async()=>{await c(s.rules),await E(),t.refresh()};n(`filter-pro/list`,async()=>(await w,t.get()),{authority:3}),n(`filter-pro/targets`,async()=>(await T(),f.list()),{authority:3}),n(`filter-pro/create`,async e=>{await w;let t=y(e||{});return s.rules.push(t),await r(),h(t)},{authority:3}),n(`filter-pro/update`,async e=>{if(await w,!e?.id)return null;let t=s.rules.findIndex(t=>t.id===e.id);if(t<0)return null;let n=s.rules[t];return s.rules[t]=y({...n,...e,id:n.id}),await r(),h(s.rules[t])},{authority:3}),n(`filter-pro/delete`,async e=>{await w;let t=s.rules.findIndex(t=>t.id===e);return t<0?!1:(s.rules.splice(t,1),await r(),!0)},{authority:3}),n(`filter-pro/reorder`,async e=>{if(await w,!Array.isArray(e))return t.get();let n=new Map(e.map((e,t)=>[e,t]));s.rules.sort((e,t)=>(n.has(e.id)?n.get(e.id):2**53-1)-(n.has(t.id)?n.get(t.id):2**53-1));for(let e=0;e<s.rules.length;e++)s.rules[e].priority=e;return await r(),t.get()},{authority:3}),n(`filter-pro/toggle`,async e=>{if(await w,!e?.id)return null;let t=s.rules.find(t=>t.id===e.id);return t?(t.enabled=!!e.enabled,await r(),h(t)):null},{authority:3})})}export{d as Config,j as apply,u as filter,c as name,l as reusable};
1
+ import{Random as e,Schema as t}from"koishi";import{DataService as n}from"@koishijs/plugin-console";import{join as r,resolve as i}from"node:path";import{mkdir as a,readFile as o,writeFile as s}from"node:fs/promises";const c=`filter-pro`,l=!0,u=!1,d=t.object({filename:t.string().default(`rules.json`).description(`持久化文件名(位于 data/filterpro/ 下)。`),debug:t.boolean().default(!1).description(`输出规则匹配调试日志。`)}),f=Symbol.for(`koishi.loader.record`);var p=class extends n{constructor(e,t){super(e,`filter-pro`),this.state=t}async get(){return _(this.state.rules).map(h)}};function m(){return{type:`group`,operator:`and`,children:[{type:`compare`,field:`guildId`,operator:`eq`,value:``}]}}function h(e){return{id:e.id,name:e.name,enabled:e.enabled,priority:e.priority,action:e.action,target:{...e.target},condition:g(e.condition),response:e.response}}function g(e){return e.type===`group`?{type:`group`,operator:e.operator,children:e.children.map(g)}:e.type===`not`?{type:`not`,child:g(e.child)}:{type:`compare`,field:e.field,operator:e.operator,value:e.value}}function _(e){return[...e].sort((e,t)=>e.priority-t.priority||e.id.localeCompare(t.id))}function v(e){if(!e||typeof e!=`object`)return m();let t=e;if(t.type===`group`)return{type:`group`,operator:t.operator===`or`?`or`:`and`,children:Array.isArray(t.children)?t.children.map(v):[]};if(t.type===`not`)return{type:`not`,child:v(t.child)};let n=[`eq`,`ne`,`in`,`nin`,`includes`,`notincludes`,`regex`,`gt`,`gte`,`lt`,`lte`,`exists`].includes(t.operator)?t.operator:`eq`;return{type:`compare`,field:typeof t.field==`string`?t.field:`content`,operator:n,value:t.value}}function y(t){let n=t.target||{type:`global`},r;n.type===`global`?r=``:(n.type===`plugin`||n.type===`command`)&&(r=Array.isArray(n.value)?n.value.filter(e=>typeof e==`string`&&e.trim()).map(e=>e.trim()):typeof n.value==`string`&&n.value.trim()?[n.value.trim()]:[]);let i={type:n.type===`command`?`command`:n.type===`plugin`?`plugin`:`global`,value:r};return{id:t.id||e.id(8),name:t.name||`new-rule`,enabled:t.enabled??!0,priority:t.priority??0,action:t.action||`block`,target:i,condition:v(t.condition),response:t.response??``}}function b(e,t){if(!e||e.type===`global`)return!0;if(e.type===`plugin`){let n=typeof t.pluginKey==`string`?t.pluginKey:``;if(!n)return!1;if(Array.isArray(e.value))return e.value.length>0&&e.value.includes(n);let r=typeof e.value==`string`?e.value.trim():``;return r&&n===r}if(e.type===`command`){let n=typeof t.commandName==`string`?t.commandName:``;if(!n)return!1;if(Array.isArray(e.value))return e.value.length>0&&e.value.includes(n);let r=typeof e.value==`string`?e.value.trim():``;return r&&n===r}return!1}function x(e){let t=[],n=new Set,r=new Set,i=e=>{let a=e?.scope?.[f];if(!(!a||r.has(a))){r.add(a);for(let[e,r]of Object.entries(a)){let a=String(e).replace(/^~/,``),[o,s=``]=a.split(`:`,2);r?.runtime?.plugin?.filter!==!1&&(o&&o!==`group`&&!n.has(a)&&(n.add(a),t.push({key:a,name:o,ident:s,label:s?`${o}:${s}`:o})),i(r?.ctx))}}};return i(e.root),t.sort((e,t)=>e.key.localeCompare(t.key))}function S(e){let t=new Map,n=new Set,r=e=>{let i=e?.scope?.[f];if(!(!i||n.has(i))){n.add(i);for(let[e,n]of Object.entries(i)){let i=String(e).replace(/^~/,``);t.set(i,n),r(n?.ctx)}}};return r(e.root),t}function C(e,t){let n=[],r=new Map,i=new Map,a=new WeakMap,o=t=>{if(!t)return;let n=r.get(t);if(n)return n;let a=e.loader;if(a?.paths){let e=a.paths(t);for(let t of e||[]){let e=String(t).replace(/^~/,``),n=i.get(e);if(n)return n}}};return{rebuild:()=>{n=x(e),r.clear(),i.clear();for(let e of n)i.set(e.key,e);t?.(`resolver:rebuild:start`,{targetCount:n.length,sample:n.slice(0,10).map(e=>e.key)});let a=new Set,o=e=>{let t=e?.scope?.[f];if(!(!t||a.has(t))){a.add(t);for(let[e,n]of Object.entries(t)){let t=String(e).replace(/^~/,``),a=i.get(t);a&&n?.ctx?.scope&&r.set(n.ctx.scope,a),o(n?.ctx)}}};o(e.root),t?.(`resolver:rebuild:done`,{targetCount:n.length,scopeBindings:r.size})},list:()=>n,resolveByCommand:e=>{let n=String(e?.name??``),r=a.get(e);if(r)return t?.(`resolver:resolve:cache-hit`,{command:n,pluginKey:r.key}),r;let i=o(e?.caller?.scope);return i?(a.set(e,i),t?.(`resolver:resolve:resolved`,{command:n,pluginKey:i.key,pluginName:i.name})):t?.(`resolver:resolve:miss`,{command:n}),i},bindCommand:e=>{let n=o(e?.caller?.scope);n?(a.set(e,n),t?.(`resolver:bind:ok`,{command:String(e?.name??``),pluginKey:n.key,pluginName:n.name})):t?.(`resolver:bind:miss`,{command:String(e?.name??``)})}}}function w(e,t){if(!t)return;let n=t.split(`.`),r=e;for(let e of n){if(!r||typeof r!=`object`)return;r=r[e]}return r}function T(e){if(typeof e==`number`)return Number.isFinite(e)?e:null;if(typeof e==`string`&&e.trim()){let t=Number(e);return Number.isFinite(t)?t:null}return null}function E(e){return e==null||typeof e==`object`?e:String(e)}function D(e){if(Array.isArray(e))return e;if(typeof e!=`string`)return[e];let t=e.split(/[,,]/).map(e=>e.trim()).filter(e=>e);return t.length>1?t:[e]}function O(e,t){if(t.operator===`exists`)return e!=null;let n=t.value,r=E(e),i=E(n);if(t.operator===`eq`)return r===i;if(t.operator===`ne`)return r!==i;let a=D(n);if(t.operator===`in`)return a.some(e=>r===E(e));if(t.operator===`nin`)return a.every(e=>r!==E(e));if(t.operator===`includes`){if(typeof r==`string`)return a.some(e=>r.includes(String(E(e)??``)));if(Array.isArray(e)){let t=e.map(e=>E(e));return a.some(e=>t.includes(E(e)))}return!1}if(t.operator===`notincludes`){if(typeof r==`string`)return a.every(e=>!r.includes(String(E(e)??``)));if(Array.isArray(e)){let t=e.map(e=>E(e));return a.every(e=>!t.includes(E(e)))}return!1}if(t.operator===`regex`){if(typeof r!=`string`)return!1;try{return new RegExp(String(E(a[0])??``)).test(r)}catch{return!1}}let o=E(a[0]),s=T(e),c=T(o);return s===null||c===null?!1:t.operator===`gt`?s>c:t.operator===`gte`?s>=c:t.operator===`lt`?s<c:t.operator===`lte`?s<=c:!1}function k(e,t){return e.type===`group`?e.children.length?e.operator===`and`?e.children.every(e=>k(e,t)):e.children.some(e=>k(e,t)):!0:e.type===`not`?!k(e.child,t):O(w(t,e.field),e)}async function A(e){try{let t=await o(e,`utf8`),n=JSON.parse(t);return Array.isArray(n)?n.map(e=>y(e)):[]}catch{return null}}function j(e){let t=Promise.resolve();return async n=>{t=t.catch(()=>{}).then(async()=>{await s(e,JSON.stringify(n.map(h),null,2),`utf8`)}),await t}}function M(e,t={}){let n=r(e.baseDir||process.cwd(),`data`,`filterpro`),o=r(n,t.filename||`rules.json`),s={rules:[]},c=j(o),l=e.logger(`filter-pro`),u=!!t.debug,d=(e,t)=>{u&&e===`native-filter:evaluate`&&t?.matched&&l.info(`[trace:%s] %s`,e,JSON.stringify(t))},f=C(e,d),m=new Map,g=new Map,v=(e,t={})=>({platform:String(e.platform??``),selfId:String(e.selfId??``),userId:String(e.userId??``),channelId:String(e.channelId??``),guildId:String(e.guildId??``),isDirect:e.isDirect,content:String(e.content??``),type:String(e.type??``),event:e.event,author:e.author,quote:e.quote,...t}),x=(e,t)=>{let n=v(t,{pluginKey:e});for(let t of _(s.rules)){if(!t.enabled||t.target.type!==`plugin`)continue;let r=!1;if(Array.isArray(t.target.value)?r=t.target.value.includes(e):typeof t.target.value==`string`&&(r=t.target.value.trim()===e),!r)continue;let i=k(t.condition,n);if(d(`native-filter:evaluate`,{pluginKey:e,ruleId:t.id,ruleName:t.name,action:t.action,matched:i}),i)return t.action===`bypass`}return!0},w=(async()=>{await a(n,{recursive:!0});let e=await A(o);if(e){s.rules=e;return}s.rules=[],await c(s.rules)})().catch(t=>{e.logger(`filter-pro`).warn(`failed to initialize persistent rules: %s`,String(t)),s.rules=[]}),T=async()=>{await w,f.rebuild();let t=e?.$commander?._commandList;if(Array.isArray(t)){d(`resolver:bind-existing:start`,{commandCount:t.length});for(let e of t)f.bindCommand(e);d(`resolver:bind-existing:done`,{commandCount:t.length})}else d(`resolver:bind-existing:skip`,{reason:`$commander not available`})},E=async()=>{await T();for(let[e,t]of g.entries()){if(e?.filter!==t)continue;let n=m.get(e);n&&(e.filter=n)}g.clear();let t=S(e),n=new Set;for(let e of s.rules)if(!(!e.enabled||e.target.type!==`plugin`||!e.target.value)){if(Array.isArray(e.target.value))for(let t of e.target.value)n.add(t);else if(typeof e.target.value==`string`){let t=e.target.value.trim();t&&n.add(t)}}d(`native-filter:sync:start`,{activeTargetCount:n.size,discoveredForks:t.size});for(let[e,r]of t.entries()){let t=r?.parent;if(!t||typeof t.filter!=`function`)continue;m.has(t),m.set(t,t.filter);let i=m.get(t);if(!n.has(e)){t.filter=i;continue}let a=t=>i(t)?x(e,t):!1;t.filter=a,g.set(t,a)}d(`native-filter:sync:done`,{activeTargetCount:n.size})};T(),E(),e.on(`ready`,E),e.on(`internal/fork`,E),e.on(`internal/before-update`,E),e.on(`internal/update`,E),e.on(`internal/runtime`,E),e.on(`dispose`,()=>{for(let[e,t]of g.entries()){if(e?.filter!==t)continue;let n=m.get(e);n&&(e.filter=n)}g.clear()}),e.on(`command-added`,e=>{f.bindCommand(e),d(`command:added`,{command:String(e?.name??``)})}),e.middleware(async(e,t)=>{await w;let n=v(e);d(`message:incoming`,{platform:n.platform,userId:n.userId,channelId:n.channelId,guildId:n.guildId,isDirect:n.isDirect,content:n.content,ruleCount:s.rules.length});for(let e of _(s.rules)){if(!e.enabled||e.target.type!==`global`)continue;if(!b(e.target,n)){d(`message:skip-target`,{ruleId:e.id,ruleName:e.name,target:e.target,pluginKey:n.pluginKey});continue}let r=k(e.condition,n);if(d(`message:evaluate`,{ruleId:e.id,ruleName:e.name,action:e.action,matched:r,expr:e.condition}),r)return e.action===`bypass`?(d(`message:action`,{ruleId:e.id,action:`bypass`}),t()):e.response?(d(`message:action`,{ruleId:e.id,action:`block`,response:e.response}),e.response):(d(`message:action`,{ruleId:e.id,action:`block`,response:``}),``)}return d(`message:pass`,{reason:`no-rule-matched`}),t()},!0),e.before(`command/execute`,async e=>{await w;let t=f.resolveByCommand(e.command),n=String(e.command.name??``),r=v(e.session,{commandName:n,pluginKey:t?.key,pluginName:t?.name});d(`command:incoming`,{command:r.commandName,pluginKey:r.pluginKey,pluginName:r.pluginName,isDirect:r.isDirect,guildId:r.guildId,content:r.content,ruleCount:s.rules.length});for(let t of _(s.rules)){if(!t.enabled||t.target.type!==`command`||!b(t.target,r))continue;let i=k(t.condition,r);if(d(`command:evaluate`,{ruleId:t.id,ruleName:t.name,action:t.action,matched:i,commandName:n}),i){if(t.action===`bypass`){d(`command:action`,{ruleId:t.id,action:`bypass`});return}return d(`command:action`,{ruleId:t.id,action:`block`,response:t.response||``}),t.response&&await e.session.send(t.response),``}}d(`command:pass`,{reason:`no-command-rule-matched`})}),e.inject([`console`],e=>{e.console.addEntry({dev:i(__dirname,`../client/index.ts`),prod:i(__dirname,`../dist`)});let t=new p(e,s),n=e.console.addListener.bind(e.console),r=async()=>{await c(s.rules),await E(),t.refresh()};n(`filter-pro/list`,async()=>(await w,t.get()),{authority:3}),n(`filter-pro/targets`,async()=>(await T(),f.list()),{authority:3}),n(`filter-pro/commands`,async()=>(e?.$commander?._commandList||[]).map(e=>({name:String(e.name??``),label:String(e.name??``)})),{authority:3}),n(`filter-pro/create`,async e=>{await w;let t=y(e||{});return s.rules.push(t),await r(),h(t)},{authority:3}),n(`filter-pro/update`,async e=>{if(await w,!e?.id)return null;let t=s.rules.findIndex(t=>t.id===e.id);if(t<0)return null;let n=s.rules[t];return s.rules[t]=y({...n,...e,id:n.id}),await r(),h(s.rules[t])},{authority:3}),n(`filter-pro/delete`,async e=>{await w;let t=s.rules.findIndex(t=>t.id===e);return t<0?!1:(s.rules.splice(t,1),await r(),!0)},{authority:3}),n(`filter-pro/reorder`,async e=>{if(await w,!Array.isArray(e))return t.get();let n=new Map(e.map((e,t)=>[e,t]));s.rules.sort((e,t)=>(n.has(e.id)?n.get(e.id):2**53-1)-(n.has(t.id)?n.get(t.id):2**53-1));for(let e=0;e<s.rules.length;e++)s.rules[e].priority=e;return await r(),t.get()},{authority:3}),n(`filter-pro/toggle`,async e=>{if(await w,!e?.id)return null;let t=s.rules.find(t=>t.id===e.id);return t?(t.enabled=!!e.enabled,await r(),h(t)):null},{authority:3})})}export{d as Config,M as apply,u as filter,c as name,l as reusable};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-filter-pro",
3
3
  "description": "A powerful filter plugin for Koishi",
4
- "version": "1.0.14",
4
+ "version": "1.0.17",
5
5
  "main": "lib/index.cjs",
6
6
  "module": "lib/index.mjs",
7
7
  "types": "lib/index.d.ts",
@@ -25,6 +25,10 @@
25
25
  "lint": "biome check && biome lint",
26
26
  "lint-fix": "biome format --write && biome lint --write"
27
27
  },
28
+ "contributors": [
29
+ "q78kg <hoshino-yumetsuki@outlook.com>",
30
+ "shangxueink <1919892171@qq.com>"
31
+ ],
28
32
  "repository": {
29
33
  "type": "git",
30
34
  "url": "git+https://github.com/Hoshino-Yumetsuki/koishi-plugin-filter-pro",