@coderpp/yunxiao-cli 0.1.7 → 0.1.9
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.
- package/README.md +258 -3
- package/dist/src/cli.js +531 -70
- package/dist/src/client.d.ts +109 -2
- package/dist/src/client.js +280 -0
- package/package.json +7 -2
package/dist/src/client.d.ts
CHANGED
|
@@ -42,6 +42,85 @@ export interface ListRepositoriesOptions {
|
|
|
42
42
|
search?: string;
|
|
43
43
|
archived?: boolean;
|
|
44
44
|
}
|
|
45
|
+
export interface SearchProjectsOptions {
|
|
46
|
+
conditions?: string;
|
|
47
|
+
extraConditions?: string;
|
|
48
|
+
orderBy?: "gmtCreate" | "name" | string;
|
|
49
|
+
page?: number;
|
|
50
|
+
perPage?: number;
|
|
51
|
+
sort?: "asc" | "desc" | string;
|
|
52
|
+
}
|
|
53
|
+
export interface ListProjectMembersOptions {
|
|
54
|
+
name?: string;
|
|
55
|
+
roleId?: string;
|
|
56
|
+
}
|
|
57
|
+
export interface ChangeProjectMemberOptions {
|
|
58
|
+
operatorId?: string;
|
|
59
|
+
roleId: string;
|
|
60
|
+
userIds: string[];
|
|
61
|
+
}
|
|
62
|
+
export interface DeleteProjectMemberOptions {
|
|
63
|
+
operatorId?: string;
|
|
64
|
+
roleId: string;
|
|
65
|
+
userIds: string[];
|
|
66
|
+
}
|
|
67
|
+
export interface ListMembersOptions {
|
|
68
|
+
page?: number;
|
|
69
|
+
perPage?: number;
|
|
70
|
+
}
|
|
71
|
+
export interface SearchWorkitemsOptions {
|
|
72
|
+
category: string;
|
|
73
|
+
conditions?: string;
|
|
74
|
+
orderBy?: "gmtCreate" | "gmtModified" | "updateStatusAt" | "name" | string;
|
|
75
|
+
page?: number;
|
|
76
|
+
perPage?: number;
|
|
77
|
+
sort?: "asc" | "desc" | string;
|
|
78
|
+
spaceId: string;
|
|
79
|
+
spaceType?: "Project" | "Program" | string;
|
|
80
|
+
}
|
|
81
|
+
export interface CreateWorkitemCommentOptions {
|
|
82
|
+
content: string;
|
|
83
|
+
operatorId?: string;
|
|
84
|
+
parentId?: string;
|
|
85
|
+
}
|
|
86
|
+
export type UpdateWorkitemOptions = Record<string, unknown>;
|
|
87
|
+
export interface ListPipelineRunsOptions {
|
|
88
|
+
page?: number;
|
|
89
|
+
perPage?: number;
|
|
90
|
+
startTime?: number;
|
|
91
|
+
endTime?: number;
|
|
92
|
+
status?: "FAIL" | "SUCCESS" | "RUNNING" | string;
|
|
93
|
+
triggerMode?: number;
|
|
94
|
+
}
|
|
95
|
+
export interface ListPipelinesOptions {
|
|
96
|
+
createStartTime?: number;
|
|
97
|
+
createEndTime?: number;
|
|
98
|
+
executeStartTime?: number;
|
|
99
|
+
executeEndTime?: number;
|
|
100
|
+
pipelineName?: string;
|
|
101
|
+
statusList?: string;
|
|
102
|
+
page?: number;
|
|
103
|
+
perPage?: number;
|
|
104
|
+
}
|
|
105
|
+
export interface ListLatestFailedPipelineRunsOptions {
|
|
106
|
+
hours?: number;
|
|
107
|
+
startTime?: number;
|
|
108
|
+
endTime?: number;
|
|
109
|
+
perPage?: number;
|
|
110
|
+
}
|
|
111
|
+
export interface LatestFailedPipelineRun {
|
|
112
|
+
pipelineId: number | string;
|
|
113
|
+
pipelineName: string;
|
|
114
|
+
pipelineRunId: number | string;
|
|
115
|
+
status?: string;
|
|
116
|
+
triggerMode?: number | string;
|
|
117
|
+
triggerModeName: string;
|
|
118
|
+
startTime?: number | string;
|
|
119
|
+
startTimeText: string;
|
|
120
|
+
endTime?: number | string;
|
|
121
|
+
endTimeText: string;
|
|
122
|
+
creatorAccountId?: string;
|
|
123
|
+
}
|
|
45
124
|
export interface RepositorySummary {
|
|
46
125
|
id: number | string;
|
|
47
126
|
name?: string;
|
|
@@ -71,6 +150,7 @@ export interface ReleaseByRepositoryNameOptions {
|
|
|
71
150
|
repositoryName: string;
|
|
72
151
|
sourceBranch: string;
|
|
73
152
|
targetBranch: string;
|
|
153
|
+
createOnly?: boolean;
|
|
74
154
|
title?: string;
|
|
75
155
|
description?: string;
|
|
76
156
|
mergeType?: MergeChangeRequestOptions["mergeType"];
|
|
@@ -78,8 +158,8 @@ export interface ReleaseByRepositoryNameOptions {
|
|
|
78
158
|
export interface ReleaseResult {
|
|
79
159
|
repository: RepositorySummary;
|
|
80
160
|
changeRequest: unknown;
|
|
81
|
-
review: unknown;
|
|
82
|
-
merge: unknown;
|
|
161
|
+
review: unknown | null;
|
|
162
|
+
merge: unknown | null;
|
|
83
163
|
}
|
|
84
164
|
export interface ApproveAndMergeOptions extends ReviewChangeRequestOptions, MergeChangeRequestOptions {
|
|
85
165
|
}
|
|
@@ -100,6 +180,25 @@ export declare class YunxiaoClient {
|
|
|
100
180
|
listChangeRequests(options?: ListChangeRequestsOptions): Promise<unknown>;
|
|
101
181
|
getCurrentUser(): Promise<CurrentUser>;
|
|
102
182
|
listRepositories(options?: ListRepositoriesOptions): Promise<RepositorySummary[]>;
|
|
183
|
+
searchProjects(options?: SearchProjectsOptions): Promise<unknown>;
|
|
184
|
+
getProject(projectId: string): Promise<unknown>;
|
|
185
|
+
listProjectMembers(projectId: string, options?: ListProjectMembersOptions): Promise<unknown>;
|
|
186
|
+
createProjectMember(projectId: string, options: ChangeProjectMemberOptions): Promise<unknown>;
|
|
187
|
+
deleteProjectMember(projectId: string, options: DeleteProjectMemberOptions): Promise<unknown>;
|
|
188
|
+
listMembers(options?: ListMembersOptions): Promise<unknown>;
|
|
189
|
+
getMember(memberId: string): Promise<unknown>;
|
|
190
|
+
searchWorkitems(options: SearchWorkitemsOptions): Promise<unknown>;
|
|
191
|
+
getWorkitem(workitemId: string): Promise<unknown>;
|
|
192
|
+
updateWorkitem(workitemId: string, options: UpdateWorkitemOptions): Promise<unknown>;
|
|
193
|
+
listWorkitemActivities(workitemId: string): Promise<unknown>;
|
|
194
|
+
listWorkitemComments(workitemId: string): Promise<unknown>;
|
|
195
|
+
createWorkitemComment(workitemId: string, options: CreateWorkitemCommentOptions): Promise<unknown>;
|
|
196
|
+
getWorkitemTimeline(workitemId: string): Promise<unknown>;
|
|
197
|
+
listPipelineRuns(pipelineId: string, options?: ListPipelineRunsOptions): Promise<unknown>;
|
|
198
|
+
listPipelines(options?: ListPipelinesOptions): Promise<unknown>;
|
|
199
|
+
listLatestFailedPipelineRuns(options?: ListLatestFailedPipelineRunsOptions): Promise<LatestFailedPipelineRun[]>;
|
|
200
|
+
getPipelineRun(pipelineId: string, pipelineRunId: string): Promise<unknown>;
|
|
201
|
+
retryPipelineJobRun(pipelineId: string, pipelineRunId: string, jobId: string): Promise<unknown>;
|
|
103
202
|
createChangeRequest(repositoryId: string, options: CreateChangeRequestOptions): Promise<unknown>;
|
|
104
203
|
reviewChangeRequest(repositoryId: string, localId: number, options?: ReviewChangeRequestOptions): Promise<unknown>;
|
|
105
204
|
mergeChangeRequest(repositoryId: string, localId: number, options?: MergeChangeRequestOptions): Promise<unknown>;
|
|
@@ -111,5 +210,13 @@ export declare class YunxiaoClient {
|
|
|
111
210
|
private repositoriesPath;
|
|
112
211
|
private repositoryPath;
|
|
113
212
|
private repositoryChangeRequestPath;
|
|
213
|
+
private projexPath;
|
|
214
|
+
private workitemsSearchPath;
|
|
215
|
+
private projectPath;
|
|
216
|
+
private platformMembersPath;
|
|
217
|
+
private pipelinesPath;
|
|
218
|
+
private pipelinePath;
|
|
219
|
+
private listAllPipelines;
|
|
220
|
+
private listAllPipelineRuns;
|
|
114
221
|
private request;
|
|
115
222
|
}
|
package/dist/src/client.js
CHANGED
|
@@ -40,6 +40,150 @@ export class YunxiaoClient {
|
|
|
40
40
|
listRepositories(options = {}) {
|
|
41
41
|
return this.request("GET", this.repositoriesPath(), options);
|
|
42
42
|
}
|
|
43
|
+
searchProjects(options = {}) {
|
|
44
|
+
return this.request("POST", this.projexPath("/projects:search"), undefined, options);
|
|
45
|
+
}
|
|
46
|
+
getProject(projectId) {
|
|
47
|
+
return this.request("GET", this.projectPath(projectId));
|
|
48
|
+
}
|
|
49
|
+
listProjectMembers(projectId, options = {}) {
|
|
50
|
+
return this.request("GET", `${this.projectPath(projectId)}/members`, options);
|
|
51
|
+
}
|
|
52
|
+
createProjectMember(projectId, options) {
|
|
53
|
+
return this.request("POST", `${this.projectPath(projectId)}/members`, undefined, {
|
|
54
|
+
operatorId: options.operatorId,
|
|
55
|
+
roleId: options.roleId,
|
|
56
|
+
userIds: options.userIds
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
deleteProjectMember(projectId, options) {
|
|
60
|
+
return this.request("DELETE", `${this.projectPath(projectId)}/members`, undefined, {
|
|
61
|
+
operatorId: options.operatorId,
|
|
62
|
+
roleIds: [options.roleId],
|
|
63
|
+
userId: options.userIds.length === 1 ? options.userIds[0] : undefined,
|
|
64
|
+
userIds: options.userIds.length > 1 ? options.userIds : undefined
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
listMembers(options = {}) {
|
|
68
|
+
return this.request("GET", this.platformMembersPath(), options);
|
|
69
|
+
}
|
|
70
|
+
getMember(memberId) {
|
|
71
|
+
return this.request("GET", `${this.platformMembersPath()}/${encodePathSegment(memberId)}`);
|
|
72
|
+
}
|
|
73
|
+
searchWorkitems(options) {
|
|
74
|
+
return this.request("POST", this.workitemsSearchPath(), undefined, {
|
|
75
|
+
category: options.category,
|
|
76
|
+
conditions: options.conditions,
|
|
77
|
+
orderBy: options.orderBy,
|
|
78
|
+
page: options.page,
|
|
79
|
+
perPage: options.perPage,
|
|
80
|
+
sort: options.sort,
|
|
81
|
+
spaceId: options.spaceId,
|
|
82
|
+
spaceType: options.spaceType ?? "Project"
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
getWorkitem(workitemId) {
|
|
86
|
+
return this.request("GET", `${this.projexPath("/workitems")}/${encodePathSegment(workitemId)}`);
|
|
87
|
+
}
|
|
88
|
+
updateWorkitem(workitemId, options) {
|
|
89
|
+
return this.request("PUT", `${this.projexPath("/workitems")}/${encodePathSegment(workitemId)}`, undefined, options);
|
|
90
|
+
}
|
|
91
|
+
listWorkitemActivities(workitemId) {
|
|
92
|
+
return this.request("GET", `${this.projexPath("/workitems")}/${encodePathSegment(workitemId)}/activities`);
|
|
93
|
+
}
|
|
94
|
+
listWorkitemComments(workitemId) {
|
|
95
|
+
return this.request("GET", `${this.projexPath("/workitems")}/${encodePathSegment(workitemId)}/comments`);
|
|
96
|
+
}
|
|
97
|
+
createWorkitemComment(workitemId, options) {
|
|
98
|
+
return this.request("POST", `${this.projexPath("/workitems")}/${encodePathSegment(workitemId)}/comments`, undefined, {
|
|
99
|
+
content: options.content,
|
|
100
|
+
operatorId: options.operatorId,
|
|
101
|
+
parentId: options.parentId
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
async getWorkitemTimeline(workitemId) {
|
|
105
|
+
const [workitem, activities, comments] = await Promise.all([
|
|
106
|
+
this.getWorkitem(workitemId),
|
|
107
|
+
this.listWorkitemActivities(workitemId),
|
|
108
|
+
this.listWorkitemComments(workitemId)
|
|
109
|
+
]);
|
|
110
|
+
return { workitem, activities, comments };
|
|
111
|
+
}
|
|
112
|
+
listPipelineRuns(pipelineId, options = {}) {
|
|
113
|
+
return this.request("GET", `${this.pipelinePath(pipelineId)}/runs`, {
|
|
114
|
+
page: options.page,
|
|
115
|
+
perPage: options.perPage,
|
|
116
|
+
startTime: options.startTime,
|
|
117
|
+
endTme: options.endTime,
|
|
118
|
+
status: options.status,
|
|
119
|
+
triggerMode: options.triggerMode
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
listPipelines(options = {}) {
|
|
123
|
+
return this.request("GET", this.pipelinesPath(), {
|
|
124
|
+
page: options.page,
|
|
125
|
+
perPage: options.perPage,
|
|
126
|
+
executeStartTime: options.executeStartTime,
|
|
127
|
+
executeEndTime: options.executeEndTime,
|
|
128
|
+
statusList: options.statusList,
|
|
129
|
+
pipelineName: options.pipelineName,
|
|
130
|
+
createStartTime: options.createStartTime,
|
|
131
|
+
createEndTime: options.createEndTime
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
async listLatestFailedPipelineRuns(options = {}) {
|
|
135
|
+
const endTime = options.endTime ?? Date.now();
|
|
136
|
+
const startTime = options.startTime ?? endTime - (options.hours ?? 24) * 60 * 60 * 1000;
|
|
137
|
+
const perPage = options.perPage ?? 30;
|
|
138
|
+
const pipelines = await this.listAllPipelines({
|
|
139
|
+
page: 1,
|
|
140
|
+
perPage,
|
|
141
|
+
executeStartTime: startTime,
|
|
142
|
+
executeEndTime: endTime,
|
|
143
|
+
statusList: "FAIL"
|
|
144
|
+
});
|
|
145
|
+
const uniquePipelines = uniqueBy(pipelines, (pipeline) => String(recordValue(pipeline, "pipelineId") ?? recordValue(pipeline, "id")));
|
|
146
|
+
const results = [];
|
|
147
|
+
for (const pipeline of uniquePipelines) {
|
|
148
|
+
const pipelineId = recordValue(pipeline, "pipelineId") ?? recordValue(pipeline, "id");
|
|
149
|
+
if (pipelineId === undefined || pipelineId === null || pipelineId === "") {
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
const runs = await this.listAllPipelineRuns(String(pipelineId), {
|
|
153
|
+
page: 1,
|
|
154
|
+
perPage,
|
|
155
|
+
startTime,
|
|
156
|
+
endTime,
|
|
157
|
+
status: "FAIL"
|
|
158
|
+
});
|
|
159
|
+
const latestRun = runs
|
|
160
|
+
.filter((run) => timestampInRange(recordValue(run, "startTime"), startTime, endTime))
|
|
161
|
+
.sort((left, right) => Number(recordValue(right, "startTime") ?? 0) - Number(recordValue(left, "startTime") ?? 0))[0];
|
|
162
|
+
if (!latestRun) {
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
results.push({
|
|
166
|
+
pipelineId: normalizeNumericId(pipelineId),
|
|
167
|
+
pipelineName: stringRecordValue(pipeline, "pipelineName") ?? stringRecordValue(pipeline, "name") ?? "",
|
|
168
|
+
pipelineRunId: normalizeNumericId(recordValue(latestRun, "pipelineRunId") ?? ""),
|
|
169
|
+
status: stringRecordValue(latestRun, "status"),
|
|
170
|
+
triggerMode: numericOrStringValue(recordValue(latestRun, "triggerMode")),
|
|
171
|
+
triggerModeName: triggerModeName(recordValue(latestRun, "triggerMode")),
|
|
172
|
+
startTime: numericOrStringValue(recordValue(latestRun, "startTime")),
|
|
173
|
+
startTimeText: formatTimestamp(recordValue(latestRun, "startTime")),
|
|
174
|
+
endTime: numericOrStringValue(recordValue(latestRun, "endTime")),
|
|
175
|
+
endTimeText: formatTimestamp(recordValue(latestRun, "endTime")),
|
|
176
|
+
creatorAccountId: stringRecordValue(latestRun, "creatorAccountId")
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
return results.sort((left, right) => Number(right.startTime ?? 0) - Number(left.startTime ?? 0));
|
|
180
|
+
}
|
|
181
|
+
getPipelineRun(pipelineId, pipelineRunId) {
|
|
182
|
+
return this.request("GET", `${this.pipelinePath(pipelineId)}/runs/${encodePathSegment(pipelineRunId)}`);
|
|
183
|
+
}
|
|
184
|
+
retryPipelineJobRun(pipelineId, pipelineRunId, jobId) {
|
|
185
|
+
return this.request("PUT", `${this.pipelinePath(pipelineId)}/pipelineRuns/${encodePathSegment(pipelineRunId)}/jobs/${encodePathSegment(jobId)}/retry`);
|
|
186
|
+
}
|
|
43
187
|
createChangeRequest(repositoryId, options) {
|
|
44
188
|
return this.request("POST", `${this.repositoryPath(repositoryId)}/changeRequests`, undefined, {
|
|
45
189
|
createFrom: options.createFrom ?? "WEB",
|
|
@@ -116,6 +260,14 @@ export class YunxiaoClient {
|
|
|
116
260
|
description: options.description
|
|
117
261
|
});
|
|
118
262
|
const localId = localIdFromChangeRequest(changeRequest);
|
|
263
|
+
if (options.createOnly) {
|
|
264
|
+
return {
|
|
265
|
+
repository,
|
|
266
|
+
changeRequest,
|
|
267
|
+
review: null,
|
|
268
|
+
merge: null
|
|
269
|
+
};
|
|
270
|
+
}
|
|
119
271
|
const review = await this.reviewChangeRequest(repositoryId, localId, {
|
|
120
272
|
reviewComment: "Approved by yunxiao-cli release workflow"
|
|
121
273
|
});
|
|
@@ -152,6 +304,65 @@ export class YunxiaoClient {
|
|
|
152
304
|
repositoryChangeRequestPath(repositoryId, localId) {
|
|
153
305
|
return `${this.repositoryPath(repositoryId)}/changeRequests/${localId}`;
|
|
154
306
|
}
|
|
307
|
+
projexPath(path) {
|
|
308
|
+
if (this.edition === "center") {
|
|
309
|
+
return `/oapi/v1/projex/organizations/${encodePathSegment(this.organizationId ?? "")}${path}`;
|
|
310
|
+
}
|
|
311
|
+
return `/oapi/v1/projex${path}`;
|
|
312
|
+
}
|
|
313
|
+
workitemsSearchPath() {
|
|
314
|
+
if (this.edition === "center") {
|
|
315
|
+
return this.projexPath("/workitems:search");
|
|
316
|
+
}
|
|
317
|
+
return this.organizationId
|
|
318
|
+
? `/oapi/v1/projex/${encodePathSegment(this.organizationId)}/workitems:search`
|
|
319
|
+
: "/oapi/v1/projex/workitems:search";
|
|
320
|
+
}
|
|
321
|
+
projectPath(projectId) {
|
|
322
|
+
return `${this.projexPath("/projects")}/${encodePathSegment(projectId)}`;
|
|
323
|
+
}
|
|
324
|
+
platformMembersPath() {
|
|
325
|
+
if (this.edition === "center") {
|
|
326
|
+
return `/oapi/v1/platform/organizations/${encodePathSegment(this.organizationId ?? "")}/members`;
|
|
327
|
+
}
|
|
328
|
+
return "/oapi/v1/platform/members";
|
|
329
|
+
}
|
|
330
|
+
pipelinesPath() {
|
|
331
|
+
if (this.edition === "center") {
|
|
332
|
+
return `/oapi/v1/flow/organizations/${encodePathSegment(this.organizationId ?? "")}/pipelines`;
|
|
333
|
+
}
|
|
334
|
+
return "/oapi/v1/flow/pipelines";
|
|
335
|
+
}
|
|
336
|
+
pipelinePath(pipelineId) {
|
|
337
|
+
const encodedPipelineId = encodePathSegment(pipelineId);
|
|
338
|
+
return `${this.pipelinesPath()}/${encodedPipelineId}`;
|
|
339
|
+
}
|
|
340
|
+
async listAllPipelines(options) {
|
|
341
|
+
const rows = [];
|
|
342
|
+
const perPage = options.perPage ?? 30;
|
|
343
|
+
for (let page = options.page ?? 1;; page += 1) {
|
|
344
|
+
const response = await this.listPipelines({ ...options, page, perPage });
|
|
345
|
+
const pageRows = arrayRecords(response);
|
|
346
|
+
rows.push(...pageRows);
|
|
347
|
+
if (pageRows.length < perPage) {
|
|
348
|
+
break;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
return rows;
|
|
352
|
+
}
|
|
353
|
+
async listAllPipelineRuns(pipelineId, options) {
|
|
354
|
+
const rows = [];
|
|
355
|
+
const perPage = options.perPage ?? 30;
|
|
356
|
+
for (let page = options.page ?? 1;; page += 1) {
|
|
357
|
+
const response = await this.listPipelineRuns(pipelineId, { ...options, page, perPage });
|
|
358
|
+
const pageRows = arrayRecords(response);
|
|
359
|
+
rows.push(...pageRows);
|
|
360
|
+
if (pageRows.length < perPage) {
|
|
361
|
+
break;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
return rows;
|
|
365
|
+
}
|
|
155
366
|
async request(method, path, query, body) {
|
|
156
367
|
const url = new URL(`https://${this.domain}${path}`);
|
|
157
368
|
for (const [key, value] of Object.entries(query ?? {})) {
|
|
@@ -186,6 +397,75 @@ function stripProtocol(domain) {
|
|
|
186
397
|
function encodePathSegment(value) {
|
|
187
398
|
return encodeURIComponent(value);
|
|
188
399
|
}
|
|
400
|
+
function arrayRecords(value) {
|
|
401
|
+
return Array.isArray(value) ? value.filter(isRecord) : [];
|
|
402
|
+
}
|
|
403
|
+
function isRecord(value) {
|
|
404
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
405
|
+
}
|
|
406
|
+
function recordValue(record, key) {
|
|
407
|
+
return record[key];
|
|
408
|
+
}
|
|
409
|
+
function stringRecordValue(record, key) {
|
|
410
|
+
const value = record[key];
|
|
411
|
+
return typeof value === "string" ? value : undefined;
|
|
412
|
+
}
|
|
413
|
+
function uniqueBy(values, keyFn) {
|
|
414
|
+
const seen = new Set();
|
|
415
|
+
const result = [];
|
|
416
|
+
for (const value of values) {
|
|
417
|
+
const key = keyFn(value);
|
|
418
|
+
if (!key || seen.has(key)) {
|
|
419
|
+
continue;
|
|
420
|
+
}
|
|
421
|
+
seen.add(key);
|
|
422
|
+
result.push(value);
|
|
423
|
+
}
|
|
424
|
+
return result;
|
|
425
|
+
}
|
|
426
|
+
function timestampInRange(value, startTime, endTime) {
|
|
427
|
+
const timestamp = Number(value);
|
|
428
|
+
return Number.isFinite(timestamp) && timestamp >= startTime && timestamp <= endTime;
|
|
429
|
+
}
|
|
430
|
+
function normalizeNumericId(value) {
|
|
431
|
+
const numberValue = Number(value);
|
|
432
|
+
return Number.isInteger(numberValue) ? numberValue : String(value);
|
|
433
|
+
}
|
|
434
|
+
function numericOrStringValue(value) {
|
|
435
|
+
if (value === undefined || value === null || value === "") {
|
|
436
|
+
return undefined;
|
|
437
|
+
}
|
|
438
|
+
const numberValue = Number(value);
|
|
439
|
+
return Number.isFinite(numberValue) ? numberValue : String(value);
|
|
440
|
+
}
|
|
441
|
+
function formatTimestamp(value) {
|
|
442
|
+
const timestamp = Number(value);
|
|
443
|
+
if (!Number.isFinite(timestamp)) {
|
|
444
|
+
return "";
|
|
445
|
+
}
|
|
446
|
+
const date = new Date(timestamp);
|
|
447
|
+
if (Number.isNaN(date.getTime())) {
|
|
448
|
+
return "";
|
|
449
|
+
}
|
|
450
|
+
const pad = (part) => String(part).padStart(2, "0");
|
|
451
|
+
return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`;
|
|
452
|
+
}
|
|
453
|
+
function triggerModeName(value) {
|
|
454
|
+
switch (Number(value)) {
|
|
455
|
+
case 1:
|
|
456
|
+
return "人工触发";
|
|
457
|
+
case 2:
|
|
458
|
+
return "定时触发";
|
|
459
|
+
case 3:
|
|
460
|
+
return "代码提交触发";
|
|
461
|
+
case 5:
|
|
462
|
+
return "流水线触发";
|
|
463
|
+
case 6:
|
|
464
|
+
return "Webhook触发";
|
|
465
|
+
default:
|
|
466
|
+
return value === undefined || value === null ? "" : String(value);
|
|
467
|
+
}
|
|
468
|
+
}
|
|
189
469
|
function compactBody(body) {
|
|
190
470
|
return Object.fromEntries(Object.entries(body).filter(([, value]) => value !== undefined && value !== null && value !== ""));
|
|
191
471
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coderpp/yunxiao-cli",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "A CLI for Yunxiao
|
|
3
|
+
"version": "0.1.9",
|
|
4
|
+
"description": "A CLI for Yunxiao merge request, pipeline retry, project member, and workitem workflows.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -18,6 +18,11 @@
|
|
|
18
18
|
"build": "tsc -p tsconfig.json",
|
|
19
19
|
"pack:dry-run": "npm pack --dry-run",
|
|
20
20
|
"prepack": "npm run build",
|
|
21
|
+
"skills:sync": "scripts/sync-skills.sh",
|
|
22
|
+
"skills:watch": "scripts/watch-skills.sh",
|
|
23
|
+
"skills:watch:start": "scripts/start-skill-sync-watch.sh",
|
|
24
|
+
"skills:watch:status": "scripts/status-skill-sync-watch.sh",
|
|
25
|
+
"skills:watch:stop": "scripts/stop-skill-sync-watch.sh",
|
|
21
26
|
"test": "tsc -p tsconfig.json && node --test dist/test/*.test.js"
|
|
22
27
|
},
|
|
23
28
|
"publishConfig": {
|