@koishi-ce/plugin-market 1.1.3 → 1.1.4

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/style.css CHANGED
@@ -1,2 +1,2 @@
1
- .confirm-panel td.arrow{padding:0}.confirm-panel td.arrow span{justify-content:center;align-items:center;display:flex}.confirm-panel .el-dialog__footer{justify-content:space-between;align-items:center;display:flex}.manual-panel .k-comment{margin-top:0}.dep-package-view[data-v-0fc4cb55]{height:3rem;position:relative}.dep-package-view .el-button[data-v-0fc4cb55]{width:4rem}.page-deps{flex-flow:column;display:flex}.page-deps .body-container{margin-top:-1px;transform:translateY(1px)}.page-deps table tr:first-child{border-top:none}.page-deps tbody tr{transition:all .3s}.page-deps tbody tr:hover{background-color:var(--k-side-bg)}@media (width<=768px){.page-deps td{padding:.5em}}.theme-color.primary{color:var(--primary)}.theme-color.success{color:var(--success)}.theme-color.warning{color:var(--warning)}.theme-color.danger{color:var(--danger)}.install-panel .el-dialog__header{align-items:center;gap:0 .5em;padding-bottom:4px;padding-right:36px;display:flex}.install-panel .el-dialog__header .el-dialog__title{color:var(--fg1);flex:none;margin-right:.5rem;font-weight:500}.install-panel .el-dialog__header .el-select{flex:auto;max-width:12.5rem;margin:-2px 0 -4px}.install-panel .warning{color:var(--k-color-warning)}.install-panel .danger{color:var(--k-color-danger)}.install-panel .version-badges{float:right;margin-right:-12px}.install-panel .el-dialog__body{min-height:40px;padding:0 20px}.install-panel .el-dialog__body>div{margin:1rem 0}.install-panel .el-dialog__body:last-child{padding-bottom:1rem}.install-panel table thead td,.install-panel table thead th,.install-panel table tbody td,.install-panel table tbody th{white-space:nowrap;padding:.5em .875em}.install-panel span.link:hover{cursor:pointer;text-decoration:underline}.install-panel .el-button+.el-button{margin-left:1rem}.install-panel .el-dialog__footer{justify-content:space-between;align-items:center;display:flex}.install-panel .wrapper{display:inline-flex;position:relative}.install-panel .wrapper .shadow{letter-spacing:1px;visibility:hidden;padding-right:22px}.install-panel .wrapper .el-select{position:absolute;top:50%;left:0;right:0;transform:translateY(-50%)}.dot-hint:before{content:"";background-color:currentColor;border-radius:100%;width:.5rem;height:.5rem;transition:background-color .3s;position:absolute;top:50%;right:20px;transform:translateY(-50%);box-shadow:1px 1px 2px #3333}.market-filter-item[data-v-23068a68]{box-sizing:border-box;color:var(--k-text-normal);z-index:2;cursor:pointer;border-radius:8px;align-items:center;height:28px;margin:2px 0;padding:0 .5rem;transition:color .2s,background-color .2s;display:flex}.market-filter-item[data-v-23068a68]:hover{color:var(--k-text-dark);background-color:var(--k-hover-bg)}.market-filter-item.active[data-v-23068a68]{color:var(--k-color-primary);background-color:color-mix(in srgb, var(--k-color-primary) 10%, transparent)}.market-filter-item.active .text[data-v-23068a68]{font-weight:600}.market-filter-item.active.verified[data-v-23068a68],.market-filter-item.active.newborn[data-v-23068a68]{color:var(--k-color-success);background-color:color-mix(in srgb, var(--k-color-success) 10%, transparent)}.market-filter-item.active.preview[data-v-23068a68],.market-filter-item.active.portable[data-v-23068a68]{color:var(--k-color-warning);background-color:color-mix(in srgb, var(--k-color-warning) 10%, transparent)}.market-filter-item.active.insecure[data-v-23068a68]{color:var(--k-color-danger);background-color:color-mix(in srgb, var(--k-color-danger) 10%, transparent)}.market-filter-item.disabled[data-v-23068a68]{opacity:.5;text-decoration:line-through;text-decoration-thickness:2px}.market-filter-item .icon[data-v-23068a68]{justify-content:center;align-items:center;width:1.75rem;margin-right:4px;display:inline-flex}.market-filter-item:not(.active) .order[data-v-23068a68]{display:none}.market-filter-item .order[data-v-23068a68]{justify-content:center;align-items:center;width:1.75rem;display:inline-flex}.market-filter-item svg[data-v-23068a68]{max-width:1.125rem;height:1rem}.market-filter-item .text[data-v-23068a68],.market-filter-item .count[data-v-23068a68]{font-size:14px;font-weight:500;line-height:20px}.market-filter-item .count[data-v-23068a68]{opacity:.7;margin-right:4px;font-size:12px}.market-filter-item .spacer[data-v-23068a68]{flex:1}.cat-adapter[data-v-715b4290]{--c:#38bdf8}.cat-general[data-v-715b4290]{--c:#4ade80}.cat-extension[data-v-715b4290]{--c:#a78bfa}.cat-webui[data-v-715b4290]{--c:#fb923c}.cat-manage[data-v-715b4290]{--c:#facc15}.cat-preset[data-v-715b4290]{--c:#60a5fa}.cat-image[data-v-715b4290]{--c:#f472b6}.cat-media[data-v-715b4290]{--c:#e879f9}.cat-tool[data-v-715b4290]{--c:#94a3b8}.cat-life[data-v-715b4290]{--c:#34d399}.cat-ai[data-v-715b4290]{--c:#818cf8}.cat-meme[data-v-715b4290]{--c:#fbbf24}.cat-game[data-v-715b4290]{--c:#f87171}.cat-gametool[data-v-715b4290]{--c:#c084fc}.cat-other[data-v-715b4290]{--c:#64748b}.market-package[data-v-715b4290]{box-sizing:border-box;background-color:var(--k-card-bg);border:1px solid var(--k-color-border);contain:layout paint style;border-radius:12px;width:100%;max-width:540px;height:calc(12.5rem + 2px);margin:0;padding:1rem 1.25rem;transition:border-color .18s,box-shadow .18s,background-color .18s;position:relative}.market-package[data-v-715b4290]:hover{border-color:var(--k-color-primary);box-shadow:0 4px 12px #0000000f}.market-package .market-icon[data-v-715b4290]{height:1em;display:inline}.market-package .header[data-v-715b4290],.market-package .footer[data-v-715b4290]{flex:none}.market-package .header[data-v-715b4290]{position:relative}.market-package .header .left[data-v-715b4290]{box-sizing:border-box;border:1px solid color-mix(in srgb, var(--c) 35%, var(--k-color-border));background:linear-gradient(135deg, color-mix(in srgb, var(--c) 18%, var(--k-card-bg)), color-mix(in srgb, var(--c) 10%, var(--k-card-bg)));width:3.5rem;height:3.5rem;transition:var(--color-transition);border-radius:10px}.market-package .header .left svg[data-v-715b4290]{height:1.75rem;color:var(--c)}.market-package .header h2[data-v-715b4290]{align-items:center;margin:0;font-size:1.125rem;font-weight:600;line-height:1.2;display:flex}.market-package .header h2 .title[data-v-715b4290]{flex:0 auto;line-height:1.5rem;display:inline-block}.market-package .header .heartbeat[data-v-715b4290]{height:1.5rem;color:var(--k-text-light);align-items:center;gap:5px;font-size:12px;display:inline-flex}.market-package .header .heartbeat .market-icon[data-v-715b4290]{width:12px;height:12px;color:color-mix(in srgb, #eb4d55 var(--heart-mix,0%), var(--k-text-light));opacity:var(--heart-opacity,.5);filter:drop-shadow(0 0 calc(var(--heart-glow,0) * 4px) rgb(235, 77, 85, calc(var(--heart-glow,0) * .45)));flex:none;transition:color .3s,opacity .3s}.market-package .badge-float[data-v-715b4290]{position:absolute;bottom:2.5rem;right:1.25rem}.market-package .badge-pill[data-v-715b4290]{box-sizing:border-box;border:1px solid color-mix(in srgb, var(--k-color-success) 20%, transparent);background-color:color-mix(in srgb, var(--k-color-success) 10%, transparent);height:20px;color:var(--k-color-success);cursor:pointer;-webkit-user-select:none;user-select:none;border-radius:10px;align-items:center;gap:3px;padding:0 6px;font-size:12px;font-weight:500;line-height:20px;display:inline-flex}.market-package .badge-pill .market-icon[data-v-715b4290]{width:12px;height:12px}.market-package .badge-pill.preview[data-v-715b4290]{border-color:color-mix(in srgb, var(--k-color-warning) 20%, transparent);background-color:color-mix(in srgb, var(--k-color-warning) 10%, transparent);color:var(--k-color-warning)}.market-package .badge-pill.insecure[data-v-715b4290]{border-color:color-mix(in srgb, var(--k-color-danger) 20%, transparent);background-color:color-mix(in srgb, var(--k-color-danger) 10%, transparent);color:var(--k-color-danger)}.market-package .desc[data-v-715b4290]{color:var(--k-text-light);word-break:break-word;text-overflow:ellipsis;-webkit-line-clamp:3;-webkit-box-orient:vertical;flex:auto;margin:0;font-size:14px;line-height:1.6;display:-webkit-box;overflow:hidden}.market-package .footer[data-v-715b4290]{cursor:default;height:1.5rem;color:var(--k-text-light);align-items:center;gap:.5rem;margin-bottom:-.25rem;font-size:13px;transition:color .3s;display:flex;overflow:hidden}.market-package .footer[data-v-715b4290]>*{flex:none}.market-package .footer .spacer[data-v-715b4290]{flex:0 2 .5rem}.market-package .footer .long-spacer[data-v-715b4290]{flex:auto}.market-package .footer .market-icon[data-v-715b4290]{vertical-align:-1px;width:16px;height:12px;margin-right:6px}.market-package .footer .avatars[data-v-715b4290]{gap:.25rem;display:flex}.market-package .footer .avatars .avatar[data-v-715b4290]{cursor:pointer;border-radius:100%;width:1.5rem;height:1.5rem}.market-package .footer .avatars .avatar img[data-v-715b4290]{vertical-align:middle;border-radius:100%;width:1.5rem;height:1.5rem}.market-package .footer .avatars .avatar.fallback[data-v-715b4290]{box-sizing:border-box;background:linear-gradient(135deg, color-mix(in srgb, var(--c) 30%, var(--k-card-bg)), color-mix(in srgb, var(--c) 12%, var(--k-card-bg)));color:color-mix(in srgb, var(--c) 80%, var(--k-text-dark));justify-content:center;align-items:center;font-size:.68rem;font-weight:700;display:inline-flex}.market-package .footer .avatars .avatar.fallback[data-v-715b4290]:before{content:attr(data-initial)}@media (width<=420px){.market-package[data-v-715b4290]{height:auto;min-height:11rem;padding:.82rem .9rem}.market-package .header .left[data-v-715b4290]{width:3rem;height:3rem}.market-package h2[data-v-715b4290]{font-size:1rem}.market-package .badge-float[data-v-715b4290]{bottom:2.3rem;right:.9rem}.market-package .footer[data-v-715b4290]{flex-wrap:wrap;height:auto}.market-package .footer .long-spacer[data-v-715b4290]{display:none}}.package-list[data-v-7274b89c]{gap:var(--card-margin);flex:1 0 auto;grid-template-columns:repeat(auto-fill,minmax(336px,1fr));justify-items:center;display:grid}.pagination[data-v-7274b89c]{margin:var(--card-margin) 0;justify-content:center}.k-empty[data-v-7274b89c]{flex:1 0 auto}.search-box[data-v-98462ea9]{border:1.5px solid var(--k-color-border);box-sizing:border-box;background-color:var(--k-card-bg);border-radius:2rem;align-items:center;width:100%;max-width:640px;margin:2rem auto 0;transition:border-color .2s,box-shadow .2s;display:flex;box-shadow:0 2px 12px #0000000f,0 1px 3px #0000000a}.search-box[data-v-98462ea9]:focus-within{border-color:var(--k-color-primary);box-shadow:0 0 0 3px color-mix(in srgb, var(--k-color-primary) 15%, transparent), 0 2px 12px #0000000f, 0 1px 3px #0000000a}.search-container[data-v-98462ea9]{flex-wrap:wrap;flex:auto;align-items:center;gap:8px 6px;padding:.75rem 0 .75rem 1.25rem;display:flex}.search-container input[data-v-98462ea9]{box-sizing:border-box;min-width:10rem;height:1.25rem;color:inherit;background-color:#0000;border:none;outline:none;flex:auto;padding:0;font-size:.925rem}.search-action[data-v-98462ea9]{cursor:pointer;flex-direction:column;flex:none;justify-content:center;align-items:center;width:3rem;height:2.5rem;display:flex}.search-action .market-icon[data-v-98462ea9]{opacity:.45;height:1rem;transition:opacity .2s}.search-action:hover .market-icon[data-v-98462ea9]{opacity:.85}.search-action:hover .market-icon.search[data-v-98462ea9],.search-action:not(:hover) .market-icon.close[data-v-98462ea9]{display:none}.search-word[data-v-98462ea9]{box-sizing:border-box;border:1px solid color-mix(in srgb, var(--k-color-primary) 25%, transparent);background-color:color-mix(in srgb, var(--k-color-primary) 12%, transparent);height:1.375rem;color:var(--k-color-primary);white-space:nowrap;vertical-align:baseline;cursor:pointer;-webkit-user-select:none;user-select:none;border-radius:6px;flex:none;padding:0 8px;font-size:12px;font-weight:500;line-height:calc(1.375rem - 2px);transition:opacity .3s,background-color .3s,border-color .3s;display:inline-block}.search-word.invalid[data-v-98462ea9]{opacity:.5;text-decoration:line-through}.search-word.invalid[data-v-98462ea9]:hover{opacity:1}@media (width<=420px){.search-box[data-v-98462ea9]{border-radius:12px}}.page-market .layout-main .el-scrollbar__view{padding:0 var(--card-margin);flex-direction:column;min-height:100%;display:flex}.page-market .layout-left .market-filter-group{margin:1.5rem 0;padding:0 1rem}.page-market .layout-left h2{letter-spacing:.08em;text-transform:uppercase;color:var(--k-text-light);opacity:.7;margin:0;padding:6px .5rem;font-size:11px;font-weight:700}.market-loading{flex-direction:column;flex:1 0 auto;justify-content:center;align-items:center;gap:2rem;min-height:50vh;display:flex}.market-loading .el-loading-spinner{margin-top:0}.market-slow.k-comment{max-width:640px}.market-hint{width:100%;color:var(--el-text-color-regular);font-size:var(--el-font-size-base);font-weight:var(--el-font-weight-primary);margin:1rem 0 .75rem;transition:color .3s}.market-container .k-button{margin-left:1rem;padding:.35em .85em;transform:translateY(-1px)}.market-error.k-comment{margin-left:2rem;margin-right:2rem}.page-market .el-scrollbar__thumb{background-clip:content-box;background-color:color-mix(in srgb, var(--k-color-primary) 26%, var(--fg3));border:2px solid #0000;border-radius:999px;min-height:32px}.page-market .el-scrollbar__thumb:hover{background-color:color-mix(in srgb, var(--k-color-primary) 44%, var(--fg3))}.k-status .el-progress-bar{width:120px;margin-right:2px}.dialog-config-fork .el-dialog__header .el-dialog__title{color:var(--fg1);flex:none;margin-right:.5rem;font-weight:500}.dialog-config-fork .status-light{margin-right:.75rem}.dialog-config-fork .actions{justify-content:flex-end;align-items:center;gap:0 .5rem;display:flex}.dialog-config-fork .action{cursor:pointer;width:1.25rem;color:var(--fg2);transition:var(--color-transition);justify-content:center;display:inline-flex}.dialog-config-fork .action:hover{color:var(--fg1)}.dialog-config-fork .el-dialog__footer{justify-content:space-between;align-items:center;font-size:.9em;display:flex}.modifier,.plugin-view .markdown.usage{margin-bottom:2rem}.plugin-view .markdown.usage h2{font-size:1.25rem}.plugin-tree{width:100%;height:100%;overflow:auto}.plugin-tree .el-scrollbar__view{padding:1rem 0;line-height:2.25rem}.plugin-tree .search{padding:0 1.5rem}.plugin-tree .k-icon-filter{height:15px}.plugin-tree .el-tree-node.is-group>.el-tree-node__content{font-weight:700}.plugin-tree .el-tree-node__content .item{flex:1;justify-content:space-between;align-items:center;height:100%;display:flex;overflow:hidden}.plugin-tree .el-tree-node__content .label{text-overflow:ellipsis;transition:var(--color-transition);overflow:hidden}.plugin-tree .el-tree-node__content .right{height:100%;margin:0 1.5rem 0 .5rem}.end{margin-right:.5rem}.config-header{margin:0 0 2rem;font-size:1.375rem;line-height:2rem}.config-header .k-button{float:right}.plugin-view .k-content>:first-child{margin-top:0}.plugin-select .el-dialog__header{border-bottom:1px solid var(--k-color-divider);justify-content:space-between;align-items:center;margin-right:0;padding:12px 20px;display:flex}.plugin-select .el-dialog__header button{top:2px}.plugin-select .el-dialog__header .title{flex:none}.plugin-select .el-dialog__header .el-input{width:220px;height:2rem;display:inline-block}.plugin-select .el-dialog__body{height:50vh;padding:0;display:flex}.plugin-select .el-dialog__body .tabs{border-right:1px solid var(--k-color-divider);flex:none;width:7.5rem;font-size:15px}@media screen and (width<=768px){.plugin-select .el-dialog__body .tabs{width:3rem}}.plugin-select .el-dialog__body .tabs .el-scrollbar__view{padding:.5rem 0}.plugin-select .el-dialog__body .tabs .tab-item{cursor:pointer;height:2rem;transition:var(--color-transition);justify-content:center;align-items:center;padding:0 1rem;font-size:.875rem;display:flex}.plugin-select .el-dialog__body .tabs .tab-item:hover{background-color:var(--k-hover-bg)}@media screen and (width<=768px){.plugin-select .el-dialog__body .tabs .tab-item{padding:0}}.plugin-select .el-dialog__body .tabs .tab-item .market-icon{width:1.25rem;height:1rem}.plugin-select .el-dialog__body .tabs .tab-item.active{color:var(--primary)}.plugin-select .el-dialog__body .tabs .tab-item .title{width:3.5rem;margin-left:.5rem}@media screen and (width<=768px){.plugin-select .el-dialog__body .tabs .tab-item .title{display:none}}.plugin-select .el-dialog__body .content{flex:auto}.plugin-select .el-dialog__body .content .package{cursor:pointer;transition:var(--color-transition);padding:.5rem 1rem}.plugin-select .el-dialog__body .content .package h3{margin:0 0 .25rem;font-size:16px}.plugin-select .el-dialog__body .content .package p{margin:0;font-size:14px}.plugin-select .el-dialog__body .content .package:hover{background-color:var(--k-hover-bg)}.absolute{position:absolute}.relative{position:relative}.grid{display:grid}.my-8{margin-top:2rem;margin-bottom:2rem}.inline{display:inline}.inline-block{display:inline-block}.hidden{display:none}.h2{height:.5rem}.h3{height:.75rem}.flex{display:flex}.inline-flex{display:inline-flex}.shrink-0{flex-shrink:0}.grow-1{flex-grow:1}.flex-row{flex-direction:row}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.transform{transform:translateX(var(--un-translate-x)) translateY(var(--un-translate-y)) translateZ(var(--un-translate-z)) rotate(var(--un-rotate)) rotateX(var(--un-rotate-x)) rotateY(var(--un-rotate-y)) rotateZ(var(--un-rotate-z)) skewX(var(--un-skew-x)) skewY(var(--un-skew-y)) scaleX(var(--un-scale-x)) scaleY(var(--un-scale-y)) scaleZ(var(--un-scale-z))}.items-center{align-items:center}.justify-center{justify-content:center}.justify-around{justify-content:space-around}.gap-1{gap:.25rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-x-4{column-gap:1rem}.gap-y-2{row-gap:.5rem}.overflow-hidden{overflow:hidden}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.b,.border{border-width:1px}.pl-8{padding-left:2rem}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.line-through{text-decoration-line:line-through}.underline{text-decoration-line:underline}.shadow{--un-shadow:var(--un-shadow-inset) 0 1px 3px 0 var(--un-shadow-color,#0000001a),var(--un-shadow-inset) 0 1px 2px -1px var(--un-shadow-color,#0000001a);box-shadow:var(--un-ring-offset-shadow), var(--un-ring-shadow), var(--un-shadow)}.outline{outline-style:solid}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter,backdrop-filter;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.ease{transition-timing-function:cubic-bezier(.4,0,.2,1)}.dialog-config-fork .status-light,.plugin-tree .status-light{width:.625rem;height:.625rem;transition:var(--color-transition);border-radius:100%;display:inline-block}.dialog-config-fork .status-light.active,.plugin-tree .status-light.active{background-color:var(--k-color-success)}.dialog-config-fork .status-light.pending,.plugin-tree .status-light.pending{background-color:var(--k-color-warning)}.dialog-config-fork .status-light.loading,.plugin-tree .status-light.loading{background-color:var(--k-color-warning);animation:1s infinite status-flash}.dialog-config-fork .status-light.failed,.plugin-tree .status-light.failed{background-color:var(--k-color-danger)}.dialog-config-fork .status-light.disabled:not(.ignore-disabled),.plugin-tree .status-light.disabled:not(.ignore-disabled){opacity:.5;background-color:var(--k-color-disabled)}@keyframes status-flash{0%,to{opacity:0}50%{opacity:1}}
1
+ .confirm-panel td.arrow{padding:0}.confirm-panel td.arrow span{justify-content:center;align-items:center;display:flex}.confirm-panel .el-dialog__footer{justify-content:space-between;align-items:center;display:flex}.manual-panel .k-comment{margin-top:0}.dep-package-view[data-v-171c4d25]{height:3rem;position:relative}.dep-package-view .el-button[data-v-171c4d25]{width:4rem}.page-deps{flex-flow:column;display:flex}.page-deps .body-container{margin-top:-1px;transform:translateY(1px)}.page-deps table tr:first-child{border-top:none}.page-deps tbody tr{transition:all .3s}.page-deps tbody tr:hover{background-color:var(--k-side-bg)}@media (width<=768px){.page-deps td{padding:.5em}}.theme-color.primary{color:var(--primary)}.theme-color.success{color:var(--success)}.theme-color.warning{color:var(--warning)}.theme-color.danger{color:var(--danger)}.install-panel .el-dialog__header{align-items:center;gap:0 .5em;padding-bottom:4px;padding-right:36px;display:flex}.install-panel .el-dialog__header .el-dialog__title{color:var(--fg1);flex:none;margin-right:.5rem;font-weight:500}.install-panel .el-dialog__header .el-select{flex:auto;max-width:12.5rem;margin:-2px 0 -4px}.install-panel .warning{color:var(--k-color-warning)}.install-panel .danger{color:var(--k-color-danger)}.install-panel .version-badges{float:right;margin-right:-12px}.install-panel .el-dialog__body{min-height:40px;padding:0 20px}.install-panel .el-dialog__body>div{margin:1rem 0}.install-panel .el-dialog__body:last-child{padding-bottom:1rem}.install-panel table thead td,.install-panel table thead th,.install-panel table tbody td,.install-panel table tbody th{white-space:nowrap;padding:.5em .875em}.install-panel span.link:hover{cursor:pointer;text-decoration:underline}.install-panel .el-button+.el-button{margin-left:1rem}.install-panel .el-dialog__footer{justify-content:space-between;align-items:center;display:flex}.install-panel .wrapper{display:inline-flex;position:relative}.install-panel .wrapper .shadow{letter-spacing:1px;visibility:hidden;padding-right:22px}.install-panel .wrapper .el-select{position:absolute;top:50%;left:0;right:0;transform:translateY(-50%)}.dot-hint:before{content:"";background-color:currentColor;border-radius:100%;width:.5rem;height:.5rem;transition:background-color .3s;position:absolute;top:50%;right:20px;transform:translateY(-50%);box-shadow:1px 1px 2px #3333}.market-filter-item[data-v-cc4310be]{box-sizing:border-box;color:var(--k-text-normal);z-index:2;cursor:pointer;border-radius:8px;align-items:center;height:28px;margin:2px 0;padding:0 .5rem;transition:color .2s,background-color .2s;display:flex}.market-filter-item[data-v-cc4310be]:hover{color:var(--k-text-dark);background-color:var(--k-hover-bg)}.market-filter-item.active[data-v-cc4310be]{color:var(--k-color-primary);background-color:color-mix(in srgb, var(--k-color-primary) 10%, transparent)}.market-filter-item.active .text[data-v-cc4310be]{font-weight:600}.market-filter-item.active.verified[data-v-cc4310be],.market-filter-item.active.newborn[data-v-cc4310be]{color:var(--k-color-success);background-color:color-mix(in srgb, var(--k-color-success) 10%, transparent)}.market-filter-item.active.preview[data-v-cc4310be],.market-filter-item.active.portable[data-v-cc4310be]{color:var(--k-color-warning);background-color:color-mix(in srgb, var(--k-color-warning) 10%, transparent)}.market-filter-item.active.insecure[data-v-cc4310be]{color:var(--k-color-danger);background-color:color-mix(in srgb, var(--k-color-danger) 10%, transparent)}.market-filter-item.disabled[data-v-cc4310be]{opacity:.5;text-decoration:line-through;text-decoration-thickness:2px}.market-filter-item .icon[data-v-cc4310be]{justify-content:center;align-items:center;width:1.75rem;margin-right:4px;display:inline-flex}.market-filter-item:not(.active) .order[data-v-cc4310be]{display:none}.market-filter-item .order[data-v-cc4310be]{justify-content:center;align-items:center;width:1.75rem;display:inline-flex}.market-filter-item svg[data-v-cc4310be]{max-width:1.125rem;height:1rem}.market-filter-item .text[data-v-cc4310be],.market-filter-item .count[data-v-cc4310be]{font-size:14px;font-weight:500;line-height:20px}.market-filter-item .count[data-v-cc4310be]{opacity:.7;margin-right:4px;font-size:12px}.market-filter-item .spacer[data-v-cc4310be]{flex:1}.cat-adapter[data-v-b54f5ebc]{--c:#38bdf8}.cat-general[data-v-b54f5ebc]{--c:#4ade80}.cat-extension[data-v-b54f5ebc]{--c:#a78bfa}.cat-webui[data-v-b54f5ebc]{--c:#fb923c}.cat-manage[data-v-b54f5ebc]{--c:#facc15}.cat-preset[data-v-b54f5ebc]{--c:#60a5fa}.cat-image[data-v-b54f5ebc]{--c:#f472b6}.cat-media[data-v-b54f5ebc]{--c:#e879f9}.cat-tool[data-v-b54f5ebc]{--c:#94a3b8}.cat-life[data-v-b54f5ebc]{--c:#34d399}.cat-ai[data-v-b54f5ebc]{--c:#818cf8}.cat-meme[data-v-b54f5ebc]{--c:#fbbf24}.cat-game[data-v-b54f5ebc]{--c:#f87171}.cat-gametool[data-v-b54f5ebc]{--c:#c084fc}.cat-other[data-v-b54f5ebc]{--c:#64748b}.market-package[data-v-b54f5ebc]{box-sizing:border-box;background-color:var(--k-card-bg);border:1px solid var(--k-color-border);contain:layout paint style;border-radius:12px;width:100%;max-width:540px;height:calc(12.5rem + 2px);margin:0;padding:1rem 1.25rem;transition:border-color .18s,box-shadow .18s,background-color .18s;position:relative}.market-package[data-v-b54f5ebc]:hover{border-color:var(--k-color-primary);box-shadow:0 4px 12px #0000000f}.market-package .market-icon[data-v-b54f5ebc]{height:1em;display:inline}.market-package .header[data-v-b54f5ebc],.market-package .footer[data-v-b54f5ebc]{flex:none}.market-package .header[data-v-b54f5ebc]{position:relative}.market-package .header .left[data-v-b54f5ebc]{box-sizing:border-box;border:1px solid color-mix(in srgb, var(--c) 35%, var(--k-color-border));background:linear-gradient(135deg, color-mix(in srgb, var(--c) 18%, var(--k-card-bg)), color-mix(in srgb, var(--c) 10%, var(--k-card-bg)));width:3.5rem;height:3.5rem;transition:var(--color-transition);border-radius:10px}.market-package .header .left svg[data-v-b54f5ebc]{height:1.75rem;color:var(--c)}.market-package .header h2[data-v-b54f5ebc]{align-items:center;margin:0;font-size:1.125rem;font-weight:600;line-height:1.2;display:flex}.market-package .header h2 .title[data-v-b54f5ebc]{flex:0 auto;line-height:1.5rem;display:inline-block}.market-package .header .heartbeat[data-v-b54f5ebc]{height:1.5rem;color:var(--k-text-light);align-items:center;gap:5px;font-size:12px;display:inline-flex}.market-package .header .heartbeat .market-icon[data-v-b54f5ebc]{width:12px;height:12px;color:color-mix(in srgb, #eb4d55 var(--heart-mix,0%), var(--k-text-light));opacity:var(--heart-opacity,.5);filter:drop-shadow(0 0 calc(var(--heart-glow,0) * 4px) rgb(235, 77, 85, calc(var(--heart-glow,0) * .45)));flex:none;transition:color .3s,opacity .3s}.market-package .badge-float[data-v-b54f5ebc]{position:absolute;bottom:2.5rem;right:1.25rem}.market-package .badge-pill[data-v-b54f5ebc]{box-sizing:border-box;border:1px solid color-mix(in srgb, var(--k-color-success) 20%, transparent);background-color:color-mix(in srgb, var(--k-color-success) 10%, transparent);height:20px;color:var(--k-color-success);cursor:pointer;-webkit-user-select:none;user-select:none;border-radius:10px;align-items:center;gap:3px;padding:0 6px;font-size:12px;font-weight:500;line-height:20px;display:inline-flex}.market-package .badge-pill .market-icon[data-v-b54f5ebc]{width:12px;height:12px}.market-package .badge-pill.preview[data-v-b54f5ebc]{border-color:color-mix(in srgb, var(--k-color-warning) 20%, transparent);background-color:color-mix(in srgb, var(--k-color-warning) 10%, transparent);color:var(--k-color-warning)}.market-package .badge-pill.insecure[data-v-b54f5ebc]{border-color:color-mix(in srgb, var(--k-color-danger) 20%, transparent);background-color:color-mix(in srgb, var(--k-color-danger) 10%, transparent);color:var(--k-color-danger)}.market-package .desc[data-v-b54f5ebc]{color:var(--k-text-light);word-break:break-word;text-overflow:ellipsis;-webkit-line-clamp:3;-webkit-box-orient:vertical;flex:auto;margin:0;font-size:14px;line-height:1.6;display:-webkit-box;overflow:hidden}.market-package .footer[data-v-b54f5ebc]{cursor:default;height:1.5rem;color:var(--k-text-light);align-items:center;gap:.5rem;margin-bottom:-.25rem;font-size:13px;transition:color .3s;display:flex;overflow:hidden}.market-package .footer[data-v-b54f5ebc]>*{flex:none}.market-package .footer .spacer[data-v-b54f5ebc]{flex:0 2 .5rem}.market-package .footer .long-spacer[data-v-b54f5ebc]{flex:auto}.market-package .footer .market-icon[data-v-b54f5ebc]{vertical-align:-1px;width:16px;height:12px;margin-right:6px}.market-package .footer .avatars[data-v-b54f5ebc]{gap:.25rem;display:flex}.market-package .footer .avatars .avatar[data-v-b54f5ebc]{cursor:pointer;border-radius:100%;width:1.5rem;height:1.5rem}.market-package .footer .avatars .avatar img[data-v-b54f5ebc]{vertical-align:middle;border-radius:100%;width:1.5rem;height:1.5rem}.market-package .footer .avatars .avatar.fallback[data-v-b54f5ebc]{box-sizing:border-box;background:linear-gradient(135deg, color-mix(in srgb, var(--c) 30%, var(--k-card-bg)), color-mix(in srgb, var(--c) 12%, var(--k-card-bg)));color:color-mix(in srgb, var(--c) 80%, var(--k-text-dark));justify-content:center;align-items:center;font-size:.68rem;font-weight:700;display:inline-flex}.market-package .footer .avatars .avatar.fallback[data-v-b54f5ebc]:before{content:attr(data-initial)}@media (width<=420px){.market-package[data-v-b54f5ebc]{height:auto;min-height:11rem;padding:.82rem .9rem}.market-package .header .left[data-v-b54f5ebc]{width:3rem;height:3rem}.market-package h2[data-v-b54f5ebc]{font-size:1rem}.market-package .badge-float[data-v-b54f5ebc]{bottom:2.3rem;right:.9rem}.market-package .footer[data-v-b54f5ebc]{flex-wrap:wrap;height:auto}.market-package .footer .long-spacer[data-v-b54f5ebc]{display:none}}.package-list[data-v-a6a009ba]{gap:var(--card-margin);flex:1 0 auto;grid-template-columns:repeat(auto-fill,minmax(336px,1fr));justify-items:center;display:grid}.pagination[data-v-a6a009ba]{margin:var(--card-margin) 0;justify-content:center}.k-empty[data-v-a6a009ba]{flex:1 0 auto}.search-box[data-v-283643d9]{border:1.5px solid var(--k-color-border);box-sizing:border-box;background-color:var(--k-card-bg);border-radius:2rem;align-items:center;width:100%;max-width:640px;margin:2rem auto 0;transition:border-color .2s,box-shadow .2s;display:flex;box-shadow:0 2px 12px #0000000f,0 1px 3px #0000000a}.search-box[data-v-283643d9]:focus-within{border-color:var(--k-color-primary);box-shadow:0 0 0 3px color-mix(in srgb, var(--k-color-primary) 15%, transparent), 0 2px 12px #0000000f, 0 1px 3px #0000000a}.search-container[data-v-283643d9]{flex-wrap:wrap;flex:auto;align-items:center;gap:8px 6px;padding:.75rem 0 .75rem 1.25rem;display:flex}.search-container input[data-v-283643d9]{box-sizing:border-box;min-width:10rem;height:1.25rem;color:inherit;background-color:#0000;border:none;outline:none;flex:auto;padding:0;font-size:.925rem}.search-action[data-v-283643d9]{cursor:pointer;flex-direction:column;flex:none;justify-content:center;align-items:center;width:3rem;height:2.5rem;display:flex}.search-action .market-icon[data-v-283643d9]{opacity:.45;height:1rem;transition:opacity .2s}.search-action:hover .market-icon[data-v-283643d9]{opacity:.85}.search-action:hover .market-icon.search[data-v-283643d9],.search-action:not(:hover) .market-icon.close[data-v-283643d9]{display:none}.search-word[data-v-283643d9]{box-sizing:border-box;border:1px solid color-mix(in srgb, var(--k-color-primary) 25%, transparent);background-color:color-mix(in srgb, var(--k-color-primary) 12%, transparent);height:1.375rem;color:var(--k-color-primary);white-space:nowrap;vertical-align:baseline;cursor:pointer;-webkit-user-select:none;user-select:none;border-radius:6px;flex:none;padding:0 8px;font-size:12px;font-weight:500;line-height:calc(1.375rem - 2px);transition:opacity .3s,background-color .3s,border-color .3s;display:inline-block}.search-word.invalid[data-v-283643d9]{opacity:.5;text-decoration:line-through}.search-word.invalid[data-v-283643d9]:hover{opacity:1}@media (width<=420px){.search-box[data-v-283643d9]{border-radius:12px}}.page-market .layout-main .el-scrollbar__view{padding:0 var(--card-margin);flex-direction:column;min-height:100%;display:flex}.page-market .layout-left .market-filter-group{margin:1.5rem 0;padding:0 1rem}.page-market .layout-left h2{letter-spacing:.08em;text-transform:uppercase;color:var(--k-text-light);opacity:.7;margin:0;padding:6px .5rem;font-size:11px;font-weight:700}.market-loading{flex-direction:column;flex:1 0 auto;justify-content:center;align-items:center;gap:2rem;min-height:50vh;display:flex}.market-loading .el-loading-spinner{margin-top:0}.market-slow.k-comment{max-width:640px}.market-hint{width:100%;color:var(--el-text-color-regular);font-size:var(--el-font-size-base);font-weight:var(--el-font-weight-primary);margin:1rem 0 .75rem;transition:color .3s}.market-container .k-button{margin-left:1rem;padding:.35em .85em;transform:translateY(-1px)}.market-error.k-comment{margin-left:2rem;margin-right:2rem}.page-market .el-scrollbar__thumb{background-clip:content-box;background-color:color-mix(in srgb, var(--k-color-primary) 26%, var(--fg3));border:2px solid #0000;border-radius:999px;min-height:32px}.page-market .el-scrollbar__thumb:hover{background-color:color-mix(in srgb, var(--k-color-primary) 44%, var(--fg3))}.k-status .el-progress-bar{width:120px;margin-right:2px}.dialog-config-fork .el-dialog__header .el-dialog__title{color:var(--fg1);flex:none;margin-right:.5rem;font-weight:500}.dialog-config-fork .status-light{margin-right:.75rem}.dialog-config-fork .actions{justify-content:flex-end;align-items:center;gap:0 .5rem;display:flex}.dialog-config-fork .action{cursor:pointer;width:1.25rem;color:var(--fg2);transition:var(--color-transition);justify-content:center;display:inline-flex}.dialog-config-fork .action:hover{color:var(--fg1)}.dialog-config-fork .el-dialog__footer{justify-content:space-between;align-items:center;font-size:.9em;display:flex}.modifier,.plugin-view .markdown.usage{margin-bottom:2rem}.plugin-view .markdown.usage h2{font-size:1.25rem}.plugin-tree{width:100%;height:100%;overflow:auto}.plugin-tree .el-scrollbar__view{padding:1rem 0;line-height:2.25rem}.plugin-tree .search{padding:0 1.5rem}.plugin-tree .k-icon-filter{height:15px}.plugin-tree .el-tree-node.is-group>.el-tree-node__content{font-weight:700}.plugin-tree .el-tree-node__content .item{flex:1;justify-content:space-between;align-items:center;height:100%;display:flex;overflow:hidden}.plugin-tree .el-tree-node__content .label{text-overflow:ellipsis;transition:var(--color-transition);overflow:hidden}.plugin-tree .el-tree-node__content .right{height:100%;margin:0 1.5rem 0 .5rem}.end{margin-right:.5rem}.config-header{margin:0 0 2rem;font-size:1.375rem;line-height:2rem}.config-header .k-button{float:right}.plugin-view .k-content>:first-child{margin-top:0}.plugin-select .el-dialog__header{border-bottom:1px solid var(--k-color-divider);justify-content:space-between;align-items:center;margin-right:0;padding:12px 20px;display:flex}.plugin-select .el-dialog__header button{top:2px}.plugin-select .el-dialog__header .title{flex:none}.plugin-select .el-dialog__header .el-input{width:220px;height:2rem;display:inline-block}.plugin-select .el-dialog__body{height:50vh;padding:0;display:flex}.plugin-select .el-dialog__body .tabs{border-right:1px solid var(--k-color-divider);flex:none;width:7.5rem;font-size:15px}@media screen and (width<=768px){.plugin-select .el-dialog__body .tabs{width:3rem}}.plugin-select .el-dialog__body .tabs .el-scrollbar__view{padding:.5rem 0}.plugin-select .el-dialog__body .tabs .tab-item{cursor:pointer;height:2rem;transition:var(--color-transition);justify-content:center;align-items:center;padding:0 1rem;font-size:.875rem;display:flex}.plugin-select .el-dialog__body .tabs .tab-item:hover{background-color:var(--k-hover-bg)}@media screen and (width<=768px){.plugin-select .el-dialog__body .tabs .tab-item{padding:0}}.plugin-select .el-dialog__body .tabs .tab-item .market-icon{width:1.25rem;height:1rem}.plugin-select .el-dialog__body .tabs .tab-item.active{color:var(--primary)}.plugin-select .el-dialog__body .tabs .tab-item .title{width:3.5rem;margin-left:.5rem}@media screen and (width<=768px){.plugin-select .el-dialog__body .tabs .tab-item .title{display:none}}.plugin-select .el-dialog__body .content{flex:auto}.plugin-select .el-dialog__body .content .package{cursor:pointer;transition:var(--color-transition);padding:.5rem 1rem}.plugin-select .el-dialog__body .content .package h3{margin:0 0 .25rem;font-size:16px}.plugin-select .el-dialog__body .content .package p{margin:0;font-size:14px}.plugin-select .el-dialog__body .content .package:hover{background-color:var(--k-hover-bg)}.absolute{position:absolute}.relative{position:relative}.grid{display:grid}.my-8{margin-top:2rem;margin-bottom:2rem}.inline{display:inline}.inline-block{display:inline-block}.hidden{display:none}.h2{height:.5rem}.h3{height:.75rem}.flex{display:flex}.inline-flex{display:inline-flex}.shrink-0{flex-shrink:0}.grow-1{flex-grow:1}.flex-row{flex-direction:row}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.transform{transform:translateX(var(--un-translate-x)) translateY(var(--un-translate-y)) translateZ(var(--un-translate-z)) rotate(var(--un-rotate)) rotateX(var(--un-rotate-x)) rotateY(var(--un-rotate-y)) rotateZ(var(--un-rotate-z)) skewX(var(--un-skew-x)) skewY(var(--un-skew-y)) scaleX(var(--un-scale-x)) scaleY(var(--un-scale-y)) scaleZ(var(--un-scale-z))}.items-center{align-items:center}.justify-center{justify-content:center}.justify-around{justify-content:space-around}.gap-1{gap:.25rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-x-4{column-gap:1rem}.gap-y-2{row-gap:.5rem}.overflow-hidden{overflow:hidden}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.b,.border{border-width:1px}.pl-8{padding-left:2rem}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.line-through{text-decoration-line:line-through}.underline{text-decoration-line:underline}.shadow{--un-shadow:var(--un-shadow-inset) 0 1px 3px 0 var(--un-shadow-color,#0000001a),var(--un-shadow-inset) 0 1px 2px -1px var(--un-shadow-color,#0000001a);box-shadow:var(--un-ring-offset-shadow), var(--un-ring-shadow), var(--un-shadow)}.outline{outline-style:solid}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter,backdrop-filter;transition-duration:.15s;transition-timing-function:cubic-bezier(.4,0,.2,1)}.ease{transition-timing-function:cubic-bezier(.4,0,.2,1)}.dialog-config-fork .status-light,.plugin-tree .status-light{width:.625rem;height:.625rem;transition:var(--color-transition);border-radius:100%;display:inline-block}.dialog-config-fork .status-light.active,.plugin-tree .status-light.active{background-color:var(--k-color-success)}.dialog-config-fork .status-light.pending,.plugin-tree .status-light.pending{background-color:var(--k-color-warning)}.dialog-config-fork .status-light.loading,.plugin-tree .status-light.loading{background-color:var(--k-color-warning);animation:1s infinite status-flash}.dialog-config-fork .status-light.failed,.plugin-tree .status-light.failed{background-color:var(--k-color-danger)}.dialog-config-fork .status-light.disabled:not(.ignore-disabled),.plugin-tree .status-light.disabled:not(.ignore-disabled){opacity:.5;background-color:var(--k-color-disabled)}@keyframes status-flash{0%,to{opacity:0}50%{opacity:1}}
2
2
  /*$vite$:1*/
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@koishi-ce/plugin-market",
3
3
  "description": "Manage your bots and plugins with console",
4
- "version": "1.1.3",
4
+ "version": "1.1.4",
5
5
  "type": "module",
6
6
  "main": "lib/index.mjs",
7
7
  "typings": "lib/index.d.ts",
@@ -60,10 +60,10 @@
60
60
  }
61
61
  },
