@catchmexz/fedin-vibe-mcp-server 0.1.0

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.
Files changed (83) hide show
  1. package/LICENSE +202 -0
  2. package/dist/common/errors.js +69 -0
  3. package/dist/common/modularTemplates.js +483 -0
  4. package/dist/common/pipelineTemplates.js +19 -0
  5. package/dist/common/types.js +42 -0
  6. package/dist/common/utils.js +347 -0
  7. package/dist/common/version.js +1 -0
  8. package/dist/index.js +217 -0
  9. package/dist/operations/appstack/appOrchestrations.js +235 -0
  10. package/dist/operations/appstack/appTags.js +147 -0
  11. package/dist/operations/appstack/appTemplates.js +67 -0
  12. package/dist/operations/appstack/applications.js +154 -0
  13. package/dist/operations/appstack/changeOrders.js +293 -0
  14. package/dist/operations/appstack/changeRequests.js +263 -0
  15. package/dist/operations/appstack/deploymentResources.js +265 -0
  16. package/dist/operations/appstack/globalVars.js +200 -0
  17. package/dist/operations/appstack/releaseWorkflows.js +178 -0
  18. package/dist/operations/appstack/variableGroups.js +216 -0
  19. package/dist/operations/codeup/branches.js +144 -0
  20. package/dist/operations/codeup/changeRequestComments.js +89 -0
  21. package/dist/operations/codeup/changeRequests.js +203 -0
  22. package/dist/operations/codeup/compare.js +26 -0
  23. package/dist/operations/codeup/files.js +483 -0
  24. package/dist/operations/codeup/repositories.js +83 -0
  25. package/dist/operations/codeup/types.js +372 -0
  26. package/dist/operations/flow/hostGroup.js +48 -0
  27. package/dist/operations/flow/pipeline.js +530 -0
  28. package/dist/operations/flow/pipelineJob.js +113 -0
  29. package/dist/operations/flow/serviceConnection.js +23 -0
  30. package/dist/operations/flow/types.js +377 -0
  31. package/dist/operations/git/git-repository.js +334 -0
  32. package/dist/operations/git/index.js +210 -0
  33. package/dist/operations/organization/members.js +94 -0
  34. package/dist/operations/organization/organization.js +73 -0
  35. package/dist/operations/organization/types.js +111 -0
  36. package/dist/operations/packages/artifacts.js +64 -0
  37. package/dist/operations/packages/repositories.js +35 -0
  38. package/dist/operations/packages/types.js +56 -0
  39. package/dist/operations/projex/project.js +206 -0
  40. package/dist/operations/projex/sprint.js +90 -0
  41. package/dist/operations/projex/types.js +390 -0
  42. package/dist/operations/projex/workitem.js +452 -0
  43. package/dist/tool-handlers/appstack-change-orders.js +55 -0
  44. package/dist/tool-handlers/appstack-change-requests.js +49 -0
  45. package/dist/tool-handlers/appstack-deployment-resources.js +43 -0
  46. package/dist/tool-handlers/appstack-global-vars.js +43 -0
  47. package/dist/tool-handlers/appstack-orchestrations.js +49 -0
  48. package/dist/tool-handlers/appstack-tags.js +43 -0
  49. package/dist/tool-handlers/appstack-templates.js +19 -0
  50. package/dist/tool-handlers/appstack-variable-groups.js +55 -0
  51. package/dist/tool-handlers/appstack.js +37 -0
  52. package/dist/tool-handlers/code-management.js +174 -0
  53. package/dist/tool-handlers/git/branch-operations.js +1 -0
  54. package/dist/tool-handlers/git/clone-repository.js +36 -0
  55. package/dist/tool-handlers/git/create-branch.js +26 -0
  56. package/dist/tool-handlers/git/get-repository-status.js +33 -0
  57. package/dist/tool-handlers/git/pull-repository.js +27 -0
  58. package/dist/tool-handlers/git/push-repository.js +37 -0
  59. package/dist/tool-handlers/git/switch-branch.js +25 -0
  60. package/dist/tool-handlers/index.js +43 -0
  61. package/dist/tool-handlers/organization.js +90 -0
  62. package/dist/tool-handlers/packages.js +32 -0
  63. package/dist/tool-handlers/pipeline.js +272 -0
  64. package/dist/tool-handlers/project-management.js +152 -0
  65. package/dist/tool-handlers/service-connections.js +16 -0
  66. package/dist/tool-registry/appstack-change-orders.js +40 -0
  67. package/dist/tool-registry/appstack-change-requests.js +35 -0
  68. package/dist/tool-registry/appstack-deployment-resources.js +30 -0
  69. package/dist/tool-registry/appstack-global-vars.js +30 -0
  70. package/dist/tool-registry/appstack-orchestrations.js +35 -0
  71. package/dist/tool-registry/appstack-tags.js +30 -0
  72. package/dist/tool-registry/appstack-templates.js +10 -0
  73. package/dist/tool-registry/appstack-variable-groups.js +40 -0
  74. package/dist/tool-registry/appstack.js +25 -0
  75. package/dist/tool-registry/code-management.js +89 -0
  76. package/dist/tool-registry/git-repository.js +41 -0
  77. package/dist/tool-registry/index.js +6 -0
  78. package/dist/tool-registry/organization.js +65 -0
  79. package/dist/tool-registry/packages.js +21 -0
  80. package/dist/tool-registry/pipeline.js +157 -0
  81. package/dist/tool-registry/project-management.js +108 -0
  82. package/dist/tool-registry/service-connections.js +10 -0
  83. package/package.json +39 -0
