koishi-plugin-chat-patch 2.0.1 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client/index.scss +50 -0
- package/client/vue/chat-logic.ts +471 -11
- package/client/vue/composables/useChatData.ts +4 -2
- package/client/vue/index.vue +279 -101
- package/client/vue/types.ts +2 -0
- package/dist/index.js +2 -2
- package/dist/style.css +1 -1
- package/lib/api-handlers.d.ts +19 -0
- package/lib/index.js +226 -132
- package/lib/message-handler.d.ts +21 -0
- package/lib/types.d.ts +57 -0
- package/package.json +1 -1
- package/src/api-handlers.ts +122 -94
- package/src/message-handler.ts +160 -62
- package/src/types.ts +2 -0
package/dist/style.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
.scrollbar-hide::-webkit-scrollbar{display:none}.chat-patch-wrapper .el-textarea__inner{border-radius:12px;padding:10px 12px;resize:none}.chat-patch-wrapper .el-button--primary{border-radius:10px}.forward-dialog .el-dialog__body{padding:0}.image-viewer-dialog .el-dialog__header{padding-bottom:10px}.fixed{position:fixed!important}.absolute{position:absolute!important}.relative{position:relative!important}.inset-0{top:0!important;right:0!important;bottom:0!important;left:0!important}.-right-2{right:-.5rem!important}.-top-2{top:-.5rem!important}.z-10{z-index:10!important}.z-50{z-index:50!important}.z-\[2000\]{z-index:2000!important}.z-\[60\]{z-index:60!important}.mx-0\.5{margin-left:.125rem!important;margin-right:.125rem!important}.my-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-1\.5{margin-top:.375rem!important;margin-bottom:.375rem!important}.my-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.mb-1{margin-bottom:.25rem!important}.mb-1\.5{margin-bottom:.375rem!important}.mb-2{margin-bottom:.5rem!important}.mb-2\.5{margin-bottom:.625rem!important}.mb-3{margin-bottom:.75rem!important}.mb-6{margin-bottom:1.5rem!important}.ml-2{margin-left:.5rem!important}.ml-3{margin-left:.75rem!important}.mr-1{margin-right:.25rem!important}.mr-3{margin-right:.75rem!important}.mt-2{margin-top:.5rem!important}.block{display:block!important}.flex{display:flex!important}.\!h-10,.h-10{height:2.5rem!important}.h-14{height:3.5rem!important}.h-2\.5{height:.625rem!important}.h-20{height:5rem!important}.h-full{height:100%!important}.max-h-\[100px\]{max-height:100px!important}.max-h-\[400px\]{max-height:400px!important}.max-h-\[70vh\]{max-height:70vh!important}.max-h-full{max-height:100%!important}.min-h-\[1em\]{min-height:1em!important}.min-h-full{min-height:100%!important}.\!w-10{width:2.5rem!important}.w-2\.5{width:.625rem!important}.w-20{width:5rem!important}.w-full{width:100%!important}.min-w-\[140px\]{min-width:140px!important}.min-w-\[20px\]{min-width:20px!important}.max-w-\[100px\]{max-width:100px!important}.max-w-\[300px\]{max-width:300px!important}.max-w-\[85\%\]{max-width:85%!important}.max-w-full{max-width:100%!important}.flex-1{flex:1 1 0%!important}.flex-shrink-0{flex-shrink:0!important}.cursor-default{cursor:default!important}.cursor-pointer{cursor:pointer!important}.resize{resize:both!important}.flex-row{flex-direction:row!important}.flex-row-reverse{flex-direction:row-reverse!important}.flex-col{flex-direction:column!important}.items-start{align-items:flex-start!important}.items-end{align-items:flex-end!important}.items-center{align-items:center!important}.justify-center{justify-content:center!important}.gap-1{gap:.25rem!important}.gap-2{gap:.5rem!important}.gap-3{gap:.75rem!important}.gap-4{gap:1rem!important}.space-y-1\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0 !important;margin-top:calc(.375rem * calc(1 - var(--tw-space-y-reverse)))!important;margin-bottom:calc(.375rem * var(--tw-space-y-reverse))!important}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0 !important;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)))!important;margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))!important}.overflow-hidden{overflow:hidden!important}.overflow-x-auto{overflow-x:auto!important}.truncate{overflow:hidden!important;text-overflow:ellipsis!important;white-space:nowrap!important}.break-all{word-break:break-all!important}.rounded{border-radius:.25rem!important}.rounded-2xl{border-radius:1rem!important}.rounded-full{border-radius:9999px!important}.rounded-lg{border-radius:.5rem!important}.rounded-xl{border-radius:.75rem!important}.rounded-tl-none{border-top-left-radius:0!important}.rounded-tr-none{border-top-right-radius:0!important}.border{border-width:1px!important}.border-2{border-width:2px!important}.border-b{border-bottom-width:1px!important}.border-l-4{border-left-width:4px!important}.border-r{border-right-width:1px!important}.border-t{border-top-width:1px!important}.\!border-none{border-style:none!important}.\!border-\[var\(--k-color-primary\)\]{border-color:var(--k-color-primary)!important}.border-\[var\(--k-border-color\)\]{border-color:var(--k-border-color)!important}.border-black\/10{border-color:#0000001a!important}.border-black\/5{border-color:#0000000d!important}.border-gray-400\/50{border-color:#9ca3af80!important}.border-transparent{border-color:transparent!important}.border-white\/10{border-color:#ffffff1a!important}.\!bg-white\/10{background-color:#ffffff1a!important}.bg-\[\#95ec69\]{--tw-bg-opacity: 1 !important;background-color:rgb(149 236 105 / var(--tw-bg-opacity, 1))!important}.bg-\[var\(--k-button-active-bg\)\]{background-color:var(--k-button-active-bg)!important}.bg-\[var\(--k-card-bg\)\]{background-color:var(--k-card-bg)!important}.bg-\[var\(--k-page-bg\)\]{background-color:var(--k-page-bg)!important}.bg-black{--tw-bg-opacity: 1 !important;background-color:rgb(0 0 0 / var(--tw-bg-opacity, 1))!important}.bg-black\/5{background-color:#0000000d!important}.bg-gray-100{--tw-bg-opacity: 1 !important;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))!important}.bg-gray-400{--tw-bg-opacity: 1 !important;background-color:rgb(156 163 175 / var(--tw-bg-opacity, 1))!important}.bg-gray-50{--tw-bg-opacity: 1 !important;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))!important}.bg-green-500{--tw-bg-opacity: 1 !important;background-color:rgb(34 197 94 / var(--tw-bg-opacity, 1))!important}.bg-white{--tw-bg-opacity: 1 !important;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))!important}.bg-opacity-50{--tw-bg-opacity: .5 !important}.bg-opacity-90{--tw-bg-opacity: .9 !important}.object-contain{-o-object-fit:contain!important;object-fit:contain!important}.p-0{padding:0!important}.p-2\.5{padding:.625rem!important}.p-3{padding:.75rem!important}.p-3\.5{padding:.875rem!important}.p-4{padding:1rem!important}.p-6{padding:1.5rem!important}.px-4{padding-left:1rem!important;padding-right:1rem!important}.px-6{padding-left:1.5rem!important;padding-right:1.5rem!important}.py-1\.5{padding-top:.375rem!important;padding-bottom:.375rem!important}.py-2\.5{padding-top:.625rem!important;padding-bottom:.625rem!important}.py-4{padding-top:1rem!important;padding-bottom:1rem!important}.pb-2{padding-bottom:.5rem!important}.pt-2{padding-top:.5rem!important}.text-left{text-align:left!important}.font-sans{font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji"!important}.\!text-base{font-size:1rem!important;line-height:1.5rem!important}.\!text-xl{font-size:1.25rem!important;line-height:1.75rem!important}.text-\[10px\]{font-size:10px!important}.text-\[15px\]{font-size:15px!important}.text-lg{font-size:1.125rem!important;line-height:1.75rem!important}.text-sm{font-size:.875rem!important;line-height:1.25rem!important}.text-xs{font-size:.75rem!important;line-height:1rem!important}.font-bold{font-weight:700!important}.font-medium{font-weight:500!important}.italic{font-style:italic!important}.leading-relaxed{line-height:1.625!important}.\!text-white{--tw-text-opacity: 1 !important;color:rgb(255 255 255 / var(--tw-text-opacity, 1))!important}.text-\[var\(--k-color-primary\)\]{color:var(--k-color-primary)!important}.text-\[var\(--k-text-color\)\]{color:var(--k-text-color)!important}.text-\[var\(--k-text-color-secondary\)\]{color:var(--k-text-color-secondary)!important}.text-black{--tw-text-opacity: 1 !important;color:rgb(0 0 0 / var(--tw-text-opacity, 1))!important}.text-blue-500{--tw-text-opacity: 1 !important;color:rgb(59 130 246 / var(--tw-text-opacity, 1))!important}.text-gray-400{--tw-text-opacity: 1 !important;color:rgb(156 163 175 / var(--tw-text-opacity, 1))!important}.text-orange-400{--tw-text-opacity: 1 !important;color:rgb(251 146 60 / var(--tw-text-opacity, 1))!important}.text-red-500{--tw-text-opacity: 1 !important;color:rgb(239 68 68 / var(--tw-text-opacity, 1))!important}.text-white{--tw-text-opacity: 1 !important;color:rgb(255 255 255 / var(--tw-text-opacity, 1))!important}.opacity-0{opacity:0!important}.opacity-50{opacity:.5!important}.opacity-60{opacity:.6!important}.opacity-70{opacity:.7!important}.opacity-80{opacity:.8!important}.opacity-90{opacity:.9!important}.shadow-2xl{--tw-shadow: 0 25px 50px -12px rgb(0 0 0 / .25) !important;--tw-shadow-colored: 0 25px 50px -12px var(--tw-shadow-color) !important;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)!important}.shadow-\[0_-2px_10px_rgba\(0\,0\,0\,0\.05\)\]{--tw-shadow: 0 -2px 10px rgba(0,0,0,.05) !important;--tw-shadow-colored: 0 -2px 10px var(--tw-shadow-color) !important;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)!important}.shadow-inner{--tw-shadow: inset 0 2px 4px 0 rgb(0 0 0 / .05) !important;--tw-shadow-colored: inset 0 2px 4px 0 var(--tw-shadow-color) !important;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)!important}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1) !important;--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color) !important;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)!important}.shadow-md{--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1) !important;--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color) !important;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)!important}.shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05) !important;--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color) !important;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)!important}.shadow-xl{--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1) !important;--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color) !important;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)!important}.brightness-100{--tw-brightness: brightness(1) !important;filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)!important}.brightness-105{--tw-brightness: brightness(1.05) !important;filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)!important}.brightness-95{--tw-brightness: brightness(.95) !important;filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)!important}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)!important}.backdrop-blur-sm{--tw-backdrop-blur: blur(4px) !important;-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)!important;backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)!important}.transition-all{transition-property:all!important;transition-timing-function:cubic-bezier(.4,0,.2,1)!important;transition-duration:.15s!important}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke!important;transition-timing-function:cubic-bezier(.4,0,.2,1)!important;transition-duration:.15s!important}.transition-opacity{transition-property:opacity!important;transition-timing-function:cubic-bezier(.4,0,.2,1)!important;transition-duration:.15s!important}.transition-transform{transition-property:transform!important;transition-timing-function:cubic-bezier(.4,0,.2,1)!important;transition-duration:.15s!important}:root{--chat-bg: var(--k-page-bg);--chat-panel-bg: var(--k-card-bg);--chat-border: var(--k-border-color);--chat-text: var(--k-text-color);--chat-text-sub: var(--k-text-color-secondary)}.chat-patch-wrapper{color:var(--chat-text);background-color:var(--chat-bg)}.chat-patch-wrapper .el-aside,.chat-patch-wrapper .el-main,.chat-patch-wrapper .el-header,.chat-patch-wrapper .el-footer{background-color:transparent!important;color:inherit!important}.chat-patch-wrapper .el-scrollbar{background-color:transparent!important}.chat-patch-wrapper .el-input__wrapper,.chat-patch-wrapper .el-textarea__inner{background-color:var(--k-input-bg)!important;color:var(--chat-text)!important;box-shadow:0 0 0 1px var(--chat-border) inset!important}.chat-patch-wrapper .el-empty{background-color:transparent!important}.layout-iframe{width:100%;height:100%;border:none}.hover\:scale-105:hover{--tw-scale-x: 1.05 !important;--tw-scale-y: 1.05 !important;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))!important}.hover\:bg-\[var\(--k-button-hover-bg\)\]:hover{background-color:var(--k-button-hover-bg)!important}.hover\:bg-black\/10:hover{background-color:#0000001a!important}.hover\:underline:hover{text-decoration-line:underline!important}.hover\:opacity-90:hover{opacity:.9!important}.group:hover .group-hover\:opacity-100{opacity:1!important}@media (min-width: 768px){.md\:max-w-\[75\%\]{max-width:75%!important}}@media (prefers-color-scheme: dark){.dark\:border-white\/10{border-color:#ffffff1a!important}.dark\:border-white\/5{border-color:#ffffff0d!important}.dark\:bg-black\/10{background-color:#0000001a!important}.dark\:bg-black\/20{background-color:#0003!important}.dark\:bg-white\/5{background-color:#ffffff0d!important}.dark\:brightness-100{--tw-brightness: brightness(1) !important;filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)!important}.dark\:brightness-90{--tw-brightness: brightness(.9) !important;filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)!important}.dark\:brightness-95{--tw-brightness: brightness(.95) !important;filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)!important}.dark\:hover\:bg-white\/10:hover{background-color:#ffffff1a!important}}
|
|
1
|
+
@charset "UTF-8";.scrollbar-hide::-webkit-scrollbar{display:none}.chat-patch-wrapper .el-textarea__inner{border-radius:12px;padding:10px 12px;resize:none}.chat-patch-wrapper .raw-content-area .el-textarea__inner{font-family:monospace;font-size:14px;line-height:1.5;background:var(--k-card-bg)!important}.chat-patch-wrapper .el-button--primary{border-radius:10px}.forward-dialog .el-dialog__body{padding:0}.image-viewer-dialog .el-dialog__header{padding-bottom:10px}.fixed{position:fixed!important}.absolute{position:absolute!important}.relative{position:relative!important}.inset-0{top:0!important;right:0!important;bottom:0!important;left:0!important}.-right-1\.5{right:-.375rem!important}.-top-1\.5{top:-.375rem!important}.left-0{left:0!important}.right-0{right:0!important}.right-1{right:.25rem!important}.top-1{top:.25rem!important}.z-10{z-index:10!important}.z-50{z-index:50!important}.z-\[2000\]{z-index:2000!important}.z-\[60\]{z-index:60!important}.z-\[70\]{z-index:70!important}.z-\[80\]{z-index:80!important}.mx-0\.5{margin-left:.125rem!important;margin-right:.125rem!important}.mx-1{margin-left:.25rem!important;margin-right:.25rem!important}.my-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-1\.5{margin-top:.375rem!important;margin-bottom:.375rem!important}.my-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.mb-1{margin-bottom:.25rem!important}.mb-1\.5{margin-bottom:.375rem!important}.mb-2{margin-bottom:.5rem!important}.mb-2\.5{margin-bottom:.625rem!important}.mb-3{margin-bottom:.75rem!important}.mb-6{margin-bottom:1.5rem!important}.ml-2{margin-left:.5rem!important}.ml-3{margin-left:.75rem!important}.mr-1{margin-right:.25rem!important}.mr-2{margin-right:.5rem!important}.mr-3{margin-right:.75rem!important}.mt-1{margin-top:.25rem!important}.mt-2{margin-top:.5rem!important}.mt-4{margin-top:1rem!important}.block{display:block!important}.flex{display:flex!important}.hidden{display:none!important}.\!h-10,.h-10{height:2.5rem!important}.h-14{height:3.5rem!important}.h-2\.5{height:.625rem!important}.h-20{height:5rem!important}.h-8{height:2rem!important}.h-full{height:100%!important}.max-h-\[100px\]{max-height:100px!important}.max-h-\[400px\]{max-height:400px!important}.max-h-\[70vh\]{max-height:70vh!important}.max-h-full{max-height:100%!important}.min-h-\[1em\]{min-height:1em!important}.\!w-10{width:2.5rem!important}.w-2\.5{width:.625rem!important}.w-20{width:5rem!important}.w-8{width:2rem!important}.w-full{width:100%!important}.min-w-\[140px\]{min-width:140px!important}.min-w-\[20px\]{min-width:20px!important}.max-w-\[100px\]{max-width:100px!important}.max-w-\[300px\]{max-width:300px!important}.max-w-\[85\%\]{max-width:85%!important}.max-w-full{max-width:100%!important}.flex-1{flex:1 1 0%!important}.flex-shrink-0{flex-shrink:0!important}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))!important}.cursor-context-menu{cursor:context-menu!important}.cursor-default{cursor:default!important}.cursor-pointer{cursor:pointer!important}.resize{resize:both!important}.flex-row{flex-direction:row!important}.flex-row-reverse{flex-direction:row-reverse!important}.flex-col{flex-direction:column!important}.items-start{align-items:flex-start!important}.items-end{align-items:flex-end!important}.items-center{align-items:center!important}.justify-center{justify-content:center!important}.justify-between{justify-content:space-between!important}.gap-1{gap:.25rem!important}.gap-2{gap:.5rem!important}.gap-3{gap:.75rem!important}.gap-4{gap:1rem!important}.gap-6{gap:1.5rem!important}.space-y-1\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0 !important;margin-top:calc(.375rem * calc(1 - var(--tw-space-y-reverse)))!important;margin-bottom:calc(.375rem * var(--tw-space-y-reverse))!important}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0 !important;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)))!important;margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.overflow-x-auto{overflow-x:auto!important}.truncate{overflow:hidden!important;text-overflow:ellipsis!important;white-space:nowrap!important}.break-all{word-break:break-all!important}.rounded{border-radius:.25rem!important}.rounded-2xl{border-radius:1rem!important}.rounded-full{border-radius:9999px!important}.rounded-lg{border-radius:.5rem!important}.rounded-xl{border-radius:.75rem!important}.rounded-tl-none{border-top-left-radius:0!important}.rounded-tr-none{border-top-right-radius:0!important}.border{border-width:1px!important}.border-2{border-width:2px!important}.border-b{border-bottom-width:1px!important}.border-l-4{border-left-width:4px!important}.border-r{border-right-width:1px!important}.border-t{border-top-width:1px!important}.\!border-none{border-style:none!important}.\!border-\[var\(--k-color-primary\)\]{border-color:var(--k-color-primary)!important}.border-\[var\(--k-border-color\)\]{border-color:var(--k-border-color)!important}.border-black\/10{border-color:#0000001a!important}.border-black\/5{border-color:#0000000d!important}.border-blue-500{--tw-border-opacity: 1 !important;border-color:rgb(59 130 246 / var(--tw-border-opacity, 1))!important}.border-gray-400\/50{border-color:#9ca3af80!important}.border-transparent{border-color:transparent!important}.border-white\/10{border-color:#ffffff1a!important}.\!bg-white\/10{background-color:#ffffff1a!important}.bg-\[\#95ec69\]{--tw-bg-opacity: 1 !important;background-color:rgb(149 236 105 / var(--tw-bg-opacity, 1))!important}.bg-\[var\(--k-button-active-bg\)\]{background-color:var(--k-button-active-bg)!important}.bg-\[var\(--k-card-bg\)\]{background-color:var(--k-card-bg)!important}.bg-\[var\(--k-page-bg\)\]{background-color:var(--k-page-bg)!important}.bg-black{--tw-bg-opacity: 1 !important;background-color:rgb(0 0 0 / var(--tw-bg-opacity, 1))!important}.bg-black\/5{background-color:#0000000d!important}.bg-blue-50\/10{background-color:#eff6ff1a!important}.bg-gray-100{--tw-bg-opacity: 1 !important;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))!important}.bg-gray-400{--tw-bg-opacity: 1 !important;background-color:rgb(156 163 175 / var(--tw-bg-opacity, 1))!important}.bg-gray-50{--tw-bg-opacity: 1 !important;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))!important}.bg-green-500{--tw-bg-opacity: 1 !important;background-color:rgb(34 197 94 / var(--tw-bg-opacity, 1))!important}.bg-white{--tw-bg-opacity: 1 !important;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))!important}.bg-opacity-50{--tw-bg-opacity: .5 !important}.bg-opacity-90{--tw-bg-opacity: .9 !important}.object-contain{-o-object-fit:contain!important;object-fit:contain!important}.p-0{padding:0!important}.p-10{padding:2.5rem!important}.p-2\.5{padding:.625rem!important}.p-3{padding:.75rem!important}.p-3\.5{padding:.875rem!important}.p-4{padding:1rem!important}.p-6{padding:1.5rem!important}.p-8{padding:2rem!important}.px-3{padding-left:.75rem!important;padding-right:.75rem!important}.px-4{padding-left:1rem!important;padding-right:1rem!important}.px-6{padding-left:1.5rem!important;padding-right:1.5rem!important}.py-1\.5{padding-top:.375rem!important;padding-bottom:.375rem!important}.py-2\.5{padding-top:.625rem!important;padding-bottom:.625rem!important}.py-4{padding-top:1rem!important;padding-bottom:1rem!important}.pb-2{padding-bottom:.5rem!important}.pb-8{padding-bottom:2rem!important}.pr-8{padding-right:2rem!important}.pt-2{padding-top:.5rem!important}.text-left{text-align:left!important}.text-center{text-align:center!important}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace!important}.font-sans{font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji"!important}.\!text-base{font-size:1rem!important;line-height:1.5rem!important}.\!text-xl{font-size:1.25rem!important;line-height:1.75rem!important}.text-2xl{font-size:1.5rem!important;line-height:2rem!important}.text-\[10px\]{font-size:10px!important}.text-\[15px\]{font-size:15px!important}.text-lg{font-size:1.125rem!important;line-height:1.75rem!important}.text-sm{font-size:.875rem!important;line-height:1.25rem!important}.text-xl{font-size:1.25rem!important;line-height:1.75rem!important}.text-xs{font-size:.75rem!important;line-height:1rem!important}.font-bold{font-weight:700!important}.font-medium{font-weight:500!important}.italic{font-style:italic!important}.leading-relaxed{line-height:1.625!important}.\!text-white{--tw-text-opacity: 1 !important;color:rgb(255 255 255 / var(--tw-text-opacity, 1))!important}.text-\[var\(--k-color-primary\)\]{color:var(--k-color-primary)!important}.text-\[var\(--k-text-color\)\]{color:var(--k-text-color)!important}.text-\[var\(--k-text-color-secondary\)\]{color:var(--k-text-color-secondary)!important}.text-black{--tw-text-opacity: 1 !important;color:rgb(0 0 0 / var(--tw-text-opacity, 1))!important}.text-blue-500{--tw-text-opacity: 1 !important;color:rgb(59 130 246 / var(--tw-text-opacity, 1))!important}.text-gray-400{--tw-text-opacity: 1 !important;color:rgb(156 163 175 / var(--tw-text-opacity, 1))!important}.text-orange-400{--tw-text-opacity: 1 !important;color:rgb(251 146 60 / var(--tw-text-opacity, 1))!important}.text-red-500{--tw-text-opacity: 1 !important;color:rgb(239 68 68 / var(--tw-text-opacity, 1))!important}.text-white{--tw-text-opacity: 1 !important;color:rgb(255 255 255 / var(--tw-text-opacity, 1))!important}.opacity-0{opacity:0!important}.opacity-100{opacity:1!important}.opacity-40{opacity:.4!important}.opacity-50{opacity:.5!important}.opacity-60{opacity:.6!important}.opacity-70{opacity:.7!important}.opacity-80{opacity:.8!important}.opacity-90{opacity:.9!important}.shadow{--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1) !important;--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color) !important;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)!important}.shadow-\[0_-2px_10px_rgba\(0\,0\,0\,0\.05\)\]{--tw-shadow: 0 -2px 10px rgba(0,0,0,.05) !important;--tw-shadow-colored: 0 -2px 10px var(--tw-shadow-color) !important;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)!important}.shadow-inner{--tw-shadow: inset 0 2px 4px 0 rgb(0 0 0 / .05) !important;--tw-shadow-colored: inset 0 2px 4px 0 var(--tw-shadow-color) !important;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)!important}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1) !important;--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color) !important;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)!important}.shadow-md{--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1) !important;--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color) !important;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)!important}.shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05) !important;--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color) !important;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)!important}.shadow-xl{--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1) !important;--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color) !important;box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)!important}.blur{--tw-blur: blur(8px) !important;filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)!important}.brightness-100{--tw-brightness: brightness(1) !important;filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)!important}.brightness-105{--tw-brightness: brightness(1.05) !important;filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)!important}.brightness-95{--tw-brightness: brightness(.95) !important;filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)!important}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)!important}.backdrop-blur-sm{--tw-backdrop-blur: blur(4px) !important;-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)!important;backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)!important}.transition-all{transition-property:all!important;transition-timing-function:cubic-bezier(.4,0,.2,1)!important;transition-duration:.15s!important}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke!important;transition-timing-function:cubic-bezier(.4,0,.2,1)!important;transition-duration:.15s!important}.transition-opacity{transition-property:opacity!important;transition-timing-function:cubic-bezier(.4,0,.2,1)!important;transition-duration:.15s!important}.transition-transform{transition-property:transform!important;transition-timing-function:cubic-bezier(.4,0,.2,1)!important;transition-duration:.15s!important}.duration-200{transition-duration:.2s!important}.ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)!important}.will-change-transform{will-change:transform!important}:root{--chat-bg: var(--k-page-bg);--chat-panel-bg: var(--k-card-bg);--chat-border: var(--k-border-color);--chat-text: var(--k-text-color);--chat-text-sub: var(--k-text-color-secondary)}.chat-patch-wrapper .mobile-scrollbar-fix .el-scrollbar__bar{display:none!important;opacity:0!important;width:0!important;height:0!important}.chat-patch-wrapper .mobile-scrollbar-fix .el-scrollbar__thumb{display:none!important}.chat-patch-wrapper .mobile-scrollbar-fix .el-scrollbar__wrap{overflow-x:hidden!important;scrollbar-width:none!important;-ms-overflow-style:none!important}.chat-patch-wrapper .mobile-scrollbar-fix .el-scrollbar__wrap::-webkit-scrollbar{display:none!important;width:0!important;height:0!important;background:transparent!important}.chat-patch-wrapper .mobile-scrollbar-fix .el-scrollbar__wrap::-webkit-scrollbar-track{display:none!important}.chat-patch-wrapper .mobile-scrollbar-fix .el-scrollbar__wrap::-webkit-scrollbar-thumb{display:none!important}.chat-patch-wrapper{color:var(--chat-text);background-color:var(--chat-bg)}.chat-patch-wrapper .el-aside,.chat-patch-wrapper .el-main,.chat-patch-wrapper .el-header,.chat-patch-wrapper .el-footer{background-color:transparent!important;color:inherit!important}.chat-patch-wrapper .el-scrollbar{background-color:transparent!important}.chat-patch-wrapper .el-input__wrapper,.chat-patch-wrapper .el-textarea__inner{background-color:var(--k-input-bg)!important;color:var(--chat-text)!important;box-shadow:0 0 0 1px var(--chat-border) inset!important}.chat-patch-wrapper .el-empty{background-color:transparent!important}.layout-iframe{width:100%;height:100%;border:none}.message-highlight{animation:highlight-fade 1.5s ease-in-out;border-radius:8px}@keyframes highlight-fade{0%{background-color:transparent}10%{background-color:#409eff66;filter:brightness(1.2)}30%{background-color:#409eff66;filter:brightness(1.2)}to{background-color:transparent}}.hover\:scale-105:hover{--tw-scale-x: 1.05 !important;--tw-scale-y: 1.05 !important;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))!important}.hover\:scale-110:hover{--tw-scale-x: 1.1 !important;--tw-scale-y: 1.1 !important;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))!important}.hover\:bg-\[var\(--k-button-hover-bg\)\]:hover{background-color:var(--k-button-hover-bg)!important}.hover\:bg-black\/10:hover{background-color:#0000001a!important}.hover\:text-red-500:hover{--tw-text-opacity: 1 !important;color:rgb(239 68 68 / var(--tw-text-opacity, 1))!important}.hover\:underline:hover{text-decoration-line:underline!important}.hover\:opacity-90:hover{opacity:.9!important}.hover\:brightness-90:hover{--tw-brightness: brightness(.9) !important;filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)!important}.active\:scale-95:active{--tw-scale-x: .95 !important;--tw-scale-y: .95 !important;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))!important}.group\/msg:hover .group-hover\/msg\:opacity-100,.group\/quote:hover .group-hover\/quote\:opacity-100,.group:hover .group-hover\:opacity-100{opacity:1!important}@media (min-width: 768px){.md\:inline{display:inline!important}.md\:max-w-\[75\%\]{max-width:75%!important}}@media (prefers-color-scheme: dark){.dark\:border-white\/10{border-color:#ffffff1a!important}.dark\:border-white\/5{border-color:#ffffff0d!important}.dark\:bg-black\/10{background-color:#0000001a!important}.dark\:bg-black\/20{background-color:#0003!important}.dark\:bg-white\/5{background-color:#ffffff0d!important}.dark\:brightness-100{--tw-brightness: brightness(1) !important;filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)!important}.dark\:brightness-90{--tw-brightness: brightness(.9) !important;filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)!important}.dark\:brightness-95{--tw-brightness: brightness(.95) !important;filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)!important}.dark\:hover\:bg-white\/10:hover{background-color:#ffffff1a!important}}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { FileManager } from './file-manager';
|
|
2
|
+
import { MessageHandler } from './message-handler';
|
|
3
|
+
import { Context } from 'koishi';
|
|
4
|
+
import { Config } from './config';
|
|
5
|
+
export declare class ApiHandlers {
|
|
6
|
+
private ctx;
|
|
7
|
+
private config;
|
|
8
|
+
private fileManager;
|
|
9
|
+
private messageHandler;
|
|
10
|
+
private logger;
|
|
11
|
+
constructor(ctx: Context, config: Config, fileManager: FileManager, messageHandler: MessageHandler);
|
|
12
|
+
registerApiHandlers(): void;
|
|
13
|
+
private isFileUrl;
|
|
14
|
+
private createFileUrl;
|
|
15
|
+
private handleLocalFileRequest;
|
|
16
|
+
private setupTempFileCleanup;
|
|
17
|
+
private cleanupMediaCache;
|
|
18
|
+
private logInfo;
|
|
19
|
+
}
|
package/lib/index.js
CHANGED
|
@@ -197,55 +197,118 @@ var MessageHandler = class {
|
|
|
197
197
|
}
|
|
198
198
|
// 更新频道信息到JSON文件
|
|
199
199
|
async updateChannelInfoToFile(session) {
|
|
200
|
+
const isDirect = session.isDirect || session.channelId?.includes("private");
|
|
200
201
|
let guildName = session.channelId;
|
|
201
|
-
|
|
202
|
+
const directUserName = session.username || session.event?.user?.name || session.userId;
|
|
202
203
|
const data = this.fileManager.readChatDataFromFile();
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
if (session.userId && session.isDirect && session.bot.getUser && typeof session.bot.getUser === "function") {
|
|
209
|
-
try {
|
|
210
|
-
const user = await session.bot.getUser(session.userId);
|
|
211
|
-
directUserName = user?.name || session.username || session.userId || "未知用户";
|
|
212
|
-
} catch (userError) {
|
|
213
|
-
this.logInfo("获取用户信息失败,使用备用名称:", userError);
|
|
204
|
+
if (!isDirect) {
|
|
205
|
+
try {
|
|
206
|
+
if (session.guildId && session.bot.getGuild && typeof session.bot.getGuild === "function") {
|
|
207
|
+
const guild = await session.bot.getGuild(session.guildId);
|
|
208
|
+
guildName = guild?.name || session.channelId;
|
|
214
209
|
}
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
210
|
+
if (session.guildId && !session.bot.getGuild && session.bot.getChannel && typeof session.bot.getChannel === "function") {
|
|
211
|
+
try {
|
|
212
|
+
const channel = await session.bot.getChannel(session.guildId);
|
|
213
|
+
guildName = channel?.name || session.channelId;
|
|
214
|
+
} catch (channelError) {
|
|
215
|
+
this.logInfo("获取频道信息失败,使用频道ID作为备用:", channelError);
|
|
216
|
+
}
|
|
222
217
|
}
|
|
218
|
+
} catch (error) {
|
|
219
|
+
this.logInfo("获取频道信息失败,使用频道ID作为备用:", error);
|
|
220
|
+
guildName = session.channelId;
|
|
223
221
|
}
|
|
224
|
-
} catch (error) {
|
|
225
|
-
this.logInfo("获取频道信息失败,使用频道ID作为备用:", error);
|
|
226
|
-
guildName = session.channelId;
|
|
227
222
|
}
|
|
228
223
|
if (!data.channels[session.selfId]) {
|
|
229
224
|
data.channels[session.selfId] = {};
|
|
230
225
|
}
|
|
226
|
+
const existingChannel = data.channels[session.selfId][session.channelId];
|
|
227
|
+
let finalName;
|
|
228
|
+
if (isDirect) {
|
|
229
|
+
if (directUserName && directUserName !== session.userId) {
|
|
230
|
+
finalName = `私聊(${directUserName})`;
|
|
231
|
+
} else if (existingChannel?.name && !existingChannel.name.includes("未知")) {
|
|
232
|
+
finalName = existingChannel.name;
|
|
233
|
+
} else {
|
|
234
|
+
finalName = "私聊(未知用户)";
|
|
235
|
+
}
|
|
236
|
+
} else {
|
|
237
|
+
finalName = guildName || session.channelId;
|
|
238
|
+
}
|
|
231
239
|
const channelInfo = {
|
|
232
240
|
id: session.channelId,
|
|
233
|
-
name:
|
|
241
|
+
name: finalName,
|
|
234
242
|
type: session.type || 0,
|
|
235
243
|
channelId: session.channelId,
|
|
236
244
|
guildName,
|
|
237
|
-
isDirect:
|
|
245
|
+
isDirect: !!isDirect
|
|
238
246
|
};
|
|
247
|
+
if (existingChannel && existingChannel.name !== finalName) {
|
|
248
|
+
this.logInfo("更新频道名称:", {
|
|
249
|
+
channelId: session.channelId,
|
|
250
|
+
oldName: existingChannel.name,
|
|
251
|
+
newName: finalName
|
|
252
|
+
});
|
|
253
|
+
}
|
|
239
254
|
data.channels[session.selfId][session.channelId] = channelInfo;
|
|
240
255
|
this.fileManager.writeChatDataToFile(data);
|
|
241
256
|
this.logInfo("更新频道信息到文件:", channelInfo.name);
|
|
242
257
|
return guildName;
|
|
243
258
|
}
|
|
259
|
+
// 下载并缓存媒体文件
|
|
260
|
+
async downloadAndCacheMedia(url, type) {
|
|
261
|
+
try {
|
|
262
|
+
if (!url || url.startsWith("data:") || url.startsWith("file:")) return url;
|
|
263
|
+
let folder = "media";
|
|
264
|
+
if (type === "image") folder = "images";
|
|
265
|
+
else if (type === "avatar") folder = "avatars";
|
|
266
|
+
const dir = require("node:path").join(this.ctx.baseDir, "data", "chat-patch", "persist-media", folder);
|
|
267
|
+
if (!require("node:fs").existsSync(dir)) {
|
|
268
|
+
require("node:fs").mkdirSync(dir, { recursive: true });
|
|
269
|
+
}
|
|
270
|
+
const crypto = require("node:crypto");
|
|
271
|
+
const hash = crypto.createHash("md5").update(url).digest("hex");
|
|
272
|
+
const ext = require("node:path").extname(new URL(url).pathname) || (type === "image" ? ".jpg" : ".mp4");
|
|
273
|
+
const filename = `${hash}${ext}`;
|
|
274
|
+
const filePath = require("node:path").join(dir, filename);
|
|
275
|
+
if (require("node:fs").existsSync(filePath)) {
|
|
276
|
+
return require("node:url").pathToFileURL(filePath).href;
|
|
277
|
+
}
|
|
278
|
+
const buffer = await this.ctx.http.get(url, { responseType: "arraybuffer" });
|
|
279
|
+
require("node:fs").writeFileSync(filePath, Buffer.from(buffer));
|
|
280
|
+
return require("node:url").pathToFileURL(filePath).href;
|
|
281
|
+
} catch (e) {
|
|
282
|
+
return url;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
// 处理消息中的媒体元素并缓存
|
|
286
|
+
async processMediaElements(elements) {
|
|
287
|
+
if (!elements) return elements;
|
|
288
|
+
for (const el of elements) {
|
|
289
|
+
if (["image", "img", "mface"].includes(el.type)) {
|
|
290
|
+
const src = el.attrs.src || el.attrs.url || el.attrs.file;
|
|
291
|
+
if (src) el.attrs.src = await this.downloadAndCacheMedia(src, "image");
|
|
292
|
+
} else if (["audio", "video"].includes(el.type)) {
|
|
293
|
+
const src = el.attrs.src || el.attrs.url || el.attrs.file;
|
|
294
|
+
if (src) el.attrs.src = await this.downloadAndCacheMedia(src, "media");
|
|
295
|
+
}
|
|
296
|
+
if (el.children) await this.processMediaElements(el.children);
|
|
297
|
+
}
|
|
298
|
+
return elements;
|
|
299
|
+
}
|
|
244
300
|
async broadcastMessageEvent(session) {
|
|
245
301
|
try {
|
|
246
302
|
await this.updateBotInfoToFile(session);
|
|
247
303
|
const guildName = await this.updateChannelInfoToFile(session);
|
|
304
|
+
const isDirect = session.isDirect || session.channelId?.includes("private");
|
|
248
305
|
const timestamp = Date.now();
|
|
306
|
+
if (session.elements) {
|
|
307
|
+
await this.processMediaElements(session.elements);
|
|
308
|
+
}
|
|
309
|
+
if (session.quote?.elements) {
|
|
310
|
+
await this.processMediaElements(session.quote.elements);
|
|
311
|
+
}
|
|
249
312
|
let quoteInfo = void 0;
|
|
250
313
|
if (session.quote) {
|
|
251
314
|
quoteInfo = {
|
|
@@ -290,7 +353,7 @@ var MessageHandler = class {
|
|
|
290
353
|
guildName,
|
|
291
354
|
platform: session.platform || "unknown",
|
|
292
355
|
quote: quoteInfo ? this.utils.cleanBase64Content(quoteInfo) : void 0,
|
|
293
|
-
isDirect:
|
|
356
|
+
isDirect: !!isDirect
|
|
294
357
|
};
|
|
295
358
|
await this.fileManager.addMessageToFile(messageInfo);
|
|
296
359
|
const messageEvent = {
|
|
@@ -323,22 +386,47 @@ var MessageHandler = class {
|
|
|
323
386
|
async broadcastBotMessageEvent(session) {
|
|
324
387
|
try {
|
|
325
388
|
const correctChannelId = this.getCorrectChannelId(session.selfId);
|
|
326
|
-
this.logInfo("机器人发送消息调试信息:", {
|
|
327
|
-
"session.channelId": session.channelId,
|
|
328
|
-
"session.event?.channel?.id": session.event?.channel?.id,
|
|
329
|
-
"correctChannelId": correctChannelId,
|
|
330
|
-
"session.guildId": session.guildId,
|
|
331
|
-
"session.isDirect": session.isDirect,
|
|
332
|
-
"session.platform": session.platform
|
|
333
|
-
});
|
|
334
389
|
const finalChannelId = correctChannelId || session.channelId;
|
|
335
390
|
await this.updateBotInfoToFile(session);
|
|
336
391
|
const guildName = await this.updateChannelInfoToFile(session);
|
|
392
|
+
const isDirect = session.isDirect || finalChannelId?.includes("private");
|
|
337
393
|
const timestamp = Date.now();
|
|
394
|
+
if (session.event?.message?.elements) {
|
|
395
|
+
await this.processMediaElements(session.event.message.elements);
|
|
396
|
+
}
|
|
338
397
|
let content = session.content || "";
|
|
339
398
|
if (!content && session.event?.message?.elements) {
|
|
340
399
|
content = this.utils.extractTextContent(session.event.message.elements).trim();
|
|
341
400
|
}
|
|
401
|
+
let quoteInfo = void 0;
|
|
402
|
+
const quoteMatch = content.match(/<quote id="([^"]+)"\/>/);
|
|
403
|
+
if (quoteMatch) {
|
|
404
|
+
const quoteId = quoteMatch[1];
|
|
405
|
+
const data = this.fileManager.readChatDataFromFile();
|
|
406
|
+
const channelKey = `${session.selfId}:${finalChannelId}`;
|
|
407
|
+
const quotedMsg = data.messages[channelKey]?.find((m) => m.id === quoteId);
|
|
408
|
+
if (quotedMsg) {
|
|
409
|
+
const realId = quotedMsg.id.startsWith("bot-msg-") ? quotedMsg.realId : quotedMsg.id;
|
|
410
|
+
quoteInfo = {
|
|
411
|
+
messageId: realId || quotedMsg.id,
|
|
412
|
+
id: realId || quotedMsg.id,
|
|
413
|
+
content: quotedMsg.content,
|
|
414
|
+
elements: quotedMsg.elements,
|
|
415
|
+
user: {
|
|
416
|
+
id: quotedMsg.userId,
|
|
417
|
+
name: quotedMsg.username,
|
|
418
|
+
userId: quotedMsg.userId,
|
|
419
|
+
avatar: quotedMsg.avatar,
|
|
420
|
+
username: quotedMsg.username
|
|
421
|
+
},
|
|
422
|
+
timestamp: quotedMsg.timestamp
|
|
423
|
+
};
|
|
424
|
+
content = content.replace(/<quote id="[^"]+"\/>\s*/, "");
|
|
425
|
+
if (realId) {
|
|
426
|
+
session.content = session.content.replace(/id="[^"]+"/, `id="${realId}"`);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
}
|
|
342
430
|
const messageInfo = {
|
|
343
431
|
id: `bot-msg-${timestamp}`,
|
|
344
432
|
content,
|
|
@@ -352,7 +440,10 @@ var MessageHandler = class {
|
|
|
352
440
|
type: "bot",
|
|
353
441
|
guildName,
|
|
354
442
|
platform: session.platform || "unknown",
|
|
355
|
-
|
|
443
|
+
quote: quoteInfo,
|
|
444
|
+
isDirect: !!isDirect,
|
|
445
|
+
sending: true
|
|
446
|
+
// 标记为正在发送
|
|
356
447
|
};
|
|
357
448
|
await this.fileManager.addMessageToFile(messageInfo);
|
|
358
449
|
const messageEvent = {
|
|
@@ -369,26 +460,14 @@ var MessageHandler = class {
|
|
|
369
460
|
guildName,
|
|
370
461
|
channelType: session.event?.channel?.type || session.type || 0,
|
|
371
462
|
elements: this.utils.cleanBase64Content(session.event?.message?.elements),
|
|
372
|
-
|
|
463
|
+
quote: quoteInfo,
|
|
464
|
+
isDirect: !!isDirect,
|
|
465
|
+
sending: true,
|
|
373
466
|
bot: {
|
|
374
467
|
avatar: session.bot.user?.avatar,
|
|
375
468
|
name: session.bot.user?.name
|
|
376
469
|
}
|
|
377
470
|
};
|
|
378
|
-
const imageElements = session.event?.message?.elements?.filter(
|
|
379
|
-
(element) => element.type === "img" || element.type === "image" || element.type === "mface"
|
|
380
|
-
) || [];
|
|
381
|
-
this.logInfo("机器人发送消息 (before-send):", {
|
|
382
|
-
selfId: session.selfId,
|
|
383
|
-
channelId: messageEvent.channelId,
|
|
384
|
-
originalChannelId: session.channelId,
|
|
385
|
-
correctedChannelId: finalChannelId,
|
|
386
|
-
content,
|
|
387
|
-
platform: session.platform,
|
|
388
|
-
imageCount: imageElements.length,
|
|
389
|
-
imageUrls: imageElements.map((el) => el.attrs?.src || el.attrs?.url || el.attrs?.file)
|
|
390
|
-
});
|
|
391
|
-
this.correctChannelIds.delete(session.selfId);
|
|
392
471
|
this.ctx.console.broadcast("chat-bot-message-event", messageEvent);
|
|
393
472
|
} catch (error) {
|
|
394
473
|
this.logger.error("广播机器人消息事件失败:", error);
|
|
@@ -574,19 +653,16 @@ var ApiHandlers = class {
|
|
|
574
653
|
this.ctx.console.addListener("get-chat-data", async () => {
|
|
575
654
|
try {
|
|
576
655
|
const data = this.fileManager.readChatDataFromFile();
|
|
577
|
-
|
|
578
|
-
this.logInfo("获取聊天数据:", {
|
|
579
|
-
机器人数量: Object.keys(cleanedData.bots).length,
|
|
580
|
-
频道数量: Object.keys(cleanedData.channels).reduce((total, botId) => total + Object.keys(cleanedData.channels[botId] || {}).length, 0),
|
|
581
|
-
消息频道数: Object.keys(cleanedData.messages).length,
|
|
582
|
-
总消息数: Object.values(cleanedData.messages).reduce((total, msgs) => total + msgs.length, 0)
|
|
583
|
-
});
|
|
656
|
+
this.logInfo("获取基础聊天数据");
|
|
584
657
|
return {
|
|
585
658
|
success: true,
|
|
586
659
|
data: {
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
660
|
+
bots: data.bots || {},
|
|
661
|
+
channels: data.channels || {},
|
|
662
|
+
pinnedBots: data.pinnedBots || [],
|
|
663
|
+
pinnedChannels: data.pinnedChannels || [],
|
|
664
|
+
// 不返回 messages,由前端按需拉取
|
|
665
|
+
messages: {}
|
|
590
666
|
}
|
|
591
667
|
};
|
|
592
668
|
} catch (error) {
|
|
@@ -731,31 +807,23 @@ var ApiHandlers = class {
|
|
|
731
807
|
this.logInfo("消息发送成功:", result);
|
|
732
808
|
const messageId = Array.isArray(result) ? result[0] : result;
|
|
733
809
|
if (messageId) {
|
|
734
|
-
const
|
|
735
|
-
const
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
channelType: 0,
|
|
749
|
-
// 这个信息在前端会补充
|
|
750
|
-
elements: [],
|
|
751
|
-
// 这个信息在前端会补充
|
|
752
|
-
isDirect: false
|
|
753
|
-
// 这个信息在前端会补充
|
|
754
|
-
};
|
|
755
|
-
this.ctx.console.broadcast("bot-message-sent-event", botMessageEvent);
|
|
810
|
+
const chatData = this.fileManager.readChatDataFromFile();
|
|
811
|
+
const channelKey = `${data.selfId}:${data.channelId}`;
|
|
812
|
+
const messages = chatData.messages[channelKey] || [];
|
|
813
|
+
const msg = [...messages].reverse().find((m) => m.type === "bot" && m.sending);
|
|
814
|
+
if (msg) {
|
|
815
|
+
msg.realId = messageId;
|
|
816
|
+
msg.sending = false;
|
|
817
|
+
this.fileManager.writeChatDataToFile(chatData);
|
|
818
|
+
this.ctx.console.broadcast("bot-message-updated", {
|
|
819
|
+
channelKey,
|
|
820
|
+
tempId: msg.id,
|
|
821
|
+
realId: messageId
|
|
822
|
+
});
|
|
823
|
+
}
|
|
756
824
|
}
|
|
757
825
|
return {
|
|
758
|
-
success:
|
|
826
|
+
success: !!messageId,
|
|
759
827
|
messageId,
|
|
760
828
|
tempImageIds: data.images?.map((img) => img.tempId) || []
|
|
761
829
|
};
|
|
@@ -923,6 +991,61 @@ var ApiHandlers = class {
|
|
|
923
991
|
return { success: false, error: error?.message || String(error) };
|
|
924
992
|
}
|
|
925
993
|
});
|
|
994
|
+
this.ctx.console.addListener("get-user-info", async (data) => {
|
|
995
|
+
try {
|
|
996
|
+
const bot = this.ctx.bots.find((b) => b.selfId === data.selfId);
|
|
997
|
+
if (!bot) return { success: false, error: "机器人不存在" };
|
|
998
|
+
const user = await bot.getUser(data.userId, data.guildId);
|
|
999
|
+
if (user) {
|
|
1000
|
+
if (user.avatar) {
|
|
1001
|
+
user.avatar = await this.messageHandler.downloadAndCacheMedia(user.avatar, "avatar");
|
|
1002
|
+
}
|
|
1003
|
+
const chatData = this.fileManager.readChatDataFromFile();
|
|
1004
|
+
let changed = false;
|
|
1005
|
+
const botChannels = chatData.channels[data.selfId] || {};
|
|
1006
|
+
const possibleChannelIds = [
|
|
1007
|
+
data.userId,
|
|
1008
|
+
`private:${data.userId}`,
|
|
1009
|
+
`direct:${data.userId}`
|
|
1010
|
+
];
|
|
1011
|
+
for (const channelId of possibleChannelIds) {
|
|
1012
|
+
const channel = botChannels[channelId];
|
|
1013
|
+
if (channel && channel.isDirect) {
|
|
1014
|
+
const newName = `私聊(${user.name})`;
|
|
1015
|
+
if (channel.name !== newName) {
|
|
1016
|
+
channel.name = newName;
|
|
1017
|
+
changed = true;
|
|
1018
|
+
this.logInfo("更新私聊频道名称:", { channelId, oldName: channel.name, newName });
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
const channelKeyPrefix = `${data.selfId}:`;
|
|
1023
|
+
for (const [key, messages] of Object.entries(chatData.messages)) {
|
|
1024
|
+
if (key.startsWith(channelKeyPrefix)) {
|
|
1025
|
+
messages.forEach((msg) => {
|
|
1026
|
+
if (msg.userId === data.userId) {
|
|
1027
|
+
if (user.name && msg.username !== user.name) {
|
|
1028
|
+
msg.username = user.name;
|
|
1029
|
+
changed = true;
|
|
1030
|
+
}
|
|
1031
|
+
if (user.avatar && msg.avatar !== user.avatar) {
|
|
1032
|
+
msg.avatar = user.avatar;
|
|
1033
|
+
changed = true;
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
});
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
1039
|
+
if (changed) {
|
|
1040
|
+
this.fileManager.writeChatDataToFile(chatData);
|
|
1041
|
+
this.ctx.console.broadcast("chat-data-updated", {});
|
|
1042
|
+
}
|
|
1043
|
+
}
|
|
1044
|
+
return { success: true, data: user };
|
|
1045
|
+
} catch (error) {
|
|
1046
|
+
return { success: false, error: error?.message || "获取用户信息失败" };
|
|
1047
|
+
}
|
|
1048
|
+
});
|
|
926
1049
|
this.ctx.console.addListener("debug-get-raw-data", async () => {
|
|
927
1050
|
try {
|
|
928
1051
|
const data = this.fileManager.readChatDataFromFile();
|
|
@@ -979,61 +1102,32 @@ var ApiHandlers = class {
|
|
|
979
1102
|
// 设置定时清理临时文件
|
|
980
1103
|
setupTempFileCleanup() {
|
|
981
1104
|
setInterval(() => {
|
|
982
|
-
this.
|
|
1105
|
+
this.cleanupMediaCache();
|
|
983
1106
|
}, 5 * 60 * 1e3);
|
|
984
1107
|
}
|
|
985
|
-
//
|
|
986
|
-
async
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
const
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
return {
|
|
1000
|
-
name: file,
|
|
1001
|
-
path: filePath,
|
|
1002
|
-
mtime: stats.mtime.getTime(),
|
|
1003
|
-
age: fileAge,
|
|
1004
|
-
protected: fileAge < protectionTime
|
|
1005
|
-
// 是否在保护期内
|
|
1006
|
-
};
|
|
1007
|
-
} catch (error) {
|
|
1008
|
-
return null;
|
|
1009
|
-
}
|
|
1010
|
-
}).filter((file) => file !== null).sort((a, b) => b.mtime - a.mtime);
|
|
1011
|
-
const keepCount = this.config.keepTempImages;
|
|
1012
|
-
let cleanedCount = 0;
|
|
1013
|
-
let protectedCount = 0;
|
|
1014
|
-
const protectedFiles = files.filter((file) => file.protected);
|
|
1015
|
-
const deletableFiles = files.filter((file) => !file.protected);
|
|
1016
|
-
protectedCount = protectedFiles.length;
|
|
1017
|
-
if (deletableFiles.length > keepCount) {
|
|
1018
|
-
const filesToDelete = deletableFiles.slice(keepCount);
|
|
1019
|
-
for (const file of filesToDelete) {
|
|
1108
|
+
// 统一清理媒体缓存
|
|
1109
|
+
async cleanupMediaCache() {
|
|
1110
|
+
const baseDir = this.ctx.baseDir + "/data/chat-patch/persist-media";
|
|
1111
|
+
if (!require("node:fs").existsSync(baseDir)) return;
|
|
1112
|
+
const cleanupDir = /* @__PURE__ */ __name((dirName, limit) => {
|
|
1113
|
+
const dirPath = require("node:path").join(baseDir, dirName);
|
|
1114
|
+
if (!require("node:fs").existsSync(dirPath)) return;
|
|
1115
|
+
const files = require("node:fs").readdirSync(dirPath).map((file) => {
|
|
1116
|
+
const filePath = require("node:path").join(dirPath, file);
|
|
1117
|
+
const stats = require("node:fs").statSync(filePath);
|
|
1118
|
+
return { name: file, path: filePath, mtime: stats.mtimeMs };
|
|
1119
|
+
}).sort((a, b) => b.mtime - a.mtime);
|
|
1120
|
+
if (files.length > limit) {
|
|
1121
|
+
files.slice(limit).forEach((f) => {
|
|
1020
1122
|
try {
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
cleanedCount++;
|
|
1024
|
-
this.logInfo("清理多余临时图片:", file.path);
|
|
1025
|
-
}
|
|
1026
|
-
} catch (fileError) {
|
|
1027
|
-
this.logger.warn("删除临时文件失败:", { file: file.name, error: fileError });
|
|
1123
|
+
require("node:fs").unlinkSync(f.path);
|
|
1124
|
+
} catch {
|
|
1028
1125
|
}
|
|
1029
|
-
}
|
|
1030
|
-
}
|
|
1031
|
-
if (cleanedCount > 0 || protectedCount > 0) {
|
|
1032
|
-
this.logInfo(`基于数量清理完成,保留最新 ${keepCount} 张图片,清理了 ${cleanedCount} 张多余图片,保护了 ${protectedCount} 张新上传图片`);
|
|
1126
|
+
});
|
|
1033
1127
|
}
|
|
1034
|
-
}
|
|
1035
|
-
|
|
1036
|
-
|
|
1128
|
+
}, "cleanupDir");
|
|
1129
|
+
cleanupDir("images", 100);
|
|
1130
|
+
cleanupDir("media", 20);
|
|
1037
1131
|
}
|
|
1038
1132
|
logInfo(...args) {
|
|
1039
1133
|
if (this.config.loggerinfo) {
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Context, Session } from 'koishi';
|
|
2
|
+
import { FileManager } from './file-manager';
|
|
3
|
+
import { Config } from './config';
|
|
4
|
+
export declare class MessageHandler {
|
|
5
|
+
private ctx;
|
|
6
|
+
private config;
|
|
7
|
+
private fileManager;
|
|
8
|
+
private logger;
|
|
9
|
+
private utils;
|
|
10
|
+
private correctChannelIds;
|
|
11
|
+
constructor(ctx: Context, config: Config, fileManager: FileManager);
|
|
12
|
+
setCorrectChannelId(selfId: string, channelId: string): void;
|
|
13
|
+
getCorrectChannelId(selfId: string): string | undefined;
|
|
14
|
+
updateBotInfoToFile(session: Session): Promise<void>;
|
|
15
|
+
updateChannelInfoToFile(session: Session): Promise<string>;
|
|
16
|
+
downloadAndCacheMedia(url: string, type: 'image' | 'media' | 'avatar'): Promise<any>;
|
|
17
|
+
private processMediaElements;
|
|
18
|
+
broadcastMessageEvent(session: Session): Promise<void>;
|
|
19
|
+
broadcastBotMessageEvent(session: Session): Promise<void>;
|
|
20
|
+
private logInfo;
|
|
21
|
+
}
|
package/lib/types.d.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { h } from 'koishi';
|
|
2
|
+
export interface BotInfo {
|
|
3
|
+
selfId: string;
|
|
4
|
+
platform: string;
|
|
5
|
+
username: string;
|
|
6
|
+
avatar?: string;
|
|
7
|
+
status: 'online' | 'offline';
|
|
8
|
+
}
|
|
9
|
+
export interface ChannelInfo {
|
|
10
|
+
id: string;
|
|
11
|
+
name: string;
|
|
12
|
+
type: number | string;
|
|
13
|
+
channelId?: string;
|
|
14
|
+
guildName?: string;
|
|
15
|
+
isDirect?: boolean;
|
|
16
|
+
}
|
|
17
|
+
export interface QuoteInfo {
|
|
18
|
+
messageId: string;
|
|
19
|
+
id: string;
|
|
20
|
+
content: string;
|
|
21
|
+
elements?: h[];
|
|
22
|
+
user: {
|
|
23
|
+
id: string;
|
|
24
|
+
name: string;
|
|
25
|
+
userId: string;
|
|
26
|
+
avatar?: string;
|
|
27
|
+
username: string;
|
|
28
|
+
};
|
|
29
|
+
timestamp: number;
|
|
30
|
+
}
|
|
31
|
+
export interface MessageInfo {
|
|
32
|
+
id: string;
|
|
33
|
+
content: string;
|
|
34
|
+
userId: string;
|
|
35
|
+
username: string;
|
|
36
|
+
avatar?: string;
|
|
37
|
+
timestamp: number;
|
|
38
|
+
channelId: string;
|
|
39
|
+
selfId: string;
|
|
40
|
+
elements?: h[];
|
|
41
|
+
type: 'user' | 'bot';
|
|
42
|
+
guildId?: string;
|
|
43
|
+
guildName?: string;
|
|
44
|
+
platform: string;
|
|
45
|
+
quote?: QuoteInfo;
|
|
46
|
+
isDirect?: boolean;
|
|
47
|
+
sending?: boolean;
|
|
48
|
+
realId?: string;
|
|
49
|
+
}
|
|
50
|
+
export interface ChatData {
|
|
51
|
+
bots: Record<string, BotInfo>;
|
|
52
|
+
channels: Record<string, Record<string, ChannelInfo>>;
|
|
53
|
+
messages: Record<string, MessageInfo[]>;
|
|
54
|
+
pinnedBots: string[];
|
|
55
|
+
pinnedChannels: string[];
|
|
56
|
+
lastSaveTime?: number;
|
|
57
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "koishi-plugin-chat-patch",
|
|
3
3
|
"description": "[<ruby>chat-patch<rp>(</rp><rt>点我预览效果</rt><rp>)</rp></ruby>](https://i0.hdslb.com/bfs/openplatform/71074dfc9e5256fc3333d8bd8478bec1af874046.png) 视奸小插件((bushi( (低性能警告)。手机端适配。灵感来自 chat 插件。",
|
|
4
|
-
"version": "2.0
|
|
4
|
+
"version": "2.1.0",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"typings": "lib/index.d.ts",
|
|
7
7
|
"files": [
|