devops-mcp-server-extension 1.0.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 (102) hide show
  1. package/LICENSE +218 -0
  2. package/README.md +527 -0
  3. package/README.zh-cn.md +503 -0
  4. package/dist/common/errors.js +77 -0
  5. package/dist/common/modularTemplates.js +483 -0
  6. package/dist/common/pipelineTemplates.js +19 -0
  7. package/dist/common/toolsetManager.js +123 -0
  8. package/dist/common/toolsets.js +23 -0
  9. package/dist/common/types.js +60 -0
  10. package/dist/common/utils.js +381 -0
  11. package/dist/common/version.js +1 -0
  12. package/dist/index.js +225 -0
  13. package/dist/operations/appstack/appOrchestrations.js +260 -0
  14. package/dist/operations/appstack/appTags.js +168 -0
  15. package/dist/operations/appstack/appTemplates.js +72 -0
  16. package/dist/operations/appstack/applications.js +171 -0
  17. package/dist/operations/appstack/changeOrders.js +320 -0
  18. package/dist/operations/appstack/changeRequests.js +288 -0
  19. package/dist/operations/appstack/deploymentResources.js +286 -0
  20. package/dist/operations/appstack/globalVars.js +221 -0
  21. package/dist/operations/appstack/releaseWorkflows.js +695 -0
  22. package/dist/operations/appstack/variableGroups.js +245 -0
  23. package/dist/operations/codeup/branches.js +157 -0
  24. package/dist/operations/codeup/changeRequestComments.js +140 -0
  25. package/dist/operations/codeup/changeRequests.js +230 -0
  26. package/dist/operations/codeup/commits.js +121 -0
  27. package/dist/operations/codeup/compare.js +30 -0
  28. package/dist/operations/codeup/files.js +249 -0
  29. package/dist/operations/codeup/repositories.js +71 -0
  30. package/dist/operations/codeup/types.js +414 -0
  31. package/dist/operations/flow/hostGroup.js +52 -0
  32. package/dist/operations/flow/pipeline.js +609 -0
  33. package/dist/operations/flow/pipelineJob.js +126 -0
  34. package/dist/operations/flow/resourceMember.js +137 -0
  35. package/dist/operations/flow/serviceConnection.js +27 -0
  36. package/dist/operations/flow/tag.js +191 -0
  37. package/dist/operations/flow/types.js +523 -0
  38. package/dist/operations/flow/vmDeployOrder.js +171 -0
  39. package/dist/operations/organization/members.js +106 -0
  40. package/dist/operations/organization/organization.js +110 -0
  41. package/dist/operations/organization/types.js +111 -0
  42. package/dist/operations/packages/artifacts.js +71 -0
  43. package/dist/operations/packages/repositories.js +39 -0
  44. package/dist/operations/packages/types.js +56 -0
  45. package/dist/operations/projex/effort.js +122 -0
  46. package/dist/operations/projex/project.js +243 -0
  47. package/dist/operations/projex/sprint.js +103 -0
  48. package/dist/operations/projex/types.js +618 -0
  49. package/dist/operations/projex/workitem.js +826 -0
  50. package/dist/operations/testhub/testcases.js +240 -0
  51. package/dist/operations/testhub/testplans.js +128 -0
  52. package/dist/tool-handlers/appstack-app-release-workflows.js +103 -0
  53. package/dist/tool-handlers/appstack-change-orders.js +55 -0
  54. package/dist/tool-handlers/appstack-change-requests.js +49 -0
  55. package/dist/tool-handlers/appstack-deployment-resources.js +31 -0
  56. package/dist/tool-handlers/appstack-global-vars.js +37 -0
  57. package/dist/tool-handlers/appstack-orchestrations.js +49 -0
  58. package/dist/tool-handlers/appstack-release-workflows.js +37 -0
  59. package/dist/tool-handlers/appstack-tags.js +37 -0
  60. package/dist/tool-handlers/appstack-templates.js +19 -0
  61. package/dist/tool-handlers/appstack-variable-groups.js +55 -0
  62. package/dist/tool-handlers/appstack.js +37 -0
  63. package/dist/tool-handlers/base.js +25 -0
  64. package/dist/tool-handlers/code-management.js +150 -0
  65. package/dist/tool-handlers/commit.js +31 -0
  66. package/dist/tool-handlers/effort.js +103 -0
  67. package/dist/tool-handlers/index.js +119 -0
  68. package/dist/tool-handlers/organization.js +72 -0
  69. package/dist/tool-handlers/packages.js +32 -0
  70. package/dist/tool-handlers/pipeline.js +289 -0
  71. package/dist/tool-handlers/project-management.js +201 -0
  72. package/dist/tool-handlers/resourceMember.js +43 -0
  73. package/dist/tool-handlers/service-connections.js +16 -0
  74. package/dist/tool-handlers/tag.js +64 -0
  75. package/dist/tool-handlers/test-management.js +74 -0
  76. package/dist/tool-handlers/vmDeployOrder.js +50 -0
  77. package/dist/tool-registry/appstack-app-release-workflows.js +80 -0
  78. package/dist/tool-registry/appstack-change-orders.js +40 -0
  79. package/dist/tool-registry/appstack-change-requests.js +35 -0
  80. package/dist/tool-registry/appstack-deployment-resources.js +20 -0
  81. package/dist/tool-registry/appstack-global-vars.js +25 -0
  82. package/dist/tool-registry/appstack-orchestrations.js +35 -0
  83. package/dist/tool-registry/appstack-release-workflows.js +25 -0
  84. package/dist/tool-registry/appstack-tags.js +25 -0
  85. package/dist/tool-registry/appstack-templates.js +10 -0
  86. package/dist/tool-registry/appstack-variable-groups.js +40 -0
  87. package/dist/tool-registry/appstack.js +25 -0
  88. package/dist/tool-registry/base.js +19 -0
  89. package/dist/tool-registry/code-management.js +109 -0
  90. package/dist/tool-registry/commit.js +20 -0
  91. package/dist/tool-registry/effort.js +39 -0
  92. package/dist/tool-registry/index.js +7 -0
  93. package/dist/tool-registry/organization.js +65 -0
  94. package/dist/tool-registry/packages.js +21 -0
  95. package/dist/tool-registry/pipeline.js +190 -0
  96. package/dist/tool-registry/project-management.js +143 -0
  97. package/dist/tool-registry/resourceMember.js +29 -0
  98. package/dist/tool-registry/service-connections.js +10 -0
  99. package/dist/tool-registry/tag.js +44 -0
  100. package/dist/tool-registry/test-management.js +59 -0
  101. package/dist/tool-registry/vmDeployOrder.js +34 -0
  102. package/package.json +52 -0
