@koishi-ce/plugin-market 1.1.0 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +3 -4
- package/dist/style.css +1 -1
- package/lib/index.d.ts +9 -19
- package/lib/index.mjs +165 -119
- package/package.json +9 -7
- package/src/index.test.ts +3 -3
- package/src/node/deps.ts +1 -1
- package/src/node/index.ts +3 -3
- package/src/node/installer/exec.ts +53 -0
- package/src/node/installer/index.ts +337 -0
- package/src/node/installer/integrity.ts +104 -0
- package/src/node/installer/manifest.ts +108 -0
- package/src/node/installer/registry-config.ts +16 -0
- package/src/node/installer/versions.ts +73 -0
- package/src/node/installer.ts +0 -586
- package/src/node/locales/message.de-DE.yml +0 -29
- package/src/node/locales/message.en-US.yml +0 -29
- package/src/node/locales/message.fr-FR.yml +0 -29
- package/src/node/locales/message.ja-JP.yml +0 -29
- package/src/node/locales/message.ru-RU.yml +0 -29
- package/src/node/locales/message.zh-CN.yml +0 -32
- package/src/node/locales/message.zh-TW.yml +0 -29
- package/src/node/locales/schema.de-DE.yml +0 -13
- package/src/node/locales/schema.en-US.yml +0 -13
- package/src/node/locales/schema.fr-FR.yml +0 -13
- package/src/node/locales/schema.ja-JP.yml +0 -13
- package/src/node/locales/schema.ru-RU.yml +0 -13
- package/src/node/locales/schema.zh-CN.yml +0 -14
- package/src/node/locales/schema.zh-TW.yml +0 -13
- /package/src/node/{proc.ts → installer/proc.ts} +0 -0
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}.k-schema-item p{margin:.25rem;font-size:.875rem;line-height:1.7}.k-schema-item .markdown p{margin:0}.k-schema-item ul{width:100%;padding-left:1rem;font-size:.875rem;list-style:none}.k-schema-item ul .el-radio,.k-schema-item ul .el-checkbox{height:1.375rem}.k-schema-item .el-button+.el-button{margin-left:0}.k-schema-item .k-schema-main{grid-template-columns:1fr auto 2rem;justify-content:space-between;align-items:center;gap:.25rem 1rem;min-height:3rem;display:grid}.k-schema-item h3{-webkit-user-select:none;user-select:none;align-items:center;margin:0;font-size:1rem;line-height:1.7;display:flex;position:relative}.k-schema-item h3>*{flex:none}.k-schema-item h3 .prefix{text-overflow:ellipsis;flex:0 auto;font-weight:400;overflow:hidden}.k-schema-item .k-schema-right{flex:1;justify-content:flex-end;gap:1rem;display:flex}.k-schema-item .el-button.ellipsis{padding:8px 9px}.k-schema-item .el-button.ellipsis .k-icon{width:12px}.k-schema-item .bottom{margin:.5rem 0 .25rem}.k-schema-item .actions{width:.5rem;height:100%;transition:var(--color-transition);border-left:2px solid #0000;position:absolute;top:0;left:0}.k-schema-item.changed .actions{border-left-color:var(--el-color-primary)}.k-schema-item.required .actions{border-left-color:var(--el-color-error)}.k-schema-item.invalid .actions{border-left-color:var(--el-color-warning)}.k-schema-item .el-input .suffix-icon{justify-content:center;align-items:center;width:1rem;margin-left:6px;display:flex}.k-schema-item .el-input .k-icon{color:var(--k-text-light);transition:var(--color-transition);cursor:pointer;height:.75rem}.k-schema-item .el-input .k-icon:hover{color:var(--k-text-dark)}.k-schema-item .el-input .k-icon.invalid{cursor:auto;color:var(--k-color-danger)}.k-schema-item .el-input.nullable:not(:focus-within) .el-input__prefix{border-top:var(--el-border);width:40%;transition:var(--color-transition);display:block;position:absolute;top:50%}.k-schema-item .el-input .el-input__wrapper{padding-right:9px}.k-schema-item .el-input:not(.minimal).invalid .el-input__wrapper:hover,.k-schema-item .el-input:not(.minimal).invalid .el-input__wrapper.is-focus{box-shadow:0 0 0 1px var(--k-color-danger) inset}.k-schema-item .el-input-number .el-input__wrapper{padding-right:42px}.k-schema-item .el-switch.nullable .el-switch__core{border:1px solid var(--el-border-color);background-color:#0000}.k-schema-item .el-switch.nullable .el-switch__action{background-color:var(--el-border-color);border-radius:0;width:16px;height:1px;left:11px}.k-schema-item .el-switch.nullable:hover .el-switch__core{border-color:var(--el-color-primary)}.entry-input[data-v-e26e0849]{position:relative}.entry-input .shadow[data-v-e26e0849]{visibility:hidden;white-space:pre}.entry-input .placeholder[data-v-e26e0849]{min-width:2rem;display:inline-block}.entry-input input[data-v-e26e0849]{font-size:1em;font-weight:inherit;border:none;border-radius:0;outline:none;margin:0;padding:0 .5em;font-family:inherit;position:absolute;left:-.5em;right:-.5em}.k-schema-table-container{position:relative}.k-schema-table-container .cell-outline{box-sizing:border-box;border:1px solid var(--k-color-active);pointer-events:none;position:absolute}.k-schema-table-container .cell-outline.invalid{border-color:var(--k-color-danger)}.k-schema-table td,.k-schema-table th{border:1px solid var(--el-border-color)}.k-schema-table th{padding:.5rem .75rem;line-height:1.25rem}.k-schema-table td{transition:var(--color-transition);padding:0}.k-schema-table td:hover{background-color:var(--k-button-hover-bg)}.k-schema-table td.k-schema-table-button{width:2rem;max-width:2rem;color:var(--k-text-light);cursor:pointer}.k-schema-table td.k-schema-table-button:hover{color:var(--k-color-active)}.k-schema-table td.k-schema-table-button .inner{box-sizing:border-box;justify-content:center;align-items:center;height:2rem;display:flex}.k-schema-table td.k-schema-table-button .k-icon{height:1rem}.k-schema-table td.k-schema-table-button.disabled{color:var(--k-color-disabled);pointer-events:none}.k-badge{color:#fff;white-space:nowrap;vertical-align:baseline;border-radius:4px;height:1.25rem;margin-left:.5rem;padding:0 6px;font-size:14px;font-weight:500;line-height:1.25rem;display:inline-block}.k-badge.primary{background-color:var(--k-color-primary)}.k-badge.warning{background-color:var(--k-color-warning)}.k-badge.success{background-color:var(--k-color-success)}.k-badge.danger{background-color:var(--k-color-danger)}.k-form:not(:first-child){margin-top:2rem}@media screen and (width<=480px){.k-form{margin:0 -1.5rem}.k-form .k-schema-header{padding:0 1.5rem}.k-form .k-schema-item{padding:.5rem 1.5rem}.k-form .k-schema-item .k-schema-main{min-height:unset;grid-template-rows:auto auto;grid-template-columns:auto 2rem}.k-form .k-schema-item .k-schema-right{grid-area:2/1/auto/2;display:block}.k-form .k-schema-item .k-schema-right>:first-child{margin-top:.25rem}.k-form .k-schema-item .k-schema-right>:last-child{margin-bottom:.25rem}}.k-menu,.k-menu.el-popper.is-light{z-index:1000;background-color:var(--el-bg-color-overlay);min-width:12rem;box-shadow:var(--k-menu-shadow);border-radius:6px;padding:.375rem 0;font-size:14px;position:fixed}.k-menu-separator{border-top:1px solid var(--el-border-color-light);margin:.375rem 0}.k-menu-separator:first-child,.k-menu-separator:last-child,.k-menu-separator+.k-menu-separator{display:none}.k-menu-item{-webkit-user-select:none;user-select:none;cursor:pointer;transition:var(--color-transition);border-radius:4px;margin:0 .375rem;padding:.375rem 0 .375rem 2.5rem;position:relative}.k-menu-item.disabled{color:var(--k-color-disabled);pointer-events:none}.k-menu-item:not(.disabled):hover{background-color:var(--k-hover-bg);color:inherit!important}.k-menu-item:not(.disabled).primary{color:var(--el-color-primary)}.k-menu-item:not(.disabled).primary:hover{background-color:var(--el-color-primary)}.k-menu-item:not(.disabled).danger{color:var(--el-color-error)}.k-menu-item:not(.disabled).danger:hover{background-color:var(--el-color-error)}.k-menu-item:not(.disabled).warning{color:var(--el-color-warning)}.k-menu-item:not(.disabled).warning:hover{background-color:var(--el-color-warning)}.k-menu-icon{justify-content:center;align-items:center;width:2.5rem;height:100%;display:flex;position:absolute;top:0;left:0}.k-menu-icon .k-icon{height:1rem}.k-schema-item{border-bottom:1px solid var(--el-border-color-light);transition:var(--color-transition);padding:.5rem 1rem;position:relative}.k-schema-item:first-child,:not(.k-schema-item):not(.k-schema-group)+.k-schema-item{border-top:1px solid var(--el-border-color-light)}.k-schema-item+h2{margin-top:2rem}.k-schema-item:hover{background-color:var(--el-fill-color)}.k-schema-item .k-schema-right .el-select{width:12rem}.k-schema-header{margin:1rem 0;font-size:1.25rem}.k-schema-header:not(:first-child){margin-top:2rem}.k-schema-group{position:relative}.k-schema-group:empty{border-bottom:none}.k-schema-group>:first-child{border-top:none}.k-schema-table .el-input,.k-schema-table .el-input-number{width:100%}.k-schema-table-cell-input,.k-schema-table-cell-input-number,.k-schema-table-cell-select{min-width:6rem}.k-schema-table .el-input__wrapper,.k-schema-table .el-select__wrapper{box-shadow:none!important}.el-input.invalid .el-input__wrapper,.el-textarea.invalid .el-textarea__inner{box-shadow:0 0 0 1px var(--el-color-danger) inset}.k-schema-edit-dialog .el-dialog__footer{justify-content:space-between;display:flex}.k-filter-expr{flex:1 0 auto;display:inline-flex}.k-filter-expr .entity,.k-filter-expr .operator{flex:none;width:7.5rem}.k-filter-expr .value{flex:1 0 auto;width:auto}.k-filter-item{display:flex}.overlay-enter-from,.overlay-leave-to{opacity:0}.overlay-enter,.overlay-leave{opacity:1}.image-viewer{position:absolute;inset:0}.image-viewer .button{cursor:pointer;-webkit-user-select:none;user-select:none;opacity:.5;background-color:#303133;border-radius:3rem;justify-content:space-evenly;align-items:center;height:3rem;font-size:1.5rem;transition:all .4s;display:flex;position:absolute}.image-viewer .button .k-icon{height:1.25rem;transition:all .4s}.image-viewer .button:not(.disabled):hover{opacity:.8}.image-viewer .button:not(.disabled) .k-icon:hover{color:#f4f4f5cc}.image-viewer .button.left{z-index:2000;width:3rem;top:50%;left:3rem;transform:translateY(-50%)}.image-viewer .button.left .k-icon{margin-left:-3px}.image-viewer .button.right{z-index:2000;width:3rem;top:50%;right:3rem;transform:translateY(-50%)}.image-viewer .button.right .k-icon{margin-right:-3px}.image-viewer .button.bottom{z-index:2000;width:18rem;bottom:3rem;left:50%;transform:translate(-50%)}.image-viewer .button.disabled{cursor:not-allowed}.image-viewer img{transition:all .3s;position:absolute}.k-link{cursor:pointer;text-decoration:underline}.k-link:hover{text-decoration:underline}.market-filter-item[data-v-542fc917]{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-542fc917]:hover{color:var(--k-text-dark);background-color:var(--k-hover-bg)}.market-filter-item.active[data-v-542fc917]{color:var(--k-color-primary);background-color:color-mix(in srgb, var(--k-color-primary) 10%, transparent)}.market-filter-item.active .text[data-v-542fc917]{font-weight:600}.market-filter-item.active.verified[data-v-542fc917],.market-filter-item.active.newborn[data-v-542fc917]{color:var(--k-color-success);background-color:color-mix(in srgb, var(--k-color-success) 10%, transparent)}.market-filter-item.active.preview[data-v-542fc917],.market-filter-item.active.portable[data-v-542fc917]{color:var(--k-color-warning);background-color:color-mix(in srgb, var(--k-color-warning) 10%, transparent)}.market-filter-item.active.insecure[data-v-542fc917]{color:var(--k-color-danger);background-color:color-mix(in srgb, var(--k-color-danger) 10%, transparent)}.market-filter-item.disabled[data-v-542fc917]{opacity:.5;text-decoration:line-through;text-decoration-thickness:2px}.market-filter-item .icon[data-v-542fc917]{justify-content:center;align-items:center;width:1.75rem;margin-right:4px;display:inline-flex}.market-filter-item:not(.active) .order[data-v-542fc917]{display:none}.market-filter-item .order[data-v-542fc917]{justify-content:center;align-items:center;width:1.75rem;display:inline-flex}.market-filter-item svg[data-v-542fc917]{max-width:1.125rem;height:1rem}.market-filter-item .text[data-v-542fc917],.market-filter-item .count[data-v-542fc917]{font-size:14px;font-weight:500;line-height:20px}.market-filter-item .count[data-v-542fc917]{opacity:.7;margin-right:4px;font-size:12px}.market-filter-item .spacer[data-v-542fc917]{flex:1}.cat-adapter[data-v-0e838db4]{--c:#38bdf8}.cat-general[data-v-0e838db4]{--c:#4ade80}.cat-extension[data-v-0e838db4]{--c:#a78bfa}.cat-webui[data-v-0e838db4]{--c:#fb923c}.cat-manage[data-v-0e838db4]{--c:#facc15}.cat-preset[data-v-0e838db4]{--c:#60a5fa}.cat-image[data-v-0e838db4]{--c:#f472b6}.cat-media[data-v-0e838db4]{--c:#e879f9}.cat-tool[data-v-0e838db4]{--c:#94a3b8}.cat-life[data-v-0e838db4]{--c:#34d399}.cat-ai[data-v-0e838db4]{--c:#818cf8}.cat-meme[data-v-0e838db4]{--c:#fbbf24}.cat-game[data-v-0e838db4]{--c:#f87171}.cat-gametool[data-v-0e838db4]{--c:#c084fc}.cat-other[data-v-0e838db4]{--c:#64748b}.market-package[data-v-0e838db4]{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-0e838db4]:hover{border-color:var(--k-color-primary);box-shadow:0 4px 12px #0000000f}.market-package .market-icon[data-v-0e838db4]{height:1em;display:inline}.market-package .header[data-v-0e838db4],.market-package .footer[data-v-0e838db4]{flex:none}.market-package .header[data-v-0e838db4]{position:relative}.market-package .header .left[data-v-0e838db4]{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-0e838db4]{height:1.75rem;color:var(--c)}.market-package .header h2[data-v-0e838db4]{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-0e838db4]{flex:0 auto;line-height:1.5rem;display:inline-block}.market-package .header .heartbeat[data-v-0e838db4]{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-0e838db4]{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-0e838db4]{position:absolute;bottom:2.5rem;right:1.25rem}.market-package .badge-pill[data-v-0e838db4]{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-0e838db4]{width:12px;height:12px}.market-package .badge-pill.preview[data-v-0e838db4]{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-0e838db4]{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-0e838db4]{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-0e838db4]{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-0e838db4]>*{flex:none}.market-package .footer .spacer[data-v-0e838db4]{flex:0 2 .5rem}.market-package .footer .long-spacer[data-v-0e838db4]{flex:auto}.market-package .footer .market-icon[data-v-0e838db4]{vertical-align:-1px;width:16px;height:12px;margin-right:6px}.market-package .footer .avatars[data-v-0e838db4]{gap:.25rem;display:flex}.market-package .footer .avatars .avatar[data-v-0e838db4]{cursor:pointer;border-radius:100%;width:1.5rem;height:1.5rem}.market-package .footer .avatars .avatar img[data-v-0e838db4]{vertical-align:middle;border-radius:100%;width:1.5rem;height:1.5rem}.market-package .footer .avatars .avatar.fallback[data-v-0e838db4]{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-0e838db4]:before{content:attr(data-initial)}@media (width<=420px){.market-package[data-v-0e838db4]{height:auto;min-height:11rem;padding:.82rem .9rem}.market-package .header .left[data-v-0e838db4]{width:3rem;height:3rem}.market-package h2[data-v-0e838db4]{font-size:1rem}.market-package .badge-float[data-v-0e838db4]{bottom:2.3rem;right:.9rem}.market-package .footer[data-v-0e838db4]{flex-wrap:wrap;height:auto}.market-package .footer .long-spacer[data-v-0e838db4]{display:none}}.package-list[data-v-e3691166]{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-e3691166]{margin:var(--card-margin) 0;justify-content:center}.k-empty[data-v-e3691166]{flex:1 0 auto}.search-box[data-v-ee66eeec]{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-ee66eeec]: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-ee66eeec]{flex-wrap:wrap;flex:auto;align-items:center;gap:8px 6px;padding:.75rem 0 .75rem 1.25rem;display:flex}.search-container input[data-v-ee66eeec]{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-ee66eeec]{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-ee66eeec]{opacity:.45;height:1rem;transition:opacity .2s}.search-action:hover .market-icon[data-v-ee66eeec]{opacity:.85}.search-action:hover .market-icon.search[data-v-ee66eeec],.search-action:not(:hover) .market-icon.close[data-v-ee66eeec]{display:none}.search-word[data-v-ee66eeec]{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-ee66eeec]{opacity:.5;text-decoration:line-through}.search-word.invalid[data-v-ee66eeec]:hover{opacity:1}@media (width<=420px){.search-box[data-v-ee66eeec]{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}.block{display:block}.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}.px{padding-left:1rem;padding-right:1rem}.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-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}}
|
|
2
2
|
/*$vite$:1*/
|
package/lib/index.d.ts
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { Awaitable, Context, Dict, HTTP, Schema, Service } from "@koishi-ce/koishi";
|
|
2
2
|
import { DataService } from "@koishi-ce/console";
|
|
3
3
|
import { DependencyMetaKey, RemotePackage, SearchObject, SearchResult } from "@koishi-ce/registry";
|
|
4
|
-
//#region src/node/installer.d.ts
|
|
4
|
+
//#region src/node/installer/versions.d.ts
|
|
5
|
+
/** 归一化后的版本表:版本号 → 依赖元信息(键序即降序,首项为最新版) */
|
|
6
|
+
type VersionMap = Dict<Pick<RemotePackage, DependencyMetaKey>>;
|
|
7
|
+
//#endregion
|
|
8
|
+
//#region src/node/installer/index.d.ts
|
|
5
9
|
interface Dependency {
|
|
6
10
|
/**
|
|
7
11
|
* requested semver range
|
|
@@ -23,8 +27,8 @@ interface Dependency {
|
|
|
23
27
|
declare class Installer extends Service {
|
|
24
28
|
http: HTTP;
|
|
25
29
|
endpoint: string | undefined;
|
|
26
|
-
fullCache: Dict<
|
|
27
|
-
tempCache: Dict<
|
|
30
|
+
fullCache: Dict<VersionMap>;
|
|
31
|
+
tempCache: Dict<VersionMap>;
|
|
28
32
|
private pkgTasks;
|
|
29
33
|
private manifest;
|
|
30
34
|
private depTask;
|
|
@@ -37,7 +41,7 @@ declare class Installer extends Service {
|
|
|
37
41
|
findVersion(names: string[]): Promise<Dict<string> | undefined>;
|
|
38
42
|
private _getPackage;
|
|
39
43
|
setPackage(name: string, versions: RemotePackage[]): void;
|
|
40
|
-
getPackage(name: string): Promise<
|
|
44
|
+
getPackage(name: string): Promise<VersionMap>;
|
|
41
45
|
private _getDeps;
|
|
42
46
|
getDeps(): Promise<Dict<Dependency>>;
|
|
43
47
|
refreshData(): void;
|
|
@@ -45,20 +49,6 @@ declare class Installer extends Service {
|
|
|
45
49
|
exec(args: string[]): Promise<number>;
|
|
46
50
|
override(deps: Dict<string | null>): Promise<void>;
|
|
47
51
|
private _install;
|
|
48
|
-
/**
|
|
49
|
-
* 安装完整性校验:从本次安装的包出发递归纯 fs 探测依赖可达性,返回
|
|
50
|
-
* 「包: 缺失依赖」描述列表。背景是 Bun isolated 布局的增量安装缺陷
|
|
51
|
-
* (2026-09-07 实证):升级插件时包目录 hash 变化,而其依赖的解析
|
|
52
|
-
* 结果未变,bun 的增量安装跳过新包目录内的依赖链接建立——插件入口
|
|
53
|
-
* (顶层 symlink)可加载,内部依赖的 require 却炸 MODULE_NOT_FOUND;
|
|
54
|
-
* 此时补跑一次普通 bun install,bun 按磁盘实际状态检测到包不完整
|
|
55
|
-
* 即重建链接(秒级)。全程只走 existsSync / readFileSync /
|
|
56
|
-
* realpathSync,不触碰解析 API(防父目录快照缓存,与
|
|
57
|
-
* resolvePackageJson 同一纪律)。peer / optional 依赖由宿主或按需
|
|
58
|
-
* 提供不入校验;workspace / alias 等非 semver 声明的落盘名与键名无
|
|
59
|
-
* 直接映射,同样跳过。
|
|
60
|
-
*/
|
|
61
|
-
private _findMissingDeps;
|
|
62
52
|
private _getLocalDeps;
|
|
63
53
|
install(deps: Dict<string | null>, forced?: boolean): Promise<number>;
|
|
64
54
|
static Config: Schema<Installer.Config>;
|
|
@@ -77,7 +67,7 @@ declare class DependencyProvider extends DataService<Dict<Dependency>> {
|
|
|
77
67
|
}
|
|
78
68
|
declare class RegistryProvider extends DataService<Dict<Dict<Pick<RemotePackage, DependencyMetaKey>>>> {
|
|
79
69
|
constructor(ctx: Context);
|
|
80
|
-
get(): Promise<Dict<
|
|
70
|
+
get(): Promise<Dict<VersionMap>>;
|
|
81
71
|
}
|
|
82
72
|
//#endregion
|
|
83
73
|
//#region src/shared/index.d.ts
|
package/lib/index.mjs
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { dirname, join, resolve } from "node:path";
|
|
2
2
|
import { Logger, Schema, Service, Time, defineProperty, pick, sleep, valueMap } from "@koishi-ce/koishi";
|
|
3
3
|
import { compare, gt, satisfies, valid } from "semver";
|
|
4
|
+
import messageZhCN from "./assets/message.zh-CN-D1DbsO3I.yml";
|
|
5
|
+
import schemaZhCN from "./assets/schema.zh-CN-Bj0_jaVr.yml";
|
|
4
6
|
import { DataService } from "@koishi-ce/console";
|
|
5
|
-
import { existsSync, readFileSync, realpathSync } from "node:fs";
|
|
6
|
-
import { homedir } from "node:os";
|
|
7
7
|
import Scanner, { isResidentInCache, mapLimit, resolvePackageJson } from "@koishi-ce/registry";
|
|
8
8
|
import { spawn } from "node:child_process";
|
|
9
|
-
import
|
|
10
|
-
import
|
|
9
|
+
import { existsSync, readFileSync, realpathSync } from "node:fs";
|
|
10
|
+
import { NPM_OFFICIAL_REGISTRY, getLocalRegistry } from "@koishi-ce/utils";
|
|
11
11
|
//#region src/node/deps.ts
|
|
12
12
|
var DependencyProvider = class extends DataService {
|
|
13
13
|
constructor(ctx) {
|
|
@@ -26,7 +26,7 @@ var RegistryProvider = class extends DataService {
|
|
|
26
26
|
}
|
|
27
27
|
};
|
|
28
28
|
//#endregion
|
|
29
|
-
//#region src/node/proc.ts
|
|
29
|
+
//#region src/node/installer/proc.ts
|
|
30
30
|
/**
|
|
31
31
|
* 安装子进程的创建封装(原依赖 execa)。
|
|
32
32
|
*
|
|
@@ -47,21 +47,57 @@ function spawnBun(args, cwd) {
|
|
|
47
47
|
return spawn(process.execPath, args, { cwd });
|
|
48
48
|
}
|
|
49
49
|
//#endregion
|
|
50
|
-
//#region src/node/installer.ts
|
|
51
|
-
const logger$2 = new Logger("market");
|
|
50
|
+
//#region src/node/installer/exec.ts
|
|
52
51
|
/**
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
* -
|
|
57
|
-
*
|
|
58
|
-
* packages/shim/koishi-shim)。
|
|
59
|
-
* 两者被覆盖或删除都会让 peer 解析失去归属,重新拉下 npm 官方包形成
|
|
60
|
-
* 第二份框架副本。
|
|
52
|
+
* bun 安装子进程的驱动与输出转发。
|
|
53
|
+
*
|
|
54
|
+
* Bun-first:CE 生态只存在 bun 这一种包管理器,直接驱动 bun 执行安装
|
|
55
|
+
* (上游经 which-pm-runs 探测 npm/yarn/bun,此处固定为 bun)。子进程本身的
|
|
56
|
+
* 创建见 ./proc.ts;本模块负责退出码归一化与日志转发,不持有任何服务状态。
|
|
61
57
|
*/
|
|
62
|
-
|
|
63
|
-
|
|
58
|
+
const logger$3 = new Logger("market");
|
|
59
|
+
/**
|
|
60
|
+
* 在 cwd 下执行 `bun <args>`,返回退出码(spawn 失败与异常退出统一为非 0,
|
|
61
|
+
* 由调用方按失败处理)。
|
|
62
|
+
*
|
|
63
|
+
* 输出按行转发到 market 日志:未成行的尾段暂存到下一次数据到来时补齐,
|
|
64
|
+
* 避免半行日志刷屏。
|
|
65
|
+
*/
|
|
66
|
+
function runBun(args, cwd) {
|
|
67
|
+
return new Promise((resolve) => {
|
|
68
|
+
const child = spawnBun(args, cwd);
|
|
69
|
+
child.on("exit", (code) => resolve(code ?? -1));
|
|
70
|
+
child.on("error", () => resolve(-1));
|
|
71
|
+
let stderr = "";
|
|
72
|
+
child.stderr?.on("data", (data) => {
|
|
73
|
+
stderr += data.toString();
|
|
74
|
+
const lines = stderr.split("\n");
|
|
75
|
+
stderr = lines.pop() ?? "";
|
|
76
|
+
for (const line of lines) logger$3.warn(line);
|
|
77
|
+
});
|
|
78
|
+
let stdout = "";
|
|
79
|
+
child.stdout?.on("data", (data) => {
|
|
80
|
+
stdout += data.toString();
|
|
81
|
+
const lines = stdout.split("\n");
|
|
82
|
+
stdout = lines.pop() ?? "";
|
|
83
|
+
for (const line of lines) logger$3.info(line);
|
|
84
|
+
});
|
|
85
|
+
});
|
|
64
86
|
}
|
|
87
|
+
//#endregion
|
|
88
|
+
//#region src/node/installer/integrity.ts
|
|
89
|
+
/**
|
|
90
|
+
* 安装完整性校验:Bun isolated 布局的增量安装缺陷防御。
|
|
91
|
+
*
|
|
92
|
+
* 背景(2026-09-07 实证):升级插件时包目录 hash 变化,而其依赖的解析
|
|
93
|
+
* 结果未变,bun 的增量安装跳过新包目录内的依赖链接建立——插件入口(顶层
|
|
94
|
+
* symlink)可加载,内部依赖的 require 却炸 MODULE_NOT_FOUND;此时补跑一次
|
|
95
|
+
* 普通 bun install,bun 按磁盘实际状态检测到包不完整即重建链接(秒级)。
|
|
96
|
+
* 本模块只负责「发现问题」,补救(补装、告警)由 installer 侧完成。
|
|
97
|
+
*
|
|
98
|
+
* 全程只走 existsSync / readFileSync / realpathSync,不触碰解析 API
|
|
99
|
+
* (防父目录快照缓存,与 registry 的 resolvePackageJson 同一纪律)。
|
|
100
|
+
*/
|
|
65
101
|
/**
|
|
66
102
|
* 从 fromDir 沿 node_modules 链纯 fs 探测依赖包,命中返回其真实目录。
|
|
67
103
|
* realpath 化是 isolated 布局的关键:顶层条目是 symlink,包的依赖链接
|
|
@@ -82,32 +118,66 @@ function probePackage(fromDir, name) {
|
|
|
82
118
|
dir = parent;
|
|
83
119
|
}
|
|
84
120
|
}
|
|
85
|
-
/**
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
121
|
+
/**
|
|
122
|
+
* 从本次安装的包出发递归纯 fs 探测依赖可达性,返回「包: 缺失依赖」描述
|
|
123
|
+
* 列表。peer / optional 依赖由宿主或按需提供不入校验;workspace / alias
|
|
124
|
+
* 等非 semver 声明的落盘名与键名无直接映射,同样跳过。
|
|
125
|
+
*
|
|
126
|
+
* @param root 项目根目录
|
|
127
|
+
* @param deps 依赖增删清单(值为 null 表示卸载该依赖)
|
|
128
|
+
*/
|
|
129
|
+
function findMissingDeps(root, deps) {
|
|
130
|
+
const problems = [];
|
|
131
|
+
const visited = /* @__PURE__ */ new Set();
|
|
132
|
+
const walk = (dir, label) => {
|
|
133
|
+
if (visited.has(dir)) return;
|
|
134
|
+
visited.add(dir);
|
|
135
|
+
let manifest;
|
|
136
|
+
try {
|
|
137
|
+
manifest = JSON.parse(readFileSync(join(dir, "package.json"), "utf8"));
|
|
138
|
+
} catch {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
for (const [dep, request] of Object.entries(manifest.dependencies ?? {})) {
|
|
142
|
+
if (request.includes(":")) continue;
|
|
143
|
+
const depDir = probePackage(dir, dep);
|
|
144
|
+
if (!depDir) {
|
|
145
|
+
problems.push(`${label} 的依赖 ${dep} 未被链接`);
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
walk(depDir, `${label} → ${dep}`);
|
|
91
149
|
}
|
|
92
|
-
}
|
|
150
|
+
};
|
|
151
|
+
for (const name in deps) {
|
|
152
|
+
const request = deps[name];
|
|
153
|
+
if (!request || request.includes(":")) continue;
|
|
154
|
+
const dir = probePackage(root, name);
|
|
155
|
+
if (!dir) continue;
|
|
156
|
+
walk(dir, name);
|
|
157
|
+
}
|
|
158
|
+
return problems;
|
|
93
159
|
}
|
|
160
|
+
//#endregion
|
|
161
|
+
//#region src/node/installer/manifest.ts
|
|
94
162
|
/**
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
* 源(对齐被移除的 get-registry 的默认值),保证 http 恒有 endpoint
|
|
101
|
-
* 可拼接相对 URL——缺省时相对请求会在 resolveURL 抛 Invalid URL。
|
|
163
|
+
* 项目根 package.json(安装清单)的读写与护栏判定。
|
|
164
|
+
*
|
|
165
|
+
* 只做纯 fs 的清单操作,与 registry 的交互(版本探测、http 缓存)无关,
|
|
166
|
+
* 故独立于 installer 服务;依赖链接的探测属安装完整性校验,见
|
|
167
|
+
* ./integrity.ts。
|
|
102
168
|
*/
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
169
|
+
/**
|
|
170
|
+
* 判断依赖声明是否受护栏保护、不可被安装清单覆盖或删除。两类:
|
|
171
|
+
* - `workspace:` 声明是本仓库(monorepo)对上游名的归属(如 koishi
|
|
172
|
+
* 裸名 shim,见 packages/shim/koishi);
|
|
173
|
+
* - `npm:@koishi-ce/...` alias 是下游脚手架生成项目对上游名的归属
|
|
174
|
+
* (如 "koishi": "npm:@koishi-ce/koishi-shim@^4.18.11",见
|
|
175
|
+
* packages/shim/koishi-shim)。
|
|
176
|
+
* 两者被覆盖或删除都会让 peer 解析失去归属,重新拉下 npm 官方包形成
|
|
177
|
+
* 第二份框架副本。
|
|
178
|
+
*/
|
|
179
|
+
function isGuardedRequest(request) {
|
|
180
|
+
return request?.startsWith("workspace:") === true || request?.startsWith("npm:@koishi-ce") === true;
|
|
111
181
|
}
|
|
112
182
|
function loadManifest(name) {
|
|
113
183
|
const filename = resolvePackageJson(name);
|
|
@@ -116,6 +186,38 @@ function loadManifest(name) {
|
|
|
116
186
|
defineProperty(meta, "$workspace", !filename.includes("node_modules"));
|
|
117
187
|
return meta;
|
|
118
188
|
}
|
|
189
|
+
/**
|
|
190
|
+
* 把依赖增删写回项目根 package.json,返回写回后的清单。
|
|
191
|
+
*
|
|
192
|
+
* 现读现写:调用方持有的清单原为构造期的启动快照,运行期间根
|
|
193
|
+
* package.json 可能已被外部更新,基于快照整体重写会抹掉变更,故此处
|
|
194
|
+
* 重新读盘。受护栏保护的声明(见 isGuardedRequest)既不覆盖也不删除。
|
|
195
|
+
*
|
|
196
|
+
* @param cwd 项目根目录
|
|
197
|
+
* @param deps 依赖增删清单(值为 null 表示卸载该依赖)
|
|
198
|
+
*/
|
|
199
|
+
async function writeManifest(cwd, deps) {
|
|
200
|
+
const filename = resolve(cwd, "package.json");
|
|
201
|
+
const manifest = JSON.parse(readFileSync(filename, "utf8"));
|
|
202
|
+
manifest.dependencies ||= {};
|
|
203
|
+
for (const key in deps) if (deps[key]) {
|
|
204
|
+
if (isGuardedRequest(manifest.dependencies[key])) continue;
|
|
205
|
+
manifest.dependencies[key] = deps[key];
|
|
206
|
+
} else if (!isGuardedRequest(manifest.dependencies[key])) delete manifest.dependencies[key];
|
|
207
|
+
manifest.dependencies = Object.fromEntries(Object.entries(manifest.dependencies).sort((a, b) => a[0].localeCompare(b[0])));
|
|
208
|
+
await Bun.write(filename, `${JSON.stringify(manifest, null, " ")}\n`);
|
|
209
|
+
return manifest;
|
|
210
|
+
}
|
|
211
|
+
//#endregion
|
|
212
|
+
//#region src/node/installer/versions.ts
|
|
213
|
+
/**
|
|
214
|
+
* 远端包版本探测与归一化。
|
|
215
|
+
*
|
|
216
|
+
* 从 registry 取回版本数组后,过滤掉与当前框架不兼容的版本,再归一化为
|
|
217
|
+
* 「版本号 → peer 依赖声明 / 弃用标记」的映射并按版本号降序排列(首项即
|
|
218
|
+
* 最新版)。纯 IO + 纯函数,不持有服务状态;缓存与去重由 installer 侧负责。
|
|
219
|
+
*/
|
|
220
|
+
/** 把 registry 返回的版本数组归一化并降序排列 */
|
|
119
221
|
function getVersions(versions) {
|
|
120
222
|
return Object.fromEntries(versions.map((item) => [item.version, pick(item, [
|
|
121
223
|
"peerDependencies",
|
|
@@ -123,6 +225,24 @@ function getVersions(versions) {
|
|
|
123
225
|
"deprecated"
|
|
124
226
|
])]).sort(([a], [b]) => compare(b, a)));
|
|
125
227
|
}
|
|
228
|
+
/**
|
|
229
|
+
* 取回单个包的可用版本表(已过滤不兼容版本)。
|
|
230
|
+
*
|
|
231
|
+
* 兼容性口径:`koishi` 本体按 4.x 判定;其余包若确认为插件则要求与
|
|
232
|
+
* 4.x 兼容(Scanner 的判定基于包名与 remote 元信息)。
|
|
233
|
+
*
|
|
234
|
+
* @throws 网络或 registry 响应异常时向上抛出,由调用方决定日志口径
|
|
235
|
+
*/
|
|
236
|
+
async function fetchVersions(http, name) {
|
|
237
|
+
const registry = await http.get(`/${name}`);
|
|
238
|
+
return getVersions(Object.values(registry.versions).filter((remote) => {
|
|
239
|
+
if (name === "koishi") return satisfies(remote.version, "4");
|
|
240
|
+
return !Scanner.isPlugin(name) || Scanner.isCompatible("4", remote);
|
|
241
|
+
}));
|
|
242
|
+
}
|
|
243
|
+
//#endregion
|
|
244
|
+
//#region src/node/installer/index.ts
|
|
245
|
+
const logger$2 = new Logger("market");
|
|
126
246
|
var Installer = class extends Service {
|
|
127
247
|
fullCache = {};
|
|
128
248
|
tempCache = {};
|
|
@@ -144,7 +264,7 @@ var Installer = class extends Service {
|
|
|
144
264
|
}
|
|
145
265
|
async start() {
|
|
146
266
|
const { endpoint, timeout } = this.config;
|
|
147
|
-
this.endpoint = endpoint ?? getLocalRegistry(this.cwd);
|
|
267
|
+
this.endpoint = endpoint ?? getLocalRegistry(this.cwd) ?? NPM_OFFICIAL_REGISTRY;
|
|
148
268
|
const options = {};
|
|
149
269
|
if (this.endpoint) options.endpoint = this.endpoint;
|
|
150
270
|
if (timeout !== void 0) options.timeout = timeout;
|
|
@@ -171,11 +291,7 @@ var Installer = class extends Service {
|
|
|
171
291
|
}
|
|
172
292
|
async _getPackage(name) {
|
|
173
293
|
try {
|
|
174
|
-
const
|
|
175
|
-
const versions = getVersions(Object.values(registry.versions).filter((remote) => {
|
|
176
|
-
if (name === "koishi") return satisfies(remote.version, "4");
|
|
177
|
-
return !Scanner.isPlugin(name) || Scanner.isCompatible("4", remote);
|
|
178
|
-
}));
|
|
294
|
+
const versions = await fetchVersions(this.http, name);
|
|
179
295
|
this.fullCache[name] = this.tempCache[name] = versions;
|
|
180
296
|
this.flushData();
|
|
181
297
|
return versions;
|
|
@@ -228,86 +344,16 @@ var Installer = class extends Service {
|
|
|
228
344
|
}
|
|
229
345
|
async exec(args) {
|
|
230
346
|
args.unshift("install");
|
|
231
|
-
return
|
|
232
|
-
const child = spawnBun(args, this.cwd);
|
|
233
|
-
child.on("exit", (code) => resolve(code ?? -1));
|
|
234
|
-
child.on("error", () => resolve(-1));
|
|
235
|
-
let stderr = "";
|
|
236
|
-
child.stderr?.on("data", (data) => {
|
|
237
|
-
stderr += data.toString();
|
|
238
|
-
const lines = stderr.split("\n");
|
|
239
|
-
stderr = lines.pop() ?? "";
|
|
240
|
-
for (const line of lines) logger$2.warn(line);
|
|
241
|
-
});
|
|
242
|
-
let stdout = "";
|
|
243
|
-
child.stdout?.on("data", (data) => {
|
|
244
|
-
stdout += data.toString();
|
|
245
|
-
const lines = stdout.split("\n");
|
|
246
|
-
stdout = lines.pop() ?? "";
|
|
247
|
-
for (const line of lines) logger$2.info(line);
|
|
248
|
-
});
|
|
249
|
-
});
|
|
347
|
+
return runBun(args, this.cwd);
|
|
250
348
|
}
|
|
251
349
|
async override(deps) {
|
|
252
|
-
|
|
253
|
-
this.manifest = JSON.parse(readFileSync(filename, "utf8"));
|
|
254
|
-
this.manifest.dependencies ||= {};
|
|
255
|
-
for (const key in deps) if (deps[key]) {
|
|
256
|
-
if (isGuardedRequest(this.manifest.dependencies[key])) continue;
|
|
257
|
-
this.manifest.dependencies[key] = deps[key];
|
|
258
|
-
} else if (!isGuardedRequest(this.manifest.dependencies[key])) delete this.manifest.dependencies[key];
|
|
259
|
-
this.manifest.dependencies = Object.fromEntries(Object.entries(this.manifest.dependencies).sort((a, b) => a[0].localeCompare(b[0])));
|
|
260
|
-
await Bun.write(filename, `${JSON.stringify(this.manifest, null, " ")}\n`);
|
|
350
|
+
this.manifest = await writeManifest(this.cwd, deps);
|
|
261
351
|
}
|
|
262
352
|
_install() {
|
|
263
353
|
const args = [];
|
|
264
354
|
if (this.endpoint) args.push("--registry", this.endpoint);
|
|
265
355
|
return this.exec(args);
|
|
266
356
|
}
|
|
267
|
-
/**
|
|
268
|
-
* 安装完整性校验:从本次安装的包出发递归纯 fs 探测依赖可达性,返回
|
|
269
|
-
* 「包: 缺失依赖」描述列表。背景是 Bun isolated 布局的增量安装缺陷
|
|
270
|
-
* (2026-09-07 实证):升级插件时包目录 hash 变化,而其依赖的解析
|
|
271
|
-
* 结果未变,bun 的增量安装跳过新包目录内的依赖链接建立——插件入口
|
|
272
|
-
* (顶层 symlink)可加载,内部依赖的 require 却炸 MODULE_NOT_FOUND;
|
|
273
|
-
* 此时补跑一次普通 bun install,bun 按磁盘实际状态检测到包不完整
|
|
274
|
-
* 即重建链接(秒级)。全程只走 existsSync / readFileSync /
|
|
275
|
-
* realpathSync,不触碰解析 API(防父目录快照缓存,与
|
|
276
|
-
* resolvePackageJson 同一纪律)。peer / optional 依赖由宿主或按需
|
|
277
|
-
* 提供不入校验;workspace / alias 等非 semver 声明的落盘名与键名无
|
|
278
|
-
* 直接映射,同样跳过。
|
|
279
|
-
*/
|
|
280
|
-
_findMissingDeps(deps) {
|
|
281
|
-
const problems = [];
|
|
282
|
-
const visited = /* @__PURE__ */ new Set();
|
|
283
|
-
const walk = (dir, label) => {
|
|
284
|
-
if (visited.has(dir)) return;
|
|
285
|
-
visited.add(dir);
|
|
286
|
-
let manifest;
|
|
287
|
-
try {
|
|
288
|
-
manifest = JSON.parse(readFileSync(join(dir, "package.json"), "utf8"));
|
|
289
|
-
} catch {
|
|
290
|
-
return;
|
|
291
|
-
}
|
|
292
|
-
for (const [dep, request] of Object.entries(manifest.dependencies ?? {})) {
|
|
293
|
-
if (request.includes(":")) continue;
|
|
294
|
-
const depDir = probePackage(dir, dep);
|
|
295
|
-
if (!depDir) {
|
|
296
|
-
problems.push(`${label} 的依赖 ${dep} 未被链接`);
|
|
297
|
-
continue;
|
|
298
|
-
}
|
|
299
|
-
walk(depDir, `${label} → ${dep}`);
|
|
300
|
-
}
|
|
301
|
-
};
|
|
302
|
-
for (const name in deps) {
|
|
303
|
-
const request = deps[name];
|
|
304
|
-
if (!request || request.includes(":")) continue;
|
|
305
|
-
const dir = probePackage(this.cwd, name);
|
|
306
|
-
if (!dir) continue;
|
|
307
|
-
walk(dir, name);
|
|
308
|
-
}
|
|
309
|
-
return problems;
|
|
310
|
-
}
|
|
311
357
|
_getLocalDeps(override) {
|
|
312
358
|
return valueMap(override, (request, name) => {
|
|
313
359
|
const dep = { request };
|
|
@@ -333,12 +379,12 @@ var Installer = class extends Service {
|
|
|
333
379
|
if (shouldInstall) {
|
|
334
380
|
const code = await this._install();
|
|
335
381
|
if (code) return code;
|
|
336
|
-
const missing = this.
|
|
382
|
+
const missing = findMissingDeps(this.cwd, deps);
|
|
337
383
|
if (missing.length) {
|
|
338
384
|
logger$2.warn(`检测到增量安装未建立部分依赖链接(isolated 布局已知缺陷),正在补装: ${missing.join("; ")}`);
|
|
339
385
|
const retry = await this._install();
|
|
340
386
|
if (retry) return retry;
|
|
341
|
-
if (this.
|
|
387
|
+
if (findMissingDeps(this.cwd, deps).length) logger$2.warn("自动补装后依赖链接仍不完整,请在项目根目录运行 bun install --force 并重启 koishi");
|
|
342
388
|
}
|
|
343
389
|
}
|
|
344
390
|
this.refresh();
|
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.
|
|
4
|
+
"version": "1.1.2",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.mjs",
|
|
7
7
|
"typings": "lib/index.d.ts",
|
|
@@ -61,19 +61,21 @@
|
|
|
61
61
|
},
|
|
62
62
|
"devDependencies": {
|
|
63
63
|
"@koishi-ce/plugin-database-memory": "^1.1.0",
|
|
64
|
-
"@koishi-ce/client": "^1.
|
|
65
|
-
"@koishi-ce/loader": "^1.0
|
|
66
|
-
"@koishi-ce/plugin-config": "^1.1.
|
|
67
|
-
"@
|
|
64
|
+
"@koishi-ce/client": "^1.3.0",
|
|
65
|
+
"@koishi-ce/loader": "^1.1.0",
|
|
66
|
+
"@koishi-ce/plugin-config": "^1.1.4",
|
|
67
|
+
"@koishi-ce/components": "^1.0.4",
|
|
68
68
|
"@types/semver": "^7.5.8",
|
|
69
|
-
"@types/spark-md5": "^3.0.4",
|
|
70
69
|
"@vueuse/core": "^14.4.0",
|
|
70
|
+
"cosmokit": "^1.8.1",
|
|
71
71
|
"spark-md5": "^3.0.2",
|
|
72
72
|
"vue": "^3.5.12",
|
|
73
|
+
"vue-i18n": "^11.4.10",
|
|
73
74
|
"vue-router": "^5.2.0"
|
|
74
75
|
},
|
|
75
76
|
"dependencies": {
|
|
76
|
-
"@koishi-ce/console": "^1.
|
|
77
|
+
"@koishi-ce/console": "^1.1.0",
|
|
78
|
+
"@koishi-ce/utils": "^1.1.0",
|
|
77
79
|
"@koishi-ce/registry": "^1.0.5",
|
|
78
80
|
"semver": "^7.6.3"
|
|
79
81
|
},
|
package/src/index.test.ts
CHANGED
|
@@ -23,7 +23,7 @@ import memory from "@koishi-ce/plugin-database-memory";
|
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
25
|
* market 插件测试:
|
|
26
|
-
* - 子进程(bun 安装)经 mock.module
|
|
26
|
+
* - 子进程(bun 安装)经 mock.module 拦截 installer/proc.ts(spawnBun 封装),不落盘不联网安装;
|
|
27
27
|
* - registry 网络请求由进程内 Bun.serve 提供(registry 协议的最小 JSON);
|
|
28
28
|
* - 宿主环境(loader / cwd)使用 FakeLoader 与临时目录 + chdir,
|
|
29
29
|
* Installer 的 override 写盘只会作用于临时 package.json。
|
|
@@ -64,7 +64,7 @@ const spawnBunMock = (_args: string[], _cwd: string) => {
|
|
|
64
64
|
};
|
|
65
65
|
};
|
|
66
66
|
|
|
67
|
-
mock.module("
|
|
67
|
+
mock.module("./node/installer/proc.ts", () => ({
|
|
68
68
|
spawnBun: spawnBunMock,
|
|
69
69
|
}));
|
|
70
70
|
|
|
@@ -84,7 +84,7 @@ const { isResidentInCache } = await import(
|
|
|
84
84
|
);
|
|
85
85
|
const market = await import("./node/index.ts");
|
|
86
86
|
const { default: Installer } = await import(
|
|
87
|
-
"./node/installer.ts"
|
|
87
|
+
"./node/installer/index.ts"
|
|
88
88
|
);
|
|
89
89
|
const mockPlugin = (await import("@koishi-ce/plugin-mock"))
|
|
90
90
|
.default;
|
package/src/node/deps.ts
CHANGED
|
@@ -8,7 +8,7 @@ import type {
|
|
|
8
8
|
DependencyMetaKey,
|
|
9
9
|
RemotePackage,
|
|
10
10
|
} from "@koishi-ce/registry";
|
|
11
|
-
import type { Dependency } from "./installer.ts";
|
|
11
|
+
import type { Dependency } from "./installer/index.ts";
|
|
12
12
|
|
|
13
13
|
class DependencyProvider extends DataService<
|
|
14
14
|
Dict<Dependency>
|
package/src/node/index.ts
CHANGED
|
@@ -14,13 +14,13 @@ import type {
|
|
|
14
14
|
RemotePackage,
|
|
15
15
|
} from "@koishi-ce/registry";
|
|
16
16
|
import { gt } from "semver";
|
|
17
|
+
import messageZhCN from "../../locales/message.zh-CN.yml";
|
|
18
|
+
import schemaZhCN from "../../locales/schema.zh-CN.yml";
|
|
17
19
|
import {
|
|
18
20
|
DependencyProvider,
|
|
19
21
|
RegistryProvider,
|
|
20
22
|
} from "./deps.ts";
|
|
21
|
-
import Installer from "./installer.ts";
|
|
22
|
-
import messageZhCN from "./locales/message.zh-CN.yml";
|
|
23
|
-
import schemaZhCN from "./locales/schema.zh-CN.yml";
|
|
23
|
+
import Installer from "./installer/index.ts";
|
|
24
24
|
import MarketProvider from "./market.ts";
|
|
25
25
|
|
|
26
26
|
export * from "../shared/index.ts";
|