feat: manually mirror opencoze's code from bytedance

Change-Id: I09a73aadda978ad9511264a756b2ce51f5761adf
This commit is contained in:
fanlv
2025-07-20 17:36:12 +08:00
commit 890153324f
14811 changed files with 1923430 additions and 0 deletions

View File

@@ -0,0 +1,109 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { SpaceRoleType, SpaceType } from '@coze-arch/idl/developer_api';
import { ProjectRoleType, EProjectPermission } from './constants';
const projectRolePermissionMapOfTeamSpace = {
[ProjectRoleType.Owner]: [
EProjectPermission.View,
EProjectPermission.EDIT_INFO,
EProjectPermission.DELETE,
EProjectPermission.PUBLISH,
EProjectPermission.CREATE_RESOURCE,
EProjectPermission.COPY_RESOURCE,
EProjectPermission.COPY,
EProjectPermission.TEST_RUN_PLUGIN,
EProjectPermission.TEST_RUN_WORKFLOW,
EProjectPermission.ADD_COLLABORATOR,
EProjectPermission.DELETE_COLLABORATOR,
EProjectPermission.ROLLBACK,
],
[ProjectRoleType.Editor]: [
EProjectPermission.View,
EProjectPermission.EDIT_INFO,
EProjectPermission.CREATE_RESOURCE,
EProjectPermission.COPY_RESOURCE,
EProjectPermission.COPY,
EProjectPermission.TEST_RUN_PLUGIN,
EProjectPermission.TEST_RUN_WORKFLOW,
EProjectPermission.ADD_COLLABORATOR,
],
};
const spaceRolePermissionMapOfTeamSpace = {
[SpaceRoleType.Member]: [
EProjectPermission.View,
EProjectPermission.COPY,
EProjectPermission.TEST_RUN_WORKFLOW,
],
[SpaceRoleType.Owner]: [
EProjectPermission.View,
EProjectPermission.COPY,
EProjectPermission.TEST_RUN_WORKFLOW,
],
[SpaceRoleType.Admin]: [
EProjectPermission.View,
EProjectPermission.COPY,
EProjectPermission.TEST_RUN_WORKFLOW,
],
[SpaceRoleType.Default]: [] as EProjectPermission[],
};
const personalSpacePermission = [
EProjectPermission.View,
EProjectPermission.EDIT_INFO,
EProjectPermission.PUBLISH,
EProjectPermission.DELETE,
EProjectPermission.CREATE_RESOURCE,
EProjectPermission.COPY_RESOURCE,
EProjectPermission.COPY,
EProjectPermission.TEST_RUN_PLUGIN,
EProjectPermission.TEST_RUN_WORKFLOW,
EProjectPermission.ROLLBACK,
];
export function calcPermission(
key: EProjectPermission,
{
projectRoles,
spaceRoles,
spaceType,
}: {
projectRoles: ProjectRoleType[];
spaceRoles: SpaceRoleType[];
spaceType: SpaceType;
},
) {
if (spaceType === SpaceType.Personal) {
return personalSpacePermission.includes(key);
} else {
for (const projectRole of projectRoles) {
if (projectRolePermissionMapOfTeamSpace[projectRole]?.includes(key)) {
return true;
}
}
for (const spaceRole of spaceRoles) {
if (spaceRolePermissionMapOfTeamSpace[spaceRole]?.includes(key)) {
return true;
}
}
return false;
}
}

View File

@@ -0,0 +1,72 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// TODO: 替换成Project接口导出的idl
export enum ProjectRoleType {
Owner = 'owner',
Editor = 'editor',
}
export enum EProjectPermission {
/**
* 访问/查看project
*/
View,
/**
* 编辑project基础信息
*/
EDIT_INFO,
/**
* 删除project
*/
DELETE,
/**
* 发布project
*/
PUBLISH,
/**
* 创建project内资源
*/
CREATE_RESOURCE,
/**
* 在project内复制资源
*/
COPY_RESOURCE,
/**
* 复制project/创建副本
*/
COPY,
/**
* 试运行plugin
*/
TEST_RUN_PLUGIN,
/**
* 试运行workflow
*/
TEST_RUN_WORKFLOW,
/**
* 添加project协作者
*/
ADD_COLLABORATOR,
/**
* 删除project协作者
*/
DELETE_COLLABORATOR,
/**
* 回滚 APP 版本
*/
ROLLBACK,
}

View File

@@ -0,0 +1,71 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { devtools } from 'zustand/middleware';
import { create } from 'zustand';
import { type ProjectRoleType } from './constants';
interface ProjectAuthStoreState {
// 每一个Project的角色数据
roles: {
[projectId: string]: ProjectRoleType[];
};
// 每一个Project的角色数据的初始化状态是否完成初始化。
isReady: {
[projectId: string]: boolean;
};
}
interface SpaceAuthStoreAction {
// 设置projectId对应的Project的角色
setRoles: (projectId: string, role: ProjectRoleType[]) => void;
// 设置projectId对应的Project的数据是否ready
setIsReady: (projectId: string, isReady: boolean) => void;
// 回收Project数据
destory: (projectId) => void;
}
/**
* ProjectAuthStore设计成支持多Project切换维护多个Project的数据防止因为Project切换时序导致的bug。
*/
export const useProjectAuthStore = create<
ProjectAuthStoreState & SpaceAuthStoreAction
>()(
devtools(
set => ({
roles: {},
isReady: {},
setRoles: (projectId, roles) =>
set(state => ({
roles: {
...state.roles,
[projectId]: roles,
},
})),
setIsReady: (projectId, isReady) =>
set(state => ({ isReady: { ...state.isReady, [projectId]: isReady } })),
destory: projectId =>
set(state => ({
roles: { ...state.roles, [projectId]: [] },
isReady: { ...state.isReady, [projectId]: false },
})),
}),
{
enabled: IS_DEV_MODE,
name: 'botStudio.projectAuthStore',
},
),
);

View File

@@ -0,0 +1,31 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { useEffect } from 'react';
import { useProjectAuthStore } from './store';
export function useDestoryProject(projectId: string) {
const destorySpace = useProjectAuthStore(store => store.destory);
return useEffect(
() => () => {
// 空间组件销毁时清空对应space数据
destorySpace(projectId);
},
[],
);
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { useSpace } from '@coze-arch/foundation-sdk';
import { useSpaceRole } from '../space/use-space-role';
import { useProjectRole } from './use-project-role';
import { type EProjectPermission } from './constants';
import { calcPermission } from './calc-permission';
export function useProjectAuth(
key: EProjectPermission,
projectId: string,
spaceId: string,
) {
// 获取space类型信息
const space = useSpace(spaceId);
if (!space?.space_type) {
throw new Error(
'useSpaceAuth must be used after space list has been pulled.',
);
}
// 获取space role信息
const spaceRoles = useSpaceRole(spaceId);
// 获取project role信息
const projectRoles = useProjectRole(projectId);
// 计算权限点
return calcPermission(key, {
projectRoles,
spaceRoles,
spaceType: space.space_type,
});
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { useShallow } from 'zustand/react/shallow';
import { useProjectAuthStore } from './store';
import { type ProjectRoleType } from './constants';
export function useProjectRole(projectId: string): ProjectRoleType[] {
const { isReady: isProjectReady, role: projectRole = [] } =
useProjectAuthStore(
useShallow(store => ({
isReady: store.isReady[projectId],
role: store.roles[projectId],
})),
);
if (!isProjectReady) {
throw new Error(
'useProjectAuth must be used after useInitProjectRole has been completed.',
);
}
return projectRole;
}