@@ -0,0 +1,122 @@
1
+ import { z } from "zod";
2
+ import { yunxiaoRequest, isRegionEdition } from "../../common/utils.js";
3
+ import { resolveOrganizationId } from "../organization/organization.js";
4
+ import { EffortRecordSchema, EstimatedEffortSchema, IdentifierDTOSchema, ListCurrentUserEffortRecordsSchema, ListEffortRecordsSchema, CreateEffortRecordRequestSchema, ListEstimatedEffortsSchema, CreateEstimatedEffortRequestSchema } from "./types.js";
5
+ // List current user effort records
6
+ export async function listCurrentUserEffortRecords(params) {
7
+ const validatedParams = ListCurrentUserEffortRecordsSchema.parse(params);
8
+ const finalOrgId = await resolveOrganizationId(validatedParams.organizationId);
9
+ const url = isRegionEdition()
10
+ ? `/oapi/v1/projex/effortRecords`
11
+ : `/oapi/v1/projex/organizations/${finalOrgId}/effortRecords`;
12
+ const queryParams = {
13
+ startDate: validatedParams.startDate,
14
+ endDate: validatedParams.endDate
15
+ };
16
+ const response = await yunxiaoRequest(`${url}?startDate=${queryParams.startDate}&endDate=${queryParams.endDate}`, {
17
+ method: "GET"
18
+ });
19
+ return z.array(EffortRecordSchema).parse(response);
20
+ }
21
+ // List effort records
22
+ export async function listEffortRecords(params) {
23
+ const validatedParams = ListEffortRecordsSchema.parse(params);
24
+ const finalOrgId = await resolveOrganizationId(validatedParams.organizationId);
25
+ const url = isRegionEdition()
26
+ ? `/oapi/v1/projex/workitems/${validatedParams.id}/effortRecords`
27
+ : `/oapi/v1/projex/organizations/${finalOrgId}/workitems/${validatedParams.id}/effortRecords`;
28
+ const response = await yunxiaoRequest(url, {
29
+ method: "GET"
30
+ });
31
+ return z.array(EffortRecordSchema).parse(response);
32
+ }
33
+ // Create effort record
34
+ export async function createEffortRecord(params) {
35
+ const validatedParams = CreateEffortRecordRequestSchema.parse({
36
+ actualTime: params.actualTime,
37
+ description: params.description,
38
+ gmtEnd: params.gmtEnd,
39
+ gmtStart: params.gmtStart,
40
+ operatorId: params.operatorId,
41
+ workType: params.workType
42
+ });
43
+ const finalOrgId = await resolveOrganizationId(params.organizationId);
44
+ const url = isRegionEdition()
45
+ ? `/oapi/v1/projex/workitems/${params.id}/effortRecords`
46
+ : `/oapi/v1/projex/organizations/${finalOrgId}/workitems/${params.id}/effortRecords`;
47
+ const response = await yunxiaoRequest(url, {
48
+ method: "POST",
49
+ body: validatedParams
50
+ });
51
+ return IdentifierDTOSchema.parse(response);
52
+ }
53
+ // List estimated efforts
54
+ export async function listEstimatedEfforts(params) {
55
+ const validatedParams = ListEstimatedEffortsSchema.parse(params);
56
+ const finalOrgId = await resolveOrganizationId(validatedParams.organizationId);
57
+ const url = isRegionEdition()
58
+ ? `/oapi/v1/projex/workitems/${validatedParams.id}/estimatedEfforts`
59
+ : `/oapi/v1/projex/organizations/${finalOrgId}/workitems/${validatedParams.id}/estimatedEfforts`;
60
+ const response = await yunxiaoRequest(url, {
61
+ method: "GET"
62
+ });
63
+ return z.array(EstimatedEffortSchema).parse(response);
64
+ }
65
+ // Create estimated effort
66
+ export async function createEstimatedEffort(params) {
67
+ const validatedParams = CreateEstimatedEffortRequestSchema.parse({
68
+ description: params.description,
69
+ operatorId: params.operatorId,
70
+ owner: params.owner,
71
+ spentTime: params.spentTime,
72
+ workType: params.workType
73
+ });
74
+ const finalOrgId = await resolveOrganizationId(params.organizationId);
75
+ const url = isRegionEdition()
76
+ ? `/oapi/v1/projex/workitems/${params.id}/estimatedEfforts`
77
+ : `/oapi/v1/projex/organizations/${finalOrgId}/workitems/${params.id}/estimatedEfforts`;
78
+ const response = await yunxiaoRequest(url, {
79
+ method: "POST",
80
+ body: validatedParams
81
+ });
82
+ return IdentifierDTOSchema.parse(response);
83
+ }
84
+ // Update effort record
85
+ export async function updateEffortRecord(params) {
86
+ const validatedParams = CreateEffortRecordRequestSchema.parse({
87
+ actualTime: params.actualTime,
88
+ description: params.description,
89
+ gmtEnd: params.gmtEnd,
90
+ gmtStart: params.gmtStart,
91
+ operatorId: params.operatorId,
92
+ workType: params.workType
93
+ });
94
+ const finalOrgId = await resolveOrganizationId(params.organizationId);
95
+ const url = isRegionEdition()
96
+ ? `/oapi/v1/projex/workitems/${params.workitemId}/effortRecords/${params.id}`
97
+ : `/oapi/v1/projex/organizations/${finalOrgId}/workitems/${params.workitemId}/effortRecords/${params.id}`;
98
+ const response = await yunxiaoRequest(url, {
99
+ method: "PUT",
100
+ body: validatedParams
101
+ });
102
+ return response;
103
+ }
104
+ // Update estimated effort
105
+ export async function updateEstimatedEffort(params) {
106
+ const validatedParams = CreateEstimatedEffortRequestSchema.parse({
107
+ description: params.description,
108
+ operatorId: params.operatorId,
109
+ owner: params.owner,
110
+ spentTime: params.spentTime,
111
+ workType: params.workType
112
+ });
113
+ const finalOrgId = await resolveOrganizationId(params.organizationId);
114
+ const url = isRegionEdition()
115
+ ? `/oapi/v1/projex/workitems/${params.workitemId}/estimatedEfforts/${params.id}`
116
+ : `/oapi/v1/projex/organizations/${finalOrgId}/workitems/${params.workitemId}/estimatedEfforts/${params.id}`;
117
+ const response = await yunxiaoRequest(url, {
118
+ method: "PUT",
119
+ body: validatedParams
120
+ });
121
+ return response;
122
+ }
@@ -0,0 +1,243 @@
1
+ /**
2
+ * 项目(Project)相关操作
3
+ *
4
+ * 概念说明:
5
+ * - 项目(Project)是云效平台中的项目管理单元,包含工作项、迭代等管理概念
6
+ * - 项目与代码库(Repository)是不同的概念,代码库属于CodeUp产品,用于代码管理
7
+ * - 一个项目可以关联多个代码库,但两者是不同的资源类型
8
+ */
9
+ import { yunxiaoRequest, isRegionEdition } from "../../common/utils.js";
10
+ import { resolveOrganizationId } from "../organization/organization.js";
11
+ import { ProjectInfoSchema, ProjectMemberSchema } from "./types.js";
12
+ /**
13
+ * 获取项目详情
14
+ * @param organizationId
15
+ * @param id
16
+ */
17
+ export async function getProjectFunc(organizationId, id) {
18
+ const finalOrgId = await resolveOrganizationId(organizationId);
19
+ const url = isRegionEdition()
20
+ ? `/oapi/v1/projex/projects/${id}`
21
+ : `/oapi/v1/projex/organizations/${finalOrgId}/projects/${id}`;
22
+ const response = await yunxiaoRequest(url, {
23
+ method: "GET",
24
+ });
25
+ return ProjectInfoSchema.parse(response);
26
+ }
27
+ /**
28
+ * 搜索项目
29
+ * @param organizationId
30
+ * @param name
31
+ * @param status
32
+ * @param createdAfter
33
+ * @param createdBefore
34
+ * @param creator
35
+ * @param adminUserId
36
+ * @param logicalStatus
37
+ * @param advancedConditions
38
+ * @param extraConditions
39
+ * @param orderBy
40
+ * @param page
41
+ * @param perPage
42
+ * @param sort
43
+ * @param scenarioFilter
44
+ * @param userId
45
+ */
46
+ export async function searchProjectsFunc(organizationId, name, status, createdAfter, createdBefore, creator, adminUserId, // Project administrator user ID
47
+ logicalStatus, advancedConditions, extraConditions, // Should be constructed using buildExtraConditions for common filters
48
+ orderBy, // Possible values: "gmtCreate", "name"
49
+ page, perPage, sort, // Possible values: "desc", "asc"
50
+ scenarioFilter, // Common project filter scenarios
51
+ userId // User ID to use with scenarioFilter
52
+ ) {
53
+ const finalOrgId = await resolveOrganizationId(organizationId);
54
+ const url = isRegionEdition()
55
+ ? `/oapi/v1/projex/projects:search`
56
+ : `/oapi/v1/projex/organizations/${finalOrgId}/projects:search`;
57
+ const payload = {};
58
+ if (scenarioFilter && userId) {
59
+ extraConditions = buildExtraConditions(scenarioFilter, userId);
60
+ }
61
+ const conditions = buildProjectConditions({
62
+ name,
63
+ status,
64
+ createdAfter,
65
+ createdBefore,
66
+ creator,
67
+ adminUserId,
68
+ logicalStatus,
69
+ advancedConditions
70
+ });
71
+ if (conditions) {
72
+ payload.conditions = conditions;
73
+ }
74
+ if (extraConditions) {
75
+ payload.extraConditions = extraConditions;
76
+ }
77
+ if (orderBy) {
78
+ payload.orderBy = orderBy;
79
+ }
80
+ if (page !== undefined) {
81
+ payload.page = page;
82
+ }
83
+ if (perPage !== undefined) {
84
+ payload.perPage = perPage;
85
+ }
86
+ if (sort) {
87
+ payload.sort = sort;
88
+ }
89
+ const response = await yunxiaoRequest(url, {
90
+ method: "POST",
91
+ body: payload,
92
+ });
93
+ if (!Array.isArray(response)) {
94
+ return [];
95
+ }
96
+ return response.map(project => ProjectInfoSchema.parse(project));
97
+ }
98
+ /**
99
+ * 构建项目过滤条件(源API所需参数conditions是一个固定的JSON结构)
100
+ * @param args
101
+ */
102
+ function buildProjectConditions(args) {
103
+ if (args.advancedConditions) {
104
+ return args.advancedConditions;
105
+ }
106
+ const filterConditions = [];
107
+ if (args.name) {
108
+ filterConditions.push({
109
+ className: "string",
110
+ fieldIdentifier: "name",
111
+ format: "input",
112
+ operator: "CONTAINS",
113
+ toValue: null,
114
+ value: [args.name],
115
+ });
116
+ }
117
+ if (args.status) {
118
+ const statusValues = args.status.split(",");
119
+ const values = statusValues.map(v => v.trim());
120
+ filterConditions.push({
121
+ className: "status",
122
+ fieldIdentifier: "status",
123
+ format: "list",
124
+ operator: "CONTAINS",
125
+ toValue: null,
126
+ value: values,
127
+ });
128
+ }
129
+ if (args.createdAfter) {
130
+ const createdBefore = args.createdBefore ? `${args.createdBefore} 23:59:59` : null;
131
+ filterConditions.push({
132
+ className: "date",
133
+ fieldIdentifier: "gmtCreate",
134
+ format: "input",
135
+ operator: "BETWEEN",
136
+ toValue: createdBefore,
137
+ value: [`${args.createdAfter} 00:00:00`],
138
+ });
139
+ }
140
+ if (args.creator) {
141
+ const creatorValues = args.creator.split(",");
142
+ const values = creatorValues.map(v => v.trim());
143
+ filterConditions.push({
144
+ className: "user",
145
+ fieldIdentifier: "creator",
146
+ format: "list",
147
+ operator: "CONTAINS",
148
+ toValue: null,
149
+ value: values,
150
+ });
151
+ }
152
+ if (args.adminUserId) {
153
+ const adminValues = args.adminUserId.split(",");
154
+ const values = adminValues.map(v => v.trim());
155
+ filterConditions.push({
156
+ className: "user",
157
+ fieldIdentifier: "project.admin",
158
+ format: "multiList",
159
+ operator: "CONTAINS",
160
+ toValue: null,
161
+ value: values,
162
+ });
163
+ }
164
+ if (args.logicalStatus) {
165
+ filterConditions.push({
166
+ className: "string",
167
+ fieldIdentifier: "logicalStatus",
168
+ format: "list",
169
+ operator: "CONTAINS",
170
+ toValue: null,
171
+ value: [args.logicalStatus],
172
+ });
173
+ }
174
+ if (filterConditions.length === 0) {
175
+ return undefined;
176
+ }
177
+ const conditions = {
178
+ conditionGroups: [filterConditions],
179
+ };
180
+ return JSON.stringify(conditions);
181
+ }
182
+ /**
183
+ * 获取项目成员列表
184
+ * @param organizationId 组织ID
185
+ * @param id 项目唯一标识
186
+ * @param name 名称过滤
187
+ * @param roleId 角色ID过滤,如 project.admin 表示管理员
188
+ */
189
+ export async function listProjectMembersFunc(organizationId, id, name, roleId) {
190
+ const finalOrgId = await resolveOrganizationId(organizationId);
191
+ const url = isRegionEdition()
192
+ ? `/oapi/v1/projex/projects/${id}/members`
193
+ : `/oapi/v1/projex/organizations/${finalOrgId}/projects/${id}/members`;
194
+ const params = {};
195
+ if (name) {
196
+ params.name = name;
197
+ }
198
+ if (roleId) {
199
+ params.roleId = roleId;
200
+ }
201
+ const queryString = Object.keys(params).length > 0
202
+ ? '?' + Object.entries(params).map(([k, v]) => `${k}=${encodeURIComponent(v)}`).join('&')
203
+ : '';
204
+ const response = await yunxiaoRequest(url + queryString, {
205
+ method: "GET",
206
+ });
207
+ if (!Array.isArray(response)) {
208
+ return [];
209
+ }
210
+ return response.map(member => ProjectMemberSchema.parse(member));
211
+ }
212
+ /**
213
+ * 项目额外过滤条件
214
+ * @param scenario The filter scenario: "manage" (projects I manage), "participate" (projects I participate in), "favorite" (projects I favorited)
215
+ * @param userId The user ID to filter by
216
+ * @returns JSON string for extraConditions parameter
217
+ */
218
+ export function buildExtraConditions(scenario, userId) {
219
+ let fieldIdentifier;
220
+ switch (scenario) {
221
+ case "manage":
222
+ fieldIdentifier = "project.admin";
223
+ break;
224
+ case "participate":
225
+ fieldIdentifier = "users";
226
+ break;
227
+ case "favorite":
228
+ fieldIdentifier = "collectMembers";
229
+ break;
230
+ default:
231
+ throw new Error(`Unknown scenario: ${scenario}`);
232
+ }
233
+ const conditions = {
234
+ conditionGroups: [[{
235
+ className: "user",
236
+ fieldIdentifier: fieldIdentifier,
237
+ format: "multiList",
238
+ operator: "CONTAINS",
239
+ value: [userId]
240
+ }]]
241
+ };
242
+ return JSON.stringify(conditions);
243
+ }
@@ -0,0 +1,103 @@
1
+ import { z } from "zod";
2
+ import { yunxiaoRequest, buildUrl, isRegionEdition } from "../../common/utils.js";
3
+ import { resolveOrganizationId } from "../organization/organization.js";
4
+ import { SprintInfoSchema } from "./types.js";
5
+ // Create Sprint Response Schema
6
+ const CreateSprintResponseSchema = z.object({
7
+ id: z.string().describe("Created sprint ID"),
8
+ });
9
+ export async function getSprintFunc(organizationId, projectId, id) {
10
+ const finalOrgId = await resolveOrganizationId(organizationId);
11
+ const url = isRegionEdition()
12
+ ? `/oapi/v1/projex/projects/${projectId}/sprints/${id}`
13
+ : `/oapi/v1/projex/organizations/${finalOrgId}/projects/${projectId}/sprints/${id}`;
14
+ const response = await yunxiaoRequest(url, {
15
+ method: "GET",
16
+ });
17
+ return SprintInfoSchema.parse(response);
18
+ }
19
+ export async function listSprintsFunc(organizationId, id, status, page, perPage) {
20
+ const finalOrgId = await resolveOrganizationId(organizationId);
21
+ const baseUrl = isRegionEdition()
22
+ ? `/oapi/v1/projex/projects/${id}/sprints`
23
+ : `/oapi/v1/projex/organizations/${finalOrgId}/projects/${id}/sprints`;
24
+ const queryParams = {};
25
+ if (status !== undefined && status.length > 0) {
26
+ queryParams.status = status.join(',');
27
+ }
28
+ if (page !== undefined) {
29
+ queryParams.page = page;
30
+ }
31
+ if (perPage !== undefined) {
32
+ queryParams.perPage = perPage;
33
+ }
34
+ const url = buildUrl(baseUrl, queryParams);
35
+ const response = await yunxiaoRequest(url, {
36
+ method: "GET",
37
+ });
38
+ if (!Array.isArray(response)) {
39
+ return [];
40
+ }
41
+ return response.map(sprint => SprintInfoSchema.parse(sprint));
42
+ }
43
+ export async function createSprintFunc(organizationId, projectId, name, owners, startDate, endDate, description, capacityHours, operatorId) {
44
+ const finalOrgId = await resolveOrganizationId(organizationId);
45
+ const url = isRegionEdition()
46
+ ? `/oapi/v1/projex/projects/${projectId}/sprints`
47
+ : `/oapi/v1/projex/organizations/${finalOrgId}/projects/${projectId}/sprints`;
48
+ const requestBody = {
49
+ name,
50
+ owners,
51
+ };
52
+ if (startDate !== undefined) {
53
+ requestBody.startDate = startDate;
54
+ }
55
+ if (endDate !== undefined) {
56
+ requestBody.endDate = endDate;
57
+ }
58
+ if (description !== undefined) {
59
+ requestBody.description = description;
60
+ }
61
+ if (capacityHours !== undefined) {
62
+ requestBody.capacityHours = capacityHours;
63
+ }
64
+ if (operatorId !== undefined) {
65
+ requestBody.operatorId = operatorId;
66
+ }
67
+ const response = await yunxiaoRequest(url, {
68
+ method: "POST",
69
+ body: requestBody,
70
+ });
71
+ return CreateSprintResponseSchema.parse(response);
72
+ }
73
+ export async function updateSprintFunc(organizationId, projectId, id, name, owners, startDate, endDate, description, capacityHours, operatorId) {
74
+ const finalOrgId = await resolveOrganizationId(organizationId);
75
+ const url = isRegionEdition()
76
+ ? `/oapi/v1/projex/projects/${projectId}/sprints/${id}`
77
+ : `/oapi/v1/projex/organizations/${finalOrgId}/projects/${projectId}/sprints/${id}`;
78
+ const requestBody = {
79
+ name,
80
+ };
81
+ if (owners !== undefined) {
82
+ requestBody.owners = owners;
83
+ }
84
+ if (startDate !== undefined) {
85
+ requestBody.startDate = startDate;
86
+ }
87
+ if (endDate !== undefined) {
88
+ requestBody.endDate = endDate;
89
+ }
90
+ if (description !== undefined) {
91
+ requestBody.description = description;
92
+ }
93
+ if (capacityHours !== undefined) {
94
+ requestBody.capacityHours = capacityHours;
95
+ }
96
+ if (operatorId !== undefined) {
97
+ requestBody.operatorId = operatorId;
98
+ }
99
+ await yunxiaoRequest(url, {
100
+ method: "PUT",
101
+ body: requestBody,
102
+ });
103
+ }