Skip to content

Commit

Permalink
feat(market): check for bulk mode versions, fix koishijs#287
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed Jan 16, 2024
1 parent 1e278f4 commit e863ada
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 37 deletions.
8 changes: 2 additions & 6 deletions plugins/market/client/components/dependencies.vue
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,16 @@
import { computed, watch, WatchStopHandle } from 'vue'
import { store, useContext } from '@koishijs/client'
import { config, hasUpdate } from '../utils'
import { manualDeps } from './utils'
import { addManual } from './utils'
import ManualInstall from './manual.vue'
import PackageView from './package.vue'
import { compare } from 'semver'
const names = computed(() => {
return Object
.keys({
...store.dependencies,
...config.value.override,
})
.filter(name => !store.dependencies[name]?.workspace)
.sort((a, b) => a > b ? 1 : -1)
})
Expand All @@ -60,9 +58,7 @@ watch(() => store.market?.registry, (registry) => {
dispose = watch(() => config.value.override, (object) => {
Object.keys(object).forEach(async (name) => {
if (store.dependencies[name]) return
const response = await fetch(`${registry}/${name}`)
const data = await response.json()
manualDeps[name] = data
addManual(name)
})
}, { immediate: true })
}, { immediate: true })
Expand Down
60 changes: 42 additions & 18 deletions plugins/market/client/components/install.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<span :id="titleId" :class="titleClass">
{{ active + (workspace ? ' (工作区)' : '') }}
</span>
<el-select v-if="data" :disabled="workspace" v-model="selectVersion">
<el-select v-if="data" :disabled="!!workspace" v-model="selectVersion">
<el-option v-for="({ result }, version) in data" :key="version" :value="version">
{{ version }}
<template v-if="version === current">(当前)</template>
Expand Down Expand Up @@ -41,10 +41,10 @@
<td>{{ request }}</td>
<td>{{ resolved }}</td>
<td :class="['theme-color', result]">
<span v-if="result === 'primary'"><k-icon name="info-full"></k-icon>可选</span>
<span v-else-if="result === 'warning'"><k-icon name="exclamation-full"></k-icon>未下载</span>
<span v-else-if="result === 'success'"><k-icon name="check-full"></k-icon>已下载</span>
<span v-else><k-icon name="times-full"></k-icon>不兼容</span>
<span class="inline-flex items-center gap-1">
<k-icon :name="getResultIcon(result)"></k-icon>
{{ getResultText(result, name) }}
</span>
</td>
</tr>
</table>
Expand All @@ -60,14 +60,13 @@
</el-checkbox>
</div>
<div class="right">
<el-button @click="active = ''">取消</el-button>
<el-button v-if="local" type="primary" @click="configure()">配置</el-button>
<template v-if="workspace">
<el-button v-if="current || config.bulk && config.override[active]" @click="installDep('', true)">移除</el-button>
<el-button v-else @click="installDep(version)" :disabled="unchanged">添加</el-button>
<el-button v-if="showRemoveButton" @click="installDep('', true)" type="danger">移除</el-button>
<el-button v-else @click="installDep(workspace)" type="success">添加</el-button>
</template>
<template v-else-if="data">
<el-button v-if="current || store.dependencies[active] || config.bulk && config.override[active]" @click="installDep('', true)" type="danger">卸载</el-button>
<el-button v-if="showRemoveButton" @click="installDep('', true)" type="danger">卸载</el-button>
<el-button :type="result" @click="installDep(version)" :disabled="unchanged">
{{ current ? '更新' : store.dependencies?.[active] ? '修复' : '安装' }}
</el-button>
Expand Down Expand Up @@ -100,7 +99,8 @@ const confirmRemoveConfig = ref(false)
function installDep(version: string, checkConfig = false, removeConfig = false) {
const target = active.value
if (!target) return
if (config.value.bulk) {
// workspace packages don't need to be installed
if (config.value.bulk && !workspace.value) {
config.value.override[target] = version
active.value = ''
return
Expand All @@ -110,6 +110,7 @@ function installDep(version: string, checkConfig = false, removeConfig = false)
return
}
install({ [target]: version }, async () => {
if (workspace.value) return
if (version) {
ctx.configWriter?.ensure(target)
} else if (removeConfig) {
Expand Down Expand Up @@ -142,10 +143,19 @@ const current = computed(() => store.dependencies?.[active.value]?.resolved)
const local = computed(() => store.packages?.[active.value])
const versions = computed(() => store.registry?.[active.value])
const showRemoveButton = computed(() => {
return current.value || store.dependencies[active.value] || config.value.bulk && config.value.override[active.value]
})
const workspace = computed(() => {
// workspace plugins: dependencies ? packages √
// workspace non-plugins: dependencies √ packages ×
return store.dependencies?.[active.value]?.workspace || local.value?.workspace
if (store.dependencies?.[active.value]?.workspace) {
return store.dependencies?.[active.value]?.resolved
}
if (local.value?.workspace) {
return local.value?.package.version
}
})
watch(active, async (name) => {
Expand All @@ -157,7 +167,7 @@ watch(active, async (name) => {
const data = computed(() => {
if (!active.value || workspace.value) return
return analyzeVersions(active.value)
return analyzeVersions(active.value, config.value.bulk)
})
const danger = computed(() => {
Expand Down Expand Up @@ -200,6 +210,26 @@ function configure() {
active.value = null
}
function getResultIcon(type: 'primary' | 'warning' | 'danger' | 'success') {
switch (type) {
case 'primary': return 'info-full'
case 'warning': return 'exclamation-full'
case 'danger': return 'times-full'
case 'success': return 'check-full'
}
}
function getResultText(type: 'primary' | 'warning' | 'danger' | 'success', name: string) {
const isOverriden = config.value.bulk && name in config.value.override
const isInstalled = store.packages ? !!store.packages[name] : !!store.dependencies?.[name]
switch (type) {
case 'primary': return '可选'
case 'warning': return isOverriden ? '等待移除' : '未下载'
case 'danger': return '不兼容'
case 'success': return isOverriden ? isInstalled ? '等待更新' : '等待安装' : '已下载'
}
}
</script>

<style lang="scss">
Expand Down Expand Up @@ -272,12 +302,6 @@ function configure() {
}
}
td.theme-color span {
display: inline-flex;
align-items: center;
gap: 0.25rem;
}
span.link {
&:hover {
cursor: pointer;
Expand Down
6 changes: 2 additions & 4 deletions plugins/market/client/components/manual.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { computed, ref, watch } from 'vue'
import type { Registry } from '@koishijs/registry'
import { store } from '@koishijs/client'
import { useDebounceFn } from '@vueuse/core'
import { showManual, manualDeps } from './utils'
import { showManual, addManual } from './utils'
import { config } from '../utils'
const invalid = computed(() => false)
Expand All @@ -33,9 +33,7 @@ const remote = ref<Registry>()
const fetchRemote = useDebounceFn(async (name2: string) => {
try {
const response = await fetch(`${store.market.registry}/${name2}`)
const data = await response.json()
manualDeps[name2] = data
const data = await addManual(name2)
if (name2 === name.value) remote.value = data
} catch {}
}, 500)
Expand Down
2 changes: 1 addition & 1 deletion plugins/market/client/components/market.vue
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ function getText(data: SearchObject) {
if (version) return '等待更新'
return '修改'
}
if (version) return '等待添加'
if (version) return '等待安装'
return '添加'
}
Expand Down
2 changes: 1 addition & 1 deletion plugins/market/client/components/package.vue
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ const version = computed({
const data = computed(() => {
if (local.value?.workspace || local.value?.invalid) return
return analyzeVersions(props.name)
return analyzeVersions(props.name, true)
})
</script>
Expand Down
25 changes: 18 additions & 7 deletions plugins/market/client/components/utils.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,29 @@
import { Awaitable, Dict, loading, message, send, socket, store, valueMap } from '@koishijs/client'
import type { Registry } from '@koishijs/registry'
import { satisfies } from 'semver'
import { compare, satisfies } from 'semver'
import { reactive, ref, watch } from 'vue'
import { active } from '../utils'
import { active, config } from '../utils'

type ResultType = 'success' | 'warning' | 'danger' | 'primary'

interface AnalyzeResult {
peers: Dict<{
request: string
resolved: string
result: 'success' | 'warning' | 'danger' | 'primary'
result: ResultType
}>
result: 'success' | 'warning' | 'danger' | 'primary'
result: ResultType
}

export function analyzeVersions(name: string): Dict<AnalyzeResult> {
export function analyzeVersions(name: string, bulkMode = true): Dict<AnalyzeResult> {
const versions = store.registry?.[name] || manualDeps[name]?.versions
if (!versions) return
return valueMap(versions, (item) => {
const peers = valueMap({ ...item.peerDependencies }, (request, name) => {
const resolved = store.dependencies[name]?.resolved || store.packages?.[name]?.package.version
const result: 'success' | 'warning' | 'danger' | 'primary' = !resolved
const resolved = (bulkMode ? config.value.override[name] : null)
?? store.dependencies[name]?.resolved
?? store.packages?.[name]?.package.version
const result: ResultType = !resolved
? item.peerDependenciesMeta?.[name]?.optional ? 'primary' : 'warning'
: satisfies(resolved, request, { includePrerelease: true }) ? 'success' : 'danger'
return { request, resolved, result }
Expand All @@ -41,6 +45,13 @@ export function analyzeVersions(name: string): Dict<AnalyzeResult> {

export const manualDeps = reactive<Dict<Registry>>({})

export async function addManual(name: string) {
const response = await fetch(`${store.market.registry}/${name}`)
const data: Registry = await response.json()
data.versions = Object.fromEntries(Object.entries(data.versions).sort((a, b) => compare(b[0], a[0])))
return manualDeps[name] = data
}

export const showManual = ref(false)
export const showConfirm = ref(false)

Expand Down

0 comments on commit e863ada

Please sign in to comment.