@xurenxiang1219/pingcode-mcp 0.3.1

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 (268) hide show
  1. package/.env.example +115 -0
  2. package/.env.stdio.local.example +13 -0
  3. package/README.md +222 -0
  4. package/dist/approve-write.d.ts +3 -0
  5. package/dist/approve-write.d.ts.map +1 -0
  6. package/dist/approve-write.js +81 -0
  7. package/dist/approve-write.js.map +1 -0
  8. package/dist/auth/cimd-client-resolver.d.ts +35 -0
  9. package/dist/auth/cimd-client-resolver.d.ts.map +1 -0
  10. package/dist/auth/cimd-client-resolver.js +293 -0
  11. package/dist/auth/cimd-client-resolver.js.map +1 -0
  12. package/dist/auth/memory-store.d.ts +15 -0
  13. package/dist/auth/memory-store.d.ts.map +1 -0
  14. package/dist/auth/memory-store.js +46 -0
  15. package/dist/auth/memory-store.js.map +1 -0
  16. package/dist/auth/pingcode-oauth-client.d.ts +23 -0
  17. package/dist/auth/pingcode-oauth-client.d.ts.map +1 -0
  18. package/dist/auth/pingcode-oauth-client.js +103 -0
  19. package/dist/auth/pingcode-oauth-client.js.map +1 -0
  20. package/dist/auth/pingcode-oauth-provider.d.ts +70 -0
  21. package/dist/auth/pingcode-oauth-provider.d.ts.map +1 -0
  22. package/dist/auth/pingcode-oauth-provider.js +414 -0
  23. package/dist/auth/pingcode-oauth-provider.js.map +1 -0
  24. package/dist/auth/redis-store.d.ts +16 -0
  25. package/dist/auth/redis-store.d.ts.map +1 -0
  26. package/dist/auth/redis-store.js +54 -0
  27. package/dist/auth/redis-store.js.map +1 -0
  28. package/dist/auth/runtime.d.ts +10 -0
  29. package/dist/auth/runtime.d.ts.map +1 -0
  30. package/dist/auth/runtime.js +57 -0
  31. package/dist/auth/runtime.js.map +1 -0
  32. package/dist/auth/store.d.ts +35 -0
  33. package/dist/auth/store.d.ts.map +1 -0
  34. package/dist/auth/store.js +55 -0
  35. package/dist/auth/store.js.map +1 -0
  36. package/dist/auth/token-cipher.d.ts +7 -0
  37. package/dist/auth/token-cipher.d.ts.map +1 -0
  38. package/dist/auth/token-cipher.js +36 -0
  39. package/dist/auth/token-cipher.js.map +1 -0
  40. package/dist/config.d.ts +54 -0
  41. package/dist/config.d.ts.map +1 -0
  42. package/dist/config.js +270 -0
  43. package/dist/config.js.map +1 -0
  44. package/dist/domain/content-hash.d.ts +5 -0
  45. package/dist/domain/content-hash.d.ts.map +1 -0
  46. package/dist/domain/content-hash.js +17 -0
  47. package/dist/domain/content-hash.js.map +1 -0
  48. package/dist/domain/requirement-context.d.ts +29 -0
  49. package/dist/domain/requirement-context.d.ts.map +1 -0
  50. package/dist/domain/requirement-context.js +2 -0
  51. package/dist/domain/requirement-context.js.map +1 -0
  52. package/dist/domain/test-case-context.d.ts +56 -0
  53. package/dist/domain/test-case-context.d.ts.map +1 -0
  54. package/dist/domain/test-case-context.js +2 -0
  55. package/dist/domain/test-case-context.js.map +1 -0
  56. package/dist/domain/work-item-context.d.ts +47 -0
  57. package/dist/domain/work-item-context.d.ts.map +1 -0
  58. package/dist/domain/work-item-context.js +2 -0
  59. package/dist/domain/work-item-context.js.map +1 -0
  60. package/dist/environment.d.ts +2 -0
  61. package/dist/environment.d.ts.map +1 -0
  62. package/dist/environment.js +21 -0
  63. package/dist/environment.js.map +1 -0
  64. package/dist/index.d.ts +3 -0
  65. package/dist/index.d.ts.map +1 -0
  66. package/dist/index.js +52 -0
  67. package/dist/index.js.map +1 -0
  68. package/dist/inspect-wiki.d.ts +3 -0
  69. package/dist/inspect-wiki.d.ts.map +1 -0
  70. package/dist/inspect-wiki.js +49 -0
  71. package/dist/inspect-wiki.js.map +1 -0
  72. package/dist/logger.d.ts +9 -0
  73. package/dist/logger.d.ts.map +1 -0
  74. package/dist/logger.js +40 -0
  75. package/dist/logger.js.map +1 -0
  76. package/dist/mcp/create-server.d.ts +10 -0
  77. package/dist/mcp/create-server.d.ts.map +1 -0
  78. package/dist/mcp/create-server.js +40 -0
  79. package/dist/mcp/create-server.js.map +1 -0
  80. package/dist/mcp/pagination-guidance.d.ts +19 -0
  81. package/dist/mcp/pagination-guidance.d.ts.map +1 -0
  82. package/dist/mcp/pagination-guidance.js +36 -0
  83. package/dist/mcp/pagination-guidance.js.map +1 -0
  84. package/dist/mcp/reference-resolution.d.ts +19 -0
  85. package/dist/mcp/reference-resolution.d.ts.map +1 -0
  86. package/dist/mcp/reference-resolution.js +160 -0
  87. package/dist/mcp/reference-resolution.js.map +1 -0
  88. package/dist/mcp/tool-registry.d.ts +2 -0
  89. package/dist/mcp/tool-registry.d.ts.map +1 -0
  90. package/dist/mcp/tool-registry.js +55 -0
  91. package/dist/mcp/tool-registry.js.map +1 -0
  92. package/dist/mcp/tool-runtime.d.ts +22 -0
  93. package/dist/mcp/tool-runtime.d.ts.map +1 -0
  94. package/dist/mcp/tool-runtime.js +214 -0
  95. package/dist/mcp/tool-runtime.js.map +1 -0
  96. package/dist/mcp/tools/member-role.d.ts +8 -0
  97. package/dist/mcp/tools/member-role.d.ts.map +1 -0
  98. package/dist/mcp/tools/member-role.js +451 -0
  99. package/dist/mcp/tools/member-role.js.map +1 -0
  100. package/dist/mcp/tools/metadata.d.ts +5 -0
  101. package/dist/mcp/tools/metadata.d.ts.map +1 -0
  102. package/dist/mcp/tools/metadata.js +606 -0
  103. package/dist/mcp/tools/metadata.js.map +1 -0
  104. package/dist/mcp/tools/project-context.d.ts +4 -0
  105. package/dist/mcp/tools/project-context.d.ts.map +1 -0
  106. package/dist/mcp/tools/project-context.js +111 -0
  107. package/dist/mcp/tools/project-context.js.map +1 -0
  108. package/dist/mcp/tools/project.d.ts +7 -0
  109. package/dist/mcp/tools/project.d.ts.map +1 -0
  110. package/dist/mcp/tools/project.js +370 -0
  111. package/dist/mcp/tools/project.js.map +1 -0
  112. package/dist/mcp/tools/relation.d.ts +7 -0
  113. package/dist/mcp/tools/relation.d.ts.map +1 -0
  114. package/dist/mcp/tools/relation.js +592 -0
  115. package/dist/mcp/tools/relation.js.map +1 -0
  116. package/dist/mcp/tools/runtime-info.d.ts +4 -0
  117. package/dist/mcp/tools/runtime-info.d.ts.map +1 -0
  118. package/dist/mcp/tools/runtime-info.js +49 -0
  119. package/dist/mcp/tools/runtime-info.js.map +1 -0
  120. package/dist/mcp/tools/ship-suite.d.ts +7 -0
  121. package/dist/mcp/tools/ship-suite.d.ts.map +1 -0
  122. package/dist/mcp/tools/ship-suite.js +636 -0
  123. package/dist/mcp/tools/ship-suite.js.map +1 -0
  124. package/dist/mcp/tools/ship.d.ts +7 -0
  125. package/dist/mcp/tools/ship.d.ts.map +1 -0
  126. package/dist/mcp/tools/ship.js +617 -0
  127. package/dist/mcp/tools/ship.js.map +1 -0
  128. package/dist/mcp/tools/sync.d.ts +10 -0
  129. package/dist/mcp/tools/sync.d.ts.map +1 -0
  130. package/dist/mcp/tools/sync.js +1110 -0
  131. package/dist/mcp/tools/sync.js.map +1 -0
  132. package/dist/mcp/tools/task.d.ts +5 -0
  133. package/dist/mcp/tools/task.d.ts.map +1 -0
  134. package/dist/mcp/tools/task.js +236 -0
  135. package/dist/mcp/tools/task.js.map +1 -0
  136. package/dist/mcp/tools/test-case-bulk.d.ts +7 -0
  137. package/dist/mcp/tools/test-case-bulk.d.ts.map +1 -0
  138. package/dist/mcp/tools/test-case-bulk.js +297 -0
  139. package/dist/mcp/tools/test-case-bulk.js.map +1 -0
  140. package/dist/mcp/tools/test-case-delete.d.ts +7 -0
  141. package/dist/mcp/tools/test-case-delete.d.ts.map +1 -0
  142. package/dist/mcp/tools/test-case-delete.js +247 -0
  143. package/dist/mcp/tools/test-case-delete.js.map +1 -0
  144. package/dist/mcp/tools/test-case.d.ts +5 -0
  145. package/dist/mcp/tools/test-case.d.ts.map +1 -0
  146. package/dist/mcp/tools/test-case.js +155 -0
  147. package/dist/mcp/tools/test-case.js.map +1 -0
  148. package/dist/mcp/tools/test-library.d.ts +7 -0
  149. package/dist/mcp/tools/test-library.d.ts.map +1 -0
  150. package/dist/mcp/tools/test-library.js +302 -0
  151. package/dist/mcp/tools/test-library.js.map +1 -0
  152. package/dist/mcp/tools/wiki.d.ts +5 -0
  153. package/dist/mcp/tools/wiki.d.ts.map +1 -0
  154. package/dist/mcp/tools/wiki.js +266 -0
  155. package/dist/mcp/tools/wiki.js.map +1 -0
  156. package/dist/mcp/write-approval.d.ts +48 -0
  157. package/dist/mcp/write-approval.d.ts.map +1 -0
  158. package/dist/mcp/write-approval.js +321 -0
  159. package/dist/mcp/write-approval.js.map +1 -0
  160. package/dist/observability/metrics.d.ts +46 -0
  161. package/dist/observability/metrics.d.ts.map +1 -0
  162. package/dist/observability/metrics.js +79 -0
  163. package/dist/observability/metrics.js.map +1 -0
  164. package/dist/pingcode/access-token-provider.d.ts +5 -0
  165. package/dist/pingcode/access-token-provider.d.ts.map +1 -0
  166. package/dist/pingcode/access-token-provider.js +2 -0
  167. package/dist/pingcode/access-token-provider.js.map +1 -0
  168. package/dist/pingcode/client.d.ts +43 -0
  169. package/dist/pingcode/client.d.ts.map +1 -0
  170. package/dist/pingcode/client.js +300 -0
  171. package/dist/pingcode/client.js.map +1 -0
  172. package/dist/pingcode/errors.d.ts +20 -0
  173. package/dist/pingcode/errors.d.ts.map +1 -0
  174. package/dist/pingcode/errors.js +14 -0
  175. package/dist/pingcode/errors.js.map +1 -0
  176. package/dist/pingcode/schemas.d.ts +465 -0
  177. package/dist/pingcode/schemas.d.ts.map +1 -0
  178. package/dist/pingcode/schemas.js +450 -0
  179. package/dist/pingcode/schemas.js.map +1 -0
  180. package/dist/pingcode/token-provider.d.ts +20 -0
  181. package/dist/pingcode/token-provider.d.ts.map +1 -0
  182. package/dist/pingcode/token-provider.js +97 -0
  183. package/dist/pingcode/token-provider.js.map +1 -0
  184. package/dist/pingcode/write-response.d.ts +9 -0
  185. package/dist/pingcode/write-response.d.ts.map +1 -0
  186. package/dist/pingcode/write-response.js +39 -0
  187. package/dist/pingcode/write-response.js.map +1 -0
  188. package/dist/services.d.ts +22 -0
  189. package/dist/services.d.ts.map +1 -0
  190. package/dist/services.js +84 -0
  191. package/dist/services.js.map +1 -0
  192. package/dist/sources/metadata-source.d.ts +445 -0
  193. package/dist/sources/metadata-source.d.ts.map +1 -0
  194. package/dist/sources/metadata-source.js +167 -0
  195. package/dist/sources/metadata-source.js.map +1 -0
  196. package/dist/sources/project-context-source.d.ts +61 -0
  197. package/dist/sources/project-context-source.d.ts.map +1 -0
  198. package/dist/sources/project-context-source.js +224 -0
  199. package/dist/sources/project-context-source.js.map +1 -0
  200. package/dist/sources/relation-source.d.ts +83 -0
  201. package/dist/sources/relation-source.d.ts.map +1 -0
  202. package/dist/sources/relation-source.js +129 -0
  203. package/dist/sources/relation-source.js.map +1 -0
  204. package/dist/sources/requirement-source.d.ts +5 -0
  205. package/dist/sources/requirement-source.d.ts.map +1 -0
  206. package/dist/sources/requirement-source.js +2 -0
  207. package/dist/sources/requirement-source.js.map +1 -0
  208. package/dist/sources/ship-source.d.ts +67 -0
  209. package/dist/sources/ship-source.d.ts.map +1 -0
  210. package/dist/sources/ship-source.js +135 -0
  211. package/dist/sources/ship-source.js.map +1 -0
  212. package/dist/sources/test-case-source.d.ts +30 -0
  213. package/dist/sources/test-case-source.d.ts.map +1 -0
  214. package/dist/sources/test-case-source.js +206 -0
  215. package/dist/sources/test-case-source.js.map +1 -0
  216. package/dist/sources/wiki-source.d.ts +34 -0
  217. package/dist/sources/wiki-source.d.ts.map +1 -0
  218. package/dist/sources/wiki-source.js +136 -0
  219. package/dist/sources/wiki-source.js.map +1 -0
  220. package/dist/sources/work-item-source.d.ts +33 -0
  221. package/dist/sources/work-item-source.d.ts.map +1 -0
  222. package/dist/sources/work-item-source.js +159 -0
  223. package/dist/sources/work-item-source.js.map +1 -0
  224. package/dist/sources/write-source.d.ts +461 -0
  225. package/dist/sources/write-source.d.ts.map +1 -0
  226. package/dist/sources/write-source.js +174 -0
  227. package/dist/sources/write-source.js.map +1 -0
  228. package/dist/transports/bearer-auth.d.ts +20 -0
  229. package/dist/transports/bearer-auth.d.ts.map +1 -0
  230. package/dist/transports/bearer-auth.js +79 -0
  231. package/dist/transports/bearer-auth.js.map +1 -0
  232. package/dist/transports/http.d.ts +11 -0
  233. package/dist/transports/http.d.ts.map +1 -0
  234. package/dist/transports/http.js +203 -0
  235. package/dist/transports/http.js.map +1 -0
  236. package/dist/transports/metrics-auth.d.ts +3 -0
  237. package/dist/transports/metrics-auth.d.ts.map +1 -0
  238. package/dist/transports/metrics-auth.js +22 -0
  239. package/dist/transports/metrics-auth.js.map +1 -0
  240. package/dist/transports/stdio.d.ts +5 -0
  241. package/dist/transports/stdio.d.ts.map +1 -0
  242. package/dist/transports/stdio.js +11 -0
  243. package/dist/transports/stdio.js.map +1 -0
  244. package/dist/uat/run-label.d.ts +2 -0
  245. package/dist/uat/run-label.d.ts.map +1 -0
  246. package/dist/uat/run-label.js +12 -0
  247. package/dist/uat/run-label.js.map +1 -0
  248. package/dist/verify.d.ts +3 -0
  249. package/dist/verify.d.ts.map +1 -0
  250. package/dist/verify.js +59 -0
  251. package/dist/verify.js.map +1 -0
  252. package/dist/write/approval.d.ts +35 -0
  253. package/dist/write/approval.d.ts.map +1 -0
  254. package/dist/write/approval.js +66 -0
  255. package/dist/write/approval.js.map +1 -0
  256. package/dist/write/plan.d.ts +2 -0
  257. package/dist/write/plan.d.ts.map +1 -0
  258. package/dist/write/plan.js +17 -0
  259. package/dist/write/plan.js.map +1 -0
  260. package/dist/write/runtime.d.ts +90 -0
  261. package/dist/write/runtime.d.ts.map +1 -0
  262. package/dist/write/runtime.js +244 -0
  263. package/dist/write/runtime.js.map +1 -0
  264. package/dist/write/store.d.ts +101 -0
  265. package/dist/write/store.d.ts.map +1 -0
  266. package/dist/write/store.js +201 -0
  267. package/dist/write/store.js.map +1 -0
  268. package/package.json +58 -0