@@ -0,0 +1,73 @@
1
+ import { buildUrl, yunxiaoRequest } from "../../common/utils.js";
2
+ import { CurrentOrganizationInfoSchema, UserOrganizationsInfoSchema, CurrentUserSchema, OrganizationDepartmentsSchema, DepartmentInfoSchema, OrganizationRoleSchema, OrganizationRole, } from "./types.js";
3
+ export async function getCurrentOrganizationInfoFunc() {
4
+ const url = "/oapi/v1/platform/user";
5
+ const response = await yunxiaoRequest(url, {
6
+ method: "GET",
7
+ });
8
+ const responseData = response;
9
+ const mappedResponse = {
10
+ lastOrganization: responseData.lastOrganization, // Organization ID
11
+ userId: responseData.id, // Map API's "id" to userId
12
+ userName: responseData.name // Map API's "name" to userName
13
+ };
14
+ return CurrentOrganizationInfoSchema.parse(mappedResponse);
15
+ }
16
+ export async function getUserOrganizationsFunc() {
17
+ const url = "/oapi/v1/platform/organizations";
18
+ const response = await yunxiaoRequest(url, {
19
+ method: "GET",
20
+ });
21
+ if (!Array.isArray(response)) {
22
+ return [];
23
+ }
24
+ return UserOrganizationsInfoSchema.parse(response);
25
+ }
26
+ export async function getOrganizationDepartmentsFunc(organizationId, parentId) {
27
+ const baseUrl = `/oapi/v1/platform/organizations/${organizationId}/departments`;
28
+ const params = {};
29
+ if (parentId) {
30
+ params.parentId = parentId;
31
+ }
32
+ const url = buildUrl(baseUrl, params);
33
+ const response = await yunxiaoRequest(url, {
34
+ method: "GET"
35
+ });
36
+ return OrganizationDepartmentsSchema.parse(response);
37
+ }
38
+ export async function getOrganizationDepartmentInfoFunc(organizationId, id) {
39
+ const url = `/oapi/v1/platform/organizations/${organizationId}/departments/${id}`;
40
+ const response = await yunxiaoRequest(url, {
41
+ method: "GET",
42
+ });
43
+ return DepartmentInfoSchema.parse(response);
44
+ }
45
+ export async function getOrganizationDepartmentAncestorsFunc(organizationId, id) {
46
+ const url = `/oapi/v1/platform/organizations/${organizationId}/departments/${id}/ancestors`;
47
+ const response = await yunxiaoRequest(url, {
48
+ method: "GET",
49
+ });
50
+ return OrganizationDepartmentsSchema.parse(response);
51
+ }
52
+ ;
53
+ export async function listOrganizationRolesFunc(organizationId) {
54
+ const url = `/oapi/v1/platform/organizations/${organizationId}/roles`;
55
+ const response = await yunxiaoRequest(url, {
56
+ method: "GET"
57
+ });
58
+ return OrganizationRole.parse(response);
59
+ }
60
+ export async function getOrganizationRoleFunc(organizationId, roleId) {
61
+ const url = `/oapi/v1/platform/organizations/${organizationId}/roles/${roleId}`;
62
+ const response = await yunxiaoRequest(url, {
63
+ method: "GET"
64
+ });
65
+ return OrganizationRoleSchema.parse(response);
66
+ }
67
+ export async function getCurrentUserFunc() {
68
+ const url = "/oapi/v1/platform/user";
69
+ const response = await yunxiaoRequest(url, {
70
+ method: "GET",
71
+ });
72
+ return CurrentUserSchema.parse(response);
73
+ }
@@ -0,0 +1,111 @@
1
+ import { z } from "zod";
2
+ // Organization Role related types
3
+ export const OrganizationRoleSchema = z.object({
4
+ id: z.string().describe("Role ID"),
5
+ name: z.string().describe("Role name"),
6
+ organizationId: z.string().describe("Organization ID"),
7
+ permissions: z.array(z.string()).describe("Role permission list")
8
+ });
9
+ export const OrganizationRole = z.array(OrganizationRoleSchema);
10
+ export const ListOrganizationRolesSchema = z.object({
11
+ organizationId: z.string().describe("Organization ID")
12
+ });
13
+ export const GetOrganizationRoleSchema = z.object({
14
+ organizationId: z.string().describe("Organization ID"),
15
+ roleId: z.string().describe("Role ID")
16
+ });
17
+ // Organization Department related types
18
+ export const GetOrganizationDepartmentAncestorsSchema = z.object({
19
+ organizationId: z.string().describe("Organization ID"),
20
+ id: z.string().describe("Department ID"),
21
+ });
22
+ export const GetOrganizationDepartmentInfoSchema = z.object({
23
+ organizationId: z.string().describe("Organization ID"),
24
+ id: z.string().describe("Department ID"),
25
+ });
26
+ export const GetOrganizationDepartmentsSchema = z.object({
27
+ organizationId: z.string().describe("Organization ID"),
28
+ parentId: z.string().optional().describe("Parent department ID"),
29
+ });
30
+ // Organization related types
31
+ export const CurrentOrganizationInfoSchema = z.object({
32
+ lastOrganization: z.string().optional().describe("Organization ID of the most recent login, used for subsequent API calls, should be used as organizationId"),
33
+ userId: z.string().optional().describe("Current user ID, not the organization ID"),
34
+ userName: z.string().optional().describe("Current user name"),
35
+ });
36
+ export const OrganizationInfoSchema = z.object({
37
+ id: z.string().optional().describe("Organization ID"),
38
+ name: z.string().optional().describe("Organization name"),
39
+ description: z.string().optional().describe("Organization description"),
40
+ });
41
+ export const UserOrganizationsInfoSchema = z.array(OrganizationInfoSchema);
42
+ // User related types
43
+ export const UserInfoSchema = z.object({
44
+ id: z.string().nullable().optional().describe("User ID"),
45
+ name: z.string().nullable().optional().describe("User name"),
46
+ });
47
+ // Current user information schema
48
+ export const CurrentUserSchema = z.object({
49
+ id: z.string().nullable().optional().describe("User ID"),
50
+ name: z.string().optional().describe("Display name"),
51
+ email: z.string().optional().describe("Email address"),
52
+ username: z.string().optional().describe("Login account name"),
53
+ lastOrganization: z.string().optional().describe("Last login organization ID"),
54
+ staffId: z.string().optional().describe("Staff ID"),
55
+ nickName: z.string().optional().describe("Nickname"),
56
+ sysDeptIds: z.array(z.string()).optional().describe("Department IDs"),
57
+ createdAt: z.string().optional().describe("Creation time"),
58
+ deletedAt: z.string().optional().describe("Deletion time")
59
+ });
60
+ // Organization Department related types
61
+ export const DepartmentInfoSchema = z.object({
62
+ creatorId: z.string().optional().describe("创建人 ID"),
63
+ id: z.string().optional().describe("部门 ID"),
64
+ name: z.string().optional().describe("部门名称"),
65
+ organizationId: z.string().optional().describe("组织 ID"),
66
+ parentId: z.string().optional().describe("父部门 ID"),
67
+ hasSub: z.boolean().optional().describe("是否有子部门")
68
+ });
69
+ export const OrganizationDepartmentsSchema = z.array(DepartmentInfoSchema);
70
+ // Organization Member related types
71
+ export const MemberInfoSchema = z.object({
72
+ deptIds: z.array(z.string()).optional().describe("所属组织部门列表"),
73
+ id: z.string().optional().describe("成员 ID"),
74
+ joined: z.string().optional().describe("加入时间"),
75
+ name: z.string().optional().describe("成员名"),
76
+ organizationId: z.string().optional().describe("组织 ID"),
77
+ roleIds: z.array(z.string()).optional().describe("角色信息"),
78
+ status: z.string().optional().describe("成员状态,可选值:ENABLED,DISABLED,UNDELETED,DELETED,NORMAL_USING,UNVISITED"),
79
+ userId: z.string().optional().describe("用户 ID"),
80
+ visited: z.string().optional().describe("最后访问时间")
81
+ });
82
+ export const OrganizationMembersSchema = z.array(MemberInfoSchema);
83
+ // Organization Member detail types
84
+ export const GetOrganizationMemberInfoSchema = z.object({
85
+ organizationId: z.string().describe("组织 ID"),
86
+ memberId: z.string().describe("成员 ID"),
87
+ });
88
+ // Get organization member by user ID types
89
+ export const GetOrganizationMemberByUserIdInfoSchema = z.object({
90
+ organizationId: z.string().describe("组织 ID"),
91
+ userId: z.string().describe("用户 ID"),
92
+ });
93
+ // Search organization members types
94
+ export const SearchOrganizationMembersSchema = z.object({
95
+ organizationId: z.string().describe("Organization ID, can be found in the basic information page of the organization admin console"),
96
+ deptIds: z.array(z.string()).optional().describe("Department IDs to search for"),
97
+ query: z.string().optional().describe("Search query"),
98
+ includeChildren: z.boolean().optional().describe("Whether to include sub-departments"),
99
+ nextToken: z.string().optional().describe("Next token for pagination"),
100
+ roleIds: z.array(z.string()).optional().describe("Role IDs to search for"),
101
+ statuses: z.array(z.string()).optional().describe("User statuses, posibble values: ENABLED,DISABLED,UNDELETED,DELETED,NORMAL_USING,UNVISITED。ENABLED=NORMAL_USING+UNVISITED;UNDELETED=ENABLED+DISABLED"),
102
+ page: z.number().int().optional().describe("Current page number, defaults to 1"),
103
+ perPage: z.number().int().optional().describe("Number of items per page, defaults to 100")
104
+ });
105
+ export const SearchOrganizationMembersResultSchema = z.array(MemberInfoSchema);
106
+ // Get organization members schema
107
+ export const GetOrganizationMembersSchema = z.object({
108
+ organizationId: z.string().describe("Organization ID"),
109
+ page: z.number().int().optional().describe("Page number"),
110
+ perPage: z.number().int().optional().describe("Page size"),
111
+ });
@@ -0,0 +1,64 @@
1
+ import { yunxiaoRequest, buildUrl } from "../../common/utils.js";
2
+ import { ArtifactSchema, } from "./types.js";
3
+ /**
4
+ * 查询制品信息
5
+ * @param organizationId
6
+ * @param repoId
7
+ * @param repoType
8
+ * @param page
9
+ * @param perPage
10
+ * @param search
11
+ * @param orderBy
12
+ * @param sort
13
+ * @returns 制品信息列表
14
+ */
15
+ export async function listArtifactsFunc(organizationId, repoId, repoType, page, perPage, search, orderBy = "latestUpdate", sort = "desc") {
16
+ const baseUrl = `/oapi/v1/packages/organizations/${organizationId}/repositories/${repoId}/artifacts`;
17
+ const queryParams = {
18
+ repoType,
19
+ };
20
+ if (page !== undefined) {
21
+ queryParams.page = page;
22
+ }
23
+ if (perPage !== undefined) {
24
+ queryParams.perPage = perPage;
25
+ }
26
+ if (search !== undefined) {
27
+ queryParams.search = search;
28
+ }
29
+ queryParams.orderBy = orderBy;
30
+ queryParams.sort = sort;
31
+ const url = buildUrl(baseUrl, queryParams);
32
+ const response = await yunxiaoRequest(url, {
33
+ method: "GET",
34
+ });
35
+ if (!Array.isArray(response)) {
36
+ return [];
37
+ }
38
+ return response.map(artifact => ArtifactSchema.parse(artifact));
39
+ }
40
+ /**
41
+ * 查看单个制品信息
42
+ * @param organizationId
43
+ * @param repoId
44
+ * @param id
45
+ * @param repoType
46
+ * @returns 制品信息
47
+ */
48
+ export async function getArtifactFunc(organizationId, repoId, id, repoType) {
49
+ const baseUrl = `/oapi/v1/packages/organizations/${organizationId}/repositories/${repoId}/artifacts/${id}`;
50
+ const queryParams = {
51
+ repoType,
52
+ };
53
+ const url = buildUrl(baseUrl, queryParams);
54
+ try {
55
+ const response = await yunxiaoRequest(url, {
56
+ method: "GET",
57
+ });
58
+ return ArtifactSchema.parse(response);
59
+ }
60
+ catch (error) {
61
+ console.error(`Error fetching artifact: ${error}`);
62
+ return null;
63
+ }
64
+ }
@@ -0,0 +1,35 @@
1
+ import { yunxiaoRequest, buildUrl } from "../../common/utils.js";
2
+ import { PackageRepositorySchema, } from "./types.js";
3
+ /**
4
+ * 查看制品仓库信息
5
+ * @param organizationId
6
+ * @param repoTypes
7
+ * @param repoCategories
8
+ * @param perPage
9
+ * @param page
10
+ * @returns 制品仓库信息列表
11
+ */
12
+ export async function listPackageRepositoriesFunc(organizationId, repoTypes, repoCategories, perPage, page) {
13
+ const baseUrl = `/oapi/v1/packages/organizations/${organizationId}/repositories`;
14
+ const queryParams = {};
15
+ if (repoTypes !== undefined) {
16
+ queryParams.repoTypes = repoTypes;
17
+ }
18
+ if (repoCategories !== undefined) {
19
+ queryParams.repoCategories = repoCategories;
20
+ }
21
+ if (perPage !== undefined) {
22
+ queryParams.perPage = perPage;
23
+ }
24
+ if (page !== undefined) {
25
+ queryParams.page = page;
26
+ }
27
+ const url = buildUrl(baseUrl, queryParams);
28
+ const response = await yunxiaoRequest(url, {
29
+ method: "GET",
30
+ });
31
+ if (!Array.isArray(response)) {
32
+ return [];
33
+ }
34
+ return response.map(repo => PackageRepositorySchema.parse(repo));
35
+ }
@@ -0,0 +1,56 @@
1
+ import { z } from "zod";
2
+ // Package Repository related schemas
3
+ export const PackageRepositorySchema = z.object({
4
+ accessLevel: z.string().nullable().optional().describe("Access level: PRIVATE - Private repository (only accessible to repository members), INTERNAL - Organization-wide visibility (accessible to all organization members)"),
5
+ latestUpdate: z.number().int().nullable().optional().describe("Latest update time"),
6
+ repoCategory: z.string().nullable().optional().describe("Repository mode: Hybrid/Local/Proxy/ProxyCache/Group"),
7
+ repoDesc: z.string().nullable().optional().describe("Repository description"),
8
+ repoDescriptor: z.string().nullable().optional().describe("Repository descriptor file"),
9
+ repoId: z.string().nullable().optional().describe("Repository ID"),
10
+ repoName: z.string().nullable().optional().describe("Repository name"),
11
+ repoType: z.string().nullable().optional().describe("Repository type: GENERIC/DOCKER/MAVEN/NPM/NUGET"),
12
+ star: z.boolean().nullable().optional().describe("Whether the repository is favorited"),
13
+ });
14
+ export const ListPackageRepositoriesSchema = z.object({
15
+ organizationId: z.string().describe("Organization ID"),
16
+ repoTypes: z.string().optional().describe("Repository types, available values: GENERIC/DOCKER/MAVEN/NPM/NUGET, multiple types can be separated by commas"),
17
+ repoCategories: z.string().optional().describe("Repository modes, available values: Hybrid/Local/Proxy/ProxyCache/Group, multiple modes can be separated by commas"),
18
+ perPage: z.number().int().optional().default(8).describe("Number of items per page, default value is 8"),
19
+ page: z.number().int().optional().default(1).describe("Current page number"),
20
+ });
21
+ // Artifact related schemas
22
+ export const ArtifactVersionSchema = z.object({
23
+ createTime: z.number().int().nullable().optional().describe("Creation time"),
24
+ creator: z.string().nullable().optional().describe("Creator"),
25
+ gmtDownload: z.number().int().nullable().optional().describe("Latest download time"),
26
+ id: z.number().int().nullable().optional().describe("Artifact version ID"),
27
+ modifier: z.string().nullable().optional().describe("Modifier"),
28
+ updateTime: z.number().int().nullable().optional().describe("Modification time"),
29
+ version: z.string().nullable().optional().describe("Version number"),
30
+ });
31
+ export const ArtifactSchema = z.object({
32
+ downloadCount: z.number().int().nullable().optional().describe("Download count"),
33
+ gmtDownload: z.number().int().nullable().optional().describe("Latest download time"),
34
+ id: z.number().int().nullable().optional().describe("Artifact ID"),
35
+ latestUpdate: z.number().int().nullable().optional().describe("Latest update time"),
36
+ module: z.string().nullable().optional().describe("Module name"),
37
+ organization: z.string().nullable().optional().describe("Organization information"),
38
+ repositoryId: z.string().nullable().optional().describe("Repository ID"),
39
+ versions: z.array(ArtifactVersionSchema).nullable().optional().describe("Version list"),
40
+ });
41
+ export const ListArtifactsSchema = z.object({
42
+ organizationId: z.string().describe("Organization ID"),
43
+ repoId: z.string().describe("Repository ID"),
44
+ repoType: z.string().describe("Repository type, available values: GENERIC/DOCKER/MAVEN/NPM/NUGET"),
45
+ page: z.number().int().optional().default(1).describe("Current page number"),
46
+ perPage: z.number().int().optional().default(8).describe("Number of items per page, default is 10"),
47
+ search: z.string().optional().describe("Search by package name"),
48
+ orderBy: z.string().optional().default("latestUpdate").describe("Sort method: latestUpdate - by latest update time; gmtDownload - by latest download time"),
49
+ sort: z.string().optional().default("desc").describe("Sort order: asc - ascending; desc - descending"),
50
+ });
51
+ export const GetArtifactSchema = z.object({
52
+ organizationId: z.string().describe("Organization ID"),
53
+ repoId: z.string().describe("Repository ID"),
54
+ id: z.number().int().describe("Artifact ID, can be obtained from ListArtifacts API"),
55
+ repoType: z.string().describe("Repository type, available values: GENERIC/DOCKER/MAVEN/NPM/NUGET/PYPI"),
56
+ });
@@ -0,0 +1,206 @@
1
+ /**
2
+ * 项目(Project)相关操作
3
+ *
4
+ * 概念说明:
5
+ * - 项目(Project)是云效平台中的项目管理单元,包含工作项、迭代等管理概念
6
+ * - 项目与代码库(Repository)是不同的概念,代码库属于CodeUp产品,用于代码管理
7
+ * - 一个项目可以关联多个代码库,但两者是不同的资源类型
8
+ */
9
+ import { yunxiaoRequest } from "../../common/utils.js";
10
+ import { ProjectInfoSchema } from "./types.js";
11
+ /**
12
+ * 获取项目详情
13
+ * @param organizationId
14
+ * @param id
15
+ */
16
+ export async function getProjectFunc(organizationId, id) {
17
+ const url = `/oapi/v1/projex/organizations/${organizationId}/projects/${id}`;
18
+ const response = await yunxiaoRequest(url, {
19
+ method: "GET",
20
+ });
21
+ return ProjectInfoSchema.parse(response);
22
+ }
23
+ /**
24
+ * 搜索项目
25
+ * @param organizationId
26
+ * @param name
27
+ * @param status
28
+ * @param createdAfter
29
+ * @param createdBefore
30
+ * @param creator
31
+ * @param adminUserId
32
+ * @param logicalStatus
33
+ * @param advancedConditions
34
+ * @param extraConditions
35
+ * @param orderBy
36
+ * @param page
37
+ * @param perPage
38
+ * @param sort
39
+ * @param scenarioFilter
40
+ * @param userId
41
+ */
42
+ export async function searchProjectsFunc(organizationId, name, status, createdAfter, createdBefore, creator, adminUserId, // Project administrator user ID
43
+ logicalStatus, advancedConditions, extraConditions, // Should be constructed using buildExtraConditions for common filters
44
+ orderBy, // Possible values: "gmtCreate", "name"
45
+ page, perPage, sort, // Possible values: "desc", "asc"
46
+ scenarioFilter, // Common project filter scenarios
47
+ userId // User ID to use with scenarioFilter
48
+ ) {
49
+ const url = `/oapi/v1/projex/organizations/${organizationId}/projects:search`;
50
+ const payload = {};
51
+ if (scenarioFilter && userId) {
52
+ extraConditions = buildExtraConditions(scenarioFilter, userId);
53
+ }
54
+ const conditions = buildProjectConditions({
55
+ name,
56
+ status,
57
+ createdAfter,
58
+ createdBefore,
59
+ creator,
60
+ adminUserId,
61
+ logicalStatus,
62
+ advancedConditions
63
+ });
64
+ if (conditions) {
65
+ payload.conditions = conditions;
66
+ }
67
+ if (extraConditions) {
68
+ payload.extraConditions = extraConditions;
69
+ }
70
+ if (orderBy) {
71
+ payload.orderBy = orderBy;
72
+ }
73
+ if (page !== undefined) {
74
+ payload.page = page;
75
+ }
76
+ if (perPage !== undefined) {
77
+ payload.perPage = perPage;
78
+ }
79
+ if (sort) {
80
+ payload.sort = sort;
81
+ }
82
+ const response = await yunxiaoRequest(url, {
83
+ method: "POST",
84
+ body: payload,
85
+ });
86
+ if (!Array.isArray(response)) {
87
+ return [];
88
+ }
89
+ return response.map(project => ProjectInfoSchema.parse(project));
90
+ }
91
+ /**
92
+ * 构建项目过滤条件(源API所需参数conditions是一个固定的JSON结构)
93
+ * @param args
94
+ */
95
+ function buildProjectConditions(args) {
96
+ if (args.advancedConditions) {
97
+ return args.advancedConditions;
98
+ }
99
+ const filterConditions = [];
100
+ if (args.name) {
101
+ filterConditions.push({
102
+ className: "string",
103
+ fieldIdentifier: "name",
104
+ format: "input",
105
+ operator: "CONTAINS",
106
+ toValue: null,
107
+ value: [args.name],
108
+ });
109
+ }
110
+ if (args.status) {
111
+ const statusValues = args.status.split(",");
112
+ const values = statusValues.map(v => v.trim());
113
+ filterConditions.push({
114
+ className: "status",
115
+ fieldIdentifier: "status",
116
+ format: "list",
117
+ operator: "CONTAINS",
118
+ toValue: null,
119
+ value: values,
120
+ });
121
+ }
122
+ if (args.createdAfter) {
123
+ const createdBefore = args.createdBefore ? `${args.createdBefore} 23:59:59` : null;
124
+ filterConditions.push({
125
+ className: "date",
126
+ fieldIdentifier: "gmtCreate",
127
+ format: "input",
128
+ operator: "BETWEEN",
129
+ toValue: createdBefore,
130
+ value: [`${args.createdAfter} 00:00:00`],
131
+ });
132
+ }
133
+ if (args.creator) {
134
+ const creatorValues = args.creator.split(",");
135
+ const values = creatorValues.map(v => v.trim());
136
+ filterConditions.push({
137
+ className: "user",
138
+ fieldIdentifier: "creator",
139
+ format: "list",
140
+ operator: "CONTAINS",
141
+ toValue: null,
142
+ value: values,
143
+ });
144
+ }
145
+ if (args.adminUserId) {
146
+ const adminValues = args.adminUserId.split(",");
147
+ const values = adminValues.map(v => v.trim());
148
+ filterConditions.push({
149
+ className: "user",
150
+ fieldIdentifier: "project.admin",
151
+ format: "multiList",
152
+ operator: "CONTAINS",
153
+ toValue: null,
154
+ value: values,
155
+ });
156
+ }
157
+ if (args.logicalStatus) {
158
+ filterConditions.push({
159
+ className: "string",
160
+ fieldIdentifier: "logicalStatus",
161
+ format: "list",
162
+ operator: "CONTAINS",
163
+ toValue: null,
164
+ value: [args.logicalStatus],
165
+ });
166
+ }
167
+ if (filterConditions.length === 0) {
168
+ return undefined;
169
+ }
170
+ const conditions = {
171
+ conditionGroups: [filterConditions],
172
+ };
173
+ return JSON.stringify(conditions);
174
+ }
175
+ /**
176
+ * 项目额外过滤条件
177
+ * @param scenario The filter scenario: "manage" (projects I manage), "participate" (projects I participate in), "favorite" (projects I favorited)
178
+ * @param userId The user ID to filter by
179
+ * @returns JSON string for extraConditions parameter
180
+ */
181
+ export function buildExtraConditions(scenario, userId) {
182
+ let fieldIdentifier;
183
+ switch (scenario) {
184
+ case "manage":
185
+ fieldIdentifier = "project.admin";
186
+ break;
187
+ case "participate":
188
+ fieldIdentifier = "users";
189
+ break;
190
+ case "favorite":
191
+ fieldIdentifier = "collectMembers";
192
+ break;
193
+ default:
194
+ throw new Error(`Unknown scenario: ${scenario}`);
195
+ }
196
+ const conditions = {
197
+ conditionGroups: [[{
198
+ className: "user",
199
+ fieldIdentifier: fieldIdentifier,
200
+ format: "multiList",
201
+ operator: "CONTAINS",
202
+ value: [userId]
203
+ }]]
204
+ };
205
+ return JSON.stringify(conditions);
206
+ }
@@ -0,0 +1,90 @@
1
+ import { z } from "zod";
2
+ import { yunxiaoRequest, buildUrl } from "../../common/utils.js";
3
+ import { SprintInfoSchema } from "./types.js";
4
+ // Create Sprint Response Schema
5
+ const CreateSprintResponseSchema = z.object({
6
+ id: z.string().describe("Created sprint ID"),
7
+ });
8
+ export async function getSprintFunc(organizationId, projectId, id) {
9
+ const url = `/oapi/v1/projex/organizations/${organizationId}/projects/${projectId}/sprints/${id}`;
10
+ const response = await yunxiaoRequest(url, {
11
+ method: "GET",
12
+ });
13
+ return SprintInfoSchema.parse(response);
14
+ }
15
+ export async function listSprintsFunc(organizationId, id, status, page, perPage) {
16
+ const baseUrl = `/oapi/v1/projex/organizations/${organizationId}/projects/${id}/sprints`;
17
+ const queryParams = {};
18
+ if (status !== undefined && status.length > 0) {
19
+ queryParams.status = status.join(',');
20
+ }
21
+ if (page !== undefined) {
22
+ queryParams.page = page;
23
+ }
24
+ if (perPage !== undefined) {
25
+ queryParams.perPage = perPage;
26
+ }
27
+ const url = buildUrl(baseUrl, queryParams);
28
+ const response = await yunxiaoRequest(url, {
29
+ method: "GET",
30
+ });
31
+ if (!Array.isArray(response)) {
32
+ return [];
33
+ }
34
+ return response.map(sprint => SprintInfoSchema.parse(sprint));
35
+ }
36
+ export async function createSprintFunc(organizationId, projectId, name, owners, startDate, endDate, description, capacityHours, operatorId) {
37
+ const url = `/oapi/v1/projex/organizations/${organizationId}/projects/${projectId}/sprints`;
38
+ const requestBody = {
39
+ name,
40
+ owners,
41
+ };
42
+ if (startDate !== undefined) {
43
+ requestBody.startDate = startDate;
44
+ }
45
+ if (endDate !== undefined) {
46
+ requestBody.endDate = endDate;
47
+ }
48
+ if (description !== undefined) {
49
+ requestBody.description = description;
50
+ }
51
+ if (capacityHours !== undefined) {
52
+ requestBody.capacityHours = capacityHours;
53
+ }
54
+ if (operatorId !== undefined) {
55
+ requestBody.operatorId = operatorId;
56
+ }
57
+ const response = await yunxiaoRequest(url, {
58
+ method: "POST",
59
+ body: requestBody,
60
+ });
61
+ return CreateSprintResponseSchema.parse(response);
62
+ }
63
+ export async function updateSprintFunc(organizationId, projectId, id, name, owners, startDate, endDate, description, capacityHours, operatorId) {
64
+ const url = `/oapi/v1/projex/organizations/${organizationId}/projects/${projectId}/sprints/${id}`;
65
+ const requestBody = {
66
+ name,
67
+ };
68
+ if (owners !== undefined) {
69
+ requestBody.owners = owners;
70
+ }
71
+ if (startDate !== undefined) {
72
+ requestBody.startDate = startDate;
73
+ }
74
+ if (endDate !== undefined) {
75
+ requestBody.endDate = endDate;
76
+ }
77
+ if (description !== undefined) {
78
+ requestBody.description = description;
79
+ }
80
+ if (capacityHours !== undefined) {
81
+ requestBody.capacityHours = capacityHours;
82
+ }
83
+ if (operatorId !== undefined) {
84
+ requestBody.operatorId = operatorId;
85
+ }
86
+ await yunxiaoRequest(url, {
87
+ method: "PUT",
88
+ body: requestBody,
89
+ });
90
+ }