62
62
  "devDependencies": {
63
- "@koishi-ce/plugin-database-memory": "^1.1.0",
63
+ "@koishi-ce/plugin-database-memory": "^1.1.1",
64
64
  "@koishi-ce/client": "^1.3.0",
65
- "@koishi-ce/loader": "^1.1.0",
66
- "@koishi-ce/plugin-config": "^1.1.4",
65
+ "@koishi-ce/loader": "^1.1.1",
66
+ "@koishi-ce/plugin-config": "^1.1.5",
67
67
  "@koishi-ce/components": "^1.0.4",
68
68
  "@types/semver": "^7.5.8",
69
69
  "@vueuse/core": "^14.4.0",
@@ -0,0 +1,349 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ // Copyright (c) 2019-present Shigma and Koishijs contributors.
3
+ // Copyright (c) 2026-present Koishi-CE contributors.
4
+
5
+ import {
6
+ afterAll,
7
+ beforeAll,
8
+ describe,
9
+ expect,
10
+ it,
11
+ } from "bun:test";
12
+ import { mkdirSync, writeFileSync } from "node:fs";
13
+ import { join } from "node:path";
14
+ import type { Plugin } from "@koishi-ce/koishi";
15
+ import {
16
+ App,
17
+ app,
18
+ client,
19
+ FakeConsole,
20
+ type FakeLoader,
21
+ http,
22
+ itQuiet,
23
+ Logger,
24
+ market,
25
+ registryData,
26
+ registryServer,
27
+ setNextExitCode,
28
+ setSearchResponse,
29
+ spawnCalls,
30
+ startApp,
31
+ stopApp,
32
+ type TestApp,
33
+ tmp,
34
+ } from "./helpers.ts";
35
+
36
+ beforeAll(startApp);
37
+ afterAll(stopApp);
38
+
39
+ describe("market 聊天指令", () => {
40
+ itQuiet(
41
+ "plugin.install 缺参与未找到的报错路径",
42
+ async () => {
43
+ const missing = await client.receive(
44
+ "plugin.install",
45
+ );
46
+ expect(missing[0]).toContain("请输入插件名。");
47
+ const notFound = await client.receive(
48
+ "plugin.install absent-pkg",
49
+ );
50
+ expect(notFound[0]).toContain("未找到该插件。");
51
+ },
52
+ );
53
+
54
+ it("plugin.install 已安装时提示重复", async () => {
55
+ const replies = await client.receive(
56
+ "plugin.install demo",
57
+ );
58
+ expect(replies[0]).toContain("该插件已安装。");
59
+ });
60
+
61
+ itQuiet(
62
+ "plugin.install 安装新插件并写入依赖",
63
+ async () => {
64
+ setNextExitCode(0);
65
+ spawnCalls.length = 0;
66
+ const replies = await client.receive(
67
+ "plugin.install newpkg",
68
+ );
69
+ expect(replies[0]).toContain("安装成功!");
70
+ expect(spawnCalls.length).toBe(1);
71
+ const manifest = JSON.parse(
72
+ await Bun.file(join(tmp, "package.json")).text(),
73
+ ) as { dependencies: Record<string, string> };
74
+ expect(
75
+ manifest.dependencies["koishi-plugin-newpkg"],
76
+ ).toBe("1.0.0");
77
+ // 重启消息在安装完成后复位(Loader 与桩形状不同,经 unknown 二段式断言)
78
+ expect(
79
+ (app.loader as unknown as FakeLoader).envData[
80
+ "message"
81
+ ],
82
+ ).toBeNull();
83
+ },
84
+ 15000,
85
+ );
86
+
87
+ itQuiet(
88
+ "plugin.uninstall 卸载依赖并从清单移除",
89
+ async () => {
90
+ setNextExitCode(0);
91
+ spawnCalls.length = 0;
92
+ const replies = await client.receive(
93
+ "plugin.uninstall newpkg",
94
+ );
95
+ expect(replies[0]).toContain("卸载成功!");
96
+ const manifest = JSON.parse(
97
+ await Bun.file(join(tmp, "package.json")).text(),
98
+ ) as { dependencies: Record<string, string> };
99
+ expect(
100
+ manifest.dependencies["koishi-plugin-newpkg"],
101
+ ).toBeUndefined();
102
+ },
103
+ 15000,
104
+ );
105
+
106
+ it("plugin.uninstall 未安装时提示", async () => {
107
+ const replies = await client.receive(
108
+ "plugin.uninstall absent-pkg",
109
+ );
110
+ expect(replies[0]).toContain("该插件未安装。");
111
+ });
112
+
113
+ it("plugin.upgrade 无可升级项时提示已最新", async () => {
114
+ const replies = await client.receive("plugin.upgrade");
115
+ expect(replies[0]).toContain("所有插件已是最新版本。");
116
+ }, 10000);
117
+ });
118
+
119
+ describe("market 进阶链路", () => {
120
+ itQuiet("宿主配置不可写时不加载安装器", async () => {
121
+ // apply 的「仅告警并跳过」正是被测行为,静默 app 域避免预期告警刷屏
122
+ const levels = Logger.levels as Record<string, number>;
123
+ levels["app"] = 0;
124
+ try {
125
+ const appNoLoader = new App();
126
+ appNoLoader.plugin(http);
127
+ appNoLoader.plugin(
128
+ FakeConsole as unknown as Plugin.Constructor<TestApp>,
129
+ );
130
+ appNoLoader.plugin(market, {
131
+ registry: {
132
+ endpoint: `http://127.0.0.1:${registryServer.port}/`,
133
+ },
134
+ });
135
+ await appNoLoader.start();
136
+ // apply 在 loader 缺席时仅告警并提前返回
137
+ expect(appNoLoader.installer).toBeUndefined();
138
+ await appNoLoader.stop();
139
+ } finally {
140
+ delete levels["app"];
141
+ }
142
+ });
143
+
144
+ itQuiet(
145
+ "浏览器 market/install 监听器执行安装并刷新服务",
146
+ async () => {
147
+ setNextExitCode(0);
148
+ const listener =
149
+ app.console.listeners["market/install"];
150
+ expect(listener).toBeDefined();
151
+ const code = (await listener?.callback.call(
152
+ {} as never,
153
+ { "koishi-plugin-newpkg": "1.0.0" },
154
+ true,
155
+ )) as number;
156
+ expect(code).toBe(0);
157
+ },
158
+ 15000,
159
+ );
160
+
161
+ itQuiet(
162
+ "浏览器 market/registry 监听器批量查询包元数据",
163
+ async () => {
164
+ const listener =
165
+ app.console.listeners["market/registry"];
166
+ expect(listener).toBeDefined();
167
+ const meta = (await listener?.callback.call(
168
+ {} as never,
169
+ ["koishi-plugin-demo", "koishi-plugin-missing"],
170
+ )) as Record<string, unknown>;
171
+ expect(
172
+ Object.keys(meta["koishi-plugin-demo"] ?? {}),
173
+ ).toContain("2.0.0");
174
+ expect(meta["koishi-plugin-missing"]).toEqual({});
175
+ },
176
+ );
177
+
178
+ it("搜索结果中不兼容的包被跳过(analyze onSkipped/ignored)", async () => {
179
+ const svc = app.get("console.services.market");
180
+ // ghost 有 registry 条目,但版本声明的 koishi peer 与 4.x 不相交
181
+ registryData["koishi-plugin-ghost"] = {
182
+ versions: {
183
+ "1.0.0": {
184
+ version: "1.0.0",
185
+ peerDependencies: { koishi: "^5.0.0" },
186
+ },
187
+ },
188
+ time: { "1.0.0": "2024-01-01T00:00:00Z" },
189
+ };
190
+ setSearchResponse({
191
+ objects: [
192
+ {
193
+ package: {
194
+ name: "koishi-plugin-ghost",
195
+ version: "1.0.0",
196
+ date: "2024-01-01T00:00:00Z",
197
+ },
198
+ },
199
+ ],
200
+ total: 1,
201
+ });
202
+ await svc?.start(true);
203
+ // collect 对 analyze 为即发即忘,等待逐包分析完成
204
+ await new Promise((resolve) =>
205
+ setTimeout(resolve, 300),
206
+ );
207
+ const payload = await svc?.get();
208
+ // 无兼容版本:对象标记 ignored,不进入数据缓存。
209
+ // progress 恒为 0:Scanner 以 defineProperty 定义 progress(不可写),
210
+ // analyze 收尾的自增在严格模式下抛错且被即发即忘吞掉(上游行为)。
211
+ expect(payload?.data).toEqual({});
212
+ expect(payload?.failed).toBe(0);
213
+ expect(payload?.total).toBe(1);
214
+ expect(payload?.progress).toBe(0);
215
+ delete registryData["koishi-plugin-ghost"];
216
+ });
217
+
218
+ itQuiet(
219
+ "搜索结果中被限流的包经重试后计入 failed(onFailure)",
220
+ async () => {
221
+ const svc = app.get("console.services.market");
222
+ setSearchResponse({
223
+ objects: [
224
+ {
225
+ package: {
226
+ name: "koishi-plugin-ratelimited",
227
+ version: "1.0.0",
228
+ date: "2024-01-01T00:00:00Z",
229
+ },
230
+ },
231
+ ],
232
+ total: 1,
233
+ });
234
+ await svc?.start(true);
235
+ // 等待限流重试(Retry-After 10ms × 3 次)与即发即忘的 analyze。
236
+ // 注意不能经 get() 断言:super.start() 会清空 _task,get() 触发的
237
+ // 二次 collect 会把 failed 重置(即发即忘的 analyze 尚未完成)。
238
+ await new Promise((resolve) =>
239
+ setTimeout(resolve, 400),
240
+ );
241
+ // 不可达/被限流的包名进入 failed 列表(上一个用例中 registry
242
+ // 条目已删除的 ghost 包经 404 路径同样落入此处)
243
+ const provider = svc as unknown as {
244
+ failed: string[];
245
+ };
246
+ expect(
247
+ provider.failed.some((name) =>
248
+ name.startsWith("koishi-plugin-"),
249
+ ),
250
+ ).toBe(true);
251
+ },
252
+ );
253
+
254
+ itQuiet(
255
+ "plugin.upgrade 检出可升级项并输出确认提示",
256
+ async () => {
257
+ // 本地放置旧版安装,使 resolved 有值且低于远端 latest
258
+ mkdirSync(
259
+ join(tmp, "node_modules", "koishi-plugin-demo"),
260
+ {
261
+ recursive: true,
262
+ },
263
+ );
264
+ writeFileSync(
265
+ join(
266
+ tmp,
267
+ "node_modules",
268
+ "koishi-plugin-demo",
269
+ "package.json",
270
+ ),
271
+ JSON.stringify({
272
+ name: "koishi-plugin-demo",
273
+ version: "1.0.0",
274
+ }),
275
+ );
276
+ app.installer.refresh();
277
+
278
+ setNextExitCode(0);
279
+ // 发出升级指令(异步等待确认),再以 Y 回复确认。
280
+ // 注:mock 环境下指令 ctx 对 loader 服务的可见性受 cordis
281
+ // isolate 语义限制(见仓库测试任务记录),确认后的安装段
282
+ // 由 market/install 监听器用例覆盖。
283
+ const question = client.receive(
284
+ "plugin.upgrade demo",
285
+ );
286
+ await new Promise((resolve) =>
287
+ setTimeout(resolve, 200),
288
+ );
289
+ await client.receive("Y");
290
+ const replies = await question;
291
+ const output = replies.join("\n");
292
+ expect(output).toContain("koishi-plugin-demo");
293
+ expect(output).toContain("1.0.0 -> 2.0.0");
294
+ },
295
+ 20000,
296
+ );
297
+
298
+ itQuiet(
299
+ "plugin.upgrade 对本地畸形版本静默跳过(非法 semver catch)",
300
+ async () => {
301
+ // registry 侧提供合法 latest;本地安装产物的 version 是畸形串,
302
+ // request(清单声明)合法故不标记 invalid,gt(latest, resolved)
303
+ // 解析失败进入 catch 分支:该包被过滤,视为无可升级项
304
+ registryData["koishi-plugin-weird"] = {
305
+ versions: {
306
+ "2.0.0": {
307
+ version: "2.0.0",
308
+ peerDependencies: { koishi: "^4.17.0" },
309
+ },
310
+ },
311
+ };
312
+ mkdirSync(
313
+ join(tmp, "node_modules", "koishi-plugin-weird"),
314
+ {
315
+ recursive: true,
316
+ },
317
+ );
318
+ writeFileSync(
319
+ join(
320
+ tmp,
321
+ "node_modules",
322
+ "koishi-plugin-weird",
323
+ "package.json",
324
+ ),
325
+ JSON.stringify({
326
+ name: "koishi-plugin-weird",
327
+ version: "not.a.version",
328
+ }),
329
+ );
330
+ setNextExitCode(0);
331
+ // 经 install 注入清单声明(顺带刷新 Installer 的 manifest 快照)
332
+ const code = await app.installer.install({
333
+ "koishi-plugin-weird": "1.0.0",
334
+ });
335
+ expect(code).toBe(0);
336
+ const deps = await app.installer.getDeps();
337
+ expect(deps["koishi-plugin-weird"]?.resolved).toBe(
338
+ "not.a.version",
339
+ );
340
+ const replies = await client.receive(
341
+ "plugin.upgrade weird",
342
+ );
343
+ expect(replies[0]).toContain(
344
+ "所有插件已是最新版本。",
345
+ );
346
+ },
347
+ 20000,
348
+ );
349
+ });