@@ -0,0 +1,129 @@
1
+ import { PingCodeError } from "../pingcode/errors.js";
2
+ import { paginatedSchema, relationSchema, shipIdeaSchema, testCaseSchema, wikiPageSchema, workItemSchema, } from "../pingcode/schemas.js";
3
+ /** Resource types accepted by the official Relation response/list contract. */
4
+ export const traceableResourceTypes = [
5
+ "idea",
6
+ "ticket",
7
+ "work_item",
8
+ "test_plan",
9
+ "test_run",
10
+ "test_case",
11
+ "page",
12
+ ];
13
+ const supportedRelationReadTargets = {
14
+ idea: ["ticket", "work_item", "test_case", "idea", "page"],
15
+ ticket: ["idea", "work_item", "ticket", "page"],
16
+ work_item: ["test_case", "idea", "ticket", "page"],
17
+ test_plan: ["work_item"],
18
+ test_run: ["work_item"],
19
+ test_case: ["idea", "work_item", "page"],
20
+ page: ["idea", "ticket", "work_item", "test_case"],
21
+ };
22
+ export class RelationSource {
23
+ client;
24
+ constructor(client) {
25
+ this.client = client;
26
+ }
27
+ async listRelations(input) {
28
+ if (!isSupportedRelationReadPair(input.principalType, input.targetType)) {
29
+ throw new PingCodeError(`官方 Relation 不支持查询 ${input.principalType} -> ${input.targetType} 组合;请按官方参数组合重新选择 target_type`, "BAD_REQUEST");
30
+ }
31
+ return paginatedSchema(relationSchema).parse(await this.client.get("/v1/relations", {
32
+ principal_type: input.principalType,
33
+ principal_id: input.principalId,
34
+ target_type: input.targetType,
35
+ page_index: input.pageIndex,
36
+ page_size: input.pageSize,
37
+ }));
38
+ }
39
+ async getRelation(relationId) {
40
+ return relationSchema.parse(await this.client.get(`/v1/relations/${encodeURIComponent(relationId)}`));
41
+ }
42
+ async findExactRelation(input) {
43
+ let pageIndex = 0;
44
+ for (;;) {
45
+ const page = await this.listRelations({ ...input, pageIndex, pageSize: 100 });
46
+ const target = page.values.find((relation) => relationTargetResourceId(relation) === input.targetId);
47
+ if (target) {
48
+ return target;
49
+ }
50
+ const consumed = (page.page_index + 1) * page.page_size;
51
+ if (consumed >= page.total || page.values.length === 0) {
52
+ return null;
53
+ }
54
+ pageIndex = page.page_index + 1;
55
+ }
56
+ }
57
+ async createRelation(fields) {
58
+ const response = await this.client.post("/v1/relations", {
59
+ principal_type: fields.principalType,
60
+ principal_id: fields.principalId,
61
+ target_type: fields.targetType,
62
+ target_id: fields.targetId,
63
+ });
64
+ try {
65
+ return relationSchema.parse(response);
66
+ }
67
+ catch (error) {
68
+ throw new PingCodeError("PingCode 已接受关联创建请求,但返回内容无法确认 Relation 身份;请使用 pingcode_relation_list 在 MCP 内回读,禁止更换幂等键重试", "WRITE_OUTCOME_UNKNOWN", { cause: error });
69
+ }
70
+ }
71
+ async deleteRelation(relationId) {
72
+ if (!this.client.delete) {
73
+ throw new PingCodeError("当前 PingCode Client 不支持 DELETE 请求", "NOT_CONFIGURED");
74
+ }
75
+ await this.client.delete(`/v1/relations/${encodeURIComponent(relationId)}`);
76
+ }
77
+ async readResource(type, id) {
78
+ if (type === "idea") {
79
+ const value = shipIdeaSchema.parse(await this.client.get(`/v1/ship/ideas/${encodeURIComponent(id)}`));
80
+ return {
81
+ type,
82
+ id: value.id,
83
+ identifier: value.identifier,
84
+ title: value.title,
85
+ };
86
+ }
87
+ if (type === "work_item") {
88
+ const value = workItemSchema.parse(await this.client.get(`/v1/project/work_items/${encodeURIComponent(id)}`));
89
+ return {
90
+ type,
91
+ id: value.id,
92
+ identifier: value.identifier,
93
+ title: value.title,
94
+ workItemType: value.type,
95
+ };
96
+ }
97
+ if (type === "test_case") {
98
+ const value = testCaseSchema.parse(await this.client.get(`/v1/testhub/cases/${encodeURIComponent(id)}`));
99
+ return { type, id: value.id, identifier: value.identifier, title: value.title };
100
+ }
101
+ if (type === "page") {
102
+ const value = wikiPageSchema.parse(await this.client.get(`/v1/wiki/pages/${encodeURIComponent(id)}`));
103
+ return { type, id: value.id, identifier: value.short_id ?? null, title: value.name };
104
+ }
105
+ throw new PingCodeError(`${type} 已被官方 Relation 响应支持,但当前 MCP 尚未接入该资源目录,不能按名称解析;请使用官方回读得到的资源 ID`, "BAD_REQUEST");
106
+ }
107
+ }
108
+ export function isSupportedRelationReadPair(principalType, targetType) {
109
+ return supportedRelationReadTargets[principalType].includes(targetType);
110
+ }
111
+ export function isSupportedRelationWritePair(principalType, targetType) {
112
+ if (principalType === "idea") {
113
+ return targetType === "work_item" || targetType === "test_case" || targetType === "page";
114
+ }
115
+ if (principalType === "work_item") {
116
+ return targetType === "idea" || targetType === "test_case" || targetType === "page";
117
+ }
118
+ if (principalType === "test_case") {
119
+ return targetType === "idea" || targetType === "work_item" || targetType === "page";
120
+ }
121
+ return false;
122
+ }
123
+ export function relationPrincipalResourceId(relation) {
124
+ return relation.principal_id ?? relation.principal?.id;
125
+ }
126
+ export function relationTargetResourceId(relation) {
127
+ return relation.target_id ?? relation.target?.id;
128
+ }
129
+ //# sourceMappingURL=relation-source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relation-source.js","sourceRoot":"","sources":["../../src/sources/relation-source.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { RequirementContext } from "../domain/requirement-context.js";
2
+ export interface RequirementSource {
3
+ getRequirementContext(reference: string): Promise<RequirementContext>;
4
+ }
5
+ //# sourceMappingURL=requirement-source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"requirement-source.d.ts","sourceRoot":"","sources":["../../src/sources/requirement-source.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AAE3E,MAAM,WAAW,iBAAiB;IAChC,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;CACvE"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=requirement-source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"requirement-source.js","sourceRoot":"","sources":["../../src/sources/requirement-source.ts"],"names":[],"mappings":""}
@@ -0,0 +1,67 @@
1
+ import type { PingCodeWriteClientLike } from "../pingcode/client.js";
2
+ import { type ShipIdea, type ShipProduct, type ShipSuite } from "../pingcode/schemas.js";
3
+ export interface ShipListInput {
4
+ keywords?: string;
5
+ productId?: string;
6
+ pageIndex?: number;
7
+ pageSize?: number;
8
+ }
9
+ export interface ShipProductMember {
10
+ id: string;
11
+ type: "user" | "user_group";
12
+ }
13
+ export interface ShipProductWriteFields {
14
+ scopeType?: "organization" | "user_group";
15
+ scopeId?: string;
16
+ name?: string;
17
+ visibility?: "public" | "private";
18
+ identifier?: string;
19
+ description?: string;
20
+ members?: ShipProductMember[];
21
+ }
22
+ export interface ShipIdeaWriteFields {
23
+ productId?: string;
24
+ title?: string;
25
+ assigneeId?: string;
26
+ description?: string;
27
+ suiteId?: string;
28
+ priorityId?: string;
29
+ properties?: Record<string, unknown>;
30
+ }
31
+ export interface ShipSuiteWriteFields {
32
+ name: string;
33
+ type: "product" | "module";
34
+ parentId?: string;
35
+ }
36
+ export declare class ShipSource {
37
+ private readonly client;
38
+ constructor(client: PingCodeWriteClientLike);
39
+ listProducts(input: ShipListInput): Promise<{
40
+ page_size: number;
41
+ page_index: number;
42
+ total: number;
43
+ values: ShipProduct[];
44
+ }>;
45
+ getProduct(productId: string): Promise<ShipProduct>;
46
+ createProduct(fields: ShipProductWriteFields): Promise<ShipProduct>;
47
+ updateProduct(productId: string, fields: ShipProductWriteFields): Promise<ShipProduct>;
48
+ listIdeas(input: ShipListInput): Promise<{
49
+ page_size: number;
50
+ page_index: number;
51
+ total: number;
52
+ values: ShipIdea[];
53
+ }>;
54
+ getIdea(ideaId: string): Promise<ShipIdea>;
55
+ createIdea(fields: ShipIdeaWriteFields): Promise<ShipIdea>;
56
+ updateIdea(ideaId: string, fields: ShipIdeaWriteFields): Promise<ShipIdea>;
57
+ listSuites(productId: string, input?: Pick<ShipListInput, "pageIndex" | "pageSize">): Promise<{
58
+ page_size: number;
59
+ page_index: number;
60
+ total: number;
61
+ values: ShipSuite[];
62
+ }>;
63
+ getSuite(productId: string, suiteId: string): Promise<ShipSuite>;
64
+ createSuite(productId: string, fields: ShipSuiteWriteFields): Promise<ShipSuite>;
65
+ removeSuite(productId: string, suiteId: string): Promise<void>;
66
+ }
67
+ //# sourceMappingURL=ship-source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ship-source.d.ts","sourceRoot":"","sources":["../../src/sources/ship-source.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAErE,OAAO,EAKL,KAAK,QAAQ,EACb,KAAK,WAAW,EAChB,KAAK,SAAS,EACf,MAAM,wBAAwB,CAAC;AAGhC,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,GAAG,YAAY,CAAC;CAC7B;AAED,MAAM,WAAW,sBAAsB;IACrC,SAAS,CAAC,EAAE,cAAc,GAAG,YAAY,CAAC;IAC1C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,iBAAiB,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,mBAAmB;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,UAAU;IACT,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,uBAAuB;IAEtD,YAAY,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,WAAW,EAAE,CAAA;KAAE,CAAC;IAM5H,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAMnD,aAAa,CAAC,MAAM,EAAE,sBAAsB,GAAG,OAAO,CAAC,WAAW,CAAC;IAoBnE,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,sBAAsB,GAAG,OAAO,CAAC,WAAW,CAAC;IAStF,SAAS,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,QAAQ,EAAE,CAAA;KAAE,CAAC;IAMtH,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAM1C,UAAU,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,QAAQ,CAAC;IAmB1D,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,QAAQ,CAAC;IAM1E,UAAU,CACd,SAAS,EAAE,MAAM,EACjB,KAAK,GAAE,IAAI,CAAC,aAAa,EAAE,WAAW,GAAG,UAAU,CAAM,GACxD,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,SAAS,EAAE,CAAA;KAAE,CAAC;IASnF,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IAQhE,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAAC,SAAS,CAAC;IAShF,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAQrE"}
@@ -0,0 +1,135 @@
1
+ import { PingCodeError } from "../pingcode/errors.js";
2
+ import { paginatedSchema, shipIdeaSchema, shipProductSchema, shipSuiteSchema, } from "../pingcode/schemas.js";
3
+ import { extractWriteResourceId, unknownWriteResponse, unwrapWriteResponse } from "../pingcode/write-response.js";
4
+ export class ShipSource {
5
+ client;
6
+ constructor(client) {
7
+ this.client = client;
8
+ }
9
+ async listProducts(input) {
10
+ return paginatedSchema(shipProductSchema).parse(await this.client.get("/v1/ship/products", listQuery(input)));
11
+ }
12
+ async getProduct(productId) {
13
+ return shipProductSchema.parse(await this.client.get(`/v1/ship/products/${encodeURIComponent(productId)}`));
14
+ }
15
+ async createProduct(fields) {
16
+ const raw = unwrapWriteResponse(await this.client.post("/v1/ship/products", mapProductFields(fields)));
17
+ const id = extractWriteResourceId(raw);
18
+ if (id === undefined)
19
+ throw unknownWriteResponse("Ship 产品创建", raw);
20
+ const parsed = shipProductSchema.safeParse({
21
+ ...raw,
22
+ id,
23
+ identifier: typeof raw.identifier === "string" ? raw.identifier : fields.identifier,
24
+ name: typeof raw.name === "string" ? raw.name : fields.name,
25
+ });
26
+ if (parsed.success)
27
+ return parsed.data;
28
+ try {
29
+ return shipProductSchema.parse(await this.client.get(`/v1/ship/products/${encodeURIComponent(id)}`));
30
+ }
31
+ catch (error) {
32
+ throw unknownWriteResponse(`Ship 产品创建(${id})`, error);
33
+ }
34
+ }
35
+ async updateProduct(productId, fields) {
36
+ return shipProductSchema.parse(await this.client.patch(`/v1/ship/products/${encodeURIComponent(productId)}`, mapProductUpdateFields(fields)));
37
+ }
38
+ async listIdeas(input) {
39
+ return paginatedSchema(shipIdeaSchema).parse(await this.client.get("/v1/ship/ideas", listQuery(input)));
40
+ }
41
+ async getIdea(ideaId) {
42
+ return shipIdeaSchema.parse(await this.client.get(`/v1/ship/ideas/${encodeURIComponent(ideaId)}`));
43
+ }
44
+ async createIdea(fields) {
45
+ const raw = unwrapWriteResponse(await this.client.post("/v1/ship/ideas", mapIdeaFields(fields)));
46
+ const id = extractWriteResourceId(raw);
47
+ if (id === undefined)
48
+ throw unknownWriteResponse("Ship 需求创建", raw);
49
+ const parsed = shipIdeaSchema.safeParse({
50
+ ...raw,
51
+ id,
52
+ title: typeof raw.title === "string" ? raw.title : fields.title,
53
+ });
54
+ if (parsed.success)
55
+ return parsed.data;
56
+ try {
57
+ return shipIdeaSchema.parse(await this.client.get(`/v1/ship/ideas/${encodeURIComponent(id)}`));
58
+ }
59
+ catch (error) {
60
+ throw unknownWriteResponse(`Ship 需求创建(${id})`, error);
61
+ }
62
+ }
63
+ async updateIdea(ideaId, fields) {
64
+ return shipIdeaSchema.parse(await this.client.patch(`/v1/ship/ideas/${encodeURIComponent(ideaId)}`, mapIdeaUpdateFields(fields)));
65
+ }
66
+ async listSuites(productId, input = {}) {
67
+ return paginatedSchema(shipSuiteSchema).parse(await this.client.get(`/v1/ship/products/${encodeURIComponent(productId)}/suites`, {
68
+ page_index: input.pageIndex,
69
+ page_size: input.pageSize,
70
+ }));
71
+ }
72
+ async getSuite(productId, suiteId) {
73
+ return shipSuiteSchema.parse(await this.client.get(`/v1/ship/products/${encodeURIComponent(productId)}/suites/${encodeURIComponent(suiteId)}`));
74
+ }
75
+ async createSuite(productId, fields) {
76
+ return shipSuiteSchema.parse(await this.client.post(`/v1/ship/products/${encodeURIComponent(productId)}/suites`, compact({ name: fields.name, type: fields.type, parent_id: fields.parentId })));
77
+ }
78
+ async removeSuite(productId, suiteId) {
79
+ if (!this.client.delete) {
80
+ throw new PingCodeError("当前 PingCode Client 不支持 DELETE 请求", "NOT_CONFIGURED");
81
+ }
82
+ await this.client.delete(`/v1/ship/products/${encodeURIComponent(productId)}/suites/${encodeURIComponent(suiteId)}`);
83
+ }
84
+ }
85
+ function listQuery(input) {
86
+ return {
87
+ keywords: input.keywords,
88
+ product_id: input.productId,
89
+ page_index: input.pageIndex,
90
+ page_size: input.pageSize,
91
+ };
92
+ }
93
+ function mapProductFields(fields) {
94
+ return compact({
95
+ scope_type: fields.scopeType,
96
+ scope_id: fields.scopeId,
97
+ name: fields.name,
98
+ visibility: fields.visibility,
99
+ identifier: fields.identifier,
100
+ description: fields.description,
101
+ members: fields.members,
102
+ });
103
+ }
104
+ function mapProductUpdateFields(fields) {
105
+ return compact({
106
+ name: fields.name,
107
+ identifier: fields.identifier,
108
+ description: fields.description,
109
+ });
110
+ }
111
+ function mapIdeaFields(fields) {
112
+ return compact({
113
+ product_id: fields.productId,
114
+ title: fields.title,
115
+ assignee_id: fields.assigneeId,
116
+ description: fields.description,
117
+ suite_id: fields.suiteId,
118
+ priority_id: fields.priorityId,
119
+ properties: fields.properties,
120
+ });
121
+ }
122
+ function mapIdeaUpdateFields(fields) {
123
+ return compact({
124
+ title: fields.title,
125
+ assignee_id: fields.assigneeId,
126
+ description: fields.description,
127
+ suite_id: fields.suiteId,
128
+ priority_id: fields.priorityId,
129
+ properties: fields.properties,
130
+ });
131
+ }
132
+ function compact(value) {
133
+ return Object.fromEntries(Object.entries(value).filter(([, nested]) => nested !== undefined));
134
+ }
135
+ //# sourceMappingURL=ship-source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ship-source.js","sourceRoot":"","sources":["../../src/sources/ship-source.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import type { TestCaseContext } from "../domain/test-case-context.js";
2
+ import type { PingCodeClientLike } from "../pingcode/client.js";
3
+ import { type TestCase } from "../pingcode/schemas.js";
4
+ import type { ListResult } from "./wiki-source.js";
5
+ export interface ListTestCasesInput {
6
+ libraryId?: string;
7
+ maintenanceId?: string;
8
+ stateId?: string;
9
+ importantLevelId?: string;
10
+ tagId?: string;
11
+ keywords?: string;
12
+ pageIndex?: number;
13
+ pageSize?: number;
14
+ }
15
+ export declare class TestCaseRequirementSource {
16
+ private readonly client;
17
+ private readonly now;
18
+ constructor(client: PingCodeClientLike, now?: () => Date);
19
+ listTestCases(input: ListTestCasesInput): Promise<ListResult<TestCase>>;
20
+ getTestCaseContext(reference: string): Promise<TestCaseContext>;
21
+ /**
22
+ * PingCode's write response and HTML URL can expose a display identifier
23
+ * (for example LIB-12), while the detail endpoint requires the internal ID.
24
+ * Resolve that identifier through the read-only list endpoint before giving
25
+ * up, so newly-created cases remain usable by subsequent tools.
26
+ */
27
+ private getTestCasePayload;
28
+ private listTestCaseRelations;
29
+ }
30
+ //# sourceMappingURL=test-case-source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-case-source.d.ts","sourceRoot":"","sources":["../../src/sources/test-case-source.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACtE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAEhE,OAAO,EAIL,KAAK,QAAQ,EACd,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAGnD,MAAM,WAAW,kBAAkB;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,yBAAyB;IAElC,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,GAAG;gBADH,MAAM,EAAE,kBAAkB,EAC1B,GAAG,GAAE,MAAM,IAAuB;IAG/C,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;IAsBvE,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAsFrE;;;;;OAKG;YACW,kBAAkB;YAuBlB,qBAAqB;CAsBpC"}
@@ -0,0 +1,206 @@
1
+ import { createHash } from "node:crypto";
2
+ import { PingCodeError } from "../pingcode/errors.js";
3
+ import { paginatedSchema, relationSchema, testCaseSchema, } from "../pingcode/schemas.js";
4
+ import { normalizeContentHash } from "../domain/content-hash.js";
5
+ export class TestCaseRequirementSource {
6
+ client;
7
+ now;
8
+ constructor(client, now = () => new Date()) {
9
+ this.client = client;
10
+ this.now = now;
11
+ }
12
+ async listTestCases(input) {
13
+ const payload = await this.client.get("/v1/testhub/cases", {
14
+ library_id: input.libraryId,
15
+ maintenance_id: input.maintenanceId,
16
+ state_id: input.stateId,
17
+ important_level_id: input.importantLevelId,
18
+ tag_id: input.tagId,
19
+ keywords: input.keywords,
20
+ page_index: input.pageIndex,
21
+ page_size: input.pageSize,
22
+ include_deleted: false,
23
+ include_archived: false,
24
+ });
25
+ const parsed = paginatedSchema(testCaseSchema).parse(payload);
26
+ return {
27
+ pageSize: parsed.page_size,
28
+ pageIndex: parsed.page_index,
29
+ total: parsed.total,
30
+ values: parsed.values,
31
+ };
32
+ }
33
+ async getTestCaseContext(reference) {
34
+ const normalizedReference = normalizeCaseReference(reference);
35
+ const { payload } = await this.getTestCasePayload(normalizedReference);
36
+ const testCase = testCaseSchema.parse(payload);
37
+ const effectiveCaseId = testCase.id;
38
+ let relations = [];
39
+ let relationsAvailable = true;
40
+ let relationErrorCode = null;
41
+ try {
42
+ relations = await this.listTestCaseRelations(effectiveCaseId);
43
+ }
44
+ catch (error) {
45
+ if (!(error instanceof PingCodeError)) {
46
+ throw error;
47
+ }
48
+ relationsAvailable = false;
49
+ relationErrorCode = error.code;
50
+ }
51
+ return {
52
+ source: {
53
+ type: "test_case",
54
+ id: testCase.id,
55
+ identifier: testCase.identifier,
56
+ shortId: testCase.short_id ?? null,
57
+ url: testCase.html_url ?? testCase.url,
58
+ apiUrl: testCase.url,
59
+ libraryId: testCase.library.id,
60
+ libraryIdentifier: testCase.library.identifier,
61
+ libraryName: testCase.library.name,
62
+ updatedAt: testCase.updated_at ?? null,
63
+ retrievedAt: this.now().toISOString(),
64
+ contentHash: normalizeContentHash(createHash("sha256").update(stableJson(testCase), "utf8").digest("hex")),
65
+ },
66
+ title: testCase.title,
67
+ description: testCase.description ?? null,
68
+ precondition: testCase.precondition ?? null,
69
+ level: testCase.level ?? null,
70
+ testType: testCase.test_type ?? null,
71
+ importantLevel: testCase.important_level
72
+ ? { id: testCase.important_level.id, name: testCase.important_level.name }
73
+ : null,
74
+ suite: testCase.suite
75
+ ? {
76
+ id: testCase.suite.id,
77
+ name: testCase.suite.name,
78
+ paths: testCase.suite.paths ?? null,
79
+ }
80
+ : null,
81
+ state: testCase.state
82
+ ? {
83
+ id: testCase.state.id,
84
+ name: testCase.state.name,
85
+ type: testCase.state.type ?? null,
86
+ }
87
+ : null,
88
+ type: testCase.type ? { id: testCase.type.id, name: testCase.type.name } : null,
89
+ maintenance: testCase.maintenance
90
+ ? {
91
+ id: testCase.maintenance.id,
92
+ name: testCase.maintenance.name ?? null,
93
+ displayName: testCase.maintenance.display_name ?? null,
94
+ }
95
+ : null,
96
+ properties: testCase.properties ?? {},
97
+ relationsAvailable,
98
+ relationErrorCode,
99
+ relationIds: relations.map((relation) => relation.id),
100
+ relatedWorkItemIds: relations
101
+ .filter((relation) => relation.target_type === "work_item")
102
+ .map(relationTargetId)
103
+ .filter((id) => id !== undefined),
104
+ relations: relations.map((relation) => ({
105
+ id: relation.id,
106
+ targetType: relation.target_type,
107
+ targetId: relationTargetId(relation) ?? null,
108
+ })),
109
+ steps: (testCase.steps ?? []).map((step) => ({
110
+ stepId: step.step_id ?? null,
111
+ description: step.description,
112
+ expectedValue: step.expected_value ?? null,
113
+ isGroup: step.is_group ?? false,
114
+ groupId: step.group_id ?? null,
115
+ })),
116
+ };
117
+ }
118
+ /**
119
+ * PingCode's write response and HTML URL can expose a display identifier
120
+ * (for example LIB-12), while the detail endpoint requires the internal ID.
121
+ * Resolve that identifier through the read-only list endpoint before giving
122
+ * up, so newly-created cases remain usable by subsequent tools.
123
+ */
124
+ async getTestCasePayload(reference) {
125
+ try {
126
+ return {
127
+ payload: await this.client.get(`/v1/testhub/cases/${encodeURIComponent(reference)}`),
128
+ };
129
+ }
130
+ catch (error) {
131
+ if (!(error instanceof PingCodeError) || !["NOT_FOUND", "BAD_REQUEST"].includes(error.code)) {
132
+ throw error;
133
+ }
134
+ const listed = await this.listTestCases({ keywords: reference, pageIndex: 0, pageSize: 100 });
135
+ const matches = listed.values.filter((testCase) => testCase.id === reference || testCase.identifier === reference || testCase.short_id === reference);
136
+ if (matches.length === 1 && matches[0]) {
137
+ const resolvedId = matches[0].id;
138
+ return {
139
+ payload: await this.client.get(`/v1/testhub/cases/${encodeURIComponent(resolvedId)}`),
140
+ };
141
+ }
142
+ throw error;
143
+ }
144
+ }
145
+ async listTestCaseRelations(caseId) {
146
+ const relations = [];
147
+ let pageIndex = 0;
148
+ for (;;) {
149
+ const page = paginatedSchema(relationSchema).parse(await this.client.get("/v1/relations", {
150
+ principal_type: "test_case",
151
+ principal_id: caseId,
152
+ target_type: "work_item",
153
+ page_index: pageIndex,
154
+ page_size: 100,
155
+ }));
156
+ relations.push(...page.values);
157
+ const consumed = (page.page_index + 1) * page.page_size;
158
+ if (consumed >= page.total || page.values.length === 0) {
159
+ return relations;
160
+ }
161
+ pageIndex = page.page_index + 1;
162
+ }
163
+ }
164
+ }
165
+ function relationTargetId(relation) {
166
+ return relation.target_id ?? relation.target?.id;
167
+ }
168
+ function normalizeCaseReference(reference) {
169
+ const normalized = reference.trim();
170
+ if (!normalized) {
171
+ throw new PingCodeError("caseReference 不能為空", "BAD_REQUEST");
172
+ }
173
+ if (!normalized.includes("://")) {
174
+ return normalized;
175
+ }
176
+ let url;
177
+ try {
178
+ url = new URL(normalized);
179
+ }
180
+ catch {
181
+ throw new PingCodeError("caseReference 不是有效的 Test Case URL", "BAD_REQUEST");
182
+ }
183
+ const match = url.pathname.match(/\/testhub\/cases\/([^/]+)\/?$/);
184
+ if (!match) {
185
+ throw new PingCodeError("caseReference URL 必須指向 PingCode Test Case API", "BAD_REQUEST");
186
+ }
187
+ try {
188
+ return decodeURIComponent(match[1]);
189
+ }
190
+ catch {
191
+ throw new PingCodeError("caseReference URL 包含無效的 Test Case ID", "BAD_REQUEST");
192
+ }
193
+ }
194
+ function stableJson(value) {
195
+ if (Array.isArray(value)) {
196
+ return `[${value.map(stableJson).join(",")}]`;
197
+ }
198
+ if (value && typeof value === "object") {
199
+ return `{${Object.entries(value)
200
+ .sort(([left], [right]) => left.localeCompare(right))
201
+ .map(([key, nested]) => `${JSON.stringify(key)}:${stableJson(nested)}`)
202
+ .join(",")}}`;
203
+ }
204
+ return JSON.stringify(value);
205
+ }
206
+ //# sourceMappingURL=test-case-source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-case-source.js","sourceRoot":"","sources":["../../src/sources/test-case-source.ts"],"names":[],"mappings":"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"}