feat: add cnb API module with various endpoints for workspace management, repository operations, and issue tracking

This commit is contained in:
2026-03-10 01:23:18 +08:00
parent 253ef2ac7d
commit 4ed81a1c68
10 changed files with 1264 additions and 288 deletions

View File

@@ -18,7 +18,7 @@ import { useRepoStore } from '../store'
import { useMemo, useState } from 'react'
import { useShallow } from 'zustand/shallow'
import { myOrgs } from '../store/build'
import { app, cnb } from '@/agents/app'
import { app } from '@/agents/app'
import { toast } from 'sonner'
import { useNavigate } from '@tanstack/react-router'
import clsx from 'clsx'

View File

@@ -64,7 +64,7 @@ export function EditRepoDialog({ open, onOpenChange, repo }: EditRepoDialogProps
path: repo.path,
description: data.description?.trim() || '',
site: data.site?.trim() || '',
topics: tags.join(','),
topics: tags as any,
license: data.license?.trim() || '',
})

View File

@@ -1,11 +1,10 @@
import { create } from 'zustand';
import { query } from '@/modules/query';
import { toast } from 'sonner';
import { cnb } from '@/agents/app'
import { queryApi as cnbApi } from '@/modules/cnb-api'
import { WorkspaceInfo } from '@kevisual/cnb'
import { createBuildConfig, createCommitBlankConfig, createDevConfig } from './build';
import { useLayoutStore } from '@/pages/auth/store';
import { useConfigStore } from '@/pages/config/store';
interface DisplayModule {
activity: boolean;
contributors: boolean;
@@ -77,7 +76,7 @@ type State = {
showCreateDialog: boolean;
setShowCreateDialog: (show: boolean) => void;
getList: (params?: { search?: string }, silent?: boolean) => Promise<any>;
updateRepoInfo: (data: Partial<Data>) => Promise<any>;
updateRepoInfo: (data: Partial<Data & { topics: string[] }>) => Promise<any>;
createRepo: (data: { visibility: any, path: string, description: string, license: string }) => Promise<any>;
deleteItem: (repo: string) => Promise<any>;
workspaceList: WorkspaceInfo[];
@@ -236,9 +235,10 @@ export const useRepoStore = create<State>((set, get) => {
toast.error('请先保存构建配置');
return;
}
const res = await cnb.build.startBuild(config.repo, {
const res = await cnbApi.cnb['cloud-build']({
repo: config.repo,
branch: config.branch,
env: {},
env: {} as any,
event: config.event,
config: config.config,
})
@@ -252,7 +252,7 @@ export const useRepoStore = create<State>((set, get) => {
const { setLoading } = get();
setLoading(true);
try {
const res = await cnb.repo.getRepo(repo)
const res = await cnbApi.cnb['get-repo']({ name: repo })
if (res.code === 200) {
const data = res.data!;
set({ editRepo: data })
@@ -275,9 +275,9 @@ export const useRepoStore = create<State>((set, get) => {
search: params.search
}
}
const res = await cnb.repo.getRepoList(opts)
const res = await cnbApi.cnb['list-repos'](opts)
if (res.code === 200) {
const list = res.data! || []
const list = res.data?.list || []
set({ list });
} else {
toast.error(res.message || '请求失败');
@@ -291,7 +291,7 @@ export const useRepoStore = create<State>((set, get) => {
},
updateRepoInfo: async (data) => {
const repo = data.path!;
let topics = data.topics?.split?.(',');
let topics = data.topics as string[];
if (Array.isArray(topics)) {
topics = topics.map(t => t.trim()).filter(Boolean);
}
@@ -299,12 +299,12 @@ export const useRepoStore = create<State>((set, get) => {
topics.push('cnb-center')
}
const updateData = {
description: data.description,
description: data.description!,
license: data?.license as any,
site: data.site,
topics: topics
}
const res = await cnb.repo.updateRepoInfo(repo, updateData)
const res = await cnbApi.cnb['update-repo-info']({ name: repo, ...updateData })
if (res.code === 200) {
toast.success('更新成功');
} else {
@@ -314,7 +314,7 @@ export const useRepoStore = create<State>((set, get) => {
refresh: async (opts?: { message?: string, showTips?: boolean, search?: string }) => {
const getList = get().getList({ search: opts?.search }, true);
const getWorkspaceList = get().getWorkspaceList();
await Promise.all([getList, getWorkspaceList]);
if (opts?.showTips !== false) {
@@ -329,7 +329,7 @@ export const useRepoStore = create<State>((set, get) => {
description: data.description || '',
license: data?.license as any,
};
const res = await cnb.repo.createRepo(createData);
const res = await cnbApi.cnb['create-repo'](createData);
console.log('res', res)
// if (res.code === 200) {
// toast.success('仓库创建成功');
@@ -345,7 +345,7 @@ export const useRepoStore = create<State>((set, get) => {
},
deleteItem: async (repo: string) => {
try {
const res = await cnb.repo.deleteRepoCookie(repo)
const res = await cnbApi.cnb['delete-repo']({ name: repo });
if (res.code === 200) {
toast.success('删除成功');
// 刷新列表
@@ -367,7 +367,8 @@ export const useRepoStore = create<State>((set, get) => {
},
workspaceList: [],
getWorkspaceList: async () => {
const res = await cnb.workspace.list({
// const res = await cnb.workspace.list({
const res = await cnbApi.cnb['list-workspace']({
status: 'running',
pageSize: 100
})
@@ -381,9 +382,7 @@ export const useRepoStore = create<State>((set, get) => {
startWorkspace: async (data, params = { open: true, branch: 'main' }) => {
const repo = data.path;
const checkOpen = async () => {
const res = await cnb.workspace.startWorkspace(repo!, {
branch: params.branch || 'main'
})
const res = await cnbApi.cnb['start-workspace']({ repo: repo!, branch: params.branch || 'main' });
if (res.code === 200) {
if (!res?.data?.sn) {
const url = res.data?.url! || '';
@@ -456,7 +455,7 @@ export const useRepoStore = create<State>((set, get) => {
toast.error('未选择工作区');
return;
}
const res = await cnb.workspace.stopWorkspace({ sn });
const res = await cnbApi.cnb['stop-workspace']({ sn })
// @ts-ignore
if (res?.code === 200) {
toast.success('工作区已停止');
@@ -469,7 +468,7 @@ export const useRepoStore = create<State>((set, get) => {
},
selectWorkspace: undefined,
getWorkspaceDetail: async (workspaceInfo) => {
const res = await cnb.workspace.getDetail(workspaceInfo.slug, workspaceInfo.sn) as any;
const res = await cnbApi.cnb['get-workspace']({ repo: workspaceInfo.slug, sn: workspaceInfo.sn }) as any;
if (res.code === 200) {
set({
workspaceLink: res.data,
@@ -488,9 +487,10 @@ export const useRepoStore = create<State>((set, get) => {
return;
}
let event = toRepo ? 'api_trigger_sync_to_gitea' : 'api_trigger_sync_from_gitea';
const res = await cnb.build.startBuild(repo, {
const res = await cnbApi.cnb['cloud-build']({
repo: toRepo! || fromRepo!,
branch: 'main',
env: {},
env: {} as any,
event: event,
config: createBuildConfig({ repo: toRepo! || fromRepo! }),
})
@@ -501,9 +501,10 @@ export const useRepoStore = create<State>((set, get) => {
}
},
buildUpdate: async (data) => {
const res = await cnb.build.startBuild(data.path!, {
const res = await cnbApi.cnb['cloud-build']({
repo: data.path!,
branch: 'main',
env: {},
env: {} as any,
event: 'api_trigger_event',
config: createCommitBlankConfig({ repo: data.path!, event: 'api_trigger_event' }),
})